summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-08-05 20:13:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-08-05 20:13:21 -0700
commit47ec5303d73ea344e84f46660fff693c57641386 (patch)
treea2252debab749de29620c43285295d60c4741119 /drivers
parent8186749621ed6b8fc42644c399e8c755a2b6f630 (diff)
parentc1055b76ad00aed0e8b79417080f212d736246b6 (diff)
downloadlinux-47ec5303d73ea344e84f46660fff693c57641386.tar.bz2
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from David Miller: 1) Support 6Ghz band in ath11k driver, from Rajkumar Manoharan. 2) Support UDP segmentation in code TSO code, from Eric Dumazet. 3) Allow flashing different flash images in cxgb4 driver, from Vishal Kulkarni. 4) Add drop frames counter and flow status to tc flower offloading, from Po Liu. 5) Support n-tuple filters in cxgb4, from Vishal Kulkarni. 6) Various new indirect call avoidance, from Eric Dumazet and Brian Vazquez. 7) Fix BPF verifier failures on 32-bit pointer arithmetic, from Yonghong Song. 8) Support querying and setting hardware address of a port function via devlink, use this in mlx5, from Parav Pandit. 9) Support hw ipsec offload on bonding slaves, from Jarod Wilson. 10) Switch qca8k driver over to phylink, from Jonathan McDowell. 11) In bpftool, show list of processes holding BPF FD references to maps, programs, links, and btf objects. From Andrii Nakryiko. 12) Several conversions over to generic power management, from Vaibhav Gupta. 13) Add support for SO_KEEPALIVE et al. to bpf_setsockopt(), from Dmitry Yakunin. 14) Various https url conversions, from Alexander A. Klimov. 15) Timestamping and PHC support for mscc PHY driver, from Antoine Tenart. 16) Support bpf iterating over tcp and udp sockets, from Yonghong Song. 17) Support 5GBASE-T i40e NICs, from Aleksandr Loktionov. 18) Add kTLS RX HW offload support to mlx5e, from Tariq Toukan. 19) Fix the ->ndo_start_xmit() return type to be netdev_tx_t in several drivers. From Luc Van Oostenryck. 20) XDP support for xen-netfront, from Denis Kirjanov. 21) Support receive buffer autotuning in MPTCP, from Florian Westphal. 22) Support EF100 chip in sfc driver, from Edward Cree. 23) Add XDP support to mvpp2 driver, from Matteo Croce. 24) Support MPTCP in sock_diag, from Paolo Abeni. 25) Commonize UDP tunnel offloading code by creating udp_tunnel_nic infrastructure, from Jakub Kicinski. 26) Several pci_ --> dma_ API conversions, from Christophe JAILLET. 27) Add FLOW_ACTION_POLICE support to mlxsw, from Ido Schimmel. 28) Add SK_LOOKUP bpf program type, from Jakub Sitnicki. 29) Refactor a lot of networking socket option handling code in order to avoid set_fs() calls, from Christoph Hellwig. 30) Add rfc4884 support to icmp code, from Willem de Bruijn. 31) Support TBF offload in dpaa2-eth driver, from Ioana Ciornei. 32) Support XDP_REDIRECT in qede driver, from Alexander Lobakin. 33) Support PCI relaxed ordering in mlx5 driver, from Aya Levin. 34) Support TCP syncookies in MPTCP, from Flowian Westphal. 35) Fix several tricky cases of PMTU handling wrt. briding, from Stefano Brivio. * git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2056 commits) net: thunderx: initialize VF's mailbox mutex before first usage usb: hso: remove bogus check for EINPROGRESS usb: hso: no complaint about kmalloc failure hso: fix bailout in error case of probe ip_tunnel_core: Fix build for archs without _HAVE_ARCH_IPV6_CSUM selftests/net: relax cpu affinity requirement in msg_zerocopy test mptcp: be careful on subflow creation selftests: rtnetlink: make kci_test_encap() return sub-test result selftests: rtnetlink: correct the final return value for the test net: dsa: sja1105: use detected device id instead of DT one on mismatch tipc: set ub->ifindex for local ipv6 address ipv6: add ipv6_dev_find() net: openvswitch: silence suspicious RCU usage warning Revert "vxlan: fix tos value before xmit" ptp: only allow phase values lower than 1 period farsync: switch from 'pci_' to 'dma_' API wan: wanxl: switch from 'pci_' to 'dma_' API hv_netvsc: do not use VF device if link is down dpaa2-eth: Fix passing zero to 'PTR_ERR' warning net: macb: Properly handle phylink on at91sam9x ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/atm/Kconfig8
-rw-r--r--drivers/atm/eni.c21
-rw-r--r--drivers/atm/firestream.c2
-rw-r--r--drivers/atm/fore200e.c27
-rw-r--r--drivers/atm/horizon.c40
-rw-r--r--drivers/atm/idt77252.c9
-rw-r--r--drivers/atm/iphase.c16
-rw-r--r--drivers/atm/lanai.c2
-rw-r--r--drivers/atm/solos-pci.c4
-rw-r--r--drivers/atm/zatm.c16
-rw-r--r--drivers/bcma/driver_gpio.c23
-rw-r--r--drivers/bcma/scan.c8
-rw-r--r--drivers/bluetooth/bcm203x.c2
-rw-r--r--drivers/bluetooth/bluecard_cs.c2
-rw-r--r--drivers/bluetooth/btintel.c59
-rw-r--r--drivers/bluetooth/btintel.h21
-rw-r--r--drivers/bluetooth/btmrvl_main.c11
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c21
-rw-r--r--drivers/bluetooth/btmtksdio.c16
-rw-r--r--drivers/bluetooth/btqca.c27
-rw-r--r--drivers/bluetooth/btqca.h2
-rw-r--r--drivers/bluetooth/btusb.c303
-rw-r--r--drivers/bluetooth/hci_h5.c2
-rw-r--r--drivers/bluetooth/hci_ll.c2
-rw-r--r--drivers/bluetooth/hci_qca.c134
-rw-r--r--drivers/bluetooth/hci_serdev.c3
-rw-r--r--drivers/crypto/chelsio/chtls/chtls_cm.c3
-rw-r--r--drivers/crypto/chelsio/chtls/chtls_main.c18
-rw-r--r--drivers/infiniband/hw/bnxt_re/hw_counters.c2
-rw-r--r--drivers/infiniband/hw/i40iw/Makefile1
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw.h2
-rw-r--r--drivers/infiniband/hw/qedr/main.c20
-rw-r--r--drivers/infiniband/hw/qedr/verbs.c97
-rw-r--r--drivers/isdn/capi/Kconfig2
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c12
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c3
-rw-r--r--drivers/isdn/hardware/mISDN/netjet.c8
-rw-r--r--drivers/isdn/mISDN/socket.c10
-rw-r--r--drivers/net/Kconfig3
-rw-r--r--drivers/net/appletalk/Kconfig3
-rw-r--r--drivers/net/bareudp.c7
-rw-r--r--drivers/net/bonding/bond_main.c139
-rw-r--r--drivers/net/bonding/bond_options.c8
-rw-r--r--drivers/net/caif/caif_hsi.c6
-rw-r--r--drivers/net/caif/caif_serial.c2
-rw-r--r--drivers/net/caif/caif_spi.c4
-rw-r--r--drivers/net/caif/caif_virtio.c2
-rw-r--r--drivers/net/dsa/Kconfig1
-rw-r--r--drivers/net/dsa/b53/b53_common.c31
-rw-r--r--drivers/net/dsa/b53/b53_spi.c26
-rw-r--r--drivers/net/dsa/bcm_sf2.c89
-rw-r--r--drivers/net/dsa/bcm_sf2_cfp.c8
-rw-r--r--drivers/net/dsa/dsa_loop.c72
-rw-r--r--drivers/net/dsa/lan9303-core.c7
-rw-r--r--drivers/net/dsa/microchip/ksz8795.c19
-rw-r--r--drivers/net/dsa/microchip/ksz9477.c24
-rw-r--r--drivers/net/dsa/microchip/ksz_common.c35
-rw-r--r--drivers/net/dsa/microchip/ksz_common.h9
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c41
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.h7
-rw-r--r--drivers/net/dsa/mv88e6xxx/global1.c17
-rw-r--r--drivers/net/dsa/mv88e6xxx/global1.h2
-rw-r--r--drivers/net/dsa/mv88e6xxx/global2.c5
-rw-r--r--drivers/net/dsa/mv88e6xxx/global2_scratch.c9
-rw-r--r--drivers/net/dsa/ocelot/Kconfig15
-rw-r--r--drivers/net/dsa/ocelot/Makefile3
-rw-r--r--drivers/net/dsa/ocelot/felix.c364
-rw-r--r--drivers/net/dsa/ocelot/felix.h39
-rw-r--r--drivers/net/dsa/ocelot/felix_vsc9959.c626
-rw-r--r--drivers/net/dsa/ocelot/seville_vsc9953.c1104
-rw-r--r--drivers/net/dsa/qca/ar9331.c60
-rw-r--r--drivers/net/dsa/qca8k.c558
-rw-r--r--drivers/net/dsa/qca8k.h45
-rw-r--r--drivers/net/dsa/rtl8366.c37
-rw-r--r--drivers/net/dsa/rtl8366rb.c31
-rw-r--r--drivers/net/dsa/sja1105/sja1105.h12
-rw-r--r--drivers/net/dsa/sja1105/sja1105_dynamic_config.c25
-rw-r--r--drivers/net/dsa/sja1105/sja1105_dynamic_config.h4
-rw-r--r--drivers/net/dsa/sja1105/sja1105_flower.c16
-rw-r--r--drivers/net/dsa/sja1105/sja1105_main.c39
-rw-r--r--drivers/net/dsa/sja1105/sja1105_ptp.c79
-rw-r--r--drivers/net/dsa/sja1105/sja1105_ptp.h5
-rw-r--r--drivers/net/dsa/sja1105/sja1105_spi.c17
-rw-r--r--drivers/net/dsa/sja1105/sja1105_static_config.c36
-rw-r--r--drivers/net/dsa/sja1105/sja1105_static_config.h12
-rw-r--r--drivers/net/dsa/sja1105/sja1105_tas.c3
-rw-r--r--drivers/net/dsa/sja1105/sja1105_vl.c2
-rw-r--r--drivers/net/dsa/vitesse-vsc73xx-platform.c2
-rw-r--r--drivers/net/dsa/vitesse-vsc73xx-spi.c2
-rw-r--r--drivers/net/ethernet/3com/3c59x.c4
-rw-r--r--drivers/net/ethernet/3com/Kconfig4
-rw-r--r--drivers/net/ethernet/3com/typhoon.c53
-rw-r--r--drivers/net/ethernet/8390/8390.h61
-rw-r--r--drivers/net/ethernet/8390/ne2k-pci.c38
-rw-r--r--drivers/net/ethernet/adaptec/starfire.c23
-rw-r--r--drivers/net/ethernet/aeroflex/greth.c2
-rw-r--r--drivers/net/ethernet/agere/et131x.c7
-rw-r--r--drivers/net/ethernet/alteon/acenic.c119
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_admin_defs.h47
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_com.c19
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_com.h13
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_eth_com.c51
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_eth_com.h3
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_ethtool.c4
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_netdev.c211
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_netdev.h3
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_pci_id_tbl.h5
-rw-r--r--drivers/net/ethernet/amd/amd8111e.c111
-rw-r--r--drivers/net/ethernet/amd/au1000_eth.c5
-rw-r--r--drivers/net/ethernet/amd/pcnet32.c203
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c275
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-main.c12
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-pci.c19
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe.h13
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_common.h18
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c62
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.h10
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c98
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_hw.h17
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c34
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h8
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_main.c22
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_nic.c117
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_nic.h9
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c9
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_pci_func.h8
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_ptp.c77
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_ptp.h27
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_ring.c85
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_ring.h22
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_vec.c74
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_vec.h11
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c138
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c70
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.h3
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c61
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h28
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h41
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c62
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h2
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c4
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c10
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.c3
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c227
-rw-r--r--drivers/net/ethernet/arc/emac_main.c2
-rw-r--r--drivers/net/ethernet/aurora/nb8800.c2
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.c36
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/Makefile2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h18
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c15
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h12
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c155
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h78
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_self_test.c3183
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c880
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.h126
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c15
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c190
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h3
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h468
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c18
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c4
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c17
-rw-r--r--drivers/net/ethernet/broadcom/tg3.h2
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_ioc.c3
-rw-r--r--drivers/net/ethernet/brocade/bna/bfi.h2
-rw-r--r--drivers/net/ethernet/cadence/macb.h3
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c221
-rw-r--r--drivers/net/ethernet/cadence/macb_pci.c2
-rw-r--r--drivers/net/ethernet/cadence/macb_ptp.c2
-rw-r--r--drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c2
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_main.c90
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_vf_main.c59
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_device.c11
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_network.h2
-rw-r--r--drivers/net/ethernet/cavium/liquidio/request_manager.c10
-rw-r--r--drivers/net/ethernet/cavium/octeon/octeon_mgmt.c7
-rw-r--r--drivers/net/ethernet/cavium/thunder/nicvf_main.c11
-rw-r--r--drivers/net/ethernet/cavium/thunder/nicvf_queues.c5
-rw-r--r--drivers/net/ethernet/chelsio/Kconfig2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h161
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c443
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.h4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h120
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c260
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c66
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c626
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c5
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c598
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c144
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h8
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c146
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.h6
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/sge.c109
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/smt.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c334
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_regs.h10
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/adapter.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c47
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/sge.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c6
-rw-r--r--drivers/net/ethernet/cirrus/Kconfig2
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c105
-rw-r--r--drivers/net/ethernet/cortina/Kconfig2
-rw-r--r--drivers/net/ethernet/dec/tulip/Kconfig4
-rw-r--r--drivers/net/ethernet/dec/tulip/de2104x.c25
-rw-r--r--drivers/net/ethernet/dec/tulip/dmfe.c49
-rw-r--r--drivers/net/ethernet/dec/tulip/tulip_core.c51
-rw-r--r--drivers/net/ethernet/dec/tulip/uli526x.c48
-rw-r--r--drivers/net/ethernet/dec/tulip/winbond-840.c26
-rw-r--r--drivers/net/ethernet/dlink/dl2k.c10
-rw-r--r--drivers/net/ethernet/dlink/sundance.c29
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h5
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c220
-rw-r--r--drivers/net/ethernet/fealnx.c91
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c8
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-trace.h1
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c263
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h15
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c3
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h13
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpni.c44
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpni.h16
-rw-r--r--drivers/net/ethernet/freescale/enetc/Kconfig2
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc.c164
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc.h36
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_ethtool.c84
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_hw.h50
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_pf.c196
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_pf.h5
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_qos.c213
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c7
-rw-r--r--drivers/net/ethernet/freescale/fec_ptp.c13
-rw-r--r--drivers/net/ethernet/freescale/fman/fman.c3
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_dtsec.c4
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_mac.h2
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_memac.c3
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_port.c9
-rw-r--r--drivers/net/ethernet/freescale/fman/fman_tgec.c2
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c6
-rw-r--r--drivers/net/ethernet/freescale/xgmac_mdio.c33
-rw-r--r--drivers/net/ethernet/hisilicon/hix5hd2_gmac.c6
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c2
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.c41
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.h2
-rw-r--r--drivers/net/ethernet/huawei/hinic/Makefile2
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_dev.h23
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_devlink.c608
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_devlink.h119
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_ethtool.c602
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c27
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h4
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c2
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h10
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c254
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h226
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c39
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h6
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_if.c23
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_if.h10
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_io.h10
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c312
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.h22
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c11
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h17
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_main.c205
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_port.c256
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_port.h144
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_rx.c58
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_sriov.c81
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_tx.c80
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_tx.h2
-rw-r--r--drivers/net/ethernet/intel/Kconfig25
-rw-r--r--drivers/net/ethernet/intel/e100.c38
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000.h1
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_ethtool.c6
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_hw.c4
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_main.c8
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_param.c2
-rw-r--r--drivers/net/ethernet/intel/e1000e/82571.c4
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h1
-rw-r--r--drivers/net/ethernet/intel/e1000e/ethtool.c17
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c14
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c38
-rw-r--r--drivers/net/ethernet/intel/e1000e/param.c2
-rw-r--r--drivers/net/ethernet/intel/e1000e/phy.c2
-rw-r--r--drivers/net/ethernet/intel/e1000e/ptp.c3
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k.h11
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c6
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_main.c18
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_mbx.c6
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_netdev.c166
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pci.c4
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pf.c8
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h49
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.c2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h496
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_client.c2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_client.h203
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c7
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_dcb.h5
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_debugfs.c101
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_devids.h7
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c13
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_hmc.h1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c282
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_osdep.h1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ptp.c2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_register.h4658
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c23
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.h26
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_type.h82
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c234
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_xsk.c61
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_xsk.h3
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf.h1
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_ethtool.c1
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_main.c68
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_txrx.c2
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_type.h8
-rw-r--r--drivers/net/ethernet/intel/ice/Makefile1
-rw-r--r--drivers/net/ethernet/intel/ice/ice.h23
-rw-r--r--drivers/net/ethernet/intel/ice/ice_adminq_cmd.h214
-rw-r--r--drivers/net/ethernet/intel/ice/ice_base.c2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_common.c1432
-rw-r--r--drivers/net/ethernet/intel/ice/ice_common.h36
-rw-r--r--drivers/net/ethernet/intel/ice/ice_controlq.c6
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb.c37
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb.h4
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb_lib.c6
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb_lib.h11
-rw-r--r--drivers/net/ethernet/intel/ice/ice_devlink.c121
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ethtool.c745
-rw-r--r--drivers/net/ethernet/intel/ice/ice_flex_pipe.c135
-rw-r--r--drivers/net/ethernet/intel/ice/ice_flex_type.h39
-rw-r--r--drivers/net/ethernet/intel/ice/ice_flow.c13
-rw-r--r--drivers/net/ethernet/intel/ice/ice_fw_update.c773
-rw-r--r--drivers/net/ethernet/intel/ice/ice_fw_update.h12
-rw-r--r--drivers/net/ethernet/intel/ice/ice_hw_autogen.h13
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h314
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lib.c43
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lib.h2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c1137
-rw-r--r--drivers/net/ethernet/intel/ice/ice_nvm.c191
-rw-r--r--drivers/net/ethernet/intel/ice/ice_nvm.h20
-rw-r--r--drivers/net/ethernet/intel/ice/ice_sched.c135
-rw-r--r--drivers/net/ethernet/intel/ice/ice_sched.h2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_switch.c58
-rw-r--r--drivers/net/ethernet/intel/ice/ice_txrx.c39
-rw-r--r--drivers/net/ethernet/intel/ice/ice_txrx.h2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_txrx_lib.c7
-rw-r--r--drivers/net/ethernet/intel/ice/ice_type.h73
-rw-r--r--drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c61
-rw-r--r--drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h3
-rw-r--r--drivers/net/ethernet/intel/ice/ice_xsk.c18
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.c4
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_nvm.c2
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.c4
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h1
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c13
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c41
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ptp.c2
-rw-r--r--drivers/net/ethernet/intel/igbvf/ethtool.c2
-rw-r--r--drivers/net/ethernet/intel/igbvf/igbvf.h1
-rw-r--r--drivers/net/ethernet/intel/igbvf/netdev.c46
-rw-r--r--drivers/net/ethernet/intel/igc/igc.h8
-rw-r--r--drivers/net/ethernet/intel/igc/igc_defines.h39
-rw-r--r--drivers/net/ethernet/intel/igc/igc_ethtool.c112
-rw-r--r--drivers/net/ethernet/intel/igc/igc_hw.h21
-rw-r--r--drivers/net/ethernet/intel/igc/igc_i225.c156
-rw-r--r--drivers/net/ethernet/intel/igc/igc_i225.h3
-rw-r--r--drivers/net/ethernet/intel/igc/igc_mac.c28
-rw-r--r--drivers/net/ethernet/intel/igc/igc_main.c68
-rw-r--r--drivers/net/ethernet/intel/igc/igc_ptp.c256
-rw-r--r--drivers/net/ethernet/intel/igc/igc_regs.h30
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb.h1
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c2
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_main.c6
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c6
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c283
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c5
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c8
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c317
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c14
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c6
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c10
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ethtool.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c67
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/vf.c6
-rw-r--r--drivers/net/ethernet/jme.c2
-rw-r--r--drivers/net/ethernet/jme.h2
-rw-r--r--drivers/net/ethernet/marvell/Kconfig1
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c5
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c242
-rw-r--r--drivers/net/ethernet/marvell/mvpp2/mvpp2.h57
-rw-r--r--drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c906
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/common.h2
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c6
-rw-r--r--drivers/net/ethernet/marvell/skge.c76
-rw-r--r--drivers/net/ethernet/marvell/sky2.c87
-rw-r--r--drivers/net/ethernet/mediatek/mtk_eth_soc.c45
-rw-r--r--drivers/net/ethernet/mediatek/mtk_star_emac.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c131
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/Kconfig27
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/Makefile8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c108
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h45
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec_offload.c385
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec_offload.h38
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/accel/tls.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/accel/tls.h19
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/devlink.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.h33
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h103
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c19
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/fs.h34
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/health.c58
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/health.h16
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.c157
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.h31
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/params.h22
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/port.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c17
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c154
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c93
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c481
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h32
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h93
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c30
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h13
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c54
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c22
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c400
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.h27
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c51
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c544
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.h26
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c56
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h23
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c123
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h114
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c680
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c208
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.c119
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.h42
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_utils.h86
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.c28
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.h14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c34
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.h34
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c36
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_common.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c23
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_fs.c84
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c290
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.c75
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.h6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rx.c169
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_stats.c39
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_stats.h25
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c279
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.h33
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tx.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.c161
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.h47
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c115
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c51
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h37
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.h10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fw.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c114
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c145
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c15
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c42
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/vport.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/wq.h15
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/Makefile3
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core.c34
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core.h25
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c355
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h10
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_env.c53
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/minimal.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/pci.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/pci_hw.h7
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/reg.h195
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/resources.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c1680
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.h151
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c108
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c31
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c1644
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_flow.c18
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c30
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c29
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_policer.c468
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c524
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c655
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h33
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c255
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.h18
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/switchib.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/switchx2.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/trap.h10
-rw-r--r--drivers/net/ethernet/micrel/ksz884x.c93
-rw-r--r--drivers/net/ethernet/microchip/lan743x_main.c93
-rw-r--r--drivers/net/ethernet/mscc/Kconfig22
-rw-r--r--drivers/net/ethernet/mscc/Makefile16
-rw-r--r--drivers/net/ethernet/mscc/ocelot.c1093
-rw-r--r--drivers/net/ethernet/mscc/ocelot.h51
-rw-r--r--drivers/net/ethernet/mscc/ocelot_board.c626
-rw-r--r--drivers/net/ethernet/mscc/ocelot_flower.c148
-rw-r--r--drivers/net/ethernet/mscc/ocelot_io.c18
-rw-r--r--drivers/net/ethernet/mscc/ocelot_net.c1050
-rw-r--r--drivers/net/ethernet/mscc/ocelot_police.c49
-rw-r--r--drivers/net/ethernet/mscc/ocelot_police.h25
-rw-r--r--drivers/net/ethernet/mscc/ocelot_ptp.c74
-rw-r--r--drivers/net/ethernet/mscc/ocelot_regs.c450
-rw-r--r--drivers/net/ethernet/mscc/ocelot_tc.c179
-rw-r--r--drivers/net/ethernet/mscc/ocelot_tc.h22
-rw-r--r--drivers/net/ethernet/mscc/ocelot_vcap.c (renamed from drivers/net/ethernet/mscc/ocelot_ace.c)336
-rw-r--r--drivers/net/ethernet/mscc/ocelot_vcap.h (renamed from drivers/net/ethernet/mscc/ocelot_ace.h)88
-rw-r--r--drivers/net/ethernet/mscc/ocelot_vsc7514.c1138
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c37
-rw-r--r--drivers/net/ethernet/natsemi/natsemi.c26
-rw-r--r--drivers/net/ethernet/neterion/Kconfig4
-rw-r--r--drivers/net/ethernet/neterion/s2io.c191
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-config.c42
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-main.c82
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/main.h2
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/offload.c10
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/qos_conf.c8
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_devlink.c17
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net.h5
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_common.c132
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c2
-rw-r--r--drivers/net/ethernet/packetengines/hamachi.c111
-rw-r--r--drivers/net/ethernet/packetengines/yellowfin.c83
-rw-r--r--drivers/net/ethernet/pensando/Kconfig2
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c9
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_dev.h2
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_devlink.c5
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_ethtool.c96
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_if.h88
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_lif.c66
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_lif.h19
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_txrx.c188
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_txrx.h2
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c59
-rw-r--r--drivers/net/ethernet/qlogic/qed/Makefile41
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed.h155
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_chain.c371
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_cxt.c49
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_cxt.h30
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_dcbx.c57
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_dcbx.h32
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_debug.c55
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_debug.h3
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_dev.c475
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_dev_api.h62
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_fcoe.c84
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_fcoe.h35
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_hsi.h1085
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_hw.c35
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_hw.h37
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c158
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_init_ops.c103
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_init_ops.h30
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_int.c153
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_int.h30
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_iscsi.c117
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_iscsi.h34
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_iwarp.c181
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_iwarp.h31
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_l2.c111
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_l2.h31
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_ll2.c83
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_ll2.h32
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_main.c811
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.c161
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.h176
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c8
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_ooo.c30
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_ooo.h30
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_ptp.c32
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_ptp.h9
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_rdma.c84
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_rdma.h33
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_reg_addr.h30
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_roce.c237
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_roce.h31
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_selftest.c30
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_selftest.h4
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_sp.h39
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_sp_commands.c58
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_spq.c136
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_sriov.c70
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_sriov.h32
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_vf.c30
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_vf.h29
-rw-r--r--drivers/net/ethernet/qlogic/qede/Makefile4
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede.h209
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_dcbnl.c7
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_ethtool.c528
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_filter.c184
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_fp.c205
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_main.c232
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_ptp.c41
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_ptp.h31
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_rdma.c31
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h7
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c31
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c11
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c97
-rw-r--r--drivers/net/ethernet/rdc/r6040.c64
-rw-r--r--drivers/net/ethernet/realtek/r8169.h2
-rw-r--r--drivers/net/ethernet/realtek/r8169_main.c390
-rw-r--r--drivers/net/ethernet/realtek/r8169_phy_config.c81
-rw-r--r--drivers/net/ethernet/sfc/Kconfig5
-rw-r--r--drivers/net/ethernet/sfc/Makefile4
-rw-r--r--drivers/net/ethernet/sfc/bitfield.h34
-rw-r--r--drivers/net/ethernet/sfc/ef10.c346
-rw-r--r--drivers/net/ethernet/sfc/ef100.c543
-rw-r--r--drivers/net/ethernet/sfc/ef100.h12
-rw-r--r--drivers/net/ethernet/sfc/ef100_ethtool.c24
-rw-r--r--drivers/net/ethernet/sfc/ef100_ethtool.h12
-rw-r--r--drivers/net/ethernet/sfc/ef100_netdev.c289
-rw-r--r--drivers/net/ethernet/sfc/ef100_netdev.h17
-rw-r--r--drivers/net/ethernet/sfc/ef100_nic.c1278
-rw-r--r--drivers/net/ethernet/sfc/ef100_nic.h80
-rw-r--r--drivers/net/ethernet/sfc/ef100_regs.h693
-rw-r--r--drivers/net/ethernet/sfc/ef100_rx.c167
-rw-r--r--drivers/net/ethernet/sfc/ef100_rx.h21
-rw-r--r--drivers/net/ethernet/sfc/ef100_tx.c408
-rw-r--r--drivers/net/ethernet/sfc/ef100_tx.h26
-rw-r--r--drivers/net/ethernet/sfc/efx.c322
-rw-r--r--drivers/net/ethernet/sfc/efx.h50
-rw-r--r--drivers/net/ethernet/sfc/efx_channels.c76
-rw-r--r--drivers/net/ethernet/sfc/efx_channels.h3
-rw-r--r--drivers/net/ethernet/sfc/efx_common.c263
-rw-r--r--drivers/net/ethernet/sfc/efx_common.h44
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c914
-rw-r--r--drivers/net/ethernet/sfc/ethtool_common.c910
-rw-r--r--drivers/net/ethernet/sfc/ethtool_common.h35
-rw-r--r--drivers/net/ethernet/sfc/farch.c6
-rw-r--r--drivers/net/ethernet/sfc/io.h16
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c74
-rw-r--r--drivers/net/ethernet/sfc/mcdi.h14
-rw-r--r--drivers/net/ethernet/sfc/mcdi_filters.c77
-rw-r--r--drivers/net/ethernet/sfc/mcdi_filters.h3
-rw-r--r--drivers/net/ethernet/sfc/mcdi_functions.c57
-rw-r--r--drivers/net/ethernet/sfc/mcdi_functions.h1
-rw-r--r--drivers/net/ethernet/sfc/mcdi_pcol.h6877
-rw-r--r--drivers/net/ethernet/sfc/mcdi_port.c105
-rw-r--r--drivers/net/ethernet/sfc/mcdi_port.h18
-rw-r--r--drivers/net/ethernet/sfc/mcdi_port_common.c141
-rw-r--r--drivers/net/ethernet/sfc/mcdi_port_common.h5
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h98
-rw-r--r--drivers/net/ethernet/sfc/nic.c44
-rw-r--r--drivers/net/ethernet/sfc/nic.h301
-rw-r--r--drivers/net/ethernet/sfc/nic_common.h286
-rw-r--r--drivers/net/ethernet/sfc/ptp.c25
-rw-r--r--drivers/net/ethernet/sfc/ptp.h45
-rw-r--r--drivers/net/ethernet/sfc/rx.c244
-rw-r--r--drivers/net/ethernet/sfc/rx_common.c245
-rw-r--r--drivers/net/ethernet/sfc/rx_common.h15
-rw-r--r--drivers/net/ethernet/sfc/selftest.c18
-rw-r--r--drivers/net/ethernet/sfc/siena.c9
-rw-r--r--drivers/net/ethernet/sfc/tx.c82
-rw-r--r--drivers/net/ethernet/sfc/tx.h3
-rw-r--r--drivers/net/ethernet/sfc/tx_common.c53
-rw-r--r--drivers/net/ethernet/sfc/tx_common.h3
-rw-r--r--drivers/net/ethernet/sgi/ioc3-eth.c4
-rw-r--r--drivers/net/ethernet/silan/sc92031.c26
-rw-r--r--drivers/net/ethernet/sis/sis190.c52
-rw-r--r--drivers/net/ethernet/sis/sis900.c112
-rw-r--r--drivers/net/ethernet/smsc/Kconfig4
-rw-r--r--drivers/net/ethernet/smsc/epic100.c19
-rw-r--r--drivers/net/ethernet/smsc/smsc9420.c40
-rw-r--r--drivers/net/ethernet/socionext/netsec.c3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c53
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c19
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c18
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c2
-rw-r--r--drivers/net/ethernet/sun/cassini.c121
-rw-r--r--drivers/net/ethernet/sun/niu.c17
-rw-r--r--drivers/net/ethernet/sun/sungem.c129
-rw-r--r--drivers/net/ethernet/synopsys/dwc-xlgmac-net.c2
-rw-r--r--drivers/net/ethernet/ti/Kconfig2
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-ethtool.c6
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-nuss.c77
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-nuss.h2
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-qos.c8
-rw-r--r--drivers/net/ethernet/ti/cpsw_priv.c3
-rw-r--r--drivers/net/ethernet/ti/tlan.c33
-rw-r--r--drivers/net/ethernet/toshiba/spider_net.c6
-rw-r--r--drivers/net/ethernet/via/via-velocity.c163
-rw-r--r--drivers/net/ethernet/via/via-velocity.h44
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac_main.c6
-rw-r--r--drivers/net/ethernet/xircom/xirc2ps_cs.c2
-rw-r--r--drivers/net/fddi/Kconfig4
-rw-r--r--drivers/net/fddi/skfp/ess.c10
-rw-r--r--drivers/net/fddi/skfp/h/cmtdef.h1
-rw-r--r--drivers/net/fddi/skfp/smt.c60
-rw-r--r--drivers/net/geneve.c246
-rw-r--r--drivers/net/hamradio/Kconfig16
-rw-r--r--drivers/net/hamradio/scc.c2
-rw-r--r--drivers/net/hyperv/hyperv_net.h1
-rw-r--r--drivers/net/hyperv/netvsc_bpf.c21
-rw-r--r--drivers/net/hyperv/netvsc_drv.c50
-rw-r--r--drivers/net/ipa/gsi.c117
-rw-r--r--drivers/net/ipa/gsi.h12
-rw-r--r--drivers/net/ipa/gsi_private.h6
-rw-r--r--drivers/net/ipa/gsi_trans.h12
-rw-r--r--drivers/net/ipa/ipa_clock.c8
-rw-r--r--drivers/net/ipa/ipa_clock.h10
-rw-r--r--drivers/net/ipa/ipa_cmd.h10
-rw-r--r--drivers/net/ipa/ipa_endpoint.c304
-rw-r--r--drivers/net/ipa/ipa_gsi.h13
-rw-r--r--drivers/net/ipa/ipa_interrupt.h2
-rw-r--r--drivers/net/ipa/ipa_main.c13
-rw-r--r--drivers/net/ipa/ipa_mem.c7
-rw-r--r--drivers/net/ipa/ipa_reg.h60
-rw-r--r--drivers/net/ipa/ipa_smp2p.h2
-rw-r--r--drivers/net/ipa/ipa_table.c3
-rw-r--r--drivers/net/ipa/ipa_table.h4
-rw-r--r--drivers/net/ipa/ipa_uc.c15
-rw-r--r--drivers/net/netdevsim/Makefile2
-rw-r--r--drivers/net/netdevsim/bpf.c4
-rw-r--r--drivers/net/netdevsim/dev.c17
-rw-r--r--drivers/net/netdevsim/netdev.c14
-rw-r--r--drivers/net/netdevsim/netdevsim.h21
-rw-r--r--drivers/net/netdevsim/udp_tunnels.c192
-rw-r--r--drivers/net/phy/Kconfig6
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/adin.c12
-rw-r--r--drivers/net/phy/at803x.c85
-rw-r--r--drivers/net/phy/dp83640.c5
-rw-r--r--drivers/net/phy/dp83822.c79
-rw-r--r--drivers/net/phy/dp83869.c53
-rw-r--r--drivers/net/phy/marvell.c268
-rw-r--r--drivers/net/phy/marvell10g.c22
-rw-r--r--drivers/net/phy/mdio-boardinfo.c3
-rw-r--r--drivers/net/phy/mdio-cavium.h14
-rw-r--r--drivers/net/phy/mdio-mux-gpio.c11
-rw-r--r--drivers/net/phy/mdio-octeon.c11
-rw-r--r--drivers/net/phy/mdio-thunder.c2
-rw-r--r--drivers/net/phy/mdio_bus.c127
-rw-r--r--drivers/net/phy/mdio_device.c19
-rw-r--r--drivers/net/phy/mdio_devres.c133
-rw-r--r--drivers/net/phy/mscc/Makefile4
-rw-r--r--drivers/net/phy/mscc/mscc.h63
-rw-r--r--drivers/net/phy/mscc/mscc_fc_buffer.h2
-rw-r--r--drivers/net/phy/mscc/mscc_mac.h2
-rw-r--r--drivers/net/phy/mscc/mscc_macsec.c22
-rw-r--r--drivers/net/phy/mscc/mscc_macsec.h2
-rw-r--r--drivers/net/phy/mscc/mscc_main.c111
-rw-r--r--drivers/net/phy/mscc/mscc_ptp.c1590
-rw-r--r--drivers/net/phy/mscc/mscc_ptp.h477
-rw-r--r--drivers/net/phy/phy-c45.c4
-rw-r--r--drivers/net/phy/phy-core.c17
-rw-r--r--drivers/net/phy/phy.c48
-rw-r--r--drivers/net/phy/phy_device.c324
-rw-r--r--drivers/net/phy/phylink.c431
-rw-r--r--drivers/net/phy/realtek.c12
-rw-r--r--drivers/net/phy/sfp.c54
-rw-r--r--drivers/net/plip/plip.c4
-rw-r--r--drivers/net/ppp/pppoe.c2
-rw-r--r--drivers/net/ppp/pptp.c2
-rw-r--r--drivers/net/thunderbolt.c4
-rw-r--r--drivers/net/tun.c17
-rw-r--r--drivers/net/usb/cdc_ether.c7
-rw-r--r--drivers/net/usb/cdc_ncm.c4
-rw-r--r--drivers/net/usb/hso.c16
-rw-r--r--drivers/net/usb/ipheth.c2
-rw-r--r--drivers/net/usb/usbnet.c3
-rw-r--r--drivers/net/veth.c15
-rw-r--r--drivers/net/virtio_net.c17
-rw-r--r--drivers/net/vrf.c468
-rw-r--r--drivers/net/vxlan.c57
-rw-r--r--drivers/net/wan/c101.c2
-rw-r--r--drivers/net/wan/cosa.c4
-rw-r--r--drivers/net/wan/farsync.c37
-rw-r--r--drivers/net/wan/lmc/lmc_main.c2
-rw-r--r--drivers/net/wan/n2.c2
-rw-r--r--drivers/net/wan/pc300too.c2
-rw-r--r--drivers/net/wan/pci200syn.c2
-rw-r--r--drivers/net/wan/wanxl.c54
-rw-r--r--drivers/net/wireless/Kconfig6
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/admtek/adm8211.c25
-rw-r--r--drivers/net/wireless/ath/Kconfig4
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c9
-rw-r--r--drivers/net/wireless/ath/ath10k/usb.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/Kconfig9
-rw-r--r--drivers/net/wireless/ath/ath11k/Makefile4
-rw-r--r--drivers/net/wireless/ath/ath11k/core.c10
-rw-r--r--drivers/net/wireless/ath/ath11k/core.h52
-rw-r--r--drivers/net/wireless/ath/ath11k/dbring.c356
-rw-r--r--drivers/net/wireless/ath/ath11k/dbring.h79
-rw-r--r--drivers/net/wireless/ath/ath11k/debug.c128
-rw-r--r--drivers/net/wireless/ath/ath11k/dp.c3
-rw-r--r--drivers/net/wireless/ath/ath11k/dp.h42
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_rx.c36
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_tx.c7
-rw-r--r--drivers/net/wireless/ath/ath11k/mac.c222
-rw-r--r--drivers/net/wireless/ath/ath11k/reg.c4
-rw-r--r--drivers/net/wireless/ath/ath11k/spectral.c1023
-rw-r--r--drivers/net/wireless/ath/ath11k/spectral.h82
-rw-r--r--drivers/net/wireless/ath/ath11k/wmi.c690
-rw-r--r--drivers/net/wireless/ath/ath11k/wmi.h184
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/Kconfig2
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c2
-rw-r--r--drivers/net/wireless/ath/spectral_common.h17
-rw-r--r--drivers/net/wireless/ath/wil6210/Kconfig2
-rw-r--r--drivers/net/wireless/atmel/at76c50x-usb.c2
-rw-r--r--drivers/net/wireless/broadcom/b43/main.c16
-rw-r--r--drivers/net/wireless/broadcom/b43/phy_common.c2
-rw-r--r--drivers/net/wireless/broadcom/b43/phy_g.c12
-rw-r--r--drivers/net/wireless/broadcom/b43/phy_ht.c2
-rw-r--r--drivers/net/wireless/broadcom/b43/phy_lp.c2
-rw-r--r--drivers/net/wireless/broadcom/b43/phy_n.c150
-rw-r--r--drivers/net/wireless/broadcom/b43/radio_2056.c2
-rw-r--r--drivers/net/wireless/broadcom/b43/tables_nphy.c4
-rw-r--r--drivers/net/wireless/broadcom/b43legacy/main.c12
-rw-r--r--drivers/net/wireless/broadcom/b43legacy/phy.c8
-rw-r--r--drivers/net/wireless/broadcom/b43legacy/radio.c8
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c56
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c75
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c19
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c5
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c59
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c62
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h6
-rw-r--r--drivers/net/wireless/cisco/airo.c43
-rw-r--r--drivers/net/wireless/intel/ipw2x00/Kconfig8
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2100.c156
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2200.c86
-rw-r--r--drivers/net/wireless/intel/iwlegacy/4965-mac.c2
-rw-r--r--drivers/net/wireless/intel/iwlegacy/4965-rs.c2
-rw-r--r--drivers/net/wireless/intel/iwlegacy/common.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/Kconfig2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/commands.h12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/tx.h14
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/debugfs.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-config.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c8
-rw-r--r--drivers/net/wireless/intersil/Kconfig2
-rw-r--r--drivers/net/wireless/intersil/hostap/hostap_hw.c6
-rw-r--r--drivers/net/wireless/intersil/hostap/hostap_pci.c34
-rw-r--r--drivers/net/wireless/intersil/orinoco/Kconfig4
-rw-r--r--drivers/net/wireless/intersil/orinoco/orinoco_nortel.c3
-rw-r--r--drivers/net/wireless/intersil/orinoco/orinoco_pci.c3
-rw-r--r--drivers/net/wireless/intersil/orinoco/orinoco_pci.h32
-rw-r--r--drivers/net/wireless/intersil/orinoco/orinoco_plx.c3
-rw-r--r--drivers/net/wireless/intersil/orinoco/orinoco_tmd.c3
-rw-r--r--drivers/net/wireless/intersil/orinoco/orinoco_usb.c6
-rw-r--r--drivers/net/wireless/intersil/p54/Kconfig6
-rw-r--r--drivers/net/wireless/intersil/p54/fwio.c2
-rw-r--r--drivers/net/wireless/intersil/p54/p54pci.c65
-rw-r--r--drivers/net/wireless/intersil/p54/p54usb.c2
-rw-r--r--drivers/net/wireless/intersil/prism54/isl_oid.h2
-rw-r--r--drivers/net/wireless/intersil/prism54/islpci_dev.c30
-rw-r--r--drivers/net/wireless/intersil/prism54/islpci_eth.c24
-rw-r--r--drivers/net/wireless/intersil/prism54/islpci_hotplug.c39
-rw-r--r--drivers/net/wireless/intersil/prism54/islpci_mgt.c21
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cfg80211.c21
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sdio.h4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sta_cmd.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c22
-rw-r--r--drivers/net/wireless/mediatek/mt76/Kconfig4
-rw-r--r--drivers/net/wireless/mediatek/mt76/Makefile3
-rw-r--r--drivers/net/wireless/mediatek/mt76/debugfs.c7
-rw-r--r--drivers/net/wireless/mediatek/mt76/dma.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/eeprom.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mac80211.c37
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76.h115
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7603/main.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/Kconfig19
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/Makefile7
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c102
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/dma.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/init.c17
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mac.c312
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mac.h5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/main.c332
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mcu.c371
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mcu.h54
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mmio.c49
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h95
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/pci.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/regs.h33
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/sdio.c478
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/sdio.h115
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c162
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c268
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/testmode.c363
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/usb.c246
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/usb_init.c145
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c7
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c394
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x0/usb.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02.h1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c7
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_util.c8
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2/pci.c70
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c17
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2/usb.c8
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c11
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/dma.c21
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/init.c44
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mac.c93
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mac.h17
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/main.c13
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mcu.c117
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mcu.h6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h35
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/pci.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/regs.h5
-rw-r--r--drivers/net/wireless/mediatek/mt76/pci.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/sdio.c368
-rw-r--r--drivers/net/wireless/mediatek/mt76/testmode.c497
-rw-r--r--drivers/net/wireless/mediatek/mt76/testmode.h156
-rw-r--r--drivers/net/wireless/mediatek/mt76/tx.c47
-rw-r--r--drivers/net/wireless/mediatek/mt76/usb.c90
-rw-r--r--drivers/net/wireless/mediatek/mt76/util.c4
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/mcu.c4
-rw-r--r--drivers/net/wireless/microchip/Kconfig15
-rw-r--r--drivers/net/wireless/microchip/Makefile2
-rw-r--r--drivers/net/wireless/microchip/wilc1000/Kconfig (renamed from drivers/staging/wilc1000/Kconfig)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/Makefile (renamed from drivers/staging/wilc1000/Makefile)3
-rw-r--r--drivers/net/wireless/microchip/wilc1000/cfg80211.c (renamed from drivers/staging/wilc1000/cfg80211.c)2
-rw-r--r--drivers/net/wireless/microchip/wilc1000/cfg80211.h (renamed from drivers/staging/wilc1000/cfg80211.h)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/fw.h (renamed from drivers/staging/wilc1000/fw.h)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/hif.c (renamed from drivers/staging/wilc1000/hif.c)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/hif.h (renamed from drivers/staging/wilc1000/hif.h)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/mon.c (renamed from drivers/staging/wilc1000/mon.c)3
-rw-r--r--drivers/net/wireless/microchip/wilc1000/netdev.c (renamed from drivers/staging/wilc1000/netdev.c)35
-rw-r--r--drivers/net/wireless/microchip/wilc1000/netdev.h (renamed from drivers/staging/wilc1000/netdev.h)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/sdio.c (renamed from drivers/staging/wilc1000/sdio.c)6
-rw-r--r--drivers/net/wireless/microchip/wilc1000/spi.c (renamed from drivers/staging/wilc1000/spi.c)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/wlan.c (renamed from drivers/staging/wilc1000/wlan.c)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/wlan.h (renamed from drivers/staging/wilc1000/wlan.h)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/wlan_cfg.c (renamed from drivers/staging/wilc1000/wlan_cfg.c)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/wlan_cfg.h (renamed from drivers/staging/wilc1000/wlan_cfg.h)0
-rw-r--r--drivers/net/wireless/microchip/wilc1000/wlan_if.h (renamed from drivers/staging/wilc1000/wlan_if.h)0
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/core.c5
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2400pci.c3
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2500pci.c3
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800pci.c3
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00.h5
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00dev.c4
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00pci.c31
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00pci.h9
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00soc.c2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00usb.c2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt61pci.c3
-rw-r--r--drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c23
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c8
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/ps.c12
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c138
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/usb.c12
-rw-r--r--drivers/net/wireless/realtek/rtw88/Kconfig14
-rw-r--r--drivers/net/wireless/realtek/rtw88/Makefile6
-rw-r--r--drivers/net/wireless/realtek/rtw88/bf.c5
-rw-r--r--drivers/net/wireless/realtek/rtw88/coex.c101
-rw-r--r--drivers/net/wireless/realtek/rtw88/coex.h3
-rw-r--r--drivers/net/wireless/realtek/rtw88/debug.c30
-rw-r--r--drivers/net/wireless/realtek/rtw88/fw.c17
-rw-r--r--drivers/net/wireless/realtek/rtw88/fw.h2
-rw-r--r--drivers/net/wireless/realtek/rtw88/mac80211.c27
-rw-r--r--drivers/net/wireless/realtek/rtw88/main.c23
-rw-r--r--drivers/net/wireless/realtek/rtw88/main.h13
-rw-r--r--drivers/net/wireless/realtek/rtw88/pci.c9
-rw-r--r--drivers/net/wireless/realtek/rtw88/reg.h5
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8723d.c13
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821c.c1853
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821c.h259
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821c_table.c6611
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821c_table.h15
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821ce.c30
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821ce.h14
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822b.c7
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822c.c10
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822ce.c4
-rw-r--r--drivers/net/wireless/realtek/rtw88/tx.c104
-rw-r--r--drivers/net/wireless/realtek/rtw88/tx.h13
-rw-r--r--drivers/net/wireless/ti/wl1251/event.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c84
-rw-r--r--drivers/net/wireless/zydas/zd1211rw/zd_usb.c4
-rw-r--r--drivers/net/xen-netback/common.h4
-rw-r--r--drivers/net/xen-netback/interface.c2
-rw-r--r--drivers/net/xen-netback/netback.c7
-rw-r--r--drivers/net/xen-netback/rx.c15
-rw-r--r--drivers/net/xen-netback/xenbus.c34
-rw-r--r--drivers/net/xen-netfront.c319
-rw-r--r--drivers/of/of_mdio.c4
-rw-r--r--drivers/ptp/idt8a340_reg.h48
-rw-r--r--drivers/ptp/ptp_chardev.c46
-rw-r--r--drivers/ptp/ptp_clockmatrix.c1145
-rw-r--r--drivers/ptp/ptp_clockmatrix.h61
-rw-r--r--drivers/ptp/ptp_pch.c37
-rw-r--r--drivers/s390/net/ism_drv.c2
-rw-r--r--drivers/s390/net/qeth_core.h10
-rw-r--r--drivers/s390/net/qeth_core_main.c269
-rw-r--r--drivers/s390/net/qeth_core_mpc.c16
-rw-r--r--drivers/s390/net/qeth_core_mpc.h17
-rw-r--r--drivers/s390/net/qeth_core_sys.c20
-rw-r--r--drivers/s390/net/qeth_l2_main.c14
-rw-r--r--drivers/s390/net/qeth_l3_main.c20
-rw-r--r--drivers/scsi/qedf/qedf_main.c78
-rw-r--r--drivers/ssb/driver_chipcommon.c4
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c2
-rw-r--r--drivers/ssb/sprom.c2
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/octeon/ethernet-mdio.c2
-rw-r--r--drivers/staging/octeon/ethernet-mdio.h2
-rw-r--r--drivers/staging/octeon/ethernet.c3
-rw-r--r--drivers/staging/wilc1000/microchip,wilc1000.yaml71
1092 files changed, 78245 insertions, 30375 deletions
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index 8007e051876c..b9370bbca828 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -306,8 +306,9 @@ config ATM_IA
for more info about the cards. Say Y (or M to compile as a module
named iphase) here if you have one of these cards.
- See the file <file:Documentation/networking/iphase.rst> for further
- details.
+ See the file
+ <file:Documentation/networking/device_drivers/atm/iphase.rst>
+ for further details.
config ATM_IA_DEBUG
bool "Enable debugging messages"
@@ -336,7 +337,8 @@ config ATM_FORE200E
on PCI and SBUS hosts. Say Y (or M to compile as a module
named fore_200e) here if you have one of these ATM adapters.
- See the file <file:Documentation/networking/fore200e.rst> for
+ See the file
+ <file:Documentation/networking/device_drivers/atm/fore200e.rst> for
further details.
config ATM_FORE200E_USE_TASKLET
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 17d47ad03ab7..39be444534d0 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -1034,6 +1034,7 @@ static enum enq_res do_tx(struct sk_buff *skb)
u32 dma_rd,dma_wr;
u32 size; /* in words */
int aal5,dma_size,i,j;
+ unsigned char skb_data3;
DPRINTK(">do_tx\n");
NULLCHECK(skb);
@@ -1108,6 +1109,7 @@ DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags);
vcc->dev->number);
return enq_jam;
}
+ skb_data3 = skb->data[3];
paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len,
DMA_TO_DEVICE);
ENI_PRV_PADDR(skb) = paddr;
@@ -1150,7 +1152,7 @@ DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
(size/(ATM_CELL_PAYLOAD/4)),tx->send+tx->tx_pos*4);
/*printk("dsc = 0x%08lx\n",(unsigned long) readl(tx->send+tx->tx_pos*4));*/
writel((vcc->vci << MID_SEG_VCI_SHIFT) |
- (aal5 ? 0 : (skb->data[3] & 0xf)) |
+ (aal5 ? 0 : (skb_data3 & 0xf)) |
(ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ? MID_SEG_CLP : 0),
tx->send+((tx->tx_pos+1) & (tx->words-1))*4);
DPRINTK("size: %d, len:%d\n",size,skb->len);
@@ -2027,21 +2029,6 @@ static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
return dev->phy->ioctl(dev,cmd,arg);
}
-
-static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen)
-{
- return -EINVAL;
-}
-
-
-static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,unsigned int optlen)
-{
- return -EINVAL;
-}
-
-
static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb)
{
enum enq_res res;
@@ -2215,8 +2202,6 @@ static const struct atmdev_ops ops = {
.open = eni_open,
.close = eni_close,
.ioctl = eni_ioctl,
- .getsockopt = eni_getsockopt,
- .setsockopt = eni_setsockopt,
.send = eni_send,
.phy_put = eni_phy_put,
.phy_get = eni_phy_get,
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index cc87004d5e2d..2ca9ec802734 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1277,8 +1277,6 @@ static const struct atmdev_ops ops = {
.send = fs_send,
.owner = THIS_MODULE,
/* ioctl: fs_ioctl, */
- /* getsockopt: fs_getsockopt, */
- /* setsockopt: fs_setsockopt, */
/* change_qos: fs_change_qos, */
/* For now implement these internally here... */
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index f4ad7ce25ae8..a81bc49c14ac 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -1710,31 +1710,6 @@ fore200e_getstats(struct fore200e* fore200e)
return 0;
}
-
-static int
-fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
-{
- /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
-
- DPRINTK(2, "getsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
- vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
-
- return -EINVAL;
-}
-
-
-static int
-fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
-{
- /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
-
- DPRINTK(2, "setsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
- vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
-
- return -EINVAL;
-}
-
-
#if 0 /* currently unused */
static int
fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
@@ -3026,8 +3001,6 @@ static const struct atmdev_ops fore200e_ops = {
.open = fore200e_open,
.close = fore200e_close,
.ioctl = fore200e_ioctl,
- .getsockopt = fore200e_getsockopt,
- .setsockopt = fore200e_setsockopt,
.send = fore200e_send,
.change_qos = fore200e_change_qos,
.proc_read = fore200e_proc_read,
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index e5da51f907a2..4f2951cbe69c 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2528,46 +2528,6 @@ static void hrz_close (struct atm_vcc * atm_vcc) {
}
#if 0
-static int hrz_getsockopt (struct atm_vcc * atm_vcc, int level, int optname,
- void *optval, int optlen) {
- hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
- PRINTD (DBG_FLOW|DBG_VCC, "hrz_getsockopt");
- switch (level) {
- case SOL_SOCKET:
- switch (optname) {
-// case SO_BCTXOPT:
-// break;
-// case SO_BCRXOPT:
-// break;
- default:
- return -ENOPROTOOPT;
- };
- break;
- }
- return -EINVAL;
-}
-
-static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname,
- void *optval, unsigned int optlen) {
- hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
- PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt");
- switch (level) {
- case SOL_SOCKET:
- switch (optname) {
-// case SO_BCTXOPT:
-// break;
-// case SO_BCRXOPT:
-// break;
- default:
- return -ENOPROTOOPT;
- };
- break;
- }
- return -EINVAL;
-}
-#endif
-
-#if 0
static int hrz_ioctl (struct atm_dev * atm_dev, unsigned int cmd, void *arg) {
hrz_dev * dev = HRZ_DEV(atm_dev);
PRINTD (DBG_FLOW, "hrz_ioctl");
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index df51680e8931..65a3886f68c9 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -835,6 +835,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
unsigned long flags;
int error;
int aal;
+ u32 word4;
if (skb->len == 0) {
printk("%s: invalid skb->len (%d)\n", card->name, skb->len);
@@ -846,6 +847,8 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
tbd = &IDT77252_PRV_TBD(skb);
vcc = ATM_SKB(skb)->vcc;
+ word4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
+ (skb->data[2] << 8) | (skb->data[3] << 0);
IDT77252_PRV_PADDR(skb) = dma_map_single(&card->pcidev->dev, skb->data,
skb->len, DMA_TO_DEVICE);
@@ -859,8 +862,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
tbd->word_1 = SAR_TBD_OAM | ATM_CELL_PAYLOAD | SAR_TBD_EPDU;
tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
tbd->word_3 = 0x00000000;
- tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
- (skb->data[2] << 8) | (skb->data[3] << 0);
+ tbd->word_4 = word4;
if (test_bit(VCF_RSV, &vc->flags))
vc = card->vcs[0];
@@ -890,8 +892,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
tbd->word_3 = 0x00000000;
- tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
- (skb->data[2] << 8) | (skb->data[3] << 0);
+ tbd->word_4 = word4;
break;
case ATM_AAL5:
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 8c7a996d1f16..eef637fd90b3 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -2880,20 +2880,6 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
return 0;
}
-static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,
- void __user *optval, int optlen)
-{
- IF_EVENT(printk(">ia_getsockopt\n");)
- return -EINVAL;
-}
-
-static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,
- void __user *optval, unsigned int optlen)
-{
- IF_EVENT(printk(">ia_setsockopt\n");)
- return -EINVAL;
-}
-
static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
IADEV *iadev;
struct dle *wr_ptr;
@@ -3164,8 +3150,6 @@ static const struct atmdev_ops ops = {
.open = ia_open,
.close = ia_close,
.ioctl = ia_ioctl,
- .getsockopt = ia_getsockopt,
- .setsockopt = ia_setsockopt,
.send = ia_send,
.phy_put = ia_phy_put,
.phy_get = ia_phy_get,
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 645a6bc1df88..986c1313694c 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -2537,8 +2537,6 @@ static const struct atmdev_ops ops = {
.dev_close = lanai_dev_close,
.open = lanai_open,
.close = lanai_close,
- .getsockopt = NULL,
- .setsockopt = NULL,
.send = lanai_send,
.phy_put = NULL,
.phy_get = NULL,
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index c32f7dd9879a..94fbc3abe60e 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Driver for the Solos PCI ADSL2+ card, designed to support Linux by
- * Traverse Technologies -- http://www.traverse.com.au/
+ * Traverse Technologies -- https://www.traverse.com.au/
* Xrio Limited -- http://www.xrio.com/
*
* Copyright © 2008 Traverse Technologies
@@ -1179,8 +1179,6 @@ static const struct atmdev_ops fpga_ops = {
.open = popen,
.close = pclose,
.ioctl = NULL,
- .getsockopt = NULL,
- .setsockopt = NULL,
.send = psend,
.send_oam = NULL,
.phy_put = NULL,
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 165eebe06e39..ee059c77e3bb 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1515,20 +1515,6 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
}
}
-
-static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen)
-{
- return -EINVAL;
-}
-
-
-static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,unsigned int optlen)
-{
- return -EINVAL;
-}
-
static int zatm_send(struct atm_vcc *vcc,struct sk_buff *skb)
{
int error;
@@ -1582,8 +1568,6 @@ static const struct atmdev_ops ops = {
.open = zatm_open,
.close = zatm_close,
.ioctl = zatm_ioctl,
- .getsockopt = zatm_getsockopt,
- .setsockopt = zatm_setsockopt,
.send = zatm_send,
.phy_put = zatm_phy_put,
.phy_get = zatm_phy_get,
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index a5df3d111334..8a1e4705bc87 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -122,6 +122,7 @@ static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
static int bcma_gpio_irq_init(struct bcma_drv_cc *cc)
{
struct gpio_chip *chip = &cc->gpio;
+ struct gpio_irq_chip *girq = &chip->irq;
int hwirq, err;
if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
@@ -136,15 +137,13 @@ static int bcma_gpio_irq_init(struct bcma_drv_cc *cc)
bcma_chipco_gpio_intmask(cc, ~0, 0);
bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
- err = gpiochip_irqchip_add(chip,
- &bcma_gpio_irq_chip,
- 0,
- handle_simple_irq,
- IRQ_TYPE_NONE);
- if (err) {
- free_irq(hwirq, cc);
- return err;
- }
+ girq->chip = &bcma_gpio_irq_chip;
+ /* This will let us handle the parent IRQ in the driver */
+ girq->parent_handler = NULL;
+ girq->num_parents = 0;
+ girq->parents = NULL;
+ girq->default_type = IRQ_TYPE_NONE;
+ girq->handler = handle_simple_irq;
return 0;
}
@@ -212,13 +211,13 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
else
chip->base = -1;
- err = gpiochip_add_data(chip, cc);
+ err = bcma_gpio_irq_init(cc);
if (err)
return err;
- err = bcma_gpio_irq_init(cc);
+ err = gpiochip_add_data(chip, cc);
if (err) {
- gpiochip_remove(chip);
+ bcma_gpio_irq_exit(cc);
return err;
}
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 1a942f734188..d49e7c0de2b6 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -219,7 +219,7 @@ static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 __iomem **eromptr)
static u32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
u32 type, u8 port)
{
- u32 addrl, addrh, sizeh = 0;
+ u32 addrl;
u32 size;
u32 ent = bcma_erom_get_ent(bus, eromptr);
@@ -233,14 +233,12 @@ static u32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
addrl = ent & SCAN_ADDR_ADDR;
if (ent & SCAN_ADDR_AG32)
- addrh = bcma_erom_get_ent(bus, eromptr);
- else
- addrh = 0;
+ bcma_erom_get_ent(bus, eromptr);
if ((ent & SCAN_ADDR_SZ) == SCAN_ADDR_SZ_SZD) {
size = bcma_erom_get_ent(bus, eromptr);
if (size & SCAN_SIZE_SG32)
- sizeh = bcma_erom_get_ent(bus, eromptr);
+ bcma_erom_get_ent(bus, eromptr);
}
return addrl;
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 3b176257b993..e667933c3d70 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -106,7 +106,7 @@ static void bcm203x_complete(struct urb *urb)
}
data->state = BCM203X_LOAD_FIRMWARE;
- /* fall through */
+ fallthrough;
case BCM203X_LOAD_FIRMWARE:
if (data->fw_sent == data->fw_size) {
usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP),
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index cc6e56223656..36eabf61717f 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -295,7 +295,6 @@ static void bluecard_write_wakeup(struct bluecard_info *info)
baud_reg = REG_CONTROL_BAUD_RATE_115200;
break;
case PKT_BAUD_RATE_57600:
- /* Fall through... */
default:
baud_reg = REG_CONTROL_BAUD_RATE_57600;
break;
@@ -585,7 +584,6 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
hci_skb_pkt_type(skb) = PKT_BAUD_RATE_115200;
break;
case 57600:
- /* Fall through... */
default:
cmd[4] = 0x03;
hci_skb_pkt_type(skb) = PKT_BAUD_RATE_57600;
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 6a0e2c5a8beb..5fa5be3c5598 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -754,6 +754,65 @@ void btintel_reset_to_bootloader(struct hci_dev *hdev)
}
EXPORT_SYMBOL_GPL(btintel_reset_to_bootloader);
+int btintel_read_debug_features(struct hci_dev *hdev,
+ struct intel_debug_features *features)
+{
+ struct sk_buff *skb;
+ u8 page_no = 1;
+
+ /* Intel controller supports two pages, each page is of 128-bit
+ * feature bit mask. And each bit defines specific feature support
+ */
+ skb = __hci_cmd_sync(hdev, 0xfca6, sizeof(page_no), &page_no,
+ HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Reading supported features failed (%ld)",
+ PTR_ERR(skb));
+ return PTR_ERR(skb);
+ }
+
+ if (skb->len != (sizeof(features->page1) + 3)) {
+ bt_dev_err(hdev, "Supported features event size mismatch");
+ kfree_skb(skb);
+ return -EILSEQ;
+ }
+
+ memcpy(features->page1, skb->data + 3, sizeof(features->page1));
+
+ /* Read the supported features page2 if required in future.
+ */
+ kfree_skb(skb);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(btintel_read_debug_features);
+
+int btintel_set_debug_features(struct hci_dev *hdev,
+ const struct intel_debug_features *features)
+{
+ u8 mask[11] = { 0x0a, 0x92, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00 };
+ struct sk_buff *skb;
+
+ if (!features)
+ return -EINVAL;
+
+ if (!(features->page1[0] & 0x3f)) {
+ bt_dev_info(hdev, "Telemetry exception format not supported");
+ return 0;
+ }
+
+ skb = __hci_cmd_sync(hdev, 0xfc8b, 11, mask, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Setting Intel telemetry ddc write event mask failed (%ld)",
+ PTR_ERR(skb));
+ return PTR_ERR(skb);
+ }
+
+ kfree_skb(skb);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(btintel_set_debug_features);
+
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth support for Intel devices ver " VERSION);
MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h
index a69ea8a87b9b..08e20606fb58 100644
--- a/drivers/bluetooth/btintel.h
+++ b/drivers/bluetooth/btintel.h
@@ -62,6 +62,10 @@ struct intel_reset {
__le32 boot_param;
} __packed;
+struct intel_debug_features {
+ __u8 page1[16];
+} __packed;
+
#if IS_ENABLED(CONFIG_BT_INTEL)
int btintel_check_bdaddr(struct hci_dev *hdev);
@@ -88,6 +92,10 @@ int btintel_read_boot_params(struct hci_dev *hdev,
int btintel_download_firmware(struct hci_dev *dev, const struct firmware *fw,
u32 *boot_param);
void btintel_reset_to_bootloader(struct hci_dev *hdev);
+int btintel_read_debug_features(struct hci_dev *hdev,
+ struct intel_debug_features *features);
+int btintel_set_debug_features(struct hci_dev *hdev,
+ const struct intel_debug_features *features);
#else
static inline int btintel_check_bdaddr(struct hci_dev *hdev)
@@ -186,4 +194,17 @@ static inline int btintel_download_firmware(struct hci_dev *dev,
static inline void btintel_reset_to_bootloader(struct hci_dev *hdev)
{
}
+
+static inline int btintel_read_debug_features(struct hci_dev *hdev,
+ struct intel_debug_features *features)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int btintel_set_debug_features(struct hci_dev *hdev,
+ const struct intel_debug_features *features)
+{
+ return -EOPNOTSUPP;
+}
+
#endif
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 708ad21683eb..8b9d78ce6bb2 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -587,6 +587,14 @@ static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
return 0;
}
+static bool btmrvl_prevent_wake(struct hci_dev *hdev)
+{
+ struct btmrvl_private *priv = hci_get_drvdata(hdev);
+ struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
+
+ return !device_may_wakeup(&card->func->dev);
+}
+
/*
* This function handles the event generated by firmware, rx data
* received from firmware, and tx data sent from kernel.
@@ -669,6 +677,7 @@ static int btmrvl_service_main_thread(void *data)
int btmrvl_register_hdev(struct btmrvl_private *priv)
{
struct hci_dev *hdev = NULL;
+ struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
int ret;
hdev = hci_alloc_dev();
@@ -687,6 +696,8 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
hdev->send = btmrvl_send_frame;
hdev->setup = btmrvl_setup;
hdev->set_bdaddr = btmrvl_set_bdaddr;
+ hdev->prevent_wake = btmrvl_prevent_wake;
+ SET_HCIDEV_DEV(hdev, &card->func->dev);
hdev->dev_type = priv->btmrvl_dev.dev_type;
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index a296f8526433..d15fd5be0216 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -111,6 +111,9 @@ static int btmrvl_sdio_probe_of(struct device *dev,
"Failed to request irq_bt %d (%d)\n",
cfg->irq_bt, ret);
}
+
+ /* Configure wakeup (enabled by default) */
+ device_init_wakeup(dev, true);
disable_irq(cfg->irq_bt);
}
}
@@ -328,7 +331,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8977 = {
.helper = NULL,
- .firmware = "mrvl/sd8977_uapsta.bin",
+ .firmware = "mrvl/sdsd8977_combo_v2.bin",
.reg = &btmrvl_reg_8977,
.support_pscan_win_report = true,
.sd_blksz_fw_dl = 256,
@@ -346,7 +349,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8987 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8997 = {
.helper = NULL,
- .firmware = "mrvl/sd8997_uapsta.bin",
+ .firmware = "mrvl/sdsd8997_combo_v4.bin",
.reg = &btmrvl_reg_8997,
.support_pscan_win_report = true,
.sd_blksz_fw_dl = 256,
@@ -1654,6 +1657,7 @@ static void btmrvl_sdio_remove(struct sdio_func *func)
MODULE_SHUTDOWN_REQ);
btmrvl_sdio_disable_host_int(card);
}
+
BT_DBG("unregister dev");
card->priv->surprise_removed = true;
btmrvl_sdio_unregister_dev(card);
@@ -1690,7 +1694,8 @@ static int btmrvl_sdio_suspend(struct device *dev)
}
/* Enable platform specific wakeup interrupt */
- if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) {
+ if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 &&
+ device_may_wakeup(dev)) {
card->plt_wake_cfg->wake_by_bt = false;
enable_irq(card->plt_wake_cfg->irq_bt);
enable_irq_wake(card->plt_wake_cfg->irq_bt);
@@ -1707,7 +1712,8 @@ static int btmrvl_sdio_suspend(struct device *dev)
BT_ERR("HS not activated, suspend failed!");
/* Disable platform specific wakeup interrupt */
if (card->plt_wake_cfg &&
- card->plt_wake_cfg->irq_bt >= 0) {
+ card->plt_wake_cfg->irq_bt >= 0 &&
+ device_may_wakeup(dev)) {
disable_irq_wake(card->plt_wake_cfg->irq_bt);
disable_irq(card->plt_wake_cfg->irq_bt);
}
@@ -1767,7 +1773,8 @@ static int btmrvl_sdio_resume(struct device *dev)
hci_resume_dev(hcidev);
/* Disable platform specific wakeup interrupt */
- if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) {
+ if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 &&
+ device_may_wakeup(dev)) {
disable_irq_wake(card->plt_wake_cfg->irq_bt);
disable_irq(card->plt_wake_cfg->irq_bt);
if (card->plt_wake_cfg->wake_by_bt)
@@ -1831,6 +1838,6 @@ MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
-MODULE_FIRMWARE("mrvl/sd8977_uapsta.bin");
+MODULE_FIRMWARE("mrvl/sdsd8977_combo_v2.bin");
MODULE_FIRMWARE("mrvl/sd8987_uapsta.bin");
-MODULE_FIRMWARE("mrvl/sd8997_uapsta.bin");
+MODULE_FIRMWARE("mrvl/sdsd8997_combo_v4.bin");
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index bff095be2f97..c7ab7a23bd67 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -685,7 +685,7 @@ static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
const u8 *fw_ptr;
size_t fw_size;
int err, dlen;
- u8 flag;
+ u8 flag, param;
err = request_firmware(&fw, fwname, &hdev->dev);
if (err < 0) {
@@ -693,6 +693,20 @@ static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
return err;
}
+ /* Power on data RAM the firmware relies on. */
+ param = 1;
+ wmt_params.op = MTK_WMT_FUNC_CTRL;
+ wmt_params.flag = 3;
+ wmt_params.dlen = sizeof(param);
+ wmt_params.data = &param;
+ wmt_params.status = NULL;
+
+ err = mtk_hci_wmt_sync(hdev, &wmt_params);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
+ return err;
+ }
+
fw_ptr = fw->data;
fw_size = fw->size;
diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index c5984966f315..ce9dcffdc5bf 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -400,6 +400,27 @@ out:
return ret;
}
+static int qca_disable_soc_logging(struct hci_dev *hdev)
+{
+ struct sk_buff *skb;
+ u8 cmd[2];
+ int err;
+
+ cmd[0] = QCA_DISABLE_LOGGING_SUB_OP;
+ cmd[1] = 0x00;
+ skb = __hci_cmd_sync_ev(hdev, QCA_DISABLE_LOGGING, sizeof(cmd), cmd,
+ HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ err = PTR_ERR(skb);
+ bt_dev_err(hdev, "QCA Failed to disable soc logging(%d)", err);
+ return err;
+ }
+
+ kfree_skb(skb);
+
+ return 0;
+}
+
int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
{
struct sk_buff *skb;
@@ -486,6 +507,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
return err;
}
+ if (soc_type >= QCA_WCN3991) {
+ err = qca_disable_soc_logging(hdev);
+ if (err < 0)
+ return err;
+ }
+
/* Perform HCI reset */
err = qca_send_reset(hdev);
if (err < 0) {
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index 6e1e62dd4b95..d81b74c408a5 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -14,6 +14,7 @@
#define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
#define MAX_SIZE_PER_TLV_SEGMENT (243)
#define QCA_PRE_SHUTDOWN_CMD (0xFC08)
+#define QCA_DISABLE_LOGGING (0xFC17)
#define EDL_CMD_REQ_RES_EVT (0x00)
#define EDL_PATCH_VER_RES_EVT (0x19)
@@ -22,6 +23,7 @@
#define EDL_CMD_EXE_STATUS_EVT (0x00)
#define EDL_SET_BAUDRATE_RSP_EVT (0x92)
#define EDL_NVM_ACCESS_CODE_EVT (0x0B)
+#define QCA_DISABLE_LOGGING_SUB_OP (0x14)
#define EDL_TAG_ID_HCI (17)
#define EDL_TAG_ID_DEEP_SLEEP (27)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5f022e9cf667..8d2608ddfd08 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -359,6 +359,10 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
.driver_info = BTUSB_IGNORE },
+ /* Realtek 8822CE Bluetooth devices */
+ { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
+
/* Realtek Bluetooth devices */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
.driver_info = BTUSB_REALTEK },
@@ -453,6 +457,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
#define BTUSB_HW_RESET_ACTIVE 12
#define BTUSB_TX_WAIT_VND_EVT 13
#define BTUSB_WAKEUP_DISABLE 14
+#define BTUSB_USE_ALT1_FOR_WBS 15
struct btusb_data {
struct hci_dev *hdev;
@@ -511,7 +516,6 @@ struct btusb_data {
unsigned cmd_timeout_cnt;
};
-
static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
@@ -573,6 +577,23 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
gpiod_set_value_cansleep(reset_gpio, 0);
}
+static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
+{
+ struct btusb_data *data = hci_get_drvdata(hdev);
+ int err;
+
+ if (++data->cmd_timeout_cnt < 5)
+ return;
+
+ bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device.");
+ /* This is not an unbalanced PM reference since the device will reset */
+ err = usb_autopm_get_interface(data->intf);
+ if (!err)
+ usb_queue_reset_device(data->intf);
+ else
+ bt_dev_err(hdev, "Failed usb_autopm_get_interface with %d", err);
+}
+
static inline void btusb_free_frags(struct btusb_data *data)
{
unsigned long flags;
@@ -1666,14 +1687,15 @@ static void btusb_work(struct work_struct *work)
new_alts = data->sco_num;
}
} else if (data->air_mode == HCI_NOTIFY_ENABLE_SCO_TRANSP) {
-
- data->usb_alt6_packet_flow = true;
-
/* Check if Alt 6 is supported for Transparent audio */
- if (btusb_find_altsetting(data, 6))
+ if (btusb_find_altsetting(data, 6)) {
+ data->usb_alt6_packet_flow = true;
new_alts = 6;
- else
+ } else if (test_bit(BTUSB_USE_ALT1_FOR_WBS, &data->flags)) {
+ new_alts = 1;
+ } else {
bt_dev_err(hdev, "Device does not support ALT setting 6");
+ }
}
if (btusb_switch_alt_setting(hdev, new_alts) < 0)
@@ -1720,6 +1742,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
{
struct hci_rp_read_local_version *rp;
struct sk_buff *skb;
+ bool is_fake = false;
BT_DBG("%s", hdev->name);
@@ -1739,18 +1762,69 @@ static int btusb_setup_csr(struct hci_dev *hdev)
rp = (struct hci_rp_read_local_version *)skb->data;
- /* Detect controllers which aren't real CSR ones. */
+ /* Detect a wide host of Chinese controllers that aren't CSR.
+ *
+ * Known fake bcdDevices: 0x0100, 0x0134, 0x1915, 0x2520, 0x7558, 0x8891
+ *
+ * The main thing they have in common is that these are really popular low-cost
+ * options that support newer Bluetooth versions but rely on heavy VID/PID
+ * squatting of this poor old Bluetooth 1.1 device. Even sold as such.
+ *
+ * We detect actual CSR devices by checking that the HCI manufacturer code
+ * is Cambridge Silicon Radio (10) and ensuring that LMP sub-version and
+ * HCI rev values always match. As they both store the firmware number.
+ */
if (le16_to_cpu(rp->manufacturer) != 10 ||
- le16_to_cpu(rp->lmp_subver) == 0x0c5c) {
+ le16_to_cpu(rp->hci_rev) != le16_to_cpu(rp->lmp_subver))
+ is_fake = true;
+
+ /* Known legit CSR firmware build numbers and their supported BT versions:
+ * - 1.1 (0x1) -> 0x0073, 0x020d, 0x033c, 0x034e
+ * - 1.2 (0x2) -> 0x04d9, 0x0529
+ * - 2.0 (0x3) -> 0x07a6, 0x07ad, 0x0c5c
+ * - 2.1 (0x4) -> 0x149c, 0x1735, 0x1899 (0x1899 is a BlueCore4-External)
+ * - 4.0 (0x6) -> 0x1d86, 0x2031, 0x22bb
+ *
+ * e.g. Real CSR dongles with LMP subversion 0x73 are old enough that
+ * support BT 1.1 only; so it's a dead giveaway when some
+ * third-party BT 4.0 dongle reuses it.
+ */
+ else if (le16_to_cpu(rp->lmp_subver) <= 0x034e &&
+ le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_1)
+ is_fake = true;
+
+ else if (le16_to_cpu(rp->lmp_subver) <= 0x0529 &&
+ le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_2)
+ is_fake = true;
+
+ else if (le16_to_cpu(rp->lmp_subver) <= 0x0c5c &&
+ le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_0)
+ is_fake = true;
+
+ else if (le16_to_cpu(rp->lmp_subver) <= 0x1899 &&
+ le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_1)
+ is_fake = true;
+
+ else if (le16_to_cpu(rp->lmp_subver) <= 0x22bb &&
+ le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_4_0)
+ is_fake = true;
+
+ if (is_fake) {
+ bt_dev_warn(hdev, "CSR: Unbranded CSR clone detected; adding workarounds...");
+
+ /* Generally these clones have big discrepancies between
+ * advertised features and what's actually supported.
+ * Probably will need to be expanded in the future;
+ * without these the controller will lock up.
+ */
+ set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
+ set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+
/* Clear the reset quirk since this is not an actual
* early Bluetooth 1.1 device from CSR.
*/
clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
-
- /* These fake CSR controllers have all a broken
- * stored link key handling and so just disable it.
- */
- set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
+ clear_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
}
kfree_skb(skb);
@@ -2262,45 +2336,25 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
return true;
}
-static int btusb_setup_intel_new(struct hci_dev *hdev)
+static int btusb_intel_download_firmware(struct hci_dev *hdev,
+ struct intel_version *ver,
+ struct intel_boot_params *params)
{
- struct btusb_data *data = hci_get_drvdata(hdev);
- struct intel_version ver;
- struct intel_boot_params params;
const struct firmware *fw;
u32 boot_param;
char fwname[64];
- ktime_t calltime, delta, rettime;
- unsigned long long duration;
int err;
+ struct btusb_data *data = hci_get_drvdata(hdev);
- BT_DBG("%s", hdev->name);
-
- /* Set the default boot parameter to 0x0 and it is updated to
- * SKU specific boot parameter after reading Intel_Write_Boot_Params
- * command while downloading the firmware.
- */
- boot_param = 0x00000000;
-
- calltime = ktime_get();
-
- /* Read the Intel version information to determine if the device
- * is in bootloader mode or if it already has operational firmware
- * loaded.
- */
- err = btintel_read_version(hdev, &ver);
- if (err) {
- bt_dev_err(hdev, "Intel Read version failed (%d)", err);
- btintel_reset_to_bootloader(hdev);
- return err;
- }
+ if (!ver || !params)
+ return -EINVAL;
/* The hardware platform number has a fixed value of 0x37 and
* for now only accept this single value.
*/
- if (ver.hw_platform != 0x37) {
+ if (ver->hw_platform != 0x37) {
bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
- ver.hw_platform);
+ ver->hw_platform);
return -EINVAL;
}
@@ -2310,7 +2364,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
* This check has been put in place to ensure correct forward
* compatibility options when newer hardware variants come along.
*/
- switch (ver.hw_variant) {
+ switch (ver->hw_variant) {
case 0x0b: /* SfP */
case 0x0c: /* WsP */
case 0x11: /* JfP */
@@ -2320,11 +2374,11 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
break;
default:
bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
- ver.hw_variant);
+ ver->hw_variant);
return -EINVAL;
}
- btintel_version_info(hdev, &ver);
+ btintel_version_info(hdev, ver);
/* The firmware variant determines if the device is in bootloader
* mode or is running operational firmware. The value 0x06 identifies
@@ -2339,25 +2393,25 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
* It is not possible to use the Secure Boot Parameters in this
* case since that command is only available in bootloader mode.
*/
- if (ver.fw_variant == 0x23) {
+ if (ver->fw_variant == 0x23) {
clear_bit(BTUSB_BOOTLOADER, &data->flags);
btintel_check_bdaddr(hdev);
- goto finish;
+ return 0;
}
/* If the device is not in bootloader mode, then the only possible
* choice is to return an error and abort the device initialization.
*/
- if (ver.fw_variant != 0x06) {
+ if (ver->fw_variant != 0x06) {
bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
- ver.fw_variant);
+ ver->fw_variant);
return -ENODEV;
}
/* Read the secure boot parameters to identify the operating
* details of the bootloader.
*/
- err = btintel_read_boot_params(hdev, &params);
+ err = btintel_read_boot_params(hdev, params);
if (err)
return err;
@@ -2365,16 +2419,16 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
* with a command complete event. If the boot parameters indicate
* that this bootloader does not send them, then abort the setup.
*/
- if (params.limited_cce != 0x00) {
+ if (params->limited_cce != 0x00) {
bt_dev_err(hdev, "Unsupported Intel firmware loading method (%u)",
- params.limited_cce);
+ params->limited_cce);
return -EINVAL;
}
/* If the OTP has no valid Bluetooth device address, then there will
* also be no valid address for the operational firmware.
*/
- if (!bacmp(&params.otp_bdaddr, BDADDR_ANY)) {
+ if (!bacmp(&params->otp_bdaddr, BDADDR_ANY)) {
bt_dev_info(hdev, "No device address configured");
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
}
@@ -2400,7 +2454,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
* ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi.
*
*/
- err = btusb_setup_intel_new_get_fw_name(&ver, &params, fwname,
+ err = btusb_setup_intel_new_get_fw_name(ver, params, fwname,
sizeof(fwname), "sfi");
if (!err) {
bt_dev_err(hdev, "Unsupported Intel firmware naming");
@@ -2415,16 +2469,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
bt_dev_info(hdev, "Found device firmware: %s", fwname);
- /* Save the DDC file name for later use to apply once the firmware
- * downloading is done.
- */
- err = btusb_setup_intel_new_get_fw_name(&ver, &params, fwname,
- sizeof(fwname), "ddc");
- if (!err) {
- bt_dev_err(hdev, "Unsupported Intel firmware naming");
- return -EINVAL;
- }
-
if (fw->size < 644) {
bt_dev_err(hdev, "Invalid size of firmware file (%zu)",
fw->size);
@@ -2479,18 +2523,58 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
goto done;
}
+done:
+ release_firmware(fw);
+ return err;
+}
+
+static int btusb_setup_intel_new(struct hci_dev *hdev)
+{
+ struct btusb_data *data = hci_get_drvdata(hdev);
+ struct intel_version ver;
+ struct intel_boot_params params;
+ u32 boot_param;
+ char ddcname[64];
+ ktime_t calltime, delta, rettime;
+ unsigned long long duration;
+ int err;
+ struct intel_debug_features features;
+
+ BT_DBG("%s", hdev->name);
+
+ /* Set the default boot parameter to 0x0 and it is updated to
+ * SKU specific boot parameter after reading Intel_Write_Boot_Params
+ * command while downloading the firmware.
+ */
+ boot_param = 0x00000000;
+
+ calltime = ktime_get();
+
+ /* Read the Intel version information to determine if the device
+ * is in bootloader mode or if it already has operational firmware
+ * loaded.
+ */
+ err = btintel_read_version(hdev, &ver);
+ if (err) {
+ bt_dev_err(hdev, "Intel Read version failed (%d)", err);
+ btintel_reset_to_bootloader(hdev);
+ return err;
+ }
+
+ err = btusb_intel_download_firmware(hdev, &ver, &params);
+ if (err)
+ return err;
+
+ /* controller is already having an operational firmware */
+ if (ver.fw_variant == 0x23)
+ goto finish;
+
rettime = ktime_get();
delta = ktime_sub(rettime, calltime);
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration);
-done:
- release_firmware(fw);
-
- if (err < 0)
- return err;
-
calltime = ktime_get();
set_bit(BTUSB_BOOTING, &data->flags);
@@ -2534,13 +2618,28 @@ done:
clear_bit(BTUSB_BOOTLOADER, &data->flags);
- /* Once the device is running in operational mode, it needs to apply
- * the device configuration (DDC) parameters.
- *
- * The device can work without DDC parameters, so even if it fails
- * to load the file, no need to fail the setup.
+ err = btusb_setup_intel_new_get_fw_name(&ver, &params, ddcname,
+ sizeof(ddcname), "ddc");
+
+ if (!err) {
+ bt_dev_err(hdev, "Unsupported Intel firmware naming");
+ } else {
+ /* Once the device is running in operational mode, it needs to
+ * apply the device configuration (DDC) parameters.
+ *
+ * The device can work without DDC parameters, so even if it
+ * fails to load the file, no need to fail the setup.
+ */
+ btintel_load_ddc_config(hdev, ddcname);
+ }
+
+ /* Read the Intel supported features and if new exception formats
+ * supported, need to load the additional DDC config to enable.
*/
- btintel_load_ddc_config(hdev, fwname);
+ btintel_read_debug_features(hdev, &features);
+
+ /* Set DDC mask for available debug features */
+ btintel_set_debug_features(hdev, &features);
/* Read the Intel version information after loading the FW */
err = btintel_read_version(hdev, &ver);
@@ -2925,7 +3024,7 @@ static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
const u8 *fw_ptr;
size_t fw_size;
int err, dlen;
- u8 flag;
+ u8 flag, param;
err = request_firmware(&fw, fwname, &hdev->dev);
if (err < 0) {
@@ -2933,6 +3032,20 @@ static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
return err;
}
+ /* Power on data RAM the firmware relies on. */
+ param = 1;
+ wmt_params.op = BTMTK_WMT_FUNC_CTRL;
+ wmt_params.flag = 3;
+ wmt_params.dlen = sizeof(param);
+ wmt_params.data = &param;
+ wmt_params.status = NULL;
+
+ err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
+ return err;
+ }
+
fw_ptr = fw->data;
fw_size = fw->size;
@@ -3704,6 +3817,9 @@ static bool btusb_prevent_wake(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
+ if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
+ return true;
+
return !device_may_wakeup(&data->udev->dev);
}
@@ -3941,10 +4057,20 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_QCA_ROME) {
data->setup_on_usb = btusb_setup_qca;
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
+ hdev->cmd_timeout = btusb_qca_cmd_timeout;
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
btusb_check_needs_reset_resume(intf);
}
+ if (id->driver_info & BTUSB_AMP) {
+ /* AMP controllers do not support SCO packets */
+ data->isoc = NULL;
+ } else {
+ /* Interface orders are hardcoded in the specification */
+ data->isoc = usb_ifnum_to_if(data->udev, ifnum_base + 1);
+ data->isoc_ifnum = ifnum_base + 1;
+ }
+
if (IS_ENABLED(CONFIG_BT_HCIBTUSB_RTL) &&
(id->driver_info & BTUSB_REALTEK)) {
hdev->setup = btrtl_setup_realtek;
@@ -3956,19 +4082,10 @@ static int btusb_probe(struct usb_interface *intf,
* (DEVICE_REMOTE_WAKEUP)
*/
set_bit(BTUSB_WAKEUP_DISABLE, &data->flags);
-
- err = usb_autopm_get_interface(intf);
- if (err < 0)
- goto out_free_dev;
- }
-
- if (id->driver_info & BTUSB_AMP) {
- /* AMP controllers do not support SCO packets */
- data->isoc = NULL;
- } else {
- /* Interface orders are hardcoded in the specification */
- data->isoc = usb_ifnum_to_if(data->udev, ifnum_base + 1);
- data->isoc_ifnum = ifnum_base + 1;
+ if (btusb_find_altsetting(data, 1))
+ set_bit(BTUSB_USE_ALT1_FOR_WBS, &data->flags);
+ else
+ bt_dev_err(hdev, "Device does not support ALT setting 1");
}
if (!reset)
@@ -4001,11 +4118,13 @@ static int btusb_probe(struct usb_interface *intf,
if (bcdDevice < 0x117)
set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
+ /* This must be set first in case we disable it for fakes */
+ set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+
/* Fake CSR devices with broken commands */
- if (bcdDevice <= 0x100 || bcdDevice == 0x134)
+ if (le16_to_cpu(udev->descriptor.idVendor) == 0x0a12 &&
+ le16_to_cpu(udev->descriptor.idProduct) == 0x0001)
hdev->setup = btusb_setup_csr;
-
- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
}
if (id->driver_info & BTUSB_SNIFFER) {
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index e60b2e0773db..e41854e0d79a 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -793,7 +793,7 @@ static int h5_serdev_probe(struct serdev_device *serdev)
if (!h5)
return -ENOMEM;
- set_bit(HCI_UART_RESET_ON_INIT, &h5->serdev_hu.flags);
+ set_bit(HCI_UART_RESET_ON_INIT, &h5->serdev_hu.hdev_flags);
h5->hu = &h5->serdev_hu;
h5->serdev_hu.serdev = serdev;
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index d9a4c6c691e0..8bfe024d1fcd 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -219,7 +219,7 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu)
* perfectly safe to always send one.
*/
BT_DBG("dual wake-up-indication");
- /* fall through */
+ fallthrough;
case HCILL_ASLEEP:
/* acknowledge device wake up */
if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 81c3c38baba1..20e1dedbc58c 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -46,7 +46,7 @@
#define HCI_MAX_IBS_SIZE 10
#define IBS_WAKE_RETRANS_TIMEOUT_MS 100
-#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS 40
+#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS 200
#define IBS_HOST_TX_IDLE_TIMEOUT_MS 2000
#define CMD_TRANS_TIMEOUT_MS 100
#define MEMDUMP_TIMEOUT_MS 8000
@@ -72,7 +72,8 @@ enum qca_flags {
QCA_DROP_VENDOR_EVENT,
QCA_SUSPENDING,
QCA_MEMDUMP_COLLECTION,
- QCA_HW_ERROR_EVENT
+ QCA_HW_ERROR_EVENT,
+ QCA_SSR_TRIGGERED
};
enum qca_capabilities {
@@ -289,25 +290,21 @@ static void serial_clock_vote(unsigned long vote, struct hci_uart *hu)
case HCI_IBS_TX_VOTE_CLOCK_ON:
qca->tx_vote = true;
qca->tx_votes_on++;
- new_vote = true;
break;
case HCI_IBS_RX_VOTE_CLOCK_ON:
qca->rx_vote = true;
qca->rx_votes_on++;
- new_vote = true;
break;
case HCI_IBS_TX_VOTE_CLOCK_OFF:
qca->tx_vote = false;
qca->tx_votes_off++;
- new_vote = qca->rx_vote | qca->tx_vote;
break;
case HCI_IBS_RX_VOTE_CLOCK_OFF:
qca->rx_vote = false;
qca->rx_votes_off++;
- new_vote = qca->rx_vote | qca->tx_vote;
break;
default:
@@ -315,6 +312,8 @@ static void serial_clock_vote(unsigned long vote, struct hci_uart *hu)
return;
}
+ new_vote = qca->rx_vote | qca->tx_vote;
+
if (new_vote != old_vote) {
if (new_vote)
__serial_clock_on(hu->tty);
@@ -474,8 +473,6 @@ static void hci_ibs_tx_idle_timeout(struct timer_list *t)
case HCI_IBS_TX_ASLEEP:
case HCI_IBS_TX_WAKING:
- /* Fall through */
-
default:
BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state);
break;
@@ -518,8 +515,6 @@ static void hci_ibs_wake_retrans_timeout(struct timer_list *t)
case HCI_IBS_TX_ASLEEP:
case HCI_IBS_TX_AWAKE:
- /* Fall through */
-
default:
BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state);
break;
@@ -837,8 +832,6 @@ static void device_woke_up(struct hci_uart *hu)
break;
case HCI_IBS_TX_ASLEEP:
- /* Fall through */
-
default:
BT_ERR("Received HCI_IBS_WAKE_ACK in tx state %d",
qca->tx_ibs_state);
@@ -862,6 +855,13 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
BT_DBG("hu %p qca enq skb %p tx_ibs_state %d", hu, skb,
qca->tx_ibs_state);
+ if (test_bit(QCA_SSR_TRIGGERED, &qca->flags)) {
+ /* As SSR is in progress, ignore the packets */
+ bt_dev_dbg(hu->hdev, "SSR is in progress");
+ kfree_skb(skb);
+ return 0;
+ }
+
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
@@ -983,8 +983,11 @@ static void qca_controller_memdump(struct work_struct *work)
while ((skb = skb_dequeue(&qca->rx_memdump_q))) {
mutex_lock(&qca->hci_memdump_lock);
- /* Skip processing the received packets if timeout detected. */
- if (qca->memdump_state == QCA_MEMDUMP_TIMEOUT) {
+ /* Skip processing the received packets if timeout detected
+ * or memdump collection completed.
+ */
+ if (qca->memdump_state == QCA_MEMDUMP_TIMEOUT ||
+ qca->memdump_state == QCA_MEMDUMP_COLLECTED) {
mutex_unlock(&qca->hci_memdump_lock);
return;
}
@@ -1128,6 +1131,7 @@ static int qca_controller_memdump_event(struct hci_dev *hdev,
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
+ set_bit(QCA_SSR_TRIGGERED, &qca->flags);
skb_queue_tail(&qca->rx_memdump_q, skb);
queue_work(qca->workqueue, &qca->ctrl_memdump_evt);
@@ -1485,9 +1489,8 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
{
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
- struct qca_memdump_data *qca_memdump = qca->qca_memdump;
- char *memdump_buf = NULL;
+ set_bit(QCA_SSR_TRIGGERED, &qca->flags);
set_bit(QCA_HW_ERROR_EVENT, &qca->flags);
bt_dev_info(hdev, "mem_dump_status: %d", qca->memdump_state);
@@ -1509,19 +1512,23 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
qca_wait_for_dump_collection(hdev);
}
+ mutex_lock(&qca->hci_memdump_lock);
if (qca->memdump_state != QCA_MEMDUMP_COLLECTED) {
bt_dev_err(hu->hdev, "clearing allocated memory due to memdump timeout");
- mutex_lock(&qca->hci_memdump_lock);
- if (qca_memdump)
- memdump_buf = qca_memdump->memdump_buf_head;
- vfree(memdump_buf);
- kfree(qca_memdump);
- qca->qca_memdump = NULL;
+ if (qca->qca_memdump) {
+ vfree(qca->qca_memdump->memdump_buf_head);
+ kfree(qca->qca_memdump);
+ qca->qca_memdump = NULL;
+ }
qca->memdump_state = QCA_MEMDUMP_TIMEOUT;
cancel_delayed_work(&qca->ctrl_memdump_timeout);
- skb_queue_purge(&qca->rx_memdump_q);
- mutex_unlock(&qca->hci_memdump_lock);
+ }
+ mutex_unlock(&qca->hci_memdump_lock);
+
+ if (qca->memdump_state == QCA_MEMDUMP_TIMEOUT ||
+ qca->memdump_state == QCA_MEMDUMP_COLLECTED) {
cancel_work_sync(&qca->ctrl_memdump_evt);
+ skb_queue_purge(&qca->rx_memdump_q);
}
clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
@@ -1532,10 +1539,30 @@ static void qca_cmd_timeout(struct hci_dev *hdev)
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
- if (qca->memdump_state == QCA_MEMDUMP_IDLE)
+ set_bit(QCA_SSR_TRIGGERED, &qca->flags);
+ if (qca->memdump_state == QCA_MEMDUMP_IDLE) {
+ set_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
qca_send_crashbuffer(hu);
- else
- bt_dev_info(hdev, "Dump collection is in process");
+ qca_wait_for_dump_collection(hdev);
+ } else if (qca->memdump_state == QCA_MEMDUMP_COLLECTING) {
+ /* Let us wait here until memory dump collected or
+ * memory dump timer expired.
+ */
+ bt_dev_info(hdev, "waiting for dump to complete");
+ qca_wait_for_dump_collection(hdev);
+ }
+
+ mutex_lock(&qca->hci_memdump_lock);
+ if (qca->memdump_state != QCA_MEMDUMP_COLLECTED) {
+ qca->memdump_state = QCA_MEMDUMP_TIMEOUT;
+ if (!test_bit(QCA_HW_ERROR_EVENT, &qca->flags)) {
+ /* Inject hw error event to reset the device
+ * and driver.
+ */
+ hci_reset_dev(hu->hdev);
+ }
+ }
+ mutex_unlock(&qca->hci_memdump_lock);
}
static int qca_wcn3990_init(struct hci_uart *hu)
@@ -1641,11 +1668,15 @@ static int qca_setup(struct hci_uart *hu)
bt_dev_info(hdev, "setting up %s",
qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME/QCA6390");
+ qca->memdump_state = QCA_MEMDUMP_IDLE;
+
retry:
ret = qca_power_on(hdev);
if (ret)
return ret;
+ clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
+
if (qca_is_wcn399x(soc_type)) {
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
@@ -1788,9 +1819,6 @@ static void qca_power_shutdown(struct hci_uart *hu)
qca_flush(hu);
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
- hu->hdev->hw_error = NULL;
- hu->hdev->cmd_timeout = NULL;
-
/* Non-serdev device usually is powered by external power
* and don't need additional action in driver for power down
*/
@@ -1812,6 +1840,9 @@ static int qca_power_off(struct hci_dev *hdev)
struct qca_data *qca = hu->priv;
enum qca_btsoc_type soc_type = qca_soc_type(hu);
+ hu->hdev->hw_error = NULL;
+ hu->hdev->cmd_timeout = NULL;
+
/* Stop sending shutdown command if soc crashes. */
if (soc_type != QCA_ROME
&& qca->memdump_state == QCA_MEMDUMP_IDLE) {
@@ -1819,7 +1850,6 @@ static int qca_power_off(struct hci_dev *hdev)
usleep_range(8000, 10000);
}
- qca->memdump_state = QCA_MEMDUMP_IDLE;
qca_power_shutdown(hu);
return 0;
}
@@ -1962,17 +1992,17 @@ static int qca_serdev_probe(struct serdev_device *serdev)
}
qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL);
- if (!qcadev->susclk) {
+ if (IS_ERR(qcadev->susclk)) {
dev_warn(&serdev->dev, "failed to acquire clk\n");
- } else {
- err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ);
- if (err)
- return err;
-
- err = clk_prepare_enable(qcadev->susclk);
- if (err)
- return err;
+ return PTR_ERR(qcadev->susclk);
}
+ err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ);
+ if (err)
+ return err;
+
+ err = clk_prepare_enable(qcadev->susclk);
+ if (err)
+ return err;
err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
if (err) {
@@ -2050,6 +2080,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
struct hci_uart *hu = &qcadev->serdev_hu;
struct qca_data *qca = hu->priv;
unsigned long flags;
+ bool tx_pending = false;
int ret = 0;
u8 cmd;
@@ -2068,7 +2099,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
switch (qca->tx_ibs_state) {
case HCI_IBS_TX_WAKING:
del_timer(&qca->wake_retrans_timer);
- /* Fall through */
+ fallthrough;
case HCI_IBS_TX_AWAKE:
del_timer(&qca->tx_idle_timer);
@@ -2083,8 +2114,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
qca->ibs_sent_slps++;
-
- qca_wq_serial_tx_clock_vote_off(&qca->ws_tx_vote_off);
+ tx_pending = true;
break;
case HCI_IBS_TX_ASLEEP:
@@ -2101,22 +2131,24 @@ static int __maybe_unused qca_suspend(struct device *dev)
if (ret < 0)
goto error;
- serdev_device_wait_until_sent(hu->serdev,
- msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
+ if (tx_pending) {
+ serdev_device_wait_until_sent(hu->serdev,
+ msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
+ serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
+ }
/* Wait for HCI_IBS_SLEEP_IND sent by device to indicate its Tx is going
* to sleep, so that the packet does not wake the system later.
*/
-
ret = wait_event_interruptible_timeout(qca->suspend_wait_q,
qca->rx_ibs_state == HCI_IBS_RX_ASLEEP,
msecs_to_jiffies(IBS_BTSOC_TX_IDLE_TIMEOUT_MS));
-
- if (ret > 0)
- return 0;
-
- if (ret == 0)
+ if (ret == 0) {
ret = -ETIMEDOUT;
+ goto error;
+ }
+
+ return 0;
error:
clear_bit(QCA_SUSPENDING, &qca->flags);
diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
index 599855e4c57c..7b233312e723 100644
--- a/drivers/bluetooth/hci_serdev.c
+++ b/drivers/bluetooth/hci_serdev.c
@@ -355,7 +355,8 @@ void hci_uart_unregister_device(struct hci_uart *hu)
struct hci_dev *hdev = hu->hdev;
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
- hci_unregister_dev(hdev);
+ if (test_bit(HCI_UART_REGISTERED, &hu->flags))
+ hci_unregister_dev(hdev);
hci_free_dev(hdev);
cancel_work_sync(&hu->write_work);
diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c b/drivers/crypto/chelsio/chtls/chtls_cm.c
index 54093115eb95..05520dccd906 100644
--- a/drivers/crypto/chelsio/chtls/chtls_cm.c
+++ b/drivers/crypto/chelsio/chtls/chtls_cm.c
@@ -1056,6 +1056,7 @@ static void chtls_pass_accept_rpl(struct sk_buff *skb,
opt2 |= CONG_CNTRL_V(CONG_ALG_NEWRENO);
opt2 |= T5_ISS_F;
opt2 |= T5_OPT_2_VALID_F;
+ opt2 |= WND_SCALE_EN_V(WSCALE_OK(tp));
rpl5->opt0 = cpu_to_be64(opt0);
rpl5->opt2 = cpu_to_be32(opt2);
rpl5->iss = cpu_to_be32((prandom_u32() & ~7UL) - 1);
@@ -1347,7 +1348,7 @@ static void chtls_pass_accept_request(struct sock *sk,
oreq->rsk_rcv_wnd = 0;
oreq->rsk_window_clamp = 0;
- oreq->cookie_ts = 0;
+ oreq->syncookie = 0;
oreq->mss = 0;
oreq->ts_recent = 0;
diff --git a/drivers/crypto/chelsio/chtls/chtls_main.c b/drivers/crypto/chelsio/chtls/chtls_main.c
index d98b89d0fa6e..66d247efd561 100644
--- a/drivers/crypto/chelsio/chtls/chtls_main.c
+++ b/drivers/crypto/chelsio/chtls/chtls_main.c
@@ -488,7 +488,7 @@ static int chtls_getsockopt(struct sock *sk, int level, int optname,
}
static int do_chtls_setsockopt(struct sock *sk, int optname,
- char __user *optval, unsigned int optlen)
+ sockptr_t optval, unsigned int optlen)
{
struct tls_crypto_info *crypto_info, tmp_crypto_info;
struct chtls_sock *csk;
@@ -498,12 +498,12 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
csk = rcu_dereference_sk_user_data(sk);
- if (!optval || optlen < sizeof(*crypto_info)) {
+ if (sockptr_is_null(optval) || optlen < sizeof(*crypto_info)) {
rc = -EINVAL;
goto out;
}
- rc = copy_from_user(&tmp_crypto_info, optval, sizeof(*crypto_info));
+ rc = copy_from_sockptr(&tmp_crypto_info, optval, sizeof(*crypto_info));
if (rc) {
rc = -EFAULT;
goto out;
@@ -525,8 +525,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
/* Obtain version and type from previous copy */
crypto_info[0] = tmp_crypto_info;
/* Now copy the following data */
- rc = copy_from_user((char *)crypto_info + sizeof(*crypto_info),
- optval + sizeof(*crypto_info),
+ rc = copy_from_sockptr_offset((char *)crypto_info +
+ sizeof(*crypto_info),
+ optval, sizeof(*crypto_info),
sizeof(struct tls12_crypto_info_aes_gcm_128)
- sizeof(*crypto_info));
@@ -541,8 +542,9 @@ static int do_chtls_setsockopt(struct sock *sk, int optname,
}
case TLS_CIPHER_AES_GCM_256: {
crypto_info[0] = tmp_crypto_info;
- rc = copy_from_user((char *)crypto_info + sizeof(*crypto_info),
- optval + sizeof(*crypto_info),
+ rc = copy_from_sockptr_offset((char *)crypto_info +
+ sizeof(*crypto_info),
+ optval, sizeof(*crypto_info),
sizeof(struct tls12_crypto_info_aes_gcm_256)
- sizeof(*crypto_info));
@@ -565,7 +567,7 @@ out:
}
static int chtls_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
+ sockptr_t optval, unsigned int optlen)
{
struct tls_context *ctx = tls_get_ctx(sk);
diff --git a/drivers/infiniband/hw/bnxt_re/hw_counters.c b/drivers/infiniband/hw/bnxt_re/hw_counters.c
index 3421a0b15983..5f5408cdf008 100644
--- a/drivers/infiniband/hw/bnxt_re/hw_counters.c
+++ b/drivers/infiniband/hw/bnxt_re/hw_counters.c
@@ -132,7 +132,7 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
stats->value[BNXT_RE_RECOVERABLE_ERRORS] =
le64_to_cpu(bnxt_re_stats->tx_bcast_pkts);
stats->value[BNXT_RE_RX_DROPS] =
- le64_to_cpu(bnxt_re_stats->rx_drop_pkts);
+ le64_to_cpu(bnxt_re_stats->rx_error_pkts);
stats->value[BNXT_RE_RX_DISCARDS] =
le64_to_cpu(bnxt_re_stats->rx_discard_pkts);
stats->value[BNXT_RE_RX_PKTS] =
diff --git a/drivers/infiniband/hw/i40iw/Makefile b/drivers/infiniband/hw/i40iw/Makefile
index 8942f8229945..34da9eba8a7c 100644
--- a/drivers/infiniband/hw/i40iw/Makefile
+++ b/drivers/infiniband/hw/i40iw/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-ccflags-y := -I $(srctree)/drivers/net/ethernet/intel/i40e
obj-$(CONFIG_INFINIBAND_I40IW) += i40iw.o
diff --git a/drivers/infiniband/hw/i40iw/i40iw.h b/drivers/infiniband/hw/i40iw/i40iw.h
index 49d92638e0db..25747b85a79c 100644
--- a/drivers/infiniband/hw/i40iw/i40iw.h
+++ b/drivers/infiniband/hw/i40iw/i40iw.h
@@ -45,6 +45,7 @@
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/crc32c.h>
+#include <linux/net/intel/i40e_client.h>
#include <rdma/ib_smi.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_pack.h>
@@ -57,7 +58,6 @@
#include "i40iw_d.h"
#include "i40iw_hmc.h"
-#include <i40e_client.h>
#include "i40iw_type.h"
#include "i40iw_p.h"
#include <rdma/i40iw-abi.h>
diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c
index ccaedfd53e49..b1de8d608e4d 100644
--- a/drivers/infiniband/hw/qedr/main.c
+++ b/drivers/infiniband/hw/qedr/main.c
@@ -346,9 +346,14 @@ static void qedr_free_resources(struct qedr_dev *dev)
static int qedr_alloc_resources(struct qedr_dev *dev)
{
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .intended_use = QED_CHAIN_USE_TO_CONSUME,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
+ .elem_size = sizeof(struct regpair *),
+ };
struct qedr_cnq *cnq;
__le16 *cons_pi;
- u16 n_entries;
int i, rc;
dev->sgid_tbl = kcalloc(QEDR_MAX_SGID, sizeof(union ib_gid),
@@ -382,7 +387,9 @@ static int qedr_alloc_resources(struct qedr_dev *dev)
dev->sb_start = dev->ops->rdma_get_start_sb(dev->cdev);
/* Allocate CNQ PBLs */
- n_entries = min_t(u32, QED_RDMA_MAX_CNQ_SIZE, QEDR_ROCE_MAX_CNQ_SIZE);
+ params.num_elems = min_t(u32, QED_RDMA_MAX_CNQ_SIZE,
+ QEDR_ROCE_MAX_CNQ_SIZE);
+
for (i = 0; i < dev->num_cnq; i++) {
cnq = &dev->cnq_array[i];
@@ -391,13 +398,8 @@ static int qedr_alloc_resources(struct qedr_dev *dev)
if (rc)
goto err3;
- rc = dev->ops->common->chain_alloc(dev->cdev,
- QED_CHAIN_USE_TO_CONSUME,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- n_entries,
- sizeof(struct regpair *),
- &cnq->pbl, NULL);
+ rc = dev->ops->common->chain_alloc(dev->cdev, &cnq->pbl,
+ &params);
if (rc)
goto err4;
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
index 9b9e80266367..f5aa85a5377c 100644
--- a/drivers/infiniband/hw/qedr/verbs.c
+++ b/drivers/infiniband/hw/qedr/verbs.c
@@ -891,6 +891,12 @@ int qedr_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
udata, struct qedr_ucontext, ibucontext);
struct qed_rdma_destroy_cq_out_params destroy_oparams;
struct qed_rdma_destroy_cq_in_params destroy_iparams;
+ struct qed_chain_init_params chain_params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .intended_use = QED_CHAIN_USE_TO_CONSUME,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U32,
+ .elem_size = sizeof(union rdma_cqe),
+ };
struct qedr_dev *dev = get_qedr_dev(ibdev);
struct qed_rdma_create_cq_in_params params;
struct qedr_create_cq_ureq ureq = {};
@@ -917,6 +923,7 @@ int qedr_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
chain_entries = qedr_align_cq_entries(entries);
chain_entries = min_t(int, chain_entries, QEDR_MAX_CQES);
+ chain_params.num_elems = chain_entries;
/* calc db offset. user will add DPI base, kernel will add db addr */
db_offset = DB_ADDR_SHIFT(DQ_PWM_OFFSET_UCM_RDMA_CQ_CONS_32BIT);
@@ -951,13 +958,8 @@ int qedr_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
} else {
cq->cq_type = QEDR_CQ_TYPE_KERNEL;
- rc = dev->ops->common->chain_alloc(dev->cdev,
- QED_CHAIN_USE_TO_CONSUME,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U32,
- chain_entries,
- sizeof(union rdma_cqe),
- &cq->pbl, NULL);
+ rc = dev->ops->common->chain_alloc(dev->cdev, &cq->pbl,
+ &chain_params);
if (rc)
goto err0;
@@ -1446,6 +1448,12 @@ static int qedr_alloc_srq_kernel_params(struct qedr_srq *srq,
struct ib_srq_init_attr *init_attr)
{
struct qedr_srq_hwq_info *hw_srq = &srq->hw_srq;
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U32,
+ .elem_size = QEDR_SRQ_WQE_ELEM_SIZE,
+ };
dma_addr_t phy_prod_pair_addr;
u32 num_elems;
void *va;
@@ -1464,13 +1472,9 @@ static int qedr_alloc_srq_kernel_params(struct qedr_srq *srq,
hw_srq->virt_prod_pair_addr = va;
num_elems = init_attr->attr.max_wr * RDMA_MAX_SRQ_WQE_SIZE;
- rc = dev->ops->common->chain_alloc(dev->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U32,
- num_elems,
- QEDR_SRQ_WQE_ELEM_SIZE,
- &hw_srq->pbl, NULL);
+ params.num_elems = num_elems;
+
+ rc = dev->ops->common->chain_alloc(dev->cdev, &hw_srq->pbl, &params);
if (rc)
goto err0;
@@ -1901,29 +1905,28 @@ qedr_roce_create_kernel_qp(struct qedr_dev *dev,
u32 n_sq_elems, u32 n_rq_elems)
{
struct qed_rdma_create_qp_out_params out_params;
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U32,
+ };
int rc;
- rc = dev->ops->common->chain_alloc(dev->cdev,
- QED_CHAIN_USE_TO_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U32,
- n_sq_elems,
- QEDR_SQE_ELEMENT_SIZE,
- &qp->sq.pbl, NULL);
+ params.intended_use = QED_CHAIN_USE_TO_PRODUCE;
+ params.num_elems = n_sq_elems;
+ params.elem_size = QEDR_SQE_ELEMENT_SIZE;
+ rc = dev->ops->common->chain_alloc(dev->cdev, &qp->sq.pbl, &params);
if (rc)
return rc;
in_params->sq_num_pages = qed_chain_get_page_cnt(&qp->sq.pbl);
in_params->sq_pbl_ptr = qed_chain_get_pbl_phys(&qp->sq.pbl);
- rc = dev->ops->common->chain_alloc(dev->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U32,
- n_rq_elems,
- QEDR_RQE_ELEMENT_SIZE,
- &qp->rq.pbl, NULL);
+ params.intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE;
+ params.num_elems = n_rq_elems;
+ params.elem_size = QEDR_RQE_ELEMENT_SIZE;
+
+ rc = dev->ops->common->chain_alloc(dev->cdev, &qp->rq.pbl, &params);
if (rc)
return rc;
@@ -1949,14 +1952,19 @@ qedr_iwarp_create_kernel_qp(struct qedr_dev *dev,
u32 n_sq_elems, u32 n_rq_elems)
{
struct qed_rdma_create_qp_out_params out_params;
- struct qed_chain_ext_pbl ext_pbl;
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U32,
+ };
int rc;
in_params->sq_num_pages = QED_CHAIN_PAGE_CNT(n_sq_elems,
QEDR_SQE_ELEMENT_SIZE,
+ QED_CHAIN_PAGE_SIZE,
QED_CHAIN_MODE_PBL);
in_params->rq_num_pages = QED_CHAIN_PAGE_CNT(n_rq_elems,
QEDR_RQE_ELEMENT_SIZE,
+ QED_CHAIN_PAGE_SIZE,
QED_CHAIN_MODE_PBL);
qp->qed_qp = dev->ops->rdma_create_qp(dev->rdma_ctx,
@@ -1966,31 +1974,24 @@ qedr_iwarp_create_kernel_qp(struct qedr_dev *dev,
return -EINVAL;
/* Now we allocate the chain */
- ext_pbl.p_pbl_virt = out_params.sq_pbl_virt;
- ext_pbl.p_pbl_phys = out_params.sq_pbl_phys;
- rc = dev->ops->common->chain_alloc(dev->cdev,
- QED_CHAIN_USE_TO_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U32,
- n_sq_elems,
- QEDR_SQE_ELEMENT_SIZE,
- &qp->sq.pbl, &ext_pbl);
+ params.intended_use = QED_CHAIN_USE_TO_PRODUCE;
+ params.num_elems = n_sq_elems;
+ params.elem_size = QEDR_SQE_ELEMENT_SIZE;
+ params.ext_pbl_virt = out_params.sq_pbl_virt;
+ params.ext_pbl_phys = out_params.sq_pbl_phys;
+ rc = dev->ops->common->chain_alloc(dev->cdev, &qp->sq.pbl, &params);
if (rc)
goto err;
- ext_pbl.p_pbl_virt = out_params.rq_pbl_virt;
- ext_pbl.p_pbl_phys = out_params.rq_pbl_phys;
-
- rc = dev->ops->common->chain_alloc(dev->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U32,
- n_rq_elems,
- QEDR_RQE_ELEMENT_SIZE,
- &qp->rq.pbl, &ext_pbl);
+ params.intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE;
+ params.num_elems = n_rq_elems;
+ params.elem_size = QEDR_RQE_ELEMENT_SIZE;
+ params.ext_pbl_virt = out_params.rq_pbl_virt;
+ params.ext_pbl_phys = out_params.rq_pbl_phys;
+ rc = dev->ops->common->chain_alloc(dev->cdev, &qp->rq.pbl, &params);
if (rc)
goto err;
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig
index cc408ad9aafb..fdb43a632215 100644
--- a/drivers/isdn/capi/Kconfig
+++ b/drivers/isdn/capi/Kconfig
@@ -5,7 +5,7 @@ config ISDN_CAPI
This provides CAPI (the Common ISDN Application Programming
Interface) Version 2.0, a standard making it easy for programs to
access ISDN hardware in a device independent way. (For details see
- <http://www.capi.org/>.) CAPI supports making and accepting voice
+ <https://www.capi.org/>.) CAPI supports making and accepting voice
and data connections, controlling call options and protocols,
as well as ISDN supplementary services like call forwarding or
three-party conferences (if supported by the specific hardware
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index abdf787c1a71..904a4f4c5ff9 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -158,7 +158,8 @@ release_io_hfcpci(struct hfc_pci *hc)
/* disable memory mapped ports + busmaster */
pci_write_config_word(hc->pdev, PCI_COMMAND, 0);
del_timer(&hc->hw.timer);
- pci_free_consistent(hc->pdev, 0x8000, hc->hw.fifos, hc->hw.dmahandle);
+ dma_free_coherent(&hc->pdev->dev, 0x8000, hc->hw.fifos,
+ hc->hw.dmahandle);
iounmap(hc->hw.pci_io);
}
@@ -2004,8 +2005,9 @@ setup_hw(struct hfc_pci *hc)
}
/* Allocate memory for FIFOS */
/* the memory needs to be on a 32k boundary within the first 4G */
- pci_set_dma_mask(hc->pdev, 0xFFFF8000);
- buffer = pci_alloc_consistent(hc->pdev, 0x8000, &hc->hw.dmahandle);
+ dma_set_mask(&hc->pdev->dev, 0xFFFF8000);
+ buffer = dma_alloc_coherent(&hc->pdev->dev, 0x8000, &hc->hw.dmahandle,
+ GFP_KERNEL);
/* We silently assume the address is okay if nonzero */
if (!buffer) {
printk(KERN_WARNING
@@ -2018,8 +2020,8 @@ setup_hw(struct hfc_pci *hc)
if (unlikely(!hc->hw.pci_io)) {
printk(KERN_WARNING
"HFC-PCI: Error in ioremap for PCI!\n");
- pci_free_consistent(hc->pdev, 0x8000, hc->hw.fifos,
- hc->hw.dmahandle);
+ dma_free_coherent(&hc->pdev->dev, 0x8000, hc->hw.fifos,
+ hc->hw.dmahandle);
return 1;
}
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index 621364bb6b12..4274906f8654 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -261,8 +261,7 @@ hfcsusb_ph_info(struct hfcsusb *hw)
phi->bch[i].Flags = hw->bch[i].Flags;
}
_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
- sizeof(struct ph_info_dch) + dch->dev.nrbchan *
- sizeof(struct ph_info_ch), phi, GFP_ATOMIC);
+ struct_size(phi, bch, dch->dev.nrbchan), phi, GFP_ATOMIC);
kfree(phi);
}
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
index 6aae97e827b7..ee925b58bbce 100644
--- a/drivers/isdn/hardware/mISDN/netjet.c
+++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -297,8 +297,8 @@ inittiger(struct tiger_hw *card)
{
int i;
- card->dma_p = pci_alloc_consistent(card->pdev, NJ_DMA_SIZE,
- &card->dma);
+ card->dma_p = dma_alloc_coherent(&card->pdev->dev, NJ_DMA_SIZE,
+ &card->dma, GFP_ATOMIC);
if (!card->dma_p) {
pr_info("%s: No DMA memory\n", card->name);
return -ENOMEM;
@@ -965,8 +965,8 @@ nj_release(struct tiger_hw *card)
kfree(card->bc[i].hrbuf);
}
if (card->dma_p)
- pci_free_consistent(card->pdev, NJ_DMA_SIZE,
- card->dma_p, card->dma);
+ dma_free_coherent(&card->pdev->dev, NJ_DMA_SIZE, card->dma_p,
+ card->dma);
write_lock_irqsave(&card_lock, flags);
list_del(&card->list);
write_unlock_irqrestore(&card_lock, flags);
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index dff4132b3702..a6606736d8c5 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -401,20 +401,20 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}
static int data_sock_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int len)
+ sockptr_t optval, unsigned int len)
{
struct sock *sk = sock->sk;
int err = 0, opt = 0;
if (*debug & DEBUG_SOCKET)
- printk(KERN_DEBUG "%s(%p, %d, %x, %p, %d)\n", __func__, sock,
- level, optname, optval, len);
+ printk(KERN_DEBUG "%s(%p, %d, %x, optval, %d)\n", __func__, sock,
+ level, optname, len);
lock_sock(sk);
switch (optname) {
case MISDN_TIME_STAMP:
- if (get_user(opt, (int __user *)optval)) {
+ if (copy_from_sockptr(&opt, optval, sizeof(int))) {
err = -EFAULT;
break;
}
@@ -738,8 +738,6 @@ static const struct proto_ops base_sock_ops = {
.recvmsg = sock_no_recvmsg,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9a49c4c2316b..1368d1d6a114 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -460,7 +460,7 @@ config NET_SB1000
At present this driver only compiles as a module, so say M here if
you have this card. The module will be called sb1000. Then read
- <file:Documentation/networking/device_drivers/sb1000.rst> for
+ <file:Documentation/networking/device_drivers/cable/sb1000.rst> for
information on how to use this module, as it needs special ppp
scripts for establishing a connection. Further documentation
and the necessary scripts can be found at:
@@ -495,6 +495,7 @@ config XEN_NETDEV_FRONTEND
tristate "Xen network device frontend driver"
depends on XEN
select XEN_XENBUS_FRONTEND
+ select PAGE_POOL
default y
help
This driver provides support for Xen paravirtual network
diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig
index 09f94d4b14e2..d4f22a2e5be4 100644
--- a/drivers/net/appletalk/Kconfig
+++ b/drivers/net/appletalk/Kconfig
@@ -59,7 +59,8 @@ config COPS
package. This driver is experimental, which means that it may not
work. This driver will only work if you choose "AppleTalk DDP"
networking support, above.
- Please read the file <file:Documentation/networking/cops.rst>.
+ Please read the file
+ <file:Documentation/networking/device_drivers/appletalk/cops.rst>.
config COPS_DAYNA
bool "Dayna firmware support"
diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c
index 88e7900853db..841910f1db65 100644
--- a/drivers/net/bareudp.c
+++ b/drivers/net/bareudp.c
@@ -125,7 +125,6 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
bareudp->dev->stats.rx_dropped++;
goto drop;
}
-
tun_dst = udp_tun_rx_dst(skb, family, TUNNEL_KEY, 0, 0);
if (!tun_dst) {
bareudp->dev->stats.rx_dropped++;
@@ -309,7 +308,7 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
return PTR_ERR(rt);
skb_tunnel_check_pmtu(skb, &rt->dst,
- BAREUDP_IPV4_HLEN + info->options_len);
+ BAREUDP_IPV4_HLEN + info->options_len, false);
sport = udp_flow_src_port(bareudp->net, skb,
bareudp->sport_min, USHRT_MAX,
@@ -370,7 +369,8 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (IS_ERR(dst))
return PTR_ERR(dst);
- skb_tunnel_check_pmtu(skb, dst, BAREUDP_IPV6_HLEN + info->options_len);
+ skb_tunnel_check_pmtu(skb, dst, BAREUDP_IPV6_HLEN + info->options_len,
+ false);
sport = udp_flow_src_port(bareudp->net, skb,
bareudp->sport_min, USHRT_MAX,
@@ -627,6 +627,7 @@ static int bareudp_configure(struct net *net, struct net_device *dev,
bareudp->ethertype = conf->ethertype;
bareudp->sport_min = conf->sport_min;
bareudp->multi_proto_mode = conf->multi_proto_mode;
+
err = register_netdevice(dev);
if (err)
return err;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f88cb097b022..5ad43aaf76e5 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -79,6 +79,7 @@
#include <net/pkt_sched.h>
#include <linux/rculist.h>
#include <net/flow_dissector.h>
+#include <net/xfrm.h>
#include <net/bonding.h>
#include <net/bond_3ad.h>
#include <net/bond_alb.h>
@@ -278,8 +279,6 @@ const char *bond_mode_name(int mode)
return names[mode];
}
-/*---------------------------------- VLAN -----------------------------------*/
-
/**
* bond_dev_queue_xmit - Prepare skb for xmit.
*
@@ -302,6 +301,8 @@ netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
return dev_queue_xmit(skb);
}
+/*---------------------------------- VLAN -----------------------------------*/
+
/* In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid,
* We don't protect the slave list iteration with a lock because:
* a. This operation is performed in IOCTL context,
@@ -372,6 +373,98 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
return 0;
}
+/*---------------------------------- XFRM -----------------------------------*/
+
+#ifdef CONFIG_XFRM_OFFLOAD
+/**
+ * bond_ipsec_add_sa - program device with a security association
+ * @xs: pointer to transformer state struct
+ **/
+static int bond_ipsec_add_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond;
+ struct slave *slave;
+
+ if (!bond_dev)
+ return -EINVAL;
+
+ bond = netdev_priv(bond_dev);
+ slave = rcu_dereference(bond->curr_active_slave);
+ xs->xso.real_dev = slave->dev;
+ bond->xs = xs;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
+ slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n");
+ return -EINVAL;
+ }
+
+ return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
+}
+
+/**
+ * bond_ipsec_del_sa - clear out this specific SA
+ * @xs: pointer to transformer state struct
+ **/
+static void bond_ipsec_del_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond;
+ struct slave *slave;
+
+ if (!bond_dev)
+ return;
+
+ bond = netdev_priv(bond_dev);
+ slave = rcu_dereference(bond->curr_active_slave);
+
+ if (!slave)
+ return;
+
+ xs->xso.real_dev = slave->dev;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
+ slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__);
+ return;
+ }
+
+ slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
+}
+
+/**
+ * bond_ipsec_offload_ok - can this packet use the xfrm hw offload
+ * @skb: current data packet
+ * @xs: pointer to transformer state struct
+ **/
+static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *curr_active = rcu_dereference(bond->curr_active_slave);
+ struct net_device *slave_dev = curr_active->dev;
+
+ if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)
+ return true;
+
+ if (!(slave_dev->xfrmdev_ops
+ && slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) {
+ slave_warn(bond_dev, slave_dev, "%s: no slave xdo_dev_offload_ok\n", __func__);
+ return false;
+ }
+
+ xs->xso.real_dev = slave_dev;
+ return slave_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
+}
+
+static const struct xfrmdev_ops bond_xfrmdev_ops = {
+ .xdo_dev_state_add = bond_ipsec_add_sa,
+ .xdo_dev_state_delete = bond_ipsec_del_sa,
+ .xdo_dev_offload_ok = bond_ipsec_offload_ok,
+};
+#endif /* CONFIG_XFRM_OFFLOAD */
+
/*------------------------------- Link status -------------------------------*/
/* Set the carrier state for the master according to the state of its
@@ -878,6 +971,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (old_active == new_active)
return;
+#ifdef CONFIG_XFRM_OFFLOAD
+ if (old_active && bond->xs)
+ bond_ipsec_del_sa(bond->xs);
+#endif /* CONFIG_XFRM_OFFLOAD */
+
if (new_active) {
new_active->last_link_up = jiffies;
@@ -950,6 +1048,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
}
}
+#ifdef CONFIG_XFRM_OFFLOAD
+ if (new_active && bond->xs) {
+ xfrm_dev_state_flush(dev_net(bond->dev), bond->dev, true);
+ bond_ipsec_add_sa(bond->xs);
+ }
+#endif /* CONFIG_XFRM_OFFLOAD */
+
/* resend IGMP joins since active slave has changed or
* all were sent on curr_active_slave.
* resend only if bond is brought up with the affected
@@ -1130,12 +1235,16 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
#define BOND_MPLS_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_ALL_TSO)
+
static void bond_compute_features(struct bonding *bond)
{
unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE |
IFF_XMIT_DST_RELEASE_PERM;
netdev_features_t vlan_features = BOND_VLAN_FEATURES;
netdev_features_t enc_features = BOND_ENC_FEATURES;
+#ifdef CONFIG_XFRM_OFFLOAD
+ netdev_features_t xfrm_features = BOND_XFRM_FEATURES;
+#endif /* CONFIG_XFRM_OFFLOAD */
netdev_features_t mpls_features = BOND_MPLS_FEATURES;
struct net_device *bond_dev = bond->dev;
struct list_head *iter;
@@ -1157,6 +1266,12 @@ static void bond_compute_features(struct bonding *bond)
slave->dev->hw_enc_features,
BOND_ENC_FEATURES);
+#ifdef CONFIG_XFRM_OFFLOAD
+ xfrm_features = netdev_increment_features(xfrm_features,
+ slave->dev->hw_enc_features,
+ BOND_XFRM_FEATURES);
+#endif /* CONFIG_XFRM_OFFLOAD */
+
mpls_features = netdev_increment_features(mpls_features,
slave->dev->mpls_features,
BOND_MPLS_FEATURES);
@@ -1176,6 +1291,9 @@ done:
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX |
NETIF_F_GSO_UDP_L4;
+#ifdef CONFIG_XFRM_OFFLOAD
+ bond_dev->hw_enc_features |= xfrm_features;
+#endif /* CONFIG_XFRM_OFFLOAD */
bond_dev->mpls_features = mpls_features;
bond_dev->gso_max_segs = gso_max_segs;
netif_set_gso_max_size(bond_dev, gso_max_size);
@@ -1464,6 +1582,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
slave_dbg(bond_dev, slave_dev, "is !NETIF_F_VLAN_CHALLENGED\n");
}
+ if (slave_dev->features & NETIF_F_HW_ESP)
+ slave_dbg(bond_dev, slave_dev, "is esp-hw-offload capable\n");
+
/* Old ifenslave binaries are no longer supported. These can
* be identified with moderate accuracy by the state of the slave:
* the current ifenslave will set the interface down prior to
@@ -4540,6 +4661,12 @@ void bond_setup(struct net_device *bond_dev)
bond_dev->priv_flags |= IFF_BONDING | IFF_UNICAST_FLT | IFF_NO_QUEUE;
bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+#ifdef CONFIG_XFRM_OFFLOAD
+ /* set up xfrm device ops (only supported in active-backup right now) */
+ bond_dev->xfrmdev_ops = &bond_xfrmdev_ops;
+ bond->xs = NULL;
+#endif /* CONFIG_XFRM_OFFLOAD */
+
/* don't acquire bond device's netif_tx_lock when transmitting */
bond_dev->features |= NETIF_F_LLTX;
@@ -4558,8 +4685,16 @@ void bond_setup(struct net_device *bond_dev)
NETIF_F_HW_VLAN_CTAG_FILTER;
bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
+#ifdef CONFIG_XFRM_OFFLOAD
+ bond_dev->hw_features |= BOND_XFRM_FEATURES;
+#endif /* CONFIG_XFRM_OFFLOAD */
bond_dev->features |= bond_dev->hw_features;
bond_dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
+#ifdef CONFIG_XFRM_OFFLOAD
+ /* Disable XFRM features if this isn't an active-backup config */
+ if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)
+ bond_dev->features &= ~BOND_XFRM_FEATURES;
+#endif /* CONFIG_XFRM_OFFLOAD */
}
/* Destroy a bonding device.
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index ddb3916d3506..9abfaae1c6f7 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -767,6 +767,14 @@ static int bond_option_mode_set(struct bonding *bond,
if (newval->value == BOND_MODE_ALB)
bond->params.tlb_dynamic_lb = 1;
+#ifdef CONFIG_XFRM_OFFLOAD
+ if (newval->value == BOND_MODE_ACTIVEBACKUP)
+ bond->dev->wanted_features |= BOND_XFRM_FEATURES;
+ else
+ bond->dev->wanted_features &= ~BOND_XFRM_FEATURES;
+ netdev_change_features(bond->dev);
+#endif /* CONFIG_XFRM_OFFLOAD */
+
/* don't cache arp_validate between modes */
bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
bond->params.mode = newval->value;
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index bbb2575d4728..4a33ec4fc089 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -1006,7 +1006,7 @@ static void cfhsi_aggregation_tout(struct timer_list *t)
cfhsi_start_tx(cfhsi);
}
-static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct cfhsi *cfhsi = NULL;
int start_xfer = 0;
@@ -1072,7 +1072,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_bh(&cfhsi->lock);
if (aggregate_ready)
cfhsi_start_tx(cfhsi);
- return 0;
+ return NETDEV_TX_OK;
}
/* Delete inactivity timer if started. */
@@ -1102,7 +1102,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
queue_work(cfhsi->wq, &cfhsi->wake_up_work);
}
- return 0;
+ return NETDEV_TX_OK;
}
static const struct net_device_ops cfhsi_netdevops;
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
index d737ceb61203..bcc14c5875bf 100644
--- a/drivers/net/caif/caif_serial.c
+++ b/drivers/net/caif/caif_serial.c
@@ -266,7 +266,7 @@ error:
return tty_wr;
}
-static int caif_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t caif_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ser_device *ser;
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
index 63f2548f5b1b..7d5899626130 100644
--- a/drivers/net/caif/caif_spi.c
+++ b/drivers/net/caif/caif_spi.c
@@ -488,7 +488,7 @@ static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc)
complete(&cfspi->comp);
}
-static int cfspi_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t cfspi_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct cfspi *cfspi = NULL;
unsigned long flags;
@@ -514,7 +514,7 @@ static int cfspi_xmit(struct sk_buff *skb, struct net_device *dev)
cfspi->cfdev.flowctrl(cfspi->ndev, 0);
}
- return 0;
+ return NETDEV_TX_OK;
}
int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len)
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c
index eb426822ad06..80ea2e913c2b 100644
--- a/drivers/net/caif/caif_virtio.c
+++ b/drivers/net/caif/caif_virtio.c
@@ -519,7 +519,7 @@ err:
}
/* Put the CAIF packet on the virtio ring and kick the receiver */
-static int cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev)
{
struct cfv_info *cfv = netdev_priv(netdev);
struct buf_info *buf_info;
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index d0024cb30a7b..468b3c4273c5 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -70,6 +70,7 @@ config NET_DSA_QCA8K
config NET_DSA_REALTEK_SMI
tristate "Realtek SMI Ethernet switch family support"
depends on NET_DSA
+ select NET_DSA_TAG_RTL4_A
select FIXED_PHY
select IRQ_DOMAIN
select REALTEK_PHY
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 1df05841ab6b..6500179c2ca2 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1037,7 +1037,8 @@ static void b53_force_link(struct b53_device *dev, int port, int link)
}
static void b53_force_port_config(struct b53_device *dev, int port,
- int speed, int duplex, int pause)
+ int speed, int duplex,
+ bool tx_pause, bool rx_pause)
{
u8 reg, val, off;
@@ -1075,9 +1076,9 @@ static void b53_force_port_config(struct b53_device *dev, int port,
return;
}
- if (pause & MLO_PAUSE_RX)
+ if (rx_pause)
reg |= PORT_OVERRIDE_RX_FLOW;
- if (pause & MLO_PAUSE_TX)
+ if (tx_pause)
reg |= PORT_OVERRIDE_TX_FLOW;
b53_write8(dev, B53_CTRL_PAGE, off, reg);
@@ -1089,22 +1090,24 @@ static void b53_adjust_link(struct dsa_switch *ds, int port,
struct b53_device *dev = ds->priv;
struct ethtool_eee *p = &dev->ports[port].eee;
u8 rgmii_ctrl = 0, reg = 0, off;
- int pause = 0;
+ bool tx_pause = false;
+ bool rx_pause = false;
if (!phy_is_pseudo_fixed_link(phydev))
return;
/* Enable flow control on BCM5301x's CPU port */
if (is5301x(dev) && port == dev->cpu_port)
- pause = MLO_PAUSE_TXRX_MASK;
+ tx_pause = rx_pause = true;
if (phydev->pause) {
if (phydev->asym_pause)
- pause |= MLO_PAUSE_TX;
- pause |= MLO_PAUSE_RX;
+ tx_pause = true;
+ rx_pause = true;
}
- b53_force_port_config(dev, port, phydev->speed, phydev->duplex, pause);
+ b53_force_port_config(dev, port, phydev->speed, phydev->duplex,
+ tx_pause, rx_pause);
b53_force_link(dev, port, phydev->link);
if (is531x5(dev) && phy_interface_is_rgmii(phydev)) {
@@ -1166,7 +1169,7 @@ static void b53_adjust_link(struct dsa_switch *ds, int port,
} else if (is5301x(dev)) {
if (port != dev->cpu_port) {
b53_force_port_config(dev, dev->cpu_port, 2000,
- DUPLEX_FULL, MLO_PAUSE_TXRX_MASK);
+ DUPLEX_FULL, true, true);
b53_force_link(dev, dev->cpu_port, 1);
}
}
@@ -1251,15 +1254,9 @@ void b53_phylink_mac_config(struct dsa_switch *ds, int port,
{
struct b53_device *dev = ds->priv;
- if (mode == MLO_AN_PHY)
+ if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED)
return;
- if (mode == MLO_AN_FIXED) {
- b53_force_port_config(dev, port, state->speed,
- state->duplex, state->pause);
- return;
- }
-
if ((phy_interface_mode_is_8023z(state->interface) ||
state->interface == PHY_INTERFACE_MODE_SGMII) &&
dev->ops->serdes_config)
@@ -1309,6 +1306,8 @@ void b53_phylink_mac_link_up(struct dsa_switch *ds, int port,
return;
if (mode == MLO_AN_FIXED) {
+ b53_force_port_config(dev, port, speed, duplex,
+ tx_pause, rx_pause);
b53_force_link(dev, port, true);
return;
}
diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c
index f89f5308a99b..7abec8dab8ba 100644
--- a/drivers/net/dsa/b53/b53_spi.c
+++ b/drivers/net/dsa/b53/b53_spi.c
@@ -145,42 +145,52 @@ static int b53_spi_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val)
static int b53_spi_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val)
{
- int ret = b53_spi_read(dev, page, reg, (u8 *)val, 2);
+ __le16 value;
+ int ret;
+
+ ret = b53_spi_read(dev, page, reg, (u8 *)&value, 2);
if (!ret)
- *val = le16_to_cpu(*val);
+ *val = le16_to_cpu(value);
return ret;
}
static int b53_spi_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val)
{
- int ret = b53_spi_read(dev, page, reg, (u8 *)val, 4);
+ __le32 value;
+ int ret;
+
+ ret = b53_spi_read(dev, page, reg, (u8 *)&value, 4);
if (!ret)
- *val = le32_to_cpu(*val);
+ *val = le32_to_cpu(value);
return ret;
}
static int b53_spi_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val)
{
+ __le64 value;
int ret;
*val = 0;
- ret = b53_spi_read(dev, page, reg, (u8 *)val, 6);
+ ret = b53_spi_read(dev, page, reg, (u8 *)&value, 6);
if (!ret)
- *val = le64_to_cpu(*val);
+ *val = le64_to_cpu(value);
return ret;
}
static int b53_spi_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val)
{
- int ret = b53_spi_read(dev, page, reg, (u8 *)val, 8);
+ __le64 value;
+ int ret;
+
+ ret = b53_spi_read(dev, page, reg, (u8 *)&value, 8);
if (!ret)
- *val = le64_to_cpu(*val);
+ *val = le64_to_cpu(value);
return ret;
}
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 946e41f020a5..bafddb35f3a9 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -558,16 +558,11 @@ static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port,
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
u32 id_mode_dis = 0, port_mode;
- u32 reg, offset;
+ u32 reg;
if (port == core_readl(priv, CORE_IMP0_PRT_ID))
return;
- if (priv->type == BCM7445_DEVICE_ID)
- offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
- else
- offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
-
switch (state->interface) {
case PHY_INTERFACE_MODE_RGMII:
id_mode_dis = 1;
@@ -582,8 +577,8 @@ static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port,
port_mode = EXT_REVMII;
break;
default:
- /* all other PHYs: internal and MoCA */
- goto force_link;
+ /* Nothing required for all other PHYs: internal and MoCA */
+ return;
}
/* Clear id_mode_dis bit, and the existing port mode, let
@@ -592,38 +587,12 @@ static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port,
reg = reg_readl(priv, REG_RGMII_CNTRL_P(port));
reg &= ~ID_MODE_DIS;
reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT);
- reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
reg |= port_mode;
if (id_mode_dis)
reg |= ID_MODE_DIS;
- if (state->pause & MLO_PAUSE_TXRX_MASK) {
- if (state->pause & MLO_PAUSE_TX)
- reg |= TX_PAUSE_EN;
- reg |= RX_PAUSE_EN;
- }
-
reg_writel(priv, reg, REG_RGMII_CNTRL_P(port));
-
-force_link:
- /* Force link settings detected from the PHY */
- reg = SW_OVERRIDE;
- switch (state->speed) {
- case SPEED_1000:
- reg |= SPDSTS_1000 << SPEED_SHIFT;
- break;
- case SPEED_100:
- reg |= SPDSTS_100 << SPEED_SHIFT;
- break;
- }
-
- if (state->link)
- reg |= LINK_STS;
- if (state->duplex == DUPLEX_FULL)
- reg |= DUPLX_MODE;
-
- core_writel(priv, reg, offset);
}
static void bcm_sf2_sw_mac_link_set(struct dsa_switch *ds, int port,
@@ -650,6 +619,20 @@ static void bcm_sf2_sw_mac_link_down(struct dsa_switch *ds, int port,
unsigned int mode,
phy_interface_t interface)
{
+ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
+ u32 reg, offset;
+
+ if (port != core_readl(priv, CORE_IMP0_PRT_ID)) {
+ if (priv->type == BCM7445_DEVICE_ID)
+ offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
+ else
+ offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
+
+ reg = core_readl(priv, offset);
+ reg &= ~LINK_STS;
+ core_writel(priv, reg, offset);
+ }
+
bcm_sf2_sw_mac_link_set(ds, port, interface, false);
}
@@ -662,9 +645,47 @@ static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
struct ethtool_eee *p = &priv->dev->ports[port].eee;
+ u32 reg, offset;
bcm_sf2_sw_mac_link_set(ds, port, interface, true);
+ if (port != core_readl(priv, CORE_IMP0_PRT_ID)) {
+ if (priv->type == BCM7445_DEVICE_ID)
+ offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
+ else
+ offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
+
+ if (interface == PHY_INTERFACE_MODE_RGMII ||
+ interface == PHY_INTERFACE_MODE_RGMII_TXID ||
+ interface == PHY_INTERFACE_MODE_MII ||
+ interface == PHY_INTERFACE_MODE_REVMII) {
+ reg = reg_readl(priv, REG_RGMII_CNTRL_P(port));
+ reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
+
+ if (tx_pause)
+ reg |= TX_PAUSE_EN;
+ if (rx_pause)
+ reg |= RX_PAUSE_EN;
+
+ reg_writel(priv, reg, REG_RGMII_CNTRL_P(port));
+ }
+
+ reg = SW_OVERRIDE | LINK_STS;
+ switch (speed) {
+ case SPEED_1000:
+ reg |= SPDSTS_1000 << SPEED_SHIFT;
+ break;
+ case SPEED_100:
+ reg |= SPDSTS_100 << SPEED_SHIFT;
+ break;
+ }
+
+ if (duplex == DUPLEX_FULL)
+ reg |= DUPLX_MODE;
+
+ core_writel(priv, reg, offset);
+ }
+
if (mode == MLO_AN_PHY && phydev)
p->eee_enabled = b53_eee_init(ds, port, phydev);
}
diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
index f707edc641cf..d82cee5d9202 100644
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -128,12 +128,12 @@ static inline unsigned int bcm_sf2_get_num_udf_slices(const u8 *layout)
return count;
}
-static inline u32 udf_upper_bits(unsigned int num_udf)
+static inline u32 udf_upper_bits(int num_udf)
{
return GENMASK(num_udf - 1, 0) >> (UDFS_PER_SLICE - 1);
}
-static inline u32 udf_lower_bits(unsigned int num_udf)
+static inline u32 udf_lower_bits(int num_udf)
{
return (u8)GENMASK(num_udf - 1, 0);
}
@@ -348,8 +348,8 @@ static int bcm_sf2_cfp_ipv4_rule_set(struct bcm_sf2_priv *priv, int port,
unsigned int queue_num,
struct ethtool_rx_flow_spec *fs)
{
+ __be16 vlan_tci = 0, vlan_m_tci = htons(0xffff);
struct ethtool_rx_flow_spec_input input = {};
- __be16 vlan_tci = 0 , vlan_m_tci = 0xffff;
const struct cfp_udf_layout *layout;
unsigned int slice_num, rule_index;
struct ethtool_rx_flow_rule *flow;
@@ -629,8 +629,8 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port,
unsigned int queue_num,
struct ethtool_rx_flow_spec *fs)
{
+ __be16 vlan_tci = 0, vlan_m_tci = htons(0xffff);
struct ethtool_rx_flow_spec_input input = {};
- __be16 vlan_tci = 0, vlan_m_tci = 0xffff;
unsigned int slice_num, rule_index[2];
const struct cfp_udf_layout *layout;
struct ethtool_rx_flow_rule *flow;
diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
index 400207c5c7de..eb600b3dbf26 100644
--- a/drivers/net/dsa/dsa_loop.c
+++ b/drivers/net/dsa/dsa_loop.c
@@ -14,28 +14,11 @@
#include <linux/workqueue.h>
#include <linux/module.h>
#include <linux/if_bridge.h>
+#include <linux/dsa/loop.h>
#include <net/dsa.h>
#include "dsa_loop.h"
-struct dsa_loop_vlan {
- u16 members;
- u16 untagged;
-};
-
-struct dsa_loop_mib_entry {
- char name[ETH_GSTRING_LEN];
- unsigned long val;
-};
-
-enum dsa_loop_mib_counters {
- DSA_LOOP_PHY_READ_OK,
- DSA_LOOP_PHY_READ_ERR,
- DSA_LOOP_PHY_WRITE_OK,
- DSA_LOOP_PHY_WRITE_ERR,
- __DSA_LOOP_CNT_MAX,
-};
-
static struct dsa_loop_mib_entry dsa_loop_mibs[] = {
[DSA_LOOP_PHY_READ_OK] = { "phy_read_ok", },
[DSA_LOOP_PHY_READ_ERR] = { "phy_read_err", },
@@ -43,21 +26,6 @@ static struct dsa_loop_mib_entry dsa_loop_mibs[] = {
[DSA_LOOP_PHY_WRITE_ERR] = { "phy_write_err", },
};
-struct dsa_loop_port {
- struct dsa_loop_mib_entry mib[__DSA_LOOP_CNT_MAX];
-};
-
-#define DSA_LOOP_VLANS 5
-
-struct dsa_loop_priv {
- struct mii_bus *bus;
- unsigned int port_base;
- struct dsa_loop_vlan vlans[DSA_LOOP_VLANS];
- struct net_device *netdev;
- struct dsa_loop_port ports[DSA_MAX_PORTS];
- u16 pvid;
-};
-
static struct phy_device *phydevs[PHY_MAX_ADDR];
static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds,
@@ -191,7 +159,7 @@ dsa_loop_port_vlan_prepare(struct dsa_switch *ds, int port,
/* Just do a sleeping operation to make lockdep checks effective */
mdiobus_read(bus, ps->port_base + port, MII_BMSR);
- if (vlan->vid_end > DSA_LOOP_VLANS)
+ if (vlan->vid_end > ARRAY_SIZE(ps->vlans))
return -ERANGE;
return 0;
@@ -224,7 +192,7 @@ static void dsa_loop_port_vlan_add(struct dsa_switch *ds, int port,
}
if (pvid)
- ps->pvid = vid;
+ ps->ports[port].pvid = vid;
}
static int dsa_loop_port_vlan_del(struct dsa_switch *ds, int port,
@@ -234,7 +202,7 @@ static int dsa_loop_port_vlan_del(struct dsa_switch *ds, int port,
struct dsa_loop_priv *ps = ds->priv;
struct mii_bus *bus = ps->bus;
struct dsa_loop_vlan *vl;
- u16 vid, pvid = ps->pvid;
+ u16 vid, pvid = ps->ports[port].pvid;
/* Just do a sleeping operation to make lockdep checks effective */
mdiobus_read(bus, ps->port_base + port, MII_BMSR);
@@ -252,11 +220,26 @@ static int dsa_loop_port_vlan_del(struct dsa_switch *ds, int port,
dev_dbg(ds->dev, "%s: port: %d vlan: %d, %stagged, pvid: %d\n",
__func__, port, vid, untagged ? "un" : "", pvid);
}
- ps->pvid = pvid;
+ ps->ports[port].pvid = pvid;
+
+ return 0;
+}
+
+static int dsa_loop_port_change_mtu(struct dsa_switch *ds, int port,
+ int new_mtu)
+{
+ struct dsa_loop_priv *priv = ds->priv;
+
+ priv->ports[port].mtu = new_mtu;
return 0;
}
+static int dsa_loop_port_max_mtu(struct dsa_switch *ds, int port)
+{
+ return ETH_MAX_MTU;
+}
+
static const struct dsa_switch_ops dsa_loop_driver = {
.get_tag_protocol = dsa_loop_get_protocol,
.setup = dsa_loop_setup,
@@ -273,6 +256,8 @@ static const struct dsa_switch_ops dsa_loop_driver = {
.port_vlan_prepare = dsa_loop_port_vlan_prepare,
.port_vlan_add = dsa_loop_port_vlan_add,
.port_vlan_del = dsa_loop_port_vlan_del,
+ .port_change_mtu = dsa_loop_port_change_mtu,
+ .port_max_mtu = dsa_loop_port_max_mtu,
};
static int dsa_loop_drv_probe(struct mdio_device *mdiodev)
@@ -280,19 +265,17 @@ static int dsa_loop_drv_probe(struct mdio_device *mdiodev)
struct dsa_loop_pdata *pdata = mdiodev->dev.platform_data;
struct dsa_loop_priv *ps;
struct dsa_switch *ds;
+ int ret;
if (!pdata)
return -ENODEV;
- dev_info(&mdiodev->dev, "%s: 0x%0x\n",
- pdata->name, pdata->enabled_ports);
-
ds = devm_kzalloc(&mdiodev->dev, sizeof(*ds), GFP_KERNEL);
if (!ds)
return -ENOMEM;
ds->dev = &mdiodev->dev;
- ds->num_ports = DSA_MAX_PORTS;
+ ds->num_ports = DSA_LOOP_NUM_PORTS;
ps = devm_kzalloc(&mdiodev->dev, sizeof(*ps), GFP_KERNEL);
if (!ps)
@@ -311,7 +294,12 @@ static int dsa_loop_drv_probe(struct mdio_device *mdiodev)
dev_set_drvdata(&mdiodev->dev, ds);
- return dsa_register_switch(ds);
+ ret = dsa_register_switch(ds);
+ if (!ret)
+ dev_info(&mdiodev->dev, "%s: 0x%0x\n",
+ pdata->name, pdata->enabled_ports);
+
+ return ret;
}
static void dsa_loop_drv_remove(struct mdio_device *mdiodev)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index cc17a44dd3a8..aa1142d6a9f5 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -1042,7 +1042,7 @@ static void lan9303_adjust_link(struct dsa_switch *ds, int port,
struct phy_device *phydev)
{
struct lan9303 *chip = ds->priv;
- int ctl, res;
+ int ctl;
if (!phy_is_pseudo_fixed_link(phydev))
return;
@@ -1063,15 +1063,14 @@ static void lan9303_adjust_link(struct dsa_switch *ds, int port,
else
ctl &= ~BMCR_FULLDPLX;
- res = lan9303_phy_write(ds, port, MII_BMCR, ctl);
+ lan9303_phy_write(ds, port, MII_BMCR, ctl);
if (port == chip->phy_addr_base) {
/* Virtual Phy: Remove Turbo 200Mbit mode */
lan9303_read(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, &ctl);
ctl &= ~LAN9303_VIRT_SPECIAL_TURBO;
- res = regmap_write(chip->regmap,
- LAN9303_VIRT_SPECIAL_CTRL, ctl);
+ regmap_write(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, ctl);
}
}
diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c
index 7c17b0f705ec..8f1d15ea15d9 100644
--- a/drivers/net/dsa/microchip/ksz8795.c
+++ b/drivers/net/dsa/microchip/ksz8795.c
@@ -731,15 +731,6 @@ static void ksz8795_port_stp_state_set(struct dsa_switch *ds, int port,
ksz_pwrite8(dev, port, P_STP_CTRL, data);
p->stp_state = state;
- if (data & PORT_RX_ENABLE)
- dev->rx_ports |= BIT(port);
- else
- dev->rx_ports &= ~BIT(port);
- if (data & PORT_TX_ENABLE)
- dev->tx_ports |= BIT(port);
- else
- dev->tx_ports &= ~BIT(port);
-
/* Port membership may share register with STP state. */
if (member >= 0 && member != p->member)
ksz8795_cfg_port_member(dev, port, (u8)member);
@@ -976,15 +967,8 @@ static void ksz8795_port_setup(struct ksz_device *dev, int port, bool cpu_port)
p->phydev.duplex = 1;
member = dev->port_mask;
- dev->on_ports = dev->host_mask;
- dev->live_ports = dev->host_mask;
} else {
member = dev->host_mask | p->vid_member;
- dev->on_ports |= BIT(port);
-
- /* Link was detected before port is enabled. */
- if (p->phydev.link)
- dev->live_ports |= BIT(port);
}
ksz8795_cfg_port_member(dev, port, member);
}
@@ -1111,9 +1095,8 @@ static const struct dsa_switch_ops ksz8795_switch_ops = {
.setup = ksz8795_setup,
.phy_read = ksz_phy_read16,
.phy_write = ksz_phy_write16,
- .adjust_link = ksz_adjust_link,
+ .phylink_mac_link_down = ksz_mac_link_down,
.port_enable = ksz_enable_port,
- .port_disable = ksz_disable_port,
.get_strings = ksz8795_get_strings,
.get_ethtool_stats = ksz_get_ethtool_stats,
.get_sset_count = ksz_sset_count,
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index 4a9239b2c2e4..dc999406ce86 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -452,15 +452,6 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
ksz_pwrite8(dev, port, P_STP_CTRL, data);
p->stp_state = state;
mutex_lock(&dev->dev_mutex);
- if (data & PORT_RX_ENABLE)
- dev->rx_ports |= (1 << port);
- else
- dev->rx_ports &= ~(1 << port);
- if (data & PORT_TX_ENABLE)
- dev->tx_ports |= (1 << port);
- else
- dev->tx_ports &= ~(1 << port);
-
/* Port membership may share register with STP state. */
if (member >= 0 && member != p->member)
ksz9477_cfg_port_member(dev, port, (u8)member);
@@ -1251,18 +1242,10 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
p->phydev.duplex = 1;
}
mutex_lock(&dev->dev_mutex);
- if (cpu_port) {
+ if (cpu_port)
member = dev->port_mask;
- dev->on_ports = dev->host_mask;
- dev->live_ports = dev->host_mask;
- } else {
+ else
member = dev->host_mask | p->vid_member;
- dev->on_ports |= (1 << port);
-
- /* Link was detected before port is enabled. */
- if (p->phydev.link)
- dev->live_ports |= (1 << port);
- }
mutex_unlock(&dev->dev_mutex);
ksz9477_cfg_port_member(dev, port, member);
@@ -1382,9 +1365,8 @@ static const struct dsa_switch_ops ksz9477_switch_ops = {
.setup = ksz9477_setup,
.phy_read = ksz9477_phy_read16,
.phy_write = ksz9477_phy_write16,
- .adjust_link = ksz_adjust_link,
+ .phylink_mac_link_down = ksz_mac_link_down,
.port_enable = ksz_enable_port,
- .port_disable = ksz_disable_port,
.get_strings = ksz9477_get_strings,
.get_ethtool_stats = ksz_get_ethtool_stats,
.get_sset_count = ksz_sset_count,
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 7b6c0dce7536..8d53b12d40a8 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -135,26 +135,17 @@ int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
}
EXPORT_SYMBOL_GPL(ksz_phy_write16);
-void ksz_adjust_link(struct dsa_switch *ds, int port,
- struct phy_device *phydev)
+void ksz_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
+ phy_interface_t interface)
{
struct ksz_device *dev = ds->priv;
struct ksz_port *p = &dev->ports[port];
/* Read all MIB counters when the link is going down. */
- if (!phydev->link) {
- p->read = true;
- schedule_delayed_work(&dev->mib_read, 0);
- }
- mutex_lock(&dev->dev_mutex);
- if (!phydev->link)
- dev->live_ports &= ~(1 << port);
- else
- /* Remember which port is connected and active. */
- dev->live_ports |= (1 << port) & dev->on_ports;
- mutex_unlock(&dev->dev_mutex);
+ p->read = true;
+ schedule_delayed_work(&dev->mib_read, 0);
}
-EXPORT_SYMBOL_GPL(ksz_adjust_link);
+EXPORT_SYMBOL_GPL(ksz_mac_link_down);
int ksz_sset_count(struct dsa_switch *ds, int port, int sset)
{
@@ -367,22 +358,6 @@ int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
}
EXPORT_SYMBOL_GPL(ksz_enable_port);
-void ksz_disable_port(struct dsa_switch *ds, int port)
-{
- struct ksz_device *dev = ds->priv;
-
- if (!dsa_is_user_port(ds, port))
- return;
-
- dev->on_ports &= ~(1 << port);
- dev->live_ports &= ~(1 << port);
-
- /* port_stp_state_set() will be called after to disable the port so
- * there is no need to do anything.
- */
-}
-EXPORT_SYMBOL_GPL(ksz_disable_port);
-
struct ksz_device *ksz_switch_alloc(struct device *base, void *priv)
{
struct dsa_switch *ds;
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 7d11dd32ec0d..206838160f49 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -84,10 +84,6 @@ struct ksz_device {
unsigned long mib_read_interval;
u16 br_member;
u16 member;
- u16 live_ports;
- u16 on_ports; /* ports enabled by DSA */
- u16 rx_ports;
- u16 tx_ports;
u16 mirror_rx;
u16 mirror_tx;
u32 features; /* chip specific features */
@@ -157,8 +153,8 @@ void ksz_init_mib_timer(struct ksz_device *dev);
int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg);
int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val);
-void ksz_adjust_link(struct dsa_switch *ds, int port,
- struct phy_device *phydev);
+void ksz_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
+ phy_interface_t interface);
int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf);
int ksz_port_bridge_join(struct dsa_switch *ds, int port,
@@ -177,7 +173,6 @@ void ksz_port_mdb_add(struct dsa_switch *ds, int port,
int ksz_port_mdb_del(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb);
int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
-void ksz_disable_port(struct dsa_switch *ds, int port);
/* Common register access functions */
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index fee16c947c2e..7a71c9902e73 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1767,7 +1767,7 @@ static int mv88e6xxx_policy_insert(struct mv88e6xxx_chip *chip, int port,
}
if ((fs->flow_type & FLOW_EXT) && fs->m_ext.vlan_tci) {
- if (fs->m_ext.vlan_tci != 0xffff)
+ if (fs->m_ext.vlan_tci != htons(0xffff))
return -EOPNOTSUPP;
vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
}
@@ -2709,6 +2709,35 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
}
+static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
+{
+ struct mv88e6xxx_chip *chip = ds->priv;
+
+ if (chip->info->ops->port_set_jumbo_size)
+ return 10240;
+ else if (chip->info->ops->set_max_frame_size)
+ return 1632;
+ return 1522;
+}
+
+static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+ struct mv88e6xxx_chip *chip = ds->priv;
+ int ret = 0;
+
+ mv88e6xxx_reg_lock(chip);
+ if (chip->info->ops->port_set_jumbo_size)
+ ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
+ else if (chip->info->ops->set_max_frame_size)
+ ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
+ else
+ if (new_mtu > 1522)
+ ret = -EINVAL;
+ mv88e6xxx_reg_unlock(chip);
+
+ return ret;
+}
+
static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
struct phy_device *phydev)
{
@@ -3441,6 +3470,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
.phylink_validate = mv88e6185_phylink_validate,
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
};
static const struct mv88e6xxx_ops mv88e6095_ops = {
@@ -3469,6 +3499,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
.vtu_getnext = mv88e6185_g1_vtu_getnext,
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
.phylink_validate = mv88e6185_phylink_validate,
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
};
static const struct mv88e6xxx_ops mv88e6097_ops = {
@@ -3485,7 +3516,6 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_floods = mv88e6352_port_set_egress_floods,
.port_set_ether_type = mv88e6351_port_set_ether_type,
- .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
.port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
.port_pause_limit = mv88e6097_port_pause_limit,
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
@@ -3507,6 +3537,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
.phylink_validate = mv88e6185_phylink_validate,
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
};
static const struct mv88e6xxx_ops mv88e6123_ops = {
@@ -3541,6 +3572,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
.phylink_validate = mv88e6185_phylink_validate,
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
};
static const struct mv88e6xxx_ops mv88e6131_ops = {
@@ -3930,6 +3962,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
.vtu_getnext = mv88e6185_g1_vtu_getnext,
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
.phylink_validate = mv88e6185_phylink_validate,
+ .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
};
static const struct mv88e6xxx_ops mv88e6190_ops = {
@@ -3950,6 +3983,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_floods = mv88e6352_port_set_egress_floods,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
.port_pause_limit = mv88e6390_port_pause_limit,
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
@@ -4008,6 +4042,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_floods = mv88e6352_port_set_egress_floods,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
.port_pause_limit = mv88e6390_port_pause_limit,
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
@@ -5541,6 +5576,8 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.get_sset_count = mv88e6xxx_get_sset_count,
.port_enable = mv88e6xxx_port_enable,
.port_disable = mv88e6xxx_port_disable,
+ .port_max_mtu = mv88e6xxx_get_max_mtu,
+ .port_change_mtu = mv88e6xxx_change_mtu,
.get_mac_eee = mv88e6xxx_get_mac_eee,
.set_mac_eee = mv88e6xxx_set_mac_eee,
.get_eeprom_len = mv88e6xxx_get_eeprom_len,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 6476524e8239..823ae89e5fca 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -167,7 +167,7 @@ struct mv88e6xxx_irq {
u16 masked;
struct irq_chip chip;
struct irq_domain *domain;
- unsigned int nirqs;
+ int nirqs;
};
/* state flags for mv88e6xxx_port_hwtstamp::state */
@@ -553,6 +553,9 @@ struct mv88e6xxx_ops {
void (*phylink_validate)(struct mv88e6xxx_chip *chip, int port,
unsigned long *mask,
struct phylink_link_state *state);
+
+ /* Max Frame Size */
+ int (*set_max_frame_size)(struct mv88e6xxx_chip *chip, int mtu);
};
struct mv88e6xxx_irq_ops {
@@ -655,7 +658,7 @@ static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip)
{
- return GENMASK(mv88e6xxx_num_ports(chip) - 1, 0);
+ return GENMASK((s32)mv88e6xxx_num_ports(chip) - 1, 0);
}
static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip)
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c
index ca3a7a7a73c3..f62aa83ca08d 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.c
+++ b/drivers/net/dsa/mv88e6xxx/global1.c
@@ -196,6 +196,23 @@ int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip)
return mv88e6185_g1_wait_ppu_disabled(chip);
}
+int mv88e6185_g1_set_max_frame_size(struct mv88e6xxx_chip *chip, int mtu)
+{
+ u16 val;
+ int err;
+
+ err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
+ if (err)
+ return err;
+
+ val &= ~MV88E6185_G1_CTL1_MAX_FRAME_1632;
+
+ if (mtu > 1518)
+ val |= MV88E6185_G1_CTL1_MAX_FRAME_1632;
+
+ return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
+}
+
/* Offset 0x10: IP-PRI Mapping Register 0
* Offset 0x11: IP-PRI Mapping Register 1
* Offset 0x12: IP-PRI Mapping Register 2
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index 5324c6f4ae90..1e3546f8b072 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -282,6 +282,8 @@ int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip);
int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip);
int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip);
+int mv88e6185_g1_set_max_frame_size(struct mv88e6xxx_chip *chip, int mtu);
+
int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port);
int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port);
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
index 8fd483020c5b..75b227d0f73b 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.c
+++ b/drivers/net/dsa/mv88e6xxx/global2.c
@@ -876,19 +876,18 @@ static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
{
- int err;
u16 reg;
mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
MV88E6390_G2_WDOG_CTL_PTR_EVENT);
- err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
+ mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
dev_info(chip->dev, "Watchdog event: 0x%04x",
reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
- err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
+ mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
dev_info(chip->dev, "Watchdog history: 0x%04x",
reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
diff --git a/drivers/net/dsa/mv88e6xxx/global2_scratch.c b/drivers/net/dsa/mv88e6xxx/global2_scratch.c
index 33b7b9570d29..7c2c67405322 100644
--- a/drivers/net/dsa/mv88e6xxx/global2_scratch.c
+++ b/drivers/net/dsa/mv88e6xxx/global2_scratch.c
@@ -44,7 +44,8 @@ static int mv88e6xxx_g2_scratch_write(struct mv88e6xxx_chip *chip, int reg,
/**
* mv88e6xxx_g2_scratch_gpio_get_bit - get a bit
* @chip: chip private data
- * @nr: bit index
+ * @base_reg: base of scratch bits
+ * @offset: index of bit within the register
* @set: is bit set?
*/
static int mv88e6xxx_g2_scratch_get_bit(struct mv88e6xxx_chip *chip,
@@ -68,8 +69,9 @@ static int mv88e6xxx_g2_scratch_get_bit(struct mv88e6xxx_chip *chip,
/**
* mv88e6xxx_g2_scratch_gpio_set_bit - set (or clear) a bit
* @chip: chip private data
- * @nr: bit index
- * @set: set if true, clear if false
+ * @base_reg: base of scratch bits
+ * @offset: index of bit within the register
+ * @set: should this bit be set?
*
* Helper function for dealing with the direction and data registers.
*/
@@ -165,6 +167,7 @@ static int mv88e6352_g2_scratch_gpio_get_dir(struct mv88e6xxx_chip *chip,
* mv88e6352_g2_scratch_gpio_set_dir - set direction of gpio pin
* @chip: chip private data
* @pin: gpio index
+ * @input: should the gpio be an input, or an output?
*/
static int mv88e6352_g2_scratch_gpio_set_dir(struct mv88e6xxx_chip *chip,
unsigned int pin, bool input)
diff --git a/drivers/net/dsa/ocelot/Kconfig b/drivers/net/dsa/ocelot/Kconfig
index a5b7cca03d09..f121619d81fe 100644
--- a/drivers/net/dsa/ocelot/Kconfig
+++ b/drivers/net/dsa/ocelot/Kconfig
@@ -4,11 +4,16 @@ config NET_DSA_MSCC_FELIX
depends on NET_DSA && PCI
depends on NET_VENDOR_MICROSEMI
depends on NET_VENDOR_FREESCALE
- select MSCC_OCELOT_SWITCH
+ depends on HAS_IOMEM
+ select MSCC_OCELOT_SWITCH_LIB
select NET_DSA_TAG_OCELOT
select FSL_ENETC_MDIO
help
- This driver supports the VSC9959 network switch, which is a member of
- the Vitesse / Microsemi / Microchip Ocelot family of switching cores.
- It is embedded as a PCIe function of the NXP LS1028A ENETC integrated
- endpoint.
+ This driver supports network switches from the the Vitesse /
+ Microsemi / Microchip Ocelot family of switching cores that are
+ connected to their host CPU via Ethernet.
+ The following switches are supported:
+ - VSC9959 (Felix): embedded as a PCIe function of the NXP LS1028A
+ ENETC integrated endpoint.
+ - VSC9953 (Seville): embedded as a platform device on the
+ NXP T1040 SoC.
diff --git a/drivers/net/dsa/ocelot/Makefile b/drivers/net/dsa/ocelot/Makefile
index 37ad403e0b2a..ec57a5a12330 100644
--- a/drivers/net/dsa/ocelot/Makefile
+++ b/drivers/net/dsa/ocelot/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_NET_DSA_MSCC_FELIX) += mscc_felix.o
mscc_felix-objs := \
felix.o \
- felix_vsc9959.o
+ felix_vsc9959.o \
+ seville_vsc9953.o
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 66648986e6e3..c69d9592a2b7 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -1,5 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright 2019 NXP Semiconductors
+ *
+ * This is an umbrella module for all network switches that are
+ * register-compatible with Ocelot and that perform I/O to their host CPU
+ * through an NPI (Node Processor Interface) Ethernet port.
*/
#include <uapi/linux/if_bridge.h>
#include <soc/mscc/ocelot_vcap.h>
@@ -9,6 +13,7 @@
#include <soc/mscc/ocelot_ana.h>
#include <soc/mscc/ocelot_ptp.h>
#include <soc/mscc/ocelot.h>
+#include <linux/platform_device.h>
#include <linux/packing.h>
#include <linux/module.h>
#include <linux/of_net.h>
@@ -59,6 +64,29 @@ static int felix_fdb_del(struct dsa_switch *ds, int port,
return ocelot_fdb_del(ocelot, port, addr, vid);
}
+/* This callback needs to be present */
+static int felix_mdb_prepare(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ return 0;
+}
+
+static void felix_mdb_add(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ struct ocelot *ocelot = ds->priv;
+
+ ocelot_port_mdb_add(ocelot, port, mdb);
+}
+
+static int felix_mdb_del(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ struct ocelot *ocelot = ds->priv;
+
+ return ocelot_port_mdb_del(ocelot, port, mdb);
+}
+
static void felix_bridge_stp_state_set(struct dsa_switch *ds, int port,
u8 state)
{
@@ -162,35 +190,10 @@ static void felix_phylink_validate(struct dsa_switch *ds, int port,
struct phylink_link_state *state)
{
struct ocelot *ocelot = ds->priv;
- struct ocelot_port *ocelot_port = ocelot->ports[port];
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-
- if (state->interface != PHY_INTERFACE_MODE_NA &&
- state->interface != ocelot_port->phy_mode) {
- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
- return;
- }
-
- /* No half-duplex. */
- phylink_set_port_modes(mask);
- phylink_set(mask, Autoneg);
- phylink_set(mask, Pause);
- phylink_set(mask, Asym_Pause);
- phylink_set(mask, 10baseT_Full);
- phylink_set(mask, 100baseT_Full);
- phylink_set(mask, 1000baseT_Full);
-
- if (state->interface == PHY_INTERFACE_MODE_INTERNAL ||
- state->interface == PHY_INTERFACE_MODE_2500BASEX ||
- state->interface == PHY_INTERFACE_MODE_USXGMII) {
- phylink_set(mask, 2500baseT_Full);
- phylink_set(mask, 2500baseX_Full);
- }
+ struct felix *felix = ocelot_to_felix(ocelot);
- bitmap_and(supported, supported, mask,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
- bitmap_and(state->advertising, state->advertising, mask,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
+ if (felix->info->phylink_validate)
+ felix->info->phylink_validate(ocelot, port, supported, state);
}
static int felix_phylink_mac_pcs_get_state(struct dsa_switch *ds, int port,
@@ -210,50 +213,10 @@ static void felix_phylink_mac_config(struct dsa_switch *ds, int port,
const struct phylink_link_state *state)
{
struct ocelot *ocelot = ds->priv;
- struct ocelot_port *ocelot_port = ocelot->ports[port];
struct felix *felix = ocelot_to_felix(ocelot);
- u32 mac_fc_cfg;
-
- /* Take port out of reset by clearing the MAC_TX_RST, MAC_RX_RST and
- * PORT_RST bits in CLOCK_CFG
- */
- ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(state->speed),
- DEV_CLOCK_CFG);
-
- /* Flow control. Link speed is only used here to evaluate the time
- * specification in incoming pause frames.
- */
- mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(state->speed);
- /* handle Rx pause in all cases, with 2500base-X this is used for rate
- * adaptation.
- */
- mac_fc_cfg |= SYS_MAC_FC_CFG_RX_FC_ENA;
-
- if (state->pause & MLO_PAUSE_TX)
- mac_fc_cfg |= SYS_MAC_FC_CFG_TX_FC_ENA |
- SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) |
- SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) |
- SYS_MAC_FC_CFG_ZERO_PAUSE_ENA;
- ocelot_write_rix(ocelot, mac_fc_cfg, SYS_MAC_FC_CFG, port);
-
- ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port);
-
- if (felix->info->pcs_init)
- felix->info->pcs_init(ocelot, port, link_an_mode, state);
-
- if (felix->info->port_sched_speed_set)
- felix->info->port_sched_speed_set(ocelot, port,
- state->speed);
-}
-
-static void felix_phylink_mac_an_restart(struct dsa_switch *ds, int port)
-{
- struct ocelot *ocelot = ds->priv;
- struct felix *felix = ocelot_to_felix(ocelot);
-
- if (felix->info->pcs_an_restart)
- felix->info->pcs_an_restart(ocelot, port);
+ if (felix->info->pcs_config)
+ felix->info->pcs_config(ocelot, port, link_an_mode, state);
}
static void felix_phylink_mac_link_down(struct dsa_switch *ds, int port,
@@ -264,8 +227,7 @@ static void felix_phylink_mac_link_down(struct dsa_switch *ds, int port,
struct ocelot_port *ocelot_port = ocelot->ports[port];
ocelot_port_writel(ocelot_port, 0, DEV_MAC_ENA_CFG);
- ocelot_rmw_rix(ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA,
- QSYS_SWITCH_PORT_MODE, port);
+ ocelot_fields_write(ocelot, port, QSYS_SWITCH_PORT_MODE_PORT_ENA, 0);
}
static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port,
@@ -277,8 +239,58 @@ static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port,
{
struct ocelot *ocelot = ds->priv;
struct ocelot_port *ocelot_port = ocelot->ports[port];
+ struct felix *felix = ocelot_to_felix(ocelot);
+ u32 mac_fc_cfg;
+
+ /* Take port out of reset by clearing the MAC_TX_RST, MAC_RX_RST and
+ * PORT_RST bits in DEV_CLOCK_CFG. Note that the way this system is
+ * integrated is that the MAC speed is fixed and it's the PCS who is
+ * performing the rate adaptation, so we have to write "1000Mbps" into
+ * the LINK_SPEED field of DEV_CLOCK_CFG (which is also its default
+ * value).
+ */
+ ocelot_port_writel(ocelot_port,
+ DEV_CLOCK_CFG_LINK_SPEED(OCELOT_SPEED_1000),
+ DEV_CLOCK_CFG);
+
+ switch (speed) {
+ case SPEED_10:
+ mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(3);
+ break;
+ case SPEED_100:
+ mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(2);
+ break;
+ case SPEED_1000:
+ case SPEED_2500:
+ mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(1);
+ break;
+ default:
+ dev_err(ocelot->dev, "Unsupported speed on port %d: %d\n",
+ port, speed);
+ return;
+ }
+
+ /* handle Rx pause in all cases, with 2500base-X this is used for rate
+ * adaptation.
+ */
+ mac_fc_cfg |= SYS_MAC_FC_CFG_RX_FC_ENA;
+
+ if (tx_pause)
+ mac_fc_cfg |= SYS_MAC_FC_CFG_TX_FC_ENA |
+ SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) |
+ SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) |
+ SYS_MAC_FC_CFG_ZERO_PAUSE_ENA;
- /* Enable MAC module */
+ /* Flow control. Link speed is only used here to evaluate the time
+ * specification in incoming pause frames.
+ */
+ ocelot_write_rix(ocelot, mac_fc_cfg, SYS_MAC_FC_CFG, port);
+
+ ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port);
+
+ /* Undo the effects of felix_phylink_mac_link_down:
+ * enable MAC module
+ */
ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA |
DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG);
@@ -291,10 +303,15 @@ static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port,
ANA_PORT_PORT_CFG, port);
/* Core: Enable port for frame transfer */
- ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
- QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
- QSYS_SWITCH_PORT_MODE_PORT_ENA,
- QSYS_SWITCH_PORT_MODE, port);
+ ocelot_fields_write(ocelot, port,
+ QSYS_SWITCH_PORT_MODE_PORT_ENA, 1);
+
+ if (felix->info->pcs_link_up)
+ felix->info->pcs_link_up(ocelot, port, link_an_mode, interface,
+ speed, duplex);
+
+ if (felix->info->port_sched_speed_set)
+ felix->info->port_sched_speed_set(ocelot, port, speed);
}
static void felix_port_qos_map_init(struct ocelot *ocelot, int port)
@@ -417,7 +434,6 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
{
struct ocelot *ocelot = &felix->ocelot;
phy_interface_t *port_phy_modes;
- resource_size_t switch_base;
struct resource res;
int port, i, err;
@@ -448,9 +464,6 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
return err;
}
- switch_base = pci_resource_start(felix->pdev,
- felix->info->switch_pci_bar);
-
for (i = 0; i < TARGET_MAX; i++) {
struct regmap *target;
@@ -459,8 +472,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
memcpy(&res, &felix->info->target_io_res[i], sizeof(res));
res.flags = IORESOURCE_MEM;
- res.start += switch_base;
- res.end += switch_base;
+ res.start += felix->switch_base;
+ res.end += felix->switch_base;
target = ocelot_regmap_init(ocelot, &res);
if (IS_ERR(target)) {
@@ -482,7 +495,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
for (port = 0; port < num_phys_ports; port++) {
struct ocelot_port *ocelot_port;
- void __iomem *port_regs;
+ struct regmap *target;
+ u8 *template;
ocelot_port = devm_kzalloc(ocelot->dev,
sizeof(struct ocelot_port),
@@ -496,21 +510,34 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
memcpy(&res, &felix->info->port_io_res[port], sizeof(res));
res.flags = IORESOURCE_MEM;
- res.start += switch_base;
- res.end += switch_base;
+ res.start += felix->switch_base;
+ res.end += felix->switch_base;
+
+ target = ocelot_regmap_init(ocelot, &res);
+ if (IS_ERR(target)) {
+ dev_err(ocelot->dev,
+ "Failed to map memory space for port %d\n",
+ port);
+ kfree(port_phy_modes);
+ return PTR_ERR(target);
+ }
- port_regs = devm_ioremap_resource(ocelot->dev, &res);
- if (IS_ERR(port_regs)) {
+ template = devm_kzalloc(ocelot->dev, OCELOT_TAG_LEN,
+ GFP_KERNEL);
+ if (!template) {
dev_err(ocelot->dev,
- "failed to map registers for port %d\n", port);
+ "Failed to allocate memory for DSA tag\n");
kfree(port_phy_modes);
- return PTR_ERR(port_regs);
+ return -ENOMEM;
}
ocelot_port->phy_mode = port_phy_modes[port];
ocelot_port->ocelot = ocelot;
- ocelot_port->regs = port_regs;
+ ocelot_port->target = target;
+ ocelot_port->xmit_template = template;
ocelot->ports[port] = ocelot_port;
+
+ felix->info->xmit_template_populate(ocelot, port);
}
kfree(port_phy_modes);
@@ -723,9 +750,7 @@ static int felix_port_policer_add(struct dsa_switch *ds, int port,
struct ocelot *ocelot = ds->priv;
struct ocelot_policer pol = {
.rate = div_u64(policer->rate_bytes_per_sec, 1000) * 8,
- .burst = div_u64(policer->rate_bytes_per_sec *
- PSCHED_NS2TICKS(policer->burst),
- PSCHED_TICKS_PER_SEC),
+ .burst = policer->burst,
};
return ocelot_port_policer_add(ocelot, port, &pol);
@@ -751,7 +776,7 @@ static int felix_port_setup_tc(struct dsa_switch *ds, int port,
return -EOPNOTSUPP;
}
-static const struct dsa_switch_ops felix_switch_ops = {
+const struct dsa_switch_ops felix_switch_ops = {
.get_tag_protocol = felix_get_tag_protocol,
.setup = felix_setup,
.teardown = felix_teardown,
@@ -763,7 +788,6 @@ static const struct dsa_switch_ops felix_switch_ops = {
.phylink_validate = felix_phylink_validate,
.phylink_mac_link_state = felix_phylink_mac_pcs_get_state,
.phylink_mac_config = felix_phylink_mac_config,
- .phylink_mac_an_restart = felix_phylink_mac_an_restart,
.phylink_mac_link_down = felix_phylink_mac_link_down,
.phylink_mac_link_up = felix_phylink_mac_link_up,
.port_enable = felix_port_enable,
@@ -771,6 +795,9 @@ static const struct dsa_switch_ops felix_switch_ops = {
.port_fdb_dump = felix_fdb_dump,
.port_fdb_add = felix_fdb_add,
.port_fdb_del = felix_fdb_del,
+ .port_mdb_prepare = felix_mdb_prepare,
+ .port_mdb_add = felix_mdb_add,
+ .port_mdb_del = felix_mdb_del,
.port_bridge_join = felix_bridge_join,
.port_bridge_leave = felix_bridge_leave,
.port_stp_state_set = felix_bridge_stp_state_set,
@@ -792,149 +819,28 @@ static const struct dsa_switch_ops felix_switch_ops = {
.port_setup_tc = felix_port_setup_tc,
};
-static struct felix_info *felix_instance_tbl[] = {
- [FELIX_INSTANCE_VSC9959] = &felix_info_vsc9959,
-};
-
-static irqreturn_t felix_irq_handler(int irq, void *data)
-{
- struct ocelot *ocelot = (struct ocelot *)data;
-
- /* The INTB interrupt is used for both PTP TX timestamp interrupt
- * and preemption status change interrupt on each port.
- *
- * - Get txtstamp if have
- * - TODO: handle preemption. Without handling it, driver may get
- * interrupt storm.
- */
-
- ocelot_get_txtstamp(ocelot);
-
- return IRQ_HANDLED;
-}
-
-static int felix_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int __init felix_init(void)
{
- enum felix_instance instance = id->driver_data;
- struct dsa_switch *ds;
- struct ocelot *ocelot;
- struct felix *felix;
int err;
- if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
- dev_info(&pdev->dev, "device is disabled, skipping\n");
- return -ENODEV;
- }
-
- err = pci_enable_device(pdev);
- if (err) {
- dev_err(&pdev->dev, "device enable failed\n");
- goto err_pci_enable;
- }
-
- /* set up for high or low dma */
- err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
- if (err) {
- err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
- if (err) {
- dev_err(&pdev->dev,
- "DMA configuration failed: 0x%x\n", err);
- goto err_dma;
- }
- }
-
- felix = kzalloc(sizeof(struct felix), GFP_KERNEL);
- if (!felix) {
- err = -ENOMEM;
- dev_err(&pdev->dev, "Failed to allocate driver memory\n");
- goto err_alloc_felix;
- }
-
- pci_set_drvdata(pdev, felix);
- ocelot = &felix->ocelot;
- ocelot->dev = &pdev->dev;
- felix->pdev = pdev;
- felix->info = felix_instance_tbl[instance];
-
- pci_set_master(pdev);
-
- err = devm_request_threaded_irq(&pdev->dev, pdev->irq, NULL,
- &felix_irq_handler, IRQF_ONESHOT,
- "felix-intb", ocelot);
- if (err) {
- dev_err(&pdev->dev, "Failed to request irq\n");
- goto err_alloc_irq;
- }
-
- ocelot->ptp = 1;
-
- ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL);
- if (!ds) {
- err = -ENOMEM;
- dev_err(&pdev->dev, "Failed to allocate DSA switch\n");
- goto err_alloc_ds;
- }
-
- ds->dev = &pdev->dev;
- ds->num_ports = felix->info->num_ports;
- ds->num_tx_queues = felix->info->num_tx_queues;
- ds->ops = &felix_switch_ops;
- ds->priv = ocelot;
- felix->ds = ds;
+ err = pci_register_driver(&felix_vsc9959_pci_driver);
+ if (err)
+ return err;
- err = dsa_register_switch(ds);
- if (err) {
- dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err);
- goto err_register_ds;
- }
+ err = platform_driver_register(&seville_vsc9953_driver);
+ if (err)
+ return err;
return 0;
-
-err_register_ds:
- kfree(ds);
-err_alloc_ds:
-err_alloc_irq:
-err_alloc_felix:
- kfree(felix);
-err_dma:
- pci_disable_device(pdev);
-err_pci_enable:
- return err;
}
+module_init(felix_init);
-static void felix_pci_remove(struct pci_dev *pdev)
+static void __exit felix_exit(void)
{
- struct felix *felix;
-
- felix = pci_get_drvdata(pdev);
-
- dsa_unregister_switch(felix->ds);
-
- kfree(felix->ds);
- kfree(felix);
-
- pci_disable_device(pdev);
+ pci_unregister_driver(&felix_vsc9959_pci_driver);
+ platform_driver_unregister(&seville_vsc9953_driver);
}
-
-static struct pci_device_id felix_ids[] = {
- {
- /* NXP LS1028A */
- PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0xEEF0),
- .driver_data = FELIX_INSTANCE_VSC9959,
- },
- { 0, }
-};
-MODULE_DEVICE_TABLE(pci, felix_ids);
-
-static struct pci_driver felix_pci_driver = {
- .name = KBUILD_MODNAME,
- .id_table = felix_ids,
- .probe = felix_pci_probe,
- .remove = felix_pci_remove,
-};
-
-module_pci_driver(felix_pci_driver);
+module_exit(felix_exit);
MODULE_DESCRIPTION("Felix Switch driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
index a891736ca006..98f14621ac23 100644
--- a/drivers/net/dsa/ocelot/felix.h
+++ b/drivers/net/dsa/ocelot/felix.h
@@ -28,34 +28,51 @@ struct felix_info {
int imdio_pci_bar;
int (*mdio_bus_alloc)(struct ocelot *ocelot);
void (*mdio_bus_free)(struct ocelot *ocelot);
- void (*pcs_init)(struct ocelot *ocelot, int port,
- unsigned int link_an_mode,
- const struct phylink_link_state *state);
- void (*pcs_an_restart)(struct ocelot *ocelot, int port);
+ void (*pcs_config)(struct ocelot *ocelot, int port,
+ unsigned int link_an_mode,
+ const struct phylink_link_state *state);
+ void (*pcs_link_up)(struct ocelot *ocelot, int port,
+ unsigned int link_an_mode,
+ phy_interface_t interface,
+ int speed, int duplex);
void (*pcs_link_state)(struct ocelot *ocelot, int port,
struct phylink_link_state *state);
+ void (*phylink_validate)(struct ocelot *ocelot, int port,
+ unsigned long *supported,
+ struct phylink_link_state *state);
int (*prevalidate_phy_mode)(struct ocelot *ocelot, int port,
phy_interface_t phy_mode);
int (*port_setup_tc)(struct dsa_switch *ds, int port,
enum tc_setup_type type, void *type_data);
void (*port_sched_speed_set)(struct ocelot *ocelot, int port,
u32 speed);
+ void (*xmit_template_populate)(struct ocelot *ocelot, int port);
};
-extern struct felix_info felix_info_vsc9959;
-
-enum felix_instance {
- FELIX_INSTANCE_VSC9959 = 0,
-};
+extern const struct dsa_switch_ops felix_switch_ops;
+extern struct pci_driver felix_vsc9959_pci_driver;
+extern struct platform_driver seville_vsc9953_driver;
/* DSA glue / front-end for struct ocelot */
struct felix {
struct dsa_switch *ds;
- struct pci_dev *pdev;
- struct felix_info *info;
+ const struct felix_info *info;
struct ocelot ocelot;
struct mii_bus *imdio;
struct phy_device **pcs;
+ resource_size_t switch_base;
+ resource_size_t imdio_base;
};
+void vsc9959_pcs_link_state(struct ocelot *ocelot, int port,
+ struct phylink_link_state *state);
+void vsc9959_pcs_config(struct ocelot *ocelot, int port,
+ unsigned int link_an_mode,
+ const struct phylink_link_state *state);
+void vsc9959_pcs_link_up(struct ocelot *ocelot, int port,
+ unsigned int link_an_mode,
+ phy_interface_t interface,
+ int speed, int duplex);
+void vsc9959_mdio_bus_free(struct ocelot *ocelot);
+
#endif
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 1dd9e348152d..9b720c8ddfc3 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -8,37 +8,18 @@
#include <soc/mscc/ocelot_ptp.h>
#include <soc/mscc/ocelot_sys.h>
#include <soc/mscc/ocelot.h>
+#include <linux/packing.h>
#include <net/pkt_sched.h>
#include <linux/iopoll.h>
+#include <linux/mdio.h>
#include <linux/pci.h>
#include "felix.h"
#define VSC9959_VCAP_IS2_CNT 1024
#define VSC9959_VCAP_IS2_ENTRY_WIDTH 376
#define VSC9959_VCAP_PORT_CNT 6
-
-/* TODO: should find a better place for these */
-#define USXGMII_BMCR_RESET BIT(15)
-#define USXGMII_BMCR_AN_EN BIT(12)
-#define USXGMII_BMCR_RST_AN BIT(9)
-#define USXGMII_BMSR_LNKS(status) (((status) & GENMASK(2, 2)) >> 2)
-#define USXGMII_BMSR_AN_CMPL(status) (((status) & GENMASK(5, 5)) >> 5)
-#define USXGMII_ADVERTISE_LNKS(x) (((x) << 15) & BIT(15))
-#define USXGMII_ADVERTISE_FDX BIT(12)
-#define USXGMII_ADVERTISE_SPEED(x) (((x) << 9) & GENMASK(11, 9))
-#define USXGMII_LPA_LNKS(lpa) ((lpa) >> 15)
-#define USXGMII_LPA_DUPLEX(lpa) (((lpa) & GENMASK(12, 12)) >> 12)
-#define USXGMII_LPA_SPEED(lpa) (((lpa) & GENMASK(11, 9)) >> 9)
-
#define VSC9959_TAS_GCL_ENTRY_MAX 63
-enum usxgmii_speed {
- USXGMII_SPEED_10 = 0,
- USXGMII_SPEED_100 = 1,
- USXGMII_SPEED_1000 = 2,
- USXGMII_SPEED_2500 = 4,
-};
-
static const u32 vsc9959_ana_regmap[] = {
REG(ANA_ADVLEARN, 0x0089a0),
REG(ANA_VLANMASK, 0x0089a4),
@@ -329,7 +310,49 @@ static const u32 vsc9959_gcb_regmap[] = {
REG(GCB_SOFT_RST, 0x000004),
};
-static const u32 *vsc9959_regmap[] = {
+static const u32 vsc9959_dev_gmii_regmap[] = {
+ REG(DEV_CLOCK_CFG, 0x0),
+ REG(DEV_PORT_MISC, 0x4),
+ REG(DEV_EVENTS, 0x8),
+ REG(DEV_EEE_CFG, 0xc),
+ REG(DEV_RX_PATH_DELAY, 0x10),
+ REG(DEV_TX_PATH_DELAY, 0x14),
+ REG(DEV_PTP_PREDICT_CFG, 0x18),
+ REG(DEV_MAC_ENA_CFG, 0x1c),
+ REG(DEV_MAC_MODE_CFG, 0x20),
+ REG(DEV_MAC_MAXLEN_CFG, 0x24),
+ REG(DEV_MAC_TAGS_CFG, 0x28),
+ REG(DEV_MAC_ADV_CHK_CFG, 0x2c),
+ REG(DEV_MAC_IFG_CFG, 0x30),
+ REG(DEV_MAC_HDX_CFG, 0x34),
+ REG(DEV_MAC_DBG_CFG, 0x38),
+ REG(DEV_MAC_FC_MAC_LOW_CFG, 0x3c),
+ REG(DEV_MAC_FC_MAC_HIGH_CFG, 0x40),
+ REG(DEV_MAC_STICKY, 0x44),
+ REG_RESERVED(PCS1G_CFG),
+ REG_RESERVED(PCS1G_MODE_CFG),
+ REG_RESERVED(PCS1G_SD_CFG),
+ REG_RESERVED(PCS1G_ANEG_CFG),
+ REG_RESERVED(PCS1G_ANEG_NP_CFG),
+ REG_RESERVED(PCS1G_LB_CFG),
+ REG_RESERVED(PCS1G_DBG_CFG),
+ REG_RESERVED(PCS1G_CDET_CFG),
+ REG_RESERVED(PCS1G_ANEG_STATUS),
+ REG_RESERVED(PCS1G_ANEG_NP_STATUS),
+ REG_RESERVED(PCS1G_LINK_STATUS),
+ REG_RESERVED(PCS1G_LINK_DOWN_CNT),
+ REG_RESERVED(PCS1G_STICKY),
+ REG_RESERVED(PCS1G_DEBUG_STATUS),
+ REG_RESERVED(PCS1G_LPI_CFG),
+ REG_RESERVED(PCS1G_LPI_WAKE_ERROR_CNT),
+ REG_RESERVED(PCS1G_LPI_STATUS),
+ REG_RESERVED(PCS1G_TSTPAT_MODE_CFG),
+ REG_RESERVED(PCS1G_TSTPAT_STATUS),
+ REG_RESERVED(DEV_PCS_FX100_CFG),
+ REG_RESERVED(DEV_PCS_FX100_STATUS),
+};
+
+static const u32 *vsc9959_regmap[TARGET_MAX] = {
[ANA] = vsc9959_ana_regmap,
[QS] = vsc9959_qs_regmap,
[QSYS] = vsc9959_qsys_regmap,
@@ -338,10 +361,11 @@ static const u32 *vsc9959_regmap[] = {
[S2] = vsc9959_s2_regmap,
[PTP] = vsc9959_ptp_regmap,
[GCB] = vsc9959_gcb_regmap,
+ [DEV_GMII] = vsc9959_dev_gmii_regmap,
};
/* Addresses are relative to the PCI device's base address */
-static const struct resource vsc9959_target_io_res[] = {
+static const struct resource vsc9959_target_io_res[TARGET_MAX] = {
[ANA] = {
.start = 0x0280000,
.end = 0x028ffff,
@@ -426,7 +450,7 @@ static const struct resource vsc9959_imdio_res = {
.name = "imdio",
};
-static const struct reg_field vsc9959_regfields[] = {
+static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = {
[ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 6, 6),
[ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 5),
[ANA_ANEVENTS_FLOOD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 30, 30),
@@ -460,6 +484,20 @@ static const struct reg_field vsc9959_regfields[] = {
[ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 10),
[SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 0, 0),
[GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 0, 0),
+ /* Replicated per number of ports (7), register size 4 per port */
+ [QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 14, 14, 7, 4),
+ [QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 11, 13, 7, 4),
+ [QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 7, 4),
+ [QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 7, 4),
+ [QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 7, 4),
+ [QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 7, 4),
+ [SYS_PORT_MODE_DATA_WO_TS] = REG_FIELD_ID(SYS_PORT_MODE, 5, 6, 7, 4),
+ [SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 3, 4, 7, 4),
+ [SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 1, 2, 7, 4),
+ [SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 7, 4),
+ [SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 10, 18, 7, 4),
+ [SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 9, 7, 4),
+ [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 7, 4),
};
static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
@@ -557,7 +595,7 @@ static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
{ .offset = 0x111, .name = "drop_green_prio_7", },
};
-struct vcap_field vsc9959_vcap_is2_keys[] = {
+static struct vcap_field vsc9959_vcap_is2_keys[] = {
/* Common: 41 bits */
[VCAP_IS2_TYPE] = { 0, 4},
[VCAP_IS2_HK_FIRST] = { 4, 1},
@@ -637,7 +675,7 @@ struct vcap_field vsc9959_vcap_is2_keys[] = {
[VCAP_IS2_HK_OAM_IS_Y1731] = {182, 1},
};
-struct vcap_field vsc9959_vcap_is2_actions[] = {
+static struct vcap_field vsc9959_vcap_is2_actions[] = {
[VCAP_IS2_ACT_HIT_ME_ONCE] = { 0, 1},
[VCAP_IS2_ACT_CPU_COPY_ENA] = { 1, 1},
[VCAP_IS2_ACT_CPU_QU_NUM] = { 2, 3},
@@ -728,20 +766,74 @@ static int vsc9959_reset(struct ocelot *ocelot)
return 0;
}
-static void vsc9959_pcs_an_restart_sgmii(struct phy_device *pcs)
+/* We enable SGMII AN only when the PHY has managed = "in-band-status" in the
+ * device tree. If we are in MLO_AN_PHY mode, we program directly state->speed
+ * into the PCS, which is retrieved out-of-band over MDIO. This also has the
+ * benefit of working with SGMII fixed-links, like downstream switches, where
+ * both link partners attempt to operate as AN slaves and therefore AN never
+ * completes. But it also has the disadvantage that some PHY chips don't pass
+ * traffic if SGMII AN is enabled but not completed (acknowledged by us), so
+ * setting MLO_AN_INBAND is actually required for those.
+ */
+static void vsc9959_pcs_config_sgmii(struct phy_device *pcs,
+ unsigned int link_an_mode,
+ const struct phylink_link_state *state)
{
- phy_set_bits(pcs, MII_BMCR, BMCR_ANRESTART);
+ int bmsr, bmcr;
+
+ /* Some PHYs like VSC8234 don't like it when AN restarts on
+ * their system side and they restart line side AN too, going
+ * into an endless link up/down loop. Don't restart PCS AN if
+ * link is up already.
+ * We do check that AN is enabled just in case this is the 1st
+ * call, PCS detects a carrier but AN is disabled from power on
+ * or by boot loader.
+ */
+ bmcr = phy_read(pcs, MII_BMCR);
+ if (bmcr < 0)
+ return;
+
+ bmsr = phy_read(pcs, MII_BMSR);
+ if (bmsr < 0)
+ return;
+
+ if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_LSTATUS))
+ return;
+
+ /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001
+ * for the MAC PCS in order to acknowledge the AN.
+ */
+ phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII |
+ ADVERTISE_LPACK);
+
+ phy_write(pcs, ENETC_PCS_IF_MODE,
+ ENETC_PCS_IF_MODE_SGMII_EN |
+ ENETC_PCS_IF_MODE_USE_SGMII_AN);
+
+ /* Adjust link timer for SGMII */
+ phy_write(pcs, ENETC_PCS_LINK_TIMER1,
+ ENETC_PCS_LINK_TIMER1_VAL);
+ phy_write(pcs, ENETC_PCS_LINK_TIMER2,
+ ENETC_PCS_LINK_TIMER2_VAL);
+
+ phy_set_bits(pcs, MII_BMCR, BMCR_ANENABLE);
}
-static void vsc9959_pcs_an_restart_usxgmii(struct phy_device *pcs)
+static void vsc9959_pcs_config_usxgmii(struct phy_device *pcs,
+ unsigned int link_an_mode,
+ const struct phylink_link_state *state)
{
- phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_BMCR,
- USXGMII_BMCR_RESET |
- USXGMII_BMCR_AN_EN |
- USXGMII_BMCR_RST_AN);
+ /* Configure device ability for the USXGMII Replicator */
+ phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_ADVERTISE,
+ MDIO_USXGMII_2500FULL |
+ MDIO_USXGMII_LINK |
+ ADVERTISE_SGMII |
+ ADVERTISE_LPACK);
}
-static void vsc9959_pcs_an_restart(struct ocelot *ocelot, int port)
+void vsc9959_pcs_config(struct ocelot *ocelot, int port,
+ unsigned int link_an_mode,
+ const struct phylink_link_state *state)
{
struct felix *felix = ocelot_to_felix(ocelot);
struct phy_device *pcs = felix->pcs[port];
@@ -749,107 +841,76 @@ static void vsc9959_pcs_an_restart(struct ocelot *ocelot, int port)
if (!pcs)
return;
+ /* The PCS does not implement the BMSR register fully, so capability
+ * detection via genphy_read_abilities does not work. Since we can get
+ * the PHY config word from the LPA register though, there is still
+ * value in using the generic phy_resolve_aneg_linkmode function. So
+ * populate the supported and advertising link modes manually here.
+ */
+ linkmode_set_bit_array(phy_basic_ports_array,
+ ARRAY_SIZE(phy_basic_ports_array),
+ pcs->supported);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, pcs->supported);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, pcs->supported);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, pcs->supported);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, pcs->supported);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, pcs->supported);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, pcs->supported);
+ if (pcs->interface == PHY_INTERFACE_MODE_2500BASEX ||
+ pcs->interface == PHY_INTERFACE_MODE_USXGMII)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
+ pcs->supported);
+ if (pcs->interface != PHY_INTERFACE_MODE_2500BASEX)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+ pcs->supported);
+ phy_advertise_supported(pcs);
+
+ if (!phylink_autoneg_inband(link_an_mode))
+ return;
+
switch (pcs->interface) {
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_QSGMII:
- vsc9959_pcs_an_restart_sgmii(pcs);
+ vsc9959_pcs_config_sgmii(pcs, link_an_mode, state);
+ break;
+ case PHY_INTERFACE_MODE_2500BASEX:
+ phydev_err(pcs, "AN not supported on 3.125GHz SerDes lane\n");
break;
case PHY_INTERFACE_MODE_USXGMII:
- vsc9959_pcs_an_restart_usxgmii(pcs);
+ vsc9959_pcs_config_usxgmii(pcs, link_an_mode, state);
break;
default:
- dev_err(ocelot->dev, "Invalid PCS interface type %s\n",
+ dev_err(ocelot->dev, "Unsupported link mode %s\n",
phy_modes(pcs->interface));
- break;
}
}
-/* We enable SGMII AN only when the PHY has managed = "in-band-status" in the
- * device tree. If we are in MLO_AN_PHY mode, we program directly state->speed
- * into the PCS, which is retrieved out-of-band over MDIO. This also has the
- * benefit of working with SGMII fixed-links, like downstream switches, where
- * both link partners attempt to operate as AN slaves and therefore AN never
- * completes. But it also has the disadvantage that some PHY chips don't pass
- * traffic if SGMII AN is enabled but not completed (acknowledged by us), so
- * setting MLO_AN_INBAND is actually required for those.
- */
-static void vsc9959_pcs_init_sgmii(struct phy_device *pcs,
- unsigned int link_an_mode,
- const struct phylink_link_state *state)
+static void vsc9959_pcs_link_up_sgmii(struct phy_device *pcs,
+ unsigned int link_an_mode,
+ int speed, int duplex)
{
- if (link_an_mode == MLO_AN_INBAND) {
- int bmsr, bmcr;
-
- /* Some PHYs like VSC8234 don't like it when AN restarts on
- * their system side and they restart line side AN too, going
- * into an endless link up/down loop. Don't restart PCS AN if
- * link is up already.
- * We do check that AN is enabled just in case this is the 1st
- * call, PCS detects a carrier but AN is disabled from power on
- * or by boot loader.
- */
- bmcr = phy_read(pcs, MII_BMCR);
- if (bmcr < 0)
- return;
-
- bmsr = phy_read(pcs, MII_BMSR);
- if (bmsr < 0)
- return;
-
- if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_LSTATUS))
- return;
-
- /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001
- * for the MAC PCS in order to acknowledge the AN.
- */
- phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII |
- ADVERTISE_LPACK);
-
- phy_write(pcs, ENETC_PCS_IF_MODE,
- ENETC_PCS_IF_MODE_SGMII_EN |
- ENETC_PCS_IF_MODE_USE_SGMII_AN);
-
- /* Adjust link timer for SGMII */
- phy_write(pcs, ENETC_PCS_LINK_TIMER1,
- ENETC_PCS_LINK_TIMER1_VAL);
- phy_write(pcs, ENETC_PCS_LINK_TIMER2,
- ENETC_PCS_LINK_TIMER2_VAL);
-
- phy_write(pcs, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE);
- } else {
- int speed;
-
- if (state->duplex == DUPLEX_HALF) {
- phydev_err(pcs, "Half duplex not supported\n");
- return;
- }
- switch (state->speed) {
- case SPEED_1000:
- speed = ENETC_PCS_SPEED_1000;
- break;
- case SPEED_100:
- speed = ENETC_PCS_SPEED_100;
- break;
- case SPEED_10:
- speed = ENETC_PCS_SPEED_10;
- break;
- case SPEED_UNKNOWN:
- /* Silently don't do anything */
- return;
- default:
- phydev_err(pcs, "Invalid PCS speed %d\n", state->speed);
- return;
- }
-
- phy_write(pcs, ENETC_PCS_IF_MODE,
- ENETC_PCS_IF_MODE_SGMII_EN |
- ENETC_PCS_IF_MODE_SGMII_SPEED(speed));
+ u16 if_mode = ENETC_PCS_IF_MODE_SGMII_EN;
- /* Yes, not a mistake: speed is given by IF_MODE. */
- phy_write(pcs, MII_BMCR, BMCR_RESET |
- BMCR_SPEED1000 |
- BMCR_FULLDPLX);
+ switch (speed) {
+ case SPEED_1000:
+ if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_1000);
+ break;
+ case SPEED_100:
+ if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_100);
+ break;
+ case SPEED_10:
+ if_mode |= ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_10);
+ break;
+ default:
+ phydev_err(pcs, "Invalid PCS speed %d\n", speed);
+ return;
}
+
+ if (duplex == DUPLEX_HALF)
+ if_mode |= ENETC_PCS_IF_MODE_DUPLEX_HALF;
+
+ phy_write(pcs, ENETC_PCS_IF_MODE, if_mode);
+ phy_clear_bits(pcs, MII_BMCR, BMCR_ANENABLE);
}
/* 2500Base-X is SerDes protocol 7 on Felix and 6 on ENETC. It is a SerDes lane
@@ -869,45 +930,24 @@ static void vsc9959_pcs_init_sgmii(struct phy_device *pcs,
* lower link speed on line side, the system-side interface remains fixed at
* 2500 Mbps and we do rate adaptation through pause frames.
*/
-static void vsc9959_pcs_init_2500basex(struct phy_device *pcs,
- unsigned int link_an_mode,
- const struct phylink_link_state *state)
+static void vsc9959_pcs_link_up_2500basex(struct phy_device *pcs,
+ unsigned int link_an_mode,
+ int speed, int duplex)
{
- if (link_an_mode == MLO_AN_INBAND) {
- phydev_err(pcs, "AN not supported on 3.125GHz SerDes lane\n");
- return;
- }
-
- phy_write(pcs, ENETC_PCS_IF_MODE,
- ENETC_PCS_IF_MODE_SGMII_EN |
- ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500));
-
- phy_write(pcs, MII_BMCR, BMCR_SPEED1000 |
- BMCR_FULLDPLX |
- BMCR_RESET);
-}
+ u16 if_mode = ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500) |
+ ENETC_PCS_IF_MODE_SGMII_EN;
-static void vsc9959_pcs_init_usxgmii(struct phy_device *pcs,
- unsigned int link_an_mode,
- const struct phylink_link_state *state)
-{
- if (link_an_mode != MLO_AN_INBAND) {
- phydev_err(pcs, "USXGMII only supports in-band AN for now\n");
- return;
- }
+ if (duplex == DUPLEX_HALF)
+ if_mode |= ENETC_PCS_IF_MODE_DUPLEX_HALF;
- /* Configure device ability for the USXGMII Replicator */
- phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_ADVERTISE,
- USXGMII_ADVERTISE_SPEED(USXGMII_SPEED_2500) |
- USXGMII_ADVERTISE_LNKS(1) |
- ADVERTISE_SGMII |
- ADVERTISE_LPACK |
- USXGMII_ADVERTISE_FDX);
+ phy_write(pcs, ENETC_PCS_IF_MODE, if_mode);
+ phy_clear_bits(pcs, MII_BMCR, BMCR_ANENABLE);
}
-static void vsc9959_pcs_init(struct ocelot *ocelot, int port,
- unsigned int link_an_mode,
- const struct phylink_link_state *state)
+void vsc9959_pcs_link_up(struct ocelot *ocelot, int port,
+ unsigned int link_an_mode,
+ phy_interface_t interface,
+ int speed, int duplex)
{
struct felix *felix = ocelot_to_felix(ocelot);
struct phy_device *pcs = felix->pcs[port];
@@ -915,37 +955,20 @@ static void vsc9959_pcs_init(struct ocelot *ocelot, int port,
if (!pcs)
return;
- /* The PCS does not implement the BMSR register fully, so capability
- * detection via genphy_read_abilities does not work. Since we can get
- * the PHY config word from the LPA register though, there is still
- * value in using the generic phy_resolve_aneg_linkmode function. So
- * populate the supported and advertising link modes manually here.
- */
- linkmode_set_bit_array(phy_basic_ports_array,
- ARRAY_SIZE(phy_basic_ports_array),
- pcs->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, pcs->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, pcs->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, pcs->supported);
- if (pcs->interface == PHY_INTERFACE_MODE_2500BASEX ||
- pcs->interface == PHY_INTERFACE_MODE_USXGMII)
- linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
- pcs->supported);
- if (pcs->interface != PHY_INTERFACE_MODE_2500BASEX)
- linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
- pcs->supported);
- phy_advertise_supported(pcs);
+ if (phylink_autoneg_inband(link_an_mode))
+ return;
- switch (pcs->interface) {
+ switch (interface) {
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_QSGMII:
- vsc9959_pcs_init_sgmii(pcs, link_an_mode, state);
+ vsc9959_pcs_link_up_sgmii(pcs, link_an_mode, speed, duplex);
break;
case PHY_INTERFACE_MODE_2500BASEX:
- vsc9959_pcs_init_2500basex(pcs, link_an_mode, state);
+ vsc9959_pcs_link_up_2500basex(pcs, link_an_mode, speed,
+ duplex);
break;
case PHY_INTERFACE_MODE_USXGMII:
- vsc9959_pcs_init_usxgmii(pcs, link_an_mode, state);
+ phydev_err(pcs, "USXGMII only supports in-band AN for now\n");
break;
default:
dev_err(ocelot->dev, "Unsupported link mode %s\n",
@@ -1019,8 +1042,8 @@ static void vsc9959_pcs_link_state_usxgmii(struct phy_device *pcs,
return;
pcs->autoneg = true;
- pcs->autoneg_complete = USXGMII_BMSR_AN_CMPL(status);
- pcs->link = USXGMII_BMSR_LNKS(status);
+ pcs->autoneg_complete = !!(status & BMSR_ANEGCOMPLETE);
+ pcs->link = !!(status & BMSR_LSTATUS);
if (!pcs->link || !pcs->autoneg_complete)
return;
@@ -1029,31 +1052,31 @@ static void vsc9959_pcs_link_state_usxgmii(struct phy_device *pcs,
if (lpa < 0)
return;
- switch (USXGMII_LPA_SPEED(lpa)) {
- case USXGMII_SPEED_10:
+ switch (lpa & MDIO_USXGMII_SPD_MASK) {
+ case MDIO_USXGMII_10:
pcs->speed = SPEED_10;
break;
- case USXGMII_SPEED_100:
+ case MDIO_USXGMII_100:
pcs->speed = SPEED_100;
break;
- case USXGMII_SPEED_1000:
+ case MDIO_USXGMII_1000:
pcs->speed = SPEED_1000;
break;
- case USXGMII_SPEED_2500:
+ case MDIO_USXGMII_2500:
pcs->speed = SPEED_2500;
break;
default:
break;
}
- if (USXGMII_LPA_DUPLEX(lpa))
+ if (lpa & MDIO_USXGMII_FULL_DUPLEX)
pcs->duplex = DUPLEX_FULL;
else
pcs->duplex = DUPLEX_HALF;
}
-static void vsc9959_pcs_link_state(struct ocelot *ocelot, int port,
- struct phylink_link_state *state)
+void vsc9959_pcs_link_state(struct ocelot *ocelot, int port,
+ struct phylink_link_state *state)
{
struct felix *felix = ocelot_to_felix(ocelot);
struct phy_device *pcs = felix->pcs[port];
@@ -1084,6 +1107,43 @@ static void vsc9959_pcs_link_state(struct ocelot *ocelot, int port,
vsc9959_pcs_link_state_resolve(pcs, state);
}
+static void vsc9959_phylink_validate(struct ocelot *ocelot, int port,
+ unsigned long *supported,
+ struct phylink_link_state *state)
+{
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
+ if (state->interface != PHY_INTERFACE_MODE_NA &&
+ state->interface != ocelot_port->phy_mode) {
+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
+ return;
+ }
+
+ phylink_set_port_modes(mask);
+ phylink_set(mask, Autoneg);
+ phylink_set(mask, Pause);
+ phylink_set(mask, Asym_Pause);
+ phylink_set(mask, 10baseT_Half);
+ phylink_set(mask, 10baseT_Full);
+ phylink_set(mask, 100baseT_Half);
+ phylink_set(mask, 100baseT_Full);
+ phylink_set(mask, 1000baseT_Half);
+ phylink_set(mask, 1000baseT_Full);
+
+ if (state->interface == PHY_INTERFACE_MODE_INTERNAL ||
+ state->interface == PHY_INTERFACE_MODE_2500BASEX ||
+ state->interface == PHY_INTERFACE_MODE_USXGMII) {
+ phylink_set(mask, 2500baseT_Full);
+ phylink_set(mask, 2500baseX_Full);
+ }
+
+ bitmap_and(supported, supported, mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ bitmap_and(state->advertising, state->advertising, mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port,
phy_interface_t phy_mode)
{
@@ -1105,8 +1165,21 @@ static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port,
}
}
+/* Watermark encode
+ * Bit 8: Unit; 0:1, 1:16
+ * Bit 7-0: Value to be multiplied with unit
+ */
+static u16 vsc9959_wm_enc(u16 value)
+{
+ if (value >= BIT(8))
+ return BIT(8) | (value / 16);
+
+ return value;
+}
+
static const struct ocelot_ops vsc9959_ops = {
.reset = vsc9959_reset,
+ .wm_enc = vsc9959_wm_enc,
};
static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
@@ -1114,7 +1187,6 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
struct felix *felix = ocelot_to_felix(ocelot);
struct enetc_mdio_priv *mdio_priv;
struct device *dev = ocelot->dev;
- resource_size_t imdio_base;
void __iomem *imdio_regs;
struct resource res;
struct enetc_hw *hw;
@@ -1130,13 +1202,10 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
return -ENOMEM;
}
- imdio_base = pci_resource_start(felix->pdev,
- felix->info->imdio_pci_bar);
-
memcpy(&res, felix->info->imdio_res, sizeof(res));
res.flags = IORESOURCE_MEM;
- res.start += imdio_base;
- res.end += imdio_base;
+ res.start += felix->imdio_base;
+ res.end += felix->imdio_base;
imdio_regs = devm_ioremap_resource(dev, &res);
if (IS_ERR(imdio_regs)) {
@@ -1196,7 +1265,7 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
return 0;
}
-static void vsc9959_mdio_bus_free(struct ocelot *ocelot)
+void vsc9959_mdio_bus_free(struct ocelot *ocelot)
{
struct felix *felix = ocelot_to_felix(ocelot);
int port;
@@ -1392,7 +1461,25 @@ static int vsc9959_port_setup_tc(struct dsa_switch *ds, int port,
}
}
-struct felix_info felix_info_vsc9959 = {
+static void vsc9959_xmit_template_populate(struct ocelot *ocelot, int port)
+{
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ u8 *template = ocelot_port->xmit_template;
+ u64 bypass, dest, src;
+
+ /* Set the source port as the CPU port module and not the
+ * NPI port
+ */
+ src = ocelot->num_phys_ports;
+ dest = BIT(port);
+ bypass = true;
+
+ packing(template, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
+ packing(template, &dest, 68, 56, OCELOT_TAG_LEN, PACK, 0);
+ packing(template, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0);
+}
+
+static const struct felix_info felix_info_vsc9959 = {
.target_io_res = vsc9959_target_io_res,
.port_io_res = vsc9959_port_io_res,
.imdio_res = &vsc9959_imdio_res,
@@ -1412,10 +1499,151 @@ struct felix_info felix_info_vsc9959 = {
.imdio_pci_bar = 0,
.mdio_bus_alloc = vsc9959_mdio_bus_alloc,
.mdio_bus_free = vsc9959_mdio_bus_free,
- .pcs_init = vsc9959_pcs_init,
- .pcs_an_restart = vsc9959_pcs_an_restart,
+ .pcs_config = vsc9959_pcs_config,
+ .pcs_link_up = vsc9959_pcs_link_up,
.pcs_link_state = vsc9959_pcs_link_state,
+ .phylink_validate = vsc9959_phylink_validate,
.prevalidate_phy_mode = vsc9959_prevalidate_phy_mode,
.port_setup_tc = vsc9959_port_setup_tc,
.port_sched_speed_set = vsc9959_sched_speed_set,
+ .xmit_template_populate = vsc9959_xmit_template_populate,
+};
+
+static irqreturn_t felix_irq_handler(int irq, void *data)
+{
+ struct ocelot *ocelot = (struct ocelot *)data;
+
+ /* The INTB interrupt is used for both PTP TX timestamp interrupt
+ * and preemption status change interrupt on each port.
+ *
+ * - Get txtstamp if have
+ * - TODO: handle preemption. Without handling it, driver may get
+ * interrupt storm.
+ */
+
+ ocelot_get_txtstamp(ocelot);
+
+ return IRQ_HANDLED;
+}
+
+static int felix_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct dsa_switch *ds;
+ struct ocelot *ocelot;
+ struct felix *felix;
+ int err;
+
+ if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
+ dev_info(&pdev->dev, "device is disabled, skipping\n");
+ return -ENODEV;
+ }
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "device enable failed\n");
+ goto err_pci_enable;
+ }
+
+ /* set up for high or low dma */
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+ if (err) {
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (err) {
+ dev_err(&pdev->dev,
+ "DMA configuration failed: 0x%x\n", err);
+ goto err_dma;
+ }
+ }
+
+ felix = kzalloc(sizeof(struct felix), GFP_KERNEL);
+ if (!felix) {
+ err = -ENOMEM;
+ dev_err(&pdev->dev, "Failed to allocate driver memory\n");
+ goto err_alloc_felix;
+ }
+
+ pci_set_drvdata(pdev, felix);
+ ocelot = &felix->ocelot;
+ ocelot->dev = &pdev->dev;
+ felix->info = &felix_info_vsc9959;
+ felix->switch_base = pci_resource_start(pdev,
+ felix->info->switch_pci_bar);
+ felix->imdio_base = pci_resource_start(pdev,
+ felix->info->imdio_pci_bar);
+
+ pci_set_master(pdev);
+
+ err = devm_request_threaded_irq(&pdev->dev, pdev->irq, NULL,
+ &felix_irq_handler, IRQF_ONESHOT,
+ "felix-intb", ocelot);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to request irq\n");
+ goto err_alloc_irq;
+ }
+
+ ocelot->ptp = 1;
+
+ ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL);
+ if (!ds) {
+ err = -ENOMEM;
+ dev_err(&pdev->dev, "Failed to allocate DSA switch\n");
+ goto err_alloc_ds;
+ }
+
+ ds->dev = &pdev->dev;
+ ds->num_ports = felix->info->num_ports;
+ ds->num_tx_queues = felix->info->num_tx_queues;
+ ds->ops = &felix_switch_ops;
+ ds->priv = ocelot;
+ felix->ds = ds;
+
+ err = dsa_register_switch(ds);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err);
+ goto err_register_ds;
+ }
+
+ return 0;
+
+err_register_ds:
+ kfree(ds);
+err_alloc_ds:
+err_alloc_irq:
+err_alloc_felix:
+ kfree(felix);
+err_dma:
+ pci_disable_device(pdev);
+err_pci_enable:
+ return err;
+}
+
+static void felix_pci_remove(struct pci_dev *pdev)
+{
+ struct felix *felix;
+
+ felix = pci_get_drvdata(pdev);
+
+ dsa_unregister_switch(felix->ds);
+
+ kfree(felix->ds);
+ kfree(felix);
+
+ pci_disable_device(pdev);
+}
+
+static struct pci_device_id felix_ids[] = {
+ {
+ /* NXP LS1028A */
+ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0xEEF0),
+ },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, felix_ids);
+
+struct pci_driver felix_vsc9959_pci_driver = {
+ .name = "mscc_felix",
+ .id_table = felix_ids,
+ .probe = felix_pci_probe,
+ .remove = felix_pci_remove,
};
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
new file mode 100644
index 000000000000..625b1891d955
--- /dev/null
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -0,0 +1,1104 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/* Distributed Switch Architecture VSC9953 driver
+ * Copyright (C) 2020, Maxim Kochetkov <fido_max@inbox.ru>
+ */
+#include <linux/types.h>
+#include <soc/mscc/ocelot_vcap.h>
+#include <soc/mscc/ocelot_sys.h>
+#include <soc/mscc/ocelot.h>
+#include <linux/of_platform.h>
+#include <linux/packing.h>
+#include <linux/iopoll.h>
+#include "felix.h"
+
+#define VSC9953_VCAP_IS2_CNT 1024
+#define VSC9953_VCAP_IS2_ENTRY_WIDTH 376
+#define VSC9953_VCAP_PORT_CNT 10
+
+#define MSCC_MIIM_REG_STATUS 0x0
+#define MSCC_MIIM_STATUS_STAT_BUSY BIT(3)
+#define MSCC_MIIM_REG_CMD 0x8
+#define MSCC_MIIM_CMD_OPR_WRITE BIT(1)
+#define MSCC_MIIM_CMD_OPR_READ BIT(2)
+#define MSCC_MIIM_CMD_WRDATA_SHIFT 4
+#define MSCC_MIIM_CMD_REGAD_SHIFT 20
+#define MSCC_MIIM_CMD_PHYAD_SHIFT 25
+#define MSCC_MIIM_CMD_VLD BIT(31)
+#define MSCC_MIIM_REG_DATA 0xC
+#define MSCC_MIIM_DATA_ERROR (BIT(16) | BIT(17))
+
+#define MSCC_PHY_REG_PHY_CFG 0x0
+#define PHY_CFG_PHY_ENA (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define PHY_CFG_PHY_COMMON_RESET BIT(4)
+#define PHY_CFG_PHY_RESET (BIT(5) | BIT(6) | BIT(7) | BIT(8))
+#define MSCC_PHY_REG_PHY_STATUS 0x4
+
+static const u32 vsc9953_ana_regmap[] = {
+ REG(ANA_ADVLEARN, 0x00b500),
+ REG(ANA_VLANMASK, 0x00b504),
+ REG_RESERVED(ANA_PORT_B_DOMAIN),
+ REG(ANA_ANAGEFIL, 0x00b50c),
+ REG(ANA_ANEVENTS, 0x00b510),
+ REG(ANA_STORMLIMIT_BURST, 0x00b514),
+ REG(ANA_STORMLIMIT_CFG, 0x00b518),
+ REG(ANA_ISOLATED_PORTS, 0x00b528),
+ REG(ANA_COMMUNITY_PORTS, 0x00b52c),
+ REG(ANA_AUTOAGE, 0x00b530),
+ REG(ANA_MACTOPTIONS, 0x00b534),
+ REG(ANA_LEARNDISC, 0x00b538),
+ REG(ANA_AGENCTRL, 0x00b53c),
+ REG(ANA_MIRRORPORTS, 0x00b540),
+ REG(ANA_EMIRRORPORTS, 0x00b544),
+ REG(ANA_FLOODING, 0x00b548),
+ REG(ANA_FLOODING_IPMC, 0x00b54c),
+ REG(ANA_SFLOW_CFG, 0x00b550),
+ REG(ANA_PORT_MODE, 0x00b57c),
+ REG_RESERVED(ANA_CUT_THRU_CFG),
+ REG(ANA_PGID_PGID, 0x00b600),
+ REG(ANA_TABLES_ANMOVED, 0x00b4ac),
+ REG(ANA_TABLES_MACHDATA, 0x00b4b0),
+ REG(ANA_TABLES_MACLDATA, 0x00b4b4),
+ REG_RESERVED(ANA_TABLES_STREAMDATA),
+ REG(ANA_TABLES_MACACCESS, 0x00b4b8),
+ REG(ANA_TABLES_MACTINDX, 0x00b4bc),
+ REG(ANA_TABLES_VLANACCESS, 0x00b4c0),
+ REG(ANA_TABLES_VLANTIDX, 0x00b4c4),
+ REG_RESERVED(ANA_TABLES_ISDXACCESS),
+ REG_RESERVED(ANA_TABLES_ISDXTIDX),
+ REG(ANA_TABLES_ENTRYLIM, 0x00b480),
+ REG_RESERVED(ANA_TABLES_PTP_ID_HIGH),
+ REG_RESERVED(ANA_TABLES_PTP_ID_LOW),
+ REG_RESERVED(ANA_TABLES_STREAMACCESS),
+ REG_RESERVED(ANA_TABLES_STREAMTIDX),
+ REG_RESERVED(ANA_TABLES_SEQ_HISTORY),
+ REG_RESERVED(ANA_TABLES_SEQ_MASK),
+ REG_RESERVED(ANA_TABLES_SFID_MASK),
+ REG_RESERVED(ANA_TABLES_SFIDACCESS),
+ REG_RESERVED(ANA_TABLES_SFIDTIDX),
+ REG_RESERVED(ANA_MSTI_STATE),
+ REG_RESERVED(ANA_OAM_UPM_LM_CNT),
+ REG_RESERVED(ANA_SG_ACCESS_CTRL),
+ REG_RESERVED(ANA_SG_CONFIG_REG_1),
+ REG_RESERVED(ANA_SG_CONFIG_REG_2),
+ REG_RESERVED(ANA_SG_CONFIG_REG_3),
+ REG_RESERVED(ANA_SG_CONFIG_REG_4),
+ REG_RESERVED(ANA_SG_CONFIG_REG_5),
+ REG_RESERVED(ANA_SG_GCL_GS_CONFIG),
+ REG_RESERVED(ANA_SG_GCL_TI_CONFIG),
+ REG_RESERVED(ANA_SG_STATUS_REG_1),
+ REG_RESERVED(ANA_SG_STATUS_REG_2),
+ REG_RESERVED(ANA_SG_STATUS_REG_3),
+ REG(ANA_PORT_VLAN_CFG, 0x000000),
+ REG(ANA_PORT_DROP_CFG, 0x000004),
+ REG(ANA_PORT_QOS_CFG, 0x000008),
+ REG(ANA_PORT_VCAP_CFG, 0x00000c),
+ REG(ANA_PORT_VCAP_S1_KEY_CFG, 0x000010),
+ REG(ANA_PORT_VCAP_S2_CFG, 0x00001c),
+ REG(ANA_PORT_PCP_DEI_MAP, 0x000020),
+ REG(ANA_PORT_CPU_FWD_CFG, 0x000060),
+ REG(ANA_PORT_CPU_FWD_BPDU_CFG, 0x000064),
+ REG(ANA_PORT_CPU_FWD_GARP_CFG, 0x000068),
+ REG(ANA_PORT_CPU_FWD_CCM_CFG, 0x00006c),
+ REG(ANA_PORT_PORT_CFG, 0x000070),
+ REG(ANA_PORT_POL_CFG, 0x000074),
+ REG_RESERVED(ANA_PORT_PTP_CFG),
+ REG_RESERVED(ANA_PORT_PTP_DLY1_CFG),
+ REG_RESERVED(ANA_PORT_PTP_DLY2_CFG),
+ REG_RESERVED(ANA_PORT_SFID_CFG),
+ REG(ANA_PFC_PFC_CFG, 0x00c000),
+ REG_RESERVED(ANA_PFC_PFC_TIMER),
+ REG_RESERVED(ANA_IPT_OAM_MEP_CFG),
+ REG_RESERVED(ANA_IPT_IPT),
+ REG_RESERVED(ANA_PPT_PPT),
+ REG_RESERVED(ANA_FID_MAP_FID_MAP),
+ REG(ANA_AGGR_CFG, 0x00c600),
+ REG(ANA_CPUQ_CFG, 0x00c604),
+ REG_RESERVED(ANA_CPUQ_CFG2),
+ REG(ANA_CPUQ_8021_CFG, 0x00c60c),
+ REG(ANA_DSCP_CFG, 0x00c64c),
+ REG(ANA_DSCP_REWR_CFG, 0x00c74c),
+ REG(ANA_VCAP_RNG_TYPE_CFG, 0x00c78c),
+ REG(ANA_VCAP_RNG_VAL_CFG, 0x00c7ac),
+ REG_RESERVED(ANA_VRAP_CFG),
+ REG_RESERVED(ANA_VRAP_HDR_DATA),
+ REG_RESERVED(ANA_VRAP_HDR_MASK),
+ REG(ANA_DISCARD_CFG, 0x00c7d8),
+ REG(ANA_FID_CFG, 0x00c7dc),
+ REG(ANA_POL_PIR_CFG, 0x00a000),
+ REG(ANA_POL_CIR_CFG, 0x00a004),
+ REG(ANA_POL_MODE_CFG, 0x00a008),
+ REG(ANA_POL_PIR_STATE, 0x00a00c),
+ REG(ANA_POL_CIR_STATE, 0x00a010),
+ REG_RESERVED(ANA_POL_STATE),
+ REG(ANA_POL_FLOWC, 0x00c280),
+ REG(ANA_POL_HYST, 0x00c2ec),
+ REG_RESERVED(ANA_POL_MISC_CFG),
+};
+
+static const u32 vsc9953_qs_regmap[] = {
+ REG(QS_XTR_GRP_CFG, 0x000000),
+ REG(QS_XTR_RD, 0x000008),
+ REG(QS_XTR_FRM_PRUNING, 0x000010),
+ REG(QS_XTR_FLUSH, 0x000018),
+ REG(QS_XTR_DATA_PRESENT, 0x00001c),
+ REG(QS_XTR_CFG, 0x000020),
+ REG(QS_INJ_GRP_CFG, 0x000024),
+ REG(QS_INJ_WR, 0x00002c),
+ REG(QS_INJ_CTRL, 0x000034),
+ REG(QS_INJ_STATUS, 0x00003c),
+ REG(QS_INJ_ERR, 0x000040),
+ REG_RESERVED(QS_INH_DBG),
+};
+
+static const u32 vsc9953_s2_regmap[] = {
+ REG(S2_CORE_UPDATE_CTRL, 0x000000),
+ REG(S2_CORE_MV_CFG, 0x000004),
+ REG(S2_CACHE_ENTRY_DAT, 0x000008),
+ REG(S2_CACHE_MASK_DAT, 0x000108),
+ REG(S2_CACHE_ACTION_DAT, 0x000208),
+ REG(S2_CACHE_CNT_DAT, 0x000308),
+ REG(S2_CACHE_TG_DAT, 0x000388),
+};
+
+static const u32 vsc9953_qsys_regmap[] = {
+ REG(QSYS_PORT_MODE, 0x003600),
+ REG(QSYS_SWITCH_PORT_MODE, 0x003630),
+ REG(QSYS_STAT_CNT_CFG, 0x00365c),
+ REG(QSYS_EEE_CFG, 0x003660),
+ REG(QSYS_EEE_THRES, 0x003688),
+ REG(QSYS_IGR_NO_SHARING, 0x00368c),
+ REG(QSYS_EGR_NO_SHARING, 0x003690),
+ REG(QSYS_SW_STATUS, 0x003694),
+ REG(QSYS_EXT_CPU_CFG, 0x0036c0),
+ REG_RESERVED(QSYS_PAD_CFG),
+ REG(QSYS_CPU_GROUP_MAP, 0x0036c8),
+ REG_RESERVED(QSYS_QMAP),
+ REG_RESERVED(QSYS_ISDX_SGRP),
+ REG_RESERVED(QSYS_TIMED_FRAME_ENTRY),
+ REG_RESERVED(QSYS_TFRM_MISC),
+ REG_RESERVED(QSYS_TFRM_PORT_DLY),
+ REG_RESERVED(QSYS_TFRM_TIMER_CFG_1),
+ REG_RESERVED(QSYS_TFRM_TIMER_CFG_2),
+ REG_RESERVED(QSYS_TFRM_TIMER_CFG_3),
+ REG_RESERVED(QSYS_TFRM_TIMER_CFG_4),
+ REG_RESERVED(QSYS_TFRM_TIMER_CFG_5),
+ REG_RESERVED(QSYS_TFRM_TIMER_CFG_6),
+ REG_RESERVED(QSYS_TFRM_TIMER_CFG_7),
+ REG_RESERVED(QSYS_TFRM_TIMER_CFG_8),
+ REG(QSYS_RED_PROFILE, 0x003724),
+ REG(QSYS_RES_QOS_MODE, 0x003764),
+ REG(QSYS_RES_CFG, 0x004000),
+ REG(QSYS_RES_STAT, 0x004004),
+ REG(QSYS_EGR_DROP_MODE, 0x003768),
+ REG(QSYS_EQ_CTRL, 0x00376c),
+ REG_RESERVED(QSYS_EVENTS_CORE),
+ REG_RESERVED(QSYS_QMAXSDU_CFG_0),
+ REG_RESERVED(QSYS_QMAXSDU_CFG_1),
+ REG_RESERVED(QSYS_QMAXSDU_CFG_2),
+ REG_RESERVED(QSYS_QMAXSDU_CFG_3),
+ REG_RESERVED(QSYS_QMAXSDU_CFG_4),
+ REG_RESERVED(QSYS_QMAXSDU_CFG_5),
+ REG_RESERVED(QSYS_QMAXSDU_CFG_6),
+ REG_RESERVED(QSYS_QMAXSDU_CFG_7),
+ REG_RESERVED(QSYS_PREEMPTION_CFG),
+ REG(QSYS_CIR_CFG, 0x000000),
+ REG_RESERVED(QSYS_EIR_CFG),
+ REG(QSYS_SE_CFG, 0x000008),
+ REG(QSYS_SE_DWRR_CFG, 0x00000c),
+ REG_RESERVED(QSYS_SE_CONNECT),
+ REG_RESERVED(QSYS_SE_DLB_SENSE),
+ REG(QSYS_CIR_STATE, 0x000044),
+ REG_RESERVED(QSYS_EIR_STATE),
+ REG_RESERVED(QSYS_SE_STATE),
+ REG(QSYS_HSCH_MISC_CFG, 0x003774),
+ REG_RESERVED(QSYS_TAG_CONFIG),
+ REG_RESERVED(QSYS_TAS_PARAM_CFG_CTRL),
+ REG_RESERVED(QSYS_PORT_MAX_SDU),
+ REG_RESERVED(QSYS_PARAM_CFG_REG_1),
+ REG_RESERVED(QSYS_PARAM_CFG_REG_2),
+ REG_RESERVED(QSYS_PARAM_CFG_REG_3),
+ REG_RESERVED(QSYS_PARAM_CFG_REG_4),
+ REG_RESERVED(QSYS_PARAM_CFG_REG_5),
+ REG_RESERVED(QSYS_GCL_CFG_REG_1),
+ REG_RESERVED(QSYS_GCL_CFG_REG_2),
+ REG_RESERVED(QSYS_PARAM_STATUS_REG_1),
+ REG_RESERVED(QSYS_PARAM_STATUS_REG_2),
+ REG_RESERVED(QSYS_PARAM_STATUS_REG_3),
+ REG_RESERVED(QSYS_PARAM_STATUS_REG_4),
+ REG_RESERVED(QSYS_PARAM_STATUS_REG_5),
+ REG_RESERVED(QSYS_PARAM_STATUS_REG_6),
+ REG_RESERVED(QSYS_PARAM_STATUS_REG_7),
+ REG_RESERVED(QSYS_PARAM_STATUS_REG_8),
+ REG_RESERVED(QSYS_PARAM_STATUS_REG_9),
+ REG_RESERVED(QSYS_GCL_STATUS_REG_1),
+ REG_RESERVED(QSYS_GCL_STATUS_REG_2),
+};
+
+static const u32 vsc9953_rew_regmap[] = {
+ REG(REW_PORT_VLAN_CFG, 0x000000),
+ REG(REW_TAG_CFG, 0x000004),
+ REG(REW_PORT_CFG, 0x000008),
+ REG(REW_DSCP_CFG, 0x00000c),
+ REG(REW_PCP_DEI_QOS_MAP_CFG, 0x000010),
+ REG_RESERVED(REW_PTP_CFG),
+ REG_RESERVED(REW_PTP_DLY1_CFG),
+ REG_RESERVED(REW_RED_TAG_CFG),
+ REG(REW_DSCP_REMAP_DP1_CFG, 0x000610),
+ REG(REW_DSCP_REMAP_CFG, 0x000710),
+ REG_RESERVED(REW_STAT_CFG),
+ REG_RESERVED(REW_REW_STICKY),
+ REG_RESERVED(REW_PPT),
+};
+
+static const u32 vsc9953_sys_regmap[] = {
+ REG(SYS_COUNT_RX_OCTETS, 0x000000),
+ REG(SYS_COUNT_RX_MULTICAST, 0x000008),
+ REG(SYS_COUNT_RX_SHORTS, 0x000010),
+ REG(SYS_COUNT_RX_FRAGMENTS, 0x000014),
+ REG(SYS_COUNT_RX_JABBERS, 0x000018),
+ REG(SYS_COUNT_RX_64, 0x000024),
+ REG(SYS_COUNT_RX_65_127, 0x000028),
+ REG(SYS_COUNT_RX_128_255, 0x00002c),
+ REG(SYS_COUNT_RX_256_1023, 0x000030),
+ REG(SYS_COUNT_RX_1024_1526, 0x000034),
+ REG(SYS_COUNT_RX_1527_MAX, 0x000038),
+ REG(SYS_COUNT_RX_LONGS, 0x000048),
+ REG(SYS_COUNT_TX_OCTETS, 0x000100),
+ REG(SYS_COUNT_TX_COLLISION, 0x000110),
+ REG(SYS_COUNT_TX_DROPS, 0x000114),
+ REG(SYS_COUNT_TX_64, 0x00011c),
+ REG(SYS_COUNT_TX_65_127, 0x000120),
+ REG(SYS_COUNT_TX_128_511, 0x000124),
+ REG(SYS_COUNT_TX_512_1023, 0x000128),
+ REG(SYS_COUNT_TX_1024_1526, 0x00012c),
+ REG(SYS_COUNT_TX_1527_MAX, 0x000130),
+ REG(SYS_COUNT_TX_AGING, 0x000178),
+ REG(SYS_RESET_CFG, 0x000318),
+ REG_RESERVED(SYS_SR_ETYPE_CFG),
+ REG(SYS_VLAN_ETYPE_CFG, 0x000320),
+ REG(SYS_PORT_MODE, 0x000324),
+ REG(SYS_FRONT_PORT_MODE, 0x000354),
+ REG(SYS_FRM_AGING, 0x00037c),
+ REG(SYS_STAT_CFG, 0x000380),
+ REG_RESERVED(SYS_SW_STATUS),
+ REG_RESERVED(SYS_MISC_CFG),
+ REG_RESERVED(SYS_REW_MAC_HIGH_CFG),
+ REG_RESERVED(SYS_REW_MAC_LOW_CFG),
+ REG_RESERVED(SYS_TIMESTAMP_OFFSET),
+ REG(SYS_PAUSE_CFG, 0x00044c),
+ REG(SYS_PAUSE_TOT_CFG, 0x000478),
+ REG(SYS_ATOP, 0x00047c),
+ REG(SYS_ATOP_TOT_CFG, 0x0004a8),
+ REG(SYS_MAC_FC_CFG, 0x0004ac),
+ REG(SYS_MMGT, 0x0004d4),
+ REG_RESERVED(SYS_MMGT_FAST),
+ REG_RESERVED(SYS_EVENTS_DIF),
+ REG_RESERVED(SYS_EVENTS_CORE),
+ REG_RESERVED(SYS_CNT),
+ REG_RESERVED(SYS_PTP_STATUS),
+ REG_RESERVED(SYS_PTP_TXSTAMP),
+ REG_RESERVED(SYS_PTP_NXT),
+ REG_RESERVED(SYS_PTP_CFG),
+ REG_RESERVED(SYS_RAM_INIT),
+ REG_RESERVED(SYS_CM_ADDR),
+ REG_RESERVED(SYS_CM_DATA_WR),
+ REG_RESERVED(SYS_CM_DATA_RD),
+ REG_RESERVED(SYS_CM_OP),
+ REG_RESERVED(SYS_CM_DATA),
+};
+
+static const u32 vsc9953_gcb_regmap[] = {
+ REG(GCB_SOFT_RST, 0x000008),
+ REG(GCB_MIIM_MII_STATUS, 0x0000ac),
+ REG(GCB_MIIM_MII_CMD, 0x0000b4),
+ REG(GCB_MIIM_MII_DATA, 0x0000b8),
+};
+
+static const u32 vsc9953_dev_gmii_regmap[] = {
+ REG(DEV_CLOCK_CFG, 0x0),
+ REG(DEV_PORT_MISC, 0x4),
+ REG_RESERVED(DEV_EVENTS),
+ REG(DEV_EEE_CFG, 0xc),
+ REG_RESERVED(DEV_RX_PATH_DELAY),
+ REG_RESERVED(DEV_TX_PATH_DELAY),
+ REG_RESERVED(DEV_PTP_PREDICT_CFG),
+ REG(DEV_MAC_ENA_CFG, 0x10),
+ REG(DEV_MAC_MODE_CFG, 0x14),
+ REG(DEV_MAC_MAXLEN_CFG, 0x18),
+ REG(DEV_MAC_TAGS_CFG, 0x1c),
+ REG(DEV_MAC_ADV_CHK_CFG, 0x20),
+ REG(DEV_MAC_IFG_CFG, 0x24),
+ REG(DEV_MAC_HDX_CFG, 0x28),
+ REG_RESERVED(DEV_MAC_DBG_CFG),
+ REG(DEV_MAC_FC_MAC_LOW_CFG, 0x30),
+ REG(DEV_MAC_FC_MAC_HIGH_CFG, 0x34),
+ REG(DEV_MAC_STICKY, 0x38),
+ REG_RESERVED(PCS1G_CFG),
+ REG_RESERVED(PCS1G_MODE_CFG),
+ REG_RESERVED(PCS1G_SD_CFG),
+ REG_RESERVED(PCS1G_ANEG_CFG),
+ REG_RESERVED(PCS1G_ANEG_NP_CFG),
+ REG_RESERVED(PCS1G_LB_CFG),
+ REG_RESERVED(PCS1G_DBG_CFG),
+ REG_RESERVED(PCS1G_CDET_CFG),
+ REG_RESERVED(PCS1G_ANEG_STATUS),
+ REG_RESERVED(PCS1G_ANEG_NP_STATUS),
+ REG_RESERVED(PCS1G_LINK_STATUS),
+ REG_RESERVED(PCS1G_LINK_DOWN_CNT),
+ REG_RESERVED(PCS1G_STICKY),
+ REG_RESERVED(PCS1G_DEBUG_STATUS),
+ REG_RESERVED(PCS1G_LPI_CFG),
+ REG_RESERVED(PCS1G_LPI_WAKE_ERROR_CNT),
+ REG_RESERVED(PCS1G_LPI_STATUS),
+ REG_RESERVED(PCS1G_TSTPAT_MODE_CFG),
+ REG_RESERVED(PCS1G_TSTPAT_STATUS),
+ REG_RESERVED(DEV_PCS_FX100_CFG),
+ REG_RESERVED(DEV_PCS_FX100_STATUS),
+};
+
+static const u32 *vsc9953_regmap[TARGET_MAX] = {
+ [ANA] = vsc9953_ana_regmap,
+ [QS] = vsc9953_qs_regmap,
+ [QSYS] = vsc9953_qsys_regmap,
+ [REW] = vsc9953_rew_regmap,
+ [SYS] = vsc9953_sys_regmap,
+ [S2] = vsc9953_s2_regmap,
+ [GCB] = vsc9953_gcb_regmap,
+ [DEV_GMII] = vsc9953_dev_gmii_regmap,
+};
+
+/* Addresses are relative to the device's base address */
+static const struct resource vsc9953_target_io_res[TARGET_MAX] = {
+ [ANA] = {
+ .start = 0x0280000,
+ .end = 0x028ffff,
+ .name = "ana",
+ },
+ [QS] = {
+ .start = 0x0080000,
+ .end = 0x00800ff,
+ .name = "qs",
+ },
+ [QSYS] = {
+ .start = 0x0200000,
+ .end = 0x021ffff,
+ .name = "qsys",
+ },
+ [REW] = {
+ .start = 0x0030000,
+ .end = 0x003ffff,
+ .name = "rew",
+ },
+ [SYS] = {
+ .start = 0x0010000,
+ .end = 0x001ffff,
+ .name = "sys",
+ },
+ [S2] = {
+ .start = 0x0060000,
+ .end = 0x00603ff,
+ .name = "s2",
+ },
+ [PTP] = {
+ .start = 0x0090000,
+ .end = 0x00900cb,
+ .name = "ptp",
+ },
+ [GCB] = {
+ .start = 0x0070000,
+ .end = 0x00701ff,
+ .name = "devcpu_gcb",
+ },
+};
+
+static const struct resource vsc9953_port_io_res[] = {
+ {
+ .start = 0x0100000,
+ .end = 0x010ffff,
+ .name = "port0",
+ },
+ {
+ .start = 0x0110000,
+ .end = 0x011ffff,
+ .name = "port1",
+ },
+ {
+ .start = 0x0120000,
+ .end = 0x012ffff,
+ .name = "port2",
+ },
+ {
+ .start = 0x0130000,
+ .end = 0x013ffff,
+ .name = "port3",
+ },
+ {
+ .start = 0x0140000,
+ .end = 0x014ffff,
+ .name = "port4",
+ },
+ {
+ .start = 0x0150000,
+ .end = 0x015ffff,
+ .name = "port5",
+ },
+ {
+ .start = 0x0160000,
+ .end = 0x016ffff,
+ .name = "port6",
+ },
+ {
+ .start = 0x0170000,
+ .end = 0x017ffff,
+ .name = "port7",
+ },
+ {
+ .start = 0x0180000,
+ .end = 0x018ffff,
+ .name = "port8",
+ },
+ {
+ .start = 0x0190000,
+ .end = 0x019ffff,
+ .name = "port9",
+ },
+};
+
+static const struct reg_field vsc9953_regfields[REGFIELD_MAX] = {
+ [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 10, 10),
+ [ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 9),
+ [ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24),
+ [ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22),
+ [ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21),
+ [ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20),
+ [ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19),
+ [ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
+ [ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17),
+ [ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16),
+ [ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15),
+ [ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13),
+ [ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12),
+ [ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
+ [ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
+ [ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9),
+ [ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8),
+ [ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7),
+ [ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
+ [ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
+ [ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4),
+ [ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3),
+ [ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2),
+ [ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1),
+ [ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0),
+ [ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 16, 16),
+ [ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 11, 12),
+ [ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 10),
+ [SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 7, 7),
+ [SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 6, 6),
+ [SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 5, 5),
+ [GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 0, 0),
+ [GCB_MIIM_MII_STATUS_PENDING] = REG_FIELD(GCB_MIIM_MII_STATUS, 2, 2),
+ [GCB_MIIM_MII_STATUS_BUSY] = REG_FIELD(GCB_MIIM_MII_STATUS, 3, 3),
+ /* Replicated per number of ports (11), register size 4 per port */
+ [QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 13, 13, 11, 4),
+ [QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 11, 4),
+ [QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 11, 4),
+ [QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 11, 4),
+ [QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 11, 4),
+ [SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 4, 5, 11, 4),
+ [SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 2, 3, 11, 4),
+ [SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 11, 4),
+ [SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 11, 20, 11, 4),
+ [SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 10, 11, 4),
+ [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 11, 4),
+};
+
+static const struct ocelot_stat_layout vsc9953_stats_layout[] = {
+ { .offset = 0x00, .name = "rx_octets", },
+ { .offset = 0x01, .name = "rx_unicast", },
+ { .offset = 0x02, .name = "rx_multicast", },
+ { .offset = 0x03, .name = "rx_broadcast", },
+ { .offset = 0x04, .name = "rx_shorts", },
+ { .offset = 0x05, .name = "rx_fragments", },
+ { .offset = 0x06, .name = "rx_jabbers", },
+ { .offset = 0x07, .name = "rx_crc_align_errs", },
+ { .offset = 0x08, .name = "rx_sym_errs", },
+ { .offset = 0x09, .name = "rx_frames_below_65_octets", },
+ { .offset = 0x0A, .name = "rx_frames_65_to_127_octets", },
+ { .offset = 0x0B, .name = "rx_frames_128_to_255_octets", },
+ { .offset = 0x0C, .name = "rx_frames_256_to_511_octets", },
+ { .offset = 0x0D, .name = "rx_frames_512_to_1023_octets", },
+ { .offset = 0x0E, .name = "rx_frames_1024_to_1526_octets", },
+ { .offset = 0x0F, .name = "rx_frames_over_1526_octets", },
+ { .offset = 0x10, .name = "rx_pause", },
+ { .offset = 0x11, .name = "rx_control", },
+ { .offset = 0x12, .name = "rx_longs", },
+ { .offset = 0x13, .name = "rx_classified_drops", },
+ { .offset = 0x14, .name = "rx_red_prio_0", },
+ { .offset = 0x15, .name = "rx_red_prio_1", },
+ { .offset = 0x16, .name = "rx_red_prio_2", },
+ { .offset = 0x17, .name = "rx_red_prio_3", },
+ { .offset = 0x18, .name = "rx_red_prio_4", },
+ { .offset = 0x19, .name = "rx_red_prio_5", },
+ { .offset = 0x1A, .name = "rx_red_prio_6", },
+ { .offset = 0x1B, .name = "rx_red_prio_7", },
+ { .offset = 0x1C, .name = "rx_yellow_prio_0", },
+ { .offset = 0x1D, .name = "rx_yellow_prio_1", },
+ { .offset = 0x1E, .name = "rx_yellow_prio_2", },
+ { .offset = 0x1F, .name = "rx_yellow_prio_3", },
+ { .offset = 0x20, .name = "rx_yellow_prio_4", },
+ { .offset = 0x21, .name = "rx_yellow_prio_5", },
+ { .offset = 0x22, .name = "rx_yellow_prio_6", },
+ { .offset = 0x23, .name = "rx_yellow_prio_7", },
+ { .offset = 0x24, .name = "rx_green_prio_0", },
+ { .offset = 0x25, .name = "rx_green_prio_1", },
+ { .offset = 0x26, .name = "rx_green_prio_2", },
+ { .offset = 0x27, .name = "rx_green_prio_3", },
+ { .offset = 0x28, .name = "rx_green_prio_4", },
+ { .offset = 0x29, .name = "rx_green_prio_5", },
+ { .offset = 0x2A, .name = "rx_green_prio_6", },
+ { .offset = 0x2B, .name = "rx_green_prio_7", },
+ { .offset = 0x40, .name = "tx_octets", },
+ { .offset = 0x41, .name = "tx_unicast", },
+ { .offset = 0x42, .name = "tx_multicast", },
+ { .offset = 0x43, .name = "tx_broadcast", },
+ { .offset = 0x44, .name = "tx_collision", },
+ { .offset = 0x45, .name = "tx_drops", },
+ { .offset = 0x46, .name = "tx_pause", },
+ { .offset = 0x47, .name = "tx_frames_below_65_octets", },
+ { .offset = 0x48, .name = "tx_frames_65_to_127_octets", },
+ { .offset = 0x49, .name = "tx_frames_128_255_octets", },
+ { .offset = 0x4A, .name = "tx_frames_256_511_octets", },
+ { .offset = 0x4B, .name = "tx_frames_512_1023_octets", },
+ { .offset = 0x4C, .name = "tx_frames_1024_1526_octets", },
+ { .offset = 0x4D, .name = "tx_frames_over_1526_octets", },
+ { .offset = 0x4E, .name = "tx_yellow_prio_0", },
+ { .offset = 0x4F, .name = "tx_yellow_prio_1", },
+ { .offset = 0x50, .name = "tx_yellow_prio_2", },
+ { .offset = 0x51, .name = "tx_yellow_prio_3", },
+ { .offset = 0x52, .name = "tx_yellow_prio_4", },
+ { .offset = 0x53, .name = "tx_yellow_prio_5", },
+ { .offset = 0x54, .name = "tx_yellow_prio_6", },
+ { .offset = 0x55, .name = "tx_yellow_prio_7", },
+ { .offset = 0x56, .name = "tx_green_prio_0", },
+ { .offset = 0x57, .name = "tx_green_prio_1", },
+ { .offset = 0x58, .name = "tx_green_prio_2", },
+ { .offset = 0x59, .name = "tx_green_prio_3", },
+ { .offset = 0x5A, .name = "tx_green_prio_4", },
+ { .offset = 0x5B, .name = "tx_green_prio_5", },
+ { .offset = 0x5C, .name = "tx_green_prio_6", },
+ { .offset = 0x5D, .name = "tx_green_prio_7", },
+ { .offset = 0x5E, .name = "tx_aged", },
+ { .offset = 0x80, .name = "drop_local", },
+ { .offset = 0x81, .name = "drop_tail", },
+ { .offset = 0x82, .name = "drop_yellow_prio_0", },
+ { .offset = 0x83, .name = "drop_yellow_prio_1", },
+ { .offset = 0x84, .name = "drop_yellow_prio_2", },
+ { .offset = 0x85, .name = "drop_yellow_prio_3", },
+ { .offset = 0x86, .name = "drop_yellow_prio_4", },
+ { .offset = 0x87, .name = "drop_yellow_prio_5", },
+ { .offset = 0x88, .name = "drop_yellow_prio_6", },
+ { .offset = 0x89, .name = "drop_yellow_prio_7", },
+ { .offset = 0x8A, .name = "drop_green_prio_0", },
+ { .offset = 0x8B, .name = "drop_green_prio_1", },
+ { .offset = 0x8C, .name = "drop_green_prio_2", },
+ { .offset = 0x8D, .name = "drop_green_prio_3", },
+ { .offset = 0x8E, .name = "drop_green_prio_4", },
+ { .offset = 0x8F, .name = "drop_green_prio_5", },
+ { .offset = 0x90, .name = "drop_green_prio_6", },
+ { .offset = 0x91, .name = "drop_green_prio_7", },
+};
+
+static struct vcap_field vsc9953_vcap_is2_keys[] = {
+ /* Common: 41 bits */
+ [VCAP_IS2_TYPE] = { 0, 4},
+ [VCAP_IS2_HK_FIRST] = { 4, 1},
+ [VCAP_IS2_HK_PAG] = { 5, 8},
+ [VCAP_IS2_HK_IGR_PORT_MASK] = { 13, 11},
+ [VCAP_IS2_HK_RSV2] = { 24, 1},
+ [VCAP_IS2_HK_HOST_MATCH] = { 25, 1},
+ [VCAP_IS2_HK_L2_MC] = { 26, 1},
+ [VCAP_IS2_HK_L2_BC] = { 27, 1},
+ [VCAP_IS2_HK_VLAN_TAGGED] = { 28, 1},
+ [VCAP_IS2_HK_VID] = { 29, 12},
+ [VCAP_IS2_HK_DEI] = { 41, 1},
+ [VCAP_IS2_HK_PCP] = { 42, 3},
+ /* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
+ [VCAP_IS2_HK_L2_DMAC] = { 45, 48},
+ [VCAP_IS2_HK_L2_SMAC] = { 93, 48},
+ /* MAC_ETYPE (TYPE=000) */
+ [VCAP_IS2_HK_MAC_ETYPE_ETYPE] = {141, 16},
+ [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0] = {157, 16},
+ [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1] = {173, 8},
+ [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2] = {181, 3},
+ /* MAC_LLC (TYPE=001) */
+ [VCAP_IS2_HK_MAC_LLC_L2_LLC] = {141, 40},
+ /* MAC_SNAP (TYPE=010) */
+ [VCAP_IS2_HK_MAC_SNAP_L2_SNAP] = {141, 40},
+ /* MAC_ARP (TYPE=011) */
+ [VCAP_IS2_HK_MAC_ARP_SMAC] = { 45, 48},
+ [VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK] = { 93, 1},
+ [VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK] = { 94, 1},
+ [VCAP_IS2_HK_MAC_ARP_LEN_OK] = { 95, 1},
+ [VCAP_IS2_HK_MAC_ARP_TARGET_MATCH] = { 96, 1},
+ [VCAP_IS2_HK_MAC_ARP_SENDER_MATCH] = { 97, 1},
+ [VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN] = { 98, 1},
+ [VCAP_IS2_HK_MAC_ARP_OPCODE] = { 99, 2},
+ [VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP] = {101, 32},
+ [VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP] = {133, 32},
+ [VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP] = {165, 1},
+ /* IP4_TCP_UDP / IP4_OTHER common */
+ [VCAP_IS2_HK_IP4] = { 45, 1},
+ [VCAP_IS2_HK_L3_FRAGMENT] = { 46, 1},
+ [VCAP_IS2_HK_L3_FRAG_OFS_GT0] = { 47, 1},
+ [VCAP_IS2_HK_L3_OPTIONS] = { 48, 1},
+ [VCAP_IS2_HK_IP4_L3_TTL_GT0] = { 49, 1},
+ [VCAP_IS2_HK_L3_TOS] = { 50, 8},
+ [VCAP_IS2_HK_L3_IP4_DIP] = { 58, 32},
+ [VCAP_IS2_HK_L3_IP4_SIP] = { 90, 32},
+ [VCAP_IS2_HK_DIP_EQ_SIP] = {122, 1},
+ /* IP4_TCP_UDP (TYPE=100) */
+ [VCAP_IS2_HK_TCP] = {123, 1},
+ [VCAP_IS2_HK_L4_SPORT] = {124, 16},
+ [VCAP_IS2_HK_L4_DPORT] = {140, 16},
+ [VCAP_IS2_HK_L4_RNG] = {156, 8},
+ [VCAP_IS2_HK_L4_SPORT_EQ_DPORT] = {164, 1},
+ [VCAP_IS2_HK_L4_SEQUENCE_EQ0] = {165, 1},
+ [VCAP_IS2_HK_L4_URG] = {166, 1},
+ [VCAP_IS2_HK_L4_ACK] = {167, 1},
+ [VCAP_IS2_HK_L4_PSH] = {168, 1},
+ [VCAP_IS2_HK_L4_RST] = {169, 1},
+ [VCAP_IS2_HK_L4_SYN] = {170, 1},
+ [VCAP_IS2_HK_L4_FIN] = {171, 1},
+ /* IP4_OTHER (TYPE=101) */
+ [VCAP_IS2_HK_IP4_L3_PROTO] = {123, 8},
+ [VCAP_IS2_HK_L3_PAYLOAD] = {131, 56},
+ /* IP6_STD (TYPE=110) */
+ [VCAP_IS2_HK_IP6_L3_TTL_GT0] = { 45, 1},
+ [VCAP_IS2_HK_L3_IP6_SIP] = { 46, 128},
+ [VCAP_IS2_HK_IP6_L3_PROTO] = {174, 8},
+};
+
+static struct vcap_field vsc9953_vcap_is2_actions[] = {
+ [VCAP_IS2_ACT_HIT_ME_ONCE] = { 0, 1},
+ [VCAP_IS2_ACT_CPU_COPY_ENA] = { 1, 1},
+ [VCAP_IS2_ACT_CPU_QU_NUM] = { 2, 3},
+ [VCAP_IS2_ACT_MASK_MODE] = { 5, 2},
+ [VCAP_IS2_ACT_MIRROR_ENA] = { 7, 1},
+ [VCAP_IS2_ACT_LRN_DIS] = { 8, 1},
+ [VCAP_IS2_ACT_POLICE_ENA] = { 9, 1},
+ [VCAP_IS2_ACT_POLICE_IDX] = { 10, 8},
+ [VCAP_IS2_ACT_POLICE_VCAP_ONLY] = { 21, 1},
+ [VCAP_IS2_ACT_PORT_MASK] = { 22, 10},
+ [VCAP_IS2_ACT_ACL_ID] = { 44, 6},
+ [VCAP_IS2_ACT_HIT_CNT] = { 50, 32},
+};
+
+static const struct vcap_props vsc9953_vcap_props[] = {
+ [VCAP_IS2] = {
+ .tg_width = 2,
+ .sw_count = 4,
+ .entry_count = VSC9953_VCAP_IS2_CNT,
+ .entry_width = VSC9953_VCAP_IS2_ENTRY_WIDTH,
+ .action_count = VSC9953_VCAP_IS2_CNT +
+ VSC9953_VCAP_PORT_CNT + 2,
+ .action_width = 101,
+ .action_type_width = 1,
+ .action_table = {
+ [IS2_ACTION_TYPE_NORMAL] = {
+ .width = 44,
+ .count = 2
+ },
+ [IS2_ACTION_TYPE_SMAC_SIP] = {
+ .width = 6,
+ .count = 4
+ },
+ },
+ .counter_words = 4,
+ .counter_width = 32,
+ },
+};
+
+#define VSC9953_INIT_TIMEOUT 50000
+#define VSC9953_GCB_RST_SLEEP 100
+#define VSC9953_SYS_RAMINIT_SLEEP 80
+#define VCS9953_MII_TIMEOUT 10000
+
+static int vsc9953_gcb_soft_rst_status(struct ocelot *ocelot)
+{
+ int val;
+
+ ocelot_field_read(ocelot, GCB_SOFT_RST_SWC_RST, &val);
+
+ return val;
+}
+
+static int vsc9953_sys_ram_init_status(struct ocelot *ocelot)
+{
+ int val;
+
+ ocelot_field_read(ocelot, SYS_RESET_CFG_MEM_INIT, &val);
+
+ return val;
+}
+
+static int vsc9953_gcb_miim_pending_status(struct ocelot *ocelot)
+{
+ int val;
+
+ ocelot_field_read(ocelot, GCB_MIIM_MII_STATUS_PENDING, &val);
+
+ return val;
+}
+
+static int vsc9953_gcb_miim_busy_status(struct ocelot *ocelot)
+{
+ int val;
+
+ ocelot_field_read(ocelot, GCB_MIIM_MII_STATUS_BUSY, &val);
+
+ return val;
+}
+
+static int vsc9953_mdio_write(struct mii_bus *bus, int phy_id, int regnum,
+ u16 value)
+{
+ struct ocelot *ocelot = bus->priv;
+ int err, cmd, val;
+
+ /* Wait while MIIM controller becomes idle */
+ err = readx_poll_timeout(vsc9953_gcb_miim_pending_status, ocelot,
+ val, !val, 10, VCS9953_MII_TIMEOUT);
+ if (err) {
+ dev_err(ocelot->dev, "MDIO write: pending timeout\n");
+ goto out;
+ }
+
+ cmd = MSCC_MIIM_CMD_VLD | (phy_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
+ (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) |
+ (value << MSCC_MIIM_CMD_WRDATA_SHIFT) |
+ MSCC_MIIM_CMD_OPR_WRITE;
+
+ ocelot_write(ocelot, cmd, GCB_MIIM_MII_CMD);
+
+out:
+ return err;
+}
+
+static int vsc9953_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
+{
+ struct ocelot *ocelot = bus->priv;
+ int err, cmd, val;
+
+ /* Wait until MIIM controller becomes idle */
+ err = readx_poll_timeout(vsc9953_gcb_miim_pending_status, ocelot,
+ val, !val, 10, VCS9953_MII_TIMEOUT);
+ if (err) {
+ dev_err(ocelot->dev, "MDIO read: pending timeout\n");
+ goto out;
+ }
+
+ /* Write the MIIM COMMAND register */
+ cmd = MSCC_MIIM_CMD_VLD | (phy_id << MSCC_MIIM_CMD_PHYAD_SHIFT) |
+ (regnum << MSCC_MIIM_CMD_REGAD_SHIFT) | MSCC_MIIM_CMD_OPR_READ;
+
+ ocelot_write(ocelot, cmd, GCB_MIIM_MII_CMD);
+
+ /* Wait while read operation via the MIIM controller is in progress */
+ err = readx_poll_timeout(vsc9953_gcb_miim_busy_status, ocelot,
+ val, !val, 10, VCS9953_MII_TIMEOUT);
+ if (err) {
+ dev_err(ocelot->dev, "MDIO read: busy timeout\n");
+ goto out;
+ }
+
+ val = ocelot_read(ocelot, GCB_MIIM_MII_DATA);
+
+ err = val & 0xFFFF;
+out:
+ return err;
+}
+
+static int vsc9953_reset(struct ocelot *ocelot)
+{
+ int val, err;
+
+ /* soft-reset the switch core */
+ ocelot_field_write(ocelot, GCB_SOFT_RST_SWC_RST, 1);
+
+ err = readx_poll_timeout(vsc9953_gcb_soft_rst_status, ocelot, val, !val,
+ VSC9953_GCB_RST_SLEEP, VSC9953_INIT_TIMEOUT);
+ if (err) {
+ dev_err(ocelot->dev, "timeout: switch core reset\n");
+ return err;
+ }
+
+ /* initialize switch mem ~40us */
+ ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_INIT, 1);
+ ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_ENA, 1);
+
+ err = readx_poll_timeout(vsc9953_sys_ram_init_status, ocelot, val, !val,
+ VSC9953_SYS_RAMINIT_SLEEP,
+ VSC9953_INIT_TIMEOUT);
+ if (err) {
+ dev_err(ocelot->dev, "timeout: switch sram init\n");
+ return err;
+ }
+
+ /* enable switch core */
+ ocelot_field_write(ocelot, SYS_RESET_CFG_MEM_ENA, 1);
+ ocelot_field_write(ocelot, SYS_RESET_CFG_CORE_ENA, 1);
+
+ return 0;
+}
+
+static void vsc9953_phylink_validate(struct ocelot *ocelot, int port,
+ unsigned long *supported,
+ struct phylink_link_state *state)
+{
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
+ if (state->interface != PHY_INTERFACE_MODE_NA &&
+ state->interface != ocelot_port->phy_mode) {
+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
+ return;
+ }
+
+ phylink_set_port_modes(mask);
+ phylink_set(mask, Autoneg);
+ phylink_set(mask, Pause);
+ phylink_set(mask, Asym_Pause);
+ phylink_set(mask, 10baseT_Full);
+ phylink_set(mask, 10baseT_Half);
+ phylink_set(mask, 100baseT_Full);
+ phylink_set(mask, 100baseT_Half);
+ phylink_set(mask, 1000baseT_Full);
+
+ if (state->interface == PHY_INTERFACE_MODE_INTERNAL) {
+ phylink_set(mask, 2500baseT_Full);
+ phylink_set(mask, 2500baseX_Full);
+ }
+
+ bitmap_and(supported, supported, mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ bitmap_and(state->advertising, state->advertising, mask,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+static int vsc9953_prevalidate_phy_mode(struct ocelot *ocelot, int port,
+ phy_interface_t phy_mode)
+{
+ switch (phy_mode) {
+ case PHY_INTERFACE_MODE_INTERNAL:
+ if (port != 8 && port != 9)
+ return -ENOTSUPP;
+ return 0;
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_QSGMII:
+ /* Not supported on internal to-CPU ports */
+ if (port == 8 || port == 9)
+ return -ENOTSUPP;
+ return 0;
+ default:
+ return -ENOTSUPP;
+ }
+}
+
+/* Watermark encode
+ * Bit 9: Unit; 0:1, 1:16
+ * Bit 8-0: Value to be multiplied with unit
+ */
+static u16 vsc9953_wm_enc(u16 value)
+{
+ if (value >= BIT(9))
+ return BIT(9) | (value / 16);
+
+ return value;
+}
+
+static const struct ocelot_ops vsc9953_ops = {
+ .reset = vsc9953_reset,
+ .wm_enc = vsc9953_wm_enc,
+};
+
+static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)
+{
+ struct felix *felix = ocelot_to_felix(ocelot);
+ struct device *dev = ocelot->dev;
+ struct mii_bus *bus;
+ int port;
+ int rc;
+
+ felix->pcs = devm_kcalloc(dev, felix->info->num_ports,
+ sizeof(struct phy_device *),
+ GFP_KERNEL);
+ if (!felix->pcs) {
+ dev_err(dev, "failed to allocate array for PCS PHYs\n");
+ return -ENOMEM;
+ }
+
+ bus = devm_mdiobus_alloc(dev);
+ if (!bus)
+ return -ENOMEM;
+
+ bus->name = "VSC9953 internal MDIO bus";
+ bus->read = vsc9953_mdio_read;
+ bus->write = vsc9953_mdio_write;
+ bus->parent = dev;
+ bus->priv = ocelot;
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev));
+
+ /* Needed in order to initialize the bus mutex lock */
+ rc = mdiobus_register(bus);
+ if (rc < 0) {
+ dev_err(dev, "failed to register MDIO bus\n");
+ return rc;
+ }
+
+ felix->imdio = bus;
+
+ for (port = 0; port < felix->info->num_ports; port++) {
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ struct phy_device *pcs;
+ int addr = port + 4;
+
+ if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_INTERNAL)
+ continue;
+
+ pcs = get_phy_device(felix->imdio, addr, false);
+ if (IS_ERR(pcs))
+ continue;
+
+ pcs->interface = ocelot_port->phy_mode;
+ felix->pcs[port] = pcs;
+
+ dev_info(dev, "Found PCS at internal MDIO address %d\n", addr);
+ }
+
+ return 0;
+}
+
+static void vsc9953_xmit_template_populate(struct ocelot *ocelot, int port)
+{
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ u8 *template = ocelot_port->xmit_template;
+ u64 bypass, dest, src;
+
+ /* Set the source port as the CPU port module and not the
+ * NPI port
+ */
+ src = ocelot->num_phys_ports;
+ dest = BIT(port);
+ bypass = true;
+
+ packing(template, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
+ packing(template, &dest, 67, 57, OCELOT_TAG_LEN, PACK, 0);
+ packing(template, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0);
+}
+
+static const struct felix_info seville_info_vsc9953 = {
+ .target_io_res = vsc9953_target_io_res,
+ .port_io_res = vsc9953_port_io_res,
+ .regfields = vsc9953_regfields,
+ .map = vsc9953_regmap,
+ .ops = &vsc9953_ops,
+ .stats_layout = vsc9953_stats_layout,
+ .num_stats = ARRAY_SIZE(vsc9953_stats_layout),
+ .vcap_is2_keys = vsc9953_vcap_is2_keys,
+ .vcap_is2_actions = vsc9953_vcap_is2_actions,
+ .vcap = vsc9953_vcap_props,
+ .shared_queue_sz = 128 * 1024,
+ .num_mact_rows = 2048,
+ .num_ports = 10,
+ .mdio_bus_alloc = vsc9953_mdio_bus_alloc,
+ .mdio_bus_free = vsc9959_mdio_bus_free,
+ .pcs_config = vsc9959_pcs_config,
+ .pcs_link_up = vsc9959_pcs_link_up,
+ .pcs_link_state = vsc9959_pcs_link_state,
+ .phylink_validate = vsc9953_phylink_validate,
+ .prevalidate_phy_mode = vsc9953_prevalidate_phy_mode,
+ .xmit_template_populate = vsc9953_xmit_template_populate,
+};
+
+static int seville_probe(struct platform_device *pdev)
+{
+ struct dsa_switch *ds;
+ struct ocelot *ocelot;
+ struct resource *res;
+ struct felix *felix;
+ int err;
+
+ felix = kzalloc(sizeof(struct felix), GFP_KERNEL);
+ if (!felix) {
+ err = -ENOMEM;
+ dev_err(&pdev->dev, "Failed to allocate driver memory\n");
+ goto err_alloc_felix;
+ }
+
+ platform_set_drvdata(pdev, felix);
+
+ ocelot = &felix->ocelot;
+ ocelot->dev = &pdev->dev;
+ felix->info = &seville_info_vsc9953;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ felix->switch_base = res->start;
+
+ ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL);
+ if (!ds) {
+ err = -ENOMEM;
+ dev_err(&pdev->dev, "Failed to allocate DSA switch\n");
+ goto err_alloc_ds;
+ }
+
+ ds->dev = &pdev->dev;
+ ds->num_ports = felix->info->num_ports;
+ ds->ops = &felix_switch_ops;
+ ds->priv = ocelot;
+ felix->ds = ds;
+
+ err = dsa_register_switch(ds);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err);
+ goto err_register_ds;
+ }
+
+ return 0;
+
+err_register_ds:
+ kfree(ds);
+err_alloc_ds:
+err_alloc_felix:
+ kfree(felix);
+ return err;
+}
+
+static int seville_remove(struct platform_device *pdev)
+{
+ struct felix *felix;
+
+ felix = platform_get_drvdata(pdev);
+
+ dsa_unregister_switch(felix->ds);
+
+ kfree(felix->ds);
+ kfree(felix);
+
+ return 0;
+}
+
+static const struct of_device_id seville_of_match[] = {
+ { .compatible = "mscc,vsc9953-switch" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, seville_of_match);
+
+struct platform_driver seville_vsc9953_driver = {
+ .probe = seville_probe,
+ .remove = seville_remove,
+ .driver = {
+ .name = "mscc_seville",
+ .of_match_table = of_match_ptr(seville_of_match),
+ },
+};
diff --git a/drivers/net/dsa/qca/ar9331.c b/drivers/net/dsa/qca/ar9331.c
index 7c86056b9401..e24a99031b80 100644
--- a/drivers/net/dsa/qca/ar9331.c
+++ b/drivers/net/dsa/qca/ar9331.c
@@ -97,8 +97,7 @@
(AR9331_SW_PORT_STATUS_TXMAC | AR9331_SW_PORT_STATUS_RXMAC)
#define AR9331_SW_PORT_STATUS_LINK_MASK \
- (AR9331_SW_PORT_STATUS_LINK_EN | AR9331_SW_PORT_STATUS_FLOW_LINK_EN | \
- AR9331_SW_PORT_STATUS_DUPLEX_MODE | \
+ (AR9331_SW_PORT_STATUS_DUPLEX_MODE | \
AR9331_SW_PORT_STATUS_RX_FLOW_EN | AR9331_SW_PORT_STATUS_TX_FLOW_EN | \
AR9331_SW_PORT_STATUS_SPEED_M)
@@ -410,33 +409,10 @@ static void ar9331_sw_phylink_mac_config(struct dsa_switch *ds, int port,
struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ds->priv;
struct regmap *regmap = priv->regmap;
int ret;
- u32 val;
-
- switch (state->speed) {
- case SPEED_1000:
- val = AR9331_SW_PORT_STATUS_SPEED_1000;
- break;
- case SPEED_100:
- val = AR9331_SW_PORT_STATUS_SPEED_100;
- break;
- case SPEED_10:
- val = AR9331_SW_PORT_STATUS_SPEED_10;
- break;
- default:
- return;
- }
-
- if (state->duplex)
- val |= AR9331_SW_PORT_STATUS_DUPLEX_MODE;
-
- if (state->pause & MLO_PAUSE_TX)
- val |= AR9331_SW_PORT_STATUS_TX_FLOW_EN;
-
- if (state->pause & MLO_PAUSE_RX)
- val |= AR9331_SW_PORT_STATUS_RX_FLOW_EN;
ret = regmap_update_bits(regmap, AR9331_SW_REG_PORT_STATUS(port),
- AR9331_SW_PORT_STATUS_LINK_MASK, val);
+ AR9331_SW_PORT_STATUS_LINK_EN |
+ AR9331_SW_PORT_STATUS_FLOW_LINK_EN, 0);
if (ret)
dev_err_ratelimited(priv->dev, "%s: %i\n", __func__, ret);
}
@@ -464,11 +440,37 @@ static void ar9331_sw_phylink_mac_link_up(struct dsa_switch *ds, int port,
{
struct ar9331_sw_priv *priv = (struct ar9331_sw_priv *)ds->priv;
struct regmap *regmap = priv->regmap;
+ u32 val;
int ret;
+ val = AR9331_SW_PORT_STATUS_MAC_MASK;
+ switch (speed) {
+ case SPEED_1000:
+ val |= AR9331_SW_PORT_STATUS_SPEED_1000;
+ break;
+ case SPEED_100:
+ val |= AR9331_SW_PORT_STATUS_SPEED_100;
+ break;
+ case SPEED_10:
+ val |= AR9331_SW_PORT_STATUS_SPEED_10;
+ break;
+ default:
+ return;
+ }
+
+ if (duplex)
+ val |= AR9331_SW_PORT_STATUS_DUPLEX_MODE;
+
+ if (tx_pause)
+ val |= AR9331_SW_PORT_STATUS_TX_FLOW_EN;
+
+ if (rx_pause)
+ val |= AR9331_SW_PORT_STATUS_RX_FLOW_EN;
+
ret = regmap_update_bits(regmap, AR9331_SW_REG_PORT_STATUS(port),
- AR9331_SW_PORT_STATUS_MAC_MASK,
- AR9331_SW_PORT_STATUS_MAC_MASK);
+ AR9331_SW_PORT_STATUS_MAC_MASK |
+ AR9331_SW_PORT_STATUS_LINK_MASK,
+ val);
if (ret)
dev_err_ratelimited(priv->dev, "%s: %i\n", __func__, ret);
}
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index d2b5ab403e06..f1e484477e35 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -14,6 +14,7 @@
#include <linux/of_platform.h>
#include <linux/if_bridge.h>
#include <linux/mdio.h>
+#include <linux/phylink.h>
#include <linux/gpio/consumer.h>
#include <linux/etherdevice.h>
@@ -407,64 +408,121 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
mutex_unlock(&priv->reg_mutex);
}
-static void
-qca8k_mib_init(struct qca8k_priv *priv)
+static int
+qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
{
+ u32 reg;
+
+ /* Set the command and VLAN index */
+ reg = QCA8K_VTU_FUNC1_BUSY;
+ reg |= cmd;
+ reg |= vid << QCA8K_VTU_FUNC1_VID_S;
+
+ /* Write the function register triggering the table access */
+ qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
+
+ /* wait for completion */
+ if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
+ return -ETIMEDOUT;
+
+ /* Check for table full violation when adding an entry */
+ if (cmd == QCA8K_VLAN_LOAD) {
+ reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
+ if (reg & QCA8K_VTU_FUNC1_FULL)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int
+qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
+{
+ u32 reg;
+ int ret;
+
+ /*
+ We do the right thing with VLAN 0 and treat it as untagged while
+ preserving the tag on egress.
+ */
+ if (vid == 0)
+ return 0;
+
mutex_lock(&priv->reg_mutex);
- qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
- qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
- qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
- qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
+ if (ret < 0)
+ goto out;
+
+ reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
+ reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+ if (untagged)
+ reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG <<
+ QCA8K_VTU_FUNC0_EG_MODE_S(port);
+ else
+ reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
+ QCA8K_VTU_FUNC0_EG_MODE_S(port);
+
+ qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+
+out:
mutex_unlock(&priv->reg_mutex);
+
+ return ret;
}
static int
-qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode)
+qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
{
- u32 reg, val;
+ u32 reg, mask;
+ int ret, i;
+ bool del;
- switch (port) {
- case 0:
- reg = QCA8K_REG_PORT0_PAD_CTRL;
- break;
- case 6:
- reg = QCA8K_REG_PORT6_PAD_CTRL;
- break;
- default:
- pr_err("Can't set PAD_CTRL on port %d\n", port);
- return -EINVAL;
+ mutex_lock(&priv->reg_mutex);
+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
+ if (ret < 0)
+ goto out;
+
+ reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+ reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+ reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
+ QCA8K_VTU_FUNC0_EG_MODE_S(port);
+
+ /* Check if we're the last member to be removed */
+ del = true;
+ for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+ mask = QCA8K_VTU_FUNC0_EG_MODE_NOT;
+ mask <<= QCA8K_VTU_FUNC0_EG_MODE_S(i);
+
+ if ((reg & mask) != mask) {
+ del = false;
+ break;
+ }
}
- /* Configure a port to be directly connected to an external
- * PHY or MAC.
- */
- switch (mode) {
- case PHY_INTERFACE_MODE_RGMII:
- /* RGMII mode means no delay so don't enable the delay */
- val = QCA8K_PORT_PAD_RGMII_EN;
- qca8k_write(priv, reg, val);
- break;
- case PHY_INTERFACE_MODE_RGMII_ID:
- /* RGMII_ID needs internal delay. This is enabled through
- * PORT5_PAD_CTRL for all ports, rather than individual port
- * registers
- */
- qca8k_write(priv, reg,
- QCA8K_PORT_PAD_RGMII_EN |
- QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
- QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
- qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
- break;
- case PHY_INTERFACE_MODE_SGMII:
- qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
- break;
- default:
- pr_err("xMII mode %d not supported\n", mode);
- return -EINVAL;
+ if (del) {
+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
+ } else {
+ qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
}
- return 0;
+out:
+ mutex_unlock(&priv->reg_mutex);
+
+ return ret;
+}
+
+static void
+qca8k_mib_init(struct qca8k_priv *priv)
+{
+ mutex_lock(&priv->reg_mutex);
+ qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
+ qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
+ qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
+ qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
+ mutex_unlock(&priv->reg_mutex);
}
static void
@@ -639,9 +697,7 @@ static int
qca8k_setup(struct dsa_switch *ds)
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
- phy_interface_t phy_mode = PHY_INTERFACE_MODE_NA;
int ret, i;
- u32 mask;
/* Make sure that port 0 is the cpu port */
if (!dsa_is_cpu_port(ds, 0)) {
@@ -661,24 +717,9 @@ qca8k_setup(struct dsa_switch *ds)
if (ret)
return ret;
- /* Initialize CPU port pad mode (xMII type, delays...) */
- ret = of_get_phy_mode(dsa_to_port(ds, QCA8K_CPU_PORT)->dn, &phy_mode);
- if (ret) {
- pr_err("Can't find phy-mode for master device\n");
- return ret;
- }
- ret = qca8k_set_pad_ctrl(priv, QCA8K_CPU_PORT, phy_mode);
- if (ret < 0)
- return ret;
-
- /* Enable CPU Port, force it to maximum bandwidth and full-duplex */
- mask = QCA8K_PORT_STATUS_SPEED_1000 | QCA8K_PORT_STATUS_TXFLOW |
- QCA8K_PORT_STATUS_RXFLOW | QCA8K_PORT_STATUS_DUPLEX;
- qca8k_write(priv, QCA8K_REG_PORT_STATUS(QCA8K_CPU_PORT), mask);
+ /* Enable CPU Port */
qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
- qca8k_port_set_status(priv, QCA8K_CPU_PORT, 1);
- priv->port_sts[QCA8K_CPU_PORT].enabled = 1;
/* Enable MIB counters */
qca8k_mib_init(priv);
@@ -693,10 +734,9 @@ qca8k_setup(struct dsa_switch *ds)
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
QCA8K_PORT_LOOKUP_MEMBER, 0);
- /* Disable MAC by default on all user ports */
+ /* Disable MAC by default on all ports */
for (i = 1; i < QCA8K_NUM_PORTS; i++)
- if (dsa_is_user_port(ds, i))
- qca8k_port_set_status(priv, i, 0);
+ qca8k_port_set_status(priv, i, 0);
/* Forward all unknown frames to CPU port for Linux processing */
qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
@@ -713,7 +753,7 @@ qca8k_setup(struct dsa_switch *ds)
QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
}
- /* Invividual user ports get connected to CPU port only */
+ /* Individual user ports get connected to CPU port only */
if (dsa_is_user_port(ds, i)) {
int shift = 16 * (i % 2);
@@ -729,58 +769,273 @@ qca8k_setup(struct dsa_switch *ds)
* default egress vid
*/
qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
- 0xffff << shift, 1 << shift);
+ 0xfff << shift,
+ QCA8K_PORT_VID_DEF << shift);
qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
- QCA8K_PORT_VLAN_CVID(1) |
- QCA8K_PORT_VLAN_SVID(1));
+ QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
+ QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
}
}
+ /* Setup our port MTUs to match power on defaults */
+ for (i = 0; i < QCA8K_NUM_PORTS; i++)
+ priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
+ qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
+
/* Flush the FDB table */
qca8k_fdb_flush(priv);
+ /* We don't have interrupts for link changes, so we need to poll */
+ ds->pcs_poll = true;
+
return 0;
}
static void
-qca8k_adjust_link(struct dsa_switch *ds, int port, struct phy_device *phy)
+qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
+ const struct phylink_link_state *state)
{
struct qca8k_priv *priv = ds->priv;
- u32 reg;
+ u32 reg, val;
+
+ switch (port) {
+ case 0: /* 1st CPU port */
+ if (state->interface != PHY_INTERFACE_MODE_RGMII &&
+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
+ state->interface != PHY_INTERFACE_MODE_SGMII)
+ return;
+
+ reg = QCA8K_REG_PORT0_PAD_CTRL;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ /* Internal PHY, nothing to do */
+ return;
+ case 6: /* 2nd CPU port / external PHY */
+ if (state->interface != PHY_INTERFACE_MODE_RGMII &&
+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
+ state->interface != PHY_INTERFACE_MODE_SGMII &&
+ state->interface != PHY_INTERFACE_MODE_1000BASEX)
+ return;
+
+ reg = QCA8K_REG_PORT6_PAD_CTRL;
+ break;
+ default:
+ dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
+ return;
+ }
+
+ if (port != 6 && phylink_autoneg_inband(mode)) {
+ dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
+ __func__);
+ return;
+ }
+
+ switch (state->interface) {
+ case PHY_INTERFACE_MODE_RGMII:
+ /* RGMII mode means no delay so don't enable the delay */
+ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
+ break;
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ /* RGMII_ID needs internal delay. This is enabled through
+ * PORT5_PAD_CTRL for all ports, rather than individual port
+ * registers
+ */
+ qca8k_write(priv, reg,
+ QCA8K_PORT_PAD_RGMII_EN |
+ QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
+ QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
+ qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ /* Enable SGMII on the port */
+ qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
- /* Force fixed-link setting for CPU port, skip others. */
- if (!phy_is_pseudo_fixed_link(phy))
+ /* Enable/disable SerDes auto-negotiation as necessary */
+ val = qca8k_read(priv, QCA8K_REG_PWS);
+ if (phylink_autoneg_inband(mode))
+ val &= ~QCA8K_PWS_SERDES_AEN_DIS;
+ else
+ val |= QCA8K_PWS_SERDES_AEN_DIS;
+ qca8k_write(priv, QCA8K_REG_PWS, val);
+
+ /* Configure the SGMII parameters */
+ val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
+
+ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+ QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
+
+ if (dsa_is_cpu_port(ds, port)) {
+ /* CPU port, we're talking to the CPU MAC, be a PHY */
+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+ val |= QCA8K_SGMII_MODE_CTRL_PHY;
+ } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+ val |= QCA8K_SGMII_MODE_CTRL_MAC;
+ } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+ val |= QCA8K_SGMII_MODE_CTRL_BASEX;
+ }
+
+ qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
+ break;
+ default:
+ dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
+ phy_modes(state->interface), port);
return;
+ }
+}
+
+static void
+qca8k_phylink_validate(struct dsa_switch *ds, int port,
+ unsigned long *supported,
+ struct phylink_link_state *state)
+{
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
- /* Set port speed */
- switch (phy->speed) {
- case 10:
- reg = QCA8K_PORT_STATUS_SPEED_10;
+ switch (port) {
+ case 0: /* 1st CPU port */
+ if (state->interface != PHY_INTERFACE_MODE_NA &&
+ state->interface != PHY_INTERFACE_MODE_RGMII &&
+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
+ state->interface != PHY_INTERFACE_MODE_SGMII)
+ goto unsupported;
break;
- case 100:
- reg = QCA8K_PORT_STATUS_SPEED_100;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ /* Internal PHY */
+ if (state->interface != PHY_INTERFACE_MODE_NA &&
+ state->interface != PHY_INTERFACE_MODE_GMII)
+ goto unsupported;
break;
- case 1000:
- reg = QCA8K_PORT_STATUS_SPEED_1000;
+ case 6: /* 2nd CPU port / external PHY */
+ if (state->interface != PHY_INTERFACE_MODE_NA &&
+ state->interface != PHY_INTERFACE_MODE_RGMII &&
+ state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
+ state->interface != PHY_INTERFACE_MODE_SGMII &&
+ state->interface != PHY_INTERFACE_MODE_1000BASEX)
+ goto unsupported;
break;
default:
- dev_dbg(priv->dev, "port%d link speed %dMbps not supported.\n",
- port, phy->speed);
+unsupported:
+ linkmode_zero(supported);
return;
}
- /* Set duplex mode */
- if (phy->duplex == DUPLEX_FULL)
- reg |= QCA8K_PORT_STATUS_DUPLEX;
+ phylink_set_port_modes(mask);
+ phylink_set(mask, Autoneg);
+
+ phylink_set(mask, 1000baseT_Full);
+ phylink_set(mask, 10baseT_Half);
+ phylink_set(mask, 10baseT_Full);
+ phylink_set(mask, 100baseT_Half);
+ phylink_set(mask, 100baseT_Full);
- /* Force flow control */
- if (dsa_is_cpu_port(ds, port))
- reg |= QCA8K_PORT_STATUS_RXFLOW | QCA8K_PORT_STATUS_TXFLOW;
+ if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
+ phylink_set(mask, 1000baseX_Full);
+
+ phylink_set(mask, Pause);
+ phylink_set(mask, Asym_Pause);
+
+ linkmode_and(supported, supported, mask);
+ linkmode_and(state->advertising, state->advertising, mask);
+}
+
+static int
+qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port,
+ struct phylink_link_state *state)
+{
+ struct qca8k_priv *priv = ds->priv;
+ u32 reg;
+
+ reg = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port));
+
+ state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
+ state->an_complete = state->link;
+ state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO);
+ state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL :
+ DUPLEX_HALF;
+
+ switch (reg & QCA8K_PORT_STATUS_SPEED) {
+ case QCA8K_PORT_STATUS_SPEED_10:
+ state->speed = SPEED_10;
+ break;
+ case QCA8K_PORT_STATUS_SPEED_100:
+ state->speed = SPEED_100;
+ break;
+ case QCA8K_PORT_STATUS_SPEED_1000:
+ state->speed = SPEED_1000;
+ break;
+ default:
+ state->speed = SPEED_UNKNOWN;
+ break;
+ }
+
+ state->pause = MLO_PAUSE_NONE;
+ if (reg & QCA8K_PORT_STATUS_RXFLOW)
+ state->pause |= MLO_PAUSE_RX;
+ if (reg & QCA8K_PORT_STATUS_TXFLOW)
+ state->pause |= MLO_PAUSE_TX;
+
+ return 1;
+}
+
+static void
+qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
+ phy_interface_t interface)
+{
+ struct qca8k_priv *priv = ds->priv;
- /* Force link down before changing MAC options */
qca8k_port_set_status(priv, port, 0);
+}
+
+static void
+qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode,
+ phy_interface_t interface, struct phy_device *phydev,
+ int speed, int duplex, bool tx_pause, bool rx_pause)
+{
+ struct qca8k_priv *priv = ds->priv;
+ u32 reg;
+
+ if (phylink_autoneg_inband(mode)) {
+ reg = QCA8K_PORT_STATUS_LINK_AUTO;
+ } else {
+ switch (speed) {
+ case SPEED_10:
+ reg = QCA8K_PORT_STATUS_SPEED_10;
+ break;
+ case SPEED_100:
+ reg = QCA8K_PORT_STATUS_SPEED_100;
+ break;
+ case SPEED_1000:
+ reg = QCA8K_PORT_STATUS_SPEED_1000;
+ break;
+ default:
+ reg = QCA8K_PORT_STATUS_LINK_AUTO;
+ break;
+ }
+
+ if (duplex == DUPLEX_FULL)
+ reg |= QCA8K_PORT_STATUS_DUPLEX;
+
+ if (rx_pause || dsa_is_cpu_port(ds, port))
+ reg |= QCA8K_PORT_STATUS_RXFLOW;
+
+ if (tx_pause || dsa_is_cpu_port(ds, port))
+ reg |= QCA8K_PORT_STATUS_TXFLOW;
+ }
+
+ reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
+
qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
- qca8k_port_set_status(priv, port, 1);
}
static void
@@ -937,13 +1192,11 @@ qca8k_port_enable(struct dsa_switch *ds, int port,
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
- if (!dsa_is_user_port(ds, port))
- return 0;
-
qca8k_port_set_status(priv, port, 1);
priv->port_sts[port].enabled = 1;
- phy_support_asym_pause(phy);
+ if (dsa_is_user_port(ds, port))
+ phy_support_asym_pause(phy);
return 0;
}
@@ -958,12 +1211,36 @@ qca8k_port_disable(struct dsa_switch *ds, int port)
}
static int
+qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+ struct qca8k_priv *priv = ds->priv;
+ int i, mtu = 0;
+
+ priv->port_mtu[port] = new_mtu;
+
+ for (i = 0; i < QCA8K_NUM_PORTS; i++)
+ if (priv->port_mtu[port] > mtu)
+ mtu = priv->port_mtu[port];
+
+ /* Include L2 header / FCS length */
+ qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
+
+ return 0;
+}
+
+static int
+qca8k_port_max_mtu(struct dsa_switch *ds, int port)
+{
+ return QCA8K_MAX_MTU;
+}
+
+static int
qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
u16 port_mask, u16 vid)
{
/* Set the vid to the port vlan id if no vid is set */
if (!vid)
- vid = 1;
+ vid = QCA8K_PORT_VID_DEF;
return qca8k_fdb_add(priv, addr, port_mask, vid,
QCA8K_ATU_STATUS_STATIC);
@@ -987,7 +1264,7 @@ qca8k_port_fdb_del(struct dsa_switch *ds, int port,
u16 port_mask = BIT(port);
if (!vid)
- vid = 1;
+ vid = QCA8K_PORT_VID_DEF;
return qca8k_fdb_del(priv, addr, port_mask, vid);
}
@@ -1016,6 +1293,76 @@ qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
return 0;
}
+static int
+qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering)
+{
+ struct qca8k_priv *priv = ds->priv;
+
+ if (vlan_filtering) {
+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
+ QCA8K_PORT_LOOKUP_VLAN_MODE,
+ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
+ } else {
+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
+ QCA8K_PORT_LOOKUP_VLAN_MODE,
+ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
+ }
+
+ return 0;
+}
+
+static int
+qca8k_port_vlan_prepare(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_vlan *vlan)
+{
+ return 0;
+}
+
+static void
+qca8k_port_vlan_add(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_vlan *vlan)
+{
+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
+ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
+ struct qca8k_priv *priv = ds->priv;
+ int ret = 0;
+ u16 vid;
+
+ for (vid = vlan->vid_begin; vid <= vlan->vid_end && !ret; ++vid)
+ ret = qca8k_vlan_add(priv, port, vid, untagged);
+
+ if (ret)
+ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
+
+ if (pvid) {
+ int shift = 16 * (port % 2);
+
+ qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
+ 0xfff << shift,
+ vlan->vid_end << shift);
+ qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
+ QCA8K_PORT_VLAN_CVID(vlan->vid_end) |
+ QCA8K_PORT_VLAN_SVID(vlan->vid_end));
+ }
+}
+
+static int
+qca8k_port_vlan_del(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_vlan *vlan)
+{
+ struct qca8k_priv *priv = ds->priv;
+ int ret = 0;
+ u16 vid;
+
+ for (vid = vlan->vid_begin; vid <= vlan->vid_end && !ret; ++vid)
+ ret = qca8k_vlan_del(priv, port, vid);
+
+ if (ret)
+ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
+
+ return ret;
+}
+
static enum dsa_tag_protocol
qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
enum dsa_tag_protocol mp)
@@ -1026,7 +1373,6 @@ qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
static const struct dsa_switch_ops qca8k_switch_ops = {
.get_tag_protocol = qca8k_get_tag_protocol,
.setup = qca8k_setup,
- .adjust_link = qca8k_adjust_link,
.get_strings = qca8k_get_strings,
.get_ethtool_stats = qca8k_get_ethtool_stats,
.get_sset_count = qca8k_get_sset_count,
@@ -1034,12 +1380,23 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
.set_mac_eee = qca8k_set_mac_eee,
.port_enable = qca8k_port_enable,
.port_disable = qca8k_port_disable,
+ .port_change_mtu = qca8k_port_change_mtu,
+ .port_max_mtu = qca8k_port_max_mtu,
.port_stp_state_set = qca8k_port_stp_state_set,
.port_bridge_join = qca8k_port_bridge_join,
.port_bridge_leave = qca8k_port_bridge_leave,
.port_fdb_add = qca8k_port_fdb_add,
.port_fdb_del = qca8k_port_fdb_del,
.port_fdb_dump = qca8k_port_fdb_dump,
+ .port_vlan_filtering = qca8k_port_vlan_filtering,
+ .port_vlan_prepare = qca8k_port_vlan_prepare,
+ .port_vlan_add = qca8k_port_vlan_add,
+ .port_vlan_del = qca8k_port_vlan_del,
+ .phylink_validate = qca8k_phylink_validate,
+ .phylink_mac_link_state = qca8k_phylink_mac_link_state,
+ .phylink_mac_config = qca8k_phylink_mac_config,
+ .phylink_mac_link_down = qca8k_phylink_mac_link_down,
+ .phylink_mac_link_up = qca8k_phylink_mac_link_up,
};
static int
@@ -1085,6 +1442,7 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
priv->ds->dev = &mdiodev->dev;
priv->ds->num_ports = QCA8K_NUM_PORTS;
+ priv->ds->configure_vlan_while_not_filtering = true;
priv->ds->priv = priv;
priv->ops = qca8k_switch_ops;
priv->ds->ops = &priv->ops;
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 42d6ea24eb14..7ca4b93e0bb5 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -13,6 +13,7 @@
#include <linux/gpio.h>
#define QCA8K_NUM_PORTS 7
+#define QCA8K_MAX_MTU 9000
#define PHY_ID_QCA8337 0x004dd036
#define QCA8K_ID_QCA8337 0x13
@@ -21,6 +22,8 @@
#define QCA8K_CPU_PORT 0
+#define QCA8K_PORT_VID_DEF 1
+
/* Global control registers */
#define QCA8K_REG_MASK_CTRL 0x000
#define QCA8K_MASK_CTRL_ID_M 0xff
@@ -36,6 +39,8 @@
#define QCA8K_MAX_DELAY 3
#define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
#define QCA8K_PORT_PAD_SGMII_EN BIT(7)
+#define QCA8K_REG_PWS 0x010
+#define QCA8K_PWS_SERDES_AEN_DIS BIT(7)
#define QCA8K_REG_MODULE_EN 0x030
#define QCA8K_MODULE_EN_MIB BIT(0)
#define QCA8K_REG_MIB 0x034
@@ -56,6 +61,7 @@
#define QCA8K_MDIO_MASTER_MAX_REG 32
#define QCA8K_GOL_MAC_ADDR0 0x60
#define QCA8K_GOL_MAC_ADDR1 0x64
+#define QCA8K_MAX_FRAME_SIZE 0x78
#define QCA8K_REG_PORT_STATUS(_i) (0x07c + (_i) * 4)
#define QCA8K_PORT_STATUS_SPEED GENMASK(1, 0)
#define QCA8K_PORT_STATUS_SPEED_10 0
@@ -69,6 +75,7 @@
#define QCA8K_PORT_STATUS_LINK_UP BIT(8)
#define QCA8K_PORT_STATUS_LINK_AUTO BIT(9)
#define QCA8K_PORT_STATUS_LINK_PAUSE BIT(10)
+#define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12)
#define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4))
#define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2)
#define QCA8K_PORT_HDR_CTRL_RX_S 2
@@ -77,6 +84,16 @@
#define QCA8K_PORT_HDR_CTRL_ALL 2
#define QCA8K_PORT_HDR_CTRL_MGMT 1
#define QCA8K_PORT_HDR_CTRL_NONE 0
+#define QCA8K_REG_SGMII_CTRL 0x0e0
+#define QCA8K_SGMII_EN_PLL BIT(1)
+#define QCA8K_SGMII_EN_RX BIT(2)
+#define QCA8K_SGMII_EN_TX BIT(3)
+#define QCA8K_SGMII_EN_SD BIT(4)
+#define QCA8K_SGMII_CLK125M_DELAY BIT(7)
+#define QCA8K_SGMII_MODE_CTRL_MASK (BIT(22) | BIT(23))
+#define QCA8K_SGMII_MODE_CTRL_BASEX (0 << 22)
+#define QCA8K_SGMII_MODE_CTRL_PHY (1 << 22)
+#define QCA8K_SGMII_MODE_CTRL_MAC (2 << 22)
/* EEE control registers */
#define QCA8K_REG_EEE_CTRL 0x100
@@ -111,6 +128,19 @@
#define QCA8K_ATU_FUNC_FULL BIT(12)
#define QCA8K_ATU_FUNC_PORT_M 0xf
#define QCA8K_ATU_FUNC_PORT_S 8
+#define QCA8K_REG_VTU_FUNC0 0x610
+#define QCA8K_VTU_FUNC0_VALID BIT(20)
+#define QCA8K_VTU_FUNC0_IVL_EN BIT(19)
+#define QCA8K_VTU_FUNC0_EG_MODE_S(_i) (4 + (_i) * 2)
+#define QCA8K_VTU_FUNC0_EG_MODE_MASK 3
+#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD 0
+#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG 1
+#define QCA8K_VTU_FUNC0_EG_MODE_TAG 2
+#define QCA8K_VTU_FUNC0_EG_MODE_NOT 3
+#define QCA8K_REG_VTU_FUNC1 0x614
+#define QCA8K_VTU_FUNC1_BUSY BIT(31)
+#define QCA8K_VTU_FUNC1_VID_S 16
+#define QCA8K_VTU_FUNC1_FULL BIT(4)
#define QCA8K_REG_GLOBAL_FW_CTRL0 0x620
#define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10)
#define QCA8K_REG_GLOBAL_FW_CTRL1 0x624
@@ -120,6 +150,11 @@
#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_S 0
#define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc)
#define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0)
+#define QCA8K_PORT_LOOKUP_VLAN_MODE GENMASK(9, 8)
+#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE (0 << 8)
+#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK (1 << 8)
+#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK (2 << 8)
+#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE (3 << 8)
#define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16)
#define QCA8K_PORT_LOOKUP_STATE_DISABLED (0 << 16)
#define QCA8K_PORT_LOOKUP_STATE_BLOCKING (1 << 16)
@@ -163,6 +198,15 @@ enum qca8k_fdb_cmd {
QCA8K_FDB_SEARCH = 7,
};
+enum qca8k_vlan_cmd {
+ QCA8K_VLAN_FLUSH = 1,
+ QCA8K_VLAN_LOAD = 2,
+ QCA8K_VLAN_PURGE = 3,
+ QCA8K_VLAN_REMOVE_PORT = 4,
+ QCA8K_VLAN_NEXT = 5,
+ QCA8K_VLAN_READ = 6,
+};
+
struct ar8xxx_port_status {
int enabled;
};
@@ -176,6 +220,7 @@ struct qca8k_priv {
struct device *dev;
struct dsa_switch_ops ops;
struct gpio_desc *reset_gpio;
+ unsigned int port_mtu[QCA8K_NUM_PORTS];
};
struct qca8k_mib_desc {
diff --git a/drivers/net/dsa/rtl8366.c b/drivers/net/dsa/rtl8366.c
index ac88caca5ad4..8f40fbf70a82 100644
--- a/drivers/net/dsa/rtl8366.c
+++ b/drivers/net/dsa/rtl8366.c
@@ -43,18 +43,26 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member,
int ret;
int i;
+ dev_dbg(smi->dev,
+ "setting VLAN%d 4k members: 0x%02x, untagged: 0x%02x\n",
+ vid, member, untag);
+
/* Update the 4K table */
ret = smi->ops->get_vlan_4k(smi, vid, &vlan4k);
if (ret)
return ret;
- vlan4k.member = member;
- vlan4k.untag = untag;
+ vlan4k.member |= member;
+ vlan4k.untag |= untag;
vlan4k.fid = fid;
ret = smi->ops->set_vlan_4k(smi, &vlan4k);
if (ret)
return ret;
+ dev_dbg(smi->dev,
+ "resulting VLAN%d 4k members: 0x%02x, untagged: 0x%02x\n",
+ vid, vlan4k.member, vlan4k.untag);
+
/* Try to find an existing MC entry for this VID */
for (i = 0; i < smi->num_vlan_mc; i++) {
struct rtl8366_vlan_mc vlanmc;
@@ -65,11 +73,16 @@ int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member,
if (vid == vlanmc.vid) {
/* update the MC entry */
- vlanmc.member = member;
- vlanmc.untag = untag;
+ vlanmc.member |= member;
+ vlanmc.untag |= untag;
vlanmc.fid = fid;
ret = smi->ops->set_vlan_mc(smi, i, &vlanmc);
+
+ dev_dbg(smi->dev,
+ "resulting VLAN%d MC members: 0x%02x, untagged: 0x%02x\n",
+ vid, vlanmc.member, vlanmc.untag);
+
break;
}
}
@@ -272,7 +285,7 @@ int rtl8366_init_vlan(struct realtek_smi *smi)
/* For the CPU port, make all ports members of this
* VLAN.
*/
- mask = GENMASK(smi->num_ports - 1, 0);
+ mask = GENMASK((int)smi->num_ports - 1, 0);
else
/* For all other ports, enable itself plus the
* CPU port.
@@ -384,7 +397,7 @@ void rtl8366_vlan_add(struct dsa_switch *ds, int port,
if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
dev_err(smi->dev, "port is DSA or CPU port\n");
- for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
+ for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
int pvid_val = 0;
dev_info(smi->dev, "add VLAN %04x\n", vid);
@@ -407,13 +420,13 @@ void rtl8366_vlan_add(struct dsa_switch *ds, int port,
if (ret < 0)
return;
}
- }
- ret = rtl8366_set_vlan(smi, port, member, untag, 0);
- if (ret)
- dev_err(smi->dev,
- "failed to set up VLAN %04x",
- vid);
+ ret = rtl8366_set_vlan(smi, vid, member, untag, 0);
+ if (ret)
+ dev_err(smi->dev,
+ "failed to set up VLAN %04x",
+ vid);
+ }
}
EXPORT_SYMBOL_GPL(rtl8366_vlan_add);
diff --git a/drivers/net/dsa/rtl8366rb.c b/drivers/net/dsa/rtl8366rb.c
index fd1977590cb4..48f1ff746799 100644
--- a/drivers/net/dsa/rtl8366rb.c
+++ b/drivers/net/dsa/rtl8366rb.c
@@ -109,8 +109,8 @@
/* CPU port control reg */
#define RTL8368RB_CPU_CTRL_REG 0x0061
#define RTL8368RB_CPU_PORTS_MSK 0x00FF
-/* Enables inserting custom tag length/type 0x8899 */
-#define RTL8368RB_CPU_INSTAG BIT(15)
+/* Disables inserting custom tag length/type 0x8899 */
+#define RTL8368RB_CPU_NO_TAG BIT(15)
#define RTL8366RB_SMAR0 0x0070 /* bits 0..15 */
#define RTL8366RB_SMAR1 0x0071 /* bits 16..31 */
@@ -844,16 +844,14 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
if (ret)
return ret;
- /* Enable CPU port and enable inserting CPU tag
+ /* Enable CPU port with custom DSA tag 8899.
*
- * Disabling RTL8368RB_CPU_INSTAG here will change the behaviour
- * of the switch totally and it will start talking Realtek RRCP
- * internally. It is probably possible to experiment with this,
- * but then the kernel needs to understand and handle RRCP first.
+ * If you set RTL8368RB_CPU_NO_TAG (bit 15) in this registers
+ * the custom tag is turned off.
*/
ret = regmap_update_bits(smi->map, RTL8368RB_CPU_CTRL_REG,
0xFFFF,
- RTL8368RB_CPU_INSTAG | BIT(smi->cpu_port));
+ BIT(smi->cpu_port));
if (ret)
return ret;
@@ -967,21 +965,8 @@ static enum dsa_tag_protocol rtl8366_get_tag_protocol(struct dsa_switch *ds,
int port,
enum dsa_tag_protocol mp)
{
- /* For now, the RTL switches are handled without any custom tags.
- *
- * It is possible to turn on "custom tags" by removing the
- * RTL8368RB_CPU_INSTAG flag when enabling the port but what it
- * does is unfamiliar to DSA: ethernet frames of type 8899, the Realtek
- * Remote Control Protocol (RRCP) start to appear on the CPU port of
- * the device. So this is not the ordinary few extra bytes in the
- * frame. Instead it appears that the switch starts to talk Realtek
- * RRCP internally which means a pretty complex RRCP implementation
- * decoding and responding the RRCP protocol is needed to exploit this.
- *
- * The OpenRRCP project (dormant since 2009) have reverse-egineered
- * parts of the protocol.
- */
- return DSA_TAG_PROTO_NONE;
+ /* This switch uses the 4 byte protocol A Realtek DSA tag */
+ return DSA_TAG_PROTO_RTL4_A;
}
static void rtl8366rb_adjust_link(struct dsa_switch *ds, int port,
diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h
index 29ed21687295..ba70b40a9a95 100644
--- a/drivers/net/dsa/sja1105/sja1105.h
+++ b/drivers/net/dsa/sja1105/sja1105.h
@@ -262,12 +262,12 @@ int sja1105_static_config_upload(struct sja1105_private *priv);
int sja1105_inhibit_tx(const struct sja1105_private *priv,
unsigned long port_bitmap, bool tx_inhibited);
-extern struct sja1105_info sja1105e_info;
-extern struct sja1105_info sja1105t_info;
-extern struct sja1105_info sja1105p_info;
-extern struct sja1105_info sja1105q_info;
-extern struct sja1105_info sja1105r_info;
-extern struct sja1105_info sja1105s_info;
+extern const struct sja1105_info sja1105e_info;
+extern const struct sja1105_info sja1105t_info;
+extern const struct sja1105_info sja1105p_info;
+extern const struct sja1105_info sja1105q_info;
+extern const struct sja1105_info sja1105r_info;
+extern const struct sja1105_info sja1105s_info;
/* From sja1105_clocking.c */
diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
index 4471eeccc293..75247f342124 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
@@ -638,9 +638,7 @@ static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr,
#define OP_SEARCH BIT(3)
/* SJA1105E/T: First generation */
-struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
- [BLK_IDX_SCHEDULE] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {0},
+const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
[BLK_IDX_VL_LOOKUP] = {
.entry_packing = sja1105et_vl_lookup_entry_packing,
.cmd_packing = sja1105_vl_lookup_cmd_packing,
@@ -649,8 +647,6 @@ struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105ET_SJA1105_SIZE_VL_LOOKUP_DYN_CMD,
.addr = 0x35,
},
- [BLK_IDX_VL_POLICING] = {0},
- [BLK_IDX_VL_FORWARDING] = {0},
[BLK_IDX_L2_LOOKUP] = {
.entry_packing = sja1105et_dyn_l2_lookup_entry_packing,
.cmd_packing = sja1105et_l2_lookup_cmd_packing,
@@ -667,7 +663,6 @@ struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD,
.addr = 0x20,
},
- [BLK_IDX_L2_POLICING] = {0},
[BLK_IDX_VLAN_LOOKUP] = {
.entry_packing = sja1105_vlan_lookup_entry_packing,
.cmd_packing = sja1105_vlan_lookup_cmd_packing,
@@ -692,9 +687,6 @@ struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105ET_SIZE_MAC_CONFIG_DYN_CMD,
.addr = 0x36,
},
- [BLK_IDX_SCHEDULE_PARAMS] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {0},
- [BLK_IDX_VL_FORWARDING_PARAMS] = {0},
[BLK_IDX_L2_LOOKUP_PARAMS] = {
.entry_packing = sja1105et_l2_lookup_params_entry_packing,
.cmd_packing = sja1105et_l2_lookup_params_cmd_packing,
@@ -703,8 +695,6 @@ struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD,
.addr = 0x38,
},
- [BLK_IDX_L2_FORWARDING_PARAMS] = {0},
- [BLK_IDX_AVB_PARAMS] = {0},
[BLK_IDX_GENERAL_PARAMS] = {
.entry_packing = sja1105et_general_params_entry_packing,
.cmd_packing = sja1105et_general_params_cmd_packing,
@@ -729,13 +719,10 @@ struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105ET_SIZE_CBS_DYN_CMD,
.addr = 0x2c,
},
- [BLK_IDX_XMII_PARAMS] = {0},
};
/* SJA1105P/Q/R/S: Second generation */
-struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
- [BLK_IDX_SCHEDULE] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {0},
+const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
[BLK_IDX_VL_LOOKUP] = {
.entry_packing = sja1105_vl_lookup_entry_packing,
.cmd_packing = sja1105_vl_lookup_cmd_packing,
@@ -744,8 +731,6 @@ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105PQRS_SJA1105_SIZE_VL_LOOKUP_DYN_CMD,
.addr = 0x47,
},
- [BLK_IDX_VL_POLICING] = {0},
- [BLK_IDX_VL_FORWARDING] = {0},
[BLK_IDX_L2_LOOKUP] = {
.entry_packing = sja1105pqrs_dyn_l2_lookup_entry_packing,
.cmd_packing = sja1105pqrs_l2_lookup_cmd_packing,
@@ -762,7 +747,6 @@ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD,
.addr = 0x24,
},
- [BLK_IDX_L2_POLICING] = {0},
[BLK_IDX_VLAN_LOOKUP] = {
.entry_packing = sja1105_vlan_lookup_entry_packing,
.cmd_packing = sja1105_vlan_lookup_cmd_packing,
@@ -787,9 +771,6 @@ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD,
.addr = 0x4B,
},
- [BLK_IDX_SCHEDULE_PARAMS] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {0},
- [BLK_IDX_VL_FORWARDING_PARAMS] = {0},
[BLK_IDX_L2_LOOKUP_PARAMS] = {
.entry_packing = sja1105pqrs_l2_lookup_params_entry_packing,
.cmd_packing = sja1105pqrs_l2_lookup_params_cmd_packing,
@@ -798,7 +779,6 @@ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_DYN_CMD,
.addr = 0x54,
},
- [BLK_IDX_L2_FORWARDING_PARAMS] = {0},
[BLK_IDX_AVB_PARAMS] = {
.entry_packing = sja1105pqrs_avb_params_entry_packing,
.cmd_packing = sja1105pqrs_avb_params_cmd_packing,
@@ -831,7 +811,6 @@ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
.packed_size = SJA1105PQRS_SIZE_CBS_DYN_CMD,
.addr = 0x32,
},
- [BLK_IDX_XMII_PARAMS] = {0},
};
/* Provides read access to the settings through the dynamic interface
diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h
index 1fc0d13dc623..28d4eb5efb8b 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h
@@ -34,7 +34,7 @@ struct sja1105_mgmt_entry {
u64 index;
};
-extern struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN];
-extern struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN];
+extern const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN];
+extern const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN];
#endif
diff --git a/drivers/net/dsa/sja1105/sja1105_flower.c b/drivers/net/dsa/sja1105/sja1105_flower.c
index 9ee8968610cd..12e76020bea3 100644
--- a/drivers/net/dsa/sja1105/sja1105_flower.c
+++ b/drivers/net/dsa/sja1105/sja1105_flower.c
@@ -31,7 +31,7 @@ static int sja1105_setup_bcast_policer(struct sja1105_private *priv,
struct netlink_ext_ack *extack,
unsigned long cookie, int port,
u64 rate_bytes_per_sec,
- s64 burst)
+ u32 burst)
{
struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
struct sja1105_l2_policing_entry *policing;
@@ -79,9 +79,8 @@ static int sja1105_setup_bcast_policer(struct sja1105_private *priv,
policing[rule->bcast_pol.sharindx].rate = div_u64(rate_bytes_per_sec *
512, 1000000);
- policing[rule->bcast_pol.sharindx].smax = div_u64(rate_bytes_per_sec *
- PSCHED_NS2TICKS(burst),
- PSCHED_TICKS_PER_SEC);
+ policing[rule->bcast_pol.sharindx].smax = burst;
+
/* TODO: support per-flow MTU */
policing[rule->bcast_pol.sharindx].maxlen = VLAN_ETH_FRAME_LEN +
ETH_FCS_LEN;
@@ -103,7 +102,7 @@ static int sja1105_setup_tc_policer(struct sja1105_private *priv,
struct netlink_ext_ack *extack,
unsigned long cookie, int port, int tc,
u64 rate_bytes_per_sec,
- s64 burst)
+ u32 burst)
{
struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
struct sja1105_l2_policing_entry *policing;
@@ -152,9 +151,8 @@ static int sja1105_setup_tc_policer(struct sja1105_private *priv,
policing[rule->tc_pol.sharindx].rate = div_u64(rate_bytes_per_sec *
512, 1000000);
- policing[rule->tc_pol.sharindx].smax = div_u64(rate_bytes_per_sec *
- PSCHED_NS2TICKS(burst),
- PSCHED_TICKS_PER_SEC);
+ policing[rule->tc_pol.sharindx].smax = burst;
+
/* TODO: support per-flow MTU */
policing[rule->tc_pol.sharindx].maxlen = VLAN_ETH_FRAME_LEN +
ETH_FCS_LEN;
@@ -177,7 +175,7 @@ static int sja1105_flower_policer(struct sja1105_private *priv, int port,
unsigned long cookie,
struct sja1105_key *key,
u64 rate_bytes_per_sec,
- s64 burst)
+ u32 burst)
{
switch (key->type) {
case SJA1105_KEY_BCAST:
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 789b288cc78b..c3f6f124e5f0 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -3324,9 +3324,7 @@ static int sja1105_port_policer_add(struct dsa_switch *ds, int port,
*/
policing[port].rate = div_u64(512 * policer->rate_bytes_per_sec,
1000000);
- policing[port].smax = div_u64(policer->rate_bytes_per_sec *
- PSCHED_NS2TICKS(policer->burst),
- PSCHED_TICKS_PER_SEC);
+ policing[port].smax = policer->burst;
return sja1105_static_config_reload(priv, SJA1105_BEST_EFFORT_POLICING);
}
@@ -3393,11 +3391,14 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
.devlink_param_set = sja1105_devlink_param_set,
};
+static const struct of_device_id sja1105_dt_ids[];
+
static int sja1105_check_device_id(struct sja1105_private *priv)
{
const struct sja1105_regs *regs = priv->info->regs;
u8 prod_id[SJA1105_SIZE_DEVICE_ID] = {0};
struct device *dev = &priv->spidev->dev;
+ const struct of_device_id *match;
u32 device_id;
u64 part_no;
int rc;
@@ -3407,12 +3408,6 @@ static int sja1105_check_device_id(struct sja1105_private *priv)
if (rc < 0)
return rc;
- if (device_id != priv->info->device_id) {
- dev_err(dev, "Expected device ID 0x%llx but read 0x%x\n",
- priv->info->device_id, device_id);
- return -ENODEV;
- }
-
rc = sja1105_xfer_buf(priv, SPI_READ, regs->prod_id, prod_id,
SJA1105_SIZE_DEVICE_ID);
if (rc < 0)
@@ -3420,13 +3415,29 @@ static int sja1105_check_device_id(struct sja1105_private *priv)
sja1105_unpack(prod_id, &part_no, 19, 4, SJA1105_SIZE_DEVICE_ID);
- if (part_no != priv->info->part_no) {
- dev_err(dev, "Expected part number 0x%llx but read 0x%llx\n",
- priv->info->part_no, part_no);
- return -ENODEV;
+ for (match = sja1105_dt_ids; match->compatible; match++) {
+ const struct sja1105_info *info = match->data;
+
+ /* Is what's been probed in our match table at all? */
+ if (info->device_id != device_id || info->part_no != part_no)
+ continue;
+
+ /* But is it what's in the device tree? */
+ if (priv->info->device_id != device_id ||
+ priv->info->part_no != part_no) {
+ dev_warn(dev, "Device tree specifies chip %s but found %s, please fix it!\n",
+ priv->info->name, info->name);
+ /* It isn't. No problem, pick that up. */
+ priv->info = info;
+ }
+
+ return 0;
}
- return 0;
+ dev_err(dev, "Unexpected {device ID, part number}: 0x%x 0x%llx\n",
+ device_id, part_no);
+
+ return -ENODEV;
}
static int sja1105_probe(struct spi_device *spi)
diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c
index 177134596458..1b90570b257b 100644
--- a/drivers/net/dsa/sja1105/sja1105_ptp.c
+++ b/drivers/net/dsa/sja1105/sja1105_ptp.c
@@ -24,7 +24,7 @@
* this hardware can do (but may be enough for some setups). Anything of higher
* frequency than 1 Hz will be lost, since there is no timestamp FIFO.
*/
-#define SJA1105_EXTTS_INTERVAL (HZ / 4)
+#define SJA1105_EXTTS_INTERVAL (HZ / 6)
/* This range is actually +/- SJA1105_MAX_ADJ_PPB
* divided by 1000 (ppb -> ppm) and with a 16-bit
@@ -51,8 +51,8 @@ enum sja1105_ptp_clk_mode {
PTP_SET_MODE = 0,
};
-#define extts_to_data(d) \
- container_of((d), struct sja1105_ptp_data, extts_work)
+#define extts_to_data(t) \
+ container_of((t), struct sja1105_ptp_data, extts_timer)
#define ptp_caps_to_data(d) \
container_of((d), struct sja1105_ptp_data, caps)
#define ptp_data_to_sja1105(d) \
@@ -350,6 +350,30 @@ static int sja1105_ptpclkval_write(struct sja1105_private *priv, u64 ticks,
ptp_sts);
}
+static void sja1105_extts_poll(struct sja1105_private *priv)
+{
+ struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
+ const struct sja1105_regs *regs = priv->info->regs;
+ struct ptp_clock_event event;
+ u64 ptpsyncts = 0;
+ int rc;
+
+ rc = sja1105_xfer_u64(priv, SPI_READ, regs->ptpsyncts, &ptpsyncts,
+ NULL);
+ if (rc < 0)
+ dev_err_ratelimited(priv->ds->dev,
+ "Failed to read PTPSYNCTS: %d\n", rc);
+
+ if (ptpsyncts && ptp_data->ptpsyncts != ptpsyncts) {
+ event.index = 0;
+ event.type = PTP_CLOCK_EXTTS;
+ event.timestamp = ns_to_ktime(sja1105_ticks_to_ns(ptpsyncts));
+ ptp_clock_event(ptp_data->clock, &event);
+
+ ptp_data->ptpsyncts = ptpsyncts;
+ }
+}
+
static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp)
{
struct sja1105_ptp_data *ptp_data = ptp_caps_to_data(ptp);
@@ -380,6 +404,9 @@ static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp)
netif_rx_ni(skb);
}
+ if (ptp_data->extts_enabled)
+ sja1105_extts_poll(priv);
+
mutex_unlock(&ptp_data->lock);
/* Don't restart */
@@ -595,36 +622,21 @@ static int sja1105_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
return rc;
}
-static void sja1105_ptp_extts_work(struct work_struct *work)
+static void sja1105_ptp_extts_setup_timer(struct sja1105_ptp_data *ptp_data)
{
- struct delayed_work *dw = to_delayed_work(work);
- struct sja1105_ptp_data *ptp_data = extts_to_data(dw);
- struct sja1105_private *priv = ptp_data_to_sja1105(ptp_data);
- const struct sja1105_regs *regs = priv->info->regs;
- struct ptp_clock_event event;
- u64 ptpsyncts = 0;
- int rc;
-
- mutex_lock(&ptp_data->lock);
-
- rc = sja1105_xfer_u64(priv, SPI_READ, regs->ptpsyncts, &ptpsyncts,
- NULL);
- if (rc < 0)
- dev_err_ratelimited(priv->ds->dev,
- "Failed to read PTPSYNCTS: %d\n", rc);
+ unsigned long expires = ((jiffies / SJA1105_EXTTS_INTERVAL) + 1) *
+ SJA1105_EXTTS_INTERVAL;
- if (ptpsyncts && ptp_data->ptpsyncts != ptpsyncts) {
- event.index = 0;
- event.type = PTP_CLOCK_EXTTS;
- event.timestamp = ns_to_ktime(sja1105_ticks_to_ns(ptpsyncts));
- ptp_clock_event(ptp_data->clock, &event);
+ mod_timer(&ptp_data->extts_timer, expires);
+}
- ptp_data->ptpsyncts = ptpsyncts;
- }
+static void sja1105_ptp_extts_timer(struct timer_list *t)
+{
+ struct sja1105_ptp_data *ptp_data = extts_to_data(t);
- mutex_unlock(&ptp_data->lock);
+ ptp_schedule_worker(ptp_data->clock, 0);
- schedule_delayed_work(&ptp_data->extts_work, SJA1105_EXTTS_INTERVAL);
+ sja1105_ptp_extts_setup_timer(ptp_data);
}
static int sja1105_change_ptp_clk_pin_func(struct sja1105_private *priv,
@@ -771,11 +783,12 @@ static int sja1105_extts_enable(struct sja1105_private *priv,
if (rc)
return rc;
+ priv->ptp_data.extts_enabled = on;
+
if (on)
- schedule_delayed_work(&priv->ptp_data.extts_work,
- SJA1105_EXTTS_INTERVAL);
+ sja1105_ptp_extts_setup_timer(&priv->ptp_data);
else
- cancel_delayed_work_sync(&priv->ptp_data.extts_work);
+ del_timer_sync(&priv->ptp_data.extts_timer);
return 0;
}
@@ -858,7 +871,7 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds)
ptp_data->cmd.corrclk4ts = true;
ptp_data->cmd.ptpclkadd = PTP_SET_MODE;
- INIT_DELAYED_WORK(&ptp_data->extts_work, sja1105_ptp_extts_work);
+ timer_setup(&ptp_data->extts_timer, sja1105_ptp_extts_timer, 0);
return sja1105_ptp_reset(ds);
}
@@ -871,7 +884,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
if (IS_ERR_OR_NULL(ptp_data->clock))
return;
- cancel_delayed_work_sync(&ptp_data->extts_work);
+ del_timer_sync(&ptp_data->extts_timer);
ptp_cancel_worker_sync(ptp_data->clock);
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
ptp_clock_unregister(ptp_data->clock);
diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.h b/drivers/net/dsa/sja1105/sja1105_ptp.h
index 6408d1158f2d..3daa33e98e77 100644
--- a/drivers/net/dsa/sja1105/sja1105_ptp.h
+++ b/drivers/net/dsa/sja1105/sja1105_ptp.h
@@ -4,6 +4,8 @@
#ifndef _SJA1105_PTP_H
#define _SJA1105_PTP_H
+#include <linux/timer.h>
+
#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
/* Timestamps are in units of 8 ns clock ticks (equivalent to
@@ -72,13 +74,14 @@ struct sja1105_ptp_cmd {
};
struct sja1105_ptp_data {
- struct delayed_work extts_work;
+ struct timer_list extts_timer;
struct sk_buff_head skb_rxtstamp_queue;
struct ptp_clock_info caps;
struct ptp_clock *clock;
struct sja1105_ptp_cmd cmd;
/* Serializes all operations on the PTP hardware clock */
struct mutex lock;
+ bool extts_enabled;
u64 ptpsyncts;
};
diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c
index bb52b9c841b2..704dcf1d1c01 100644
--- a/drivers/net/dsa/sja1105/sja1105_spi.c
+++ b/drivers/net/dsa/sja1105/sja1105_spi.c
@@ -507,7 +507,7 @@ static struct sja1105_regs sja1105pqrs_regs = {
.ptpsyncts = 0x1F,
};
-struct sja1105_info sja1105e_info = {
+const struct sja1105_info sja1105e_info = {
.device_id = SJA1105E_DEVICE_ID,
.part_no = SJA1105ET_PART_NO,
.static_ops = sja1105e_table_ops,
@@ -523,7 +523,8 @@ struct sja1105_info sja1105e_info = {
.regs = &sja1105et_regs,
.name = "SJA1105E",
};
-struct sja1105_info sja1105t_info = {
+
+const struct sja1105_info sja1105t_info = {
.device_id = SJA1105T_DEVICE_ID,
.part_no = SJA1105ET_PART_NO,
.static_ops = sja1105t_table_ops,
@@ -539,7 +540,8 @@ struct sja1105_info sja1105t_info = {
.regs = &sja1105et_regs,
.name = "SJA1105T",
};
-struct sja1105_info sja1105p_info = {
+
+const struct sja1105_info sja1105p_info = {
.device_id = SJA1105PR_DEVICE_ID,
.part_no = SJA1105P_PART_NO,
.static_ops = sja1105p_table_ops,
@@ -556,7 +558,8 @@ struct sja1105_info sja1105p_info = {
.regs = &sja1105pqrs_regs,
.name = "SJA1105P",
};
-struct sja1105_info sja1105q_info = {
+
+const struct sja1105_info sja1105q_info = {
.device_id = SJA1105QS_DEVICE_ID,
.part_no = SJA1105Q_PART_NO,
.static_ops = sja1105q_table_ops,
@@ -573,7 +576,8 @@ struct sja1105_info sja1105q_info = {
.regs = &sja1105pqrs_regs,
.name = "SJA1105Q",
};
-struct sja1105_info sja1105r_info = {
+
+const struct sja1105_info sja1105r_info = {
.device_id = SJA1105PR_DEVICE_ID,
.part_no = SJA1105R_PART_NO,
.static_ops = sja1105r_table_ops,
@@ -590,7 +594,8 @@ struct sja1105_info sja1105r_info = {
.regs = &sja1105pqrs_regs,
.name = "SJA1105R",
};
-struct sja1105_info sja1105s_info = {
+
+const struct sja1105_info sja1105s_info = {
.device_id = SJA1105QS_DEVICE_ID,
.part_no = SJA1105S_PART_NO,
.static_ops = sja1105s_table_ops,
diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c
index ff3fe471efc2..139b7b4fbd0d 100644
--- a/drivers/net/dsa/sja1105/sja1105_static_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_static_config.c
@@ -838,12 +838,7 @@ sja1105_static_config_get_length(const struct sja1105_static_config *config)
/* Compatibility matrices */
/* SJA1105E: First generation, no TTEthernet */
-struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX] = {
- [BLK_IDX_SCHEDULE] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {0},
- [BLK_IDX_VL_LOOKUP] = {0},
- [BLK_IDX_VL_POLICING] = {0},
- [BLK_IDX_VL_FORWARDING] = {0},
+const struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX] = {
[BLK_IDX_L2_LOOKUP] = {
.packing = sja1105et_l2_lookup_entry_packing,
.unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
@@ -874,9 +869,6 @@ struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX] = {
.packed_entry_size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY,
.max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
},
- [BLK_IDX_SCHEDULE_PARAMS] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {0},
- [BLK_IDX_VL_FORWARDING_PARAMS] = {0},
[BLK_IDX_L2_LOOKUP_PARAMS] = {
.packing = sja1105et_l2_lookup_params_entry_packing,
.unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
@@ -916,7 +908,7 @@ struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX] = {
};
/* SJA1105T: First generation, TTEthernet */
-struct sja1105_table_ops sja1105t_table_ops[BLK_IDX_MAX] = {
+const struct sja1105_table_ops sja1105t_table_ops[BLK_IDX_MAX] = {
[BLK_IDX_SCHEDULE] = {
.packing = sja1105_schedule_entry_packing,
.unpacked_entry_size = sizeof(struct sja1105_schedule_entry),
@@ -1034,12 +1026,7 @@ struct sja1105_table_ops sja1105t_table_ops[BLK_IDX_MAX] = {
};
/* SJA1105P: Second generation, no TTEthernet, no SGMII */
-struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX] = {
- [BLK_IDX_SCHEDULE] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {0},
- [BLK_IDX_VL_LOOKUP] = {0},
- [BLK_IDX_VL_POLICING] = {0},
- [BLK_IDX_VL_FORWARDING] = {0},
+const struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX] = {
[BLK_IDX_L2_LOOKUP] = {
.packing = sja1105pqrs_l2_lookup_entry_packing,
.unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
@@ -1070,9 +1057,6 @@ struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX] = {
.packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
.max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
},
- [BLK_IDX_SCHEDULE_PARAMS] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {0},
- [BLK_IDX_VL_FORWARDING_PARAMS] = {0},
[BLK_IDX_L2_LOOKUP_PARAMS] = {
.packing = sja1105pqrs_l2_lookup_params_entry_packing,
.unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
@@ -1112,7 +1096,7 @@ struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX] = {
};
/* SJA1105Q: Second generation, TTEthernet, no SGMII */
-struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX] = {
+const struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX] = {
[BLK_IDX_SCHEDULE] = {
.packing = sja1105_schedule_entry_packing,
.unpacked_entry_size = sizeof(struct sja1105_schedule_entry),
@@ -1230,12 +1214,7 @@ struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX] = {
};
/* SJA1105R: Second generation, no TTEthernet, SGMII */
-struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX] = {
- [BLK_IDX_SCHEDULE] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {0},
- [BLK_IDX_VL_LOOKUP] = {0},
- [BLK_IDX_VL_POLICING] = {0},
- [BLK_IDX_VL_FORWARDING] = {0},
+const struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX] = {
[BLK_IDX_L2_LOOKUP] = {
.packing = sja1105pqrs_l2_lookup_entry_packing,
.unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
@@ -1266,9 +1245,6 @@ struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX] = {
.packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
.max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
},
- [BLK_IDX_SCHEDULE_PARAMS] = {0},
- [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {0},
- [BLK_IDX_VL_FORWARDING_PARAMS] = {0},
[BLK_IDX_L2_LOOKUP_PARAMS] = {
.packing = sja1105pqrs_l2_lookup_params_entry_packing,
.unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
@@ -1308,7 +1284,7 @@ struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX] = {
};
/* SJA1105S: Second generation, TTEthernet, SGMII */
-struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX] = {
+const struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX] = {
[BLK_IDX_SCHEDULE] = {
.packing = sja1105_schedule_entry_packing,
.unpacked_entry_size = sizeof(struct sja1105_schedule_entry),
diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.h b/drivers/net/dsa/sja1105/sja1105_static_config.h
index ee0f10062763..bc7606899289 100644
--- a/drivers/net/dsa/sja1105/sja1105_static_config.h
+++ b/drivers/net/dsa/sja1105/sja1105_static_config.h
@@ -381,12 +381,12 @@ struct sja1105_static_config {
struct sja1105_table tables[BLK_IDX_MAX];
};
-extern struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX];
-extern struct sja1105_table_ops sja1105t_table_ops[BLK_IDX_MAX];
-extern struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX];
-extern struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX];
-extern struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX];
-extern struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX];
+extern const struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX];
+extern const struct sja1105_table_ops sja1105t_table_ops[BLK_IDX_MAX];
+extern const struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX];
+extern const struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX];
+extern const struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX];
+extern const struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX];
size_t sja1105_table_header_packing(void *buf, void *hdr, enum packing_op op);
void
diff --git a/drivers/net/dsa/sja1105/sja1105_tas.c b/drivers/net/dsa/sja1105/sja1105_tas.c
index 3aa1a8b5f766..31d8acff1f01 100644
--- a/drivers/net/dsa/sja1105/sja1105_tas.c
+++ b/drivers/net/dsa/sja1105/sja1105_tas.c
@@ -475,8 +475,7 @@ bool sja1105_gating_check_conflicts(struct sja1105_private *priv, int port,
if (list_empty(&gating_cfg->entries))
return false;
- dummy = kzalloc(sizeof(struct tc_taprio_sched_entry) * num_entries +
- sizeof(struct tc_taprio_qopt_offload), GFP_KERNEL);
+ dummy = kzalloc(struct_size(dummy, entries, num_entries), GFP_KERNEL);
if (!dummy) {
NL_SET_ERR_MSG_MOD(extack, "Failed to allocate memory");
return true;
diff --git a/drivers/net/dsa/sja1105/sja1105_vl.c b/drivers/net/dsa/sja1105/sja1105_vl.c
index af3565160db6..ffc4042b4502 100644
--- a/drivers/net/dsa/sja1105/sja1105_vl.c
+++ b/drivers/net/dsa/sja1105/sja1105_vl.c
@@ -778,7 +778,7 @@ int sja1105_vl_stats(struct sja1105_private *priv, int port,
pkts = timingerr + unreleased + lengtherr;
- flow_stats_update(stats, 0, pkts - rule->vl.stats.pkts,
+ flow_stats_update(stats, 0, pkts - rule->vl.stats.pkts, 0,
jiffies - rule->vl.stats.lastused,
FLOW_ACTION_HW_STATS_IMMEDIATE);
diff --git a/drivers/net/dsa/vitesse-vsc73xx-platform.c b/drivers/net/dsa/vitesse-vsc73xx-platform.c
index 5e54a5726aa4..2a57f337b2a2 100644
--- a/drivers/net/dsa/vitesse-vsc73xx-platform.c
+++ b/drivers/net/dsa/vitesse-vsc73xx-platform.c
@@ -28,7 +28,7 @@
#define VSC73XX_CMD_PLATFORM_SUBBLOCK_MASK 0xf
#define VSC73XX_CMD_PLATFORM_REGISTER_SHIFT 2
-/**
+/*
* struct vsc73xx_platform - VSC73xx Platform state container
*/
struct vsc73xx_platform {
diff --git a/drivers/net/dsa/vitesse-vsc73xx-spi.c b/drivers/net/dsa/vitesse-vsc73xx-spi.c
index e73c8fcddc9f..81eca4a5781d 100644
--- a/drivers/net/dsa/vitesse-vsc73xx-spi.c
+++ b/drivers/net/dsa/vitesse-vsc73xx-spi.c
@@ -26,7 +26,7 @@
#define VSC73XX_CMD_SPI_BLOCK_MASK 0x7
#define VSC73XX_CMD_SPI_SUBBLOCK_MASK 0xf
-/**
+/*
* struct vsc73xx_spi - VSC73xx SPI state container
*/
struct vsc73xx_spi {
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 5984b7033999..741c67e546d4 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -1149,7 +1149,7 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
print_info = (vortex_debug > 1);
if (print_info)
- pr_info("See Documentation/networking/device_drivers/3com/vortex.rst\n");
+ pr_info("See Documentation/networking/device_drivers/ethernet/3com/vortex.rst\n");
pr_info("%s: 3Com %s %s at %p.\n",
print_name,
@@ -1954,7 +1954,7 @@ vortex_error(struct net_device *dev, int status)
dev->name, tx_status);
if (tx_status == 0x82) {
pr_err("Probably a duplex mismatch. See "
- "Documentation/networking/device_drivers/3com/vortex.rst\n");
+ "Documentation/networking/device_drivers/ethernet/3com/vortex.rst\n");
}
dump_tx_ring(dev);
}
diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig
index 074b0974769c..a52a3740f0c9 100644
--- a/drivers/net/ethernet/3com/Kconfig
+++ b/drivers/net/ethernet/3com/Kconfig
@@ -76,8 +76,8 @@ config VORTEX
"Hurricane" (3c555/3cSOHO) PCI
If you have such a card, say Y here. More specific information is in
- <file:Documentation/networking/device_drivers/3com/vortex.rst> and
- in the comments at the beginning of
+ <file:Documentation/networking/device_drivers/ethernet/3com/vortex.rst>
+ and in the comments at the beginning of
<file:drivers/net/ethernet/3com/3c59x.c>.
To compile this support as a module, choose M here.
diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c
index 5ed33c2c4742..d3b30bacc94e 100644
--- a/drivers/net/ethernet/3com/typhoon.c
+++ b/drivers/net/ethernet/3com/typhoon.c
@@ -1801,9 +1801,8 @@ typhoon_free_rx_rings(struct typhoon *tp)
}
static int
-typhoon_sleep(struct typhoon *tp, pci_power_t state, __le16 events)
+typhoon_sleep_early(struct typhoon *tp, __le16 events)
{
- struct pci_dev *pdev = tp->pdev;
void __iomem *ioaddr = tp->ioaddr;
struct cmd_desc xp_cmd;
int err;
@@ -1832,20 +1831,29 @@ typhoon_sleep(struct typhoon *tp, pci_power_t state, __le16 events)
*/
netif_carrier_off(tp->dev);
+ return 0;
+}
+
+static int
+typhoon_sleep(struct typhoon *tp, pci_power_t state, __le16 events)
+{
+ int err;
+
+ err = typhoon_sleep_early(tp, events);
+
+ if (err)
+ return err;
+
pci_enable_wake(tp->pdev, state, 1);
- pci_disable_device(pdev);
- return pci_set_power_state(pdev, state);
+ pci_disable_device(tp->pdev);
+ return pci_set_power_state(tp->pdev, state);
}
static int
typhoon_wakeup(struct typhoon *tp, int wait_type)
{
- struct pci_dev *pdev = tp->pdev;
void __iomem *ioaddr = tp->ioaddr;
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
/* Post 2.x.x versions of the Sleep Image require a reset before
* we can download the Runtime Image. But let's not make users of
* the old firmware pay for the reset.
@@ -2049,6 +2057,9 @@ typhoon_open(struct net_device *dev)
if (err)
goto out;
+ pci_set_power_state(tp->pdev, PCI_D0);
+ pci_restore_state(tp->pdev);
+
err = typhoon_wakeup(tp, WaitSleep);
if (err < 0) {
netdev_err(dev, "unable to wakeup device\n");
@@ -2114,11 +2125,10 @@ typhoon_close(struct net_device *dev)
return 0;
}
-#ifdef CONFIG_PM
-static int
-typhoon_resume(struct pci_dev *pdev)
+static int __maybe_unused
+typhoon_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct typhoon *tp = netdev_priv(dev);
/* If we're down, resume when we are upped.
@@ -2144,9 +2154,10 @@ reset:
return -EBUSY;
}
-static int
-typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused
+typhoon_suspend(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct net_device *dev = pci_get_drvdata(pdev);
struct typhoon *tp = netdev_priv(dev);
struct cmd_desc xp_cmd;
@@ -2190,18 +2201,19 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
goto need_resume;
}
- if (typhoon_sleep(tp, pci_choose_state(pdev, state), tp->wol_events) < 0) {
+ if (typhoon_sleep_early(tp, tp->wol_events) < 0) {
netdev_err(dev, "unable to put card to sleep\n");
goto need_resume;
}
+ device_wakeup_enable(dev_d);
+
return 0;
need_resume:
- typhoon_resume(pdev);
+ typhoon_resume(dev_d);
return -EBUSY;
}
-#endif
static int
typhoon_test_mmio(struct pci_dev *pdev)
@@ -2533,15 +2545,14 @@ typhoon_remove_one(struct pci_dev *pdev)
free_netdev(dev);
}
+static SIMPLE_DEV_PM_OPS(typhoon_pm_ops, typhoon_suspend, typhoon_resume);
+
static struct pci_driver typhoon_driver = {
.name = KBUILD_MODNAME,
.id_table = typhoon_pci_tbl,
.probe = typhoon_init_one,
.remove = typhoon_remove_one,
-#ifdef CONFIG_PM
- .suspend = typhoon_suspend,
- .resume = typhoon_resume,
-#endif
+ .driver.pm = &typhoon_pm_ops,
};
static int __init
diff --git a/drivers/net/ethernet/8390/8390.h b/drivers/net/ethernet/8390/8390.h
index 529c728f334a..e52264465998 100644
--- a/drivers/net/ethernet/8390/8390.h
+++ b/drivers/net/ethernet/8390/8390.h
@@ -1,8 +1,10 @@
/* Generic NS8390 register definitions. */
+
/* This file is part of Donald Becker's 8390 drivers, and is distributed
- under the same license. Auto-loading of 8390.o only in v2.2 - Paul G.
- Some of these names and comments originated from the Crynwr
- packet drivers, which are distributed under the GPL. */
+ * under the same license. Auto-loading of 8390.o only in v2.2 - Paul G.
+ * Some of these names and comments originated from the Crynwr
+ * packet drivers, which are distributed under the GPL.
+ */
#ifndef _8390_h
#define _8390_h
@@ -16,9 +18,9 @@
/* The 8390 specific per-packet-header format. */
struct e8390_pkt_hdr {
- unsigned char status; /* status */
- unsigned char next; /* pointer to next packet. */
- unsigned short count; /* header + packet length in bytes */
+ unsigned char status; /* status */
+ unsigned char next; /* pointer to next packet. */
+ unsigned short count; /* header + packet length in bytes */
};
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -66,18 +68,24 @@ static inline struct net_device *alloc_eip_netdev(void)
/* You have one of these per-board */
struct ei_device {
const char *name;
- void (*reset_8390)(struct net_device *);
- void (*get_8390_hdr)(struct net_device *, struct e8390_pkt_hdr *, int);
- void (*block_output)(struct net_device *, int, const unsigned char *, int);
- void (*block_input)(struct net_device *, int, struct sk_buff *, int);
+ void (*reset_8390)(struct net_device *dev);
+ void (*get_8390_hdr)(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page);
+ void (*block_output)(struct net_device *dev, int count,
+ const unsigned char *buf, int start_page);
+ void (*block_input)(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset);
unsigned long rmem_start;
unsigned long rmem_end;
void __iomem *mem;
unsigned char mcfilter[8];
unsigned open:1;
- unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */
- unsigned bigendian:1; /* 16-bit big endian mode. Do NOT */
- /* set this on random 8390 clones! */
+ unsigned word16:1; /* We have the 16-bit (vs 8-bit)
+ * version of the card.
+ */
+ unsigned bigendian:1; /* 16-bit big endian mode. Do NOT
+ * set this on random 8390 clones!
+ */
unsigned txing:1; /* Transmit Active */
unsigned irqlock:1; /* 8390's intrs disabled when '1'. */
unsigned dmaing:1; /* Remote DMA Active */
@@ -115,12 +123,16 @@ struct ei_device {
#define E8390_RXCONFIG (ei_status.rxcr_base | 0x04)
#define E8390_RXOFF (ei_status.rxcr_base | 0x20)
#else
-#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
-#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
+/* EN0_RXCR: broadcasts, no multicast,errors */
+#define E8390_RXCONFIG 0x4
+/* EN0_RXCR: Accept no packets */
+#define E8390_RXOFF 0x20
#endif
-#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */
-#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
+/* EN0_TXCR: Normal transmit mode */
+#define E8390_TXCONFIG 0x00
+/* EN0_TXCR: Transmitter off */
+#define E8390_TXOFF 0x02
/* Register accessed at EN_CMD, the 8390 base addr. */
@@ -134,17 +146,16 @@ struct ei_device {
#define E8390_PAGE1 0x40 /* using the two high-order bits */
#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
-/*
- * Only generate indirect loads given a machine that needs them.
- * - removed AMIGA_PCMCIA from this list, handled as ISA io now
- * - the _p for generates no delay by default 8390p.c overrides this.
+/* Only generate indirect loads given a machine that needs them.
+ * - removed AMIGA_PCMCIA from this list, handled as ISA io now
+ * - the _p for generates no delay by default 8390p.c overrides this.
*/
#ifndef ei_inb
#define ei_inb(_p) inb(_p)
-#define ei_outb(_v,_p) outb(_v,_p)
+#define ei_outb(_v, _p) outb(_v, _p)
#define ei_inb_p(_p) inb(_p)
-#define ei_outb_p(_v,_p) outb(_v,_p)
+#define ei_outb_p(_v, _p) outb(_v, _p)
#endif
#ifndef EI_SHIFT
@@ -153,9 +164,9 @@ struct ei_device {
#define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */
/* Page 0 register offsets. */
-#define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */
+#define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */
#define EN0_STARTPG EI_SHIFT(0x01) /* Starting page of ring bfr WR */
-#define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */
+#define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */
#define EN0_STOPPG EI_SHIFT(0x02) /* Ending page +1 of ring bfr WR */
#define EN0_BOUNDARY EI_SHIFT(0x03) /* Boundary page of ring bfr RD WR */
#define EN0_TSR EI_SHIFT(0x04) /* Transmit status reg RD */
diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c
index 77d78b4c59c4..bc6edb3f1af3 100644
--- a/drivers/net/ethernet/8390/ne2k-pci.c
+++ b/drivers/net/ethernet/8390/ne2k-pci.c
@@ -62,7 +62,10 @@ static int options[MAX_UNITS];
#include "8390.h"
-static u32 ne2k_msg_enable;
+static int ne2k_msg_enable;
+
+static const int default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
+ NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR);
#if defined(__powerpc__)
#define inl_le(addr) le32_to_cpu(inl(addr))
@@ -74,7 +77,7 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
MODULE_LICENSE("GPL");
-module_param_named(msg_enable, ne2k_msg_enable, uint, 0444);
+module_param_named(msg_enable, ne2k_msg_enable, int, 0444);
module_param_array(options, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
@@ -282,7 +285,7 @@ static int ne2k_pci_init_one(struct pci_dev *pdev,
}
dev->netdev_ops = &ne2k_netdev_ops;
ei_local = netdev_priv(dev);
- ei_local->msg_enable = ne2k_msg_enable;
+ ei_local->msg_enable = netif_msg_init(ne2k_msg_enable, default_msg_level);
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -699,30 +702,18 @@ static void ne2k_pci_remove_one(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-#ifdef CONFIG_PM
-static int ne2k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused ne2k_pci_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
netif_device_detach(dev);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
-static int ne2k_pci_resume(struct pci_dev *pdev)
+static int __maybe_unused ne2k_pci_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
- int rc;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
- rc = pci_enable_device(pdev);
- if (rc)
- return rc;
+ struct net_device *dev = dev_get_drvdata(dev_d);
NS8390_init(dev, 1);
netif_device_attach(dev);
@@ -730,19 +721,14 @@ static int ne2k_pci_resume(struct pci_dev *pdev)
return 0;
}
-#endif /* CONFIG_PM */
-
+static SIMPLE_DEV_PM_OPS(ne2k_pci_pm_ops, ne2k_pci_suspend, ne2k_pci_resume);
static struct pci_driver ne2k_driver = {
.name = DRV_NAME,
.probe = ne2k_pci_init_one,
.remove = ne2k_pci_remove_one,
.id_table = ne2k_pci_tbl,
-#ifdef CONFIG_PM
- .suspend = ne2k_pci_suspend,
- .resume = ne2k_pci_resume,
-#endif
-
+ .driver.pm = &ne2k_pci_pm_ops,
};
diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
index a64191fc2af9..ba0055bb1614 100644
--- a/drivers/net/ethernet/adaptec/starfire.c
+++ b/drivers/net/ethernet/adaptec/starfire.c
@@ -1984,28 +1984,21 @@ static int netdev_close(struct net_device *dev)
return 0;
}
-#ifdef CONFIG_PM
-static int starfire_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused starfire_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
if (netif_running(dev)) {
netif_device_detach(dev);
netdev_close(dev);
}
- pci_save_state(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev,state));
-
return 0;
}
-static int starfire_resume(struct pci_dev *pdev)
+static int __maybe_unused starfire_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
if (netif_running(dev)) {
netdev_open(dev);
@@ -2014,8 +2007,6 @@ static int starfire_resume(struct pci_dev *pdev)
return 0;
}
-#endif /* CONFIG_PM */
-
static void starfire_remove_one(struct pci_dev *pdev)
{
@@ -2040,15 +2031,13 @@ static void starfire_remove_one(struct pci_dev *pdev)
free_netdev(dev); /* Will also free np!! */
}
+static SIMPLE_DEV_PM_OPS(starfire_pm_ops, starfire_suspend, starfire_resume);
static struct pci_driver starfire_driver = {
.name = DRV_NAME,
.probe = starfire_init_one,
.remove = starfire_remove_one,
-#ifdef CONFIG_PM
- .suspend = starfire_suspend,
- .resume = starfire_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &starfire_pm_ops,
.id_table = starfire_pci_tbl,
};
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
index bf546118dbc6..9c5891bbfe61 100644
--- a/drivers/net/ethernet/aeroflex/greth.c
+++ b/drivers/net/ethernet/aeroflex/greth.c
@@ -8,7 +8,7 @@
* available in the GRLIB VHDL IP core library.
*
* Full documentation of both cores can be found here:
- * http://www.gaisler.com/products/grlib/grip.pdf
+ * https://www.gaisler.com/products/grlib/grip.pdf
*
* The Gigabit version supports scatter/gather DMA, any alignment of
* buffers and checksum offloading.
diff --git a/drivers/net/ethernet/agere/et131x.c b/drivers/net/ethernet/agere/et131x.c
index 865892c1f23f..41f8821f792d 100644
--- a/drivers/net/ethernet/agere/et131x.c
+++ b/drivers/net/ethernet/agere/et131x.c
@@ -950,7 +950,6 @@ static void et1310_setup_device_for_multicast(struct et131x_adapter *adapter)
u32 hash2 = 0;
u32 hash3 = 0;
u32 hash4 = 0;
- u32 pm_csr;
/* If ET131X_PACKET_TYPE_MULTICAST is specified, then we provision
* the multi-cast LIST. If it is NOT specified, (and "ALL" is not
@@ -984,7 +983,6 @@ static void et1310_setup_device_for_multicast(struct et131x_adapter *adapter)
}
/* Write out the new hash to the device */
- pm_csr = readl(&adapter->regs->global.pm_csr);
if (!et1310_in_phy_coma(adapter)) {
writel(hash1, &rxmac->multi_hash1);
writel(hash2, &rxmac->multi_hash2);
@@ -999,7 +997,6 @@ static void et1310_setup_device_for_unicast(struct et131x_adapter *adapter)
u32 uni_pf1;
u32 uni_pf2;
u32 uni_pf3;
- u32 pm_csr;
/* Set up unicast packet filter reg 3 to be the first two octets of
* the MAC address for both address
@@ -1025,7 +1022,6 @@ static void et1310_setup_device_for_unicast(struct et131x_adapter *adapter)
(adapter->addr[4] << ET_RX_UNI_PF_ADDR1_5_SHIFT) |
adapter->addr[5];
- pm_csr = readl(&adapter->regs->global.pm_csr);
if (!et1310_in_phy_coma(adapter)) {
writel(uni_pf1, &rxmac->uni_pf_addr1);
writel(uni_pf2, &rxmac->uni_pf_addr2);
@@ -3443,12 +3439,9 @@ static irqreturn_t et131x_isr(int irq, void *dev_id)
* send a pause packet, otherwise just exit
*/
if (adapter->flow == FLOW_TXONLY || adapter->flow == FLOW_BOTH) {
- u32 pm_csr;
-
/* Tell the device to send a pause packet via the back
* pressure register (bp req and bp xon/xoff)
*/
- pm_csr = readl(&iomem->global.pm_csr);
if (!et1310_in_phy_coma(adapter))
writel(3, &iomem->txmac.bp_ctrl);
}
diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c
index 5d192d551623..ac86fcae1582 100644
--- a/drivers/net/ethernet/alteon/acenic.c
+++ b/drivers/net/ethernet/alteon/acenic.c
@@ -642,9 +642,8 @@ static void acenic_remove_one(struct pci_dev *pdev)
ringp = &ap->skb->rx_std_skbuff[i];
mapping = dma_unmap_addr(ringp, mapping);
- pci_unmap_page(ap->pdev, mapping,
- ACE_STD_BUFSIZE,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_page(&ap->pdev->dev, mapping,
+ ACE_STD_BUFSIZE, DMA_FROM_DEVICE);
ap->rx_std_ring[i].size = 0;
ap->skb->rx_std_skbuff[i].skb = NULL;
@@ -662,9 +661,9 @@ static void acenic_remove_one(struct pci_dev *pdev)
ringp = &ap->skb->rx_mini_skbuff[i];
mapping = dma_unmap_addr(ringp,mapping);
- pci_unmap_page(ap->pdev, mapping,
+ dma_unmap_page(&ap->pdev->dev, mapping,
ACE_MINI_BUFSIZE,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
ap->rx_mini_ring[i].size = 0;
ap->skb->rx_mini_skbuff[i].skb = NULL;
@@ -681,9 +680,8 @@ static void acenic_remove_one(struct pci_dev *pdev)
ringp = &ap->skb->rx_jumbo_skbuff[i];
mapping = dma_unmap_addr(ringp, mapping);
- pci_unmap_page(ap->pdev, mapping,
- ACE_JUMBO_BUFSIZE,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_page(&ap->pdev->dev, mapping,
+ ACE_JUMBO_BUFSIZE, DMA_FROM_DEVICE);
ap->rx_jumbo_ring[i].size = 0;
ap->skb->rx_jumbo_skbuff[i].skb = NULL;
@@ -713,8 +711,8 @@ static void ace_free_descriptors(struct net_device *dev)
RX_JUMBO_RING_ENTRIES +
RX_MINI_RING_ENTRIES +
RX_RETURN_RING_ENTRIES));
- pci_free_consistent(ap->pdev, size, ap->rx_std_ring,
- ap->rx_ring_base_dma);
+ dma_free_coherent(&ap->pdev->dev, size, ap->rx_std_ring,
+ ap->rx_ring_base_dma);
ap->rx_std_ring = NULL;
ap->rx_jumbo_ring = NULL;
ap->rx_mini_ring = NULL;
@@ -722,31 +720,30 @@ static void ace_free_descriptors(struct net_device *dev)
}
if (ap->evt_ring != NULL) {
size = (sizeof(struct event) * EVT_RING_ENTRIES);
- pci_free_consistent(ap->pdev, size, ap->evt_ring,
- ap->evt_ring_dma);
+ dma_free_coherent(&ap->pdev->dev, size, ap->evt_ring,
+ ap->evt_ring_dma);
ap->evt_ring = NULL;
}
if (ap->tx_ring != NULL && !ACE_IS_TIGON_I(ap)) {
size = (sizeof(struct tx_desc) * MAX_TX_RING_ENTRIES);
- pci_free_consistent(ap->pdev, size, ap->tx_ring,
- ap->tx_ring_dma);
+ dma_free_coherent(&ap->pdev->dev, size, ap->tx_ring,
+ ap->tx_ring_dma);
}
ap->tx_ring = NULL;
if (ap->evt_prd != NULL) {
- pci_free_consistent(ap->pdev, sizeof(u32),
- (void *)ap->evt_prd, ap->evt_prd_dma);
+ dma_free_coherent(&ap->pdev->dev, sizeof(u32),
+ (void *)ap->evt_prd, ap->evt_prd_dma);
ap->evt_prd = NULL;
}
if (ap->rx_ret_prd != NULL) {
- pci_free_consistent(ap->pdev, sizeof(u32),
- (void *)ap->rx_ret_prd,
- ap->rx_ret_prd_dma);
+ dma_free_coherent(&ap->pdev->dev, sizeof(u32),
+ (void *)ap->rx_ret_prd, ap->rx_ret_prd_dma);
ap->rx_ret_prd = NULL;
}
if (ap->tx_csm != NULL) {
- pci_free_consistent(ap->pdev, sizeof(u32),
- (void *)ap->tx_csm, ap->tx_csm_dma);
+ dma_free_coherent(&ap->pdev->dev, sizeof(u32),
+ (void *)ap->tx_csm, ap->tx_csm_dma);
ap->tx_csm = NULL;
}
}
@@ -763,8 +760,8 @@ static int ace_allocate_descriptors(struct net_device *dev)
RX_MINI_RING_ENTRIES +
RX_RETURN_RING_ENTRIES));
- ap->rx_std_ring = pci_alloc_consistent(ap->pdev, size,
- &ap->rx_ring_base_dma);
+ ap->rx_std_ring = dma_alloc_coherent(&ap->pdev->dev, size,
+ &ap->rx_ring_base_dma, GFP_KERNEL);
if (ap->rx_std_ring == NULL)
goto fail;
@@ -774,7 +771,8 @@ static int ace_allocate_descriptors(struct net_device *dev)
size = (sizeof(struct event) * EVT_RING_ENTRIES);
- ap->evt_ring = pci_alloc_consistent(ap->pdev, size, &ap->evt_ring_dma);
+ ap->evt_ring = dma_alloc_coherent(&ap->pdev->dev, size,
+ &ap->evt_ring_dma, GFP_KERNEL);
if (ap->evt_ring == NULL)
goto fail;
@@ -786,25 +784,25 @@ static int ace_allocate_descriptors(struct net_device *dev)
if (!ACE_IS_TIGON_I(ap)) {
size = (sizeof(struct tx_desc) * MAX_TX_RING_ENTRIES);
- ap->tx_ring = pci_alloc_consistent(ap->pdev, size,
- &ap->tx_ring_dma);
+ ap->tx_ring = dma_alloc_coherent(&ap->pdev->dev, size,
+ &ap->tx_ring_dma, GFP_KERNEL);
if (ap->tx_ring == NULL)
goto fail;
}
- ap->evt_prd = pci_alloc_consistent(ap->pdev, sizeof(u32),
- &ap->evt_prd_dma);
+ ap->evt_prd = dma_alloc_coherent(&ap->pdev->dev, sizeof(u32),
+ &ap->evt_prd_dma, GFP_KERNEL);
if (ap->evt_prd == NULL)
goto fail;
- ap->rx_ret_prd = pci_alloc_consistent(ap->pdev, sizeof(u32),
- &ap->rx_ret_prd_dma);
+ ap->rx_ret_prd = dma_alloc_coherent(&ap->pdev->dev, sizeof(u32),
+ &ap->rx_ret_prd_dma, GFP_KERNEL);
if (ap->rx_ret_prd == NULL)
goto fail;
- ap->tx_csm = pci_alloc_consistent(ap->pdev, sizeof(u32),
- &ap->tx_csm_dma);
+ ap->tx_csm = dma_alloc_coherent(&ap->pdev->dev, sizeof(u32),
+ &ap->tx_csm_dma, GFP_KERNEL);
if (ap->tx_csm == NULL)
goto fail;
@@ -830,8 +828,8 @@ static void ace_init_cleanup(struct net_device *dev)
ace_free_descriptors(dev);
if (ap->info)
- pci_free_consistent(ap->pdev, sizeof(struct ace_info),
- ap->info, ap->info_dma);
+ dma_free_coherent(&ap->pdev->dev, sizeof(struct ace_info),
+ ap->info, ap->info_dma);
kfree(ap->skb);
kfree(ap->trace_buf);
@@ -1129,9 +1127,9 @@ static int ace_init(struct net_device *dev)
/*
* Configure DMA attributes.
*/
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
ap->pci_using_dac = 1;
- } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
ap->pci_using_dac = 0;
} else {
ecode = -ENODEV;
@@ -1143,8 +1141,8 @@ static int ace_init(struct net_device *dev)
* and the control blocks for the transmit and receive rings
* as they need to be setup once and for all.
*/
- if (!(info = pci_alloc_consistent(ap->pdev, sizeof(struct ace_info),
- &ap->info_dma))) {
+ if (!(info = dma_alloc_coherent(&ap->pdev->dev, sizeof(struct ace_info),
+ &ap->info_dma, GFP_KERNEL))) {
ecode = -EAGAIN;
goto init_error;
}
@@ -1153,7 +1151,7 @@ static int ace_init(struct net_device *dev)
/*
* Get the memory for the skb rings.
*/
- if (!(ap->skb = kmalloc(sizeof(struct ace_skb), GFP_KERNEL))) {
+ if (!(ap->skb = kzalloc(sizeof(struct ace_skb), GFP_KERNEL))) {
ecode = -EAGAIN;
goto init_error;
}
@@ -1174,9 +1172,6 @@ static int ace_init(struct net_device *dev)
ap->last_mini_rx = 0;
#endif
- memset(ap->info, 0, sizeof(struct ace_info));
- memset(ap->skb, 0, sizeof(struct ace_skb));
-
ecode = ace_load_firmware(dev);
if (ecode)
goto init_error;
@@ -1646,10 +1641,10 @@ static void ace_load_std_rx_ring(struct net_device *dev, int nr_bufs)
if (!skb)
break;
- mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
+ mapping = dma_map_page(&ap->pdev->dev,
+ virt_to_page(skb->data),
offset_in_page(skb->data),
- ACE_STD_BUFSIZE,
- PCI_DMA_FROMDEVICE);
+ ACE_STD_BUFSIZE, DMA_FROM_DEVICE);
ap->skb->rx_std_skbuff[idx].skb = skb;
dma_unmap_addr_set(&ap->skb->rx_std_skbuff[idx],
mapping, mapping);
@@ -1707,10 +1702,10 @@ static void ace_load_mini_rx_ring(struct net_device *dev, int nr_bufs)
if (!skb)
break;
- mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
+ mapping = dma_map_page(&ap->pdev->dev,
+ virt_to_page(skb->data),
offset_in_page(skb->data),
- ACE_MINI_BUFSIZE,
- PCI_DMA_FROMDEVICE);
+ ACE_MINI_BUFSIZE, DMA_FROM_DEVICE);
ap->skb->rx_mini_skbuff[idx].skb = skb;
dma_unmap_addr_set(&ap->skb->rx_mini_skbuff[idx],
mapping, mapping);
@@ -1763,10 +1758,10 @@ static void ace_load_jumbo_rx_ring(struct net_device *dev, int nr_bufs)
if (!skb)
break;
- mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
+ mapping = dma_map_page(&ap->pdev->dev,
+ virt_to_page(skb->data),
offset_in_page(skb->data),
- ACE_JUMBO_BUFSIZE,
- PCI_DMA_FROMDEVICE);
+ ACE_JUMBO_BUFSIZE, DMA_FROM_DEVICE);
ap->skb->rx_jumbo_skbuff[idx].skb = skb;
dma_unmap_addr_set(&ap->skb->rx_jumbo_skbuff[idx],
mapping, mapping);
@@ -1977,10 +1972,8 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
skb = rip->skb;
rip->skb = NULL;
- pci_unmap_page(ap->pdev,
- dma_unmap_addr(rip, mapping),
- mapsize,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_page(&ap->pdev->dev, dma_unmap_addr(rip, mapping),
+ mapsize, DMA_FROM_DEVICE);
skb_put(skb, retdesc->size);
/*
@@ -2046,9 +2039,10 @@ static inline void ace_tx_int(struct net_device *dev,
skb = info->skb;
if (dma_unmap_len(info, maplen)) {
- pci_unmap_page(ap->pdev, dma_unmap_addr(info, mapping),
+ dma_unmap_page(&ap->pdev->dev,
+ dma_unmap_addr(info, mapping),
dma_unmap_len(info, maplen),
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
dma_unmap_len_set(info, maplen, 0);
}
@@ -2337,9 +2331,10 @@ static int ace_close(struct net_device *dev)
} else
memset(ap->tx_ring + i, 0,
sizeof(struct tx_desc));
- pci_unmap_page(ap->pdev, dma_unmap_addr(info, mapping),
+ dma_unmap_page(&ap->pdev->dev,
+ dma_unmap_addr(info, mapping),
dma_unmap_len(info, maplen),
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
dma_unmap_len_set(info, maplen, 0);
}
if (skb) {
@@ -2369,9 +2364,9 @@ ace_map_tx_skb(struct ace_private *ap, struct sk_buff *skb,
dma_addr_t mapping;
struct tx_ring_info *info;
- mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
- offset_in_page(skb->data),
- skb->len, PCI_DMA_TODEVICE);
+ mapping = dma_map_page(&ap->pdev->dev, virt_to_page(skb->data),
+ offset_in_page(skb->data), skb->len,
+ DMA_TO_DEVICE);
info = ap->skb->tx_skbuff + idx;
info->skb = tail;
diff --git a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
index 336742f6e3c3..b818a169c193 100644
--- a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+++ b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
@@ -491,6 +491,36 @@ enum ena_admin_llq_stride_ctrl {
ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY = 2,
};
+enum ena_admin_accel_mode_feat {
+ ENA_ADMIN_DISABLE_META_CACHING = 0,
+ ENA_ADMIN_LIMIT_TX_BURST = 1,
+};
+
+struct ena_admin_accel_mode_get {
+ /* bit field of enum ena_admin_accel_mode_feat */
+ u16 supported_flags;
+
+ /* maximum burst size between two doorbells. The size is in bytes */
+ u16 max_tx_burst_size;
+};
+
+struct ena_admin_accel_mode_set {
+ /* bit field of enum ena_admin_accel_mode_feat */
+ u16 enabled_flags;
+
+ u16 reserved;
+};
+
+struct ena_admin_accel_mode_req {
+ union {
+ u32 raw[2];
+
+ struct ena_admin_accel_mode_get get;
+
+ struct ena_admin_accel_mode_set set;
+ } u;
+};
+
struct ena_admin_feature_llq_desc {
u32 max_llq_num;
@@ -536,10 +566,13 @@ struct ena_admin_feature_llq_desc {
/* the stride control the driver selected to use */
u16 descriptors_stride_ctrl_enabled;
- /* Maximum size in bytes taken by llq entries in a single tx burst.
- * Set to 0 when there is no such limit.
+ /* reserved */
+ u32 reserved1;
+
+ /* accelerated low latency queues requirement. driver needs to
+ * support those requirements in order to use accelerated llq
*/
- u32 max_tx_burst_size;
+ struct ena_admin_accel_mode_req accel_mode;
};
struct ena_admin_queue_ext_feature_fields {
@@ -816,7 +849,9 @@ struct ena_admin_host_info {
/* 0 : reserved
* 1 : rx_offset
* 2 : interrupt_moderation
- * 31:3 : reserved
+ * 3 : rx_buf_mirroring
+ * 4 : rss_configurable_function_key
+ * 31:5 : reserved
*/
u32 driver_supported_features;
};
@@ -1129,6 +1164,10 @@ struct ena_admin_ena_mmio_req_read_less_resp {
#define ENA_ADMIN_HOST_INFO_RX_OFFSET_MASK BIT(1)
#define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_SHIFT 2
#define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK BIT(2)
+#define ENA_ADMIN_HOST_INFO_RX_BUF_MIRRORING_SHIFT 3
+#define ENA_ADMIN_HOST_INFO_RX_BUF_MIRRORING_MASK BIT(3)
+#define ENA_ADMIN_HOST_INFO_RSS_CONFIGURABLE_FUNCTION_KEY_SHIFT 4
+#define ENA_ADMIN_HOST_INFO_RSS_CONFIGURABLE_FUNCTION_KEY_MASK BIT(4)
/* aenq_common_desc */
#define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0)
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
index 432f143559a1..435bf05a853c 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -403,6 +403,8 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev,
0x0, io_sq->llq_info.desc_list_entry_size);
io_sq->llq_buf_ctrl.descs_left_in_line =
io_sq->llq_info.descs_num_before_header;
+ io_sq->disable_meta_caching =
+ io_sq->llq_info.disable_meta_caching;
if (io_sq->llq_info.max_entries_in_tx_burst > 0)
io_sq->entries_in_tx_burst_left =
@@ -626,6 +628,10 @@ static int ena_com_set_llq(struct ena_com_dev *ena_dev)
cmd.u.llq.desc_num_before_header_enabled = llq_info->descs_num_before_header;
cmd.u.llq.descriptors_stride_ctrl_enabled = llq_info->desc_stride_ctrl;
+ cmd.u.llq.accel_mode.u.set.enabled_flags =
+ BIT(ENA_ADMIN_DISABLE_META_CACHING) |
+ BIT(ENA_ADMIN_LIMIT_TX_BURST);
+
ret = ena_com_execute_admin_command(admin_queue,
(struct ena_admin_aq_entry *)&cmd,
sizeof(cmd),
@@ -643,6 +649,7 @@ static int ena_com_config_llq_info(struct ena_com_dev *ena_dev,
struct ena_llq_configurations *llq_default_cfg)
{
struct ena_com_llq_info *llq_info = &ena_dev->llq_info;
+ struct ena_admin_accel_mode_get llq_accel_mode_get;
u16 supported_feat;
int rc;
@@ -742,9 +749,17 @@ static int ena_com_config_llq_info(struct ena_com_dev *ena_dev,
llq_default_cfg->llq_num_decs_before_header,
supported_feat, llq_info->descs_num_before_header);
}
+ /* Check for accelerated queue supported */
+ llq_accel_mode_get = llq_features->accel_mode.u.get;
+
+ llq_info->disable_meta_caching =
+ !!(llq_accel_mode_get.supported_flags &
+ BIT(ENA_ADMIN_DISABLE_META_CACHING));
- llq_info->max_entries_in_tx_burst =
- (u16)(llq_features->max_tx_burst_size / llq_default_cfg->llq_ring_entry_size_value);
+ if (llq_accel_mode_get.supported_flags & BIT(ENA_ADMIN_LIMIT_TX_BURST))
+ llq_info->max_entries_in_tx_burst =
+ llq_accel_mode_get.max_tx_burst_size /
+ llq_default_cfg->llq_ring_entry_size_value;
rc = ena_com_set_llq(ena_dev);
if (rc)
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.h b/drivers/net/ethernet/amazon/ena/ena_com.h
index bc187adf54e4..4287d47b2b0b 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_com.h
@@ -127,6 +127,7 @@ struct ena_com_llq_info {
u16 descs_num_before_header;
u16 descs_per_entry;
u16 max_entries_in_tx_burst;
+ bool disable_meta_caching;
};
struct ena_com_io_cq {
@@ -189,6 +190,8 @@ struct ena_com_io_sq {
enum queue_direction direction;
enum ena_admin_placement_policy_type mem_queue_type;
+ bool disable_meta_caching;
+
u32 msix_vector;
struct ena_com_tx_meta cached_tx_meta;
struct ena_com_llq_info llq_info;
@@ -230,11 +233,11 @@ struct ena_com_admin_sq {
};
struct ena_com_stats_admin {
- u32 aborted_cmd;
- u32 submitted_cmd;
- u32 completed_cmd;
- u32 out_of_space;
- u32 no_completion;
+ u64 aborted_cmd;
+ u64 submitted_cmd;
+ u64 completed_cmd;
+ u64 out_of_space;
+ u64 no_completion;
};
struct ena_com_admin_queue {
diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
index ec8ea25e988d..ccd440589565 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c
@@ -285,11 +285,10 @@ static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
return count;
}
-static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
- struct ena_com_tx_ctx *ena_tx_ctx)
+static int ena_com_create_meta(struct ena_com_io_sq *io_sq,
+ struct ena_com_tx_meta *ena_meta)
{
struct ena_eth_io_tx_meta_desc *meta_desc = NULL;
- struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta;
meta_desc = get_sq_desc(io_sq);
memset(meta_desc, 0x0, sizeof(struct ena_eth_io_tx_meta_desc));
@@ -309,12 +308,13 @@ static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
/* Extended meta desc */
meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK;
- meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK;
meta_desc->len_ctrl |= (io_sq->phase <<
ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT) &
ENA_ETH_IO_TX_META_DESC_PHASE_MASK;
meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_FIRST_MASK;
+ meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK;
+
meta_desc->word2 |= ena_meta->l3_hdr_len &
ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK;
meta_desc->word2 |= (ena_meta->l3_hdr_offset <<
@@ -325,13 +325,36 @@ static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT) &
ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK;
- meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK;
+ return ena_com_sq_update_tail(io_sq);
+}
+
+static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
+ struct ena_com_tx_ctx *ena_tx_ctx,
+ bool *have_meta)
+{
+ struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta;
- /* Cached the meta desc */
- memcpy(&io_sq->cached_tx_meta, ena_meta,
- sizeof(struct ena_com_tx_meta));
+ /* When disable meta caching is set, don't bother to save the meta and
+ * compare it to the stored version, just create the meta
+ */
+ if (io_sq->disable_meta_caching) {
+ if (unlikely(!ena_tx_ctx->meta_valid))
+ return -EINVAL;
- return ena_com_sq_update_tail(io_sq);
+ *have_meta = true;
+ return ena_com_create_meta(io_sq, ena_meta);
+ }
+
+ if (ena_com_meta_desc_changed(io_sq, ena_tx_ctx)) {
+ *have_meta = true;
+ /* Cache the meta desc */
+ memcpy(&io_sq->cached_tx_meta, ena_meta,
+ sizeof(struct ena_com_tx_meta));
+ return ena_com_create_meta(io_sq, ena_meta);
+ }
+
+ *have_meta = false;
+ return 0;
}
static void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx,
@@ -402,12 +425,10 @@ int ena_com_prepare_tx(struct ena_com_io_sq *io_sq,
if (unlikely(rc))
return rc;
- have_meta = ena_tx_ctx->meta_valid && ena_com_meta_desc_changed(io_sq,
- ena_tx_ctx);
- if (have_meta) {
- rc = ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx);
- if (unlikely(rc))
- return rc;
+ rc = ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx, &have_meta);
+ if (unlikely(rc)) {
+ pr_err("failed to create and store tx meta desc\n");
+ return rc;
}
/* If the caller doesn't want to send packets */
diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.h b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
index 8b1afd3b32f2..b6592cb93b04 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
@@ -157,7 +157,8 @@ static inline bool ena_com_is_doorbell_needed(struct ena_com_io_sq *io_sq,
llq_info = &io_sq->llq_info;
num_descs = ena_tx_ctx->num_bufs;
- if (unlikely(ena_com_meta_desc_changed(io_sq, ena_tx_ctx)))
+ if (llq_info->disable_meta_caching ||
+ unlikely(ena_com_meta_desc_changed(io_sq, ena_tx_ctx)))
++num_descs;
if (num_descs > llq_info->descs_num_before_header) {
diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index e340b65af08c..430275bc0d04 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -164,13 +164,13 @@ static void ena_queue_stats(struct ena_adapter *adapter, u64 **data)
static void ena_dev_admin_queue_stats(struct ena_adapter *adapter, u64 **data)
{
const struct ena_stats *ena_stats;
- u32 *ptr;
+ u64 *ptr;
int i;
for (i = 0; i < ENA_STATS_ARRAY_ENA_COM; i++) {
ena_stats = &ena_stats_ena_com_strings[i];
- ptr = (u32 *)((uintptr_t)&adapter->ena_dev->admin_queue.stats +
+ ptr = (u64 *)((uintptr_t)&adapter->ena_dev->admin_queue.stats +
(uintptr_t)ena_stats->stat_offset);
*(*data)++ = *ptr;
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index dda4b8fc9525..2a6c9725e092 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -307,7 +307,7 @@ static int ena_xdp_xmit_buff(struct net_device *dev,
struct ena_rx_buffer *rx_info)
{
struct ena_adapter *adapter = netdev_priv(dev);
- struct ena_com_tx_ctx ena_tx_ctx = {0};
+ struct ena_com_tx_ctx ena_tx_ctx = {};
struct ena_tx_buffer *tx_info;
struct ena_ring *xdp_ring;
u16 next_to_use, req_id;
@@ -576,15 +576,9 @@ static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)
*/
static int ena_xdp(struct net_device *netdev, struct netdev_bpf *bpf)
{
- struct ena_adapter *adapter = netdev_priv(netdev);
-
switch (bpf->command) {
case XDP_SETUP_PROG:
return ena_xdp_set(netdev, bpf);
- case XDP_QUERY_PROG:
- bpf->prog_id = adapter->xdp_bpf_prog ?
- adapter->xdp_bpf_prog->aux->id : 0;
- break;
default:
return -EINVAL;
}
@@ -655,6 +649,7 @@ static void ena_init_io_rings(struct ena_adapter *adapter,
txr->sgl_size = adapter->max_tx_sgl_size;
txr->smoothed_interval =
ena_com_get_nonadaptive_moderation_interval_tx(ena_dev);
+ txr->disable_meta_caching = adapter->disable_meta_caching;
/* Don't init RX queues for xdp queues */
if (!ENA_IS_XDP_INDEX(adapter, i)) {
@@ -959,8 +954,11 @@ static int ena_alloc_rx_page(struct ena_ring *rx_ring,
return -ENOMEM;
}
+ /* To enable NIC-side port-mirroring, AKA SPAN port,
+ * we make the buffer readable from the nic as well
+ */
dma = dma_map_page(rx_ring->dev, page, 0, ENA_PAGE_SIZE,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(rx_ring->dev, dma))) {
u64_stats_update_begin(&rx_ring->syncp);
rx_ring->rx_stats.dma_mapping_err++;
@@ -993,10 +991,9 @@ static void ena_free_rx_page(struct ena_ring *rx_ring,
return;
}
- dma_unmap_page(rx_ring->dev,
- ena_buf->paddr - rx_ring->rx_headroom,
+ dma_unmap_page(rx_ring->dev, ena_buf->paddr - rx_ring->rx_headroom,
ENA_PAGE_SIZE,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
__free_page(page);
rx_info->page = NULL;
@@ -1431,7 +1428,7 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
do {
dma_unmap_page(rx_ring->dev,
dma_unmap_addr(&rx_info->ena_buf, paddr),
- ENA_PAGE_SIZE, DMA_FROM_DEVICE);
+ ENA_PAGE_SIZE, DMA_BIDIRECTIONAL);
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page,
rx_info->page_offset, len, ENA_PAGE_SIZE);
@@ -1913,7 +1910,10 @@ static int ena_io_poll(struct napi_struct *napi, int budget)
/* Update numa and unmask the interrupt only when schedule
* from the interrupt context (vs from sk_busy_loop)
*/
- if (napi_complete_done(napi, rx_work_done)) {
+ if (napi_complete_done(napi, rx_work_done) &&
+ READ_ONCE(ena_napi->interrupts_masked)) {
+ smp_rmb(); /* make sure interrupts_masked is read */
+ WRITE_ONCE(ena_napi->interrupts_masked, false);
/* We apply adaptive moderation on Rx path only.
* Tx uses static interrupt moderation.
*/
@@ -1961,6 +1961,9 @@ static irqreturn_t ena_intr_msix_io(int irq, void *data)
ena_napi->first_interrupt = true;
+ WRITE_ONCE(ena_napi->interrupts_masked, true);
+ smp_wmb(); /* write interrupts_masked before calling napi */
+
napi_schedule_irqoff(&ena_napi->napi);
return IRQ_HANDLED;
@@ -2190,14 +2193,13 @@ static void ena_del_napi_in_range(struct ena_adapter *adapter,
static void ena_init_napi_in_range(struct ena_adapter *adapter,
int first_index, int count)
{
- struct ena_napi *napi = {0};
int i;
for (i = first_index; i < first_index + count; i++) {
- napi = &adapter->ena_napi[i];
+ struct ena_napi *napi = &adapter->ena_napi[i];
netif_napi_add(adapter->netdev,
- &adapter->ena_napi[i].napi,
+ &napi->napi,
ENA_IS_XDP_INDEX(adapter, i) ? ena_xdp_io_poll : ena_io_poll,
ENA_NAPI_BUDGET);
@@ -2776,7 +2778,9 @@ int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count)
return dev_was_up ? ena_open(adapter->netdev) : 0;
}
-static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct sk_buff *skb)
+static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx,
+ struct sk_buff *skb,
+ bool disable_meta_caching)
{
u32 mss = skb_shinfo(skb)->gso_size;
struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta;
@@ -2820,7 +2824,9 @@ static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct sk_buff *skb)
ena_meta->l3_hdr_len = skb_network_header_len(skb);
ena_meta->l3_hdr_offset = skb_network_offset(skb);
ena_tx_ctx->meta_valid = 1;
-
+ } else if (disable_meta_caching) {
+ memset(ena_meta, 0, sizeof(*ena_meta));
+ ena_tx_ctx->meta_valid = 1;
} else {
ena_tx_ctx->meta_valid = 0;
}
@@ -3004,7 +3010,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
ena_tx_ctx.header_len = header_len;
/* set flags and meta data */
- ena_tx_csum(&ena_tx_ctx, skb);
+ ena_tx_csum(&ena_tx_ctx, skb, tx_ring->disable_meta_caching);
rc = ena_xmit_common(dev,
tx_ring,
@@ -3118,7 +3124,9 @@ static void ena_config_host_info(struct ena_com_dev *ena_dev, struct pci_dev *pd
host_info->driver_supported_features =
ENA_ADMIN_HOST_INFO_RX_OFFSET_MASK |
- ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK;
+ ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK |
+ ENA_ADMIN_HOST_INFO_RX_BUF_MIRRORING_MASK |
+ ENA_ADMIN_HOST_INFO_RSS_CONFIGURABLE_FUNCTION_KEY_MASK;
rc = ena_com_set_host_attributes(ena_dev);
if (rc) {
@@ -3271,10 +3279,71 @@ static int ena_device_validate_params(struct ena_adapter *adapter,
return 0;
}
+static void set_default_llq_configurations(struct ena_llq_configurations *llq_config)
+{
+ llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER;
+ llq_config->llq_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY;
+ llq_config->llq_num_decs_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2;
+ llq_config->llq_ring_entry_size = ENA_ADMIN_LIST_ENTRY_SIZE_128B;
+ llq_config->llq_ring_entry_size_value = 128;
+}
+
+static int ena_set_queues_placement_policy(struct pci_dev *pdev,
+ struct ena_com_dev *ena_dev,
+ struct ena_admin_feature_llq_desc *llq,
+ struct ena_llq_configurations *llq_default_configurations)
+{
+ int rc;
+ u32 llq_feature_mask;
+
+ llq_feature_mask = 1 << ENA_ADMIN_LLQ;
+ if (!(ena_dev->supported_features & llq_feature_mask)) {
+ dev_err(&pdev->dev,
+ "LLQ is not supported Fallback to host mode policy.\n");
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ return 0;
+ }
+
+ rc = ena_com_config_dev_mode(ena_dev, llq, llq_default_configurations);
+ if (unlikely(rc)) {
+ dev_err(&pdev->dev,
+ "Failed to configure the device mode. Fallback to host mode policy.\n");
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ }
+
+ return 0;
+}
+
+static int ena_map_llq_mem_bar(struct pci_dev *pdev, struct ena_com_dev *ena_dev,
+ int bars)
+{
+ bool has_mem_bar = !!(bars & BIT(ENA_MEM_BAR));
+
+ if (!has_mem_bar) {
+ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+ dev_err(&pdev->dev,
+ "ENA device does not expose LLQ bar. Fallback to host mode policy.\n");
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ }
+
+ return 0;
+ }
+
+ ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev,
+ pci_resource_start(pdev, ENA_MEM_BAR),
+ pci_resource_len(pdev, ENA_MEM_BAR));
+
+ if (!ena_dev->mem_bar)
+ return -EFAULT;
+
+ return 0;
+}
+
static int ena_device_init(struct ena_com_dev *ena_dev, struct pci_dev *pdev,
struct ena_com_dev_get_features_ctx *get_feat_ctx,
bool *wd_state)
{
+ struct ena_llq_configurations llq_config;
struct device *dev = &pdev->dev;
bool readless_supported;
u32 aenq_groups;
@@ -3365,6 +3434,15 @@ static int ena_device_init(struct ena_com_dev *ena_dev, struct pci_dev *pdev,
*wd_state = !!(aenq_groups & BIT(ENA_ADMIN_KEEP_ALIVE));
+ set_default_llq_configurations(&llq_config);
+
+ rc = ena_set_queues_placement_policy(pdev, ena_dev, &get_feat_ctx->llq,
+ &llq_config);
+ if (rc) {
+ dev_err(&pdev->dev, "ena device init failed\n");
+ goto err_admin_init;
+ }
+
return 0;
err_admin_init:
@@ -3871,54 +3949,6 @@ static u32 ena_calc_max_io_queue_num(struct pci_dev *pdev,
return max_num_io_queues;
}
-static int ena_set_queues_placement_policy(struct pci_dev *pdev,
- struct ena_com_dev *ena_dev,
- struct ena_admin_feature_llq_desc *llq,
- struct ena_llq_configurations *llq_default_configurations)
-{
- bool has_mem_bar;
- int rc;
- u32 llq_feature_mask;
-
- llq_feature_mask = 1 << ENA_ADMIN_LLQ;
- if (!(ena_dev->supported_features & llq_feature_mask)) {
- dev_err(&pdev->dev,
- "LLQ is not supported Fallback to host mode policy.\n");
- ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
- return 0;
- }
-
- has_mem_bar = pci_select_bars(pdev, IORESOURCE_MEM) & BIT(ENA_MEM_BAR);
-
- rc = ena_com_config_dev_mode(ena_dev, llq, llq_default_configurations);
- if (unlikely(rc)) {
- dev_err(&pdev->dev,
- "Failed to configure the device mode. Fallback to host mode policy.\n");
- ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
- return 0;
- }
-
- /* Nothing to config, exit */
- if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
- return 0;
-
- if (!has_mem_bar) {
- dev_err(&pdev->dev,
- "ENA device does not expose LLQ bar. Fallback to host mode policy.\n");
- ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
- return 0;
- }
-
- ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev,
- pci_resource_start(pdev, ENA_MEM_BAR),
- pci_resource_len(pdev, ENA_MEM_BAR));
-
- if (!ena_dev->mem_bar)
- return -EFAULT;
-
- return 0;
-}
-
static void ena_set_dev_offloads(struct ena_com_dev_get_features_ctx *feat,
struct net_device *netdev)
{
@@ -4034,14 +4064,6 @@ static void ena_release_bars(struct ena_com_dev *ena_dev, struct pci_dev *pdev)
pci_release_selected_regions(pdev, release_bars);
}
-static void set_default_llq_configurations(struct ena_llq_configurations *llq_config)
-{
- llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER;
- llq_config->llq_ring_entry_size = ENA_ADMIN_LIST_ENTRY_SIZE_128B;
- llq_config->llq_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY;
- llq_config->llq_num_decs_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2;
- llq_config->llq_ring_entry_size_value = 128;
-}
static int ena_calc_io_queue_size(struct ena_calc_queue_size_ctx *ctx)
{
@@ -4123,7 +4145,6 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct ena_calc_queue_size_ctx calc_queue_ctx = { 0 };
struct ena_com_dev_get_features_ctx get_feat_ctx;
- struct ena_llq_configurations llq_config;
struct ena_com_dev *ena_dev = NULL;
struct ena_adapter *adapter;
struct net_device *netdev;
@@ -4178,13 +4199,10 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_free_region;
}
- set_default_llq_configurations(&llq_config);
-
- rc = ena_set_queues_placement_policy(pdev, ena_dev, &get_feat_ctx.llq,
- &llq_config);
+ rc = ena_map_llq_mem_bar(pdev, ena_dev, bars);
if (rc) {
- dev_err(&pdev->dev, "ena device init failed\n");
- goto err_device_destroy;
+ dev_err(&pdev->dev, "ena llq bar mapping failed\n");
+ goto err_free_ena_dev;
}
calc_queue_ctx.ena_dev = ena_dev;
@@ -4241,6 +4259,11 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->xdp_num_queues = 0;
adapter->rx_copybreak = ENA_DEFAULT_RX_COPYBREAK;
+ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
+ adapter->disable_meta_caching =
+ !!(get_feat_ctx.llq.accel_mode.u.get.supported_flags &
+ BIT(ENA_ADMIN_DISABLE_META_CACHING));
+
adapter->wd_state = wd_state;
snprintf(adapter->name, ENA_NAME_MAX_LEN, "ena_%d", adapters_found);
@@ -4420,13 +4443,12 @@ static void ena_shutdown(struct pci_dev *pdev)
__ena_shutoff(pdev, true);
}
-#ifdef CONFIG_PM
/* ena_suspend - PM suspend callback
- * @pdev: PCI device information struct
- * @state:power state
+ * @dev_d: Device information struct
*/
-static int ena_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused ena_suspend(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct ena_adapter *adapter = pci_get_drvdata(pdev);
u64_stats_update_begin(&adapter->syncp);
@@ -4445,12 +4467,11 @@ static int ena_suspend(struct pci_dev *pdev, pm_message_t state)
}
/* ena_resume - PM resume callback
- * @pdev: PCI device information struct
- *
+ * @dev_d: Device information struct
*/
-static int ena_resume(struct pci_dev *pdev)
+static int __maybe_unused ena_resume(struct device *dev_d)
{
- struct ena_adapter *adapter = pci_get_drvdata(pdev);
+ struct ena_adapter *adapter = dev_get_drvdata(dev_d);
int rc;
u64_stats_update_begin(&adapter->syncp);
@@ -4462,7 +4483,8 @@ static int ena_resume(struct pci_dev *pdev)
rtnl_unlock();
return rc;
}
-#endif
+
+static SIMPLE_DEV_PM_OPS(ena_pm_ops, ena_suspend, ena_resume);
static struct pci_driver ena_pci_driver = {
.name = DRV_MODULE_NAME,
@@ -4470,10 +4492,7 @@ static struct pci_driver ena_pci_driver = {
.probe = ena_probe,
.remove = ena_remove,
.shutdown = ena_shutdown,
-#ifdef CONFIG_PM
- .suspend = ena_suspend,
- .resume = ena_resume,
-#endif
+ .driver.pm = &ena_pm_ops,
.sriov_configure = pci_sriov_configure_simple,
};
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index ba030d260940..0c8504006247 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -167,6 +167,7 @@ struct ena_napi {
struct ena_ring *rx_ring;
struct ena_ring *xdp_ring;
bool first_interrupt;
+ bool interrupts_masked;
u32 qid;
struct dim dim;
};
@@ -297,6 +298,7 @@ struct ena_ring {
u8 tx_max_header_size;
bool first_interrupt;
+ bool disable_meta_caching;
u16 no_interrupt_event_cnt;
/* cpu for TPH */
@@ -398,6 +400,7 @@ struct ena_adapter {
bool wd_state;
bool dev_up_before_reset;
+ bool disable_meta_caching;
unsigned long last_keep_alive_jiffies;
struct u64_stats_sync syncp;
diff --git a/drivers/net/ethernet/amazon/ena/ena_pci_id_tbl.h b/drivers/net/ethernet/amazon/ena/ena_pci_id_tbl.h
index f80d2a47fa94..426e57e10a7f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_pci_id_tbl.h
+++ b/drivers/net/ethernet/amazon/ena/ena_pci_id_tbl.h
@@ -53,10 +53,15 @@
#define PCI_DEV_ID_ENA_LLQ_VF 0xec21
#endif
+#ifndef PCI_DEV_ID_ENA_RESRV0
+#define PCI_DEV_ID_ENA_RESRV0 0x0051
+#endif
+
#define ENA_PCI_ID_TABLE_ENTRY(devid) \
{PCI_DEVICE(PCI_VENDOR_ID_AMAZON, devid)},
static const struct pci_device_id ena_pci_tbl[] = {
+ ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_RESRV0)
ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_PF)
ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_LLQ_PF)
ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_VF)
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index 7a1286f8e983..b6c43b58ed3d 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -226,7 +226,9 @@ static int amd8111e_free_skbs(struct net_device *dev)
/* Freeing transmit skbs */
for(i = 0; i < NUM_TX_BUFFERS; i++){
if(lp->tx_skbuff[i]){
- pci_unmap_single(lp->pci_dev,lp->tx_dma_addr[i], lp->tx_skbuff[i]->len,PCI_DMA_TODEVICE);
+ dma_unmap_single(&lp->pci_dev->dev,
+ lp->tx_dma_addr[i],
+ lp->tx_skbuff[i]->len, DMA_TO_DEVICE);
dev_kfree_skb (lp->tx_skbuff[i]);
lp->tx_skbuff[i] = NULL;
lp->tx_dma_addr[i] = 0;
@@ -236,8 +238,9 @@ static int amd8111e_free_skbs(struct net_device *dev)
for (i = 0; i < NUM_RX_BUFFERS; i++){
rx_skbuff = lp->rx_skbuff[i];
if(rx_skbuff != NULL){
- pci_unmap_single(lp->pci_dev,lp->rx_dma_addr[i],
- lp->rx_buff_len - 2,PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&lp->pci_dev->dev,
+ lp->rx_dma_addr[i],
+ lp->rx_buff_len - 2, DMA_FROM_DEVICE);
dev_kfree_skb(lp->rx_skbuff[i]);
lp->rx_skbuff[i] = NULL;
lp->rx_dma_addr[i] = 0;
@@ -287,20 +290,20 @@ static int amd8111e_init_ring(struct net_device *dev)
amd8111e_free_skbs(dev);
else{
- /* allocate the tx and rx descriptors */
- if((lp->tx_ring = pci_alloc_consistent(lp->pci_dev,
- sizeof(struct amd8111e_tx_dr)*NUM_TX_RING_DR,
- &lp->tx_ring_dma_addr)) == NULL)
-
+ /* allocate the tx and rx descriptors */
+ lp->tx_ring = dma_alloc_coherent(&lp->pci_dev->dev,
+ sizeof(struct amd8111e_tx_dr) * NUM_TX_RING_DR,
+ &lp->tx_ring_dma_addr, GFP_ATOMIC);
+ if (!lp->tx_ring)
goto err_no_mem;
- if((lp->rx_ring = pci_alloc_consistent(lp->pci_dev,
- sizeof(struct amd8111e_rx_dr)*NUM_RX_RING_DR,
- &lp->rx_ring_dma_addr)) == NULL)
-
+ lp->rx_ring = dma_alloc_coherent(&lp->pci_dev->dev,
+ sizeof(struct amd8111e_rx_dr) * NUM_RX_RING_DR,
+ &lp->rx_ring_dma_addr, GFP_ATOMIC);
+ if (!lp->rx_ring)
goto err_free_tx_ring;
-
}
+
/* Set new receive buff size */
amd8111e_set_rx_buff_len(dev);
@@ -318,8 +321,10 @@ static int amd8111e_init_ring(struct net_device *dev)
}
/* Initilaizing receive descriptors */
for (i = 0; i < NUM_RX_BUFFERS; i++) {
- lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev,
- lp->rx_skbuff[i]->data,lp->rx_buff_len-2, PCI_DMA_FROMDEVICE);
+ lp->rx_dma_addr[i] = dma_map_single(&lp->pci_dev->dev,
+ lp->rx_skbuff[i]->data,
+ lp->rx_buff_len - 2,
+ DMA_FROM_DEVICE);
lp->rx_ring[i].buff_phy_addr = cpu_to_le32(lp->rx_dma_addr[i]);
lp->rx_ring[i].buff_count = cpu_to_le16(lp->rx_buff_len-2);
@@ -338,15 +343,15 @@ static int amd8111e_init_ring(struct net_device *dev)
err_free_rx_ring:
- pci_free_consistent(lp->pci_dev,
- sizeof(struct amd8111e_rx_dr)*NUM_RX_RING_DR,lp->rx_ring,
- lp->rx_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct amd8111e_rx_dr) * NUM_RX_RING_DR,
+ lp->rx_ring, lp->rx_ring_dma_addr);
err_free_tx_ring:
- pci_free_consistent(lp->pci_dev,
- sizeof(struct amd8111e_tx_dr)*NUM_TX_RING_DR,lp->tx_ring,
- lp->tx_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct amd8111e_tx_dr) * NUM_TX_RING_DR,
+ lp->tx_ring, lp->tx_ring_dma_addr);
err_no_mem:
return -ENOMEM;
@@ -612,16 +617,16 @@ static void amd8111e_free_ring(struct amd8111e_priv *lp)
{
/* Free transmit and receive descriptor rings */
if(lp->rx_ring){
- pci_free_consistent(lp->pci_dev,
- sizeof(struct amd8111e_rx_dr)*NUM_RX_RING_DR,
- lp->rx_ring, lp->rx_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct amd8111e_rx_dr) * NUM_RX_RING_DR,
+ lp->rx_ring, lp->rx_ring_dma_addr);
lp->rx_ring = NULL;
}
if(lp->tx_ring){
- pci_free_consistent(lp->pci_dev,
- sizeof(struct amd8111e_tx_dr)*NUM_TX_RING_DR,
- lp->tx_ring, lp->tx_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct amd8111e_tx_dr) * NUM_TX_RING_DR,
+ lp->tx_ring, lp->tx_ring_dma_addr);
lp->tx_ring = NULL;
}
@@ -649,9 +654,10 @@ static int amd8111e_tx(struct net_device *dev)
/* We must free the original skb */
if (lp->tx_skbuff[tx_index]) {
- pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[tx_index],
- lp->tx_skbuff[tx_index]->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&lp->pci_dev->dev,
+ lp->tx_dma_addr[tx_index],
+ lp->tx_skbuff[tx_index]->len,
+ DMA_TO_DEVICE);
dev_consume_skb_irq(lp->tx_skbuff[tx_index]);
lp->tx_skbuff[tx_index] = NULL;
lp->tx_dma_addr[tx_index] = 0;
@@ -737,14 +743,14 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
skb_reserve(new_skb, 2);
skb = lp->rx_skbuff[rx_index];
- pci_unmap_single(lp->pci_dev,lp->rx_dma_addr[rx_index],
- lp->rx_buff_len-2, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&lp->pci_dev->dev, lp->rx_dma_addr[rx_index],
+ lp->rx_buff_len - 2, DMA_FROM_DEVICE);
skb_put(skb, pkt_len);
lp->rx_skbuff[rx_index] = new_skb;
- lp->rx_dma_addr[rx_index] = pci_map_single(lp->pci_dev,
+ lp->rx_dma_addr[rx_index] = dma_map_single(&lp->pci_dev->dev,
new_skb->data,
- lp->rx_buff_len-2,
- PCI_DMA_FROMDEVICE);
+ lp->rx_buff_len - 2,
+ DMA_FROM_DEVICE);
skb->protocol = eth_type_trans(skb, dev);
@@ -1270,7 +1276,8 @@ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
}
#endif
lp->tx_dma_addr[tx_index] =
- pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE);
+ dma_map_single(&lp->pci_dev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
lp->tx_ring[tx_index].buff_phy_addr =
cpu_to_le32(lp->tx_dma_addr[tx_index]);
@@ -1580,9 +1587,10 @@ static void amd8111e_tx_timeout(struct net_device *dev, unsigned int txqueue)
if(!err)
netif_wake_queue(dev);
}
-static int amd8111e_suspend(struct pci_dev *pci_dev, pm_message_t state)
+
+static int __maybe_unused amd8111e_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pci_dev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct amd8111e_priv *lp = netdev_priv(dev);
if (!netif_running(dev))
@@ -1609,34 +1617,24 @@ static int amd8111e_suspend(struct pci_dev *pci_dev, pm_message_t state)
if(lp->options & OPTION_WAKE_PHY_ENABLE)
amd8111e_enable_link_change(lp);
- pci_enable_wake(pci_dev, PCI_D3hot, 1);
- pci_enable_wake(pci_dev, PCI_D3cold, 1);
+ device_set_wakeup_enable(dev_d, 1);
}
else{
- pci_enable_wake(pci_dev, PCI_D3hot, 0);
- pci_enable_wake(pci_dev, PCI_D3cold, 0);
+ device_set_wakeup_enable(dev_d, 0);
}
- pci_save_state(pci_dev);
- pci_set_power_state(pci_dev, PCI_D3hot);
-
return 0;
}
-static int amd8111e_resume(struct pci_dev *pci_dev)
+
+static int __maybe_unused amd8111e_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pci_dev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct amd8111e_priv *lp = netdev_priv(dev);
if (!netif_running(dev))
return 0;
- pci_set_power_state(pci_dev, PCI_D0);
- pci_restore_state(pci_dev);
-
- pci_enable_wake(pci_dev, PCI_D3hot, 0);
- pci_enable_wake(pci_dev, PCI_D3cold, 0); /* D3 cold */
-
netif_device_attach(dev);
spin_lock_irq(&lp->lock);
@@ -1782,7 +1780,7 @@ static int amd8111e_probe_one(struct pci_dev *pdev,
}
/* Initialize DMA */
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) < 0) {
+ if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)) < 0) {
dev_err(&pdev->dev, "DMA not supported\n");
err = -ENODEV;
goto err_free_reg;
@@ -1918,13 +1916,14 @@ static const struct pci_device_id amd8111e_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl);
+static SIMPLE_DEV_PM_OPS(amd8111e_pm_ops, amd8111e_suspend, amd8111e_resume);
+
static struct pci_driver amd8111e_driver = {
.name = MODULE_NAME,
.id_table = amd8111e_pci_tbl,
.probe = amd8111e_probe_one,
.remove = amd8111e_remove_one,
- .suspend = amd8111e_suspend,
- .resume = amd8111e_resume
+ .driver.pm = &amd8111e_pm_ops
};
module_pci_driver(amd8111e_driver);
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 9f6e3cc2ce80..75dbd221dc59 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -241,7 +241,6 @@ MODULE_LICENSE("GPL");
* ps: make sure the used irqs are configured properly in the board
* specific irq-map
*/
-
static void au1000_enable_mac(struct net_device *dev, int force_reset)
{
unsigned long flags;
@@ -556,7 +555,6 @@ static int au1000_mii_probe(struct net_device *dev)
return 0;
}
-
/*
* Buffer allocation/deallocation routines. The buffer descriptor returned
* has the virtual and dma address of a buffer suitable for
@@ -647,7 +645,6 @@ au1000_setup_hw_rings(struct au1000_private *aup, void __iomem *tx_base)
/*
* ethtool operations
*/
-
static void
au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
@@ -679,7 +676,6 @@ static const struct ethtool_ops au1000_ethtool_ops = {
.set_link_ksettings = phy_ethtool_set_link_ksettings,
};
-
/*
* Initialize the interface.
*
@@ -1255,7 +1251,6 @@ static int au1000_probe(struct platform_device *pdev)
aup->rx_db_inuse[i] = pDB;
}
- err = -ENODEV;
for (i = 0; i < NUM_TX_DMA; i++) {
pDB = au1000_GetFreeDB(aup);
if (!pDB)
diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c
index 07e8211eea51..187b0b9a6e1d 100644
--- a/drivers/net/ethernet/amd/pcnet32.c
+++ b/drivers/net/ethernet/amd/pcnet32.c
@@ -250,7 +250,7 @@ struct pcnet32_access {
/*
* The first field of pcnet32_private is read by the ethernet device
- * so the structure should be allocated using pci_alloc_consistent().
+ * so the structure should be allocated using dma_alloc_coherent().
*/
struct pcnet32_private {
struct pcnet32_init_block *init_block;
@@ -258,7 +258,7 @@ struct pcnet32_private {
struct pcnet32_rx_head *rx_ring;
struct pcnet32_tx_head *tx_ring;
dma_addr_t init_dma_addr;/* DMA address of beginning of the init block,
- returned by pci_alloc_consistent */
+ returned by dma_alloc_coherent */
struct pci_dev *pci_dev;
const char *name;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
@@ -485,9 +485,9 @@ static void pcnet32_realloc_tx_ring(struct net_device *dev,
pcnet32_purge_tx_ring(dev);
new_tx_ring =
- pci_zalloc_consistent(lp->pci_dev,
- sizeof(struct pcnet32_tx_head) * entries,
- &new_ring_dma_addr);
+ dma_alloc_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_tx_head) * entries,
+ &new_ring_dma_addr, GFP_ATOMIC);
if (new_tx_ring == NULL)
return;
@@ -501,9 +501,9 @@ static void pcnet32_realloc_tx_ring(struct net_device *dev,
kfree(lp->tx_skbuff);
kfree(lp->tx_dma_addr);
- pci_free_consistent(lp->pci_dev,
- sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
- lp->tx_ring, lp->tx_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+ lp->tx_ring, lp->tx_ring_dma_addr);
lp->tx_ring_size = entries;
lp->tx_mod_mask = lp->tx_ring_size - 1;
@@ -517,10 +517,9 @@ static void pcnet32_realloc_tx_ring(struct net_device *dev,
free_new_lists:
kfree(new_dma_addr_list);
free_new_tx_ring:
- pci_free_consistent(lp->pci_dev,
- sizeof(struct pcnet32_tx_head) * entries,
- new_tx_ring,
- new_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_tx_head) * entries,
+ new_tx_ring, new_ring_dma_addr);
}
/*
@@ -545,9 +544,9 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
unsigned int entries = BIT(size);
new_rx_ring =
- pci_zalloc_consistent(lp->pci_dev,
- sizeof(struct pcnet32_rx_head) * entries,
- &new_ring_dma_addr);
+ dma_alloc_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_rx_head) * entries,
+ &new_ring_dma_addr, GFP_ATOMIC);
if (new_rx_ring == NULL)
return;
@@ -580,10 +579,9 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
skb_reserve(rx_skbuff, NET_IP_ALIGN);
new_dma_addr_list[new] =
- pci_map_single(lp->pci_dev, rx_skbuff->data,
- PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(lp->pci_dev,
- new_dma_addr_list[new])) {
+ dma_map_single(&lp->pci_dev->dev, rx_skbuff->data,
+ PKT_BUF_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&lp->pci_dev->dev, new_dma_addr_list[new])) {
netif_err(lp, drv, dev, "%s dma mapping failed\n",
__func__);
dev_kfree_skb(new_skb_list[new]);
@@ -596,22 +594,20 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
/* and free any unneeded buffers */
for (; new < lp->rx_ring_size; new++) {
if (lp->rx_skbuff[new]) {
- if (!pci_dma_mapping_error(lp->pci_dev,
- lp->rx_dma_addr[new]))
- pci_unmap_single(lp->pci_dev,
+ if (!dma_mapping_error(&lp->pci_dev->dev, lp->rx_dma_addr[new]))
+ dma_unmap_single(&lp->pci_dev->dev,
lp->rx_dma_addr[new],
PKT_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
dev_kfree_skb(lp->rx_skbuff[new]);
}
}
kfree(lp->rx_skbuff);
kfree(lp->rx_dma_addr);
- pci_free_consistent(lp->pci_dev,
- sizeof(struct pcnet32_rx_head) *
- lp->rx_ring_size, lp->rx_ring,
- lp->rx_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+ lp->rx_ring, lp->rx_ring_dma_addr);
lp->rx_ring_size = entries;
lp->rx_mod_mask = lp->rx_ring_size - 1;
@@ -625,12 +621,11 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
free_all_new:
while (--new >= lp->rx_ring_size) {
if (new_skb_list[new]) {
- if (!pci_dma_mapping_error(lp->pci_dev,
- new_dma_addr_list[new]))
- pci_unmap_single(lp->pci_dev,
+ if (!dma_mapping_error(&lp->pci_dev->dev, new_dma_addr_list[new]))
+ dma_unmap_single(&lp->pci_dev->dev,
new_dma_addr_list[new],
PKT_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
dev_kfree_skb(new_skb_list[new]);
}
}
@@ -638,10 +633,9 @@ free_all_new:
free_new_lists:
kfree(new_dma_addr_list);
free_new_rx_ring:
- pci_free_consistent(lp->pci_dev,
- sizeof(struct pcnet32_rx_head) * entries,
- new_rx_ring,
- new_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_rx_head) * entries,
+ new_rx_ring, new_ring_dma_addr);
}
static void pcnet32_purge_rx_ring(struct net_device *dev)
@@ -654,12 +648,11 @@ static void pcnet32_purge_rx_ring(struct net_device *dev)
lp->rx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->rx_skbuff[i]) {
- if (!pci_dma_mapping_error(lp->pci_dev,
- lp->rx_dma_addr[i]))
- pci_unmap_single(lp->pci_dev,
+ if (!dma_mapping_error(&lp->pci_dev->dev, lp->rx_dma_addr[i]))
+ dma_unmap_single(&lp->pci_dev->dev,
lp->rx_dma_addr[i],
PKT_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
dev_kfree_skb_any(lp->rx_skbuff[i]);
}
lp->rx_skbuff[i] = NULL;
@@ -1036,9 +1029,9 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
*packet++ = i;
lp->tx_dma_addr[x] =
- pci_map_single(lp->pci_dev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(lp->pci_dev, lp->tx_dma_addr[x])) {
+ dma_map_single(&lp->pci_dev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&lp->pci_dev->dev, lp->tx_dma_addr[x])) {
netif_printk(lp, hw, KERN_DEBUG, dev,
"DMA mapping error at line: %d!\n",
__LINE__);
@@ -1226,21 +1219,21 @@ static void pcnet32_rx_entry(struct net_device *dev,
*/
if (newskb) {
skb_reserve(newskb, NET_IP_ALIGN);
- new_dma_addr = pci_map_single(lp->pci_dev,
+ new_dma_addr = dma_map_single(&lp->pci_dev->dev,
newskb->data,
PKT_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(lp->pci_dev, new_dma_addr)) {
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&lp->pci_dev->dev, new_dma_addr)) {
netif_err(lp, rx_err, dev,
"DMA mapping error.\n");
dev_kfree_skb(newskb);
skb = NULL;
} else {
skb = lp->rx_skbuff[entry];
- pci_unmap_single(lp->pci_dev,
+ dma_unmap_single(&lp->pci_dev->dev,
lp->rx_dma_addr[entry],
PKT_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
skb_put(skb, pkt_len);
lp->rx_skbuff[entry] = newskb;
lp->rx_dma_addr[entry] = new_dma_addr;
@@ -1259,17 +1252,15 @@ static void pcnet32_rx_entry(struct net_device *dev,
if (!rx_in_place) {
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pkt_len); /* Make room */
- pci_dma_sync_single_for_cpu(lp->pci_dev,
- lp->rx_dma_addr[entry],
- pkt_len,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&lp->pci_dev->dev,
+ lp->rx_dma_addr[entry], pkt_len,
+ DMA_FROM_DEVICE);
skb_copy_to_linear_data(skb,
(unsigned char *)(lp->rx_skbuff[entry]->data),
pkt_len);
- pci_dma_sync_single_for_device(lp->pci_dev,
- lp->rx_dma_addr[entry],
- pkt_len,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&lp->pci_dev->dev,
+ lp->rx_dma_addr[entry], pkt_len,
+ DMA_FROM_DEVICE);
}
dev->stats.rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, dev);
@@ -1358,10 +1349,10 @@ static int pcnet32_tx(struct net_device *dev)
/* We must free the original skb */
if (lp->tx_skbuff[entry]) {
- pci_unmap_single(lp->pci_dev,
+ dma_unmap_single(&lp->pci_dev->dev,
lp->tx_dma_addr[entry],
- lp->tx_skbuff[entry]->
- len, PCI_DMA_TODEVICE);
+ lp->tx_skbuff[entry]->len,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(lp->tx_skbuff[entry]);
lp->tx_skbuff[entry] = NULL;
lp->tx_dma_addr[entry] = 0;
@@ -1551,7 +1542,7 @@ pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_disable_dev;
}
- err = pci_set_dma_mask(pdev, PCNET32_DMA_MASK);
+ err = dma_set_mask(&pdev->dev, PCNET32_DMA_MASK);
if (err) {
if (pcnet32_debug & NETIF_MSG_PROBE)
pr_err("architecture does not support 32bit PCI busmaster DMA\n");
@@ -1834,12 +1825,13 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
dev->base_addr = ioaddr;
lp = netdev_priv(dev);
- /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
- lp->init_block = pci_alloc_consistent(pdev, sizeof(*lp->init_block),
- &lp->init_dma_addr);
+ /* dma_alloc_coherent returns page-aligned memory, so we do not have to check the alignment */
+ lp->init_block = dma_alloc_coherent(&pdev->dev,
+ sizeof(*lp->init_block),
+ &lp->init_dma_addr, GFP_KERNEL);
if (!lp->init_block) {
if (pcnet32_debug & NETIF_MSG_PROBE)
- pr_err("Consistent memory allocation failed\n");
+ pr_err("Coherent memory allocation failed\n");
ret = -ENOMEM;
goto err_free_netdev;
}
@@ -1998,8 +1990,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
err_free_ring:
pcnet32_free_ring(dev);
- pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
- lp->init_block, lp->init_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev, sizeof(*lp->init_block),
+ lp->init_block, lp->init_dma_addr);
err_free_netdev:
free_netdev(dev);
err_release_region:
@@ -2012,21 +2004,19 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name)
{
struct pcnet32_private *lp = netdev_priv(dev);
- lp->tx_ring = pci_alloc_consistent(lp->pci_dev,
- sizeof(struct pcnet32_tx_head) *
- lp->tx_ring_size,
- &lp->tx_ring_dma_addr);
+ lp->tx_ring = dma_alloc_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+ &lp->tx_ring_dma_addr, GFP_KERNEL);
if (lp->tx_ring == NULL) {
- netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
+ netif_err(lp, drv, dev, "Coherent memory allocation failed\n");
return -ENOMEM;
}
- lp->rx_ring = pci_alloc_consistent(lp->pci_dev,
- sizeof(struct pcnet32_rx_head) *
- lp->rx_ring_size,
- &lp->rx_ring_dma_addr);
+ lp->rx_ring = dma_alloc_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+ &lp->rx_ring_dma_addr, GFP_KERNEL);
if (lp->rx_ring == NULL) {
- netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
+ netif_err(lp, drv, dev, "Coherent memory allocation failed\n");
return -ENOMEM;
}
@@ -2070,18 +2060,16 @@ static void pcnet32_free_ring(struct net_device *dev)
lp->rx_dma_addr = NULL;
if (lp->tx_ring) {
- pci_free_consistent(lp->pci_dev,
- sizeof(struct pcnet32_tx_head) *
- lp->tx_ring_size, lp->tx_ring,
- lp->tx_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+ lp->tx_ring, lp->tx_ring_dma_addr);
lp->tx_ring = NULL;
}
if (lp->rx_ring) {
- pci_free_consistent(lp->pci_dev,
- sizeof(struct pcnet32_rx_head) *
- lp->rx_ring_size, lp->rx_ring,
- lp->rx_ring_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev,
+ sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+ lp->rx_ring, lp->rx_ring_dma_addr);
lp->rx_ring = NULL;
}
}
@@ -2342,12 +2330,11 @@ static void pcnet32_purge_tx_ring(struct net_device *dev)
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->tx_skbuff[i]) {
- if (!pci_dma_mapping_error(lp->pci_dev,
- lp->tx_dma_addr[i]))
- pci_unmap_single(lp->pci_dev,
+ if (!dma_mapping_error(&lp->pci_dev->dev, lp->tx_dma_addr[i]))
+ dma_unmap_single(&lp->pci_dev->dev,
lp->tx_dma_addr[i],
lp->tx_skbuff[i]->len,
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
dev_kfree_skb_any(lp->tx_skbuff[i]);
}
lp->tx_skbuff[i] = NULL;
@@ -2382,10 +2369,9 @@ static int pcnet32_init_ring(struct net_device *dev)
rmb();
if (lp->rx_dma_addr[i] == 0) {
lp->rx_dma_addr[i] =
- pci_map_single(lp->pci_dev, rx_skbuff->data,
- PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(lp->pci_dev,
- lp->rx_dma_addr[i])) {
+ dma_map_single(&lp->pci_dev->dev, rx_skbuff->data,
+ PKT_BUF_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&lp->pci_dev->dev, lp->rx_dma_addr[i])) {
/* there is not much we can do at this point */
netif_err(lp, drv, dev,
"%s pci dma mapping error\n",
@@ -2523,8 +2509,9 @@ static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb,
lp->tx_ring[entry].misc = 0x00000000;
lp->tx_dma_addr[entry] =
- pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(lp->pci_dev, lp->tx_dma_addr[entry])) {
+ dma_map_single(&lp->pci_dev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&lp->pci_dev->dev, lp->tx_dma_addr[entry])) {
dev_kfree_skb_any(skb);
dev->stats.tx_dropped++;
goto drop_packet;
@@ -2913,30 +2900,27 @@ static void pcnet32_watchdog(struct timer_list *t)
mod_timer(&lp->watchdog_timer, round_jiffies(PCNET32_WATCHDOG_TIMEOUT));
}
-static int pcnet32_pm_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused pcnet32_pm_suspend(struct device *device_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(device_d);
if (netif_running(dev)) {
netif_device_detach(dev);
pcnet32_close(dev);
}
- pci_save_state(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
return 0;
}
-static int pcnet32_pm_resume(struct pci_dev *pdev)
+static int __maybe_unused pcnet32_pm_resume(struct device *device_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
+ struct net_device *dev = dev_get_drvdata(device_d);
if (netif_running(dev)) {
pcnet32_open(dev);
netif_device_attach(dev);
}
+
return 0;
}
@@ -2950,20 +2934,23 @@ static void pcnet32_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
pcnet32_free_ring(dev);
release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
- pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
- lp->init_block, lp->init_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev, sizeof(*lp->init_block),
+ lp->init_block, lp->init_dma_addr);
free_netdev(dev);
pci_disable_device(pdev);
}
}
+static SIMPLE_DEV_PM_OPS(pcnet32_pm_ops, pcnet32_pm_suspend, pcnet32_pm_resume);
+
static struct pci_driver pcnet32_driver = {
.name = DRV_NAME,
.probe = pcnet32_probe_pci,
.remove = pcnet32_remove_one,
.id_table = pcnet32_pci_tbl,
- .suspend = pcnet32_pm_suspend,
- .resume = pcnet32_pm_resume,
+ .driver = {
+ .pm = &pcnet32_pm_ops,
+ },
};
/* An additional parameter that may be passed in... */
@@ -3030,8 +3017,8 @@ static void __exit pcnet32_cleanup_module(void)
unregister_netdev(pcnet32_dev);
pcnet32_free_ring(pcnet32_dev);
release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
- pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
- lp->init_block, lp->init_dma_addr);
+ dma_free_coherent(&lp->pci_dev->dev, sizeof(*lp->init_block),
+ lp->init_block, lp->init_dma_addr);
free_netdev(pcnet32_dev);
pcnet32_dev = next_dev;
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index a87264f95f1a..43294a148f8a 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -904,114 +904,40 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
}
}
-static void xgbe_disable_vxlan_offloads(struct xgbe_prv_data *pdata)
+static int xgbe_vxlan_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti)
{
- struct net_device *netdev = pdata->netdev;
-
- if (!pdata->vxlan_offloads_set)
- return;
-
- netdev_info(netdev, "disabling VXLAN offloads\n");
-
- netdev->hw_enc_features &= ~(NETIF_F_SG |
- NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM |
- NETIF_F_RXCSUM |
- NETIF_F_TSO |
- NETIF_F_TSO6 |
- NETIF_F_GRO |
- NETIF_F_GSO_UDP_TUNNEL |
- NETIF_F_GSO_UDP_TUNNEL_CSUM);
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
- netdev->features &= ~(NETIF_F_GSO_UDP_TUNNEL |
- NETIF_F_GSO_UDP_TUNNEL_CSUM);
+ pdata->vxlan_port = be16_to_cpu(ti->port);
+ pdata->hw_if.enable_vxlan(pdata);
- pdata->vxlan_offloads_set = 0;
+ return 0;
}
-static void xgbe_disable_vxlan_hw(struct xgbe_prv_data *pdata)
+static int xgbe_vxlan_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti)
{
- if (!pdata->vxlan_port_set)
- return;
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
pdata->hw_if.disable_vxlan(pdata);
-
- pdata->vxlan_port_set = 0;
pdata->vxlan_port = 0;
-}
-
-static void xgbe_disable_vxlan_accel(struct xgbe_prv_data *pdata)
-{
- xgbe_disable_vxlan_offloads(pdata);
-
- xgbe_disable_vxlan_hw(pdata);
-}
-
-static void xgbe_enable_vxlan_offloads(struct xgbe_prv_data *pdata)
-{
- struct net_device *netdev = pdata->netdev;
-
- if (pdata->vxlan_offloads_set)
- return;
-
- netdev_info(netdev, "enabling VXLAN offloads\n");
-
- netdev->hw_enc_features |= NETIF_F_SG |
- NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM |
- NETIF_F_RXCSUM |
- NETIF_F_TSO |
- NETIF_F_TSO6 |
- NETIF_F_GRO |
- pdata->vxlan_features;
-
- netdev->features |= pdata->vxlan_features;
-
- pdata->vxlan_offloads_set = 1;
-}
-
-static void xgbe_enable_vxlan_hw(struct xgbe_prv_data *pdata)
-{
- struct xgbe_vxlan_data *vdata;
- if (pdata->vxlan_port_set)
- return;
-
- if (list_empty(&pdata->vxlan_ports))
- return;
-
- vdata = list_first_entry(&pdata->vxlan_ports,
- struct xgbe_vxlan_data, list);
-
- pdata->vxlan_port_set = 1;
- pdata->vxlan_port = be16_to_cpu(vdata->port);
-
- pdata->hw_if.enable_vxlan(pdata);
+ return 0;
}
-static void xgbe_enable_vxlan_accel(struct xgbe_prv_data *pdata)
-{
- /* VXLAN acceleration desired? */
- if (!pdata->vxlan_features)
- return;
-
- /* VXLAN acceleration possible? */
- if (pdata->vxlan_force_disable)
- return;
-
- xgbe_enable_vxlan_hw(pdata);
-
- xgbe_enable_vxlan_offloads(pdata);
-}
+static const struct udp_tunnel_nic_info xgbe_udp_tunnels = {
+ .set_port = xgbe_vxlan_set_port,
+ .unset_port = xgbe_vxlan_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
-static void xgbe_reset_vxlan_accel(struct xgbe_prv_data *pdata)
+const struct udp_tunnel_nic_info *xgbe_get_udp_tunnel_info(void)
{
- xgbe_disable_vxlan_hw(pdata);
-
- if (pdata->vxlan_features)
- xgbe_enable_vxlan_offloads(pdata);
-
- pdata->vxlan_force_disable = 0;
+ return &xgbe_udp_tunnels;
}
static void xgbe_napi_enable(struct xgbe_prv_data *pdata, unsigned int add)
@@ -1406,7 +1332,7 @@ static int xgbe_start(struct xgbe_prv_data *pdata)
hw_if->enable_tx(pdata);
hw_if->enable_rx(pdata);
- udp_tunnel_get_rx_info(netdev);
+ udp_tunnel_nic_reset_ntf(netdev);
netif_tx_start_all_queues(netdev);
@@ -1447,7 +1373,7 @@ static void xgbe_stop(struct xgbe_prv_data *pdata)
xgbe_stop_timers(pdata);
flush_workqueue(pdata->dev_workqueue);
- xgbe_reset_vxlan_accel(pdata);
+ xgbe_vxlan_unset_port(netdev, 0, 0, NULL);
hw_if->disable_tx(pdata);
hw_if->disable_rx(pdata);
@@ -1773,13 +1699,8 @@ static int xgbe_prep_tso(struct sk_buff *skb, struct xgbe_packet_data *packet)
return 0;
}
-static bool xgbe_is_vxlan(struct xgbe_prv_data *pdata, struct sk_buff *skb)
+static bool xgbe_is_vxlan(struct sk_buff *skb)
{
- struct xgbe_vxlan_data *vdata;
-
- if (pdata->vxlan_force_disable)
- return false;
-
if (!skb->encapsulation)
return false;
@@ -1801,19 +1722,13 @@ static bool xgbe_is_vxlan(struct xgbe_prv_data *pdata, struct sk_buff *skb)
return false;
}
- /* See if we have the UDP port in our list */
- list_for_each_entry(vdata, &pdata->vxlan_ports, list) {
- if ((skb->protocol == htons(ETH_P_IP)) &&
- (vdata->sa_family == AF_INET) &&
- (vdata->port == udp_hdr(skb)->dest))
- return true;
- else if ((skb->protocol == htons(ETH_P_IPV6)) &&
- (vdata->sa_family == AF_INET6) &&
- (vdata->port == udp_hdr(skb)->dest))
- return true;
- }
+ if (skb->inner_protocol_type != ENCAP_TYPE_ETHER ||
+ skb->inner_protocol != htons(ETH_P_TEB) ||
+ (skb_inner_mac_header(skb) - skb_transport_header(skb) !=
+ sizeof(struct udphdr) + sizeof(struct vxlanhdr)))
+ return false;
- return false;
+ return true;
}
static int xgbe_is_tso(struct sk_buff *skb)
@@ -1864,7 +1779,7 @@ static void xgbe_packet_info(struct xgbe_prv_data *pdata,
XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
CSUM_ENABLE, 1);
- if (xgbe_is_vxlan(pdata, skb))
+ if (xgbe_is_vxlan(skb))
XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
VXLAN, 1);
@@ -2271,23 +2186,12 @@ static netdev_features_t xgbe_fix_features(struct net_device *netdev,
netdev_features_t features)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
- netdev_features_t vxlan_base, vxlan_mask;
+ netdev_features_t vxlan_base;
vxlan_base = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_RX_UDP_TUNNEL_PORT;
- vxlan_mask = vxlan_base | NETIF_F_GSO_UDP_TUNNEL_CSUM;
-
- pdata->vxlan_features = features & vxlan_mask;
- /* Only fix VXLAN-related features */
- if (!pdata->vxlan_features)
- return features;
-
- /* If VXLAN isn't supported then clear any features:
- * This is needed because NETIF_F_RX_UDP_TUNNEL_PORT gets
- * automatically set if ndo_udp_tunnel_add is set.
- */
if (!pdata->hw_feat.vxn)
- return features & ~vxlan_mask;
+ return features;
/* VXLAN CSUM requires VXLAN base */
if ((features & NETIF_F_GSO_UDP_TUNNEL_CSUM) &&
@@ -2318,15 +2222,6 @@ static netdev_features_t xgbe_fix_features(struct net_device *netdev,
}
}
- pdata->vxlan_features = features & vxlan_mask;
-
- /* Adjust UDP Tunnel based on current state */
- if (pdata->vxlan_force_disable) {
- netdev_notice(netdev,
- "VXLAN acceleration disabled, turning off udp tunnel features\n");
- features &= ~vxlan_mask;
- }
-
return features;
}
@@ -2336,14 +2231,12 @@ static int xgbe_set_features(struct net_device *netdev,
struct xgbe_prv_data *pdata = netdev_priv(netdev);
struct xgbe_hw_if *hw_if = &pdata->hw_if;
netdev_features_t rxhash, rxcsum, rxvlan, rxvlan_filter;
- netdev_features_t udp_tunnel;
int ret = 0;
rxhash = pdata->netdev_features & NETIF_F_RXHASH;
rxcsum = pdata->netdev_features & NETIF_F_RXCSUM;
rxvlan = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX;
rxvlan_filter = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_FILTER;
- udp_tunnel = pdata->netdev_features & NETIF_F_GSO_UDP_TUNNEL;
if ((features & NETIF_F_RXHASH) && !rxhash)
ret = hw_if->enable_rss(pdata);
@@ -2367,11 +2260,6 @@ static int xgbe_set_features(struct net_device *netdev,
else if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER) && rxvlan_filter)
hw_if->disable_rx_vlan_filtering(pdata);
- if ((features & NETIF_F_GSO_UDP_TUNNEL) && !udp_tunnel)
- xgbe_enable_vxlan_accel(pdata);
- else if (!(features & NETIF_F_GSO_UDP_TUNNEL) && udp_tunnel)
- xgbe_disable_vxlan_accel(pdata);
-
pdata->netdev_features = features;
DBGPR("<--xgbe_set_features\n");
@@ -2379,101 +2267,6 @@ static int xgbe_set_features(struct net_device *netdev,
return 0;
}
-static void xgbe_udp_tunnel_add(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- struct xgbe_prv_data *pdata = netdev_priv(netdev);
- struct xgbe_vxlan_data *vdata;
-
- if (!pdata->hw_feat.vxn)
- return;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- pdata->vxlan_port_count++;
-
- netif_dbg(pdata, drv, netdev,
- "adding VXLAN tunnel, family=%hx/port=%hx\n",
- ti->sa_family, be16_to_cpu(ti->port));
-
- if (pdata->vxlan_force_disable)
- return;
-
- vdata = kzalloc(sizeof(*vdata), GFP_ATOMIC);
- if (!vdata) {
- /* Can no longer properly track VXLAN ports */
- pdata->vxlan_force_disable = 1;
- netif_dbg(pdata, drv, netdev,
- "internal error, disabling VXLAN accelerations\n");
-
- xgbe_disable_vxlan_accel(pdata);
-
- return;
- }
- vdata->sa_family = ti->sa_family;
- vdata->port = ti->port;
-
- list_add_tail(&vdata->list, &pdata->vxlan_ports);
-
- /* First port added? */
- if (pdata->vxlan_port_count == 1) {
- xgbe_enable_vxlan_accel(pdata);
-
- return;
- }
-}
-
-static void xgbe_udp_tunnel_del(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- struct xgbe_prv_data *pdata = netdev_priv(netdev);
- struct xgbe_vxlan_data *vdata;
-
- if (!pdata->hw_feat.vxn)
- return;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- netif_dbg(pdata, drv, netdev,
- "deleting VXLAN tunnel, family=%hx/port=%hx\n",
- ti->sa_family, be16_to_cpu(ti->port));
-
- /* Don't need safe version since loop terminates with deletion */
- list_for_each_entry(vdata, &pdata->vxlan_ports, list) {
- if (vdata->sa_family != ti->sa_family)
- continue;
-
- if (vdata->port != ti->port)
- continue;
-
- list_del(&vdata->list);
- kfree(vdata);
-
- break;
- }
-
- pdata->vxlan_port_count--;
- if (!pdata->vxlan_port_count) {
- xgbe_reset_vxlan_accel(pdata);
-
- return;
- }
-
- if (pdata->vxlan_force_disable)
- return;
-
- /* See if VXLAN tunnel id needs to be changed */
- vdata = list_first_entry(&pdata->vxlan_ports,
- struct xgbe_vxlan_data, list);
- if (pdata->vxlan_port == be16_to_cpu(vdata->port))
- return;
-
- pdata->vxlan_port = be16_to_cpu(vdata->port);
- pdata->hw_if.set_vxlan_id(pdata);
-}
-
static netdev_features_t xgbe_features_check(struct sk_buff *skb,
struct net_device *netdev,
netdev_features_t features)
@@ -2503,8 +2296,8 @@ static const struct net_device_ops xgbe_netdev_ops = {
.ndo_setup_tc = xgbe_setup_tc,
.ndo_fix_features = xgbe_fix_features,
.ndo_set_features = xgbe_set_features,
- .ndo_udp_tunnel_add = xgbe_udp_tunnel_add,
- .ndo_udp_tunnel_del = xgbe_udp_tunnel_del,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = xgbe_features_check,
};
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index 2a70714a791d..a218dc6f2edd 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -192,7 +192,6 @@ struct xgbe_prv_data *xgbe_alloc_pdata(struct device *dev)
mutex_init(&pdata->i2c_mutex);
init_completion(&pdata->i2c_complete);
init_completion(&pdata->mdio_complete);
- INIT_LIST_HEAD(&pdata->vxlan_ports);
pdata->msg_enable = netif_msg_init(debug, default_msg_level);
@@ -366,17 +365,12 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
NETIF_F_TSO6 |
NETIF_F_GRO |
NETIF_F_GSO_UDP_TUNNEL |
- NETIF_F_GSO_UDP_TUNNEL_CSUM |
- NETIF_F_RX_UDP_TUNNEL_PORT;
+ NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
- NETIF_F_GSO_UDP_TUNNEL_CSUM |
- NETIF_F_RX_UDP_TUNNEL_PORT;
+ NETIF_F_GSO_UDP_TUNNEL_CSUM;
- pdata->vxlan_offloads_set = 1;
- pdata->vxlan_features = NETIF_F_GSO_UDP_TUNNEL |
- NETIF_F_GSO_UDP_TUNNEL_CSUM |
- NETIF_F_RX_UDP_TUNNEL_PORT;
+ netdev->udp_tunnel_nic_info = xgbe_get_udp_tunnel_info();
}
netdev->vlan_features |= NETIF_F_SG |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
index 7b86240ecd5f..90cb55eb5466 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
@@ -421,10 +421,9 @@ static void xgbe_pci_remove(struct pci_dev *pdev)
xgbe_free_pdata(pdata);
}
-#ifdef CONFIG_PM
-static int xgbe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused xgbe_pci_suspend(struct device *dev)
{
- struct xgbe_prv_data *pdata = pci_get_drvdata(pdev);
+ struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
struct net_device *netdev = pdata->netdev;
int ret = 0;
@@ -438,9 +437,9 @@ static int xgbe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
return ret;
}
-static int xgbe_pci_resume(struct pci_dev *pdev)
+static int __maybe_unused xgbe_pci_resume(struct device *dev)
{
- struct xgbe_prv_data *pdata = pci_get_drvdata(pdev);
+ struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
struct net_device *netdev = pdata->netdev;
int ret = 0;
@@ -460,7 +459,6 @@ static int xgbe_pci_resume(struct pci_dev *pdev)
return ret;
}
-#endif /* CONFIG_PM */
static const struct xgbe_version_data xgbe_v2a = {
.init_function_ptrs_phy_impl = xgbe_init_function_ptrs_phy_v2,
@@ -502,15 +500,16 @@ static const struct pci_device_id xgbe_pci_table[] = {
};
MODULE_DEVICE_TABLE(pci, xgbe_pci_table);
+static SIMPLE_DEV_PM_OPS(xgbe_pci_pm_ops, xgbe_pci_suspend, xgbe_pci_resume);
+
static struct pci_driver xgbe_driver = {
.name = XGBE_DRV_NAME,
.id_table = xgbe_pci_table,
.probe = xgbe_pci_probe,
.remove = xgbe_pci_remove,
-#ifdef CONFIG_PM
- .suspend = xgbe_pci_suspend,
- .resume = xgbe_pci_resume,
-#endif
+ .driver = {
+ .pm = &xgbe_pci_pm_ops,
+ }
};
int xgbe_pci_init(void)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index 5897e46faca5..ba8321ec1ee7 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -1014,12 +1014,6 @@ struct xgbe_version_data {
unsigned int an_cdr_workaround;
};
-struct xgbe_vxlan_data {
- struct list_head list;
- sa_family_t sa_family;
- __be16 port;
-};
-
struct xgbe_prv_data {
struct net_device *netdev;
struct pci_dev *pcidev;
@@ -1172,13 +1166,7 @@ struct xgbe_prv_data {
u32 rss_options;
/* VXLAN settings */
- unsigned int vxlan_port_set;
- unsigned int vxlan_offloads_set;
- unsigned int vxlan_force_disable;
- unsigned int vxlan_port_count;
- struct list_head vxlan_ports;
u16 vxlan_port;
- netdev_features_t vxlan_features;
/* Netdev related settings */
unsigned char mac_addr[ETH_ALEN];
@@ -1321,6 +1309,7 @@ void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *);
void xgbe_init_function_ptrs_i2c(struct xgbe_i2c_if *);
const struct net_device_ops *xgbe_get_netdev_ops(void);
const struct ethtool_ops *xgbe_get_ethtool_ops(void);
+const struct udp_tunnel_nic_info *xgbe_get_udp_tunnel_info(void);
#ifdef CONFIG_AMD_XGBE_DCB
const struct dcbnl_rtnl_ops *xgbe_get_dcbnl_ops(void);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_common.h b/drivers/net/ethernet/aquantia/atlantic/aq_common.h
index 52ad9433cabc..23b2d390fcdd 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_common.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_common.h
@@ -58,11 +58,19 @@
#define AQ_NIC_RATE_1G BIT(4)
#define AQ_NIC_RATE_100M BIT(5)
#define AQ_NIC_RATE_10M BIT(6)
+#define AQ_NIC_RATE_1G_HALF BIT(7)
+#define AQ_NIC_RATE_100M_HALF BIT(8)
+#define AQ_NIC_RATE_10M_HALF BIT(9)
-#define AQ_NIC_RATE_EEE_10G BIT(7)
-#define AQ_NIC_RATE_EEE_5G BIT(8)
-#define AQ_NIC_RATE_EEE_2G5 BIT(9)
-#define AQ_NIC_RATE_EEE_1G BIT(10)
-#define AQ_NIC_RATE_EEE_100M BIT(11)
+#define AQ_NIC_RATE_EEE_10G BIT(10)
+#define AQ_NIC_RATE_EEE_5G BIT(11)
+#define AQ_NIC_RATE_EEE_2G5 BIT(12)
+#define AQ_NIC_RATE_EEE_1G BIT(13)
+#define AQ_NIC_RATE_EEE_100M BIT(14)
+#define AQ_NIC_RATE_EEE_MSK (AQ_NIC_RATE_EEE_10G |\
+ AQ_NIC_RATE_EEE_5G |\
+ AQ_NIC_RATE_EEE_2G5 |\
+ AQ_NIC_RATE_EEE_1G |\
+ AQ_NIC_RATE_EEE_100M)
#endif /* AQ_COMMON_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c b/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c
index 6da65099047d..d3526cd38f3d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.c
@@ -1,5 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (C) 2014-2019 aQuantia Corporation. */
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
+ */
/* File aq_drvinfo.c: Definition of common code for firmware info in sys.*/
@@ -12,32 +16,51 @@
#include <linux/uaccess.h>
#include "aq_drvinfo.h"
+#include "aq_nic.h"
#if IS_REACHABLE(CONFIG_HWMON)
+static const char * const atl_temp_label[] = {
+ "PHY Temperature",
+ "MAC Temperature",
+};
+
static int aq_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *value)
{
struct aq_nic_s *aq_nic = dev_get_drvdata(dev);
+ int err = 0;
int temp;
- int err;
if (!aq_nic)
return -EIO;
- if (type != hwmon_temp)
+ if (type != hwmon_temp || attr != hwmon_temp_input)
return -EOPNOTSUPP;
- if (!aq_nic->aq_fw_ops->get_phy_temp)
- return -EOPNOTSUPP;
+ switch (channel) {
+ case 0:
+ if (!aq_nic->aq_fw_ops->get_phy_temp)
+ return -EOPNOTSUPP;
- switch (attr) {
- case hwmon_temp_input:
err = aq_nic->aq_fw_ops->get_phy_temp(aq_nic->aq_hw, &temp);
*value = temp;
- return err;
+ break;
+ case 1:
+ if (!aq_nic->aq_fw_ops->get_mac_temp &&
+ !aq_nic->aq_hw_ops->hw_get_mac_temp)
+ return -EOPNOTSUPP;
+
+ if (aq_nic->aq_fw_ops->get_mac_temp)
+ err = aq_nic->aq_fw_ops->get_mac_temp(aq_nic->aq_hw, &temp);
+ else
+ err = aq_nic->aq_hw_ops->hw_get_mac_temp(aq_nic->aq_hw, &temp);
+ *value = temp;
+ break;
default:
return -EOPNOTSUPP;
}
+
+ return err;
}
static int aq_hwmon_read_string(struct device *dev,
@@ -49,28 +72,32 @@ static int aq_hwmon_read_string(struct device *dev,
if (!aq_nic)
return -EIO;
- if (type != hwmon_temp)
+ if (type != hwmon_temp || attr != hwmon_temp_label)
return -EOPNOTSUPP;
- if (!aq_nic->aq_fw_ops->get_phy_temp)
+ if (channel < ARRAY_SIZE(atl_temp_label))
+ *str = atl_temp_label[channel];
+ else
return -EOPNOTSUPP;
- switch (attr) {
- case hwmon_temp_label:
- *str = "PHY Temperature";
- return 0;
- default:
- return -EOPNOTSUPP;
- }
+ return 0;
}
static umode_t aq_hwmon_is_visible(const void *data,
enum hwmon_sensor_types type,
u32 attr, int channel)
{
+ const struct aq_nic_s *nic = data;
+
if (type != hwmon_temp)
return 0;
+ if (channel == 0 && !nic->aq_fw_ops->get_phy_temp)
+ return 0;
+ else if (channel == 1 && !nic->aq_fw_ops->get_mac_temp &&
+ !nic->aq_hw_ops->hw_get_mac_temp)
+ return 0;
+
switch (attr) {
case hwmon_temp_input:
case hwmon_temp_label:
@@ -88,6 +115,7 @@ static const struct hwmon_ops aq_hwmon_ops = {
static u32 aq_hwmon_temp_config[] = {
HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
0,
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.h b/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.h
index 23a0487893a7..59113a20622a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_drvinfo.h
@@ -1,14 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (C) 2014-2017 aQuantia Corporation. */
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
+ */
/* File aq_drvinfo.h: Declaration of common code for firmware info in sys.*/
#ifndef AQ_DRVINFO_H
#define AQ_DRVINFO_H
-#include "aq_nic.h"
-#include "aq_hw.h"
-#include "hw_atl/hw_atl_utils.h"
+struct net_device;
int aq_drvinfo_init(struct net_device *ndev);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index 743d3b13b39d..1ab5314c4c1b 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_ethtool.c: Definition of ethertool related functions. */
@@ -88,13 +89,19 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
"InDroppedDma",
};
-static const char * const aq_ethtool_queue_stat_names[] = {
+static const char * const aq_ethtool_queue_rx_stat_names[] = {
"%sQueue[%d] InPackets",
- "%sQueue[%d] OutPackets",
- "%sQueue[%d] Restarts",
"%sQueue[%d] InJumboPackets",
"%sQueue[%d] InLroPackets",
"%sQueue[%d] InErrors",
+ "%sQueue[%d] AllocFails",
+ "%sQueue[%d] SkbAllocFails",
+ "%sQueue[%d] Polls",
+};
+
+static const char * const aq_ethtool_queue_tx_stat_names[] = {
+ "%sQueue[%d] OutPackets",
+ "%sQueue[%d] Restarts",
};
#if IS_ENABLED(CONFIG_MACSEC)
@@ -123,21 +130,21 @@ static const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = {
"MACSec OutUnctrlHitDropRedir",
};
-static const char *aq_macsec_txsc_stat_names[] = {
+static const char * const aq_macsec_txsc_stat_names[] = {
"MACSecTXSC%d ProtectedPkts",
"MACSecTXSC%d EncryptedPkts",
"MACSecTXSC%d ProtectedOctets",
"MACSecTXSC%d EncryptedOctets",
};
-static const char *aq_macsec_txsa_stat_names[] = {
+static const char * const aq_macsec_txsa_stat_names[] = {
"MACSecTXSC%dSA%d HitDropRedirect",
"MACSecTXSC%dSA%d Protected2Pkts",
"MACSecTXSC%dSA%d ProtectedPkts",
"MACSecTXSC%dSA%d EncryptedPkts",
};
-static const char *aq_macsec_rxsa_stat_names[] = {
+static const char * const aq_macsec_rxsa_stat_names[] = {
"MACSecRXSC%dSA%d UntaggedHitPkts",
"MACSecRXSC%dSA%d CtrlHitDrpRedir",
"MACSecRXSC%dSA%d NotUsingSa",
@@ -163,11 +170,17 @@ static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
static u32 aq_ethtool_n_stats(struct net_device *ndev)
{
+ const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
+ const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
struct aq_nic_s *nic = netdev_priv(ndev);
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
- ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs *
- cfg->tcs;
+ (rx_stat_cnt + tx_stat_cnt) * cfg->vecs * cfg->tcs;
+
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
+ n_stats += rx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_RX) +
+ tx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
+#endif
#if IS_ENABLED(CONFIG_MACSEC)
if (nic->macsec_cfg) {
@@ -191,6 +204,9 @@ static void aq_ethtool_stats(struct net_device *ndev,
memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
data = aq_nic_get_stats(aq_nic, data);
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
+ data = aq_ptp_get_stats(aq_nic, data);
+#endif
#if IS_ENABLED(CONFIG_MACSEC)
data = aq_macsec_get_stats(aq_nic, data);
#endif
@@ -236,7 +252,8 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
switch (stringset) {
case ETH_SS_STATS: {
- const int stat_cnt = ARRAY_SIZE(aq_ethtool_queue_stat_names);
+ const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
+ const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
char tc_string[8];
int tc;
@@ -250,15 +267,51 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
snprintf(tc_string, 8, "TC%d ", tc);
for (i = 0; i < cfg->vecs; i++) {
- for (si = 0; si < stat_cnt; si++) {
+ for (si = 0; si < rx_stat_cnt; si++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ aq_ethtool_queue_rx_stat_names[si],
+ tc_string,
+ AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
+ p += ETH_GSTRING_LEN;
+ }
+ for (si = 0; si < tx_stat_cnt; si++) {
snprintf(p, ETH_GSTRING_LEN,
- aq_ethtool_queue_stat_names[si],
+ aq_ethtool_queue_tx_stat_names[si],
tc_string,
AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
p += ETH_GSTRING_LEN;
}
}
}
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
+ if (nic->aq_ptp) {
+ const int rx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_RX);
+ const int tx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
+ unsigned int ptp_ring_idx =
+ aq_ptp_ring_idx(nic->aq_nic_cfg.tc_mode);
+
+ snprintf(tc_string, 8, "PTP ");
+
+ for (i = 0; i < max(rx_ring_cnt, tx_ring_cnt); i++) {
+ for (si = 0; si < rx_stat_cnt; si++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ aq_ethtool_queue_rx_stat_names[si],
+ tc_string,
+ i ? PTP_HWST_RING_IDX : ptp_ring_idx);
+ p += ETH_GSTRING_LEN;
+ }
+ if (i >= tx_ring_cnt)
+ continue;
+ for (si = 0; si < tx_stat_cnt; si++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ aq_ethtool_queue_tx_stat_names[si],
+ tc_string,
+ i ? PTP_HWST_RING_IDX : ptp_ring_idx);
+ p += ETH_GSTRING_LEN;
+ }
+ }
+ }
+#endif
#if IS_ENABLED(CONFIG_MACSEC)
if (!nic->macsec_cfg)
break;
@@ -606,21 +659,20 @@ static int aq_ethtool_get_ts_info(struct net_device *ndev,
BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
+#endif
return 0;
}
-static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed)
+static u32 eee_mask_to_ethtool_mask(u32 speed)
{
u32 rate = 0;
if (speed & AQ_NIC_RATE_EEE_10G)
rate |= SUPPORTED_10000baseT_Full;
- if (speed & AQ_NIC_RATE_EEE_2G5)
- rate |= SUPPORTED_2500baseX_Full;
-
if (speed & AQ_NIC_RATE_EEE_1G)
rate |= SUPPORTED_1000baseT_Full;
@@ -656,7 +708,7 @@ static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
eee->eee_enabled = !!eee->advertised;
eee->tx_lpi_enabled = eee->eee_enabled;
- if (eee->advertised & eee->lp_advertised)
+ if ((supported_rates & rate) & AQ_NIC_RATE_EEE_MSK)
eee->eee_active = true;
return 0;
@@ -718,13 +770,12 @@ static void aq_ethtool_get_pauseparam(struct net_device *ndev,
struct ethtool_pauseparam *pause)
{
struct aq_nic_s *aq_nic = netdev_priv(ndev);
- u32 fc = aq_nic->aq_nic_cfg.fc.req;
+ int fc = aq_nic->aq_nic_cfg.fc.req;
pause->autoneg = 0;
pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
-
}
static int aq_ethtool_set_pauseparam(struct net_device *ndev,
@@ -838,6 +889,7 @@ static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
struct aq_nic_s *aq_nic = netdev_priv(ndev);
struct aq_nic_cfg_s *cfg;
u32 priv_flags;
+ int ret = 0;
cfg = aq_nic_get_cfg(aq_nic);
priv_flags = cfg->priv_flags;
@@ -859,10 +911,10 @@ static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
dev_open(ndev, NULL);
}
} else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
- aq_nic_set_loopback(aq_nic);
+ ret = aq_nic_set_loopback(aq_nic);
}
- return 0;
+ return ret;
}
const struct ethtool_ops aq_ethtool_ops = {
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index 992fedbe4ce3..7df74015fbc9 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_hw.h: Declaration of abstract interface for NIC hardware specific
@@ -35,6 +36,8 @@ enum aq_tc_mode {
(AQ_RX_LAST_LOC_FVLANID - AQ_RX_FIRST_LOC_FVLANID + 1U)
#define AQ_RX_QUEUE_NOT_ASSIGNED 0xFFU
+#define AQ_FRAC_PER_NS 0x100000000LL
+
/* Used for rate to Mbps conversion */
#define AQ_MBPS_DIVISOR 125000 /* 1000000 / 8 */
@@ -64,12 +67,16 @@ struct aq_hw_caps_s {
u8 rx_rings;
bool flow_control;
bool is_64_dma;
+ bool op64bit;
u32 quirks;
u32 priv_data_len;
};
struct aq_hw_link_status_s {
unsigned int mbps;
+ bool full_duplex;
+ u32 lp_link_speed_msk;
+ u32 lp_flow_control;
};
struct aq_stats_s {
@@ -327,6 +334,8 @@ struct aq_hw_ops {
int (*hw_set_fc)(struct aq_hw_s *self, u32 fc, u32 tc);
int (*hw_set_loopback)(struct aq_hw_s *self, u32 mode, bool enable);
+
+ int (*hw_get_mac_temp)(struct aq_hw_s *self, u32 *temp);
};
struct aq_fw_ops {
@@ -349,6 +358,8 @@ struct aq_fw_ops {
int (*update_stats)(struct aq_hw_s *self);
+ int (*get_mac_temp)(struct aq_hw_s *self, int *temp);
+
int (*get_phy_temp)(struct aq_hw_s *self, int *temp);
u32 (*get_flow_control)(struct aq_hw_s *self, u32 *fcmode);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
index 342c5179f846..1921741f7311 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_hw_utils.c: Definitions of helper functions used across
@@ -9,6 +10,9 @@
*/
#include "aq_hw_utils.h"
+
+#include <linux/io-64-nonatomic-lo-hi.h>
+
#include "aq_hw.h"
#include "aq_nic.h"
@@ -37,9 +41,8 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg)
{
u32 value = readl(hw->mmio + reg);
- if ((~0U) == value &&
- (~0U) == readl(hw->mmio +
- hw->aq_nic_cfg->aq_hw_caps->hw_alive_check_addr))
+ if (value == U32_MAX &&
+ readl(hw->mmio + hw->aq_nic_cfg->aq_hw_caps->hw_alive_check_addr) == U32_MAX)
aq_utils_obj_set(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG);
return value;
@@ -56,13 +59,28 @@ void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value)
*/
u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg)
{
- u64 value = aq_hw_read_reg(hw, reg);
+ u64 value = U64_MAX;
- value |= (u64)aq_hw_read_reg(hw, reg + 4) << 32;
+ if (hw->aq_nic_cfg->aq_hw_caps->op64bit)
+ value = readq(hw->mmio + reg);
+ else
+ value = lo_hi_readq(hw->mmio + reg);
+
+ if (value == U64_MAX &&
+ readl(hw->mmio + hw->aq_nic_cfg->aq_hw_caps->hw_alive_check_addr) == U32_MAX)
+ aq_utils_obj_set(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG);
return value;
}
+void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value)
+{
+ if (hw->aq_nic_cfg->aq_hw_caps->op64bit)
+ writeq(value, hw->mmio + reg);
+ else
+ lo_hi_writeq(value, hw->mmio + reg);
+}
+
int aq_hw_err_from_flags(struct aq_hw_s *hw)
{
int err = 0;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
index 32aa5f2fb840..ffa6e4067c21 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_hw_utils.h: Declaration of helper functions used across hardware
@@ -33,6 +34,7 @@ u32 aq_hw_read_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, u32 shift);
u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg);
void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value);
u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg);
+void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value);
int aq_hw_err_from_flags(struct aq_hw_s *hw);
int aq_hw_num_tcs(struct aq_hw_s *hw);
int aq_hw_q_per_tc(struct aq_hw_s *hw);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index 8a1da044e908..8f70a3909929 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_main.c: Main file for aQuantia Linux driver. */
@@ -94,10 +95,11 @@ err_exit:
return err;
}
-static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct aq_nic_s *aq_nic = netdev_priv(ndev);
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
if (unlikely(aq_utils_obj_test(&aq_nic->flags, AQ_NIC_PTP_DPATH_UP))) {
/* Hardware adds the Timestamp for PTPv2 802.AS1
* and PTPv2 IPv4 UDP.
@@ -114,6 +116,7 @@ static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
unlikely(eth_hdr(skb)->h_proto == htons(ETH_P_1588)))
return aq_ptp_xmit(aq_nic, skb);
}
+#endif
skb_tx_timestamp(skb);
return aq_nic_xmit(aq_nic, skb);
@@ -222,6 +225,7 @@ static void aq_ndev_set_multicast_settings(struct net_device *ndev)
(void)aq_nic_set_multicast_list(aq_nic, ndev);
}
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
static int aq_ndev_config_hwtstamp(struct aq_nic_s *aq_nic,
struct hwtstamp_config *config)
{
@@ -256,26 +260,31 @@ static int aq_ndev_config_hwtstamp(struct aq_nic_s *aq_nic,
return aq_ptp_hwtstamp_config_set(aq_nic->aq_ptp, config);
}
+#endif
static int aq_ndev_hwtstamp_set(struct aq_nic_s *aq_nic, struct ifreq *ifr)
{
struct hwtstamp_config config;
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
int ret_val;
+#endif
if (!aq_nic->aq_ptp)
return -EOPNOTSUPP;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
-
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
ret_val = aq_ndev_config_hwtstamp(aq_nic, &config);
if (ret_val)
return ret_val;
+#endif
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
}
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
static int aq_ndev_hwtstamp_get(struct aq_nic_s *aq_nic, struct ifreq *ifr)
{
struct hwtstamp_config config;
@@ -287,6 +296,7 @@ static int aq_ndev_hwtstamp_get(struct aq_nic_s *aq_nic, struct ifreq *ifr)
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
}
+#endif
static int aq_ndev_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
@@ -296,8 +306,10 @@ static int aq_ndev_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
case SIOCSHWTSTAMP:
return aq_ndev_hwtstamp_set(aq_nic, ifr);
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
case SIOCGHWTSTAMP:
return aq_ndev_hwtstamp_get(aq_nic, ifr);
+#endif
}
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 7c7bf6bf163f..c6bdf1d677d1 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -371,7 +371,7 @@ void aq_nic_ndev_init(struct aq_nic_s *self)
self->ndev->features = aq_hw_caps->hw_features;
self->ndev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
NETIF_F_RXHASH | NETIF_F_SG |
- NETIF_F_LRO | NETIF_F_TSO;
+ NETIF_F_LRO | NETIF_F_TSO | NETIF_F_TSO6;
self->ndev->gso_partial_features = NETIF_F_GSO_UDP_L4;
self->ndev->priv_flags = aq_hw_caps->hw_priv_flags;
self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
@@ -916,13 +916,13 @@ u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
aq_vec && self->aq_vecs > i;
++i, aq_vec = self->aq_vec[i]) {
data += count;
- aq_vec_get_sw_stats(aq_vec, tc, data, &count);
+ count = aq_vec_get_sw_stats(aq_vec, tc, data);
}
}
data += count;
-err_exit:;
+err_exit:
return data;
}
@@ -944,12 +944,17 @@ static void aq_nic_update_ndev_stats(struct aq_nic_s *self)
void aq_nic_get_link_ksettings(struct aq_nic_s *self,
struct ethtool_link_ksettings *cmd)
{
+ u32 lp_link_speed_msk;
+
if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE)
cmd->base.port = PORT_FIBRE;
else
cmd->base.port = PORT_TP;
- /* This driver supports only 10G capable adapters, so DUPLEX_FULL */
- cmd->base.duplex = DUPLEX_FULL;
+
+ cmd->base.duplex = DUPLEX_UNKNOWN;
+ if (self->link_status.mbps)
+ cmd->base.duplex = self->link_status.full_duplex ?
+ DUPLEX_FULL : DUPLEX_HALF;
cmd->base.autoneg = self->aq_nic_cfg.is_autoneg;
ethtool_link_ksettings_zero_link_mode(cmd, supported);
@@ -970,14 +975,26 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
ethtool_link_ksettings_add_link_mode(cmd, supported,
1000baseT_Full);
+ if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_1G_HALF)
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 1000baseT_Half);
+
if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_100M)
ethtool_link_ksettings_add_link_mode(cmd, supported,
100baseT_Full);
+ if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_100M_HALF)
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 100baseT_Half);
+
if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_10M)
ethtool_link_ksettings_add_link_mode(cmd, supported,
10baseT_Full);
+ if (self->aq_nic_cfg.aq_hw_caps->link_speed_msk & AQ_NIC_RATE_10M_HALF)
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 10baseT_Half);
+
if (self->aq_nic_cfg.aq_hw_caps->flow_control) {
ethtool_link_ksettings_add_link_mode(cmd, supported,
Pause);
@@ -997,30 +1014,42 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
if (self->aq_nic_cfg.is_autoneg)
ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
- if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_10G)
+ if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_10G)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
10000baseT_Full);
- if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_5G)
+ if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_5G)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
5000baseT_Full);
- if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_2G5)
+ if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_2G5)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
2500baseT_Full);
- if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_1G)
+ if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_1G)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
1000baseT_Full);
- if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_100M)
+ if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_1G_HALF)
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 1000baseT_Half);
+
+ if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_100M)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
100baseT_Full);
- if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_10M)
+ if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_100M_HALF)
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 100baseT_Half);
+
+ if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_10M)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
10baseT_Full);
+ if (self->aq_nic_cfg.link_speed_msk & AQ_NIC_RATE_10M_HALF)
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 10baseT_Half);
+
if (self->aq_nic_cfg.fc.cur & AQ_NIC_FC_RX)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
Pause);
@@ -1035,32 +1064,84 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
else
ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
+
+ ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising);
+ lp_link_speed_msk = self->aq_hw->aq_link_status.lp_link_speed_msk;
+
+ if (lp_link_speed_msk & AQ_NIC_RATE_10G)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ 10000baseT_Full);
+
+ if (lp_link_speed_msk & AQ_NIC_RATE_5G)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ 5000baseT_Full);
+
+ if (lp_link_speed_msk & AQ_NIC_RATE_2G5)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ 2500baseT_Full);
+
+ if (lp_link_speed_msk & AQ_NIC_RATE_1G)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ 1000baseT_Full);
+
+ if (lp_link_speed_msk & AQ_NIC_RATE_1G_HALF)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ 1000baseT_Half);
+
+ if (lp_link_speed_msk & AQ_NIC_RATE_100M)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ 100baseT_Full);
+
+ if (lp_link_speed_msk & AQ_NIC_RATE_100M_HALF)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ 100baseT_Half);
+
+ if (lp_link_speed_msk & AQ_NIC_RATE_10M)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ 10baseT_Full);
+
+ if (lp_link_speed_msk & AQ_NIC_RATE_10M_HALF)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ 10baseT_Half);
+
+ if (self->aq_hw->aq_link_status.lp_flow_control & AQ_NIC_FC_RX)
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ Pause);
+ if (!!(self->aq_hw->aq_link_status.lp_flow_control & AQ_NIC_FC_TX) ^
+ !!(self->aq_hw->aq_link_status.lp_flow_control & AQ_NIC_FC_RX))
+ ethtool_link_ksettings_add_link_mode(cmd, lp_advertising,
+ Asym_Pause);
}
int aq_nic_set_link_ksettings(struct aq_nic_s *self,
const struct ethtool_link_ksettings *cmd)
{
- u32 speed = 0U;
+ int fduplex = (cmd->base.duplex == DUPLEX_FULL);
+ u32 speed = cmd->base.speed;
u32 rate = 0U;
int err = 0;
+ if (!fduplex && speed > SPEED_1000) {
+ err = -EINVAL;
+ goto err_exit;
+ }
+
if (cmd->base.autoneg == AUTONEG_ENABLE) {
rate = self->aq_nic_cfg.aq_hw_caps->link_speed_msk;
self->aq_nic_cfg.is_autoneg = true;
} else {
- speed = cmd->base.speed;
-
switch (speed) {
case SPEED_10:
- rate = AQ_NIC_RATE_10M;
+ rate = fduplex ? AQ_NIC_RATE_10M : AQ_NIC_RATE_10M_HALF;
break;
case SPEED_100:
- rate = AQ_NIC_RATE_100M;
+ rate = fduplex ? AQ_NIC_RATE_100M
+ : AQ_NIC_RATE_100M_HALF;
break;
case SPEED_1000:
- rate = AQ_NIC_RATE_1G;
+ rate = fduplex ? AQ_NIC_RATE_1G : AQ_NIC_RATE_1G_HALF;
break;
case SPEED_2500:
@@ -1116,7 +1197,7 @@ int aq_nic_set_loopback(struct aq_nic_s *self)
if (!self->aq_hw_ops->hw_set_loopback ||
!self->aq_fw_ops->set_phyloopback)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
mutex_lock(&self->fwreq_mutex);
self->aq_hw_ops->hw_set_loopback(self->aq_hw,
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
index 439ce9692dac..eb7d8430f2f5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_nic.h: Declaration of common code for NIC. */
@@ -113,7 +114,7 @@ struct aq_hw_rx_fltrs_s {
u16 active_filters;
struct aq_hw_rx_fl2 fl2;
struct aq_hw_rx_fl3l4 fl3l4;
- /*filter ether type */
+ /* filter ether type */
u8 fet_reserved_count;
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
index 41c0f560f95b..59253846e885 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_pci_func.c: Definition of PCI functions. */
@@ -114,7 +115,7 @@ static int aq_pci_probe_get_hw_by_id(struct pci_dev *pdev,
return 0;
}
-int aq_pci_func_init(struct pci_dev *pdev)
+static int aq_pci_func_init(struct pci_dev *pdev)
{
int err;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.h b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.h
index 77be7ee0d7b3..3fa5f7a73680 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_pci_func.h: Declaration of PCI functions. */
@@ -19,7 +20,6 @@ struct aq_board_revision_s {
const struct aq_hw_caps_s *caps;
};
-int aq_pci_func_init(struct pci_dev *pdev);
int aq_pci_func_alloc_irq(struct aq_nic_s *self, unsigned int i,
char *name, irq_handler_t irq_handler,
void *irq_arg, cpumask_t *affinity_mask);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c
index 599ced261b2a..06de19f63287 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Aquantia Corporation Network Driver
- * Copyright (C) 2014-2019 Aquantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_ptp.c:
@@ -18,6 +20,8 @@
#include "aq_phy.h"
#include "aq_filters.h"
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
+
#define AQ_PTP_TX_TIMEOUT (HZ * 10)
#define POLL_SYNC_TIMER_MS 15
@@ -77,6 +81,8 @@ struct aq_ptp_s {
bool extts_pin_enabled;
u64 last_sync1588_ts;
+
+ bool a1_ptp;
};
struct ptp_tm_offset {
@@ -778,8 +784,10 @@ int aq_ptp_xmit(struct aq_nic_s *aq_nic, struct sk_buff *skb)
err = aq_nic->aq_hw_ops->hw_ring_tx_xmit(aq_nic->aq_hw,
ring, frags);
if (err >= 0) {
+ u64_stats_update_begin(&ring->stats.tx.syncp);
++ring->stats.tx.packets;
ring->stats.tx.bytes += skb->len;
+ u64_stats_update_end(&ring->stats.tx.syncp);
}
} else {
err = NETDEV_TX_BUSY;
@@ -840,7 +848,7 @@ int aq_ptp_ring_init(struct aq_nic_s *aq_nic)
if (!aq_ptp)
return 0;
- err = aq_ring_init(&aq_ptp->ptp_tx);
+ err = aq_ring_init(&aq_ptp->ptp_tx, ATL_RING_TX);
if (err < 0)
goto err_exit;
err = aq_nic->aq_hw_ops->hw_ring_tx_init(aq_nic->aq_hw,
@@ -849,7 +857,7 @@ int aq_ptp_ring_init(struct aq_nic_s *aq_nic)
if (err < 0)
goto err_exit;
- err = aq_ring_init(&aq_ptp->ptp_rx);
+ err = aq_ring_init(&aq_ptp->ptp_rx, ATL_RING_RX);
if (err < 0)
goto err_exit;
err = aq_nic->aq_hw_ops->hw_ring_rx_init(aq_nic->aq_hw,
@@ -867,7 +875,7 @@ int aq_ptp_ring_init(struct aq_nic_s *aq_nic)
if (err < 0)
goto err_rx_free;
- err = aq_ring_init(&aq_ptp->hwts_rx);
+ err = aq_ring_init(&aq_ptp->hwts_rx, ATL_RING_RX);
if (err < 0)
goto err_rx_free;
err = aq_nic->aq_hw_ops->hw_ring_rx_init(aq_nic->aq_hw,
@@ -941,21 +949,6 @@ void aq_ptp_ring_deinit(struct aq_nic_s *aq_nic)
aq_ring_rx_deinit(&aq_ptp->ptp_rx);
}
-#define PTP_8TC_RING_IDX 8
-#define PTP_4TC_RING_IDX 16
-#define PTP_HWST_RING_IDX 31
-
-/* Index must be 8 (8 TCs) or 16 (4 TCs).
- * It depends on Traffic Class mode.
- */
-static unsigned int ptp_ring_idx(const enum aq_tc_mode tc_mode)
-{
- if (tc_mode == AQ_TC_MODE_8TCS)
- return PTP_8TC_RING_IDX;
-
- return PTP_4TC_RING_IDX;
-}
-
int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
{
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
@@ -967,7 +960,7 @@ int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
if (!aq_ptp)
return 0;
- tx_ring_idx = ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);
+ tx_ring_idx = aq_ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);
ring = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic,
tx_ring_idx, &aq_nic->aq_nic_cfg);
@@ -976,7 +969,7 @@ int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
goto err_exit;
}
- rx_ring_idx = ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);
+ rx_ring_idx = aq_ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);
ring = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic,
rx_ring_idx, &aq_nic->aq_nic_cfg);
@@ -1168,11 +1161,17 @@ static void aq_ptp_poll_sync_work_cb(struct work_struct *w);
int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
{
+ bool a1_ptp = ATL_HW_IS_CHIP_FEATURE(aq_nic->aq_hw, ATLANTIC);
struct hw_atl_utils_mbox mbox;
struct ptp_clock *clock;
struct aq_ptp_s *aq_ptp;
int err = 0;
+ if (!a1_ptp) {
+ aq_nic->aq_ptp = NULL;
+ return 0;
+ }
+
if (!aq_nic->aq_hw_ops->hw_get_ptp_ts) {
aq_nic->aq_ptp = NULL;
return 0;
@@ -1199,6 +1198,7 @@ int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
}
aq_ptp->aq_nic = aq_nic;
+ aq_ptp->a1_ptp = a1_ptp;
spin_lock_init(&aq_ptp->ptp_lock);
spin_lock_init(&aq_ptp->ptp_ring_lock);
@@ -1389,3 +1389,36 @@ static void aq_ptp_poll_sync_work_cb(struct work_struct *w)
schedule_delayed_work(&aq_ptp->poll_sync, timeout);
}
}
+
+int aq_ptp_get_ring_cnt(struct aq_nic_s *aq_nic, const enum atl_ring_type ring_type)
+{
+ if (!aq_nic->aq_ptp)
+ return 0;
+
+ /* Additional RX ring is allocated for PTP HWTS on A1 */
+ return (aq_nic->aq_ptp->a1_ptp && ring_type == ATL_RING_RX) ? 2 : 1;
+}
+
+u64 *aq_ptp_get_stats(struct aq_nic_s *aq_nic, u64 *data)
+{
+ struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
+ unsigned int count = 0U;
+
+ if (!aq_ptp)
+ return data;
+
+ count = aq_ring_fill_stats_data(&aq_ptp->ptp_rx, data);
+ data += count;
+ count = aq_ring_fill_stats_data(&aq_ptp->ptp_tx, data);
+ data += count;
+
+ if (aq_ptp->a1_ptp) {
+ /* Only Receive ring for HWTS */
+ count = aq_ring_fill_stats_data(&aq_ptp->hwts_rx, data);
+ data += count;
+ }
+
+ return data;
+}
+
+#endif
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h
index 231906431a48..28ccb7ca2df9 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Aquantia Corporation Network Driver
- * Copyright (C) 2014-2019 Aquantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_ptp.h: Declaration of PTP functions.
@@ -10,6 +12,23 @@
#include <linux/net_tstamp.h>
+#include "aq_ring.h"
+
+#define PTP_8TC_RING_IDX 8
+#define PTP_4TC_RING_IDX 16
+#define PTP_HWST_RING_IDX 31
+
+/* Index must to be 8 (8 TCs) or 16 (4 TCs).
+ * It depends from Traffic Class mode.
+ */
+static inline unsigned int aq_ptp_ring_idx(const enum aq_tc_mode tc_mode)
+{
+ if (tc_mode == AQ_TC_MODE_8TCS)
+ return PTP_8TC_RING_IDX;
+
+ return PTP_4TC_RING_IDX;
+}
+
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
/* Common functions */
@@ -55,6 +74,10 @@ struct ptp_clock *aq_ptp_get_ptp_clock(struct aq_ptp_s *aq_ptp);
int aq_ptp_link_change(struct aq_nic_s *aq_nic);
+/* PTP ring statistics */
+int aq_ptp_get_ring_cnt(struct aq_nic_s *aq_nic, const enum atl_ring_type ring_type);
+u64 *aq_ptp_get_stats(struct aq_nic_s *aq_nic, u64 *data);
+
#else
static inline int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 68fdb3994088..4f913658eea4 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_ring.c: Definition of functions for Rx/Tx rings. */
@@ -69,24 +70,35 @@ static int aq_get_rxpages(struct aq_ring_s *self, struct aq_ring_buff_s *rxbuf,
rxbuf->rxdata.pg_off += AQ_CFG_RX_FRAME_MAX;
if (rxbuf->rxdata.pg_off + AQ_CFG_RX_FRAME_MAX <=
(PAGE_SIZE << order)) {
+ u64_stats_update_begin(&self->stats.rx.syncp);
self->stats.rx.pg_flips++;
+ u64_stats_update_end(&self->stats.rx.syncp);
} else {
/* Buffer exhausted. We have other users and
* should release this page and realloc
*/
aq_free_rxpage(&rxbuf->rxdata,
aq_nic_get_dev(self->aq_nic));
+ u64_stats_update_begin(&self->stats.rx.syncp);
self->stats.rx.pg_losts++;
+ u64_stats_update_end(&self->stats.rx.syncp);
}
} else {
rxbuf->rxdata.pg_off = 0;
+ u64_stats_update_begin(&self->stats.rx.syncp);
self->stats.rx.pg_reuses++;
+ u64_stats_update_end(&self->stats.rx.syncp);
}
}
if (!rxbuf->rxdata.page) {
ret = aq_get_rxpage(&rxbuf->rxdata, order,
aq_nic_get_dev(self->aq_nic));
+ if (ret) {
+ u64_stats_update_begin(&self->stats.rx.syncp);
+ self->stats.rx.alloc_fails++;
+ u64_stats_update_end(&self->stats.rx.syncp);
+ }
return ret;
}
@@ -205,11 +217,17 @@ aq_ring_hwts_rx_alloc(struct aq_ring_s *self, struct aq_nic_s *aq_nic,
return self;
}
-int aq_ring_init(struct aq_ring_s *self)
+int aq_ring_init(struct aq_ring_s *self, const enum atl_ring_type ring_type)
{
self->hw_head = 0;
self->sw_head = 0;
self->sw_tail = 0;
+ self->ring_type = ring_type;
+
+ if (self->ring_type == ATL_RING_RX)
+ u64_stats_init(&self->stats.rx.syncp);
+ else
+ u64_stats_init(&self->stats.tx.syncp);
return 0;
}
@@ -237,7 +255,9 @@ void aq_ring_queue_wake(struct aq_ring_s *ring)
ring->idx))) {
netif_wake_subqueue(ndev,
AQ_NIC_RING2QMAP(ring->aq_nic, ring->idx));
+ u64_stats_update_begin(&ring->stats.tx.syncp);
ring->stats.tx.queue_restarts++;
+ u64_stats_update_end(&ring->stats.tx.syncp);
}
}
@@ -279,8 +299,10 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
}
if (unlikely(buff->is_eop)) {
- ++self->stats.rx.packets;
+ u64_stats_update_begin(&self->stats.tx.syncp);
+ ++self->stats.tx.packets;
self->stats.tx.bytes += buff->skb->len;
+ u64_stats_update_end(&self->stats.tx.syncp);
dev_kfree_skb_any(buff->skb);
}
@@ -300,7 +322,9 @@ static void aq_rx_checksum(struct aq_ring_s *self,
return;
if (unlikely(buff->is_cso_err)) {
+ u64_stats_update_begin(&self->stats.rx.syncp);
++self->stats.rx.errors;
+ u64_stats_update_end(&self->stats.rx.syncp);
skb->ip_summed = CHECKSUM_NONE;
return;
}
@@ -370,13 +394,17 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
buff_->is_cleaned = true;
} while (!buff_->is_eop);
+ u64_stats_update_begin(&self->stats.rx.syncp);
++self->stats.rx.errors;
+ u64_stats_update_end(&self->stats.rx.syncp);
continue;
}
}
if (buff->is_error) {
+ u64_stats_update_begin(&self->stats.rx.syncp);
++self->stats.rx.errors;
+ u64_stats_update_end(&self->stats.rx.syncp);
continue;
}
@@ -391,6 +419,9 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
skb = build_skb(aq_buf_vaddr(&buff->rxdata),
AQ_CFG_RX_FRAME_MAX);
if (unlikely(!skb)) {
+ u64_stats_update_begin(&self->stats.rx.syncp);
+ self->stats.rx.skb_alloc_fails++;
+ u64_stats_update_end(&self->stats.rx.syncp);
err = -ENOMEM;
goto err_exit;
}
@@ -404,6 +435,9 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
} else {
skb = napi_alloc_skb(napi, AQ_CFG_RX_HDR_SIZE);
if (unlikely(!skb)) {
+ u64_stats_update_begin(&self->stats.rx.syncp);
+ self->stats.rx.skb_alloc_fails++;
+ u64_stats_update_end(&self->stats.rx.syncp);
err = -ENOMEM;
goto err_exit;
}
@@ -477,8 +511,10 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
: AQ_NIC_RING2QMAP(self->aq_nic,
self->idx));
+ u64_stats_update_begin(&self->stats.rx.syncp);
++self->stats.rx.packets;
self->stats.rx.bytes += skb->len;
+ u64_stats_update_end(&self->stats.rx.syncp);
napi_gro_receive(napi, skb);
}
@@ -489,6 +525,7 @@ err_exit:
void aq_ring_hwts_rx_clean(struct aq_ring_s *self, struct aq_nic_s *aq_nic)
{
+#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
while (self->sw_head != self->hw_head) {
u64 ns;
@@ -500,6 +537,7 @@ void aq_ring_hwts_rx_clean(struct aq_ring_s *self, struct aq_nic_s *aq_nic)
self->sw_head = aq_ring_next_dx(self, self->sw_head);
}
+#endif
}
int aq_ring_rx_fill(struct aq_ring_s *self)
@@ -535,7 +573,7 @@ err_exit:
void aq_ring_rx_deinit(struct aq_ring_s *self)
{
if (!self)
- goto err_exit;
+ return;
for (; self->sw_head != self->sw_tail;
self->sw_head = aq_ring_next_dx(self, self->sw_head)) {
@@ -543,14 +581,12 @@ void aq_ring_rx_deinit(struct aq_ring_s *self)
aq_free_rxpage(&buff->rxdata, aq_nic_get_dev(self->aq_nic));
}
-
-err_exit:;
}
void aq_ring_free(struct aq_ring_s *self)
{
if (!self)
- goto err_exit;
+ return;
kfree(self->buff_ring);
@@ -558,6 +594,35 @@ void aq_ring_free(struct aq_ring_s *self)
dma_free_coherent(aq_nic_get_dev(self->aq_nic),
self->size * self->dx_size, self->dx_ring,
self->dx_ring_pa);
+}
+
+unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data)
+{
+ unsigned int count;
+ unsigned int start;
+
+ if (self->ring_type == ATL_RING_RX) {
+ /* This data should mimic aq_ethtool_queue_rx_stat_names structure */
+ do {
+ count = 0;
+ start = u64_stats_fetch_begin_irq(&self->stats.rx.syncp);
+ data[count] = self->stats.rx.packets;
+ data[++count] = self->stats.rx.jumbo_packets;
+ data[++count] = self->stats.rx.lro_packets;
+ data[++count] = self->stats.rx.errors;
+ data[++count] = self->stats.rx.alloc_fails;
+ data[++count] = self->stats.rx.skb_alloc_fails;
+ data[++count] = self->stats.rx.polls;
+ } while (u64_stats_fetch_retry_irq(&self->stats.rx.syncp, start));
+ } else {
+ /* This data should mimic aq_ethtool_queue_tx_stat_names structure */
+ do {
+ count = 0;
+ start = u64_stats_fetch_begin_irq(&self->stats.tx.syncp);
+ data[count] = self->stats.tx.packets;
+ data[++count] = self->stats.tx.queue_restarts;
+ } while (u64_stats_fetch_retry_irq(&self->stats.tx.syncp, start));
+ }
-err_exit:;
+ return ++count;
}
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
index 2c96f20f6289..93659e58f1ce 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_ring.h: Declaration of functions for Rx/Tx rings. */
@@ -88,17 +89,22 @@ struct __packed aq_ring_buff_s {
};
struct aq_ring_stats_rx_s {
+ struct u64_stats_sync syncp; /* must be first */
u64 errors;
u64 packets;
u64 bytes;
u64 lro_packets;
u64 jumbo_packets;
+ u64 alloc_fails;
+ u64 skb_alloc_fails;
+ u64 polls;
u64 pg_losts;
u64 pg_flips;
u64 pg_reuses;
};
struct aq_ring_stats_tx_s {
+ struct u64_stats_sync syncp; /* must be first */
u64 errors;
u64 packets;
u64 bytes;
@@ -110,6 +116,11 @@ union aq_ring_stats_s {
struct aq_ring_stats_tx_s tx;
};
+enum atl_ring_type {
+ ATL_RING_TX,
+ ATL_RING_RX,
+};
+
struct aq_ring_s {
struct aq_ring_buff_s *buff_ring;
u8 *dx_ring; /* descriptors ring, dma shared mem */
@@ -124,6 +135,7 @@ struct aq_ring_s {
unsigned int page_order;
union aq_ring_stats_s stats;
dma_addr_t dx_ring_pa;
+ enum atl_ring_type ring_type;
};
struct aq_ring_param_s {
@@ -163,7 +175,7 @@ struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self,
struct aq_nic_s *aq_nic,
unsigned int idx,
struct aq_nic_cfg_s *aq_nic_cfg);
-int aq_ring_init(struct aq_ring_s *self);
+int aq_ring_init(struct aq_ring_s *self, const enum atl_ring_type ring_type);
void aq_ring_rx_deinit(struct aq_ring_s *self);
void aq_ring_free(struct aq_ring_s *self);
void aq_ring_update_queue_state(struct aq_ring_s *ring);
@@ -181,4 +193,6 @@ struct aq_ring_s *aq_ring_hwts_rx_alloc(struct aq_ring_s *self,
unsigned int size, unsigned int dx_size);
void aq_ring_hwts_rx_clean(struct aq_ring_s *self, struct aq_nic_s *aq_nic);
+unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data);
+
#endif /* AQ_RING_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
index d1d43c8ce400..d281322d7dd2 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_vec.c: Definition of common structure for vector of Rx and Tx rings.
@@ -44,6 +45,9 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
} else {
for (i = 0U, ring = self->ring[0];
self->tx_rings > i; ++i, ring = self->ring[i]) {
+ u64_stats_update_begin(&ring[AQ_VEC_RX_ID].stats.rx.syncp);
+ ring[AQ_VEC_RX_ID].stats.rx.polls++;
+ u64_stats_update_end(&ring[AQ_VEC_RX_ID].stats.rx.syncp);
if (self->aq_hw_ops->hw_ring_tx_head_update) {
err = self->aq_hw_ops->hw_ring_tx_head_update(
self->aq_hw,
@@ -180,7 +184,7 @@ int aq_vec_init(struct aq_vec_s *self, const struct aq_hw_ops *aq_hw_ops,
for (i = 0U, ring = self->ring[0];
self->tx_rings > i; ++i, ring = self->ring[i]) {
- err = aq_ring_init(&ring[AQ_VEC_TX_ID]);
+ err = aq_ring_init(&ring[AQ_VEC_TX_ID], ATL_RING_TX);
if (err < 0)
goto err_exit;
@@ -190,7 +194,7 @@ int aq_vec_init(struct aq_vec_s *self, const struct aq_hw_ops *aq_hw_ops,
if (err < 0)
goto err_exit;
- err = aq_ring_init(&ring[AQ_VEC_RX_ID]);
+ err = aq_ring_init(&ring[AQ_VEC_RX_ID], ATL_RING_RX);
if (err < 0)
goto err_exit;
@@ -349,59 +353,23 @@ cpumask_t *aq_vec_get_affinity_mask(struct aq_vec_s *self)
return &self->aq_ring_param.affinity_mask;
}
-static void aq_vec_add_stats(struct aq_vec_s *self,
- const unsigned int tc,
- struct aq_ring_stats_rx_s *stats_rx,
- struct aq_ring_stats_tx_s *stats_tx)
+bool aq_vec_is_valid_tc(struct aq_vec_s *self, const unsigned int tc)
{
- struct aq_ring_s *ring = self->ring[tc];
-
- if (tc < self->rx_rings) {
- struct aq_ring_stats_rx_s *rx = &ring[AQ_VEC_RX_ID].stats.rx;
-
- stats_rx->packets += rx->packets;
- stats_rx->bytes += rx->bytes;
- stats_rx->errors += rx->errors;
- stats_rx->jumbo_packets += rx->jumbo_packets;
- stats_rx->lro_packets += rx->lro_packets;
- stats_rx->pg_losts += rx->pg_losts;
- stats_rx->pg_flips += rx->pg_flips;
- stats_rx->pg_reuses += rx->pg_reuses;
- }
-
- if (tc < self->tx_rings) {
- struct aq_ring_stats_tx_s *tx = &ring[AQ_VEC_TX_ID].stats.tx;
-
- stats_tx->packets += tx->packets;
- stats_tx->bytes += tx->bytes;
- stats_tx->errors += tx->errors;
- stats_tx->queue_restarts += tx->queue_restarts;
- }
+ return tc < self->rx_rings && tc < self->tx_rings;
}
-int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u64 *data,
- unsigned int *p_count)
+unsigned int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u64 *data)
{
- struct aq_ring_stats_rx_s stats_rx;
- struct aq_ring_stats_tx_s stats_tx;
- unsigned int count = 0U;
-
- memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
- memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
-
- aq_vec_add_stats(self, tc, &stats_rx, &stats_tx);
+ unsigned int count;
- /* This data should mimic aq_ethtool_queue_stat_names structure
- */
- data[count] += stats_rx.packets;
- data[++count] += stats_tx.packets;
- data[++count] += stats_tx.queue_restarts;
- data[++count] += stats_rx.jumbo_packets;
- data[++count] += stats_rx.lro_packets;
- data[++count] += stats_rx.errors;
+ WARN_ONCE(!aq_vec_is_valid_tc(self, tc),
+ "Invalid tc %u (#rx=%u, #tx=%u)\n",
+ tc, self->rx_rings, self->tx_rings);
+ if (!aq_vec_is_valid_tc(self, tc))
+ return 0;
- if (p_count)
- *p_count = ++count;
+ count = aq_ring_fill_stats_data(&self->ring[tc][AQ_VEC_RX_ID], data);
+ count += aq_ring_fill_stats_data(&self->ring[tc][AQ_VEC_TX_ID], data + count);
- return 0;
+ return count;
}
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.h b/drivers/net/ethernet/aquantia/atlantic/aq_vec.h
index 541af85e6510..567f3d4b79a2 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File aq_vec.h: Definition of common structures for vector of Rx and Tx rings.
@@ -35,7 +36,7 @@ void aq_vec_ring_free(struct aq_vec_s *self);
int aq_vec_start(struct aq_vec_s *self);
void aq_vec_stop(struct aq_vec_s *self);
cpumask_t *aq_vec_get_affinity_mask(struct aq_vec_s *self);
-int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u64 *data,
- unsigned int *p_count);
+bool aq_vec_is_valid_tc(struct aq_vec_s *self, const unsigned int tc);
+unsigned int aq_vec_get_sw_stats(struct aq_vec_s *self, const unsigned int tc, u64 *data);
#endif /* AQ_VEC_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index a312864969af..611875ef2cd1 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -16,32 +16,35 @@
#include "hw_atl_llh.h"
#include "hw_atl_a0_internal.h"
-#define DEFAULT_A0_BOARD_BASIC_CAPABILITIES \
- .is_64_dma = true, \
- .msix_irqs = 4U, \
- .irq_mask = ~0U, \
- .vecs = HW_ATL_A0_RSS_MAX, \
- .tcs_max = HW_ATL_A0_TC_MAX, \
- .rxd_alignment = 1U, \
- .rxd_size = HW_ATL_A0_RXD_SIZE, \
- .rxds_max = HW_ATL_A0_MAX_RXD, \
- .rxds_min = HW_ATL_A0_MIN_RXD, \
- .txd_alignment = 1U, \
- .txd_size = HW_ATL_A0_TXD_SIZE, \
- .txds_max = HW_ATL_A0_MAX_TXD, \
- .txds_min = HW_ATL_A0_MIN_RXD, \
- .txhwb_alignment = 4096U, \
- .tx_rings = HW_ATL_A0_TX_RINGS, \
- .rx_rings = HW_ATL_A0_RX_RINGS, \
- .hw_features = NETIF_F_HW_CSUM | \
- NETIF_F_RXHASH | \
- NETIF_F_RXCSUM | \
- NETIF_F_SG | \
- NETIF_F_TSO, \
- .hw_priv_flags = IFF_UNICAST_FLT, \
- .flow_control = true, \
- .mtu = HW_ATL_A0_MTU_JUMBO, \
- .mac_regs_count = 88, \
+#define DEFAULT_A0_BOARD_BASIC_CAPABILITIES \
+ .is_64_dma = true, \
+ .op64bit = false, \
+ .msix_irqs = 4U, \
+ .irq_mask = ~0U, \
+ .vecs = HW_ATL_A0_RSS_MAX, \
+ .tcs_max = HW_ATL_A0_TC_MAX, \
+ .rxd_alignment = 1U, \
+ .rxd_size = HW_ATL_A0_RXD_SIZE, \
+ .rxds_max = HW_ATL_A0_MAX_RXD, \
+ .rxds_min = HW_ATL_A0_MIN_RXD, \
+ .txd_alignment = 1U, \
+ .txd_size = HW_ATL_A0_TXD_SIZE, \
+ .txds_max = HW_ATL_A0_MAX_TXD, \
+ .txds_min = HW_ATL_A0_MIN_RXD, \
+ .txhwb_alignment = 4096U, \
+ .tx_rings = HW_ATL_A0_TX_RINGS, \
+ .rx_rings = HW_ATL_A0_RX_RINGS, \
+ .hw_features = NETIF_F_HW_CSUM | \
+ NETIF_F_RXHASH | \
+ NETIF_F_RXCSUM | \
+ NETIF_F_SG | \
+ NETIF_F_TSO | \
+ NETIF_F_NTUPLE | \
+ NETIF_F_HW_VLAN_CTAG_FILTER, \
+ .hw_priv_flags = IFF_UNICAST_FLT, \
+ .flow_control = true, \
+ .mtu = HW_ATL_A0_MTU_JUMBO, \
+ .mac_regs_count = 88, \
.hw_alive_check_addr = 0x10U
const struct aq_hw_caps_s hw_atl_a0_caps_aqc100 = {
@@ -329,6 +332,7 @@ static int hw_atl_a0_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr)
err = -EINVAL;
goto err_exit;
}
+
h = (mac_addr[0] << 8) | (mac_addr[1]);
l = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
(mac_addr[4] << 8) | mac_addr[5];
@@ -355,7 +359,6 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
struct aq_nic_cfg_s *aq_nic_cfg = self->aq_nic_cfg;
int err = 0;
-
hw_atl_a0_hw_init_tx_path(self);
hw_atl_a0_hw_init_rx_path(self);
@@ -751,6 +754,7 @@ static int hw_atl_a0_hw_irq_read(struct aq_hw_s *self, u64 *mask)
static int hw_atl_a0_hw_packet_filter_set(struct aq_hw_s *self,
unsigned int packet_filter)
{
+ struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
unsigned int i = 0U;
hw_atl_rpfl2promiscuous_mode_en_set(self,
@@ -759,14 +763,13 @@ static int hw_atl_a0_hw_packet_filter_set(struct aq_hw_s *self,
IS_FILTER_ENABLED(IFF_MULTICAST), 0);
hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST));
- self->aq_nic_cfg->is_mc_list_enabled =
- IS_FILTER_ENABLED(IFF_MULTICAST);
+ cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST);
for (i = HW_ATL_A0_MAC_MIN; i < HW_ATL_A0_MAC_MAX; ++i)
hw_atl_rpfl2_uc_flr_en_set(self,
- (self->aq_nic_cfg->is_mc_list_enabled &&
- (i <= self->aq_nic_cfg->mc_list_count)) ?
- 1U : 0U, i);
+ (cfg->is_mc_list_enabled &&
+ (i <= cfg->mc_list_count)) ? 1U : 0U,
+ i);
return aq_hw_err_from_flags(self);
}
@@ -779,19 +782,18 @@ static int hw_atl_a0_hw_multicast_list_set(struct aq_hw_s *self,
[ETH_ALEN],
u32 count)
{
+ struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
int err = 0;
if (count > (HW_ATL_A0_MAC_MAX - HW_ATL_A0_MAC_MIN)) {
- err = EBADRQC;
+ err = -EBADRQC;
goto err_exit;
}
- for (self->aq_nic_cfg->mc_list_count = 0U;
- self->aq_nic_cfg->mc_list_count < count;
- ++self->aq_nic_cfg->mc_list_count) {
- u32 i = self->aq_nic_cfg->mc_list_count;
+ for (cfg->mc_list_count = 0U; cfg->mc_list_count < count; ++cfg->mc_list_count) {
+ u32 i = cfg->mc_list_count;
u32 h = (ar_mac[i][0] << 8) | (ar_mac[i][1]);
u32 l = (ar_mac[i][2] << 24) | (ar_mac[i][3] << 16) |
- (ar_mac[i][4] << 8) | ar_mac[i][5];
+ (ar_mac[i][4] << 8) | ar_mac[i][5];
hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL_A0_MAC_MIN + i);
@@ -804,7 +806,7 @@ static int hw_atl_a0_hw_multicast_list_set(struct aq_hw_s *self,
HW_ATL_A0_MAC_MIN + i);
hw_atl_rpfl2_uc_flr_en_set(self,
- (self->aq_nic_cfg->is_mc_list_enabled),
+ (cfg->is_mc_list_enabled),
HW_ATL_A0_MAC_MIN + i);
}
@@ -885,6 +887,63 @@ static int hw_atl_a0_hw_ring_rx_stop(struct aq_hw_s *self,
return aq_hw_err_from_flags(self);
}
+static int hw_atl_a0_hw_fl3l4_clear(struct aq_hw_s *self,
+ struct aq_rx_filter_l3l4 *data)
+{
+ u8 location = data->location;
+
+ if (!data->is_ipv6) {
+ hw_atl_rpfl3l4_cmd_clear(self, location);
+ hw_atl_rpf_l4_spd_set(self, 0U, location);
+ hw_atl_rpf_l4_dpd_set(self, 0U, location);
+ hw_atl_rpfl3l4_ipv4_src_addr_clear(self, location);
+ hw_atl_rpfl3l4_ipv4_dest_addr_clear(self, location);
+ } else {
+ int i;
+
+ for (i = 0; i < HW_ATL_RX_CNT_REG_ADDR_IPV6; ++i) {
+ hw_atl_rpfl3l4_cmd_clear(self, location + i);
+ hw_atl_rpf_l4_spd_set(self, 0U, location + i);
+ hw_atl_rpf_l4_dpd_set(self, 0U, location + i);
+ }
+ hw_atl_rpfl3l4_ipv6_src_addr_clear(self, location);
+ hw_atl_rpfl3l4_ipv6_dest_addr_clear(self, location);
+ }
+
+ return aq_hw_err_from_flags(self);
+}
+
+static int hw_atl_a0_hw_fl3l4_set(struct aq_hw_s *self,
+ struct aq_rx_filter_l3l4 *data)
+{
+ u8 location = data->location;
+
+ hw_atl_a0_hw_fl3l4_clear(self, data);
+
+ if (data->cmd) {
+ if (!data->is_ipv6) {
+ hw_atl_rpfl3l4_ipv4_dest_addr_set(self,
+ location,
+ data->ip_dst[0]);
+ hw_atl_rpfl3l4_ipv4_src_addr_set(self,
+ location,
+ data->ip_src[0]);
+ } else {
+ hw_atl_rpfl3l4_ipv6_dest_addr_set(self,
+ location,
+ data->ip_dst);
+ hw_atl_rpfl3l4_ipv6_src_addr_set(self,
+ location,
+ data->ip_src);
+ }
+ }
+ hw_atl_rpf_l4_dpd_set(self, data->p_dst, location);
+ hw_atl_rpf_l4_spd_set(self, data->p_src, location);
+ hw_atl_rpfl3l4_cmd_set(self, location, data->cmd);
+
+ return aq_hw_err_from_flags(self);
+}
+
const struct aq_hw_ops hw_atl_ops_a0 = {
.hw_soft_reset = hw_atl_utils_soft_reset,
.hw_prepare = hw_atl_utils_initfw,
@@ -911,6 +970,7 @@ const struct aq_hw_ops hw_atl_ops_a0 = {
.hw_ring_rx_init = hw_atl_a0_hw_ring_rx_init,
.hw_ring_tx_init = hw_atl_a0_hw_ring_tx_init,
.hw_packet_filter_set = hw_atl_a0_hw_packet_filter_set,
+ .hw_filter_l3l4_set = hw_atl_a0_hw_fl3l4_set,
.hw_multicast_list_set = hw_atl_a0_hw_multicast_list_set,
.hw_interrupt_moderation_set = hw_atl_a0_hw_interrupt_moderation_set,
.hw_rss_set = hw_atl_a0_hw_rss_set,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 2125bc20ab6a..16a944707ba9 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -20,6 +20,7 @@
#define DEFAULT_B0_BOARD_BASIC_CAPABILITIES \
.is_64_dma = true, \
+ .op64bit = false, \
.msix_irqs = 8U, \
.irq_mask = ~0U, \
.vecs = HW_ATL_B0_RSS_MAX, \
@@ -40,6 +41,7 @@
NETIF_F_RXHASH | \
NETIF_F_SG | \
NETIF_F_TSO | \
+ NETIF_F_TSO6 | \
NETIF_F_LRO | \
NETIF_F_NTUPLE | \
NETIF_F_HW_VLAN_CTAG_FILTER | \
@@ -54,8 +56,6 @@
.mac_regs_count = 88, \
.hw_alive_check_addr = 0x10U
-#define FRAC_PER_NS 0x100000000LL
-
const struct aq_hw_caps_s hw_atl_b0_caps_aqc100 = {
DEFAULT_B0_BOARD_BASIC_CAPABILITIES,
.media_type = AQ_HW_MEDIA_TYPE_FIBRE,
@@ -127,7 +127,7 @@ static int hw_atl_b0_hw_reset(struct aq_hw_s *self)
return err;
}
-static int hw_atl_b0_set_fc(struct aq_hw_s *self, u32 fc, u32 tc)
+int hw_atl_b0_set_fc(struct aq_hw_s *self, u32 fc, u32 tc)
{
hw_atl_rpb_rx_xoff_en_per_tc_set(self, !!(fc & AQ_NIC_FC_RX), tc);
@@ -1257,7 +1257,7 @@ static void hw_atl_b0_adj_params_get(u64 freq, s64 adj, u32 *ns, u32 *fns)
if (base_ns != nsi * NSEC_PER_SEC) {
s64 divisor = div64_s64((s64)NSEC_PER_SEC * NSEC_PER_SEC,
base_ns - nsi * NSEC_PER_SEC);
- nsi_frac = div64_s64(FRAC_PER_NS * NSEC_PER_SEC, divisor);
+ nsi_frac = div64_s64(AQ_FRAC_PER_NS * NSEC_PER_SEC, divisor);
}
*ns = (u32)nsi;
@@ -1270,23 +1270,23 @@ hw_atl_b0_mac_adj_param_calc(struct hw_fw_request_ptp_adj_freq *ptp_adj_freq,
{
s64 adj_fns_val;
s64 fns_in_sec_phy = phyfreq * (ptp_adj_freq->fns_phy +
- FRAC_PER_NS * ptp_adj_freq->ns_phy);
+ AQ_FRAC_PER_NS * ptp_adj_freq->ns_phy);
s64 fns_in_sec_mac = macfreq * (ptp_adj_freq->fns_mac +
- FRAC_PER_NS * ptp_adj_freq->ns_mac);
- s64 fault_in_sec_phy = FRAC_PER_NS * NSEC_PER_SEC - fns_in_sec_phy;
- s64 fault_in_sec_mac = FRAC_PER_NS * NSEC_PER_SEC - fns_in_sec_mac;
+ AQ_FRAC_PER_NS * ptp_adj_freq->ns_mac);
+ s64 fault_in_sec_phy = AQ_FRAC_PER_NS * NSEC_PER_SEC - fns_in_sec_phy;
+ s64 fault_in_sec_mac = AQ_FRAC_PER_NS * NSEC_PER_SEC - fns_in_sec_mac;
/* MAC MCP counter freq is macfreq / 4 */
s64 diff_in_mcp_overflow = (fault_in_sec_mac - fault_in_sec_phy) *
- 4 * FRAC_PER_NS;
+ 4 * AQ_FRAC_PER_NS;
diff_in_mcp_overflow = div64_s64(diff_in_mcp_overflow,
AQ_HW_MAC_COUNTER_HZ);
- adj_fns_val = (ptp_adj_freq->fns_mac + FRAC_PER_NS *
+ adj_fns_val = (ptp_adj_freq->fns_mac + AQ_FRAC_PER_NS *
ptp_adj_freq->ns_mac) + diff_in_mcp_overflow;
- ptp_adj_freq->mac_ns_adj = div64_s64(adj_fns_val, FRAC_PER_NS);
+ ptp_adj_freq->mac_ns_adj = div64_s64(adj_fns_val, AQ_FRAC_PER_NS);
ptp_adj_freq->mac_fns_adj = adj_fns_val - ptp_adj_freq->mac_ns_adj *
- FRAC_PER_NS;
+ AQ_FRAC_PER_NS;
}
static int hw_atl_b0_adj_sys_clock(struct aq_hw_s *self, s64 delta)
@@ -1580,7 +1580,7 @@ static int hw_atl_b0_hw_vlan_ctrl(struct aq_hw_s *self, bool enable)
return aq_hw_err_from_flags(self);
}
-static int hw_atl_b0_set_loopback(struct aq_hw_s *self, u32 mode, bool enable)
+int hw_atl_b0_set_loopback(struct aq_hw_s *self, u32 mode, bool enable)
{
switch (mode) {
case AQ_HW_LOOPBACK_DMA_SYS:
@@ -1605,6 +1605,48 @@ static int hw_atl_b0_set_loopback(struct aq_hw_s *self, u32 mode, bool enable)
return 0;
}
+static u32 hw_atl_b0_ts_ready_and_latch_high_get(struct aq_hw_s *self)
+{
+ if (hw_atl_ts_ready_get(self) && hw_atl_ts_ready_latch_high_get(self))
+ return 1;
+
+ return 0;
+}
+
+static int hw_atl_b0_get_mac_temp(struct aq_hw_s *self, u32 *temp)
+{
+ bool ts_disabled;
+ int err;
+ u32 val;
+ u32 ts;
+
+ ts_disabled = (hw_atl_ts_power_down_get(self) == 1U);
+
+ if (ts_disabled) {
+ // Set AFE Temperature Sensor to on (off by default)
+ hw_atl_ts_power_down_set(self, 0U);
+
+ // Reset internal capacitors, biasing, and counters
+ hw_atl_ts_reset_set(self, 1);
+ hw_atl_ts_reset_set(self, 0);
+ }
+
+ err = readx_poll_timeout_atomic(hw_atl_b0_ts_ready_and_latch_high_get,
+ self, val, val == 1, 10000U, 500000U);
+ if (err)
+ return err;
+
+ ts = hw_atl_ts_data_get(self);
+ *temp = ts * ts * 16 / 100000 + 60 * ts - 83410;
+
+ if (ts_disabled) {
+ // Set AFE Temperature Sensor back to off
+ hw_atl_ts_power_down_set(self, 1U);
+ }
+
+ return 0;
+}
+
const struct aq_hw_ops hw_atl_ops_b0 = {
.hw_soft_reset = hw_atl_utils_soft_reset,
.hw_prepare = hw_atl_utils_initfw,
@@ -1661,4 +1703,6 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
.hw_set_offload = hw_atl_b0_hw_offload_set,
.hw_set_loopback = hw_atl_b0_set_loopback,
.hw_set_fc = hw_atl_b0_set_fc,
+
+ .hw_get_mac_temp = hw_atl_b0_get_mac_temp,
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.h
index 16091af17980..d8db972113ec 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.h
@@ -60,6 +60,9 @@ void hw_atl_b0_hw_init_rx_rss_ctrl1(struct aq_hw_s *self);
int hw_atl_b0_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr);
+int hw_atl_b0_set_fc(struct aq_hw_s *self, u32 fc, u32 tc);
+int hw_atl_b0_set_loopback(struct aq_hw_s *self, u32 mode, bool enable);
+
int hw_atl_b0_hw_start(struct aq_hw_s *self);
int hw_atl_b0_hw_irq_enable(struct aq_hw_s *self, u64 mask);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
index d775b23025c1..7b67bdd8a258 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File hw_atl_llh.c: Definitions of bitfield and register access functions for
@@ -12,6 +13,50 @@
#include "hw_atl_llh_internal.h"
#include "../aq_hw_utils.h"
+void hw_atl_ts_reset_set(struct aq_hw_s *aq_hw, u32 val)
+{
+ aq_hw_write_reg_bit(aq_hw, HW_ATL_TS_RESET_ADR,
+ HW_ATL_TS_RESET_MSK,
+ HW_ATL_TS_RESET_SHIFT,
+ val);
+}
+
+void hw_atl_ts_power_down_set(struct aq_hw_s *aq_hw, u32 val)
+{
+ aq_hw_write_reg_bit(aq_hw, HW_ATL_TS_POWER_DOWN_ADR,
+ HW_ATL_TS_POWER_DOWN_MSK,
+ HW_ATL_TS_POWER_DOWN_SHIFT,
+ val);
+}
+
+u32 hw_atl_ts_power_down_get(struct aq_hw_s *aq_hw)
+{
+ return aq_hw_read_reg_bit(aq_hw, HW_ATL_TS_POWER_DOWN_ADR,
+ HW_ATL_TS_POWER_DOWN_MSK,
+ HW_ATL_TS_POWER_DOWN_SHIFT);
+}
+
+u32 hw_atl_ts_ready_get(struct aq_hw_s *aq_hw)
+{
+ return aq_hw_read_reg_bit(aq_hw, HW_ATL_TS_READY_ADR,
+ HW_ATL_TS_READY_MSK,
+ HW_ATL_TS_READY_SHIFT);
+}
+
+u32 hw_atl_ts_ready_latch_high_get(struct aq_hw_s *aq_hw)
+{
+ return aq_hw_read_reg_bit(aq_hw, HW_ATL_TS_READY_LATCH_HIGH_ADR,
+ HW_ATL_TS_READY_LATCH_HIGH_MSK,
+ HW_ATL_TS_READY_LATCH_HIGH_SHIFT);
+}
+
+u32 hw_atl_ts_data_get(struct aq_hw_s *aq_hw)
+{
+ return aq_hw_read_reg_bit(aq_hw, HW_ATL_TS_DATA_OUT_ADR,
+ HW_ATL_TS_DATA_OUT_MSK,
+ HW_ATL_TS_DATA_OUT_SHIFT);
+}
+
/* global */
void hw_atl_reg_glb_cpu_sem_set(struct aq_hw_s *aq_hw, u32 glb_cpu_sem,
u32 semaphore)
@@ -1724,6 +1769,16 @@ u32 hw_atl_sem_mdio_get(struct aq_hw_s *self)
return hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_MDIO);
}
+u32 hw_atl_sem_reset1_get(struct aq_hw_s *self)
+{
+ return hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RESET1);
+}
+
+u32 hw_atl_sem_reset2_get(struct aq_hw_s *self)
+{
+ return hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RESET2);
+}
+
u32 hw_atl_scrpad_get(struct aq_hw_s *aq_hw, u32 scratch_scp)
{
return aq_hw_read_reg(aq_hw,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
index 61a6f70c51cd..58f5ee0a6214 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File hw_atl_llh.h: Declarations of bitfield and register access functions for
@@ -15,6 +16,24 @@
struct aq_hw_s;
+/* set temperature sense reset */
+void hw_atl_ts_reset_set(struct aq_hw_s *aq_hw, u32 val);
+
+/* set temperature sense power down */
+void hw_atl_ts_power_down_set(struct aq_hw_s *aq_hw, u32 val);
+
+/* get temperature sense power down */
+u32 hw_atl_ts_power_down_get(struct aq_hw_s *aq_hw);
+
+/* get temperature sense ready */
+u32 hw_atl_ts_ready_get(struct aq_hw_s *aq_hw);
+
+/* get temperature sense ready latch high */
+u32 hw_atl_ts_ready_latch_high_get(struct aq_hw_s *aq_hw);
+
+/* get temperature sense data */
+u32 hw_atl_ts_data_get(struct aq_hw_s *aq_hw);
+
/* global */
/* set global microprocessor semaphore */
@@ -838,6 +857,9 @@ u32 hw_atl_sem_ram_get(struct aq_hw_s *self);
/* get global microprocessor mdio semaphore */
u32 hw_atl_sem_mdio_get(struct aq_hw_s *self);
+u32 hw_atl_sem_reset1_get(struct aq_hw_s *self);
+u32 hw_atl_sem_reset2_get(struct aq_hw_s *self);
+
/* get global microprocessor scratch pad register */
u32 hw_atl_scrpad_get(struct aq_hw_s *aq_hw, u32 scratch_scp);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
index 7430ff025134..4a6467031b9e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
*/
/* File hw_atl_llh_internal.h: Preprocessor definitions
@@ -11,6 +12,36 @@
#ifndef HW_ATL_LLH_INTERNAL_H
#define HW_ATL_LLH_INTERNAL_H
+/* COM Temperature Sense Reset Bitfield Definitions */
+#define HW_ATL_TS_RESET_ADR 0x00003100
+#define HW_ATL_TS_RESET_MSK 0x00000004
+#define HW_ATL_TS_RESET_SHIFT 2
+#define HW_ATL_TS_RESET_WIDTH 1
+
+/* COM Temperature Sense Power Down Bitfield Definitions */
+#define HW_ATL_TS_POWER_DOWN_ADR 0x00003100
+#define HW_ATL_TS_POWER_DOWN_MSK 0x00000001
+#define HW_ATL_TS_POWER_DOWN_SHIFT 0
+#define HW_ATL_TS_POWER_DOWN_WIDTH 1
+
+/* COM Temperature Sense Ready Bitfield Definitions */
+#define HW_ATL_TS_READY_ADR 0x00003120
+#define HW_ATL_TS_READY_MSK 0x80000000
+#define HW_ATL_TS_READY_SHIFT 31
+#define HW_ATL_TS_READY_WIDTH 1
+
+/* COM Temperature Sense Ready Latch High Bitfield Definitions */
+#define HW_ATL_TS_READY_LATCH_HIGH_ADR 0x00003120
+#define HW_ATL_TS_READY_LATCH_HIGH_MSK 0x40000000
+#define HW_ATL_TS_READY_LATCH_HIGH_SHIFT 30
+#define HW_ATL_TS_READY_LATCH_HIGH_WIDTH 1
+
+/* COM Temperature Sense Data Out [B:0] Bitfield Definitions */
+#define HW_ATL_TS_DATA_OUT_ADR 0x00003120
+#define HW_ATL_TS_DATA_OUT_MSK 0x00000FFF
+#define HW_ATL_TS_DATA_OUT_SHIFT 0
+#define HW_ATL_TS_DATA_OUT_WIDTH 12
+
/* global microprocessor semaphore definitions
* base address: 0x000003a0
* parameter: semaphore {s} | stride size 0x4 | range [0, 15]
@@ -2837,7 +2868,11 @@
/* Default value of bitfield MDIO Address [F:0] */
#define HW_ATL_MDIO_ADDRESS_DEFAULT 0x0
+#define HW_ATL_MIF_RESET_TIMEOUT_ADR 0x00000348
+
#define HW_ATL_FW_SM_MDIO 0x0U
#define HW_ATL_FW_SM_RAM 0x2U
+#define HW_ATL_FW_SM_RESET1 0x3U
+#define HW_ATL_FW_SM_RESET2 0x4U
#endif /* HW_ATL_LLH_INTERNAL_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index 73c0f41df8d8..404cbf60d3f2 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -46,6 +46,7 @@
#define HW_ATL_FW_VER_1X 0x01050006U
#define HW_ATL_FW_VER_2X 0x02000000U
#define HW_ATL_FW_VER_3X 0x03000000U
+#define HW_ATL_FW_VER_4X 0x04000000U
#define FORCE_FLASHLESS 0
@@ -72,14 +73,13 @@ int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
self->fw_ver_actual = hw_atl_utils_get_fw_version(self);
- if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
- self->fw_ver_actual) == 0) {
+ if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, self->fw_ver_actual)) {
*fw_ops = &aq_fw_1x_ops;
- } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X,
- self->fw_ver_actual) == 0) {
+ } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X, self->fw_ver_actual)) {
*fw_ops = &aq_fw_2x_ops;
- } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X,
- self->fw_ver_actual) == 0) {
+ } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X, self->fw_ver_actual)) {
+ *fw_ops = &aq_fw_2x_ops;
+ } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_4X, self->fw_ver_actual)) {
*fw_ops = &aq_fw_2x_ops;
} else {
aq_pr_err("Bad FW version detected: %x\n",
@@ -217,7 +217,7 @@ static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)
if (rbl_status == 0xF1A7) {
aq_pr_err("No FW detected. Dynamic FW load not implemented\n");
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
for (k = 0; k < 1000; k++) {
@@ -239,6 +239,7 @@ static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)
int hw_atl_utils_soft_reset(struct aq_hw_s *self)
{
+ int ver = hw_atl_utils_get_fw_version(self);
u32 boot_exit_code = 0;
u32 val;
int k;
@@ -259,14 +260,12 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self)
self->rbl_enabled = (boot_exit_code != 0);
- /* FW 1.x may bootup in an invalid POWER state (WOL feature).
- * We should work around this by forcing its state back to DEINIT
- */
- if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
- aq_hw_read_reg(self,
- HW_ATL_MPI_FW_VERSION))) {
+ if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, ver)) {
int err = 0;
+ /* FW 1.x may bootup in an invalid POWER state (WOL feature).
+ * We should work around this by forcing its state back to DEINIT
+ */
hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
err = readx_poll_timeout_atomic(hw_atl_utils_mpi_get_state,
self, val,
@@ -275,6 +274,27 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self)
10, 10000U);
if (err)
return err;
+ } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_4X, ver)) {
+ u64 sem_timeout = aq_hw_read_reg(self, HW_ATL_MIF_RESET_TIMEOUT_ADR);
+
+ /* Acquire 2 semaphores before issuing reset for FW 4.x */
+ if (sem_timeout > 3000)
+ sem_timeout = 3000;
+ sem_timeout = sem_timeout * 1000;
+
+ if (sem_timeout != 0) {
+ int err;
+
+ err = readx_poll_timeout_atomic(hw_atl_sem_reset1_get, self, val,
+ val == 1U, 1U, sem_timeout);
+ if (err)
+ aq_pr_err("reset sema1 timeout");
+
+ err = readx_poll_timeout_atomic(hw_atl_sem_reset2_get, self, val,
+ val == 1U, 1U, sem_timeout);
+ if (err)
+ aq_pr_err("reset sema2 timeout");
+ }
}
if (self->rbl_enabled)
@@ -434,20 +454,20 @@ int hw_atl_write_fwsettings_dwords(struct aq_hw_s *self, u32 offset, u32 *p,
p, cnt, MCP_AREA_SETTINGS);
}
-int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
+bool hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
{
const u32 dw_major_mask = 0xff000000U;
const u32 dw_minor_mask = 0x00ffffffU;
- int err = 0;
+ bool ver_match;
- err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;
- if (err < 0)
+ ver_match = (dw_major_mask & (ver_expected ^ ver_actual)) ? false : true;
+ if (!ver_match)
goto err_exit;
- err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
- -EOPNOTSUPP : 0;
+ ver_match = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
+ false : true;
err_exit:
- return err;
+ return ver_match;
}
static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
@@ -704,6 +724,7 @@ int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
return -EBUSY;
}
}
+ link_status->full_duplex = true;
return 0;
}
@@ -1045,6 +1066,7 @@ const struct aq_fw_ops aq_fw_1x_ops = {
.set_state = hw_atl_utils_mpi_set_state,
.update_link_status = hw_atl_utils_mpi_get_link_status,
.update_stats = hw_atl_utils_update_stats,
+ .get_mac_temp = NULL,
.get_phy_temp = NULL,
.set_power = aq_fw1x_set_power,
.set_eee_rate = NULL,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index 0b4b54fc1de0..f5901f8e3907 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -635,7 +635,7 @@ int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size);
int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
struct hw_atl_utils_fw_rpc **rpc);
-int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
+bool hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
extern const struct aq_fw_ops aq_fw_1x_ops;
extern const struct aq_fw_ops aq_fw_2x_ops;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index eeedd8c90067..93c06dfa6c55 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -274,6 +274,7 @@ static int aq_fw2x_update_link_status(struct aq_hw_s *self)
} else {
link_status->mbps = 0;
}
+ link_status->full_duplex = true;
return 0;
}
@@ -352,7 +353,7 @@ static int aq_fw2x_get_phy_temp(struct aq_hw_s *self, int *temp)
/* Convert PHY temperature from 1/256 degree Celsius
* to 1/1000 degree Celsius.
*/
- *temp = (temp_res & 0xFFFF) * 1000 / 256;
+ *temp = (int16_t)(temp_res & 0xFFFF) * 1000 / 256;
return 0;
}
@@ -680,6 +681,7 @@ const struct aq_fw_ops aq_fw_2x_ops = {
.set_state = aq_fw2x_set_state,
.update_link_status = aq_fw2x_update_link_status,
.update_stats = aq_fw2x_update_stats,
+ .get_mac_temp = NULL,
.get_phy_temp = aq_fw2x_get_phy_temp,
.set_power = aq_fw2x_set_power,
.set_eee_rate = aq_fw2x_set_eee_rate,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
index 8df9d4ef36f0..92f64048bf69 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
@@ -21,6 +21,7 @@ static int hw_atl2_act_rslvr_table_set(struct aq_hw_s *self, u8 location,
#define DEFAULT_BOARD_BASIC_CAPABILITIES \
.is_64_dma = true, \
+ .op64bit = true, \
.msix_irqs = 8U, \
.irq_mask = ~0U, \
.vecs = HW_ATL2_RSS_MAX, \
@@ -64,8 +65,11 @@ const struct aq_hw_caps_s hw_atl2_caps_aqc113 = {
AQ_NIC_RATE_5G |
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
+ AQ_NIC_RATE_1G_HALF |
AQ_NIC_RATE_100M |
- AQ_NIC_RATE_10M,
+ AQ_NIC_RATE_100M_HALF |
+ AQ_NIC_RATE_10M |
+ AQ_NIC_RATE_10M_HALF,
};
static u32 hw_atl2_sem_act_rslvr_get(struct aq_hw_s *self)
@@ -178,6 +182,8 @@ static int hw_atl2_hw_qos_set(struct aq_hw_s *self)
threshold = (rx_buff_size * (1024U / 32U) * 50U) / 100U;
hw_atl_rpb_rx_buff_lo_threshold_per_tc_set(self, threshold, tc);
+
+ hw_atl_b0_set_fc(self, self->aq_nic_cfg->fc.req, tc);
}
/* QoS 802.1p priority -> TC mapping */
@@ -838,4 +844,6 @@ const struct aq_hw_ops hw_atl2_ops = {
.hw_get_hw_stats = hw_atl2_utils_get_hw_stats,
.hw_get_fw_version = hw_atl2_utils_get_fw_version,
.hw_set_offload = hw_atl_b0_hw_offload_set,
+ .hw_set_loopback = hw_atl_b0_set_loopback,
+ .hw_set_fc = hw_atl_b0_set_fc,
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.c
index f3766780e975..0fe6257d9c08 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.c
@@ -36,8 +36,7 @@ int hw_atl2_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
self->fw_ver_actual = hw_atl2_utils_get_fw_version(self);
- if (hw_atl_utils_ver_match(HW_ATL2_FW_VER_1X,
- self->fw_ver_actual) == 0) {
+ if (hw_atl_utils_ver_match(HW_ATL2_FW_VER_1X, self->fw_ver_actual)) {
*fw_ops = &aq_a2_fw_ops;
} else {
aq_pr_err("Bad FW version detected: %x, but continue\n",
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
index 0ffc33bd67d0..85628acbcc1d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
@@ -7,6 +7,7 @@
#include "aq_hw.h"
#include "aq_hw_utils.h"
+#include "aq_nic.h"
#include "hw_atl/hw_atl_llh.h"
#include "hw_atl2_utils.h"
#include "hw_atl2_llh.h"
@@ -15,15 +16,29 @@
#define AQ_A2_FW_READ_TRY_MAX 1000
#define hw_atl2_shared_buffer_write(HW, ITEM, VARIABLE) \
+{\
+ BUILD_BUG_ON_MSG((offsetof(struct fw_interface_in, ITEM) % \
+ sizeof(u32)) != 0,\
+ "Unaligned write " # ITEM);\
+ BUILD_BUG_ON_MSG((sizeof(VARIABLE) % sizeof(u32)) != 0,\
+ "Unaligned write length " # ITEM);\
hw_atl2_mif_shared_buf_write(HW,\
(offsetof(struct fw_interface_in, ITEM) / sizeof(u32)),\
- (u32 *)&(VARIABLE), sizeof(VARIABLE) / sizeof(u32))
+ (u32 *)&(VARIABLE), sizeof(VARIABLE) / sizeof(u32));\
+}
#define hw_atl2_shared_buffer_get(HW, ITEM, VARIABLE) \
+{\
+ BUILD_BUG_ON_MSG((offsetof(struct fw_interface_in, ITEM) % \
+ sizeof(u32)) != 0,\
+ "Unaligned get " # ITEM);\
+ BUILD_BUG_ON_MSG((sizeof(VARIABLE) % sizeof(u32)) != 0,\
+ "Unaligned get length " # ITEM);\
hw_atl2_mif_shared_buf_get(HW, \
(offsetof(struct fw_interface_in, ITEM) / sizeof(u32)),\
(u32 *)&(VARIABLE), \
- sizeof(VARIABLE) / sizeof(u32))
+ sizeof(VARIABLE) / sizeof(u32));\
+}
/* This should never be used on non atomic fields,
* treat any > u32 read as non atomic.
@@ -32,7 +47,9 @@
{\
BUILD_BUG_ON_MSG((offsetof(struct fw_interface_out, ITEM) % \
sizeof(u32)) != 0,\
- "Non aligned read " # ITEM);\
+ "Unaligned read " # ITEM);\
+ BUILD_BUG_ON_MSG((sizeof(VARIABLE) % sizeof(u32)) != 0,\
+ "Unaligned read length " # ITEM);\
BUILD_BUG_ON_MSG(sizeof(VARIABLE) > sizeof(u32),\
"Non atomic read " # ITEM);\
hw_atl2_mif_shared_buf_read(HW, \
@@ -41,10 +58,18 @@
}
#define hw_atl2_shared_buffer_read_safe(HW, ITEM, DATA) \
+({\
+ BUILD_BUG_ON_MSG((offsetof(struct fw_interface_out, ITEM) % \
+ sizeof(u32)) != 0,\
+ "Unaligned read_safe " # ITEM);\
+ BUILD_BUG_ON_MSG((sizeof(((struct fw_interface_out *)0)->ITEM) % \
+ sizeof(u32)) != 0,\
+ "Unaligned read_safe length " # ITEM);\
hw_atl2_shared_buffer_read_block((HW), \
(offsetof(struct fw_interface_out, ITEM) / sizeof(u32)),\
sizeof(((struct fw_interface_out *)0)->ITEM) / sizeof(u32),\
- (DATA))
+ (DATA));\
+})
static int hw_atl2_shared_buffer_read_block(struct aq_hw_s *self,
u32 offset, u32 dwords, void *data)
@@ -135,6 +160,67 @@ static void a2_link_speed_mask2fw(u32 speed,
link_options->rate_1G = !!(speed & AQ_NIC_RATE_1G);
link_options->rate_100M = !!(speed & AQ_NIC_RATE_100M);
link_options->rate_10M = !!(speed & AQ_NIC_RATE_10M);
+
+ link_options->rate_1G_hd = !!(speed & AQ_NIC_RATE_1G_HALF);
+ link_options->rate_100M_hd = !!(speed & AQ_NIC_RATE_100M_HALF);
+ link_options->rate_10M_hd = !!(speed & AQ_NIC_RATE_10M_HALF);
+}
+
+static u32 a2_fw_dev_to_eee_mask(struct device_link_caps_s *device_link_caps)
+{
+ u32 rate = 0;
+
+ if (device_link_caps->eee_10G)
+ rate |= AQ_NIC_RATE_EEE_10G;
+ if (device_link_caps->eee_5G)
+ rate |= AQ_NIC_RATE_EEE_5G;
+ if (device_link_caps->eee_2P5G)
+ rate |= AQ_NIC_RATE_EEE_2G5;
+ if (device_link_caps->eee_1G)
+ rate |= AQ_NIC_RATE_EEE_1G;
+ if (device_link_caps->eee_100M)
+ rate |= AQ_NIC_RATE_EEE_100M;
+
+ return rate;
+}
+
+static u32 a2_fw_lkp_to_mask(struct lkp_link_caps_s *lkp_link_caps)
+{
+ u32 rate = 0;
+
+ if (lkp_link_caps->rate_10G)
+ rate |= AQ_NIC_RATE_10G;
+ if (lkp_link_caps->rate_5G)
+ rate |= AQ_NIC_RATE_5G;
+ if (lkp_link_caps->rate_N5G)
+ rate |= AQ_NIC_RATE_5GSR;
+ if (lkp_link_caps->rate_2P5G)
+ rate |= AQ_NIC_RATE_2G5;
+ if (lkp_link_caps->rate_1G)
+ rate |= AQ_NIC_RATE_1G;
+ if (lkp_link_caps->rate_1G_hd)
+ rate |= AQ_NIC_RATE_1G_HALF;
+ if (lkp_link_caps->rate_100M)
+ rate |= AQ_NIC_RATE_100M;
+ if (lkp_link_caps->rate_100M_hd)
+ rate |= AQ_NIC_RATE_100M_HALF;
+ if (lkp_link_caps->rate_10M)
+ rate |= AQ_NIC_RATE_10M;
+ if (lkp_link_caps->rate_10M_hd)
+ rate |= AQ_NIC_RATE_10M_HALF;
+
+ if (lkp_link_caps->eee_10G)
+ rate |= AQ_NIC_RATE_EEE_10G;
+ if (lkp_link_caps->eee_5G)
+ rate |= AQ_NIC_RATE_EEE_5G;
+ if (lkp_link_caps->eee_2P5G)
+ rate |= AQ_NIC_RATE_EEE_2G5;
+ if (lkp_link_caps->eee_1G)
+ rate |= AQ_NIC_RATE_EEE_1G;
+ if (lkp_link_caps->eee_100M)
+ rate |= AQ_NIC_RATE_EEE_100M;
+
+ return rate;
}
static int aq_a2_fw_set_link_speed(struct aq_hw_s *self, u32 speed)
@@ -149,6 +235,26 @@ static int aq_a2_fw_set_link_speed(struct aq_hw_s *self, u32 speed)
return hw_atl2_shared_buffer_finish_ack(self);
}
+static void aq_a2_fw_set_mpi_flow_control(struct aq_hw_s *self,
+ struct link_options_s *link_options)
+{
+ u32 flow_control = self->aq_nic_cfg->fc.req;
+
+ link_options->pause_rx = !!(flow_control & AQ_NIC_FC_RX);
+ link_options->pause_tx = !!(flow_control & AQ_NIC_FC_TX);
+}
+
+static void aq_a2_fw_upd_eee_rate_bits(struct aq_hw_s *self,
+ struct link_options_s *link_options,
+ u32 eee_speeds)
+{
+ link_options->eee_10G = !!(eee_speeds & AQ_NIC_RATE_EEE_10G);
+ link_options->eee_5G = !!(eee_speeds & AQ_NIC_RATE_EEE_5G);
+ link_options->eee_2P5G = !!(eee_speeds & AQ_NIC_RATE_EEE_2G5);
+ link_options->eee_1G = !!(eee_speeds & AQ_NIC_RATE_EEE_1G);
+ link_options->eee_100M = !!(eee_speeds & AQ_NIC_RATE_EEE_100M);
+}
+
static int aq_a2_fw_set_state(struct aq_hw_s *self,
enum hal_atl_utils_fw_state_e state)
{
@@ -159,6 +265,9 @@ static int aq_a2_fw_set_state(struct aq_hw_s *self,
switch (state) {
case MPI_INIT:
link_options.link_up = 1U;
+ aq_a2_fw_upd_eee_rate_bits(self, &link_options,
+ self->aq_nic_cfg->eee_speeds);
+ aq_a2_fw_set_mpi_flow_control(self, &link_options);
break;
case MPI_DEINIT:
link_options.link_up = 0U;
@@ -176,6 +285,7 @@ static int aq_a2_fw_set_state(struct aq_hw_s *self,
static int aq_a2_fw_update_link_status(struct aq_hw_s *self)
{
+ struct lkp_link_caps_s lkp_link_caps;
struct link_status_s link_status;
hw_atl2_shared_buffer_read(self, link_status, link_status);
@@ -202,6 +312,15 @@ static int aq_a2_fw_update_link_status(struct aq_hw_s *self)
default:
self->aq_link_status.mbps = 0;
}
+ self->aq_link_status.full_duplex = link_status.duplex;
+
+ hw_atl2_shared_buffer_read(self, lkp_link_caps, lkp_link_caps);
+
+ self->aq_link_status.lp_link_speed_msk =
+ a2_fw_lkp_to_mask(&lkp_link_caps);
+ self->aq_link_status.lp_flow_control =
+ ((lkp_link_caps.pause_rx) ? AQ_NIC_FC_RX : 0) |
+ ((lkp_link_caps.pause_tx) ? AQ_NIC_FC_TX : 0);
return 0;
}
@@ -260,6 +379,53 @@ static int aq_a2_fw_update_stats(struct aq_hw_s *self)
return 0;
}
+static int aq_a2_fw_get_phy_temp(struct aq_hw_s *self, int *temp)
+{
+ struct phy_health_monitor_s phy_health_monitor;
+
+ hw_atl2_shared_buffer_read_safe(self, phy_health_monitor,
+ &phy_health_monitor);
+
+ *temp = (int8_t)phy_health_monitor.phy_temperature * 1000;
+ return 0;
+}
+
+static int aq_a2_fw_get_mac_temp(struct aq_hw_s *self, int *temp)
+{
+ /* There's only one temperature sensor on A2, use it for
+ * both MAC and PHY.
+ */
+ return aq_a2_fw_get_phy_temp(self, temp);
+}
+
+static int aq_a2_fw_set_eee_rate(struct aq_hw_s *self, u32 speed)
+{
+ struct link_options_s link_options;
+
+ hw_atl2_shared_buffer_get(self, link_options, link_options);
+
+ aq_a2_fw_upd_eee_rate_bits(self, &link_options, speed);
+
+ hw_atl2_shared_buffer_write(self, link_options, link_options);
+
+ return hw_atl2_shared_buffer_finish_ack(self);
+}
+
+static int aq_a2_fw_get_eee_rate(struct aq_hw_s *self, u32 *rate,
+ u32 *supported_rates)
+{
+ struct device_link_caps_s device_link_caps;
+ struct lkp_link_caps_s lkp_link_caps;
+
+ hw_atl2_shared_buffer_read(self, device_link_caps, device_link_caps);
+ hw_atl2_shared_buffer_read(self, lkp_link_caps, lkp_link_caps);
+
+ *supported_rates = a2_fw_dev_to_eee_mask(&device_link_caps);
+ *rate = a2_fw_lkp_to_mask(&lkp_link_caps);
+
+ return 0;
+}
+
static int aq_a2_fw_renegotiate(struct aq_hw_s *self)
{
struct link_options_s link_options;
@@ -280,6 +446,52 @@ static int aq_a2_fw_renegotiate(struct aq_hw_s *self)
return err;
}
+static int aq_a2_fw_set_flow_control(struct aq_hw_s *self)
+{
+ struct link_options_s link_options;
+
+ hw_atl2_shared_buffer_get(self, link_options, link_options);
+
+ aq_a2_fw_set_mpi_flow_control(self, &link_options);
+
+ hw_atl2_shared_buffer_write(self, link_options, link_options);
+
+ return hw_atl2_shared_buffer_finish_ack(self);
+}
+
+static u32 aq_a2_fw_get_flow_control(struct aq_hw_s *self, u32 *fcmode)
+{
+ struct link_status_s link_status;
+
+ hw_atl2_shared_buffer_read(self, link_status, link_status);
+
+ *fcmode = ((link_status.pause_rx) ? AQ_NIC_FC_RX : 0) |
+ ((link_status.pause_tx) ? AQ_NIC_FC_TX : 0);
+ return 0;
+}
+
+static int aq_a2_fw_set_phyloopback(struct aq_hw_s *self, u32 mode, bool enable)
+{
+ struct link_options_s link_options;
+
+ hw_atl2_shared_buffer_get(self, link_options, link_options);
+
+ switch (mode) {
+ case AQ_HW_LOOPBACK_PHYINT_SYS:
+ link_options.internal_loopback = enable;
+ break;
+ case AQ_HW_LOOPBACK_PHYEXT_SYS:
+ link_options.external_loopback = enable;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ hw_atl2_shared_buffer_write(self, link_options, link_options);
+
+ return hw_atl2_shared_buffer_finish_ack(self);
+}
+
u32 hw_atl2_utils_get_fw_version(struct aq_hw_s *self)
{
struct version_s version;
@@ -317,4 +529,11 @@ const struct aq_fw_ops aq_a2_fw_ops = {
.set_state = aq_a2_fw_set_state,
.update_link_status = aq_a2_fw_update_link_status,
.update_stats = aq_a2_fw_update_stats,
+ .get_mac_temp = aq_a2_fw_get_mac_temp,
+ .get_phy_temp = aq_a2_fw_get_phy_temp,
+ .set_eee_rate = aq_a2_fw_set_eee_rate,
+ .get_eee_rate = aq_a2_fw_get_eee_rate,
+ .set_flow_control = aq_a2_fw_set_flow_control,
+ .get_flow_control = aq_a2_fw_get_flow_control,
+ .set_phyloopback = aq_a2_fw_set_phyloopback,
};
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index 38cd968b6a3b..b56a9e2aecd9 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -673,7 +673,7 @@ static struct net_device_stats *arc_emac_stats(struct net_device *ndev)
*
* This function is invoked from upper layers to initiate transmission.
*/
-static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
{
struct arc_emac_priv *priv = netdev_priv(ndev);
unsigned int len, *txbd_curr = &priv->txbd_curr;
diff --git a/drivers/net/ethernet/aurora/nb8800.c b/drivers/net/ethernet/aurora/nb8800.c
index bc273e0db7ff..5b20185cbd62 100644
--- a/drivers/net/ethernet/aurora/nb8800.c
+++ b/drivers/net/ethernet/aurora/nb8800.c
@@ -384,7 +384,7 @@ static void nb8800_tx_dma_start_irq(struct net_device *dev)
spin_unlock(&priv->tx_lock);
}
-static int nb8800_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t nb8800_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct nb8800_priv *priv = netdev_priv(dev);
struct nb8800_tx_desc *txd;
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index b25356e21a1e..dfed9ade6950 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -160,13 +160,26 @@ static void bcm_sysport_set_tx_csum(struct net_device *dev,
/* Hardware transmit checksum requires us to enable the Transmit status
* block prepended to the packet contents
*/
- priv->tsb_en = !!(wanted & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM));
+ priv->tsb_en = !!(wanted & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_HW_VLAN_CTAG_TX));
reg = tdma_readl(priv, TDMA_CONTROL);
if (priv->tsb_en)
reg |= tdma_control_bit(priv, TSB_EN);
else
reg &= ~tdma_control_bit(priv, TSB_EN);
+ /* Indicating that software inserts Broadcom tags is needed for the TX
+ * checksum to be computed correctly when using VLAN HW acceleration,
+ * else it has no effect, so it can always be turned on.
+ */
+ if (netdev_uses_dsa(dev))
+ reg |= tdma_control_bit(priv, SW_BRCM_TAG);
+ else
+ reg &= ~tdma_control_bit(priv, SW_BRCM_TAG);
tdma_writel(priv, reg, TDMA_CONTROL);
+
+ /* Default TPID is ETH_P_8021AD, change to ETH_P_8021Q */
+ if (wanted & NETIF_F_HW_VLAN_CTAG_TX)
+ tdma_writel(priv, ETH_P_8021Q, TDMA_TPID);
}
static int bcm_sysport_set_features(struct net_device *dev,
@@ -1236,6 +1249,11 @@ static struct sk_buff *bcm_sysport_insert_tsb(struct sk_buff *skb,
/* Zero-out TSB by default */
memset(tsb, 0, sizeof(*tsb));
+ if (skb_vlan_tag_present(skb)) {
+ tsb->pcp_dei_vid = skb_vlan_tag_get_prio(skb) & PCP_DEI_MASK;
+ tsb->pcp_dei_vid |= (u32)skb_vlan_tag_get_id(skb) << VID_SHIFT;
+ }
+
if (skb->ip_summed == CHECKSUM_PARTIAL) {
ip_ver = skb->protocol;
switch (ip_ver) {
@@ -1251,6 +1269,9 @@ static struct sk_buff *bcm_sysport_insert_tsb(struct sk_buff *skb,
/* Get the checksum offset and the L4 (transport) offset */
csum_start = skb_checksum_start_offset(skb) - sizeof(*tsb);
+ /* Account for the HW inserted VLAN tag */
+ if (skb_vlan_tag_present(skb))
+ csum_start += VLAN_HLEN;
csum_info = (csum_start + skb->csum_offset) & L4_CSUM_PTR_MASK;
csum_info |= (csum_start << L4_PTR_SHIFT);
@@ -1330,6 +1351,8 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
DESC_STATUS_SHIFT;
if (skb->ip_summed == CHECKSUM_PARTIAL)
len_status |= (DESC_L4_CSUM << DESC_STATUS_SHIFT);
+ if (skb_vlan_tag_present(skb))
+ len_status |= (TX_STATUS_VLAN_VID_TSB << DESC_STATUS_SHIFT);
ring->curr_desc++;
if (ring->curr_desc == ring->size)
@@ -1503,7 +1526,13 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
reg |= RING_IGNORE_STATUS;
}
tdma_writel(priv, reg, TDMA_DESC_RING_MAPPING(index));
- tdma_writel(priv, 0, TDMA_DESC_RING_PCP_DEI_VID(index));
+ reg = 0;
+ /* Adjust the packet size calculations if SYSTEMPORT is responsible
+ * for HW insertion of VLAN tags
+ */
+ if (priv->netdev->features & NETIF_F_HW_VLAN_CTAG_TX)
+ reg = VLAN_HLEN << RING_PKT_SIZE_ADJ_SHIFT;
+ tdma_writel(priv, reg, TDMA_DESC_RING_PCP_DEI_VID(index));
/* Enable ACB algorithm 2 */
reg = tdma_readl(priv, TDMA_CONTROL);
@@ -2523,7 +2552,8 @@ static int bcm_sysport_probe(struct platform_device *pdev)
netif_napi_add(dev, &priv->napi, bcm_sysport_poll, 64);
dev->features |= NETIF_F_RXCSUM | NETIF_F_HIGHDMA |
- NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_HW_VLAN_CTAG_TX;
dev->hw_features |= dev->features;
dev->vlan_features |= dev->features;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/Makefile b/drivers/net/ethernet/broadcom/bnx2x/Makefile
index 9fdfaa269af9..2523cfc7527d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/Makefile
+++ b/drivers/net/ethernet/broadcom/bnx2x/Makefile
@@ -5,5 +5,5 @@
obj-$(CONFIG_BNX2X) += bnx2x.o
-bnx2x-y := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o bnx2x_sp.o
+bnx2x-y := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o bnx2x_sp.o bnx2x_self_test.o
bnx2x-$(CONFIG_BNX2X_SRIOV) += bnx2x_vfpf.o bnx2x_sriov.o
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 4f5b2b81be3d..d04994840b87 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1287,7 +1287,6 @@ enum sp_rtnl_flag {
BNX2X_SP_RTNL_HYPERVISOR_VLAN,
BNX2X_SP_RTNL_TX_STOP,
BNX2X_SP_RTNL_GET_DRV_VERSION,
- BNX2X_SP_RTNL_CHANGE_UDP_PORT,
BNX2X_SP_RTNL_UPDATE_SVID,
};
@@ -1343,11 +1342,6 @@ enum bnx2x_udp_port_type {
BNX2X_UDP_PORT_MAX,
};
-struct bnx2x_udp_tunnel {
- u16 dst_port;
- u8 count;
-};
-
struct bnx2x {
/* Fields used in the tx and intr/napi performance paths
* are grouped together in the beginning of the structure
@@ -1855,7 +1849,7 @@ struct bnx2x {
bool accept_any_vlan;
/* Vxlan/Geneve related information */
- struct bnx2x_udp_tunnel udp_tunnel_ports[BNX2X_UDP_PORT_MAX];
+ u16 udp_tunnel_ports[BNX2X_UDP_PORT_MAX];
};
/* Tx queues may be less or equal to Rx queues */
@@ -1979,6 +1973,9 @@ struct bnx2x_func_init_params {
#define skip_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx))
+/*self test*/
+int bnx2x_idle_chk(struct bnx2x *bp);
+
/**
* bnx2x_set_mac_one - configure a single MAC address
*
@@ -2430,13 +2427,6 @@ int bnx2x_compare_fw_ver(struct bnx2x *bp, u32 load_code, bool print_err);
#define HC_SEG_ACCESS_ATTN 4
#define HC_SEG_ACCESS_NORM 0 /*Driver decision 0-1*/
-static const u32 dmae_reg_go_c[] = {
- DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
- DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7,
- DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11,
- DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15
-};
-
void bnx2x_set_ethtool_ops(struct bnx2x *bp, struct net_device *netdev);
void bnx2x_notify_link_changed(struct bnx2x *bp);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index ee9e9290f112..e3d92e4f2193 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -4988,8 +4988,9 @@ void bnx2x_tx_timeout(struct net_device *dev, unsigned int txqueue)
bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_TX_TIMEOUT, 0);
}
-int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused bnx2x_suspend(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2x *bp;
@@ -5001,8 +5002,6 @@ int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
rtnl_lock();
- pci_save_state(pdev);
-
if (!netif_running(dev)) {
rtnl_unlock();
return 0;
@@ -5012,15 +5011,14 @@ int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
bnx2x_nic_unload(bp, UNLOAD_CLOSE, false);
- bnx2x_set_power_state(bp, pci_choose_state(pdev, state));
-
rtnl_unlock();
return 0;
}
-int bnx2x_resume(struct pci_dev *pdev)
+static int __maybe_unused bnx2x_resume(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2x *bp;
int rc;
@@ -5038,14 +5036,11 @@ int bnx2x_resume(struct pci_dev *pdev)
rtnl_lock();
- pci_restore_state(pdev);
-
if (!netif_running(dev)) {
rtnl_unlock();
return 0;
}
- bnx2x_set_power_state(bp, PCI_D0);
netif_device_attach(dev);
rc = bnx2x_nic_load(bp, LOAD_OPEN);
@@ -5055,6 +5050,8 @@ int bnx2x_resume(struct pci_dev *pdev)
return rc;
}
+SIMPLE_DEV_PM_OPS(bnx2x_pm_ops, bnx2x_suspend, bnx2x_resume);
+
void bnx2x_set_ctx_validation(struct bnx2x *bp, struct eth_context *cxt,
u32 cid)
{
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 6f1352d51cb2..7e4c93be4451 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -541,9 +541,7 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p);
/* NAPI poll Tx part */
int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata);
-/* suspend/resume callbacks */
-int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state);
-int bnx2x_resume(struct pci_dev *pdev);
+extern const struct dev_pm_ops bnx2x_pm_ops;
/* Release IRQ vectors */
void bnx2x_free_irq(struct bnx2x *bp);
@@ -962,12 +960,12 @@ static inline int bnx2x_func_start(struct bnx2x *bp)
start_params->network_cos_mode = STATIC_COS;
else /* CHIP_IS_E1X */
start_params->network_cos_mode = FW_WRR;
- if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count) {
- port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].dst_port;
+ if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN]) {
+ port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN];
start_params->vxlan_dst_port = port;
}
- if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count) {
- port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].dst_port;
+ if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE]) {
+ port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE];
start_params->geneve_dst_port = port;
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index db5107e7937c..7f24d2689fdd 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -276,6 +276,13 @@ static const struct pci_device_id bnx2x_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
+const u32 dmae_reg_go_c[] = {
+ DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
+ DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7,
+ DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11,
+ DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15
+};
+
/* Global resources for unloading a previously loaded device */
#define BNX2X_PREV_WAIT_NEEDED 1
static DEFINE_SEMAPHORE(bnx2x_prev_sem);
@@ -1169,9 +1176,18 @@ void bnx2x_panic_dump(struct bnx2x *bp, bool disable_int)
}
#endif
if (IS_PF(bp)) {
+ int tmp_msg_en = bp->msg_enable;
+
bnx2x_fw_dump(bp);
+ bp->msg_enable |= NETIF_MSG_HW;
+ BNX2X_ERR("Idle check (1st round) ----------\n");
+ bnx2x_idle_chk(bp);
+ BNX2X_ERR("Idle check (2nd round) ----------\n");
+ bnx2x_idle_chk(bp);
+ bp->msg_enable = tmp_msg_en;
bnx2x_mc_assert(bp);
}
+
BNX2X_ERR("end crash dump -----------------\n");
}
@@ -10136,7 +10152,6 @@ static int bnx2x_udp_port_update(struct bnx2x *bp)
{
struct bnx2x_func_switch_update_params *switch_update_params;
struct bnx2x_func_state_params func_params = {NULL};
- struct bnx2x_udp_tunnel *udp_tunnel;
u16 vxlan_port = 0, geneve_port = 0;
int rc;
@@ -10153,15 +10168,13 @@ static int bnx2x_udp_port_update(struct bnx2x *bp)
__set_bit(BNX2X_F_UPDATE_TUNNEL_CFG_CHNG,
&switch_update_params->changes);
- if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count) {
- udp_tunnel = &bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE];
- geneve_port = udp_tunnel->dst_port;
+ if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE]) {
+ geneve_port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE];
switch_update_params->geneve_dst_port = geneve_port;
}
- if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count) {
- udp_tunnel = &bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN];
- vxlan_port = udp_tunnel->dst_port;
+ if (bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN]) {
+ vxlan_port = bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN];
switch_update_params->vxlan_dst_port = vxlan_port;
}
@@ -10181,94 +10194,27 @@ static int bnx2x_udp_port_update(struct bnx2x *bp)
return rc;
}
-static void __bnx2x_add_udp_port(struct bnx2x *bp, u16 port,
- enum bnx2x_udp_port_type type)
-{
- struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
-
- if (!netif_running(bp->dev) || !IS_PF(bp) || CHIP_IS_E1x(bp))
- return;
-
- if (udp_port->count && udp_port->dst_port == port) {
- udp_port->count++;
- return;
- }
-
- if (udp_port->count) {
- DP(BNX2X_MSG_SP,
- "UDP tunnel [%d] - destination port limit reached\n",
- type);
- return;
- }
-
- udp_port->dst_port = port;
- udp_port->count = 1;
- bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_CHANGE_UDP_PORT, 0);
-}
-
-static void __bnx2x_del_udp_port(struct bnx2x *bp, u16 port,
- enum bnx2x_udp_port_type type)
-{
- struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
-
- if (!IS_PF(bp) || CHIP_IS_E1x(bp))
- return;
-
- if (!udp_port->count || udp_port->dst_port != port) {
- DP(BNX2X_MSG_SP, "Invalid UDP tunnel [%d] port\n",
- type);
- return;
- }
-
- /* Remove reference, and make certain it's no longer in use */
- udp_port->count--;
- if (udp_port->count)
- return;
- udp_port->dst_port = 0;
-
- if (netif_running(bp->dev))
- bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_CHANGE_UDP_PORT, 0);
- else
- DP(BNX2X_MSG_SP, "Deleted UDP tunnel [%d] port %d\n",
- type, port);
-}
-
-static void bnx2x_udp_tunnel_add(struct net_device *netdev,
- struct udp_tunnel_info *ti)
+static int bnx2x_udp_tunnel_sync(struct net_device *netdev, unsigned int table)
{
struct bnx2x *bp = netdev_priv(netdev);
- u16 t_port = ntohs(ti->port);
+ struct udp_tunnel_info ti;
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- __bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- __bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
- break;
- default:
- break;
- }
-}
-
-static void bnx2x_udp_tunnel_del(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- struct bnx2x *bp = netdev_priv(netdev);
- u16 t_port = ntohs(ti->port);
+ udp_tunnel_nic_get_port(netdev, table, 0, &ti);
+ bp->udp_tunnel_ports[table] = be16_to_cpu(ti.port);
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- __bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
- break;
- default:
- break;
- }
+ return bnx2x_udp_port_update(bp);
}
+static const struct udp_tunnel_nic_info bnx2x_udp_tunnels = {
+ .sync_table = bnx2x_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
+ UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+ },
+};
+
static int bnx2x_close(struct net_device *dev);
/* bnx2x_nic_unload() flushes the bnx2x_wq, thus reset task is
@@ -10391,24 +10337,6 @@ sp_rtnl_not_reset:
if (test_and_clear_bit(BNX2X_SP_RTNL_UPDATE_SVID, &bp->sp_rtnl_state))
bnx2x_handle_update_svid_cmd(bp);
- if (test_and_clear_bit(BNX2X_SP_RTNL_CHANGE_UDP_PORT,
- &bp->sp_rtnl_state)) {
- if (bnx2x_udp_port_update(bp)) {
- /* On error, forget configuration */
- memset(bp->udp_tunnel_ports, 0,
- sizeof(struct bnx2x_udp_tunnel) *
- BNX2X_UDP_PORT_MAX);
- } else {
- /* Since we don't store additional port information,
- * if no ports are configured for any feature ask for
- * information about currently configured ports.
- */
- if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count &&
- !bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count)
- udp_tunnel_get_rx_info(bp->dev);
- }
- }
-
/* work which needs rtnl lock not-taken (as it takes the lock itself and
* can be called from other contexts as well)
*/
@@ -12604,9 +12532,6 @@ static int bnx2x_open(struct net_device *dev)
if (rc)
return rc;
- if (IS_PF(bp))
- udp_tunnel_get_rx_info(dev);
-
return 0;
}
@@ -13146,8 +13071,8 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_get_phys_port_id = bnx2x_get_phys_port_id,
.ndo_set_vf_link_state = bnx2x_set_vf_link_state,
.ndo_features_check = bnx2x_features_check,
- .ndo_udp_tunnel_add = bnx2x_udp_tunnel_add,
- .ndo_udp_tunnel_del = bnx2x_udp_tunnel_del,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
};
static int bnx2x_set_coherency_mask(struct bnx2x *bp)
@@ -13342,6 +13267,9 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
dev->gso_partial_features = NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_UDP_TUNNEL_CSUM;
+
+ if (IS_PF(bp))
+ dev->udp_tunnel_nic_info = &bnx2x_udp_tunnels;
}
dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
@@ -14462,8 +14390,7 @@ static struct pci_driver bnx2x_pci_driver = {
.id_table = bnx2x_pci_tbl,
.probe = bnx2x_init_one,
.remove = bnx2x_remove_one,
- .suspend = bnx2x_suspend,
- .resume = bnx2x_resume,
+ .driver.pm = &bnx2x_pm_ops,
.err_handler = &bnx2x_err_handler,
#ifdef CONFIG_BNX2X_SRIOV
.sriov_configure = bnx2x_sriov_configure,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index a43dea259b12..bfc0e45d4a2b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -7639,6 +7639,82 @@ Theotherbitsarereservedandshouldbezero*/
(0x80 | ((_type)&0xf << 3) | ((CDU_CRC8(_cid, _region, _type)) & 0x7))
#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
+/* IdleChk registers */
+#define PXP_REG_HST_VF_DISABLED_ERROR_VALID 0x1030bc
+#define PXP_REG_HST_VF_DISABLED_ERROR_DATA 0x1030b8
+#define PXP_REG_HST_PER_VIOLATION_VALID 0x1030e0
+#define PXP_REG_HST_INCORRECT_ACCESS_VALID 0x1030cc
+#define PXP2_REG_RD_CPL_ERR_DETAILS 0x120778
+#define PXP2_REG_RD_CPL_ERR_DETAILS2 0x12077c
+#define PXP2_REG_RQ_GARB 0x120748
+#define PBF_REG_DISABLE_NEW_TASK_PROC_Q0 0x15c1bc
+#define PBF_REG_DISABLE_NEW_TASK_PROC_Q1 0x15c1c0
+#define PBF_REG_DISABLE_NEW_TASK_PROC_Q2 0x15c1c4
+#define PBF_REG_DISABLE_NEW_TASK_PROC_Q3 0x15c1c8
+#define PBF_REG_DISABLE_NEW_TASK_PROC_Q4 0x15c1cc
+#define PBF_REG_DISABLE_NEW_TASK_PROC_Q5 0x15c1d0
+#define PBF_REG_CREDIT_Q2 0x140344
+#define PBF_REG_CREDIT_Q3 0x140348
+#define PBF_REG_CREDIT_Q4 0x14034c
+#define PBF_REG_CREDIT_Q5 0x140350
+#define PBF_REG_INIT_CRD_Q2 0x15c238
+#define PBF_REG_INIT_CRD_Q3 0x15c23c
+#define PBF_REG_INIT_CRD_Q4 0x15c240
+#define PBF_REG_INIT_CRD_Q5 0x15c244
+#define PBF_REG_TASK_CNT_Q0 0x140374
+#define PBF_REG_TASK_CNT_Q1 0x140378
+#define PBF_REG_TASK_CNT_Q2 0x14037c
+#define PBF_REG_TASK_CNT_Q3 0x140380
+#define PBF_REG_TASK_CNT_Q4 0x140384
+#define PBF_REG_TASK_CNT_Q5 0x140388
+#define PBF_REG_TASK_CNT_LB_Q 0x140370
+#define QM_REG_BYTECRD0 0x16e6fc
+#define QM_REG_BYTECRD1 0x16e700
+#define QM_REG_BYTECRD2 0x16e704
+#define QM_REG_BYTECRD3 0x16e7ac
+#define QM_REG_BYTECRD4 0x16e7b0
+#define QM_REG_BYTECRD5 0x16e7b4
+#define QM_REG_BYTECRD6 0x16e7b8
+#define QM_REG_BYTECRDCMDQ_0 0x16e6e8
+#define QM_REG_BYTECRDERRREG 0x16e708
+#define MISC_REG_GRC_TIMEOUT_ATTN_FULL_FID 0xa714
+#define QM_REG_VOQCREDIT_2 0x1682d8
+#define QM_REG_VOQCREDIT_3 0x1682dc
+#define QM_REG_VOQCREDIT_5 0x1682e4
+#define QM_REG_VOQCREDIT_6 0x1682e8
+#define QM_REG_VOQINITCREDIT_3 0x16806c
+#define QM_REG_VOQINITCREDIT_6 0x168078
+#define QM_REG_FWVOQ0TOHWVOQ 0x16e7bc
+#define QM_REG_FWVOQ1TOHWVOQ 0x16e7c0
+#define QM_REG_FWVOQ2TOHWVOQ 0x16e7c4
+#define QM_REG_FWVOQ3TOHWVOQ 0x16e7c8
+#define QM_REG_FWVOQ4TOHWVOQ 0x16e7cc
+#define QM_REG_FWVOQ5TOHWVOQ 0x16e7d0
+#define QM_REG_FWVOQ6TOHWVOQ 0x16e7d4
+#define QM_REG_FWVOQ7TOHWVOQ 0x16e7d8
+#define NIG_REG_INGRESS_EOP_PORT0_EMPTY 0x104ec
+#define NIG_REG_INGRESS_EOP_PORT1_EMPTY 0x104f8
+#define NIG_REG_INGRESS_RMP0_DSCR_EMPTY 0x10530
+#define NIG_REG_INGRESS_RMP1_DSCR_EMPTY 0x10538
+#define NIG_REG_INGRESS_LB_PBF_DELAY_EMPTY 0x10508
+#define NIG_REG_EGRESS_MNG0_FIFO_EMPTY 0x10460
+#define NIG_REG_EGRESS_MNG1_FIFO_EMPTY 0x10474
+#define NIG_REG_EGRESS_DEBUG_FIFO_EMPTY 0x10418
+#define NIG_REG_EGRESS_DELAY0_EMPTY 0x10420
+#define NIG_REG_EGRESS_DELAY1_EMPTY 0x10428
+#define NIG_REG_LLH0_FIFO_EMPTY 0x10548
+#define NIG_REG_LLH1_FIFO_EMPTY 0x10558
+#define NIG_REG_P0_TX_MNG_HOST_FIFO_EMPTY 0x182a8
+#define NIG_REG_P0_TLLH_FIFO_EMPTY 0x18308
+#define NIG_REG_P0_HBUF_DSCR_EMPTY 0x18318
+#define NIG_REG_P1_HBUF_DSCR_EMPTY 0x18348
+#define NIG_REG_P0_RX_MACFIFO_EMPTY 0x18570
+#define NIG_REG_P0_TX_MACFIFO_EMPTY 0x18578
+#define NIG_REG_EGRESS_DELAY2_EMPTY 0x1862c
+#define NIG_REG_EGRESS_DELAY3_EMPTY 0x18630
+#define NIG_REG_EGRESS_DELAY4_EMPTY 0x18634
+#define NIG_REG_EGRESS_DELAY5_EMPTY 0x18638
+
/******************************************************************************
* Description:
* Calculates crc 8 on a word value: polynomial 0-1-2-8
@@ -7697,6 +7773,4 @@ static inline u8 calc_crc8(u32 data, u8 crc)
return crc_res;
}
-
-
#endif /* BNX2X_REG_H */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_self_test.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_self_test.c
new file mode 100644
index 000000000000..3f8bdad3351c
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_self_test.c
@@ -0,0 +1,3183 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include "bnx2x.h"
+
+#define NA 0xCD
+
+#define IDLE_CHK_E1 0x01
+#define IDLE_CHK_E1H 0x02
+#define IDLE_CHK_E2 0x04
+#define IDLE_CHK_E3A0 0x08
+#define IDLE_CHK_E3B0 0x10
+
+#define IDLE_CHK_ERROR 1
+#define IDLE_CHK_ERROR_NO_TRAFFIC 2
+#define IDLE_CHK_WARNING 3
+
+#define MAX_FAIL_MSG 256
+
+/* statistics and error reporting */
+static int idle_chk_errors, idle_chk_warnings;
+
+/* masks for all chip types */
+static int is_e1, is_e1h, is_e2, is_e3a0, is_e3b0;
+
+/* struct for the argument list for a predicate in the self test databasei */
+struct st_pred_args {
+ u32 val1; /* value read from first register */
+ u32 val2; /* value read from second register, if applicable */
+ u32 imm1; /* 1st value in predicate condition, left-to-right */
+ u32 imm2; /* 2nd value in predicate condition, left-to-right */
+ u32 imm3; /* 3rd value in predicate condition, left-to-right */
+ u32 imm4; /* 4th value in predicate condition, left-to-right */
+};
+
+/* struct representing self test record - a single test */
+struct st_record {
+ u8 chip_mask;
+ u8 macro;
+ u32 reg1;
+ u32 reg2;
+ u16 loop;
+ u16 incr;
+ int (*bnx2x_predicate)(struct st_pred_args *pred_args);
+ u32 reg3;
+ u8 severity;
+ char *fail_msg;
+ struct st_pred_args pred_args;
+};
+
+/* predicates for self test */
+static int peq(struct st_pred_args *args)
+{
+ return (args->val1 == args->imm1);
+}
+
+static int pneq(struct st_pred_args *args)
+{
+ return (args->val1 != args->imm1);
+}
+
+static int pand_neq(struct st_pred_args *args)
+{
+ return ((args->val1 & args->imm1) != args->imm2);
+}
+
+static int pand_neq_x2(struct st_pred_args *args)
+{
+ return (((args->val1 & args->imm1) != args->imm2) &&
+ ((args->val1 & args->imm3) != args->imm4));
+}
+
+static int pneq_err(struct st_pred_args *args)
+{
+ return ((args->val1 != args->imm1) && (idle_chk_errors > args->imm2));
+}
+
+static int pgt(struct st_pred_args *args)
+{
+ return (args->val1 > args->imm1);
+}
+
+static int pneq_r2(struct st_pred_args *args)
+{
+ return (args->val1 != args->val2);
+}
+
+static int plt_sub_r2(struct st_pred_args *args)
+{
+ return (args->val1 < (args->val2 - args->imm1));
+}
+
+static int pne_sub_r2(struct st_pred_args *args)
+{
+ return (args->val1 != (args->val2 - args->imm1));
+}
+
+static int prsh_and_neq(struct st_pred_args *args)
+{
+ return (((args->val1 >> args->imm1) & args->imm2) != args->imm3);
+}
+
+static int peq_neq_r2(struct st_pred_args *args)
+{
+ return ((args->val1 == args->imm1) && (args->val2 != args->imm2));
+}
+
+static int peq_neq_neq_r2(struct st_pred_args *args)
+{
+ return ((args->val1 == args->imm1) && (args->val2 != args->imm2) &&
+ (args->val2 != args->imm3));
+}
+
+/* struct holding the database of self test checks (registers and predicates) */
+/* lines start from 2 since line 1 is heading in csv */
+#define ST_DB_LINES 468
+static struct st_record st_database[ST_DB_LINES] = {
+/*line 2*/{(0x3), 1, 0x2114,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "PCIE: ucorr_err_status is not 0",
+ {NA, NA, 0x0FF010, 0, NA, NA} },
+
+/*line 3*/{(0x3), 1, 0x2114,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "PCIE: ucorr_err_status - Unsupported request error",
+ {NA, NA, 0x100000, 0, NA, NA} },
+
+/*line 4*/{(0x3), 1, 0x2120,
+ NA, 1, 0, pand_neq_x2,
+ NA, IDLE_CHK_WARNING,
+ "PCIE: corr_err_status is not 0x2000",
+ {NA, NA, 0x31C1, 0x2000, 0x31C1, 0} },
+
+/*line 5*/{(0x3), 1, 0x2814,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "PCIE: attentions register is not 0x40100",
+ {NA, NA, ~0x40100, 0, NA, NA} },
+
+/*line 6*/{(0x2), 1, 0x281c,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "PCIE: attentions register is not 0x40040100",
+ {NA, NA, ~0x40040100, 0, NA, NA} },
+
+/*line 7*/{(0x2), 1, 0x2820,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "PCIE: attentions register is not 0x40040100",
+ {NA, NA, ~0x40040100, 0, NA, NA} },
+
+/*line 8*/{(0x3), 1, PXP2_REG_PGL_EXP_ROM2,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: There are outstanding read requests. Not all completios have arrived for read requests on tags that are marked with 0",
+ {NA, NA, 0xffffffff, NA, NA, NA} },
+
+/*line 9*/{(0x3), 2, 0x212c,
+ NA, 4, 4, pneq_err,
+ NA, IDLE_CHK_WARNING,
+ "PCIE: error packet header is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 10*/{(0x1C), 1, 0x2104,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "PCIE: ucorr_err_status is not 0",
+ {NA, NA, 0x0FD010, 0, NA, NA} },
+
+/*line 11*/{(0x1C), 1, 0x2104,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "PCIE: ucorr_err_status - Unsupported request error",
+ {NA, NA, 0x100000, 0, NA, NA} },
+
+/*line 12*/{(0x1C), 1, 0x2104,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "PCIE: ucorr_err_status - Flow Control Protocol Error",
+ {NA, NA, 0x2000, 0, NA, NA} },
+
+/*line 13*/{(0x1C), 1, 0x2110,
+ NA, 1, 0, pand_neq_x2,
+ NA, IDLE_CHK_WARNING,
+ "PCIE: corr_err_status is not 0x2000",
+ {NA, NA, 0x31C1, 0x2000, 0x31C1, 0} },
+
+/*line 14*/{(0x1C), 1, 0x2814,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "PCIE: TTX_BRIDGE_FORWARD_ERR - Received master request while BME was 0",
+ {NA, NA, 0x2000000, 0, NA, NA} },
+
+/*line 15*/{(0x1C), 1, 0x2814,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "PCIE: Func 0 1: attentions register is not 0x2040902",
+ {NA, NA, ~0x2040902, 0, NA, NA} },
+
+/*line 16*/{(0x1C), 1, 0x2854,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "PCIE: Func 2 3 4: attentions register is not 0x10240902",
+ {NA, NA, ~0x10240902, 0, NA, NA} },
+
+/*line 17*/{(0x1C), 1, 0x285c,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "PCIE: Func 5 6 7: attentions register is not 0x10240902",
+ {NA, NA, ~0x10240902, 0, NA, NA} },
+
+/*line 18*/{(0x18), 1, 0x3040,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "PCIE: Overflow in DLP2TLP buffer",
+ {NA, NA, 0x2, 0, NA, NA} },
+
+/*line 19*/{(0x1C), 1, PXP2_REG_PGL_EXP_ROM2,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: There are outstanding read requests for tags 0-31. Not all completios have arrived for read requests on tags that are marked with 0",
+ {NA, NA, 0xffffffff, NA, NA, NA} },
+
+/*line 20*/{(0x1C), 2, 0x211c,
+ NA, 4, 4, pneq_err,
+ NA, IDLE_CHK_WARNING,
+ "PCIE: error packet header is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 21*/{(0x1C), 1, PGLUE_B_REG_INCORRECT_RCV_DETAILS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PGLUE_B: Packet received from PCIe not according to the rules",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 22*/{(0x1C), 1, PGLUE_B_REG_WAS_ERROR_VF_31_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: was_error for VFs 0-31 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 23*/{(0x1C), 1, PGLUE_B_REG_WAS_ERROR_VF_63_32,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: was_error for VFs 32-63 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 24*/{(0x1C), 1, PGLUE_B_REG_WAS_ERROR_VF_95_64,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: was_error for VFs 64-95 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 25*/{(0x1C), 1, PGLUE_B_REG_WAS_ERROR_VF_127_96,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: was_error for VFs 96-127 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 26*/{(0x1C), 1, PGLUE_B_REG_WAS_ERROR_PF_7_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: was_error for PFs 0-7 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 27*/{(0x1C), 1, PGLUE_B_REG_RX_ERR_DETAILS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Completion received with error. (2:0) - PFID. (3) - VF_VALID. (9:4) - VFID. (11:10) - Error code : 0 - Completion Timeout; 1 - Unsupported Request; 2 - Completer Abort. (12) - valid bit",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 28*/{(0x1C), 1, PGLUE_B_REG_RX_TCPL_ERR_DETAILS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: ATS TCPL received with error. (2:0) - PFID. (3) - VF_VALID. (9:4) - VFID. (11:10) - Error code : 0 - Completion Timeout ; 1 - Unsupported Request; 2 - Completer Abort. (16:12) - OTB Entry ID. (17) - valid bit",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 29*/{(0x1C), 1, PGLUE_B_REG_TX_ERR_WR_ADD_31_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Error in master write. Address(31:0) is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 30*/{(0x1C), 1, PGLUE_B_REG_TX_ERR_WR_ADD_63_32,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Error in master write. Address(63:32) is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 31*/{(0x1C), 1, PGLUE_B_REG_TX_ERR_WR_DETAILS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Error in master write. Error details register is not 0. (4:0) VQID. (23:21) - PFID. (24) - VF_VALID. (30:25) - VFID",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 32*/{(0x1C), 1, PGLUE_B_REG_TX_ERR_WR_DETAILS2,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Error in master write. Error details 2nd register is not 0. (21) - was_error set; (22) - BME cleared; (23) - FID_enable cleared; (24) - VF with parent PF FLR_request or IOV_disable_request",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 33*/{(0x1C), 1, PGLUE_B_REG_TX_ERR_RD_ADD_31_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE: Error in master read address(31:0) is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 34*/{(0x1C), 1, PGLUE_B_REG_TX_ERR_RD_ADD_63_32,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Error in master read address(63:32) is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 35*/{(0x1C), 1, PGLUE_B_REG_TX_ERR_RD_DETAILS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Error in master read Error details register is not 0. (4:0) VQID. (23:21) - PFID. (24) - VF_VALID. (30:25) - VFID",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 36*/{(0x1C), 1, PGLUE_B_REG_TX_ERR_RD_DETAILS2,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Error in master read Error details 2nd register is not 0. (21) - was_error set; (22) - BME cleared; (23) - FID_enable cleared; (24) - VF with parent PF FLR_request or IOV_disable_request",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 37*/{(0x1C), 1, PGLUE_B_REG_VF_LENGTH_VIOLATION_DETAILS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Target VF length violation access",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 38*/{(0x1C), 1, PGLUE_B_REG_VF_GRC_SPACE_VIOLATION_DETAILS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Target VF GRC space access failed permission check",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 39*/{(0x1C), 1, PGLUE_B_REG_TAGS_63_32,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: There are outstanding read requests for tags 32-63. Not all completios have arrived for read requests on tags that are marked with 0",
+ {NA, NA, 0xffffffff, NA, NA, NA} },
+
+/*line 40*/{(0x1C), 3, PXP_REG_HST_VF_DISABLED_ERROR_VALID,
+ PXP_REG_HST_VF_DISABLED_ERROR_DATA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: Access to disabled VF took place",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 41*/{(0x1C), 1, PXP_REG_HST_PER_VIOLATION_VALID,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: Zone A permission violation occurred",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 42*/{(0x1C), 1, PXP_REG_HST_INCORRECT_ACCESS_VALID,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: Incorrect transaction took place",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 43*/{(0x1C), 1, PXP2_REG_RD_CPL_ERR_DETAILS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: Completion received with error. Error details register is not 0. (15:0) - ECHO. (28:16) - Sub Request length plus start_offset_2_0 minus 1",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 44*/{(0x1C), 1, PXP2_REG_RD_CPL_ERR_DETAILS2,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: Completion received with error. Error details 2nd register is not 0. (4:0) - VQ ID. (8:5) - client ID. (9) - valid bit",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 45*/{(0x1F), 1, PXP2_REG_RQ_VQ0_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ0 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 46*/{(0x1F), 1, PXP2_REG_RQ_VQ1_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ1 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 47*/{(0x1F), 1, PXP2_REG_RQ_VQ2_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ2 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 48*/{(0x1F), 1, PXP2_REG_RQ_VQ3_ENTRY_CNT,
+ NA, 1, 0, pgt,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ3 is not empty",
+ {NA, NA, 2, NA, NA, NA} },
+
+/*line 49*/{(0x1F), 1, PXP2_REG_RQ_VQ4_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ4 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 50*/{(0x1F), 1, PXP2_REG_RQ_VQ5_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ5 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 51*/{(0x1F), 1, PXP2_REG_RQ_VQ6_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ6 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 52*/{(0x1F), 1, PXP2_REG_RQ_VQ7_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ7 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 53*/{(0x1F), 1, PXP2_REG_RQ_VQ8_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ8 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 54*/{(0x1F), 1, PXP2_REG_RQ_VQ9_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ9 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 55*/{(0x1F), 1, PXP2_REG_RQ_VQ10_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ10 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 56*/{(0x1F), 1, PXP2_REG_RQ_VQ11_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ11 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 57*/{(0x1F), 1, PXP2_REG_RQ_VQ12_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ12 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 58*/{(0x1F), 1, PXP2_REG_RQ_VQ13_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ13 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 59*/{(0x1F), 1, PXP2_REG_RQ_VQ14_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ14 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 60*/{(0x1F), 1, PXP2_REG_RQ_VQ15_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ15 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 61*/{(0x1F), 1, PXP2_REG_RQ_VQ16_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ16 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 62*/{(0x1F), 1, PXP2_REG_RQ_VQ17_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ17 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 63*/{(0x1F), 1, PXP2_REG_RQ_VQ18_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ18 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 64*/{(0x1F), 1, PXP2_REG_RQ_VQ19_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ19 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 65*/{(0x1F), 1, PXP2_REG_RQ_VQ20_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ20 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 66*/{(0x1F), 1, PXP2_REG_RQ_VQ21_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ21 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 67*/{(0x1F), 1, PXP2_REG_RQ_VQ22_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ22 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 68*/{(0x1F), 1, PXP2_REG_RQ_VQ23_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ23 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 69*/{(0x1F), 1, PXP2_REG_RQ_VQ24_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ24 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 70*/{(0x1F), 1, PXP2_REG_RQ_VQ25_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ25 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 71*/{(0x1F), 1, PXP2_REG_RQ_VQ26_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ26 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 72*/{(0x1F), 1, PXP2_REG_RQ_VQ27_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ27 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 73*/{(0x1F), 1, PXP2_REG_RQ_VQ28_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ28 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 74*/{(0x1F), 1, PXP2_REG_RQ_VQ29_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ29 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 75*/{(0x1F), 1, PXP2_REG_RQ_VQ30_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ30 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 76*/{(0x1F), 1, PXP2_REG_RQ_VQ31_ENTRY_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: VQ31 is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 77*/{(0x1F), 1, PXP2_REG_RQ_UFIFO_NUM_OF_ENTRY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: rq_ufifo_num_of_entry is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 78*/{(0x1F), 1, PXP2_REG_RQ_RBC_DONE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PXP2: rq_rbc_done is not 1",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 79*/{(0x1F), 1, PXP2_REG_RQ_CFG_DONE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PXP2: rq_cfg_done is not 1",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 80*/{(0x3), 1, PXP2_REG_PSWRQ_BW_CREDIT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: rq_read_credit and rq_write_credit are not 3",
+ {NA, NA, 0x1B, NA, NA, NA} },
+
+/*line 81*/{(0x1F), 1, PXP2_REG_RD_START_INIT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PXP2: rd_start_init is not 1",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 82*/{(0x1F), 1, PXP2_REG_RD_INIT_DONE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PXP2: rd_init_done is not 1",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 83*/{(0x1F), 3, PXP2_REG_RD_SR_CNT,
+ PXP2_REG_RD_SR_NUM_CFG, 1, 0, pne_sub_r2,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: rd_sr_cnt is not equal to rd_sr_num_cfg",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 84*/{(0x1F), 3, PXP2_REG_RD_BLK_CNT,
+ PXP2_REG_RD_BLK_NUM_CFG, 1, 0, pneq_r2,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: rd_blk_cnt is not equal to rd_blk_num_cfg",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 85*/{(0x1F), 3, PXP2_REG_RD_SR_CNT,
+ PXP2_REG_RD_SR_NUM_CFG, 1, 0, plt_sub_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: There are more than two unused SRs",
+ {NA, NA, 3, NA, NA, NA} },
+
+/*line 86*/{(0x1F), 3, PXP2_REG_RD_BLK_CNT,
+ PXP2_REG_RD_BLK_NUM_CFG, 1, 0, plt_sub_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: There are more than two unused blocks",
+ {NA, NA, 2, NA, NA, NA} },
+
+/*line 87*/{(0x1F), 1, PXP2_REG_RD_PORT_IS_IDLE_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: P0 All delivery ports are not idle",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 88*/{(0x1F), 1, PXP2_REG_RD_PORT_IS_IDLE_1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: P1 All delivery ports are not idle",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 89*/{(0x1F), 2, PXP2_REG_RD_ALMOST_FULL_0,
+ NA, 11, 4, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: rd_almost_full is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 90*/{(0x1F), 1, PXP2_REG_RD_DISABLE_INPUTS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PXP2: PSWRD inputs are disabled",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 91*/{(0x1F), 1, PXP2_REG_HST_HEADER_FIFO_STATUS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: HST header FIFO status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 92*/{(0x1F), 1, PXP2_REG_HST_DATA_FIFO_STATUS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: HST data FIFO status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 93*/{(0x3), 1, PXP2_REG_PGL_WRITE_BLOCKED,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PXP2: pgl_write_blocked is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 94*/{(0x3), 1, PXP2_REG_PGL_READ_BLOCKED,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PXP2: pgl_read_blocked is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 95*/{(0x1C), 1, PXP2_REG_PGL_WRITE_BLOCKED,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: pgl_write_blocked is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 96*/{(0x1C), 1, PXP2_REG_PGL_READ_BLOCKED,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: pgl_read_blocked is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 97*/{(0x1F), 1, PXP2_REG_PGL_TXW_CDTS,
+ NA, 1, 0, prsh_and_neq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PXP2: There is data which is ready",
+ {NA, NA, 17, 1, 0, NA} },
+
+/*line 98*/{(0x1F), 1, PXP_REG_HST_ARB_IS_IDLE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: HST arbiter is not idle",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 99*/{(0x1F), 1, PXP_REG_HST_CLIENTS_WAITING_TO_ARB,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: HST one of the clients is waiting for delivery",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 100*/{(0x1E), 1, PXP_REG_HST_DISCARD_INTERNAL_WRITES_STATUS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: HST Close the gates: Discarding internal writes",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 101*/{(0x1E), 1, PXP_REG_HST_DISCARD_DOORBELLS_STATUS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: HST Close the gates: Discarding doorbells",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 102*/{(0x1C), 1, PXP2_REG_RQ_GARB,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: PSWRQ Close the gates is asserted. Check AEU AFTER_INVERT registers for parity errors",
+ {NA, NA, 0x1000, 0, NA, NA} },
+
+/*line 103*/{(0x1F), 1, DMAE_REG_GO_C0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 0 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 104*/{(0x1F), 1, DMAE_REG_GO_C1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 1 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 105*/{(0x1F), 1, DMAE_REG_GO_C2,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 2 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 106*/{(0x1F), 1, DMAE_REG_GO_C3,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 3 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 107*/{(0x1F), 1, DMAE_REG_GO_C4,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 4 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 108*/{(0x1F), 1, DMAE_REG_GO_C5,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 5 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 109*/{(0x1F), 1, DMAE_REG_GO_C6,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 6 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 110*/{(0x1F), 1, DMAE_REG_GO_C7,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 7 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 111*/{(0x1F), 1, DMAE_REG_GO_C8,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 8 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 112*/{(0x1F), 1, DMAE_REG_GO_C9,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 9 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 113*/{(0x1F), 1, DMAE_REG_GO_C10,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 10 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 114*/{(0x1F), 1, DMAE_REG_GO_C11,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 11 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 115*/{(0x1F), 1, DMAE_REG_GO_C12,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 12 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 116*/{(0x1F), 1, DMAE_REG_GO_C13,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 13 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 117*/{(0x1F), 1, DMAE_REG_GO_C14,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 14 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 118*/{(0x1F), 1, DMAE_REG_GO_C15,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DMAE: command 15 go is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 119*/{(0x1F), 1, CFC_REG_ERROR_VECTOR,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CFC: error vector is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 120*/{(0x1F), 1, CFC_REG_NUM_LCIDS_ARRIVING,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CFC: number of arriving LCIDs is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 121*/{(0x1F), 1, CFC_REG_NUM_LCIDS_ALLOC,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CFC: number of alloc LCIDs is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 122*/{(0x1F), 1, CFC_REG_NUM_LCIDS_LEAVING,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CFC: number of leaving LCIDs is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 123*/{(0x1F), 7, CFC_REG_INFO_RAM,
+ CFC_REG_CID_CAM, (CFC_REG_INFO_RAM_SIZE >> 4), 16, peq_neq_neq_r2,
+ CFC_REG_ACTIVITY_COUNTER, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CFC: AC is neither 0 nor 2 on connType 0 (ETH)",
+ {NA, NA, 0, 0, 2, NA} },
+
+/*line 124*/{(0x1F), 7, CFC_REG_INFO_RAM,
+ CFC_REG_CID_CAM, (CFC_REG_INFO_RAM_SIZE >> 4), 16, peq_neq_r2,
+ CFC_REG_ACTIVITY_COUNTER, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CFC: AC is not 0 on connType 1 (TOE)",
+ {NA, NA, 1, 0, NA, NA} },
+
+/*line 125*/{(0x1F), 7, CFC_REG_INFO_RAM,
+ CFC_REG_CID_CAM, (CFC_REG_INFO_RAM_SIZE >> 4), 16, peq_neq_r2,
+ CFC_REG_ACTIVITY_COUNTER, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CFC: AC is not 0 on connType 3 (iSCSI)",
+ {NA, NA, 3, 0, NA, NA} },
+
+/*line 126*/{(0x1F), 7, CFC_REG_INFO_RAM,
+ CFC_REG_CID_CAM, (CFC_REG_INFO_RAM_SIZE >> 4), 16, peq_neq_r2,
+ CFC_REG_ACTIVITY_COUNTER, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CFC: AC is not 0 on connType 4 (FCoE)",
+ {NA, NA, 4, 0, NA, NA} },
+
+/*line 127*/{(0x1F), 2, QM_REG_QTASKCTR_0,
+ NA, 64, 4, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Queue is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 128*/{(0xF), 3, QM_REG_VOQCREDIT_0,
+ QM_REG_VOQINITCREDIT_0, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_0, VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 129*/{(0xF), 3, QM_REG_VOQCREDIT_1,
+ QM_REG_VOQINITCREDIT_1, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_1, VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 130*/{(0xF), 3, QM_REG_VOQCREDIT_4,
+ QM_REG_VOQINITCREDIT_4, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_4, VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 131*/{(0x3), 3, QM_REG_PORT0BYTECRD,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: P0 Byte credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 132*/{(0x3), 3, QM_REG_PORT1BYTECRD,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: P1 Byte credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 133*/{(0x1F), 1, CCM_REG_CAM_OCCUP,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CCM: XX protection CAM is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 134*/{(0x1F), 1, TCM_REG_CAM_OCCUP,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TCM: XX protection CAM is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 135*/{(0x1F), 1, UCM_REG_CAM_OCCUP,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "UCM: XX protection CAM is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 136*/{(0x1F), 1, XCM_REG_CAM_OCCUP,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XCM: XX protection CAM is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 137*/{(0x1F), 1, BRB1_REG_NUM_OF_FULL_BLOCKS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "BRB1: BRB is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 138*/{(0x1F), 1, CSEM_REG_SLEEP_THREADS_VALID,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CSEM: There are sleeping threads",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 139*/{(0x1F), 1, TSEM_REG_SLEEP_THREADS_VALID,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TSEM: There are sleeping threads",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 140*/{(0x1F), 1, USEM_REG_SLEEP_THREADS_VALID,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "USEM: There are sleeping threads",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 141*/{(0x1F), 1, XSEM_REG_SLEEP_THREADS_VALID,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XSEM: There are sleeping threads",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 142*/{(0x1F), 1, CSEM_REG_SLOW_EXT_STORE_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CSEM: External store FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 143*/{(0x1F), 1, TSEM_REG_SLOW_EXT_STORE_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TSEM: External store FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 144*/{(0x1F), 1, USEM_REG_SLOW_EXT_STORE_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "USEM: External store FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 145*/{(0x1F), 1, XSEM_REG_SLOW_EXT_STORE_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XSEM: External store FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 146*/{(0x1F), 1, CSDM_REG_SYNC_PARSER_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CSDM: Parser serial FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 147*/{(0x1F), 1, TSDM_REG_SYNC_PARSER_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TSDM: Parser serial FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 148*/{(0x1F), 1, USDM_REG_SYNC_PARSER_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "USDM: Parser serial FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 149*/{(0x1F), 1, XSDM_REG_SYNC_PARSER_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XSDM: Parser serial FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 150*/{(0x1F), 1, CSDM_REG_SYNC_SYNC_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CSDM: Parser SYNC serial FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 151*/{(0x1F), 1, TSDM_REG_SYNC_SYNC_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TSDM: Parser SYNC serial FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 152*/{(0x1F), 1, USDM_REG_SYNC_SYNC_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "USDM: Parser SYNC serial FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 153*/{(0x1F), 1, XSDM_REG_SYNC_SYNC_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XSDM: Parser SYNC serial FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 154*/{(0x1F), 1, CSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CSDM: pxp_ctrl rd_data fifo is not empty in sdm_dma_rsp block",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 155*/{(0x1F), 1, TSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TSDM: pxp_ctrl rd_data fifo is not empty in sdm_dma_rsp block",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 156*/{(0x1F), 1, USDM_REG_RSP_PXP_CTRL_RDATA_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "USDM: pxp_ctrl rd_data fifo is not empty in sdm_dma_rsp block",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 157*/{(0x1F), 1, XSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XSDM: pxp_ctrl rd_data fifo is not empty in sdm_dma_rsp block",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 158*/{(0x1F), 1, DORQ_REG_DQ_FILL_LVLF,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DORQ: DORQ queue is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 159*/{(0x1F), 1, CFC_REG_CFC_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CFC: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 160*/{(0x1F), 1, CDU_REG_CDU_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CDU: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 161*/{(0x1F), 1, CCM_REG_CCM_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CCM: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 162*/{(0x1F), 1, TCM_REG_TCM_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TCM: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 163*/{(0x1F), 1, UCM_REG_UCM_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "UCM: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 164*/{(0x1F), 1, XCM_REG_XCM_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 165*/{(0xF), 1, PBF_REG_PBF_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PBF: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 166*/{(0x1F), 1, TM_REG_TM_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TIMERS: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 167*/{(0x1F), 1, DORQ_REG_DORQ_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "DORQ: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 168*/{(0x1F), 1, SRC_REG_SRC_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "SRCH: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 169*/{(0x1F), 1, PRS_REG_PRS_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PRS: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 170*/{(0x1F), 1, BRB1_REG_BRB1_INT_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "BRB1: Interrupt status is not 0",
+ {NA, NA, ~0xFC00, 0, NA, NA} },
+
+/*line 171*/{(0x1F), 1, GRCBASE_XPB + PB_REG_PB_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XPB: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 172*/{(0x1F), 1, GRCBASE_UPB + PB_REG_PB_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "UPB: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 173*/{(0x1), 1, PXP2_REG_PXP2_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: Interrupt status 0 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 174*/{(0x1E), 1, PXP2_REG_PXP2_INT_STS_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: Interrupt status 0 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 175*/{(0x1E), 1, PXP2_REG_PXP2_INT_STS_1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: Interrupt status 1 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 176*/{(0x1F), 1, QM_REG_QM_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 177*/{(0x1F), 1, PXP_REG_PXP_INT_STS_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: P0 Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 178*/{(0x1F), 1, PXP_REG_PXP_INT_STS_1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: P1 Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 179*/{(0x1C), 1, PGLUE_B_REG_PGLUE_B_INT_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: Interrupt status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 180*/{(0x1F), 1, DORQ_REG_RSPA_CRD_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DORQ: Credit to XCM is not full",
+ {NA, NA, 2, NA, NA, NA} },
+
+/*line 181*/{(0x1F), 1, DORQ_REG_RSPB_CRD_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "DORQ: Credit to UCM is not full",
+ {NA, NA, 2, NA, NA, NA} },
+
+/*line 182*/{(0x3), 1, QM_REG_VOQCRDERRREG,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: Credit error register is not 0 (byte or credit overflow/underflow)",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 183*/{(0x1F), 1, DORQ_REG_DQ_FULL_ST,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "DORQ: DORQ queue is full",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 184*/{(0x1F), 1, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "AEU: P0 AFTER_INVERT_1 is not 0",
+ {NA, NA, ~0xCFFC, 0, NA, NA} },
+
+/*line 185*/{(0x1F), 1, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "AEU: P0 AFTER_INVERT_2 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 186*/{(0x1F), 1, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "AEU: P0 AFTER_INVERT_3 is not 0",
+ {NA, NA, ~0xFFFF0000, 0, NA, NA} },
+
+/*line 187*/{(0x1F), 1, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "AEU: P0 AFTER_INVERT_4 is not 0",
+ {NA, NA, ~0x801FFFFF, 0, NA, NA} },
+
+/*line 188*/{(0x3), 1, MISC_REG_AEU_AFTER_INVERT_1_FUNC_1,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "AEU: P1 AFTER_INVERT_1 is not 0",
+ {NA, NA, ~0xCFFC, 0, NA, NA} },
+
+/*line 189*/{(0x3), 1, MISC_REG_AEU_AFTER_INVERT_2_FUNC_1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "AEU: P1 AFTER_INVERT_2 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 190*/{(0x3), 1, MISC_REG_AEU_AFTER_INVERT_3_FUNC_1,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "AEU: P1 AFTER_INVERT_3 is not 0",
+ {NA, NA, ~0xFFFF0000, 0, NA, NA} },
+
+/*line 191*/{(0x3), 1, MISC_REG_AEU_AFTER_INVERT_4_FUNC_1,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "AEU: P1 AFTER_INVERT_4 is not 0",
+ {NA, NA, ~0x801FFFFF, 0, NA, NA} },
+
+/*line 192*/{(0x1F), 1, MISC_REG_AEU_AFTER_INVERT_1_MCP,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "AEU: MCP AFTER_INVERT_1 is not 0",
+ {NA, NA, ~0xCFFC, 0, NA, NA} },
+
+/*line 193*/{(0x1F), 1, MISC_REG_AEU_AFTER_INVERT_2_MCP,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "AEU: MCP AFTER_INVERT_2 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 194*/{(0x1F), 1, MISC_REG_AEU_AFTER_INVERT_3_MCP,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "AEU: MCP AFTER_INVERT_3 is not 0",
+ {NA, NA, ~0xFFFF0000, 0, NA, NA} },
+
+/*line 195*/{(0x1F), 1, MISC_REG_AEU_AFTER_INVERT_4_MCP,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "AEU: MCP AFTER_INVERT_4 is not 0",
+ {NA, NA, ~0x801FFFFF, 0, NA, NA} },
+
+/*line 196*/{(0xF), 5, PBF_REG_P0_CREDIT,
+ PBF_REG_P0_INIT_CRD, 1, 0, pneq_r2,
+ PBF_REG_DISABLE_NEW_TASK_PROC_P0, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: P0 credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 197*/{(0xF), 5, PBF_REG_P1_CREDIT,
+ PBF_REG_P1_INIT_CRD, 1, 0, pneq_r2,
+ PBF_REG_DISABLE_NEW_TASK_PROC_P1, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: P1 credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 198*/{(0xF), 3, PBF_REG_P4_CREDIT,
+ PBF_REG_P4_INIT_CRD, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: P4 credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 199*/{(0x10), 5, PBF_REG_CREDIT_Q0,
+ PBF_REG_INIT_CRD_Q0, 1, 0, pneq_r2,
+ PBF_REG_DISABLE_NEW_TASK_PROC_Q0, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q0 credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 200*/{(0x10), 5, PBF_REG_CREDIT_Q1,
+ PBF_REG_INIT_CRD_Q1, 1, 0, pneq_r2,
+ PBF_REG_DISABLE_NEW_TASK_PROC_Q1, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q1 credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 201*/{(0x10), 5, PBF_REG_CREDIT_Q2,
+ PBF_REG_INIT_CRD_Q2, 1, 0, pneq_r2,
+ PBF_REG_DISABLE_NEW_TASK_PROC_Q2, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q2 credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 202*/{(0x10), 5, PBF_REG_CREDIT_Q3,
+ PBF_REG_INIT_CRD_Q3, 1, 0, pneq_r2,
+ PBF_REG_DISABLE_NEW_TASK_PROC_Q3, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q3 credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 203*/{(0x10), 5, PBF_REG_CREDIT_Q4,
+ PBF_REG_INIT_CRD_Q4, 1, 0, pneq_r2,
+ PBF_REG_DISABLE_NEW_TASK_PROC_Q4, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q4 credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 204*/{(0x10), 5, PBF_REG_CREDIT_Q5,
+ PBF_REG_INIT_CRD_Q5, 1, 0, pneq_r2,
+ PBF_REG_DISABLE_NEW_TASK_PROC_Q5, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q5 credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 205*/{(0x10), 3, PBF_REG_CREDIT_LB_Q,
+ PBF_REG_INIT_CRD_LB_Q, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: LB Q credit is not equal to init_crd",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 206*/{(0xF), 1, PBF_REG_P0_TASK_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: P0 task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 207*/{(0xF), 1, PBF_REG_P1_TASK_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: P1 task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 208*/{(0xF), 1, PBF_REG_P4_TASK_CNT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: P4 task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 209*/{(0x10), 1, PBF_REG_TASK_CNT_Q0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q0 task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 210*/{(0x10), 1, PBF_REG_TASK_CNT_Q1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q1 task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 211*/{(0x10), 1, PBF_REG_TASK_CNT_Q2,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q2 task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 212*/{(0x10), 1, PBF_REG_TASK_CNT_Q3,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q3 task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 213*/{(0x10), 1, PBF_REG_TASK_CNT_Q4,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q4 task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 214*/{(0x10), 1, PBF_REG_TASK_CNT_Q5,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: Q5 task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 215*/{(0x10), 1, PBF_REG_TASK_CNT_LB_Q,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PBF: LB Q task_cnt is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 216*/{(0x1F), 1, XCM_REG_CFC_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XCM: CFC_INIT_CRD is not 1",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 217*/{(0x1F), 1, UCM_REG_CFC_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "UCM: CFC_INIT_CRD is not 1",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 218*/{(0x1F), 1, TCM_REG_CFC_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TCM: CFC_INIT_CRD is not 1",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 219*/{(0x1F), 1, CCM_REG_CFC_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CCM: CFC_INIT_CRD is not 1",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 220*/{(0x1F), 1, XCM_REG_XQM_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XCM: XQM_INIT_CRD is not 32",
+ {NA, NA, 32, NA, NA, NA} },
+
+/*line 221*/{(0x1F), 1, UCM_REG_UQM_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "UCM: UQM_INIT_CRD is not 32",
+ {NA, NA, 32, NA, NA, NA} },
+
+/*line 222*/{(0x1F), 1, TCM_REG_TQM_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TCM: TQM_INIT_CRD is not 32",
+ {NA, NA, 32, NA, NA, NA} },
+
+/*line 223*/{(0x1F), 1, CCM_REG_CQM_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CCM: CQM_INIT_CRD is not 32",
+ {NA, NA, 32, NA, NA, NA} },
+
+/*line 224*/{(0x1F), 1, XCM_REG_TM_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XCM: TM_INIT_CRD is not 4",
+ {NA, NA, 4, NA, NA, NA} },
+
+/*line 225*/{(0x1F), 1, UCM_REG_TM_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "UCM: TM_INIT_CRD is not 4",
+ {NA, NA, 4, NA, NA, NA} },
+
+/*line 226*/{(0x1F), 1, XCM_REG_FIC0_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "XCM: FIC0_INIT_CRD is not 64",
+ {NA, NA, 64, NA, NA, NA} },
+
+/*line 227*/{(0x1F), 1, UCM_REG_FIC0_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "UCM: FIC0_INIT_CRD is not 64",
+ {NA, NA, 64, NA, NA, NA} },
+
+/*line 228*/{(0x1F), 1, TCM_REG_FIC0_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TCM: FIC0_INIT_CRD is not 64",
+ {NA, NA, 64, NA, NA, NA} },
+
+/*line 229*/{(0x1F), 1, CCM_REG_FIC0_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CCM: FIC0_INIT_CRD is not 64",
+ {NA, NA, 64, NA, NA, NA} },
+
+/*line 230*/{(0x1F), 1, XCM_REG_FIC1_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XCM: FIC1_INIT_CRD is not 64",
+ {NA, NA, 64, NA, NA, NA} },
+
+/*line 231*/{(0x1F), 1, UCM_REG_FIC1_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "UCM: FIC1_INIT_CRD is not 64",
+ {NA, NA, 64, NA, NA, NA} },
+
+/*line 232*/{(0x1F), 1, TCM_REG_FIC1_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TCM: FIC1_INIT_CRD is not 64",
+ {NA, NA, 64, NA, NA, NA} },
+
+/*line 233*/{(0x1F), 1, CCM_REG_FIC1_INIT_CRD,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CCM: FIC1_INIT_CRD is not 64",
+ {NA, NA, 64, NA, NA, NA} },
+
+/*line 234*/{(0x1), 1, XCM_REG_XX_FREE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XCM: XX_FREE differs from expected 31",
+ {NA, NA, 31, NA, NA, NA} },
+
+/*line 235*/{(0x1E), 1, XCM_REG_XX_FREE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XCM: XX_FREE differs from expected 32",
+ {NA, NA, 32, NA, NA, NA} },
+
+/*line 236*/{(0x1F), 1, UCM_REG_XX_FREE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "UCM: XX_FREE differs from expected 27",
+ {NA, NA, 27, NA, NA, NA} },
+
+/*line 237*/{(0x7), 1, TCM_REG_XX_FREE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TCM: XX_FREE differs from expected 32",
+ {NA, NA, 32, NA, NA, NA} },
+
+/*line 238*/{(0x18), 1, TCM_REG_XX_FREE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TCM: XX_FREE differs from expected 29",
+ {NA, NA, 29, NA, NA, NA} },
+
+/*line 239*/{(0x1F), 1, CCM_REG_XX_FREE,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CCM: XX_FREE differs from expected 24",
+ {NA, NA, 24, NA, NA, NA} },
+
+/*line 240*/{(0x1F), 1, XSEM_REG_FAST_MEMORY + 0x18000,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XSEM: FOC0 credit less than initial credit",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 241*/{(0x1F), 1, XSEM_REG_FAST_MEMORY + 0x18040,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XSEM: FOC1 credit less than initial credit",
+ {NA, NA, 24, NA, NA, NA} },
+
+/*line 242*/{(0x1F), 1, XSEM_REG_FAST_MEMORY + 0x18080,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "XSEM: FOC2 credit less than initial credit",
+ {NA, NA, 12, NA, NA, NA} },
+
+/*line 243*/{(0x1F), 1, USEM_REG_FAST_MEMORY + 0x18000,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "USEM: FOC0 credit less than initial credit",
+ {NA, NA, 26, NA, NA, NA} },
+
+/*line 244*/{(0x1F), 1, USEM_REG_FAST_MEMORY + 0x18040,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "USEM: FOC1 credit less than initial credit",
+ {NA, NA, 78, NA, NA, NA} },
+
+/*line 245*/{(0x1F), 1, USEM_REG_FAST_MEMORY + 0x18080,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "USEM: FOC2 credit less than initial credit",
+ {NA, NA, 16, NA, NA, NA} },
+
+/*line 246*/{(0x1F), 1, USEM_REG_FAST_MEMORY + 0x180C0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "USEM: FOC3 credit less than initial credit",
+ {NA, NA, 32, NA, NA, NA} },
+
+/*line 247*/{(0x1F), 1, TSEM_REG_FAST_MEMORY + 0x18000,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TSEM: FOC0 credit less than initial credit",
+ {NA, NA, 52, NA, NA, NA} },
+
+/*line 248*/{(0x1F), 1, TSEM_REG_FAST_MEMORY + 0x18040,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TSEM: FOC1 credit less than initial credit",
+ {NA, NA, 24, NA, NA, NA} },
+
+/*line 249*/{(0x1F), 1, TSEM_REG_FAST_MEMORY + 0x18080,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TSEM: FOC2 credit less than initial credit",
+ {NA, NA, 12, NA, NA, NA} },
+
+/*line 250*/{(0x1F), 1, TSEM_REG_FAST_MEMORY + 0x180C0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "TSEM: FOC3 credit less than initial credit",
+ {NA, NA, 32, NA, NA, NA} },
+
+/*line 251*/{(0x1F), 1, CSEM_REG_FAST_MEMORY + 0x18000,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CSEM: FOC0 credit less than initial credit",
+ {NA, NA, 16, NA, NA, NA} },
+
+/*line 252*/{(0x1F), 1, CSEM_REG_FAST_MEMORY + 0x18040,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CSEM: FOC1 credit less than initial credit",
+ {NA, NA, 18, NA, NA, NA} },
+
+/*line 253*/{(0x1F), 1, CSEM_REG_FAST_MEMORY + 0x18080,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CSEM: FOC2 credit less than initial credit",
+ {NA, NA, 48, NA, NA, NA} },
+
+/*line 254*/{(0x1F), 1, CSEM_REG_FAST_MEMORY + 0x180C0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "CSEM: FOC3 credit less than initial credit",
+ {NA, NA, 14, NA, NA, NA} },
+
+/*line 255*/{(0x1F), 1, PRS_REG_TSDM_CURRENT_CREDIT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PRS: TSDM current credit is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 256*/{(0x1F), 1, PRS_REG_TCM_CURRENT_CREDIT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PRS: TCM current credit is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 257*/{(0x1F), 1, PRS_REG_CFC_LD_CURRENT_CREDIT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PRS: CFC_LD current credit is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 258*/{(0x1F), 1, PRS_REG_CFC_SEARCH_CURRENT_CREDIT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PRS: CFC_SEARCH current credit is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 259*/{(0x1F), 1, PRS_REG_SRC_CURRENT_CREDIT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PRS: SRCH current credit is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 260*/{(0x1F), 1, PRS_REG_PENDING_BRB_PRS_RQ,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PRS: PENDING_BRB_PRS_RQ is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 261*/{(0x1F), 2, PRS_REG_PENDING_BRB_CAC0_RQ,
+ NA, 5, 4, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PRS: PENDING_BRB_CAC_RQ is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 262*/{(0x1F), 1, PRS_REG_SERIAL_NUM_STATUS_LSB,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PRS: SERIAL_NUM_STATUS_LSB is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 263*/{(0x1F), 1, PRS_REG_SERIAL_NUM_STATUS_MSB,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "PRS: SERIAL_NUM_STATUS_MSB is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 264*/{(0x1F), 1, CDU_REG_ERROR_DATA,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CDU: ERROR_DATA is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 265*/{(0x1F), 1, CCM_REG_STORM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CCM: STORM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 266*/{(0x1F), 1, CCM_REG_CSDM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CCM: CSDM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 267*/{(0x1F), 1, CCM_REG_TSEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CCM: TSEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 268*/{(0x1F), 1, CCM_REG_XSEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CCM: XSEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 269*/{(0x1F), 1, CCM_REG_USEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CCM: USEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 270*/{(0x1F), 1, CCM_REG_PBF_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CCM: PBF declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 271*/{(0x1F), 1, TCM_REG_STORM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TCM: STORM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 272*/{(0x1F), 1, TCM_REG_TSDM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TCM: TSDM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 273*/{(0x1F), 1, TCM_REG_PRS_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TCM: PRS declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 274*/{(0x1F), 1, TCM_REG_PBF_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TCM: PBF declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 275*/{(0x1F), 1, TCM_REG_USEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TCM: USEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 276*/{(0x1F), 1, TCM_REG_CSEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TCM: CSEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 277*/{(0x1F), 1, UCM_REG_STORM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "UCM: STORM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 278*/{(0x1F), 1, UCM_REG_USDM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "UCM: USDM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 279*/{(0x1F), 1, UCM_REG_TSEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "UCM: TSEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 280*/{(0x1F), 1, UCM_REG_CSEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "UCM: CSEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 281*/{(0x1F), 1, UCM_REG_XSEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "UCM: XSEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 282*/{(0x1F), 1, UCM_REG_DORQ_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "UCM: DORQ declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 283*/{(0x1F), 1, XCM_REG_STORM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: STORM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 284*/{(0x1F), 1, XCM_REG_XSDM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: XSDM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 285*/{(0x1F), 1, XCM_REG_TSEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: TSEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 286*/{(0x1F), 1, XCM_REG_CSEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: CSEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 287*/{(0x1F), 1, XCM_REG_USEM_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: USEM declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 288*/{(0x1F), 1, XCM_REG_DORQ_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: DORQ declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 289*/{(0x1F), 1, XCM_REG_PBF_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: PBF declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 290*/{(0x1F), 1, XCM_REG_NIG0_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: NIG0 declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 291*/{(0x1F), 1, XCM_REG_NIG1_LENGTH_MIS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XCM: NIG1 declared message length unequal to actual",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 292*/{(0x1F), 1, QM_REG_XQM_WRC_FIFOLVL,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: XQM wrc_fifolvl is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 293*/{(0x1F), 1, QM_REG_UQM_WRC_FIFOLVL,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: UQM wrc_fifolvl is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 294*/{(0x1F), 1, QM_REG_TQM_WRC_FIFOLVL,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: TQM wrc_fifolvl is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 295*/{(0x1F), 1, QM_REG_CQM_WRC_FIFOLVL,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: CQM wrc_fifolvl is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 296*/{(0x1F), 1, QM_REG_QSTATUS_LOW,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: QSTATUS_LOW is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 297*/{(0x1F), 1, QM_REG_QSTATUS_HIGH,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: QSTATUS_HIGH is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 298*/{(0x1F), 1, QM_REG_PAUSESTATE0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: PAUSESTATE0 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 299*/{(0x1F), 1, QM_REG_PAUSESTATE1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: PAUSESTATE1 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 300*/{(0x1F), 1, QM_REG_OVFQNUM,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: OVFQNUM is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 301*/{(0x1F), 1, QM_REG_OVFERROR,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: OVFERROR is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 302*/{(0x1F), 6, QM_REG_PTRTBL,
+ NA, 64, 8, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: read and write variables not equal",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 303*/{(0x1F), 1, BRB1_REG_BRB1_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "BRB1: parity status is not 0",
+ {NA, NA, ~0x8, 0, NA, NA} },
+
+/*line 304*/{(0x1F), 1, CDU_REG_CDU_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "CDU: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 305*/{(0x1F), 1, CFC_REG_CFC_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "CFC: parity status is not 0",
+ {NA, NA, ~0x2, 0, NA, NA} },
+
+/*line 306*/{(0x1F), 1, CSDM_REG_CSDM_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "CSDM: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 307*/{(0x3), 1, DBG_REG_DBG_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "DBG: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 308*/{(0x1F), 1, DMAE_REG_DMAE_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "DMAE: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 309*/{(0x1F), 1, DORQ_REG_DORQ_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "DORQ: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 310*/{(0x1), 1, TCM_REG_TCM_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "TCM: parity status is not 0",
+ {NA, NA, ~0x3ffc0, 0, NA, NA} },
+
+/*line 311*/{(0x1E), 1, TCM_REG_TCM_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "TCM: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 312*/{(0x1), 1, CCM_REG_CCM_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "CCM: parity status is not 0",
+ {NA, NA, ~0x3ffc0, 0, NA, NA} },
+
+/*line 313*/{(0x1E), 1, CCM_REG_CCM_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "CCM: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 314*/{(0x1), 1, UCM_REG_UCM_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "UCM: parity status is not 0",
+ {NA, NA, ~0x3ffc0, 0, NA, NA} },
+
+/*line 315*/{(0x1E), 1, UCM_REG_UCM_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "UCM: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 316*/{(0x1), 1, XCM_REG_XCM_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "XCM: parity status is not 0",
+ {NA, NA, ~0x3ffc0, 0, NA, NA} },
+
+/*line 317*/{(0x1E), 1, XCM_REG_XCM_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "XCM: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 318*/{(0x1), 1, HC_REG_HC_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "HC: parity status is not 0",
+ {NA, NA, ~0x1, 0, NA, NA} },
+
+/*line 319*/{(0x1), 1, MISC_REG_MISC_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "MISC: parity status is not 0",
+ {NA, NA, ~0x1, 0, NA, NA} },
+
+/*line 320*/{(0x1F), 1, PRS_REG_PRS_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PRS: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 321*/{(0x1F), 1, PXP_REG_PXP_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 322*/{(0x1F), 1, QM_REG_QM_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "QM: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 323*/{(0x1), 1, SRC_REG_SRC_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "SRCH: parity status is not 0",
+ {NA, NA, ~0x4, 0, NA, NA} },
+
+/*line 324*/{(0x1F), 1, TSDM_REG_TSDM_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "TSDM: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 325*/{(0x1F), 1, USDM_REG_USDM_PRTY_STS,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "USDM: parity status is not 0",
+ {NA, NA, ~0x20, 0, NA, NA} },
+
+/*line 326*/{(0x1F), 1, XSDM_REG_XSDM_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "XSDM: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 327*/{(0x1F), 1, GRCBASE_XPB + PB_REG_PB_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "XPB: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 328*/{(0x1F), 1, GRCBASE_UPB + PB_REG_PB_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "UPB: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 329*/{(0x1F), 1, CSEM_REG_CSEM_PRTY_STS_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "CSEM: parity status 0 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 330*/{(0x1), 1, PXP2_REG_PXP2_PRTY_STS_0,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: parity status 0 is not 0",
+ {NA, NA, ~0xfff40020, 0, NA, NA} },
+
+/*line 331*/{(0x1E), 1, PXP2_REG_PXP2_PRTY_STS_0,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: parity status 0 is not 0",
+ {NA, NA, ~0x20, 0, NA, NA} },
+
+/*line 332*/{(0x1F), 1, TSEM_REG_TSEM_PRTY_STS_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "TSEM: parity status 0 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 333*/{(0x1F), 1, USEM_REG_USEM_PRTY_STS_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "USEM: parity status 0 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 334*/{(0x1F), 1, XSEM_REG_XSEM_PRTY_STS_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "XSEM: parity status 0 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 335*/{(0x1F), 1, CSEM_REG_CSEM_PRTY_STS_1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "CSEM: parity status 1 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 336*/{(0x1), 1, PXP2_REG_PXP2_PRTY_STS_1,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: parity status 1 is not 0",
+ {NA, NA, ~0x20, 0, NA, NA} },
+
+/*line 337*/{(0x1E), 1, PXP2_REG_PXP2_PRTY_STS_1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PXP2: parity status 1 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 338*/{(0x1F), 1, TSEM_REG_TSEM_PRTY_STS_1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "TSEM: parity status 1 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 339*/{(0x1F), 1, USEM_REG_USEM_PRTY_STS_1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "USEM: parity status 1 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 340*/{(0x1F), 1, XSEM_REG_XSEM_PRTY_STS_1,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "XSEM: parity status 1 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 341*/{(0x1C), 1, PGLUE_B_REG_PGLUE_B_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGLUE_B: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 342*/{(0x2), 2, QM_REG_QTASKCTR_EXT_A_0,
+ NA, 64, 4, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Q_EXT_A (upper 64 queues), Queue is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 343*/{(0x2), 1, QM_REG_QSTATUS_LOW_EXT_A,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: QSTATUS_LOW_EXT_A is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 344*/{(0x2), 1, QM_REG_QSTATUS_HIGH_EXT_A,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: QSTATUS_HIGH_EXT_A is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 345*/{(0x1E), 1, QM_REG_PAUSESTATE2,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: PAUSESTATE2 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 346*/{(0x1E), 1, QM_REG_PAUSESTATE3,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: PAUSESTATE3 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 347*/{(0x2), 1, QM_REG_PAUSESTATE4,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: PAUSESTATE4 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 348*/{(0x2), 1, QM_REG_PAUSESTATE5,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: PAUSESTATE5 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 349*/{(0x2), 1, QM_REG_PAUSESTATE6,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: PAUSESTATE6 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 350*/{(0x2), 1, QM_REG_PAUSESTATE7,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "QM: PAUSESTATE7 is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 351*/{(0x2), 6, QM_REG_PTRTBL_EXT_A,
+ NA, 64, 8, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: read and write variables not equal in ext table",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 352*/{(0x1E), 1, MISC_REG_AEU_SYS_KILL_OCCURRED,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "MISC: system kill occurred;",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 353*/{(0x1E), 1, MISC_REG_AEU_SYS_KILL_STATUS_0,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "MISC: system kill occurred; status_0 register",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 354*/{(0x1E), 1, MISC_REG_AEU_SYS_KILL_STATUS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "MISC: system kill occurred; status_1 register",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 355*/{(0x1E), 1, MISC_REG_AEU_SYS_KILL_STATUS_2,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "MISC: system kill occurred; status_2 register",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 356*/{(0x1E), 1, MISC_REG_AEU_SYS_KILL_STATUS_3,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "MISC: system kill occurred; status_3 register",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 357*/{(0x1E), 1, MISC_REG_PCIE_HOT_RESET,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_WARNING,
+ "MISC: pcie_rst_b was asserted without perst assertion",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 358*/{(0x1F), 1, NIG_REG_NIG_INT_STS_0,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "NIG: interrupt 0 is active",
+ {NA, NA, ~0x300, 0, NA, NA} },
+
+/*line 359*/{(0x1F), 1, NIG_REG_NIG_INT_STS_0,
+ NA, NA, NA, peq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Access to BMAC while not active. If tested on FPGA, ignore this warning",
+ {NA, NA, 0x300, NA, NA, NA} },
+
+/*line 360*/{(0x1F), 1, NIG_REG_NIG_INT_STS_1,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "NIG: interrupt 1 is active",
+ {NA, NA, 0x783FF03, 0, NA, NA} },
+
+/*line 361*/{(0x1F), 1, NIG_REG_NIG_INT_STS_1,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: port cos was paused too long",
+ {NA, NA, ~0x783FF0F, 0, NA, NA} },
+
+/*line 362*/{(0x1F), 1, NIG_REG_NIG_INT_STS_1,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Got packets w/o Outer-VLAN in MF mode",
+ {NA, NA, 0xC, 0, NA, NA} },
+
+/*line 363*/{(0x2), 1, NIG_REG_NIG_PRTY_STS,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "NIG: parity interrupt is active",
+ {NA, NA, ~0xFFC00000, 0, NA, NA} },
+
+/*line 364*/{(0x1C), 1, NIG_REG_NIG_PRTY_STS_0,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "NIG: parity 0 interrupt is active",
+ {NA, NA, ~0xFFC00000, 0, NA, NA} },
+
+/*line 365*/{(0x4), 1, NIG_REG_NIG_PRTY_STS_1,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "NIG: parity 1 interrupt is active",
+ {NA, NA, 0xff, 0, NA, NA} },
+
+/*line 366*/{(0x18), 1, NIG_REG_NIG_PRTY_STS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "NIG: parity 1 interrupt is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 367*/{(0x1F), 1, TSEM_REG_TSEM_INT_STS_0,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "TSEM: interrupt 0 is active",
+ {NA, NA, ~0x10000000, 0, NA, NA} },
+
+/*line 368*/{(0x1F), 1, TSEM_REG_TSEM_INT_STS_0,
+ NA, NA, NA, peq,
+ NA, IDLE_CHK_WARNING,
+ "TSEM: interrupt 0 is active",
+ {NA, NA, 0x10000000, NA, NA, NA} },
+
+/*line 369*/{(0x1F), 1, TSEM_REG_TSEM_INT_STS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TSEM: interrupt 1 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 370*/{(0x1F), 1, CSEM_REG_CSEM_INT_STS_0,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "CSEM: interrupt 0 is active",
+ {NA, NA, ~0x10000000, 0, NA, NA} },
+
+/*line 371*/{(0x1F), 1, CSEM_REG_CSEM_INT_STS_0,
+ NA, NA, NA, peq,
+ NA, IDLE_CHK_WARNING,
+ "CSEM: interrupt 0 is active",
+ {NA, NA, 0x10000000, NA, NA, NA} },
+
+/*line 372*/{(0x1F), 1, CSEM_REG_CSEM_INT_STS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CSEM: interrupt 1 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 373*/{(0x1F), 1, USEM_REG_USEM_INT_STS_0,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "USEM: interrupt 0 is active",
+ {NA, NA, ~0x10000000, 0, NA, NA} },
+
+/*line 374*/{(0x1F), 1, USEM_REG_USEM_INT_STS_0,
+ NA, NA, NA, peq,
+ NA, IDLE_CHK_WARNING,
+ "USEM: interrupt 0 is active",
+ {NA, NA, 0x10000000, NA, NA, NA} },
+
+/*line 375*/{(0x1F), 1, USEM_REG_USEM_INT_STS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "USEM: interrupt 1 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 376*/{(0x1F), 1, XSEM_REG_XSEM_INT_STS_0,
+ NA, NA, NA, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "XSEM: interrupt 0 is active",
+ {NA, NA, ~0x10000000, 0, NA, NA} },
+
+/*line 377*/{(0x1F), 1, XSEM_REG_XSEM_INT_STS_0,
+ NA, NA, NA, peq,
+ NA, IDLE_CHK_WARNING,
+ "XSEM: interrupt 0 is active",
+ {NA, NA, 0x10000000, NA, NA, NA} },
+
+/*line 378*/{(0x1F), 1, XSEM_REG_XSEM_INT_STS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XSEM: interrupt 1 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 379*/{(0x1F), 1, TSDM_REG_TSDM_INT_STS_0,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TSDM: interrupt 0 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 380*/{(0x1F), 1, TSDM_REG_TSDM_INT_STS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "TSDM: interrupt 0 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 381*/{(0x1F), 1, CSDM_REG_CSDM_INT_STS_0,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CSDM: interrupt 0 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 382*/{(0x1F), 1, CSDM_REG_CSDM_INT_STS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "CSDM: interrupt 0 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 383*/{(0x1F), 1, USDM_REG_USDM_INT_STS_0,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "USDM: interrupt 0 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 384*/{(0x1F), 1, USDM_REG_USDM_INT_STS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "USDM: interrupt 0 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 385*/{(0x1F), 1, XSDM_REG_XSDM_INT_STS_0,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XSDM: interrupt 0 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 386*/{(0x1F), 1, XSDM_REG_XSDM_INT_STS_1,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_ERROR,
+ "XSDM: interrupt 0 is active",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 387*/{(0x2), 1, HC_REG_HC_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "HC: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 388*/{(0x1E), 1, MISC_REG_MISC_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "MISC: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 389*/{(0x1E), 1, SRC_REG_SRC_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "SRCH: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 390*/{(0xC), 3, QM_REG_BYTECRD0,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 0 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 391*/{(0xC), 3, QM_REG_BYTECRD1,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 1 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 392*/{(0xC), 3, QM_REG_BYTECRD2,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 2 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 393*/{(0x1C), 1, QM_REG_VOQCRDERRREG,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "QM: VOQ credit error register is not 0 (VOQ credit overflow/underflow)",
+ {NA, NA, 0xFFFF, 0, NA, NA} },
+
+/*line 394*/{(0x1C), 1, QM_REG_BYTECRDERRREG,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "QM: Byte credit error register is not 0 (Byte credit overflow/underflow)",
+ {NA, NA, 0xFFF, 0, NA, NA} },
+
+/*line 395*/{(0x1C), 1, PGLUE_B_REG_FLR_REQUEST_VF_31_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGL: FLR request is set for VF addresses 31-0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 396*/{(0x1C), 1, PGLUE_B_REG_FLR_REQUEST_VF_63_32,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGL: FLR request is set for VF addresses 63-32",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 397*/{(0x1C), 1, PGLUE_B_REG_FLR_REQUEST_VF_95_64,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGL: FLR request is set for VF addresses 95-64",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 398*/{(0x1C), 1, PGLUE_B_REG_FLR_REQUEST_VF_127_96,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGL: FLR request is set for VF addresses 127-96",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 399*/{(0x1C), 1, PGLUE_B_REG_FLR_REQUEST_PF_7_0,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGL: FLR request is set for PF addresses 7-0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 400*/{(0x1C), 1, PGLUE_B_REG_SR_IOV_DISABLED_REQUEST,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGL: SR-IOV disable request is set",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 401*/{(0x1C), 1, PGLUE_B_REG_CFG_SPACE_A_REQUEST,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGL: Cfg-Space A request is set",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 402*/{(0x1C), 1, PGLUE_B_REG_CFG_SPACE_B_REQUEST,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "PGL: Cfg-Space B request is set",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 403*/{(0x1C), 1, IGU_REG_ERROR_HANDLING_DATA_VALID,
+ NA, NA, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "IGU: some unauthorized commands arrived to the IGU. Use igu_dump_fifo utility for more details",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 404*/{(0x1C), 1, IGU_REG_ATTN_WRITE_DONE_PENDING,
+ NA, NA, NA, pneq,
+ NA, IDLE_CHK_WARNING,
+ "IGU attention message write done pending is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 405*/{(0x1C), 1, IGU_REG_WRITE_DONE_PENDING,
+ NA, 5, 4, pneq,
+ NA, IDLE_CHK_WARNING,
+ "IGU MSI/MSIX message write done pending is not empty",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 406*/{(0x1C), 1, IGU_REG_IGU_PRTY_STS,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "IGU: parity status is not 0",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 407*/{(0x1E), 3, MISC_REG_GRC_TIMEOUT_ATTN,
+ MISC_REG_AEU_AFTER_INVERT_4_FUNC_0, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "MISC_REG_GRC_TIMEOUT_ATTN: GRC timeout attention parameters (FUNC_0)",
+ {NA, NA, 0x4000000, 0, NA, NA} },
+
+/*line 408*/{(0x1C), 3, MISC_REG_GRC_TIMEOUT_ATTN_FULL_FID,
+ MISC_REG_AEU_AFTER_INVERT_4_FUNC_0, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "MISC_REG_GRC_TIMEOUT_ATTN_FULL_FID: GRC timeout attention FID (FUNC_0)",
+ {NA, NA, 0x4000000, 0, NA, NA} },
+
+/*line 409*/{(0x1E), 3, MISC_REG_GRC_TIMEOUT_ATTN,
+ MISC_REG_AEU_AFTER_INVERT_4_FUNC_1, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "MISC_REG_GRC_TIMEOUT_ATTN: GRC timeout attention parameters (FUNC_1)",
+ {NA, NA, 0x4000000, 0, NA, NA} },
+
+/*line 410*/{(0x1C), 3, MISC_REG_GRC_TIMEOUT_ATTN_FULL_FID,
+ MISC_REG_AEU_AFTER_INVERT_4_FUNC_1, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "MISC_REG_GRC_TIMEOUT_ATTN_FULL_FID: GRC timeout attention FID (FUNC_1)",
+ {NA, NA, 0x4000000, 0, NA, NA} },
+
+/*line 411*/{(0x1E), 3, MISC_REG_GRC_TIMEOUT_ATTN,
+ MISC_REG_AEU_AFTER_INVERT_4_MCP, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "MISC_REG_GRC_TIMEOUT_ATTN: GRC timeout attention parameters (MCP)",
+ {NA, NA, 0x4000000, 0, NA, NA} },
+
+/*line 412*/{(0x1C), 3, MISC_REG_GRC_TIMEOUT_ATTN_FULL_FID,
+ MISC_REG_AEU_AFTER_INVERT_4_MCP, 1, 0, pand_neq,
+ NA, IDLE_CHK_ERROR,
+ "MISC_REG_GRC_TIMEOUT_ATTN_FULL_FID: GRC timeout attention FID (MCP)",
+ {NA, NA, 0x4000000, 0, NA, NA} },
+
+/*line 413*/{(0x1C), 1, IGU_REG_SILENT_DROP,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "Some messages were not executed in the IGU",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 414*/{(0x1C), 1, PXP2_REG_PSWRQ_BW_CREDIT,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR,
+ "PXP2: rq_read_credit and rq_write_credit are not 5",
+ {NA, NA, 0x2D, NA, NA, NA} },
+
+/*line 415*/{(0x1C), 1, IGU_REG_SB_CTRL_FSM,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "IGU: block is not in idle. SB_CTRL_FSM should be zero in idle state",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 416*/{(0x1C), 1, IGU_REG_INT_HANDLE_FSM,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "IGU: block is not in idle. INT_HANDLE_FSM should be zero in idle state",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 417*/{(0x1C), 1, IGU_REG_ATTN_FSM,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "IGU: block is not in idle. SB_ATTN_FSMshould be zeroor two in idle state",
+ {NA, NA, ~0x2, 0, NA, NA} },
+
+/*line 418*/{(0x1C), 1, IGU_REG_CTRL_FSM,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "IGU: block is not in idle. SB_CTRL_FSM should be zero in idle state",
+ {NA, NA, ~0x1, 0, NA, NA} },
+
+/*line 419*/{(0x1C), 1, IGU_REG_PXP_ARB_FSM,
+ NA, 1, 0, pand_neq,
+ NA, IDLE_CHK_WARNING,
+ "IGU: block is not in idle. SB_ARB_FSM should be zero in idle state",
+ {NA, NA, ~0x1, 0, NA, NA} },
+
+/*line 420*/{(0x1C), 1, IGU_REG_PENDING_BITS_STATUS,
+ NA, 5, 4, pneq,
+ NA, IDLE_CHK_WARNING,
+ "IGU: block is not in idle. There are pending write done",
+ {NA, NA, 0, NA, NA, NA} },
+
+/*line 421*/{(0x10), 3, QM_REG_VOQCREDIT_0,
+ QM_REG_VOQINITCREDIT_0, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_0, VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 422*/{(0x10), 3, QM_REG_VOQCREDIT_1,
+ QM_REG_VOQINITCREDIT_1, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_1, VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 423*/{(0x10), 3, QM_REG_VOQCREDIT_2,
+ QM_REG_VOQINITCREDIT_2, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_2, VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 424*/{(0x10), 3, QM_REG_VOQCREDIT_3,
+ QM_REG_VOQINITCREDIT_3, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_3, VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 425*/{(0x10), 3, QM_REG_VOQCREDIT_4,
+ QM_REG_VOQINITCREDIT_4, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_4, VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 426*/{(0x10), 3, QM_REG_VOQCREDIT_5,
+ QM_REG_VOQINITCREDIT_5, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_5, VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 427*/{(0x10), 3, QM_REG_VOQCREDIT_6,
+ QM_REG_VOQINITCREDIT_6, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: VOQ_6 (LB VOQ), VOQ credit is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 428*/{(0x10), 3, QM_REG_BYTECRD0,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 0 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 429*/{(0x10), 3, QM_REG_BYTECRD1,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 1 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 430*/{(0x10), 3, QM_REG_BYTECRD2,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 2 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 431*/{(0x10), 3, QM_REG_BYTECRD3,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 3 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 432*/{(0x10), 3, QM_REG_BYTECRD4,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 4 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 433*/{(0x10), 3, QM_REG_BYTECRD5,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 5 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 434*/{(0x10), 3, QM_REG_BYTECRD6,
+ QM_REG_BYTECRDINITVAL, 1, 0, pneq_r2,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "QM: Byte credit 6 is not equal to initial credit",
+ {NA, NA, NA, NA, NA, NA} },
+
+/*line 435*/{(0x10), 1, QM_REG_FWVOQ0TOHWVOQ,
+ NA, 1, 0, peq,
+ NA, IDLE_CHK_ERROR,
+ "QM: FwVoq0 is mapped to HwVoq7 (non-TX HwVoq)",
+ {NA, NA, 0x7, NA, NA, NA} },
+
+/*line 436*/{(0x10), 1, QM_REG_FWVOQ1TOHWVOQ,
+ NA, 1, 0, peq,
+ NA, IDLE_CHK_ERROR,
+ "QM: FwVoq1 is mapped to HwVoq7 (non-TX HwVoq)",
+ {NA, NA, 0x7, NA, NA, NA} },
+
+/*line 437*/{(0x10), 1, QM_REG_FWVOQ2TOHWVOQ,
+ NA, 1, 0, peq,
+ NA, IDLE_CHK_ERROR,
+ "QM: FwVoq2 is mapped to HwVoq7 (non-TX HwVoq)",
+ {NA, NA, 0x7, NA, NA, NA} },
+
+/*line 438*/{(0x10), 1, QM_REG_FWVOQ3TOHWVOQ,
+ NA, 1, 0, peq,
+ NA, IDLE_CHK_ERROR,
+ "QM: FwVoq3 is mapped to HwVoq7 (non-TX HwVoq)",
+ {NA, NA, 0x7, NA, NA, NA} },
+
+/*line 439*/{(0x10), 1, QM_REG_FWVOQ4TOHWVOQ,
+ NA, 1, 0, peq,
+ NA, IDLE_CHK_ERROR,
+ "QM: FwVoq4 is mapped to HwVoq7 (non-TX HwVoq)",
+ {NA, NA, 0x7, NA, NA, NA} },
+
+/*line 440*/{(0x10), 1, QM_REG_FWVOQ5TOHWVOQ,
+ NA, 1, 0, peq,
+ NA, IDLE_CHK_ERROR,
+ "QM: FwVoq5 is mapped to HwVoq7 (non-TX HwVoq)",
+ {NA, NA, 0x7, NA, NA, NA} },
+
+/*line 441*/{(0x10), 1, QM_REG_FWVOQ6TOHWVOQ,
+ NA, 1, 0, peq,
+ NA, IDLE_CHK_ERROR,
+ "QM: FwVoq6 is mapped to HwVoq7 (non-TX HwVoq)",
+ {NA, NA, 0x7, NA, NA, NA} },
+
+/*line 442*/{(0x10), 1, QM_REG_FWVOQ7TOHWVOQ,
+ NA, 1, 0, peq,
+ NA, IDLE_CHK_ERROR,
+ "QM: FwVoq7 is mapped to HwVoq7 (non-TX HwVoq)",
+ {NA, NA, 0x7, NA, NA, NA} },
+
+/*line 443*/{(0x1F), 1, NIG_REG_INGRESS_EOP_PORT0_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 0 EOP FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 444*/{(0x1F), 1, NIG_REG_INGRESS_EOP_PORT1_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 1 EOP FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 445*/{(0x1F), 1, NIG_REG_INGRESS_EOP_LB_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: LB EOP FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 446*/{(0x1F), 1, NIG_REG_INGRESS_RMP0_DSCR_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Port 0 RX MCP descriptor FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 447*/{(0x1F), 1, NIG_REG_INGRESS_RMP1_DSCR_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Port 1 RX MCP descriptor FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 448*/{(0x1F), 1, NIG_REG_INGRESS_LB_PBF_DELAY_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: PBF LB FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 449*/{(0x1F), 1, NIG_REG_EGRESS_MNG0_FIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Port 0 TX MCP FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 450*/{(0x1F), 1, NIG_REG_EGRESS_MNG1_FIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Port 1 TX MCP FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 451*/{(0x1F), 1, NIG_REG_EGRESS_DEBUG_FIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Debug FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 452*/{(0x1F), 1, NIG_REG_EGRESS_DELAY0_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: PBF IF0 FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 453*/{(0x1F), 1, NIG_REG_EGRESS_DELAY1_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: PBF IF1 FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 454*/{(0x1F), 1, NIG_REG_LLH0_FIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 0 RX LLH FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 455*/{(0x1F), 1, NIG_REG_LLH1_FIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 1 RX LLH FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 456*/{(0x1C), 1, NIG_REG_P0_TX_MNG_HOST_FIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Port 0 TX MCP FIFO for traffic going to the host is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 457*/{(0x1C), 1, NIG_REG_P1_TX_MNG_HOST_FIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Port 1 TX MCP FIFO for traffic going to the host is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 458*/{(0x1C), 1, NIG_REG_P0_TLLH_FIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 0 TX LLH FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 459*/{(0x1C), 1, NIG_REG_P1_TLLH_FIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 1 TX LLH FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 460*/{(0x1C), 1, NIG_REG_P0_HBUF_DSCR_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Port 0 RX MCP descriptor FIFO for traffic from the host is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 461*/{(0x1C), 1, NIG_REG_P1_HBUF_DSCR_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_WARNING,
+ "NIG: Port 1 RX MCP descriptor FIFO for traffic from the host is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 462*/{(0x18), 1, NIG_REG_P0_RX_MACFIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 0 RX MAC interface FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 463*/{(0x18), 1, NIG_REG_P1_RX_MACFIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 1 RX MAC interface FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 464*/{(0x18), 1, NIG_REG_P0_TX_MACFIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 0 TX MAC interface FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 465*/{(0x18), 1, NIG_REG_P1_TX_MACFIFO_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: Port 1 TX MAC interface FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 466*/{(0x10), 1, NIG_REG_EGRESS_DELAY2_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: PBF IF2 FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 467*/{(0x10), 1, NIG_REG_EGRESS_DELAY3_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: PBF IF3 FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 468*/{(0x10), 1, NIG_REG_EGRESS_DELAY4_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: PBF IF4 FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+
+/*line 469*/{(0x10), 1, NIG_REG_EGRESS_DELAY5_EMPTY,
+ NA, 1, 0, pneq,
+ NA, IDLE_CHK_ERROR_NO_TRAFFIC,
+ "NIG: PBF IF5 FIFO is not empty",
+ {NA, NA, 1, NA, NA, NA} },
+};
+
+/* handle self test fails according to severity and type */
+static void bnx2x_self_test_log(struct bnx2x *bp, u8 severity, char *message)
+{
+ switch (severity) {
+ case IDLE_CHK_ERROR:
+ BNX2X_ERR("ERROR %s", message);
+ idle_chk_errors++;
+ break;
+ case IDLE_CHK_ERROR_NO_TRAFFIC:
+ DP(NETIF_MSG_HW, "INFO %s", message);
+ break;
+ case IDLE_CHK_WARNING:
+ DP(NETIF_MSG_HW, "WARNING %s", message);
+ idle_chk_warnings++;
+ break;
+ }
+}
+
+/* specific test for QM rd/wr pointers and rd/wr banks */
+static void bnx2x_idle_chk6(struct bnx2x *bp,
+ struct st_record *rec, char *message)
+{
+ u32 rd_ptr, wr_ptr, rd_bank, wr_bank;
+ int i;
+
+ for (i = 0; i < rec->loop; i++) {
+ /* read regs */
+ rec->pred_args.val1 =
+ REG_RD(bp, rec->reg1 + i * rec->incr);
+ rec->pred_args.val2 =
+ REG_RD(bp, rec->reg1 + i * rec->incr + 4);
+
+ /* calc read and write pointers */
+ rd_ptr = ((rec->pred_args.val1 & 0x3FFFFFC0) >> 6);
+ wr_ptr = ((((rec->pred_args.val1 & 0xC0000000) >> 30) & 0x3) |
+ ((rec->pred_args.val2 & 0x3FFFFF) << 2));
+
+ /* perfrom pointer test */
+ if (rd_ptr != wr_ptr) {
+ snprintf(message, MAX_FAIL_MSG,
+ "QM: PTRTBL entry %d- rd_ptr is not equal to wr_ptr. Values are 0x%x and 0x%x\n",
+ i, rd_ptr, wr_ptr);
+ bnx2x_self_test_log(bp, rec->severity, message);
+ }
+
+ /* calculate read and write banks */
+ rd_bank = ((rec->pred_args.val1 & 0x30) >> 4);
+ wr_bank = (rec->pred_args.val1 & 0x03);
+
+ /* perform bank test */
+ if (rd_bank != wr_bank) {
+ snprintf(message, MAX_FAIL_MSG,
+ "QM: PTRTBL entry %d - rd_bank is not equal to wr_bank. Values are 0x%x 0x%x\n",
+ i, rd_bank, wr_bank);
+ bnx2x_self_test_log(bp, rec->severity, message);
+ }
+ }
+}
+
+/* specific test for cfc info ram and cid cam */
+static void bnx2x_idle_chk7(struct bnx2x *bp,
+ struct st_record *rec, char *message)
+{
+ int i;
+
+ /* iterate through lcids */
+ for (i = 0; i < rec->loop; i++) {
+ /* make sure cam entry is valid (bit 0) */
+ if ((REG_RD(bp, (rec->reg2 + i * 4)) & 0x1) != 0x1)
+ continue;
+
+ /* get connection type (multiple reads due to widebus) */
+ REG_RD(bp, (rec->reg1 + i * rec->incr));
+ REG_RD(bp, (rec->reg1 + i * rec->incr + 4));
+ rec->pred_args.val1 =
+ REG_RD(bp, (rec->reg1 + i * rec->incr + 8));
+ REG_RD(bp, (rec->reg1 + i * rec->incr + 12));
+
+ /* obtain connection type */
+ if (is_e1 || is_e1h) {
+ /* E1 E1H (bits 4..7) */
+ rec->pred_args.val1 &= 0x78;
+ rec->pred_args.val1 >>= 3;
+ } else {
+ /* E2 E3A0 E3B0 (bits 26..29) */
+ rec->pred_args.val1 &= 0x1E000000;
+ rec->pred_args.val1 >>= 25;
+ }
+
+ /* get activity counter value */
+ rec->pred_args.val2 = REG_RD(bp, rec->reg3 + i * 4);
+
+ /* validate ac value is legal for con_type at idle state */
+ if (rec->bnx2x_predicate(&rec->pred_args)) {
+ snprintf(message, MAX_FAIL_MSG,
+ "%s. Values are 0x%x 0x%x\n", rec->fail_msg,
+ rec->pred_args.val1, rec->pred_args.val2);
+ bnx2x_self_test_log(bp, rec->severity, message);
+ }
+ }
+}
+
+/* self test procedure
+ * scan auto-generated database
+ * for each line:
+ * 1. compare chip mask
+ * 2. determine type (according to maro number)
+ * 3. read registers
+ * 4. call predicate
+ * 5. collate results and statistics
+ */
+int bnx2x_idle_chk(struct bnx2x *bp)
+{
+ u16 i; /* loop counter */
+ u16 st_ind; /* self test database access index */
+ struct st_record rec; /* current record variable */
+ char message[MAX_FAIL_MSG]; /* message to log */
+
+ /*init stats*/
+ idle_chk_errors = 0;
+ idle_chk_warnings = 0;
+
+ /*create masks for all chip types*/
+ is_e1 = CHIP_IS_E1(bp);
+ is_e1h = CHIP_IS_E1H(bp);
+ is_e2 = CHIP_IS_E2(bp);
+ is_e3a0 = CHIP_IS_E3A0(bp);
+ is_e3b0 = CHIP_IS_E3B0(bp);
+
+ /*database main loop*/
+ for (st_ind = 0; st_ind < ST_DB_LINES; st_ind++) {
+ rec = st_database[st_ind];
+
+ /*check if test applies to chip*/
+ if (!((rec.chip_mask & IDLE_CHK_E1) && is_e1) &&
+ !((rec.chip_mask & IDLE_CHK_E1H) && is_e1h) &&
+ !((rec.chip_mask & IDLE_CHK_E2) && is_e2) &&
+ !((rec.chip_mask & IDLE_CHK_E3A0) && is_e3a0) &&
+ !((rec.chip_mask & IDLE_CHK_E3B0) && is_e3b0))
+ continue;
+
+ /* identify macro */
+ switch (rec.macro) {
+ case 1:
+ /* read single reg and call predicate */
+ rec.pred_args.val1 = REG_RD(bp, rec.reg1);
+ DP(BNX2X_MSG_IDLE, "mac1 add %x\n", rec.reg1);
+ if (rec.bnx2x_predicate(&rec.pred_args)) {
+ snprintf(message, sizeof(message),
+ "%s.Value is 0x%x\n", rec.fail_msg,
+ rec.pred_args.val1);
+ bnx2x_self_test_log(bp, rec.severity, message);
+ }
+ break;
+ case 2:
+ /* read repeatedly starting from reg1 and call
+ * predicate after each read
+ */
+ for (i = 0; i < rec.loop; i++) {
+ rec.pred_args.val1 =
+ REG_RD(bp, rec.reg1 + i * rec.incr);
+ DP(BNX2X_MSG_IDLE, "mac2 add %x\n", rec.reg1);
+ if (rec.bnx2x_predicate(&rec.pred_args)) {
+ snprintf(message, sizeof(message),
+ "%s. Value is 0x%x in loop %d\n",
+ rec.fail_msg,
+ rec.pred_args.val1, i);
+ bnx2x_self_test_log(bp, rec.severity,
+ message);
+ }
+ }
+ break;
+ case 3:
+ /* read two regs and call predicate */
+ rec.pred_args.val1 = REG_RD(bp, rec.reg1);
+ rec.pred_args.val2 = REG_RD(bp, rec.reg2);
+ DP(BNX2X_MSG_IDLE, "mac3 add1 %x add2 %x\n",
+ rec.reg1, rec.reg2);
+ if (rec.bnx2x_predicate(&rec.pred_args)) {
+ snprintf(message, sizeof(message),
+ "%s. Values are 0x%x 0x%x\n",
+ rec.fail_msg, rec.pred_args.val1,
+ rec.pred_args.val2);
+ bnx2x_self_test_log(bp, rec.severity, message);
+ }
+ break;
+ case 4:
+ /*unused to-date*/
+ for (i = 0; i < rec.loop; i++) {
+ rec.pred_args.val1 =
+ REG_RD(bp, rec.reg1 + i * rec.incr);
+ rec.pred_args.val2 =
+ (REG_RD(bp,
+ rec.reg2 + i * rec.incr)) >> 1;
+ if (rec.bnx2x_predicate(&rec.pred_args)) {
+ snprintf(message, sizeof(message),
+ "%s. Values are 0x%x 0x%x in loop %d\n",
+ rec.fail_msg,
+ rec.pred_args.val1,
+ rec.pred_args.val2, i);
+ bnx2x_self_test_log(bp, rec.severity,
+ message);
+ }
+ }
+ break;
+ case 5:
+ /* compare two regs, pending
+ * the value of a condition reg
+ */
+ rec.pred_args.val1 = REG_RD(bp, rec.reg1);
+ rec.pred_args.val2 = REG_RD(bp, rec.reg2);
+ DP(BNX2X_MSG_IDLE, "mac3 add1 %x add2 %x add3 %x\n",
+ rec.reg1, rec.reg2, rec.reg3);
+ if (REG_RD(bp, rec.reg3) != 0) {
+ if (rec.bnx2x_predicate(&rec.pred_args)) {
+ snprintf(message, sizeof(message),
+ "%s. Values are 0x%x 0x%x\n",
+ rec.fail_msg,
+ rec.pred_args.val1,
+ rec.pred_args.val2);
+ bnx2x_self_test_log(bp, rec.severity,
+ message);
+ }
+ }
+ break;
+ case 6:
+ /* compare read and write pointers
+ * and read and write banks in QM
+ */
+ bnx2x_idle_chk6(bp, &rec, message);
+ break;
+ case 7:
+ /* compare cfc info cam with cid cam */
+ bnx2x_idle_chk7(bp, &rec, message);
+ break;
+ default:
+ DP(BNX2X_MSG_IDLE,
+ "unknown macro in self test data base. macro %d line %d",
+ rec.macro, st_ind);
+ }
+ }
+
+ /* abort if interface is not running */
+ if (!netif_running(bp->dev))
+ return idle_chk_errors;
+
+ /* return value accorindg to statistics */
+ if (idle_chk_errors == 0) {
+ DP(BNX2X_MSG_IDLE,
+ "completed successfully (logged %d warnings)\n",
+ idle_chk_warnings);
+ } else {
+ BNX2X_ERR("failed (with %d errors, %d warnings)\n",
+ idle_chk_errors, idle_chk_warnings);
+ }
+ return idle_chk_errors;
+}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index 7e0919aa450e..0b193edb73b8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -23,6 +23,8 @@
#include "bnx2x_cmn.h"
#include "bnx2x_sriov.h"
+extern const u32 dmae_reg_go_c[];
+
/* Statistics */
/*
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 7463a1847ceb..31fb5a28e1c4 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -1614,7 +1614,7 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp,
skb_set_hash(skb, tpa_info->rss_hash, tpa_info->hash_type);
if ((tpa_info->flags2 & RX_CMP_FLAGS2_META_FORMAT_VLAN) &&
- (skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
+ (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) {
u16 vlan_proto = tpa_info->metadata >>
RX_CMP_FLAGS2_METADATA_TPID_SFT;
u16 vtag = tpa_info->metadata & RX_CMP_FLAGS2_METADATA_TCI_MASK;
@@ -1832,7 +1832,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
if ((rxcmp1->rx_cmp_flags2 &
cpu_to_le32(RX_CMP_FLAGS2_META_FORMAT_VLAN)) &&
- (skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
+ (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) {
u32 meta_data = le32_to_cpu(rxcmp1->rx_cmp_meta_data);
u16 vtag = meta_data & RX_CMP_FLAGS2_METADATA_TCI_MASK;
u16 vlan_proto = meta_data >> RX_CMP_FLAGS2_METADATA_TPID_SFT;
@@ -3546,7 +3546,7 @@ static void bnxt_free_vnic_attributes(struct bnxt *bp)
}
if (vnic->rss_table) {
- dma_free_coherent(&pdev->dev, PAGE_SIZE,
+ dma_free_coherent(&pdev->dev, vnic->rss_table_size,
vnic->rss_table,
vnic->rss_table_dma_addr);
vnic->rss_table = NULL;
@@ -3611,7 +3611,13 @@ vnic_skip_grps:
continue;
/* Allocate rss table and hash key */
- vnic->rss_table = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
+ size = L1_CACHE_ALIGN(HW_HASH_INDEX_SIZE * sizeof(u16));
+ if (bp->flags & BNXT_FLAG_CHIP_P5)
+ size = L1_CACHE_ALIGN(BNXT_MAX_RSS_TABLE_SIZE_P5);
+
+ vnic->rss_table_size = size + HW_HASH_KEY_SIZE;
+ vnic->rss_table = dma_alloc_coherent(&pdev->dev,
+ vnic->rss_table_size,
&vnic->rss_table_dma_addr,
GFP_KERNEL);
if (!vnic->rss_table) {
@@ -3619,8 +3625,6 @@ vnic_skip_grps:
goto out;
}
- size = L1_CACHE_ALIGN(HW_HASH_INDEX_SIZE * sizeof(u16));
-
vnic->rss_hash_key = ((void *)vnic->rss_table) + size;
vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr + size;
}
@@ -3707,67 +3711,189 @@ static int bnxt_alloc_hwrm_short_cmd_req(struct bnxt *bp)
return 0;
}
-static void bnxt_free_port_stats(struct bnxt *bp)
+static void bnxt_free_stats_mem(struct bnxt *bp, struct bnxt_stats_mem *stats)
{
- struct pci_dev *pdev = bp->pdev;
+ kfree(stats->hw_masks);
+ stats->hw_masks = NULL;
+ kfree(stats->sw_stats);
+ stats->sw_stats = NULL;
+ if (stats->hw_stats) {
+ dma_free_coherent(&bp->pdev->dev, stats->len, stats->hw_stats,
+ stats->hw_stats_map);
+ stats->hw_stats = NULL;
+ }
+}
- bp->flags &= ~BNXT_FLAG_PORT_STATS;
- bp->flags &= ~BNXT_FLAG_PORT_STATS_EXT;
+static int bnxt_alloc_stats_mem(struct bnxt *bp, struct bnxt_stats_mem *stats,
+ bool alloc_masks)
+{
+ stats->hw_stats = dma_alloc_coherent(&bp->pdev->dev, stats->len,
+ &stats->hw_stats_map, GFP_KERNEL);
+ if (!stats->hw_stats)
+ return -ENOMEM;
- if (bp->hw_rx_port_stats) {
- dma_free_coherent(&pdev->dev, bp->hw_port_stats_size,
- bp->hw_rx_port_stats,
- bp->hw_rx_port_stats_map);
- bp->hw_rx_port_stats = NULL;
- }
+ stats->sw_stats = kzalloc(stats->len, GFP_KERNEL);
+ if (!stats->sw_stats)
+ goto stats_mem_err;
- if (bp->hw_tx_port_stats_ext) {
- dma_free_coherent(&pdev->dev, sizeof(struct tx_port_stats_ext),
- bp->hw_tx_port_stats_ext,
- bp->hw_tx_port_stats_ext_map);
- bp->hw_tx_port_stats_ext = NULL;
+ if (alloc_masks) {
+ stats->hw_masks = kzalloc(stats->len, GFP_KERNEL);
+ if (!stats->hw_masks)
+ goto stats_mem_err;
}
+ return 0;
+
+stats_mem_err:
+ bnxt_free_stats_mem(bp, stats);
+ return -ENOMEM;
+}
+
+static void bnxt_fill_masks(u64 *mask_arr, u64 mask, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ mask_arr[i] = mask;
+}
+
+static void bnxt_copy_hw_masks(u64 *mask_arr, __le64 *hw_mask_arr, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ mask_arr[i] = le64_to_cpu(hw_mask_arr[i]);
+}
+
+static int bnxt_hwrm_func_qstat_ext(struct bnxt *bp,
+ struct bnxt_stats_mem *stats)
+{
+ struct hwrm_func_qstats_ext_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_func_qstats_ext_input req = {0};
+ __le64 *hw_masks;
+ int rc;
+
+ if (!(bp->fw_cap & BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED) ||
+ !(bp->flags & BNXT_FLAG_CHIP_P5))
+ return -EOPNOTSUPP;
+
+ bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QSTATS_EXT, -1, -1);
+ req.flags = FUNC_QSTATS_EXT_REQ_FLAGS_COUNTER_MASK;
+ mutex_lock(&bp->hwrm_cmd_lock);
+ rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+ if (rc)
+ goto qstat_exit;
- if (bp->hw_rx_port_stats_ext) {
- dma_free_coherent(&pdev->dev, sizeof(struct rx_port_stats_ext),
- bp->hw_rx_port_stats_ext,
- bp->hw_rx_port_stats_ext_map);
- bp->hw_rx_port_stats_ext = NULL;
+ hw_masks = &resp->rx_ucast_pkts;
+ bnxt_copy_hw_masks(stats->hw_masks, hw_masks, stats->len / 8);
+
+qstat_exit:
+ mutex_unlock(&bp->hwrm_cmd_lock);
+ return rc;
+}
+
+static int bnxt_hwrm_port_qstats(struct bnxt *bp, u8 flags);
+static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp, u8 flags);
+
+static void bnxt_init_stats(struct bnxt *bp)
+{
+ struct bnxt_napi *bnapi = bp->bnapi[0];
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_stats_mem *stats;
+ __le64 *rx_stats, *tx_stats;
+ int rc, rx_count, tx_count;
+ u64 *rx_masks, *tx_masks;
+ u64 mask;
+ u8 flags;
+
+ cpr = &bnapi->cp_ring;
+ stats = &cpr->stats;
+ rc = bnxt_hwrm_func_qstat_ext(bp, stats);
+ if (rc) {
+ if (bp->flags & BNXT_FLAG_CHIP_P5)
+ mask = (1ULL << 48) - 1;
+ else
+ mask = -1ULL;
+ bnxt_fill_masks(stats->hw_masks, mask, stats->len / 8);
}
+ if (bp->flags & BNXT_FLAG_PORT_STATS) {
+ stats = &bp->port_stats;
+ rx_stats = stats->hw_stats;
+ rx_masks = stats->hw_masks;
+ rx_count = sizeof(struct rx_port_stats) / 8;
+ tx_stats = rx_stats + BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
+ tx_masks = rx_masks + BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
+ tx_count = sizeof(struct tx_port_stats) / 8;
+
+ flags = PORT_QSTATS_REQ_FLAGS_COUNTER_MASK;
+ rc = bnxt_hwrm_port_qstats(bp, flags);
+ if (rc) {
+ mask = (1ULL << 40) - 1;
+
+ bnxt_fill_masks(rx_masks, mask, rx_count);
+ bnxt_fill_masks(tx_masks, mask, tx_count);
+ } else {
+ bnxt_copy_hw_masks(rx_masks, rx_stats, rx_count);
+ bnxt_copy_hw_masks(tx_masks, tx_stats, tx_count);
+ bnxt_hwrm_port_qstats(bp, 0);
+ }
+ }
+ if (bp->flags & BNXT_FLAG_PORT_STATS_EXT) {
+ stats = &bp->rx_port_stats_ext;
+ rx_stats = stats->hw_stats;
+ rx_masks = stats->hw_masks;
+ rx_count = sizeof(struct rx_port_stats_ext) / 8;
+ stats = &bp->tx_port_stats_ext;
+ tx_stats = stats->hw_stats;
+ tx_masks = stats->hw_masks;
+ tx_count = sizeof(struct tx_port_stats_ext) / 8;
+
+ flags = FUNC_QSTATS_EXT_REQ_FLAGS_COUNTER_MASK;
+ rc = bnxt_hwrm_port_qstats_ext(bp, flags);
+ if (rc) {
+ mask = (1ULL << 40) - 1;
- if (bp->hw_pcie_stats) {
- dma_free_coherent(&pdev->dev, sizeof(struct pcie_ctx_hw_stats),
- bp->hw_pcie_stats, bp->hw_pcie_stats_map);
- bp->hw_pcie_stats = NULL;
+ bnxt_fill_masks(rx_masks, mask, rx_count);
+ if (tx_stats)
+ bnxt_fill_masks(tx_masks, mask, tx_count);
+ } else {
+ bnxt_copy_hw_masks(rx_masks, rx_stats, rx_count);
+ if (tx_stats)
+ bnxt_copy_hw_masks(tx_masks, tx_stats,
+ tx_count);
+ bnxt_hwrm_port_qstats_ext(bp, 0);
+ }
}
}
+static void bnxt_free_port_stats(struct bnxt *bp)
+{
+ bp->flags &= ~BNXT_FLAG_PORT_STATS;
+ bp->flags &= ~BNXT_FLAG_PORT_STATS_EXT;
+
+ bnxt_free_stats_mem(bp, &bp->port_stats);
+ bnxt_free_stats_mem(bp, &bp->rx_port_stats_ext);
+ bnxt_free_stats_mem(bp, &bp->tx_port_stats_ext);
+}
+
static void bnxt_free_ring_stats(struct bnxt *bp)
{
- struct pci_dev *pdev = bp->pdev;
- int size, i;
+ int i;
if (!bp->bnapi)
return;
- size = bp->hw_ring_stats_size;
-
for (i = 0; i < bp->cp_nr_rings; i++) {
struct bnxt_napi *bnapi = bp->bnapi[i];
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
- if (cpr->hw_stats) {
- dma_free_coherent(&pdev->dev, size, cpr->hw_stats,
- cpr->hw_stats_map);
- cpr->hw_stats = NULL;
- }
+ bnxt_free_stats_mem(bp, &cpr->stats);
}
}
static int bnxt_alloc_stats(struct bnxt *bp)
{
u32 size, i;
- struct pci_dev *pdev = bp->pdev;
+ int rc;
size = bp->hw_ring_stats_size;
@@ -3775,11 +3901,10 @@ static int bnxt_alloc_stats(struct bnxt *bp)
struct bnxt_napi *bnapi = bp->bnapi[i];
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
- cpr->hw_stats = dma_alloc_coherent(&pdev->dev, size,
- &cpr->hw_stats_map,
- GFP_KERNEL);
- if (!cpr->hw_stats)
- return -ENOMEM;
+ cpr->stats.len = size;
+ rc = bnxt_alloc_stats_mem(bp, &cpr->stats, !i);
+ if (rc)
+ return rc;
cpr->hw_stats_ctx_id = INVALID_STATS_CTX_ID;
}
@@ -3787,22 +3912,14 @@ static int bnxt_alloc_stats(struct bnxt *bp)
if (BNXT_VF(bp) || bp->chip_num == CHIP_NUM_58700)
return 0;
- if (bp->hw_rx_port_stats)
+ if (bp->port_stats.hw_stats)
goto alloc_ext_stats;
- bp->hw_port_stats_size = sizeof(struct rx_port_stats) +
- sizeof(struct tx_port_stats) + 1024;
-
- bp->hw_rx_port_stats =
- dma_alloc_coherent(&pdev->dev, bp->hw_port_stats_size,
- &bp->hw_rx_port_stats_map,
- GFP_KERNEL);
- if (!bp->hw_rx_port_stats)
- return -ENOMEM;
+ bp->port_stats.len = BNXT_PORT_STATS_SIZE;
+ rc = bnxt_alloc_stats_mem(bp, &bp->port_stats, true);
+ if (rc)
+ return rc;
- bp->hw_tx_port_stats = (void *)(bp->hw_rx_port_stats + 1) + 512;
- bp->hw_tx_port_stats_map = bp->hw_rx_port_stats_map +
- sizeof(struct rx_port_stats) + 512;
bp->flags |= BNXT_FLAG_PORT_STATS;
alloc_ext_stats:
@@ -3811,41 +3928,28 @@ alloc_ext_stats:
if (!(bp->fw_cap & BNXT_FW_CAP_EXT_STATS_SUPPORTED))
return 0;
- if (bp->hw_rx_port_stats_ext)
+ if (bp->rx_port_stats_ext.hw_stats)
goto alloc_tx_ext_stats;
- bp->hw_rx_port_stats_ext =
- dma_alloc_coherent(&pdev->dev, sizeof(struct rx_port_stats_ext),
- &bp->hw_rx_port_stats_ext_map, GFP_KERNEL);
- if (!bp->hw_rx_port_stats_ext)
+ bp->rx_port_stats_ext.len = sizeof(struct rx_port_stats_ext);
+ rc = bnxt_alloc_stats_mem(bp, &bp->rx_port_stats_ext, true);
+ /* Extended stats are optional */
+ if (rc)
return 0;
alloc_tx_ext_stats:
- if (bp->hw_tx_port_stats_ext)
- goto alloc_pcie_stats;
+ if (bp->tx_port_stats_ext.hw_stats)
+ return 0;
if (bp->hwrm_spec_code >= 0x10902 ||
(bp->fw_cap & BNXT_FW_CAP_EXT_STATS_SUPPORTED)) {
- bp->hw_tx_port_stats_ext =
- dma_alloc_coherent(&pdev->dev,
- sizeof(struct tx_port_stats_ext),
- &bp->hw_tx_port_stats_ext_map,
- GFP_KERNEL);
+ bp->tx_port_stats_ext.len = sizeof(struct tx_port_stats_ext);
+ rc = bnxt_alloc_stats_mem(bp, &bp->tx_port_stats_ext, true);
+ /* Extended stats are optional */
+ if (rc)
+ return 0;
}
bp->flags |= BNXT_FLAG_PORT_STATS_EXT;
-
-alloc_pcie_stats:
- if (bp->hw_pcie_stats ||
- !(bp->fw_cap & BNXT_FW_CAP_PCIE_STATS_SUPPORTED))
- return 0;
-
- bp->hw_pcie_stats =
- dma_alloc_coherent(&pdev->dev, sizeof(struct pcie_ctx_hw_stats),
- &bp->hw_pcie_stats_map, GFP_KERNEL);
- if (!bp->hw_pcie_stats)
- return 0;
-
- bp->flags |= BNXT_FLAG_PCIE_STATS;
return 0;
}
@@ -3945,6 +4049,8 @@ static void bnxt_free_mem(struct bnxt *bp, bool irq_re_init)
bnxt_free_ntp_fltrs(bp, irq_re_init);
if (irq_re_init) {
bnxt_free_ring_stats(bp);
+ if (!(bp->fw_cap & BNXT_FW_CAP_PORT_STATS_NO_RESET))
+ bnxt_free_port_stats(bp);
bnxt_free_ring_grps(bp);
bnxt_free_vnics(bp);
kfree(bp->tx_ring_map);
@@ -4048,6 +4154,7 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool irq_re_init)
rc = bnxt_alloc_stats(bp);
if (rc)
goto alloc_mem_err;
+ bnxt_init_stats(bp);
rc = bnxt_alloc_ntp_fltrs(bp);
if (rc)
@@ -4513,10 +4620,12 @@ static int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, u8 tunnel_type)
switch (tunnel_type) {
case TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN:
- req.tunnel_dst_port_id = bp->vxlan_fw_dst_port_id;
+ req.tunnel_dst_port_id = cpu_to_le16(bp->vxlan_fw_dst_port_id);
+ bp->vxlan_fw_dst_port_id = INVALID_HW_RING_ID;
break;
case TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE:
- req.tunnel_dst_port_id = bp->nge_fw_dst_port_id;
+ req.tunnel_dst_port_id = cpu_to_le16(bp->nge_fw_dst_port_id);
+ bp->nge_fw_dst_port_id = INVALID_HW_RING_ID;
break;
default:
break;
@@ -4551,10 +4660,11 @@ static int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, __be16 port,
switch (tunnel_type) {
case TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN:
- bp->vxlan_fw_dst_port_id = resp->tunnel_dst_port_id;
+ bp->vxlan_fw_dst_port_id =
+ le16_to_cpu(resp->tunnel_dst_port_id);
break;
case TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE:
- bp->nge_fw_dst_port_id = resp->tunnel_dst_port_id;
+ bp->nge_fw_dst_port_id = le16_to_cpu(resp->tunnel_dst_port_id);
break;
default:
break;
@@ -4834,9 +4944,112 @@ static u16 bnxt_cp_ring_for_tx(struct bnxt *bp, struct bnxt_tx_ring_info *txr)
}
}
+static int bnxt_alloc_rss_indir_tbl(struct bnxt *bp)
+{
+ int entries;
+
+ if (bp->flags & BNXT_FLAG_CHIP_P5)
+ entries = BNXT_MAX_RSS_TABLE_ENTRIES_P5;
+ else
+ entries = HW_HASH_INDEX_SIZE;
+
+ bp->rss_indir_tbl_entries = entries;
+ bp->rss_indir_tbl = kmalloc_array(entries, sizeof(*bp->rss_indir_tbl),
+ GFP_KERNEL);
+ if (!bp->rss_indir_tbl)
+ return -ENOMEM;
+ return 0;
+}
+
+static void bnxt_set_dflt_rss_indir_tbl(struct bnxt *bp)
+{
+ u16 max_rings, max_entries, pad, i;
+
+ if (!bp->rx_nr_rings)
+ return;
+
+ if (BNXT_CHIP_TYPE_NITRO_A0(bp))
+ max_rings = bp->rx_nr_rings - 1;
+ else
+ max_rings = bp->rx_nr_rings;
+
+ max_entries = bnxt_get_rxfh_indir_size(bp->dev);
+
+ for (i = 0; i < max_entries; i++)
+ bp->rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, max_rings);
+
+ pad = bp->rss_indir_tbl_entries - max_entries;
+ if (pad)
+ memset(&bp->rss_indir_tbl[i], 0, pad * sizeof(u16));
+}
+
+static u16 bnxt_get_max_rss_ring(struct bnxt *bp)
+{
+ u16 i, tbl_size, max_ring = 0;
+
+ if (!bp->rss_indir_tbl)
+ return 0;
+
+ tbl_size = bnxt_get_rxfh_indir_size(bp->dev);
+ for (i = 0; i < tbl_size; i++)
+ max_ring = max(max_ring, bp->rss_indir_tbl[i]);
+ return max_ring;
+}
+
+int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings)
+{
+ if (bp->flags & BNXT_FLAG_CHIP_P5)
+ return DIV_ROUND_UP(rx_rings, BNXT_RSS_TABLE_ENTRIES_P5);
+ if (BNXT_CHIP_TYPE_NITRO_A0(bp))
+ return 2;
+ return 1;
+}
+
+static void __bnxt_fill_hw_rss_tbl(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ bool no_rss = !(vnic->flags & BNXT_VNIC_RSS_FLAG);
+ u16 i, j;
+
+ /* Fill the RSS indirection table with ring group ids */
+ for (i = 0, j = 0; i < HW_HASH_INDEX_SIZE; i++) {
+ if (!no_rss)
+ j = bp->rss_indir_tbl[i];
+ vnic->rss_table[i] = cpu_to_le16(vnic->fw_grp_ids[j]);
+ }
+}
+
+static void __bnxt_fill_hw_rss_tbl_p5(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic)
+{
+ __le16 *ring_tbl = vnic->rss_table;
+ struct bnxt_rx_ring_info *rxr;
+ u16 tbl_size, i;
+
+ tbl_size = bnxt_get_rxfh_indir_size(bp->dev);
+
+ for (i = 0; i < tbl_size; i++) {
+ u16 ring_id, j;
+
+ j = bp->rss_indir_tbl[i];
+ rxr = &bp->rx_ring[j];
+
+ ring_id = rxr->rx_ring_struct.fw_ring_id;
+ *ring_tbl++ = cpu_to_le16(ring_id);
+ ring_id = bnxt_cp_ring_for_rx(bp, rxr);
+ *ring_tbl++ = cpu_to_le16(ring_id);
+ }
+}
+
+static void bnxt_fill_hw_rss_tbl(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ if (bp->flags & BNXT_FLAG_CHIP_P5)
+ __bnxt_fill_hw_rss_tbl_p5(bp, vnic);
+ else
+ __bnxt_fill_hw_rss_tbl(bp, vnic);
+}
+
static int bnxt_hwrm_vnic_set_rss(struct bnxt *bp, u16 vnic_id, bool set_rss)
{
- u32 i, j, max_rings;
struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
struct hwrm_vnic_rss_cfg_input req = {0};
@@ -4846,24 +5059,9 @@ static int bnxt_hwrm_vnic_set_rss(struct bnxt *bp, u16 vnic_id, bool set_rss)
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VNIC_RSS_CFG, -1, -1);
if (set_rss) {
+ bnxt_fill_hw_rss_tbl(bp, vnic);
req.hash_type = cpu_to_le32(bp->rss_hash_cfg);
req.hash_mode_flags = VNIC_RSS_CFG_REQ_HASH_MODE_FLAGS_DEFAULT;
- if (vnic->flags & BNXT_VNIC_RSS_FLAG) {
- if (BNXT_CHIP_TYPE_NITRO_A0(bp))
- max_rings = bp->rx_nr_rings - 1;
- else
- max_rings = bp->rx_nr_rings;
- } else {
- max_rings = 1;
- }
-
- /* Fill the RSS indirection table with ring group ids */
- for (i = 0, j = 0; i < HW_HASH_INDEX_SIZE; i++, j++) {
- if (j == max_rings)
- j = 0;
- vnic->rss_table[i] = cpu_to_le16(vnic->fw_grp_ids[j]);
- }
-
req.ring_grp_tbl_addr = cpu_to_le64(vnic->rss_table_dma_addr);
req.hash_key_tbl_addr =
cpu_to_le64(vnic->rss_hash_key_dma_addr);
@@ -4875,9 +5073,9 @@ static int bnxt_hwrm_vnic_set_rss(struct bnxt *bp, u16 vnic_id, bool set_rss)
static int bnxt_hwrm_vnic_set_rss_p5(struct bnxt *bp, u16 vnic_id, bool set_rss)
{
struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
- u32 i, j, k, nr_ctxs, max_rings = bp->rx_nr_rings;
- struct bnxt_rx_ring_info *rxr = &bp->rx_ring[0];
struct hwrm_vnic_rss_cfg_input req = {0};
+ dma_addr_t ring_tbl_map;
+ u32 i, nr_ctxs;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VNIC_RSS_CFG, -1, -1);
req.vnic_id = cpu_to_le16(vnic->fw_vnic_id);
@@ -4885,31 +5083,18 @@ static int bnxt_hwrm_vnic_set_rss_p5(struct bnxt *bp, u16 vnic_id, bool set_rss)
hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
return 0;
}
+ bnxt_fill_hw_rss_tbl(bp, vnic);
req.hash_type = cpu_to_le32(bp->rss_hash_cfg);
req.hash_mode_flags = VNIC_RSS_CFG_REQ_HASH_MODE_FLAGS_DEFAULT;
- req.ring_grp_tbl_addr = cpu_to_le64(vnic->rss_table_dma_addr);
req.hash_key_tbl_addr = cpu_to_le64(vnic->rss_hash_key_dma_addr);
- nr_ctxs = DIV_ROUND_UP(bp->rx_nr_rings, 64);
- for (i = 0, k = 0; i < nr_ctxs; i++) {
- __le16 *ring_tbl = vnic->rss_table;
+ ring_tbl_map = vnic->rss_table_dma_addr;
+ nr_ctxs = bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings);
+ for (i = 0; i < nr_ctxs; ring_tbl_map += BNXT_RSS_TABLE_SIZE_P5, i++) {
int rc;
+ req.ring_grp_tbl_addr = cpu_to_le64(ring_tbl_map);
req.ring_table_pair_index = i;
req.rss_ctx_idx = cpu_to_le16(vnic->fw_rss_cos_lb_ctx[i]);
- for (j = 0; j < 64; j++) {
- u16 ring_id;
-
- ring_id = rxr->rx_ring_struct.fw_ring_id;
- *ring_tbl++ = cpu_to_le16(ring_id);
- ring_id = bnxt_cp_ring_for_rx(bp, rxr);
- *ring_tbl++ = cpu_to_le16(ring_id);
- rxr++;
- k++;
- if (k == max_rings) {
- k = 0;
- rxr = &bp->rx_ring[0];
- }
- }
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc)
return rc;
@@ -5147,6 +5332,14 @@ static int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
if (flags &
VNIC_QCAPS_RESP_FLAGS_ROCE_MIRRORING_CAPABLE_VNIC_CAP)
bp->flags |= BNXT_FLAG_ROCE_MIRROR_CAP;
+
+ /* Older P5 fw before EXT_HW_STATS support did not set
+ * VLAN_STRIP_CAP properly.
+ */
+ if ((flags & VNIC_QCAPS_RESP_FLAGS_VLAN_STRIP_CAP) ||
+ ((bp->flags & BNXT_FLAG_CHIP_P5) &&
+ !(bp->fw_cap & BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED)))
+ bp->fw_cap |= BNXT_FW_CAP_VLAN_RX_STRIP;
bp->max_tpa_v2 = le16_to_cpu(resp->max_aggs_supported);
if (bp->max_tpa_v2)
bp->hw_ring_stats_size =
@@ -6000,6 +6193,21 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
rx = rx_rings << 1;
cp = sh ? max_t(int, tx, rx_rings) : tx + rx_rings;
bp->tx_nr_rings = tx;
+
+ /* If we cannot reserve all the RX rings, reset the RSS map only
+ * if absolutely necessary
+ */
+ if (rx_rings != bp->rx_nr_rings) {
+ netdev_warn(bp->dev, "Able to reserve only %d out of %d requested RX rings\n",
+ rx_rings, bp->rx_nr_rings);
+ if ((bp->dev->priv_flags & IFF_RXFH_CONFIGURED) &&
+ (bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings) !=
+ bnxt_get_nr_rss_ctxs(bp, rx_rings) ||
+ bnxt_get_max_rss_ring(bp) >= rx_rings)) {
+ netdev_warn(bp->dev, "RSS table entries reverting to default\n");
+ bp->dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
+ }
+ }
bp->rx_nr_rings = rx_rings;
bp->cp_nr_rings = cp;
@@ -6353,7 +6561,7 @@ static int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp)
struct bnxt_napi *bnapi = bp->bnapi[i];
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
- req.stats_dma_addr = cpu_to_le64(cpr->hw_stats_map);
+ req.stats_dma_addr = cpu_to_le64(cpr->stats.hw_stats_map);
rc = _hwrm_send_message(bp, &req, sizeof(req),
HWRM_CMD_TIMEOUT);
@@ -6963,7 +7171,7 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
struct hwrm_func_qcaps_input req = {0};
struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
- u32 flags;
+ u32 flags, flags_ext;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QCAPS, -1, -1);
req.fid = cpu_to_le16(0xffff);
@@ -6988,6 +7196,12 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
bp->fw_cap |= BNXT_FW_CAP_ERROR_RECOVERY;
if (flags & FUNC_QCAPS_RESP_FLAGS_ERR_RECOVER_RELOAD)
bp->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD;
+ if (!(flags & FUNC_QCAPS_RESP_FLAGS_VLAN_ACCELERATION_TX_DISABLED))
+ bp->fw_cap |= BNXT_FW_CAP_VLAN_TX_INSERT;
+
+ flags_ext = le32_to_cpu(resp->flags_ext);
+ if (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_EXT_HW_STATS_SUPPORTED)
+ bp->fw_cap |= BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED;
bp->tx_push_thresh = 0;
if ((flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) &&
@@ -7378,7 +7592,89 @@ int bnxt_hwrm_fw_set_time(struct bnxt *bp)
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
}
-static int bnxt_hwrm_port_qstats(struct bnxt *bp)
+static void bnxt_add_one_ctr(u64 hw, u64 *sw, u64 mask)
+{
+ u64 sw_tmp;
+
+ sw_tmp = (*sw & ~mask) | hw;
+ if (hw < (*sw & mask))
+ sw_tmp += mask + 1;
+ WRITE_ONCE(*sw, sw_tmp);
+}
+
+static void __bnxt_accumulate_stats(__le64 *hw_stats, u64 *sw_stats, u64 *masks,
+ int count, bool ignore_zero)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ u64 hw = le64_to_cpu(READ_ONCE(hw_stats[i]));
+
+ if (ignore_zero && !hw)
+ continue;
+
+ if (masks[i] == -1ULL)
+ sw_stats[i] = hw;
+ else
+ bnxt_add_one_ctr(hw, &sw_stats[i], masks[i]);
+ }
+}
+
+static void bnxt_accumulate_stats(struct bnxt_stats_mem *stats)
+{
+ if (!stats->hw_stats)
+ return;
+
+ __bnxt_accumulate_stats(stats->hw_stats, stats->sw_stats,
+ stats->hw_masks, stats->len / 8, false);
+}
+
+static void bnxt_accumulate_all_stats(struct bnxt *bp)
+{
+ struct bnxt_stats_mem *ring0_stats;
+ bool ignore_zero = false;
+ int i;
+
+ /* Chip bug. Counter intermittently becomes 0. */
+ if (bp->flags & BNXT_FLAG_CHIP_P5)
+ ignore_zero = true;
+
+ for (i = 0; i < bp->cp_nr_rings; i++) {
+ struct bnxt_napi *bnapi = bp->bnapi[i];
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_stats_mem *stats;
+
+ cpr = &bnapi->cp_ring;
+ stats = &cpr->stats;
+ if (!i)
+ ring0_stats = stats;
+ __bnxt_accumulate_stats(stats->hw_stats, stats->sw_stats,
+ ring0_stats->hw_masks,
+ ring0_stats->len / 8, ignore_zero);
+ }
+ if (bp->flags & BNXT_FLAG_PORT_STATS) {
+ struct bnxt_stats_mem *stats = &bp->port_stats;
+ __le64 *hw_stats = stats->hw_stats;
+ u64 *sw_stats = stats->sw_stats;
+ u64 *masks = stats->hw_masks;
+ int cnt;
+
+ cnt = sizeof(struct rx_port_stats) / 8;
+ __bnxt_accumulate_stats(hw_stats, sw_stats, masks, cnt, false);
+
+ hw_stats += BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
+ sw_stats += BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
+ masks += BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
+ cnt = sizeof(struct tx_port_stats) / 8;
+ __bnxt_accumulate_stats(hw_stats, sw_stats, masks, cnt, false);
+ }
+ if (bp->flags & BNXT_FLAG_PORT_STATS_EXT) {
+ bnxt_accumulate_stats(&bp->rx_port_stats_ext);
+ bnxt_accumulate_stats(&bp->tx_port_stats_ext);
+ }
+}
+
+static int bnxt_hwrm_port_qstats(struct bnxt *bp, u8 flags)
{
struct bnxt_pf_info *pf = &bp->pf;
struct hwrm_port_qstats_input req = {0};
@@ -7386,14 +7682,19 @@ static int bnxt_hwrm_port_qstats(struct bnxt *bp)
if (!(bp->flags & BNXT_FLAG_PORT_STATS))
return 0;
+ if (flags && !(bp->fw_cap & BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED))
+ return -EOPNOTSUPP;
+
+ req.flags = flags;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_QSTATS, -1, -1);
req.port_id = cpu_to_le16(pf->port_id);
- req.tx_stat_host_addr = cpu_to_le64(bp->hw_tx_port_stats_map);
- req.rx_stat_host_addr = cpu_to_le64(bp->hw_rx_port_stats_map);
+ req.tx_stat_host_addr = cpu_to_le64(bp->port_stats.hw_stats_map +
+ BNXT_TX_PORT_STATS_BYTE_OFFSET);
+ req.rx_stat_host_addr = cpu_to_le64(bp->port_stats.hw_stats_map);
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
}
-static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp)
+static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp, u8 flags)
{
struct hwrm_port_qstats_ext_output *resp = bp->hwrm_cmd_resp_addr;
struct hwrm_queue_pri2cos_qcfg_input req2 = {0};
@@ -7405,14 +7706,18 @@ static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp)
if (!(bp->flags & BNXT_FLAG_PORT_STATS_EXT))
return 0;
+ if (flags && !(bp->fw_cap & BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED))
+ return -EOPNOTSUPP;
+
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_QSTATS_EXT, -1, -1);
+ req.flags = flags;
req.port_id = cpu_to_le16(pf->port_id);
req.rx_stat_size = cpu_to_le16(sizeof(struct rx_port_stats_ext));
- req.rx_stat_host_addr = cpu_to_le64(bp->hw_rx_port_stats_ext_map);
- tx_stat_size = bp->hw_tx_port_stats_ext ?
- sizeof(*bp->hw_tx_port_stats_ext) : 0;
+ req.rx_stat_host_addr = cpu_to_le64(bp->rx_port_stats_ext.hw_stats_map);
+ tx_stat_size = bp->tx_port_stats_ext.hw_stats ?
+ sizeof(struct tx_port_stats_ext) : 0;
req.tx_stat_size = cpu_to_le16(tx_stat_size);
- req.tx_stat_host_addr = cpu_to_le64(bp->hw_tx_port_stats_ext_map);
+ req.tx_stat_host_addr = cpu_to_le64(bp->tx_port_stats_ext.hw_stats_map);
mutex_lock(&bp->hwrm_cmd_lock);
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (!rc) {
@@ -7423,6 +7728,9 @@ static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp)
bp->fw_rx_stats_ext_size = 0;
bp->fw_tx_stats_ext_size = 0;
}
+ if (flags)
+ goto qstats_done;
+
if (bp->fw_tx_stats_ext_size <=
offsetof(struct tx_port_stats_ext, pfc_pri0_tx_duration_us) / 8) {
mutex_unlock(&bp->hwrm_cmd_lock);
@@ -7463,31 +7771,14 @@ qstats_done:
return rc;
}
-static int bnxt_hwrm_pcie_qstats(struct bnxt *bp)
-{
- struct hwrm_pcie_qstats_input req = {0};
-
- if (!(bp->flags & BNXT_FLAG_PCIE_STATS))
- return 0;
-
- bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PCIE_QSTATS, -1, -1);
- req.pcie_stat_size = cpu_to_le16(sizeof(struct pcie_ctx_hw_stats));
- req.pcie_stat_host_addr = cpu_to_le64(bp->hw_pcie_stats_map);
- return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
-}
-
static void bnxt_hwrm_free_tunnel_ports(struct bnxt *bp)
{
- if (bp->vxlan_port_cnt) {
+ if (bp->vxlan_fw_dst_port_id != INVALID_HW_RING_ID)
bnxt_hwrm_tunnel_dst_port_free(
bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN);
- }
- bp->vxlan_port_cnt = 0;
- if (bp->nge_port_cnt) {
+ if (bp->nge_fw_dst_port_id != INVALID_HW_RING_ID)
bnxt_hwrm_tunnel_dst_port_free(
bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE);
- }
- bp->nge_port_cnt = 0;
}
static int bnxt_set_tpa(struct bnxt *bp, bool set_tpa)
@@ -7642,7 +7933,7 @@ static int __bnxt_setup_vnic_p5(struct bnxt *bp, u16 vnic_id)
{
int rc, i, nr_ctxs;
- nr_ctxs = DIV_ROUND_UP(bp->rx_nr_rings, 64);
+ nr_ctxs = bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings);
for (i = 0; i < nr_ctxs; i++) {
rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic_id, i);
if (rc) {
@@ -8204,6 +8495,9 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init)
rc = bnxt_init_int_mode(bp);
bnxt_ulp_irq_restart(bp, rc);
}
+ if (!netif_is_rxfh_configured(bp->dev))
+ bnxt_set_dflt_rss_indir_tbl(bp);
+
if (rc) {
netdev_err(bp->dev, "ring reservation/IRQ init failure rc: %d\n", rc);
return rc;
@@ -8498,6 +8792,9 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp)
if (BNXT_PF(bp))
bp->fw_cap |= BNXT_FW_CAP_SHARED_PORT_CFG;
}
+ if (resp->flags & PORT_PHY_QCAPS_RESP_FLAGS_CUMULATIVE_COUNTERS_ON_RESET)
+ bp->fw_cap |= BNXT_FW_CAP_PORT_STATS_NO_RESET;
+
if (resp->supported_speeds_auto_mode)
link_info->support_auto_speeds =
le16_to_cpu(resp->supported_speeds_auto_mode);
@@ -9202,7 +9499,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
}
if (irq_re_init)
- udp_tunnel_get_rx_info(bp->dev);
+ udp_tunnel_nic_reset_ntf(bp->dev);
set_bit(BNXT_STATE_OPEN, &bp->state);
bnxt_enable_int(bp);
@@ -9500,34 +9797,33 @@ static void bnxt_get_ring_stats(struct bnxt *bp,
{
int i;
-
for (i = 0; i < bp->cp_nr_rings; i++) {
struct bnxt_napi *bnapi = bp->bnapi[i];
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
- struct ctx_hw_stats *hw_stats = cpr->hw_stats;
+ u64 *sw = cpr->stats.sw_stats;
- stats->rx_packets += le64_to_cpu(hw_stats->rx_ucast_pkts);
- stats->rx_packets += le64_to_cpu(hw_stats->rx_mcast_pkts);
- stats->rx_packets += le64_to_cpu(hw_stats->rx_bcast_pkts);
+ stats->rx_packets += BNXT_GET_RING_STATS64(sw, rx_ucast_pkts);
+ stats->rx_packets += BNXT_GET_RING_STATS64(sw, rx_mcast_pkts);
+ stats->rx_packets += BNXT_GET_RING_STATS64(sw, rx_bcast_pkts);
- stats->tx_packets += le64_to_cpu(hw_stats->tx_ucast_pkts);
- stats->tx_packets += le64_to_cpu(hw_stats->tx_mcast_pkts);
- stats->tx_packets += le64_to_cpu(hw_stats->tx_bcast_pkts);
+ stats->tx_packets += BNXT_GET_RING_STATS64(sw, tx_ucast_pkts);
+ stats->tx_packets += BNXT_GET_RING_STATS64(sw, tx_mcast_pkts);
+ stats->tx_packets += BNXT_GET_RING_STATS64(sw, tx_bcast_pkts);
- stats->rx_bytes += le64_to_cpu(hw_stats->rx_ucast_bytes);
- stats->rx_bytes += le64_to_cpu(hw_stats->rx_mcast_bytes);
- stats->rx_bytes += le64_to_cpu(hw_stats->rx_bcast_bytes);
+ stats->rx_bytes += BNXT_GET_RING_STATS64(sw, rx_ucast_bytes);
+ stats->rx_bytes += BNXT_GET_RING_STATS64(sw, rx_mcast_bytes);
+ stats->rx_bytes += BNXT_GET_RING_STATS64(sw, rx_bcast_bytes);
- stats->tx_bytes += le64_to_cpu(hw_stats->tx_ucast_bytes);
- stats->tx_bytes += le64_to_cpu(hw_stats->tx_mcast_bytes);
- stats->tx_bytes += le64_to_cpu(hw_stats->tx_bcast_bytes);
+ stats->tx_bytes += BNXT_GET_RING_STATS64(sw, tx_ucast_bytes);
+ stats->tx_bytes += BNXT_GET_RING_STATS64(sw, tx_mcast_bytes);
+ stats->tx_bytes += BNXT_GET_RING_STATS64(sw, tx_bcast_bytes);
stats->rx_missed_errors +=
- le64_to_cpu(hw_stats->rx_discard_pkts);
+ BNXT_GET_RING_STATS64(sw, rx_discard_pkts);
- stats->multicast += le64_to_cpu(hw_stats->rx_mcast_pkts);
+ stats->multicast += BNXT_GET_RING_STATS64(sw, rx_mcast_pkts);
- stats->tx_dropped += le64_to_cpu(hw_stats->tx_drop_pkts);
+ stats->tx_dropped += BNXT_GET_RING_STATS64(sw, tx_error_pkts);
}
}
@@ -9565,19 +9861,26 @@ bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
bnxt_add_prev_stats(bp, stats);
if (bp->flags & BNXT_FLAG_PORT_STATS) {
- struct rx_port_stats *rx = bp->hw_rx_port_stats;
- struct tx_port_stats *tx = bp->hw_tx_port_stats;
-
- stats->rx_crc_errors = le64_to_cpu(rx->rx_fcs_err_frames);
- stats->rx_frame_errors = le64_to_cpu(rx->rx_align_err_frames);
- stats->rx_length_errors = le64_to_cpu(rx->rx_undrsz_frames) +
- le64_to_cpu(rx->rx_ovrsz_frames) +
- le64_to_cpu(rx->rx_runt_frames);
- stats->rx_errors = le64_to_cpu(rx->rx_false_carrier_frames) +
- le64_to_cpu(rx->rx_jbr_frames);
- stats->collisions = le64_to_cpu(tx->tx_total_collisions);
- stats->tx_fifo_errors = le64_to_cpu(tx->tx_fifo_underruns);
- stats->tx_errors = le64_to_cpu(tx->tx_err);
+ u64 *rx = bp->port_stats.sw_stats;
+ u64 *tx = bp->port_stats.sw_stats +
+ BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
+
+ stats->rx_crc_errors =
+ BNXT_GET_RX_PORT_STATS64(rx, rx_fcs_err_frames);
+ stats->rx_frame_errors =
+ BNXT_GET_RX_PORT_STATS64(rx, rx_align_err_frames);
+ stats->rx_length_errors =
+ BNXT_GET_RX_PORT_STATS64(rx, rx_undrsz_frames) +
+ BNXT_GET_RX_PORT_STATS64(rx, rx_ovrsz_frames) +
+ BNXT_GET_RX_PORT_STATS64(rx, rx_runt_frames);
+ stats->rx_errors =
+ BNXT_GET_RX_PORT_STATS64(rx, rx_false_carrier_frames) +
+ BNXT_GET_RX_PORT_STATS64(rx, rx_jbr_frames);
+ stats->collisions =
+ BNXT_GET_TX_PORT_STATS64(tx, tx_total_collisions);
+ stats->tx_fifo_errors =
+ BNXT_GET_TX_PORT_STATS64(tx, tx_fifo_underruns);
+ stats->tx_errors = BNXT_GET_TX_PORT_STATS64(tx, tx_err);
}
clear_bit(BNXT_STATE_READ_STATS, &bp->state);
}
@@ -9843,24 +10146,16 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev,
/* Both CTAG and STAG VLAN accelaration on the RX side have to be
* turned on or off together.
*/
- vlan_features = features & (NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HW_VLAN_STAG_RX);
- if (vlan_features != (NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HW_VLAN_STAG_RX)) {
- if (dev->features & NETIF_F_HW_VLAN_CTAG_RX)
- features &= ~(NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HW_VLAN_STAG_RX);
+ vlan_features = features & BNXT_HW_FEATURE_VLAN_ALL_RX;
+ if (vlan_features != BNXT_HW_FEATURE_VLAN_ALL_RX) {
+ if (dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)
+ features &= ~BNXT_HW_FEATURE_VLAN_ALL_RX;
else if (vlan_features)
- features |= NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HW_VLAN_STAG_RX;
+ features |= BNXT_HW_FEATURE_VLAN_ALL_RX;
}
#ifdef CONFIG_BNXT_SRIOV
- if (BNXT_VF(bp)) {
- if (bp->vf.vlan) {
- features &= ~(NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HW_VLAN_STAG_RX);
- }
- }
+ if (BNXT_VF(bp) && bp->vf.vlan)
+ features &= ~BNXT_HW_FEATURE_VLAN_ALL_RX;
#endif
return features;
}
@@ -9883,7 +10178,7 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features)
if (bp->flags & BNXT_FLAG_NO_AGG_RINGS)
flags &= ~BNXT_FLAG_TPA;
- if (features & NETIF_F_HW_VLAN_CTAG_RX)
+ if (features & BNXT_HW_FEATURE_VLAN_ALL_RX)
flags |= BNXT_FLAG_STRIP_VLAN;
if (features & NETIF_F_NTUPLE)
@@ -9931,6 +10226,38 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features)
return rc;
}
+int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words,
+ u32 *reg_buf)
+{
+ struct hwrm_dbg_read_direct_output *resp = bp->hwrm_cmd_resp_addr;
+ struct hwrm_dbg_read_direct_input req = {0};
+ __le32 *dbg_reg_buf;
+ dma_addr_t mapping;
+ int rc, i;
+
+ dbg_reg_buf = dma_alloc_coherent(&bp->pdev->dev, num_words * 4,
+ &mapping, GFP_KERNEL);
+ if (!dbg_reg_buf)
+ return -ENOMEM;
+ bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_DBG_READ_DIRECT, -1, -1);
+ req.host_dest_addr = cpu_to_le64(mapping);
+ req.read_addr = cpu_to_le32(reg_off + CHIMP_REG_VIEW_ADDR);
+ req.read_len32 = cpu_to_le32(num_words);
+ mutex_lock(&bp->hwrm_cmd_lock);
+ rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+ if (rc || resp->error_code) {
+ rc = -EIO;
+ goto dbg_rd_reg_exit;
+ }
+ for (i = 0; i < num_words; i++)
+ reg_buf[i] = le32_to_cpu(dbg_reg_buf[i]);
+
+dbg_rd_reg_exit:
+ mutex_unlock(&bp->hwrm_cmd_lock);
+ dma_free_coherent(&bp->pdev->dev, num_words * 4, dbg_reg_buf, mapping);
+ return rc;
+}
+
static int bnxt_dbg_hwrm_ring_info_get(struct bnxt *bp, u8 ring_type,
u32 ring_id, u32 *prod, u32 *cons)
{
@@ -10075,8 +10402,7 @@ static void bnxt_timer(struct timer_list *t)
if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)
bnxt_fw_health_check(bp);
- if (bp->link_info.link_up && (bp->flags & BNXT_FLAG_PORT_STATS) &&
- bp->stats_coal_ticks) {
+ if (bp->link_info.link_up && bp->stats_coal_ticks) {
set_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event);
bnxt_queue_sp_work(bp);
}
@@ -10361,28 +10687,10 @@ static void bnxt_sp_task(struct work_struct *work)
bnxt_cfg_ntp_filters(bp);
if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event))
bnxt_hwrm_exec_fwd_req(bp);
- if (test_and_clear_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event)) {
- bnxt_hwrm_tunnel_dst_port_alloc(
- bp, bp->vxlan_port,
- TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN);
- }
- if (test_and_clear_bit(BNXT_VXLAN_DEL_PORT_SP_EVENT, &bp->sp_event)) {
- bnxt_hwrm_tunnel_dst_port_free(
- bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN);
- }
- if (test_and_clear_bit(BNXT_GENEVE_ADD_PORT_SP_EVENT, &bp->sp_event)) {
- bnxt_hwrm_tunnel_dst_port_alloc(
- bp, bp->nge_port,
- TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE);
- }
- if (test_and_clear_bit(BNXT_GENEVE_DEL_PORT_SP_EVENT, &bp->sp_event)) {
- bnxt_hwrm_tunnel_dst_port_free(
- bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE);
- }
if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) {
- bnxt_hwrm_port_qstats(bp);
- bnxt_hwrm_port_qstats_ext(bp);
- bnxt_hwrm_pcie_qstats(bp);
+ bnxt_hwrm_port_qstats(bp, 0);
+ bnxt_hwrm_port_qstats_ext(bp, 0);
+ bnxt_accumulate_all_stats(bp);
}
if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
@@ -10975,6 +11283,9 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
timer_setup(&bp->timer, bnxt_timer, 0);
bp->current_interval = BNXT_TIMER_INTERVAL;
+ bp->vxlan_fw_dst_port_id = INVALID_HW_RING_ID;
+ bp->nge_fw_dst_port_id = INVALID_HW_RING_ID;
+
clear_bit(BNXT_STATE_OPEN, &bp->state);
return 0;
@@ -11302,84 +11613,33 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
#endif /* CONFIG_RFS_ACCEL */
-static void bnxt_udp_tunnel_add(struct net_device *dev,
- struct udp_tunnel_info *ti)
+static int bnxt_udp_tunnel_sync(struct net_device *netdev, unsigned int table)
{
- struct bnxt *bp = netdev_priv(dev);
-
- if (ti->sa_family != AF_INET6 && ti->sa_family != AF_INET)
- return;
-
- if (!netif_running(dev))
- return;
+ struct bnxt *bp = netdev_priv(netdev);
+ struct udp_tunnel_info ti;
+ unsigned int cmd;
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- if (bp->vxlan_port_cnt && bp->vxlan_port != ti->port)
- return;
+ udp_tunnel_nic_get_port(netdev, table, 0, &ti);
+ if (ti.type == UDP_TUNNEL_TYPE_VXLAN)
+ cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN;
+ else
+ cmd = TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE;
- bp->vxlan_port_cnt++;
- if (bp->vxlan_port_cnt == 1) {
- bp->vxlan_port = ti->port;
- set_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event);
- bnxt_queue_sp_work(bp);
- }
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- if (bp->nge_port_cnt && bp->nge_port != ti->port)
- return;
+ if (ti.port)
+ return bnxt_hwrm_tunnel_dst_port_alloc(bp, ti.port, cmd);
- bp->nge_port_cnt++;
- if (bp->nge_port_cnt == 1) {
- bp->nge_port = ti->port;
- set_bit(BNXT_GENEVE_ADD_PORT_SP_EVENT, &bp->sp_event);
- }
- break;
- default:
- return;
- }
-
- bnxt_queue_sp_work(bp);
+ return bnxt_hwrm_tunnel_dst_port_free(bp, cmd);
}
-static void bnxt_udp_tunnel_del(struct net_device *dev,
- struct udp_tunnel_info *ti)
-{
- struct bnxt *bp = netdev_priv(dev);
-
- if (ti->sa_family != AF_INET6 && ti->sa_family != AF_INET)
- return;
-
- if (!netif_running(dev))
- return;
-
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- if (!bp->vxlan_port_cnt || bp->vxlan_port != ti->port)
- return;
- bp->vxlan_port_cnt--;
-
- if (bp->vxlan_port_cnt != 0)
- return;
-
- set_bit(BNXT_VXLAN_DEL_PORT_SP_EVENT, &bp->sp_event);
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- if (!bp->nge_port_cnt || bp->nge_port != ti->port)
- return;
- bp->nge_port_cnt--;
-
- if (bp->nge_port_cnt != 0)
- return;
-
- set_bit(BNXT_GENEVE_DEL_PORT_SP_EVENT, &bp->sp_event);
- break;
- default:
- return;
- }
-
- bnxt_queue_sp_work(bp);
-}
+static const struct udp_tunnel_nic_info bnxt_udp_tunnels = {
+ .sync_table = bnxt_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
+ UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+ },
+};
static int bnxt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
struct net_device *dev, u32 filter_mask,
@@ -11477,8 +11737,8 @@ static const struct net_device_ops bnxt_netdev_ops = {
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = bnxt_rx_flow_steer,
#endif
- .ndo_udp_tunnel_add = bnxt_udp_tunnel_add,
- .ndo_udp_tunnel_del = bnxt_udp_tunnel_del,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_bpf = bnxt_xdp,
.ndo_xdp_xmit = bnxt_xdp_xmit,
.ndo_bridge_getlink = bnxt_bridge_getlink,
@@ -11518,6 +11778,8 @@ static void bnxt_remove_one(struct pci_dev *pdev)
bnxt_free_ctx_mem(bp);
kfree(bp->ctx);
bp->ctx = NULL;
+ kfree(bp->rss_indir_tbl);
+ bp->rss_indir_tbl = NULL;
bnxt_free_port_stats(bp);
free_netdev(dev);
}
@@ -11966,11 +12228,15 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_IPXIP4 | NETIF_F_GSO_PARTIAL;
+ dev->udp_tunnel_nic_info = &bnxt_udp_tunnels;
+
dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_GRE_CSUM;
dev->vlan_features = dev->hw_features | NETIF_F_HIGHDMA;
- dev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX |
- NETIF_F_HW_VLAN_STAG_RX | NETIF_F_HW_VLAN_STAG_TX;
+ if (bp->fw_cap & BNXT_FW_CAP_VLAN_RX_STRIP)
+ dev->hw_features |= BNXT_HW_FEATURE_VLAN_ALL_RX;
+ if (bp->fw_cap & BNXT_FW_CAP_VLAN_TX_INSERT)
+ dev->hw_features |= BNXT_HW_FEATURE_VLAN_ALL_TX;
if (BNXT_SUPPORTS_TPA(bp))
dev->hw_features |= NETIF_F_GRO_HW;
dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
@@ -12026,7 +12292,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
bnxt_fw_init_one_p3(bp);
- if (dev->hw_features & NETIF_F_HW_VLAN_CTAG_RX)
+ if (dev->hw_features & BNXT_HW_FEATURE_VLAN_ALL_RX)
bp->flags |= BNXT_FLAG_STRIP_VLAN;
rc = bnxt_init_int_mode(bp);
@@ -12038,6 +12304,11 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
+ rc = bnxt_alloc_rss_indir_tbl(bp);
+ if (rc)
+ goto init_err_pci_clean;
+ bnxt_set_dflt_rss_indir_tbl(bp);
+
if (BNXT_PF(bp)) {
if (!bnxt_pf_wq) {
bnxt_pf_wq =
@@ -12047,7 +12318,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto init_err_pci_clean;
}
}
- bnxt_init_tc(bp);
+ rc = bnxt_init_tc(bp);
+ if (rc)
+ netdev_err(dev, "Failed to initialize TC flower offload, err = %d.\n",
+ rc);
}
bnxt_dl_register(bp);
@@ -12082,6 +12356,8 @@ init_err_pci_clean:
bnxt_free_ctx_mem(bp);
kfree(bp->ctx);
bp->ctx = NULL;
+ kfree(bp->rss_indir_tbl);
+ bp->rss_indir_tbl = NULL;
init_err_free:
free_netdev(dev);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 78e2fd63ac3d..5a13eb66beda 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -919,6 +919,14 @@ struct bnxt_sw_stats {
struct bnxt_cmn_sw_stats cmn;
};
+struct bnxt_stats_mem {
+ u64 *sw_stats;
+ u64 *hw_masks;
+ void *hw_stats;
+ dma_addr_t hw_stats_map;
+ int len;
+};
+
struct bnxt_cp_ring_info {
struct bnxt_napi *bnapi;
u32 cp_raw_cons;
@@ -943,8 +951,7 @@ struct bnxt_cp_ring_info {
dma_addr_t cp_desc_mapping[MAX_CP_PAGES];
- struct ctx_hw_stats *hw_stats;
- dma_addr_t hw_stats_map;
+ struct bnxt_stats_mem stats;
u32 hw_stats_ctx_id;
struct bnxt_sw_stats sw_stats;
@@ -1017,6 +1024,15 @@ struct bnxt_vnic_info {
__le16 *rss_table;
dma_addr_t rss_hash_key_dma_addr;
u64 *rss_hash_key;
+ int rss_table_size;
+#define BNXT_RSS_TABLE_ENTRIES_P5 64
+#define BNXT_RSS_TABLE_SIZE_P5 (BNXT_RSS_TABLE_ENTRIES_P5 * 4)
+#define BNXT_RSS_TABLE_MAX_TBL_P5 8
+#define BNXT_MAX_RSS_TABLE_SIZE_P5 \
+ (BNXT_RSS_TABLE_SIZE_P5 * BNXT_RSS_TABLE_MAX_TBL_P5)
+#define BNXT_MAX_RSS_TABLE_ENTRIES_P5 \
+ (BNXT_RSS_TABLE_ENTRIES_P5 * BNXT_RSS_TABLE_MAX_TBL_P5)
+
u32 rx_mask;
u8 *mc_list;
@@ -1126,6 +1142,50 @@ struct bnxt_ntuple_filter {
#define BNXT_FLTR_UPDATE 1
};
+struct hwrm_port_phy_qcfg_output_compat {
+ __le16 error_code;
+ __le16 req_type;
+ __le16 seq_id;
+ __le16 resp_len;
+ u8 link;
+ u8 link_signal_mode;
+ __le16 link_speed;
+ u8 duplex_cfg;
+ u8 pause;
+ __le16 support_speeds;
+ __le16 force_link_speed;
+ u8 auto_mode;
+ u8 auto_pause;
+ __le16 auto_link_speed;
+ __le16 auto_link_speed_mask;
+ u8 wirespeed;
+ u8 lpbk;
+ u8 force_pause;
+ u8 module_status;
+ __le32 preemphasis;
+ u8 phy_maj;
+ u8 phy_min;
+ u8 phy_bld;
+ u8 phy_type;
+ u8 media_type;
+ u8 xcvr_pkg_type;
+ u8 eee_config_phy_addr;
+ u8 parallel_detect;
+ __le16 link_partner_adv_speeds;
+ u8 link_partner_adv_auto_mode;
+ u8 link_partner_adv_pause;
+ __le16 adv_eee_link_speed_mask;
+ __le16 link_partner_adv_eee_link_speed_mask;
+ __le32 xcvr_identifier_type_tx_lpi_timer;
+ __le16 fec_cfg;
+ u8 duplex_state;
+ u8 option_flags;
+ char phy_vendor_name[16];
+ char phy_vendor_partnumber[16];
+ u8 unused_0[7];
+ u8 valid;
+};
+
struct bnxt_link_info {
u8 phy_type;
u8 media_type;
@@ -1244,6 +1304,9 @@ struct bnxt_test_info {
char string[BNXT_MAX_TEST][ETH_GSTRING_LEN];
};
+#define CHIMP_REG_VIEW_ADDR \
+ ((bp->flags & BNXT_FLAG_CHIP_P5) ? 0x80000000 : 0xb1000000)
+
#define BNXT_GRCPF_REG_CHIMP_COMM 0x0
#define BNXT_GRCPF_REG_CHIMP_COMM_TRIGGER 0x100
#define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400
@@ -1557,7 +1620,6 @@ struct bnxt {
#define BNXT_FLAG_DIM 0x2000000
#define BNXT_FLAG_ROCE_MIRROR_CAP 0x4000000
#define BNXT_FLAG_PORT_STATS_EXT 0x10000000
- #define BNXT_FLAG_PCIE_STATS 0x40000000
#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \
BNXT_FLAG_RFS | \
@@ -1648,6 +1710,8 @@ struct bnxt {
struct bnxt_ring_grp_info *grp_info;
struct bnxt_vnic_info *vnic_info;
int nr_vnics;
+ u16 *rss_indir_tbl;
+ u16 rss_indir_tbl_entries;
u32 rss_hash_cfg;
u16 max_mtu;
@@ -1705,6 +1769,10 @@ struct bnxt {
#define BNXT_FW_CAP_ERR_RECOVER_RELOAD 0x00100000
#define BNXT_FW_CAP_HOT_RESET 0x00200000
#define BNXT_FW_CAP_SHARED_PORT_CFG 0x00400000
+ #define BNXT_FW_CAP_VLAN_RX_STRIP 0x01000000
+ #define BNXT_FW_CAP_VLAN_TX_INSERT 0x02000000
+ #define BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED 0x04000000
+ #define BNXT_FW_CAP_PORT_STATS_NO_RESET 0x10000000
#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
u32 hwrm_spec_code;
@@ -1719,17 +1787,9 @@ struct bnxt {
dma_addr_t hwrm_cmd_kong_resp_dma_addr;
struct rtnl_link_stats64 net_stats_prev;
- struct rx_port_stats *hw_rx_port_stats;
- struct tx_port_stats *hw_tx_port_stats;
- struct rx_port_stats_ext *hw_rx_port_stats_ext;
- struct tx_port_stats_ext *hw_tx_port_stats_ext;
- struct pcie_ctx_hw_stats *hw_pcie_stats;
- dma_addr_t hw_rx_port_stats_map;
- dma_addr_t hw_tx_port_stats_map;
- dma_addr_t hw_rx_port_stats_ext_map;
- dma_addr_t hw_tx_port_stats_ext_map;
- dma_addr_t hw_pcie_stats_map;
- int hw_port_stats_size;
+ struct bnxt_stats_mem port_stats;
+ struct bnxt_stats_mem rx_port_stats_ext;
+ struct bnxt_stats_mem tx_port_stats_ext;
u16 fw_rx_stats_ext_size;
u16 fw_tx_stats_ext_size;
u16 hw_ring_stats_size;
@@ -1751,12 +1811,8 @@ struct bnxt {
((u64)(maj) << 48 | (u64)(min) << 32 | (u64)(bld) << 16 | (rsv))
#define BNXT_FW_MAJ(bp) ((bp)->fw_ver_code >> 48)
- __be16 vxlan_port;
- u8 vxlan_port_cnt;
- __le16 vxlan_fw_dst_port_id;
- __be16 nge_port;
- u8 nge_port_cnt;
- __le16 nge_fw_dst_port_id;
+ u16 vxlan_fw_dst_port_id;
+ u16 nge_fw_dst_port_id;
u8 port_partition_type;
u8 port_count;
u16 br_mode;
@@ -1776,16 +1832,12 @@ struct bnxt {
#define BNXT_RX_NTP_FLTR_SP_EVENT 1
#define BNXT_LINK_CHNG_SP_EVENT 2
#define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT 3
-#define BNXT_VXLAN_ADD_PORT_SP_EVENT 4
-#define BNXT_VXLAN_DEL_PORT_SP_EVENT 5
#define BNXT_RESET_TASK_SP_EVENT 6
#define BNXT_RST_RING_SP_EVENT 7
#define BNXT_HWRM_PF_UNLOAD_SP_EVENT 8
#define BNXT_PERIODIC_STATS_SP_EVENT 9
#define BNXT_HWRM_PORT_MODULE_SP_EVENT 10
#define BNXT_RESET_TASK_SILENT_SP_EVENT 11
-#define BNXT_GENEVE_ADD_PORT_SP_EVENT 12
-#define BNXT_GENEVE_DEL_PORT_SP_EVENT 13
#define BNXT_LINK_SPEED_CHNG_SP_EVENT 14
#define BNXT_FLOW_STATS_SP_EVENT 15
#define BNXT_UPDATE_PHY_SP_EVENT 16
@@ -1879,12 +1931,27 @@ struct bnxt {
struct device *hwmon_dev;
};
+#define BNXT_GET_RING_STATS64(sw, counter) \
+ (*((sw) + offsetof(struct ctx_hw_stats, counter) / 8))
+
+#define BNXT_GET_RX_PORT_STATS64(sw, counter) \
+ (*((sw) + offsetof(struct rx_port_stats, counter) / 8))
+
+#define BNXT_GET_TX_PORT_STATS64(sw, counter) \
+ (*((sw) + offsetof(struct tx_port_stats, counter) / 8))
+
+#define BNXT_PORT_STATS_SIZE \
+ (sizeof(struct rx_port_stats) + sizeof(struct tx_port_stats) + 1024)
+
+#define BNXT_TX_PORT_STATS_BYTE_OFFSET \
+ (sizeof(struct rx_port_stats) + 512)
+
#define BNXT_RX_STATS_OFFSET(counter) \
(offsetof(struct rx_port_stats, counter) / 8)
#define BNXT_TX_STATS_OFFSET(counter) \
((offsetof(struct tx_port_stats, counter) + \
- sizeof(struct rx_port_stats) + 512) / 8)
+ BNXT_TX_PORT_STATS_BYTE_OFFSET) / 8)
#define BNXT_RX_STATS_EXT_OFFSET(counter) \
(offsetof(struct rx_port_stats_ext, counter) / 8)
@@ -1892,8 +1959,10 @@ struct bnxt {
#define BNXT_TX_STATS_EXT_OFFSET(counter) \
(offsetof(struct tx_port_stats_ext, counter) / 8)
-#define BNXT_PCIE_STATS_OFFSET(counter) \
- (offsetof(struct pcie_ctx_hw_stats, counter) / 8)
+#define BNXT_HW_FEATURE_VLAN_ALL_RX \
+ (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)
+#define BNXT_HW_FEATURE_VLAN_ALL_TX \
+ (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX)
#define I2C_DEV_ADDR_A0 0xa0
#define I2C_DEV_ADDR_A2 0xa2
@@ -2028,6 +2097,7 @@ int hwrm_send_message(struct bnxt *, void *, u32, int);
int hwrm_send_message_silent(struct bnxt *, void *, u32, int);
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
int bmap_size, bool async_only);
+int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
int bnxt_nq_rings_in_use(struct bnxt *bp);
@@ -2050,6 +2120,8 @@ int bnxt_open_nic(struct bnxt *, bool, bool);
int bnxt_half_open_nic(struct bnxt *bp);
void bnxt_half_close_nic(struct bnxt *bp);
int bnxt_close_nic(struct bnxt *, bool, bool);
+int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words,
+ u32 *reg_buf);
void bnxt_fw_exception(struct bnxt *bp);
void bnxt_fw_reset(struct bnxt *bp);
int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
index 02b27551d34d..8e90224c43a2 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
@@ -544,7 +544,7 @@ static int bnxt_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets)
static int bnxt_dcbnl_ieee_getpfc(struct net_device *dev, struct ieee_pfc *pfc)
{
struct bnxt *bp = netdev_priv(dev);
- __le64 *stats = (__le64 *)bp->hw_rx_port_stats;
+ __le64 *stats = bp->port_stats.hw_stats;
struct ieee_pfc *my_pfc = bp->ieee_pfc;
long rx_off, tx_off;
int i, rc;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
index a812beb46325..3a854195d5b0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
@@ -411,6 +411,12 @@ static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
return rc;
}
+ if (strlen(bp->board_serialno)) {
+ rc = devlink_info_board_serial_number_put(req, bp->board_serialno);
+ if (rc)
+ return rc;
+ }
+
sprintf(buf, "%X", bp->chip_num);
rc = devlink_info_version_fixed_put(req,
DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, buf);
@@ -685,6 +691,7 @@ static void bnxt_dl_params_unregister(struct bnxt *bp)
int bnxt_dl_register(struct bnxt *bp)
{
+ struct devlink_port_attrs attrs = {};
struct devlink *dl;
int rc;
@@ -713,9 +720,11 @@ int bnxt_dl_register(struct bnxt *bp)
if (!BNXT_PF(bp))
return 0;
- devlink_port_attrs_set(&bp->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- bp->pf.port_id, false, 0, bp->dsn,
- sizeof(bp->dsn));
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = bp->pf.port_id;
+ memcpy(attrs.switch_id.id, bp->dsn, sizeof(bp->dsn));
+ attrs.switch_id.id_len = sizeof(bp->dsn);
+ devlink_port_attrs_set(&bp->dl_port, &attrs);
rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id);
if (rc) {
netdev_err(bp->dev, "devlink_port_register failed\n");
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index b4aa56dc4f9f..64da654f1038 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -142,7 +142,7 @@ static const char * const bnxt_ring_rx_stats_str[] = {
"rx_mcast_packets",
"rx_bcast_packets",
"rx_discards",
- "rx_drops",
+ "rx_errors",
"rx_ucast_bytes",
"rx_mcast_bytes",
"rx_bcast_bytes",
@@ -152,8 +152,8 @@ static const char * const bnxt_ring_tx_stats_str[] = {
"tx_ucast_packets",
"tx_mcast_packets",
"tx_bcast_packets",
+ "tx_errors",
"tx_discards",
- "tx_drops",
"tx_ucast_bytes",
"tx_mcast_bytes",
"tx_bcast_bytes",
@@ -293,9 +293,6 @@ static const char * const bnxt_cmn_sw_stats_str[] = {
BNXT_TX_STATS_PRI_ENTRY(counter, 6), \
BNXT_TX_STATS_PRI_ENTRY(counter, 7)
-#define BNXT_PCIE_STATS_ENTRY(counter) \
- { BNXT_PCIE_STATS_OFFSET(counter), __stringify(counter) }
-
enum {
RX_TOTAL_DISCARDS,
TX_TOTAL_DISCARDS,
@@ -454,24 +451,6 @@ static const struct {
BNXT_TX_STATS_PRI_ENTRIES(tx_packets),
};
-static const struct {
- long offset;
- char string[ETH_GSTRING_LEN];
-} bnxt_pcie_stats_arr[] = {
- BNXT_PCIE_STATS_ENTRY(pcie_pl_signal_integrity),
- BNXT_PCIE_STATS_ENTRY(pcie_dl_signal_integrity),
- BNXT_PCIE_STATS_ENTRY(pcie_tl_signal_integrity),
- BNXT_PCIE_STATS_ENTRY(pcie_link_integrity),
- BNXT_PCIE_STATS_ENTRY(pcie_tx_traffic_rate),
- BNXT_PCIE_STATS_ENTRY(pcie_rx_traffic_rate),
- BNXT_PCIE_STATS_ENTRY(pcie_tx_dllp_statistics),
- BNXT_PCIE_STATS_ENTRY(pcie_rx_dllp_statistics),
- BNXT_PCIE_STATS_ENTRY(pcie_equalization_time),
- BNXT_PCIE_STATS_ENTRY(pcie_ltssm_histogram[0]),
- BNXT_PCIE_STATS_ENTRY(pcie_ltssm_histogram[2]),
- BNXT_PCIE_STATS_ENTRY(pcie_recovery_histogram),
-};
-
#define BNXT_NUM_SW_FUNC_STATS ARRAY_SIZE(bnxt_sw_func_stats)
#define BNXT_NUM_PORT_STATS ARRAY_SIZE(bnxt_port_stats_arr)
#define BNXT_NUM_STATS_PRI \
@@ -479,7 +458,6 @@ static const struct {
ARRAY_SIZE(bnxt_rx_pkts_pri_arr) + \
ARRAY_SIZE(bnxt_tx_bytes_pri_arr) + \
ARRAY_SIZE(bnxt_tx_pkts_pri_arr))
-#define BNXT_NUM_PCIE_STATS ARRAY_SIZE(bnxt_pcie_stats_arr)
static int bnxt_get_num_tpa_ring_stats(struct bnxt *bp)
{
@@ -526,9 +504,6 @@ static int bnxt_get_num_stats(struct bnxt *bp)
num_stats += BNXT_NUM_STATS_PRI;
}
- if (bp->flags & BNXT_FLAG_PCIE_STATS)
- num_stats += BNXT_NUM_PCIE_STATS;
-
return num_stats;
}
@@ -584,19 +559,19 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
for (i = 0; i < bp->cp_nr_rings; i++) {
struct bnxt_napi *bnapi = bp->bnapi[i];
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
- __le64 *hw_stats = (__le64 *)cpr->hw_stats;
+ u64 *sw_stats = cpr->stats.sw_stats;
u64 *sw;
int k;
if (is_rx_ring(bp, i)) {
for (k = 0; k < NUM_RING_RX_HW_STATS; j++, k++)
- buf[j] = le64_to_cpu(hw_stats[k]);
+ buf[j] = sw_stats[k];
}
if (is_tx_ring(bp, i)) {
k = NUM_RING_RX_HW_STATS;
for (; k < NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS;
j++, k++)
- buf[j] = le64_to_cpu(hw_stats[k]);
+ buf[j] = sw_stats[k];
}
if (!tpa_stats || !is_rx_ring(bp, i))
goto skip_tpa_ring_stats;
@@ -604,7 +579,7 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
k = NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS;
for (; k < NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS +
tpa_stats; j++, k++)
- buf[j] = le64_to_cpu(hw_stats[k]);
+ buf[j] = sw_stats[k];
skip_tpa_ring_stats:
sw = (u64 *)&cpr->sw_stats.rx;
@@ -618,9 +593,9 @@ skip_tpa_ring_stats:
buf[j] = sw[k];
bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter +=
- le64_to_cpu(cpr->hw_stats->rx_discard_pkts);
+ BNXT_GET_RING_STATS64(sw_stats, rx_discard_pkts);
bnxt_sw_func_stats[TX_TOTAL_DISCARDS].counter +=
- le64_to_cpu(cpr->hw_stats->tx_discard_pkts);
+ BNXT_GET_RING_STATS64(sw_stats, tx_discard_pkts);
}
for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++, j++)
@@ -628,60 +603,50 @@ skip_tpa_ring_stats:
skip_ring_stats:
if (bp->flags & BNXT_FLAG_PORT_STATS) {
- __le64 *port_stats = (__le64 *)bp->hw_rx_port_stats;
+ u64 *port_stats = bp->port_stats.sw_stats;
- for (i = 0; i < BNXT_NUM_PORT_STATS; i++, j++) {
- buf[j] = le64_to_cpu(*(port_stats +
- bnxt_port_stats_arr[i].offset));
- }
+ for (i = 0; i < BNXT_NUM_PORT_STATS; i++, j++)
+ buf[j] = *(port_stats + bnxt_port_stats_arr[i].offset);
}
if (bp->flags & BNXT_FLAG_PORT_STATS_EXT) {
- __le64 *rx_port_stats_ext = (__le64 *)bp->hw_rx_port_stats_ext;
- __le64 *tx_port_stats_ext = (__le64 *)bp->hw_tx_port_stats_ext;
+ u64 *rx_port_stats_ext = bp->rx_port_stats_ext.sw_stats;
+ u64 *tx_port_stats_ext = bp->tx_port_stats_ext.sw_stats;
for (i = 0; i < bp->fw_rx_stats_ext_size; i++, j++) {
- buf[j] = le64_to_cpu(*(rx_port_stats_ext +
- bnxt_port_stats_ext_arr[i].offset));
+ buf[j] = *(rx_port_stats_ext +
+ bnxt_port_stats_ext_arr[i].offset);
}
for (i = 0; i < bp->fw_tx_stats_ext_size; i++, j++) {
- buf[j] = le64_to_cpu(*(tx_port_stats_ext +
- bnxt_tx_port_stats_ext_arr[i].offset));
+ buf[j] = *(tx_port_stats_ext +
+ bnxt_tx_port_stats_ext_arr[i].offset);
}
if (bp->pri2cos_valid) {
for (i = 0; i < 8; i++, j++) {
long n = bnxt_rx_bytes_pri_arr[i].base_off +
bp->pri2cos_idx[i];
- buf[j] = le64_to_cpu(*(rx_port_stats_ext + n));
+ buf[j] = *(rx_port_stats_ext + n);
}
for (i = 0; i < 8; i++, j++) {
long n = bnxt_rx_pkts_pri_arr[i].base_off +
bp->pri2cos_idx[i];
- buf[j] = le64_to_cpu(*(rx_port_stats_ext + n));
+ buf[j] = *(rx_port_stats_ext + n);
}
for (i = 0; i < 8; i++, j++) {
long n = bnxt_tx_bytes_pri_arr[i].base_off +
bp->pri2cos_idx[i];
- buf[j] = le64_to_cpu(*(tx_port_stats_ext + n));
+ buf[j] = *(tx_port_stats_ext + n);
}
for (i = 0; i < 8; i++, j++) {
long n = bnxt_tx_pkts_pri_arr[i].base_off +
bp->pri2cos_idx[i];
- buf[j] = le64_to_cpu(*(tx_port_stats_ext + n));
+ buf[j] = *(tx_port_stats_ext + n);
}
}
}
- if (bp->flags & BNXT_FLAG_PCIE_STATS) {
- __le64 *pcie_stats = (__le64 *)bp->hw_pcie_stats;
-
- for (i = 0; i < BNXT_NUM_PCIE_STATS; i++, j++) {
- buf[j] = le64_to_cpu(*(pcie_stats +
- bnxt_pcie_stats_arr[i].offset));
- }
- }
}
static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
@@ -782,12 +747,6 @@ skip_tpa_stats:
}
}
}
- if (bp->flags & BNXT_FLAG_PCIE_STATS) {
- for (i = 0; i < BNXT_NUM_PCIE_STATS; i++) {
- strcpy(buf, bnxt_pcie_stats_arr[i].string);
- buf += ETH_GSTRING_LEN;
- }
- }
break;
case ETH_SS_TEST:
if (bp->num_tests)
@@ -926,6 +885,13 @@ static int bnxt_set_channels(struct net_device *dev,
return rc;
}
+ if (bnxt_get_nr_rss_ctxs(bp, req_rx_rings) !=
+ bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings) &&
+ (dev->priv_flags & IFF_RXFH_CONFIGURED)) {
+ netdev_warn(dev, "RSS table size change required, RSS table entries must be default to proceed\n");
+ return -EINVAL;
+ }
+
if (netif_running(dev)) {
if (BNXT_PF(bp)) {
/* TODO CHIMP_FW: Send message to all VF's
@@ -1273,8 +1239,12 @@ static int bnxt_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
return rc;
}
-static u32 bnxt_get_rxfh_indir_size(struct net_device *dev)
+u32 bnxt_get_rxfh_indir_size(struct net_device *dev)
{
+ struct bnxt *bp = netdev_priv(dev);
+
+ if (bp->flags & BNXT_FLAG_CHIP_P5)
+ return ALIGN(bp->rx_nr_rings, BNXT_RSS_TABLE_ENTRIES_P5);
return HW_HASH_INDEX_SIZE;
}
@@ -1288,7 +1258,7 @@ static int bnxt_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
{
struct bnxt *bp = netdev_priv(dev);
struct bnxt_vnic_info *vnic;
- int i = 0;
+ u32 i, tbl_size;
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
@@ -1297,9 +1267,10 @@ static int bnxt_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
return 0;
vnic = &bp->vnic_info[0];
- if (indir && vnic->rss_table) {
- for (i = 0; i < HW_HASH_INDEX_SIZE; i++)
- indir[i] = le16_to_cpu(vnic->rss_table[i]);
+ if (indir && bp->rss_indir_tbl) {
+ tbl_size = bnxt_get_rxfh_indir_size(dev);
+ for (i = 0; i < tbl_size; i++)
+ indir[i] = bp->rss_indir_tbl[i];
}
if (key && vnic->rss_hash_key)
@@ -1308,6 +1279,35 @@ static int bnxt_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
return 0;
}
+static int bnxt_set_rxfh(struct net_device *dev, const u32 *indir,
+ const u8 *key, const u8 hfunc)
+{
+ struct bnxt *bp = netdev_priv(dev);
+ int rc = 0;
+
+ if (hfunc && hfunc != ETH_RSS_HASH_TOP)
+ return -EOPNOTSUPP;
+
+ if (key)
+ return -EOPNOTSUPP;
+
+ if (indir) {
+ u32 i, pad, tbl_size = bnxt_get_rxfh_indir_size(dev);
+
+ for (i = 0; i < tbl_size; i++)
+ bp->rss_indir_tbl[i] = indir[i];
+ pad = bp->rss_indir_tbl_entries - tbl_size;
+ if (pad)
+ memset(&bp->rss_indir_tbl[i], 0, pad * sizeof(u16));
+ }
+
+ if (netif_running(bp->dev)) {
+ bnxt_close_nic(bp, false, false);
+ rc = bnxt_open_nic(bp, false, false);
+ }
+ return rc;
+}
+
static void bnxt_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
@@ -1324,6 +1324,59 @@ static void bnxt_get_drvinfo(struct net_device *dev,
info->regdump_len = 0;
}
+static int bnxt_get_regs_len(struct net_device *dev)
+{
+ struct bnxt *bp = netdev_priv(dev);
+ int reg_len;
+
+ reg_len = BNXT_PXP_REG_LEN;
+
+ if (bp->fw_cap & BNXT_FW_CAP_PCIE_STATS_SUPPORTED)
+ reg_len += sizeof(struct pcie_ctx_hw_stats);
+
+ return reg_len;
+}
+
+static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ void *_p)
+{
+ struct pcie_ctx_hw_stats *hw_pcie_stats;
+ struct hwrm_pcie_qstats_input req = {0};
+ struct bnxt *bp = netdev_priv(dev);
+ dma_addr_t hw_pcie_stats_addr;
+ int rc;
+
+ regs->version = 0;
+ bnxt_dbg_hwrm_rd_reg(bp, 0, BNXT_PXP_REG_LEN / 4, _p);
+
+ if (!(bp->fw_cap & BNXT_FW_CAP_PCIE_STATS_SUPPORTED))
+ return;
+
+ hw_pcie_stats = dma_alloc_coherent(&bp->pdev->dev,
+ sizeof(*hw_pcie_stats),
+ &hw_pcie_stats_addr, GFP_KERNEL);
+ if (!hw_pcie_stats)
+ return;
+
+ regs->version = 1;
+ bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PCIE_QSTATS, -1, -1);
+ req.pcie_stat_size = cpu_to_le16(sizeof(*hw_pcie_stats));
+ req.pcie_stat_host_addr = cpu_to_le64(hw_pcie_stats_addr);
+ mutex_lock(&bp->hwrm_cmd_lock);
+ rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+ if (!rc) {
+ __le64 *src = (__le64 *)hw_pcie_stats;
+ u64 *dst = (u64 *)(_p + BNXT_PXP_REG_LEN);
+ int i;
+
+ for (i = 0; i < sizeof(*hw_pcie_stats) / sizeof(__le64); i++)
+ dst[i] = le64_to_cpu(src[i]);
+ }
+ mutex_unlock(&bp->hwrm_cmd_lock);
+ dma_free_coherent(&bp->pdev->dev, sizeof(*hw_pcie_stats), hw_pcie_stats,
+ hw_pcie_stats_addr);
+}
+
static void bnxt_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct bnxt *bp = netdev_priv(dev);
@@ -3599,6 +3652,8 @@ const struct ethtool_ops bnxt_ethtool_ops = {
.get_pauseparam = bnxt_get_pauseparam,
.set_pauseparam = bnxt_set_pauseparam,
.get_drvinfo = bnxt_get_drvinfo,
+ .get_regs_len = bnxt_get_regs_len,
+ .get_regs = bnxt_get_regs,
.get_wol = bnxt_get_wol,
.set_wol = bnxt_set_wol,
.get_coalesce = bnxt_get_coalesce,
@@ -3617,6 +3672,7 @@ const struct ethtool_ops bnxt_ethtool_ops = {
.get_rxfh_indir_size = bnxt_get_rxfh_indir_size,
.get_rxfh_key_size = bnxt_get_rxfh_key_size,
.get_rxfh = bnxt_get_rxfh,
+ .set_rxfh = bnxt_set_rxfh,
.flash_device = bnxt_flash_device,
.get_eeprom_len = bnxt_get_eeprom_len,
.get_eeprom = bnxt_get_eeprom,
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h
index ce7585ff9e4d..34f44ddfad79 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h
@@ -84,8 +84,11 @@ struct hwrm_dbg_cmn_output {
ETH_RESET_PHY | ETH_RESET_RAM) \
<< ETH_RESET_SHARED_SHIFT)
+#define BNXT_PXP_REG_LEN 0x3110
+
extern const struct ethtool_ops bnxt_ethtool_ops;
+u32 bnxt_get_rxfh_indir_size(struct net_device *dev);
u32 _bnxt_fw_to_ethtool_adv_spds(u16, u8);
u32 bnxt_fw_to_ethtool_speed(u16);
u16 bnxt_get_fw_auto_link_speeds(u32);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h
index 7e9235c8d21e..c4af6bf15e36 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h
@@ -169,9 +169,14 @@ struct cmd_nums {
#define HWRM_RING_CMPL_RING_QAGGINT_PARAMS 0x52UL
#define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS 0x53UL
#define HWRM_RING_AGGINT_QCAPS 0x54UL
+ #define HWRM_RING_SCHQ_ALLOC 0x55UL
+ #define HWRM_RING_SCHQ_CFG 0x56UL
+ #define HWRM_RING_SCHQ_FREE 0x57UL
#define HWRM_RING_RESET 0x5eUL
#define HWRM_RING_GRP_ALLOC 0x60UL
#define HWRM_RING_GRP_FREE 0x61UL
+ #define HWRM_RING_CFG 0x62UL
+ #define HWRM_RING_QCFG 0x63UL
#define HWRM_RESERVED5 0x64UL
#define HWRM_RESERVED6 0x65UL
#define HWRM_VNIC_RSS_COS_LB_CTX_ALLOC 0x70UL
@@ -224,6 +229,7 @@ struct cmd_nums {
#define HWRM_FW_IPC_MAILBOX 0xccUL
#define HWRM_FW_ECN_CFG 0xcdUL
#define HWRM_FW_ECN_QCFG 0xceUL
+ #define HWRM_FW_SECURE_CFG 0xcfUL
#define HWRM_EXEC_FWD_RESP 0xd0UL
#define HWRM_REJECT_FWD_RESP 0xd1UL
#define HWRM_FWD_RESP 0xd2UL
@@ -337,6 +343,7 @@ struct cmd_nums {
#define HWRM_FUNC_VF_BW_QCFG 0x196UL
#define HWRM_FUNC_HOST_PF_IDS_QUERY 0x197UL
#define HWRM_FUNC_QSTATS_EXT 0x198UL
+ #define HWRM_STAT_EXT_CTX_QUERY 0x199UL
#define HWRM_SELFTEST_QLIST 0x200UL
#define HWRM_SELFTEST_EXEC 0x201UL
#define HWRM_SELFTEST_IRQ 0x202UL
@@ -353,24 +360,30 @@ struct cmd_nums {
#define HWRM_TF_VERSION_GET 0x2bdUL
#define HWRM_TF_SESSION_OPEN 0x2c6UL
#define HWRM_TF_SESSION_ATTACH 0x2c7UL
- #define HWRM_TF_SESSION_CLOSE 0x2c8UL
- #define HWRM_TF_SESSION_QCFG 0x2c9UL
- #define HWRM_TF_SESSION_RESC_QCAPS 0x2caUL
- #define HWRM_TF_SESSION_RESC_ALLOC 0x2cbUL
- #define HWRM_TF_SESSION_RESC_FREE 0x2ccUL
- #define HWRM_TF_SESSION_RESC_FLUSH 0x2cdUL
- #define HWRM_TF_TBL_TYPE_GET 0x2d0UL
- #define HWRM_TF_TBL_TYPE_SET 0x2d1UL
- #define HWRM_TF_CTXT_MEM_RGTR 0x2daUL
- #define HWRM_TF_CTXT_MEM_UNRGTR 0x2dbUL
- #define HWRM_TF_EXT_EM_QCAPS 0x2dcUL
- #define HWRM_TF_EXT_EM_OP 0x2ddUL
- #define HWRM_TF_EXT_EM_CFG 0x2deUL
- #define HWRM_TF_EXT_EM_QCFG 0x2dfUL
- #define HWRM_TF_TCAM_SET 0x2eeUL
- #define HWRM_TF_TCAM_GET 0x2efUL
- #define HWRM_TF_TCAM_MOVE 0x2f0UL
- #define HWRM_TF_TCAM_FREE 0x2f1UL
+ #define HWRM_TF_SESSION_REGISTER 0x2c8UL
+ #define HWRM_TF_SESSION_UNREGISTER 0x2c9UL
+ #define HWRM_TF_SESSION_CLOSE 0x2caUL
+ #define HWRM_TF_SESSION_QCFG 0x2cbUL
+ #define HWRM_TF_SESSION_RESC_QCAPS 0x2ccUL
+ #define HWRM_TF_SESSION_RESC_ALLOC 0x2cdUL
+ #define HWRM_TF_SESSION_RESC_FREE 0x2ceUL
+ #define HWRM_TF_SESSION_RESC_FLUSH 0x2cfUL
+ #define HWRM_TF_TBL_TYPE_GET 0x2daUL
+ #define HWRM_TF_TBL_TYPE_SET 0x2dbUL
+ #define HWRM_TF_CTXT_MEM_RGTR 0x2e4UL
+ #define HWRM_TF_CTXT_MEM_UNRGTR 0x2e5UL
+ #define HWRM_TF_EXT_EM_QCAPS 0x2e6UL
+ #define HWRM_TF_EXT_EM_OP 0x2e7UL
+ #define HWRM_TF_EXT_EM_CFG 0x2e8UL
+ #define HWRM_TF_EXT_EM_QCFG 0x2e9UL
+ #define HWRM_TF_EM_INSERT 0x2eaUL
+ #define HWRM_TF_EM_DELETE 0x2ebUL
+ #define HWRM_TF_TCAM_SET 0x2f8UL
+ #define HWRM_TF_TCAM_GET 0x2f9UL
+ #define HWRM_TF_TCAM_MOVE 0x2faUL
+ #define HWRM_TF_TCAM_FREE 0x2fbUL
+ #define HWRM_TF_GLOBAL_CFG_SET 0x2fcUL
+ #define HWRM_TF_GLOBAL_CFG_GET 0x2fdUL
#define HWRM_SV 0x400UL
#define HWRM_DBG_READ_DIRECT 0xff10UL
#define HWRM_DBG_READ_INDIRECT 0xff11UL
@@ -391,6 +404,7 @@ struct cmd_nums {
#define HWRM_DBG_QCAPS 0xff20UL
#define HWRM_DBG_QCFG 0xff21UL
#define HWRM_DBG_CRASHDUMP_MEDIUM_CFG 0xff22UL
+ #define HWRM_NVM_REQ_ARBITRATION 0xffedUL
#define HWRM_NVM_FACTORY_DEFAULTS 0xffeeUL
#define HWRM_NVM_VALIDATE_OPTION 0xffefUL
#define HWRM_NVM_FLUSH 0xfff0UL
@@ -464,8 +478,8 @@ struct hwrm_err_output {
#define HWRM_VERSION_MAJOR 1
#define HWRM_VERSION_MINOR 10
#define HWRM_VERSION_UPDATE 1
-#define HWRM_VERSION_RSVD 33
-#define HWRM_VERSION_STR "1.10.1.33"
+#define HWRM_VERSION_RSVD 54
+#define HWRM_VERSION_STR "1.10.1.54"
/* hwrm_ver_get_input (size:192b/24B) */
struct hwrm_ver_get_input {
@@ -1094,6 +1108,8 @@ struct hwrm_func_vf_cfg_input {
#define FUNC_VF_CFG_REQ_FLAGS_STAT_CTX_ASSETS_TEST 0x20UL
#define FUNC_VF_CFG_REQ_FLAGS_VNIC_ASSETS_TEST 0x40UL
#define FUNC_VF_CFG_REQ_FLAGS_L2_CTX_ASSETS_TEST 0x80UL
+ #define FUNC_VF_CFG_REQ_FLAGS_PPP_PUSH_MODE_ENABLE 0x100UL
+ #define FUNC_VF_CFG_REQ_FLAGS_PPP_PUSH_MODE_DISABLE 0x200UL
__le16 num_rsscos_ctxs;
__le16 num_cmpl_rings;
__le16 num_tx_rings;
@@ -1189,10 +1205,16 @@ struct hwrm_func_qcaps_output {
__le16 max_sp_tx_rings;
u8 unused_0[2];
__le32 flags_ext;
- #define FUNC_QCAPS_RESP_FLAGS_EXT_ECN_MARK_SUPPORTED 0x1UL
- #define FUNC_QCAPS_RESP_FLAGS_EXT_ECN_STATS_SUPPORTED 0x2UL
- #define FUNC_QCAPS_RESP_FLAGS_EXT_EXT_HW_STATS_SUPPORTED 0x4UL
- u8 unused_1[3];
+ #define FUNC_QCAPS_RESP_FLAGS_EXT_ECN_MARK_SUPPORTED 0x1UL
+ #define FUNC_QCAPS_RESP_FLAGS_EXT_ECN_STATS_SUPPORTED 0x2UL
+ #define FUNC_QCAPS_RESP_FLAGS_EXT_EXT_HW_STATS_SUPPORTED 0x4UL
+ #define FUNC_QCAPS_RESP_FLAGS_EXT_HOT_RESET_IF_SUPPORT 0x8UL
+ #define FUNC_QCAPS_RESP_FLAGS_EXT_PROXY_MODE_SUPPORT 0x10UL
+ #define FUNC_QCAPS_RESP_FLAGS_EXT_TX_PROXY_SRC_INTF_OVERRIDE_SUPPORT 0x20UL
+ #define FUNC_QCAPS_RESP_FLAGS_EXT_SCHQ_SUPPORTED 0x40UL
+ #define FUNC_QCAPS_RESP_FLAGS_EXT_PPP_PUSH_MODE_SUPPORTED 0x80UL
+ u8 max_schqs;
+ u8 unused_1[2];
u8 valid;
};
@@ -1226,6 +1248,8 @@ struct hwrm_func_qcfg_output {
#define FUNC_QCFG_RESP_FLAGS_TRUSTED_VF 0x40UL
#define FUNC_QCFG_RESP_FLAGS_SECURE_MODE_ENABLED 0x80UL
#define FUNC_QCFG_RESP_FLAGS_PREBOOT_LEGACY_L2_RINGS 0x100UL
+ #define FUNC_QCFG_RESP_FLAGS_HOT_RESET_ALLOWED 0x200UL
+ #define FUNC_QCFG_RESP_FLAGS_PPP_PUSH_MODE_ENABLED 0x400UL
u8 mac_address[6];
__le16 pci_id;
__le16 alloc_rsscos_ctx;
@@ -1321,7 +1345,7 @@ struct hwrm_func_qcfg_output {
u8 valid;
};
-/* hwrm_func_cfg_input (size:704b/88B) */
+/* hwrm_func_cfg_input (size:768b/96B) */
struct hwrm_func_cfg_input {
__le16 req_type;
__le16 cmpl_ring;
@@ -1352,30 +1376,35 @@ struct hwrm_func_cfg_input {
#define FUNC_CFG_REQ_FLAGS_NQ_ASSETS_TEST 0x800000UL
#define FUNC_CFG_REQ_FLAGS_TRUSTED_VF_DISABLE 0x1000000UL
#define FUNC_CFG_REQ_FLAGS_PREBOOT_LEGACY_L2_RINGS 0x2000000UL
+ #define FUNC_CFG_REQ_FLAGS_HOT_RESET_IF_EN_DIS 0x4000000UL
+ #define FUNC_CFG_REQ_FLAGS_PPP_PUSH_MODE_ENABLE 0x8000000UL
+ #define FUNC_CFG_REQ_FLAGS_PPP_PUSH_MODE_DISABLE 0x10000000UL
__le32 enables;
- #define FUNC_CFG_REQ_ENABLES_MTU 0x1UL
- #define FUNC_CFG_REQ_ENABLES_MRU 0x2UL
- #define FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS 0x4UL
- #define FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS 0x8UL
- #define FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS 0x10UL
- #define FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS 0x20UL
- #define FUNC_CFG_REQ_ENABLES_NUM_L2_CTXS 0x40UL
- #define FUNC_CFG_REQ_ENABLES_NUM_VNICS 0x80UL
- #define FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS 0x100UL
- #define FUNC_CFG_REQ_ENABLES_DFLT_MAC_ADDR 0x200UL
- #define FUNC_CFG_REQ_ENABLES_DFLT_VLAN 0x400UL
- #define FUNC_CFG_REQ_ENABLES_DFLT_IP_ADDR 0x800UL
- #define FUNC_CFG_REQ_ENABLES_MIN_BW 0x1000UL
- #define FUNC_CFG_REQ_ENABLES_MAX_BW 0x2000UL
- #define FUNC_CFG_REQ_ENABLES_ASYNC_EVENT_CR 0x4000UL
- #define FUNC_CFG_REQ_ENABLES_VLAN_ANTISPOOF_MODE 0x8000UL
- #define FUNC_CFG_REQ_ENABLES_ALLOWED_VLAN_PRIS 0x10000UL
- #define FUNC_CFG_REQ_ENABLES_EVB_MODE 0x20000UL
- #define FUNC_CFG_REQ_ENABLES_NUM_MCAST_FILTERS 0x40000UL
- #define FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS 0x80000UL
- #define FUNC_CFG_REQ_ENABLES_CACHE_LINESIZE 0x100000UL
- #define FUNC_CFG_REQ_ENABLES_NUM_MSIX 0x200000UL
- #define FUNC_CFG_REQ_ENABLES_ADMIN_LINK_STATE 0x400000UL
+ #define FUNC_CFG_REQ_ENABLES_MTU 0x1UL
+ #define FUNC_CFG_REQ_ENABLES_MRU 0x2UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS 0x4UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS 0x8UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS 0x10UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS 0x20UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_L2_CTXS 0x40UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_VNICS 0x80UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS 0x100UL
+ #define FUNC_CFG_REQ_ENABLES_DFLT_MAC_ADDR 0x200UL
+ #define FUNC_CFG_REQ_ENABLES_DFLT_VLAN 0x400UL
+ #define FUNC_CFG_REQ_ENABLES_DFLT_IP_ADDR 0x800UL
+ #define FUNC_CFG_REQ_ENABLES_MIN_BW 0x1000UL
+ #define FUNC_CFG_REQ_ENABLES_MAX_BW 0x2000UL
+ #define FUNC_CFG_REQ_ENABLES_ASYNC_EVENT_CR 0x4000UL
+ #define FUNC_CFG_REQ_ENABLES_VLAN_ANTISPOOF_MODE 0x8000UL
+ #define FUNC_CFG_REQ_ENABLES_ALLOWED_VLAN_PRIS 0x10000UL
+ #define FUNC_CFG_REQ_ENABLES_EVB_MODE 0x20000UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_MCAST_FILTERS 0x40000UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS 0x80000UL
+ #define FUNC_CFG_REQ_ENABLES_CACHE_LINESIZE 0x100000UL
+ #define FUNC_CFG_REQ_ENABLES_NUM_MSIX 0x200000UL
+ #define FUNC_CFG_REQ_ENABLES_ADMIN_LINK_STATE 0x400000UL
+ #define FUNC_CFG_REQ_ENABLES_HOT_RESET_IF_SUPPORT 0x800000UL
+ #define FUNC_CFG_REQ_ENABLES_SCHQ_ID 0x1000000UL
__le16 mtu;
__le16 mru;
__le16 num_rsscos_ctxs;
@@ -1449,6 +1478,8 @@ struct hwrm_func_cfg_input {
#define FUNC_CFG_REQ_OPTIONS_RSVD_MASK 0xf0UL
#define FUNC_CFG_REQ_OPTIONS_RSVD_SFT 4
__le16 num_mcast_filters;
+ __le16 schq_id;
+ u8 unused_0[6];
};
/* hwrm_func_cfg_output (size:128b/16B) */
@@ -1507,7 +1538,7 @@ struct hwrm_func_qstats_output {
u8 valid;
};
-/* hwrm_func_qstats_ext_input (size:192b/24B) */
+/* hwrm_func_qstats_ext_input (size:256b/32B) */
struct hwrm_func_qstats_ext_input {
__le16 req_type;
__le16 cmpl_ring;
@@ -1520,7 +1551,12 @@ struct hwrm_func_qstats_ext_input {
#define FUNC_QSTATS_EXT_REQ_FLAGS_ROCE_ONLY 0x1UL
#define FUNC_QSTATS_EXT_REQ_FLAGS_COUNTER_MASK 0x2UL
#define FUNC_QSTATS_EXT_REQ_FLAGS_LAST FUNC_QSTATS_EXT_REQ_FLAGS_COUNTER_MASK
- u8 unused_0[5];
+ u8 unused_0[1];
+ __le32 enables;
+ #define FUNC_QSTATS_EXT_REQ_ENABLES_SCHQ_ID 0x1UL
+ __le16 schq_id;
+ __le16 traffic_class;
+ u8 unused_1[4];
};
/* hwrm_func_qstats_ext_output (size:1472b/184B) */
@@ -1533,15 +1569,15 @@ struct hwrm_func_qstats_ext_output {
__le64 rx_mcast_pkts;
__le64 rx_bcast_pkts;
__le64 rx_discard_pkts;
- __le64 rx_drop_pkts;
+ __le64 rx_error_pkts;
__le64 rx_ucast_bytes;
__le64 rx_mcast_bytes;
__le64 rx_bcast_bytes;
__le64 tx_ucast_pkts;
__le64 tx_mcast_pkts;
__le64 tx_bcast_pkts;
+ __le64 tx_error_pkts;
__le64 tx_discard_pkts;
- __le64 tx_drop_pkts;
__le64 tx_ucast_bytes;
__le64 tx_mcast_bytes;
__le64 tx_bcast_bytes;
@@ -2376,33 +2412,39 @@ struct hwrm_port_phy_cfg_input {
__le16 target_id;
__le64 resp_addr;
__le32 flags;
- #define PORT_PHY_CFG_REQ_FLAGS_RESET_PHY 0x1UL
- #define PORT_PHY_CFG_REQ_FLAGS_DEPRECATED 0x2UL
- #define PORT_PHY_CFG_REQ_FLAGS_FORCE 0x4UL
- #define PORT_PHY_CFG_REQ_FLAGS_RESTART_AUTONEG 0x8UL
- #define PORT_PHY_CFG_REQ_FLAGS_EEE_ENABLE 0x10UL
- #define PORT_PHY_CFG_REQ_FLAGS_EEE_DISABLE 0x20UL
- #define PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_ENABLE 0x40UL
- #define PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_DISABLE 0x80UL
- #define PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_ENABLE 0x100UL
- #define PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE 0x200UL
- #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_ENABLE 0x400UL
- #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE 0x800UL
- #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_ENABLE 0x1000UL
- #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_DISABLE 0x2000UL
- #define PORT_PHY_CFG_REQ_FLAGS_FORCE_LINK_DWN 0x4000UL
+ #define PORT_PHY_CFG_REQ_FLAGS_RESET_PHY 0x1UL
+ #define PORT_PHY_CFG_REQ_FLAGS_DEPRECATED 0x2UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FORCE 0x4UL
+ #define PORT_PHY_CFG_REQ_FLAGS_RESTART_AUTONEG 0x8UL
+ #define PORT_PHY_CFG_REQ_FLAGS_EEE_ENABLE 0x10UL
+ #define PORT_PHY_CFG_REQ_FLAGS_EEE_DISABLE 0x20UL
+ #define PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_ENABLE 0x40UL
+ #define PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_DISABLE 0x80UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_ENABLE 0x100UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE 0x200UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_ENABLE 0x400UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE 0x800UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_ENABLE 0x1000UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_DISABLE 0x2000UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FORCE_LINK_DWN 0x4000UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_ENABLE 0x8000UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_DISABLE 0x10000UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_2XN_ENABLE 0x20000UL
+ #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_2XN_DISABLE 0x40000UL
__le32 enables;
- #define PORT_PHY_CFG_REQ_ENABLES_AUTO_MODE 0x1UL
- #define PORT_PHY_CFG_REQ_ENABLES_AUTO_DUPLEX 0x2UL
- #define PORT_PHY_CFG_REQ_ENABLES_AUTO_PAUSE 0x4UL
- #define PORT_PHY_CFG_REQ_ENABLES_AUTO_LINK_SPEED 0x8UL
- #define PORT_PHY_CFG_REQ_ENABLES_AUTO_LINK_SPEED_MASK 0x10UL
- #define PORT_PHY_CFG_REQ_ENABLES_WIRESPEED 0x20UL
- #define PORT_PHY_CFG_REQ_ENABLES_LPBK 0x40UL
- #define PORT_PHY_CFG_REQ_ENABLES_PREEMPHASIS 0x80UL
- #define PORT_PHY_CFG_REQ_ENABLES_FORCE_PAUSE 0x100UL
- #define PORT_PHY_CFG_REQ_ENABLES_EEE_LINK_SPEED_MASK 0x200UL
- #define PORT_PHY_CFG_REQ_ENABLES_TX_LPI_TIMER 0x400UL
+ #define PORT_PHY_CFG_REQ_ENABLES_AUTO_MODE 0x1UL
+ #define PORT_PHY_CFG_REQ_ENABLES_AUTO_DUPLEX 0x2UL
+ #define PORT_PHY_CFG_REQ_ENABLES_AUTO_PAUSE 0x4UL
+ #define PORT_PHY_CFG_REQ_ENABLES_AUTO_LINK_SPEED 0x8UL
+ #define PORT_PHY_CFG_REQ_ENABLES_AUTO_LINK_SPEED_MASK 0x10UL
+ #define PORT_PHY_CFG_REQ_ENABLES_WIRESPEED 0x20UL
+ #define PORT_PHY_CFG_REQ_ENABLES_LPBK 0x40UL
+ #define PORT_PHY_CFG_REQ_ENABLES_PREEMPHASIS 0x80UL
+ #define PORT_PHY_CFG_REQ_ENABLES_FORCE_PAUSE 0x100UL
+ #define PORT_PHY_CFG_REQ_ENABLES_EEE_LINK_SPEED_MASK 0x200UL
+ #define PORT_PHY_CFG_REQ_ENABLES_TX_LPI_TIMER 0x400UL
+ #define PORT_PHY_CFG_REQ_ENABLES_FORCE_PAM4_LINK_SPEED 0x800UL
+ #define PORT_PHY_CFG_REQ_ENABLES_AUTO_PAM4_LINK_SPEED_MASK 0x1000UL
__le16 port_id;
__le16 force_link_speed;
#define PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100MB 0x1UL
@@ -2415,7 +2457,6 @@ struct hwrm_port_phy_cfg_input {
#define PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_40GB 0x190UL
#define PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_50GB 0x1f4UL
#define PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100GB 0x3e8UL
- #define PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_200GB 0x7d0UL
#define PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_10MB 0xffffUL
#define PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_LAST PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_10MB
u8 auto_mode;
@@ -2446,7 +2487,6 @@ struct hwrm_port_phy_cfg_input {
#define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_40GB 0x190UL
#define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_50GB 0x1f4UL
#define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_100GB 0x3e8UL
- #define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_200GB 0x7d0UL
#define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_10MB 0xffffUL
#define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_LAST PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_10MB
__le16 auto_link_speed_mask;
@@ -2464,7 +2504,6 @@ struct hwrm_port_phy_cfg_input {
#define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_MASK_100GB 0x800UL
#define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_MASK_10MBHD 0x1000UL
#define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_MASK_10MB 0x2000UL
- #define PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_MASK_200GB 0x4000UL
u8 wirespeed;
#define PORT_PHY_CFG_REQ_WIRESPEED_OFF 0x0UL
#define PORT_PHY_CFG_REQ_WIRESPEED_ON 0x1UL
@@ -2488,11 +2527,19 @@ struct hwrm_port_phy_cfg_input {
#define PORT_PHY_CFG_REQ_EEE_LINK_SPEED_MASK_RSVD3 0x10UL
#define PORT_PHY_CFG_REQ_EEE_LINK_SPEED_MASK_RSVD4 0x20UL
#define PORT_PHY_CFG_REQ_EEE_LINK_SPEED_MASK_10GB 0x40UL
- u8 unused_2[2];
+ __le16 force_pam4_link_speed;
+ #define PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_50GB 0x1f4UL
+ #define PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_100GB 0x3e8UL
+ #define PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_200GB 0x7d0UL
+ #define PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_LAST PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_200GB
__le32 tx_lpi_timer;
#define PORT_PHY_CFG_REQ_TX_LPI_TIMER_MASK 0xffffffUL
#define PORT_PHY_CFG_REQ_TX_LPI_TIMER_SFT 0
- __le32 unused_3;
+ __le16 auto_link_pam4_speed_mask;
+ #define PORT_PHY_CFG_REQ_AUTO_LINK_PAM4_SPEED_MASK_50G 0x1UL
+ #define PORT_PHY_CFG_REQ_AUTO_LINK_PAM4_SPEED_MASK_100G 0x2UL
+ #define PORT_PHY_CFG_REQ_AUTO_LINK_PAM4_SPEED_MASK_200G 0x4UL
+ u8 unused_2[2];
};
/* hwrm_port_phy_cfg_output (size:128b/16B) */
@@ -2526,7 +2573,7 @@ struct hwrm_port_phy_qcfg_input {
u8 unused_0[6];
};
-/* hwrm_port_phy_qcfg_output (size:768b/96B) */
+/* hwrm_port_phy_qcfg_output (size:832b/104B) */
struct hwrm_port_phy_qcfg_output {
__le16 error_code;
__le16 req_type;
@@ -2537,7 +2584,10 @@ struct hwrm_port_phy_qcfg_output {
#define PORT_PHY_QCFG_RESP_LINK_SIGNAL 0x1UL
#define PORT_PHY_QCFG_RESP_LINK_LINK 0x2UL
#define PORT_PHY_QCFG_RESP_LINK_LAST PORT_PHY_QCFG_RESP_LINK_LINK
- u8 unused_0;
+ u8 link_signal_mode;
+ #define PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_NRZ 0x0UL
+ #define PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_PAM4 0x1UL
+ #define PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_LAST PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_PAM4
__le16 link_speed;
#define PORT_PHY_QCFG_RESP_LINK_SPEED_100MB 0x1UL
#define PORT_PHY_QCFG_RESP_LINK_SPEED_1GB 0xaUL
@@ -2574,7 +2624,6 @@ struct hwrm_port_phy_qcfg_output {
#define PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_100GB 0x800UL
#define PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_10MBHD 0x1000UL
#define PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_10MB 0x2000UL
- #define PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_200GB 0x4000UL
__le16 force_link_speed;
#define PORT_PHY_QCFG_RESP_FORCE_LINK_SPEED_100MB 0x1UL
#define PORT_PHY_QCFG_RESP_FORCE_LINK_SPEED_1GB 0xaUL
@@ -2586,7 +2635,6 @@ struct hwrm_port_phy_qcfg_output {
#define PORT_PHY_QCFG_RESP_FORCE_LINK_SPEED_40GB 0x190UL
#define PORT_PHY_QCFG_RESP_FORCE_LINK_SPEED_50GB 0x1f4UL
#define PORT_PHY_QCFG_RESP_FORCE_LINK_SPEED_100GB 0x3e8UL
- #define PORT_PHY_QCFG_RESP_FORCE_LINK_SPEED_200GB 0x7d0UL
#define PORT_PHY_QCFG_RESP_FORCE_LINK_SPEED_10MB 0xffffUL
#define PORT_PHY_QCFG_RESP_FORCE_LINK_SPEED_LAST PORT_PHY_QCFG_RESP_FORCE_LINK_SPEED_10MB
u8 auto_mode;
@@ -2611,7 +2659,6 @@ struct hwrm_port_phy_qcfg_output {
#define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_40GB 0x190UL
#define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_50GB 0x1f4UL
#define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_100GB 0x3e8UL
- #define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_200GB 0x7d0UL
#define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_10MB 0xffffUL
#define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_LAST PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_10MB
__le16 auto_link_speed_mask;
@@ -2629,7 +2676,6 @@ struct hwrm_port_phy_qcfg_output {
#define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_MASK_100GB 0x800UL
#define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_MASK_10MBHD 0x1000UL
#define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_MASK_10MB 0x2000UL
- #define PORT_PHY_QCFG_RESP_AUTO_LINK_SPEED_MASK_200GB 0x4000UL
u8 wirespeed;
#define PORT_PHY_QCFG_RESP_WIRESPEED_OFF 0x0UL
#define PORT_PHY_QCFG_RESP_WIRESPEED_ON 0x1UL
@@ -2763,13 +2809,21 @@ struct hwrm_port_phy_qcfg_output {
#define PORT_PHY_QCFG_RESP_XCVR_IDENTIFIER_TYPE_QSFP28 (0x11UL << 24)
#define PORT_PHY_QCFG_RESP_XCVR_IDENTIFIER_TYPE_LAST PORT_PHY_QCFG_RESP_XCVR_IDENTIFIER_TYPE_QSFP28
__le16 fec_cfg;
- #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED 0x1UL
- #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_SUPPORTED 0x2UL
- #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_ENABLED 0x4UL
- #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_SUPPORTED 0x8UL
- #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_ENABLED 0x10UL
- #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_SUPPORTED 0x20UL
- #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ENABLED 0x40UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED 0x1UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_SUPPORTED 0x2UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_ENABLED 0x4UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_SUPPORTED 0x8UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_ENABLED 0x10UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_SUPPORTED 0x20UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ENABLED 0x40UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_SUPPORTED 0x80UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_ENABLED 0x100UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_2XN_SUPPORTED 0x200UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_2XN_ENABLED 0x400UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_ACTIVE 0x800UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ACTIVE 0x1000UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_ACTIVE 0x2000UL
+ #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_2XN_ACTIVE 0x4000UL
u8 duplex_state;
#define PORT_PHY_QCFG_RESP_DUPLEX_STATE_HALF 0x0UL
#define PORT_PHY_QCFG_RESP_DUPLEX_STATE_FULL 0x1UL
@@ -2778,7 +2832,24 @@ struct hwrm_port_phy_qcfg_output {
#define PORT_PHY_QCFG_RESP_OPTION_FLAGS_MEDIA_AUTO_DETECT 0x1UL
char phy_vendor_name[16];
char phy_vendor_partnumber[16];
- u8 unused_2[7];
+ __le16 support_pam4_speeds;
+ #define PORT_PHY_QCFG_RESP_SUPPORT_PAM4_SPEEDS_50G 0x1UL
+ #define PORT_PHY_QCFG_RESP_SUPPORT_PAM4_SPEEDS_100G 0x2UL
+ #define PORT_PHY_QCFG_RESP_SUPPORT_PAM4_SPEEDS_200G 0x4UL
+ __le16 force_pam4_link_speed;
+ #define PORT_PHY_QCFG_RESP_FORCE_PAM4_LINK_SPEED_50GB 0x1f4UL
+ #define PORT_PHY_QCFG_RESP_FORCE_PAM4_LINK_SPEED_100GB 0x3e8UL
+ #define PORT_PHY_QCFG_RESP_FORCE_PAM4_LINK_SPEED_200GB 0x7d0UL
+ #define PORT_PHY_QCFG_RESP_FORCE_PAM4_LINK_SPEED_LAST PORT_PHY_QCFG_RESP_FORCE_PAM4_LINK_SPEED_200GB
+ __le16 auto_pam4_link_speed_mask;
+ #define PORT_PHY_QCFG_RESP_AUTO_PAM4_LINK_SPEED_MASK_50G 0x1UL
+ #define PORT_PHY_QCFG_RESP_AUTO_PAM4_LINK_SPEED_MASK_100G 0x2UL
+ #define PORT_PHY_QCFG_RESP_AUTO_PAM4_LINK_SPEED_MASK_200G 0x4UL
+ __le16 link_partner_pam4_adv_speeds;
+ #define PORT_PHY_QCFG_RESP_LINK_PARTNER_PAM4_ADV_SPEEDS_50GB 0x1UL
+ #define PORT_PHY_QCFG_RESP_LINK_PARTNER_PAM4_ADV_SPEEDS_100GB 0x2UL
+ #define PORT_PHY_QCFG_RESP_LINK_PARTNER_PAM4_ADV_SPEEDS_200GB 0x4UL
+ u8 unused_0[7];
u8 valid;
};
@@ -3304,19 +3375,20 @@ struct hwrm_port_phy_qcaps_input {
u8 unused_0[6];
};
-/* hwrm_port_phy_qcaps_output (size:192b/24B) */
+/* hwrm_port_phy_qcaps_output (size:256b/32B) */
struct hwrm_port_phy_qcaps_output {
__le16 error_code;
__le16 req_type;
__le16 seq_id;
__le16 resp_len;
u8 flags;
- #define PORT_PHY_QCAPS_RESP_FLAGS_EEE_SUPPORTED 0x1UL
- #define PORT_PHY_QCAPS_RESP_FLAGS_EXTERNAL_LPBK_SUPPORTED 0x2UL
- #define PORT_PHY_QCAPS_RESP_FLAGS_AUTONEG_LPBK_SUPPORTED 0x4UL
- #define PORT_PHY_QCAPS_RESP_FLAGS_SHARED_PHY_CFG_SUPPORTED 0x8UL
- #define PORT_PHY_QCAPS_RESP_FLAGS_RSVD1_MASK 0xf0UL
- #define PORT_PHY_QCAPS_RESP_FLAGS_RSVD1_SFT 4
+ #define PORT_PHY_QCAPS_RESP_FLAGS_EEE_SUPPORTED 0x1UL
+ #define PORT_PHY_QCAPS_RESP_FLAGS_EXTERNAL_LPBK_SUPPORTED 0x2UL
+ #define PORT_PHY_QCAPS_RESP_FLAGS_AUTONEG_LPBK_SUPPORTED 0x4UL
+ #define PORT_PHY_QCAPS_RESP_FLAGS_SHARED_PHY_CFG_SUPPORTED 0x8UL
+ #define PORT_PHY_QCAPS_RESP_FLAGS_CUMULATIVE_COUNTERS_ON_RESET 0x10UL
+ #define PORT_PHY_QCAPS_RESP_FLAGS_RSVD1_MASK 0xe0UL
+ #define PORT_PHY_QCAPS_RESP_FLAGS_RSVD1_SFT 5
u8 port_cnt;
#define PORT_PHY_QCAPS_RESP_PORT_CNT_UNKNOWN 0x0UL
#define PORT_PHY_QCAPS_RESP_PORT_CNT_1 0x1UL
@@ -3339,7 +3411,6 @@ struct hwrm_port_phy_qcaps_output {
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_FORCE_MODE_100GB 0x800UL
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_FORCE_MODE_10MBHD 0x1000UL
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_FORCE_MODE_10MB 0x2000UL
- #define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_FORCE_MODE_200GB 0x4000UL
__le16 supported_speeds_auto_mode;
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_AUTO_MODE_100MBHD 0x1UL
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_AUTO_MODE_100MB 0x2UL
@@ -3355,7 +3426,6 @@ struct hwrm_port_phy_qcaps_output {
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_AUTO_MODE_100GB 0x800UL
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_AUTO_MODE_10MBHD 0x1000UL
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_AUTO_MODE_10MB 0x2000UL
- #define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_AUTO_MODE_200GB 0x4000UL
__le16 supported_speeds_eee_mode;
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_EEE_MODE_RSVD1 0x1UL
#define PORT_PHY_QCAPS_RESP_SUPPORTED_SPEEDS_EEE_MODE_100MB 0x2UL
@@ -3372,8 +3442,18 @@ struct hwrm_port_phy_qcaps_output {
__le32 valid_tx_lpi_timer_high;
#define PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK 0xffffffUL
#define PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_SFT 0
- #define PORT_PHY_QCAPS_RESP_VALID_MASK 0xff000000UL
- #define PORT_PHY_QCAPS_RESP_VALID_SFT 24
+ #define PORT_PHY_QCAPS_RESP_RSVD_MASK 0xff000000UL
+ #define PORT_PHY_QCAPS_RESP_RSVD_SFT 24
+ __le16 supported_pam4_speeds_auto_mode;
+ #define PORT_PHY_QCAPS_RESP_SUPPORTED_PAM4_SPEEDS_AUTO_MODE_50G 0x1UL
+ #define PORT_PHY_QCAPS_RESP_SUPPORTED_PAM4_SPEEDS_AUTO_MODE_100G 0x2UL
+ #define PORT_PHY_QCAPS_RESP_SUPPORTED_PAM4_SPEEDS_AUTO_MODE_200G 0x4UL
+ __le16 supported_pam4_speeds_force_mode;
+ #define PORT_PHY_QCAPS_RESP_SUPPORTED_PAM4_SPEEDS_FORCE_MODE_50G 0x1UL
+ #define PORT_PHY_QCAPS_RESP_SUPPORTED_PAM4_SPEEDS_FORCE_MODE_100G 0x2UL
+ #define PORT_PHY_QCAPS_RESP_SUPPORTED_PAM4_SPEEDS_FORCE_MODE_200G 0x4UL
+ u8 unused_0[3];
+ u8 valid;
};
/* hwrm_port_phy_i2c_read_input (size:320b/40B) */
@@ -3812,7 +3892,7 @@ struct hwrm_queue_qportcfg_input {
u8 unused_0;
};
-/* hwrm_queue_qportcfg_output (size:256b/32B) */
+/* hwrm_queue_qportcfg_output (size:1344b/168B) */
struct hwrm_queue_qportcfg_output {
__le16 error_code;
__le16 req_type;
@@ -3898,6 +3978,49 @@ struct hwrm_queue_qportcfg_output {
#define QUEUE_QPORTCFG_RESP_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS_NIC 0x3UL
#define QUEUE_QPORTCFG_RESP_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN 0xffUL
#define QUEUE_QPORTCFG_RESP_QUEUE_ID7_SERVICE_PROFILE_LAST QUEUE_QPORTCFG_RESP_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN
+ u8 unused_0;
+ char qid0_name[16];
+ char qid1_name[16];
+ char qid2_name[16];
+ char qid3_name[16];
+ char qid4_name[16];
+ char qid5_name[16];
+ char qid6_name[16];
+ char qid7_name[16];
+ u8 unused_1[7];
+ u8 valid;
+};
+
+/* hwrm_queue_qcfg_input (size:192b/24B) */
+struct hwrm_queue_qcfg_input {
+ __le16 req_type;
+ __le16 cmpl_ring;
+ __le16 seq_id;
+ __le16 target_id;
+ __le64 resp_addr;
+ __le32 flags;
+ #define QUEUE_QCFG_REQ_FLAGS_PATH 0x1UL
+ #define QUEUE_QCFG_REQ_FLAGS_PATH_TX 0x0UL
+ #define QUEUE_QCFG_REQ_FLAGS_PATH_RX 0x1UL
+ #define QUEUE_QCFG_REQ_FLAGS_PATH_LAST QUEUE_QCFG_REQ_FLAGS_PATH_RX
+ __le32 queue_id;
+};
+
+/* hwrm_queue_qcfg_output (size:128b/16B) */
+struct hwrm_queue_qcfg_output {
+ __le16 error_code;
+ __le16 req_type;
+ __le16 seq_id;
+ __le16 resp_len;
+ __le32 queue_len;
+ u8 service_profile;
+ #define QUEUE_QCFG_RESP_SERVICE_PROFILE_LOSSY 0x0UL
+ #define QUEUE_QCFG_RESP_SERVICE_PROFILE_LOSSLESS 0x1UL
+ #define QUEUE_QCFG_RESP_SERVICE_PROFILE_UNKNOWN 0xffUL
+ #define QUEUE_QCFG_RESP_SERVICE_PROFILE_LAST QUEUE_QCFG_RESP_SERVICE_PROFILE_UNKNOWN
+ u8 queue_cfg_info;
+ #define QUEUE_QCFG_RESP_QUEUE_CFG_INFO_ASYM_CFG 0x1UL
+ u8 unused_0;
u8 valid;
};
@@ -4938,6 +5061,7 @@ struct hwrm_vnic_cfg_input {
#define VNIC_CFG_REQ_ENABLES_DEFAULT_RX_RING_ID 0x20UL
#define VNIC_CFG_REQ_ENABLES_DEFAULT_CMPL_RING_ID 0x40UL
#define VNIC_CFG_REQ_ENABLES_QUEUE_ID 0x80UL
+ #define VNIC_CFG_REQ_ENABLES_RX_CSUM_V2_MODE 0x100UL
__le16 vnic_id;
__le16 dflt_ring_grp;
__le16 rss_rule;
@@ -4947,7 +5071,12 @@ struct hwrm_vnic_cfg_input {
__le16 default_rx_ring_id;
__le16 default_cmpl_ring_id;
__le16 queue_id;
- u8 unused0[6];
+ u8 rx_csum_v2_mode;
+ #define VNIC_CFG_REQ_RX_CSUM_V2_MODE_DEFAULT 0x0UL
+ #define VNIC_CFG_REQ_RX_CSUM_V2_MODE_ALL_OK 0x1UL
+ #define VNIC_CFG_REQ_RX_CSUM_V2_MODE_MAX 0x2UL
+ #define VNIC_CFG_REQ_RX_CSUM_V2_MODE_LAST VNIC_CFG_REQ_RX_CSUM_V2_MODE_MAX
+ u8 unused0[5];
};
/* hwrm_vnic_cfg_output (size:128b/16B) */
@@ -4989,6 +5118,7 @@ struct hwrm_vnic_qcaps_output {
#define VNIC_QCAPS_RESP_FLAGS_ROCE_MIRRORING_CAPABLE_VNIC_CAP 0x40UL
#define VNIC_QCAPS_RESP_FLAGS_OUTERMOST_RSS_CAP 0x80UL
#define VNIC_QCAPS_RESP_FLAGS_COS_ASSIGNMENT_CAP 0x100UL
+ #define VNIC_QCAPS_RESP_FLAGS_RX_CMPL_V2_CAP 0x200UL
__le16 max_aggs_supported;
u8 unused_1[5];
u8 valid;
@@ -5155,15 +5285,18 @@ struct hwrm_vnic_plcmodes_cfg_input {
#define VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_IPV6 0x8UL
#define VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_FCOE 0x10UL
#define VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_ROCE 0x20UL
+ #define VNIC_PLCMODES_CFG_REQ_FLAGS_VIRTIO_PLACEMENT 0x40UL
__le32 enables;
#define VNIC_PLCMODES_CFG_REQ_ENABLES_JUMBO_THRESH_VALID 0x1UL
#define VNIC_PLCMODES_CFG_REQ_ENABLES_HDS_OFFSET_VALID 0x2UL
#define VNIC_PLCMODES_CFG_REQ_ENABLES_HDS_THRESHOLD_VALID 0x4UL
+ #define VNIC_PLCMODES_CFG_REQ_ENABLES_MAX_BDS_VALID 0x8UL
__le32 vnic_id;
__le16 jumbo_thresh;
__le16 hds_offset;
__le16 hds_threshold;
- u8 unused_0[6];
+ __le16 max_bds;
+ u8 unused_0[4];
};
/* hwrm_vnic_plcmodes_cfg_output (size:128b/16B) */
@@ -5231,6 +5364,7 @@ struct hwrm_ring_alloc_input {
#define RING_ALLOC_REQ_ENABLES_RX_RING_ID_VALID 0x40UL
#define RING_ALLOC_REQ_ENABLES_NQ_RING_ID_VALID 0x80UL
#define RING_ALLOC_REQ_ENABLES_RX_BUF_SIZE_VALID 0x100UL
+ #define RING_ALLOC_REQ_ENABLES_SCHQ_ID 0x200UL
u8 ring_type;
#define RING_ALLOC_REQ_RING_TYPE_L2_CMPL 0x0UL
#define RING_ALLOC_REQ_RING_TYPE_TX 0x1UL
@@ -5246,7 +5380,7 @@ struct hwrm_ring_alloc_input {
__le32 fbo;
u8 page_size;
u8 page_tbl_depth;
- u8 unused_1[2];
+ __le16 schq_id;
__le32 length;
__le16 logical_id;
__le16 cmpl_ring_id;
@@ -5344,11 +5478,12 @@ struct hwrm_ring_reset_input {
__le16 target_id;
__le64 resp_addr;
u8 ring_type;
- #define RING_RESET_REQ_RING_TYPE_L2_CMPL 0x0UL
- #define RING_RESET_REQ_RING_TYPE_TX 0x1UL
- #define RING_RESET_REQ_RING_TYPE_RX 0x2UL
- #define RING_RESET_REQ_RING_TYPE_ROCE_CMPL 0x3UL
- #define RING_RESET_REQ_RING_TYPE_LAST RING_RESET_REQ_RING_TYPE_ROCE_CMPL
+ #define RING_RESET_REQ_RING_TYPE_L2_CMPL 0x0UL
+ #define RING_RESET_REQ_RING_TYPE_TX 0x1UL
+ #define RING_RESET_REQ_RING_TYPE_RX 0x2UL
+ #define RING_RESET_REQ_RING_TYPE_ROCE_CMPL 0x3UL
+ #define RING_RESET_REQ_RING_TYPE_RX_RING_GRP 0x6UL
+ #define RING_RESET_REQ_RING_TYPE_LAST RING_RESET_REQ_RING_TYPE_RX_RING_GRP
u8 unused_0;
__le16 ring_id;
u8 unused_1[4];
@@ -5529,6 +5664,7 @@ struct hwrm_ring_grp_free_output {
u8 unused_0[7];
u8 valid;
};
+
#define DEFAULT_FLOW_ID 0xFFFFFFFFUL
#define ROCEV1_FLOW_ID 0xFFFFFFFEUL
#define ROCEV2_FLOW_ID 0xFFFFFFFDUL
@@ -6816,15 +6952,15 @@ struct ctx_hw_stats {
__le64 rx_mcast_pkts;
__le64 rx_bcast_pkts;
__le64 rx_discard_pkts;
- __le64 rx_drop_pkts;
+ __le64 rx_error_pkts;
__le64 rx_ucast_bytes;
__le64 rx_mcast_bytes;
__le64 rx_bcast_bytes;
__le64 tx_ucast_pkts;
__le64 tx_mcast_pkts;
__le64 tx_bcast_pkts;
+ __le64 tx_error_pkts;
__le64 tx_discard_pkts;
- __le64 tx_drop_pkts;
__le64 tx_ucast_bytes;
__le64 tx_mcast_bytes;
__le64 tx_bcast_bytes;
@@ -6840,15 +6976,15 @@ struct ctx_hw_stats_ext {
__le64 rx_mcast_pkts;
__le64 rx_bcast_pkts;
__le64 rx_discard_pkts;
- __le64 rx_drop_pkts;
+ __le64 rx_error_pkts;
__le64 rx_ucast_bytes;
__le64 rx_mcast_bytes;
__le64 rx_bcast_bytes;
__le64 tx_ucast_pkts;
__le64 tx_mcast_pkts;
__le64 tx_bcast_pkts;
+ __le64 tx_error_pkts;
__le64 tx_discard_pkts;
- __le64 tx_drop_pkts;
__le64 tx_ucast_bytes;
__le64 tx_mcast_bytes;
__le64 tx_bcast_bytes;
@@ -6915,7 +7051,9 @@ struct hwrm_stat_ctx_query_input {
__le16 target_id;
__le64 resp_addr;
__le32 stat_ctx_id;
- u8 unused_0[4];
+ u8 flags;
+ #define STAT_CTX_QUERY_REQ_FLAGS_COUNTER_MASK 0x1UL
+ u8 unused_0[3];
};
/* hwrm_stat_ctx_query_output (size:1408b/176B) */
@@ -6948,6 +7086,50 @@ struct hwrm_stat_ctx_query_output {
u8 valid;
};
+/* hwrm_stat_ext_ctx_query_input (size:192b/24B) */
+struct hwrm_stat_ext_ctx_query_input {
+ __le16 req_type;
+ __le16 cmpl_ring;
+ __le16 seq_id;
+ __le16 target_id;
+ __le64 resp_addr;
+ __le32 stat_ctx_id;
+ u8 flags;
+ #define STAT_EXT_CTX_QUERY_REQ_FLAGS_COUNTER_MASK 0x1UL
+ u8 unused_0[3];
+};
+
+/* hwrm_stat_ext_ctx_query_output (size:1472b/184B) */
+struct hwrm_stat_ext_ctx_query_output {
+ __le16 error_code;
+ __le16 req_type;
+ __le16 seq_id;
+ __le16 resp_len;
+ __le64 rx_ucast_pkts;
+ __le64 rx_mcast_pkts;
+ __le64 rx_bcast_pkts;
+ __le64 rx_discard_pkts;
+ __le64 rx_error_pkts;
+ __le64 rx_ucast_bytes;
+ __le64 rx_mcast_bytes;
+ __le64 rx_bcast_bytes;
+ __le64 tx_ucast_pkts;
+ __le64 tx_mcast_pkts;
+ __le64 tx_bcast_pkts;
+ __le64 tx_error_pkts;
+ __le64 tx_discard_pkts;
+ __le64 tx_ucast_bytes;
+ __le64 tx_mcast_bytes;
+ __le64 tx_bcast_bytes;
+ __le64 rx_tpa_eligible_pkt;
+ __le64 rx_tpa_eligible_bytes;
+ __le64 rx_tpa_pkt;
+ __le64 rx_tpa_bytes;
+ __le64 rx_tpa_errors;
+ u8 unused_0[7];
+ u8 valid;
+};
+
/* hwrm_stat_ctx_clr_stats_input (size:192b/24B) */
struct hwrm_stat_ctx_clr_stats_input {
__le16 req_type;
@@ -7497,6 +7679,29 @@ struct hwrm_wol_reason_qcfg_output {
u8 valid;
};
+/* hwrm_dbg_read_direct_input (size:256b/32B) */
+struct hwrm_dbg_read_direct_input {
+ __le16 req_type;
+ __le16 cmpl_ring;
+ __le16 seq_id;
+ __le16 target_id;
+ __le64 resp_addr;
+ __le64 host_dest_addr;
+ __le32 read_addr;
+ __le32 read_len32;
+};
+
+/* hwrm_dbg_read_direct_output (size:128b/16B) */
+struct hwrm_dbg_read_direct_output {
+ __le16 error_code;
+ __le16 req_type;
+ __le16 seq_id;
+ __le16 resp_len;
+ __le32 crc32;
+ u8 unused_0[3];
+ u8 valid;
+};
+
/* coredump_segment_record (size:128b/16B) */
struct coredump_segment_record {
__le16 component_id;
@@ -7507,7 +7712,8 @@ struct coredump_segment_record {
u8 seg_flags;
u8 compress_flags;
#define SFLAG_COMPRESSED_ZLIB 0x1UL
- u8 unused_0[6];
+ u8 unused_0[2];
+ __le32 segment_len;
};
/* hwrm_dbg_coredump_list_input (size:256b/32B) */
@@ -7620,7 +7826,8 @@ struct hwrm_dbg_ring_info_get_input {
#define DBG_RING_INFO_GET_REQ_RING_TYPE_L2_CMPL 0x0UL
#define DBG_RING_INFO_GET_REQ_RING_TYPE_TX 0x1UL
#define DBG_RING_INFO_GET_REQ_RING_TYPE_RX 0x2UL
- #define DBG_RING_INFO_GET_REQ_RING_TYPE_LAST DBG_RING_INFO_GET_REQ_RING_TYPE_RX
+ #define DBG_RING_INFO_GET_REQ_RING_TYPE_NQ 0x3UL
+ #define DBG_RING_INFO_GET_REQ_RING_TYPE_LAST DBG_RING_INFO_GET_REQ_RING_TYPE_NQ
u8 unused_0[3];
__le32 fw_ring_id;
};
@@ -7633,7 +7840,8 @@ struct hwrm_dbg_ring_info_get_output {
__le16 resp_len;
__le32 producer_index;
__le32 consumer_index;
- u8 unused_0[7];
+ __le32 cag_vector_ctrl;
+ u8 unused_0[3];
u8 valid;
};
@@ -7922,6 +8130,7 @@ struct hwrm_nvm_install_update_input {
#define NVM_INSTALL_UPDATE_REQ_FLAGS_ERASE_UNUSED_SPACE 0x1UL
#define NVM_INSTALL_UPDATE_REQ_FLAGS_REMOVE_UNUSED_PKG 0x2UL
#define NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG 0x4UL
+ #define NVM_INSTALL_UPDATE_REQ_FLAGS_VERIFY_ONLY 0x8UL
u8 unused_0[2];
};
@@ -8101,7 +8310,14 @@ struct hwrm_selftest_qlist_output {
char test5_name[32];
char test6_name[32];
char test7_name[32];
- u8 unused_2[7];
+ u8 eyescope_target_BER_support;
+ #define SELFTEST_QLIST_RESP_EYESCOPE_TARGET_BER_SUPPORT_BER_1E8_SUPPORTED 0x0UL
+ #define SELFTEST_QLIST_RESP_EYESCOPE_TARGET_BER_SUPPORT_BER_1E9_SUPPORTED 0x1UL
+ #define SELFTEST_QLIST_RESP_EYESCOPE_TARGET_BER_SUPPORT_BER_1E10_SUPPORTED 0x2UL
+ #define SELFTEST_QLIST_RESP_EYESCOPE_TARGET_BER_SUPPORT_BER_1E11_SUPPORTED 0x3UL
+ #define SELFTEST_QLIST_RESP_EYESCOPE_TARGET_BER_SUPPORT_BER_1E12_SUPPORTED 0x4UL
+ #define SELFTEST_QLIST_RESP_EYESCOPE_TARGET_BER_SUPPORT_LAST SELFTEST_QLIST_RESP_EYESCOPE_TARGET_BER_SUPPORT_BER_1E12_SUPPORTED
+ u8 unused_2[6];
u8 valid;
};
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
index 392e32c7122a..cc2ee4d0bd18 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
@@ -1029,7 +1029,7 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf)
rc = bnxt_hwrm_exec_fwd_resp(
bp, vf, sizeof(struct hwrm_port_phy_qcfg_input));
} else {
- struct hwrm_port_phy_qcfg_output phy_qcfg_resp;
+ struct hwrm_port_phy_qcfg_output_compat phy_qcfg_resp = {0};
struct hwrm_port_phy_qcfg_input *phy_qcfg_req;
phy_qcfg_req =
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
index 4a11c1e7cc02..5e4429b14b8c 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
@@ -1638,7 +1638,7 @@ static int bnxt_tc_get_flow_stats(struct bnxt *bp,
lastused = flow->lastused;
spin_unlock(&flow->stats_lock);
- flow_stats_update(&tc_flow_cmd->stats, stats.bytes, stats.packets,
+ flow_stats_update(&tc_flow_cmd->stats, stats.bytes, stats.packets, 0,
lastused, FLOW_ACTION_HW_STATS_DELAYED);
return 0;
}
@@ -1888,7 +1888,7 @@ static void bnxt_tc_setup_indr_rel(void *cb_priv)
kfree(priv);
}
-static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
+static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct Qdisc *sch, struct bnxt *bp,
struct flow_block_offload *f, void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
{
@@ -1911,7 +1911,7 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
block_cb = flow_indr_block_cb_alloc(bnxt_tc_setup_indr_block_cb,
cb_priv, cb_priv,
bnxt_tc_setup_indr_rel, f,
- netdev, data, bp, cleanup);
+ netdev, sch, data, bp, cleanup);
if (IS_ERR(block_cb)) {
list_del(&cb_priv->list);
kfree(cb_priv);
@@ -1946,7 +1946,7 @@ static bool bnxt_is_netdev_indr_offload(struct net_device *netdev)
return netif_is_vxlan(netdev);
}
-static int bnxt_tc_setup_indr_cb(struct net_device *netdev, void *cb_priv,
+static int bnxt_tc_setup_indr_cb(struct net_device *netdev, struct Qdisc *sch, void *cb_priv,
enum tc_setup_type type, void *type_data,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
@@ -1956,8 +1956,7 @@ static int bnxt_tc_setup_indr_cb(struct net_device *netdev, void *cb_priv,
switch (type) {
case TC_SETUP_BLOCK:
- return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data, data,
- cleanup);
+ return bnxt_tc_setup_indr_block(netdev, sch, cb_priv, type_data, data, cleanup);
default:
break;
}
@@ -2001,11 +2000,8 @@ int bnxt_init_tc(struct bnxt *bp)
struct bnxt_tc_info *tc_info;
int rc;
- if (bp->hwrm_spec_code < 0x10803) {
- netdev_warn(bp->dev,
- "Firmware does not support TC flower offload.\n");
- return -ENOTSUPP;
- }
+ if (bp->hwrm_spec_code < 0x10803)
+ return 0;
tc_info = kzalloc(sizeof(*tc_info), GFP_KERNEL);
if (!tc_info)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 5e3b4a3b69ea..2704a4709bc7 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -330,10 +330,6 @@ int bnxt_xdp(struct net_device *dev, struct netdev_bpf *xdp)
case XDP_SETUP_PROG:
rc = bnxt_xdp_set(bp, xdp->prog);
break;
- case XDP_QUERY_PROG:
- xdp->prog_id = bp->xdp_prog ? bp->xdp_prog->aux->id : 0;
- rc = 0;
- break;
default:
rc = -EINVAL;
break;
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index e471b14fc6e9..1fecc25767bd 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -3636,6 +3636,22 @@ static struct net_device_stats *bcmgenet_get_stats(struct net_device *dev)
return &dev->stats;
}
+static int bcmgenet_change_carrier(struct net_device *dev, bool new_carrier)
+{
+ struct bcmgenet_priv *priv = netdev_priv(dev);
+
+ if (!dev->phydev || !phy_is_pseudo_fixed_link(dev->phydev) ||
+ priv->phy_interface != PHY_INTERFACE_MODE_MOCA)
+ return -EOPNOTSUPP;
+
+ if (new_carrier)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);
+
+ return 0;
+}
+
static const struct net_device_ops bcmgenet_netdev_ops = {
.ndo_open = bcmgenet_open,
.ndo_stop = bcmgenet_close,
@@ -3649,6 +3665,7 @@ static const struct net_device_ops bcmgenet_netdev_ops = {
.ndo_poll_controller = bcmgenet_poll_controller,
#endif
.ndo_get_stats = bcmgenet_get_stats,
+ .ndo_change_carrier = bcmgenet_change_carrier,
};
/* Array of GENET hardware parameters/characteristics */
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 6953d0546acb..1000c894064f 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2847,7 +2847,7 @@ struct tg3_ocir {
u32 port1_flags;
u32 port2_flags;
u32 port3_flags;
- u32 reserved2[1];
+ u32 reserved2;
};
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
index e17bfc87da90..49358d42a0e2 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
@@ -1535,7 +1535,6 @@ static int
bfa_flash_fifo_flush(void __iomem *pci_bar)
{
u32 i;
- u32 t;
union bfa_flash_dev_status_reg dev_status;
dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
@@ -1545,7 +1544,7 @@ bfa_flash_fifo_flush(void __iomem *pci_bar)
/* fifo counter in terms of words */
for (i = 0; i < dev_status.r.fifo_cnt; i++)
- t = readl(pci_bar + FLI_RDDATA_REG);
+ readl(pci_bar + FLI_RDDATA_REG);
/* Check the device status. It may take some time. */
for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
diff --git a/drivers/net/ethernet/brocade/bna/bfi.h b/drivers/net/ethernet/brocade/bna/bfi.h
index 09c912e984fe..f780d42c946d 100644
--- a/drivers/net/ethernet/brocade/bna/bfi.h
+++ b/drivers/net/ethernet/brocade/bna/bfi.h
@@ -389,7 +389,7 @@ struct bfi_msgq_mhdr {
u16 msg_token;
u16 num_entries;
u8 enet_id;
- u8 rsvd[1];
+ u8 rsvd;
} __packed;
#define bfi_msgq_mhdr_set(_mh, _mc, _mid, _tok, _enet_id) do { \
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index ab827fb4b6b9..4f1b41569260 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -90,6 +90,7 @@
#define GEM_SA3T 0x009C /* Specific3 Top */
#define GEM_SA4B 0x00A0 /* Specific4 Bottom */
#define GEM_SA4T 0x00A4 /* Specific4 Top */
+#define GEM_WOL 0x00b8 /* Wake on LAN */
#define GEM_EFTSH 0x00e8 /* PTP Event Frame Transmitted Seconds Register 47:32 */
#define GEM_EFRSH 0x00ec /* PTP Event Frame Received Seconds Register 47:32 */
#define GEM_PEFTSH 0x00f0 /* PTP Peer Event Frame Transmitted Seconds Register 47:32 */
@@ -396,6 +397,8 @@
#define MACB_PDRSFT_SIZE 1
#define MACB_SRI_OFFSET 26 /* TSU Seconds Register Increment */
#define MACB_SRI_SIZE 1
+#define GEM_WOL_OFFSET 28 /* Enable wake-on-lan interrupt */
+#define GEM_WOL_SIZE 1
/* Timer increment fields */
#define MACB_TI_CNS_OFFSET 0
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 2213e6ab8151..6761f404b8aa 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -578,7 +578,7 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode,
if (bp->caps & MACB_CAPS_MACB_IS_EMAC) {
if (state->interface == PHY_INTERFACE_MODE_RMII)
ctrl |= MACB_BIT(RM9200_RMII);
- } else {
+ } else if (macb_is_gem(bp)) {
ctrl &= ~(GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL));
if (state->interface == PHY_INTERFACE_MODE_SGMII)
@@ -639,10 +639,13 @@ static void macb_mac_link_up(struct phylink_config *config,
ctrl |= MACB_BIT(FD);
if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) {
- ctrl &= ~(GEM_BIT(GBE) | MACB_BIT(PAE));
+ ctrl &= ~MACB_BIT(PAE);
+ if (macb_is_gem(bp)) {
+ ctrl &= ~GEM_BIT(GBE);
- if (speed == SPEED_1000)
- ctrl |= GEM_BIT(GBE);
+ if (speed == SPEED_1000)
+ ctrl |= GEM_BIT(GBE);
+ }
/* We do not support MLO_PAUSE_RX yet */
if (tx_pause)
@@ -1467,7 +1470,7 @@ static void macb_hresp_error_task(unsigned long data)
{
struct macb *bp = (struct macb *)data;
struct net_device *dev = bp->dev;
- struct macb_queue *queue = bp->queues;
+ struct macb_queue *queue;
unsigned int q;
u32 ctrl;
@@ -1517,6 +1520,64 @@ static void macb_tx_restart(struct macb_queue *queue)
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
}
+static irqreturn_t macb_wol_interrupt(int irq, void *dev_id)
+{
+ struct macb_queue *queue = dev_id;
+ struct macb *bp = queue->bp;
+ u32 status;
+
+ status = queue_readl(queue, ISR);
+
+ if (unlikely(!status))
+ return IRQ_NONE;
+
+ spin_lock(&bp->lock);
+
+ if (status & MACB_BIT(WOL)) {
+ queue_writel(queue, IDR, MACB_BIT(WOL));
+ macb_writel(bp, WOL, 0);
+ netdev_vdbg(bp->dev, "MACB WoL: queue = %u, isr = 0x%08lx\n",
+ (unsigned int)(queue - bp->queues),
+ (unsigned long)status);
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR, MACB_BIT(WOL));
+ pm_wakeup_event(&bp->pdev->dev, 0);
+ }
+
+ spin_unlock(&bp->lock);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t gem_wol_interrupt(int irq, void *dev_id)
+{
+ struct macb_queue *queue = dev_id;
+ struct macb *bp = queue->bp;
+ u32 status;
+
+ status = queue_readl(queue, ISR);
+
+ if (unlikely(!status))
+ return IRQ_NONE;
+
+ spin_lock(&bp->lock);
+
+ if (status & GEM_BIT(WOL)) {
+ queue_writel(queue, IDR, GEM_BIT(WOL));
+ gem_writel(bp, WOL, 0);
+ netdev_vdbg(bp->dev, "GEM WoL: queue = %u, isr = 0x%08lx\n",
+ (unsigned int)(queue - bp->queues),
+ (unsigned long)status);
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR, GEM_BIT(WOL));
+ pm_wakeup_event(&bp->pdev->dev, 0);
+ }
+
+ spin_unlock(&bp->lock);
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t macb_interrupt(int irq, void *dev_id)
{
struct macb_queue *queue = dev_id;
@@ -1933,7 +1994,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
unsigned int desc_cnt, nr_frags, frag_size, f;
unsigned int hdrlen;
- bool is_lso, is_udp = 0;
+ bool is_lso;
netdev_tx_t ret = NETDEV_TX_OK;
if (macb_clear_csum(skb)) {
@@ -1949,10 +2010,8 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
is_lso = (skb_shinfo(skb)->gso_size != 0);
if (is_lso) {
- is_udp = !!(ip_hdr(skb)->protocol == IPPROTO_UDP);
-
/* length of headers */
- if (is_udp)
+ if (ip_hdr(skb)->protocol == IPPROTO_UDP)
/* only queue eth + ip headers separately for UDP */
hdrlen = skb_transport_offset(skb);
else
@@ -3318,6 +3377,8 @@ static const struct ethtool_ops macb_ethtool_ops = {
static const struct ethtool_ops gem_ethtool_ops = {
.get_regs_len = macb_get_regs_len,
.get_regs = macb_get_regs,
+ .get_wol = macb_get_wol,
+ .set_wol = macb_set_wol,
.get_link = ethtool_op_get_link,
.get_ts_info = macb_get_ts_info,
.get_ethtool_stats = gem_get_ethtool_stats,
@@ -3488,8 +3549,6 @@ static void macb_probe_queues(void __iomem *mem,
unsigned int *queue_mask,
unsigned int *num_queues)
{
- unsigned int hw_q;
-
*queue_mask = 0x1;
*num_queues = 1;
@@ -3503,13 +3562,8 @@ static void macb_probe_queues(void __iomem *mem,
return;
/* bit 0 is never set but queue 0 always exists */
- *queue_mask = readl_relaxed(mem + GEM_DCFG6) & 0xff;
-
- *queue_mask |= 0x1;
-
- for (hw_q = 1; hw_q < MACB_MAX_QUEUES; ++hw_q)
- if (*queue_mask & (1 << hw_q))
- (*num_queues)++;
+ *queue_mask |= readl_relaxed(mem + GEM_DCFG6) & 0xff;
+ *num_queues = hweight32(*queue_mask);
}
static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
@@ -4576,33 +4630,77 @@ static int __maybe_unused macb_suspend(struct device *dev)
struct macb_queue *queue = bp->queues;
unsigned long flags;
unsigned int q;
+ int err;
if (!netif_running(netdev))
return 0;
if (bp->wol & MACB_WOL_ENABLED) {
- macb_writel(bp, IER, MACB_BIT(WOL));
- macb_writel(bp, WOL, MACB_BIT(MAG));
- enable_irq_wake(bp->queues[0].irq);
- netif_device_detach(netdev);
- } else {
- netif_device_detach(netdev);
+ spin_lock_irqsave(&bp->lock, flags);
+ /* Flush all status bits */
+ macb_writel(bp, TSR, -1);
+ macb_writel(bp, RSR, -1);
for (q = 0, queue = bp->queues; q < bp->num_queues;
- ++q, ++queue)
- napi_disable(&queue->napi);
+ ++q, ++queue) {
+ /* Disable all interrupts */
+ queue_writel(queue, IDR, -1);
+ queue_readl(queue, ISR);
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR, -1);
+ }
+ /* Change interrupt handler and
+ * Enable WoL IRQ on queue 0
+ */
+ devm_free_irq(dev, bp->queues[0].irq, bp->queues);
+ if (macb_is_gem(bp)) {
+ err = devm_request_irq(dev, bp->queues[0].irq, gem_wol_interrupt,
+ IRQF_SHARED, netdev->name, bp->queues);
+ if (err) {
+ dev_err(dev,
+ "Unable to request IRQ %d (error %d)\n",
+ bp->queues[0].irq, err);
+ spin_unlock_irqrestore(&bp->lock, flags);
+ return err;
+ }
+ queue_writel(bp->queues, IER, GEM_BIT(WOL));
+ gem_writel(bp, WOL, MACB_BIT(MAG));
+ } else {
+ err = devm_request_irq(dev, bp->queues[0].irq, macb_wol_interrupt,
+ IRQF_SHARED, netdev->name, bp->queues);
+ if (err) {
+ dev_err(dev,
+ "Unable to request IRQ %d (error %d)\n",
+ bp->queues[0].irq, err);
+ spin_unlock_irqrestore(&bp->lock, flags);
+ return err;
+ }
+ queue_writel(bp->queues, IER, MACB_BIT(WOL));
+ macb_writel(bp, WOL, MACB_BIT(MAG));
+ }
+ spin_unlock_irqrestore(&bp->lock, flags);
+
+ enable_irq_wake(bp->queues[0].irq);
+ }
+
+ netif_device_detach(netdev);
+ for (q = 0, queue = bp->queues; q < bp->num_queues;
+ ++q, ++queue)
+ napi_disable(&queue->napi);
+
+ if (!(bp->wol & MACB_WOL_ENABLED)) {
rtnl_lock();
phylink_stop(bp->phylink);
rtnl_unlock();
spin_lock_irqsave(&bp->lock, flags);
macb_reset_hw(bp);
spin_unlock_irqrestore(&bp->lock, flags);
+ }
- if (!(bp->caps & MACB_CAPS_USRIO_DISABLED))
- bp->pm_data.usrio = macb_or_gem_readl(bp, USRIO);
+ if (!(bp->caps & MACB_CAPS_USRIO_DISABLED))
+ bp->pm_data.usrio = macb_or_gem_readl(bp, USRIO);
- if (netdev->hw_features & NETIF_F_NTUPLE)
- bp->pm_data.scrt2 = gem_readl_n(bp, ETHT, SCRT2_ETHT);
- }
+ if (netdev->hw_features & NETIF_F_NTUPLE)
+ bp->pm_data.scrt2 = gem_readl_n(bp, ETHT, SCRT2_ETHT);
if (bp->ptp_info)
bp->ptp_info->ptp_remove(netdev);
@@ -4617,7 +4715,9 @@ static int __maybe_unused macb_resume(struct device *dev)
struct net_device *netdev = dev_get_drvdata(dev);
struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue = bp->queues;
+ unsigned long flags;
unsigned int q;
+ int err;
if (!netif_running(netdev))
return 0;
@@ -4626,29 +4726,60 @@ static int __maybe_unused macb_resume(struct device *dev)
pm_runtime_force_resume(dev);
if (bp->wol & MACB_WOL_ENABLED) {
- macb_writel(bp, IDR, MACB_BIT(WOL));
- macb_writel(bp, WOL, 0);
- disable_irq_wake(bp->queues[0].irq);
- } else {
- macb_writel(bp, NCR, MACB_BIT(MPE));
-
- if (netdev->hw_features & NETIF_F_NTUPLE)
- gem_writel_n(bp, ETHT, SCRT2_ETHT, bp->pm_data.scrt2);
+ spin_lock_irqsave(&bp->lock, flags);
+ /* Disable WoL */
+ if (macb_is_gem(bp)) {
+ queue_writel(bp->queues, IDR, GEM_BIT(WOL));
+ gem_writel(bp, WOL, 0);
+ } else {
+ queue_writel(bp->queues, IDR, MACB_BIT(WOL));
+ macb_writel(bp, WOL, 0);
+ }
+ /* Clear ISR on queue 0 */
+ queue_readl(bp->queues, ISR);
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(bp->queues, ISR, -1);
+ /* Replace interrupt handler on queue 0 */
+ devm_free_irq(dev, bp->queues[0].irq, bp->queues);
+ err = devm_request_irq(dev, bp->queues[0].irq, macb_interrupt,
+ IRQF_SHARED, netdev->name, bp->queues);
+ if (err) {
+ dev_err(dev,
+ "Unable to request IRQ %d (error %d)\n",
+ bp->queues[0].irq, err);
+ spin_unlock_irqrestore(&bp->lock, flags);
+ return err;
+ }
+ spin_unlock_irqrestore(&bp->lock, flags);
- if (!(bp->caps & MACB_CAPS_USRIO_DISABLED))
- macb_or_gem_writel(bp, USRIO, bp->pm_data.usrio);
+ disable_irq_wake(bp->queues[0].irq);
- for (q = 0, queue = bp->queues; q < bp->num_queues;
- ++q, ++queue)
- napi_enable(&queue->napi);
+ /* Now make sure we disable phy before moving
+ * to common restore path
+ */
rtnl_lock();
- phylink_start(bp->phylink);
+ phylink_stop(bp->phylink);
rtnl_unlock();
}
+ for (q = 0, queue = bp->queues; q < bp->num_queues;
+ ++q, ++queue)
+ napi_enable(&queue->napi);
+
+ if (netdev->hw_features & NETIF_F_NTUPLE)
+ gem_writel_n(bp, ETHT, SCRT2_ETHT, bp->pm_data.scrt2);
+
+ if (!(bp->caps & MACB_CAPS_USRIO_DISABLED))
+ macb_or_gem_writel(bp, USRIO, bp->pm_data.usrio);
+
+ macb_writel(bp, NCR, MACB_BIT(MPE));
macb_init_hw(bp);
macb_set_rx_mode(netdev);
macb_restore_features(bp);
+ rtnl_lock();
+ phylink_start(bp->phylink);
+ rtnl_unlock();
+
netif_device_attach(netdev);
if (bp->ptp_info)
bp->ptp_info->ptp_init(netdev);
diff --git a/drivers/net/ethernet/cadence/macb_pci.c b/drivers/net/ethernet/cadence/macb_pci.c
index 617b3b728dd0..cd7d0332cba3 100644
--- a/drivers/net/ethernet/cadence/macb_pci.c
+++ b/drivers/net/ethernet/cadence/macb_pci.c
@@ -2,7 +2,7 @@
/**
* Cadence GEM PCI wrapper.
*
- * Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
+ * Copyright (C) 2016 Cadence Design Systems - https://www.cadence.com
*
* Authors: Rafal Ozieblo <rafalo@cadence.com>
* Bartosz Folta <bfolta@cadence.com>
diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c
index 43a3f0dbf857..31ebf3ee7ec0 100644
--- a/drivers/net/ethernet/cadence/macb_ptp.c
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -2,7 +2,7 @@
/**
* 1588 PTP support for Cadence GEM device.
*
- * Copyright (C) 2017 Cadence Design Systems - http://www.cadence.com
+ * Copyright (C) 2017 Cadence Design Systems - https://www.cadence.com
*
* Authors: Rafal Ozieblo <rafalo@cadence.com>
* Bartosz Folta <bfolta@cadence.com>
diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
index 43d11c38b38a..4cddd628d41b 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
@@ -1167,7 +1167,7 @@ static int cn23xx_get_pf_num(struct octeon_device *oct)
oct->pf_num = ((fdl_bit >> CN23XX_PCIE_SRIOV_FDL_BIT_POS) &
CN23XX_PCIE_SRIOV_FDL_MASK);
} else {
- ret = EINVAL;
+ ret = -EINVAL;
/* Under some virtual environments, extended PCI regs are
* inaccessible, in which case the above read will have failed.
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 66d31c018c7e..e73bc211779a 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -405,27 +405,8 @@ static void liquidio_pcie_resume(struct pci_dev *pdev __attribute__((unused)))
/* Nothing to be done here. */
}
-#ifdef CONFIG_PM
-/**
- * \brief called when suspending
- * @param pdev Pointer to PCI device
- * @param state state to suspend to
- */
-static int liquidio_suspend(struct pci_dev *pdev __attribute__((unused)),
- pm_message_t state __attribute__((unused)))
-{
- return 0;
-}
-
-/**
- * \brief called when resuming
- * @param pdev Pointer to PCI device
- */
-static int liquidio_resume(struct pci_dev *pdev __attribute__((unused)))
-{
- return 0;
-}
-#endif
+#define liquidio_suspend NULL
+#define liquidio_resume NULL
/* For PCI-E Advanced Error Recovery (AER) Interface */
static const struct pci_error_handlers liquidio_err_handler = {
@@ -451,17 +432,15 @@ static const struct pci_device_id liquidio_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, liquidio_pci_tbl);
+static SIMPLE_DEV_PM_OPS(liquidio_pm_ops, liquidio_suspend, liquidio_resume);
+
static struct pci_driver liquidio_pci_driver = {
.name = "LiquidIO",
.id_table = liquidio_pci_tbl,
.probe = liquidio_probe,
.remove = liquidio_remove,
.err_handler = &liquidio_err_handler, /* For AER */
-
-#ifdef CONFIG_PM
- .suspend = liquidio_suspend,
- .resume = liquidio_resume,
-#endif
+ .driver.pm = &liquidio_pm_ops,
#ifdef CONFIG_PCI_IOV
.sriov_configure = liquidio_enable_sriov,
#endif
@@ -2691,6 +2670,35 @@ static int liquidio_vxlan_port_command(struct net_device *netdev, int command,
return ret;
}
+static int liquidio_udp_tunnel_set_port(struct net_device *netdev,
+ unsigned int table, unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return liquidio_vxlan_port_command(netdev,
+ OCTNET_CMD_VXLAN_PORT_CONFIG,
+ htons(ti->port),
+ OCTNET_CMD_VXLAN_PORT_ADD);
+}
+
+static int liquidio_udp_tunnel_unset_port(struct net_device *netdev,
+ unsigned int table,
+ unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return liquidio_vxlan_port_command(netdev,
+ OCTNET_CMD_VXLAN_PORT_CONFIG,
+ htons(ti->port),
+ OCTNET_CMD_VXLAN_PORT_DEL);
+}
+
+static const struct udp_tunnel_nic_info liquidio_udp_tunnels = {
+ .set_port = liquidio_udp_tunnel_set_port,
+ .unset_port = liquidio_udp_tunnel_unset_port,
+ .tables = {
+ { .n_entries = 1024, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+
/** \brief Net device fix features
* @param netdev pointer to network device
* @param request features requested
@@ -2779,30 +2787,6 @@ static int liquidio_set_features(struct net_device *netdev,
return 0;
}
-static void liquidio_add_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- liquidio_vxlan_port_command(netdev,
- OCTNET_CMD_VXLAN_PORT_CONFIG,
- htons(ti->port),
- OCTNET_CMD_VXLAN_PORT_ADD);
-}
-
-static void liquidio_del_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- liquidio_vxlan_port_command(netdev,
- OCTNET_CMD_VXLAN_PORT_CONFIG,
- htons(ti->port),
- OCTNET_CMD_VXLAN_PORT_DEL);
-}
-
static int __liquidio_set_vf_mac(struct net_device *netdev, int vfidx,
u8 *mac, bool is_admin_assigned)
{
@@ -3229,8 +3213,8 @@ static const struct net_device_ops lionetdevops = {
.ndo_do_ioctl = liquidio_ioctl,
.ndo_fix_features = liquidio_fix_features,
.ndo_set_features = liquidio_set_features,
- .ndo_udp_tunnel_add = liquidio_add_vxlan_port,
- .ndo_udp_tunnel_del = liquidio_del_vxlan_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_set_vf_mac = liquidio_set_vf_mac,
.ndo_set_vf_vlan = liquidio_set_vf_vlan,
.ndo_get_vf_config = liquidio_get_vf_config,
@@ -3585,6 +3569,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
netdev->hw_enc_features = (lio->enc_dev_capability &
~NETIF_F_LRO);
+ netdev->udp_tunnel_nic_info = &liquidio_udp_tunnels;
+
lio->dev_capability |= NETIF_F_GSO_UDP_TUNNEL;
netdev->vlan_features = lio->dev_capability;
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
index bbd9bfa4a989..90ef21086f27 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
@@ -1767,6 +1767,35 @@ static int liquidio_vxlan_port_command(struct net_device *netdev, int command,
return ret;
}
+static int liquidio_udp_tunnel_set_port(struct net_device *netdev,
+ unsigned int table, unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return liquidio_vxlan_port_command(netdev,
+ OCTNET_CMD_VXLAN_PORT_CONFIG,
+ htons(ti->port),
+ OCTNET_CMD_VXLAN_PORT_ADD);
+}
+
+static int liquidio_udp_tunnel_unset_port(struct net_device *netdev,
+ unsigned int table,
+ unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return liquidio_vxlan_port_command(netdev,
+ OCTNET_CMD_VXLAN_PORT_CONFIG,
+ htons(ti->port),
+ OCTNET_CMD_VXLAN_PORT_DEL);
+}
+
+static const struct udp_tunnel_nic_info liquidio_udp_tunnels = {
+ .set_port = liquidio_udp_tunnel_set_port,
+ .unset_port = liquidio_udp_tunnel_unset_port,
+ .tables = {
+ { .n_entries = 1024, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+
/** \brief Net device fix features
* @param netdev pointer to network device
* @param request features requested
@@ -1835,30 +1864,6 @@ static int liquidio_set_features(struct net_device *netdev,
return 0;
}
-static void liquidio_add_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- liquidio_vxlan_port_command(netdev,
- OCTNET_CMD_VXLAN_PORT_CONFIG,
- htons(ti->port),
- OCTNET_CMD_VXLAN_PORT_ADD);
-}
-
-static void liquidio_del_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- liquidio_vxlan_port_command(netdev,
- OCTNET_CMD_VXLAN_PORT_CONFIG,
- htons(ti->port),
- OCTNET_CMD_VXLAN_PORT_DEL);
-}
-
static const struct net_device_ops lionetdevops = {
.ndo_open = liquidio_open,
.ndo_stop = liquidio_stop,
@@ -1873,8 +1878,8 @@ static const struct net_device_ops lionetdevops = {
.ndo_do_ioctl = liquidio_ioctl,
.ndo_fix_features = liquidio_fix_features,
.ndo_set_features = liquidio_set_features,
- .ndo_udp_tunnel_add = liquidio_add_vxlan_port,
- .ndo_udp_tunnel_del = liquidio_del_vxlan_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
};
static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf)
@@ -2095,6 +2100,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
netdev->hw_enc_features =
(lio->enc_dev_capability & ~NETIF_F_LRO);
+ netdev->udp_tunnel_nic_info = &liquidio_udp_tunnels;
+
netdev->vlan_features = lio->dev_capability;
/* Add any unchangeable hw features */
lio->dev_capability |= NETIF_F_HW_VLAN_CTAG_FILTER |
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.c b/drivers/net/ethernet/cavium/liquidio/octeon_device.c
index 934115d18488..ac32facaa427 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.c
@@ -1056,7 +1056,7 @@ void octeon_delete_dispatch_list(struct octeon_device *oct)
list_for_each_safe(temp, tmp2, &freelist) {
list_del(temp);
- vfree(temp);
+ kfree(temp);
}
}
@@ -1152,13 +1152,10 @@ octeon_register_dispatch_fn(struct octeon_device *oct,
dev_dbg(&oct->pci_dev->dev,
"Adding opcode to dispatch list linked list\n");
- dispatch = (struct octeon_dispatch *)
- vmalloc(sizeof(struct octeon_dispatch));
- if (!dispatch) {
- dev_err(&oct->pci_dev->dev,
- "No memory to add dispatch function\n");
+ dispatch = kmalloc(sizeof(*dispatch), GFP_KERNEL);
+ if (!dispatch)
return 1;
- }
+
dispatch->opcode = combined_opcode;
dispatch->dispatch_fn = fn;
dispatch->arg = fn_arg;
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_network.h b/drivers/net/ethernet/cavium/liquidio/octeon_network.h
index 50201fc86dcf..ebe56bd8849b 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_network.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_network.h
@@ -612,7 +612,7 @@ static inline struct list_head *lio_list_delete_head(struct list_head *root)
{
struct list_head *node;
- if (root->prev == root && root->next == root)
+ if (list_empty_careful(root))
node = NULL;
else
node = root->next;
diff --git a/drivers/net/ethernet/cavium/liquidio/request_manager.c b/drivers/net/ethernet/cavium/liquidio/request_manager.c
index 6dd65f9b347c..8e59c2825533 100644
--- a/drivers/net/ethernet/cavium/liquidio/request_manager.c
+++ b/drivers/net/ethernet/cavium/liquidio/request_manager.c
@@ -95,12 +95,10 @@ int octeon_init_instr_queue(struct octeon_device *oct,
/* Initialize a list to holds requests that have been posted to Octeon
* but has yet to be fetched by octeon
*/
- iq->request_list = vmalloc_node((sizeof(*iq->request_list) * num_descs),
- numa_node);
+ iq->request_list = vzalloc_node(array_size(num_descs, sizeof(*iq->request_list)),
+ numa_node);
if (!iq->request_list)
- iq->request_list =
- vmalloc(array_size(num_descs,
- sizeof(*iq->request_list)));
+ iq->request_list = vzalloc(array_size(num_descs, sizeof(*iq->request_list)));
if (!iq->request_list) {
lio_dma_free(oct, q_size, iq->base_addr, iq->base_addr_dma);
dev_err(&oct->pci_dev->dev, "Alloc failed for IQ[%d] nr free list\n",
@@ -108,8 +106,6 @@ int octeon_init_instr_queue(struct octeon_device *oct,
return 1;
}
- memset(iq->request_list, 0, sizeof(*iq->request_list) * num_descs);
-
dev_dbg(&oct->pci_dev->dev, "IQ[%d]: base: %p basedma: %pad count: %d\n",
iq_no, iq->base_addr, &iq->base_addr_dma, iq->max_count);
diff --git a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
index cbaa1924afbe..3e17ce0d2314 100644
--- a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
+++ b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
@@ -961,7 +961,7 @@ static int octeon_mgmt_init_phy(struct net_device *netdev)
PHY_INTERFACE_MODE_MII);
if (!phydev)
- return -ENODEV;
+ return -EPROBE_DEFER;
return 0;
}
@@ -1554,12 +1554,8 @@ static struct platform_driver octeon_mgmt_driver = {
.remove = octeon_mgmt_remove,
};
-extern void octeon_mdiobus_force_mod_depencency(void);
-
static int __init octeon_mgmt_mod_init(void)
{
- /* Force our mdiobus driver module to be loaded first. */
- octeon_mdiobus_force_mod_depencency();
return platform_driver_register(&octeon_mgmt_driver);
}
@@ -1571,6 +1567,7 @@ static void __exit octeon_mgmt_mod_exit(void)
module_init(octeon_mgmt_mod_init);
module_exit(octeon_mgmt_mod_exit);
+MODULE_SOFTDEP("pre: mdio-cavium");
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR("David Daney");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 2ba0ce115e63..c1378b5c780c 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -1906,9 +1906,6 @@ static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp)
switch (xdp->command) {
case XDP_SETUP_PROG:
return nicvf_xdp_setup(nic, xdp->prog);
- case XDP_QUERY_PROG:
- xdp->prog_id = nic->xdp_prog ? nic->xdp_prog->aux->id : 0;
- return 0;
default:
return -EINVAL;
}
@@ -2042,11 +2039,11 @@ static void nicvf_set_rx_mode_task(struct work_struct *work_arg)
/* Save message data locally to prevent them from
* being overwritten by next ndo_set_rx_mode call().
*/
- spin_lock(&nic->rx_mode_wq_lock);
+ spin_lock_bh(&nic->rx_mode_wq_lock);
mode = vf_work->mode;
mc = vf_work->mc;
vf_work->mc = NULL;
- spin_unlock(&nic->rx_mode_wq_lock);
+ spin_unlock_bh(&nic->rx_mode_wq_lock);
__nicvf_set_rx_mode_task(mode, mc, nic);
}
@@ -2180,6 +2177,9 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
nic->max_queues *= 2;
nic->ptp_clock = ptp_clock;
+ /* Initialize mutex that serializes usage of VF's mailbox */
+ mutex_init(&nic->rx_mode_mtx);
+
/* MAP VF's configuration registers */
nic->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
if (!nic->reg_base) {
@@ -2256,7 +2256,6 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
INIT_WORK(&nic->rx_mode_work.work, nicvf_set_rx_mode_task);
spin_lock_init(&nic->rx_mode_wq_lock);
- mutex_init(&nic->rx_mode_mtx);
err = register_netdev(netdev);
if (err) {
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index 069e7413f1ef..a45223f0cca5 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -1489,9 +1489,10 @@ static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq,
int seg_subdescs = 0, desc_cnt = 0;
int seg_len, total_len, data_left;
int hdr_qentry = qentry;
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ int hdr_len;
+
+ hdr_len = tso_start(skb, &tso);
- tso_start(skb, &tso);
total_len = skb->len - hdr_len;
while (total_len > 0) {
char *hdr;
diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig
index b7f43254598f..f6f3ef9a93cf 100644
--- a/drivers/net/ethernet/chelsio/Kconfig
+++ b/drivers/net/ethernet/chelsio/Kconfig
@@ -26,7 +26,7 @@ config CHELSIO_T1
This driver supports Chelsio gigabit and 10-gigabit
Ethernet cards. More information about adapter features and
performance tuning is in
- <file:Documentation/networking/device_drivers/chelsio/cxgb.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/chelsio/cxgb.rst>.
For general information about Chelsio and our products, visit
our website at <http://www.chelsio.com>.
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h b/drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h
index dcab94cc2dee..876f90e5795e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h
@@ -350,167 +350,6 @@ struct cudbg_qdesc_info {
#define IREG_NUM_ELEM 4
-static const u32 t6_tp_pio_array[][IREG_NUM_ELEM] = {
- {0x7e40, 0x7e44, 0x020, 28}, /* t6_tp_pio_regs_20_to_3b */
- {0x7e40, 0x7e44, 0x040, 10}, /* t6_tp_pio_regs_40_to_49 */
- {0x7e40, 0x7e44, 0x050, 10}, /* t6_tp_pio_regs_50_to_59 */
- {0x7e40, 0x7e44, 0x060, 14}, /* t6_tp_pio_regs_60_to_6d */
- {0x7e40, 0x7e44, 0x06F, 1}, /* t6_tp_pio_regs_6f */
- {0x7e40, 0x7e44, 0x070, 6}, /* t6_tp_pio_regs_70_to_75 */
- {0x7e40, 0x7e44, 0x130, 18}, /* t6_tp_pio_regs_130_to_141 */
- {0x7e40, 0x7e44, 0x145, 19}, /* t6_tp_pio_regs_145_to_157 */
- {0x7e40, 0x7e44, 0x160, 1}, /* t6_tp_pio_regs_160 */
- {0x7e40, 0x7e44, 0x230, 25}, /* t6_tp_pio_regs_230_to_248 */
- {0x7e40, 0x7e44, 0x24a, 3}, /* t6_tp_pio_regs_24c */
- {0x7e40, 0x7e44, 0x8C0, 1} /* t6_tp_pio_regs_8c0 */
-};
-
-static const u32 t5_tp_pio_array[][IREG_NUM_ELEM] = {
- {0x7e40, 0x7e44, 0x020, 28}, /* t5_tp_pio_regs_20_to_3b */
- {0x7e40, 0x7e44, 0x040, 19}, /* t5_tp_pio_regs_40_to_52 */
- {0x7e40, 0x7e44, 0x054, 2}, /* t5_tp_pio_regs_54_to_55 */
- {0x7e40, 0x7e44, 0x060, 13}, /* t5_tp_pio_regs_60_to_6c */
- {0x7e40, 0x7e44, 0x06F, 1}, /* t5_tp_pio_regs_6f */
- {0x7e40, 0x7e44, 0x120, 4}, /* t5_tp_pio_regs_120_to_123 */
- {0x7e40, 0x7e44, 0x12b, 2}, /* t5_tp_pio_regs_12b_to_12c */
- {0x7e40, 0x7e44, 0x12f, 21}, /* t5_tp_pio_regs_12f_to_143 */
- {0x7e40, 0x7e44, 0x145, 19}, /* t5_tp_pio_regs_145_to_157 */
- {0x7e40, 0x7e44, 0x230, 25}, /* t5_tp_pio_regs_230_to_248 */
- {0x7e40, 0x7e44, 0x8C0, 1} /* t5_tp_pio_regs_8c0 */
-};
-
-static const u32 t6_tp_tm_pio_array[][IREG_NUM_ELEM] = {
- {0x7e18, 0x7e1c, 0x0, 12}
-};
-
-static const u32 t5_tp_tm_pio_array[][IREG_NUM_ELEM] = {
- {0x7e18, 0x7e1c, 0x0, 12}
-};
-
-static const u32 t6_tp_mib_index_array[6][IREG_NUM_ELEM] = {
- {0x7e50, 0x7e54, 0x0, 13},
- {0x7e50, 0x7e54, 0x10, 6},
- {0x7e50, 0x7e54, 0x18, 21},
- {0x7e50, 0x7e54, 0x30, 32},
- {0x7e50, 0x7e54, 0x50, 22},
- {0x7e50, 0x7e54, 0x68, 12}
-};
-
-static const u32 t5_tp_mib_index_array[9][IREG_NUM_ELEM] = {
- {0x7e50, 0x7e54, 0x0, 13},
- {0x7e50, 0x7e54, 0x10, 6},
- {0x7e50, 0x7e54, 0x18, 8},
- {0x7e50, 0x7e54, 0x20, 13},
- {0x7e50, 0x7e54, 0x30, 16},
- {0x7e50, 0x7e54, 0x40, 16},
- {0x7e50, 0x7e54, 0x50, 16},
- {0x7e50, 0x7e54, 0x60, 6},
- {0x7e50, 0x7e54, 0x68, 4}
-};
-
-static const u32 t5_sge_dbg_index_array[2][IREG_NUM_ELEM] = {
- {0x10cc, 0x10d0, 0x0, 16},
- {0x10cc, 0x10d4, 0x0, 16},
-};
-
-static const u32 t6_sge_qbase_index_array[] = {
- /* 1 addr reg SGE_QBASE_INDEX and 4 data reg SGE_QBASE_MAP[0-3] */
- 0x1250, 0x1240, 0x1244, 0x1248, 0x124c,
-};
-
-static const u32 t5_pcie_pdbg_array[][IREG_NUM_ELEM] = {
- {0x5a04, 0x5a0c, 0x00, 0x20}, /* t5_pcie_pdbg_regs_00_to_20 */
- {0x5a04, 0x5a0c, 0x21, 0x20}, /* t5_pcie_pdbg_regs_21_to_40 */
- {0x5a04, 0x5a0c, 0x41, 0x10}, /* t5_pcie_pdbg_regs_41_to_50 */
-};
-
-static const u32 t5_pcie_cdbg_array[][IREG_NUM_ELEM] = {
- {0x5a10, 0x5a18, 0x00, 0x20}, /* t5_pcie_cdbg_regs_00_to_20 */
- {0x5a10, 0x5a18, 0x21, 0x18}, /* t5_pcie_cdbg_regs_21_to_37 */
-};
-
-static const u32 t5_pm_rx_array[][IREG_NUM_ELEM] = {
- {0x8FD0, 0x8FD4, 0x10000, 0x20}, /* t5_pm_rx_regs_10000_to_10020 */
- {0x8FD0, 0x8FD4, 0x10021, 0x0D}, /* t5_pm_rx_regs_10021_to_1002c */
-};
-
-static const u32 t5_pm_tx_array[][IREG_NUM_ELEM] = {
- {0x8FF0, 0x8FF4, 0x10000, 0x20}, /* t5_pm_tx_regs_10000_to_10020 */
- {0x8FF0, 0x8FF4, 0x10021, 0x1D}, /* t5_pm_tx_regs_10021_to_1003c */
-};
-
#define CUDBG_NUM_PCIE_CONFIG_REGS 0x61
-static const u32 t5_pcie_config_array[][2] = {
- {0x0, 0x34},
- {0x3c, 0x40},
- {0x50, 0x64},
- {0x70, 0x80},
- {0x94, 0xa0},
- {0xb0, 0xb8},
- {0xd0, 0xd4},
- {0x100, 0x128},
- {0x140, 0x148},
- {0x150, 0x164},
- {0x170, 0x178},
- {0x180, 0x194},
- {0x1a0, 0x1b8},
- {0x1c0, 0x208},
-};
-
-static const u32 t6_ma_ireg_array[][IREG_NUM_ELEM] = {
- {0x78f8, 0x78fc, 0xa000, 23}, /* t6_ma_regs_a000_to_a016 */
- {0x78f8, 0x78fc, 0xa400, 30}, /* t6_ma_regs_a400_to_a41e */
- {0x78f8, 0x78fc, 0xa800, 20} /* t6_ma_regs_a800_to_a813 */
-};
-
-static const u32 t6_ma_ireg_array2[][IREG_NUM_ELEM] = {
- {0x78f8, 0x78fc, 0xe400, 17}, /* t6_ma_regs_e400_to_e600 */
- {0x78f8, 0x78fc, 0xe640, 13} /* t6_ma_regs_e640_to_e7c0 */
-};
-
-static const u32 t6_up_cim_reg_array[][IREG_NUM_ELEM + 1] = {
- {0x7b50, 0x7b54, 0x2000, 0x20, 0}, /* up_cim_2000_to_207c */
- {0x7b50, 0x7b54, 0x2080, 0x1d, 0}, /* up_cim_2080_to_20fc */
- {0x7b50, 0x7b54, 0x00, 0x20, 0}, /* up_cim_00_to_7c */
- {0x7b50, 0x7b54, 0x80, 0x20, 0}, /* up_cim_80_to_fc */
- {0x7b50, 0x7b54, 0x100, 0x11, 0}, /* up_cim_100_to_14c */
- {0x7b50, 0x7b54, 0x200, 0x10, 0}, /* up_cim_200_to_23c */
- {0x7b50, 0x7b54, 0x240, 0x2, 0}, /* up_cim_240_to_244 */
- {0x7b50, 0x7b54, 0x250, 0x2, 0}, /* up_cim_250_to_254 */
- {0x7b50, 0x7b54, 0x260, 0x2, 0}, /* up_cim_260_to_264 */
- {0x7b50, 0x7b54, 0x270, 0x2, 0}, /* up_cim_270_to_274 */
- {0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */
- {0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */
- {0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */
- {0x7b50, 0x7b54, 0x4900, 0x4, 0x4}, /* up_cim_4900_to_4c60 */
- {0x7b50, 0x7b54, 0x4904, 0x4, 0x4}, /* up_cim_4904_to_4c64 */
- {0x7b50, 0x7b54, 0x4908, 0x4, 0x4}, /* up_cim_4908_to_4c68 */
- {0x7b50, 0x7b54, 0x4910, 0x4, 0x4}, /* up_cim_4910_to_4c70 */
- {0x7b50, 0x7b54, 0x4914, 0x4, 0x4}, /* up_cim_4914_to_4c74 */
- {0x7b50, 0x7b54, 0x4920, 0x10, 0x10}, /* up_cim_4920_to_4a10 */
- {0x7b50, 0x7b54, 0x4924, 0x10, 0x10}, /* up_cim_4924_to_4a14 */
- {0x7b50, 0x7b54, 0x4928, 0x10, 0x10}, /* up_cim_4928_to_4a18 */
- {0x7b50, 0x7b54, 0x492c, 0x10, 0x10}, /* up_cim_492c_to_4a1c */
-};
-
-static const u32 t5_up_cim_reg_array[][IREG_NUM_ELEM + 1] = {
- {0x7b50, 0x7b54, 0x2000, 0x20, 0}, /* up_cim_2000_to_207c */
- {0x7b50, 0x7b54, 0x2080, 0x19, 0}, /* up_cim_2080_to_20ec */
- {0x7b50, 0x7b54, 0x00, 0x20, 0}, /* up_cim_00_to_7c */
- {0x7b50, 0x7b54, 0x80, 0x20, 0}, /* up_cim_80_to_fc */
- {0x7b50, 0x7b54, 0x100, 0x11, 0}, /* up_cim_100_to_14c */
- {0x7b50, 0x7b54, 0x200, 0x10, 0}, /* up_cim_200_to_23c */
- {0x7b50, 0x7b54, 0x240, 0x2, 0}, /* up_cim_240_to_244 */
- {0x7b50, 0x7b54, 0x250, 0x2, 0}, /* up_cim_250_to_254 */
- {0x7b50, 0x7b54, 0x260, 0x2, 0}, /* up_cim_260_to_264 */
- {0x7b50, 0x7b54, 0x270, 0x2, 0}, /* up_cim_270_to_274 */
- {0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */
- {0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */
- {0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */
-};
-
-static const u32 t6_hma_ireg_array[][IREG_NUM_ELEM] = {
- {0x51320, 0x51324, 0xa000, 32} /* t6_hma_regs_a000_to_a01f */
-};
#endif /* __CUDBG_ENTITY_H__ */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h b/drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h
index fc3813050f0d..c84719e3ca08 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_if.h
@@ -70,7 +70,8 @@ enum cudbg_dbg_entity_type {
CUDBG_HMA_INDIRECT = 67,
CUDBG_HMA = 68,
CUDBG_QDESC = 70,
- CUDBG_MAX_ENTITY = 71,
+ CUDBG_FLASH = 71,
+ CUDBG_MAX_ENTITY = 72,
};
struct cudbg_init {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
index d8ab8e366818..75474f810249 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
@@ -15,6 +15,412 @@
#include "cudbg_lib.h"
#include "cudbg_zlib.h"
+static const u32 t6_tp_pio_array[][IREG_NUM_ELEM] = {
+ {0x7e40, 0x7e44, 0x020, 28}, /* t6_tp_pio_regs_20_to_3b */
+ {0x7e40, 0x7e44, 0x040, 10}, /* t6_tp_pio_regs_40_to_49 */
+ {0x7e40, 0x7e44, 0x050, 10}, /* t6_tp_pio_regs_50_to_59 */
+ {0x7e40, 0x7e44, 0x060, 14}, /* t6_tp_pio_regs_60_to_6d */
+ {0x7e40, 0x7e44, 0x06F, 1}, /* t6_tp_pio_regs_6f */
+ {0x7e40, 0x7e44, 0x070, 6}, /* t6_tp_pio_regs_70_to_75 */
+ {0x7e40, 0x7e44, 0x130, 18}, /* t6_tp_pio_regs_130_to_141 */
+ {0x7e40, 0x7e44, 0x145, 19}, /* t6_tp_pio_regs_145_to_157 */
+ {0x7e40, 0x7e44, 0x160, 1}, /* t6_tp_pio_regs_160 */
+ {0x7e40, 0x7e44, 0x230, 25}, /* t6_tp_pio_regs_230_to_248 */
+ {0x7e40, 0x7e44, 0x24a, 3}, /* t6_tp_pio_regs_24c */
+ {0x7e40, 0x7e44, 0x8C0, 1} /* t6_tp_pio_regs_8c0 */
+};
+
+static const u32 t5_tp_pio_array[][IREG_NUM_ELEM] = {
+ {0x7e40, 0x7e44, 0x020, 28}, /* t5_tp_pio_regs_20_to_3b */
+ {0x7e40, 0x7e44, 0x040, 19}, /* t5_tp_pio_regs_40_to_52 */
+ {0x7e40, 0x7e44, 0x054, 2}, /* t5_tp_pio_regs_54_to_55 */
+ {0x7e40, 0x7e44, 0x060, 13}, /* t5_tp_pio_regs_60_to_6c */
+ {0x7e40, 0x7e44, 0x06F, 1}, /* t5_tp_pio_regs_6f */
+ {0x7e40, 0x7e44, 0x120, 4}, /* t5_tp_pio_regs_120_to_123 */
+ {0x7e40, 0x7e44, 0x12b, 2}, /* t5_tp_pio_regs_12b_to_12c */
+ {0x7e40, 0x7e44, 0x12f, 21}, /* t5_tp_pio_regs_12f_to_143 */
+ {0x7e40, 0x7e44, 0x145, 19}, /* t5_tp_pio_regs_145_to_157 */
+ {0x7e40, 0x7e44, 0x230, 25}, /* t5_tp_pio_regs_230_to_248 */
+ {0x7e40, 0x7e44, 0x8C0, 1} /* t5_tp_pio_regs_8c0 */
+};
+
+static const u32 t6_tp_tm_pio_array[][IREG_NUM_ELEM] = {
+ {0x7e18, 0x7e1c, 0x0, 12}
+};
+
+static const u32 t5_tp_tm_pio_array[][IREG_NUM_ELEM] = {
+ {0x7e18, 0x7e1c, 0x0, 12}
+};
+
+static const u32 t6_tp_mib_index_array[6][IREG_NUM_ELEM] = {
+ {0x7e50, 0x7e54, 0x0, 13},
+ {0x7e50, 0x7e54, 0x10, 6},
+ {0x7e50, 0x7e54, 0x18, 21},
+ {0x7e50, 0x7e54, 0x30, 32},
+ {0x7e50, 0x7e54, 0x50, 22},
+ {0x7e50, 0x7e54, 0x68, 12}
+};
+
+static const u32 t5_tp_mib_index_array[9][IREG_NUM_ELEM] = {
+ {0x7e50, 0x7e54, 0x0, 13},
+ {0x7e50, 0x7e54, 0x10, 6},
+ {0x7e50, 0x7e54, 0x18, 8},
+ {0x7e50, 0x7e54, 0x20, 13},
+ {0x7e50, 0x7e54, 0x30, 16},
+ {0x7e50, 0x7e54, 0x40, 16},
+ {0x7e50, 0x7e54, 0x50, 16},
+ {0x7e50, 0x7e54, 0x60, 6},
+ {0x7e50, 0x7e54, 0x68, 4}
+};
+
+static const u32 t5_sge_dbg_index_array[2][IREG_NUM_ELEM] = {
+ {0x10cc, 0x10d0, 0x0, 16},
+ {0x10cc, 0x10d4, 0x0, 16},
+};
+
+static const u32 t6_sge_qbase_index_array[] = {
+ /* 1 addr reg SGE_QBASE_INDEX and 4 data reg SGE_QBASE_MAP[0-3] */
+ 0x1250, 0x1240, 0x1244, 0x1248, 0x124c,
+};
+
+static const u32 t5_pcie_pdbg_array[][IREG_NUM_ELEM] = {
+ {0x5a04, 0x5a0c, 0x00, 0x20}, /* t5_pcie_pdbg_regs_00_to_20 */
+ {0x5a04, 0x5a0c, 0x21, 0x20}, /* t5_pcie_pdbg_regs_21_to_40 */
+ {0x5a04, 0x5a0c, 0x41, 0x10}, /* t5_pcie_pdbg_regs_41_to_50 */
+};
+
+static const u32 t5_pcie_cdbg_array[][IREG_NUM_ELEM] = {
+ {0x5a10, 0x5a18, 0x00, 0x20}, /* t5_pcie_cdbg_regs_00_to_20 */
+ {0x5a10, 0x5a18, 0x21, 0x18}, /* t5_pcie_cdbg_regs_21_to_37 */
+};
+
+static const u32 t5_pm_rx_array[][IREG_NUM_ELEM] = {
+ {0x8FD0, 0x8FD4, 0x10000, 0x20}, /* t5_pm_rx_regs_10000_to_10020 */
+ {0x8FD0, 0x8FD4, 0x10021, 0x0D}, /* t5_pm_rx_regs_10021_to_1002c */
+};
+
+static const u32 t5_pm_tx_array[][IREG_NUM_ELEM] = {
+ {0x8FF0, 0x8FF4, 0x10000, 0x20}, /* t5_pm_tx_regs_10000_to_10020 */
+ {0x8FF0, 0x8FF4, 0x10021, 0x1D}, /* t5_pm_tx_regs_10021_to_1003c */
+};
+
+static const u32 t5_pcie_config_array[][2] = {
+ {0x0, 0x34},
+ {0x3c, 0x40},
+ {0x50, 0x64},
+ {0x70, 0x80},
+ {0x94, 0xa0},
+ {0xb0, 0xb8},
+ {0xd0, 0xd4},
+ {0x100, 0x128},
+ {0x140, 0x148},
+ {0x150, 0x164},
+ {0x170, 0x178},
+ {0x180, 0x194},
+ {0x1a0, 0x1b8},
+ {0x1c0, 0x208},
+};
+
+static const u32 t6_ma_ireg_array[][IREG_NUM_ELEM] = {
+ {0x78f8, 0x78fc, 0xa000, 23}, /* t6_ma_regs_a000_to_a016 */
+ {0x78f8, 0x78fc, 0xa400, 30}, /* t6_ma_regs_a400_to_a41e */
+ {0x78f8, 0x78fc, 0xa800, 20} /* t6_ma_regs_a800_to_a813 */
+};
+
+static const u32 t6_ma_ireg_array2[][IREG_NUM_ELEM] = {
+ {0x78f8, 0x78fc, 0xe400, 17}, /* t6_ma_regs_e400_to_e600 */
+ {0x78f8, 0x78fc, 0xe640, 13} /* t6_ma_regs_e640_to_e7c0 */
+};
+
+static const u32 t6_up_cim_reg_array[][IREG_NUM_ELEM + 1] = {
+ {0x7b50, 0x7b54, 0x2000, 0x20, 0}, /* up_cim_2000_to_207c */
+ {0x7b50, 0x7b54, 0x2080, 0x1d, 0}, /* up_cim_2080_to_20fc */
+ {0x7b50, 0x7b54, 0x00, 0x20, 0}, /* up_cim_00_to_7c */
+ {0x7b50, 0x7b54, 0x80, 0x20, 0}, /* up_cim_80_to_fc */
+ {0x7b50, 0x7b54, 0x100, 0x11, 0}, /* up_cim_100_to_14c */
+ {0x7b50, 0x7b54, 0x200, 0x10, 0}, /* up_cim_200_to_23c */
+ {0x7b50, 0x7b54, 0x240, 0x2, 0}, /* up_cim_240_to_244 */
+ {0x7b50, 0x7b54, 0x250, 0x2, 0}, /* up_cim_250_to_254 */
+ {0x7b50, 0x7b54, 0x260, 0x2, 0}, /* up_cim_260_to_264 */
+ {0x7b50, 0x7b54, 0x270, 0x2, 0}, /* up_cim_270_to_274 */
+ {0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */
+ {0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */
+ {0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */
+ {0x7b50, 0x7b54, 0x4900, 0x4, 0x4}, /* up_cim_4900_to_4c60 */
+ {0x7b50, 0x7b54, 0x4904, 0x4, 0x4}, /* up_cim_4904_to_4c64 */
+ {0x7b50, 0x7b54, 0x4908, 0x4, 0x4}, /* up_cim_4908_to_4c68 */
+ {0x7b50, 0x7b54, 0x4910, 0x4, 0x4}, /* up_cim_4910_to_4c70 */
+ {0x7b50, 0x7b54, 0x4914, 0x4, 0x4}, /* up_cim_4914_to_4c74 */
+ {0x7b50, 0x7b54, 0x4920, 0x10, 0x10}, /* up_cim_4920_to_4a10 */
+ {0x7b50, 0x7b54, 0x4924, 0x10, 0x10}, /* up_cim_4924_to_4a14 */
+ {0x7b50, 0x7b54, 0x4928, 0x10, 0x10}, /* up_cim_4928_to_4a18 */
+ {0x7b50, 0x7b54, 0x492c, 0x10, 0x10}, /* up_cim_492c_to_4a1c */
+};
+
+static const u32 t5_up_cim_reg_array[][IREG_NUM_ELEM + 1] = {
+ {0x7b50, 0x7b54, 0x2000, 0x20, 0}, /* up_cim_2000_to_207c */
+ {0x7b50, 0x7b54, 0x2080, 0x19, 0}, /* up_cim_2080_to_20ec */
+ {0x7b50, 0x7b54, 0x00, 0x20, 0}, /* up_cim_00_to_7c */
+ {0x7b50, 0x7b54, 0x80, 0x20, 0}, /* up_cim_80_to_fc */
+ {0x7b50, 0x7b54, 0x100, 0x11, 0}, /* up_cim_100_to_14c */
+ {0x7b50, 0x7b54, 0x200, 0x10, 0}, /* up_cim_200_to_23c */
+ {0x7b50, 0x7b54, 0x240, 0x2, 0}, /* up_cim_240_to_244 */
+ {0x7b50, 0x7b54, 0x250, 0x2, 0}, /* up_cim_250_to_254 */
+ {0x7b50, 0x7b54, 0x260, 0x2, 0}, /* up_cim_260_to_264 */
+ {0x7b50, 0x7b54, 0x270, 0x2, 0}, /* up_cim_270_to_274 */
+ {0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */
+ {0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */
+ {0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */
+};
+
+static const u32 t6_hma_ireg_array[][IREG_NUM_ELEM] = {
+ {0x51320, 0x51324, 0xa000, 32} /* t6_hma_regs_a000_to_a01f */
+};
+
+u32 cudbg_get_entity_length(struct adapter *adap, u32 entity)
+{
+ struct cudbg_tcam tcam_region = { 0 };
+ u32 value, n = 0, len = 0;
+
+ switch (entity) {
+ case CUDBG_REG_DUMP:
+ switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
+ case CHELSIO_T4:
+ len = T4_REGMAP_SIZE;
+ break;
+ case CHELSIO_T5:
+ case CHELSIO_T6:
+ len = T5_REGMAP_SIZE;
+ break;
+ default:
+ break;
+ }
+ break;
+ case CUDBG_DEV_LOG:
+ len = adap->params.devlog.size;
+ break;
+ case CUDBG_CIM_LA:
+ if (is_t6(adap->params.chip)) {
+ len = adap->params.cim_la_size / 10 + 1;
+ len *= 10 * sizeof(u32);
+ } else {
+ len = adap->params.cim_la_size / 8;
+ len *= 8 * sizeof(u32);
+ }
+ len += sizeof(u32); /* for reading CIM LA configuration */
+ break;
+ case CUDBG_CIM_MA_LA:
+ len = 2 * CIM_MALA_SIZE * 5 * sizeof(u32);
+ break;
+ case CUDBG_CIM_QCFG:
+ len = sizeof(struct cudbg_cim_qcfg);
+ break;
+ case CUDBG_CIM_IBQ_TP0:
+ case CUDBG_CIM_IBQ_TP1:
+ case CUDBG_CIM_IBQ_ULP:
+ case CUDBG_CIM_IBQ_SGE0:
+ case CUDBG_CIM_IBQ_SGE1:
+ case CUDBG_CIM_IBQ_NCSI:
+ len = CIM_IBQ_SIZE * 4 * sizeof(u32);
+ break;
+ case CUDBG_CIM_OBQ_ULP0:
+ len = cudbg_cim_obq_size(adap, 0);
+ break;
+ case CUDBG_CIM_OBQ_ULP1:
+ len = cudbg_cim_obq_size(adap, 1);
+ break;
+ case CUDBG_CIM_OBQ_ULP2:
+ len = cudbg_cim_obq_size(adap, 2);
+ break;
+ case CUDBG_CIM_OBQ_ULP3:
+ len = cudbg_cim_obq_size(adap, 3);
+ break;
+ case CUDBG_CIM_OBQ_SGE:
+ len = cudbg_cim_obq_size(adap, 4);
+ break;
+ case CUDBG_CIM_OBQ_NCSI:
+ len = cudbg_cim_obq_size(adap, 5);
+ break;
+ case CUDBG_CIM_OBQ_RXQ0:
+ len = cudbg_cim_obq_size(adap, 6);
+ break;
+ case CUDBG_CIM_OBQ_RXQ1:
+ len = cudbg_cim_obq_size(adap, 7);
+ break;
+ case CUDBG_EDC0:
+ value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
+ if (value & EDRAM0_ENABLE_F) {
+ value = t4_read_reg(adap, MA_EDRAM0_BAR_A);
+ len = EDRAM0_SIZE_G(value);
+ }
+ len = cudbg_mbytes_to_bytes(len);
+ break;
+ case CUDBG_EDC1:
+ value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
+ if (value & EDRAM1_ENABLE_F) {
+ value = t4_read_reg(adap, MA_EDRAM1_BAR_A);
+ len = EDRAM1_SIZE_G(value);
+ }
+ len = cudbg_mbytes_to_bytes(len);
+ break;
+ case CUDBG_MC0:
+ value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
+ if (value & EXT_MEM0_ENABLE_F) {
+ value = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A);
+ len = EXT_MEM0_SIZE_G(value);
+ }
+ len = cudbg_mbytes_to_bytes(len);
+ break;
+ case CUDBG_MC1:
+ value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
+ if (value & EXT_MEM1_ENABLE_F) {
+ value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
+ len = EXT_MEM1_SIZE_G(value);
+ }
+ len = cudbg_mbytes_to_bytes(len);
+ break;
+ case CUDBG_RSS:
+ len = t4_chip_rss_size(adap) * sizeof(u16);
+ break;
+ case CUDBG_RSS_VF_CONF:
+ len = adap->params.arch.vfcount *
+ sizeof(struct cudbg_rss_vf_conf);
+ break;
+ case CUDBG_PATH_MTU:
+ len = NMTUS * sizeof(u16);
+ break;
+ case CUDBG_PM_STATS:
+ len = sizeof(struct cudbg_pm_stats);
+ break;
+ case CUDBG_HW_SCHED:
+ len = sizeof(struct cudbg_hw_sched);
+ break;
+ case CUDBG_TP_INDIRECT:
+ switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
+ case CHELSIO_T5:
+ n = sizeof(t5_tp_pio_array) +
+ sizeof(t5_tp_tm_pio_array) +
+ sizeof(t5_tp_mib_index_array);
+ break;
+ case CHELSIO_T6:
+ n = sizeof(t6_tp_pio_array) +
+ sizeof(t6_tp_tm_pio_array) +
+ sizeof(t6_tp_mib_index_array);
+ break;
+ default:
+ break;
+ }
+ n = n / (IREG_NUM_ELEM * sizeof(u32));
+ len = sizeof(struct ireg_buf) * n;
+ break;
+ case CUDBG_SGE_INDIRECT:
+ len = sizeof(struct ireg_buf) * 2 +
+ sizeof(struct sge_qbase_reg_field);
+ break;
+ case CUDBG_ULPRX_LA:
+ len = sizeof(struct cudbg_ulprx_la);
+ break;
+ case CUDBG_TP_LA:
+ len = sizeof(struct cudbg_tp_la) + TPLA_SIZE * sizeof(u64);
+ break;
+ case CUDBG_MEMINFO:
+ len = sizeof(struct cudbg_ver_hdr) +
+ sizeof(struct cudbg_meminfo);
+ break;
+ case CUDBG_CIM_PIF_LA:
+ len = sizeof(struct cudbg_cim_pif_la);
+ len += 2 * CIM_PIFLA_SIZE * 6 * sizeof(u32);
+ break;
+ case CUDBG_CLK:
+ len = sizeof(struct cudbg_clk_info);
+ break;
+ case CUDBG_PCIE_INDIRECT:
+ n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32));
+ len = sizeof(struct ireg_buf) * n * 2;
+ break;
+ case CUDBG_PM_INDIRECT:
+ n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32));
+ len = sizeof(struct ireg_buf) * n * 2;
+ break;
+ case CUDBG_TID_INFO:
+ len = sizeof(struct cudbg_tid_info_region_rev1);
+ break;
+ case CUDBG_PCIE_CONFIG:
+ len = sizeof(u32) * CUDBG_NUM_PCIE_CONFIG_REGS;
+ break;
+ case CUDBG_DUMP_CONTEXT:
+ len = cudbg_dump_context_size(adap);
+ break;
+ case CUDBG_MPS_TCAM:
+ len = sizeof(struct cudbg_mps_tcam) *
+ adap->params.arch.mps_tcam_size;
+ break;
+ case CUDBG_VPD_DATA:
+ len = sizeof(struct cudbg_vpd_data);
+ break;
+ case CUDBG_LE_TCAM:
+ cudbg_fill_le_tcam_info(adap, &tcam_region);
+ len = sizeof(struct cudbg_tcam) +
+ sizeof(struct cudbg_tid_data) * tcam_region.max_tid;
+ break;
+ case CUDBG_CCTRL:
+ len = sizeof(u16) * NMTUS * NCCTRL_WIN;
+ break;
+ case CUDBG_MA_INDIRECT:
+ if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
+ n = sizeof(t6_ma_ireg_array) /
+ (IREG_NUM_ELEM * sizeof(u32));
+ len = sizeof(struct ireg_buf) * n * 2;
+ }
+ break;
+ case CUDBG_ULPTX_LA:
+ len = sizeof(struct cudbg_ver_hdr) +
+ sizeof(struct cudbg_ulptx_la);
+ break;
+ case CUDBG_UP_CIM_INDIRECT:
+ n = 0;
+ if (is_t5(adap->params.chip))
+ n = sizeof(t5_up_cim_reg_array) /
+ ((IREG_NUM_ELEM + 1) * sizeof(u32));
+ else if (is_t6(adap->params.chip))
+ n = sizeof(t6_up_cim_reg_array) /
+ ((IREG_NUM_ELEM + 1) * sizeof(u32));
+ len = sizeof(struct ireg_buf) * n;
+ break;
+ case CUDBG_PBT_TABLE:
+ len = sizeof(struct cudbg_pbt_tables);
+ break;
+ case CUDBG_MBOX_LOG:
+ len = sizeof(struct cudbg_mbox_log) * adap->mbox_log->size;
+ break;
+ case CUDBG_HMA_INDIRECT:
+ if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
+ n = sizeof(t6_hma_ireg_array) /
+ (IREG_NUM_ELEM * sizeof(u32));
+ len = sizeof(struct ireg_buf) * n;
+ }
+ break;
+ case CUDBG_HMA:
+ value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
+ if (value & HMA_MUX_F) {
+ /* In T6, there's no MC1. So, HMA shares MC1
+ * address space.
+ */
+ value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
+ len = EXT_MEM1_SIZE_G(value);
+ }
+ len = cudbg_mbytes_to_bytes(len);
+ break;
+ case CUDBG_QDESC:
+ cudbg_fill_qdesc_num_and_size(adap, NULL, &len);
+ break;
+ default:
+ break;
+ }
+
+ return len;
+}
+
static int cudbg_do_compression(struct cudbg_init *pdbg_init,
struct cudbg_buffer *pin_buff,
struct cudbg_buffer *dbg_buff)
@@ -3158,3 +3564,40 @@ out_free:
return rc;
}
+
+int cudbg_collect_flash(struct cudbg_init *pdbg_init,
+ struct cudbg_buffer *dbg_buff,
+ struct cudbg_error *cudbg_err)
+{
+ struct adapter *padap = pdbg_init->adap;
+ u32 count = padap->params.sf_size, n;
+ struct cudbg_buffer temp_buff = {0};
+ u32 addr, i;
+ int rc;
+
+ addr = FLASH_EXP_ROM_START;
+
+ for (i = 0; i < count; i += SF_PAGE_SIZE) {
+ n = min_t(u32, count - i, SF_PAGE_SIZE);
+
+ rc = cudbg_get_buff(pdbg_init, dbg_buff, n, &temp_buff);
+ if (rc) {
+ cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;
+ goto out;
+ }
+ rc = t4_read_flash(padap, addr, n, (u32 *)temp_buff.data, 0);
+ if (rc)
+ goto out;
+
+ addr += (n * 4);
+ rc = cudbg_write_and_release_buff(pdbg_init, &temp_buff,
+ dbg_buff);
+ if (rc) {
+ cudbg_err->sys_warn = CUDBG_STATUS_PARTIAL_DATA;
+ goto out;
+ }
+ }
+
+out:
+ return rc;
+}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.h b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.h
index 10ee6ed1d932..d6d6cd298930 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.h
@@ -162,7 +162,11 @@ int cudbg_collect_hma_meminfo(struct cudbg_init *pdbg_init,
int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,
struct cudbg_buffer *dbg_buff,
struct cudbg_error *cudbg_err);
+int cudbg_collect_flash(struct cudbg_init *pdbg_init,
+ struct cudbg_buffer *dbg_buff,
+ struct cudbg_error *cudbg_err);
+u32 cudbg_get_entity_length(struct adapter *adap, u32 entity);
struct cudbg_entity_hdr *cudbg_get_entity_hdr(void *outbuf, int i);
void cudbg_align_debug_buffer(struct cudbg_buffer *dbg_buff,
struct cudbg_entity_hdr *entity_hdr);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index cf69c6edcfec..9cb8b229c1b3 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -139,6 +139,64 @@ enum cc_fec {
FEC_BASER_RS = 1 << 2 /* BaseR/Reed-Solomon */
};
+enum {
+ CXGB4_ETHTOOL_FLASH_FW = 1,
+ CXGB4_ETHTOOL_FLASH_PHY = 2,
+ CXGB4_ETHTOOL_FLASH_BOOT = 3,
+ CXGB4_ETHTOOL_FLASH_BOOTCFG = 4
+};
+
+struct cxgb4_bootcfg_data {
+ __le16 signature;
+ __u8 reserved[2];
+};
+
+struct cxgb4_pcir_data {
+ __le32 signature; /* Signature. The string "PCIR" */
+ __le16 vendor_id; /* Vendor Identification */
+ __le16 device_id; /* Device Identification */
+ __u8 vital_product[2]; /* Pointer to Vital Product Data */
+ __u8 length[2]; /* PCIR Data Structure Length */
+ __u8 revision; /* PCIR Data Structure Revision */
+ __u8 class_code[3]; /* Class Code */
+ __u8 image_length[2]; /* Image Length. Multiple of 512B */
+ __u8 code_revision[2]; /* Revision Level of Code/Data */
+ __u8 code_type;
+ __u8 indicator;
+ __u8 reserved[2];
+};
+
+/* BIOS boot headers */
+struct cxgb4_pci_exp_rom_header {
+ __le16 signature; /* ROM Signature. Should be 0xaa55 */
+ __u8 reserved[22]; /* Reserved per processor Architecture data */
+ __le16 pcir_offset; /* Offset to PCI Data Structure */
+};
+
+/* Legacy PCI Expansion ROM Header */
+struct legacy_pci_rom_hdr {
+ __u8 signature[2]; /* ROM Signature. Should be 0xaa55 */
+ __u8 size512; /* Current Image Size in units of 512 bytes */
+ __u8 initentry_point[4];
+ __u8 cksum; /* Checksum computed on the entire Image */
+ __u8 reserved[16]; /* Reserved */
+ __le16 pcir_offset; /* Offset to PCI Data Struture */
+};
+
+#define CXGB4_HDR_CODE1 0x00
+#define CXGB4_HDR_CODE2 0x03
+#define CXGB4_HDR_INDI 0x80
+
+/* BOOT constants */
+enum {
+ BOOT_CFG_SIG = 0x4243,
+ BOOT_SIZE_INC = 512,
+ BOOT_SIGNATURE = 0xaa55,
+ BOOT_MIN_SIZE = sizeof(struct cxgb4_pci_exp_rom_header),
+ BOOT_MAX_SIZE = 1024 * BOOT_SIZE_INC,
+ PCIR_SIGNATURE = 0x52494350
+};
+
struct port_stats {
u64 tx_octets; /* total # of octets in good frames */
u64 tx_frames; /* all good frames */
@@ -474,6 +532,12 @@ static inline struct mbox_cmd *mbox_cmd_log_entry(struct mbox_cmd_log *log,
FW_HDR_FW_VER_BUILD_G(chip##FW_VERSION_BUILD))
#define FW_INTFVER(chip, intf) (FW_HDR_INTFVER_##intf)
+struct cxgb4_ethtool_lb_test {
+ struct completion completion;
+ int result;
+ int loopback;
+};
+
struct fw_info {
u8 chip;
char *fs_name;
@@ -492,6 +556,11 @@ struct trace_params {
unsigned char port;
};
+struct cxgb4_fw_data {
+ __be32 signature;
+ __u8 reserved[4];
+};
+
/* Firmware Port Capabilities types. */
typedef u16 fw_port_cap16_t; /* 16-bit Port Capabilities integral value */
@@ -616,6 +685,13 @@ struct port_info {
u8 rx_cchan;
bool tc_block_shared;
+
+ /* Mirror VI information */
+ u16 viid_mirror;
+ u16 nmirrorqsets;
+ u32 vi_mirror_count;
+ struct mutex vi_mirror_mutex; /* Sync access to Mirror VI info */
+ struct cxgb4_ethtool_lb_test ethtool_lb;
};
struct dentry;
@@ -642,6 +718,13 @@ enum {
ULP_CRYPTO_KTLS_INLINE = 1 << 3,
};
+#define CXGB4_MIRROR_RXQ_DEFAULT_DESC_NUM 1024
+#define CXGB4_MIRROR_RXQ_DEFAULT_DESC_SIZE 64
+#define CXGB4_MIRROR_RXQ_DEFAULT_INTR_USEC 5
+#define CXGB4_MIRROR_RXQ_DEFAULT_PKT_CNT 8
+
+#define CXGB4_MIRROR_FLQ_DEFAULT_DESC_NUM 72
+
struct rx_sw_desc;
struct sge_fl { /* SGE free-buffer queue state */
@@ -891,12 +974,15 @@ struct sge {
struct sge_eohw_txq *eohw_txq;
struct sge_ofld_rxq *eohw_rxq;
+ struct sge_eth_rxq *mirror_rxq[NCHAN];
+
u16 max_ethqsets; /* # of available Ethernet queue sets */
u16 ethqsets; /* # of active Ethernet queue sets */
u16 ethtxq_rover; /* Tx queue to clean up next */
u16 ofldqsets; /* # of active ofld queue sets */
u16 nqs_per_uld; /* # of Rx queues per ULD */
u16 eoqsets; /* # of ETHOFLD queues */
+ u16 mirrorqsets; /* # of Mirror queues */
u16 timer_val[SGE_NTIMERS];
u8 counter_val[SGE_NCOUNTERS];
@@ -1003,6 +1089,17 @@ struct mps_entries_ref {
refcount_t refcnt;
};
+struct cxgb4_ethtool_filter_info {
+ u32 *loc_array; /* Array holding the actual TIDs set to filters */
+ unsigned long *bmap; /* Bitmap for managing filters in use */
+ u32 in_use; /* # of filters in use */
+};
+
+struct cxgb4_ethtool_filter {
+ u32 nentries; /* Adapter wide number of supported filters */
+ struct cxgb4_ethtool_filter_info *port; /* Per port entry */
+};
+
struct adapter {
void __iomem *regs;
void __iomem *bar2;
@@ -1019,9 +1116,7 @@ struct adapter {
int msg_enable;
__be16 vxlan_port;
- u8 vxlan_port_cnt;
__be16 geneve_port;
- u8 geneve_port_cnt;
struct adapter_params params;
struct cxgb4_virt_res vres;
@@ -1128,6 +1223,9 @@ struct adapter {
/* TC MATCHALL classifier offload */
struct cxgb4_tc_matchall *tc_matchall;
+
+ /* Ethtool n-tuple */
+ struct cxgb4_ethtool_filter *ethtool_filters;
};
/* Support for "sched-class" command to allow a TX Scheduling Class to be
@@ -1340,6 +1438,8 @@ enum {
NAT_MODE_ALL /* NAT on entire 4-tuple */
};
+#define CXGB4_FILTER_TYPE_MAX 2
+
/* Host shadow copy of ingress filter entry. This is in host native format
* and doesn't match the ordering or bit order, etc. of the hardware of the
* firmware command. The use of bit-field structure elements is purely to
@@ -1504,6 +1604,7 @@ void t4_free_sge_resources(struct adapter *adap);
void t4_free_ofld_rxqs(struct adapter *adap, int n, struct sge_ofld_rxq *q);
irq_handler_t t4_intr_handler(struct adapter *adap);
netdev_tx_t t4_start_xmit(struct sk_buff *skb, struct net_device *dev);
+int cxgb4_selftest_lb_pkt(struct net_device *netdev);
int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
const struct pkt_gl *gl);
int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb);
@@ -1736,8 +1837,7 @@ int t4_get_pfres(struct adapter *adapter);
int t4_read_flash(struct adapter *adapter, unsigned int addr,
unsigned int nwords, u32 *data, int byte_oriented);
int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
-int t4_load_phy_fw(struct adapter *adap,
- int win, spinlock_t *lock,
+int t4_load_phy_fw(struct adapter *adap, int win,
int (*phy_fw_version)(const u8 *, size_t),
const u8 *phy_fw_data, size_t phy_fw_size);
int t4_phy_fw_ver(struct adapter *adap, int *phy_fw_ver);
@@ -1781,6 +1881,8 @@ int t4_init_rss_mode(struct adapter *adap, int mbox);
int t4_init_portinfo(struct port_info *pi, int mbox,
int port, int pf, int vf, u8 mac[]);
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
+int t4_init_port_mirror(struct port_info *pi, u8 mbox, u8 port, u8 pf, u8 vf,
+ u16 *mirror_viid);
void t4_fatal_err(struct adapter *adapter);
unsigned int t4_chip_rss_size(struct adapter *adapter);
int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
@@ -1890,8 +1992,8 @@ int t4_free_vi(struct adapter *adap, unsigned int mbox,
unsigned int pf, unsigned int vf,
unsigned int viid);
int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
- int mtu, int promisc, int all_multi, int bcast, int vlanex,
- bool sleep_ok);
+ unsigned int viid_mirror, int mtu, int promisc, int all_multi,
+ int bcast, int vlanex, bool sleep_ok);
int t4_free_raw_mac_filt(struct adapter *adap, unsigned int viid,
const u8 *addr, const u8 *mask, unsigned int idx,
u8 lookup_type, u8 port_id, bool sleep_ok);
@@ -1988,6 +2090,10 @@ void t4_register_netevent_notifier(void);
int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
unsigned int devid, unsigned int offset,
unsigned int len, u8 *buf);
+int t4_load_boot(struct adapter *adap, u8 *boot_data,
+ unsigned int boot_addr, unsigned int size);
+int t4_load_bootcfg(struct adapter *adap,
+ const u8 *cfg_data, unsigned int size);
void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl);
void free_tx_desc(struct adapter *adap, struct sge_txq *q,
unsigned int n, bool unmap);
@@ -2061,6 +2167,8 @@ int cxgb_open(struct net_device *dev);
int cxgb_close(struct net_device *dev);
void cxgb4_enable_rx(struct adapter *adap, struct sge_rspq *q);
void cxgb4_quiesce_rx(struct sge_rspq *q);
+int cxgb4_port_mirror_alloc(struct net_device *dev);
+void cxgb4_port_mirror_free(struct net_device *dev);
#ifdef CONFIG_CHELSIO_TLS_DEVICE
int cxgb4_set_ktls_feature(struct adapter *adap, bool enable);
#endif
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c
index e374b413d9ac..77648e4ab4cc 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c
@@ -66,249 +66,9 @@ static const struct cxgb4_collect_entity cxgb4_collect_hw_dump[] = {
{ CUDBG_HMA_INDIRECT, cudbg_collect_hma_indirect },
};
-static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity)
-{
- struct cudbg_tcam tcam_region = { 0 };
- u32 value, n = 0, len = 0;
-
- switch (entity) {
- case CUDBG_REG_DUMP:
- switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
- case CHELSIO_T4:
- len = T4_REGMAP_SIZE;
- break;
- case CHELSIO_T5:
- case CHELSIO_T6:
- len = T5_REGMAP_SIZE;
- break;
- default:
- break;
- }
- break;
- case CUDBG_DEV_LOG:
- len = adap->params.devlog.size;
- break;
- case CUDBG_CIM_LA:
- if (is_t6(adap->params.chip)) {
- len = adap->params.cim_la_size / 10 + 1;
- len *= 10 * sizeof(u32);
- } else {
- len = adap->params.cim_la_size / 8;
- len *= 8 * sizeof(u32);
- }
- len += sizeof(u32); /* for reading CIM LA configuration */
- break;
- case CUDBG_CIM_MA_LA:
- len = 2 * CIM_MALA_SIZE * 5 * sizeof(u32);
- break;
- case CUDBG_CIM_QCFG:
- len = sizeof(struct cudbg_cim_qcfg);
- break;
- case CUDBG_CIM_IBQ_TP0:
- case CUDBG_CIM_IBQ_TP1:
- case CUDBG_CIM_IBQ_ULP:
- case CUDBG_CIM_IBQ_SGE0:
- case CUDBG_CIM_IBQ_SGE1:
- case CUDBG_CIM_IBQ_NCSI:
- len = CIM_IBQ_SIZE * 4 * sizeof(u32);
- break;
- case CUDBG_CIM_OBQ_ULP0:
- len = cudbg_cim_obq_size(adap, 0);
- break;
- case CUDBG_CIM_OBQ_ULP1:
- len = cudbg_cim_obq_size(adap, 1);
- break;
- case CUDBG_CIM_OBQ_ULP2:
- len = cudbg_cim_obq_size(adap, 2);
- break;
- case CUDBG_CIM_OBQ_ULP3:
- len = cudbg_cim_obq_size(adap, 3);
- break;
- case CUDBG_CIM_OBQ_SGE:
- len = cudbg_cim_obq_size(adap, 4);
- break;
- case CUDBG_CIM_OBQ_NCSI:
- len = cudbg_cim_obq_size(adap, 5);
- break;
- case CUDBG_CIM_OBQ_RXQ0:
- len = cudbg_cim_obq_size(adap, 6);
- break;
- case CUDBG_CIM_OBQ_RXQ1:
- len = cudbg_cim_obq_size(adap, 7);
- break;
- case CUDBG_EDC0:
- value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
- if (value & EDRAM0_ENABLE_F) {
- value = t4_read_reg(adap, MA_EDRAM0_BAR_A);
- len = EDRAM0_SIZE_G(value);
- }
- len = cudbg_mbytes_to_bytes(len);
- break;
- case CUDBG_EDC1:
- value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
- if (value & EDRAM1_ENABLE_F) {
- value = t4_read_reg(adap, MA_EDRAM1_BAR_A);
- len = EDRAM1_SIZE_G(value);
- }
- len = cudbg_mbytes_to_bytes(len);
- break;
- case CUDBG_MC0:
- value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
- if (value & EXT_MEM0_ENABLE_F) {
- value = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A);
- len = EXT_MEM0_SIZE_G(value);
- }
- len = cudbg_mbytes_to_bytes(len);
- break;
- case CUDBG_MC1:
- value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
- if (value & EXT_MEM1_ENABLE_F) {
- value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
- len = EXT_MEM1_SIZE_G(value);
- }
- len = cudbg_mbytes_to_bytes(len);
- break;
- case CUDBG_RSS:
- len = t4_chip_rss_size(adap) * sizeof(u16);
- break;
- case CUDBG_RSS_VF_CONF:
- len = adap->params.arch.vfcount *
- sizeof(struct cudbg_rss_vf_conf);
- break;
- case CUDBG_PATH_MTU:
- len = NMTUS * sizeof(u16);
- break;
- case CUDBG_PM_STATS:
- len = sizeof(struct cudbg_pm_stats);
- break;
- case CUDBG_HW_SCHED:
- len = sizeof(struct cudbg_hw_sched);
- break;
- case CUDBG_TP_INDIRECT:
- switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
- case CHELSIO_T5:
- n = sizeof(t5_tp_pio_array) +
- sizeof(t5_tp_tm_pio_array) +
- sizeof(t5_tp_mib_index_array);
- break;
- case CHELSIO_T6:
- n = sizeof(t6_tp_pio_array) +
- sizeof(t6_tp_tm_pio_array) +
- sizeof(t6_tp_mib_index_array);
- break;
- default:
- break;
- }
- n = n / (IREG_NUM_ELEM * sizeof(u32));
- len = sizeof(struct ireg_buf) * n;
- break;
- case CUDBG_SGE_INDIRECT:
- len = sizeof(struct ireg_buf) * 2 +
- sizeof(struct sge_qbase_reg_field);
- break;
- case CUDBG_ULPRX_LA:
- len = sizeof(struct cudbg_ulprx_la);
- break;
- case CUDBG_TP_LA:
- len = sizeof(struct cudbg_tp_la) + TPLA_SIZE * sizeof(u64);
- break;
- case CUDBG_MEMINFO:
- len = sizeof(struct cudbg_ver_hdr) +
- sizeof(struct cudbg_meminfo);
- break;
- case CUDBG_CIM_PIF_LA:
- len = sizeof(struct cudbg_cim_pif_la);
- len += 2 * CIM_PIFLA_SIZE * 6 * sizeof(u32);
- break;
- case CUDBG_CLK:
- len = sizeof(struct cudbg_clk_info);
- break;
- case CUDBG_PCIE_INDIRECT:
- n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32));
- len = sizeof(struct ireg_buf) * n * 2;
- break;
- case CUDBG_PM_INDIRECT:
- n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32));
- len = sizeof(struct ireg_buf) * n * 2;
- break;
- case CUDBG_TID_INFO:
- len = sizeof(struct cudbg_tid_info_region_rev1);
- break;
- case CUDBG_PCIE_CONFIG:
- len = sizeof(u32) * CUDBG_NUM_PCIE_CONFIG_REGS;
- break;
- case CUDBG_DUMP_CONTEXT:
- len = cudbg_dump_context_size(adap);
- break;
- case CUDBG_MPS_TCAM:
- len = sizeof(struct cudbg_mps_tcam) *
- adap->params.arch.mps_tcam_size;
- break;
- case CUDBG_VPD_DATA:
- len = sizeof(struct cudbg_vpd_data);
- break;
- case CUDBG_LE_TCAM:
- cudbg_fill_le_tcam_info(adap, &tcam_region);
- len = sizeof(struct cudbg_tcam) +
- sizeof(struct cudbg_tid_data) * tcam_region.max_tid;
- break;
- case CUDBG_CCTRL:
- len = sizeof(u16) * NMTUS * NCCTRL_WIN;
- break;
- case CUDBG_MA_INDIRECT:
- if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
- n = sizeof(t6_ma_ireg_array) /
- (IREG_NUM_ELEM * sizeof(u32));
- len = sizeof(struct ireg_buf) * n * 2;
- }
- break;
- case CUDBG_ULPTX_LA:
- len = sizeof(struct cudbg_ver_hdr) +
- sizeof(struct cudbg_ulptx_la);
- break;
- case CUDBG_UP_CIM_INDIRECT:
- n = 0;
- if (is_t5(adap->params.chip))
- n = sizeof(t5_up_cim_reg_array) /
- ((IREG_NUM_ELEM + 1) * sizeof(u32));
- else if (is_t6(adap->params.chip))
- n = sizeof(t6_up_cim_reg_array) /
- ((IREG_NUM_ELEM + 1) * sizeof(u32));
- len = sizeof(struct ireg_buf) * n;
- break;
- case CUDBG_PBT_TABLE:
- len = sizeof(struct cudbg_pbt_tables);
- break;
- case CUDBG_MBOX_LOG:
- len = sizeof(struct cudbg_mbox_log) * adap->mbox_log->size;
- break;
- case CUDBG_HMA_INDIRECT:
- if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
- n = sizeof(t6_hma_ireg_array) /
- (IREG_NUM_ELEM * sizeof(u32));
- len = sizeof(struct ireg_buf) * n;
- }
- break;
- case CUDBG_HMA:
- value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
- if (value & HMA_MUX_F) {
- /* In T6, there's no MC1. So, HMA shares MC1
- * address space.
- */
- value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A);
- len = EXT_MEM1_SIZE_G(value);
- }
- len = cudbg_mbytes_to_bytes(len);
- break;
- case CUDBG_QDESC:
- cudbg_fill_qdesc_num_and_size(adap, NULL, &len);
- break;
- default:
- break;
- }
-
- return len;
-}
+static const struct cxgb4_collect_entity cxgb4_collect_flash_dump[] = {
+ { CUDBG_FLASH, cudbg_collect_flash },
+};
u32 cxgb4_get_dump_length(struct adapter *adap, u32 flag)
{
@@ -319,17 +79,20 @@ u32 cxgb4_get_dump_length(struct adapter *adap, u32 flag)
if (flag & CXGB4_ETH_DUMP_HW) {
for (i = 0; i < ARRAY_SIZE(cxgb4_collect_hw_dump); i++) {
entity = cxgb4_collect_hw_dump[i].entity;
- len += cxgb4_get_entity_length(adap, entity);
+ len += cudbg_get_entity_length(adap, entity);
}
}
if (flag & CXGB4_ETH_DUMP_MEM) {
for (i = 0; i < ARRAY_SIZE(cxgb4_collect_mem_dump); i++) {
entity = cxgb4_collect_mem_dump[i].entity;
- len += cxgb4_get_entity_length(adap, entity);
+ len += cudbg_get_entity_length(adap, entity);
}
}
+ if (flag & CXGB4_ETH_DUMP_FLASH)
+ len += adap->params.sf_size;
+
/* If compression is enabled, a smaller destination buffer is enough */
wsize = cudbg_get_workspace_size();
if (wsize && len > CUDBG_DUMP_BUFF_SIZE)
@@ -468,6 +231,13 @@ int cxgb4_cudbg_collect(struct adapter *adap, void *buf, u32 *buf_size,
buf,
&total_size);
+ if (flag & CXGB4_ETH_DUMP_FLASH)
+ cxgb4_cudbg_collect_entity(&cudbg_init, &dbg_buff,
+ cxgb4_collect_flash_dump,
+ ARRAY_SIZE(cxgb4_collect_flash_dump),
+ buf,
+ &total_size);
+
cudbg_free_compress_buff(&cudbg_init);
cudbg_hdr->data_len = total_size;
if (cudbg_init.compress_type != CUDBG_COMPRESSION_NONE)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h
index 66b805c7a92c..c04a49b6378d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.h
@@ -27,6 +27,7 @@ enum CXGB4_ETHTOOL_DUMP_FLAGS {
CXGB4_ETH_DUMP_NONE = ETH_FW_DUMP_DISABLE,
CXGB4_ETH_DUMP_MEM = (1 << 0), /* On-Chip Memory Dumps */
CXGB4_ETH_DUMP_HW = (1 << 1), /* various FW and HW dumps */
+ CXGB4_ETH_DUMP_FLASH = (1 << 2), /* Dump flash memory */
};
#define CXGB4_ETH_DUMP_ALL (CXGB4_ETH_DUMP_MEM | CXGB4_ETH_DUMP_HW)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index b477b8842905..05f33b7e3677 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -2742,6 +2742,58 @@ do { \
}
r -= eth_entries;
+ for_each_port(adap, j) {
+ struct port_info *pi = adap2pinfo(adap, j);
+ const struct sge_eth_rxq *rx;
+
+ mutex_lock(&pi->vi_mirror_mutex);
+ if (!pi->vi_mirror_count) {
+ mutex_unlock(&pi->vi_mirror_mutex);
+ continue;
+ }
+
+ if (r >= DIV_ROUND_UP(pi->nmirrorqsets, 4)) {
+ r -= DIV_ROUND_UP(pi->nmirrorqsets, 4);
+ mutex_unlock(&pi->vi_mirror_mutex);
+ continue;
+ }
+
+ rx = &s->mirror_rxq[j][r * 4];
+ n = min(4, pi->nmirrorqsets - 4 * r);
+
+ S("QType:", "Mirror-Rxq");
+ S("Interface:",
+ rx[i].rspq.netdev ? rx[i].rspq.netdev->name : "N/A");
+ R("RspQ ID:", rspq.abs_id);
+ R("RspQ size:", rspq.size);
+ R("RspQE size:", rspq.iqe_len);
+ R("RspQ CIDX:", rspq.cidx);
+ R("RspQ Gen:", rspq.gen);
+ S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
+ S3("u", "Intr pktcnt:", s->counter_val[rx[i].rspq.pktcnt_idx]);
+ R("FL ID:", fl.cntxt_id);
+ R("FL size:", fl.size - 8);
+ R("FL pend:", fl.pend_cred);
+ R("FL avail:", fl.avail);
+ R("FL PIDX:", fl.pidx);
+ R("FL CIDX:", fl.cidx);
+ RL("RxPackets:", stats.pkts);
+ RL("RxCSO:", stats.rx_cso);
+ RL("VLANxtract:", stats.vlan_ex);
+ RL("LROmerged:", stats.lro_merged);
+ RL("LROpackets:", stats.lro_pkts);
+ RL("RxDrops:", stats.rx_drops);
+ RL("RxBadPkts:", stats.bad_rx_pkts);
+ RL("FLAllocErr:", fl.alloc_failed);
+ RL("FLLrgAlcErr:", fl.large_alloc_failed);
+ RL("FLMapErr:", fl.mapping_err);
+ RL("FLLow:", fl.low);
+ RL("FLStarving:", fl.starving);
+
+ mutex_unlock(&pi->vi_mirror_mutex);
+ goto out;
+ }
+
if (!adap->tc_mqprio)
goto skip_mqprio;
@@ -3098,9 +3150,10 @@ unlock:
return 0;
}
-static int sge_queue_entries(const struct adapter *adap)
+static int sge_queue_entries(struct adapter *adap)
{
int i, tot_uld_entries = 0, eohw_entries = 0, eosw_entries = 0;
+ int mirror_rxq_entries = 0;
if (adap->tc_mqprio) {
struct cxgb4_tc_port_mqprio *port_mqprio;
@@ -3123,6 +3176,15 @@ static int sge_queue_entries(const struct adapter *adap)
mutex_unlock(&adap->tc_mqprio->mqprio_mutex);
}
+ for_each_port(adap, i) {
+ struct port_info *pi = adap2pinfo(adap, i);
+
+ mutex_lock(&pi->vi_mirror_mutex);
+ if (pi->vi_mirror_count)
+ mirror_rxq_entries += DIV_ROUND_UP(pi->nmirrorqsets, 4);
+ mutex_unlock(&pi->vi_mirror_mutex);
+ }
+
if (!is_uld(adap))
goto lld_only;
@@ -3137,7 +3199,7 @@ static int sge_queue_entries(const struct adapter *adap)
mutex_unlock(&uld_mutex);
lld_only:
- return DIV_ROUND_UP(adap->sge.ethqsets, 4) +
+ return DIV_ROUND_UP(adap->sge.ethqsets, 4) + mirror_rxq_entries +
eohw_entries + eosw_entries + tot_uld_entries +
DIV_ROUND_UP(MAX_CTRL_QUEUES, 4) + 1;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
index f27be1132d37..9f3173f86eed 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
@@ -10,6 +10,8 @@
#include "t4_regs.h"
#include "t4fw_api.h"
#include "cxgb4_cudbg.h"
+#include "cxgb4_filter.h"
+#include "cxgb4_tc_flower.h"
#define EEPROM_MAGIC 0x38E2F10C
@@ -23,6 +25,23 @@ static void set_msglevel(struct net_device *dev, u32 val)
netdev2adap(dev)->msg_enable = val;
}
+enum cxgb4_ethtool_tests {
+ CXGB4_ETHTOOL_LB_TEST,
+ CXGB4_ETHTOOL_MAX_TEST,
+};
+
+static const char cxgb4_selftest_strings[CXGB4_ETHTOOL_MAX_TEST][ETH_GSTRING_LEN] = {
+ "Loop back test (offline)",
+};
+
+static const char * const flash_region_strings[] = {
+ "All",
+ "Firmware",
+ "PHY Firmware",
+ "Boot",
+ "Boot CFG",
+};
+
static const char stats_strings[][ETH_GSTRING_LEN] = {
"tx_octets_ok ",
"tx_frames_ok ",
@@ -156,6 +175,8 @@ static int get_sset_count(struct net_device *dev, int sset)
ARRAY_SIZE(loopback_stats_strings);
case ETH_SS_PRIV_FLAGS:
return ARRAY_SIZE(cxgb4_priv_flags_strings);
+ case ETH_SS_TEST:
+ return ARRAY_SIZE(cxgb4_selftest_strings);
default:
return -EOPNOTSUPP;
}
@@ -218,6 +239,9 @@ static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
} else if (stringset == ETH_SS_PRIV_FLAGS) {
memcpy(data, cxgb4_priv_flags_strings,
sizeof(cxgb4_priv_flags_strings));
+ } else if (stringset == ETH_SS_TEST) {
+ memcpy(data, cxgb4_selftest_strings,
+ sizeof(cxgb4_selftest_strings));
}
}
@@ -1235,15 +1259,211 @@ out:
return err;
}
-static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
+static int cxgb4_ethtool_flash_bootcfg(struct net_device *netdev,
+ const u8 *data, u32 size)
{
+ struct adapter *adap = netdev2adap(netdev);
int ret;
- const struct firmware *fw;
+
+ ret = t4_load_bootcfg(adap, data, size);
+ if (ret)
+ dev_err(adap->pdev_dev, "Failed to load boot cfg image\n");
+
+ return ret;
+}
+
+static int cxgb4_ethtool_flash_boot(struct net_device *netdev,
+ const u8 *bdata, u32 size)
+{
+ struct adapter *adap = netdev2adap(netdev);
+ unsigned int offset;
+ u8 *data;
+ int ret;
+
+ data = kmemdup(bdata, size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ offset = OFFSET_G(t4_read_reg(adap, PF_REG(0, PCIE_PF_EXPROM_OFST_A)));
+
+ ret = t4_load_boot(adap, data, offset, size);
+ if (ret)
+ dev_err(adap->pdev_dev, "Failed to load boot image\n");
+
+ kfree(data);
+ return ret;
+}
+
+#define CXGB4_PHY_SIG 0x130000ea
+
+static int cxgb4_validate_phy_image(const u8 *data, u32 *size)
+{
+ struct cxgb4_fw_data *header;
+
+ header = (struct cxgb4_fw_data *)data;
+ if (be32_to_cpu(header->signature) != CXGB4_PHY_SIG)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int cxgb4_ethtool_flash_phy(struct net_device *netdev,
+ const u8 *data, u32 size)
+{
+ struct adapter *adap = netdev2adap(netdev);
+ int ret;
+
+ ret = cxgb4_validate_phy_image(data, NULL);
+ if (ret) {
+ dev_err(adap->pdev_dev, "PHY signature mismatch\n");
+ return ret;
+ }
+
+ spin_lock_bh(&adap->win0_lock);
+ ret = t4_load_phy_fw(adap, MEMWIN_NIC, NULL, data, size);
+ spin_unlock_bh(&adap->win0_lock);
+ if (ret)
+ dev_err(adap->pdev_dev, "Failed to load PHY FW\n");
+
+ return ret;
+}
+
+static int cxgb4_ethtool_flash_fw(struct net_device *netdev,
+ const u8 *data, u32 size)
+{
struct adapter *adap = netdev2adap(netdev);
unsigned int mbox = PCIE_FW_MASTER_M + 1;
- u32 pcie_fw;
+ int ret;
+
+ /* If the adapter has been fully initialized then we'll go ahead and
+ * try to get the firmware's cooperation in upgrading to the new
+ * firmware image otherwise we'll try to do the entire job from the
+ * host ... and we always "force" the operation in this path.
+ */
+ if (adap->flags & CXGB4_FULL_INIT_DONE)
+ mbox = adap->mbox;
+
+ ret = t4_fw_upgrade(adap, mbox, data, size, 1);
+ if (ret)
+ dev_err(adap->pdev_dev,
+ "Failed to flash firmware\n");
+
+ return ret;
+}
+
+static int cxgb4_ethtool_flash_region(struct net_device *netdev,
+ const u8 *data, u32 size, u32 region)
+{
+ struct adapter *adap = netdev2adap(netdev);
+ int ret;
+
+ switch (region) {
+ case CXGB4_ETHTOOL_FLASH_FW:
+ ret = cxgb4_ethtool_flash_fw(netdev, data, size);
+ break;
+ case CXGB4_ETHTOOL_FLASH_PHY:
+ ret = cxgb4_ethtool_flash_phy(netdev, data, size);
+ break;
+ case CXGB4_ETHTOOL_FLASH_BOOT:
+ ret = cxgb4_ethtool_flash_boot(netdev, data, size);
+ break;
+ case CXGB4_ETHTOOL_FLASH_BOOTCFG:
+ ret = cxgb4_ethtool_flash_bootcfg(netdev, data, size);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ if (!ret)
+ dev_info(adap->pdev_dev,
+ "loading %s successful, reload cxgb4 driver\n",
+ flash_region_strings[region]);
+ return ret;
+}
+
+#define CXGB4_FW_SIG 0x4368656c
+#define CXGB4_FW_SIG_OFFSET 0x160
+
+static int cxgb4_validate_fw_image(const u8 *data, u32 *size)
+{
+ struct cxgb4_fw_data *header;
+
+ header = (struct cxgb4_fw_data *)&data[CXGB4_FW_SIG_OFFSET];
+ if (be32_to_cpu(header->signature) != CXGB4_FW_SIG)
+ return -EINVAL;
+
+ if (size)
+ *size = be16_to_cpu(((struct fw_hdr *)data)->len512) * 512;
+
+ return 0;
+}
+
+static int cxgb4_validate_bootcfg_image(const u8 *data, u32 *size)
+{
+ struct cxgb4_bootcfg_data *header;
+
+ header = (struct cxgb4_bootcfg_data *)data;
+ if (le16_to_cpu(header->signature) != BOOT_CFG_SIG)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int cxgb4_validate_boot_image(const u8 *data, u32 *size)
+{
+ struct cxgb4_pci_exp_rom_header *exp_header;
+ struct cxgb4_pcir_data *pcir_header;
+ struct legacy_pci_rom_hdr *header;
+ const u8 *cur_header = data;
+ u16 pcir_offset;
+
+ exp_header = (struct cxgb4_pci_exp_rom_header *)data;
+
+ if (le16_to_cpu(exp_header->signature) != BOOT_SIGNATURE)
+ return -EINVAL;
+
+ if (size) {
+ do {
+ header = (struct legacy_pci_rom_hdr *)cur_header;
+ pcir_offset = le16_to_cpu(header->pcir_offset);
+ pcir_header = (struct cxgb4_pcir_data *)(cur_header +
+ pcir_offset);
+
+ *size += header->size512 * 512;
+ cur_header += header->size512 * 512;
+ } while (!(pcir_header->indicator & CXGB4_HDR_INDI));
+ }
+
+ return 0;
+}
+
+static int cxgb4_ethtool_get_flash_region(const u8 *data, u32 *size)
+{
+ if (!cxgb4_validate_fw_image(data, size))
+ return CXGB4_ETHTOOL_FLASH_FW;
+ if (!cxgb4_validate_boot_image(data, size))
+ return CXGB4_ETHTOOL_FLASH_BOOT;
+ if (!cxgb4_validate_phy_image(data, size))
+ return CXGB4_ETHTOOL_FLASH_PHY;
+ if (!cxgb4_validate_bootcfg_image(data, size))
+ return CXGB4_ETHTOOL_FLASH_BOOTCFG;
+
+ return -EOPNOTSUPP;
+}
+
+static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
+{
+ struct adapter *adap = netdev2adap(netdev);
+ const struct firmware *fw;
unsigned int master;
u8 master_vld = 0;
+ const u8 *fw_data;
+ size_t fw_size;
+ u32 size = 0;
+ u32 pcie_fw;
+ int region;
+ int ret;
pcie_fw = t4_read_reg(adap, PCIE_FW_A);
master = PCIE_FW_MASTER_G(pcie_fw);
@@ -1261,19 +1481,32 @@ static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
if (ret < 0)
return ret;
- /* If the adapter has been fully initialized then we'll go ahead and
- * try to get the firmware's cooperation in upgrading to the new
- * firmware image otherwise we'll try to do the entire job from the
- * host ... and we always "force" the operation in this path.
- */
- if (adap->flags & CXGB4_FULL_INIT_DONE)
- mbox = adap->mbox;
+ fw_data = fw->data;
+ fw_size = fw->size;
+ if (ef->region == ETHTOOL_FLASH_ALL_REGIONS) {
+ while (fw_size > 0) {
+ size = 0;
+ region = cxgb4_ethtool_get_flash_region(fw_data, &size);
+ if (region < 0 || !size) {
+ ret = region;
+ goto out_free_fw;
+ }
+
+ ret = cxgb4_ethtool_flash_region(netdev, fw_data, size,
+ region);
+ if (ret)
+ goto out_free_fw;
- ret = t4_fw_upgrade(adap, mbox, fw->data, fw->size, 1);
+ fw_data += size;
+ fw_size -= size;
+ }
+ } else {
+ ret = cxgb4_ethtool_flash_region(netdev, fw_data, fw_size,
+ ef->region);
+ }
+
+out_free_fw:
release_firmware(fw);
- if (!ret)
- dev_info(adap->pdev_dev,
- "loaded firmware %s, reload cxgb4 driver\n", ef->data);
return ret;
}
@@ -1355,10 +1588,120 @@ static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key,
return -EPERM;
}
+static struct filter_entry *cxgb4_get_filter_entry(struct adapter *adap,
+ u32 ftid)
+{
+ struct tid_info *t = &adap->tids;
+ struct filter_entry *f;
+
+ if (ftid < t->nhpftids)
+ f = &adap->tids.hpftid_tab[ftid];
+ else if (ftid < t->nftids)
+ f = &adap->tids.ftid_tab[ftid - t->nhpftids];
+ else
+ f = lookup_tid(&adap->tids, ftid);
+
+ return f;
+}
+
+static void cxgb4_fill_filter_rule(struct ethtool_rx_flow_spec *fs,
+ struct ch_filter_specification *dfs)
+{
+ switch (dfs->val.proto) {
+ case IPPROTO_TCP:
+ if (dfs->type)
+ fs->flow_type = TCP_V6_FLOW;
+ else
+ fs->flow_type = TCP_V4_FLOW;
+ break;
+ case IPPROTO_UDP:
+ if (dfs->type)
+ fs->flow_type = UDP_V6_FLOW;
+ else
+ fs->flow_type = UDP_V4_FLOW;
+ break;
+ }
+
+ if (dfs->type) {
+ fs->h_u.tcp_ip6_spec.psrc = cpu_to_be16(dfs->val.fport);
+ fs->m_u.tcp_ip6_spec.psrc = cpu_to_be16(dfs->mask.fport);
+ fs->h_u.tcp_ip6_spec.pdst = cpu_to_be16(dfs->val.lport);
+ fs->m_u.tcp_ip6_spec.pdst = cpu_to_be16(dfs->mask.lport);
+ memcpy(&fs->h_u.tcp_ip6_spec.ip6src, &dfs->val.fip[0],
+ sizeof(fs->h_u.tcp_ip6_spec.ip6src));
+ memcpy(&fs->m_u.tcp_ip6_spec.ip6src, &dfs->mask.fip[0],
+ sizeof(fs->m_u.tcp_ip6_spec.ip6src));
+ memcpy(&fs->h_u.tcp_ip6_spec.ip6dst, &dfs->val.lip[0],
+ sizeof(fs->h_u.tcp_ip6_spec.ip6dst));
+ memcpy(&fs->m_u.tcp_ip6_spec.ip6dst, &dfs->mask.lip[0],
+ sizeof(fs->m_u.tcp_ip6_spec.ip6dst));
+ fs->h_u.tcp_ip6_spec.tclass = dfs->val.tos;
+ fs->m_u.tcp_ip6_spec.tclass = dfs->mask.tos;
+ } else {
+ fs->h_u.tcp_ip4_spec.psrc = cpu_to_be16(dfs->val.fport);
+ fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(dfs->mask.fport);
+ fs->h_u.tcp_ip4_spec.pdst = cpu_to_be16(dfs->val.lport);
+ fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(dfs->mask.lport);
+ memcpy(&fs->h_u.tcp_ip4_spec.ip4src, &dfs->val.fip[0],
+ sizeof(fs->h_u.tcp_ip4_spec.ip4src));
+ memcpy(&fs->m_u.tcp_ip4_spec.ip4src, &dfs->mask.fip[0],
+ sizeof(fs->m_u.tcp_ip4_spec.ip4src));
+ memcpy(&fs->h_u.tcp_ip4_spec.ip4dst, &dfs->val.lip[0],
+ sizeof(fs->h_u.tcp_ip4_spec.ip4dst));
+ memcpy(&fs->m_u.tcp_ip4_spec.ip4dst, &dfs->mask.lip[0],
+ sizeof(fs->m_u.tcp_ip4_spec.ip4dst));
+ fs->h_u.tcp_ip4_spec.tos = dfs->val.tos;
+ fs->m_u.tcp_ip4_spec.tos = dfs->mask.tos;
+ }
+ fs->h_ext.vlan_tci = cpu_to_be16(dfs->val.ivlan);
+ fs->m_ext.vlan_tci = cpu_to_be16(dfs->mask.ivlan);
+ fs->flow_type |= FLOW_EXT;
+
+ if (dfs->action == FILTER_DROP)
+ fs->ring_cookie = RX_CLS_FLOW_DISC;
+ else
+ fs->ring_cookie = dfs->iq;
+}
+
+static int cxgb4_ntuple_get_filter(struct net_device *dev,
+ struct ethtool_rxnfc *cmd,
+ unsigned int loc)
+{
+ const struct port_info *pi = netdev_priv(dev);
+ struct adapter *adap = netdev2adap(dev);
+ struct filter_entry *f;
+ int ftid;
+
+ if (!(adap->flags & CXGB4_FULL_INIT_DONE))
+ return -EAGAIN;
+
+ /* Check for maximum filter range */
+ if (!adap->ethtool_filters)
+ return -EOPNOTSUPP;
+
+ if (loc >= adap->ethtool_filters->nentries)
+ return -ERANGE;
+
+ if (!test_bit(loc, adap->ethtool_filters->port[pi->port_id].bmap))
+ return -ENOENT;
+
+ ftid = adap->ethtool_filters->port[pi->port_id].loc_array[loc];
+
+ /* Fetch filter_entry */
+ f = cxgb4_get_filter_entry(adap, ftid);
+
+ cxgb4_fill_filter_rule(&cmd->fs, &f->fs);
+
+ return 0;
+}
+
static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
u32 *rules)
{
const struct port_info *pi = netdev_priv(dev);
+ struct adapter *adap = netdev2adap(dev);
+ unsigned int count = 0, index = 0;
+ int ret = 0;
switch (info->cmd) {
case ETHTOOL_GRXFH: {
@@ -1414,10 +1757,144 @@ static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
case ETHTOOL_GRXRINGS:
info->data = pi->nqsets;
return 0;
+ case ETHTOOL_GRXCLSRLCNT:
+ info->rule_cnt =
+ adap->ethtool_filters->port[pi->port_id].in_use;
+ return 0;
+ case ETHTOOL_GRXCLSRULE:
+ return cxgb4_ntuple_get_filter(dev, info, info->fs.location);
+ case ETHTOOL_GRXCLSRLALL:
+ info->data = adap->ethtool_filters->nentries;
+ while (count < info->rule_cnt) {
+ ret = cxgb4_ntuple_get_filter(dev, info, index);
+ if (!ret)
+ rules[count++] = index;
+ index++;
+ }
+ return 0;
}
+
return -EOPNOTSUPP;
}
+static int cxgb4_ntuple_del_filter(struct net_device *dev,
+ struct ethtool_rxnfc *cmd)
+{
+ struct cxgb4_ethtool_filter_info *filter_info;
+ struct adapter *adapter = netdev2adap(dev);
+ struct port_info *pi = netdev_priv(dev);
+ struct filter_entry *f;
+ u32 filter_id;
+ int ret;
+
+ if (!(adapter->flags & CXGB4_FULL_INIT_DONE))
+ return -EAGAIN; /* can still change nfilters */
+
+ if (!adapter->ethtool_filters)
+ return -EOPNOTSUPP;
+
+ if (cmd->fs.location >= adapter->ethtool_filters->nentries) {
+ dev_err(adapter->pdev_dev,
+ "Location must be < %u",
+ adapter->ethtool_filters->nentries);
+ return -ERANGE;
+ }
+
+ filter_info = &adapter->ethtool_filters->port[pi->port_id];
+
+ if (!test_bit(cmd->fs.location, filter_info->bmap))
+ return -ENOENT;
+
+ filter_id = filter_info->loc_array[cmd->fs.location];
+ f = cxgb4_get_filter_entry(adapter, filter_id);
+
+ ret = cxgb4_flow_rule_destroy(dev, f->fs.tc_prio, &f->fs, filter_id);
+ if (ret)
+ goto err;
+
+ clear_bit(cmd->fs.location, filter_info->bmap);
+ filter_info->in_use--;
+
+err:
+ return ret;
+}
+
+/* Add Ethtool n-tuple filters. */
+static int cxgb4_ntuple_set_filter(struct net_device *netdev,
+ struct ethtool_rxnfc *cmd)
+{
+ struct ethtool_rx_flow_spec_input input = {};
+ struct cxgb4_ethtool_filter_info *filter_info;
+ struct adapter *adapter = netdev2adap(netdev);
+ struct port_info *pi = netdev_priv(netdev);
+ struct ch_filter_specification fs;
+ struct ethtool_rx_flow_rule *flow;
+ u32 tid;
+ int ret;
+
+ if (!(adapter->flags & CXGB4_FULL_INIT_DONE))
+ return -EAGAIN; /* can still change nfilters */
+
+ if (!adapter->ethtool_filters)
+ return -EOPNOTSUPP;
+
+ if (cmd->fs.location >= adapter->ethtool_filters->nentries) {
+ dev_err(adapter->pdev_dev,
+ "Location must be < %u",
+ adapter->ethtool_filters->nentries);
+ return -ERANGE;
+ }
+
+ if (test_bit(cmd->fs.location,
+ adapter->ethtool_filters->port[pi->port_id].bmap))
+ return -EEXIST;
+
+ memset(&fs, 0, sizeof(fs));
+
+ input.fs = &cmd->fs;
+ flow = ethtool_rx_flow_rule_create(&input);
+ if (IS_ERR(flow)) {
+ ret = PTR_ERR(flow);
+ goto exit;
+ }
+
+ fs.hitcnts = 1;
+
+ ret = cxgb4_flow_rule_replace(netdev, flow->rule, cmd->fs.location,
+ NULL, &fs, &tid);
+ if (ret)
+ goto free;
+
+ filter_info = &adapter->ethtool_filters->port[pi->port_id];
+
+ filter_info->loc_array[cmd->fs.location] = tid;
+ set_bit(cmd->fs.location, filter_info->bmap);
+ filter_info->in_use++;
+
+free:
+ ethtool_rx_flow_rule_destroy(flow);
+exit:
+ return ret;
+}
+
+static int set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+ int ret = -EOPNOTSUPP;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_SRXCLSRLINS:
+ ret = cxgb4_ntuple_set_filter(dev, cmd);
+ break;
+ case ETHTOOL_SRXCLSRLDEL:
+ ret = cxgb4_ntuple_del_filter(dev, cmd);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
static int set_dump(struct net_device *dev, struct ethtool_dump *eth_dump)
{
struct adapter *adapter = netdev2adap(dev);
@@ -1593,6 +2070,44 @@ static int cxgb4_set_priv_flags(struct net_device *netdev, u32 flags)
return 0;
}
+static void cxgb4_lb_test(struct net_device *netdev, u64 *lb_status)
+{
+ int dev_state = netif_running(netdev);
+
+ if (dev_state) {
+ netif_tx_stop_all_queues(netdev);
+ netif_carrier_off(netdev);
+ }
+
+ *lb_status = cxgb4_selftest_lb_pkt(netdev);
+
+ if (dev_state) {
+ netif_tx_start_all_queues(netdev);
+ netif_carrier_on(netdev);
+ }
+}
+
+static void cxgb4_self_test(struct net_device *netdev,
+ struct ethtool_test *eth_test, u64 *data)
+{
+ struct port_info *pi = netdev_priv(netdev);
+ struct adapter *adap = pi->adapter;
+
+ memset(data, 0, sizeof(u64) * CXGB4_ETHTOOL_MAX_TEST);
+
+ if (!(adap->flags & CXGB4_FULL_INIT_DONE) ||
+ !(adap->flags & CXGB4_FW_OK)) {
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+ return;
+ }
+
+ if (eth_test->flags & ETH_TEST_FL_OFFLINE)
+ cxgb4_lb_test(netdev, &data[CXGB4_ETHTOOL_LB_TEST]);
+
+ if (data[CXGB4_ETHTOOL_LB_TEST])
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+}
+
static const struct ethtool_ops cxgb_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_RX_MAX_FRAMES |
@@ -1623,9 +2138,11 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
.get_regs_len = get_regs_len,
.get_regs = get_regs,
.get_rxnfc = get_rxnfc,
+ .set_rxnfc = set_rxnfc,
.get_rxfh_indir_size = get_rss_table_size,
.get_rxfh = get_rss_table,
.set_rxfh = set_rss_table,
+ .self_test = cxgb4_self_test,
.flash_device = set_flash,
.get_ts_info = get_ts_info,
.set_dump = set_dump,
@@ -1637,6 +2154,87 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
.set_priv_flags = cxgb4_set_priv_flags,
};
+void cxgb4_cleanup_ethtool_filters(struct adapter *adap)
+{
+ struct cxgb4_ethtool_filter_info *eth_filter_info;
+ u8 i;
+
+ if (!adap->ethtool_filters)
+ return;
+
+ eth_filter_info = adap->ethtool_filters->port;
+
+ if (eth_filter_info) {
+ for (i = 0; i < adap->params.nports; i++) {
+ kvfree(eth_filter_info[i].loc_array);
+ kfree(eth_filter_info[i].bmap);
+ }
+ kfree(eth_filter_info);
+ }
+
+ kfree(adap->ethtool_filters);
+}
+
+int cxgb4_init_ethtool_filters(struct adapter *adap)
+{
+ struct cxgb4_ethtool_filter_info *eth_filter_info;
+ struct cxgb4_ethtool_filter *eth_filter;
+ struct tid_info *tids = &adap->tids;
+ u32 nentries, i;
+ int ret;
+
+ eth_filter = kzalloc(sizeof(*eth_filter), GFP_KERNEL);
+ if (!eth_filter)
+ return -ENOMEM;
+
+ eth_filter_info = kcalloc(adap->params.nports,
+ sizeof(*eth_filter_info),
+ GFP_KERNEL);
+ if (!eth_filter_info) {
+ ret = -ENOMEM;
+ goto free_eth_filter;
+ }
+
+ eth_filter->port = eth_filter_info;
+
+ nentries = tids->nhpftids + tids->nftids;
+ if (is_hashfilter(adap))
+ nentries += tids->nhash +
+ (adap->tids.stid_base - adap->tids.tid_base);
+ eth_filter->nentries = nentries;
+
+ for (i = 0; i < adap->params.nports; i++) {
+ eth_filter->port[i].loc_array = kvzalloc(nentries, GFP_KERNEL);
+ if (!eth_filter->port[i].loc_array) {
+ ret = -ENOMEM;
+ goto free_eth_finfo;
+ }
+
+ eth_filter->port[i].bmap = kcalloc(BITS_TO_LONGS(nentries),
+ sizeof(unsigned long),
+ GFP_KERNEL);
+ if (!eth_filter->port[i].bmap) {
+ ret = -ENOMEM;
+ goto free_eth_finfo;
+ }
+ }
+
+ adap->ethtool_filters = eth_filter;
+ return 0;
+
+free_eth_finfo:
+ while (i-- > 0) {
+ kfree(eth_filter->port[i].bmap);
+ kvfree(eth_filter->port[i].loc_array);
+ }
+ kfree(eth_filter_info);
+
+free_eth_filter:
+ kfree(eth_filter);
+
+ return ret;
+}
+
void cxgb4_set_ethtool_ops(struct net_device *netdev)
{
netdev->ethtool_ops = &cxgb_ethtool_ops;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
index d02d346629b3..650db92cb11c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
@@ -1159,6 +1159,11 @@ bool is_filter_exact_match(struct adapter *adap,
if (!is_hashfilter(adap))
return false;
+ if ((atomic_read(&adap->tids.hash_tids_in_use) +
+ atomic_read(&adap->tids.tids_in_use)) >=
+ (adap->tids.nhash + (adap->tids.stid_base - adap->tids.tid_base)))
+ return false;
+
/* Keep tunnel VNI match disabled for hash-filters for now */
if (fs->mask.encap_vld)
return false;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.h
index b0751c0611ec..807a8dafec45 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.h
@@ -53,4 +53,6 @@ void clear_all_filters(struct adapter *adapter);
void init_hash_filter(struct adapter *adap);
bool is_filter_exact_match(struct adapter *adap,
struct ch_filter_specification *fs);
+void cxgb4_cleanup_ethtool_filters(struct adapter *adap);
+int cxgb4_init_ethtool_filters(struct adapter *adap);
#endif /* __CXGB4_FILTER_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 0329a6b52087..de078a5bf23e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -435,8 +435,8 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok)
__dev_uc_sync(dev, cxgb4_mac_sync, cxgb4_mac_unsync);
__dev_mc_sync(dev, cxgb4_mac_sync, cxgb4_mac_unsync);
- return t4_set_rxmode(adapter, adapter->mbox, pi->viid, mtu,
- (dev->flags & IFF_PROMISC) ? 1 : 0,
+ return t4_set_rxmode(adapter, adapter->mbox, pi->viid, pi->viid_mirror,
+ mtu, (dev->flags & IFF_PROMISC) ? 1 : 0,
(dev->flags & IFF_ALLMULTI) ? 1 : 0, 1, -1,
sleep_ok);
}
@@ -503,15 +503,16 @@ set_hash:
*/
static int link_start(struct net_device *dev)
{
- int ret;
struct port_info *pi = netdev_priv(dev);
- unsigned int mb = pi->adapter->pf;
+ unsigned int mb = pi->adapter->mbox;
+ int ret;
/*
* We do not set address filters and promiscuity here, the stack does
* that step explicitly.
*/
- ret = t4_set_rxmode(pi->adapter, mb, pi->viid, dev->mtu, -1, -1, -1,
+ ret = t4_set_rxmode(pi->adapter, mb, pi->viid, pi->viid_mirror,
+ dev->mtu, -1, -1, -1,
!!(dev->features & NETIF_F_HW_VLAN_CTAG_RX), true);
if (ret == 0)
ret = cxgb4_update_mac_filt(pi, pi->viid, &pi->xact_addr_filt,
@@ -822,6 +823,31 @@ static void adap_config_hpfilter(struct adapter *adapter)
"HP filter region isn't supported by FW\n");
}
+static int cxgb4_config_rss(const struct port_info *pi, u16 *rss,
+ u16 rss_size, u16 viid)
+{
+ struct adapter *adap = pi->adapter;
+ int ret;
+
+ ret = t4_config_rss_range(adap, adap->mbox, viid, 0, rss_size, rss,
+ rss_size);
+ if (ret)
+ return ret;
+
+ /* If Tunnel All Lookup isn't specified in the global RSS
+ * Configuration, then we need to specify a default Ingress
+ * Queue for any ingress packets which aren't hashed. We'll
+ * use our first ingress queue ...
+ */
+ return t4_config_vi_rss(adap, adap->mbox, viid,
+ FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F |
+ FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F |
+ FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F |
+ FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F |
+ FW_RSS_VI_CONFIG_CMD_UDPEN_F,
+ rss[0]);
+}
+
/**
* cxgb4_write_rss - write the RSS table for a given port
* @pi: the port
@@ -833,10 +859,10 @@ static void adap_config_hpfilter(struct adapter *adapter)
*/
int cxgb4_write_rss(const struct port_info *pi, const u16 *queues)
{
- u16 *rss;
- int i, err;
struct adapter *adapter = pi->adapter;
const struct sge_eth_rxq *rxq;
+ int i, err;
+ u16 *rss;
rxq = &adapter->sge.ethrxq[pi->first_qset];
rss = kmalloc_array(pi->rss_size, sizeof(u16), GFP_KERNEL);
@@ -847,21 +873,7 @@ int cxgb4_write_rss(const struct port_info *pi, const u16 *queues)
for (i = 0; i < pi->rss_size; i++, queues++)
rss[i] = rxq[*queues].rspq.abs_id;
- err = t4_config_rss_range(adapter, adapter->pf, pi->viid, 0,
- pi->rss_size, rss, pi->rss_size);
- /* If Tunnel All Lookup isn't specified in the global RSS
- * Configuration, then we need to specify a default Ingress
- * Queue for any ingress packets which aren't hashed. We'll
- * use our first ingress queue ...
- */
- if (!err)
- err = t4_config_vi_rss(adapter, adapter->mbox, pi->viid,
- FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F |
- FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F |
- FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F |
- FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F |
- FW_RSS_VI_CONFIG_CMD_UDPEN_F,
- rss[0]);
+ err = cxgb4_config_rss(pi, rss, pi->rss_size, pi->viid);
kfree(rss);
return err;
}
@@ -1259,15 +1271,15 @@ int cxgb4_set_rspq_intr_params(struct sge_rspq *q,
static int cxgb_set_features(struct net_device *dev, netdev_features_t features)
{
- const struct port_info *pi = netdev_priv(dev);
netdev_features_t changed = dev->features ^ features;
+ const struct port_info *pi = netdev_priv(dev);
int err;
if (!(changed & NETIF_F_HW_VLAN_CTAG_RX))
return 0;
- err = t4_set_rxmode(pi->adapter, pi->adapter->pf, pi->viid, -1,
- -1, -1, -1,
+ err = t4_set_rxmode(pi->adapter, pi->adapter->mbox, pi->viid,
+ pi->viid_mirror, -1, -1, -1, -1,
!!(features & NETIF_F_HW_VLAN_CTAG_RX), true);
if (unlikely(err))
dev->features = features ^ NETIF_F_HW_VLAN_CTAG_RX;
@@ -1285,6 +1297,292 @@ static int setup_debugfs(struct adapter *adap)
return 0;
}
+static void cxgb4_port_mirror_free_rxq(struct adapter *adap,
+ struct sge_eth_rxq *mirror_rxq)
+{
+ if ((adap->flags & CXGB4_FULL_INIT_DONE) &&
+ !(adap->flags & CXGB4_SHUTTING_DOWN))
+ cxgb4_quiesce_rx(&mirror_rxq->rspq);
+
+ if (adap->flags & CXGB4_USING_MSIX) {
+ cxgb4_clear_msix_aff(mirror_rxq->msix->vec,
+ mirror_rxq->msix->aff_mask);
+ free_irq(mirror_rxq->msix->vec, &mirror_rxq->rspq);
+ cxgb4_free_msix_idx_in_bmap(adap, mirror_rxq->msix->idx);
+ }
+
+ free_rspq_fl(adap, &mirror_rxq->rspq, &mirror_rxq->fl);
+}
+
+static int cxgb4_port_mirror_alloc_queues(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
+ struct sge_eth_rxq *mirror_rxq;
+ struct sge *s = &adap->sge;
+ int ret = 0, msix = 0;
+ u16 i, rxqid;
+ u16 *rss;
+
+ if (!pi->vi_mirror_count)
+ return 0;
+
+ if (s->mirror_rxq[pi->port_id])
+ return 0;
+
+ mirror_rxq = kcalloc(pi->nmirrorqsets, sizeof(*mirror_rxq), GFP_KERNEL);
+ if (!mirror_rxq)
+ return -ENOMEM;
+
+ s->mirror_rxq[pi->port_id] = mirror_rxq;
+
+ if (!(adap->flags & CXGB4_USING_MSIX))
+ msix = -((int)adap->sge.intrq.abs_id + 1);
+
+ for (i = 0, rxqid = 0; i < pi->nmirrorqsets; i++, rxqid++) {
+ mirror_rxq = &s->mirror_rxq[pi->port_id][i];
+
+ /* Allocate Mirror Rxqs */
+ if (msix >= 0) {
+ msix = cxgb4_get_msix_idx_from_bmap(adap);
+ if (msix < 0) {
+ ret = msix;
+ goto out_free_queues;
+ }
+
+ mirror_rxq->msix = &adap->msix_info[msix];
+ snprintf(mirror_rxq->msix->desc,
+ sizeof(mirror_rxq->msix->desc),
+ "%s-mirrorrxq%d", dev->name, i);
+ }
+
+ init_rspq(adap, &mirror_rxq->rspq,
+ CXGB4_MIRROR_RXQ_DEFAULT_INTR_USEC,
+ CXGB4_MIRROR_RXQ_DEFAULT_PKT_CNT,
+ CXGB4_MIRROR_RXQ_DEFAULT_DESC_NUM,
+ CXGB4_MIRROR_RXQ_DEFAULT_DESC_SIZE);
+
+ mirror_rxq->fl.size = CXGB4_MIRROR_FLQ_DEFAULT_DESC_NUM;
+
+ ret = t4_sge_alloc_rxq(adap, &mirror_rxq->rspq, false,
+ dev, msix, &mirror_rxq->fl,
+ t4_ethrx_handler, NULL, 0);
+ if (ret)
+ goto out_free_msix_idx;
+
+ /* Setup MSI-X vectors for Mirror Rxqs */
+ if (adap->flags & CXGB4_USING_MSIX) {
+ ret = request_irq(mirror_rxq->msix->vec,
+ t4_sge_intr_msix, 0,
+ mirror_rxq->msix->desc,
+ &mirror_rxq->rspq);
+ if (ret)
+ goto out_free_rxq;
+
+ cxgb4_set_msix_aff(adap, mirror_rxq->msix->vec,
+ &mirror_rxq->msix->aff_mask, i);
+ }
+
+ /* Start NAPI for Mirror Rxqs */
+ cxgb4_enable_rx(adap, &mirror_rxq->rspq);
+ }
+
+ /* Setup RSS for Mirror Rxqs */
+ rss = kcalloc(pi->rss_size, sizeof(u16), GFP_KERNEL);
+ if (!rss) {
+ ret = -ENOMEM;
+ goto out_free_queues;
+ }
+
+ mirror_rxq = &s->mirror_rxq[pi->port_id][0];
+ for (i = 0; i < pi->rss_size; i++)
+ rss[i] = mirror_rxq[i % pi->nmirrorqsets].rspq.abs_id;
+
+ ret = cxgb4_config_rss(pi, rss, pi->rss_size, pi->viid_mirror);
+ kfree(rss);
+ if (ret)
+ goto out_free_queues;
+
+ return 0;
+
+out_free_rxq:
+ free_rspq_fl(adap, &mirror_rxq->rspq, &mirror_rxq->fl);
+
+out_free_msix_idx:
+ cxgb4_free_msix_idx_in_bmap(adap, mirror_rxq->msix->idx);
+
+out_free_queues:
+ while (rxqid-- > 0)
+ cxgb4_port_mirror_free_rxq(adap,
+ &s->mirror_rxq[pi->port_id][rxqid]);
+
+ kfree(s->mirror_rxq[pi->port_id]);
+ s->mirror_rxq[pi->port_id] = NULL;
+ return ret;
+}
+
+static void cxgb4_port_mirror_free_queues(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
+ struct sge *s = &adap->sge;
+ u16 i;
+
+ if (!pi->vi_mirror_count)
+ return;
+
+ if (!s->mirror_rxq[pi->port_id])
+ return;
+
+ for (i = 0; i < pi->nmirrorqsets; i++)
+ cxgb4_port_mirror_free_rxq(adap,
+ &s->mirror_rxq[pi->port_id][i]);
+
+ kfree(s->mirror_rxq[pi->port_id]);
+ s->mirror_rxq[pi->port_id] = NULL;
+}
+
+static int cxgb4_port_mirror_start(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
+ int ret, idx = -1;
+
+ if (!pi->vi_mirror_count)
+ return 0;
+
+ /* Mirror VIs can be created dynamically after stack had
+ * already setup Rx modes like MTU, promisc, allmulti, etc.
+ * on main VI. So, parse what the stack had setup on the
+ * main VI and update the same on the mirror VI.
+ */
+ ret = t4_set_rxmode(adap, adap->mbox, pi->viid, pi->viid_mirror,
+ dev->mtu, (dev->flags & IFF_PROMISC) ? 1 : 0,
+ (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1,
+ !!(dev->features & NETIF_F_HW_VLAN_CTAG_RX), true);
+ if (ret) {
+ dev_err(adap->pdev_dev,
+ "Failed start up Rx mode for Mirror VI 0x%x, ret: %d\n",
+ pi->viid_mirror, ret);
+ return ret;
+ }
+
+ /* Enable replication bit for the device's MAC address
+ * in MPS TCAM, so that the packets for the main VI are
+ * replicated to mirror VI.
+ */
+ ret = cxgb4_update_mac_filt(pi, pi->viid_mirror, &idx,
+ dev->dev_addr, true, NULL);
+ if (ret) {
+ dev_err(adap->pdev_dev,
+ "Failed updating MAC filter for Mirror VI 0x%x, ret: %d\n",
+ pi->viid_mirror, ret);
+ return ret;
+ }
+
+ /* Enabling a Virtual Interface can result in an interrupt
+ * during the processing of the VI Enable command and, in some
+ * paths, result in an attempt to issue another command in the
+ * interrupt context. Thus, we disable interrupts during the
+ * course of the VI Enable command ...
+ */
+ local_bh_disable();
+ ret = t4_enable_vi_params(adap, adap->mbox, pi->viid_mirror, true, true,
+ false);
+ local_bh_enable();
+ if (ret)
+ dev_err(adap->pdev_dev,
+ "Failed starting Mirror VI 0x%x, ret: %d\n",
+ pi->viid_mirror, ret);
+
+ return ret;
+}
+
+static void cxgb4_port_mirror_stop(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
+
+ if (!pi->vi_mirror_count)
+ return;
+
+ t4_enable_vi_params(adap, adap->mbox, pi->viid_mirror, false, false,
+ false);
+}
+
+int cxgb4_port_mirror_alloc(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
+ int ret = 0;
+
+ if (!pi->nmirrorqsets)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&pi->vi_mirror_mutex);
+ if (pi->viid_mirror) {
+ pi->vi_mirror_count++;
+ goto out_unlock;
+ }
+
+ ret = t4_init_port_mirror(pi, adap->mbox, pi->port_id, adap->pf, 0,
+ &pi->viid_mirror);
+ if (ret)
+ goto out_unlock;
+
+ pi->vi_mirror_count = 1;
+
+ if (adap->flags & CXGB4_FULL_INIT_DONE) {
+ ret = cxgb4_port_mirror_alloc_queues(dev);
+ if (ret)
+ goto out_free_vi;
+
+ ret = cxgb4_port_mirror_start(dev);
+ if (ret)
+ goto out_free_queues;
+ }
+
+ mutex_unlock(&pi->vi_mirror_mutex);
+ return 0;
+
+out_free_queues:
+ cxgb4_port_mirror_free_queues(dev);
+
+out_free_vi:
+ pi->vi_mirror_count = 0;
+ t4_free_vi(adap, adap->mbox, adap->pf, 0, pi->viid_mirror);
+ pi->viid_mirror = 0;
+
+out_unlock:
+ mutex_unlock(&pi->vi_mirror_mutex);
+ return ret;
+}
+
+void cxgb4_port_mirror_free(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
+
+ mutex_lock(&pi->vi_mirror_mutex);
+ if (!pi->viid_mirror)
+ goto out_unlock;
+
+ if (pi->vi_mirror_count > 1) {
+ pi->vi_mirror_count--;
+ goto out_unlock;
+ }
+
+ cxgb4_port_mirror_stop(dev);
+ cxgb4_port_mirror_free_queues(dev);
+
+ pi->vi_mirror_count = 0;
+ t4_free_vi(adap, adap->mbox, adap->pf, 0, pi->viid_mirror);
+ pi->viid_mirror = 0;
+
+out_unlock:
+ mutex_unlock(&pi->vi_mirror_mutex);
+}
+
/*
* upper-layer driver support
*/
@@ -2557,8 +2855,29 @@ int cxgb_open(struct net_device *dev)
return err;
err = link_start(dev);
- if (!err)
- netif_tx_start_all_queues(dev);
+ if (err)
+ return err;
+
+ if (pi->nmirrorqsets) {
+ mutex_lock(&pi->vi_mirror_mutex);
+ err = cxgb4_port_mirror_alloc_queues(dev);
+ if (err)
+ goto out_unlock;
+
+ err = cxgb4_port_mirror_start(dev);
+ if (err)
+ goto out_free_queues;
+ mutex_unlock(&pi->vi_mirror_mutex);
+ }
+
+ netif_tx_start_all_queues(dev);
+ return 0;
+
+out_free_queues:
+ cxgb4_port_mirror_free_queues(dev);
+
+out_unlock:
+ mutex_unlock(&pi->vi_mirror_mutex);
return err;
}
@@ -2576,7 +2895,17 @@ int cxgb_close(struct net_device *dev)
cxgb4_dcb_reset(dev);
dcb_tx_queue_prio_enable(dev, false);
#endif
- return ret;
+ if (ret)
+ return ret;
+
+ if (pi->nmirrorqsets) {
+ mutex_lock(&pi->vi_mirror_mutex);
+ cxgb4_port_mirror_stop(dev);
+ cxgb4_port_mirror_free_queues(dev);
+ mutex_unlock(&pi->vi_mirror_mutex);
+ }
+
+ return 0;
}
int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
@@ -2842,11 +3171,11 @@ static void cxgb_set_rxmode(struct net_device *dev)
static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
{
- int ret;
struct port_info *pi = netdev_priv(dev);
+ int ret;
- ret = t4_set_rxmode(pi->adapter, pi->adapter->pf, pi->viid, new_mtu, -1,
- -1, -1, -1, true);
+ ret = t4_set_rxmode(pi->adapter, pi->adapter->mbox, pi->viid,
+ pi->viid_mirror, new_mtu, -1, -1, -1, -1, true);
if (!ret)
dev->mtu = new_mtu;
return ret;
@@ -3403,129 +3732,71 @@ static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type,
}
}
-static void cxgb_del_udp_tunnel(struct net_device *netdev,
- struct udp_tunnel_info *ti)
+static int cxgb_udp_tunnel_unset_port(struct net_device *netdev,
+ unsigned int table, unsigned int entry,
+ struct udp_tunnel_info *ti)
{
struct port_info *pi = netdev_priv(netdev);
struct adapter *adapter = pi->adapter;
- unsigned int chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
u8 match_all_mac[] = { 0, 0, 0, 0, 0, 0 };
int ret = 0, i;
- if (chip_ver < CHELSIO_T6)
- return;
-
switch (ti->type) {
case UDP_TUNNEL_TYPE_VXLAN:
- if (!adapter->vxlan_port_cnt ||
- adapter->vxlan_port != ti->port)
- return; /* Invalid VxLAN destination port */
-
- adapter->vxlan_port_cnt--;
- if (adapter->vxlan_port_cnt)
- return;
-
adapter->vxlan_port = 0;
t4_write_reg(adapter, MPS_RX_VXLAN_TYPE_A, 0);
break;
case UDP_TUNNEL_TYPE_GENEVE:
- if (!adapter->geneve_port_cnt ||
- adapter->geneve_port != ti->port)
- return; /* Invalid GENEVE destination port */
-
- adapter->geneve_port_cnt--;
- if (adapter->geneve_port_cnt)
- return;
-
adapter->geneve_port = 0;
t4_write_reg(adapter, MPS_RX_GENEVE_TYPE_A, 0);
break;
default:
- return;
+ return -EINVAL;
}
/* Matchall mac entries can be deleted only after all tunnel ports
* are brought down or removed.
*/
if (!adapter->rawf_cnt)
- return;
+ return 0;
for_each_port(adapter, i) {
pi = adap2pinfo(adapter, i);
ret = t4_free_raw_mac_filt(adapter, pi->viid,
match_all_mac, match_all_mac,
- adapter->rawf_start +
- pi->port_id,
+ adapter->rawf_start + pi->port_id,
1, pi->port_id, false);
if (ret < 0) {
netdev_info(netdev, "Failed to free mac filter entry, for port %d\n",
i);
- return;
+ return ret;
}
}
+
+ return 0;
}
-static void cxgb_add_udp_tunnel(struct net_device *netdev,
- struct udp_tunnel_info *ti)
+static int cxgb_udp_tunnel_set_port(struct net_device *netdev,
+ unsigned int table, unsigned int entry,
+ struct udp_tunnel_info *ti)
{
struct port_info *pi = netdev_priv(netdev);
struct adapter *adapter = pi->adapter;
- unsigned int chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
u8 match_all_mac[] = { 0, 0, 0, 0, 0, 0 };
int i, ret;
- if (chip_ver < CHELSIO_T6 || !adapter->rawf_cnt)
- return;
-
switch (ti->type) {
case UDP_TUNNEL_TYPE_VXLAN:
- /* Callback for adding vxlan port can be called with the same
- * port for both IPv4 and IPv6. We should not disable the
- * offloading when the same port for both protocols is added
- * and later one of them is removed.
- */
- if (adapter->vxlan_port_cnt &&
- adapter->vxlan_port == ti->port) {
- adapter->vxlan_port_cnt++;
- return;
- }
-
- /* We will support only one VxLAN port */
- if (adapter->vxlan_port_cnt) {
- netdev_info(netdev, "UDP port %d already offloaded, not adding port %d\n",
- be16_to_cpu(adapter->vxlan_port),
- be16_to_cpu(ti->port));
- return;
- }
-
adapter->vxlan_port = ti->port;
- adapter->vxlan_port_cnt = 1;
-
t4_write_reg(adapter, MPS_RX_VXLAN_TYPE_A,
VXLAN_V(be16_to_cpu(ti->port)) | VXLAN_EN_F);
break;
case UDP_TUNNEL_TYPE_GENEVE:
- if (adapter->geneve_port_cnt &&
- adapter->geneve_port == ti->port) {
- adapter->geneve_port_cnt++;
- return;
- }
-
- /* We will support only one GENEVE port */
- if (adapter->geneve_port_cnt) {
- netdev_info(netdev, "UDP port %d already offloaded, not adding port %d\n",
- be16_to_cpu(adapter->geneve_port),
- be16_to_cpu(ti->port));
- return;
- }
-
adapter->geneve_port = ti->port;
- adapter->geneve_port_cnt = 1;
-
t4_write_reg(adapter, MPS_RX_GENEVE_TYPE_A,
GENEVE_V(be16_to_cpu(ti->port)) | GENEVE_EN_F);
break;
default:
- return;
+ return -EINVAL;
}
/* Create a 'match all' mac filter entry for inner mac,
@@ -3540,18 +3811,27 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev,
ret = t4_alloc_raw_mac_filt(adapter, pi->viid,
match_all_mac,
match_all_mac,
- adapter->rawf_start +
- pi->port_id,
+ adapter->rawf_start + pi->port_id,
1, pi->port_id, false);
if (ret < 0) {
netdev_info(netdev, "Failed to allocate a mac filter entry, not adding port %d\n",
be16_to_cpu(ti->port));
- cxgb_del_udp_tunnel(netdev, ti);
- return;
+ return ret;
}
}
+
+ return 0;
}
+static const struct udp_tunnel_nic_info cxgb_udp_tunnels = {
+ .set_port = cxgb_udp_tunnel_set_port,
+ .unset_port = cxgb_udp_tunnel_unset_port,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+ },
+};
+
static netdev_features_t cxgb_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
@@ -3601,8 +3881,8 @@ static const struct net_device_ops cxgb4_netdev_ops = {
#endif /* CONFIG_CHELSIO_T4_FCOE */
.ndo_set_tx_maxrate = cxgb_set_tx_maxrate,
.ndo_setup_tc = cxgb_setup_tc,
- .ndo_udp_tunnel_add = cxgb_add_udp_tunnel,
- .ndo_udp_tunnel_del = cxgb_del_udp_tunnel,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = cxgb_features_check,
.ndo_fix_features = cxgb_fix_features,
};
@@ -4147,9 +4427,10 @@ static int adap_init0_phy(struct adapter *adap)
/* Load PHY Firmware onto adapter.
*/
- ret = t4_load_phy_fw(adap, MEMWIN_NIC, &adap->win0_lock,
- phy_info->phy_fw_version,
+ spin_lock_bh(&adap->win0_lock);
+ ret = t4_load_phy_fw(adap, MEMWIN_NIC, phy_info->phy_fw_version,
(u8 *)phyf->data, phyf->size);
+ spin_unlock_bh(&adap->win0_lock);
if (ret < 0)
dev_err(adap->pdev_dev, "PHY Firmware transfer error %d\n",
-ret);
@@ -5503,6 +5784,19 @@ static int cfg_queues(struct adapter *adap)
avail_qsets -= s->eoqsets;
}
+ /* Mirror queues must follow same scheme as normal Ethernet
+ * Queues, when there are enough queues available. Otherwise,
+ * allocate at least 1 queue per port. If even 1 queue is not
+ * available, then disable mirror queues support.
+ */
+ if (avail_qsets >= s->max_ethqsets)
+ s->mirrorqsets = s->max_ethqsets;
+ else if (avail_qsets >= adap->params.nports)
+ s->mirrorqsets = adap->params.nports;
+ else
+ s->mirrorqsets = 0;
+ avail_qsets -= s->mirrorqsets;
+
for (i = 0; i < ARRAY_SIZE(s->ethrxq); i++) {
struct sge_eth_rxq *r = &s->ethrxq[i];
@@ -5616,8 +5910,8 @@ void cxgb4_free_msix_idx_in_bmap(struct adapter *adap,
static int enable_msix(struct adapter *adap)
{
- u32 eth_need, uld_need = 0, ethofld_need = 0;
- u32 ethqsets = 0, ofldqsets = 0, eoqsets = 0;
+ u32 eth_need, uld_need = 0, ethofld_need = 0, mirror_need = 0;
+ u32 ethqsets = 0, ofldqsets = 0, eoqsets = 0, mirrorqsets = 0;
u8 num_uld = 0, nchan = adap->params.nports;
u32 i, want, need, num_vec;
struct sge *s = &adap->sge;
@@ -5648,6 +5942,12 @@ static int enable_msix(struct adapter *adap)
need += ethofld_need;
}
+ if (s->mirrorqsets) {
+ want += s->mirrorqsets;
+ mirror_need = nchan;
+ need += mirror_need;
+ }
+
want += EXTRA_VECS;
need += EXTRA_VECS;
@@ -5681,8 +5981,10 @@ static int enable_msix(struct adapter *adap)
adap->params.ethofld = 0;
s->ofldqsets = 0;
s->eoqsets = 0;
+ s->mirrorqsets = 0;
uld_need = 0;
ethofld_need = 0;
+ mirror_need = 0;
}
num_vec = allocated;
@@ -5696,6 +5998,8 @@ static int enable_msix(struct adapter *adap)
ofldqsets = nchan;
if (is_ethofld(adap))
eoqsets = ethofld_need;
+ if (s->mirrorqsets)
+ mirrorqsets = mirror_need;
num_vec -= need;
while (num_vec) {
@@ -5727,12 +6031,25 @@ static int enable_msix(struct adapter *adap)
num_vec -= uld_need;
}
}
+
+ if (s->mirrorqsets) {
+ while (num_vec) {
+ if (num_vec < mirror_need ||
+ mirrorqsets > s->mirrorqsets)
+ break;
+
+ mirrorqsets++;
+ num_vec -= mirror_need;
+ }
+ }
} else {
ethqsets = s->max_ethqsets;
if (is_uld(adap))
ofldqsets = s->ofldqsets;
if (is_ethofld(adap))
eoqsets = s->eoqsets;
+ if (s->mirrorqsets)
+ mirrorqsets = s->mirrorqsets;
}
if (ethqsets < s->max_ethqsets) {
@@ -5748,6 +6065,15 @@ static int enable_msix(struct adapter *adap)
if (is_ethofld(adap))
s->eoqsets = eoqsets;
+ if (s->mirrorqsets) {
+ s->mirrorqsets = mirrorqsets;
+ for_each_port(adap, i) {
+ pi = adap2pinfo(adap, i);
+ pi->nmirrorqsets = s->mirrorqsets / nchan;
+ mutex_init(&pi->vi_mirror_mutex);
+ }
+ }
+
/* map for msix */
ret = alloc_msix_info(adap, allocated);
if (ret)
@@ -5759,8 +6085,9 @@ static int enable_msix(struct adapter *adap)
}
dev_info(adap->pdev_dev,
- "%d MSI-X vectors allocated, nic %d eoqsets %d per uld %d\n",
- allocated, s->max_ethqsets, s->eoqsets, s->nqs_per_uld);
+ "%d MSI-X vectors allocated, nic %d eoqsets %d per uld %d mirrorqsets %d\n",
+ allocated, s->max_ethqsets, s->eoqsets, s->nqs_per_uld,
+ s->mirrorqsets);
kfree(entries);
return 0;
@@ -5861,6 +6188,7 @@ static void free_some_resources(struct adapter *adapter)
cxgb4_cleanup_tc_mqprio(adapter);
cxgb4_cleanup_tc_flower(adapter);
cxgb4_cleanup_tc_u32(adapter);
+ cxgb4_cleanup_ethtool_filters(adapter);
kfree(adapter->sge.egr_map);
kfree(adapter->sge.ingr_map);
kfree(adapter->sge.starving_fl);
@@ -6371,7 +6699,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_GRO |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HW_TC;
+ NETIF_F_HW_TC | NETIF_F_NTUPLE;
if (chip_ver > CHELSIO_T5) {
netdev->hw_enc_features |= NETIF_F_IP_CSUM |
@@ -6384,6 +6712,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_HW_TLS_RECORD;
+
+ if (adapter->rawf_cnt)
+ netdev->udp_tunnel_nic_info = &cxgb_udp_tunnels;
}
if (highdma)
@@ -6494,6 +6825,24 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
i);
}
+ if (is_offload(adapter) || is_hashfilter(adapter)) {
+ if (t4_read_reg(adapter, LE_DB_CONFIG_A) & HASHEN_F) {
+ u32 v;
+
+ v = t4_read_reg(adapter, LE_DB_HASH_CONFIG_A);
+ if (chip_ver <= CHELSIO_T5) {
+ adapter->tids.nhash = 1 << HASHTIDSIZE_G(v);
+ v = t4_read_reg(adapter, LE_DB_TID_HASHBASE_A);
+ adapter->tids.hash_base = v / 4;
+ } else {
+ adapter->tids.nhash = HASHTBLSIZE_G(v) << 3;
+ v = t4_read_reg(adapter,
+ T6_LE_DB_HASH_TID_BASE_A);
+ adapter->tids.hash_base = v;
+ }
+ }
+ }
+
if (tid_init(&adapter->tids) < 0) {
dev_warn(&pdev->dev, "could not allocate TID table, "
"continuing\n");
@@ -6515,22 +6864,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (cxgb4_init_tc_matchall(adapter))
dev_warn(&pdev->dev,
"could not offload tc matchall, continuing\n");
- }
-
- if (is_offload(adapter) || is_hashfilter(adapter)) {
- if (t4_read_reg(adapter, LE_DB_CONFIG_A) & HASHEN_F) {
- u32 hash_base, hash_reg;
-
- if (chip_ver <= CHELSIO_T5) {
- hash_reg = LE_DB_TID_HASHBASE_A;
- hash_base = t4_read_reg(adapter, hash_reg);
- adapter->tids.hash_base = hash_base / 4;
- } else {
- hash_reg = T6_LE_DB_HASH_TID_BASE_A;
- hash_base = t4_read_reg(adapter, hash_reg);
- adapter->tids.hash_base = hash_base;
- }
- }
+ if (cxgb4_init_ethtool_filters(adapter))
+ dev_warn(&pdev->dev,
+ "could not initialize ethtool filters, continuing\n");
}
/* See what interrupts we'll be using */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index 59b65d4db086..f642c1b475c4 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -77,10 +77,9 @@ static struct ch_tc_flower_entry *ch_flower_lookup(struct adapter *adap,
}
static void cxgb4_process_flow_match(struct net_device *dev,
- struct flow_cls_offload *cls,
+ struct flow_rule *rule,
struct ch_filter_specification *fs)
{
- struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
u16 addr_type = 0;
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
@@ -88,6 +87,10 @@ static void cxgb4_process_flow_match(struct net_device *dev,
flow_rule_match_control(rule, &match);
addr_type = match.key->addr_type;
+ } else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
+ addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+ } else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
+ addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
@@ -220,9 +223,8 @@ static void cxgb4_process_flow_match(struct net_device *dev,
}
static int cxgb4_validate_flow_match(struct net_device *dev,
- struct flow_cls_offload *cls)
+ struct flow_rule *rule)
{
- struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
struct flow_dissector *dissector = rule->match.dissector;
u16 ethtype_mask = 0;
u16 ethtype_key = 0;
@@ -383,6 +385,7 @@ void cxgb4_process_flow_actions(struct net_device *in,
case FLOW_ACTION_DROP:
fs->action = FILTER_DROP;
break;
+ case FLOW_ACTION_MIRRED:
case FLOW_ACTION_REDIRECT: {
struct net_device *out = act->dev;
struct port_info *pi = netdev_priv(out);
@@ -426,6 +429,11 @@ void cxgb4_process_flow_actions(struct net_device *in,
process_pedit_field(fs, val, mask, offset, htype);
}
break;
+ case FLOW_ACTION_QUEUE:
+ fs->action = FILTER_PASS;
+ fs->dirsteer = 1;
+ fs->iq = act->queue.index;
+ break;
default:
break;
}
@@ -535,7 +543,8 @@ static bool valid_pedit_action(struct net_device *dev,
int cxgb4_validate_flow_actions(struct net_device *dev,
struct flow_action *actions,
- struct netlink_ext_ack *extack)
+ struct netlink_ext_ack *extack,
+ u8 matchall_filter)
{
struct flow_action_entry *act;
bool act_redir = false;
@@ -552,11 +561,19 @@ int cxgb4_validate_flow_actions(struct net_device *dev,
case FLOW_ACTION_DROP:
/* Do nothing */
break;
+ case FLOW_ACTION_MIRRED:
case FLOW_ACTION_REDIRECT: {
struct adapter *adap = netdev2adap(dev);
struct net_device *n_dev, *target_dev;
- unsigned int i;
bool found = false;
+ unsigned int i;
+
+ if (act->id == FLOW_ACTION_MIRRED &&
+ !matchall_filter) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Egress mirror action is only supported for tc-matchall");
+ return -EOPNOTSUPP;
+ }
target_dev = act->dev;
for_each_port(adap, i) {
@@ -610,6 +627,9 @@ int cxgb4_validate_flow_actions(struct net_device *dev,
act_pedit = true;
}
break;
+ case FLOW_ACTION_QUEUE:
+ /* Do nothing. cxgb4_set_filter will validate */
+ break;
default:
netdev_err(dev, "%s: Unsupported action\n", __func__);
return -EOPNOTSUPP;
@@ -683,33 +703,22 @@ out_unlock:
spin_unlock_bh(&t->ftid_lock);
}
-int cxgb4_tc_flower_replace(struct net_device *dev,
- struct flow_cls_offload *cls)
+int cxgb4_flow_rule_replace(struct net_device *dev, struct flow_rule *rule,
+ u32 tc_prio, struct netlink_ext_ack *extack,
+ struct ch_filter_specification *fs, u32 *tid)
{
- struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
- struct netlink_ext_ack *extack = cls->common.extack;
struct adapter *adap = netdev2adap(dev);
- struct ch_tc_flower_entry *ch_flower;
- struct ch_filter_specification *fs;
struct filter_ctx ctx;
u8 inet_family;
int fidx, ret;
- if (cxgb4_validate_flow_actions(dev, &rule->action, extack))
+ if (cxgb4_validate_flow_actions(dev, &rule->action, extack, 0))
return -EOPNOTSUPP;
- if (cxgb4_validate_flow_match(dev, cls))
+ if (cxgb4_validate_flow_match(dev, rule))
return -EOPNOTSUPP;
- ch_flower = allocate_flower_entry();
- if (!ch_flower) {
- netdev_err(dev, "%s: ch_flower alloc failed.\n", __func__);
- return -ENOMEM;
- }
-
- fs = &ch_flower->fs;
- fs->hitcnts = 1;
- cxgb4_process_flow_match(dev, cls, fs);
+ cxgb4_process_flow_match(dev, rule, fs);
cxgb4_process_flow_actions(dev, &rule->action, fs);
fs->hash = is_filter_exact_match(adap, fs);
@@ -720,12 +729,11 @@ int cxgb4_tc_flower_replace(struct net_device *dev,
* existing rules.
*/
fidx = cxgb4_get_free_ftid(dev, inet_family, fs->hash,
- cls->common.prio);
+ tc_prio);
if (fidx < 0) {
NL_SET_ERR_MSG_MOD(extack,
"No free LETCAM index available");
- ret = -ENOMEM;
- goto free_entry;
+ return -ENOMEM;
}
if (fidx < adap->tids.nhpftids) {
@@ -739,42 +747,70 @@ int cxgb4_tc_flower_replace(struct net_device *dev,
if (fs->hash)
fidx = 0;
- fs->tc_prio = cls->common.prio;
- fs->tc_cookie = cls->cookie;
+ fs->tc_prio = tc_prio;
init_completion(&ctx.completion);
ret = __cxgb4_set_filter(dev, fidx, fs, &ctx);
if (ret) {
netdev_err(dev, "%s: filter creation err %d\n",
__func__, ret);
- goto free_entry;
+ return ret;
}
/* Wait for reply */
ret = wait_for_completion_timeout(&ctx.completion, 10 * HZ);
- if (!ret) {
- ret = -ETIMEDOUT;
- goto free_entry;
- }
+ if (!ret)
+ return -ETIMEDOUT;
- ret = ctx.result;
/* Check if hw returned error for filter creation */
+ if (ctx.result)
+ return ctx.result;
+
+ *tid = ctx.tid;
+
+ if (fs->hash)
+ cxgb4_tc_flower_hash_prio_add(adap, tc_prio);
+
+ return 0;
+}
+
+int cxgb4_tc_flower_replace(struct net_device *dev,
+ struct flow_cls_offload *cls)
+{
+ struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
+ struct netlink_ext_ack *extack = cls->common.extack;
+ struct adapter *adap = netdev2adap(dev);
+ struct ch_tc_flower_entry *ch_flower;
+ struct ch_filter_specification *fs;
+ int ret;
+
+ ch_flower = allocate_flower_entry();
+ if (!ch_flower) {
+ netdev_err(dev, "%s: ch_flower alloc failed.\n", __func__);
+ return -ENOMEM;
+ }
+
+ fs = &ch_flower->fs;
+ fs->hitcnts = 1;
+ fs->tc_cookie = cls->cookie;
+
+ ret = cxgb4_flow_rule_replace(dev, rule, cls->common.prio, extack, fs,
+ &ch_flower->filter_id);
if (ret)
goto free_entry;
ch_flower->tc_flower_cookie = cls->cookie;
- ch_flower->filter_id = ctx.tid;
ret = rhashtable_insert_fast(&adap->flower_tbl, &ch_flower->node,
adap->flower_ht_params);
if (ret)
goto del_filter;
- if (fs->hash)
- cxgb4_tc_flower_hash_prio_add(adap, cls->common.prio);
-
return 0;
del_filter:
+ if (fs->hash)
+ cxgb4_tc_flower_hash_prio_del(adap, cls->common.prio);
+
cxgb4_del_filter(dev, ch_flower->filter_id, &ch_flower->fs);
free_entry:
@@ -782,23 +818,38 @@ free_entry:
return ret;
}
+int cxgb4_flow_rule_destroy(struct net_device *dev, u32 tc_prio,
+ struct ch_filter_specification *fs, int tid)
+{
+ struct adapter *adap = netdev2adap(dev);
+ u8 hash;
+ int ret;
+
+ hash = fs->hash;
+
+ ret = cxgb4_del_filter(dev, tid, fs);
+ if (ret)
+ return ret;
+
+ if (hash)
+ cxgb4_tc_flower_hash_prio_del(adap, tc_prio);
+
+ return ret;
+}
+
int cxgb4_tc_flower_destroy(struct net_device *dev,
struct flow_cls_offload *cls)
{
struct adapter *adap = netdev2adap(dev);
struct ch_tc_flower_entry *ch_flower;
- u32 tc_prio;
- bool hash;
int ret;
ch_flower = ch_flower_lookup(adap, cls->cookie);
if (!ch_flower)
return -ENOENT;
- hash = ch_flower->fs.hash;
- tc_prio = ch_flower->fs.tc_prio;
-
- ret = cxgb4_del_filter(dev, ch_flower->filter_id, &ch_flower->fs);
+ ret = cxgb4_flow_rule_destroy(dev, ch_flower->fs.tc_prio,
+ &ch_flower->fs, ch_flower->filter_id);
if (ret)
goto err;
@@ -810,9 +861,6 @@ int cxgb4_tc_flower_destroy(struct net_device *dev,
}
kfree_rcu(ch_flower, rcu);
- if (hash)
- cxgb4_tc_flower_hash_prio_del(adap, tc_prio);
-
err:
return ret;
}
@@ -892,7 +940,7 @@ int cxgb4_tc_flower_stats(struct net_device *dev,
if (ofld_stats->prev_packet_count != packets)
ofld_stats->last_used = jiffies;
flow_stats_update(&cls->stats, bytes - ofld_stats->byte_count,
- packets - ofld_stats->packet_count,
+ packets - ofld_stats->packet_count, 0,
ofld_stats->last_used,
FLOW_ACTION_HW_STATS_IMMEDIATE);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
index 0a30c96b81ff..6296e1d5a12b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
@@ -113,7 +113,8 @@ void cxgb4_process_flow_actions(struct net_device *in,
struct ch_filter_specification *fs);
int cxgb4_validate_flow_actions(struct net_device *dev,
struct flow_action *actions,
- struct netlink_ext_ack *extack);
+ struct netlink_ext_ack *extack,
+ u8 matchall_filter);
int cxgb4_tc_flower_replace(struct net_device *dev,
struct flow_cls_offload *cls);
@@ -121,6 +122,11 @@ int cxgb4_tc_flower_destroy(struct net_device *dev,
struct flow_cls_offload *cls);
int cxgb4_tc_flower_stats(struct net_device *dev,
struct flow_cls_offload *cls);
+int cxgb4_flow_rule_replace(struct net_device *dev, struct flow_rule *rule,
+ u32 tc_prio, struct netlink_ext_ack *extack,
+ struct ch_filter_specification *fs, u32 *tid);
+int cxgb4_flow_rule_destroy(struct net_device *dev, u32 tc_prio,
+ struct ch_filter_specification *fs, int tid);
int cxgb4_init_tc_flower(struct adapter *adap);
void cxgb4_cleanup_tc_flower(struct adapter *adap);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
index c88c47a14fbb..2e309f6673f7 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
@@ -188,23 +188,83 @@ static void cxgb4_matchall_free_tc(struct net_device *dev)
tc_port_matchall->egress.state = CXGB4_MATCHALL_STATE_DISABLED;
}
-static int cxgb4_matchall_alloc_filter(struct net_device *dev,
+static int cxgb4_matchall_mirror_alloc(struct net_device *dev,
struct tc_cls_matchall_offload *cls)
{
struct netlink_ext_ack *extack = cls->common.extack;
struct cxgb4_tc_port_matchall *tc_port_matchall;
struct port_info *pi = netdev2pinfo(dev);
struct adapter *adap = netdev2adap(dev);
+ struct flow_action_entry *act;
+ int ret;
+ u32 i;
+
+ tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id];
+ flow_action_for_each(i, act, &cls->rule->action) {
+ if (act->id == FLOW_ACTION_MIRRED) {
+ ret = cxgb4_port_mirror_alloc(dev);
+ if (ret) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Couldn't allocate mirror");
+ return ret;
+ }
+
+ tc_port_matchall->ingress.viid_mirror = pi->viid_mirror;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void cxgb4_matchall_mirror_free(struct net_device *dev)
+{
+ struct cxgb4_tc_port_matchall *tc_port_matchall;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
+
+ tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id];
+ if (!tc_port_matchall->ingress.viid_mirror)
+ return;
+
+ cxgb4_port_mirror_free(dev);
+ tc_port_matchall->ingress.viid_mirror = 0;
+}
+
+static int cxgb4_matchall_del_filter(struct net_device *dev, u8 filter_type)
+{
+ struct cxgb4_tc_port_matchall *tc_port_matchall;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
+ int ret;
+
+ tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id];
+ ret = cxgb4_del_filter(dev, tc_port_matchall->ingress.tid[filter_type],
+ &tc_port_matchall->ingress.fs[filter_type]);
+ if (ret)
+ return ret;
+
+ tc_port_matchall->ingress.tid[filter_type] = 0;
+ return 0;
+}
+
+static int cxgb4_matchall_add_filter(struct net_device *dev,
+ struct tc_cls_matchall_offload *cls,
+ u8 filter_type)
+{
+ struct netlink_ext_ack *extack = cls->common.extack;
+ struct cxgb4_tc_port_matchall *tc_port_matchall;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
struct ch_filter_specification *fs;
int ret, fidx;
/* Get a free filter entry TID, where we can insert this new
* rule. Only insert rule if its prio doesn't conflict with
* existing rules.
- *
- * 1 slot is enough to create a wildcard matchall VIID rule.
*/
- fidx = cxgb4_get_free_ftid(dev, PF_INET, false, cls->common.prio);
+ fidx = cxgb4_get_free_ftid(dev, filter_type ? PF_INET6 : PF_INET,
+ false, cls->common.prio);
if (fidx < 0) {
NL_SET_ERR_MSG_MOD(extack,
"No free LETCAM index available");
@@ -212,13 +272,14 @@ static int cxgb4_matchall_alloc_filter(struct net_device *dev,
}
tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id];
- fs = &tc_port_matchall->ingress.fs;
+ fs = &tc_port_matchall->ingress.fs[filter_type];
memset(fs, 0, sizeof(*fs));
if (fidx < adap->tids.nhpftids)
fs->prio = 1;
fs->tc_prio = cls->common.prio;
fs->tc_cookie = cls->cookie;
+ fs->type = filter_type;
fs->hitcnts = 1;
fs->val.pfvf_vld = 1;
@@ -231,9 +292,39 @@ static int cxgb4_matchall_alloc_filter(struct net_device *dev,
if (ret)
return ret;
- tc_port_matchall->ingress.tid = fidx;
+ tc_port_matchall->ingress.tid[filter_type] = fidx;
+ return 0;
+}
+
+static int cxgb4_matchall_alloc_filter(struct net_device *dev,
+ struct tc_cls_matchall_offload *cls)
+{
+ struct cxgb4_tc_port_matchall *tc_port_matchall;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = netdev2adap(dev);
+ int ret, i;
+
+ tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id];
+
+ ret = cxgb4_matchall_mirror_alloc(dev, cls);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < CXGB4_FILTER_TYPE_MAX; i++) {
+ ret = cxgb4_matchall_add_filter(dev, cls, i);
+ if (ret)
+ goto out_free;
+ }
+
tc_port_matchall->ingress.state = CXGB4_MATCHALL_STATE_ENABLED;
return 0;
+
+out_free:
+ while (i-- > 0)
+ cxgb4_matchall_del_filter(dev, i);
+
+ cxgb4_matchall_mirror_free(dev);
+ return ret;
}
static int cxgb4_matchall_free_filter(struct net_device *dev)
@@ -242,18 +333,21 @@ static int cxgb4_matchall_free_filter(struct net_device *dev)
struct port_info *pi = netdev2pinfo(dev);
struct adapter *adap = netdev2adap(dev);
int ret;
+ u8 i;
tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id];
- ret = cxgb4_del_filter(dev, tc_port_matchall->ingress.tid,
- &tc_port_matchall->ingress.fs);
- if (ret)
- return ret;
+ for (i = 0; i < CXGB4_FILTER_TYPE_MAX; i++) {
+ ret = cxgb4_matchall_del_filter(dev, i);
+ if (ret)
+ return ret;
+ }
+
+ cxgb4_matchall_mirror_free(dev);
tc_port_matchall->ingress.packets = 0;
tc_port_matchall->ingress.bytes = 0;
tc_port_matchall->ingress.last_used = 0;
- tc_port_matchall->ingress.tid = 0;
tc_port_matchall->ingress.state = CXGB4_MATCHALL_STATE_DISABLED;
return 0;
}
@@ -279,7 +373,7 @@ int cxgb4_tc_matchall_replace(struct net_device *dev,
ret = cxgb4_validate_flow_actions(dev,
&cls_matchall->rule->action,
- extack);
+ extack, 1);
if (ret)
return ret;
@@ -309,8 +403,12 @@ int cxgb4_tc_matchall_destroy(struct net_device *dev,
tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id];
if (ingress) {
+ /* All the filter types of this matchall rule save the
+ * same cookie. So, checking for the first one is
+ * enough.
+ */
if (cls_matchall->cookie !=
- tc_port_matchall->ingress.fs.tc_cookie)
+ tc_port_matchall->ingress.fs[0].tc_cookie)
return -ENOENT;
return cxgb4_matchall_free_filter(dev);
@@ -326,27 +424,35 @@ int cxgb4_tc_matchall_destroy(struct net_device *dev,
int cxgb4_tc_matchall_stats(struct net_device *dev,
struct tc_cls_matchall_offload *cls_matchall)
{
+ u64 tmp_packets, tmp_bytes, packets = 0, bytes = 0;
struct cxgb4_tc_port_matchall *tc_port_matchall;
+ struct cxgb4_matchall_ingress_entry *ingress;
struct port_info *pi = netdev2pinfo(dev);
struct adapter *adap = netdev2adap(dev);
- u64 packets, bytes;
int ret;
+ u8 i;
tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id];
if (tc_port_matchall->ingress.state == CXGB4_MATCHALL_STATE_DISABLED)
return -ENOENT;
- ret = cxgb4_get_filter_counters(dev, tc_port_matchall->ingress.tid,
- &packets, &bytes,
- tc_port_matchall->ingress.fs.hash);
- if (ret)
- return ret;
+ ingress = &tc_port_matchall->ingress;
+ for (i = 0; i < CXGB4_FILTER_TYPE_MAX; i++) {
+ ret = cxgb4_get_filter_counters(dev, ingress->tid[i],
+ &tmp_packets, &tmp_bytes,
+ ingress->fs[i].hash);
+ if (ret)
+ return ret;
+
+ packets += tmp_packets;
+ bytes += tmp_bytes;
+ }
if (tc_port_matchall->ingress.packets != packets) {
flow_stats_update(&cls_matchall->stats,
bytes - tc_port_matchall->ingress.bytes,
packets - tc_port_matchall->ingress.packets,
- tc_port_matchall->ingress.last_used,
+ 0, tc_port_matchall->ingress.last_used,
FLOW_ACTION_HW_STATS_IMMEDIATE);
tc_port_matchall->ingress.packets = packets;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.h
index ab6b5683dfd3..fe7ec423a4c9 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.h
@@ -19,8 +19,10 @@ struct cxgb4_matchall_egress_entry {
struct cxgb4_matchall_ingress_entry {
enum cxgb4_matchall_state state; /* Current MATCHALL offload state */
- u32 tid; /* Index to hardware filter entry */
- struct ch_filter_specification fs; /* Filter entry */
+ u32 tid[CXGB4_FILTER_TYPE_MAX]; /* Index to hardware filter entries */
+ /* Filter entries */
+ struct ch_filter_specification fs[CXGB4_FILTER_TYPE_MAX];
+ u16 viid_mirror; /* Identifier for allocated Mirror VI */
u64 bytes; /* # of bytes hitting the filter */
u64 packets; /* # of packets hitting the filter */
u64 last_used; /* Last updated jiffies time */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index dbce99b209d6..a963fd0b4540 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -106,6 +106,8 @@ struct tid_info {
unsigned long *stid_bmap;
unsigned int nstids;
unsigned int stid_base;
+
+ unsigned int nhash;
unsigned int hash_base;
union aopen_entry *atid_tab;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index 92eee66cbc84..d2b587d1670a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -2432,7 +2432,7 @@ int cxgb4_ethofld_send_flowc(struct net_device *dev, u32 eotid, u32 tc)
struct sk_buff *skb;
int ret = 0;
- len = sizeof(*flowc) + sizeof(struct fw_flowc_mnemval) * nparams;
+ len = struct_size(flowc, mnemval, nparams);
len16 = DIV_ROUND_UP(len, 16);
entry = cxgb4_lookup_eotid(&adap->tids, eotid);
@@ -2537,6 +2537,80 @@ static void ctrlq_check_stop(struct sge_ctrl_txq *q, struct fw_wr_hdr *wr)
}
}
+#define CXGB4_SELFTEST_LB_STR "CHELSIO_SELFTEST"
+
+int cxgb4_selftest_lb_pkt(struct net_device *netdev)
+{
+ struct port_info *pi = netdev_priv(netdev);
+ struct adapter *adap = pi->adapter;
+ struct cxgb4_ethtool_lb_test *lb;
+ int ret, i = 0, pkt_len, credits;
+ struct fw_eth_tx_pkt_wr *wr;
+ struct cpl_tx_pkt_core *cpl;
+ u32 ctrl0, ndesc, flits;
+ struct sge_eth_txq *q;
+ u8 *sgl;
+
+ pkt_len = ETH_HLEN + sizeof(CXGB4_SELFTEST_LB_STR);
+
+ flits = DIV_ROUND_UP(pkt_len + sizeof(struct cpl_tx_pkt) +
+ sizeof(*wr), sizeof(__be64));
+ ndesc = flits_to_desc(flits);
+
+ lb = &pi->ethtool_lb;
+ lb->loopback = 1;
+
+ q = &adap->sge.ethtxq[pi->first_qset];
+
+ reclaim_completed_tx(adap, &q->q, -1, true);
+ credits = txq_avail(&q->q) - ndesc;
+ if (unlikely(credits < 0))
+ return -ENOMEM;
+
+ wr = (void *)&q->q.desc[q->q.pidx];
+ memset(wr, 0, sizeof(struct tx_desc));
+
+ wr->op_immdlen = htonl(FW_WR_OP_V(FW_ETH_TX_PKT_WR) |
+ FW_WR_IMMDLEN_V(pkt_len +
+ sizeof(*cpl)));
+ wr->equiq_to_len16 = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(flits, 2)));
+ wr->r3 = cpu_to_be64(0);
+
+ cpl = (void *)(wr + 1);
+ sgl = (u8 *)(cpl + 1);
+
+ ctrl0 = TXPKT_OPCODE_V(CPL_TX_PKT_XT) | TXPKT_PF_V(adap->pf) |
+ TXPKT_INTF_V(pi->tx_chan + 4);
+
+ cpl->ctrl0 = htonl(ctrl0);
+ cpl->pack = htons(0);
+ cpl->len = htons(pkt_len);
+ cpl->ctrl1 = cpu_to_be64(TXPKT_L4CSUM_DIS_F | TXPKT_IPCSUM_DIS_F);
+
+ eth_broadcast_addr(sgl);
+ i += ETH_ALEN;
+ ether_addr_copy(&sgl[i], netdev->dev_addr);
+ i += ETH_ALEN;
+
+ snprintf(&sgl[i], sizeof(CXGB4_SELFTEST_LB_STR), "%s",
+ CXGB4_SELFTEST_LB_STR);
+
+ init_completion(&lb->completion);
+ txq_advance(&q->q, ndesc);
+ cxgb4_ring_tx_db(adap, &q->q, ndesc);
+
+ /* wait for the pkt to return */
+ ret = wait_for_completion_timeout(&lb->completion, 10 * HZ);
+ if (!ret)
+ ret = -ETIMEDOUT;
+ else
+ ret = lb->result;
+
+ lb->loopback = 0;
+
+ return ret;
+}
+
/**
* ctrl_xmit - send a packet through an SGE control Tx queue
* @q: the control queue
@@ -3414,6 +3488,31 @@ static void t4_tx_completion_handler(struct sge_rspq *rspq,
t4_sge_eth_txq_egress_update(adapter, txq, -1);
}
+static int cxgb4_validate_lb_pkt(struct port_info *pi, const struct pkt_gl *si)
+{
+ struct adapter *adap = pi->adapter;
+ struct cxgb4_ethtool_lb_test *lb;
+ struct sge *s = &adap->sge;
+ struct net_device *netdev;
+ u8 *data;
+ int i;
+
+ netdev = adap->port[pi->port_id];
+ lb = &pi->ethtool_lb;
+ data = si->va + s->pktshift;
+
+ i = ETH_ALEN;
+ if (!ether_addr_equal(data + i, netdev->dev_addr))
+ return -1;
+
+ i += ETH_ALEN;
+ if (strcmp(&data[i], CXGB4_SELFTEST_LB_STR))
+ lb->result = -EIO;
+
+ complete(&lb->completion);
+ return 0;
+}
+
/**
* t4_ethrx_handler - process an ingress ethernet packet
* @q: the response queue that received the packet
@@ -3437,6 +3536,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
struct port_info *pi;
int ret = 0;
+ pi = netdev_priv(q->netdev);
/* If we're looking at TX Queue CIDX Update, handle that separately
* and return.
*/
@@ -3464,6 +3564,12 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
if (err_vec)
rxq->stats.bad_rx_pkts++;
+ if (unlikely(pi->ethtool_lb.loopback && pkt->iff >= NCHAN)) {
+ ret = cxgb4_validate_lb_pkt(pi, si);
+ if (!ret)
+ return 0;
+ }
+
if (((pkt->l2info & htonl(RXF_TCP_F)) ||
tnl_hdr_len) &&
(q->netdev->features & NETIF_F_GRO) && csum_ok && !pkt->ip_frag) {
@@ -3477,7 +3583,6 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
rxq->stats.rx_drops++;
return 0;
}
- pi = netdev_priv(q->netdev);
/* Handle PTP Event Rx packet */
if (unlikely(pi->ptp_enable)) {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/smt.c b/drivers/net/ethernet/chelsio/cxgb4/smt.c
index cbe72ed27b1e..e617e4aabbcc 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/smt.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/smt.c
@@ -55,7 +55,7 @@ struct smt_data *t4_init_smt(void)
for (i = 0; i < s->smt_size; ++i) {
s->smtab[i].idx = i;
s->smtab[i].state = SMT_STATE_UNUSED;
- memset(&s->smtab[i].src_mac, 0, ETH_ALEN);
+ eth_zero_addr(s->smtab[i].src_mac);
spin_lock_init(&s->smtab[i].lock);
s->smtab[i].refcnt = 0;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index ad522f822cc2..8a56491bb034 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -3752,7 +3752,6 @@ int t4_phy_fw_ver(struct adapter *adap, int *phy_fw_ver)
* t4_load_phy_fw - download port PHY firmware
* @adap: the adapter
* @win: the PCI-E Memory Window index to use for t4_memory_rw()
- * @win_lock: the lock to use to guard the memory copy
* @phy_fw_version: function to check PHY firmware versions
* @phy_fw_data: the PHY firmware image to write
* @phy_fw_size: image size
@@ -3761,9 +3760,7 @@ int t4_phy_fw_ver(struct adapter *adap, int *phy_fw_ver)
* @phy_fw_version is supplied, then it will be used to determine if
* it's necessary to perform the transfer by comparing the version
* of any existing adapter PHY firmware with that of the passed in
- * PHY firmware image. If @win_lock is non-NULL then it will be used
- * around the call to t4_memory_rw() which transfers the PHY firmware
- * to the adapter.
+ * PHY firmware image.
*
* A negative error number will be returned if an error occurs. If
* version number support is available and there's no need to upgrade
@@ -3775,14 +3772,13 @@ int t4_phy_fw_ver(struct adapter *adap, int *phy_fw_ver)
* contents. Thus, loading PHY firmware on such adapters must happen
* after any FW_RESET_CMDs ...
*/
-int t4_load_phy_fw(struct adapter *adap,
- int win, spinlock_t *win_lock,
+int t4_load_phy_fw(struct adapter *adap, int win,
int (*phy_fw_version)(const u8 *, size_t),
const u8 *phy_fw_data, size_t phy_fw_size)
{
+ int cur_phy_fw_ver = 0, new_phy_fw_vers = 0;
unsigned long mtype = 0, maddr = 0;
u32 param, val;
- int cur_phy_fw_ver = 0, new_phy_fw_vers = 0;
int ret;
/* If we have version number support, then check to see if the adapter
@@ -3822,13 +3818,9 @@ int t4_load_phy_fw(struct adapter *adap,
/* Copy the supplied PHY Firmware image to the adapter memory location
* allocated by the adapter firmware.
*/
- if (win_lock)
- spin_lock_bh(win_lock);
ret = t4_memory_rw(adap, win, mtype, maddr,
phy_fw_size, (__be32 *)phy_fw_data,
T4_MEMORY_WRITE);
- if (win_lock)
- spin_unlock_bh(win_lock);
if (ret)
return ret;
@@ -7719,6 +7711,7 @@ int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
* @adap: the adapter
* @mbox: mailbox to use for the FW command
* @viid: the VI id
+ * @viid_mirror: the mirror VI id
* @mtu: the new MTU or -1
* @promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change
* @all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change
@@ -7729,10 +7722,11 @@ int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
* Sets Rx properties of a virtual interface.
*/
int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
- int mtu, int promisc, int all_multi, int bcast, int vlanex,
- bool sleep_ok)
+ unsigned int viid_mirror, int mtu, int promisc, int all_multi,
+ int bcast, int vlanex, bool sleep_ok)
{
- struct fw_vi_rxmode_cmd c;
+ struct fw_vi_rxmode_cmd c, c_mirror;
+ int ret;
/* convert to FW values */
if (mtu < 0)
@@ -7757,7 +7751,24 @@ int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
FW_VI_RXMODE_CMD_ALLMULTIEN_V(all_multi) |
FW_VI_RXMODE_CMD_BROADCASTEN_V(bcast) |
FW_VI_RXMODE_CMD_VLANEXEN_V(vlanex));
- return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
+
+ if (viid_mirror) {
+ memcpy(&c_mirror, &c, sizeof(c_mirror));
+ c_mirror.op_to_viid =
+ cpu_to_be32(FW_CMD_OP_V(FW_VI_RXMODE_CMD) |
+ FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
+ FW_VI_RXMODE_CMD_VIID_V(viid_mirror));
+ }
+
+ ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
+ if (ret)
+ return ret;
+
+ if (viid_mirror)
+ ret = t4_wr_mbox_meat(adap, mbox, &c_mirror, sizeof(c_mirror),
+ NULL, sleep_ok);
+
+ return ret;
}
/**
@@ -9719,6 +9730,22 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
return 0;
}
+int t4_init_port_mirror(struct port_info *pi, u8 mbox, u8 port, u8 pf, u8 vf,
+ u16 *mirror_viid)
+{
+ int ret;
+
+ ret = t4_alloc_vi(pi->adapter, mbox, port, pf, vf, 1, NULL, NULL,
+ NULL, NULL);
+ if (ret < 0)
+ return ret;
+
+ if (mirror_viid)
+ *mirror_viid = ret;
+
+ return 0;
+}
+
/**
* t4_read_cimq_cfg - read CIM queue configuration
* @adap: the adapter
@@ -10481,3 +10508,280 @@ int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
return t4_wr_mbox(adap, adap->mbox, &vlan_cmd, sizeof(vlan_cmd), NULL);
}
+
+/**
+ * modify_device_id - Modifies the device ID of the Boot BIOS image
+ * @device_id: the device ID to write.
+ * @boot_data: the boot image to modify.
+ *
+ * Write the supplied device ID to the boot BIOS image.
+ */
+static void modify_device_id(int device_id, u8 *boot_data)
+{
+ struct cxgb4_pcir_data *pcir_header;
+ struct legacy_pci_rom_hdr *header;
+ u8 *cur_header = boot_data;
+ u16 pcir_offset;
+
+ /* Loop through all chained images and change the device ID's */
+ do {
+ header = (struct legacy_pci_rom_hdr *)cur_header;
+ pcir_offset = le16_to_cpu(header->pcir_offset);
+ pcir_header = (struct cxgb4_pcir_data *)(cur_header +
+ pcir_offset);
+
+ /**
+ * Only modify the Device ID if code type is Legacy or HP.
+ * 0x00: Okay to modify
+ * 0x01: FCODE. Do not modify
+ * 0x03: Okay to modify
+ * 0x04-0xFF: Do not modify
+ */
+ if (pcir_header->code_type == CXGB4_HDR_CODE1) {
+ u8 csum = 0;
+ int i;
+
+ /**
+ * Modify Device ID to match current adatper
+ */
+ pcir_header->device_id = cpu_to_le16(device_id);
+
+ /**
+ * Set checksum temporarily to 0.
+ * We will recalculate it later.
+ */
+ header->cksum = 0x0;
+
+ /**
+ * Calculate and update checksum
+ */
+ for (i = 0; i < (header->size512 * 512); i++)
+ csum += cur_header[i];
+
+ /**
+ * Invert summed value to create the checksum
+ * Writing new checksum value directly to the boot data
+ */
+ cur_header[7] = -csum;
+
+ } else if (pcir_header->code_type == CXGB4_HDR_CODE2) {
+ /**
+ * Modify Device ID to match current adatper
+ */
+ pcir_header->device_id = cpu_to_le16(device_id);
+ }
+
+ /**
+ * Move header pointer up to the next image in the ROM.
+ */
+ cur_header += header->size512 * 512;
+ } while (!(pcir_header->indicator & CXGB4_HDR_INDI));
+}
+
+/**
+ * t4_load_boot - download boot flash
+ * @adap: the adapter
+ * @boot_data: the boot image to write
+ * @boot_addr: offset in flash to write boot_data
+ * @size: image size
+ *
+ * Write the supplied boot image to the card's serial flash.
+ * The boot image has the following sections: a 28-byte header and the
+ * boot image.
+ */
+int t4_load_boot(struct adapter *adap, u8 *boot_data,
+ unsigned int boot_addr, unsigned int size)
+{
+ unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
+ unsigned int boot_sector = (boot_addr * 1024);
+ struct cxgb4_pci_exp_rom_header *header;
+ struct cxgb4_pcir_data *pcir_header;
+ int pcir_offset;
+ unsigned int i;
+ u16 device_id;
+ int ret, addr;
+
+ /**
+ * Make sure the boot image does not encroach on the firmware region
+ */
+ if ((boot_sector + size) >> 16 > FLASH_FW_START_SEC) {
+ dev_err(adap->pdev_dev, "boot image encroaching on firmware region\n");
+ return -EFBIG;
+ }
+
+ /* Get boot header */
+ header = (struct cxgb4_pci_exp_rom_header *)boot_data;
+ pcir_offset = le16_to_cpu(header->pcir_offset);
+ /* PCIR Data Structure */
+ pcir_header = (struct cxgb4_pcir_data *)&boot_data[pcir_offset];
+
+ /**
+ * Perform some primitive sanity testing to avoid accidentally
+ * writing garbage over the boot sectors. We ought to check for
+ * more but it's not worth it for now ...
+ */
+ if (size < BOOT_MIN_SIZE || size > BOOT_MAX_SIZE) {
+ dev_err(adap->pdev_dev, "boot image too small/large\n");
+ return -EFBIG;
+ }
+
+ if (le16_to_cpu(header->signature) != BOOT_SIGNATURE) {
+ dev_err(adap->pdev_dev, "Boot image missing signature\n");
+ return -EINVAL;
+ }
+
+ /* Check PCI header signature */
+ if (le32_to_cpu(pcir_header->signature) != PCIR_SIGNATURE) {
+ dev_err(adap->pdev_dev, "PCI header missing signature\n");
+ return -EINVAL;
+ }
+
+ /* Check Vendor ID matches Chelsio ID*/
+ if (le16_to_cpu(pcir_header->vendor_id) != PCI_VENDOR_ID_CHELSIO) {
+ dev_err(adap->pdev_dev, "Vendor ID missing signature\n");
+ return -EINVAL;
+ }
+
+ /**
+ * The boot sector is comprised of the Expansion-ROM boot, iSCSI boot,
+ * and Boot configuration data sections. These 3 boot sections span
+ * sectors 0 to 7 in flash and live right before the FW image location.
+ */
+ i = DIV_ROUND_UP(size ? size : FLASH_FW_START, sf_sec_size);
+ ret = t4_flash_erase_sectors(adap, boot_sector >> 16,
+ (boot_sector >> 16) + i - 1);
+
+ /**
+ * If size == 0 then we're simply erasing the FLASH sectors associated
+ * with the on-adapter option ROM file
+ */
+ if (ret || size == 0)
+ goto out;
+ /* Retrieve adapter's device ID */
+ pci_read_config_word(adap->pdev, PCI_DEVICE_ID, &device_id);
+ /* Want to deal with PF 0 so I strip off PF 4 indicator */
+ device_id = device_id & 0xf0ff;
+
+ /* Check PCIE Device ID */
+ if (le16_to_cpu(pcir_header->device_id) != device_id) {
+ /**
+ * Change the device ID in the Boot BIOS image to match
+ * the Device ID of the current adapter.
+ */
+ modify_device_id(device_id, boot_data);
+ }
+
+ /**
+ * Skip over the first SF_PAGE_SIZE worth of data and write it after
+ * we finish copying the rest of the boot image. This will ensure
+ * that the BIOS boot header will only be written if the boot image
+ * was written in full.
+ */
+ addr = boot_sector;
+ for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
+ addr += SF_PAGE_SIZE;
+ boot_data += SF_PAGE_SIZE;
+ ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, boot_data);
+ if (ret)
+ goto out;
+ }
+
+ ret = t4_write_flash(adap, boot_sector, SF_PAGE_SIZE,
+ (const u8 *)header);
+
+out:
+ if (ret)
+ dev_err(adap->pdev_dev, "boot image load failed, error %d\n",
+ ret);
+ return ret;
+}
+
+/**
+ * t4_flash_bootcfg_addr - return the address of the flash
+ * optionrom configuration
+ * @adapter: the adapter
+ *
+ * Return the address within the flash where the OptionROM Configuration
+ * is stored, or an error if the device FLASH is too small to contain
+ * a OptionROM Configuration.
+ */
+static int t4_flash_bootcfg_addr(struct adapter *adapter)
+{
+ /**
+ * If the device FLASH isn't large enough to hold a Firmware
+ * Configuration File, return an error.
+ */
+ if (adapter->params.sf_size <
+ FLASH_BOOTCFG_START + FLASH_BOOTCFG_MAX_SIZE)
+ return -ENOSPC;
+
+ return FLASH_BOOTCFG_START;
+}
+
+int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
+{
+ unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
+ struct cxgb4_bootcfg_data *header;
+ unsigned int flash_cfg_start_sec;
+ unsigned int addr, npad;
+ int ret, i, n, cfg_addr;
+
+ cfg_addr = t4_flash_bootcfg_addr(adap);
+ if (cfg_addr < 0)
+ return cfg_addr;
+
+ addr = cfg_addr;
+ flash_cfg_start_sec = addr / SF_SEC_SIZE;
+
+ if (size > FLASH_BOOTCFG_MAX_SIZE) {
+ dev_err(adap->pdev_dev, "bootcfg file too large, max is %u bytes\n",
+ FLASH_BOOTCFG_MAX_SIZE);
+ return -EFBIG;
+ }
+
+ header = (struct cxgb4_bootcfg_data *)cfg_data;
+ if (le16_to_cpu(header->signature) != BOOT_CFG_SIG) {
+ dev_err(adap->pdev_dev, "Wrong bootcfg signature\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ i = DIV_ROUND_UP(FLASH_BOOTCFG_MAX_SIZE,
+ sf_sec_size);
+ ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec,
+ flash_cfg_start_sec + i - 1);
+
+ /**
+ * If size == 0 then we're simply erasing the FLASH sectors associated
+ * with the on-adapter OptionROM Configuration File.
+ */
+ if (ret || size == 0)
+ goto out;
+
+ /* this will write to the flash up to SF_PAGE_SIZE at a time */
+ for (i = 0; i < size; i += SF_PAGE_SIZE) {
+ n = min_t(u32, size - i, SF_PAGE_SIZE);
+
+ ret = t4_write_flash(adap, addr, n, cfg_data);
+ if (ret)
+ goto out;
+
+ addr += SF_PAGE_SIZE;
+ cfg_data += SF_PAGE_SIZE;
+ }
+
+ npad = ((size + 4 - 1) & ~3) - size;
+ for (i = 0; i < npad; i++) {
+ u8 data = 0;
+
+ ret = t4_write_flash(adap, cfg_addr + size + i, 1, &data);
+ if (ret)
+ goto out;
+ }
+
+out:
+ if (ret)
+ dev_err(adap->pdev_dev, "boot config data %s failed %d\n",
+ (size == 0 ? "clear" : "download"), ret);
+ return ret;
+}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 4a9fcd6c226c..065c01c654ff 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -563,6 +563,12 @@
#define AIVEC_V(x) ((x) << AIVEC_S)
#define PCIE_PF_CLI_A 0x44
+
+#define PCIE_PF_EXPROM_OFST_A 0x4c
+#define OFFSET_S 10
+#define OFFSET_M 0x3fffU
+#define OFFSET_G(x) (((x) >> OFFSET_S) & OFFSET_M)
+
#define PCIE_INT_CAUSE_A 0x3004
#define UNXSPLCPLERR_S 29
@@ -3038,6 +3044,10 @@
#define HASHTIDSIZE_M 0x3fU
#define HASHTIDSIZE_G(x) (((x) >> HASHTIDSIZE_S) & HASHTIDSIZE_M)
+#define HASHTBLSIZE_S 3
+#define HASHTBLSIZE_M 0x1ffffU
+#define HASHTBLSIZE_G(x) (((x) >> HASHTBLSIZE_S) & HASHTBLSIZE_M)
+
#define LE_DB_HASH_TID_BASE_A 0x19c30
#define LE_DB_HASH_TBL_BASE_ADDR_A 0x19c30
#define LE_DB_INT_CAUSE_A 0x19c3c
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
index 3782e48dada2..f55105a4112f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
@@ -562,7 +562,7 @@ int t4vf_sge_alloc_eth_txq(struct adapter *, struct sge_eth_txq *,
unsigned int);
void t4vf_free_sge_resources(struct adapter *);
-int t4vf_eth_xmit(struct sk_buff *, struct net_device *);
+netdev_tx_t t4vf_eth_xmit(struct sk_buff *, struct net_device *);
int t4vf_ethrx_handler(struct sge_rspq *, const __be64 *,
const struct pkt_gl *);
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index a7641be9094f..dbe8ee7e0e21 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -2916,6 +2916,39 @@ static const struct net_device_ops cxgb4vf_netdev_ops = {
#endif
};
+/**
+ * cxgb4vf_get_port_mask - Get port mask for the VF based on mac
+ * address stored on the adapter
+ * @adapter: The adapter
+ *
+ * Find the the port mask for the VF based on the index of mac
+ * address stored in the adapter. If no mac address is stored on
+ * the adapter for the VF, use the port mask received from the
+ * firmware.
+ */
+static unsigned int cxgb4vf_get_port_mask(struct adapter *adapter)
+{
+ unsigned int naddr = 1, pidx = 0;
+ unsigned int pmask, rmask = 0;
+ u8 mac[ETH_ALEN];
+ int err;
+
+ pmask = adapter->params.vfres.pmask;
+ while (pmask) {
+ if (pmask & 1) {
+ err = t4vf_get_vf_mac_acl(adapter, pidx, &naddr, mac);
+ if (!err && !is_zero_ether_addr(mac))
+ rmask |= (1 << pidx);
+ }
+ pmask >>= 1;
+ pidx++;
+ }
+ if (!rmask)
+ rmask = adapter->params.vfres.pmask;
+
+ return rmask;
+}
+
/*
* "Probe" a device: initialize a device and construct all kernel and driver
* state needed to manage the device. This routine is called "init_one" in
@@ -2924,13 +2957,12 @@ static const struct net_device_ops cxgb4vf_netdev_ops = {
static int cxgb4vf_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- int pci_using_dac;
- int err, pidx;
- unsigned int pmask;
struct adapter *adapter;
- struct port_info *pi;
struct net_device *netdev;
- unsigned int pf;
+ struct port_info *pi;
+ unsigned int pmask;
+ int pci_using_dac;
+ int err, pidx;
/*
* Initialize generic PCI device state.
@@ -3073,8 +3105,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
/*
* Allocate our "adapter ports" and stitch everything together.
*/
- pmask = adapter->params.vfres.pmask;
- pf = t4vf_get_pf_from_vf(adapter);
+ pmask = cxgb4vf_get_port_mask(adapter);
for_each_port(adapter, pidx) {
int port_id, viid;
u8 mac[ETH_ALEN];
@@ -3157,7 +3188,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
goto err_free_dev;
}
- err = t4vf_get_vf_mac_acl(adapter, pf, &naddr, mac);
+ err = t4vf_get_vf_mac_acl(adapter, port_id, &naddr, mac);
if (err) {
dev_err(&pdev->dev,
"unable to determine MAC ACL address, "
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
index 8c3d6e11a4bf..95657da0aa4b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
@@ -1154,7 +1154,7 @@ static inline void txq_advance(struct sge_txq *tq, unsigned int n)
*
* Add a packet to an SGE Ethernet TX queue. Runs with softirqs disabled.
*/
-int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev)
{
u32 wr_mid;
u64 cntrl, *end;
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
index 57cfd10a99ec..03777145efec 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
@@ -415,7 +415,7 @@ int t4vf_eth_eq_free(struct adapter *, unsigned int);
int t4vf_update_port_info(struct port_info *pi);
int t4vf_handle_fw_rpl(struct adapter *, const __be64 *);
int t4vf_prep_adapter(struct adapter *);
-int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
+int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int port,
unsigned int *naddr, u8 *addr);
int t4vf_get_vf_vlan_acl(struct adapter *adapter);
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
index a31b87390b50..cd8f9a481d73 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
@@ -2187,14 +2187,14 @@ int t4vf_prep_adapter(struct adapter *adapter)
* t4vf_get_vf_mac_acl - Get the MAC address to be set to
* the VI of this VF.
* @adapter: The adapter
- * @pf: The pf associated with vf
+ * @port: The port associated with vf
* @naddr: the number of ACL MAC addresses returned in addr
* @addr: Placeholder for MAC addresses
*
* Find the MAC address to be set to the VF's VI. The requested MAC address
* is from the host OS via callback in the PF driver.
*/
-int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
+int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int port,
unsigned int *naddr, u8 *addr)
{
struct fw_acl_mac_cmd cmd;
@@ -2212,7 +2212,7 @@ int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
if (cmd.nmac < *naddr)
*naddr = cmd.nmac;
- switch (pf) {
+ switch (port) {
case 3:
memcpy(addr, cmd.macaddr3, sizeof(cmd.macaddr3));
break;
diff --git a/drivers/net/ethernet/cirrus/Kconfig b/drivers/net/ethernet/cirrus/Kconfig
index 7cf4526596f3..d8af9e64dd1e 100644
--- a/drivers/net/ethernet/cirrus/Kconfig
+++ b/drivers/net/ethernet/cirrus/Kconfig
@@ -24,7 +24,7 @@ config CS89x0
help
Support for CS89x0 chipset based Ethernet cards. If you have a
network (Ethernet) card of this type, say Y and read the file
- <file:Documentation/networking/device_drivers/cirrus/cs89x0.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/cirrus/cs89x0.rst>.
To compile this driver as a module, choose M here. The module
will be called cs89x0.
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index cd5fe4f6b54c..6bc7e7ba38c3 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -176,50 +176,18 @@ static void enic_unset_affinity_hint(struct enic *enic)
irq_set_affinity_hint(enic->msix_entry[i].vector, NULL);
}
-static void enic_udp_tunnel_add(struct net_device *netdev,
- struct udp_tunnel_info *ti)
+static int enic_udp_tunnel_set_port(struct net_device *netdev,
+ unsigned int table, unsigned int entry,
+ struct udp_tunnel_info *ti)
{
struct enic *enic = netdev_priv(netdev);
- __be16 port = ti->port;
int err;
spin_lock_bh(&enic->devcmd_lock);
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN) {
- netdev_info(netdev, "udp_tnl: only vxlan tunnel offload supported");
- goto error;
- }
-
- switch (ti->sa_family) {
- case AF_INET6:
- if (!(enic->vxlan.flags & ENIC_VXLAN_OUTER_IPV6)) {
- netdev_info(netdev, "vxlan: only IPv4 offload supported");
- goto error;
- }
- /* Fall through */
- case AF_INET:
- break;
- default:
- goto error;
- }
-
- if (enic->vxlan.vxlan_udp_port_number) {
- if (ntohs(port) == enic->vxlan.vxlan_udp_port_number)
- netdev_warn(netdev, "vxlan: udp port already offloaded");
- else
- netdev_info(netdev, "vxlan: offload supported for only one UDP port");
-
- goto error;
- }
- if ((vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ) != 1) &&
- !(enic->vxlan.flags & ENIC_VXLAN_MULTI_WQ)) {
- netdev_info(netdev, "vxlan: vxlan offload with multi wq not supported on this adapter");
- goto error;
- }
-
err = vnic_dev_overlay_offload_cfg(enic->vdev,
OVERLAY_CFG_VXLAN_PORT_UPDATE,
- ntohs(port));
+ ntohs(ti->port));
if (err)
goto error;
@@ -228,52 +196,50 @@ static void enic_udp_tunnel_add(struct net_device *netdev,
if (err)
goto error;
- enic->vxlan.vxlan_udp_port_number = ntohs(port);
-
- netdev_info(netdev, "vxlan fw-vers-%d: offload enabled for udp port: %d, sa_family: %d ",
- (int)enic->vxlan.patch_level, ntohs(port), ti->sa_family);
-
- goto unlock;
-
+ enic->vxlan.vxlan_udp_port_number = ntohs(ti->port);
error:
- netdev_info(netdev, "failed to offload udp port: %d, sa_family: %d, type: %d",
- ntohs(port), ti->sa_family, ti->type);
-unlock:
spin_unlock_bh(&enic->devcmd_lock);
+
+ return err;
}
-static void enic_udp_tunnel_del(struct net_device *netdev,
- struct udp_tunnel_info *ti)
+static int enic_udp_tunnel_unset_port(struct net_device *netdev,
+ unsigned int table, unsigned int entry,
+ struct udp_tunnel_info *ti)
{
struct enic *enic = netdev_priv(netdev);
int err;
spin_lock_bh(&enic->devcmd_lock);
- if ((ntohs(ti->port) != enic->vxlan.vxlan_udp_port_number) ||
- ti->type != UDP_TUNNEL_TYPE_VXLAN) {
- netdev_info(netdev, "udp_tnl: port:%d, sa_family: %d, type: %d not offloaded",
- ntohs(ti->port), ti->sa_family, ti->type);
- goto unlock;
- }
-
err = vnic_dev_overlay_offload_ctrl(enic->vdev, OVERLAY_FEATURE_VXLAN,
OVERLAY_OFFLOAD_DISABLE);
- if (err) {
- netdev_err(netdev, "vxlan: del offload udp port: %d failed",
- ntohs(ti->port));
+ if (err)
goto unlock;
- }
enic->vxlan.vxlan_udp_port_number = 0;
- netdev_info(netdev, "vxlan: del offload udp port %d, family %d\n",
- ntohs(ti->port), ti->sa_family);
-
unlock:
spin_unlock_bh(&enic->devcmd_lock);
+
+ return err;
}
+static const struct udp_tunnel_nic_info enic_udp_tunnels = {
+ .set_port = enic_udp_tunnel_set_port,
+ .unset_port = enic_udp_tunnel_unset_port,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+}, enic_udp_tunnels_v4 = {
+ .set_port = enic_udp_tunnel_set_port,
+ .unset_port = enic_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_IPV4_ONLY,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+
static netdev_features_t enic_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
@@ -2526,8 +2492,8 @@ static const struct net_device_ops enic_netdev_dynamic_ops = {
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = enic_rx_flow_steer,
#endif
- .ndo_udp_tunnel_add = enic_udp_tunnel_add,
- .ndo_udp_tunnel_del = enic_udp_tunnel_del,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = enic_features_check,
};
@@ -2552,8 +2518,8 @@ static const struct net_device_ops enic_netdev_ops = {
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = enic_rx_flow_steer,
#endif
- .ndo_udp_tunnel_add = enic_udp_tunnel_add,
- .ndo_udp_tunnel_del = enic_udp_tunnel_del,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = enic_features_check,
};
@@ -2963,6 +2929,13 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
patch_level = fls(patch_level);
patch_level = patch_level ? patch_level - 1 : 0;
enic->vxlan.patch_level = patch_level;
+
+ if (vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ) == 1 ||
+ enic->vxlan.flags & ENIC_VXLAN_MULTI_WQ) {
+ netdev->udp_tunnel_nic_info = &enic_udp_tunnels_v4;
+ if (enic->vxlan.flags & ENIC_VXLAN_OUTER_IPV6)
+ netdev->udp_tunnel_nic_info = &enic_udp_tunnels;
+ }
}
netdev->features |= netdev->hw_features;
diff --git a/drivers/net/ethernet/cortina/Kconfig b/drivers/net/ethernet/cortina/Kconfig
index ac8cb5744a87..aaf9e294b70b 100644
--- a/drivers/net/ethernet/cortina/Kconfig
+++ b/drivers/net/ethernet/cortina/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_CORTINA
help
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
+ <https://www.tldp.org/docs.html#howto>.
if NET_VENDOR_CORTINA
diff --git a/drivers/net/ethernet/dec/tulip/Kconfig b/drivers/net/ethernet/dec/tulip/Kconfig
index 8afc5942179a..79dc336ce709 100644
--- a/drivers/net/ethernet/dec/tulip/Kconfig
+++ b/drivers/net/ethernet/dec/tulip/Kconfig
@@ -114,7 +114,7 @@ config DE4X5
These include the DE425, DE434, DE435, DE450 and DE500 models. If
you have a network card of this type, say Y. More specific
information is contained in
- <file:Documentation/networking/device_drivers/dec/de4x5.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/dec/de4x5.rst>.
To compile this driver as a module, choose M here. The module will
be called de4x5.
@@ -138,7 +138,7 @@ config DM9102
This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from
Davicom (<http://www.davicom.com.tw/>). If you have such a network
(Ethernet) card, say Y. Some information is contained in the file
- <file:Documentation/networking/device_drivers/dec/dmfe.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/dec/dmfe.rst>.
To compile this driver as a module, choose M here. The module will
be called dmfe.
diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c
index 592454f444ce..cb116b530f5e 100644
--- a/drivers/net/ethernet/dec/tulip/de2104x.c
+++ b/drivers/net/ethernet/dec/tulip/de2104x.c
@@ -2105,11 +2105,10 @@ static void de_remove_one(struct pci_dev *pdev)
free_netdev(dev);
}
-#ifdef CONFIG_PM
-
-static int de_suspend (struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused de_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata (pdev);
+ struct pci_dev *pdev = to_pci_dev(dev_d);
+ struct net_device *dev = pci_get_drvdata(pdev);
struct de_private *de = netdev_priv(dev);
rtnl_lock();
@@ -2136,7 +2135,6 @@ static int de_suspend (struct pci_dev *pdev, pm_message_t state)
de_clean_rings(de);
de_adapter_sleep(de);
- pci_disable_device(pdev);
} else {
netif_device_detach(dev);
}
@@ -2144,21 +2142,17 @@ static int de_suspend (struct pci_dev *pdev, pm_message_t state)
return 0;
}
-static int de_resume (struct pci_dev *pdev)
+static int __maybe_unused de_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata (pdev);
+ struct pci_dev *pdev = to_pci_dev(dev_d);
+ struct net_device *dev = pci_get_drvdata(pdev);
struct de_private *de = netdev_priv(dev);
- int retval = 0;
rtnl_lock();
if (netif_device_present(dev))
goto out;
if (!netif_running(dev))
goto out_attach;
- if ((retval = pci_enable_device(pdev))) {
- netdev_err(dev, "pci_enable_device failed in resume\n");
- goto out;
- }
pci_set_master(pdev);
de_init_rings(de);
de_init_hw(de);
@@ -2169,17 +2163,14 @@ out:
return 0;
}
-#endif /* CONFIG_PM */
+static SIMPLE_DEV_PM_OPS(de_pm_ops, de_suspend, de_resume);
static struct pci_driver de_driver = {
.name = DRV_NAME,
.id_table = de_pci_tbl,
.probe = de_init_one,
.remove = de_remove_one,
-#ifdef CONFIG_PM
- .suspend = de_suspend,
- .resume = de_resume,
-#endif
+ .driver.pm = &de_pm_ops,
};
static int __init de_init (void)
diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c
index c1884fc9ad32..c3b4abff48b5 100644
--- a/drivers/net/ethernet/dec/tulip/dmfe.c
+++ b/drivers/net/ethernet/dec/tulip/dmfe.c
@@ -2081,14 +2081,11 @@ static const struct pci_device_id dmfe_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl);
-
-#ifdef CONFIG_PM
-static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state)
+static int __maybe_unused dmfe_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pci_dev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct dmfe_board_info *db = netdev_priv(dev);
void __iomem *ioaddr = db->ioaddr;
- u32 tmp;
/* Disable upper layer interface */
netif_device_detach(dev);
@@ -2105,63 +2102,35 @@ static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state)
dmfe_free_rxbuffer(db);
/* Enable WOL */
- pci_read_config_dword(pci_dev, 0x40, &tmp);
- tmp &= ~(DMFE_WOL_LINKCHANGE|DMFE_WOL_MAGICPACKET);
-
- if (db->wol_mode & WAKE_PHY)
- tmp |= DMFE_WOL_LINKCHANGE;
- if (db->wol_mode & WAKE_MAGIC)
- tmp |= DMFE_WOL_MAGICPACKET;
-
- pci_write_config_dword(pci_dev, 0x40, tmp);
-
- pci_enable_wake(pci_dev, PCI_D3hot, 1);
- pci_enable_wake(pci_dev, PCI_D3cold, 1);
-
- /* Power down device*/
- pci_save_state(pci_dev);
- pci_set_power_state(pci_dev, pci_choose_state (pci_dev, state));
+ device_wakeup_enable(dev_d);
return 0;
}
-static int dmfe_resume(struct pci_dev *pci_dev)
+static int __maybe_unused dmfe_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pci_dev);
- u32 tmp;
-
- pci_set_power_state(pci_dev, PCI_D0);
- pci_restore_state(pci_dev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
/* Re-initialize DM910X board */
dmfe_init_dm910x(dev);
/* Disable WOL */
- pci_read_config_dword(pci_dev, 0x40, &tmp);
-
- tmp &= ~(DMFE_WOL_LINKCHANGE | DMFE_WOL_MAGICPACKET);
- pci_write_config_dword(pci_dev, 0x40, tmp);
-
- pci_enable_wake(pci_dev, PCI_D3hot, 0);
- pci_enable_wake(pci_dev, PCI_D3cold, 0);
+ device_wakeup_disable(dev_d);
/* Restart upper layer interface */
netif_device_attach(dev);
return 0;
}
-#else
-#define dmfe_suspend NULL
-#define dmfe_resume NULL
-#endif
+
+static SIMPLE_DEV_PM_OPS(dmfe_pm_ops, dmfe_suspend, dmfe_resume);
static struct pci_driver dmfe_driver = {
.name = "dmfe",
.id_table = dmfe_pci_tbl,
.probe = dmfe_init_one,
.remove = dmfe_remove_one,
- .suspend = dmfe_suspend,
- .resume = dmfe_resume
+ .driver.pm = &dmfe_pm_ops,
};
MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw");
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index 15efc294f513..9db23527275a 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -1803,13 +1803,9 @@ static void tulip_set_wolopts (struct pci_dev *pdev, u32 wolopts)
}
}
-#ifdef CONFIG_PM
-
-
-static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused tulip_suspend(struct device *dev_d)
{
- pci_power_t pstate;
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct tulip_private *tp = netdev_priv(dev);
if (!dev)
@@ -1825,45 +1821,27 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
free_irq(tp->pdev->irq, dev);
save_state:
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pstate = pci_choose_state(pdev, state);
- if (state.event == PM_EVENT_SUSPEND && pstate != PCI_D0) {
- int rc;
-
- tulip_set_wolopts(pdev, tp->wolinfo.wolopts);
- rc = pci_enable_wake(pdev, pstate, tp->wolinfo.wolopts);
- if (rc)
- pr_err("pci_enable_wake failed (%d)\n", rc);
- }
- pci_set_power_state(pdev, pstate);
+ tulip_set_wolopts(to_pci_dev(dev_d), tp->wolinfo.wolopts);
+ device_set_wakeup_enable(dev_d, !!tp->wolinfo.wolopts);
return 0;
}
-
-static int tulip_resume(struct pci_dev *pdev)
+static int __maybe_unused tulip_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct pci_dev *pdev = to_pci_dev(dev_d);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct tulip_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->base_addr;
- int retval;
unsigned int tmp;
+ int retval = 0;
if (!dev)
return -EINVAL;
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
if (!netif_running(dev))
return 0;
- if ((retval = pci_enable_device(pdev))) {
- pr_err("pci_enable_device failed in resume\n");
- return retval;
- }
-
retval = request_irq(pdev->irq, tulip_interrupt, IRQF_SHARED,
dev->name, dev);
if (retval) {
@@ -1872,8 +1850,7 @@ static int tulip_resume(struct pci_dev *pdev)
}
if (tp->flags & COMET_PM) {
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ device_set_wakeup_enable(dev_d, 0);
/* Clear the PMES flag */
tmp = ioread32(ioaddr + CSR20);
@@ -1891,9 +1868,6 @@ static int tulip_resume(struct pci_dev *pdev)
return 0;
}
-#endif /* CONFIG_PM */
-
-
static void tulip_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
@@ -1937,15 +1911,14 @@ static void poll_tulip (struct net_device *dev)
}
#endif
+static SIMPLE_DEV_PM_OPS(tulip_pm_ops, tulip_suspend, tulip_resume);
+
static struct pci_driver tulip_driver = {
.name = DRV_NAME,
.id_table = tulip_pci_tbl,
.probe = tulip_init_one,
.remove = tulip_remove_one,
-#ifdef CONFIG_PM
- .suspend = tulip_suspend,
- .resume = tulip_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &tulip_pm_ops,
};
diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c
index f726436b1985..f942399f0f32 100644
--- a/drivers/net/ethernet/dec/tulip/uli526x.c
+++ b/drivers/net/ethernet/dec/tulip/uli526x.c
@@ -1163,65 +1163,41 @@ static void uli526x_dynamic_reset(struct net_device *dev)
netif_wake_queue(dev);
}
-
-#ifdef CONFIG_PM
-
/*
* Suspend the interface.
*/
-static int uli526x_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused uli526x_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
- pci_power_t power_state;
- int err;
+ struct net_device *dev = dev_get_drvdata(dev_d);
ULI526X_DBUG(0, "uli526x_suspend", 0);
- pci_save_state(pdev);
-
if (!netif_running(dev))
return 0;
netif_device_detach(dev);
uli526x_reset_prepare(dev);
- power_state = pci_choose_state(pdev, state);
- pci_enable_wake(pdev, power_state, 0);
- err = pci_set_power_state(pdev, power_state);
- if (err) {
- netif_device_attach(dev);
- /* Re-initialize ULI526X board */
- uli526x_init(dev);
- /* Restart upper layer interface */
- netif_wake_queue(dev);
- }
+ device_set_wakeup_enable(dev_d, 0);
- return err;
+ return 0;
}
/*
* Resume the interface.
*/
-static int uli526x_resume(struct pci_dev *pdev)
+static int __maybe_unused uli526x_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
- int err;
+ struct net_device *dev = dev_get_drvdata(dev_d);
ULI526X_DBUG(0, "uli526x_resume", 0);
- pci_restore_state(pdev);
if (!netif_running(dev))
return 0;
- err = pci_set_power_state(pdev, PCI_D0);
- if (err) {
- netdev_warn(dev, "Could not put device into D0\n");
- return err;
- }
-
netif_device_attach(dev);
/* Re-initialize ULI526X board */
uli526x_init(dev);
@@ -1231,14 +1207,6 @@ static int uli526x_resume(struct pci_dev *pdev)
return 0;
}
-#else /* !CONFIG_PM */
-
-#define uli526x_suspend NULL
-#define uli526x_resume NULL
-
-#endif /* !CONFIG_PM */
-
-
/*
* free all allocated rx buffer
*/
@@ -1761,14 +1729,14 @@ static const struct pci_device_id uli526x_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, uli526x_pci_tbl);
+static SIMPLE_DEV_PM_OPS(uli526x_pm_ops, uli526x_suspend, uli526x_resume);
static struct pci_driver uli526x_driver = {
.name = "uli526x",
.id_table = uli526x_pci_tbl,
.probe = uli526x_init_one,
.remove = uli526x_remove_one,
- .suspend = uli526x_suspend,
- .resume = uli526x_resume,
+ .driver.pm = &uli526x_pm_ops,
};
MODULE_AUTHOR("Peer Chen, peer.chen@uli.com.tw");
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c
index 4d5e4fa53023..5dcc66f60144 100644
--- a/drivers/net/ethernet/dec/tulip/winbond-840.c
+++ b/drivers/net/ethernet/dec/tulip/winbond-840.c
@@ -1530,8 +1530,6 @@ static void w840_remove1(struct pci_dev *pdev)
}
}
-#ifdef CONFIG_PM
-
/*
* suspend/resume synchronization:
* - open, close, do_ioctl:
@@ -1555,9 +1553,9 @@ static void w840_remove1(struct pci_dev *pdev)
* Detach must occur under spin_unlock_irq(), interrupts from a detached
* device would cause an irq storm.
*/
-static int w840_suspend (struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused w840_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata (pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base_addr;
@@ -1590,21 +1588,15 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state)
return 0;
}
-static int w840_resume (struct pci_dev *pdev)
+static int __maybe_unused w840_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata (pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev);
- int retval = 0;
rtnl_lock();
if (netif_device_present(dev))
goto out; /* device not suspended */
if (netif_running(dev)) {
- if ((retval = pci_enable_device(pdev))) {
- dev_err(&dev->dev,
- "pci_enable_device failed in resume\n");
- goto out;
- }
spin_lock_irq(&np->lock);
iowrite32(1, np->base_addr+PCIBusCfg);
ioread32(np->base_addr+PCIBusCfg);
@@ -1622,19 +1614,17 @@ static int w840_resume (struct pci_dev *pdev)
}
out:
rtnl_unlock();
- return retval;
+ return 0;
}
-#endif
+
+static SIMPLE_DEV_PM_OPS(w840_pm_ops, w840_suspend, w840_resume);
static struct pci_driver w840_driver = {
.name = DRV_NAME,
.id_table = w840_pci_tbl,
.probe = w840_probe1,
.remove = w840_remove1,
-#ifdef CONFIG_PM
- .suspend = w840_suspend,
- .resume = w840_resume,
-#endif
+ .driver.pm = &w840_pm_ops,
};
static int __init w840_init(void)
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
index 5143722c4419..be6d8a9ada27 100644
--- a/drivers/net/ethernet/dlink/dl2k.c
+++ b/drivers/net/ethernet/dlink/dl2k.c
@@ -1863,13 +1863,5 @@ static struct pci_driver rio_driver = {
};
module_pci_driver(rio_driver);
-/*
-
-Compile command:
-
-gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2k.c
-
-Read Documentation/networking/device_drivers/dlink/dl2k.rst for details.
-
-*/
+/* Read Documentation/networking/device_drivers/ethernet/dlink/dl2k.rst. */
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
index dc566fcc3ba9..b3f8597e77aa 100644
--- a/drivers/net/ethernet/dlink/sundance.c
+++ b/drivers/net/ethernet/dlink/sundance.c
@@ -18,7 +18,7 @@
http://www.scyld.com/network/sundance.html
[link no longer provides useful info -jgarzik]
Archives of the mailing list are still available at
- http://www.beowulf.org/pipermail/netdrivers/
+ https://www.beowulf.org/pipermail/netdrivers/
*/
@@ -1928,11 +1928,9 @@ static void sundance_remove1(struct pci_dev *pdev)
}
}
-#ifdef CONFIG_PM
-
-static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
+static int __maybe_unused sundance_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pci_dev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base;
@@ -1942,30 +1940,24 @@ static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
netdev_close(dev);
netif_device_detach(dev);
- pci_save_state(pci_dev);
if (np->wol_enabled) {
iowrite8(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
iowrite16(RxEnable, ioaddr + MACCtrl1);
}
- pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state),
- np->wol_enabled);
- pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+
+ device_set_wakeup_enable(dev_d, np->wol_enabled);
return 0;
}
-static int sundance_resume(struct pci_dev *pci_dev)
+static int __maybe_unused sundance_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pci_dev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
int err = 0;
if (!netif_running(dev))
return 0;
- pci_set_power_state(pci_dev, PCI_D0);
- pci_restore_state(pci_dev);
- pci_enable_wake(pci_dev, PCI_D0, 0);
-
err = netdev_open(dev);
if (err) {
printk(KERN_ERR "%s: Can't resume interface!\n",
@@ -1979,17 +1971,14 @@ out:
return err;
}
-#endif /* CONFIG_PM */
+static SIMPLE_DEV_PM_OPS(sundance_pm_ops, sundance_suspend, sundance_resume);
static struct pci_driver sundance_driver = {
.name = DRV_NAME,
.id_table = sundance_pci_tbl,
.probe = sundance_probe1,
.remove = sundance_remove1,
-#ifdef CONFIG_PM
- .suspend = sundance_suspend,
- .resume = sundance_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &sundance_pm_ops,
};
static int __init sundance_init(void)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 6e9022083004..8689d4a51fe5 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -654,8 +654,6 @@ struct be_adapter {
u8 hba_port_num;
u16 pvid;
__be16 vxlan_port; /* offloaded vxlan port num */
- int vxlan_port_count; /* active vxlan port count */
- struct list_head vxlan_port_list; /* vxlan port list */
struct phy_info phy;
u8 wol_cap;
bool wol_en;
@@ -679,9 +677,6 @@ struct be_adapter {
struct be_cmd_work {
struct work_struct work;
struct be_adapter *adapter;
- union {
- __be16 vxlan_port;
- } info;
};
#define be_physfn(adapter) (!adapter->virtfn)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a7ac23a6862b..676e437d78f6 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3829,8 +3829,8 @@ static int be_open(struct net_device *netdev)
be_link_status_update(adapter, link_status);
netif_tx_start_all_queues(netdev);
- if (skyhawk_chip(adapter))
- udp_tunnel_get_rx_info(netdev);
+
+ udp_tunnel_nic_reset_ntf(netdev);
return 0;
err:
@@ -3967,18 +3967,23 @@ static void be_cancel_err_detection(struct be_adapter *adapter)
}
}
-static int be_enable_vxlan_offloads(struct be_adapter *adapter)
+/* VxLAN offload Notes:
+ *
+ * The stack defines tunnel offload flags (hw_enc_features) for IP and doesn't
+ * distinguish various types of transports (VxLAN, GRE, NVGRE ..). So, offload
+ * is expected to work across all types of IP tunnels once exported. Skyhawk
+ * supports offloads for either VxLAN or NVGRE, exclusively. So we export VxLAN
+ * offloads in hw_enc_features only when a VxLAN port is added. If other (non
+ * VxLAN) tunnels are configured while VxLAN offloads are enabled, offloads for
+ * those other tunnels are unexported on the fly through ndo_features_check().
+ */
+static int be_vxlan_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti)
{
- struct net_device *netdev = adapter->netdev;
+ struct be_adapter *adapter = netdev_priv(netdev);
struct device *dev = &adapter->pdev->dev;
- struct be_vxlan_port *vxlan_port;
- __be16 port;
int status;
- vxlan_port = list_first_entry(&adapter->vxlan_port_list,
- struct be_vxlan_port, list);
- port = vxlan_port->port;
-
status = be_cmd_manage_iface(adapter, adapter->if_handle,
OP_CONVERT_NORMAL_TO_TUNNEL);
if (status) {
@@ -3987,25 +3992,26 @@ static int be_enable_vxlan_offloads(struct be_adapter *adapter)
}
adapter->flags |= BE_FLAGS_VXLAN_OFFLOADS;
- status = be_cmd_set_vxlan_port(adapter, port);
+ status = be_cmd_set_vxlan_port(adapter, ti->port);
if (status) {
dev_warn(dev, "Failed to add VxLAN port\n");
return status;
}
- adapter->vxlan_port = port;
+ adapter->vxlan_port = ti->port;
netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_TUNNEL;
dev_info(dev, "Enabled VxLAN offloads for UDP port %d\n",
- be16_to_cpu(port));
+ be16_to_cpu(ti->port));
return 0;
}
-static void be_disable_vxlan_offloads(struct be_adapter *adapter)
+static int be_vxlan_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti)
{
- struct net_device *netdev = adapter->netdev;
+ struct be_adapter *adapter = netdev_priv(netdev);
if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS)
be_cmd_manage_iface(adapter, adapter->if_handle,
@@ -4018,8 +4024,19 @@ static void be_disable_vxlan_offloads(struct be_adapter *adapter)
adapter->vxlan_port = 0;
netdev->hw_enc_features = 0;
+ return 0;
}
+static const struct udp_tunnel_nic_info be_udp_tunnels = {
+ .set_port = be_vxlan_set_port,
+ .unset_port = be_vxlan_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
+ UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+
static void be_calculate_vf_res(struct be_adapter *adapter, u16 num_vfs,
struct be_resources *vft_res)
{
@@ -4135,7 +4152,7 @@ static int be_clear(struct be_adapter *adapter)
&vft_res);
}
- be_disable_vxlan_offloads(adapter);
+ be_vxlan_unset_port(adapter->netdev, 0, 0, NULL);
be_if_destroy(adapter);
@@ -5053,147 +5070,6 @@ static struct be_cmd_work *be_alloc_work(struct be_adapter *adapter,
return work;
}
-/* VxLAN offload Notes:
- *
- * The stack defines tunnel offload flags (hw_enc_features) for IP and doesn't
- * distinguish various types of transports (VxLAN, GRE, NVGRE ..). So, offload
- * is expected to work across all types of IP tunnels once exported. Skyhawk
- * supports offloads for either VxLAN or NVGRE, exclusively. So we export VxLAN
- * offloads in hw_enc_features only when a VxLAN port is added. If other (non
- * VxLAN) tunnels are configured while VxLAN offloads are enabled, offloads for
- * those other tunnels are unexported on the fly through ndo_features_check().
- *
- * Skyhawk supports VxLAN offloads only for one UDP dport. So, if the stack
- * adds more than one port, disable offloads and re-enable them again when
- * there's only one port left. We maintain a list of ports for this purpose.
- */
-static void be_work_add_vxlan_port(struct work_struct *work)
-{
- struct be_cmd_work *cmd_work =
- container_of(work, struct be_cmd_work, work);
- struct be_adapter *adapter = cmd_work->adapter;
- struct device *dev = &adapter->pdev->dev;
- __be16 port = cmd_work->info.vxlan_port;
- struct be_vxlan_port *vxlan_port;
- int status;
-
- /* Bump up the alias count if it is an existing port */
- list_for_each_entry(vxlan_port, &adapter->vxlan_port_list, list) {
- if (vxlan_port->port == port) {
- vxlan_port->port_aliases++;
- goto done;
- }
- }
-
- /* Add a new port to our list. We don't need a lock here since port
- * add/delete are done only in the context of a single-threaded work
- * queue (be_wq).
- */
- vxlan_port = kzalloc(sizeof(*vxlan_port), GFP_KERNEL);
- if (!vxlan_port)
- goto done;
-
- vxlan_port->port = port;
- INIT_LIST_HEAD(&vxlan_port->list);
- list_add_tail(&vxlan_port->list, &adapter->vxlan_port_list);
- adapter->vxlan_port_count++;
-
- if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) {
- dev_info(dev,
- "Only one UDP port supported for VxLAN offloads\n");
- dev_info(dev, "Disabling VxLAN offloads\n");
- goto err;
- }
-
- if (adapter->vxlan_port_count > 1)
- goto done;
-
- status = be_enable_vxlan_offloads(adapter);
- if (!status)
- goto done;
-
-err:
- be_disable_vxlan_offloads(adapter);
-done:
- kfree(cmd_work);
- return;
-}
-
-static void be_work_del_vxlan_port(struct work_struct *work)
-{
- struct be_cmd_work *cmd_work =
- container_of(work, struct be_cmd_work, work);
- struct be_adapter *adapter = cmd_work->adapter;
- __be16 port = cmd_work->info.vxlan_port;
- struct be_vxlan_port *vxlan_port;
-
- /* Nothing to be done if a port alias is being deleted */
- list_for_each_entry(vxlan_port, &adapter->vxlan_port_list, list) {
- if (vxlan_port->port == port) {
- if (vxlan_port->port_aliases) {
- vxlan_port->port_aliases--;
- goto done;
- }
- break;
- }
- }
-
- /* No port aliases left; delete the port from the list */
- list_del(&vxlan_port->list);
- adapter->vxlan_port_count--;
-
- /* Disable VxLAN offload if this is the offloaded port */
- if (adapter->vxlan_port == vxlan_port->port) {
- WARN_ON(adapter->vxlan_port_count);
- be_disable_vxlan_offloads(adapter);
- dev_info(&adapter->pdev->dev,
- "Disabled VxLAN offloads for UDP port %d\n",
- be16_to_cpu(port));
- goto out;
- }
-
- /* If only 1 port is left, re-enable VxLAN offload */
- if (adapter->vxlan_port_count == 1)
- be_enable_vxlan_offloads(adapter);
-
-out:
- kfree(vxlan_port);
-done:
- kfree(cmd_work);
-}
-
-static void be_cfg_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti,
- void (*func)(struct work_struct *))
-{
- struct be_adapter *adapter = netdev_priv(netdev);
- struct be_cmd_work *cmd_work;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- if (lancer_chip(adapter) || BEx_chip(adapter) || be_is_mc(adapter))
- return;
-
- cmd_work = be_alloc_work(adapter, func);
- if (cmd_work) {
- cmd_work->info.vxlan_port = ti->port;
- queue_work(be_wq, &cmd_work->work);
- }
-}
-
-static void be_del_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- be_cfg_vxlan_port(netdev, ti, be_work_del_vxlan_port);
-}
-
-static void be_add_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- be_cfg_vxlan_port(netdev, ti, be_work_add_vxlan_port);
-}
-
static netdev_features_t be_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
@@ -5309,8 +5185,8 @@ static const struct net_device_ops be_netdev_ops = {
#endif
.ndo_bridge_setlink = be_ndo_bridge_setlink,
.ndo_bridge_getlink = be_ndo_bridge_getlink,
- .ndo_udp_tunnel_add = be_add_vxlan_port,
- .ndo_udp_tunnel_del = be_del_vxlan_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = be_features_check,
.ndo_get_phys_port_id = be_get_phys_port_id,
};
@@ -5342,6 +5218,9 @@ static void be_netdev_init(struct net_device *netdev)
netdev->ethtool_ops = &be_ethtool_ops;
+ if (!lancer_chip(adapter) && !BEx_chip(adapter) && !be_is_mc(adapter))
+ netdev->udp_tunnel_nic_info = &be_udp_tunnels;
+
/* MTU range: 256 - 9000 */
netdev->min_mtu = BE_MIN_MTU;
netdev->max_mtu = BE_MAX_MTU;
@@ -5819,7 +5698,6 @@ static int be_drv_init(struct be_adapter *adapter)
/* Must be a power of 2 or else MODULO will BUG_ON */
adapter->be_get_temp_freq = 64;
- INIT_LIST_HEAD(&adapter->vxlan_port_list);
return 0;
free_rx_filter:
@@ -6037,32 +5915,23 @@ do_none:
return status;
}
-static int be_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused be_suspend(struct device *dev_d)
{
- struct be_adapter *adapter = pci_get_drvdata(pdev);
+ struct be_adapter *adapter = dev_get_drvdata(dev_d);
be_intr_set(adapter, false);
be_cancel_err_detection(adapter);
be_cleanup(adapter);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
-static int be_pci_resume(struct pci_dev *pdev)
+static int __maybe_unused be_pci_resume(struct device *dev_d)
{
- struct be_adapter *adapter = pci_get_drvdata(pdev);
+ struct be_adapter *adapter = dev_get_drvdata(dev_d);
int status = 0;
- status = pci_enable_device(pdev);
- if (status)
- return status;
-
- pci_restore_state(pdev);
-
status = be_resume(adapter);
if (status)
return status;
@@ -6234,13 +6103,14 @@ static const struct pci_error_handlers be_eeh_handlers = {
.resume = be_eeh_resume,
};
+static SIMPLE_DEV_PM_OPS(be_pci_pm_ops, be_suspend, be_pci_resume);
+
static struct pci_driver be_driver = {
.name = DRV_NAME,
.id_table = be_dev_ids,
.probe = be_probe,
.remove = be_remove,
- .suspend = be_suspend,
- .resume = be_pci_resume,
+ .driver.pm = &be_pci_pm_ops,
.shutdown = be_shutdown,
.sriov_configure = be_pci_sriov_configure,
.err_handler = &be_eeh_handlers
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c
index 73e896a7d8fd..c696651dd735 100644
--- a/drivers/net/ethernet/fealnx.c
+++ b/drivers/net/ethernet/fealnx.c
@@ -543,7 +543,8 @@ static int fealnx_init_one(struct pci_dev *pdev,
np->mii.phy_id_mask = 0x1f;
np->mii.reg_num_mask = 0x1f;
- ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE, &ring_dma,
+ GFP_KERNEL);
if (!ring_space) {
err = -ENOMEM;
goto err_out_free_dev;
@@ -551,7 +552,8 @@ static int fealnx_init_one(struct pci_dev *pdev,
np->rx_ring = ring_space;
np->rx_ring_dma = ring_dma;
- ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE, &ring_dma,
+ GFP_KERNEL);
if (!ring_space) {
err = -ENOMEM;
goto err_out_free_rx;
@@ -656,9 +658,11 @@ static int fealnx_init_one(struct pci_dev *pdev,
return 0;
err_out_free_tx:
- pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
+ dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring,
+ np->tx_ring_dma);
err_out_free_rx:
- pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
+ dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring,
+ np->rx_ring_dma);
err_out_free_dev:
free_netdev(dev);
err_out_unmap:
@@ -676,10 +680,10 @@ static void fealnx_remove_one(struct pci_dev *pdev)
if (dev) {
struct netdev_private *np = netdev_priv(dev);
- pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring,
- np->tx_ring_dma);
- pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring,
- np->rx_ring_dma);
+ dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring,
+ np->tx_ring_dma);
+ dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring,
+ np->rx_ring_dma);
unregister_netdev(dev);
pci_iounmap(pdev, np->mem);
free_netdev(dev);
@@ -1056,8 +1060,10 @@ static void allocate_rx_buffers(struct net_device *dev)
np->lack_rxbuf = np->lack_rxbuf->next_desc_logical;
np->lack_rxbuf->skbuff = skb;
- np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data,
- np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ np->lack_rxbuf->buffer = dma_map_single(&np->pci_dev->dev,
+ skb->data,
+ np->rx_buf_sz,
+ DMA_FROM_DEVICE);
np->lack_rxbuf->status = RXOWN;
++np->really_rx_count;
}
@@ -1251,8 +1257,10 @@ static void init_ring(struct net_device *dev)
++np->really_rx_count;
np->rx_ring[i].skbuff = skb;
- np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data,
- np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ np->rx_ring[i].buffer = dma_map_single(&np->pci_dev->dev,
+ skb->data,
+ np->rx_buf_sz,
+ DMA_FROM_DEVICE);
np->rx_ring[i].status = RXOWN;
np->rx_ring[i].control |= RXIC;
}
@@ -1290,8 +1298,8 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
#define one_buffer
#define BPT 1022
#if defined(one_buffer)
- np->cur_tx_copy->buffer = pci_map_single(np->pci_dev, skb->data,
- skb->len, PCI_DMA_TODEVICE);
+ np->cur_tx_copy->buffer = dma_map_single(&np->pci_dev->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable;
np->cur_tx_copy->control |= (skb->len << PKTSShift); /* pkt size */
np->cur_tx_copy->control |= (skb->len << TBSShift); /* buffer size */
@@ -1306,8 +1314,9 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
struct fealnx_desc *next;
/* for the first descriptor */
- np->cur_tx_copy->buffer = pci_map_single(np->pci_dev, skb->data,
- BPT, PCI_DMA_TODEVICE);
+ np->cur_tx_copy->buffer = dma_map_single(&np->pci_dev->dev,
+ skb->data, BPT,
+ DMA_TO_DEVICE);
np->cur_tx_copy->control = TXIC | TXFD | CRCEnable | PADEnable;
np->cur_tx_copy->control |= (skb->len << PKTSShift); /* pkt size */
np->cur_tx_copy->control |= (BPT << TBSShift); /* buffer size */
@@ -1321,8 +1330,9 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
// 89/12/29 add,
if (np->pci_dev->device == 0x891)
np->cur_tx_copy->control |= ETIControl | RetryTxLC;
- next->buffer = pci_map_single(ep->pci_dev, skb->data + BPT,
- skb->len - BPT, PCI_DMA_TODEVICE);
+ next->buffer = dma_map_single(&ep->pci_dev->dev,
+ skb->data + BPT, skb->len - BPT,
+ DMA_TO_DEVICE);
next->status = TXOWN;
np->cur_tx_copy->status = TXOWN;
@@ -1330,8 +1340,9 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
np->cur_tx_copy = next->next_desc_logical;
np->free_tx_count -= 2;
} else {
- np->cur_tx_copy->buffer = pci_map_single(np->pci_dev, skb->data,
- skb->len, PCI_DMA_TODEVICE);
+ np->cur_tx_copy->buffer = dma_map_single(&np->pci_dev->dev,
+ skb->data, skb->len,
+ DMA_TO_DEVICE);
np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable;
np->cur_tx_copy->control |= (skb->len << PKTSShift); /* pkt size */
np->cur_tx_copy->control |= (skb->len << TBSShift); /* buffer size */
@@ -1371,8 +1382,8 @@ static void reset_tx_descriptors(struct net_device *dev)
for (i = 0; i < TX_RING_SIZE; i++) {
cur = &np->tx_ring[i];
if (cur->skbuff) {
- pci_unmap_single(np->pci_dev, cur->buffer,
- cur->skbuff->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&np->pci_dev->dev, cur->buffer,
+ cur->skbuff->len, DMA_TO_DEVICE);
dev_kfree_skb_any(cur->skbuff);
cur->skbuff = NULL;
}
@@ -1515,8 +1526,10 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
}
/* Free the original skb. */
- pci_unmap_single(np->pci_dev, np->cur_tx->buffer,
- np->cur_tx->skbuff->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&np->pci_dev->dev,
+ np->cur_tx->buffer,
+ np->cur_tx->skbuff->len,
+ DMA_TO_DEVICE);
dev_consume_skb_irq(np->cur_tx->skbuff);
np->cur_tx->skbuff = NULL;
--np->really_tx_count;
@@ -1682,10 +1695,10 @@ static int netdev_rx(struct net_device *dev)
if (pkt_len < rx_copybreak &&
(skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
skb_reserve(skb, 2); /* 16 byte align the IP header */
- pci_dma_sync_single_for_cpu(np->pci_dev,
- np->cur_rx->buffer,
- np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&np->pci_dev->dev,
+ np->cur_rx->buffer,
+ np->rx_buf_sz,
+ DMA_FROM_DEVICE);
/* Call copy + cksum if available. */
#if ! defined(__alpha__)
@@ -1696,15 +1709,15 @@ static int netdev_rx(struct net_device *dev)
skb_put_data(skb, np->cur_rx->skbuff->data,
pkt_len);
#endif
- pci_dma_sync_single_for_device(np->pci_dev,
- np->cur_rx->buffer,
- np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&np->pci_dev->dev,
+ np->cur_rx->buffer,
+ np->rx_buf_sz,
+ DMA_FROM_DEVICE);
} else {
- pci_unmap_single(np->pci_dev,
+ dma_unmap_single(&np->pci_dev->dev,
np->cur_rx->buffer,
np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
skb_put(skb = np->cur_rx->skbuff, pkt_len);
np->cur_rx->skbuff = NULL;
--np->really_rx_count;
@@ -1896,8 +1909,9 @@ static int netdev_close(struct net_device *dev)
np->rx_ring[i].status = 0;
if (skb) {
- pci_unmap_single(np->pci_dev, np->rx_ring[i].buffer,
- np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&np->pci_dev->dev,
+ np->rx_ring[i].buffer, np->rx_buf_sz,
+ DMA_FROM_DEVICE);
dev_kfree_skb(skb);
np->rx_ring[i].skbuff = NULL;
}
@@ -1907,8 +1921,9 @@ static int netdev_close(struct net_device *dev)
struct sk_buff *skb = np->tx_ring[i].skbuff;
if (skb) {
- pci_unmap_single(np->pci_dev, np->tx_ring[i].buffer,
- skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&np->pci_dev->dev,
+ np->tx_ring[i].buffer, skb->len,
+ DMA_TO_DEVICE);
dev_kfree_skb(skb);
np->tx_ring[i].skbuff = NULL;
}
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c
index c453a23045c1..56d9927fbfda 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c
@@ -21,7 +21,7 @@ static int dpaa2_dbg_cpu_show(struct seq_file *file, void *offset)
seq_printf(file, "Per-CPU stats for %s\n", priv->net_dev->name);
seq_printf(file, "%s%16s%16s%16s%16s%16s%16s%16s%16s%16s\n",
"CPU", "Rx", "Rx Err", "Rx SG", "Tx", "Tx Err", "Tx conf",
- "Tx SG", "Tx realloc", "Enq busy");
+ "Tx SG", "Tx converted to SG", "Enq busy");
for_each_online_cpu(i) {
stats = per_cpu_ptr(priv->percpu_stats, i);
@@ -35,7 +35,7 @@ static int dpaa2_dbg_cpu_show(struct seq_file *file, void *offset)
stats->tx_errors,
extras->tx_conf_frames,
extras->tx_sg_frames,
- extras->tx_reallocs,
+ extras->tx_converted_sg_frames,
extras->tx_portal_busy);
}
@@ -90,6 +90,10 @@ static int dpaa2_dbg_fqs_show(struct seq_file *file, void *offset)
if (err)
fcnt = 0;
+ /* Skip FQs with no traffic */
+ if (!fq->stats.frames && !fcnt)
+ continue;
+
seq_printf(file, "%5d%16d%16d%16s%16llu%16u\n",
fq->fqid,
fq->target_cpu,
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-trace.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-trace.h
index 9801528db2a5..5fb5f14e01ec 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-trace.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-trace.h
@@ -10,7 +10,6 @@
#include <linux/skbuff.h>
#include <linux/netdevice.h>
-#include "dpaa2-eth.h"
#include <linux/tracepoint.h>
#define TR_FMT "[%s] fd: addr=0x%llx, len=%u, off=%u"
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 0998ceb1a26e..457106e761be 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -15,6 +15,7 @@
#include <linux/fsl/mc.h>
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
+#include <net/pkt_cls.h>
#include <net/sock.h>
#include "dpaa2-eth.h"
@@ -611,6 +612,10 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv,
sg_init_table(scl, nr_frags + 1);
num_sg = skb_to_sgvec(skb, scl, 0, skb->len);
+ if (unlikely(num_sg < 0)) {
+ err = -ENOMEM;
+ goto dma_map_sg_failed;
+ }
num_dma_bufs = dma_map_sg(dev, scl, num_sg, DMA_BIDIRECTIONAL);
if (unlikely(!num_dma_bufs)) {
err = -ENOMEM;
@@ -681,6 +686,86 @@ dma_map_sg_failed:
return err;
}
+/* Create a SG frame descriptor based on a linear skb.
+ *
+ * This function is used on the Tx path when the skb headroom is not large
+ * enough for the HW requirements, thus instead of realloc-ing the skb we
+ * create a SG frame descriptor with only one entry.
+ */
+static int build_sg_fd_single_buf(struct dpaa2_eth_priv *priv,
+ struct sk_buff *skb,
+ struct dpaa2_fd *fd)
+{
+ struct device *dev = priv->net_dev->dev.parent;
+ struct dpaa2_eth_sgt_cache *sgt_cache;
+ struct dpaa2_sg_entry *sgt;
+ struct dpaa2_eth_swa *swa;
+ dma_addr_t addr, sgt_addr;
+ void *sgt_buf = NULL;
+ int sgt_buf_size;
+ int err;
+
+ /* Prepare the HW SGT structure */
+ sgt_cache = this_cpu_ptr(priv->sgt_cache);
+ sgt_buf_size = priv->tx_data_offset + sizeof(struct dpaa2_sg_entry);
+
+ if (sgt_cache->count == 0)
+ sgt_buf = kzalloc(sgt_buf_size + DPAA2_ETH_TX_BUF_ALIGN,
+ GFP_ATOMIC);
+ else
+ sgt_buf = sgt_cache->buf[--sgt_cache->count];
+ if (unlikely(!sgt_buf))
+ return -ENOMEM;
+
+ sgt_buf = PTR_ALIGN(sgt_buf, DPAA2_ETH_TX_BUF_ALIGN);
+ sgt = (struct dpaa2_sg_entry *)(sgt_buf + priv->tx_data_offset);
+
+ addr = dma_map_single(dev, skb->data, skb->len, DMA_BIDIRECTIONAL);
+ if (unlikely(dma_mapping_error(dev, addr))) {
+ err = -ENOMEM;
+ goto data_map_failed;
+ }
+
+ /* Fill in the HW SGT structure */
+ dpaa2_sg_set_addr(sgt, addr);
+ dpaa2_sg_set_len(sgt, skb->len);
+ dpaa2_sg_set_final(sgt, true);
+
+ /* Store the skb backpointer in the SGT buffer */
+ swa = (struct dpaa2_eth_swa *)sgt_buf;
+ swa->type = DPAA2_ETH_SWA_SINGLE;
+ swa->single.skb = skb;
+ swa->sg.sgt_size = sgt_buf_size;
+
+ /* Separately map the SGT buffer */
+ sgt_addr = dma_map_single(dev, sgt_buf, sgt_buf_size, DMA_BIDIRECTIONAL);
+ if (unlikely(dma_mapping_error(dev, sgt_addr))) {
+ err = -ENOMEM;
+ goto sgt_map_failed;
+ }
+
+ dpaa2_fd_set_offset(fd, priv->tx_data_offset);
+ dpaa2_fd_set_format(fd, dpaa2_fd_sg);
+ dpaa2_fd_set_addr(fd, sgt_addr);
+ dpaa2_fd_set_len(fd, skb->len);
+ dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
+
+ if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+ enable_tx_tstamp(fd, sgt_buf);
+
+ return 0;
+
+sgt_map_failed:
+ dma_unmap_single(dev, addr, skb->len, DMA_BIDIRECTIONAL);
+data_map_failed:
+ if (sgt_cache->count >= DPAA2_ETH_SGT_CACHE_SIZE)
+ kfree(sgt_buf);
+ else
+ sgt_cache->buf[sgt_cache->count++] = sgt_buf;
+
+ return err;
+}
+
/* Create a frame descriptor based on a linear skb */
static int build_single_fd(struct dpaa2_eth_priv *priv,
struct sk_buff *skb,
@@ -739,13 +824,16 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv,
const struct dpaa2_fd *fd, bool in_napi)
{
struct device *dev = priv->net_dev->dev.parent;
- dma_addr_t fd_addr;
+ dma_addr_t fd_addr, sg_addr;
struct sk_buff *skb = NULL;
unsigned char *buffer_start;
struct dpaa2_eth_swa *swa;
u8 fd_format = dpaa2_fd_get_format(fd);
u32 fd_len = dpaa2_fd_get_len(fd);
+ struct dpaa2_eth_sgt_cache *sgt_cache;
+ struct dpaa2_sg_entry *sgt;
+
fd_addr = dpaa2_fd_get_addr(fd);
buffer_start = dpaa2_iova_to_virt(priv->iommu_domain, fd_addr);
swa = (struct dpaa2_eth_swa *)buffer_start;
@@ -765,16 +853,29 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv,
DMA_BIDIRECTIONAL);
}
} else if (fd_format == dpaa2_fd_sg) {
- skb = swa->sg.skb;
+ if (swa->type == DPAA2_ETH_SWA_SG) {
+ skb = swa->sg.skb;
- /* Unmap the scatterlist */
- dma_unmap_sg(dev, swa->sg.scl, swa->sg.num_sg,
- DMA_BIDIRECTIONAL);
- kfree(swa->sg.scl);
+ /* Unmap the scatterlist */
+ dma_unmap_sg(dev, swa->sg.scl, swa->sg.num_sg,
+ DMA_BIDIRECTIONAL);
+ kfree(swa->sg.scl);
- /* Unmap the SGT buffer */
- dma_unmap_single(dev, fd_addr, swa->sg.sgt_size,
- DMA_BIDIRECTIONAL);
+ /* Unmap the SGT buffer */
+ dma_unmap_single(dev, fd_addr, swa->sg.sgt_size,
+ DMA_BIDIRECTIONAL);
+ } else {
+ skb = swa->single.skb;
+
+ /* Unmap the SGT Buffer */
+ dma_unmap_single(dev, fd_addr, swa->single.sgt_size,
+ DMA_BIDIRECTIONAL);
+
+ sgt = (struct dpaa2_sg_entry *)(buffer_start +
+ priv->tx_data_offset);
+ sg_addr = dpaa2_sg_get_addr(sgt);
+ dma_unmap_single(dev, sg_addr, skb->len, DMA_BIDIRECTIONAL);
+ }
} else {
netdev_dbg(priv->net_dev, "Invalid FD format\n");
return;
@@ -804,8 +905,17 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv,
}
/* Free SGT buffer allocated on tx */
- if (fd_format != dpaa2_fd_single)
- skb_free_frag(buffer_start);
+ if (fd_format != dpaa2_fd_single) {
+ sgt_cache = this_cpu_ptr(priv->sgt_cache);
+ if (swa->type == DPAA2_ETH_SWA_SG) {
+ skb_free_frag(buffer_start);
+ } else {
+ if (sgt_cache->count >= DPAA2_ETH_SGT_CACHE_SIZE)
+ kfree(buffer_start);
+ else
+ sgt_cache->buf[sgt_cache->count++] = buffer_start;
+ }
+ }
/* Move on with skb release */
napi_consume_skb(skb, in_napi);
@@ -829,22 +939,6 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
percpu_extras = this_cpu_ptr(priv->percpu_extras);
needed_headroom = dpaa2_eth_needed_headroom(priv, skb);
- if (skb_headroom(skb) < needed_headroom) {
- struct sk_buff *ns;
-
- ns = skb_realloc_headroom(skb, needed_headroom);
- if (unlikely(!ns)) {
- percpu_stats->tx_dropped++;
- goto err_alloc_headroom;
- }
- percpu_extras->tx_reallocs++;
-
- if (skb->sk)
- skb_set_owner_w(ns, skb->sk);
-
- dev_kfree_skb(skb);
- skb = ns;
- }
/* We'll be holding a back-reference to the skb until Tx Confirmation;
* we don't want that overwritten by a concurrent Tx with a cloned skb.
@@ -863,6 +957,12 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
err = build_sg_fd(priv, skb, &fd);
percpu_extras->tx_sg_frames++;
percpu_extras->tx_sg_bytes += skb->len;
+ } else if (skb_headroom(skb) < needed_headroom) {
+ err = build_sg_fd_single_buf(priv, skb, &fd);
+ percpu_extras->tx_sg_frames++;
+ percpu_extras->tx_sg_bytes += skb->len;
+ percpu_extras->tx_converted_sg_frames++;
+ percpu_extras->tx_converted_sg_bytes += skb->len;
} else {
err = build_single_fd(priv, skb, &fd);
}
@@ -920,7 +1020,6 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
return NETDEV_TX_OK;
err_build_fd:
-err_alloc_headroom:
dev_kfree_skb(skb);
return NETDEV_TX_OK;
@@ -1109,7 +1208,7 @@ static void drain_bufs(struct dpaa2_eth_priv *priv, int count)
buf_array, count);
if (ret < 0) {
if (ret == -EBUSY &&
- retries++ >= DPAA2_ETH_SWP_BUSY_RETRIES)
+ retries++ < DPAA2_ETH_SWP_BUSY_RETRIES)
continue;
netdev_err(priv->net_dev, "dpaa2_io_service_acquire() failed\n");
return;
@@ -1157,6 +1256,22 @@ static int refill_pool(struct dpaa2_eth_priv *priv,
return 0;
}
+static void dpaa2_eth_sgt_cache_drain(struct dpaa2_eth_priv *priv)
+{
+ struct dpaa2_eth_sgt_cache *sgt_cache;
+ u16 count;
+ int k, i;
+
+ for_each_possible_cpu(k) {
+ sgt_cache = per_cpu_ptr(priv->sgt_cache, k);
+ count = sgt_cache->count;
+
+ for (i = 0; i < count; i++)
+ kfree(sgt_cache->buf[i]);
+ sgt_cache->count = 0;
+ }
+}
+
static int pull_channel(struct dpaa2_eth_channel *ch)
{
int err;
@@ -1558,6 +1673,9 @@ static int dpaa2_eth_stop(struct net_device *net_dev)
/* Empty the buffer pool */
drain_pool(priv);
+ /* Empty the Scatter-Gather Buffer cache */
+ dpaa2_eth_sgt_cache_drain(priv);
+
return 0;
}
@@ -1959,14 +2077,9 @@ out_err:
static int dpaa2_eth_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
- struct dpaa2_eth_priv *priv = netdev_priv(dev);
-
switch (xdp->command) {
case XDP_SETUP_PROG:
return setup_xdp(dev, xdp->prog);
- case XDP_QUERY_PROG:
- xdp->prog_id = priv->xdp_prog ? priv->xdp_prog->aux->id : 0;
- break;
default:
return -EINVAL;
}
@@ -2096,17 +2209,13 @@ static int update_xps(struct dpaa2_eth_priv *priv)
return err;
}
-static int dpaa2_eth_setup_tc(struct net_device *net_dev,
- enum tc_setup_type type, void *type_data)
+static int dpaa2_eth_setup_mqprio(struct net_device *net_dev,
+ struct tc_mqprio_qopt *mqprio)
{
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
- struct tc_mqprio_qopt *mqprio = type_data;
u8 num_tc, num_queues;
int i;
- if (type != TC_SETUP_QDISC_MQPRIO)
- return -EOPNOTSUPP;
-
mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
num_queues = dpaa2_eth_queue_count(priv);
num_tc = mqprio->num_tc;
@@ -2138,6 +2247,60 @@ out:
return 0;
}
+#define bps_to_mbits(rate) (div_u64((rate), 1000000) * 8)
+
+static int dpaa2_eth_setup_tbf(struct net_device *net_dev, struct tc_tbf_qopt_offload *p)
+{
+ struct tc_tbf_qopt_offload_replace_params *cfg = &p->replace_params;
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+ struct dpni_tx_shaping_cfg tx_cr_shaper = { 0 };
+ struct dpni_tx_shaping_cfg tx_er_shaper = { 0 };
+ int err;
+
+ if (p->command == TC_TBF_STATS)
+ return -EOPNOTSUPP;
+
+ /* Only per port Tx shaping */
+ if (p->parent != TC_H_ROOT)
+ return -EOPNOTSUPP;
+
+ if (p->command == TC_TBF_REPLACE) {
+ if (cfg->max_size > DPAA2_ETH_MAX_BURST_SIZE) {
+ netdev_err(net_dev, "burst size cannot be greater than %d\n",
+ DPAA2_ETH_MAX_BURST_SIZE);
+ return -EINVAL;
+ }
+
+ tx_cr_shaper.max_burst_size = cfg->max_size;
+ /* The TBF interface is in bytes/s, whereas DPAA2 expects the
+ * rate in Mbits/s
+ */
+ tx_cr_shaper.rate_limit = bps_to_mbits(cfg->rate.rate_bytes_ps);
+ }
+
+ err = dpni_set_tx_shaping(priv->mc_io, 0, priv->mc_token, &tx_cr_shaper,
+ &tx_er_shaper, 0);
+ if (err) {
+ netdev_err(net_dev, "dpni_set_tx_shaping() = %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int dpaa2_eth_setup_tc(struct net_device *net_dev,
+ enum tc_setup_type type, void *type_data)
+{
+ switch (type) {
+ case TC_SETUP_QDISC_MQPRIO:
+ return dpaa2_eth_setup_mqprio(net_dev, type_data);
+ case TC_SETUP_QDISC_TBF:
+ return dpaa2_eth_setup_tbf(net_dev, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static const struct net_device_ops dpaa2_eth_ops = {
.ndo_open = dpaa2_eth_open,
.ndo_start_xmit = dpaa2_eth_tx,
@@ -2162,7 +2325,7 @@ static void cdan_cb(struct dpaa2_io_notification_ctx *ctx)
/* Update NAPI statistics */
ch->stats.cdan++;
- napi_schedule_irqoff(&ch->napi);
+ napi_schedule(&ch->napi);
}
/* Allocate and configure a DPCON object */
@@ -2207,7 +2370,7 @@ close:
free:
fsl_mc_object_free(dpcon);
- return NULL;
+ return ERR_PTR(err);
}
static void free_dpcon(struct dpaa2_eth_priv *priv,
@@ -2231,8 +2394,8 @@ alloc_channel(struct dpaa2_eth_priv *priv)
return NULL;
channel->dpcon = setup_dpcon(priv);
- if (IS_ERR_OR_NULL(channel->dpcon)) {
- err = PTR_ERR_OR_ZERO(channel->dpcon);
+ if (IS_ERR(channel->dpcon)) {
+ err = PTR_ERR(channel->dpcon);
goto err_setup;
}
@@ -3602,7 +3765,7 @@ static int netdev_init(struct net_device *net_dev)
net_dev->features = NETIF_F_RXCSUM |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_SG | NETIF_F_HIGHDMA |
- NETIF_F_LLTX;
+ NETIF_F_LLTX | NETIF_F_HW_TC;
net_dev->hw_features = net_dev->features;
return 0;
@@ -3842,6 +4005,13 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
goto err_alloc_percpu_extras;
}
+ priv->sgt_cache = alloc_percpu(*priv->sgt_cache);
+ if (!priv->sgt_cache) {
+ dev_err(dev, "alloc_percpu(sgt_cache) failed\n");
+ err = -ENOMEM;
+ goto err_alloc_sgt_cache;
+ }
+
err = netdev_init(net_dev);
if (err)
goto err_netdev_init;
@@ -3910,6 +4080,8 @@ err_poll_thread:
err_alloc_rings:
err_csum:
err_netdev_init:
+ free_percpu(priv->sgt_cache);
+err_alloc_sgt_cache:
free_percpu(priv->percpu_extras);
err_alloc_percpu_extras:
free_percpu(priv->percpu_stats);
@@ -3955,6 +4127,7 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
fsl_mc_free_irqs(ls_dev);
free_rings(priv);
+ free_percpu(priv->sgt_cache);
free_percpu(priv->percpu_stats);
free_percpu(priv->percpu_extras);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 2d7ada0f0dbd..7f3c41dc98f2 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -43,6 +43,9 @@
*/
#define DPAA2_ETH_FQ_TAILDROP_THRESH (1024 * 1024)
+/* Maximum burst size value for Tx shaping */
+#define DPAA2_ETH_MAX_BURST_SIZE 0xF7FF
+
/* Maximum number of Tx confirmation frames to be processed
* in a single NAPI call
*/
@@ -125,6 +128,7 @@ struct dpaa2_eth_swa {
union {
struct {
struct sk_buff *skb;
+ int sgt_size;
} single;
struct {
struct sk_buff *skb;
@@ -282,9 +286,11 @@ struct dpaa2_eth_drv_stats {
__u64 tx_conf_bytes;
__u64 tx_sg_frames;
__u64 tx_sg_bytes;
- __u64 tx_reallocs;
__u64 rx_sg_frames;
__u64 rx_sg_bytes;
+ /* Linear skbs sent as a S/G FD due to insufficient headroom */
+ __u64 tx_converted_sg_frames;
+ __u64 tx_converted_sg_bytes;
/* Enqueues retried due to portal busy */
__u64 tx_portal_busy;
};
@@ -395,6 +401,12 @@ struct dpaa2_eth_cls_rule {
u8 in_use;
};
+#define DPAA2_ETH_SGT_CACHE_SIZE 256
+struct dpaa2_eth_sgt_cache {
+ void *buf[DPAA2_ETH_SGT_CACHE_SIZE];
+ u16 count;
+};
+
/* Driver private data */
struct dpaa2_eth_priv {
struct net_device *net_dev;
@@ -409,6 +421,7 @@ struct dpaa2_eth_priv {
u8 num_channels;
struct dpaa2_eth_channel *channel[DPAA2_ETH_MAX_DPCONS];
+ struct dpaa2_eth_sgt_cache __percpu *sgt_cache;
struct dpni_attr dpni_attrs;
u16 dpni_ver_major;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
index e88269fe3de7..8356f1fbbee1 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -43,9 +43,10 @@ static char dpaa2_ethtool_extras[][ETH_GSTRING_LEN] = {
"[drv] tx conf bytes",
"[drv] tx sg frames",
"[drv] tx sg bytes",
- "[drv] tx realloc frames",
"[drv] rx sg frames",
"[drv] rx sg bytes",
+ "[drv] tx converted sg frames",
+ "[drv] tx converted sg bytes",
"[drv] enqueue portal busy",
/* Channel stats */
"[drv] dequeue portal busy",
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
index fd069f67be9b..593e3812af93 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
@@ -626,4 +626,17 @@ struct dpni_cmd_set_congestion_notification {
__le32 threshold_exit;
};
+#define DPNI_COUPLED_SHIFT 0
+#define DPNI_COUPLED_SIZE 1
+
+struct dpni_cmd_set_tx_shaping {
+ __le16 tx_cr_max_burst_size;
+ __le16 tx_er_max_burst_size;
+ __le32 pad;
+ __le32 tx_cr_rate_limit;
+ __le32 tx_er_rate_limit;
+ /* from LSB: coupled:1 */
+ u8 coupled;
+};
+
#endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.c b/drivers/net/ethernet/freescale/dpaa2/dpni.c
index 6b479ba66465..68ed4c41b282 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c
@@ -1558,10 +1558,10 @@ int dpni_get_statistics(struct fsl_mc_io *mc_io,
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPNI object
* @cg_point: Congestion point
- * @q_type: Queue type on which the taildrop is configured.
+ * @qtype: Queue type on which the taildrop is configured.
* Only Rx queues are supported for now
* @tc: Traffic class to apply this taildrop to
- * @q_index: Index of the queue if the DPNI supports multiple queues for
+ * @index: Index of the queue if the DPNI supports multiple queues for
* traffic distribution. Ignored if CONGESTION_POINT is not 0.
* @taildrop: Taildrop structure
*
@@ -1602,10 +1602,10 @@ int dpni_set_taildrop(struct fsl_mc_io *mc_io,
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPNI object
* @cg_point: Congestion point
- * @q_type: Queue type on which the taildrop is configured.
+ * @qtype: Queue type on which the taildrop is configured.
* Only Rx queues are supported for now
* @tc: Traffic class to apply this taildrop to
- * @q_index: Index of the queue if the DPNI supports multiple queues for
+ * @index: Index of the queue if the DPNI supports multiple queues for
* traffic distribution. Ignored if CONGESTION_POINT is not 0.
* @taildrop: Taildrop structure
*
@@ -1963,3 +1963,39 @@ int dpni_clear_qos_table(struct fsl_mc_io *mc_io,
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
+
+/**
+ * dpni_set_tx_shaping() - Set the transmit shaping
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @tx_cr_shaper: TX committed rate shaping configuration
+ * @tx_er_shaper: TX excess rate shaping configuration
+ * @coupled: Committed and excess rate shapers are coupled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
+ u32 cmd_flags,
+ u16 token,
+ const struct dpni_tx_shaping_cfg *tx_cr_shaper,
+ const struct dpni_tx_shaping_cfg *tx_er_shaper,
+ int coupled)
+{
+ struct dpni_cmd_set_tx_shaping *cmd_params;
+ struct fsl_mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_SHAPING,
+ cmd_flags,
+ token);
+ cmd_params = (struct dpni_cmd_set_tx_shaping *)cmd.params;
+ cmd_params->tx_cr_max_burst_size = cpu_to_le16(tx_cr_shaper->max_burst_size);
+ cmd_params->tx_er_max_burst_size = cpu_to_le16(tx_er_shaper->max_burst_size);
+ cmd_params->tx_cr_rate_limit = cpu_to_le32(tx_cr_shaper->rate_limit);
+ cmd_params->tx_er_rate_limit = cpu_to_le32(tx_er_shaper->rate_limit);
+ dpni_set_field(cmd_params->coupled, COUPLED, coupled);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.h b/drivers/net/ethernet/freescale/dpaa2/dpni.h
index e874d8084142..39387991a1f9 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h
@@ -1062,5 +1062,21 @@ int dpni_get_api_version(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 *major_ver,
u16 *minor_ver);
+/**
+ * struct dpni_tx_shaping - Structure representing DPNI tx shaping configuration
+ * @rate_limit: Rate in Mbps
+ * @max_burst_size: Burst size in bytes (up to 64KB)
+ */
+struct dpni_tx_shaping_cfg {
+ u32 rate_limit;
+ u16 max_burst_size;
+};
+
+int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
+ u32 cmd_flags,
+ u16 token,
+ const struct dpni_tx_shaping_cfg *tx_cr_shaper,
+ const struct dpni_tx_shaping_cfg *tx_er_shaper,
+ int coupled);
#endif /* __FSL_DPNI_H */
diff --git a/drivers/net/ethernet/freescale/enetc/Kconfig b/drivers/net/ethernet/freescale/enetc/Kconfig
index 2b43848e1363..37b804f8bd76 100644
--- a/drivers/net/ethernet/freescale/enetc/Kconfig
+++ b/drivers/net/ethernet/freescale/enetc/Kconfig
@@ -4,6 +4,7 @@ config FSL_ENETC
depends on PCI && PCI_MSI
select FSL_ENETC_MDIO
select PHYLIB
+ select DIMLIB
help
This driver supports NXP ENETC gigabit ethernet controller PCIe
physical function (PF) devices, managing ENETC Ports at a privileged
@@ -15,6 +16,7 @@ config FSL_ENETC_VF
tristate "ENETC VF driver"
depends on PCI && PCI_MSI
select PHYLIB
+ select DIMLIB
help
This driver supports NXP ENETC gigabit ethernet controller PCIe
virtual function (VF) devices enabled by the ENETC PF driver.
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 22105d09bc89..f78ca7b343d2 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -265,11 +265,12 @@ static irqreturn_t enetc_msix(int irq, void *data)
/* disable interrupts */
enetc_wr_reg(v->rbier, 0);
+ enetc_wr_reg(v->ricr1, v->rx_ictt);
for_each_set_bit(i, &v->tx_rings_map, ENETC_MAX_NUM_TXQS)
enetc_wr_reg(v->tbier_base + ENETC_BDR_OFF(i), 0);
- napi_schedule_irqoff(&v->napi);
+ napi_schedule(&v->napi);
return IRQ_HANDLED;
}
@@ -278,6 +279,34 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget);
static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring,
struct napi_struct *napi, int work_limit);
+static void enetc_rx_dim_work(struct work_struct *w)
+{
+ struct dim *dim = container_of(w, struct dim, work);
+ struct dim_cq_moder moder =
+ net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
+ struct enetc_int_vector *v =
+ container_of(dim, struct enetc_int_vector, rx_dim);
+
+ v->rx_ictt = enetc_usecs_to_cycles(moder.usec);
+ dim->state = DIM_START_MEASURE;
+}
+
+static void enetc_rx_net_dim(struct enetc_int_vector *v)
+{
+ struct dim_sample dim_sample;
+
+ v->comp_cnt++;
+
+ if (!v->rx_napi_work)
+ return;
+
+ dim_update_sample(v->comp_cnt,
+ v->rx_ring.stats.packets,
+ v->rx_ring.stats.bytes,
+ &dim_sample);
+ net_dim(&v->rx_dim, dim_sample);
+}
+
static int enetc_poll(struct napi_struct *napi, int budget)
{
struct enetc_int_vector
@@ -293,12 +322,19 @@ static int enetc_poll(struct napi_struct *napi, int budget)
work_done = enetc_clean_rx_ring(&v->rx_ring, napi, budget);
if (work_done == budget)
complete = false;
+ if (work_done)
+ v->rx_napi_work = true;
if (!complete)
return budget;
napi_complete_done(napi, work_done);
+ if (likely(v->rx_dim_en))
+ enetc_rx_net_dim(v);
+
+ v->rx_napi_work = false;
+
/* enable interrupts */
enetc_wr_reg(v->rbier, ENETC_RBIER_RXTIE);
@@ -1064,8 +1100,8 @@ void enetc_init_si_rings_params(struct enetc_ndev_priv *priv)
struct enetc_si *si = priv->si;
int cpus = num_online_cpus();
- priv->tx_bd_count = ENETC_BDR_DEFAULT_SIZE;
- priv->rx_bd_count = ENETC_BDR_DEFAULT_SIZE;
+ priv->tx_bd_count = ENETC_TX_RING_DEFAULT_SIZE;
+ priv->rx_bd_count = ENETC_RX_RING_DEFAULT_SIZE;
/* Enable all available TX rings in order to configure as many
* priorities as possible, when needed.
@@ -1074,6 +1110,8 @@ void enetc_init_si_rings_params(struct enetc_ndev_priv *priv)
priv->num_rx_rings = min_t(int, cpus, si->num_rx_rings);
priv->num_tx_rings = si->num_tx_rings;
priv->bdr_int_num = cpus;
+ priv->ic_mode = ENETC_IC_RX_ADAPTIVE | ENETC_IC_TX_MANUAL;
+ priv->tx_ictt = ENETC_TXIC_TIMETHR;
/* SI specific */
si->cbd_ring.bd_count = ENETC_CBDR_DEFAULT_SIZE;
@@ -1140,7 +1178,7 @@ static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
tx_ring->next_to_clean = enetc_txbdr_rd(hw, idx, ENETC_TBCIR);
/* enable Tx ints by setting pkt thr to 1 */
- enetc_txbdr_wr(hw, idx, ENETC_TBICIR0, ENETC_TBICIR0_ICEN | 0x1);
+ enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1);
tbmr = ENETC_TBMR_EN;
if (tx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_TX)
@@ -1174,7 +1212,7 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
/* enable Rx ints by setting pkt thr to 1 */
- enetc_rxbdr_wr(hw, idx, ENETC_RBICIR0, ENETC_RBICIR0_ICEN | 0x1);
+ enetc_rxbdr_wr(hw, idx, ENETC_RBICR0, ENETC_RBICR0_ICEN | 0x1);
rbmr = ENETC_RBMR_EN;
@@ -1264,9 +1302,11 @@ static int enetc_setup_irqs(struct enetc_ndev_priv *priv)
dev_err(priv->dev, "request_irq() failed!\n");
goto irq_err;
}
+ disable_irq(irq);
v->tbier_base = hw->reg + ENETC_BDR(TX, 0, ENETC_TBIER);
v->rbier = hw->reg + ENETC_BDR(RX, i, ENETC_RBIER);
+ v->ricr1 = hw->reg + ENETC_BDR(RX, i, ENETC_RBICR1);
enetc_wr(hw, ENETC_SIMSIRRV(i), entry);
@@ -1306,23 +1346,42 @@ static void enetc_free_irqs(struct enetc_ndev_priv *priv)
}
}
-static void enetc_enable_interrupts(struct enetc_ndev_priv *priv)
+static void enetc_setup_interrupts(struct enetc_ndev_priv *priv)
{
+ struct enetc_hw *hw = &priv->si->hw;
+ u32 icpt, ictt;
int i;
/* enable Tx & Rx event indication */
+ if (priv->ic_mode &
+ (ENETC_IC_RX_MANUAL | ENETC_IC_RX_ADAPTIVE)) {
+ icpt = ENETC_RBICR0_SET_ICPT(ENETC_RXIC_PKTTHR);
+ /* init to non-0 minimum, will be adjusted later */
+ ictt = 0x1;
+ } else {
+ icpt = 0x1; /* enable Rx ints by setting pkt thr to 1 */
+ ictt = 0;
+ }
+
for (i = 0; i < priv->num_rx_rings; i++) {
- enetc_rxbdr_wr(&priv->si->hw, i,
- ENETC_RBIER, ENETC_RBIER_RXTIE);
+ enetc_rxbdr_wr(hw, i, ENETC_RBICR1, ictt);
+ enetc_rxbdr_wr(hw, i, ENETC_RBICR0, ENETC_RBICR0_ICEN | icpt);
+ enetc_rxbdr_wr(hw, i, ENETC_RBIER, ENETC_RBIER_RXTIE);
}
+ if (priv->ic_mode & ENETC_IC_TX_MANUAL)
+ icpt = ENETC_TBICR0_SET_ICPT(ENETC_TXIC_PKTTHR);
+ else
+ icpt = 0x1; /* enable Tx ints by setting pkt thr to 1 */
+
for (i = 0; i < priv->num_tx_rings; i++) {
- enetc_txbdr_wr(&priv->si->hw, i,
- ENETC_TBIER, ENETC_TBIER_TXTIE);
+ enetc_txbdr_wr(hw, i, ENETC_TBICR1, priv->tx_ictt);
+ enetc_txbdr_wr(hw, i, ENETC_TBICR0, ENETC_TBICR0_ICEN | icpt);
+ enetc_txbdr_wr(hw, i, ENETC_TBIER, ENETC_TBIER_TXTIE);
}
}
-static void enetc_disable_interrupts(struct enetc_ndev_priv *priv)
+static void enetc_clear_interrupts(struct enetc_ndev_priv *priv)
{
int i;
@@ -1369,10 +1428,33 @@ static int enetc_phy_connect(struct net_device *ndev)
return 0;
}
+void enetc_start(struct net_device *ndev)
+{
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ int i;
+
+ enetc_setup_interrupts(priv);
+
+ for (i = 0; i < priv->bdr_int_num; i++) {
+ int irq = pci_irq_vector(priv->si->pdev,
+ ENETC_BDR_INT_BASE_IDX + i);
+
+ napi_enable(&priv->int_vector[i]->napi);
+ enable_irq(irq);
+ }
+
+ if (ndev->phydev)
+ phy_start(ndev->phydev);
+ else
+ netif_carrier_on(ndev);
+
+ netif_tx_start_all_queues(ndev);
+}
+
int enetc_open(struct net_device *ndev)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
- int i, err;
+ int err;
err = enetc_setup_irqs(priv);
if (err)
@@ -1390,8 +1472,6 @@ int enetc_open(struct net_device *ndev)
if (err)
goto err_alloc_rx;
- enetc_setup_bdrs(priv);
-
err = netif_set_real_num_tx_queues(ndev, priv->num_tx_rings);
if (err)
goto err_set_queues;
@@ -1400,17 +1480,8 @@ int enetc_open(struct net_device *ndev)
if (err)
goto err_set_queues;
- for (i = 0; i < priv->bdr_int_num; i++)
- napi_enable(&priv->int_vector[i]->napi);
-
- enetc_enable_interrupts(priv);
-
- if (ndev->phydev)
- phy_start(ndev->phydev);
- else
- netif_carrier_on(ndev);
-
- netif_tx_start_all_queues(ndev);
+ enetc_setup_bdrs(priv);
+ enetc_start(ndev);
return 0;
@@ -1427,28 +1498,39 @@ err_phy_connect:
return err;
}
-int enetc_close(struct net_device *ndev)
+void enetc_stop(struct net_device *ndev)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
int i;
netif_tx_stop_all_queues(ndev);
- if (ndev->phydev) {
- phy_stop(ndev->phydev);
- phy_disconnect(ndev->phydev);
- } else {
- netif_carrier_off(ndev);
- }
-
for (i = 0; i < priv->bdr_int_num; i++) {
+ int irq = pci_irq_vector(priv->si->pdev,
+ ENETC_BDR_INT_BASE_IDX + i);
+
+ disable_irq(irq);
napi_synchronize(&priv->int_vector[i]->napi);
napi_disable(&priv->int_vector[i]->napi);
}
- enetc_disable_interrupts(priv);
+ if (ndev->phydev)
+ phy_stop(ndev->phydev);
+ else
+ netif_carrier_off(ndev);
+
+ enetc_clear_interrupts(priv);
+}
+
+int enetc_close(struct net_device *ndev)
+{
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+
+ enetc_stop(ndev);
enetc_clear_bdrs(priv);
+ if (ndev->phydev)
+ phy_disconnect(ndev->phydev);
enetc_free_rxtx_rings(priv);
enetc_free_rx_resources(priv);
enetc_free_tx_resources(priv);
@@ -1713,7 +1795,7 @@ int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
int enetc_alloc_msix(struct enetc_ndev_priv *priv)
{
struct pci_dev *pdev = priv->si->pdev;
- int size, v_tx_rings;
+ int v_tx_rings;
int i, n, err, nvec;
nvec = ENETC_BDR_INT_BASE_IDX + priv->bdr_int_num;
@@ -1728,15 +1810,13 @@ int enetc_alloc_msix(struct enetc_ndev_priv *priv)
/* # of tx rings per int vector */
v_tx_rings = priv->num_tx_rings / priv->bdr_int_num;
- size = sizeof(struct enetc_int_vector) +
- sizeof(struct enetc_bdr) * v_tx_rings;
for (i = 0; i < priv->bdr_int_num; i++) {
struct enetc_int_vector *v;
struct enetc_bdr *bdr;
int j;
- v = kzalloc(size, GFP_KERNEL);
+ v = kzalloc(struct_size(v, tx_ring, v_tx_rings), GFP_KERNEL);
if (!v) {
err = -ENOMEM;
goto fail;
@@ -1744,6 +1824,12 @@ int enetc_alloc_msix(struct enetc_ndev_priv *priv)
priv->int_vector[i] = v;
+ /* init defaults for adaptive IC */
+ if (priv->ic_mode & ENETC_IC_RX_ADAPTIVE) {
+ v->rx_ictt = 0x1;
+ v->rx_dim_en = true;
+ }
+ INIT_WORK(&v->rx_dim.work, enetc_rx_dim_work);
netif_napi_add(priv->ndev, &v->napi, enetc_poll,
NAPI_POLL_WEIGHT);
v->count_tx_rings = v_tx_rings;
@@ -1779,6 +1865,7 @@ int enetc_alloc_msix(struct enetc_ndev_priv *priv)
fail:
while (i--) {
netif_napi_del(&priv->int_vector[i]->napi);
+ cancel_work_sync(&priv->int_vector[i]->rx_dim.work);
kfree(priv->int_vector[i]);
}
@@ -1795,6 +1882,7 @@ void enetc_free_msix(struct enetc_ndev_priv *priv)
struct enetc_int_vector *v = priv->int_vector[i];
netif_napi_del(&v->napi);
+ cancel_work_sync(&v->rx_dim.work);
}
for (i = 0; i < priv->num_rx_rings; i++)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index b705464f6882..d309803cfeb6 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -10,6 +10,7 @@
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/phy.h>
+#include <linux/dim.h>
#include "enetc_hw.h"
@@ -44,8 +45,9 @@ struct enetc_ring_stats {
unsigned int rx_alloc_errs;
};
-#define ENETC_BDR_DEFAULT_SIZE 1024
-#define ENETC_DEFAULT_TX_WORK 256
+#define ENETC_RX_RING_DEFAULT_SIZE 512
+#define ENETC_TX_RING_DEFAULT_SIZE 256
+#define ENETC_DEFAULT_TX_WORK (ENETC_TX_RING_DEFAULT_SIZE / 2)
struct enetc_bdr {
struct device *dev; /* for DMA mapping */
@@ -189,14 +191,19 @@ static inline bool enetc_si_is_pf(struct enetc_si *si)
struct enetc_int_vector {
void __iomem *rbier;
void __iomem *tbier_base;
+ void __iomem *ricr1;
unsigned long tx_rings_map;
int count_tx_rings;
- struct napi_struct napi;
+ u32 rx_ictt;
+ u16 comp_cnt;
+ bool rx_dim_en, rx_napi_work;
+ struct napi_struct napi ____cacheline_aligned_in_smp;
+ struct dim rx_dim ____cacheline_aligned_in_smp;
char name[ENETC_INT_NAME_MAX];
- struct enetc_bdr rx_ring ____cacheline_aligned_in_smp;
+ struct enetc_bdr rx_ring;
struct enetc_bdr tx_ring[];
-};
+} ____cacheline_aligned_in_smp;
struct enetc_cls_rule {
struct ethtool_rx_flow_spec fs;
@@ -220,6 +227,21 @@ enum enetc_active_offloads {
ENETC_F_QCI = BIT(3),
};
+/* interrupt coalescing modes */
+enum enetc_ic_mode {
+ /* one interrupt per frame */
+ ENETC_IC_NONE = 0,
+ /* activated when int coalescing time is set to a non-0 value */
+ ENETC_IC_RX_MANUAL = BIT(0),
+ ENETC_IC_TX_MANUAL = BIT(1),
+ /* use dynamic interrupt moderation */
+ ENETC_IC_RX_ADAPTIVE = BIT(2),
+};
+
+#define ENETC_RXIC_PKTTHR min_t(u32, 256, ENETC_RX_RING_DEFAULT_SIZE / 2)
+#define ENETC_TXIC_PKTTHR min_t(u32, 128, ENETC_TX_RING_DEFAULT_SIZE / 2)
+#define ENETC_TXIC_TIMETHR enetc_usecs_to_cycles(600)
+
struct enetc_ndev_priv {
struct net_device *ndev;
struct device *dev; /* dma-mapping device */
@@ -244,6 +266,8 @@ struct enetc_ndev_priv {
struct device_node *phy_node;
phy_interface_t if_mode;
+ int ic_mode;
+ u32 tx_ictt;
};
/* Messaging */
@@ -273,6 +297,8 @@ void enetc_free_si_resources(struct enetc_ndev_priv *priv);
int enetc_open(struct net_device *ndev);
int enetc_close(struct net_device *ndev);
+void enetc_start(struct net_device *ndev);
+void enetc_stop(struct net_device *ndev);
netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev);
struct net_device_stats *enetc_get_stats(struct net_device *ndev);
int enetc_set_features(struct net_device *ndev,
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
index 34bd1f3fb415..1dab83fbca77 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
@@ -14,12 +14,14 @@ static const u32 enetc_si_regs[] = {
static const u32 enetc_txbdr_regs[] = {
ENETC_TBMR, ENETC_TBSR, ENETC_TBBAR0, ENETC_TBBAR1,
- ENETC_TBPIR, ENETC_TBCIR, ENETC_TBLENR, ENETC_TBIER
+ ENETC_TBPIR, ENETC_TBCIR, ENETC_TBLENR, ENETC_TBIER, ENETC_TBICR0,
+ ENETC_TBICR1
};
static const u32 enetc_rxbdr_regs[] = {
ENETC_RBMR, ENETC_RBSR, ENETC_RBBSR, ENETC_RBCIR, ENETC_RBBAR0,
- ENETC_RBBAR1, ENETC_RBPIR, ENETC_RBLENR, ENETC_RBICIR0, ENETC_RBIER
+ ENETC_RBBAR1, ENETC_RBPIR, ENETC_RBLENR, ENETC_RBIER, ENETC_RBICR0,
+ ENETC_RBICR1
};
static const u32 enetc_port_regs[] = {
@@ -561,6 +563,74 @@ static void enetc_get_ringparam(struct net_device *ndev,
}
}
+static int enetc_get_coalesce(struct net_device *ndev,
+ struct ethtool_coalesce *ic)
+{
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ struct enetc_int_vector *v = priv->int_vector[0];
+
+ ic->tx_coalesce_usecs = enetc_cycles_to_usecs(priv->tx_ictt);
+ ic->rx_coalesce_usecs = enetc_cycles_to_usecs(v->rx_ictt);
+
+ ic->tx_max_coalesced_frames = ENETC_TXIC_PKTTHR;
+ ic->rx_max_coalesced_frames = ENETC_RXIC_PKTTHR;
+
+ ic->use_adaptive_rx_coalesce = priv->ic_mode & ENETC_IC_RX_ADAPTIVE;
+
+ return 0;
+}
+
+static int enetc_set_coalesce(struct net_device *ndev,
+ struct ethtool_coalesce *ic)
+{
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ u32 rx_ictt, tx_ictt;
+ int i, ic_mode;
+ bool changed;
+
+ tx_ictt = enetc_usecs_to_cycles(ic->tx_coalesce_usecs);
+ rx_ictt = enetc_usecs_to_cycles(ic->rx_coalesce_usecs);
+
+ if (ic->rx_max_coalesced_frames != ENETC_RXIC_PKTTHR)
+ return -EOPNOTSUPP;
+
+ if (ic->tx_max_coalesced_frames != ENETC_TXIC_PKTTHR)
+ return -EOPNOTSUPP;
+
+ ic_mode = ENETC_IC_NONE;
+ if (ic->use_adaptive_rx_coalesce) {
+ ic_mode |= ENETC_IC_RX_ADAPTIVE;
+ rx_ictt = 0x1;
+ } else {
+ ic_mode |= rx_ictt ? ENETC_IC_RX_MANUAL : 0;
+ }
+
+ ic_mode |= tx_ictt ? ENETC_IC_TX_MANUAL : 0;
+
+ /* commit the settings */
+ changed = (ic_mode != priv->ic_mode) || (priv->tx_ictt != tx_ictt);
+
+ priv->ic_mode = ic_mode;
+ priv->tx_ictt = tx_ictt;
+
+ for (i = 0; i < priv->bdr_int_num; i++) {
+ struct enetc_int_vector *v = priv->int_vector[i];
+
+ v->rx_ictt = rx_ictt;
+ v->rx_dim_en = !!(ic_mode & ENETC_IC_RX_ADAPTIVE);
+ }
+
+ if (netif_running(ndev) && changed) {
+ /* reconfigure the operation mode of h/w interrupts,
+ * traffic needs to be paused in the process
+ */
+ enetc_stop(ndev);
+ enetc_start(ndev);
+ }
+
+ return 0;
+}
+
static int enetc_get_ts_info(struct net_device *ndev,
struct ethtool_ts_info *info)
{
@@ -617,6 +687,9 @@ static int enetc_set_wol(struct net_device *dev,
}
static const struct ethtool_ops enetc_pf_ethtool_ops = {
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
.get_regs_len = enetc_get_reglen,
.get_regs = enetc_get_regs,
.get_sset_count = enetc_get_sset_count,
@@ -629,6 +702,8 @@ static const struct ethtool_ops enetc_pf_ethtool_ops = {
.get_rxfh = enetc_get_rxfh,
.set_rxfh = enetc_set_rxfh,
.get_ringparam = enetc_get_ringparam,
+ .get_coalesce = enetc_get_coalesce,
+ .set_coalesce = enetc_set_coalesce,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
.get_link = ethtool_op_get_link,
@@ -638,6 +713,9 @@ static const struct ethtool_ops enetc_pf_ethtool_ops = {
};
static const struct ethtool_ops enetc_vf_ethtool_ops = {
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
.get_regs_len = enetc_get_reglen,
.get_regs = enetc_get_regs,
.get_sset_count = enetc_get_sset_count,
@@ -649,6 +727,8 @@ static const struct ethtool_ops enetc_vf_ethtool_ops = {
.get_rxfh = enetc_get_rxfh,
.set_rxfh = enetc_set_rxfh,
.get_ringparam = enetc_get_ringparam,
+ .get_coalesce = enetc_get_coalesce,
+ .set_coalesce = enetc_set_coalesce,
.get_link = ethtool_op_get_link,
.get_ts_info = enetc_get_ts_info,
};
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index ce0d321c0639..17cf7c94fdb5 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -121,8 +121,11 @@ enum enetc_bdr_type {TX, RX};
#define ENETC_RBIER 0xa0
#define ENETC_RBIER_RXTIE BIT(0)
#define ENETC_RBIDR 0xa4
-#define ENETC_RBICIR0 0xa8
-#define ENETC_RBICIR0_ICEN BIT(31)
+#define ENETC_RBICR0 0xa8
+#define ENETC_RBICR0_ICEN BIT(31)
+#define ENETC_RBICR0_ICPT_MASK 0x1ff
+#define ENETC_RBICR0_SET_ICPT(n) ((n) & ENETC_RBICR0_ICPT_MASK)
+#define ENETC_RBICR1 0xac
/* TX BDR reg offsets */
#define ENETC_TBMR 0
@@ -141,8 +144,11 @@ enum enetc_bdr_type {TX, RX};
#define ENETC_TBIER 0xa0
#define ENETC_TBIER_TXTIE BIT(0)
#define ENETC_TBIDR 0xa4
-#define ENETC_TBICIR0 0xa8
-#define ENETC_TBICIR0_ICEN BIT(31)
+#define ENETC_TBICR0 0xa8
+#define ENETC_TBICR0_ICEN BIT(31)
+#define ENETC_TBICR0_ICPT_MASK 0xf
+#define ENETC_TBICR0_SET_ICPT(n) ((ilog2(n) + 1) & ENETC_TBICR0_ICPT_MASK)
+#define ENETC_TBICR1 0xac
#define ENETC_RTBLENR_LEN(n) ((n) & ~0x7)
@@ -224,6 +230,9 @@ enum enetc_bdr_type {TX, RX};
#define ENETC_PM0_MAXFRM 0x8014
#define ENETC_SET_TX_MTU(val) ((val) << 16)
#define ENETC_SET_MAXFRM(val) ((val) & 0xffff)
+
+#define ENETC_PM_IMDIO_BASE 0x8030
+
#define ENETC_PM0_IF_MODE 0x8300
#define ENETC_PMO_IFM_RG BIT(2)
#define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11))
@@ -570,6 +579,7 @@ enum bdcr_cmd_class {
BDCR_CMD_STREAM_IDENTIFY,
BDCR_CMD_STREAM_FILTER,
BDCR_CMD_STREAM_GCL,
+ BDCR_CMD_FLOW_METER,
__BDCR_CMD_MAX_LEN,
BDCR_CMD_MAX_LEN = __BDCR_CMD_MAX_LEN - 1,
};
@@ -736,10 +746,33 @@ struct sgcl_data {
struct sgce sgcl[0];
};
+#define ENETC_CBDR_FMI_MR BIT(0)
+#define ENETC_CBDR_FMI_MREN BIT(1)
+#define ENETC_CBDR_FMI_DOY BIT(2)
+#define ENETC_CBDR_FMI_CM BIT(3)
+#define ENETC_CBDR_FMI_CF BIT(4)
+#define ENETC_CBDR_FMI_NDOR BIT(5)
+#define ENETC_CBDR_FMI_OALEN BIT(6)
+#define ENETC_CBDR_FMI_IRFPP_MASK GENMASK(4, 0)
+
+/* class 10: command 0/1, Flow Meter Instance Set, short Format */
+struct fmi_conf {
+ __le32 cir;
+ __le32 cbs;
+ __le32 eir;
+ __le32 ebs;
+ u8 conf;
+ u8 res1;
+ u8 ir_fpp;
+ u8 res2[4];
+ u8 en;
+};
+
struct enetc_cbd {
union{
struct sfi_conf sfi_conf;
struct sgi_table sgi_table;
+ struct fmi_conf fmi_conf;
struct {
__le32 addr[2];
union {
@@ -760,6 +793,15 @@ struct enetc_cbd {
};
#define ENETC_CLK 400000000ULL
+static inline u32 enetc_cycles_to_usecs(u32 cycles)
+{
+ return (u32)div_u64(cycles * 1000000ULL, ENETC_CLK);
+}
+
+static inline u32 enetc_usecs_to_cycles(u32 usecs)
+{
+ return (u32)div_u64(usecs * ENETC_CLK, 1000000ULL);
+}
/* port time gating control register */
#define ENETC_QBV_PTGCR_OFFSET 0x11a00
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 7a9675bd36e8..26d5981b798f 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/* Copyright 2017-2019 NXP */
+#include <linux/mdio.h>
#include <linux/module.h>
#include <linux/fsl/enetc_mdio.h>
#include <linux/of_mdio.h>
@@ -481,7 +482,8 @@ static void enetc_port_si_configure(struct enetc_si *si)
enetc_port_wr(hw, ENETC_PSIVLANFMR, ENETC_PSIVLANFMR_VS);
}
-static void enetc_configure_port_mac(struct enetc_hw *hw)
+static void enetc_configure_port_mac(struct enetc_hw *hw,
+ phy_interface_t phy_mode)
{
enetc_port_wr(hw, ENETC_PM0_MAXFRM,
ENETC_SET_MAXFRM(ENETC_RX_MAXFRM_SIZE));
@@ -497,9 +499,11 @@ static void enetc_configure_port_mac(struct enetc_hw *hw)
ENETC_PM0_CMD_TXP | ENETC_PM0_PROMISC |
ENETC_PM0_TX_EN | ENETC_PM0_RX_EN);
/* set auto-speed for RGMII */
- if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG)
+ if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG ||
+ phy_interface_mode_is_rgmii(phy_mode))
enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO);
- if (enetc_global_rd(hw, ENETC_G_EPFBLPR(1)) == ENETC_G_EPFBLPR1_XGMII)
+
+ if (phy_mode == PHY_INTERFACE_MODE_USXGMII)
enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII);
}
@@ -523,7 +527,7 @@ static void enetc_configure_port(struct enetc_pf *pf)
enetc_configure_port_pmac(hw);
- enetc_configure_port_mac(hw);
+ enetc_configure_port_mac(hw, pf->if_mode);
enetc_port_si_configure(pf->si);
@@ -775,27 +779,27 @@ static void enetc_mdio_remove(struct enetc_pf *pf)
mdiobus_unregister(pf->mdio);
}
-static int enetc_of_get_phy(struct enetc_ndev_priv *priv)
+static int enetc_of_get_phy(struct enetc_pf *pf)
{
- struct enetc_pf *pf = enetc_si_priv(priv->si);
- struct device_node *np = priv->dev->of_node;
+ struct device *dev = &pf->si->pdev->dev;
+ struct device_node *np = dev->of_node;
struct device_node *mdio_np;
int err;
- priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
- if (!priv->phy_node) {
+ pf->phy_node = of_parse_phandle(np, "phy-handle", 0);
+ if (!pf->phy_node) {
if (!of_phy_is_fixed_link(np)) {
- dev_err(priv->dev, "PHY not specified\n");
+ dev_err(dev, "PHY not specified\n");
return -ENODEV;
}
err = of_phy_register_fixed_link(np);
if (err < 0) {
- dev_err(priv->dev, "fixed link registration failed\n");
+ dev_err(dev, "fixed link registration failed\n");
return err;
}
- priv->phy_node = of_node_get(np);
+ pf->phy_node = of_node_get(np);
}
mdio_np = of_get_child_by_name(np, "mdio");
@@ -803,15 +807,15 @@ static int enetc_of_get_phy(struct enetc_ndev_priv *priv)
of_node_put(mdio_np);
err = enetc_mdio_probe(pf);
if (err) {
- of_node_put(priv->phy_node);
+ of_node_put(pf->phy_node);
return err;
}
}
- err = of_get_phy_mode(np, &priv->if_mode);
+ err = of_get_phy_mode(np, &pf->if_mode);
if (err) {
- dev_err(priv->dev, "missing phy type\n");
- of_node_put(priv->phy_node);
+ dev_err(dev, "missing phy type\n");
+ of_node_put(pf->phy_node);
if (of_phy_is_fixed_link(np))
of_phy_deregister_fixed_link(np);
else
@@ -823,14 +827,150 @@ static int enetc_of_get_phy(struct enetc_ndev_priv *priv)
return 0;
}
-static void enetc_of_put_phy(struct enetc_ndev_priv *priv)
+static void enetc_of_put_phy(struct enetc_pf *pf)
{
- struct device_node *np = priv->dev->of_node;
+ struct device_node *np = pf->si->pdev->dev.of_node;
if (np && of_phy_is_fixed_link(np))
of_phy_deregister_fixed_link(np);
- if (priv->phy_node)
- of_node_put(priv->phy_node);
+ if (pf->phy_node)
+ of_node_put(pf->phy_node);
+}
+
+static int enetc_imdio_init(struct enetc_pf *pf, bool is_c45)
+{
+ struct device *dev = &pf->si->pdev->dev;
+ struct enetc_mdio_priv *mdio_priv;
+ struct phy_device *pcs;
+ struct mii_bus *bus;
+ int err;
+
+ bus = mdiobus_alloc_size(sizeof(*mdio_priv));
+ if (!bus)
+ return -ENOMEM;
+
+ bus->name = "Freescale ENETC internal MDIO Bus";
+ bus->read = enetc_mdio_read;
+ bus->write = enetc_mdio_write;
+ bus->parent = dev;
+ bus->phy_mask = ~0;
+ mdio_priv = bus->priv;
+ mdio_priv->hw = &pf->si->hw;
+ mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev));
+
+ err = mdiobus_register(bus);
+ if (err) {
+ dev_err(dev, "cannot register internal MDIO bus (%d)\n", err);
+ goto free_mdio_bus;
+ }
+
+ pcs = get_phy_device(bus, 0, is_c45);
+ if (IS_ERR(pcs)) {
+ err = PTR_ERR(pcs);
+ dev_err(dev, "cannot get internal PCS PHY (%d)\n", err);
+ goto unregister_mdiobus;
+ }
+
+ pf->imdio = bus;
+ pf->pcs = pcs;
+
+ return 0;
+
+unregister_mdiobus:
+ mdiobus_unregister(bus);
+free_mdio_bus:
+ mdiobus_free(bus);
+ return err;
+}
+
+static void enetc_imdio_remove(struct enetc_pf *pf)
+{
+ if (pf->pcs)
+ put_device(&pf->pcs->mdio.dev);
+ if (pf->imdio) {
+ mdiobus_unregister(pf->imdio);
+ mdiobus_free(pf->imdio);
+ }
+}
+
+static void enetc_configure_sgmii(struct phy_device *pcs)
+{
+ /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001
+ * for the MAC PCS in order to acknowledge the AN.
+ */
+ phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII | ADVERTISE_LPACK);
+
+ phy_write(pcs, ENETC_PCS_IF_MODE,
+ ENETC_PCS_IF_MODE_SGMII_EN |
+ ENETC_PCS_IF_MODE_USE_SGMII_AN);
+
+ /* Adjust link timer for SGMII */
+ phy_write(pcs, ENETC_PCS_LINK_TIMER1, ENETC_PCS_LINK_TIMER1_VAL);
+ phy_write(pcs, ENETC_PCS_LINK_TIMER2, ENETC_PCS_LINK_TIMER2_VAL);
+
+ phy_write(pcs, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE);
+}
+
+static void enetc_configure_2500basex(struct phy_device *pcs)
+{
+ phy_write(pcs, ENETC_PCS_IF_MODE,
+ ENETC_PCS_IF_MODE_SGMII_EN |
+ ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500));
+
+ phy_write(pcs, MII_BMCR, BMCR_SPEED1000 | BMCR_FULLDPLX | BMCR_RESET);
+}
+
+static void enetc_configure_usxgmii(struct phy_device *pcs)
+{
+ /* Configure device ability for the USXGMII Replicator */
+ phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_ADVERTISE,
+ ADVERTISE_SGMII | ADVERTISE_LPACK |
+ MDIO_USXGMII_FULL_DUPLEX);
+
+ /* Restart PCS AN */
+ phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_BMCR,
+ BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
+}
+
+static int enetc_configure_serdes(struct enetc_ndev_priv *priv)
+{
+ bool is_c45 = priv->if_mode == PHY_INTERFACE_MODE_USXGMII;
+ struct enetc_pf *pf = enetc_si_priv(priv->si);
+ int err;
+
+ if (priv->if_mode != PHY_INTERFACE_MODE_SGMII &&
+ priv->if_mode != PHY_INTERFACE_MODE_2500BASEX &&
+ priv->if_mode != PHY_INTERFACE_MODE_USXGMII)
+ return 0;
+
+ err = enetc_imdio_init(pf, is_c45);
+ if (err)
+ return err;
+
+ switch (priv->if_mode) {
+ case PHY_INTERFACE_MODE_SGMII:
+ enetc_configure_sgmii(pf->pcs);
+ break;
+ case PHY_INTERFACE_MODE_2500BASEX:
+ enetc_configure_2500basex(pf->pcs);
+ break;
+ case PHY_INTERFACE_MODE_USXGMII:
+ enetc_configure_usxgmii(pf->pcs);
+ break;
+ default:
+ dev_err(&pf->si->pdev->dev, "Unsupported link mode %s\n",
+ phy_modes(priv->if_mode));
+ }
+
+ return 0;
+}
+
+static void enetc_teardown_serdes(struct enetc_ndev_priv *priv)
+{
+ struct enetc_pf *pf = enetc_si_priv(priv->si);
+
+ enetc_imdio_remove(pf);
}
static int enetc_pf_probe(struct pci_dev *pdev,
@@ -864,6 +1004,10 @@ static int enetc_pf_probe(struct pci_dev *pdev,
pf->si = si;
pf->total_vfs = pci_sriov_get_totalvfs(pdev);
+ err = enetc_of_get_phy(pf);
+ if (err)
+ dev_warn(&pdev->dev, "Fallback to PHY-less operation\n");
+
enetc_configure_port(pf);
enetc_get_si_caps(si);
@@ -878,6 +1022,8 @@ static int enetc_pf_probe(struct pci_dev *pdev,
enetc_pf_netdev_setup(si, ndev, &enetc_ndev_ops);
priv = netdev_priv(ndev);
+ priv->phy_node = pf->phy_node;
+ priv->if_mode = pf->if_mode;
enetc_init_si_rings_params(priv);
@@ -893,9 +1039,9 @@ static int enetc_pf_probe(struct pci_dev *pdev,
goto err_alloc_msix;
}
- err = enetc_of_get_phy(priv);
+ err = enetc_configure_serdes(priv);
if (err)
- dev_warn(&pdev->dev, "Fallback to PHY-less operation\n");
+ dev_warn(&pdev->dev, "Attempted SerDes config but failed\n");
err = register_netdev(ndev);
if (err)
@@ -906,8 +1052,8 @@ static int enetc_pf_probe(struct pci_dev *pdev,
return 0;
err_reg_netdev:
+ enetc_teardown_serdes(priv);
enetc_mdio_remove(pf);
- enetc_of_put_phy(priv);
enetc_free_msix(priv);
err_alloc_msix:
enetc_free_si_resources(priv);
@@ -915,6 +1061,7 @@ err_alloc_si_res:
si->ndev = NULL;
free_netdev(ndev);
err_alloc_netdev:
+ enetc_of_put_phy(pf);
err_map_pf_space:
enetc_pci_remove(pdev);
@@ -933,8 +1080,9 @@ static void enetc_pf_remove(struct pci_dev *pdev)
priv = netdev_priv(si->ndev);
unregister_netdev(si->ndev);
+ enetc_teardown_serdes(priv);
enetc_mdio_remove(pf);
- enetc_of_put_phy(priv);
+ enetc_of_put_phy(pf);
enetc_free_msix(priv);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index 59e65a6f6c3e..0d0ee91282a5 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -44,6 +44,11 @@ struct enetc_pf {
DECLARE_BITMAP(active_vlans, VLAN_N_VID);
struct mii_bus *mdio; /* saved for cleanup */
+ struct mii_bus *imdio;
+ struct phy_device *pcs;
+
+ struct device_node *phy_node;
+ phy_interface_t if_mode;
};
int enetc_msg_psi_init(struct enetc_pf *pf);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
index fd3df19eaa32..1c4a535890da 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
@@ -389,6 +389,7 @@ struct enetc_psfp_filter {
u32 index;
s32 handle;
s8 prio;
+ u32 maxsdu;
u32 gate_id;
s32 meter_id;
refcount_t refcount;
@@ -407,10 +408,26 @@ struct enetc_psfp_gate {
struct action_gate_entry entries[0];
};
+/* Only enable the green color frame now
+ * Will add eir and ebs color blind, couple flag etc when
+ * policing action add more offloading parameters
+ */
+struct enetc_psfp_meter {
+ u32 index;
+ u32 cir;
+ u32 cbs;
+ refcount_t refcount;
+ struct hlist_node node;
+};
+
+#define ENETC_PSFP_FLAGS_FMI BIT(0)
+
struct enetc_stream_filter {
struct enetc_streamid sid;
u32 sfi_index;
u32 sgi_index;
+ u32 flags;
+ u32 fmi_index;
struct flow_stats stats;
struct hlist_node node;
};
@@ -421,6 +438,7 @@ struct enetc_psfp {
struct hlist_head stream_list;
struct hlist_head psfp_filter_list;
struct hlist_head psfp_gate_list;
+ struct hlist_head psfp_meter_list;
spinlock_t psfp_lock; /* spinlock for the struct enetc_psfp r/w */
};
@@ -430,6 +448,12 @@ static struct actions_fwd enetc_act_fwd[] = {
BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS),
FILTER_ACTION_TYPE_PSFP
},
+ {
+ BIT(FLOW_ACTION_POLICE) |
+ BIT(FLOW_ACTION_GATE),
+ BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS),
+ FILTER_ACTION_TYPE_PSFP
+ },
/* example for ACL actions */
{
BIT(FLOW_ACTION_DROP),
@@ -487,7 +511,7 @@ static int enetc_streamid_hw_set(struct enetc_ndev_priv *priv,
cbd.addr[0] = lower_32_bits(dma);
cbd.addr[1] = upper_32_bits(dma);
- memset(si_data->dmac, 0xff, ETH_ALEN);
+ eth_broadcast_addr(si_data->dmac);
si_data->vid_vidm_tg =
cpu_to_le16(ENETC_CBDR_SID_VID_MASK
+ ((0x3 << 14) | ENETC_CBDR_SID_VIDM));
@@ -594,8 +618,12 @@ static int enetc_streamfilter_hw_set(struct enetc_ndev_priv *priv,
/* Filter Type. Identifies the contents of the MSDU/FM_INST_INDEX
* field as being either an MSDU value or an index into the Flow
* Meter Instance table.
- * TODO: no limit max sdu
*/
+ if (sfi->maxsdu) {
+ sfi_config->msdu =
+ cpu_to_le16(sfi->maxsdu);
+ sfi_config->multi |= 0x40;
+ }
if (sfi->meter_id >= 0) {
sfi_config->fm_inst_table_index = cpu_to_le16(sfi->meter_id);
@@ -831,6 +859,47 @@ exit:
return err;
}
+static int enetc_flowmeter_hw_set(struct enetc_ndev_priv *priv,
+ struct enetc_psfp_meter *fmi,
+ u8 enable)
+{
+ struct enetc_cbd cbd = { .cmd = 0 };
+ struct fmi_conf *fmi_config;
+ u64 temp = 0;
+
+ cbd.index = cpu_to_le16((u16)fmi->index);
+ cbd.cls = BDCR_CMD_FLOW_METER;
+ cbd.status_flags = 0x80;
+
+ if (!enable)
+ return enetc_send_cmd(priv->si, &cbd);
+
+ fmi_config = &cbd.fmi_conf;
+ fmi_config->en = 0x80;
+
+ if (fmi->cir) {
+ temp = (u64)8000 * fmi->cir;
+ temp = div_u64(temp, 3725);
+ }
+
+ fmi_config->cir = cpu_to_le32((u32)temp);
+ fmi_config->cbs = cpu_to_le32(fmi->cbs);
+
+ /* Default for eir ebs disable */
+ fmi_config->eir = 0;
+ fmi_config->ebs = 0;
+
+ /* Default:
+ * mark red disable
+ * drop on yellow disable
+ * color mode disable
+ * couple flag disable
+ */
+ fmi_config->conf = 0;
+
+ return enetc_send_cmd(priv->si, &cbd);
+}
+
static struct enetc_stream_filter *enetc_get_stream_by_index(u32 index)
{
struct enetc_stream_filter *f;
@@ -864,6 +933,17 @@ static struct enetc_psfp_filter *enetc_get_filter_by_index(u32 index)
return NULL;
}
+static struct enetc_psfp_meter *enetc_get_meter_by_index(u32 index)
+{
+ struct enetc_psfp_meter *m;
+
+ hlist_for_each_entry(m, &epsfp.psfp_meter_list, node)
+ if (m->index == index)
+ return m;
+
+ return NULL;
+}
+
static struct enetc_psfp_filter
*enetc_psfp_check_sfi(struct enetc_psfp_filter *sfi)
{
@@ -872,6 +952,7 @@ static struct enetc_psfp_filter
hlist_for_each_entry(s, &epsfp.psfp_filter_list, node)
if (s->gate_id == sfi->gate_id &&
s->prio == sfi->prio &&
+ s->maxsdu == sfi->maxsdu &&
s->meter_id == sfi->meter_id)
return s;
@@ -922,9 +1003,27 @@ static void stream_gate_unref(struct enetc_ndev_priv *priv, u32 index)
}
}
+static void flow_meter_unref(struct enetc_ndev_priv *priv, u32 index)
+{
+ struct enetc_psfp_meter *fmi;
+ u8 z;
+
+ fmi = enetc_get_meter_by_index(index);
+ WARN_ON(!fmi);
+ z = refcount_dec_and_test(&fmi->refcount);
+ if (z) {
+ enetc_flowmeter_hw_set(priv, fmi, false);
+ hlist_del(&fmi->node);
+ kfree(fmi);
+ }
+}
+
static void remove_one_chain(struct enetc_ndev_priv *priv,
struct enetc_stream_filter *filter)
{
+ if (filter->flags & ENETC_PSFP_FLAGS_FMI)
+ flow_meter_unref(priv, filter->fmi_index);
+
stream_gate_unref(priv, filter->sgi_index);
stream_filter_unref(priv, filter->sfi_index);
@@ -935,7 +1034,8 @@ static void remove_one_chain(struct enetc_ndev_priv *priv,
static int enetc_psfp_hw_set(struct enetc_ndev_priv *priv,
struct enetc_streamid *sid,
struct enetc_psfp_filter *sfi,
- struct enetc_psfp_gate *sgi)
+ struct enetc_psfp_gate *sgi,
+ struct enetc_psfp_meter *fmi)
{
int err;
@@ -953,8 +1053,16 @@ static int enetc_psfp_hw_set(struct enetc_ndev_priv *priv,
if (err)
goto revert_sfi;
+ if (fmi) {
+ err = enetc_flowmeter_hw_set(priv, fmi, true);
+ if (err)
+ goto revert_sgi;
+ }
+
return 0;
+revert_sgi:
+ enetc_streamgate_hw_set(priv, sgi, false);
revert_sfi:
if (sfi)
enetc_streamfilter_hw_set(priv, sfi, false);
@@ -979,9 +1087,11 @@ static struct actions_fwd *enetc_check_flow_actions(u64 acts,
static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
struct flow_cls_offload *f)
{
+ struct flow_action_entry *entryg = NULL, *entryp = NULL;
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
struct netlink_ext_ack *extack = f->common.extack;
struct enetc_stream_filter *filter, *old_filter;
+ struct enetc_psfp_meter *fmi = NULL, *old_fmi;
struct enetc_psfp_filter *sfi, *old_sfi;
struct enetc_psfp_gate *sgi, *old_sgi;
struct flow_action_entry *entry;
@@ -997,9 +1107,12 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
flow_action_for_each(i, entry, &rule->action)
if (entry->id == FLOW_ACTION_GATE)
- break;
+ entryg = entry;
+ else if (entry->id == FLOW_ACTION_POLICE)
+ entryp = entry;
- if (entry->id != FLOW_ACTION_GATE)
+ /* Not support without gate action */
+ if (!entryg)
return -EINVAL;
filter = kzalloc(sizeof(*filter), GFP_KERNEL);
@@ -1017,7 +1130,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
!is_zero_ether_addr(match.mask->src)) {
NL_SET_ERR_MSG_MOD(extack,
"Cannot match on both source and destination MAC");
- err = EINVAL;
+ err = -EINVAL;
goto free_filter;
}
@@ -1025,7 +1138,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
if (!is_broadcast_ether_addr(match.mask->dst)) {
NL_SET_ERR_MSG_MOD(extack,
"Masked matching on destination MAC not supported");
- err = EINVAL;
+ err = -EINVAL;
goto free_filter;
}
ether_addr_copy(filter->sid.dst_mac, match.key->dst);
@@ -1036,7 +1149,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
if (!is_broadcast_ether_addr(match.mask->src)) {
NL_SET_ERR_MSG_MOD(extack,
"Masked matching on source MAC not supported");
- err = EINVAL;
+ err = -EINVAL;
goto free_filter;
}
ether_addr_copy(filter->sid.src_mac, match.key->src);
@@ -1044,7 +1157,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
}
} else {
NL_SET_ERR_MSG_MOD(extack, "Unsupported, must include ETH_ADDRS");
- err = EINVAL;
+ err = -EINVAL;
goto free_filter;
}
@@ -1079,19 +1192,19 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
}
/* parsing gate action */
- if (entry->gate.index >= priv->psfp_cap.max_psfp_gate) {
+ if (entryg->gate.index >= priv->psfp_cap.max_psfp_gate) {
NL_SET_ERR_MSG_MOD(extack, "No Stream Gate resource!");
err = -ENOSPC;
goto free_filter;
}
- if (entry->gate.num_entries >= priv->psfp_cap.max_psfp_gatelist) {
+ if (entryg->gate.num_entries >= priv->psfp_cap.max_psfp_gatelist) {
NL_SET_ERR_MSG_MOD(extack, "No Stream Gate resource!");
err = -ENOSPC;
goto free_filter;
}
- entries_size = struct_size(sgi, entries, entry->gate.num_entries);
+ entries_size = struct_size(sgi, entries, entryg->gate.num_entries);
sgi = kzalloc(entries_size, GFP_KERNEL);
if (!sgi) {
err = -ENOMEM;
@@ -1099,18 +1212,18 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
}
refcount_set(&sgi->refcount, 1);
- sgi->index = entry->gate.index;
- sgi->init_ipv = entry->gate.prio;
- sgi->basetime = entry->gate.basetime;
- sgi->cycletime = entry->gate.cycletime;
- sgi->num_entries = entry->gate.num_entries;
+ sgi->index = entryg->gate.index;
+ sgi->init_ipv = entryg->gate.prio;
+ sgi->basetime = entryg->gate.basetime;
+ sgi->cycletime = entryg->gate.cycletime;
+ sgi->num_entries = entryg->gate.num_entries;
e = sgi->entries;
- for (i = 0; i < entry->gate.num_entries; i++) {
- e[i].gate_state = entry->gate.entries[i].gate_state;
- e[i].interval = entry->gate.entries[i].interval;
- e[i].ipv = entry->gate.entries[i].ipv;
- e[i].maxoctets = entry->gate.entries[i].maxoctets;
+ for (i = 0; i < entryg->gate.num_entries; i++) {
+ e[i].gate_state = entryg->gate.entries[i].gate_state;
+ e[i].interval = entryg->gate.entries[i].interval;
+ e[i].ipv = entryg->gate.entries[i].ipv;
+ e[i].maxoctets = entryg->gate.entries[i].maxoctets;
}
filter->sgi_index = sgi->index;
@@ -1123,10 +1236,29 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
refcount_set(&sfi->refcount, 1);
sfi->gate_id = sgi->index;
-
- /* flow meter not support yet */
sfi->meter_id = ENETC_PSFP_WILDCARD;
+ /* Flow meter and max frame size */
+ if (entryp) {
+ if (entryp->police.burst) {
+ fmi = kzalloc(sizeof(*fmi), GFP_KERNEL);
+ if (!fmi) {
+ err = -ENOMEM;
+ goto free_sfi;
+ }
+ refcount_set(&fmi->refcount, 1);
+ fmi->cir = entryp->police.rate_bytes_ps;
+ fmi->cbs = entryp->police.burst;
+ fmi->index = entryp->police.index;
+ filter->flags |= ENETC_PSFP_FLAGS_FMI;
+ filter->fmi_index = fmi->index;
+ sfi->meter_id = fmi->index;
+ }
+
+ if (entryp->police.mtu)
+ sfi->maxsdu = entryp->police.mtu;
+ }
+
/* prio ref the filter prio */
if (f->common.prio && f->common.prio <= BIT(3))
sfi->prio = f->common.prio - 1;
@@ -1141,7 +1273,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
if (sfi->handle < 0) {
NL_SET_ERR_MSG_MOD(extack, "No Stream Filter resource!");
err = -ENOSPC;
- goto free_sfi;
+ goto free_fmi;
}
sfi->index = index;
@@ -1157,11 +1289,23 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
}
err = enetc_psfp_hw_set(priv, &filter->sid,
- sfi_overwrite ? NULL : sfi, sgi);
+ sfi_overwrite ? NULL : sfi, sgi, fmi);
if (err)
- goto free_sfi;
+ goto free_fmi;
spin_lock(&epsfp.psfp_lock);
+ if (filter->flags & ENETC_PSFP_FLAGS_FMI) {
+ old_fmi = enetc_get_meter_by_index(filter->fmi_index);
+ if (old_fmi) {
+ fmi->refcount = old_fmi->refcount;
+ refcount_set(&fmi->refcount,
+ refcount_read(&old_fmi->refcount) + 1);
+ hlist_del(&old_fmi->node);
+ kfree(old_fmi);
+ }
+ hlist_add_head(&fmi->node, &epsfp.psfp_meter_list);
+ }
+
/* Remove the old node if exist and update with a new node */
old_sgi = enetc_get_gate_by_index(filter->sgi_index);
if (old_sgi) {
@@ -1192,6 +1336,8 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
return 0;
+free_fmi:
+ kfree(fmi);
free_sfi:
kfree(sfi);
free_gate:
@@ -1290,13 +1436,20 @@ static int enetc_psfp_get_stats(struct enetc_ndev_priv *priv,
return -EINVAL;
spin_lock(&epsfp.psfp_lock);
- stats.pkts = counters.matching_frames_count - filter->stats.pkts;
+ stats.pkts = counters.matching_frames_count +
+ counters.not_passing_sdu_count -
+ filter->stats.pkts;
+ stats.drops = counters.not_passing_frames_count +
+ counters.not_passing_sdu_count +
+ counters.red_frames_count -
+ filter->stats.drops;
stats.lastused = filter->stats.lastused;
filter->stats.pkts += stats.pkts;
+ filter->stats.drops += stats.drops;
spin_unlock(&epsfp.psfp_lock);
- flow_stats_update(&f->stats, 0x0, stats.pkts, stats.lastused,
- FLOW_ACTION_HW_STATS_DELAYED);
+ flow_stats_update(&f->stats, 0x0, stats.pkts, stats.drops,
+ stats.lastused, FLOW_ACTION_HW_STATS_DELAYED);
return 0;
}
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index cc7fbfc09354..9934421814b4 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -708,8 +708,7 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- int total_len, data_left;
+ int hdr_len, total_len, data_left;
struct bufdesc *bdp = txq->bd.cur;
struct tso_t tso;
unsigned int index = 0;
@@ -729,7 +728,7 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
}
/* Initialize the TSO handler, and prepare the first payload */
- tso_start(skb, &tso);
+ hdr_len = tso_start(skb, &tso);
total_len = skb->len - hdr_len;
while (total_len > 0) {
@@ -3690,6 +3689,8 @@ fec_probe(struct platform_device *pdev)
fec_enet_clk_enable(ndev, false);
pinctrl_pm_select_sleep_state(&pdev->dev);
+ ndev->max_mtu = PKT_MAXBUF_SIZE - ETH_HLEN - ETH_FCS_LEN;
+
ret = register_netdev(ndev);
if (ret)
goto failed_register;
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index f8a592c96beb..a0c1f4410306 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -103,11 +103,6 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
u64 ns;
val = 0;
- if (!(fep->hwts_tx_en || fep->hwts_rx_en)) {
- dev_err(&fep->pdev->dev, "No ptp stack is running\n");
- return -EINVAL;
- }
-
if (fep->pps_enable == enable)
return 0;
@@ -269,7 +264,7 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
fep->cc.mult = FEC_CC_MULT;
/* reset the ns time counter */
- timecounter_init(&fep->tc, &fep->cc, ktime_to_ns(ktime_get_real()));
+ timecounter_init(&fep->tc, &fep->cc, 0);
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
}
@@ -490,9 +485,7 @@ int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr)
switch (config.rx_filter) {
case HWTSTAMP_FILTER_NONE:
- if (fep->hwts_rx_en)
- fep->hwts_rx_en = 0;
- config.rx_filter = HWTSTAMP_FILTER_NONE;
+ fep->hwts_rx_en = 0;
break;
default:
@@ -589,7 +582,7 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)
int ret;
fep->ptp_caps.owner = THIS_MODULE;
- snprintf(fep->ptp_caps.name, 16, "fec ptp");
+ strlcpy(fep->ptp_caps.name, "fec ptp", sizeof(fep->ptp_caps.name));
fep->ptp_caps.max_adj = 250000000;
fep->ptp_caps.n_alarm = 0;
diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c
index f151d6e111dd..ef67e8599b39 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -1398,8 +1398,7 @@ static void enable_time_stamp(struct fman *fman)
{
struct fman_fpm_regs __iomem *fpm_rg = fman->fpm_regs;
u16 fm_clk_freq = fman->state->fm_clk_freq;
- u32 tmp, intgr, ts_freq;
- u64 frac;
+ u32 tmp, intgr, ts_freq, frac;
ts_freq = (u32)(1 << fman->state->count1_micro_bit);
/* configure timestamp so that bit 8 will count 1 microsecond
diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
index 004c266802a8..bce3c9398887 100644
--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
@@ -1200,7 +1200,7 @@ int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
list_for_each(pos,
&dtsec->multicast_addr_hash->lsts[bucket]) {
hash_entry = ETH_HASH_ENTRY_OBJ(pos);
- if (hash_entry->addr == addr) {
+ if (hash_entry && hash_entry->addr == addr) {
list_del_init(&hash_entry->node);
kfree(hash_entry);
break;
@@ -1213,7 +1213,7 @@ int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
list_for_each(pos,
&dtsec->unicast_addr_hash->lsts[bucket]) {
hash_entry = ETH_HASH_ENTRY_OBJ(pos);
- if (hash_entry->addr == addr) {
+ if (hash_entry && hash_entry->addr == addr) {
list_del_init(&hash_entry->node);
kfree(hash_entry);
break;
diff --git a/drivers/net/ethernet/freescale/fman/fman_mac.h b/drivers/net/ethernet/freescale/fman/fman_mac.h
index dd6d0526f6c1..19f327efdaff 100644
--- a/drivers/net/ethernet/freescale/fman/fman_mac.h
+++ b/drivers/net/ethernet/freescale/fman/fman_mac.h
@@ -252,7 +252,7 @@ static inline struct eth_hash_t *alloc_hash_table(u16 size)
struct eth_hash_t *hash;
/* Allocate address hash table */
- hash = kmalloc_array(size, sizeof(struct eth_hash_t *), GFP_KERNEL);
+ hash = kmalloc(sizeof(*hash), GFP_KERNEL);
if (!hash)
return NULL;
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index a5500ede4070..645764abdaae 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -852,7 +852,6 @@ int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
tmp = ioread32be(&regs->command_config);
tmp &= ~CMD_CFG_PFC_MODE;
- priority = 0;
iowrite32be(tmp, &regs->command_config);
@@ -982,7 +981,7 @@ int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
list_for_each(pos, &memac->multicast_addr_hash->lsts[hash]) {
hash_entry = ETH_HASH_ENTRY_OBJ(pos);
- if (hash_entry->addr == addr) {
+ if (hash_entry && hash_entry->addr == addr) {
list_del_init(&hash_entry->node);
kfree(hash_entry);
break;
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c
index 87b26f063cc8..c27df153f895 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -1767,6 +1767,7 @@ static int fman_port_probe(struct platform_device *of_dev)
struct fman_port *port;
struct fman *fman;
struct device_node *fm_node, *port_node;
+ struct platform_device *fm_pdev;
struct resource res;
struct resource *dev_res;
u32 val;
@@ -1791,8 +1792,14 @@ static int fman_port_probe(struct platform_device *of_dev)
goto return_err;
}
- fman = dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
+ fm_pdev = of_find_device_by_node(fm_node);
of_node_put(fm_node);
+ if (!fm_pdev) {
+ err = -EINVAL;
+ goto return_err;
+ }
+
+ fman = dev_get_drvdata(&fm_pdev->dev);
if (!fman) {
err = -EINVAL;
goto return_err;
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c
index 8c7eb878d5b4..41946b16f6c7 100644
--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
@@ -626,7 +626,7 @@ int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
list_for_each(pos, &tgec->multicast_addr_hash->lsts[hash]) {
hash_entry = ETH_HASH_ENTRY_OBJ(pos);
- if (hash_entry->addr == addr) {
+ if (hash_entry && hash_entry->addr == addr) {
list_del_init(&hash_entry->node);
kfree(hash_entry);
break;
diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index b0d4b1984a70..bf846b42bc74 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -1043,8 +1043,7 @@ out_cleanup_data:
out_free_dev:
free_netdev(ndev);
out_put:
- if (fpi->clk_per)
- clk_disable_unprepare(fpi->clk_per);
+ clk_disable_unprepare(fpi->clk_per);
out_deregister_fixed_link:
of_node_put(fpi->phy_node);
if (of_phy_is_fixed_link(ofdev->dev.of_node))
@@ -1065,8 +1064,7 @@ static int fs_enet_remove(struct platform_device *ofdev)
fep->ops->cleanup_data(ndev);
dev_set_drvdata(fep->dev, NULL);
of_node_put(fep->fpi->phy_node);
- if (fep->fpi->clk_per)
- clk_disable_unprepare(fep->fpi->clk_per);
+ clk_disable_unprepare(fep->fpi->clk_per);
if (of_phy_is_fixed_link(ofdev->dev.of_node))
of_phy_deregister_fixed_link(ofdev->dev.of_node);
free_netdev(ndev);
diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
index c82c85ef5fb3..98be51d8b08c 100644
--- a/drivers/net/ethernet/freescale/xgmac_mdio.c
+++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
@@ -245,14 +245,19 @@ static int xgmac_mdio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mii_bus *bus;
- struct resource res;
+ struct resource *res;
struct mdio_fsl_priv *priv;
int ret;
- ret = of_address_to_resource(np, 0, &res);
- if (ret) {
+ /* In DPAA-1, MDIO is one of the many FMan sub-devices. The FMan
+ * defines a register space that spans a large area, covering all the
+ * subdevice areas. Therefore, MDIO cannot claim exclusive access to
+ * this register area.
+ */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
dev_err(&pdev->dev, "could not obtain address\n");
- return ret;
+ return -EINVAL;
}
bus = mdiobus_alloc_size(sizeof(struct mdio_fsl_priv));
@@ -263,21 +268,22 @@ static int xgmac_mdio_probe(struct platform_device *pdev)
bus->read = xgmac_mdio_read;
bus->write = xgmac_mdio_write;
bus->parent = &pdev->dev;
- snprintf(bus->id, MII_BUS_ID_SIZE, "%llx", (unsigned long long)res.start);
+ bus->probe_capabilities = MDIOBUS_C22_C45;
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res->start);
/* Set the PHY base address */
priv = bus->priv;
- priv->mdio_base = of_iomap(np, 0);
+ priv->mdio_base = ioremap(res->start, resource_size(res));
if (!priv->mdio_base) {
ret = -ENOMEM;
goto err_ioremap;
}
- priv->is_little_endian = of_property_read_bool(pdev->dev.of_node,
- "little-endian");
+ priv->is_little_endian = device_property_read_bool(&pdev->dev,
+ "little-endian");
- priv->has_a011043 = of_property_read_bool(pdev->dev.of_node,
- "fsl,erratum-a011043");
+ priv->has_a011043 = device_property_read_bool(&pdev->dev,
+ "fsl,erratum-a011043");
ret = of_mdiobus_register(bus, np);
if (ret) {
@@ -320,10 +326,17 @@ static const struct of_device_id xgmac_mdio_match[] = {
};
MODULE_DEVICE_TABLE(of, xgmac_mdio_match);
+static const struct acpi_device_id xgmac_acpi_match[] = {
+ { "NXP0006" },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, xgmac_acpi_match);
+
static struct platform_driver xgmac_mdio_driver = {
.driver = {
.name = "fsl-fman_xmdio",
.of_match_table = xgmac_mdio_match,
+ .acpi_match_table = xgmac_acpi_match,
},
.probe = xgmac_mdio_probe,
.remove = xgmac_mdio_remove,
diff --git a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
index 4fb776920a93..8b2bf85039f1 100644
--- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
@@ -1024,9 +1024,9 @@ static int hix5hd2_init_sg_desc_queue(struct hix5hd2_priv *priv)
struct sg_desc *desc;
dma_addr_t phys_addr;
- desc = (struct sg_desc *)dma_alloc_coherent(priv->dev,
- TX_DESC_NUM * sizeof(struct sg_desc),
- &phys_addr, GFP_KERNEL);
+ desc = dma_alloc_coherent(priv->dev,
+ TX_DESC_NUM * sizeof(struct sg_desc),
+ &phys_addr, GFP_KERNEL);
if (!desc)
return -ENOMEM;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 1c5243cc1dc6..acfa86e5296f 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -1724,7 +1724,7 @@ static void hns_dsaf_setup_mc_mask(struct dsaf_device *dsaf_dev,
u8 port_num, u8 *mask, u8 *addr)
{
if (MAC_IS_BROADCAST(addr))
- memset(mask, 0xff, ETH_ALEN);
+ eth_broadcast_addr(mask);
else
memcpy(mask, dsaf_dev->mac_cb[port_num]->mc_mask, ETH_ALEN);
}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 71ed4c54f6d5..87776ce3539b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -8,6 +8,7 @@
#include <linux/cpu_rmap.h>
#endif
#include <linux/if_vlan.h>
+#include <linux/irq.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/module.h>
@@ -154,6 +155,7 @@ static int hns3_nic_init_irq(struct hns3_nic_priv *priv)
tqp_vectors->name[HNAE3_INT_NAME_LEN - 1] = '\0';
+ irq_set_status_flags(tqp_vectors->vector_irq, IRQ_NOAUTOEN);
ret = request_irq(tqp_vectors->vector_irq, hns3_irq_handle, 0,
tqp_vectors->name, tqp_vectors);
if (ret) {
@@ -163,8 +165,6 @@ static int hns3_nic_init_irq(struct hns3_nic_priv *priv)
return ret;
}
- disable_irq(tqp_vectors->vector_irq);
-
irq_set_affinity_hint(tqp_vectors->vector_irq,
&tqp_vectors->affinity_mask);
@@ -2093,10 +2093,8 @@ static int hns3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, ae_dev);
ret = hnae3_register_ae_dev(ae_dev);
- if (ret) {
- devm_kfree(&pdev->dev, ae_dev);
+ if (ret)
pci_set_drvdata(pdev, NULL);
- }
return ret;
}
@@ -2153,7 +2151,6 @@ static void hns3_shutdown(struct pci_dev *pdev)
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
hnae3_unregister_ae_dev(ae_dev);
- devm_kfree(&pdev->dev, ae_dev);
pci_set_drvdata(pdev, NULL);
if (system_state == SYSTEM_POWER_OFF)
@@ -2404,7 +2401,7 @@ static int hns3_alloc_desc(struct hns3_enet_ring *ring)
return 0;
}
-static int hns3_reserve_buffer_map(struct hns3_enet_ring *ring,
+static int hns3_alloc_and_map_buffer(struct hns3_enet_ring *ring,
struct hns3_desc_cb *cb)
{
int ret;
@@ -2425,9 +2422,9 @@ out:
return ret;
}
-static int hns3_alloc_buffer_attach(struct hns3_enet_ring *ring, int i)
+static int hns3_alloc_and_attach_buffer(struct hns3_enet_ring *ring, int i)
{
- int ret = hns3_reserve_buffer_map(ring, &ring->desc_cb[i]);
+ int ret = hns3_alloc_and_map_buffer(ring, &ring->desc_cb[i]);
if (ret)
return ret;
@@ -2443,7 +2440,7 @@ static int hns3_alloc_ring_buffers(struct hns3_enet_ring *ring)
int i, j, ret;
for (i = 0; i < ring->desc_num; i++) {
- ret = hns3_alloc_buffer_attach(ring, i);
+ ret = hns3_alloc_and_attach_buffer(ring, i);
if (ret)
goto out_buffer_fail;
}
@@ -2472,6 +2469,11 @@ static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i)
ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
ring->desc_cb[i].page_offset);
ring->desc[i].rx.bd_base_info = 0;
+
+ dma_sync_single_for_device(ring_to_dev(ring),
+ ring->desc_cb[i].dma + ring->desc_cb[i].page_offset,
+ hns3_buf_size(ring),
+ DMA_FROM_DEVICE);
}
static void hns3_nic_reclaim_desc(struct hns3_enet_ring *ring, int head,
@@ -2589,7 +2591,7 @@ static void hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,
hns3_reuse_buffer(ring, ring->next_to_use);
} else {
- ret = hns3_reserve_buffer_map(ring, &res_cbs);
+ ret = hns3_alloc_and_map_buffer(ring, &res_cbs);
if (ret) {
u64_stats_update_begin(&ring->syncp);
ring->stats.sw_err_cnt++;
@@ -2917,6 +2919,11 @@ static int hns3_add_frag(struct hns3_enet_ring *ring)
skb = ring->tail_skb;
}
+ dma_sync_single_for_cpu(ring_to_dev(ring),
+ desc_cb->dma + desc_cb->page_offset,
+ hns3_buf_size(ring),
+ DMA_FROM_DEVICE);
+
hns3_nic_reuse_page(skb, ring->frag_num++, ring, 0, desc_cb);
trace_hns3_rx_desc(ring);
ring_ptr_move_fw(ring, next_to_clean);
@@ -3068,8 +3075,14 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring)
if (unlikely(!(bd_base_info & BIT(HNS3_RXD_VLD_B))))
return -ENXIO;
- if (!skb)
- ring->va = (unsigned char *)desc_cb->buf + desc_cb->page_offset;
+ if (!skb) {
+ ring->va = desc_cb->buf + desc_cb->page_offset;
+
+ dma_sync_single_for_cpu(ring_to_dev(ring),
+ desc_cb->dma + desc_cb->page_offset,
+ hns3_buf_size(ring),
+ DMA_FROM_DEVICE);
+ }
/* Prefetch first cache line of first page
* Idea is to cache few bytes of the header of the packet. Our L1 Cache
@@ -4182,7 +4195,7 @@ static int hns3_clear_rx_ring(struct hns3_enet_ring *ring)
* stack, so we need to replace the buffer here.
*/
if (!ring->desc_cb[ring->next_to_use].reuse_flag) {
- ret = hns3_reserve_buffer_map(ring, &res_cbs);
+ ret = hns3_alloc_and_map_buffer(ring, &res_cbs);
if (ret) {
u64_stats_update_begin(&ring->syncp);
ring->stats.sw_err_cnt++;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index a8776620acbc..9922c5fd7f94 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -405,7 +405,7 @@ struct hns3_enet_ring {
u32 pull_len; /* head length for current packet */
u32 frag_num;
- unsigned char *va; /* first buffer address for current packet */
+ void *va; /* first buffer address for current packet */
u32 flag; /* ring attribute */
diff --git a/drivers/net/ethernet/huawei/hinic/Makefile b/drivers/net/ethernet/huawei/hinic/Makefile
index 32a011ca44c3..67b59d0ba769 100644
--- a/drivers/net/ethernet/huawei/hinic/Makefile
+++ b/drivers/net/ethernet/huawei/hinic/Makefile
@@ -4,4 +4,4 @@ obj-$(CONFIG_HINIC) += hinic.o
hinic-y := hinic_main.o hinic_tx.o hinic_rx.o hinic_port.o hinic_hw_dev.o \
hinic_hw_io.o hinic_hw_qp.o hinic_hw_cmdq.o hinic_hw_wq.o \
hinic_hw_mgmt.o hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.o \
- hinic_common.o hinic_ethtool.o hinic_hw_mbox.o hinic_sriov.o
+ hinic_common.o hinic_ethtool.o hinic_devlink.o hinic_hw_mbox.o hinic_sriov.o
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_dev.h
index 48b40be3e84d..0a1e20edf7cf 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_dev.h
@@ -20,11 +20,14 @@
#define HINIC_DRV_NAME "hinic"
+#define LP_PKT_CNT 64
+
enum hinic_flags {
HINIC_LINK_UP = BIT(0),
HINIC_INTF_UP = BIT(1),
HINIC_RSS_ENABLE = BIT(2),
HINIC_LINK_DOWN = BIT(3),
+ HINIC_LP_TEST = BIT(4),
};
struct hinic_rx_mode_work {
@@ -49,6 +52,12 @@ enum hinic_rss_hash_type {
HINIC_RSS_HASH_ENGINE_TYPE_MAX,
};
+struct hinic_intr_coal_info {
+ u8 pending_limt;
+ u8 coalesce_timer_cfg;
+ u8 resend_timer_cfg;
+};
+
struct hinic_dev {
struct net_device *netdev;
struct hinic_hwdev *hwdev;
@@ -82,7 +91,21 @@ struct hinic_dev {
struct hinic_rss_type rss_type;
u8 *rss_hkey_user;
s32 *rss_indir_user;
+ struct hinic_intr_coal_info *rx_intr_coalesce;
+ struct hinic_intr_coal_info *tx_intr_coalesce;
struct hinic_sriov_info sriov_info;
+ int lb_test_rx_idx;
+ int lb_pkt_len;
+ u8 *lb_test_rx_buf;
+ struct devlink *devlink;
+ bool cable_unplugged;
+ bool module_unrecognized;
+};
+
+struct hinic_devlink_priv {
+ struct hinic_hwdev *hwdev;
+ struct devlink_health_reporter *hw_fault_reporter;
+ struct devlink_health_reporter *fw_fault_reporter;
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c
new file mode 100644
index 000000000000..c6adc776f3c8
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c
@@ -0,0 +1,608 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Huawei HiNIC PCI Express Linux driver
+ * Copyright(c) 2017 Huawei Technologies Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ */
+#include <linux/netlink.h>
+#include <net/devlink.h>
+#include <linux/firmware.h>
+
+#include "hinic_port.h"
+#include "hinic_devlink.h"
+#include "hinic_hw_dev.h"
+
+static bool check_image_valid(struct hinic_devlink_priv *priv, const u8 *buf,
+ u32 image_size, struct host_image_st *host_image)
+{
+ struct fw_image_st *fw_image = NULL;
+ u32 len = 0;
+ u32 i;
+
+ fw_image = (struct fw_image_st *)buf;
+
+ if (fw_image->fw_magic != HINIC_MAGIC_NUM) {
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Wrong fw_magic read from file, fw_magic: 0x%x\n",
+ fw_image->fw_magic);
+ return false;
+ }
+
+ if (fw_image->fw_info.fw_section_cnt > MAX_FW_TYPE_NUM) {
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Wrong fw_type_num read from file, fw_type_num: 0x%x\n",
+ fw_image->fw_info.fw_section_cnt);
+ return false;
+ }
+
+ for (i = 0; i < fw_image->fw_info.fw_section_cnt; i++) {
+ len += fw_image->fw_section_info[i].fw_section_len;
+ memcpy(&host_image->image_section_info[i],
+ &fw_image->fw_section_info[i],
+ sizeof(struct fw_section_info_st));
+ }
+
+ if (len != fw_image->fw_len ||
+ (fw_image->fw_len + UPDATEFW_IMAGE_HEAD_SIZE) != image_size) {
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Wrong data size read from file\n");
+ return false;
+ }
+
+ host_image->image_info.up_total_len = fw_image->fw_len;
+ host_image->image_info.fw_version = fw_image->fw_version;
+ host_image->section_type_num = fw_image->fw_info.fw_section_cnt;
+ host_image->device_id = fw_image->device_id;
+
+ return true;
+}
+
+static bool check_image_integrity(struct hinic_devlink_priv *priv,
+ struct host_image_st *host_image,
+ u32 update_type)
+{
+ u32 collect_section_type = 0;
+ u32 i, type;
+
+ for (i = 0; i < host_image->section_type_num; i++) {
+ type = host_image->image_section_info[i].fw_section_type;
+ if (collect_section_type & (1U << type)) {
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Duplicate section type: %u\n",
+ type);
+ return false;
+ }
+ collect_section_type |= (1U << type);
+ }
+
+ if (update_type == FW_UPDATE_COLD &&
+ (((collect_section_type & _IMAGE_COLD_SUB_MODULES_MUST_IN) ==
+ _IMAGE_COLD_SUB_MODULES_MUST_IN) ||
+ collect_section_type == _IMAGE_CFG_SUB_MODULES_MUST_IN))
+ return true;
+
+ if (update_type == FW_UPDATE_HOT &&
+ (collect_section_type & _IMAGE_HOT_SUB_MODULES_MUST_IN) ==
+ _IMAGE_HOT_SUB_MODULES_MUST_IN)
+ return true;
+
+ if (update_type == FW_UPDATE_COLD)
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Check file integrity failed, valid: 0x%x or 0x%lx, current: 0x%x\n",
+ _IMAGE_COLD_SUB_MODULES_MUST_IN,
+ _IMAGE_CFG_SUB_MODULES_MUST_IN, collect_section_type);
+ else
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Check file integrity failed, valid:0x%x, current: 0x%x\n",
+ _IMAGE_HOT_SUB_MODULES_MUST_IN, collect_section_type);
+
+ return false;
+}
+
+static int check_image_device_type(struct hinic_devlink_priv *priv,
+ u32 image_device_type)
+{
+ struct hinic_comm_board_info board_info = {0};
+
+ if (hinic_get_board_info(priv->hwdev, &board_info)) {
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Get board info failed\n");
+ return false;
+ }
+
+ if (image_device_type == board_info.info.board_type)
+ return true;
+
+ dev_err(&priv->hwdev->hwif->pdev->dev, "The device type of upgrade file doesn't match the device type of current firmware, please check the upgrade file\n");
+ dev_err(&priv->hwdev->hwif->pdev->dev, "The image device type: 0x%x, firmware device type: 0x%x\n",
+ image_device_type, board_info.info.board_type);
+
+ return false;
+}
+
+static int hinic_flash_fw(struct hinic_devlink_priv *priv, const u8 *data,
+ struct host_image_st *host_image)
+{
+ u32 section_remain_send_len, send_fragment_len, send_pos, up_total_len;
+ struct hinic_cmd_update_fw *fw_update_msg = NULL;
+ u32 section_type, section_crc, section_version;
+ u32 i, len, section_len, section_offset;
+ u16 out_size = sizeof(*fw_update_msg);
+ int total_len_flag = 0;
+ int err;
+
+ fw_update_msg = kzalloc(sizeof(*fw_update_msg), GFP_KERNEL);
+ if (!fw_update_msg)
+ return -ENOMEM;
+
+ up_total_len = host_image->image_info.up_total_len;
+
+ for (i = 0; i < host_image->section_type_num; i++) {
+ len = host_image->image_section_info[i].fw_section_len;
+ if (host_image->image_section_info[i].fw_section_type ==
+ UP_FW_UPDATE_BOOT) {
+ up_total_len = up_total_len - len;
+ break;
+ }
+ }
+
+ for (i = 0; i < host_image->section_type_num; i++) {
+ section_len =
+ host_image->image_section_info[i].fw_section_len;
+ section_offset =
+ host_image->image_section_info[i].fw_section_offset;
+ section_remain_send_len = section_len;
+ section_type =
+ host_image->image_section_info[i].fw_section_type;
+ section_crc = host_image->image_section_info[i].fw_section_crc;
+ section_version =
+ host_image->image_section_info[i].fw_section_version;
+
+ if (section_type == UP_FW_UPDATE_BOOT)
+ continue;
+
+ send_fragment_len = 0;
+ send_pos = 0;
+
+ while (section_remain_send_len > 0) {
+ if (!total_len_flag) {
+ fw_update_msg->total_len = up_total_len;
+ total_len_flag = 1;
+ } else {
+ fw_update_msg->total_len = 0;
+ }
+
+ memset(fw_update_msg->data, 0, MAX_FW_FRAGMENT_LEN);
+
+ fw_update_msg->ctl_info.SF =
+ (section_remain_send_len == section_len) ?
+ true : false;
+ fw_update_msg->section_info.FW_section_CRC = section_crc;
+ fw_update_msg->fw_section_version = section_version;
+ fw_update_msg->ctl_info.flag = UP_TYPE_A;
+
+ if (section_type <= UP_FW_UPDATE_UP_DATA_B) {
+ fw_update_msg->section_info.FW_section_type =
+ (section_type % 2) ?
+ UP_FW_UPDATE_UP_DATA :
+ UP_FW_UPDATE_UP_TEXT;
+
+ fw_update_msg->ctl_info.flag = UP_TYPE_B;
+ if (section_type <= UP_FW_UPDATE_UP_DATA_A)
+ fw_update_msg->ctl_info.flag = UP_TYPE_A;
+ } else {
+ fw_update_msg->section_info.FW_section_type =
+ section_type - 0x2;
+ }
+
+ fw_update_msg->setion_total_len = section_len;
+ fw_update_msg->section_offset = send_pos;
+
+ if (section_remain_send_len <= MAX_FW_FRAGMENT_LEN) {
+ fw_update_msg->ctl_info.SL = true;
+ fw_update_msg->ctl_info.fragment_len =
+ section_remain_send_len;
+ send_fragment_len += section_remain_send_len;
+ } else {
+ fw_update_msg->ctl_info.SL = false;
+ fw_update_msg->ctl_info.fragment_len =
+ MAX_FW_FRAGMENT_LEN;
+ send_fragment_len += MAX_FW_FRAGMENT_LEN;
+ }
+
+ memcpy(fw_update_msg->data,
+ data + UPDATEFW_IMAGE_HEAD_SIZE +
+ section_offset + send_pos,
+ fw_update_msg->ctl_info.fragment_len);
+
+ err = hinic_port_msg_cmd(priv->hwdev,
+ HINIC_PORT_CMD_UPDATE_FW,
+ fw_update_msg,
+ sizeof(*fw_update_msg),
+ fw_update_msg, &out_size);
+ if (err || !out_size || fw_update_msg->status) {
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Failed to update firmware, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, fw_update_msg->status, out_size);
+ err = fw_update_msg->status ?
+ fw_update_msg->status : -EIO;
+ kfree(fw_update_msg);
+ return err;
+ }
+
+ send_pos = send_fragment_len;
+ section_remain_send_len = section_len -
+ send_fragment_len;
+ }
+ }
+
+ kfree(fw_update_msg);
+
+ return 0;
+}
+
+static int hinic_firmware_update(struct hinic_devlink_priv *priv,
+ const struct firmware *fw,
+ struct netlink_ext_ack *extack)
+{
+ struct host_image_st host_image;
+ int err;
+
+ memset(&host_image, 0, sizeof(struct host_image_st));
+
+ if (!check_image_valid(priv, fw->data, fw->size, &host_image) ||
+ !check_image_integrity(priv, &host_image, FW_UPDATE_COLD) ||
+ !check_image_device_type(priv, host_image.device_id)) {
+ NL_SET_ERR_MSG_MOD(extack, "Check image failed");
+ return -EINVAL;
+ }
+
+ dev_info(&priv->hwdev->hwif->pdev->dev, "Flash firmware begin\n");
+
+ err = hinic_flash_fw(priv, fw->data, &host_image);
+ if (err) {
+ if (err == HINIC_FW_DISMATCH_ERROR) {
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Firmware image doesn't match this card, please use newer image, err: %d\n",
+ err);
+ NL_SET_ERR_MSG_MOD(extack,
+ "Firmware image doesn't match this card, please use newer image");
+ } else {
+ dev_err(&priv->hwdev->hwif->pdev->dev, "Send firmware image data failed, err: %d\n",
+ err);
+ NL_SET_ERR_MSG_MOD(extack, "Send firmware image data failed");
+ }
+
+ return err;
+ }
+
+ dev_info(&priv->hwdev->hwif->pdev->dev, "Flash firmware end\n");
+
+ return 0;
+}
+
+static int hinic_devlink_flash_update(struct devlink *devlink,
+ const char *file_name,
+ const char *component,
+ struct netlink_ext_ack *extack)
+{
+ struct hinic_devlink_priv *priv = devlink_priv(devlink);
+ const struct firmware *fw;
+ int err;
+
+ if (component)
+ return -EOPNOTSUPP;
+
+ err = request_firmware_direct(&fw, file_name,
+ &priv->hwdev->hwif->pdev->dev);
+ if (err)
+ return err;
+
+ err = hinic_firmware_update(priv, fw, extack);
+ release_firmware(fw);
+
+ return err;
+}
+
+static const struct devlink_ops hinic_devlink_ops = {
+ .flash_update = hinic_devlink_flash_update,
+};
+
+struct devlink *hinic_devlink_alloc(void)
+{
+ return devlink_alloc(&hinic_devlink_ops, sizeof(struct hinic_dev));
+}
+
+void hinic_devlink_free(struct devlink *devlink)
+{
+ devlink_free(devlink);
+}
+
+int hinic_devlink_register(struct hinic_devlink_priv *priv, struct device *dev)
+{
+ struct devlink *devlink = priv_to_devlink(priv);
+
+ return devlink_register(devlink, dev);
+}
+
+void hinic_devlink_unregister(struct hinic_devlink_priv *priv)
+{
+ struct devlink *devlink = priv_to_devlink(priv);
+
+ devlink_unregister(devlink);
+}
+
+static int chip_fault_show(struct devlink_fmsg *fmsg,
+ struct hinic_fault_event *event)
+{
+ char fault_level[FAULT_TYPE_MAX][FAULT_SHOW_STR_LEN + 1] = {
+ "fatal", "reset", "flr", "general", "suggestion"};
+ char level_str[FAULT_SHOW_STR_LEN + 1] = {0};
+ u8 level;
+ int err;
+
+ level = event->event.chip.err_level;
+ if (level < FAULT_LEVEL_MAX)
+ strncpy(level_str, fault_level[level], strlen(fault_level[level]));
+ else
+ strncpy(level_str, "Unknown", strlen("Unknown"));
+
+ if (level == FAULT_LEVEL_SERIOUS_FLR) {
+ err = devlink_fmsg_u32_pair_put(fmsg, "Function level err func_id",
+ (u32)event->event.chip.func_id);
+ if (err)
+ return err;
+ }
+
+ err = devlink_fmsg_u8_pair_put(fmsg, "module_id", event->event.chip.node_id);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "err_type", (u32)event->event.chip.err_type);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_string_pair_put(fmsg, "err_level", level_str);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "err_csr_addr",
+ event->event.chip.err_csr_addr);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "err_csr_value",
+ event->event.chip.err_csr_value);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int fault_report_show(struct devlink_fmsg *fmsg,
+ struct hinic_fault_event *event)
+{
+ char fault_type[FAULT_TYPE_MAX][FAULT_SHOW_STR_LEN + 1] = {
+ "chip", "ucode", "mem rd timeout", "mem wr timeout",
+ "reg rd timeout", "reg wr timeout", "phy fault"};
+ char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
+ int err;
+
+ if (event->type < FAULT_TYPE_MAX)
+ strncpy(type_str, fault_type[event->type], strlen(fault_type[event->type]));
+ else
+ strncpy(type_str, "Unknown", strlen("Unknown"));
+
+ err = devlink_fmsg_string_pair_put(fmsg, "Fault type", type_str);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_binary_pair_put(fmsg, "Fault raw data",
+ event->event.val, sizeof(event->event.val));
+ if (err)
+ return err;
+
+ switch (event->type) {
+ case FAULT_TYPE_CHIP:
+ err = chip_fault_show(fmsg, event);
+ if (err)
+ return err;
+ break;
+ case FAULT_TYPE_UCODE:
+ err = devlink_fmsg_u8_pair_put(fmsg, "Cause_id", event->event.ucode.cause_id);
+ if (err)
+ return err;
+ err = devlink_fmsg_u8_pair_put(fmsg, "core_id", event->event.ucode.core_id);
+ if (err)
+ return err;
+ err = devlink_fmsg_u8_pair_put(fmsg, "c_id", event->event.ucode.c_id);
+ if (err)
+ return err;
+ err = devlink_fmsg_u8_pair_put(fmsg, "epc", event->event.ucode.epc);
+ if (err)
+ return err;
+ break;
+ case FAULT_TYPE_MEM_RD_TIMEOUT:
+ case FAULT_TYPE_MEM_WR_TIMEOUT:
+ err = devlink_fmsg_u32_pair_put(fmsg, "Err_csr_ctrl",
+ event->event.mem_timeout.err_csr_ctrl);
+ if (err)
+ return err;
+ err = devlink_fmsg_u32_pair_put(fmsg, "err_csr_data",
+ event->event.mem_timeout.err_csr_data);
+ if (err)
+ return err;
+ err = devlink_fmsg_u32_pair_put(fmsg, "ctrl_tab",
+ event->event.mem_timeout.ctrl_tab);
+ if (err)
+ return err;
+ err = devlink_fmsg_u32_pair_put(fmsg, "mem_index",
+ event->event.mem_timeout.mem_index);
+ if (err)
+ return err;
+ break;
+ case FAULT_TYPE_REG_RD_TIMEOUT:
+ case FAULT_TYPE_REG_WR_TIMEOUT:
+ err = devlink_fmsg_u32_pair_put(fmsg, "Err_csr", event->event.reg_timeout.err_csr);
+ if (err)
+ return err;
+ break;
+ case FAULT_TYPE_PHY_FAULT:
+ err = devlink_fmsg_u8_pair_put(fmsg, "Op_type", event->event.phy_fault.op_type);
+ if (err)
+ return err;
+ err = devlink_fmsg_u8_pair_put(fmsg, "port_id", event->event.phy_fault.port_id);
+ if (err)
+ return err;
+ err = devlink_fmsg_u8_pair_put(fmsg, "dev_ad", event->event.phy_fault.dev_ad);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "csr_addr", event->event.phy_fault.csr_addr);
+ if (err)
+ return err;
+ err = devlink_fmsg_u32_pair_put(fmsg, "op_data", event->event.phy_fault.op_data);
+ if (err)
+ return err;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int hinic_hw_reporter_dump(struct devlink_health_reporter *reporter,
+ struct devlink_fmsg *fmsg, void *priv_ctx,
+ struct netlink_ext_ack *extack)
+{
+ if (priv_ctx)
+ return fault_report_show(fmsg, priv_ctx);
+
+ return 0;
+}
+
+static int mgmt_watchdog_report_show(struct devlink_fmsg *fmsg,
+ struct hinic_mgmt_watchdog_info *watchdog_info)
+{
+ int err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "Mgmt deadloop time_h", watchdog_info->curr_time_h);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "time_l", watchdog_info->curr_time_l);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "task_id", watchdog_info->task_id);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "sp", watchdog_info->sp);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "stack_current_used", watchdog_info->curr_used);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "peak_used", watchdog_info->peak_used);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "\n Overflow_flag", watchdog_info->is_overflow);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "stack_top", watchdog_info->stack_top);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "stack_bottom", watchdog_info->stack_bottom);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "mgmt_pc", watchdog_info->pc);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "lr", watchdog_info->lr);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "cpsr", watchdog_info->cpsr);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_binary_pair_put(fmsg, "Mgmt register info",
+ watchdog_info->reg, sizeof(watchdog_info->reg));
+ if (err)
+ return err;
+
+ err = devlink_fmsg_binary_pair_put(fmsg, "Mgmt dump stack(start from sp)",
+ watchdog_info->data, sizeof(watchdog_info->data));
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int hinic_fw_reporter_dump(struct devlink_health_reporter *reporter,
+ struct devlink_fmsg *fmsg, void *priv_ctx,
+ struct netlink_ext_ack *extack)
+{
+ if (priv_ctx)
+ return mgmt_watchdog_report_show(fmsg, priv_ctx);
+
+ return 0;
+}
+
+static const struct devlink_health_reporter_ops hinic_hw_fault_reporter_ops = {
+ .name = "hw",
+ .dump = hinic_hw_reporter_dump,
+};
+
+static const struct devlink_health_reporter_ops hinic_fw_fault_reporter_ops = {
+ .name = "fw",
+ .dump = hinic_fw_reporter_dump,
+};
+
+int hinic_health_reporters_create(struct hinic_devlink_priv *priv)
+{
+ struct devlink *devlink = priv_to_devlink(priv);
+
+ priv->hw_fault_reporter =
+ devlink_health_reporter_create(devlink, &hinic_hw_fault_reporter_ops,
+ 0, priv);
+ if (IS_ERR(priv->hw_fault_reporter)) {
+ dev_warn(&priv->hwdev->hwif->pdev->dev, "Failed to create hw fault reporter, err: %ld\n",
+ PTR_ERR(priv->hw_fault_reporter));
+ return PTR_ERR(priv->hw_fault_reporter);
+ }
+
+ priv->fw_fault_reporter =
+ devlink_health_reporter_create(devlink, &hinic_fw_fault_reporter_ops,
+ 0, priv);
+ if (IS_ERR(priv->fw_fault_reporter)) {
+ dev_warn(&priv->hwdev->hwif->pdev->dev, "Failed to create fw fault reporter, err: %ld\n",
+ PTR_ERR(priv->fw_fault_reporter));
+ devlink_health_reporter_destroy(priv->hw_fault_reporter);
+ priv->hw_fault_reporter = NULL;
+ return PTR_ERR(priv->fw_fault_reporter);
+ }
+
+ return 0;
+}
+
+void hinic_health_reporters_destroy(struct hinic_devlink_priv *priv)
+{
+ if (!IS_ERR_OR_NULL(priv->fw_fault_reporter)) {
+ devlink_health_reporter_destroy(priv->fw_fault_reporter);
+ priv->fw_fault_reporter = NULL;
+ }
+
+ if (!IS_ERR_OR_NULL(priv->hw_fault_reporter)) {
+ devlink_health_reporter_destroy(priv->hw_fault_reporter);
+ priv->hw_fault_reporter = NULL;
+ }
+}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_devlink.h b/drivers/net/ethernet/huawei/hinic/hinic_devlink.h
new file mode 100644
index 000000000000..a090ebcfaabb
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic/hinic_devlink.h
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Huawei HiNIC PCI Express Linux driver
+ * Copyright(c) 2017 Huawei Technologies Co., Ltd
+ */
+
+#ifndef __HINIC_DEVLINK_H__
+#define __HINIC_DEVLINK_H__
+
+#include <net/devlink.h>
+#include "hinic_dev.h"
+
+#define MAX_FW_TYPE_NUM 30
+#define HINIC_MAGIC_NUM 0x18221100
+#define UPDATEFW_IMAGE_HEAD_SIZE 1024
+#define FW_UPDATE_COLD 0
+#define FW_UPDATE_HOT 1
+
+#define UP_TYPE_A 0x0
+#define UP_TYPE_B 0x1
+
+#define MAX_FW_FRAGMENT_LEN 1536
+#define HINIC_FW_DISMATCH_ERROR 10
+
+enum hinic_fw_type {
+ UP_FW_UPDATE_UP_TEXT_A = 0x0,
+ UP_FW_UPDATE_UP_DATA_A,
+ UP_FW_UPDATE_UP_TEXT_B,
+ UP_FW_UPDATE_UP_DATA_B,
+ UP_FW_UPDATE_UP_DICT,
+
+ UP_FW_UPDATE_HLINK_ONE = 0x5,
+ UP_FW_UPDATE_HLINK_TWO,
+ UP_FW_UPDATE_HLINK_THR,
+ UP_FW_UPDATE_PHY,
+ UP_FW_UPDATE_TILE_TEXT,
+
+ UP_FW_UPDATE_TILE_DATA = 0xa,
+ UP_FW_UPDATE_TILE_DICT,
+ UP_FW_UPDATE_PPE_STATE,
+ UP_FW_UPDATE_PPE_BRANCH,
+ UP_FW_UPDATE_PPE_EXTACT,
+
+ UP_FW_UPDATE_CLP_LEGACY = 0xf,
+ UP_FW_UPDATE_PXE_LEGACY,
+ UP_FW_UPDATE_ISCSI_LEGACY,
+ UP_FW_UPDATE_CLP_EFI,
+ UP_FW_UPDATE_PXE_EFI,
+
+ UP_FW_UPDATE_ISCSI_EFI = 0x14,
+ UP_FW_UPDATE_CFG,
+ UP_FW_UPDATE_BOOT,
+ UP_FW_UPDATE_VPD,
+ FILE_TYPE_TOTAL_NUM
+};
+
+#define _IMAGE_UP_ALL_IN ((1 << UP_FW_UPDATE_UP_TEXT_A) | \
+ (1 << UP_FW_UPDATE_UP_DATA_A) | \
+ (1 << UP_FW_UPDATE_UP_TEXT_B) | \
+ (1 << UP_FW_UPDATE_UP_DATA_B) | \
+ (1 << UP_FW_UPDATE_UP_DICT) | \
+ (1 << UP_FW_UPDATE_BOOT) | \
+ (1 << UP_FW_UPDATE_HLINK_ONE) | \
+ (1 << UP_FW_UPDATE_HLINK_TWO) | \
+ (1 << UP_FW_UPDATE_HLINK_THR))
+
+#define _IMAGE_UCODE_ALL_IN ((1 << UP_FW_UPDATE_TILE_TEXT) | \
+ (1 << UP_FW_UPDATE_TILE_DICT) | \
+ (1 << UP_FW_UPDATE_PPE_STATE) | \
+ (1 << UP_FW_UPDATE_PPE_BRANCH) | \
+ (1 << UP_FW_UPDATE_PPE_EXTACT))
+
+#define _IMAGE_COLD_SUB_MODULES_MUST_IN (_IMAGE_UP_ALL_IN | _IMAGE_UCODE_ALL_IN)
+#define _IMAGE_HOT_SUB_MODULES_MUST_IN (_IMAGE_UP_ALL_IN | _IMAGE_UCODE_ALL_IN)
+#define _IMAGE_CFG_SUB_MODULES_MUST_IN BIT(UP_FW_UPDATE_CFG)
+#define UP_FW_UPDATE_UP_TEXT 0x0
+#define UP_FW_UPDATE_UP_DATA 0x1
+#define UP_FW_UPDATE_VPD_B 0x15
+
+struct fw_section_info_st {
+ u32 fw_section_len;
+ u32 fw_section_offset;
+ u32 fw_section_version;
+ u32 fw_section_type;
+ u32 fw_section_crc;
+};
+
+struct fw_image_st {
+ u32 fw_version;
+ u32 fw_len;
+ u32 fw_magic;
+ struct {
+ u32 fw_section_cnt:16;
+ u32 resd:16;
+ } fw_info;
+ struct fw_section_info_st fw_section_info[MAX_FW_TYPE_NUM];
+ u32 device_id;
+ u32 res[101];
+ void *bin_data;
+};
+
+struct host_image_st {
+ struct fw_section_info_st image_section_info[MAX_FW_TYPE_NUM];
+ struct {
+ u32 up_total_len;
+ u32 fw_version;
+ } image_info;
+ u32 section_type_num;
+ u32 device_id;
+};
+
+struct devlink *hinic_devlink_alloc(void);
+void hinic_devlink_free(struct devlink *devlink);
+int hinic_devlink_register(struct hinic_devlink_priv *priv, struct device *dev);
+void hinic_devlink_unregister(struct hinic_devlink_priv *priv);
+
+int hinic_health_reporters_create(struct hinic_devlink_priv *priv);
+void hinic_health_reporters_destroy(struct hinic_devlink_priv *priv);
+
+#endif /* __HINIC_DEVLINK_H__ */
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c
index efb02e03e7da..6bb65ade1d77 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c
@@ -25,6 +25,7 @@
#include <linux/if_vlan.h>
#include <linux/ethtool.h>
#include <linux/vmalloc.h>
+#include <linux/sfp.h>
#include "hinic_hw_qp.h"
#include "hinic_hw_dev.h"
@@ -49,6 +50,13 @@
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
((ecmd)->advertising |= ADVERTISED_##mode)
+#define COALESCE_PENDING_LIMIT_UNIT 8
+#define COALESCE_TIMER_CFG_UNIT 9
+#define COALESCE_ALL_QUEUE 0xFFFF
+#define COALESCE_MAX_PENDING_LIMIT (255 * COALESCE_PENDING_LIMIT_UNIT)
+#define COALESCE_MAX_TIMER_CFG (255 * COALESCE_TIMER_CFG_UNIT)
+#define OBJ_STR_MAX_LEN 32
+
struct hw2ethtool_link_mode {
enum ethtool_link_mode_bit_indices link_mode_bit;
u32 speed;
@@ -126,6 +134,16 @@ static struct hw2ethtool_link_mode
},
};
+#define LP_DEFAULT_TIME 5 /* seconds */
+#define LP_PKT_LEN 1514
+
+#define PORT_DOWN_ERR_IDX 0
+enum diag_test_index {
+ INTERNAL_LP_TEST = 0,
+ EXTERNAL_LP_TEST = 1,
+ DIAG_TEST_MAX = 2,
+};
+
static void set_link_speed(struct ethtool_link_ksettings *link_ksettings,
enum hinic_speed speed)
{
@@ -613,6 +631,255 @@ static int hinic_set_ringparam(struct net_device *netdev,
return 0;
}
+
+static int __hinic_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic_intr_coal_info *rx_intr_coal_info;
+ struct hinic_intr_coal_info *tx_intr_coal_info;
+
+ if (queue == COALESCE_ALL_QUEUE) {
+ /* get tx/rx irq0 as default parameters */
+ rx_intr_coal_info = &nic_dev->rx_intr_coalesce[0];
+ tx_intr_coal_info = &nic_dev->tx_intr_coalesce[0];
+ } else {
+ if (queue >= nic_dev->num_qps) {
+ netif_err(nic_dev, drv, netdev,
+ "Invalid queue_id: %d\n", queue);
+ return -EINVAL;
+ }
+ rx_intr_coal_info = &nic_dev->rx_intr_coalesce[queue];
+ tx_intr_coal_info = &nic_dev->tx_intr_coalesce[queue];
+ }
+
+ /* coalesce_timer is in unit of 9us */
+ coal->rx_coalesce_usecs = rx_intr_coal_info->coalesce_timer_cfg *
+ COALESCE_TIMER_CFG_UNIT;
+ /* coalesced_frames is in unit of 8 */
+ coal->rx_max_coalesced_frames = rx_intr_coal_info->pending_limt *
+ COALESCE_PENDING_LIMIT_UNIT;
+ coal->tx_coalesce_usecs = tx_intr_coal_info->coalesce_timer_cfg *
+ COALESCE_TIMER_CFG_UNIT;
+ coal->tx_max_coalesced_frames = tx_intr_coal_info->pending_limt *
+ COALESCE_PENDING_LIMIT_UNIT;
+
+ return 0;
+}
+
+static int is_coalesce_exceed_limit(const struct ethtool_coalesce *coal)
+{
+ if (coal->rx_coalesce_usecs > COALESCE_MAX_TIMER_CFG ||
+ coal->rx_max_coalesced_frames > COALESCE_MAX_PENDING_LIMIT ||
+ coal->tx_coalesce_usecs > COALESCE_MAX_TIMER_CFG ||
+ coal->tx_max_coalesced_frames > COALESCE_MAX_PENDING_LIMIT)
+ return -ERANGE;
+
+ return 0;
+}
+
+static int set_queue_coalesce(struct hinic_dev *nic_dev, u16 q_id,
+ struct hinic_intr_coal_info *coal,
+ bool set_rx_coal)
+{
+ struct hinic_intr_coal_info *intr_coal = NULL;
+ struct hinic_msix_config interrupt_info = {0};
+ struct net_device *netdev = nic_dev->netdev;
+ u16 msix_idx;
+ int err;
+
+ intr_coal = set_rx_coal ? &nic_dev->rx_intr_coalesce[q_id] :
+ &nic_dev->tx_intr_coalesce[q_id];
+
+ intr_coal->coalesce_timer_cfg = coal->coalesce_timer_cfg;
+ intr_coal->pending_limt = coal->pending_limt;
+
+ /* netdev not running or qp not in using,
+ * don't need to set coalesce to hw
+ */
+ if (!(nic_dev->flags & HINIC_INTF_UP) ||
+ q_id >= nic_dev->num_qps)
+ return 0;
+
+ msix_idx = set_rx_coal ? nic_dev->rxqs[q_id].rq->msix_entry :
+ nic_dev->txqs[q_id].sq->msix_entry;
+ interrupt_info.msix_index = msix_idx;
+ interrupt_info.coalesce_timer_cnt = intr_coal->coalesce_timer_cfg;
+ interrupt_info.pending_cnt = intr_coal->pending_limt;
+ interrupt_info.resend_timer_cnt = intr_coal->resend_timer_cfg;
+
+ err = hinic_set_interrupt_cfg(nic_dev->hwdev, &interrupt_info);
+ if (err)
+ netif_warn(nic_dev, drv, netdev,
+ "Failed to set %s queue%d coalesce",
+ set_rx_coal ? "rx" : "tx", q_id);
+
+ return err;
+}
+
+static int __set_hw_coal_param(struct hinic_dev *nic_dev,
+ struct hinic_intr_coal_info *intr_coal,
+ u16 queue, bool set_rx_coal)
+{
+ int err;
+ u16 i;
+
+ if (queue == COALESCE_ALL_QUEUE) {
+ for (i = 0; i < nic_dev->max_qps; i++) {
+ err = set_queue_coalesce(nic_dev, i, intr_coal,
+ set_rx_coal);
+ if (err)
+ return err;
+ }
+ } else {
+ if (queue >= nic_dev->num_qps) {
+ netif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid queue_id: %d\n", queue);
+ return -EINVAL;
+ }
+ err = set_queue_coalesce(nic_dev, queue, intr_coal,
+ set_rx_coal);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int __hinic_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic_intr_coal_info rx_intr_coal = {0};
+ struct hinic_intr_coal_info tx_intr_coal = {0};
+ bool set_rx_coal = false;
+ bool set_tx_coal = false;
+ int err;
+
+ err = is_coalesce_exceed_limit(coal);
+ if (err)
+ return err;
+
+ if (coal->rx_coalesce_usecs || coal->rx_max_coalesced_frames) {
+ rx_intr_coal.coalesce_timer_cfg =
+ (u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
+ rx_intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ COALESCE_PENDING_LIMIT_UNIT);
+ set_rx_coal = true;
+ }
+
+ if (coal->tx_coalesce_usecs || coal->tx_max_coalesced_frames) {
+ tx_intr_coal.coalesce_timer_cfg =
+ (u8)(coal->tx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
+ tx_intr_coal.pending_limt = (u8)(coal->tx_max_coalesced_frames /
+ COALESCE_PENDING_LIMIT_UNIT);
+ set_tx_coal = true;
+ }
+
+ /* setting coalesce timer or pending limit to zero will disable
+ * coalesce
+ */
+ if (set_rx_coal && (!rx_intr_coal.coalesce_timer_cfg ||
+ !rx_intr_coal.pending_limt))
+ netif_warn(nic_dev, drv, netdev, "RX coalesce will be disabled\n");
+ if (set_tx_coal && (!tx_intr_coal.coalesce_timer_cfg ||
+ !tx_intr_coal.pending_limt))
+ netif_warn(nic_dev, drv, netdev, "TX coalesce will be disabled\n");
+
+ if (set_rx_coal) {
+ err = __set_hw_coal_param(nic_dev, &rx_intr_coal, queue, true);
+ if (err)
+ return err;
+ }
+ if (set_tx_coal) {
+ err = __set_hw_coal_param(nic_dev, &tx_intr_coal, queue, false);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int hinic_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+{
+ return __hinic_get_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
+}
+
+static int hinic_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+{
+ return __hinic_set_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
+}
+
+static int hinic_get_per_queue_coalesce(struct net_device *netdev, u32 queue,
+ struct ethtool_coalesce *coal)
+{
+ return __hinic_get_coalesce(netdev, coal, queue);
+}
+
+static int hinic_set_per_queue_coalesce(struct net_device *netdev, u32 queue,
+ struct ethtool_coalesce *coal)
+{
+ return __hinic_set_coalesce(netdev, coal, queue);
+}
+
+static void hinic_get_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic_pause_config pause_info = {0};
+ struct hinic_nic_cfg *nic_cfg;
+ int err;
+
+ nic_cfg = &nic_dev->hwdev->func_to_io.nic_cfg;
+
+ err = hinic_get_hw_pause_info(nic_dev->hwdev, &pause_info);
+ if (!err) {
+ pause->autoneg = pause_info.auto_neg;
+ if (nic_cfg->pause_set || !pause_info.auto_neg) {
+ pause->rx_pause = nic_cfg->rx_pause;
+ pause->tx_pause = nic_cfg->tx_pause;
+ } else {
+ pause->rx_pause = pause_info.rx_pause;
+ pause->tx_pause = pause_info.tx_pause;
+ }
+ }
+}
+
+static int hinic_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic_pause_config pause_info = {0};
+ struct hinic_port_cap port_cap = {0};
+ int err;
+
+ err = hinic_port_get_cap(nic_dev, &port_cap);
+ if (err)
+ return -EIO;
+
+ if (pause->autoneg != port_cap.autoneg_state)
+ return -EOPNOTSUPP;
+
+ pause_info.auto_neg = pause->autoneg;
+ pause_info.rx_pause = pause->rx_pause;
+ pause_info.tx_pause = pause->tx_pause;
+
+ mutex_lock(&nic_dev->hwdev->func_to_io.nic_cfg.cfg_mutex);
+ err = hinic_set_hw_pause_info(nic_dev->hwdev, &pause_info);
+ if (err) {
+ mutex_unlock(&nic_dev->hwdev->func_to_io.nic_cfg.cfg_mutex);
+ return err;
+ }
+ nic_dev->hwdev->func_to_io.nic_cfg.pause_set = true;
+ nic_dev->hwdev->func_to_io.nic_cfg.auto_neg = pause->autoneg;
+ nic_dev->hwdev->func_to_io.nic_cfg.rx_pause = pause->rx_pause;
+ nic_dev->hwdev->func_to_io.nic_cfg.tx_pause = pause->tx_pause;
+ mutex_unlock(&nic_dev->hwdev->func_to_io.nic_cfg.cfg_mutex);
+
+ return 0;
+}
+
static void hinic_get_channels(struct net_device *netdev,
struct ethtool_channels *channels)
{
@@ -970,6 +1237,11 @@ static struct hinic_stats hinic_function_stats[] = {
HINIC_FUNC_STAT(rx_err_vport),
};
+static char hinic_test_strings[][ETH_GSTRING_LEN] = {
+ "Internal lb test (on/offline)",
+ "External lb test (external_lb)",
+};
+
#define HINIC_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
.size = sizeof_field(struct hinic_phy_port_stats, _stat_item), \
@@ -1179,6 +1451,8 @@ static int hinic_get_sset_count(struct net_device *netdev, int sset)
int count, q_num;
switch (sset) {
+ case ETH_SS_TEST:
+ return ARRAY_LEN(hinic_test_strings);
case ETH_SS_STATS:
q_num = nic_dev->num_qps;
count = ARRAY_LEN(hinic_function_stats) +
@@ -1201,6 +1475,9 @@ static void hinic_get_strings(struct net_device *netdev,
u16 i, j;
switch (stringset) {
+ case ETH_SS_TEST:
+ memcpy(data, *hinic_test_strings, sizeof(hinic_test_strings));
+ return;
case ETH_SS_STATS:
for (i = 0; i < ARRAY_LEN(hinic_function_stats); i++) {
memcpy(p, hinic_function_stats[i].name,
@@ -1234,13 +1511,331 @@ static void hinic_get_strings(struct net_device *netdev,
}
}
+static int hinic_run_lp_test(struct hinic_dev *nic_dev, u32 test_time)
+{
+ u8 *lb_test_rx_buf = nic_dev->lb_test_rx_buf;
+ struct net_device *netdev = nic_dev->netdev;
+ struct sk_buff *skb_tmp = NULL;
+ struct sk_buff *skb = NULL;
+ u32 cnt = test_time * 5;
+ u8 *test_data = NULL;
+ u32 i;
+ u8 j;
+
+ skb_tmp = alloc_skb(LP_PKT_LEN, GFP_ATOMIC);
+ if (!skb_tmp)
+ return -ENOMEM;
+
+ test_data = __skb_put(skb_tmp, LP_PKT_LEN);
+
+ memset(test_data, 0xFF, 2 * ETH_ALEN);
+ test_data[ETH_ALEN] = 0xFE;
+ test_data[2 * ETH_ALEN] = 0x08;
+ test_data[2 * ETH_ALEN + 1] = 0x0;
+
+ for (i = ETH_HLEN; i < LP_PKT_LEN; i++)
+ test_data[i] = i & 0xFF;
+
+ skb_tmp->queue_mapping = 0;
+ skb_tmp->ip_summed = CHECKSUM_COMPLETE;
+ skb_tmp->dev = netdev;
+
+ for (i = 0; i < cnt; i++) {
+ nic_dev->lb_test_rx_idx = 0;
+ memset(lb_test_rx_buf, 0, LP_PKT_CNT * LP_PKT_LEN);
+
+ for (j = 0; j < LP_PKT_CNT; j++) {
+ skb = pskb_copy(skb_tmp, GFP_ATOMIC);
+ if (!skb) {
+ dev_kfree_skb_any(skb_tmp);
+ netif_err(nic_dev, drv, netdev,
+ "Copy skb failed for loopback test\n");
+ return -ENOMEM;
+ }
+
+ /* mark index for every pkt */
+ skb->data[LP_PKT_LEN - 1] = j;
+
+ if (hinic_lb_xmit_frame(skb, netdev)) {
+ dev_kfree_skb_any(skb);
+ dev_kfree_skb_any(skb_tmp);
+ netif_err(nic_dev, drv, netdev,
+ "Xmit pkt failed for loopback test\n");
+ return -EBUSY;
+ }
+ }
+
+ /* wait till all pkts received to RX buffer */
+ msleep(200);
+
+ for (j = 0; j < LP_PKT_CNT; j++) {
+ if (memcmp(lb_test_rx_buf + j * LP_PKT_LEN,
+ skb_tmp->data, LP_PKT_LEN - 1) ||
+ (*(lb_test_rx_buf + j * LP_PKT_LEN +
+ LP_PKT_LEN - 1) != j)) {
+ dev_kfree_skb_any(skb_tmp);
+ netif_err(nic_dev, drv, netdev,
+ "Compare pkt failed in loopback test(index=0x%02x, data[%d]=0x%02x)\n",
+ j + i * LP_PKT_CNT,
+ LP_PKT_LEN - 1,
+ *(lb_test_rx_buf + j * LP_PKT_LEN +
+ LP_PKT_LEN - 1));
+ return -EIO;
+ }
+ }
+ }
+
+ dev_kfree_skb_any(skb_tmp);
+ return 0;
+}
+
+static int do_lp_test(struct hinic_dev *nic_dev, u32 flags, u32 test_time,
+ enum diag_test_index *test_index)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u8 *lb_test_rx_buf = NULL;
+ int err = 0;
+
+ if (!(flags & ETH_TEST_FL_EXTERNAL_LB)) {
+ *test_index = INTERNAL_LP_TEST;
+ if (hinic_set_loopback_mode(nic_dev->hwdev,
+ HINIC_INTERNAL_LP_MODE, true)) {
+ netif_err(nic_dev, drv, netdev,
+ "Failed to set port loopback mode before loopback test\n");
+ return -EIO;
+ }
+ } else {
+ *test_index = EXTERNAL_LP_TEST;
+ }
+
+ lb_test_rx_buf = vmalloc(LP_PKT_CNT * LP_PKT_LEN);
+ if (!lb_test_rx_buf) {
+ err = -ENOMEM;
+ } else {
+ nic_dev->lb_test_rx_buf = lb_test_rx_buf;
+ nic_dev->lb_pkt_len = LP_PKT_LEN;
+ nic_dev->flags |= HINIC_LP_TEST;
+ err = hinic_run_lp_test(nic_dev, test_time);
+ nic_dev->flags &= ~HINIC_LP_TEST;
+ msleep(100);
+ vfree(lb_test_rx_buf);
+ nic_dev->lb_test_rx_buf = NULL;
+ }
+
+ if (!(flags & ETH_TEST_FL_EXTERNAL_LB)) {
+ if (hinic_set_loopback_mode(nic_dev->hwdev,
+ HINIC_INTERNAL_LP_MODE, false)) {
+ netif_err(nic_dev, drv, netdev,
+ "Failed to cancel port loopback mode after loopback test\n");
+ err = -EIO;
+ }
+ }
+
+ return err;
+}
+
+static void hinic_diag_test(struct net_device *netdev,
+ struct ethtool_test *eth_test, u64 *data)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+ enum hinic_port_link_state link_state;
+ enum diag_test_index test_index = 0;
+ int err = 0;
+
+ memset(data, 0, DIAG_TEST_MAX * sizeof(u64));
+
+ /* don't support loopback test when netdev is closed. */
+ if (!(nic_dev->flags & HINIC_INTF_UP)) {
+ netif_err(nic_dev, drv, netdev,
+ "Do not support loopback test when netdev is closed\n");
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+ data[PORT_DOWN_ERR_IDX] = 1;
+ return;
+ }
+
+ netif_carrier_off(netdev);
+
+ err = do_lp_test(nic_dev, eth_test->flags, LP_DEFAULT_TIME,
+ &test_index);
+ if (err) {
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+ data[test_index] = 1;
+ }
+
+ err = hinic_port_link_state(nic_dev, &link_state);
+ if (!err && link_state == HINIC_LINK_STATE_UP)
+ netif_carrier_on(netdev);
+}
+
+static int hinic_set_phys_id(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+ int err = 0;
+ u8 port;
+
+ port = nic_dev->hwdev->port_id;
+
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ err = hinic_set_led_status(nic_dev->hwdev, port,
+ HINIC_LED_TYPE_LINK,
+ HINIC_LED_MODE_FORCE_2HZ);
+ if (err)
+ netif_err(nic_dev, drv, netdev,
+ "Set LED blinking in 2HZ failed\n");
+ break;
+
+ case ETHTOOL_ID_INACTIVE:
+ err = hinic_reset_led_status(nic_dev->hwdev, port);
+ if (err)
+ netif_err(nic_dev, drv, netdev,
+ "Reset LED to original status failed\n");
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return err;
+}
+
+static int hinic_get_module_info(struct net_device *netdev,
+ struct ethtool_modinfo *modinfo)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+ u8 sfp_type_ext;
+ u8 sfp_type;
+ int err;
+
+ err = hinic_get_sfp_type(nic_dev->hwdev, &sfp_type, &sfp_type_ext);
+ if (err)
+ return err;
+
+ switch (sfp_type) {
+ case SFF8024_ID_SFP:
+ modinfo->type = ETH_MODULE_SFF_8472;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+ break;
+ case SFF8024_ID_QSFP_8438:
+ modinfo->type = ETH_MODULE_SFF_8436;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
+ break;
+ case SFF8024_ID_QSFP_8436_8636:
+ if (sfp_type_ext >= 0x3) {
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+
+ } else {
+ modinfo->type = ETH_MODULE_SFF_8436;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
+ }
+ break;
+ case SFF8024_ID_QSFP28_8636:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ default:
+ netif_warn(nic_dev, drv, netdev,
+ "Optical module unknown: 0x%x\n", sfp_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int hinic_get_module_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *ee, u8 *data)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+ u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
+ u16 len;
+ int err;
+
+ if (!ee->len || ((ee->len + ee->offset) > STD_SFP_INFO_MAX_SIZE))
+ return -EINVAL;
+
+ memset(data, 0, ee->len);
+
+ err = hinic_get_sfp_eeprom(nic_dev->hwdev, sfp_data, &len);
+ if (err)
+ return err;
+
+ memcpy(data, sfp_data + ee->offset, ee->len);
+
+ return 0;
+}
+
+static int
+hinic_get_link_ext_state(struct net_device *netdev,
+ struct ethtool_link_ext_state_info *link_ext_state_info)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+
+ if (netif_carrier_ok(netdev))
+ return -ENODATA;
+
+ if (nic_dev->cable_unplugged)
+ link_ext_state_info->link_ext_state =
+ ETHTOOL_LINK_EXT_STATE_NO_CABLE;
+ else if (nic_dev->module_unrecognized)
+ link_ext_state_info->link_ext_state =
+ ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH;
+
+ return 0;
+}
+
static const struct ethtool_ops hinic_ethtool_ops = {
+ .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
+ ETHTOOL_COALESCE_RX_MAX_FRAMES |
+ ETHTOOL_COALESCE_TX_USECS |
+ ETHTOOL_COALESCE_TX_MAX_FRAMES,
+
.get_link_ksettings = hinic_get_link_ksettings,
.set_link_ksettings = hinic_set_link_ksettings,
.get_drvinfo = hinic_get_drvinfo,
.get_link = ethtool_op_get_link,
+ .get_link_ext_state = hinic_get_link_ext_state,
+ .get_ringparam = hinic_get_ringparam,
+ .set_ringparam = hinic_set_ringparam,
+ .get_coalesce = hinic_get_coalesce,
+ .set_coalesce = hinic_set_coalesce,
+ .get_per_queue_coalesce = hinic_get_per_queue_coalesce,
+ .set_per_queue_coalesce = hinic_set_per_queue_coalesce,
+ .get_pauseparam = hinic_get_pauseparam,
+ .set_pauseparam = hinic_set_pauseparam,
+ .get_channels = hinic_get_channels,
+ .set_channels = hinic_set_channels,
+ .get_rxnfc = hinic_get_rxnfc,
+ .set_rxnfc = hinic_set_rxnfc,
+ .get_rxfh_key_size = hinic_get_rxfh_key_size,
+ .get_rxfh_indir_size = hinic_get_rxfh_indir_size,
+ .get_rxfh = hinic_get_rxfh,
+ .set_rxfh = hinic_set_rxfh,
+ .get_sset_count = hinic_get_sset_count,
+ .get_ethtool_stats = hinic_get_ethtool_stats,
+ .get_strings = hinic_get_strings,
+ .self_test = hinic_diag_test,
+ .set_phys_id = hinic_set_phys_id,
+ .get_module_info = hinic_get_module_info,
+ .get_module_eeprom = hinic_get_module_eeprom,
+};
+
+static const struct ethtool_ops hinicvf_ethtool_ops = {
+ .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
+ ETHTOOL_COALESCE_RX_MAX_FRAMES |
+ ETHTOOL_COALESCE_TX_USECS |
+ ETHTOOL_COALESCE_TX_MAX_FRAMES,
+
+ .get_link_ksettings = hinic_get_link_ksettings,
+ .get_drvinfo = hinic_get_drvinfo,
+ .get_link = ethtool_op_get_link,
.get_ringparam = hinic_get_ringparam,
.set_ringparam = hinic_set_ringparam,
+ .get_coalesce = hinic_get_coalesce,
+ .set_coalesce = hinic_set_coalesce,
+ .get_per_queue_coalesce = hinic_get_per_queue_coalesce,
+ .set_per_queue_coalesce = hinic_set_per_queue_coalesce,
.get_channels = hinic_get_channels,
.set_channels = hinic_set_channels,
.get_rxnfc = hinic_get_rxnfc,
@@ -1256,5 +1851,10 @@ static const struct ethtool_ops hinic_ethtool_ops = {
void hinic_set_ethtool_ops(struct net_device *netdev)
{
- netdev->ethtool_ops = &hinic_ethtool_ops;
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+
+ if (!HINIC_IS_VF(nic_dev->hwdev->hwif))
+ netdev->ethtool_ops = &hinic_ethtool_ops;
+ else
+ netdev->ethtool_ops = &hinicvf_ethtool_ops;
}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
index 583fd24c29cf..29e88e25a4a4 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
@@ -112,6 +112,26 @@ static u32 get_hw_cons_idx(struct hinic_api_cmd_chain *chain)
return HINIC_API_CMD_STATUS_GET(val, CONS_IDX);
}
+static void dump_api_chain_reg(struct hinic_api_cmd_chain *chain)
+{
+ u32 addr, val;
+
+ addr = HINIC_CSR_API_CMD_STATUS_ADDR(chain->chain_type);
+ val = hinic_hwif_read_reg(chain->hwif, addr);
+
+ dev_err(&chain->hwif->pdev->dev, "Chain type: 0x%x, cpld error: 0x%x, check error: 0x%x, current fsm: 0x%x\n",
+ chain->chain_type, HINIC_API_CMD_STATUS_GET(val, CPLD_ERR),
+ HINIC_API_CMD_STATUS_GET(val, CHKSUM_ERR),
+ HINIC_API_CMD_STATUS_GET(val, FSM));
+
+ dev_err(&chain->hwif->pdev->dev, "Chain hw current ci: 0x%x\n",
+ HINIC_API_CMD_STATUS_GET(val, CONS_IDX));
+
+ addr = HINIC_CSR_API_CMD_CHAIN_PI_ADDR(chain->chain_type);
+ val = hinic_hwif_read_reg(chain->hwif, addr);
+ dev_err(&chain->hwif->pdev->dev, "Chain hw current pi: 0x%x\n", val);
+}
+
/**
* chain_busy - check if the chain is still processing last requests
* @chain: chain to check
@@ -131,8 +151,10 @@ static int chain_busy(struct hinic_api_cmd_chain *chain)
/* check for a space for a new command */
if (chain->cons_idx == MASKED_IDX(chain, prod_idx + 1)) {
- dev_err(&pdev->dev, "API CMD chain %d is busy\n",
- chain->chain_type);
+ dev_err(&pdev->dev, "API CMD chain %d is busy, cons_idx: %d, prod_idx: %d\n",
+ chain->chain_type, chain->cons_idx,
+ chain->prod_idx);
+ dump_api_chain_reg(chain);
return -EBUSY;
}
break;
@@ -332,6 +354,7 @@ static int wait_for_api_cmd_completion(struct hinic_api_cmd_chain *chain)
err = wait_for_status_poll(chain);
if (err) {
dev_err(&pdev->dev, "API CMD Poll status timeout\n");
+ dump_api_chain_reg(chain);
break;
}
break;
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
index 0ba00fd828df..6d1654b050ad 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
@@ -103,10 +103,14 @@
HINIC_API_CMD_STATUS_HEADER_##member##_MASK)
#define HINIC_API_CMD_STATUS_CONS_IDX_SHIFT 0
+#define HINIC_API_CMD_STATUS_FSM_SHIFT 24
#define HINIC_API_CMD_STATUS_CHKSUM_ERR_SHIFT 28
+#define HINIC_API_CMD_STATUS_CPLD_ERR_SHIFT 30
#define HINIC_API_CMD_STATUS_CONS_IDX_MASK 0xFFFFFF
+#define HINIC_API_CMD_STATUS_FSM_MASK 0xFU
#define HINIC_API_CMD_STATUS_CHKSUM_ERR_MASK 0x3
+#define HINIC_API_CMD_STATUS_CPLD_ERR_MASK 0x1U
#define HINIC_API_CMD_STATUS_GET(val, member) \
(((val) >> HINIC_API_CMD_STATUS_##member##_SHIFT) & \
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
index cb5b6e5f787f..e0eb294779ec 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
@@ -401,6 +401,7 @@ static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq,
spin_unlock_bh(&cmdq->cmdq_lock);
+ hinic_dump_ceq_info(cmdq->hwdev);
return -ETIMEDOUT;
}
@@ -807,6 +808,7 @@ static int init_cmdqs_ctxt(struct hinic_hwdev *hwdev,
cmdq_type = HINIC_CMDQ_SYNC;
for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {
+ cmdqs->cmdq[cmdq_type].hwdev = hwdev;
err = init_cmdq(&cmdqs->cmdq[cmdq_type],
&cmdqs->saved_wqs[cmdq_type], cmdq_type,
db_area[cmdq_type]);
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
index 3e4b0aef9fe6..9c413e963a04 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
@@ -31,6 +31,10 @@
(((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
<< HINIC_CMDQ_CTXT_##member##_SHIFT)
+#define HINIC_CMDQ_CTXT_PAGE_INFO_GET(val, member) \
+ (((u64)(val) >> HINIC_CMDQ_CTXT_##member##_SHIFT) \
+ & HINIC_CMDQ_CTXT_##member##_MASK)
+
#define HINIC_CMDQ_CTXT_PAGE_INFO_CLEAR(val, member) \
((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
<< HINIC_CMDQ_CTXT_##member##_SHIFT)))
@@ -45,6 +49,10 @@
(((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
<< HINIC_CMDQ_CTXT_##member##_SHIFT)
+#define HINIC_CMDQ_CTXT_BLOCK_INFO_GET(val, member) \
+ (((u64)(val) >> HINIC_CMDQ_CTXT_##member##_SHIFT) \
+ & HINIC_CMDQ_CTXT_##member##_MASK)
+
#define HINIC_CMDQ_CTXT_BLOCK_INFO_CLEAR(val, member) \
((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
<< HINIC_CMDQ_CTXT_##member##_SHIFT)))
@@ -130,6 +138,8 @@ struct hinic_cmdq_ctxt {
};
struct hinic_cmdq {
+ struct hinic_hwdev *hwdev;
+
struct hinic_wq *wq;
enum hinic_cmdq_type cmdq_type;
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
index b735bc537508..0c737765d113 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
@@ -16,8 +16,11 @@
#include <linux/log2.h>
#include <linux/err.h>
#include <linux/netdevice.h>
+#include <net/devlink.h>
+#include "hinic_devlink.h"
#include "hinic_sriov.h"
+#include "hinic_dev.h"
#include "hinic_hw_if.h"
#include "hinic_hw_eqs.h"
#include "hinic_hw_mgmt.h"
@@ -83,6 +86,8 @@ static int parse_capability(struct hinic_hwdev *hwdev,
nic_cap->max_vf_qps = dev_cap->max_vf_sqs + 1;
}
+ hwdev->port_id = dev_cap->port_id;
+
return 0;
}
@@ -253,9 +258,9 @@ static int init_fw_ctxt(struct hinic_hwdev *hwdev)
&fw_ctxt, sizeof(fw_ctxt),
&fw_ctxt, &out_size);
if (err || (out_size != sizeof(fw_ctxt)) || fw_ctxt.status) {
- dev_err(&pdev->dev, "Failed to init FW ctxt, ret = %d\n",
- fw_ctxt.status);
- return -EFAULT;
+ dev_err(&pdev->dev, "Failed to init FW ctxt, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, fw_ctxt.status, out_size);
+ return -EIO;
}
return 0;
@@ -420,9 +425,9 @@ static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn)
&cmd_base_qpn, sizeof(cmd_base_qpn),
&cmd_base_qpn, &out_size);
if (err || (out_size != sizeof(cmd_base_qpn)) || cmd_base_qpn.status) {
- dev_err(&pdev->dev, "Failed to get base qpn, status = %d\n",
- cmd_base_qpn.status);
- return -EFAULT;
+ dev_err(&pdev->dev, "Failed to get base qpn, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, cmd_base_qpn.status, out_size);
+ return -EIO;
}
*base_qpn = cmd_base_qpn.qpn;
@@ -619,6 +624,113 @@ static void nic_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in,
nic_cb->cb_state &= ~HINIC_CB_RUNNING;
}
+static void hinic_comm_recv_mgmt_self_cmd_reg(struct hinic_pfhwdev *pfhwdev,
+ u8 cmd,
+ comm_mgmt_self_msg_proc proc)
+{
+ u8 cmd_idx;
+
+ cmd_idx = pfhwdev->proc.cmd_num;
+ if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) {
+ dev_err(&pfhwdev->hwdev.hwif->pdev->dev,
+ "Register recv mgmt process failed, cmd: 0x%x\n", cmd);
+ return;
+ }
+
+ pfhwdev->proc.info[cmd_idx].cmd = cmd;
+ pfhwdev->proc.info[cmd_idx].proc = proc;
+ pfhwdev->proc.cmd_num++;
+}
+
+static void hinic_comm_recv_mgmt_self_cmd_unreg(struct hinic_pfhwdev *pfhwdev,
+ u8 cmd)
+{
+ u8 cmd_idx;
+
+ cmd_idx = pfhwdev->proc.cmd_num;
+ if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) {
+ dev_err(&pfhwdev->hwdev.hwif->pdev->dev, "Unregister recv mgmt process failed, cmd: 0x%x\n",
+ cmd);
+ return;
+ }
+
+ for (cmd_idx = 0; cmd_idx < HINIC_COMM_SELF_CMD_MAX; cmd_idx++) {
+ if (cmd == pfhwdev->proc.info[cmd_idx].cmd) {
+ pfhwdev->proc.info[cmd_idx].cmd = 0;
+ pfhwdev->proc.info[cmd_idx].proc = NULL;
+ pfhwdev->proc.cmd_num--;
+ }
+ }
+}
+
+static void comm_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct hinic_pfhwdev *pfhwdev = handle;
+ u8 cmd_idx;
+
+ for (cmd_idx = 0; cmd_idx < pfhwdev->proc.cmd_num; cmd_idx++) {
+ if (cmd == pfhwdev->proc.info[cmd_idx].cmd) {
+ if (!pfhwdev->proc.info[cmd_idx].proc) {
+ dev_warn(&pfhwdev->hwdev.hwif->pdev->dev,
+ "PF recv mgmt comm msg handle null, cmd: 0x%x\n",
+ cmd);
+ } else {
+ pfhwdev->proc.info[cmd_idx].proc
+ (&pfhwdev->hwdev, buf_in, in_size,
+ buf_out, out_size);
+ }
+
+ return;
+ }
+ }
+
+ dev_warn(&pfhwdev->hwdev.hwif->pdev->dev, "Received unknown mgmt cpu event: 0x%x\n",
+ cmd);
+
+ *out_size = 0;
+}
+
+/* pf fault report event */
+static void pf_fault_event_handler(void *dev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct hinic_cmd_fault_event *fault_event = buf_in;
+ struct hinic_hwdev *hwdev = dev;
+
+ if (in_size != sizeof(*fault_event)) {
+ dev_err(&hwdev->hwif->pdev->dev, "Invalid fault event report, length: %d, should be %zu\n",
+ in_size, sizeof(*fault_event));
+ return;
+ }
+
+ if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->hw_fault_reporter))
+ return;
+
+ devlink_health_report(hwdev->devlink_dev->hw_fault_reporter,
+ "HW fatal error reported", &fault_event->event);
+}
+
+static void mgmt_watchdog_timeout_event_handler(void *dev,
+ void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct hinic_mgmt_watchdog_info *watchdog_info = buf_in;
+ struct hinic_hwdev *hwdev = dev;
+
+ if (in_size != sizeof(*watchdog_info)) {
+ dev_err(&hwdev->hwif->pdev->dev, "Invalid mgmt watchdog report, length: %d, should be %zu\n",
+ in_size, sizeof(*watchdog_info));
+ return;
+ }
+
+ if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->fw_fault_reporter))
+ return;
+
+ devlink_health_report(hwdev->devlink_dev->fw_fault_reporter,
+ "FW fatal error reported", watchdog_info);
+}
+
/**
* init_pfhwdev - Initialize the extended components of PF
* @pfhwdev: the HW device for PF
@@ -638,20 +750,37 @@ static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev)
return err;
}
+ err = hinic_devlink_register(hwdev->devlink_dev, &pdev->dev);
+ if (err) {
+ dev_err(&hwif->pdev->dev, "Failed to register devlink\n");
+ hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
+ return err;
+ }
+
err = hinic_func_to_func_init(hwdev);
if (err) {
dev_err(&hwif->pdev->dev, "Failed to init mailbox\n");
+ hinic_devlink_unregister(hwdev->devlink_dev);
hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
return err;
}
- if (!HINIC_IS_VF(hwif))
+ if (!HINIC_IS_VF(hwif)) {
hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt,
HINIC_MOD_L2NIC, pfhwdev,
nic_mgmt_msg_handler);
- else
+ hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
+ pfhwdev, comm_mgmt_msg_handler);
+ hinic_comm_recv_mgmt_self_cmd_reg(pfhwdev,
+ HINIC_COMM_CMD_FAULT_REPORT,
+ pf_fault_event_handler);
+ hinic_comm_recv_mgmt_self_cmd_reg
+ (pfhwdev, HINIC_COMM_CMD_WATCHDOG_INFO,
+ mgmt_watchdog_timeout_event_handler);
+ } else {
hinic_register_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC,
nic_mgmt_msg_handler);
+ }
hinic_set_pf_action(hwif, HINIC_PF_MGMT_ACTIVE);
@@ -668,14 +797,23 @@ static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev)
hinic_set_pf_action(hwdev->hwif, HINIC_PF_MGMT_INIT);
- if (!HINIC_IS_VF(hwdev->hwif))
+ if (!HINIC_IS_VF(hwdev->hwif)) {
+ hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev,
+ HINIC_COMM_CMD_WATCHDOG_INFO);
+ hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev,
+ HINIC_COMM_CMD_FAULT_REPORT);
+ hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt,
+ HINIC_MOD_COMM);
hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt,
HINIC_MOD_L2NIC);
- else
+ } else {
hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC);
+ }
hinic_func_to_func_free(hwdev);
+ hinic_devlink_unregister(hwdev->devlink_dev);
+
hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
}
@@ -705,6 +843,68 @@ static int hinic_l2nic_reset(struct hinic_hwdev *hwdev)
return 0;
}
+int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev,
+ struct hinic_msix_config *interrupt_info)
+{
+ u16 out_size = sizeof(*interrupt_info);
+ struct hinic_pfhwdev *pfhwdev;
+ int err;
+
+ if (!hwdev || !interrupt_info)
+ return -EINVAL;
+
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
+
+ interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
+
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
+ HINIC_COMM_CMD_MSI_CTRL_REG_RD_BY_UP,
+ interrupt_info, sizeof(*interrupt_info),
+ interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC);
+ if (err || !out_size || interrupt_info->status) {
+ dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, interrupt_info->status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,
+ struct hinic_msix_config *interrupt_info)
+{
+ u16 out_size = sizeof(*interrupt_info);
+ struct hinic_msix_config temp_info;
+ struct hinic_pfhwdev *pfhwdev;
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
+
+ interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
+
+ err = hinic_get_interrupt_cfg(hwdev, &temp_info);
+ if (err)
+ return -EINVAL;
+
+ interrupt_info->lli_credit_cnt = temp_info.lli_timer_cnt;
+ interrupt_info->lli_timer_cnt = temp_info.lli_timer_cnt;
+
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
+ HINIC_COMM_CMD_MSI_CTRL_REG_WR_BY_UP,
+ interrupt_info, sizeof(*interrupt_info),
+ interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC);
+ if (err || !out_size || interrupt_info->status) {
+ dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, interrupt_info->status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
/**
* hinic_init_hwdev - Initialize the NIC HW
* @pdev: the NIC pci device
@@ -713,7 +913,7 @@ static int hinic_l2nic_reset(struct hinic_hwdev *hwdev)
*
* Initialize the NIC HW device and return a pointer to it
**/
-struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev)
+struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev, struct devlink *devlink)
{
struct hinic_pfhwdev *pfhwdev;
struct hinic_hwdev *hwdev;
@@ -738,6 +938,8 @@ struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev)
hwdev = &pfhwdev->hwdev;
hwdev->hwif = hwif;
+ hwdev->devlink_dev = devlink_priv(devlink);
+ hwdev->devlink_dev->hwdev = hwdev;
err = init_msix(hwdev);
if (err) {
@@ -777,6 +979,8 @@ struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev)
goto err_dev_cap;
}
+ mutex_init(&hwdev->func_to_io.nic_cfg.cfg_mutex);
+
err = hinic_vf_func_init(hwdev);
if (err) {
dev_err(&pdev->dev, "Failed to init nic mbox\n");
@@ -831,6 +1035,8 @@ void hinic_free_hwdev(struct hinic_hwdev *hwdev)
set_resources_state(hwdev, HINIC_RES_CLEAN);
+ hinic_vf_func_free(hwdev);
+
free_pfhwdev(pfhwdev);
hinic_aeqs_free(&hwdev->aeqs);
@@ -981,3 +1187,29 @@ void hinic_hwdev_set_msix_state(struct hinic_hwdev *hwdev, u16 msix_index,
{
hinic_set_msix_state(hwdev->hwif, msix_index, flag);
}
+
+int hinic_get_board_info(struct hinic_hwdev *hwdev,
+ struct hinic_comm_board_info *board_info)
+{
+ u16 out_size = sizeof(*board_info);
+ struct hinic_pfhwdev *pfhwdev;
+ int err;
+
+ if (!hwdev || !board_info)
+ return -EINVAL;
+
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
+
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
+ HINIC_COMM_CMD_GET_BOARD_INFO,
+ board_info, sizeof(*board_info),
+ board_info, &out_size, HINIC_MGMT_MSG_SYNC);
+ if (err || board_info->status || !out_size) {
+ dev_err(&hwdev->hwif->pdev->dev,
+ "Failed to get board info, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, board_info->status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h
index 71ea7e46dbbc..dc6e645f2689 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h
@@ -10,6 +10,7 @@
#include <linux/pci.h>
#include <linux/types.h>
#include <linux/bitops.h>
+#include <net/devlink.h>
#include "hinic_hw_if.h"
#include "hinic_hw_eqs.h"
@@ -27,6 +28,8 @@
#define HINIC_MGMT_STATUS_EXIST 0x6
#define HINIC_MGMT_CMD_UNSUPPORTED 0xFF
+#define HINIC_CMD_VER_FUNC_ID 2
+
struct hinic_cap {
u16 max_qps;
u16 num_qps;
@@ -48,6 +51,8 @@ enum hinic_port_cmd {
HINIC_PORT_CMD_ADD_VLAN = 3,
HINIC_PORT_CMD_DEL_VLAN = 4,
+ HINIC_PORT_CMD_SET_PFC = 5,
+
HINIC_PORT_CMD_SET_MAC = 9,
HINIC_PORT_CMD_GET_MAC = 10,
HINIC_PORT_CMD_DEL_MAC = 11,
@@ -95,6 +100,9 @@ enum hinic_port_cmd {
HINIC_PORT_CMD_FWCTXT_INIT = 69,
+ HINIC_PORT_CMD_GET_LOOPBACK_MODE = 72,
+ HINIC_PORT_CMD_SET_LOOPBACK_MODE,
+
HINIC_PORT_CMD_ENABLE_SPOOFCHK = 78,
HINIC_PORT_CMD_GET_MGMT_VERSION = 88,
@@ -111,6 +119,8 @@ enum hinic_port_cmd {
HINIC_PORT_CMD_SET_TSO = 112,
+ HINIC_PORT_CMD_UPDATE_FW = 114,
+
HINIC_PORT_CMD_SET_RQ_IQ_MAP = 115,
HINIC_PORT_CMD_LINK_STATUS_REPORT = 160,
@@ -125,9 +135,13 @@ enum hinic_port_cmd {
HINIC_PORT_CMD_SET_AUTONEG = 219,
+ HINIC_PORT_CMD_GET_STD_SFP_INFO = 240,
+
HINIC_PORT_CMD_SET_LRO_TIMER = 244,
HINIC_PORT_CMD_SET_VF_MAX_MIN_RATE = 249,
+
+ HINIC_PORT_CMD_GET_SFP_ABS = 251,
};
/* cmd of mgmt CPU message for HILINK module */
@@ -153,9 +167,12 @@ enum hinic_ucode_cmd {
#define NIC_RSS_CMD_TEMP_FREE 0x02
enum hinic_mgmt_msg_cmd {
- HINIC_MGMT_MSG_CMD_BASE = 160,
+ HINIC_MGMT_MSG_CMD_BASE = 0xA0,
- HINIC_MGMT_MSG_CMD_LINK_STATUS = 160,
+ HINIC_MGMT_MSG_CMD_LINK_STATUS = 0xA0,
+
+ HINIC_MGMT_MSG_CMD_CABLE_PLUG_EVENT = 0xE5,
+ HINIC_MGMT_MSG_CMD_LINK_ERR_EVENT = 0xE6,
HINIC_MGMT_MSG_CMD_MAX,
};
@@ -283,6 +300,61 @@ struct hinic_cmd_l2nic_reset {
u16 reset_flag;
};
+struct hinic_msix_config {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u16 msix_index;
+ u8 pending_cnt;
+ u8 coalesce_timer_cnt;
+ u8 lli_timer_cnt;
+ u8 lli_credit_cnt;
+ u8 resend_timer_cnt;
+ u8 rsvd1[3];
+};
+
+struct hinic_set_random_id {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u8 vf_in_pf;
+ u8 rsvd1;
+ u16 func_idx;
+ u32 random_id;
+};
+
+struct hinic_board_info {
+ u32 board_type;
+ u32 port_num;
+ u32 port_speed;
+ u32 pcie_width;
+ u32 host_num;
+ u32 pf_num;
+ u32 vf_total_num;
+ u32 tile_num;
+ u32 qcm_num;
+ u32 core_num;
+ u32 work_mode;
+ u32 service_mode;
+ u32 pcie_mode;
+ u32 cfg_addr;
+ u32 boot_sel;
+ u32 board_id;
+};
+
+struct hinic_comm_board_info {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ struct hinic_board_info info;
+
+ u32 rsvd1[4];
+};
+
struct hinic_hwdev {
struct hinic_hwif *hwif;
struct msix_entry *msix_entries;
@@ -292,6 +364,8 @@ struct hinic_hwdev {
struct hinic_mbox_func_to_func *func_to_func;
struct hinic_cap nic_cap;
+ u8 port_id;
+ struct hinic_devlink_priv *devlink_dev;
};
struct hinic_nic_cb {
@@ -303,12 +377,29 @@ struct hinic_nic_cb {
unsigned long cb_state;
};
+#define HINIC_COMM_SELF_CMD_MAX 4
+
+typedef void (*comm_mgmt_self_msg_proc)(void *handle, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size);
+
+struct comm_mgmt_self_msg_sub_info {
+ u8 cmd;
+ comm_mgmt_self_msg_proc proc;
+};
+
+struct comm_mgmt_self_msg_info {
+ u8 cmd_num;
+ struct comm_mgmt_self_msg_sub_info info[HINIC_COMM_SELF_CMD_MAX];
+};
+
struct hinic_pfhwdev {
struct hinic_hwdev hwdev;
struct hinic_pf_to_mgmt pf_to_mgmt;
struct hinic_nic_cb nic_cb[HINIC_MGMT_NUM_MSG_CMD];
+
+ struct comm_mgmt_self_msg_info proc;
};
struct hinic_dev_cap {
@@ -330,6 +421,126 @@ struct hinic_dev_cap {
u8 rsvd3[204];
};
+union hinic_fault_hw_mgmt {
+ u32 val[4];
+ /* valid only type == FAULT_TYPE_CHIP */
+ struct {
+ u8 node_id;
+ u8 err_level;
+ u16 err_type;
+ u32 err_csr_addr;
+ u32 err_csr_value;
+ /* func_id valid only if err_level == FAULT_LEVEL_SERIOUS_FLR */
+ u16 func_id;
+ u16 rsvd2;
+ } chip;
+
+ /* valid only if type == FAULT_TYPE_UCODE */
+ struct {
+ u8 cause_id;
+ u8 core_id;
+ u8 c_id;
+ u8 rsvd3;
+ u32 epc;
+ u32 rsvd4;
+ u32 rsvd5;
+ } ucode;
+
+ /* valid only if type == FAULT_TYPE_MEM_RD_TIMEOUT ||
+ * FAULT_TYPE_MEM_WR_TIMEOUT
+ */
+ struct {
+ u32 err_csr_ctrl;
+ u32 err_csr_data;
+ u32 ctrl_tab;
+ u32 mem_index;
+ } mem_timeout;
+
+ /* valid only if type == FAULT_TYPE_REG_RD_TIMEOUT ||
+ * FAULT_TYPE_REG_WR_TIMEOUT
+ */
+ struct {
+ u32 err_csr;
+ u32 rsvd6;
+ u32 rsvd7;
+ u32 rsvd8;
+ } reg_timeout;
+
+ struct {
+ /* 0: read; 1: write */
+ u8 op_type;
+ u8 port_id;
+ u8 dev_ad;
+ u8 rsvd9;
+ u32 csr_addr;
+ u32 op_data;
+ u32 rsvd10;
+ } phy_fault;
+};
+
+struct hinic_fault_event {
+ u8 type;
+ u8 fault_level;
+ u8 rsvd0[2];
+ union hinic_fault_hw_mgmt event;
+};
+
+struct hinic_cmd_fault_event {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ struct hinic_fault_event event;
+};
+
+enum hinic_fault_type {
+ FAULT_TYPE_CHIP,
+ FAULT_TYPE_UCODE,
+ FAULT_TYPE_MEM_RD_TIMEOUT,
+ FAULT_TYPE_MEM_WR_TIMEOUT,
+ FAULT_TYPE_REG_RD_TIMEOUT,
+ FAULT_TYPE_REG_WR_TIMEOUT,
+ FAULT_TYPE_PHY_FAULT,
+ FAULT_TYPE_MAX,
+};
+
+#define FAULT_SHOW_STR_LEN 16
+
+enum hinic_fault_err_level {
+ FAULT_LEVEL_FATAL,
+ FAULT_LEVEL_SERIOUS_RESET,
+ FAULT_LEVEL_SERIOUS_FLR,
+ FAULT_LEVEL_GENERAL,
+ FAULT_LEVEL_SUGGESTION,
+ FAULT_LEVEL_MAX
+};
+
+struct hinic_mgmt_watchdog_info {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u32 curr_time_h;
+ u32 curr_time_l;
+ u32 task_id;
+ u32 rsv;
+
+ u32 reg[13];
+ u32 pc;
+ u32 lr;
+ u32 cpsr;
+
+ u32 stack_top;
+ u32 stack_bottom;
+ u32 sp;
+ u32 curr_used;
+ u32 peak_used;
+ u32 is_overflow;
+
+ u32 stack_actlen;
+ u8 data[1024];
+};
+
void hinic_hwdev_cb_register(struct hinic_hwdev *hwdev,
enum hinic_mgmt_msg_cmd cmd, void *handle,
void (*handler)(void *handle, void *buf_in,
@@ -351,7 +562,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth);
void hinic_hwdev_ifdown(struct hinic_hwdev *hwdev);
-struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev);
+struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev, struct devlink *devlink);
void hinic_free_hwdev(struct hinic_hwdev *hwdev);
@@ -376,4 +587,13 @@ int hinic_hwdev_hw_ci_addr_set(struct hinic_hwdev *hwdev, struct hinic_sq *sq,
void hinic_hwdev_set_msix_state(struct hinic_hwdev *hwdev, u16 msix_index,
enum hinic_msix_state flag);
+int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev,
+ struct hinic_msix_config *interrupt_info);
+
+int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,
+ struct hinic_msix_config *interrupt_info);
+
+int hinic_get_board_info(struct hinic_hwdev *hwdev,
+ struct hinic_comm_board_info *board_info);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c
index 397936cac304..ca8cb68a8d20 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c
@@ -953,3 +953,42 @@ void hinic_ceqs_free(struct hinic_ceqs *ceqs)
for (q_id = 0; q_id < ceqs->num_ceqs; q_id++)
remove_eq(&ceqs->ceq[q_id]);
}
+
+void hinic_dump_ceq_info(struct hinic_hwdev *hwdev)
+{
+ struct hinic_eq *eq = NULL;
+ u32 addr, ci, pi;
+ int q_id;
+
+ for (q_id = 0; q_id < hwdev->func_to_io.ceqs.num_ceqs; q_id++) {
+ eq = &hwdev->func_to_io.ceqs.ceq[q_id];
+ addr = EQ_CONS_IDX_REG_ADDR(eq);
+ ci = hinic_hwif_read_reg(hwdev->hwif, addr);
+ addr = EQ_PROD_IDX_REG_ADDR(eq);
+ pi = hinic_hwif_read_reg(hwdev->hwif, addr);
+ dev_err(&hwdev->hwif->pdev->dev, "Ceq id: %d, ci: 0x%08x, sw_ci: 0x%08x, pi: 0x%x, tasklet_state: 0x%lx, wrap: %d, ceqe: 0x%x\n",
+ q_id, ci, eq->cons_idx, pi,
+ eq->ceq_tasklet.state,
+ eq->wrapped, be32_to_cpu(*(__be32 *)(GET_CURR_CEQ_ELEM(eq))));
+ }
+}
+
+void hinic_dump_aeq_info(struct hinic_hwdev *hwdev)
+{
+ struct hinic_aeq_elem *aeqe_pos = NULL;
+ struct hinic_eq *eq = NULL;
+ u32 addr, ci, pi;
+ int q_id;
+
+ for (q_id = 0; q_id < hwdev->aeqs.num_aeqs; q_id++) {
+ eq = &hwdev->aeqs.aeq[q_id];
+ addr = EQ_CONS_IDX_REG_ADDR(eq);
+ ci = hinic_hwif_read_reg(hwdev->hwif, addr);
+ addr = EQ_PROD_IDX_REG_ADDR(eq);
+ pi = hinic_hwif_read_reg(hwdev->hwif, addr);
+ aeqe_pos = GET_CURR_AEQ_ELEM(eq);
+ dev_err(&hwdev->hwif->pdev->dev, "Aeq id: %d, ci: 0x%08x, pi: 0x%x, work_state: 0x%x, wrap: %d, desc: 0x%x\n",
+ q_id, ci, pi, work_busy(&eq->aeq_work.work),
+ eq->wrapped, be32_to_cpu(aeqe_pos->desc));
+ }
+}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h
index 74b9ff90640c..43065fc70869 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h
@@ -162,7 +162,7 @@ enum hinic_eqe_state {
struct hinic_aeq_elem {
u8 data[HINIC_AEQE_DATA_SIZE];
- u32 desc;
+ __be32 desc;
};
struct hinic_eq_work {
@@ -254,4 +254,8 @@ int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif,
void hinic_ceqs_free(struct hinic_ceqs *ceqs);
+void hinic_dump_ceq_info(struct hinic_hwdev *hwdev);
+
+void hinic_dump_aeq_info(struct hinic_hwdev *hwdev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
index cf127d896ba6..bc8925c0c982 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
@@ -21,6 +21,8 @@
#define WAIT_HWIF_READY_TIMEOUT 10000
+#define HINIC_SELFTEST_RESULT 0x883C
+
/**
* hinic_msix_attr_set - set message attribute for msix entry
* @hwif: the HW interface of a pci function device
@@ -369,6 +371,26 @@ u16 hinic_pf_id_of_vf_hw(struct hinic_hwif *hwif)
return HINIC_FA0_GET(attr0, PF_IDX);
}
+static void __print_selftest_reg(struct hinic_hwif *hwif)
+{
+ u32 addr, attr0, attr1;
+
+ addr = HINIC_CSR_FUNC_ATTR1_ADDR;
+ attr1 = hinic_hwif_read_reg(hwif, addr);
+
+ if (attr1 == HINIC_PCIE_LINK_DOWN) {
+ dev_err(&hwif->pdev->dev, "PCIE is link down\n");
+ return;
+ }
+
+ addr = HINIC_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic_hwif_read_reg(hwif, addr);
+ if (HINIC_FA0_GET(attr0, FUNC_TYPE) != HINIC_VF &&
+ !HINIC_FA0_GET(attr0, PCI_INTF_IDX))
+ dev_err(&hwif->pdev->dev, "Selftest reg: 0x%08x\n",
+ hinic_hwif_read_reg(hwif, HINIC_SELFTEST_RESULT));
+}
+
/**
* hinic_init_hwif - initialize the hw interface
* @hwif: the HW interface of a pci function device
@@ -398,6 +420,7 @@ int hinic_init_hwif(struct hinic_hwif *hwif, struct pci_dev *pdev)
err = wait_hwif_ready(hwif);
if (err) {
dev_err(&pdev->dev, "HW interface is not ready\n");
+ __print_selftest_reg(hwif);
goto err_hwif_ready;
}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
index 0872e035faa1..c06f2253151e 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
@@ -12,6 +12,8 @@
#include <linux/types.h>
#include <asm/byteorder.h>
+#define HINIC_PCIE_LINK_DOWN 0xFFFFFFFF
+
#define HINIC_DMA_ATTR_ST_SHIFT 0
#define HINIC_DMA_ATTR_AT_SHIFT 8
#define HINIC_DMA_ATTR_PH_SHIFT 10
@@ -249,13 +251,17 @@ struct hinic_hwif {
static inline u32 hinic_hwif_read_reg(struct hinic_hwif *hwif, u32 reg)
{
- return be32_to_cpu(readl(hwif->cfg_regs_bar + reg));
+ u32 out = readl(hwif->cfg_regs_bar + reg);
+
+ return be32_to_cpu(*(__be32 *)&out);
}
static inline void hinic_hwif_write_reg(struct hinic_hwif *hwif, u32 reg,
u32 val)
{
- writel(cpu_to_be32(val), hwif->cfg_regs_bar + reg);
+ __be32 in = cpu_to_be32(val);
+
+ writel(*(u32 *)&in, hwif->cfg_regs_bar + reg);
}
int hinic_msix_attr_set(struct hinic_hwif *hwif, u16 msix_index,
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_io.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_io.h
index 214f162f7579..ee6d60762d84 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_io.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_io.h
@@ -47,6 +47,15 @@ struct hinic_free_db_area {
struct semaphore idx_lock;
};
+struct hinic_nic_cfg {
+ /* lock for getting nic cfg */
+ struct mutex cfg_mutex;
+ bool pause_set;
+ u32 auto_neg;
+ u32 rx_pause;
+ u32 tx_pause;
+};
+
struct hinic_func_to_io {
struct hinic_hwif *hwif;
struct hinic_hwdev *hwdev;
@@ -78,6 +87,7 @@ struct hinic_func_to_io {
u16 max_vfs;
struct vf_data_storage *vf_infos;
u8 link_status;
+ struct hinic_nic_cfg nic_cfg;
};
struct hinic_wq_page_size {
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
index bc2f87e6cb5d..5078c0c73863 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
@@ -153,7 +153,6 @@ enum hinic_mbox_tx_status {
(MBOX_MSG_ID(func_to_func_mbox) + 1) & MBOX_MSG_ID_MASK)
#define FUNC_ID_OFF_SET_8B 8
-#define FUNC_ID_OFF_SET_10B 10
/* max message counter wait to process for one function */
#define HINIC_MAX_MSG_CNT_TO_PROCESS 10
@@ -189,6 +188,37 @@ enum mbox_aeq_trig_type {
TRIGGER,
};
+static bool check_func_id(struct hinic_hwdev *hwdev, u16 src_func_idx,
+ const void *buf_in, u16 in_size, u16 offset)
+{
+ u16 func_idx;
+
+ if (in_size < offset + sizeof(func_idx)) {
+ dev_warn(&hwdev->hwif->pdev->dev,
+ "Receive mailbox msg len: %d less than %d Bytes is invalid\n",
+ in_size, offset);
+ return false;
+ }
+
+ func_idx = *((u16 *)((u8 *)buf_in + offset));
+
+ if (src_func_idx != func_idx) {
+ dev_warn(&hwdev->hwif->pdev->dev,
+ "Receive mailbox function id: 0x%x not equal to msg function id: 0x%x\n",
+ src_func_idx, func_idx);
+ return false;
+ }
+
+ return true;
+}
+
+bool hinic_mbox_check_func_id_8B(struct hinic_hwdev *hwdev, u16 func_idx,
+ void *buf_in, u16 in_size)
+{
+ return check_func_id(hwdev, func_idx, buf_in, in_size,
+ FUNC_ID_OFF_SET_8B);
+}
+
/**
* hinic_register_pf_mbox_cb - register mbox callback for pf
* @hwdev: the pointer to hw device
@@ -486,6 +516,111 @@ err_alloc_rcv_mbox_msg:
kfree(rcv_mbox_temp);
}
+static int set_vf_mbox_random_id(struct hinic_hwdev *hwdev, u16 func_id)
+{
+ struct hinic_mbox_func_to_func *func_to_func = hwdev->func_to_func;
+ struct hinic_set_random_id rand_info = {0};
+ u16 out_size = sizeof(rand_info);
+ struct hinic_pfhwdev *pfhwdev;
+ int ret;
+
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
+
+ rand_info.version = HINIC_CMD_VER_FUNC_ID;
+ rand_info.func_idx = func_id;
+ rand_info.vf_in_pf = func_id - hinic_glb_pf_vf_offset(hwdev->hwif);
+ rand_info.random_id = get_random_u32();
+
+ func_to_func->vf_mbx_rand_id[func_id] = rand_info.random_id;
+
+ ret = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
+ HINIC_MGMT_CMD_SET_VF_RANDOM_ID,
+ &rand_info, sizeof(rand_info),
+ &rand_info, &out_size, HINIC_MGMT_MSG_SYNC);
+ if ((rand_info.status != HINIC_MGMT_CMD_UNSUPPORTED &&
+ rand_info.status) || !out_size || ret) {
+ dev_err(&hwdev->hwif->pdev->dev, "Set VF random id failed, err: %d, status: 0x%x, out size: 0x%x\n",
+ ret, rand_info.status, out_size);
+ return -EIO;
+ }
+
+ if (rand_info.status == HINIC_MGMT_CMD_UNSUPPORTED)
+ return rand_info.status;
+
+ func_to_func->vf_mbx_old_rand_id[func_id] =
+ func_to_func->vf_mbx_rand_id[func_id];
+
+ return 0;
+}
+
+static void update_random_id_work_handler(struct work_struct *work)
+{
+ struct hinic_mbox_work *mbox_work =
+ container_of(work, struct hinic_mbox_work, work);
+ struct hinic_mbox_func_to_func *func_to_func;
+ u16 src = mbox_work->src_func_idx;
+
+ func_to_func = mbox_work->func_to_func;
+
+ if (set_vf_mbox_random_id(func_to_func->hwdev, src))
+ dev_warn(&func_to_func->hwdev->hwif->pdev->dev, "Update VF id: 0x%x random id failed\n",
+ mbox_work->src_func_idx);
+
+ kfree(mbox_work);
+}
+
+static bool check_vf_mbox_random_id(struct hinic_mbox_func_to_func *func_to_func,
+ u8 *header)
+{
+ struct hinic_hwdev *hwdev = func_to_func->hwdev;
+ struct hinic_mbox_work *mbox_work = NULL;
+ u64 mbox_header = *((u64 *)header);
+ u16 offset, src;
+ u32 random_id;
+ int vf_in_pf;
+
+ src = HINIC_MBOX_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);
+
+ if (IS_PF_OR_PPF_SRC(src) || !func_to_func->support_vf_random)
+ return true;
+
+ if (!HINIC_IS_PPF(hwdev->hwif)) {
+ offset = hinic_glb_pf_vf_offset(hwdev->hwif);
+ vf_in_pf = src - offset;
+
+ if (vf_in_pf < 1 || vf_in_pf > hwdev->nic_cap.max_vf) {
+ dev_warn(&hwdev->hwif->pdev->dev,
+ "Receive vf id(0x%x) is invalid, vf id should be from 0x%x to 0x%x\n",
+ src, offset + 1,
+ hwdev->nic_cap.max_vf + offset);
+ return false;
+ }
+ }
+
+ random_id = be32_to_cpu(*(u32 *)(header + MBOX_SEG_LEN +
+ MBOX_HEADER_SZ));
+
+ if (random_id == func_to_func->vf_mbx_rand_id[src] ||
+ random_id == func_to_func->vf_mbx_old_rand_id[src])
+ return true;
+
+ dev_warn(&hwdev->hwif->pdev->dev,
+ "The mailbox random id(0x%x) of func_id(0x%x) doesn't match with pf reservation(0x%x)\n",
+ random_id, src, func_to_func->vf_mbx_rand_id[src]);
+
+ mbox_work = kzalloc(sizeof(*mbox_work), GFP_KERNEL);
+ if (!mbox_work)
+ return false;
+
+ mbox_work->func_to_func = func_to_func;
+ mbox_work->src_func_idx = src;
+
+ INIT_WORK(&mbox_work->work, update_random_id_work_handler);
+ queue_work(func_to_func->workq, &mbox_work->work);
+
+ return false;
+}
+
void hinic_mbox_func_aeqe_handler(void *handle, void *header, u8 size)
{
struct hinic_mbox_func_to_func *func_to_func;
@@ -504,6 +639,9 @@ void hinic_mbox_func_aeqe_handler(void *handle, void *header, u8 size)
return;
}
+ if (!check_vf_mbox_random_id(func_to_func, header))
+ return;
+
recv_mbox = (dir == HINIC_HWIF_DIRECT_SEND) ?
&func_to_func->mbox_send[src] :
&func_to_func->mbox_resp[src];
@@ -650,6 +788,7 @@ wait_for_mbox_seg_completion(struct hinic_mbox_func_to_func *func_to_func,
if (!wait_for_completion_timeout(done, jif)) {
dev_err(&hwdev->hwif->pdev->dev, "Send mailbox segment timeout\n");
dump_mox_reg(hwdev);
+ hinic_dump_aeq_info(hwdev);
return -ETIMEDOUT;
}
@@ -897,6 +1036,7 @@ int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);
dev_err(&func_to_func->hwif->pdev->dev,
"Send mbox msg timeout, msg_id: %d\n", msg_info.msg_id);
+ hinic_dump_aeq_info(func_to_func->hwdev);
err = -ETIMEDOUT;
goto err_send_mbox;
}
@@ -1095,15 +1235,156 @@ static void free_mbox_wb_status(struct hinic_mbox_func_to_func *func_to_func)
send_mbox->wb_paddr);
}
+bool hinic_mbox_check_cmd_valid(struct hinic_hwdev *hwdev,
+ struct vf_cmd_check_handle *cmd_handle,
+ u16 vf_id, u8 cmd, void *buf_in,
+ u16 in_size, u8 size)
+{
+ u16 src_idx = vf_id + hinic_glb_pf_vf_offset(hwdev->hwif);
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (cmd == cmd_handle[i].cmd) {
+ if (cmd_handle[i].check_cmd)
+ return cmd_handle[i].check_cmd(hwdev, src_idx,
+ buf_in, in_size);
+ else
+ return true;
+ }
+ }
+
+ dev_err(&hwdev->hwif->pdev->dev,
+ "PF Receive VF(%d) unsupported cmd(0x%x)\n",
+ vf_id + hinic_glb_pf_vf_offset(hwdev->hwif), cmd);
+
+ return false;
+}
+
+static bool hinic_cmdq_check_vf_ctxt(struct hinic_hwdev *hwdev,
+ struct hinic_cmdq_ctxt *cmdq_ctxt)
+{
+ struct hinic_cmdq_ctxt_info *ctxt_info = &cmdq_ctxt->ctxt_info;
+ u64 curr_pg_pfn, wq_block_pfn;
+
+ if (cmdq_ctxt->ppf_idx != HINIC_HWIF_PPF_IDX(hwdev->hwif) ||
+ cmdq_ctxt->cmdq_type > HINIC_MAX_CMDQ_TYPES)
+ return false;
+
+ curr_pg_pfn = HINIC_CMDQ_CTXT_PAGE_INFO_GET
+ (ctxt_info->curr_wqe_page_pfn, CURR_WQE_PAGE_PFN);
+ wq_block_pfn = HINIC_CMDQ_CTXT_BLOCK_INFO_GET
+ (ctxt_info->wq_block_pfn, WQ_BLOCK_PFN);
+ /* VF must use 0-level CLA */
+ if (curr_pg_pfn != wq_block_pfn)
+ return false;
+
+ return true;
+}
+
+static bool check_cmdq_ctxt(struct hinic_hwdev *hwdev, u16 func_idx,
+ void *buf_in, u16 in_size)
+{
+ if (!hinic_mbox_check_func_id_8B(hwdev, func_idx, buf_in, in_size))
+ return false;
+
+ return hinic_cmdq_check_vf_ctxt(hwdev, buf_in);
+}
+
+#define HW_CTX_QPS_VALID(hw_ctxt) \
+ ((hw_ctxt)->rq_depth >= HINIC_QUEUE_MIN_DEPTH && \
+ (hw_ctxt)->rq_depth <= HINIC_QUEUE_MAX_DEPTH && \
+ (hw_ctxt)->sq_depth >= HINIC_QUEUE_MIN_DEPTH && \
+ (hw_ctxt)->sq_depth <= HINIC_QUEUE_MAX_DEPTH && \
+ (hw_ctxt)->rx_buf_sz_idx <= HINIC_MAX_RX_BUFFER_SIZE)
+
+static bool hw_ctxt_qps_param_valid(struct hinic_cmd_hw_ioctxt *hw_ctxt)
+{
+ if (HW_CTX_QPS_VALID(hw_ctxt))
+ return true;
+
+ if (!hw_ctxt->rq_depth && !hw_ctxt->sq_depth &&
+ !hw_ctxt->rx_buf_sz_idx)
+ return true;
+
+ return false;
+}
+
+static bool check_hwctxt(struct hinic_hwdev *hwdev, u16 func_idx,
+ void *buf_in, u16 in_size)
+{
+ struct hinic_cmd_hw_ioctxt *hw_ctxt = buf_in;
+
+ if (!hinic_mbox_check_func_id_8B(hwdev, func_idx, buf_in, in_size))
+ return false;
+
+ if (hw_ctxt->ppf_idx != HINIC_HWIF_PPF_IDX(hwdev->hwif))
+ return false;
+
+ if (hw_ctxt->set_cmdq_depth) {
+ if (hw_ctxt->cmdq_depth >= HINIC_QUEUE_MIN_DEPTH &&
+ hw_ctxt->cmdq_depth <= HINIC_QUEUE_MAX_DEPTH)
+ return true;
+
+ return false;
+ }
+
+ return hw_ctxt_qps_param_valid(hw_ctxt);
+}
+
+static bool check_set_wq_page_size(struct hinic_hwdev *hwdev, u16 func_idx,
+ void *buf_in, u16 in_size)
+{
+ struct hinic_wq_page_size *page_size_info = buf_in;
+
+ if (!hinic_mbox_check_func_id_8B(hwdev, func_idx, buf_in, in_size))
+ return false;
+
+ if (page_size_info->ppf_idx != HINIC_HWIF_PPF_IDX(hwdev->hwif))
+ return false;
+
+ if (((1U << page_size_info->page_size) * SZ_4K) !=
+ HINIC_DEFAULT_WQ_PAGE_SIZE)
+ return false;
+
+ return true;
+}
+
+static struct vf_cmd_check_handle hw_cmd_support_vf[] = {
+ {HINIC_COMM_CMD_START_FLR, hinic_mbox_check_func_id_8B},
+ {HINIC_COMM_CMD_DMA_ATTR_SET, hinic_mbox_check_func_id_8B},
+ {HINIC_COMM_CMD_CMDQ_CTXT_SET, check_cmdq_ctxt},
+ {HINIC_COMM_CMD_CMDQ_CTXT_GET, check_cmdq_ctxt},
+ {HINIC_COMM_CMD_HWCTXT_SET, check_hwctxt},
+ {HINIC_COMM_CMD_HWCTXT_GET, check_hwctxt},
+ {HINIC_COMM_CMD_SQ_HI_CI_SET, hinic_mbox_check_func_id_8B},
+ {HINIC_COMM_CMD_RES_STATE_SET, hinic_mbox_check_func_id_8B},
+ {HINIC_COMM_CMD_IO_RES_CLEAR, hinic_mbox_check_func_id_8B},
+ {HINIC_COMM_CMD_CEQ_CTRL_REG_WR_BY_UP, hinic_mbox_check_func_id_8B},
+ {HINIC_COMM_CMD_MSI_CTRL_REG_WR_BY_UP, hinic_mbox_check_func_id_8B},
+ {HINIC_COMM_CMD_MSI_CTRL_REG_RD_BY_UP, hinic_mbox_check_func_id_8B},
+ {HINIC_COMM_CMD_L2NIC_RESET, hinic_mbox_check_func_id_8B},
+ {HINIC_COMM_CMD_PAGESIZE_SET, check_set_wq_page_size},
+};
+
static int comm_pf_mbox_handler(void *handle, u16 vf_id, u8 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size)
{
+ u8 size = ARRAY_SIZE(hw_cmd_support_vf);
struct hinic_hwdev *hwdev = handle;
struct hinic_pfhwdev *pfhwdev;
int err = 0;
pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
+ if (!hinic_mbox_check_cmd_valid(handle, hw_cmd_support_vf, vf_id, cmd,
+ buf_in, in_size, size)) {
+ dev_err(&hwdev->hwif->pdev->dev,
+ "PF Receive VF: %d common cmd: 0x%x or mbox len: 0x%x is invalid\n",
+ vf_id + hinic_glb_pf_vf_offset(hwdev->hwif), cmd,
+ in_size);
+ return HINIC_MBOX_VF_CMD_ERROR;
+ }
+
if (cmd == HINIC_COMM_CMD_START_FLR) {
*out_size = 0;
} else {
@@ -1208,3 +1489,32 @@ void hinic_func_to_func_free(struct hinic_hwdev *hwdev)
kfree(func_to_func);
}
+
+int hinic_vf_mbox_random_id_init(struct hinic_hwdev *hwdev)
+{
+ u16 vf_offset;
+ u8 vf_in_pf;
+ int err = 0;
+
+ if (HINIC_IS_VF(hwdev->hwif))
+ return 0;
+
+ vf_offset = hinic_glb_pf_vf_offset(hwdev->hwif);
+
+ for (vf_in_pf = 1; vf_in_pf <= hwdev->nic_cap.max_vf; vf_in_pf++) {
+ err = set_vf_mbox_random_id(hwdev, vf_offset + vf_in_pf);
+ if (err)
+ break;
+ }
+
+ if (err == HINIC_MGMT_CMD_UNSUPPORTED) {
+ hwdev->func_to_func->support_vf_random = false;
+ err = 0;
+ dev_warn(&hwdev->hwif->pdev->dev, "Mgmt is unsupported to set VF%d random id\n",
+ vf_in_pf - 1);
+ } else if (!err) {
+ hwdev->func_to_func->support_vf_random = true;
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.h
index 7b18559bfe80..46953190d29e 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.h
@@ -22,6 +22,14 @@
#define HINIC_FUNC_CSR_MAILBOX_RESULT_H_OFF 0x0108
#define HINIC_FUNC_CSR_MAILBOX_RESULT_L_OFF 0x010C
+#define MAX_FUNCTION_NUM 512
+
+struct vf_cmd_check_handle {
+ u8 cmd;
+ bool (*check_cmd)(struct hinic_hwdev *hwdev, u16 src_func_idx,
+ void *buf_in, u16 in_size);
+};
+
enum hinic_mbox_ack_type {
MBOX_ACK,
MBOX_NO_ACK,
@@ -100,6 +108,10 @@ struct hinic_mbox_func_to_func {
/* lock for mbox event flag */
spinlock_t mbox_lock;
+
+ u32 vf_mbx_old_rand_id[MAX_FUNCTION_NUM];
+ u32 vf_mbx_rand_id[MAX_FUNCTION_NUM];
+ bool support_vf_random;
};
struct hinic_mbox_work {
@@ -116,6 +128,14 @@ struct vf_cmd_msg_handle {
void *buf_out, u16 *out_size);
};
+bool hinic_mbox_check_func_id_8B(struct hinic_hwdev *hwdev, u16 func_idx,
+ void *buf_in, u16 in_size);
+
+bool hinic_mbox_check_cmd_valid(struct hinic_hwdev *hwdev,
+ struct vf_cmd_check_handle *cmd_handle,
+ u16 vf_id, u8 cmd, void *buf_in,
+ u16 in_size, u8 size);
+
int hinic_register_pf_mbox_cb(struct hinic_hwdev *hwdev,
enum hinic_mod_type mod,
hinic_pf_mbox_cb callback);
@@ -151,4 +171,6 @@ int hinic_mbox_to_vf(struct hinic_hwdev *hwdev,
enum hinic_mod_type mod, u16 vf_id, u8 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size, u32 timeout);
+int hinic_vf_mbox_random_id_init(struct hinic_hwdev *hwdev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c
index e0f5a81d8620..c6ce5966284c 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c
@@ -12,8 +12,10 @@
#include <linux/semaphore.h>
#include <linux/completion.h>
#include <linux/slab.h>
+#include <net/devlink.h>
#include <asm/barrier.h>
+#include "hinic_devlink.h"
#include "hinic_hw_if.h"
#include "hinic_hw_eqs.h"
#include "hinic_hw_api_cmd.h"
@@ -274,6 +276,7 @@ static int msg_to_mgmt_sync(struct hinic_pf_to_mgmt *pf_to_mgmt,
if (!wait_for_completion_timeout(recv_done, timeo)) {
dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id);
+ hinic_dump_aeq_info(pf_to_mgmt->hwdev);
err = -ETIMEDOUT;
goto unlock_sync_msg;
}
@@ -617,10 +620,15 @@ int hinic_pf_to_mgmt_init(struct hinic_pf_to_mgmt *pf_to_mgmt,
if (HINIC_IS_VF(hwif))
return 0;
+ err = hinic_health_reporters_create(hwdev->devlink_dev);
+ if (err)
+ return err;
+
sema_init(&pf_to_mgmt->sync_msg_lock, 1);
pf_to_mgmt->workq = create_singlethread_workqueue("hinic_mgmt");
if (!pf_to_mgmt->workq) {
dev_err(&pdev->dev, "Failed to initialize MGMT workqueue\n");
+ hinic_health_reporters_destroy(hwdev->devlink_dev);
return -ENOMEM;
}
pf_to_mgmt->sync_msg_id = 0;
@@ -628,12 +636,14 @@ int hinic_pf_to_mgmt_init(struct hinic_pf_to_mgmt *pf_to_mgmt,
err = alloc_msg_buf(pf_to_mgmt);
if (err) {
dev_err(&pdev->dev, "Failed to allocate msg buffers\n");
+ hinic_health_reporters_destroy(hwdev->devlink_dev);
return err;
}
err = hinic_api_cmd_init(pf_to_mgmt->cmd_chain, hwif);
if (err) {
dev_err(&pdev->dev, "Failed to initialize cmd chains\n");
+ hinic_health_reporters_destroy(hwdev->devlink_dev);
return err;
}
@@ -658,4 +668,5 @@ void hinic_pf_to_mgmt_free(struct hinic_pf_to_mgmt *pf_to_mgmt)
hinic_aeq_unregister_hw_cb(&hwdev->aeqs, HINIC_MSG_FROM_MGMT_CPU);
hinic_api_cmd_free(pf_to_mgmt->cmd_chain);
destroy_workqueue(pf_to_mgmt->workq);
+ hinic_health_reporters_destroy(hwdev->devlink_dev);
}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h
index a824fbda59db..4ca81cc838db 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h
@@ -78,11 +78,24 @@ enum hinic_comm_cmd {
HINIC_COMM_CMD_CEQ_CTRL_REG_WR_BY_UP = 0x33,
- HINIC_COMM_CMD_L2NIC_RESET = 0x4b,
+ HINIC_COMM_CMD_MSI_CTRL_REG_WR_BY_UP,
+ HINIC_COMM_CMD_MSI_CTRL_REG_RD_BY_UP,
+
+ HINIC_COMM_CMD_FAULT_REPORT = 0x37,
+
+ HINIC_COMM_CMD_SET_LED_STATUS = 0x4a,
+
+ HINIC_COMM_CMD_L2NIC_RESET = 0x4b,
HINIC_COMM_CMD_PAGESIZE_SET = 0x50,
- HINIC_COMM_CMD_MAX = 0x51,
+ HINIC_COMM_CMD_GET_BOARD_INFO = 0x52,
+
+ HINIC_COMM_CMD_WATCHDOG_INFO = 0x56,
+
+ HINIC_MGMT_CMD_SET_VF_RANDOM_ID = 0x61,
+
+ HINIC_COMM_CMD_MAX,
};
enum hinic_mgmt_cb_state {
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
index e9e6f4c9309a..501056fd32ee 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
@@ -18,6 +18,7 @@
#include <linux/semaphore.h>
#include <linux/workqueue.h>
#include <net/ip.h>
+#include <net/devlink.h>
#include <linux/bitops.h>
#include <linux/bitmap.h>
#include <linux/delay.h>
@@ -25,6 +26,7 @@
#include "hinic_hw_qp.h"
#include "hinic_hw_dev.h"
+#include "hinic_devlink.h"
#include "hinic_port.h"
#include "hinic_tx.h"
#include "hinic_rx.h"
@@ -69,6 +71,10 @@ MODULE_PARM_DESC(rx_weight, "Number Rx packets for NAPI budget (default=64)");
#define HINIC_WAIT_SRIOV_CFG_TIMEOUT 15000
+#define HINIC_DEAULT_TXRX_MSIX_PENDING_LIMIT 2
+#define HINIC_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG 32
+#define HINIC_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG 7
+
static int change_mac_addr(struct net_device *netdev, const u8 *addr);
static int set_features(struct hinic_dev *nic_dev,
@@ -438,8 +444,11 @@ int hinic_open(struct net_device *netdev)
if (!HINIC_IS_VF(nic_dev->hwdev->hwif))
hinic_notify_all_vfs_link_changed(nic_dev->hwdev, link_state);
- if (link_state == HINIC_LINK_STATE_UP)
+ if (link_state == HINIC_LINK_STATE_UP) {
nic_dev->flags |= HINIC_LINK_UP;
+ nic_dev->cable_unplugged = false;
+ nic_dev->module_unrecognized = false;
+ }
nic_dev->flags |= HINIC_INTF_UP;
@@ -887,6 +896,26 @@ static void netdev_features_init(struct net_device *netdev)
netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
}
+static void hinic_refresh_nic_cfg(struct hinic_dev *nic_dev)
+{
+ struct hinic_nic_cfg *nic_cfg = &nic_dev->hwdev->func_to_io.nic_cfg;
+ struct hinic_pause_config pause_info = {0};
+ struct hinic_port_cap port_cap = {0};
+
+ if (hinic_port_get_cap(nic_dev, &port_cap))
+ return;
+
+ mutex_lock(&nic_cfg->cfg_mutex);
+ if (nic_cfg->pause_set || !port_cap.autoneg_state) {
+ nic_cfg->auto_neg = port_cap.autoneg_state;
+ pause_info.auto_neg = nic_cfg->auto_neg;
+ pause_info.rx_pause = nic_cfg->rx_pause;
+ pause_info.tx_pause = nic_cfg->tx_pause;
+ hinic_set_hw_pause_info(nic_dev->hwdev, &pause_info);
+ }
+ mutex_unlock(&nic_cfg->cfg_mutex);
+}
+
/**
* link_status_event_handler - link event handler
* @handle: nic device for the handler
@@ -909,6 +938,8 @@ static void link_status_event_handler(void *handle, void *buf_in, u16 in_size,
down(&nic_dev->mgmt_lock);
nic_dev->flags |= HINIC_LINK_UP;
+ nic_dev->cable_unplugged = false;
+ nic_dev->module_unrecognized = false;
if ((nic_dev->flags & (HINIC_LINK_UP | HINIC_INTF_UP)) ==
(HINIC_LINK_UP | HINIC_INTF_UP)) {
@@ -918,6 +949,9 @@ static void link_status_event_handler(void *handle, void *buf_in, u16 in_size,
up(&nic_dev->mgmt_lock);
+ if (!HINIC_IS_VF(nic_dev->hwdev->hwif))
+ hinic_refresh_nic_cfg(nic_dev);
+
netif_info(nic_dev, drv, nic_dev->netdev, "HINIC_Link is UP\n");
} else {
down(&nic_dev->mgmt_lock);
@@ -942,34 +976,132 @@ static void link_status_event_handler(void *handle, void *buf_in, u16 in_size,
*out_size = sizeof(*ret_link_status);
}
+static void cable_plug_event(void *handle,
+ void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct hinic_cable_plug_event *plug_event = buf_in;
+ struct hinic_dev *nic_dev = handle;
+
+ nic_dev->cable_unplugged = plug_event->plugged ? false : true;
+
+ *out_size = sizeof(*plug_event);
+ plug_event = buf_out;
+ plug_event->status = 0;
+}
+
+static void link_err_event(void *handle,
+ void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct hinic_link_err_event *link_err = buf_in;
+ struct hinic_dev *nic_dev = handle;
+
+ if (link_err->err_type >= LINK_ERR_NUM)
+ netif_info(nic_dev, link, nic_dev->netdev,
+ "Link failed, Unknown error type: 0x%x\n",
+ link_err->err_type);
+ else
+ nic_dev->module_unrecognized = true;
+
+ *out_size = sizeof(*link_err);
+ link_err = buf_out;
+ link_err->status = 0;
+}
+
static int set_features(struct hinic_dev *nic_dev,
netdev_features_t pre_features,
netdev_features_t features, bool force_change)
{
netdev_features_t changed = force_change ? ~0 : pre_features ^ features;
u32 csum_en = HINIC_RX_CSUM_OFFLOAD_EN;
+ netdev_features_t failed_features = 0;
+ int ret = 0;
int err = 0;
- if (changed & NETIF_F_TSO)
- err = hinic_port_set_tso(nic_dev, (features & NETIF_F_TSO) ?
+ if (changed & NETIF_F_TSO) {
+ ret = hinic_port_set_tso(nic_dev, (features & NETIF_F_TSO) ?
HINIC_TSO_ENABLE : HINIC_TSO_DISABLE);
+ if (ret) {
+ err = ret;
+ failed_features |= NETIF_F_TSO;
+ }
+ }
- if (changed & NETIF_F_RXCSUM)
- err = hinic_set_rx_csum_offload(nic_dev, csum_en);
+ if (changed & NETIF_F_RXCSUM) {
+ ret = hinic_set_rx_csum_offload(nic_dev, csum_en);
+ if (ret) {
+ err = ret;
+ failed_features |= NETIF_F_RXCSUM;
+ }
+ }
if (changed & NETIF_F_LRO) {
- err = hinic_set_rx_lro_state(nic_dev,
+ ret = hinic_set_rx_lro_state(nic_dev,
!!(features & NETIF_F_LRO),
HINIC_LRO_RX_TIMER_DEFAULT,
HINIC_LRO_MAX_WQE_NUM_DEFAULT);
+ if (ret) {
+ err = ret;
+ failed_features |= NETIF_F_LRO;
+ }
}
- if (changed & NETIF_F_HW_VLAN_CTAG_RX)
- err = hinic_set_rx_vlan_offload(nic_dev,
+ if (changed & NETIF_F_HW_VLAN_CTAG_RX) {
+ ret = hinic_set_rx_vlan_offload(nic_dev,
!!(features &
NETIF_F_HW_VLAN_CTAG_RX));
+ if (ret) {
+ err = ret;
+ failed_features |= NETIF_F_HW_VLAN_CTAG_RX;
+ }
+ }
- return err;
+ if (err) {
+ nic_dev->netdev->features = features ^ failed_features;
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic_init_intr_coalesce(struct hinic_dev *nic_dev)
+{
+ u64 size;
+ u16 i;
+
+ size = sizeof(struct hinic_intr_coal_info) * nic_dev->max_qps;
+ nic_dev->rx_intr_coalesce = kzalloc(size, GFP_KERNEL);
+ if (!nic_dev->rx_intr_coalesce)
+ return -ENOMEM;
+ nic_dev->tx_intr_coalesce = kzalloc(size, GFP_KERNEL);
+ if (!nic_dev->tx_intr_coalesce) {
+ kfree(nic_dev->rx_intr_coalesce);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < nic_dev->max_qps; i++) {
+ nic_dev->rx_intr_coalesce[i].pending_limt =
+ HINIC_DEAULT_TXRX_MSIX_PENDING_LIMIT;
+ nic_dev->rx_intr_coalesce[i].coalesce_timer_cfg =
+ HINIC_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG;
+ nic_dev->rx_intr_coalesce[i].resend_timer_cfg =
+ HINIC_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
+ nic_dev->tx_intr_coalesce[i].pending_limt =
+ HINIC_DEAULT_TXRX_MSIX_PENDING_LIMIT;
+ nic_dev->tx_intr_coalesce[i].coalesce_timer_cfg =
+ HINIC_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG;
+ nic_dev->tx_intr_coalesce[i].resend_timer_cfg =
+ HINIC_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
+ }
+
+ return 0;
+}
+
+static void hinic_free_intr_coalesce(struct hinic_dev *nic_dev)
+{
+ kfree(nic_dev->tx_intr_coalesce);
+ kfree(nic_dev->rx_intr_coalesce);
}
/**
@@ -986,11 +1118,19 @@ static int nic_dev_init(struct pci_dev *pdev)
struct hinic_dev *nic_dev;
struct net_device *netdev;
struct hinic_hwdev *hwdev;
+ struct devlink *devlink;
int err, num_qps;
- hwdev = hinic_init_hwdev(pdev);
+ devlink = hinic_devlink_alloc();
+ if (!devlink) {
+ dev_err(&pdev->dev, "Hinic devlink alloc failed\n");
+ return -ENOMEM;
+ }
+
+ hwdev = hinic_init_hwdev(pdev, devlink);
if (IS_ERR(hwdev)) {
dev_err(&pdev->dev, "Failed to initialize HW device\n");
+ hinic_devlink_free(devlink);
return PTR_ERR(hwdev);
}
@@ -1008,8 +1148,6 @@ static int nic_dev_init(struct pci_dev *pdev)
goto err_alloc_etherdev;
}
- hinic_set_ethtool_ops(netdev);
-
if (!HINIC_IS_VF(hwdev->hwif))
netdev->netdev_ops = &hinic_netdev_ops;
else
@@ -1031,6 +1169,9 @@ static int nic_dev_init(struct pci_dev *pdev)
nic_dev->sriov_info.hwdev = hwdev;
nic_dev->sriov_info.pdev = pdev;
nic_dev->max_qps = num_qps;
+ nic_dev->devlink = devlink;
+
+ hinic_set_ethtool_ops(netdev);
sema_init(&nic_dev->mgmt_lock, 1);
@@ -1095,13 +1236,30 @@ static int nic_dev_init(struct pci_dev *pdev)
hinic_hwdev_cb_register(nic_dev->hwdev, HINIC_MGMT_MSG_CMD_LINK_STATUS,
nic_dev, link_status_event_handler);
+ hinic_hwdev_cb_register(nic_dev->hwdev,
+ HINIC_MGMT_MSG_CMD_CABLE_PLUG_EVENT,
+ nic_dev, cable_plug_event);
+ hinic_hwdev_cb_register(nic_dev->hwdev,
+ HINIC_MGMT_MSG_CMD_LINK_ERR_EVENT,
+ nic_dev, link_err_event);
err = set_features(nic_dev, 0, nic_dev->netdev->features, true);
if (err)
goto err_set_features;
+ /* enable pause and disable pfc by default */
+ err = hinic_dcb_set_pfc(nic_dev->hwdev, 0, 0);
+ if (err)
+ goto err_set_pfc;
+
SET_NETDEV_DEV(netdev, &pdev->dev);
+ err = hinic_init_intr_coalesce(nic_dev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to init_intr_coalesce\n");
+ goto err_init_intr;
+ }
+
err = register_netdev(netdev);
if (err) {
dev_err(&pdev->dev, "Failed to register netdev\n");
@@ -1111,17 +1269,24 @@ static int nic_dev_init(struct pci_dev *pdev)
return 0;
err_reg_netdev:
+ hinic_free_intr_coalesce(nic_dev);
+err_init_intr:
+err_set_pfc:
err_set_features:
hinic_hwdev_cb_unregister(nic_dev->hwdev,
+ HINIC_MGMT_MSG_CMD_LINK_ERR_EVENT);
+ hinic_hwdev_cb_unregister(nic_dev->hwdev,
+ HINIC_MGMT_MSG_CMD_CABLE_PLUG_EVENT);
+ hinic_hwdev_cb_unregister(nic_dev->hwdev,
HINIC_MGMT_MSG_CMD_LINK_STATUS);
cancel_work_sync(&rx_mode_work->work);
err_set_mtu:
-err_get_mac:
+ hinic_port_del_mac(nic_dev, netdev->dev_addr, 0);
err_add_mac:
+err_get_mac:
pci_set_drvdata(pdev, NULL);
destroy_workqueue(nic_dev->workq);
-
err_workq:
err_vlan_bitmap:
free_netdev(netdev);
@@ -1129,6 +1294,7 @@ err_vlan_bitmap:
err_alloc_etherdev:
err_num_qps:
hinic_free_hwdev(hwdev);
+ hinic_devlink_free(devlink);
return err;
}
@@ -1215,6 +1381,7 @@ static void hinic_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct hinic_dev *nic_dev = netdev_priv(netdev);
+ struct devlink *devlink = nic_dev->devlink;
struct hinic_rx_mode_work *rx_mode_work;
if (!HINIC_IS_VF(nic_dev->hwdev->hwif)) {
@@ -1224,9 +1391,15 @@ static void hinic_remove(struct pci_dev *pdev)
unregister_netdev(netdev);
+ hinic_free_intr_coalesce(nic_dev);
+
hinic_port_del_mac(nic_dev, netdev->dev_addr, 0);
hinic_hwdev_cb_unregister(nic_dev->hwdev,
+ HINIC_MGMT_MSG_CMD_LINK_ERR_EVENT);
+ hinic_hwdev_cb_unregister(nic_dev->hwdev,
+ HINIC_MGMT_MSG_CMD_CABLE_PLUG_EVENT);
+ hinic_hwdev_cb_unregister(nic_dev->hwdev,
HINIC_MGMT_MSG_CMD_LINK_STATUS);
rx_mode_work = &nic_dev->rx_mode_work;
@@ -1236,12 +1409,12 @@ static void hinic_remove(struct pci_dev *pdev)
destroy_workqueue(nic_dev->workq);
- hinic_vf_func_free(nic_dev->hwdev);
-
hinic_free_hwdev(nic_dev->hwdev);
free_netdev(netdev);
+ hinic_devlink_free(devlink);
+
pci_release_regions(pdev);
pci_disable_device(pdev);
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_port.c b/drivers/net/ethernet/huawei/hinic/hinic_port.c
index 175c0ee00038..02cd635d6914 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_port.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_port.c
@@ -61,8 +61,8 @@ static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
(port_mac_cmd.status &&
port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY &&
port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
- dev_err(&pdev->dev, "Failed to change MAC, ret = %d\n",
- port_mac_cmd.status);
+ dev_err(&pdev->dev, "Failed to change MAC, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_mac_cmd.status, out_size);
return -EFAULT;
}
@@ -129,8 +129,8 @@ int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
&port_mac_cmd, sizeof(port_mac_cmd),
&port_mac_cmd, &out_size);
if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) {
- dev_err(&pdev->dev, "Failed to get mac, ret = %d\n",
- port_mac_cmd.status);
+ dev_err(&pdev->dev, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_mac_cmd.status, out_size);
return -EFAULT;
}
@@ -172,9 +172,9 @@ int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
&port_mtu_cmd, sizeof(port_mtu_cmd),
&port_mtu_cmd, &out_size);
- if (err || (out_size != sizeof(port_mtu_cmd)) || port_mtu_cmd.status) {
- dev_err(&pdev->dev, "Failed to set mtu, ret = %d\n",
- port_mtu_cmd.status);
+ if (err || out_size != sizeof(port_mtu_cmd) || port_mtu_cmd.status) {
+ dev_err(&pdev->dev, "Failed to set mtu, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_mtu_cmd.status, out_size);
return -EFAULT;
}
@@ -264,8 +264,8 @@ int hinic_port_link_state(struct hinic_dev *nic_dev,
&link_cmd, sizeof(link_cmd),
&link_cmd, &out_size);
if (err || (out_size != sizeof(link_cmd)) || link_cmd.status) {
- dev_err(&pdev->dev, "Failed to get link state, ret = %d\n",
- link_cmd.status);
+ dev_err(&pdev->dev, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, link_cmd.status, out_size);
return -EINVAL;
}
@@ -298,8 +298,8 @@ int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
&port_state, sizeof(port_state),
&port_state, &out_size);
if (err || (out_size != sizeof(port_state)) || port_state.status) {
- dev_err(&pdev->dev, "Failed to set port state, ret = %d\n",
- port_state.status);
+ dev_err(&pdev->dev, "Failed to set port state, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_state.status, out_size);
return -EFAULT;
}
@@ -330,8 +330,8 @@ int hinic_port_set_func_state(struct hinic_dev *nic_dev,
&func_state, sizeof(func_state),
&func_state, &out_size);
if (err || (out_size != sizeof(func_state)) || func_state.status) {
- dev_err(&pdev->dev, "Failed to set port func state, ret = %d\n",
- func_state.status);
+ dev_err(&pdev->dev, "Failed to set port func state, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, func_state.status, out_size);
return -EFAULT;
}
@@ -361,9 +361,9 @@ int hinic_port_get_cap(struct hinic_dev *nic_dev,
port_cap, &out_size);
if (err || (out_size != sizeof(*port_cap)) || port_cap->status) {
dev_err(&pdev->dev,
- "Failed to get port capabilities, ret = %d\n",
- port_cap->status);
- return -EINVAL;
+ "Failed to get port capabilities, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_cap->status, out_size);
+ return -EIO;
}
return 0;
@@ -393,9 +393,9 @@ int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state)
&tso_cfg, &out_size);
if (err || out_size != sizeof(tso_cfg) || tso_cfg.status) {
dev_err(&pdev->dev,
- "Failed to set port tso, ret = %d\n",
- tso_cfg.status);
- return -EINVAL;
+ "Failed to set port tso, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, tso_cfg.status, out_size);
+ return -EIO;
}
return 0;
@@ -423,9 +423,9 @@ int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en)
&rx_csum_cfg, &out_size);
if (err || !out_size || rx_csum_cfg.status) {
dev_err(&pdev->dev,
- "Failed to set rx csum offload, ret = %d\n",
- rx_csum_cfg.status);
- return -EINVAL;
+ "Failed to set rx csum offload, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_csum_cfg.status, out_size);
+ return -EIO;
}
return 0;
@@ -480,9 +480,9 @@ int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
&rq_num, &out_size);
if (err || !out_size || rq_num.status) {
dev_err(&pdev->dev,
- "Failed to rxq number, ret = %d\n",
- rq_num.status);
- return -EINVAL;
+ "Failed to set rxq number, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rq_num.status, out_size);
+ return -EIO;
}
return 0;
@@ -508,9 +508,9 @@ static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
&lro_cfg, &out_size);
if (err || !out_size || lro_cfg.status) {
dev_err(&pdev->dev,
- "Failed to set lro offload, ret = %d\n",
- lro_cfg.status);
- return -EINVAL;
+ "Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, lro_cfg.status, out_size);
+ return -EIO;
}
return 0;
@@ -542,10 +542,10 @@ static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
if (err || !out_size || lro_timer.status) {
dev_err(&pdev->dev,
- "Failed to set lro timer, ret = %d\n",
- lro_timer.status);
+ "Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, lro_timer.status, out_size);
- return -EINVAL;
+ return -EIO;
}
return 0;
@@ -1082,6 +1082,7 @@ int hinic_get_link_mode(struct hinic_hwdev *hwdev,
if (!hwdev || !link_mode)
return -EINVAL;
+ link_mode->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
out_size = sizeof(*link_mode);
err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_MODE,
@@ -1172,6 +1173,8 @@ int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev,
u16 out_size = sizeof(*pause_info);
int err;
+ pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
+
err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO,
pause_info, sizeof(*pause_info),
pause_info, &out_size);
@@ -1190,6 +1193,8 @@ int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev,
u16 out_size = sizeof(*pause_info);
int err;
+ pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
+
err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PAUSE_INFO,
pause_info, sizeof(*pause_info),
pause_info, &out_size);
@@ -1201,3 +1206,192 @@ int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev,
return 0;
}
+
+int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap)
+{
+ struct hinic_nic_cfg *nic_cfg = &hwdev->func_to_io.nic_cfg;
+ struct hinic_set_pfc pfc = {0};
+ u16 out_size = sizeof(pfc);
+ int err;
+
+ if (HINIC_IS_VF(hwdev->hwif))
+ return 0;
+
+ mutex_lock(&nic_cfg->cfg_mutex);
+
+ pfc.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
+ pfc.pfc_bitmap = pfc_bitmap;
+ pfc.pfc_en = pfc_en;
+
+ err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PFC,
+ &pfc, sizeof(pfc), &pfc, &out_size);
+ if (err || pfc.status || !out_size) {
+ dev_err(&hwdev->hwif->pdev->dev, "Failed to %s pfc, err: %d, status: 0x%x, out size: 0x%x\n",
+ pfc_en ? "enable" : "disable", err, pfc.status,
+ out_size);
+ mutex_unlock(&nic_cfg->cfg_mutex);
+ return -EIO;
+ }
+
+ /* pause settings is opposite from pfc */
+ nic_cfg->rx_pause = pfc_en ? 0 : 1;
+ nic_cfg->tx_pause = pfc_en ? 0 : 1;
+
+ mutex_unlock(&nic_cfg->cfg_mutex);
+
+ return 0;
+}
+
+int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable)
+{
+ struct hinic_port_loopback lb = {0};
+ u16 out_size = sizeof(lb);
+ int err;
+
+ lb.mode = mode;
+ lb.en = enable;
+
+ if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
+ dev_err(&hwdev->hwif->pdev->dev,
+ "Invalid loopback mode %d to set\n", mode);
+ return -EINVAL;
+ }
+
+ err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LOOPBACK_MODE,
+ &lb, sizeof(lb), &lb, &out_size);
+ if (err || !out_size || lb.status) {
+ dev_err(&hwdev->hwif->pdev->dev,
+ "Failed to set loopback mode %d en %d, err: %d, status: 0x%x, out size: 0x%x\n",
+ mode, enable, err, lb.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int _set_led_status(struct hinic_hwdev *hwdev, u8 port,
+ enum hinic_led_type type,
+ enum hinic_led_mode mode, u8 reset)
+{
+ struct hinic_led_info led_info = {0};
+ u16 out_size = sizeof(led_info);
+ struct hinic_pfhwdev *pfhwdev;
+ int err;
+
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
+
+ led_info.port = port;
+ led_info.reset = reset;
+
+ led_info.type = type;
+ led_info.mode = mode;
+
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
+ HINIC_COMM_CMD_SET_LED_STATUS,
+ &led_info, sizeof(led_info),
+ &led_info, &out_size, HINIC_MGMT_MSG_SYNC);
+ if (err || led_info.status || !out_size) {
+ dev_err(&hwdev->hwif->pdev->dev, "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, led_info.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port,
+ enum hinic_led_type type, enum hinic_led_mode mode)
+{
+ if (!hwdev)
+ return -EINVAL;
+
+ return _set_led_status(hwdev, port, type, mode, 0);
+}
+
+int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port)
+{
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ err = _set_led_status(hwdev, port, HINIC_LED_TYPE_INVALID,
+ HINIC_LED_MODE_INVALID, 1);
+ if (err)
+ dev_err(&hwdev->hwif->pdev->dev,
+ "Failed to reset led status\n");
+
+ return err;
+}
+
+static bool hinic_if_sfp_absent(struct hinic_hwdev *hwdev)
+{
+ struct hinic_cmd_get_light_module_abs sfp_abs = {0};
+ u16 out_size = sizeof(sfp_abs);
+ u8 port_id = hwdev->port_id;
+ int err;
+
+ sfp_abs.port_id = port_id;
+ err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_SFP_ABS,
+ &sfp_abs, sizeof(sfp_abs), &sfp_abs,
+ &out_size);
+ if (sfp_abs.status || err || !out_size) {
+ dev_err(&hwdev->hwif->pdev->dev,
+ "Failed to get port%d sfp absent status, err: %d, status: 0x%x, out size: 0x%x\n",
+ port_id, err, sfp_abs.status, out_size);
+ return true;
+ }
+
+ return ((sfp_abs.abs_status == 0) ? false : true);
+}
+
+int hinic_get_sfp_eeprom(struct hinic_hwdev *hwdev, u8 *data, u16 *len)
+{
+ struct hinic_cmd_get_std_sfp_info sfp_info = {0};
+ u16 out_size = sizeof(sfp_info);
+ u8 port_id;
+ int err;
+
+ if (!hwdev || !data || !len)
+ return -EINVAL;
+
+ port_id = hwdev->port_id;
+
+ if (hinic_if_sfp_absent(hwdev))
+ return -ENXIO;
+
+ sfp_info.port_id = port_id;
+ err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_STD_SFP_INFO,
+ &sfp_info, sizeof(sfp_info), &sfp_info,
+ &out_size);
+ if (sfp_info.status || err || !out_size) {
+ dev_err(&hwdev->hwif->pdev->dev,
+ "Failed to get port%d sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ port_id, err, sfp_info.status, out_size);
+ return -EIO;
+ }
+
+ *len = min_t(u16, sfp_info.eeprom_len, STD_SFP_INFO_MAX_SIZE);
+ memcpy(data, sfp_info.sfp_info, STD_SFP_INFO_MAX_SIZE);
+
+ return 0;
+}
+
+int hinic_get_sfp_type(struct hinic_hwdev *hwdev, u8 *data0, u8 *data1)
+{
+ u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
+ u16 len;
+ int err;
+
+ if (hinic_if_sfp_absent(hwdev))
+ return -ENXIO;
+
+ err = hinic_get_sfp_eeprom(hwdev, sfp_data, &len);
+ if (err)
+ return err;
+
+ *data0 = sfp_data[0];
+ *data1 = sfp_data[1];
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_port.h b/drivers/net/ethernet/huawei/hinic/hinic_port.h
index 661c6322dc15..9c3cbe45c9ec 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_port.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_port.h
@@ -189,6 +189,31 @@ struct hinic_port_link_status {
u8 port_id;
};
+struct hinic_cable_plug_event {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u8 plugged; /* 0: unplugged, 1: plugged */
+ u8 port_id;
+};
+
+enum link_err_type {
+ LINK_ERR_MODULE_UNRECOGENIZED,
+ LINK_ERR_NUM,
+};
+
+struct hinic_link_err_event {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u8 err_type;
+ u8 port_id;
+};
+
struct hinic_port_func_state_cmd {
u8 status;
u8 version;
@@ -641,6 +666,93 @@ struct hinic_pause_config {
u32 tx_pause;
};
+struct hinic_set_pfc {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u8 pfc_en;
+ u8 pfc_bitmap;
+ u8 rsvd1[4];
+};
+
+/* get or set loopback mode, need to modify by base API */
+#define HINIC_INTERNAL_LP_MODE 5
+#define LOOP_MODE_MIN 1
+#define LOOP_MODE_MAX 6
+
+struct hinic_port_loopback {
+ u8 status;
+ u8 version;
+ u8 rsvd[6];
+
+ u32 mode;
+ u32 en;
+};
+
+struct hinic_led_info {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u8 port;
+ u8 type;
+ u8 mode;
+ u8 reset;
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+
+struct hinic_cmd_get_light_module_abs {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsv[2];
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+
+struct hinic_cmd_get_std_sfp_info {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u8 port_id;
+ u8 wire_type;
+ u16 eeprom_len;
+ u32 rsvd;
+ u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
+};
+
+struct hinic_cmd_update_fw {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ struct {
+ u32 SL:1;
+ u32 SF:1;
+ u32 flag:1;
+ u32 reserved:13;
+ u32 fragment_len:16;
+ } ctl_info;
+
+ struct {
+ u32 FW_section_CRC;
+ u32 FW_section_type;
+ } section_info;
+
+ u32 total_len;
+ u32 setion_total_len;
+ u32 fw_section_version;
+ u32 section_offset;
+ u32 data[384];
+};
+
int hinic_port_add_mac(struct hinic_dev *nic_dev, const u8 *addr,
u16 vlan_id);
@@ -736,6 +848,38 @@ int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev,
int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev,
struct hinic_pause_config *pause_info);
+int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap);
+
+int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable);
+
+enum hinic_led_mode {
+ HINIC_LED_MODE_ON,
+ HINIC_LED_MODE_OFF,
+ HINIC_LED_MODE_FORCE_1HZ,
+ HINIC_LED_MODE_FORCE_2HZ,
+ HINIC_LED_MODE_FORCE_4HZ,
+ HINIC_LED_MODE_1HZ,
+ HINIC_LED_MODE_2HZ,
+ HINIC_LED_MODE_4HZ,
+ HINIC_LED_MODE_INVALID,
+};
+
+enum hinic_led_type {
+ HINIC_LED_TYPE_LINK,
+ HINIC_LED_TYPE_LOW_SPEED,
+ HINIC_LED_TYPE_HIGH_SPEED,
+ HINIC_LED_TYPE_INVALID,
+};
+
+int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port);
+
+int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port,
+ enum hinic_led_type type, enum hinic_led_mode mode);
+
+int hinic_get_sfp_type(struct hinic_hwdev *hwdev, u8 *data0, u8 *data1);
+
+int hinic_get_sfp_eeprom(struct hinic_hwdev *hwdev, u8 *data, u16 *len);
+
int hinic_open(struct net_device *netdev);
int hinic_close(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
index af20d0dd6de7..5bee951fe9d4 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
@@ -316,6 +316,39 @@ static int rx_recv_jumbo_pkt(struct hinic_rxq *rxq, struct sk_buff *head_skb,
return num_wqes;
}
+static void hinic_copy_lp_data(struct hinic_dev *nic_dev,
+ struct sk_buff *skb)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u8 *lb_buf = nic_dev->lb_test_rx_buf;
+ int lb_len = nic_dev->lb_pkt_len;
+ int pkt_offset, frag_len, i;
+ void *frag_data = NULL;
+
+ if (nic_dev->lb_test_rx_idx == LP_PKT_CNT) {
+ nic_dev->lb_test_rx_idx = 0;
+ netif_warn(nic_dev, drv, netdev, "Loopback test warning, receive too more test pkts\n");
+ }
+
+ if (skb->len != nic_dev->lb_pkt_len) {
+ netif_warn(nic_dev, drv, netdev, "Wrong packet length\n");
+ nic_dev->lb_test_rx_idx++;
+ return;
+ }
+
+ pkt_offset = nic_dev->lb_test_rx_idx * lb_len;
+ frag_len = (int)skb_headlen(skb);
+ memcpy(lb_buf + pkt_offset, skb->data, frag_len);
+ pkt_offset += frag_len;
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ frag_data = skb_frag_address(&skb_shinfo(skb)->frags[i]);
+ frag_len = (int)skb_frag_size(&skb_shinfo(skb)->frags[i]);
+ memcpy((lb_buf + pkt_offset), frag_data, frag_len);
+ pkt_offset += frag_len;
+ }
+ nic_dev->lb_test_rx_idx++;
+}
+
/**
* rxq_recv - Rx handler
* @rxq: rx queue
@@ -330,6 +363,7 @@ static int rxq_recv(struct hinic_rxq *rxq, int budget)
u64 pkt_len = 0, rx_bytes = 0;
struct hinic_rq *rq = rxq->rq;
struct hinic_rq_wqe *rq_wqe;
+ struct hinic_dev *nic_dev;
unsigned int free_wqebbs;
struct hinic_rq_cqe *cqe;
int num_wqes, pkts = 0;
@@ -342,6 +376,8 @@ static int rxq_recv(struct hinic_rxq *rxq, int budget)
u32 vlan_len;
u16 vid;
+ nic_dev = netdev_priv(netdev);
+
while (pkts < budget) {
num_wqes = 0;
@@ -384,6 +420,9 @@ static int rxq_recv(struct hinic_rxq *rxq, int budget)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
}
+ if (unlikely(nic_dev->flags & HINIC_LP_TEST))
+ hinic_copy_lp_data(nic_dev, skb);
+
skb_record_rx_queue(skb, qp->q_id);
skb->protocol = eth_type_trans(skb, rxq->netdev);
@@ -478,11 +517,15 @@ static irqreturn_t rx_irq(int irq, void *data)
static int rx_request_irq(struct hinic_rxq *rxq)
{
struct hinic_dev *nic_dev = netdev_priv(rxq->netdev);
+ struct hinic_msix_config interrupt_info = {0};
+ struct hinic_intr_coal_info *intr_coal = NULL;
struct hinic_hwdev *hwdev = nic_dev->hwdev;
struct hinic_rq *rq = rxq->rq;
struct hinic_qp *qp;
int err;
+ qp = container_of(rq, struct hinic_qp, rq);
+
rx_add_napi(rxq);
hinic_hwdev_msix_set(hwdev, rq->msix_entry,
@@ -490,13 +533,26 @@ static int rx_request_irq(struct hinic_rxq *rxq)
RX_IRQ_NO_LLI_TIMER, RX_IRQ_NO_CREDIT,
RX_IRQ_NO_RESEND_TIMER);
+ intr_coal = &nic_dev->rx_intr_coalesce[qp->q_id];
+ interrupt_info.msix_index = rq->msix_entry;
+ interrupt_info.coalesce_timer_cnt = intr_coal->coalesce_timer_cfg;
+ interrupt_info.pending_cnt = intr_coal->pending_limt;
+ interrupt_info.resend_timer_cnt = intr_coal->resend_timer_cfg;
+
+ err = hinic_set_interrupt_cfg(hwdev, &interrupt_info);
+ if (err) {
+ netif_err(nic_dev, drv, rxq->netdev,
+ "Failed to set RX interrupt coalescing attribute\n");
+ rx_del_napi(rxq);
+ return err;
+ }
+
err = request_irq(rq->irq, rx_irq, 0, rxq->irq_name, rxq);
if (err) {
rx_del_napi(rxq);
return err;
}
- qp = container_of(rq, struct hinic_qp, rq);
cpumask_set_cpu(qp->q_id % num_online_cpus(), &rq->affinity_mask);
return irq_set_affinity_hint(rq->irq, &rq->affinity_mask);
}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
index efab2dd2c889..4d63680f2143 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
@@ -40,9 +40,9 @@ static int hinic_set_mac(struct hinic_hwdev *hwdev, const u8 *mac_addr,
if (err || out_size != sizeof(mac_info) ||
(mac_info.status && mac_info.status != HINIC_PF_SET_VF_ALREADY &&
mac_info.status != HINIC_MGMT_STATUS_EXIST)) {
- dev_err(&hwdev->func_to_io.hwif->pdev->dev, "Failed to change MAC, ret = %d\n",
- mac_info.status);
- return -EFAULT;
+ dev_err(&hwdev->func_to_io.hwif->pdev->dev, "Failed to set MAC, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, mac_info.status, out_size);
+ return -EIO;
}
return 0;
@@ -383,7 +383,7 @@ static int hinic_del_vf_mac_msg_handler(void *hwdev, u16 vf_id,
nic_io = &hw_dev->func_to_io;
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
- if (vf_info->pf_set_mac && is_valid_ether_addr(mac_in->mac) &&
+ if (vf_info->pf_set_mac && is_valid_ether_addr(mac_in->mac) &&
!memcmp(vf_info->vf_mac_addr, mac_in->mac, ETH_ALEN)) {
dev_warn(&hw_dev->hwif->pdev->dev, "PF has already set VF mac.\n");
mac_out->status = HINIC_PF_SET_VF_ALREADY;
@@ -429,6 +429,18 @@ static int hinic_get_vf_link_status_msg_handler(void *hwdev, u16 vf_id,
return 0;
}
+static bool check_func_table(struct hinic_hwdev *hwdev, u16 func_idx,
+ void *buf_in, u16 in_size)
+{
+ struct hinic_cmd_fw_ctxt *function_table = buf_in;
+
+ if (!hinic_mbox_check_func_id_8B(hwdev, func_idx, buf_in, in_size) ||
+ !function_table->rx_buf_sz)
+ return false;
+
+ return true;
+}
+
static struct vf_cmd_msg_handle nic_vf_cmd_msg_handler[] = {
{HINIC_PORT_CMD_VF_REGISTER, hinic_register_vf_msg_handler},
{HINIC_PORT_CMD_VF_UNREGISTER, hinic_unregister_vf_msg_handler},
@@ -439,6 +451,45 @@ static struct vf_cmd_msg_handle nic_vf_cmd_msg_handler[] = {
{HINIC_PORT_CMD_GET_LINK_STATE, hinic_get_vf_link_status_msg_handler},
};
+static struct vf_cmd_check_handle nic_cmd_support_vf[] = {
+ {HINIC_PORT_CMD_VF_REGISTER, NULL},
+ {HINIC_PORT_CMD_VF_UNREGISTER, NULL},
+ {HINIC_PORT_CMD_CHANGE_MTU, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_ADD_VLAN, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_DEL_VLAN, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_MAC, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_MAC, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_DEL_MAC, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_RX_MODE, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_PAUSE_INFO, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_LINK_STATE, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_LRO, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_RX_CSUM, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_VPORT_STAT, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_CLEAN_VPORT_STAT, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
+ hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_RSS_HASH_ENGINE, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_RSS_HASH_ENGINE, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_RSS_CTX_TBL, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_RSS_CTX_TBL, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_RSS_TEMP_MGR, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_RSS_CFG, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_FWCTXT_INIT, check_func_table},
+ {HINIC_PORT_CMD_GET_MGMT_VERSION, NULL},
+ {HINIC_PORT_CMD_SET_FUNC_STATE, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_GLOBAL_QPN, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_TSO, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_SET_RQ_IQ_MAP, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_LINK_STATUS_REPORT, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_UPDATE_MAC, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_CAP, hinic_mbox_check_func_id_8B},
+ {HINIC_PORT_CMD_GET_LINK_MODE, hinic_mbox_check_func_id_8B},
+};
+
#define CHECK_IPSU_15BIT 0X8000
static
@@ -905,7 +956,6 @@ int hinic_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)
err = hinic_set_vf_spoofchk(sriov_info->hwdev,
OS_VF_ID_TO_HW(vf), setting);
-
if (!err) {
netif_info(nic_dev, drv, netdev, "Set VF %d spoofchk %s successfully\n",
vf, setting ? "on" : "off");
@@ -973,6 +1023,7 @@ int hinic_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
static int nic_pf_mbox_handler(void *hwdev, u16 vf_id, u8 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size)
{
+ u8 size = ARRAY_SIZE(nic_cmd_support_vf);
struct vf_cmd_msg_handle *vf_msg_handle;
struct hinic_hwdev *dev = hwdev;
struct hinic_func_to_io *nic_io;
@@ -981,7 +1032,15 @@ static int nic_pf_mbox_handler(void *hwdev, u16 vf_id, u8 cmd, void *buf_in,
u32 i;
if (!hwdev)
- return -EFAULT;
+ return -EINVAL;
+
+ if (!hinic_mbox_check_cmd_valid(hwdev, nic_cmd_support_vf, vf_id, cmd,
+ buf_in, in_size, size)) {
+ dev_err(&dev->hwif->pdev->dev,
+ "PF Receive VF nic cmd: 0x%x, mbox len: 0x%x is invalid\n",
+ cmd, in_size);
+ return HINIC_MBOX_VF_CMD_ERROR;
+ }
pfhwdev = container_of(dev, struct hinic_pfhwdev, hwdev);
nic_io = &dev->func_to_io;
@@ -1020,6 +1079,7 @@ static int cfg_mbx_pf_proc_vf_msg(void *hwdev, u16 vf_id, u8 cmd, void *buf_in,
dev_cap->max_vf = cap->max_vf;
dev_cap->max_sqs = cap->max_vf_qps;
dev_cap->max_rqs = cap->max_vf_qps;
+ dev_cap->port_id = dev->port_id;
*out_size = sizeof(*dev_cap);
@@ -1060,9 +1120,7 @@ static int hinic_init_vf_infos(struct hinic_func_to_io *nic_io, u16 vf_id)
static void hinic_clear_vf_infos(struct hinic_dev *nic_dev, u16 vf_id)
{
struct vf_data_storage *vf_infos;
- u16 func_id;
- func_id = hinic_glb_pf_vf_offset(nic_dev->hwdev->hwif) + vf_id;
vf_infos = nic_dev->hwdev->func_to_io.vf_infos + HW_VF_ID_TO_OS(vf_id);
if (vf_infos->pf_set_mac)
hinic_port_del_mac(nic_dev, vf_infos->vf_mac_addr, 0);
@@ -1110,6 +1168,13 @@ int hinic_vf_func_init(struct hinic_hwdev *hwdev)
int err = 0;
u32 size, i;
+ err = hinic_vf_mbox_random_id_init(hwdev);
+ if (err) {
+ dev_err(&hwdev->hwif->pdev->dev, "Failed to init vf mbox random id, err: %d\n",
+ err);
+ return err;
+ }
+
nic_io = &hwdev->func_to_io;
if (HINIC_IS_VF(hwdev->hwif)) {
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
index 4c66a0bc1b28..a97498ee6914 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
@@ -459,6 +459,67 @@ static int hinic_tx_offload(struct sk_buff *skb, struct hinic_sq_task *task,
return 0;
}
+netdev_tx_t hinic_lb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+ u16 prod_idx, q_id = skb->queue_mapping;
+ struct netdev_queue *netdev_txq;
+ int nr_sges, err = NETDEV_TX_OK;
+ struct hinic_sq_wqe *sq_wqe;
+ unsigned int wqe_size;
+ struct hinic_txq *txq;
+ struct hinic_qp *qp;
+
+ txq = &nic_dev->txqs[q_id];
+ qp = container_of(txq->sq, struct hinic_qp, sq);
+ nr_sges = skb_shinfo(skb)->nr_frags + 1;
+
+ err = tx_map_skb(nic_dev, skb, txq->sges);
+ if (err)
+ goto skb_error;
+
+ wqe_size = HINIC_SQ_WQE_SIZE(nr_sges);
+
+ sq_wqe = hinic_sq_get_wqe(txq->sq, wqe_size, &prod_idx);
+ if (!sq_wqe) {
+ netif_stop_subqueue(netdev, qp->q_id);
+
+ sq_wqe = hinic_sq_get_wqe(txq->sq, wqe_size, &prod_idx);
+ if (sq_wqe) {
+ netif_wake_subqueue(nic_dev->netdev, qp->q_id);
+ goto process_sq_wqe;
+ }
+
+ tx_unmap_skb(nic_dev, skb, txq->sges);
+
+ u64_stats_update_begin(&txq->txq_stats.syncp);
+ txq->txq_stats.tx_busy++;
+ u64_stats_update_end(&txq->txq_stats.syncp);
+ err = NETDEV_TX_BUSY;
+ wqe_size = 0;
+ goto flush_skbs;
+ }
+
+process_sq_wqe:
+ hinic_sq_prepare_wqe(txq->sq, prod_idx, sq_wqe, txq->sges, nr_sges);
+ hinic_sq_write_wqe(txq->sq, prod_idx, sq_wqe, skb, wqe_size);
+
+flush_skbs:
+ netdev_txq = netdev_get_tx_queue(netdev, q_id);
+ if ((!netdev_xmit_more()) || (netif_xmit_stopped(netdev_txq)))
+ hinic_sq_write_db(txq->sq, prod_idx, wqe_size, 0);
+
+ return err;
+
+skb_error:
+ dev_kfree_skb_any(skb);
+ u64_stats_update_begin(&txq->txq_stats.syncp);
+ txq->txq_stats.tx_dropped++;
+ u64_stats_update_end(&txq->txq_stats.syncp);
+
+ return NETDEV_TX_OK;
+}
+
netdev_tx_t hinic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct hinic_dev *nic_dev = netdev_priv(netdev);
@@ -718,12 +779,17 @@ static irqreturn_t tx_irq(int irq, void *data)
static int tx_request_irq(struct hinic_txq *txq)
{
struct hinic_dev *nic_dev = netdev_priv(txq->netdev);
+ struct hinic_msix_config interrupt_info = {0};
+ struct hinic_intr_coal_info *intr_coal = NULL;
struct hinic_hwdev *hwdev = nic_dev->hwdev;
struct hinic_hwif *hwif = hwdev->hwif;
struct pci_dev *pdev = hwif->pdev;
struct hinic_sq *sq = txq->sq;
+ struct hinic_qp *qp;
int err;
+ qp = container_of(sq, struct hinic_qp, sq);
+
tx_napi_add(txq, nic_dev->tx_weight);
hinic_hwdev_msix_set(nic_dev->hwdev, sq->msix_entry,
@@ -731,6 +797,20 @@ static int tx_request_irq(struct hinic_txq *txq)
TX_IRQ_NO_LLI_TIMER, TX_IRQ_NO_CREDIT,
TX_IRQ_NO_RESEND_TIMER);
+ intr_coal = &nic_dev->tx_intr_coalesce[qp->q_id];
+ interrupt_info.msix_index = sq->msix_entry;
+ interrupt_info.coalesce_timer_cnt = intr_coal->coalesce_timer_cfg;
+ interrupt_info.pending_cnt = intr_coal->pending_limt;
+ interrupt_info.resend_timer_cnt = intr_coal->resend_timer_cfg;
+
+ err = hinic_set_interrupt_cfg(hwdev, &interrupt_info);
+ if (err) {
+ netif_err(nic_dev, drv, txq->netdev,
+ "Failed to set TX interrupt coalescing attribute\n");
+ tx_napi_del(txq);
+ return err;
+ }
+
err = request_irq(sq->irq, tx_irq, 0, txq->irq_name, txq);
if (err) {
dev_err(&pdev->dev, "Failed to request Tx irq\n");
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.h b/drivers/net/ethernet/huawei/hinic/hinic_tx.h
index f158b7db7fb8..b3c8657774a7 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.h
@@ -44,6 +44,8 @@ void hinic_txq_clean_stats(struct hinic_txq *txq);
void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats);
+netdev_tx_t hinic_lb_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+
netdev_tx_t hinic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
int hinic_init_txq(struct hinic_txq *txq, struct hinic_sq *sq,
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
index 48a8f9aa1dd0..5aa86318ed3e 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -34,7 +34,7 @@ config E100
to identify the adapter.
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/e100.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/e100.rst>.
To compile this driver as a module, choose M here. The module
will be called e100.
@@ -50,7 +50,7 @@ config E1000
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/e1000.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/e1000.rst>.
To compile this driver as a module, choose M here. The module
will be called e1000.
@@ -70,7 +70,7 @@ config E1000E
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/e1000e.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/e1000e.rst>.
To compile this driver as a module, choose M here. The module
will be called e1000e.
@@ -98,7 +98,7 @@ config IGB
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/igb.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/igb.rst>.
To compile this driver as a module, choose M here. The module
will be called igb.
@@ -134,7 +134,7 @@ config IGBVF
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/igbvf.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/igbvf.rst>.
To compile this driver as a module, choose M here. The module
will be called igbvf.
@@ -151,7 +151,7 @@ config IXGB
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/ixgb.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/ixgb.rst>.
To compile this driver as a module, choose M here. The module
will be called ixgb.
@@ -170,7 +170,7 @@ config IXGBE
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/ixgbe.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/ixgbe.rst>.
To compile this driver as a module, choose M here. The module
will be called ixgbe.
@@ -222,7 +222,7 @@ config IXGBEVF
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/ixgbevf.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/ixgbevf.rst>.
To compile this driver as a module, choose M here. The module
will be called ixgbevf. MSI-X interrupt support is required
@@ -249,7 +249,7 @@ config I40E
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/i40e.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/i40e.rst>.
To compile this driver as a module, choose M here. The module
will be called i40e.
@@ -284,7 +284,7 @@ config I40EVF
This driver was formerly named i40evf.
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/iavf.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/iavf.rst>.
To compile this driver as a module, choose M here. The module
will be called iavf. MSI-X interrupt support is required
@@ -295,6 +295,7 @@ config ICE
default n
depends on PCI_MSI
select NET_DEVLINK
+ select PLDMFW
help
This driver supports Intel(R) Ethernet Connection E800 Series of
devices. For more information on how to identify your adapter, go
@@ -303,7 +304,7 @@ config ICE
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/ice.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/ice.rst>.
To compile this driver as a module, choose M here. The module
will be called ice.
@@ -321,7 +322,7 @@ config FM10K
<http://support.intel.com>
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/intel/fm10k.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/intel/fm10k.rst>.
To compile this driver as a module, choose M here. The module
will be called fm10k. MSI-X interrupt support is required
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index 1b8d015ebfb0..36da059388dc 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -150,8 +150,6 @@
#define DRV_NAME "e100"
-#define DRV_EXT "-NAPI"
-#define DRV_VERSION "3.5.24-k2"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation"
@@ -165,7 +163,6 @@
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
MODULE_FIRMWARE(FIRMWARE_D101M);
MODULE_FIRMWARE(FIRMWARE_D101S);
MODULE_FIRMWARE(FIRMWARE_D102E);
@@ -2430,7 +2427,6 @@ static void e100_get_drvinfo(struct net_device *netdev,
{
struct nic *nic = netdev_priv(netdev);
strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
strlcpy(info->bus_info, pci_name(nic->pdev),
sizeof(info->bus_info));
}
@@ -2997,8 +2993,6 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake)
e100_down(nic);
netif_device_detach(netdev);
- pci_save_state(pdev);
-
if ((nic->flags & wol_magic) | e100_asf(nic)) {
/* enable reverse auto-negotiation */
if (nic->phy == phy_82552_v) {
@@ -3028,24 +3022,22 @@ static int __e100_power_off(struct pci_dev *pdev, bool wake)
return 0;
}
-#ifdef CONFIG_PM
-static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused e100_suspend(struct device *dev_d)
{
bool wake;
- __e100_shutdown(pdev, &wake);
- return __e100_power_off(pdev, wake);
+
+ __e100_shutdown(to_pci_dev(dev_d), &wake);
+
+ device_wakeup_disable(dev_d);
+
+ return 0;
}
-static int e100_resume(struct pci_dev *pdev)
+static int __maybe_unused e100_resume(struct device *dev_d)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
+ struct net_device *netdev = dev_get_drvdata(dev_d);
struct nic *nic = netdev_priv(netdev);
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- /* ack any pending wake events, disable PME */
- pci_enable_wake(pdev, PCI_D0, 0);
-
/* disable reverse auto-negotiation */
if (nic->phy == phy_82552_v) {
u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
@@ -3062,7 +3054,6 @@ static int e100_resume(struct pci_dev *pdev)
return 0;
}
-#endif /* CONFIG_PM */
static void e100_shutdown(struct pci_dev *pdev)
{
@@ -3150,16 +3141,17 @@ static const struct pci_error_handlers e100_err_handler = {
.resume = e100_io_resume,
};
+static SIMPLE_DEV_PM_OPS(e100_pm_ops, e100_suspend, e100_resume);
+
static struct pci_driver e100_driver = {
.name = DRV_NAME,
.id_table = e100_id_table,
.probe = e100_probe,
.remove = e100_remove,
-#ifdef CONFIG_PM
+
/* Power Management hooks */
- .suspend = e100_suspend,
- .resume = e100_resume,
-#endif
+ .driver.pm = &e100_pm_ops,
+
.shutdown = e100_shutdown,
.err_handler = &e100_err_handler,
};
@@ -3167,7 +3159,7 @@ static struct pci_driver e100_driver = {
static int __init e100_init_module(void)
{
if (((1 << debug) - 1) & NETIF_MSG_DRV) {
- pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
+ pr_info("%s\n", DRV_DESCRIPTION);
pr_info("%s\n", DRV_COPYRIGHT);
}
return pci_register_driver(&e100_driver);
diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h
index 7fad2f24dcad..4817eb13ca6f 100644
--- a/drivers/net/ethernet/intel/e1000/e1000.h
+++ b/drivers/net/ethernet/intel/e1000/e1000.h
@@ -330,7 +330,6 @@ struct net_device *e1000_get_hw_dev(struct e1000_hw *hw);
dev_err(&adapter->pdev->dev, format, ## arg)
extern char e1000_driver_name[];
-extern const char e1000_driver_version[];
int e1000_open(struct net_device *netdev);
int e1000_close(struct net_device *netdev);
diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
index 6f45df5690d4..f976e9daa3d8 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
@@ -533,8 +533,6 @@ static void e1000_get_drvinfo(struct net_device *netdev,
strlcpy(drvinfo->driver, e1000_driver_name,
sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, e1000_driver_version,
- sizeof(drvinfo->version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
@@ -1358,8 +1356,8 @@ static void e1000_create_lbtest_frame(struct sk_buff *skb,
memset(skb->data, 0xFF, frame_size);
frame_size &= ~1;
memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
- memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
- memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
+ skb->data[frame_size / 2 + 10] = 0xBE;
+ skb->data[frame_size / 2 + 12] = 0xAF;
}
static int e1000_check_lbtest_frame(const unsigned char *data,
diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.c b/drivers/net/ethernet/intel/e1000/e1000_hw.c
index 623e516a9630..4e7a0810eaeb 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_hw.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_hw.c
@@ -4526,7 +4526,7 @@ s32 e1000_setup_led(struct e1000_hw *hw)
~IGP01E1000_GMII_SPD));
if (ret_val)
return ret_val;
- /* Fall Through */
+ fallthrough;
default:
if (hw->media_type == e1000_media_type_fiber) {
ledctl = er32(LEDCTL);
@@ -4571,7 +4571,7 @@ s32 e1000_cleanup_led(struct e1000_hw *hw)
hw->phy_spd_default);
if (ret_val)
return ret_val;
- /* Fall Through */
+ fallthrough;
default:
/* Restore LEDCTL settings */
ew32(LEDCTL, hw->ledctl_default);
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 4b2de08137be..1e6ec081fd9d 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -10,8 +10,6 @@
char e1000_driver_name[] = "e1000";
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-#define DRV_VERSION "7.3.21-k8-NAPI"
-const char e1000_driver_version[] = DRV_VERSION;
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table
@@ -194,7 +192,6 @@ static struct pci_driver e1000_driver = {
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
static int debug = -1;
@@ -221,7 +218,7 @@ struct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
static int __init e1000_init_module(void)
{
int ret;
- pr_info("%s - version %s\n", e1000_driver_string, e1000_driver_version);
+ pr_info("%s\n", e1000_driver_string);
pr_info("%s\n", e1000_copyright);
@@ -1141,7 +1138,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
break;
}
- /* Fall Through */
+ fallthrough;
default:
e1000_read_eeprom(hw,
EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
@@ -3157,7 +3154,6 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
if ((unsigned long)(skb_tail_pointer(skb) - 1)
& 4)
break;
- /* fall through */
pull_size = min((unsigned int)4, skb->data_len);
if (!__pskb_pull_tail(skb, pull_size)) {
e_err(drv, "__pskb_pull_tail "
diff --git a/drivers/net/ethernet/intel/e1000/e1000_param.c b/drivers/net/ethernet/intel/e1000/e1000_param.c
index d3f29ffe1e47..4d4f5bf1e516 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_param.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_param.c
@@ -708,7 +708,7 @@ static void e1000_check_copper_options(struct e1000_adapter *adapter)
goto full_duplex_only;
case SPEED_1000 + HALF_DUPLEX:
e_dev_info("Half Duplex is not supported at 1000 Mbps\n");
- /* fall through */
+ fallthrough;
case SPEED_1000 + FULL_DUPLEX:
full_duplex_only:
e_dev_info("Using Autonegotiation at 1000 Mbps Full Duplex "
diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c
index 2c1bab377b2a..88faf05e23ba 100644
--- a/drivers/net/ethernet/intel/e1000e/82571.c
+++ b/drivers/net/ethernet/intel/e1000e/82571.c
@@ -154,7 +154,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
ew32(EECD, eecd);
break;
}
- /* Fall Through */
+ fallthrough;
default:
nvm->type = e1000_nvm_eeprom_spi;
size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
@@ -1107,7 +1107,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
switch (mac->type) {
case e1000_82573:
e1000e_enable_tx_pkt_filtering(hw);
- /* fall through */
+ fallthrough;
case e1000_82574:
case e1000_82583:
reg_data = er32(GCR);
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index 944abd5eae11..ba7a0f8f6937 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -460,7 +460,6 @@ enum latency_range {
};
extern char e1000e_driver_name[];
-extern const char e1000e_driver_version[];
void e1000e_check_options(struct e1000_adapter *adapter);
void e1000e_set_ethtool_ops(struct net_device *netdev);
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index 1d47e2503072..a8fc9208382c 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -633,8 +633,6 @@ static void e1000_get_drvinfo(struct net_device *netdev,
struct e1000_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, e1000e_driver_name, sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, e1000e_driver_version,
- sizeof(drvinfo->version));
/* EEPROM image version # is reported as firmware version # for
* PCI-E controllers
@@ -895,7 +893,6 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
case e1000_pch_lpt:
case e1000_pch_spt:
case e1000_pch_cnp:
- /* fall through */
case e1000_pch_tgp:
case e1000_pch_adp:
mask |= BIT(18);
@@ -1571,7 +1568,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
/* set bit 29 (value of MULR requests is now 0) */
tarc0 &= 0xcfffffff;
ew32(TARC(0), tarc0);
- /* fall through */
+ fallthrough;
case e1000_80003es2lan:
if (hw->phy.media_type == e1000_media_type_fiber ||
hw->phy.media_type == e1000_media_type_internal_serdes) {
@@ -1579,7 +1576,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
ew32(CTRL_EXT, adapter->tx_fifo_head);
adapter->tx_fifo_head = 0;
}
- /* fall through */
+ fallthrough;
case e1000_82571:
case e1000_82572:
if (hw->phy.media_type == e1000_media_type_fiber ||
@@ -1589,7 +1586,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
usleep_range(10000, 11000);
break;
}
- /* Fall Through */
+ fallthrough;
default:
hw->mac.autoneg = 1;
if (hw->phy.type == e1000_phy_gg82563)
@@ -1611,8 +1608,8 @@ static void e1000_create_lbtest_frame(struct sk_buff *skb,
memset(skb->data, 0xFF, frame_size);
frame_size &= ~1;
memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
- memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
- memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
+ skb->data[frame_size / 2 + 10] = 0xBE;
+ skb->data[frame_size / 2 + 12] = 0xAF;
}
static int e1000_check_lbtest_frame(struct sk_buff *skb,
@@ -2124,7 +2121,7 @@ static int e1000_get_rxnfc(struct net_device *netdev,
case TCP_V4_FLOW:
if (mrqc & E1000_MRQC_RSS_FIELD_IPV4_TCP)
info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fall through */
+ fallthrough;
case UDP_V4_FLOW:
case SCTP_V4_FLOW:
case AH_ESP_V4_FLOW:
@@ -2135,7 +2132,7 @@ static int e1000_get_rxnfc(struct net_device *netdev,
case TCP_V6_FLOW:
if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_TCP)
info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fall through */
+ fallthrough;
case UDP_V6_FLOW:
case SCTP_V6_FLOW:
case AH_ESP_V6_FLOW:
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 489bb5b59475..b2f2fcfdf732 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -336,12 +336,12 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
*/
msleep(50);
- /* fall-through */
+ fallthrough;
case e1000_pch2lan:
if (e1000_phy_is_accessible_pchlan(hw))
break;
- /* fall-through */
+ fallthrough;
case e1000_pchlan:
if ((hw->mac.type == e1000_pchlan) &&
(fwsm & E1000_ICH_FWSM_FW_VALID))
@@ -457,7 +457,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
return ret_val;
if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK))
break;
- /* fall-through */
+ fallthrough;
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
@@ -702,7 +702,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
case e1000_pch2lan:
mac->rar_entry_count = E1000_PCH2_RAR_ENTRIES;
mac->ops.rar_set = e1000_rar_set_pch2lan;
- /* fall-through */
+ fallthrough;
case e1000_pch_lpt:
case e1000_pch_spt:
case e1000_pch_cnp:
@@ -1557,7 +1557,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
ret_val = e1000_k1_workaround_lv(hw);
if (ret_val)
return ret_val;
- /* fall-thru */
+ fallthrough;
case e1000_pchlan:
if (hw->phy.type == e1000_phy_82578) {
ret_val = e1000_link_stall_workaround_hv(hw);
@@ -2094,7 +2094,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
break;
}
- /* Fall-thru */
+ fallthrough;
case e1000_pchlan:
case e1000_pch2lan:
case e1000_pch_lpt:
@@ -3187,7 +3187,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
return 0;
}
e_dbg("Unable to determine valid NVM bank via EEC - reading flash signature\n");
- /* fall-thru */
+ fallthrough;
default:
/* set bank to 0 in case flash read fails */
*bank = 0;
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 6f6479ca1267..63dde3bcf5bc 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -28,11 +28,7 @@
#include "e1000.h"
-#define DRV_EXTRAVERSION "-k"
-
-#define DRV_VERSION "3.2.6" DRV_EXTRAVERSION
char e1000e_driver_name[] = "e1000e";
-const char e1000e_driver_version[] = DRV_VERSION;
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
static int debug = -1;
@@ -2111,7 +2107,7 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
e1000e_reset_interrupt_capability(adapter);
}
adapter->int_mode = E1000E_INT_MODE_MSI;
- /* Fall through */
+ fallthrough;
case E1000E_INT_MODE_MSI:
if (!pci_enable_msi(adapter->pdev)) {
adapter->flags |= FLAG_MSI_ENABLED;
@@ -2119,7 +2115,7 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
adapter->int_mode = E1000E_INT_MODE_LEGACY;
e_err("Failed to initialize MSI interrupts. Falling back to legacy interrupts.\n");
}
- /* Fall through */
+ fallthrough;
case E1000E_INT_MODE_LEGACY:
/* Don't do anything; this is the system default */
break;
@@ -3177,10 +3173,10 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
switch (adapter->rx_ps_pages) {
case 3:
psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE3_SHIFT;
- /* fall-through */
+ fallthrough;
case 2:
psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE2_SHIFT;
- /* fall-through */
+ fallthrough;
case 1:
psrctl |= PAGE_SIZE >> E1000_PSRCTL_BSIZE1_SHIFT;
break;
@@ -3677,9 +3673,8 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
is_l2 = true;
break;
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
- /* Hardware cannot filter just V2 L4 Sync messages;
- * fall-through to V2 (both L2 and L4) Sync.
- */
+ /* Hardware cannot filter just V2 L4 Sync messages */
+ fallthrough;
case HWTSTAMP_FILTER_PTP_V2_SYNC:
/* Also time stamps V2 Path Delay Request/Response. */
tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
@@ -3688,9 +3683,8 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
is_l4 = true;
break;
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
- /* Hardware cannot filter just V2 L4 Delay Request messages;
- * fall-through to V2 (both L2 and L4) Delay Request.
- */
+ /* Hardware cannot filter just V2 L4 Delay Request messages */
+ fallthrough;
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
/* Also time stamps V2 Path Delay Request/Response. */
tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
@@ -3700,9 +3694,8 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
break;
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
- /* Hardware cannot filter just V2 L4 or L2 Event messages;
- * fall-through to all V2 (both L2 and L4) Events.
- */
+ /* Hardware cannot filter just V2 L4 or L2 Event messages */
+ fallthrough;
case HWTSTAMP_FILTER_PTP_V2_EVENT:
tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2;
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
@@ -3714,6 +3707,7 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
* Delay Request messages but not both so fall-through to
* time stamp all packets.
*/
+ fallthrough;
case HWTSTAMP_FILTER_NTP_ALL:
case HWTSTAMP_FILTER_ALL:
is_l2 = true;
@@ -4060,7 +4054,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
fc->low_water = fc->high_water - 8;
break;
}
- /* fall-through */
+ fallthrough;
default:
hwm = min(((pba << 10) * 9 / 10),
((pba << 10) - adapter->max_frame_size));
@@ -4085,7 +4079,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
case e1000_pch_lpt:
case e1000_pch_spt:
case e1000_pch_cnp:
- /* fall-through */
+ fallthrough;
case e1000_pch_tgp:
case e1000_pch_adp:
fc->refresh_time = 0xFFFF;
@@ -6768,7 +6762,7 @@ static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state, int locked)
case PCIE_LINK_STATE_L0S:
case PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1:
aspm_dis_mask |= PCI_EXP_LNKCTL_ASPM_L0S;
- /* fall-through - can't have L1 without L0s */
+ fallthrough; /* can't have L1 without L0s */
case PCIE_LINK_STATE_L1:
aspm_dis_mask |= PCI_EXP_LNKCTL_ASPM_L1;
break;
@@ -7899,8 +7893,7 @@ static struct pci_driver e1000_driver = {
**/
static int __init e1000_init_module(void)
{
- pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
- e1000e_driver_version);
+ pr_info("Intel(R) PRO/1000 Network Driver\n");
pr_info("Copyright(c) 1999 - 2015 Intel Corporation.\n");
return pci_register_driver(&e1000_driver);
@@ -7922,6 +7915,5 @@ module_exit(e1000_exit_module);
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
/* netdev.c */
diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c
index 098369fd3e65..ebe121db4307 100644
--- a/drivers/net/ethernet/intel/e1000e/param.c
+++ b/drivers/net/ethernet/intel/e1000e/param.c
@@ -375,7 +375,7 @@ void e1000e_check_options(struct e1000_adapter *adapter)
"%s Invalid mode - setting default\n",
opt.name);
adapter->itr_setting = opt.def;
- /* fall-through */
+ fallthrough;
case 3:
dev_info(&adapter->pdev->dev,
"%s set to dynamic conservative mode\n",
diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c
index 42233019255a..e11c877595fb 100644
--- a/drivers/net/ethernet/intel/e1000e/phy.c
+++ b/drivers/net/ethernet/intel/e1000e/phy.c
@@ -607,7 +607,7 @@ static s32 e1000_set_master_slave_mode(struct e1000_hw *hw)
break;
case e1000_ms_auto:
phy_data &= ~CTL1000_ENABLE_MASTER;
- /* fall-through */
+ fallthrough;
default:
break;
}
diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c
index 439fda2f5368..34b988d70488 100644
--- a/drivers/net/ethernet/intel/e1000e/ptp.c
+++ b/drivers/net/ethernet/intel/e1000e/ptp.c
@@ -295,7 +295,6 @@ void e1000e_ptp_init(struct e1000_adapter *adapter)
case e1000_pch_lpt:
case e1000_pch_spt:
case e1000_pch_cnp:
- /* fall-through */
case e1000_pch_tgp:
case e1000_pch_adp:
if ((hw->mac.type < e1000_pch_lpt) ||
@@ -303,7 +302,7 @@ void e1000e_ptp_init(struct e1000_adapter *adapter)
adapter->ptp_clock_info.max_adj = 24000000 - 1;
break;
}
- /* fall-through */
+ fallthrough;
case e1000_82574:
case e1000_82583:
adapter->ptp_clock_info.max_adj = 600000000 - 1;
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k.h b/drivers/net/ethernet/intel/fm10k/fm10k.h
index 5b78362b82ac..6119a4108838 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k.h
+++ b/drivers/net/ethernet/intel/fm10k/fm10k.h
@@ -221,12 +221,6 @@ struct fm10k_iov_data {
struct fm10k_vf_info vf_info[];
};
-struct fm10k_udp_port {
- struct list_head list;
- sa_family_t sa_family;
- __be16 port;
-};
-
enum fm10k_macvlan_request_type {
FM10K_UC_MAC_REQUEST,
FM10K_MC_MAC_REQUEST,
@@ -370,8 +364,8 @@ struct fm10k_intfc {
u32 rssrk[FM10K_RSSRK_SIZE];
/* UDP encapsulation port tracking information */
- struct list_head vxlan_port;
- struct list_head geneve_port;
+ __be16 vxlan_port;
+ __be16 geneve_port;
/* MAC/VLAN update queue */
struct list_head macvlan_requests;
@@ -476,7 +470,6 @@ struct fm10k_cb {
/* main */
extern char fm10k_driver_name[];
-extern const char fm10k_driver_version[];
int fm10k_init_queueing_scheme(struct fm10k_intfc *interface);
void fm10k_clear_queueing_scheme(struct fm10k_intfc *interface);
__be16 fm10k_tx_encap_offload(struct sk_buff *skb);
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
index 37fbc646deb9..908fefaa6b85 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
@@ -449,8 +449,6 @@ static void fm10k_get_drvinfo(struct net_device *dev,
strncpy(info->driver, fm10k_driver_name,
sizeof(info->driver) - 1);
- strncpy(info->version, fm10k_driver_version,
- sizeof(info->version) - 1);
strncpy(info->bus_info, pci_name(interface->pdev),
sizeof(info->bus_info) - 1);
}
@@ -694,12 +692,12 @@ static int fm10k_get_rss_hash_opts(struct fm10k_intfc *interface,
case TCP_V4_FLOW:
case TCP_V6_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fall through */
+ fallthrough;
case UDP_V4_FLOW:
if (test_bit(FM10K_FLAG_RSS_FIELD_IPV4_UDP,
interface->flags))
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fall through */
+ fallthrough;
case SCTP_V4_FLOW:
case SCTP_V6_FLOW:
case AH_ESP_V4_FLOW:
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
index 17738b0a9873..d88dd41a9442 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -11,9 +11,7 @@
#include "fm10k.h"
-#define DRV_VERSION "0.27.1-k"
#define DRV_SUMMARY "Intel(R) Ethernet Switch Host Interface Driver"
-const char fm10k_driver_version[] = DRV_VERSION;
char fm10k_driver_name[] = "fm10k";
static const char fm10k_driver_string[] = DRV_SUMMARY;
static const char fm10k_copyright[] =
@@ -22,7 +20,6 @@ static const char fm10k_copyright[] =
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION(DRV_SUMMARY);
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
/* single workqueue for entire fm10k driver */
struct workqueue_struct *fm10k_workqueue;
@@ -35,7 +32,7 @@ struct workqueue_struct *fm10k_workqueue;
**/
static int __init fm10k_init_module(void)
{
- pr_info("%s - version %s\n", fm10k_driver_string, fm10k_driver_version);
+ pr_info("%s\n", fm10k_driver_string);
pr_info("%s\n", fm10k_copyright);
/* create driver workqueue */
@@ -638,15 +635,8 @@ static int fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
static struct ethhdr *fm10k_port_is_vxlan(struct sk_buff *skb)
{
struct fm10k_intfc *interface = netdev_priv(skb->dev);
- struct fm10k_udp_port *vxlan_port;
- /* we can only offload a vxlan if we recognize it as such */
- vxlan_port = list_first_entry_or_null(&interface->vxlan_port,
- struct fm10k_udp_port, list);
-
- if (!vxlan_port)
- return NULL;
- if (vxlan_port->port != udp_hdr(skb)->dest)
+ if (interface->vxlan_port != udp_hdr(skb)->dest)
return NULL;
/* return offset of udp_hdr plus 8 bytes for VXLAN header */
@@ -859,7 +849,7 @@ static void fm10k_tx_csum(struct fm10k_ring *tx_ring,
case IPPROTO_GRE:
if (skb->encapsulation)
break;
- /* fall through */
+ fallthrough;
default:
if (unlikely(net_ratelimit())) {
dev_warn(tx_ring->dev,
@@ -1557,7 +1547,7 @@ static bool fm10k_set_rss_queues(struct fm10k_intfc *interface)
* important, starting with the "most" number of features turned on at once,
* and ending with the smallest set of features. This way large combinations
* can be allocated if they're turned on, and smaller combinations are the
- * fallthrough conditions.
+ * fall through conditions.
*
**/
static void fm10k_set_num_queues(struct fm10k_intfc *interface)
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
index 75e51f91036c..8e2e92bf3cd4 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
@@ -967,7 +967,7 @@ static s32 fm10k_mbx_validate_msg_hdr(struct fm10k_mbx_info *mbx)
if (tail != mbx->head)
return FM10K_MBX_ERR_TAIL;
- /* fall through */
+ fallthrough;
case FM10K_MSG_DATA:
/* validate that head is moving correctly */
if (!head || (head == FM10K_MSG_HDR_MASK(HEAD)))
@@ -987,7 +987,7 @@ static s32 fm10k_mbx_validate_msg_hdr(struct fm10k_mbx_info *mbx)
if ((size < FM10K_VFMBX_MSG_MTU) || (size & (size + 1)))
return FM10K_MBX_ERR_SIZE;
- /* fall through */
+ fallthrough;
case FM10K_MSG_ERROR:
if (!head || (head == FM10K_MSG_HDR_MASK(HEAD)))
return FM10K_MBX_ERR_HEAD;
@@ -1570,7 +1570,7 @@ s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx,
mbx->mbmem_reg = FM10K_MBMEM_VF(id, 0);
break;
}
- /* fall through */
+ fallthrough;
default:
return FM10K_MBX_ERR_NO_MBX;
}
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
index 0637ccadee79..5c19ff452558 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
@@ -367,39 +367,6 @@ static void fm10k_request_glort_range(struct fm10k_intfc *interface)
}
/**
- * fm10k_free_udp_port_info
- * @interface: board private structure
- *
- * This function frees both geneve_port and vxlan_port structures
- **/
-static void fm10k_free_udp_port_info(struct fm10k_intfc *interface)
-{
- struct fm10k_udp_port *port;
-
- /* flush all entries from vxlan list */
- port = list_first_entry_or_null(&interface->vxlan_port,
- struct fm10k_udp_port, list);
- while (port) {
- list_del(&port->list);
- kfree(port);
- port = list_first_entry_or_null(&interface->vxlan_port,
- struct fm10k_udp_port,
- list);
- }
-
- /* flush all entries from geneve list */
- port = list_first_entry_or_null(&interface->geneve_port,
- struct fm10k_udp_port, list);
- while (port) {
- list_del(&port->list);
- kfree(port);
- port = list_first_entry_or_null(&interface->vxlan_port,
- struct fm10k_udp_port,
- list);
- }
-}
-
-/**
* fm10k_restore_udp_port_info
* @interface: board private structure
*
@@ -408,131 +375,52 @@ static void fm10k_free_udp_port_info(struct fm10k_intfc *interface)
static void fm10k_restore_udp_port_info(struct fm10k_intfc *interface)
{
struct fm10k_hw *hw = &interface->hw;
- struct fm10k_udp_port *port;
/* only the PF supports configuring tunnels */
if (hw->mac.type != fm10k_mac_pf)
return;
- port = list_first_entry_or_null(&interface->vxlan_port,
- struct fm10k_udp_port, list);
-
/* restore tunnel configuration register */
fm10k_write_reg(hw, FM10K_TUNNEL_CFG,
- (port ? ntohs(port->port) : 0) |
+ ntohs(interface->vxlan_port) |
(ETH_P_TEB << FM10K_TUNNEL_CFG_NVGRE_SHIFT));
- port = list_first_entry_or_null(&interface->geneve_port,
- struct fm10k_udp_port, list);
-
/* restore Geneve tunnel configuration register */
fm10k_write_reg(hw, FM10K_TUNNEL_CFG_GENEVE,
- (port ? ntohs(port->port) : 0));
-}
-
-static struct fm10k_udp_port *
-fm10k_remove_tunnel_port(struct list_head *ports,
- struct udp_tunnel_info *ti)
-{
- struct fm10k_udp_port *port;
-
- list_for_each_entry(port, ports, list) {
- if ((port->port == ti->port) &&
- (port->sa_family == ti->sa_family)) {
- list_del(&port->list);
- return port;
- }
- }
-
- return NULL;
-}
-
-static void fm10k_insert_tunnel_port(struct list_head *ports,
- struct udp_tunnel_info *ti)
-{
- struct fm10k_udp_port *port;
-
- /* remove existing port entry from the list so that the newest items
- * are always at the tail of the list.
- */
- port = fm10k_remove_tunnel_port(ports, ti);
- if (!port) {
- port = kmalloc(sizeof(*port), GFP_ATOMIC);
- if (!port)
- return;
- port->port = ti->port;
- port->sa_family = ti->sa_family;
- }
-
- list_add_tail(&port->list, ports);
+ ntohs(interface->geneve_port));
}
/**
- * fm10k_udp_tunnel_add
+ * fm10k_udp_tunnel_sync - Called when UDP tunnel ports change
* @dev: network interface device structure
- * @ti: Tunnel endpoint information
+ * @table: Tunnel table (according to tables of @fm10k_udp_tunnels)
*
- * This function is called when a new UDP tunnel port has been added.
+ * This function is called when a new UDP tunnel port is added or deleted.
* Due to hardware restrictions, only one port per type can be offloaded at
- * once.
+ * once. Core will send to the driver a port of its choice.
**/
-static void fm10k_udp_tunnel_add(struct net_device *dev,
- struct udp_tunnel_info *ti)
+static int fm10k_udp_tunnel_sync(struct net_device *dev, unsigned int table)
{
struct fm10k_intfc *interface = netdev_priv(dev);
+ struct udp_tunnel_info ti;
- /* only the PF supports configuring tunnels */
- if (interface->hw.mac.type != fm10k_mac_pf)
- return;
-
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- fm10k_insert_tunnel_port(&interface->vxlan_port, ti);
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- fm10k_insert_tunnel_port(&interface->geneve_port, ti);
- break;
- default:
- return;
- }
+ udp_tunnel_nic_get_port(dev, table, 0, &ti);
+ if (!table)
+ interface->vxlan_port = ti.port;
+ else
+ interface->geneve_port = ti.port;
fm10k_restore_udp_port_info(interface);
+ return 0;
}
-/**
- * fm10k_udp_tunnel_del
- * @dev: network interface device structure
- * @ti: Tunnel end point information
- *
- * This function is called when a new UDP tunnel port is deleted. The freed
- * port will be removed from the list, then we reprogram the offloaded port
- * based on the head of the list.
- **/
-static void fm10k_udp_tunnel_del(struct net_device *dev,
- struct udp_tunnel_info *ti)
-{
- struct fm10k_intfc *interface = netdev_priv(dev);
- struct fm10k_udp_port *port = NULL;
-
- if (interface->hw.mac.type != fm10k_mac_pf)
- return;
-
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- port = fm10k_remove_tunnel_port(&interface->vxlan_port, ti);
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- port = fm10k_remove_tunnel_port(&interface->geneve_port, ti);
- break;
- default:
- return;
- }
-
- /* if we did remove a port we need to free its memory */
- kfree(port);
-
- fm10k_restore_udp_port_info(interface);
-}
+static const struct udp_tunnel_nic_info fm10k_udp_tunnels = {
+ .sync_table = fm10k_udp_tunnel_sync,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+ },
+};
/**
* fm10k_open - Called when a network interface is made active
@@ -580,8 +468,6 @@ int fm10k_open(struct net_device *netdev)
if (err)
goto err_set_queues;
- udp_tunnel_get_rx_info(netdev);
-
fm10k_up(interface);
return 0;
@@ -615,8 +501,6 @@ int fm10k_close(struct net_device *netdev)
fm10k_qv_free_irq(interface);
- fm10k_free_udp_port_info(interface);
-
fm10k_free_all_tx_resources(interface);
fm10k_free_all_rx_resources(interface);
@@ -853,7 +737,7 @@ void fm10k_clear_macvlan_queue(struct fm10k_intfc *interface,
/* Don't free requests for other interfaces */
if (r->mac.glort != glort)
break;
- /* fall through */
+ fallthrough;
case FM10K_VLAN_REQUEST:
if (vlans) {
list_del(&r->list);
@@ -1647,8 +1531,8 @@ static const struct net_device_ops fm10k_netdev_ops = {
.ndo_set_vf_rate = fm10k_ndo_set_vf_bw,
.ndo_get_vf_config = fm10k_ndo_get_vf_config,
.ndo_get_vf_stats = fm10k_ndo_get_vf_stats,
- .ndo_udp_tunnel_add = fm10k_udp_tunnel_add,
- .ndo_udp_tunnel_del = fm10k_udp_tunnel_del,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_dfwd_add_station = fm10k_dfwd_add_station,
.ndo_dfwd_del_station = fm10k_dfwd_del_station,
.ndo_features_check = fm10k_features_check,
@@ -1695,6 +1579,8 @@ struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info)
NETIF_F_SG;
dev->features |= NETIF_F_GSO_UDP_TUNNEL;
+
+ dev->udp_tunnel_nic_info = &fm10k_udp_tunnels;
}
/* all features defined to this point should be changeable */
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
index d122d0087191..140212bfe08b 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -2066,10 +2066,6 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
interface->tx_itr = FM10K_TX_ITR_DEFAULT;
interface->rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
- /* initialize udp port lists */
- INIT_LIST_HEAD(&interface->vxlan_port);
- INIT_LIST_HEAD(&interface->geneve_port);
-
/* Initialize the MAC/VLAN queue */
INIT_LIST_HEAD(&interface->macvlan_requests);
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
index be07bfdb0bb4..c0780c3624c8 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
@@ -1317,19 +1317,19 @@ static u8 fm10k_iov_supported_xcast_mode_pf(struct fm10k_vf_info *vf_info,
case FM10K_XCAST_MODE_PROMISC:
if (vf_flags & FM10K_VF_FLAG_PROMISC_CAPABLE)
return FM10K_XCAST_MODE_PROMISC;
- /* fall through */
+ fallthrough;
case FM10K_XCAST_MODE_ALLMULTI:
if (vf_flags & FM10K_VF_FLAG_ALLMULTI_CAPABLE)
return FM10K_XCAST_MODE_ALLMULTI;
- /* fall through */
+ fallthrough;
case FM10K_XCAST_MODE_MULTI:
if (vf_flags & FM10K_VF_FLAG_MULTI_CAPABLE)
return FM10K_XCAST_MODE_MULTI;
- /* fall through */
+ fallthrough;
case FM10K_XCAST_MODE_NONE:
if (vf_flags & FM10K_VF_FLAG_NONE_CAPABLE)
return FM10K_XCAST_MODE_NONE;
- /* fall through */
+ fallthrough;
default:
break;
}
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index e95b8da45e07..a7e212d1caa2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -38,7 +38,7 @@
#include <net/xdp_sock.h>
#include "i40e_type.h"
#include "i40e_prototype.h"
-#include "i40e_client.h"
+#include <linux/net/intel/i40e_client.h>
#include <linux/avf/virtchnl.h>
#include "i40e_virtchnl_pf.h"
#include "i40e_txrx.h"
@@ -60,17 +60,14 @@
(((pf)->hw_features & I40E_HW_RSS_AQ_CAPABLE) ? 4 : 1)
#define I40E_DEFAULT_QUEUES_PER_VF 4
#define I40E_MAX_VF_QUEUES 16
-#define I40E_DEFAULT_QUEUES_PER_TC 1 /* should be a power of 2 */
#define i40e_pf_get_max_q_per_tc(pf) \
(((pf)->hw_features & I40E_HW_128_QP_RSS_CAPABLE) ? 128 : 64)
-#define I40E_FDIR_RING 0
#define I40E_FDIR_RING_COUNT 32
#define I40E_MAX_AQ_BUF_SIZE 4096
#define I40E_AQ_LEN 256
#define I40E_AQ_WORK_LIMIT 66 /* max number of VFs + a little */
#define I40E_MAX_USER_PRIORITY 8
#define I40E_DEFAULT_TRAFFIC_CLASS BIT(0)
-#define I40E_DEFAULT_MSG_ENABLE 4
#define I40E_QUEUE_WAIT_RETRY_LIMIT 10
#define I40E_INT_NAME_STR_LEN (IFNAMSIZ + 16)
@@ -92,10 +89,6 @@
#define I40E_OEM_SNAP_SHIFT 16
#define I40E_OEM_RELEASE_MASK 0x0000ffff
-/* The values in here are decimal coded as hex as is the case in the NVM map*/
-#define I40E_CURRENT_NVM_VERSION_HI 0x2
-#define I40E_CURRENT_NVM_VERSION_LO 0x40
-
#define I40E_RX_DESC(R, i) \
(&(((union i40e_32byte_rx_desc *)((R)->desc))[i]))
#define I40E_TX_DESC(R, i) \
@@ -105,9 +98,6 @@
#define I40E_TX_FDIRDESC(R, i) \
(&(((struct i40e_filter_program_desc *)((R)->desc))[i]))
-/* default to trying for four seconds */
-#define I40E_TRY_LINK_TIMEOUT (4 * HZ)
-
/* BW rate limiting */
#define I40E_BW_CREDIT_DIVISOR 50 /* 50Mbps per BW credit */
#define I40E_BW_MBPS_DIVISOR 125000 /* rate / (1000000 / 8) Mbps */
@@ -295,9 +285,6 @@ struct i40e_cloud_filter {
u8 tunnel_type;
};
-#define I40E_DCB_PRIO_TYPE_STRICT 0
-#define I40E_DCB_PRIO_TYPE_ETS 1
-#define I40E_DCB_STRICT_PRIO_CREDITS 127
/* DCB per TC information data structure */
struct i40e_tc_info {
u16 qoffset; /* Queue offset from base queue */
@@ -357,15 +344,6 @@ struct i40e_ddp_old_profile_list {
I40E_FLEX_SET_FSIZE(fsize) | \
I40E_FLEX_SET_SRC_WORD(src))
-#define I40E_FLEX_PIT_GET_SRC(flex) (((flex) & \
- I40E_PRTQF_FLX_PIT_SOURCE_OFF_MASK) >> \
- I40E_PRTQF_FLX_PIT_SOURCE_OFF_SHIFT)
-#define I40E_FLEX_PIT_GET_DST(flex) (((flex) & \
- I40E_PRTQF_FLX_PIT_DEST_OFF_MASK) >> \
- I40E_PRTQF_FLX_PIT_DEST_OFF_SHIFT)
-#define I40E_FLEX_PIT_GET_FSIZE(flex) (((flex) & \
- I40E_PRTQF_FLX_PIT_FSIZE_MASK) >> \
- I40E_PRTQF_FLX_PIT_FSIZE_SHIFT)
#define I40E_MAX_FLEX_SRC_OFFSET 0x1F
@@ -390,7 +368,6 @@ struct i40e_ddp_old_profile_list {
#define I40E_L4_GLQF_ORT_IDX 35
/* Flex PIT register index */
-#define I40E_FLEX_PIT_IDX_START_L2 0
#define I40E_FLEX_PIT_IDX_START_L3 3
#define I40E_FLEX_PIT_IDX_START_L4 6
@@ -531,7 +508,6 @@ struct i40e_pf {
#define I40E_HW_GENEVE_OFFLOAD_CAPABLE BIT(9)
#define I40E_HW_PTP_L4_CAPABLE BIT(10)
#define I40E_HW_WOL_MC_MAGIC_PKT_WAKE BIT(11)
-#define I40E_HW_MPLS_HDR_OFFLOAD_CAPABLE BIT(12)
#define I40E_HW_HAVE_CRT_RETIMER BIT(13)
#define I40E_HW_OUTER_UDP_CSUM_CAPABLE BIT(14)
#define I40E_HW_PHY_CONTROLS_LEDS BIT(15)
@@ -567,6 +543,28 @@ struct i40e_pf {
#define I40E_FLAG_DISABLE_FW_LLDP BIT(24)
#define I40E_FLAG_RS_FEC BIT(25)
#define I40E_FLAG_BASE_R_FEC BIT(26)
+/* TOTAL_PORT_SHUTDOWN
+ * Allows to physically disable the link on the NIC's port.
+ * If enabled, (after link down request from the OS)
+ * no link, traffic or led activity is possible on that port.
+ *
+ * If I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED is set, the
+ * I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED must be explicitly forced to true
+ * and cannot be disabled by system admin at that time.
+ * The functionalities are exclusive in terms of configuration, but they also
+ * have similar behavior (allowing to disable physical link of the port),
+ * with following differences:
+ * - LINK_DOWN_ON_CLOSE_ENABLED is configurable at host OS run-time and is
+ * supported by whole family of 7xx Intel Ethernet Controllers
+ * - TOTAL_PORT_SHUTDOWN may be enabled only before OS loads (in BIOS)
+ * only if motherboard's BIOS and NIC's FW has support of it
+ * - when LINK_DOWN_ON_CLOSE_ENABLED is used, the link is being brought down
+ * by sending phy_type=0 to NIC's FW
+ * - when TOTAL_PORT_SHUTDOWN is used, phy_type is not altered, instead
+ * the link is being brought down by clearing bit (I40E_AQ_PHY_ENABLE_LINK)
+ * in abilities field of i40e_aq_set_phy_config structure
+ */
+#define I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED BIT(27)
struct i40e_client_instance *cinst;
bool stat_offsets_loaded;
@@ -992,7 +990,6 @@ static inline void i40e_write_fd_input_set(struct i40e_pf *pf,
int i40e_up(struct i40e_vsi *vsi);
void i40e_down(struct i40e_vsi *vsi);
extern const char i40e_driver_name[];
-extern const char i40e_driver_version_str[];
void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags);
void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags, bool lock_acquired);
int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index 6a089848c857..c897a2863e4f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -541,7 +541,7 @@ static void i40e_set_hw_flags(struct i40e_hw *hw)
(aq->api_maj_ver == 1 &&
aq->api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_X722))
hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE;
- /* fall through */
+ fallthrough;
default:
break;
}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
index aa5f1c0aa721..a62ddd626929 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
@@ -55,29 +55,17 @@ struct i40e_aq_desc {
*/
/* command flags and offsets*/
-#define I40E_AQ_FLAG_DD_SHIFT 0
-#define I40E_AQ_FLAG_CMP_SHIFT 1
#define I40E_AQ_FLAG_ERR_SHIFT 2
-#define I40E_AQ_FLAG_VFE_SHIFT 3
#define I40E_AQ_FLAG_LB_SHIFT 9
#define I40E_AQ_FLAG_RD_SHIFT 10
-#define I40E_AQ_FLAG_VFC_SHIFT 11
#define I40E_AQ_FLAG_BUF_SHIFT 12
#define I40E_AQ_FLAG_SI_SHIFT 13
-#define I40E_AQ_FLAG_EI_SHIFT 14
-#define I40E_AQ_FLAG_FE_SHIFT 15
-#define I40E_AQ_FLAG_DD BIT(I40E_AQ_FLAG_DD_SHIFT) /* 0x1 */
-#define I40E_AQ_FLAG_CMP BIT(I40E_AQ_FLAG_CMP_SHIFT) /* 0x2 */
#define I40E_AQ_FLAG_ERR BIT(I40E_AQ_FLAG_ERR_SHIFT) /* 0x4 */
-#define I40E_AQ_FLAG_VFE BIT(I40E_AQ_FLAG_VFE_SHIFT) /* 0x8 */
#define I40E_AQ_FLAG_LB BIT(I40E_AQ_FLAG_LB_SHIFT) /* 0x200 */
#define I40E_AQ_FLAG_RD BIT(I40E_AQ_FLAG_RD_SHIFT) /* 0x400 */
-#define I40E_AQ_FLAG_VFC BIT(I40E_AQ_FLAG_VFC_SHIFT) /* 0x800 */
#define I40E_AQ_FLAG_BUF BIT(I40E_AQ_FLAG_BUF_SHIFT) /* 0x1000 */
#define I40E_AQ_FLAG_SI BIT(I40E_AQ_FLAG_SI_SHIFT) /* 0x2000 */
-#define I40E_AQ_FLAG_EI BIT(I40E_AQ_FLAG_EI_SHIFT) /* 0x4000 */
-#define I40E_AQ_FLAG_FE BIT(I40E_AQ_FLAG_FE_SHIFT) /* 0x8000 */
/* error codes */
enum i40e_admin_queue_err {
@@ -362,13 +350,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_pf_context);
/* Request resource ownership (direct 0x0008)
* Release resource ownership (direct 0x0009)
*/
-#define I40E_AQ_RESOURCE_NVM 1
-#define I40E_AQ_RESOURCE_SDP 2
-#define I40E_AQ_RESOURCE_ACCESS_READ 1
-#define I40E_AQ_RESOURCE_ACCESS_WRITE 2
-#define I40E_AQ_RESOURCE_NVM_READ_TIMEOUT 3000
-#define I40E_AQ_RESOURCE_NVM_WRITE_TIMEOUT 180000
-
struct i40e_aqc_request_resource {
__le16 resource_id;
__le16 access_type;
@@ -384,7 +365,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_request_resource);
*/
struct i40e_aqc_list_capabilites {
u8 command_flags;
-#define I40E_AQ_LIST_CAP_PF_INDEX_EN 1
u8 pf_index;
u8 reserved[2];
__le32 count;
@@ -411,8 +391,6 @@ struct i40e_aqc_list_capabilities_element_resp {
#define I40E_AQ_CAP_ID_NPAR_ACTIVE 0x0003
#define I40E_AQ_CAP_ID_OS2BMC_CAP 0x0004
#define I40E_AQ_CAP_ID_FUNCTIONS_VALID 0x0005
-#define I40E_AQ_CAP_ID_ALTERNATE_RAM 0x0006
-#define I40E_AQ_CAP_ID_WOL_AND_PROXY 0x0008
#define I40E_AQ_CAP_ID_SRIOV 0x0012
#define I40E_AQ_CAP_ID_VF 0x0013
#define I40E_AQ_CAP_ID_VMDQ 0x0014
@@ -441,11 +419,6 @@ struct i40e_aqc_list_capabilities_element_resp {
/* Set CPPM Configuration (direct 0x0103) */
struct i40e_aqc_cppm_configuration {
__le16 command_flags;
-#define I40E_AQ_CPPM_EN_LTRC 0x0800
-#define I40E_AQ_CPPM_EN_DMCTH 0x1000
-#define I40E_AQ_CPPM_EN_DMCTLX 0x2000
-#define I40E_AQ_CPPM_EN_HPTC 0x4000
-#define I40E_AQ_CPPM_EN_DMARC 0x8000
__le16 ttlx;
__le32 dmacr;
__le16 dmcth;
@@ -459,15 +432,8 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_cppm_configuration);
/* Set ARP Proxy command / response (indirect 0x0104) */
struct i40e_aqc_arp_proxy_data {
__le16 command_flags;
-#define I40E_AQ_ARP_INIT_IPV4 0x0800
-#define I40E_AQ_ARP_UNSUP_CTL 0x1000
-#define I40E_AQ_ARP_ENA 0x2000
-#define I40E_AQ_ARP_ADD_IPV4 0x4000
-#define I40E_AQ_ARP_DEL_IPV4 0x8000
__le16 table_id;
__le32 enabled_offloads;
-#define I40E_AQ_ARP_DIRECTED_OFFLOAD_ENABLE 0x00000020
-#define I40E_AQ_ARP_OFFLOAD_ENABLE 0x00000800
__le32 ip_addr;
u8 mac_addr[6];
u8 reserved[2];
@@ -482,19 +448,6 @@ struct i40e_aqc_ns_proxy_data {
__le16 table_idx_ipv6_0;
__le16 table_idx_ipv6_1;
__le16 control;
-#define I40E_AQ_NS_PROXY_ADD_0 0x0001
-#define I40E_AQ_NS_PROXY_DEL_0 0x0002
-#define I40E_AQ_NS_PROXY_ADD_1 0x0004
-#define I40E_AQ_NS_PROXY_DEL_1 0x0008
-#define I40E_AQ_NS_PROXY_ADD_IPV6_0 0x0010
-#define I40E_AQ_NS_PROXY_DEL_IPV6_0 0x0020
-#define I40E_AQ_NS_PROXY_ADD_IPV6_1 0x0040
-#define I40E_AQ_NS_PROXY_DEL_IPV6_1 0x0080
-#define I40E_AQ_NS_PROXY_COMMAND_SEQ 0x0100
-#define I40E_AQ_NS_PROXY_INIT_IPV6_TBL 0x0200
-#define I40E_AQ_NS_PROXY_INIT_MAC_TBL 0x0400
-#define I40E_AQ_NS_PROXY_OFFLOAD_ENABLE 0x0800
-#define I40E_AQ_NS_PROXY_DIRECTED_OFFLOAD_ENABLE 0x1000
u8 mac_addr_0[6];
u8 mac_addr_1[6];
u8 local_mac_addr[6];
@@ -507,7 +460,6 @@ I40E_CHECK_STRUCT_LEN(0x3c, i40e_aqc_ns_proxy_data);
/* Manage LAA Command (0x0106) - obsolete */
struct i40e_aqc_mng_laa {
__le16 command_flags;
-#define I40E_AQ_LAA_FLAG_WR 0x8000
u8 reserved[2];
__le32 sal;
__le16 sah;
@@ -520,11 +472,7 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_mng_laa);
struct i40e_aqc_mac_address_read {
__le16 command_flags;
#define I40E_AQC_LAN_ADDR_VALID 0x10
-#define I40E_AQC_SAN_ADDR_VALID 0x20
#define I40E_AQC_PORT_ADDR_VALID 0x40
-#define I40E_AQC_WOL_ADDR_VALID 0x80
-#define I40E_AQC_MC_MAG_EN_VALID 0x100
-#define I40E_AQC_ADDR_VALID_MASK 0x3F0
u8 reserved[6];
__le32 addr_high;
__le32 addr_low;
@@ -548,9 +496,7 @@ struct i40e_aqc_mac_address_write {
#define I40E_AQC_WOL_PRESERVE_ON_PFR 0x0200
#define I40E_AQC_WRITE_TYPE_LAA_ONLY 0x0000
#define I40E_AQC_WRITE_TYPE_LAA_WOL 0x4000
-#define I40E_AQC_WRITE_TYPE_PORT 0x8000
#define I40E_AQC_WRITE_TYPE_UPDATE_MC_MAG 0xC000
-#define I40E_AQC_WRITE_TYPE_MASK 0xC000
__le16 mac_sah;
__le32 mac_sal;
@@ -573,22 +519,9 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_clear_pxe);
struct i40e_aqc_set_wol_filter {
__le16 filter_index;
-#define I40E_AQC_MAX_NUM_WOL_FILTERS 8
-#define I40E_AQC_SET_WOL_FILTER_TYPE_MAGIC_SHIFT 15
-#define I40E_AQC_SET_WOL_FILTER_TYPE_MAGIC_MASK (0x1 << \
- I40E_AQC_SET_WOL_FILTER_TYPE_MAGIC_SHIFT)
-
-#define I40E_AQC_SET_WOL_FILTER_INDEX_SHIFT 0
-#define I40E_AQC_SET_WOL_FILTER_INDEX_MASK (0x7 << \
- I40E_AQC_SET_WOL_FILTER_INDEX_SHIFT)
+
__le16 cmd_flags;
-#define I40E_AQC_SET_WOL_FILTER 0x8000
-#define I40E_AQC_SET_WOL_FILTER_NO_TCO_WOL 0x4000
-#define I40E_AQC_SET_WOL_FILTER_ACTION_CLEAR 0
-#define I40E_AQC_SET_WOL_FILTER_ACTION_SET 1
__le16 valid_flags;
-#define I40E_AQC_SET_WOL_FILTER_ACTION_VALID 0x8000
-#define I40E_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID 0x4000
u8 reserved[2];
__le32 address_high;
__le32 address_low;
@@ -608,12 +541,6 @@ I40E_CHECK_STRUCT_LEN(0x90, i40e_aqc_set_wol_filter_data);
struct i40e_aqc_get_wake_reason_completion {
u8 reserved_1[2];
__le16 wake_reason;
-#define I40E_AQC_GET_WAKE_UP_REASON_WOL_REASON_MATCHED_INDEX_SHIFT 0
-#define I40E_AQC_GET_WAKE_UP_REASON_WOL_REASON_MATCHED_INDEX_MASK (0xFF << \
- I40E_AQC_GET_WAKE_UP_REASON_WOL_REASON_MATCHED_INDEX_SHIFT)
-#define I40E_AQC_GET_WAKE_UP_REASON_WOL_REASON_RESERVED_SHIFT 8
-#define I40E_AQC_GET_WAKE_UP_REASON_WOL_REASON_RESERVED_MASK (0xFF << \
- I40E_AQC_GET_WAKE_UP_REASON_WOL_REASON_RESERVED_SHIFT)
u8 reserved_2[12];
};
@@ -646,25 +573,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_get_switch_config_header_resp);
struct i40e_aqc_switch_config_element_resp {
u8 element_type;
-#define I40E_AQ_SW_ELEM_TYPE_MAC 1
-#define I40E_AQ_SW_ELEM_TYPE_PF 2
-#define I40E_AQ_SW_ELEM_TYPE_VF 3
-#define I40E_AQ_SW_ELEM_TYPE_EMP 4
-#define I40E_AQ_SW_ELEM_TYPE_BMC 5
-#define I40E_AQ_SW_ELEM_TYPE_PV 16
-#define I40E_AQ_SW_ELEM_TYPE_VEB 17
-#define I40E_AQ_SW_ELEM_TYPE_PA 18
-#define I40E_AQ_SW_ELEM_TYPE_VSI 19
u8 revision;
-#define I40E_AQ_SW_ELEM_REV_1 1
__le16 seid;
__le16 uplink_seid;
__le16 downlink_seid;
u8 reserved[3];
u8 connection_type;
-#define I40E_AQ_CONN_TYPE_REGULAR 0x1
-#define I40E_AQ_CONN_TYPE_DEFAULT 0x2
-#define I40E_AQ_CONN_TYPE_CASCADED 0x3
__le16 scheduler_id;
__le16 element_info;
};
@@ -697,12 +611,7 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_statistics);
/* Set Port Parameters command (direct 0x0203) */
struct i40e_aqc_set_port_parameters {
__le16 command_flags;
-#define I40E_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS 1
-#define I40E_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS 2 /* must set! */
-#define I40E_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA 4
__le16 bad_frame_vsi;
-#define I40E_AQ_SET_P_PARAMS_BFRAME_SEID_SHIFT 0x0
-#define I40E_AQ_SET_P_PARAMS_BFRAME_SEID_MASK 0x3FF
__le16 default_seid; /* reserved for command */
u8 reserved[10];
};
@@ -722,25 +631,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_get_switch_resource_alloc);
/* expect an array of these structs in the response buffer */
struct i40e_aqc_switch_resource_alloc_element_resp {
u8 resource_type;
-#define I40E_AQ_RESOURCE_TYPE_VEB 0x0
-#define I40E_AQ_RESOURCE_TYPE_VSI 0x1
-#define I40E_AQ_RESOURCE_TYPE_MACADDR 0x2
-#define I40E_AQ_RESOURCE_TYPE_STAG 0x3
-#define I40E_AQ_RESOURCE_TYPE_ETAG 0x4
-#define I40E_AQ_RESOURCE_TYPE_MULTICAST_HASH 0x5
-#define I40E_AQ_RESOURCE_TYPE_UNICAST_HASH 0x6
-#define I40E_AQ_RESOURCE_TYPE_VLAN 0x7
-#define I40E_AQ_RESOURCE_TYPE_VSI_LIST_ENTRY 0x8
-#define I40E_AQ_RESOURCE_TYPE_ETAG_LIST_ENTRY 0x9
-#define I40E_AQ_RESOURCE_TYPE_VLAN_STAT_POOL 0xA
-#define I40E_AQ_RESOURCE_TYPE_MIRROR_RULE 0xB
-#define I40E_AQ_RESOURCE_TYPE_QUEUE_SETS 0xC
-#define I40E_AQ_RESOURCE_TYPE_VLAN_FILTERS 0xD
-#define I40E_AQ_RESOURCE_TYPE_INNER_MAC_FILTERS 0xF
-#define I40E_AQ_RESOURCE_TYPE_IP_FILTERS 0x10
-#define I40E_AQ_RESOURCE_TYPE_GRE_VN_KEYS 0x11
-#define I40E_AQ_RESOURCE_TYPE_VN2_KEYS 0x12
-#define I40E_AQ_RESOURCE_TYPE_TUNNEL_PORTS 0x13
u8 reserved1;
__le16 guaranteed;
__le16 total;
@@ -756,7 +646,6 @@ struct i40e_aqc_set_switch_config {
__le16 flags;
/* flags used for both fields below */
#define I40E_AQ_SET_SWITCH_CFG_PROMISC 0x0001
-#define I40E_AQ_SET_SWITCH_CFG_L2_FILTER 0x0002
__le16 valid_flags;
/* The ethertype in switch_tag is dropped on ingress and used
* internally by the switch. Set this to zero for the default
@@ -789,17 +678,10 @@ struct i40e_aqc_set_switch_config {
*/
#define I40E_AQ_SET_SWITCH_BIT7_VALID 0x80
-#define I40E_AQ_SET_SWITCH_L4_SRC_PORT 0x40
-#define I40E_AQ_SET_SWITCH_L4_TYPE_RSVD 0x00
#define I40E_AQ_SET_SWITCH_L4_TYPE_TCP 0x10
-#define I40E_AQ_SET_SWITCH_L4_TYPE_UDP 0x20
-#define I40E_AQ_SET_SWITCH_L4_TYPE_BOTH 0x30
-#define I40E_AQ_SET_SWITCH_MODE_DEFAULT 0x00
-#define I40E_AQ_SET_SWITCH_MODE_L4_PORT 0x01
#define I40E_AQ_SET_SWITCH_MODE_NON_TUNNEL 0x02
-#define I40E_AQ_SET_SWITCH_MODE_TUNNEL 0x03
u8 mode;
u8 rsvd5[5];
};
@@ -834,19 +716,13 @@ struct i40e_aqc_add_get_update_vsi {
__le16 uplink_seid;
u8 connection_type;
#define I40E_AQ_VSI_CONN_TYPE_NORMAL 0x1
-#define I40E_AQ_VSI_CONN_TYPE_DEFAULT 0x2
-#define I40E_AQ_VSI_CONN_TYPE_CASCADED 0x3
u8 reserved1;
u8 vf_id;
u8 reserved2;
__le16 vsi_flags;
-#define I40E_AQ_VSI_TYPE_SHIFT 0x0
-#define I40E_AQ_VSI_TYPE_MASK (0x3 << I40E_AQ_VSI_TYPE_SHIFT)
#define I40E_AQ_VSI_TYPE_VF 0x0
#define I40E_AQ_VSI_TYPE_VMDQ2 0x1
#define I40E_AQ_VSI_TYPE_PF 0x2
-#define I40E_AQ_VSI_TYPE_EMP_MNG 0x3
-#define I40E_AQ_VSI_FLAG_CASCADED_PV 0x4
__le32 addr_high;
__le32 addr_low;
};
@@ -870,24 +746,18 @@ struct i40e_aqc_vsi_properties_data {
#define I40E_AQ_VSI_PROP_SWITCH_VALID 0x0001
#define I40E_AQ_VSI_PROP_SECURITY_VALID 0x0002
#define I40E_AQ_VSI_PROP_VLAN_VALID 0x0004
-#define I40E_AQ_VSI_PROP_CAS_PV_VALID 0x0008
-#define I40E_AQ_VSI_PROP_INGRESS_UP_VALID 0x0010
-#define I40E_AQ_VSI_PROP_EGRESS_UP_VALID 0x0020
#define I40E_AQ_VSI_PROP_QUEUE_MAP_VALID 0x0040
#define I40E_AQ_VSI_PROP_QUEUE_OPT_VALID 0x0080
-#define I40E_AQ_VSI_PROP_OUTER_UP_VALID 0x0100
#define I40E_AQ_VSI_PROP_SCHED_VALID 0x0200
/* switch section */
__le16 switch_id; /* 12bit id combined with flags below */
#define I40E_AQ_VSI_SW_ID_SHIFT 0x0000
#define I40E_AQ_VSI_SW_ID_MASK (0xFFF << I40E_AQ_VSI_SW_ID_SHIFT)
-#define I40E_AQ_VSI_SW_ID_FLAG_NOT_STAG 0x1000
#define I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB 0x2000
#define I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB 0x4000
u8 sw_reserved[2];
/* security section */
u8 sec_flags;
-#define I40E_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD 0x01
#define I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK 0x02
#define I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK 0x04
u8 sec_reserved;
@@ -899,78 +769,33 @@ struct i40e_aqc_vsi_properties_data {
#define I40E_AQ_VSI_PVLAN_MODE_MASK (0x03 << \
I40E_AQ_VSI_PVLAN_MODE_SHIFT)
#define I40E_AQ_VSI_PVLAN_MODE_TAGGED 0x01
-#define I40E_AQ_VSI_PVLAN_MODE_UNTAGGED 0x02
#define I40E_AQ_VSI_PVLAN_MODE_ALL 0x03
#define I40E_AQ_VSI_PVLAN_INSERT_PVID 0x04
#define I40E_AQ_VSI_PVLAN_EMOD_SHIFT 0x03
#define I40E_AQ_VSI_PVLAN_EMOD_MASK (0x3 << \
I40E_AQ_VSI_PVLAN_EMOD_SHIFT)
#define I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH 0x0
-#define I40E_AQ_VSI_PVLAN_EMOD_STR_UP 0x08
#define I40E_AQ_VSI_PVLAN_EMOD_STR 0x10
#define I40E_AQ_VSI_PVLAN_EMOD_NOTHING 0x18
u8 pvlan_reserved[3];
/* ingress egress up sections */
__le32 ingress_table; /* bitmap, 3 bits per up */
-#define I40E_AQ_VSI_UP_TABLE_UP0_SHIFT 0
-#define I40E_AQ_VSI_UP_TABLE_UP0_MASK (0x7 << \
- I40E_AQ_VSI_UP_TABLE_UP0_SHIFT)
-#define I40E_AQ_VSI_UP_TABLE_UP1_SHIFT 3
-#define I40E_AQ_VSI_UP_TABLE_UP1_MASK (0x7 << \
- I40E_AQ_VSI_UP_TABLE_UP1_SHIFT)
-#define I40E_AQ_VSI_UP_TABLE_UP2_SHIFT 6
-#define I40E_AQ_VSI_UP_TABLE_UP2_MASK (0x7 << \
- I40E_AQ_VSI_UP_TABLE_UP2_SHIFT)
-#define I40E_AQ_VSI_UP_TABLE_UP3_SHIFT 9
-#define I40E_AQ_VSI_UP_TABLE_UP3_MASK (0x7 << \
- I40E_AQ_VSI_UP_TABLE_UP3_SHIFT)
-#define I40E_AQ_VSI_UP_TABLE_UP4_SHIFT 12
-#define I40E_AQ_VSI_UP_TABLE_UP4_MASK (0x7 << \
- I40E_AQ_VSI_UP_TABLE_UP4_SHIFT)
-#define I40E_AQ_VSI_UP_TABLE_UP5_SHIFT 15
-#define I40E_AQ_VSI_UP_TABLE_UP5_MASK (0x7 << \
- I40E_AQ_VSI_UP_TABLE_UP5_SHIFT)
-#define I40E_AQ_VSI_UP_TABLE_UP6_SHIFT 18
-#define I40E_AQ_VSI_UP_TABLE_UP6_MASK (0x7 << \
- I40E_AQ_VSI_UP_TABLE_UP6_SHIFT)
-#define I40E_AQ_VSI_UP_TABLE_UP7_SHIFT 21
-#define I40E_AQ_VSI_UP_TABLE_UP7_MASK (0x7 << \
- I40E_AQ_VSI_UP_TABLE_UP7_SHIFT)
__le32 egress_table; /* same defines as for ingress table */
/* cascaded PV section */
__le16 cas_pv_tag;
u8 cas_pv_flags;
-#define I40E_AQ_VSI_CAS_PV_TAGX_SHIFT 0x00
-#define I40E_AQ_VSI_CAS_PV_TAGX_MASK (0x03 << \
- I40E_AQ_VSI_CAS_PV_TAGX_SHIFT)
-#define I40E_AQ_VSI_CAS_PV_TAGX_LEAVE 0x00
-#define I40E_AQ_VSI_CAS_PV_TAGX_REMOVE 0x01
-#define I40E_AQ_VSI_CAS_PV_TAGX_COPY 0x02
-#define I40E_AQ_VSI_CAS_PV_INSERT_TAG 0x10
-#define I40E_AQ_VSI_CAS_PV_ETAG_PRUNE 0x20
-#define I40E_AQ_VSI_CAS_PV_ACCEPT_HOST_TAG 0x40
u8 cas_pv_reserved;
/* queue mapping section */
__le16 mapping_flags;
#define I40E_AQ_VSI_QUE_MAP_CONTIG 0x0
#define I40E_AQ_VSI_QUE_MAP_NONCONTIG 0x1
__le16 queue_mapping[16];
-#define I40E_AQ_VSI_QUEUE_SHIFT 0x0
-#define I40E_AQ_VSI_QUEUE_MASK (0x7FF << I40E_AQ_VSI_QUEUE_SHIFT)
__le16 tc_mapping[8];
#define I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT 0
-#define I40E_AQ_VSI_TC_QUE_OFFSET_MASK (0x1FF << \
- I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT)
#define I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT 9
-#define I40E_AQ_VSI_TC_QUE_NUMBER_MASK (0x7 << \
- I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT)
/* queueing option section */
u8 queueing_opt_flags;
-#define I40E_AQ_VSI_QUE_OPT_MULTICAST_UDP_ENA 0x04
-#define I40E_AQ_VSI_QUE_OPT_UNICAST_UDP_ENA 0x08
#define I40E_AQ_VSI_QUE_OPT_TCP_ENA 0x10
-#define I40E_AQ_VSI_QUE_OPT_FCOE_ENA 0x20
-#define I40E_AQ_VSI_QUE_OPT_RSS_LUT_PF 0x00
#define I40E_AQ_VSI_QUE_OPT_RSS_LUT_VSI 0x40
u8 queueing_opt_reserved[3];
/* scheduler section */
@@ -995,10 +820,6 @@ I40E_CHECK_STRUCT_LEN(128, i40e_aqc_vsi_properties_data);
*/
struct i40e_aqc_add_update_pv {
__le16 command_flags;
-#define I40E_AQC_PV_FLAG_PV_TYPE 0x1
-#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_STAG_EN 0x2
-#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_ETAG_EN 0x4
-#define I40E_AQC_PV_FLAG_IS_CTRL_PORT 0x8
__le16 uplink_seid;
__le16 connected_seid;
u8 reserved[10];
@@ -1009,10 +830,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_update_pv);
struct i40e_aqc_add_update_pv_completion {
/* reserved for update; for add also encodes error if rc == ENOSPC */
__le16 pv_seid;
-#define I40E_AQC_PV_ERR_FLAG_NO_PV 0x1
-#define I40E_AQC_PV_ERR_FLAG_NO_SCHED 0x2
-#define I40E_AQC_PV_ERR_FLAG_NO_COUNTER 0x4
-#define I40E_AQC_PV_ERR_FLAG_NO_ENTRY 0x8
u8 reserved[14];
};
@@ -1026,9 +843,6 @@ struct i40e_aqc_get_pv_params_completion {
__le16 seid;
__le16 default_stag;
__le16 pv_flags; /* same flags as add_pv */
-#define I40E_AQC_GET_PV_PV_TYPE 0x1
-#define I40E_AQC_GET_PV_FRWD_UNKNOWN_STAG 0x2
-#define I40E_AQC_GET_PV_FRWD_UNKNOWN_ETAG 0x4
u8 reserved[8];
__le16 default_port_seid;
};
@@ -1041,12 +855,8 @@ struct i40e_aqc_add_veb {
__le16 downlink_seid;
__le16 veb_flags;
#define I40E_AQC_ADD_VEB_FLOATING 0x1
-#define I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT 1
-#define I40E_AQC_ADD_VEB_PORT_TYPE_MASK (0x3 << \
- I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT)
#define I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT 0x2
#define I40E_AQC_ADD_VEB_PORT_TYPE_DATA 0x4
-#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER 0x8 /* deprecated */
#define I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS 0x10
u8 enable_tcs;
u8 reserved[9];
@@ -1059,10 +869,6 @@ struct i40e_aqc_add_veb_completion {
__le16 switch_seid;
/* also encodes error if rc == ENOSPC; codes are the same as add_pv */
__le16 veb_seid;
-#define I40E_AQC_VEB_ERR_FLAG_NO_VEB 0x1
-#define I40E_AQC_VEB_ERR_FLAG_NO_SCHED 0x2
-#define I40E_AQC_VEB_ERR_FLAG_NO_COUNTER 0x4
-#define I40E_AQC_VEB_ERR_FLAG_NO_ENTRY 0x8
__le16 statistic_index;
__le16 vebs_used;
__le16 vebs_free;
@@ -1095,9 +901,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_get_veb_parameters_completion);
struct i40e_aqc_macvlan {
__le16 num_addresses;
__le16 seid[3];
-#define I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT 0
-#define I40E_AQC_MACVLAN_CMD_SEID_NUM_MASK (0x3FF << \
- I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT)
#define I40E_AQC_MACVLAN_CMD_SEID_VALID 0x8000
__le32 addr_high;
__le32 addr_low;
@@ -1111,18 +914,11 @@ struct i40e_aqc_add_macvlan_element_data {
__le16 vlan_tag;
__le16 flags;
#define I40E_AQC_MACVLAN_ADD_PERFECT_MATCH 0x0001
-#define I40E_AQC_MACVLAN_ADD_HASH_MATCH 0x0002
#define I40E_AQC_MACVLAN_ADD_IGNORE_VLAN 0x0004
-#define I40E_AQC_MACVLAN_ADD_TO_QUEUE 0x0008
#define I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC 0x0010
__le16 queue_number;
-#define I40E_AQC_MACVLAN_CMD_QUEUE_SHIFT 0
-#define I40E_AQC_MACVLAN_CMD_QUEUE_MASK (0x7FF << \
- I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT)
/* response section */
u8 match_method;
-#define I40E_AQC_MM_PERFECT_MATCH 0x01
-#define I40E_AQC_MM_HASH_MATCH 0x02
#define I40E_AQC_MM_ERR_NO_RES 0xFF
u8 reserved1[3];
};
@@ -1148,14 +944,10 @@ struct i40e_aqc_remove_macvlan_element_data {
__le16 vlan_tag;
u8 flags;
#define I40E_AQC_MACVLAN_DEL_PERFECT_MATCH 0x01
-#define I40E_AQC_MACVLAN_DEL_HASH_MATCH 0x02
#define I40E_AQC_MACVLAN_DEL_IGNORE_VLAN 0x08
-#define I40E_AQC_MACVLAN_DEL_ALL_VSIS 0x10
u8 reserved[3];
/* reply section */
u8 error_code;
-#define I40E_AQC_REMOVE_MACVLAN_SUCCESS 0x0
-#define I40E_AQC_REMOVE_MACVLAN_FAIL 0xFF
u8 reply_reserved[3];
};
@@ -1166,30 +958,8 @@ struct i40e_aqc_remove_macvlan_element_data {
struct i40e_aqc_add_remove_vlan_element_data {
__le16 vlan_tag;
u8 vlan_flags;
-/* flags for add VLAN */
-#define I40E_AQC_ADD_VLAN_LOCAL 0x1
-#define I40E_AQC_ADD_PVLAN_TYPE_SHIFT 1
-#define I40E_AQC_ADD_PVLAN_TYPE_MASK (0x3 << I40E_AQC_ADD_PVLAN_TYPE_SHIFT)
-#define I40E_AQC_ADD_PVLAN_TYPE_REGULAR 0x0
-#define I40E_AQC_ADD_PVLAN_TYPE_PRIMARY 0x2
-#define I40E_AQC_ADD_PVLAN_TYPE_SECONDARY 0x4
-#define I40E_AQC_VLAN_PTYPE_SHIFT 3
-#define I40E_AQC_VLAN_PTYPE_MASK (0x3 << I40E_AQC_VLAN_PTYPE_SHIFT)
-#define I40E_AQC_VLAN_PTYPE_REGULAR_VSI 0x0
-#define I40E_AQC_VLAN_PTYPE_PROMISC_VSI 0x8
-#define I40E_AQC_VLAN_PTYPE_COMMUNITY_VSI 0x10
-#define I40E_AQC_VLAN_PTYPE_ISOLATED_VSI 0x18
-/* flags for remove VLAN */
-#define I40E_AQC_REMOVE_VLAN_ALL 0x1
u8 reserved;
u8 result;
-/* flags for add VLAN */
-#define I40E_AQC_ADD_VLAN_SUCCESS 0x0
-#define I40E_AQC_ADD_VLAN_FAIL_REQUEST 0xFE
-#define I40E_AQC_ADD_VLAN_FAIL_RESOURCE 0xFF
-/* flags for remove VLAN */
-#define I40E_AQC_REMOVE_VLAN_SUCCESS 0x0
-#define I40E_AQC_REMOVE_VLAN_FAIL 0xFF
u8 reserved1[3];
};
@@ -1213,9 +983,7 @@ struct i40e_aqc_set_vsi_promiscuous_modes {
#define I40E_AQC_SET_VSI_PROMISC_VLAN 0x10
#define I40E_AQC_SET_VSI_PROMISC_TX 0x8000
__le16 seid;
-#define I40E_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF
__le16 vlan_tag;
-#define I40E_AQC_SET_VSI_VLAN_MASK 0x0FFF
#define I40E_AQC_SET_VSI_VLAN_VALID 0x8000
u8 reserved[8];
};
@@ -1227,11 +995,7 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_vsi_promiscuous_modes);
*/
struct i40e_aqc_add_tag {
__le16 flags;
-#define I40E_AQC_ADD_TAG_FLAG_TO_QUEUE 0x0001
__le16 seid;
-#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT 0
-#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_MASK (0x3FF << \
- I40E_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT)
__le16 tag;
__le16 queue_number;
u8 reserved[8];
@@ -1252,9 +1016,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_tag_completion);
*/
struct i40e_aqc_remove_tag {
__le16 seid;
-#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT 0
-#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_MASK (0x3FF << \
- I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT)
__le16 tag;
u8 reserved[12];
};
@@ -1290,9 +1051,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_mcast_etag_completion);
/* Update S/E-Tag (direct 0x0259) */
struct i40e_aqc_update_tag {
__le16 seid;
-#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT 0
-#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_MASK (0x3FF << \
- I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT)
__le16 old_tag;
__le16 new_tag;
u8 reserved[10];
@@ -1319,13 +1077,8 @@ struct i40e_aqc_add_remove_control_packet_filter {
__le16 flags;
#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC 0x0001
#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP 0x0002
-#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE 0x0004
#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX 0x0008
-#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_RX 0x0000
__le16 seid;
-#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT 0
-#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_MASK (0x3FF << \
- I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT)
__le16 queue;
u8 reserved[2];
};
@@ -1351,9 +1104,6 @@ struct i40e_aqc_add_remove_cloud_filters {
u8 num_filters;
u8 reserved;
__le16 seid;
-#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT 0
-#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_MASK (0x3FF << \
- I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT)
u8 big_buffer_flag;
#define I40E_AQC_ADD_CLOUD_CMD_BB 1
u8 reserved2[3];
@@ -1380,9 +1130,6 @@ struct i40e_aqc_cloud_filters_element_data {
} raw_v6;
} ipaddr;
__le16 flags;
-#define I40E_AQC_ADD_CLOUD_FILTER_SHIFT 0
-#define I40E_AQC_ADD_CLOUD_FILTER_MASK (0x3F << \
- I40E_AQC_ADD_CLOUD_FILTER_SHIFT)
/* 0x0000 reserved */
/* 0x0001 reserved */
/* 0x0002 reserved */
@@ -1404,36 +1151,20 @@ struct i40e_aqc_cloud_filters_element_data {
#define I40E_AQC_ADD_CLOUD_FILTER_MAC_PORT 0x0011 /* Dest MAC + L4 Port */
#define I40E_AQC_ADD_CLOUD_FILTER_MAC_VLAN_PORT 0x0012 /* Dest MAC + VLAN + L4 Port */
-#define I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE 0x0080
-#define I40E_AQC_ADD_CLOUD_VNK_SHIFT 6
-#define I40E_AQC_ADD_CLOUD_VNK_MASK 0x00C0
#define I40E_AQC_ADD_CLOUD_FLAGS_IPV4 0
#define I40E_AQC_ADD_CLOUD_FLAGS_IPV6 0x0100
#define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT 9
#define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK 0x1E00
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN 0
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC 1
#define I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE 2
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP 3
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_RESERVED 4
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN_GPE 5
-#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_MAC 0x2000
-#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_INNER_MAC 0x4000
-#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_IP 0x8000
__le32 tenant_id;
u8 reserved[4];
__le16 queue_number;
-#define I40E_AQC_ADD_CLOUD_QUEUE_SHIFT 0
-#define I40E_AQC_ADD_CLOUD_QUEUE_MASK (0x7FF << \
- I40E_AQC_ADD_CLOUD_QUEUE_SHIFT)
u8 reserved2[14];
/* response section */
u8 allocation_result;
-#define I40E_AQC_ADD_CLOUD_FILTER_SUCCESS 0x0
-#define I40E_AQC_ADD_CLOUD_FILTER_FAIL 0xFF
u8 response_reserved[7];
};
@@ -1445,37 +1176,7 @@ I40E_CHECK_STRUCT_LEN(0x40, i40e_aqc_cloud_filters_element_data);
struct i40e_aqc_cloud_filters_element_bb {
struct i40e_aqc_cloud_filters_element_data element;
u16 general_fields[32];
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD0 0
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1 1
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD2 2
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0 3
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1 4
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2 5
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD0 6
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD1 7
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD2 8
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD0 9
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD1 10
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD2 11
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X14_WORD0 12
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X14_WORD1 13
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X14_WORD2 14
#define I40E_AQC_ADD_CLOUD_FV_FLU_0X16_WORD0 15
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X16_WORD1 16
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X16_WORD2 17
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X16_WORD3 18
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X16_WORD4 19
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X16_WORD5 20
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X16_WORD6 21
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X16_WORD7 22
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X17_WORD0 23
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X17_WORD1 24
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X17_WORD2 25
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X17_WORD3 26
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X17_WORD4 27
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X17_WORD5 28
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X17_WORD6 29
-#define I40E_AQC_ADD_CLOUD_FV_FLU_0X17_WORD7 30
};
I40E_CHECK_STRUCT_LEN(0x80, i40e_aqc_cloud_filters_element_bb);
@@ -1504,11 +1205,6 @@ I40E_CHECK_STRUCT_LEN(4, i40e_filter_data);
struct i40e_aqc_replace_cloud_filters_cmd {
u8 valid_flags;
-#define I40E_AQC_REPLACE_L1_FILTER 0x0
-#define I40E_AQC_REPLACE_CLOUD_FILTER 0x1
-#define I40E_AQC_GET_CLOUD_FILTERS 0x2
-#define I40E_AQC_MIRROR_CLOUD_FILTER 0x4
-#define I40E_AQC_HIGH_PRIORITY_CLOUD_FILTER 0x8
u8 old_filter_type;
u8 new_filter_type;
u8 tr_bit;
@@ -1521,25 +1217,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_replace_cloud_filters_cmd);
struct i40e_aqc_replace_cloud_filters_cmd_buf {
u8 data[32];
-/* Filter type INPUT codes*/
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_ENTRIES_MAX 3
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED BIT(7)
-
-/* Field Vector offsets */
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_MAC_DA 0
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_ETH 6
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG 7
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_VLAN 8
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_OVLAN 9
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_IVLAN 10
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TUNNLE_KEY 11
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC 12
-/* big FLU */
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IP_DA 14
-/* big FLU */
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_OIP_DA 15
-
-#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_INNER_VLAN 37
struct i40e_filter_data filters[8];
};
@@ -1556,8 +1233,6 @@ struct i40e_aqc_add_delete_mirror_rule {
#define I40E_AQC_MIRROR_RULE_TYPE_SHIFT 0
#define I40E_AQC_MIRROR_RULE_TYPE_MASK (0x7 << \
I40E_AQC_MIRROR_RULE_TYPE_SHIFT)
-#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS 1
-#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS 2
#define I40E_AQC_MIRROR_RULE_TYPE_VLAN 3
#define I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS 4
#define I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS 5
@@ -1600,8 +1275,6 @@ struct i40e_aqc_write_ddp_resp {
struct i40e_aqc_get_applied_profiles {
u8 flags;
-#define I40E_AQC_GET_DDP_GET_CONF 0x1
-#define I40E_AQC_GET_DDP_GET_RDPU_CONF 0x2
u8 rsv[3];
__le32 reserved;
__le32 addr_high;
@@ -1618,8 +1291,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_get_applied_profiles);
struct i40e_aqc_pfc_ignore {
u8 tc_bitmap;
u8 command_flags; /* unused on response */
-#define I40E_AQC_PFC_IGNORE_SET 0x80
-#define I40E_AQC_PFC_IGNORE_CLEAR 0x0
u8 reserved[14];
};
@@ -1736,7 +1407,6 @@ struct i40e_aqc_configure_switching_comp_ets_data {
u8 reserved[4];
u8 tc_valid_bits;
u8 seepage;
-#define I40E_AQ_ETS_SEEPAGE_EN_MASK 0x1
u8 tc_strict_priority_flags;
u8 reserved1[17];
u8 tc_bw_share_credits[8];
@@ -1977,40 +1647,18 @@ struct i40e_aq_get_phy_abilities_resp {
u8 abilities;
#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01
#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02
-#define I40E_AQ_PHY_FLAG_LOW_POWER 0x04
-#define I40E_AQ_PHY_LINK_ENABLED 0x08
-#define I40E_AQ_PHY_AN_ENABLED 0x10
-#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20
-#define I40E_AQ_PHY_FEC_ABILITY_KR 0x40
-#define I40E_AQ_PHY_FEC_ABILITY_RS 0x80
__le16 eee_capability;
-#define I40E_AQ_EEE_100BASE_TX 0x0002
-#define I40E_AQ_EEE_1000BASE_T 0x0004
-#define I40E_AQ_EEE_10GBASE_T 0x0008
-#define I40E_AQ_EEE_1000BASE_KX 0x0010
-#define I40E_AQ_EEE_10GBASE_KX4 0x0020
-#define I40E_AQ_EEE_10GBASE_KR 0x0040
__le32 eeer_val;
u8 d3_lpan;
-#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01
u8 phy_type_ext;
#define I40E_AQ_PHY_TYPE_EXT_25G_KR 0X01
#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
-#define I40E_AQ_PHY_TYPE_EXT_25G_AOC 0x10
-#define I40E_AQ_PHY_TYPE_EXT_25G_ACC 0x20
-#define I40E_AQ_PHY_TYPE_EXT_2_5GBASE_T 0x40
-#define I40E_AQ_PHY_TYPE_EXT_5GBASE_T 0x80
u8 fec_cfg_curr_mod_ext_info;
-#define I40E_AQ_ENABLE_FEC_KR 0x01
-#define I40E_AQ_ENABLE_FEC_RS 0x02
#define I40E_AQ_REQUEST_FEC_KR 0x04
#define I40E_AQ_REQUEST_FEC_RS 0x08
#define I40E_AQ_ENABLE_FEC_AUTO 0x10
-#define I40E_AQ_FEC
-#define I40E_AQ_MODULE_TYPE_EXT_MASK 0xE0
-#define I40E_AQ_MODULE_TYPE_EXT_SHIFT 5
u8 ext_comp_code;
u8 phy_id[4];
@@ -2056,21 +1704,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config);
struct i40e_aq_set_mac_config {
__le16 max_frame_size;
u8 params;
-#define I40E_AQ_SET_MAC_CONFIG_CRC_EN 0x04
-#define I40E_AQ_SET_MAC_CONFIG_PACING_MASK 0x78
-#define I40E_AQ_SET_MAC_CONFIG_PACING_SHIFT 3
-#define I40E_AQ_SET_MAC_CONFIG_PACING_NONE 0x0
-#define I40E_AQ_SET_MAC_CONFIG_PACING_1B_13TX 0xF
-#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_9TX 0x9
-#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_4TX 0x8
-#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_7TX 0x7
-#define I40E_AQ_SET_MAC_CONFIG_PACING_2DW_3TX 0x6
-#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_1TX 0x5
-#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_2TX 0x4
-#define I40E_AQ_SET_MAC_CONFIG_PACING_7DW_3TX 0x3
-#define I40E_AQ_SET_MAC_CONFIG_PACING_4DW_1TX 0x2
-#define I40E_AQ_SET_MAC_CONFIG_PACING_9DW_1TX 0x1
-#define I40E_AQ_SET_MAC_CONFIG_DROP_BLOCKING_PACKET_EN 0x80
u8 tx_timer_priority; /* bitmap */
__le16 tx_timer_value;
__le16 fc_refresh_threshold;
@@ -2092,8 +1725,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_link_restart_an);
/* Get Link Status cmd & response data structure (direct 0x0607) */
struct i40e_aqc_get_link_status {
__le16 command_flags; /* only field set on command */
-#define I40E_AQ_LSE_MASK 0x3
-#define I40E_AQ_LSE_NOP 0x0
#define I40E_AQ_LSE_DISABLE 0x2
#define I40E_AQ_LSE_ENABLE 0x3
/* only response uses this flag */
@@ -2102,44 +1733,16 @@ struct i40e_aqc_get_link_status {
u8 link_speed; /* i40e_aq_link_speed */
u8 link_info;
#define I40E_AQ_LINK_UP 0x01 /* obsolete */
-#define I40E_AQ_LINK_UP_FUNCTION 0x01
-#define I40E_AQ_LINK_FAULT 0x02
-#define I40E_AQ_LINK_FAULT_TX 0x04
-#define I40E_AQ_LINK_FAULT_RX 0x08
-#define I40E_AQ_LINK_FAULT_REMOTE 0x10
-#define I40E_AQ_LINK_UP_PORT 0x20
#define I40E_AQ_MEDIA_AVAILABLE 0x40
-#define I40E_AQ_SIGNAL_DETECT 0x80
u8 an_info;
#define I40E_AQ_AN_COMPLETED 0x01
-#define I40E_AQ_LP_AN_ABILITY 0x02
-#define I40E_AQ_PD_FAULT 0x04
-#define I40E_AQ_FEC_EN 0x08
-#define I40E_AQ_PHY_LOW_POWER 0x10
#define I40E_AQ_LINK_PAUSE_TX 0x20
#define I40E_AQ_LINK_PAUSE_RX 0x40
#define I40E_AQ_QUALIFIED_MODULE 0x80
u8 ext_info;
-#define I40E_AQ_LINK_PHY_TEMP_ALARM 0x01
-#define I40E_AQ_LINK_XCESSIVE_ERRORS 0x02
-#define I40E_AQ_LINK_TX_SHIFT 0x02
-#define I40E_AQ_LINK_TX_MASK (0x03 << I40E_AQ_LINK_TX_SHIFT)
-#define I40E_AQ_LINK_TX_ACTIVE 0x00
-#define I40E_AQ_LINK_TX_DRAINED 0x01
-#define I40E_AQ_LINK_TX_FLUSHED 0x03
-#define I40E_AQ_LINK_FORCED_40G 0x10
-/* 25G Error Codes */
-#define I40E_AQ_25G_NO_ERR 0X00
-#define I40E_AQ_25G_NOT_PRESENT 0X01
-#define I40E_AQ_25G_NVM_CRC_ERR 0X02
-#define I40E_AQ_25G_SBUS_UCODE_ERR 0X03
-#define I40E_AQ_25G_SERDES_UCODE_ERR 0X04
-#define I40E_AQ_25G_NIMB_UCODE_ERR 0X05
u8 loopback; /* use defines from i40e_aqc_set_lb_mode */
/* Since firmware API 1.7 loopback field keeps power class info as well */
#define I40E_AQ_LOOPBACK_MASK 0x07
-#define I40E_AQ_PWR_CLASS_SHIFT_LB 6
-#define I40E_AQ_PWR_CLASS_MASK_LB (0x03 << I40E_AQ_PWR_CLASS_SHIFT_LB)
__le16 max_frame_size;
u8 config;
#define I40E_AQ_CONFIG_FEC_KR_ENA 0x01
@@ -2149,11 +1752,6 @@ struct i40e_aqc_get_link_status {
union {
struct {
u8 power_desc;
-#define I40E_AQ_LINK_POWER_CLASS_1 0x00
-#define I40E_AQ_LINK_POWER_CLASS_2 0x01
-#define I40E_AQ_LINK_POWER_CLASS_3 0x02
-#define I40E_AQ_LINK_POWER_CLASS_4 0x03
-#define I40E_AQ_PWR_CLASS_MASK 0x03
u8 reserved[4];
};
struct {
@@ -2171,13 +1769,7 @@ struct i40e_aqc_set_phy_int_mask {
__le16 event_mask;
#define I40E_AQ_EVENT_LINK_UPDOWN 0x0002
#define I40E_AQ_EVENT_MEDIA_NA 0x0004
-#define I40E_AQ_EVENT_LINK_FAULT 0x0008
-#define I40E_AQ_EVENT_PHY_TEMP_ALARM 0x0010
-#define I40E_AQ_EVENT_EXCESSIVE_ERRORS 0x0020
-#define I40E_AQ_EVENT_SIGNAL_DETECT 0x0040
-#define I40E_AQ_EVENT_AN_COMPLETED 0x0080
#define I40E_AQ_EVENT_MODULE_QUAL_FAIL 0x0100
-#define I40E_AQ_EVENT_PORT_TX_SUSPENDED 0x0200
u8 reserved1[6];
};
@@ -2209,13 +1801,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_lb_mode);
/* Set PHY Debug command (0x0622) */
struct i40e_aqc_set_phy_debug {
u8 command_flags;
-#define I40E_AQ_PHY_DEBUG_RESET_INTERNAL 0x02
-#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SHIFT 2
-#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_MASK (0x03 << \
- I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SHIFT)
-#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_NONE 0x00
-#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_HARD 0x01
-#define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SOFT 0x02
/* Disable link manageability on a single port */
#define I40E_AQ_PHY_DEBUG_DISABLE_LINK_FW 0x10
/* Disable link manageability on all ports */
@@ -2247,7 +1832,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_run_phy_activity);
/* Get PHY Register command (0x0629) */
struct i40e_aqc_phy_register_access {
u8 phy_interface;
-#define I40E_AQ_PHY_REG_ACCESS_INTERNAL 0
#define I40E_AQ_PHY_REG_ACCESS_EXTERNAL 1
#define I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE 2
u8 dev_address;
@@ -2274,9 +1858,7 @@ struct i40e_aqc_nvm_update {
#define I40E_AQ_NVM_LAST_CMD 0x01
#define I40E_AQ_NVM_REARRANGE_TO_FLAT 0x20
#define I40E_AQ_NVM_REARRANGE_TO_STRUCT 0x40
-#define I40E_AQ_NVM_FLASH_ONLY 0x80
#define I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT 1
-#define I40E_AQ_NVM_PRESERVATION_FLAGS_MASK 0x03
#define I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED 0x03
#define I40E_AQ_NVM_PRESERVATION_FLAGS_ALL 0x01
u8 module_pointer;
@@ -2291,9 +1873,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_update);
/* NVM Config Read (indirect 0x0704) */
struct i40e_aqc_nvm_config_read {
__le16 cmd_flags;
-#define I40E_AQ_ANVM_SINGLE_OR_MULTIPLE_FEATURES_MASK 1
-#define I40E_AQ_ANVM_READ_SINGLE_FEATURE 0
-#define I40E_AQ_ANVM_READ_MULTIPLE_FEATURES 1
__le16 element_count;
__le16 element_id; /* Feature/field ID */
__le16 element_id_msw; /* MSWord of field ID */
@@ -2315,16 +1894,8 @@ struct i40e_aqc_nvm_config_write {
I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_config_write);
/* Used for 0x0704 as well as for 0x0705 commands */
-#define I40E_AQ_ANVM_FEATURE_OR_IMMEDIATE_SHIFT 1
-#define I40E_AQ_ANVM_FEATURE_OR_IMMEDIATE_MASK \
- BIT(I40E_AQ_ANVM_FEATURE_OR_IMMEDIATE_SHIFT)
-#define I40E_AQ_ANVM_FEATURE 0
-#define I40E_AQ_ANVM_IMMEDIATE_FIELD BIT(FEATURE_OR_IMMEDIATE_SHIFT)
struct i40e_aqc_nvm_config_data_feature {
__le16 feature_id;
-#define I40E_AQ_ANVM_FEATURE_OPTION_OEM_ONLY 0x01
-#define I40E_AQ_ANVM_FEATURE_OPTION_DWORD_MAP 0x08
-#define I40E_AQ_ANVM_FEATURE_OPTION_POR_CSR 0x10
__le16 feature_options;
__le16 feature_selection;
};
@@ -2344,7 +1915,6 @@ I40E_CHECK_STRUCT_LEN(0xc, i40e_aqc_nvm_config_data_immediate_field);
* no command data struct used
*/
struct i40e_aqc_nvm_oem_post_update {
-#define I40E_AQ_NVM_OEM_POST_UPDATE_EXTERNAL_DATA 0x01
u8 sel_data;
u8 reserved[7];
};
@@ -2366,9 +1936,6 @@ I40E_CHECK_STRUCT_LEN(0x28, i40e_aqc_nvm_oem_post_update_buffer);
*/
struct i40e_aqc_thermal_sensor {
u8 sensor_action;
-#define I40E_AQ_THERMAL_SENSOR_READ_CONFIG 0
-#define I40E_AQ_THERMAL_SENSOR_SET_CONFIG 1
-#define I40E_AQ_THERMAL_SENSOR_READ_TEMP 2
u8 reserved[7];
__le32 addr_high;
__le32 addr_low;
@@ -2421,10 +1988,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_ind_write);
*/
struct i40e_aqc_alternate_write_done {
__le16 cmd_flags;
-#define I40E_AQ_ALTERNATE_MODE_BIOS_MASK 1
-#define I40E_AQ_ALTERNATE_MODE_BIOS_LEGACY 0
-#define I40E_AQ_ALTERNATE_MODE_BIOS_UEFI 1
-#define I40E_AQ_ALTERNATE_RESET_NEEDED 2
u8 reserved[14];
};
@@ -2433,8 +1996,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_write_done);
/* Set OEM mode (direct 0x0905) */
struct i40e_aqc_alternate_set_mode {
__le32 mode;
-#define I40E_AQ_ALTERNATE_MODE_NONE 0
-#define I40E_AQ_ALTERNATE_MODE_OEM 1
u8 reserved[12];
};
@@ -2460,13 +2021,9 @@ struct i40e_aqc_lldp_get_mib {
#define I40E_AQ_LLDP_MIB_TYPE_MASK 0x3
#define I40E_AQ_LLDP_MIB_LOCAL 0x0
#define I40E_AQ_LLDP_MIB_REMOTE 0x1
-#define I40E_AQ_LLDP_MIB_LOCAL_AND_REMOTE 0x2
#define I40E_AQ_LLDP_BRIDGE_TYPE_MASK 0xC
#define I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT 0x2
#define I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE 0x0
-#define I40E_AQ_LLDP_BRIDGE_TYPE_NON_TPMR 0x1
-#define I40E_AQ_LLDP_TX_SHIFT 0x4
-#define I40E_AQ_LLDP_TX_MASK (0x03 << I40E_AQ_LLDP_TX_SHIFT)
/* TX pause flags use I40E_AQ_LINK_TX_* above */
__le16 local_len;
__le16 remote_len;
@@ -2482,7 +2039,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_get_mib);
*/
struct i40e_aqc_lldp_update_mib {
u8 command;
-#define I40E_AQ_LLDP_MIB_UPDATE_ENABLE 0x0
#define I40E_AQ_LLDP_MIB_UPDATE_DISABLE 0x1
u8 reserved[7];
__le32 addr_high;
@@ -2521,7 +2077,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_tlv);
/* Stop LLDP (direct 0x0A05) */
struct i40e_aqc_lldp_stop {
u8 command;
-#define I40E_AQ_LLDP_AGENT_STOP 0x0
#define I40E_AQ_LLDP_AGENT_SHUTDOWN 0x1
#define I40E_AQ_LLDP_AGENT_STOP_PERSIST 0x2
u8 reserved[15];
@@ -2627,13 +2182,6 @@ I40E_CHECK_STRUCT_LEN(0x20, i40e_aqc_get_cee_dcb_cfg_resp);
* Used to replace the local MIB of a given LLDP agent. e.g. DCBx
*/
struct i40e_aqc_lldp_set_local_mib {
-#define SET_LOCAL_MIB_AC_TYPE_DCBX_SHIFT 0
-#define SET_LOCAL_MIB_AC_TYPE_DCBX_MASK BIT(SET_LOCAL_MIB_AC_TYPE_DCBX_SHIFT)
-#define SET_LOCAL_MIB_AC_TYPE_LOCAL_MIB 0x0
-#define SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT (1)
-#define SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_MASK \
- BIT(SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT)
-#define SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS 0x1
u8 type;
u8 reserved0;
__le16 length;
@@ -2648,9 +2196,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_set_local_mib);
* Used for stopping/starting specific LLDP agent. e.g. DCBx
*/
struct i40e_aqc_lldp_stop_start_specific_agent {
-#define I40E_AQC_START_SPECIFIC_AGENT_SHIFT 0
-#define I40E_AQC_START_SPECIFIC_AGENT_MASK \
- BIT(I40E_AQC_START_SPECIFIC_AGENT_SHIFT)
u8 command;
u8 reserved[15];
};
@@ -2660,7 +2205,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop_start_specific_agent);
/* Restore LLDP Agent factory settings (direct 0x0A0A) */
struct i40e_aqc_lldp_restore {
u8 command;
-#define I40E_AQ_LLDP_AGENT_RESTORE_NOT 0x0
#define I40E_AQ_LLDP_AGENT_RESTORE 0x1
u8 reserved[15];
};
@@ -2674,8 +2218,6 @@ struct i40e_aqc_add_udp_tunnel {
u8 protocol_type;
#define I40E_AQC_TUNNEL_TYPE_VXLAN 0x00
#define I40E_AQC_TUNNEL_TYPE_NGE 0x01
-#define I40E_AQC_TUNNEL_TYPE_TEREDO 0x10
-#define I40E_AQC_TUNNEL_TYPE_VXLAN_GPE 0x11
u8 reserved1[10];
};
@@ -2685,8 +2227,6 @@ struct i40e_aqc_add_udp_tunnel_completion {
__le16 udp_port;
u8 filter_entry_index;
u8 multiple_pfs;
-#define I40E_AQC_SINGLE_PF 0x0
-#define I40E_AQC_MULTIPLE_PFS 0x1
u8 total_filters;
u8 reserved[11];
};
@@ -2759,16 +2299,7 @@ struct i40e_aqc_tunnel_key_structure {
u8 key1_len; /* 0 to 15 */
u8 key2_len; /* 0 to 15 */
u8 flags;
-#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01
-/* response flags */
-#define I40E_AQC_TUNNEL_KEY_STRUCT_SUCCESS 0x01
-#define I40E_AQC_TUNNEL_KEY_STRUCT_MODIFIED 0x02
-#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03
u8 network_key_index;
-#define I40E_AQC_NETWORK_KEY_INDEX_VXLAN 0x0
-#define I40E_AQC_NETWORK_KEY_INDEX_NGE 0x1
-#define I40E_AQC_NETWORK_KEY_INDEX_FLEX_MAC_IN_UDP 0x2
-#define I40E_AQC_NETWORK_KEY_INDEX_GRE 0x3
u8 reserved[10];
};
@@ -2777,9 +2308,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_tunnel_key_structure);
/* OEM mode commands (direct 0xFE0x) */
struct i40e_aqc_oem_param_change {
__le32 param_type;
-#define I40E_AQ_OEM_PARAM_TYPE_PF_CTL 0
-#define I40E_AQ_OEM_PARAM_TYPE_BW_CTL 1
-#define I40E_AQ_OEM_PARAM_MAC 2
__le32 param_value1;
__le16 param_value2;
u8 reserved[6];
@@ -2789,8 +2317,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_oem_param_change);
struct i40e_aqc_oem_state_change {
__le32 state;
-#define I40E_AQ_OEM_STATE_LINK_DOWN 0x0
-#define I40E_AQ_OEM_STATE_LINK_UP 0x1
u8 reserved[12];
};
@@ -2826,14 +2352,8 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_opc_oem_ocbb_initialize);
struct i40e_acq_set_test_mode {
u8 mode;
-#define I40E_AQ_TEST_PARTIAL 0
-#define I40E_AQ_TEST_FULL 1
-#define I40E_AQ_TEST_NVM 2
u8 reserved[3];
u8 command;
-#define I40E_AQ_TEST_OPEN 0
-#define I40E_AQ_TEST_CLOSE 1
-#define I40E_AQ_TEST_INC 2
u8 reserved2[3];
__le32 address_high;
__le32 address_low;
@@ -2874,20 +2394,6 @@ struct i40e_aqc_debug_modify_reg {
I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_reg);
/* dump internal data (0xFF08, indirect) */
-
-#define I40E_AQ_CLUSTER_ID_AUX 0
-#define I40E_AQ_CLUSTER_ID_SWITCH_FLU 1
-#define I40E_AQ_CLUSTER_ID_TXSCHED 2
-#define I40E_AQ_CLUSTER_ID_HMC 3
-#define I40E_AQ_CLUSTER_ID_MAC0 4
-#define I40E_AQ_CLUSTER_ID_MAC1 5
-#define I40E_AQ_CLUSTER_ID_MAC2 6
-#define I40E_AQ_CLUSTER_ID_MAC3 7
-#define I40E_AQ_CLUSTER_ID_DCB 8
-#define I40E_AQ_CLUSTER_ID_EMP_MEM 9
-#define I40E_AQ_CLUSTER_ID_PKT_BUF 10
-#define I40E_AQ_CLUSTER_ID_ALTRAM 11
-
struct i40e_aqc_debug_dump_internals {
u8 cluster_id;
u8 table_id;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c
index e81530ca08d0..befd3018183f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_client.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_client.c
@@ -3,10 +3,10 @@
#include <linux/list.h>
#include <linux/errno.h>
+#include <linux/net/intel/i40e_client.h>
#include "i40e.h"
#include "i40e_prototype.h"
-#include "i40e_client.h"
static const char i40e_client_interface_version_str[] = I40E_CLIENT_VERSION_STR;
static struct i40e_client *registered_client;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.h b/drivers/net/ethernet/intel/i40e/i40e_client.h
deleted file mode 100644
index 72994baf4941..000000000000
--- a/drivers/net/ethernet/intel/i40e/i40e_client.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2013 - 2018 Intel Corporation. */
-
-#ifndef _I40E_CLIENT_H_
-#define _I40E_CLIENT_H_
-
-#define I40E_CLIENT_STR_LENGTH 10
-
-/* Client interface version should be updated anytime there is a change in the
- * existing APIs or data structures.
- */
-#define I40E_CLIENT_VERSION_MAJOR 0
-#define I40E_CLIENT_VERSION_MINOR 01
-#define I40E_CLIENT_VERSION_BUILD 00
-#define I40E_CLIENT_VERSION_STR \
- __stringify(I40E_CLIENT_VERSION_MAJOR) "." \
- __stringify(I40E_CLIENT_VERSION_MINOR) "." \
- __stringify(I40E_CLIENT_VERSION_BUILD)
-
-struct i40e_client_version {
- u8 major;
- u8 minor;
- u8 build;
- u8 rsvd;
-};
-
-enum i40e_client_state {
- __I40E_CLIENT_NULL,
- __I40E_CLIENT_REGISTERED
-};
-
-enum i40e_client_instance_state {
- __I40E_CLIENT_INSTANCE_NONE,
- __I40E_CLIENT_INSTANCE_OPENED,
-};
-
-struct i40e_ops;
-struct i40e_client;
-
-/* HW does not define a type value for AEQ; only for RX/TX and CEQ.
- * In order for us to keep the interface simple, SW will define a
- * unique type value for AEQ.
- */
-#define I40E_QUEUE_TYPE_PE_AEQ 0x80
-#define I40E_QUEUE_INVALID_IDX 0xFFFF
-
-struct i40e_qv_info {
- u32 v_idx; /* msix_vector */
- u16 ceq_idx;
- u16 aeq_idx;
- u8 itr_idx;
-};
-
-struct i40e_qvlist_info {
- u32 num_vectors;
- struct i40e_qv_info qv_info[1];
-};
-
-#define I40E_CLIENT_MSIX_ALL 0xFFFFFFFF
-
-/* set of LAN parameters useful for clients managed by LAN */
-
-/* Struct to hold per priority info */
-struct i40e_prio_qos_params {
- u16 qs_handle; /* qs handle for prio */
- u8 tc; /* TC mapped to prio */
- u8 reserved;
-};
-
-#define I40E_CLIENT_MAX_USER_PRIORITY 8
-/* Struct to hold Client QoS */
-struct i40e_qos_params {
- struct i40e_prio_qos_params prio_qos[I40E_CLIENT_MAX_USER_PRIORITY];
-};
-
-struct i40e_params {
- struct i40e_qos_params qos;
- u16 mtu;
-};
-
-/* Structure to hold Lan device info for a client device */
-struct i40e_info {
- struct i40e_client_version version;
- u8 lanmac[6];
- struct net_device *netdev;
- struct pci_dev *pcidev;
- u8 __iomem *hw_addr;
- u8 fid; /* function id, PF id or VF id */
-#define I40E_CLIENT_FTYPE_PF 0
-#define I40E_CLIENT_FTYPE_VF 1
- u8 ftype; /* function type, PF or VF */
- void *pf;
-
- /* All L2 params that could change during the life span of the PF
- * and needs to be communicated to the client when they change
- */
- struct i40e_qvlist_info *qvlist_info;
- struct i40e_params params;
- struct i40e_ops *ops;
-
- u16 msix_count; /* number of msix vectors*/
- /* Array down below will be dynamically allocated based on msix_count */
- struct msix_entry *msix_entries;
- u16 itr_index; /* Which ITR index the PE driver is suppose to use */
- u16 fw_maj_ver; /* firmware major version */
- u16 fw_min_ver; /* firmware minor version */
- u32 fw_build; /* firmware build number */
-};
-
-#define I40E_CLIENT_RESET_LEVEL_PF 1
-#define I40E_CLIENT_RESET_LEVEL_CORE 2
-#define I40E_CLIENT_VSI_FLAG_TCP_ENABLE BIT(1)
-
-struct i40e_ops {
- /* setup_q_vector_list enables queues with a particular vector */
- int (*setup_qvlist)(struct i40e_info *ldev, struct i40e_client *client,
- struct i40e_qvlist_info *qv_info);
-
- int (*virtchnl_send)(struct i40e_info *ldev, struct i40e_client *client,
- u32 vf_id, u8 *msg, u16 len);
-
- /* If the PE Engine is unresponsive, RDMA driver can request a reset.
- * The level helps determine the level of reset being requested.
- */
- void (*request_reset)(struct i40e_info *ldev,
- struct i40e_client *client, u32 level);
-
- /* API for the RDMA driver to set certain VSI flags that control
- * PE Engine.
- */
- int (*update_vsi_ctxt)(struct i40e_info *ldev,
- struct i40e_client *client,
- bool is_vf, u32 vf_id,
- u32 flag, u32 valid_flag);
-};
-
-struct i40e_client_ops {
- /* Should be called from register_client() or whenever PF is ready
- * to create a specific client instance.
- */
- int (*open)(struct i40e_info *ldev, struct i40e_client *client);
-
- /* Should be called when netdev is unavailable or when unregister
- * call comes in. If the close is happenening due to a reset being
- * triggered set the reset bit to true.
- */
- void (*close)(struct i40e_info *ldev, struct i40e_client *client,
- bool reset);
-
- /* called when some l2 managed parameters changes - mtu */
- void (*l2_param_change)(struct i40e_info *ldev,
- struct i40e_client *client,
- struct i40e_params *params);
-
- int (*virtchnl_receive)(struct i40e_info *ldev,
- struct i40e_client *client, u32 vf_id,
- u8 *msg, u16 len);
-
- /* called when a VF is reset by the PF */
- void (*vf_reset)(struct i40e_info *ldev,
- struct i40e_client *client, u32 vf_id);
-
- /* called when the number of VFs changes */
- void (*vf_enable)(struct i40e_info *ldev,
- struct i40e_client *client, u32 num_vfs);
-
- /* returns true if VF is capable of specified offload */
- int (*vf_capable)(struct i40e_info *ldev,
- struct i40e_client *client, u32 vf_id);
-};
-
-/* Client device */
-struct i40e_client_instance {
- struct list_head list;
- struct i40e_info lan_info;
- struct i40e_client *client;
- unsigned long state;
-};
-
-struct i40e_client {
- struct list_head list; /* list of registered clients */
- char name[I40E_CLIENT_STR_LENGTH];
- struct i40e_client_version version;
- unsigned long state; /* client state */
- atomic_t ref_cnt; /* Count of all the client devices of this kind */
- u32 flags;
-#define I40E_CLIENT_FLAGS_LAUNCH_ON_PROBE BIT(0)
-#define I40E_TX_FLAGS_NOTIFY_OTHER_EVENTS BIT(2)
- u8 type;
-#define I40E_CLIENT_IWARP 0
- const struct i40e_client_ops *ops; /* client ops provided by the client */
-};
-
-static inline bool i40e_client_is_registered(struct i40e_client *client)
-{
- return test_bit(__I40E_CLIENT_REGISTERED, &client->state);
-}
-
-/* used by clients */
-int i40e_register_client(struct i40e_client *client);
-int i40e_unregister_client(struct i40e_client *client);
-
-#endif /* _I40E_CLIENT_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 45b90eb11adb..afad5e9f80e0 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -27,6 +27,7 @@ i40e_status i40e_set_mac_type(struct i40e_hw *hw)
case I40E_DEV_ID_QSFP_A:
case I40E_DEV_ID_QSFP_B:
case I40E_DEV_ID_QSFP_C:
+ case I40E_DEV_ID_5G_BASE_T_BC:
case I40E_DEV_ID_10G_BASE_T:
case I40E_DEV_ID_10G_BASE_T4:
case I40E_DEV_ID_10G_BASE_T_BC:
@@ -1455,10 +1456,6 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
return gpio_val;
}
-#define I40E_COMBINED_ACTIVITY 0xA
-#define I40E_FILTER_ACTIVITY 0xE
-#define I40E_LINK_ACTIVITY 0xC
-#define I40E_MAC_ACTIVITY 0xD
#define I40E_FW_LED BIT(4)
#define I40E_LED_MODE_VALID (I40E_GLGEN_GPIO_CTL_LED_MODE_MASK >> \
I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT)
@@ -4910,6 +4907,7 @@ i40e_status i40e_write_phy_register(struct i40e_hw *hw,
status = i40e_write_phy_register_clause22(hw, reg, phy_addr,
value);
break;
+ case I40E_DEV_ID_5G_BASE_T_BC:
case I40E_DEV_ID_10G_BASE_T:
case I40E_DEV_ID_10G_BASE_T4:
case I40E_DEV_ID_10G_BASE_T_BC:
@@ -4947,6 +4945,7 @@ i40e_status i40e_read_phy_register(struct i40e_hw *hw,
status = i40e_read_phy_register_clause22(hw, reg, phy_addr,
value);
break;
+ case I40E_DEV_ID_5G_BASE_T_BC:
case I40E_DEV_ID_10G_BASE_T:
case I40E_DEV_ID_10G_BASE_T4:
case I40E_DEV_ID_10G_BASE_T_BC:
diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.h b/drivers/net/ethernet/intel/i40e/i40e_dcb.h
index ba86ad833bee..2b1a2e81ac73 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_dcb.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.h
@@ -6,10 +6,8 @@
#include "i40e_type.h"
-#define I40E_DCBX_STATUS_NOT_STARTED 0
#define I40E_DCBX_STATUS_IN_PROGRESS 1
#define I40E_DCBX_STATUS_DONE 2
-#define I40E_DCBX_STATUS_MULTIPLE_PEERS 3
#define I40E_DCBX_STATUS_DISABLED 7
#define I40E_TLV_TYPE_END 0
@@ -24,7 +22,6 @@
#define I40E_CEE_DCBX_OUI 0x001b21
#define I40E_CEE_DCBX_TYPE 2
-#define I40E_CEE_SUBTYPE_CTRL 1
#define I40E_CEE_SUBTYPE_PG_CFG 2
#define I40E_CEE_SUBTYPE_PFC_CFG 3
#define I40E_CEE_SUBTYPE_APP_PRI 4
@@ -105,9 +102,7 @@ struct i40e_cee_ctrl_tlv {
struct i40e_cee_feat_tlv {
struct i40e_cee_tlv_hdr hdr;
u8 en_will_err; /* Bits: |En|Will|Err|Reserved(5)| */
-#define I40E_CEE_FEAT_TLV_ENABLE_MASK 0x80
#define I40E_CEE_FEAT_TLV_WILLING_MASK 0x40
-#define I40E_CEE_FEAT_TLV_ERR_MASK 0x20
u8 subtype;
u8 tlvinfo[1];
};
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
index 99ea543dd245..d3ad2e3aa838 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -10,6 +10,12 @@
static struct dentry *i40e_dbg_root;
+enum ring_type {
+ RING_TYPE_RX,
+ RING_TYPE_TX,
+ RING_TYPE_XDP
+};
+
/**
* i40e_dbg_find_vsi - searches for the vsi with the given seid
* @pf: the PF structure to search for the vsi
@@ -319,6 +325,47 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
i, tx_ring->itr_setting,
ITR_IS_DYNAMIC(tx_ring->itr_setting) ? "dynamic" : "fixed");
}
+ if (i40e_enabled_xdp_vsi(vsi)) {
+ for (i = 0; i < vsi->num_queue_pairs; i++) {
+ struct i40e_ring *xdp_ring = READ_ONCE(vsi->xdp_rings[i]);
+
+ if (!xdp_ring)
+ continue;
+
+ dev_info(&pf->pdev->dev,
+ " xdp_rings[%i]: state = %lu, queue_index = %d, reg_idx = %d\n",
+ i, *xdp_ring->state,
+ xdp_ring->queue_index,
+ xdp_ring->reg_idx);
+ dev_info(&pf->pdev->dev,
+ " xdp_rings[%i]: next_to_use = %d, next_to_clean = %d, ring_active = %i\n",
+ i,
+ xdp_ring->next_to_use,
+ xdp_ring->next_to_clean,
+ xdp_ring->ring_active);
+ dev_info(&pf->pdev->dev,
+ " xdp_rings[%i]: tx_stats: packets = %lld, bytes = %lld, restart_queue = %lld\n",
+ i, xdp_ring->stats.packets,
+ xdp_ring->stats.bytes,
+ xdp_ring->tx_stats.restart_queue);
+ dev_info(&pf->pdev->dev,
+ " xdp_rings[%i]: tx_stats: tx_busy = %lld, tx_done_old = %lld\n",
+ i,
+ xdp_ring->tx_stats.tx_busy,
+ xdp_ring->tx_stats.tx_done_old);
+ dev_info(&pf->pdev->dev,
+ " xdp_rings[%i]: size = %i\n",
+ i, xdp_ring->size);
+ dev_info(&pf->pdev->dev,
+ " xdp_rings[%i]: DCB tc = %d\n",
+ i, xdp_ring->dcb_tc);
+ dev_info(&pf->pdev->dev,
+ " xdp_rings[%i]: itr_setting = %d (%s)\n",
+ i, xdp_ring->itr_setting,
+ ITR_IS_DYNAMIC(xdp_ring->itr_setting) ?
+ "dynamic" : "fixed");
+ }
+ }
rcu_read_unlock();
dev_info(&pf->pdev->dev,
" work_limit = %d\n",
@@ -489,11 +536,12 @@ static void i40e_dbg_dump_aq_desc(struct i40e_pf *pf)
* @ring_id: ring id entered by user
* @desc_n: descriptor number entered by user
* @pf: the i40e_pf created in command write
- * @is_rx_ring: true if rx, false if tx
+ * @type: enum describing whether ring is RX, TX or XDP
**/
static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
- struct i40e_pf *pf, bool is_rx_ring)
+ struct i40e_pf *pf, enum ring_type type)
{
+ bool is_rx_ring = type == RING_TYPE_RX;
struct i40e_tx_desc *txd;
union i40e_rx_desc *rxd;
struct i40e_ring *ring;
@@ -505,6 +553,10 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
dev_info(&pf->pdev->dev, "vsi %d not found\n", vsi_seid);
return;
}
+ if (type == RING_TYPE_XDP && !i40e_enabled_xdp_vsi(vsi)) {
+ dev_info(&pf->pdev->dev, "XDP not enabled on VSI %d\n", vsi_seid);
+ return;
+ }
if (ring_id >= vsi->num_queue_pairs || ring_id < 0) {
dev_info(&pf->pdev->dev, "ring %d not found\n", ring_id);
return;
@@ -516,15 +568,32 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
return;
}
- ring = kmemdup(is_rx_ring
- ? vsi->rx_rings[ring_id] : vsi->tx_rings[ring_id],
- sizeof(*ring), GFP_KERNEL);
+ switch (type) {
+ case RING_TYPE_RX:
+ ring = kmemdup(vsi->rx_rings[ring_id], sizeof(*ring), GFP_KERNEL);
+ break;
+ case RING_TYPE_TX:
+ ring = kmemdup(vsi->tx_rings[ring_id], sizeof(*ring), GFP_KERNEL);
+ break;
+ case RING_TYPE_XDP:
+ ring = kmemdup(vsi->xdp_rings[ring_id], sizeof(*ring), GFP_KERNEL);
+ break;
+ }
if (!ring)
return;
if (cnt == 2) {
- dev_info(&pf->pdev->dev, "vsi = %02i %s ring = %02i\n",
- vsi_seid, is_rx_ring ? "rx" : "tx", ring_id);
+ switch (type) {
+ case RING_TYPE_RX:
+ dev_info(&pf->pdev->dev, "VSI = %02i Rx ring = %02i\n", vsi_seid, ring_id);
+ break;
+ case RING_TYPE_TX:
+ dev_info(&pf->pdev->dev, "VSI = %02i Tx ring = %02i\n", vsi_seid, ring_id);
+ break;
+ case RING_TYPE_XDP:
+ dev_info(&pf->pdev->dev, "VSI = %02i XDP ring = %02i\n", vsi_seid, ring_id);
+ break;
+ }
for (i = 0; i < ring->count; i++) {
if (!is_rx_ring) {
txd = I40E_TX_DESC(ring, i);
@@ -562,7 +631,7 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
rxd->read.rsvd1, rxd->read.rsvd2);
}
} else {
- dev_info(&pf->pdev->dev, "dump desc rx/tx <vsi_seid> <ring_id> [<desc_n>]\n");
+ dev_info(&pf->pdev->dev, "dump desc rx/tx/xdp <vsi_seid> <ring_id> [<desc_n>]\n");
}
out:
@@ -688,7 +757,6 @@ static void i40e_dbg_dump_vf_all(struct i40e_pf *pf)
i40e_dbg_dump_vf(pf, i);
}
-#define I40E_MAX_DEBUG_OUT_BUFFER (4096*4)
/**
* i40e_dbg_command_write - write into command datum
* @filp: the opened file
@@ -920,13 +988,19 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
cnt = sscanf(&cmd_buf[12], "%i %i %i",
&vsi_seid, &ring_id, &desc_n);
i40e_dbg_dump_desc(cnt, vsi_seid, ring_id,
- desc_n, pf, true);
+ desc_n, pf, RING_TYPE_RX);
} else if (strncmp(&cmd_buf[10], "tx", 2)
== 0) {
cnt = sscanf(&cmd_buf[12], "%i %i %i",
&vsi_seid, &ring_id, &desc_n);
i40e_dbg_dump_desc(cnt, vsi_seid, ring_id,
- desc_n, pf, false);
+ desc_n, pf, RING_TYPE_TX);
+ } else if (strncmp(&cmd_buf[10], "xdp", 3)
+ == 0) {
+ cnt = sscanf(&cmd_buf[13], "%i %i %i",
+ &vsi_seid, &ring_id, &desc_n);
+ i40e_dbg_dump_desc(cnt, vsi_seid, ring_id,
+ desc_n, pf, RING_TYPE_XDP);
} else if (strncmp(&cmd_buf[10], "aq", 2) == 0) {
i40e_dbg_dump_aq_desc(pf);
} else {
@@ -934,6 +1008,8 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
"dump desc tx <vsi_seid> <ring_id> [<desc_n>]\n");
dev_info(&pf->pdev->dev,
"dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n");
+ dev_info(&pf->pdev->dev,
+ "dump desc xdp <vsi_seid> <ring_id> [<desc_n>]\n");
dev_info(&pf->pdev->dev, "dump desc aq\n");
}
} else if (strncmp(&cmd_buf[5], "reset stats", 11) == 0) {
@@ -1104,7 +1180,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
buff = NULL;
} else {
dev_info(&pf->pdev->dev,
- "dump desc tx <vsi_seid> <ring_id> [<desc_n>], dump desc rx <vsi_seid> <ring_id> [<desc_n>],\n");
+ "dump desc tx <vsi_seid> <ring_id> [<desc_n>], dump desc rx <vsi_seid> <ring_id> [<desc_n>], dump desc xdp <vsi_seid> <ring_id> [<desc_n>],\n");
dev_info(&pf->pdev->dev, "dump switch\n");
dev_info(&pf->pdev->dev, "dump vsi [seid]\n");
dev_info(&pf->pdev->dev, "dump reset stats\n");
@@ -1520,6 +1596,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
dev_info(&pf->pdev->dev, " dump vsi [seid]\n");
dev_info(&pf->pdev->dev, " dump desc tx <vsi_seid> <ring_id> [<desc_n>]\n");
dev_info(&pf->pdev->dev, " dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n");
+ dev_info(&pf->pdev->dev, " dump desc xdp <vsi_seid> <ring_id> [<desc_n>]\n");
dev_info(&pf->pdev->dev, " dump desc aq\n");
dev_info(&pf->pdev->dev, " dump reset stats\n");
dev_info(&pf->pdev->dev, " dump debug fwdata <cluster_id> <table_id> <index>\n");
diff --git a/drivers/net/ethernet/intel/i40e/i40e_devids.h b/drivers/net/ethernet/intel/i40e/i40e_devids.h
index bf15a868292f..1bcb0ec0f0c0 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_devids.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_devids.h
@@ -23,8 +23,10 @@
#define I40E_DEV_ID_10G_BASE_T_BC 0x15FF
#define I40E_DEV_ID_10G_B 0x104F
#define I40E_DEV_ID_10G_SFP 0x104E
+#define I40E_DEV_ID_5G_BASE_T_BC 0x101F
#define I40E_IS_X710TL_DEVICE(d) \
- ((d) == I40E_DEV_ID_10G_BASE_T_BC)
+ (((d) == I40E_DEV_ID_5G_BASE_T_BC) || \
+ ((d) == I40E_DEV_ID_10G_BASE_T_BC))
#define I40E_DEV_ID_KX_X722 0x37CE
#define I40E_DEV_ID_QSFP_X722 0x37CF
#define I40E_DEV_ID_SFP_X722 0x37D0
@@ -32,8 +34,5 @@
#define I40E_DEV_ID_10G_BASE_T_X722 0x37D2
#define I40E_DEV_ID_SFP_I_X722 0x37D3
-#define i40e_is_40G_device(d) ((d) == I40E_DEV_ID_QSFP_A || \
- (d) == I40E_DEV_ID_QSFP_B || \
- (d) == I40E_DEV_ID_QSFP_C)
#endif /* _I40E_DEVIDS_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 67806b7b2f49..825c104ecba1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -428,6 +428,8 @@ struct i40e_priv_flags {
static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
/* NOTE: MFP setting cannot be changed */
I40E_PRIV_FLAG("MFP", I40E_FLAG_MFP_ENABLED, 1),
+ I40E_PRIV_FLAG("total-port-shutdown",
+ I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED, 1),
I40E_PRIV_FLAG("LinkPolling", I40E_FLAG_LINK_POLLING_ENABLED, 0),
I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0),
I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0),
@@ -1893,8 +1895,6 @@ static void i40e_get_drvinfo(struct net_device *netdev,
struct i40e_pf *pf = vsi->back;
strlcpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, i40e_driver_version_str,
- sizeof(drvinfo->version));
strlcpy(drvinfo->fw_version, i40e_nvm_version_str(&pf->hw),
sizeof(drvinfo->fw_version));
strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
@@ -4104,7 +4104,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
switch (fsp->flow_type & ~FLOW_EXT) {
case SCTP_V4_FLOW:
new_mask &= ~I40E_VERIFY_TAG_MASK;
- /* Fall through */
+ fallthrough;
case TCP_V4_FLOW:
case UDP_V4_FLOW:
tcp_ip4_spec = &fsp->m_u.tcp_ip4_spec;
@@ -5009,6 +5009,13 @@ flags_complete:
dev_warn(&pf->pdev->dev, "Cannot change FEC config\n");
}
+ if ((changed_flags & I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
+ (orig_flags & I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED)) {
+ dev_err(&pf->pdev->dev,
+ "Setting link-down-on-close not supported on this port (because total-port-shutdown is enabled)\n");
+ return -EOPNOTSUPP;
+ }
+
if ((changed_flags & new_flags &
I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
(new_flags & I40E_FLAG_MFP_ENABLED))
diff --git a/drivers/net/ethernet/intel/i40e/i40e_hmc.h b/drivers/net/ethernet/intel/i40e/i40e_hmc.h
index 1c78de838857..3113792afaff 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_hmc.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_hmc.h
@@ -14,7 +14,6 @@ struct i40e_hw;
#define I40E_HMC_DIRECT_BP_SIZE 0x200000 /* 2M */
#define I40E_HMC_PAGED_BP_SIZE 4096
#define I40E_HMC_PD_BP_BUF_ALIGNMENT 4096
-#define I40E_FIRST_VF_FPM_ID 16
struct i40e_hmc_obj_info {
u64 base; /* base addr in FPM */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 56ecd6c3f236..d8315811cbdf 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -5,6 +5,7 @@
#include <linux/of_net.h>
#include <linux/pci.h>
#include <linux/bpf.h>
+#include <generated/utsrelease.h>
/* Local includes */
#include "i40e.h"
@@ -23,15 +24,6 @@ const char i40e_driver_name[] = "i40e";
static const char i40e_driver_string[] =
"Intel(R) Ethernet Connection XL710 Network Driver";
-#define DRV_KERN "-k"
-
-#define DRV_VERSION_MAJOR 2
-#define DRV_VERSION_MINOR 8
-#define DRV_VERSION_BUILD 20
-#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
- __stringify(DRV_VERSION_MINOR) "." \
- __stringify(DRV_VERSION_BUILD) DRV_KERN
-const char i40e_driver_version_str[] = DRV_VERSION;
static const char i40e_copyright[] = "Copyright (c) 2013 - 2019 Intel Corporation.";
/* a bit of forward declarations */
@@ -54,7 +46,7 @@ static void i40e_fdir_sb_setup(struct i40e_pf *pf);
static int i40e_veb_get_bw_info(struct i40e_veb *veb);
static int i40e_get_capabilities(struct i40e_pf *pf,
enum i40e_admin_queue_opc list_type);
-
+static bool i40e_is_total_port_shutdown_enabled(struct i40e_pf *pf);
/* i40e_pci_tbl - PCI Device ID Table
*
@@ -101,7 +93,6 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all), Debug mask (0x8XXXXXXX
MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
MODULE_DESCRIPTION("Intel(R) Ethernet Connection XL710 Network Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
static struct workqueue_struct *i40e_wq;
@@ -820,6 +811,25 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
rx_p += packets;
rx_buf += p->rx_stats.alloc_buff_failed;
rx_page += p->rx_stats.alloc_page_failed;
+
+ if (i40e_enabled_xdp_vsi(vsi)) {
+ /* locate XDP ring */
+ p = READ_ONCE(vsi->xdp_rings[q]);
+ if (!p)
+ continue;
+
+ do {
+ start = u64_stats_fetch_begin_irq(&p->syncp);
+ packets = p->stats.packets;
+ bytes = p->stats.bytes;
+ } while (u64_stats_fetch_retry_irq(&p->syncp, start));
+ tx_b += bytes;
+ tx_p += packets;
+ tx_restart += p->tx_stats.restart_queue;
+ tx_busy += p->tx_stats.tx_busy;
+ tx_linearize += p->tx_stats.tx_linearize;
+ tx_force_wb += p->tx_stats.tx_force_wb;
+ }
}
rcu_read_unlock();
vsi->tx_restart = tx_restart;
@@ -1826,7 +1836,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
num_tc_qps);
break;
}
- /* fall through */
+ fallthrough;
case I40E_VSI_FDIR:
case I40E_VSI_SRIOV:
case I40E_VSI_VMDQ2:
@@ -6501,8 +6511,7 @@ out:
return err;
}
#endif /* CONFIG_I40E_DCB */
-#define SPEED_SIZE 14
-#define FC_SIZE 8
+
/**
* i40e_print_link_message - print link up or down
* @vsi: the VSI for which link needs a message
@@ -6690,21 +6699,6 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi)
}
/**
- * i40e_up - Bring the connection back up after being down
- * @vsi: the VSI being configured
- **/
-int i40e_up(struct i40e_vsi *vsi)
-{
- int err;
-
- err = i40e_vsi_configure(vsi);
- if (!err)
- err = i40e_up_complete(vsi);
-
- return err;
-}
-
-/**
* i40e_force_link_state - Force the link status
* @pf: board private structure
* @is_up: whether the link state should be forced up or down
@@ -6713,6 +6707,7 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
{
struct i40e_aq_get_phy_abilities_resp abilities;
struct i40e_aq_set_phy_config config = {0};
+ bool non_zero_phy_type = is_up;
struct i40e_hw *hw = &pf->hw;
i40e_status err;
u64 mask;
@@ -6748,8 +6743,11 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
/* If link needs to go up, but was not forced to go down,
* and its speed values are OK, no need for a flap
+ * if non_zero_phy_type was set, still need to force up
*/
- if (is_up && abilities.phy_type != 0 && abilities.link_speed != 0)
+ if (pf->flags & I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED)
+ non_zero_phy_type = true;
+ else if (is_up && abilities.phy_type != 0 && abilities.link_speed != 0)
return I40E_SUCCESS;
/* To force link we need to set bits for all supported PHY types,
@@ -6757,10 +6755,18 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
* across two fields.
*/
mask = I40E_PHY_TYPES_BITMASK;
- config.phy_type = is_up ? cpu_to_le32((u32)(mask & 0xffffffff)) : 0;
- config.phy_type_ext = is_up ? (u8)((mask >> 32) & 0xff) : 0;
+ config.phy_type =
+ non_zero_phy_type ? cpu_to_le32((u32)(mask & 0xffffffff)) : 0;
+ config.phy_type_ext =
+ non_zero_phy_type ? (u8)((mask >> 32) & 0xff) : 0;
/* Copy the old settings, except of phy_type */
config.abilities = abilities.abilities;
+ if (pf->flags & I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED) {
+ if (is_up)
+ config.abilities |= I40E_AQ_PHY_ENABLE_LINK;
+ else
+ config.abilities &= ~(I40E_AQ_PHY_ENABLE_LINK);
+ }
if (abilities.link_speed != 0)
config.link_speed = abilities.link_speed;
else
@@ -6791,12 +6797,32 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
i40e_update_link_info(hw);
}
- i40e_aq_set_link_restart_an(hw, true, NULL);
+ i40e_aq_set_link_restart_an(hw, is_up, NULL);
return I40E_SUCCESS;
}
/**
+ * i40e_up - Bring the connection back up after being down
+ * @vsi: the VSI being configured
+ **/
+int i40e_up(struct i40e_vsi *vsi)
+{
+ int err;
+
+ if (vsi->type == I40E_VSI_MAIN &&
+ (vsi->back->flags & I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED ||
+ vsi->back->flags & I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED))
+ i40e_force_link_state(vsi->back, true);
+
+ err = i40e_vsi_configure(vsi);
+ if (!err)
+ err = i40e_up_complete(vsi);
+
+ return err;
+}
+
+/**
* i40e_down - Shutdown the connection processing
* @vsi: the VSI being stopped
**/
@@ -6814,7 +6840,8 @@ void i40e_down(struct i40e_vsi *vsi)
i40e_vsi_disable_irq(vsi);
i40e_vsi_stop_rings(vsi);
if (vsi->type == I40E_VSI_MAIN &&
- vsi->back->flags & I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED)
+ (vsi->back->flags & I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED ||
+ vsi->back->flags & I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED))
i40e_force_link_state(vsi->back, false);
i40e_napi_disable_all(vsi);
@@ -8959,13 +8986,6 @@ u32 i40e_get_current_atr_cnt(struct i40e_pf *pf)
return i40e_get_current_fd_count(pf) - pf->fdir_pf_active_filters;
}
-/* We can see up to 256 filter programming desc in transit if the filters are
- * being applied really fast; before we see the first
- * filter miss error on Rx queue 0. Accumulating enough error messages before
- * reacting will make sure we don't cause flush too often.
- */
-#define I40E_MAX_FD_PROGRAM_ERROR 256
-
/**
* i40e_fdir_reinit_subtask - Worker thread to reinit FDIR filter table
* @pf: board private structure
@@ -9860,11 +9880,11 @@ static void i40e_send_version(struct i40e_pf *pf)
{
struct i40e_driver_version dv;
- dv.major_version = DRV_VERSION_MAJOR;
- dv.minor_version = DRV_VERSION_MINOR;
- dv.build_version = DRV_VERSION_BUILD;
+ dv.major_version = 0xff;
+ dv.minor_version = 0xff;
+ dv.build_version = 0xff;
dv.subbuild_version = 0;
- strlcpy(dv.driver_string, DRV_VERSION, sizeof(dv.driver_string));
+ strlcpy(dv.driver_string, UTS_RELEASE, sizeof(dv.driver_string));
i40e_aq_send_driver_version(&pf->hw, &dv, NULL);
}
@@ -11855,6 +11875,58 @@ bw_commit_out:
}
/**
+ * i40e_is_total_port_shutdown_enabled - read NVM and return value
+ * if total port shutdown feature is enabled for this PF
+ * @pf: board private structure
+ **/
+static bool i40e_is_total_port_shutdown_enabled(struct i40e_pf *pf)
+{
+#define I40E_TOTAL_PORT_SHUTDOWN_ENABLED BIT(4)
+#define I40E_FEATURES_ENABLE_PTR 0x2A
+#define I40E_CURRENT_SETTING_PTR 0x2B
+#define I40E_LINK_BEHAVIOR_WORD_OFFSET 0x2D
+#define I40E_LINK_BEHAVIOR_WORD_LENGTH 0x1
+#define I40E_LINK_BEHAVIOR_OS_FORCED_ENABLED BIT(0)
+#define I40E_LINK_BEHAVIOR_PORT_BIT_LENGTH 4
+ i40e_status read_status = I40E_SUCCESS;
+ u16 sr_emp_sr_settings_ptr = 0;
+ u16 features_enable = 0;
+ u16 link_behavior = 0;
+ bool ret = false;
+
+ read_status = i40e_read_nvm_word(&pf->hw,
+ I40E_SR_EMP_SR_SETTINGS_PTR,
+ &sr_emp_sr_settings_ptr);
+ if (read_status)
+ goto err_nvm;
+ read_status = i40e_read_nvm_word(&pf->hw,
+ sr_emp_sr_settings_ptr +
+ I40E_FEATURES_ENABLE_PTR,
+ &features_enable);
+ if (read_status)
+ goto err_nvm;
+ if (I40E_TOTAL_PORT_SHUTDOWN_ENABLED & features_enable) {
+ read_status = i40e_read_nvm_module_data(&pf->hw,
+ I40E_SR_EMP_SR_SETTINGS_PTR,
+ I40E_CURRENT_SETTING_PTR,
+ I40E_LINK_BEHAVIOR_WORD_OFFSET,
+ I40E_LINK_BEHAVIOR_WORD_LENGTH,
+ &link_behavior);
+ if (read_status)
+ goto err_nvm;
+ link_behavior >>= (pf->hw.port * I40E_LINK_BEHAVIOR_PORT_BIT_LENGTH);
+ ret = I40E_LINK_BEHAVIOR_OS_FORCED_ENABLED & link_behavior;
+ }
+ return ret;
+
+err_nvm:
+ dev_warn(&pf->pdev->dev,
+ "total-port-shutdown feature is off due to read nvm error: %s\n",
+ i40e_stat_str(&pf->hw, read_status));
+ return ret;
+}
+
+/**
* i40e_sw_init - Initialize general software structures (struct i40e_pf)
* @pf: board private structure to initialize
*
@@ -12029,6 +12101,16 @@ static int i40e_sw_init(struct i40e_pf *pf)
pf->tx_timeout_recovery_level = 1;
+ if (pf->hw.mac.type != I40E_MAC_X722 &&
+ i40e_is_total_port_shutdown_enabled(pf)) {
+ /* Link down on close must be on when total port shutdown
+ * is enabled for a given port
+ */
+ pf->flags |= (I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED |
+ I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED);
+ dev_info(&pf->pdev->dev,
+ "total-port-shutdown was enabled, link-down-on-close is forced on\n");
+ }
mutex_init(&pf->switch_mutex);
sw_init_done:
@@ -12841,9 +12923,6 @@ static int i40e_xdp(struct net_device *dev,
switch (xdp->command) {
case XDP_SETUP_PROG:
return i40e_xdp_setup(vsi, xdp->prog);
- case XDP_QUERY_PROG:
- xdp->prog_id = vsi->xdp_prog ? vsi->xdp_prog->aux->id : 0;
- return 0;
case XDP_SETUP_XSK_UMEM:
return i40e_xsk_umem_setup(vsi, xdp->xsk.umem,
xdp->xsk.queue_id);
@@ -13703,8 +13782,7 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
/* Setup DCB netlink interface */
i40e_dcbnl_setup(vsi);
#endif /* CONFIG_I40E_DCB */
- /* fall through */
-
+ fallthrough;
case I40E_VSI_FDIR:
/* set up vectors and rings if needed */
ret = i40e_vsi_setup_vectors(vsi);
@@ -13720,7 +13798,6 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
i40e_vsi_reset_stats(vsi);
break;
-
default:
/* no netdev or rings for the other VSI types */
break;
@@ -14574,28 +14651,17 @@ void i40e_set_fec_in_flags(u8 fec_cfg, u32 *flags)
**/
static bool i40e_check_recovery_mode(struct i40e_pf *pf)
{
- u32 val = rd32(&pf->hw, I40E_GL_FWSTS) & I40E_GL_FWSTS_FWS1B_MASK;
- bool is_recovery_mode = false;
-
- if (pf->hw.mac.type == I40E_MAC_XL710)
- is_recovery_mode =
- val == I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_CORER_MASK ||
- val == I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_GLOBR_MASK ||
- val == I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_TRANSITION_MASK ||
- val == I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_NVM_MASK;
- if (pf->hw.mac.type == I40E_MAC_X722)
- is_recovery_mode =
- val == I40E_X722_GL_FWSTS_FWS1B_REC_MOD_CORER_MASK ||
- val == I40E_X722_GL_FWSTS_FWS1B_REC_MOD_GLOBR_MASK;
- if (is_recovery_mode) {
- dev_notice(&pf->pdev->dev, "Firmware recovery mode detected. Limiting functionality.\n");
- dev_notice(&pf->pdev->dev, "Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode.\n");
+ u32 val = rd32(&pf->hw, I40E_GL_FWSTS);
+
+ if (val & I40E_GL_FWSTS_FWS1B_MASK) {
+ dev_crit(&pf->pdev->dev, "Firmware recovery mode detected. Limiting functionality.\n");
+ dev_crit(&pf->pdev->dev, "Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode.\n");
set_bit(__I40E_RECOVERY_MODE, pf->state);
return true;
}
- if (test_and_clear_bit(__I40E_RECOVERY_MODE, pf->state))
- dev_info(&pf->pdev->dev, "Reinitializing in normal mode with full functionality.\n");
+ if (test_bit(__I40E_RECOVERY_MODE, pf->state))
+ dev_info(&pf->pdev->dev, "Please do Power-On Reset to initialize adapter in normal mode with full functionality.\n");
return false;
}
@@ -14623,29 +14689,68 @@ static bool i40e_check_recovery_mode(struct i40e_pf *pf)
**/
static i40e_status i40e_pf_loop_reset(struct i40e_pf *pf)
{
- const unsigned short MAX_CNT = 1000;
- const unsigned short MSECS = 10;
+ /* wait max 10 seconds for PF reset to succeed */
+ const unsigned long time_end = jiffies + 10 * HZ;
+
struct i40e_hw *hw = &pf->hw;
i40e_status ret;
- int cnt;
- for (cnt = 0; cnt < MAX_CNT; ++cnt) {
+ ret = i40e_pf_reset(hw);
+ while (ret != I40E_SUCCESS && time_before(jiffies, time_end)) {
+ usleep_range(10000, 20000);
ret = i40e_pf_reset(hw);
- if (!ret)
- break;
- msleep(MSECS);
}
- if (cnt == MAX_CNT) {
+ if (ret == I40E_SUCCESS)
+ pf->pfr_count++;
+ else
dev_info(&pf->pdev->dev, "PF reset failed: %d\n", ret);
- return ret;
- }
- pf->pfr_count++;
return ret;
}
/**
+ * i40e_check_fw_empr - check if FW issued unexpected EMP Reset
+ * @pf: board private structure
+ *
+ * Check FW registers to determine if FW issued unexpected EMP Reset.
+ * Every time when unexpected EMP Reset occurs the FW increments
+ * a counter of unexpected EMP Resets. When the counter reaches 10
+ * the FW should enter the Recovery mode
+ *
+ * Returns true if FW issued unexpected EMP Reset
+ **/
+static bool i40e_check_fw_empr(struct i40e_pf *pf)
+{
+ const u32 fw_sts = rd32(&pf->hw, I40E_GL_FWSTS) &
+ I40E_GL_FWSTS_FWS1B_MASK;
+ return (fw_sts > I40E_GL_FWSTS_FWS1B_EMPR_0) &&
+ (fw_sts <= I40E_GL_FWSTS_FWS1B_EMPR_10);
+}
+
+/**
+ * i40e_handle_resets - handle EMP resets and PF resets
+ * @pf: board private structure
+ *
+ * Handle both EMP resets and PF resets and conclude whether there are
+ * any issues regarding these resets. If there are any issues then
+ * generate log entry.
+ *
+ * Return 0 if NIC is healthy or negative value when there are issues
+ * with resets
+ **/
+static i40e_status i40e_handle_resets(struct i40e_pf *pf)
+{
+ const i40e_status pfr = i40e_pf_loop_reset(pf);
+ const bool is_empr = i40e_check_fw_empr(pf);
+
+ if (is_empr || pfr != I40E_SUCCESS)
+ dev_crit(&pf->pdev->dev, "Entering recovery mode due to repeated FW resets. This may take several minutes. Refer to the Intel(R) Ethernet Adapters and Devices User Guide.\n");
+
+ return is_empr ? I40E_ERR_RESET_FAILED : pfr;
+}
+
+/**
* i40e_init_recovery_mode - initialize subsystems needed in recovery mode
* @pf: board private structure
* @hw: ptr to the hardware info
@@ -14881,11 +14986,9 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_pf_reset;
}
- err = i40e_pf_loop_reset(pf);
- if (err) {
- dev_info(&pdev->dev, "Initial pf_reset failed: %d\n", err);
+ err = i40e_handle_resets(pf);
+ if (err)
goto err_pf_reset;
- }
i40e_check_recovery_mode(pf);
@@ -15281,6 +15384,14 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
i40e_stat_str(&pf->hw, err),
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+ /* make sure the MFS hasn't been set lower than the default */
+#define MAX_FRAME_SIZE_DEFAULT 0x2600
+ val = (rd32(&pf->hw, I40E_PRTGL_SAH) &
+ I40E_PRTGL_SAH_MFS_MASK) >> I40E_PRTGL_SAH_MFS_SHIFT;
+ if (val < MAX_FRAME_SIZE_DEFAULT)
+ dev_warn(&pdev->dev, "MFS for port %x has been set below the default: %x\n",
+ i, val);
+
/* Add a filter to drop all Flow control frames from any VSI from being
* transmitted. By doing so we stop a malicious VF from sending out
* PAUSE or PFC frames and potentially controlling traffic for other
@@ -15791,8 +15902,7 @@ static struct pci_driver i40e_driver = {
**/
static int __init i40e_init_module(void)
{
- pr_info("%s: %s - version %s\n", i40e_driver_name,
- i40e_driver_string, i40e_driver_version_str);
+ pr_info("%s: %s\n", i40e_driver_name, i40e_driver_string);
pr_info("%s: %s\n", i40e_driver_name, i40e_copyright);
/* There is no need to throttle the number of active tasks because
diff --git a/drivers/net/ethernet/intel/i40e/i40e_osdep.h b/drivers/net/ethernet/intel/i40e/i40e_osdep.h
index c302ef2524f8..2f6815b2f8df 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_osdep.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_osdep.h
@@ -26,7 +26,6 @@ do { \
#define wr32(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
#define rd32(a, reg) readl((a)->hw_addr + (reg))
-#define wr64(a, reg, value) writeq((value), ((a)->hw_addr + (reg)))
#define rd64(a, reg) readq((a)->hw_addr + (reg))
#define i40e_flush(a) readl((a)->hw_addr + I40E_GLGEN_STAT)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
index 9bf1ad4319f5..ff7b19c6bc73 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
@@ -586,7 +586,7 @@ static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
if (!(pf->hw_features & I40E_HW_PTP_L4_CAPABLE))
return -ERANGE;
- /* fall through */
+ fallthrough;
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
diff --git a/drivers/net/ethernet/intel/i40e/i40e_register.h b/drivers/net/ethernet/intel/i40e/i40e_register.h
index d35d690ca10f..564df22f3f46 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_register.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_register.h
@@ -4,53 +4,14 @@
#ifndef _I40E_REGISTER_H_
#define _I40E_REGISTER_H_
-#define I40E_GL_ARQBAH 0x000801C0 /* Reset: EMPR */
-#define I40E_GL_ARQBAH_ARQBAH_SHIFT 0
-#define I40E_GL_ARQBAH_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ARQBAH_ARQBAH_SHIFT)
-#define I40E_GL_ARQBAL 0x000800C0 /* Reset: EMPR */
-#define I40E_GL_ARQBAL_ARQBAL_SHIFT 0
-#define I40E_GL_ARQBAL_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ARQBAL_ARQBAL_SHIFT)
-#define I40E_GL_ARQH 0x000803C0 /* Reset: EMPR */
-#define I40E_GL_ARQH_ARQH_SHIFT 0
-#define I40E_GL_ARQH_ARQH_MASK I40E_MASK(0x3FF, I40E_GL_ARQH_ARQH_SHIFT)
-#define I40E_GL_ARQT 0x000804C0 /* Reset: EMPR */
-#define I40E_GL_ARQT_ARQT_SHIFT 0
-#define I40E_GL_ARQT_ARQT_MASK I40E_MASK(0x3FF, I40E_GL_ARQT_ARQT_SHIFT)
-#define I40E_GL_ATQBAH 0x00080140 /* Reset: EMPR */
-#define I40E_GL_ATQBAH_ATQBAH_SHIFT 0
-#define I40E_GL_ATQBAH_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ATQBAH_ATQBAH_SHIFT)
-#define I40E_GL_ATQBAL 0x00080040 /* Reset: EMPR */
-#define I40E_GL_ATQBAL_ATQBAL_SHIFT 0
-#define I40E_GL_ATQBAL_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ATQBAL_ATQBAL_SHIFT)
-#define I40E_GL_ATQH 0x00080340 /* Reset: EMPR */
-#define I40E_GL_ATQH_ATQH_SHIFT 0
-#define I40E_GL_ATQH_ATQH_MASK I40E_MASK(0x3FF, I40E_GL_ATQH_ATQH_SHIFT)
-#define I40E_GL_ATQLEN 0x00080240 /* Reset: EMPR */
-#define I40E_GL_ATQLEN_ATQLEN_SHIFT 0
-#define I40E_GL_ATQLEN_ATQLEN_MASK I40E_MASK(0x3FF, I40E_GL_ATQLEN_ATQLEN_SHIFT)
-#define I40E_GL_ATQLEN_ATQVFE_SHIFT 28
-#define I40E_GL_ATQLEN_ATQVFE_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQVFE_SHIFT)
-#define I40E_GL_ATQLEN_ATQOVFL_SHIFT 29
-#define I40E_GL_ATQLEN_ATQOVFL_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQOVFL_SHIFT)
#define I40E_GL_ATQLEN_ATQCRIT_SHIFT 30
#define I40E_GL_ATQLEN_ATQCRIT_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQCRIT_SHIFT)
-#define I40E_GL_ATQLEN_ATQENABLE_SHIFT 31
-#define I40E_GL_ATQLEN_ATQENABLE_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQENABLE_SHIFT)
-#define I40E_GL_ATQT 0x00080440 /* Reset: EMPR */
-#define I40E_GL_ATQT_ATQT_SHIFT 0
-#define I40E_GL_ATQT_ATQT_MASK I40E_MASK(0x3FF, I40E_GL_ATQT_ATQT_SHIFT)
#define I40E_PF_ARQBAH 0x00080180 /* Reset: EMPR */
-#define I40E_PF_ARQBAH_ARQBAH_SHIFT 0
-#define I40E_PF_ARQBAH_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ARQBAH_ARQBAH_SHIFT)
#define I40E_PF_ARQBAL 0x00080080 /* Reset: EMPR */
-#define I40E_PF_ARQBAL_ARQBAL_SHIFT 0
-#define I40E_PF_ARQBAL_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ARQBAL_ARQBAL_SHIFT)
#define I40E_PF_ARQH 0x00080380 /* Reset: EMPR */
#define I40E_PF_ARQH_ARQH_SHIFT 0
#define I40E_PF_ARQH_ARQH_MASK I40E_MASK(0x3FF, I40E_PF_ARQH_ARQH_SHIFT)
#define I40E_PF_ARQLEN 0x00080280 /* Reset: EMPR */
-#define I40E_PF_ARQLEN_ARQLEN_SHIFT 0
-#define I40E_PF_ARQLEN_ARQLEN_MASK I40E_MASK(0x3FF, I40E_PF_ARQLEN_ARQLEN_SHIFT)
#define I40E_PF_ARQLEN_ARQVFE_SHIFT 28
#define I40E_PF_ARQLEN_ARQVFE_MASK I40E_MASK(0x1, I40E_PF_ARQLEN_ARQVFE_SHIFT)
#define I40E_PF_ARQLEN_ARQOVFL_SHIFT 29
@@ -60,20 +21,10 @@
#define I40E_PF_ARQLEN_ARQENABLE_SHIFT 31
#define I40E_PF_ARQLEN_ARQENABLE_MASK I40E_MASK(0x1u, I40E_PF_ARQLEN_ARQENABLE_SHIFT)
#define I40E_PF_ARQT 0x00080480 /* Reset: EMPR */
-#define I40E_PF_ARQT_ARQT_SHIFT 0
-#define I40E_PF_ARQT_ARQT_MASK I40E_MASK(0x3FF, I40E_PF_ARQT_ARQT_SHIFT)
#define I40E_PF_ATQBAH 0x00080100 /* Reset: EMPR */
-#define I40E_PF_ATQBAH_ATQBAH_SHIFT 0
-#define I40E_PF_ATQBAH_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ATQBAH_ATQBAH_SHIFT)
#define I40E_PF_ATQBAL 0x00080000 /* Reset: EMPR */
-#define I40E_PF_ATQBAL_ATQBAL_SHIFT 0
-#define I40E_PF_ATQBAL_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ATQBAL_ATQBAL_SHIFT)
#define I40E_PF_ATQH 0x00080300 /* Reset: EMPR */
-#define I40E_PF_ATQH_ATQH_SHIFT 0
-#define I40E_PF_ATQH_ATQH_MASK I40E_MASK(0x3FF, I40E_PF_ATQH_ATQH_SHIFT)
#define I40E_PF_ATQLEN 0x00080200 /* Reset: EMPR */
-#define I40E_PF_ATQLEN_ATQLEN_SHIFT 0
-#define I40E_PF_ATQLEN_ATQLEN_MASK I40E_MASK(0x3FF, I40E_PF_ATQLEN_ATQLEN_SHIFT)
#define I40E_PF_ATQLEN_ATQVFE_SHIFT 28
#define I40E_PF_ATQLEN_ATQVFE_MASK I40E_MASK(0x1, I40E_PF_ATQLEN_ATQVFE_SHIFT)
#define I40E_PF_ATQLEN_ATQOVFL_SHIFT 29
@@ -83,786 +34,136 @@
#define I40E_PF_ATQLEN_ATQENABLE_SHIFT 31
#define I40E_PF_ATQLEN_ATQENABLE_MASK I40E_MASK(0x1u, I40E_PF_ATQLEN_ATQENABLE_SHIFT)
#define I40E_PF_ATQT 0x00080400 /* Reset: EMPR */
-#define I40E_PF_ATQT_ATQT_SHIFT 0
-#define I40E_PF_ATQT_ATQT_MASK I40E_MASK(0x3FF, I40E_PF_ATQT_ATQT_SHIFT)
-#define I40E_VF_ARQBAH(_VF) (0x00081400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ARQBAH_MAX_INDEX 127
-#define I40E_VF_ARQBAH_ARQBAH_SHIFT 0
-#define I40E_VF_ARQBAH_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAH_ARQBAH_SHIFT)
-#define I40E_VF_ARQBAL(_VF) (0x00080C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ARQBAL_MAX_INDEX 127
-#define I40E_VF_ARQBAL_ARQBAL_SHIFT 0
-#define I40E_VF_ARQBAL_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAL_ARQBAL_SHIFT)
-#define I40E_VF_ARQH(_VF) (0x00082400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ARQH_MAX_INDEX 127
-#define I40E_VF_ARQH_ARQH_SHIFT 0
-#define I40E_VF_ARQH_ARQH_MASK I40E_MASK(0x3FF, I40E_VF_ARQH_ARQH_SHIFT)
-#define I40E_VF_ARQLEN(_VF) (0x00081C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ARQLEN_MAX_INDEX 127
-#define I40E_VF_ARQLEN_ARQLEN_SHIFT 0
-#define I40E_VF_ARQLEN_ARQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ARQLEN_ARQLEN_SHIFT)
-#define I40E_VF_ARQLEN_ARQVFE_SHIFT 28
-#define I40E_VF_ARQLEN_ARQVFE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQVFE_SHIFT)
-#define I40E_VF_ARQLEN_ARQOVFL_SHIFT 29
-#define I40E_VF_ARQLEN_ARQOVFL_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQOVFL_SHIFT)
-#define I40E_VF_ARQLEN_ARQCRIT_SHIFT 30
-#define I40E_VF_ARQLEN_ARQCRIT_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQCRIT_SHIFT)
-#define I40E_VF_ARQLEN_ARQENABLE_SHIFT 31
-#define I40E_VF_ARQLEN_ARQENABLE_MASK I40E_MASK(0x1u, I40E_VF_ARQLEN_ARQENABLE_SHIFT)
-#define I40E_VF_ARQT(_VF) (0x00082C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ARQT_MAX_INDEX 127
-#define I40E_VF_ARQT_ARQT_SHIFT 0
-#define I40E_VF_ARQT_ARQT_MASK I40E_MASK(0x3FF, I40E_VF_ARQT_ARQT_SHIFT)
-#define I40E_VF_ATQBAH(_VF) (0x00081000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ATQBAH_MAX_INDEX 127
-#define I40E_VF_ATQBAH_ATQBAH_SHIFT 0
-#define I40E_VF_ATQBAH_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAH_ATQBAH_SHIFT)
-#define I40E_VF_ATQBAL(_VF) (0x00080800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ATQBAL_MAX_INDEX 127
-#define I40E_VF_ATQBAL_ATQBAL_SHIFT 0
-#define I40E_VF_ATQBAL_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAL_ATQBAL_SHIFT)
-#define I40E_VF_ATQH(_VF) (0x00082000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ATQH_MAX_INDEX 127
-#define I40E_VF_ATQH_ATQH_SHIFT 0
-#define I40E_VF_ATQH_ATQH_MASK I40E_MASK(0x3FF, I40E_VF_ATQH_ATQH_SHIFT)
-#define I40E_VF_ATQLEN(_VF) (0x00081800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ATQLEN_MAX_INDEX 127
-#define I40E_VF_ATQLEN_ATQLEN_SHIFT 0
-#define I40E_VF_ATQLEN_ATQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ATQLEN_ATQLEN_SHIFT)
-#define I40E_VF_ATQLEN_ATQVFE_SHIFT 28
-#define I40E_VF_ATQLEN_ATQVFE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQVFE_SHIFT)
-#define I40E_VF_ATQLEN_ATQOVFL_SHIFT 29
-#define I40E_VF_ATQLEN_ATQOVFL_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQOVFL_SHIFT)
-#define I40E_VF_ATQLEN_ATQCRIT_SHIFT 30
-#define I40E_VF_ATQLEN_ATQCRIT_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQCRIT_SHIFT)
-#define I40E_VF_ATQLEN_ATQENABLE_SHIFT 31
-#define I40E_VF_ATQLEN_ATQENABLE_MASK I40E_MASK(0x1u, I40E_VF_ATQLEN_ATQENABLE_SHIFT)
-#define I40E_VF_ATQT(_VF) (0x00082800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_VF_ATQT_MAX_INDEX 127
-#define I40E_VF_ATQT_ATQT_SHIFT 0
-#define I40E_VF_ATQT_ATQT_MASK I40E_MASK(0x3FF, I40E_VF_ATQT_ATQT_SHIFT)
-#define I40E_PRT_L2TAGSEN 0x001C0B20 /* Reset: CORER */
-#define I40E_PRT_L2TAGSEN_ENABLE_SHIFT 0
-#define I40E_PRT_L2TAGSEN_ENABLE_MASK I40E_MASK(0xFF, I40E_PRT_L2TAGSEN_ENABLE_SHIFT)
-#define I40E_PFCM_LAN_ERRDATA 0x0010C080 /* Reset: PFR */
-#define I40E_PFCM_LAN_ERRDATA_ERROR_CODE_SHIFT 0
-#define I40E_PFCM_LAN_ERRDATA_ERROR_CODE_MASK I40E_MASK(0xF, I40E_PFCM_LAN_ERRDATA_ERROR_CODE_SHIFT)
-#define I40E_PFCM_LAN_ERRDATA_Q_TYPE_SHIFT 4
-#define I40E_PFCM_LAN_ERRDATA_Q_TYPE_MASK I40E_MASK(0x7, I40E_PFCM_LAN_ERRDATA_Q_TYPE_SHIFT)
-#define I40E_PFCM_LAN_ERRDATA_Q_NUM_SHIFT 8
-#define I40E_PFCM_LAN_ERRDATA_Q_NUM_MASK I40E_MASK(0xFFF, I40E_PFCM_LAN_ERRDATA_Q_NUM_SHIFT)
-#define I40E_PFCM_LAN_ERRINFO 0x0010C000 /* Reset: PFR */
-#define I40E_PFCM_LAN_ERRINFO_ERROR_VALID_SHIFT 0
-#define I40E_PFCM_LAN_ERRINFO_ERROR_VALID_MASK I40E_MASK(0x1, I40E_PFCM_LAN_ERRINFO_ERROR_VALID_SHIFT)
-#define I40E_PFCM_LAN_ERRINFO_ERROR_INST_SHIFT 4
-#define I40E_PFCM_LAN_ERRINFO_ERROR_INST_MASK I40E_MASK(0x7, I40E_PFCM_LAN_ERRINFO_ERROR_INST_SHIFT)
-#define I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_SHIFT 8
-#define I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_SHIFT)
-#define I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_SHIFT 16
-#define I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_SHIFT)
-#define I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_SHIFT 24
-#define I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_SHIFT)
-#define I40E_PFCM_LANCTXCTL 0x0010C300 /* Reset: CORER */
-#define I40E_PFCM_LANCTXCTL_QUEUE_NUM_SHIFT 0
-#define I40E_PFCM_LANCTXCTL_QUEUE_NUM_MASK I40E_MASK(0xFFF, I40E_PFCM_LANCTXCTL_QUEUE_NUM_SHIFT)
-#define I40E_PFCM_LANCTXCTL_SUB_LINE_SHIFT 12
-#define I40E_PFCM_LANCTXCTL_SUB_LINE_MASK I40E_MASK(0x7, I40E_PFCM_LANCTXCTL_SUB_LINE_SHIFT)
-#define I40E_PFCM_LANCTXCTL_QUEUE_TYPE_SHIFT 15
-#define I40E_PFCM_LANCTXCTL_QUEUE_TYPE_MASK I40E_MASK(0x3, I40E_PFCM_LANCTXCTL_QUEUE_TYPE_SHIFT)
-#define I40E_PFCM_LANCTXCTL_OP_CODE_SHIFT 17
-#define I40E_PFCM_LANCTXCTL_OP_CODE_MASK I40E_MASK(0x3, I40E_PFCM_LANCTXCTL_OP_CODE_SHIFT)
-#define I40E_PFCM_LANCTXDATA(_i) (0x0010C100 + ((_i) * 128)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_PFCM_LANCTXDATA_MAX_INDEX 3
-#define I40E_PFCM_LANCTXDATA_DATA_SHIFT 0
-#define I40E_PFCM_LANCTXDATA_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_PFCM_LANCTXDATA_DATA_SHIFT)
-#define I40E_PFCM_LANCTXSTAT 0x0010C380 /* Reset: CORER */
-#define I40E_PFCM_LANCTXSTAT_CTX_DONE_SHIFT 0
-#define I40E_PFCM_LANCTXSTAT_CTX_DONE_MASK I40E_MASK(0x1, I40E_PFCM_LANCTXSTAT_CTX_DONE_SHIFT)
-#define I40E_PFCM_LANCTXSTAT_CTX_MISS_SHIFT 1
-#define I40E_PFCM_LANCTXSTAT_CTX_MISS_MASK I40E_MASK(0x1, I40E_PFCM_LANCTXSTAT_CTX_MISS_SHIFT)
-#define I40E_VFCM_PE_ERRDATA1(_VF) (0x00138800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFCM_PE_ERRDATA1_MAX_INDEX 127
-#define I40E_VFCM_PE_ERRDATA1_ERROR_CODE_SHIFT 0
-#define I40E_VFCM_PE_ERRDATA1_ERROR_CODE_MASK I40E_MASK(0xF, I40E_VFCM_PE_ERRDATA1_ERROR_CODE_SHIFT)
-#define I40E_VFCM_PE_ERRDATA1_Q_TYPE_SHIFT 4
-#define I40E_VFCM_PE_ERRDATA1_Q_TYPE_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRDATA1_Q_TYPE_SHIFT)
-#define I40E_VFCM_PE_ERRDATA1_Q_NUM_SHIFT 8
-#define I40E_VFCM_PE_ERRDATA1_Q_NUM_MASK I40E_MASK(0x3FFFF, I40E_VFCM_PE_ERRDATA1_Q_NUM_SHIFT)
-#define I40E_VFCM_PE_ERRINFO1(_VF) (0x00138400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFCM_PE_ERRINFO1_MAX_INDEX 127
-#define I40E_VFCM_PE_ERRINFO1_ERROR_VALID_SHIFT 0
-#define I40E_VFCM_PE_ERRINFO1_ERROR_VALID_MASK I40E_MASK(0x1, I40E_VFCM_PE_ERRINFO1_ERROR_VALID_SHIFT)
-#define I40E_VFCM_PE_ERRINFO1_ERROR_INST_SHIFT 4
-#define I40E_VFCM_PE_ERRINFO1_ERROR_INST_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRINFO1_ERROR_INST_SHIFT)
-#define I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_SHIFT 8
-#define I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_SHIFT)
-#define I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_SHIFT 16
-#define I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_SHIFT)
-#define I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_SHIFT 24
-#define I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_SHIFT)
-#define I40E_GLDCB_GENC 0x00083044 /* Reset: CORER */
-#define I40E_GLDCB_GENC_PCIRTT_SHIFT 0
-#define I40E_GLDCB_GENC_PCIRTT_MASK I40E_MASK(0xFFFF, I40E_GLDCB_GENC_PCIRTT_SHIFT)
-#define I40E_GLDCB_RUPTI 0x00122618 /* Reset: CORER */
-#define I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_SHIFT 0
-#define I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_SHIFT)
-#define I40E_PRTDCB_FCCFG 0x001E4640 /* Reset: GLOBR */
-#define I40E_PRTDCB_FCCFG_TFCE_SHIFT 3
-#define I40E_PRTDCB_FCCFG_TFCE_MASK I40E_MASK(0x3, I40E_PRTDCB_FCCFG_TFCE_SHIFT)
-#define I40E_PRTDCB_FCRTV 0x001E4600 /* Reset: GLOBR */
-#define I40E_PRTDCB_FCRTV_FC_REFRESH_TH_SHIFT 0
-#define I40E_PRTDCB_FCRTV_FC_REFRESH_TH_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_FCRTV_FC_REFRESH_TH_SHIFT)
-#define I40E_PRTDCB_FCTTVN(_i) (0x001E4580 + ((_i) * 32)) /* _i=0...3 */ /* Reset: GLOBR */
-#define I40E_PRTDCB_FCTTVN_MAX_INDEX 3
-#define I40E_PRTDCB_FCTTVN_TTV_2N_SHIFT 0
-#define I40E_PRTDCB_FCTTVN_TTV_2N_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_FCTTVN_TTV_2N_SHIFT)
-#define I40E_PRTDCB_FCTTVN_TTV_2N_P1_SHIFT 16
-#define I40E_PRTDCB_FCTTVN_TTV_2N_P1_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_FCTTVN_TTV_2N_P1_SHIFT)
#define I40E_PRTDCB_GENC 0x00083000 /* Reset: CORER */
-#define I40E_PRTDCB_GENC_RESERVED_1_SHIFT 0
-#define I40E_PRTDCB_GENC_RESERVED_1_MASK I40E_MASK(0x3, I40E_PRTDCB_GENC_RESERVED_1_SHIFT)
-#define I40E_PRTDCB_GENC_NUMTC_SHIFT 2
-#define I40E_PRTDCB_GENC_NUMTC_MASK I40E_MASK(0xF, I40E_PRTDCB_GENC_NUMTC_SHIFT)
-#define I40E_PRTDCB_GENC_FCOEUP_SHIFT 6
-#define I40E_PRTDCB_GENC_FCOEUP_MASK I40E_MASK(0x7, I40E_PRTDCB_GENC_FCOEUP_SHIFT)
-#define I40E_PRTDCB_GENC_FCOEUP_VALID_SHIFT 9
-#define I40E_PRTDCB_GENC_FCOEUP_VALID_MASK I40E_MASK(0x1, I40E_PRTDCB_GENC_FCOEUP_VALID_SHIFT)
#define I40E_PRTDCB_GENC_PFCLDA_SHIFT 16
#define I40E_PRTDCB_GENC_PFCLDA_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_GENC_PFCLDA_SHIFT)
#define I40E_PRTDCB_GENS 0x00083020 /* Reset: CORER */
#define I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT 0
#define I40E_PRTDCB_GENS_DCBX_STATUS_MASK I40E_MASK(0x7, I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT)
-#define I40E_PRTDCB_MFLCN 0x001E2400 /* Reset: GLOBR */
-#define I40E_PRTDCB_MFLCN_PMCF_SHIFT 0
-#define I40E_PRTDCB_MFLCN_PMCF_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_PMCF_SHIFT)
-#define I40E_PRTDCB_MFLCN_DPF_SHIFT 1
-#define I40E_PRTDCB_MFLCN_DPF_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_DPF_SHIFT)
-#define I40E_PRTDCB_MFLCN_RPFCM_SHIFT 2
-#define I40E_PRTDCB_MFLCN_RPFCM_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_RPFCM_SHIFT)
-#define I40E_PRTDCB_MFLCN_RFCE_SHIFT 3
-#define I40E_PRTDCB_MFLCN_RFCE_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_RFCE_SHIFT)
-#define I40E_PRTDCB_MFLCN_RPFCE_SHIFT 4
-#define I40E_PRTDCB_MFLCN_RPFCE_MASK I40E_MASK(0xFF, I40E_PRTDCB_MFLCN_RPFCE_SHIFT)
-#define I40E_PRTDCB_RETSC 0x001223E0 /* Reset: CORER */
-#define I40E_PRTDCB_RETSC_ETS_MODE_SHIFT 0
-#define I40E_PRTDCB_RETSC_ETS_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSC_ETS_MODE_SHIFT)
-#define I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT 1
-#define I40E_PRTDCB_RETSC_NON_ETS_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT)
-#define I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT 2
-#define I40E_PRTDCB_RETSC_ETS_MAX_EXP_MASK I40E_MASK(0xF, I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT)
-#define I40E_PRTDCB_RETSC_LLTC_SHIFT 8
-#define I40E_PRTDCB_RETSC_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_RETSC_LLTC_SHIFT)
-#define I40E_PRTDCB_RETSTCC(_i) (0x00122180 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTDCB_RETSTCC_MAX_INDEX 7
-#define I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT 0
-#define I40E_PRTDCB_RETSTCC_BWSHARE_MASK I40E_MASK(0x7F, I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT)
-#define I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT 30
-#define I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT)
-#define I40E_PRTDCB_RETSTCC_ETSTC_SHIFT 31
-#define I40E_PRTDCB_RETSTCC_ETSTC_MASK I40E_MASK(0x1u, I40E_PRTDCB_RETSTCC_ETSTC_SHIFT)
-#define I40E_PRTDCB_RPPMC 0x001223A0 /* Reset: CORER */
-#define I40E_PRTDCB_RPPMC_LANRPPM_SHIFT 0
-#define I40E_PRTDCB_RPPMC_LANRPPM_MASK I40E_MASK(0xFF, I40E_PRTDCB_RPPMC_LANRPPM_SHIFT)
-#define I40E_PRTDCB_RPPMC_RDMARPPM_SHIFT 8
-#define I40E_PRTDCB_RPPMC_RDMARPPM_MASK I40E_MASK(0xFF, I40E_PRTDCB_RPPMC_RDMARPPM_SHIFT)
-#define I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT 16
-#define I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_MASK I40E_MASK(0xFF, I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT)
-#define I40E_PRTDCB_RUP 0x001C0B00 /* Reset: CORER */
-#define I40E_PRTDCB_RUP_NOVLANUP_SHIFT 0
-#define I40E_PRTDCB_RUP_NOVLANUP_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP_NOVLANUP_SHIFT)
-#define I40E_PRTDCB_RUP2TC 0x001C09A0 /* Reset: CORER */
-#define I40E_PRTDCB_RUP2TC_UP0TC_SHIFT 0
-#define I40E_PRTDCB_RUP2TC_UP0TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP0TC_SHIFT)
-#define I40E_PRTDCB_RUP2TC_UP1TC_SHIFT 3
-#define I40E_PRTDCB_RUP2TC_UP1TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP1TC_SHIFT)
-#define I40E_PRTDCB_RUP2TC_UP2TC_SHIFT 6
-#define I40E_PRTDCB_RUP2TC_UP2TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP2TC_SHIFT)
-#define I40E_PRTDCB_RUP2TC_UP3TC_SHIFT 9
-#define I40E_PRTDCB_RUP2TC_UP3TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP3TC_SHIFT)
-#define I40E_PRTDCB_RUP2TC_UP4TC_SHIFT 12
-#define I40E_PRTDCB_RUP2TC_UP4TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP4TC_SHIFT)
-#define I40E_PRTDCB_RUP2TC_UP5TC_SHIFT 15
-#define I40E_PRTDCB_RUP2TC_UP5TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP5TC_SHIFT)
-#define I40E_PRTDCB_RUP2TC_UP6TC_SHIFT 18
-#define I40E_PRTDCB_RUP2TC_UP6TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP6TC_SHIFT)
-#define I40E_PRTDCB_RUP2TC_UP7TC_SHIFT 21
-#define I40E_PRTDCB_RUP2TC_UP7TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP7TC_SHIFT)
-#define I40E_PRTDCB_RUPTQ(_i) (0x00122400 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTDCB_RUPTQ_MAX_INDEX 7
-#define I40E_PRTDCB_RUPTQ_RXQNUM_SHIFT 0
-#define I40E_PRTDCB_RUPTQ_RXQNUM_MASK I40E_MASK(0x3FFF, I40E_PRTDCB_RUPTQ_RXQNUM_SHIFT)
-#define I40E_PRTDCB_TC2PFC 0x001C0980 /* Reset: CORER */
-#define I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT 0
-#define I40E_PRTDCB_TC2PFC_TC2PFC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT)
-#define I40E_PRTDCB_TCMSTC(_i) (0x000A0040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTDCB_TCMSTC_MAX_INDEX 7
-#define I40E_PRTDCB_TCMSTC_MSTC_SHIFT 0
-#define I40E_PRTDCB_TCMSTC_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TCMSTC_MSTC_SHIFT)
-#define I40E_PRTDCB_TCPMC 0x000A21A0 /* Reset: CORER */
-#define I40E_PRTDCB_TCPMC_CPM_SHIFT 0
-#define I40E_PRTDCB_TCPMC_CPM_MASK I40E_MASK(0x1FFF, I40E_PRTDCB_TCPMC_CPM_SHIFT)
-#define I40E_PRTDCB_TCPMC_LLTC_SHIFT 13
-#define I40E_PRTDCB_TCPMC_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TCPMC_LLTC_SHIFT)
-#define I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT 30
-#define I40E_PRTDCB_TCPMC_TCPM_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT)
-#define I40E_PRTDCB_TCWSTC(_i) (0x000A2040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTDCB_TCWSTC_MAX_INDEX 7
-#define I40E_PRTDCB_TCWSTC_MSTC_SHIFT 0
-#define I40E_PRTDCB_TCWSTC_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TCWSTC_MSTC_SHIFT)
-#define I40E_PRTDCB_TDPMC 0x000A0180 /* Reset: CORER */
-#define I40E_PRTDCB_TDPMC_DPM_SHIFT 0
-#define I40E_PRTDCB_TDPMC_DPM_MASK I40E_MASK(0xFF, I40E_PRTDCB_TDPMC_DPM_SHIFT)
-#define I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT 30
-#define I40E_PRTDCB_TDPMC_TCPM_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT)
-#define I40E_PRTDCB_TETSC_TCB 0x000AE060 /* Reset: CORER */
-#define I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_SHIFT 0
-#define I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_MASK I40E_MASK(0x1, I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_SHIFT)
-#define I40E_PRTDCB_TETSC_TCB_LLTC_SHIFT 8
-#define I40E_PRTDCB_TETSC_TCB_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TETSC_TCB_LLTC_SHIFT)
-#define I40E_PRTDCB_TETSC_TPB 0x00098060 /* Reset: CORER */
-#define I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_SHIFT 0
-#define I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_MASK I40E_MASK(0x1, I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_SHIFT)
-#define I40E_PRTDCB_TETSC_TPB_LLTC_SHIFT 8
-#define I40E_PRTDCB_TETSC_TPB_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TETSC_TPB_LLTC_SHIFT)
-#define I40E_PRTDCB_TFCS 0x001E4560 /* Reset: GLOBR */
-#define I40E_PRTDCB_TFCS_TXOFF_SHIFT 0
-#define I40E_PRTDCB_TFCS_TXOFF_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF_SHIFT)
-#define I40E_PRTDCB_TFCS_TXOFF0_SHIFT 8
-#define I40E_PRTDCB_TFCS_TXOFF0_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF0_SHIFT)
-#define I40E_PRTDCB_TFCS_TXOFF1_SHIFT 9
-#define I40E_PRTDCB_TFCS_TXOFF1_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF1_SHIFT)
-#define I40E_PRTDCB_TFCS_TXOFF2_SHIFT 10
-#define I40E_PRTDCB_TFCS_TXOFF2_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF2_SHIFT)
-#define I40E_PRTDCB_TFCS_TXOFF3_SHIFT 11
-#define I40E_PRTDCB_TFCS_TXOFF3_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF3_SHIFT)
-#define I40E_PRTDCB_TFCS_TXOFF4_SHIFT 12
-#define I40E_PRTDCB_TFCS_TXOFF4_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF4_SHIFT)
-#define I40E_PRTDCB_TFCS_TXOFF5_SHIFT 13
-#define I40E_PRTDCB_TFCS_TXOFF5_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF5_SHIFT)
-#define I40E_PRTDCB_TFCS_TXOFF6_SHIFT 14
-#define I40E_PRTDCB_TFCS_TXOFF6_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF6_SHIFT)
-#define I40E_PRTDCB_TFCS_TXOFF7_SHIFT 15
-#define I40E_PRTDCB_TFCS_TXOFF7_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF7_SHIFT)
-#define I40E_PRTDCB_TPFCTS(_i) (0x001E4660 + ((_i) * 32)) /* _i=0...7 */ /* Reset: GLOBR */
-#define I40E_PRTDCB_TPFCTS_MAX_INDEX 7
-#define I40E_PRTDCB_TPFCTS_PFCTIMER_SHIFT 0
-#define I40E_PRTDCB_TPFCTS_PFCTIMER_MASK I40E_MASK(0x3FFF, I40E_PRTDCB_TPFCTS_PFCTIMER_SHIFT)
-#define I40E_GLFCOE_RCTL 0x00269B94 /* Reset: CORER */
-#define I40E_GLFCOE_RCTL_FCOEVER_SHIFT 0
-#define I40E_GLFCOE_RCTL_FCOEVER_MASK I40E_MASK(0xF, I40E_GLFCOE_RCTL_FCOEVER_SHIFT)
-#define I40E_GLFCOE_RCTL_SAVBAD_SHIFT 4
-#define I40E_GLFCOE_RCTL_SAVBAD_MASK I40E_MASK(0x1, I40E_GLFCOE_RCTL_SAVBAD_SHIFT)
-#define I40E_GLFCOE_RCTL_ICRC_SHIFT 5
-#define I40E_GLFCOE_RCTL_ICRC_MASK I40E_MASK(0x1, I40E_GLFCOE_RCTL_ICRC_SHIFT)
-#define I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT 16
-#define I40E_GLFCOE_RCTL_MAX_SIZE_MASK I40E_MASK(0x3FFF, I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT)
#define I40E_GL_FWSTS 0x00083048 /* Reset: POR */
-#define I40E_GL_FWSTS_FWS0B_SHIFT 0
-#define I40E_GL_FWSTS_FWS0B_MASK I40E_MASK(0xFF, I40E_GL_FWSTS_FWS0B_SHIFT)
-#define I40E_GL_FWSTS_FWRI_SHIFT 9
-#define I40E_GL_FWSTS_FWRI_MASK I40E_MASK(0x1, I40E_GL_FWSTS_FWRI_SHIFT)
#define I40E_GL_FWSTS_FWS1B_SHIFT 16
#define I40E_GL_FWSTS_FWS1B_MASK I40E_MASK(0xFF, I40E_GL_FWSTS_FWS1B_SHIFT)
+#define I40E_GL_FWSTS_FWS1B_EMPR_0 I40E_MASK(0x20, I40E_GL_FWSTS_FWS1B_SHIFT)
+#define I40E_GL_FWSTS_FWS1B_EMPR_10 I40E_MASK(0x2A, I40E_GL_FWSTS_FWS1B_SHIFT)
#define I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_CORER_MASK I40E_MASK(0x30, I40E_GL_FWSTS_FWS1B_SHIFT)
#define I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_GLOBR_MASK I40E_MASK(0x31, I40E_GL_FWSTS_FWS1B_SHIFT)
#define I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_TRANSITION_MASK I40E_MASK(0x32, I40E_GL_FWSTS_FWS1B_SHIFT)
#define I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_NVM_MASK I40E_MASK(0x33, I40E_GL_FWSTS_FWS1B_SHIFT)
#define I40E_X722_GL_FWSTS_FWS1B_REC_MOD_CORER_MASK I40E_MASK(0xB, I40E_GL_FWSTS_FWS1B_SHIFT)
#define I40E_X722_GL_FWSTS_FWS1B_REC_MOD_GLOBR_MASK I40E_MASK(0xC, I40E_GL_FWSTS_FWS1B_SHIFT)
-#define I40E_GLGEN_CLKSTAT 0x000B8184 /* Reset: POR */
-#define I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT 0
-#define I40E_GLGEN_CLKSTAT_CLKMODE_MASK I40E_MASK(0x1, I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT)
-#define I40E_GLGEN_CLKSTAT_U_CLK_SPEED_SHIFT 4
-#define I40E_GLGEN_CLKSTAT_U_CLK_SPEED_MASK I40E_MASK(0x3, I40E_GLGEN_CLKSTAT_U_CLK_SPEED_SHIFT)
-#define I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_SHIFT 8
-#define I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_SHIFT)
-#define I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_SHIFT 12
-#define I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_SHIFT)
-#define I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_SHIFT 16
-#define I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_SHIFT)
-#define I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_SHIFT 20
-#define I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_SHIFT)
#define I40E_GLGEN_GPIO_CTL(_i) (0x00088100 + ((_i) * 4)) /* _i=0...29 */ /* Reset: POR */
#define I40E_GLGEN_GPIO_CTL_MAX_INDEX 29
#define I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT 0
#define I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK I40E_MASK(0x3, I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_SHIFT 3
#define I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_SHIFT)
-#define I40E_GLGEN_GPIO_CTL_PIN_DIR_SHIFT 4
-#define I40E_GLGEN_GPIO_CTL_PIN_DIR_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_PIN_DIR_SHIFT)
-#define I40E_GLGEN_GPIO_CTL_TRI_CTL_SHIFT 5
-#define I40E_GLGEN_GPIO_CTL_TRI_CTL_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_TRI_CTL_SHIFT)
-#define I40E_GLGEN_GPIO_CTL_OUT_CTL_SHIFT 6
-#define I40E_GLGEN_GPIO_CTL_OUT_CTL_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_OUT_CTL_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT 7
#define I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK I40E_MASK(0x7, I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT)
-#define I40E_GLGEN_GPIO_CTL_LED_INVRT_SHIFT 10
-#define I40E_GLGEN_GPIO_CTL_LED_INVRT_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_LED_INVRT_SHIFT)
#define I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT 11
-#define I40E_GLGEN_GPIO_CTL_LED_BLINK_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT)
#define I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT 12
#define I40E_GLGEN_GPIO_CTL_LED_MODE_MASK I40E_MASK(0x1F, I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT)
-#define I40E_GLGEN_GPIO_CTL_INT_MODE_SHIFT 17
-#define I40E_GLGEN_GPIO_CTL_INT_MODE_MASK I40E_MASK(0x3, I40E_GLGEN_GPIO_CTL_INT_MODE_SHIFT)
-#define I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_SHIFT 19
-#define I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_SHIFT)
-#define I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_SHIFT 20
-#define I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_MASK I40E_MASK(0x3F, I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_SHIFT)
-#define I40E_GLGEN_GPIO_CTL_PRT_BIT_MAP_SHIFT 26
-#define I40E_GLGEN_GPIO_CTL_PRT_BIT_MAP_MASK I40E_MASK(0xF, I40E_GLGEN_GPIO_CTL_PRT_BIT_MAP_SHIFT)
-#define I40E_GLGEN_GPIO_SET 0x00088184 /* Reset: POR */
-#define I40E_GLGEN_GPIO_SET_GPIO_INDX_SHIFT 0
-#define I40E_GLGEN_GPIO_SET_GPIO_INDX_MASK I40E_MASK(0x1F, I40E_GLGEN_GPIO_SET_GPIO_INDX_SHIFT)
-#define I40E_GLGEN_GPIO_SET_SDP_DATA_SHIFT 5
-#define I40E_GLGEN_GPIO_SET_SDP_DATA_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_SET_SDP_DATA_SHIFT)
-#define I40E_GLGEN_GPIO_SET_DRIVE_SDP_SHIFT 6
-#define I40E_GLGEN_GPIO_SET_DRIVE_SDP_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_SET_DRIVE_SDP_SHIFT)
-#define I40E_GLGEN_GPIO_STAT 0x0008817C /* Reset: POR */
-#define I40E_GLGEN_GPIO_STAT_GPIO_VALUE_SHIFT 0
-#define I40E_GLGEN_GPIO_STAT_GPIO_VALUE_MASK I40E_MASK(0x3FFFFFFF, I40E_GLGEN_GPIO_STAT_GPIO_VALUE_SHIFT)
-#define I40E_GLGEN_GPIO_TRANSIT 0x00088180 /* Reset: POR */
-#define I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_SHIFT 0
-#define I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_MASK I40E_MASK(0x3FFFFFFF, I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_SHIFT)
-#define I40E_GLGEN_I2CCMD(_i) (0x000881E0 + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_GLGEN_I2CCMD_MAX_INDEX 3
-#define I40E_GLGEN_I2CCMD_DATA_SHIFT 0
-#define I40E_GLGEN_I2CCMD_DATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_I2CCMD_DATA_SHIFT)
-#define I40E_GLGEN_I2CCMD_REGADD_SHIFT 16
-#define I40E_GLGEN_I2CCMD_REGADD_MASK I40E_MASK(0xFF, I40E_GLGEN_I2CCMD_REGADD_SHIFT)
-#define I40E_GLGEN_I2CCMD_PHYADD_SHIFT 24
-#define I40E_GLGEN_I2CCMD_PHYADD_MASK I40E_MASK(0x7, I40E_GLGEN_I2CCMD_PHYADD_SHIFT)
-#define I40E_GLGEN_I2CCMD_OP_SHIFT 27
-#define I40E_GLGEN_I2CCMD_OP_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_OP_SHIFT)
-#define I40E_GLGEN_I2CCMD_RESET_SHIFT 28
-#define I40E_GLGEN_I2CCMD_RESET_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_RESET_SHIFT)
-#define I40E_GLGEN_I2CCMD_R_SHIFT 29
-#define I40E_GLGEN_I2CCMD_R_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_R_SHIFT)
-#define I40E_GLGEN_I2CCMD_E_SHIFT 31
-#define I40E_GLGEN_I2CCMD_E_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_E_SHIFT)
-#define I40E_GLGEN_I2CPARAMS(_i) (0x000881AC + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_GLGEN_I2CPARAMS_MAX_INDEX 3
-#define I40E_GLGEN_I2CPARAMS_WRITE_TIME_SHIFT 0
-#define I40E_GLGEN_I2CPARAMS_WRITE_TIME_MASK I40E_MASK(0x1F, I40E_GLGEN_I2CPARAMS_WRITE_TIME_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_READ_TIME_SHIFT 5
-#define I40E_GLGEN_I2CPARAMS_READ_TIME_MASK I40E_MASK(0x7, I40E_GLGEN_I2CPARAMS_READ_TIME_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_I2CBB_EN_SHIFT 8
-#define I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_I2CBB_EN_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_CLK_SHIFT 9
-#define I40E_GLGEN_I2CPARAMS_CLK_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_DATA_OUT_SHIFT 10
-#define I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_DATA_OUT_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_DATA_OE_N_SHIFT 11
-#define I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_DATA_OE_N_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_DATA_IN_SHIFT 12
-#define I40E_GLGEN_I2CPARAMS_DATA_IN_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_DATA_IN_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_CLK_OE_N_SHIFT 13
-#define I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_OE_N_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_CLK_IN_SHIFT 14
-#define I40E_GLGEN_I2CPARAMS_CLK_IN_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_IN_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_SHIFT 15
-#define I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_SHIFT)
-#define I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_SHIFT 31
-#define I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_SHIFT)
-#define I40E_GLGEN_LED_CTL 0x00088178 /* Reset: POR */
-#define I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_SHIFT 0
-#define I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_MASK I40E_MASK(0x1, I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_SHIFT)
-#define I40E_GLGEN_MDIO_CTRL(_i) (0x000881D0 + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_GLGEN_MDIO_CTRL_MAX_INDEX 3
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_SHIFT 0
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_MASK I40E_MASK(0x1FFFF, I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_SHIFT)
-#define I40E_GLGEN_MDIO_CTRL_CONTMDC_SHIFT 17
-#define I40E_GLGEN_MDIO_CTRL_CONTMDC_MASK I40E_MASK(0x1, I40E_GLGEN_MDIO_CTRL_CONTMDC_SHIFT)
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_SHIFT 18
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_MASK I40E_MASK(0x7FF, I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_SHIFT)
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD0_SHIFT 29
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD0_MASK I40E_MASK(0x7, I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD0_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL(_i) (0x000881C0 + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_GLGEN_MDIO_I2C_SEL_MAX_INDEX 3
-#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_SHIFT 0
-#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_MASK I40E_MASK(0x1, I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_SHIFT)
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_SHIFT 1
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_MASK I40E_MASK(0xF, I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_SHIFT)
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_SHIFT 5
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_SHIFT)
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_SHIFT 10
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_SHIFT)
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_SHIFT 15
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_SHIFT)
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_SHIFT 20
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_SHIFT)
-#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_SHIFT 25
-#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_MASK I40E_MASK(0xF, I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_SHIFT)
-#define I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_SHIFT 31
-#define I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_MASK I40E_MASK(0x1, I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_SHIFT)
#define I40E_GLGEN_MSCA(_i) (0x0008818C + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_GLGEN_MSCA_MAX_INDEX 3
#define I40E_GLGEN_MSCA_MDIADD_SHIFT 0
-#define I40E_GLGEN_MSCA_MDIADD_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSCA_MDIADD_SHIFT)
#define I40E_GLGEN_MSCA_DEVADD_SHIFT 16
-#define I40E_GLGEN_MSCA_DEVADD_MASK I40E_MASK(0x1F, I40E_GLGEN_MSCA_DEVADD_SHIFT)
#define I40E_GLGEN_MSCA_PHYADD_SHIFT 21
-#define I40E_GLGEN_MSCA_PHYADD_MASK I40E_MASK(0x1F, I40E_GLGEN_MSCA_PHYADD_SHIFT)
#define I40E_GLGEN_MSCA_OPCODE_SHIFT 26
-#define I40E_GLGEN_MSCA_OPCODE_MASK I40E_MASK(0x3, I40E_GLGEN_MSCA_OPCODE_SHIFT)
#define I40E_GLGEN_MSCA_STCODE_SHIFT 28
-#define I40E_GLGEN_MSCA_STCODE_MASK I40E_MASK(0x3, I40E_GLGEN_MSCA_STCODE_SHIFT)
#define I40E_GLGEN_MSCA_MDICMD_SHIFT 30
#define I40E_GLGEN_MSCA_MDICMD_MASK I40E_MASK(0x1, I40E_GLGEN_MSCA_MDICMD_SHIFT)
#define I40E_GLGEN_MSCA_MDIINPROGEN_SHIFT 31
#define I40E_GLGEN_MSCA_MDIINPROGEN_MASK I40E_MASK(0x1u, I40E_GLGEN_MSCA_MDIINPROGEN_SHIFT)
#define I40E_GLGEN_MSRWD(_i) (0x0008819C + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_GLGEN_MSRWD_MAX_INDEX 3
#define I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT 0
-#define I40E_GLGEN_MSRWD_MDIWRDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT)
#define I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT 16
#define I40E_GLGEN_MSRWD_MDIRDDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT)
-#define I40E_GLGEN_PCIFCNCNT 0x001C0AB4 /* Reset: PCIR */
-#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT 0
-#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK I40E_MASK(0x1F, I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT)
-#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT 16
-#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK I40E_MASK(0xFF, I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT)
#define I40E_GLGEN_RSTAT 0x000B8188 /* Reset: POR */
#define I40E_GLGEN_RSTAT_DEVSTATE_SHIFT 0
#define I40E_GLGEN_RSTAT_DEVSTATE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_DEVSTATE_SHIFT)
#define I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT 2
#define I40E_GLGEN_RSTAT_RESET_TYPE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT)
-#define I40E_GLGEN_RSTAT_CORERCNT_SHIFT 4
-#define I40E_GLGEN_RSTAT_CORERCNT_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_CORERCNT_SHIFT)
-#define I40E_GLGEN_RSTAT_GLOBRCNT_SHIFT 6
-#define I40E_GLGEN_RSTAT_GLOBRCNT_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_GLOBRCNT_SHIFT)
-#define I40E_GLGEN_RSTAT_EMPRCNT_SHIFT 8
-#define I40E_GLGEN_RSTAT_EMPRCNT_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_EMPRCNT_SHIFT)
-#define I40E_GLGEN_RSTAT_TIME_TO_RST_SHIFT 10
-#define I40E_GLGEN_RSTAT_TIME_TO_RST_MASK I40E_MASK(0x3F, I40E_GLGEN_RSTAT_TIME_TO_RST_SHIFT)
#define I40E_GLGEN_RSTCTL 0x000B8180 /* Reset: POR */
#define I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT 0
#define I40E_GLGEN_RSTCTL_GRSTDEL_MASK I40E_MASK(0x3F, I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT)
-#define I40E_GLGEN_RSTCTL_ECC_RST_ENA_SHIFT 8
-#define I40E_GLGEN_RSTCTL_ECC_RST_ENA_MASK I40E_MASK(0x1, I40E_GLGEN_RSTCTL_ECC_RST_ENA_SHIFT)
#define I40E_GLGEN_RTRIG 0x000B8190 /* Reset: CORER */
#define I40E_GLGEN_RTRIG_CORER_SHIFT 0
#define I40E_GLGEN_RTRIG_CORER_MASK I40E_MASK(0x1, I40E_GLGEN_RTRIG_CORER_SHIFT)
#define I40E_GLGEN_RTRIG_GLOBR_SHIFT 1
#define I40E_GLGEN_RTRIG_GLOBR_MASK I40E_MASK(0x1, I40E_GLGEN_RTRIG_GLOBR_SHIFT)
-#define I40E_GLGEN_RTRIG_EMPFWR_SHIFT 2
-#define I40E_GLGEN_RTRIG_EMPFWR_MASK I40E_MASK(0x1, I40E_GLGEN_RTRIG_EMPFWR_SHIFT)
#define I40E_GLGEN_STAT 0x000B612C /* Reset: POR */
-#define I40E_GLGEN_STAT_HWRSVD0_SHIFT 0
-#define I40E_GLGEN_STAT_HWRSVD0_MASK I40E_MASK(0x3, I40E_GLGEN_STAT_HWRSVD0_SHIFT)
-#define I40E_GLGEN_STAT_DCBEN_SHIFT 2
-#define I40E_GLGEN_STAT_DCBEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_DCBEN_SHIFT)
-#define I40E_GLGEN_STAT_VTEN_SHIFT 3
-#define I40E_GLGEN_STAT_VTEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_VTEN_SHIFT)
-#define I40E_GLGEN_STAT_FCOEN_SHIFT 4
-#define I40E_GLGEN_STAT_FCOEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_FCOEN_SHIFT)
-#define I40E_GLGEN_STAT_EVBEN_SHIFT 5
-#define I40E_GLGEN_STAT_EVBEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_EVBEN_SHIFT)
-#define I40E_GLGEN_STAT_HWRSVD1_SHIFT 6
-#define I40E_GLGEN_STAT_HWRSVD1_MASK I40E_MASK(0x3, I40E_GLGEN_STAT_HWRSVD1_SHIFT)
#define I40E_GLGEN_VFLRSTAT(_i) (0x00092600 + ((_i) * 4)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLGEN_VFLRSTAT_MAX_INDEX 3
-#define I40E_GLGEN_VFLRSTAT_VFLRE_SHIFT 0
-#define I40E_GLGEN_VFLRSTAT_VFLRE_MASK I40E_MASK(0xFFFFFFFF, I40E_GLGEN_VFLRSTAT_VFLRE_SHIFT)
#define I40E_GLVFGEN_TIMER 0x000881BC /* Reset: CORER */
-#define I40E_GLVFGEN_TIMER_GTIME_SHIFT 0
-#define I40E_GLVFGEN_TIMER_GTIME_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVFGEN_TIMER_GTIME_SHIFT)
#define I40E_PFGEN_CTRL 0x00092400 /* Reset: PFR */
#define I40E_PFGEN_CTRL_PFSWR_SHIFT 0
#define I40E_PFGEN_CTRL_PFSWR_MASK I40E_MASK(0x1, I40E_PFGEN_CTRL_PFSWR_SHIFT)
-#define I40E_PFGEN_DRUN 0x00092500 /* Reset: CORER */
-#define I40E_PFGEN_DRUN_DRVUNLD_SHIFT 0
-#define I40E_PFGEN_DRUN_DRVUNLD_MASK I40E_MASK(0x1, I40E_PFGEN_DRUN_DRVUNLD_SHIFT)
#define I40E_PFGEN_PORTNUM 0x001C0480 /* Reset: CORER */
#define I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT 0
#define I40E_PFGEN_PORTNUM_PORT_NUM_MASK I40E_MASK(0x3, I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT)
-#define I40E_PFGEN_STATE 0x00088000 /* Reset: CORER */
-#define I40E_PFGEN_STATE_RESERVED_0_SHIFT 0
-#define I40E_PFGEN_STATE_RESERVED_0_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_RESERVED_0_SHIFT)
-#define I40E_PFGEN_STATE_PFFCEN_SHIFT 1
-#define I40E_PFGEN_STATE_PFFCEN_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_PFFCEN_SHIFT)
-#define I40E_PFGEN_STATE_PFLINKEN_SHIFT 2
-#define I40E_PFGEN_STATE_PFLINKEN_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_PFLINKEN_SHIFT)
-#define I40E_PFGEN_STATE_PFSCEN_SHIFT 3
-#define I40E_PFGEN_STATE_PFSCEN_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_PFSCEN_SHIFT)
#define I40E_PRTGEN_CNF 0x000B8120 /* Reset: POR */
#define I40E_PRTGEN_CNF_PORT_DIS_SHIFT 0
#define I40E_PRTGEN_CNF_PORT_DIS_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF_PORT_DIS_SHIFT)
-#define I40E_PRTGEN_CNF_ALLOW_PORT_DIS_SHIFT 1
-#define I40E_PRTGEN_CNF_ALLOW_PORT_DIS_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF_ALLOW_PORT_DIS_SHIFT)
-#define I40E_PRTGEN_CNF_EMP_PORT_DIS_SHIFT 2
-#define I40E_PRTGEN_CNF_EMP_PORT_DIS_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF_EMP_PORT_DIS_SHIFT)
-#define I40E_PRTGEN_CNF2 0x000B8160 /* Reset: POR */
-#define I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_SHIFT 0
-#define I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_SHIFT)
#define I40E_PRTGEN_STATUS 0x000B8100 /* Reset: POR */
-#define I40E_PRTGEN_STATUS_PORT_VALID_SHIFT 0
-#define I40E_PRTGEN_STATUS_PORT_VALID_MASK I40E_MASK(0x1, I40E_PRTGEN_STATUS_PORT_VALID_SHIFT)
-#define I40E_PRTGEN_STATUS_PORT_ACTIVE_SHIFT 1
-#define I40E_PRTGEN_STATUS_PORT_ACTIVE_MASK I40E_MASK(0x1, I40E_PRTGEN_STATUS_PORT_ACTIVE_SHIFT)
#define I40E_VFGEN_RSTAT1(_VF) (0x00074400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFGEN_RSTAT1_MAX_INDEX 127
-#define I40E_VFGEN_RSTAT1_VFR_STATE_SHIFT 0
-#define I40E_VFGEN_RSTAT1_VFR_STATE_MASK I40E_MASK(0x3, I40E_VFGEN_RSTAT1_VFR_STATE_SHIFT)
#define I40E_VPGEN_VFRSTAT(_VF) (0x00091C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_VPGEN_VFRSTAT_MAX_INDEX 127
#define I40E_VPGEN_VFRSTAT_VFRD_SHIFT 0
#define I40E_VPGEN_VFRSTAT_VFRD_MASK I40E_MASK(0x1, I40E_VPGEN_VFRSTAT_VFRD_SHIFT)
#define I40E_VPGEN_VFRTRIG(_VF) (0x00091800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_VPGEN_VFRTRIG_MAX_INDEX 127
#define I40E_VPGEN_VFRTRIG_VFSWR_SHIFT 0
#define I40E_VPGEN_VFRTRIG_VFSWR_MASK I40E_MASK(0x1, I40E_VPGEN_VFRTRIG_VFSWR_SHIFT)
-#define I40E_VSIGEN_RSTAT(_VSI) (0x00090800 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_VSIGEN_RSTAT_MAX_INDEX 383
-#define I40E_VSIGEN_RSTAT_VMRD_SHIFT 0
-#define I40E_VSIGEN_RSTAT_VMRD_MASK I40E_MASK(0x1, I40E_VSIGEN_RSTAT_VMRD_SHIFT)
-#define I40E_VSIGEN_RTRIG(_VSI) (0x00090000 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_VSIGEN_RTRIG_MAX_INDEX 383
-#define I40E_VSIGEN_RTRIG_VMSWR_SHIFT 0
-#define I40E_VSIGEN_RTRIG_VMSWR_MASK I40E_MASK(0x1, I40E_VSIGEN_RTRIG_VMSWR_SHIFT)
#define I40E_GLHMC_FCOEDDPBASE(_i) (0x000C6600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_FCOEDDPBASE_MAX_INDEX 15
#define I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_SHIFT 0
#define I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_SHIFT)
#define I40E_GLHMC_FCOEDDPCNT(_i) (0x000C6700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_FCOEDDPCNT_MAX_INDEX 15
-#define I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_SHIFT 0
-#define I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_MASK I40E_MASK(0xFFFFF, I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_SHIFT)
#define I40E_GLHMC_FCOEDDPOBJSZ 0x000C2010 /* Reset: CORER */
-#define I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_SHIFT 0
-#define I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_SHIFT)
#define I40E_GLHMC_FCOEFBASE(_i) (0x000C6800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_FCOEFBASE_MAX_INDEX 15
#define I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_SHIFT 0
#define I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_SHIFT)
#define I40E_GLHMC_FCOEFCNT(_i) (0x000C6900 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_FCOEFCNT_MAX_INDEX 15
-#define I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_SHIFT 0
-#define I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_MASK I40E_MASK(0x7FFFFF, I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_SHIFT)
#define I40E_GLHMC_FCOEFMAX 0x000C20D0 /* Reset: CORER */
#define I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT 0
#define I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK I40E_MASK(0xFFFF, I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT)
#define I40E_GLHMC_FCOEFOBJSZ 0x000C2018 /* Reset: CORER */
-#define I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_SHIFT 0
-#define I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_SHIFT)
#define I40E_GLHMC_FCOEMAX 0x000C2014 /* Reset: CORER */
-#define I40E_GLHMC_FCOEMAX_PMFCOEMAX_SHIFT 0
-#define I40E_GLHMC_FCOEMAX_PMFCOEMAX_MASK I40E_MASK(0x1FFF, I40E_GLHMC_FCOEMAX_PMFCOEMAX_SHIFT)
-#define I40E_GLHMC_FSIAVBASE(_i) (0x000C5600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_FSIAVBASE_MAX_INDEX 15
-#define I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_SHIFT 0
-#define I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_SHIFT)
-#define I40E_GLHMC_FSIAVCNT(_i) (0x000C5700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_FSIAVCNT_MAX_INDEX 15
-#define I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_SHIFT 0
-#define I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_SHIFT)
-#define I40E_GLHMC_FSIAVCNT_RSVD_SHIFT 29
-#define I40E_GLHMC_FSIAVCNT_RSVD_MASK I40E_MASK(0x7, I40E_GLHMC_FSIAVCNT_RSVD_SHIFT)
-#define I40E_GLHMC_FSIAVMAX 0x000C2068 /* Reset: CORER */
-#define I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_SHIFT 0
-#define I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_MASK I40E_MASK(0x1FFFF, I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_SHIFT)
-#define I40E_GLHMC_FSIAVOBJSZ 0x000C2064 /* Reset: CORER */
-#define I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_SHIFT 0
-#define I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_SHIFT)
-#define I40E_GLHMC_FSIMCBASE(_i) (0x000C6000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_FSIMCBASE_MAX_INDEX 15
-#define I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_SHIFT 0
-#define I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_SHIFT)
-#define I40E_GLHMC_FSIMCCNT(_i) (0x000C6100 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_FSIMCCNT_MAX_INDEX 15
-#define I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_SHIFT 0
-#define I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_SHIFT)
-#define I40E_GLHMC_FSIMCMAX 0x000C2060 /* Reset: CORER */
-#define I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_SHIFT 0
-#define I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_MASK I40E_MASK(0x3FFF, I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_SHIFT)
-#define I40E_GLHMC_FSIMCOBJSZ 0x000C205c /* Reset: CORER */
-#define I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_SHIFT 0
-#define I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_SHIFT)
#define I40E_GLHMC_LANQMAX 0x000C2008 /* Reset: CORER */
-#define I40E_GLHMC_LANQMAX_PMLANQMAX_SHIFT 0
-#define I40E_GLHMC_LANQMAX_PMLANQMAX_MASK I40E_MASK(0x7FF, I40E_GLHMC_LANQMAX_PMLANQMAX_SHIFT)
#define I40E_GLHMC_LANRXBASE(_i) (0x000C6400 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_LANRXBASE_MAX_INDEX 15
#define I40E_GLHMC_LANRXBASE_FPMLANRXBASE_SHIFT 0
#define I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_LANRXBASE_FPMLANRXBASE_SHIFT)
#define I40E_GLHMC_LANRXCNT(_i) (0x000C6500 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_LANRXCNT_MAX_INDEX 15
-#define I40E_GLHMC_LANRXCNT_FPMLANRXCNT_SHIFT 0
-#define I40E_GLHMC_LANRXCNT_FPMLANRXCNT_MASK I40E_MASK(0x7FF, I40E_GLHMC_LANRXCNT_FPMLANRXCNT_SHIFT)
#define I40E_GLHMC_LANRXOBJSZ 0x000C200c /* Reset: CORER */
-#define I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_SHIFT 0
-#define I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_SHIFT)
#define I40E_GLHMC_LANTXBASE(_i) (0x000C6200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_LANTXBASE_MAX_INDEX 15
#define I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT 0
#define I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT)
-#define I40E_GLHMC_LANTXBASE_RSVD_SHIFT 24
-#define I40E_GLHMC_LANTXBASE_RSVD_MASK I40E_MASK(0xFF, I40E_GLHMC_LANTXBASE_RSVD_SHIFT)
#define I40E_GLHMC_LANTXCNT(_i) (0x000C6300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_LANTXCNT_MAX_INDEX 15
-#define I40E_GLHMC_LANTXCNT_FPMLANTXCNT_SHIFT 0
-#define I40E_GLHMC_LANTXCNT_FPMLANTXCNT_MASK I40E_MASK(0x7FF, I40E_GLHMC_LANTXCNT_FPMLANTXCNT_SHIFT)
#define I40E_GLHMC_LANTXOBJSZ 0x000C2004 /* Reset: CORER */
-#define I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_SHIFT 0
-#define I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_SHIFT)
-#define I40E_GLHMC_PFASSIGN(_i) (0x000C0c00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PFASSIGN_MAX_INDEX 15
-#define I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_SHIFT 0
-#define I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_MASK I40E_MASK(0xF, I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_SHIFT)
-#define I40E_GLHMC_SDPART(_i) (0x000C0800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_SDPART_MAX_INDEX 15
-#define I40E_GLHMC_SDPART_PMSDBASE_SHIFT 0
-#define I40E_GLHMC_SDPART_PMSDBASE_MASK I40E_MASK(0xFFF, I40E_GLHMC_SDPART_PMSDBASE_SHIFT)
-#define I40E_GLHMC_SDPART_PMSDSIZE_SHIFT 16
-#define I40E_GLHMC_SDPART_PMSDSIZE_MASK I40E_MASK(0x1FFF, I40E_GLHMC_SDPART_PMSDSIZE_SHIFT)
#define I40E_PFHMC_ERRORDATA 0x000C0500 /* Reset: PFR */
-#define I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_SHIFT 0
-#define I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_MASK I40E_MASK(0x3FFFFFFF, I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_SHIFT)
#define I40E_PFHMC_ERRORINFO 0x000C0400 /* Reset: PFR */
-#define I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT 0
-#define I40E_PFHMC_ERRORINFO_PMF_INDEX_MASK I40E_MASK(0x1F, I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT)
-#define I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT 7
-#define I40E_PFHMC_ERRORINFO_PMF_ISVF_MASK I40E_MASK(0x1, I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT)
-#define I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT 8
-#define I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_MASK I40E_MASK(0xF, I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT)
-#define I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT 16
-#define I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_MASK I40E_MASK(0x1F, I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT)
-#define I40E_PFHMC_ERRORINFO_ERROR_DETECTED_SHIFT 31
-#define I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK I40E_MASK(0x1, I40E_PFHMC_ERRORINFO_ERROR_DETECTED_SHIFT)
#define I40E_PFHMC_PDINV 0x000C0300 /* Reset: PFR */
#define I40E_PFHMC_PDINV_PMSDIDX_SHIFT 0
-#define I40E_PFHMC_PDINV_PMSDIDX_MASK I40E_MASK(0xFFF, I40E_PFHMC_PDINV_PMSDIDX_SHIFT)
#define I40E_PFHMC_PDINV_PMPDIDX_SHIFT 16
-#define I40E_PFHMC_PDINV_PMPDIDX_MASK I40E_MASK(0x1FF, I40E_PFHMC_PDINV_PMPDIDX_SHIFT)
#define I40E_PFHMC_SDCMD 0x000C0000 /* Reset: PFR */
-#define I40E_PFHMC_SDCMD_PMSDIDX_SHIFT 0
-#define I40E_PFHMC_SDCMD_PMSDIDX_MASK I40E_MASK(0xFFF, I40E_PFHMC_SDCMD_PMSDIDX_SHIFT)
#define I40E_PFHMC_SDCMD_PMSDWR_SHIFT 31
-#define I40E_PFHMC_SDCMD_PMSDWR_MASK I40E_MASK(0x1, I40E_PFHMC_SDCMD_PMSDWR_SHIFT)
#define I40E_PFHMC_SDDATAHIGH 0x000C0200 /* Reset: PFR */
-#define I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_SHIFT 0
-#define I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_MASK I40E_MASK(0xFFFFFFFF, I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_SHIFT)
#define I40E_PFHMC_SDDATALOW 0x000C0100 /* Reset: PFR */
#define I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT 0
-#define I40E_PFHMC_SDDATALOW_PMSDVALID_MASK I40E_MASK(0x1, I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT)
#define I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT 1
-#define I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK I40E_MASK(0x1, I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT)
#define I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT 2
-#define I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK I40E_MASK(0x3FF, I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT)
-#define I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT 12
-#define I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK I40E_MASK(0xFFFFF, I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT)
-#define I40E_GL_GP_FUSE(_i) (0x0009400C + ((_i) * 4)) /* _i=0...28 */ /* Reset: POR */
-#define I40E_GL_GP_FUSE_MAX_INDEX 28
-#define I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT 0
-#define I40E_GL_GP_FUSE_GL_GP_FUSE_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT)
-#define I40E_GL_UFUSE 0x00094008 /* Reset: POR */
-#define I40E_GL_UFUSE_FOUR_PORT_ENABLE_SHIFT 1
-#define I40E_GL_UFUSE_FOUR_PORT_ENABLE_MASK I40E_MASK(0x1, I40E_GL_UFUSE_FOUR_PORT_ENABLE_SHIFT)
-#define I40E_GL_UFUSE_NIC_ID_SHIFT 2
-#define I40E_GL_UFUSE_NIC_ID_MASK I40E_MASK(0x1, I40E_GL_UFUSE_NIC_ID_SHIFT)
-#define I40E_GL_UFUSE_ULT_LOCKOUT_SHIFT 10
-#define I40E_GL_UFUSE_ULT_LOCKOUT_MASK I40E_MASK(0x1, I40E_GL_UFUSE_ULT_LOCKOUT_SHIFT)
-#define I40E_GL_UFUSE_CLS_LOCKOUT_SHIFT 11
-#define I40E_GL_UFUSE_CLS_LOCKOUT_MASK I40E_MASK(0x1, I40E_GL_UFUSE_CLS_LOCKOUT_SHIFT)
-#define I40E_EMPINT_GPIO_ENA 0x00088188 /* Reset: POR */
-#define I40E_EMPINT_GPIO_ENA_GPIO0_ENA_SHIFT 0
-#define I40E_EMPINT_GPIO_ENA_GPIO0_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO0_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO1_ENA_SHIFT 1
-#define I40E_EMPINT_GPIO_ENA_GPIO1_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO1_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO2_ENA_SHIFT 2
-#define I40E_EMPINT_GPIO_ENA_GPIO2_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO2_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO3_ENA_SHIFT 3
-#define I40E_EMPINT_GPIO_ENA_GPIO3_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO3_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO4_ENA_SHIFT 4
-#define I40E_EMPINT_GPIO_ENA_GPIO4_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO4_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO5_ENA_SHIFT 5
-#define I40E_EMPINT_GPIO_ENA_GPIO5_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO5_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO6_ENA_SHIFT 6
-#define I40E_EMPINT_GPIO_ENA_GPIO6_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO6_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO7_ENA_SHIFT 7
-#define I40E_EMPINT_GPIO_ENA_GPIO7_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO7_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO8_ENA_SHIFT 8
-#define I40E_EMPINT_GPIO_ENA_GPIO8_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO8_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO9_ENA_SHIFT 9
-#define I40E_EMPINT_GPIO_ENA_GPIO9_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO9_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO10_ENA_SHIFT 10
-#define I40E_EMPINT_GPIO_ENA_GPIO10_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO10_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO11_ENA_SHIFT 11
-#define I40E_EMPINT_GPIO_ENA_GPIO11_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO11_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO12_ENA_SHIFT 12
-#define I40E_EMPINT_GPIO_ENA_GPIO12_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO12_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO13_ENA_SHIFT 13
-#define I40E_EMPINT_GPIO_ENA_GPIO13_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO13_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO14_ENA_SHIFT 14
-#define I40E_EMPINT_GPIO_ENA_GPIO14_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO14_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO15_ENA_SHIFT 15
-#define I40E_EMPINT_GPIO_ENA_GPIO15_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO15_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO16_ENA_SHIFT 16
-#define I40E_EMPINT_GPIO_ENA_GPIO16_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO16_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO17_ENA_SHIFT 17
-#define I40E_EMPINT_GPIO_ENA_GPIO17_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO17_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO18_ENA_SHIFT 18
-#define I40E_EMPINT_GPIO_ENA_GPIO18_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO18_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO19_ENA_SHIFT 19
-#define I40E_EMPINT_GPIO_ENA_GPIO19_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO19_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO20_ENA_SHIFT 20
-#define I40E_EMPINT_GPIO_ENA_GPIO20_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO20_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO21_ENA_SHIFT 21
-#define I40E_EMPINT_GPIO_ENA_GPIO21_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO21_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO22_ENA_SHIFT 22
-#define I40E_EMPINT_GPIO_ENA_GPIO22_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO22_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO23_ENA_SHIFT 23
-#define I40E_EMPINT_GPIO_ENA_GPIO23_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO23_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO24_ENA_SHIFT 24
-#define I40E_EMPINT_GPIO_ENA_GPIO24_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO24_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO25_ENA_SHIFT 25
-#define I40E_EMPINT_GPIO_ENA_GPIO25_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO25_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO26_ENA_SHIFT 26
-#define I40E_EMPINT_GPIO_ENA_GPIO26_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO26_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO27_ENA_SHIFT 27
-#define I40E_EMPINT_GPIO_ENA_GPIO27_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO27_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO28_ENA_SHIFT 28
-#define I40E_EMPINT_GPIO_ENA_GPIO28_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO28_ENA_SHIFT)
-#define I40E_EMPINT_GPIO_ENA_GPIO29_ENA_SHIFT 29
-#define I40E_EMPINT_GPIO_ENA_GPIO29_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO29_ENA_SHIFT)
#define I40E_PFGEN_PORTMDIO_NUM 0x0003F100 /* Reset: CORER */
-#define I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_SHIFT 0
-#define I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_MASK I40E_MASK(0x3, I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_SHIFT)
#define I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_SHIFT 4
#define I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK I40E_MASK(0x1, I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_SHIFT)
#define I40E_PFINT_AEQCTL 0x00038700 /* Reset: CORER */
#define I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_PFINT_AEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT)
#define I40E_PFINT_AEQCTL_ITR_INDX_SHIFT 11
-#define I40E_PFINT_AEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_AEQCTL_ITR_INDX_SHIFT)
-#define I40E_PFINT_AEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_PFINT_AEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_PFINT_AEQCTL_MSIX0_INDX_SHIFT)
#define I40E_PFINT_AEQCTL_CAUSE_ENA_SHIFT 30
#define I40E_PFINT_AEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_PFINT_AEQCTL_CAUSE_ENA_SHIFT)
-#define I40E_PFINT_AEQCTL_INTEVENT_SHIFT 31
-#define I40E_PFINT_AEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_AEQCTL_INTEVENT_SHIFT)
#define I40E_PFINT_CEQCTL(_INTPF) (0x00036800 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: CORER */
-#define I40E_PFINT_CEQCTL_MAX_INDEX 511
#define I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_PFINT_CEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_ITR_INDX_SHIFT 11
-#define I40E_PFINT_CEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_CEQCTL_ITR_INDX_SHIFT)
-#define I40E_PFINT_CEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_PFINT_CEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_PFINT_CEQCTL_MSIX0_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT 16
-#define I40E_PFINT_CEQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT)
-#define I40E_PFINT_CEQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_PFINT_CEQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_PFINT_CEQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT 30
#define I40E_PFINT_CEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT)
-#define I40E_PFINT_CEQCTL_INTEVENT_SHIFT 31
-#define I40E_PFINT_CEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_INTEVENT_SHIFT)
#define I40E_GLINT_CTL 0x0003F800 /* Reset: CORER */
-#define I40E_GLINT_CTL_DIS_AUTOMASK_PF0_SHIFT 0
-#define I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK I40E_MASK(0x1, I40E_GLINT_CTL_DIS_AUTOMASK_PF0_SHIFT)
#define I40E_GLINT_CTL_DIS_AUTOMASK_VF0_SHIFT 1
#define I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK I40E_MASK(0x1, I40E_GLINT_CTL_DIS_AUTOMASK_VF0_SHIFT)
-#define I40E_GLINT_CTL_DIS_AUTOMASK_N_SHIFT 2
-#define I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK I40E_MASK(0x1, I40E_GLINT_CTL_DIS_AUTOMASK_N_SHIFT)
#define I40E_PFINT_DYN_CTL0 0x00038480 /* Reset: PFR */
#define I40E_PFINT_DYN_CTL0_INTENA_SHIFT 0
#define I40E_PFINT_DYN_CTL0_INTENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_INTENA_SHIFT)
@@ -872,8 +173,6 @@
#define I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
#define I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT 3
#define I40E_PFINT_DYN_CTL0_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT)
-#define I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT 5
-#define I40E_PFINT_DYN_CTL0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT)
#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT 24
#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_SHIFT 25
@@ -881,7 +180,6 @@
#define I40E_PFINT_DYN_CTL0_INTENA_MSK_SHIFT 31
#define I40E_PFINT_DYN_CTL0_INTENA_MSK_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_INTENA_MSK_SHIFT)
#define I40E_PFINT_DYN_CTLN(_INTPF) (0x00034800 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: PFR */
-#define I40E_PFINT_DYN_CTLN_MAX_INDEX 511
#define I40E_PFINT_DYN_CTLN_INTENA_SHIFT 0
#define I40E_PFINT_DYN_CTLN_INTENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_INTENA_SHIFT)
#define I40E_PFINT_DYN_CTLN_CLEARPBA_SHIFT 1
@@ -891,93 +189,13 @@
#define I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT 3
#define I40E_PFINT_DYN_CTLN_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT)
#define I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT 5
-#define I40E_PFINT_DYN_CTLN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT)
#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT 24
#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
-#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT 25
-#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
-#define I40E_PFINT_DYN_CTLN_INTENA_MSK_SHIFT 31
-#define I40E_PFINT_DYN_CTLN_INTENA_MSK_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_INTENA_MSK_SHIFT)
-#define I40E_PFINT_GPIO_ENA 0x00088080 /* Reset: CORER */
-#define I40E_PFINT_GPIO_ENA_GPIO0_ENA_SHIFT 0
-#define I40E_PFINT_GPIO_ENA_GPIO0_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO0_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO1_ENA_SHIFT 1
-#define I40E_PFINT_GPIO_ENA_GPIO1_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO1_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO2_ENA_SHIFT 2
-#define I40E_PFINT_GPIO_ENA_GPIO2_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO2_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO3_ENA_SHIFT 3
-#define I40E_PFINT_GPIO_ENA_GPIO3_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO3_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO4_ENA_SHIFT 4
-#define I40E_PFINT_GPIO_ENA_GPIO4_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO4_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO5_ENA_SHIFT 5
-#define I40E_PFINT_GPIO_ENA_GPIO5_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO5_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO6_ENA_SHIFT 6
-#define I40E_PFINT_GPIO_ENA_GPIO6_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO6_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO7_ENA_SHIFT 7
-#define I40E_PFINT_GPIO_ENA_GPIO7_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO7_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO8_ENA_SHIFT 8
-#define I40E_PFINT_GPIO_ENA_GPIO8_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO8_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO9_ENA_SHIFT 9
-#define I40E_PFINT_GPIO_ENA_GPIO9_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO9_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO10_ENA_SHIFT 10
-#define I40E_PFINT_GPIO_ENA_GPIO10_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO10_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO11_ENA_SHIFT 11
-#define I40E_PFINT_GPIO_ENA_GPIO11_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO11_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO12_ENA_SHIFT 12
-#define I40E_PFINT_GPIO_ENA_GPIO12_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO12_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO13_ENA_SHIFT 13
-#define I40E_PFINT_GPIO_ENA_GPIO13_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO13_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO14_ENA_SHIFT 14
-#define I40E_PFINT_GPIO_ENA_GPIO14_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO14_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO15_ENA_SHIFT 15
-#define I40E_PFINT_GPIO_ENA_GPIO15_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO15_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO16_ENA_SHIFT 16
-#define I40E_PFINT_GPIO_ENA_GPIO16_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO16_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO17_ENA_SHIFT 17
-#define I40E_PFINT_GPIO_ENA_GPIO17_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO17_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO18_ENA_SHIFT 18
-#define I40E_PFINT_GPIO_ENA_GPIO18_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO18_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO19_ENA_SHIFT 19
-#define I40E_PFINT_GPIO_ENA_GPIO19_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO19_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO20_ENA_SHIFT 20
-#define I40E_PFINT_GPIO_ENA_GPIO20_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO20_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO21_ENA_SHIFT 21
-#define I40E_PFINT_GPIO_ENA_GPIO21_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO21_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO22_ENA_SHIFT 22
-#define I40E_PFINT_GPIO_ENA_GPIO22_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO22_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO23_ENA_SHIFT 23
-#define I40E_PFINT_GPIO_ENA_GPIO23_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO23_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO24_ENA_SHIFT 24
-#define I40E_PFINT_GPIO_ENA_GPIO24_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO24_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO25_ENA_SHIFT 25
-#define I40E_PFINT_GPIO_ENA_GPIO25_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO25_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO26_ENA_SHIFT 26
-#define I40E_PFINT_GPIO_ENA_GPIO26_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO26_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO27_ENA_SHIFT 27
-#define I40E_PFINT_GPIO_ENA_GPIO27_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO27_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO28_ENA_SHIFT 28
-#define I40E_PFINT_GPIO_ENA_GPIO28_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO28_ENA_SHIFT)
-#define I40E_PFINT_GPIO_ENA_GPIO29_ENA_SHIFT 29
-#define I40E_PFINT_GPIO_ENA_GPIO29_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO29_ENA_SHIFT)
#define I40E_PFINT_ICR0 0x00038780 /* Reset: CORER */
#define I40E_PFINT_ICR0_INTEVENT_SHIFT 0
#define I40E_PFINT_ICR0_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_INTEVENT_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_0_SHIFT 1
#define I40E_PFINT_ICR0_QUEUE_0_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_0_SHIFT)
-#define I40E_PFINT_ICR0_QUEUE_1_SHIFT 2
-#define I40E_PFINT_ICR0_QUEUE_1_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_1_SHIFT)
-#define I40E_PFINT_ICR0_QUEUE_2_SHIFT 3
-#define I40E_PFINT_ICR0_QUEUE_2_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_2_SHIFT)
-#define I40E_PFINT_ICR0_QUEUE_3_SHIFT 4
-#define I40E_PFINT_ICR0_QUEUE_3_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_3_SHIFT)
-#define I40E_PFINT_ICR0_QUEUE_4_SHIFT 5
-#define I40E_PFINT_ICR0_QUEUE_4_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_4_SHIFT)
-#define I40E_PFINT_ICR0_QUEUE_5_SHIFT 6
-#define I40E_PFINT_ICR0_QUEUE_5_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_5_SHIFT)
-#define I40E_PFINT_ICR0_QUEUE_6_SHIFT 7
-#define I40E_PFINT_ICR0_QUEUE_6_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_6_SHIFT)
-#define I40E_PFINT_ICR0_QUEUE_7_SHIFT 8
-#define I40E_PFINT_ICR0_QUEUE_7_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_7_SHIFT)
#define I40E_PFINT_ICR0_ECC_ERR_SHIFT 16
#define I40E_PFINT_ICR0_ECC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ECC_ERR_SHIFT)
#define I40E_PFINT_ICR0_MAL_DETECT_SHIFT 19
@@ -986,14 +204,8 @@
#define I40E_PFINT_ICR0_GRST_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_GRST_SHIFT)
#define I40E_PFINT_ICR0_PCI_EXCEPTION_SHIFT 21
#define I40E_PFINT_ICR0_PCI_EXCEPTION_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_PCI_EXCEPTION_SHIFT)
-#define I40E_PFINT_ICR0_GPIO_SHIFT 22
-#define I40E_PFINT_ICR0_GPIO_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_GPIO_SHIFT)
#define I40E_PFINT_ICR0_TIMESYNC_SHIFT 23
#define I40E_PFINT_ICR0_TIMESYNC_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_TIMESYNC_SHIFT)
-#define I40E_PFINT_ICR0_STORM_DETECT_SHIFT 24
-#define I40E_PFINT_ICR0_STORM_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_STORM_DETECT_SHIFT)
-#define I40E_PFINT_ICR0_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
#define I40E_PFINT_ICR0_HMC_ERR_SHIFT 26
#define I40E_PFINT_ICR0_HMC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_HMC_ERR_SHIFT)
#define I40E_PFINT_ICR0_PE_CRITERR_SHIFT 28
@@ -1017,10 +229,6 @@
#define I40E_PFINT_ICR0_ENA_GPIO_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_GPIO_SHIFT)
#define I40E_PFINT_ICR0_ENA_TIMESYNC_SHIFT 23
#define I40E_PFINT_ICR0_ENA_TIMESYNC_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_TIMESYNC_SHIFT)
-#define I40E_PFINT_ICR0_ENA_STORM_DETECT_SHIFT 24
-#define I40E_PFINT_ICR0_ENA_STORM_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_STORM_DETECT_SHIFT)
-#define I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
#define I40E_PFINT_ICR0_ENA_HMC_ERR_SHIFT 26
#define I40E_PFINT_ICR0_ENA_HMC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_HMC_ERR_SHIFT)
#define I40E_PFINT_ICR0_ENA_PE_CRITERR_SHIFT 28
@@ -1029,43 +237,17 @@
#define I40E_PFINT_ICR0_ENA_VFLR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_VFLR_SHIFT)
#define I40E_PFINT_ICR0_ENA_ADMINQ_SHIFT 30
#define I40E_PFINT_ICR0_ENA_ADMINQ_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_ADMINQ_SHIFT)
-#define I40E_PFINT_ICR0_ENA_RSVD_SHIFT 31
-#define I40E_PFINT_ICR0_ENA_RSVD_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_RSVD_SHIFT)
#define I40E_PFINT_ITR0(_i) (0x00038000 + ((_i) * 128)) /* _i=0...2 */ /* Reset: PFR */
-#define I40E_PFINT_ITR0_MAX_INDEX 2
-#define I40E_PFINT_ITR0_INTERVAL_SHIFT 0
-#define I40E_PFINT_ITR0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_ITR0_INTERVAL_SHIFT)
#define I40E_PFINT_ITRN(_i, _INTPF) (0x00030000 + ((_i) * 2048 + (_INTPF) * 4)) /* _i=0...2, _INTPF=0...511 */ /* Reset: PFR */
-#define I40E_PFINT_ITRN_MAX_INDEX 2
-#define I40E_PFINT_ITRN_INTERVAL_SHIFT 0
-#define I40E_PFINT_ITRN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_ITRN_INTERVAL_SHIFT)
#define I40E_PFINT_LNKLST0 0x00038500 /* Reset: PFR */
#define I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT 0
-#define I40E_PFINT_LNKLST0_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT)
-#define I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT 11
-#define I40E_PFINT_LNKLST0_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
#define I40E_PFINT_LNKLSTN(_INTPF) (0x00035000 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: PFR */
-#define I40E_PFINT_LNKLSTN_MAX_INDEX 511
#define I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT 0
#define I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
#define I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT 11
-#define I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
-#define I40E_PFINT_RATE0 0x00038580 /* Reset: PFR */
-#define I40E_PFINT_RATE0_INTERVAL_SHIFT 0
-#define I40E_PFINT_RATE0_INTERVAL_MASK I40E_MASK(0x3F, I40E_PFINT_RATE0_INTERVAL_SHIFT)
-#define I40E_PFINT_RATE0_INTRL_ENA_SHIFT 6
-#define I40E_PFINT_RATE0_INTRL_ENA_MASK I40E_MASK(0x1, I40E_PFINT_RATE0_INTRL_ENA_SHIFT)
#define I40E_PFINT_RATEN(_INTPF) (0x00035800 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: PFR */
-#define I40E_PFINT_RATEN_MAX_INDEX 511
-#define I40E_PFINT_RATEN_INTERVAL_SHIFT 0
-#define I40E_PFINT_RATEN_INTERVAL_MASK I40E_MASK(0x3F, I40E_PFINT_RATEN_INTERVAL_SHIFT)
-#define I40E_PFINT_RATEN_INTRL_ENA_SHIFT 6
-#define I40E_PFINT_RATEN_INTRL_ENA_MASK I40E_MASK(0x1, I40E_PFINT_RATEN_INTRL_ENA_SHIFT)
#define I40E_PFINT_STAT_CTL0 0x00038400 /* Reset: CORER */
-#define I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT 2
-#define I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
#define I40E_QINT_RQCTL(_Q) (0x0003A000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
-#define I40E_QINT_RQCTL_MAX_INDEX 1535
#define I40E_QINT_RQCTL_MSIX_INDX_SHIFT 0
#define I40E_QINT_RQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_QINT_RQCTL_MSIX_INDX_SHIFT)
#define I40E_QINT_RQCTL_ITR_INDX_SHIFT 11
@@ -1075,13 +257,11 @@
#define I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT 16
#define I40E_QINT_RQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT)
#define I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_QINT_RQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_QINT_RQCTL_CAUSE_ENA_SHIFT 30
#define I40E_QINT_RQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_QINT_RQCTL_CAUSE_ENA_SHIFT)
#define I40E_QINT_RQCTL_INTEVENT_SHIFT 31
#define I40E_QINT_RQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_QINT_RQCTL_INTEVENT_SHIFT)
#define I40E_QINT_TQCTL(_Q) (0x0003C000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
-#define I40E_QINT_TQCTL_MAX_INDEX 1535
#define I40E_QINT_TQCTL_MSIX_INDX_SHIFT 0
#define I40E_QINT_TQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_QINT_TQCTL_MSIX_INDX_SHIFT)
#define I40E_QINT_TQCTL_ITR_INDX_SHIFT 11
@@ -1091,160 +271,45 @@
#define I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT 16
#define I40E_QINT_TQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT)
#define I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_QINT_TQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_QINT_TQCTL_CAUSE_ENA_SHIFT 30
#define I40E_QINT_TQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_QINT_TQCTL_CAUSE_ENA_SHIFT)
#define I40E_QINT_TQCTL_INTEVENT_SHIFT 31
#define I40E_QINT_TQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_QINT_TQCTL_INTEVENT_SHIFT)
#define I40E_VFINT_DYN_CTL0(_VF) (0x0002A400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFINT_DYN_CTL0_MAX_INDEX 127
-#define I40E_VFINT_DYN_CTL0_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTL0_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_INTENA_SHIFT)
-#define I40E_VFINT_DYN_CTL0_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTL0_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_CLEARPBA_SHIFT)
-#define I40E_VFINT_DYN_CTL0_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTL0_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
-#define I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTL0_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT)
-#define I40E_VFINT_DYN_CTL0_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTL0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTL0_INTERVAL_SHIFT)
-#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
-#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL0_SW_ITR_INDX_SHIFT)
-#define I40E_VFINT_DYN_CTL0_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTL0_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_INTENA_MSK_SHIFT)
#define I40E_VFINT_DYN_CTLN(_INTVF) (0x00024800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */
-#define I40E_VFINT_DYN_CTLN_MAX_INDEX 511
-#define I40E_VFINT_DYN_CTLN_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTLN_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_INTENA_SHIFT)
#define I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT 1
#define I40E_VFINT_DYN_CTLN_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT)
-#define I40E_VFINT_DYN_CTLN_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_SWINT_TRIG_SHIFT)
-#define I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTLN_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT)
-#define I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTLN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT)
-#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
-#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
-#define I40E_VFINT_DYN_CTLN_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTLN_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_INTENA_MSK_SHIFT)
-#define I40E_VFINT_ICR0(_VF) (0x0002BC00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_VFINT_ICR0_MAX_INDEX 127
-#define I40E_VFINT_ICR0_INTEVENT_SHIFT 0
-#define I40E_VFINT_ICR0_INTEVENT_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_INTEVENT_SHIFT)
-#define I40E_VFINT_ICR0_QUEUE_0_SHIFT 1
-#define I40E_VFINT_ICR0_QUEUE_0_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_0_SHIFT)
-#define I40E_VFINT_ICR0_QUEUE_1_SHIFT 2
-#define I40E_VFINT_ICR0_QUEUE_1_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_1_SHIFT)
-#define I40E_VFINT_ICR0_QUEUE_2_SHIFT 3
-#define I40E_VFINT_ICR0_QUEUE_2_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_2_SHIFT)
-#define I40E_VFINT_ICR0_QUEUE_3_SHIFT 4
-#define I40E_VFINT_ICR0_QUEUE_3_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_3_SHIFT)
-#define I40E_VFINT_ICR0_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR0_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
-#define I40E_VFINT_ICR0_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR0_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ADMINQ_SHIFT)
-#define I40E_VFINT_ICR0_SWINT_SHIFT 31
-#define I40E_VFINT_ICR0_SWINT_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_SWINT_SHIFT)
-#define I40E_VFINT_ICR0_ENA(_VF) (0x0002C000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_VFINT_ICR0_ENA_MAX_INDEX 127
-#define I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
-#define I40E_VFINT_ICR0_ENA_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR0_ENA_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA_ADMINQ_SHIFT)
-#define I40E_VFINT_ICR0_ENA_RSVD_SHIFT 31
-#define I40E_VFINT_ICR0_ENA_RSVD_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA_RSVD_SHIFT)
-#define I40E_VFINT_ITR0(_i, _VF) (0x00028000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...2, _VF=0...127 */ /* Reset: VFR */
-#define I40E_VFINT_ITR0_MAX_INDEX 2
-#define I40E_VFINT_ITR0_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITR0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITR0_INTERVAL_SHIFT)
-#define I40E_VFINT_ITRN(_i, _INTVF) (0x00020000 + ((_i) * 2048 + (_INTVF) * 4)) /* _i=0...2, _INTVF=0...511 */ /* Reset: VFR */
-#define I40E_VFINT_ITRN_MAX_INDEX 2
-#define I40E_VFINT_ITRN_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITRN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITRN_INTERVAL_SHIFT)
-#define I40E_VFINT_STAT_CTL0(_VF) (0x0002A000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_VFINT_STAT_CTL0_MAX_INDEX 127
-#define I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT 2
-#define I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
#define I40E_VPINT_AEQCTL(_VF) (0x0002B800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_VPINT_AEQCTL_MAX_INDEX 127
#define I40E_VPINT_AEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_VPINT_AEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_VPINT_AEQCTL_MSIX_INDX_SHIFT)
#define I40E_VPINT_AEQCTL_ITR_INDX_SHIFT 11
-#define I40E_VPINT_AEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_VPINT_AEQCTL_ITR_INDX_SHIFT)
-#define I40E_VPINT_AEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_VPINT_AEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_VPINT_AEQCTL_MSIX0_INDX_SHIFT)
#define I40E_VPINT_AEQCTL_CAUSE_ENA_SHIFT 30
#define I40E_VPINT_AEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_VPINT_AEQCTL_CAUSE_ENA_SHIFT)
-#define I40E_VPINT_AEQCTL_INTEVENT_SHIFT 31
-#define I40E_VPINT_AEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_VPINT_AEQCTL_INTEVENT_SHIFT)
#define I40E_VPINT_CEQCTL(_INTVF) (0x00026800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: CORER */
-#define I40E_VPINT_CEQCTL_MAX_INDEX 511
#define I40E_VPINT_CEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_VPINT_CEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_VPINT_CEQCTL_MSIX_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_ITR_INDX_SHIFT 11
-#define I40E_VPINT_CEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_VPINT_CEQCTL_ITR_INDX_SHIFT)
-#define I40E_VPINT_CEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_VPINT_CEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_VPINT_CEQCTL_MSIX0_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_NEXTQ_INDX_SHIFT 16
#define I40E_VPINT_CEQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_VPINT_CEQCTL_NEXTQ_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_NEXTQ_TYPE_SHIFT 27
#define I40E_VPINT_CEQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_VPINT_CEQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_VPINT_CEQCTL_CAUSE_ENA_SHIFT 30
#define I40E_VPINT_CEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_VPINT_CEQCTL_CAUSE_ENA_SHIFT)
-#define I40E_VPINT_CEQCTL_INTEVENT_SHIFT 31
-#define I40E_VPINT_CEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_VPINT_CEQCTL_INTEVENT_SHIFT)
#define I40E_VPINT_LNKLST0(_VF) (0x0002A800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VPINT_LNKLST0_MAX_INDEX 127
#define I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT 0
#define I40E_VPINT_LNKLST0_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT)
-#define I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT 11
-#define I40E_VPINT_LNKLST0_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
#define I40E_VPINT_LNKLSTN(_INTVF) (0x00025000 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */
-#define I40E_VPINT_LNKLSTN_MAX_INDEX 511
#define I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT 0
#define I40E_VPINT_LNKLSTN_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
#define I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT 11
#define I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
-#define I40E_VPINT_RATE0(_VF) (0x0002AC00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VPINT_RATE0_MAX_INDEX 127
-#define I40E_VPINT_RATE0_INTERVAL_SHIFT 0
-#define I40E_VPINT_RATE0_INTERVAL_MASK I40E_MASK(0x3F, I40E_VPINT_RATE0_INTERVAL_SHIFT)
-#define I40E_VPINT_RATE0_INTRL_ENA_SHIFT 6
-#define I40E_VPINT_RATE0_INTRL_ENA_MASK I40E_MASK(0x1, I40E_VPINT_RATE0_INTRL_ENA_SHIFT)
-#define I40E_VPINT_RATEN(_INTVF) (0x00025800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */
-#define I40E_VPINT_RATEN_MAX_INDEX 511
-#define I40E_VPINT_RATEN_INTERVAL_SHIFT 0
-#define I40E_VPINT_RATEN_INTERVAL_MASK I40E_MASK(0x3F, I40E_VPINT_RATEN_INTERVAL_SHIFT)
-#define I40E_VPINT_RATEN_INTRL_ENA_SHIFT 6
-#define I40E_VPINT_RATEN_INTRL_ENA_MASK I40E_MASK(0x1, I40E_VPINT_RATEN_INTRL_ENA_SHIFT)
-#define I40E_GL_RDPU_CNTRL 0x00051060 /* Reset: CORER */
-#define I40E_GL_RDPU_CNTRL_RX_PAD_EN_SHIFT 0
-#define I40E_GL_RDPU_CNTRL_RX_PAD_EN_MASK I40E_MASK(0x1, I40E_GL_RDPU_CNTRL_RX_PAD_EN_SHIFT)
-#define I40E_GL_RDPU_CNTRL_ECO_SHIFT 1
-#define I40E_GL_RDPU_CNTRL_ECO_MASK I40E_MASK(0x7FFFFFFF, I40E_GL_RDPU_CNTRL_ECO_SHIFT)
#define I40E_GLLAN_RCTL_0 0x0012A500 /* Reset: CORER */
#define I40E_GLLAN_RCTL_0_PXE_MODE_SHIFT 0
#define I40E_GLLAN_RCTL_0_PXE_MODE_MASK I40E_MASK(0x1, I40E_GLLAN_RCTL_0_PXE_MODE_SHIFT)
#define I40E_GLLAN_TSOMSK_F 0x000442D8 /* Reset: CORER */
-#define I40E_GLLAN_TSOMSK_F_TCPMSKF_SHIFT 0
-#define I40E_GLLAN_TSOMSK_F_TCPMSKF_MASK I40E_MASK(0xFFF, I40E_GLLAN_TSOMSK_F_TCPMSKF_SHIFT)
#define I40E_GLLAN_TSOMSK_L 0x000442E0 /* Reset: CORER */
-#define I40E_GLLAN_TSOMSK_L_TCPMSKL_SHIFT 0
-#define I40E_GLLAN_TSOMSK_L_TCPMSKL_MASK I40E_MASK(0xFFF, I40E_GLLAN_TSOMSK_L_TCPMSKL_SHIFT)
#define I40E_GLLAN_TSOMSK_M 0x000442DC /* Reset: CORER */
-#define I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT 0
-#define I40E_GLLAN_TSOMSK_M_TCPMSKM_MASK I40E_MASK(0xFFF, I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT)
#define I40E_GLLAN_TXPRE_QDIS(_i) (0x000e6500 + ((_i) * 4)) /* _i=0...11 */ /* Reset: CORER */
-#define I40E_GLLAN_TXPRE_QDIS_MAX_INDEX 11
#define I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT 0
#define I40E_GLLAN_TXPRE_QDIS_QINDX_MASK I40E_MASK(0x7FF, I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT)
-#define I40E_GLLAN_TXPRE_QDIS_QDIS_STAT_SHIFT 16
-#define I40E_GLLAN_TXPRE_QDIS_QDIS_STAT_MASK I40E_MASK(0x1, I40E_GLLAN_TXPRE_QDIS_QDIS_STAT_SHIFT)
#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT 30
#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK I40E_MASK(0x1, I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT)
#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT 31
@@ -1257,19 +322,12 @@
#define I40E_PFLAN_QALLOC_VALID_SHIFT 31
#define I40E_PFLAN_QALLOC_VALID_MASK I40E_MASK(0x1u, I40E_PFLAN_QALLOC_VALID_SHIFT)
#define I40E_QRX_ENA(_Q) (0x00120000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: PFR */
-#define I40E_QRX_ENA_MAX_INDEX 1535
#define I40E_QRX_ENA_QENA_REQ_SHIFT 0
#define I40E_QRX_ENA_QENA_REQ_MASK I40E_MASK(0x1, I40E_QRX_ENA_QENA_REQ_SHIFT)
-#define I40E_QRX_ENA_FAST_QDIS_SHIFT 1
-#define I40E_QRX_ENA_FAST_QDIS_MASK I40E_MASK(0x1, I40E_QRX_ENA_FAST_QDIS_SHIFT)
#define I40E_QRX_ENA_QENA_STAT_SHIFT 2
#define I40E_QRX_ENA_QENA_STAT_MASK I40E_MASK(0x1, I40E_QRX_ENA_QENA_STAT_SHIFT)
#define I40E_QRX_TAIL(_Q) (0x00128000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
-#define I40E_QRX_TAIL_MAX_INDEX 1535
-#define I40E_QRX_TAIL_TAIL_SHIFT 0
-#define I40E_QRX_TAIL_TAIL_MASK I40E_MASK(0x1FFF, I40E_QRX_TAIL_TAIL_SHIFT)
#define I40E_QTX_CTL(_Q) (0x00104000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
-#define I40E_QTX_CTL_MAX_INDEX 1535
#define I40E_QTX_CTL_PFVF_Q_SHIFT 0
#define I40E_QTX_CTL_PFVF_Q_MASK I40E_MASK(0x3, I40E_QTX_CTL_PFVF_Q_SHIFT)
#define I40E_QTX_CTL_PF_INDX_SHIFT 2
@@ -1277,43 +335,22 @@
#define I40E_QTX_CTL_VFVM_INDX_SHIFT 7
#define I40E_QTX_CTL_VFVM_INDX_MASK I40E_MASK(0x1FF, I40E_QTX_CTL_VFVM_INDX_SHIFT)
#define I40E_QTX_ENA(_Q) (0x00100000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: PFR */
-#define I40E_QTX_ENA_MAX_INDEX 1535
#define I40E_QTX_ENA_QENA_REQ_SHIFT 0
#define I40E_QTX_ENA_QENA_REQ_MASK I40E_MASK(0x1, I40E_QTX_ENA_QENA_REQ_SHIFT)
-#define I40E_QTX_ENA_FAST_QDIS_SHIFT 1
-#define I40E_QTX_ENA_FAST_QDIS_MASK I40E_MASK(0x1, I40E_QTX_ENA_FAST_QDIS_SHIFT)
#define I40E_QTX_ENA_QENA_STAT_SHIFT 2
#define I40E_QTX_ENA_QENA_STAT_MASK I40E_MASK(0x1, I40E_QTX_ENA_QENA_STAT_SHIFT)
#define I40E_QTX_HEAD(_Q) (0x000E4000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
-#define I40E_QTX_HEAD_MAX_INDEX 1535
-#define I40E_QTX_HEAD_HEAD_SHIFT 0
-#define I40E_QTX_HEAD_HEAD_MASK I40E_MASK(0x1FFF, I40E_QTX_HEAD_HEAD_SHIFT)
-#define I40E_QTX_HEAD_RS_PENDING_SHIFT 16
-#define I40E_QTX_HEAD_RS_PENDING_MASK I40E_MASK(0x1, I40E_QTX_HEAD_RS_PENDING_SHIFT)
#define I40E_QTX_TAIL(_Q) (0x00108000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: PFR */
-#define I40E_QTX_TAIL_MAX_INDEX 1535
-#define I40E_QTX_TAIL_TAIL_SHIFT 0
-#define I40E_QTX_TAIL_TAIL_MASK I40E_MASK(0x1FFF, I40E_QTX_TAIL_TAIL_SHIFT)
#define I40E_VPLAN_MAPENA(_VF) (0x00074000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VPLAN_MAPENA_MAX_INDEX 127
#define I40E_VPLAN_MAPENA_TXRX_ENA_SHIFT 0
#define I40E_VPLAN_MAPENA_TXRX_ENA_MASK I40E_MASK(0x1, I40E_VPLAN_MAPENA_TXRX_ENA_SHIFT)
#define I40E_VPLAN_QTABLE(_i, _VF) (0x00070000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: VFR */
-#define I40E_VPLAN_QTABLE_MAX_INDEX 15
#define I40E_VPLAN_QTABLE_QINDEX_SHIFT 0
#define I40E_VPLAN_QTABLE_QINDEX_MASK I40E_MASK(0x7FF, I40E_VPLAN_QTABLE_QINDEX_SHIFT)
#define I40E_VSILAN_QBASE(_VSI) (0x0020C800 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: PFR */
-#define I40E_VSILAN_QBASE_MAX_INDEX 383
-#define I40E_VSILAN_QBASE_VSIBASE_SHIFT 0
-#define I40E_VSILAN_QBASE_VSIBASE_MASK I40E_MASK(0x7FF, I40E_VSILAN_QBASE_VSIBASE_SHIFT)
#define I40E_VSILAN_QBASE_VSIQTABLE_ENA_SHIFT 11
#define I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK I40E_MASK(0x1, I40E_VSILAN_QBASE_VSIQTABLE_ENA_SHIFT)
#define I40E_VSILAN_QTABLE(_i, _VSI) (0x00200000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...7, _VSI=0...383 */ /* Reset: PFR */
-#define I40E_VSILAN_QTABLE_MAX_INDEX 7
-#define I40E_VSILAN_QTABLE_QINDEX_0_SHIFT 0
-#define I40E_VSILAN_QTABLE_QINDEX_0_MASK I40E_MASK(0x7FF, I40E_VSILAN_QTABLE_QINDEX_0_SHIFT)
-#define I40E_VSILAN_QTABLE_QINDEX_1_SHIFT 16
-#define I40E_VSILAN_QTABLE_QINDEX_1_MASK I40E_MASK(0x7FF, I40E_VSILAN_QTABLE_QINDEX_1_SHIFT)
#define I40E_PRTGL_SAH 0x001E2140 /* Reset: GLOBR */
#define I40E_PRTGL_SAH_FC_SAH_SHIFT 0
#define I40E_PRTGL_SAH_FC_SAH_MASK I40E_MASK(0xFFFF, I40E_PRTGL_SAH_FC_SAH_SHIFT)
@@ -1322,789 +359,47 @@
#define I40E_PRTGL_SAL 0x001E2120 /* Reset: GLOBR */
#define I40E_PRTGL_SAL_FC_SAL_SHIFT 0
#define I40E_PRTGL_SAL_FC_SAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTGL_SAL_FC_SAL_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP 0x001E30E0 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP 0x001E3260 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP 0x001E32E0 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL 0x001E3360 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1 0x001E3110 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2 0x001E3120 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE 0x001E30C0 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_MASK I40E_MASK(0x1FF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1 0x001E3140 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2 0x001E3150 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE 0x001E30D0 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_MASK I40E_MASK(0x1FF, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(_i) (0x001E3370 + ((_i) * 16)) /* _i=0...8 */ /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX 8
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(_i) (0x001E3400 + ((_i) * 16)) /* _i=0...8 */ /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MAX_INDEX 8
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1 0x001E34B0 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2 0x001E34C0 /* Reset: GLOBR */
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A 0x0008C480 /* Reset: GLOBR */
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_SHIFT 0
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_SHIFT 2
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_SHIFT 4
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_SHIFT 6
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_SHIFT 8
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_SHIFT 10
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_SHIFT 12
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_SHIFT 14
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B 0x0008C484 /* Reset: GLOBR */
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_SHIFT 0
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_SHIFT 2
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_SHIFT 4
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_SHIFT 6
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_SHIFT 8
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_SHIFT 10
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_SHIFT 12
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT 14
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT)
-#define I40E_GL_FWRESETCNT 0x00083100 /* Reset: POR */
-#define I40E_GL_FWRESETCNT_FWRESETCNT_SHIFT 0
-#define I40E_GL_FWRESETCNT_FWRESETCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FWRESETCNT_FWRESETCNT_SHIFT)
-#define I40E_GL_MNG_FWSM 0x000B6134 /* Reset: POR */
-#define I40E_GL_MNG_FWSM_FW_MODES_SHIFT 0
-#define I40E_GL_MNG_FWSM_FW_MODES_MASK I40E_MASK(0x3, I40E_GL_MNG_FWSM_FW_MODES_SHIFT)
-#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT 10
-#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT)
-#define I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_SHIFT 11
-#define I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_MASK I40E_MASK(0xF, I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_SHIFT)
-#define I40E_GL_MNG_FWSM_FW_STATUS_VALID_SHIFT 15
-#define I40E_GL_MNG_FWSM_FW_STATUS_VALID_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_FW_STATUS_VALID_SHIFT)
-#define I40E_GL_MNG_FWSM_RESET_CNT_SHIFT 16
-#define I40E_GL_MNG_FWSM_RESET_CNT_MASK I40E_MASK(0x7, I40E_GL_MNG_FWSM_RESET_CNT_SHIFT)
-#define I40E_GL_MNG_FWSM_EXT_ERR_IND_SHIFT 19
-#define I40E_GL_MNG_FWSM_EXT_ERR_IND_MASK I40E_MASK(0x3F, I40E_GL_MNG_FWSM_EXT_ERR_IND_SHIFT)
-#define I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_SHIFT 26
-#define I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_SHIFT)
-#define I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_SHIFT 27
-#define I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_SHIFT)
-#define I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_SHIFT 28
-#define I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_SHIFT)
-#define I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_SHIFT 29
-#define I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_SHIFT)
-#define I40E_GL_MNG_HWARB_CTRL 0x000B6130 /* Reset: POR */
-#define I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_SHIFT 0
-#define I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_MASK I40E_MASK(0x1, I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_SHIFT)
-#define I40E_PRT_MNG_FTFT_DATA(_i) (0x000852A0 + ((_i) * 32)) /* _i=0...31 */ /* Reset: POR */
-#define I40E_PRT_MNG_FTFT_DATA_MAX_INDEX 31
-#define I40E_PRT_MNG_FTFT_DATA_DWORD_SHIFT 0
-#define I40E_PRT_MNG_FTFT_DATA_DWORD_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_FTFT_DATA_DWORD_SHIFT)
-#define I40E_PRT_MNG_FTFT_LENGTH 0x00085260 /* Reset: POR */
-#define I40E_PRT_MNG_FTFT_LENGTH_LENGTH_SHIFT 0
-#define I40E_PRT_MNG_FTFT_LENGTH_LENGTH_MASK I40E_MASK(0xFF, I40E_PRT_MNG_FTFT_LENGTH_LENGTH_SHIFT)
-#define I40E_PRT_MNG_FTFT_MASK(_i) (0x00085160 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
-#define I40E_PRT_MNG_FTFT_MASK_MAX_INDEX 7
-#define I40E_PRT_MNG_FTFT_MASK_MASK_SHIFT 0
-#define I40E_PRT_MNG_FTFT_MASK_MASK_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_FTFT_MASK_MASK_SHIFT)
-#define I40E_PRT_MNG_MANC 0x00256A20 /* Reset: POR */
-#define I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_SHIFT 0
-#define I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_SHIFT)
-#define I40E_PRT_MNG_MANC_NCSI_DISCARD_SHIFT 1
-#define I40E_PRT_MNG_MANC_NCSI_DISCARD_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_NCSI_DISCARD_SHIFT)
-#define I40E_PRT_MNG_MANC_RCV_TCO_EN_SHIFT 17
-#define I40E_PRT_MNG_MANC_RCV_TCO_EN_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_RCV_TCO_EN_SHIFT)
-#define I40E_PRT_MNG_MANC_RCV_ALL_SHIFT 19
-#define I40E_PRT_MNG_MANC_RCV_ALL_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_RCV_ALL_SHIFT)
-#define I40E_PRT_MNG_MANC_FIXED_NET_TYPE_SHIFT 25
-#define I40E_PRT_MNG_MANC_FIXED_NET_TYPE_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_FIXED_NET_TYPE_SHIFT)
-#define I40E_PRT_MNG_MANC_NET_TYPE_SHIFT 26
-#define I40E_PRT_MNG_MANC_NET_TYPE_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_NET_TYPE_SHIFT)
-#define I40E_PRT_MNG_MANC_EN_BMC2OS_SHIFT 28
-#define I40E_PRT_MNG_MANC_EN_BMC2OS_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_EN_BMC2OS_SHIFT)
-#define I40E_PRT_MNG_MANC_EN_BMC2NET_SHIFT 29
-#define I40E_PRT_MNG_MANC_EN_BMC2NET_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_EN_BMC2NET_SHIFT)
-#define I40E_PRT_MNG_MAVTV(_i) (0x00255900 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
-#define I40E_PRT_MNG_MAVTV_MAX_INDEX 7
-#define I40E_PRT_MNG_MAVTV_VID_SHIFT 0
-#define I40E_PRT_MNG_MAVTV_VID_MASK I40E_MASK(0xFFF, I40E_PRT_MNG_MAVTV_VID_SHIFT)
-#define I40E_PRT_MNG_MDEF(_i) (0x00255D00 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
-#define I40E_PRT_MNG_MDEF_MAX_INDEX 7
-#define I40E_PRT_MNG_MDEF_MAC_EXACT_AND_SHIFT 0
-#define I40E_PRT_MNG_MDEF_MAC_EXACT_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_MAC_EXACT_AND_SHIFT)
-#define I40E_PRT_MNG_MDEF_BROADCAST_AND_SHIFT 4
-#define I40E_PRT_MNG_MDEF_BROADCAST_AND_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_BROADCAST_AND_SHIFT)
-#define I40E_PRT_MNG_MDEF_VLAN_AND_SHIFT 5
-#define I40E_PRT_MNG_MDEF_VLAN_AND_MASK I40E_MASK(0xFF, I40E_PRT_MNG_MDEF_VLAN_AND_SHIFT)
-#define I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_SHIFT 13
-#define I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_SHIFT)
-#define I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_SHIFT 17
-#define I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_SHIFT)
-#define I40E_PRT_MNG_MDEF_MAC_EXACT_OR_SHIFT 21
-#define I40E_PRT_MNG_MDEF_MAC_EXACT_OR_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_MAC_EXACT_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_BROADCAST_OR_SHIFT 25
-#define I40E_PRT_MNG_MDEF_BROADCAST_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_BROADCAST_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_MULTICAST_AND_SHIFT 26
-#define I40E_PRT_MNG_MDEF_MULTICAST_AND_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_MULTICAST_AND_SHIFT)
-#define I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_SHIFT 27
-#define I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_SHIFT 28
-#define I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_SHIFT 29
-#define I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_PORT_0X298_OR_SHIFT 30
-#define I40E_PRT_MNG_MDEF_PORT_0X298_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_PORT_0X298_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_PORT_0X26F_OR_SHIFT 31
-#define I40E_PRT_MNG_MDEF_PORT_0X26F_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_PORT_0X26F_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT(_i) (0x00255F00 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
-#define I40E_PRT_MNG_MDEF_EXT_MAX_INDEX 7
-#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_SHIFT 0
-#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_SHIFT 4
-#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_SHIFT 8
-#define I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_SHIFT 24
-#define I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_SHIFT 25
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_SHIFT 26
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_SHIFT 27
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_ICMP_OR_SHIFT 28
-#define I40E_PRT_MNG_MDEF_EXT_ICMP_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_ICMP_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_MLD_SHIFT 29
-#define I40E_PRT_MNG_MDEF_EXT_MLD_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_MLD_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_SHIFT 30
-#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_SHIFT 31
-#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_SHIFT)
-#define I40E_PRT_MNG_MDEFVSI(_i) (0x00256580 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_PRT_MNG_MDEFVSI_MAX_INDEX 3
-#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_SHIFT 0
-#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_SHIFT)
-#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_SHIFT 16
-#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_SHIFT)
-#define I40E_PRT_MNG_METF(_i) (0x00256780 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_PRT_MNG_METF_MAX_INDEX 3
-#define I40E_PRT_MNG_METF_ETYPE_SHIFT 0
-#define I40E_PRT_MNG_METF_ETYPE_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_METF_ETYPE_SHIFT)
-#define I40E_PRT_MNG_METF_POLARITY_SHIFT 30
-#define I40E_PRT_MNG_METF_POLARITY_MASK I40E_MASK(0x1, I40E_PRT_MNG_METF_POLARITY_SHIFT)
-#define I40E_PRT_MNG_MFUTP(_i) (0x00254E00 + ((_i) * 32)) /* _i=0...15 */ /* Reset: POR */
-#define I40E_PRT_MNG_MFUTP_MAX_INDEX 15
-#define I40E_PRT_MNG_MFUTP_MFUTP_N_SHIFT 0
-#define I40E_PRT_MNG_MFUTP_MFUTP_N_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MFUTP_MFUTP_N_SHIFT)
-#define I40E_PRT_MNG_MFUTP_UDP_SHIFT 16
-#define I40E_PRT_MNG_MFUTP_UDP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MFUTP_UDP_SHIFT)
-#define I40E_PRT_MNG_MFUTP_TCP_SHIFT 17
-#define I40E_PRT_MNG_MFUTP_TCP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MFUTP_TCP_SHIFT)
-#define I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_SHIFT 18
-#define I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_MASK I40E_MASK(0x1, I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_SHIFT)
-#define I40E_PRT_MNG_MIPAF4(_i) (0x00256280 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_PRT_MNG_MIPAF4_MAX_INDEX 3
-#define I40E_PRT_MNG_MIPAF4_MIPAF_SHIFT 0
-#define I40E_PRT_MNG_MIPAF4_MIPAF_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_MIPAF4_MIPAF_SHIFT)
-#define I40E_PRT_MNG_MIPAF6(_i) (0x00254200 + ((_i) * 32)) /* _i=0...15 */ /* Reset: POR */
-#define I40E_PRT_MNG_MIPAF6_MAX_INDEX 15
-#define I40E_PRT_MNG_MIPAF6_MIPAF_SHIFT 0
-#define I40E_PRT_MNG_MIPAF6_MIPAF_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_MIPAF6_MIPAF_SHIFT)
-#define I40E_PRT_MNG_MMAH(_i) (0x00256380 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_PRT_MNG_MMAH_MAX_INDEX 3
-#define I40E_PRT_MNG_MMAH_MMAH_SHIFT 0
-#define I40E_PRT_MNG_MMAH_MMAH_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MMAH_MMAH_SHIFT)
-#define I40E_PRT_MNG_MMAL(_i) (0x00256480 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
-#define I40E_PRT_MNG_MMAL_MAX_INDEX 3
-#define I40E_PRT_MNG_MMAL_MMAL_SHIFT 0
-#define I40E_PRT_MNG_MMAL_MMAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_MMAL_MMAL_SHIFT)
-#define I40E_PRT_MNG_MNGONLY 0x00256A60 /* Reset: POR */
-#define I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_SHIFT 0
-#define I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_MASK I40E_MASK(0xFF, I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_SHIFT)
-#define I40E_PRT_MNG_MSFM 0x00256AA0 /* Reset: POR */
-#define I40E_PRT_MNG_MSFM_PORT_26F_UDP_SHIFT 0
-#define I40E_PRT_MNG_MSFM_PORT_26F_UDP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_26F_UDP_SHIFT)
-#define I40E_PRT_MNG_MSFM_PORT_26F_TCP_SHIFT 1
-#define I40E_PRT_MNG_MSFM_PORT_26F_TCP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_26F_TCP_SHIFT)
-#define I40E_PRT_MNG_MSFM_PORT_298_UDP_SHIFT 2
-#define I40E_PRT_MNG_MSFM_PORT_298_UDP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_298_UDP_SHIFT)
-#define I40E_PRT_MNG_MSFM_PORT_298_TCP_SHIFT 3
-#define I40E_PRT_MNG_MSFM_PORT_298_TCP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_298_TCP_SHIFT)
-#define I40E_PRT_MNG_MSFM_IPV6_0_MASK_SHIFT 4
-#define I40E_PRT_MNG_MSFM_IPV6_0_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_0_MASK_SHIFT)
-#define I40E_PRT_MNG_MSFM_IPV6_1_MASK_SHIFT 5
-#define I40E_PRT_MNG_MSFM_IPV6_1_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_1_MASK_SHIFT)
-#define I40E_PRT_MNG_MSFM_IPV6_2_MASK_SHIFT 6
-#define I40E_PRT_MNG_MSFM_IPV6_2_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_2_MASK_SHIFT)
-#define I40E_PRT_MNG_MSFM_IPV6_3_MASK_SHIFT 7
-#define I40E_PRT_MNG_MSFM_IPV6_3_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_3_MASK_SHIFT)
-#define I40E_MSIX_PBA(_i) (0x00001000 + ((_i) * 4)) /* _i=0...5 */ /* Reset: FLR */
-#define I40E_MSIX_PBA_MAX_INDEX 5
-#define I40E_MSIX_PBA_PENBIT_SHIFT 0
-#define I40E_MSIX_PBA_PENBIT_MASK I40E_MASK(0xFFFFFFFF, I40E_MSIX_PBA_PENBIT_SHIFT)
-#define I40E_MSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
-#define I40E_MSIX_TADD_MAX_INDEX 128
-#define I40E_MSIX_TADD_MSIXTADD10_SHIFT 0
-#define I40E_MSIX_TADD_MSIXTADD10_MASK I40E_MASK(0x3, I40E_MSIX_TADD_MSIXTADD10_SHIFT)
-#define I40E_MSIX_TADD_MSIXTADD_SHIFT 2
-#define I40E_MSIX_TADD_MSIXTADD_MASK I40E_MASK(0x3FFFFFFF, I40E_MSIX_TADD_MSIXTADD_SHIFT)
-#define I40E_MSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
-#define I40E_MSIX_TMSG_MAX_INDEX 128
-#define I40E_MSIX_TMSG_MSIXTMSG_SHIFT 0
-#define I40E_MSIX_TMSG_MSIXTMSG_MASK I40E_MASK(0xFFFFFFFF, I40E_MSIX_TMSG_MSIXTMSG_SHIFT)
-#define I40E_MSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
-#define I40E_MSIX_TUADD_MAX_INDEX 128
-#define I40E_MSIX_TUADD_MSIXTUADD_SHIFT 0
-#define I40E_MSIX_TUADD_MSIXTUADD_MASK I40E_MASK(0xFFFFFFFF, I40E_MSIX_TUADD_MSIXTUADD_SHIFT)
-#define I40E_MSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
-#define I40E_MSIX_TVCTRL_MAX_INDEX 128
-#define I40E_MSIX_TVCTRL_MASK_SHIFT 0
-#define I40E_MSIX_TVCTRL_MASK_MASK I40E_MASK(0x1, I40E_MSIX_TVCTRL_MASK_SHIFT)
-#define I40E_VFMSIX_PBA1(_i) (0x00002000 + ((_i) * 4)) /* _i=0...19 */ /* Reset: VFLR */
-#define I40E_VFMSIX_PBA1_MAX_INDEX 19
-#define I40E_VFMSIX_PBA1_PENBIT_SHIFT 0
-#define I40E_VFMSIX_PBA1_PENBIT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_PBA1_PENBIT_SHIFT)
-#define I40E_VFMSIX_TADD1(_i) (0x00002100 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
-#define I40E_VFMSIX_TADD1_MAX_INDEX 639
-#define I40E_VFMSIX_TADD1_MSIXTADD10_SHIFT 0
-#define I40E_VFMSIX_TADD1_MSIXTADD10_MASK I40E_MASK(0x3, I40E_VFMSIX_TADD1_MSIXTADD10_SHIFT)
-#define I40E_VFMSIX_TADD1_MSIXTADD_SHIFT 2
-#define I40E_VFMSIX_TADD1_MSIXTADD_MASK I40E_MASK(0x3FFFFFFF, I40E_VFMSIX_TADD1_MSIXTADD_SHIFT)
-#define I40E_VFMSIX_TMSG1(_i) (0x00002108 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
-#define I40E_VFMSIX_TMSG1_MAX_INDEX 639
-#define I40E_VFMSIX_TMSG1_MSIXTMSG_SHIFT 0
-#define I40E_VFMSIX_TMSG1_MSIXTMSG_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TMSG1_MSIXTMSG_SHIFT)
-#define I40E_VFMSIX_TUADD1(_i) (0x00002104 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
-#define I40E_VFMSIX_TUADD1_MAX_INDEX 639
-#define I40E_VFMSIX_TUADD1_MSIXTUADD_SHIFT 0
-#define I40E_VFMSIX_TUADD1_MSIXTUADD_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TUADD1_MSIXTUADD_SHIFT)
-#define I40E_VFMSIX_TVCTRL1(_i) (0x0000210C + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
-#define I40E_VFMSIX_TVCTRL1_MAX_INDEX 639
-#define I40E_VFMSIX_TVCTRL1_MASK_SHIFT 0
-#define I40E_VFMSIX_TVCTRL1_MASK_MASK I40E_MASK(0x1, I40E_VFMSIX_TVCTRL1_MASK_SHIFT)
#define I40E_GLNVM_FLA 0x000B6108 /* Reset: POR */
-#define I40E_GLNVM_FLA_FL_SCK_SHIFT 0
-#define I40E_GLNVM_FLA_FL_SCK_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_SCK_SHIFT)
-#define I40E_GLNVM_FLA_FL_CE_SHIFT 1
-#define I40E_GLNVM_FLA_FL_CE_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_CE_SHIFT)
-#define I40E_GLNVM_FLA_FL_SI_SHIFT 2
-#define I40E_GLNVM_FLA_FL_SI_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_SI_SHIFT)
-#define I40E_GLNVM_FLA_FL_SO_SHIFT 3
-#define I40E_GLNVM_FLA_FL_SO_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_SO_SHIFT)
-#define I40E_GLNVM_FLA_FL_REQ_SHIFT 4
-#define I40E_GLNVM_FLA_FL_REQ_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_REQ_SHIFT)
-#define I40E_GLNVM_FLA_FL_GNT_SHIFT 5
-#define I40E_GLNVM_FLA_FL_GNT_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_GNT_SHIFT)
#define I40E_GLNVM_FLA_LOCKED_SHIFT 6
#define I40E_GLNVM_FLA_LOCKED_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_LOCKED_SHIFT)
-#define I40E_GLNVM_FLA_FL_SADDR_SHIFT 18
-#define I40E_GLNVM_FLA_FL_SADDR_MASK I40E_MASK(0x7FF, I40E_GLNVM_FLA_FL_SADDR_SHIFT)
-#define I40E_GLNVM_FLA_FL_BUSY_SHIFT 30
-#define I40E_GLNVM_FLA_FL_BUSY_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_BUSY_SHIFT)
-#define I40E_GLNVM_FLA_FL_DER_SHIFT 31
-#define I40E_GLNVM_FLA_FL_DER_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_DER_SHIFT)
-#define I40E_GLNVM_FLASHID 0x000B6104 /* Reset: POR */
-#define I40E_GLNVM_FLASHID_FLASHID_SHIFT 0
-#define I40E_GLNVM_FLASHID_FLASHID_MASK I40E_MASK(0xFFFFFF, I40E_GLNVM_FLASHID_FLASHID_SHIFT)
-#define I40E_GLNVM_FLASHID_FLEEP_PERF_SHIFT 31
-#define I40E_GLNVM_FLASHID_FLEEP_PERF_MASK I40E_MASK(0x1, I40E_GLNVM_FLASHID_FLEEP_PERF_SHIFT)
#define I40E_GLNVM_GENS 0x000B6100 /* Reset: POR */
-#define I40E_GLNVM_GENS_NVM_PRES_SHIFT 0
-#define I40E_GLNVM_GENS_NVM_PRES_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_NVM_PRES_SHIFT)
#define I40E_GLNVM_GENS_SR_SIZE_SHIFT 5
#define I40E_GLNVM_GENS_SR_SIZE_MASK I40E_MASK(0x7, I40E_GLNVM_GENS_SR_SIZE_SHIFT)
-#define I40E_GLNVM_GENS_BANK1VAL_SHIFT 8
-#define I40E_GLNVM_GENS_BANK1VAL_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_BANK1VAL_SHIFT)
-#define I40E_GLNVM_GENS_ALT_PRST_SHIFT 23
-#define I40E_GLNVM_GENS_ALT_PRST_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_ALT_PRST_SHIFT)
-#define I40E_GLNVM_GENS_FL_AUTO_RD_SHIFT 25
-#define I40E_GLNVM_GENS_FL_AUTO_RD_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_FL_AUTO_RD_SHIFT)
-#define I40E_GLNVM_PROTCSR(_i) (0x000B6010 + ((_i) * 4)) /* _i=0...59 */ /* Reset: POR */
-#define I40E_GLNVM_PROTCSR_MAX_INDEX 59
-#define I40E_GLNVM_PROTCSR_ADDR_BLOCK_SHIFT 0
-#define I40E_GLNVM_PROTCSR_ADDR_BLOCK_MASK I40E_MASK(0xFFFFFF, I40E_GLNVM_PROTCSR_ADDR_BLOCK_SHIFT)
#define I40E_GLNVM_SRCTL 0x000B6110 /* Reset: POR */
-#define I40E_GLNVM_SRCTL_SRBUSY_SHIFT 0
-#define I40E_GLNVM_SRCTL_SRBUSY_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_SRBUSY_SHIFT)
#define I40E_GLNVM_SRCTL_ADDR_SHIFT 14
-#define I40E_GLNVM_SRCTL_ADDR_MASK I40E_MASK(0x7FFF, I40E_GLNVM_SRCTL_ADDR_SHIFT)
-#define I40E_GLNVM_SRCTL_WRITE_SHIFT 29
-#define I40E_GLNVM_SRCTL_WRITE_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_WRITE_SHIFT)
#define I40E_GLNVM_SRCTL_START_SHIFT 30
-#define I40E_GLNVM_SRCTL_START_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_START_SHIFT)
#define I40E_GLNVM_SRCTL_DONE_SHIFT 31
#define I40E_GLNVM_SRCTL_DONE_MASK I40E_MASK(0x1u, I40E_GLNVM_SRCTL_DONE_SHIFT)
#define I40E_GLNVM_SRDATA 0x000B6114 /* Reset: POR */
-#define I40E_GLNVM_SRDATA_WRDATA_SHIFT 0
-#define I40E_GLNVM_SRDATA_WRDATA_MASK I40E_MASK(0xFFFF, I40E_GLNVM_SRDATA_WRDATA_SHIFT)
#define I40E_GLNVM_SRDATA_RDDATA_SHIFT 16
#define I40E_GLNVM_SRDATA_RDDATA_MASK I40E_MASK(0xFFFF, I40E_GLNVM_SRDATA_RDDATA_SHIFT)
#define I40E_GLNVM_ULD 0x000B6008 /* Reset: POR */
-#define I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT 0
-#define I40E_GLNVM_ULD_CONF_PCIR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT)
-#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT 1
-#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT)
-#define I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT 2
-#define I40E_GLNVM_ULD_CONF_LCB_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT 3
#define I40E_GLNVM_ULD_CONF_CORE_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT 4
#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT)
-#define I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT 5
-#define I40E_GLNVM_ULD_CONF_POR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT)
-#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT 6
-#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT)
-#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT 7
-#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT)
-#define I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT 8
-#define I40E_GLNVM_ULD_CONF_EMP_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT)
-#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT 9
-#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT)
-#define I40E_GLPCI_BYTCTH 0x0009C484 /* Reset: PCIR */
-#define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT 0
-#define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT)
-#define I40E_GLPCI_BYTCTL 0x0009C488 /* Reset: PCIR */
-#define I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_SHIFT 0
-#define I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_SHIFT)
-#define I40E_GLPCI_CAPCTRL 0x000BE4A4 /* Reset: PCIR */
-#define I40E_GLPCI_CAPCTRL_VPD_EN_SHIFT 0
-#define I40E_GLPCI_CAPCTRL_VPD_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPCTRL_VPD_EN_SHIFT)
#define I40E_GLPCI_CAPSUP 0x000BE4A8 /* Reset: PCIR */
-#define I40E_GLPCI_CAPSUP_PCIE_VER_SHIFT 0
-#define I40E_GLPCI_CAPSUP_PCIE_VER_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_PCIE_VER_SHIFT)
-#define I40E_GLPCI_CAPSUP_LTR_EN_SHIFT 2
-#define I40E_GLPCI_CAPSUP_LTR_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_LTR_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP_TPH_EN_SHIFT 3
-#define I40E_GLPCI_CAPSUP_TPH_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_TPH_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_ARI_EN_SHIFT 4
#define I40E_GLPCI_CAPSUP_ARI_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ARI_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP_IOV_EN_SHIFT 5
-#define I40E_GLPCI_CAPSUP_IOV_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_IOV_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP_ACS_EN_SHIFT 6
-#define I40E_GLPCI_CAPSUP_ACS_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ACS_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP_SEC_EN_SHIFT 7
-#define I40E_GLPCI_CAPSUP_SEC_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_SEC_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP_ECRC_GEN_EN_SHIFT 16
-#define I40E_GLPCI_CAPSUP_ECRC_GEN_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ECRC_GEN_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP_ECRC_CHK_EN_SHIFT 17
-#define I40E_GLPCI_CAPSUP_ECRC_CHK_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ECRC_CHK_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP_IDO_EN_SHIFT 18
-#define I40E_GLPCI_CAPSUP_IDO_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_IDO_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP_MSI_MASK_SHIFT 19
-#define I40E_GLPCI_CAPSUP_MSI_MASK_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_MSI_MASK_SHIFT)
-#define I40E_GLPCI_CAPSUP_CSR_CONF_EN_SHIFT 20
-#define I40E_GLPCI_CAPSUP_CSR_CONF_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_CSR_CONF_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_SHIFT 30
-#define I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_SHIFT)
-#define I40E_GLPCI_CAPSUP_LOAD_DEV_ID_SHIFT 31
-#define I40E_GLPCI_CAPSUP_LOAD_DEV_ID_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_LOAD_DEV_ID_SHIFT)
-#define I40E_GLPCI_CNF 0x000BE4C0 /* Reset: POR */
-#define I40E_GLPCI_CNF_FLEX10_SHIFT 1
-#define I40E_GLPCI_CNF_FLEX10_MASK I40E_MASK(0x1, I40E_GLPCI_CNF_FLEX10_SHIFT)
-#define I40E_GLPCI_CNF_WAKE_PIN_EN_SHIFT 2
-#define I40E_GLPCI_CNF_WAKE_PIN_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CNF_WAKE_PIN_EN_SHIFT)
#define I40E_GLPCI_CNF2 0x000BE494 /* Reset: PCIR */
-#define I40E_GLPCI_CNF2_RO_DIS_SHIFT 0
-#define I40E_GLPCI_CNF2_RO_DIS_MASK I40E_MASK(0x1, I40E_GLPCI_CNF2_RO_DIS_SHIFT)
-#define I40E_GLPCI_CNF2_CACHELINE_SIZE_SHIFT 1
-#define I40E_GLPCI_CNF2_CACHELINE_SIZE_MASK I40E_MASK(0x1, I40E_GLPCI_CNF2_CACHELINE_SIZE_SHIFT)
#define I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT 2
#define I40E_GLPCI_CNF2_MSI_X_PF_N_MASK I40E_MASK(0x7FF, I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT)
#define I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT 13
#define I40E_GLPCI_CNF2_MSI_X_VF_N_MASK I40E_MASK(0x7FF, I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT)
-#define I40E_GLPCI_DREVID 0x0009C480 /* Reset: PCIR */
-#define I40E_GLPCI_DREVID_DEFAULT_REVID_SHIFT 0
-#define I40E_GLPCI_DREVID_DEFAULT_REVID_MASK I40E_MASK(0xFF, I40E_GLPCI_DREVID_DEFAULT_REVID_SHIFT)
-#define I40E_GLPCI_GSCL_1 0x0009C48C /* Reset: PCIR */
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_SHIFT 0
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_SHIFT)
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_SHIFT 1
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_SHIFT)
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_SHIFT 2
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_SHIFT)
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_SHIFT 3
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_SHIFT)
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_0_SHIFT 4
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_0_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_0_SHIFT)
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_1_SHIFT 5
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_1_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_1_SHIFT)
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_2_SHIFT 6
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_2_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_2_SHIFT)
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_3_SHIFT 7
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_3_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_3_SHIFT)
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_SHIFT 8
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_SHIFT)
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_SHIFT 9
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_MASK I40E_MASK(0x1F, I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_SHIFT)
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_SHIFT 14
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_SHIFT)
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_SHIFT 15
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_MASK I40E_MASK(0x1F, I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_SHIFT)
-#define I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_SHIFT 28
-#define I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_SHIFT)
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_SHIFT 29
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_SHIFT)
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_SHIFT 30
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_SHIFT)
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_START_SHIFT 31
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_START_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_START_SHIFT)
-#define I40E_GLPCI_GSCL_2 0x0009C490 /* Reset: PCIR */
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_SHIFT 0
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_SHIFT)
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_SHIFT 8
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_SHIFT)
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_SHIFT 16
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_SHIFT)
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_SHIFT 24
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_SHIFT)
-#define I40E_GLPCI_GSCL_5_8(_i) (0x0009C494 + ((_i) * 4)) /* _i=0...3 */ /* Reset: PCIR */
-#define I40E_GLPCI_GSCL_5_8_MAX_INDEX 3
-#define I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_SHIFT 0
-#define I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_MASK I40E_MASK(0xFFFF, I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_SHIFT)
-#define I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_SHIFT 16
-#define I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_MASK I40E_MASK(0xFFFF, I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_SHIFT)
-#define I40E_GLPCI_GSCN_0_3(_i) (0x0009C4A4 + ((_i) * 4)) /* _i=0...3 */ /* Reset: PCIR */
-#define I40E_GLPCI_GSCN_0_3_MAX_INDEX 3
-#define I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_SHIFT 0
-#define I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_SHIFT)
#define I40E_GLPCI_LBARCTRL 0x000BE484 /* Reset: POR */
-#define I40E_GLPCI_LBARCTRL_PREFBAR_SHIFT 0
-#define I40E_GLPCI_LBARCTRL_PREFBAR_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_PREFBAR_SHIFT)
-#define I40E_GLPCI_LBARCTRL_BAR32_SHIFT 1
-#define I40E_GLPCI_LBARCTRL_BAR32_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_BAR32_SHIFT)
-#define I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_SHIFT 3
-#define I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_SHIFT)
-#define I40E_GLPCI_LBARCTRL_RSVD_4_SHIFT 4
-#define I40E_GLPCI_LBARCTRL_RSVD_4_MASK I40E_MASK(0x3, I40E_GLPCI_LBARCTRL_RSVD_4_SHIFT)
#define I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT 6
#define I40E_GLPCI_LBARCTRL_FL_SIZE_MASK I40E_MASK(0x7, I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT)
-#define I40E_GLPCI_LBARCTRL_RSVD_10_SHIFT 10
-#define I40E_GLPCI_LBARCTRL_RSVD_10_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_RSVD_10_SHIFT)
-#define I40E_GLPCI_LBARCTRL_EXROM_SIZE_SHIFT 11
-#define I40E_GLPCI_LBARCTRL_EXROM_SIZE_MASK I40E_MASK(0x7, I40E_GLPCI_LBARCTRL_EXROM_SIZE_SHIFT)
-#define I40E_GLPCI_LINKCAP 0x000BE4AC /* Reset: PCIR */
-#define I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_SHIFT 0
-#define I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_MASK I40E_MASK(0x3F, I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_SHIFT)
-#define I40E_GLPCI_LINKCAP_MAX_PAYLOAD_SHIFT 6
-#define I40E_GLPCI_LINKCAP_MAX_PAYLOAD_MASK I40E_MASK(0x7, I40E_GLPCI_LINKCAP_MAX_PAYLOAD_SHIFT)
-#define I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_SHIFT 9
-#define I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_MASK I40E_MASK(0xF, I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_SHIFT)
-#define I40E_GLPCI_PCIERR 0x000BE4FC /* Reset: PCIR */
-#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT 0
-#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT)
-#define I40E_GLPCI_PKTCT 0x0009C4BC /* Reset: PCIR */
-#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT 0
-#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT)
-#define I40E_GLPCI_PM_MUX_NPQ 0x0009C4F4 /* Reset: PCIR */
-#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT 0
-#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_MASK I40E_MASK(0x7, I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT)
-#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT 16
-#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_MASK I40E_MASK(0x1F, I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT)
-#define I40E_GLPCI_PM_MUX_PFB 0x0009C4F0 /* Reset: PCIR */
-#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT 0
-#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_MASK I40E_MASK(0x1F, I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT)
-#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT 16
-#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_MASK I40E_MASK(0x7, I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT)
-#define I40E_GLPCI_PMSUP 0x000BE4B0 /* Reset: PCIR */
-#define I40E_GLPCI_PMSUP_ASPM_SUP_SHIFT 0
-#define I40E_GLPCI_PMSUP_ASPM_SUP_MASK I40E_MASK(0x3, I40E_GLPCI_PMSUP_ASPM_SUP_SHIFT)
-#define I40E_GLPCI_PMSUP_L0S_EXIT_LAT_SHIFT 2
-#define I40E_GLPCI_PMSUP_L0S_EXIT_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L0S_EXIT_LAT_SHIFT)
-#define I40E_GLPCI_PMSUP_L1_EXIT_LAT_SHIFT 5
-#define I40E_GLPCI_PMSUP_L1_EXIT_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L1_EXIT_LAT_SHIFT)
-#define I40E_GLPCI_PMSUP_L0S_ACC_LAT_SHIFT 8
-#define I40E_GLPCI_PMSUP_L0S_ACC_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L0S_ACC_LAT_SHIFT)
-#define I40E_GLPCI_PMSUP_L1_ACC_LAT_SHIFT 11
-#define I40E_GLPCI_PMSUP_L1_ACC_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L1_ACC_LAT_SHIFT)
-#define I40E_GLPCI_PMSUP_SLOT_CLK_SHIFT 14
-#define I40E_GLPCI_PMSUP_SLOT_CLK_MASK I40E_MASK(0x1, I40E_GLPCI_PMSUP_SLOT_CLK_SHIFT)
-#define I40E_GLPCI_PMSUP_OBFF_SUP_SHIFT 15
-#define I40E_GLPCI_PMSUP_OBFF_SUP_MASK I40E_MASK(0x3, I40E_GLPCI_PMSUP_OBFF_SUP_SHIFT)
-#define I40E_GLPCI_PQ_MAX_USED_SPC 0x0009C4EC /* Reset: PCIR */
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT 0
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_MASK I40E_MASK(0xFF, I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT)
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT 8
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_MASK I40E_MASK(0xFF, I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT)
-#define I40E_GLPCI_PWRDATA 0x000BE490 /* Reset: PCIR */
-#define I40E_GLPCI_PWRDATA_D0_POWER_SHIFT 0
-#define I40E_GLPCI_PWRDATA_D0_POWER_MASK I40E_MASK(0xFF, I40E_GLPCI_PWRDATA_D0_POWER_SHIFT)
-#define I40E_GLPCI_PWRDATA_COMM_POWER_SHIFT 8
-#define I40E_GLPCI_PWRDATA_COMM_POWER_MASK I40E_MASK(0xFF, I40E_GLPCI_PWRDATA_COMM_POWER_SHIFT)
-#define I40E_GLPCI_PWRDATA_D3_POWER_SHIFT 16
-#define I40E_GLPCI_PWRDATA_D3_POWER_MASK I40E_MASK(0xFF, I40E_GLPCI_PWRDATA_D3_POWER_SHIFT)
-#define I40E_GLPCI_PWRDATA_DATA_SCALE_SHIFT 24
-#define I40E_GLPCI_PWRDATA_DATA_SCALE_MASK I40E_MASK(0x3, I40E_GLPCI_PWRDATA_DATA_SCALE_SHIFT)
-#define I40E_GLPCI_REVID 0x000BE4B4 /* Reset: PCIR */
-#define I40E_GLPCI_REVID_NVM_REVID_SHIFT 0
-#define I40E_GLPCI_REVID_NVM_REVID_MASK I40E_MASK(0xFF, I40E_GLPCI_REVID_NVM_REVID_SHIFT)
-#define I40E_GLPCI_SERH 0x000BE49C /* Reset: PCIR */
-#define I40E_GLPCI_SERH_SER_NUM_H_SHIFT 0
-#define I40E_GLPCI_SERH_SER_NUM_H_MASK I40E_MASK(0xFFFF, I40E_GLPCI_SERH_SER_NUM_H_SHIFT)
-#define I40E_GLPCI_SERL 0x000BE498 /* Reset: PCIR */
-#define I40E_GLPCI_SERL_SER_NUM_L_SHIFT 0
-#define I40E_GLPCI_SERL_SER_NUM_L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_SERL_SER_NUM_L_SHIFT)
-#define I40E_GLPCI_SPARE_BITS_0 0x0009C4F8 /* Reset: PCIR */
-#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT 0
-#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT)
-#define I40E_GLPCI_SPARE_BITS_1 0x0009C4FC /* Reset: PCIR */
-#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT 0
-#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT)
-#define I40E_GLPCI_SUBVENID 0x000BE48C /* Reset: PCIR */
-#define I40E_GLPCI_SUBVENID_SUB_VEN_ID_SHIFT 0
-#define I40E_GLPCI_SUBVENID_SUB_VEN_ID_MASK I40E_MASK(0xFFFF, I40E_GLPCI_SUBVENID_SUB_VEN_ID_SHIFT)
-#define I40E_GLPCI_UPADD 0x000BE4F8 /* Reset: PCIR */
-#define I40E_GLPCI_UPADD_ADDRESS_SHIFT 1
-#define I40E_GLPCI_UPADD_ADDRESS_MASK I40E_MASK(0x7FFFFFFF, I40E_GLPCI_UPADD_ADDRESS_SHIFT)
-#define I40E_GLPCI_VENDORID 0x000BE518 /* Reset: PCIR */
-#define I40E_GLPCI_VENDORID_VENDORID_SHIFT 0
-#define I40E_GLPCI_VENDORID_VENDORID_MASK I40E_MASK(0xFFFF, I40E_GLPCI_VENDORID_VENDORID_SHIFT)
-#define I40E_GLPCI_VFSUP 0x000BE4B8 /* Reset: PCIR */
-#define I40E_GLPCI_VFSUP_VF_PREFETCH_SHIFT 0
-#define I40E_GLPCI_VFSUP_VF_PREFETCH_MASK I40E_MASK(0x1, I40E_GLPCI_VFSUP_VF_PREFETCH_SHIFT)
-#define I40E_GLPCI_VFSUP_VR_BAR_TYPE_SHIFT 1
-#define I40E_GLPCI_VFSUP_VR_BAR_TYPE_MASK I40E_MASK(0x1, I40E_GLPCI_VFSUP_VR_BAR_TYPE_SHIFT)
-#define I40E_GLTPH_CTRL 0x000BE480 /* Reset: PCIR */
-#define I40E_GLTPH_CTRL_DESC_PH_SHIFT 9
-#define I40E_GLTPH_CTRL_DESC_PH_MASK I40E_MASK(0x3, I40E_GLTPH_CTRL_DESC_PH_SHIFT)
-#define I40E_GLTPH_CTRL_DATA_PH_SHIFT 11
-#define I40E_GLTPH_CTRL_DATA_PH_MASK I40E_MASK(0x3, I40E_GLTPH_CTRL_DATA_PH_SHIFT)
#define I40E_PF_FUNC_RID 0x0009C000 /* Reset: PCIR */
-#define I40E_PF_FUNC_RID_FUNCTION_NUMBER_SHIFT 0
-#define I40E_PF_FUNC_RID_FUNCTION_NUMBER_MASK I40E_MASK(0x7, I40E_PF_FUNC_RID_FUNCTION_NUMBER_SHIFT)
-#define I40E_PF_FUNC_RID_DEVICE_NUMBER_SHIFT 3
-#define I40E_PF_FUNC_RID_DEVICE_NUMBER_MASK I40E_MASK(0x1F, I40E_PF_FUNC_RID_DEVICE_NUMBER_SHIFT)
-#define I40E_PF_FUNC_RID_BUS_NUMBER_SHIFT 8
-#define I40E_PF_FUNC_RID_BUS_NUMBER_MASK I40E_MASK(0xFF, I40E_PF_FUNC_RID_BUS_NUMBER_SHIFT)
#define I40E_PF_PCI_CIAA 0x0009C080 /* Reset: FLR */
-#define I40E_PF_PCI_CIAA_ADDRESS_SHIFT 0
-#define I40E_PF_PCI_CIAA_ADDRESS_MASK I40E_MASK(0xFFF, I40E_PF_PCI_CIAA_ADDRESS_SHIFT)
#define I40E_PF_PCI_CIAA_VF_NUM_SHIFT 12
-#define I40E_PF_PCI_CIAA_VF_NUM_MASK I40E_MASK(0x7F, I40E_PF_PCI_CIAA_VF_NUM_SHIFT)
#define I40E_PF_PCI_CIAD 0x0009C100 /* Reset: FLR */
-#define I40E_PF_PCI_CIAD_DATA_SHIFT 0
-#define I40E_PF_PCI_CIAD_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_PCI_CIAD_DATA_SHIFT)
-#define I40E_PFPCI_CLASS 0x000BE400 /* Reset: PCIR */
-#define I40E_PFPCI_CLASS_STORAGE_CLASS_SHIFT 0
-#define I40E_PFPCI_CLASS_STORAGE_CLASS_MASK I40E_MASK(0x1, I40E_PFPCI_CLASS_STORAGE_CLASS_SHIFT)
-#define I40E_PFPCI_CLASS_RESERVED_1_SHIFT 1
-#define I40E_PFPCI_CLASS_RESERVED_1_MASK I40E_MASK(0x1, I40E_PFPCI_CLASS_RESERVED_1_SHIFT)
-#define I40E_PFPCI_CLASS_PF_IS_LAN_SHIFT 2
-#define I40E_PFPCI_CLASS_PF_IS_LAN_MASK I40E_MASK(0x1, I40E_PFPCI_CLASS_PF_IS_LAN_SHIFT)
-#define I40E_PFPCI_CNF 0x000BE000 /* Reset: PCIR */
-#define I40E_PFPCI_CNF_MSI_EN_SHIFT 2
-#define I40E_PFPCI_CNF_MSI_EN_MASK I40E_MASK(0x1, I40E_PFPCI_CNF_MSI_EN_SHIFT)
-#define I40E_PFPCI_CNF_EXROM_DIS_SHIFT 3
-#define I40E_PFPCI_CNF_EXROM_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_CNF_EXROM_DIS_SHIFT)
-#define I40E_PFPCI_CNF_IO_BAR_SHIFT 4
-#define I40E_PFPCI_CNF_IO_BAR_MASK I40E_MASK(0x1, I40E_PFPCI_CNF_IO_BAR_SHIFT)
-#define I40E_PFPCI_CNF_INT_PIN_SHIFT 5
-#define I40E_PFPCI_CNF_INT_PIN_MASK I40E_MASK(0x3, I40E_PFPCI_CNF_INT_PIN_SHIFT)
-#define I40E_PFPCI_DEVID 0x000BE080 /* Reset: PCIR */
-#define I40E_PFPCI_DEVID_PF_DEV_ID_SHIFT 0
-#define I40E_PFPCI_DEVID_PF_DEV_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_DEVID_PF_DEV_ID_SHIFT)
-#define I40E_PFPCI_DEVID_VF_DEV_ID_SHIFT 16
-#define I40E_PFPCI_DEVID_VF_DEV_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_DEVID_VF_DEV_ID_SHIFT)
-#define I40E_PFPCI_FACTPS 0x0009C180 /* Reset: FLR */
-#define I40E_PFPCI_FACTPS_FUNC_POWER_STATE_SHIFT 0
-#define I40E_PFPCI_FACTPS_FUNC_POWER_STATE_MASK I40E_MASK(0x3, I40E_PFPCI_FACTPS_FUNC_POWER_STATE_SHIFT)
-#define I40E_PFPCI_FACTPS_FUNC_AUX_EN_SHIFT 3
-#define I40E_PFPCI_FACTPS_FUNC_AUX_EN_MASK I40E_MASK(0x1, I40E_PFPCI_FACTPS_FUNC_AUX_EN_SHIFT)
-#define I40E_PFPCI_FUNC 0x000BE200 /* Reset: POR */
-#define I40E_PFPCI_FUNC_FUNC_DIS_SHIFT 0
-#define I40E_PFPCI_FUNC_FUNC_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC_FUNC_DIS_SHIFT)
-#define I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_SHIFT 1
-#define I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_SHIFT)
-#define I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_SHIFT 2
-#define I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_SHIFT)
-#define I40E_PFPCI_FUNC2 0x000BE180 /* Reset: PCIR */
-#define I40E_PFPCI_FUNC2_EMP_FUNC_DIS_SHIFT 0
-#define I40E_PFPCI_FUNC2_EMP_FUNC_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC2_EMP_FUNC_DIS_SHIFT)
-#define I40E_PFPCI_ICAUSE 0x0009C200 /* Reset: PFR */
-#define I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_SHIFT 0
-#define I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_SHIFT)
-#define I40E_PFPCI_IENA 0x0009C280 /* Reset: PFR */
-#define I40E_PFPCI_IENA_PCIE_ERR_EN_SHIFT 0
-#define I40E_PFPCI_IENA_PCIE_ERR_EN_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPCI_IENA_PCIE_ERR_EN_SHIFT)
-#define I40E_PFPCI_PF_FLUSH_DONE 0x0009C800 /* Reset: PCIR */
-#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_PM 0x000BE300 /* Reset: POR */
-#define I40E_PFPCI_PM_PME_EN_SHIFT 0
-#define I40E_PFPCI_PM_PME_EN_MASK I40E_MASK(0x1, I40E_PFPCI_PM_PME_EN_SHIFT)
-#define I40E_PFPCI_STATUS1 0x000BE280 /* Reset: POR */
-#define I40E_PFPCI_STATUS1_FUNC_VALID_SHIFT 0
-#define I40E_PFPCI_STATUS1_FUNC_VALID_MASK I40E_MASK(0x1, I40E_PFPCI_STATUS1_FUNC_VALID_SHIFT)
-#define I40E_PFPCI_SUBSYSID 0x000BE100 /* Reset: PCIR */
-#define I40E_PFPCI_SUBSYSID_PF_SUBSYS_ID_SHIFT 0
-#define I40E_PFPCI_SUBSYSID_PF_SUBSYS_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_SUBSYSID_PF_SUBSYS_ID_SHIFT)
-#define I40E_PFPCI_SUBSYSID_VF_SUBSYS_ID_SHIFT 16
-#define I40E_PFPCI_SUBSYSID_VF_SUBSYS_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_SUBSYSID_VF_SUBSYS_ID_SHIFT)
-#define I40E_PFPCI_VF_FLUSH_DONE 0x0000E400 /* Reset: PCIR */
-#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_VF_FLUSH_DONE1(_VF) (0x0009C600 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: PCIR */
-#define I40E_PFPCI_VF_FLUSH_DONE1_MAX_INDEX 127
-#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_VM_FLUSH_DONE 0x0009C880 /* Reset: PCIR */
-#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_VMINDEX 0x0009C300 /* Reset: PCIR */
-#define I40E_PFPCI_VMINDEX_VMINDEX_SHIFT 0
-#define I40E_PFPCI_VMINDEX_VMINDEX_MASK I40E_MASK(0x1FF, I40E_PFPCI_VMINDEX_VMINDEX_SHIFT)
-#define I40E_PFPCI_VMPEND 0x0009C380 /* Reset: PCIR */
-#define I40E_PFPCI_VMPEND_PENDING_SHIFT 0
-#define I40E_PFPCI_VMPEND_PENDING_MASK I40E_MASK(0x1, I40E_PFPCI_VMPEND_PENDING_SHIFT)
#define I40E_PRTPM_EEE_STAT 0x001E4320 /* Reset: GLOBR */
-#define I40E_PRTPM_EEE_STAT_EEE_NEG_SHIFT 29
-#define I40E_PRTPM_EEE_STAT_EEE_NEG_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_EEE_NEG_SHIFT)
#define I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT 30
#define I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT)
#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT 31
#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT)
-#define I40E_PRTPM_EEEC 0x001E4380 /* Reset: GLOBR */
-#define I40E_PRTPM_EEEC_TW_WAKE_MIN_SHIFT 16
-#define I40E_PRTPM_EEEC_TW_WAKE_MIN_MASK I40E_MASK(0x3F, I40E_PRTPM_EEEC_TW_WAKE_MIN_SHIFT)
-#define I40E_PRTPM_EEEC_TX_LU_LPI_DLY_SHIFT 24
-#define I40E_PRTPM_EEEC_TX_LU_LPI_DLY_MASK I40E_MASK(0x3, I40E_PRTPM_EEEC_TX_LU_LPI_DLY_SHIFT)
-#define I40E_PRTPM_EEEC_TEEE_DLY_SHIFT 26
-#define I40E_PRTPM_EEEC_TEEE_DLY_MASK I40E_MASK(0x3F, I40E_PRTPM_EEEC_TEEE_DLY_SHIFT)
-#define I40E_PRTPM_EEEFWD 0x001E4400 /* Reset: GLOBR */
-#define I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_SHIFT 31
-#define I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_MASK I40E_MASK(0x1, I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_SHIFT)
-#define I40E_PRTPM_EEER 0x001E4360 /* Reset: GLOBR */
-#define I40E_PRTPM_EEER_TW_SYSTEM_SHIFT 0
-#define I40E_PRTPM_EEER_TW_SYSTEM_MASK I40E_MASK(0xFFFF, I40E_PRTPM_EEER_TW_SYSTEM_SHIFT)
-#define I40E_PRTPM_EEER_TX_LPI_EN_SHIFT 16
-#define I40E_PRTPM_EEER_TX_LPI_EN_MASK I40E_MASK(0x1, I40E_PRTPM_EEER_TX_LPI_EN_SHIFT)
-#define I40E_PRTPM_EEETXC 0x001E43E0 /* Reset: GLOBR */
-#define I40E_PRTPM_EEETXC_TW_PHY_SHIFT 0
-#define I40E_PRTPM_EEETXC_TW_PHY_MASK I40E_MASK(0xFFFF, I40E_PRTPM_EEETXC_TW_PHY_SHIFT)
-#define I40E_PRTPM_GC 0x000B8140 /* Reset: POR */
-#define I40E_PRTPM_GC_EMP_LINK_ON_SHIFT 0
-#define I40E_PRTPM_GC_EMP_LINK_ON_MASK I40E_MASK(0x1, I40E_PRTPM_GC_EMP_LINK_ON_SHIFT)
-#define I40E_PRTPM_GC_MNG_VETO_SHIFT 1
-#define I40E_PRTPM_GC_MNG_VETO_MASK I40E_MASK(0x1, I40E_PRTPM_GC_MNG_VETO_SHIFT)
-#define I40E_PRTPM_GC_RATD_SHIFT 2
-#define I40E_PRTPM_GC_RATD_MASK I40E_MASK(0x1, I40E_PRTPM_GC_RATD_SHIFT)
-#define I40E_PRTPM_GC_LCDMP_SHIFT 3
-#define I40E_PRTPM_GC_LCDMP_MASK I40E_MASK(0x1, I40E_PRTPM_GC_LCDMP_SHIFT)
-#define I40E_PRTPM_GC_LPLU_ASSERTED_SHIFT 31
-#define I40E_PRTPM_GC_LPLU_ASSERTED_MASK I40E_MASK(0x1, I40E_PRTPM_GC_LPLU_ASSERTED_SHIFT)
#define I40E_PRTPM_RLPIC 0x001E43A0 /* Reset: GLOBR */
-#define I40E_PRTPM_RLPIC_ERLPIC_SHIFT 0
-#define I40E_PRTPM_RLPIC_ERLPIC_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_RLPIC_ERLPIC_SHIFT)
#define I40E_PRTPM_TLPIC 0x001E43C0 /* Reset: GLOBR */
-#define I40E_PRTPM_TLPIC_ETLPIC_SHIFT 0
-#define I40E_PRTPM_TLPIC_ETLPIC_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_TLPIC_ETLPIC_SHIFT)
-#define I40E_GL_PRS_FVBM(_i) (0x00269760 + ((_i) * 4)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GL_PRS_FVBM_MAX_INDEX 3
-#define I40E_GL_PRS_FVBM_FV_BYTE_INDX_SHIFT 0
-#define I40E_GL_PRS_FVBM_FV_BYTE_INDX_MASK I40E_MASK(0x7F, I40E_GL_PRS_FVBM_FV_BYTE_INDX_SHIFT)
-#define I40E_GL_PRS_FVBM_RULE_BUS_INDX_SHIFT 8
-#define I40E_GL_PRS_FVBM_RULE_BUS_INDX_MASK I40E_MASK(0x3F, I40E_GL_PRS_FVBM_RULE_BUS_INDX_SHIFT)
-#define I40E_GL_PRS_FVBM_MSK_ENA_SHIFT 31
-#define I40E_GL_PRS_FVBM_MSK_ENA_MASK I40E_MASK(0x1, I40E_GL_PRS_FVBM_MSK_ENA_SHIFT)
-#define I40E_GLRPB_DPSS 0x000AC828 /* Reset: CORER */
-#define I40E_GLRPB_DPSS_DPS_TCN_SHIFT 0
-#define I40E_GLRPB_DPSS_DPS_TCN_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_DPSS_DPS_TCN_SHIFT)
-#define I40E_GLRPB_GHW 0x000AC830 /* Reset: CORER */
-#define I40E_GLRPB_GHW_GHW_SHIFT 0
-#define I40E_GLRPB_GHW_GHW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_GHW_GHW_SHIFT)
-#define I40E_GLRPB_GLW 0x000AC834 /* Reset: CORER */
-#define I40E_GLRPB_GLW_GLW_SHIFT 0
-#define I40E_GLRPB_GLW_GLW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_GLW_GLW_SHIFT)
-#define I40E_GLRPB_PHW 0x000AC844 /* Reset: CORER */
-#define I40E_GLRPB_PHW_PHW_SHIFT 0
-#define I40E_GLRPB_PHW_PHW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_PHW_PHW_SHIFT)
-#define I40E_GLRPB_PLW 0x000AC848 /* Reset: CORER */
-#define I40E_GLRPB_PLW_PLW_SHIFT 0
-#define I40E_GLRPB_PLW_PLW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_PLW_PLW_SHIFT)
-#define I40E_PRTRPB_DHW(_i) (0x000AC100 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTRPB_DHW_MAX_INDEX 7
-#define I40E_PRTRPB_DHW_DHW_TCN_SHIFT 0
-#define I40E_PRTRPB_DHW_DHW_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_DHW_DHW_TCN_SHIFT)
-#define I40E_PRTRPB_DLW(_i) (0x000AC220 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTRPB_DLW_MAX_INDEX 7
-#define I40E_PRTRPB_DLW_DLW_TCN_SHIFT 0
-#define I40E_PRTRPB_DLW_DLW_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_DLW_DLW_TCN_SHIFT)
-#define I40E_PRTRPB_DPS(_i) (0x000AC320 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTRPB_DPS_MAX_INDEX 7
-#define I40E_PRTRPB_DPS_DPS_TCN_SHIFT 0
-#define I40E_PRTRPB_DPS_DPS_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_DPS_DPS_TCN_SHIFT)
-#define I40E_PRTRPB_SHT(_i) (0x000AC480 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTRPB_SHT_MAX_INDEX 7
-#define I40E_PRTRPB_SHT_SHT_TCN_SHIFT 0
-#define I40E_PRTRPB_SHT_SHT_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SHT_SHT_TCN_SHIFT)
-#define I40E_PRTRPB_SHW 0x000AC580 /* Reset: CORER */
-#define I40E_PRTRPB_SHW_SHW_SHIFT 0
-#define I40E_PRTRPB_SHW_SHW_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SHW_SHW_SHIFT)
-#define I40E_PRTRPB_SLT(_i) (0x000AC5A0 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTRPB_SLT_MAX_INDEX 7
-#define I40E_PRTRPB_SLT_SLT_TCN_SHIFT 0
-#define I40E_PRTRPB_SLT_SLT_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SLT_SLT_TCN_SHIFT)
-#define I40E_PRTRPB_SLW 0x000AC6A0 /* Reset: CORER */
-#define I40E_PRTRPB_SLW_SLW_SHIFT 0
-#define I40E_PRTRPB_SLW_SLW_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SLW_SLW_SHIFT)
-#define I40E_PRTRPB_SPS 0x000AC7C0 /* Reset: CORER */
-#define I40E_PRTRPB_SPS_SPS_SHIFT 0
-#define I40E_PRTRPB_SPS_SPS_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SPS_SPS_SHIFT)
-#define I40E_GLQF_CTL 0x00269BA4 /* Reset: CORER */
-#define I40E_GLQF_CTL_HTOEP_SHIFT 1
-#define I40E_GLQF_CTL_HTOEP_MASK I40E_MASK(0x1, I40E_GLQF_CTL_HTOEP_SHIFT)
-#define I40E_GLQF_CTL_HTOEP_FCOE_SHIFT 2
-#define I40E_GLQF_CTL_HTOEP_FCOE_MASK I40E_MASK(0x1, I40E_GLQF_CTL_HTOEP_FCOE_SHIFT)
-#define I40E_GLQF_CTL_PCNT_ALLOC_SHIFT 3
-#define I40E_GLQF_CTL_PCNT_ALLOC_MASK I40E_MASK(0x7, I40E_GLQF_CTL_PCNT_ALLOC_SHIFT)
-#define I40E_GLQF_CTL_FD_AUTO_PCTYPE_SHIFT 6
-#define I40E_GLQF_CTL_FD_AUTO_PCTYPE_MASK I40E_MASK(0x1, I40E_GLQF_CTL_FD_AUTO_PCTYPE_SHIFT)
-#define I40E_GLQF_CTL_RSVD_SHIFT 7
-#define I40E_GLQF_CTL_RSVD_MASK I40E_MASK(0x1, I40E_GLQF_CTL_RSVD_SHIFT)
-#define I40E_GLQF_CTL_MAXPEBLEN_SHIFT 8
-#define I40E_GLQF_CTL_MAXPEBLEN_MASK I40E_MASK(0x7, I40E_GLQF_CTL_MAXPEBLEN_SHIFT)
-#define I40E_GLQF_CTL_MAXFCBLEN_SHIFT 11
-#define I40E_GLQF_CTL_MAXFCBLEN_MASK I40E_MASK(0x7, I40E_GLQF_CTL_MAXFCBLEN_SHIFT)
-#define I40E_GLQF_CTL_MAXFDBLEN_SHIFT 14
-#define I40E_GLQF_CTL_MAXFDBLEN_MASK I40E_MASK(0x7, I40E_GLQF_CTL_MAXFDBLEN_SHIFT)
-#define I40E_GLQF_CTL_FDBEST_SHIFT 17
-#define I40E_GLQF_CTL_FDBEST_MASK I40E_MASK(0xFF, I40E_GLQF_CTL_FDBEST_SHIFT)
-#define I40E_GLQF_CTL_PROGPRIO_SHIFT 25
-#define I40E_GLQF_CTL_PROGPRIO_MASK I40E_MASK(0x1, I40E_GLQF_CTL_PROGPRIO_SHIFT)
-#define I40E_GLQF_CTL_INVALPRIO_SHIFT 26
-#define I40E_GLQF_CTL_INVALPRIO_MASK I40E_MASK(0x1, I40E_GLQF_CTL_INVALPRIO_SHIFT)
-#define I40E_GLQF_CTL_IGNORE_IP_SHIFT 27
-#define I40E_GLQF_CTL_IGNORE_IP_MASK I40E_MASK(0x1, I40E_GLQF_CTL_IGNORE_IP_SHIFT)
#define I40E_GLQF_FDCNT_0 0x00269BAC /* Reset: CORER */
#define I40E_GLQF_FDCNT_0_GUARANT_CNT_SHIFT 0
#define I40E_GLQF_FDCNT_0_GUARANT_CNT_MASK I40E_MASK(0x1FFF, I40E_GLQF_FDCNT_0_GUARANT_CNT_SHIFT)
@@ -2112,36 +407,7 @@
#define I40E_GLQF_FDCNT_0_BESTCNT_MASK I40E_MASK(0x1FFF, I40E_GLQF_FDCNT_0_BESTCNT_SHIFT)
#define I40E_GLQF_HKEY(_i) (0x00270140 + ((_i) * 4)) /* _i=0...12 */ /* Reset: CORER */
#define I40E_GLQF_HKEY_MAX_INDEX 12
-#define I40E_GLQF_HKEY_KEY_0_SHIFT 0
-#define I40E_GLQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_0_SHIFT)
-#define I40E_GLQF_HKEY_KEY_1_SHIFT 8
-#define I40E_GLQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_1_SHIFT)
-#define I40E_GLQF_HKEY_KEY_2_SHIFT 16
-#define I40E_GLQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_2_SHIFT)
-#define I40E_GLQF_HKEY_KEY_3_SHIFT 24
-#define I40E_GLQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_3_SHIFT)
-#define I40E_GLQF_HSYM(_i) (0x00269D00 + ((_i) * 4)) /* _i=0...63 */ /* Reset: CORER */
-#define I40E_GLQF_HSYM_MAX_INDEX 63
-#define I40E_GLQF_HSYM_SYMH_ENA_SHIFT 0
-#define I40E_GLQF_HSYM_SYMH_ENA_MASK I40E_MASK(0x1, I40E_GLQF_HSYM_SYMH_ENA_SHIFT)
#define I40E_GLQF_PCNT(_i) (0x00266800 + ((_i) * 4)) /* _i=0...511 */ /* Reset: CORER */
-#define I40E_GLQF_PCNT_MAX_INDEX 511
-#define I40E_GLQF_PCNT_PCNT_SHIFT 0
-#define I40E_GLQF_PCNT_PCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLQF_PCNT_PCNT_SHIFT)
-#define I40E_GLQF_SWAP(_i, _j) (0x00267E00 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */ /* Reset: CORER */
-#define I40E_GLQF_SWAP_MAX_INDEX 1
-#define I40E_GLQF_SWAP_OFF0_SRC0_SHIFT 0
-#define I40E_GLQF_SWAP_OFF0_SRC0_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF0_SRC0_SHIFT)
-#define I40E_GLQF_SWAP_OFF0_SRC1_SHIFT 6
-#define I40E_GLQF_SWAP_OFF0_SRC1_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF0_SRC1_SHIFT)
-#define I40E_GLQF_SWAP_FLEN0_SHIFT 12
-#define I40E_GLQF_SWAP_FLEN0_MASK I40E_MASK(0xF, I40E_GLQF_SWAP_FLEN0_SHIFT)
-#define I40E_GLQF_SWAP_OFF1_SRC0_SHIFT 16
-#define I40E_GLQF_SWAP_OFF1_SRC0_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF1_SRC0_SHIFT)
-#define I40E_GLQF_SWAP_OFF1_SRC1_SHIFT 22
-#define I40E_GLQF_SWAP_OFF1_SRC1_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF1_SRC1_SHIFT)
-#define I40E_GLQF_SWAP_FLEN1_SHIFT 28
-#define I40E_GLQF_SWAP_FLEN1_MASK I40E_MASK(0xF, I40E_GLQF_SWAP_FLEN1_SHIFT)
#define I40E_PFQF_CTL_0 0x001C0AC0 /* Reset: CORER */
#define I40E_PFQF_CTL_0_PEHSIZE_SHIFT 0
#define I40E_PFQF_CTL_0_PEHSIZE_MASK I40E_MASK(0x1F, I40E_PFQF_CTL_0_PEHSIZE_SHIFT)
@@ -2159,54 +425,19 @@
#define I40E_PFQF_CTL_0_ETYPE_ENA_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_ETYPE_ENA_SHIFT)
#define I40E_PFQF_CTL_0_MACVLAN_ENA_SHIFT 19
#define I40E_PFQF_CTL_0_MACVLAN_ENA_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_MACVLAN_ENA_SHIFT)
-#define I40E_PFQF_CTL_0_VFFCHSIZE_SHIFT 20
-#define I40E_PFQF_CTL_0_VFFCHSIZE_MASK I40E_MASK(0xF, I40E_PFQF_CTL_0_VFFCHSIZE_SHIFT)
-#define I40E_PFQF_CTL_0_VFFCDSIZE_SHIFT 24
-#define I40E_PFQF_CTL_0_VFFCDSIZE_MASK I40E_MASK(0x3, I40E_PFQF_CTL_0_VFFCDSIZE_SHIFT)
#define I40E_PFQF_CTL_1 0x00245D80 /* Reset: CORER */
#define I40E_PFQF_CTL_1_CLEARFDTABLE_SHIFT 0
#define I40E_PFQF_CTL_1_CLEARFDTABLE_MASK I40E_MASK(0x1, I40E_PFQF_CTL_1_CLEARFDTABLE_SHIFT)
-#define I40E_PFQF_FDALLOC 0x00246280 /* Reset: CORER */
-#define I40E_PFQF_FDALLOC_FDALLOC_SHIFT 0
-#define I40E_PFQF_FDALLOC_FDALLOC_MASK I40E_MASK(0xFF, I40E_PFQF_FDALLOC_FDALLOC_SHIFT)
-#define I40E_PFQF_FDALLOC_FDBEST_SHIFT 8
-#define I40E_PFQF_FDALLOC_FDBEST_MASK I40E_MASK(0xFF, I40E_PFQF_FDALLOC_FDBEST_SHIFT)
#define I40E_PFQF_FDSTAT 0x00246380 /* Reset: CORER */
#define I40E_PFQF_FDSTAT_GUARANT_CNT_SHIFT 0
#define I40E_PFQF_FDSTAT_GUARANT_CNT_MASK I40E_MASK(0x1FFF, I40E_PFQF_FDSTAT_GUARANT_CNT_SHIFT)
#define I40E_PFQF_FDSTAT_BEST_CNT_SHIFT 16
#define I40E_PFQF_FDSTAT_BEST_CNT_MASK I40E_MASK(0x1FFF, I40E_PFQF_FDSTAT_BEST_CNT_SHIFT)
#define I40E_PFQF_HENA(_i) (0x00245900 + ((_i) * 128)) /* _i=0...1 */ /* Reset: CORER */
-#define I40E_PFQF_HENA_MAX_INDEX 1
-#define I40E_PFQF_HENA_PTYPE_ENA_SHIFT 0
-#define I40E_PFQF_HENA_PTYPE_ENA_MASK I40E_MASK(0xFFFFFFFF, I40E_PFQF_HENA_PTYPE_ENA_SHIFT)
#define I40E_PFQF_HKEY(_i) (0x00244800 + ((_i) * 128)) /* _i=0...12 */ /* Reset: CORER */
#define I40E_PFQF_HKEY_MAX_INDEX 12
-#define I40E_PFQF_HKEY_KEY_0_SHIFT 0
-#define I40E_PFQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_0_SHIFT)
-#define I40E_PFQF_HKEY_KEY_1_SHIFT 8
-#define I40E_PFQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_1_SHIFT)
-#define I40E_PFQF_HKEY_KEY_2_SHIFT 16
-#define I40E_PFQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_2_SHIFT)
-#define I40E_PFQF_HKEY_KEY_3_SHIFT 24
-#define I40E_PFQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_3_SHIFT)
#define I40E_PFQF_HLUT(_i) (0x00240000 + ((_i) * 128)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_PFQF_HLUT_MAX_INDEX 127
-#define I40E_PFQF_HLUT_LUT0_SHIFT 0
-#define I40E_PFQF_HLUT_LUT0_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT0_SHIFT)
-#define I40E_PFQF_HLUT_LUT1_SHIFT 8
-#define I40E_PFQF_HLUT_LUT1_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT1_SHIFT)
-#define I40E_PFQF_HLUT_LUT2_SHIFT 16
-#define I40E_PFQF_HLUT_LUT2_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT2_SHIFT)
-#define I40E_PFQF_HLUT_LUT3_SHIFT 24
-#define I40E_PFQF_HLUT_LUT3_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT3_SHIFT)
-#define I40E_PRTQF_CTL_0 0x00256E60 /* Reset: CORER */
-#define I40E_PRTQF_CTL_0_HSYM_ENA_SHIFT 0
-#define I40E_PRTQF_CTL_0_HSYM_ENA_MASK I40E_MASK(0x1, I40E_PRTQF_CTL_0_HSYM_ENA_SHIFT)
-#define I40E_PRTQF_FD_FLXINSET(_i) (0x00253800 + ((_i) * 32)) /* _i=0...63 */ /* Reset: CORER */
-#define I40E_PRTQF_FD_FLXINSET_MAX_INDEX 63
-#define I40E_PRTQF_FD_FLXINSET_INSET_SHIFT 0
-#define I40E_PRTQF_FD_FLXINSET_INSET_MASK I40E_MASK(0xFF, I40E_PRTQF_FD_FLXINSET_INSET_SHIFT)
#define I40E_PRTQF_FD_INSET(_i, _j) (0x00250000 + ((_i) * 64 + (_j) * 32)) /* _i=0...63, _j=0...1 */ /* Reset: CORER */
#define I40E_PRTQF_FD_INSET_MAX_INDEX 63
#define I40E_PRTQF_FD_INSET_INSET_SHIFT 0
@@ -2215,14 +446,7 @@
#define I40E_PRTQF_FD_INSET_MAX_INDEX 63
#define I40E_PRTQF_FD_INSET_INSET_SHIFT 0
#define I40E_PRTQF_FD_INSET_INSET_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTQF_FD_INSET_INSET_SHIFT)
-#define I40E_PRTQF_FD_MSK(_i, _j) (0x00252000 + ((_i) * 64 + (_j) * 32)) /* _i=0...63, _j=0...1 */ /* Reset: CORER */
-#define I40E_PRTQF_FD_MSK_MAX_INDEX 63
-#define I40E_PRTQF_FD_MSK_MASK_SHIFT 0
-#define I40E_PRTQF_FD_MSK_MASK_MASK I40E_MASK(0xFFFF, I40E_PRTQF_FD_MSK_MASK_SHIFT)
-#define I40E_PRTQF_FD_MSK_OFFSET_SHIFT 16
-#define I40E_PRTQF_FD_MSK_OFFSET_MASK I40E_MASK(0x3F, I40E_PRTQF_FD_MSK_OFFSET_SHIFT)
#define I40E_PRTQF_FLX_PIT(_i) (0x00255200 + ((_i) * 32)) /* _i=0...8 */ /* Reset: CORER */
-#define I40E_PRTQF_FLX_PIT_MAX_INDEX 8
#define I40E_PRTQF_FLX_PIT_SOURCE_OFF_SHIFT 0
#define I40E_PRTQF_FLX_PIT_SOURCE_OFF_MASK I40E_MASK(0x1F, I40E_PRTQF_FLX_PIT_SOURCE_OFF_SHIFT)
#define I40E_PRTQF_FLX_PIT_FSIZE_SHIFT 5
@@ -2230,775 +454,148 @@
#define I40E_PRTQF_FLX_PIT_DEST_OFF_SHIFT 10
#define I40E_PRTQF_FLX_PIT_DEST_OFF_MASK I40E_MASK(0x3F, I40E_PRTQF_FLX_PIT_DEST_OFF_SHIFT)
#define I40E_VFQF_HENA1(_i, _VF) (0x00230800 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...1, _VF=0...127 */ /* Reset: CORER */
-#define I40E_VFQF_HENA1_MAX_INDEX 1
-#define I40E_VFQF_HENA1_PTYPE_ENA_SHIFT 0
-#define I40E_VFQF_HENA1_PTYPE_ENA_MASK I40E_MASK(0xFFFFFFFF, I40E_VFQF_HENA1_PTYPE_ENA_SHIFT)
#define I40E_VFQF_HKEY1(_i, _VF) (0x00228000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...12, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HKEY1_MAX_INDEX 12
-#define I40E_VFQF_HKEY1_KEY_0_SHIFT 0
-#define I40E_VFQF_HKEY1_KEY_0_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_0_SHIFT)
-#define I40E_VFQF_HKEY1_KEY_1_SHIFT 8
-#define I40E_VFQF_HKEY1_KEY_1_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_1_SHIFT)
-#define I40E_VFQF_HKEY1_KEY_2_SHIFT 16
-#define I40E_VFQF_HKEY1_KEY_2_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_2_SHIFT)
-#define I40E_VFQF_HKEY1_KEY_3_SHIFT 24
-#define I40E_VFQF_HKEY1_KEY_3_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_3_SHIFT)
#define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HLUT1_MAX_INDEX 15
-#define I40E_VFQF_HLUT1_LUT0_SHIFT 0
-#define I40E_VFQF_HLUT1_LUT0_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT0_SHIFT)
-#define I40E_VFQF_HLUT1_LUT1_SHIFT 8
-#define I40E_VFQF_HLUT1_LUT1_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT1_SHIFT)
-#define I40E_VFQF_HLUT1_LUT2_SHIFT 16
-#define I40E_VFQF_HLUT1_LUT2_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT2_SHIFT)
-#define I40E_VFQF_HLUT1_LUT3_SHIFT 24
-#define I40E_VFQF_HLUT1_LUT3_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT3_SHIFT)
-#define I40E_VFQF_HREGION1(_i, _VF) (0x0022E000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...7, _VF=0...127 */ /* Reset: CORER */
-#define I40E_VFQF_HREGION1_MAX_INDEX 7
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_0_SHIFT 0
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_0_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_0_SHIFT)
-#define I40E_VFQF_HREGION1_REGION_0_SHIFT 1
-#define I40E_VFQF_HREGION1_REGION_0_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_0_SHIFT)
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_1_SHIFT 4
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_1_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_1_SHIFT)
-#define I40E_VFQF_HREGION1_REGION_1_SHIFT 5
-#define I40E_VFQF_HREGION1_REGION_1_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_1_SHIFT)
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_2_SHIFT 8
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_2_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_2_SHIFT)
-#define I40E_VFQF_HREGION1_REGION_2_SHIFT 9
-#define I40E_VFQF_HREGION1_REGION_2_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_2_SHIFT)
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_3_SHIFT 12
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_3_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_3_SHIFT)
-#define I40E_VFQF_HREGION1_REGION_3_SHIFT 13
-#define I40E_VFQF_HREGION1_REGION_3_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_3_SHIFT)
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_4_SHIFT 16
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_4_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_4_SHIFT)
-#define I40E_VFQF_HREGION1_REGION_4_SHIFT 17
-#define I40E_VFQF_HREGION1_REGION_4_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_4_SHIFT)
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_5_SHIFT 20
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_5_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_5_SHIFT)
-#define I40E_VFQF_HREGION1_REGION_5_SHIFT 21
-#define I40E_VFQF_HREGION1_REGION_5_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_5_SHIFT)
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_6_SHIFT 24
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_6_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_6_SHIFT)
-#define I40E_VFQF_HREGION1_REGION_6_SHIFT 25
-#define I40E_VFQF_HREGION1_REGION_6_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_6_SHIFT)
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_7_SHIFT 28
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_7_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_7_SHIFT)
-#define I40E_VFQF_HREGION1_REGION_7_SHIFT 29
-#define I40E_VFQF_HREGION1_REGION_7_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_7_SHIFT)
-#define I40E_VPQF_CTL(_VF) (0x001C0000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VPQF_CTL_MAX_INDEX 127
-#define I40E_VPQF_CTL_PEHSIZE_SHIFT 0
-#define I40E_VPQF_CTL_PEHSIZE_MASK I40E_MASK(0x1F, I40E_VPQF_CTL_PEHSIZE_SHIFT)
-#define I40E_VPQF_CTL_PEDSIZE_SHIFT 5
-#define I40E_VPQF_CTL_PEDSIZE_MASK I40E_MASK(0x1F, I40E_VPQF_CTL_PEDSIZE_SHIFT)
-#define I40E_VPQF_CTL_FCHSIZE_SHIFT 10
-#define I40E_VPQF_CTL_FCHSIZE_MASK I40E_MASK(0xF, I40E_VPQF_CTL_FCHSIZE_SHIFT)
-#define I40E_VPQF_CTL_FCDSIZE_SHIFT 14
-#define I40E_VPQF_CTL_FCDSIZE_MASK I40E_MASK(0x3, I40E_VPQF_CTL_FCDSIZE_SHIFT)
-#define I40E_VSIQF_CTL(_VSI) (0x0020D800 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: PFR */
-#define I40E_VSIQF_CTL_MAX_INDEX 383
-#define I40E_VSIQF_CTL_FCOE_ENA_SHIFT 0
-#define I40E_VSIQF_CTL_FCOE_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_FCOE_ENA_SHIFT)
-#define I40E_VSIQF_CTL_PETCP_ENA_SHIFT 1
-#define I40E_VSIQF_CTL_PETCP_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PETCP_ENA_SHIFT)
-#define I40E_VSIQF_CTL_PEUUDP_ENA_SHIFT 2
-#define I40E_VSIQF_CTL_PEUUDP_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEUUDP_ENA_SHIFT)
-#define I40E_VSIQF_CTL_PEMUDP_ENA_SHIFT 3
-#define I40E_VSIQF_CTL_PEMUDP_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEMUDP_ENA_SHIFT)
-#define I40E_VSIQF_CTL_PEUFRAG_ENA_SHIFT 4
-#define I40E_VSIQF_CTL_PEUFRAG_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEUFRAG_ENA_SHIFT)
-#define I40E_VSIQF_CTL_PEMFRAG_ENA_SHIFT 5
-#define I40E_VSIQF_CTL_PEMFRAG_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEMFRAG_ENA_SHIFT)
-#define I40E_VSIQF_TCREGION(_i, _VSI) (0x00206000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...3, _VSI=0...383 */ /* Reset: PFR */
-#define I40E_VSIQF_TCREGION_MAX_INDEX 3
-#define I40E_VSIQF_TCREGION_TC_OFFSET_SHIFT 0
-#define I40E_VSIQF_TCREGION_TC_OFFSET_MASK I40E_MASK(0x1FF, I40E_VSIQF_TCREGION_TC_OFFSET_SHIFT)
-#define I40E_VSIQF_TCREGION_TC_SIZE_SHIFT 9
-#define I40E_VSIQF_TCREGION_TC_SIZE_MASK I40E_MASK(0x7, I40E_VSIQF_TCREGION_TC_SIZE_SHIFT)
-#define I40E_VSIQF_TCREGION_TC_OFFSET2_SHIFT 16
-#define I40E_VSIQF_TCREGION_TC_OFFSET2_MASK I40E_MASK(0x1FF, I40E_VSIQF_TCREGION_TC_OFFSET2_SHIFT)
-#define I40E_VSIQF_TCREGION_TC_SIZE2_SHIFT 25
-#define I40E_VSIQF_TCREGION_TC_SIZE2_MASK I40E_MASK(0x7, I40E_VSIQF_TCREGION_TC_SIZE2_SHIFT)
-#define I40E_GL_FCOECRC(_i) (0x00314d80 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOECRC_MAX_INDEX 143
-#define I40E_GL_FCOECRC_FCOECRC_SHIFT 0
-#define I40E_GL_FCOECRC_FCOECRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOECRC_FCOECRC_SHIFT)
-#define I40E_GL_FCOEDDPC(_i) (0x00314480 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEDDPC_MAX_INDEX 143
-#define I40E_GL_FCOEDDPC_FCOEDDPC_SHIFT 0
-#define I40E_GL_FCOEDDPC_FCOEDDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDDPC_FCOEDDPC_SHIFT)
-#define I40E_GL_FCOEDIFEC(_i) (0x00318480 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEDIFEC_MAX_INDEX 143
-#define I40E_GL_FCOEDIFEC_FCOEDIFRC_SHIFT 0
-#define I40E_GL_FCOEDIFEC_FCOEDIFRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIFEC_FCOEDIFRC_SHIFT)
-#define I40E_GL_FCOEDIFTCL(_i) (0x00354000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEDIFTCL_MAX_INDEX 143
-#define I40E_GL_FCOEDIFTCL_FCOEDIFTC_SHIFT 0
-#define I40E_GL_FCOEDIFTCL_FCOEDIFTC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIFTCL_FCOEDIFTC_SHIFT)
-#define I40E_GL_FCOEDIXEC(_i) (0x0034c000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEDIXEC_MAX_INDEX 143
-#define I40E_GL_FCOEDIXEC_FCOEDIXEC_SHIFT 0
-#define I40E_GL_FCOEDIXEC_FCOEDIXEC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIXEC_FCOEDIXEC_SHIFT)
-#define I40E_GL_FCOEDIXVC(_i) (0x00350000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEDIXVC_MAX_INDEX 143
-#define I40E_GL_FCOEDIXVC_FCOEDIXVC_SHIFT 0
-#define I40E_GL_FCOEDIXVC_FCOEDIXVC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIXVC_FCOEDIXVC_SHIFT)
-#define I40E_GL_FCOEDWRCH(_i) (0x00320004 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEDWRCH_MAX_INDEX 143
-#define I40E_GL_FCOEDWRCH_FCOEDWRCH_SHIFT 0
-#define I40E_GL_FCOEDWRCH_FCOEDWRCH_MASK I40E_MASK(0xFFFF, I40E_GL_FCOEDWRCH_FCOEDWRCH_SHIFT)
-#define I40E_GL_FCOEDWRCL(_i) (0x00320000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEDWRCL_MAX_INDEX 143
-#define I40E_GL_FCOEDWRCL_FCOEDWRCL_SHIFT 0
-#define I40E_GL_FCOEDWRCL_FCOEDWRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDWRCL_FCOEDWRCL_SHIFT)
-#define I40E_GL_FCOEDWTCH(_i) (0x00348084 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEDWTCH_MAX_INDEX 143
-#define I40E_GL_FCOEDWTCH_FCOEDWTCH_SHIFT 0
-#define I40E_GL_FCOEDWTCH_FCOEDWTCH_MASK I40E_MASK(0xFFFF, I40E_GL_FCOEDWTCH_FCOEDWTCH_SHIFT)
-#define I40E_GL_FCOEDWTCL(_i) (0x00348080 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEDWTCL_MAX_INDEX 143
-#define I40E_GL_FCOEDWTCL_FCOEDWTCL_SHIFT 0
-#define I40E_GL_FCOEDWTCL_FCOEDWTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDWTCL_FCOEDWTCL_SHIFT)
-#define I40E_GL_FCOELAST(_i) (0x00314000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOELAST_MAX_INDEX 143
-#define I40E_GL_FCOELAST_FCOELAST_SHIFT 0
-#define I40E_GL_FCOELAST_FCOELAST_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOELAST_FCOELAST_SHIFT)
-#define I40E_GL_FCOEPRC(_i) (0x00315200 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEPRC_MAX_INDEX 143
-#define I40E_GL_FCOEPRC_FCOEPRC_SHIFT 0
-#define I40E_GL_FCOEPRC_FCOEPRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEPRC_FCOEPRC_SHIFT)
-#define I40E_GL_FCOEPTC(_i) (0x00344C00 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOEPTC_MAX_INDEX 143
-#define I40E_GL_FCOEPTC_FCOEPTC_SHIFT 0
-#define I40E_GL_FCOEPTC_FCOEPTC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEPTC_FCOEPTC_SHIFT)
-#define I40E_GL_FCOERPDC(_i) (0x00324000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_FCOERPDC_MAX_INDEX 143
-#define I40E_GL_FCOERPDC_FCOERPDC_SHIFT 0
-#define I40E_GL_FCOERPDC_FCOERPDC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOERPDC_FCOERPDC_SHIFT)
-#define I40E_GL_RXERR1_L(_i) (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_RXERR1_L_MAX_INDEX 143
-#define I40E_GL_RXERR1_L_FCOEDIFRC_SHIFT 0
-#define I40E_GL_RXERR1_L_FCOEDIFRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1_L_FCOEDIFRC_SHIFT)
-#define I40E_GL_RXERR2_L(_i) (0x0031c000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
-#define I40E_GL_RXERR2_L_MAX_INDEX 143
-#define I40E_GL_RXERR2_L_FCOEDIXAC_SHIFT 0
-#define I40E_GL_RXERR2_L_FCOEDIXAC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR2_L_FCOEDIXAC_SHIFT)
#define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_BPRCH_MAX_INDEX 3
-#define I40E_GLPRT_BPRCH_BPRCH_SHIFT 0
-#define I40E_GLPRT_BPRCH_BPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_BPRCH_BPRCH_SHIFT)
#define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_BPRCL_MAX_INDEX 3
-#define I40E_GLPRT_BPRCL_BPRCL_SHIFT 0
-#define I40E_GLPRT_BPRCL_BPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_BPRCL_BPRCL_SHIFT)
#define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_BPTCH_MAX_INDEX 3
-#define I40E_GLPRT_BPTCH_BPTCH_SHIFT 0
-#define I40E_GLPRT_BPTCH_BPTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_BPTCH_BPTCH_SHIFT)
#define I40E_GLPRT_BPTCL(_i) (0x00300A00 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_BPTCL_MAX_INDEX 3
-#define I40E_GLPRT_BPTCL_BPTCL_SHIFT 0
-#define I40E_GLPRT_BPTCL_BPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_BPTCL_BPTCL_SHIFT)
#define I40E_GLPRT_CRCERRS(_i) (0x00300080 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_CRCERRS_MAX_INDEX 3
-#define I40E_GLPRT_CRCERRS_CRCERRS_SHIFT 0
-#define I40E_GLPRT_CRCERRS_CRCERRS_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_CRCERRS_CRCERRS_SHIFT)
#define I40E_GLPRT_GORCH(_i) (0x00300004 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_GORCH_MAX_INDEX 3
-#define I40E_GLPRT_GORCH_GORCH_SHIFT 0
-#define I40E_GLPRT_GORCH_GORCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_GORCH_GORCH_SHIFT)
#define I40E_GLPRT_GORCL(_i) (0x00300000 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_GORCL_MAX_INDEX 3
-#define I40E_GLPRT_GORCL_GORCL_SHIFT 0
-#define I40E_GLPRT_GORCL_GORCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_GORCL_GORCL_SHIFT)
#define I40E_GLPRT_GOTCH(_i) (0x00300684 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_GOTCH_MAX_INDEX 3
-#define I40E_GLPRT_GOTCH_GOTCH_SHIFT 0
-#define I40E_GLPRT_GOTCH_GOTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_GOTCH_GOTCH_SHIFT)
#define I40E_GLPRT_GOTCL(_i) (0x00300680 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_GOTCL_MAX_INDEX 3
-#define I40E_GLPRT_GOTCL_GOTCL_SHIFT 0
-#define I40E_GLPRT_GOTCL_GOTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_GOTCL_GOTCL_SHIFT)
#define I40E_GLPRT_ILLERRC(_i) (0x003000E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_ILLERRC_MAX_INDEX 3
-#define I40E_GLPRT_ILLERRC_ILLERRC_SHIFT 0
-#define I40E_GLPRT_ILLERRC_ILLERRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_ILLERRC_ILLERRC_SHIFT)
-#define I40E_GLPRT_LDPC(_i) (0x00300620 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_LDPC_MAX_INDEX 3
-#define I40E_GLPRT_LDPC_LDPC_SHIFT 0
-#define I40E_GLPRT_LDPC_LDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LDPC_LDPC_SHIFT)
#define I40E_GLPRT_LXOFFRXC(_i) (0x00300160 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_LXOFFRXC_MAX_INDEX 3
-#define I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_SHIFT 0
-#define I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_SHIFT)
#define I40E_GLPRT_LXOFFTXC(_i) (0x003009A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_LXOFFTXC_MAX_INDEX 3
-#define I40E_GLPRT_LXOFFTXC_LXOFFTXC_SHIFT 0
-#define I40E_GLPRT_LXOFFTXC_LXOFFTXC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXOFFTXC_LXOFFTXC_SHIFT)
#define I40E_GLPRT_LXONRXC(_i) (0x00300140 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_LXONRXC_MAX_INDEX 3
-#define I40E_GLPRT_LXONRXC_LXONRXCNT_SHIFT 0
-#define I40E_GLPRT_LXONRXC_LXONRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXONRXC_LXONRXCNT_SHIFT)
#define I40E_GLPRT_LXONTXC(_i) (0x00300980 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_LXONTXC_MAX_INDEX 3
-#define I40E_GLPRT_LXONTXC_LXONTXC_SHIFT 0
-#define I40E_GLPRT_LXONTXC_LXONTXC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXONTXC_LXONTXC_SHIFT)
#define I40E_GLPRT_MLFC(_i) (0x00300020 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_MLFC_MAX_INDEX 3
-#define I40E_GLPRT_MLFC_MLFC_SHIFT 0
-#define I40E_GLPRT_MLFC_MLFC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MLFC_MLFC_SHIFT)
#define I40E_GLPRT_MPRCH(_i) (0x003005C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_MPRCH_MAX_INDEX 3
-#define I40E_GLPRT_MPRCH_MPRCH_SHIFT 0
-#define I40E_GLPRT_MPRCH_MPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_MPRCH_MPRCH_SHIFT)
#define I40E_GLPRT_MPRCL(_i) (0x003005C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_MPRCL_MAX_INDEX 3
-#define I40E_GLPRT_MPRCL_MPRCL_SHIFT 0
-#define I40E_GLPRT_MPRCL_MPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MPRCL_MPRCL_SHIFT)
#define I40E_GLPRT_MPTCH(_i) (0x003009E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_MPTCH_MAX_INDEX 3
-#define I40E_GLPRT_MPTCH_MPTCH_SHIFT 0
-#define I40E_GLPRT_MPTCH_MPTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_MPTCH_MPTCH_SHIFT)
#define I40E_GLPRT_MPTCL(_i) (0x003009E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_MPTCL_MAX_INDEX 3
-#define I40E_GLPRT_MPTCL_MPTCL_SHIFT 0
-#define I40E_GLPRT_MPTCL_MPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MPTCL_MPTCL_SHIFT)
#define I40E_GLPRT_MRFC(_i) (0x00300040 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_MRFC_MAX_INDEX 3
-#define I40E_GLPRT_MRFC_MRFC_SHIFT 0
-#define I40E_GLPRT_MRFC_MRFC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MRFC_MRFC_SHIFT)
#define I40E_GLPRT_PRC1023H(_i) (0x00300504 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC1023H_MAX_INDEX 3
-#define I40E_GLPRT_PRC1023H_PRC1023H_SHIFT 0
-#define I40E_GLPRT_PRC1023H_PRC1023H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC1023H_PRC1023H_SHIFT)
#define I40E_GLPRT_PRC1023L(_i) (0x00300500 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC1023L_MAX_INDEX 3
-#define I40E_GLPRT_PRC1023L_PRC1023L_SHIFT 0
-#define I40E_GLPRT_PRC1023L_PRC1023L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC1023L_PRC1023L_SHIFT)
#define I40E_GLPRT_PRC127H(_i) (0x003004A4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC127H_MAX_INDEX 3
-#define I40E_GLPRT_PRC127H_PRC127H_SHIFT 0
-#define I40E_GLPRT_PRC127H_PRC127H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC127H_PRC127H_SHIFT)
#define I40E_GLPRT_PRC127L(_i) (0x003004A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC127L_MAX_INDEX 3
-#define I40E_GLPRT_PRC127L_PRC127L_SHIFT 0
-#define I40E_GLPRT_PRC127L_PRC127L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC127L_PRC127L_SHIFT)
#define I40E_GLPRT_PRC1522H(_i) (0x00300524 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC1522H_MAX_INDEX 3
-#define I40E_GLPRT_PRC1522H_PRC1522H_SHIFT 0
-#define I40E_GLPRT_PRC1522H_PRC1522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC1522H_PRC1522H_SHIFT)
#define I40E_GLPRT_PRC1522L(_i) (0x00300520 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC1522L_MAX_INDEX 3
-#define I40E_GLPRT_PRC1522L_PRC1522L_SHIFT 0
-#define I40E_GLPRT_PRC1522L_PRC1522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC1522L_PRC1522L_SHIFT)
#define I40E_GLPRT_PRC255H(_i) (0x003004C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC255H_MAX_INDEX 3
-#define I40E_GLPRT_PRC255H_PRTPRC255H_SHIFT 0
-#define I40E_GLPRT_PRC255H_PRTPRC255H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC255H_PRTPRC255H_SHIFT)
#define I40E_GLPRT_PRC255L(_i) (0x003004C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC255L_MAX_INDEX 3
-#define I40E_GLPRT_PRC255L_PRC255L_SHIFT 0
-#define I40E_GLPRT_PRC255L_PRC255L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC255L_PRC255L_SHIFT)
#define I40E_GLPRT_PRC511H(_i) (0x003004E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC511H_MAX_INDEX 3
-#define I40E_GLPRT_PRC511H_PRC511H_SHIFT 0
-#define I40E_GLPRT_PRC511H_PRC511H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC511H_PRC511H_SHIFT)
#define I40E_GLPRT_PRC511L(_i) (0x003004E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC511L_MAX_INDEX 3
-#define I40E_GLPRT_PRC511L_PRC511L_SHIFT 0
-#define I40E_GLPRT_PRC511L_PRC511L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC511L_PRC511L_SHIFT)
#define I40E_GLPRT_PRC64H(_i) (0x00300484 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC64H_MAX_INDEX 3
-#define I40E_GLPRT_PRC64H_PRC64H_SHIFT 0
-#define I40E_GLPRT_PRC64H_PRC64H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC64H_PRC64H_SHIFT)
#define I40E_GLPRT_PRC64L(_i) (0x00300480 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC64L_MAX_INDEX 3
-#define I40E_GLPRT_PRC64L_PRC64L_SHIFT 0
-#define I40E_GLPRT_PRC64L_PRC64L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC64L_PRC64L_SHIFT)
#define I40E_GLPRT_PRC9522H(_i) (0x00300544 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC9522H_MAX_INDEX 3
-#define I40E_GLPRT_PRC9522H_PRC1522H_SHIFT 0
-#define I40E_GLPRT_PRC9522H_PRC1522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC9522H_PRC1522H_SHIFT)
#define I40E_GLPRT_PRC9522L(_i) (0x00300540 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PRC9522L_MAX_INDEX 3
-#define I40E_GLPRT_PRC9522L_PRC1522L_SHIFT 0
-#define I40E_GLPRT_PRC9522L_PRC1522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC9522L_PRC1522L_SHIFT)
#define I40E_GLPRT_PTC1023H(_i) (0x00300724 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC1023H_MAX_INDEX 3
-#define I40E_GLPRT_PTC1023H_PTC1023H_SHIFT 0
-#define I40E_GLPRT_PTC1023H_PTC1023H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC1023H_PTC1023H_SHIFT)
#define I40E_GLPRT_PTC1023L(_i) (0x00300720 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC1023L_MAX_INDEX 3
-#define I40E_GLPRT_PTC1023L_PTC1023L_SHIFT 0
-#define I40E_GLPRT_PTC1023L_PTC1023L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC1023L_PTC1023L_SHIFT)
#define I40E_GLPRT_PTC127H(_i) (0x003006C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC127H_MAX_INDEX 3
-#define I40E_GLPRT_PTC127H_PTC127H_SHIFT 0
-#define I40E_GLPRT_PTC127H_PTC127H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC127H_PTC127H_SHIFT)
#define I40E_GLPRT_PTC127L(_i) (0x003006C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC127L_MAX_INDEX 3
-#define I40E_GLPRT_PTC127L_PTC127L_SHIFT 0
-#define I40E_GLPRT_PTC127L_PTC127L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC127L_PTC127L_SHIFT)
#define I40E_GLPRT_PTC1522H(_i) (0x00300744 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC1522H_MAX_INDEX 3
-#define I40E_GLPRT_PTC1522H_PTC1522H_SHIFT 0
-#define I40E_GLPRT_PTC1522H_PTC1522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC1522H_PTC1522H_SHIFT)
#define I40E_GLPRT_PTC1522L(_i) (0x00300740 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC1522L_MAX_INDEX 3
-#define I40E_GLPRT_PTC1522L_PTC1522L_SHIFT 0
-#define I40E_GLPRT_PTC1522L_PTC1522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC1522L_PTC1522L_SHIFT)
#define I40E_GLPRT_PTC255H(_i) (0x003006E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC255H_MAX_INDEX 3
-#define I40E_GLPRT_PTC255H_PTC255H_SHIFT 0
-#define I40E_GLPRT_PTC255H_PTC255H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC255H_PTC255H_SHIFT)
#define I40E_GLPRT_PTC255L(_i) (0x003006E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC255L_MAX_INDEX 3
-#define I40E_GLPRT_PTC255L_PTC255L_SHIFT 0
-#define I40E_GLPRT_PTC255L_PTC255L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC255L_PTC255L_SHIFT)
#define I40E_GLPRT_PTC511H(_i) (0x00300704 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC511H_MAX_INDEX 3
-#define I40E_GLPRT_PTC511H_PTC511H_SHIFT 0
-#define I40E_GLPRT_PTC511H_PTC511H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC511H_PTC511H_SHIFT)
#define I40E_GLPRT_PTC511L(_i) (0x00300700 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC511L_MAX_INDEX 3
-#define I40E_GLPRT_PTC511L_PTC511L_SHIFT 0
-#define I40E_GLPRT_PTC511L_PTC511L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC511L_PTC511L_SHIFT)
#define I40E_GLPRT_PTC64H(_i) (0x003006A4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC64H_MAX_INDEX 3
-#define I40E_GLPRT_PTC64H_PTC64H_SHIFT 0
-#define I40E_GLPRT_PTC64H_PTC64H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC64H_PTC64H_SHIFT)
#define I40E_GLPRT_PTC64L(_i) (0x003006A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC64L_MAX_INDEX 3
-#define I40E_GLPRT_PTC64L_PTC64L_SHIFT 0
-#define I40E_GLPRT_PTC64L_PTC64L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC64L_PTC64L_SHIFT)
#define I40E_GLPRT_PTC9522H(_i) (0x00300764 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC9522H_MAX_INDEX 3
-#define I40E_GLPRT_PTC9522H_PTC9522H_SHIFT 0
-#define I40E_GLPRT_PTC9522H_PTC9522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC9522H_PTC9522H_SHIFT)
#define I40E_GLPRT_PTC9522L(_i) (0x00300760 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_PTC9522L_MAX_INDEX 3
-#define I40E_GLPRT_PTC9522L_PTC9522L_SHIFT 0
-#define I40E_GLPRT_PTC9522L_PTC9522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC9522L_PTC9522L_SHIFT)
#define I40E_GLPRT_PXOFFRXC(_i, _j) (0x00300280 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
-#define I40E_GLPRT_PXOFFRXC_MAX_INDEX 3
-#define I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_SHIFT 0
-#define I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_SHIFT)
#define I40E_GLPRT_PXOFFTXC(_i, _j) (0x00300880 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
-#define I40E_GLPRT_PXOFFTXC_MAX_INDEX 3
-#define I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_SHIFT 0
-#define I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_SHIFT)
#define I40E_GLPRT_PXONRXC(_i, _j) (0x00300180 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
-#define I40E_GLPRT_PXONRXC_MAX_INDEX 3
-#define I40E_GLPRT_PXONRXC_PRPXONRXCNT_SHIFT 0
-#define I40E_GLPRT_PXONRXC_PRPXONRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXONRXC_PRPXONRXCNT_SHIFT)
#define I40E_GLPRT_PXONTXC(_i, _j) (0x00300780 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
-#define I40E_GLPRT_PXONTXC_MAX_INDEX 3
-#define I40E_GLPRT_PXONTXC_PRPXONTXC_SHIFT 0
-#define I40E_GLPRT_PXONTXC_PRPXONTXC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXONTXC_PRPXONTXC_SHIFT)
#define I40E_GLPRT_RDPC(_i) (0x00300600 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_RDPC_MAX_INDEX 3
-#define I40E_GLPRT_RDPC_RDPC_SHIFT 0
-#define I40E_GLPRT_RDPC_RDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RDPC_RDPC_SHIFT)
#define I40E_GLPRT_RFC(_i) (0x00300560 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_RFC_MAX_INDEX 3
-#define I40E_GLPRT_RFC_RFC_SHIFT 0
-#define I40E_GLPRT_RFC_RFC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RFC_RFC_SHIFT)
#define I40E_GLPRT_RJC(_i) (0x00300580 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_RJC_MAX_INDEX 3
-#define I40E_GLPRT_RJC_RJC_SHIFT 0
-#define I40E_GLPRT_RJC_RJC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RJC_RJC_SHIFT)
#define I40E_GLPRT_RLEC(_i) (0x003000A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_RLEC_MAX_INDEX 3
-#define I40E_GLPRT_RLEC_RLEC_SHIFT 0
-#define I40E_GLPRT_RLEC_RLEC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RLEC_RLEC_SHIFT)
#define I40E_GLPRT_ROC(_i) (0x00300120 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_ROC_MAX_INDEX 3
-#define I40E_GLPRT_ROC_ROC_SHIFT 0
-#define I40E_GLPRT_ROC_ROC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_ROC_ROC_SHIFT)
#define I40E_GLPRT_RUC(_i) (0x00300100 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_RUC_MAX_INDEX 3
-#define I40E_GLPRT_RUC_RUC_SHIFT 0
-#define I40E_GLPRT_RUC_RUC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RUC_RUC_SHIFT)
-#define I40E_GLPRT_RUPP(_i) (0x00300660 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_RUPP_MAX_INDEX 3
-#define I40E_GLPRT_RUPP_RUPP_SHIFT 0
-#define I40E_GLPRT_RUPP_RUPP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RUPP_RUPP_SHIFT)
#define I40E_GLPRT_RXON2OFFCNT(_i, _j) (0x00300380 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
-#define I40E_GLPRT_RXON2OFFCNT_MAX_INDEX 3
-#define I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_SHIFT 0
-#define I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_SHIFT)
#define I40E_GLPRT_TDOLD(_i) (0x00300A20 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_TDOLD_MAX_INDEX 3
-#define I40E_GLPRT_TDOLD_GLPRT_TDOLD_SHIFT 0
-#define I40E_GLPRT_TDOLD_GLPRT_TDOLD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_TDOLD_GLPRT_TDOLD_SHIFT)
#define I40E_GLPRT_UPRCH(_i) (0x003005A4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_UPRCH_MAX_INDEX 3
-#define I40E_GLPRT_UPRCH_UPRCH_SHIFT 0
-#define I40E_GLPRT_UPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_UPRCH_UPRCH_SHIFT)
#define I40E_GLPRT_UPRCL(_i) (0x003005A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_UPRCL_MAX_INDEX 3
-#define I40E_GLPRT_UPRCL_UPRCL_SHIFT 0
-#define I40E_GLPRT_UPRCL_UPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_UPRCL_UPRCL_SHIFT)
#define I40E_GLPRT_UPTCH(_i) (0x003009C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_UPTCH_MAX_INDEX 3
-#define I40E_GLPRT_UPTCH_UPTCH_SHIFT 0
-#define I40E_GLPRT_UPTCH_UPTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_UPTCH_UPTCH_SHIFT)
#define I40E_GLPRT_UPTCL(_i) (0x003009C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_GLPRT_UPTCL_MAX_INDEX 3
-#define I40E_GLPRT_UPTCL_VUPTCH_SHIFT 0
-#define I40E_GLPRT_UPTCL_VUPTCH_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_UPTCL_VUPTCH_SHIFT)
#define I40E_GLSW_BPRCH(_i) (0x00370104 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_BPRCH_MAX_INDEX 15
-#define I40E_GLSW_BPRCH_BPRCH_SHIFT 0
-#define I40E_GLSW_BPRCH_BPRCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_BPRCH_BPRCH_SHIFT)
#define I40E_GLSW_BPRCL(_i) (0x00370100 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_BPRCL_MAX_INDEX 15
-#define I40E_GLSW_BPRCL_BPRCL_SHIFT 0
-#define I40E_GLSW_BPRCL_BPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_BPRCL_BPRCL_SHIFT)
#define I40E_GLSW_BPTCH(_i) (0x00340104 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_BPTCH_MAX_INDEX 15
-#define I40E_GLSW_BPTCH_BPTCH_SHIFT 0
-#define I40E_GLSW_BPTCH_BPTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_BPTCH_BPTCH_SHIFT)
#define I40E_GLSW_BPTCL(_i) (0x00340100 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_BPTCL_MAX_INDEX 15
-#define I40E_GLSW_BPTCL_BPTCL_SHIFT 0
-#define I40E_GLSW_BPTCL_BPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_BPTCL_BPTCL_SHIFT)
#define I40E_GLSW_GORCH(_i) (0x0035C004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_GORCH_MAX_INDEX 15
-#define I40E_GLSW_GORCH_GORCH_SHIFT 0
-#define I40E_GLSW_GORCH_GORCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_GORCH_GORCH_SHIFT)
#define I40E_GLSW_GORCL(_i) (0x0035c000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_GORCL_MAX_INDEX 15
-#define I40E_GLSW_GORCL_GORCL_SHIFT 0
-#define I40E_GLSW_GORCL_GORCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_GORCL_GORCL_SHIFT)
#define I40E_GLSW_GOTCH(_i) (0x0032C004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_GOTCH_MAX_INDEX 15
-#define I40E_GLSW_GOTCH_GOTCH_SHIFT 0
-#define I40E_GLSW_GOTCH_GOTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_GOTCH_GOTCH_SHIFT)
#define I40E_GLSW_GOTCL(_i) (0x0032c000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_GOTCL_MAX_INDEX 15
-#define I40E_GLSW_GOTCL_GOTCL_SHIFT 0
-#define I40E_GLSW_GOTCL_GOTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_GOTCL_GOTCL_SHIFT)
#define I40E_GLSW_MPRCH(_i) (0x00370084 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_MPRCH_MAX_INDEX 15
-#define I40E_GLSW_MPRCH_MPRCH_SHIFT 0
-#define I40E_GLSW_MPRCH_MPRCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_MPRCH_MPRCH_SHIFT)
#define I40E_GLSW_MPRCL(_i) (0x00370080 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_MPRCL_MAX_INDEX 15
-#define I40E_GLSW_MPRCL_MPRCL_SHIFT 0
-#define I40E_GLSW_MPRCL_MPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_MPRCL_MPRCL_SHIFT)
#define I40E_GLSW_MPTCH(_i) (0x00340084 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_MPTCH_MAX_INDEX 15
-#define I40E_GLSW_MPTCH_MPTCH_SHIFT 0
-#define I40E_GLSW_MPTCH_MPTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_MPTCH_MPTCH_SHIFT)
#define I40E_GLSW_MPTCL(_i) (0x00340080 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_MPTCL_MAX_INDEX 15
-#define I40E_GLSW_MPTCL_MPTCL_SHIFT 0
-#define I40E_GLSW_MPTCL_MPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_MPTCL_MPTCL_SHIFT)
#define I40E_GLSW_RUPP(_i) (0x00370180 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_RUPP_MAX_INDEX 15
-#define I40E_GLSW_RUPP_RUPP_SHIFT 0
-#define I40E_GLSW_RUPP_RUPP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_RUPP_RUPP_SHIFT)
#define I40E_GLSW_TDPC(_i) (0x00348000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_TDPC_MAX_INDEX 15
-#define I40E_GLSW_TDPC_TDPC_SHIFT 0
-#define I40E_GLSW_TDPC_TDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_TDPC_TDPC_SHIFT)
#define I40E_GLSW_UPRCH(_i) (0x00370004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_UPRCH_MAX_INDEX 15
-#define I40E_GLSW_UPRCH_UPRCH_SHIFT 0
-#define I40E_GLSW_UPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_UPRCH_UPRCH_SHIFT)
#define I40E_GLSW_UPRCL(_i) (0x00370000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_UPRCL_MAX_INDEX 15
-#define I40E_GLSW_UPRCL_UPRCL_SHIFT 0
-#define I40E_GLSW_UPRCL_UPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_UPRCL_UPRCL_SHIFT)
#define I40E_GLSW_UPTCH(_i) (0x00340004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_UPTCH_MAX_INDEX 15
-#define I40E_GLSW_UPTCH_UPTCH_SHIFT 0
-#define I40E_GLSW_UPTCH_UPTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_UPTCH_UPTCH_SHIFT)
#define I40E_GLSW_UPTCL(_i) (0x00340000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLSW_UPTCL_MAX_INDEX 15
-#define I40E_GLSW_UPTCL_UPTCL_SHIFT 0
-#define I40E_GLSW_UPTCL_UPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_UPTCL_UPTCL_SHIFT)
#define I40E_GLV_BPRCH(_i) (0x0036D804 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_BPRCH_MAX_INDEX 383
-#define I40E_GLV_BPRCH_BPRCH_SHIFT 0
-#define I40E_GLV_BPRCH_BPRCH_MASK I40E_MASK(0xFFFF, I40E_GLV_BPRCH_BPRCH_SHIFT)
#define I40E_GLV_BPRCL(_i) (0x0036d800 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_BPRCL_MAX_INDEX 383
-#define I40E_GLV_BPRCL_BPRCL_SHIFT 0
-#define I40E_GLV_BPRCL_BPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_BPRCL_BPRCL_SHIFT)
#define I40E_GLV_BPTCH(_i) (0x0033D804 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_BPTCH_MAX_INDEX 383
-#define I40E_GLV_BPTCH_BPTCH_SHIFT 0
-#define I40E_GLV_BPTCH_BPTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_BPTCH_BPTCH_SHIFT)
#define I40E_GLV_BPTCL(_i) (0x0033d800 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_BPTCL_MAX_INDEX 383
-#define I40E_GLV_BPTCL_BPTCL_SHIFT 0
-#define I40E_GLV_BPTCL_BPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_BPTCL_BPTCL_SHIFT)
#define I40E_GLV_GORCH(_i) (0x00358004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_GORCH_MAX_INDEX 383
-#define I40E_GLV_GORCH_GORCH_SHIFT 0
-#define I40E_GLV_GORCH_GORCH_MASK I40E_MASK(0xFFFF, I40E_GLV_GORCH_GORCH_SHIFT)
#define I40E_GLV_GORCL(_i) (0x00358000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_GORCL_MAX_INDEX 383
-#define I40E_GLV_GORCL_GORCL_SHIFT 0
-#define I40E_GLV_GORCL_GORCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_GORCL_GORCL_SHIFT)
#define I40E_GLV_GOTCH(_i) (0x00328004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_GOTCH_MAX_INDEX 383
-#define I40E_GLV_GOTCH_GOTCH_SHIFT 0
-#define I40E_GLV_GOTCH_GOTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_GOTCH_GOTCH_SHIFT)
#define I40E_GLV_GOTCL(_i) (0x00328000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_GOTCL_MAX_INDEX 383
-#define I40E_GLV_GOTCL_GOTCL_SHIFT 0
-#define I40E_GLV_GOTCL_GOTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_GOTCL_GOTCL_SHIFT)
#define I40E_GLV_MPRCH(_i) (0x0036CC04 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_MPRCH_MAX_INDEX 383
-#define I40E_GLV_MPRCH_MPRCH_SHIFT 0
-#define I40E_GLV_MPRCH_MPRCH_MASK I40E_MASK(0xFFFF, I40E_GLV_MPRCH_MPRCH_SHIFT)
#define I40E_GLV_MPRCL(_i) (0x0036cc00 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_MPRCL_MAX_INDEX 383
-#define I40E_GLV_MPRCL_MPRCL_SHIFT 0
-#define I40E_GLV_MPRCL_MPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_MPRCL_MPRCL_SHIFT)
#define I40E_GLV_MPTCH(_i) (0x0033CC04 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_MPTCH_MAX_INDEX 383
-#define I40E_GLV_MPTCH_MPTCH_SHIFT 0
-#define I40E_GLV_MPTCH_MPTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_MPTCH_MPTCH_SHIFT)
#define I40E_GLV_MPTCL(_i) (0x0033cc00 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_MPTCL_MAX_INDEX 383
-#define I40E_GLV_MPTCL_MPTCL_SHIFT 0
-#define I40E_GLV_MPTCL_MPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_MPTCL_MPTCL_SHIFT)
#define I40E_GLV_RDPC(_i) (0x00310000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_RDPC_MAX_INDEX 383
-#define I40E_GLV_RDPC_RDPC_SHIFT 0
-#define I40E_GLV_RDPC_RDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_RDPC_RDPC_SHIFT)
#define I40E_GLV_RUPP(_i) (0x0036E400 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_RUPP_MAX_INDEX 383
-#define I40E_GLV_RUPP_RUPP_SHIFT 0
-#define I40E_GLV_RUPP_RUPP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_RUPP_RUPP_SHIFT)
#define I40E_GLV_TEPC(_i) (0x00344000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_TEPC_MAX_INDEX 383
-#define I40E_GLV_TEPC_TEPC_SHIFT 0
-#define I40E_GLV_TEPC_TEPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_TEPC_TEPC_SHIFT)
#define I40E_GLV_UPRCH(_i) (0x0036C004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_UPRCH_MAX_INDEX 383
-#define I40E_GLV_UPRCH_UPRCH_SHIFT 0
-#define I40E_GLV_UPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLV_UPRCH_UPRCH_SHIFT)
#define I40E_GLV_UPRCL(_i) (0x0036c000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_UPRCL_MAX_INDEX 383
-#define I40E_GLV_UPRCL_UPRCL_SHIFT 0
-#define I40E_GLV_UPRCL_UPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_UPRCL_UPRCL_SHIFT)
#define I40E_GLV_UPTCH(_i) (0x0033C004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_UPTCH_MAX_INDEX 383
-#define I40E_GLV_UPTCH_GLVUPTCH_SHIFT 0
-#define I40E_GLV_UPTCH_GLVUPTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_UPTCH_GLVUPTCH_SHIFT)
#define I40E_GLV_UPTCL(_i) (0x0033c000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
-#define I40E_GLV_UPTCL_MAX_INDEX 383
-#define I40E_GLV_UPTCL_UPTCL_SHIFT 0
-#define I40E_GLV_UPTCL_UPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_UPTCL_UPTCL_SHIFT)
#define I40E_GLVEBTC_RBCH(_i, _j) (0x00364004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
-#define I40E_GLVEBTC_RBCH_MAX_INDEX 7
-#define I40E_GLVEBTC_RBCH_TCBCH_SHIFT 0
-#define I40E_GLVEBTC_RBCH_TCBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_RBCH_TCBCH_SHIFT)
#define I40E_GLVEBTC_RBCL(_i, _j) (0x00364000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
-#define I40E_GLVEBTC_RBCL_MAX_INDEX 7
-#define I40E_GLVEBTC_RBCL_TCBCL_SHIFT 0
-#define I40E_GLVEBTC_RBCL_TCBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_RBCL_TCBCL_SHIFT)
#define I40E_GLVEBTC_RPCH(_i, _j) (0x00368004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
-#define I40E_GLVEBTC_RPCH_MAX_INDEX 7
-#define I40E_GLVEBTC_RPCH_TCPCH_SHIFT 0
-#define I40E_GLVEBTC_RPCH_TCPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_RPCH_TCPCH_SHIFT)
#define I40E_GLVEBTC_RPCL(_i, _j) (0x00368000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
-#define I40E_GLVEBTC_RPCL_MAX_INDEX 7
-#define I40E_GLVEBTC_RPCL_TCPCL_SHIFT 0
-#define I40E_GLVEBTC_RPCL_TCPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_RPCL_TCPCL_SHIFT)
#define I40E_GLVEBTC_TBCH(_i, _j) (0x00334004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
-#define I40E_GLVEBTC_TBCH_MAX_INDEX 7
-#define I40E_GLVEBTC_TBCH_TCBCH_SHIFT 0
-#define I40E_GLVEBTC_TBCH_TCBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_TBCH_TCBCH_SHIFT)
#define I40E_GLVEBTC_TBCL(_i, _j) (0x00334000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
-#define I40E_GLVEBTC_TBCL_MAX_INDEX 7
-#define I40E_GLVEBTC_TBCL_TCBCL_SHIFT 0
-#define I40E_GLVEBTC_TBCL_TCBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_TBCL_TCBCL_SHIFT)
#define I40E_GLVEBTC_TPCH(_i, _j) (0x00338004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
-#define I40E_GLVEBTC_TPCH_MAX_INDEX 7
-#define I40E_GLVEBTC_TPCH_TCPCH_SHIFT 0
-#define I40E_GLVEBTC_TPCH_TCPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_TPCH_TCPCH_SHIFT)
#define I40E_GLVEBTC_TPCL(_i, _j) (0x00338000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
-#define I40E_GLVEBTC_TPCL_MAX_INDEX 7
-#define I40E_GLVEBTC_TPCL_TCPCL_SHIFT 0
-#define I40E_GLVEBTC_TPCL_TCPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_TPCL_TCPCL_SHIFT)
-#define I40E_GLVEBVL_BPCH(_i) (0x00374804 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_BPCH_MAX_INDEX 127
-#define I40E_GLVEBVL_BPCH_VLBPCH_SHIFT 0
-#define I40E_GLVEBVL_BPCH_VLBPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_BPCH_VLBPCH_SHIFT)
-#define I40E_GLVEBVL_BPCL(_i) (0x00374800 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_BPCL_MAX_INDEX 127
-#define I40E_GLVEBVL_BPCL_VLBPCL_SHIFT 0
-#define I40E_GLVEBVL_BPCL_VLBPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_BPCL_VLBPCL_SHIFT)
-#define I40E_GLVEBVL_GORCH(_i) (0x00360004 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_GORCH_MAX_INDEX 127
-#define I40E_GLVEBVL_GORCH_VLBCH_SHIFT 0
-#define I40E_GLVEBVL_GORCH_VLBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_GORCH_VLBCH_SHIFT)
-#define I40E_GLVEBVL_GORCL(_i) (0x00360000 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_GORCL_MAX_INDEX 127
-#define I40E_GLVEBVL_GORCL_VLBCL_SHIFT 0
-#define I40E_GLVEBVL_GORCL_VLBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_GORCL_VLBCL_SHIFT)
-#define I40E_GLVEBVL_GOTCH(_i) (0x00330004 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_GOTCH_MAX_INDEX 127
-#define I40E_GLVEBVL_GOTCH_VLBCH_SHIFT 0
-#define I40E_GLVEBVL_GOTCH_VLBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_GOTCH_VLBCH_SHIFT)
-#define I40E_GLVEBVL_GOTCL(_i) (0x00330000 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_GOTCL_MAX_INDEX 127
-#define I40E_GLVEBVL_GOTCL_VLBCL_SHIFT 0
-#define I40E_GLVEBVL_GOTCL_VLBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_GOTCL_VLBCL_SHIFT)
-#define I40E_GLVEBVL_MPCH(_i) (0x00374404 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_MPCH_MAX_INDEX 127
-#define I40E_GLVEBVL_MPCH_VLMPCH_SHIFT 0
-#define I40E_GLVEBVL_MPCH_VLMPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_MPCH_VLMPCH_SHIFT)
-#define I40E_GLVEBVL_MPCL(_i) (0x00374400 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_MPCL_MAX_INDEX 127
-#define I40E_GLVEBVL_MPCL_VLMPCL_SHIFT 0
-#define I40E_GLVEBVL_MPCL_VLMPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_MPCL_VLMPCL_SHIFT)
-#define I40E_GLVEBVL_UPCH(_i) (0x00374004 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_UPCH_MAX_INDEX 127
-#define I40E_GLVEBVL_UPCH_VLUPCH_SHIFT 0
-#define I40E_GLVEBVL_UPCH_VLUPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_UPCH_VLUPCH_SHIFT)
-#define I40E_GLVEBVL_UPCL(_i) (0x00374000 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_GLVEBVL_UPCL_MAX_INDEX 127
-#define I40E_GLVEBVL_UPCL_VLUPCL_SHIFT 0
-#define I40E_GLVEBVL_UPCL_VLUPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_UPCL_VLUPCL_SHIFT)
-#define I40E_GL_MTG_FLU_MSK_H 0x00269F4C /* Reset: CORER */
-#define I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_SHIFT 0
-#define I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_MASK I40E_MASK(0xFFFF, I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_SHIFT)
-#define I40E_GL_SWR_DEF_ACT(_i) (0x00270200 + ((_i) * 4)) /* _i=0...35 */ /* Reset: CORER */
-#define I40E_GL_SWR_DEF_ACT_MAX_INDEX 35
-#define I40E_GL_SWR_DEF_ACT_DEF_ACTION_SHIFT 0
-#define I40E_GL_SWR_DEF_ACT_DEF_ACTION_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_SWR_DEF_ACT_DEF_ACTION_SHIFT)
-#define I40E_GL_SWR_DEF_ACT_EN(_i) (0x0026CFB8 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
-#define I40E_GL_SWR_DEF_ACT_EN_MAX_INDEX 1
-#define I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_SHIFT 0
-#define I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_SHIFT)
-#define I40E_PRTTSYN_ADJ 0x001E4280 /* Reset: GLOBR */
-#define I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT 0
-#define I40E_PRTTSYN_ADJ_TSYNADJ_MASK I40E_MASK(0x7FFFFFFF, I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT)
-#define I40E_PRTTSYN_ADJ_SIGN_SHIFT 31
-#define I40E_PRTTSYN_ADJ_SIGN_MASK I40E_MASK(0x1, I40E_PRTTSYN_ADJ_SIGN_SHIFT)
-#define I40E_PRTTSYN_AUX_0(_i) (0x001E42A0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
-#define I40E_PRTTSYN_AUX_0_MAX_INDEX 1
-#define I40E_PRTTSYN_AUX_0_OUT_ENA_SHIFT 0
-#define I40E_PRTTSYN_AUX_0_OUT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_0_OUT_ENA_SHIFT)
-#define I40E_PRTTSYN_AUX_0_OUTMOD_SHIFT 1
-#define I40E_PRTTSYN_AUX_0_OUTMOD_MASK I40E_MASK(0x3, I40E_PRTTSYN_AUX_0_OUTMOD_SHIFT)
-#define I40E_PRTTSYN_AUX_0_OUTLVL_SHIFT 3
-#define I40E_PRTTSYN_AUX_0_OUTLVL_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_0_OUTLVL_SHIFT)
-#define I40E_PRTTSYN_AUX_0_PULSEW_SHIFT 8
-#define I40E_PRTTSYN_AUX_0_PULSEW_MASK I40E_MASK(0xF, I40E_PRTTSYN_AUX_0_PULSEW_SHIFT)
-#define I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT 16
-#define I40E_PRTTSYN_AUX_0_EVNTLVL_MASK I40E_MASK(0x3, I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT)
-#define I40E_PRTTSYN_AUX_1(_i) (0x001E42E0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
-#define I40E_PRTTSYN_AUX_1_MAX_INDEX 1
-#define I40E_PRTTSYN_AUX_1_INSTNT_SHIFT 0
-#define I40E_PRTTSYN_AUX_1_INSTNT_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_1_INSTNT_SHIFT)
-#define I40E_PRTTSYN_AUX_1_SAMPLE_TIME_SHIFT 1
-#define I40E_PRTTSYN_AUX_1_SAMPLE_TIME_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_1_SAMPLE_TIME_SHIFT)
-#define I40E_PRTTSYN_CLKO(_i) (0x001E4240 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
-#define I40E_PRTTSYN_CLKO_MAX_INDEX 1
-#define I40E_PRTTSYN_CLKO_TSYNCLKO_SHIFT 0
-#define I40E_PRTTSYN_CLKO_TSYNCLKO_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_CLKO_TSYNCLKO_SHIFT)
#define I40E_PRTTSYN_CTL0 0x001E4200 /* Reset: GLOBR */
-#define I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_SHIFT 0
-#define I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_SHIFT)
#define I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_SHIFT 1
#define I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_SHIFT)
-#define I40E_PRTTSYN_CTL0_EVENT_INT_ENA_SHIFT 2
-#define I40E_PRTTSYN_CTL0_EVENT_INT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_EVENT_INT_ENA_SHIFT)
-#define I40E_PRTTSYN_CTL0_TGT_INT_ENA_SHIFT 3
-#define I40E_PRTTSYN_CTL0_TGT_INT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_TGT_INT_ENA_SHIFT)
#define I40E_PRTTSYN_CTL0_PF_ID_SHIFT 8
#define I40E_PRTTSYN_CTL0_PF_ID_MASK I40E_MASK(0xF, I40E_PRTTSYN_CTL0_PF_ID_SHIFT)
-#define I40E_PRTTSYN_CTL0_TSYNACT_SHIFT 12
-#define I40E_PRTTSYN_CTL0_TSYNACT_MASK I40E_MASK(0x3, I40E_PRTTSYN_CTL0_TSYNACT_SHIFT)
#define I40E_PRTTSYN_CTL0_TSYNENA_SHIFT 31
#define I40E_PRTTSYN_CTL0_TSYNENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_TSYNENA_SHIFT)
#define I40E_PRTTSYN_CTL1 0x00085020 /* Reset: CORER */
#define I40E_PRTTSYN_CTL1_V1MESSTYPE0_SHIFT 0
#define I40E_PRTTSYN_CTL1_V1MESSTYPE0_MASK I40E_MASK(0xFF, I40E_PRTTSYN_CTL1_V1MESSTYPE0_SHIFT)
-#define I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT 8
-#define I40E_PRTTSYN_CTL1_V1MESSTYPE1_MASK I40E_MASK(0xFF, I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT)
#define I40E_PRTTSYN_CTL1_V2MESSTYPE0_SHIFT 16
#define I40E_PRTTSYN_CTL1_V2MESSTYPE0_MASK I40E_MASK(0xF, I40E_PRTTSYN_CTL1_V2MESSTYPE0_SHIFT)
-#define I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT 20
-#define I40E_PRTTSYN_CTL1_V2MESSTYPE1_MASK I40E_MASK(0xF, I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT)
#define I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT 24
-#define I40E_PRTTSYN_CTL1_TSYNTYPE_MASK I40E_MASK(0x3, I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT)
#define I40E_PRTTSYN_CTL1_UDP_ENA_SHIFT 26
#define I40E_PRTTSYN_CTL1_UDP_ENA_MASK I40E_MASK(0x3, I40E_PRTTSYN_CTL1_UDP_ENA_SHIFT)
#define I40E_PRTTSYN_CTL1_TSYNENA_SHIFT 31
#define I40E_PRTTSYN_CTL1_TSYNENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL1_TSYNENA_SHIFT)
-#define I40E_PRTTSYN_EVNT_H(_i) (0x001E40C0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
-#define I40E_PRTTSYN_EVNT_H_MAX_INDEX 1
-#define I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_SHIFT 0
-#define I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_SHIFT)
-#define I40E_PRTTSYN_EVNT_L(_i) (0x001E4080 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
-#define I40E_PRTTSYN_EVNT_L_MAX_INDEX 1
-#define I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_SHIFT 0
-#define I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_SHIFT)
#define I40E_PRTTSYN_INC_H 0x001E4060 /* Reset: GLOBR */
-#define I40E_PRTTSYN_INC_H_TSYNINC_H_SHIFT 0
-#define I40E_PRTTSYN_INC_H_TSYNINC_H_MASK I40E_MASK(0x3F, I40E_PRTTSYN_INC_H_TSYNINC_H_SHIFT)
#define I40E_PRTTSYN_INC_L 0x001E4040 /* Reset: GLOBR */
-#define I40E_PRTTSYN_INC_L_TSYNINC_L_SHIFT 0
-#define I40E_PRTTSYN_INC_L_TSYNINC_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_INC_L_TSYNINC_L_SHIFT)
#define I40E_PRTTSYN_RXTIME_H(_i) (0x00085040 + ((_i) * 32)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_PRTTSYN_RXTIME_H_MAX_INDEX 3
-#define I40E_PRTTSYN_RXTIME_H_RXTIEM_H_SHIFT 0
-#define I40E_PRTTSYN_RXTIME_H_RXTIEM_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_RXTIME_H_RXTIEM_H_SHIFT)
#define I40E_PRTTSYN_RXTIME_L(_i) (0x000850C0 + ((_i) * 32)) /* _i=0...3 */ /* Reset: CORER */
-#define I40E_PRTTSYN_RXTIME_L_MAX_INDEX 3
-#define I40E_PRTTSYN_RXTIME_L_RXTIEM_L_SHIFT 0
-#define I40E_PRTTSYN_RXTIME_L_RXTIEM_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_RXTIME_L_RXTIEM_L_SHIFT)
#define I40E_PRTTSYN_STAT_0 0x001E4220 /* Reset: GLOBR */
-#define I40E_PRTTSYN_STAT_0_EVENT0_SHIFT 0
-#define I40E_PRTTSYN_STAT_0_EVENT0_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_EVENT0_SHIFT)
-#define I40E_PRTTSYN_STAT_0_EVENT1_SHIFT 1
-#define I40E_PRTTSYN_STAT_0_EVENT1_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_EVENT1_SHIFT)
-#define I40E_PRTTSYN_STAT_0_TGT0_SHIFT 2
-#define I40E_PRTTSYN_STAT_0_TGT0_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_TGT0_SHIFT)
-#define I40E_PRTTSYN_STAT_0_TGT1_SHIFT 3
-#define I40E_PRTTSYN_STAT_0_TGT1_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_TGT1_SHIFT)
#define I40E_PRTTSYN_STAT_0_TXTIME_SHIFT 4
#define I40E_PRTTSYN_STAT_0_TXTIME_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_TXTIME_SHIFT)
#define I40E_PRTTSYN_STAT_1 0x00085140 /* Reset: CORER */
-#define I40E_PRTTSYN_STAT_1_RXT0_SHIFT 0
-#define I40E_PRTTSYN_STAT_1_RXT0_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT0_SHIFT)
-#define I40E_PRTTSYN_STAT_1_RXT1_SHIFT 1
-#define I40E_PRTTSYN_STAT_1_RXT1_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT1_SHIFT)
-#define I40E_PRTTSYN_STAT_1_RXT2_SHIFT 2
-#define I40E_PRTTSYN_STAT_1_RXT2_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT2_SHIFT)
-#define I40E_PRTTSYN_STAT_1_RXT3_SHIFT 3
-#define I40E_PRTTSYN_STAT_1_RXT3_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT3_SHIFT)
-#define I40E_PRTTSYN_TGT_H(_i) (0x001E4180 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
-#define I40E_PRTTSYN_TGT_H_MAX_INDEX 1
-#define I40E_PRTTSYN_TGT_H_TSYNTGTT_H_SHIFT 0
-#define I40E_PRTTSYN_TGT_H_TSYNTGTT_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TGT_H_TSYNTGTT_H_SHIFT)
-#define I40E_PRTTSYN_TGT_L(_i) (0x001E4140 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
-#define I40E_PRTTSYN_TGT_L_MAX_INDEX 1
-#define I40E_PRTTSYN_TGT_L_TSYNTGTT_L_SHIFT 0
-#define I40E_PRTTSYN_TGT_L_TSYNTGTT_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TGT_L_TSYNTGTT_L_SHIFT)
#define I40E_PRTTSYN_TIME_H 0x001E4120 /* Reset: GLOBR */
-#define I40E_PRTTSYN_TIME_H_TSYNTIME_H_SHIFT 0
-#define I40E_PRTTSYN_TIME_H_TSYNTIME_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TIME_H_TSYNTIME_H_SHIFT)
#define I40E_PRTTSYN_TIME_L 0x001E4100 /* Reset: GLOBR */
-#define I40E_PRTTSYN_TIME_L_TSYNTIME_L_SHIFT 0
-#define I40E_PRTTSYN_TIME_L_TSYNTIME_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TIME_L_TSYNTIME_L_SHIFT)
#define I40E_PRTTSYN_TXTIME_H 0x001E41E0 /* Reset: GLOBR */
-#define I40E_PRTTSYN_TXTIME_H_TXTIEM_H_SHIFT 0
-#define I40E_PRTTSYN_TXTIME_H_TXTIEM_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TXTIME_H_TXTIEM_H_SHIFT)
#define I40E_PRTTSYN_TXTIME_L 0x001E41C0 /* Reset: GLOBR */
-#define I40E_PRTTSYN_TXTIME_L_TXTIEM_L_SHIFT 0
-#define I40E_PRTTSYN_TXTIME_L_TXTIEM_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TXTIME_L_TXTIEM_L_SHIFT)
#define I40E_GL_MDET_RX 0x0012A510 /* Reset: CORER */
#define I40E_GL_MDET_RX_FUNCTION_SHIFT 0
#define I40E_GL_MDET_RX_FUNCTION_MASK I40E_MASK(0xFF, I40E_GL_MDET_RX_FUNCTION_SHIFT)
@@ -3033,2304 +630,53 @@
#define I40E_PF_VT_PFALLOC_VALID_SHIFT 31
#define I40E_PF_VT_PFALLOC_VALID_MASK I40E_MASK(0x1u, I40E_PF_VT_PFALLOC_VALID_SHIFT)
#define I40E_VP_MDET_RX(_VF) (0x0012A000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_VP_MDET_RX_MAX_INDEX 127
#define I40E_VP_MDET_RX_VALID_SHIFT 0
#define I40E_VP_MDET_RX_VALID_MASK I40E_MASK(0x1, I40E_VP_MDET_RX_VALID_SHIFT)
#define I40E_VP_MDET_TX(_VF) (0x000E6000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_VP_MDET_TX_MAX_INDEX 127
#define I40E_VP_MDET_TX_VALID_SHIFT 0
#define I40E_VP_MDET_TX_VALID_MASK I40E_MASK(0x1, I40E_VP_MDET_TX_VALID_SHIFT)
-#define I40E_GLPM_WUMC 0x0006C800 /* Reset: POR */
-#define I40E_GLPM_WUMC_NOTCO_SHIFT 0
-#define I40E_GLPM_WUMC_NOTCO_MASK I40E_MASK(0x1, I40E_GLPM_WUMC_NOTCO_SHIFT)
-#define I40E_GLPM_WUMC_SRST_PIN_VAL_SHIFT 1
-#define I40E_GLPM_WUMC_SRST_PIN_VAL_MASK I40E_MASK(0x1, I40E_GLPM_WUMC_SRST_PIN_VAL_SHIFT)
-#define I40E_GLPM_WUMC_ROL_MODE_SHIFT 2
-#define I40E_GLPM_WUMC_ROL_MODE_MASK I40E_MASK(0x1, I40E_GLPM_WUMC_ROL_MODE_SHIFT)
-#define I40E_GLPM_WUMC_RESERVED_4_SHIFT 3
-#define I40E_GLPM_WUMC_RESERVED_4_MASK I40E_MASK(0x1FFF, I40E_GLPM_WUMC_RESERVED_4_SHIFT)
-#define I40E_GLPM_WUMC_MNG_WU_PF_SHIFT 16
-#define I40E_GLPM_WUMC_MNG_WU_PF_MASK I40E_MASK(0xFFFF, I40E_GLPM_WUMC_MNG_WU_PF_SHIFT)
#define I40E_PFPM_APM 0x000B8080 /* Reset: POR */
#define I40E_PFPM_APM_APME_SHIFT 0
#define I40E_PFPM_APM_APME_MASK I40E_MASK(0x1, I40E_PFPM_APM_APME_SHIFT)
-#define I40E_PFPM_FHFT_LENGTH(_i) (0x0006A000 + ((_i) * 128)) /* _i=0...7 */ /* Reset: POR */
-#define I40E_PFPM_FHFT_LENGTH_MAX_INDEX 7
-#define I40E_PFPM_FHFT_LENGTH_LENGTH_SHIFT 0
-#define I40E_PFPM_FHFT_LENGTH_LENGTH_MASK I40E_MASK(0xFF, I40E_PFPM_FHFT_LENGTH_LENGTH_SHIFT)
-#define I40E_PFPM_WUC 0x0006B200 /* Reset: POR */
-#define I40E_PFPM_WUC_EN_APM_D0_SHIFT 5
-#define I40E_PFPM_WUC_EN_APM_D0_MASK I40E_MASK(0x1, I40E_PFPM_WUC_EN_APM_D0_SHIFT)
#define I40E_PFPM_WUFC 0x0006B400 /* Reset: POR */
-#define I40E_PFPM_WUFC_LNKC_SHIFT 0
-#define I40E_PFPM_WUFC_LNKC_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_LNKC_SHIFT)
#define I40E_PFPM_WUFC_MAG_SHIFT 1
#define I40E_PFPM_WUFC_MAG_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_MAG_SHIFT)
-#define I40E_PFPM_WUFC_MNG_SHIFT 3
-#define I40E_PFPM_WUFC_MNG_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_MNG_SHIFT)
-#define I40E_PFPM_WUFC_FLX0_ACT_SHIFT 4
-#define I40E_PFPM_WUFC_FLX0_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX0_ACT_SHIFT)
-#define I40E_PFPM_WUFC_FLX1_ACT_SHIFT 5
-#define I40E_PFPM_WUFC_FLX1_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX1_ACT_SHIFT)
-#define I40E_PFPM_WUFC_FLX2_ACT_SHIFT 6
-#define I40E_PFPM_WUFC_FLX2_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX2_ACT_SHIFT)
-#define I40E_PFPM_WUFC_FLX3_ACT_SHIFT 7
-#define I40E_PFPM_WUFC_FLX3_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX3_ACT_SHIFT)
-#define I40E_PFPM_WUFC_FLX4_ACT_SHIFT 8
-#define I40E_PFPM_WUFC_FLX4_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX4_ACT_SHIFT)
-#define I40E_PFPM_WUFC_FLX5_ACT_SHIFT 9
-#define I40E_PFPM_WUFC_FLX5_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX5_ACT_SHIFT)
-#define I40E_PFPM_WUFC_FLX6_ACT_SHIFT 10
-#define I40E_PFPM_WUFC_FLX6_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX6_ACT_SHIFT)
-#define I40E_PFPM_WUFC_FLX7_ACT_SHIFT 11
-#define I40E_PFPM_WUFC_FLX7_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX7_ACT_SHIFT)
-#define I40E_PFPM_WUFC_FLX0_SHIFT 16
-#define I40E_PFPM_WUFC_FLX0_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX0_SHIFT)
-#define I40E_PFPM_WUFC_FLX1_SHIFT 17
-#define I40E_PFPM_WUFC_FLX1_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX1_SHIFT)
-#define I40E_PFPM_WUFC_FLX2_SHIFT 18
-#define I40E_PFPM_WUFC_FLX2_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX2_SHIFT)
-#define I40E_PFPM_WUFC_FLX3_SHIFT 19
-#define I40E_PFPM_WUFC_FLX3_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX3_SHIFT)
-#define I40E_PFPM_WUFC_FLX4_SHIFT 20
-#define I40E_PFPM_WUFC_FLX4_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX4_SHIFT)
-#define I40E_PFPM_WUFC_FLX5_SHIFT 21
-#define I40E_PFPM_WUFC_FLX5_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX5_SHIFT)
-#define I40E_PFPM_WUFC_FLX6_SHIFT 22
-#define I40E_PFPM_WUFC_FLX6_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX6_SHIFT)
-#define I40E_PFPM_WUFC_FLX7_SHIFT 23
-#define I40E_PFPM_WUFC_FLX7_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX7_SHIFT)
-#define I40E_PFPM_WUFC_FW_RST_WK_SHIFT 31
-#define I40E_PFPM_WUFC_FW_RST_WK_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FW_RST_WK_SHIFT)
-#define I40E_PFPM_WUS 0x0006B600 /* Reset: POR */
-#define I40E_PFPM_WUS_LNKC_SHIFT 0
-#define I40E_PFPM_WUS_LNKC_MASK I40E_MASK(0x1, I40E_PFPM_WUS_LNKC_SHIFT)
-#define I40E_PFPM_WUS_MAG_SHIFT 1
-#define I40E_PFPM_WUS_MAG_MASK I40E_MASK(0x1, I40E_PFPM_WUS_MAG_SHIFT)
-#define I40E_PFPM_WUS_PME_STATUS_SHIFT 2
-#define I40E_PFPM_WUS_PME_STATUS_MASK I40E_MASK(0x1, I40E_PFPM_WUS_PME_STATUS_SHIFT)
-#define I40E_PFPM_WUS_MNG_SHIFT 3
-#define I40E_PFPM_WUS_MNG_MASK I40E_MASK(0x1, I40E_PFPM_WUS_MNG_SHIFT)
-#define I40E_PFPM_WUS_FLX0_SHIFT 16
-#define I40E_PFPM_WUS_FLX0_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX0_SHIFT)
-#define I40E_PFPM_WUS_FLX1_SHIFT 17
-#define I40E_PFPM_WUS_FLX1_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX1_SHIFT)
-#define I40E_PFPM_WUS_FLX2_SHIFT 18
-#define I40E_PFPM_WUS_FLX2_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX2_SHIFT)
-#define I40E_PFPM_WUS_FLX3_SHIFT 19
-#define I40E_PFPM_WUS_FLX3_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX3_SHIFT)
-#define I40E_PFPM_WUS_FLX4_SHIFT 20
-#define I40E_PFPM_WUS_FLX4_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX4_SHIFT)
-#define I40E_PFPM_WUS_FLX5_SHIFT 21
-#define I40E_PFPM_WUS_FLX5_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX5_SHIFT)
-#define I40E_PFPM_WUS_FLX6_SHIFT 22
-#define I40E_PFPM_WUS_FLX6_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX6_SHIFT)
-#define I40E_PFPM_WUS_FLX7_SHIFT 23
-#define I40E_PFPM_WUS_FLX7_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX7_SHIFT)
-#define I40E_PFPM_WUS_FW_RST_WK_SHIFT 31
-#define I40E_PFPM_WUS_FW_RST_WK_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FW_RST_WK_SHIFT)
-#define I40E_PRTPM_FHFHR 0x0006C000 /* Reset: POR */
-#define I40E_PRTPM_FHFHR_UNICAST_SHIFT 0
-#define I40E_PRTPM_FHFHR_UNICAST_MASK I40E_MASK(0x1, I40E_PRTPM_FHFHR_UNICAST_SHIFT)
-#define I40E_PRTPM_FHFHR_MULTICAST_SHIFT 1
-#define I40E_PRTPM_FHFHR_MULTICAST_MASK I40E_MASK(0x1, I40E_PRTPM_FHFHR_MULTICAST_SHIFT)
-#define I40E_PRTPM_SAH(_i) (0x001E44C0 + ((_i) * 32)) /* _i=0...3 */ /* Reset: PFR */
-#define I40E_PRTPM_SAH_MAX_INDEX 3
-#define I40E_PRTPM_SAH_PFPM_SAH_SHIFT 0
-#define I40E_PRTPM_SAH_PFPM_SAH_MASK I40E_MASK(0xFFFF, I40E_PRTPM_SAH_PFPM_SAH_SHIFT)
-#define I40E_PRTPM_SAH_PF_NUM_SHIFT 26
-#define I40E_PRTPM_SAH_PF_NUM_MASK I40E_MASK(0xF, I40E_PRTPM_SAH_PF_NUM_SHIFT)
-#define I40E_PRTPM_SAH_MC_MAG_EN_SHIFT 30
-#define I40E_PRTPM_SAH_MC_MAG_EN_MASK I40E_MASK(0x1, I40E_PRTPM_SAH_MC_MAG_EN_SHIFT)
-#define I40E_PRTPM_SAH_AV_SHIFT 31
-#define I40E_PRTPM_SAH_AV_MASK I40E_MASK(0x1, I40E_PRTPM_SAH_AV_SHIFT)
-#define I40E_PRTPM_SAL(_i) (0x001E4440 + ((_i) * 32)) /* _i=0...3 */ /* Reset: PFR */
-#define I40E_PRTPM_SAL_MAX_INDEX 3
-#define I40E_PRTPM_SAL_PFPM_SAL_SHIFT 0
-#define I40E_PRTPM_SAL_PFPM_SAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_SAL_PFPM_SAL_SHIFT)
#define I40E_VF_ARQBAH1 0x00006000 /* Reset: EMPR */
-#define I40E_VF_ARQBAH1_ARQBAH_SHIFT 0
-#define I40E_VF_ARQBAH1_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAH1_ARQBAH_SHIFT)
#define I40E_VF_ARQBAL1 0x00006C00 /* Reset: EMPR */
-#define I40E_VF_ARQBAL1_ARQBAL_SHIFT 0
-#define I40E_VF_ARQBAL1_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAL1_ARQBAL_SHIFT)
#define I40E_VF_ARQH1 0x00007400 /* Reset: EMPR */
-#define I40E_VF_ARQH1_ARQH_SHIFT 0
-#define I40E_VF_ARQH1_ARQH_MASK I40E_MASK(0x3FF, I40E_VF_ARQH1_ARQH_SHIFT)
#define I40E_VF_ARQLEN1 0x00008000 /* Reset: EMPR */
-#define I40E_VF_ARQLEN1_ARQLEN_SHIFT 0
-#define I40E_VF_ARQLEN1_ARQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ARQLEN1_ARQLEN_SHIFT)
-#define I40E_VF_ARQLEN1_ARQVFE_SHIFT 28
-#define I40E_VF_ARQLEN1_ARQVFE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQVFE_SHIFT)
-#define I40E_VF_ARQLEN1_ARQOVFL_SHIFT 29
-#define I40E_VF_ARQLEN1_ARQOVFL_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQOVFL_SHIFT)
-#define I40E_VF_ARQLEN1_ARQCRIT_SHIFT 30
-#define I40E_VF_ARQLEN1_ARQCRIT_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQCRIT_SHIFT)
-#define I40E_VF_ARQLEN1_ARQENABLE_SHIFT 31
-#define I40E_VF_ARQLEN1_ARQENABLE_MASK I40E_MASK(0x1u, I40E_VF_ARQLEN1_ARQENABLE_SHIFT)
#define I40E_VF_ARQT1 0x00007000 /* Reset: EMPR */
-#define I40E_VF_ARQT1_ARQT_SHIFT 0
-#define I40E_VF_ARQT1_ARQT_MASK I40E_MASK(0x3FF, I40E_VF_ARQT1_ARQT_SHIFT)
#define I40E_VF_ATQBAH1 0x00007800 /* Reset: EMPR */
-#define I40E_VF_ATQBAH1_ATQBAH_SHIFT 0
-#define I40E_VF_ATQBAH1_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAH1_ATQBAH_SHIFT)
#define I40E_VF_ATQBAL1 0x00007C00 /* Reset: EMPR */
-#define I40E_VF_ATQBAL1_ATQBAL_SHIFT 0
-#define I40E_VF_ATQBAL1_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAL1_ATQBAL_SHIFT)
#define I40E_VF_ATQH1 0x00006400 /* Reset: EMPR */
-#define I40E_VF_ATQH1_ATQH_SHIFT 0
-#define I40E_VF_ATQH1_ATQH_MASK I40E_MASK(0x3FF, I40E_VF_ATQH1_ATQH_SHIFT)
#define I40E_VF_ATQLEN1 0x00006800 /* Reset: EMPR */
-#define I40E_VF_ATQLEN1_ATQLEN_SHIFT 0
-#define I40E_VF_ATQLEN1_ATQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ATQLEN1_ATQLEN_SHIFT)
-#define I40E_VF_ATQLEN1_ATQVFE_SHIFT 28
-#define I40E_VF_ATQLEN1_ATQVFE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQVFE_SHIFT)
-#define I40E_VF_ATQLEN1_ATQOVFL_SHIFT 29
-#define I40E_VF_ATQLEN1_ATQOVFL_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQOVFL_SHIFT)
-#define I40E_VF_ATQLEN1_ATQCRIT_SHIFT 30
-#define I40E_VF_ATQLEN1_ATQCRIT_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQCRIT_SHIFT)
-#define I40E_VF_ATQLEN1_ATQENABLE_SHIFT 31
-#define I40E_VF_ATQLEN1_ATQENABLE_MASK I40E_MASK(0x1u, I40E_VF_ATQLEN1_ATQENABLE_SHIFT)
#define I40E_VF_ATQT1 0x00008400 /* Reset: EMPR */
-#define I40E_VF_ATQT1_ATQT_SHIFT 0
-#define I40E_VF_ATQT1_ATQT_MASK I40E_MASK(0x3FF, I40E_VF_ATQT1_ATQT_SHIFT)
-#define I40E_VFGEN_RSTAT 0x00008800 /* Reset: VFR */
-#define I40E_VFGEN_RSTAT_VFR_STATE_SHIFT 0
-#define I40E_VFGEN_RSTAT_VFR_STATE_MASK I40E_MASK(0x3, I40E_VFGEN_RSTAT_VFR_STATE_SHIFT)
-#define I40E_VFINT_DYN_CTL01 0x00005C00 /* Reset: VFR */
-#define I40E_VFINT_DYN_CTL01_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTL01_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_INTENA_SHIFT)
-#define I40E_VFINT_DYN_CTL01_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTL01_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_CLEARPBA_SHIFT)
-#define I40E_VFINT_DYN_CTL01_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTL01_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_SWINT_TRIG_SHIFT)
-#define I40E_VFINT_DYN_CTL01_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTL01_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL01_ITR_INDX_SHIFT)
-#define I40E_VFINT_DYN_CTL01_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTL01_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTL01_INTERVAL_SHIFT)
-#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT)
-#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL01_SW_ITR_INDX_SHIFT)
-#define I40E_VFINT_DYN_CTL01_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTL01_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_INTENA_MSK_SHIFT)
-#define I40E_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...15 */ /* Reset: VFR */
-#define I40E_VFINT_DYN_CTLN1_MAX_INDEX 15
-#define I40E_VFINT_DYN_CTLN1_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTLN1_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_INTENA_SHIFT)
-#define I40E_VFINT_DYN_CTLN1_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_CLEARPBA_SHIFT)
-#define I40E_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTLN1_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT)
-#define I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT)
-#define I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTLN1_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT)
-#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT)
-#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT)
-#define I40E_VFINT_DYN_CTLN1_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTLN1_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_INTENA_MSK_SHIFT)
-#define I40E_VFINT_ICR0_ENA1 0x00005000 /* Reset: CORER */
-#define I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT)
-#define I40E_VFINT_ICR0_ENA1_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR0_ENA1_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA1_ADMINQ_SHIFT)
-#define I40E_VFINT_ICR0_ENA1_RSVD_SHIFT 31
-#define I40E_VFINT_ICR0_ENA1_RSVD_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA1_RSVD_SHIFT)
-#define I40E_VFINT_ICR01 0x00004800 /* Reset: CORER */
-#define I40E_VFINT_ICR01_INTEVENT_SHIFT 0
-#define I40E_VFINT_ICR01_INTEVENT_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_INTEVENT_SHIFT)
-#define I40E_VFINT_ICR01_QUEUE_0_SHIFT 1
-#define I40E_VFINT_ICR01_QUEUE_0_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_0_SHIFT)
-#define I40E_VFINT_ICR01_QUEUE_1_SHIFT 2
-#define I40E_VFINT_ICR01_QUEUE_1_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_1_SHIFT)
-#define I40E_VFINT_ICR01_QUEUE_2_SHIFT 3
-#define I40E_VFINT_ICR01_QUEUE_2_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_2_SHIFT)
-#define I40E_VFINT_ICR01_QUEUE_3_SHIFT 4
-#define I40E_VFINT_ICR01_QUEUE_3_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_3_SHIFT)
-#define I40E_VFINT_ICR01_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR01_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_LINK_STAT_CHANGE_SHIFT)
-#define I40E_VFINT_ICR01_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR01_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_ADMINQ_SHIFT)
-#define I40E_VFINT_ICR01_SWINT_SHIFT 31
-#define I40E_VFINT_ICR01_SWINT_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_SWINT_SHIFT)
-#define I40E_VFINT_ITR01(_i) (0x00004C00 + ((_i) * 4)) /* _i=0...2 */ /* Reset: VFR */
-#define I40E_VFINT_ITR01_MAX_INDEX 2
-#define I40E_VFINT_ITR01_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITR01_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITR01_INTERVAL_SHIFT)
-#define I40E_VFINT_ITRN1(_i, _INTVF) (0x00002800 + ((_i) * 64 + (_INTVF) * 4)) /* _i=0...2, _INTVF=0...15 */ /* Reset: VFR */
-#define I40E_VFINT_ITRN1_MAX_INDEX 2
-#define I40E_VFINT_ITRN1_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITRN1_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITRN1_INTERVAL_SHIFT)
-#define I40E_VFINT_STAT_CTL01 0x00005400 /* Reset: CORER */
-#define I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT 2
-#define I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT)
-#define I40E_QRX_TAIL1(_Q) (0x00002000 + ((_Q) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_QRX_TAIL1_MAX_INDEX 15
-#define I40E_QRX_TAIL1_TAIL_SHIFT 0
-#define I40E_QRX_TAIL1_TAIL_MASK I40E_MASK(0x1FFF, I40E_QRX_TAIL1_TAIL_SHIFT)
-#define I40E_QTX_TAIL1(_Q) (0x00000000 + ((_Q) * 4)) /* _i=0...15 */ /* Reset: PFR */
-#define I40E_QTX_TAIL1_MAX_INDEX 15
-#define I40E_QTX_TAIL1_TAIL_SHIFT 0
-#define I40E_QTX_TAIL1_TAIL_MASK I40E_MASK(0x1FFF, I40E_QTX_TAIL1_TAIL_SHIFT)
-#define I40E_VFMSIX_PBA 0x00002000 /* Reset: VFLR */
-#define I40E_VFMSIX_PBA_PENBIT_SHIFT 0
-#define I40E_VFMSIX_PBA_PENBIT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_PBA_PENBIT_SHIFT)
-#define I40E_VFMSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
-#define I40E_VFMSIX_TADD_MAX_INDEX 16
-#define I40E_VFMSIX_TADD_MSIXTADD10_SHIFT 0
-#define I40E_VFMSIX_TADD_MSIXTADD10_MASK I40E_MASK(0x3, I40E_VFMSIX_TADD_MSIXTADD10_SHIFT)
-#define I40E_VFMSIX_TADD_MSIXTADD_SHIFT 2
-#define I40E_VFMSIX_TADD_MSIXTADD_MASK I40E_MASK(0x3FFFFFFF, I40E_VFMSIX_TADD_MSIXTADD_SHIFT)
-#define I40E_VFMSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
-#define I40E_VFMSIX_TMSG_MAX_INDEX 16
-#define I40E_VFMSIX_TMSG_MSIXTMSG_SHIFT 0
-#define I40E_VFMSIX_TMSG_MSIXTMSG_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TMSG_MSIXTMSG_SHIFT)
-#define I40E_VFMSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
-#define I40E_VFMSIX_TUADD_MAX_INDEX 16
-#define I40E_VFMSIX_TUADD_MSIXTUADD_SHIFT 0
-#define I40E_VFMSIX_TUADD_MSIXTUADD_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TUADD_MSIXTUADD_SHIFT)
-#define I40E_VFMSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
-#define I40E_VFMSIX_TVCTRL_MAX_INDEX 16
-#define I40E_VFMSIX_TVCTRL_MASK_SHIFT 0
-#define I40E_VFMSIX_TVCTRL_MASK_MASK I40E_MASK(0x1, I40E_VFMSIX_TVCTRL_MASK_SHIFT)
-#define I40E_VFCM_PE_ERRDATA 0x0000DC00 /* Reset: VFR */
-#define I40E_VFCM_PE_ERRDATA_ERROR_CODE_SHIFT 0
-#define I40E_VFCM_PE_ERRDATA_ERROR_CODE_MASK I40E_MASK(0xF, I40E_VFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
-#define I40E_VFCM_PE_ERRDATA_Q_TYPE_SHIFT 4
-#define I40E_VFCM_PE_ERRDATA_Q_TYPE_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRDATA_Q_TYPE_SHIFT)
-#define I40E_VFCM_PE_ERRDATA_Q_NUM_SHIFT 8
-#define I40E_VFCM_PE_ERRDATA_Q_NUM_MASK I40E_MASK(0x3FFFF, I40E_VFCM_PE_ERRDATA_Q_NUM_SHIFT)
-#define I40E_VFCM_PE_ERRINFO 0x0000D800 /* Reset: VFR */
-#define I40E_VFCM_PE_ERRINFO_ERROR_VALID_SHIFT 0
-#define I40E_VFCM_PE_ERRINFO_ERROR_VALID_MASK I40E_MASK(0x1, I40E_VFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
-#define I40E_VFCM_PE_ERRINFO_ERROR_INST_SHIFT 4
-#define I40E_VFCM_PE_ERRINFO_ERROR_INST_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRINFO_ERROR_INST_SHIFT)
-#define I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT 8
-#define I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
-#define I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT 16
-#define I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
-#define I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT 24
-#define I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
-#define I40E_VFQF_HENA(_i) (0x0000C400 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
-#define I40E_VFQF_HENA_MAX_INDEX 1
-#define I40E_VFQF_HENA_PTYPE_ENA_SHIFT 0
-#define I40E_VFQF_HENA_PTYPE_ENA_MASK I40E_MASK(0xFFFFFFFF, I40E_VFQF_HENA_PTYPE_ENA_SHIFT)
-#define I40E_VFQF_HKEY(_i) (0x0000CC00 + ((_i) * 4)) /* _i=0...12 */ /* Reset: CORER */
-#define I40E_VFQF_HKEY_MAX_INDEX 12
-#define I40E_VFQF_HKEY_KEY_0_SHIFT 0
-#define I40E_VFQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_0_SHIFT)
-#define I40E_VFQF_HKEY_KEY_1_SHIFT 8
-#define I40E_VFQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_1_SHIFT)
-#define I40E_VFQF_HKEY_KEY_2_SHIFT 16
-#define I40E_VFQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_2_SHIFT)
-#define I40E_VFQF_HKEY_KEY_3_SHIFT 24
-#define I40E_VFQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_3_SHIFT)
-#define I40E_VFQF_HLUT(_i) (0x0000D000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_VFQF_HLUT_MAX_INDEX 15
-#define I40E_VFQF_HLUT_LUT0_SHIFT 0
-#define I40E_VFQF_HLUT_LUT0_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT0_SHIFT)
-#define I40E_VFQF_HLUT_LUT1_SHIFT 8
-#define I40E_VFQF_HLUT_LUT1_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT1_SHIFT)
-#define I40E_VFQF_HLUT_LUT2_SHIFT 16
-#define I40E_VFQF_HLUT_LUT2_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT2_SHIFT)
-#define I40E_VFQF_HLUT_LUT3_SHIFT 24
-#define I40E_VFQF_HLUT_LUT3_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT3_SHIFT)
-#define I40E_VFQF_HREGION(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_VFQF_HREGION_MAX_INDEX 7
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_0_SHIFT 0
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_0_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
-#define I40E_VFQF_HREGION_REGION_0_SHIFT 1
-#define I40E_VFQF_HREGION_REGION_0_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_0_SHIFT)
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_1_SHIFT 4
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_1_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
-#define I40E_VFQF_HREGION_REGION_1_SHIFT 5
-#define I40E_VFQF_HREGION_REGION_1_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_1_SHIFT)
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_2_SHIFT 8
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_2_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
-#define I40E_VFQF_HREGION_REGION_2_SHIFT 9
-#define I40E_VFQF_HREGION_REGION_2_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_2_SHIFT)
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_3_SHIFT 12
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_3_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
-#define I40E_VFQF_HREGION_REGION_3_SHIFT 13
-#define I40E_VFQF_HREGION_REGION_3_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_3_SHIFT)
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_4_SHIFT 16
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_4_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
-#define I40E_VFQF_HREGION_REGION_4_SHIFT 17
-#define I40E_VFQF_HREGION_REGION_4_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_4_SHIFT)
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_5_SHIFT 20
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_5_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
-#define I40E_VFQF_HREGION_REGION_5_SHIFT 21
-#define I40E_VFQF_HREGION_REGION_5_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_5_SHIFT)
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_6_SHIFT 24
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_6_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
-#define I40E_VFQF_HREGION_REGION_6_SHIFT 25
-#define I40E_VFQF_HREGION_REGION_6_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_6_SHIFT)
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_7_SHIFT 28
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_7_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
-#define I40E_VFQF_HREGION_REGION_7_SHIFT 29
-#define I40E_VFQF_HREGION_REGION_7_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_7_SHIFT)
-#define I40E_MNGSB_FDCRC 0x000B7050 /* Reset: POR */
-#define I40E_MNGSB_FDCRC_CRC_RES_SHIFT 0
-#define I40E_MNGSB_FDCRC_CRC_RES_MASK I40E_MASK(0xFF, I40E_MNGSB_FDCRC_CRC_RES_SHIFT)
-#define I40E_MNGSB_FDCS 0x000B7040 /* Reset: POR */
-#define I40E_MNGSB_FDCS_CRC_CONT_SHIFT 2
-#define I40E_MNGSB_FDCS_CRC_CONT_MASK I40E_MASK(0x1, I40E_MNGSB_FDCS_CRC_CONT_SHIFT)
-#define I40E_MNGSB_FDCS_CRC_SEED_EN_SHIFT 3
-#define I40E_MNGSB_FDCS_CRC_SEED_EN_MASK I40E_MASK(0x1, I40E_MNGSB_FDCS_CRC_SEED_EN_SHIFT)
-#define I40E_MNGSB_FDCS_CRC_WR_INH_SHIFT 4
-#define I40E_MNGSB_FDCS_CRC_WR_INH_MASK I40E_MASK(0x1, I40E_MNGSB_FDCS_CRC_WR_INH_SHIFT)
-#define I40E_MNGSB_FDCS_CRC_SEED_SHIFT 8
-#define I40E_MNGSB_FDCS_CRC_SEED_MASK I40E_MASK(0xFF, I40E_MNGSB_FDCS_CRC_SEED_SHIFT)
-#define I40E_MNGSB_FDS 0x000B7048 /* Reset: POR */
-#define I40E_MNGSB_FDS_START_BC_SHIFT 0
-#define I40E_MNGSB_FDS_START_BC_MASK I40E_MASK(0xFFF, I40E_MNGSB_FDS_START_BC_SHIFT)
-#define I40E_MNGSB_FDS_LAST_BC_SHIFT 16
-#define I40E_MNGSB_FDS_LAST_BC_MASK I40E_MASK(0xFFF, I40E_MNGSB_FDS_LAST_BC_SHIFT)
-#define I40E_GL_VF_CTRL_RX(_VF) (0x00083600 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_GL_VF_CTRL_RX_MAX_INDEX 127
-#define I40E_GL_VF_CTRL_RX_AQ_RX_EN_SHIFT 0
-#define I40E_GL_VF_CTRL_RX_AQ_RX_EN_MASK I40E_MASK(0x1, I40E_GL_VF_CTRL_RX_AQ_RX_EN_SHIFT)
-#define I40E_GL_VF_CTRL_TX(_VF) (0x00083400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
-#define I40E_GL_VF_CTRL_TX_MAX_INDEX 127
-#define I40E_GL_VF_CTRL_TX_AQ_TX_EN_SHIFT 0
-#define I40E_GL_VF_CTRL_TX_AQ_TX_EN_MASK I40E_MASK(0x1, I40E_GL_VF_CTRL_TX_AQ_TX_EN_SHIFT)
-#define I40E_GLCM_LAN_CACHESIZE 0x0010C4D8 /* Reset: CORER */
-#define I40E_GLCM_LAN_CACHESIZE_WORD_SIZE_SHIFT 0
-#define I40E_GLCM_LAN_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFFF, I40E_GLCM_LAN_CACHESIZE_WORD_SIZE_SHIFT)
-#define I40E_GLCM_LAN_CACHESIZE_SETS_SHIFT 12
-#define I40E_GLCM_LAN_CACHESIZE_SETS_MASK I40E_MASK(0xF, I40E_GLCM_LAN_CACHESIZE_SETS_SHIFT)
-#define I40E_GLCM_LAN_CACHESIZE_WAYS_SHIFT 16
-#define I40E_GLCM_LAN_CACHESIZE_WAYS_MASK I40E_MASK(0x3FF, I40E_GLCM_LAN_CACHESIZE_WAYS_SHIFT)
-#define I40E_GLCM_PE_CACHESIZE 0x00138FE4 /* Reset: CORER */
-#define I40E_GLCM_PE_CACHESIZE_WORD_SIZE_SHIFT 0
-#define I40E_GLCM_PE_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFFF, I40E_GLCM_PE_CACHESIZE_WORD_SIZE_SHIFT)
-#define I40E_GLCM_PE_CACHESIZE_SETS_SHIFT 12
-#define I40E_GLCM_PE_CACHESIZE_SETS_MASK I40E_MASK(0xF, I40E_GLCM_PE_CACHESIZE_SETS_SHIFT)
-#define I40E_GLCM_PE_CACHESIZE_WAYS_SHIFT 16
-#define I40E_GLCM_PE_CACHESIZE_WAYS_MASK I40E_MASK(0x1FF, I40E_GLCM_PE_CACHESIZE_WAYS_SHIFT)
-#define I40E_PFCM_PE_ERRDATA 0x00138D00 /* Reset: PFR */
-#define I40E_PFCM_PE_ERRDATA_ERROR_CODE_SHIFT 0
-#define I40E_PFCM_PE_ERRDATA_ERROR_CODE_MASK I40E_MASK(0xF, I40E_PFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
-#define I40E_PFCM_PE_ERRDATA_Q_TYPE_SHIFT 4
-#define I40E_PFCM_PE_ERRDATA_Q_TYPE_MASK I40E_MASK(0x7, I40E_PFCM_PE_ERRDATA_Q_TYPE_SHIFT)
-#define I40E_PFCM_PE_ERRDATA_Q_NUM_SHIFT 8
-#define I40E_PFCM_PE_ERRDATA_Q_NUM_MASK I40E_MASK(0x3FFFF, I40E_PFCM_PE_ERRDATA_Q_NUM_SHIFT)
-#define I40E_PFCM_PE_ERRINFO 0x00138C80 /* Reset: PFR */
-#define I40E_PFCM_PE_ERRINFO_ERROR_VALID_SHIFT 0
-#define I40E_PFCM_PE_ERRINFO_ERROR_VALID_MASK I40E_MASK(0x1, I40E_PFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_ERROR_INST_SHIFT 4
-#define I40E_PFCM_PE_ERRINFO_ERROR_INST_MASK I40E_MASK(0x7, I40E_PFCM_PE_ERRINFO_ERROR_INST_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT 8
-#define I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT 16
-#define I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT 24
-#define I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
-#define I40E_PRTDCB_TFMSTC(_i) (0x000A0040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PRTDCB_TFMSTC_MAX_INDEX 7
-#define I40E_PRTDCB_TFMSTC_MSTC_SHIFT 0
-#define I40E_PRTDCB_TFMSTC_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TFMSTC_MSTC_SHIFT)
-#define I40E_GL_FWSTS_FWROWD_SHIFT 8
-#define I40E_GL_FWSTS_FWROWD_MASK I40E_MASK(0x1, I40E_GL_FWSTS_FWROWD_SHIFT)
-#define I40E_GLFOC_CACHESIZE 0x000AA0DC /* Reset: CORER */
-#define I40E_GLFOC_CACHESIZE_WORD_SIZE_SHIFT 0
-#define I40E_GLFOC_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFF, I40E_GLFOC_CACHESIZE_WORD_SIZE_SHIFT)
-#define I40E_GLFOC_CACHESIZE_SETS_SHIFT 8
-#define I40E_GLFOC_CACHESIZE_SETS_MASK I40E_MASK(0xFFF, I40E_GLFOC_CACHESIZE_SETS_SHIFT)
-#define I40E_GLFOC_CACHESIZE_WAYS_SHIFT 20
-#define I40E_GLFOC_CACHESIZE_WAYS_MASK I40E_MASK(0xF, I40E_GLFOC_CACHESIZE_WAYS_SHIFT)
-#define I40E_GLHMC_APBVTINUSEBASE(_i) (0x000C4a00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_APBVTINUSEBASE_MAX_INDEX 15
-#define I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT 0
-#define I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT)
-#define I40E_GLHMC_CEQPART(_i) (0x001312C0 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_CEQPART_MAX_INDEX 15
-#define I40E_GLHMC_CEQPART_PMCEQBASE_SHIFT 0
-#define I40E_GLHMC_CEQPART_PMCEQBASE_MASK I40E_MASK(0xFF, I40E_GLHMC_CEQPART_PMCEQBASE_SHIFT)
-#define I40E_GLHMC_CEQPART_PMCEQSIZE_SHIFT 16
-#define I40E_GLHMC_CEQPART_PMCEQSIZE_MASK I40E_MASK(0x1FF, I40E_GLHMC_CEQPART_PMCEQSIZE_SHIFT)
-#define I40E_GLHMC_DBCQMAX 0x000C20F0 /* Reset: CORER */
-#define I40E_GLHMC_DBCQMAX_GLHMC_DBCQMAX_SHIFT 0
-#define I40E_GLHMC_DBCQMAX_GLHMC_DBCQMAX_MASK I40E_MASK(0x3FFFF, I40E_GLHMC_DBCQMAX_GLHMC_DBCQMAX_SHIFT)
-#define I40E_GLHMC_DBCQPART(_i) (0x00131240 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_DBCQPART_MAX_INDEX 15
-#define I40E_GLHMC_DBCQPART_PMDBCQBASE_SHIFT 0
-#define I40E_GLHMC_DBCQPART_PMDBCQBASE_MASK I40E_MASK(0x3FFF, I40E_GLHMC_DBCQPART_PMDBCQBASE_SHIFT)
-#define I40E_GLHMC_DBCQPART_PMDBCQSIZE_SHIFT 16
-#define I40E_GLHMC_DBCQPART_PMDBCQSIZE_MASK I40E_MASK(0x7FFF, I40E_GLHMC_DBCQPART_PMDBCQSIZE_SHIFT)
-#define I40E_GLHMC_DBQPMAX 0x000C20EC /* Reset: CORER */
-#define I40E_GLHMC_DBQPMAX_GLHMC_DBQPMAX_SHIFT 0
-#define I40E_GLHMC_DBQPMAX_GLHMC_DBQPMAX_MASK I40E_MASK(0x7FFFF, I40E_GLHMC_DBQPMAX_GLHMC_DBQPMAX_SHIFT)
-#define I40E_GLHMC_DBQPPART(_i) (0x00138D80 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_DBQPPART_MAX_INDEX 15
-#define I40E_GLHMC_DBQPPART_PMDBQPBASE_SHIFT 0
-#define I40E_GLHMC_DBQPPART_PMDBQPBASE_MASK I40E_MASK(0x3FFF, I40E_GLHMC_DBQPPART_PMDBQPBASE_SHIFT)
-#define I40E_GLHMC_DBQPPART_PMDBQPSIZE_SHIFT 16
-#define I40E_GLHMC_DBQPPART_PMDBQPSIZE_MASK I40E_MASK(0x7FFF, I40E_GLHMC_DBQPPART_PMDBQPSIZE_SHIFT)
-#define I40E_GLHMC_PEARPBASE(_i) (0x000C4800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEARPBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEARPBASE_FPMPEARPBASE_SHIFT 0
-#define I40E_GLHMC_PEARPBASE_FPMPEARPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEARPBASE_FPMPEARPBASE_SHIFT)
-#define I40E_GLHMC_PEARPCNT(_i) (0x000C4900 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEARPCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEARPCNT_FPMPEARPCNT_SHIFT 0
-#define I40E_GLHMC_PEARPCNT_FPMPEARPCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEARPCNT_FPMPEARPCNT_SHIFT)
-#define I40E_GLHMC_PEARPMAX 0x000C2038 /* Reset: CORER */
-#define I40E_GLHMC_PEARPMAX_PMPEARPMAX_SHIFT 0
-#define I40E_GLHMC_PEARPMAX_PMPEARPMAX_MASK I40E_MASK(0x1FFFF, I40E_GLHMC_PEARPMAX_PMPEARPMAX_SHIFT)
-#define I40E_GLHMC_PEARPOBJSZ 0x000C2034 /* Reset: CORER */
-#define I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_MASK I40E_MASK(0x7, I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_SHIFT)
-#define I40E_GLHMC_PECQBASE(_i) (0x000C4200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PECQBASE_MAX_INDEX 15
-#define I40E_GLHMC_PECQBASE_FPMPECQBASE_SHIFT 0
-#define I40E_GLHMC_PECQBASE_FPMPECQBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PECQBASE_FPMPECQBASE_SHIFT)
-#define I40E_GLHMC_PECQCNT(_i) (0x000C4300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PECQCNT_MAX_INDEX 15
-#define I40E_GLHMC_PECQCNT_FPMPECQCNT_SHIFT 0
-#define I40E_GLHMC_PECQCNT_FPMPECQCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PECQCNT_FPMPECQCNT_SHIFT)
-#define I40E_GLHMC_PECQOBJSZ 0x000C2020 /* Reset: CORER */
-#define I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_SHIFT 0
-#define I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_SHIFT)
-#define I40E_GLHMC_PEHTCNT(_i) (0x000C4700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEHTCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEHTCNT_FPMPEHTCNT_SHIFT 0
-#define I40E_GLHMC_PEHTCNT_FPMPEHTCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEHTCNT_FPMPEHTCNT_SHIFT)
-#define I40E_GLHMC_PEHTEBASE(_i) (0x000C4600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEHTEBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_SHIFT 0
-#define I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_SHIFT)
-#define I40E_GLHMC_PEHTEOBJSZ 0x000C202c /* Reset: CORER */
-#define I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_SHIFT)
-#define I40E_GLHMC_PEHTMAX 0x000C2030 /* Reset: CORER */
-#define I40E_GLHMC_PEHTMAX_PMPEHTMAX_SHIFT 0
-#define I40E_GLHMC_PEHTMAX_PMPEHTMAX_MASK I40E_MASK(0x1FFFFF, I40E_GLHMC_PEHTMAX_PMPEHTMAX_SHIFT)
-#define I40E_GLHMC_PEMRBASE(_i) (0x000C4c00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEMRBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEMRBASE_FPMPEMRBASE_SHIFT 0
-#define I40E_GLHMC_PEMRBASE_FPMPEMRBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEMRBASE_FPMPEMRBASE_SHIFT)
-#define I40E_GLHMC_PEMRCNT(_i) (0x000C4d00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEMRCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEMRCNT_FPMPEMRSZ_SHIFT 0
-#define I40E_GLHMC_PEMRCNT_FPMPEMRSZ_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEMRCNT_FPMPEMRSZ_SHIFT)
-#define I40E_GLHMC_PEMRMAX 0x000C2040 /* Reset: CORER */
-#define I40E_GLHMC_PEMRMAX_PMPEMRMAX_SHIFT 0
-#define I40E_GLHMC_PEMRMAX_PMPEMRMAX_MASK I40E_MASK(0x7FFFFF, I40E_GLHMC_PEMRMAX_PMPEMRMAX_SHIFT)
-#define I40E_GLHMC_PEMROBJSZ 0x000C203c /* Reset: CORER */
-#define I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_SHIFT 0
-#define I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_SHIFT)
-#define I40E_GLHMC_PEPBLBASE(_i) (0x000C5800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEPBLBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_SHIFT 0
-#define I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_SHIFT)
-#define I40E_GLHMC_PEPBLCNT(_i) (0x000C5900 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEPBLCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_SHIFT 0
-#define I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_SHIFT)
-#define I40E_GLHMC_PEPBLMAX 0x000C206c /* Reset: CORER */
-#define I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_SHIFT 0
-#define I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_SHIFT)
-#define I40E_GLHMC_PEPFFIRSTSD 0x000C20E4 /* Reset: CORER */
-#define I40E_GLHMC_PEPFFIRSTSD_GLHMC_PEPFFIRSTSD_SHIFT 0
-#define I40E_GLHMC_PEPFFIRSTSD_GLHMC_PEPFFIRSTSD_MASK I40E_MASK(0xFFF, I40E_GLHMC_PEPFFIRSTSD_GLHMC_PEPFFIRSTSD_SHIFT)
-#define I40E_GLHMC_PEQ1BASE(_i) (0x000C5200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEQ1BASE_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_SHIFT 0
-#define I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_SHIFT)
-#define I40E_GLHMC_PEQ1CNT(_i) (0x000C5300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEQ1CNT_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_SHIFT 0
-#define I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_SHIFT)
-#define I40E_GLHMC_PEQ1FLBASE(_i) (0x000C5400 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEQ1FLBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_SHIFT 0
-#define I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_SHIFT)
-#define I40E_GLHMC_PEQ1FLMAX 0x000C2058 /* Reset: CORER */
-#define I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_SHIFT 0
-#define I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_MASK I40E_MASK(0x3FFFFFF, I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_SHIFT)
-#define I40E_GLHMC_PEQ1MAX 0x000C2054 /* Reset: CORER */
-#define I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_SHIFT 0
-#define I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_MASK I40E_MASK(0x3FFFFFF, I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_SHIFT)
-#define I40E_GLHMC_PEQ1OBJSZ 0x000C2050 /* Reset: CORER */
-#define I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_SHIFT 0
-#define I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_SHIFT)
-#define I40E_GLHMC_PEQPBASE(_i) (0x000C4000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEQPBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEQPBASE_FPMPEQPBASE_SHIFT 0
-#define I40E_GLHMC_PEQPBASE_FPMPEQPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEQPBASE_FPMPEQPBASE_SHIFT)
-#define I40E_GLHMC_PEQPCNT(_i) (0x000C4100 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEQPCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEQPCNT_FPMPEQPCNT_SHIFT 0
-#define I40E_GLHMC_PEQPCNT_FPMPEQPCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEQPCNT_FPMPEQPCNT_SHIFT)
-#define I40E_GLHMC_PEQPOBJSZ 0x000C201c /* Reset: CORER */
-#define I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_SHIFT)
-#define I40E_GLHMC_PESRQBASE(_i) (0x000C4400 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PESRQBASE_MAX_INDEX 15
-#define I40E_GLHMC_PESRQBASE_FPMPESRQBASE_SHIFT 0
-#define I40E_GLHMC_PESRQBASE_FPMPESRQBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PESRQBASE_FPMPESRQBASE_SHIFT)
-#define I40E_GLHMC_PESRQCNT(_i) (0x000C4500 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PESRQCNT_MAX_INDEX 15
-#define I40E_GLHMC_PESRQCNT_FPMPESRQCNT_SHIFT 0
-#define I40E_GLHMC_PESRQCNT_FPMPESRQCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PESRQCNT_FPMPESRQCNT_SHIFT)
-#define I40E_GLHMC_PESRQMAX 0x000C2028 /* Reset: CORER */
-#define I40E_GLHMC_PESRQMAX_PMPESRQMAX_SHIFT 0
-#define I40E_GLHMC_PESRQMAX_PMPESRQMAX_MASK I40E_MASK(0xFFFF, I40E_GLHMC_PESRQMAX_PMPESRQMAX_SHIFT)
-#define I40E_GLHMC_PESRQOBJSZ 0x000C2024 /* Reset: CORER */
-#define I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_SHIFT 0
-#define I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_SHIFT)
-#define I40E_GLHMC_PETIMERBASE(_i) (0x000C5A00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PETIMERBASE_MAX_INDEX 15
-#define I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_SHIFT 0
-#define I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_SHIFT)
-#define I40E_GLHMC_PETIMERCNT(_i) (0x000C5B00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PETIMERCNT_MAX_INDEX 15
-#define I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_SHIFT 0
-#define I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_SHIFT)
-#define I40E_GLHMC_PETIMERMAX 0x000C2084 /* Reset: CORER */
-#define I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_SHIFT 0
-#define I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_SHIFT)
-#define I40E_GLHMC_PETIMEROBJSZ 0x000C2080 /* Reset: CORER */
-#define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT 0
-#define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT)
-#define I40E_GLHMC_PEXFBASE(_i) (0x000C4e00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEXFBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT 0
-#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT)
-#define I40E_GLHMC_PEXFCNT(_i) (0x000C4f00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEXFCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT 0
-#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT)
-#define I40E_GLHMC_PEXFFLBASE(_i) (0x000C5000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PEXFFLBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT 0
-#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT)
-#define I40E_GLHMC_PEXFFLMAX 0x000C204c /* Reset: CORER */
-#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT 0
-#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_MASK I40E_MASK(0x1FFFFFF, I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT)
-#define I40E_GLHMC_PEXFMAX 0x000C2048 /* Reset: CORER */
-#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT 0
-#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_MASK I40E_MASK(0x3FFFFFF, I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT)
-#define I40E_GLHMC_PEXFOBJSZ 0x000C2044 /* Reset: CORER */
-#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT)
-#define I40E_GLHMC_PFPESDPART(_i) (0x000C0880 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLHMC_PFPESDPART_MAX_INDEX 15
-#define I40E_GLHMC_PFPESDPART_PMSDBASE_SHIFT 0
-#define I40E_GLHMC_PFPESDPART_PMSDBASE_MASK I40E_MASK(0xFFF, I40E_GLHMC_PFPESDPART_PMSDBASE_SHIFT)
-#define I40E_GLHMC_PFPESDPART_PMSDSIZE_SHIFT 16
-#define I40E_GLHMC_PFPESDPART_PMSDSIZE_MASK I40E_MASK(0x1FFF, I40E_GLHMC_PFPESDPART_PMSDSIZE_SHIFT)
-#define I40E_GLHMC_VFAPBVTINUSEBASE(_i) (0x000Cca00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFAPBVTINUSEBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT 0
-#define I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT)
-#define I40E_GLHMC_VFCEQPART(_i) (0x00132240 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFCEQPART_MAX_INDEX 31
-#define I40E_GLHMC_VFCEQPART_PMCEQBASE_SHIFT 0
-#define I40E_GLHMC_VFCEQPART_PMCEQBASE_MASK I40E_MASK(0xFF, I40E_GLHMC_VFCEQPART_PMCEQBASE_SHIFT)
-#define I40E_GLHMC_VFCEQPART_PMCEQSIZE_SHIFT 16
-#define I40E_GLHMC_VFCEQPART_PMCEQSIZE_MASK I40E_MASK(0x1FF, I40E_GLHMC_VFCEQPART_PMCEQSIZE_SHIFT)
-#define I40E_GLHMC_VFDBCQPART(_i) (0x00132140 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFDBCQPART_MAX_INDEX 31
-#define I40E_GLHMC_VFDBCQPART_PMDBCQBASE_SHIFT 0
-#define I40E_GLHMC_VFDBCQPART_PMDBCQBASE_MASK I40E_MASK(0x3FFF, I40E_GLHMC_VFDBCQPART_PMDBCQBASE_SHIFT)
-#define I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_SHIFT 16
-#define I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_MASK I40E_MASK(0x7FFF, I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_SHIFT)
-#define I40E_GLHMC_VFDBQPPART(_i) (0x00138E00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFDBQPPART_MAX_INDEX 31
-#define I40E_GLHMC_VFDBQPPART_PMDBQPBASE_SHIFT 0
-#define I40E_GLHMC_VFDBQPPART_PMDBQPBASE_MASK I40E_MASK(0x3FFF, I40E_GLHMC_VFDBQPPART_PMDBQPBASE_SHIFT)
-#define I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_SHIFT 16
-#define I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_MASK I40E_MASK(0x7FFF, I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_SHIFT)
-#define I40E_GLHMC_VFFSIAVBASE(_i) (0x000Cd600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFFSIAVBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_SHIFT 0
-#define I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_SHIFT)
-#define I40E_GLHMC_VFFSIAVCNT(_i) (0x000Cd700 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFFSIAVCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_SHIFT 0
-#define I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_SHIFT)
-#define I40E_GLHMC_VFPDINV(_i) (0x000C8300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPDINV_MAX_INDEX 31
-#define I40E_GLHMC_VFPDINV_PMSDIDX_SHIFT 0
-#define I40E_GLHMC_VFPDINV_PMSDIDX_MASK I40E_MASK(0xFFF, I40E_GLHMC_VFPDINV_PMSDIDX_SHIFT)
-#define I40E_GLHMC_VFPDINV_PMSDPARTSEL_SHIFT 15
-#define I40E_GLHMC_VFPDINV_PMSDPARTSEL_MASK I40E_MASK(0x1, I40E_GLHMC_VFPDINV_PMSDPARTSEL_SHIFT)
-#define I40E_GLHMC_VFPDINV_PMPDIDX_SHIFT 16
-#define I40E_GLHMC_VFPDINV_PMPDIDX_MASK I40E_MASK(0x1FF, I40E_GLHMC_VFPDINV_PMPDIDX_SHIFT)
-#define I40E_GLHMC_VFPEARPBASE(_i) (0x000Cc800 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEARPBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_SHIFT 0
-#define I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_SHIFT)
-#define I40E_GLHMC_VFPEARPCNT(_i) (0x000Cc900 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEARPCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_SHIFT 0
-#define I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_SHIFT)
-#define I40E_GLHMC_VFPECQBASE(_i) (0x000Cc200 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPECQBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPECQBASE_FPMPECQBASE_SHIFT 0
-#define I40E_GLHMC_VFPECQBASE_FPMPECQBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPECQBASE_FPMPECQBASE_SHIFT)
-#define I40E_GLHMC_VFPECQCNT(_i) (0x000Cc300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPECQCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPECQCNT_FPMPECQCNT_SHIFT 0
-#define I40E_GLHMC_VFPECQCNT_FPMPECQCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPECQCNT_FPMPECQCNT_SHIFT)
-#define I40E_GLHMC_VFPEHTCNT(_i) (0x000Cc700 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEHTCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_SHIFT 0
-#define I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_SHIFT)
-#define I40E_GLHMC_VFPEHTEBASE(_i) (0x000Cc600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEHTEBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_SHIFT 0
-#define I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_SHIFT)
-#define I40E_GLHMC_VFPEMRBASE(_i) (0x000Ccc00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEMRBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_SHIFT 0
-#define I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_SHIFT)
-#define I40E_GLHMC_VFPEMRCNT(_i) (0x000Ccd00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEMRCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_SHIFT 0
-#define I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_SHIFT)
-#define I40E_GLHMC_VFPEPBLBASE(_i) (0x000Cd800 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEPBLBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_SHIFT 0
-#define I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_SHIFT)
-#define I40E_GLHMC_VFPEPBLCNT(_i) (0x000Cd900 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEPBLCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_SHIFT 0
-#define I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_SHIFT)
-#define I40E_GLHMC_VFPEQ1BASE(_i) (0x000Cd200 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEQ1BASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_SHIFT 0
-#define I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_SHIFT)
-#define I40E_GLHMC_VFPEQ1CNT(_i) (0x000Cd300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEQ1CNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_SHIFT 0
-#define I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_SHIFT)
-#define I40E_GLHMC_VFPEQ1FLBASE(_i) (0x000Cd400 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEQ1FLBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_SHIFT 0
-#define I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_SHIFT)
-#define I40E_GLHMC_VFPEQPBASE(_i) (0x000Cc000 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEQPBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_SHIFT 0
-#define I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_SHIFT)
-#define I40E_GLHMC_VFPEQPCNT(_i) (0x000Cc100 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEQPCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_SHIFT 0
-#define I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_SHIFT)
-#define I40E_GLHMC_VFPESRQBASE(_i) (0x000Cc400 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPESRQBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_SHIFT 0
-#define I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_SHIFT)
-#define I40E_GLHMC_VFPESRQCNT(_i) (0x000Cc500 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPESRQCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_SHIFT 0
-#define I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_SHIFT)
-#define I40E_GLHMC_VFPETIMERBASE(_i) (0x000CDA00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPETIMERBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_SHIFT 0
-#define I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_SHIFT)
-#define I40E_GLHMC_VFPETIMERCNT(_i) (0x000CDB00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPETIMERCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT 0
-#define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT)
-#define I40E_GLHMC_VFPEXFBASE(_i) (0x000Cce00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEXFBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT 0
-#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT)
-#define I40E_GLHMC_VFPEXFCNT(_i) (0x000Ccf00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEXFCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT 0
-#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT)
-#define I40E_GLHMC_VFPEXFFLBASE(_i) (0x000Cd000 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFPEXFFLBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT 0
-#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT)
-#define I40E_GLHMC_VFSDPART(_i) (0x000C8800 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLHMC_VFSDPART_MAX_INDEX 31
-#define I40E_GLHMC_VFSDPART_PMSDBASE_SHIFT 0
-#define I40E_GLHMC_VFSDPART_PMSDBASE_MASK I40E_MASK(0xFFF, I40E_GLHMC_VFSDPART_PMSDBASE_SHIFT)
-#define I40E_GLHMC_VFSDPART_PMSDSIZE_SHIFT 16
-#define I40E_GLHMC_VFSDPART_PMSDSIZE_MASK I40E_MASK(0x1FFF, I40E_GLHMC_VFSDPART_PMSDSIZE_SHIFT)
-#define I40E_GLPBLOC_CACHESIZE 0x000A80BC /* Reset: CORER */
-#define I40E_GLPBLOC_CACHESIZE_WORD_SIZE_SHIFT 0
-#define I40E_GLPBLOC_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFF, I40E_GLPBLOC_CACHESIZE_WORD_SIZE_SHIFT)
-#define I40E_GLPBLOC_CACHESIZE_SETS_SHIFT 8
-#define I40E_GLPBLOC_CACHESIZE_SETS_MASK I40E_MASK(0xFFF, I40E_GLPBLOC_CACHESIZE_SETS_SHIFT)
-#define I40E_GLPBLOC_CACHESIZE_WAYS_SHIFT 20
-#define I40E_GLPBLOC_CACHESIZE_WAYS_MASK I40E_MASK(0xF, I40E_GLPBLOC_CACHESIZE_WAYS_SHIFT)
-#define I40E_GLPDOC_CACHESIZE 0x000D0088 /* Reset: CORER */
-#define I40E_GLPDOC_CACHESIZE_WORD_SIZE_SHIFT 0
-#define I40E_GLPDOC_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFF, I40E_GLPDOC_CACHESIZE_WORD_SIZE_SHIFT)
-#define I40E_GLPDOC_CACHESIZE_SETS_SHIFT 8
-#define I40E_GLPDOC_CACHESIZE_SETS_MASK I40E_MASK(0xFFF, I40E_GLPDOC_CACHESIZE_SETS_SHIFT)
-#define I40E_GLPDOC_CACHESIZE_WAYS_SHIFT 20
-#define I40E_GLPDOC_CACHESIZE_WAYS_MASK I40E_MASK(0xF, I40E_GLPDOC_CACHESIZE_WAYS_SHIFT)
-#define I40E_GLPEOC_CACHESIZE 0x000A60E8 /* Reset: CORER */
-#define I40E_GLPEOC_CACHESIZE_WORD_SIZE_SHIFT 0
-#define I40E_GLPEOC_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFF, I40E_GLPEOC_CACHESIZE_WORD_SIZE_SHIFT)
-#define I40E_GLPEOC_CACHESIZE_SETS_SHIFT 8
-#define I40E_GLPEOC_CACHESIZE_SETS_MASK I40E_MASK(0xFFF, I40E_GLPEOC_CACHESIZE_SETS_SHIFT)
-#define I40E_GLPEOC_CACHESIZE_WAYS_SHIFT 20
-#define I40E_GLPEOC_CACHESIZE_WAYS_MASK I40E_MASK(0xF, I40E_GLPEOC_CACHESIZE_WAYS_SHIFT)
-#define I40E_PFHMC_PDINV_PMSDPARTSEL_SHIFT 15
-#define I40E_PFHMC_PDINV_PMSDPARTSEL_MASK I40E_MASK(0x1, I40E_PFHMC_PDINV_PMSDPARTSEL_SHIFT)
-#define I40E_PFHMC_SDCMD_PMSDPARTSEL_SHIFT 15
-#define I40E_PFHMC_SDCMD_PMSDPARTSEL_MASK I40E_MASK(0x1, I40E_PFHMC_SDCMD_PMSDPARTSEL_SHIFT)
-#define I40E_GL_PPRS_SPARE 0x000856E0 /* Reset: CORER */
-#define I40E_GL_PPRS_SPARE_GL_PPRS_SPARE_SHIFT 0
-#define I40E_GL_PPRS_SPARE_GL_PPRS_SPARE_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_PPRS_SPARE_GL_PPRS_SPARE_SHIFT)
-#define I40E_GL_TLAN_SPARE 0x000E64E0 /* Reset: CORER */
-#define I40E_GL_TLAN_SPARE_GL_TLAN_SPARE_SHIFT 0
-#define I40E_GL_TLAN_SPARE_GL_TLAN_SPARE_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_TLAN_SPARE_GL_TLAN_SPARE_SHIFT)
-#define I40E_GL_TUPM_SPARE 0x000a2230 /* Reset: CORER */
-#define I40E_GL_TUPM_SPARE_GL_TUPM_SPARE_SHIFT 0
-#define I40E_GL_TUPM_SPARE_GL_TUPM_SPARE_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_TUPM_SPARE_GL_TUPM_SPARE_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG 0x000B81C0 /* Reset: POR */
-#define I40E_GLGEN_CAR_DEBUG_CAR_UPPER_CORE_CLK_EN_SHIFT 0
-#define I40E_GLGEN_CAR_DEBUG_CAR_UPPER_CORE_CLK_EN_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_UPPER_CORE_CLK_EN_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_HIU_CLK_EN_SHIFT 1
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_HIU_CLK_EN_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_HIU_CLK_EN_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_PE_CLK_EN_SHIFT 2
-#define I40E_GLGEN_CAR_DEBUG_CAR_PE_CLK_EN_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PE_CLK_EN_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_PRIM_CLK_ACTIVE_SHIFT 3
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_PRIM_CLK_ACTIVE_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_PRIM_CLK_ACTIVE_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CDC_PE_ACTIVE_SHIFT 4
-#define I40E_GLGEN_CAR_DEBUG_CDC_PE_ACTIVE_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CDC_PE_ACTIVE_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_PRST_RESET_N_SHIFT 5
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_PRST_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_PRST_RESET_N_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_SCLR_RESET_N_SHIFT 6
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_SCLR_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_SCLR_RESET_N_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IB_RESET_N_SHIFT 7
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IB_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IB_RESET_N_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IMIB_RESET_N_SHIFT 8
-#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IMIB_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IMIB_RESET_N_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_EMP_RESET_N_SHIFT 9
-#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_EMP_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_RAW_EMP_RESET_N_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_GLOBAL_RESET_N_SHIFT 10
-#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_GLOBAL_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_RAW_GLOBAL_RESET_N_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_LAN_POWER_GOOD_SHIFT 11
-#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_LAN_POWER_GOOD_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_RAW_LAN_POWER_GOOD_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_CDC_IOSF_PRIMERY_RST_B_SHIFT 12
-#define I40E_GLGEN_CAR_DEBUG_CDC_IOSF_PRIMERY_RST_B_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CDC_IOSF_PRIMERY_RST_B_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_GBE_GLOBALRST_B_SHIFT 13
-#define I40E_GLGEN_CAR_DEBUG_GBE_GLOBALRST_B_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_GBE_GLOBALRST_B_SHIFT)
-#define I40E_GLGEN_CAR_DEBUG_FLEEP_AL_GLOBR_DONE_SHIFT 14
-#define I40E_GLGEN_CAR_DEBUG_FLEEP_AL_GLOBR_DONE_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_FLEEP_AL_GLOBR_DONE_SHIFT)
-#define I40E_GLGEN_MISC_SPARE 0x000880E0 /* Reset: POR */
-#define I40E_GLGEN_MISC_SPARE_GLGEN_MISC_SPARE_SHIFT 0
-#define I40E_GLGEN_MISC_SPARE_GLGEN_MISC_SPARE_MASK I40E_MASK(0xFFFFFFFF, I40E_GLGEN_MISC_SPARE_GLGEN_MISC_SPARE_SHIFT)
-#define I40E_GL_UFUSE_SOC 0x000BE550 /* Reset: POR */
-#define I40E_GL_UFUSE_SOC_PORT_MODE_SHIFT 0
-#define I40E_GL_UFUSE_SOC_PORT_MODE_MASK I40E_MASK(0x3, I40E_GL_UFUSE_SOC_PORT_MODE_SHIFT)
-#define I40E_GL_UFUSE_SOC_NIC_ID_SHIFT 2
-#define I40E_GL_UFUSE_SOC_NIC_ID_MASK I40E_MASK(0x1, I40E_GL_UFUSE_SOC_NIC_ID_SHIFT)
-#define I40E_GL_UFUSE_SOC_SPARE_FUSES_SHIFT 3
-#define I40E_GL_UFUSE_SOC_SPARE_FUSES_MASK I40E_MASK(0x1FFF, I40E_GL_UFUSE_SOC_SPARE_FUSES_SHIFT)
#define I40E_PFINT_DYN_CTL0_WB_ON_ITR_SHIFT 30
#define I40E_PFINT_DYN_CTL0_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_WB_ON_ITR_SHIFT)
#define I40E_PFINT_DYN_CTLN_WB_ON_ITR_SHIFT 30
#define I40E_PFINT_DYN_CTLN_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_WB_ON_ITR_SHIFT)
-#define I40E_VFINT_DYN_CTL0_WB_ON_ITR_SHIFT 30
-#define I40E_VFINT_DYN_CTL0_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_WB_ON_ITR_SHIFT)
-#define I40E_VFINT_DYN_CTLN_WB_ON_ITR_SHIFT 30
-#define I40E_VFINT_DYN_CTLN_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_WB_ON_ITR_SHIFT)
-#define I40E_VPLAN_QBASE(_VF) (0x00074800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VPLAN_QBASE_MAX_INDEX 127
-#define I40E_VPLAN_QBASE_VFFIRSTQ_SHIFT 0
-#define I40E_VPLAN_QBASE_VFFIRSTQ_MASK I40E_MASK(0x7FF, I40E_VPLAN_QBASE_VFFIRSTQ_SHIFT)
-#define I40E_VPLAN_QBASE_VFNUMQ_SHIFT 11
-#define I40E_VPLAN_QBASE_VFNUMQ_MASK I40E_MASK(0xFF, I40E_VPLAN_QBASE_VFNUMQ_SHIFT)
-#define I40E_VPLAN_QBASE_VFQTABLE_ENA_SHIFT 31
-#define I40E_VPLAN_QBASE_VFQTABLE_ENA_MASK I40E_MASK(0x1, I40E_VPLAN_QBASE_VFQTABLE_ENA_SHIFT)
-#define I40E_PRTMAC_LINK_DOWN_COUNTER 0x001E2440 /* Reset: GLOBR */
-#define I40E_PRTMAC_LINK_DOWN_COUNTER_LINK_DOWN_COUNTER_SHIFT 0
-#define I40E_PRTMAC_LINK_DOWN_COUNTER_LINK_DOWN_COUNTER_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_LINK_DOWN_COUNTER_LINK_DOWN_COUNTER_SHIFT)
-#define I40E_GLNVM_AL_REQ 0x000B6164 /* Reset: POR */
-#define I40E_GLNVM_AL_REQ_POR_SHIFT 0
-#define I40E_GLNVM_AL_REQ_POR_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_POR_SHIFT)
-#define I40E_GLNVM_AL_REQ_PCIE_IMIB_SHIFT 1
-#define I40E_GLNVM_AL_REQ_PCIE_IMIB_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_PCIE_IMIB_SHIFT)
-#define I40E_GLNVM_AL_REQ_GLOBR_SHIFT 2
-#define I40E_GLNVM_AL_REQ_GLOBR_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_GLOBR_SHIFT)
-#define I40E_GLNVM_AL_REQ_CORER_SHIFT 3
-#define I40E_GLNVM_AL_REQ_CORER_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_CORER_SHIFT)
-#define I40E_GLNVM_AL_REQ_PE_SHIFT 4
-#define I40E_GLNVM_AL_REQ_PE_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_PE_SHIFT)
-#define I40E_GLNVM_AL_REQ_PCIE_IMIB_ASSERT_SHIFT 5
-#define I40E_GLNVM_AL_REQ_PCIE_IMIB_ASSERT_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_PCIE_IMIB_ASSERT_SHIFT)
-#define I40E_GLNVM_ALTIMERS 0x000B6140 /* Reset: POR */
-#define I40E_GLNVM_ALTIMERS_PCI_ALTIMER_SHIFT 0
-#define I40E_GLNVM_ALTIMERS_PCI_ALTIMER_MASK I40E_MASK(0xFFF, I40E_GLNVM_ALTIMERS_PCI_ALTIMER_SHIFT)
-#define I40E_GLNVM_ALTIMERS_GEN_ALTIMER_SHIFT 12
-#define I40E_GLNVM_ALTIMERS_GEN_ALTIMER_MASK I40E_MASK(0xFFFFF, I40E_GLNVM_ALTIMERS_GEN_ALTIMER_SHIFT)
#define I40E_GLNVM_FLA 0x000B6108 /* Reset: POR */
#define I40E_GLNVM_FLA_LOCKED_SHIFT 6
#define I40E_GLNVM_FLA_LOCKED_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_LOCKED_SHIFT)
#define I40E_GLNVM_ULD 0x000B6008 /* Reset: POR */
-#define I40E_GLNVM_ULD_PCIER_DONE_SHIFT 0
-#define I40E_GLNVM_ULD_PCIER_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_PCIER_DONE_SHIFT)
-#define I40E_GLNVM_ULD_PCIER_DONE_1_SHIFT 1
-#define I40E_GLNVM_ULD_PCIER_DONE_1_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_PCIER_DONE_1_SHIFT)
-#define I40E_GLNVM_ULD_CORER_DONE_SHIFT 3
-#define I40E_GLNVM_ULD_CORER_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CORER_DONE_SHIFT)
-#define I40E_GLNVM_ULD_GLOBR_DONE_SHIFT 4
-#define I40E_GLNVM_ULD_GLOBR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_GLOBR_DONE_SHIFT)
-#define I40E_GLNVM_ULD_POR_DONE_SHIFT 5
-#define I40E_GLNVM_ULD_POR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_POR_DONE_SHIFT)
-#define I40E_GLNVM_ULD_POR_DONE_1_SHIFT 8
-#define I40E_GLNVM_ULD_POR_DONE_1_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_POR_DONE_1_SHIFT)
-#define I40E_GLNVM_ULD_PCIER_DONE_2_SHIFT 9
-#define I40E_GLNVM_ULD_PCIER_DONE_2_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_PCIER_DONE_2_SHIFT)
-#define I40E_GLNVM_ULD_PE_DONE_SHIFT 10
-#define I40E_GLNVM_ULD_PE_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_PE_DONE_SHIFT)
-#define I40E_GLNVM_ULT 0x000B6154 /* Reset: POR */
-#define I40E_GLNVM_ULT_CONF_PCIR_AE_SHIFT 0
-#define I40E_GLNVM_ULT_CONF_PCIR_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_PCIR_AE_SHIFT)
-#define I40E_GLNVM_ULT_CONF_PCIRTL_AE_SHIFT 1
-#define I40E_GLNVM_ULT_CONF_PCIRTL_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_PCIRTL_AE_SHIFT)
-#define I40E_GLNVM_ULT_RESERVED_1_SHIFT 2
-#define I40E_GLNVM_ULT_RESERVED_1_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_RESERVED_1_SHIFT)
-#define I40E_GLNVM_ULT_CONF_CORE_AE_SHIFT 3
-#define I40E_GLNVM_ULT_CONF_CORE_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_CORE_AE_SHIFT)
-#define I40E_GLNVM_ULT_CONF_GLOBAL_AE_SHIFT 4
-#define I40E_GLNVM_ULT_CONF_GLOBAL_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_GLOBAL_AE_SHIFT)
-#define I40E_GLNVM_ULT_CONF_POR_AE_SHIFT 5
-#define I40E_GLNVM_ULT_CONF_POR_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_POR_AE_SHIFT)
-#define I40E_GLNVM_ULT_RESERVED_2_SHIFT 6
-#define I40E_GLNVM_ULT_RESERVED_2_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_RESERVED_2_SHIFT)
-#define I40E_GLNVM_ULT_RESERVED_3_SHIFT 7
-#define I40E_GLNVM_ULT_RESERVED_3_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_RESERVED_3_SHIFT)
-#define I40E_GLNVM_ULT_CONF_EMP_AE_SHIFT 8
-#define I40E_GLNVM_ULT_CONF_EMP_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_EMP_AE_SHIFT)
-#define I40E_GLNVM_ULT_CONF_PCIALT_AE_SHIFT 9
-#define I40E_GLNVM_ULT_CONF_PCIALT_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_PCIALT_AE_SHIFT)
-#define I40E_GLNVM_ULT_RESERVED_4_SHIFT 10
-#define I40E_GLNVM_ULT_RESERVED_4_MASK I40E_MASK(0x3FFFFF, I40E_GLNVM_ULT_RESERVED_4_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT 0x000B615C /* Reset: POR */
-#define I40E_MEM_INIT_DONE_STAT_CMLAN_MEM_INIT_DONE_SHIFT 0
-#define I40E_MEM_INIT_DONE_STAT_CMLAN_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_CMLAN_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_PMAT_MEM_INIT_DONE_SHIFT 1
-#define I40E_MEM_INIT_DONE_STAT_PMAT_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_PMAT_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_RCU_MEM_INIT_DONE_SHIFT 2
-#define I40E_MEM_INIT_DONE_STAT_RCU_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RCU_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_TDPU_MEM_INIT_DONE_SHIFT 3
-#define I40E_MEM_INIT_DONE_STAT_TDPU_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TDPU_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_TLAN_MEM_INIT_DONE_SHIFT 4
-#define I40E_MEM_INIT_DONE_STAT_TLAN_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TLAN_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_RLAN_MEM_INIT_DONE_SHIFT 5
-#define I40E_MEM_INIT_DONE_STAT_RLAN_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RLAN_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_RDPU_MEM_INIT_DONE_SHIFT 6
-#define I40E_MEM_INIT_DONE_STAT_RDPU_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RDPU_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_PPRS_MEM_INIT_DONE_SHIFT 7
-#define I40E_MEM_INIT_DONE_STAT_PPRS_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_PPRS_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_RPB_MEM_INIT_DONE_SHIFT 8
-#define I40E_MEM_INIT_DONE_STAT_RPB_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RPB_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_TPB_MEM_INIT_DONE_SHIFT 9
-#define I40E_MEM_INIT_DONE_STAT_TPB_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TPB_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_FOC_MEM_INIT_DONE_SHIFT 10
-#define I40E_MEM_INIT_DONE_STAT_FOC_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_FOC_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_TSCD_MEM_INIT_DONE_SHIFT 11
-#define I40E_MEM_INIT_DONE_STAT_TSCD_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TSCD_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_TCB_MEM_INIT_DONE_SHIFT 12
-#define I40E_MEM_INIT_DONE_STAT_TCB_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TCB_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_RCB_MEM_INIT_DONE_SHIFT 13
-#define I40E_MEM_INIT_DONE_STAT_RCB_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RCB_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_WUC_MEM_INIT_DONE_SHIFT 14
-#define I40E_MEM_INIT_DONE_STAT_WUC_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_WUC_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_STAT_MEM_INIT_DONE_SHIFT 15
-#define I40E_MEM_INIT_DONE_STAT_STAT_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_STAT_MEM_INIT_DONE_SHIFT)
-#define I40E_MEM_INIT_DONE_STAT_ITR_MEM_INIT_DONE_SHIFT 16
-#define I40E_MEM_INIT_DONE_STAT_ITR_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_ITR_MEM_INIT_DONE_SHIFT)
-#define I40E_MNGSB_DADD 0x000B7030 /* Reset: POR */
-#define I40E_MNGSB_DADD_ADDR_SHIFT 0
-#define I40E_MNGSB_DADD_ADDR_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_DADD_ADDR_SHIFT)
-#define I40E_MNGSB_DCNT 0x000B7034 /* Reset: POR */
-#define I40E_MNGSB_DCNT_BYTE_CNT_SHIFT 0
-#define I40E_MNGSB_DCNT_BYTE_CNT_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_DCNT_BYTE_CNT_SHIFT)
-#define I40E_MNGSB_MSGCTL 0x000B7020 /* Reset: POR */
-#define I40E_MNGSB_MSGCTL_HDR_DWS_SHIFT 0
-#define I40E_MNGSB_MSGCTL_HDR_DWS_MASK I40E_MASK(0x3, I40E_MNGSB_MSGCTL_HDR_DWS_SHIFT)
-#define I40E_MNGSB_MSGCTL_EXP_RDW_SHIFT 8
-#define I40E_MNGSB_MSGCTL_EXP_RDW_MASK I40E_MASK(0x1FF, I40E_MNGSB_MSGCTL_EXP_RDW_SHIFT)
-#define I40E_MNGSB_MSGCTL_MSG_MODE_SHIFT 26
-#define I40E_MNGSB_MSGCTL_MSG_MODE_MASK I40E_MASK(0x3, I40E_MNGSB_MSGCTL_MSG_MODE_SHIFT)
-#define I40E_MNGSB_MSGCTL_TOKEN_MODE_SHIFT 28
-#define I40E_MNGSB_MSGCTL_TOKEN_MODE_MASK I40E_MASK(0x3, I40E_MNGSB_MSGCTL_TOKEN_MODE_SHIFT)
-#define I40E_MNGSB_MSGCTL_BARCLR_SHIFT 30
-#define I40E_MNGSB_MSGCTL_BARCLR_MASK I40E_MASK(0x1, I40E_MNGSB_MSGCTL_BARCLR_SHIFT)
-#define I40E_MNGSB_MSGCTL_CMDV_SHIFT 31
-#define I40E_MNGSB_MSGCTL_CMDV_MASK I40E_MASK(0x1, I40E_MNGSB_MSGCTL_CMDV_SHIFT)
-#define I40E_MNGSB_RDATA 0x000B7300 /* Reset: POR */
-#define I40E_MNGSB_RDATA_DATA_SHIFT 0
-#define I40E_MNGSB_RDATA_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_RDATA_DATA_SHIFT)
-#define I40E_MNGSB_RHDR0 0x000B72FC /* Reset: POR */
-#define I40E_MNGSB_RHDR0_DESTINATION_SHIFT 0
-#define I40E_MNGSB_RHDR0_DESTINATION_MASK I40E_MASK(0xFF, I40E_MNGSB_RHDR0_DESTINATION_SHIFT)
-#define I40E_MNGSB_RHDR0_SOURCE_SHIFT 8
-#define I40E_MNGSB_RHDR0_SOURCE_MASK I40E_MASK(0xFF, I40E_MNGSB_RHDR0_SOURCE_SHIFT)
-#define I40E_MNGSB_RHDR0_OPCODE_SHIFT 16
-#define I40E_MNGSB_RHDR0_OPCODE_MASK I40E_MASK(0xFF, I40E_MNGSB_RHDR0_OPCODE_SHIFT)
-#define I40E_MNGSB_RHDR0_TAG_SHIFT 24
-#define I40E_MNGSB_RHDR0_TAG_MASK I40E_MASK(0x7, I40E_MNGSB_RHDR0_TAG_SHIFT)
-#define I40E_MNGSB_RHDR0_RESPONSE_SHIFT 27
-#define I40E_MNGSB_RHDR0_RESPONSE_MASK I40E_MASK(0x7, I40E_MNGSB_RHDR0_RESPONSE_SHIFT)
-#define I40E_MNGSB_RHDR0_EH_SHIFT 31
-#define I40E_MNGSB_RHDR0_EH_MASK I40E_MASK(0x1, I40E_MNGSB_RHDR0_EH_SHIFT)
-#define I40E_MNGSB_RSPCTL 0x000B7024 /* Reset: POR */
-#define I40E_MNGSB_RSPCTL_DMA_MSG_DWORDS_SHIFT 0
-#define I40E_MNGSB_RSPCTL_DMA_MSG_DWORDS_MASK I40E_MASK(0x1FF, I40E_MNGSB_RSPCTL_DMA_MSG_DWORDS_SHIFT)
-#define I40E_MNGSB_RSPCTL_RSP_MODE_SHIFT 26
-#define I40E_MNGSB_RSPCTL_RSP_MODE_MASK I40E_MASK(0x3, I40E_MNGSB_RSPCTL_RSP_MODE_SHIFT)
-#define I40E_MNGSB_RSPCTL_RSP_BAD_LEN_SHIFT 30
-#define I40E_MNGSB_RSPCTL_RSP_BAD_LEN_MASK I40E_MASK(0x1, I40E_MNGSB_RSPCTL_RSP_BAD_LEN_SHIFT)
-#define I40E_MNGSB_RSPCTL_RSP_ERR_SHIFT 31
-#define I40E_MNGSB_RSPCTL_RSP_ERR_MASK I40E_MASK(0x1, I40E_MNGSB_RSPCTL_RSP_ERR_SHIFT)
-#define I40E_MNGSB_WDATA 0x000B7100 /* Reset: POR */
-#define I40E_MNGSB_WDATA_DATA_SHIFT 0
-#define I40E_MNGSB_WDATA_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_WDATA_DATA_SHIFT)
-#define I40E_MNGSB_WHDR0 0x000B70F4 /* Reset: POR */
-#define I40E_MNGSB_WHDR0_RAW_DEST_SHIFT 0
-#define I40E_MNGSB_WHDR0_RAW_DEST_MASK I40E_MASK(0xFF, I40E_MNGSB_WHDR0_RAW_DEST_SHIFT)
-#define I40E_MNGSB_WHDR0_DEST_SEL_SHIFT 12
-#define I40E_MNGSB_WHDR0_DEST_SEL_MASK I40E_MASK(0xF, I40E_MNGSB_WHDR0_DEST_SEL_SHIFT)
-#define I40E_MNGSB_WHDR0_OPCODE_SEL_SHIFT 16
-#define I40E_MNGSB_WHDR0_OPCODE_SEL_MASK I40E_MASK(0xFF, I40E_MNGSB_WHDR0_OPCODE_SEL_SHIFT)
-#define I40E_MNGSB_WHDR0_TAG_SHIFT 24
-#define I40E_MNGSB_WHDR0_TAG_MASK I40E_MASK(0x7F, I40E_MNGSB_WHDR0_TAG_SHIFT)
-#define I40E_MNGSB_WHDR1 0x000B70F8 /* Reset: POR */
-#define I40E_MNGSB_WHDR1_ADDR_SHIFT 0
-#define I40E_MNGSB_WHDR1_ADDR_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_WHDR1_ADDR_SHIFT)
-#define I40E_MNGSB_WHDR2 0x000B70FC /* Reset: POR */
-#define I40E_MNGSB_WHDR2_LENGTH_SHIFT 0
-#define I40E_MNGSB_WHDR2_LENGTH_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_WHDR2_LENGTH_SHIFT)
-#define I40E_GLPCI_CAPSUP_WAKUP_EN_SHIFT 21
-#define I40E_GLPCI_CAPSUP_WAKUP_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_WAKUP_EN_SHIFT)
-#define I40E_GLPCI_CUR_CLNT_COMMON 0x0009CA18 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_CLNT_COMMON_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_CLNT_COMMON_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_CLNT_COMMON_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_CLNT_COMMON_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_CLNT_COMMON_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_CLNT_COMMON_OSR_SHIFT)
-#define I40E_GLPCI_CUR_CLNT_PIPEMON 0x0009CA20 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_CLNT_PIPEMON_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_CLNT_PIPEMON_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_CLNT_PIPEMON_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_MNG_ALWD 0x0009c514 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_MNG_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_MNG_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_MNG_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_MNG_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_MNG_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_MNG_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_MNG_RSVD 0x0009c594 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_MNG_RSVD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_MNG_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_MNG_RSVD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_MNG_RSVD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_MNG_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_MNG_RSVD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_PMAT_ALWD 0x0009c510 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_PMAT_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_PMAT_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_PMAT_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_PMAT_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_PMAT_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_PMAT_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_PMAT_RSVD 0x0009c590 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_PMAT_RSVD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_PMAT_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_PMAT_RSVD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_PMAT_RSVD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_PMAT_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_PMAT_RSVD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_RLAN_ALWD 0x0009c500 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_RLAN_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_RLAN_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RLAN_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_RLAN_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_RLAN_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RLAN_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_RLAN_RSVD 0x0009c580 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_RLAN_RSVD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_RLAN_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RLAN_RSVD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_RLAN_RSVD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_RLAN_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RLAN_RSVD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_RXPE_ALWD 0x0009c508 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_RXPE_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_RXPE_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RXPE_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_RXPE_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_RXPE_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RXPE_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_RXPE_RSVD 0x0009c588 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_RXPE_RSVD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_RXPE_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RXPE_RSVD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_RXPE_RSVD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_RXPE_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RXPE_RSVD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_TDPU_ALWD 0x0009c518 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_TDPU_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_TDPU_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TDPU_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_TDPU_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_TDPU_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TDPU_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_TDPU_RSVD 0x0009c598 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_TDPU_RSVD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_TDPU_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TDPU_RSVD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_TDPU_RSVD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_TDPU_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TDPU_RSVD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_TLAN_ALWD 0x0009c504 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_TLAN_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_TLAN_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TLAN_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_TLAN_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_TLAN_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TLAN_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_TLAN_RSVD 0x0009c584 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_TLAN_RSVD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_TLAN_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TLAN_RSVD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_TLAN_RSVD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_TLAN_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TLAN_RSVD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_TXPE_ALWD 0x0009c50C /* Reset: PCIR */
-#define I40E_GLPCI_CUR_TXPE_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_TXPE_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TXPE_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_TXPE_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_TXPE_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TXPE_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_TXPE_RSVD 0x0009c58c /* Reset: PCIR */
-#define I40E_GLPCI_CUR_TXPE_RSVD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_TXPE_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TXPE_RSVD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_TXPE_RSVD_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_TXPE_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TXPE_RSVD_OSR_SHIFT)
-#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON 0x0009CA28 /* Reset: PCIR */
-#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_WATMK_CLNT_COMMON_DATA_LINES_SHIFT)
-#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON_OSR_SHIFT 16
-#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_WATMK_CLNT_COMMON_OSR_SHIFT)
-#define I40E_GLPCI_LBARCTRL_PE_DB_SIZE_SHIFT 4
-#define I40E_GLPCI_LBARCTRL_PE_DB_SIZE_MASK I40E_MASK(0x3, I40E_GLPCI_LBARCTRL_PE_DB_SIZE_SHIFT)
-#define I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_SHIFT 10
-#define I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_SHIFT)
-#define I40E_GLPCI_NPQ_CFG 0x0009CA00 /* Reset: PCIR */
-#define I40E_GLPCI_NPQ_CFG_EXTEND_TO_SHIFT 0
-#define I40E_GLPCI_NPQ_CFG_EXTEND_TO_MASK I40E_MASK(0x1, I40E_GLPCI_NPQ_CFG_EXTEND_TO_SHIFT)
-#define I40E_GLPCI_NPQ_CFG_SMALL_TO_SHIFT 1
-#define I40E_GLPCI_NPQ_CFG_SMALL_TO_MASK I40E_MASK(0x1, I40E_GLPCI_NPQ_CFG_SMALL_TO_SHIFT)
-#define I40E_GLPCI_NPQ_CFG_WEIGHT_AVG_SHIFT 2
-#define I40E_GLPCI_NPQ_CFG_WEIGHT_AVG_MASK I40E_MASK(0xF, I40E_GLPCI_NPQ_CFG_WEIGHT_AVG_SHIFT)
-#define I40E_GLPCI_NPQ_CFG_NPQ_SPARE_SHIFT 6
-#define I40E_GLPCI_NPQ_CFG_NPQ_SPARE_MASK I40E_MASK(0x3FF, I40E_GLPCI_NPQ_CFG_NPQ_SPARE_SHIFT)
-#define I40E_GLPCI_NPQ_CFG_NPQ_ERR_STAT_SHIFT 16
-#define I40E_GLPCI_NPQ_CFG_NPQ_ERR_STAT_MASK I40E_MASK(0xF, I40E_GLPCI_NPQ_CFG_NPQ_ERR_STAT_SHIFT)
-#define I40E_GLPCI_WATMK_CLNT_PIPEMON 0x0009CA30 /* Reset: PCIR */
-#define I40E_GLPCI_WATMK_CLNT_PIPEMON_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_WATMK_CLNT_PIPEMON_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_CLNT_PIPEMON_DATA_LINES_SHIFT)
-#define I40E_GLPCI_WATMK_MNG_ALWD 0x0009CB14 /* Reset: PCIR */
-#define I40E_GLPCI_WATMK_MNG_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_WATMK_MNG_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_MNG_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_WATMK_MNG_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_WATMK_MNG_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_MNG_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_WATMK_PMAT_ALWD 0x0009CB10 /* Reset: PCIR */
-#define I40E_GLPCI_WATMK_PMAT_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_WATMK_PMAT_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_PMAT_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_WATMK_PMAT_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_WATMK_PMAT_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_PMAT_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_WATMK_RLAN_ALWD 0x0009CB00 /* Reset: PCIR */
-#define I40E_GLPCI_WATMK_RLAN_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_WATMK_RLAN_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_RLAN_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_WATMK_RLAN_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_WATMK_RLAN_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_RLAN_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_WATMK_RXPE_ALWD 0x0009CB08 /* Reset: PCIR */
-#define I40E_GLPCI_WATMK_RXPE_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_WATMK_RXPE_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_RXPE_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_WATMK_RXPE_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_WATMK_RXPE_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_RXPE_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_WATMK_TLAN_ALWD 0x0009CB04 /* Reset: PCIR */
-#define I40E_GLPCI_WATMK_TLAN_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_WATMK_TLAN_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TLAN_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_WATMK_TLAN_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_WATMK_TLAN_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TLAN_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_WATMK_TPDU_ALWD 0x0009CB18 /* Reset: PCIR */
-#define I40E_GLPCI_WATMK_TPDU_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_WATMK_TPDU_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TPDU_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_WATMK_TPDU_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_WATMK_TPDU_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TPDU_ALWD_OSR_SHIFT)
-#define I40E_GLPCI_WATMK_TXPE_ALWD 0x0009CB0c /* Reset: PCIR */
-#define I40E_GLPCI_WATMK_TXPE_ALWD_DATA_LINES_SHIFT 0
-#define I40E_GLPCI_WATMK_TXPE_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TXPE_ALWD_DATA_LINES_SHIFT)
-#define I40E_GLPCI_WATMK_TXPE_ALWD_OSR_SHIFT 16
-#define I40E_GLPCI_WATMK_TXPE_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TXPE_ALWD_OSR_SHIFT)
-#define I40E_GLPE_CPUSTATUS0 0x0000D040 /* Reset: PE_CORER */
-#define I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_SHIFT 0
-#define I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_SHIFT)
-#define I40E_GLPE_CPUSTATUS1 0x0000D044 /* Reset: PE_CORER */
-#define I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_SHIFT 0
-#define I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_SHIFT)
-#define I40E_GLPE_CPUSTATUS2 0x0000D048 /* Reset: PE_CORER */
-#define I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_SHIFT 0
-#define I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_SHIFT)
-#define I40E_GLPE_CPUTRIG0 0x0000D060 /* Reset: PE_CORER */
-#define I40E_GLPE_CPUTRIG0_PECPUTRIG0_SHIFT 0
-#define I40E_GLPE_CPUTRIG0_PECPUTRIG0_MASK I40E_MASK(0xFFFF, I40E_GLPE_CPUTRIG0_PECPUTRIG0_SHIFT)
-#define I40E_GLPE_CPUTRIG0_TEPREQUEST0_SHIFT 17
-#define I40E_GLPE_CPUTRIG0_TEPREQUEST0_MASK I40E_MASK(0x1, I40E_GLPE_CPUTRIG0_TEPREQUEST0_SHIFT)
-#define I40E_GLPE_CPUTRIG0_OOPREQUEST0_SHIFT 18
-#define I40E_GLPE_CPUTRIG0_OOPREQUEST0_MASK I40E_MASK(0x1, I40E_GLPE_CPUTRIG0_OOPREQUEST0_SHIFT)
-#define I40E_GLPE_DUAL40_RUPM 0x0000DA04 /* Reset: PE_CORER */
-#define I40E_GLPE_DUAL40_RUPM_DUAL_40G_MODE_SHIFT 0
-#define I40E_GLPE_DUAL40_RUPM_DUAL_40G_MODE_MASK I40E_MASK(0x1, I40E_GLPE_DUAL40_RUPM_DUAL_40G_MODE_SHIFT)
-#define I40E_GLPE_PFAEQEDROPCNT(_i) (0x00131440 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLPE_PFAEQEDROPCNT_MAX_INDEX 15
-#define I40E_GLPE_PFAEQEDROPCNT_AEQEDROPCNT_SHIFT 0
-#define I40E_GLPE_PFAEQEDROPCNT_AEQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_PFAEQEDROPCNT_AEQEDROPCNT_SHIFT)
-#define I40E_GLPE_PFCEQEDROPCNT(_i) (0x001313C0 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLPE_PFCEQEDROPCNT_MAX_INDEX 15
-#define I40E_GLPE_PFCEQEDROPCNT_CEQEDROPCNT_SHIFT 0
-#define I40E_GLPE_PFCEQEDROPCNT_CEQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_PFCEQEDROPCNT_CEQEDROPCNT_SHIFT)
-#define I40E_GLPE_PFCQEDROPCNT(_i) (0x00131340 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
-#define I40E_GLPE_PFCQEDROPCNT_MAX_INDEX 15
-#define I40E_GLPE_PFCQEDROPCNT_CQEDROPCNT_SHIFT 0
-#define I40E_GLPE_PFCQEDROPCNT_CQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_PFCQEDROPCNT_CQEDROPCNT_SHIFT)
-#define I40E_GLPE_RUPM_CQPPOOL 0x0000DACC /* Reset: PE_CORER */
-#define I40E_GLPE_RUPM_CQPPOOL_CQPSPADS_SHIFT 0
-#define I40E_GLPE_RUPM_CQPPOOL_CQPSPADS_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_CQPPOOL_CQPSPADS_SHIFT)
-#define I40E_GLPE_RUPM_FLRPOOL 0x0000DAC4 /* Reset: PE_CORER */
-#define I40E_GLPE_RUPM_FLRPOOL_FLRSPADS_SHIFT 0
-#define I40E_GLPE_RUPM_FLRPOOL_FLRSPADS_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_FLRPOOL_FLRSPADS_SHIFT)
-#define I40E_GLPE_RUPM_GCTL 0x0000DA00 /* Reset: PE_CORER */
-#define I40E_GLPE_RUPM_GCTL_ALLOFFTH_SHIFT 0
-#define I40E_GLPE_RUPM_GCTL_ALLOFFTH_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_GCTL_ALLOFFTH_SHIFT)
-#define I40E_GLPE_RUPM_GCTL_RUPM_P0_DIS_SHIFT 26
-#define I40E_GLPE_RUPM_GCTL_RUPM_P0_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_P0_DIS_SHIFT)
-#define I40E_GLPE_RUPM_GCTL_RUPM_P1_DIS_SHIFT 27
-#define I40E_GLPE_RUPM_GCTL_RUPM_P1_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_P1_DIS_SHIFT)
-#define I40E_GLPE_RUPM_GCTL_RUPM_P2_DIS_SHIFT 28
-#define I40E_GLPE_RUPM_GCTL_RUPM_P2_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_P2_DIS_SHIFT)
-#define I40E_GLPE_RUPM_GCTL_RUPM_P3_DIS_SHIFT 29
-#define I40E_GLPE_RUPM_GCTL_RUPM_P3_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_P3_DIS_SHIFT)
-#define I40E_GLPE_RUPM_GCTL_RUPM_DIS_SHIFT 30
-#define I40E_GLPE_RUPM_GCTL_RUPM_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_DIS_SHIFT)
-#define I40E_GLPE_RUPM_GCTL_SWLB_MODE_SHIFT 31
-#define I40E_GLPE_RUPM_GCTL_SWLB_MODE_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_SWLB_MODE_SHIFT)
-#define I40E_GLPE_RUPM_PTXPOOL 0x0000DAC8 /* Reset: PE_CORER */
-#define I40E_GLPE_RUPM_PTXPOOL_PTXSPADS_SHIFT 0
-#define I40E_GLPE_RUPM_PTXPOOL_PTXSPADS_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_PTXPOOL_PTXSPADS_SHIFT)
-#define I40E_GLPE_RUPM_PUSHPOOL 0x0000DAC0 /* Reset: PE_CORER */
-#define I40E_GLPE_RUPM_PUSHPOOL_PUSHSPADS_SHIFT 0
-#define I40E_GLPE_RUPM_PUSHPOOL_PUSHSPADS_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_PUSHPOOL_PUSHSPADS_SHIFT)
-#define I40E_GLPE_RUPM_TXHOST_EN 0x0000DA08 /* Reset: PE_CORER */
-#define I40E_GLPE_RUPM_TXHOST_EN_TXHOST_EN_SHIFT 0
-#define I40E_GLPE_RUPM_TXHOST_EN_TXHOST_EN_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_TXHOST_EN_TXHOST_EN_SHIFT)
-#define I40E_GLPE_VFAEQEDROPCNT(_i) (0x00132540 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLPE_VFAEQEDROPCNT_MAX_INDEX 31
-#define I40E_GLPE_VFAEQEDROPCNT_AEQEDROPCNT_SHIFT 0
-#define I40E_GLPE_VFAEQEDROPCNT_AEQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFAEQEDROPCNT_AEQEDROPCNT_SHIFT)
-#define I40E_GLPE_VFCEQEDROPCNT(_i) (0x00132440 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLPE_VFCEQEDROPCNT_MAX_INDEX 31
-#define I40E_GLPE_VFCEQEDROPCNT_CEQEDROPCNT_SHIFT 0
-#define I40E_GLPE_VFCEQEDROPCNT_CEQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFCEQEDROPCNT_CEQEDROPCNT_SHIFT)
-#define I40E_GLPE_VFCQEDROPCNT(_i) (0x00132340 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
-#define I40E_GLPE_VFCQEDROPCNT_MAX_INDEX 31
-#define I40E_GLPE_VFCQEDROPCNT_CQEDROPCNT_SHIFT 0
-#define I40E_GLPE_VFCQEDROPCNT_CQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFCQEDROPCNT_CQEDROPCNT_SHIFT)
-#define I40E_GLPE_VFFLMOBJCTRL(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPE_VFFLMOBJCTRL_MAX_INDEX 31
-#define I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT 0
-#define I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_MASK I40E_MASK(0x7, I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT 8
-#define I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_MASK I40E_MASK(0x7, I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_VFFLMQ1ALLOCERR(_i) (0x0000C700 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPE_VFFLMQ1ALLOCERR_MAX_INDEX 31
-#define I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_GLPE_VFFLMXMITALLOCERR(_i) (0x0000C600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPE_VFFLMXMITALLOCERR_MAX_INDEX 31
-#define I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_GLPE_VFUDACTRL(_i) (0x0000C000 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPE_VFUDACTRL_MAX_INDEX 31
-#define I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_SHIFT 0
-#define I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_SHIFT 1
-#define I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_SHIFT 2
-#define I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_SHIFT 3
-#define I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_SHIFT 4
-#define I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_SHIFT)
-#define I40E_GLPE_VFUDAUCFBQPN(_i) (0x0000C100 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPE_VFUDAUCFBQPN_MAX_INDEX 31
-#define I40E_GLPE_VFUDAUCFBQPN_QPN_SHIFT 0
-#define I40E_GLPE_VFUDAUCFBQPN_QPN_MASK I40E_MASK(0x3FFFF, I40E_GLPE_VFUDAUCFBQPN_QPN_SHIFT)
-#define I40E_GLPE_VFUDAUCFBQPN_VALID_SHIFT 31
-#define I40E_GLPE_VFUDAUCFBQPN_VALID_MASK I40E_MASK(0x1, I40E_GLPE_VFUDAUCFBQPN_VALID_SHIFT)
-#define I40E_PFPE_AEQALLOC 0x00131180 /* Reset: PFR */
-#define I40E_PFPE_AEQALLOC_AECOUNT_SHIFT 0
-#define I40E_PFPE_AEQALLOC_AECOUNT_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPE_AEQALLOC_AECOUNT_SHIFT)
-#define I40E_PFPE_CCQPHIGH 0x00008200 /* Reset: PFR */
-#define I40E_PFPE_CCQPHIGH_PECCQPHIGH_SHIFT 0
-#define I40E_PFPE_CCQPHIGH_PECCQPHIGH_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPE_CCQPHIGH_PECCQPHIGH_SHIFT)
-#define I40E_PFPE_CCQPLOW 0x00008180 /* Reset: PFR */
-#define I40E_PFPE_CCQPLOW_PECCQPLOW_SHIFT 0
-#define I40E_PFPE_CCQPLOW_PECCQPLOW_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPE_CCQPLOW_PECCQPLOW_SHIFT)
-#define I40E_PFPE_CCQPSTATUS 0x00008100 /* Reset: PFR */
-#define I40E_PFPE_CCQPSTATUS_CCQP_DONE_SHIFT 0
-#define I40E_PFPE_CCQPSTATUS_CCQP_DONE_MASK I40E_MASK(0x1, I40E_PFPE_CCQPSTATUS_CCQP_DONE_SHIFT)
-#define I40E_PFPE_CCQPSTATUS_HMC_PROFILE_SHIFT 4
-#define I40E_PFPE_CCQPSTATUS_HMC_PROFILE_MASK I40E_MASK(0x7, I40E_PFPE_CCQPSTATUS_HMC_PROFILE_SHIFT)
-#define I40E_PFPE_CCQPSTATUS_RDMA_EN_VFS_SHIFT 16
-#define I40E_PFPE_CCQPSTATUS_RDMA_EN_VFS_MASK I40E_MASK(0x3F, I40E_PFPE_CCQPSTATUS_RDMA_EN_VFS_SHIFT)
-#define I40E_PFPE_CCQPSTATUS_CCQP_ERR_SHIFT 31
-#define I40E_PFPE_CCQPSTATUS_CCQP_ERR_MASK I40E_MASK(0x1, I40E_PFPE_CCQPSTATUS_CCQP_ERR_SHIFT)
-#define I40E_PFPE_CQACK 0x00131100 /* Reset: PFR */
-#define I40E_PFPE_CQACK_PECQID_SHIFT 0
-#define I40E_PFPE_CQACK_PECQID_MASK I40E_MASK(0x1FFFF, I40E_PFPE_CQACK_PECQID_SHIFT)
-#define I40E_PFPE_CQARM 0x00131080 /* Reset: PFR */
-#define I40E_PFPE_CQARM_PECQID_SHIFT 0
-#define I40E_PFPE_CQARM_PECQID_MASK I40E_MASK(0x1FFFF, I40E_PFPE_CQARM_PECQID_SHIFT)
-#define I40E_PFPE_CQPDB 0x00008000 /* Reset: PFR */
-#define I40E_PFPE_CQPDB_WQHEAD_SHIFT 0
-#define I40E_PFPE_CQPDB_WQHEAD_MASK I40E_MASK(0x7FF, I40E_PFPE_CQPDB_WQHEAD_SHIFT)
-#define I40E_PFPE_CQPERRCODES 0x00008880 /* Reset: PFR */
-#define I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT 0
-#define I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_MASK I40E_MASK(0xFFFF, I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT)
-#define I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT 16
-#define I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_MASK I40E_MASK(0xFFFF, I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT)
-#define I40E_PFPE_CQPTAIL 0x00008080 /* Reset: PFR */
-#define I40E_PFPE_CQPTAIL_WQTAIL_SHIFT 0
-#define I40E_PFPE_CQPTAIL_WQTAIL_MASK I40E_MASK(0x7FF, I40E_PFPE_CQPTAIL_WQTAIL_SHIFT)
-#define I40E_PFPE_CQPTAIL_CQP_OP_ERR_SHIFT 31
-#define I40E_PFPE_CQPTAIL_CQP_OP_ERR_MASK I40E_MASK(0x1, I40E_PFPE_CQPTAIL_CQP_OP_ERR_SHIFT)
-#define I40E_PFPE_FLMQ1ALLOCERR 0x00008980 /* Reset: PFR */
-#define I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_MASK I40E_MASK(0xFFFF, I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_PFPE_FLMXMITALLOCERR 0x00008900 /* Reset: PFR */
-#define I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_MASK I40E_MASK(0xFFFF, I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_PFPE_IPCONFIG0 0x00008280 /* Reset: PFR */
-#define I40E_PFPE_IPCONFIG0_PEIPID_SHIFT 0
-#define I40E_PFPE_IPCONFIG0_PEIPID_MASK I40E_MASK(0xFFFF, I40E_PFPE_IPCONFIG0_PEIPID_SHIFT)
-#define I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT 16
-#define I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_MASK I40E_MASK(0x1, I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT)
-#define I40E_PFPE_MRTEIDXMASK 0x00008600 /* Reset: PFR */
-#define I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT 0
-#define I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_MASK I40E_MASK(0x1F, I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT)
-#define I40E_PFPE_RCVUNEXPECTEDERROR 0x00008680 /* Reset: PFR */
-#define I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT 0
-#define I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_MASK I40E_MASK(0xFFFFFF, I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT)
-#define I40E_PFPE_TCPNOWTIMER 0x00008580 /* Reset: PFR */
-#define I40E_PFPE_TCPNOWTIMER_TCP_NOW_SHIFT 0
-#define I40E_PFPE_TCPNOWTIMER_TCP_NOW_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPE_TCPNOWTIMER_TCP_NOW_SHIFT)
-#define I40E_PFPE_UDACTRL 0x00008700 /* Reset: PFR */
-#define I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_SHIFT 0
-#define I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_SHIFT 1
-#define I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_SHIFT 2
-#define I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_SHIFT 3
-#define I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_SHIFT 4
-#define I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_SHIFT)
-#define I40E_PFPE_UDAUCFBQPN 0x00008780 /* Reset: PFR */
-#define I40E_PFPE_UDAUCFBQPN_QPN_SHIFT 0
-#define I40E_PFPE_UDAUCFBQPN_QPN_MASK I40E_MASK(0x3FFFF, I40E_PFPE_UDAUCFBQPN_QPN_SHIFT)
-#define I40E_PFPE_UDAUCFBQPN_VALID_SHIFT 31
-#define I40E_PFPE_UDAUCFBQPN_VALID_MASK I40E_MASK(0x1, I40E_PFPE_UDAUCFBQPN_VALID_SHIFT)
-#define I40E_PFPE_WQEALLOC 0x00138C00 /* Reset: PFR */
-#define I40E_PFPE_WQEALLOC_PEQPID_SHIFT 0
-#define I40E_PFPE_WQEALLOC_PEQPID_MASK I40E_MASK(0x3FFFF, I40E_PFPE_WQEALLOC_PEQPID_SHIFT)
-#define I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT 20
-#define I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_MASK I40E_MASK(0xFFF, I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT)
-#define I40E_PRTDCB_RLPMC 0x0001F140 /* Reset: PE_CORER */
-#define I40E_PRTDCB_RLPMC_TC2PFC_SHIFT 0
-#define I40E_PRTDCB_RLPMC_TC2PFC_MASK I40E_MASK(0xFF, I40E_PRTDCB_RLPMC_TC2PFC_SHIFT)
-#define I40E_PRTDCB_TCMSTC_RLPM(_i) (0x0001F040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: PE_CORER */
-#define I40E_PRTDCB_TCMSTC_RLPM_MAX_INDEX 7
-#define I40E_PRTDCB_TCMSTC_RLPM_MSTC_SHIFT 0
-#define I40E_PRTDCB_TCMSTC_RLPM_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TCMSTC_RLPM_MSTC_SHIFT)
-#define I40E_PRTDCB_TCPMC_RLPM 0x0001F1A0 /* Reset: PE_CORER */
-#define I40E_PRTDCB_TCPMC_RLPM_CPM_SHIFT 0
-#define I40E_PRTDCB_TCPMC_RLPM_CPM_MASK I40E_MASK(0x1FFF, I40E_PRTDCB_TCPMC_RLPM_CPM_SHIFT)
-#define I40E_PRTDCB_TCPMC_RLPM_LLTC_SHIFT 13
-#define I40E_PRTDCB_TCPMC_RLPM_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TCPMC_RLPM_LLTC_SHIFT)
-#define I40E_PRTDCB_TCPMC_RLPM_TCPM_MODE_SHIFT 30
-#define I40E_PRTDCB_TCPMC_RLPM_TCPM_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_TCPMC_RLPM_TCPM_MODE_SHIFT)
-#define I40E_PRTE_RUPM_TCCNTR03 0x0000DAE0 /* Reset: PE_CORER */
-#define I40E_PRTE_RUPM_TCCNTR03_TC0COUNT_SHIFT 0
-#define I40E_PRTE_RUPM_TCCNTR03_TC0COUNT_MASK I40E_MASK(0xFF, I40E_PRTE_RUPM_TCCNTR03_TC0COUNT_SHIFT)
-#define I40E_PRTE_RUPM_TCCNTR03_TC1COUNT_SHIFT 8
-#define I40E_PRTE_RUPM_TCCNTR03_TC1COUNT_MASK I40E_MASK(0xFF, I40E_PRTE_RUPM_TCCNTR03_TC1COUNT_SHIFT)
-#define I40E_PRTE_RUPM_TCCNTR03_TC2COUNT_SHIFT 16
-#define I40E_PRTE_RUPM_TCCNTR03_TC2COUNT_MASK I40E_MASK(0xFF, I40E_PRTE_RUPM_TCCNTR03_TC2COUNT_SHIFT)
-#define I40E_PRTE_RUPM_TCCNTR03_TC3COUNT_SHIFT 24
-#define I40E_PRTE_RUPM_TCCNTR03_TC3COUNT_MASK I40E_MASK(0xFF, I40E_PRTE_RUPM_TCCNTR03_TC3COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_CNTR 0x0000DB20 /* Reset: PE_CORER */
-#define I40E_PRTPE_RUPM_CNTR_COUNT_SHIFT 0
-#define I40E_PRTPE_RUPM_CNTR_COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_CNTR_COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_CTL 0x0000DA40 /* Reset: PE_CORER */
-#define I40E_PRTPE_RUPM_CTL_LLTC_SHIFT 13
-#define I40E_PRTPE_RUPM_CTL_LLTC_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_CTL_LLTC_SHIFT)
-#define I40E_PRTPE_RUPM_CTL_RUPM_MODE_SHIFT 30
-#define I40E_PRTPE_RUPM_CTL_RUPM_MODE_MASK I40E_MASK(0x1, I40E_PRTPE_RUPM_CTL_RUPM_MODE_SHIFT)
-#define I40E_PRTPE_RUPM_PFCCTL 0x0000DA60 /* Reset: PE_CORER */
-#define I40E_PRTPE_RUPM_PFCCTL_TC2PFC_SHIFT 0
-#define I40E_PRTPE_RUPM_PFCCTL_TC2PFC_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PFCCTL_TC2PFC_SHIFT)
-#define I40E_PRTPE_RUPM_PFCPC 0x0000DA80 /* Reset: PE_CORER */
-#define I40E_PRTPE_RUPM_PFCPC_PORTOFFTH_SHIFT 0
-#define I40E_PRTPE_RUPM_PFCPC_PORTOFFTH_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PFCPC_PORTOFFTH_SHIFT)
-#define I40E_PRTPE_RUPM_PFCTCC 0x0000DAA0 /* Reset: PE_CORER */
-#define I40E_PRTPE_RUPM_PFCTCC_TCOFFTH_SHIFT 0
-#define I40E_PRTPE_RUPM_PFCTCC_TCOFFTH_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PFCTCC_TCOFFTH_SHIFT)
-#define I40E_PRTPE_RUPM_PFCTCC_LL_PRI_TH_SHIFT 16
-#define I40E_PRTPE_RUPM_PFCTCC_LL_PRI_TH_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PFCTCC_LL_PRI_TH_SHIFT)
-#define I40E_PRTPE_RUPM_PFCTCC_LL_PRI_EN_SHIFT 31
-#define I40E_PRTPE_RUPM_PFCTCC_LL_PRI_EN_MASK I40E_MASK(0x1, I40E_PRTPE_RUPM_PFCTCC_LL_PRI_EN_SHIFT)
-#define I40E_PRTPE_RUPM_PTCTCCNTR47 0x0000DB60 /* Reset: PE_CORER */
-#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC4COUNT_SHIFT 0
-#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC4COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTCTCCNTR47_TC4COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC5COUNT_SHIFT 8
-#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC5COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTCTCCNTR47_TC5COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC6COUNT_SHIFT 16
-#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC6COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTCTCCNTR47_TC6COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC7COUNT_SHIFT 24
-#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC7COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTCTCCNTR47_TC7COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_PTXTCCNTR03 0x0000DB40 /* Reset: PE_CORER */
-#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC0COUNT_SHIFT 0
-#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC0COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTXTCCNTR03_TC0COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC1COUNT_SHIFT 8
-#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC1COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTXTCCNTR03_TC1COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC2COUNT_SHIFT 16
-#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC2COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTXTCCNTR03_TC2COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC3COUNT_SHIFT 24
-#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC3COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTXTCCNTR03_TC3COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_TCCNTR47 0x0000DB00 /* Reset: PE_CORER */
-#define I40E_PRTPE_RUPM_TCCNTR47_TC4COUNT_SHIFT 0
-#define I40E_PRTPE_RUPM_TCCNTR47_TC4COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_TCCNTR47_TC4COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_TCCNTR47_TC5COUNT_SHIFT 8
-#define I40E_PRTPE_RUPM_TCCNTR47_TC5COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_TCCNTR47_TC5COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_TCCNTR47_TC6COUNT_SHIFT 16
-#define I40E_PRTPE_RUPM_TCCNTR47_TC6COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_TCCNTR47_TC6COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_TCCNTR47_TC7COUNT_SHIFT 24
-#define I40E_PRTPE_RUPM_TCCNTR47_TC7COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_TCCNTR47_TC7COUNT_SHIFT)
-#define I40E_PRTPE_RUPM_THRES 0x0000DA20 /* Reset: PE_CORER */
-#define I40E_PRTPE_RUPM_THRES_MINSPADSPERTC_SHIFT 0
-#define I40E_PRTPE_RUPM_THRES_MINSPADSPERTC_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_THRES_MINSPADSPERTC_SHIFT)
-#define I40E_PRTPE_RUPM_THRES_MAXSPADS_SHIFT 8
-#define I40E_PRTPE_RUPM_THRES_MAXSPADS_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_THRES_MAXSPADS_SHIFT)
-#define I40E_PRTPE_RUPM_THRES_MAXSPADSPERTC_SHIFT 16
-#define I40E_PRTPE_RUPM_THRES_MAXSPADSPERTC_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_THRES_MAXSPADSPERTC_SHIFT)
-#define I40E_VFPE_AEQALLOC(_VF) (0x00130C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_AEQALLOC_MAX_INDEX 127
-#define I40E_VFPE_AEQALLOC_AECOUNT_SHIFT 0
-#define I40E_VFPE_AEQALLOC_AECOUNT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_AEQALLOC_AECOUNT_SHIFT)
-#define I40E_VFPE_CCQPHIGH(_VF) (0x00001000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_CCQPHIGH_MAX_INDEX 127
-#define I40E_VFPE_CCQPHIGH_PECCQPHIGH_SHIFT 0
-#define I40E_VFPE_CCQPHIGH_PECCQPHIGH_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_CCQPHIGH_PECCQPHIGH_SHIFT)
-#define I40E_VFPE_CCQPLOW(_VF) (0x00000C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_CCQPLOW_MAX_INDEX 127
-#define I40E_VFPE_CCQPLOW_PECCQPLOW_SHIFT 0
-#define I40E_VFPE_CCQPLOW_PECCQPLOW_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_CCQPLOW_PECCQPLOW_SHIFT)
-#define I40E_VFPE_CCQPSTATUS(_VF) (0x00000800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_CCQPSTATUS_MAX_INDEX 127
-#define I40E_VFPE_CCQPSTATUS_CCQP_DONE_SHIFT 0
-#define I40E_VFPE_CCQPSTATUS_CCQP_DONE_MASK I40E_MASK(0x1, I40E_VFPE_CCQPSTATUS_CCQP_DONE_SHIFT)
-#define I40E_VFPE_CCQPSTATUS_HMC_PROFILE_SHIFT 4
-#define I40E_VFPE_CCQPSTATUS_HMC_PROFILE_MASK I40E_MASK(0x7, I40E_VFPE_CCQPSTATUS_HMC_PROFILE_SHIFT)
-#define I40E_VFPE_CCQPSTATUS_RDMA_EN_VFS_SHIFT 16
-#define I40E_VFPE_CCQPSTATUS_RDMA_EN_VFS_MASK I40E_MASK(0x3F, I40E_VFPE_CCQPSTATUS_RDMA_EN_VFS_SHIFT)
-#define I40E_VFPE_CCQPSTATUS_CCQP_ERR_SHIFT 31
-#define I40E_VFPE_CCQPSTATUS_CCQP_ERR_MASK I40E_MASK(0x1, I40E_VFPE_CCQPSTATUS_CCQP_ERR_SHIFT)
-#define I40E_VFPE_CQACK(_VF) (0x00130800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_CQACK_MAX_INDEX 127
-#define I40E_VFPE_CQACK_PECQID_SHIFT 0
-#define I40E_VFPE_CQACK_PECQID_MASK I40E_MASK(0x1FFFF, I40E_VFPE_CQACK_PECQID_SHIFT)
-#define I40E_VFPE_CQARM(_VF) (0x00130400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_CQARM_MAX_INDEX 127
-#define I40E_VFPE_CQARM_PECQID_SHIFT 0
-#define I40E_VFPE_CQARM_PECQID_MASK I40E_MASK(0x1FFFF, I40E_VFPE_CQARM_PECQID_SHIFT)
-#define I40E_VFPE_CQPDB(_VF) (0x00000000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_CQPDB_MAX_INDEX 127
-#define I40E_VFPE_CQPDB_WQHEAD_SHIFT 0
-#define I40E_VFPE_CQPDB_WQHEAD_MASK I40E_MASK(0x7FF, I40E_VFPE_CQPDB_WQHEAD_SHIFT)
-#define I40E_VFPE_CQPERRCODES(_VF) (0x00001800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_CQPERRCODES_MAX_INDEX 127
-#define I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT 0
-#define I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_MASK I40E_MASK(0xFFFF, I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT)
-#define I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT 16
-#define I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_MASK I40E_MASK(0xFFFF, I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT)
-#define I40E_VFPE_CQPTAIL(_VF) (0x00000400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_CQPTAIL_MAX_INDEX 127
-#define I40E_VFPE_CQPTAIL_WQTAIL_SHIFT 0
-#define I40E_VFPE_CQPTAIL_WQTAIL_MASK I40E_MASK(0x7FF, I40E_VFPE_CQPTAIL_WQTAIL_SHIFT)
-#define I40E_VFPE_CQPTAIL_CQP_OP_ERR_SHIFT 31
-#define I40E_VFPE_CQPTAIL_CQP_OP_ERR_MASK I40E_MASK(0x1, I40E_VFPE_CQPTAIL_CQP_OP_ERR_SHIFT)
-#define I40E_VFPE_IPCONFIG0(_VF) (0x00001400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_IPCONFIG0_MAX_INDEX 127
-#define I40E_VFPE_IPCONFIG0_PEIPID_SHIFT 0
-#define I40E_VFPE_IPCONFIG0_PEIPID_MASK I40E_MASK(0xFFFF, I40E_VFPE_IPCONFIG0_PEIPID_SHIFT)
-#define I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT 16
-#define I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_MASK I40E_MASK(0x1, I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT)
-#define I40E_VFPE_MRTEIDXMASK(_VF) (0x00003000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_MRTEIDXMASK_MAX_INDEX 127
-#define I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT 0
-#define I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_MASK I40E_MASK(0x1F, I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT)
-#define I40E_VFPE_RCVUNEXPECTEDERROR(_VF) (0x00003400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_RCVUNEXPECTEDERROR_MAX_INDEX 127
-#define I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT 0
-#define I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_MASK I40E_MASK(0xFFFFFF, I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT)
-#define I40E_VFPE_TCPNOWTIMER(_VF) (0x00002C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_TCPNOWTIMER_MAX_INDEX 127
-#define I40E_VFPE_TCPNOWTIMER_TCP_NOW_SHIFT 0
-#define I40E_VFPE_TCPNOWTIMER_TCP_NOW_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_TCPNOWTIMER_TCP_NOW_SHIFT)
-#define I40E_VFPE_WQEALLOC(_VF) (0x00138000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
-#define I40E_VFPE_WQEALLOC_MAX_INDEX 127
-#define I40E_VFPE_WQEALLOC_PEQPID_SHIFT 0
-#define I40E_VFPE_WQEALLOC_PEQPID_MASK I40E_MASK(0x3FFFF, I40E_VFPE_WQEALLOC_PEQPID_SHIFT)
-#define I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT 20
-#define I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_MASK I40E_MASK(0xFFF, I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT)
-#define I40E_GLPES_PFIP4RXDISCARD(_i) (0x00010600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXDISCARD_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_SHIFT 0
-#define I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_SHIFT)
-#define I40E_GLPES_PFIP4RXFRAGSHI(_i) (0x00010804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXFRAGSLO(_i) (0x00010800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXMCOCTSHI(_i) (0x00010A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXMCOCTSLO(_i) (0x00010A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXMCPKTSHI(_i) (0x00010C04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXMCPKTSLO(_i) (0x00010C00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXOCTSHI(_i) (0x00010204 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXOCTSLO(_i) (0x00010200 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXPKTSHI(_i) (0x00010404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXPKTSLO(_i) (0x00010400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXTRUNC(_i) (0x00010700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4RXTRUNC_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_SHIFT 0
-#define I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_SHIFT)
-#define I40E_GLPES_PFIP4TXFRAGSHI(_i) (0x00011E04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXFRAGSLO(_i) (0x00011E00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXMCOCTSHI(_i) (0x00012004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXMCOCTSLO(_i) (0x00012000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXMCPKTSHI(_i) (0x00012204 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXMCPKTSLO(_i) (0x00012200 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXNOROUTE(_i) (0x00012E00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXNOROUTE_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT 0
-#define I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT)
-#define I40E_GLPES_PFIP4TXOCTSHI(_i) (0x00011A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXOCTSLO(_i) (0x00011A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXPKTSHI(_i) (0x00011C04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXPKTSLO(_i) (0x00011C00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP4TXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXDISCARD(_i) (0x00011200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXDISCARD_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_SHIFT 0
-#define I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_SHIFT)
-#define I40E_GLPES_PFIP6RXFRAGSHI(_i) (0x00011404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXFRAGSLO(_i) (0x00011400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXMCOCTSHI(_i) (0x00011604 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXMCOCTSLO(_i) (0x00011600 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXMCPKTSHI(_i) (0x00011804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXMCPKTSLO(_i) (0x00011800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXOCTSHI(_i) (0x00010E04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXOCTSLO(_i) (0x00010E00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXPKTSHI(_i) (0x00011004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXPKTSLO(_i) (0x00011000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXTRUNC(_i) (0x00011300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6RXTRUNC_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_SHIFT 0
-#define I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_SHIFT)
-#define I40E_GLPES_PFIP6TXFRAGSHI(_i) (0x00012804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXFRAGSLO(_i) (0x00012800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXMCOCTSHI(_i) (0x00012A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXMCOCTSLO(_i) (0x00012A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXMCPKTSHI(_i) (0x00012C04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXMCPKTSLO(_i) (0x00012C00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXNOROUTE(_i) (0x00012F00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXNOROUTE_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT 0
-#define I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT)
-#define I40E_GLPES_PFIP6TXOCTSHI(_i) (0x00012404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXOCTSLO(_i) (0x00012400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXPKTSHI(_i) (0x00012604 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXPKTSLO(_i) (0x00012600 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFIP6TXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT)
-#define I40E_GLPES_PFRDMARXRDSHI(_i) (0x00013E04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMARXRDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_PFRDMARXRDSLO(_i) (0x00013E00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMARXRDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_PFRDMARXSNDSHI(_i) (0x00014004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMARXSNDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_PFRDMARXSNDSLO(_i) (0x00014000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMARXSNDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_PFRDMARXWRSHI(_i) (0x00013C04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMARXWRSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_PFRDMARXWRSLO(_i) (0x00013C00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMARXWRSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_PFRDMATXRDSHI(_i) (0x00014404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMATXRDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_PFRDMATXRDSLO(_i) (0x00014400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMATXRDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_PFRDMATXSNDSHI(_i) (0x00014604 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMATXSNDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_PFRDMATXSNDSLO(_i) (0x00014600 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMATXSNDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_PFRDMATXWRSHI(_i) (0x00014204 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMATXWRSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_PFRDMATXWRSLO(_i) (0x00014200 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMATXWRSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_PFRDMAVBNDHI(_i) (0x00014804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMAVBNDHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_SHIFT 0
-#define I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_SHIFT)
-#define I40E_GLPES_PFRDMAVBNDLO(_i) (0x00014800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMAVBNDLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_SHIFT 0
-#define I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_SHIFT)
-#define I40E_GLPES_PFRDMAVINVHI(_i) (0x00014A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMAVINVHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_SHIFT 0
-#define I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_SHIFT)
-#define I40E_GLPES_PFRDMAVINVLO(_i) (0x00014A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRDMAVINVLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_SHIFT 0
-#define I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_SHIFT)
-#define I40E_GLPES_PFRXVLANERR(_i) (0x00010000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFRXVLANERR_MAX_INDEX 15
-#define I40E_GLPES_PFRXVLANERR_RXVLANERR_SHIFT 0
-#define I40E_GLPES_PFRXVLANERR_RXVLANERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFRXVLANERR_RXVLANERR_SHIFT)
-#define I40E_GLPES_PFTCPRTXSEG(_i) (0x00013600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFTCPRTXSEG_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_SHIFT 0
-#define I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_SHIFT)
-#define I40E_GLPES_PFTCPRXOPTERR(_i) (0x00013200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFTCPRXOPTERR_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_SHIFT 0
-#define I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_SHIFT)
-#define I40E_GLPES_PFTCPRXPROTOERR(_i) (0x00013300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFTCPRXPROTOERR_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT 0
-#define I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT)
-#define I40E_GLPES_PFTCPRXSEGSHI(_i) (0x00013004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFTCPRXSEGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT 0
-#define I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT)
-#define I40E_GLPES_PFTCPRXSEGSLO(_i) (0x00013000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFTCPRXSEGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT 0
-#define I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT)
-#define I40E_GLPES_PFTCPTXSEGHI(_i) (0x00013404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFTCPTXSEGHI_MAX_INDEX 15
-#define I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_SHIFT 0
-#define I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_SHIFT)
-#define I40E_GLPES_PFTCPTXSEGLO(_i) (0x00013400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFTCPTXSEGLO_MAX_INDEX 15
-#define I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_SHIFT 0
-#define I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_SHIFT)
-#define I40E_GLPES_PFUDPRXPKTSHI(_i) (0x00013804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFUDPRXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT)
-#define I40E_GLPES_PFUDPRXPKTSLO(_i) (0x00013800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFUDPRXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT)
-#define I40E_GLPES_PFUDPTXPKTSHI(_i) (0x00013A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFUDPTXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT)
-#define I40E_GLPES_PFUDPTXPKTSLO(_i) (0x00013A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
-#define I40E_GLPES_PFUDPTXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT)
-#define I40E_GLPES_RDMARXMULTFPDUSHI 0x0001E014 /* Reset: PE_CORER */
-#define I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_SHIFT 0
-#define I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_SHIFT)
-#define I40E_GLPES_RDMARXMULTFPDUSLO 0x0001E010 /* Reset: PE_CORER */
-#define I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_SHIFT 0
-#define I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_SHIFT)
-#define I40E_GLPES_RDMARXOOODDPHI 0x0001E01C /* Reset: PE_CORER */
-#define I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_SHIFT 0
-#define I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_SHIFT)
-#define I40E_GLPES_RDMARXOOODDPLO 0x0001E018 /* Reset: PE_CORER */
-#define I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_SHIFT 0
-#define I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_SHIFT)
-#define I40E_GLPES_RDMARXOOONOMARK 0x0001E004 /* Reset: PE_CORER */
-#define I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_SHIFT 0
-#define I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_SHIFT)
-#define I40E_GLPES_RDMARXUNALIGN 0x0001E000 /* Reset: PE_CORER */
-#define I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_SHIFT 0
-#define I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_SHIFT)
-#define I40E_GLPES_TCPRXFOURHOLEHI 0x0001E044 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXFOURHOLELO 0x0001E040 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXONEHOLEHI 0x0001E02C /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXONEHOLELO 0x0001E028 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXPUREACKHI 0x0001E024 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_SHIFT 0
-#define I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_SHIFT)
-#define I40E_GLPES_TCPRXPUREACKSLO 0x0001E020 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_SHIFT 0
-#define I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_SHIFT)
-#define I40E_GLPES_TCPRXTHREEHOLEHI 0x0001E03C /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXTHREEHOLELO 0x0001E038 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXTWOHOLEHI 0x0001E034 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXTWOHOLELO 0x0001E030 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_SHIFT)
-#define I40E_GLPES_TCPTXRETRANSFASTHI 0x0001E04C /* Reset: PE_CORER */
-#define I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_SHIFT 0
-#define I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_SHIFT)
-#define I40E_GLPES_TCPTXRETRANSFASTLO 0x0001E048 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_SHIFT 0
-#define I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSFASTHI 0x0001E054 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSFASTLO 0x0001E050 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSHI 0x0001E05C /* Reset: PE_CORER */
-#define I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSLO 0x0001E058 /* Reset: PE_CORER */
-#define I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXDISCARD(_i) (0x00018600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXDISCARD_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_SHIFT 0
-#define I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_SHIFT)
-#define I40E_GLPES_VFIP4RXFRAGSHI(_i) (0x00018804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXFRAGSLO(_i) (0x00018800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXMCOCTSHI(_i) (0x00018A04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXMCOCTSLO(_i) (0x00018A00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXMCPKTSHI(_i) (0x00018C04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXMCPKTSLO(_i) (0x00018C00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXOCTSHI(_i) (0x00018204 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXOCTSLO(_i) (0x00018200 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXPKTSHI(_i) (0x00018404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXPKTSLO(_i) (0x00018400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXTRUNC(_i) (0x00018700 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4RXTRUNC_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_SHIFT 0
-#define I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_SHIFT)
-#define I40E_GLPES_VFIP4TXFRAGSHI(_i) (0x00019E04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXFRAGSLO(_i) (0x00019E00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXMCOCTSHI(_i) (0x0001A004 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXMCOCTSLO(_i) (0x0001A000 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXMCPKTSHI(_i) (0x0001A204 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXMCPKTSLO(_i) (0x0001A200 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXNOROUTE(_i) (0x0001AE00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXNOROUTE_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT 0
-#define I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT)
-#define I40E_GLPES_VFIP4TXOCTSHI(_i) (0x00019A04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXOCTSLO(_i) (0x00019A00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXPKTSHI(_i) (0x00019C04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXPKTSLO(_i) (0x00019C00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP4TXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXDISCARD(_i) (0x00019200 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXDISCARD_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_SHIFT 0
-#define I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_SHIFT)
-#define I40E_GLPES_VFIP6RXFRAGSHI(_i) (0x00019404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXFRAGSLO(_i) (0x00019400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXMCOCTSHI(_i) (0x00019604 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXMCOCTSLO(_i) (0x00019600 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXMCPKTSHI(_i) (0x00019804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXMCPKTSLO(_i) (0x00019800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXOCTSHI(_i) (0x00018E04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXOCTSLO(_i) (0x00018E00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXPKTSHI(_i) (0x00019004 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXPKTSLO(_i) (0x00019000 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXTRUNC(_i) (0x00019300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6RXTRUNC_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_SHIFT 0
-#define I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_SHIFT)
-#define I40E_GLPES_VFIP6TXFRAGSHI(_i) (0x0001A804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXFRAGSLO(_i) (0x0001A800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXMCOCTSHI(_i) (0x0001AA04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXMCOCTSLO(_i) (0x0001AA00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXMCPKTSHI(_i) (0x0001AC04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXMCPKTSLO(_i) (0x0001AC00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXNOROUTE(_i) (0x0001AF00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXNOROUTE_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT 0
-#define I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT)
-#define I40E_GLPES_VFIP6TXOCTSHI(_i) (0x0001A404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXOCTSLO(_i) (0x0001A400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXPKTSHI(_i) (0x0001A604 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXPKTSLO(_i) (0x0001A600 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFIP6TXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT)
-#define I40E_GLPES_VFRDMARXRDSHI(_i) (0x0001BE04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMARXRDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_VFRDMARXRDSLO(_i) (0x0001BE00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMARXRDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_VFRDMARXSNDSHI(_i) (0x0001C004 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMARXSNDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_VFRDMARXSNDSLO(_i) (0x0001C000 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMARXSNDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_VFRDMARXWRSHI(_i) (0x0001BC04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMARXWRSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_VFRDMARXWRSLO(_i) (0x0001BC00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMARXWRSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_VFRDMATXRDSHI(_i) (0x0001C404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMATXRDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_VFRDMATXRDSLO(_i) (0x0001C400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMATXRDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_VFRDMATXSNDSHI(_i) (0x0001C604 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMATXSNDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_VFRDMATXSNDSLO(_i) (0x0001C600 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMATXSNDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_VFRDMATXWRSHI(_i) (0x0001C204 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMATXWRSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_VFRDMATXWRSLO(_i) (0x0001C200 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMATXWRSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_VFRDMAVBNDHI(_i) (0x0001C804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMAVBNDHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_SHIFT 0
-#define I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_SHIFT)
-#define I40E_GLPES_VFRDMAVBNDLO(_i) (0x0001C800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMAVBNDLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_SHIFT 0
-#define I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_SHIFT)
-#define I40E_GLPES_VFRDMAVINVHI(_i) (0x0001CA04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMAVINVHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_SHIFT 0
-#define I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_SHIFT)
-#define I40E_GLPES_VFRDMAVINVLO(_i) (0x0001CA00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRDMAVINVLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_SHIFT 0
-#define I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_SHIFT)
-#define I40E_GLPES_VFRXVLANERR(_i) (0x00018000 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFRXVLANERR_MAX_INDEX 31
-#define I40E_GLPES_VFRXVLANERR_RXVLANERR_SHIFT 0
-#define I40E_GLPES_VFRXVLANERR_RXVLANERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFRXVLANERR_RXVLANERR_SHIFT)
-#define I40E_GLPES_VFTCPRTXSEG(_i) (0x0001B600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFTCPRTXSEG_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_SHIFT 0
-#define I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_SHIFT)
-#define I40E_GLPES_VFTCPRXOPTERR(_i) (0x0001B200 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFTCPRXOPTERR_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_SHIFT 0
-#define I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_SHIFT)
-#define I40E_GLPES_VFTCPRXPROTOERR(_i) (0x0001B300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFTCPRXPROTOERR_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT 0
-#define I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT)
-#define I40E_GLPES_VFTCPRXSEGSHI(_i) (0x0001B004 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFTCPRXSEGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT 0
-#define I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT)
-#define I40E_GLPES_VFTCPRXSEGSLO(_i) (0x0001B000 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFTCPRXSEGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT 0
-#define I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT)
-#define I40E_GLPES_VFTCPTXSEGHI(_i) (0x0001B404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFTCPTXSEGHI_MAX_INDEX 31
-#define I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_SHIFT 0
-#define I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_SHIFT)
-#define I40E_GLPES_VFTCPTXSEGLO(_i) (0x0001B400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFTCPTXSEGLO_MAX_INDEX 31
-#define I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_SHIFT 0
-#define I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_SHIFT)
-#define I40E_GLPES_VFUDPRXPKTSHI(_i) (0x0001B804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFUDPRXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT)
-#define I40E_GLPES_VFUDPRXPKTSLO(_i) (0x0001B800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFUDPRXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT)
-#define I40E_GLPES_VFUDPTXPKTSHI(_i) (0x0001BA04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFUDPTXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT)
-#define I40E_GLPES_VFUDPTXPKTSLO(_i) (0x0001BA00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
-#define I40E_GLPES_VFUDPTXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT)
-#define I40E_GLGEN_PME_TO 0x000B81BC /* Reset: POR */
-#define I40E_GLGEN_PME_TO_PME_TO_FOR_PE_SHIFT 0
-#define I40E_GLGEN_PME_TO_PME_TO_FOR_PE_MASK I40E_MASK(0x1, I40E_GLGEN_PME_TO_PME_TO_FOR_PE_SHIFT)
-#define I40E_GLQF_APBVT(_i) (0x00260000 + ((_i) * 4)) /* _i=0...2047 */ /* Reset: CORER */
-#define I40E_GLQF_APBVT_MAX_INDEX 2047
-#define I40E_GLQF_APBVT_APBVT_SHIFT 0
-#define I40E_GLQF_APBVT_APBVT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLQF_APBVT_APBVT_SHIFT)
-#define I40E_GLQF_FD_PCTYPES(_i) (0x00268000 + ((_i) * 4)) /* _i=0...63 */ /* Reset: POR */
-#define I40E_GLQF_FD_PCTYPES_MAX_INDEX 63
-#define I40E_GLQF_FD_PCTYPES_FD_PCTYPE_SHIFT 0
-#define I40E_GLQF_FD_PCTYPES_FD_PCTYPE_MASK I40E_MASK(0x3F, I40E_GLQF_FD_PCTYPES_FD_PCTYPE_SHIFT)
-#define I40E_GLQF_FD_MSK(_i, _j) (0x00267200 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */ /* Reset: CORER */
-#define I40E_GLQF_FD_MSK_MAX_INDEX 1
-#define I40E_GLQF_FD_MSK_MASK_SHIFT 0
-#define I40E_GLQF_FD_MSK_MASK_MASK I40E_MASK(0xFFFF, I40E_GLQF_FD_MSK_MASK_SHIFT)
-#define I40E_GLQF_FD_MSK_OFFSET_SHIFT 16
-#define I40E_GLQF_FD_MSK_OFFSET_MASK I40E_MASK(0x3F, I40E_GLQF_FD_MSK_OFFSET_SHIFT)
#define I40E_GLQF_HASH_INSET(_i, _j) (0x00267600 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */ /* Reset: CORER */
-#define I40E_GLQF_HASH_INSET_MAX_INDEX 1
-#define I40E_GLQF_HASH_INSET_INSET_SHIFT 0
-#define I40E_GLQF_HASH_INSET_INSET_MASK I40E_MASK(0xFFFFFFFF, I40E_GLQF_HASH_INSET_INSET_SHIFT)
-#define I40E_GLQF_HASH_MSK(_i, _j) (0x00267A00 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */ /* Reset: CORER */
-#define I40E_GLQF_HASH_MSK_MAX_INDEX 1
-#define I40E_GLQF_HASH_MSK_MASK_SHIFT 0
-#define I40E_GLQF_HASH_MSK_MASK_MASK I40E_MASK(0xFFFF, I40E_GLQF_HASH_MSK_MASK_SHIFT)
-#define I40E_GLQF_HASH_MSK_OFFSET_SHIFT 16
-#define I40E_GLQF_HASH_MSK_OFFSET_MASK I40E_MASK(0x3F, I40E_GLQF_HASH_MSK_OFFSET_SHIFT)
#define I40E_GLQF_ORT(_i) (0x00268900 + ((_i) * 4)) /* _i=0...63 */ /* Reset: CORER */
-#define I40E_GLQF_ORT_MAX_INDEX 63
#define I40E_GLQF_ORT_PIT_INDX_SHIFT 0
#define I40E_GLQF_ORT_PIT_INDX_MASK I40E_MASK(0x1F, I40E_GLQF_ORT_PIT_INDX_SHIFT)
#define I40E_GLQF_ORT_FIELD_CNT_SHIFT 5
#define I40E_GLQF_ORT_FIELD_CNT_MASK I40E_MASK(0x3, I40E_GLQF_ORT_FIELD_CNT_SHIFT)
#define I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT 7
#define I40E_GLQF_ORT_FLX_PAYLOAD_MASK I40E_MASK(0x1, I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT)
-#define I40E_GLQF_PIT(_i) (0x00268C80 + ((_i) * 4)) /* _i=0...23 */ /* Reset: CORER */
-#define I40E_GLQF_PIT_MAX_INDEX 23
-#define I40E_GLQF_PIT_SOURCE_OFF_SHIFT 0
-#define I40E_GLQF_PIT_SOURCE_OFF_MASK I40E_MASK(0x1F, I40E_GLQF_PIT_SOURCE_OFF_SHIFT)
-#define I40E_GLQF_PIT_FSIZE_SHIFT 5
-#define I40E_GLQF_PIT_FSIZE_MASK I40E_MASK(0x1F, I40E_GLQF_PIT_FSIZE_SHIFT)
-#define I40E_GLQF_PIT_DEST_OFF_SHIFT 10
-#define I40E_GLQF_PIT_DEST_OFF_MASK I40E_MASK(0x3F, I40E_GLQF_PIT_DEST_OFF_SHIFT)
#define I40E_GLQF_FDEVICTENA(_i) (0x00270384 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
-#define I40E_GLQF_FDEVICTENA_MAX_INDEX 1
-#define I40E_GLQF_FDEVICTENA_GLQF_FDEVICTENA_SHIFT 0
-#define I40E_GLQF_FDEVICTENA_GLQF_FDEVICTENA_MASK I40E_MASK(0xFFFFFFFF, I40E_GLQF_FDEVICTENA_GLQF_FDEVICTENA_SHIFT)
-#define I40E_GLQF_FDEVICTFLAG 0x00270280 /* Reset: CORER */
-#define I40E_GLQF_FDEVICTFLAG_TX_FLAGS_SHIFT 0
-#define I40E_GLQF_FDEVICTFLAG_TX_FLAGS_MASK I40E_MASK(0xFF, I40E_GLQF_FDEVICTFLAG_TX_FLAGS_SHIFT)
-#define I40E_GLQF_FDEVICTFLAG_RX_FLAGS_SHIFT 8
-#define I40E_GLQF_FDEVICTFLAG_RX_FLAGS_MASK I40E_MASK(0xFF, I40E_GLQF_FDEVICTFLAG_RX_FLAGS_SHIFT)
-#define I40E_PFQF_CTL_2 0x00270300 /* Reset: CORER */
-#define I40E_PFQF_CTL_2_PEHSIZE_SHIFT 0
-#define I40E_PFQF_CTL_2_PEHSIZE_MASK I40E_MASK(0x1F, I40E_PFQF_CTL_2_PEHSIZE_SHIFT)
-#define I40E_PFQF_CTL_2_PEDSIZE_SHIFT 5
-#define I40E_PFQF_CTL_2_PEDSIZE_MASK I40E_MASK(0x1F, I40E_PFQF_CTL_2_PEDSIZE_SHIFT)
/* Redefined for X722 family */
-#define I40E_X722_PFQF_HLUT(_i) (0x00240000 + ((_i) * 128)) /* _i=0...127 */ /* Reset: CORER */
-#define I40E_X722_PFQF_HLUT_MAX_INDEX 127
-#define I40E_X722_PFQF_HLUT_LUT0_SHIFT 0
-#define I40E_X722_PFQF_HLUT_LUT0_MASK I40E_MASK(0x7F, I40E_X722_PFQF_HLUT_LUT0_SHIFT)
-#define I40E_X722_PFQF_HLUT_LUT1_SHIFT 8
-#define I40E_X722_PFQF_HLUT_LUT1_MASK I40E_MASK(0x7F, I40E_X722_PFQF_HLUT_LUT1_SHIFT)
-#define I40E_X722_PFQF_HLUT_LUT2_SHIFT 16
-#define I40E_X722_PFQF_HLUT_LUT2_MASK I40E_MASK(0x7F, I40E_X722_PFQF_HLUT_LUT2_SHIFT)
-#define I40E_X722_PFQF_HLUT_LUT3_SHIFT 24
-#define I40E_X722_PFQF_HLUT_LUT3_MASK I40E_MASK(0x7F, I40E_X722_PFQF_HLUT_LUT3_SHIFT)
-#define I40E_PFQF_HREGION(_i) (0x00245400 + ((_i) * 128)) /* _i=0...7 */ /* Reset: CORER */
-#define I40E_PFQF_HREGION_MAX_INDEX 7
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT 0
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_0_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
-#define I40E_PFQF_HREGION_REGION_0_SHIFT 1
-#define I40E_PFQF_HREGION_REGION_0_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_0_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT 4
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_1_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
-#define I40E_PFQF_HREGION_REGION_1_SHIFT 5
-#define I40E_PFQF_HREGION_REGION_1_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_1_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT 8
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_2_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
-#define I40E_PFQF_HREGION_REGION_2_SHIFT 9
-#define I40E_PFQF_HREGION_REGION_2_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_2_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT 12
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_3_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
-#define I40E_PFQF_HREGION_REGION_3_SHIFT 13
-#define I40E_PFQF_HREGION_REGION_3_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_3_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT 16
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_4_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
-#define I40E_PFQF_HREGION_REGION_4_SHIFT 17
-#define I40E_PFQF_HREGION_REGION_4_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_4_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT 20
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_5_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
-#define I40E_PFQF_HREGION_REGION_5_SHIFT 21
-#define I40E_PFQF_HREGION_REGION_5_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_5_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT 24
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_6_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
-#define I40E_PFQF_HREGION_REGION_6_SHIFT 25
-#define I40E_PFQF_HREGION_REGION_6_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_6_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT 28
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_7_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
-#define I40E_PFQF_HREGION_REGION_7_SHIFT 29
-#define I40E_PFQF_HREGION_REGION_7_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_7_SHIFT)
-#define I40E_VSIQF_CTL_RSS_LUT_TYPE_SHIFT 8
-#define I40E_VSIQF_CTL_RSS_LUT_TYPE_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_RSS_LUT_TYPE_SHIFT)
-#define I40E_VSIQF_HKEY(_i, _VSI) (0x002A0000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...12, _VSI=0...383 */ /* Reset: CORER */
-#define I40E_VSIQF_HKEY_MAX_INDEX 12
-#define I40E_VSIQF_HKEY_KEY_0_SHIFT 0
-#define I40E_VSIQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_VSIQF_HKEY_KEY_0_SHIFT)
-#define I40E_VSIQF_HKEY_KEY_1_SHIFT 8
-#define I40E_VSIQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_VSIQF_HKEY_KEY_1_SHIFT)
-#define I40E_VSIQF_HKEY_KEY_2_SHIFT 16
-#define I40E_VSIQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_VSIQF_HKEY_KEY_2_SHIFT)
-#define I40E_VSIQF_HKEY_KEY_3_SHIFT 24
-#define I40E_VSIQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_VSIQF_HKEY_KEY_3_SHIFT)
-#define I40E_VSIQF_HLUT(_i, _VSI) (0x00220000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...15, _VSI=0...383 */ /* Reset: CORER */
-#define I40E_VSIQF_HLUT_MAX_INDEX 15
-#define I40E_VSIQF_HLUT_LUT0_SHIFT 0
-#define I40E_VSIQF_HLUT_LUT0_MASK I40E_MASK(0xF, I40E_VSIQF_HLUT_LUT0_SHIFT)
-#define I40E_VSIQF_HLUT_LUT1_SHIFT 8
-#define I40E_VSIQF_HLUT_LUT1_MASK I40E_MASK(0xF, I40E_VSIQF_HLUT_LUT1_SHIFT)
-#define I40E_VSIQF_HLUT_LUT2_SHIFT 16
-#define I40E_VSIQF_HLUT_LUT2_MASK I40E_MASK(0xF, I40E_VSIQF_HLUT_LUT2_SHIFT)
-#define I40E_VSIQF_HLUT_LUT3_SHIFT 24
-#define I40E_VSIQF_HLUT_LUT3_MASK I40E_MASK(0xF, I40E_VSIQF_HLUT_LUT3_SHIFT)
#define I40E_GLGEN_STAT_CLEAR 0x00390004 /* Reset: CORER */
-#define I40E_GLGEN_STAT_CLEAR_GLGEN_STAT_CLEAR_SHIFT 0
-#define I40E_GLGEN_STAT_CLEAR_GLGEN_STAT_CLEAR_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_CLEAR_GLGEN_STAT_CLEAR_SHIFT)
-#define I40E_GLGEN_STAT_HALT 0x00390000 /* Reset: CORER */
-#define I40E_GLGEN_STAT_HALT_HALT_CELLS_SHIFT 0
-#define I40E_GLGEN_STAT_HALT_HALT_CELLS_MASK I40E_MASK(0x3FFFFFFF, I40E_GLGEN_STAT_HALT_HALT_CELLS_SHIFT)
-#define I40E_VFINT_DYN_CTL01_WB_ON_ITR_SHIFT 30
-#define I40E_VFINT_DYN_CTL01_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_WB_ON_ITR_SHIFT)
-#define I40E_VFINT_DYN_CTLN1_WB_ON_ITR_SHIFT 30
-#define I40E_VFINT_DYN_CTLN1_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_WB_ON_ITR_SHIFT)
-#define I40E_VFPE_AEQALLOC1 0x0000A400 /* Reset: VFR */
-#define I40E_VFPE_AEQALLOC1_AECOUNT_SHIFT 0
-#define I40E_VFPE_AEQALLOC1_AECOUNT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_AEQALLOC1_AECOUNT_SHIFT)
-#define I40E_VFPE_CCQPHIGH1 0x00009800 /* Reset: VFR */
-#define I40E_VFPE_CCQPHIGH1_PECCQPHIGH_SHIFT 0
-#define I40E_VFPE_CCQPHIGH1_PECCQPHIGH_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_CCQPHIGH1_PECCQPHIGH_SHIFT)
-#define I40E_VFPE_CCQPLOW1 0x0000AC00 /* Reset: VFR */
-#define I40E_VFPE_CCQPLOW1_PECCQPLOW_SHIFT 0
-#define I40E_VFPE_CCQPLOW1_PECCQPLOW_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_CCQPLOW1_PECCQPLOW_SHIFT)
-#define I40E_VFPE_CCQPSTATUS1 0x0000B800 /* Reset: VFR */
-#define I40E_VFPE_CCQPSTATUS1_CCQP_DONE_SHIFT 0
-#define I40E_VFPE_CCQPSTATUS1_CCQP_DONE_MASK I40E_MASK(0x1, I40E_VFPE_CCQPSTATUS1_CCQP_DONE_SHIFT)
-#define I40E_VFPE_CCQPSTATUS1_HMC_PROFILE_SHIFT 4
-#define I40E_VFPE_CCQPSTATUS1_HMC_PROFILE_MASK I40E_MASK(0x7, I40E_VFPE_CCQPSTATUS1_HMC_PROFILE_SHIFT)
-#define I40E_VFPE_CCQPSTATUS1_RDMA_EN_VFS_SHIFT 16
-#define I40E_VFPE_CCQPSTATUS1_RDMA_EN_VFS_MASK I40E_MASK(0x3F, I40E_VFPE_CCQPSTATUS1_RDMA_EN_VFS_SHIFT)
-#define I40E_VFPE_CCQPSTATUS1_CCQP_ERR_SHIFT 31
-#define I40E_VFPE_CCQPSTATUS1_CCQP_ERR_MASK I40E_MASK(0x1, I40E_VFPE_CCQPSTATUS1_CCQP_ERR_SHIFT)
-#define I40E_VFPE_CQACK1 0x0000B000 /* Reset: VFR */
-#define I40E_VFPE_CQACK1_PECQID_SHIFT 0
-#define I40E_VFPE_CQACK1_PECQID_MASK I40E_MASK(0x1FFFF, I40E_VFPE_CQACK1_PECQID_SHIFT)
-#define I40E_VFPE_CQARM1 0x0000B400 /* Reset: VFR */
-#define I40E_VFPE_CQARM1_PECQID_SHIFT 0
-#define I40E_VFPE_CQARM1_PECQID_MASK I40E_MASK(0x1FFFF, I40E_VFPE_CQARM1_PECQID_SHIFT)
-#define I40E_VFPE_CQPDB1 0x0000BC00 /* Reset: VFR */
-#define I40E_VFPE_CQPDB1_WQHEAD_SHIFT 0
-#define I40E_VFPE_CQPDB1_WQHEAD_MASK I40E_MASK(0x7FF, I40E_VFPE_CQPDB1_WQHEAD_SHIFT)
-#define I40E_VFPE_CQPERRCODES1 0x00009C00 /* Reset: VFR */
-#define I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT 0
-#define I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_MASK I40E_MASK(0xFFFF, I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT)
-#define I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT 16
-#define I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_MASK I40E_MASK(0xFFFF, I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT)
-#define I40E_VFPE_CQPTAIL1 0x0000A000 /* Reset: VFR */
-#define I40E_VFPE_CQPTAIL1_WQTAIL_SHIFT 0
-#define I40E_VFPE_CQPTAIL1_WQTAIL_MASK I40E_MASK(0x7FF, I40E_VFPE_CQPTAIL1_WQTAIL_SHIFT)
-#define I40E_VFPE_CQPTAIL1_CQP_OP_ERR_SHIFT 31
-#define I40E_VFPE_CQPTAIL1_CQP_OP_ERR_MASK I40E_MASK(0x1, I40E_VFPE_CQPTAIL1_CQP_OP_ERR_SHIFT)
-#define I40E_VFPE_IPCONFIG01 0x00008C00 /* Reset: VFR */
-#define I40E_VFPE_IPCONFIG01_PEIPID_SHIFT 0
-#define I40E_VFPE_IPCONFIG01_PEIPID_MASK I40E_MASK(0xFFFF, I40E_VFPE_IPCONFIG01_PEIPID_SHIFT)
-#define I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT 16
-#define I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_MASK I40E_MASK(0x1, I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT)
-#define I40E_VFPE_MRTEIDXMASK1 0x00009000 /* Reset: VFR */
-#define I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT 0
-#define I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_MASK I40E_MASK(0x1F, I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT)
-#define I40E_VFPE_RCVUNEXPECTEDERROR1 0x00009400 /* Reset: VFR */
-#define I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT 0
-#define I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_MASK I40E_MASK(0xFFFFFF, I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT)
-#define I40E_VFPE_TCPNOWTIMER1 0x0000A800 /* Reset: VFR */
-#define I40E_VFPE_TCPNOWTIMER1_TCP_NOW_SHIFT 0
-#define I40E_VFPE_TCPNOWTIMER1_TCP_NOW_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_TCPNOWTIMER1_TCP_NOW_SHIFT)
-#define I40E_VFPE_WQEALLOC1 0x0000C000 /* Reset: VFR */
-#define I40E_VFPE_WQEALLOC1_PEQPID_SHIFT 0
-#define I40E_VFPE_WQEALLOC1_PEQPID_MASK I40E_MASK(0x3FFFF, I40E_VFPE_WQEALLOC1_PEQPID_SHIFT)
-#define I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT 20
-#define I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_MASK I40E_MASK(0xFFF, I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT)
#endif /* _I40E_REGISTER_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index f9555c847f73..3e5c566ceb01 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -1690,7 +1690,7 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi,
case I40E_RX_PTYPE_INNER_PROT_UDP:
case I40E_RX_PTYPE_INNER_PROT_SCTP:
skb->ip_summed = CHECKSUM_UNNECESSARY;
- /* fall though */
+ fallthrough;
default:
break;
}
@@ -2210,10 +2210,10 @@ static struct sk_buff *i40e_run_xdp(struct i40e_ring *rx_ring,
break;
default:
bpf_warn_invalid_xdp_action(act);
- /* fall through */
+ fallthrough;
case XDP_ABORTED:
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
- /* fall through -- handle aborts by dropping packet */
+ fallthrough; /* handle aborts by dropping packet */
case XDP_DROP:
result = I40E_XDP_CONSUMED;
break;
@@ -2580,7 +2580,7 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
*/
i40e_for_each_ring(ring, q_vector->tx) {
bool wd = ring->xsk_umem ?
- i40e_clean_xdp_tx_irq(vsi, ring, budget) :
+ i40e_clean_xdp_tx_irq(vsi, ring) :
i40e_clean_tx_irq(vsi, ring, budget);
if (!wd) {
@@ -2595,10 +2595,16 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
if (budget <= 0)
goto tx_only;
- /* We attempt to distribute budget to each Rx queue fairly, but don't
- * allow the budget to go below 1 because that would exit polling early.
- */
- budget_per_ring = max(budget/q_vector->num_ringpairs, 1);
+ /* normally we have 1 Rx ring per q_vector */
+ if (unlikely(q_vector->num_ringpairs > 1))
+ /* We attempt to distribute budget to each Rx queue fairly, but
+ * don't allow the budget to go below 1 because that would exit
+ * polling early.
+ */
+ budget_per_ring = max_t(int, budget / q_vector->num_ringpairs, 1);
+ else
+ /* Max of 1 Rx ring in this q_vector so give it the budget */
+ budget_per_ring = budget;
i40e_for_each_ring(ring, q_vector->rx) {
int cleaned = ring->xsk_umem ?
@@ -3538,6 +3544,7 @@ static int i40e_xmit_xdp_ring(struct xdp_frame *xdpf,
*/
smp_wmb();
+ xdp_ring->xdp_tx_active++;
i++;
if (i == xdp_ring->count)
i = 0;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
index 5c255977fd58..4036893d6825 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
@@ -18,10 +18,7 @@
#define I40E_ITR_DYNAMIC 0x8000 /* use top bit as a flag */
#define I40E_ITR_MASK 0x1FFE /* mask for ITR register value */
#define I40E_MIN_ITR 2 /* reg uses 2 usec resolution */
-#define I40E_ITR_100K 10 /* all values below must be even */
-#define I40E_ITR_50K 20
#define I40E_ITR_20K 50
-#define I40E_ITR_18K 60
#define I40E_ITR_8K 122
#define I40E_MAX_ITR 8160 /* maximum value as per datasheet */
#define ITR_TO_REG(setting) ((setting) & ~I40E_ITR_DYNAMIC)
@@ -52,9 +49,6 @@ static inline u16 i40e_intrl_usec_to_reg(int intrl)
else
return 0;
}
-#define I40E_INTRL_8K 125 /* 8000 ints/sec */
-#define I40E_INTRL_62K 16 /* 62500 ints/sec */
-#define I40E_INTRL_83K 12 /* 83333 ints/sec */
#define I40E_QUEUE_END_OF_LIST 0x7FF
@@ -73,7 +67,6 @@ enum i40e_dyn_idx_t {
/* these are indexes into ITRN registers */
#define I40E_RX_ITR I40E_IDX_ITR0
#define I40E_TX_ITR I40E_IDX_ITR1
-#define I40E_PE_ITR I40E_IDX_ITR2
/* Supported RSS offloads */
#define I40E_DEFAULT_RSS_HENA ( \
@@ -193,13 +186,6 @@ static inline bool i40e_test_staterr(union i40e_rx_desc *rx_desc,
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define I40E_RX_BUFFER_WRITE 32 /* Must be power of 2 */
-#define I40E_RX_INCREMENT(r, i) \
- do { \
- (i)++; \
- if ((i) == (r)->count) \
- i = 0; \
- r->next_to_clean = i; \
- } while (0)
#define I40E_RX_NEXT_DESC(r, i, n) \
do { \
@@ -209,11 +195,6 @@ static inline bool i40e_test_staterr(union i40e_rx_desc *rx_desc,
(n) = I40E_RX_DESC((r), (i)); \
} while (0)
-#define I40E_RX_NEXT_DESC_PREFETCH(r, i, n) \
- do { \
- I40E_RX_NEXT_DESC((r), (i), (n)); \
- prefetch((n)); \
- } while (0)
#define I40E_MAX_BUFFER_TXD 8
#define I40E_MIN_TX_LEN 17
@@ -262,15 +243,12 @@ static inline unsigned int i40e_txd_use_count(unsigned int size)
/* Tx Descriptors needed, worst case */
#define DESC_NEEDED (MAX_SKB_FRAGS + 6)
-#define I40E_MIN_DESC_PENDING 4
#define I40E_TX_FLAGS_HW_VLAN BIT(1)
#define I40E_TX_FLAGS_SW_VLAN BIT(2)
#define I40E_TX_FLAGS_TSO BIT(3)
#define I40E_TX_FLAGS_IPV4 BIT(4)
#define I40E_TX_FLAGS_IPV6 BIT(5)
-#define I40E_TX_FLAGS_FCCRC BIT(6)
-#define I40E_TX_FLAGS_FSO BIT(7)
#define I40E_TX_FLAGS_TSYN BIT(8)
#define I40E_TX_FLAGS_FD_SB BIT(9)
#define I40E_TX_FLAGS_UDP_TUNNEL BIT(10)
@@ -332,9 +310,7 @@ enum i40e_ring_state_t {
/* some useful defines for virtchannel interface, which
* is the only remaining user of header split
*/
-#define I40E_RX_DTYPE_NO_SPLIT 0
#define I40E_RX_DTYPE_HEADER_SPLIT 1
-#define I40E_RX_DTYPE_SPLIT_ALWAYS 2
#define I40E_RX_SPLIT_L2 0x1
#define I40E_RX_SPLIT_IP 0x2
#define I40E_RX_SPLIT_TCP_UDP 0x4
@@ -371,6 +347,7 @@ struct i40e_ring {
/* used in interrupt processing */
u16 next_to_use;
u16 next_to_clean;
+ u16 xdp_tx_active;
u8 atr_sample_rate;
u8 atr_count;
@@ -444,7 +421,6 @@ static inline void set_ring_xdp(struct i40e_ring *ring)
#define I40E_ITR_ADAPTIVE_MAX_USECS 0x007e
#define I40E_ITR_ADAPTIVE_LATENCY 0x8000
#define I40E_ITR_ADAPTIVE_BULK 0x0000
-#define ITR_IS_BULK(x) (!((x) & I40E_ITR_ADAPTIVE_LATENCY))
struct i40e_ring_container {
struct i40e_ring *ring; /* pointer to linked list of ring(s) */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 63e098f7cb63..52410d609ba1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -84,8 +84,6 @@ enum i40e_debug_mask {
I40E_GLGEN_MSCA_OPCODE_SHIFT)
#define I40E_MDIO_CLAUSE45_OPCODE_WRITE_MASK I40E_MASK(1, \
I40E_GLGEN_MSCA_OPCODE_SHIFT)
-#define I40E_MDIO_CLAUSE45_OPCODE_READ_INC_ADDR_MASK I40E_MASK(2, \
- I40E_GLGEN_MSCA_OPCODE_SHIFT)
#define I40E_MDIO_CLAUSE45_OPCODE_READ_MASK I40E_MASK(3, \
I40E_GLGEN_MSCA_OPCODE_SHIFT)
@@ -178,21 +176,9 @@ struct i40e_link_status {
u8 module_type[3];
/* 1st byte: module identifier */
#define I40E_MODULE_TYPE_SFP 0x03
-#define I40E_MODULE_TYPE_QSFP 0x0D
- /* 2nd byte: ethernet compliance codes for 10/40G */
-#define I40E_MODULE_TYPE_40G_ACTIVE 0x01
-#define I40E_MODULE_TYPE_40G_LR4 0x02
-#define I40E_MODULE_TYPE_40G_SR4 0x04
-#define I40E_MODULE_TYPE_40G_CR4 0x08
-#define I40E_MODULE_TYPE_10G_BASE_SR 0x10
-#define I40E_MODULE_TYPE_10G_BASE_LR 0x20
-#define I40E_MODULE_TYPE_10G_BASE_LRM 0x40
-#define I40E_MODULE_TYPE_10G_BASE_ER 0x80
/* 3rd byte: ethernet compliance codes for 1G */
#define I40E_MODULE_TYPE_1000BASE_SX 0x01
#define I40E_MODULE_TYPE_1000BASE_LX 0x02
-#define I40E_MODULE_TYPE_1000BASE_CX 0x04
-#define I40E_MODULE_TYPE_1000BASE_T 0x08
};
struct i40e_phy_info {
@@ -262,9 +248,6 @@ struct i40e_phy_info {
/* Capabilities of a PF or a VF or the whole device */
struct i40e_hw_capabilities {
u32 switch_mode;
-#define I40E_NVM_IMAGE_TYPE_EVB 0x0
-#define I40E_NVM_IMAGE_TYPE_CLOUD 0x2
-#define I40E_NVM_IMAGE_TYPE_UDP_CLOUD 0x3
/* Cloud filter modes:
* Mode1: Filter on L4 port only
@@ -273,14 +256,10 @@ struct i40e_hw_capabilities {
*/
#define I40E_CLOUD_FILTER_MODE1 0x6
#define I40E_CLOUD_FILTER_MODE2 0x7
-#define I40E_CLOUD_FILTER_MODE3 0x8
#define I40E_SWITCH_MODE_MASK 0xF
u32 management_mode;
u32 mng_protocols_over_mctp;
-#define I40E_MNG_PROTOCOL_PLDM 0x2
-#define I40E_MNG_PROTOCOL_OEM_COMMANDS 0x4
-#define I40E_MNG_PROTOCOL_NCSI 0x8
u32 npar_enable;
u32 os2bmc;
u32 valid_functions;
@@ -294,13 +273,8 @@ struct i40e_hw_capabilities {
bool flex10_enable;
bool flex10_capable;
u32 flex10_mode;
-#define I40E_FLEX10_MODE_UNKNOWN 0x0
-#define I40E_FLEX10_MODE_DCC 0x1
-#define I40E_FLEX10_MODE_DCI 0x2
u32 flex10_status;
-#define I40E_FLEX10_STATUS_DCC_ERROR 0x1
-#define I40E_FLEX10_STATUS_VC_MODE 0x2
bool sec_rev_disabled;
bool update_disabled;
@@ -421,11 +395,8 @@ enum i40e_nvmupd_state {
#define I40E_NVM_AQE 0xe
#define I40E_NVM_EXEC 0xf
-#define I40E_NVM_ADAPT_SHIFT 16
-#define I40E_NVM_ADAPT_MASK (0xffff << I40E_NVM_ADAPT_SHIFT)
#define I40E_NVMUPD_MAX_DATA 4096
-#define I40E_NVMUPD_IFACE_TIMEOUT 2 /* seconds */
struct i40e_nvm_access {
u32 command;
@@ -438,7 +409,6 @@ struct i40e_nvm_access {
/* (Q)SFP module access definitions */
#define I40E_I2C_EEPROM_DEV_ADDR 0xA0
#define I40E_I2C_EEPROM_DEV_ADDR2 0xA2
-#define I40E_MODULE_TYPE_ADDR 0x00
#define I40E_MODULE_REVISION_ADDR 0x01
#define I40E_MODULE_SFF_8472_COMP 0x5E
#define I40E_MODULE_SFF_8472_SWAP 0x5C
@@ -547,7 +517,6 @@ struct i40e_dcbx_config {
#define I40E_DCBX_MODE_CEE 0x1
#define I40E_DCBX_MODE_IEEE 0x2
u8 app_mode;
-#define I40E_DCBX_APPS_NON_WILLING 0x1
u32 numapps;
u32 tlv_status; /* CEE mode TLV status */
struct i40e_dcb_ets_config etscfg;
@@ -895,9 +864,6 @@ enum i40e_rx_ptype_payload_layer {
#define I40E_RXD_QW1_LENGTH_PBUF_MASK (0x3FFFULL << \
I40E_RXD_QW1_LENGTH_PBUF_SHIFT)
-#define I40E_RXD_QW1_LENGTH_HBUF_SHIFT 52
-#define I40E_RXD_QW1_LENGTH_HBUF_MASK (0x7FFULL << \
- I40E_RXD_QW1_LENGTH_HBUF_SHIFT)
#define I40E_RXD_QW1_LENGTH_SPH_SHIFT 63
#define I40E_RXD_QW1_LENGTH_SPH_MASK BIT_ULL(I40E_RXD_QW1_LENGTH_SPH_SHIFT)
@@ -926,7 +892,6 @@ enum i40e_rx_desc_pe_status_bits {
I40E_RX_DESC_PE_STATUS_IPOPT_SHIFT = 29
};
-#define I40E_RX_PROG_STATUS_DESC_LENGTH_SHIFT 38
#define I40E_RX_PROG_STATUS_DESC_LENGTH 0x2000000
#define I40E_RX_PROG_STATUS_DESC_QW1_PROGID_SHIFT 2
@@ -963,8 +928,6 @@ struct i40e_tx_desc {
__le64 cmd_type_offset_bsz;
};
-#define I40E_TXD_QW1_DTYPE_SHIFT 0
-#define I40E_TXD_QW1_DTYPE_MASK (0xFUL << I40E_TXD_QW1_DTYPE_SHIFT)
enum i40e_tx_desc_dtype_value {
I40E_TX_DESC_DTYPE_DATA = 0x0,
@@ -980,7 +943,6 @@ enum i40e_tx_desc_dtype_value {
};
#define I40E_TXD_QW1_CMD_SHIFT 4
-#define I40E_TXD_QW1_CMD_MASK (0x3FFUL << I40E_TXD_QW1_CMD_SHIFT)
enum i40e_tx_desc_cmd_bits {
I40E_TX_DESC_CMD_EOP = 0x0001,
@@ -1004,8 +966,6 @@ enum i40e_tx_desc_cmd_bits {
};
#define I40E_TXD_QW1_OFFSET_SHIFT 16
-#define I40E_TXD_QW1_OFFSET_MASK (0x3FFFFULL << \
- I40E_TXD_QW1_OFFSET_SHIFT)
enum i40e_tx_desc_length_fields {
/* Note: These are predefined bit offsets */
@@ -1015,11 +975,8 @@ enum i40e_tx_desc_length_fields {
};
#define I40E_TXD_QW1_TX_BUF_SZ_SHIFT 34
-#define I40E_TXD_QW1_TX_BUF_SZ_MASK (0x3FFFULL << \
- I40E_TXD_QW1_TX_BUF_SZ_SHIFT)
#define I40E_TXD_QW1_L2TAG1_SHIFT 48
-#define I40E_TXD_QW1_L2TAG1_MASK (0xFFFFULL << I40E_TXD_QW1_L2TAG1_SHIFT)
/* Context descriptors */
struct i40e_tx_context_desc {
@@ -1029,11 +986,8 @@ struct i40e_tx_context_desc {
__le64 type_cmd_tso_mss;
};
-#define I40E_TXD_CTX_QW1_DTYPE_SHIFT 0
-#define I40E_TXD_CTX_QW1_DTYPE_MASK (0xFUL << I40E_TXD_CTX_QW1_DTYPE_SHIFT)
#define I40E_TXD_CTX_QW1_CMD_SHIFT 4
-#define I40E_TXD_CTX_QW1_CMD_MASK (0xFFFFUL << I40E_TXD_CTX_QW1_CMD_SHIFT)
enum i40e_tx_ctx_desc_cmd_bits {
I40E_TX_CTX_DESC_TSO = 0x01,
@@ -1048,19 +1002,10 @@ enum i40e_tx_ctx_desc_cmd_bits {
};
#define I40E_TXD_CTX_QW1_TSO_LEN_SHIFT 30
-#define I40E_TXD_CTX_QW1_TSO_LEN_MASK (0x3FFFFULL << \
- I40E_TXD_CTX_QW1_TSO_LEN_SHIFT)
#define I40E_TXD_CTX_QW1_MSS_SHIFT 50
-#define I40E_TXD_CTX_QW1_MSS_MASK (0x3FFFULL << \
- I40E_TXD_CTX_QW1_MSS_SHIFT)
-#define I40E_TXD_CTX_QW1_VSI_SHIFT 50
-#define I40E_TXD_CTX_QW1_VSI_MASK (0x1FFULL << I40E_TXD_CTX_QW1_VSI_SHIFT)
-#define I40E_TXD_CTX_QW0_EXT_IP_SHIFT 0
-#define I40E_TXD_CTX_QW0_EXT_IP_MASK (0x3ULL << \
- I40E_TXD_CTX_QW0_EXT_IP_SHIFT)
enum i40e_tx_ctx_desc_eipt_offload {
I40E_TX_CTX_EXT_IP_NONE = 0x0,
@@ -1070,28 +1015,16 @@ enum i40e_tx_ctx_desc_eipt_offload {
};
#define I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT 2
-#define I40E_TXD_CTX_QW0_EXT_IPLEN_MASK (0x3FULL << \
- I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT)
#define I40E_TXD_CTX_QW0_NATT_SHIFT 9
-#define I40E_TXD_CTX_QW0_NATT_MASK (0x3ULL << I40E_TXD_CTX_QW0_NATT_SHIFT)
#define I40E_TXD_CTX_UDP_TUNNELING BIT_ULL(I40E_TXD_CTX_QW0_NATT_SHIFT)
#define I40E_TXD_CTX_GRE_TUNNELING (0x2ULL << I40E_TXD_CTX_QW0_NATT_SHIFT)
-#define I40E_TXD_CTX_QW0_EIP_NOINC_SHIFT 11
-#define I40E_TXD_CTX_QW0_EIP_NOINC_MASK \
- BIT_ULL(I40E_TXD_CTX_QW0_EIP_NOINC_SHIFT)
-#define I40E_TXD_CTX_EIP_NOINC_IPID_CONST I40E_TXD_CTX_QW0_EIP_NOINC_MASK
#define I40E_TXD_CTX_QW0_NATLEN_SHIFT 12
-#define I40E_TXD_CTX_QW0_NATLEN_MASK (0X7FULL << \
- I40E_TXD_CTX_QW0_NATLEN_SHIFT)
-#define I40E_TXD_CTX_QW0_DECTTL_SHIFT 19
-#define I40E_TXD_CTX_QW0_DECTTL_MASK (0xFULL << \
- I40E_TXD_CTX_QW0_DECTTL_SHIFT)
#define I40E_TXD_CTX_QW0_L4T_CS_SHIFT 23
#define I40E_TXD_CTX_QW0_L4T_CS_MASK BIT_ULL(I40E_TXD_CTX_QW0_L4T_CS_SHIFT)
@@ -1161,11 +1094,8 @@ enum i40e_filter_program_desc_fd_status {
I40E_TXD_FLTR_QW0_DEST_VSI_SHIFT)
#define I40E_TXD_FLTR_QW1_CMD_SHIFT 4
-#define I40E_TXD_FLTR_QW1_CMD_MASK (0xFFFFULL << \
- I40E_TXD_FLTR_QW1_CMD_SHIFT)
#define I40E_TXD_FLTR_QW1_PCMD_SHIFT (0x0ULL + I40E_TXD_FLTR_QW1_CMD_SHIFT)
-#define I40E_TXD_FLTR_QW1_PCMD_MASK (0x7ULL << I40E_TXD_FLTR_QW1_PCMD_SHIFT)
enum i40e_filter_program_desc_pcmd {
I40E_FILTER_PROGRAM_DESC_PCMD_ADD_UPDATE = 0x1,
@@ -1316,7 +1246,6 @@ struct i40e_hw_port_stats {
#define I40E_NVM_OEM_VER_OFF 0x83
#define I40E_SR_NVM_DEV_STARTER_VERSION 0x18
#define I40E_SR_NVM_WAKE_ON_LAN 0x19
-#define I40E_SR_ALTERNATE_SAN_MAC_ADDRESS_PTR 0x27
#define I40E_SR_NVM_EETRACK_LO 0x2D
#define I40E_SR_NVM_EETRACK_HI 0x2E
#define I40E_SR_VPD_PTR 0x2F
@@ -1329,7 +1258,6 @@ struct i40e_hw_port_stats {
#define I40E_SR_PCIE_ALT_MODULE_MAX_SIZE 1024
#define I40E_SR_CONTROL_WORD_1_SHIFT 0x06
#define I40E_SR_CONTROL_WORD_1_MASK (0x03 << I40E_SR_CONTROL_WORD_1_SHIFT)
-#define I40E_SR_CONTROL_WORD_1_NVM_BANK_VALID BIT(5)
#define I40E_SR_NVM_MAP_STRUCTURE_TYPE BIT(12)
#define I40E_PTR_TYPE BIT(15)
#define I40E_SR_OCP_CFG_WORD0 0x2B
@@ -1463,14 +1391,11 @@ struct i40e_lldp_variables {
/* Offsets into Alternate Ram */
#define I40E_ALT_STRUCT_FIRST_PF_OFFSET 0 /* in dwords */
#define I40E_ALT_STRUCT_DWORDS_PER_PF 64 /* in dwords */
-#define I40E_ALT_STRUCT_OUTER_VLAN_TAG_OFFSET 0xD /* in dwords */
-#define I40E_ALT_STRUCT_USER_PRIORITY_OFFSET 0xC /* in dwords */
#define I40E_ALT_STRUCT_MIN_BW_OFFSET 0xE /* in dwords */
#define I40E_ALT_STRUCT_MAX_BW_OFFSET 0xF /* in dwords */
/* Alternate Ram Bandwidth Masks */
#define I40E_ALT_BW_VALUE_MASK 0xFF
-#define I40E_ALT_BW_RELATIVE_MASK 0x40000000
#define I40E_ALT_BW_VALID_MASK 0x80000000
/* RSS Hash Table Size */
@@ -1529,9 +1454,7 @@ struct i40e_package_header {
/* Generic segment header */
struct i40e_generic_seg_header {
#define SEGMENT_TYPE_METADATA 0x00000001
-#define SEGMENT_TYPE_NOTES 0x00000002
#define SEGMENT_TYPE_I40E 0x00000011
-#define SEGMENT_TYPE_X722 0x00000012
u32 type;
struct i40e_ddp_version version;
u32 size;
@@ -1541,7 +1464,6 @@ struct i40e_generic_seg_header {
struct i40e_metadata_segment {
struct i40e_generic_seg_header header;
struct i40e_ddp_version version;
-#define I40E_DDP_TRACKID_RDONLY 0
#define I40E_DDP_TRACKID_INVALID 0xFFFFFFFF
u32 track_id;
char name[I40E_DDP_NAME_SIZE];
@@ -1575,10 +1497,6 @@ struct i40e_profile_section_header {
#define SECTION_TYPE_AQ 0x00000801
#define SECTION_TYPE_RB_AQ 0x00001801
#define SECTION_TYPE_NOTE 0x80000000
-#define SECTION_TYPE_NAME 0x80000001
-#define SECTION_TYPE_PROTO 0x80000002
-#define SECTION_TYPE_PCTYPE 0x80000003
-#define SECTION_TYPE_PTYPE 0x80000004
u32 type;
u32 offset;
u32 size;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 56b9e445732b..8e133d6545bd 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -1106,39 +1106,81 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf)
return -EIO;
}
-static inline int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi);
+/**
+ * i40e_getnum_vf_vsi_vlan_filters
+ * @vsi: pointer to the vsi
+ *
+ * called to get the number of VLANs offloaded on this VF
+ **/
+static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
+{
+ struct i40e_mac_filter *f;
+ int num_vlans = 0, bkt;
+
+ hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
+ if (f->vlan >= 0 && f->vlan <= I40E_MAX_VLANID)
+ num_vlans++;
+ }
+
+ return num_vlans;
+}
/**
- * i40e_config_vf_promiscuous_mode
- * @vf: pointer to the VF info
- * @vsi_id: VSI id
- * @allmulti: set MAC L2 layer multicast promiscuous enable/disable
- * @alluni: set MAC L2 layer unicast promiscuous enable/disable
+ * i40e_get_vlan_list_sync
+ * @vsi: pointer to the VSI
+ * @num_vlans: number of VLANs in mac_filter_hash, returned to caller
+ * @vlan_list: list of VLANs present in mac_filter_hash, returned to caller.
+ * This array is allocated here, but has to be freed in caller.
*
- * Called from the VF to configure the promiscuous mode of
- * VF vsis and from the VF reset path to reset promiscuous mode.
+ * Called to get number of VLANs and VLAN list present in mac_filter_hash.
**/
-static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
- u16 vsi_id,
- bool allmulti,
- bool alluni)
+static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, int *num_vlans,
+ s16 **vlan_list)
{
- struct i40e_pf *pf = vf->pf;
- struct i40e_hw *hw = &pf->hw;
struct i40e_mac_filter *f;
- i40e_status aq_ret = 0;
- struct i40e_vsi *vsi;
+ int i = 0;
int bkt;
- vsi = i40e_find_vsi_from_id(pf, vsi_id);
- if (!i40e_vc_isvalid_vsi_id(vf, vsi_id) || !vsi)
- return I40E_ERR_PARAM;
+ spin_lock_bh(&vsi->mac_filter_hash_lock);
+ *num_vlans = i40e_getnum_vf_vsi_vlan_filters(vsi);
+ *vlan_list = kcalloc(*num_vlans, sizeof(**vlan_list), GFP_ATOMIC);
+ if (!(*vlan_list))
+ goto err;
- if (vf->port_vlan_id) {
- aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw, vsi->seid,
- allmulti,
- vf->port_vlan_id,
- NULL);
+ hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
+ if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID)
+ continue;
+ (*vlan_list)[i++] = f->vlan;
+ }
+err:
+ spin_unlock_bh(&vsi->mac_filter_hash_lock);
+}
+
+/**
+ * i40e_set_vsi_promisc
+ * @vf: pointer to the VF struct
+ * @seid: VSI number
+ * @multi_enable: set MAC L2 layer multicast promiscuous enable/disable
+ * for a given VLAN
+ * @unicast_enable: set MAC L2 layer unicast promiscuous enable/disable
+ * for a given VLAN
+ * @vl: List of VLANs - apply filter for given VLANs
+ * @num_vlans: Number of elements in @vl
+ **/
+static i40e_status
+i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+ bool unicast_enable, s16 *vl, int num_vlans)
+{
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_hw *hw = &pf->hw;
+ i40e_status aq_ret;
+ int i;
+
+ /* No VLAN to set promisc on, set on VSI */
+ if (!num_vlans || !vl) {
+ aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, seid,
+ multi_enable,
+ NULL);
if (aq_ret) {
int aq_err = pf->hw.aq.asq_last_status;
@@ -1147,13 +1189,14 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
vf->vf_id,
i40e_stat_str(&pf->hw, aq_ret),
i40e_aq_str(&pf->hw, aq_err));
+
return aq_ret;
}
- aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, vsi->seid,
- alluni,
- vf->port_vlan_id,
- NULL);
+ aq_ret = i40e_aq_set_vsi_unicast_promiscuous(hw, seid,
+ unicast_enable,
+ NULL, true);
+
if (aq_ret) {
int aq_err = pf->hw.aq.asq_last_status;
@@ -1163,68 +1206,84 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
i40e_stat_str(&pf->hw, aq_ret),
i40e_aq_str(&pf->hw, aq_err));
}
+
return aq_ret;
- } else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) {
- hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
- if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID)
- continue;
- aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw,
- vsi->seid,
- allmulti,
- f->vlan,
- NULL);
- if (aq_ret) {
- int aq_err = pf->hw.aq.asq_last_status;
+ }
- dev_err(&pf->pdev->dev,
- "Could not add VLAN %d to multicast promiscuous domain err %s aq_err %s\n",
- f->vlan,
- i40e_stat_str(&pf->hw, aq_ret),
- i40e_aq_str(&pf->hw, aq_err));
- }
+ for (i = 0; i < num_vlans; i++) {
+ aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw, seid,
+ multi_enable,
+ vl[i], NULL);
+ if (aq_ret) {
+ int aq_err = pf->hw.aq.asq_last_status;
+
+ dev_err(&pf->pdev->dev,
+ "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n",
+ vf->vf_id,
+ i40e_stat_str(&pf->hw, aq_ret),
+ i40e_aq_str(&pf->hw, aq_err));
+ }
- aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw,
- vsi->seid,
- alluni,
- f->vlan,
- NULL);
- if (aq_ret) {
- int aq_err = pf->hw.aq.asq_last_status;
+ aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, seid,
+ unicast_enable,
+ vl[i], NULL);
+ if (aq_ret) {
+ int aq_err = pf->hw.aq.asq_last_status;
- dev_err(&pf->pdev->dev,
- "Could not add VLAN %d to Unicast promiscuous domain err %s aq_err %s\n",
- f->vlan,
- i40e_stat_str(&pf->hw, aq_ret),
- i40e_aq_str(&pf->hw, aq_err));
- }
+ dev_err(&pf->pdev->dev,
+ "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n",
+ vf->vf_id,
+ i40e_stat_str(&pf->hw, aq_ret),
+ i40e_aq_str(&pf->hw, aq_err));
}
- return aq_ret;
}
- aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, allmulti,
- NULL);
- if (aq_ret) {
- int aq_err = pf->hw.aq.asq_last_status;
+ return aq_ret;
+}
- dev_err(&pf->pdev->dev,
- "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n",
- vf->vf_id,
- i40e_stat_str(&pf->hw, aq_ret),
- i40e_aq_str(&pf->hw, aq_err));
+/**
+ * i40e_config_vf_promiscuous_mode
+ * @vf: pointer to the VF info
+ * @vsi_id: VSI id
+ * @allmulti: set MAC L2 layer multicast promiscuous enable/disable
+ * @alluni: set MAC L2 layer unicast promiscuous enable/disable
+ *
+ * Called from the VF to configure the promiscuous mode of
+ * VF vsis and from the VF reset path to reset promiscuous mode.
+ **/
+static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
+ u16 vsi_id,
+ bool allmulti,
+ bool alluni)
+{
+ i40e_status aq_ret = I40E_SUCCESS;
+ struct i40e_pf *pf = vf->pf;
+ struct i40e_vsi *vsi;
+ int num_vlans;
+ s16 *vl;
+
+ vsi = i40e_find_vsi_from_id(pf, vsi_id);
+ if (!i40e_vc_isvalid_vsi_id(vf, vsi_id) || !vsi)
+ return I40E_ERR_PARAM;
+
+ if (vf->port_vlan_id) {
+ aq_ret = i40e_set_vsi_promisc(vf, vsi->seid, allmulti,
+ alluni, &vf->port_vlan_id, 1);
return aq_ret;
- }
+ } else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) {
+ i40e_get_vlan_list_sync(vsi, &num_vlans, &vl);
- aq_ret = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, alluni,
- NULL, true);
- if (aq_ret) {
- int aq_err = pf->hw.aq.asq_last_status;
+ if (!vl)
+ return I40E_ERR_NO_MEMORY;
- dev_err(&pf->pdev->dev,
- "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n",
- vf->vf_id,
- i40e_stat_str(&pf->hw, aq_ret),
- i40e_aq_str(&pf->hw, aq_err));
+ aq_ret = i40e_set_vsi_promisc(vf, vsi->seid, allmulti, alluni,
+ vl, num_vlans);
+ kfree(vl);
+ return aq_ret;
}
+ /* no VLANs to set on, set on VSI */
+ aq_ret = i40e_set_vsi_promisc(vf, vsi->seid, allmulti, alluni,
+ NULL, 0);
return aq_ret;
}
@@ -1973,25 +2032,6 @@ static void i40e_vc_reset_vf_msg(struct i40e_vf *vf)
}
/**
- * i40e_getnum_vf_vsi_vlan_filters
- * @vsi: pointer to the vsi
- *
- * called to get the number of VLANs offloaded on this VF
- **/
-static inline int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
-{
- struct i40e_mac_filter *f;
- int num_vlans = 0, bkt;
-
- hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
- if (f->vlan >= 0 && f->vlan <= I40E_MAX_VLANID)
- num_vlans++;
- }
-
- return num_vlans;
-}
-
-/**
* i40e_vc_config_promiscuous_mode_msg
* @vf: pointer to the VF info
* @msg: pointer to the msg buffer
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
index 631248c0981a..5491215d81de 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
@@ -10,7 +10,6 @@
#define I40E_VIRTCHNL_SUPPORTED_QTYPES 2
-#define I40E_DEFAULT_NUM_MDD_EVENTS_ALLOWED 3
#define I40E_DEFAULT_NUM_INVALID_MSGS_ALLOWED 10
#define I40E_VLAN_PRIORITY_SHIFT 13
diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c b/drivers/net/ethernet/intel/i40e/i40e_xsk.c
index 7276580cbe64..8ce57b507a21 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c
@@ -168,10 +168,10 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
break;
default:
bpf_warn_invalid_xdp_action(act);
- /* fall through */
+ fallthrough;
case XDP_ABORTED:
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
- /* fallthrough -- handle aborts by dropping packet */
+ fallthrough; /* handle aborts by dropping packet */
case XDP_DROP:
result = I40E_XDP_CONSUMED;
break;
@@ -378,19 +378,13 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
**/
static bool i40e_xmit_zc(struct i40e_ring *xdp_ring, unsigned int budget)
{
+ unsigned int sent_frames = 0, total_bytes = 0;
struct i40e_tx_desc *tx_desc = NULL;
struct i40e_tx_buffer *tx_bi;
- bool work_done = true;
struct xdp_desc desc;
dma_addr_t dma;
while (budget-- > 0) {
- if (!unlikely(I40E_DESC_UNUSED(xdp_ring))) {
- xdp_ring->tx_stats.tx_busy++;
- work_done = false;
- break;
- }
-
if (!xsk_umem_consume_tx(xdp_ring->xsk_umem, &desc))
break;
@@ -408,6 +402,9 @@ static bool i40e_xmit_zc(struct i40e_ring *xdp_ring, unsigned int budget)
| I40E_TX_DESC_CMD_EOP,
0, desc.len, 0);
+ sent_frames++;
+ total_bytes += tx_bi->bytecount;
+
xdp_ring->next_to_use++;
if (xdp_ring->next_to_use == xdp_ring->count)
xdp_ring->next_to_use = 0;
@@ -420,9 +417,10 @@ static bool i40e_xmit_zc(struct i40e_ring *xdp_ring, unsigned int budget)
i40e_xdp_ring_update_tail(xdp_ring);
xsk_umem_consume_tx_done(xdp_ring->xsk_umem);
+ i40e_update_tx_stats(xdp_ring, sent_frames, total_bytes);
}
- return !!budget && work_done;
+ return !!budget;
}
/**
@@ -434,6 +432,7 @@ static void i40e_clean_xdp_tx_buffer(struct i40e_ring *tx_ring,
struct i40e_tx_buffer *tx_bi)
{
xdp_return_frame(tx_bi->xdpf);
+ tx_ring->xdp_tx_active--;
dma_unmap_single(tx_ring->dev,
dma_unmap_addr(tx_bi, dma),
dma_unmap_len(tx_bi, len), DMA_TO_DEVICE);
@@ -442,32 +441,29 @@ static void i40e_clean_xdp_tx_buffer(struct i40e_ring *tx_ring,
/**
* i40e_clean_xdp_tx_irq - Completes AF_XDP entries, and cleans XDP entries
+ * @vsi: Current VSI
* @tx_ring: XDP Tx ring
- * @tx_bi: Tx buffer info to clean
*
* Returns true if cleanup/tranmission is done.
**/
-bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi,
- struct i40e_ring *tx_ring, int napi_budget)
+bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring)
{
- unsigned int ntc, total_bytes = 0, budget = vsi->work_limit;
- u32 i, completed_frames, frames_ready, xsk_frames = 0;
struct xdp_umem *umem = tx_ring->xsk_umem;
+ u32 i, completed_frames, xsk_frames = 0;
u32 head_idx = i40e_get_head(tx_ring);
- bool work_done = true, xmit_done;
struct i40e_tx_buffer *tx_bi;
+ unsigned int ntc;
if (head_idx < tx_ring->next_to_clean)
head_idx += tx_ring->count;
- frames_ready = head_idx - tx_ring->next_to_clean;
+ completed_frames = head_idx - tx_ring->next_to_clean;
- if (frames_ready == 0) {
+ if (completed_frames == 0)
goto out_xmit;
- } else if (frames_ready > budget) {
- completed_frames = budget;
- work_done = false;
- } else {
- completed_frames = frames_ready;
+
+ if (likely(!tx_ring->xdp_tx_active)) {
+ xsk_frames = completed_frames;
+ goto skip;
}
ntc = tx_ring->next_to_clean;
@@ -475,18 +471,18 @@ bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi,
for (i = 0; i < completed_frames; i++) {
tx_bi = &tx_ring->tx_bi[ntc];
- if (tx_bi->xdpf)
+ if (tx_bi->xdpf) {
i40e_clean_xdp_tx_buffer(tx_ring, tx_bi);
- else
+ tx_bi->xdpf = NULL;
+ } else {
xsk_frames++;
-
- tx_bi->xdpf = NULL;
- total_bytes += tx_bi->bytecount;
+ }
if (++ntc >= tx_ring->count)
ntc = 0;
}
+skip:
tx_ring->next_to_clean += completed_frames;
if (unlikely(tx_ring->next_to_clean >= tx_ring->count))
tx_ring->next_to_clean -= tx_ring->count;
@@ -494,16 +490,13 @@ bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi,
if (xsk_frames)
xsk_umem_complete_tx(umem, xsk_frames);
- i40e_arm_wb(tx_ring, vsi, budget);
- i40e_update_tx_stats(tx_ring, completed_frames, total_bytes);
+ i40e_arm_wb(tx_ring, vsi, completed_frames);
out_xmit:
if (xsk_umem_uses_need_wakeup(tx_ring->xsk_umem))
xsk_set_tx_need_wakeup(tx_ring->xsk_umem);
- xmit_done = i40e_xmit_zc(tx_ring, budget);
-
- return work_done && xmit_done;
+ return i40e_xmit_zc(tx_ring, I40E_DESC_UNUSED(tx_ring));
}
/**
@@ -567,7 +560,7 @@ void i40e_xsk_clean_rx_ring(struct i40e_ring *rx_ring)
/**
* i40e_xsk_clean_xdp_ring - Clean the XDP Tx ring on shutdown
- * @xdp_ring: XDP Tx ring
+ * @tx_ring: XDP Tx ring
**/
void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring)
{
diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.h b/drivers/net/ethernet/intel/i40e/i40e_xsk.h
index ea919a7d60ec..c524c142127f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_xsk.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.h
@@ -15,8 +15,7 @@ int i40e_xsk_umem_setup(struct i40e_vsi *vsi, struct xdp_umem *umem,
bool i40e_alloc_rx_buffers_zc(struct i40e_ring *rx_ring, u16 cleaned_count);
int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget);
-bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi,
- struct i40e_ring *tx_ring, int napi_budget);
+bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring);
int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags);
int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring);
void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring);
diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
index 10b805ba03ee..8a65525a7c0d 100644
--- a/drivers/net/ethernet/intel/iavf/iavf.h
+++ b/drivers/net/ethernet/intel/iavf/iavf.h
@@ -375,7 +375,6 @@ struct iavf_device {
/* needed by iavf_ethtool.c */
extern char iavf_driver_name[];
-extern const char iavf_driver_version[];
extern struct workqueue_struct *iavf_wq;
int iavf_up(struct iavf_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
index 181573822942..c93567f4d0f7 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
@@ -571,7 +571,6 @@ static void iavf_get_drvinfo(struct net_device *netdev,
struct iavf_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, iavf_driver_name, 32);
- strlcpy(drvinfo->version, iavf_driver_version, 32);
strlcpy(drvinfo->fw_version, "N/A", 4);
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_priv_flags = IAVF_PRIV_FLAGS_STR_LEN;
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
index fa82768e5eda..d870343cf689 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -21,16 +21,6 @@ char iavf_driver_name[] = "iavf";
static const char iavf_driver_string[] =
"Intel(R) Ethernet Adaptive Virtual Function Network Driver";
-#define DRV_KERN "-k"
-
-#define DRV_VERSION_MAJOR 3
-#define DRV_VERSION_MINOR 2
-#define DRV_VERSION_BUILD 3
-#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
- __stringify(DRV_VERSION_MINOR) "." \
- __stringify(DRV_VERSION_BUILD) \
- DRV_KERN
-const char iavf_driver_version[] = DRV_VERSION;
static const char iavf_copyright[] =
"Copyright (c) 2013 - 2018 Intel Corporation.";
@@ -57,7 +47,6 @@ MODULE_ALIAS("i40evf");
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION("Intel(R) Ethernet Adaptive Virtual Function Network Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
static const struct net_device_ops iavf_netdev_ops;
struct workqueue_struct *iavf_wq;
@@ -1863,8 +1852,10 @@ static int iavf_init_get_resources(struct iavf_adapter *adapter)
adapter->rss_key = kzalloc(adapter->rss_key_size, GFP_KERNEL);
adapter->rss_lut = kzalloc(adapter->rss_lut_size, GFP_KERNEL);
- if (!adapter->rss_key || !adapter->rss_lut)
+ if (!adapter->rss_key || !adapter->rss_lut) {
+ err = -ENOMEM;
goto err_mem;
+ }
if (RSS_AQ(adapter))
adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_RSS;
else
@@ -1946,7 +1937,10 @@ static void iavf_watchdog_task(struct work_struct *work)
iavf_send_api_ver(adapter);
}
} else {
- if (!iavf_process_aq_command(adapter) &&
+ /* An error will be returned if no commands were
+ * processed; use this opportunity to update stats
+ */
+ if (iavf_process_aq_command(adapter) &&
adapter->state == __IAVF_RUNNING)
iavf_request_stats(adapter);
}
@@ -3772,7 +3766,6 @@ err_dma:
return err;
}
-#ifdef CONFIG_PM
/**
* iavf_suspend - Power management suspend routine
* @pdev: PCI device information struct
@@ -3780,11 +3773,10 @@ err_dma:
*
* Called when the system (VM) is entering sleep/suspend.
**/
-static int iavf_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused iavf_suspend(struct device *dev_d)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
+ struct net_device *netdev = dev_get_drvdata(dev_d);
struct iavf_adapter *adapter = netdev_priv(netdev);
- int retval = 0;
netif_device_detach(netdev);
@@ -3802,12 +3794,6 @@ static int iavf_suspend(struct pci_dev *pdev, pm_message_t state)
clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section);
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-
- pci_disable_device(pdev);
-
return 0;
}
@@ -3817,24 +3803,13 @@ static int iavf_suspend(struct pci_dev *pdev, pm_message_t state)
*
* Called when the system (VM) is resumed from sleep/suspend.
**/
-static int iavf_resume(struct pci_dev *pdev)
+static int __maybe_unused iavf_resume(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct iavf_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *netdev = adapter->netdev;
u32 err;
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- /* pci_restore_state clears dev->state_saved so call
- * pci_save_state to restore it.
- */
- pci_save_state(pdev);
-
- err = pci_enable_device_mem(pdev);
- if (err) {
- dev_err(&pdev->dev, "Cannot enable PCI device from suspend.\n");
- return err;
- }
pci_set_master(pdev);
rtnl_lock();
@@ -3858,7 +3833,6 @@ static int iavf_resume(struct pci_dev *pdev)
return err;
}
-#endif /* CONFIG_PM */
/**
* iavf_remove - Device Removal Routine
* @pdev: PCI device information struct
@@ -3960,16 +3934,15 @@ static void iavf_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
+static SIMPLE_DEV_PM_OPS(iavf_pm_ops, iavf_suspend, iavf_resume);
+
static struct pci_driver iavf_driver = {
- .name = iavf_driver_name,
- .id_table = iavf_pci_tbl,
- .probe = iavf_probe,
- .remove = iavf_remove,
-#ifdef CONFIG_PM
- .suspend = iavf_suspend,
- .resume = iavf_resume,
-#endif
- .shutdown = iavf_shutdown,
+ .name = iavf_driver_name,
+ .id_table = iavf_pci_tbl,
+ .probe = iavf_probe,
+ .remove = iavf_remove,
+ .driver.pm = &iavf_pm_ops,
+ .shutdown = iavf_shutdown,
};
/**
@@ -3982,8 +3955,7 @@ static int __init iavf_init_module(void)
{
int ret;
- pr_info("iavf: %s - version %s\n", iavf_driver_string,
- iavf_driver_version);
+ pr_info("iavf: %s\n", iavf_driver_string);
pr_info("%s\n", iavf_copyright);
diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
index e091bab7e770..ca041b39ffda 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
@@ -1007,7 +1007,7 @@ static inline void iavf_rx_checksum(struct iavf_vsi *vsi,
case IAVF_RX_PTYPE_INNER_PROT_UDP:
case IAVF_RX_PTYPE_INNER_PROT_SCTP:
skb->ip_summed = CHECKSUM_UNNECESSARY;
- /* fall though */
+ fallthrough;
default:
break;
}
diff --git a/drivers/net/ethernet/intel/iavf/iavf_type.h b/drivers/net/ethernet/intel/iavf/iavf_type.h
index 7190a40c540c..de9fda78b43a 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_type.h
+++ b/drivers/net/ethernet/intel/iavf/iavf_type.h
@@ -192,14 +192,6 @@ struct iavf_hw {
char err_str[16];
};
-struct iavf_driver_version {
- u8 major_version;
- u8 minor_version;
- u8 build_version;
- u8 subbuild_version;
- u8 driver_string[32];
-};
-
/* RX Descriptors */
union iavf_16byte_rx_desc {
struct {
diff --git a/drivers/net/ethernet/intel/ice/Makefile b/drivers/net/ethernet/intel/ice/Makefile
index 980bbcc64b4b..6da4f43f2348 100644
--- a/drivers/net/ethernet/intel/ice/Makefile
+++ b/drivers/net/ethernet/intel/ice/Makefile
@@ -23,6 +23,7 @@ ice-y := ice_main.o \
ice_flex_pipe.o \
ice_flow.o \
ice_devlink.o \
+ ice_fw_update.o \
ice_ethtool.o
ice-$(CONFIG_PCI_IOV) += ice_virtchnl_pf.o ice_sriov.o
ice-$(CONFIG_DCB) += ice_dcb.o ice_dcb_nl.o ice_dcb_lib.o
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index 5792ee616b5c..fe140ff38f74 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -19,6 +19,7 @@
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/workqueue.h>
+#include <linux/wait.h>
#include <linux/aer.h>
#include <linux/interrupt.h>
#include <linux/ethtool.h>
@@ -55,7 +56,6 @@
#include "ice_xsk.h"
#include "ice_arfs.h"
-extern const char ice_drv_ver[];
#define ICE_BAR0 0
#define ICE_REQ_DESC_MULTIPLE 32
#define ICE_MIN_NUM_DESC 64
@@ -223,6 +223,8 @@ enum ice_state {
__ICE_OICR_INTR_DIS, /* Global OICR interrupt disabled */
__ICE_MDD_VF_PRINT_PENDING, /* set when MDD event handle */
__ICE_VF_RESETS_DISABLED, /* disable resets during ice_remove */
+ __ICE_LINK_DEFAULT_OVERRIDE_PENDING,
+ __ICE_PHY_INIT_COMPLETE,
__ICE_STATE_NBITS /* must be last */
};
@@ -254,6 +256,7 @@ struct ice_vsi {
u32 tx_busy;
u32 rx_buf_failed;
u32 rx_page_failed;
+ u32 rx_gro_dropped;
u16 num_q_vectors;
u16 base_vector; /* IRQ base for OS reserved vectors */
enum ice_vsi_type type;
@@ -358,12 +361,14 @@ enum ice_pf_flags {
ICE_FLAG_FD_ENA,
ICE_FLAG_ADV_FEATURES,
ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA,
+ ICE_FLAG_TOTAL_PORT_SHUTDOWN_ENA,
ICE_FLAG_NO_MEDIA,
ICE_FLAG_FW_LLDP_AGENT,
ICE_FLAG_ETHTOOL_CTXT, /* set when ethtool holds RTNL lock */
ICE_FLAG_LEGACY_RX,
ICE_FLAG_VF_TRUE_PROMISC_ENA,
ICE_FLAG_MDD_AUTO_RESET_VF,
+ ICE_FLAG_LINK_LENIENT_MODE_ENA,
ICE_PF_FLAGS_NBITS /* must be last */
};
@@ -374,6 +379,7 @@ struct ice_pf {
struct devlink_port devlink_port;
struct devlink_region *nvm_region;
+ struct devlink_region *devcaps_region;
/* OS reserved IRQ details */
struct msix_entry *msix_entries;
@@ -408,6 +414,12 @@ struct ice_pf {
struct mutex sw_mutex; /* lock for protecting VSI alloc flow */
struct mutex tc_mutex; /* lock to protect TC changes */
u32 msg_enable;
+
+ /* spinlock to protect the AdminQ wait list */
+ spinlock_t aq_wait_lock;
+ struct hlist_head aq_wait_list;
+ wait_queue_head_t aq_wait_queue;
+
u32 hw_csum_rx_error;
u16 oicr_idx; /* Other interrupt cause MSIX vector index */
u16 num_avail_sw_msix; /* remaining MSIX SW vectors left unclaimed */
@@ -423,6 +435,8 @@ struct ice_pf {
u16 empr_count; /* EMP reset count */
u16 pfr_count; /* PF reset count */
+ u8 wol_ena : 1; /* software state of WoL */
+ u32 wakeup_reason; /* last wakeup reason */
struct ice_hw_port_stats stats;
struct ice_hw_port_stats stats_prev;
struct ice_hw hw;
@@ -435,6 +449,10 @@ struct ice_pf {
u32 tx_timeout_recovery_level;
char int_name[ICE_INT_NAME_STR_LEN];
u32 sw_int_count;
+
+ __le64 nvm_phy_type_lo; /* NVM PHY type low */
+ __le64 nvm_phy_type_hi; /* NVM PHY type high */
+ struct ice_link_default_override_tlv link_dflt_override;
};
struct ice_netdev_priv {
@@ -568,6 +586,7 @@ int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset);
void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
const char *ice_stat_str(enum ice_status stat_err);
const char *ice_aq_str(enum ice_aq_err aq_err);
+bool ice_is_wol_supported(struct ice_pf *pf);
int
ice_fdir_write_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input, bool add,
bool is_tun);
@@ -582,6 +601,8 @@ void ice_fdir_release_flows(struct ice_hw *hw);
void ice_fdir_replay_flows(struct ice_hw *hw);
void ice_fdir_replay_fltrs(struct ice_pf *pf);
int ice_fdir_create_dflt_rules(struct ice_pf *pf);
+int ice_aq_wait_for_event(struct ice_pf *pf, u16 opcode, unsigned long timeout,
+ struct ice_rq_event_info *event);
int ice_open(struct net_device *netdev);
int ice_stop(struct net_device *netdev);
void ice_service_task_schedule(struct ice_pf *pf);
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
index 92f82f2a8af4..ba9375218fef 100644
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
@@ -109,6 +109,13 @@ struct ice_aqc_list_caps_elem {
#define ICE_AQC_CAPS_MSIX 0x0043
#define ICE_AQC_CAPS_FD 0x0045
#define ICE_AQC_CAPS_MAX_MTU 0x0047
+#define ICE_AQC_CAPS_NVM_VER 0x0048
+#define ICE_AQC_CAPS_PENDING_NVM_VER 0x0049
+#define ICE_AQC_CAPS_OROM_VER 0x004A
+#define ICE_AQC_CAPS_PENDING_OROM_VER 0x004B
+#define ICE_AQC_CAPS_NET_VER 0x004C
+#define ICE_AQC_CAPS_PENDING_NET_VER 0x004D
+#define ICE_AQC_CAPS_NVM_MGMT 0x0080
u8 major_ver;
u8 minor_ver;
@@ -215,13 +222,6 @@ struct ice_aqc_get_sw_cfg_resp_elem {
#define ICE_AQC_GET_SW_CONF_RESP_IS_VF BIT(15)
};
-/* The response buffer is as follows. Note that the length of the
- * elements array varies with the length of the command response.
- */
-struct ice_aqc_get_sw_cfg_resp {
- struct ice_aqc_get_sw_cfg_resp_elem elements[1];
-};
-
/* These resource type defines are used for all switch resource
* commands where a resource type is required, such as:
* Get Resource Allocation command (indirect 0x0204)
@@ -274,7 +274,7 @@ struct ice_aqc_alloc_free_res_elem {
#define ICE_AQC_RES_TYPE_VSI_PRUNE_LIST_M \
(0xF << ICE_AQC_RES_TYPE_VSI_PRUNE_LIST_S)
__le16 num_elems;
- struct ice_aqc_res_elem elem[1];
+ struct ice_aqc_res_elem elem[];
};
/* Add VSI (indirect 0x0210)
@@ -568,8 +568,8 @@ struct ice_sw_rule_lkup_rx_tx {
* lookup-type
*/
__le16 hdr_len;
- u8 hdr[1];
-} __packed;
+ u8 hdr[];
+};
/* Add/Update/Remove large action command/response entry
* "index" is returned as part of a response to a successful Add command, and
@@ -578,7 +578,6 @@ struct ice_sw_rule_lkup_rx_tx {
struct ice_sw_rule_lg_act {
__le16 index; /* Index in large action table */
__le16 size;
- __le32 act[1]; /* array of size for actions */
/* Max number of large actions */
#define ICE_MAX_LG_ACT 4
/* Bit 0:1 - Action type */
@@ -629,6 +628,7 @@ struct ice_sw_rule_lg_act {
#define ICE_LG_ACT_STAT_COUNT 0x7
#define ICE_LG_ACT_STAT_COUNT_S 3
#define ICE_LG_ACT_STAT_COUNT_M (0x7F << ICE_LG_ACT_STAT_COUNT_S)
+ __le32 act[]; /* array of size for actions */
};
/* Add/Update/Remove VSI list command/response entry
@@ -638,7 +638,7 @@ struct ice_sw_rule_lg_act {
struct ice_sw_rule_vsi_list {
__le16 index; /* Index of VSI/Prune list */
__le16 number_vsi;
- __le16 vsi[1]; /* Array of number_vsi VSI numbers */
+ __le16 vsi[]; /* Array of number_vsi VSI numbers */
};
/* Query VSI list command/response entry */
@@ -695,14 +695,6 @@ struct ice_aqc_sched_elem_cmd {
__le32 addr_low;
};
-/* This is the buffer for:
- * Suspend Nodes (indirect 0x0409)
- * Resume Nodes (indirect 0x040A)
- */
-struct ice_aqc_suspend_resume_elem {
- __le32 teid[1];
-};
-
struct ice_aqc_elem_info_bw {
__le16 bw_profile_idx;
__le16 bw_alloc;
@@ -753,15 +745,7 @@ struct ice_aqc_txsched_topo_grp_info_hdr {
struct ice_aqc_add_elem {
struct ice_aqc_txsched_topo_grp_info_hdr hdr;
- struct ice_aqc_txsched_elem_data generic[1];
-};
-
-struct ice_aqc_conf_elem {
- struct ice_aqc_txsched_elem_data generic[1];
-};
-
-struct ice_aqc_get_elem {
- struct ice_aqc_txsched_elem_data generic[1];
+ struct ice_aqc_txsched_elem_data generic[];
};
struct ice_aqc_get_topo_elem {
@@ -772,7 +756,7 @@ struct ice_aqc_get_topo_elem {
struct ice_aqc_delete_elem {
struct ice_aqc_txsched_topo_grp_info_hdr hdr;
- __le32 teid[1];
+ __le32 teid[];
};
/* Query Port ETS (indirect 0x040E)
@@ -835,10 +819,6 @@ struct ice_aqc_rl_profile_elem {
__le16 rl_encode;
};
-struct ice_aqc_rl_profile_generic_elem {
- struct ice_aqc_rl_profile_elem generic[1];
-};
-
/* Query Scheduler Resource Allocation (indirect 0x0412)
* This indirect command retrieves the scheduler resources allocated by
* EMP Firmware to the given PF.
@@ -988,8 +968,11 @@ struct ice_aqc_get_phy_caps_data {
#define ICE_AQC_GET_PHY_EN_MOD_QUAL BIT(5)
#define ICE_AQC_PHY_EN_AUTO_FEC BIT(7)
#define ICE_AQC_PHY_CAPS_MASK ICE_M(0xff, 0)
- u8 low_power_ctrl;
+ u8 low_power_ctrl_an;
#define ICE_AQC_PHY_EN_D3COLD_LOW_POWER_AUTONEG BIT(0)
+#define ICE_AQC_PHY_AN_EN_CLAUSE28 BIT(1)
+#define ICE_AQC_PHY_AN_EN_CLAUSE73 BIT(2)
+#define ICE_AQC_PHY_AN_EN_CLAUSE37 BIT(3)
__le16 eee_cap;
#define ICE_AQC_PHY_EEE_EN_100BASE_TX BIT(0)
#define ICE_AQC_PHY_EEE_EN_1000BASE_T BIT(1)
@@ -1010,12 +993,14 @@ struct ice_aqc_get_phy_caps_data {
#define ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN BIT(6)
#define ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN BIT(7)
#define ICE_AQC_PHY_FEC_MASK ICE_M(0xdf, 0)
- u8 rsvd1; /* Byte 35 reserved */
+ u8 module_compliance_enforcement;
+#define ICE_AQC_MOD_ENFORCE_STRICT_MODE BIT(0)
u8 extended_compliance_code;
#define ICE_MODULE_TYPE_TOTAL_BYTE 3
u8 module_type[ICE_MODULE_TYPE_TOTAL_BYTE];
#define ICE_AQC_MOD_TYPE_BYTE0_SFP_PLUS 0xA0
#define ICE_AQC_MOD_TYPE_BYTE0_QSFP_PLUS 0x80
+#define ICE_AQC_MOD_TYPE_IDENT 1
#define ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE BIT(0)
#define ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE BIT(1)
#define ICE_AQC_MOD_TYPE_BYTE1_10G_BASE_SR BIT(4)
@@ -1059,11 +1044,11 @@ struct ice_aqc_set_phy_cfg_data {
#define ICE_AQ_PHY_ENA_AUTO_LINK_UPDT BIT(5)
#define ICE_AQ_PHY_ENA_LESM BIT(6)
#define ICE_AQ_PHY_ENA_AUTO_FEC BIT(7)
- u8 low_power_ctrl;
+ u8 low_power_ctrl_an;
__le16 eee_cap; /* Value from ice_aqc_get_phy_caps */
__le16 eeer_value;
u8 link_fec_opt; /* Use defines from ice_aqc_get_phy_caps */
- u8 rsvd1;
+ u8 module_compliance_enforcement;
};
/* Set MAC Config command data structure (direct 0x0603) */
@@ -1174,6 +1159,7 @@ struct ice_aqc_get_link_status_data {
#define ICE_AQ_LINK_PWR_QSFP_CLASS_3 2
#define ICE_AQ_LINK_PWR_QSFP_CLASS_4 3
__le16 link_speed;
+#define ICE_AQ_LINK_SPEED_M 0x7FF
#define ICE_AQ_LINK_SPEED_10MB BIT(0)
#define ICE_AQ_LINK_SPEED_100MB BIT(1)
#define ICE_AQ_LINK_SPEED_1000MB BIT(2)
@@ -1216,6 +1202,57 @@ struct ice_aqc_set_mac_lb {
u8 reserved[15];
};
+struct ice_aqc_link_topo_addr {
+ u8 lport_num;
+ u8 lport_num_valid;
+#define ICE_AQC_LINK_TOPO_PORT_NUM_VALID BIT(0)
+ u8 node_type_ctx;
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_S 0
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_M (0xF << ICE_AQC_LINK_TOPO_NODE_TYPE_S)
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_PHY 0
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL 1
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_MUX_CTRL 2
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_LED_CTRL 3
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_LED 4
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_THERMAL 5
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE 6
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_MEZZ 7
+#define ICE_AQC_LINK_TOPO_NODE_TYPE_ID_EEPROM 8
+#define ICE_AQC_LINK_TOPO_NODE_CTX_S 4
+#define ICE_AQC_LINK_TOPO_NODE_CTX_M \
+ (0xF << ICE_AQC_LINK_TOPO_NODE_CTX_S)
+#define ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL 0
+#define ICE_AQC_LINK_TOPO_NODE_CTX_BOARD 1
+#define ICE_AQC_LINK_TOPO_NODE_CTX_PORT 2
+#define ICE_AQC_LINK_TOPO_NODE_CTX_NODE 3
+#define ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED 4
+#define ICE_AQC_LINK_TOPO_NODE_CTX_OVERRIDE 5
+ u8 index;
+ __le16 handle;
+#define ICE_AQC_LINK_TOPO_HANDLE_S 0
+#define ICE_AQC_LINK_TOPO_HANDLE_M (0x3FF << ICE_AQC_LINK_TOPO_HANDLE_S)
+/* Used to decode the handle field */
+#define ICE_AQC_LINK_TOPO_HANDLE_BRD_TYPE_M BIT(9)
+#define ICE_AQC_LINK_TOPO_HANDLE_BRD_TYPE_LOM BIT(9)
+#define ICE_AQC_LINK_TOPO_HANDLE_BRD_TYPE_MEZZ 0
+#define ICE_AQC_LINK_TOPO_HANDLE_NODE_S 0
+/* In case of a Mezzanine type */
+#define ICE_AQC_LINK_TOPO_HANDLE_MEZZ_NODE_M \
+ (0x3F << ICE_AQC_LINK_TOPO_HANDLE_NODE_S)
+#define ICE_AQC_LINK_TOPO_HANDLE_MEZZ_S 6
+#define ICE_AQC_LINK_TOPO_HANDLE_MEZZ_M (0x7 << ICE_AQC_LINK_TOPO_HANDLE_MEZZ_S)
+/* In case of a LOM type */
+#define ICE_AQC_LINK_TOPO_HANDLE_LOM_NODE_M \
+ (0x1FF << ICE_AQC_LINK_TOPO_HANDLE_NODE_S)
+};
+
+/* Get Link Topology Handle (direct, 0x06E0) */
+struct ice_aqc_get_link_topo {
+ struct ice_aqc_link_topo_addr addr;
+ u8 node_part_num;
+ u8 rsvd[9];
+};
+
/* Set Port Identification LED (direct, 0x06E9) */
struct ice_aqc_set_port_id_led {
u8 lport_num;
@@ -1268,7 +1305,14 @@ struct ice_aqc_nvm {
#define ICE_AQC_NVM_PRESERVATION_M (3 << ICE_AQC_NVM_PRESERVATION_S)
#define ICE_AQC_NVM_NO_PRESERVATION (0 << ICE_AQC_NVM_PRESERVATION_S)
#define ICE_AQC_NVM_PRESERVE_ALL BIT(1)
+#define ICE_AQC_NVM_FACTORY_DEFAULT (2 << ICE_AQC_NVM_PRESERVATION_S)
#define ICE_AQC_NVM_PRESERVE_SELECTED (3 << ICE_AQC_NVM_PRESERVATION_S)
+#define ICE_AQC_NVM_ACTIV_SEL_NVM BIT(3) /* Write Activate/SR Dump only */
+#define ICE_AQC_NVM_ACTIV_SEL_OROM BIT(4)
+#define ICE_AQC_NVM_ACTIV_SEL_NETLIST BIT(5)
+#define ICE_AQC_NVM_SPECIAL_UPDATE BIT(6)
+#define ICE_AQC_NVM_REVERT_LAST_ACTIV BIT(6) /* Write Activate only */
+#define ICE_AQC_NVM_ACTIV_SEL_MASK ICE_M(0x7, 3)
#define ICE_AQC_NVM_FLASH_ONLY BIT(7)
__le16 module_typeid;
__le16 length;
@@ -1317,6 +1361,67 @@ struct ice_aqc_nvm_checksum {
#define ICE_AQC_NVM_NETLIST_ID_BLK_SHA_HASH 0xA
#define ICE_AQC_NVM_NETLIST_ID_BLK_CUST_VER 0x2F
+/* Used for NVM Set Package Data command - 0x070A */
+struct ice_aqc_nvm_pkg_data {
+ u8 reserved[3];
+ u8 cmd_flags;
+#define ICE_AQC_NVM_PKG_DELETE BIT(0) /* used for command call */
+#define ICE_AQC_NVM_PKG_SKIPPED BIT(0) /* used for command response */
+
+ u32 reserved1;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+/* Used for Pass Component Table command - 0x070B */
+struct ice_aqc_nvm_pass_comp_tbl {
+ u8 component_response; /* Response only */
+#define ICE_AQ_NVM_PASS_COMP_CAN_BE_UPDATED 0x0
+#define ICE_AQ_NVM_PASS_COMP_CAN_MAY_BE_UPDATEABLE 0x1
+#define ICE_AQ_NVM_PASS_COMP_CAN_NOT_BE_UPDATED 0x2
+ u8 component_response_code; /* Response only */
+#define ICE_AQ_NVM_PASS_COMP_CAN_BE_UPDATED_CODE 0x0
+#define ICE_AQ_NVM_PASS_COMP_STAMP_IDENTICAL_CODE 0x1
+#define ICE_AQ_NVM_PASS_COMP_STAMP_LOWER 0x2
+#define ICE_AQ_NVM_PASS_COMP_INVALID_STAMP_CODE 0x3
+#define ICE_AQ_NVM_PASS_COMP_CONFLICT_CODE 0x4
+#define ICE_AQ_NVM_PASS_COMP_PRE_REQ_NOT_MET_CODE 0x5
+#define ICE_AQ_NVM_PASS_COMP_NOT_SUPPORTED_CODE 0x6
+#define ICE_AQ_NVM_PASS_COMP_CANNOT_DOWNGRADE_CODE 0x7
+#define ICE_AQ_NVM_PASS_COMP_INCOMPLETE_IMAGE_CODE 0x8
+#define ICE_AQ_NVM_PASS_COMP_VER_STR_IDENTICAL_CODE 0xA
+#define ICE_AQ_NVM_PASS_COMP_VER_STR_LOWER_CODE 0xB
+ u8 reserved;
+ u8 transfer_flag;
+#define ICE_AQ_NVM_PASS_COMP_TBL_START 0x1
+#define ICE_AQ_NVM_PASS_COMP_TBL_MIDDLE 0x2
+#define ICE_AQ_NVM_PASS_COMP_TBL_END 0x4
+#define ICE_AQ_NVM_PASS_COMP_TBL_START_AND_END 0x5
+ __le32 reserved1;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+struct ice_aqc_nvm_comp_tbl {
+ __le16 comp_class;
+#define NVM_COMP_CLASS_ALL_FW 0x000A
+
+ __le16 comp_id;
+#define NVM_COMP_ID_OROM 0x5
+#define NVM_COMP_ID_NVM 0x6
+#define NVM_COMP_ID_NETLIST 0x8
+
+ u8 comp_class_idx;
+#define FWU_COMP_CLASS_IDX_NOT_USE 0x0
+
+ __le32 comp_cmp_stamp;
+ u8 cvs_type;
+#define NVM_CVS_TYPE_ASCII 0x1
+
+ u8 cvs_len;
+ u8 cvs[]; /* Component Version String */
+} __packed;
+
/**
* Send to PF command (indirect 0x0801) ID is only used by PF
*
@@ -1476,7 +1581,7 @@ struct ice_aqc_get_set_rss_keys {
struct ice_aqc_get_set_rss_lut {
#define ICE_AQC_GSET_RSS_LUT_VSI_VALID BIT(15)
#define ICE_AQC_GSET_RSS_LUT_VSI_ID_S 0
-#define ICE_AQC_GSET_RSS_LUT_VSI_ID_M (0x1FF << ICE_AQC_GSET_RSS_LUT_VSI_ID_S)
+#define ICE_AQC_GSET_RSS_LUT_VSI_ID_M (0x3FF << ICE_AQC_GSET_RSS_LUT_VSI_ID_S)
__le16 vsi_id;
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S 0
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M \
@@ -1537,7 +1642,7 @@ struct ice_aqc_add_tx_qgrp {
__le32 parent_teid;
u8 num_txqs;
u8 rsvd[3];
- struct ice_aqc_add_txqs_perq txqs[1];
+ struct ice_aqc_add_txqs_perq txqs[];
};
/* Disable Tx LAN Queues (indirect 0x0C31) */
@@ -1575,18 +1680,13 @@ struct ice_aqc_dis_txq_item {
u8 num_qs;
u8 rsvd;
/* The length of the q_id array varies according to num_qs */
- __le16 q_id[1];
- /* This only applies from F8 onward */
#define ICE_AQC_Q_DIS_BUF_ELEM_TYPE_S 15
#define ICE_AQC_Q_DIS_BUF_ELEM_TYPE_LAN_Q \
(0 << ICE_AQC_Q_DIS_BUF_ELEM_TYPE_S)
#define ICE_AQC_Q_DIS_BUF_ELEM_TYPE_RDMA_QSET \
(1 << ICE_AQC_Q_DIS_BUF_ELEM_TYPE_S)
-};
-
-struct ice_aqc_dis_txq {
- struct ice_aqc_dis_txq_item qgrps[1];
-};
+ __le16 q_id[];
+} __packed;
/* Configure Firmware Logging Command (indirect 0xFF09)
* Logging Information Read Response (indirect 0xFF10)
@@ -1636,12 +1736,7 @@ enum ice_aqc_fw_logging_mod {
ICE_AQC_FW_LOG_ID_MAX,
};
-/* This is the buffer for both of the logging commands.
- * The entry array size depends on the datalen parameter in the descriptor.
- * There will be a total of datalen / 2 entries.
- */
-struct ice_aqc_fw_logging_data {
- __le16 entry[1];
+/* Defines for both above FW logging command/response buffers */
#define ICE_AQC_FW_LOG_ID_S 0
#define ICE_AQC_FW_LOG_ID_M (0xFFF << ICE_AQC_FW_LOG_ID_S)
@@ -1654,7 +1749,6 @@ struct ice_aqc_fw_logging_data {
#define ICE_AQC_FW_LOG_INIT_EN BIT(13) /* Used by command */
#define ICE_AQC_FW_LOG_FLOW_EN BIT(14) /* Used by command */
#define ICE_AQC_FW_LOG_ERR_EN BIT(15) /* Used by command */
-};
/* Get/Clear FW Log (indirect 0xFF11) */
struct ice_aqc_get_clear_fw_log {
@@ -1716,7 +1810,7 @@ struct ice_aqc_get_pkg_info {
/* Get Package Info List response buffer format (0x0C43) */
struct ice_aqc_get_pkg_info_resp {
__le32 count;
- struct ice_aqc_get_pkg_info pkg_info[1];
+ struct ice_aqc_get_pkg_info pkg_info[];
};
/* Lan Queue Overflow Event (direct, 0x1001) */
@@ -1775,6 +1869,8 @@ struct ice_aq_desc {
struct ice_aqc_rl_profile rl_profile;
struct ice_aqc_nvm nvm;
struct ice_aqc_nvm_checksum nvm_checksum;
+ struct ice_aqc_nvm_pkg_data pkg_data;
+ struct ice_aqc_nvm_pass_comp_tbl pass_comp_tbl;
struct ice_aqc_pf_vf_msg virt;
struct ice_aqc_lldp_get_mib lldp_get_mib;
struct ice_aqc_lldp_set_mib_change lldp_set_event;
@@ -1797,6 +1893,7 @@ struct ice_aq_desc {
struct ice_aqc_set_event_mask set_event_mask;
struct ice_aqc_get_link_status get_link_status;
struct ice_aqc_event_lan_overflow lan_overflow;
+ struct ice_aqc_get_link_topo get_link_topo;
} params;
};
@@ -1896,12 +1993,19 @@ enum ice_adminq_opc {
ice_aqc_opc_get_link_status = 0x0607,
ice_aqc_opc_set_event_mask = 0x0613,
ice_aqc_opc_set_mac_lb = 0x0620,
+ ice_aqc_opc_get_link_topo = 0x06E0,
ice_aqc_opc_set_port_id_led = 0x06E9,
ice_aqc_opc_sff_eeprom = 0x06EE,
/* NVM commands */
ice_aqc_opc_nvm_read = 0x0701,
+ ice_aqc_opc_nvm_erase = 0x0702,
+ ice_aqc_opc_nvm_write = 0x0703,
ice_aqc_opc_nvm_checksum = 0x0706,
+ ice_aqc_opc_nvm_write_activate = 0x0707,
+ ice_aqc_opc_nvm_update_empr = 0x0709,
+ ice_aqc_opc_nvm_pkg_data = 0x070A,
+ ice_aqc_opc_nvm_pass_component_tbl = 0x070B,
/* PF/VF mailbox commands */
ice_mbx_opc_send_msg_to_pf = 0x0801,
diff --git a/drivers/net/ethernet/intel/ice/ice_base.c b/drivers/net/ethernet/intel/ice/ice_base.c
index d620d26d42ed..87008476d8fe 100644
--- a/drivers/net/ethernet/intel/ice/ice_base.c
+++ b/drivers/net/ethernet/intel/ice/ice_base.c
@@ -635,10 +635,10 @@ int
ice_vsi_cfg_txq(struct ice_vsi *vsi, struct ice_ring *ring,
struct ice_aqc_add_tx_qgrp *qg_buf)
{
+ u8 buf_len = struct_size(qg_buf, txqs, 1);
struct ice_tlan_ctx tlan_ctx = { 0 };
struct ice_aqc_add_txqs_perq *txq;
struct ice_pf *pf = vsi->back;
- u8 buf_len = sizeof(*qg_buf);
struct ice_hw *hw = &pf->hw;
enum ice_status status;
u16 pf_q;
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index bce0e1281168..34abfcea9858 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -20,7 +20,40 @@ static enum ice_status ice_set_mac_type(struct ice_hw *hw)
if (hw->vendor_id != PCI_VENDOR_ID_INTEL)
return ICE_ERR_DEVICE_NOT_SUPPORTED;
- hw->mac_type = ICE_MAC_GENERIC;
+ switch (hw->device_id) {
+ case ICE_DEV_ID_E810C_BACKPLANE:
+ case ICE_DEV_ID_E810C_QSFP:
+ case ICE_DEV_ID_E810C_SFP:
+ case ICE_DEV_ID_E810_XXV_SFP:
+ hw->mac_type = ICE_MAC_E810;
+ break;
+ case ICE_DEV_ID_E823C_10G_BASE_T:
+ case ICE_DEV_ID_E823C_BACKPLANE:
+ case ICE_DEV_ID_E823C_QSFP:
+ case ICE_DEV_ID_E823C_SFP:
+ case ICE_DEV_ID_E823C_SGMII:
+ case ICE_DEV_ID_E822C_10G_BASE_T:
+ case ICE_DEV_ID_E822C_BACKPLANE:
+ case ICE_DEV_ID_E822C_QSFP:
+ case ICE_DEV_ID_E822C_SFP:
+ case ICE_DEV_ID_E822C_SGMII:
+ case ICE_DEV_ID_E822L_10G_BASE_T:
+ case ICE_DEV_ID_E822L_BACKPLANE:
+ case ICE_DEV_ID_E822L_SFP:
+ case ICE_DEV_ID_E822L_SGMII:
+ case ICE_DEV_ID_E823L_10G_BASE_T:
+ case ICE_DEV_ID_E823L_1GBE:
+ case ICE_DEV_ID_E823L_BACKPLANE:
+ case ICE_DEV_ID_E823L_QSFP:
+ case ICE_DEV_ID_E823L_SFP:
+ hw->mac_type = ICE_MAC_GENERIC;
+ break;
+ default:
+ hw->mac_type = ICE_MAC_UNKNOWN;
+ break;
+ }
+
+ ice_debug(hw, ICE_DBG_INIT, "mac_type: %d\n", hw->mac_type);
return 0;
}
@@ -52,7 +85,8 @@ enum ice_status ice_clear_pf_cfg(struct ice_hw *hw)
* is returned in user specified buffer. Please interpret user specified
* buffer as "manage_mac_read" response.
* Response such as various MAC addresses are stored in HW struct (port.mac)
- * ice_aq_discover_caps is expected to be called before this function is called.
+ * ice_discover_dev_caps is expected to be called before this function is
+ * called.
*/
static enum ice_status
ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size,
@@ -116,11 +150,13 @@ ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
u16 pcaps_size = sizeof(*pcaps);
struct ice_aq_desc desc;
enum ice_status status;
+ struct ice_hw *hw;
cmd = &desc.params.get_phy;
if (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi)
return ICE_ERR_PARAM;
+ hw = pi->hw;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps);
@@ -128,17 +164,94 @@ ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
cmd->param0 |= cpu_to_le16(ICE_AQC_GET_PHY_RQM);
cmd->param0 |= cpu_to_le16(report_mode);
- status = ice_aq_send_cmd(pi->hw, &desc, pcaps, pcaps_size, cd);
+ status = ice_aq_send_cmd(hw, &desc, pcaps, pcaps_size, cd);
+
+ ice_debug(hw, ICE_DBG_LINK, "get phy caps - report_mode = 0x%x\n",
+ report_mode);
+ ice_debug(hw, ICE_DBG_LINK, " phy_type_low = 0x%llx\n",
+ (unsigned long long)le64_to_cpu(pcaps->phy_type_low));
+ ice_debug(hw, ICE_DBG_LINK, " phy_type_high = 0x%llx\n",
+ (unsigned long long)le64_to_cpu(pcaps->phy_type_high));
+ ice_debug(hw, ICE_DBG_LINK, " caps = 0x%x\n", pcaps->caps);
+ ice_debug(hw, ICE_DBG_LINK, " low_power_ctrl_an = 0x%x\n",
+ pcaps->low_power_ctrl_an);
+ ice_debug(hw, ICE_DBG_LINK, " eee_cap = 0x%x\n", pcaps->eee_cap);
+ ice_debug(hw, ICE_DBG_LINK, " eeer_value = 0x%x\n",
+ pcaps->eeer_value);
+ ice_debug(hw, ICE_DBG_LINK, " link_fec_options = 0x%x\n",
+ pcaps->link_fec_options);
+ ice_debug(hw, ICE_DBG_LINK, " module_compliance_enforcement = 0x%x\n",
+ pcaps->module_compliance_enforcement);
+ ice_debug(hw, ICE_DBG_LINK, " extended_compliance_code = 0x%x\n",
+ pcaps->extended_compliance_code);
+ ice_debug(hw, ICE_DBG_LINK, " module_type[0] = 0x%x\n",
+ pcaps->module_type[0]);
+ ice_debug(hw, ICE_DBG_LINK, " module_type[1] = 0x%x\n",
+ pcaps->module_type[1]);
+ ice_debug(hw, ICE_DBG_LINK, " module_type[2] = 0x%x\n",
+ pcaps->module_type[2]);
if (!status && report_mode == ICE_AQC_REPORT_TOPO_CAP) {
pi->phy.phy_type_low = le64_to_cpu(pcaps->phy_type_low);
pi->phy.phy_type_high = le64_to_cpu(pcaps->phy_type_high);
+ memcpy(pi->phy.link_info.module_type, &pcaps->module_type,
+ sizeof(pi->phy.link_info.module_type));
}
return status;
}
/**
+ * ice_aq_get_link_topo_handle - get link topology node return status
+ * @pi: port information structure
+ * @node_type: requested node type
+ * @cd: pointer to command details structure or NULL
+ *
+ * Get link topology node return status for specified node type (0x06E0)
+ *
+ * Node type cage can be used to determine if cage is present. If AQC
+ * returns error (ENOENT), then no cage present. If no cage present, then
+ * connection type is backplane or BASE-T.
+ */
+static enum ice_status
+ice_aq_get_link_topo_handle(struct ice_port_info *pi, u8 node_type,
+ struct ice_sq_cd *cd)
+{
+ struct ice_aqc_get_link_topo *cmd;
+ struct ice_aq_desc desc;
+
+ cmd = &desc.params.get_link_topo;
+
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
+
+ cmd->addr.node_type_ctx = (ICE_AQC_LINK_TOPO_NODE_CTX_PORT <<
+ ICE_AQC_LINK_TOPO_NODE_CTX_S);
+
+ /* set node type */
+ cmd->addr.node_type_ctx |= (ICE_AQC_LINK_TOPO_NODE_TYPE_M & node_type);
+
+ return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd);
+}
+
+/**
+ * ice_is_media_cage_present
+ * @pi: port information structure
+ *
+ * Returns true if media cage is present, else false. If no cage, then
+ * media type is backplane or BASE-T.
+ */
+static bool ice_is_media_cage_present(struct ice_port_info *pi)
+{
+ /* Node type cage can be used to determine if cage is present. If AQC
+ * returns error (ENOENT), then no cage present. If no cage present then
+ * connection type is backplane or BASE-T.
+ */
+ return !ice_aq_get_link_topo_handle(pi,
+ ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE,
+ NULL);
+}
+
+/**
* ice_get_media_type - Gets media type
* @pi: port information structure
*/
@@ -155,6 +268,18 @@ static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
return ICE_MEDIA_UNKNOWN;
if (hw_link_info->phy_type_low) {
+ /* 1G SGMII is a special case where some DA cable PHYs
+ * may show this as an option when it really shouldn't
+ * be since SGMII is meant to be between a MAC and a PHY
+ * in a backplane. Try to detect this case and handle it
+ */
+ if (hw_link_info->phy_type_low == ICE_PHY_TYPE_LOW_1G_SGMII &&
+ (hw_link_info->module_type[ICE_AQC_MOD_TYPE_IDENT] ==
+ ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE ||
+ hw_link_info->module_type[ICE_AQC_MOD_TYPE_IDENT] ==
+ ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE))
+ return ICE_MEDIA_DA;
+
switch (hw_link_info->phy_type_low) {
case ICE_PHY_TYPE_LOW_1000BASE_SX:
case ICE_PHY_TYPE_LOW_1000BASE_LX:
@@ -163,7 +288,6 @@ static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
case ICE_PHY_TYPE_LOW_10G_SFI_C2C:
case ICE_PHY_TYPE_LOW_25GBASE_SR:
case ICE_PHY_TYPE_LOW_25GBASE_LR:
- case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
case ICE_PHY_TYPE_LOW_40GBASE_SR4:
case ICE_PHY_TYPE_LOW_40GBASE_LR4:
case ICE_PHY_TYPE_LOW_50GBASE_SR2:
@@ -175,6 +299,14 @@ static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
case ICE_PHY_TYPE_LOW_100GBASE_LR4:
case ICE_PHY_TYPE_LOW_100GBASE_SR2:
case ICE_PHY_TYPE_LOW_100GBASE_DR:
+ case ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC:
+ case ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC:
+ case ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC:
+ case ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC:
+ case ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC:
+ case ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC:
+ case ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC:
+ case ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC:
return ICE_MEDIA_FIBER;
case ICE_PHY_TYPE_LOW_100BASE_TX:
case ICE_PHY_TYPE_LOW_1000BASE_T:
@@ -194,6 +326,16 @@ static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
case ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4:
case ICE_PHY_TYPE_LOW_100GBASE_CP2:
return ICE_MEDIA_DA;
+ case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
+ case ICE_PHY_TYPE_LOW_40G_XLAUI:
+ case ICE_PHY_TYPE_LOW_50G_LAUI2:
+ case ICE_PHY_TYPE_LOW_50G_AUI2:
+ case ICE_PHY_TYPE_LOW_50G_AUI1:
+ case ICE_PHY_TYPE_LOW_100G_AUI4:
+ case ICE_PHY_TYPE_LOW_100G_CAUI4:
+ if (ice_is_media_cage_present(pi))
+ return ICE_MEDIA_DA;
+ fallthrough;
case ICE_PHY_TYPE_LOW_1000BASE_KX:
case ICE_PHY_TYPE_LOW_2500BASE_KX:
case ICE_PHY_TYPE_LOW_2500BASE_X:
@@ -211,8 +353,16 @@ static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
}
} else {
switch (hw_link_info->phy_type_high) {
+ case ICE_PHY_TYPE_HIGH_100G_AUI2:
+ case ICE_PHY_TYPE_HIGH_100G_CAUI2:
+ if (ice_is_media_cage_present(pi))
+ return ICE_MEDIA_DA;
+ fallthrough;
case ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4:
return ICE_MEDIA_BACKPLANE;
+ case ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC:
+ case ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC:
+ return ICE_MEDIA_FIBER;
}
}
return ICE_MEDIA_UNKNOWN;
@@ -292,18 +442,21 @@ ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
li->lse_ena = !!(resp->cmd_flags & cpu_to_le16(ICE_AQ_LSE_IS_ENABLED));
- ice_debug(hw, ICE_DBG_LINK, "link_speed = 0x%x\n", li->link_speed);
- ice_debug(hw, ICE_DBG_LINK, "phy_type_low = 0x%llx\n",
+ ice_debug(hw, ICE_DBG_LINK, "get link info\n");
+ ice_debug(hw, ICE_DBG_LINK, " link_speed = 0x%x\n", li->link_speed);
+ ice_debug(hw, ICE_DBG_LINK, " phy_type_low = 0x%llx\n",
(unsigned long long)li->phy_type_low);
- ice_debug(hw, ICE_DBG_LINK, "phy_type_high = 0x%llx\n",
+ ice_debug(hw, ICE_DBG_LINK, " phy_type_high = 0x%llx\n",
(unsigned long long)li->phy_type_high);
- ice_debug(hw, ICE_DBG_LINK, "media_type = 0x%x\n", *hw_media_type);
- ice_debug(hw, ICE_DBG_LINK, "link_info = 0x%x\n", li->link_info);
- ice_debug(hw, ICE_DBG_LINK, "an_info = 0x%x\n", li->an_info);
- ice_debug(hw, ICE_DBG_LINK, "ext_info = 0x%x\n", li->ext_info);
- ice_debug(hw, ICE_DBG_LINK, "lse_ena = 0x%x\n", li->lse_ena);
- ice_debug(hw, ICE_DBG_LINK, "max_frame = 0x%x\n", li->max_frame_size);
- ice_debug(hw, ICE_DBG_LINK, "pacing = 0x%x\n", li->pacing);
+ ice_debug(hw, ICE_DBG_LINK, " media_type = 0x%x\n", *hw_media_type);
+ ice_debug(hw, ICE_DBG_LINK, " link_info = 0x%x\n", li->link_info);
+ ice_debug(hw, ICE_DBG_LINK, " an_info = 0x%x\n", li->an_info);
+ ice_debug(hw, ICE_DBG_LINK, " ext_info = 0x%x\n", li->ext_info);
+ ice_debug(hw, ICE_DBG_LINK, " fec_info = 0x%x\n", li->fec_info);
+ ice_debug(hw, ICE_DBG_LINK, " lse_ena = 0x%x\n", li->lse_ena);
+ ice_debug(hw, ICE_DBG_LINK, " max_frame = 0x%x\n",
+ li->max_frame_size);
+ ice_debug(hw, ICE_DBG_LINK, " pacing = 0x%x\n", li->pacing);
/* save link status information */
if (link)
@@ -440,32 +593,24 @@ static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
devm_kfree(ice_hw_to_dev(hw), sw);
}
-#define ICE_FW_LOG_DESC_SIZE(n) (sizeof(struct ice_aqc_fw_logging_data) + \
- (((n) - 1) * sizeof(((struct ice_aqc_fw_logging_data *)0)->entry)))
-#define ICE_FW_LOG_DESC_SIZE_MAX \
- ICE_FW_LOG_DESC_SIZE(ICE_AQC_FW_LOG_ID_MAX)
-
/**
* ice_get_fw_log_cfg - get FW logging configuration
* @hw: pointer to the HW struct
*/
static enum ice_status ice_get_fw_log_cfg(struct ice_hw *hw)
{
- struct ice_aqc_fw_logging_data *config;
struct ice_aq_desc desc;
enum ice_status status;
+ __le16 *config;
u16 size;
- size = ICE_FW_LOG_DESC_SIZE_MAX;
+ size = sizeof(*config) * ICE_AQC_FW_LOG_ID_MAX;
config = devm_kzalloc(ice_hw_to_dev(hw), size, GFP_KERNEL);
if (!config)
return ICE_ERR_NO_MEMORY;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging_info);
- desc.flags |= cpu_to_le16(ICE_AQ_FLAG_BUF);
- desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
-
status = ice_aq_send_cmd(hw, &desc, config, size, NULL);
if (!status) {
u16 i;
@@ -474,7 +619,7 @@ static enum ice_status ice_get_fw_log_cfg(struct ice_hw *hw)
for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
u16 v, m, flgs;
- v = le16_to_cpu(config->entry[i]);
+ v = le16_to_cpu(config[i]);
m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
flgs = (v & ICE_AQC_FW_LOG_EN_M) >> ICE_AQC_FW_LOG_EN_S;
@@ -526,11 +671,11 @@ static enum ice_status ice_get_fw_log_cfg(struct ice_hw *hw)
*/
static enum ice_status ice_cfg_fw_log(struct ice_hw *hw, bool enable)
{
- struct ice_aqc_fw_logging_data *data = NULL;
struct ice_aqc_fw_logging *cmd;
enum ice_status status = 0;
u16 i, chgs = 0, len = 0;
struct ice_aq_desc desc;
+ __le16 *data = NULL;
u8 actv_evnts = 0;
void *buf = NULL;
@@ -571,8 +716,9 @@ static enum ice_status ice_cfg_fw_log(struct ice_hw *hw, bool enable)
continue;
if (!data) {
- data = devm_kzalloc(ice_hw_to_dev(hw),
- ICE_FW_LOG_DESC_SIZE_MAX,
+ data = devm_kcalloc(ice_hw_to_dev(hw),
+ sizeof(*data),
+ ICE_AQC_FW_LOG_ID_MAX,
GFP_KERNEL);
if (!data)
return ICE_ERR_NO_MEMORY;
@@ -580,7 +726,7 @@ static enum ice_status ice_cfg_fw_log(struct ice_hw *hw, bool enable)
val = i << ICE_AQC_FW_LOG_ID_S;
val |= hw->fw_log.evnts[i].cfg << ICE_AQC_FW_LOG_EN_S;
- data->entry[chgs++] = cpu_to_le16(val);
+ data[chgs++] = cpu_to_le16(val);
}
/* Only enable FW logging if at least one module is specified.
@@ -599,7 +745,7 @@ static enum ice_status ice_cfg_fw_log(struct ice_hw *hw, bool enable)
cmd->log_ctrl |= ICE_AQC_FW_LOG_UART_EN;
buf = data;
- len = ICE_FW_LOG_DESC_SIZE(chgs);
+ len = sizeof(*data) * chgs;
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
}
}
@@ -629,7 +775,7 @@ static enum ice_status ice_cfg_fw_log(struct ice_hw *hw, bool enable)
continue;
}
- v = le16_to_cpu(data->entry[i]);
+ v = le16_to_cpu(data[i]);
m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
hw->fw_log.evnts[m].cur = hw->fw_log.evnts[m].cfg;
}
@@ -881,23 +1027,23 @@ void ice_deinit_hw(struct ice_hw *hw)
*/
enum ice_status ice_check_reset(struct ice_hw *hw)
{
- u32 cnt, reg = 0, grst_delay, uld_mask;
+ u32 cnt, reg = 0, grst_timeout, uld_mask;
/* Poll for Device Active state in case a recent CORER, GLOBR,
* or EMPR has occurred. The grst delay value is in 100ms units.
* Add 1sec for outstanding AQ commands that can take a long time.
*/
- grst_delay = ((rd32(hw, GLGEN_RSTCTL) & GLGEN_RSTCTL_GRSTDEL_M) >>
- GLGEN_RSTCTL_GRSTDEL_S) + 10;
+ grst_timeout = ((rd32(hw, GLGEN_RSTCTL) & GLGEN_RSTCTL_GRSTDEL_M) >>
+ GLGEN_RSTCTL_GRSTDEL_S) + 10;
- for (cnt = 0; cnt < grst_delay; cnt++) {
+ for (cnt = 0; cnt < grst_timeout; cnt++) {
mdelay(100);
reg = rd32(hw, GLGEN_RSTAT);
if (!(reg & GLGEN_RSTAT_DEVSTATE_M))
break;
}
- if (cnt == grst_delay) {
+ if (cnt == grst_timeout) {
ice_debug(hw, ICE_DBG_INIT,
"Global reset polling failed to complete.\n");
return ICE_ERR_RESET_FAILED;
@@ -1541,7 +1687,7 @@ ice_alloc_hw_res(struct ice_hw *hw, u16 type, u16 num, bool btm, u16 *res)
enum ice_status status;
u16 buf_len;
- buf_len = struct_size(buf, elem, num - 1);
+ buf_len = struct_size(buf, elem, num);
buf = kzalloc(buf_len, GFP_KERNEL);
if (!buf)
return ICE_ERR_NO_MEMORY;
@@ -1558,7 +1704,7 @@ ice_alloc_hw_res(struct ice_hw *hw, u16 type, u16 num, bool btm, u16 *res)
if (status)
goto ice_alloc_res_exit;
- memcpy(res, buf->elem, sizeof(buf->elem) * num);
+ memcpy(res, buf->elem, sizeof(*buf->elem) * num);
ice_alloc_res_exit:
kfree(buf);
@@ -1572,14 +1718,13 @@ ice_alloc_res_exit:
* @num: number of resources
* @res: pointer to array that contains the resources to free
*/
-enum ice_status
-ice_free_hw_res(struct ice_hw *hw, u16 type, u16 num, u16 *res)
+enum ice_status ice_free_hw_res(struct ice_hw *hw, u16 type, u16 num, u16 *res)
{
struct ice_aqc_alloc_free_res_elem *buf;
enum ice_status status;
u16 buf_len;
- buf_len = struct_size(buf, elem, num - 1);
+ buf_len = struct_size(buf, elem, num);
buf = kzalloc(buf_len, GFP_KERNEL);
if (!buf)
return ICE_ERR_NO_MEMORY;
@@ -1587,7 +1732,7 @@ ice_free_hw_res(struct ice_hw *hw, u16 type, u16 num, u16 *res)
/* Prepare buffer to free resource. */
buf->num_elems = cpu_to_le16(num);
buf->res_type = cpu_to_le16(type);
- memcpy(buf->elem, res, sizeof(buf->elem) * num);
+ memcpy(buf->elem, res, sizeof(*buf->elem) * num);
status = ice_aq_alloc_free_res(hw, num, buf, buf_len,
ice_aqc_opc_free_res, NULL);
@@ -1622,221 +1767,431 @@ static u32 ice_get_num_per_func(struct ice_hw *hw, u32 max)
}
/**
- * ice_parse_caps - parse function/device capabilities
+ * ice_parse_common_caps - parse common device/function capabilities
* @hw: pointer to the HW struct
- * @buf: pointer to a buffer containing function/device capability records
- * @cap_count: number of capability records in the list
- * @opc: type of capabilities list to parse
+ * @caps: pointer to common capabilities structure
+ * @elem: the capability element to parse
+ * @prefix: message prefix for tracing capabilities
+ *
+ * Given a capability element, extract relevant details into the common
+ * capability structure.
+ *
+ * Returns: true if the capability matches one of the common capability ids,
+ * false otherwise.
+ */
+static bool
+ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
+ struct ice_aqc_list_caps_elem *elem, const char *prefix)
+{
+ u32 logical_id = le32_to_cpu(elem->logical_id);
+ u32 phys_id = le32_to_cpu(elem->phys_id);
+ u32 number = le32_to_cpu(elem->number);
+ u16 cap = le16_to_cpu(elem->cap);
+ bool found = true;
+
+ switch (cap) {
+ case ICE_AQC_CAPS_VALID_FUNCTIONS:
+ caps->valid_functions = number;
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: valid_functions (bitmap) = %d\n", prefix,
+ caps->valid_functions);
+ break;
+ case ICE_AQC_CAPS_SRIOV:
+ caps->sr_iov_1_1 = (number == 1);
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: sr_iov_1_1 = %d\n", prefix,
+ caps->sr_iov_1_1);
+ break;
+ case ICE_AQC_CAPS_DCB:
+ caps->dcb = (number == 1);
+ caps->active_tc_bitmap = logical_id;
+ caps->maxtc = phys_id;
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: dcb = %d\n", prefix, caps->dcb);
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: active_tc_bitmap = %d\n", prefix,
+ caps->active_tc_bitmap);
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: maxtc = %d\n", prefix, caps->maxtc);
+ break;
+ case ICE_AQC_CAPS_RSS:
+ caps->rss_table_size = number;
+ caps->rss_table_entry_width = logical_id;
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: rss_table_size = %d\n", prefix,
+ caps->rss_table_size);
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: rss_table_entry_width = %d\n", prefix,
+ caps->rss_table_entry_width);
+ break;
+ case ICE_AQC_CAPS_RXQS:
+ caps->num_rxq = number;
+ caps->rxq_first_id = phys_id;
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: num_rxq = %d\n", prefix,
+ caps->num_rxq);
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: rxq_first_id = %d\n", prefix,
+ caps->rxq_first_id);
+ break;
+ case ICE_AQC_CAPS_TXQS:
+ caps->num_txq = number;
+ caps->txq_first_id = phys_id;
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: num_txq = %d\n", prefix,
+ caps->num_txq);
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: txq_first_id = %d\n", prefix,
+ caps->txq_first_id);
+ break;
+ case ICE_AQC_CAPS_MSIX:
+ caps->num_msix_vectors = number;
+ caps->msix_vector_first_id = phys_id;
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: num_msix_vectors = %d\n", prefix,
+ caps->num_msix_vectors);
+ ice_debug(hw, ICE_DBG_INIT,
+ "%s: msix_vector_first_id = %d\n", prefix,
+ caps->msix_vector_first_id);
+ break;
+ case ICE_AQC_CAPS_PENDING_NVM_VER:
+ caps->nvm_update_pending_nvm = true;
+ ice_debug(hw, ICE_DBG_INIT, "%s: update_pending_nvm\n", prefix);
+ break;
+ case ICE_AQC_CAPS_PENDING_OROM_VER:
+ caps->nvm_update_pending_orom = true;
+ ice_debug(hw, ICE_DBG_INIT, "%s: update_pending_orom\n", prefix);
+ break;
+ case ICE_AQC_CAPS_PENDING_NET_VER:
+ caps->nvm_update_pending_netlist = true;
+ ice_debug(hw, ICE_DBG_INIT, "%s: update_pending_netlist\n", prefix);
+ break;
+ case ICE_AQC_CAPS_NVM_MGMT:
+ caps->nvm_unified_update =
+ (number & ICE_NVM_MGMT_UNIFIED_UPD_SUPPORT) ?
+ true : false;
+ ice_debug(hw, ICE_DBG_INIT, "%s: nvm_unified_update = %d\n", prefix,
+ caps->nvm_unified_update);
+ break;
+ case ICE_AQC_CAPS_MAX_MTU:
+ caps->max_mtu = number;
+ ice_debug(hw, ICE_DBG_INIT, "%s: max_mtu = %d\n",
+ prefix, caps->max_mtu);
+ break;
+ default:
+ /* Not one of the recognized common capabilities */
+ found = false;
+ }
+
+ return found;
+}
+
+/**
+ * ice_recalc_port_limited_caps - Recalculate port limited capabilities
+ * @hw: pointer to the HW structure
+ * @caps: pointer to capabilities structure to fix
+ *
+ * Re-calculate the capabilities that are dependent on the number of physical
+ * ports; i.e. some features are not supported or function differently on
+ * devices with more than 4 ports.
+ */
+static void
+ice_recalc_port_limited_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps)
+{
+ /* This assumes device capabilities are always scanned before function
+ * capabilities during the initialization flow.
+ */
+ if (hw->dev_caps.num_funcs > 4) {
+ /* Max 4 TCs per port */
+ caps->maxtc = 4;
+ ice_debug(hw, ICE_DBG_INIT,
+ "reducing maxtc to %d (based on #ports)\n",
+ caps->maxtc);
+ }
+}
+
+/**
+ * ice_parse_vf_func_caps - Parse ICE_AQC_CAPS_VF function caps
+ * @hw: pointer to the HW struct
+ * @func_p: pointer to function capabilities structure
+ * @cap: pointer to the capability element to parse
+ *
+ * Extract function capabilities for ICE_AQC_CAPS_VF.
+ */
+static void
+ice_parse_vf_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
+ struct ice_aqc_list_caps_elem *cap)
+{
+ u32 logical_id = le32_to_cpu(cap->logical_id);
+ u32 number = le32_to_cpu(cap->number);
+
+ func_p->num_allocd_vfs = number;
+ func_p->vf_base_id = logical_id;
+ ice_debug(hw, ICE_DBG_INIT, "func caps: num_allocd_vfs = %d\n",
+ func_p->num_allocd_vfs);
+ ice_debug(hw, ICE_DBG_INIT, "func caps: vf_base_id = %d\n",
+ func_p->vf_base_id);
+}
+
+/**
+ * ice_parse_vsi_func_caps - Parse ICE_AQC_CAPS_VSI function caps
+ * @hw: pointer to the HW struct
+ * @func_p: pointer to function capabilities structure
+ * @cap: pointer to the capability element to parse
+ *
+ * Extract function capabilities for ICE_AQC_CAPS_VSI.
+ */
+static void
+ice_parse_vsi_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
+ struct ice_aqc_list_caps_elem *cap)
+{
+ func_p->guar_num_vsi = ice_get_num_per_func(hw, ICE_MAX_VSI);
+ ice_debug(hw, ICE_DBG_INIT, "func caps: guar_num_vsi (fw) = %d\n",
+ le32_to_cpu(cap->number));
+ ice_debug(hw, ICE_DBG_INIT, "func caps: guar_num_vsi = %d\n",
+ func_p->guar_num_vsi);
+}
+
+/**
+ * ice_parse_fdir_func_caps - Parse ICE_AQC_CAPS_FD function caps
+ * @hw: pointer to the HW struct
+ * @func_p: pointer to function capabilities structure
+ *
+ * Extract function capabilities for ICE_AQC_CAPS_FD.
+ */
+static void
+ice_parse_fdir_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p)
+{
+ u32 reg_val, val;
+
+ reg_val = rd32(hw, GLQF_FD_SIZE);
+ val = (reg_val & GLQF_FD_SIZE_FD_GSIZE_M) >>
+ GLQF_FD_SIZE_FD_GSIZE_S;
+ func_p->fd_fltr_guar =
+ ice_get_num_per_func(hw, val);
+ val = (reg_val & GLQF_FD_SIZE_FD_BSIZE_M) >>
+ GLQF_FD_SIZE_FD_BSIZE_S;
+ func_p->fd_fltr_best_effort = val;
+
+ ice_debug(hw, ICE_DBG_INIT,
+ "func caps: fd_fltr_guar = %d\n",
+ func_p->fd_fltr_guar);
+ ice_debug(hw, ICE_DBG_INIT,
+ "func caps: fd_fltr_best_effort = %d\n",
+ func_p->fd_fltr_best_effort);
+}
+
+/**
+ * ice_parse_func_caps - Parse function capabilities
+ * @hw: pointer to the HW struct
+ * @func_p: pointer to function capabilities structure
+ * @buf: buffer containing the function capability records
+ * @cap_count: the number of capabilities
+ *
+ * Helper function to parse function (0x000A) capabilities list. For
+ * capabilities shared between device and function, this relies on
+ * ice_parse_common_caps.
*
- * Helper function to parse function(0x000a)/device(0x000b) capabilities list.
+ * Loop through the list of provided capabilities and extract the relevant
+ * data into the function capabilities structured.
*/
static void
-ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count,
- enum ice_adminq_opc opc)
+ice_parse_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
+ void *buf, u32 cap_count)
{
struct ice_aqc_list_caps_elem *cap_resp;
- struct ice_hw_func_caps *func_p = NULL;
- struct ice_hw_dev_caps *dev_p = NULL;
- struct ice_hw_common_caps *caps;
- char const *prefix;
u32 i;
- if (!buf)
- return;
-
cap_resp = (struct ice_aqc_list_caps_elem *)buf;
- if (opc == ice_aqc_opc_list_dev_caps) {
- dev_p = &hw->dev_caps;
- caps = &dev_p->common_cap;
- prefix = "dev cap";
- } else if (opc == ice_aqc_opc_list_func_caps) {
- func_p = &hw->func_caps;
- caps = &func_p->common_cap;
- prefix = "func cap";
- } else {
- ice_debug(hw, ICE_DBG_INIT, "wrong opcode\n");
- return;
- }
+ memset(func_p, 0, sizeof(*func_p));
- for (i = 0; caps && i < cap_count; i++, cap_resp++) {
- u32 logical_id = le32_to_cpu(cap_resp->logical_id);
- u32 phys_id = le32_to_cpu(cap_resp->phys_id);
- u32 number = le32_to_cpu(cap_resp->number);
- u16 cap = le16_to_cpu(cap_resp->cap);
+ for (i = 0; i < cap_count; i++) {
+ u16 cap = le16_to_cpu(cap_resp[i].cap);
+ bool found;
- switch (cap) {
- case ICE_AQC_CAPS_VALID_FUNCTIONS:
- caps->valid_functions = number;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: valid_functions (bitmap) = %d\n", prefix,
- caps->valid_functions);
+ found = ice_parse_common_caps(hw, &func_p->common_cap,
+ &cap_resp[i], "func caps");
- /* store func count for resource management purposes */
- if (dev_p)
- dev_p->num_funcs = hweight32(number);
- break;
- case ICE_AQC_CAPS_SRIOV:
- caps->sr_iov_1_1 = (number == 1);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: sr_iov_1_1 = %d\n", prefix,
- caps->sr_iov_1_1);
- break;
+ switch (cap) {
case ICE_AQC_CAPS_VF:
- if (dev_p) {
- dev_p->num_vfs_exposed = number;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: num_vfs_exposed = %d\n", prefix,
- dev_p->num_vfs_exposed);
- } else if (func_p) {
- func_p->num_allocd_vfs = number;
- func_p->vf_base_id = logical_id;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: num_allocd_vfs = %d\n", prefix,
- func_p->num_allocd_vfs);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: vf_base_id = %d\n", prefix,
- func_p->vf_base_id);
- }
+ ice_parse_vf_func_caps(hw, func_p, &cap_resp[i]);
break;
case ICE_AQC_CAPS_VSI:
- if (dev_p) {
- dev_p->num_vsi_allocd_to_host = number;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: num_vsi_allocd_to_host = %d\n",
- prefix,
- dev_p->num_vsi_allocd_to_host);
- } else if (func_p) {
- func_p->guar_num_vsi =
- ice_get_num_per_func(hw, ICE_MAX_VSI);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: guar_num_vsi (fw) = %d\n",
- prefix, number);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: guar_num_vsi = %d\n",
- prefix, func_p->guar_num_vsi);
- }
+ ice_parse_vsi_func_caps(hw, func_p, &cap_resp[i]);
break;
- case ICE_AQC_CAPS_DCB:
- caps->dcb = (number == 1);
- caps->active_tc_bitmap = logical_id;
- caps->maxtc = phys_id;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: dcb = %d\n", prefix, caps->dcb);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: active_tc_bitmap = %d\n", prefix,
- caps->active_tc_bitmap);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: maxtc = %d\n", prefix, caps->maxtc);
- break;
- case ICE_AQC_CAPS_RSS:
- caps->rss_table_size = number;
- caps->rss_table_entry_width = logical_id;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: rss_table_size = %d\n", prefix,
- caps->rss_table_size);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: rss_table_entry_width = %d\n", prefix,
- caps->rss_table_entry_width);
+ case ICE_AQC_CAPS_FD:
+ ice_parse_fdir_func_caps(hw, func_p);
break;
- case ICE_AQC_CAPS_RXQS:
- caps->num_rxq = number;
- caps->rxq_first_id = phys_id;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: num_rxq = %d\n", prefix,
- caps->num_rxq);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: rxq_first_id = %d\n", prefix,
- caps->rxq_first_id);
+ default:
+ /* Don't list common capabilities as unknown */
+ if (!found)
+ ice_debug(hw, ICE_DBG_INIT,
+ "func caps: unknown capability[%d]: 0x%x\n",
+ i, cap);
break;
- case ICE_AQC_CAPS_TXQS:
- caps->num_txq = number;
- caps->txq_first_id = phys_id;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: num_txq = %d\n", prefix,
- caps->num_txq);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: txq_first_id = %d\n", prefix,
- caps->txq_first_id);
+ }
+ }
+
+ ice_recalc_port_limited_caps(hw, &func_p->common_cap);
+}
+
+/**
+ * ice_parse_valid_functions_cap - Parse ICE_AQC_CAPS_VALID_FUNCTIONS caps
+ * @hw: pointer to the HW struct
+ * @dev_p: pointer to device capabilities structure
+ * @cap: capability element to parse
+ *
+ * Parse ICE_AQC_CAPS_VALID_FUNCTIONS for device capabilities.
+ */
+static void
+ice_parse_valid_functions_cap(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
+ struct ice_aqc_list_caps_elem *cap)
+{
+ u32 number = le32_to_cpu(cap->number);
+
+ dev_p->num_funcs = hweight32(number);
+ ice_debug(hw, ICE_DBG_INIT, "dev caps: num_funcs = %d\n",
+ dev_p->num_funcs);
+}
+
+/**
+ * ice_parse_vf_dev_caps - Parse ICE_AQC_CAPS_VF device caps
+ * @hw: pointer to the HW struct
+ * @dev_p: pointer to device capabilities structure
+ * @cap: capability element to parse
+ *
+ * Parse ICE_AQC_CAPS_VF for device capabilities.
+ */
+static void
+ice_parse_vf_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
+ struct ice_aqc_list_caps_elem *cap)
+{
+ u32 number = le32_to_cpu(cap->number);
+
+ dev_p->num_vfs_exposed = number;
+ ice_debug(hw, ICE_DBG_INIT, "dev_caps: num_vfs_exposed = %d\n",
+ dev_p->num_vfs_exposed);
+}
+
+/**
+ * ice_parse_vsi_dev_caps - Parse ICE_AQC_CAPS_VSI device caps
+ * @hw: pointer to the HW struct
+ * @dev_p: pointer to device capabilities structure
+ * @cap: capability element to parse
+ *
+ * Parse ICE_AQC_CAPS_VSI for device capabilities.
+ */
+static void
+ice_parse_vsi_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
+ struct ice_aqc_list_caps_elem *cap)
+{
+ u32 number = le32_to_cpu(cap->number);
+
+ dev_p->num_vsi_allocd_to_host = number;
+ ice_debug(hw, ICE_DBG_INIT, "dev caps: num_vsi_allocd_to_host = %d\n",
+ dev_p->num_vsi_allocd_to_host);
+}
+
+/**
+ * ice_parse_fdir_dev_caps - Parse ICE_AQC_CAPS_FD device caps
+ * @hw: pointer to the HW struct
+ * @dev_p: pointer to device capabilities structure
+ * @cap: capability element to parse
+ *
+ * Parse ICE_AQC_CAPS_FD for device capabilities.
+ */
+static void
+ice_parse_fdir_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
+ struct ice_aqc_list_caps_elem *cap)
+{
+ u32 number = le32_to_cpu(cap->number);
+
+ dev_p->num_flow_director_fltr = number;
+ ice_debug(hw, ICE_DBG_INIT, "dev caps: num_flow_director_fltr = %d\n",
+ dev_p->num_flow_director_fltr);
+}
+
+/**
+ * ice_parse_dev_caps - Parse device capabilities
+ * @hw: pointer to the HW struct
+ * @dev_p: pointer to device capabilities structure
+ * @buf: buffer containing the device capability records
+ * @cap_count: the number of capabilities
+ *
+ * Helper device to parse device (0x000B) capabilities list. For
+ * capabilities shared between device and function, this relies on
+ * ice_parse_common_caps.
+ *
+ * Loop through the list of provided capabilities and extract the relevant
+ * data into the device capabilities structured.
+ */
+static void
+ice_parse_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
+ void *buf, u32 cap_count)
+{
+ struct ice_aqc_list_caps_elem *cap_resp;
+ u32 i;
+
+ cap_resp = (struct ice_aqc_list_caps_elem *)buf;
+
+ memset(dev_p, 0, sizeof(*dev_p));
+
+ for (i = 0; i < cap_count; i++) {
+ u16 cap = le16_to_cpu(cap_resp[i].cap);
+ bool found;
+
+ found = ice_parse_common_caps(hw, &dev_p->common_cap,
+ &cap_resp[i], "dev caps");
+
+ switch (cap) {
+ case ICE_AQC_CAPS_VALID_FUNCTIONS:
+ ice_parse_valid_functions_cap(hw, dev_p, &cap_resp[i]);
break;
- case ICE_AQC_CAPS_MSIX:
- caps->num_msix_vectors = number;
- caps->msix_vector_first_id = phys_id;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: num_msix_vectors = %d\n", prefix,
- caps->num_msix_vectors);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: msix_vector_first_id = %d\n", prefix,
- caps->msix_vector_first_id);
+ case ICE_AQC_CAPS_VF:
+ ice_parse_vf_dev_caps(hw, dev_p, &cap_resp[i]);
break;
- case ICE_AQC_CAPS_FD:
- if (dev_p) {
- dev_p->num_flow_director_fltr = number;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: num_flow_director_fltr = %d\n",
- prefix,
- dev_p->num_flow_director_fltr);
- }
- if (func_p) {
- u32 reg_val, val;
-
- reg_val = rd32(hw, GLQF_FD_SIZE);
- val = (reg_val & GLQF_FD_SIZE_FD_GSIZE_M) >>
- GLQF_FD_SIZE_FD_GSIZE_S;
- func_p->fd_fltr_guar =
- ice_get_num_per_func(hw, val);
- val = (reg_val & GLQF_FD_SIZE_FD_BSIZE_M) >>
- GLQF_FD_SIZE_FD_BSIZE_S;
- func_p->fd_fltr_best_effort = val;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: fd_fltr_guar = %d\n",
- prefix, func_p->fd_fltr_guar);
- ice_debug(hw, ICE_DBG_INIT,
- "%s: fd_fltr_best_effort = %d\n",
- prefix, func_p->fd_fltr_best_effort);
- }
+ case ICE_AQC_CAPS_VSI:
+ ice_parse_vsi_dev_caps(hw, dev_p, &cap_resp[i]);
break;
- case ICE_AQC_CAPS_MAX_MTU:
- caps->max_mtu = number;
- ice_debug(hw, ICE_DBG_INIT, "%s: max_mtu = %d\n",
- prefix, caps->max_mtu);
+ case ICE_AQC_CAPS_FD:
+ ice_parse_fdir_dev_caps(hw, dev_p, &cap_resp[i]);
break;
default:
- ice_debug(hw, ICE_DBG_INIT,
- "%s: unknown capability[%d]: 0x%x\n", prefix,
- i, cap);
+ /* Don't list common capabilities as unknown */
+ if (!found)
+ ice_debug(hw, ICE_DBG_INIT,
+ "dev caps: unknown capability[%d]: 0x%x\n",
+ i, cap);
break;
}
}
- /* Re-calculate capabilities that are dependent on the number of
- * physical ports; i.e. some features are not supported or function
- * differently on devices with more than 4 ports.
- */
- if (hw->dev_caps.num_funcs > 4) {
- /* Max 4 TCs per port */
- caps->maxtc = 4;
- ice_debug(hw, ICE_DBG_INIT,
- "%s: maxtc = %d (based on #ports)\n", prefix,
- caps->maxtc);
- }
+ ice_recalc_port_limited_caps(hw, &dev_p->common_cap);
}
/**
- * ice_aq_discover_caps - query function/device capabilities
+ * ice_aq_list_caps - query function/device capabilities
* @hw: pointer to the HW struct
- * @buf: a virtual buffer to hold the capabilities
- * @buf_size: Size of the virtual buffer
- * @cap_count: cap count needed if AQ err==ENOMEM
- * @opc: capabilities type to discover - pass in the command opcode
+ * @buf: a buffer to hold the capabilities
+ * @buf_size: size of the buffer
+ * @cap_count: if not NULL, set to the number of capabilities reported
+ * @opc: capabilities type to discover, device or function
* @cd: pointer to command details structure or NULL
*
- * Get the function(0x000a)/device(0x000b) capabilities description from
- * the firmware.
+ * Get the function (0x000A) or device (0x000B) capabilities description from
+ * firmware and store it in the buffer.
+ *
+ * If the cap_count pointer is not NULL, then it is set to the number of
+ * capabilities firmware will report. Note that if the buffer size is too
+ * small, it is possible the command will return ICE_AQ_ERR_ENOMEM. The
+ * cap_count will still be updated in this case. It is recommended that the
+ * buffer size be set to ICE_AQ_MAX_BUF_LEN (the largest possible buffer that
+ * firmware could return) to avoid this.
*/
-static enum ice_status
-ice_aq_discover_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
- enum ice_adminq_opc opc, struct ice_sq_cd *cd)
+enum ice_status
+ice_aq_list_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
+ enum ice_adminq_opc opc, struct ice_sq_cd *cd)
{
struct ice_aqc_list_caps *cmd;
struct ice_aq_desc desc;
@@ -1849,59 +2204,78 @@ ice_aq_discover_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
return ICE_ERR_PARAM;
ice_fill_dflt_direct_cmd_desc(&desc, opc);
-
status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
- if (!status)
- ice_parse_caps(hw, buf, le32_to_cpu(cmd->count), opc);
- else if (hw->adminq.sq_last_status == ICE_AQ_RC_ENOMEM)
+
+ if (cap_count)
*cap_count = le32_to_cpu(cmd->count);
+
return status;
}
/**
- * ice_discover_caps - get info about the HW
+ * ice_discover_dev_caps - Read and extract device capabilities
* @hw: pointer to the hardware structure
- * @opc: capabilities type to discover - pass in the command opcode
+ * @dev_caps: pointer to device capabilities structure
+ *
+ * Read the device capabilities and extract them into the dev_caps structure
+ * for later use.
*/
-static enum ice_status
-ice_discover_caps(struct ice_hw *hw, enum ice_adminq_opc opc)
+enum ice_status
+ice_discover_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_caps)
{
enum ice_status status;
- u32 cap_count;
- u16 cbuf_len;
- u8 retries;
-
- /* The driver doesn't know how many capabilities the device will return
- * so the buffer size required isn't known ahead of time. The driver
- * starts with cbuf_len and if this turns out to be insufficient, the
- * device returns ICE_AQ_RC_ENOMEM and also the cap_count it needs.
- * The driver then allocates the buffer based on the count and retries
- * the operation. So it follows that the retry count is 2.
+ u32 cap_count = 0;
+ void *cbuf;
+
+ cbuf = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
+ if (!cbuf)
+ return ICE_ERR_NO_MEMORY;
+
+ /* Although the driver doesn't know the number of capabilities the
+ * device will return, we can simply send a 4KB buffer, the maximum
+ * possible size that firmware can return.
*/
-#define ICE_GET_CAP_BUF_COUNT 40
-#define ICE_GET_CAP_RETRY_COUNT 2
+ cap_count = ICE_AQ_MAX_BUF_LEN / sizeof(struct ice_aqc_list_caps_elem);
- cap_count = ICE_GET_CAP_BUF_COUNT;
- retries = ICE_GET_CAP_RETRY_COUNT;
+ status = ice_aq_list_caps(hw, cbuf, ICE_AQ_MAX_BUF_LEN, &cap_count,
+ ice_aqc_opc_list_dev_caps, NULL);
+ if (!status)
+ ice_parse_dev_caps(hw, dev_caps, cbuf, cap_count);
+ kfree(cbuf);
- do {
- void *cbuf;
+ return status;
+}
- cbuf_len = (u16)(cap_count *
- sizeof(struct ice_aqc_list_caps_elem));
- cbuf = devm_kzalloc(ice_hw_to_dev(hw), cbuf_len, GFP_KERNEL);
- if (!cbuf)
- return ICE_ERR_NO_MEMORY;
+/**
+ * ice_discover_func_caps - Read and extract function capabilities
+ * @hw: pointer to the hardware structure
+ * @func_caps: pointer to function capabilities structure
+ *
+ * Read the function capabilities and extract them into the func_caps structure
+ * for later use.
+ */
+static enum ice_status
+ice_discover_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_caps)
+{
+ enum ice_status status;
+ u32 cap_count = 0;
+ void *cbuf;
- status = ice_aq_discover_caps(hw, cbuf, cbuf_len, &cap_count,
- opc, NULL);
- devm_kfree(ice_hw_to_dev(hw), cbuf);
+ cbuf = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
+ if (!cbuf)
+ return ICE_ERR_NO_MEMORY;
- if (!status || hw->adminq.sq_last_status != ICE_AQ_RC_ENOMEM)
- break;
+ /* Although the driver doesn't know the number of capabilities the
+ * device will return, we can simply send a 4KB buffer, the maximum
+ * possible size that firmware can return.
+ */
+ cap_count = ICE_AQ_MAX_BUF_LEN / sizeof(struct ice_aqc_list_caps_elem);
- /* If ENOMEM is returned, try again with bigger buffer */
- } while (--retries);
+ status = ice_aq_list_caps(hw, cbuf, ICE_AQ_MAX_BUF_LEN, &cap_count,
+ ice_aqc_opc_list_func_caps, NULL);
+ if (!status)
+ ice_parse_func_caps(hw, func_caps, cbuf, cap_count);
+ kfree(cbuf);
return status;
}
@@ -1978,11 +2352,11 @@ enum ice_status ice_get_caps(struct ice_hw *hw)
{
enum ice_status status;
- status = ice_discover_caps(hw, ice_aqc_opc_list_dev_caps);
- if (!status)
- status = ice_discover_caps(hw, ice_aqc_opc_list_func_caps);
+ status = ice_discover_dev_caps(hw, &hw->dev_caps);
+ if (status)
+ return status;
- return status;
+ return ice_discover_func_caps(hw, &hw->func_caps);
}
/**
@@ -2218,7 +2592,7 @@ ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
/**
* ice_aq_set_phy_cfg
* @hw: pointer to the HW struct
- * @lport: logical port number
+ * @pi: port info structure of the interested logical port
* @cfg: structure with PHY configuration data to be set
* @cd: pointer to command details structure or NULL
*
@@ -2228,7 +2602,7 @@ ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
* parameters. This status will be indicated by the command response (0x0601).
*/
enum ice_status
-ice_aq_set_phy_cfg(struct ice_hw *hw, u8 lport,
+ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi,
struct ice_aqc_set_phy_cfg_data *cfg, struct ice_sq_cd *cd)
{
struct ice_aq_desc desc;
@@ -2247,24 +2621,29 @@ ice_aq_set_phy_cfg(struct ice_hw *hw, u8 lport,
}
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_phy_cfg);
- desc.params.set_phy.lport_num = lport;
+ desc.params.set_phy.lport_num = pi->lport;
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
- ice_debug(hw, ICE_DBG_LINK, "phy_type_low = 0x%llx\n",
+ ice_debug(hw, ICE_DBG_LINK, "set phy cfg\n");
+ ice_debug(hw, ICE_DBG_LINK, " phy_type_low = 0x%llx\n",
(unsigned long long)le64_to_cpu(cfg->phy_type_low));
- ice_debug(hw, ICE_DBG_LINK, "phy_type_high = 0x%llx\n",
+ ice_debug(hw, ICE_DBG_LINK, " phy_type_high = 0x%llx\n",
(unsigned long long)le64_to_cpu(cfg->phy_type_high));
- ice_debug(hw, ICE_DBG_LINK, "caps = 0x%x\n", cfg->caps);
- ice_debug(hw, ICE_DBG_LINK, "low_power_ctrl = 0x%x\n",
- cfg->low_power_ctrl);
- ice_debug(hw, ICE_DBG_LINK, "eee_cap = 0x%x\n", cfg->eee_cap);
- ice_debug(hw, ICE_DBG_LINK, "eeer_value = 0x%x\n", cfg->eeer_value);
- ice_debug(hw, ICE_DBG_LINK, "link_fec_opt = 0x%x\n", cfg->link_fec_opt);
+ ice_debug(hw, ICE_DBG_LINK, " caps = 0x%x\n", cfg->caps);
+ ice_debug(hw, ICE_DBG_LINK, " low_power_ctrl_an = 0x%x\n",
+ cfg->low_power_ctrl_an);
+ ice_debug(hw, ICE_DBG_LINK, " eee_cap = 0x%x\n", cfg->eee_cap);
+ ice_debug(hw, ICE_DBG_LINK, " eeer_value = 0x%x\n", cfg->eeer_value);
+ ice_debug(hw, ICE_DBG_LINK, " link_fec_opt = 0x%x\n",
+ cfg->link_fec_opt);
status = ice_aq_send_cmd(hw, &desc, cfg, sizeof(*cfg), cd);
if (hw->adminq.sq_last_status == ICE_AQ_RC_EMODE)
status = 0;
+ if (!status)
+ pi->phy.curr_user_phy_cfg = *cfg;
+
return status;
}
@@ -2298,9 +2677,6 @@ enum ice_status ice_update_link_info(struct ice_port_info *pi)
status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP,
pcaps, NULL);
- if (!status)
- memcpy(li->module_type, &pcaps->module_type,
- sizeof(li->module_type));
devm_kfree(ice_hw_to_dev(hw), pcaps);
}
@@ -2309,28 +2685,101 @@ enum ice_status ice_update_link_info(struct ice_port_info *pi)
}
/**
- * ice_set_fc
+ * ice_cache_phy_user_req
* @pi: port information structure
- * @aq_failures: pointer to status code, specific to ice_set_fc routine
- * @ena_auto_link_update: enable automatic link update
+ * @cache_data: PHY logging data
+ * @cache_mode: PHY logging mode
*
- * Set the requested flow control mode.
+ * Log the user request on (FC, FEC, SPEED) for later use.
+ */
+static void
+ice_cache_phy_user_req(struct ice_port_info *pi,
+ struct ice_phy_cache_mode_data cache_data,
+ enum ice_phy_cache_mode cache_mode)
+{
+ if (!pi)
+ return;
+
+ switch (cache_mode) {
+ case ICE_FC_MODE:
+ pi->phy.curr_user_fc_req = cache_data.data.curr_user_fc_req;
+ break;
+ case ICE_SPEED_MODE:
+ pi->phy.curr_user_speed_req =
+ cache_data.data.curr_user_speed_req;
+ break;
+ case ICE_FEC_MODE:
+ pi->phy.curr_user_fec_req = cache_data.data.curr_user_fec_req;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * ice_caps_to_fc_mode
+ * @caps: PHY capabilities
+ *
+ * Convert PHY FC capabilities to ice FC mode
+ */
+enum ice_fc_mode ice_caps_to_fc_mode(u8 caps)
+{
+ if (caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE &&
+ caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE)
+ return ICE_FC_FULL;
+
+ if (caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE)
+ return ICE_FC_TX_PAUSE;
+
+ if (caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE)
+ return ICE_FC_RX_PAUSE;
+
+ return ICE_FC_NONE;
+}
+
+/**
+ * ice_caps_to_fec_mode
+ * @caps: PHY capabilities
+ * @fec_options: Link FEC options
+ *
+ * Convert PHY FEC capabilities to ice FEC mode
+ */
+enum ice_fec_mode ice_caps_to_fec_mode(u8 caps, u8 fec_options)
+{
+ if (caps & ICE_AQC_PHY_EN_AUTO_FEC)
+ return ICE_FEC_AUTO;
+
+ if (fec_options & (ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN |
+ ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ |
+ ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN |
+ ICE_AQC_PHY_FEC_25G_KR_REQ))
+ return ICE_FEC_BASER;
+
+ if (fec_options & (ICE_AQC_PHY_FEC_25G_RS_528_REQ |
+ ICE_AQC_PHY_FEC_25G_RS_544_REQ |
+ ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN))
+ return ICE_FEC_RS;
+
+ return ICE_FEC_NONE;
+}
+
+/**
+ * ice_cfg_phy_fc - Configure PHY FC data based on FC mode
+ * @pi: port information structure
+ * @cfg: PHY configuration data to set FC mode
+ * @req_mode: FC mode to configure
*/
enum ice_status
-ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
+ice_cfg_phy_fc(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
+ enum ice_fc_mode req_mode)
{
- struct ice_aqc_set_phy_cfg_data cfg = { 0 };
- struct ice_aqc_get_phy_caps_data *pcaps;
- enum ice_status status;
+ struct ice_phy_cache_mode_data cache_data;
u8 pause_mask = 0x0;
- struct ice_hw *hw;
- if (!pi)
- return ICE_ERR_PARAM;
- hw = pi->hw;
- *aq_failures = ICE_SET_FC_AQ_FAIL_NONE;
+ if (!pi || !cfg)
+ return ICE_ERR_BAD_PTR;
- switch (pi->fc.req_mode) {
+ switch (req_mode) {
case ICE_FC_FULL:
pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE;
pause_mask |= ICE_AQC_PHY_EN_RX_LINK_PAUSE;
@@ -2345,6 +2794,42 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
break;
}
+ /* clear the old pause settings */
+ cfg->caps &= ~(ICE_AQC_PHY_EN_TX_LINK_PAUSE |
+ ICE_AQC_PHY_EN_RX_LINK_PAUSE);
+
+ /* set the new capabilities */
+ cfg->caps |= pause_mask;
+
+ /* Cache user FC request */
+ cache_data.data.curr_user_fc_req = req_mode;
+ ice_cache_phy_user_req(pi, cache_data, ICE_FC_MODE);
+
+ return 0;
+}
+
+/**
+ * ice_set_fc
+ * @pi: port information structure
+ * @aq_failures: pointer to status code, specific to ice_set_fc routine
+ * @ena_auto_link_update: enable automatic link update
+ *
+ * Set the requested flow control mode.
+ */
+enum ice_status
+ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
+{
+ struct ice_aqc_set_phy_cfg_data cfg = { 0 };
+ struct ice_aqc_get_phy_caps_data *pcaps;
+ enum ice_status status;
+ struct ice_hw *hw;
+
+ if (!pi || !aq_failures)
+ return ICE_ERR_BAD_PTR;
+
+ *aq_failures = 0;
+ hw = pi->hw;
+
pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL);
if (!pcaps)
return ICE_ERR_NO_MEMORY;
@@ -2357,12 +2842,12 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
goto out;
}
- /* clear the old pause settings */
- cfg.caps = pcaps->caps & ~(ICE_AQC_PHY_EN_TX_LINK_PAUSE |
- ICE_AQC_PHY_EN_RX_LINK_PAUSE);
+ ice_copy_phy_caps_to_cfg(pi, pcaps, &cfg);
- /* set the new capabilities */
- cfg.caps |= pause_mask;
+ /* Configure the set PHY data */
+ status = ice_cfg_phy_fc(pi, &cfg, pi->fc.req_mode);
+ if (status)
+ goto out;
/* If the capabilities have changed, then set the new config */
if (cfg.caps != pcaps->caps) {
@@ -2371,15 +2856,8 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
/* Auto restart link so settings take effect */
if (ena_auto_link_update)
cfg.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
- /* Copy over all the old settings */
- cfg.phy_type_high = pcaps->phy_type_high;
- cfg.phy_type_low = pcaps->phy_type_low;
- cfg.low_power_ctrl = pcaps->low_power_ctrl;
- cfg.eee_cap = pcaps->eee_cap;
- cfg.eeer_value = pcaps->eeer_value;
- cfg.link_fec_opt = pcaps->link_fec_options;
-
- status = ice_aq_set_phy_cfg(hw, pi->lport, &cfg, NULL);
+
+ status = ice_aq_set_phy_cfg(hw, pi, &cfg, NULL);
if (status) {
*aq_failures = ICE_SET_FC_AQ_FAIL_SET;
goto out;
@@ -2409,7 +2887,44 @@ out:
}
/**
+ * ice_phy_caps_equals_cfg
+ * @phy_caps: PHY capabilities
+ * @phy_cfg: PHY configuration
+ *
+ * Helper function to determine if PHY capabilities matches PHY
+ * configuration
+ */
+bool
+ice_phy_caps_equals_cfg(struct ice_aqc_get_phy_caps_data *phy_caps,
+ struct ice_aqc_set_phy_cfg_data *phy_cfg)
+{
+ u8 caps_mask, cfg_mask;
+
+ if (!phy_caps || !phy_cfg)
+ return false;
+
+ /* These bits are not common between capabilities and configuration.
+ * Do not use them to determine equality.
+ */
+ caps_mask = ICE_AQC_PHY_CAPS_MASK & ~(ICE_AQC_PHY_AN_MODE |
+ ICE_AQC_GET_PHY_EN_MOD_QUAL);
+ cfg_mask = ICE_AQ_PHY_ENA_VALID_MASK & ~ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
+
+ if (phy_caps->phy_type_low != phy_cfg->phy_type_low ||
+ phy_caps->phy_type_high != phy_cfg->phy_type_high ||
+ ((phy_caps->caps & caps_mask) != (phy_cfg->caps & cfg_mask)) ||
+ phy_caps->low_power_ctrl_an != phy_cfg->low_power_ctrl_an ||
+ phy_caps->eee_cap != phy_cfg->eee_cap ||
+ phy_caps->eeer_value != phy_cfg->eeer_value ||
+ phy_caps->link_fec_options != phy_cfg->link_fec_opt)
+ return false;
+
+ return true;
+}
+
+/**
* ice_copy_phy_caps_to_cfg - Copy PHY ability data to configuration data
+ * @pi: port information structure
* @caps: PHY ability structure to copy date from
* @cfg: PHY configuration structure to copy data to
*
@@ -2417,42 +2932,73 @@ out:
* data structure
*/
void
-ice_copy_phy_caps_to_cfg(struct ice_aqc_get_phy_caps_data *caps,
+ice_copy_phy_caps_to_cfg(struct ice_port_info *pi,
+ struct ice_aqc_get_phy_caps_data *caps,
struct ice_aqc_set_phy_cfg_data *cfg)
{
- if (!caps || !cfg)
+ if (!pi || !caps || !cfg)
return;
+ memset(cfg, 0, sizeof(*cfg));
cfg->phy_type_low = caps->phy_type_low;
cfg->phy_type_high = caps->phy_type_high;
cfg->caps = caps->caps;
- cfg->low_power_ctrl = caps->low_power_ctrl;
+ cfg->low_power_ctrl_an = caps->low_power_ctrl_an;
cfg->eee_cap = caps->eee_cap;
cfg->eeer_value = caps->eeer_value;
cfg->link_fec_opt = caps->link_fec_options;
+ cfg->module_compliance_enforcement =
+ caps->module_compliance_enforcement;
+
+ if (ice_fw_supports_link_override(pi->hw)) {
+ struct ice_link_default_override_tlv tlv;
+
+ if (ice_get_link_default_override(&tlv, pi))
+ return;
+
+ if (tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE)
+ cfg->module_compliance_enforcement |=
+ ICE_LINK_OVERRIDE_STRICT_MODE;
+ }
}
/**
* ice_cfg_phy_fec - Configure PHY FEC data based on FEC mode
+ * @pi: port information structure
* @cfg: PHY configuration data to set FEC mode
* @fec: FEC mode to configure
- *
- * Caller should copy ice_aqc_get_phy_caps_data.caps ICE_AQC_PHY_EN_AUTO_FEC
- * (bit 7) and ice_aqc_get_phy_caps_data.link_fec_options to cfg.caps
- * ICE_AQ_PHY_ENA_AUTO_FEC (bit 7) and cfg.link_fec_options before calling.
*/
-void
-ice_cfg_phy_fec(struct ice_aqc_set_phy_cfg_data *cfg, enum ice_fec_mode fec)
+enum ice_status
+ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
+ enum ice_fec_mode fec)
{
+ struct ice_aqc_get_phy_caps_data *pcaps;
+ enum ice_status status;
+
+ if (!pi || !cfg)
+ return ICE_ERR_BAD_PTR;
+
+ pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
+ if (!pcaps)
+ return ICE_ERR_NO_MEMORY;
+
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP, pcaps,
+ NULL);
+ if (status)
+ goto out;
+
+ cfg->caps |= pcaps->caps & ICE_AQC_PHY_EN_AUTO_FEC;
+ cfg->link_fec_opt = pcaps->link_fec_options;
+
switch (fec) {
case ICE_FEC_BASER:
/* Clear RS bits, and AND BASE-R ability
* bits and OR request bits.
*/
cfg->link_fec_opt &= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN |
- ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN;
+ ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN;
cfg->link_fec_opt |= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ |
- ICE_AQC_PHY_FEC_25G_KR_REQ;
+ ICE_AQC_PHY_FEC_25G_KR_REQ;
break;
case ICE_FEC_RS:
/* Clear BASE-R bits, and AND RS ability
@@ -2460,7 +3006,7 @@ ice_cfg_phy_fec(struct ice_aqc_set_phy_cfg_data *cfg, enum ice_fec_mode fec)
*/
cfg->link_fec_opt &= ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN;
cfg->link_fec_opt |= ICE_AQC_PHY_FEC_25G_RS_528_REQ |
- ICE_AQC_PHY_FEC_25G_RS_544_REQ;
+ ICE_AQC_PHY_FEC_25G_RS_544_REQ;
break;
case ICE_FEC_NONE:
/* Clear all FEC option bits. */
@@ -2469,8 +3015,28 @@ ice_cfg_phy_fec(struct ice_aqc_set_phy_cfg_data *cfg, enum ice_fec_mode fec)
case ICE_FEC_AUTO:
/* AND auto FEC bit, and all caps bits. */
cfg->caps &= ICE_AQC_PHY_CAPS_MASK;
+ cfg->link_fec_opt |= pcaps->link_fec_options;
break;
+ default:
+ status = ICE_ERR_PARAM;
+ break;
+ }
+
+ if (fec == ICE_FEC_AUTO && ice_fw_supports_link_override(pi->hw)) {
+ struct ice_link_default_override_tlv tlv;
+
+ if (ice_get_link_default_override(&tlv, pi))
+ goto out;
+
+ if (!(tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE) &&
+ (tlv.options & ICE_LINK_OVERRIDE_EN))
+ cfg->link_fec_opt = tlv.fec_options;
}
+
+out:
+ kfree(pcaps);
+
+ return status;
}
/**
@@ -2889,10 +3455,10 @@ ice_aq_add_lan_txq(struct ice_hw *hw, u8 num_qgrps,
struct ice_aqc_add_tx_qgrp *qg_list, u16 buf_size,
struct ice_sq_cd *cd)
{
- u16 i, sum_header_size, sum_q_size = 0;
struct ice_aqc_add_tx_qgrp *list;
struct ice_aqc_add_txqs *cmd;
struct ice_aq_desc desc;
+ u16 i, sum_size = 0;
cmd = &desc.params.add_txqs;
@@ -2904,18 +3470,13 @@ ice_aq_add_lan_txq(struct ice_hw *hw, u8 num_qgrps,
if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS)
return ICE_ERR_PARAM;
- sum_header_size = num_qgrps *
- (sizeof(*qg_list) - sizeof(*qg_list->txqs));
-
- list = qg_list;
- for (i = 0; i < num_qgrps; i++) {
- struct ice_aqc_add_txqs_perq *q = list->txqs;
-
- sum_q_size += list->num_txqs * sizeof(*q);
- list = (struct ice_aqc_add_tx_qgrp *)(q + list->num_txqs);
+ for (i = 0, list = qg_list; i < num_qgrps; i++) {
+ sum_size += struct_size(list, txqs, list->num_txqs);
+ list = (struct ice_aqc_add_tx_qgrp *)(list->txqs +
+ list->num_txqs);
}
- if (buf_size != (sum_header_size + sum_q_size))
+ if (buf_size != sum_size)
return ICE_ERR_PARAM;
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
@@ -2943,6 +3504,7 @@ ice_aq_dis_lan_txq(struct ice_hw *hw, u8 num_qgrps,
enum ice_disq_rst_src rst_src, u16 vmvf_num,
struct ice_sq_cd *cd)
{
+ struct ice_aqc_dis_txq_item *item;
struct ice_aqc_dis_txqs *cmd;
struct ice_aq_desc desc;
enum ice_status status;
@@ -2992,16 +3554,16 @@ ice_aq_dis_lan_txq(struct ice_hw *hw, u8 num_qgrps,
*/
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
- for (i = 0; i < num_qgrps; ++i) {
- /* Calculate the size taken up by the queue IDs in this group */
- sz += qg_list[i].num_qs * sizeof(qg_list[i].q_id);
-
- /* Add the size of the group header */
- sz += sizeof(qg_list[i]) - sizeof(qg_list[i].q_id);
+ for (i = 0, item = qg_list; i < num_qgrps; i++) {
+ u16 item_size = struct_size(item, q_id, item->num_qs);
/* If the num of queues is even, add 2 bytes of padding */
- if ((qg_list[i].num_qs % 2) == 0)
- sz += 2;
+ if ((item->num_qs % 2) == 0)
+ item_size += 2;
+
+ sz += item_size;
+
+ item = (struct ice_aqc_dis_txq_item *)((u8 *)item + item_size);
}
if (buf_size != sz)
@@ -3342,7 +3904,18 @@ ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 q_handle,
* Without setting the generic section as valid in valid_sections, the
* Admin queue command will fail with error code ICE_AQ_RC_EINVAL.
*/
- buf->txqs[0].info.valid_sections = ICE_AQC_ELEM_VALID_GENERIC;
+ buf->txqs[0].info.valid_sections =
+ ICE_AQC_ELEM_VALID_GENERIC | ICE_AQC_ELEM_VALID_CIR |
+ ICE_AQC_ELEM_VALID_EIR;
+ buf->txqs[0].info.generic = 0;
+ buf->txqs[0].info.cir_bw.bw_profile_idx =
+ cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
+ buf->txqs[0].info.cir_bw.bw_alloc =
+ cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
+ buf->txqs[0].info.eir_bw.bw_profile_idx =
+ cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
+ buf->txqs[0].info.eir_bw.bw_alloc =
+ cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
/* add the LAN queue */
status = ice_aq_add_lan_txq(hw, num_qgrps, buf, buf_size, cd);
@@ -3390,24 +3963,32 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues,
struct ice_sq_cd *cd)
{
enum ice_status status = ICE_ERR_DOES_NOT_EXIST;
- struct ice_aqc_dis_txq_item qg_list;
+ struct ice_aqc_dis_txq_item *qg_list;
struct ice_q_ctx *q_ctx;
- u16 i;
+ struct ice_hw *hw;
+ u16 i, buf_size;
if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
return ICE_ERR_CFG;
+ hw = pi->hw;
+
if (!num_queues) {
/* if queue is disabled already yet the disable queue command
* has to be sent to complete the VF reset, then call
* ice_aq_dis_lan_txq without any queue information
*/
if (rst_src)
- return ice_aq_dis_lan_txq(pi->hw, 0, NULL, 0, rst_src,
+ return ice_aq_dis_lan_txq(hw, 0, NULL, 0, rst_src,
vmvf_num, NULL);
return ICE_ERR_CFG;
}
+ buf_size = struct_size(qg_list, q_id, 1);
+ qg_list = kzalloc(buf_size, GFP_KERNEL);
+ if (!qg_list)
+ return ICE_ERR_NO_MEMORY;
+
mutex_lock(&pi->sched_lock);
for (i = 0; i < num_queues; i++) {
@@ -3416,23 +3997,22 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues,
node = ice_sched_find_node_by_teid(pi->root, q_teids[i]);
if (!node)
continue;
- q_ctx = ice_get_lan_q_ctx(pi->hw, vsi_handle, tc, q_handles[i]);
+ q_ctx = ice_get_lan_q_ctx(hw, vsi_handle, tc, q_handles[i]);
if (!q_ctx) {
- ice_debug(pi->hw, ICE_DBG_SCHED, "invalid queue handle%d\n",
+ ice_debug(hw, ICE_DBG_SCHED, "invalid queue handle%d\n",
q_handles[i]);
continue;
}
if (q_ctx->q_handle != q_handles[i]) {
- ice_debug(pi->hw, ICE_DBG_SCHED, "Err:handles %d %d\n",
+ ice_debug(hw, ICE_DBG_SCHED, "Err:handles %d %d\n",
q_ctx->q_handle, q_handles[i]);
continue;
}
- qg_list.parent_teid = node->info.parent_teid;
- qg_list.num_qs = 1;
- qg_list.q_id[0] = cpu_to_le16(q_ids[i]);
- status = ice_aq_dis_lan_txq(pi->hw, 1, &qg_list,
- sizeof(qg_list), rst_src, vmvf_num,
- cd);
+ qg_list->parent_teid = node->info.parent_teid;
+ qg_list->num_qs = 1;
+ qg_list->q_id[0] = cpu_to_le16(q_ids[i]);
+ status = ice_aq_dis_lan_txq(hw, 1, qg_list, buf_size, rst_src,
+ vmvf_num, cd);
if (status)
break;
@@ -3440,6 +4020,7 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues,
q_ctx->q_handle = ICE_INVAL_Q_HANDLE;
}
mutex_unlock(&pi->sched_lock);
+ kfree(qg_list);
return status;
}
@@ -3652,17 +4233,168 @@ ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
*/
enum ice_status
ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
- struct ice_aqc_get_elem *buf)
+ struct ice_aqc_txsched_elem_data *buf)
{
u16 buf_size, num_elem_ret = 0;
enum ice_status status;
buf_size = sizeof(*buf);
memset(buf, 0, buf_size);
- buf->generic[0].node_teid = cpu_to_le32(node_teid);
+ buf->node_teid = cpu_to_le32(node_teid);
status = ice_aq_query_sched_elems(hw, 1, buf, buf_size, &num_elem_ret,
NULL);
if (status || num_elem_ret != 1)
ice_debug(hw, ICE_DBG_SCHED, "query element failed\n");
return status;
}
+
+/**
+ * ice_fw_supports_link_override
+ * @hw: pointer to the hardware structure
+ *
+ * Checks if the firmware supports link override
+ */
+bool ice_fw_supports_link_override(struct ice_hw *hw)
+{
+ /* Currently, only supported for E810 devices */
+ if (hw->mac_type != ICE_MAC_E810)
+ return false;
+
+ if (hw->api_maj_ver == ICE_FW_API_LINK_OVERRIDE_MAJ) {
+ if (hw->api_min_ver > ICE_FW_API_LINK_OVERRIDE_MIN)
+ return true;
+ if (hw->api_min_ver == ICE_FW_API_LINK_OVERRIDE_MIN &&
+ hw->api_patch >= ICE_FW_API_LINK_OVERRIDE_PATCH)
+ return true;
+ } else if (hw->api_maj_ver > ICE_FW_API_LINK_OVERRIDE_MAJ) {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * ice_get_link_default_override
+ * @ldo: pointer to the link default override struct
+ * @pi: pointer to the port info struct
+ *
+ * Gets the link default override for a port
+ */
+enum ice_status
+ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
+ struct ice_port_info *pi)
+{
+ u16 i, tlv, tlv_len, tlv_start, buf, offset;
+ struct ice_hw *hw = pi->hw;
+ enum ice_status status;
+
+ status = ice_get_pfa_module_tlv(hw, &tlv, &tlv_len,
+ ICE_SR_LINK_DEFAULT_OVERRIDE_PTR);
+ if (status) {
+ ice_debug(hw, ICE_DBG_INIT,
+ "Failed to read link override TLV.\n");
+ return status;
+ }
+
+ /* Each port has its own config; calculate for our port */
+ tlv_start = tlv + pi->lport * ICE_SR_PFA_LINK_OVERRIDE_WORDS +
+ ICE_SR_PFA_LINK_OVERRIDE_OFFSET;
+
+ /* link options first */
+ status = ice_read_sr_word(hw, tlv_start, &buf);
+ if (status) {
+ ice_debug(hw, ICE_DBG_INIT,
+ "Failed to read override link options.\n");
+ return status;
+ }
+ ldo->options = buf & ICE_LINK_OVERRIDE_OPT_M;
+ ldo->phy_config = (buf & ICE_LINK_OVERRIDE_PHY_CFG_M) >>
+ ICE_LINK_OVERRIDE_PHY_CFG_S;
+
+ /* link PHY config */
+ offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_FEC_OFFSET;
+ status = ice_read_sr_word(hw, offset, &buf);
+ if (status) {
+ ice_debug(hw, ICE_DBG_INIT,
+ "Failed to read override phy config.\n");
+ return status;
+ }
+ ldo->fec_options = buf & ICE_LINK_OVERRIDE_FEC_OPT_M;
+
+ /* PHY types low */
+ offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET;
+ for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
+ status = ice_read_sr_word(hw, (offset + i), &buf);
+ if (status) {
+ ice_debug(hw, ICE_DBG_INIT,
+ "Failed to read override link options.\n");
+ return status;
+ }
+ /* shift 16 bits at a time to fill 64 bits */
+ ldo->phy_type_low |= ((u64)buf << (i * 16));
+ }
+
+ /* PHY types high */
+ offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET +
+ ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS;
+ for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
+ status = ice_read_sr_word(hw, (offset + i), &buf);
+ if (status) {
+ ice_debug(hw, ICE_DBG_INIT,
+ "Failed to read override link options.\n");
+ return status;
+ }
+ /* shift 16 bits at a time to fill 64 bits */
+ ldo->phy_type_high |= ((u64)buf << (i * 16));
+ }
+
+ return status;
+}
+
+/**
+ * ice_is_phy_caps_an_enabled - check if PHY capabilities autoneg is enabled
+ * @caps: get PHY capability data
+ */
+bool ice_is_phy_caps_an_enabled(struct ice_aqc_get_phy_caps_data *caps)
+{
+ if (caps->caps & ICE_AQC_PHY_AN_MODE ||
+ caps->low_power_ctrl_an & (ICE_AQC_PHY_AN_EN_CLAUSE28 |
+ ICE_AQC_PHY_AN_EN_CLAUSE73 |
+ ICE_AQC_PHY_AN_EN_CLAUSE37))
+ return true;
+
+ return false;
+}
+
+/**
+ * ice_aq_set_lldp_mib - Set the LLDP MIB
+ * @hw: pointer to the HW struct
+ * @mib_type: Local, Remote or both Local and Remote MIBs
+ * @buf: pointer to the caller-supplied buffer to store the MIB block
+ * @buf_size: size of the buffer (in bytes)
+ * @cd: pointer to command details structure or NULL
+ *
+ * Set the LLDP MIB. (0x0A08)
+ */
+enum ice_status
+ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size,
+ struct ice_sq_cd *cd)
+{
+ struct ice_aqc_lldp_set_local_mib *cmd;
+ struct ice_aq_desc desc;
+
+ cmd = &desc.params.lldp_set_mib;
+
+ if (buf_size == 0 || !buf)
+ return ICE_ERR_PARAM;
+
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_set_local_mib);
+
+ desc.flags |= cpu_to_le16((u16)ICE_AQ_FLAG_RD);
+ desc.datalen = cpu_to_le16(buf_size);
+
+ cmd->type = mib_type;
+ cmd->length = cpu_to_le16(buf_size);
+
+ return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
+}
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
index 9b9e50d2398b..3ebb973878c7 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.h
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
@@ -11,8 +11,6 @@
#include "ice_switch.h"
#include <linux/avf/virtchnl.h>
-enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw);
-
enum ice_status ice_init_hw(struct ice_hw *hw);
void ice_deinit_hw(struct ice_hw *hw);
enum ice_status ice_check_reset(struct ice_hw *hw);
@@ -87,6 +85,11 @@ enum ice_status
ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
struct ice_aqc_get_phy_caps_data *caps,
struct ice_sq_cd *cd);
+enum ice_status
+ice_aq_list_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
+ enum ice_adminq_opc opc, struct ice_sq_cd *cd);
+enum ice_status
+ice_discover_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_caps);
void
ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
u16 link_speeds_bitmap);
@@ -95,17 +98,33 @@ ice_aq_manage_mac_write(struct ice_hw *hw, const u8 *mac_addr, u8 flags,
struct ice_sq_cd *cd);
enum ice_status ice_clear_pf_cfg(struct ice_hw *hw);
enum ice_status
-ice_aq_set_phy_cfg(struct ice_hw *hw, u8 lport,
+ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi,
struct ice_aqc_set_phy_cfg_data *cfg, struct ice_sq_cd *cd);
+bool ice_fw_supports_link_override(struct ice_hw *hw);
+enum ice_status
+ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
+ struct ice_port_info *pi);
+bool ice_is_phy_caps_an_enabled(struct ice_aqc_get_phy_caps_data *caps);
+
+enum ice_fc_mode ice_caps_to_fc_mode(u8 caps);
+enum ice_fec_mode ice_caps_to_fec_mode(u8 caps, u8 fec_options);
enum ice_status
ice_set_fc(struct ice_port_info *pi, u8 *aq_failures,
bool ena_auto_link_update);
+enum ice_status
+ice_cfg_phy_fc(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
+ enum ice_fc_mode fc);
+bool
+ice_phy_caps_equals_cfg(struct ice_aqc_get_phy_caps_data *caps,
+ struct ice_aqc_set_phy_cfg_data *cfg);
void
-ice_cfg_phy_fec(struct ice_aqc_set_phy_cfg_data *cfg, enum ice_fec_mode fec);
-void
-ice_copy_phy_caps_to_cfg(struct ice_aqc_get_phy_caps_data *caps,
+ice_copy_phy_caps_to_cfg(struct ice_port_info *pi,
+ struct ice_aqc_get_phy_caps_data *caps,
struct ice_aqc_set_phy_cfg_data *cfg);
enum ice_status
+ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
+ enum ice_fec_mode fec);
+enum ice_status
ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
struct ice_sq_cd *cd);
enum ice_status
@@ -152,5 +171,8 @@ ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
u64 *prev_stat, u64 *cur_stat);
enum ice_status
ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
- struct ice_aqc_get_elem *buf);
+ struct ice_aqc_txsched_elem_data *buf);
+enum ice_status
+ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size,
+ struct ice_sq_cd *cd);
#endif /* _ICE_COMMON_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.c b/drivers/net/ethernet/intel/ice/ice_controlq.c
index 1e18021aa073..1f46a7828be8 100644
--- a/drivers/net/ethernet/intel/ice/ice_controlq.c
+++ b/drivers/net/ethernet/intel/ice/ice_controlq.c
@@ -312,9 +312,10 @@ ice_cfg_rq_regs(struct ice_hw *hw, struct ice_ctl_q_info *cq)
#define ICE_FREE_CQ_BUFS(hw, qi, ring) \
do { \
- int i; \
/* free descriptors */ \
- if ((qi)->ring.r.ring##_bi) \
+ if ((qi)->ring.r.ring##_bi) { \
+ int i; \
+ \
for (i = 0; i < (qi)->num_##ring##_entries; i++) \
if ((qi)->ring.r.ring##_bi[i].pa) { \
dmam_free_coherent(ice_hw_to_dev(hw), \
@@ -325,6 +326,7 @@ do { \
(qi)->ring.r.ring##_bi[i].pa = 0;\
(qi)->ring.r.ring##_bi[i].size = 0;\
} \
+ } \
/* free the buffer info list */ \
if ((qi)->ring.cmd_buf) \
devm_kfree(ice_hw_to_dev(hw), (qi)->ring.cmd_buf); \
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb.c b/drivers/net/ethernet/intel/ice/ice_dcb.c
index adb8dab765c8..2a3147ee0bbb 100644
--- a/drivers/net/ethernet/intel/ice/ice_dcb.c
+++ b/drivers/net/ethernet/intel/ice/ice_dcb.c
@@ -135,39 +135,6 @@ ice_aq_start_lldp(struct ice_hw *hw, bool persist, struct ice_sq_cd *cd)
}
/**
- * ice_aq_set_lldp_mib - Set the LLDP MIB
- * @hw: pointer to the HW struct
- * @mib_type: Local, Remote or both Local and Remote MIBs
- * @buf: pointer to the caller-supplied buffer to store the MIB block
- * @buf_size: size of the buffer (in bytes)
- * @cd: pointer to command details structure or NULL
- *
- * Set the LLDP MIB. (0x0A08)
- */
-static enum ice_status
-ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size,
- struct ice_sq_cd *cd)
-{
- struct ice_aqc_lldp_set_local_mib *cmd;
- struct ice_aq_desc desc;
-
- cmd = &desc.params.lldp_set_mib;
-
- if (buf_size == 0 || !buf)
- return ICE_ERR_PARAM;
-
- ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_set_local_mib);
-
- desc.flags |= cpu_to_le16((u16)ICE_AQ_FLAG_RD);
- desc.datalen = cpu_to_le16(buf_size);
-
- cmd->type = mib_type;
- cmd->length = cpu_to_le16(buf_size);
-
- return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
-}
-
-/**
* ice_get_dcbx_status
* @hw: pointer to the HW struct
*
@@ -1362,7 +1329,7 @@ ice_update_port_tc_tree_cfg(struct ice_port_info *pi,
struct ice_aqc_port_ets_elem *buf)
{
struct ice_sched_node *node, *tc_node;
- struct ice_aqc_get_elem elem;
+ struct ice_aqc_txsched_elem_data elem;
enum ice_status status = 0;
u32 teid1, teid2;
u8 i, j;
@@ -1404,7 +1371,7 @@ ice_update_port_tc_tree_cfg(struct ice_port_info *pi,
/* new TC */
status = ice_sched_query_elem(pi->hw, teid2, &elem);
if (!status)
- status = ice_sched_add_node(pi, 1, &elem.generic[0]);
+ status = ice_sched_add_node(pi, 1, &elem);
if (status)
break;
/* update the TC number */
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb.h b/drivers/net/ethernet/intel/ice/ice_dcb.h
index ee138f9bdc7c..d7e5e6178a21 100644
--- a/drivers/net/ethernet/intel/ice/ice_dcb.h
+++ b/drivers/net/ethernet/intel/ice/ice_dcb.h
@@ -87,7 +87,7 @@
struct ice_lldp_org_tlv {
__be16 typelen;
__be32 ouisubtype;
- u8 tlvinfo[1];
+ u8 tlvinfo[];
} __packed;
struct ice_cee_tlv_hdr {
@@ -109,7 +109,7 @@ struct ice_cee_feat_tlv {
#define ICE_CEE_FEAT_TLV_WILLING_M 0x40
#define ICE_CEE_FEAT_TLV_ERR_M 0x20
u8 subtype;
- u8 tlvinfo[1];
+ u8 tlvinfo[];
};
struct ice_cee_app_prio {
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
index 979af197f8a3..36abd6b7280c 100644
--- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
@@ -444,10 +444,6 @@ void ice_dcb_rebuild(struct ice_pf *pf)
goto dcb_error;
}
- /* If DCB was not enabled previously, we are done */
- if (!test_bit(ICE_FLAG_DCB_ENA, pf->flags))
- return;
-
mutex_lock(&pf->tc_mutex);
if (!pf->hw.port_info->is_sw_lldp)
@@ -467,7 +463,7 @@ void ice_dcb_rebuild(struct ice_pf *pf)
}
}
- dev_info(dev, "DCB restored after reset\n");
+ dev_info(dev, "DCB info restored\n");
ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
if (ret) {
dev_err(dev, "Query Port ETS failed\n");
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.h b/drivers/net/ethernet/intel/ice/ice_dcb_lib.h
index 323238669572..35c21d9ae009 100644
--- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.h
@@ -53,6 +53,12 @@ ice_set_cgd_num(struct ice_tlan_ctx *tlan_ctx, struct ice_ring *ring)
{
tlan_ctx->cgd_num = ring->dcb_tc;
}
+
+static inline bool ice_is_dcb_active(struct ice_pf *pf)
+{
+ return (test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags) ||
+ test_bit(ICE_FLAG_DCB_ENA, pf->flags));
+}
#else
#define ice_dcb_rebuild(pf) do {} while (0)
@@ -95,6 +101,11 @@ ice_tx_prepare_vlan_flags_dcb(struct ice_ring __always_unused *tx_ring,
return 0;
}
+static inline bool ice_is_dcb_active(struct ice_pf __always_unused *pf)
+{
+ return false;
+}
+
static inline bool
ice_is_pfc_causing_hung_q(struct ice_pf __always_unused *pf,
unsigned int __always_unused txqueue)
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c
index a73d06e06b5d..111d6bfe4222 100644
--- a/drivers/net/ethernet/intel/ice/ice_devlink.c
+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c
@@ -4,6 +4,7 @@
#include "ice.h"
#include "ice_lib.h"
#include "ice_devlink.h"
+#include "ice_fw_update.h"
static int ice_info_get_dsn(struct ice_pf *pf, char *buf, size_t len)
{
@@ -229,8 +230,61 @@ static int ice_devlink_info_get(struct devlink *devlink,
return 0;
}
+/**
+ * ice_devlink_flash_update - Update firmware stored in flash on the device
+ * @devlink: pointer to devlink associated with device to update
+ * @path: the path of the firmware file to use via request_firmware
+ * @component: name of the component to update, or NULL
+ * @extack: netlink extended ACK structure
+ *
+ * Perform a device flash update. The bulk of the update logic is contained
+ * within the ice_flash_pldm_image function.
+ *
+ * Returns: zero on success, or an error code on failure.
+ */
+static int
+ice_devlink_flash_update(struct devlink *devlink, const char *path,
+ const char *component, struct netlink_ext_ack *extack)
+{
+ struct ice_pf *pf = devlink_priv(devlink);
+ struct device *dev = &pf->pdev->dev;
+ struct ice_hw *hw = &pf->hw;
+ const struct firmware *fw;
+ int err;
+
+ /* individual component update is not yet supported */
+ if (component)
+ return -EOPNOTSUPP;
+
+ if (!hw->dev_caps.common_cap.nvm_unified_update) {
+ NL_SET_ERR_MSG_MOD(extack, "Current firmware does not support unified update");
+ return -EOPNOTSUPP;
+ }
+
+ err = ice_check_for_pending_update(pf, component, extack);
+ if (err)
+ return err;
+
+ err = request_firmware(&fw, path, dev);
+ if (err) {
+ NL_SET_ERR_MSG_MOD(extack, "Unable to read file from disk");
+ return err;
+ }
+
+ devlink_flash_update_begin_notify(devlink);
+ devlink_flash_update_status_notify(devlink, "Preparing to flash",
+ component, 0, 0);
+ err = ice_flash_pldm_image(pf, fw, extack);
+ devlink_flash_update_end_notify(devlink);
+
+ release_firmware(fw);
+
+ return err;
+}
+
static const struct devlink_ops ice_devlink_ops = {
.info_get = ice_devlink_info_get,
+ .flash_update = ice_devlink_flash_update,
};
static void ice_devlink_free(void *devlink_ptr)
@@ -303,7 +357,7 @@ void ice_devlink_unregister(struct ice_pf *pf)
*
* Create and register a devlink_port for this PF. Note that although each
* physical function is connected to a separate devlink instance, the port
- * will still be numbered according to the physical function id.
+ * will still be numbered according to the physical function ID.
*
* Return: zero on success or an error code on failure.
*/
@@ -312,6 +366,7 @@ int ice_devlink_create_port(struct ice_pf *pf)
struct devlink *devlink = priv_to_devlink(pf);
struct ice_vsi *vsi = ice_get_main_vsi(pf);
struct device *dev = ice_pf_to_dev(pf);
+ struct devlink_port_attrs attrs = {};
int err;
if (!vsi) {
@@ -319,8 +374,9 @@ int ice_devlink_create_port(struct ice_pf *pf)
return -EIO;
}
- devlink_port_attrs_set(&pf->devlink_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- pf->hw.pf_id, false, 0, NULL, 0);
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = pf->hw.pf_id;
+ devlink_port_attrs_set(&pf->devlink_port, &attrs);
err = devlink_port_register(devlink, &pf->devlink_port, pf->hw.pf_id);
if (err) {
dev_err(dev, "devlink_port_register failed: %d\n", err);
@@ -397,12 +453,60 @@ static int ice_devlink_nvm_snapshot(struct devlink *devlink,
return 0;
}
+/**
+ * ice_devlink_devcaps_snapshot - Capture snapshot of device capabilities
+ * @devlink: the devlink instance
+ * @extack: extended ACK response structure
+ * @data: on exit points to snapshot data buffer
+ *
+ * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for
+ * the device-caps devlink region. It captures a snapshot of the device
+ * capabilities reported by firmware.
+ *
+ * @returns zero on success, and updates the data pointer. Returns a non-zero
+ * error code on failure.
+ */
+static int
+ice_devlink_devcaps_snapshot(struct devlink *devlink,
+ struct netlink_ext_ack *extack, u8 **data)
+{
+ struct ice_pf *pf = devlink_priv(devlink);
+ struct device *dev = ice_pf_to_dev(pf);
+ struct ice_hw *hw = &pf->hw;
+ enum ice_status status;
+ void *devcaps;
+
+ devcaps = vzalloc(ICE_AQ_MAX_BUF_LEN);
+ if (!devcaps)
+ return -ENOMEM;
+
+ status = ice_aq_list_caps(hw, devcaps, ICE_AQ_MAX_BUF_LEN, NULL,
+ ice_aqc_opc_list_dev_caps, NULL);
+ if (status) {
+ dev_dbg(dev, "ice_aq_list_caps: failed to read device capabilities, err %d aq_err %d\n",
+ status, hw->adminq.sq_last_status);
+ NL_SET_ERR_MSG_MOD(extack, "Failed to read device capabilities");
+ vfree(devcaps);
+ return -EIO;
+ }
+
+ *data = (u8 *)devcaps;
+
+ return 0;
+}
+
static const struct devlink_region_ops ice_nvm_region_ops = {
.name = "nvm-flash",
.destructor = vfree,
.snapshot = ice_devlink_nvm_snapshot,
};
+static const struct devlink_region_ops ice_devcaps_region_ops = {
+ .name = "device-caps",
+ .destructor = vfree,
+ .snapshot = ice_devlink_devcaps_snapshot,
+};
+
/**
* ice_devlink_init_regions - Initialize devlink regions
* @pf: the PF device structure
@@ -424,6 +528,15 @@ void ice_devlink_init_regions(struct ice_pf *pf)
PTR_ERR(pf->nvm_region));
pf->nvm_region = NULL;
}
+
+ pf->devcaps_region = devlink_region_create(devlink,
+ &ice_devcaps_region_ops, 10,
+ ICE_AQ_MAX_BUF_LEN);
+ if (IS_ERR(pf->devcaps_region)) {
+ dev_err(dev, "failed to create device-caps devlink region, err %ld\n",
+ PTR_ERR(pf->devcaps_region));
+ pf->devcaps_region = NULL;
+ }
}
/**
@@ -436,4 +549,6 @@ void ice_devlink_destroy_regions(struct ice_pf *pf)
{
if (pf->nvm_region)
devlink_region_destroy(pf->nvm_region);
+ if (pf->devcaps_region)
+ devlink_region_destroy(pf->devcaps_region);
}
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
index 68c38004a088..9e8e9531cd87 100644
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -59,8 +59,11 @@ static const struct ice_stats ice_gstrings_vsi_stats[] = {
ICE_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol),
ICE_VSI_STAT("rx_alloc_fail", rx_buf_failed),
ICE_VSI_STAT("rx_pg_alloc_fail", rx_page_failed),
+ ICE_VSI_STAT("rx_gro_dropped", rx_gro_dropped),
ICE_VSI_STAT("tx_errors", eth_stats.tx_errors),
ICE_VSI_STAT("tx_linearize", tx_linearize),
+ ICE_VSI_STAT("tx_busy", tx_busy),
+ ICE_VSI_STAT("tx_restart", tx_restart),
};
enum ice_ethtool_test_id {
@@ -100,6 +103,7 @@ static const struct ice_stats ice_gstrings_pf_stats[] = {
ICE_PF_STAT("rx_broadcast.nic", stats.eth.rx_broadcast),
ICE_PF_STAT("tx_broadcast.nic", stats.eth.tx_broadcast),
ICE_PF_STAT("tx_errors.nic", stats.eth.tx_errors),
+ ICE_PF_STAT("tx_timeout.nic", tx_timeout_count),
ICE_PF_STAT("rx_size_64.nic", stats.rx_size_64),
ICE_PF_STAT("tx_size_64.nic", stats.tx_size_64),
ICE_PF_STAT("rx_size_127.nic", stats.rx_size_127),
@@ -179,7 +183,6 @@ ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
orom = &nvm->orom;
strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
- strscpy(drvinfo->version, ice_drv_ver, sizeof(drvinfo->version));
/* Display NVM version (from which the firmware version can be
* determined) which contains more pertinent information.
@@ -967,12 +970,8 @@ static int ice_set_fec_cfg(struct net_device *netdev, enum ice_fec_mode req_fec)
{
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ice_aqc_set_phy_cfg_data config = { 0 };
- struct ice_aqc_get_phy_caps_data *caps;
struct ice_vsi *vsi = np->vsi;
- u8 sw_cfg_caps, sw_cfg_fec;
struct ice_port_info *pi;
- enum ice_status status;
- int err = 0;
pi = vsi->port_info;
if (!pi)
@@ -984,54 +983,26 @@ static int ice_set_fec_cfg(struct net_device *netdev, enum ice_fec_mode req_fec)
return -EOPNOTSUPP;
}
- /* Get last SW configuration */
- caps = kzalloc(sizeof(*caps), GFP_KERNEL);
- if (!caps)
- return -ENOMEM;
-
- status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG,
- caps, NULL);
- if (status) {
- err = -EAGAIN;
- goto done;
- }
-
- /* Copy SW configuration returned from PHY caps to PHY config */
- ice_copy_phy_caps_to_cfg(caps, &config);
- sw_cfg_caps = caps->caps;
- sw_cfg_fec = caps->link_fec_options;
-
- /* Get toloplogy caps, then copy PHY FEC topoloy caps to PHY config */
- memset(caps, 0, sizeof(*caps));
-
- status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP,
- caps, NULL);
- if (status) {
- err = -EAGAIN;
- goto done;
- }
-
- config.caps |= (caps->caps & ICE_AQC_PHY_EN_AUTO_FEC);
- config.link_fec_opt = caps->link_fec_options;
+ /* Proceed only if requesting different FEC mode */
+ if (pi->phy.curr_user_fec_req == req_fec)
+ return 0;
- ice_cfg_phy_fec(&config, req_fec);
+ /* Copy the current user PHY configuration. The current user PHY
+ * configuration is initialized during probe from PHY capabilities
+ * software mode, and updated on set PHY configuration.
+ */
+ memcpy(&config, &pi->phy.curr_user_phy_cfg, sizeof(config));
- /* If FEC mode has changed, then set PHY configuration and enable AN. */
- if ((config.caps & ICE_AQ_PHY_ENA_AUTO_FEC) !=
- (sw_cfg_caps & ICE_AQC_PHY_EN_AUTO_FEC) ||
- config.link_fec_opt != sw_cfg_fec) {
- if (caps->caps & ICE_AQC_PHY_AN_MODE)
- config.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
+ ice_cfg_phy_fec(pi, &config, req_fec);
+ config.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
- status = ice_aq_set_phy_cfg(pi->hw, pi->lport, &config, NULL);
+ if (ice_aq_set_phy_cfg(pi->hw, pi, &config, NULL))
+ return -EAGAIN;
- if (status)
- err = -EAGAIN;
- }
+ /* Save requested FEC config */
+ pi->phy.curr_user_fec_req = req_fec;
-done:
- kfree(caps);
- return err;
+ return 0;
}
/**
@@ -1229,6 +1200,17 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
bitmap_xor(change_flags, pf->flags, orig_flags, ICE_PF_FLAGS_NBITS);
+ /* Do not allow change to link-down-on-close when Total Port Shutdown
+ * is enabled.
+ */
+ if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, change_flags) &&
+ test_bit(ICE_FLAG_TOTAL_PORT_SHUTDOWN_ENA, pf->flags)) {
+ dev_err(dev, "Setting link-down-on-close not supported on this port\n");
+ set_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, pf->flags);
+ ret = -EINVAL;
+ goto ethtool_exit;
+ }
+
if (test_bit(ICE_FLAG_FW_LLDP_AGENT, change_flags)) {
if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags)) {
enum ice_status status;
@@ -1316,6 +1298,7 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
change_bit(ICE_FLAG_VF_TRUE_PROMISC_ENA, pf->flags);
ret = -EAGAIN;
}
+ethtool_exit:
clear_bit(ICE_FLAG_ETHTOOL_CTXT, pf->flags);
return ret;
}
@@ -1420,6 +1403,77 @@ ice_get_ethtool_stats(struct net_device *netdev,
}
}
+#define ICE_PHY_TYPE_LOW_MASK_MIN_1G (ICE_PHY_TYPE_LOW_100BASE_TX | \
+ ICE_PHY_TYPE_LOW_100M_SGMII)
+
+#define ICE_PHY_TYPE_LOW_MASK_MIN_25G (ICE_PHY_TYPE_LOW_MASK_MIN_1G | \
+ ICE_PHY_TYPE_LOW_1000BASE_T | \
+ ICE_PHY_TYPE_LOW_1000BASE_SX | \
+ ICE_PHY_TYPE_LOW_1000BASE_LX | \
+ ICE_PHY_TYPE_LOW_1000BASE_KX | \
+ ICE_PHY_TYPE_LOW_1G_SGMII | \
+ ICE_PHY_TYPE_LOW_2500BASE_T | \
+ ICE_PHY_TYPE_LOW_2500BASE_X | \
+ ICE_PHY_TYPE_LOW_2500BASE_KX | \
+ ICE_PHY_TYPE_LOW_5GBASE_T | \
+ ICE_PHY_TYPE_LOW_5GBASE_KR | \
+ ICE_PHY_TYPE_LOW_10GBASE_T | \
+ ICE_PHY_TYPE_LOW_10G_SFI_DA | \
+ ICE_PHY_TYPE_LOW_10GBASE_SR | \
+ ICE_PHY_TYPE_LOW_10GBASE_LR | \
+ ICE_PHY_TYPE_LOW_10GBASE_KR_CR1 | \
+ ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC | \
+ ICE_PHY_TYPE_LOW_10G_SFI_C2C)
+
+#define ICE_PHY_TYPE_LOW_MASK_100G (ICE_PHY_TYPE_LOW_100GBASE_CR4 | \
+ ICE_PHY_TYPE_LOW_100GBASE_SR4 | \
+ ICE_PHY_TYPE_LOW_100GBASE_LR4 | \
+ ICE_PHY_TYPE_LOW_100GBASE_KR4 | \
+ ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC | \
+ ICE_PHY_TYPE_LOW_100G_CAUI4 | \
+ ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC | \
+ ICE_PHY_TYPE_LOW_100G_AUI4 | \
+ ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4 | \
+ ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4 | \
+ ICE_PHY_TYPE_LOW_100GBASE_CP2 | \
+ ICE_PHY_TYPE_LOW_100GBASE_SR2 | \
+ ICE_PHY_TYPE_LOW_100GBASE_DR)
+
+#define ICE_PHY_TYPE_HIGH_MASK_100G (ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4 | \
+ ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC |\
+ ICE_PHY_TYPE_HIGH_100G_CAUI2 | \
+ ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC | \
+ ICE_PHY_TYPE_HIGH_100G_AUI2)
+
+/**
+ * ice_mask_min_supported_speeds
+ * @phy_types_high: PHY type high
+ * @phy_types_low: PHY type low to apply minimum supported speeds mask
+ *
+ * Apply minimum supported speeds mask to PHY type low. These are the speeds
+ * for ethtool supported link mode.
+ */
+static
+void ice_mask_min_supported_speeds(u64 phy_types_high, u64 *phy_types_low)
+{
+ /* if QSFP connection with 100G speed, minimum supported speed is 25G */
+ if (*phy_types_low & ICE_PHY_TYPE_LOW_MASK_100G ||
+ phy_types_high & ICE_PHY_TYPE_HIGH_MASK_100G)
+ *phy_types_low &= ~ICE_PHY_TYPE_LOW_MASK_MIN_25G;
+ else
+ *phy_types_low &= ~ICE_PHY_TYPE_LOW_MASK_MIN_1G;
+}
+
+#define ice_ethtool_advertise_link_mode(aq_link_speed, ethtool_link_mode) \
+ do { \
+ if (req_speeds & (aq_link_speed) || \
+ (!req_speeds && \
+ (adv_phy_type_lo & phy_type_mask_lo || \
+ adv_phy_type_hi & phy_type_mask_hi))) \
+ ethtool_link_ksettings_add_link_mode(ks, advertising,\
+ ethtool_link_mode); \
+ } while (0)
+
/**
* ice_phy_type_to_ethtool - convert the phy_types to ethtool link modes
* @netdev: network interface device structure
@@ -1430,277 +1484,312 @@ ice_phy_type_to_ethtool(struct net_device *netdev,
struct ethtool_link_ksettings *ks)
{
struct ice_netdev_priv *np = netdev_priv(netdev);
- struct ice_link_status *hw_link_info;
- bool need_add_adv_mode = false;
struct ice_vsi *vsi = np->vsi;
- u64 phy_types_high;
- u64 phy_types_low;
+ struct ice_pf *pf = vsi->back;
+ u64 phy_type_mask_lo = 0;
+ u64 phy_type_mask_hi = 0;
+ u64 adv_phy_type_lo = 0;
+ u64 adv_phy_type_hi = 0;
+ u64 phy_types_high = 0;
+ u64 phy_types_low = 0;
+ u16 req_speeds;
+
+ req_speeds = vsi->port_info->phy.link_info.req_speeds;
+
+ /* Check if lenient mode is supported and enabled, or in strict mode.
+ *
+ * In lenient mode the Supported link modes are the PHY types without
+ * media. The Advertising link mode is either 1. the user requested
+ * speed, 2. the override PHY mask, or 3. the PHY types with media.
+ *
+ * In strict mode Supported link mode are the PHY type with media,
+ * and Advertising link modes are the media PHY type or the speed
+ * requested by user.
+ */
+ if (test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags)) {
+ struct ice_link_default_override_tlv *ldo;
- hw_link_info = &vsi->port_info->phy.link_info;
- phy_types_low = vsi->port_info->phy.phy_type_low;
- phy_types_high = vsi->port_info->phy.phy_type_high;
+ ldo = &pf->link_dflt_override;
+ phy_types_low = le64_to_cpu(pf->nvm_phy_type_lo);
+ phy_types_high = le64_to_cpu(pf->nvm_phy_type_hi);
+
+ ice_mask_min_supported_speeds(phy_types_high, &phy_types_low);
+
+ /* If override enabled and PHY mask set, then
+ * Advertising link mode is the intersection of the PHY
+ * types without media and the override PHY mask.
+ */
+ if (ldo->options & ICE_LINK_OVERRIDE_EN &&
+ (ldo->phy_type_low || ldo->phy_type_high)) {
+ adv_phy_type_lo =
+ le64_to_cpu(pf->nvm_phy_type_lo) &
+ ldo->phy_type_low;
+ adv_phy_type_hi =
+ le64_to_cpu(pf->nvm_phy_type_hi) &
+ ldo->phy_type_high;
+ }
+ } else {
+ phy_types_low = vsi->port_info->phy.phy_type_low;
+ phy_types_high = vsi->port_info->phy.phy_type_high;
+ }
+
+ /* If Advertising link mode PHY type is not using override PHY type,
+ * then use PHY type with media.
+ */
+ if (!adv_phy_type_lo && !adv_phy_type_hi) {
+ adv_phy_type_lo = vsi->port_info->phy.phy_type_low;
+ adv_phy_type_hi = vsi->port_info->phy.phy_type_high;
+ }
ethtool_link_ksettings_zero_link_mode(ks, supported);
ethtool_link_ksettings_zero_link_mode(ks, advertising);
- if (phy_types_low & ICE_PHY_TYPE_LOW_100BASE_TX ||
- phy_types_low & ICE_PHY_TYPE_LOW_100M_SGMII) {
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100BASE_TX |
+ ICE_PHY_TYPE_LOW_100M_SGMII;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
100baseT_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100MB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 100baseT_Full);
+
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100MB,
+ 100baseT_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_T ||
- phy_types_low & ICE_PHY_TYPE_LOW_1G_SGMII) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_1000BASE_T |
+ ICE_PHY_TYPE_LOW_1G_SGMII;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
1000baseT_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_1000MB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 1000baseT_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_1000MB,
+ 1000baseT_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_KX) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_1000BASE_KX;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
1000baseKX_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_1000MB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 1000baseKX_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_1000MB,
+ 1000baseKX_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_SX ||
- phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_LX) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_1000BASE_SX |
+ ICE_PHY_TYPE_LOW_1000BASE_LX;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
1000baseX_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_1000MB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 1000baseX_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_1000MB,
+ 1000baseX_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_2500BASE_T) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_2500BASE_T;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
2500baseT_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_2500MB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 2500baseT_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_2500MB,
+ 2500baseT_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_2500BASE_X ||
- phy_types_low & ICE_PHY_TYPE_LOW_2500BASE_KX) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_2500BASE_X |
+ ICE_PHY_TYPE_LOW_2500BASE_KX;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
2500baseX_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_2500MB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 2500baseX_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_2500MB,
+ 2500baseX_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_5GBASE_T ||
- phy_types_low & ICE_PHY_TYPE_LOW_5GBASE_KR) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_5GBASE_T |
+ ICE_PHY_TYPE_LOW_5GBASE_KR;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
5000baseT_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_5GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 5000baseT_Full);
- }
- if (phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_T ||
- phy_types_low & ICE_PHY_TYPE_LOW_10G_SFI_DA ||
- phy_types_low & ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC ||
- phy_types_low & ICE_PHY_TYPE_LOW_10G_SFI_C2C) {
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_5GB,
+ 5000baseT_Full);
+ }
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_T |
+ ICE_PHY_TYPE_LOW_10G_SFI_DA |
+ ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC |
+ ICE_PHY_TYPE_LOW_10G_SFI_C2C;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
10000baseT_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_10GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 10000baseT_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
+ 10000baseT_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_KR_CR1) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_KR_CR1;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
10000baseKR_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_10GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 10000baseKR_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
+ 10000baseKR_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_SR) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_SR;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
10000baseSR_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_10GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 10000baseSR_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
+ 10000baseSR_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_LR) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_LR;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
10000baseLR_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_10GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 10000baseLR_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
+ 10000baseLR_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_T ||
- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_CR ||
- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_CR_S ||
- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_CR1 ||
- phy_types_low & ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC ||
- phy_types_low & ICE_PHY_TYPE_LOW_25G_AUI_C2C) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_25GBASE_T |
+ ICE_PHY_TYPE_LOW_25GBASE_CR |
+ ICE_PHY_TYPE_LOW_25GBASE_CR_S |
+ ICE_PHY_TYPE_LOW_25GBASE_CR1 |
+ ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC |
+ ICE_PHY_TYPE_LOW_25G_AUI_C2C;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
25000baseCR_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_25GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 25000baseCR_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_25GB,
+ 25000baseCR_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_SR ||
- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_LR) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_25GBASE_SR |
+ ICE_PHY_TYPE_LOW_25GBASE_LR;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
25000baseSR_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_25GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 25000baseSR_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_25GB,
+ 25000baseSR_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_KR ||
- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_KR_S ||
- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_KR1) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_25GBASE_KR |
+ ICE_PHY_TYPE_LOW_25GBASE_KR_S |
+ ICE_PHY_TYPE_LOW_25GBASE_KR1;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
25000baseKR_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_25GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 25000baseKR_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_25GB,
+ 25000baseKR_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_KR4) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_KR4;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
40000baseKR4_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_40GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 40000baseKR4_Full);
- }
- if (phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_CR4 ||
- phy_types_low & ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC ||
- phy_types_low & ICE_PHY_TYPE_LOW_40G_XLAUI) {
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
+ 40000baseKR4_Full);
+ }
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_CR4 |
+ ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC |
+ ICE_PHY_TYPE_LOW_40G_XLAUI;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
40000baseCR4_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_40GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 40000baseCR4_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
+ 40000baseCR4_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_SR4) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_SR4;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
40000baseSR4_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_40GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 40000baseSR4_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
+ 40000baseSR4_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_LR4) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_LR4;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
40000baseLR4_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_40GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 40000baseLR4_Full);
- }
- if (phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_CR2 ||
- phy_types_low & ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC ||
- phy_types_low & ICE_PHY_TYPE_LOW_50G_LAUI2 ||
- phy_types_low & ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC ||
- phy_types_low & ICE_PHY_TYPE_LOW_50G_AUI2 ||
- phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_CP ||
- phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_SR ||
- phy_types_low & ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC ||
- phy_types_low & ICE_PHY_TYPE_LOW_50G_AUI1) {
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
+ 40000baseLR4_Full);
+ }
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_50GBASE_CR2 |
+ ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC |
+ ICE_PHY_TYPE_LOW_50G_LAUI2 |
+ ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC |
+ ICE_PHY_TYPE_LOW_50G_AUI2 |
+ ICE_PHY_TYPE_LOW_50GBASE_CP |
+ ICE_PHY_TYPE_LOW_50GBASE_SR |
+ ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC |
+ ICE_PHY_TYPE_LOW_50G_AUI1;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
50000baseCR2_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_50GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 50000baseCR2_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_50GB,
+ 50000baseCR2_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_KR2 ||
- phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_50GBASE_KR2 |
+ ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
50000baseKR2_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_50GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 50000baseKR2_Full);
- }
- if (phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_SR2 ||
- phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_LR2 ||
- phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_FR ||
- phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_LR) {
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_50GB,
+ 50000baseKR2_Full);
+ }
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_50GBASE_SR2 |
+ ICE_PHY_TYPE_LOW_50GBASE_LR2 |
+ ICE_PHY_TYPE_LOW_50GBASE_FR |
+ ICE_PHY_TYPE_LOW_50GBASE_LR;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
50000baseSR2_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_50GB)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 50000baseSR2_Full);
- }
- if (phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_CR4 ||
- phy_types_low & ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC ||
- phy_types_low & ICE_PHY_TYPE_LOW_100G_CAUI4 ||
- phy_types_low & ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC ||
- phy_types_low & ICE_PHY_TYPE_LOW_100G_AUI4 ||
- phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4 ||
- phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_CP2 ||
- phy_types_high & ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC ||
- phy_types_high & ICE_PHY_TYPE_HIGH_100G_CAUI2 ||
- phy_types_high & ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC ||
- phy_types_high & ICE_PHY_TYPE_HIGH_100G_AUI2) {
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_50GB,
+ 50000baseSR2_Full);
+ }
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_CR4 |
+ ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC |
+ ICE_PHY_TYPE_LOW_100G_CAUI4 |
+ ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC |
+ ICE_PHY_TYPE_LOW_100G_AUI4 |
+ ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4 |
+ ICE_PHY_TYPE_LOW_100GBASE_CP2;
+ phy_type_mask_hi = ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC |
+ ICE_PHY_TYPE_HIGH_100G_CAUI2 |
+ ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC |
+ ICE_PHY_TYPE_HIGH_100G_AUI2;
+ if (phy_types_low & phy_type_mask_lo ||
+ phy_types_high & phy_type_mask_hi) {
ethtool_link_ksettings_add_link_mode(ks, supported,
100000baseCR4_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100GB)
- need_add_adv_mode = true;
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
+ 100000baseCR4_Full);
}
- if (need_add_adv_mode) {
- need_add_adv_mode = false;
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 100000baseCR4_Full);
- }
- if (phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_SR4 ||
- phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_SR2) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_SR4 |
+ ICE_PHY_TYPE_LOW_100GBASE_SR2;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
100000baseSR4_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100GB)
- need_add_adv_mode = true;
- }
- if (need_add_adv_mode) {
- need_add_adv_mode = false;
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 100000baseSR4_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
+ 100000baseSR4_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_LR4 ||
- phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_DR) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_LR4 |
+ ICE_PHY_TYPE_LOW_100GBASE_DR;
+ if (phy_types_low & phy_type_mask_lo) {
ethtool_link_ksettings_add_link_mode(ks, supported,
100000baseLR4_ER4_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100GB)
- need_add_adv_mode = true;
- }
- if (need_add_adv_mode) {
- need_add_adv_mode = false;
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 100000baseLR4_ER4_Full);
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
+ 100000baseLR4_ER4_Full);
}
- if (phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_KR4 ||
- phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4 ||
- phy_types_high & ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4) {
+
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_KR4 |
+ ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4;
+ phy_type_mask_hi = ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4;
+ if (phy_types_low & phy_type_mask_lo ||
+ phy_types_high & phy_type_mask_hi) {
ethtool_link_ksettings_add_link_mode(ks, supported,
100000baseKR4_Full);
- if (!hw_link_info->req_speeds ||
- hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100GB)
- need_add_adv_mode = true;
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
+ 100000baseKR4_Full);
}
- if (need_add_adv_mode)
- ethtool_link_ksettings_add_link_mode(ks, advertising,
- 100000baseKR4_Full);
/* Autoneg PHY types */
if (phy_types_low & ICE_PHY_TYPE_LOW_100BASE_TX ||
@@ -2128,18 +2217,18 @@ static int
ice_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *ks)
{
- u8 autoneg, timeout = TEST_SET_BITS_TIMEOUT, lport = 0;
struct ice_netdev_priv *np = netdev_priv(netdev);
struct ethtool_link_ksettings safe_ks, copy_ks;
struct ice_aqc_get_phy_caps_data *abilities;
+ u8 autoneg, timeout = TEST_SET_BITS_TIMEOUT;
u16 adv_link_speed, curr_link_speed, idx;
struct ice_aqc_set_phy_cfg_data config;
struct ice_pf *pf = np->vsi->back;
struct ice_port_info *p;
u8 autoneg_changed = 0;
enum ice_status status;
- u64 phy_type_high;
- u64 phy_type_low;
+ u64 phy_type_high = 0;
+ u64 phy_type_low = 0;
int err = 0;
bool linkup;
@@ -2163,6 +2252,18 @@ ice_set_link_ksettings(struct net_device *netdev,
p->phy.link_info.link_info & ICE_AQ_LINK_UP)
return -EOPNOTSUPP;
+ abilities = kzalloc(sizeof(*abilities), GFP_KERNEL);
+ if (!abilities)
+ return -ENOMEM;
+
+ /* Get the PHY capabilities based on media */
+ status = ice_aq_get_phy_caps(p, false, ICE_AQC_REPORT_TOPO_CAP,
+ abilities, NULL);
+ if (status) {
+ err = -EAGAIN;
+ goto done;
+ }
+
/* copy the ksettings to copy_ks to avoid modifying the original */
memcpy(&copy_ks, ks, sizeof(copy_ks));
@@ -2179,8 +2280,12 @@ ice_set_link_ksettings(struct net_device *netdev,
*/
if (!bitmap_subset(copy_ks.link_modes.advertising,
safe_ks.link_modes.supported,
- __ETHTOOL_LINK_MODE_MASK_NBITS))
- return -EINVAL;
+ __ETHTOOL_LINK_MODE_MASK_NBITS)) {
+ if (!test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags))
+ netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
+ err = -EINVAL;
+ goto done;
+ }
/* get our own copy of the bits to check against */
memset(&safe_ks, 0, sizeof(safe_ks));
@@ -2197,33 +2302,27 @@ ice_set_link_ksettings(struct net_device *netdev,
/* If copy_ks.base and safe_ks.base are not the same now, then they are
* trying to set something that we do not support.
*/
- if (memcmp(&copy_ks.base, &safe_ks.base, sizeof(copy_ks.base)))
- return -EOPNOTSUPP;
+ if (memcmp(&copy_ks.base, &safe_ks.base, sizeof(copy_ks.base))) {
+ err = -EOPNOTSUPP;
+ goto done;
+ }
while (test_and_set_bit(__ICE_CFG_BUSY, pf->state)) {
timeout--;
- if (!timeout)
- return -EBUSY;
+ if (!timeout) {
+ err = -EBUSY;
+ goto done;
+ }
usleep_range(TEST_SET_BITS_SLEEP_MIN, TEST_SET_BITS_SLEEP_MAX);
}
- abilities = kzalloc(sizeof(*abilities), GFP_KERNEL);
- if (!abilities)
- return -ENOMEM;
-
- /* Get the current PHY config */
- status = ice_aq_get_phy_caps(p, false, ICE_AQC_REPORT_SW_CFG, abilities,
- NULL);
- if (status) {
- err = -EAGAIN;
- goto done;
- }
+ /* Copy the current user PHY configuration. The current user PHY
+ * configuration is initialized during probe from PHY capabilities
+ * software mode, and updated on set PHY configuration.
+ */
+ memcpy(&config, &p->phy.curr_user_phy_cfg, sizeof(config));
- /* Copy abilities to config in case autoneg is not set below */
- memset(&config, 0, sizeof(config));
- config.caps = abilities->caps & ~ICE_AQC_PHY_AN_MODE;
- if (abilities->caps & ICE_AQC_PHY_AN_MODE)
- config.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
+ config.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
/* Check autoneg */
err = ice_setup_autoneg(p, &safe_ks, &config, autoneg, &autoneg_changed,
@@ -2258,29 +2357,44 @@ ice_set_link_ksettings(struct net_device *netdev,
goto done;
}
- /* copy over the rest of the abilities */
- config.low_power_ctrl = abilities->low_power_ctrl;
- config.eee_cap = abilities->eee_cap;
- config.eeer_value = abilities->eeer_value;
- config.link_fec_opt = abilities->link_fec_options;
-
/* save the requested speeds */
p->phy.link_info.req_speeds = adv_link_speed;
/* set link and auto negotiation so changes take effect */
config.caps |= ICE_AQ_PHY_ENA_LINK;
- if (phy_type_low || phy_type_high) {
- config.phy_type_high = cpu_to_le64(phy_type_high) &
- abilities->phy_type_high;
- config.phy_type_low = cpu_to_le64(phy_type_low) &
- abilities->phy_type_low;
- } else {
+ /* check if there is a PHY type for the requested advertised speed */
+ if (!(phy_type_low || phy_type_high)) {
+ netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
err = -EAGAIN;
- netdev_info(netdev, "Nothing changed. No PHY_TYPE is corresponded to advertised link speed.\n");
goto done;
}
+ /* intersect requested advertised speed PHY types with media PHY types
+ * for set PHY configuration
+ */
+ config.phy_type_high = cpu_to_le64(phy_type_high) &
+ abilities->phy_type_high;
+ config.phy_type_low = cpu_to_le64(phy_type_low) &
+ abilities->phy_type_low;
+
+ if (!(config.phy_type_high || config.phy_type_low)) {
+ /* If there is no intersection and lenient mode is enabled, then
+ * intersect the requested advertised speed with NVM media type
+ * PHY types.
+ */
+ if (test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags)) {
+ config.phy_type_high = cpu_to_le64(phy_type_high) &
+ pf->nvm_phy_type_hi;
+ config.phy_type_low = cpu_to_le64(phy_type_low) &
+ pf->nvm_phy_type_lo;
+ } else {
+ netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
+ err = -EAGAIN;
+ goto done;
+ }
+ }
+
/* If link is up put link down */
if (p->phy.link_info.link_info & ICE_AQ_LINK_UP) {
/* Tell the OS link is going down, the link will go
@@ -2292,12 +2406,15 @@ ice_set_link_ksettings(struct net_device *netdev,
}
/* make the aq call */
- status = ice_aq_set_phy_cfg(&pf->hw, lport, &config, NULL);
+ status = ice_aq_set_phy_cfg(&pf->hw, p, &config, NULL);
if (status) {
netdev_info(netdev, "Set phy config failed,\n");
err = -EAGAIN;
+ goto done;
}
+ /* Save speed request */
+ p->phy.curr_user_speed_req = adv_link_speed;
done:
kfree(abilities);
clear_bit(__ICE_CFG_BUSY, pf->state);
@@ -2874,8 +2991,8 @@ ice_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
if (status)
goto out;
- pause->autoneg = ((pcaps->caps & ICE_AQC_PHY_AN_MODE) ?
- AUTONEG_ENABLE : AUTONEG_DISABLE);
+ pause->autoneg = ice_is_phy_caps_an_enabled(pcaps) ? AUTONEG_ENABLE :
+ AUTONEG_DISABLE;
if (dcbx_cfg->pfc.pfcena)
/* PFC enabled so report LFC as off */
@@ -2943,8 +3060,8 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
return -EIO;
}
- is_an = ((pcaps->caps & ICE_AQC_PHY_AN_MODE) ?
- AUTONEG_ENABLE : AUTONEG_DISABLE);
+ is_an = ice_is_phy_caps_an_enabled(pcaps) ? AUTONEG_ENABLE :
+ AUTONEG_DISABLE;
kfree(pcaps);
@@ -3323,6 +3440,58 @@ static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch)
return 0;
}
+/**
+ * ice_get_wol - get current Wake on LAN configuration
+ * @netdev: network interface device structure
+ * @wol: Ethtool structure to retrieve WoL settings
+ */
+static void ice_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct ice_netdev_priv *np = netdev_priv(netdev);
+ struct ice_pf *pf = np->vsi->back;
+
+ if (np->vsi->type != ICE_VSI_PF)
+ netdev_warn(netdev, "Wake on LAN is not supported on this interface!\n");
+
+ /* Get WoL settings based on the HW capability */
+ if (ice_is_wol_supported(pf)) {
+ wol->supported = WAKE_MAGIC;
+ wol->wolopts = pf->wol_ena ? WAKE_MAGIC : 0;
+ } else {
+ wol->supported = 0;
+ wol->wolopts = 0;
+ }
+}
+
+/**
+ * ice_set_wol - set Wake on LAN on supported device
+ * @netdev: network interface device structure
+ * @wol: Ethtool structure to set WoL
+ */
+static int ice_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct ice_netdev_priv *np = netdev_priv(netdev);
+ struct ice_vsi *vsi = np->vsi;
+ struct ice_pf *pf = vsi->back;
+
+ if (vsi->type != ICE_VSI_PF || !ice_is_wol_supported(pf))
+ return -EOPNOTSUPP;
+
+ /* only magic packet is supported */
+ if (wol->wolopts && wol->wolopts != WAKE_MAGIC)
+ return -EOPNOTSUPP;
+
+ /* Set WoL only if there is a new value */
+ if (pf->wol_ena != !!wol->wolopts) {
+ pf->wol_ena = !!wol->wolopts;
+ device_set_wakeup_enable(ice_pf_to_dev(pf), pf->wol_ena);
+ netdev_dbg(netdev, "WoL magic packet %sabled\n",
+ pf->wol_ena ? "en" : "dis");
+ }
+
+ return 0;
+}
+
enum ice_container_type {
ICE_RX_CONTAINER,
ICE_TX_CONTAINER,
@@ -3806,6 +3975,8 @@ static const struct ethtool_ops ice_ethtool_ops = {
.get_drvinfo = ice_get_drvinfo,
.get_regs_len = ice_get_regs_len,
.get_regs = ice_get_regs,
+ .get_wol = ice_get_wol,
+ .set_wol = ice_set_wol,
.get_msglevel = ice_get_msglevel,
.set_msglevel = ice_set_msglevel,
.self_test = ice_self_test,
@@ -3848,6 +4019,8 @@ static const struct ethtool_ops ice_ethtool_safe_mode_ops = {
.get_drvinfo = ice_get_drvinfo,
.get_regs_len = ice_get_regs_len,
.get_regs = ice_get_regs,
+ .get_wol = ice_get_wol,
+ .set_wol = ice_set_wol,
.get_msglevel = ice_get_msglevel,
.set_msglevel = ice_set_msglevel,
.get_link = ethtool_op_get_link,
diff --git a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
index 4420fc02f7e7..b17ae3e20157 100644
--- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
+++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
@@ -644,7 +644,7 @@ static bool ice_bits_max_set(const u8 *mask, u16 size, u16 max)
* This function generates a key from a value, a don't care mask and a never
* match mask.
* upd, dc, and nm are optional parameters, and can be NULL:
- * upd == NULL --> udp mask is all 1's (update all bits)
+ * upd == NULL --> upd mask is all 1's (update all bits)
* dc == NULL --> dc mask is all 0's (no don't care bits)
* nm == NULL --> nm mask is all 0's (no never match bits)
*/
@@ -1121,8 +1121,7 @@ static enum ice_status ice_get_pkg_info(struct ice_hw *hw)
u16 size;
u32 i;
- size = sizeof(*pkg_info) + (sizeof(pkg_info->pkg_info[0]) *
- (ICE_PKG_CNT - 1));
+ size = struct_size(pkg_info, pkg_info, ICE_PKG_CNT);
pkg_info = kzalloc(size, GFP_KERNEL);
if (!pkg_info)
return ICE_ERR_NO_MEMORY;
@@ -1180,7 +1179,7 @@ static enum ice_status ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
u32 seg_count;
u32 i;
- if (len < sizeof(*pkg))
+ if (len < struct_size(pkg, seg_offset, 1))
return ICE_ERR_BUF_TOO_SHORT;
if (pkg->pkg_format_ver.major != ICE_PKG_FMT_VER_MAJ ||
@@ -1195,7 +1194,7 @@ static enum ice_status ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
return ICE_ERR_CFG;
/* make sure segment array fits in package length */
- if (len < sizeof(*pkg) + ((seg_count - 1) * sizeof(pkg->seg_offset)))
+ if (len < struct_size(pkg, seg_offset, seg_count))
return ICE_ERR_BUF_TOO_SHORT;
/* all segments must fit within length */
@@ -1300,7 +1299,7 @@ ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,
}
/* Check if FW is compatible with the OS package */
- size = struct_size(pkg, pkg_info, ICE_PKG_CNT - 1);
+ size = struct_size(pkg, pkg_info, ICE_PKG_CNT);
pkg = kzalloc(size, GFP_KERNEL);
if (!pkg)
return ICE_ERR_NO_MEMORY;
@@ -1764,13 +1763,13 @@ ice_create_tunnel(struct ice_hw *hw, enum ice_tunnel_type type, u16 port)
goto ice_create_tunnel_err;
sect_rx = ice_pkg_buf_alloc_section(bld, ICE_SID_RXPARSER_BOOST_TCAM,
- sizeof(*sect_rx));
+ struct_size(sect_rx, tcam, 1));
if (!sect_rx)
goto ice_create_tunnel_err;
sect_rx->count = cpu_to_le16(1);
sect_tx = ice_pkg_buf_alloc_section(bld, ICE_SID_TXPARSER_BOOST_TCAM,
- sizeof(*sect_tx));
+ struct_size(sect_tx, tcam, 1));
if (!sect_tx)
goto ice_create_tunnel_err;
sect_tx->count = cpu_to_le16(1);
@@ -1847,7 +1846,7 @@ enum ice_status ice_destroy_tunnel(struct ice_hw *hw, u16 port, bool all)
}
/* size of section - there is at least one entry */
- size = struct_size(sect_rx, tcam, count - 1);
+ size = struct_size(sect_rx, tcam, count);
bld = ice_pkg_buf_alloc(hw);
if (!bld) {
@@ -2922,6 +2921,8 @@ static void ice_free_flow_profs(struct ice_hw *hw, u8 blk_idx)
ICE_FLOW_ENTRY_HNDL(e));
list_del(&p->l_entry);
+
+ mutex_destroy(&p->entries_lock);
devm_kfree(ice_hw_to_dev(hw), p);
}
mutex_unlock(&hw->fl_profs_locks[blk_idx]);
@@ -3039,7 +3040,7 @@ void ice_clear_hw_tbls(struct ice_hw *hw)
memset(prof_redir->t, 0,
prof_redir->count * sizeof(*prof_redir->t));
- memset(es->t, 0, es->count * sizeof(*es->t));
+ memset(es->t, 0, es->count * sizeof(*es->t) * es->fvw);
memset(es->ref_count, 0, es->count * sizeof(*es->ref_count));
memset(es->written, 0, es->count * sizeof(*es->written));
}
@@ -3150,10 +3151,12 @@ enum ice_status ice_init_hw_tbls(struct ice_hw *hw)
es->ref_count = devm_kcalloc(ice_hw_to_dev(hw), es->count,
sizeof(*es->ref_count),
GFP_KERNEL);
+ if (!es->ref_count)
+ goto err;
es->written = devm_kcalloc(ice_hw_to_dev(hw), es->count,
sizeof(*es->written), GFP_KERNEL);
- if (!es->ref_count)
+ if (!es->written)
goto err;
}
return 0;
@@ -3324,10 +3327,10 @@ ice_prof_bld_es(struct ice_hw *hw, enum ice_block blk,
u32 id;
id = ice_sect_id(blk, ICE_VEC_TBL);
- p = (struct ice_pkg_es *)
- ice_pkg_buf_alloc_section(bld, id, sizeof(*p) +
- vec_size -
- sizeof(p->es[0]));
+ p = ice_pkg_buf_alloc_section(bld, id,
+ struct_size(p, es, 1) +
+ vec_size -
+ sizeof(p->es[0]));
if (!p)
return ICE_ERR_MAX_LIMIT;
@@ -3360,8 +3363,8 @@ ice_prof_bld_tcam(struct ice_hw *hw, enum ice_block blk,
u32 id;
id = ice_sect_id(blk, ICE_PROF_TCAM);
- p = (struct ice_prof_id_section *)
- ice_pkg_buf_alloc_section(bld, id, sizeof(*p));
+ p = ice_pkg_buf_alloc_section(bld, id,
+ struct_size(p, entry, 1));
if (!p)
return ICE_ERR_MAX_LIMIT;
@@ -3396,8 +3399,8 @@ ice_prof_bld_xlt1(enum ice_block blk, struct ice_buf_build *bld,
u32 id;
id = ice_sect_id(blk, ICE_XLT1);
- p = (struct ice_xlt1_section *)
- ice_pkg_buf_alloc_section(bld, id, sizeof(*p));
+ p = ice_pkg_buf_alloc_section(bld, id,
+ struct_size(p, value, 1));
if (!p)
return ICE_ERR_MAX_LIMIT;
@@ -3431,8 +3434,8 @@ ice_prof_bld_xlt2(enum ice_block blk, struct ice_buf_build *bld,
case ICE_VSI_MOVE:
case ICE_VSIG_REM:
id = ice_sect_id(blk, ICE_XLT2);
- p = (struct ice_xlt2_section *)
- ice_pkg_buf_alloc_section(bld, id, sizeof(*p));
+ p = ice_pkg_buf_alloc_section(bld, id,
+ struct_size(p, value, 1));
if (!p)
return ICE_ERR_MAX_LIMIT;
@@ -3875,16 +3878,16 @@ err_ice_add_prof:
}
/**
- * ice_search_prof_id_low - Search for a profile tracking ID low level
+ * ice_search_prof_id - Search for a profile tracking ID
* @hw: pointer to the HW struct
* @blk: hardware block
* @id: profile tracking ID
*
- * This will search for a profile tracking ID which was previously added. This
- * version assumes that the caller has already acquired the prof map lock.
+ * This will search for a profile tracking ID which was previously added.
+ * The profile map lock should be held before calling this function.
*/
static struct ice_prof_map *
-ice_search_prof_id_low(struct ice_hw *hw, enum ice_block blk, u64 id)
+ice_search_prof_id(struct ice_hw *hw, enum ice_block blk, u64 id)
{
struct ice_prof_map *entry = NULL;
struct ice_prof_map *map;
@@ -3899,26 +3902,6 @@ ice_search_prof_id_low(struct ice_hw *hw, enum ice_block blk, u64 id)
}
/**
- * ice_search_prof_id - Search for a profile tracking ID
- * @hw: pointer to the HW struct
- * @blk: hardware block
- * @id: profile tracking ID
- *
- * This will search for a profile tracking ID which was previously added.
- */
-static struct ice_prof_map *
-ice_search_prof_id(struct ice_hw *hw, enum ice_block blk, u64 id)
-{
- struct ice_prof_map *entry;
-
- mutex_lock(&hw->blk[blk].es.prof_map_lock);
- entry = ice_search_prof_id_low(hw, blk, id);
- mutex_unlock(&hw->blk[blk].es.prof_map_lock);
-
- return entry;
-}
-
-/**
* ice_vsig_prof_id_count - count profiles in a VSIG
* @hw: pointer to the HW struct
* @blk: hardware block
@@ -4134,7 +4117,7 @@ enum ice_status ice_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 id)
mutex_lock(&hw->blk[blk].es.prof_map_lock);
- pmap = ice_search_prof_id_low(hw, blk, id);
+ pmap = ice_search_prof_id(hw, blk, id);
if (!pmap) {
status = ICE_ERR_DOES_NOT_EXIST;
goto err_ice_rem_prof;
@@ -4167,22 +4150,28 @@ static enum ice_status
ice_get_prof(struct ice_hw *hw, enum ice_block blk, u64 hdl,
struct list_head *chg)
{
+ enum ice_status status = 0;
struct ice_prof_map *map;
struct ice_chs_chg *p;
u16 i;
+ mutex_lock(&hw->blk[blk].es.prof_map_lock);
/* Get the details on the profile specified by the handle ID */
map = ice_search_prof_id(hw, blk, hdl);
- if (!map)
- return ICE_ERR_DOES_NOT_EXIST;
+ if (!map) {
+ status = ICE_ERR_DOES_NOT_EXIST;
+ goto err_ice_get_prof;
+ }
for (i = 0; i < map->ptg_cnt; i++)
if (!hw->blk[blk].es.written[map->prof_id]) {
/* add ES to change list */
p = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*p),
GFP_KERNEL);
- if (!p)
+ if (!p) {
+ status = ICE_ERR_NO_MEMORY;
goto err_ice_get_prof;
+ }
p->type = ICE_PTG_ES_ADD;
p->ptype = 0;
@@ -4197,11 +4186,10 @@ ice_get_prof(struct ice_hw *hw, enum ice_block blk, u64 hdl,
list_add(&p->list_entry, chg);
}
- return 0;
-
err_ice_get_prof:
+ mutex_unlock(&hw->blk[blk].es.prof_map_lock);
/* let caller clean up the change list */
- return ICE_ERR_NO_MEMORY;
+ return status;
}
/**
@@ -4255,17 +4243,23 @@ static enum ice_status
ice_add_prof_to_lst(struct ice_hw *hw, enum ice_block blk,
struct list_head *lst, u64 hdl)
{
+ enum ice_status status = 0;
struct ice_prof_map *map;
struct ice_vsig_prof *p;
u16 i;
+ mutex_lock(&hw->blk[blk].es.prof_map_lock);
map = ice_search_prof_id(hw, blk, hdl);
- if (!map)
- return ICE_ERR_DOES_NOT_EXIST;
+ if (!map) {
+ status = ICE_ERR_DOES_NOT_EXIST;
+ goto err_ice_add_prof_to_lst;
+ }
p = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*p), GFP_KERNEL);
- if (!p)
- return ICE_ERR_NO_MEMORY;
+ if (!p) {
+ status = ICE_ERR_NO_MEMORY;
+ goto err_ice_add_prof_to_lst;
+ }
p->profile_cookie = map->profile_cookie;
p->prof_id = map->prof_id;
@@ -4279,7 +4273,9 @@ ice_add_prof_to_lst(struct ice_hw *hw, enum ice_block blk,
list_add(&p->list, lst);
- return 0;
+err_ice_add_prof_to_lst:
+ mutex_unlock(&hw->blk[blk].es.prof_map_lock);
+ return status;
}
/**
@@ -4497,16 +4493,12 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0x00, 0x00, 0x00 };
u8 nm_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
+ enum ice_status status = 0;
struct ice_prof_map *map;
struct ice_vsig_prof *t;
struct ice_chs_chg *p;
u16 vsig_idx, i;
- /* Get the details on the profile specified by the handle ID */
- map = ice_search_prof_id(hw, blk, hdl);
- if (!map)
- return ICE_ERR_DOES_NOT_EXIST;
-
/* Error, if this VSIG already has this profile */
if (ice_has_prof_vsig(hw, blk, vsig, hdl))
return ICE_ERR_ALREADY_EXISTS;
@@ -4516,19 +4508,28 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
if (!t)
return ICE_ERR_NO_MEMORY;
+ mutex_lock(&hw->blk[blk].es.prof_map_lock);
+ /* Get the details on the profile specified by the handle ID */
+ map = ice_search_prof_id(hw, blk, hdl);
+ if (!map) {
+ status = ICE_ERR_DOES_NOT_EXIST;
+ goto err_ice_add_prof_id_vsig;
+ }
+
t->profile_cookie = map->profile_cookie;
t->prof_id = map->prof_id;
t->tcam_count = map->ptg_cnt;
/* create TCAM entries */
for (i = 0; i < map->ptg_cnt; i++) {
- enum ice_status status;
u16 tcam_idx;
/* add TCAM to change list */
p = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*p), GFP_KERNEL);
- if (!p)
+ if (!p) {
+ status = ICE_ERR_NO_MEMORY;
goto err_ice_add_prof_id_vsig;
+ }
/* allocate the TCAM entry index */
status = ice_alloc_tcam_ent(hw, blk, &tcam_idx);
@@ -4572,12 +4573,14 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
list_add(&t->list,
&hw->blk[blk].xlt2.vsig_tbl[vsig_idx].prop_lst);
- return 0;
+ mutex_unlock(&hw->blk[blk].es.prof_map_lock);
+ return status;
err_ice_add_prof_id_vsig:
+ mutex_unlock(&hw->blk[blk].es.prof_map_lock);
/* let caller clean up the change list */
devm_kfree(ice_hw_to_dev(hw), t);
- return ICE_ERR_NO_MEMORY;
+ return status;
}
/**
diff --git a/drivers/net/ethernet/intel/ice/ice_flex_type.h b/drivers/net/ethernet/intel/ice/ice_flex_type.h
index a6f391eac8ff..c1c99a267a98 100644
--- a/drivers/net/ethernet/intel/ice/ice_flex_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_flex_type.h
@@ -22,7 +22,7 @@ struct ice_fv {
struct ice_pkg_hdr {
struct ice_pkg_ver pkg_format_ver;
__le32 seg_count;
- __le32 seg_offset[1];
+ __le32 seg_offset[];
};
/* generic segment */
@@ -53,12 +53,12 @@ struct ice_device_id_entry {
struct ice_seg {
struct ice_generic_seg_hdr hdr;
__le32 device_table_count;
- struct ice_device_id_entry device_table[1];
+ struct ice_device_id_entry device_table[];
};
struct ice_nvm_table {
__le32 table_count;
- __le32 vers[1];
+ __le32 vers[];
};
struct ice_buf {
@@ -68,7 +68,7 @@ struct ice_buf {
struct ice_buf_table {
__le32 buf_count;
- struct ice_buf buf_array[1];
+ struct ice_buf buf_array[];
};
/* global metadata specific segment */
@@ -101,11 +101,12 @@ struct ice_section_entry {
struct ice_buf_hdr {
__le16 section_count;
__le16 data_end;
- struct ice_section_entry section_entry[1];
+ struct ice_section_entry section_entry[];
};
#define ICE_MAX_ENTRIES_IN_BUF(hd_sz, ent_sz) ((ICE_PKG_BUF_SIZE - \
- sizeof(struct ice_buf_hdr) - (hd_sz)) / (ent_sz))
+ struct_size((struct ice_buf_hdr *)0, section_entry, 1) - (hd_sz)) /\
+ (ent_sz))
/* ice package section IDs */
#define ICE_SID_XLT0_SW 10
@@ -198,17 +199,17 @@ struct ice_label {
struct ice_label_section {
__le16 count;
- struct ice_label label[1];
+ struct ice_label label[];
};
#define ICE_MAX_LABELS_IN_BUF ICE_MAX_ENTRIES_IN_BUF( \
- sizeof(struct ice_label_section) - sizeof(struct ice_label), \
- sizeof(struct ice_label))
+ struct_size((struct ice_label_section *)0, label, 1) - \
+ sizeof(struct ice_label), sizeof(struct ice_label))
struct ice_sw_fv_section {
__le16 count;
__le16 base_offset;
- struct ice_fv fv[1];
+ struct ice_fv fv[];
};
/* The BOOST TCAM stores the match packet header in reverse order, meaning
@@ -245,30 +246,30 @@ struct ice_boost_tcam_entry {
struct ice_boost_tcam_section {
__le16 count;
__le16 reserved;
- struct ice_boost_tcam_entry tcam[1];
+ struct ice_boost_tcam_entry tcam[];
};
#define ICE_MAX_BST_TCAMS_IN_BUF ICE_MAX_ENTRIES_IN_BUF( \
- sizeof(struct ice_boost_tcam_section) - \
+ struct_size((struct ice_boost_tcam_section *)0, tcam, 1) - \
sizeof(struct ice_boost_tcam_entry), \
sizeof(struct ice_boost_tcam_entry))
struct ice_xlt1_section {
__le16 count;
__le16 offset;
- u8 value[1];
-} __packed;
+ u8 value[];
+};
struct ice_xlt2_section {
__le16 count;
__le16 offset;
- __le16 value[1];
+ __le16 value[];
};
struct ice_prof_redir_section {
__le16 count;
__le16 offset;
- u8 redir_value[1];
+ u8 redir_value[];
};
/* package buffer building */
@@ -327,7 +328,7 @@ struct ice_tunnel_table {
struct ice_pkg_es {
__le16 count;
__le16 offset;
- struct ice_fv_word es[1];
+ struct ice_fv_word es[];
};
struct ice_es {
@@ -461,8 +462,8 @@ struct ice_prof_tcam_entry {
struct ice_prof_id_section {
__le16 count;
- struct ice_prof_tcam_entry entry[1];
-} __packed;
+ struct ice_prof_tcam_entry entry[];
+};
struct ice_prof_tcam {
u32 sid;
diff --git a/drivers/net/ethernet/intel/ice/ice_flow.c b/drivers/net/ethernet/intel/ice/ice_flow.c
index d74e5290677f..fe677621dd51 100644
--- a/drivers/net/ethernet/intel/ice/ice_flow.c
+++ b/drivers/net/ethernet/intel/ice/ice_flow.c
@@ -1187,7 +1187,7 @@ enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
if (list_empty(&hw->fl_profs[blk]))
return 0;
- mutex_lock(&hw->fl_profs_locks[blk]);
+ mutex_lock(&hw->rss_locks);
list_for_each_entry_safe(p, t, &hw->fl_profs[blk], l_entry)
if (test_bit(vsi_handle, p->vsis)) {
status = ice_flow_disassoc_prof(hw, blk, p, vsi_handle);
@@ -1195,12 +1195,12 @@ enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
break;
if (bitmap_empty(p->vsis, ICE_MAX_VSI)) {
- status = ice_flow_rem_prof_sync(hw, blk, p);
+ status = ice_flow_rem_prof(hw, blk, p->id);
if (status)
break;
}
}
- mutex_unlock(&hw->fl_profs_locks[blk]);
+ mutex_unlock(&hw->rss_locks);
return status;
}
@@ -1597,7 +1597,8 @@ enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle)
*/
u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
{
- struct ice_rss_cfg *r, *rss_cfg = NULL;
+ u64 rss_hash = ICE_HASH_INVALID;
+ struct ice_rss_cfg *r;
/* verify if the protocol header is non zero and VSI is valid */
if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle))
@@ -1607,10 +1608,10 @@ u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs)
list_for_each_entry(r, &hw->rss_list_head, l_entry)
if (test_bit(vsi_handle, r->vsis) &&
r->packet_hdr == hdrs) {
- rss_cfg = r;
+ rss_hash = r->hashed_flds;
break;
}
mutex_unlock(&hw->rss_locks);
- return rss_cfg ? rss_cfg->hashed_flds : ICE_HASH_INVALID;
+ return rss_hash;
}
diff --git a/drivers/net/ethernet/intel/ice/ice_fw_update.c b/drivers/net/ethernet/intel/ice/ice_fw_update.c
new file mode 100644
index 000000000000..deaefe00c9c0
--- /dev/null
+++ b/drivers/net/ethernet/intel/ice/ice_fw_update.c
@@ -0,0 +1,773 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2018-2019, Intel Corporation. */
+
+#include <asm/unaligned.h>
+#include <linux/uuid.h>
+#include <linux/crc32.h>
+#include <linux/pldmfw.h>
+#include "ice.h"
+#include "ice_fw_update.h"
+
+struct ice_fwu_priv {
+ struct pldmfw context;
+
+ struct ice_pf *pf;
+ struct netlink_ext_ack *extack;
+
+ /* Track which NVM banks to activate at the end of the update */
+ u8 activate_flags;
+};
+
+/**
+ * ice_send_package_data - Send record package data to firmware
+ * @context: PLDM fw update structure
+ * @data: pointer to the package data
+ * @length: length of the package data
+ *
+ * Send a copy of the package data associated with the PLDM record matching
+ * this device to the firmware.
+ *
+ * Note that this function sends an AdminQ command that will fail unless the
+ * NVM resource has been acquired.
+ *
+ * Returns: zero on success, or a negative error code on failure.
+ */
+static int
+ice_send_package_data(struct pldmfw *context, const u8 *data, u16 length)
+{
+ struct ice_fwu_priv *priv = container_of(context, struct ice_fwu_priv, context);
+ struct netlink_ext_ack *extack = priv->extack;
+ struct device *dev = context->dev;
+ struct ice_pf *pf = priv->pf;
+ struct ice_hw *hw = &pf->hw;
+ enum ice_status status;
+ u8 *package_data;
+
+ package_data = kmemdup(data, length, GFP_KERNEL);
+ if (!package_data)
+ return -ENOMEM;
+
+ status = ice_nvm_set_pkg_data(hw, false, package_data, length, NULL);
+
+ kfree(package_data);
+
+ if (status) {
+ dev_err(dev, "Failed to send record package data to firmware, err %s aq_err %s\n",
+ ice_stat_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ NL_SET_ERR_MSG_MOD(extack, "Failed to record package data to firmware");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * ice_check_component_response - Report firmware response to a component
+ * @pf: device private data structure
+ * @id: component id being checked
+ * @response: indicates whether this component can be updated
+ * @code: code indicating reason for response
+ * @extack: netlink extended ACK structure
+ *
+ * Check whether firmware indicates if this component can be updated. Report
+ * a suitable error message over the netlink extended ACK if the component
+ * cannot be updated.
+ *
+ * Returns: zero if the component can be updated, or -ECANCELED of the
+ * firmware indicates the component cannot be updated.
+ */
+static int
+ice_check_component_response(struct ice_pf *pf, u16 id, u8 response, u8 code,
+ struct netlink_ext_ack *extack)
+{
+ struct device *dev = ice_pf_to_dev(pf);
+ const char *component;
+
+ switch (id) {
+ case NVM_COMP_ID_OROM:
+ component = "fw.undi";
+ break;
+ case NVM_COMP_ID_NVM:
+ component = "fw.mgmt";
+ break;
+ case NVM_COMP_ID_NETLIST:
+ component = "fw.netlist";
+ break;
+ default:
+ WARN(1, "Unexpected unknown component identifier 0x%02x", id);
+ return -EINVAL;
+ }
+
+ dev_dbg(dev, "%s: firmware response 0x%x, code 0x%x\n",
+ component, response, code);
+
+ switch (response) {
+ case ICE_AQ_NVM_PASS_COMP_CAN_BE_UPDATED:
+ /* firmware indicated this update is good to proceed */
+ return 0;
+ case ICE_AQ_NVM_PASS_COMP_CAN_MAY_BE_UPDATEABLE:
+ dev_warn(dev, "firmware recommends not updating %s, as it may result in a downgrade. continuing anyways\n", component);
+ return 0;
+ case ICE_AQ_NVM_PASS_COMP_CAN_NOT_BE_UPDATED:
+ dev_info(dev, "firmware has rejected updating %s\n", component);
+ break;
+ }
+
+ switch (code) {
+ case ICE_AQ_NVM_PASS_COMP_STAMP_IDENTICAL_CODE:
+ dev_err(dev, "Component comparison stamp for %s is identical to the running image\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Component comparison stamp is identical to running image");
+ break;
+ case ICE_AQ_NVM_PASS_COMP_STAMP_LOWER:
+ dev_err(dev, "Component comparison stamp for %s is lower than the running image\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Component comparison stamp is lower than running image");
+ break;
+ case ICE_AQ_NVM_PASS_COMP_INVALID_STAMP_CODE:
+ dev_err(dev, "Component comparison stamp for %s is invalid\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Component comparison stamp is invalid");
+ break;
+ case ICE_AQ_NVM_PASS_COMP_CONFLICT_CODE:
+ dev_err(dev, "%s conflicts with a previous component table\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Component table conflict occurred");
+ break;
+ case ICE_AQ_NVM_PASS_COMP_PRE_REQ_NOT_MET_CODE:
+ dev_err(dev, "Pre-requisites for component %s have not been met\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Component pre-requisites not met");
+ break;
+ case ICE_AQ_NVM_PASS_COMP_NOT_SUPPORTED_CODE:
+ dev_err(dev, "%s is not a supported component\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Component not supported");
+ break;
+ case ICE_AQ_NVM_PASS_COMP_CANNOT_DOWNGRADE_CODE:
+ dev_err(dev, "Security restrictions prevent %s from being downgraded\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Component cannot be downgraded");
+ break;
+ case ICE_AQ_NVM_PASS_COMP_INCOMPLETE_IMAGE_CODE:
+ dev_err(dev, "Received an incomplete component image for %s\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Incomplete component image");
+ break;
+ case ICE_AQ_NVM_PASS_COMP_VER_STR_IDENTICAL_CODE:
+ dev_err(dev, "Component version for %s is identical to the running image\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Component version is identical to running image");
+ break;
+ case ICE_AQ_NVM_PASS_COMP_VER_STR_LOWER_CODE:
+ dev_err(dev, "Component version for %s is lower than the running image\n",
+ component);
+ NL_SET_ERR_MSG_MOD(extack, "Component version is lower than the running image");
+ break;
+ default:
+ dev_err(dev, "Unexpected response code 0x02%x for %s\n",
+ code, component);
+ NL_SET_ERR_MSG_MOD(extack, "Received unexpected response code from firmware");
+ break;
+ }
+
+ return -ECANCELED;
+}
+
+/**
+ * ice_send_component_table - Send PLDM component table to firmware
+ * @context: PLDM fw update structure
+ * @component: the component to process
+ * @transfer_flag: relative transfer order of this component
+ *
+ * Read relevant data from the component and forward it to the device
+ * firmware. Check the response to determine if the firmware indicates that
+ * the update can proceed.
+ *
+ * This function sends AdminQ commands related to the NVM, and assumes that
+ * the NVM resource has been acquired.
+ *
+ * Returns: zero on success, or a negative error code on failure.
+ */
+static int
+ice_send_component_table(struct pldmfw *context, struct pldmfw_component *component,
+ u8 transfer_flag)
+{
+ struct ice_fwu_priv *priv = container_of(context, struct ice_fwu_priv, context);
+ struct netlink_ext_ack *extack = priv->extack;
+ struct ice_aqc_nvm_comp_tbl *comp_tbl;
+ u8 comp_response, comp_response_code;
+ struct device *dev = context->dev;
+ struct ice_pf *pf = priv->pf;
+ struct ice_hw *hw = &pf->hw;
+ enum ice_status status;
+ size_t length;
+
+ switch (component->identifier) {
+ case NVM_COMP_ID_OROM:
+ case NVM_COMP_ID_NVM:
+ case NVM_COMP_ID_NETLIST:
+ break;
+ default:
+ dev_err(dev, "Unable to update due to a firmware component with unknown ID %u\n",
+ component->identifier);
+ NL_SET_ERR_MSG_MOD(extack, "Unable to update due to unknown firmware component");
+ return -EOPNOTSUPP;
+ }
+
+ length = struct_size(comp_tbl, cvs, component->version_len);
+ comp_tbl = kzalloc(length, GFP_KERNEL);
+ if (!comp_tbl)
+ return -ENOMEM;
+
+ comp_tbl->comp_class = cpu_to_le16(component->classification);
+ comp_tbl->comp_id = cpu_to_le16(component->identifier);
+ comp_tbl->comp_class_idx = FWU_COMP_CLASS_IDX_NOT_USE;
+ comp_tbl->comp_cmp_stamp = cpu_to_le32(component->comparison_stamp);
+ comp_tbl->cvs_type = component->version_type;
+ comp_tbl->cvs_len = component->version_len;
+ memcpy(comp_tbl->cvs, component->version_string, component->version_len);
+
+ status = ice_nvm_pass_component_tbl(hw, (u8 *)comp_tbl, length,
+ transfer_flag, &comp_response,
+ &comp_response_code, NULL);
+
+ kfree(comp_tbl);
+
+ if (status) {
+ dev_err(dev, "Failed to transfer component table to firmware, err %s aq_err %s\n",
+ ice_stat_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ NL_SET_ERR_MSG_MOD(extack, "Failed to transfer component table to firmware");
+ return -EIO;
+ }
+
+ return ice_check_component_response(pf, component->identifier, comp_response,
+ comp_response_code, extack);
+}
+
+/**
+ * ice_write_one_nvm_block - Write an NVM block and await completion response
+ * @pf: the PF data structure
+ * @module: the module to write to
+ * @offset: offset in bytes
+ * @block_size: size of the block to write, up to 4k
+ * @block: pointer to block of data to write
+ * @last_cmd: whether this is the last command
+ * @extack: netlink extended ACK structure
+ *
+ * Write a block of data to a flash module, and await for the completion
+ * response message from firmware.
+ *
+ * Note this function assumes the caller has acquired the NVM resource.
+ *
+ * Returns: zero on success, or a negative error code on failure.
+ */
+static int
+ice_write_one_nvm_block(struct ice_pf *pf, u16 module, u32 offset,
+ u16 block_size, u8 *block, bool last_cmd,
+ struct netlink_ext_ack *extack)
+{
+ u16 completion_module, completion_retval;
+ struct device *dev = ice_pf_to_dev(pf);
+ struct ice_rq_event_info event;
+ struct ice_hw *hw = &pf->hw;
+ enum ice_status status;
+ u32 completion_offset;
+ int err;
+
+ memset(&event, 0, sizeof(event));
+
+ status = ice_aq_update_nvm(hw, module, offset, block_size, block,
+ last_cmd, 0, NULL);
+ if (status) {
+ dev_err(dev, "Failed to program flash module 0x%02x at offset %u, err %s aq_err %s\n",
+ module, offset, ice_stat_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ NL_SET_ERR_MSG_MOD(extack, "Failed to program flash module");
+ return -EIO;
+ }
+
+ err = ice_aq_wait_for_event(pf, ice_aqc_opc_nvm_write, HZ, &event);
+ if (err) {
+ dev_err(dev, "Timed out waiting for firmware write completion for module 0x%02x, err %d\n",
+ module, err);
+ NL_SET_ERR_MSG_MOD(extack, "Timed out waiting for firmware");
+ return -EIO;
+ }
+
+ completion_module = le16_to_cpu(event.desc.params.nvm.module_typeid);
+ completion_retval = le16_to_cpu(event.desc.retval);
+
+ completion_offset = le16_to_cpu(event.desc.params.nvm.offset_low);
+ completion_offset |= event.desc.params.nvm.offset_high << 16;
+
+ if (completion_module != module) {
+ dev_err(dev, "Unexpected module_typeid in write completion: got 0x%x, expected 0x%x\n",
+ completion_module, module);
+ NL_SET_ERR_MSG_MOD(extack, "Unexpected firmware response");
+ return -EIO;
+ }
+
+ if (completion_offset != offset) {
+ dev_err(dev, "Unexpected offset in write completion: got %u, expected %u\n",
+ completion_offset, offset);
+ NL_SET_ERR_MSG_MOD(extack, "Unexpected firmware response");
+ return -EIO;
+ }
+
+ if (completion_retval) {
+ dev_err(dev, "Firmware failed to program flash module 0x%02x at offset %u, completion err %s\n",
+ module, offset,
+ ice_aq_str((enum ice_aq_err)completion_retval));
+ NL_SET_ERR_MSG_MOD(extack, "Firmware failed to program flash module");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * ice_write_nvm_module - Write data to an NVM module
+ * @pf: the PF driver structure
+ * @module: the module id to program
+ * @component: the name of the component being updated
+ * @image: buffer of image data to write to the NVM
+ * @length: length of the buffer
+ * @extack: netlink extended ACK structure
+ *
+ * Loop over the data for a given NVM module and program it in 4 Kb
+ * blocks. Notify devlink core of progress after each block is programmed.
+ * Loops over a block of data and programs the NVM in 4k block chunks.
+ *
+ * Note this function assumes the caller has acquired the NVM resource.
+ *
+ * Returns: zero on success, or a negative error code on failure.
+ */
+static int
+ice_write_nvm_module(struct ice_pf *pf, u16 module, const char *component,
+ const u8 *image, u32 length,
+ struct netlink_ext_ack *extack)
+{
+ struct devlink *devlink;
+ u32 offset = 0;
+ bool last_cmd;
+ u8 *block;
+ int err;
+
+ devlink = priv_to_devlink(pf);
+
+ devlink_flash_update_status_notify(devlink, "Flashing",
+ component, 0, length);
+
+ block = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
+ if (!block)
+ return -ENOMEM;
+
+ do {
+ u32 block_size;
+
+ block_size = min_t(u32, ICE_AQ_MAX_BUF_LEN, length - offset);
+ last_cmd = !(offset + block_size < length);
+
+ /* ice_aq_update_nvm may copy the firmware response into the
+ * buffer, so we must make a copy since the source data is
+ * constant.
+ */
+ memcpy(block, image + offset, block_size);
+
+ err = ice_write_one_nvm_block(pf, module, offset, block_size,
+ block, last_cmd, extack);
+ if (err)
+ break;
+
+ offset += block_size;
+
+ devlink_flash_update_status_notify(devlink, "Flashing",
+ component, offset, length);
+ } while (!last_cmd);
+
+ if (err)
+ devlink_flash_update_status_notify(devlink, "Flashing failed",
+ component, length, length);
+ else
+ devlink_flash_update_status_notify(devlink, "Flashing done",
+ component, length, length);
+
+ kfree(block);
+ return err;
+}
+
+/**
+ * ice_erase_nvm_module - Erase an NVM module and await firmware completion
+ * @pf: the PF data structure
+ * @module: the module to erase
+ * @component: name of the component being updated
+ * @extack: netlink extended ACK structure
+ *
+ * Erase the inactive NVM bank associated with this module, and await for
+ * a completion response message from firmware.
+ *
+ * Note this function assumes the caller has acquired the NVM resource.
+ *
+ * Returns: zero on success, or a negative error code on failure.
+ */
+static int
+ice_erase_nvm_module(struct ice_pf *pf, u16 module, const char *component,
+ struct netlink_ext_ack *extack)
+{
+ u16 completion_module, completion_retval;
+ struct device *dev = ice_pf_to_dev(pf);
+ struct ice_rq_event_info event;
+ struct ice_hw *hw = &pf->hw;
+ struct devlink *devlink;
+ enum ice_status status;
+ int err;
+
+ memset(&event, 0, sizeof(event));
+
+ devlink = priv_to_devlink(pf);
+
+ devlink_flash_update_status_notify(devlink, "Erasing", component, 0, 0);
+
+ status = ice_aq_erase_nvm(hw, module, NULL);
+ if (status) {
+ dev_err(dev, "Failed to erase %s (module 0x%02x), err %s aq_err %s\n",
+ component, module, ice_stat_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ NL_SET_ERR_MSG_MOD(extack, "Failed to erase flash module");
+ err = -EIO;
+ goto out_notify_devlink;
+ }
+
+ /* Yes, this really can take minutes to complete */
+ err = ice_aq_wait_for_event(pf, ice_aqc_opc_nvm_erase, 300 * HZ, &event);
+ if (err) {
+ dev_err(dev, "Timed out waiting for firmware to respond with erase completion for %s (module 0x%02x), err %d\n",
+ component, module, err);
+ NL_SET_ERR_MSG_MOD(extack, "Timed out waiting for firmware");
+ goto out_notify_devlink;
+ }
+
+ completion_module = le16_to_cpu(event.desc.params.nvm.module_typeid);
+ completion_retval = le16_to_cpu(event.desc.retval);
+
+ if (completion_module != module) {
+ dev_err(dev, "Unexpected module_typeid in erase completion for %s: got 0x%x, expected 0x%x\n",
+ component, completion_module, module);
+ NL_SET_ERR_MSG_MOD(extack, "Unexpected firmware response");
+ err = -EIO;
+ goto out_notify_devlink;
+ }
+
+ if (completion_retval) {
+ dev_err(dev, "Firmware failed to erase %s (module 0x02%x), aq_err %s\n",
+ component, module,
+ ice_aq_str((enum ice_aq_err)completion_retval));
+ NL_SET_ERR_MSG_MOD(extack, "Firmware failed to erase flash");
+ err = -EIO;
+ goto out_notify_devlink;
+ }
+
+out_notify_devlink:
+ if (err)
+ devlink_flash_update_status_notify(devlink, "Erasing failed",
+ component, 0, 0);
+ else
+ devlink_flash_update_status_notify(devlink, "Erasing done",
+ component, 0, 0);
+
+ return err;
+}
+
+/**
+ * ice_switch_flash_banks - Tell firmware to switch NVM banks
+ * @pf: Pointer to the PF data structure
+ * @activate_flags: flags used for the activation command
+ * @extack: netlink extended ACK structure
+ *
+ * Notify firmware to activate the newly written flash banks, and wait for the
+ * firmware response.
+ *
+ * Returns: zero on success or an error code on failure.
+ */
+static int ice_switch_flash_banks(struct ice_pf *pf, u8 activate_flags,
+ struct netlink_ext_ack *extack)
+{
+ struct device *dev = ice_pf_to_dev(pf);
+ struct ice_rq_event_info event;
+ struct ice_hw *hw = &pf->hw;
+ enum ice_status status;
+ u16 completion_retval;
+ int err;
+
+ memset(&event, 0, sizeof(event));
+
+ status = ice_nvm_write_activate(hw, activate_flags);
+ if (status) {
+ dev_err(dev, "Failed to switch active flash banks, err %s aq_err %s\n",
+ ice_stat_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ NL_SET_ERR_MSG_MOD(extack, "Failed to switch active flash banks");
+ return -EIO;
+ }
+
+ err = ice_aq_wait_for_event(pf, ice_aqc_opc_nvm_write_activate, HZ,
+ &event);
+ if (err) {
+ dev_err(dev, "Timed out waiting for firmware to switch active flash banks, err %d\n",
+ err);
+ NL_SET_ERR_MSG_MOD(extack, "Timed out waiting for firmware");
+ return err;
+ }
+
+ completion_retval = le16_to_cpu(event.desc.retval);
+ if (completion_retval) {
+ dev_err(dev, "Firmware failed to switch active flash banks aq_err %s\n",
+ ice_aq_str((enum ice_aq_err)completion_retval));
+ NL_SET_ERR_MSG_MOD(extack, "Firmware failed to switch active flash banks");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * ice_flash_component - Flash a component of the NVM
+ * @context: PLDM fw update structure
+ * @component: the component table to program
+ *
+ * Program the flash contents for a given component. First, determine the
+ * module id. Then, erase the secondary bank for this module. Finally, write
+ * the contents of the component to the NVM.
+ *
+ * Note this function assumes the caller has acquired the NVM resource.
+ *
+ * Returns: zero on success, or a negative error code on failure.
+ */
+static int
+ice_flash_component(struct pldmfw *context, struct pldmfw_component *component)
+{
+ struct ice_fwu_priv *priv = container_of(context, struct ice_fwu_priv, context);
+ struct netlink_ext_ack *extack = priv->extack;
+ struct ice_pf *pf = priv->pf;
+ const char *name;
+ u16 module;
+ u8 flag;
+ int err;
+
+ switch (component->identifier) {
+ case NVM_COMP_ID_OROM:
+ module = ICE_SR_1ST_OROM_BANK_PTR;
+ flag = ICE_AQC_NVM_ACTIV_SEL_OROM;
+ name = "fw.undi";
+ break;
+ case NVM_COMP_ID_NVM:
+ module = ICE_SR_1ST_NVM_BANK_PTR;
+ flag = ICE_AQC_NVM_ACTIV_SEL_NVM;
+ name = "fw.mgmt";
+ break;
+ case NVM_COMP_ID_NETLIST:
+ module = ICE_SR_NETLIST_BANK_PTR;
+ flag = ICE_AQC_NVM_ACTIV_SEL_NETLIST;
+ name = "fw.netlist";
+ break;
+ default:
+ /* This should not trigger, since we check the id before
+ * sending the component table to firmware.
+ */
+ WARN(1, "Unexpected unknown component identifier 0x%02x",
+ component->identifier);
+ return -EINVAL;
+ }
+
+ /* Mark this component for activating at the end */
+ priv->activate_flags |= flag;
+
+ err = ice_erase_nvm_module(pf, module, name, extack);
+ if (err)
+ return err;
+
+ return ice_write_nvm_module(pf, module, name, component->component_data,
+ component->component_size, extack);
+}
+
+/**
+ * ice_finalize_update - Perform last steps to complete device update
+ * @context: PLDM fw update structure
+ *
+ * Called as the last step of the update process. Complete the update by
+ * telling the firmware to switch active banks, and perform a reset of
+ * configured.
+ *
+ * Returns: 0 on success, or an error code on failure.
+ */
+static int ice_finalize_update(struct pldmfw *context)
+{
+ struct ice_fwu_priv *priv = container_of(context, struct ice_fwu_priv, context);
+ struct netlink_ext_ack *extack = priv->extack;
+ struct ice_pf *pf = priv->pf;
+ int err;
+
+ /* Finally, notify firmware to activate the written NVM banks */
+ err = ice_switch_flash_banks(pf, priv->activate_flags, extack);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static const struct pldmfw_ops ice_fwu_ops = {
+ .match_record = &pldmfw_op_pci_match_record,
+ .send_package_data = &ice_send_package_data,
+ .send_component_table = &ice_send_component_table,
+ .flash_component = &ice_flash_component,
+ .finalize_update = &ice_finalize_update,
+};
+
+/**
+ * ice_flash_pldm_image - Write a PLDM-formatted firmware image to the device
+ * @pf: private device driver structure
+ * @fw: firmware object pointing to the relevant firmware file
+ * @extack: netlink extended ACK structure
+ *
+ * Parse the data for a given firmware file, verifying that it is a valid PLDM
+ * formatted image that matches this device.
+ *
+ * Extract the device record Package Data and Component Tables and send them
+ * to the firmware. Extract and write the flash data for each of the three
+ * main flash components, "fw.mgmt", "fw.undi", and "fw.netlist". Notify
+ * firmware once the data is written to the inactive banks.
+ *
+ * Returns: zero on success or a negative error code on failure.
+ */
+int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw,
+ struct netlink_ext_ack *extack)
+{
+ struct device *dev = ice_pf_to_dev(pf);
+ struct ice_hw *hw = &pf->hw;
+ struct ice_fwu_priv priv;
+ enum ice_status status;
+ int err;
+
+ memset(&priv, 0, sizeof(priv));
+
+ priv.context.ops = &ice_fwu_ops;
+ priv.context.dev = dev;
+ priv.extack = extack;
+ priv.pf = pf;
+ priv.activate_flags = ICE_AQC_NVM_PRESERVE_ALL;
+
+ status = ice_acquire_nvm(hw, ICE_RES_WRITE);
+ if (status) {
+ dev_err(dev, "Failed to acquire device flash lock, err %s aq_err %s\n",
+ ice_stat_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ NL_SET_ERR_MSG_MOD(extack, "Failed to acquire device flash lock");
+ return -EIO;
+ }
+
+ err = pldmfw_flash_image(&priv.context, fw);
+
+ ice_release_nvm(hw);
+
+ return err;
+}
+
+/**
+ * ice_check_for_pending_update - Check for a pending flash update
+ * @pf: the PF driver structure
+ * @component: if not NULL, the name of the component being updated
+ * @extack: Netlink extended ACK structure
+ *
+ * Check whether the device already has a pending flash update. If such an
+ * update is found, cancel it so that the requested update may proceed.
+ *
+ * Returns: zero on success, or a negative error code on failure.
+ */
+int ice_check_for_pending_update(struct ice_pf *pf, const char *component,
+ struct netlink_ext_ack *extack)
+{
+ struct devlink *devlink = priv_to_devlink(pf);
+ struct device *dev = ice_pf_to_dev(pf);
+ struct ice_hw_dev_caps *dev_caps;
+ struct ice_hw *hw = &pf->hw;
+ enum ice_status status;
+ u8 pending = 0;
+ int err;
+
+ dev_caps = kzalloc(sizeof(*dev_caps), GFP_KERNEL);
+ if (!dev_caps)
+ return -ENOMEM;
+
+ /* Read the most recent device capabilities from firmware. Do not use
+ * the cached values in hw->dev_caps, because the pending update flag
+ * may have changed, e.g. if an update was previously completed and
+ * the system has not yet rebooted.
+ */
+ status = ice_discover_dev_caps(hw, dev_caps);
+ if (status) {
+ NL_SET_ERR_MSG_MOD(extack, "Unable to read device capabilities");
+ kfree(dev_caps);
+ return -EIO;
+ }
+
+ if (dev_caps->common_cap.nvm_update_pending_nvm) {
+ dev_info(dev, "The fw.mgmt flash component has a pending update\n");
+ pending |= ICE_AQC_NVM_ACTIV_SEL_NVM;
+ }
+
+ if (dev_caps->common_cap.nvm_update_pending_orom) {
+ dev_info(dev, "The fw.undi flash component has a pending update\n");
+ pending |= ICE_AQC_NVM_ACTIV_SEL_OROM;
+ }
+
+ if (dev_caps->common_cap.nvm_update_pending_netlist) {
+ dev_info(dev, "The fw.netlist flash component has a pending update\n");
+ pending |= ICE_AQC_NVM_ACTIV_SEL_NETLIST;
+ }
+
+ kfree(dev_caps);
+
+ /* If the flash_update request is for a specific component, ignore all
+ * of the other components.
+ */
+ if (component) {
+ if (strcmp(component, "fw.mgmt") == 0)
+ pending &= ICE_AQC_NVM_ACTIV_SEL_NVM;
+ else if (strcmp(component, "fw.undi") == 0)
+ pending &= ICE_AQC_NVM_ACTIV_SEL_OROM;
+ else if (strcmp(component, "fw.netlist") == 0)
+ pending &= ICE_AQC_NVM_ACTIV_SEL_NETLIST;
+ else
+ WARN(1, "Unexpected flash component %s", component);
+ }
+
+ /* There is no previous pending update, so this request may continue */
+ if (!pending)
+ return 0;
+
+ /* In order to allow overwriting a previous pending update, notify
+ * firmware to cancel that update by issuing the appropriate command.
+ */
+ devlink_flash_update_status_notify(devlink,
+ "Canceling previous pending update",
+ component, 0, 0);
+
+ status = ice_acquire_nvm(hw, ICE_RES_WRITE);
+ if (status) {
+ dev_err(dev, "Failed to acquire device flash lock, err %s aq_err %s\n",
+ ice_stat_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ NL_SET_ERR_MSG_MOD(extack, "Failed to acquire device flash lock");
+ return -EIO;
+ }
+
+ pending |= ICE_AQC_NVM_REVERT_LAST_ACTIV;
+ err = ice_switch_flash_banks(pf, pending, extack);
+
+ ice_release_nvm(hw);
+
+ return err;
+}
diff --git a/drivers/net/ethernet/intel/ice/ice_fw_update.h b/drivers/net/ethernet/intel/ice/ice_fw_update.h
new file mode 100644
index 000000000000..79472cc618b4
--- /dev/null
+++ b/drivers/net/ethernet/intel/ice/ice_fw_update.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018-2019, Intel Corporation. */
+
+#ifndef _ICE_FW_UPDATE_H_
+#define _ICE_FW_UPDATE_H_
+
+int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw,
+ struct netlink_ext_ack *extack);
+int ice_check_for_pending_update(struct ice_pf *pf, const char *component,
+ struct netlink_ext_ack *extack);
+
+#endif
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
index 1086c9f778b4..90abc8612a6a 100644
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
@@ -57,7 +57,7 @@
#define PRTDCB_GENS 0x00083020
#define PRTDCB_GENS_DCBX_STATUS_S 0
#define PRTDCB_GENS_DCBX_STATUS_M ICE_M(0x7, 0)
-#define PRTDCB_TUP2TC 0x001D26C0 /* Reset Source: CORER */
+#define PRTDCB_TUP2TC 0x001D26C0
#define GL_PREEXT_L2_PMASK0(_i) (0x0020F0FC + ((_i) * 4))
#define GL_PREEXT_L2_PMASK1(_i) (0x0020F108 + ((_i) * 4))
#define GLFLXP_RXDID_FLX_WRD_0(_i) (0x0045c800 + ((_i) * 4))
@@ -362,13 +362,22 @@
#define GLV_TEPC(_VSI) (0x00312000 + ((_VSI) * 4))
#define GLV_UPRCL(_i) (0x003B2000 + ((_i) * 8))
#define GLV_UPTCL(_i) (0x0030A000 + ((_i) * 8))
+#define PRTRPB_RDPC 0x000AC260
#define VSIQF_FD_CNT(_VSI) (0x00464000 + ((_VSI) * 4))
#define VSIQF_FD_CNT_FD_GCNT_S 0
#define VSIQF_FD_CNT_FD_GCNT_M ICE_M(0x3FFF, 0)
#define VSIQF_HKEY_MAX_INDEX 12
#define VSIQF_HLUT_MAX_INDEX 15
+#define PFPM_APM 0x000B8080
+#define PFPM_APM_APME_M BIT(0)
+#define PFPM_WUFC 0x0009DC00
+#define PFPM_WUFC_MAG_M BIT(1)
+#define PFPM_WUS 0x0009DB80
+#define PFPM_WUS_LNKC_M BIT(0)
+#define PFPM_WUS_MAG_M BIT(1)
+#define PFPM_WUS_MNG_M BIT(3)
+#define PFPM_WUS_FW_RST_WK_M BIT(31)
#define VFINT_DYN_CTLN(_i) (0x00003800 + ((_i) * 4))
#define VFINT_DYN_CTLN_CLEARPBA_M BIT(1)
-#define PRTRPB_RDPC 0x000AC260
#endif /* _ICE_HW_AUTOGEN_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
index 14dfbbc1b2cf..4ec24c3e813f 100644
--- a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
+++ b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
@@ -601,6 +601,7 @@ struct ice_tlan_ctx {
/* shorter macros makes the table fit but are terse */
#define ICE_RX_PTYPE_NOF ICE_RX_PTYPE_NOT_FRAG
+#define ICE_RX_PTYPE_FRG ICE_RX_PTYPE_FRAG
/* Lookup table mapping the HW PTYPE to the bit field for decoding */
static const struct ice_rx_ptype_decoded ice_ptype_lkup[] = {
@@ -608,6 +609,319 @@ static const struct ice_rx_ptype_decoded ice_ptype_lkup[] = {
ICE_PTT_UNUSED_ENTRY(0),
ICE_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
ICE_PTT(2, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
+ ICE_PTT_UNUSED_ENTRY(3),
+ ICE_PTT_UNUSED_ENTRY(4),
+ ICE_PTT_UNUSED_ENTRY(5),
+ ICE_PTT(6, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
+ ICE_PTT(7, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
+ ICE_PTT_UNUSED_ENTRY(8),
+ ICE_PTT_UNUSED_ENTRY(9),
+ ICE_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
+ ICE_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
+ ICE_PTT_UNUSED_ENTRY(12),
+ ICE_PTT_UNUSED_ENTRY(13),
+ ICE_PTT_UNUSED_ENTRY(14),
+ ICE_PTT_UNUSED_ENTRY(15),
+ ICE_PTT_UNUSED_ENTRY(16),
+ ICE_PTT_UNUSED_ENTRY(17),
+ ICE_PTT_UNUSED_ENTRY(18),
+ ICE_PTT_UNUSED_ENTRY(19),
+ ICE_PTT_UNUSED_ENTRY(20),
+ ICE_PTT_UNUSED_ENTRY(21),
+
+ /* Non Tunneled IPv4 */
+ ICE_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3),
+ ICE_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3),
+ ICE_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(25),
+ ICE_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP, PAY4),
+ ICE_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4),
+ ICE_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4),
+
+ /* IPv4 --> IPv4 */
+ ICE_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
+ ICE_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
+ ICE_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(32),
+ ICE_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
+ ICE_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
+ ICE_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv4 --> IPv6 */
+ ICE_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
+ ICE_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
+ ICE_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(39),
+ ICE_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
+ ICE_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
+ ICE_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT */
+ ICE_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
+
+ /* IPv4 --> GRE/NAT --> IPv4 */
+ ICE_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
+ ICE_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
+ ICE_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(47),
+ ICE_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
+ ICE_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
+ ICE_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT --> IPv6 */
+ ICE_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
+ ICE_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
+ ICE_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(54),
+ ICE_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
+ ICE_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
+ ICE_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT --> MAC */
+ ICE_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
+
+ /* IPv4 --> GRE/NAT --> MAC --> IPv4 */
+ ICE_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
+ ICE_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
+ ICE_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(62),
+ ICE_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
+ ICE_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
+ ICE_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT -> MAC --> IPv6 */
+ ICE_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
+ ICE_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
+ ICE_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(69),
+ ICE_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
+ ICE_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
+ ICE_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT --> MAC/VLAN */
+ ICE_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
+
+ /* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */
+ ICE_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
+ ICE_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
+ ICE_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(77),
+ ICE_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
+ ICE_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
+ ICE_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */
+ ICE_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
+ ICE_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
+ ICE_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(84),
+ ICE_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
+ ICE_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
+ ICE_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
+
+ /* Non Tunneled IPv6 */
+ ICE_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
+ ICE_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
+ ICE_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY3),
+ ICE_PTT_UNUSED_ENTRY(91),
+ ICE_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4),
+ ICE_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
+ ICE_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4),
+
+ /* IPv6 --> IPv4 */
+ ICE_PTT(95, IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
+ ICE_PTT(96, IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
+ ICE_PTT(97, IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(98),
+ ICE_PTT(99, IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
+ ICE_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
+ ICE_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv6 --> IPv6 */
+ ICE_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
+ ICE_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
+ ICE_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(105),
+ ICE_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
+ ICE_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
+ ICE_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT */
+ ICE_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
+
+ /* IPv6 --> GRE/NAT -> IPv4 */
+ ICE_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
+ ICE_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
+ ICE_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(113),
+ ICE_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
+ ICE_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
+ ICE_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> IPv6 */
+ ICE_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
+ ICE_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
+ ICE_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(120),
+ ICE_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
+ ICE_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
+ ICE_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> MAC */
+ ICE_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
+
+ /* IPv6 --> GRE/NAT -> MAC -> IPv4 */
+ ICE_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
+ ICE_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
+ ICE_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(128),
+ ICE_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
+ ICE_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
+ ICE_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> MAC -> IPv6 */
+ ICE_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
+ ICE_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
+ ICE_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(135),
+ ICE_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
+ ICE_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
+ ICE_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> MAC/VLAN */
+ ICE_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
+
+ /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */
+ ICE_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
+ ICE_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
+ ICE_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(143),
+ ICE_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
+ ICE_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
+ ICE_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */
+ ICE_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
+ ICE_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
+ ICE_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
+ ICE_PTT_UNUSED_ENTRY(150),
+ ICE_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
+ ICE_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
+ ICE_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
+
+ /* unused entries */
+ ICE_PTT_UNUSED_ENTRY(154),
+ ICE_PTT_UNUSED_ENTRY(155),
+ ICE_PTT_UNUSED_ENTRY(156),
+ ICE_PTT_UNUSED_ENTRY(157),
+ ICE_PTT_UNUSED_ENTRY(158),
+ ICE_PTT_UNUSED_ENTRY(159),
+
+ ICE_PTT_UNUSED_ENTRY(160),
+ ICE_PTT_UNUSED_ENTRY(161),
+ ICE_PTT_UNUSED_ENTRY(162),
+ ICE_PTT_UNUSED_ENTRY(163),
+ ICE_PTT_UNUSED_ENTRY(164),
+ ICE_PTT_UNUSED_ENTRY(165),
+ ICE_PTT_UNUSED_ENTRY(166),
+ ICE_PTT_UNUSED_ENTRY(167),
+ ICE_PTT_UNUSED_ENTRY(168),
+ ICE_PTT_UNUSED_ENTRY(169),
+
+ ICE_PTT_UNUSED_ENTRY(170),
+ ICE_PTT_UNUSED_ENTRY(171),
+ ICE_PTT_UNUSED_ENTRY(172),
+ ICE_PTT_UNUSED_ENTRY(173),
+ ICE_PTT_UNUSED_ENTRY(174),
+ ICE_PTT_UNUSED_ENTRY(175),
+ ICE_PTT_UNUSED_ENTRY(176),
+ ICE_PTT_UNUSED_ENTRY(177),
+ ICE_PTT_UNUSED_ENTRY(178),
+ ICE_PTT_UNUSED_ENTRY(179),
+
+ ICE_PTT_UNUSED_ENTRY(180),
+ ICE_PTT_UNUSED_ENTRY(181),
+ ICE_PTT_UNUSED_ENTRY(182),
+ ICE_PTT_UNUSED_ENTRY(183),
+ ICE_PTT_UNUSED_ENTRY(184),
+ ICE_PTT_UNUSED_ENTRY(185),
+ ICE_PTT_UNUSED_ENTRY(186),
+ ICE_PTT_UNUSED_ENTRY(187),
+ ICE_PTT_UNUSED_ENTRY(188),
+ ICE_PTT_UNUSED_ENTRY(189),
+
+ ICE_PTT_UNUSED_ENTRY(190),
+ ICE_PTT_UNUSED_ENTRY(191),
+ ICE_PTT_UNUSED_ENTRY(192),
+ ICE_PTT_UNUSED_ENTRY(193),
+ ICE_PTT_UNUSED_ENTRY(194),
+ ICE_PTT_UNUSED_ENTRY(195),
+ ICE_PTT_UNUSED_ENTRY(196),
+ ICE_PTT_UNUSED_ENTRY(197),
+ ICE_PTT_UNUSED_ENTRY(198),
+ ICE_PTT_UNUSED_ENTRY(199),
+
+ ICE_PTT_UNUSED_ENTRY(200),
+ ICE_PTT_UNUSED_ENTRY(201),
+ ICE_PTT_UNUSED_ENTRY(202),
+ ICE_PTT_UNUSED_ENTRY(203),
+ ICE_PTT_UNUSED_ENTRY(204),
+ ICE_PTT_UNUSED_ENTRY(205),
+ ICE_PTT_UNUSED_ENTRY(206),
+ ICE_PTT_UNUSED_ENTRY(207),
+ ICE_PTT_UNUSED_ENTRY(208),
+ ICE_PTT_UNUSED_ENTRY(209),
+
+ ICE_PTT_UNUSED_ENTRY(210),
+ ICE_PTT_UNUSED_ENTRY(211),
+ ICE_PTT_UNUSED_ENTRY(212),
+ ICE_PTT_UNUSED_ENTRY(213),
+ ICE_PTT_UNUSED_ENTRY(214),
+ ICE_PTT_UNUSED_ENTRY(215),
+ ICE_PTT_UNUSED_ENTRY(216),
+ ICE_PTT_UNUSED_ENTRY(217),
+ ICE_PTT_UNUSED_ENTRY(218),
+ ICE_PTT_UNUSED_ENTRY(219),
+
+ ICE_PTT_UNUSED_ENTRY(220),
+ ICE_PTT_UNUSED_ENTRY(221),
+ ICE_PTT_UNUSED_ENTRY(222),
+ ICE_PTT_UNUSED_ENTRY(223),
+ ICE_PTT_UNUSED_ENTRY(224),
+ ICE_PTT_UNUSED_ENTRY(225),
+ ICE_PTT_UNUSED_ENTRY(226),
+ ICE_PTT_UNUSED_ENTRY(227),
+ ICE_PTT_UNUSED_ENTRY(228),
+ ICE_PTT_UNUSED_ENTRY(229),
+
+ ICE_PTT_UNUSED_ENTRY(230),
+ ICE_PTT_UNUSED_ENTRY(231),
+ ICE_PTT_UNUSED_ENTRY(232),
+ ICE_PTT_UNUSED_ENTRY(233),
+ ICE_PTT_UNUSED_ENTRY(234),
+ ICE_PTT_UNUSED_ENTRY(235),
+ ICE_PTT_UNUSED_ENTRY(236),
+ ICE_PTT_UNUSED_ENTRY(237),
+ ICE_PTT_UNUSED_ENTRY(238),
+ ICE_PTT_UNUSED_ENTRY(239),
+
+ ICE_PTT_UNUSED_ENTRY(240),
+ ICE_PTT_UNUSED_ENTRY(241),
+ ICE_PTT_UNUSED_ENTRY(242),
+ ICE_PTT_UNUSED_ENTRY(243),
+ ICE_PTT_UNUSED_ENTRY(244),
+ ICE_PTT_UNUSED_ENTRY(245),
+ ICE_PTT_UNUSED_ENTRY(246),
+ ICE_PTT_UNUSED_ENTRY(247),
+ ICE_PTT_UNUSED_ENTRY(248),
+ ICE_PTT_UNUSED_ENTRY(249),
+
+ ICE_PTT_UNUSED_ENTRY(250),
+ ICE_PTT_UNUSED_ENTRY(251),
+ ICE_PTT_UNUSED_ENTRY(252),
+ ICE_PTT_UNUSED_ENTRY(253),
+ ICE_PTT_UNUSED_ENTRY(254),
+ ICE_PTT_UNUSED_ENTRY(255),
};
static inline struct ice_rx_ptype_decoded ice_decode_rx_desc_ptype(u16 ptype)
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 2e3a39cea2c0..f2682776f8c8 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -127,8 +127,14 @@ static void ice_vsi_set_num_desc(struct ice_vsi *vsi)
case ICE_VSI_PF:
case ICE_VSI_CTRL:
case ICE_VSI_LB:
- vsi->num_rx_desc = ICE_DFLT_NUM_RX_DESC;
- vsi->num_tx_desc = ICE_DFLT_NUM_TX_DESC;
+ /* a user could change the values of num_[tr]x_desc using
+ * ethtool -G so we should keep those values instead of
+ * overwriting them with the defaults.
+ */
+ if (!vsi->num_rx_desc)
+ vsi->num_rx_desc = ICE_DFLT_NUM_RX_DESC;
+ if (!vsi->num_tx_desc)
+ vsi->num_tx_desc = ICE_DFLT_NUM_TX_DESC;
break;
default:
dev_dbg(ice_pf_to_dev(vsi->back), "Not setting number of Tx/Rx descriptors for VSI type %d\n",
@@ -1468,6 +1474,30 @@ static void ice_vsi_set_rss_flow_fld(struct ice_vsi *vsi)
}
/**
+ * ice_pf_state_is_nominal - checks the PF for nominal state
+ * @pf: pointer to PF to check
+ *
+ * Check the PF's state for a collection of bits that would indicate
+ * the PF is in a state that would inhibit normal operation for
+ * driver functionality.
+ *
+ * Returns true if PF is in a nominal state, false otherwise
+ */
+bool ice_pf_state_is_nominal(struct ice_pf *pf)
+{
+ DECLARE_BITMAP(check_bits, __ICE_STATE_NBITS) = { 0 };
+
+ if (!pf)
+ return false;
+
+ bitmap_set(check_bits, 0, __ICE_STATE_NOMINAL_CHECK_BITS);
+ if (bitmap_intersects(pf->state, check_bits, __ICE_STATE_NBITS))
+ return false;
+
+ return true;
+}
+
+/**
* ice_update_eth_stats - Update VSI-specific ethernet statistics counters
* @vsi: the VSI to be updated
*/
@@ -1667,7 +1697,7 @@ ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_ring **rings)
u16 q_idx = 0;
int err = 0;
- qg_buf = kzalloc(sizeof(*qg_buf), GFP_KERNEL);
+ qg_buf = kzalloc(struct_size(qg_buf, txqs, 1), GFP_KERNEL);
if (!qg_buf)
return -ENOMEM;
@@ -1987,6 +2017,13 @@ int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena, bool vlan_promisc)
if (!vsi)
return -EINVAL;
+ /* Don't enable VLAN pruning if the netdev is currently in promiscuous
+ * mode. VLAN pruning will be enabled when the interface exits
+ * promiscuous mode if any VLAN filters are active.
+ */
+ if (vsi->netdev && vsi->netdev->flags & IFF_PROMISC && ena)
+ return 0;
+
pf = vsi->back;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt)
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
index d80e6afa4511..981f3a156c24 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
@@ -8,6 +8,8 @@
const char *ice_vsi_type_str(enum ice_vsi_type vsi_type);
+bool ice_pf_state_is_nominal(struct ice_pf *pf);
+
void ice_update_eth_stats(struct ice_vsi *vsi);
int ice_vsi_cfg_rxqs(struct ice_vsi *vsi);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 4cbd49c87568..8437d72795b0 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -5,6 +5,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <generated/utsrelease.h>
#include "ice.h"
#include "ice_base.h"
#include "ice_lib.h"
@@ -13,15 +14,7 @@
#include "ice_dcb_nl.h"
#include "ice_devlink.h"
-#define DRV_VERSION_MAJOR 0
-#define DRV_VERSION_MINOR 8
-#define DRV_VERSION_BUILD 2
-
-#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
- __stringify(DRV_VERSION_MINOR) "." \
- __stringify(DRV_VERSION_BUILD) "-k"
#define DRV_SUMMARY "Intel(R) Ethernet Connection E800 Series Linux Driver"
-const char ice_drv_ver[] = DRV_VERSION;
static const char ice_driver_string[] = DRV_SUMMARY;
static const char ice_copyright[] = "Copyright (c) 2018, Intel Corporation.";
@@ -32,7 +25,6 @@ static const char ice_copyright[] = "Copyright (c) 2018, Intel Corporation.";
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION(DRV_SUMMARY);
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
MODULE_FIRMWARE(ICE_DDP_PKG_FILE);
static int debug = -1;
@@ -377,6 +369,7 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
~IFF_PROMISC;
goto out_promisc;
}
+ ice_cfg_vlan_pruning(vsi, false, false);
}
} else {
/* Clear Rx filter to remove traffic from wire */
@@ -389,6 +382,8 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
IFF_PROMISC;
goto out_promisc;
}
+ if (vsi->num_vlan > 1)
+ ice_cfg_vlan_pruning(vsi, true, false);
}
}
}
@@ -620,6 +615,7 @@ static void ice_print_topo_conflict(struct ice_vsi *vsi)
void ice_print_link_msg(struct ice_vsi *vsi, bool isup)
{
struct ice_aqc_get_phy_caps_data *caps;
+ const char *an_advertised;
enum ice_status status;
const char *fec_req;
const char *speed;
@@ -718,6 +714,7 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup)
caps = kzalloc(sizeof(*caps), GFP_KERNEL);
if (!caps) {
fec_req = "Unknown";
+ an_advertised = "Unknown";
goto done;
}
@@ -726,6 +723,8 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup)
if (status)
netdev_info(vsi->netdev, "Get phy capability failed.\n");
+ an_advertised = ice_is_phy_caps_an_enabled(caps) ? "On" : "Off";
+
if (caps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_528_REQ ||
caps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_544_REQ)
fec_req = "RS-FEC";
@@ -738,8 +737,8 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup)
kfree(caps);
done:
- netdev_info(vsi->netdev, "NIC Link is up %sbps Full Duplex, Requested FEC: %s, Negotiated FEC: %s, Autoneg: %s, Flow Control: %s\n",
- speed, fec_req, fec, an, fc);
+ netdev_info(vsi->netdev, "NIC Link is up %sbps Full Duplex, Requested FEC: %s, Negotiated FEC: %s, Autoneg Advertised: %s, Autoneg Negotiated: %s, Flow Control: %s\n",
+ speed, fec_req, fec, an_advertised, an, fc);
ice_print_topo_conflict(vsi);
}
@@ -771,6 +770,100 @@ static void ice_vsi_link_event(struct ice_vsi *vsi, bool link_up)
}
/**
+ * ice_set_dflt_mib - send a default config MIB to the FW
+ * @pf: private PF struct
+ *
+ * This function sends a default configuration MIB to the FW.
+ *
+ * If this function errors out at any point, the driver is still able to
+ * function. The main impact is that LFC may not operate as expected.
+ * Therefore an error state in this function should be treated with a DBG
+ * message and continue on with driver rebuild/reenable.
+ */
+static void ice_set_dflt_mib(struct ice_pf *pf)
+{
+ struct device *dev = ice_pf_to_dev(pf);
+ u8 mib_type, *buf, *lldpmib = NULL;
+ u16 len, typelen, offset = 0;
+ struct ice_lldp_org_tlv *tlv;
+ struct ice_hw *hw;
+ u32 ouisubtype;
+
+ if (!pf) {
+ dev_dbg(dev, "%s NULL pf pointer\n", __func__);
+ return;
+ }
+
+ hw = &pf->hw;
+ mib_type = SET_LOCAL_MIB_TYPE_LOCAL_MIB;
+ lldpmib = kzalloc(ICE_LLDPDU_SIZE, GFP_KERNEL);
+ if (!lldpmib) {
+ dev_dbg(dev, "%s Failed to allocate MIB memory\n",
+ __func__);
+ return;
+ }
+
+ /* Add ETS CFG TLV */
+ tlv = (struct ice_lldp_org_tlv *)lldpmib;
+ typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) |
+ ICE_IEEE_ETS_TLV_LEN);
+ tlv->typelen = htons(typelen);
+ ouisubtype = ((ICE_IEEE_8021QAZ_OUI << ICE_LLDP_TLV_OUI_S) |
+ ICE_IEEE_SUBTYPE_ETS_CFG);
+ tlv->ouisubtype = htonl(ouisubtype);
+
+ buf = tlv->tlvinfo;
+ buf[0] = 0;
+
+ /* ETS CFG all UPs map to TC 0. Next 4 (1 - 4) Octets = 0.
+ * Octets 5 - 12 are BW values, set octet 5 to 100% BW.
+ * Octets 13 - 20 are TSA values - leave as zeros
+ */
+ buf[5] = 0x64;
+ len = (typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S;
+ offset += len + 2;
+ tlv = (struct ice_lldp_org_tlv *)
+ ((char *)tlv + sizeof(tlv->typelen) + len);
+
+ /* Add ETS REC TLV */
+ buf = tlv->tlvinfo;
+ tlv->typelen = htons(typelen);
+
+ ouisubtype = ((ICE_IEEE_8021QAZ_OUI << ICE_LLDP_TLV_OUI_S) |
+ ICE_IEEE_SUBTYPE_ETS_REC);
+ tlv->ouisubtype = htonl(ouisubtype);
+
+ /* First octet of buf is reserved
+ * Octets 1 - 4 map UP to TC - all UPs map to zero
+ * Octets 5 - 12 are BW values - set TC 0 to 100%.
+ * Octets 13 - 20 are TSA value - leave as zeros
+ */
+ buf[5] = 0x64;
+ offset += len + 2;
+ tlv = (struct ice_lldp_org_tlv *)
+ ((char *)tlv + sizeof(tlv->typelen) + len);
+
+ /* Add PFC CFG TLV */
+ typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) |
+ ICE_IEEE_PFC_TLV_LEN);
+ tlv->typelen = htons(typelen);
+
+ ouisubtype = ((ICE_IEEE_8021QAZ_OUI << ICE_LLDP_TLV_OUI_S) |
+ ICE_IEEE_SUBTYPE_PFC_CFG);
+ tlv->ouisubtype = htonl(ouisubtype);
+
+ /* Octet 1 left as all zeros - PFC disabled */
+ buf[0] = 0x08;
+ len = (typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S;
+ offset += len + 2;
+
+ if (ice_aq_set_lldp_mib(hw, mib_type, (void *)lldpmib, offset, NULL))
+ dev_dbg(dev, "%s Failed to set default LLDP MIB\n", __func__);
+
+ kfree(lldpmib);
+}
+
+/**
* ice_link_event - process the link event
* @pf: PF that the link event is associated with
* @pi: port_info for the port that the link event is associated with
@@ -804,9 +897,11 @@ ice_link_event(struct ice_pf *pf, struct ice_port_info *pi, bool link_up,
dev_dbg(dev, "Failed to update link status and re-enable link events for port %d\n",
pi->lport);
- /* if the old link up/down and speed is the same as the new */
- if (link_up == old_link && link_speed == old_link_speed)
- return result;
+ /* Check if the link state is up after updating link info, and treat
+ * this event as an UP event since the link is actually UP now.
+ */
+ if (phy_info->link_info.link_info & ICE_AQ_LINK_UP)
+ link_up = true;
vsi = ice_get_main_vsi(pf);
if (!vsi || !vsi->port_info)
@@ -825,7 +920,17 @@ ice_link_event(struct ice_pf *pf, struct ice_port_info *pi, bool link_up,
}
}
- ice_dcb_rebuild(pf);
+ /* if the old link up/down and speed is the same as the new */
+ if (link_up == old_link && link_speed == old_link_speed)
+ return result;
+
+ if (ice_is_dcb_active(pf)) {
+ if (test_bit(ICE_FLAG_DCB_ENA, pf->flags))
+ ice_dcb_rebuild(pf);
+ } else {
+ if (link_up)
+ ice_set_dflt_mib(pf);
+ }
ice_vsi_link_event(vsi, link_up);
ice_print_link_msg(vsi, link_up);
@@ -918,6 +1023,151 @@ ice_handle_link_event(struct ice_pf *pf, struct ice_rq_event_info *event)
return status;
}
+enum ice_aq_task_state {
+ ICE_AQ_TASK_WAITING = 0,
+ ICE_AQ_TASK_COMPLETE,
+ ICE_AQ_TASK_CANCELED,
+};
+
+struct ice_aq_task {
+ struct hlist_node entry;
+
+ u16 opcode;
+ struct ice_rq_event_info *event;
+ enum ice_aq_task_state state;
+};
+
+/**
+ * ice_wait_for_aq_event - Wait for an AdminQ event from firmware
+ * @pf: pointer to the PF private structure
+ * @opcode: the opcode to wait for
+ * @timeout: how long to wait, in jiffies
+ * @event: storage for the event info
+ *
+ * Waits for a specific AdminQ completion event on the ARQ for a given PF. The
+ * current thread will be put to sleep until the specified event occurs or
+ * until the given timeout is reached.
+ *
+ * To obtain only the descriptor contents, pass an event without an allocated
+ * msg_buf. If the complete data buffer is desired, allocate the
+ * event->msg_buf with enough space ahead of time.
+ *
+ * Returns: zero on success, or a negative error code on failure.
+ */
+int ice_aq_wait_for_event(struct ice_pf *pf, u16 opcode, unsigned long timeout,
+ struct ice_rq_event_info *event)
+{
+ struct ice_aq_task *task;
+ long ret;
+ int err;
+
+ task = kzalloc(sizeof(*task), GFP_KERNEL);
+ if (!task)
+ return -ENOMEM;
+
+ INIT_HLIST_NODE(&task->entry);
+ task->opcode = opcode;
+ task->event = event;
+ task->state = ICE_AQ_TASK_WAITING;
+
+ spin_lock_bh(&pf->aq_wait_lock);
+ hlist_add_head(&task->entry, &pf->aq_wait_list);
+ spin_unlock_bh(&pf->aq_wait_lock);
+
+ ret = wait_event_interruptible_timeout(pf->aq_wait_queue, task->state,
+ timeout);
+ switch (task->state) {
+ case ICE_AQ_TASK_WAITING:
+ err = ret < 0 ? ret : -ETIMEDOUT;
+ break;
+ case ICE_AQ_TASK_CANCELED:
+ err = ret < 0 ? ret : -ECANCELED;
+ break;
+ case ICE_AQ_TASK_COMPLETE:
+ err = ret < 0 ? ret : 0;
+ break;
+ default:
+ WARN(1, "Unexpected AdminQ wait task state %u", task->state);
+ err = -EINVAL;
+ break;
+ }
+
+ spin_lock_bh(&pf->aq_wait_lock);
+ hlist_del(&task->entry);
+ spin_unlock_bh(&pf->aq_wait_lock);
+ kfree(task);
+
+ return err;
+}
+
+/**
+ * ice_aq_check_events - Check if any thread is waiting for an AdminQ event
+ * @pf: pointer to the PF private structure
+ * @opcode: the opcode of the event
+ * @event: the event to check
+ *
+ * Loops over the current list of pending threads waiting for an AdminQ event.
+ * For each matching task, copy the contents of the event into the task
+ * structure and wake up the thread.
+ *
+ * If multiple threads wait for the same opcode, they will all be woken up.
+ *
+ * Note that event->msg_buf will only be duplicated if the event has a buffer
+ * with enough space already allocated. Otherwise, only the descriptor and
+ * message length will be copied.
+ *
+ * Returns: true if an event was found, false otherwise
+ */
+static void ice_aq_check_events(struct ice_pf *pf, u16 opcode,
+ struct ice_rq_event_info *event)
+{
+ struct ice_aq_task *task;
+ bool found = false;
+
+ spin_lock_bh(&pf->aq_wait_lock);
+ hlist_for_each_entry(task, &pf->aq_wait_list, entry) {
+ if (task->state || task->opcode != opcode)
+ continue;
+
+ memcpy(&task->event->desc, &event->desc, sizeof(event->desc));
+ task->event->msg_len = event->msg_len;
+
+ /* Only copy the data buffer if a destination was set */
+ if (task->event->msg_buf &&
+ task->event->buf_len > event->buf_len) {
+ memcpy(task->event->msg_buf, event->msg_buf,
+ event->buf_len);
+ task->event->buf_len = event->buf_len;
+ }
+
+ task->state = ICE_AQ_TASK_COMPLETE;
+ found = true;
+ }
+ spin_unlock_bh(&pf->aq_wait_lock);
+
+ if (found)
+ wake_up(&pf->aq_wait_queue);
+}
+
+/**
+ * ice_aq_cancel_waiting_tasks - Immediately cancel all waiting tasks
+ * @pf: the PF private structure
+ *
+ * Set all waiting tasks to ICE_AQ_TASK_CANCELED, and wake up their threads.
+ * This will then cause ice_aq_wait_for_event to exit with -ECANCELED.
+ */
+static void ice_aq_cancel_waiting_tasks(struct ice_pf *pf)
+{
+ struct ice_aq_task *task;
+
+ spin_lock_bh(&pf->aq_wait_lock);
+ hlist_for_each_entry(task, &pf->aq_wait_list, entry)
+ task->state = ICE_AQ_TASK_CANCELED;
+ spin_unlock_bh(&pf->aq_wait_lock);
+
+ wake_up(&pf->aq_wait_queue);
+}
+
/**
* __ice_clean_ctrlq - helper function to clean controlq rings
* @pf: ptr to struct ice_pf
@@ -1014,6 +1264,9 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
opcode = le16_to_cpu(event.desc.opcode);
+ /* Notify any thread that might be waiting for this event */
+ ice_aq_check_events(pf, opcode, &event);
+
switch (opcode) {
case ice_aqc_opc_get_link_status:
if (ice_handle_link_event(pf, &event))
@@ -1137,10 +1390,15 @@ static void ice_service_task_complete(struct ice_pf *pf)
/**
* ice_service_task_stop - stop service task and cancel works
* @pf: board private structure
+ *
+ * Return 0 if the __ICE_SERVICE_DIS bit was not already set,
+ * 1 otherwise.
*/
-static void ice_service_task_stop(struct ice_pf *pf)
+static int ice_service_task_stop(struct ice_pf *pf)
{
- set_bit(__ICE_SERVICE_DIS, pf->state);
+ int ret;
+
+ ret = test_and_set_bit(__ICE_SERVICE_DIS, pf->state);
if (pf->serv_tmr.function)
del_timer_sync(&pf->serv_tmr);
@@ -1148,6 +1406,7 @@ static void ice_service_task_stop(struct ice_pf *pf)
cancel_work_sync(&pf->serv_task);
clear_bit(__ICE_SERVICE_SCHED, pf->state);
+ return ret;
}
/**
@@ -1382,25 +1641,23 @@ static int ice_force_phys_link_state(struct ice_vsi *vsi, bool link_up)
link_up == !!(pi->phy.link_info.link_info & ICE_AQ_LINK_UP))
goto out;
- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+ /* Use the current user PHY configuration. The current user PHY
+ * configuration is initialized during probe from PHY capabilities
+ * software mode, and updated on set PHY configuration.
+ */
+ cfg = kmemdup(&pi->phy.curr_user_phy_cfg, sizeof(*cfg), GFP_KERNEL);
if (!cfg) {
retcode = -ENOMEM;
goto out;
}
- cfg->phy_type_low = pcaps->phy_type_low;
- cfg->phy_type_high = pcaps->phy_type_high;
- cfg->caps = pcaps->caps | ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
- cfg->low_power_ctrl = pcaps->low_power_ctrl;
- cfg->eee_cap = pcaps->eee_cap;
- cfg->eeer_value = pcaps->eeer_value;
- cfg->link_fec_opt = pcaps->link_fec_options;
+ cfg->caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
if (link_up)
cfg->caps |= ICE_AQ_PHY_ENA_LINK;
else
cfg->caps &= ~ICE_AQ_PHY_ENA_LINK;
- retcode = ice_aq_set_phy_cfg(&vsi->back->hw, pi->lport, cfg, NULL);
+ retcode = ice_aq_set_phy_cfg(&vsi->back->hw, pi, cfg, NULL);
if (retcode) {
dev_err(dev, "Failed to set phy config, VSI %d error %d\n",
vsi->vsi_num, retcode);
@@ -1414,8 +1671,312 @@ out:
}
/**
- * ice_check_media_subtask - Check for media; bring link up if detected.
+ * ice_init_nvm_phy_type - Initialize the NVM PHY type
+ * @pi: port info structure
+ *
+ * Initialize nvm_phy_type_[low|high] for link lenient mode support
+ */
+static int ice_init_nvm_phy_type(struct ice_port_info *pi)
+{
+ struct ice_aqc_get_phy_caps_data *pcaps;
+ struct ice_pf *pf = pi->hw->back;
+ enum ice_status status;
+ int err = 0;
+
+ pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
+ if (!pcaps)
+ return -ENOMEM;
+
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_NVM_CAP, pcaps,
+ NULL);
+
+ if (status) {
+ dev_err(ice_pf_to_dev(pf), "Get PHY capability failed.\n");
+ err = -EIO;
+ goto out;
+ }
+
+ pf->nvm_phy_type_hi = pcaps->phy_type_high;
+ pf->nvm_phy_type_lo = pcaps->phy_type_low;
+
+out:
+ kfree(pcaps);
+ return err;
+}
+
+/**
+ * ice_init_link_dflt_override - Initialize link default override
+ * @pi: port info structure
+ *
+ * Initialize link default override and PHY total port shutdown during probe
+ */
+static void ice_init_link_dflt_override(struct ice_port_info *pi)
+{
+ struct ice_link_default_override_tlv *ldo;
+ struct ice_pf *pf = pi->hw->back;
+
+ ldo = &pf->link_dflt_override;
+ if (ice_get_link_default_override(ldo, pi))
+ return;
+
+ if (!(ldo->options & ICE_LINK_OVERRIDE_PORT_DIS))
+ return;
+
+ /* Enable Total Port Shutdown (override/replace link-down-on-close
+ * ethtool private flag) for ports with Port Disable bit set.
+ */
+ set_bit(ICE_FLAG_TOTAL_PORT_SHUTDOWN_ENA, pf->flags);
+ set_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, pf->flags);
+}
+
+/**
+ * ice_init_phy_cfg_dflt_override - Initialize PHY cfg default override settings
+ * @pi: port info structure
+ *
+ * If default override is enabled, initialized the user PHY cfg speed and FEC
+ * settings using the default override mask from the NVM.
+ *
+ * The PHY should only be configured with the default override settings the
+ * first time media is available. The __ICE_LINK_DEFAULT_OVERRIDE_PENDING state
+ * is used to indicate that the user PHY cfg default override is initialized
+ * and the PHY has not been configured with the default override settings. The
+ * state is set here, and cleared in ice_configure_phy the first time the PHY is
+ * configured.
+ */
+static void ice_init_phy_cfg_dflt_override(struct ice_port_info *pi)
+{
+ struct ice_link_default_override_tlv *ldo;
+ struct ice_aqc_set_phy_cfg_data *cfg;
+ struct ice_phy_info *phy = &pi->phy;
+ struct ice_pf *pf = pi->hw->back;
+
+ ldo = &pf->link_dflt_override;
+
+ /* If link default override is enabled, use to mask NVM PHY capabilities
+ * for speed and FEC default configuration.
+ */
+ cfg = &phy->curr_user_phy_cfg;
+
+ if (ldo->phy_type_low || ldo->phy_type_high) {
+ cfg->phy_type_low = pf->nvm_phy_type_lo &
+ cpu_to_le64(ldo->phy_type_low);
+ cfg->phy_type_high = pf->nvm_phy_type_hi &
+ cpu_to_le64(ldo->phy_type_high);
+ }
+ cfg->link_fec_opt = ldo->fec_options;
+ phy->curr_user_fec_req = ICE_FEC_AUTO;
+
+ set_bit(__ICE_LINK_DEFAULT_OVERRIDE_PENDING, pf->state);
+}
+
+/**
+ * ice_init_phy_user_cfg - Initialize the PHY user configuration
+ * @pi: port info structure
+ *
+ * Initialize the current user PHY configuration, speed, FEC, and FC requested
+ * mode to default. The PHY defaults are from get PHY capabilities topology
+ * with media so call when media is first available. An error is returned if
+ * called when media is not available. The PHY initialization completed state is
+ * set here.
+ *
+ * These configurations are used when setting PHY
+ * configuration. The user PHY configuration is updated on set PHY
+ * configuration. Returns 0 on success, negative on failure
+ */
+static int ice_init_phy_user_cfg(struct ice_port_info *pi)
+{
+ struct ice_aqc_get_phy_caps_data *pcaps;
+ struct ice_phy_info *phy = &pi->phy;
+ struct ice_pf *pf = pi->hw->back;
+ enum ice_status status;
+ struct ice_vsi *vsi;
+ int err = 0;
+
+ if (!(phy->link_info.link_info & ICE_AQ_MEDIA_AVAILABLE))
+ return -EIO;
+
+ vsi = ice_get_main_vsi(pf);
+ if (!vsi)
+ return -EINVAL;
+
+ pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
+ if (!pcaps)
+ return -ENOMEM;
+
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP, pcaps,
+ NULL);
+ if (status) {
+ dev_err(ice_pf_to_dev(pf), "Get PHY capability failed.\n");
+ err = -EIO;
+ goto err_out;
+ }
+
+ ice_copy_phy_caps_to_cfg(pi, pcaps, &pi->phy.curr_user_phy_cfg);
+
+ /* check if lenient mode is supported and enabled */
+ if (ice_fw_supports_link_override(&vsi->back->hw) &&
+ !(pcaps->module_compliance_enforcement &
+ ICE_AQC_MOD_ENFORCE_STRICT_MODE)) {
+ set_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags);
+
+ /* if link default override is enabled, initialize user PHY
+ * configuration with link default override values
+ */
+ if (pf->link_dflt_override.options & ICE_LINK_OVERRIDE_EN) {
+ ice_init_phy_cfg_dflt_override(pi);
+ goto out;
+ }
+ }
+
+ /* if link default override is not enabled, initialize PHY using
+ * topology with media
+ */
+ phy->curr_user_fec_req = ice_caps_to_fec_mode(pcaps->caps,
+ pcaps->link_fec_options);
+ phy->curr_user_fc_req = ice_caps_to_fc_mode(pcaps->caps);
+
+out:
+ phy->curr_user_speed_req = ICE_AQ_LINK_SPEED_M;
+ set_bit(__ICE_PHY_INIT_COMPLETE, pf->state);
+err_out:
+ kfree(pcaps);
+ return err;
+}
+
+/**
+ * ice_configure_phy - configure PHY
+ * @vsi: VSI of PHY
+ *
+ * Set the PHY configuration. If the current PHY configuration is the same as
+ * the curr_user_phy_cfg, then do nothing to avoid link flap. Otherwise
+ * configure the based get PHY capabilities for topology with media.
+ */
+static int ice_configure_phy(struct ice_vsi *vsi)
+{
+ struct device *dev = ice_pf_to_dev(vsi->back);
+ struct ice_aqc_get_phy_caps_data *pcaps;
+ struct ice_aqc_set_phy_cfg_data *cfg;
+ struct ice_port_info *pi;
+ enum ice_status status;
+ int err = 0;
+
+ pi = vsi->port_info;
+ if (!pi)
+ return -EINVAL;
+
+ /* Ensure we have media as we cannot configure a medialess port */
+ if (!(pi->phy.link_info.link_info & ICE_AQ_MEDIA_AVAILABLE))
+ return -EPERM;
+
+ ice_print_topo_conflict(vsi);
+
+ if (vsi->port_info->phy.link_info.topo_media_conflict ==
+ ICE_AQ_LINK_TOPO_UNSUPP_MEDIA)
+ return -EPERM;
+
+ if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags))
+ return ice_force_phys_link_state(vsi, true);
+
+ pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
+ if (!pcaps)
+ return -ENOMEM;
+
+ /* Get current PHY config */
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, pcaps,
+ NULL);
+ if (status) {
+ dev_err(dev, "Failed to get PHY configuration, VSI %d error %s\n",
+ vsi->vsi_num, ice_stat_str(status));
+ err = -EIO;
+ goto done;
+ }
+
+ /* If PHY enable link is configured and configuration has not changed,
+ * there's nothing to do
+ */
+ if (pcaps->caps & ICE_AQC_PHY_EN_LINK &&
+ ice_phy_caps_equals_cfg(pcaps, &pi->phy.curr_user_phy_cfg))
+ goto done;
+
+ /* Use PHY topology as baseline for configuration */
+ memset(pcaps, 0, sizeof(*pcaps));
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP, pcaps,
+ NULL);
+ if (status) {
+ dev_err(dev, "Failed to get PHY topology, VSI %d error %s\n",
+ vsi->vsi_num, ice_stat_str(status));
+ err = -EIO;
+ goto done;
+ }
+
+ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+ if (!cfg) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ ice_copy_phy_caps_to_cfg(pi, pcaps, cfg);
+
+ /* Speed - If default override pending, use curr_user_phy_cfg set in
+ * ice_init_phy_user_cfg_ldo.
+ */
+ if (test_and_clear_bit(__ICE_LINK_DEFAULT_OVERRIDE_PENDING,
+ vsi->back->state)) {
+ cfg->phy_type_low = pi->phy.curr_user_phy_cfg.phy_type_low;
+ cfg->phy_type_high = pi->phy.curr_user_phy_cfg.phy_type_high;
+ } else {
+ u64 phy_low = 0, phy_high = 0;
+
+ ice_update_phy_type(&phy_low, &phy_high,
+ pi->phy.curr_user_speed_req);
+ cfg->phy_type_low = pcaps->phy_type_low & cpu_to_le64(phy_low);
+ cfg->phy_type_high = pcaps->phy_type_high &
+ cpu_to_le64(phy_high);
+ }
+
+ /* Can't provide what was requested; use PHY capabilities */
+ if (!cfg->phy_type_low && !cfg->phy_type_high) {
+ cfg->phy_type_low = pcaps->phy_type_low;
+ cfg->phy_type_high = pcaps->phy_type_high;
+ }
+
+ /* FEC */
+ ice_cfg_phy_fec(pi, cfg, pi->phy.curr_user_fec_req);
+
+ /* Can't provide what was requested; use PHY capabilities */
+ if (cfg->link_fec_opt !=
+ (cfg->link_fec_opt & pcaps->link_fec_options)) {
+ cfg->caps |= pcaps->caps & ICE_AQC_PHY_EN_AUTO_FEC;
+ cfg->link_fec_opt = pcaps->link_fec_options;
+ }
+
+ /* Flow Control - always supported; no need to check against
+ * capabilities
+ */
+ ice_cfg_phy_fc(pi, cfg, pi->phy.curr_user_fc_req);
+
+ /* Enable link and link update */
+ cfg->caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT | ICE_AQ_PHY_ENA_LINK;
+
+ status = ice_aq_set_phy_cfg(&vsi->back->hw, pi, cfg, NULL);
+ if (status) {
+ dev_err(dev, "Failed to set phy config, VSI %d error %s\n",
+ vsi->vsi_num, ice_stat_str(status));
+ err = -EIO;
+ }
+
+ kfree(cfg);
+done:
+ kfree(pcaps);
+ return err;
+}
+
+/**
+ * ice_check_media_subtask - Check for media
* @pf: pointer to PF struct
+ *
+ * If media is available, then initialize PHY user configuration if it is not
+ * been, and configure the PHY if the interface is up.
*/
static void ice_check_media_subtask(struct ice_pf *pf)
{
@@ -1423,15 +1984,12 @@ static void ice_check_media_subtask(struct ice_pf *pf)
struct ice_vsi *vsi;
int err;
- vsi = ice_get_main_vsi(pf);
- if (!vsi)
+ /* No need to check for media if it's already present */
+ if (!test_bit(ICE_FLAG_NO_MEDIA, pf->flags))
return;
- /* No need to check for media if it's already present or the interface
- * is down
- */
- if (!test_bit(ICE_FLAG_NO_MEDIA, pf->flags) ||
- test_bit(__ICE_DOWN, vsi->state))
+ vsi = ice_get_main_vsi(pf);
+ if (!vsi)
return;
/* Refresh link info and check if media is present */
@@ -1441,10 +1999,19 @@ static void ice_check_media_subtask(struct ice_pf *pf)
return;
if (pi->phy.link_info.link_info & ICE_AQ_MEDIA_AVAILABLE) {
- err = ice_force_phys_link_state(vsi, true);
- if (err)
+ if (!test_bit(__ICE_PHY_INIT_COMPLETE, pf->state))
+ ice_init_phy_user_cfg(pi);
+
+ /* PHY settings are reset on media insertion, reconfigure
+ * PHY to preserve settings.
+ */
+ if (test_bit(__ICE_DOWN, vsi->state) &&
+ test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags))
return;
- clear_bit(ICE_FLAG_NO_MEDIA, pf->flags);
+
+ err = ice_configure_phy(vsi);
+ if (!err)
+ clear_bit(ICE_FLAG_NO_MEDIA, pf->flags);
/* A Link Status Event will be generated; the event handler
* will complete bringing the interface up
@@ -1982,9 +2549,6 @@ static int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp)
switch (xdp->command) {
case XDP_SETUP_PROG:
return ice_xdp_setup_prog(vsi, xdp->prog, xdp->extack);
- case XDP_QUERY_PROG:
- xdp->prog_id = vsi->xdp_prog ? vsi->xdp_prog->aux->id : 0;
- return 0;
case XDP_SETUP_XSK_UMEM:
return ice_xsk_umem_setup(vsi, xdp->xsk.umem,
xdp->xsk.queue_id);
@@ -2779,6 +3343,10 @@ static int ice_init_pf(struct ice_pf *pf)
mutex_init(&pf->sw_mutex);
mutex_init(&pf->tc_mutex);
+ INIT_HLIST_HEAD(&pf->aq_wait_list);
+ spin_lock_init(&pf->aq_wait_lock);
+ init_waitqueue_head(&pf->aq_wait_queue);
+
/* setup service timer and periodic service task */
timer_setup(&pf->serv_tmr, ice_service_timer, 0);
pf->serv_tmr_period = HZ;
@@ -2949,6 +3517,27 @@ static int ice_init_interrupt_scheme(struct ice_pf *pf)
}
/**
+ * ice_is_wol_supported - get NVM state of WoL
+ * @pf: board private structure
+ *
+ * Check if WoL is supported based on the HW configuration.
+ * Returns true if NVM supports and enables WoL for this port, false otherwise
+ */
+bool ice_is_wol_supported(struct ice_pf *pf)
+{
+ struct ice_hw *hw = &pf->hw;
+ u16 wol_ctrl;
+
+ /* A bit set to 1 in the NVM Software Reserved Word 2 (WoL control
+ * word) indicates WoL is not supported on the corresponding PF ID.
+ */
+ if (ice_read_sr_word(hw, ICE_SR_NVM_WOL_CFG, &wol_ctrl))
+ return false;
+
+ return !(BIT(hw->pf_id) & wol_ctrl);
+}
+
+/**
* ice_vsi_recfg_qs - Change the number of queues on a VSI
* @vsi: VSI being changed
* @new_rx: new number of Rx queues
@@ -2995,6 +3584,60 @@ done:
}
/**
+ * ice_set_safe_mode_vlan_cfg - configure PF VSI to allow all VLANs in safe mode
+ * @pf: PF to configure
+ *
+ * No VLAN offloads/filtering are advertised in safe mode so make sure the PF
+ * VSI can still Tx/Rx VLAN tagged packets.
+ */
+static void ice_set_safe_mode_vlan_cfg(struct ice_pf *pf)
+{
+ struct ice_vsi *vsi = ice_get_main_vsi(pf);
+ struct ice_vsi_ctx *ctxt;
+ enum ice_status status;
+ struct ice_hw *hw;
+
+ if (!vsi)
+ return;
+
+ ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
+ if (!ctxt)
+ return;
+
+ hw = &pf->hw;
+ ctxt->info = vsi->info;
+
+ ctxt->info.valid_sections =
+ cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID |
+ ICE_AQ_VSI_PROP_SECURITY_VALID |
+ ICE_AQ_VSI_PROP_SW_VALID);
+
+ /* disable VLAN anti-spoof */
+ ctxt->info.sec_flags &= ~(ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA <<
+ ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S);
+
+ /* disable VLAN pruning and keep all other settings */
+ ctxt->info.sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
+
+ /* allow all VLANs on Tx and don't strip on Rx */
+ ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL |
+ ICE_AQ_VSI_VLAN_EMOD_NOTHING;
+
+ status = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
+ if (status) {
+ dev_err(ice_pf_to_dev(vsi->back), "Failed to update VSI for safe mode VLANs, err %s aq_err %s\n",
+ ice_stat_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ } else {
+ vsi->info.sec_flags = ctxt->info.sec_flags;
+ vsi->info.sw_flags2 = ctxt->info.sw_flags2;
+ vsi->info.vlan_flags = ctxt->info.vlan_flags;
+ }
+
+ kfree(ctxt);
+}
+
+/**
* ice_log_pkg_init - log result of DDP package load
* @hw: pointer to hardware info
* @status: status of package load
@@ -3168,11 +3811,11 @@ static enum ice_status ice_send_version(struct ice_pf *pf)
{
struct ice_driver_ver dv;
- dv.major_ver = DRV_VERSION_MAJOR;
- dv.minor_ver = DRV_VERSION_MINOR;
- dv.build_ver = DRV_VERSION_BUILD;
+ dv.major_ver = 0xff;
+ dv.minor_ver = 0xff;
+ dv.build_ver = 0xff;
dv.subbuild_ver = 0;
- strscpy((char *)dv.driver_string, DRV_VERSION,
+ strscpy((char *)dv.driver_string, UTS_RELEASE,
sizeof(dv.driver_string));
return ice_aq_send_driver_ver(&pf->hw, &dv, NULL);
}
@@ -3296,6 +3939,33 @@ dflt_pkg_load:
}
/**
+ * ice_print_wake_reason - show the wake up cause in the log
+ * @pf: pointer to the PF struct
+ */
+static void ice_print_wake_reason(struct ice_pf *pf)
+{
+ u32 wus = pf->wakeup_reason;
+ const char *wake_str;
+
+ /* if no wake event, nothing to print */
+ if (!wus)
+ return;
+
+ if (wus & PFPM_WUS_LNKC_M)
+ wake_str = "Link\n";
+ else if (wus & PFPM_WUS_MAG_M)
+ wake_str = "Magic Packet\n";
+ else if (wus & PFPM_WUS_MNG_M)
+ wake_str = "Management\n";
+ else if (wus & PFPM_WUS_FW_RST_WK_M)
+ wake_str = "Firmware Reset\n";
+ else
+ wake_str = "Unknown\n";
+
+ dev_info(ice_pf_to_dev(pf), "Wake reason: %s", wake_str);
+}
+
+/**
* ice_probe - Device initialization routine
* @pdev: PCI device information struct
* @ent: entry in ice_pci_tbl
@@ -3463,8 +4133,8 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
err = ice_send_version(pf);
if (err) {
dev_err(dev, "probe failed sending driver version %s. error: %d\n",
- ice_drv_ver, err);
- goto err_alloc_sw_unroll;
+ UTS_RELEASE, err);
+ goto err_send_version_unroll;
}
/* since everything is good, start the service timer */
@@ -3473,14 +4143,60 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
err = ice_init_link_events(pf->hw.port_info);
if (err) {
dev_err(dev, "ice_init_link_events failed: %d\n", err);
- goto err_alloc_sw_unroll;
+ goto err_send_version_unroll;
+ }
+
+ err = ice_init_nvm_phy_type(pf->hw.port_info);
+ if (err) {
+ dev_err(dev, "ice_init_nvm_phy_type failed: %d\n", err);
+ goto err_send_version_unroll;
+ }
+
+ err = ice_update_link_info(pf->hw.port_info);
+ if (err) {
+ dev_err(dev, "ice_update_link_info failed: %d\n", err);
+ goto err_send_version_unroll;
+ }
+
+ ice_init_link_dflt_override(pf->hw.port_info);
+
+ /* if media available, initialize PHY settings */
+ if (pf->hw.port_info->phy.link_info.link_info &
+ ICE_AQ_MEDIA_AVAILABLE) {
+ err = ice_init_phy_user_cfg(pf->hw.port_info);
+ if (err) {
+ dev_err(dev, "ice_init_phy_user_cfg failed: %d\n", err);
+ goto err_send_version_unroll;
+ }
+
+ if (!test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, pf->flags)) {
+ struct ice_vsi *vsi = ice_get_main_vsi(pf);
+
+ if (vsi)
+ ice_configure_phy(vsi);
+ }
+ } else {
+ set_bit(ICE_FLAG_NO_MEDIA, pf->flags);
}
ice_verify_cacheline_size(pf);
- /* If no DDP driven features have to be setup, we are done with probe */
- if (ice_is_safe_mode(pf))
+ /* Save wakeup reason register for later use */
+ pf->wakeup_reason = rd32(hw, PFPM_WUS);
+
+ /* check for a power management event */
+ ice_print_wake_reason(pf);
+
+ /* clear wake status, all bits */
+ wr32(hw, PFPM_WUS, U32_MAX);
+
+ /* Disable WoL at init, wait for user to enable */
+ device_set_wakeup_enable(dev, false);
+
+ if (ice_is_safe_mode(pf)) {
+ ice_set_safe_mode_vlan_cfg(pf);
goto probe_done;
+ }
/* initialize DDP driven features */
@@ -3504,6 +4220,8 @@ probe_done:
clear_bit(__ICE_DOWN, pf->state);
return 0;
+err_send_version_unroll:
+ ice_vsi_release_all(pf);
err_alloc_sw_unroll:
ice_devlink_destroy_port(pf);
set_bit(__ICE_SERVICE_DIS, pf->state);
@@ -3522,10 +4240,73 @@ err_init_pf_unroll:
err_exit_unroll:
ice_devlink_unregister(pf);
pci_disable_pcie_error_reporting(pdev);
+ pci_disable_device(pdev);
return err;
}
/**
+ * ice_set_wake - enable or disable Wake on LAN
+ * @pf: pointer to the PF struct
+ *
+ * Simple helper for WoL control
+ */
+static void ice_set_wake(struct ice_pf *pf)
+{
+ struct ice_hw *hw = &pf->hw;
+ bool wol = pf->wol_ena;
+
+ /* clear wake state, otherwise new wake events won't fire */
+ wr32(hw, PFPM_WUS, U32_MAX);
+
+ /* enable / disable APM wake up, no RMW needed */
+ wr32(hw, PFPM_APM, wol ? PFPM_APM_APME_M : 0);
+
+ /* set magic packet filter enabled */
+ wr32(hw, PFPM_WUFC, wol ? PFPM_WUFC_MAG_M : 0);
+}
+
+/**
+ * ice_setup_magic_mc_wake - setup device to wake on multicast magic packet
+ * @pf: pointer to the PF struct
+ *
+ * Issue firmware command to enable multicast magic wake, making
+ * sure that any locally administered address (LAA) is used for
+ * wake, and that PF reset doesn't undo the LAA.
+ */
+static void ice_setup_mc_magic_wake(struct ice_pf *pf)
+{
+ struct device *dev = ice_pf_to_dev(pf);
+ struct ice_hw *hw = &pf->hw;
+ enum ice_status status;
+ u8 mac_addr[ETH_ALEN];
+ struct ice_vsi *vsi;
+ u8 flags;
+
+ if (!pf->wol_ena)
+ return;
+
+ vsi = ice_get_main_vsi(pf);
+ if (!vsi)
+ return;
+
+ /* Get current MAC address in case it's an LAA */
+ if (vsi->netdev)
+ ether_addr_copy(mac_addr, vsi->netdev->dev_addr);
+ else
+ ether_addr_copy(mac_addr, vsi->port_info->mac.perm_addr);
+
+ flags = ICE_AQC_MAN_MAC_WR_MC_MAG_EN |
+ ICE_AQC_MAN_MAC_UPDATE_LAA_WOL |
+ ICE_AQC_MAN_MAC_WR_WOL_LAA_PFR_KEEP;
+
+ status = ice_aq_manage_mac_write(hw, mac_addr, flags, NULL);
+ if (status)
+ dev_err(dev, "Failed to enable Multicast Magic Packet wake, err %s aq_err %s\n",
+ ice_stat_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+}
+
+/**
* ice_remove - Device removal routine
* @pdev: PCI device information struct
*/
@@ -3551,11 +4332,15 @@ static void ice_remove(struct pci_dev *pdev)
set_bit(__ICE_DOWN, pf->state);
ice_service_task_stop(pf);
+ ice_aq_cancel_waiting_tasks(pf);
+
mutex_destroy(&(&pf->hw)->fdir_fltr_lock);
if (!ice_is_safe_mode(pf))
ice_remove_arfs(pf);
+ ice_setup_mc_magic_wake(pf);
ice_devlink_destroy_port(pf);
ice_vsi_release_all(pf);
+ ice_set_wake(pf);
ice_free_irq_msix_misc(pf);
ice_for_each_vsi(pf, i) {
if (!pf->vsi[i])
@@ -3575,9 +4360,231 @@ static void ice_remove(struct pci_dev *pdev)
pci_wait_for_pending_transaction(pdev);
ice_clear_interrupt_scheme(pf);
pci_disable_pcie_error_reporting(pdev);
+ pci_disable_device(pdev);
}
/**
+ * ice_shutdown - PCI callback for shutting down device
+ * @pdev: PCI device information struct
+ */
+static void ice_shutdown(struct pci_dev *pdev)
+{
+ struct ice_pf *pf = pci_get_drvdata(pdev);
+
+ ice_remove(pdev);
+
+ if (system_state == SYSTEM_POWER_OFF) {
+ pci_wake_from_d3(pdev, pf->wol_ena);
+ pci_set_power_state(pdev, PCI_D3hot);
+ }
+}
+
+#ifdef CONFIG_PM
+/**
+ * ice_prepare_for_shutdown - prep for PCI shutdown
+ * @pf: board private structure
+ *
+ * Inform or close all dependent features in prep for PCI device shutdown
+ */
+static void ice_prepare_for_shutdown(struct ice_pf *pf)
+{
+ struct ice_hw *hw = &pf->hw;
+ u32 v;
+
+ /* Notify VFs of impending reset */
+ if (ice_check_sq_alive(hw, &hw->mailboxq))
+ ice_vc_notify_reset(pf);
+
+ dev_dbg(ice_pf_to_dev(pf), "Tearing down internal switch for shutdown\n");
+
+ /* disable the VSIs and their queues that are not already DOWN */
+ ice_pf_dis_all_vsi(pf, false);
+
+ ice_for_each_vsi(pf, v)
+ if (pf->vsi[v])
+ pf->vsi[v]->vsi_num = 0;
+
+ ice_shutdown_all_ctrlq(hw);
+}
+
+/**
+ * ice_reinit_interrupt_scheme - Reinitialize interrupt scheme
+ * @pf: board private structure to reinitialize
+ *
+ * This routine reinitialize interrupt scheme that was cleared during
+ * power management suspend callback.
+ *
+ * This should be called during resume routine to re-allocate the q_vectors
+ * and reacquire interrupts.
+ */
+static int ice_reinit_interrupt_scheme(struct ice_pf *pf)
+{
+ struct device *dev = ice_pf_to_dev(pf);
+ int ret, v;
+
+ /* Since we clear MSIX flag during suspend, we need to
+ * set it back during resume...
+ */
+
+ ret = ice_init_interrupt_scheme(pf);
+ if (ret) {
+ dev_err(dev, "Failed to re-initialize interrupt %d\n", ret);
+ return ret;
+ }
+
+ /* Remap vectors and rings, after successful re-init interrupts */
+ ice_for_each_vsi(pf, v) {
+ if (!pf->vsi[v])
+ continue;
+
+ ret = ice_vsi_alloc_q_vectors(pf->vsi[v]);
+ if (ret)
+ goto err_reinit;
+ ice_vsi_map_rings_to_vectors(pf->vsi[v]);
+ }
+
+ ret = ice_req_irq_msix_misc(pf);
+ if (ret) {
+ dev_err(dev, "Setting up misc vector failed after device suspend %d\n",
+ ret);
+ goto err_reinit;
+ }
+
+ return 0;
+
+err_reinit:
+ while (v--)
+ if (pf->vsi[v])
+ ice_vsi_free_q_vectors(pf->vsi[v]);
+
+ return ret;
+}
+
+/**
+ * ice_suspend
+ * @dev: generic device information structure
+ *
+ * Power Management callback to quiesce the device and prepare
+ * for D3 transition.
+ */
+static int __maybe_unused ice_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ice_pf *pf;
+ int disabled, v;
+
+ pf = pci_get_drvdata(pdev);
+
+ if (!ice_pf_state_is_nominal(pf)) {
+ dev_err(dev, "Device is not ready, no need to suspend it\n");
+ return -EBUSY;
+ }
+
+ /* Stop watchdog tasks until resume completion.
+ * Even though it is most likely that the service task is
+ * disabled if the device is suspended or down, the service task's
+ * state is controlled by a different state bit, and we should
+ * store and honor whatever state that bit is in at this point.
+ */
+ disabled = ice_service_task_stop(pf);
+
+ /* Already suspended?, then there is nothing to do */
+ if (test_and_set_bit(__ICE_SUSPENDED, pf->state)) {
+ if (!disabled)
+ ice_service_task_restart(pf);
+ return 0;
+ }
+
+ if (test_bit(__ICE_DOWN, pf->state) ||
+ ice_is_reset_in_progress(pf->state)) {
+ dev_err(dev, "can't suspend device in reset or already down\n");
+ if (!disabled)
+ ice_service_task_restart(pf);
+ return 0;
+ }
+
+ ice_setup_mc_magic_wake(pf);
+
+ ice_prepare_for_shutdown(pf);
+
+ ice_set_wake(pf);
+
+ /* Free vectors, clear the interrupt scheme and release IRQs
+ * for proper hibernation, especially with large number of CPUs.
+ * Otherwise hibernation might fail when mapping all the vectors back
+ * to CPU0.
+ */
+ ice_free_irq_msix_misc(pf);
+ ice_for_each_vsi(pf, v) {
+ if (!pf->vsi[v])
+ continue;
+ ice_vsi_free_q_vectors(pf->vsi[v]);
+ }
+ ice_clear_interrupt_scheme(pf);
+
+ pci_wake_from_d3(pdev, pf->wol_ena);
+ pci_set_power_state(pdev, PCI_D3hot);
+ return 0;
+}
+
+/**
+ * ice_resume - PM callback for waking up from D3
+ * @dev: generic device information structure
+ */
+static int __maybe_unused ice_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ enum ice_reset_req reset_type;
+ struct ice_pf *pf;
+ struct ice_hw *hw;
+ int ret;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ pci_save_state(pdev);
+
+ if (!pci_device_is_present(pdev))
+ return -ENODEV;
+
+ ret = pci_enable_device_mem(pdev);
+ if (ret) {
+ dev_err(dev, "Cannot enable device after suspend\n");
+ return ret;
+ }
+
+ pf = pci_get_drvdata(pdev);
+ hw = &pf->hw;
+
+ pf->wakeup_reason = rd32(hw, PFPM_WUS);
+ ice_print_wake_reason(pf);
+
+ /* We cleared the interrupt scheme when we suspended, so we need to
+ * restore it now to resume device functionality.
+ */
+ ret = ice_reinit_interrupt_scheme(pf);
+ if (ret)
+ dev_err(dev, "Cannot restore interrupt scheme: %d\n", ret);
+
+ clear_bit(__ICE_DOWN, pf->state);
+ /* Now perform PF reset and rebuild */
+ reset_type = ICE_RESET_PFR;
+ /* re-enable service task for reset, but allow reset to schedule it */
+ clear_bit(__ICE_SERVICE_DIS, pf->state);
+
+ if (ice_schedule_reset(pf, reset_type))
+ dev_err(dev, "Reset during resume failed.\n");
+
+ clear_bit(__ICE_SUSPENDED, pf->state);
+ ice_service_task_restart(pf);
+
+ /* Restart the service task */
+ mod_timer(&pf->serv_tmr, round_jiffies(jiffies + pf->serv_tmr_period));
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+/**
* ice_pci_err_detected - warning that PCI error has been detected
* @pdev: PCI device information struct
* @err: the type of PCI error
@@ -3673,6 +4680,8 @@ static void ice_pci_err_resume(struct pci_dev *pdev)
return;
}
+ ice_restore_all_vfs_msi_state(pdev);
+
ice_do_reset(pf, ICE_RESET_PFR);
ice_service_task_restart(pf);
mod_timer(&pf->serv_tmr, round_jiffies(jiffies + pf->serv_tmr_period));
@@ -3742,6 +4751,8 @@ static const struct pci_device_id ice_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, ice_pci_tbl);
+static __maybe_unused SIMPLE_DEV_PM_OPS(ice_pm_ops, ice_suspend, ice_resume);
+
static const struct pci_error_handlers ice_pci_err_handler = {
.error_detected = ice_pci_err_detected,
.slot_reset = ice_pci_err_slot_reset,
@@ -3755,6 +4766,10 @@ static struct pci_driver ice_driver = {
.id_table = ice_pci_tbl,
.probe = ice_probe,
.remove = ice_remove,
+#ifdef CONFIG_PM
+ .driver.pm = &ice_pm_ops,
+#endif /* CONFIG_PM */
+ .shutdown = ice_shutdown,
.sriov_configure = ice_sriov_configure,
.err_handler = &ice_pci_err_handler
};
@@ -3769,7 +4784,7 @@ static int __init ice_module_init(void)
{
int status;
- pr_info("%s - version %s\n", ice_driver_string, ice_drv_ver);
+ pr_info("%s\n", ice_driver_string);
pr_info("%s\n", ice_copyright);
ice_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, KBUILD_MODNAME);
@@ -4275,6 +5290,7 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
vsi->tx_linearize = 0;
vsi->rx_buf_failed = 0;
vsi->rx_page_failed = 0;
+ vsi->rx_gro_dropped = 0;
rcu_read_lock();
@@ -4289,6 +5305,7 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
vsi_stats->rx_bytes += bytes;
vsi->rx_buf_failed += ring->rx_stats.alloc_buf_failed;
vsi->rx_page_failed += ring->rx_stats.alloc_page_failed;
+ vsi->rx_gro_dropped += ring->rx_stats.gro_dropped;
}
/* update XDP Tx rings counters */
@@ -4320,7 +5337,7 @@ void ice_update_vsi_stats(struct ice_vsi *vsi)
ice_update_eth_stats(vsi);
cur_ns->tx_errors = cur_es->tx_errors;
- cur_ns->rx_dropped = cur_es->rx_discards;
+ cur_ns->rx_dropped = cur_es->rx_discards + vsi->rx_gro_dropped;
cur_ns->tx_dropped = cur_es->tx_discards;
cur_ns->multicast = cur_es->rx_multicast;
@@ -4963,10 +5980,6 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
if (err)
goto err_sched_init_port;
- err = ice_update_link_info(hw->port_info);
- if (err)
- dev_err(dev, "Get link status error %d\n", err);
-
/* start misc vector */
err = ice_req_irq_msix_misc(pf);
if (err) {
@@ -5667,20 +6680,30 @@ int ice_open(struct net_device *netdev)
/* Set PHY if there is media, otherwise, turn off PHY */
if (pi->phy.link_info.link_info & ICE_AQ_MEDIA_AVAILABLE) {
- err = ice_force_phys_link_state(vsi, true);
+ clear_bit(ICE_FLAG_NO_MEDIA, pf->flags);
+ if (!test_bit(__ICE_PHY_INIT_COMPLETE, pf->state)) {
+ err = ice_init_phy_user_cfg(pi);
+ if (err) {
+ netdev_err(netdev, "Failed to initialize PHY settings, error %d\n",
+ err);
+ return err;
+ }
+ }
+
+ err = ice_configure_phy(vsi);
if (err) {
netdev_err(netdev, "Failed to set physical link up, error %d\n",
err);
return err;
}
} else {
+ set_bit(ICE_FLAG_NO_MEDIA, pf->flags);
err = ice_aq_set_link_restart_an(pi, false, NULL);
if (err) {
netdev_err(netdev, "Failed to set PHY state, VSI %d error %d\n",
vsi->vsi_num, err);
return err;
}
- set_bit(ICE_FLAG_NO_MEDIA, vsi->back->flags);
}
err = ice_vsi_open(vsi);
diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.c b/drivers/net/ethernet/intel/ice/ice_nvm.c
index b049c1c30c88..5903a36763de 100644
--- a/drivers/net/ethernet/intel/ice/ice_nvm.c
+++ b/drivers/net/ethernet/intel/ice/ice_nvm.c
@@ -108,6 +108,76 @@ ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
}
/**
+ * ice_aq_update_nvm
+ * @hw: pointer to the HW struct
+ * @module_typeid: module pointer location in words from the NVM beginning
+ * @offset: byte offset from the module beginning
+ * @length: length of the section to be written (in bytes from the offset)
+ * @data: command buffer (size [bytes] = length)
+ * @last_command: tells if this is the last command in a series
+ * @command_flags: command parameters
+ * @cd: pointer to command details structure or NULL
+ *
+ * Update the NVM using the admin queue commands (0x0703)
+ */
+enum ice_status
+ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
+ u16 length, void *data, bool last_command, u8 command_flags,
+ struct ice_sq_cd *cd)
+{
+ struct ice_aq_desc desc;
+ struct ice_aqc_nvm *cmd;
+
+ cmd = &desc.params.nvm;
+
+ /* In offset the highest byte must be zeroed. */
+ if (offset & 0xFF000000)
+ return ICE_ERR_PARAM;
+
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_write);
+
+ cmd->cmd_flags |= command_flags;
+
+ /* If this is the last command in a series, set the proper flag. */
+ if (last_command)
+ cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
+ cmd->module_typeid = cpu_to_le16(module_typeid);
+ cmd->offset_low = cpu_to_le16(offset & 0xFFFF);
+ cmd->offset_high = (offset >> 16) & 0xFF;
+ cmd->length = cpu_to_le16(length);
+
+ desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
+
+ return ice_aq_send_cmd(hw, &desc, data, length, cd);
+}
+
+/**
+ * ice_aq_erase_nvm
+ * @hw: pointer to the HW struct
+ * @module_typeid: module pointer location in words from the NVM beginning
+ * @cd: pointer to command details structure or NULL
+ *
+ * Erase the NVM sector using the admin queue commands (0x0702)
+ */
+enum ice_status
+ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd)
+{
+ struct ice_aq_desc desc;
+ struct ice_aqc_nvm *cmd;
+
+ cmd = &desc.params.nvm;
+
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_erase);
+
+ cmd->module_typeid = cpu_to_le16(module_typeid);
+ cmd->length = cpu_to_le16(ICE_AQC_NVM_ERASE_LEN);
+ cmd->offset_low = 0;
+ cmd->offset_high = 0;
+
+ return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
+}
+
+/**
* ice_read_sr_word_aq - Reads Shadow RAM via AQ
* @hw: pointer to the HW structure
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
@@ -172,8 +242,7 @@ void ice_release_nvm(struct ice_hw *hw)
*
* Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
*/
-static enum ice_status
-ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
+enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
{
enum ice_status status;
@@ -197,7 +266,7 @@ ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
* Area (PFA) and returns the TLV pointer and length. The caller can
* use these to read the variable length TLV value.
*/
-static enum ice_status
+enum ice_status
ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
u16 module_type)
{
@@ -635,3 +704,119 @@ enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw)
return status;
}
+
+/**
+ * ice_nvm_write_activate
+ * @hw: pointer to the HW struct
+ * @cmd_flags: NVM activate admin command bits (banks to be validated)
+ *
+ * Update the control word with the required banks' validity bits
+ * and dumps the Shadow RAM to flash (0x0707)
+ */
+enum ice_status ice_nvm_write_activate(struct ice_hw *hw, u8 cmd_flags)
+{
+ struct ice_aqc_nvm *cmd;
+ struct ice_aq_desc desc;
+
+ cmd = &desc.params.nvm;
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_write_activate);
+
+ cmd->cmd_flags = cmd_flags;
+
+ return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
+}
+
+/**
+ * ice_aq_nvm_update_empr
+ * @hw: pointer to the HW struct
+ *
+ * Update empr (0x0709). This command allows SW to
+ * request an EMPR to activate new FW.
+ */
+enum ice_status ice_aq_nvm_update_empr(struct ice_hw *hw)
+{
+ struct ice_aq_desc desc;
+
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_update_empr);
+
+ return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
+}
+
+/* ice_nvm_set_pkg_data
+ * @hw: pointer to the HW struct
+ * @del_pkg_data_flag: If is set then the current pkg_data store by FW
+ * is deleted.
+ * If bit is set to 1, then buffer should be size 0.
+ * @data: pointer to buffer
+ * @length: length of the buffer
+ * @cd: pointer to command details structure or NULL
+ *
+ * Set package data (0x070A). This command is equivalent to the reception
+ * of a PLDM FW Update GetPackageData cmd. This command should be sent
+ * as part of the NVM update as the first cmd in the flow.
+ */
+
+enum ice_status
+ice_nvm_set_pkg_data(struct ice_hw *hw, bool del_pkg_data_flag, u8 *data,
+ u16 length, struct ice_sq_cd *cd)
+{
+ struct ice_aqc_nvm_pkg_data *cmd;
+ struct ice_aq_desc desc;
+
+ if (length != 0 && !data)
+ return ICE_ERR_PARAM;
+
+ cmd = &desc.params.pkg_data;
+
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_pkg_data);
+ desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
+
+ if (del_pkg_data_flag)
+ cmd->cmd_flags |= ICE_AQC_NVM_PKG_DELETE;
+
+ return ice_aq_send_cmd(hw, &desc, data, length, cd);
+}
+
+/* ice_nvm_pass_component_tbl
+ * @hw: pointer to the HW struct
+ * @data: pointer to buffer
+ * @length: length of the buffer
+ * @transfer_flag: parameter for determining stage of the update
+ * @comp_response: a pointer to the response from the 0x070B AQC.
+ * @comp_response_code: a pointer to the response code from the 0x070B AQC.
+ * @cd: pointer to command details structure or NULL
+ *
+ * Pass component table (0x070B). This command is equivalent to the reception
+ * of a PLDM FW Update PassComponentTable cmd. This command should be sent once
+ * per component. It can be only sent after Set Package Data cmd and before
+ * actual update. FW will assume these commands are going to be sent until
+ * the TransferFlag is set to End or StartAndEnd.
+ */
+
+enum ice_status
+ice_nvm_pass_component_tbl(struct ice_hw *hw, u8 *data, u16 length,
+ u8 transfer_flag, u8 *comp_response,
+ u8 *comp_response_code, struct ice_sq_cd *cd)
+{
+ struct ice_aqc_nvm_pass_comp_tbl *cmd;
+ struct ice_aq_desc desc;
+ enum ice_status status;
+
+ if (!data || !comp_response || !comp_response_code)
+ return ICE_ERR_PARAM;
+
+ cmd = &desc.params.pass_comp_tbl;
+
+ ice_fill_dflt_direct_cmd_desc(&desc,
+ ice_aqc_opc_nvm_pass_component_tbl);
+ desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
+
+ cmd->transfer_flag = transfer_flag;
+ status = ice_aq_send_cmd(hw, &desc, data, length, cd);
+
+ if (!status) {
+ *comp_response = cmd->component_response;
+ *comp_response_code = cmd->component_response_code;
+ }
+ return status;
+}
diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.h b/drivers/net/ethernet/intel/ice/ice_nvm.h
index 165eda07b93d..8d430909f846 100644
--- a/drivers/net/ethernet/intel/ice/ice_nvm.h
+++ b/drivers/net/ethernet/intel/ice/ice_nvm.h
@@ -11,6 +11,26 @@ enum ice_status
ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
bool read_shadow_ram);
enum ice_status
+ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
+ u16 module_type);
+enum ice_status
ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size);
enum ice_status ice_init_nvm(struct ice_hw *hw);
+enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data);
+enum ice_status
+ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
+ u16 length, void *data, bool last_command, u8 command_flags,
+ struct ice_sq_cd *cd);
+enum ice_status
+ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd);
+enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw);
+enum ice_status ice_nvm_write_activate(struct ice_hw *hw, u8 cmd_flags);
+enum ice_status ice_aq_nvm_update_empr(struct ice_hw *hw);
+enum ice_status
+ice_nvm_set_pkg_data(struct ice_hw *hw, bool del_pkg_data_flag, u8 *data,
+ u16 length, struct ice_sq_cd *cd);
+enum ice_status
+ice_nvm_pass_component_tbl(struct ice_hw *hw, u8 *data, u16 length,
+ u8 transfer_flag, u8 *comp_response,
+ u8 *comp_response_code, struct ice_sq_cd *cd);
#endif /* _ICE_NVM_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c
index 0475134295e4..44a228530253 100644
--- a/drivers/net/ethernet/intel/ice/ice_sched.c
+++ b/drivers/net/ethernet/intel/ice/ice_sched.c
@@ -129,7 +129,7 @@ ice_aqc_send_sched_elem_cmd(struct ice_hw *hw, enum ice_adminq_opc cmd_opc,
*/
enum ice_status
ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req,
- struct ice_aqc_get_elem *buf, u16 buf_size,
+ struct ice_aqc_txsched_elem_data *buf, u16 buf_size,
u16 *elems_ret, struct ice_sq_cd *cd)
{
return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_get_sched_elems,
@@ -149,8 +149,8 @@ enum ice_status
ice_sched_add_node(struct ice_port_info *pi, u8 layer,
struct ice_aqc_txsched_elem_data *info)
{
+ struct ice_aqc_txsched_elem_data elem;
struct ice_sched_node *parent;
- struct ice_aqc_get_elem elem;
struct ice_sched_node *node;
enum ice_status status;
struct ice_hw *hw;
@@ -170,7 +170,7 @@ ice_sched_add_node(struct ice_port_info *pi, u8 layer,
return ICE_ERR_PARAM;
}
- /* query the current node information from FW before additing it
+ /* query the current node information from FW before adding it
* to the SW DB
*/
status = ice_sched_query_elem(hw, le32_to_cpu(info->node_teid), &elem);
@@ -195,7 +195,7 @@ ice_sched_add_node(struct ice_port_info *pi, u8 layer,
node->parent = parent;
node->tx_sched_layer = layer;
parent->children[parent->num_children++] = node;
- memcpy(&node->info, &elem.generic[0], sizeof(node->info));
+ node->info = elem;
return 0;
}
@@ -238,7 +238,7 @@ ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent,
enum ice_status status;
u16 buf_size;
- buf_size = sizeof(*buf) + sizeof(u32) * (num_nodes - 1);
+ buf_size = struct_size(buf, teid, num_nodes);
buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL);
if (!buf)
return ICE_ERR_NO_MEMORY;
@@ -423,7 +423,7 @@ ice_aq_add_sched_elems(struct ice_hw *hw, u16 grps_req,
*/
static enum ice_status
ice_aq_cfg_sched_elems(struct ice_hw *hw, u16 elems_req,
- struct ice_aqc_conf_elem *buf, u16 buf_size,
+ struct ice_aqc_txsched_elem_data *buf, u16 buf_size,
u16 *elems_cfgd, struct ice_sq_cd *cd)
{
return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_cfg_sched_elems,
@@ -443,8 +443,7 @@ ice_aq_cfg_sched_elems(struct ice_hw *hw, u16 elems_req,
* Suspend scheduling elements (0x0409)
*/
static enum ice_status
-ice_aq_suspend_sched_elems(struct ice_hw *hw, u16 elems_req,
- struct ice_aqc_suspend_resume_elem *buf,
+ice_aq_suspend_sched_elems(struct ice_hw *hw, u16 elems_req, __le32 *buf,
u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd)
{
return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_suspend_sched_elems,
@@ -464,8 +463,7 @@ ice_aq_suspend_sched_elems(struct ice_hw *hw, u16 elems_req,
* resume scheduling elements (0x040A)
*/
static enum ice_status
-ice_aq_resume_sched_elems(struct ice_hw *hw, u16 elems_req,
- struct ice_aqc_suspend_resume_elem *buf,
+ice_aq_resume_sched_elems(struct ice_hw *hw, u16 elems_req, __le32 *buf,
u16 buf_size, u16 *elems_ret, struct ice_sq_cd *cd)
{
return ice_aqc_send_sched_elem_cmd(hw, ice_aqc_opc_resume_sched_elems,
@@ -506,9 +504,9 @@ static enum ice_status
ice_sched_suspend_resume_elems(struct ice_hw *hw, u8 num_nodes, u32 *node_teids,
bool suspend)
{
- struct ice_aqc_suspend_resume_elem *buf;
u16 i, buf_size, num_elem_ret = 0;
enum ice_status status;
+ __le32 *buf;
buf_size = sizeof(*buf) * num_nodes;
buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL);
@@ -516,7 +514,7 @@ ice_sched_suspend_resume_elems(struct ice_hw *hw, u8 num_nodes, u32 *node_teids,
return ICE_ERR_NO_MEMORY;
for (i = 0; i < num_nodes; i++)
- buf->teid[i] = cpu_to_le32(node_teids[i]);
+ buf[i] = cpu_to_le32(node_teids[i]);
if (suspend)
status = ice_aq_suspend_sched_elems(hw, num_nodes, buf,
@@ -580,7 +578,7 @@ ice_alloc_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs)
/**
* ice_aq_rl_profile - performs a rate limiting task
* @hw: pointer to the HW struct
- * @opcode:opcode for add, query, or remove profile(s)
+ * @opcode: opcode for add, query, or remove profile(s)
* @num_profiles: the number of profiles
* @buf: pointer to buffer
* @buf_size: buffer size in bytes
@@ -591,7 +589,7 @@ ice_alloc_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs)
*/
static enum ice_status
ice_aq_rl_profile(struct ice_hw *hw, enum ice_adminq_opc opcode,
- u16 num_profiles, struct ice_aqc_rl_profile_generic_elem *buf,
+ u16 num_profiles, struct ice_aqc_rl_profile_elem *buf,
u16 buf_size, u16 *num_processed, struct ice_sq_cd *cd)
{
struct ice_aqc_rl_profile *cmd;
@@ -622,13 +620,11 @@ ice_aq_rl_profile(struct ice_hw *hw, enum ice_adminq_opc opcode,
*/
static enum ice_status
ice_aq_add_rl_profile(struct ice_hw *hw, u16 num_profiles,
- struct ice_aqc_rl_profile_generic_elem *buf,
- u16 buf_size, u16 *num_profiles_added,
- struct ice_sq_cd *cd)
+ struct ice_aqc_rl_profile_elem *buf, u16 buf_size,
+ u16 *num_profiles_added, struct ice_sq_cd *cd)
{
- return ice_aq_rl_profile(hw, ice_aqc_opc_add_rl_profiles,
- num_profiles, buf,
- buf_size, num_profiles_added, cd);
+ return ice_aq_rl_profile(hw, ice_aqc_opc_add_rl_profiles, num_profiles,
+ buf, buf_size, num_profiles_added, cd);
}
/**
@@ -644,13 +640,12 @@ ice_aq_add_rl_profile(struct ice_hw *hw, u16 num_profiles,
*/
static enum ice_status
ice_aq_remove_rl_profile(struct ice_hw *hw, u16 num_profiles,
- struct ice_aqc_rl_profile_generic_elem *buf,
- u16 buf_size, u16 *num_profiles_removed,
- struct ice_sq_cd *cd)
+ struct ice_aqc_rl_profile_elem *buf, u16 buf_size,
+ u16 *num_profiles_removed, struct ice_sq_cd *cd)
{
return ice_aq_rl_profile(hw, ice_aqc_opc_remove_rl_profiles,
- num_profiles, buf,
- buf_size, num_profiles_removed, cd);
+ num_profiles, buf, buf_size,
+ num_profiles_removed, cd);
}
/**
@@ -666,7 +661,7 @@ static enum ice_status
ice_sched_del_rl_profile(struct ice_hw *hw,
struct ice_aqc_rl_profile_info *rl_info)
{
- struct ice_aqc_rl_profile_generic_elem *buf;
+ struct ice_aqc_rl_profile_elem *buf;
u16 num_profiles_removed;
enum ice_status status;
u16 num_profiles = 1;
@@ -675,8 +670,7 @@ ice_sched_del_rl_profile(struct ice_hw *hw,
return ICE_ERR_IN_USE;
/* Safe to remove profile ID */
- buf = (struct ice_aqc_rl_profile_generic_elem *)
- &rl_info->profile;
+ buf = &rl_info->profile;
status = ice_aq_remove_rl_profile(hw, num_profiles, buf, sizeof(*buf),
&num_profiles_removed, NULL);
if (status || num_profiles_removed != num_profiles)
@@ -831,7 +825,7 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
size_t buf_size;
u32 teid;
- buf_size = struct_size(buf, generic, num_nodes - 1);
+ buf_size = struct_size(buf, generic, num_nodes);
buf = devm_kzalloc(ice_hw_to_dev(hw), buf_size, GFP_KERNEL);
if (!buf)
return ICE_ERR_NO_MEMORY;
@@ -1282,6 +1276,53 @@ ice_sched_find_node_in_subtree(struct ice_hw *hw, struct ice_sched_node *base,
}
/**
+ * ice_sched_get_free_qgrp - Scan all queue group siblings and find a free node
+ * @pi: port information structure
+ * @vsi_node: software VSI handle
+ * @qgrp_node: first queue group node identified for scanning
+ * @owner: LAN or RDMA
+ *
+ * This function retrieves a free LAN or RDMA queue group node by scanning
+ * qgrp_node and its siblings for the queue group with the fewest number
+ * of queues currently assigned.
+ */
+static struct ice_sched_node *
+ice_sched_get_free_qgrp(struct ice_port_info *pi,
+ struct ice_sched_node *vsi_node,
+ struct ice_sched_node *qgrp_node, u8 owner)
+{
+ struct ice_sched_node *min_qgrp;
+ u8 min_children;
+
+ if (!qgrp_node)
+ return qgrp_node;
+ min_children = qgrp_node->num_children;
+ if (!min_children)
+ return qgrp_node;
+ min_qgrp = qgrp_node;
+ /* scan all queue groups until find a node which has less than the
+ * minimum number of children. This way all queue group nodes get
+ * equal number of shares and active. The bandwidth will be equally
+ * distributed across all queues.
+ */
+ while (qgrp_node) {
+ /* make sure the qgroup node is part of the VSI subtree */
+ if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node))
+ if (qgrp_node->num_children < min_children &&
+ qgrp_node->owner == owner) {
+ /* replace the new min queue group node */
+ min_qgrp = qgrp_node;
+ min_children = min_qgrp->num_children;
+ /* break if it has no children, */
+ if (!min_children)
+ break;
+ }
+ qgrp_node = qgrp_node->sibling;
+ }
+ return min_qgrp;
+}
+
+/**
* ice_sched_get_free_qparent - Get a free LAN or RDMA queue group node
* @pi: port information structure
* @vsi_handle: software VSI handle
@@ -1294,7 +1335,7 @@ struct ice_sched_node *
ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
u8 owner)
{
- struct ice_sched_node *vsi_node, *qgrp_node = NULL;
+ struct ice_sched_node *vsi_node, *qgrp_node;
struct ice_vsi_ctx *vsi_ctx;
u16 max_children;
u8 qgrp_layer;
@@ -1308,7 +1349,7 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
vsi_node = vsi_ctx->sched.vsi_node[tc];
/* validate invalid VSI ID */
if (!vsi_node)
- goto lan_q_exit;
+ return NULL;
/* get the first queue group node from VSI sub-tree */
qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer);
@@ -1321,8 +1362,8 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
qgrp_node = qgrp_node->sibling;
}
-lan_q_exit:
- return qgrp_node;
+ /* Select the best queue group */
+ return ice_sched_get_free_qgrp(pi, vsi_node, qgrp_node, owner);
}
/**
@@ -1867,7 +1908,7 @@ static void ice_sched_rm_unused_rl_prof(struct ice_port_info *pi)
* @node: pointer to node
* @info: node info to update
*
- * It updates the HW DB, and local SW DB of node. It updates the scheduling
+ * Update the HW DB, and local SW DB of node. Update the scheduling
* parameters of node from argument info data buffer (Info->data buf) and
* returns success or error on config sched element failure. The caller
* needs to hold scheduler lock.
@@ -1876,18 +1917,18 @@ static enum ice_status
ice_sched_update_elem(struct ice_hw *hw, struct ice_sched_node *node,
struct ice_aqc_txsched_elem_data *info)
{
- struct ice_aqc_conf_elem buf;
+ struct ice_aqc_txsched_elem_data buf;
enum ice_status status;
u16 elem_cfgd = 0;
u16 num_elems = 1;
- buf.generic[0] = *info;
+ buf = *info;
/* Parent TEID is reserved field in this aq call */
- buf.generic[0].parent_teid = 0;
+ buf.parent_teid = 0;
/* Element type is reserved field in this aq call */
- buf.generic[0].data.elem_type = 0;
+ buf.data.elem_type = 0;
/* Flags is reserved field in this aq call */
- buf.generic[0].data.flags = 0;
+ buf.data.flags = 0;
/* Update HW DB */
/* Configure element node */
@@ -2131,9 +2172,9 @@ static struct ice_aqc_rl_profile_info *
ice_sched_add_rl_profile(struct ice_port_info *pi,
enum ice_rl_type rl_type, u32 bw, u8 layer_num)
{
- struct ice_aqc_rl_profile_generic_elem *buf;
struct ice_aqc_rl_profile_info *rl_prof_elem;
u16 profiles_added = 0, num_profiles = 1;
+ struct ice_aqc_rl_profile_elem *buf;
enum ice_status status;
struct ice_hw *hw;
u8 profile_type;
@@ -2159,8 +2200,8 @@ ice_sched_add_rl_profile(struct ice_port_info *pi,
hw = pi->hw;
list_for_each_entry(rl_prof_elem, &pi->rl_prof_list[layer_num],
list_entry)
- if (rl_prof_elem->profile.flags == profile_type &&
- rl_prof_elem->bw == bw)
+ if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) ==
+ profile_type && rl_prof_elem->bw == bw)
/* Return existing profile ID info */
return rl_prof_elem;
@@ -2182,8 +2223,7 @@ ice_sched_add_rl_profile(struct ice_port_info *pi,
rl_prof_elem->profile.max_burst_size = cpu_to_le16(hw->max_burst_size);
/* Create new entry in HW DB */
- buf = (struct ice_aqc_rl_profile_generic_elem *)
- &rl_prof_elem->profile;
+ buf = &rl_prof_elem->profile;
status = ice_aq_add_rl_profile(hw, num_profiles, buf, sizeof(*buf),
&profiles_added, NULL);
if (status || profiles_added != num_profiles)
@@ -2391,7 +2431,8 @@ ice_sched_rm_rl_profile(struct ice_port_info *pi, u8 layer_num, u8 profile_type,
/* Check the existing list for RL profile */
list_for_each_entry(rl_prof_elem, &pi->rl_prof_list[layer_num],
list_entry)
- if (rl_prof_elem->profile.flags == profile_type &&
+ if ((rl_prof_elem->profile.flags & ICE_AQC_RL_PROFILE_TYPE_M) ==
+ profile_type &&
le16_to_cpu(rl_prof_elem->profile.profile_id) ==
profile_id) {
if (rl_prof_elem->prof_id_ref)
@@ -2553,8 +2594,8 @@ ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node,
return 0;
return ice_sched_rm_rl_profile(pi, layer_num,
- rl_prof_info->profile.flags,
- old_id);
+ rl_prof_info->profile.flags &
+ ICE_AQC_RL_PROFILE_TYPE_M, old_id);
}
/**
diff --git a/drivers/net/ethernet/intel/ice/ice_sched.h b/drivers/net/ethernet/intel/ice/ice_sched.h
index f0593cfb6521..0e55ae0d446f 100644
--- a/drivers/net/ethernet/intel/ice/ice_sched.h
+++ b/drivers/net/ethernet/intel/ice/ice_sched.h
@@ -56,7 +56,7 @@ struct ice_sched_agg_info {
/* FW AQ command calls */
enum ice_status
ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req,
- struct ice_aqc_get_elem *buf, u16 buf_size,
+ struct ice_aqc_txsched_elem_data *buf, u16 buf_size,
u16 *elems_ret, struct ice_sq_cd *cd);
enum ice_status ice_sched_init_port(struct ice_port_info *pi);
enum ice_status ice_sched_query_res_alloc(struct ice_hw *hw);
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
index ff7d16ac693e..c3a6c41385ee 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
@@ -29,25 +29,17 @@ static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
0x81, 0, 0, 0};
#define ICE_SW_RULE_RX_TX_ETH_HDR_SIZE \
- (sizeof(struct ice_aqc_sw_rules_elem) - \
- sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \
- sizeof(struct ice_sw_rule_lkup_rx_tx) + DUMMY_ETH_HDR_LEN - 1)
+ (offsetof(struct ice_aqc_sw_rules_elem, pdata.lkup_tx_rx.hdr) + \
+ (DUMMY_ETH_HDR_LEN * \
+ sizeof(((struct ice_sw_rule_lkup_rx_tx *)0)->hdr[0])))
#define ICE_SW_RULE_RX_TX_NO_HDR_SIZE \
- (sizeof(struct ice_aqc_sw_rules_elem) - \
- sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \
- sizeof(struct ice_sw_rule_lkup_rx_tx) - 1)
+ (offsetof(struct ice_aqc_sw_rules_elem, pdata.lkup_tx_rx.hdr))
#define ICE_SW_RULE_LG_ACT_SIZE(n) \
- (sizeof(struct ice_aqc_sw_rules_elem) - \
- sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \
- sizeof(struct ice_sw_rule_lg_act) - \
- sizeof(((struct ice_sw_rule_lg_act *)0)->act) + \
- ((n) * sizeof(((struct ice_sw_rule_lg_act *)0)->act)))
+ (offsetof(struct ice_aqc_sw_rules_elem, pdata.lg_act.act) + \
+ ((n) * sizeof(((struct ice_sw_rule_lg_act *)0)->act[0])))
#define ICE_SW_RULE_VSI_LIST_SIZE(n) \
- (sizeof(struct ice_aqc_sw_rules_elem) - \
- sizeof(((struct ice_aqc_sw_rules_elem *)0)->pdata) + \
- sizeof(struct ice_sw_rule_vsi_list) - \
- sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi) + \
- ((n) * sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi)))
+ (offsetof(struct ice_aqc_sw_rules_elem, pdata.vsi_list.vsi) + \
+ ((n) * sizeof(((struct ice_sw_rule_vsi_list *)0)->vsi[0])))
/**
* ice_init_def_sw_recp - initialize the recipe book keeping tables
@@ -87,7 +79,7 @@ enum ice_status ice_init_def_sw_recp(struct ice_hw *hw)
* @num_elems: pointer to number of elements
* @cd: pointer to command details structure or NULL
*
- * Get switch configuration (0x0200) to be placed in 'buff'.
+ * Get switch configuration (0x0200) to be placed in buf.
* This admin command returns information such as initial VSI/port number
* and switch ID it belongs to.
*
@@ -104,13 +96,13 @@ enum ice_status ice_init_def_sw_recp(struct ice_hw *hw)
* parsing the response buffer.
*/
static enum ice_status
-ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp *buf,
+ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
u16 buf_size, u16 *req_desc, u16 *num_elems,
struct ice_sq_cd *cd)
{
struct ice_aqc_get_sw_cfg *cmd;
- enum ice_status status;
struct ice_aq_desc desc;
+ enum ice_status status;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
cmd = &desc.params.get_sw_conf;
@@ -449,7 +441,7 @@ ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
enum ice_status status;
u16 buf_len;
- buf_len = sizeof(*sw_buf);
+ buf_len = struct_size(sw_buf, elem, 1);
sw_buf = devm_kzalloc(ice_hw_to_dev(hw), buf_len, GFP_KERNEL);
if (!sw_buf)
return ICE_ERR_NO_MEMORY;
@@ -503,6 +495,7 @@ ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
{
struct ice_aq_desc desc;
+ enum ice_status status;
if (opc != ice_aqc_opc_add_sw_rules &&
opc != ice_aqc_opc_update_sw_rules &&
@@ -514,7 +507,12 @@ ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
desc.params.sw_rules.num_rules_fltr_entry_index =
cpu_to_le16(num_rules);
- return ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
+ status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
+ if (opc != ice_aqc_opc_add_sw_rules &&
+ hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
+ status = ICE_ERR_DOES_NOT_EXIST;
+
+ return status;
}
/* ice_init_port_info - Initialize port_info with switch configuration data
@@ -550,7 +548,7 @@ ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
*/
enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
{
- struct ice_aqc_get_sw_cfg_resp *rbuf;
+ struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
enum ice_status status;
u16 req_desc = 0;
u16 num_elems;
@@ -568,19 +566,19 @@ enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
* writing a non-zero value in req_desc
*/
do {
+ struct ice_aqc_get_sw_cfg_resp_elem *ele;
+
status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
&req_desc, &num_elems, NULL);
if (status)
break;
- for (i = 0; i < num_elems; i++) {
- struct ice_aqc_get_sw_cfg_resp_elem *ele;
+ for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
u16 pf_vf_num, swid, vsi_port_num;
bool is_vf = false;
u8 res_type;
- ele = rbuf[i].elements;
vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
@@ -856,8 +854,7 @@ ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
m_ent->fltr_info.fwd_id.hw_vsi_id;
act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
- act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) &
- ICE_LG_ACT_VSI_LIST_ID_M;
+ act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M;
if (m_ent->vsi_count > 1)
act |= ICE_LG_ACT_VSI_LIST;
lg_act->pdata.lg_act.act[0] = cpu_to_le32(act);
@@ -2037,7 +2034,8 @@ ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_handle, bool set, u8 direction)
hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
- ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
+ ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
+
s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
if (!s_rule)
return ICE_ERR_NO_MEMORY;
@@ -2691,7 +2689,7 @@ ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
u16 buf_len;
/* Allocate resource */
- buf_len = sizeof(*buf);
+ buf_len = struct_size(buf, elem, 1);
buf = kzalloc(buf_len, GFP_KERNEL);
if (!buf)
return ICE_ERR_NO_MEMORY;
@@ -2729,7 +2727,7 @@ ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
u16 buf_len;
/* Free resource */
- buf_len = sizeof(*buf);
+ buf_len = struct_size(buf, elem, 1);
buf = kzalloc(buf_len, GFP_KERNEL);
if (!buf)
return ICE_ERR_NO_MEMORY;
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
index abdb137c8bb7..9d0d6b0025cf 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
@@ -509,8 +509,8 @@ static unsigned int ice_rx_offset(struct ice_ring *rx_ring)
return 0;
}
-static unsigned int ice_rx_frame_truesize(struct ice_ring *rx_ring,
- unsigned int size)
+static unsigned int
+ice_rx_frame_truesize(struct ice_ring *rx_ring, unsigned int __maybe_unused size)
{
unsigned int truesize;
@@ -631,10 +631,8 @@ ice_alloc_mapped_page(struct ice_ring *rx_ring, struct ice_rx_buf *bi)
dma_addr_t dma;
/* since we are recycling buffers we should seldom need to alloc */
- if (likely(page)) {
- rx_ring->rx_stats.page_reuse_count++;
+ if (likely(page))
return true;
- }
/* alloc new page for storage */
page = dev_alloc_pages(ice_rx_pg_order(rx_ring));
@@ -1033,7 +1031,6 @@ static void ice_put_rx_buf(struct ice_ring *rx_ring, struct ice_rx_buf *rx_buf)
if (ice_can_reuse_rx_page(rx_buf)) {
/* hand second half of page back to the ring */
ice_reuse_rx_page(rx_ring, rx_buf);
- rx_ring->rx_stats.page_reuse_count++;
} else {
/* we are not reusing the buffer so unmap it */
dma_unmap_page_attrs(rx_ring->dev, rx_buf->dma,
@@ -1254,12 +1251,12 @@ construct_skb:
* @itr: ITR value to update
*
* Calculate how big of an increment should be applied to the ITR value passed
- * in based on wmem_default, SKB overhead, Ethernet overhead, and the current
+ * in based on wmem_default, SKB overhead, ethernet overhead, and the current
* link speed.
*
* The following is a calculation derived from:
* wmem_default / (size + overhead) = desired_pkts_per_int
- * rate / bits_per_byte / (size + Ethernet overhead) = pkt_rate
+ * rate / bits_per_byte / (size + ethernet overhead) = pkt_rate
* (desired_pkt_rate / pkt_rate) * usecs_per_sec = ITR value
*
* Assuming wmem_default is 212992 and overhead is 640 bytes per
@@ -2294,10 +2291,30 @@ static bool __ice_chk_linearize(struct sk_buff *skb)
/* Walk through fragments adding latest fragment, testing it, and
* then removing stale fragments from the sum.
*/
- stale = &skb_shinfo(skb)->frags[0];
- for (;;) {
+ for (stale = &skb_shinfo(skb)->frags[0];; stale++) {
+ int stale_size = skb_frag_size(stale);
+
sum += skb_frag_size(frag++);
+ /* The stale fragment may present us with a smaller
+ * descriptor than the actual fragment size. To account
+ * for that we need to remove all the data on the front and
+ * figure out what the remainder would be in the last
+ * descriptor associated with the fragment.
+ */
+ if (stale_size > ICE_MAX_DATA_PER_TXD) {
+ int align_pad = -(skb_frag_off(stale)) &
+ (ICE_MAX_READ_REQ_SIZE - 1);
+
+ sum -= align_pad;
+ stale_size -= align_pad;
+
+ do {
+ sum -= ICE_MAX_DATA_PER_TXD_ALIGNED;
+ stale_size -= ICE_MAX_DATA_PER_TXD_ALIGNED;
+ } while (stale_size > ICE_MAX_DATA_PER_TXD);
+ }
+
/* if sum is negative we failed to make sufficient progress */
if (sum < 0)
return true;
@@ -2305,7 +2322,7 @@ static bool __ice_chk_linearize(struct sk_buff *skb)
if (!nr_frags--)
break;
- sum -= skb_frag_size(stale++);
+ sum -= stale_size;
}
return false;
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
index e70c4619edc3..51b4df7a59d2 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
@@ -193,7 +193,7 @@ struct ice_rxq_stats {
u64 non_eop_descs;
u64 alloc_page_failed;
u64 alloc_buf_failed;
- u64 page_reuse_count;
+ u64 gro_dropped; /* GRO returned dropped */
};
/* this enum matches hardware bits and is meant to be used by DYN_CTLN
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
index 02b12736ea80..bc2f4390b51d 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
@@ -191,7 +191,12 @@ ice_receive_skb(struct ice_ring *rx_ring, struct sk_buff *skb, u16 vlan_tag)
if ((rx_ring->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
(vlan_tag & VLAN_VID_MASK))
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
- napi_gro_receive(&rx_ring->q_vector->napi, skb);
+ if (napi_gro_receive(&rx_ring->q_vector->napi, skb) == GRO_DROP) {
+ /* this is tracked separately to help us debug stack drops */
+ rx_ring->rx_stats.gro_dropped++;
+ netdev_dbg(rx_ring->netdev, "Receive Queue %d: Dropped packet from GRO\n",
+ rx_ring->q_index);
+ }
}
/**
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
index c1ad8622e65c..4cdccfadf274 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -87,6 +87,12 @@ enum ice_fc_mode {
ICE_FC_DFLT
};
+enum ice_phy_cache_mode {
+ ICE_FC_MODE = 0,
+ ICE_SPEED_MODE,
+ ICE_FEC_MODE
+};
+
enum ice_fec_mode {
ICE_FEC_NONE = 0,
ICE_FEC_RS,
@@ -94,6 +100,14 @@ enum ice_fec_mode {
ICE_FEC_AUTO
};
+struct ice_phy_cache_mode_data {
+ union {
+ enum ice_fec_mode curr_user_fec_req;
+ enum ice_fc_mode curr_user_fc_req;
+ u16 curr_user_speed_req;
+ } data;
+};
+
enum ice_set_fc_aq_failures {
ICE_SET_FC_AQ_FAIL_NONE = 0,
ICE_SET_FC_AQ_FAIL_GET,
@@ -104,6 +118,7 @@ enum ice_set_fc_aq_failures {
/* Various MAC types */
enum ice_mac_type {
ICE_MAC_UNKNOWN = 0,
+ ICE_MAC_E810,
ICE_MAC_GENERIC,
};
@@ -160,6 +175,13 @@ struct ice_phy_info {
u64 phy_type_high;
enum ice_media_type media_type;
u8 get_link_info;
+ /* Please refer to struct ice_aqc_get_link_status_data to get
+ * detail of enable bit in curr_user_speed_req
+ */
+ u16 curr_user_speed_req;
+ enum ice_fec_mode curr_user_fec_req;
+ enum ice_fc_mode curr_user_fc_req;
+ struct ice_aqc_set_phy_cfg_data curr_user_phy_cfg;
};
/* protocol enumeration for filters */
@@ -222,6 +244,15 @@ struct ice_hw_common_caps {
u8 rss_table_entry_width; /* RSS Entry width in bits */
u8 dcb;
+
+ bool nvm_update_pending_nvm;
+ bool nvm_update_pending_orom;
+ bool nvm_update_pending_netlist;
+#define ICE_NVM_PENDING_NVM_IMAGE BIT(0)
+#define ICE_NVM_PENDING_OROM BIT(1)
+#define ICE_NVM_PENDING_NETLIST BIT(2)
+ bool nvm_unified_update;
+#define ICE_NVM_MGMT_UNIFIED_UPD_SUPPORT BIT(3)
};
/* Function specific capabilities */
@@ -290,7 +321,29 @@ struct ice_nvm_info {
u32 flash_size; /* Size of available flash in bytes */
u8 major_ver; /* major version of NVM package */
u8 minor_ver; /* minor version of dev starter */
- u8 blank_nvm_mode; /* is NVM empty (no FW present) */
+ u8 blank_nvm_mode; /* is NVM empty (no FW present) */
+};
+
+struct ice_link_default_override_tlv {
+ u8 options;
+#define ICE_LINK_OVERRIDE_OPT_M 0x3F
+#define ICE_LINK_OVERRIDE_STRICT_MODE BIT(0)
+#define ICE_LINK_OVERRIDE_EPCT_DIS BIT(1)
+#define ICE_LINK_OVERRIDE_PORT_DIS BIT(2)
+#define ICE_LINK_OVERRIDE_EN BIT(3)
+#define ICE_LINK_OVERRIDE_AUTO_LINK_DIS BIT(4)
+#define ICE_LINK_OVERRIDE_EEE_EN BIT(5)
+ u8 phy_config;
+#define ICE_LINK_OVERRIDE_PHY_CFG_S 8
+#define ICE_LINK_OVERRIDE_PHY_CFG_M (0xC3 << ICE_LINK_OVERRIDE_PHY_CFG_S)
+#define ICE_LINK_OVERRIDE_PAUSE_M 0x3
+#define ICE_LINK_OVERRIDE_LESM_EN BIT(6)
+#define ICE_LINK_OVERRIDE_AUTO_FEC_EN BIT(7)
+ u8 fec_options;
+#define ICE_LINK_OVERRIDE_FEC_OPT_M 0xFF
+ u8 rsvd1;
+ u64 phy_type_low;
+ u64 phy_type_high;
};
#define ICE_NVM_VER_LEN 32
@@ -356,7 +409,7 @@ enum ice_rl_type {
#define ICE_SCHED_DFLT_BW 0xFFFFFFFF /* unlimited */
#define ICE_SCHED_DFLT_RL_PROF_ID 0
#define ICE_SCHED_NO_SHARED_RL_PROF_ID 0xFFFF
-#define ICE_SCHED_DFLT_BW_WT 1
+#define ICE_SCHED_DFLT_BW_WT 4
#define ICE_SCHED_INVAL_PROF_ID 0xFFFF
#define ICE_SCHED_DFLT_BURST_SIZE (15 * 1024) /* in bytes (15k) */
@@ -444,6 +497,7 @@ struct ice_dcb_app_priority_table {
#define ICE_APP_SEL_ETHTYPE 0x1
#define ICE_APP_SEL_TCPIP 0x2
#define ICE_CEE_APP_SEL_ETHTYPE 0x0
+#define ICE_SR_LINK_DEFAULT_OVERRIDE_PTR 0x134
#define ICE_CEE_APP_SEL_TCPIP 0x1
struct ice_dcbx_cfg {
@@ -709,6 +763,7 @@ struct ice_hw_port_stats {
/* Checksum and Shadow RAM pointers */
#define ICE_SR_BOOT_CFG_PTR 0x132
+#define ICE_SR_NVM_WOL_CFG 0x19
#define ICE_NVM_OROM_VER_OFF 0x02
#define ICE_SR_PBA_BLOCK_PTR 0x16
#define ICE_SR_NVM_DEV_STARTER_VER 0x18
@@ -725,7 +780,21 @@ struct ice_hw_port_stats {
#define ICE_OROM_VER_SHIFT 24
#define ICE_OROM_VER_MASK (0xff << ICE_OROM_VER_SHIFT)
#define ICE_SR_PFA_PTR 0x40
+#define ICE_SR_1ST_NVM_BANK_PTR 0x42
+#define ICE_SR_1ST_OROM_BANK_PTR 0x44
+#define ICE_SR_NETLIST_BANK_PTR 0x46
#define ICE_SR_SECTOR_SIZE_IN_WORDS 0x800
+
+/* Link override related */
+#define ICE_SR_PFA_LINK_OVERRIDE_WORDS 10
+#define ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS 4
+#define ICE_SR_PFA_LINK_OVERRIDE_OFFSET 2
+#define ICE_SR_PFA_LINK_OVERRIDE_FEC_OFFSET 1
+#define ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET 2
+#define ICE_FW_API_LINK_OVERRIDE_MAJ 1
+#define ICE_FW_API_LINK_OVERRIDE_MIN 5
+#define ICE_FW_API_LINK_OVERRIDE_PATCH 2
+
#define ICE_SR_WORDS_IN_1KB 512
/* Hash redirection LUT for VSI - maximum array size */
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
index 16a2f2526ccc..71497776ac62 100644
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
@@ -932,6 +932,8 @@ static int ice_set_per_vf_res(struct ice_pf *pf)
num_msix_per_vf = ICE_NUM_VF_MSIX_MED;
} else if (msix_avail_per_vf >= ICE_NUM_VF_MSIX_SMALL) {
num_msix_per_vf = ICE_NUM_VF_MSIX_SMALL;
+ } else if (msix_avail_per_vf >= ICE_NUM_VF_MSIX_MULTIQ_MIN) {
+ num_msix_per_vf = ICE_NUM_VF_MSIX_MULTIQ_MIN;
} else if (msix_avail_per_vf >= ICE_MIN_INTR_PER_VF) {
num_msix_per_vf = ICE_MIN_INTR_PER_VF;
} else {
@@ -1593,31 +1595,6 @@ err_unroll_intr:
}
/**
- * ice_pf_state_is_nominal - checks the PF for nominal state
- * @pf: pointer to PF to check
- *
- * Check the PF's state for a collection of bits that would indicate
- * the PF is in a state that would inhibit normal operation for
- * driver functionality.
- *
- * Returns true if PF is in a nominal state.
- * Returns false otherwise
- */
-static bool ice_pf_state_is_nominal(struct ice_pf *pf)
-{
- DECLARE_BITMAP(check_bits, __ICE_STATE_NBITS) = { 0 };
-
- if (!pf)
- return false;
-
- bitmap_set(check_bits, 0, __ICE_STATE_NOMINAL_CHECK_BITS);
- if (bitmap_intersects(pf->state, check_bits, __ICE_STATE_NBITS))
- return false;
-
- return true;
-}
-
-/**
* ice_pci_sriov_ena - Enable or change number of VFs
* @pf: pointer to the PF structure
* @num_vfs: number of VFs to allocate
@@ -2997,8 +2974,8 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
vsi->max_frame = qpi->rxq.max_pkt_size;
}
- /* VF can request to configure less than allocated queues
- * or default allocated queues. So update the VSI with new number
+ /* VF can request to configure less than allocated queues or default
+ * allocated queues. So update the VSI with new number
*/
vsi->num_txq = num_txq;
vsi->num_rxq = num_rxq;
@@ -4096,3 +4073,33 @@ void ice_print_vfs_mdd_events(struct ice_pf *pf)
}
}
}
+
+/**
+ * ice_restore_all_vfs_msi_state - restore VF MSI state after PF FLR
+ * @pdev: pointer to a pci_dev structure
+ *
+ * Called when recovering from a PF FLR to restore interrupt capability to
+ * the VFs.
+ */
+void ice_restore_all_vfs_msi_state(struct pci_dev *pdev)
+{
+ struct pci_dev *vfdev;
+ u16 vf_id;
+ int pos;
+
+ if (!pci_num_vf(pdev))
+ return;
+
+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
+ if (pos) {
+ pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID,
+ &vf_id);
+ vfdev = pci_get_device(pdev->vendor, vf_id, NULL);
+ while (vfdev) {
+ if (vfdev->is_virtfn && vfdev->physfn == pdev)
+ pci_restore_msi_state(vfdev);
+ vfdev = pci_get_device(pdev->vendor, vf_id,
+ vfdev);
+ }
+ }
+}
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h
index 67aa9110fdd1..0f519fba3770 100644
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h
+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h
@@ -32,6 +32,7 @@
#define ICE_MAX_RSS_QS_PER_VF 16
#define ICE_NUM_VF_MSIX_MED 17
#define ICE_NUM_VF_MSIX_SMALL 5
+#define ICE_NUM_VF_MSIX_MULTIQ_MIN 3
#define ICE_MIN_INTR_PER_VF (ICE_MIN_QS_PER_VF + 1)
#define ICE_MAX_VF_RESET_TRIES 40
#define ICE_MAX_VF_RESET_SLEEP_MS 20
@@ -114,6 +115,7 @@ void ice_vc_notify_link_state(struct ice_pf *pf);
void ice_vc_notify_reset(struct ice_pf *pf);
bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr);
bool ice_reset_vf(struct ice_vf *vf, bool is_vflr);
+void ice_restore_all_vfs_msi_state(struct pci_dev *pdev);
int
ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
@@ -146,6 +148,7 @@ void ice_print_vf_rx_mdd_event(struct ice_vf *vf);
#define ice_vf_lan_overflow_event(pf, event) do {} while (0)
#define ice_print_vfs_mdd_events(pf) do {} while (0)
#define ice_print_vf_rx_mdd_event(vf) do {} while (0)
+#define ice_restore_all_vfs_msi_state(pdev) do {} while (0)
static inline bool
ice_reset_all_vfs(struct ice_pf __always_unused *pf,
diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c
index b6f928c9e9c9..20ac5fca68c6 100644
--- a/drivers/net/ethernet/intel/ice/ice_xsk.c
+++ b/drivers/net/ethernet/intel/ice/ice_xsk.c
@@ -206,12 +206,14 @@ static int ice_qp_ena(struct ice_vsi *vsi, u16 q_idx)
struct ice_aqc_add_tx_qgrp *qg_buf;
struct ice_ring *tx_ring, *rx_ring;
struct ice_q_vector *q_vector;
+ u16 size;
int err;
if (q_idx >= vsi->num_rxq || q_idx >= vsi->num_txq)
return -EINVAL;
- qg_buf = kzalloc(sizeof(*qg_buf), GFP_KERNEL);
+ size = struct_size(qg_buf, txqs, 1);
+ qg_buf = kzalloc(size, GFP_KERNEL);
if (!qg_buf)
return -ENOMEM;
@@ -228,7 +230,7 @@ static int ice_qp_ena(struct ice_vsi *vsi, u16 q_idx)
if (ice_is_xdp_ena_vsi(vsi)) {
struct ice_ring *xdp_ring = vsi->xdp_rings[q_idx];
- memset(qg_buf, 0, sizeof(*qg_buf));
+ memset(qg_buf, 0, size);
qg_buf->num_txqs = 1;
err = ice_vsi_cfg_txq(vsi, xdp_ring, qg_buf);
if (err)
@@ -296,7 +298,6 @@ static void ice_xsk_remove_umem(struct ice_vsi *vsi, u16 qid)
}
}
-
/**
* ice_xsk_umem_disable - disable a UMEM region
* @vsi: Current VSI
@@ -592,7 +593,6 @@ int ice_clean_rx_irq_zc(struct ice_ring *rx_ring, int budget)
if (!size)
break;
-
rx_buf = &rx_ring->rx_buf[rx_ring->next_to_clean];
rx_buf->xdp->data_end = rx_buf->xdp->data + size;
xsk_buff_dma_sync_for_cpu(rx_buf->xdp);
@@ -704,8 +704,6 @@ static bool ice_xmit_zc(struct ice_ring *xdp_ring, int budget)
if (tx_desc) {
ice_xdp_ring_update_tail(xdp_ring);
xsk_umem_consume_tx_done(xdp_ring->xsk_umem);
- if (xsk_umem_uses_need_wakeup(xdp_ring->xsk_umem))
- xsk_clear_tx_need_wakeup(xdp_ring->xsk_umem);
}
return budget > 0 && work_done;
@@ -781,12 +779,8 @@ bool ice_clean_tx_irq_zc(struct ice_ring *xdp_ring, int budget)
if (xsk_frames)
xsk_umem_complete_tx(xdp_ring->xsk_umem, xsk_frames);
- if (xsk_umem_uses_need_wakeup(xdp_ring->xsk_umem)) {
- if (xdp_ring->next_to_clean == xdp_ring->next_to_use)
- xsk_set_tx_need_wakeup(xdp_ring->xsk_umem);
- else
- xsk_clear_tx_need_wakeup(xdp_ring->xsk_umem);
- }
+ if (xsk_umem_uses_need_wakeup(xdp_ring->xsk_umem))
+ xsk_set_tx_need_wakeup(xdp_ring->xsk_umem);
ice_update_tx_ring_stats(xdp_ring, total_packets, total_bytes);
xmit_done = ice_xmit_zc(xdp_ring, ICE_DFLT_IRQ_WORK);
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index 438b42ce2cd9..a32391e82762 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -638,7 +638,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
dev_spec->sgmii_active = true;
break;
}
- /* fall through - for I2C based SGMII */
+ fallthrough; /* for I2C based SGMII */
case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
/* read media type from SFP EEPROM */
ret_val = igb_set_sfp_media_type_82575(hw);
@@ -1704,7 +1704,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
/* disable PCS autoneg and support parallel detect only */
pcs_autoneg = false;
- /* fall through */
+ fallthrough;
default:
if (hw->mac.type == e1000_82575 ||
hw->mac.type == e1000_82576) {
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c
index 09f4dcb09632..fa136e6e9328 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.c
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c
@@ -721,7 +721,7 @@ void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
igb_read_invm_version(hw, fw_vers);
return;
}
- /* fall through */
+ fallthrough;
case e1000_i350:
/* find combo image version */
hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c
index ad2125e5a7f7..8c8eb82e6272 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -659,7 +659,7 @@ s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
phy_data |= M88E1000_PSCR_AUTO_X_1000T;
break;
}
- /* fall through */
+ fallthrough;
case 0:
default:
phy_data |= M88E1000_PSCR_AUTO_X_MODE;
@@ -2621,7 +2621,7 @@ static s32 igb_set_master_slave_mode(struct e1000_hw *hw)
break;
case e1000_ms_auto:
phy_data &= ~CR_1000T_MS_ENABLE;
- /* fall-through */
+ fallthrough;
default:
break;
}
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 0c9282e2aaec..2f015b60a995 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -642,7 +642,6 @@ enum igb_boards {
};
extern char igb_driver_name[];
-extern char igb_driver_version[];
int igb_open(struct net_device *netdev);
int igb_close(struct net_device *netdev);
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index 2cd003c5ad43..6e8231c1ddf0 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -851,7 +851,6 @@ static void igb_get_drvinfo(struct net_device *netdev,
struct igb_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, igb_driver_name, sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, igb_driver_version, sizeof(drvinfo->version));
/* EEPROM image version # is reported as firmware version # for
* 82575 controllers
@@ -1783,8 +1782,8 @@ static void igb_create_lbtest_frame(struct sk_buff *skb,
memset(skb->data, 0xFF, frame_size);
frame_size /= 2;
memset(&skb->data[frame_size], 0xAA, frame_size - 1);
- memset(&skb->data[frame_size + 10], 0xBE, 1);
- memset(&skb->data[frame_size + 12], 0xAF, 1);
+ skb->data[frame_size + 10] = 0xBE;
+ skb->data[frame_size + 12] = 0xAF;
}
static int igb_check_lbtest_frame(struct igb_rx_buffer *rx_buffer,
@@ -2518,11 +2517,11 @@ static int igb_get_rss_hash_opts(struct igb_adapter *adapter,
switch (cmd->flow_type) {
case TCP_V4_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* Fall through */
+ fallthrough;
case UDP_V4_FLOW:
if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV4_UDP)
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* Fall through */
+ fallthrough;
case SCTP_V4_FLOW:
case AH_ESP_V4_FLOW:
case AH_V4_FLOW:
@@ -2532,11 +2531,11 @@ static int igb_get_rss_hash_opts(struct igb_adapter *adapter,
break;
case TCP_V6_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* Fall through */
+ fallthrough;
case UDP_V6_FLOW:
if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV6_UDP)
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* Fall through */
+ fallthrough;
case SCTP_V6_FLOW:
case AH_ESP_V6_FLOW:
case AH_V6_FLOW:
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 6e5861bfb0fa..4f05f6efe6af 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -38,12 +38,6 @@
#include <linux/i2c.h>
#include "igb.h"
-#define MAJ 5
-#define MIN 6
-#define BUILD 0
-#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
-__stringify(BUILD) "-k"
-
enum queue_mode {
QUEUE_MODE_STRICT_PRIORITY,
QUEUE_MODE_STREAM_RESERVATION,
@@ -55,7 +49,6 @@ enum tx_queue_prio {
};
char igb_driver_name[] = "igb";
-char igb_driver_version[] = DRV_VERSION;
static const char igb_driver_string[] =
"Intel(R) Gigabit Ethernet Network Driver";
static const char igb_copyright[] =
@@ -240,7 +233,6 @@ static struct pci_driver igb_driver = {
MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
static int debug = -1;
@@ -666,8 +658,7 @@ static int __init igb_init_module(void)
{
int ret;
- pr_info("%s - version %s\n",
- igb_driver_string, igb_driver_version);
+ pr_info("%s\n", igb_driver_string);
pr_info("%s\n", igb_copyright);
#ifdef CONFIG_IGB_DCA
@@ -720,14 +711,14 @@ static void igb_cache_ring_register(struct igb_adapter *adapter)
adapter->rx_ring[i]->reg_idx = rbase_offset +
Q_IDX_82576(i);
}
- /* Fall through */
+ fallthrough;
case e1000_82575:
case e1000_82580:
case e1000_i350:
case e1000_i354:
case e1000_i210:
case e1000_i211:
- /* Fall through */
+ fallthrough;
default:
for (; i < adapter->num_rx_queues; i++)
adapter->rx_ring[i]->reg_idx = rbase_offset + i;
@@ -2882,7 +2873,7 @@ void igb_set_fw_version(struct igb_adapter *adapter)
fw.invm_img_type);
break;
}
- /* fall through */
+ fallthrough;
default:
/* if option is rom valid, display its version too */
if (fw.or_valid) {
@@ -3733,13 +3724,13 @@ unsigned int igb_get_max_rss_queues(struct igb_adapter *adapter)
max_rss_queues = 1;
break;
}
- /* fall through */
+ fallthrough;
case e1000_82576:
if (!!adapter->vfs_allocated_count) {
max_rss_queues = 2;
break;
}
- /* fall through */
+ fallthrough;
case e1000_82580:
case e1000_i354:
default:
@@ -4878,14 +4869,14 @@ static int igb_vlan_promisc_enable(struct igb_adapter *adapter)
/* VLAN filtering needed for VLAN prio filter */
if (adapter->netdev->features & NETIF_F_NTUPLE)
break;
- /* fall through */
+ fallthrough;
case e1000_82576:
case e1000_82580:
case e1000_i354:
/* VLAN filtering needed for pool filtering */
if (adapter->vfs_allocated_count)
break;
- /* fall through */
+ fallthrough;
default:
return 1;
}
@@ -5165,7 +5156,7 @@ bool igb_has_link(struct igb_adapter *adapter)
case e1000_media_type_copper:
if (!hw->mac.get_link_status)
return true;
- /* fall through */
+ fallthrough;
case e1000_media_type_internal_serdes:
hw->mac.ops.check_for_link(hw);
link_active = !hw->mac.get_link_status;
@@ -5825,7 +5816,7 @@ csum_failed:
switch (skb->csum_offset) {
case offsetof(struct tcphdr, check):
type_tucmd = E1000_ADVTXD_TUCMD_L4T_TCP;
- /* fall through */
+ fallthrough;
case offsetof(struct udphdr, check):
break;
case offsetof(struct sctphdr, checksum):
@@ -5837,7 +5828,7 @@ csum_failed:
type_tucmd = E1000_ADVTXD_TUCMD_L4T_SCTP;
break;
}
- /* fall through */
+ fallthrough;
default:
skb_checksum_help(skb);
goto csum_failed;
@@ -6724,7 +6715,7 @@ static int __igb_notify_dca(struct device *dev, void *data)
igb_setup_dca(adapter);
break;
}
- /* Fall Through - since DCA is disabled. */
+ fallthrough; /* since DCA is disabled. */
case DCA_PROVIDER_REMOVE:
if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
/* without this a class_device is left
@@ -7177,7 +7168,7 @@ static void igb_flush_mac_table(struct igb_adapter *adapter)
for (i = 0; i < hw->mac.rar_entry_count; i++) {
adapter->mac_table[i].state &= ~IGB_MAC_STATE_IN_USE;
- memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
+ eth_zero_addr(adapter->mac_table[i].addr);
adapter->mac_table[i].queue = 0;
igb_rar_set_index(adapter, i);
}
@@ -7326,7 +7317,7 @@ static int igb_del_mac_filter_flags(struct igb_adapter *adapter,
} else {
adapter->mac_table[i].state = 0;
adapter->mac_table[i].queue = 0;
- memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
+ eth_zero_addr(adapter->mac_table[i].addr);
}
igb_rar_set_index(adapter, i);
@@ -9393,13 +9384,13 @@ static void igb_vmm_control(struct igb_adapter *adapter)
reg = rd32(E1000_DTXCTL);
reg |= E1000_DTXCTL_VLAN_ADDED;
wr32(E1000_DTXCTL, reg);
- /* Fall through */
+ fallthrough;
case e1000_82580:
/* enable replication vlan tag stripping */
reg = rd32(E1000_RPLOLR);
reg |= E1000_RPLOLR_STRVLAN;
wr32(E1000_RPLOLR, reg);
- /* Fall through */
+ fallthrough;
case e1000_i350:
/* none of the above registers are supported by i350 */
break;
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index c39e921757ba..490368d3d03c 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -1053,7 +1053,7 @@ static int igb_ptp_set_timestamp_mode(struct igb_adapter *adapter,
config->rx_filter = HWTSTAMP_FILTER_ALL;
break;
}
- /* fall through */
+ fallthrough;
default:
config->rx_filter = HWTSTAMP_FILTER_NONE;
return -ERANGE;
diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c
index 9217d150e286..f4835eb62fee 100644
--- a/drivers/net/ethernet/intel/igbvf/ethtool.c
+++ b/drivers/net/ethernet/intel/igbvf/ethtool.c
@@ -170,8 +170,6 @@ static void igbvf_get_drvinfo(struct net_device *netdev,
struct igbvf_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, igbvf_driver_name, sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, igbvf_driver_version,
- sizeof(drvinfo->version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
}
diff --git a/drivers/net/ethernet/intel/igbvf/igbvf.h b/drivers/net/ethernet/intel/igbvf/igbvf.h
index eee26a3be90b..975eb47ee04d 100644
--- a/drivers/net/ethernet/intel/igbvf/igbvf.h
+++ b/drivers/net/ethernet/intel/igbvf/igbvf.h
@@ -281,7 +281,6 @@ enum igbvf_state_t {
};
extern char igbvf_driver_name[];
-extern const char igbvf_driver_version[];
void igbvf_check_options(struct igbvf_adapter *);
void igbvf_set_ethtool_ops(struct net_device *);
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 5b1800c3ba82..19269f5d52bc 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -24,9 +24,7 @@
#include "igbvf.h"
-#define DRV_VERSION "2.4.0-k"
char igbvf_driver_name[] = "igbvf";
-const char igbvf_driver_version[] = DRV_VERSION;
static const char igbvf_driver_string[] =
"Intel(R) Gigabit Virtual Function Network Driver";
static const char igbvf_copyright[] =
@@ -2093,7 +2091,7 @@ csum_failed:
switch (skb->csum_offset) {
case offsetof(struct tcphdr, check):
type_tucmd = E1000_ADVTXD_TUCMD_L4T_TCP;
- /* fall through */
+ fallthrough;
case offsetof(struct udphdr, check):
break;
case offsetof(struct sctphdr, checksum):
@@ -2105,7 +2103,7 @@ csum_failed:
type_tucmd = E1000_ADVTXD_TUCMD_L4T_SCTP;
break;
}
- /* fall through */
+ fallthrough;
default:
skb_checksum_help(skb);
goto csum_failed;
@@ -2459,13 +2457,10 @@ static int igbvf_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
}
}
-static int igbvf_suspend(struct pci_dev *pdev, pm_message_t state)
+static int igbvf_suspend(struct device *dev_d)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
+ struct net_device *netdev = dev_get_drvdata(dev_d);
struct igbvf_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_PM
- int retval = 0;
-#endif
netif_device_detach(netdev);
@@ -2475,31 +2470,16 @@ static int igbvf_suspend(struct pci_dev *pdev, pm_message_t state)
igbvf_free_irq(adapter);
}
-#ifdef CONFIG_PM
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-#endif
-
- pci_disable_device(pdev);
-
return 0;
}
-#ifdef CONFIG_PM
-static int igbvf_resume(struct pci_dev *pdev)
+static int __maybe_unused igbvf_resume(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct net_device *netdev = pci_get_drvdata(pdev);
struct igbvf_adapter *adapter = netdev_priv(netdev);
u32 err;
- pci_restore_state(pdev);
- err = pci_enable_device_mem(pdev);
- if (err) {
- dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n");
- return err;
- }
-
pci_set_master(pdev);
if (netif_running(netdev)) {
@@ -2517,11 +2497,10 @@ static int igbvf_resume(struct pci_dev *pdev)
return 0;
}
-#endif
static void igbvf_shutdown(struct pci_dev *pdev)
{
- igbvf_suspend(pdev, PMSG_SUSPEND);
+ igbvf_suspend(&pdev->dev);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2962,17 +2941,15 @@ static const struct pci_device_id igbvf_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, igbvf_pci_tbl);
+static SIMPLE_DEV_PM_OPS(igbvf_pm_ops, igbvf_suspend, igbvf_resume);
+
/* PCI Device API Driver */
static struct pci_driver igbvf_driver = {
.name = igbvf_driver_name,
.id_table = igbvf_pci_tbl,
.probe = igbvf_probe,
.remove = igbvf_remove,
-#ifdef CONFIG_PM
- /* Power Management Hooks */
- .suspend = igbvf_suspend,
- .resume = igbvf_resume,
-#endif
+ .driver.pm = &igbvf_pm_ops,
.shutdown = igbvf_shutdown,
.err_handler = &igbvf_err_handler
};
@@ -2987,7 +2964,7 @@ static int __init igbvf_init_module(void)
{
int ret;
- pr_info("%s - version %s\n", igbvf_driver_string, igbvf_driver_version);
+ pr_info("%s\n", igbvf_driver_string);
pr_info("%s\n", igbvf_copyright);
ret = pci_register_driver(&igbvf_driver);
@@ -3011,6 +2988,5 @@ module_exit(igbvf_exit_module);
MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
MODULE_DESCRIPTION("Intel(R) Gigabit Virtual Function Network Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
/* netdev.c */
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index 5dbc5a156626..3070dfdb7eb4 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -117,6 +117,9 @@ struct igc_ring {
struct igc_adapter {
struct net_device *netdev;
+ struct ethtool_eee eee;
+ u16 eee_advert;
+
unsigned long state;
unsigned int flags;
unsigned int num_q_vectors;
@@ -207,8 +210,6 @@ struct igc_adapter {
struct sk_buff *ptp_tx_skb;
struct hwtstamp_config tstamp_config;
unsigned long ptp_tx_start;
- unsigned long last_rx_ptp_check;
- unsigned long last_rx_timestamp;
unsigned int ptp_flags;
/* System time value lock */
spinlock_t tmreg_lock;
@@ -239,7 +240,6 @@ void igc_rings_dump(struct igc_adapter *adapter);
void igc_regs_dump(struct igc_adapter *adapter);
extern char igc_driver_name[];
-extern char igc_driver_version[];
#define IGC_REGS_LEN 740
@@ -256,6 +256,7 @@ extern char igc_driver_version[];
#define IGC_FLAG_MEDIA_RESET BIT(10)
#define IGC_FLAG_MAS_ENABLE BIT(12)
#define IGC_FLAG_HAS_MSIX BIT(13)
+#define IGC_FLAG_EEE BIT(14)
#define IGC_FLAG_VLAN_PROMISC BIT(15)
#define IGC_FLAG_RX_LEGACY BIT(16)
#define IGC_FLAG_TSN_QBV_ENABLED BIT(17)
@@ -546,7 +547,6 @@ void igc_ptp_init(struct igc_adapter *adapter);
void igc_ptp_reset(struct igc_adapter *adapter);
void igc_ptp_suspend(struct igc_adapter *adapter);
void igc_ptp_stop(struct igc_adapter *adapter);
-void igc_ptp_rx_rgtstamp(struct igc_q_vector *q_vector, struct sk_buff *skb);
void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va,
struct sk_buff *skb);
int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
index 186deb1d9375..f1f464967f87 100644
--- a/drivers/net/ethernet/intel/igc/igc_defines.h
+++ b/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -323,7 +323,6 @@
/* Advanced Receive Descriptor bit definitions */
#define IGC_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */
-#define IGC_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */
#define IGC_RXDEXT_STATERR_CE 0x01000000
#define IGC_RXDEXT_STATERR_SE 0x02000000
@@ -384,7 +383,6 @@
#define IGC_FTQF_MASK_PROTO_BP 0x10000000
/* Time Sync Receive Control bit definitions */
-#define IGC_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
#define IGC_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
#define IGC_TSYNCRXCTL_TYPE_L2_V2 0x00
#define IGC_TSYNCRXCTL_TYPE_L4_V1 0x02
@@ -511,4 +509,41 @@
/* Maximum size of the MTA register table in all supported adapters */
#define MAX_MTA_REG 128
+/* EEE defines */
+#define IGC_IPCNFG_EEE_2_5G_AN 0x00000010 /* IPCNFG EEE Ena 2.5G AN */
+#define IGC_IPCNFG_EEE_1G_AN 0x00000008 /* IPCNFG EEE Ena 1G AN */
+#define IGC_IPCNFG_EEE_100M_AN 0x00000004 /* IPCNFG EEE Ena 100M AN */
+#define IGC_EEER_EEE_NEG 0x20000000 /* EEE capability nego */
+#define IGC_EEER_TX_LPI_EN 0x00010000 /* EEER Tx LPI Enable */
+#define IGC_EEER_RX_LPI_EN 0x00020000 /* EEER Rx LPI Enable */
+#define IGC_EEER_LPI_FC 0x00040000 /* EEER Ena on Flow Cntrl */
+#define IGC_EEE_SU_LPI_CLK_STP 0x00800000 /* EEE LPI Clock Stop */
+
+/* LTR defines */
+#define IGC_LTRC_EEEMS_EN 0x00000020 /* Enable EEE LTR max send */
+#define IGC_RXPBS_SIZE_I225_MASK 0x0000003F /* Rx packet buffer size */
+#define IGC_TW_SYSTEM_1000_MASK 0x000000FF
+/* Minimum time for 100BASE-T where no data will be transmit following move out
+ * of EEE LPI Tx state
+ */
+#define IGC_TW_SYSTEM_100_MASK 0x0000FF00
+#define IGC_TW_SYSTEM_100_SHIFT 8
+#define IGC_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */
+#define IGC_DMACR_DMACTHR_MASK 0x00FF0000
+#define IGC_DMACR_DMACTHR_SHIFT 16
+/* Reg val to set scale to 1024 nsec */
+#define IGC_LTRMINV_SCALE_1024 2
+/* Reg val to set scale to 32768 nsec */
+#define IGC_LTRMINV_SCALE_32768 3
+/* Reg val to set scale to 1024 nsec */
+#define IGC_LTRMAXV_SCALE_1024 2
+/* Reg val to set scale to 32768 nsec */
+#define IGC_LTRMAXV_SCALE_32768 3
+#define IGC_LTRMINV_LTRV_MASK 0x000003FF /* LTR minimum value */
+#define IGC_LTRMAXV_LTRV_MASK 0x000003FF /* LTR maximum value */
+#define IGC_LTRMINV_LSNP_REQ 0x00008000 /* LTR Snoop Requirement */
+#define IGC_LTRMINV_SCALE_SHIFT 10
+#define IGC_LTRMAXV_LSNP_REQ 0x00008000 /* LTR Snoop Requirement */
+#define IGC_LTRMAXV_SCALE_SHIFT 10
+
#endif /* _IGC_DEFINES_H_ */
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index a938ec8db681..44410c2265d6 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -4,6 +4,7 @@
/* ethtool support for igc */
#include <linux/if_vlan.h>
#include <linux/pm_runtime.h>
+#include <linux/mdio.h>
#include "igc.h"
#include "igc_diag.h"
@@ -130,7 +131,6 @@ static void igc_ethtool_get_drvinfo(struct net_device *netdev,
struct igc_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, igc_driver_name, sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, igc_driver_version, sizeof(drvinfo->version));
/* add fw_version here */
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
@@ -1015,37 +1015,29 @@ static int igc_ethtool_get_rss_hash_opts(struct igc_adapter *adapter,
switch (cmd->flow_type) {
case TCP_V4_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* Fall through */
+ fallthrough;
case UDP_V4_FLOW:
if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV4_UDP)
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* Fall through */
+ fallthrough;
case SCTP_V4_FLOW:
- /* Fall through */
case AH_ESP_V4_FLOW:
- /* Fall through */
case AH_V4_FLOW:
- /* Fall through */
case ESP_V4_FLOW:
- /* Fall through */
case IPV4_FLOW:
cmd->data |= RXH_IP_SRC | RXH_IP_DST;
break;
case TCP_V6_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* Fall through */
+ fallthrough;
case UDP_V6_FLOW:
if (adapter->flags & IGC_FLAG_RSS_FIELD_IPV6_UDP)
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* Fall through */
+ fallthrough;
case SCTP_V6_FLOW:
- /* Fall through */
case AH_ESP_V6_FLOW:
- /* Fall through */
case AH_V6_FLOW:
- /* Fall through */
case ESP_V6_FLOW:
- /* Fall through */
case IPV6_FLOW:
cmd->data |= RXH_IP_SRC | RXH_IP_DST;
break;
@@ -1549,6 +1541,98 @@ static int igc_ethtool_set_priv_flags(struct net_device *netdev, u32 priv_flags)
return 0;
}
+static int igc_ethtool_get_eee(struct net_device *netdev,
+ struct ethtool_eee *edata)
+{
+ struct igc_adapter *adapter = netdev_priv(netdev);
+ struct igc_hw *hw = &adapter->hw;
+ u32 eeer;
+
+ if (hw->dev_spec._base.eee_enable)
+ edata->advertised =
+ mmd_eee_adv_to_ethtool_adv_t(adapter->eee_advert);
+
+ *edata = adapter->eee;
+ edata->supported = SUPPORTED_Autoneg;
+
+ eeer = rd32(IGC_EEER);
+
+ /* EEE status on negotiated link */
+ if (eeer & IGC_EEER_EEE_NEG)
+ edata->eee_active = true;
+
+ if (eeer & IGC_EEER_TX_LPI_EN)
+ edata->tx_lpi_enabled = true;
+
+ edata->eee_enabled = hw->dev_spec._base.eee_enable;
+
+ edata->advertised = SUPPORTED_Autoneg;
+ edata->lp_advertised = SUPPORTED_Autoneg;
+
+ /* Report correct negotiated EEE status for devices that
+ * wrongly report EEE at half-duplex
+ */
+ if (adapter->link_duplex == HALF_DUPLEX) {
+ edata->eee_enabled = false;
+ edata->eee_active = false;
+ edata->tx_lpi_enabled = false;
+ edata->advertised &= ~edata->advertised;
+ }
+
+ return 0;
+}
+
+static int igc_ethtool_set_eee(struct net_device *netdev,
+ struct ethtool_eee *edata)
+{
+ struct igc_adapter *adapter = netdev_priv(netdev);
+ struct igc_hw *hw = &adapter->hw;
+ struct ethtool_eee eee_curr;
+ s32 ret_val;
+
+ memset(&eee_curr, 0, sizeof(struct ethtool_eee));
+
+ ret_val = igc_ethtool_get_eee(netdev, &eee_curr);
+ if (ret_val) {
+ netdev_err(netdev,
+ "Problem setting EEE advertisement options\n");
+ return -EINVAL;
+ }
+
+ if (eee_curr.eee_enabled) {
+ if (eee_curr.tx_lpi_enabled != edata->tx_lpi_enabled) {
+ netdev_err(netdev,
+ "Setting EEE tx-lpi is not supported\n");
+ return -EINVAL;
+ }
+
+ /* Tx LPI timer is not implemented currently */
+ if (edata->tx_lpi_timer) {
+ netdev_err(netdev,
+ "Setting EEE Tx LPI timer is not supported\n");
+ return -EINVAL;
+ }
+ } else if (!edata->eee_enabled) {
+ netdev_err(netdev,
+ "Setting EEE options are not supported with EEE disabled\n");
+ return -EINVAL;
+ }
+
+ adapter->eee_advert = ethtool_adv_to_mmd_eee_adv_t(edata->advertised);
+ if (hw->dev_spec._base.eee_enable != edata->eee_enabled) {
+ hw->dev_spec._base.eee_enable = edata->eee_enabled;
+ adapter->flags |= IGC_FLAG_EEE;
+
+ /* reset link */
+ if (netif_running(netdev))
+ igc_reinit_locked(adapter);
+ else
+ igc_reset(adapter);
+ }
+
+ return 0;
+}
+
static int igc_ethtool_begin(struct net_device *netdev)
{
struct igc_adapter *adapter = netdev_priv(netdev);
@@ -1830,6 +1914,8 @@ static const struct ethtool_ops igc_ethtool_ops = {
.set_channels = igc_ethtool_set_channels,
.get_priv_flags = igc_ethtool_get_priv_flags,
.set_priv_flags = igc_ethtool_set_priv_flags,
+ .get_eee = igc_ethtool_get_eee,
+ .set_eee = igc_ethtool_set_eee,
.begin = igc_ethtool_begin,
.complete = igc_ethtool_complete,
.get_link_ksettings = igc_ethtool_get_link_ksettings,
diff --git a/drivers/net/ethernet/intel/igc/igc_hw.h b/drivers/net/ethernet/intel/igc/igc_hw.h
index af34ae310327..b9fe51b91c47 100644
--- a/drivers/net/ethernet/intel/igc/igc_hw.h
+++ b/drivers/net/ethernet/intel/igc/igc_hw.h
@@ -82,13 +82,7 @@ struct igc_mac_info {
enum igc_mac_type type;
- u32 collision_delta;
- u32 ledctl_default;
- u32 ledctl_mode1;
- u32 ledctl_mode2;
u32 mc_filter_type;
- u32 tx_packet_delta;
- u32 txcw;
u16 mta_reg_count;
u16 uta_reg_count;
@@ -98,8 +92,6 @@ struct igc_mac_info {
u8 forced_speed_duplex;
- bool adaptive_ifs;
- bool has_fwsm;
bool asf_firmware_present;
bool arc_subsystem_valid;
@@ -191,6 +183,7 @@ struct igc_fc_info {
struct igc_dev_spec_base {
bool clear_semaphore_once;
+ bool eee_enable;
};
struct igc_hw {
@@ -275,21 +268,9 @@ struct igc_hw_stats {
u64 tsctc;
u64 tsctfc;
u64 iac;
- u64 icrxptc;
- u64 icrxatc;
- u64 ictxptc;
- u64 ictxatc;
- u64 ictxqec;
- u64 ictxqmtc;
- u64 icrxdmtc;
- u64 icrxoc;
- u64 cbtmpc;
u64 htdpmc;
- u64 cbrdpc;
- u64 cbrmpc;
u64 rpthc;
u64 hgptc;
- u64 htcbdpc;
u64 hgorc;
u64 hgotc;
u64 lenerrs;
diff --git a/drivers/net/ethernet/intel/igc/igc_i225.c b/drivers/net/ethernet/intel/igc/igc_i225.c
index c25f555aaf82..8b67d9b49a83 100644
--- a/drivers/net/ethernet/intel/igc/igc_i225.c
+++ b/drivers/net/ethernet/intel/igc/igc_i225.c
@@ -488,3 +488,159 @@ s32 igc_init_nvm_params_i225(struct igc_hw *hw)
}
return 0;
}
+
+/**
+ * igc_set_eee_i225 - Enable/disable EEE support
+ * @hw: pointer to the HW structure
+ * @adv2p5G: boolean flag enabling 2.5G EEE advertisement
+ * @adv1G: boolean flag enabling 1G EEE advertisement
+ * @adv100M: boolean flag enabling 100M EEE advertisement
+ *
+ * Enable/disable EEE based on setting in dev_spec structure.
+ **/
+s32 igc_set_eee_i225(struct igc_hw *hw, bool adv2p5G, bool adv1G,
+ bool adv100M)
+{
+ u32 ipcnfg, eeer;
+
+ ipcnfg = rd32(IGC_IPCNFG);
+ eeer = rd32(IGC_EEER);
+
+ /* enable or disable per user setting */
+ if (hw->dev_spec._base.eee_enable) {
+ u32 eee_su = rd32(IGC_EEE_SU);
+
+ if (adv100M)
+ ipcnfg |= IGC_IPCNFG_EEE_100M_AN;
+ else
+ ipcnfg &= ~IGC_IPCNFG_EEE_100M_AN;
+
+ if (adv1G)
+ ipcnfg |= IGC_IPCNFG_EEE_1G_AN;
+ else
+ ipcnfg &= ~IGC_IPCNFG_EEE_1G_AN;
+
+ if (adv2p5G)
+ ipcnfg |= IGC_IPCNFG_EEE_2_5G_AN;
+ else
+ ipcnfg &= ~IGC_IPCNFG_EEE_2_5G_AN;
+
+ eeer |= (IGC_EEER_TX_LPI_EN | IGC_EEER_RX_LPI_EN |
+ IGC_EEER_LPI_FC);
+
+ /* This bit should not be set in normal operation. */
+ if (eee_su & IGC_EEE_SU_LPI_CLK_STP)
+ hw_dbg("LPI Clock Stop Bit should not be set!\n");
+ } else {
+ ipcnfg &= ~(IGC_IPCNFG_EEE_2_5G_AN | IGC_IPCNFG_EEE_1G_AN |
+ IGC_IPCNFG_EEE_100M_AN);
+ eeer &= ~(IGC_EEER_TX_LPI_EN | IGC_EEER_RX_LPI_EN |
+ IGC_EEER_LPI_FC);
+ }
+ wr32(IGC_IPCNFG, ipcnfg);
+ wr32(IGC_EEER, eeer);
+ rd32(IGC_IPCNFG);
+ rd32(IGC_EEER);
+
+ return IGC_SUCCESS;
+}
+
+/* igc_set_ltr_i225 - Set Latency Tolerance Reporting thresholds
+ * @hw: pointer to the HW structure
+ * @link: bool indicating link status
+ *
+ * Set the LTR thresholds based on the link speed (Mbps), EEE, and DMAC
+ * settings, otherwise specify that there is no LTR requirement.
+ */
+s32 igc_set_ltr_i225(struct igc_hw *hw, bool link)
+{
+ u32 tw_system, ltrc, ltrv, ltr_min, ltr_max, scale_min, scale_max;
+ u16 speed, duplex;
+ s32 size;
+
+ /* If we do not have link, LTR thresholds are zero. */
+ if (link) {
+ hw->mac.ops.get_speed_and_duplex(hw, &speed, &duplex);
+
+ /* Check if using copper interface with EEE enabled or if the
+ * link speed is 10 Mbps.
+ */
+ if (hw->dev_spec._base.eee_enable &&
+ speed != SPEED_10) {
+ /* EEE enabled, so send LTRMAX threshold. */
+ ltrc = rd32(IGC_LTRC) |
+ IGC_LTRC_EEEMS_EN;
+ wr32(IGC_LTRC, ltrc);
+
+ /* Calculate tw_system (nsec). */
+ if (speed == SPEED_100) {
+ tw_system = ((rd32(IGC_EEE_SU) &
+ IGC_TW_SYSTEM_100_MASK) >>
+ IGC_TW_SYSTEM_100_SHIFT) * 500;
+ } else {
+ tw_system = (rd32(IGC_EEE_SU) &
+ IGC_TW_SYSTEM_1000_MASK) * 500;
+ }
+ } else {
+ tw_system = 0;
+ }
+
+ /* Get the Rx packet buffer size. */
+ size = rd32(IGC_RXPBS) &
+ IGC_RXPBS_SIZE_I225_MASK;
+
+ /* Calculations vary based on DMAC settings. */
+ if (rd32(IGC_DMACR) & IGC_DMACR_DMAC_EN) {
+ size -= (rd32(IGC_DMACR) &
+ IGC_DMACR_DMACTHR_MASK) >>
+ IGC_DMACR_DMACTHR_SHIFT;
+ /* Convert size to bits. */
+ size *= 1024 * 8;
+ } else {
+ /* Convert size to bytes, subtract the MTU, and then
+ * convert the size to bits.
+ */
+ size *= 1024;
+ size *= 8;
+ }
+
+ if (size < 0) {
+ hw_dbg("Invalid effective Rx buffer size %d\n",
+ size);
+ return -IGC_ERR_CONFIG;
+ }
+
+ /* Calculate the thresholds. Since speed is in Mbps, simplify
+ * the calculation by multiplying size/speed by 1000 for result
+ * to be in nsec before dividing by the scale in nsec. Set the
+ * scale such that the LTR threshold fits in the register.
+ */
+ ltr_min = (1000 * size) / speed;
+ ltr_max = ltr_min + tw_system;
+ scale_min = (ltr_min / 1024) < 1024 ? IGC_LTRMINV_SCALE_1024 :
+ IGC_LTRMINV_SCALE_32768;
+ scale_max = (ltr_max / 1024) < 1024 ? IGC_LTRMAXV_SCALE_1024 :
+ IGC_LTRMAXV_SCALE_32768;
+ ltr_min /= scale_min == IGC_LTRMINV_SCALE_1024 ? 1024 : 32768;
+ ltr_min -= 1;
+ ltr_max /= scale_max == IGC_LTRMAXV_SCALE_1024 ? 1024 : 32768;
+ ltr_max -= 1;
+
+ /* Only write the LTR thresholds if they differ from before. */
+ ltrv = rd32(IGC_LTRMINV);
+ if (ltr_min != (ltrv & IGC_LTRMINV_LTRV_MASK)) {
+ ltrv = IGC_LTRMINV_LSNP_REQ | ltr_min |
+ (scale_min << IGC_LTRMINV_SCALE_SHIFT);
+ wr32(IGC_LTRMINV, ltrv);
+ }
+
+ ltrv = rd32(IGC_LTRMAXV);
+ if (ltr_max != (ltrv & IGC_LTRMAXV_LTRV_MASK)) {
+ ltrv = IGC_LTRMAXV_LSNP_REQ | ltr_max |
+ (scale_min << IGC_LTRMAXV_SCALE_SHIFT);
+ wr32(IGC_LTRMAXV, ltrv);
+ }
+ }
+
+ return IGC_SUCCESS;
+}
diff --git a/drivers/net/ethernet/intel/igc/igc_i225.h b/drivers/net/ethernet/intel/igc/igc_i225.h
index 7b66e1f9c0e6..dae47e4f16b0 100644
--- a/drivers/net/ethernet/intel/igc/igc_i225.h
+++ b/drivers/net/ethernet/intel/igc/igc_i225.h
@@ -9,5 +9,8 @@ void igc_release_swfw_sync_i225(struct igc_hw *hw, u16 mask);
s32 igc_init_nvm_params_i225(struct igc_hw *hw);
bool igc_get_flash_presence_i225(struct igc_hw *hw);
+s32 igc_set_eee_i225(struct igc_hw *hw, bool adv2p5G, bool adv1G,
+ bool adv100M);
+s32 igc_set_ltr_i225(struct igc_hw *hw, bool link);
#endif
diff --git a/drivers/net/ethernet/intel/igc/igc_mac.c b/drivers/net/ethernet/intel/igc/igc_mac.c
index 410aeb01de5c..09cd0ec7ee87 100644
--- a/drivers/net/ethernet/intel/igc/igc_mac.c
+++ b/drivers/net/ethernet/intel/igc/igc_mac.c
@@ -289,25 +289,18 @@ void igc_clear_hw_cntrs_base(struct igc_hw *hw)
rd32(IGC_TNCRS);
rd32(IGC_HTDPMC);
rd32(IGC_TSCTC);
- rd32(IGC_TSCTFC);
rd32(IGC_MGTPRC);
rd32(IGC_MGTPDC);
rd32(IGC_MGTPTC);
rd32(IGC_IAC);
- rd32(IGC_ICRXOC);
-
- rd32(IGC_ICRXPTC);
- rd32(IGC_ICRXATC);
- rd32(IGC_ICTXPTC);
- rd32(IGC_ICTXATC);
- rd32(IGC_ICTXQEC);
- rd32(IGC_ICTXQMTC);
- rd32(IGC_ICRXDMTC);
rd32(IGC_RPTHC);
+ rd32(IGC_TLPIC);
+ rd32(IGC_RLPIC);
rd32(IGC_HGPTC);
+ rd32(IGC_RXDMTC);
rd32(IGC_HGORCL);
rd32(IGC_HGORCH);
rd32(IGC_HGOTCL);
@@ -362,8 +355,8 @@ void igc_rar_set(struct igc_hw *hw, u8 *addr, u32 index)
s32 igc_check_for_copper_link(struct igc_hw *hw)
{
struct igc_mac_info *mac = &hw->mac;
+ bool link = false;
s32 ret_val;
- bool link;
/* We only want to go out to the PHY registers to see if Auto-Neg
* has completed and/or if our link status has changed. The
@@ -417,6 +410,11 @@ s32 igc_check_for_copper_link(struct igc_hw *hw)
hw_dbg("Error configuring flow control\n");
out:
+ /* Now that we are aware of our link settings, we can set the LTR
+ * thresholds.
+ */
+ ret_val = igc_set_ltr_i225(hw, link);
+
return ret_val;
}
@@ -462,10 +460,8 @@ s32 igc_config_fc_after_link_up(struct igc_hw *hw)
* so we had to force link. In this case, we need to force the
* configuration of the MAC to match the "fc" parameter.
*/
- if (mac->autoneg_failed) {
- if (hw->phy.media_type == igc_media_type_copper)
- ret_val = igc_force_mac_fc(hw);
- }
+ if (mac->autoneg_failed)
+ ret_val = igc_force_mac_fc(hw);
if (ret_val) {
hw_dbg("Error forcing flow control settings\n");
@@ -477,7 +473,7 @@ s32 igc_config_fc_after_link_up(struct igc_hw *hw)
* has completed, and if so, how the PHY and link partner has
* flow control configured.
*/
- if (hw->phy.media_type == igc_media_type_copper && mac->autoneg) {
+ if (mac->autoneg) {
/* Read the MII Status Register and check to see if AutoNeg
* has completed. We read this twice because this reg has
* some "sticky" (latched) bits.
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 6919c50e449a..7a6f2a0d413f 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -17,7 +17,6 @@
#include "igc_hw.h"
#include "igc_tsn.h"
-#define DRV_VERSION "0.0.1-k"
#define DRV_SUMMARY "Intel(R) 2.5G Ethernet Linux Driver"
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
@@ -27,12 +26,10 @@ static int debug = -1;
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION(DRV_SUMMARY);
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
char igc_driver_name[] = "igc";
-char igc_driver_version[] = DRV_VERSION;
static const char igc_driver_string[] = DRV_SUMMARY;
static const char igc_copyright[] =
"Copyright(c) 2018 Intel Corporation.";
@@ -64,16 +61,6 @@ enum latency_range {
latency_invalid = 255
};
-/**
- * igc_power_down_link - Power down the phy/serdes link
- * @adapter: address of board private structure
- */
-static void igc_power_down_link(struct igc_adapter *adapter)
-{
- if (adapter->hw.phy.media_type == igc_media_type_copper)
- igc_power_down_phy_copper_base(&adapter->hw);
-}
-
void igc_reset(struct igc_adapter *adapter)
{
struct net_device *dev = adapter->netdev;
@@ -105,8 +92,11 @@ void igc_reset(struct igc_adapter *adapter)
if (hw->mac.ops.init_hw(hw))
netdev_err(dev, "Error on hardware initialization\n");
+ /* Re-establish EEE setting */
+ igc_set_eee_i225(hw, true, true, true);
+
if (!netif_running(adapter->netdev))
- igc_power_down_link(adapter);
+ igc_power_down_phy_copper_base(&adapter->hw);
/* Re-enable PTP, where applicable. */
igc_ptp_reset(adapter);
@@ -125,8 +115,7 @@ static void igc_power_up_link(struct igc_adapter *adapter)
{
igc_reset_phy(&adapter->hw);
- if (adapter->hw.phy.media_type == igc_media_type_copper)
- igc_power_up_phy_copper(&adapter->hw);
+ igc_power_up_phy_copper(&adapter->hw);
igc_setup_link(&adapter->hw);
}
@@ -980,7 +969,7 @@ csum_failed:
switch (skb->csum_offset) {
case offsetof(struct tcphdr, check):
type_tucmd = IGC_ADVTXD_TUCMD_L4T_TCP;
- /* fall through */
+ fallthrough;
case offsetof(struct udphdr, check):
break;
case offsetof(struct sctphdr, checksum):
@@ -992,7 +981,7 @@ csum_failed:
type_tucmd = IGC_ADVTXD_TUCMD_L4T_SCTP;
break;
}
- /* fall through */
+ fallthrough;
default:
skb_checksum_help(skb);
goto csum_failed;
@@ -1479,9 +1468,9 @@ static inline void igc_rx_hash(struct igc_ring *ring,
* @rx_desc: pointer to the EOP Rx descriptor
* @skb: pointer to current skb being populated
*
- * This function checks the ring, descriptor, and packet information in
- * order to populate the hash, checksum, VLAN, timestamp, protocol, and
- * other fields within the skb.
+ * This function checks the ring, descriptor, and packet information in order
+ * to populate the hash, checksum, VLAN, protocol, and other fields within the
+ * skb.
*/
static void igc_process_skb_fields(struct igc_ring *rx_ring,
union igc_adv_rx_desc *rx_desc,
@@ -1491,10 +1480,6 @@ static void igc_process_skb_fields(struct igc_ring *rx_ring,
igc_rx_checksum(rx_ring, rx_desc, skb);
- if (igc_test_staterr(rx_desc, IGC_RXDADV_STAT_TS) &&
- !igc_test_staterr(rx_desc, IGC_RXDADV_STAT_TSIP))
- igc_ptp_rx_rgtstamp(rx_ring->q_vector, skb);
-
skb_record_rx_queue(skb, rx_ring->queue_index);
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
@@ -1975,7 +1960,7 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
/* probably a little skewed due to removing CRC */
total_bytes += skb->len;
- /* populate checksum, timestamp, VLAN, and protocol */
+ /* populate checksum, VLAN, and protocol */
igc_process_skb_fields(rx_ring, rx_desc, skb);
napi_gro_receive(&q_vector->napi, skb);
@@ -3284,7 +3269,6 @@ static void igc_cache_ring_register(struct igc_adapter *adapter)
switch (adapter->hw.mac.type) {
case igc_i225:
- /* Fall through */
default:
for (; i < adapter->num_rx_queues; i++)
adapter->rx_ring[i]->reg_idx = i;
@@ -3744,17 +3728,8 @@ void igc_update_stats(struct igc_adapter *adapter)
adapter->stats.algnerrc += rd32(IGC_ALGNERRC);
adapter->stats.tsctc += rd32(IGC_TSCTC);
- adapter->stats.tsctfc += rd32(IGC_TSCTFC);
adapter->stats.iac += rd32(IGC_IAC);
- adapter->stats.icrxoc += rd32(IGC_ICRXOC);
- adapter->stats.icrxptc += rd32(IGC_ICRXPTC);
- adapter->stats.icrxatc += rd32(IGC_ICRXATC);
- adapter->stats.ictxptc += rd32(IGC_ICTXPTC);
- adapter->stats.ictxatc += rd32(IGC_ICTXATC);
- adapter->stats.ictxqec += rd32(IGC_ICTXQEC);
- adapter->stats.ictxqmtc += rd32(IGC_ICTXQMTC);
- adapter->stats.icrxdmtc += rd32(IGC_ICRXDMTC);
/* Fill out the OS statistics structure */
net_stats->multicast = adapter->stats.mprc;
@@ -4255,6 +4230,15 @@ static void igc_watchdog_task(struct work_struct *work)
(ctrl & IGC_CTRL_RFCE) ? "RX" :
(ctrl & IGC_CTRL_TFCE) ? "TX" : "None");
+ /* disable EEE if enabled */
+ if ((adapter->flags & IGC_FLAG_EEE) &&
+ adapter->link_duplex == HALF_DUPLEX) {
+ netdev_info(netdev,
+ "EEE Disabled: unsupported at half duplex. Re-enable using ethtool when at full duplex\n");
+ adapter->hw.dev_spec._base.eee_enable = false;
+ adapter->flags &= ~IGC_FLAG_EEE;
+ }
+
/* check if SmartSpeed worked */
igc_check_downshift(hw);
if (phy->speed_downgraded)
@@ -4611,7 +4595,7 @@ err_set_queues:
igc_free_irq(adapter);
err_req_irq:
igc_release_hw_control(adapter);
- igc_power_down_link(adapter);
+ igc_power_down_phy_copper_base(&adapter->hw);
igc_free_all_rx_resources(adapter);
err_setup_rx:
igc_free_all_tx_resources(adapter);
@@ -5185,6 +5169,10 @@ static int igc_probe(struct pci_dev *pdev,
netdev_info(netdev, "MAC: %pM\n", netdev->dev_addr);
dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
+ /* Disable EEE for internal PHY devices */
+ hw->dev_spec._base.eee_enable = false;
+ adapter->flags &= ~IGC_FLAG_EEE;
+ igc_set_eee_i225(hw, false, false, false);
pm_runtime_put_noidle(&pdev->dev);
@@ -5305,7 +5293,7 @@ static int __igc_shutdown(struct pci_dev *pdev, bool *enable_wake,
wake = wufc || adapter->en_mng_pt;
if (!wake)
- igc_power_down_link(adapter);
+ igc_power_down_phy_copper_base(&adapter->hw);
else
igc_power_up_link(adapter);
@@ -5614,9 +5602,7 @@ static int __init igc_init_module(void)
{
int ret;
- pr_info("%s - version %s\n",
- igc_driver_string, igc_driver_version);
-
+ pr_info("%s\n", igc_driver_string);
pr_info("%s\n", igc_copyright);
ret = pci_register_driver(&igc_driver);
diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
index 0d746f8588c8..e67d4655b47e 100644
--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
@@ -205,78 +205,66 @@ void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va,
ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust);
}
-/**
- * igc_ptp_rx_rgtstamp - retrieve Rx timestamp stored in register
- * @q_vector: Pointer to interrupt specific structure
- * @skb: Buffer containing timestamp and packet
- *
- * This function is meant to retrieve a timestamp from the internal registers
- * of the adapter and store it in the skb.
- */
-void igc_ptp_rx_rgtstamp(struct igc_q_vector *q_vector,
- struct sk_buff *skb)
+static void igc_ptp_disable_rx_timestamp(struct igc_adapter *adapter)
{
- struct igc_adapter *adapter = q_vector->adapter;
struct igc_hw *hw = &adapter->hw;
- u64 regval;
-
- /* If this bit is set, then the RX registers contain the time
- * stamp. No other packet will be time stamped until we read
- * these registers, so read the registers to make them
- * available again. Because only one packet can be time
- * stamped at a time, we know that the register values must
- * belong to this one here and therefore we don't need to
- * compare any of the additional attributes stored for it.
- *
- * If nothing went wrong, then it should have a shared
- * tx_flags that we can turn into a skb_shared_hwtstamps.
- */
- if (!(rd32(IGC_TSYNCRXCTL) & IGC_TSYNCRXCTL_VALID))
- return;
+ u32 val;
+ int i;
- regval = rd32(IGC_RXSTMPL);
- regval |= (u64)rd32(IGC_RXSTMPH) << 32;
+ wr32(IGC_TSYNCRXCTL, 0);
- igc_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ val = rd32(IGC_SRRCTL(i));
+ val &= ~IGC_SRRCTL_TIMESTAMP;
+ wr32(IGC_SRRCTL(i), val);
+ }
- /* Update the last_rx_timestamp timer in order to enable watchdog check
- * for error case of latched timestamp on a dropped packet.
- */
- adapter->last_rx_timestamp = jiffies;
+ val = rd32(IGC_RXPBS);
+ val &= ~IGC_RXPBS_CFG_TS_EN;
+ wr32(IGC_RXPBS, val);
}
-/**
- * igc_ptp_enable_tstamp_rxqueue - Enable RX timestamp for a queue
- * @rx_ring: Pointer to RX queue
- * @timer: Index for timer
- *
- * This function enables RX timestamping for a queue, and selects
- * which 1588 timer will provide the timestamp.
- */
-static void igc_ptp_enable_tstamp_rxqueue(struct igc_adapter *adapter,
- struct igc_ring *rx_ring, u8 timer)
+static void igc_ptp_enable_rx_timestamp(struct igc_adapter *adapter)
{
struct igc_hw *hw = &adapter->hw;
- int reg_idx = rx_ring->reg_idx;
- u32 srrctl = rd32(IGC_SRRCTL(reg_idx));
+ u32 val;
+ int i;
+
+ val = rd32(IGC_RXPBS);
+ val |= IGC_RXPBS_CFG_TS_EN;
+ wr32(IGC_RXPBS, val);
- srrctl |= IGC_SRRCTL_TIMESTAMP;
- srrctl |= IGC_SRRCTL_TIMER1SEL(timer);
- srrctl |= IGC_SRRCTL_TIMER0SEL(timer);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ val = rd32(IGC_SRRCTL(i));
+ /* FIXME: For now, only support retrieving RX timestamps from
+ * timer 0.
+ */
+ val |= IGC_SRRCTL_TIMER1SEL(0) | IGC_SRRCTL_TIMER0SEL(0) |
+ IGC_SRRCTL_TIMESTAMP;
+ wr32(IGC_SRRCTL(i), val);
+ }
- wr32(IGC_SRRCTL(reg_idx), srrctl);
+ val = IGC_TSYNCRXCTL_ENABLED | IGC_TSYNCRXCTL_TYPE_ALL |
+ IGC_TSYNCRXCTL_RXSYNSIG;
+ wr32(IGC_TSYNCRXCTL, val);
}
-static void igc_ptp_enable_tstamp_all_rxqueues(struct igc_adapter *adapter,
- u8 timer)
+static void igc_ptp_disable_tx_timestamp(struct igc_adapter *adapter)
{
- int i;
+ struct igc_hw *hw = &adapter->hw;
- for (i = 0; i < adapter->num_rx_queues; i++) {
- struct igc_ring *ring = adapter->rx_ring[i];
+ wr32(IGC_TSYNCTXCTL, 0);
+}
- igc_ptp_enable_tstamp_rxqueue(adapter, ring, timer);
- }
+static void igc_ptp_enable_tx_timestamp(struct igc_adapter *adapter)
+{
+ struct igc_hw *hw = &adapter->hw;
+
+ wr32(IGC_TSYNCTXCTL, IGC_TSYNCTXCTL_ENABLED | IGC_TSYNCTXCTL_TXSYNSIG);
+
+ /* Read TXSTMP registers to discard any timestamp previously stored. */
+ rd32(IGC_TXSTMPL);
+ rd32(IGC_TXSTMPH);
}
/**
@@ -284,37 +272,21 @@ static void igc_ptp_enable_tstamp_all_rxqueues(struct igc_adapter *adapter,
* @adapter: networking device structure
* @config: hwtstamp configuration
*
- * Outgoing time stamping can be enabled and disabled. Play nice and
- * disable it when requested, although it shouldn't case any overhead
- * when no packet needs it. At most one packet in the queue may be
- * marked for time stamping, otherwise it would be impossible to tell
- * for sure to which packet the hardware time stamp belongs.
- *
- * Incoming time stamping has to be configured via the hardware
- * filters. Not all combinations are supported, in particular event
- * type has to be specified. Matching the kind of event packet is
- * not supported, with the exception of "all V2 events regardless of
- * level 2 or 4".
- *
+ * Return: 0 in case of success, negative errno code otherwise.
*/
static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,
struct hwtstamp_config *config)
{
- u32 tsync_tx_ctl = IGC_TSYNCTXCTL_ENABLED;
- u32 tsync_rx_ctl = IGC_TSYNCRXCTL_ENABLED;
- struct igc_hw *hw = &adapter->hw;
- u32 tsync_rx_cfg = 0;
- bool is_l4 = false;
- u32 regval;
-
/* reserved for future extensions */
if (config->flags)
return -EINVAL;
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
- tsync_tx_ctl = 0;
+ igc_ptp_disable_tx_timestamp(adapter);
+ break;
case HWTSTAMP_TX_ON:
+ igc_ptp_enable_tx_timestamp(adapter);
break;
default:
return -ERANGE;
@@ -322,18 +294,10 @@ static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
- tsync_rx_ctl = 0;
+ igc_ptp_disable_rx_timestamp(adapter);
break;
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
- tsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_L4_V1;
- tsync_rx_cfg = IGC_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;
- is_l4 = true;
- break;
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
- tsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_L4_V1;
- tsync_rx_cfg = IGC_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;
- is_l4 = true;
- break;
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
@@ -343,99 +307,36 @@ static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
- tsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_EVENT_V2;
- config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
- is_l4 = true;
- break;
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_NTP_ALL:
case HWTSTAMP_FILTER_ALL:
- tsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_ALL;
+ igc_ptp_enable_rx_timestamp(adapter);
config->rx_filter = HWTSTAMP_FILTER_ALL;
break;
- /* fall through */
default:
- config->rx_filter = HWTSTAMP_FILTER_NONE;
return -ERANGE;
}
- /* Per-packet timestamping only works if all packets are
- * timestamped, so enable timestamping in all packets as long
- * as one Rx filter was configured.
- */
- if (tsync_rx_ctl) {
- tsync_rx_ctl = IGC_TSYNCRXCTL_ENABLED;
- tsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_ALL;
- tsync_rx_ctl |= IGC_TSYNCRXCTL_RXSYNSIG;
- config->rx_filter = HWTSTAMP_FILTER_ALL;
- is_l4 = true;
-
- if (hw->mac.type == igc_i225) {
- regval = rd32(IGC_RXPBS);
- regval |= IGC_RXPBS_CFG_TS_EN;
- wr32(IGC_RXPBS, regval);
-
- /* FIXME: For now, only support retrieving RX
- * timestamps from timer 0
- */
- igc_ptp_enable_tstamp_all_rxqueues(adapter, 0);
- }
- }
-
- if (tsync_tx_ctl) {
- tsync_tx_ctl = IGC_TSYNCTXCTL_ENABLED;
- tsync_tx_ctl |= IGC_TSYNCTXCTL_TXSYNSIG;
- }
-
- /* enable/disable TX */
- regval = rd32(IGC_TSYNCTXCTL);
- regval &= ~IGC_TSYNCTXCTL_ENABLED;
- regval |= tsync_tx_ctl;
- wr32(IGC_TSYNCTXCTL, regval);
-
- /* enable/disable RX */
- regval = rd32(IGC_TSYNCRXCTL);
- regval &= ~(IGC_TSYNCRXCTL_ENABLED | IGC_TSYNCRXCTL_TYPE_MASK);
- regval |= tsync_rx_ctl;
- wr32(IGC_TSYNCRXCTL, regval);
-
- /* define which PTP packets are time stamped */
- wr32(IGC_TSYNCRXCFG, tsync_rx_cfg);
-
- /* L4 Queue Filter[3]: filter by destination port and protocol */
- if (is_l4) {
- u32 ftqf = (IPPROTO_UDP /* UDP */
- | IGC_FTQF_VF_BP /* VF not compared */
- | IGC_FTQF_1588_TIME_STAMP /* Enable Timestamp */
- | IGC_FTQF_MASK); /* mask all inputs */
- ftqf &= ~IGC_FTQF_MASK_PROTO_BP; /* enable protocol check */
-
- wr32(IGC_IMIR(3), htons(PTP_EV_PORT));
- wr32(IGC_IMIREXT(3),
- (IGC_IMIREXT_SIZE_BP | IGC_IMIREXT_CTRL_BP));
- wr32(IGC_FTQF(3), ftqf);
- } else {
- wr32(IGC_FTQF(3), IGC_FTQF_MASK);
- }
- wrfl();
+ return 0;
+}
- /* clear TX/RX time stamp registers, just to be sure */
- regval = rd32(IGC_TXSTMPL);
- regval = rd32(IGC_TXSTMPH);
- regval = rd32(IGC_RXSTMPL);
- regval = rd32(IGC_RXSTMPH);
+static void igc_ptp_tx_timeout(struct igc_adapter *adapter)
+{
+ struct igc_hw *hw = &adapter->hw;
- return 0;
+ dev_kfree_skb_any(adapter->ptp_tx_skb);
+ adapter->ptp_tx_skb = NULL;
+ adapter->tx_hwtstamp_timeouts++;
+ clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
+ /* Clear the tx valid bit in TSYNCTXCTL register to enable interrupt. */
+ rd32(IGC_TXSTMPH);
+ netdev_warn(adapter->netdev, "Tx timestamp timeout\n");
}
void igc_ptp_tx_hang(struct igc_adapter *adapter)
{
bool timeout = time_is_before_jiffies(adapter->ptp_tx_start +
IGC_PTP_TX_TIMEOUT);
- struct igc_hw *hw = &adapter->hw;
-
- if (!adapter->ptp_tx_skb)
- return;
if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state))
return;
@@ -446,15 +347,7 @@ void igc_ptp_tx_hang(struct igc_adapter *adapter)
*/
if (timeout) {
cancel_work_sync(&adapter->ptp_tx_work);
- dev_kfree_skb_any(adapter->ptp_tx_skb);
- adapter->ptp_tx_skb = NULL;
- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
- adapter->tx_hwtstamp_timeouts++;
- /* Clear the Tx valid bit in TSYNCTXCTL register to enable
- * interrupt
- */
- rd32(IGC_TXSTMPH);
- netdev_warn(adapter->netdev, "Clearing Tx timestamp hang\n");
+ igc_ptp_tx_timeout(adapter);
}
}
@@ -473,6 +366,9 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
struct igc_hw *hw = &adapter->hw;
u64 regval;
+ if (WARN_ON_ONCE(!skb))
+ return;
+
regval = rd32(IGC_TXSTMPL);
regval |= (u64)rd32(IGC_TXSTMPH) << 32;
igc_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval);
@@ -504,20 +400,12 @@ static void igc_ptp_tx_work(struct work_struct *work)
struct igc_hw *hw = &adapter->hw;
u32 tsynctxctl;
- if (!adapter->ptp_tx_skb)
+ if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state))
return;
if (time_is_before_jiffies(adapter->ptp_tx_start +
IGC_PTP_TX_TIMEOUT)) {
- dev_kfree_skb_any(adapter->ptp_tx_skb);
- adapter->ptp_tx_skb = NULL;
- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
- adapter->tx_hwtstamp_timeouts++;
- /* Clear the tx valid bit in TSYNCTXCTL register to enable
- * interrupt
- */
- rd32(IGC_TXSTMPH);
- netdev_warn(adapter->netdev, "Clearing Tx timestamp hang\n");
+ igc_ptp_tx_timeout(adapter);
return;
}
@@ -634,11 +522,9 @@ void igc_ptp_suspend(struct igc_adapter *adapter)
return;
cancel_work_sync(&adapter->ptp_tx_work);
- if (adapter->ptp_tx_skb) {
- dev_kfree_skb_any(adapter->ptp_tx_skb);
- adapter->ptp_tx_skb = NULL;
- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
- }
+ dev_kfree_skb_any(adapter->ptp_tx_skb);
+ adapter->ptp_tx_skb = NULL;
+ clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
}
/**
diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
index 232e82dec62e..b52dd9d737e8 100644
--- a/drivers/net/ethernet/intel/igc/igc_regs.h
+++ b/drivers/net/ethernet/intel/igc/igc_regs.h
@@ -58,16 +58,6 @@
#define IGC_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
#define IGC_GPIE 0x01514 /* General Purpose Intr Enable - RW */
-/* Interrupt Cause */
-#define IGC_ICRXPTC 0x04104 /* Rx Packet Timer Expire Count */
-#define IGC_ICRXATC 0x04108 /* Rx Absolute Timer Expire Count */
-#define IGC_ICTXPTC 0x0410C /* Tx Packet Timer Expire Count */
-#define IGC_ICTXATC 0x04110 /* Tx Absolute Timer Expire Count */
-#define IGC_ICTXQEC 0x04118 /* Tx Queue Empty Count */
-#define IGC_ICTXQMTC 0x0411C /* Tx Queue Min Threshold Count */
-#define IGC_ICRXDMTC 0x04120 /* Rx Descriptor Min Threshold Count */
-#define IGC_ICRXOC 0x04124 /* Receiver Overrun Count */
-
/* MSI-X Table Register Descriptions */
#define IGC_PBACL 0x05B68 /* MSIx PBA Clear - R/W 1 to clear */
@@ -181,13 +171,10 @@
#define IGC_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */
#define IGC_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */
#define IGC_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
-#define IGC_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */
#define IGC_IAC 0x04100 /* Interrupt Assertion Count */
-#define IGC_ICTXPTC 0x0410C /* Interrupt Cause Tx Pkt Timer Expire Count */
-#define IGC_ICTXATC 0x04110 /* Interrupt Cause Tx Abs Timer Expire Count */
-#define IGC_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
-#define IGC_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */
#define IGC_RPTHC 0x04104 /* Rx Packets To Host */
+#define IGC_TLPIC 0x04148 /* EEE Tx LPI Count */
+#define IGC_RLPIC 0x0414C /* EEE Rx LPI Count */
#define IGC_HGPTC 0x04118 /* Host Good Packets Tx Count */
#define IGC_RXDMTC 0x04120 /* Rx Descriptor Minimum Threshold Count */
#define IGC_HGORCL 0x04128 /* Host Good Octets Received Count Low */
@@ -228,8 +215,6 @@
#define IGC_SYSTIMR 0x0B6F8 /* System time register Residue */
#define IGC_TIMINCA 0x0B608 /* Increment attributes register - RW */
-#define IGC_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
-#define IGC_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
#define IGC_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
#define IGC_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
@@ -248,6 +233,17 @@
/* Wake Up packet memory */
#define IGC_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
+/* Energy Efficient Ethernet "EEE" registers */
+#define IGC_EEER 0x0E30 /* Energy Efficient Ethernet "EEE"*/
+#define IGC_IPCNFG 0x0E38 /* Internal PHY Configuration */
+#define IGC_EEE_SU 0x0E34 /* EEE Setup */
+
+/* LTR registers */
+#define IGC_LTRC 0x01A0 /* Latency Tolerance Reporting Control */
+#define IGC_DMACR 0x02508 /* DMA Coalescing Control Register */
+#define IGC_LTRMINV 0x5BB0 /* LTR Minimum Value */
+#define IGC_LTRMAXV 0x5BB4 /* LTR Maximum Value */
+
/* forward declaration */
struct igc_hw;
u32 igc_rd32(struct igc_hw *hw, u32 reg);
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb.h b/drivers/net/ethernet/intel/ixgb/ixgb.h
index 681d44cc9784..81ac39576803 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb.h
+++ b/drivers/net/ethernet/intel/ixgb/ixgb.h
@@ -163,7 +163,6 @@ enum ixgb_state_t {
void ixgb_check_options(struct ixgb_adapter *adapter);
void ixgb_set_ethtool_ops(struct net_device *netdev);
extern char ixgb_driver_name[];
-extern const char ixgb_driver_version[];
void ixgb_set_speed_duplex(struct net_device *netdev);
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
index c65eb1afc8fb..582099a5ad41 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
@@ -458,8 +458,6 @@ ixgb_get_drvinfo(struct net_device *netdev,
strlcpy(drvinfo->driver, ixgb_driver_name,
sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, ixgb_driver_version,
- sizeof(drvinfo->version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
}
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
index b64e91ea3465..46829cfd54df 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
@@ -9,9 +9,6 @@
char ixgb_driver_name[] = "ixgb";
static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
-#define DRIVERNAPI "-NAPI"
-#define DRV_VERSION "1.0.135-k2" DRIVERNAPI
-const char ixgb_driver_version[] = DRV_VERSION;
static const char ixgb_copyright[] = "Copyright (c) 1999-2008 Intel Corporation.";
#define IXGB_CB_LENGTH 256
@@ -103,7 +100,6 @@ static struct pci_driver ixgb_driver = {
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION("Intel(R) PRO/10GbE Network Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
static int debug = -1;
@@ -120,7 +116,7 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
static int __init
ixgb_init_module(void)
{
- pr_info("%s - version %s\n", ixgb_driver_string, ixgb_driver_version);
+ pr_info("%s\n", ixgb_driver_string);
pr_info("%s\n", ixgb_copyright);
return pci_register_driver(&ixgb_driver);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5ddfc83a1e46..1e8a809233a0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -588,11 +588,9 @@ struct ixgbe_adapter {
#define IXGBE_FLAG_FCOE_ENABLED BIT(21)
#define IXGBE_FLAG_SRIOV_CAPABLE BIT(22)
#define IXGBE_FLAG_SRIOV_ENABLED BIT(23)
-#define IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE BIT(24)
#define IXGBE_FLAG_RX_HWTSTAMP_ENABLED BIT(25)
#define IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER BIT(26)
#define IXGBE_FLAG_DCB_CAPABLE BIT(27)
-#define IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE BIT(28)
u32 flags2;
#define IXGBE_FLAG2_RSC_CAPABLE BIT(0)
@@ -606,7 +604,6 @@ struct ixgbe_adapter {
#define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP BIT(9)
#define IXGBE_FLAG2_PTP_PPS_ENABLED BIT(10)
#define IXGBE_FLAG2_PHY_INTERRUPT BIT(11)
-#define IXGBE_FLAG2_UDP_TUN_REREG_NEEDED BIT(12)
#define IXGBE_FLAG2_VLAN_PROMISC BIT(13)
#define IXGBE_FLAG2_EEE_CAPABLE BIT(14)
#define IXGBE_FLAG2_EEE_ENABLED BIT(15)
@@ -846,7 +843,6 @@ extern const struct dcbnl_rtnl_ops ixgbe_dcbnl_ops;
#endif
extern char ixgbe_driver_name[];
-extern const char ixgbe_driver_version[];
#ifdef IXGBE_FCOE
extern char ixgbe_default_device_descr[];
#endif /* IXGBE_FCOE */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index eee277c1bedf..95c92fe890a1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -1098,7 +1098,7 @@ static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
/* Setup the last four at 48KB...don't re-init i */
rxpktsize = IXGBE_RXPBSIZE_48KB;
- /* Fall Through */
+ fallthrough;
case PBA_STRATEGY_EQUAL:
default:
/* Divide the remaining Rx packet buffer evenly among the TCs */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index 109f8de5a1c2..8d3798a32f0e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -1568,7 +1568,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
case 0x0000:
/* mask VLAN ID */
fdirm |= IXGBE_FDIRM_VLANID;
- /* fall through */
+ fallthrough;
case 0x0FFF:
/* mask VLAN priority */
fdirm |= IXGBE_FDIRM_VLANP;
@@ -1576,7 +1576,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
case 0xE000:
/* mask VLAN ID only */
fdirm |= IXGBE_FDIRM_VLANID;
- /* fall through */
+ fallthrough;
case 0xEFFF:
/* no VLAN fields masked */
break;
@@ -1589,7 +1589,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
case 0x0000:
/* Mask Flex Bytes */
fdirm |= IXGBE_FDIRM_FLEX;
- /* fall through */
+ fallthrough;
case 0xFFFF:
break;
default:
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 17357a12cbdc..62ddb452f862 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -145,7 +145,7 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw)
if (ret_val)
return ret_val;
- /* fall through - only backplane uses autoc */
+ fallthrough; /* only backplane uses autoc */
case ixgbe_media_type_fiber:
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
@@ -3533,7 +3533,7 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw,
rxpktsize <<= IXGBE_RXPBSIZE_SHIFT;
for (; i < (num_pb / 2); i++)
IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
- /* fall through - configure remaining packet buffers */
+ fallthrough; /* configure remaining packet buffers */
case (PBA_STRATEGY_EQUAL):
/* Divide the remaining Rx packet buffer evenly among the TCs */
rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index c6bf0a50ee63..71ec908266a6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -142,32 +142,71 @@ static const char ixgbe_priv_flags_strings[][ETH_GSTRING_LEN] = {
#define IXGBE_PRIV_FLAGS_STR_LEN ARRAY_SIZE(ixgbe_priv_flags_strings)
-/* currently supported speeds for 10G */
-#define ADVRTSD_MSK_10G (SUPPORTED_10000baseT_Full | \
- SUPPORTED_10000baseKX4_Full | \
- SUPPORTED_10000baseKR_Full)
-
#define ixgbe_isbackplane(type) ((type) == ixgbe_media_type_backplane)
-static u32 ixgbe_get_supported_10gtypes(struct ixgbe_hw *hw)
+static void ixgbe_set_supported_10gtypes(struct ixgbe_hw *hw,
+ struct ethtool_link_ksettings *cmd)
+{
+ if (!ixgbe_isbackplane(hw->phy.media_type)) {
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 10000baseT_Full);
+ return;
+ }
+
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598:
+ case IXGBE_DEV_ID_82599_KX4:
+ case IXGBE_DEV_ID_82599_KX4_MEZZ:
+ case IXGBE_DEV_ID_X550EM_X_KX4:
+ ethtool_link_ksettings_add_link_mode
+ (cmd, supported, 10000baseKX4_Full);
+ break;
+ case IXGBE_DEV_ID_82598_BX:
+ case IXGBE_DEV_ID_82599_KR:
+ case IXGBE_DEV_ID_X550EM_X_KR:
+ case IXGBE_DEV_ID_X550EM_X_XFI:
+ ethtool_link_ksettings_add_link_mode
+ (cmd, supported, 10000baseKR_Full);
+ break;
+ default:
+ ethtool_link_ksettings_add_link_mode
+ (cmd, supported, 10000baseKX4_Full);
+ ethtool_link_ksettings_add_link_mode
+ (cmd, supported, 10000baseKR_Full);
+ break;
+ }
+}
+
+static void ixgbe_set_advertising_10gtypes(struct ixgbe_hw *hw,
+ struct ethtool_link_ksettings *cmd)
{
- if (!ixgbe_isbackplane(hw->phy.media_type))
- return SUPPORTED_10000baseT_Full;
+ if (!ixgbe_isbackplane(hw->phy.media_type)) {
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 10000baseT_Full);
+ return;
+ }
switch (hw->device_id) {
case IXGBE_DEV_ID_82598:
case IXGBE_DEV_ID_82599_KX4:
case IXGBE_DEV_ID_82599_KX4_MEZZ:
case IXGBE_DEV_ID_X550EM_X_KX4:
- return SUPPORTED_10000baseKX4_Full;
+ ethtool_link_ksettings_add_link_mode
+ (cmd, advertising, 10000baseKX4_Full);
+ break;
case IXGBE_DEV_ID_82598_BX:
case IXGBE_DEV_ID_82599_KR:
case IXGBE_DEV_ID_X550EM_X_KR:
case IXGBE_DEV_ID_X550EM_X_XFI:
- return SUPPORTED_10000baseKR_Full;
+ ethtool_link_ksettings_add_link_mode
+ (cmd, advertising, 10000baseKR_Full);
+ break;
default:
- return SUPPORTED_10000baseKX4_Full |
- SUPPORTED_10000baseKR_Full;
+ ethtool_link_ksettings_add_link_mode
+ (cmd, advertising, 10000baseKX4_Full);
+ ethtool_link_ksettings_add_link_mode
+ (cmd, advertising, 10000baseKR_Full);
+ break;
}
}
@@ -178,52 +217,88 @@ static int ixgbe_get_link_ksettings(struct net_device *netdev,
struct ixgbe_hw *hw = &adapter->hw;
ixgbe_link_speed supported_link;
bool autoneg = false;
- u32 supported, advertising;
- ethtool_convert_link_mode_to_legacy_u32(&supported,
- cmd->link_modes.supported);
+ ethtool_link_ksettings_zero_link_mode(cmd, supported);
+ ethtool_link_ksettings_zero_link_mode(cmd, advertising);
hw->mac.ops.get_link_capabilities(hw, &supported_link, &autoneg);
/* set the supported link speeds */
- if (supported_link & IXGBE_LINK_SPEED_10GB_FULL)
- supported |= ixgbe_get_supported_10gtypes(hw);
- if (supported_link & IXGBE_LINK_SPEED_1GB_FULL)
- supported |= (ixgbe_isbackplane(hw->phy.media_type)) ?
- SUPPORTED_1000baseKX_Full :
- SUPPORTED_1000baseT_Full;
- if (supported_link & IXGBE_LINK_SPEED_100_FULL)
- supported |= SUPPORTED_100baseT_Full;
- if (supported_link & IXGBE_LINK_SPEED_10_FULL)
- supported |= SUPPORTED_10baseT_Full;
-
- /* default advertised speed if phy.autoneg_advertised isn't set */
- advertising = supported;
+ if (supported_link & IXGBE_LINK_SPEED_10GB_FULL) {
+ ixgbe_set_supported_10gtypes(hw, cmd);
+ ixgbe_set_advertising_10gtypes(hw, cmd);
+ }
+ if (supported_link & IXGBE_LINK_SPEED_5GB_FULL)
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 5000baseT_Full);
+
+ if (supported_link & IXGBE_LINK_SPEED_2_5GB_FULL)
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 2500baseT_Full);
+
+ if (supported_link & IXGBE_LINK_SPEED_1GB_FULL) {
+ if (ixgbe_isbackplane(hw->phy.media_type)) {
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 1000baseKX_Full);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 1000baseKX_Full);
+ } else {
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 1000baseT_Full);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 1000baseT_Full);
+ }
+ }
+ if (supported_link & IXGBE_LINK_SPEED_100_FULL) {
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 100baseT_Full);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 100baseT_Full);
+ }
+ if (supported_link & IXGBE_LINK_SPEED_10_FULL) {
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ 10baseT_Full);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 10baseT_Full);
+ }
+
/* set the advertised speeds */
if (hw->phy.autoneg_advertised) {
- advertising = 0;
+ ethtool_link_ksettings_zero_link_mode(cmd, advertising);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10_FULL)
- advertising |= ADVERTISED_10baseT_Full;
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 10baseT_Full);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
- advertising |= ADVERTISED_100baseT_Full;
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 100baseT_Full);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
- advertising |= supported & ADVRTSD_MSK_10G;
+ ixgbe_set_advertising_10gtypes(hw, cmd);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) {
- if (supported & SUPPORTED_1000baseKX_Full)
- advertising |= ADVERTISED_1000baseKX_Full;
+ if (ethtool_link_ksettings_test_link_mode
+ (cmd, supported, 1000baseKX_Full))
+ ethtool_link_ksettings_add_link_mode
+ (cmd, advertising, 1000baseKX_Full);
else
- advertising |= ADVERTISED_1000baseT_Full;
+ ethtool_link_ksettings_add_link_mode
+ (cmd, advertising, 1000baseT_Full);
}
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL)
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 5000baseT_Full);
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ 2500baseT_Full);
} else {
if (hw->phy.multispeed_fiber && !autoneg) {
if (supported_link & IXGBE_LINK_SPEED_10GB_FULL)
- advertising = ADVERTISED_10000baseT_Full;
+ ethtool_link_ksettings_add_link_mode
+ (cmd, advertising, 10000baseT_Full);
}
}
if (autoneg) {
- supported |= SUPPORTED_Autoneg;
- advertising |= ADVERTISED_Autoneg;
+ ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
cmd->base.autoneg = AUTONEG_ENABLE;
} else
cmd->base.autoneg = AUTONEG_DISABLE;
@@ -235,13 +310,13 @@ static int ixgbe_get_link_ksettings(struct net_device *netdev,
case ixgbe_phy_x550em_ext_t:
case ixgbe_phy_fw:
case ixgbe_phy_cu_unknown:
- supported |= SUPPORTED_TP;
- advertising |= ADVERTISED_TP;
+ ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
cmd->base.port = PORT_TP;
break;
case ixgbe_phy_qt:
- supported |= SUPPORTED_FIBRE;
- advertising |= ADVERTISED_FIBRE;
+ ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
cmd->base.port = PORT_FIBRE;
break;
case ixgbe_phy_nl:
@@ -260,8 +335,10 @@ static int ixgbe_get_link_ksettings(struct net_device *netdev,
case ixgbe_sfp_type_da_cu:
case ixgbe_sfp_type_da_cu_core0:
case ixgbe_sfp_type_da_cu_core1:
- supported |= SUPPORTED_FIBRE;
- advertising |= ADVERTISED_FIBRE;
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ FIBRE);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ FIBRE);
cmd->base.port = PORT_DA;
break;
case ixgbe_sfp_type_sr:
@@ -272,61 +349,76 @@ static int ixgbe_get_link_ksettings(struct net_device *netdev,
case ixgbe_sfp_type_1g_sx_core1:
case ixgbe_sfp_type_1g_lx_core0:
case ixgbe_sfp_type_1g_lx_core1:
- supported |= SUPPORTED_FIBRE;
- advertising |= ADVERTISED_FIBRE;
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ FIBRE);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ FIBRE);
cmd->base.port = PORT_FIBRE;
break;
case ixgbe_sfp_type_not_present:
- supported |= SUPPORTED_FIBRE;
- advertising |= ADVERTISED_FIBRE;
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ FIBRE);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ FIBRE);
cmd->base.port = PORT_NONE;
break;
case ixgbe_sfp_type_1g_cu_core0:
case ixgbe_sfp_type_1g_cu_core1:
- supported |= SUPPORTED_TP;
- advertising |= ADVERTISED_TP;
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ TP);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ TP);
cmd->base.port = PORT_TP;
break;
case ixgbe_sfp_type_unknown:
default:
- supported |= SUPPORTED_FIBRE;
- advertising |= ADVERTISED_FIBRE;
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ FIBRE);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ FIBRE);
cmd->base.port = PORT_OTHER;
break;
}
break;
case ixgbe_phy_xaui:
- supported |= SUPPORTED_FIBRE;
- advertising |= ADVERTISED_FIBRE;
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ FIBRE);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ FIBRE);
cmd->base.port = PORT_NONE;
break;
case ixgbe_phy_unknown:
case ixgbe_phy_generic:
case ixgbe_phy_sfp_unsupported:
default:
- supported |= SUPPORTED_FIBRE;
- advertising |= ADVERTISED_FIBRE;
+ ethtool_link_ksettings_add_link_mode(cmd, supported,
+ FIBRE);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ FIBRE);
cmd->base.port = PORT_OTHER;
break;
}
/* Indicate pause support */
- supported |= SUPPORTED_Pause;
+ ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
switch (hw->fc.requested_mode) {
case ixgbe_fc_full:
- advertising |= ADVERTISED_Pause;
+ ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause);
break;
case ixgbe_fc_rx_pause:
- advertising |= ADVERTISED_Pause |
- ADVERTISED_Asym_Pause;
+ ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause);
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ Asym_Pause);
break;
case ixgbe_fc_tx_pause:
- advertising |= ADVERTISED_Asym_Pause;
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ Asym_Pause);
break;
default:
- advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
+ ethtool_link_ksettings_del_link_mode(cmd, advertising, Pause);
+ ethtool_link_ksettings_del_link_mode(cmd, advertising,
+ Asym_Pause);
}
if (netif_carrier_ok(netdev)) {
@@ -358,11 +450,6 @@ static int ixgbe_get_link_ksettings(struct net_device *netdev,
cmd->base.duplex = DUPLEX_UNKNOWN;
}
- ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
- supported);
- ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
- advertising);
-
return 0;
}
@@ -373,12 +460,6 @@ static int ixgbe_set_link_ksettings(struct net_device *netdev,
struct ixgbe_hw *hw = &adapter->hw;
u32 advertised, old;
s32 err = 0;
- u32 supported, advertising;
-
- ethtool_convert_link_mode_to_legacy_u32(&supported,
- cmd->link_modes.supported);
- ethtool_convert_link_mode_to_legacy_u32(&advertising,
- cmd->link_modes.advertising);
if ((hw->phy.media_type == ixgbe_media_type_copper) ||
(hw->phy.multispeed_fiber)) {
@@ -386,29 +467,41 @@ static int ixgbe_set_link_ksettings(struct net_device *netdev,
* this function does not support duplex forcing, but can
* limit the advertising of the adapter to the specified speed
*/
- if (advertising & ~supported)
+ if (!bitmap_subset(cmd->link_modes.advertising,
+ cmd->link_modes.supported,
+ __ETHTOOL_LINK_MODE_MASK_NBITS))
return -EINVAL;
/* only allow one speed at a time if no autoneg */
if (!cmd->base.autoneg && hw->phy.multispeed_fiber) {
- if (advertising ==
- (ADVERTISED_10000baseT_Full |
- ADVERTISED_1000baseT_Full))
+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
+ 10000baseT_Full) &&
+ ethtool_link_ksettings_test_link_mode(cmd, advertising,
+ 1000baseT_Full))
return -EINVAL;
}
old = hw->phy.autoneg_advertised;
advertised = 0;
- if (advertising & ADVERTISED_10000baseT_Full)
+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
+ 10000baseT_Full))
advertised |= IXGBE_LINK_SPEED_10GB_FULL;
-
- if (advertising & ADVERTISED_1000baseT_Full)
+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
+ 5000baseT_Full))
+ advertised |= IXGBE_LINK_SPEED_5GB_FULL;
+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
+ 2500baseT_Full))
+ advertised |= IXGBE_LINK_SPEED_2_5GB_FULL;
+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
+ 1000baseT_Full))
advertised |= IXGBE_LINK_SPEED_1GB_FULL;
- if (advertising & ADVERTISED_100baseT_Full)
+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
+ 100baseT_Full))
advertised |= IXGBE_LINK_SPEED_100_FULL;
- if (advertising & ADVERTISED_10baseT_Full)
+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
+ 10baseT_Full))
advertised |= IXGBE_LINK_SPEED_10_FULL;
if (old == advertised)
@@ -429,7 +522,8 @@ static int ixgbe_set_link_ksettings(struct net_device *netdev,
u32 speed = cmd->base.speed;
if ((cmd->base.autoneg == AUTONEG_ENABLE) ||
- (advertising != ADVERTISED_10000baseT_Full) ||
+ (!ethtool_link_ksettings_test_link_mode(cmd, advertising,
+ 10000baseT_Full)) ||
(speed + cmd->base.duplex != SPEED_10000 + DUPLEX_FULL))
return -EINVAL;
}
@@ -1004,8 +1098,6 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, ixgbe_driver_version,
- sizeof(drvinfo->version));
strlcpy(drvinfo->fw_version, adapter->eeprom_id,
sizeof(drvinfo->fw_version));
@@ -1859,8 +1951,8 @@ static void ixgbe_create_lbtest_frame(struct sk_buff *skb,
memset(skb->data, 0xFF, frame_size);
frame_size >>= 1;
memset(&skb->data[frame_size], 0xAA, frame_size / 2 - 1);
- memset(&skb->data[frame_size + 10], 0xBE, 1);
- memset(&skb->data[frame_size + 12], 0xAF, 1);
+ skb->data[frame_size + 10] = 0xBE;
+ skb->data[frame_size + 12] = 0xAF;
}
static bool ixgbe_check_lbtest_frame(struct ixgbe_rx_buffer *rx_buffer,
@@ -2086,7 +2178,7 @@ static void ixgbe_diag_test(struct net_device *netdev,
eth_test->flags |= ETH_TEST_FL_FAILED;
clear_bit(__IXGBE_TESTING,
&adapter->state);
- goto skip_ol_tests;
+ return;
}
}
}
@@ -2158,9 +2250,6 @@ skip_loopback:
clear_bit(__IXGBE_TESTING, &adapter->state);
}
-
-skip_ol_tests:
- msleep_interruptible(4 * 1000);
}
static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter,
@@ -2509,11 +2598,11 @@ static int ixgbe_get_rss_hash_opts(struct ixgbe_adapter *adapter,
switch (cmd->flow_type) {
case TCP_V4_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fallthrough */
+ fallthrough;
case UDP_V4_FLOW:
if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV4_UDP)
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fallthrough */
+ fallthrough;
case SCTP_V4_FLOW:
case AH_ESP_V4_FLOW:
case AH_V4_FLOW:
@@ -2523,11 +2612,11 @@ static int ixgbe_get_rss_hash_opts(struct ixgbe_adapter *adapter,
break;
case TCP_V6_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fallthrough */
+ fallthrough;
case UDP_V6_FLOW:
if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP)
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- /* fallthrough */
+ fallthrough;
case SCTP_V6_FLOW:
case AH_ESP_V6_FLOW:
case AH_V6_FLOW:
@@ -2659,7 +2748,7 @@ static int ixgbe_flowspec_to_flow_type(struct ethtool_rx_flow_spec *fsp,
*flow_type = IXGBE_ATR_FLOW_TYPE_IPV4;
break;
}
- /* fall through */
+ fallthrough;
default:
return 0;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
index ec7a11d13fdc..e67b1a59ecb7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
@@ -5,6 +5,7 @@
#include <linux/if_ether.h>
#include <linux/gfp.h>
#include <linux/if_vlan.h>
+#include <generated/utsrelease.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/fc/fc_fs.h>
@@ -443,7 +444,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
ddp->err = (__force u32)ddp_err;
ddp->sgl = NULL;
ddp->sgc = 0;
- /* fall through */
+ fallthrough;
/* if DDP length is present pass it through to ULD */
case cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NODDP):
/* update length of DDPed data */
@@ -1001,7 +1002,7 @@ int ixgbe_fcoe_get_hbainfo(struct net_device *netdev,
sizeof(info->driver_version),
"%s v%s",
ixgbe_driver_name,
- ixgbe_driver_version);
+ UTS_RELEASE);
/* Firmware Version */
strlcpy(info->firmware_version, adapter->eeprom_id,
sizeof(info->firmware_version));
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 113f6087c7c9..6516980965a2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -427,7 +427,7 @@ static struct xfrm_state *ixgbe_ipsec_find_rx_state(struct ixgbe_ipsec *ipsec,
static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
u32 *mykey, u32 *mysalt)
{
- struct net_device *dev = xs->xso.dev;
+ struct net_device *dev = xs->xso.real_dev;
unsigned char *key_data;
char *alg_name = NULL;
int key_len;
@@ -477,7 +477,7 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
**/
static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
{
- struct net_device *dev = xs->xso.dev;
+ struct net_device *dev = xs->xso.real_dev;
struct ixgbe_adapter *adapter = netdev_priv(dev);
struct ixgbe_hw *hw = &adapter->hw;
u32 mfval, manc, reg;
@@ -560,7 +560,7 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
**/
static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
{
- struct net_device *dev = xs->xso.dev;
+ struct net_device *dev = xs->xso.real_dev;
struct ixgbe_adapter *adapter = netdev_priv(dev);
struct ixgbe_ipsec *ipsec = adapter->ipsec;
struct ixgbe_hw *hw = &adapter->hw;
@@ -745,7 +745,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
**/
static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)
{
- struct net_device *dev = xs->xso.dev;
+ struct net_device *dev = xs->xso.real_dev;
struct ixgbe_adapter *adapter = netdev_priv(dev);
struct ixgbe_ipsec *ipsec = adapter->ipsec;
struct ixgbe_hw *hw = &adapter->hw;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 97a423ecf808..2f8a4cfc5fa1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -28,6 +28,7 @@
#include <linux/bpf_trace.h>
#include <linux/atomic.h>
#include <linux/numa.h>
+#include <generated/utsrelease.h>
#include <scsi/fc/fc_fcoe.h>
#include <net/udp_tunnel.h>
#include <net/pkt_cls.h>
@@ -56,8 +57,6 @@ char ixgbe_default_device_descr[] =
static char ixgbe_default_device_descr[] =
"Intel(R) 10 Gigabit Network Connection";
#endif
-#define DRV_VERSION "5.1.0-k"
-const char ixgbe_driver_version[] = DRV_VERSION;
static const char ixgbe_copyright[] =
"Copyright (c) 1999-2016 Intel Corporation.";
@@ -165,7 +164,6 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
static struct workqueue_struct *ixgbe_wq;
@@ -1397,7 +1395,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
IXGBE_DCA_CTRL_DCA_MODE_CB2);
break;
}
- /* fall through - DCA is disabled. */
+ fallthrough; /* DCA is disabled. */
case DCA_PROVIDER_REMOVE:
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
dca_remove_requester(dev);
@@ -2231,10 +2229,10 @@ static struct sk_buff *ixgbe_run_xdp(struct ixgbe_adapter *adapter,
break;
default:
bpf_warn_invalid_xdp_action(act);
- /* fallthrough */
+ fallthrough;
case XDP_ABORTED:
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
- /* fallthrough -- handle aborts by dropping packet */
+ fallthrough; /* handle aborts by dropping packet */
case XDP_DROP:
result = IXGBE_XDP_CONSUMED;
break;
@@ -3009,7 +3007,7 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues,
case ixgbe_mac_82599EB:
mask |= IXGBE_EIMS_GPI_SDP1(hw);
mask |= IXGBE_EIMS_GPI_SDP2(hw);
- /* fall through */
+ fallthrough;
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
@@ -3315,7 +3313,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
ixgbe_check_sfp_event(adapter, eicr);
- /* Fall through */
+ fallthrough;
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
@@ -4337,7 +4335,7 @@ static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter)
case ixgbe_mac_x550em_a:
if (adapter->num_vfs)
rdrxctl |= IXGBE_RDRXCTL_PSP;
- /* fall through */
+ fallthrough;
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
/* Disable RSC for ACK packets */
@@ -4996,24 +4994,41 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
napi_disable(&adapter->q_vector[q_idx]->napi);
}
-static void ixgbe_clear_udp_tunnel_port(struct ixgbe_adapter *adapter, u32 mask)
+static int ixgbe_udp_tunnel_sync(struct net_device *dev, unsigned int table)
{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
struct ixgbe_hw *hw = &adapter->hw;
- u32 vxlanctrl;
+ struct udp_tunnel_info ti;
- if (!(adapter->flags & (IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE |
- IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)))
- return;
+ udp_tunnel_nic_get_port(dev, table, 0, &ti);
+ if (ti.type == UDP_TUNNEL_TYPE_VXLAN)
+ adapter->vxlan_port = ti.port;
+ else
+ adapter->geneve_port = ti.port;
- vxlanctrl = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) & ~mask;
- IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, vxlanctrl);
+ IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL,
+ ntohs(adapter->vxlan_port) |
+ ntohs(adapter->geneve_port) <<
+ IXGBE_VXLANCTRL_GENEVE_UDPPORT_SHIFT);
+ return 0;
+}
- if (mask & IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK)
- adapter->vxlan_port = 0;
+static const struct udp_tunnel_nic_info ixgbe_udp_tunnels_x550 = {
+ .sync_table = ixgbe_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_IPV4_ONLY,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
- if (mask & IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK)
- adapter->geneve_port = 0;
-}
+static const struct udp_tunnel_nic_info ixgbe_udp_tunnels_x550em_a = {
+ .sync_table = ixgbe_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_IPV4_ONLY,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+ },
+};
#ifdef CONFIG_IXGBE_DCB
/**
@@ -5503,9 +5518,13 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
return ret;
speed = hw->phy.autoneg_advertised;
- if ((!speed) && (hw->mac.ops.get_link_capabilities))
+ if (!speed && hw->mac.ops.get_link_capabilities) {
ret = hw->mac.ops.get_link_capabilities(hw, &speed,
&autoneg);
+ speed &= ~(IXGBE_LINK_SPEED_5GB_FULL |
+ IXGBE_LINK_SPEED_2_5GB_FULL);
+ }
+
if (ret)
return ret;
@@ -5887,7 +5906,7 @@ dma_engine_disable:
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
(IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
~IXGBE_DMATXCTL_TE));
- /* fall through */
+ fallthrough;
default:
break;
}
@@ -6330,7 +6349,6 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
break;
case ixgbe_mac_x550em_a:
- adapter->flags |= IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE;
switch (hw->device_id) {
case IXGBE_DEV_ID_X550EM_A_1G_T:
case IXGBE_DEV_ID_X550EM_A_1G_T_L:
@@ -6339,7 +6357,7 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
default:
break;
}
- /* fall through */
+ fallthrough;
case ixgbe_mac_X550EM_x:
#ifdef CONFIG_IXGBE_DCB
adapter->flags &= ~IXGBE_FLAG_DCB_CAPABLE;
@@ -6350,14 +6368,13 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
adapter->fcoe.up = 0;
#endif /* IXGBE_DCB */
#endif /* IXGBE_FCOE */
- /* Fall Through */
+ fallthrough;
case ixgbe_mac_X550:
if (hw->mac.type == ixgbe_mac_X550)
adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
#ifdef CONFIG_IXGBE_DCA
adapter->flags &= ~IXGBE_FLAG_DCA_CAPABLE;
#endif
- adapter->flags |= IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE;
break;
default:
break;
@@ -6796,8 +6813,7 @@ int ixgbe_open(struct net_device *netdev)
ixgbe_up_complete(adapter);
- ixgbe_clear_udp_tunnel_port(adapter, IXGBE_VXLANCTRL_ALL_UDPPORT_MASK);
- udp_tunnel_get_rx_info(netdev);
+ udp_tunnel_nic_reset_ntf(netdev);
return 0;
@@ -6861,32 +6877,20 @@ int ixgbe_close(struct net_device *netdev)
return 0;
}
-#ifdef CONFIG_PM
-static int ixgbe_resume(struct pci_dev *pdev)
+static int __maybe_unused ixgbe_resume(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *netdev = adapter->netdev;
u32 err;
adapter->hw.hw_addr = adapter->io_addr;
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- /*
- * pci_restore_state clears dev->state_saved so call
- * pci_save_state to restore it.
- */
- pci_save_state(pdev);
- err = pci_enable_device_mem(pdev);
- if (err) {
- e_dev_err("Cannot enable PCI device from suspend\n");
- return err;
- }
smp_mb__before_atomic();
clear_bit(__IXGBE_DISABLED, &adapter->state);
pci_set_master(pdev);
- pci_wake_from_d3(pdev, false);
+ device_wakeup_disable(dev_d);
ixgbe_reset(adapter);
@@ -6904,7 +6908,6 @@ static int ixgbe_resume(struct pci_dev *pdev)
return err;
}
-#endif /* CONFIG_PM */
static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
{
@@ -6913,9 +6916,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
struct ixgbe_hw *hw = &adapter->hw;
u32 ctrl;
u32 wufc = adapter->wol;
-#ifdef CONFIG_PM
- int retval = 0;
-#endif
rtnl_lock();
netif_device_detach(netdev);
@@ -6926,12 +6926,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
ixgbe_clear_interrupt_scheme(adapter);
rtnl_unlock();
-#ifdef CONFIG_PM
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-
-#endif
if (hw->mac.ops.stop_link_on_d3)
hw->mac.ops.stop_link_on_d3(hw);
@@ -6986,26 +6980,18 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
return 0;
}
-#ifdef CONFIG_PM
-static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused ixgbe_suspend(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
int retval;
bool wake;
retval = __ixgbe_shutdown(pdev, &wake);
- if (retval)
- return retval;
- if (wake) {
- pci_prepare_to_sleep(pdev);
- } else {
- pci_wake_from_d3(pdev, false);
- pci_set_power_state(pdev, PCI_D3hot);
- }
+ device_set_wakeup_enable(dev_d, wake);
- return 0;
+ return retval;
}
-#endif /* CONFIG_PM */
static void ixgbe_shutdown(struct pci_dev *pdev)
{
@@ -7170,7 +7156,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
hwstats->o2bspc += IXGBE_READ_REG(hw, IXGBE_O2BSPC);
hwstats->b2ospc += IXGBE_READ_REG(hw, IXGBE_B2OSPC);
hwstats->b2ogprc += IXGBE_READ_REG(hw, IXGBE_B2OGPRC);
- /* fall through */
+ fallthrough;
case ixgbe_mac_82599EB:
for (i = 0; i < 16; i++)
adapter->hw_rx_no_dma_resources +=
@@ -7919,12 +7905,6 @@ static void ixgbe_service_task(struct work_struct *work)
ixgbe_service_event_complete(adapter);
return;
}
- if (adapter->flags2 & IXGBE_FLAG2_UDP_TUN_REREG_NEEDED) {
- rtnl_lock();
- adapter->flags2 &= ~IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
- udp_tunnel_get_rx_info(adapter->netdev);
- rtnl_unlock();
- }
ixgbe_reset_subtask(adapter);
ixgbe_phy_interrupt_subtask(adapter);
ixgbe_sfp_detection_subtask(adapter);
@@ -8079,7 +8059,7 @@ csum_failed:
switch (skb->csum_offset) {
case offsetof(struct tcphdr, check):
type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;
- /* fall through */
+ fallthrough;
case offsetof(struct udphdr, check):
break;
case offsetof(struct sctphdr, checksum):
@@ -8091,7 +8071,7 @@ csum_failed:
type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_SCTP;
break;
}
- /* fall through */
+ fallthrough;
default:
skb_checksum_help(skb);
goto csum_failed;
@@ -8534,7 +8514,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
if (!sb_dev && (adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
break;
- /* fall through */
+ fallthrough;
default:
return netdev_pick_tx(dev, skb, sb_dev);
}
@@ -8868,7 +8848,7 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
case SIOCGMIIPHY:
if (!adapter->hw.phy.ops.read_reg)
return -EOPNOTSUPP;
- /* fall through */
+ fallthrough;
default:
return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
}
@@ -9782,26 +9762,6 @@ static int ixgbe_set_features(struct net_device *netdev,
netdev->features = features;
- if ((adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE)) {
- if (features & NETIF_F_RXCSUM) {
- adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
- } else {
- u32 port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK;
-
- ixgbe_clear_udp_tunnel_port(adapter, port_mask);
- }
- }
-
- if ((adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)) {
- if (features & NETIF_F_RXCSUM) {
- adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
- } else {
- u32 port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK;
-
- ixgbe_clear_udp_tunnel_port(adapter, port_mask);
- }
- }
-
if ((changed & NETIF_F_HW_L2FW_DOFFLOAD) && adapter->num_rx_pools > 1)
ixgbe_reset_l2fw_offload(adapter);
else if (need_reset)
@@ -9813,118 +9773,6 @@ static int ixgbe_set_features(struct net_device *netdev,
return 1;
}
-/**
- * ixgbe_add_udp_tunnel_port - Get notifications about adding UDP tunnel ports
- * @dev: The port's netdev
- * @ti: Tunnel endpoint information
- **/
-static void ixgbe_add_udp_tunnel_port(struct net_device *dev,
- struct udp_tunnel_info *ti)
-{
- struct ixgbe_adapter *adapter = netdev_priv(dev);
- struct ixgbe_hw *hw = &adapter->hw;
- __be16 port = ti->port;
- u32 port_shift = 0;
- u32 reg;
-
- if (ti->sa_family != AF_INET)
- return;
-
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
- return;
-
- if (adapter->vxlan_port == port)
- return;
-
- if (adapter->vxlan_port) {
- netdev_info(dev,
- "VXLAN port %d set, not adding port %d\n",
- ntohs(adapter->vxlan_port),
- ntohs(port));
- return;
- }
-
- adapter->vxlan_port = port;
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))
- return;
-
- if (adapter->geneve_port == port)
- return;
-
- if (adapter->geneve_port) {
- netdev_info(dev,
- "GENEVE port %d set, not adding port %d\n",
- ntohs(adapter->geneve_port),
- ntohs(port));
- return;
- }
-
- port_shift = IXGBE_VXLANCTRL_GENEVE_UDPPORT_SHIFT;
- adapter->geneve_port = port;
- break;
- default:
- return;
- }
-
- reg = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) | ntohs(port) << port_shift;
- IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, reg);
-}
-
-/**
- * ixgbe_del_udp_tunnel_port - Get notifications about removing UDP tunnel ports
- * @dev: The port's netdev
- * @ti: Tunnel endpoint information
- **/
-static void ixgbe_del_udp_tunnel_port(struct net_device *dev,
- struct udp_tunnel_info *ti)
-{
- struct ixgbe_adapter *adapter = netdev_priv(dev);
- u32 port_mask;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN &&
- ti->type != UDP_TUNNEL_TYPE_GENEVE)
- return;
-
- if (ti->sa_family != AF_INET)
- return;
-
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
- return;
-
- if (adapter->vxlan_port != ti->port) {
- netdev_info(dev, "VXLAN port %d not found\n",
- ntohs(ti->port));
- return;
- }
-
- port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK;
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))
- return;
-
- if (adapter->geneve_port != ti->port) {
- netdev_info(dev, "GENEVE port %d not found\n",
- ntohs(ti->port));
- return;
- }
-
- port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK;
- break;
- default:
- return;
- }
-
- ixgbe_clear_udp_tunnel_port(adapter, port_mask);
- adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
-}
-
static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr, u16 vid,
@@ -10312,10 +10160,6 @@ static int ixgbe_xdp(struct net_device *dev, struct netdev_bpf *xdp)
switch (xdp->command) {
case XDP_SETUP_PROG:
return ixgbe_xdp_setup(dev, xdp->prog);
- case XDP_QUERY_PROG:
- xdp->prog_id = adapter->xdp_prog ?
- adapter->xdp_prog->aux->id : 0;
- return 0;
case XDP_SETUP_XSK_UMEM:
return ixgbe_xsk_umem_setup(adapter, xdp->xsk.umem,
xdp->xsk.queue_id);
@@ -10414,8 +10258,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_bridge_getlink = ixgbe_ndo_bridge_getlink,
.ndo_dfwd_add_station = ixgbe_fwd_add,
.ndo_dfwd_del_station = ixgbe_fwd_del,
- .ndo_udp_tunnel_add = ixgbe_add_udp_tunnel_port,
- .ndo_udp_tunnel_del = ixgbe_del_udp_tunnel_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = ixgbe_features_check,
.ndo_bpf = ixgbe_xdp,
.ndo_xdp_xmit = ixgbe_xdp_xmit,
@@ -10658,7 +10502,7 @@ bool ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
/* only support first port */
if (hw->bus.func != 0)
break;
- /* fall through */
+ fallthrough;
case IXGBE_SUBDEV_ID_82599_SP_560FLR:
case IXGBE_SUBDEV_ID_82599_SFP:
case IXGBE_SUBDEV_ID_82599_RNDC:
@@ -10860,6 +10704,18 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto err_sw_init;
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_X550:
+ case ixgbe_mac_X550EM_x:
+ netdev->udp_tunnel_nic_info = &ixgbe_udp_tunnels_x550;
+ break;
+ case ixgbe_mac_x550em_a:
+ netdev->udp_tunnel_nic_info = &ixgbe_udp_tunnels_x550em_a;
+ break;
+ default:
+ break;
+ }
+
/* Make sure the SWFW semaphore is in a valid state */
if (hw->mac.ops.init_swfw_sync)
hw->mac.ops.init_swfw_sync(hw);
@@ -11154,8 +11010,8 @@ skip_sriov:
*/
if (hw->mac.ops.set_fw_drv_ver)
hw->mac.ops.set_fw_drv_ver(hw, 0xFF, 0xFF, 0xFF, 0xFF,
- sizeof(ixgbe_driver_version) - 1,
- ixgbe_driver_version);
+ sizeof(UTS_RELEASE) - 1,
+ UTS_RELEASE);
/* add san mac addr to netdev */
ixgbe_add_sanmac_netdev(netdev);
@@ -11175,10 +11031,14 @@ skip_sriov:
IXGBE_LINK_SPEED_10GB_FULL | IXGBE_LINK_SPEED_1GB_FULL,
true);
- ixgbe_mii_bus_init(hw);
+ err = ixgbe_mii_bus_init(hw);
+ if (err)
+ goto err_netdev;
return 0;
+err_netdev:
+ unregister_netdev(netdev);
err_register:
ixgbe_release_hw_control(adapter);
ixgbe_clear_interrupt_scheme(adapter);
@@ -11489,16 +11349,15 @@ static const struct pci_error_handlers ixgbe_err_handler = {
.resume = ixgbe_io_resume,
};
+static SIMPLE_DEV_PM_OPS(ixgbe_pm_ops, ixgbe_suspend, ixgbe_resume);
+
static struct pci_driver ixgbe_driver = {
- .name = ixgbe_driver_name,
- .id_table = ixgbe_pci_tbl,
- .probe = ixgbe_probe,
- .remove = ixgbe_remove,
-#ifdef CONFIG_PM
- .suspend = ixgbe_suspend,
- .resume = ixgbe_resume,
-#endif
- .shutdown = ixgbe_shutdown,
+ .name = ixgbe_driver_name,
+ .id_table = ixgbe_pci_tbl,
+ .probe = ixgbe_probe,
+ .remove = ixgbe_remove,
+ .driver.pm = &ixgbe_pm_ops,
+ .shutdown = ixgbe_shutdown,
.sriov_configure = ixgbe_pci_sriov_configure,
.err_handler = &ixgbe_err_handler
};
@@ -11512,7 +11371,7 @@ static struct pci_driver ixgbe_driver = {
static int __init ixgbe_init_module(void)
{
int ret;
- pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version);
+ pr_info("%s\n", ixgbe_driver_string);
pr_info("%s\n", ixgbe_copyright);
ixgbe_wq = create_singlethread_workqueue(ixgbe_driver_name);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index 2fb97967961c..7980d7265e10 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -905,7 +905,6 @@ s32 ixgbe_mii_bus_init(struct ixgbe_hw *hw)
struct pci_dev *pdev = adapter->pdev;
struct device *dev = &adapter->netdev->dev;
struct mii_bus *bus;
- int err = -ENODEV;
bus = devm_mdiobus_alloc(dev);
if (!bus)
@@ -923,7 +922,7 @@ s32 ixgbe_mii_bus_init(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_X550EM_A_1G_T:
case IXGBE_DEV_ID_X550EM_A_1G_T_L:
if (!ixgbe_x550em_a_has_mii(hw))
- goto ixgbe_no_mii_bus;
+ return -ENODEV;
bus->read = &ixgbe_x550em_a_mii_bus_read;
bus->write = &ixgbe_x550em_a_mii_bus_write;
break;
@@ -948,15 +947,8 @@ s32 ixgbe_mii_bus_init(struct ixgbe_hw *hw)
*/
hw->phy.mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22;
- err = mdiobus_register(bus);
- if (!err) {
- adapter->mii_bus = bus;
- return 0;
- }
-
-ixgbe_no_mii_bus:
- devm_mdiobus_free(dev, bus);
- return err;
+ adapter->mii_bus = bus;
+ return mdiobus_register(bus);
}
/**
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 0be13a90ff79..22a874eee2e8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -1051,7 +1051,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
break;
}
- /* fall through */
+ fallthrough;
default:
/*
* register RXMTRL must be set in order to do V1 packets,
@@ -1242,7 +1242,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
cc.mult = 3;
cc.shift = 2;
}
- /* fallthrough */
+ fallthrough;
case ixgbe_mac_x550em_a:
case ixgbe_mac_X550:
cc.read = ixgbe_ptp_read_X550;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index d05a5690e66b..988db46bff0e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -503,7 +503,7 @@ static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
*/
if (pf_max_frame > ETH_FRAME_LEN)
break;
- /* fall through */
+ fallthrough;
default:
/* If the PF or VF are running w/ jumbo frames enabled
* we need to shut down the VF Rx path as we cannot
@@ -783,7 +783,7 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr,
ETH_ALEN);
else
- memset(adapter->vfinfo[vf].vf_mac_addresses, 0, ETH_ALEN);
+ eth_zero_addr(adapter->vfinfo[vf].vf_mac_addresses);
return retval;
}
@@ -1141,7 +1141,7 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,
/* promisc introduced in 1.3 version */
if (xcast_mode == IXGBEVF_XCAST_MODE_PROMISC)
return -EOPNOTSUPP;
- /* Fall through */
+ fallthrough;
case ixgbe_mbox_api_13:
case ixgbe_mbox_api_14:
break;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
index 9c42f741ed5e..5e339afa682a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
@@ -306,7 +306,7 @@ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
ixgbe_setup_mux_ctl(hw);
ixgbe_check_cs4227(hw);
- /* Fallthrough */
+ fallthrough;
case IXGBE_DEV_ID_X550EM_A_SFP_N:
return ixgbe_identify_module_generic(hw);
case IXGBE_DEV_ID_X550EM_X_KX4:
@@ -325,7 +325,7 @@ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
else
hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
- /* Fallthrough */
+ fallthrough;
case IXGBE_DEV_ID_X550EM_X_10G_T:
return ixgbe_identify_phy_generic(hw);
case IXGBE_DEV_ID_X550EM_X_1G_T:
@@ -2303,7 +2303,7 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
break;
}
}
- /* fall through */
+ fallthrough;
default:
*speed = IXGBE_LINK_SPEED_10GB_FULL |
IXGBE_LINK_SPEED_1GB_FULL;
@@ -2885,7 +2885,7 @@ static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *hw)
* through to the fc_full statement. Later, we will
* disable the adapter's ability to send PAUSE frames.
*/
- /* Fallthrough */
+ fallthrough;
case ixgbe_fc_full:
pause = true;
asm_dir = true;
@@ -3284,7 +3284,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_X550EM_A_SGMII:
case IXGBE_DEV_ID_X550EM_A_SGMII_L:
hw->phy.type = ixgbe_phy_sgmii;
- /* Fallthrough */
+ fallthrough;
case IXGBE_DEV_ID_X550EM_X_KR:
case IXGBE_DEV_ID_X550EM_X_KX4:
case IXGBE_DEV_ID_X550EM_X_XFI:
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
index be9d2a8da515..ec7121f352e2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
@@ -120,10 +120,10 @@ static int ixgbe_run_xdp_zc(struct ixgbe_adapter *adapter,
break;
default:
bpf_warn_invalid_xdp_action(act);
- /* fallthrough */
+ fallthrough;
case XDP_ABORTED:
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
- /* fallthrough -- handle aborts by dropping packet */
+ fallthrough; /* handle aborts by dropping packet */
case XDP_DROP:
result = IXGBE_XDP_CONSUMED;
break;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index 988fa49fa99a..e49fb1cd9a99 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -218,8 +218,6 @@ static void ixgbevf_get_drvinfo(struct net_device *netdev,
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, ixgbevf_driver_name, sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, ixgbevf_driver_version,
- sizeof(drvinfo->version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index ecab686574b6..a0e325774819 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -440,7 +440,6 @@ extern const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops;
/* needed by ethtool.c */
extern const char ixgbevf_driver_name[];
-extern const char ixgbevf_driver_version[];
int ixgbevf_open(struct net_device *netdev);
int ixgbevf_close(struct net_device *netdev);
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index a39e2cb384dd..a428113e6d54 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -38,8 +38,6 @@ const char ixgbevf_driver_name[] = "ixgbevf";
static const char ixgbevf_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver";
-#define DRV_VERSION "4.1.0-k"
-const char ixgbevf_driver_version[] = DRV_VERSION;
static char ixgbevf_copyright[] =
"Copyright (c) 2009 - 2018 Intel Corporation.";
@@ -81,7 +79,6 @@ MODULE_DEVICE_TABLE(pci, ixgbevf_pci_tbl);
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION("Intel(R) 10 Gigabit Virtual Function Network Driver");
MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
static int debug = -1;
@@ -1082,10 +1079,10 @@ static struct sk_buff *ixgbevf_run_xdp(struct ixgbevf_adapter *adapter,
break;
default:
bpf_warn_invalid_xdp_action(act);
- /* fallthrough */
+ fallthrough;
case XDP_ABORTED:
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
- /* fallthrough -- handle aborts by dropping packet */
+ fallthrough; /* handle aborts by dropping packet */
case XDP_DROP:
result = IXGBEVF_XDP_CONSUMED;
break;
@@ -2605,7 +2602,7 @@ static int ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter,
* important, starting with the "most" number of features turned on at once,
* and ending with the smallest set of features. This way large combinations
* can be allocated if they're turned on, and smaller combinations are the
- * fallthrough conditions.
+ * fall through conditions.
*
**/
static void ixgbevf_set_num_queues(struct ixgbevf_adapter *adapter)
@@ -3877,7 +3874,7 @@ static void ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring,
switch (skb->csum_offset) {
case offsetof(struct tcphdr, check):
type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;
- /* fall through */
+ fallthrough;
case offsetof(struct udphdr, check):
break;
case offsetof(struct sctphdr, checksum):
@@ -3889,7 +3886,7 @@ static void ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring,
type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_SCTP;
break;
}
- /* fall through */
+ fallthrough;
default:
skb_checksum_help(skb);
goto no_csum;
@@ -4300,13 +4297,10 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
return 0;
}
-static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused ixgbevf_suspend(struct device *dev_d)
{
- struct net_device *netdev = pci_get_drvdata(pdev);
+ struct net_device *netdev = dev_get_drvdata(dev_d);
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_PM
- int retval = 0;
-#endif
rtnl_lock();
netif_device_detach(netdev);
@@ -4317,37 +4311,16 @@ static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state)
ixgbevf_clear_interrupt_scheme(adapter);
rtnl_unlock();
-#ifdef CONFIG_PM
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-
-#endif
- if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state))
- pci_disable_device(pdev);
-
return 0;
}
-#ifdef CONFIG_PM
-static int ixgbevf_resume(struct pci_dev *pdev)
+static int __maybe_unused ixgbevf_resume(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
u32 err;
- pci_restore_state(pdev);
- /* pci_restore_state clears dev->state_saved so call
- * pci_save_state to restore it.
- */
- pci_save_state(pdev);
-
- err = pci_enable_device_mem(pdev);
- if (err) {
- dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n");
- return err;
- }
-
adapter->hw.hw_addr = adapter->io_addr;
smp_mb__before_atomic();
clear_bit(__IXGBEVF_DISABLED, &adapter->state);
@@ -4368,10 +4341,9 @@ static int ixgbevf_resume(struct pci_dev *pdev)
return err;
}
-#endif /* CONFIG_PM */
static void ixgbevf_shutdown(struct pci_dev *pdev)
{
- ixgbevf_suspend(pdev, PMSG_SUSPEND);
+ ixgbevf_suspend(&pdev->dev);
}
static void ixgbevf_get_tx_ring_stats(struct rtnl_link_stats64 *stats,
@@ -4505,15 +4477,9 @@ static int ixgbevf_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
static int ixgbevf_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
- struct ixgbevf_adapter *adapter = netdev_priv(dev);
-
switch (xdp->command) {
case XDP_SETUP_PROG:
return ixgbevf_xdp_setup(dev, xdp->prog);
- case XDP_QUERY_PROG:
- xdp->prog_id = adapter->xdp_prog ?
- adapter->xdp_prog->aux->id : 0;
- return 0;
default:
return -EINVAL;
}
@@ -4891,16 +4857,17 @@ static const struct pci_error_handlers ixgbevf_err_handler = {
.resume = ixgbevf_io_resume,
};
+static SIMPLE_DEV_PM_OPS(ixgbevf_pm_ops, ixgbevf_suspend, ixgbevf_resume);
+
static struct pci_driver ixgbevf_driver = {
.name = ixgbevf_driver_name,
.id_table = ixgbevf_pci_tbl,
.probe = ixgbevf_probe,
.remove = ixgbevf_remove,
-#ifdef CONFIG_PM
+
/* Power Management Hooks */
- .suspend = ixgbevf_suspend,
- .resume = ixgbevf_resume,
-#endif
+ .driver.pm = &ixgbevf_pm_ops,
+
.shutdown = ixgbevf_shutdown,
.err_handler = &ixgbevf_err_handler
};
@@ -4913,9 +4880,7 @@ static struct pci_driver ixgbevf_driver = {
**/
static int __init ixgbevf_init_module(void)
{
- pr_info("%s - version %s\n", ixgbevf_driver_string,
- ixgbevf_driver_version);
-
+ pr_info("%s\n", ixgbevf_driver_string);
pr_info("%s\n", ixgbevf_copyright);
ixgbevf_wq = create_singlethread_workqueue(ixgbevf_driver_name);
if (!ixgbevf_wq) {
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c
index d5ce49636548..bfe6dfcec4ab 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.c
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
@@ -314,7 +314,7 @@ int ixgbevf_get_reta_locked(struct ixgbe_hw *hw, u32 *reta, int num_rx_queues)
case ixgbe_mbox_api_12:
if (hw->mac.type < ixgbe_mac_X550_vf)
break;
- /* fall through */
+ fallthrough;
default:
return -EOPNOTSUPP;
}
@@ -382,7 +382,7 @@ int ixgbevf_get_rss_key_locked(struct ixgbe_hw *hw, u8 *rss_key)
case ixgbe_mbox_api_12:
if (hw->mac.type < ixgbe_mac_X550_vf)
break;
- /* fall through */
+ fallthrough;
default:
return -EOPNOTSUPP;
}
@@ -540,7 +540,7 @@ static s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
/* promisc introduced in 1.3 version */
if (xcast_mode == IXGBEVF_XCAST_MODE_PROMISC)
return -EOPNOTSUPP;
- /* Fall threw */
+ fallthrough;
case ixgbe_mbox_api_14:
case ixgbe_mbox_api_13:
break;
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index c97c74164c73..ddc757680089 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -3,7 +3,7 @@
* JMicron JMC2x0 series PCIe Ethernet Linux Device Driver
*
* Copyright 2008 JMicron Technology Corporation
- * http://www.jmicron.com/
+ * https://www.jmicron.com/
* Copyright (c) 2009 - 2010 Guo-Fu Tseng <cooldavid@cooldavid.org>
*
* Author: Guo-Fu Tseng <cooldavid@cooldavid.org>
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h
index 2bba5ce20289..a2c3b00d939d 100644
--- a/drivers/net/ethernet/jme.h
+++ b/drivers/net/ethernet/jme.h
@@ -3,7 +3,7 @@
* JMicron JMC2x0 series PCIe Ethernet Linux Device Driver
*
* Copyright 2008 JMicron Technology Corporation
- * http://www.jmicron.com/
+ * https://www.jmicron.com/
* Copyright (c) 2009 - 2010 Guo-Fu Tseng <cooldavid@cooldavid.org>
*
* Author: Guo-Fu Tseng <cooldavid@cooldavid.org>
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index cd8ddd1ef6f2..ef4f35ba077d 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -87,6 +87,7 @@ config MVPP2
depends on ARCH_MVEBU || COMPILE_TEST
select MVMDIO
select PHYLINK
+ select PAGE_POOL
help
This driver supports the network interface units in the
Marvell ARMADA 375, 7K and 8K SoCs.
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 4d4b6243318a..90e6111ce534 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -816,10 +816,9 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb,
struct net_device *dev)
{
struct mv643xx_eth_private *mp = txq_to_mp(txq);
- int total_len, data_left, ret;
+ int hdr_len, total_len, data_left, ret;
int desc_count = 0;
struct tso_t tso;
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
struct tx_desc *first_tx_desc;
u32 first_cmd_sts = 0;
@@ -832,7 +831,7 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb,
first_tx_desc = &txq->tx_desc_area[txq->tx_curr_desc];
/* Initialize the TSO handler, and prepare the first payload */
- tso_start(skb, &tso);
+ hdr_len = tso_start(skb, &tso);
total_len = skb->len - hdr_len;
while (total_len > 0) {
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 7d5d9d34f4e4..832bbb8b05c8 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -698,10 +698,6 @@ struct mvneta_rx_queue {
/* Index of first RX DMA descriptor to refill */
int first_to_refill;
u32 refill_num;
-
- /* pointer to uncomplete skb buffer */
- struct sk_buff *skb;
- int left_size;
};
static enum cpuhp_state online_hpstate;
@@ -2026,6 +2022,20 @@ int mvneta_rx_refill_queue(struct mvneta_port *pp, struct mvneta_rx_queue *rxq)
return i;
}
+static void
+mvneta_xdp_put_buff(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
+ struct xdp_buff *xdp, int sync_len, bool napi)
+{
+ struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
+ int i;
+
+ page_pool_put_page(rxq->page_pool, virt_to_head_page(xdp->data),
+ sync_len, napi);
+ for (i = 0; i < sinfo->nr_frags; i++)
+ page_pool_put_full_page(rxq->page_pool,
+ skb_frag_page(&sinfo->frags[i]), napi);
+}
+
static int
mvneta_xdp_submit_frame(struct mvneta_port *pp, struct mvneta_tx_queue *txq,
struct xdp_frame *xdpf, bool dma_map)
@@ -2158,13 +2168,13 @@ mvneta_xdp_xmit(struct net_device *dev, int num_frame,
static int
mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
struct bpf_prog *prog, struct xdp_buff *xdp,
- struct mvneta_stats *stats)
+ u32 frame_sz, struct mvneta_stats *stats)
{
- unsigned int len, sync;
- struct page *page;
+ unsigned int len, data_len, sync;
u32 ret, act;
len = xdp->data_end - xdp->data_hard_start - pp->rx_offset_correction;
+ data_len = xdp->data_end - xdp->data;
act = bpf_prog_run_xdp(prog, xdp);
/* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */
@@ -2180,9 +2190,8 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
err = xdp_do_redirect(pp->dev, xdp, prog);
if (unlikely(err)) {
+ mvneta_xdp_put_buff(pp, rxq, xdp, sync, true);
ret = MVNETA_XDP_DROPPED;
- page = virt_to_head_page(xdp->data);
- page_pool_put_page(rxq->page_pool, page, sync, true);
} else {
ret = MVNETA_XDP_REDIR;
stats->xdp_redirect++;
@@ -2191,10 +2200,8 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
}
case XDP_TX:
ret = mvneta_xdp_xmit_back(pp, xdp);
- if (ret != MVNETA_XDP_TX) {
- page = virt_to_head_page(xdp->data);
- page_pool_put_page(rxq->page_pool, page, sync, true);
- }
+ if (ret != MVNETA_XDP_TX)
+ mvneta_xdp_put_buff(pp, rxq, xdp, sync, true);
break;
default:
bpf_warn_invalid_xdp_action(act);
@@ -2203,25 +2210,23 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
trace_xdp_exception(pp->dev, prog, act);
/* fall through */
case XDP_DROP:
- page = virt_to_head_page(xdp->data);
- page_pool_put_page(rxq->page_pool, page, sync, true);
+ mvneta_xdp_put_buff(pp, rxq, xdp, sync, true);
ret = MVNETA_XDP_DROPPED;
stats->xdp_drop++;
break;
}
- stats->rx_bytes += xdp->data_end - xdp->data;
+ stats->rx_bytes += frame_sz + xdp->data_end - xdp->data - data_len;
stats->rx_packets++;
return ret;
}
-static int
+static void
mvneta_swbm_rx_frame(struct mvneta_port *pp,
struct mvneta_rx_desc *rx_desc,
struct mvneta_rx_queue *rxq,
- struct xdp_buff *xdp,
- struct bpf_prog *xdp_prog,
+ struct xdp_buff *xdp, int *size,
struct page *page,
struct mvneta_stats *stats)
{
@@ -2229,7 +2234,7 @@ mvneta_swbm_rx_frame(struct mvneta_port *pp,
int data_len = -MVNETA_MH_SIZE, len;
struct net_device *dev = pp->dev;
enum dma_data_direction dma_dir;
- int ret = 0;
+ struct skb_shared_info *sinfo;
if (MVNETA_SKB_SIZE(rx_desc->data_size) > PAGE_SIZE) {
len = MVNETA_MAX_RX_BUF_SIZE;
@@ -2252,71 +2257,81 @@ mvneta_swbm_rx_frame(struct mvneta_port *pp,
xdp->data_end = xdp->data + data_len;
xdp_set_data_meta_invalid(xdp);
- if (xdp_prog) {
- ret = mvneta_run_xdp(pp, rxq, xdp_prog, xdp, stats);
- if (ret)
- goto out;
- }
-
- rxq->skb = build_skb(xdp->data_hard_start, PAGE_SIZE);
- if (unlikely(!rxq->skb)) {
- struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats);
+ sinfo = xdp_get_shared_info_from_buff(xdp);
+ sinfo->nr_frags = 0;
- netdev_err(dev, "Can't allocate skb on queue %d\n", rxq->id);
-
- u64_stats_update_begin(&stats->syncp);
- stats->es.skb_alloc_error++;
- stats->rx_dropped++;
- u64_stats_update_end(&stats->syncp);
-
- return -ENOMEM;
- }
- page_pool_release_page(rxq->page_pool, page);
-
- skb_reserve(rxq->skb,
- xdp->data - xdp->data_hard_start);
- skb_put(rxq->skb, xdp->data_end - xdp->data);
- mvneta_rx_csum(pp, rx_desc->status, rxq->skb);
-
- rxq->left_size = rx_desc->data_size - len;
-
-out:
+ *size = rx_desc->data_size - len;
rx_desc->buf_phys_addr = 0;
-
- return ret;
}
static void
mvneta_swbm_add_rx_fragment(struct mvneta_port *pp,
struct mvneta_rx_desc *rx_desc,
struct mvneta_rx_queue *rxq,
+ struct xdp_buff *xdp, int *size,
struct page *page)
{
+ struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
struct net_device *dev = pp->dev;
enum dma_data_direction dma_dir;
int data_len, len;
- if (rxq->left_size > MVNETA_MAX_RX_BUF_SIZE) {
+ if (*size > MVNETA_MAX_RX_BUF_SIZE) {
len = MVNETA_MAX_RX_BUF_SIZE;
data_len = len;
} else {
- len = rxq->left_size;
+ len = *size;
data_len = len - ETH_FCS_LEN;
}
dma_dir = page_pool_get_dma_dir(rxq->page_pool);
dma_sync_single_for_cpu(dev->dev.parent,
rx_desc->buf_phys_addr,
len, dma_dir);
- if (data_len > 0) {
- /* refill descriptor with new buffer later */
- skb_add_rx_frag(rxq->skb,
- skb_shinfo(rxq->skb)->nr_frags,
- page, pp->rx_offset_correction, data_len,
- PAGE_SIZE);
- }
- page_pool_release_page(rxq->page_pool, page);
- rx_desc->buf_phys_addr = 0;
- rxq->left_size -= len;
+
+ if (data_len > 0 && sinfo->nr_frags < MAX_SKB_FRAGS) {
+ skb_frag_t *frag = &sinfo->frags[sinfo->nr_frags];
+
+ skb_frag_off_set(frag, pp->rx_offset_correction);
+ skb_frag_size_set(frag, data_len);
+ __skb_frag_set_page(frag, page);
+ sinfo->nr_frags++;
+
+ rx_desc->buf_phys_addr = 0;
+ }
+ *size -= len;
+}
+
+static struct sk_buff *
+mvneta_swbm_build_skb(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
+ struct xdp_buff *xdp, u32 desc_status)
+{
+ struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
+ int i, num_frags = sinfo->nr_frags;
+ skb_frag_t frags[MAX_SKB_FRAGS];
+ struct sk_buff *skb;
+
+ memcpy(frags, sinfo->frags, sizeof(skb_frag_t) * num_frags);
+
+ skb = build_skb(xdp->data_hard_start, PAGE_SIZE);
+ if (!skb)
+ return ERR_PTR(-ENOMEM);
+
+ page_pool_release_page(rxq->page_pool, virt_to_page(xdp->data));
+
+ skb_reserve(skb, xdp->data - xdp->data_hard_start);
+ skb_put(skb, xdp->data_end - xdp->data);
+ mvneta_rx_csum(pp, desc_status, skb);
+
+ for (i = 0; i < num_frags; i++) {
+ struct page *page = skb_frag_page(&frags[i]);
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+ page, skb_frag_off(&frags[i]),
+ skb_frag_size(&frags[i]), PAGE_SIZE);
+ page_pool_release_page(rxq->page_pool, page);
+ }
+
+ return skb;
}
/* Main rx processing when using software buffer management */
@@ -2324,24 +2339,27 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
struct mvneta_port *pp, int budget,
struct mvneta_rx_queue *rxq)
{
- int rx_proc = 0, rx_todo, refill;
+ int rx_proc = 0, rx_todo, refill, size = 0;
struct net_device *dev = pp->dev;
+ struct xdp_buff xdp_buf = {
+ .frame_sz = PAGE_SIZE,
+ .rxq = &rxq->xdp_rxq,
+ };
struct mvneta_stats ps = {};
struct bpf_prog *xdp_prog;
- struct xdp_buff xdp_buf;
+ u32 desc_status, frame_sz;
/* Get number of received packets */
rx_todo = mvneta_rxq_busy_desc_num_get(pp, rxq);
rcu_read_lock();
xdp_prog = READ_ONCE(pp->xdp_prog);
- xdp_buf.rxq = &rxq->xdp_rxq;
- xdp_buf.frame_sz = PAGE_SIZE;
/* Fairness NAPI loop */
while (rx_proc < budget && rx_proc < rx_todo) {
struct mvneta_rx_desc *rx_desc = mvneta_rxq_next_desc_get(rxq);
u32 rx_status, index;
+ struct sk_buff *skb;
struct page *page;
index = rx_desc - rxq->descs;
@@ -2352,54 +2370,66 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
rxq->refill_num++;
if (rx_status & MVNETA_RXD_FIRST_DESC) {
- int err;
-
/* Check errors only for FIRST descriptor */
if (rx_status & MVNETA_RXD_ERR_SUMMARY) {
mvneta_rx_error(pp, rx_desc);
- /* leave the descriptor untouched */
- continue;
+ goto next;
}
- err = mvneta_swbm_rx_frame(pp, rx_desc, rxq, &xdp_buf,
- xdp_prog, page, &ps);
- if (err)
- continue;
+ size = rx_desc->data_size;
+ frame_sz = size - ETH_FCS_LEN;
+ desc_status = rx_desc->status;
+
+ mvneta_swbm_rx_frame(pp, rx_desc, rxq, &xdp_buf,
+ &size, page, &ps);
} else {
- if (unlikely(!rxq->skb)) {
- pr_debug("no skb for rx_status 0x%x\n",
- rx_status);
+ if (unlikely(!xdp_buf.data_hard_start))
continue;
- }
- mvneta_swbm_add_rx_fragment(pp, rx_desc, rxq, page);
+
+ mvneta_swbm_add_rx_fragment(pp, rx_desc, rxq, &xdp_buf,
+ &size, page);
} /* Middle or Last descriptor */
if (!(rx_status & MVNETA_RXD_LAST_DESC))
/* no last descriptor this time */
continue;
- if (rxq->left_size) {
- pr_err("get last desc, but left_size (%d) != 0\n",
- rxq->left_size);
- dev_kfree_skb_any(rxq->skb);
- rxq->left_size = 0;
- rxq->skb = NULL;
- continue;
+ if (size) {
+ mvneta_xdp_put_buff(pp, rxq, &xdp_buf, -1, true);
+ goto next;
}
- ps.rx_bytes += rxq->skb->len;
- ps.rx_packets++;
+ if (xdp_prog &&
+ mvneta_run_xdp(pp, rxq, xdp_prog, &xdp_buf, frame_sz, &ps))
+ goto next;
- /* Linux processing */
- rxq->skb->protocol = eth_type_trans(rxq->skb, dev);
+ skb = mvneta_swbm_build_skb(pp, rxq, &xdp_buf, desc_status);
+ if (IS_ERR(skb)) {
+ struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats);
- napi_gro_receive(napi, rxq->skb);
+ mvneta_xdp_put_buff(pp, rxq, &xdp_buf, -1, true);
- /* clean uncomplete skb pointer in queue */
- rxq->skb = NULL;
+ u64_stats_update_begin(&stats->syncp);
+ stats->es.skb_alloc_error++;
+ stats->rx_dropped++;
+ u64_stats_update_end(&stats->syncp);
+
+ goto next;
+ }
+
+ ps.rx_bytes += skb->len;
+ ps.rx_packets++;
+
+ skb->protocol = eth_type_trans(skb, dev);
+ napi_gro_receive(napi, skb);
+next:
+ xdp_buf.data_hard_start = NULL;
}
rcu_read_unlock();
+ if (xdp_buf.data_hard_start)
+ mvneta_xdp_put_buff(pp, rxq, &xdp_buf, -1, true);
+
if (ps.xdp_redirect)
xdp_do_flush_map();
@@ -2606,11 +2636,10 @@ mvneta_tso_put_data(struct net_device *dev, struct mvneta_tx_queue *txq,
static int mvneta_tx_tso(struct sk_buff *skb, struct net_device *dev,
struct mvneta_tx_queue *txq)
{
- int total_len, data_left;
+ int hdr_len, total_len, data_left;
int desc_count = 0;
struct mvneta_port *pp = netdev_priv(dev);
struct tso_t tso;
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
int i;
/* Count needed descriptors */
@@ -2623,7 +2652,7 @@ static int mvneta_tx_tso(struct sk_buff *skb, struct net_device *dev,
}
/* Initialize the TSO handler, and prepare the first payload */
- tso_start(skb, &tso);
+ hdr_len = tso_start(skb, &tso);
total_len = skb->len - hdr_len;
while (total_len > 0) {
@@ -3329,9 +3358,6 @@ static void mvneta_rxq_deinit(struct mvneta_port *pp,
{
mvneta_rxq_drop_pkts(pp, rxq);
- if (rxq->skb)
- dev_kfree_skb_any(rxq->skb);
-
if (rxq->descs)
dma_free_coherent(pp->dev->dev.parent,
rxq->size * MVNETA_DESC_ALIGNED_SIZE,
@@ -3344,8 +3370,6 @@ static void mvneta_rxq_deinit(struct mvneta_port *pp,
rxq->descs_phys = 0;
rxq->first_to_refill = 0;
rxq->refill_num = 0;
- rxq->skb = NULL;
- rxq->left_size = 0;
}
static int mvneta_txq_sw_init(struct mvneta_port *pp,
@@ -3612,6 +3636,10 @@ static void mvneta_start_dev(struct mvneta_port *pp)
MVNETA_CAUSE_LINK_CHANGE);
phylink_start(pp->phylink);
+
+ /* We may have called phylink_speed_down before */
+ phylink_speed_up(pp->phylink);
+
netif_tx_start_all_queues(pp->dev);
clear_bit(__MVNETA_DOWN, &pp->state);
@@ -3623,6 +3651,9 @@ static void mvneta_stop_dev(struct mvneta_port *pp)
set_bit(__MVNETA_DOWN, &pp->state);
+ if (device_may_wakeup(&pp->dev->dev))
+ phylink_speed_down(pp->phylink, false);
+
phylink_stop(pp->phylink);
if (!pp->neta_armada3700) {
@@ -4091,6 +4122,10 @@ static int mvneta_mdio_probe(struct mvneta_port *pp)
phylink_ethtool_get_wol(pp->phylink, &wol);
device_set_wakeup_capable(&pp->dev->dev, !!wol.supported);
+ /* PHY WoL may be enabled but device wakeup disabled */
+ if (wol.supported)
+ device_set_wakeup_enable(&pp->dev->dev, !!wol.wolopts);
+
return err;
}
@@ -4407,14 +4442,9 @@ static int mvneta_xdp_setup(struct net_device *dev, struct bpf_prog *prog,
static int mvneta_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
- struct mvneta_port *pp = netdev_priv(dev);
-
switch (xdp->command) {
case XDP_SETUP_PROG:
return mvneta_xdp_setup(dev, xdp->prog, xdp->extack);
- case XDP_QUERY_PROG:
- xdp->prog_id = pp->xdp_prog ? pp->xdp_prog->aux->id : 0;
- return 0;
default:
return -EINVAL;
}
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
index 543a310ec102..32753cc771bf 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
@@ -15,6 +15,19 @@
#include <linux/phy.h>
#include <linux/phylink.h>
#include <net/flow_offload.h>
+#include <net/page_pool.h>
+#include <linux/bpf.h>
+#include <net/xdp.h>
+
+/* The PacketOffset field is measured in units of 32 bytes and is 3 bits wide,
+ * so the maximum offset is 7 * 32 = 224
+ */
+#define MVPP2_SKB_HEADROOM min(max(XDP_PACKET_HEADROOM, NET_SKB_PAD), 224)
+
+#define MVPP2_XDP_PASS 0
+#define MVPP2_XDP_DROPPED BIT(0)
+#define MVPP2_XDP_TX BIT(1)
+#define MVPP2_XDP_REDIR BIT(2)
/* Fifo Registers */
#define MVPP2_RX_DATA_FIFO_SIZE_REG(port) (0x00 + 4 * (port))
@@ -628,10 +641,12 @@
ALIGN((mtu) + MVPP2_MH_SIZE + MVPP2_VLAN_TAG_LEN + \
ETH_HLEN + ETH_FCS_LEN, cache_line_size())
-#define MVPP2_RX_BUF_SIZE(pkt_size) ((pkt_size) + NET_SKB_PAD)
+#define MVPP2_RX_BUF_SIZE(pkt_size) ((pkt_size) + MVPP2_SKB_HEADROOM)
#define MVPP2_RX_TOTAL_SIZE(buf_size) ((buf_size) + MVPP2_SKB_SHINFO_SIZE)
#define MVPP2_RX_MAX_PKT_SIZE(total_size) \
- ((total_size) - NET_SKB_PAD - MVPP2_SKB_SHINFO_SIZE)
+ ((total_size) - MVPP2_SKB_HEADROOM - MVPP2_SKB_SHINFO_SIZE)
+
+#define MVPP2_MAX_RX_BUF_SIZE (PAGE_SIZE - MVPP2_SKB_SHINFO_SIZE - MVPP2_SKB_HEADROOM)
#define MVPP2_BIT_TO_BYTE(bit) ((bit) / 8)
#define MVPP2_BIT_TO_WORD(bit) ((bit) / 32)
@@ -689,9 +704,9 @@ enum mvpp2_prs_l3_cast {
#define MVPP2_BM_COOKIE_POOL_OFFS 8
#define MVPP2_BM_COOKIE_CPU_OFFS 24
-#define MVPP2_BM_SHORT_FRAME_SIZE 512
-#define MVPP2_BM_LONG_FRAME_SIZE 2048
-#define MVPP2_BM_JUMBO_FRAME_SIZE 10240
+#define MVPP2_BM_SHORT_FRAME_SIZE 704 /* frame size 128 */
+#define MVPP2_BM_LONG_FRAME_SIZE 2240 /* frame size 1664 */
+#define MVPP2_BM_JUMBO_FRAME_SIZE 10432 /* frame size 9856 */
/* BM short pool packet size
* These value assure that for SWF the total number
* of bytes allocated for each buffer will be 512
@@ -820,6 +835,9 @@ struct mvpp2 {
/* RSS Indirection tables */
struct mvpp2_rss_table *rss_tables[MVPP22_N_RSS_TABLES];
+
+ /* page_pool allocator */
+ struct page_pool *page_pool[MVPP2_PORT_MAX_RXQ];
};
struct mvpp2_pcpu_stats {
@@ -828,6 +846,14 @@ struct mvpp2_pcpu_stats {
u64 rx_bytes;
u64 tx_packets;
u64 tx_bytes;
+ /* XDP */
+ u64 xdp_redirect;
+ u64 xdp_pass;
+ u64 xdp_drop;
+ u64 xdp_xmit;
+ u64 xdp_xmit_err;
+ u64 xdp_tx;
+ u64 xdp_tx_err;
};
/* Per-CPU port control */
@@ -909,6 +935,8 @@ struct mvpp2_port {
unsigned int ntxqs;
struct net_device *dev;
+ struct bpf_prog *xdp_prog;
+
int pkt_size;
/* Per-CPU port control */
@@ -928,6 +956,8 @@ struct mvpp2_port {
struct mvpp2_pcpu_stats __percpu *stats;
u64 *ethtool_stats;
+ unsigned long state;
+
/* Per-port work and its lock to gather hardware statistics */
struct mutex gather_stats_lock;
struct delayed_work stats_work;
@@ -1060,9 +1090,20 @@ struct mvpp2_rx_desc {
};
};
+enum mvpp2_tx_buf_type {
+ MVPP2_TYPE_SKB,
+ MVPP2_TYPE_XDP_TX,
+ MVPP2_TYPE_XDP_NDO,
+};
+
struct mvpp2_txq_pcpu_buf {
+ enum mvpp2_tx_buf_type type;
+
/* Transmitted SKB */
- struct sk_buff *skb;
+ union {
+ struct xdp_frame *xdpf;
+ struct sk_buff *skb;
+ };
/* Physical address of transmitted buffer */
dma_addr_t dma;
@@ -1161,6 +1202,10 @@ struct mvpp2_rx_queue {
/* Port's logic RXQ number to which physical RXQ is mapped */
int logic_rxq;
+
+ /* XDP memory accounting */
+ struct xdp_rxq_info xdp_rxq_short;
+ struct xdp_rxq_info xdp_rxq_long;
};
struct mvpp2_bm_pool {
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 24f4d8e0da98..2a8a5842eaef 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -36,6 +36,7 @@
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/tso.h>
+#include <linux/bpf_trace.h>
#include "mvpp2.h"
#include "mvpp2_prs.h"
@@ -95,6 +96,24 @@ static inline u32 mvpp2_cpu_to_thread(struct mvpp2 *priv, int cpu)
return cpu % priv->nthreads;
}
+static struct page_pool *
+mvpp2_create_page_pool(struct device *dev, int num, int len,
+ enum dma_data_direction dma_dir)
+{
+ struct page_pool_params pp_params = {
+ /* internal DMA mapping in page_pool */
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
+ .pool_size = num,
+ .nid = NUMA_NO_NODE,
+ .dev = dev,
+ .dma_dir = dma_dir,
+ .offset = MVPP2_SKB_HEADROOM,
+ .max_len = len,
+ };
+
+ return page_pool_create(&pp_params);
+}
+
/* These accessors should be used to access:
*
* - per-thread registers, where each thread has its own copy of the
@@ -281,12 +300,17 @@ static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu *txq_pcpu)
static void mvpp2_txq_inc_put(struct mvpp2_port *port,
struct mvpp2_txq_pcpu *txq_pcpu,
- struct sk_buff *skb,
- struct mvpp2_tx_desc *tx_desc)
+ void *data,
+ struct mvpp2_tx_desc *tx_desc,
+ enum mvpp2_tx_buf_type buf_type)
{
struct mvpp2_txq_pcpu_buf *tx_buf =
txq_pcpu->buffs + txq_pcpu->txq_put_index;
- tx_buf->skb = skb;
+ tx_buf->type = buf_type;
+ if (buf_type == MVPP2_TYPE_SKB)
+ tx_buf->skb = data;
+ else
+ tx_buf->xdpf = data;
tx_buf->size = mvpp2_txdesc_size_get(port, tx_desc);
tx_buf->dma = mvpp2_txdesc_dma_addr_get(port, tx_desc) +
mvpp2_txdesc_offset_get(port, tx_desc);
@@ -327,17 +351,25 @@ static inline int mvpp2_txq_phys(int port, int txq)
return (MVPP2_MAX_TCONT + port) * MVPP2_MAX_TXQ + txq;
}
-static void *mvpp2_frag_alloc(const struct mvpp2_bm_pool *pool)
+/* Returns a struct page if page_pool is set, otherwise a buffer */
+static void *mvpp2_frag_alloc(const struct mvpp2_bm_pool *pool,
+ struct page_pool *page_pool)
{
+ if (page_pool)
+ return page_pool_dev_alloc_pages(page_pool);
+
if (likely(pool->frag_size <= PAGE_SIZE))
return netdev_alloc_frag(pool->frag_size);
- else
- return kmalloc(pool->frag_size, GFP_ATOMIC);
+
+ return kmalloc(pool->frag_size, GFP_ATOMIC);
}
-static void mvpp2_frag_free(const struct mvpp2_bm_pool *pool, void *data)
+static void mvpp2_frag_free(const struct mvpp2_bm_pool *pool,
+ struct page_pool *page_pool, void *data)
{
- if (likely(pool->frag_size <= PAGE_SIZE))
+ if (page_pool)
+ page_pool_put_full_page(page_pool, virt_to_head_page(data), false);
+ else if (likely(pool->frag_size <= PAGE_SIZE))
skb_free_frag(data);
else
kfree(data);
@@ -442,6 +474,7 @@ static void mvpp2_bm_bufs_get_addrs(struct device *dev, struct mvpp2 *priv,
static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv,
struct mvpp2_bm_pool *bm_pool, int buf_num)
{
+ struct page_pool *pp = NULL;
int i;
if (buf_num > bm_pool->buf_num) {
@@ -450,6 +483,9 @@ static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv,
buf_num = bm_pool->buf_num;
}
+ if (priv->percpu_pools)
+ pp = priv->page_pool[bm_pool->id];
+
for (i = 0; i < buf_num; i++) {
dma_addr_t buf_dma_addr;
phys_addr_t buf_phys_addr;
@@ -458,14 +494,15 @@ static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv,
mvpp2_bm_bufs_get_addrs(dev, priv, bm_pool,
&buf_dma_addr, &buf_phys_addr);
- dma_unmap_single(dev, buf_dma_addr,
- bm_pool->buf_size, DMA_FROM_DEVICE);
+ if (!pp)
+ dma_unmap_single(dev, buf_dma_addr,
+ bm_pool->buf_size, DMA_FROM_DEVICE);
data = (void *)phys_to_virt(buf_phys_addr);
if (!data)
break;
- mvpp2_frag_free(bm_pool, data);
+ mvpp2_frag_free(bm_pool, pp, data);
}
/* Update BM driver with number of buffers removed from pool */
@@ -511,6 +548,11 @@ static int mvpp2_bm_pool_destroy(struct device *dev, struct mvpp2 *priv,
val |= MVPP2_BM_STOP_MASK;
mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val);
+ if (priv->percpu_pools) {
+ page_pool_destroy(priv->page_pool[bm_pool->id]);
+ priv->page_pool[bm_pool->id] = NULL;
+ }
+
dma_free_coherent(dev, bm_pool->size_bytes,
bm_pool->virt_addr,
bm_pool->dma_addr);
@@ -546,10 +588,40 @@ err_unroll_pools:
static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv)
{
+ enum dma_data_direction dma_dir = DMA_FROM_DEVICE;
int i, err, poolnum = MVPP2_BM_POOLS_NUM;
+ struct mvpp2_port *port;
+
+ if (priv->percpu_pools) {
+ for (i = 0; i < priv->port_count; i++) {
+ port = priv->port_list[i];
+ if (port->xdp_prog) {
+ dma_dir = DMA_BIDIRECTIONAL;
+ break;
+ }
+ }
- if (priv->percpu_pools)
poolnum = mvpp2_get_nrxqs(priv) * 2;
+ for (i = 0; i < poolnum; i++) {
+ /* the pool in use */
+ int pn = i / (poolnum / 2);
+
+ priv->page_pool[i] =
+ mvpp2_create_page_pool(dev,
+ mvpp2_pools[pn].buf_num,
+ mvpp2_pools[pn].pkt_size,
+ dma_dir);
+ if (IS_ERR(priv->page_pool[i])) {
+ int j;
+
+ for (j = 0; j < i; j++) {
+ page_pool_destroy(priv->page_pool[j]);
+ priv->page_pool[j] = NULL;
+ }
+ return PTR_ERR(priv->page_pool[i]);
+ }
+ }
+ }
dev_info(dev, "using %d %s buffers\n", poolnum,
priv->percpu_pools ? "per-cpu" : "shared");
@@ -632,23 +704,31 @@ static void mvpp2_rxq_short_pool_set(struct mvpp2_port *port,
static void *mvpp2_buf_alloc(struct mvpp2_port *port,
struct mvpp2_bm_pool *bm_pool,
+ struct page_pool *page_pool,
dma_addr_t *buf_dma_addr,
phys_addr_t *buf_phys_addr,
gfp_t gfp_mask)
{
dma_addr_t dma_addr;
+ struct page *page;
void *data;
- data = mvpp2_frag_alloc(bm_pool);
+ data = mvpp2_frag_alloc(bm_pool, page_pool);
if (!data)
return NULL;
- dma_addr = dma_map_single(port->dev->dev.parent, data,
- MVPP2_RX_BUF_SIZE(bm_pool->pkt_size),
- DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(port->dev->dev.parent, dma_addr))) {
- mvpp2_frag_free(bm_pool, data);
- return NULL;
+ if (page_pool) {
+ page = (struct page *)data;
+ dma_addr = page_pool_get_dma_addr(page);
+ data = page_to_virt(page);
+ } else {
+ dma_addr = dma_map_single(port->dev->dev.parent, data,
+ MVPP2_RX_BUF_SIZE(bm_pool->pkt_size),
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(port->dev->dev.parent, dma_addr))) {
+ mvpp2_frag_free(bm_pool, NULL, data);
+ return NULL;
+ }
}
*buf_dma_addr = dma_addr;
*buf_phys_addr = virt_to_phys(data);
@@ -706,6 +786,7 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
int i, buf_size, total_size;
dma_addr_t dma_addr;
phys_addr_t phys_addr;
+ struct page_pool *pp = NULL;
void *buf;
if (port->priv->percpu_pools &&
@@ -726,8 +807,10 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
return 0;
}
+ if (port->priv->percpu_pools)
+ pp = port->priv->page_pool[bm_pool->id];
for (i = 0; i < buf_num; i++) {
- buf = mvpp2_buf_alloc(port, bm_pool, &dma_addr,
+ buf = mvpp2_buf_alloc(port, bm_pool, pp, &dma_addr,
&phys_addr, GFP_KERNEL);
if (!buf)
break;
@@ -907,28 +990,27 @@ static int mvpp2_swf_bm_pool_init_shared(struct mvpp2_port *port)
/* Initialize pools for swf, percpu buffers variant */
static int mvpp2_swf_bm_pool_init_percpu(struct mvpp2_port *port)
{
- struct mvpp2_bm_pool *p;
+ struct mvpp2_bm_pool *bm_pool;
int i;
for (i = 0; i < port->nrxqs; i++) {
- p = mvpp2_bm_pool_use_percpu(port, MVPP2_BM_SHORT, i,
- mvpp2_pools[MVPP2_BM_SHORT].pkt_size);
- if (!p)
+ bm_pool = mvpp2_bm_pool_use_percpu(port, MVPP2_BM_SHORT, i,
+ mvpp2_pools[MVPP2_BM_SHORT].pkt_size);
+ if (!bm_pool)
return -ENOMEM;
- port->priv->bm_pools[i].port_map |= BIT(port->id);
- mvpp2_rxq_short_pool_set(port, i, port->priv->bm_pools[i].id);
+ bm_pool->port_map |= BIT(port->id);
+ mvpp2_rxq_short_pool_set(port, i, bm_pool->id);
}
for (i = 0; i < port->nrxqs; i++) {
- p = mvpp2_bm_pool_use_percpu(port, MVPP2_BM_LONG, i + port->nrxqs,
- mvpp2_pools[MVPP2_BM_LONG].pkt_size);
- if (!p)
+ bm_pool = mvpp2_bm_pool_use_percpu(port, MVPP2_BM_LONG, i + port->nrxqs,
+ mvpp2_pools[MVPP2_BM_LONG].pkt_size);
+ if (!bm_pool)
return -ENOMEM;
- port->priv->bm_pools[i + port->nrxqs].port_map |= BIT(port->id);
- mvpp2_rxq_long_pool_set(port, i,
- port->priv->bm_pools[i + port->nrxqs].id);
+ bm_pool->port_map |= BIT(port->id);
+ mvpp2_rxq_long_pool_set(port, i, bm_pool->id);
}
port->pool_long = NULL;
@@ -1114,6 +1196,17 @@ mvpp2_shared_interrupt_mask_unmask(struct mvpp2_port *port, bool mask)
}
}
+/* Only GOP port 0 has an XLG MAC */
+static bool mvpp2_port_supports_xlg(struct mvpp2_port *port)
+{
+ return port->gop_id == 0;
+}
+
+static bool mvpp2_port_supports_rgmii(struct mvpp2_port *port)
+{
+ return !(port->priv->hw_version == MVPP22 && port->gop_id == 0);
+}
+
/* Port configuration routines */
static bool mvpp2_is_xlg(phy_interface_t interface)
{
@@ -1121,6 +1214,17 @@ static bool mvpp2_is_xlg(phy_interface_t interface)
interface == PHY_INTERFACE_MODE_XAUI;
}
+static void mvpp2_modify(void __iomem *ptr, u32 mask, u32 set)
+{
+ u32 old, val;
+
+ old = val = readl(ptr);
+ val &= ~mask;
+ val |= set;
+ if (old != val)
+ writel(val, ptr);
+}
+
static void mvpp22_gop_init_rgmii(struct mvpp2_port *port)
{
struct mvpp2 *priv = port->priv;
@@ -1194,7 +1298,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
- if (port->gop_id == 0)
+ if (!mvpp2_port_supports_rgmii(port))
goto invalid_conf;
mvpp22_gop_init_rgmii(port);
break;
@@ -1204,7 +1308,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
mvpp22_gop_init_sgmii(port);
break;
case PHY_INTERFACE_MODE_10GBASER:
- if (port->gop_id != 0)
+ if (!mvpp2_port_supports_xlg(port))
goto invalid_conf;
mvpp22_gop_init_10gkr(port);
break;
@@ -1246,7 +1350,7 @@ static void mvpp22_gop_unmask_irq(struct mvpp2_port *port)
writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK);
}
- if (port->gop_id == 0) {
+ if (mvpp2_port_supports_xlg(port)) {
/* Enable the XLG/GIG irqs for this port */
val = readl(port->base + MVPP22_XLG_EXT_INT_MASK);
if (mvpp2_is_xlg(port->phy_interface))
@@ -1261,7 +1365,7 @@ static void mvpp22_gop_mask_irq(struct mvpp2_port *port)
{
u32 val;
- if (port->gop_id == 0) {
+ if (mvpp2_port_supports_xlg(port)) {
val = readl(port->base + MVPP22_XLG_EXT_INT_MASK);
val &= ~(MVPP22_XLG_EXT_INT_MASK_XLG |
MVPP22_XLG_EXT_INT_MASK_GIG);
@@ -1290,7 +1394,7 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
writel(val, port->base + MVPP22_GMAC_INT_MASK);
}
- if (port->gop_id == 0) {
+ if (mvpp2_port_supports_xlg(port)) {
val = readl(port->base + MVPP22_XLG_INT_MASK);
val |= MVPP22_XLG_INT_MASK_LINK;
writel(val, port->base + MVPP22_XLG_INT_MASK);
@@ -1328,8 +1432,8 @@ static void mvpp2_port_enable(struct mvpp2_port *port)
{
u32 val;
- /* Only GOP port 0 has an XLG MAC */
- if (port->gop_id == 0 && mvpp2_is_xlg(port->phy_interface)) {
+ if (mvpp2_port_supports_xlg(port) &&
+ mvpp2_is_xlg(port->phy_interface)) {
val = readl(port->base + MVPP22_XLG_CTRL0_REG);
val |= MVPP22_XLG_CTRL0_PORT_EN;
val &= ~MVPP22_XLG_CTRL0_MIB_CNT_DIS;
@@ -1346,8 +1450,8 @@ static void mvpp2_port_disable(struct mvpp2_port *port)
{
u32 val;
- /* Only GOP port 0 has an XLG MAC */
- if (port->gop_id == 0 && mvpp2_is_xlg(port->phy_interface)) {
+ if (mvpp2_port_supports_xlg(port) &&
+ mvpp2_is_xlg(port->phy_interface)) {
val = readl(port->base + MVPP22_XLG_CTRL0_REG);
val &= ~MVPP22_XLG_CTRL0_PORT_EN;
writel(val, port->base + MVPP22_XLG_CTRL0_REG);
@@ -1390,6 +1494,16 @@ static void mvpp2_port_loopback_set(struct mvpp2_port *port,
writel(val, port->base + MVPP2_GMAC_CTRL_1_REG);
}
+enum {
+ ETHTOOL_XDP_REDIRECT,
+ ETHTOOL_XDP_PASS,
+ ETHTOOL_XDP_DROP,
+ ETHTOOL_XDP_TX,
+ ETHTOOL_XDP_TX_ERR,
+ ETHTOOL_XDP_XMIT,
+ ETHTOOL_XDP_XMIT_ERR,
+};
+
struct mvpp2_ethtool_counter {
unsigned int offset;
const char string[ETH_GSTRING_LEN];
@@ -1482,10 +1596,21 @@ static const struct mvpp2_ethtool_counter mvpp2_ethtool_rxq_regs[] = {
{ MVPP2_RX_PKTS_BM_DROP_CTR, "rxq_%d_packets_bm_drops" },
};
+static const struct mvpp2_ethtool_counter mvpp2_ethtool_xdp[] = {
+ { ETHTOOL_XDP_REDIRECT, "rx_xdp_redirect", },
+ { ETHTOOL_XDP_PASS, "rx_xdp_pass", },
+ { ETHTOOL_XDP_DROP, "rx_xdp_drop", },
+ { ETHTOOL_XDP_TX, "rx_xdp_tx", },
+ { ETHTOOL_XDP_TX_ERR, "rx_xdp_tx_errors", },
+ { ETHTOOL_XDP_XMIT, "tx_xdp_xmit", },
+ { ETHTOOL_XDP_XMIT_ERR, "tx_xdp_xmit_errors", },
+};
+
#define MVPP2_N_ETHTOOL_STATS(ntxqs, nrxqs) (ARRAY_SIZE(mvpp2_ethtool_mib_regs) + \
ARRAY_SIZE(mvpp2_ethtool_port_regs) + \
(ARRAY_SIZE(mvpp2_ethtool_txq_regs) * (ntxqs)) + \
- (ARRAY_SIZE(mvpp2_ethtool_rxq_regs) * (nrxqs)))
+ (ARRAY_SIZE(mvpp2_ethtool_rxq_regs) * (nrxqs)) + \
+ ARRAY_SIZE(mvpp2_ethtool_xdp))
static void mvpp2_ethtool_get_strings(struct net_device *netdev, u32 sset,
u8 *data)
@@ -1524,10 +1649,57 @@ static void mvpp2_ethtool_get_strings(struct net_device *netdev, u32 sset,
data += ETH_GSTRING_LEN;
}
}
+
+ for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_xdp); i++) {
+ strscpy(data, mvpp2_ethtool_xdp[i].string,
+ ETH_GSTRING_LEN);
+ data += ETH_GSTRING_LEN;
+ }
+}
+
+static void
+mvpp2_get_xdp_stats(struct mvpp2_port *port, struct mvpp2_pcpu_stats *xdp_stats)
+{
+ unsigned int start;
+ unsigned int cpu;
+
+ /* Gather XDP Statistics */
+ for_each_possible_cpu(cpu) {
+ struct mvpp2_pcpu_stats *cpu_stats;
+ u64 xdp_redirect;
+ u64 xdp_pass;
+ u64 xdp_drop;
+ u64 xdp_xmit;
+ u64 xdp_xmit_err;
+ u64 xdp_tx;
+ u64 xdp_tx_err;
+
+ cpu_stats = per_cpu_ptr(port->stats, cpu);
+ do {
+ start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
+ xdp_redirect = cpu_stats->xdp_redirect;
+ xdp_pass = cpu_stats->xdp_pass;
+ xdp_drop = cpu_stats->xdp_drop;
+ xdp_xmit = cpu_stats->xdp_xmit;
+ xdp_xmit_err = cpu_stats->xdp_xmit_err;
+ xdp_tx = cpu_stats->xdp_tx;
+ xdp_tx_err = cpu_stats->xdp_tx_err;
+ } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
+
+ xdp_stats->xdp_redirect += xdp_redirect;
+ xdp_stats->xdp_pass += xdp_pass;
+ xdp_stats->xdp_drop += xdp_drop;
+ xdp_stats->xdp_xmit += xdp_xmit;
+ xdp_stats->xdp_xmit_err += xdp_xmit_err;
+ xdp_stats->xdp_tx += xdp_tx;
+ xdp_stats->xdp_tx_err += xdp_tx_err;
+ }
}
static void mvpp2_read_stats(struct mvpp2_port *port)
{
+ struct mvpp2_pcpu_stats xdp_stats = {};
+ const struct mvpp2_ethtool_counter *s;
u64 *pstats;
int i, q;
@@ -1555,6 +1727,37 @@ static void mvpp2_read_stats(struct mvpp2_port *port)
*pstats++ += mvpp2_read_index(port->priv,
port->first_rxq + q,
mvpp2_ethtool_rxq_regs[i].offset);
+
+ /* Gather XDP Statistics */
+ mvpp2_get_xdp_stats(port, &xdp_stats);
+
+ for (i = 0, s = mvpp2_ethtool_xdp;
+ s < mvpp2_ethtool_xdp + ARRAY_SIZE(mvpp2_ethtool_xdp);
+ s++, i++) {
+ switch (s->offset) {
+ case ETHTOOL_XDP_REDIRECT:
+ *pstats++ = xdp_stats.xdp_redirect;
+ break;
+ case ETHTOOL_XDP_PASS:
+ *pstats++ = xdp_stats.xdp_pass;
+ break;
+ case ETHTOOL_XDP_DROP:
+ *pstats++ = xdp_stats.xdp_drop;
+ break;
+ case ETHTOOL_XDP_TX:
+ *pstats++ = xdp_stats.xdp_tx;
+ break;
+ case ETHTOOL_XDP_TX_ERR:
+ *pstats++ = xdp_stats.xdp_tx_err;
+ break;
+ case ETHTOOL_XDP_XMIT:
+ *pstats++ = xdp_stats.xdp_xmit;
+ break;
+ case ETHTOOL_XDP_XMIT_ERR:
+ *pstats++ = xdp_stats.xdp_xmit_err;
+ break;
+ }
+ }
}
static void mvpp2_gather_hw_statistics(struct work_struct *work)
@@ -2240,11 +2443,15 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
struct mvpp2_txq_pcpu_buf *tx_buf =
txq_pcpu->buffs + txq_pcpu->txq_get_index;
- if (!IS_TSO_HEADER(txq_pcpu, tx_buf->dma))
+ if (!IS_TSO_HEADER(txq_pcpu, tx_buf->dma) &&
+ tx_buf->type != MVPP2_TYPE_XDP_TX)
dma_unmap_single(port->dev->dev.parent, tx_buf->dma,
tx_buf->size, DMA_TO_DEVICE);
- if (tx_buf->skb)
+ if (tx_buf->type == MVPP2_TYPE_SKB && tx_buf->skb)
dev_kfree_skb_any(tx_buf->skb);
+ else if (tx_buf->type == MVPP2_TYPE_XDP_TX ||
+ tx_buf->type == MVPP2_TYPE_XDP_NDO)
+ xdp_return_frame(tx_buf->xdpf);
mvpp2_txq_inc_get(txq_pcpu);
}
@@ -2353,10 +2560,11 @@ static int mvpp2_aggr_txq_init(struct platform_device *pdev,
/* Create a specified Rx queue */
static int mvpp2_rxq_init(struct mvpp2_port *port,
struct mvpp2_rx_queue *rxq)
-
{
+ struct mvpp2 *priv = port->priv;
unsigned int thread;
u32 rxq_dma;
+ int err;
rxq->size = port->rx_ring_size;
@@ -2385,7 +2593,7 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,
put_cpu();
/* Set Offset */
- mvpp2_rxq_offset_set(port, rxq->id, NET_SKB_PAD);
+ mvpp2_rxq_offset_set(port, rxq->id, MVPP2_SKB_HEADROOM);
/* Set coalescing pkts and time */
mvpp2_rx_pkts_coal_set(port, rxq);
@@ -2394,7 +2602,43 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,
/* Add number of descriptors ready for receiving packets */
mvpp2_rxq_status_update(port, rxq->id, 0, rxq->size);
+ if (priv->percpu_pools) {
+ err = xdp_rxq_info_reg(&rxq->xdp_rxq_short, port->dev, rxq->id);
+ if (err < 0)
+ goto err_free_dma;
+
+ err = xdp_rxq_info_reg(&rxq->xdp_rxq_long, port->dev, rxq->id);
+ if (err < 0)
+ goto err_unregister_rxq_short;
+
+ /* Every RXQ has a pool for short and another for long packets */
+ err = xdp_rxq_info_reg_mem_model(&rxq->xdp_rxq_short,
+ MEM_TYPE_PAGE_POOL,
+ priv->page_pool[rxq->logic_rxq]);
+ if (err < 0)
+ goto err_unregister_rxq_long;
+
+ err = xdp_rxq_info_reg_mem_model(&rxq->xdp_rxq_long,
+ MEM_TYPE_PAGE_POOL,
+ priv->page_pool[rxq->logic_rxq +
+ port->nrxqs]);
+ if (err < 0)
+ goto err_unregister_mem_rxq_short;
+ }
+
return 0;
+
+err_unregister_mem_rxq_short:
+ xdp_rxq_info_unreg_mem_model(&rxq->xdp_rxq_short);
+err_unregister_rxq_long:
+ xdp_rxq_info_unreg(&rxq->xdp_rxq_long);
+err_unregister_rxq_short:
+ xdp_rxq_info_unreg(&rxq->xdp_rxq_short);
+err_free_dma:
+ dma_free_coherent(port->dev->dev.parent,
+ rxq->size * MVPP2_DESC_ALIGNED_SIZE,
+ rxq->descs, rxq->descs_dma);
+ return err;
}
/* Push packets received by the RXQ to BM pool */
@@ -2428,6 +2672,12 @@ static void mvpp2_rxq_deinit(struct mvpp2_port *port,
{
unsigned int thread;
+ if (xdp_rxq_info_is_reg(&rxq->xdp_rxq_short))
+ xdp_rxq_info_unreg(&rxq->xdp_rxq_short);
+
+ if (xdp_rxq_info_is_reg(&rxq->xdp_rxq_long))
+ xdp_rxq_info_unreg(&rxq->xdp_rxq_long);
+
mvpp2_rxq_drop_pkts(port, rxq);
if (rxq->descs)
@@ -2689,7 +2939,7 @@ err_cleanup:
static int mvpp2_setup_txqs(struct mvpp2_port *port)
{
struct mvpp2_tx_queue *txq;
- int queue, err, cpu;
+ int queue, err;
for (queue = 0; queue < port->ntxqs; queue++) {
txq = port->txqs[queue];
@@ -2698,8 +2948,8 @@ static int mvpp2_setup_txqs(struct mvpp2_port *port)
goto err_cleanup;
/* Assign this queue to a CPU */
- cpu = queue % num_present_cpus();
- netif_set_xps_queue(port->dev, cpumask_of(cpu), queue);
+ if (queue < num_possible_cpus())
+ netif_set_xps_queue(port->dev, cpumask_of(queue), queue);
}
if (port->has_tx_irqs) {
@@ -2740,7 +2990,8 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)
mvpp22_gop_mask_irq(port);
- if (port->gop_id == 0 && mvpp2_is_xlg(port->phy_interface)) {
+ if (mvpp2_port_supports_xlg(port) &&
+ mvpp2_is_xlg(port->phy_interface)) {
val = readl(port->base + MVPP22_XLG_INT_STAT);
if (val & MVPP22_XLG_INT_STAT_LINK) {
event = true;
@@ -2868,14 +3119,15 @@ static void mvpp2_rx_csum(struct mvpp2_port *port, u32 status,
/* Allocate a new skb and add it to BM pool */
static int mvpp2_rx_refill(struct mvpp2_port *port,
- struct mvpp2_bm_pool *bm_pool, int pool)
+ struct mvpp2_bm_pool *bm_pool,
+ struct page_pool *page_pool, int pool)
{
dma_addr_t dma_addr;
phys_addr_t phys_addr;
void *buf;
- buf = mvpp2_buf_alloc(port, bm_pool, &dma_addr, &phys_addr,
- GFP_ATOMIC);
+ buf = mvpp2_buf_alloc(port, bm_pool, page_pool,
+ &dma_addr, &phys_addr, GFP_ATOMIC);
if (!buf)
return -ENOMEM;
@@ -2916,15 +3168,251 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)
return MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE;
}
+static void mvpp2_xdp_finish_tx(struct mvpp2_port *port, u16 txq_id, int nxmit, int nxmit_byte)
+{
+ unsigned int thread = mvpp2_cpu_to_thread(port->priv, smp_processor_id());
+ struct mvpp2_tx_queue *aggr_txq;
+ struct mvpp2_txq_pcpu *txq_pcpu;
+ struct mvpp2_tx_queue *txq;
+ struct netdev_queue *nq;
+
+ txq = port->txqs[txq_id];
+ txq_pcpu = per_cpu_ptr(txq->pcpu, thread);
+ nq = netdev_get_tx_queue(port->dev, txq_id);
+ aggr_txq = &port->priv->aggr_txqs[thread];
+
+ txq_pcpu->reserved_num -= nxmit;
+ txq_pcpu->count += nxmit;
+ aggr_txq->count += nxmit;
+
+ /* Enable transmit */
+ wmb();
+ mvpp2_aggr_txq_pend_desc_add(port, nxmit);
+
+ if (txq_pcpu->count >= txq_pcpu->stop_threshold)
+ netif_tx_stop_queue(nq);
+
+ /* Finalize TX processing */
+ if (!port->has_tx_irqs && txq_pcpu->count >= txq->done_pkts_coal)
+ mvpp2_txq_done(port, txq, txq_pcpu);
+}
+
+static int
+mvpp2_xdp_submit_frame(struct mvpp2_port *port, u16 txq_id,
+ struct xdp_frame *xdpf, bool dma_map)
+{
+ unsigned int thread = mvpp2_cpu_to_thread(port->priv, smp_processor_id());
+ u32 tx_cmd = MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE |
+ MVPP2_TXD_F_DESC | MVPP2_TXD_L_DESC;
+ enum mvpp2_tx_buf_type buf_type;
+ struct mvpp2_txq_pcpu *txq_pcpu;
+ struct mvpp2_tx_queue *aggr_txq;
+ struct mvpp2_tx_desc *tx_desc;
+ struct mvpp2_tx_queue *txq;
+ int ret = MVPP2_XDP_TX;
+ dma_addr_t dma_addr;
+
+ txq = port->txqs[txq_id];
+ txq_pcpu = per_cpu_ptr(txq->pcpu, thread);
+ aggr_txq = &port->priv->aggr_txqs[thread];
+
+ /* Check number of available descriptors */
+ if (mvpp2_aggr_desc_num_check(port, aggr_txq, 1) ||
+ mvpp2_txq_reserved_desc_num_proc(port, txq, txq_pcpu, 1)) {
+ ret = MVPP2_XDP_DROPPED;
+ goto out;
+ }
+
+ /* Get a descriptor for the first part of the packet */
+ tx_desc = mvpp2_txq_next_desc_get(aggr_txq);
+ mvpp2_txdesc_txq_set(port, tx_desc, txq->id);
+ mvpp2_txdesc_size_set(port, tx_desc, xdpf->len);
+
+ if (dma_map) {
+ /* XDP_REDIRECT or AF_XDP */
+ dma_addr = dma_map_single(port->dev->dev.parent, xdpf->data,
+ xdpf->len, DMA_TO_DEVICE);
+
+ if (unlikely(dma_mapping_error(port->dev->dev.parent, dma_addr))) {
+ mvpp2_txq_desc_put(txq);
+ ret = MVPP2_XDP_DROPPED;
+ goto out;
+ }
+
+ buf_type = MVPP2_TYPE_XDP_NDO;
+ } else {
+ /* XDP_TX */
+ struct page *page = virt_to_page(xdpf->data);
+
+ dma_addr = page_pool_get_dma_addr(page) +
+ sizeof(*xdpf) + xdpf->headroom;
+ dma_sync_single_for_device(port->dev->dev.parent, dma_addr,
+ xdpf->len, DMA_BIDIRECTIONAL);
+
+ buf_type = MVPP2_TYPE_XDP_TX;
+ }
+
+ mvpp2_txdesc_dma_addr_set(port, tx_desc, dma_addr);
+
+ mvpp2_txdesc_cmd_set(port, tx_desc, tx_cmd);
+ mvpp2_txq_inc_put(port, txq_pcpu, xdpf, tx_desc, buf_type);
+
+out:
+ return ret;
+}
+
+static int
+mvpp2_xdp_xmit_back(struct mvpp2_port *port, struct xdp_buff *xdp)
+{
+ struct mvpp2_pcpu_stats *stats = this_cpu_ptr(port->stats);
+ struct xdp_frame *xdpf;
+ u16 txq_id;
+ int ret;
+
+ xdpf = xdp_convert_buff_to_frame(xdp);
+ if (unlikely(!xdpf))
+ return MVPP2_XDP_DROPPED;
+
+ /* The first of the TX queues are used for XPS,
+ * the second half for XDP_TX
+ */
+ txq_id = mvpp2_cpu_to_thread(port->priv, smp_processor_id()) + (port->ntxqs / 2);
+
+ ret = mvpp2_xdp_submit_frame(port, txq_id, xdpf, false);
+ if (ret == MVPP2_XDP_TX) {
+ u64_stats_update_begin(&stats->syncp);
+ stats->tx_bytes += xdpf->len;
+ stats->tx_packets++;
+ stats->xdp_tx++;
+ u64_stats_update_end(&stats->syncp);
+
+ mvpp2_xdp_finish_tx(port, txq_id, 1, xdpf->len);
+ } else {
+ u64_stats_update_begin(&stats->syncp);
+ stats->xdp_tx_err++;
+ u64_stats_update_end(&stats->syncp);
+ }
+
+ return ret;
+}
+
+static int
+mvpp2_xdp_xmit(struct net_device *dev, int num_frame,
+ struct xdp_frame **frames, u32 flags)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ int i, nxmit_byte = 0, nxmit = num_frame;
+ struct mvpp2_pcpu_stats *stats;
+ u16 txq_id;
+ u32 ret;
+
+ if (unlikely(test_bit(0, &port->state)))
+ return -ENETDOWN;
+
+ if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
+ return -EINVAL;
+
+ /* The first of the TX queues are used for XPS,
+ * the second half for XDP_TX
+ */
+ txq_id = mvpp2_cpu_to_thread(port->priv, smp_processor_id()) + (port->ntxqs / 2);
+
+ for (i = 0; i < num_frame; i++) {
+ ret = mvpp2_xdp_submit_frame(port, txq_id, frames[i], true);
+ if (ret == MVPP2_XDP_TX) {
+ nxmit_byte += frames[i]->len;
+ } else {
+ xdp_return_frame_rx_napi(frames[i]);
+ nxmit--;
+ }
+ }
+
+ if (likely(nxmit > 0))
+ mvpp2_xdp_finish_tx(port, txq_id, nxmit, nxmit_byte);
+
+ stats = this_cpu_ptr(port->stats);
+ u64_stats_update_begin(&stats->syncp);
+ stats->tx_bytes += nxmit_byte;
+ stats->tx_packets += nxmit;
+ stats->xdp_xmit += nxmit;
+ stats->xdp_xmit_err += num_frame - nxmit;
+ u64_stats_update_end(&stats->syncp);
+
+ return nxmit;
+}
+
+static int
+mvpp2_run_xdp(struct mvpp2_port *port, struct mvpp2_rx_queue *rxq,
+ struct bpf_prog *prog, struct xdp_buff *xdp,
+ struct page_pool *pp, struct mvpp2_pcpu_stats *stats)
+{
+ unsigned int len, sync, err;
+ struct page *page;
+ u32 ret, act;
+
+ len = xdp->data_end - xdp->data_hard_start - MVPP2_SKB_HEADROOM;
+ act = bpf_prog_run_xdp(prog, xdp);
+
+ /* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */
+ sync = xdp->data_end - xdp->data_hard_start - MVPP2_SKB_HEADROOM;
+ sync = max(sync, len);
+
+ switch (act) {
+ case XDP_PASS:
+ stats->xdp_pass++;
+ ret = MVPP2_XDP_PASS;
+ break;
+ case XDP_REDIRECT:
+ err = xdp_do_redirect(port->dev, xdp, prog);
+ if (unlikely(err)) {
+ ret = MVPP2_XDP_DROPPED;
+ page = virt_to_head_page(xdp->data);
+ page_pool_put_page(pp, page, sync, true);
+ } else {
+ ret = MVPP2_XDP_REDIR;
+ stats->xdp_redirect++;
+ }
+ break;
+ case XDP_TX:
+ ret = mvpp2_xdp_xmit_back(port, xdp);
+ if (ret != MVPP2_XDP_TX) {
+ page = virt_to_head_page(xdp->data);
+ page_pool_put_page(pp, page, sync, true);
+ }
+ break;
+ default:
+ bpf_warn_invalid_xdp_action(act);
+ fallthrough;
+ case XDP_ABORTED:
+ trace_xdp_exception(port->dev, prog, act);
+ fallthrough;
+ case XDP_DROP:
+ page = virt_to_head_page(xdp->data);
+ page_pool_put_page(pp, page, sync, true);
+ ret = MVPP2_XDP_DROPPED;
+ stats->xdp_drop++;
+ break;
+ }
+
+ return ret;
+}
+
/* Main rx processing */
static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
int rx_todo, struct mvpp2_rx_queue *rxq)
{
struct net_device *dev = port->dev;
+ struct mvpp2_pcpu_stats ps = {};
+ enum dma_data_direction dma_dir;
+ struct bpf_prog *xdp_prog;
+ struct xdp_buff xdp;
int rx_received;
int rx_done = 0;
- u32 rcvd_pkts = 0;
- u32 rcvd_bytes = 0;
+ u32 xdp_ret = 0;
+
+ rcu_read_lock();
+
+ xdp_prog = READ_ONCE(port->xdp_prog);
/* Get number of received packets and clamp the to-do */
rx_received = mvpp2_rxq_received(port, rxq->id);
@@ -2934,12 +3422,13 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
while (rx_done < rx_todo) {
struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
struct sk_buff *skb;
unsigned int frag_size;
dma_addr_t dma_addr;
phys_addr_t phys_addr;
u32 rx_status;
- int pool, rx_bytes, err;
+ int pool, rx_bytes, err, ret;
void *data;
rx_done++;
@@ -2962,9 +3451,18 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
if (rx_status & MVPP2_RXD_ERR_SUMMARY)
goto err_drop_frame;
+ if (port->priv->percpu_pools) {
+ pp = port->priv->page_pool[pool];
+ dma_dir = page_pool_get_dma_dir(pp);
+ } else {
+ dma_dir = DMA_FROM_DEVICE;
+ }
+
dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
rx_bytes + MVPP2_MH_SIZE,
- DMA_FROM_DEVICE);
+ dma_dir);
+
+ /* Prefetch header */
prefetch(data);
if (bm_pool->frag_size > PAGE_SIZE)
@@ -2972,26 +3470,59 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
else
frag_size = bm_pool->frag_size;
+ if (xdp_prog) {
+ xdp.data_hard_start = data;
+ xdp.data = data + MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM;
+ xdp.data_end = xdp.data + rx_bytes;
+ xdp.frame_sz = PAGE_SIZE;
+
+ if (bm_pool->pkt_size == MVPP2_BM_SHORT_PKT_SIZE)
+ xdp.rxq = &rxq->xdp_rxq_short;
+ else
+ xdp.rxq = &rxq->xdp_rxq_long;
+
+ xdp_set_data_meta_invalid(&xdp);
+
+ ret = mvpp2_run_xdp(port, rxq, xdp_prog, &xdp, pp, &ps);
+
+ if (ret) {
+ xdp_ret |= ret;
+ err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+ if (err) {
+ netdev_err(port->dev, "failed to refill BM pools\n");
+ goto err_drop_frame;
+ }
+
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+ continue;
+ }
+ }
+
skb = build_skb(data, frag_size);
if (!skb) {
netdev_warn(port->dev, "skb build failed\n");
goto err_drop_frame;
}
- err = mvpp2_rx_refill(port, bm_pool, pool);
+ err = mvpp2_rx_refill(port, bm_pool, pp, pool);
if (err) {
netdev_err(port->dev, "failed to refill BM pools\n");
+ dev_kfree_skb_any(skb);
goto err_drop_frame;
}
- dma_unmap_single_attrs(dev->dev.parent, dma_addr,
- bm_pool->buf_size, DMA_FROM_DEVICE,
- DMA_ATTR_SKIP_CPU_SYNC);
+ if (pp)
+ page_pool_release_page(pp, virt_to_page(data));
+ else
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size, DMA_FROM_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
- rcvd_pkts++;
- rcvd_bytes += rx_bytes;
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
- skb_reserve(skb, MVPP2_MH_SIZE + NET_SKB_PAD);
+ skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
skb_put(skb, rx_bytes);
skb->protocol = eth_type_trans(skb, dev);
mvpp2_rx_csum(port, rx_status, skb);
@@ -3006,12 +3537,21 @@ err_drop_frame:
mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
}
- if (rcvd_pkts) {
+ rcu_read_unlock();
+
+ if (xdp_ret & MVPP2_XDP_REDIR)
+ xdp_do_flush_map();
+
+ if (ps.rx_packets) {
struct mvpp2_pcpu_stats *stats = this_cpu_ptr(port->stats);
u64_stats_update_begin(&stats->syncp);
- stats->rx_packets += rcvd_pkts;
- stats->rx_bytes += rcvd_bytes;
+ stats->rx_packets += ps.rx_packets;
+ stats->rx_bytes += ps.rx_bytes;
+ /* xdp */
+ stats->xdp_redirect += ps.xdp_redirect;
+ stats->xdp_pass += ps.xdp_pass;
+ stats->xdp_drop += ps.xdp_drop;
u64_stats_update_end(&stats->syncp);
}
@@ -3072,11 +3612,11 @@ static int mvpp2_tx_frag_process(struct mvpp2_port *port, struct sk_buff *skb,
/* Last descriptor */
mvpp2_txdesc_cmd_set(port, tx_desc,
MVPP2_TXD_L_DESC);
- mvpp2_txq_inc_put(port, txq_pcpu, skb, tx_desc);
+ mvpp2_txq_inc_put(port, txq_pcpu, skb, tx_desc, MVPP2_TYPE_SKB);
} else {
/* Descriptor in the middle: Not First, Not Last */
mvpp2_txdesc_cmd_set(port, tx_desc, 0);
- mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc);
+ mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc, MVPP2_TYPE_SKB);
}
}
@@ -3114,7 +3654,7 @@ static inline void mvpp2_tso_put_hdr(struct sk_buff *skb,
mvpp2_txdesc_cmd_set(port, tx_desc, mvpp2_skb_tx_csum(port, skb) |
MVPP2_TXD_F_DESC |
MVPP2_TXD_PADDING_DISABLE);
- mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc);
+ mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc, MVPP2_TYPE_SKB);
}
static inline int mvpp2_tso_put_data(struct sk_buff *skb,
@@ -3143,14 +3683,14 @@ static inline int mvpp2_tso_put_data(struct sk_buff *skb,
if (!left) {
mvpp2_txdesc_cmd_set(port, tx_desc, MVPP2_TXD_L_DESC);
if (last) {
- mvpp2_txq_inc_put(port, txq_pcpu, skb, tx_desc);
+ mvpp2_txq_inc_put(port, txq_pcpu, skb, tx_desc, MVPP2_TYPE_SKB);
return 0;
}
} else {
mvpp2_txdesc_cmd_set(port, tx_desc, 0);
}
- mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc);
+ mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc, MVPP2_TYPE_SKB);
return 0;
}
@@ -3160,9 +3700,8 @@ static int mvpp2_tx_tso(struct sk_buff *skb, struct net_device *dev,
struct mvpp2_txq_pcpu *txq_pcpu)
{
struct mvpp2_port *port = netdev_priv(dev);
+ int hdr_sz, i, len, descs = 0;
struct tso_t tso;
- int hdr_sz = skb_transport_offset(skb) + tcp_hdrlen(skb);
- int i, len, descs = 0;
/* Check number of available descriptors */
if (mvpp2_aggr_desc_num_check(port, aggr_txq, tso_count_descs(skb)) ||
@@ -3170,7 +3709,8 @@ static int mvpp2_tx_tso(struct sk_buff *skb, struct net_device *dev,
tso_count_descs(skb)))
return 0;
- tso_start(skb, &tso);
+ hdr_sz = tso_start(skb, &tso);
+
len = skb->len - hdr_sz;
while (len > 0) {
int left = min_t(int, skb_shinfo(skb)->gso_size, len);
@@ -3263,12 +3803,12 @@ static netdev_tx_t mvpp2_tx(struct sk_buff *skb, struct net_device *dev)
/* First and Last descriptor */
tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_L_DESC;
mvpp2_txdesc_cmd_set(port, tx_desc, tx_cmd);
- mvpp2_txq_inc_put(port, txq_pcpu, skb, tx_desc);
+ mvpp2_txq_inc_put(port, txq_pcpu, skb, tx_desc, MVPP2_TYPE_SKB);
} else {
/* First but not Last */
tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_PADDING_DISABLE;
mvpp2_txdesc_cmd_set(port, tx_desc, tx_cmd);
- mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc);
+ mvpp2_txq_inc_put(port, txq_pcpu, NULL, tx_desc, MVPP2_TYPE_SKB);
/* Continue with other skb fragments */
if (mvpp2_tx_frag_process(port, skb, aggr_txq, txq)) {
@@ -3430,8 +3970,7 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
mvpp22_pcs_reset_deassert(port);
- /* Only GOP port 0 has an XLG MAC */
- if (port->gop_id == 0) {
+ if (mvpp2_port_supports_xlg(port)) {
ctrl3 = readl(port->base + MVPP22_XLG_CTRL3_REG);
ctrl3 &= ~MVPP22_XLG_CTRL3_MACMODESELECT_MASK;
@@ -3443,7 +3982,7 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
writel(ctrl3, port->base + MVPP22_XLG_CTRL3_REG);
}
- if (port->gop_id == 0 && mvpp2_is_xlg(port->phy_interface))
+ if (mvpp2_port_supports_xlg(port) && mvpp2_is_xlg(port->phy_interface))
mvpp2_xlg_max_rx_size_set(port);
else
mvpp2_gmac_max_rx_size_set(port);
@@ -3482,6 +4021,8 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
}
netif_tx_start_all_queues(port->dev);
+
+ clear_bit(0, &port->state);
}
/* Set hw internals when stopping port */
@@ -3489,6 +4030,8 @@ static void mvpp2_stop_dev(struct mvpp2_port *port)
{
int i;
+ set_bit(0, &port->state);
+
/* Disable interrupts on all threads */
mvpp2_interrupts_disable(port);
@@ -3895,6 +4438,10 @@ static int mvpp2_change_mtu(struct net_device *dev, int mtu)
}
if (MVPP2_RX_PKT_SIZE(mtu) > MVPP2_BM_LONG_PKT_SIZE) {
+ if (port->xdp_prog) {
+ netdev_err(dev, "Jumbo frames are not supported with XDP\n");
+ return -EINVAL;
+ }
if (priv->percpu_pools) {
netdev_warn(dev, "mtu %d too high, switching to shared buffers", mtu);
mvpp2_bm_switch_buffers(priv, false);
@@ -3940,6 +4487,33 @@ static int mvpp2_change_mtu(struct net_device *dev, int mtu)
return err;
}
+static int mvpp2_check_pagepool_dma(struct mvpp2_port *port)
+{
+ enum dma_data_direction dma_dir = DMA_FROM_DEVICE;
+ struct mvpp2 *priv = port->priv;
+ int err = -1, i;
+
+ if (!priv->percpu_pools)
+ return err;
+
+ if (!priv->page_pool[0])
+ return -ENOMEM;
+
+ for (i = 0; i < priv->port_count; i++) {
+ port = priv->port_list[i];
+ if (port->xdp_prog) {
+ dma_dir = DMA_BIDIRECTIONAL;
+ break;
+ }
+ }
+
+ /* All pools are equal in terms of DMA direction */
+ if (priv->page_pool[0]->p.dma_dir != dma_dir)
+ err = mvpp2_bm_switch_buffers(priv, true);
+
+ return err;
+}
+
static void
mvpp2_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
@@ -4033,6 +4607,61 @@ static int mvpp2_set_features(struct net_device *dev,
return 0;
}
+static int mvpp2_xdp_setup(struct mvpp2_port *port, struct netdev_bpf *bpf)
+{
+ struct bpf_prog *prog = bpf->prog, *old_prog;
+ bool running = netif_running(port->dev);
+ bool reset = !prog != !port->xdp_prog;
+
+ if (port->dev->mtu > ETH_DATA_LEN) {
+ NL_SET_ERR_MSG_MOD(bpf->extack, "XDP is not supported with jumbo frames enabled");
+ return -EOPNOTSUPP;
+ }
+
+ if (!port->priv->percpu_pools) {
+ NL_SET_ERR_MSG_MOD(bpf->extack, "Per CPU Pools required for XDP");
+ return -EOPNOTSUPP;
+ }
+
+ if (port->ntxqs < num_possible_cpus() * 2) {
+ NL_SET_ERR_MSG_MOD(bpf->extack, "XDP_TX needs two TX queues per CPU");
+ return -EOPNOTSUPP;
+ }
+
+ /* device is up and bpf is added/removed, must setup the RX queues */
+ if (running && reset)
+ mvpp2_stop(port->dev);
+
+ old_prog = xchg(&port->xdp_prog, prog);
+ if (old_prog)
+ bpf_prog_put(old_prog);
+
+ /* bpf is just replaced, RXQ and MTU are already setup */
+ if (!reset)
+ return 0;
+
+ /* device was up, restore the link */
+ if (running)
+ mvpp2_open(port->dev);
+
+ /* Check Page Pool DMA Direction */
+ mvpp2_check_pagepool_dma(port);
+
+ return 0;
+}
+
+static int mvpp2_xdp(struct net_device *dev, struct netdev_bpf *xdp)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+
+ switch (xdp->command) {
+ case XDP_SETUP_PROG:
+ return mvpp2_xdp_setup(port, xdp);
+ default:
+ return -EINVAL;
+ }
+}
+
/* Ethtool methods */
static int mvpp2_ethtool_nway_reset(struct net_device *dev)
@@ -4383,6 +5012,8 @@ static const struct net_device_ops mvpp2_netdev_ops = {
.ndo_vlan_rx_add_vid = mvpp2_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = mvpp2_vlan_rx_kill_vid,
.ndo_set_features = mvpp2_set_features,
+ .ndo_bpf = mvpp2_xdp,
+ .ndo_xdp_xmit = mvpp2_xdp_xmit,
};
static const struct ethtool_ops mvpp2_eth_tool_ops = {
@@ -4756,26 +5387,30 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,
eth_hw_addr_random(dev);
}
+static struct mvpp2_port *mvpp2_phylink_to_port(struct phylink_config *config)
+{
+ return container_of(config, struct mvpp2_port, phylink_config);
+}
+
static void mvpp2_phylink_validate(struct phylink_config *config,
unsigned long *supported,
struct phylink_link_state *state)
{
- struct mvpp2_port *port = container_of(config, struct mvpp2_port,
- phylink_config);
+ struct mvpp2_port *port = mvpp2_phylink_to_port(config);
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
/* Invalid combinations */
switch (state->interface) {
case PHY_INTERFACE_MODE_10GBASER:
case PHY_INTERFACE_MODE_XAUI:
- if (port->gop_id != 0)
+ if (!mvpp2_port_supports_xlg(port))
goto empty_set;
break;
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
- if (port->priv->hw_version == MVPP22 && port->gop_id == 0)
+ if (!mvpp2_port_supports_rgmii(port))
goto empty_set;
break;
default:
@@ -4791,7 +5426,7 @@ static void mvpp2_phylink_validate(struct phylink_config *config,
case PHY_INTERFACE_MODE_10GBASER:
case PHY_INTERFACE_MODE_XAUI:
case PHY_INTERFACE_MODE_NA:
- if (port->gop_id == 0) {
+ if (mvpp2_port_supports_xlg(port)) {
phylink_set(mask, 10000baseT_Full);
phylink_set(mask, 10000baseCR_Full);
phylink_set(mask, 10000baseSR_Full);
@@ -4902,8 +5537,7 @@ static void mvpp2_gmac_pcs_get_state(struct mvpp2_port *port,
static void mvpp2_phylink_mac_pcs_get_state(struct phylink_config *config,
struct phylink_link_state *state)
{
- struct mvpp2_port *port = container_of(config, struct mvpp2_port,
- phylink_config);
+ struct mvpp2_port *port = mvpp2_phylink_to_port(config);
if (port->priv->hw_version == MVPP22 && port->gop_id == 0) {
u32 mode = readl(port->base + MVPP22_XLG_CTRL3_REG);
@@ -4920,8 +5554,7 @@ static void mvpp2_phylink_mac_pcs_get_state(struct phylink_config *config,
static void mvpp2_mac_an_restart(struct phylink_config *config)
{
- struct mvpp2_port *port = container_of(config, struct mvpp2_port,
- phylink_config);
+ struct mvpp2_port *port = mvpp2_phylink_to_port(config);
u32 val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
writel(val | MVPP2_GMAC_IN_BAND_RESTART_AN,
@@ -4933,38 +5566,21 @@ static void mvpp2_mac_an_restart(struct phylink_config *config)
static void mvpp2_xlg_config(struct mvpp2_port *port, unsigned int mode,
const struct phylink_link_state *state)
{
- u32 old_ctrl0, ctrl0;
- u32 old_ctrl4, ctrl4;
-
- old_ctrl0 = ctrl0 = readl(port->base + MVPP22_XLG_CTRL0_REG);
- old_ctrl4 = ctrl4 = readl(port->base + MVPP22_XLG_CTRL4_REG);
-
- ctrl0 |= MVPP22_XLG_CTRL0_MAC_RESET_DIS;
-
- if (state->pause & MLO_PAUSE_TX)
- ctrl0 |= MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN;
- else
- ctrl0 &= ~MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN;
-
- if (state->pause & MLO_PAUSE_RX)
- ctrl0 |= MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN;
- else
- ctrl0 &= ~MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN;
-
- ctrl4 &= ~(MVPP22_XLG_CTRL4_MACMODSELECT_GMAC |
- MVPP22_XLG_CTRL4_EN_IDLE_CHECK);
- ctrl4 |= MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC;
+ u32 val;
- if (old_ctrl0 != ctrl0)
- writel(ctrl0, port->base + MVPP22_XLG_CTRL0_REG);
- if (old_ctrl4 != ctrl4)
- writel(ctrl4, port->base + MVPP22_XLG_CTRL4_REG);
+ mvpp2_modify(port->base + MVPP22_XLG_CTRL0_REG,
+ MVPP22_XLG_CTRL0_MAC_RESET_DIS,
+ MVPP22_XLG_CTRL0_MAC_RESET_DIS);
+ mvpp2_modify(port->base + MVPP22_XLG_CTRL4_REG,
+ MVPP22_XLG_CTRL4_MACMODSELECT_GMAC |
+ MVPP22_XLG_CTRL4_EN_IDLE_CHECK |
+ MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC,
+ MVPP22_XLG_CTRL4_FWD_FC | MVPP22_XLG_CTRL4_FWD_PFC);
- if (!(old_ctrl0 & MVPP22_XLG_CTRL0_MAC_RESET_DIS)) {
- while (!(readl(port->base + MVPP22_XLG_CTRL0_REG) &
- MVPP22_XLG_CTRL0_MAC_RESET_DIS))
- continue;
- }
+ /* Wait for reset to deassert */
+ do {
+ val = readl(port->base + MVPP22_XLG_CTRL0_REG);
+ } while (!(val & MVPP22_XLG_CTRL0_MAC_RESET_DIS));
}
static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,
@@ -5094,13 +5710,12 @@ static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,
static void mvpp2_mac_config(struct phylink_config *config, unsigned int mode,
const struct phylink_link_state *state)
{
- struct net_device *dev = to_net_dev(config->dev);
- struct mvpp2_port *port = netdev_priv(dev);
+ struct mvpp2_port *port = mvpp2_phylink_to_port(config);
bool change_interface = port->phy_interface != state->interface;
/* Check for invalid configuration */
if (mvpp2_is_xlg(state->interface) && port->gop_id != 0) {
- netdev_err(dev, "Invalid mode on %s\n", dev->name);
+ netdev_err(port->dev, "Invalid mode on %s\n", port->dev->name);
return;
}
@@ -5140,25 +5755,26 @@ static void mvpp2_mac_link_up(struct phylink_config *config,
int speed, int duplex,
bool tx_pause, bool rx_pause)
{
- struct net_device *dev = to_net_dev(config->dev);
- struct mvpp2_port *port = netdev_priv(dev);
+ struct mvpp2_port *port = mvpp2_phylink_to_port(config);
u32 val;
if (mvpp2_is_xlg(interface)) {
if (!phylink_autoneg_inband(mode)) {
- val = readl(port->base + MVPP22_XLG_CTRL0_REG);
- val &= ~MVPP22_XLG_CTRL0_FORCE_LINK_DOWN;
- val |= MVPP22_XLG_CTRL0_FORCE_LINK_PASS;
- writel(val, port->base + MVPP22_XLG_CTRL0_REG);
+ val = MVPP22_XLG_CTRL0_FORCE_LINK_PASS;
+ if (tx_pause)
+ val |= MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN;
+ if (rx_pause)
+ val |= MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN;
+
+ mvpp2_modify(port->base + MVPP22_XLG_CTRL0_REG,
+ MVPP22_XLG_CTRL0_FORCE_LINK_DOWN |
+ MVPP22_XLG_CTRL0_FORCE_LINK_PASS |
+ MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN |
+ MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN, val);
}
} else {
if (!phylink_autoneg_inband(mode)) {
- val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
- val &= ~(MVPP2_GMAC_FORCE_LINK_DOWN |
- MVPP2_GMAC_CONFIG_MII_SPEED |
- MVPP2_GMAC_CONFIG_GMII_SPEED |
- MVPP2_GMAC_CONFIG_FULL_DUPLEX);
- val |= MVPP2_GMAC_FORCE_LINK_PASS;
+ val = MVPP2_GMAC_FORCE_LINK_PASS;
if (speed == SPEED_1000 || speed == SPEED_2500)
val |= MVPP2_GMAC_CONFIG_GMII_SPEED;
@@ -5168,34 +5784,40 @@ static void mvpp2_mac_link_up(struct phylink_config *config,
if (duplex == DUPLEX_FULL)
val |= MVPP2_GMAC_CONFIG_FULL_DUPLEX;
- writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+ mvpp2_modify(port->base + MVPP2_GMAC_AUTONEG_CONFIG,
+ MVPP2_GMAC_FORCE_LINK_DOWN |
+ MVPP2_GMAC_FORCE_LINK_PASS |
+ MVPP2_GMAC_CONFIG_MII_SPEED |
+ MVPP2_GMAC_CONFIG_GMII_SPEED |
+ MVPP2_GMAC_CONFIG_FULL_DUPLEX, val);
}
/* We can always update the flow control enable bits;
* these will only be effective if flow control AN
* (MVPP2_GMAC_FLOW_CTRL_AUTONEG) is disabled.
*/
- val = readl(port->base + MVPP22_GMAC_CTRL_4_REG);
- val &= ~(MVPP22_CTRL4_RX_FC_EN | MVPP22_CTRL4_TX_FC_EN);
+ val = 0;
if (tx_pause)
val |= MVPP22_CTRL4_TX_FC_EN;
if (rx_pause)
val |= MVPP22_CTRL4_RX_FC_EN;
- writel(val, port->base + MVPP22_GMAC_CTRL_4_REG);
+
+ mvpp2_modify(port->base + MVPP22_GMAC_CTRL_4_REG,
+ MVPP22_CTRL4_RX_FC_EN | MVPP22_CTRL4_TX_FC_EN,
+ val);
}
mvpp2_port_enable(port);
mvpp2_egress_enable(port);
mvpp2_ingress_enable(port);
- netif_tx_wake_all_queues(dev);
+ netif_tx_wake_all_queues(port->dev);
}
static void mvpp2_mac_link_down(struct phylink_config *config,
unsigned int mode, phy_interface_t interface)
{
- struct net_device *dev = to_net_dev(config->dev);
- struct mvpp2_port *port = netdev_priv(dev);
+ struct mvpp2_port *port = mvpp2_phylink_to_port(config);
u32 val;
if (!phylink_autoneg_inband(mode)) {
@@ -5212,7 +5834,7 @@ static void mvpp2_mac_link_down(struct phylink_config *config,
}
}
- netif_tx_stop_all_queues(dev);
+ netif_tx_stop_all_queues(port->dev);
mvpp2_egress_disable(port);
mvpp2_ingress_disable(port);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/common.h b/drivers/net/ethernet/marvell/octeontx2/af/common.h
index cd33c2e6ca5f..f48eb66ed021 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/common.h
@@ -43,7 +43,7 @@ struct qmem {
void *base;
dma_addr_t iova;
int alloc_sz;
- u8 entry_sz;
+ u16 entry_sz;
u8 align;
u32 qsize;
};
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
index b04f5429d72d..3a5b34a2a7a6 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
@@ -619,13 +619,14 @@ static void otx2_sq_append_tso(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
struct sk_buff *skb, u16 qidx)
{
struct netdev_queue *txq = netdev_get_tx_queue(pfvf->netdev, qidx);
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- int tcp_data, seg_len, pkt_len, offset;
+ int hdr_len, tcp_data, seg_len, pkt_len, offset;
struct nix_sqe_hdr_s *sqe_hdr;
int first_sqe = sq->head;
struct sg_list list;
struct tso_t tso;
+ hdr_len = tso_start(skb, &tso);
+
/* Map SKB's fragments to DMA.
* It's done here to avoid mapping for every TSO segment's packet.
*/
@@ -636,7 +637,6 @@ static void otx2_sq_append_tso(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
netdev_tx_sent_queue(txq, skb->len);
- tso_start(skb, &tso);
tcp_data = skb->len - hdr_len;
while (tcp_data > 0) {
char *hdr;
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 3c89206f18a7..b792f6306a64 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -939,10 +939,10 @@ static int skge_rx_setup(struct skge_port *skge, struct skge_element *e,
struct skge_rx_desc *rd = e->desc;
dma_addr_t map;
- map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
- PCI_DMA_FROMDEVICE);
+ map = dma_map_single(&skge->hw->pdev->dev, skb->data, bufsize,
+ DMA_FROM_DEVICE);
- if (pci_dma_mapping_error(skge->hw->pdev, map))
+ if (dma_mapping_error(&skge->hw->pdev->dev, map))
return -1;
rd->dma_lo = lower_32_bits(map);
@@ -990,10 +990,10 @@ static void skge_rx_clean(struct skge_port *skge)
struct skge_rx_desc *rd = e->desc;
rd->control = 0;
if (e->skb) {
- pci_unmap_single(hw->pdev,
+ dma_unmap_single(&hw->pdev->dev,
dma_unmap_addr(e, mapaddr),
dma_unmap_len(e, maplen),
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
dev_kfree_skb(e->skb);
e->skb = NULL;
}
@@ -2547,14 +2547,15 @@ static int skge_up(struct net_device *dev)
rx_size = skge->rx_ring.count * sizeof(struct skge_rx_desc);
tx_size = skge->tx_ring.count * sizeof(struct skge_tx_desc);
skge->mem_size = tx_size + rx_size;
- skge->mem = pci_alloc_consistent(hw->pdev, skge->mem_size, &skge->dma);
+ skge->mem = dma_alloc_coherent(&hw->pdev->dev, skge->mem_size,
+ &skge->dma, GFP_KERNEL);
if (!skge->mem)
return -ENOMEM;
BUG_ON(skge->dma & 7);
if (upper_32_bits(skge->dma) != upper_32_bits(skge->dma + skge->mem_size)) {
- dev_err(&hw->pdev->dev, "pci_alloc_consistent region crosses 4G boundary\n");
+ dev_err(&hw->pdev->dev, "dma_alloc_coherent region crosses 4G boundary\n");
err = -EINVAL;
goto free_pci_mem;
}
@@ -2625,7 +2626,8 @@ static int skge_up(struct net_device *dev)
skge_rx_clean(skge);
kfree(skge->rx_ring.start);
free_pci_mem:
- pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+ dma_free_coherent(&hw->pdev->dev, skge->mem_size, skge->mem,
+ skge->dma);
skge->mem = NULL;
return err;
@@ -2715,7 +2717,8 @@ static int skge_down(struct net_device *dev)
kfree(skge->rx_ring.start);
kfree(skge->tx_ring.start);
- pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+ dma_free_coherent(&hw->pdev->dev, skge->mem_size, skge->mem,
+ skge->dma);
skge->mem = NULL;
return 0;
}
@@ -2749,8 +2752,8 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
BUG_ON(td->control & BMU_OWN);
e->skb = skb;
len = skb_headlen(skb);
- map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(hw->pdev, map))
+ map = dma_map_single(&hw->pdev->dev, skb->data, len, DMA_TO_DEVICE);
+ if (dma_mapping_error(&hw->pdev->dev, map))
goto mapping_error;
dma_unmap_addr_set(e, mapaddr, map);
@@ -2830,16 +2833,12 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
mapping_unwind:
e = skge->tx_ring.to_use;
- pci_unmap_single(hw->pdev,
- dma_unmap_addr(e, mapaddr),
- dma_unmap_len(e, maplen),
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&hw->pdev->dev, dma_unmap_addr(e, mapaddr),
+ dma_unmap_len(e, maplen), DMA_TO_DEVICE);
while (i-- > 0) {
e = e->next;
- pci_unmap_page(hw->pdev,
- dma_unmap_addr(e, mapaddr),
- dma_unmap_len(e, maplen),
- PCI_DMA_TODEVICE);
+ dma_unmap_page(&hw->pdev->dev, dma_unmap_addr(e, mapaddr),
+ dma_unmap_len(e, maplen), DMA_TO_DEVICE);
}
mapping_error:
@@ -2856,13 +2855,11 @@ static inline void skge_tx_unmap(struct pci_dev *pdev, struct skge_element *e,
{
/* skb header vs. fragment */
if (control & BMU_STF)
- pci_unmap_single(pdev, dma_unmap_addr(e, mapaddr),
- dma_unmap_len(e, maplen),
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&pdev->dev, dma_unmap_addr(e, mapaddr),
+ dma_unmap_len(e, maplen), DMA_TO_DEVICE);
else
- pci_unmap_page(pdev, dma_unmap_addr(e, mapaddr),
- dma_unmap_len(e, maplen),
- PCI_DMA_TODEVICE);
+ dma_unmap_page(&pdev->dev, dma_unmap_addr(e, mapaddr),
+ dma_unmap_len(e, maplen), DMA_TO_DEVICE);
}
/* Free all buffers in transmit ring */
@@ -3072,15 +3069,15 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
if (!skb)
goto resubmit;
- pci_dma_sync_single_for_cpu(skge->hw->pdev,
- dma_unmap_addr(e, mapaddr),
- dma_unmap_len(e, maplen),
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&skge->hw->pdev->dev,
+ dma_unmap_addr(e, mapaddr),
+ dma_unmap_len(e, maplen),
+ DMA_FROM_DEVICE);
skb_copy_from_linear_data(e->skb, skb->data, len);
- pci_dma_sync_single_for_device(skge->hw->pdev,
- dma_unmap_addr(e, mapaddr),
- dma_unmap_len(e, maplen),
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&skge->hw->pdev->dev,
+ dma_unmap_addr(e, mapaddr),
+ dma_unmap_len(e, maplen),
+ DMA_FROM_DEVICE);
skge_rx_reuse(e, skge->rx_buf_size);
} else {
struct skge_element ee;
@@ -3100,10 +3097,9 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
goto resubmit;
}
- pci_unmap_single(skge->hw->pdev,
+ dma_unmap_single(&skge->hw->pdev->dev,
dma_unmap_addr(&ee, mapaddr),
- dma_unmap_len(&ee, maplen),
- PCI_DMA_FROMDEVICE);
+ dma_unmap_len(&ee, maplen), DMA_FROM_DEVICE);
}
skb_put(skb, len);
@@ -3895,12 +3891,12 @@ static int skge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
- if (!only_32bit_dma && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ if (!only_32bit_dma && !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
- } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+ } else if (!(err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)))) {
using_dac = 0;
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
}
if (err) {
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index fe54764caea9..cec8124301c7 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -1209,8 +1209,9 @@ static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
struct sk_buff *skb = re->skb;
int i;
- re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, re->data_addr))
+ re->data_addr = dma_map_single(&pdev->dev, skb->data, size,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&pdev->dev, re->data_addr))
goto mapping_error;
dma_unmap_len_set(re, data_size, size);
@@ -1229,13 +1230,13 @@ static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
map_page_error:
while (--i >= 0) {
- pci_unmap_page(pdev, re->frag_addr[i],
+ dma_unmap_page(&pdev->dev, re->frag_addr[i],
skb_frag_size(&skb_shinfo(skb)->frags[i]),
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
}
- pci_unmap_single(pdev, re->data_addr, dma_unmap_len(re, data_size),
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&pdev->dev, re->data_addr,
+ dma_unmap_len(re, data_size), DMA_FROM_DEVICE);
mapping_error:
if (net_ratelimit())
@@ -1249,13 +1250,13 @@ static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
struct sk_buff *skb = re->skb;
int i;
- pci_unmap_single(pdev, re->data_addr, dma_unmap_len(re, data_size),
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&pdev->dev, re->data_addr,
+ dma_unmap_len(re, data_size), DMA_FROM_DEVICE);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
- pci_unmap_page(pdev, re->frag_addr[i],
+ dma_unmap_page(&pdev->dev, re->frag_addr[i],
skb_frag_size(&skb_shinfo(skb)->frags[i]),
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
}
/* Tell chip where to start receive checksum.
@@ -1592,10 +1593,9 @@ static int sky2_alloc_buffers(struct sky2_port *sky2)
struct sky2_hw *hw = sky2->hw;
/* must be power of 2 */
- sky2->tx_le = pci_alloc_consistent(hw->pdev,
- sky2->tx_ring_size *
- sizeof(struct sky2_tx_le),
- &sky2->tx_le_map);
+ sky2->tx_le = dma_alloc_coherent(&hw->pdev->dev,
+ sky2->tx_ring_size * sizeof(struct sky2_tx_le),
+ &sky2->tx_le_map, GFP_KERNEL);
if (!sky2->tx_le)
goto nomem;
@@ -1604,8 +1604,8 @@ static int sky2_alloc_buffers(struct sky2_port *sky2)
if (!sky2->tx_ring)
goto nomem;
- sky2->rx_le = pci_zalloc_consistent(hw->pdev, RX_LE_BYTES,
- &sky2->rx_le_map);
+ sky2->rx_le = dma_alloc_coherent(&hw->pdev->dev, RX_LE_BYTES,
+ &sky2->rx_le_map, GFP_KERNEL);
if (!sky2->rx_le)
goto nomem;
@@ -1626,14 +1626,14 @@ static void sky2_free_buffers(struct sky2_port *sky2)
sky2_rx_clean(sky2);
if (sky2->rx_le) {
- pci_free_consistent(hw->pdev, RX_LE_BYTES,
- sky2->rx_le, sky2->rx_le_map);
+ dma_free_coherent(&hw->pdev->dev, RX_LE_BYTES, sky2->rx_le,
+ sky2->rx_le_map);
sky2->rx_le = NULL;
}
if (sky2->tx_le) {
- pci_free_consistent(hw->pdev,
- sky2->tx_ring_size * sizeof(struct sky2_tx_le),
- sky2->tx_le, sky2->tx_le_map);
+ dma_free_coherent(&hw->pdev->dev,
+ sky2->tx_ring_size * sizeof(struct sky2_tx_le),
+ sky2->tx_le, sky2->tx_le_map);
sky2->tx_le = NULL;
}
kfree(sky2->tx_ring);
@@ -1806,13 +1806,11 @@ static unsigned tx_le_req(const struct sk_buff *skb)
static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re)
{
if (re->flags & TX_MAP_SINGLE)
- pci_unmap_single(pdev, dma_unmap_addr(re, mapaddr),
- dma_unmap_len(re, maplen),
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&pdev->dev, dma_unmap_addr(re, mapaddr),
+ dma_unmap_len(re, maplen), DMA_TO_DEVICE);
else if (re->flags & TX_MAP_PAGE)
- pci_unmap_page(pdev, dma_unmap_addr(re, mapaddr),
- dma_unmap_len(re, maplen),
- PCI_DMA_TODEVICE);
+ dma_unmap_page(&pdev->dev, dma_unmap_addr(re, mapaddr),
+ dma_unmap_len(re, maplen), DMA_TO_DEVICE);
re->flags = 0;
}
@@ -1840,9 +1838,10 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_BUSY;
len = skb_headlen(skb);
- mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+ mapping = dma_map_single(&hw->pdev->dev, skb->data, len,
+ DMA_TO_DEVICE);
- if (pci_dma_mapping_error(hw->pdev, mapping))
+ if (dma_mapping_error(&hw->pdev->dev, mapping))
goto mapping_error;
slot = sky2->tx_prod;
@@ -2464,16 +2463,17 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,
skb = netdev_alloc_skb_ip_align(sky2->netdev, length);
if (likely(skb)) {
- pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->data_addr,
- length, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&sky2->hw->pdev->dev, re->data_addr,
+ length, DMA_FROM_DEVICE);
skb_copy_from_linear_data(re->skb, skb->data, length);
skb->ip_summed = re->skb->ip_summed;
skb->csum = re->skb->csum;
skb_copy_hash(skb, re->skb);
__vlan_hwaccel_copy_tag(skb, re->skb);
- pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
- length, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&sky2->hw->pdev->dev,
+ re->data_addr, length,
+ DMA_FROM_DEVICE);
__vlan_hwaccel_clear_tag(re->skb);
skb_clear_hash(re->skb);
re->skb->ip_summed = CHECKSUM_NONE;
@@ -4985,16 +4985,16 @@ static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
if (sizeof(dma_addr_t) > sizeof(u32) &&
- !(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))) {
+ !(err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)))) {
using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (err < 0) {
dev_err(&pdev->dev, "unable to obtain 64 bit DMA "
"for consistent allocations\n");
goto err_out_free_regions;
}
} else {
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "no usable DMA configuration\n");
goto err_out_free_regions;
@@ -5038,8 +5038,9 @@ static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* ring for status responses */
hw->st_size = hw->ports * roundup_pow_of_two(3*RX_MAX_PENDING + TX_MAX_PENDING);
- hw->st_le = pci_alloc_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
- &hw->st_dma);
+ hw->st_le = dma_alloc_coherent(&pdev->dev,
+ hw->st_size * sizeof(struct sky2_status_le),
+ &hw->st_dma, GFP_KERNEL);
if (!hw->st_le) {
err = -ENOMEM;
goto err_out_reset;
@@ -5119,8 +5120,9 @@ err_out_free_netdev:
pci_disable_msi(pdev);
free_netdev(dev);
err_out_free_pci:
- pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
- hw->st_le, hw->st_dma);
+ dma_free_coherent(&pdev->dev,
+ hw->st_size * sizeof(struct sky2_status_le),
+ hw->st_le, hw->st_dma);
err_out_reset:
sky2_write8(hw, B0_CTST, CS_RST_SET);
err_out_iounmap:
@@ -5164,8 +5166,9 @@ static void sky2_remove(struct pci_dev *pdev)
if (hw->flags & SKY2_HW_USE_MSI)
pci_disable_msi(pdev);
- pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
- hw->st_le, hw->st_dma);
+ dma_free_coherent(&pdev->dev,
+ hw->st_size * sizeof(struct sky2_status_le),
+ hw->st_le, hw->st_dma);
pci_release_regions(pdev);
pci_disable_device(pdev);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index a1c45b39a230..0870fe78ea38 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -353,29 +353,9 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
/* Setup gmac */
mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
mcr_new = mcr_cur;
- mcr_new &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
- MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
- MAC_MCR_FORCE_RX_FC);
mcr_new |= MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK;
- switch (state->speed) {
- case SPEED_2500:
- case SPEED_1000:
- mcr_new |= MAC_MCR_SPEED_1000;
- break;
- case SPEED_100:
- mcr_new |= MAC_MCR_SPEED_100;
- break;
- }
- if (state->duplex == DUPLEX_FULL) {
- mcr_new |= MAC_MCR_FORCE_DPX;
- if (state->pause & MLO_PAUSE_TX)
- mcr_new |= MAC_MCR_FORCE_TX_FC;
- if (state->pause & MLO_PAUSE_RX)
- mcr_new |= MAC_MCR_FORCE_RX_FC;
- }
-
/* Only update control register when needed! */
if (mcr_new != mcr_cur)
mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
@@ -452,6 +432,31 @@ static void mtk_mac_link_up(struct phylink_config *config,
phylink_config);
u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+ mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
+ MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
+ MAC_MCR_FORCE_RX_FC);
+
+ /* Configure speed */
+ switch (speed) {
+ case SPEED_2500:
+ case SPEED_1000:
+ mcr |= MAC_MCR_SPEED_1000;
+ break;
+ case SPEED_100:
+ mcr |= MAC_MCR_SPEED_100;
+ break;
+ }
+
+ /* Configure duplex */
+ if (duplex == DUPLEX_FULL)
+ mcr |= MAC_MCR_FORCE_DPX;
+
+ /* Configure pause modes - phylink will avoid these for half duplex */
+ if (tx_pause)
+ mcr |= MAC_MCR_FORCE_TX_FC;
+ if (rx_pause)
+ mcr |= MAC_MCR_FORCE_RX_FC;
+
mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN;
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
}
diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 3e765bdcf9e1..13250553263b 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -1389,7 +1389,7 @@ static int mtk_star_mdio_init(struct net_device *ndev)
priv->mii->write = mtk_star_mdio_write;
priv->mii->priv = priv;
- ret = of_mdiobus_register(priv->mii, mdio_node);
+ ret = devm_of_mdiobus_register(dev, priv->mii, mdio_node);
out_put_node:
of_node_put(mdio_node);
@@ -1441,13 +1441,6 @@ static void mtk_star_clk_disable_unprepare(void *data)
clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
}
-static void mtk_star_mdiobus_unregister(void *data)
-{
- struct mtk_star_priv *priv = data;
-
- mdiobus_unregister(priv->mii);
-}
-
static int mtk_star_probe(struct platform_device *pdev)
{
struct device_node *of_node;
@@ -1549,10 +1542,6 @@ static int mtk_star_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = devm_add_action_or_reset(dev, mtk_star_mdiobus_unregister, priv);
- if (ret)
- return ret;
-
ret = eth_platform_get_mac_address(dev, ndev->dev_addr);
if (ret || !is_valid_ether_addr(ndev->dev_addr))
eth_hw_addr_random(ndev);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 5bd3cd37d50f..106513f772c3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1816,7 +1816,7 @@ int mlx4_en_start_port(struct net_device *dev)
queue_work(mdev->workqueue, &priv->rx_mode_task);
if (priv->mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
- udp_tunnel_get_rx_info(dev);
+ udp_tunnel_nic_reset_ntf(dev);
priv->port_up = true;
@@ -2628,89 +2628,32 @@ static int mlx4_en_get_phys_port_id(struct net_device *dev,
return 0;
}
-static void mlx4_en_add_vxlan_offloads(struct work_struct *work)
+static int mlx4_udp_tunnel_sync(struct net_device *dev, unsigned int table)
{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct udp_tunnel_info ti;
int ret;
- struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
- vxlan_add_task);
- ret = mlx4_config_vxlan_port(priv->mdev->dev, priv->vxlan_port);
- if (ret)
- goto out;
-
- ret = mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port,
- VXLAN_STEER_BY_OUTER_MAC, 1);
-out:
- if (ret) {
- en_err(priv, "failed setting L2 tunnel configuration ret %d\n", ret);
- return;
- }
-}
+ udp_tunnel_nic_get_port(dev, table, 0, &ti);
+ priv->vxlan_port = ti.port;
-static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
-{
- int ret;
- struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
- vxlan_del_task);
- ret = mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port,
- VXLAN_STEER_BY_OUTER_MAC, 0);
+ ret = mlx4_config_vxlan_port(priv->mdev->dev, priv->vxlan_port);
if (ret)
- en_err(priv, "failed setting L2 tunnel configuration ret %d\n", ret);
-
- priv->vxlan_port = 0;
-}
-
-static void mlx4_en_add_vxlan_port(struct net_device *dev,
- struct udp_tunnel_info *ti)
-{
- struct mlx4_en_priv *priv = netdev_priv(dev);
- __be16 port = ti->port;
- __be16 current_port;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- if (ti->sa_family != AF_INET)
- return;
-
- if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
- return;
-
- current_port = priv->vxlan_port;
- if (current_port && current_port != port) {
- en_warn(priv, "vxlan port %d configured, can't add port %d\n",
- ntohs(current_port), ntohs(port));
- return;
- }
+ return ret;
- priv->vxlan_port = port;
- queue_work(priv->mdev->workqueue, &priv->vxlan_add_task);
+ return mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port,
+ VXLAN_STEER_BY_OUTER_MAC,
+ !!priv->vxlan_port);
}
-static void mlx4_en_del_vxlan_port(struct net_device *dev,
- struct udp_tunnel_info *ti)
-{
- struct mlx4_en_priv *priv = netdev_priv(dev);
- __be16 port = ti->port;
- __be16 current_port;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- if (ti->sa_family != AF_INET)
- return;
-
- if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
- return;
-
- current_port = priv->vxlan_port;
- if (current_port != port) {
- en_dbg(DRV, priv, "vxlan port %d isn't configured, ignoring\n", ntohs(port));
- return;
- }
-
- queue_work(priv->mdev->workqueue, &priv->vxlan_del_task);
-}
+static const struct udp_tunnel_nic_info mlx4_udp_tunnels = {
+ .sync_table = mlx4_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
+ UDP_TUNNEL_NIC_INFO_IPV4_ONLY,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
struct net_device *dev,
@@ -2859,35 +2802,11 @@ unlock_out:
return err;
}
-static u32 mlx4_xdp_query(struct net_device *dev)
-{
- struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
- const struct bpf_prog *xdp_prog;
- u32 prog_id = 0;
-
- if (!priv->tx_ring_num[TX_XDP])
- return prog_id;
-
- mutex_lock(&mdev->state_lock);
- xdp_prog = rcu_dereference_protected(
- priv->rx_ring[0]->xdp_prog,
- lockdep_is_held(&mdev->state_lock));
- if (xdp_prog)
- prog_id = xdp_prog->aux->id;
- mutex_unlock(&mdev->state_lock);
-
- return prog_id;
-}
-
static int mlx4_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
switch (xdp->command) {
case XDP_SETUP_PROG:
return mlx4_xdp_set(dev, xdp->prog);
- case XDP_QUERY_PROG:
- xdp->prog_id = mlx4_xdp_query(dev);
- return 0;
default:
return -EINVAL;
}
@@ -2914,8 +2833,8 @@ static const struct net_device_ops mlx4_netdev_ops = {
.ndo_rx_flow_steer = mlx4_en_filter_rfs,
#endif
.ndo_get_phys_port_id = mlx4_en_get_phys_port_id,
- .ndo_udp_tunnel_add = mlx4_en_add_vxlan_port,
- .ndo_udp_tunnel_del = mlx4_en_del_vxlan_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = mlx4_en_features_check,
.ndo_set_tx_maxrate = mlx4_en_set_tx_maxrate,
.ndo_bpf = mlx4_xdp,
@@ -2948,8 +2867,8 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
.ndo_rx_flow_steer = mlx4_en_filter_rfs,
#endif
.ndo_get_phys_port_id = mlx4_en_get_phys_port_id,
- .ndo_udp_tunnel_add = mlx4_en_add_vxlan_port,
- .ndo_udp_tunnel_del = mlx4_en_del_vxlan_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = mlx4_en_features_check,
.ndo_set_tx_maxrate = mlx4_en_set_tx_maxrate,
.ndo_bpf = mlx4_xdp,
@@ -3250,8 +3169,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task);
- INIT_WORK(&priv->vxlan_add_task, mlx4_en_add_vxlan_offloads);
- INIT_WORK(&priv->vxlan_del_task, mlx4_en_del_vxlan_offloads);
#ifdef CONFIG_RFS_ACCEL
INIT_LIST_HEAD(&priv->filters);
spin_lock_init(&priv->filters_lock);
@@ -3406,6 +3323,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL;
+
+ dev->udp_tunnel_nic_info = &mlx4_udp_tunnels;
}
dev->vlan_features = dev->hw_features;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index 8a10285b0e10..b50c567ef508 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -806,10 +806,10 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
goto xdp_drop_no_cnt; /* Drop on xmit failure */
default:
bpf_warn_invalid_xdp_action(act);
- /* fall through */
+ fallthrough;
case XDP_ABORTED:
trace_xdp_exception(dev, xdp_prog, act);
- /* fall through */
+ fallthrough;
case XDP_DROP:
ring->xdp_drop++;
xdp_drop_no_cnt:
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index c790a5fcea73..ae305c2e9225 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -558,7 +558,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
mlx4_dbg(dev, "%s: MLX4_EVENT_TYPE_SRQ_LIMIT. srq_no=0x%x, eq 0x%x\n",
__func__, be32_to_cpu(eqe->event.srq.srqn),
eq->eqn);
- /* fall through */
+ fallthrough;
case MLX4_EVENT_TYPE_SRQ_CATAS_ERROR:
if (mlx4_is_master(dev)) {
/* forward only to slave owning the SRQ */
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 2d3e45780719..258c7a96f269 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -4372,8 +4372,9 @@ static const struct pci_error_handlers mlx4_err_handler = {
.resume = mlx4_pci_resume,
};
-static int mlx4_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused mlx4_suspend(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
struct mlx4_dev *dev = persist->dev;
@@ -4386,8 +4387,9 @@ static int mlx4_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-static int mlx4_resume(struct pci_dev *pdev)
+static int __maybe_unused mlx4_resume(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
struct mlx4_dev *dev = persist->dev;
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -4416,14 +4418,15 @@ static int mlx4_resume(struct pci_dev *pdev)
return ret;
}
+static SIMPLE_DEV_PM_OPS(mlx4_pm_ops, mlx4_suspend, mlx4_resume);
+
static struct pci_driver mlx4_driver = {
.name = DRV_NAME,
.id_table = mlx4_pci_table,
.probe = mlx4_init_one,
.shutdown = mlx4_shutdown,
.remove = mlx4_remove_one,
- .suspend = mlx4_suspend,
- .resume = mlx4_resume,
+ .driver.pm = &mlx4_pm_ops,
.err_handler = &mlx4_err_handler,
};
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 9486caecfbdc..f1b4ad9c66d2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -1412,7 +1412,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
case MLX4_STEERING_MODE_A0:
if (prot == MLX4_PROT_ETH)
return 0;
- /* fall through */
+ fallthrough;
case MLX4_STEERING_MODE_B0:
if (prot == MLX4_PROT_ETH)
@@ -1442,7 +1442,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
case MLX4_STEERING_MODE_A0:
if (prot == MLX4_PROT_ETH)
return 0;
- /* fall through */
+ fallthrough;
case MLX4_STEERING_MODE_B0:
if (prot == MLX4_PROT_ETH)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 9f5603612960..a46efe37cfa9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -599,8 +599,6 @@ struct mlx4_en_priv {
struct work_struct linkstate_task;
struct delayed_work stats_task;
struct delayed_work service_task;
- struct work_struct vxlan_add_task;
- struct work_struct vxlan_del_task;
struct mlx4_en_perf_stats pstats;
struct mlx4_en_pkt_stats pkstats;
struct mlx4_en_counter_stats pf_stats;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
index 4dfdbb82ea9d..99f1ec3b2575 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
@@ -134,12 +134,25 @@ config MLX5_FPGA_IPSEC
mlx5_core driver will include the Innova FPGA core and allow building
sandbox-specific client drivers.
+config MLX5_IPSEC
+ bool "Mellanox Technologies IPsec Connect-X support"
+ depends on MLX5_CORE_EN
+ depends on XFRM_OFFLOAD
+ depends on INET_ESP_OFFLOAD || INET6_ESP_OFFLOAD
+ select MLX5_ACCEL
+ default n
+ help
+ Build IPsec support for the Connect-X family of network cards by Mellanox
+ Technologies.
+ Note: If you select this option, the mlx5_core driver will include
+ IPsec support for the Connect-X family.
+
config MLX5_EN_IPSEC
bool "IPSec XFRM cryptography-offload accelaration"
depends on MLX5_CORE_EN
depends on XFRM_OFFLOAD
depends on INET_ESP_OFFLOAD || INET6_ESP_OFFLOAD
- depends on MLX5_FPGA_IPSEC
+ depends on MLX5_FPGA_IPSEC || MLX5_IPSEC
default n
help
Build support for IPsec cryptography-offload accelaration in the NIC.
@@ -150,7 +163,10 @@ config MLX5_FPGA_TLS
bool "Mellanox Technologies TLS Innova support"
depends on TLS_DEVICE
depends on TLS=y || MLX5_CORE=m
+ depends on MLX5_CORE_EN
depends on MLX5_FPGA
+ depends on XPS
+ select MLX5_EN_TLS
default n
help
Build TLS support for the Innova family of network cards by Mellanox
@@ -161,20 +177,19 @@ config MLX5_FPGA_TLS
config MLX5_TLS
bool "Mellanox Technologies TLS Connect-X support"
- depends on MLX5_CORE_EN
depends on TLS_DEVICE
depends on TLS=y || MLX5_CORE=m
+ depends on MLX5_CORE_EN
+ depends on XPS
select MLX5_ACCEL
+ select MLX5_EN_TLS
default n
help
Build TLS support for the Connect-X family of network cards by Mellanox
Technologies.
config MLX5_EN_TLS
- bool "TLS cryptography-offload accelaration"
- depends on MLX5_CORE_EN
- depends on MLX5_FPGA_TLS || MLX5_TLS
- default y
+ bool
help
Build support for TLS cryptography-offload accelaration in the NIC.
Note: Support for hardware with this capability needs to be selected
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index b61e47bc16e8..10e6886c96ba 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -35,7 +35,7 @@ mlx5_core-$(CONFIG_MLX5_EN_RXNFC) += en_fs_ethtool.o
mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) += en_dcbnl.o en/port_buffer.o
mlx5_core-$(CONFIG_PCI_HYPERV_INTERFACE) += en/hv_vhca_stats.o
mlx5_core-$(CONFIG_MLX5_ESWITCH) += lag_mp.o lib/geneve.o lib/port_tun.o \
- en_rep.o en/rep/bond.o
+ en_rep.o en/rep/bond.o en/mod_hdr.o
mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en_tc.o en/rep/tc.o en/rep/neigh.o \
en/mapping.o esw/chains.o en/tc_tun.o \
en/tc_tun_vxlan.o en/tc_tun_gre.o en/tc_tun_geneve.o \
@@ -64,6 +64,7 @@ mlx5_core-$(CONFIG_MLX5_CORE_IPOIB) += ipoib/ipoib.o ipoib/ethtool.o ipoib/ipoib
#
# Accelerations & FPGA
#
+mlx5_core-$(CONFIG_MLX5_IPSEC) += accel/ipsec_offload.o
mlx5_core-$(CONFIG_MLX5_FPGA_IPSEC) += fpga/ipsec.o
mlx5_core-$(CONFIG_MLX5_FPGA_TLS) += fpga/tls.o
mlx5_core-$(CONFIG_MLX5_ACCEL) += lib/crypto.o accel/tls.o accel/ipsec.o
@@ -71,10 +72,11 @@ mlx5_core-$(CONFIG_MLX5_ACCEL) += lib/crypto.o accel/tls.o accel/ipsec.o
mlx5_core-$(CONFIG_MLX5_FPGA) += fpga/cmd.o fpga/core.o fpga/conn.o fpga/sdk.o
mlx5_core-$(CONFIG_MLX5_EN_IPSEC) += en_accel/ipsec.o en_accel/ipsec_rxtx.o \
- en_accel/ipsec_stats.o
+ en_accel/ipsec_stats.o en_accel/ipsec_fs.o
mlx5_core-$(CONFIG_MLX5_EN_TLS) += en_accel/tls.o en_accel/tls_rxtx.o en_accel/tls_stats.o \
- en_accel/ktls.o en_accel/ktls_tx.o
+ en_accel/fs_tcp.o en_accel/ktls.o en_accel/ktls_txrx.o \
+ en_accel/ktls_tx.o en_accel/ktls_rx.o
mlx5_core-$(CONFIG_MLX5_SW_STEERING) += steering/dr_domain.o steering/dr_table.o \
steering/dr_matcher.o steering/dr_rule.o \
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
index 8a4985d8cbfe..09f5ce97af46 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
@@ -31,37 +31,88 @@
*
*/
-#ifdef CONFIG_MLX5_FPGA_IPSEC
-
#include <linux/mlx5/device.h>
#include "accel/ipsec.h"
#include "mlx5_core.h"
#include "fpga/ipsec.h"
+#include "accel/ipsec_offload.h"
+
+void mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev)
+{
+ const struct mlx5_accel_ipsec_ops *ipsec_ops;
+ int err = 0;
+
+ ipsec_ops = (mlx5_ipsec_offload_ops(mdev)) ?
+ mlx5_ipsec_offload_ops(mdev) :
+ mlx5_fpga_ipsec_ops(mdev);
+
+ if (!ipsec_ops || !ipsec_ops->init) {
+ mlx5_core_dbg(mdev, "IPsec ops is not supported\n");
+ return;
+ }
+
+ err = ipsec_ops->init(mdev);
+ if (err) {
+ mlx5_core_warn_once(mdev, "Failed to start IPsec device, err = %d\n", err);
+ return;
+ }
+
+ mdev->ipsec_ops = ipsec_ops;
+}
+
+void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev)
+{
+ const struct mlx5_accel_ipsec_ops *ipsec_ops = mdev->ipsec_ops;
+
+ if (!ipsec_ops || !ipsec_ops->cleanup)
+ return;
+
+ ipsec_ops->cleanup(mdev);
+}
u32 mlx5_accel_ipsec_device_caps(struct mlx5_core_dev *mdev)
{
- return mlx5_fpga_ipsec_device_caps(mdev);
+ const struct mlx5_accel_ipsec_ops *ipsec_ops = mdev->ipsec_ops;
+
+ if (!ipsec_ops || !ipsec_ops->device_caps)
+ return 0;
+
+ return ipsec_ops->device_caps(mdev);
}
EXPORT_SYMBOL_GPL(mlx5_accel_ipsec_device_caps);
unsigned int mlx5_accel_ipsec_counters_count(struct mlx5_core_dev *mdev)
{
- return mlx5_fpga_ipsec_counters_count(mdev);
+ const struct mlx5_accel_ipsec_ops *ipsec_ops = mdev->ipsec_ops;
+
+ if (!ipsec_ops || !ipsec_ops->counters_count)
+ return -EOPNOTSUPP;
+
+ return ipsec_ops->counters_count(mdev);
}
int mlx5_accel_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,
unsigned int count)
{
- return mlx5_fpga_ipsec_counters_read(mdev, counters, count);
+ const struct mlx5_accel_ipsec_ops *ipsec_ops = mdev->ipsec_ops;
+
+ if (!ipsec_ops || !ipsec_ops->counters_read)
+ return -EOPNOTSUPP;
+
+ return ipsec_ops->counters_read(mdev, counters, count);
}
void *mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
struct mlx5_accel_esp_xfrm *xfrm,
u32 *sa_handle)
{
+ const struct mlx5_accel_ipsec_ops *ipsec_ops = mdev->ipsec_ops;
__be32 saddr[4] = {}, daddr[4] = {};
+ if (!ipsec_ops || !ipsec_ops->create_hw_context)
+ return ERR_PTR(-EOPNOTSUPP);
+
if (!xfrm->attrs.is_ipv6) {
saddr[3] = xfrm->attrs.saddr.a4;
daddr[3] = xfrm->attrs.daddr.a4;
@@ -70,29 +121,18 @@ void *mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
memcpy(daddr, xfrm->attrs.daddr.a6, sizeof(daddr));
}
- return mlx5_fpga_ipsec_create_sa_ctx(mdev, xfrm, saddr,
- daddr, xfrm->attrs.spi,
- xfrm->attrs.is_ipv6, sa_handle);
+ return ipsec_ops->create_hw_context(mdev, xfrm, saddr, daddr, xfrm->attrs.spi,
+ xfrm->attrs.is_ipv6, sa_handle);
}
-void mlx5_accel_esp_free_hw_context(void *context)
+void mlx5_accel_esp_free_hw_context(struct mlx5_core_dev *mdev, void *context)
{
- mlx5_fpga_ipsec_delete_sa_ctx(context);
-}
+ const struct mlx5_accel_ipsec_ops *ipsec_ops = mdev->ipsec_ops;
-int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev)
-{
- return mlx5_fpga_ipsec_init(mdev);
-}
-
-void mlx5_accel_ipsec_build_fs_cmds(void)
-{
- mlx5_fpga_ipsec_build_fs_cmds();
-}
+ if (!ipsec_ops || !ipsec_ops->free_hw_context)
+ return;
-void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev)
-{
- mlx5_fpga_ipsec_cleanup(mdev);
+ ipsec_ops->free_hw_context(context);
}
struct mlx5_accel_esp_xfrm *
@@ -100,9 +140,13 @@ mlx5_accel_esp_create_xfrm(struct mlx5_core_dev *mdev,
const struct mlx5_accel_esp_xfrm_attrs *attrs,
u32 flags)
{
+ const struct mlx5_accel_ipsec_ops *ipsec_ops = mdev->ipsec_ops;
struct mlx5_accel_esp_xfrm *xfrm;
- xfrm = mlx5_fpga_esp_create_xfrm(mdev, attrs, flags);
+ if (!ipsec_ops || !ipsec_ops->esp_create_xfrm)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ xfrm = ipsec_ops->esp_create_xfrm(mdev, attrs, flags);
if (IS_ERR(xfrm))
return xfrm;
@@ -113,15 +157,23 @@ EXPORT_SYMBOL_GPL(mlx5_accel_esp_create_xfrm);
void mlx5_accel_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm)
{
- mlx5_fpga_esp_destroy_xfrm(xfrm);
+ const struct mlx5_accel_ipsec_ops *ipsec_ops = xfrm->mdev->ipsec_ops;
+
+ if (!ipsec_ops || !ipsec_ops->esp_destroy_xfrm)
+ return;
+
+ ipsec_ops->esp_destroy_xfrm(xfrm);
}
EXPORT_SYMBOL_GPL(mlx5_accel_esp_destroy_xfrm);
int mlx5_accel_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
const struct mlx5_accel_esp_xfrm_attrs *attrs)
{
- return mlx5_fpga_esp_modify_xfrm(xfrm, attrs);
+ const struct mlx5_accel_ipsec_ops *ipsec_ops = xfrm->mdev->ipsec_ops;
+
+ if (!ipsec_ops || !ipsec_ops->esp_modify_xfrm)
+ return -EOPNOTSUPP;
+
+ return ipsec_ops->esp_modify_xfrm(xfrm, attrs);
}
EXPORT_SYMBOL_GPL(mlx5_accel_esp_modify_xfrm);
-
-#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
index e89747674712..fbb9c5415d53 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
@@ -37,7 +37,7 @@
#include <linux/mlx5/driver.h>
#include <linux/mlx5/accel.h>
-#ifdef CONFIG_MLX5_FPGA_IPSEC
+#ifdef CONFIG_MLX5_ACCEL
#define MLX5_IPSEC_DEV(mdev) (mlx5_accel_ipsec_device_caps(mdev) & \
MLX5_ACCEL_IPSEC_CAP_DEVICE)
@@ -49,12 +49,30 @@ int mlx5_accel_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,
void *mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
struct mlx5_accel_esp_xfrm *xfrm,
u32 *sa_handle);
-void mlx5_accel_esp_free_hw_context(void *context);
+void mlx5_accel_esp_free_hw_context(struct mlx5_core_dev *mdev, void *context);
-int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev);
-void mlx5_accel_ipsec_build_fs_cmds(void);
+void mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev);
void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev);
+struct mlx5_accel_ipsec_ops {
+ u32 (*device_caps)(struct mlx5_core_dev *mdev);
+ unsigned int (*counters_count)(struct mlx5_core_dev *mdev);
+ int (*counters_read)(struct mlx5_core_dev *mdev, u64 *counters, unsigned int count);
+ void* (*create_hw_context)(struct mlx5_core_dev *mdev,
+ struct mlx5_accel_esp_xfrm *xfrm,
+ const __be32 saddr[4], const __be32 daddr[4],
+ const __be32 spi, bool is_ipv6, u32 *sa_handle);
+ void (*free_hw_context)(void *context);
+ int (*init)(struct mlx5_core_dev *mdev);
+ void (*cleanup)(struct mlx5_core_dev *mdev);
+ struct mlx5_accel_esp_xfrm* (*esp_create_xfrm)(struct mlx5_core_dev *mdev,
+ const struct mlx5_accel_esp_xfrm_attrs *attrs,
+ u32 flags);
+ int (*esp_modify_xfrm)(struct mlx5_accel_esp_xfrm *xfrm,
+ const struct mlx5_accel_esp_xfrm_attrs *attrs);
+ void (*esp_destroy_xfrm)(struct mlx5_accel_esp_xfrm *xfrm);
+};
+
#else
#define MLX5_IPSEC_DEV(mdev) false
@@ -67,23 +85,12 @@ mlx5_accel_esp_create_hw_context(struct mlx5_core_dev *mdev,
return NULL;
}
-static inline void mlx5_accel_esp_free_hw_context(void *context)
-{
-}
-
-static inline int mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev)
-{
- return 0;
-}
+static inline void mlx5_accel_esp_free_hw_context(struct mlx5_core_dev *mdev, void *context) {}
-static inline void mlx5_accel_ipsec_build_fs_cmds(void)
-{
-}
+static inline void mlx5_accel_ipsec_init(struct mlx5_core_dev *mdev) {}
-static inline void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev)
-{
-}
+static inline void mlx5_accel_ipsec_cleanup(struct mlx5_core_dev *mdev) {}
-#endif
+#endif /* CONFIG_MLX5_ACCEL */
#endif /* __MLX5_ACCEL_IPSEC_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec_offload.c b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec_offload.c
new file mode 100644
index 000000000000..2f13a250aab3
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec_offload.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIBt
+/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
+
+#include "mlx5_core.h"
+#include "ipsec_offload.h"
+#include "lib/mlx5.h"
+#include "en_accel/ipsec_fs.h"
+
+#define MLX5_IPSEC_DEV_BASIC_CAPS (MLX5_ACCEL_IPSEC_CAP_DEVICE | MLX5_ACCEL_IPSEC_CAP_IPV6 | \
+ MLX5_ACCEL_IPSEC_CAP_LSO)
+
+struct mlx5_ipsec_sa_ctx {
+ struct rhash_head hash;
+ u32 enc_key_id;
+ u32 ipsec_obj_id;
+ /* hw ctx */
+ struct mlx5_core_dev *dev;
+ struct mlx5_ipsec_esp_xfrm *mxfrm;
+};
+
+struct mlx5_ipsec_esp_xfrm {
+ /* reference counter of SA ctx */
+ struct mlx5_ipsec_sa_ctx *sa_ctx;
+ struct mutex lock; /* protects mlx5_ipsec_esp_xfrm */
+ struct mlx5_accel_esp_xfrm accel_xfrm;
+};
+
+static u32 mlx5_ipsec_offload_device_caps(struct mlx5_core_dev *mdev)
+{
+ u32 caps = MLX5_IPSEC_DEV_BASIC_CAPS;
+
+ if (!mlx5_is_ipsec_device(mdev))
+ return 0;
+
+ if (!MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ipsec_encrypt) ||
+ !MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ipsec_decrypt))
+ return 0;
+
+ if (MLX5_CAP_IPSEC(mdev, ipsec_crypto_esp_aes_gcm_128_encrypt) &&
+ MLX5_CAP_IPSEC(mdev, ipsec_crypto_esp_aes_gcm_128_decrypt))
+ caps |= MLX5_ACCEL_IPSEC_CAP_ESP;
+
+ if (MLX5_CAP_IPSEC(mdev, ipsec_esn)) {
+ caps |= MLX5_ACCEL_IPSEC_CAP_ESN;
+ caps |= MLX5_ACCEL_IPSEC_CAP_TX_IV_IS_ESN;
+ }
+
+ /* We can accommodate up to 2^24 different IPsec objects
+ * because we use up to 24 bit in flow table metadata
+ * to hold the IPsec Object unique handle.
+ */
+ WARN_ON_ONCE(MLX5_CAP_IPSEC(mdev, log_max_ipsec_offload) > 24);
+ return caps;
+}
+
+static int
+mlx5_ipsec_offload_esp_validate_xfrm_attrs(struct mlx5_core_dev *mdev,
+ const struct mlx5_accel_esp_xfrm_attrs *attrs)
+{
+ if (attrs->replay_type != MLX5_ACCEL_ESP_REPLAY_NONE) {
+ mlx5_core_err(mdev, "Cannot offload xfrm states with anti replay (replay_type = %d)\n",
+ attrs->replay_type);
+ return -EOPNOTSUPP;
+ }
+
+ if (attrs->keymat_type != MLX5_ACCEL_ESP_KEYMAT_AES_GCM) {
+ mlx5_core_err(mdev, "Only aes gcm keymat is supported (keymat_type = %d)\n",
+ attrs->keymat_type);
+ return -EOPNOTSUPP;
+ }
+
+ if (attrs->keymat.aes_gcm.iv_algo !=
+ MLX5_ACCEL_ESP_AES_GCM_IV_ALGO_SEQ) {
+ mlx5_core_err(mdev, "Only iv sequence algo is supported (iv_algo = %d)\n",
+ attrs->keymat.aes_gcm.iv_algo);
+ return -EOPNOTSUPP;
+ }
+
+ if (attrs->keymat.aes_gcm.key_len != 128 &&
+ attrs->keymat.aes_gcm.key_len != 256) {
+ mlx5_core_err(mdev, "Cannot offload xfrm states with key length other than 128/256 bit (key length = %d)\n",
+ attrs->keymat.aes_gcm.key_len);
+ return -EOPNOTSUPP;
+ }
+
+ if ((attrs->flags & MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED) &&
+ !MLX5_CAP_IPSEC(mdev, ipsec_esn)) {
+ mlx5_core_err(mdev, "Cannot offload xfrm states with ESN triggered\n");
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static struct mlx5_accel_esp_xfrm *
+mlx5_ipsec_offload_esp_create_xfrm(struct mlx5_core_dev *mdev,
+ const struct mlx5_accel_esp_xfrm_attrs *attrs,
+ u32 flags)
+{
+ struct mlx5_ipsec_esp_xfrm *mxfrm;
+ int err = 0;
+
+ err = mlx5_ipsec_offload_esp_validate_xfrm_attrs(mdev, attrs);
+ if (err)
+ return ERR_PTR(err);
+
+ mxfrm = kzalloc(sizeof(*mxfrm), GFP_KERNEL);
+ if (!mxfrm)
+ return ERR_PTR(-ENOMEM);
+
+ mutex_init(&mxfrm->lock);
+ memcpy(&mxfrm->accel_xfrm.attrs, attrs,
+ sizeof(mxfrm->accel_xfrm.attrs));
+
+ return &mxfrm->accel_xfrm;
+}
+
+static void mlx5_ipsec_offload_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm)
+{
+ struct mlx5_ipsec_esp_xfrm *mxfrm = container_of(xfrm, struct mlx5_ipsec_esp_xfrm,
+ accel_xfrm);
+
+ /* assuming no sa_ctx are connected to this xfrm_ctx */
+ WARN_ON(mxfrm->sa_ctx);
+ kfree(mxfrm);
+}
+
+struct mlx5_ipsec_obj_attrs {
+ const struct aes_gcm_keymat *aes_gcm;
+ u32 accel_flags;
+ u32 esn_msb;
+ u32 enc_key_id;
+};
+
+static int mlx5_create_ipsec_obj(struct mlx5_core_dev *mdev,
+ struct mlx5_ipsec_obj_attrs *attrs,
+ u32 *ipsec_id)
+{
+ const struct aes_gcm_keymat *aes_gcm = attrs->aes_gcm;
+ u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
+ u32 in[MLX5_ST_SZ_DW(create_ipsec_obj_in)] = {};
+ void *obj, *salt_p, *salt_iv_p;
+ int err;
+
+ obj = MLX5_ADDR_OF(create_ipsec_obj_in, in, ipsec_object);
+
+ /* salt and seq_iv */
+ salt_p = MLX5_ADDR_OF(ipsec_obj, obj, salt);
+ memcpy(salt_p, &aes_gcm->salt, sizeof(aes_gcm->salt));
+
+ switch (aes_gcm->icv_len) {
+ case 64:
+ MLX5_SET(ipsec_obj, obj, icv_length,
+ MLX5_IPSEC_OBJECT_ICV_LEN_8B);
+ break;
+ case 96:
+ MLX5_SET(ipsec_obj, obj, icv_length,
+ MLX5_IPSEC_OBJECT_ICV_LEN_12B);
+ break;
+ case 128:
+ MLX5_SET(ipsec_obj, obj, icv_length,
+ MLX5_IPSEC_OBJECT_ICV_LEN_16B);
+ break;
+ default:
+ return -EINVAL;
+ }
+ salt_iv_p = MLX5_ADDR_OF(ipsec_obj, obj, implicit_iv);
+ memcpy(salt_iv_p, &aes_gcm->seq_iv, sizeof(aes_gcm->seq_iv));
+ /* esn */
+ if (attrs->accel_flags & MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED) {
+ MLX5_SET(ipsec_obj, obj, esn_en, 1);
+ MLX5_SET(ipsec_obj, obj, esn_msb, attrs->esn_msb);
+ if (attrs->accel_flags & MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP)
+ MLX5_SET(ipsec_obj, obj, esn_overlap, 1);
+ }
+
+ MLX5_SET(ipsec_obj, obj, dekn, attrs->enc_key_id);
+
+ /* general object fields set */
+ MLX5_SET(general_obj_in_cmd_hdr, in, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, in, obj_type,
+ MLX5_GENERAL_OBJECT_TYPES_IPSEC);
+
+ err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
+ if (!err)
+ *ipsec_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
+
+ return err;
+}
+
+static void mlx5_destroy_ipsec_obj(struct mlx5_core_dev *mdev, u32 ipsec_id)
+{
+ u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
+ u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
+
+ MLX5_SET(general_obj_in_cmd_hdr, in, opcode,
+ MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, in, obj_type,
+ MLX5_GENERAL_OBJECT_TYPES_IPSEC);
+ MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, ipsec_id);
+
+ mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
+}
+
+static void *mlx5_ipsec_offload_create_sa_ctx(struct mlx5_core_dev *mdev,
+ struct mlx5_accel_esp_xfrm *accel_xfrm,
+ const __be32 saddr[4], const __be32 daddr[4],
+ const __be32 spi, bool is_ipv6, u32 *hw_handle)
+{
+ struct mlx5_accel_esp_xfrm_attrs *xfrm_attrs = &accel_xfrm->attrs;
+ struct aes_gcm_keymat *aes_gcm = &xfrm_attrs->keymat.aes_gcm;
+ struct mlx5_ipsec_obj_attrs ipsec_attrs = {};
+ struct mlx5_ipsec_esp_xfrm *mxfrm;
+ struct mlx5_ipsec_sa_ctx *sa_ctx;
+ int err;
+
+ /* alloc SA context */
+ sa_ctx = kzalloc(sizeof(*sa_ctx), GFP_KERNEL);
+ if (!sa_ctx)
+ return ERR_PTR(-ENOMEM);
+
+ sa_ctx->dev = mdev;
+
+ mxfrm = container_of(accel_xfrm, struct mlx5_ipsec_esp_xfrm, accel_xfrm);
+ mutex_lock(&mxfrm->lock);
+ sa_ctx->mxfrm = mxfrm;
+
+ /* key */
+ err = mlx5_create_encryption_key(mdev, aes_gcm->aes_key,
+ aes_gcm->key_len / BITS_PER_BYTE,
+ MLX5_ACCEL_OBJ_IPSEC_KEY,
+ &sa_ctx->enc_key_id);
+ if (err) {
+ mlx5_core_dbg(mdev, "Failed to create encryption key (err = %d)\n", err);
+ goto err_sa_ctx;
+ }
+
+ ipsec_attrs.aes_gcm = aes_gcm;
+ ipsec_attrs.accel_flags = accel_xfrm->attrs.flags;
+ ipsec_attrs.esn_msb = accel_xfrm->attrs.esn;
+ ipsec_attrs.enc_key_id = sa_ctx->enc_key_id;
+ err = mlx5_create_ipsec_obj(mdev, &ipsec_attrs,
+ &sa_ctx->ipsec_obj_id);
+ if (err) {
+ mlx5_core_dbg(mdev, "Failed to create IPsec object (err = %d)\n", err);
+ goto err_enc_key;
+ }
+
+ *hw_handle = sa_ctx->ipsec_obj_id;
+ mxfrm->sa_ctx = sa_ctx;
+ mutex_unlock(&mxfrm->lock);
+
+ return sa_ctx;
+
+err_enc_key:
+ mlx5_destroy_encryption_key(mdev, sa_ctx->enc_key_id);
+err_sa_ctx:
+ mutex_unlock(&mxfrm->lock);
+ kfree(sa_ctx);
+ return ERR_PTR(err);
+}
+
+static void mlx5_ipsec_offload_delete_sa_ctx(void *context)
+{
+ struct mlx5_ipsec_sa_ctx *sa_ctx = (struct mlx5_ipsec_sa_ctx *)context;
+ struct mlx5_ipsec_esp_xfrm *mxfrm = sa_ctx->mxfrm;
+
+ mutex_lock(&mxfrm->lock);
+ mlx5_destroy_ipsec_obj(sa_ctx->dev, sa_ctx->ipsec_obj_id);
+ mlx5_destroy_encryption_key(sa_ctx->dev, sa_ctx->enc_key_id);
+ kfree(sa_ctx);
+ mxfrm->sa_ctx = NULL;
+ mutex_unlock(&mxfrm->lock);
+}
+
+static int mlx5_ipsec_offload_init(struct mlx5_core_dev *mdev)
+{
+ return 0;
+}
+
+static int mlx5_modify_ipsec_obj(struct mlx5_core_dev *mdev,
+ struct mlx5_ipsec_obj_attrs *attrs,
+ u32 ipsec_id)
+{
+ u32 in[MLX5_ST_SZ_DW(modify_ipsec_obj_in)] = {};
+ u32 out[MLX5_ST_SZ_DW(query_ipsec_obj_out)];
+ u64 modify_field_select = 0;
+ u64 general_obj_types;
+ void *obj;
+ int err;
+
+ if (!(attrs->accel_flags & MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED))
+ return 0;
+
+ general_obj_types = MLX5_CAP_GEN_64(mdev, general_obj_types);
+ if (!(general_obj_types & MLX5_HCA_CAP_GENERAL_OBJECT_TYPES_IPSEC))
+ return -EINVAL;
+
+ /* general object fields set */
+ MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, MLX5_GENERAL_OBJECT_TYPES_IPSEC);
+ MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, ipsec_id);
+ err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
+ if (err) {
+ mlx5_core_err(mdev, "Query IPsec object failed (Object id %d), err = %d\n",
+ ipsec_id, err);
+ return err;
+ }
+
+ obj = MLX5_ADDR_OF(query_ipsec_obj_out, out, ipsec_object);
+ modify_field_select = MLX5_GET64(ipsec_obj, obj, modify_field_select);
+
+ /* esn */
+ if (!(modify_field_select & MLX5_MODIFY_IPSEC_BITMASK_ESN_OVERLAP) ||
+ !(modify_field_select & MLX5_MODIFY_IPSEC_BITMASK_ESN_MSB))
+ return -EOPNOTSUPP;
+
+ obj = MLX5_ADDR_OF(modify_ipsec_obj_in, in, ipsec_object);
+ MLX5_SET(ipsec_obj, obj, esn_msb, attrs->esn_msb);
+ if (attrs->accel_flags & MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP)
+ MLX5_SET(ipsec_obj, obj, esn_overlap, 1);
+
+ /* general object fields set */
+ MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT);
+
+ return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
+}
+
+static int mlx5_ipsec_offload_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
+ const struct mlx5_accel_esp_xfrm_attrs *attrs)
+{
+ struct mlx5_ipsec_obj_attrs ipsec_attrs = {};
+ struct mlx5_core_dev *mdev = xfrm->mdev;
+ struct mlx5_ipsec_esp_xfrm *mxfrm;
+
+ int err = 0;
+
+ if (!memcmp(&xfrm->attrs, attrs, sizeof(xfrm->attrs)))
+ return 0;
+
+ if (mlx5_ipsec_offload_esp_validate_xfrm_attrs(mdev, attrs))
+ return -EOPNOTSUPP;
+
+ mxfrm = container_of(xfrm, struct mlx5_ipsec_esp_xfrm, accel_xfrm);
+
+ mutex_lock(&mxfrm->lock);
+
+ if (!mxfrm->sa_ctx)
+ /* Not bound xfrm, change only sw attrs */
+ goto change_sw_xfrm_attrs;
+
+ /* need to add find and replace in ipsec_rhash_sa the sa_ctx */
+ /* modify device with new hw_sa */
+ ipsec_attrs.accel_flags = attrs->flags;
+ ipsec_attrs.esn_msb = attrs->esn;
+ err = mlx5_modify_ipsec_obj(mdev,
+ &ipsec_attrs,
+ mxfrm->sa_ctx->ipsec_obj_id);
+
+change_sw_xfrm_attrs:
+ if (!err)
+ memcpy(&xfrm->attrs, attrs, sizeof(xfrm->attrs));
+
+ mutex_unlock(&mxfrm->lock);
+ return err;
+}
+
+static const struct mlx5_accel_ipsec_ops ipsec_offload_ops = {
+ .device_caps = mlx5_ipsec_offload_device_caps,
+ .create_hw_context = mlx5_ipsec_offload_create_sa_ctx,
+ .free_hw_context = mlx5_ipsec_offload_delete_sa_ctx,
+ .init = mlx5_ipsec_offload_init,
+ .esp_create_xfrm = mlx5_ipsec_offload_esp_create_xfrm,
+ .esp_destroy_xfrm = mlx5_ipsec_offload_esp_destroy_xfrm,
+ .esp_modify_xfrm = mlx5_ipsec_offload_esp_modify_xfrm,
+};
+
+const struct mlx5_accel_ipsec_ops *mlx5_ipsec_offload_ops(struct mlx5_core_dev *mdev)
+{
+ if (!mlx5_ipsec_offload_device_caps(mdev))
+ return NULL;
+
+ return &ipsec_offload_ops;
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec_offload.h b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec_offload.h
new file mode 100644
index 000000000000..970c66d19c1d
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec_offload.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
+
+#ifndef __MLX5_IPSEC_OFFLOAD_H__
+#define __MLX5_IPSEC_OFFLOAD_H__
+
+#include <linux/mlx5/driver.h>
+#include "accel/ipsec.h"
+
+#ifdef CONFIG_MLX5_IPSEC
+
+const struct mlx5_accel_ipsec_ops *mlx5_ipsec_offload_ops(struct mlx5_core_dev *mdev);
+static inline bool mlx5_is_ipsec_device(struct mlx5_core_dev *mdev)
+{
+ if (!MLX5_CAP_GEN(mdev, ipsec_offload))
+ return false;
+
+ if (!MLX5_CAP_GEN(mdev, log_max_dek))
+ return false;
+
+ if (!(MLX5_CAP_GEN_64(mdev, general_obj_types) &
+ MLX5_HCA_CAP_GENERAL_OBJECT_TYPES_IPSEC))
+ return false;
+
+ return MLX5_CAP_IPSEC(mdev, ipsec_crypto_offload) &&
+ MLX5_CAP_ETH(mdev, insert_trailer);
+}
+
+#else
+static inline const struct mlx5_accel_ipsec_ops *
+mlx5_ipsec_offload_ops(struct mlx5_core_dev *mdev) { return NULL; }
+static inline bool mlx5_is_ipsec_device(struct mlx5_core_dev *mdev)
+{
+ return false;
+}
+
+#endif /* CONFIG_MLX5_IPSEC */
+#endif /* __MLX5_IPSEC_OFFLOAD_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.c b/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.c
index cbf3d76c05a8..6c2b86a26863 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.c
@@ -113,7 +113,9 @@ int mlx5_ktls_create_key(struct mlx5_core_dev *mdev,
return -EINVAL;
}
- return mlx5_create_encryption_key(mdev, key, sz_bytes, p_key_id);
+ return mlx5_create_encryption_key(mdev, key, sz_bytes,
+ MLX5_ACCEL_OBJ_TLS_KEY,
+ p_key_id);
}
void mlx5_ktls_destroy_key(struct mlx5_core_dev *mdev, u32 key_id)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.h b/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.h
index aefea467f7b3..fd874f0c380a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.h
@@ -43,9 +43,20 @@ int mlx5_ktls_create_key(struct mlx5_core_dev *mdev,
u32 *p_key_id);
void mlx5_ktls_destroy_key(struct mlx5_core_dev *mdev, u32 key_id);
+static inline bool mlx5_accel_is_ktls_tx(struct mlx5_core_dev *mdev)
+{
+ return MLX5_CAP_GEN(mdev, tls_tx);
+}
+
+static inline bool mlx5_accel_is_ktls_rx(struct mlx5_core_dev *mdev)
+{
+ return MLX5_CAP_GEN(mdev, tls_rx);
+}
+
static inline bool mlx5_accel_is_ktls_device(struct mlx5_core_dev *mdev)
{
- if (!MLX5_CAP_GEN(mdev, tls_tx))
+ if (!mlx5_accel_is_ktls_tx(mdev) &&
+ !mlx5_accel_is_ktls_rx(mdev))
return false;
if (!MLX5_CAP_GEN(mdev, log_max_dek))
@@ -67,6 +78,12 @@ static inline bool mlx5e_ktls_type_check(struct mlx5_core_dev *mdev,
return false;
}
#else
+static inline bool mlx5_accel_is_ktls_tx(struct mlx5_core_dev *mdev)
+{ return false; }
+
+static inline bool mlx5_accel_is_ktls_rx(struct mlx5_core_dev *mdev)
+{ return false; }
+
static inline int
mlx5_ktls_create_key(struct mlx5_core_dev *mdev,
struct tls_crypto_info *crypto_info,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index a99fe4b02b9b..c709e9a385f6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -113,6 +113,8 @@ static const struct devlink_ops mlx5_devlink_ops = {
.eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
.eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
+ .port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
+ .port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
#endif
.flash_update = mlx5_devlink_flash_update,
.info_get = mlx5_devlink_info_get,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
index a7551274be58..ad3594c4afcb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
@@ -676,7 +676,7 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work)
block_count = tracer->buff.size / TRACER_BLOCK_SIZE_BYTE;
start_offset = tracer->buff.consumer_index * TRACER_BLOCK_SIZE_BYTE;
- /* Copy the block to local buffer to avoid HW override while being processed*/
+ /* Copy the block to local buffer to avoid HW override while being processed */
memcpy(tmp_trace_block, tracer->buff.log_buf + start_offset,
TRACER_BLOCK_SIZE_BYTE);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c
index 17ab7efe693d..4924a5658853 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c
@@ -23,6 +23,9 @@ static const char *const mlx5_rsc_sgmt_name[] = {
MLX5_SGMT_STR_ASSING(SX_SLICE_ALL),
MLX5_SGMT_STR_ASSING(RDB),
MLX5_SGMT_STR_ASSING(RX_SLICE_ALL),
+ MLX5_SGMT_STR_ASSING(PRM_QUERY_QP),
+ MLX5_SGMT_STR_ASSING(PRM_QUERY_CQ),
+ MLX5_SGMT_STR_ASSING(PRM_QUERY_MKEY),
};
struct mlx5_rsc_dump {
@@ -130,11 +133,13 @@ struct mlx5_rsc_dump_cmd *mlx5_rsc_dump_cmd_create(struct mlx5_core_dev *dev,
cmd->mem_size = key->size;
return cmd;
}
+EXPORT_SYMBOL(mlx5_rsc_dump_cmd_create);
void mlx5_rsc_dump_cmd_destroy(struct mlx5_rsc_dump_cmd *cmd)
{
kfree(cmd);
}
+EXPORT_SYMBOL(mlx5_rsc_dump_cmd_destroy);
int mlx5_rsc_dump_next(struct mlx5_core_dev *dev, struct mlx5_rsc_dump_cmd *cmd,
struct page *page, int *size)
@@ -155,6 +160,7 @@ int mlx5_rsc_dump_next(struct mlx5_core_dev *dev, struct mlx5_rsc_dump_cmd *cmd,
return more_dump;
}
+EXPORT_SYMBOL(mlx5_rsc_dump_next);
#define MLX5_RSC_DUMP_MENU_SEGMENT 0xffff
static int mlx5_rsc_dump_menu(struct mlx5_core_dev *dev)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.h
index 148270073e71..64c4956db6d2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.h
@@ -4,41 +4,10 @@
#ifndef __MLX5_RSC_DUMP_H
#define __MLX5_RSC_DUMP_H
+#include <linux/mlx5/rsc_dump.h>
#include <linux/mlx5/driver.h>
#include "mlx5_core.h"
-enum mlx5_sgmt_type {
- MLX5_SGMT_TYPE_HW_CQPC,
- MLX5_SGMT_TYPE_HW_SQPC,
- MLX5_SGMT_TYPE_HW_RQPC,
- MLX5_SGMT_TYPE_FULL_SRQC,
- MLX5_SGMT_TYPE_FULL_CQC,
- MLX5_SGMT_TYPE_FULL_EQC,
- MLX5_SGMT_TYPE_FULL_QPC,
- MLX5_SGMT_TYPE_SND_BUFF,
- MLX5_SGMT_TYPE_RCV_BUFF,
- MLX5_SGMT_TYPE_SRQ_BUFF,
- MLX5_SGMT_TYPE_CQ_BUFF,
- MLX5_SGMT_TYPE_EQ_BUFF,
- MLX5_SGMT_TYPE_SX_SLICE,
- MLX5_SGMT_TYPE_SX_SLICE_ALL,
- MLX5_SGMT_TYPE_RDB,
- MLX5_SGMT_TYPE_RX_SLICE_ALL,
- MLX5_SGMT_TYPE_MENU,
- MLX5_SGMT_TYPE_TERMINATE,
-
- MLX5_SGMT_TYPE_NUM, /* Keep last */
-};
-
-struct mlx5_rsc_key {
- enum mlx5_sgmt_type rsc;
- int index1;
- int index2;
- int num_of_obj1;
- int num_of_obj2;
- int size;
-};
-
#define MLX5_RSC_DUMP_ALL 0xFFFF
struct mlx5_rsc_dump_cmd;
struct mlx5_rsc_dump;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 842db20493df..0cc2080fd847 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -45,6 +45,7 @@
#include <linux/mlx5/transobj.h>
#include <linux/mlx5/fs.h>
#include <linux/rhashtable.h>
+#include <net/udp_tunnel.h>
#include <net/switchdev.h>
#include <net/xdp.h>
#include <linux/dim.h>
@@ -191,13 +192,8 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
struct mlx5e_tx_wqe {
struct mlx5_wqe_ctrl_seg ctrl;
- union {
- struct {
- struct mlx5_wqe_eth_seg eth;
- struct mlx5_wqe_data_seg data[0];
- };
- u8 tls_progress_params_ctx[0];
- };
+ struct mlx5_wqe_eth_seg eth;
+ struct mlx5_wqe_data_seg data[0];
};
struct mlx5e_rx_wqe_ll {
@@ -213,10 +209,7 @@ struct mlx5e_umr_wqe {
struct mlx5_wqe_ctrl_seg ctrl;
struct mlx5_wqe_umr_ctrl_seg uctrl;
struct mlx5_mkey_seg mkc;
- union {
- struct mlx5_mtt inline_mtts[0];
- u8 tls_static_params_ctx[0];
- };
+ struct mlx5_mtt inline_mtts[0];
};
extern const char mlx5e_self_tests[][ETH_GSTRING_LEN];
@@ -271,6 +264,7 @@ enum {
MLX5E_RQ_STATE_AM,
MLX5E_RQ_STATE_NO_CSUM_COMPLETE,
MLX5E_RQ_STATE_CSUM_FULL, /* cqe_csum_full hw bit is set */
+ MLX5E_RQ_STATE_FPGA_TLS, /* FPGA TLS enabled */
};
struct mlx5e_cq {
@@ -537,6 +531,8 @@ typedef struct sk_buff *
typedef bool (*mlx5e_fp_post_rx_wqes)(struct mlx5e_rq *rq);
typedef void (*mlx5e_fp_dealloc_wqe)(struct mlx5e_rq*, u16);
+int mlx5e_rq_set_handlers(struct mlx5e_rq *rq, struct mlx5e_params *params, bool xsk);
+
enum mlx5e_rq_flag {
MLX5E_RQ_FLAG_XDP_XMIT,
MLX5E_RQ_FLAG_XDP_REDIRECT,
@@ -651,9 +647,11 @@ struct mlx5e_channel {
/* AF_XDP zero-copy */
struct mlx5e_rq xskrq;
struct mlx5e_xdpsq xsksq;
- struct mlx5e_icosq xskicosq;
- /* xskicosq can be accessed from any CPU - the spinlock protects it. */
- spinlock_t xskicosq_lock;
+
+ /* Async ICOSQ */
+ struct mlx5e_icosq async_icosq;
+ /* async_icosq can be accessed from any CPU - the spinlock protects it. */
+ spinlock_t async_icosq_lock;
/* data path - accessed per napi poll */
struct irq_desc *irq_desc;
@@ -795,6 +793,7 @@ struct mlx5e_priv {
u16 drop_rq_q_counter;
struct notifier_block events_nb;
+ struct udp_tunnel_nic_info nic_info;
#ifdef CONFIG_MLX5_CORE_EN_DCB
struct mlx5e_dcbx dcbx;
#endif
@@ -817,6 +816,13 @@ struct mlx5e_priv {
struct mlx5e_scratchpad scratchpad;
};
+struct mlx5e_rx_handlers {
+ mlx5e_fp_handle_rx_cqe handle_rx_cqe;
+ mlx5e_fp_handle_rx_cqe handle_rx_cqe_mpwqe;
+};
+
+extern const struct mlx5e_rx_handlers mlx5e_rx_handlers_nic;
+
struct mlx5e_profile {
int (*init)(struct mlx5_core_dev *mdev,
struct net_device *netdev,
@@ -833,78 +839,17 @@ struct mlx5e_profile {
void (*update_carrier)(struct mlx5e_priv *priv);
unsigned int (*stats_grps_num)(struct mlx5e_priv *priv);
mlx5e_stats_grp_t *stats_grps;
- struct {
- mlx5e_fp_handle_rx_cqe handle_rx_cqe;
- mlx5e_fp_handle_rx_cqe handle_rx_cqe_mpwqe;
- } rx_handlers;
+ const struct mlx5e_rx_handlers *rx_handlers;
int max_tc;
u8 rq_groups;
};
void mlx5e_build_ptys2ethtool_map(void);
-u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
- struct net_device *sb_dev);
-netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev);
-void mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
- struct mlx5e_tx_wqe *wqe, u16 pi, bool xmit_more);
-
-void mlx5e_trigger_irq(struct mlx5e_icosq *sq);
-void mlx5e_completion_event(struct mlx5_core_cq *mcq, struct mlx5_eqe *eqe);
-void mlx5e_cq_error_event(struct mlx5_core_cq *mcq, enum mlx5_event event);
-int mlx5e_napi_poll(struct napi_struct *napi, int budget);
-bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget);
-int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget);
-void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq);
-
-static inline u32 mlx5e_rqwq_get_size(struct mlx5e_rq *rq)
-{
- switch (rq->wq_type) {
- case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
- return mlx5_wq_ll_get_size(&rq->mpwqe.wq);
- default:
- return mlx5_wq_cyc_get_size(&rq->wqe.wq);
- }
-}
-
-static inline u32 mlx5e_rqwq_get_cur_sz(struct mlx5e_rq *rq)
-{
- switch (rq->wq_type) {
- case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
- return rq->mpwqe.wq.cur_sz;
- default:
- return rq->wqe.wq.cur_sz;
- }
-}
-
bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev);
bool mlx5e_striding_rq_possible(struct mlx5_core_dev *mdev,
struct mlx5e_params *params);
-void mlx5e_page_dma_unmap(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info);
-void mlx5e_page_release_dynamic(struct mlx5e_rq *rq,
- struct mlx5e_dma_info *dma_info,
- bool recycle);
-void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
-void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
-bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq);
-int mlx5e_poll_ico_cq(struct mlx5e_cq *cq);
-bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq);
-void mlx5e_dealloc_rx_wqe(struct mlx5e_rq *rq, u16 ix);
-void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix);
-struct sk_buff *
-mlx5e_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
- u16 cqe_bcnt, u32 head_offset, u32 page_idx);
-struct sk_buff *
-mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
- u16 cqe_bcnt, u32 head_offset, u32 page_idx);
-struct sk_buff *
-mlx5e_skb_from_cqe_linear(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
- struct mlx5e_wqe_frag_info *wi, u32 cqe_bcnt);
-struct sk_buff *
-mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
- struct mlx5e_wqe_frag_info *wi, u32 cqe_bcnt);
-
void mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats);
void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s);
@@ -1007,8 +952,6 @@ void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev,
int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state, int next_state);
void mlx5e_activate_rq(struct mlx5e_rq *rq);
void mlx5e_deactivate_rq(struct mlx5e_rq *rq);
-void mlx5e_free_rx_descs(struct mlx5e_rq *rq);
-void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq);
void mlx5e_activate_icosq(struct mlx5e_icosq *icosq);
void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq);
@@ -1033,6 +976,7 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev);
void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev);
int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb,
bool enable_mc_lb);
+void mlx5e_mkey_set_relaxed_ordering(struct mlx5_core_dev *mdev, void *mkc);
/* common netdev helpers */
void mlx5e_create_q_counters(struct mlx5e_priv *priv);
@@ -1070,6 +1014,7 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv);
int mlx5e_set_dev_port_mtu_ctx(struct mlx5e_priv *priv, void *context);
int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
mlx5e_fp_preactivate preactivate);
+void mlx5e_vxlan_set_netdev_info(struct mlx5e_priv *priv);
/* ethtool helpers */
void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
@@ -1138,8 +1083,6 @@ void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params,
void mlx5e_rx_dim_work(struct work_struct *work);
void mlx5e_tx_dim_work(struct work_struct *work);
-void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti);
-void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti);
netdev_features_t mlx5e_features_check(struct sk_buff *skb,
struct net_device *netdev,
netdev_features_t features);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c
index f8b2de4b04be..a69c62d72d16 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c
@@ -6,17 +6,16 @@
int mlx5e_devlink_port_register(struct mlx5e_priv *priv)
{
struct devlink *devlink = priv_to_devlink(priv->mdev);
+ struct devlink_port_attrs attrs = {};
- if (mlx5_core_is_pf(priv->mdev))
- devlink_port_attrs_set(&priv->dl_port,
- DEVLINK_PORT_FLAVOUR_PHYSICAL,
- PCI_FUNC(priv->mdev->pdev->devfn),
- false, 0,
- NULL, 0);
- else
- devlink_port_attrs_set(&priv->dl_port,
- DEVLINK_PORT_FLAVOUR_VIRTUAL,
- 0, false, 0, NULL, 0);
+ if (mlx5_core_is_pf(priv->mdev)) {
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = PCI_FUNC(priv->mdev->pdev->devfn);
+ } else {
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_VIRTUAL;
+ }
+
+ devlink_port_attrs_set(&priv->dl_port, &attrs);
return devlink_port_register(devlink, &priv->dl_port, 1);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
index 0416f7712109..6fdcd5e69476 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
@@ -4,6 +4,8 @@
#ifndef __MLX5E_FLOW_STEER_H__
#define __MLX5E_FLOW_STEER_H__
+#include "mod_hdr.h"
+
enum {
MLX5E_TC_FT_LEVEL = 0,
MLX5E_TC_TTC_FT_LEVEL,
@@ -105,11 +107,16 @@ enum mlx5e_tunnel_types {
bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev);
+struct mlx5e_ttc_rule {
+ struct mlx5_flow_handle *rule;
+ struct mlx5_flow_destination default_dest;
+};
+
/* L3/L4 traffic type classifier */
struct mlx5e_ttc_table {
- struct mlx5e_flow_table ft;
- struct mlx5_flow_handle *rules[MLX5E_NUM_TT];
- struct mlx5_flow_handle *tunnel_rules[MLX5E_NUM_TUNNEL_TT];
+ struct mlx5e_flow_table ft;
+ struct mlx5e_ttc_rule rules[MLX5E_NUM_TT];
+ struct mlx5_flow_handle *tunnel_rules[MLX5E_NUM_TUNNEL_TT];
};
/* NIC prio FTS */
@@ -118,8 +125,15 @@ enum {
MLX5E_L2_FT_LEVEL,
MLX5E_TTC_FT_LEVEL,
MLX5E_INNER_TTC_FT_LEVEL,
+#ifdef CONFIG_MLX5_EN_TLS
+ MLX5E_ACCEL_FS_TCP_FT_LEVEL,
+#endif
#ifdef CONFIG_MLX5_EN_ARFS
- MLX5E_ARFS_FT_LEVEL
+ MLX5E_ARFS_FT_LEVEL,
+#endif
+#ifdef CONFIG_MLX5_EN_IPSEC
+ MLX5E_ACCEL_FS_ESP_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,
+ MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL,
#endif
};
@@ -211,6 +225,10 @@ static inline int mlx5e_arfs_enable(struct mlx5e_priv *priv) { return -EOPNOTSUP
static inline int mlx5e_arfs_disable(struct mlx5e_priv *priv) { return -EOPNOTSUPP; }
#endif
+#ifdef CONFIG_MLX5_EN_TLS
+struct mlx5e_accel_fs_tcp;
+#endif
+
struct mlx5e_flow_steering {
struct mlx5_flow_namespace *ns;
#ifdef CONFIG_MLX5_EN_RXNFC
@@ -224,6 +242,9 @@ struct mlx5e_flow_steering {
#ifdef CONFIG_MLX5_EN_ARFS
struct mlx5e_arfs_tables arfs;
#endif
+#ifdef CONFIG_MLX5_EN_TLS
+ struct mlx5e_accel_fs_tcp *accel_tcp;
+#endif
};
struct ttc_params {
@@ -248,6 +269,11 @@ void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv,
struct mlx5e_ttc_table *ttc);
void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft);
+int mlx5e_ttc_fwd_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type,
+ struct mlx5_flow_destination *new_dest);
+struct mlx5_flow_destination
+mlx5e_ttc_get_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type);
+int mlx5e_ttc_fwd_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type);
void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv);
void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/health.c b/drivers/net/ethernet/mellanox/mlx5/core/en/health.c
index 7283443868f3..3dc200bcfabd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/health.c
@@ -5,7 +5,7 @@
#include "lib/eq.h"
#include "lib/mlx5.h"
-int mlx5e_reporter_named_obj_nest_start(struct devlink_fmsg *fmsg, char *name)
+int mlx5e_health_fmsg_named_obj_nest_start(struct devlink_fmsg *fmsg, char *name)
{
int err;
@@ -20,7 +20,7 @@ int mlx5e_reporter_named_obj_nest_start(struct devlink_fmsg *fmsg, char *name)
return 0;
}
-int mlx5e_reporter_named_obj_nest_end(struct devlink_fmsg *fmsg)
+int mlx5e_health_fmsg_named_obj_nest_end(struct devlink_fmsg *fmsg)
{
int err;
@@ -35,7 +35,7 @@ int mlx5e_reporter_named_obj_nest_end(struct devlink_fmsg *fmsg)
return 0;
}
-int mlx5e_reporter_cq_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg)
+int mlx5e_health_cq_diag_fmsg(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg)
{
struct mlx5e_priv *priv = cq->channel->priv;
u32 out[MLX5_ST_SZ_DW(query_cq_out)] = {};
@@ -50,7 +50,7 @@ int mlx5e_reporter_cq_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg)
cqc = MLX5_ADDR_OF(query_cq_out, out, cq_context);
hw_status = MLX5_GET(cqc, cqc, status);
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "CQ");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "CQ");
if (err)
return err;
@@ -62,14 +62,22 @@ int mlx5e_reporter_cq_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg)
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = devlink_fmsg_u32_pair_put(fmsg, "ci", mlx5_cqwq_get_ci(&cq->wq));
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "size", mlx5_cqwq_get_size(&cq->wq));
+ if (err)
+ return err;
+
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
return 0;
}
-int mlx5e_reporter_cq_common_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg)
+int mlx5e_health_cq_common_diag_fmsg(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg)
{
u8 cq_log_stride;
u32 cq_sz;
@@ -78,7 +86,7 @@ int mlx5e_reporter_cq_common_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *
cq_sz = mlx5_cqwq_get_size(&cq->wq);
cq_log_stride = mlx5_cqwq_get_log_stride_size(&cq->wq);
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "CQ");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "CQ");
if (err)
return err;
@@ -90,26 +98,48 @@ int mlx5e_reporter_cq_common_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
return 0;
}
-int mlx5e_health_create_reporters(struct mlx5e_priv *priv)
+int mlx5e_health_eq_diag_fmsg(struct mlx5_eq_comp *eq, struct devlink_fmsg *fmsg)
{
int err;
- err = mlx5e_reporter_tx_create(priv);
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "EQ");
if (err)
return err;
- err = mlx5e_reporter_rx_create(priv);
+ err = devlink_fmsg_u8_pair_put(fmsg, "eqn", eq->core.eqn);
if (err)
return err;
- return 0;
+ err = devlink_fmsg_u32_pair_put(fmsg, "irqn", eq->core.irqn);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "vecidx", eq->core.vecidx);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "ci", eq->core.cons_index);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "size", eq->core.nent);
+ if (err)
+ return err;
+
+ return mlx5e_health_fmsg_named_obj_nest_end(fmsg);
+}
+
+void mlx5e_health_create_reporters(struct mlx5e_priv *priv)
+{
+ mlx5e_reporter_tx_create(priv);
+ mlx5e_reporter_rx_create(priv);
}
void mlx5e_health_destroy_reporters(struct mlx5e_priv *priv)
@@ -291,7 +321,7 @@ int mlx5e_health_queue_dump(struct mlx5e_priv *priv, struct devlink_fmsg *fmsg,
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, lbl);
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, lbl);
if (err)
return err;
@@ -303,7 +333,7 @@ int mlx5e_health_queue_dump(struct mlx5e_priv *priv, struct devlink_fmsg *fmsg,
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/health.h b/drivers/net/ethernet/mellanox/mlx5/core/en/health.h
index 38f97f79ef16..b9aadddfd000 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/health.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/health.h
@@ -16,23 +16,25 @@ static inline bool cqe_syndrome_needs_recover(u8 syndrome)
syndrome == MLX5_CQE_SYNDROME_WR_FLUSH_ERR;
}
-int mlx5e_reporter_tx_create(struct mlx5e_priv *priv);
+void mlx5e_reporter_tx_create(struct mlx5e_priv *priv);
void mlx5e_reporter_tx_destroy(struct mlx5e_priv *priv);
void mlx5e_reporter_tx_err_cqe(struct mlx5e_txqsq *sq);
int mlx5e_reporter_tx_timeout(struct mlx5e_txqsq *sq);
-int mlx5e_reporter_cq_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg);
-int mlx5e_reporter_cq_common_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg);
-int mlx5e_reporter_named_obj_nest_start(struct devlink_fmsg *fmsg, char *name);
-int mlx5e_reporter_named_obj_nest_end(struct devlink_fmsg *fmsg);
+int mlx5e_health_cq_diag_fmsg(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg);
+int mlx5e_health_cq_common_diag_fmsg(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg);
+int mlx5e_health_eq_diag_fmsg(struct mlx5_eq_comp *eq, struct devlink_fmsg *fmsg);
+int mlx5e_health_fmsg_named_obj_nest_start(struct devlink_fmsg *fmsg, char *name);
+int mlx5e_health_fmsg_named_obj_nest_end(struct devlink_fmsg *fmsg);
-int mlx5e_reporter_rx_create(struct mlx5e_priv *priv);
+void mlx5e_reporter_rx_create(struct mlx5e_priv *priv);
void mlx5e_reporter_rx_destroy(struct mlx5e_priv *priv);
void mlx5e_reporter_icosq_cqe_err(struct mlx5e_icosq *icosq);
void mlx5e_reporter_rq_cqe_err(struct mlx5e_rq *rq);
void mlx5e_reporter_rx_timeout(struct mlx5e_rq *rq);
#define MLX5E_REPORTER_PER_Q_MAX_LEN 256
+#define MLX5E_REPORTER_FLUSH_TIMEOUT_MSEC 2000
struct mlx5e_err_ctx {
int (*recover)(void *ctx);
@@ -46,7 +48,7 @@ int mlx5e_health_recover_channels(struct mlx5e_priv *priv);
int mlx5e_health_report(struct mlx5e_priv *priv,
struct devlink_health_reporter *reporter, char *err_str,
struct mlx5e_err_ctx *err_ctx);
-int mlx5e_health_create_reporters(struct mlx5e_priv *priv);
+void mlx5e_health_create_reporters(struct mlx5e_priv *priv);
void mlx5e_health_destroy_reporters(struct mlx5e_priv *priv);
void mlx5e_health_channels_update(struct mlx5e_priv *priv);
int mlx5e_health_rsc_fmsg_dump(struct mlx5e_priv *priv, struct mlx5_rsc_key *key,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.c b/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.c
new file mode 100644
index 000000000000..7edde4d536fd
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+// Copyright (c) 2020 Mellanox Technologies
+
+#include <linux/jhash.h>
+#include "mod_hdr.h"
+
+#define MLX5_MH_ACT_SZ MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)
+
+struct mod_hdr_key {
+ int num_actions;
+ void *actions;
+};
+
+struct mlx5e_mod_hdr_handle {
+ /* a node of a hash table which keeps all the mod_hdr entries */
+ struct hlist_node mod_hdr_hlist;
+
+ struct mod_hdr_key key;
+
+ struct mlx5_modify_hdr *modify_hdr;
+
+ refcount_t refcnt;
+ struct completion res_ready;
+ int compl_result;
+};
+
+static u32 hash_mod_hdr_info(struct mod_hdr_key *key)
+{
+ return jhash(key->actions,
+ key->num_actions * MLX5_MH_ACT_SZ, 0);
+}
+
+static int cmp_mod_hdr_info(struct mod_hdr_key *a, struct mod_hdr_key *b)
+{
+ if (a->num_actions != b->num_actions)
+ return 1;
+
+ return memcmp(a->actions, b->actions,
+ a->num_actions * MLX5_MH_ACT_SZ);
+}
+
+void mlx5e_mod_hdr_tbl_init(struct mod_hdr_tbl *tbl)
+{
+ mutex_init(&tbl->lock);
+ hash_init(tbl->hlist);
+}
+
+void mlx5e_mod_hdr_tbl_destroy(struct mod_hdr_tbl *tbl)
+{
+ mutex_destroy(&tbl->lock);
+}
+
+static struct mlx5e_mod_hdr_handle *mod_hdr_get(struct mod_hdr_tbl *tbl,
+ struct mod_hdr_key *key,
+ u32 hash_key)
+{
+ struct mlx5e_mod_hdr_handle *mh, *found = NULL;
+
+ hash_for_each_possible(tbl->hlist, mh, mod_hdr_hlist, hash_key) {
+ if (!cmp_mod_hdr_info(&mh->key, key)) {
+ refcount_inc(&mh->refcnt);
+ found = mh;
+ break;
+ }
+ }
+
+ return found;
+}
+
+struct mlx5e_mod_hdr_handle *
+mlx5e_mod_hdr_attach(struct mlx5_core_dev *mdev,
+ struct mod_hdr_tbl *tbl,
+ enum mlx5_flow_namespace_type namespace,
+ struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
+{
+ int num_actions, actions_size, err;
+ struct mlx5e_mod_hdr_handle *mh;
+ struct mod_hdr_key key;
+ u32 hash_key;
+
+ num_actions = mod_hdr_acts->num_actions;
+ actions_size = MLX5_MH_ACT_SZ * num_actions;
+
+ key.actions = mod_hdr_acts->actions;
+ key.num_actions = num_actions;
+
+ hash_key = hash_mod_hdr_info(&key);
+
+ mutex_lock(&tbl->lock);
+ mh = mod_hdr_get(tbl, &key, hash_key);
+ if (mh) {
+ mutex_unlock(&tbl->lock);
+ wait_for_completion(&mh->res_ready);
+
+ if (mh->compl_result < 0) {
+ err = -EREMOTEIO;
+ goto attach_header_err;
+ }
+ goto attach_header;
+ }
+
+ mh = kzalloc(sizeof(*mh) + actions_size, GFP_KERNEL);
+ if (!mh) {
+ mutex_unlock(&tbl->lock);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ mh->key.actions = (void *)mh + sizeof(*mh);
+ memcpy(mh->key.actions, key.actions, actions_size);
+ mh->key.num_actions = num_actions;
+ refcount_set(&mh->refcnt, 1);
+ init_completion(&mh->res_ready);
+
+ hash_add(tbl->hlist, &mh->mod_hdr_hlist, hash_key);
+ mutex_unlock(&tbl->lock);
+
+ mh->modify_hdr = mlx5_modify_header_alloc(mdev, namespace,
+ mh->key.num_actions,
+ mh->key.actions);
+ if (IS_ERR(mh->modify_hdr)) {
+ err = PTR_ERR(mh->modify_hdr);
+ mh->compl_result = err;
+ goto alloc_header_err;
+ }
+ mh->compl_result = 1;
+ complete_all(&mh->res_ready);
+
+attach_header:
+ return mh;
+
+alloc_header_err:
+ complete_all(&mh->res_ready);
+attach_header_err:
+ mlx5e_mod_hdr_detach(mdev, tbl, mh);
+ return ERR_PTR(err);
+}
+
+void mlx5e_mod_hdr_detach(struct mlx5_core_dev *mdev,
+ struct mod_hdr_tbl *tbl,
+ struct mlx5e_mod_hdr_handle *mh)
+{
+ if (!refcount_dec_and_mutex_lock(&mh->refcnt, &tbl->lock))
+ return;
+ hash_del(&mh->mod_hdr_hlist);
+ mutex_unlock(&tbl->lock);
+
+ if (mh->compl_result > 0)
+ mlx5_modify_header_dealloc(mdev, mh->modify_hdr);
+
+ kfree(mh);
+}
+
+struct mlx5_modify_hdr *mlx5e_mod_hdr_get(struct mlx5e_mod_hdr_handle *mh)
+{
+ return mh->modify_hdr;
+}
+
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.h b/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.h
new file mode 100644
index 000000000000..33b23d8f9182
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/mod_hdr.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2020 Mellanox Technologies */
+
+#ifndef __MLX5E_EN_MOD_HDR_H__
+#define __MLX5E_EN_MOD_HDR_H__
+
+#include <linux/hashtable.h>
+#include <linux/mlx5/fs.h>
+
+struct mlx5e_mod_hdr_handle;
+
+struct mlx5e_tc_mod_hdr_acts {
+ int num_actions;
+ int max_actions;
+ void *actions;
+};
+
+struct mlx5e_mod_hdr_handle *
+mlx5e_mod_hdr_attach(struct mlx5_core_dev *mdev,
+ struct mod_hdr_tbl *tbl,
+ enum mlx5_flow_namespace_type namespace,
+ struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
+void mlx5e_mod_hdr_detach(struct mlx5_core_dev *mdev,
+ struct mod_hdr_tbl *tbl,
+ struct mlx5e_mod_hdr_handle *mh);
+struct mlx5_modify_hdr *mlx5e_mod_hdr_get(struct mlx5e_mod_hdr_handle *mh);
+
+void mlx5e_mod_hdr_tbl_init(struct mod_hdr_tbl *tbl);
+void mlx5e_mod_hdr_tbl_destroy(struct mod_hdr_tbl *tbl);
+
+#endif /* __MLX5E_EN_MOD_HDR_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.h b/drivers/net/ethernet/mellanox/mlx5/core/en/params.h
index 989d8f429438..a87273e801b2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.h
@@ -11,33 +11,33 @@ struct mlx5e_xsk_param {
u16 chunk_size;
};
+struct mlx5e_cq_param {
+ u32 cqc[MLX5_ST_SZ_DW(cqc)];
+ struct mlx5_wq_param wq;
+ u16 eq_ix;
+ u8 cq_period_mode;
+};
+
struct mlx5e_rq_param {
+ struct mlx5e_cq_param cqp;
u32 rqc[MLX5_ST_SZ_DW(rqc)];
struct mlx5_wq_param wq;
struct mlx5e_rq_frags_info frags_info;
};
struct mlx5e_sq_param {
+ struct mlx5e_cq_param cqp;
u32 sqc[MLX5_ST_SZ_DW(sqc)];
struct mlx5_wq_param wq;
bool is_mpw;
};
-struct mlx5e_cq_param {
- u32 cqc[MLX5_ST_SZ_DW(cqc)];
- struct mlx5_wq_param wq;
- u16 eq_ix;
- u8 cq_period_mode;
-};
-
struct mlx5e_channel_param {
struct mlx5e_rq_param rq;
- struct mlx5e_sq_param sq;
+ struct mlx5e_sq_param txq_sq;
struct mlx5e_sq_param xdp_sq;
struct mlx5e_sq_param icosq;
- struct mlx5e_cq_param rx_cq;
- struct mlx5e_cq_param tx_cq;
- struct mlx5e_cq_param icosq_cq;
+ struct mlx5e_sq_param async_icosq;
};
static inline bool mlx5e_qid_get_ch_if_in_group(struct mlx5e_params *params,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
index 3cf3e35053f7..5de1cb9f5330 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
@@ -76,6 +76,9 @@ static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = {
[MLX5E_100GAUI_2_100GBASE_CR2_KR2] = 100000,
[MLX5E_200GAUI_4_200GBASE_CR4_KR4] = 200000,
[MLX5E_400GAUI_8] = 400000,
+ [MLX5E_100GAUI_1_100GBASE_CR_KR] = 100000,
+ [MLX5E_200GAUI_2_200GBASE_CR2_KR2] = 200000,
+ [MLX5E_400GAUI_4_400GBASE_CR4_KR4] = 400000,
};
bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c
index c3d167fa944c..906292035088 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include <linux/notifier.h>
#include <net/netevent.h>
+#include <net/arp.h>
#include "neigh.h"
#include "tc.h"
#include "en_rep.h"
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c
index 245a99f69641..79cc42d88eec 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c
@@ -404,7 +404,7 @@ static void mlx5e_rep_indr_block_unbind(void *cb_priv)
static LIST_HEAD(mlx5e_block_cb_list);
static int
-mlx5e_rep_indr_setup_block(struct net_device *netdev,
+mlx5e_rep_indr_setup_block(struct net_device *netdev, struct Qdisc *sch,
struct mlx5e_rep_priv *rpriv,
struct flow_block_offload *f,
flow_setup_cb_t *setup_cb,
@@ -442,7 +442,7 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
block_cb = flow_indr_block_cb_alloc(setup_cb, indr_priv, indr_priv,
mlx5e_rep_indr_block_unbind,
- f, netdev, data, rpriv,
+ f, netdev, sch, data, rpriv,
cleanup);
if (IS_ERR(block_cb)) {
list_del(&indr_priv->list);
@@ -472,18 +472,18 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
}
static
-int mlx5e_rep_indr_setup_cb(struct net_device *netdev, void *cb_priv,
+int mlx5e_rep_indr_setup_cb(struct net_device *netdev, struct Qdisc *sch, void *cb_priv,
enum tc_setup_type type, void *type_data,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
{
switch (type) {
case TC_SETUP_BLOCK:
- return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
+ return mlx5e_rep_indr_setup_block(netdev, sch, cb_priv, type_data,
mlx5e_rep_indr_setup_tc_cb,
data, cleanup);
case TC_SETUP_FT:
- return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
+ return mlx5e_rep_indr_setup_block(netdev, sch, cb_priv, type_data,
mlx5e_rep_indr_setup_ft_cb,
data, cleanup);
default:
@@ -606,7 +606,7 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
struct mlx5e_tc_update_priv *tc_priv)
{
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
- u32 chain = 0, reg_c0, reg_c1, tunnel_id, tuple_id;
+ u32 chain = 0, reg_c0, reg_c1, tunnel_id, zone_restore_id;
struct mlx5_rep_uplink_priv *uplink_priv;
struct mlx5e_rep_priv *uplink_rpriv;
struct tc_skb_ext *tc_skb_ext;
@@ -643,11 +643,12 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
tc_skb_ext->chain = chain;
- tuple_id = reg_c1 & TUPLE_ID_MAX;
+ zone_restore_id = reg_c1 & ZONE_RESTORE_MAX;
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
uplink_priv = &uplink_rpriv->uplink_priv;
- if (!mlx5e_tc_ct_restore_flow(uplink_priv, skb, tuple_id))
+ if (!mlx5e_tc_ct_restore_flow(uplink_priv, skb,
+ zone_restore_id))
return false;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
index c209579fc213..9913647a1faf 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
@@ -3,6 +3,7 @@
#include "health.h"
#include "params.h"
+#include "txrx.h"
static int mlx5e_query_rq_state(struct mlx5_core_dev *dev, u32 rqn, u8 *state)
{
@@ -29,7 +30,8 @@ out:
static int mlx5e_wait_for_icosq_flush(struct mlx5e_icosq *icosq)
{
- unsigned long exp_time = jiffies + msecs_to_jiffies(2000);
+ unsigned long exp_time = jiffies +
+ msecs_to_jiffies(MLX5E_REPORTER_FLUSH_TIMEOUT_MSEC);
while (time_before(jiffies, exp_time)) {
if (icosq->cc == icosq->pc)
@@ -123,25 +125,9 @@ static int mlx5e_rq_to_ready(struct mlx5e_rq *rq, int curr_state)
static int mlx5e_rx_reporter_err_rq_cqe_recover(void *ctx)
{
- struct mlx5_core_dev *mdev;
- struct net_device *dev;
- struct mlx5e_rq *rq;
- u8 state;
+ struct mlx5e_rq *rq = ctx;
int err;
- rq = ctx;
- mdev = rq->mdev;
- dev = rq->netdev;
- err = mlx5e_query_rq_state(mdev, rq->rqn, &state);
- if (err) {
- netdev_err(dev, "Failed to query RQ 0x%x state. err = %d\n",
- rq->rqn, err);
- goto out;
- }
-
- if (state != MLX5_RQC_STATE_ERR)
- goto out;
-
mlx5e_deactivate_rq(rq);
mlx5e_free_rx_descs(rq);
@@ -191,19 +177,71 @@ static int mlx5e_rx_reporter_recover(struct devlink_health_reporter *reporter,
mlx5e_health_recover_channels(priv);
}
+static int mlx5e_reporter_icosq_diagnose(struct mlx5e_icosq *icosq, u8 hw_state,
+ struct devlink_fmsg *fmsg)
+{
+ int err;
+
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "ICOSQ");
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "sqn", icosq->sqn);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u8_pair_put(fmsg, "HW state", hw_state);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "cc", icosq->cc);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "pc", icosq->pc);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "WQE size",
+ mlx5_wq_cyc_get_size(&icosq->wq));
+ if (err)
+ return err;
+
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "CQ");
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "cqn", icosq->cq.mcq.cqn);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "cc", icosq->cq.wq.cc);
+ if (err)
+ return err;
+
+ err = devlink_fmsg_u32_pair_put(fmsg, "size", mlx5_cqwq_get_size(&icosq->cq.wq));
+ if (err)
+ return err;
+
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
+ if (err)
+ return err;
+
+ return mlx5e_health_fmsg_named_obj_nest_end(fmsg);
+}
+
static int mlx5e_rx_reporter_build_diagnose_output(struct mlx5e_rq *rq,
struct devlink_fmsg *fmsg)
{
struct mlx5e_priv *priv = rq->channel->priv;
- struct mlx5e_params *params;
struct mlx5e_icosq *icosq;
u8 icosq_hw_state;
+ u16 wqe_counter;
int wqes_sz;
u8 hw_state;
u16 wq_head;
int err;
- params = &priv->channels.params;
icosq = &rq->channel->icosq;
err = mlx5e_query_rq_state(priv->mdev, rq->rqn, &hw_state);
if (err)
@@ -214,8 +252,8 @@ static int mlx5e_rx_reporter_build_diagnose_output(struct mlx5e_rq *rq,
return err;
wqes_sz = mlx5e_rqwq_get_cur_sz(rq);
- wq_head = params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ ?
- rq->mpwqe.wq.head : mlx5_wq_cyc_get_head(&rq->wqe.wq);
+ wq_head = mlx5e_rqwq_get_head(rq);
+ wqe_counter = mlx5e_rqwq_get_wqe_counter(rq);
err = devlink_fmsg_obj_nest_start(fmsg);
if (err)
@@ -237,6 +275,10 @@ static int mlx5e_rx_reporter_build_diagnose_output(struct mlx5e_rq *rq,
if (err)
return err;
+ err = devlink_fmsg_u32_pair_put(fmsg, "WQE counter", wqe_counter);
+ if (err)
+ return err;
+
err = devlink_fmsg_u32_pair_put(fmsg, "posted WQEs", wqes_sz);
if (err)
return err;
@@ -245,11 +287,15 @@ static int mlx5e_rx_reporter_build_diagnose_output(struct mlx5e_rq *rq,
if (err)
return err;
- err = devlink_fmsg_u8_pair_put(fmsg, "ICOSQ HW state", icosq_hw_state);
+ err = mlx5e_health_cq_diag_fmsg(&rq->cq, fmsg);
if (err)
return err;
- err = mlx5e_reporter_cq_diagnose(&rq->cq, fmsg);
+ err = mlx5e_health_eq_diag_fmsg(rq->cq.mcq.eq, fmsg);
+ if (err)
+ return err;
+
+ err = mlx5e_reporter_icosq_diagnose(icosq, icosq_hw_state, fmsg);
if (err)
return err;
@@ -279,11 +325,11 @@ static int mlx5e_rx_reporter_diagnose(struct devlink_health_reporter *reporter,
rq_sz = mlx5e_rqwq_get_size(generic_rq);
rq_stride = BIT(mlx5e_mpwqe_get_log_stride_size(priv->mdev, params, NULL));
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "Common config");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "Common config");
if (err)
goto unlock;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "RQ");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "RQ");
if (err)
goto unlock;
@@ -299,15 +345,15 @@ static int mlx5e_rx_reporter_diagnose(struct devlink_health_reporter *reporter,
if (err)
goto unlock;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_cq_common_diag_fmsg(&generic_rq->cq, fmsg);
if (err)
goto unlock;
- err = mlx5e_reporter_cq_common_diagnose(&generic_rq->cq, fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
goto unlock;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
goto unlock;
@@ -340,7 +386,7 @@ static int mlx5e_rx_reporter_dump_icosq(struct mlx5e_priv *priv, struct devlink_
if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
return 0;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "SX Slice");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "SX Slice");
if (err)
return err;
@@ -350,15 +396,15 @@ static int mlx5e_rx_reporter_dump_icosq(struct mlx5e_priv *priv, struct devlink_
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "ICOSQ");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "ICOSQ");
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "QPC");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "QPC");
if (err)
return err;
@@ -370,11 +416,11 @@ static int mlx5e_rx_reporter_dump_icosq(struct mlx5e_priv *priv, struct devlink_
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "send_buff");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "send_buff");
if (err)
return err;
@@ -385,11 +431,11 @@ static int mlx5e_rx_reporter_dump_icosq(struct mlx5e_priv *priv, struct devlink_
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
- return mlx5e_reporter_named_obj_nest_end(fmsg);
+ return mlx5e_health_fmsg_named_obj_nest_end(fmsg);
}
static int mlx5e_rx_reporter_dump_rq(struct mlx5e_priv *priv, struct devlink_fmsg *fmsg,
@@ -402,7 +448,7 @@ static int mlx5e_rx_reporter_dump_rq(struct mlx5e_priv *priv, struct devlink_fms
if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
return 0;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "RX Slice");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "RX Slice");
if (err)
return err;
@@ -412,15 +458,15 @@ static int mlx5e_rx_reporter_dump_rq(struct mlx5e_priv *priv, struct devlink_fms
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "RQ");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "RQ");
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "QPC");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "QPC");
if (err)
return err;
@@ -432,11 +478,11 @@ static int mlx5e_rx_reporter_dump_rq(struct mlx5e_priv *priv, struct devlink_fms
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "receive_buff");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "receive_buff");
if (err)
return err;
@@ -446,11 +492,11 @@ static int mlx5e_rx_reporter_dump_rq(struct mlx5e_priv *priv, struct devlink_fms
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
- return mlx5e_reporter_named_obj_nest_end(fmsg);
+ return mlx5e_health_fmsg_named_obj_nest_end(fmsg);
}
static int mlx5e_rx_reporter_dump_all_rqs(struct mlx5e_priv *priv,
@@ -462,7 +508,7 @@ static int mlx5e_rx_reporter_dump_all_rqs(struct mlx5e_priv *priv,
if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
return 0;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "RX Slice");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "RX Slice");
if (err)
return err;
@@ -472,7 +518,7 @@ static int mlx5e_rx_reporter_dump_all_rqs(struct mlx5e_priv *priv,
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
@@ -563,22 +609,18 @@ static const struct devlink_health_reporter_ops mlx5_rx_reporter_ops = {
#define MLX5E_REPORTER_RX_GRACEFUL_PERIOD 500
-int mlx5e_reporter_rx_create(struct mlx5e_priv *priv)
+void mlx5e_reporter_rx_create(struct mlx5e_priv *priv)
{
- struct devlink *devlink = priv_to_devlink(priv->mdev);
struct devlink_health_reporter *reporter;
- reporter = devlink_health_reporter_create(devlink,
- &mlx5_rx_reporter_ops,
- MLX5E_REPORTER_RX_GRACEFUL_PERIOD,
- priv);
+ reporter = devlink_port_health_reporter_create(&priv->dl_port, &mlx5_rx_reporter_ops,
+ MLX5E_REPORTER_RX_GRACEFUL_PERIOD, priv);
if (IS_ERR(reporter)) {
netdev_warn(priv->netdev, "Failed to create rx reporter, err = %ld\n",
PTR_ERR(reporter));
- return PTR_ERR(reporter);
+ return;
}
priv->rx_reporter = reporter;
- return 0;
}
void mlx5e_reporter_rx_destroy(struct mlx5e_priv *priv)
@@ -586,5 +628,5 @@ void mlx5e_reporter_rx_destroy(struct mlx5e_priv *priv)
if (!priv->rx_reporter)
return;
- devlink_health_reporter_destroy(priv->rx_reporter);
+ devlink_port_health_reporter_destroy(priv->rx_reporter);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
index 9805fc085512..8be6eaa3eeb1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
@@ -5,7 +5,8 @@
static int mlx5e_wait_for_sq_flush(struct mlx5e_txqsq *sq)
{
- unsigned long exp_time = jiffies + msecs_to_jiffies(2000);
+ unsigned long exp_time = jiffies +
+ msecs_to_jiffies(MLX5E_REPORTER_FLUSH_TIMEOUT_MSEC);
while (time_before(jiffies, exp_time)) {
if (sq->cc == sq->pc)
@@ -82,17 +83,40 @@ out:
return err;
}
+struct mlx5e_tx_timeout_ctx {
+ struct mlx5e_txqsq *sq;
+ signed int status;
+};
+
static int mlx5e_tx_reporter_timeout_recover(void *ctx)
{
+ struct mlx5e_tx_timeout_ctx *to_ctx;
+ struct mlx5e_priv *priv;
struct mlx5_eq_comp *eq;
struct mlx5e_txqsq *sq;
int err;
- sq = ctx;
+ to_ctx = ctx;
+ sq = to_ctx->sq;
eq = sq->cq.mcq.eq;
+ priv = sq->channel->priv;
err = mlx5e_health_channel_eq_recover(eq, sq->channel);
- if (err)
- clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
+ if (!err) {
+ to_ctx->status = 0; /* this sq recovered */
+ return err;
+ }
+
+ err = mlx5e_safe_reopen_channels(priv);
+ if (!err) {
+ to_ctx->status = 1; /* all channels recovered */
+ return err;
+ }
+
+ to_ctx->status = err;
+ clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
+ netdev_err(priv->netdev,
+ "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n",
+ err);
return err;
}
@@ -165,7 +189,11 @@ mlx5e_tx_reporter_build_diagnose_output(struct devlink_fmsg *fmsg,
if (err)
return err;
- err = mlx5e_reporter_cq_diagnose(&sq->cq, fmsg);
+ err = mlx5e_health_cq_diag_fmsg(&sq->cq, fmsg);
+ if (err)
+ return err;
+
+ err = mlx5e_health_eq_diag_fmsg(sq->cq.mcq.eq, fmsg);
if (err)
return err;
@@ -194,11 +222,11 @@ static int mlx5e_tx_reporter_diagnose(struct devlink_health_reporter *reporter,
sq_sz = mlx5_wq_cyc_get_size(&generic_sq->wq);
sq_stride = MLX5_SEND_WQE_BB;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "Common Config");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "Common Config");
if (err)
goto unlock;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "SQ");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "SQ");
if (err)
goto unlock;
@@ -210,15 +238,15 @@ static int mlx5e_tx_reporter_diagnose(struct devlink_health_reporter *reporter,
if (err)
goto unlock;
- err = mlx5e_reporter_cq_common_diagnose(&generic_sq->cq, fmsg);
+ err = mlx5e_health_cq_common_diag_fmsg(&generic_sq->cq, fmsg);
if (err)
goto unlock;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
goto unlock;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
goto unlock;
@@ -256,7 +284,7 @@ static int mlx5e_tx_reporter_dump_sq(struct mlx5e_priv *priv, struct devlink_fms
if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
return 0;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "SX Slice");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "SX Slice");
if (err)
return err;
@@ -266,15 +294,15 @@ static int mlx5e_tx_reporter_dump_sq(struct mlx5e_priv *priv, struct devlink_fms
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "SQ");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "SQ");
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "QPC");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "QPC");
if (err)
return err;
@@ -286,11 +314,11 @@ static int mlx5e_tx_reporter_dump_sq(struct mlx5e_priv *priv, struct devlink_fms
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "send_buff");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "send_buff");
if (err)
return err;
@@ -300,11 +328,11 @@ static int mlx5e_tx_reporter_dump_sq(struct mlx5e_priv *priv, struct devlink_fms
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
- return mlx5e_reporter_named_obj_nest_end(fmsg);
+ return mlx5e_health_fmsg_named_obj_nest_end(fmsg);
}
static int mlx5e_tx_reporter_dump_all_sqs(struct mlx5e_priv *priv,
@@ -316,7 +344,7 @@ static int mlx5e_tx_reporter_dump_all_sqs(struct mlx5e_priv *priv,
if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
return 0;
- err = mlx5e_reporter_named_obj_nest_start(fmsg, "SX Slice");
+ err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "SX Slice");
if (err)
return err;
@@ -326,7 +354,7 @@ static int mlx5e_tx_reporter_dump_all_sqs(struct mlx5e_priv *priv,
if (err)
return err;
- err = mlx5e_reporter_named_obj_nest_end(fmsg);
+ err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
if (err)
return err;
@@ -384,9 +412,11 @@ int mlx5e_reporter_tx_timeout(struct mlx5e_txqsq *sq)
{
struct mlx5e_priv *priv = sq->channel->priv;
char err_str[MLX5E_REPORTER_PER_Q_MAX_LEN];
+ struct mlx5e_tx_timeout_ctx to_ctx = {};
struct mlx5e_err_ctx err_ctx = {};
- err_ctx.ctx = sq;
+ to_ctx.sq = sq;
+ err_ctx.ctx = &to_ctx;
err_ctx.recover = mlx5e_tx_reporter_timeout_recover;
err_ctx.dump = mlx5e_tx_reporter_dump_sq;
snprintf(err_str, sizeof(err_str),
@@ -394,7 +424,8 @@ int mlx5e_reporter_tx_timeout(struct mlx5e_txqsq *sq)
sq->channel->ix, sq->sqn, sq->cq.mcq.cqn, sq->cc, sq->pc,
jiffies_to_usecs(jiffies - sq->txq->trans_start));
- return mlx5e_health_report(priv, priv->tx_reporter, err_str, &err_ctx);
+ mlx5e_health_report(priv, priv->tx_reporter, err_str, &err_ctx);
+ return to_ctx.status;
}
static const struct devlink_health_reporter_ops mlx5_tx_reporter_ops = {
@@ -406,25 +437,19 @@ static const struct devlink_health_reporter_ops mlx5_tx_reporter_ops = {
#define MLX5_REPORTER_TX_GRACEFUL_PERIOD 500
-int mlx5e_reporter_tx_create(struct mlx5e_priv *priv)
+void mlx5e_reporter_tx_create(struct mlx5e_priv *priv)
{
struct devlink_health_reporter *reporter;
- struct mlx5_core_dev *mdev = priv->mdev;
- struct devlink *devlink;
-
- devlink = priv_to_devlink(mdev);
- reporter =
- devlink_health_reporter_create(devlink, &mlx5_tx_reporter_ops,
- MLX5_REPORTER_TX_GRACEFUL_PERIOD,
- priv);
+
+ reporter = devlink_port_health_reporter_create(&priv->dl_port, &mlx5_tx_reporter_ops,
+ MLX5_REPORTER_TX_GRACEFUL_PERIOD, priv);
if (IS_ERR(reporter)) {
netdev_warn(priv->netdev,
"Failed to create tx reporter, err = %ld\n",
PTR_ERR(reporter));
- return PTR_ERR(reporter);
+ return;
}
priv->tx_reporter = reporter;
- return 0;
}
void mlx5e_reporter_tx_destroy(struct mlx5e_priv *priv)
@@ -432,5 +457,5 @@ void mlx5e_reporter_tx_destroy(struct mlx5e_priv *priv)
if (!priv->tx_reporter)
return;
- devlink_health_reporter_destroy(priv->tx_reporter);
+ devlink_port_health_reporter_destroy(priv->tx_reporter);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
index aad1c29b23db..c6bc9224c3b1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
@@ -16,6 +16,8 @@
#include "esw/chains.h"
#include "en/tc_ct.h"
+#include "en/mod_hdr.h"
+#include "en/mapping.h"
#include "en.h"
#include "en_tc.h"
#include "en_rep.h"
@@ -30,6 +32,9 @@
#define MLX5_FTE_ID_MAX GENMASK(MLX5_FTE_ID_BITS - 1, 0)
#define MLX5_FTE_ID_MASK MLX5_FTE_ID_MAX
+#define MLX5_CT_LABELS_BITS (mlx5e_tc_attr_to_reg_mappings[LABELS_TO_REG].mlen * 8)
+#define MLX5_CT_LABELS_MASK GENMASK(MLX5_CT_LABELS_BITS - 1, 0)
+
#define ct_dbg(fmt, args...)\
netdev_dbg(ct_priv->netdev, "ct_debug: " fmt "\n", ##args)
@@ -39,10 +44,14 @@ struct mlx5_tc_ct_priv {
struct idr fte_ids;
struct xarray tuple_ids;
struct rhashtable zone_ht;
+ struct rhashtable ct_tuples_ht;
+ struct rhashtable ct_tuples_nat_ht;
struct mlx5_flow_table *ct;
struct mlx5_flow_table *ct_nat;
struct mlx5_flow_table *post_ct;
struct mutex control_lock; /* guards parallel adds/dels */
+ struct mapping_ctx *zone_mapping;
+ struct mapping_ctx *labels_mapping;
};
struct mlx5_ct_flow {
@@ -57,8 +66,8 @@ struct mlx5_ct_flow {
struct mlx5_ct_zone_rule {
struct mlx5_flow_handle *rule;
+ struct mlx5e_mod_hdr_handle *mh;
struct mlx5_esw_flow_attr attr;
- int tupleid;
bool nat;
};
@@ -74,6 +83,7 @@ struct mlx5_tc_ct_pre {
struct mlx5_ct_ft {
struct rhash_head node;
u16 zone;
+ u32 zone_restore_id;
refcount_t refcount;
struct nf_flowtable *nf_ft;
struct mlx5_tc_ct_priv *ct_priv;
@@ -82,12 +92,37 @@ struct mlx5_ct_ft {
struct mlx5_tc_ct_pre pre_ct_nat;
};
-struct mlx5_ct_entry {
+struct mlx5_ct_tuple {
+ u16 addr_type;
+ __be16 n_proto;
+ u8 ip_proto;
+ struct {
+ union {
+ __be32 src_v4;
+ struct in6_addr src_v6;
+ };
+ union {
+ __be32 dst_v4;
+ struct in6_addr dst_v6;
+ };
+ } ip;
+ struct {
+ __be16 src;
+ __be16 dst;
+ } port;
+
u16 zone;
+};
+
+struct mlx5_ct_entry {
struct rhash_head node;
+ struct rhash_head tuple_node;
+ struct rhash_head tuple_nat_node;
struct mlx5_fc *counter;
unsigned long cookie;
unsigned long restore_cookie;
+ struct mlx5_ct_tuple tuple;
+ struct mlx5_ct_tuple tuple_nat;
struct mlx5_ct_zone_rule zone_rules[2];
};
@@ -106,6 +141,22 @@ static const struct rhashtable_params zone_params = {
.automatic_shrinking = true,
};
+static const struct rhashtable_params tuples_ht_params = {
+ .head_offset = offsetof(struct mlx5_ct_entry, tuple_node),
+ .key_offset = offsetof(struct mlx5_ct_entry, tuple),
+ .key_len = sizeof(((struct mlx5_ct_entry *)0)->tuple),
+ .automatic_shrinking = true,
+ .min_size = 16 * 1024,
+};
+
+static const struct rhashtable_params tuples_nat_ht_params = {
+ .head_offset = offsetof(struct mlx5_ct_entry, tuple_nat_node),
+ .key_offset = offsetof(struct mlx5_ct_entry, tuple_nat),
+ .key_len = sizeof(((struct mlx5_ct_entry *)0)->tuple_nat),
+ .automatic_shrinking = true,
+ .min_size = 16 * 1024,
+};
+
static struct mlx5_tc_ct_priv *
mlx5_tc_ct_get_ct_priv(struct mlx5e_priv *priv)
{
@@ -119,6 +170,115 @@ mlx5_tc_ct_get_ct_priv(struct mlx5e_priv *priv)
}
static int
+mlx5_tc_ct_rule_to_tuple(struct mlx5_ct_tuple *tuple, struct flow_rule *rule)
+{
+ struct flow_match_control control;
+ struct flow_match_basic basic;
+
+ flow_rule_match_basic(rule, &basic);
+ flow_rule_match_control(rule, &control);
+
+ tuple->n_proto = basic.key->n_proto;
+ tuple->ip_proto = basic.key->ip_proto;
+ tuple->addr_type = control.key->addr_type;
+
+ if (tuple->addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
+ struct flow_match_ipv4_addrs match;
+
+ flow_rule_match_ipv4_addrs(rule, &match);
+ tuple->ip.src_v4 = match.key->src;
+ tuple->ip.dst_v4 = match.key->dst;
+ } else if (tuple->addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
+ struct flow_match_ipv6_addrs match;
+
+ flow_rule_match_ipv6_addrs(rule, &match);
+ tuple->ip.src_v6 = match.key->src;
+ tuple->ip.dst_v6 = match.key->dst;
+ } else {
+ return -EOPNOTSUPP;
+ }
+
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
+ struct flow_match_ports match;
+
+ flow_rule_match_ports(rule, &match);
+ switch (tuple->ip_proto) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ tuple->port.src = match.key->src;
+ tuple->port.dst = match.key->dst;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ } else {
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int
+mlx5_tc_ct_rule_to_tuple_nat(struct mlx5_ct_tuple *tuple,
+ struct flow_rule *rule)
+{
+ struct flow_action *flow_action = &rule->action;
+ struct flow_action_entry *act;
+ u32 offset, val, ip6_offset;
+ int i;
+
+ flow_action_for_each(i, act, flow_action) {
+ if (act->id != FLOW_ACTION_MANGLE)
+ continue;
+
+ offset = act->mangle.offset;
+ val = act->mangle.val;
+ switch (act->mangle.htype) {
+ case FLOW_ACT_MANGLE_HDR_TYPE_IP4:
+ if (offset == offsetof(struct iphdr, saddr))
+ tuple->ip.src_v4 = cpu_to_be32(val);
+ else if (offset == offsetof(struct iphdr, daddr))
+ tuple->ip.dst_v4 = cpu_to_be32(val);
+ else
+ return -EOPNOTSUPP;
+ break;
+
+ case FLOW_ACT_MANGLE_HDR_TYPE_IP6:
+ ip6_offset = (offset - offsetof(struct ipv6hdr, saddr));
+ ip6_offset /= 4;
+ if (ip6_offset < 8)
+ tuple->ip.src_v6.s6_addr32[ip6_offset] = cpu_to_be32(val);
+ else
+ return -EOPNOTSUPP;
+ break;
+
+ case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
+ if (offset == offsetof(struct tcphdr, source))
+ tuple->port.src = cpu_to_be16(val);
+ else if (offset == offsetof(struct tcphdr, dest))
+ tuple->port.dst = cpu_to_be16(val);
+ else
+ return -EOPNOTSUPP;
+ break;
+
+ case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
+ if (offset == offsetof(struct udphdr, source))
+ tuple->port.src = cpu_to_be16(val);
+ else if (offset == offsetof(struct udphdr, dest))
+ tuple->port.dst = cpu_to_be16(val);
+ else
+ return -EOPNOTSUPP;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
+static int
mlx5_tc_ct_set_tuple_match(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec,
struct flow_rule *rule)
{
@@ -243,11 +403,12 @@ mlx5_tc_ct_entry_del_rule(struct mlx5_tc_ct_priv *ct_priv,
struct mlx5_esw_flow_attr *attr = &zone_rule->attr;
struct mlx5_eswitch *esw = ct_priv->esw;
- ct_dbg("Deleting ct entry rule in zone %d", entry->zone);
+ ct_dbg("Deleting ct entry rule in zone %d", entry->tuple.zone);
mlx5_eswitch_del_offloaded_rule(esw, zone_rule->rule, attr);
- mlx5_modify_header_dealloc(esw->dev, attr->modify_hdr);
- xa_erase(&ct_priv->tuple_ids, zone_rule->tupleid);
+ mlx5e_mod_hdr_detach(ct_priv->esw->dev,
+ &esw->offloads.mod_hdr, zone_rule->mh);
+ mapping_remove(ct_priv->labels_mapping, attr->ct_attr.ct_labels_id);
}
static void
@@ -280,8 +441,8 @@ mlx5_tc_ct_entry_set_registers(struct mlx5_tc_ct_priv *ct_priv,
struct mlx5e_tc_mod_hdr_acts *mod_acts,
u8 ct_state,
u32 mark,
- u32 label,
- u32 tupleid)
+ u32 labels_id,
+ u8 zone_restore_id)
{
struct mlx5_eswitch *esw = ct_priv->esw;
int err;
@@ -297,12 +458,12 @@ mlx5_tc_ct_entry_set_registers(struct mlx5_tc_ct_priv *ct_priv,
return err;
err = mlx5e_tc_match_to_reg_set(esw->dev, mod_acts,
- LABELS_TO_REG, label);
+ LABELS_TO_REG, labels_id);
if (err)
return err;
err = mlx5e_tc_match_to_reg_set(esw->dev, mod_acts,
- TUPLEID_TO_REG, tupleid);
+ ZONE_RESTORE_TO_REG, zone_restore_id);
if (err)
return err;
@@ -429,12 +590,10 @@ static int
mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
struct mlx5_esw_flow_attr *attr,
struct flow_rule *flow_rule,
- u32 tupleid,
- bool nat)
+ struct mlx5e_mod_hdr_handle **mh,
+ u8 zone_restore_id, bool nat)
{
struct mlx5e_tc_mod_hdr_acts mod_acts = {};
- struct mlx5_eswitch *esw = ct_priv->esw;
- struct mlx5_modify_hdr *mod_hdr;
struct flow_action_entry *meta;
u16 ct_state = 0;
int err;
@@ -443,13 +602,10 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
if (!meta)
return -EOPNOTSUPP;
- if (meta->ct_metadata.labels[1] ||
- meta->ct_metadata.labels[2] ||
- meta->ct_metadata.labels[3]) {
- ct_dbg("Failed to offload ct entry due to unsupported label");
+ err = mapping_add(ct_priv->labels_mapping, meta->ct_metadata.labels,
+ &attr->ct_attr.ct_labels_id);
+ if (err)
return -EOPNOTSUPP;
- }
-
if (nat) {
err = mlx5_tc_ct_entry_create_nat(ct_priv, flow_rule,
&mod_acts);
@@ -463,25 +619,27 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
err = mlx5_tc_ct_entry_set_registers(ct_priv, &mod_acts,
ct_state,
meta->ct_metadata.mark,
- meta->ct_metadata.labels[0],
- tupleid);
+ attr->ct_attr.ct_labels_id,
+ zone_restore_id);
if (err)
goto err_mapping;
- mod_hdr = mlx5_modify_header_alloc(esw->dev, MLX5_FLOW_NAMESPACE_FDB,
- mod_acts.num_actions,
- mod_acts.actions);
- if (IS_ERR(mod_hdr)) {
- err = PTR_ERR(mod_hdr);
+ *mh = mlx5e_mod_hdr_attach(ct_priv->esw->dev,
+ &ct_priv->esw->offloads.mod_hdr,
+ MLX5_FLOW_NAMESPACE_FDB,
+ &mod_acts);
+ if (IS_ERR(*mh)) {
+ err = PTR_ERR(*mh);
goto err_mapping;
}
- attr->modify_hdr = mod_hdr;
+ attr->modify_hdr = mlx5e_mod_hdr_get(*mh);
dealloc_mod_hdr_actions(&mod_acts);
return 0;
err_mapping:
dealloc_mod_hdr_actions(&mod_acts);
+ mapping_remove(ct_priv->labels_mapping, attr->ct_attr.ct_labels_id);
return err;
}
@@ -489,13 +647,12 @@ static int
mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
struct flow_rule *flow_rule,
struct mlx5_ct_entry *entry,
- bool nat)
+ bool nat, u8 zone_restore_id)
{
struct mlx5_ct_zone_rule *zone_rule = &entry->zone_rules[nat];
struct mlx5_esw_flow_attr *attr = &zone_rule->attr;
struct mlx5_eswitch *esw = ct_priv->esw;
struct mlx5_flow_spec *spec = NULL;
- u32 tupleid;
int err;
zone_rule->nat = nat;
@@ -504,18 +661,9 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
if (!spec)
return -ENOMEM;
- /* Get tuple unique id */
- err = xa_alloc(&ct_priv->tuple_ids, &tupleid, zone_rule,
- XA_LIMIT(1, TUPLE_ID_MAX), GFP_KERNEL);
- if (err) {
- netdev_warn(ct_priv->netdev,
- "Failed to allocate tuple id, err: %d\n", err);
- goto err_xa_alloc;
- }
- zone_rule->tupleid = tupleid;
-
err = mlx5_tc_ct_entry_create_mod_hdr(ct_priv, attr, flow_rule,
- tupleid, nat);
+ &zone_rule->mh,
+ zone_restore_id, nat);
if (err) {
ct_dbg("Failed to create ct entry mod hdr");
goto err_mod_hdr;
@@ -533,7 +681,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
mlx5_tc_ct_set_tuple_match(netdev_priv(ct_priv->netdev), spec, flow_rule);
mlx5e_tc_match_to_reg_match(spec, ZONE_TO_REG,
- entry->zone & MLX5_CT_ZONE_MASK,
+ entry->tuple.zone & MLX5_CT_ZONE_MASK,
MLX5_CT_ZONE_MASK);
zone_rule->rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
@@ -544,15 +692,14 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
}
kfree(spec);
- ct_dbg("Offloaded ct entry rule in zone %d", entry->zone);
+ ct_dbg("Offloaded ct entry rule in zone %d", entry->tuple.zone);
return 0;
err_rule:
- mlx5_modify_header_dealloc(esw->dev, attr->modify_hdr);
+ mlx5e_mod_hdr_detach(ct_priv->esw->dev,
+ &esw->offloads.mod_hdr, zone_rule->mh);
err_mod_hdr:
- xa_erase(&ct_priv->tuple_ids, zone_rule->tupleid);
-err_xa_alloc:
kfree(spec);
return err;
}
@@ -560,7 +707,8 @@ err_xa_alloc:
static int
mlx5_tc_ct_entry_add_rules(struct mlx5_tc_ct_priv *ct_priv,
struct flow_rule *flow_rule,
- struct mlx5_ct_entry *entry)
+ struct mlx5_ct_entry *entry,
+ u8 zone_restore_id)
{
struct mlx5_eswitch *esw = ct_priv->esw;
int err;
@@ -572,11 +720,13 @@ mlx5_tc_ct_entry_add_rules(struct mlx5_tc_ct_priv *ct_priv,
return err;
}
- err = mlx5_tc_ct_entry_add_rule(ct_priv, flow_rule, entry, false);
+ err = mlx5_tc_ct_entry_add_rule(ct_priv, flow_rule, entry, false,
+ zone_restore_id);
if (err)
goto err_orig;
- err = mlx5_tc_ct_entry_add_rule(ct_priv, flow_rule, entry, true);
+ err = mlx5_tc_ct_entry_add_rule(ct_priv, flow_rule, entry, true,
+ zone_restore_id);
if (err)
goto err_nat;
@@ -613,11 +763,35 @@ mlx5_tc_ct_block_flow_offload_add(struct mlx5_ct_ft *ft,
if (!entry)
return -ENOMEM;
- entry->zone = ft->zone;
+ entry->tuple.zone = ft->zone;
entry->cookie = flow->cookie;
entry->restore_cookie = meta_action->ct_metadata.cookie;
- err = mlx5_tc_ct_entry_add_rules(ct_priv, flow_rule, entry);
+ err = mlx5_tc_ct_rule_to_tuple(&entry->tuple, flow_rule);
+ if (err)
+ goto err_set;
+
+ memcpy(&entry->tuple_nat, &entry->tuple, sizeof(entry->tuple));
+ err = mlx5_tc_ct_rule_to_tuple_nat(&entry->tuple_nat, flow_rule);
+ if (err)
+ goto err_set;
+
+ err = rhashtable_insert_fast(&ct_priv->ct_tuples_ht,
+ &entry->tuple_node,
+ tuples_ht_params);
+ if (err)
+ goto err_tuple;
+
+ if (memcmp(&entry->tuple, &entry->tuple_nat, sizeof(entry->tuple))) {
+ err = rhashtable_insert_fast(&ct_priv->ct_tuples_nat_ht,
+ &entry->tuple_nat_node,
+ tuples_nat_ht_params);
+ if (err)
+ goto err_tuple_nat;
+ }
+
+ err = mlx5_tc_ct_entry_add_rules(ct_priv, flow_rule, entry,
+ ft->zone_restore_id);
if (err)
goto err_rules;
@@ -631,12 +805,34 @@ mlx5_tc_ct_block_flow_offload_add(struct mlx5_ct_ft *ft,
err_insert:
mlx5_tc_ct_entry_del_rules(ct_priv, entry);
err_rules:
+ rhashtable_remove_fast(&ct_priv->ct_tuples_nat_ht,
+ &entry->tuple_nat_node, tuples_nat_ht_params);
+err_tuple_nat:
+ if (entry->tuple_node.next)
+ rhashtable_remove_fast(&ct_priv->ct_tuples_ht,
+ &entry->tuple_node,
+ tuples_ht_params);
+err_tuple:
+err_set:
kfree(entry);
netdev_warn(ct_priv->netdev,
"Failed to offload ct entry, err: %d\n", err);
return err;
}
+static void
+mlx5_tc_ct_del_ft_entry(struct mlx5_tc_ct_priv *ct_priv,
+ struct mlx5_ct_entry *entry)
+{
+ mlx5_tc_ct_entry_del_rules(ct_priv, entry);
+ if (entry->tuple_node.next)
+ rhashtable_remove_fast(&ct_priv->ct_tuples_nat_ht,
+ &entry->tuple_nat_node,
+ tuples_nat_ht_params);
+ rhashtable_remove_fast(&ct_priv->ct_tuples_ht, &entry->tuple_node,
+ tuples_ht_params);
+}
+
static int
mlx5_tc_ct_block_flow_offload_del(struct mlx5_ct_ft *ft,
struct flow_cls_offload *flow)
@@ -649,7 +845,7 @@ mlx5_tc_ct_block_flow_offload_del(struct mlx5_ct_ft *ft,
if (!entry)
return -ENOENT;
- mlx5_tc_ct_entry_del_rules(ft->ct_priv, entry);
+ mlx5_tc_ct_del_ft_entry(ft->ct_priv, entry);
WARN_ON(rhashtable_remove_fast(&ft->ct_entries_ht,
&entry->node,
cts_ht_params));
@@ -672,7 +868,7 @@ mlx5_tc_ct_block_flow_offload_stats(struct mlx5_ct_ft *ft,
return -ENOENT;
mlx5_fc_query_cached(entry->counter, &bytes, &packets, &lastuse);
- flow_stats_update(&f->stats, bytes, packets, lastuse,
+ flow_stats_update(&f->stats, bytes, packets, 0, lastuse,
FLOW_ACTION_HW_STATS_DELAYED);
return 0;
@@ -702,10 +898,71 @@ mlx5_tc_ct_block_flow_offload(enum tc_setup_type type, void *type_data,
return -EOPNOTSUPP;
}
+static bool
+mlx5_tc_ct_skb_to_tuple(struct sk_buff *skb, struct mlx5_ct_tuple *tuple,
+ u16 zone)
+{
+ struct flow_keys flow_keys;
+
+ skb_reset_network_header(skb);
+ skb_flow_dissect_flow_keys(skb, &flow_keys, 0);
+
+ tuple->zone = zone;
+
+ if (flow_keys.basic.ip_proto != IPPROTO_TCP &&
+ flow_keys.basic.ip_proto != IPPROTO_UDP)
+ return false;
+
+ tuple->port.src = flow_keys.ports.src;
+ tuple->port.dst = flow_keys.ports.dst;
+ tuple->n_proto = flow_keys.basic.n_proto;
+ tuple->ip_proto = flow_keys.basic.ip_proto;
+
+ switch (flow_keys.basic.n_proto) {
+ case htons(ETH_P_IP):
+ tuple->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+ tuple->ip.src_v4 = flow_keys.addrs.v4addrs.src;
+ tuple->ip.dst_v4 = flow_keys.addrs.v4addrs.dst;
+ break;
+
+ case htons(ETH_P_IPV6):
+ tuple->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+ tuple->ip.src_v6 = flow_keys.addrs.v6addrs.src;
+ tuple->ip.dst_v6 = flow_keys.addrs.v6addrs.dst;
+ break;
+ default:
+ goto out;
+ }
+
+ return true;
+
+out:
+ return false;
+}
+
+int
+mlx5_tc_ct_add_no_trk_match(struct mlx5e_priv *priv,
+ struct mlx5_flow_spec *spec)
+{
+ u32 ctstate = 0, ctstate_mask = 0;
+
+ mlx5e_tc_match_to_reg_get_match(spec, CTSTATE_TO_REG,
+ &ctstate, &ctstate_mask);
+ if (ctstate_mask)
+ return -EOPNOTSUPP;
+
+ ctstate_mask |= MLX5_CT_STATE_TRK_BIT;
+ mlx5e_tc_match_to_reg_match(spec, CTSTATE_TO_REG,
+ ctstate, ctstate_mask);
+
+ return 0;
+}
+
int
mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
struct mlx5_flow_spec *spec,
struct flow_cls_offload *f,
+ struct mlx5_ct_attr *ct_attr,
struct netlink_ext_ack *extack)
{
struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv);
@@ -716,6 +973,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
u16 ct_state_on, ct_state_off;
u16 ct_state, ct_state_mask;
struct flow_match_ct match;
+ u32 ct_labels[4];
if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
return 0;
@@ -742,12 +1000,6 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
return -EOPNOTSUPP;
}
- if (mask->ct_labels[1] || mask->ct_labels[2] || mask->ct_labels[3]) {
- NL_SET_ERR_MSG_MOD(extack,
- "only lower 32bits of ct_labels are supported for offload");
- return -EOPNOTSUPP;
- }
-
ct_state_on = ct_state & ct_state_mask;
ct_state_off = (ct_state & ct_state_mask) ^ ct_state_mask;
trk = ct_state_on & TCA_FLOWER_KEY_CT_FLAGS_TRACKED;
@@ -776,10 +1028,17 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
if (mask->ct_mark)
mlx5e_tc_match_to_reg_match(spec, MARK_TO_REG,
key->ct_mark, mask->ct_mark);
- if (mask->ct_labels[0])
- mlx5e_tc_match_to_reg_match(spec, LABELS_TO_REG,
- key->ct_labels[0],
- mask->ct_labels[0]);
+ if (mask->ct_labels[0] || mask->ct_labels[1] || mask->ct_labels[2] ||
+ mask->ct_labels[3]) {
+ ct_labels[0] = key->ct_labels[0] & mask->ct_labels[0];
+ ct_labels[1] = key->ct_labels[1] & mask->ct_labels[1];
+ ct_labels[2] = key->ct_labels[2] & mask->ct_labels[2];
+ ct_labels[3] = key->ct_labels[3] & mask->ct_labels[3];
+ if (mapping_add(ct_priv->labels_mapping, ct_labels, &ct_attr->ct_labels_id))
+ return -EOPNOTSUPP;
+ mlx5e_tc_match_to_reg_match(spec, LABELS_TO_REG, ct_attr->ct_labels_id,
+ MLX5_CT_LABELS_MASK);
+ }
return 0;
}
@@ -1054,6 +1313,10 @@ mlx5_tc_ct_add_ft_cb(struct mlx5_tc_ct_priv *ct_priv, u16 zone,
if (!ft)
return ERR_PTR(-ENOMEM);
+ err = mapping_add(ct_priv->zone_mapping, &zone, &ft->zone_restore_id);
+ if (err)
+ goto err_mapping;
+
ft->zone = zone;
ft->nf_ft = nf_ft;
ft->ct_priv = ct_priv;
@@ -1086,6 +1349,8 @@ err_insert:
err_init:
mlx5_tc_ct_free_pre_ct_tables(ft);
err_alloc_pre_ct:
+ mapping_remove(ct_priv->zone_mapping, ft->zone_restore_id);
+err_mapping:
kfree(ft);
return ERR_PTR(err);
}
@@ -1096,7 +1361,7 @@ mlx5_tc_ct_flush_ft_entry(void *ptr, void *arg)
struct mlx5_tc_ct_priv *ct_priv = arg;
struct mlx5_ct_entry *entry = ptr;
- mlx5_tc_ct_entry_del_rules(ct_priv, entry);
+ mlx5_tc_ct_del_ft_entry(ct_priv, entry);
kfree(entry);
}
@@ -1113,6 +1378,7 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
mlx5_tc_ct_flush_ft_entry,
ct_priv);
mlx5_tc_ct_free_pre_ct_tables(ft);
+ mapping_remove(ct_priv->zone_mapping, ft->zone_restore_id);
kfree(ft);
}
@@ -1138,8 +1404,9 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
* + tuple + zone match +
* +--------------------+
* | set mark
- * | set label
+ * | set labels_id
* | set established
+ * | set zone_restore
* | do nat (if needed)
* v
* +--------------+
@@ -1147,12 +1414,11 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
* + fte_id match +------------------------>
* +--------------+
*/
-static int
+static struct mlx5_flow_handle *
__mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow,
struct mlx5_flow_spec *orig_spec,
- struct mlx5_esw_flow_attr *attr,
- struct mlx5_flow_handle **flow_rule)
+ struct mlx5_esw_flow_attr *attr)
{
struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv);
bool nat = attr->ct_attr.ct_action & TCA_CT_ACT_NAT;
@@ -1172,7 +1438,7 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
if (!post_ct_spec || !ct_flow) {
kfree(post_ct_spec);
kfree(ct_flow);
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
}
/* Register for CT established events */
@@ -1293,11 +1559,10 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
}
attr->ct_attr.ct_flow = ct_flow;
- *flow_rule = ct_flow->post_ct_rule;
dealloc_mod_hdr_actions(&pre_mod_acts);
kfree(post_ct_spec);
- return 0;
+ return rule;
err_insert_orig:
mlx5_eswitch_del_offloaded_rule(ct_priv->esw, ct_flow->post_ct_rule,
@@ -1315,16 +1580,14 @@ err_ft:
kfree(post_ct_spec);
kfree(ct_flow);
netdev_warn(priv->netdev, "Failed to offload ct flow, err %d\n", err);
- return err;
+ return ERR_PTR(err);
}
-static int
+static struct mlx5_flow_handle *
__mlx5_tc_ct_flow_offload_clear(struct mlx5e_priv *priv,
- struct mlx5e_tc_flow *flow,
struct mlx5_flow_spec *orig_spec,
struct mlx5_esw_flow_attr *attr,
- struct mlx5e_tc_mod_hdr_acts *mod_acts,
- struct mlx5_flow_handle **flow_rule)
+ struct mlx5e_tc_mod_hdr_acts *mod_acts)
{
struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv);
struct mlx5_eswitch *esw = ct_priv->esw;
@@ -1336,7 +1599,7 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5e_priv *priv,
ct_flow = kzalloc(sizeof(*ct_flow), GFP_KERNEL);
if (!ct_flow)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
/* Base esw attributes on original rule attribute */
pre_ct_attr = &ct_flow->pre_ct_attr;
@@ -1371,16 +1634,14 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5e_priv *priv,
attr->ct_attr.ct_flow = ct_flow;
ct_flow->pre_ct_rule = rule;
- *flow_rule = rule;
-
- return 0;
+ return rule;
err_insert:
mlx5_modify_header_dealloc(priv->mdev, mod_hdr);
err_set_registers:
netdev_warn(priv->netdev,
"Failed to offload ct clear flow, err %d\n", err);
- return err;
+ return ERR_PTR(err);
}
struct mlx5_flow_handle *
@@ -1392,22 +1653,18 @@ mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
{
bool clear_action = attr->ct_attr.ct_action & TCA_CT_ACT_CLEAR;
struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv);
- struct mlx5_flow_handle *rule = ERR_PTR(-EINVAL);
- int err;
+ struct mlx5_flow_handle *rule;
if (!ct_priv)
return ERR_PTR(-EOPNOTSUPP);
mutex_lock(&ct_priv->control_lock);
+
if (clear_action)
- err = __mlx5_tc_ct_flow_offload_clear(priv, flow, spec, attr,
- mod_hdr_acts, &rule);
+ rule = __mlx5_tc_ct_flow_offload_clear(priv, spec, attr, mod_hdr_acts);
else
- err = __mlx5_tc_ct_flow_offload(priv, flow, spec, attr,
- &rule);
+ rule = __mlx5_tc_ct_flow_offload(priv, flow, spec, attr);
mutex_unlock(&ct_priv->control_lock);
- if (err)
- return ERR_PTR(err);
return rule;
}
@@ -1535,6 +1792,18 @@ mlx5_tc_ct_init(struct mlx5_rep_uplink_priv *uplink_priv)
goto err_alloc;
}
+ ct_priv->zone_mapping = mapping_create(sizeof(u16), 0, true);
+ if (IS_ERR(ct_priv->zone_mapping)) {
+ err = PTR_ERR(ct_priv->zone_mapping);
+ goto err_mapping_zone;
+ }
+
+ ct_priv->labels_mapping = mapping_create(sizeof(u32) * 4, 0, true);
+ if (IS_ERR(ct_priv->labels_mapping)) {
+ err = PTR_ERR(ct_priv->labels_mapping);
+ goto err_mapping_labels;
+ }
+
ct_priv->esw = esw;
ct_priv->netdev = rpriv->netdev;
ct_priv->ct = mlx5_esw_chains_create_global_table(esw);
@@ -1561,9 +1830,10 @@ mlx5_tc_ct_init(struct mlx5_rep_uplink_priv *uplink_priv)
}
idr_init(&ct_priv->fte_ids);
- xa_init_flags(&ct_priv->tuple_ids, XA_FLAGS_ALLOC1);
mutex_init(&ct_priv->control_lock);
rhashtable_init(&ct_priv->zone_ht, &zone_params);
+ rhashtable_init(&ct_priv->ct_tuples_ht, &tuples_ht_params);
+ rhashtable_init(&ct_priv->ct_tuples_nat_ht, &tuples_nat_ht_params);
/* Done, set ct_priv to know it initializted */
uplink_priv->ct_priv = ct_priv;
@@ -1575,6 +1845,10 @@ err_post_ct_tbl:
err_ct_nat_tbl:
mlx5_esw_chains_destroy_global_table(esw, ct_priv->ct);
err_ct_tbl:
+ mapping_destroy(ct_priv->labels_mapping);
+err_mapping_labels:
+ mapping_destroy(ct_priv->zone_mapping);
+err_mapping_zone:
kfree(ct_priv);
err_alloc:
err_support:
@@ -1593,10 +1867,13 @@ mlx5_tc_ct_clean(struct mlx5_rep_uplink_priv *uplink_priv)
mlx5_esw_chains_destroy_global_table(ct_priv->esw, ct_priv->post_ct);
mlx5_esw_chains_destroy_global_table(ct_priv->esw, ct_priv->ct_nat);
mlx5_esw_chains_destroy_global_table(ct_priv->esw, ct_priv->ct);
+ mapping_destroy(ct_priv->zone_mapping);
+ mapping_destroy(ct_priv->labels_mapping);
+ rhashtable_destroy(&ct_priv->ct_tuples_ht);
+ rhashtable_destroy(&ct_priv->ct_tuples_nat_ht);
rhashtable_destroy(&ct_priv->zone_ht);
mutex_destroy(&ct_priv->control_lock);
- xa_destroy(&ct_priv->tuple_ids);
idr_destroy(&ct_priv->fte_ids);
kfree(ct_priv);
@@ -1605,22 +1882,30 @@ mlx5_tc_ct_clean(struct mlx5_rep_uplink_priv *uplink_priv)
bool
mlx5e_tc_ct_restore_flow(struct mlx5_rep_uplink_priv *uplink_priv,
- struct sk_buff *skb, u32 tupleid)
+ struct sk_buff *skb, u8 zone_restore_id)
{
struct mlx5_tc_ct_priv *ct_priv = uplink_priv->ct_priv;
- struct mlx5_ct_zone_rule *zone_rule;
+ struct mlx5_ct_tuple tuple = {};
struct mlx5_ct_entry *entry;
+ u16 zone;
- if (!ct_priv || !tupleid)
+ if (!ct_priv || !zone_restore_id)
return true;
- zone_rule = xa_load(&ct_priv->tuple_ids, tupleid);
- if (!zone_rule)
+ if (mapping_find(ct_priv->zone_mapping, zone_restore_id, &zone))
return false;
- entry = container_of(zone_rule, struct mlx5_ct_entry,
- zone_rules[zone_rule->nat]);
- tcf_ct_flow_table_restore_skb(skb, entry->restore_cookie);
+ if (!mlx5_tc_ct_skb_to_tuple(skb, &tuple, zone))
+ return false;
+ entry = rhashtable_lookup_fast(&ct_priv->ct_tuples_ht, &tuple,
+ tuples_ht_params);
+ if (!entry)
+ entry = rhashtable_lookup_fast(&ct_priv->ct_tuples_nat_ht,
+ &tuple, tuples_nat_ht_params);
+ if (!entry)
+ return false;
+
+ tcf_ct_flow_table_restore_skb(skb, entry->restore_cookie);
return true;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h
index 626f6c04882e..3baef917a677 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h
@@ -25,6 +25,7 @@ struct mlx5_ct_attr {
u16 ct_action;
struct mlx5_ct_flow *ct_flow;
struct nf_flowtable *nf_ft;
+ u32 ct_labels_id;
};
#define zone_to_reg_ct {\
@@ -67,16 +68,17 @@ struct mlx5_ct_attr {
misc_parameters_2.metadata_reg_c_5),\
}
-#define tupleid_to_reg_ct {\
+#define zone_restore_to_reg_ct {\
.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_1,\
.moffset = 0,\
- .mlen = 3,\
+ .mlen = 1,\
.soffset = MLX5_BYTE_OFF(fte_match_param,\
- misc_parameters_2.metadata_reg_c_1),\
+ misc_parameters_2.metadata_reg_c_1) + 3,\
}
-#define TUPLE_ID_BITS (mlx5e_tc_attr_to_reg_mappings[TUPLEID_TO_REG].mlen * 8)
-#define TUPLE_ID_MAX GENMASK(TUPLE_ID_BITS - 1, 0)
+#define REG_MAPPING_MLEN(reg) (mlx5e_tc_attr_to_reg_mappings[reg].mlen)
+#define ZONE_RESTORE_BITS (REG_MAPPING_MLEN(ZONE_RESTORE_TO_REG) * 8)
+#define ZONE_RESTORE_MAX GENMASK(ZONE_RESTORE_BITS - 1, 0)
#if IS_ENABLED(CONFIG_MLX5_TC_CT)
@@ -89,8 +91,12 @@ int
mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
struct mlx5_flow_spec *spec,
struct flow_cls_offload *f,
+ struct mlx5_ct_attr *ct_attr,
struct netlink_ext_ack *extack);
int
+mlx5_tc_ct_add_no_trk_match(struct mlx5e_priv *priv,
+ struct mlx5_flow_spec *spec);
+int
mlx5_tc_ct_parse_action(struct mlx5e_priv *priv,
struct mlx5_esw_flow_attr *attr,
const struct flow_action_entry *act,
@@ -109,7 +115,7 @@ mlx5_tc_ct_delete_flow(struct mlx5e_priv *priv,
bool
mlx5e_tc_ct_restore_flow(struct mlx5_rep_uplink_priv *uplink_priv,
- struct sk_buff *skb, u32 tupleid);
+ struct sk_buff *skb, u8 zone_restore_id);
#else /* CONFIG_MLX5_TC_CT */
@@ -128,6 +134,7 @@ static inline int
mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
struct mlx5_flow_spec *spec,
struct flow_cls_offload *f,
+ struct mlx5_ct_attr *ct_attr,
struct netlink_ext_ack *extack)
{
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
@@ -141,6 +148,13 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
}
static inline int
+mlx5_tc_ct_add_no_trk_match(struct mlx5e_priv *priv,
+ struct mlx5_flow_spec *spec)
+{
+ return 0;
+}
+
+static inline int
mlx5_tc_ct_parse_action(struct mlx5e_priv *priv,
struct mlx5_esw_flow_attr *attr,
const struct flow_action_entry *act,
@@ -170,10 +184,10 @@ mlx5_tc_ct_delete_flow(struct mlx5e_priv *priv,
static inline bool
mlx5e_tc_ct_restore_flow(struct mlx5_rep_uplink_priv *uplink_priv,
- struct sk_buff *skb, u32 tupleid)
+ struct sk_buff *skb, u8 zone_restore_id)
{
- if (!tupleid)
- return true;
+ if (!zone_restore_id)
+ return true;
return false;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
index bfd3e1161bc6..9334c9c3e208 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
@@ -5,14 +5,47 @@
#define __MLX5_EN_TXRX_H___
#include "en.h"
+#include <linux/indirect_call_wrapper.h>
#define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start))
enum mlx5e_icosq_wqe_type {
MLX5E_ICOSQ_WQE_NOP,
MLX5E_ICOSQ_WQE_UMR_RX,
+#ifdef CONFIG_MLX5_EN_TLS
+ MLX5E_ICOSQ_WQE_UMR_TLS,
+ MLX5E_ICOSQ_WQE_SET_PSV_TLS,
+ MLX5E_ICOSQ_WQE_GET_PSV_TLS,
+#endif
};
+/* General */
+void mlx5e_trigger_irq(struct mlx5e_icosq *sq);
+void mlx5e_completion_event(struct mlx5_core_cq *mcq, struct mlx5_eqe *eqe);
+void mlx5e_cq_error_event(struct mlx5_core_cq *mcq, enum mlx5_event event);
+int mlx5e_napi_poll(struct napi_struct *napi, int budget);
+int mlx5e_poll_ico_cq(struct mlx5e_cq *cq);
+
+/* RX */
+void mlx5e_page_dma_unmap(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info);
+void mlx5e_page_release_dynamic(struct mlx5e_rq *rq,
+ struct mlx5e_dma_info *dma_info,
+ bool recycle);
+INDIRECT_CALLABLE_DECLARE(bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq));
+INDIRECT_CALLABLE_DECLARE(bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq));
+int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget);
+void mlx5e_free_rx_descs(struct mlx5e_rq *rq);
+void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq);
+
+/* TX */
+u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
+ struct net_device *sb_dev);
+netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev);
+void mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
+ struct mlx5e_tx_wqe *wqe, u16 pi, bool xmit_more);
+bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget);
+void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq);
+
static inline bool
mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n)
{
@@ -114,9 +147,19 @@ struct mlx5e_icosq_wqe_info {
struct {
struct mlx5e_rq *rq;
} umr;
+#ifdef CONFIG_MLX5_EN_TLS
+ struct {
+ struct mlx5e_ktls_offload_context_rx *priv_rx;
+ } tls_set_params;
+ struct {
+ struct mlx5e_ktls_rx_resync_buf *buf;
+ } tls_get_params;
+#endif
};
};
+void mlx5e_free_icosq_descs(struct mlx5e_icosq *sq);
+
static inline u16 mlx5e_icosq_get_next_pi(struct mlx5e_icosq *sq, u16 size)
{
struct mlx5_wq_cyc *wq = &sq->wq;
@@ -182,7 +225,7 @@ mlx5e_notify_hw(struct mlx5_wq_cyc *wq, u16 pc, void __iomem *uar_map,
static inline bool mlx5e_transport_inline_tx_wqe(struct mlx5_wqe_ctrl_seg *cseg)
{
- return cseg && !!cseg->tisn;
+ return cseg && !!cseg->tis_tir_num;
}
static inline u8
@@ -253,7 +296,7 @@ static inline void mlx5e_rqwq_reset(struct mlx5e_rq *rq)
}
}
-static inline void mlx5e_dump_error_cqe(struct mlx5e_cq *cq, u32 sqn,
+static inline void mlx5e_dump_error_cqe(struct mlx5e_cq *cq, u32 qn,
struct mlx5_err_cqe *err_cqe)
{
struct mlx5_cqwq *wq = &cq->wq;
@@ -262,13 +305,53 @@ static inline void mlx5e_dump_error_cqe(struct mlx5e_cq *cq, u32 sqn,
ci = mlx5_cqwq_ctr2ix(wq, wq->cc - 1);
netdev_err(cq->channel->netdev,
- "Error cqe on cqn 0x%x, ci 0x%x, sqn 0x%x, opcode 0x%x, syndrome 0x%x, vendor syndrome 0x%x\n",
- cq->mcq.cqn, ci, sqn,
+ "Error cqe on cqn 0x%x, ci 0x%x, qn 0x%x, opcode 0x%x, syndrome 0x%x, vendor syndrome 0x%x\n",
+ cq->mcq.cqn, ci, qn,
get_cqe_opcode((struct mlx5_cqe64 *)err_cqe),
err_cqe->syndrome, err_cqe->vendor_err_synd);
mlx5_dump_err_cqe(cq->mdev, err_cqe);
}
+static inline u32 mlx5e_rqwq_get_size(struct mlx5e_rq *rq)
+{
+ switch (rq->wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ return mlx5_wq_ll_get_size(&rq->mpwqe.wq);
+ default:
+ return mlx5_wq_cyc_get_size(&rq->wqe.wq);
+ }
+}
+
+static inline u32 mlx5e_rqwq_get_cur_sz(struct mlx5e_rq *rq)
+{
+ switch (rq->wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ return rq->mpwqe.wq.cur_sz;
+ default:
+ return rq->wqe.wq.cur_sz;
+ }
+}
+
+static inline u16 mlx5e_rqwq_get_head(struct mlx5e_rq *rq)
+{
+ switch (rq->wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ return mlx5_wq_ll_get_head(&rq->mpwqe.wq);
+ default:
+ return mlx5_wq_cyc_get_head(&rq->wqe.wq);
+ }
+}
+
+static inline u16 mlx5e_rqwq_get_wqe_counter(struct mlx5e_rq *rq)
+{
+ switch (rq->wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ return mlx5_wq_ll_get_counter(&rq->mpwqe.wq);
+ default:
+ return mlx5_wq_cyc_get_counter(&rq->wqe.wq);
+ }
+}
+
/* SW parser related functions */
struct mlx5e_swp_spec {
@@ -305,7 +388,7 @@ mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg,
switch (swp_spec->tun_l4_proto) {
case IPPROTO_UDP:
eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L4_UDP;
- /* fall through */
+ fallthrough;
case IPPROTO_TCP:
eseg->swp_inner_l4_offset = skb_inner_transport_offset(skb) / 2;
break;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
index c9d308e91965..0e6946fc121f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
@@ -114,7 +114,8 @@ mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq,
xdpi.page.di = *di;
}
- return sq->xmit_xdp_frame(sq, &xdptxd, &xdpi, 0);
+ return INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
+ mlx5e_xmit_xdp_frame, sq, &xdptxd, &xdpi, 0);
}
/* returns true if packet was consumed by xdp */
@@ -151,11 +152,11 @@ bool mlx5e_xdp_handle(struct mlx5e_rq *rq, struct mlx5e_dma_info *di,
return true;
default:
bpf_warn_invalid_xdp_action(act);
- /* fall through */
+ fallthrough;
case XDP_ABORTED:
xdp_abort:
trace_xdp_exception(rq->netdev, prog, act);
- /* fall through */
+ fallthrough;
case XDP_DROP:
rq->stats->xdp_drop++;
return true;
@@ -237,7 +238,7 @@ enum {
MLX5E_XDP_CHECK_START_MPWQE = 2,
};
-static int mlx5e_xmit_xdp_frame_check_mpwqe(struct mlx5e_xdpsq *sq)
+INDIRECT_CALLABLE_SCOPE int mlx5e_xmit_xdp_frame_check_mpwqe(struct mlx5e_xdpsq *sq)
{
if (unlikely(!sq->mpwqe.wqe)) {
const u16 stop_room = mlx5e_stop_room_for_wqe(MLX5_SEND_WQE_MAX_WQEBBS);
@@ -256,10 +257,9 @@ static int mlx5e_xmit_xdp_frame_check_mpwqe(struct mlx5e_xdpsq *sq)
return MLX5E_XDP_CHECK_OK;
}
-static bool mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq,
- struct mlx5e_xdp_xmit_data *xdptxd,
- struct mlx5e_xdp_info *xdpi,
- int check_result)
+INDIRECT_CALLABLE_SCOPE bool
+mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq, struct mlx5e_xdp_xmit_data *xdptxd,
+ struct mlx5e_xdp_info *xdpi, int check_result)
{
struct mlx5e_xdp_mpwqe *session = &sq->mpwqe;
struct mlx5e_xdpsq_stats *stats = sq->stats;
@@ -293,7 +293,7 @@ static bool mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq,
return true;
}
-static int mlx5e_xmit_xdp_frame_check(struct mlx5e_xdpsq *sq)
+INDIRECT_CALLABLE_SCOPE int mlx5e_xmit_xdp_frame_check(struct mlx5e_xdpsq *sq)
{
if (unlikely(!mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, 1))) {
/* SQ is full, ring doorbell */
@@ -305,10 +305,9 @@ static int mlx5e_xmit_xdp_frame_check(struct mlx5e_xdpsq *sq)
return MLX5E_XDP_CHECK_OK;
}
-static bool mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq,
- struct mlx5e_xdp_xmit_data *xdptxd,
- struct mlx5e_xdp_info *xdpi,
- int check_result)
+INDIRECT_CALLABLE_SCOPE bool
+mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq, struct mlx5e_xdp_xmit_data *xdptxd,
+ struct mlx5e_xdp_info *xdpi, int check_result)
{
struct mlx5_wq_cyc *wq = &sq->wq;
u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
@@ -506,6 +505,7 @@ int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
struct xdp_frame *xdpf = frames[i];
struct mlx5e_xdp_xmit_data xdptxd;
struct mlx5e_xdp_info xdpi;
+ bool ret;
xdptxd.data = xdpf->data;
xdptxd.len = xdpf->len;
@@ -522,7 +522,9 @@ int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
xdpi.frame.xdpf = xdpf;
xdpi.frame.dma_addr = xdptxd.dma_addr;
- if (unlikely(!sq->xmit_xdp_frame(sq, &xdptxd, &xdpi, 0))) {
+ ret = INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
+ mlx5e_xmit_xdp_frame, sq, &xdptxd, &xdpi, 0);
+ if (unlikely(!ret)) {
dma_unmap_single(sq->pdev, xdptxd.dma_addr,
xdptxd.len, DMA_TO_DEVICE);
xdp_return_frame_rx_napi(xdpf);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h
index ca48c293151b..e806c13d491f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h
@@ -32,6 +32,8 @@
#ifndef __MLX5_EN_XDP_H__
#define __MLX5_EN_XDP_H__
+#include <linux/indirect_call_wrapper.h>
+
#include "en.h"
#include "en/txrx.h"
@@ -70,6 +72,17 @@ void mlx5e_xdp_rx_poll_complete(struct mlx5e_rq *rq);
int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
u32 flags);
+INDIRECT_CALLABLE_DECLARE(bool mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq,
+ struct mlx5e_xdp_xmit_data *xdptxd,
+ struct mlx5e_xdp_info *xdpi,
+ int check_result));
+INDIRECT_CALLABLE_DECLARE(bool mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq,
+ struct mlx5e_xdp_xmit_data *xdptxd,
+ struct mlx5e_xdp_info *xdpi,
+ int check_result));
+INDIRECT_CALLABLE_DECLARE(int mlx5e_xmit_xdp_frame_check_mpwqe(struct mlx5e_xdpsq *sq));
+INDIRECT_CALLABLE_DECLARE(int mlx5e_xmit_xdp_frame_check(struct mlx5e_xdpsq *sq));
+
static inline void mlx5e_xdp_tx_enable(struct mlx5e_priv *priv)
{
set_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
index 2c80205dc939..dd9df519d383 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
@@ -3,6 +3,7 @@
#include "setup.h"
#include "en/params.h"
+#include "en/txrx.h"
/* It matches XDP_UMEM_MIN_CHUNK_SIZE, but as this constant is private and may
* change unexpectedly, and mlx5e has a minimum valid stride size for striding
@@ -34,31 +35,13 @@ bool mlx5e_validate_xsk_param(struct mlx5e_params *params,
}
}
-static void mlx5e_build_xskicosq_param(struct mlx5e_priv *priv,
- u8 log_wq_size,
- struct mlx5e_sq_param *param)
-{
- void *sqc = param->sqc;
- void *wq = MLX5_ADDR_OF(sqc, sqc, wq);
-
- mlx5e_build_sq_param_common(priv, param);
-
- MLX5_SET(wq, wq, log_wq_sz, log_wq_size);
-}
-
static void mlx5e_build_xsk_cparam(struct mlx5e_priv *priv,
struct mlx5e_params *params,
struct mlx5e_xsk_param *xsk,
struct mlx5e_channel_param *cparam)
{
- const u8 xskicosq_size = MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
-
mlx5e_build_rq_param(priv, params, xsk, &cparam->rq);
mlx5e_build_xdpsq_param(priv, params, &cparam->xdp_sq);
- mlx5e_build_xskicosq_param(priv, xskicosq_size, &cparam->icosq);
- mlx5e_build_rx_cq_param(priv, params, xsk, &cparam->rx_cq);
- mlx5e_build_tx_cq_param(priv, params, &cparam->tx_cq);
- mlx5e_build_ico_cq_param(priv, xskicosq_size, &cparam->icosq_cq);
}
int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params,
@@ -66,7 +49,6 @@ int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params,
struct mlx5e_channel *c)
{
struct mlx5e_channel_param *cparam;
- struct dim_cq_moder icocq_moder = {};
int err;
if (!mlx5e_validate_xsk_param(params, xsk, priv->mdev))
@@ -78,7 +60,7 @@ int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params,
mlx5e_build_xsk_cparam(priv, params, xsk, cparam);
- err = mlx5e_open_cq(c, params->rx_cq_moderation, &cparam->rx_cq, &c->xskrq.cq);
+ err = mlx5e_open_cq(c, params->rx_cq_moderation, &cparam->rq.cqp, &c->xskrq.cq);
if (unlikely(err))
goto err_free_cparam;
@@ -86,7 +68,7 @@ int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params,
if (unlikely(err))
goto err_close_rx_cq;
- err = mlx5e_open_cq(c, params->tx_cq_moderation, &cparam->tx_cq, &c->xsksq.cq);
+ err = mlx5e_open_cq(c, params->tx_cq_moderation, &cparam->xdp_sq.cqp, &c->xsksq.cq);
if (unlikely(err))
goto err_close_rq;
@@ -100,31 +82,12 @@ int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params,
if (unlikely(err))
goto err_close_tx_cq;
- err = mlx5e_open_cq(c, icocq_moder, &cparam->icosq_cq, &c->xskicosq.cq);
- if (unlikely(err))
- goto err_close_sq;
-
- /* Create a dedicated SQ for posting NOPs whenever we need an IRQ to be
- * triggered and NAPI to be called on the correct CPU.
- */
- err = mlx5e_open_icosq(c, params, &cparam->icosq, &c->xskicosq);
- if (unlikely(err))
- goto err_close_icocq;
-
kvfree(cparam);
- spin_lock_init(&c->xskicosq_lock);
-
set_bit(MLX5E_CHANNEL_STATE_XSK, c->state);
return 0;
-err_close_icocq:
- mlx5e_close_cq(&c->xskicosq.cq);
-
-err_close_sq:
- mlx5e_close_xdpsq(&c->xsksq);
-
err_close_tx_cq:
mlx5e_close_cq(&c->xsksq.cq);
@@ -148,32 +111,27 @@ void mlx5e_close_xsk(struct mlx5e_channel *c)
mlx5e_close_rq(&c->xskrq);
mlx5e_close_cq(&c->xskrq.cq);
- mlx5e_close_icosq(&c->xskicosq);
- mlx5e_close_cq(&c->xskicosq.cq);
mlx5e_close_xdpsq(&c->xsksq);
mlx5e_close_cq(&c->xsksq.cq);
memset(&c->xskrq, 0, sizeof(c->xskrq));
memset(&c->xsksq, 0, sizeof(c->xsksq));
- memset(&c->xskicosq, 0, sizeof(c->xskicosq));
}
void mlx5e_activate_xsk(struct mlx5e_channel *c)
{
- mlx5e_activate_icosq(&c->xskicosq);
set_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
/* TX queue is created active. */
- spin_lock(&c->xskicosq_lock);
- mlx5e_trigger_irq(&c->xskicosq);
- spin_unlock(&c->xskicosq_lock);
+ spin_lock(&c->async_icosq_lock);
+ mlx5e_trigger_irq(&c->async_icosq);
+ spin_unlock(&c->async_icosq_lock);
}
void mlx5e_deactivate_xsk(struct mlx5e_channel *c)
{
mlx5e_deactivate_rq(&c->xskrq);
/* TX queue is disabled on close. */
- mlx5e_deactivate_icosq(&c->xskicosq);
}
static int mlx5e_redirect_xsk_rqt(struct mlx5e_priv *priv, u16 ix, u32 rqn)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
index 83dce9cdb8c2..4d892f6cecb3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
@@ -26,19 +26,19 @@ int mlx5e_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags)
return -ENXIO;
if (!napi_if_scheduled_mark_missed(&c->napi)) {
- /* To avoid WQE overrun, don't post a NOP if XSKICOSQ is not
+ /* To avoid WQE overrun, don't post a NOP if async_icosq is not
* active and not polled by NAPI. Return 0, because the upcoming
* activate will trigger the IRQ for us.
*/
- if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &c->xskicosq.state)))
+ if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &c->async_icosq.state)))
return 0;
- if (test_and_set_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->xskicosq.state))
+ if (test_and_set_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->async_icosq.state))
return 0;
- spin_lock(&c->xskicosq_lock);
- mlx5e_trigger_irq(&c->xskicosq);
- spin_unlock(&c->xskicosq_lock);
+ spin_lock(&c->async_icosq_lock);
+ mlx5e_trigger_irq(&c->async_icosq);
+ spin_unlock(&c->async_icosq_lock);
}
return 0;
@@ -75,8 +75,12 @@ bool mlx5e_xsk_tx(struct mlx5e_xdpsq *sq, unsigned int budget)
xdpi.mode = MLX5E_XDP_XMIT_MODE_XSK;
for (; budget; budget--) {
- int check_result = sq->xmit_xdp_frame_check(sq);
+ int check_result = INDIRECT_CALL_2(sq->xmit_xdp_frame_check,
+ mlx5e_xmit_xdp_frame_check_mpwqe,
+ mlx5e_xmit_xdp_frame_check,
+ sq);
struct xdp_desc desc;
+ bool ret;
if (unlikely(check_result < 0)) {
work_done = false;
@@ -98,7 +102,9 @@ bool mlx5e_xsk_tx(struct mlx5e_xdpsq *sq, unsigned int budget)
xsk_buff_raw_dma_sync_for_device(umem, xdptxd.dma_addr, xdptxd.len);
- if (unlikely(!sq->xmit_xdp_frame(sq, &xdptxd, &xdpi, check_result))) {
+ ret = INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
+ mlx5e_xmit_xdp_frame, sq, &xdptxd, &xdpi, check_result);
+ if (unlikely(!ret)) {
if (sq->mpwqe.wqe)
mlx5e_xdp_mpwqe_complete(sq);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.c
index 7b17fcd0a56d..331ca2b0f8a4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.c
@@ -215,16 +215,3 @@ int mlx5e_xsk_setup_umem(struct net_device *dev, struct xdp_umem *umem, u16 qid)
return umem ? mlx5e_xsk_enable_umem(priv, umem, ix) :
mlx5e_xsk_disable_umem(priv, ix);
}
-
-u16 mlx5e_xsk_first_unused_channel(struct mlx5e_params *params, struct mlx5e_xsk *xsk)
-{
- u16 res = xsk->refcnt ? params->num_channels : 0;
-
- while (res) {
- if (mlx5e_xsk_get_umem(params, xsk, res - 1))
- break;
- --res;
- }
-
- return res;
-}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.h b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.h
index 25b4cbe58b54..bada94973586 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/umem.h
@@ -26,6 +26,4 @@ int mlx5e_xsk_setup_umem(struct net_device *dev, struct xdp_umem *umem, u16 qid)
int mlx5e_xsk_resize_reuseq(struct xdp_umem *umem, u32 nentries);
-u16 mlx5e_xsk_first_unused_channel(struct mlx5e_params *params, struct mlx5e_xsk *xsk);
-
#endif /* __MLX5_EN_XSK_UMEM_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
index fac145dcf2ce..110476bdeffb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
@@ -37,6 +37,7 @@
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include "en_accel/ipsec_rxtx.h"
+#include "en_accel/tls.h"
#include "en_accel/tls_rxtx.h"
#include "en.h"
#include "en/txrx.h"
@@ -147,4 +148,13 @@ static inline bool mlx5e_accel_tx_finish(struct mlx5e_priv *priv,
return true;
}
+static inline int mlx5e_accel_init_rx(struct mlx5e_priv *priv)
+{
+ return mlx5e_ktls_init_rx(priv);
+}
+
+static inline void mlx5e_accel_cleanup_rx(struct mlx5e_priv *priv)
+{
+ mlx5e_ktls_cleanup_rx(priv);
+}
#endif /* __MLX5E_EN_ACCEL_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
new file mode 100644
index 000000000000..4cdd9eac647d
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
@@ -0,0 +1,400 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
+
+#include <linux/netdevice.h>
+#include "en_accel/fs_tcp.h"
+#include "fs_core.h"
+
+enum accel_fs_tcp_type {
+ ACCEL_FS_IPV4_TCP,
+ ACCEL_FS_IPV6_TCP,
+ ACCEL_FS_TCP_NUM_TYPES,
+};
+
+struct mlx5e_accel_fs_tcp {
+ struct mlx5e_flow_table tables[ACCEL_FS_TCP_NUM_TYPES];
+ struct mlx5_flow_handle *default_rules[ACCEL_FS_TCP_NUM_TYPES];
+};
+
+static enum mlx5e_traffic_types fs_accel2tt(enum accel_fs_tcp_type i)
+{
+ switch (i) {
+ case ACCEL_FS_IPV4_TCP:
+ return MLX5E_TT_IPV4_TCP;
+ default: /* ACCEL_FS_IPV6_TCP */
+ return MLX5E_TT_IPV6_TCP;
+ }
+}
+
+static void accel_fs_tcp_set_ipv4_flow(struct mlx5_flow_spec *spec, struct sock *sk)
+{
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol);
+ MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, IPPROTO_TCP);
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version);
+ MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version, 4);
+ memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
+ outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4),
+ &inet_sk(sk)->inet_daddr, 4);
+ memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
+ outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
+ &inet_sk(sk)->inet_rcv_saddr, 4);
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4);
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
+}
+
+static void accel_fs_tcp_set_ipv6_flow(struct mlx5_flow_spec *spec, struct sock *sk)
+{
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol);
+ MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, IPPROTO_TCP);
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version);
+ MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version, 6);
+ memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
+ outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6),
+ &sk->sk_v6_daddr, 16);
+ memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
+ outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
+ &inet6_sk(sk)->saddr, 16);
+ memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
+ outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6),
+ 0xff, 16);
+ memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
+ outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
+ 0xff, 16);
+}
+
+void mlx5e_accel_fs_del_sk(struct mlx5_flow_handle *rule)
+{
+ mlx5_del_flow_rules(rule);
+}
+
+struct mlx5_flow_handle *mlx5e_accel_fs_add_sk(struct mlx5e_priv *priv,
+ struct sock *sk, u32 tirn,
+ uint32_t flow_tag)
+{
+ struct mlx5_flow_destination dest = {};
+ struct mlx5e_flow_table *ft = NULL;
+ struct mlx5e_accel_fs_tcp *fs_tcp;
+ MLX5_DECLARE_FLOW_ACT(flow_act);
+ struct mlx5_flow_handle *flow;
+ struct mlx5_flow_spec *spec;
+
+ spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
+ if (!spec)
+ return ERR_PTR(-ENOMEM);
+
+ fs_tcp = priv->fs.accel_tcp;
+
+ spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+
+ switch (sk->sk_family) {
+ case AF_INET:
+ accel_fs_tcp_set_ipv4_flow(spec, sk);
+ ft = &fs_tcp->tables[ACCEL_FS_IPV4_TCP];
+ mlx5e_dbg(HW, priv, "%s flow is %pI4:%d -> %pI4:%d\n", __func__,
+ &inet_sk(sk)->inet_rcv_saddr,
+ inet_sk(sk)->inet_sport,
+ &inet_sk(sk)->inet_daddr,
+ inet_sk(sk)->inet_dport);
+ break;
+#if IS_ENABLED(CONFIG_IPV6)
+ case AF_INET6:
+ if (!sk->sk_ipv6only &&
+ ipv6_addr_type(&sk->sk_v6_daddr) == IPV6_ADDR_MAPPED) {
+ accel_fs_tcp_set_ipv4_flow(spec, sk);
+ ft = &fs_tcp->tables[ACCEL_FS_IPV4_TCP];
+ } else {
+ accel_fs_tcp_set_ipv6_flow(spec, sk);
+ ft = &fs_tcp->tables[ACCEL_FS_IPV6_TCP];
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+
+ if (!ft) {
+ flow = ERR_PTR(-EINVAL);
+ goto out;
+ }
+
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ outer_headers.tcp_dport);
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ outer_headers.tcp_sport);
+ MLX5_SET(fte_match_param, spec->match_value, outer_headers.tcp_dport,
+ ntohs(inet_sk(sk)->inet_sport));
+ MLX5_SET(fte_match_param, spec->match_value, outer_headers.tcp_sport,
+ ntohs(inet_sk(sk)->inet_dport));
+
+ dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
+ dest.tir_num = tirn;
+ if (flow_tag != MLX5_FS_DEFAULT_FLOW_TAG) {
+ spec->flow_context.flow_tag = flow_tag;
+ spec->flow_context.flags = FLOW_CONTEXT_HAS_TAG;
+ }
+
+ flow = mlx5_add_flow_rules(ft->t, spec, &flow_act, &dest, 1);
+
+ if (IS_ERR(flow))
+ netdev_err(priv->netdev, "mlx5_add_flow_rules() failed, flow is %ld\n",
+ PTR_ERR(flow));
+
+out:
+ kvfree(spec);
+ return flow;
+}
+
+static int accel_fs_tcp_add_default_rule(struct mlx5e_priv *priv,
+ enum accel_fs_tcp_type type)
+{
+ struct mlx5e_flow_table *accel_fs_t;
+ struct mlx5_flow_destination dest;
+ struct mlx5e_accel_fs_tcp *fs_tcp;
+ MLX5_DECLARE_FLOW_ACT(flow_act);
+ struct mlx5_flow_handle *rule;
+ int err = 0;
+
+ fs_tcp = priv->fs.accel_tcp;
+ accel_fs_t = &fs_tcp->tables[type];
+
+ dest = mlx5e_ttc_get_default_dest(priv, fs_accel2tt(type));
+ rule = mlx5_add_flow_rules(accel_fs_t->t, NULL, &flow_act, &dest, 1);
+ if (IS_ERR(rule)) {
+ err = PTR_ERR(rule);
+ netdev_err(priv->netdev,
+ "%s: add default rule failed, accel_fs type=%d, err %d\n",
+ __func__, type, err);
+ return err;
+ }
+
+ fs_tcp->default_rules[type] = rule;
+ return 0;
+}
+
+#define MLX5E_ACCEL_FS_TCP_NUM_GROUPS (2)
+#define MLX5E_ACCEL_FS_TCP_GROUP1_SIZE (BIT(16) - 1)
+#define MLX5E_ACCEL_FS_TCP_GROUP2_SIZE (BIT(0))
+#define MLX5E_ACCEL_FS_TCP_TABLE_SIZE (MLX5E_ACCEL_FS_TCP_GROUP1_SIZE +\
+ MLX5E_ACCEL_FS_TCP_GROUP2_SIZE)
+static int accel_fs_tcp_create_groups(struct mlx5e_flow_table *ft,
+ enum accel_fs_tcp_type type)
+{
+ int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
+ void *outer_headers_c;
+ int ix = 0;
+ u32 *in;
+ int err;
+ u8 *mc;
+
+ ft->g = kcalloc(MLX5E_ACCEL_FS_TCP_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL);
+ in = kvzalloc(inlen, GFP_KERNEL);
+ if (!in || !ft->g) {
+ kvfree(ft->g);
+ kvfree(in);
+ return -ENOMEM;
+ }
+
+ mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
+ outer_headers_c = MLX5_ADDR_OF(fte_match_param, mc, outer_headers);
+ MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol);
+ MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ip_version);
+
+ switch (type) {
+ case ACCEL_FS_IPV4_TCP:
+ case ACCEL_FS_IPV6_TCP:
+ MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, tcp_dport);
+ MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, tcp_sport);
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+
+ switch (type) {
+ case ACCEL_FS_IPV4_TCP:
+ MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c,
+ src_ipv4_src_ipv6.ipv4_layout.ipv4);
+ MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c,
+ dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
+ break;
+ case ACCEL_FS_IPV6_TCP:
+ memset(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
+ src_ipv4_src_ipv6.ipv6_layout.ipv6),
+ 0xff, 16);
+ memset(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
+ dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
+ 0xff, 16);
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+
+ MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
+ MLX5_SET_CFG(in, start_flow_index, ix);
+ ix += MLX5E_ACCEL_FS_TCP_GROUP1_SIZE;
+ MLX5_SET_CFG(in, end_flow_index, ix - 1);
+ ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
+ if (IS_ERR(ft->g[ft->num_groups]))
+ goto err;
+ ft->num_groups++;
+
+ /* Default Flow Group */
+ memset(in, 0, inlen);
+ MLX5_SET_CFG(in, start_flow_index, ix);
+ ix += MLX5E_ACCEL_FS_TCP_GROUP2_SIZE;
+ MLX5_SET_CFG(in, end_flow_index, ix - 1);
+ ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
+ if (IS_ERR(ft->g[ft->num_groups]))
+ goto err;
+ ft->num_groups++;
+
+ kvfree(in);
+ return 0;
+
+err:
+ err = PTR_ERR(ft->g[ft->num_groups]);
+ ft->g[ft->num_groups] = NULL;
+out:
+ kvfree(in);
+
+ return err;
+}
+
+static int accel_fs_tcp_create_table(struct mlx5e_priv *priv, enum accel_fs_tcp_type type)
+{
+ struct mlx5e_flow_table *ft = &priv->fs.accel_tcp->tables[type];
+ struct mlx5_flow_table_attr ft_attr = {};
+ int err;
+
+ ft->num_groups = 0;
+
+ ft_attr.max_fte = MLX5E_ACCEL_FS_TCP_TABLE_SIZE;
+ ft_attr.level = MLX5E_ACCEL_FS_TCP_FT_LEVEL;
+ ft_attr.prio = MLX5E_NIC_PRIO;
+
+ ft->t = mlx5_create_flow_table(priv->fs.ns, &ft_attr);
+ if (IS_ERR(ft->t)) {
+ err = PTR_ERR(ft->t);
+ ft->t = NULL;
+ return err;
+ }
+
+ netdev_dbg(priv->netdev, "Created fs accel table id %u level %u\n",
+ ft->t->id, ft->t->level);
+
+ err = accel_fs_tcp_create_groups(ft, type);
+ if (err)
+ goto err;
+
+ err = accel_fs_tcp_add_default_rule(priv, type);
+ if (err)
+ goto err;
+
+ return 0;
+err:
+ mlx5e_destroy_flow_table(ft);
+ return err;
+}
+
+static int accel_fs_tcp_disable(struct mlx5e_priv *priv)
+{
+ int err, i;
+
+ for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++) {
+ /* Modify ttc rules destination to point back to the indir TIRs */
+ err = mlx5e_ttc_fwd_default_dest(priv, fs_accel2tt(i));
+ if (err) {
+ netdev_err(priv->netdev,
+ "%s: modify ttc[%d] default destination failed, err(%d)\n",
+ __func__, fs_accel2tt(i), err);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int accel_fs_tcp_enable(struct mlx5e_priv *priv)
+{
+ struct mlx5_flow_destination dest = {};
+ int err, i;
+
+ dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+ for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++) {
+ dest.ft = priv->fs.accel_tcp->tables[i].t;
+
+ /* Modify ttc rules destination to point on the accel_fs FTs */
+ err = mlx5e_ttc_fwd_dest(priv, fs_accel2tt(i), &dest);
+ if (err) {
+ netdev_err(priv->netdev,
+ "%s: modify ttc[%d] destination to accel failed, err(%d)\n",
+ __func__, fs_accel2tt(i), err);
+ return err;
+ }
+ }
+ return 0;
+}
+
+static void accel_fs_tcp_destroy_table(struct mlx5e_priv *priv, int i)
+{
+ struct mlx5e_accel_fs_tcp *fs_tcp;
+
+ fs_tcp = priv->fs.accel_tcp;
+ if (IS_ERR_OR_NULL(fs_tcp->tables[i].t))
+ return;
+
+ mlx5_del_flow_rules(fs_tcp->default_rules[i]);
+ mlx5e_destroy_flow_table(&fs_tcp->tables[i]);
+ fs_tcp->tables[i].t = NULL;
+}
+
+void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv)
+{
+ int i;
+
+ if (!priv->fs.accel_tcp)
+ return;
+
+ accel_fs_tcp_disable(priv);
+
+ for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++)
+ accel_fs_tcp_destroy_table(priv, i);
+
+ kfree(priv->fs.accel_tcp);
+ priv->fs.accel_tcp = NULL;
+}
+
+int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv)
+{
+ int i, err;
+
+ if (!MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version))
+ return -EOPNOTSUPP;
+
+ priv->fs.accel_tcp = kzalloc(sizeof(*priv->fs.accel_tcp), GFP_KERNEL);
+ if (!priv->fs.accel_tcp)
+ return -ENOMEM;
+
+ for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++) {
+ err = accel_fs_tcp_create_table(priv, i);
+ if (err)
+ goto err_destroy_tables;
+ }
+
+ err = accel_fs_tcp_enable(priv);
+ if (err)
+ goto err_destroy_tables;
+
+ return 0;
+
+err_destroy_tables:
+ while (--i >= 0)
+ accel_fs_tcp_destroy_table(priv, i);
+
+ kfree(priv->fs.accel_tcp);
+ priv->fs.accel_tcp = NULL;
+ return err;
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.h
new file mode 100644
index 000000000000..589235824543
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
+
+#ifndef __MLX5E_ACCEL_FS_TCP_H__
+#define __MLX5E_ACCEL_FS_TCP_H__
+
+#include "en.h"
+
+#ifdef CONFIG_MLX5_EN_TLS
+int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv);
+void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv);
+struct mlx5_flow_handle *mlx5e_accel_fs_add_sk(struct mlx5e_priv *priv,
+ struct sock *sk, u32 tirn,
+ uint32_t flow_tag);
+void mlx5e_accel_fs_del_sk(struct mlx5_flow_handle *rule);
+#else
+static inline int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv) { return 0; }
+static inline void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv) {}
+static inline struct mlx5_flow_handle *mlx5e_accel_fs_add_sk(struct mlx5e_priv *priv,
+ struct sock *sk, u32 tirn,
+ uint32_t flow_tag)
+{ return ERR_PTR(-EOPNOTSUPP); }
+static inline void mlx5e_accel_fs_del_sk(struct mlx5_flow_handle *rule) {}
+#endif
+
+#endif /* __MLX5E_ACCEL_FS_TCP_H__ */
+
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 92eb3bad4acd..d39989cddd90 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
@@ -40,7 +40,7 @@
#include "en.h"
#include "en_accel/ipsec.h"
#include "en_accel/ipsec_rxtx.h"
-
+#include "en_accel/ipsec_fs.h"
static struct mlx5e_ipsec_sa_entry *to_ipsec_sa_entry(struct xfrm_state *x)
{
@@ -111,7 +111,7 @@ static void mlx5e_ipsec_sadb_rx_del(struct mlx5e_ipsec_sa_entry *sa_entry)
static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
{
struct xfrm_replay_state_esn *replay_esn;
- u32 seq_bottom;
+ u32 seq_bottom = 0;
u8 overlap;
u32 *esn;
@@ -121,7 +121,9 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
}
replay_esn = sa_entry->x->replay_esn;
- seq_bottom = replay_esn->seq - replay_esn->replay_window + 1;
+ if (replay_esn->seq >= replay_esn->replay_window)
+ seq_bottom = replay_esn->seq - replay_esn->replay_window + 1;
+
overlap = sa_entry->esn_state.overlap;
sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x,
@@ -207,7 +209,7 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
{
- struct net_device *netdev = x->xso.dev;
+ struct net_device *netdev = x->xso.real_dev;
struct mlx5e_priv *priv;
priv = netdev_priv(netdev);
@@ -282,10 +284,31 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
return 0;
}
+static int mlx5e_xfrm_fs_add_rule(struct mlx5e_priv *priv,
+ struct mlx5e_ipsec_sa_entry *sa_entry)
+{
+ if (!mlx5_is_ipsec_device(priv->mdev))
+ return 0;
+
+ return mlx5e_accel_ipsec_fs_add_rule(priv, &sa_entry->xfrm->attrs,
+ sa_entry->ipsec_obj_id,
+ &sa_entry->ipsec_rule);
+}
+
+static void mlx5e_xfrm_fs_del_rule(struct mlx5e_priv *priv,
+ struct mlx5e_ipsec_sa_entry *sa_entry)
+{
+ if (!mlx5_is_ipsec_device(priv->mdev))
+ return;
+
+ mlx5e_accel_ipsec_fs_del_rule(priv, &sa_entry->xfrm->attrs,
+ &sa_entry->ipsec_rule);
+}
+
static int mlx5e_xfrm_add_state(struct xfrm_state *x)
{
struct mlx5e_ipsec_sa_entry *sa_entry = NULL;
- struct net_device *netdev = x->xso.dev;
+ struct net_device *netdev = x->xso.real_dev;
struct mlx5_accel_esp_xfrm_attrs attrs;
struct mlx5e_priv *priv;
unsigned int sa_handle;
@@ -329,10 +352,15 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x)
goto err_xfrm;
}
+ sa_entry->ipsec_obj_id = sa_handle;
+ err = mlx5e_xfrm_fs_add_rule(priv, sa_entry);
+ if (err)
+ goto err_hw_ctx;
+
if (x->xso.flags & XFRM_OFFLOAD_INBOUND) {
err = mlx5e_ipsec_sadb_rx_add(sa_entry, sa_handle);
if (err)
- goto err_hw_ctx;
+ goto err_add_rule;
} else {
sa_entry->set_iv_op = (x->props.flags & XFRM_STATE_ESN) ?
mlx5e_ipsec_set_iv_esn : mlx5e_ipsec_set_iv;
@@ -341,8 +369,10 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x)
x->xso.offload_handle = (unsigned long)sa_entry;
goto out;
+err_add_rule:
+ mlx5e_xfrm_fs_del_rule(priv, sa_entry);
err_hw_ctx:
- mlx5_accel_esp_free_hw_context(sa_entry->hw_context);
+ mlx5_accel_esp_free_hw_context(priv->mdev, sa_entry->hw_context);
err_xfrm:
mlx5_accel_esp_destroy_xfrm(sa_entry->xfrm);
err_sa_entry:
@@ -366,13 +396,15 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)
static void mlx5e_xfrm_free_state(struct xfrm_state *x)
{
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
+ struct mlx5e_priv *priv = netdev_priv(x->xso.dev);
if (!sa_entry)
return;
if (sa_entry->hw_context) {
flush_workqueue(sa_entry->ipsec->wq);
- mlx5_accel_esp_free_hw_context(sa_entry->hw_context);
+ mlx5e_xfrm_fs_del_rule(priv, sa_entry);
+ mlx5_accel_esp_free_hw_context(sa_entry->xfrm->mdev, sa_entry->hw_context);
mlx5_accel_esp_destroy_xfrm(sa_entry->xfrm);
}
@@ -405,6 +437,8 @@ int mlx5e_ipsec_init(struct mlx5e_priv *priv)
kfree(ipsec);
return -ENOMEM;
}
+
+ mlx5e_accel_ipsec_fs_init(priv);
netdev_dbg(priv->netdev, "IPSec attached to netdevice\n");
return 0;
}
@@ -416,6 +450,7 @@ void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv)
if (!ipsec)
return;
+ mlx5e_accel_ipsec_fs_cleanup(priv);
destroy_workqueue(ipsec->wq);
ida_destroy(&ipsec->halloc);
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 c85151a1e008..0fc8b4d4f4a3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
@@ -75,6 +75,8 @@ struct mlx5e_ipsec_stats {
u64 ipsec_cmd_drop;
};
+struct mlx5e_accel_fs_esp;
+
struct mlx5e_ipsec {
struct mlx5e_priv *en_priv;
DECLARE_HASHTABLE(sadb_rx, MLX5E_IPSEC_SADB_RX_BITS);
@@ -84,6 +86,7 @@ struct mlx5e_ipsec {
struct mlx5e_ipsec_sw_stats sw_stats;
struct mlx5e_ipsec_stats stats;
struct workqueue_struct *wq;
+ struct mlx5e_accel_fs_esp *rx_fs;
};
struct mlx5e_ipsec_esn_state {
@@ -92,6 +95,11 @@ struct mlx5e_ipsec_esn_state {
u8 overlap: 1;
};
+struct mlx5e_ipsec_rule {
+ struct mlx5_flow_handle *rule;
+ struct mlx5_modify_hdr *set_modify_hdr;
+};
+
struct mlx5e_ipsec_sa_entry {
struct hlist_node hlist; /* Item in SADB_RX hashtable */
struct mlx5e_ipsec_esn_state esn_state;
@@ -102,6 +110,8 @@ struct mlx5e_ipsec_sa_entry {
void *hw_context;
void (*set_iv_op)(struct sk_buff *skb, struct xfrm_state *x,
struct xfrm_offload *xo);
+ u32 ipsec_obj_id;
+ struct mlx5e_ipsec_rule ipsec_rule;
};
void mlx5e_ipsec_build_inverse_table(void);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
new file mode 100644
index 000000000000..429428bbc903
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
@@ -0,0 +1,544 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
+
+#include <linux/netdevice.h>
+#include "accel/ipsec_offload.h"
+#include "ipsec_fs.h"
+#include "fs_core.h"
+
+#define NUM_IPSEC_FTE BIT(15)
+
+enum accel_fs_esp_type {
+ ACCEL_FS_ESP4,
+ ACCEL_FS_ESP6,
+ ACCEL_FS_ESP_NUM_TYPES,
+};
+
+struct mlx5e_ipsec_rx_err {
+ struct mlx5_flow_table *ft;
+ struct mlx5_flow_handle *rule;
+ struct mlx5_modify_hdr *copy_modify_hdr;
+};
+
+struct mlx5e_accel_fs_esp_prot {
+ struct mlx5_flow_table *ft;
+ struct mlx5_flow_group *miss_group;
+ struct mlx5_flow_handle *miss_rule;
+ struct mlx5_flow_destination default_dest;
+ struct mlx5e_ipsec_rx_err rx_err;
+ u32 refcnt;
+ struct mutex prot_mutex; /* protect ESP4/ESP6 protocol */
+};
+
+struct mlx5e_accel_fs_esp {
+ struct mlx5e_accel_fs_esp_prot fs_prot[ACCEL_FS_ESP_NUM_TYPES];
+};
+
+/* IPsec RX flow steering */
+static enum mlx5e_traffic_types fs_esp2tt(enum accel_fs_esp_type i)
+{
+ if (i == ACCEL_FS_ESP4)
+ return MLX5E_TT_IPV4_IPSEC_ESP;
+ return MLX5E_TT_IPV6_IPSEC_ESP;
+}
+
+static int rx_err_add_rule(struct mlx5e_priv *priv,
+ struct mlx5e_accel_fs_esp_prot *fs_prot,
+ struct mlx5e_ipsec_rx_err *rx_err)
+{
+ u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
+ struct mlx5_core_dev *mdev = priv->mdev;
+ struct mlx5_flow_act flow_act = {};
+ struct mlx5_modify_hdr *modify_hdr;
+ struct mlx5_flow_handle *fte;
+ struct mlx5_flow_spec *spec;
+ int err = 0;
+
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (!spec)
+ return -ENOMEM;
+
+ /* Action to copy 7 bit ipsec_syndrome to regB[0:6] */
+ MLX5_SET(copy_action_in, action, action_type, MLX5_ACTION_TYPE_COPY);
+ MLX5_SET(copy_action_in, action, src_field, MLX5_ACTION_IN_FIELD_IPSEC_SYNDROME);
+ MLX5_SET(copy_action_in, action, src_offset, 0);
+ MLX5_SET(copy_action_in, action, length, 7);
+ MLX5_SET(copy_action_in, action, dst_field, MLX5_ACTION_IN_FIELD_METADATA_REG_B);
+ MLX5_SET(copy_action_in, action, dst_offset, 0);
+
+ modify_hdr = mlx5_modify_header_alloc(mdev, MLX5_FLOW_NAMESPACE_KERNEL,
+ 1, action);
+
+ if (IS_ERR(modify_hdr)) {
+ err = PTR_ERR(modify_hdr);
+ netdev_err(priv->netdev,
+ "fail to alloc ipsec copy modify_header_id err=%d\n", err);
+ goto out_spec;
+ }
+
+ /* create fte */
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_MOD_HDR |
+ MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+ flow_act.modify_hdr = modify_hdr;
+ fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act,
+ &fs_prot->default_dest, 1);
+ if (IS_ERR(fte)) {
+ err = PTR_ERR(fte);
+ netdev_err(priv->netdev, "fail to add ipsec rx err copy rule err=%d\n", err);
+ goto out;
+ }
+
+ rx_err->rule = fte;
+ rx_err->copy_modify_hdr = modify_hdr;
+
+out:
+ if (err)
+ mlx5_modify_header_dealloc(mdev, modify_hdr);
+out_spec:
+ kfree(spec);
+ return err;
+}
+
+static void rx_err_del_rule(struct mlx5e_priv *priv,
+ struct mlx5e_ipsec_rx_err *rx_err)
+{
+ if (rx_err->rule) {
+ mlx5_del_flow_rules(rx_err->rule);
+ rx_err->rule = NULL;
+ }
+
+ if (rx_err->copy_modify_hdr) {
+ mlx5_modify_header_dealloc(priv->mdev, rx_err->copy_modify_hdr);
+ rx_err->copy_modify_hdr = NULL;
+ }
+}
+
+static void rx_err_destroy_ft(struct mlx5e_priv *priv, struct mlx5e_ipsec_rx_err *rx_err)
+{
+ rx_err_del_rule(priv, rx_err);
+
+ if (rx_err->ft) {
+ mlx5_destroy_flow_table(rx_err->ft);
+ rx_err->ft = NULL;
+ }
+}
+
+static int rx_err_create_ft(struct mlx5e_priv *priv,
+ struct mlx5e_accel_fs_esp_prot *fs_prot,
+ struct mlx5e_ipsec_rx_err *rx_err)
+{
+ struct mlx5_flow_table_attr ft_attr = {};
+ struct mlx5_flow_table *ft;
+ int err;
+
+ ft_attr.max_fte = 1;
+ ft_attr.autogroup.max_num_groups = 1;
+ ft_attr.level = MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL;
+ ft_attr.prio = MLX5E_NIC_PRIO;
+ ft = mlx5_create_auto_grouped_flow_table(priv->fs.ns, &ft_attr);
+ if (IS_ERR(ft)) {
+ err = PTR_ERR(ft);
+ netdev_err(priv->netdev, "fail to create ipsec rx inline ft err=%d\n", err);
+ return err;
+ }
+
+ rx_err->ft = ft;
+ err = rx_err_add_rule(priv, fs_prot, rx_err);
+ if (err)
+ goto out_err;
+
+ return 0;
+
+out_err:
+ mlx5_destroy_flow_table(ft);
+ rx_err->ft = NULL;
+ return err;
+}
+
+static void rx_fs_destroy(struct mlx5e_accel_fs_esp_prot *fs_prot)
+{
+ if (fs_prot->miss_rule) {
+ mlx5_del_flow_rules(fs_prot->miss_rule);
+ fs_prot->miss_rule = NULL;
+ }
+
+ if (fs_prot->miss_group) {
+ mlx5_destroy_flow_group(fs_prot->miss_group);
+ fs_prot->miss_group = NULL;
+ }
+
+ if (fs_prot->ft) {
+ mlx5_destroy_flow_table(fs_prot->ft);
+ fs_prot->ft = NULL;
+ }
+}
+
+static int rx_fs_create(struct mlx5e_priv *priv,
+ struct mlx5e_accel_fs_esp_prot *fs_prot)
+{
+ int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
+ struct mlx5_flow_table_attr ft_attr = {};
+ struct mlx5_flow_group *miss_group;
+ struct mlx5_flow_handle *miss_rule;
+ MLX5_DECLARE_FLOW_ACT(flow_act);
+ struct mlx5_flow_spec *spec;
+ struct mlx5_flow_table *ft;
+ u32 *flow_group_in;
+ int err = 0;
+
+ flow_group_in = kvzalloc(inlen, GFP_KERNEL);
+ spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
+ if (!flow_group_in || !spec) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /* Create FT */
+ ft_attr.max_fte = NUM_IPSEC_FTE;
+ ft_attr.level = MLX5E_ACCEL_FS_ESP_FT_LEVEL;
+ ft_attr.prio = MLX5E_NIC_PRIO;
+ ft_attr.autogroup.num_reserved_entries = 1;
+ ft_attr.autogroup.max_num_groups = 1;
+ ft = mlx5_create_auto_grouped_flow_table(priv->fs.ns, &ft_attr);
+ if (IS_ERR(ft)) {
+ err = PTR_ERR(ft);
+ netdev_err(priv->netdev, "fail to create ipsec rx ft err=%d\n", err);
+ goto out;
+ }
+ fs_prot->ft = ft;
+
+ /* Create miss_group */
+ MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, ft->max_fte - 1);
+ MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, ft->max_fte - 1);
+ miss_group = mlx5_create_flow_group(ft, flow_group_in);
+ if (IS_ERR(miss_group)) {
+ err = PTR_ERR(miss_group);
+ netdev_err(priv->netdev, "fail to create ipsec rx miss_group err=%d\n", err);
+ goto out;
+ }
+ fs_prot->miss_group = miss_group;
+
+ /* Create miss rule */
+ miss_rule = mlx5_add_flow_rules(ft, spec, &flow_act, &fs_prot->default_dest, 1);
+ if (IS_ERR(miss_rule)) {
+ err = PTR_ERR(miss_rule);
+ netdev_err(priv->netdev, "fail to create ipsec rx miss_rule err=%d\n", err);
+ goto out;
+ }
+ fs_prot->miss_rule = miss_rule;
+
+out:
+ kfree(flow_group_in);
+ kfree(spec);
+ return err;
+}
+
+static int rx_destroy(struct mlx5e_priv *priv, enum accel_fs_esp_type type)
+{
+ struct mlx5e_accel_fs_esp_prot *fs_prot;
+ struct mlx5e_accel_fs_esp *accel_esp;
+
+ accel_esp = priv->ipsec->rx_fs;
+
+ /* The netdev unreg already happened, so all offloaded rule are already removed */
+ fs_prot = &accel_esp->fs_prot[type];
+
+ rx_fs_destroy(fs_prot);
+
+ rx_err_destroy_ft(priv, &fs_prot->rx_err);
+
+ return 0;
+}
+
+static int rx_create(struct mlx5e_priv *priv, enum accel_fs_esp_type type)
+{
+ struct mlx5e_accel_fs_esp_prot *fs_prot;
+ struct mlx5e_accel_fs_esp *accel_esp;
+ int err;
+
+ accel_esp = priv->ipsec->rx_fs;
+ fs_prot = &accel_esp->fs_prot[type];
+
+ fs_prot->default_dest = mlx5e_ttc_get_default_dest(priv, fs_esp2tt(type));
+
+ err = rx_err_create_ft(priv, fs_prot, &fs_prot->rx_err);
+ if (err)
+ return err;
+
+ err = rx_fs_create(priv, fs_prot);
+ if (err)
+ rx_destroy(priv, type);
+
+ return err;
+}
+
+static int rx_ft_get(struct mlx5e_priv *priv, enum accel_fs_esp_type type)
+{
+ struct mlx5e_accel_fs_esp_prot *fs_prot;
+ struct mlx5_flow_destination dest = {};
+ struct mlx5e_accel_fs_esp *accel_esp;
+ int err = 0;
+
+ accel_esp = priv->ipsec->rx_fs;
+ fs_prot = &accel_esp->fs_prot[type];
+ mutex_lock(&fs_prot->prot_mutex);
+ if (fs_prot->refcnt++)
+ goto out;
+
+ /* create FT */
+ err = rx_create(priv, type);
+ if (err) {
+ fs_prot->refcnt--;
+ goto out;
+ }
+
+ /* connect */
+ dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+ dest.ft = fs_prot->ft;
+ mlx5e_ttc_fwd_dest(priv, fs_esp2tt(type), &dest);
+
+out:
+ mutex_unlock(&fs_prot->prot_mutex);
+ return err;
+}
+
+static void rx_ft_put(struct mlx5e_priv *priv, enum accel_fs_esp_type type)
+{
+ struct mlx5e_accel_fs_esp_prot *fs_prot;
+ struct mlx5e_accel_fs_esp *accel_esp;
+
+ accel_esp = priv->ipsec->rx_fs;
+ fs_prot = &accel_esp->fs_prot[type];
+ mutex_lock(&fs_prot->prot_mutex);
+ if (--fs_prot->refcnt)
+ goto out;
+
+ /* disconnect */
+ mlx5e_ttc_fwd_default_dest(priv, fs_esp2tt(type));
+
+ /* remove FT */
+ rx_destroy(priv, type);
+
+out:
+ mutex_unlock(&fs_prot->prot_mutex);
+}
+
+static void setup_fte_common(struct mlx5_accel_esp_xfrm_attrs *attrs,
+ u32 ipsec_obj_id,
+ struct mlx5_flow_spec *spec,
+ struct mlx5_flow_act *flow_act)
+{
+ u8 ip_version = attrs->is_ipv6 ? 6 : 4;
+
+ spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS | MLX5_MATCH_MISC_PARAMETERS;
+
+ /* ip_version */
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version);
+ MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version, ip_version);
+
+ /* Non fragmented */
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.frag);
+ MLX5_SET(fte_match_param, spec->match_value, outer_headers.frag, 0);
+
+ /* ESP header */
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol);
+ MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, IPPROTO_ESP);
+
+ /* SPI number */
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, misc_parameters.outer_esp_spi);
+ MLX5_SET(fte_match_param, spec->match_value, misc_parameters.outer_esp_spi,
+ be32_to_cpu(attrs->spi));
+
+ if (ip_version == 4) {
+ memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
+ outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4),
+ &attrs->saddr.a4, 4);
+ memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
+ outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
+ &attrs->daddr.a4, 4);
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4);
+ MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
+ } else {
+ memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
+ outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6),
+ &attrs->saddr.a6, 16);
+ memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
+ outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
+ &attrs->daddr.a6, 16);
+ memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
+ outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6),
+ 0xff, 16);
+ memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
+ outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
+ 0xff, 16);
+ }
+
+ flow_act->ipsec_obj_id = ipsec_obj_id;
+ flow_act->flags |= FLOW_ACT_NO_APPEND;
+}
+
+static int rx_add_rule(struct mlx5e_priv *priv,
+ struct mlx5_accel_esp_xfrm_attrs *attrs,
+ u32 ipsec_obj_id,
+ struct mlx5e_ipsec_rule *ipsec_rule)
+{
+ u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
+ struct mlx5_modify_hdr *modify_hdr = NULL;
+ struct mlx5e_accel_fs_esp_prot *fs_prot;
+ struct mlx5_flow_destination dest = {};
+ struct mlx5e_accel_fs_esp *accel_esp;
+ struct mlx5_flow_act flow_act = {};
+ struct mlx5_flow_handle *rule;
+ enum accel_fs_esp_type type;
+ struct mlx5_flow_spec *spec;
+ int err = 0;
+
+ accel_esp = priv->ipsec->rx_fs;
+ type = attrs->is_ipv6 ? ACCEL_FS_ESP6 : ACCEL_FS_ESP4;
+ fs_prot = &accel_esp->fs_prot[type];
+
+ err = rx_ft_get(priv, type);
+ if (err)
+ return err;
+
+ spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
+ if (!spec) {
+ err = -ENOMEM;
+ goto out_err;
+ }
+
+ setup_fte_common(attrs, ipsec_obj_id, spec, &flow_act);
+
+ /* Set 1 bit ipsec marker */
+ /* Set 24 bit ipsec_obj_id */
+ MLX5_SET(set_action_in, action, action_type, MLX5_ACTION_TYPE_SET);
+ MLX5_SET(set_action_in, action, field, MLX5_ACTION_IN_FIELD_METADATA_REG_B);
+ MLX5_SET(set_action_in, action, data, (ipsec_obj_id << 1) | 0x1);
+ MLX5_SET(set_action_in, action, offset, 7);
+ MLX5_SET(set_action_in, action, length, 25);
+
+ modify_hdr = mlx5_modify_header_alloc(priv->mdev, MLX5_FLOW_NAMESPACE_KERNEL,
+ 1, action);
+ if (IS_ERR(modify_hdr)) {
+ err = PTR_ERR(modify_hdr);
+ netdev_err(priv->netdev,
+ "fail to alloc ipsec set modify_header_id err=%d\n", err);
+ modify_hdr = NULL;
+ goto out_err;
+ }
+
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
+ MLX5_FLOW_CONTEXT_ACTION_IPSEC_DECRYPT |
+ MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
+ dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+ flow_act.modify_hdr = modify_hdr;
+ dest.ft = fs_prot->rx_err.ft;
+ rule = mlx5_add_flow_rules(fs_prot->ft, spec, &flow_act, &dest, 1);
+ if (IS_ERR(rule)) {
+ err = PTR_ERR(rule);
+ netdev_err(priv->netdev, "fail to add ipsec rule attrs->action=0x%x, err=%d\n",
+ attrs->action, err);
+ goto out_err;
+ }
+
+ ipsec_rule->rule = rule;
+ ipsec_rule->set_modify_hdr = modify_hdr;
+ goto out;
+
+out_err:
+ if (modify_hdr)
+ mlx5_modify_header_dealloc(priv->mdev, modify_hdr);
+ rx_ft_put(priv, type);
+
+out:
+ kvfree(spec);
+ return err;
+}
+
+static void rx_del_rule(struct mlx5e_priv *priv,
+ struct mlx5_accel_esp_xfrm_attrs *attrs,
+ struct mlx5e_ipsec_rule *ipsec_rule)
+{
+ mlx5_del_flow_rules(ipsec_rule->rule);
+ ipsec_rule->rule = NULL;
+
+ mlx5_modify_header_dealloc(priv->mdev, ipsec_rule->set_modify_hdr);
+ ipsec_rule->set_modify_hdr = NULL;
+
+ rx_ft_put(priv, attrs->is_ipv6 ? ACCEL_FS_ESP6 : ACCEL_FS_ESP4);
+}
+
+int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_priv *priv,
+ struct mlx5_accel_esp_xfrm_attrs *attrs,
+ u32 ipsec_obj_id,
+ struct mlx5e_ipsec_rule *ipsec_rule)
+{
+ if (!priv->ipsec->rx_fs || attrs->action != MLX5_ACCEL_ESP_ACTION_DECRYPT)
+ return -EOPNOTSUPP;
+
+ return rx_add_rule(priv, attrs, ipsec_obj_id, ipsec_rule);
+}
+
+void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_priv *priv,
+ struct mlx5_accel_esp_xfrm_attrs *attrs,
+ struct mlx5e_ipsec_rule *ipsec_rule)
+{
+ if (!priv->ipsec->rx_fs)
+ return;
+
+ rx_del_rule(priv, attrs, ipsec_rule);
+}
+
+static void fs_cleanup_rx(struct mlx5e_priv *priv)
+{
+ struct mlx5e_accel_fs_esp_prot *fs_prot;
+ struct mlx5e_accel_fs_esp *accel_esp;
+ enum accel_fs_esp_type i;
+
+ accel_esp = priv->ipsec->rx_fs;
+ for (i = 0; i < ACCEL_FS_ESP_NUM_TYPES; i++) {
+ fs_prot = &accel_esp->fs_prot[i];
+ mutex_destroy(&fs_prot->prot_mutex);
+ WARN_ON(fs_prot->refcnt);
+ }
+ kfree(priv->ipsec->rx_fs);
+ priv->ipsec->rx_fs = NULL;
+}
+
+static int fs_init_rx(struct mlx5e_priv *priv)
+{
+ struct mlx5e_accel_fs_esp_prot *fs_prot;
+ struct mlx5e_accel_fs_esp *accel_esp;
+ enum accel_fs_esp_type i;
+
+ priv->ipsec->rx_fs =
+ kzalloc(sizeof(struct mlx5e_accel_fs_esp), GFP_KERNEL);
+ if (!priv->ipsec->rx_fs)
+ return -ENOMEM;
+
+ accel_esp = priv->ipsec->rx_fs;
+ for (i = 0; i < ACCEL_FS_ESP_NUM_TYPES; i++) {
+ fs_prot = &accel_esp->fs_prot[i];
+ mutex_init(&fs_prot->prot_mutex);
+ }
+
+ return 0;
+}
+
+void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_priv *priv)
+{
+ if (!priv->ipsec->rx_fs)
+ return;
+
+ fs_cleanup_rx(priv);
+}
+
+int mlx5e_accel_ipsec_fs_init(struct mlx5e_priv *priv)
+{
+ if (!mlx5_is_ipsec_device(priv->mdev) || !priv->ipsec)
+ return -EOPNOTSUPP;
+
+ return fs_init_rx(priv);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.h
new file mode 100644
index 000000000000..3389b3bb3ef8
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
+
+#ifndef __MLX5_IPSEC_STEERING_H__
+#define __MLX5_IPSEC_STEERING_H__
+
+#include "en.h"
+#include "ipsec.h"
+#include "accel/ipsec_offload.h"
+#include "en/fs.h"
+
+#ifdef CONFIG_MLX5_EN_IPSEC
+void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_priv *priv);
+int mlx5e_accel_ipsec_fs_init(struct mlx5e_priv *priv);
+int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_priv *priv,
+ struct mlx5_accel_esp_xfrm_attrs *attrs,
+ u32 ipsec_obj_id,
+ struct mlx5e_ipsec_rule *ipsec_rule);
+void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_priv *priv,
+ struct mlx5_accel_esp_xfrm_attrs *attrs,
+ struct mlx5e_ipsec_rule *ipsec_rule);
+#else
+static inline void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_priv *priv) {}
+static inline int mlx5e_accel_ipsec_fs_init(struct mlx5e_priv *priv) { return 0; }
+#endif
+#endif /* __MLX5_IPSEC_STEERING_H__ */
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 824b87ac8f9e..93a8d68815ad 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
@@ -360,6 +360,62 @@ struct sk_buff *mlx5e_ipsec_handle_rx_skb(struct net_device *netdev,
return skb;
}
+enum {
+ MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED,
+ MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_AUTH_FAILED,
+ MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_BAD_TRAILER,
+};
+
+void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
+ struct sk_buff *skb,
+ struct mlx5_cqe64 *cqe)
+{
+ u32 ipsec_meta_data = be32_to_cpu(cqe->ft_metadata);
+ u8 ipsec_syndrome = ipsec_meta_data & 0xFF;
+ struct mlx5e_priv *priv;
+ struct xfrm_offload *xo;
+ struct xfrm_state *xs;
+ struct sec_path *sp;
+ u32 sa_handle;
+
+ sa_handle = MLX5_IPSEC_METADATA_HANDLE(ipsec_meta_data);
+ priv = netdev_priv(netdev);
+ sp = secpath_set(skb);
+ if (unlikely(!sp)) {
+ atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_sp_alloc);
+ return;
+ }
+
+ xs = mlx5e_ipsec_sadb_rx_lookup(priv->ipsec, sa_handle);
+ if (unlikely(!xs)) {
+ atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_sadb_miss);
+ return;
+ }
+
+ sp = skb_sec_path(skb);
+ sp->xvec[sp->len++] = xs;
+ sp->olen++;
+
+ xo = xfrm_offload(skb);
+ xo->flags = CRYPTO_DONE;
+
+ switch (ipsec_syndrome & MLX5_IPSEC_METADATA_SYNDROM_MASK) {
+ case MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED:
+ xo->status = CRYPTO_SUCCESS;
+ if (WARN_ON_ONCE(priv->ipsec->no_trailer))
+ xo->flags |= XFRM_ESP_NO_TRAILER;
+ break;
+ case MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_AUTH_FAILED:
+ xo->status = CRYPTO_TUNNEL_ESP_AUTH_FAILED;
+ break;
+ case MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_BAD_TRAILER:
+ xo->status = CRYPTO_INVALID_PACKET_SYNTAX;
+ break;
+ default:
+ atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_syndrome);
+ }
+}
+
bool mlx5e_ipsec_feature_check(struct sk_buff *skb, struct net_device *netdev,
netdev_features_t features)
{
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 ba02643586a5..f96e786db158 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
@@ -34,16 +34,19 @@
#ifndef __MLX5E_IPSEC_RXTX_H__
#define __MLX5E_IPSEC_RXTX_H__
-#ifdef CONFIG_MLX5_EN_IPSEC
-
#include <linux/skbuff.h>
#include <net/xfrm.h>
#include "en.h"
#include "en/txrx.h"
+#define MLX5_IPSEC_METADATA_MARKER_MASK (0x80)
+#define MLX5_IPSEC_METADATA_SYNDROM_MASK (0x7F)
+#define MLX5_IPSEC_METADATA_HANDLE(metadata) (((metadata) >> 8) & 0xFF)
+
+#ifdef CONFIG_MLX5_EN_IPSEC
+
struct sk_buff *mlx5e_ipsec_handle_rx_skb(struct net_device *netdev,
struct sk_buff *skb, u32 *cqe_bcnt);
-void mlx5e_ipsec_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
void mlx5e_ipsec_inverse_table_init(void);
bool mlx5e_ipsec_feature_check(struct sk_buff *skb, struct net_device *netdev,
@@ -55,7 +58,21 @@ void mlx5e_ipsec_set_iv(struct sk_buff *skb, struct xfrm_state *x,
bool mlx5e_ipsec_handle_tx_skb(struct mlx5e_priv *priv,
struct mlx5_wqe_eth_seg *eseg,
struct sk_buff *skb);
+void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
+ struct sk_buff *skb,
+ struct mlx5_cqe64 *cqe);
+static inline bool mlx5_ipsec_is_rx_flow(struct mlx5_cqe64 *cqe)
+{
+ return !!(MLX5_IPSEC_METADATA_MARKER_MASK & be32_to_cpu(cqe->ft_metadata));
+}
+#else
+static inline
+void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
+ struct sk_buff *skb,
+ struct mlx5_cqe64 *cqe)
+{}
+static inline bool mlx5_ipsec_is_rx_flow(struct mlx5_cqe64 *cqe) { return false; }
#endif /* CONFIG_MLX5_EN_IPSEC */
#endif /* __MLX5E_IPSEC_RXTX_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
index 452fcf59c36b..1b392696280d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
@@ -3,31 +3,8 @@
#include "en.h"
#include "en_accel/ktls.h"
-
-u16 mlx5e_ktls_get_stop_room(struct mlx5e_txqsq *sq)
-{
- u16 num_dumps, stop_room = 0;
-
- num_dumps = mlx5e_ktls_dumps_num_wqes(sq, MAX_SKB_FRAGS, TLS_MAX_PAYLOAD_SIZE);
-
- stop_room += mlx5e_stop_room_for_wqe(MLX5E_KTLS_STATIC_WQEBBS);
- stop_room += mlx5e_stop_room_for_wqe(MLX5E_KTLS_PROGRESS_WQEBBS);
- stop_room += num_dumps * mlx5e_stop_room_for_wqe(MLX5E_KTLS_DUMP_WQEBBS);
-
- return stop_room;
-}
-
-static int mlx5e_ktls_create_tis(struct mlx5_core_dev *mdev, u32 *tisn)
-{
- u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};
- void *tisc;
-
- tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
-
- MLX5_SET(tisc, tisc, tls_en, 1);
-
- return mlx5e_create_tis(mdev, in, tisn);
-}
+#include "en_accel/ktls_utils.h"
+#include "en_accel/fs_tcp.h"
static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk,
enum tls_offload_ctx_dir direction,
@@ -35,42 +12,17 @@ static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk,
u32 start_offload_tcp_sn)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
- struct mlx5e_ktls_offload_context_tx *tx_priv;
- struct tls_context *tls_ctx = tls_get_ctx(sk);
struct mlx5_core_dev *mdev = priv->mdev;
int err;
- if (WARN_ON(direction != TLS_OFFLOAD_CTX_DIR_TX))
- return -EINVAL;
-
if (WARN_ON(!mlx5e_ktls_type_check(mdev, crypto_info)))
return -EOPNOTSUPP;
- tx_priv = kvzalloc(sizeof(*tx_priv), GFP_KERNEL);
- if (!tx_priv)
- return -ENOMEM;
-
- tx_priv->expected_seq = start_offload_tcp_sn;
- tx_priv->crypto_info = *(struct tls12_crypto_info_aes_gcm_128 *)crypto_info;
- mlx5e_set_ktls_tx_priv_ctx(tls_ctx, tx_priv);
-
- /* tc and underlay_qpn values are not in use for tls tis */
- err = mlx5e_ktls_create_tis(mdev, &tx_priv->tisn);
- if (err)
- goto create_tis_fail;
-
- err = mlx5_ktls_create_key(mdev, crypto_info, &tx_priv->key_id);
- if (err)
- goto encryption_key_create_fail;
+ if (direction == TLS_OFFLOAD_CTX_DIR_TX)
+ err = mlx5e_ktls_add_tx(netdev, sk, crypto_info, start_offload_tcp_sn);
+ else
+ err = mlx5e_ktls_add_rx(netdev, sk, crypto_info, start_offload_tcp_sn);
- mlx5e_ktls_tx_offload_set_pending(tx_priv);
-
- return 0;
-
-encryption_key_create_fail:
- mlx5e_destroy_tis(priv->mdev, tx_priv->tisn);
-create_tis_fail:
- kvfree(tx_priv);
return err;
}
@@ -78,29 +30,72 @@ static void mlx5e_ktls_del(struct net_device *netdev,
struct tls_context *tls_ctx,
enum tls_offload_ctx_dir direction)
{
- struct mlx5e_priv *priv = netdev_priv(netdev);
- struct mlx5e_ktls_offload_context_tx *tx_priv =
- mlx5e_get_ktls_tx_priv_ctx(tls_ctx);
+ if (direction == TLS_OFFLOAD_CTX_DIR_TX)
+ mlx5e_ktls_del_tx(netdev, tls_ctx);
+ else
+ mlx5e_ktls_del_rx(netdev, tls_ctx);
+}
- mlx5e_destroy_tis(priv->mdev, tx_priv->tisn);
- mlx5_ktls_destroy_key(priv->mdev, tx_priv->key_id);
- kvfree(tx_priv);
+static int mlx5e_ktls_resync(struct net_device *netdev,
+ struct sock *sk, u32 seq, u8 *rcd_sn,
+ enum tls_offload_ctx_dir direction)
+{
+ if (unlikely(direction != TLS_OFFLOAD_CTX_DIR_RX))
+ return -EOPNOTSUPP;
+
+ mlx5e_ktls_rx_resync(netdev, sk, seq, rcd_sn);
+ return 0;
}
static const struct tlsdev_ops mlx5e_ktls_ops = {
.tls_dev_add = mlx5e_ktls_add,
.tls_dev_del = mlx5e_ktls_del,
+ .tls_dev_resync = mlx5e_ktls_resync,
};
void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv)
{
struct net_device *netdev = priv->netdev;
+ struct mlx5_core_dev *mdev = priv->mdev;
- if (!mlx5_accel_is_ktls_device(priv->mdev))
- return;
+ if (mlx5_accel_is_ktls_tx(mdev)) {
+ netdev->hw_features |= NETIF_F_HW_TLS_TX;
+ netdev->features |= NETIF_F_HW_TLS_TX;
+ }
- netdev->hw_features |= NETIF_F_HW_TLS_TX;
- netdev->features |= NETIF_F_HW_TLS_TX;
+ if (mlx5_accel_is_ktls_rx(mdev))
+ netdev->hw_features |= NETIF_F_HW_TLS_RX;
netdev->tlsdev_ops = &mlx5e_ktls_ops;
}
+
+int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable)
+{
+ struct mlx5e_priv *priv = netdev_priv(netdev);
+ int err = 0;
+
+ mutex_lock(&priv->state_lock);
+ if (enable)
+ err = mlx5e_accel_fs_tcp_create(priv);
+ else
+ mlx5e_accel_fs_tcp_destroy(priv);
+ mutex_unlock(&priv->state_lock);
+
+ return err;
+}
+
+int mlx5e_ktls_init_rx(struct mlx5e_priv *priv)
+{
+ int err = 0;
+
+ if (priv->netdev->features & NETIF_F_HW_TLS_RX)
+ err = mlx5e_accel_fs_tcp_create(priv);
+
+ return err;
+}
+
+void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv)
+{
+ if (priv->netdev->features & NETIF_F_HW_TLS_RX)
+ mlx5e_accel_fs_tcp_destroy(priv);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h
index c6180892cfcb..baa58b62e8df 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h
@@ -7,122 +7,32 @@
#include "en.h"
#ifdef CONFIG_MLX5_EN_TLS
-#include <net/tls.h>
-#include "accel/tls.h"
-#include "en_accel/tls_rxtx.h"
-#define MLX5E_KTLS_STATIC_UMR_WQE_SZ \
- (offsetof(struct mlx5e_umr_wqe, tls_static_params_ctx) + \
- MLX5_ST_SZ_BYTES(tls_static_params))
-#define MLX5E_KTLS_STATIC_WQEBBS \
- (DIV_ROUND_UP(MLX5E_KTLS_STATIC_UMR_WQE_SZ, MLX5_SEND_WQE_BB))
-
-#define MLX5E_KTLS_PROGRESS_WQE_SZ \
- (offsetof(struct mlx5e_tx_wqe, tls_progress_params_ctx) + \
- MLX5_ST_SZ_BYTES(tls_progress_params))
-#define MLX5E_KTLS_PROGRESS_WQEBBS \
- (DIV_ROUND_UP(MLX5E_KTLS_PROGRESS_WQE_SZ, MLX5_SEND_WQE_BB))
-
-struct mlx5e_dump_wqe {
- struct mlx5_wqe_ctrl_seg ctrl;
- struct mlx5_wqe_data_seg data;
-};
-
-#define MLX5E_TLS_FETCH_UMR_WQE(sq, pi) \
- ((struct mlx5e_umr_wqe *)mlx5e_fetch_wqe(&(sq)->wq, pi, MLX5E_KTLS_STATIC_UMR_WQE_SZ))
-#define MLX5E_TLS_FETCH_PROGRESS_WQE(sq, pi) \
- ((struct mlx5e_tx_wqe *)mlx5e_fetch_wqe(&(sq)->wq, pi, MLX5E_KTLS_PROGRESS_WQE_SZ))
-#define MLX5E_TLS_FETCH_DUMP_WQE(sq, pi) \
- ((struct mlx5e_dump_wqe *)mlx5e_fetch_wqe(&(sq)->wq, pi, \
- sizeof(struct mlx5e_dump_wqe)))
-
-#define MLX5E_KTLS_DUMP_WQEBBS \
- (DIV_ROUND_UP(sizeof(struct mlx5e_dump_wqe), MLX5_SEND_WQE_BB))
-
-enum {
- MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD = 0,
- MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_OFFLOAD = 1,
- MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_AUTHENTICATION = 2,
-};
-
-enum {
- MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START = 0,
- MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING = 1,
- MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_SEARCHING = 2,
-};
-
-struct mlx5e_ktls_offload_context_tx {
- struct tls_offload_context_tx *tx_ctx;
- struct tls12_crypto_info_aes_gcm_128 crypto_info;
- u32 expected_seq;
- u32 tisn;
- u32 key_id;
- bool ctx_post_pending;
-};
-
-struct mlx5e_ktls_offload_context_tx_shadow {
- struct tls_offload_context_tx tx_ctx;
- struct mlx5e_ktls_offload_context_tx *priv_tx;
-};
+void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv);
+int mlx5e_ktls_init_rx(struct mlx5e_priv *priv);
+void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv);
+int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable);
+#else
-static inline void
-mlx5e_set_ktls_tx_priv_ctx(struct tls_context *tls_ctx,
- struct mlx5e_ktls_offload_context_tx *priv_tx)
+static inline void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv)
{
- struct tls_offload_context_tx *tx_ctx = tls_offload_ctx_tx(tls_ctx);
- struct mlx5e_ktls_offload_context_tx_shadow *shadow;
-
- BUILD_BUG_ON(sizeof(*shadow) > TLS_OFFLOAD_CONTEXT_SIZE_TX);
-
- shadow = (struct mlx5e_ktls_offload_context_tx_shadow *)tx_ctx;
-
- shadow->priv_tx = priv_tx;
- priv_tx->tx_ctx = tx_ctx;
}
-static inline struct mlx5e_ktls_offload_context_tx *
-mlx5e_get_ktls_tx_priv_ctx(struct tls_context *tls_ctx)
+static inline int mlx5e_ktls_init_rx(struct mlx5e_priv *priv)
{
- struct tls_offload_context_tx *tx_ctx = tls_offload_ctx_tx(tls_ctx);
- struct mlx5e_ktls_offload_context_tx_shadow *shadow;
-
- BUILD_BUG_ON(sizeof(*shadow) > TLS_OFFLOAD_CONTEXT_SIZE_TX);
-
- shadow = (struct mlx5e_ktls_offload_context_tx_shadow *)tx_ctx;
-
- return shadow->priv_tx;
+ return 0;
}
-void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv);
-void mlx5e_ktls_tx_offload_set_pending(struct mlx5e_ktls_offload_context_tx *priv_tx);
-
-bool mlx5e_ktls_handle_tx_skb(struct tls_context *tls_ctx, struct mlx5e_txqsq *sq,
- struct sk_buff *skb, int datalen,
- struct mlx5e_accel_tx_tls_state *state);
-void mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq,
- struct mlx5e_tx_wqe_info *wi,
- u32 *dma_fifo_cc);
-u16 mlx5e_ktls_get_stop_room(struct mlx5e_txqsq *sq);
-
-static inline u8
-mlx5e_ktls_dumps_num_wqes(struct mlx5e_txqsq *sq, unsigned int nfrags,
- unsigned int sync_len)
+static inline void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv)
{
- /* Given the MTU and sync_len, calculates an upper bound for the
- * number of DUMP WQEs needed for the TX resync of a record.
- */
- return nfrags + DIV_ROUND_UP(sync_len, sq->hw_mtu);
}
-#else
-static inline void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv)
+static inline int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable)
{
+ netdev_warn(netdev, "kTLS is not supported\n");
+ return -EOPNOTSUPP;
}
-static inline void
-mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq,
- struct mlx5e_tx_wqe_info *wi,
- u32 *dma_fifo_cc) {}
#endif
#endif /* __MLX5E_TLS_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c
new file mode 100644
index 000000000000..acf6d80a6bb7
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c
@@ -0,0 +1,680 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+// Copyright (c) 2019 Mellanox Technologies.
+
+#include <net/inet6_hashtables.h>
+#include "en_accel/en_accel.h"
+#include "en_accel/tls.h"
+#include "en_accel/ktls_txrx.h"
+#include "en_accel/ktls_utils.h"
+#include "en_accel/fs_tcp.h"
+
+struct accel_rule {
+ struct work_struct work;
+ struct mlx5e_priv *priv;
+ struct mlx5_flow_handle *rule;
+};
+
+#define PROGRESS_PARAMS_WRITE_UNIT 64
+#define PROGRESS_PARAMS_PADDED_SIZE \
+ (ALIGN(sizeof(struct mlx5_wqe_tls_progress_params_seg), \
+ PROGRESS_PARAMS_WRITE_UNIT))
+
+struct mlx5e_ktls_rx_resync_buf {
+ union {
+ struct mlx5_wqe_tls_progress_params_seg progress;
+ u8 pad[PROGRESS_PARAMS_PADDED_SIZE];
+ } ____cacheline_aligned_in_smp;
+ dma_addr_t dma_addr;
+ struct mlx5e_ktls_offload_context_rx *priv_rx;
+};
+
+enum {
+ MLX5E_PRIV_RX_FLAG_DELETING,
+ MLX5E_NUM_PRIV_RX_FLAGS,
+};
+
+struct mlx5e_ktls_rx_resync_ctx {
+ struct tls_offload_resync_async core;
+ struct work_struct work;
+ struct mlx5e_priv *priv;
+ refcount_t refcnt;
+ __be64 sw_rcd_sn_be;
+ u32 seq;
+};
+
+struct mlx5e_ktls_offload_context_rx {
+ struct tls12_crypto_info_aes_gcm_128 crypto_info;
+ struct accel_rule rule;
+ struct sock *sk;
+ struct mlx5e_rq_stats *stats;
+ struct completion add_ctx;
+ u32 tirn;
+ u32 key_id;
+ u32 rxq;
+ DECLARE_BITMAP(flags, MLX5E_NUM_PRIV_RX_FLAGS);
+
+ /* resync */
+ struct mlx5e_ktls_rx_resync_ctx resync;
+};
+
+static int mlx5e_ktls_create_tir(struct mlx5_core_dev *mdev, u32 *tirn, u32 rqtn)
+{
+ int err, inlen;
+ void *tirc;
+ u32 *in;
+
+ inlen = MLX5_ST_SZ_BYTES(create_tir_in);
+ in = kvzalloc(inlen, GFP_KERNEL);
+ if (!in)
+ return -ENOMEM;
+
+ tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
+
+ MLX5_SET(tirc, tirc, transport_domain, mdev->mlx5e_res.td.tdn);
+ MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
+ MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_INVERTED_XOR8);
+ MLX5_SET(tirc, tirc, indirect_table, rqtn);
+ MLX5_SET(tirc, tirc, tls_en, 1);
+ MLX5_SET(tirc, tirc, self_lb_block,
+ MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST |
+ MLX5_TIRC_SELF_LB_BLOCK_BLOCK_MULTICAST);
+
+ err = mlx5_core_create_tir(mdev, in, tirn);
+
+ kvfree(in);
+ return err;
+}
+
+static void accel_rule_handle_work(struct work_struct *work)
+{
+ struct mlx5e_ktls_offload_context_rx *priv_rx;
+ struct accel_rule *accel_rule;
+ struct mlx5_flow_handle *rule;
+
+ accel_rule = container_of(work, struct accel_rule, work);
+ priv_rx = container_of(accel_rule, struct mlx5e_ktls_offload_context_rx, rule);
+ if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags)))
+ goto out;
+
+ rule = mlx5e_accel_fs_add_sk(accel_rule->priv, priv_rx->sk,
+ priv_rx->tirn, MLX5_FS_DEFAULT_FLOW_TAG);
+ if (!IS_ERR_OR_NULL(rule))
+ accel_rule->rule = rule;
+out:
+ complete(&priv_rx->add_ctx);
+}
+
+static void accel_rule_init(struct accel_rule *rule, struct mlx5e_priv *priv,
+ struct sock *sk)
+{
+ INIT_WORK(&rule->work, accel_rule_handle_work);
+ rule->priv = priv;
+}
+
+static void icosq_fill_wi(struct mlx5e_icosq *sq, u16 pi,
+ struct mlx5e_icosq_wqe_info *wi)
+{
+ sq->db.wqe_info[pi] = *wi;
+}
+
+static struct mlx5_wqe_ctrl_seg *
+post_static_params(struct mlx5e_icosq *sq,
+ struct mlx5e_ktls_offload_context_rx *priv_rx)
+{
+ struct mlx5e_set_tls_static_params_wqe *wqe;
+ struct mlx5e_icosq_wqe_info wi;
+ u16 pi, num_wqebbs, room;
+
+ num_wqebbs = MLX5E_TLS_SET_STATIC_PARAMS_WQEBBS;
+ room = mlx5e_stop_room_for_wqe(num_wqebbs);
+ if (unlikely(!mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, room)))
+ return ERR_PTR(-ENOSPC);
+
+ pi = mlx5e_icosq_get_next_pi(sq, num_wqebbs);
+ wqe = MLX5E_TLS_FETCH_SET_STATIC_PARAMS_WQE(sq, pi);
+ mlx5e_ktls_build_static_params(wqe, sq->pc, sq->sqn, &priv_rx->crypto_info,
+ priv_rx->tirn, priv_rx->key_id,
+ priv_rx->resync.seq, false,
+ TLS_OFFLOAD_CTX_DIR_RX);
+ wi = (struct mlx5e_icosq_wqe_info) {
+ .wqe_type = MLX5E_ICOSQ_WQE_UMR_TLS,
+ .num_wqebbs = num_wqebbs,
+ .tls_set_params.priv_rx = priv_rx,
+ };
+ icosq_fill_wi(sq, pi, &wi);
+ sq->pc += num_wqebbs;
+
+ return &wqe->ctrl;
+}
+
+static struct mlx5_wqe_ctrl_seg *
+post_progress_params(struct mlx5e_icosq *sq,
+ struct mlx5e_ktls_offload_context_rx *priv_rx,
+ u32 next_record_tcp_sn)
+{
+ struct mlx5e_set_tls_progress_params_wqe *wqe;
+ struct mlx5e_icosq_wqe_info wi;
+ u16 pi, num_wqebbs, room;
+
+ num_wqebbs = MLX5E_TLS_SET_PROGRESS_PARAMS_WQEBBS;
+ room = mlx5e_stop_room_for_wqe(num_wqebbs);
+ if (unlikely(!mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, room)))
+ return ERR_PTR(-ENOSPC);
+
+ pi = mlx5e_icosq_get_next_pi(sq, num_wqebbs);
+ wqe = MLX5E_TLS_FETCH_SET_PROGRESS_PARAMS_WQE(sq, pi);
+ mlx5e_ktls_build_progress_params(wqe, sq->pc, sq->sqn, priv_rx->tirn, false,
+ next_record_tcp_sn,
+ TLS_OFFLOAD_CTX_DIR_RX);
+ wi = (struct mlx5e_icosq_wqe_info) {
+ .wqe_type = MLX5E_ICOSQ_WQE_SET_PSV_TLS,
+ .num_wqebbs = num_wqebbs,
+ .tls_set_params.priv_rx = priv_rx,
+ };
+
+ icosq_fill_wi(sq, pi, &wi);
+ sq->pc += num_wqebbs;
+
+ return &wqe->ctrl;
+}
+
+static int post_rx_param_wqes(struct mlx5e_channel *c,
+ struct mlx5e_ktls_offload_context_rx *priv_rx,
+ u32 next_record_tcp_sn)
+{
+ struct mlx5_wqe_ctrl_seg *cseg;
+ struct mlx5e_icosq *sq;
+ int err;
+
+ err = 0;
+ sq = &c->async_icosq;
+ spin_lock(&c->async_icosq_lock);
+
+ cseg = post_static_params(sq, priv_rx);
+ if (IS_ERR(cseg))
+ goto err_out;
+ cseg = post_progress_params(sq, priv_rx, next_record_tcp_sn);
+ if (IS_ERR(cseg))
+ goto err_out;
+
+ mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, cseg);
+unlock:
+ spin_unlock(&c->async_icosq_lock);
+
+ return err;
+
+err_out:
+ priv_rx->stats->tls_resync_req_skip++;
+ err = PTR_ERR(cseg);
+ complete(&priv_rx->add_ctx);
+ goto unlock;
+}
+
+static void
+mlx5e_set_ktls_rx_priv_ctx(struct tls_context *tls_ctx,
+ struct mlx5e_ktls_offload_context_rx *priv_rx)
+{
+ struct mlx5e_ktls_offload_context_rx **ctx =
+ __tls_driver_ctx(tls_ctx, TLS_OFFLOAD_CTX_DIR_RX);
+
+ BUILD_BUG_ON(sizeof(struct mlx5e_ktls_offload_context_rx *) >
+ TLS_OFFLOAD_CONTEXT_SIZE_RX);
+
+ *ctx = priv_rx;
+}
+
+static struct mlx5e_ktls_offload_context_rx *
+mlx5e_get_ktls_rx_priv_ctx(struct tls_context *tls_ctx)
+{
+ struct mlx5e_ktls_offload_context_rx **ctx =
+ __tls_driver_ctx(tls_ctx, TLS_OFFLOAD_CTX_DIR_RX);
+
+ return *ctx;
+}
+
+/* Re-sync */
+/* Runs in work context */
+static struct mlx5_wqe_ctrl_seg *
+resync_post_get_progress_params(struct mlx5e_icosq *sq,
+ struct mlx5e_ktls_offload_context_rx *priv_rx)
+{
+ struct mlx5e_get_tls_progress_params_wqe *wqe;
+ struct mlx5e_ktls_rx_resync_buf *buf;
+ struct mlx5e_icosq_wqe_info wi;
+ struct mlx5_wqe_ctrl_seg *cseg;
+ struct mlx5_seg_get_psv *psv;
+ struct device *pdev;
+ int err;
+ u16 pi;
+
+ buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+ if (unlikely(!buf)) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ pdev = sq->channel->priv->mdev->device;
+ buf->dma_addr = dma_map_single(pdev, &buf->progress,
+ PROGRESS_PARAMS_PADDED_SIZE, DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(pdev, buf->dma_addr))) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ buf->priv_rx = priv_rx;
+
+ BUILD_BUG_ON(MLX5E_KTLS_GET_PROGRESS_WQEBBS != 1);
+ if (unlikely(!mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, 1))) {
+ err = -ENOSPC;
+ goto err_out;
+ }
+
+ pi = mlx5e_icosq_get_next_pi(sq, 1);
+ wqe = MLX5E_TLS_FETCH_GET_PROGRESS_PARAMS_WQE(sq, pi);
+
+#define GET_PSV_DS_CNT (DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS))
+
+ cseg = &wqe->ctrl;
+ cseg->opmod_idx_opcode =
+ cpu_to_be32((sq->pc << 8) | MLX5_OPCODE_GET_PSV |
+ (MLX5_OPC_MOD_TLS_TIR_PROGRESS_PARAMS << 24));
+ cseg->qpn_ds =
+ cpu_to_be32((sq->sqn << MLX5_WQE_CTRL_QPN_SHIFT) | GET_PSV_DS_CNT);
+
+ psv = &wqe->psv;
+ psv->num_psv = 1 << 4;
+ psv->l_key = sq->channel->mkey_be;
+ psv->psv_index[0] = cpu_to_be32(priv_rx->tirn);
+ psv->va = cpu_to_be64(buf->dma_addr);
+
+ wi = (struct mlx5e_icosq_wqe_info) {
+ .wqe_type = MLX5E_ICOSQ_WQE_GET_PSV_TLS,
+ .num_wqebbs = 1,
+ .tls_get_params.buf = buf,
+ };
+ icosq_fill_wi(sq, pi, &wi);
+ sq->pc++;
+
+ return cseg;
+
+err_out:
+ priv_rx->stats->tls_resync_req_skip++;
+ return ERR_PTR(err);
+}
+
+/* Function is called with elevated refcount.
+ * It decreases it only if no WQE is posted.
+ */
+static void resync_handle_work(struct work_struct *work)
+{
+ struct mlx5e_ktls_offload_context_rx *priv_rx;
+ struct mlx5e_ktls_rx_resync_ctx *resync;
+ struct mlx5_wqe_ctrl_seg *cseg;
+ struct mlx5e_channel *c;
+ struct mlx5e_icosq *sq;
+ struct mlx5_wq_cyc *wq;
+
+ resync = container_of(work, struct mlx5e_ktls_rx_resync_ctx, work);
+ priv_rx = container_of(resync, struct mlx5e_ktls_offload_context_rx, resync);
+
+ if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags))) {
+ refcount_dec(&resync->refcnt);
+ return;
+ }
+
+ c = resync->priv->channels.c[priv_rx->rxq];
+ sq = &c->async_icosq;
+ wq = &sq->wq;
+
+ spin_lock(&c->async_icosq_lock);
+
+ cseg = resync_post_get_progress_params(sq, priv_rx);
+ if (IS_ERR(cseg)) {
+ refcount_dec(&resync->refcnt);
+ goto unlock;
+ }
+ mlx5e_notify_hw(wq, sq->pc, sq->uar_map, cseg);
+unlock:
+ spin_unlock(&c->async_icosq_lock);
+}
+
+static void resync_init(struct mlx5e_ktls_rx_resync_ctx *resync,
+ struct mlx5e_priv *priv)
+{
+ INIT_WORK(&resync->work, resync_handle_work);
+ resync->priv = priv;
+ refcount_set(&resync->refcnt, 1);
+}
+
+/* Function can be called with the refcount being either elevated or not.
+ * It does not affect the refcount.
+ */
+static int resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_rx,
+ struct mlx5e_channel *c)
+{
+ struct tls12_crypto_info_aes_gcm_128 *info = &priv_rx->crypto_info;
+ struct mlx5_wqe_ctrl_seg *cseg;
+ struct mlx5e_icosq *sq;
+ int err;
+
+ memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq));
+ err = 0;
+
+ sq = &c->async_icosq;
+ spin_lock(&c->async_icosq_lock);
+
+ cseg = post_static_params(sq, priv_rx);
+ if (IS_ERR(cseg)) {
+ priv_rx->stats->tls_resync_res_skip++;
+ err = PTR_ERR(cseg);
+ goto unlock;
+ }
+ /* Do not increment priv_rx refcnt, CQE handling is empty */
+ mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, cseg);
+ priv_rx->stats->tls_resync_res_ok++;
+unlock:
+ spin_unlock(&c->async_icosq_lock);
+
+ return err;
+}
+
+/* Function is called with elevated refcount, it decreases it. */
+void mlx5e_ktls_handle_get_psv_completion(struct mlx5e_icosq_wqe_info *wi,
+ struct mlx5e_icosq *sq)
+{
+ struct mlx5e_ktls_rx_resync_buf *buf = wi->tls_get_params.buf;
+ struct mlx5e_ktls_offload_context_rx *priv_rx;
+ struct mlx5e_ktls_rx_resync_ctx *resync;
+ u8 tracker_state, auth_state, *ctx;
+ u32 hw_seq;
+
+ priv_rx = buf->priv_rx;
+ resync = &priv_rx->resync;
+
+ if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags)))
+ goto out;
+
+ dma_sync_single_for_cpu(resync->priv->mdev->device, buf->dma_addr,
+ PROGRESS_PARAMS_PADDED_SIZE, DMA_FROM_DEVICE);
+
+ ctx = buf->progress.ctx;
+ tracker_state = MLX5_GET(tls_progress_params, ctx, record_tracker_state);
+ auth_state = MLX5_GET(tls_progress_params, ctx, auth_state);
+ if (tracker_state != MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING ||
+ auth_state != MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD) {
+ priv_rx->stats->tls_resync_req_skip++;
+ goto out;
+ }
+
+ hw_seq = MLX5_GET(tls_progress_params, ctx, hw_resync_tcp_sn);
+ tls_offload_rx_resync_async_request_end(priv_rx->sk, cpu_to_be32(hw_seq));
+ priv_rx->stats->tls_resync_req_end++;
+out:
+ refcount_dec(&resync->refcnt);
+ kfree(buf);
+}
+
+/* Runs in NAPI.
+ * Function elevates the refcount, unless no work is queued.
+ */
+static bool resync_queue_get_psv(struct sock *sk)
+{
+ struct mlx5e_ktls_offload_context_rx *priv_rx;
+ struct mlx5e_ktls_rx_resync_ctx *resync;
+
+ priv_rx = mlx5e_get_ktls_rx_priv_ctx(tls_get_ctx(sk));
+ if (unlikely(!priv_rx))
+ return false;
+
+ if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags)))
+ return false;
+
+ resync = &priv_rx->resync;
+ refcount_inc(&resync->refcnt);
+ if (unlikely(!queue_work(resync->priv->tls->rx_wq, &resync->work)))
+ refcount_dec(&resync->refcnt);
+
+ return true;
+}
+
+/* Runs in NAPI */
+static void resync_update_sn(struct mlx5e_rq *rq, struct sk_buff *skb)
+{
+ struct ethhdr *eth = (struct ethhdr *)(skb->data);
+ struct net_device *netdev = rq->netdev;
+ struct sock *sk = NULL;
+ unsigned int datalen;
+ struct iphdr *iph;
+ struct tcphdr *th;
+ __be32 seq;
+ int depth = 0;
+
+ __vlan_get_protocol(skb, eth->h_proto, &depth);
+ iph = (struct iphdr *)(skb->data + depth);
+
+ if (iph->version == 4) {
+ depth += sizeof(struct iphdr);
+ th = (void *)iph + sizeof(struct iphdr);
+
+ sk = inet_lookup_established(dev_net(netdev), &tcp_hashinfo,
+ iph->saddr, th->source, iph->daddr,
+ th->dest, netdev->ifindex);
+#if IS_ENABLED(CONFIG_IPV6)
+ } else {
+ struct ipv6hdr *ipv6h = (struct ipv6hdr *)iph;
+
+ depth += sizeof(struct ipv6hdr);
+ th = (void *)ipv6h + sizeof(struct ipv6hdr);
+
+ sk = __inet6_lookup_established(dev_net(netdev), &tcp_hashinfo,
+ &ipv6h->saddr, th->source,
+ &ipv6h->daddr, ntohs(th->dest),
+ netdev->ifindex, 0);
+#endif
+ }
+
+ depth += sizeof(struct tcphdr);
+
+ if (unlikely(!sk || sk->sk_state == TCP_TIME_WAIT))
+ return;
+
+ if (unlikely(!resync_queue_get_psv(sk)))
+ return;
+
+ skb->sk = sk;
+ skb->destructor = sock_edemux;
+
+ seq = th->seq;
+ datalen = skb->len - depth;
+ tls_offload_rx_resync_async_request_start(sk, seq, datalen);
+ rq->stats->tls_resync_req_start++;
+}
+
+void mlx5e_ktls_rx_resync(struct net_device *netdev, struct sock *sk,
+ u32 seq, u8 *rcd_sn)
+{
+ struct mlx5e_ktls_offload_context_rx *priv_rx;
+ struct mlx5e_ktls_rx_resync_ctx *resync;
+ struct mlx5e_priv *priv;
+ struct mlx5e_channel *c;
+
+ priv_rx = mlx5e_get_ktls_rx_priv_ctx(tls_get_ctx(sk));
+ if (unlikely(!priv_rx))
+ return;
+
+ resync = &priv_rx->resync;
+ resync->sw_rcd_sn_be = *(__be64 *)rcd_sn;
+ resync->seq = seq;
+
+ priv = netdev_priv(netdev);
+ c = priv->channels.c[priv_rx->rxq];
+
+ resync_handle_seq_match(priv_rx, c);
+}
+
+/* End of resync section */
+
+void mlx5e_ktls_handle_rx_skb(struct mlx5e_rq *rq, struct sk_buff *skb,
+ struct mlx5_cqe64 *cqe, u32 *cqe_bcnt)
+{
+ struct mlx5e_rq_stats *stats = rq->stats;
+
+ switch (get_cqe_tls_offload(cqe)) {
+ case CQE_TLS_OFFLOAD_DECRYPTED:
+ skb->decrypted = 1;
+ stats->tls_decrypted_packets++;
+ stats->tls_decrypted_bytes += *cqe_bcnt;
+ break;
+ case CQE_TLS_OFFLOAD_RESYNC:
+ stats->tls_resync_req_pkt++;
+ resync_update_sn(rq, skb);
+ break;
+ default: /* CQE_TLS_OFFLOAD_ERROR: */
+ stats->tls_err++;
+ break;
+ }
+}
+
+void mlx5e_ktls_handle_ctx_completion(struct mlx5e_icosq_wqe_info *wi)
+{
+ struct mlx5e_ktls_offload_context_rx *priv_rx = wi->tls_set_params.priv_rx;
+ struct accel_rule *rule = &priv_rx->rule;
+
+ if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags))) {
+ complete(&priv_rx->add_ctx);
+ return;
+ }
+ queue_work(rule->priv->tls->rx_wq, &rule->work);
+}
+
+static int mlx5e_ktls_sk_get_rxq(struct sock *sk)
+{
+ int rxq = sk_rx_queue_get(sk);
+
+ if (unlikely(rxq == -1))
+ rxq = 0;
+
+ return rxq;
+}
+
+int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk,
+ struct tls_crypto_info *crypto_info,
+ u32 start_offload_tcp_sn)
+{
+ struct mlx5e_ktls_offload_context_rx *priv_rx;
+ struct mlx5e_ktls_rx_resync_ctx *resync;
+ struct tls_context *tls_ctx;
+ struct mlx5_core_dev *mdev;
+ struct mlx5e_priv *priv;
+ int rxq, err;
+ u32 rqtn;
+
+ tls_ctx = tls_get_ctx(sk);
+ priv = netdev_priv(netdev);
+ mdev = priv->mdev;
+ priv_rx = kzalloc(sizeof(*priv_rx), GFP_KERNEL);
+ if (unlikely(!priv_rx))
+ return -ENOMEM;
+
+ err = mlx5_ktls_create_key(mdev, crypto_info, &priv_rx->key_id);
+ if (err)
+ goto err_create_key;
+
+ priv_rx->crypto_info =
+ *(struct tls12_crypto_info_aes_gcm_128 *)crypto_info;
+
+ rxq = mlx5e_ktls_sk_get_rxq(sk);
+ priv_rx->rxq = rxq;
+ priv_rx->sk = sk;
+
+ priv_rx->stats = &priv->channel_stats[rxq].rq;
+ mlx5e_set_ktls_rx_priv_ctx(tls_ctx, priv_rx);
+
+ rqtn = priv->direct_tir[rxq].rqt.rqtn;
+
+ err = mlx5e_ktls_create_tir(mdev, &priv_rx->tirn, rqtn);
+ if (err)
+ goto err_create_tir;
+
+ init_completion(&priv_rx->add_ctx);
+
+ accel_rule_init(&priv_rx->rule, priv, sk);
+ resync = &priv_rx->resync;
+ resync_init(resync, priv);
+ tls_offload_ctx_rx(tls_ctx)->resync_async = &resync->core;
+ tls_offload_rx_resync_set_type(sk, TLS_OFFLOAD_SYNC_TYPE_DRIVER_REQ_ASYNC);
+
+ err = post_rx_param_wqes(priv->channels.c[rxq], priv_rx, start_offload_tcp_sn);
+ if (err)
+ goto err_post_wqes;
+
+ priv_rx->stats->tls_ctx++;
+
+ return 0;
+
+err_post_wqes:
+ mlx5_core_destroy_tir(mdev, priv_rx->tirn);
+err_create_tir:
+ mlx5_ktls_destroy_key(mdev, priv_rx->key_id);
+err_create_key:
+ kfree(priv_rx);
+ return err;
+}
+
+/* Elevated refcount on the resync object means there are
+ * outstanding operations (uncompleted GET_PSV WQEs) that
+ * will read the resync / priv_rx objects once completed.
+ * Wait for them to avoid use-after-free.
+ */
+static void wait_for_resync(struct net_device *netdev,
+ struct mlx5e_ktls_rx_resync_ctx *resync)
+{
+#define MLX5E_KTLS_RX_RESYNC_TIMEOUT 20000 /* msecs */
+ unsigned long exp_time = jiffies + msecs_to_jiffies(MLX5E_KTLS_RX_RESYNC_TIMEOUT);
+ unsigned int refcnt;
+
+ do {
+ refcnt = refcount_read(&resync->refcnt);
+ if (refcnt == 1)
+ return;
+
+ msleep(20);
+ } while (time_before(jiffies, exp_time));
+
+ netdev_warn(netdev,
+ "Failed waiting for kTLS RX resync refcnt to be released (%u).\n",
+ refcnt);
+}
+
+void mlx5e_ktls_del_rx(struct net_device *netdev, struct tls_context *tls_ctx)
+{
+ struct mlx5e_ktls_offload_context_rx *priv_rx;
+ struct mlx5e_ktls_rx_resync_ctx *resync;
+ struct mlx5_core_dev *mdev;
+ struct mlx5e_priv *priv;
+
+ priv = netdev_priv(netdev);
+ mdev = priv->mdev;
+
+ priv_rx = mlx5e_get_ktls_rx_priv_ctx(tls_ctx);
+ set_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags);
+ mlx5e_set_ktls_rx_priv_ctx(tls_ctx, NULL);
+ napi_synchronize(&priv->channels.c[priv_rx->rxq]->napi);
+ if (!cancel_work_sync(&priv_rx->rule.work))
+ /* completion is needed, as the priv_rx in the add flow
+ * is maintained on the wqe info (wi), not on the socket.
+ */
+ wait_for_completion(&priv_rx->add_ctx);
+ resync = &priv_rx->resync;
+ if (cancel_work_sync(&resync->work))
+ refcount_dec(&resync->refcnt);
+ wait_for_resync(netdev, resync);
+
+ priv_rx->stats->tls_del++;
+ if (priv_rx->rule.rule)
+ mlx5e_accel_fs_del_sk(priv_rx->rule.rule);
+
+ mlx5_core_destroy_tir(mdev, priv_rx->tirn);
+ mlx5_ktls_destroy_key(mdev, priv_rx->key_id);
+ kfree(priv_rx);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
index 3cd78d9503c1..f4861545b236 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
@@ -1,105 +1,139 @@
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
// Copyright (c) 2019 Mellanox Technologies.
-#include <linux/tls.h>
-#include "en.h"
-#include "en/txrx.h"
-#include "en_accel/ktls.h"
+#include "en_accel/ktls_txrx.h"
+#include "en_accel/ktls_utils.h"
-enum {
- MLX5E_STATIC_PARAMS_CONTEXT_TLS_1_2 = 0x2,
+struct mlx5e_dump_wqe {
+ struct mlx5_wqe_ctrl_seg ctrl;
+ struct mlx5_wqe_data_seg data;
};
-enum {
- MLX5E_ENCRYPTION_STANDARD_TLS = 0x1,
-};
+#define MLX5E_KTLS_DUMP_WQEBBS \
+ (DIV_ROUND_UP(sizeof(struct mlx5e_dump_wqe), MLX5_SEND_WQE_BB))
-#define EXTRACT_INFO_FIELDS do { \
- salt = info->salt; \
- rec_seq = info->rec_seq; \
- salt_sz = sizeof(info->salt); \
- rec_seq_sz = sizeof(info->rec_seq); \
-} while (0)
+static u8
+mlx5e_ktls_dumps_num_wqes(struct mlx5e_txqsq *sq, unsigned int nfrags,
+ unsigned int sync_len)
+{
+ /* Given the MTU and sync_len, calculates an upper bound for the
+ * number of DUMP WQEs needed for the TX resync of a record.
+ */
+ return nfrags + DIV_ROUND_UP(sync_len, sq->hw_mtu);
+}
-static void
-fill_static_params_ctx(void *ctx, struct mlx5e_ktls_offload_context_tx *priv_tx)
+u16 mlx5e_ktls_get_stop_room(struct mlx5e_txqsq *sq)
{
- struct tls12_crypto_info_aes_gcm_128 *info = &priv_tx->crypto_info;
- char *initial_rn, *gcm_iv;
- u16 salt_sz, rec_seq_sz;
- char *salt, *rec_seq;
- u8 tls_version;
+ u16 num_dumps, stop_room = 0;
+
+ num_dumps = mlx5e_ktls_dumps_num_wqes(sq, MAX_SKB_FRAGS, TLS_MAX_PAYLOAD_SIZE);
- EXTRACT_INFO_FIELDS;
+ stop_room += mlx5e_stop_room_for_wqe(MLX5E_TLS_SET_STATIC_PARAMS_WQEBBS);
+ stop_room += mlx5e_stop_room_for_wqe(MLX5E_TLS_SET_PROGRESS_PARAMS_WQEBBS);
+ stop_room += num_dumps * mlx5e_stop_room_for_wqe(MLX5E_KTLS_DUMP_WQEBBS);
- gcm_iv = MLX5_ADDR_OF(tls_static_params, ctx, gcm_iv);
- initial_rn = MLX5_ADDR_OF(tls_static_params, ctx, initial_record_number);
+ return stop_room;
+}
+
+static int mlx5e_ktls_create_tis(struct mlx5_core_dev *mdev, u32 *tisn)
+{
+ u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};
+ void *tisc;
- memcpy(gcm_iv, salt, salt_sz);
- memcpy(initial_rn, rec_seq, rec_seq_sz);
+ tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
- tls_version = MLX5E_STATIC_PARAMS_CONTEXT_TLS_1_2;
+ MLX5_SET(tisc, tisc, tls_en, 1);
- MLX5_SET(tls_static_params, ctx, tls_version, tls_version);
- MLX5_SET(tls_static_params, ctx, const_1, 1);
- MLX5_SET(tls_static_params, ctx, const_2, 2);
- MLX5_SET(tls_static_params, ctx, encryption_standard,
- MLX5E_ENCRYPTION_STANDARD_TLS);
- MLX5_SET(tls_static_params, ctx, dek_index, priv_tx->key_id);
+ return mlx5e_create_tis(mdev, in, tisn);
}
+struct mlx5e_ktls_offload_context_tx {
+ struct tls_offload_context_tx *tx_ctx;
+ struct tls12_crypto_info_aes_gcm_128 crypto_info;
+ u32 expected_seq;
+ u32 tisn;
+ u32 key_id;
+ bool ctx_post_pending;
+};
+
static void
-build_static_params(struct mlx5e_umr_wqe *wqe, u16 pc, u32 sqn,
- struct mlx5e_ktls_offload_context_tx *priv_tx,
- bool fence)
+mlx5e_set_ktls_tx_priv_ctx(struct tls_context *tls_ctx,
+ struct mlx5e_ktls_offload_context_tx *priv_tx)
{
- struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
- struct mlx5_wqe_umr_ctrl_seg *ucseg = &wqe->uctrl;
+ struct mlx5e_ktls_offload_context_tx **ctx =
+ __tls_driver_ctx(tls_ctx, TLS_OFFLOAD_CTX_DIR_TX);
-#define STATIC_PARAMS_DS_CNT \
- DIV_ROUND_UP(MLX5E_KTLS_STATIC_UMR_WQE_SZ, MLX5_SEND_WQE_DS)
+ BUILD_BUG_ON(sizeof(struct mlx5e_ktls_offload_context_tx *) >
+ TLS_OFFLOAD_CONTEXT_SIZE_TX);
- cseg->opmod_idx_opcode = cpu_to_be32((pc << 8) | MLX5_OPCODE_UMR |
- (MLX5_OPC_MOD_TLS_TIS_STATIC_PARAMS << 24));
- cseg->qpn_ds = cpu_to_be32((sqn << MLX5_WQE_CTRL_QPN_SHIFT) |
- STATIC_PARAMS_DS_CNT);
- cseg->fm_ce_se = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
- cseg->tisn = cpu_to_be32(priv_tx->tisn << 8);
+ *ctx = priv_tx;
+}
- ucseg->flags = MLX5_UMR_INLINE;
- ucseg->bsf_octowords = cpu_to_be16(MLX5_ST_SZ_BYTES(tls_static_params) / 16);
+static struct mlx5e_ktls_offload_context_tx *
+mlx5e_get_ktls_tx_priv_ctx(struct tls_context *tls_ctx)
+{
+ struct mlx5e_ktls_offload_context_tx **ctx =
+ __tls_driver_ctx(tls_ctx, TLS_OFFLOAD_CTX_DIR_TX);
- fill_static_params_ctx(wqe->tls_static_params_ctx, priv_tx);
+ return *ctx;
}
-static void
-fill_progress_params_ctx(void *ctx, struct mlx5e_ktls_offload_context_tx *priv_tx)
+int mlx5e_ktls_add_tx(struct net_device *netdev, struct sock *sk,
+ struct tls_crypto_info *crypto_info, u32 start_offload_tcp_sn)
{
- MLX5_SET(tls_progress_params, ctx, tisn, priv_tx->tisn);
- MLX5_SET(tls_progress_params, ctx, record_tracker_state,
- MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START);
- MLX5_SET(tls_progress_params, ctx, auth_state,
- MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD);
+ struct mlx5e_ktls_offload_context_tx *priv_tx;
+ struct tls_context *tls_ctx;
+ struct mlx5_core_dev *mdev;
+ struct mlx5e_priv *priv;
+ int err;
+
+ tls_ctx = tls_get_ctx(sk);
+ priv = netdev_priv(netdev);
+ mdev = priv->mdev;
+
+ priv_tx = kzalloc(sizeof(*priv_tx), GFP_KERNEL);
+ if (!priv_tx)
+ return -ENOMEM;
+
+ err = mlx5_ktls_create_key(mdev, crypto_info, &priv_tx->key_id);
+ if (err)
+ goto err_create_key;
+
+ priv_tx->expected_seq = start_offload_tcp_sn;
+ priv_tx->crypto_info =
+ *(struct tls12_crypto_info_aes_gcm_128 *)crypto_info;
+ priv_tx->tx_ctx = tls_offload_ctx_tx(tls_ctx);
+
+ mlx5e_set_ktls_tx_priv_ctx(tls_ctx, priv_tx);
+
+ err = mlx5e_ktls_create_tis(mdev, &priv_tx->tisn);
+ if (err)
+ goto err_create_tis;
+
+ priv_tx->ctx_post_pending = true;
+
+ return 0;
+
+err_create_tis:
+ mlx5_ktls_destroy_key(mdev, priv_tx->key_id);
+err_create_key:
+ kfree(priv_tx);
+ return err;
}
-static void
-build_progress_params(struct mlx5e_tx_wqe *wqe, u16 pc, u32 sqn,
- struct mlx5e_ktls_offload_context_tx *priv_tx,
- bool fence)
+void mlx5e_ktls_del_tx(struct net_device *netdev, struct tls_context *tls_ctx)
{
- struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
-
-#define PROGRESS_PARAMS_DS_CNT \
- DIV_ROUND_UP(MLX5E_KTLS_PROGRESS_WQE_SZ, MLX5_SEND_WQE_DS)
+ struct mlx5e_ktls_offload_context_tx *priv_tx;
+ struct mlx5_core_dev *mdev;
+ struct mlx5e_priv *priv;
- cseg->opmod_idx_opcode =
- cpu_to_be32((pc << 8) | MLX5_OPCODE_SET_PSV |
- (MLX5_OPC_MOD_TLS_TIS_PROGRESS_PARAMS << 24));
- cseg->qpn_ds = cpu_to_be32((sqn << MLX5_WQE_CTRL_QPN_SHIFT) |
- PROGRESS_PARAMS_DS_CNT);
- cseg->fm_ce_se = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
+ priv_tx = mlx5e_get_ktls_tx_priv_ctx(tls_ctx);
+ priv = netdev_priv(netdev);
+ mdev = priv->mdev;
- fill_progress_params_ctx(wqe->tls_progress_params_ctx, priv_tx);
+ mlx5e_destroy_tis(mdev, priv_tx->tisn);
+ mlx5_ktls_destroy_key(mdev, priv_tx->key_id);
+ kfree(priv_tx);
}
static void tx_fill_wi(struct mlx5e_txqsq *sq,
@@ -115,11 +149,6 @@ static void tx_fill_wi(struct mlx5e_txqsq *sq,
};
}
-void mlx5e_ktls_tx_offload_set_pending(struct mlx5e_ktls_offload_context_tx *priv_tx)
-{
- priv_tx->ctx_post_pending = true;
-}
-
static bool
mlx5e_ktls_tx_offload_test_and_clear_pending(struct mlx5e_ktls_offload_context_tx *priv_tx)
{
@@ -135,12 +164,15 @@ post_static_params(struct mlx5e_txqsq *sq,
struct mlx5e_ktls_offload_context_tx *priv_tx,
bool fence)
{
- u16 pi, num_wqebbs = MLX5E_KTLS_STATIC_WQEBBS;
- struct mlx5e_umr_wqe *umr_wqe;
+ struct mlx5e_set_tls_static_params_wqe *wqe;
+ u16 pi, num_wqebbs;
+ num_wqebbs = MLX5E_TLS_SET_STATIC_PARAMS_WQEBBS;
pi = mlx5e_txqsq_get_next_pi(sq, num_wqebbs);
- umr_wqe = MLX5E_TLS_FETCH_UMR_WQE(sq, pi);
- build_static_params(umr_wqe, sq->pc, sq->sqn, priv_tx, fence);
+ wqe = MLX5E_TLS_FETCH_SET_STATIC_PARAMS_WQE(sq, pi);
+ mlx5e_ktls_build_static_params(wqe, sq->pc, sq->sqn, &priv_tx->crypto_info,
+ priv_tx->tisn, priv_tx->key_id, 0, fence,
+ TLS_OFFLOAD_CTX_DIR_TX);
tx_fill_wi(sq, pi, num_wqebbs, 0, NULL);
sq->pc += num_wqebbs;
}
@@ -150,12 +182,14 @@ post_progress_params(struct mlx5e_txqsq *sq,
struct mlx5e_ktls_offload_context_tx *priv_tx,
bool fence)
{
- u16 pi, num_wqebbs = MLX5E_KTLS_PROGRESS_WQEBBS;
- struct mlx5e_tx_wqe *wqe;
+ struct mlx5e_set_tls_progress_params_wqe *wqe;
+ u16 pi, num_wqebbs;
+ num_wqebbs = MLX5E_TLS_SET_PROGRESS_PARAMS_WQEBBS;
pi = mlx5e_txqsq_get_next_pi(sq, num_wqebbs);
- wqe = MLX5E_TLS_FETCH_PROGRESS_WQE(sq, pi);
- build_progress_params(wqe, sq->pc, sq->sqn, priv_tx, fence);
+ wqe = MLX5E_TLS_FETCH_SET_PROGRESS_PARAMS_WQE(sq, pi);
+ mlx5e_ktls_build_progress_params(wqe, sq->pc, sq->sqn, priv_tx->tisn, fence, 0,
+ TLS_OFFLOAD_CTX_DIR_TX);
tx_fill_wi(sq, pi, num_wqebbs, 0, NULL);
sq->pc += num_wqebbs;
}
@@ -284,7 +318,7 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, skb_frag_t *frag, u32 tisn, bool fir
cseg->opmod_idx_opcode = cpu_to_be32((sq->pc << 8) | MLX5_OPCODE_DUMP);
cseg->qpn_ds = cpu_to_be32((sq->sqn << 8) | ds_cnt);
- cseg->tisn = cpu_to_be32(tisn << 8);
+ cseg->tis_tir_num = cpu_to_be32(tisn << 8);
cseg->fm_ce_se = first ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
fsz = skb_frag_size(frag);
@@ -436,7 +470,7 @@ bool mlx5e_ktls_handle_tx_skb(struct tls_context *tls_ctx, struct mlx5e_txqsq *s
if (likely(!skb->decrypted))
goto out;
WARN_ON_ONCE(1);
- /* fall-through */
+ fallthrough;
case MLX5E_KTLS_SYNC_FAIL:
goto err_out;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.c
new file mode 100644
index 000000000000..ac29aeb8af49
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
+
+#include "en_accel/ktls_txrx.h"
+#include "en_accel/ktls_utils.h"
+
+enum {
+ MLX5E_STATIC_PARAMS_CONTEXT_TLS_1_2 = 0x2,
+};
+
+enum {
+ MLX5E_ENCRYPTION_STANDARD_TLS = 0x1,
+};
+
+#define EXTRACT_INFO_FIELDS do { \
+ salt = info->salt; \
+ rec_seq = info->rec_seq; \
+ salt_sz = sizeof(info->salt); \
+ rec_seq_sz = sizeof(info->rec_seq); \
+} while (0)
+
+static void
+fill_static_params(struct mlx5_wqe_tls_static_params_seg *params,
+ struct tls12_crypto_info_aes_gcm_128 *info,
+ u32 key_id, u32 resync_tcp_sn)
+{
+ char *initial_rn, *gcm_iv;
+ u16 salt_sz, rec_seq_sz;
+ char *salt, *rec_seq;
+ u8 tls_version;
+ u8 *ctx;
+
+ ctx = params->ctx;
+
+ EXTRACT_INFO_FIELDS;
+
+ gcm_iv = MLX5_ADDR_OF(tls_static_params, ctx, gcm_iv);
+ initial_rn = MLX5_ADDR_OF(tls_static_params, ctx, initial_record_number);
+
+ memcpy(gcm_iv, salt, salt_sz);
+ memcpy(initial_rn, rec_seq, rec_seq_sz);
+
+ tls_version = MLX5E_STATIC_PARAMS_CONTEXT_TLS_1_2;
+
+ MLX5_SET(tls_static_params, ctx, tls_version, tls_version);
+ MLX5_SET(tls_static_params, ctx, const_1, 1);
+ MLX5_SET(tls_static_params, ctx, const_2, 2);
+ MLX5_SET(tls_static_params, ctx, encryption_standard,
+ MLX5E_ENCRYPTION_STANDARD_TLS);
+ MLX5_SET(tls_static_params, ctx, resync_tcp_sn, resync_tcp_sn);
+ MLX5_SET(tls_static_params, ctx, dek_index, key_id);
+}
+
+void
+mlx5e_ktls_build_static_params(struct mlx5e_set_tls_static_params_wqe *wqe,
+ u16 pc, u32 sqn,
+ struct tls12_crypto_info_aes_gcm_128 *info,
+ u32 tis_tir_num, u32 key_id, u32 resync_tcp_sn,
+ bool fence, enum tls_offload_ctx_dir direction)
+{
+ struct mlx5_wqe_umr_ctrl_seg *ucseg = &wqe->uctrl;
+ struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
+ u8 opmod = direction == TLS_OFFLOAD_CTX_DIR_TX ?
+ MLX5_OPC_MOD_TLS_TIS_STATIC_PARAMS :
+ MLX5_OPC_MOD_TLS_TIR_STATIC_PARAMS;
+
+#define STATIC_PARAMS_DS_CNT DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS)
+
+ cseg->opmod_idx_opcode = cpu_to_be32((pc << 8) | MLX5_OPCODE_UMR | (opmod << 24));
+ cseg->qpn_ds = cpu_to_be32((sqn << MLX5_WQE_CTRL_QPN_SHIFT) |
+ STATIC_PARAMS_DS_CNT);
+ cseg->fm_ce_se = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
+ cseg->tis_tir_num = cpu_to_be32(tis_tir_num << 8);
+
+ ucseg->flags = MLX5_UMR_INLINE;
+ ucseg->bsf_octowords = cpu_to_be16(MLX5_ST_SZ_BYTES(tls_static_params) / 16);
+
+ fill_static_params(&wqe->params, info, key_id, resync_tcp_sn);
+}
+
+static void
+fill_progress_params(struct mlx5_wqe_tls_progress_params_seg *params, u32 tis_tir_num,
+ u32 next_record_tcp_sn)
+{
+ u8 *ctx = params->ctx;
+
+ params->tis_tir_num = cpu_to_be32(tis_tir_num);
+
+ MLX5_SET(tls_progress_params, ctx, next_record_tcp_sn,
+ next_record_tcp_sn);
+ MLX5_SET(tls_progress_params, ctx, record_tracker_state,
+ MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START);
+ MLX5_SET(tls_progress_params, ctx, auth_state,
+ MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD);
+}
+
+void
+mlx5e_ktls_build_progress_params(struct mlx5e_set_tls_progress_params_wqe *wqe,
+ u16 pc, u32 sqn,
+ u32 tis_tir_num, bool fence,
+ u32 next_record_tcp_sn,
+ enum tls_offload_ctx_dir direction)
+{
+ struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
+ u8 opmod = direction == TLS_OFFLOAD_CTX_DIR_TX ?
+ MLX5_OPC_MOD_TLS_TIS_PROGRESS_PARAMS :
+ MLX5_OPC_MOD_TLS_TIR_PROGRESS_PARAMS;
+
+#define PROGRESS_PARAMS_DS_CNT DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS)
+
+ cseg->opmod_idx_opcode =
+ cpu_to_be32((pc << 8) | MLX5_OPCODE_SET_PSV | (opmod << 24));
+ cseg->qpn_ds = cpu_to_be32((sqn << MLX5_WQE_CTRL_QPN_SHIFT) |
+ PROGRESS_PARAMS_DS_CNT);
+ cseg->fm_ce_se = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
+
+ fill_progress_params(&wqe->params, tis_tir_num, next_record_tcp_sn);
+}
+
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.h
new file mode 100644
index 000000000000..ff4c740af10b
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
+
+#ifndef __MLX5E_KTLS_TXRX_H__
+#define __MLX5E_KTLS_TXRX_H__
+
+#ifdef CONFIG_MLX5_EN_TLS
+
+#include <net/tls.h>
+#include "en.h"
+#include "en/txrx.h"
+
+struct mlx5e_accel_tx_tls_state {
+ u32 tls_tisn;
+};
+
+u16 mlx5e_ktls_get_stop_room(struct mlx5e_txqsq *sq);
+
+bool mlx5e_ktls_handle_tx_skb(struct tls_context *tls_ctx, struct mlx5e_txqsq *sq,
+ struct sk_buff *skb, int datalen,
+ struct mlx5e_accel_tx_tls_state *state);
+void mlx5e_ktls_handle_rx_skb(struct mlx5e_rq *rq, struct sk_buff *skb,
+ struct mlx5_cqe64 *cqe, u32 *cqe_bcnt);
+
+void mlx5e_ktls_handle_ctx_completion(struct mlx5e_icosq_wqe_info *wi);
+void mlx5e_ktls_handle_get_psv_completion(struct mlx5e_icosq_wqe_info *wi,
+ struct mlx5e_icosq *sq);
+
+void mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq,
+ struct mlx5e_tx_wqe_info *wi,
+ u32 *dma_fifo_cc);
+#else
+static inline void
+mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq,
+ struct mlx5e_tx_wqe_info *wi,
+ u32 *dma_fifo_cc)
+{
+}
+
+#endif /* CONFIG_MLX5_EN_TLS */
+
+#endif /* __MLX5E_TLS_TXRX_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_utils.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_utils.h
new file mode 100644
index 000000000000..e5c180f2403b
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_utils.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
+
+#ifndef __MLX5E_KTLS_UTILS_H__
+#define __MLX5E_KTLS_UTILS_H__
+
+#include <net/tls.h>
+#include "en.h"
+#include "accel/tls.h"
+
+enum {
+ MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD = 0,
+ MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_OFFLOAD = 1,
+ MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_AUTHENTICATION = 2,
+};
+
+enum {
+ MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START = 0,
+ MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING = 1,
+ MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_SEARCHING = 2,
+};
+
+int mlx5e_ktls_add_tx(struct net_device *netdev, struct sock *sk,
+ struct tls_crypto_info *crypto_info, u32 start_offload_tcp_sn);
+void mlx5e_ktls_del_tx(struct net_device *netdev, struct tls_context *tls_ctx);
+int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk,
+ struct tls_crypto_info *crypto_info, u32 start_offload_tcp_sn);
+void mlx5e_ktls_del_rx(struct net_device *netdev, struct tls_context *tls_ctx);
+void mlx5e_ktls_rx_resync(struct net_device *netdev, struct sock *sk, u32 seq, u8 *rcd_sn);
+
+struct mlx5e_set_tls_static_params_wqe {
+ struct mlx5_wqe_ctrl_seg ctrl;
+ struct mlx5_wqe_umr_ctrl_seg uctrl;
+ struct mlx5_mkey_seg mkc;
+ struct mlx5_wqe_tls_static_params_seg params;
+};
+
+struct mlx5e_set_tls_progress_params_wqe {
+ struct mlx5_wqe_ctrl_seg ctrl;
+ struct mlx5_wqe_tls_progress_params_seg params;
+};
+
+struct mlx5e_get_tls_progress_params_wqe {
+ struct mlx5_wqe_ctrl_seg ctrl;
+ struct mlx5_seg_get_psv psv;
+};
+
+#define MLX5E_TLS_SET_STATIC_PARAMS_WQEBBS \
+ (DIV_ROUND_UP(sizeof(struct mlx5e_set_tls_static_params_wqe), MLX5_SEND_WQE_BB))
+
+#define MLX5E_TLS_SET_PROGRESS_PARAMS_WQEBBS \
+ (DIV_ROUND_UP(sizeof(struct mlx5e_set_tls_progress_params_wqe), MLX5_SEND_WQE_BB))
+
+#define MLX5E_KTLS_GET_PROGRESS_WQEBBS \
+ (DIV_ROUND_UP(sizeof(struct mlx5e_get_tls_progress_params_wqe), MLX5_SEND_WQE_BB))
+
+#define MLX5E_TLS_FETCH_SET_STATIC_PARAMS_WQE(sq, pi) \
+ ((struct mlx5e_set_tls_static_params_wqe *)\
+ mlx5e_fetch_wqe(&(sq)->wq, pi, sizeof(struct mlx5e_set_tls_static_params_wqe)))
+
+#define MLX5E_TLS_FETCH_SET_PROGRESS_PARAMS_WQE(sq, pi) \
+ ((struct mlx5e_set_tls_progress_params_wqe *)\
+ mlx5e_fetch_wqe(&(sq)->wq, pi, sizeof(struct mlx5e_set_tls_progress_params_wqe)))
+
+#define MLX5E_TLS_FETCH_GET_PROGRESS_PARAMS_WQE(sq, pi) \
+ ((struct mlx5e_get_tls_progress_params_wqe *)\
+ mlx5e_fetch_wqe(&(sq)->wq, pi, sizeof(struct mlx5e_get_tls_progress_params_wqe)))
+
+#define MLX5E_TLS_FETCH_DUMP_WQE(sq, pi) \
+ ((struct mlx5e_dump_wqe *)\
+ mlx5e_fetch_wqe(&(sq)->wq, pi, sizeof(struct mlx5e_dump_wqe)))
+
+void
+mlx5e_ktls_build_static_params(struct mlx5e_set_tls_static_params_wqe *wqe,
+ u16 pc, u32 sqn,
+ struct tls12_crypto_info_aes_gcm_128 *info,
+ u32 tis_tir_num, u32 key_id, u32 resync_tcp_sn,
+ bool fence, enum tls_offload_ctx_dir direction);
+void
+mlx5e_ktls_build_progress_params(struct mlx5e_set_tls_progress_params_wqe *wqe,
+ u16 pc, u32 sqn,
+ u32 tis_tir_num, bool fence,
+ u32 next_record_tcp_sn,
+ enum tls_offload_ctx_dir direction);
+
+#endif /* __MLX5E_TLS_UTILS_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.c
index 1fbb5a90cb38..fee991f5ee7c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.c
@@ -197,6 +197,7 @@ void mlx5e_tls_build_netdev(struct mlx5e_priv *priv)
return;
}
+ /* FPGA */
if (!mlx5_accel_is_tls_device(priv->mdev))
return;
@@ -221,11 +222,21 @@ void mlx5e_tls_build_netdev(struct mlx5e_priv *priv)
int mlx5e_tls_init(struct mlx5e_priv *priv)
{
- struct mlx5e_tls *tls = kzalloc(sizeof(*tls), GFP_KERNEL);
+ struct mlx5e_tls *tls;
+ if (!mlx5_accel_is_tls_device(priv->mdev))
+ return 0;
+
+ tls = kzalloc(sizeof(*tls), GFP_KERNEL);
if (!tls)
return -ENOMEM;
+ tls->rx_wq = create_singlethread_workqueue("mlx5e_tls_rx");
+ if (!tls->rx_wq) {
+ kfree(tls);
+ return -ENOMEM;
+ }
+
priv->tls = tls;
return 0;
}
@@ -237,20 +248,7 @@ void mlx5e_tls_cleanup(struct mlx5e_priv *priv)
if (!tls)
return;
+ destroy_workqueue(tls->rx_wq);
kfree(tls);
priv->tls = NULL;
}
-
-u16 mlx5e_tls_get_stop_room(struct mlx5e_txqsq *sq)
-{
- struct mlx5_core_dev *mdev = sq->channel->mdev;
-
- if (!mlx5_accel_is_tls_device(mdev))
- return 0;
-
- if (MLX5_CAP_GEN(mdev, tls_tx))
- return mlx5e_ktls_get_stop_room(sq);
-
- /* Resync SKB. */
- return mlx5e_stop_room_for_wqe(MLX5_SEND_WQE_MAX_WQEBBS);
-}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.h
index 9219bdb2786e..bd270a85c804 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.h
@@ -53,6 +53,7 @@ struct mlx5e_tls_sw_stats {
struct mlx5e_tls {
struct mlx5e_tls_sw_stats sw_stats;
+ struct workqueue_struct *rx_wq;
};
struct mlx5e_tls_offload_context_tx {
@@ -86,6 +87,11 @@ mlx5e_get_tls_rx_context(struct tls_context *tls_ctx)
base);
}
+static inline bool mlx5e_is_tls_on(struct mlx5e_priv *priv)
+{
+ return priv->tls;
+}
+
void mlx5e_tls_build_netdev(struct mlx5e_priv *priv);
int mlx5e_tls_init(struct mlx5e_priv *priv);
void mlx5e_tls_cleanup(struct mlx5e_priv *priv);
@@ -94,8 +100,6 @@ int mlx5e_tls_get_count(struct mlx5e_priv *priv);
int mlx5e_tls_get_strings(struct mlx5e_priv *priv, uint8_t *data);
int mlx5e_tls_get_stats(struct mlx5e_priv *priv, u64 *data);
-u16 mlx5e_tls_get_stop_room(struct mlx5e_txqsq *sq);
-
#else
static inline void mlx5e_tls_build_netdev(struct mlx5e_priv *priv)
@@ -104,17 +108,13 @@ static inline void mlx5e_tls_build_netdev(struct mlx5e_priv *priv)
mlx5e_ktls_build_netdev(priv);
}
+static inline bool mlx5e_is_tls_on(struct mlx5e_priv *priv) { return false; }
static inline int mlx5e_tls_init(struct mlx5e_priv *priv) { return 0; }
static inline void mlx5e_tls_cleanup(struct mlx5e_priv *priv) { }
static inline int mlx5e_tls_get_count(struct mlx5e_priv *priv) { return 0; }
static inline int mlx5e_tls_get_strings(struct mlx5e_priv *priv, uint8_t *data) { return 0; }
static inline int mlx5e_tls_get_stats(struct mlx5e_priv *priv, u64 *data) { return 0; }
-static inline u16 mlx5e_tls_get_stop_room(struct mlx5e_txqsq *sq)
-{
- return 0;
-}
-
#endif
#endif /* __MLX5E_TLS_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c
index 05454a843b28..b0c31d49ff8d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c
@@ -278,9 +278,10 @@ bool mlx5e_tls_handle_tx_skb(struct net_device *netdev, struct mlx5e_txqsq *sq,
if (WARN_ON_ONCE(tls_ctx->netdev != netdev))
goto err_out;
- if (MLX5_CAP_GEN(sq->channel->mdev, tls_tx))
+ if (mlx5_accel_is_ktls_tx(sq->channel->mdev))
return mlx5e_ktls_handle_tx_skb(tls_ctx, sq, skb, datalen, state);
+ /* FPGA */
skb_seq = ntohl(tcp_hdr(skb)->seq);
context = mlx5e_get_tls_tx_context(tls_ctx);
expected_seq = context->expected_seq;
@@ -305,7 +306,7 @@ err_out:
void mlx5e_tls_handle_tx_wqe(struct mlx5e_txqsq *sq, struct mlx5_wqe_ctrl_seg *cseg,
struct mlx5e_accel_tx_tls_state *state)
{
- cseg->tisn = cpu_to_be32(state->tls_tisn << 8);
+ cseg->tis_tir_num = cpu_to_be32(state->tls_tisn << 8);
}
static int tls_update_resync_sn(struct net_device *netdev,
@@ -354,15 +355,13 @@ out:
return 0;
}
-void mlx5e_tls_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
- u32 *cqe_bcnt)
+/* FPGA tls rx handler */
+void mlx5e_tls_handle_rx_skb_metadata(struct mlx5e_rq *rq, struct sk_buff *skb,
+ u32 *cqe_bcnt)
{
struct mlx5e_tls_metadata *mdata;
struct mlx5e_priv *priv;
- if (!is_metadata_hdr_valid(skb))
- return;
-
/* Use the metadata */
mdata = (struct mlx5e_tls_metadata *)(skb->data + ETH_HLEN);
switch (mdata->content.recv.syndrome) {
@@ -370,13 +369,13 @@ void mlx5e_tls_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
skb->decrypted = 1;
break;
case SYNDROM_RESYNC_REQUEST:
- tls_update_resync_sn(netdev, skb, mdata);
- priv = netdev_priv(netdev);
+ tls_update_resync_sn(rq->netdev, skb, mdata);
+ priv = netdev_priv(rq->netdev);
atomic64_inc(&priv->tls->sw_stats.rx_tls_resync_request);
break;
case SYNDROM_AUTH_FAILED:
/* Authentication failure will be observed and verified by kTLS */
- priv = netdev_priv(netdev);
+ priv = netdev_priv(rq->netdev);
atomic64_inc(&priv->tls->sw_stats.rx_tls_auth_fail);
break;
default:
@@ -387,3 +386,18 @@ void mlx5e_tls_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
remove_metadata_hdr(skb);
*cqe_bcnt -= MLX5E_METADATA_ETHER_LEN;
}
+
+u16 mlx5e_tls_get_stop_room(struct mlx5e_txqsq *sq)
+{
+ struct mlx5_core_dev *mdev = sq->channel->mdev;
+
+ if (!mlx5_accel_is_tls_device(mdev))
+ return 0;
+
+ if (mlx5_accel_is_ktls_device(mdev))
+ return mlx5e_ktls_get_stop_room(sq);
+
+ /* FPGA */
+ /* Resync SKB. */
+ return mlx5e_stop_room_for_wqe(MLX5_SEND_WQE_MAX_WQEBBS);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.h
index a50d0394df0a..5f162ad2ee8f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.h
@@ -34,23 +34,47 @@
#ifndef __MLX5E_TLS_RXTX_H__
#define __MLX5E_TLS_RXTX_H__
+#include "accel/accel.h"
+#include "en_accel/ktls_txrx.h"
+
#ifdef CONFIG_MLX5_EN_TLS
#include <linux/skbuff.h>
#include "en.h"
#include "en/txrx.h"
-struct mlx5e_accel_tx_tls_state {
- u32 tls_tisn;
-};
+u16 mlx5e_tls_get_stop_room(struct mlx5e_txqsq *sq);
bool mlx5e_tls_handle_tx_skb(struct net_device *netdev, struct mlx5e_txqsq *sq,
struct sk_buff *skb, struct mlx5e_accel_tx_tls_state *state);
void mlx5e_tls_handle_tx_wqe(struct mlx5e_txqsq *sq, struct mlx5_wqe_ctrl_seg *cseg,
struct mlx5e_accel_tx_tls_state *state);
-void mlx5e_tls_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
- u32 *cqe_bcnt);
+void mlx5e_tls_handle_rx_skb_metadata(struct mlx5e_rq *rq, struct sk_buff *skb,
+ u32 *cqe_bcnt);
+
+static inline void
+mlx5e_tls_handle_rx_skb(struct mlx5e_rq *rq, struct sk_buff *skb,
+ struct mlx5_cqe64 *cqe, u32 *cqe_bcnt)
+{
+ if (unlikely(get_cqe_tls_offload(cqe))) /* cqe bit indicates a TLS device */
+ return mlx5e_ktls_handle_rx_skb(rq, skb, cqe, cqe_bcnt);
+
+ if (unlikely(test_bit(MLX5E_RQ_STATE_FPGA_TLS, &rq->state) && is_metadata_hdr_valid(skb)))
+ return mlx5e_tls_handle_rx_skb_metadata(rq, skb, cqe_bcnt);
+}
+
+#else
+
+static inline bool
+mlx5e_accel_is_tls(struct mlx5_cqe64 *cqe, struct sk_buff *skb) { return false; }
+static inline void
+mlx5e_tls_handle_rx_skb(struct mlx5e_rq *rq, struct sk_buff *skb,
+ struct mlx5_cqe64 *cqe, u32 *cqe_bcnt) {}
+static inline u16 mlx5e_tls_get_stop_room(struct mlx5e_txqsq *sq)
+{
+ return 0;
+}
#endif /* CONFIG_MLX5_EN_TLS */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
index 014639ea06e3..39475f6565c7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
@@ -90,23 +90,15 @@ static enum mlx5e_traffic_types arfs_get_tt(enum arfs_type type)
static int arfs_disable(struct mlx5e_priv *priv)
{
- struct mlx5_flow_destination dest = {};
- struct mlx5e_tir *tir = priv->indir_tir;
- int err = 0;
- int tt;
- int i;
+ int err, i;
- dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
for (i = 0; i < ARFS_NUM_TYPES; i++) {
- dest.tir_num = tir[i].tirn;
- tt = arfs_get_tt(i);
- /* Modify ttc rules destination to bypass the aRFS tables*/
- err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt],
- &dest, NULL);
+ /* Modify ttc rules destination back to their default */
+ err = mlx5e_ttc_fwd_default_dest(priv, arfs_get_tt(i));
if (err) {
netdev_err(priv->netdev,
- "%s: modify ttc destination failed\n",
- __func__);
+ "%s: modify ttc[%d] default destination failed, err(%d)\n",
+ __func__, arfs_get_tt(i), err);
return err;
}
}
@@ -125,21 +117,17 @@ int mlx5e_arfs_disable(struct mlx5e_priv *priv)
int mlx5e_arfs_enable(struct mlx5e_priv *priv)
{
struct mlx5_flow_destination dest = {};
- int err = 0;
- int tt;
- int i;
+ int err, i;
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
for (i = 0; i < ARFS_NUM_TYPES; i++) {
dest.ft = priv->fs.arfs.arfs_tables[i].ft.t;
- tt = arfs_get_tt(i);
/* Modify ttc rules destination to point on the aRFS FTs */
- err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt],
- &dest, NULL);
+ err = mlx5e_ttc_fwd_dest(priv, arfs_get_tt(i), &dest);
if (err) {
netdev_err(priv->netdev,
- "%s: modify ttc destination failed err=%d\n",
- __func__, err);
+ "%s: modify ttc[%d] dest to arfs, failed err(%d)\n",
+ __func__, arfs_get_tt(i), err);
arfs_disable(priv);
return err;
}
@@ -186,8 +174,10 @@ static int arfs_add_default_rule(struct mlx5e_priv *priv,
return -EINVAL;
}
+ /* FIXME: Must use mlx5e_ttc_get_default_dest(),
+ * but can't since TTC default is not setup yet !
+ */
dest.tir_num = tir[tt].tirn;
-
arfs_t->default_rule = mlx5_add_flow_rules(arfs_t->ft.t, NULL,
&flow_act,
&dest, 1);
@@ -220,7 +210,7 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft,
sizeof(*ft->g), GFP_KERNEL);
in = kvzalloc(inlen, GFP_KERNEL);
if (!in || !ft->g) {
- kvfree(ft->g);
+ kfree(ft->g);
kvfree(in);
return -ENOMEM;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
index 1e42c7ae621b..a6cf008057b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
@@ -60,6 +60,16 @@ void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
mutex_unlock(&mdev->mlx5e_res.td.list_lock);
}
+void mlx5e_mkey_set_relaxed_ordering(struct mlx5_core_dev *mdev, void *mkc)
+{
+ bool ro_pci_enable = pcie_relaxed_ordering_enabled(mdev->pdev);
+ bool ro_write = MLX5_CAP_GEN(mdev, relaxed_ordering_write);
+ bool ro_read = MLX5_CAP_GEN(mdev, relaxed_ordering_read);
+
+ MLX5_SET(mkc, mkc, relaxed_ordering_read, ro_pci_enable && ro_read);
+ MLX5_SET(mkc, mkc, relaxed_ordering_write, ro_pci_enable && ro_write);
+}
+
static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn,
struct mlx5_core_mkey *mkey)
{
@@ -76,7 +86,7 @@ static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn,
MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_PA);
MLX5_SET(mkc, mkc, lw, 1);
MLX5_SET(mkc, mkc, lr, 1);
-
+ mlx5e_mkey_set_relaxed_ordering(mdev, mkc);
MLX5_SET(mkc, mkc, pd, pdn);
MLX5_SET(mkc, mkc, length64, 1);
MLX5_SET(mkc, mkc, qpn, 0xffffff);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index c2464c349117..08270987c506 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -194,6 +194,24 @@ void mlx5e_build_ptys2ethtool_map(void)
ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT,
ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT);
+ MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GAUI_1_100GBASE_CR_KR, ext,
+ ETHTOOL_LINK_MODE_100000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseSR_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseDR_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseCR_Full_BIT);
+ MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_200GAUI_2_200GBASE_CR2_KR2, ext,
+ ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT,
+ ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT,
+ ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT,
+ ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT,
+ ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT);
+ MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_400GAUI_4_400GBASE_CR4_KR4, ext,
+ ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT,
+ ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT,
+ ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT);
}
static void mlx5e_ethtool_get_speed_arr(struct mlx5_core_dev *mdev,
@@ -225,7 +243,7 @@ int mlx5e_ethtool_get_sset_count(struct mlx5e_priv *priv, int sset)
return MLX5E_NUM_PFLAGS;
case ETH_SS_TEST:
return mlx5e_self_test_num(priv);
- /* fallthrough */
+ fallthrough;
default:
return -EOPNOTSUPP;
}
@@ -1012,7 +1030,8 @@ static u32 mlx5e_ethtool2ptys_ext_adver_link(const unsigned long *link_modes)
unsigned long modes[2];
for (i = 0; i < MLX5E_EXT_LINK_MODES_NUMBER; ++i) {
- if (*ptys2ext_ethtool_table[i].advertised == 0)
+ if (ptys2ext_ethtool_table[i].advertised[0] == 0 &&
+ ptys2ext_ethtool_table[i].advertised[1] == 0)
continue;
memset(modes, 0, sizeof(modes));
bitmap_and(modes, ptys2ext_ethtool_table[i].advertised,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
index 73d3dc07331f..64d002d92250 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
@@ -672,9 +672,9 @@ static void mlx5e_cleanup_ttc_rules(struct mlx5e_ttc_table *ttc)
int i;
for (i = 0; i < MLX5E_NUM_TT; i++) {
- if (!IS_ERR_OR_NULL(ttc->rules[i])) {
- mlx5_del_flow_rules(ttc->rules[i]);
- ttc->rules[i] = NULL;
+ if (!IS_ERR_OR_NULL(ttc->rules[i].rule)) {
+ mlx5_del_flow_rules(ttc->rules[i].rule);
+ ttc->rules[i].rule = NULL;
}
}
@@ -857,7 +857,8 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv,
struct mlx5e_ttc_table *ttc)
{
struct mlx5_flow_destination dest = {};
- struct mlx5_flow_handle **rules;
+ struct mlx5_flow_handle **trules;
+ struct mlx5e_ttc_rule *rules;
struct mlx5_flow_table *ft;
int tt;
int err;
@@ -867,39 +868,47 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv,
dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
for (tt = 0; tt < MLX5E_NUM_TT; tt++) {
+ struct mlx5e_ttc_rule *rule = &rules[tt];
+
if (tt == MLX5E_TT_ANY)
dest.tir_num = params->any_tt_tirn;
else
dest.tir_num = params->indir_tirn[tt];
- rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
- ttc_rules[tt].etype,
- ttc_rules[tt].proto);
- if (IS_ERR(rules[tt]))
+
+ rule->rule = mlx5e_generate_ttc_rule(priv, ft, &dest,
+ ttc_rules[tt].etype,
+ ttc_rules[tt].proto);
+ if (IS_ERR(rule->rule)) {
+ err = PTR_ERR(rule->rule);
+ rule->rule = NULL;
goto del_rules;
+ }
+ rule->default_dest = dest;
}
if (!params->inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev))
return 0;
- rules = ttc->tunnel_rules;
+ trules = ttc->tunnel_rules;
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dest.ft = params->inner_ttc->ft.t;
for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) {
if (!mlx5e_tunnel_proto_supported(priv->mdev,
ttc_tunnel_rules[tt].proto))
continue;
- rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
- ttc_tunnel_rules[tt].etype,
- ttc_tunnel_rules[tt].proto);
- if (IS_ERR(rules[tt]))
+ trules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
+ ttc_tunnel_rules[tt].etype,
+ ttc_tunnel_rules[tt].proto);
+ if (IS_ERR(trules[tt])) {
+ err = PTR_ERR(trules[tt]);
+ trules[tt] = NULL;
goto del_rules;
+ }
}
return 0;
del_rules:
- err = PTR_ERR(rules[tt]);
- rules[tt] = NULL;
mlx5e_cleanup_ttc_rules(ttc);
return err;
}
@@ -1015,33 +1024,38 @@ static int mlx5e_generate_inner_ttc_table_rules(struct mlx5e_priv *priv,
struct mlx5e_ttc_table *ttc)
{
struct mlx5_flow_destination dest = {};
- struct mlx5_flow_handle **rules;
+ struct mlx5e_ttc_rule *rules;
struct mlx5_flow_table *ft;
int err;
int tt;
ft = ttc->ft.t;
rules = ttc->rules;
-
dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
+
for (tt = 0; tt < MLX5E_NUM_TT; tt++) {
+ struct mlx5e_ttc_rule *rule = &rules[tt];
+
if (tt == MLX5E_TT_ANY)
dest.tir_num = params->any_tt_tirn;
else
dest.tir_num = params->indir_tirn[tt];
- rules[tt] = mlx5e_generate_inner_ttc_rule(priv, ft, &dest,
- ttc_rules[tt].etype,
- ttc_rules[tt].proto);
- if (IS_ERR(rules[tt]))
+ rule->rule = mlx5e_generate_inner_ttc_rule(priv, ft, &dest,
+ ttc_rules[tt].etype,
+ ttc_rules[tt].proto);
+ if (IS_ERR(rule->rule)) {
+ err = PTR_ERR(rule->rule);
+ rule->rule = NULL;
goto del_rules;
+ }
+ rule->default_dest = dest;
}
return 0;
del_rules:
- err = PTR_ERR(rules[tt]);
- rules[tt] = NULL;
+
mlx5e_cleanup_ttc_rules(ttc);
return err;
}
@@ -1210,6 +1224,30 @@ err:
return err;
}
+int mlx5e_ttc_fwd_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type,
+ struct mlx5_flow_destination *new_dest)
+{
+ return mlx5_modify_rule_destination(priv->fs.ttc.rules[type].rule, new_dest, NULL);
+}
+
+struct mlx5_flow_destination
+mlx5e_ttc_get_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type)
+{
+ struct mlx5_flow_destination *dest = &priv->fs.ttc.rules[type].default_dest;
+
+ WARN_ONCE(dest->type != MLX5_FLOW_DESTINATION_TYPE_TIR,
+ "TTC[%d] default dest is not setup yet", type);
+
+ return *dest;
+}
+
+int mlx5e_ttc_fwd_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type)
+{
+ struct mlx5_flow_destination dest = mlx5e_ttc_get_default_dest(priv, type);
+
+ return mlx5e_ttc_fwd_dest(priv, type, &dest);
+}
+
static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv,
struct mlx5e_l2_rule *ai)
{
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 3b892ec301b4..aebcf73f8546 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -45,7 +45,6 @@
#include "en_tc.h"
#include "en_rep.h"
#include "en_accel/ipsec.h"
-#include "en_accel/ipsec_rxtx.h"
#include "en_accel/en_accel.h"
#include "en_accel/tls.h"
#include "accel/ipsec.h"
@@ -231,7 +230,6 @@ static inline void mlx5e_build_umr_wqe(struct mlx5e_rq *rq,
cseg->qpn_ds = cpu_to_be32((sq->sqn << MLX5_WQE_CTRL_QPN_SHIFT) |
ds_cnt);
- cseg->fm_ce_se = MLX5_WQE_CTRL_CQ_UPDATE;
cseg->umr_mkey = rq->mkey_be;
ucseg->flags = MLX5_UMR_TRANSLATION_OFFSET_EN | MLX5_UMR_INLINE;
@@ -276,7 +274,7 @@ static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
MLX5_SET(mkc, mkc, lw, 1);
MLX5_SET(mkc, mkc, lr, 1);
MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MTT);
-
+ mlx5e_mkey_set_relaxed_ordering(mdev, mkc);
MLX5_SET(mkc, mkc, qpn, 0xffffff);
MLX5_SET(mkc, mkc, pd, mdev->mlx5e_res.pdn);
MLX5_SET64(mkc, mkc, len, npages << page_shift);
@@ -428,29 +426,6 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
pool_size = MLX5_MPWRQ_PAGES_PER_WQE <<
mlx5e_mpwqe_get_log_rq_size(params, xsk);
- rq->post_wqes = mlx5e_post_rx_mpwqes;
- rq->dealloc_wqe = mlx5e_dealloc_rx_mpwqe;
-
- rq->handle_rx_cqe = c->priv->profile->rx_handlers.handle_rx_cqe_mpwqe;
-#ifdef CONFIG_MLX5_EN_IPSEC
- if (MLX5_IPSEC_DEV(mdev)) {
- err = -EINVAL;
- netdev_err(c->netdev, "MPWQE RQ with IPSec offload not supported\n");
- goto err_rq_wq_destroy;
- }
-#endif
- if (!rq->handle_rx_cqe) {
- err = -EINVAL;
- netdev_err(c->netdev, "RX handler of MPWQE RQ is not set, err %d\n", err);
- goto err_rq_wq_destroy;
- }
-
- rq->mpwqe.skb_from_cqe_mpwrq = xsk ?
- mlx5e_xsk_skb_from_cqe_mpwrq_linear :
- mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL) ?
- mlx5e_skb_from_cqe_mpwrq_linear :
- mlx5e_skb_from_cqe_mpwrq_nonlinear;
-
rq->mpwqe.log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params, xsk);
rq->mpwqe.num_strides =
BIT(mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk));
@@ -492,29 +467,13 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
if (err)
goto err_free;
- rq->post_wqes = mlx5e_post_rx_wqes;
- rq->dealloc_wqe = mlx5e_dealloc_rx_wqe;
-
-#ifdef CONFIG_MLX5_EN_IPSEC
- if (c->priv->ipsec)
- rq->handle_rx_cqe = mlx5e_ipsec_handle_rx_cqe;
- else
-#endif
- rq->handle_rx_cqe = c->priv->profile->rx_handlers.handle_rx_cqe;
- if (!rq->handle_rx_cqe) {
- err = -EINVAL;
- netdev_err(c->netdev, "RX handler of RQ is not set, err %d\n", err);
- goto err_free;
- }
-
- rq->wqe.skb_from_cqe = xsk ?
- mlx5e_xsk_skb_from_cqe_linear :
- mlx5e_rx_is_linear_skb(params, NULL) ?
- mlx5e_skb_from_cqe_linear :
- mlx5e_skb_from_cqe_nonlinear;
rq->mkey_be = c->mkey_be;
}
+ err = mlx5e_rq_set_handlers(rq, params, xsk);
+ if (err)
+ goto err_free;
+
if (xsk) {
err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
MEM_TYPE_XSK_BUFF_POOL, NULL);
@@ -873,6 +832,9 @@ int mlx5e_open_rq(struct mlx5e_channel *c, struct mlx5e_params *params,
if (err)
goto err_destroy_rq;
+ if (mlx5e_is_tls_on(c->priv) && !mlx5_accel_is_ktls_device(c->mdev))
+ __set_bit(MLX5E_RQ_STATE_FPGA_TLS, &c->rq.state); /* must be FPGA */
+
if (MLX5_CAP_ETH(c->mdev, cqe_checksum_full))
__set_bit(MLX5E_RQ_STATE_CSUM_FULL, &c->rq.state);
@@ -1441,6 +1403,7 @@ void mlx5e_close_icosq(struct mlx5e_icosq *sq)
struct mlx5e_channel *c = sq->channel;
mlx5e_destroy_sq(c->mdev, sq->sqn);
+ mlx5e_free_icosq_descs(sq);
mlx5e_free_icosq(sq);
}
@@ -1675,7 +1638,7 @@ static int mlx5e_open_tx_cqs(struct mlx5e_channel *c,
for (tc = 0; tc < c->num_tc; tc++) {
err = mlx5e_open_cq(c, params->tx_cq_moderation,
- &cparam->tx_cq, &c->sq[tc].cq);
+ &cparam->txq_sq.cqp, &c->sq[tc].cq);
if (err)
goto err_close_tx_cqs;
}
@@ -1707,7 +1670,7 @@ static int mlx5e_open_sqs(struct mlx5e_channel *c,
int txq_ix = c->ix + tc * params->num_channels;
err = mlx5e_open_txqsq(c, c->priv->tisn[c->lag_port][tc], txq_ix,
- params, &cparam->sq, &c->sq[tc], tc);
+ params, &cparam->txq_sq, &c->sq[tc], tc);
if (err)
goto err_close_sqs;
}
@@ -1817,34 +1780,43 @@ static int mlx5e_open_queues(struct mlx5e_channel *c,
struct dim_cq_moder icocq_moder = {0, 0};
int err;
- err = mlx5e_open_cq(c, icocq_moder, &cparam->icosq_cq, &c->icosq.cq);
+ err = mlx5e_open_cq(c, icocq_moder, &cparam->icosq.cqp, &c->async_icosq.cq);
if (err)
return err;
+ err = mlx5e_open_cq(c, icocq_moder, &cparam->async_icosq.cqp, &c->icosq.cq);
+ if (err)
+ goto err_close_async_icosq_cq;
+
err = mlx5e_open_tx_cqs(c, params, cparam);
if (err)
goto err_close_icosq_cq;
- err = mlx5e_open_cq(c, params->tx_cq_moderation, &cparam->tx_cq, &c->xdpsq.cq);
+ err = mlx5e_open_cq(c, params->tx_cq_moderation, &cparam->xdp_sq.cqp, &c->xdpsq.cq);
if (err)
goto err_close_tx_cqs;
- err = mlx5e_open_cq(c, params->rx_cq_moderation, &cparam->rx_cq, &c->rq.cq);
+ err = mlx5e_open_cq(c, params->rx_cq_moderation, &cparam->rq.cqp, &c->rq.cq);
if (err)
goto err_close_xdp_tx_cqs;
- /* XDP SQ CQ params are same as normal TXQ sq CQ params */
err = c->xdp ? mlx5e_open_cq(c, params->tx_cq_moderation,
- &cparam->tx_cq, &c->rq_xdpsq.cq) : 0;
+ &cparam->xdp_sq.cqp, &c->rq_xdpsq.cq) : 0;
if (err)
goto err_close_rx_cq;
napi_enable(&c->napi);
- err = mlx5e_open_icosq(c, params, &cparam->icosq, &c->icosq);
+ spin_lock_init(&c->async_icosq_lock);
+
+ err = mlx5e_open_icosq(c, params, &cparam->async_icosq, &c->async_icosq);
if (err)
goto err_disable_napi;
+ err = mlx5e_open_icosq(c, params, &cparam->icosq, &c->icosq);
+ if (err)
+ goto err_close_async_icosq;
+
err = mlx5e_open_sqs(c, params, cparam);
if (err)
goto err_close_icosq;
@@ -1879,6 +1851,9 @@ err_close_sqs:
err_close_icosq:
mlx5e_close_icosq(&c->icosq);
+err_close_async_icosq:
+ mlx5e_close_icosq(&c->async_icosq);
+
err_disable_napi:
napi_disable(&c->napi);
@@ -1897,6 +1872,9 @@ err_close_tx_cqs:
err_close_icosq_cq:
mlx5e_close_cq(&c->icosq.cq);
+err_close_async_icosq_cq:
+ mlx5e_close_cq(&c->async_icosq.cq);
+
return err;
}
@@ -1908,6 +1886,7 @@ static void mlx5e_close_queues(struct mlx5e_channel *c)
mlx5e_close_xdpsq(&c->rq_xdpsq);
mlx5e_close_sqs(c);
mlx5e_close_icosq(&c->icosq);
+ mlx5e_close_icosq(&c->async_icosq);
napi_disable(&c->napi);
if (c->xdp)
mlx5e_close_cq(&c->rq_xdpsq.cq);
@@ -1915,6 +1894,7 @@ static void mlx5e_close_queues(struct mlx5e_channel *c)
mlx5e_close_cq(&c->xdpsq.cq);
mlx5e_close_tx_cqs(c);
mlx5e_close_cq(&c->icosq.cq);
+ mlx5e_close_cq(&c->async_icosq.cq);
}
static u8 mlx5e_enumerate_lag_port(struct mlx5_core_dev *mdev, int ix)
@@ -1995,6 +1975,7 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c)
for (tc = 0; tc < c->num_tc; tc++)
mlx5e_activate_txqsq(&c->sq[tc]);
mlx5e_activate_icosq(&c->icosq);
+ mlx5e_activate_icosq(&c->async_icosq);
mlx5e_activate_rq(&c->rq);
if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
@@ -2009,6 +1990,7 @@ static void mlx5e_deactivate_channel(struct mlx5e_channel *c)
mlx5e_deactivate_xsk(c);
mlx5e_deactivate_rq(&c->rq);
+ mlx5e_deactivate_icosq(&c->async_icosq);
mlx5e_deactivate_icosq(&c->icosq);
for (tc = 0; tc < c->num_tc; tc++)
mlx5e_deactivate_txqsq(&c->sq[tc]);
@@ -2138,6 +2120,7 @@ void mlx5e_build_rq_param(struct mlx5e_priv *priv,
MLX5_SET(rqc, rqc, scatter_fcs, params->scatter_fcs_en);
param->wq.buf_numa_node = dev_to_node(mdev->device);
+ mlx5e_build_rx_cq_param(priv, params, xsk, &param->cqp);
}
static void mlx5e_build_drop_rq_param(struct mlx5e_priv *priv,
@@ -2180,6 +2163,7 @@ static void mlx5e_build_sq_param(struct mlx5e_priv *priv,
mlx5e_build_sq_param_common(priv, param);
MLX5_SET(wq, wq, log_wq_sz, params->log_sq_size);
MLX5_SET(sqc, sqc, allow_swp, allow_swp);
+ mlx5e_build_tx_cq_param(priv, params, &param->cqp);
}
static void mlx5e_build_common_cq_param(struct mlx5e_priv *priv,
@@ -2256,6 +2240,7 @@ void mlx5e_build_icosq_param(struct mlx5e_priv *priv,
MLX5_SET(wq, wq, log_wq_sz, log_wq_size);
MLX5_SET(sqc, sqc, reg_umr, MLX5_CAP_ETH(priv->mdev, reg_umr_sq));
+ mlx5e_build_ico_cq_param(priv, log_wq_size, &param->cqp);
}
void mlx5e_build_xdpsq_param(struct mlx5e_priv *priv,
@@ -2268,6 +2253,7 @@ void mlx5e_build_xdpsq_param(struct mlx5e_priv *priv,
mlx5e_build_sq_param_common(priv, param);
MLX5_SET(wq, wq, log_wq_sz, params->log_sq_size);
param->is_mpw = MLX5E_GET_PFLAG(params, MLX5E_PFLAG_XDP_TX_MPWQE);
+ mlx5e_build_tx_cq_param(priv, params, &param->cqp);
}
static u8 mlx5e_build_icosq_log_wq_sz(struct mlx5e_params *params,
@@ -2282,22 +2268,29 @@ static u8 mlx5e_build_icosq_log_wq_sz(struct mlx5e_params *params,
}
}
+static u8 mlx5e_build_async_icosq_log_wq_sz(struct net_device *netdev)
+{
+ if (netdev->hw_features & NETIF_F_HW_TLS_RX)
+ return MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
+
+ return MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
+}
+
static void mlx5e_build_channel_param(struct mlx5e_priv *priv,
struct mlx5e_params *params,
struct mlx5e_channel_param *cparam)
{
- u8 icosq_log_wq_sz;
+ u8 icosq_log_wq_sz, async_icosq_log_wq_sz;
mlx5e_build_rq_param(priv, params, NULL, &cparam->rq);
icosq_log_wq_sz = mlx5e_build_icosq_log_wq_sz(params, &cparam->rq);
+ async_icosq_log_wq_sz = mlx5e_build_async_icosq_log_wq_sz(priv->netdev);
- mlx5e_build_sq_param(priv, params, &cparam->sq);
+ mlx5e_build_sq_param(priv, params, &cparam->txq_sq);
mlx5e_build_xdpsq_param(priv, params, &cparam->xdp_sq);
mlx5e_build_icosq_param(priv, icosq_log_wq_sz, &cparam->icosq);
- mlx5e_build_rx_cq_param(priv, params, NULL, &cparam->rx_cq);
- mlx5e_build_tx_cq_param(priv, params, &cparam->tx_cq);
- mlx5e_build_ico_cq_param(priv, icosq_log_wq_sz, &cparam->icosq_cq);
+ mlx5e_build_icosq_param(priv, async_icosq_log_wq_sz, &cparam->async_icosq);
}
int mlx5e_open_channels(struct mlx5e_priv *priv,
@@ -3847,6 +3840,7 @@ int mlx5e_set_features(struct net_device *netdev, netdev_features_t features)
#ifdef CONFIG_MLX5_EN_ARFS
err |= MLX5E_HANDLE_FEATURE(NETIF_F_NTUPLE, set_feature_arfs);
#endif
+ err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TLS_RX, mlx5e_ktls_set_feature_rx);
if (err) {
netdev->features = oper_features;
@@ -4197,83 +4191,6 @@ int mlx5e_get_vf_stats(struct net_device *dev,
}
#endif
-struct mlx5e_vxlan_work {
- struct work_struct work;
- struct mlx5e_priv *priv;
- u16 port;
-};
-
-static void mlx5e_vxlan_add_work(struct work_struct *work)
-{
- struct mlx5e_vxlan_work *vxlan_work =
- container_of(work, struct mlx5e_vxlan_work, work);
- struct mlx5e_priv *priv = vxlan_work->priv;
- u16 port = vxlan_work->port;
-
- mutex_lock(&priv->state_lock);
- mlx5_vxlan_add_port(priv->mdev->vxlan, port);
- mutex_unlock(&priv->state_lock);
-
- kfree(vxlan_work);
-}
-
-static void mlx5e_vxlan_del_work(struct work_struct *work)
-{
- struct mlx5e_vxlan_work *vxlan_work =
- container_of(work, struct mlx5e_vxlan_work, work);
- struct mlx5e_priv *priv = vxlan_work->priv;
- u16 port = vxlan_work->port;
-
- mutex_lock(&priv->state_lock);
- mlx5_vxlan_del_port(priv->mdev->vxlan, port);
- mutex_unlock(&priv->state_lock);
- kfree(vxlan_work);
-}
-
-static void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add)
-{
- struct mlx5e_vxlan_work *vxlan_work;
-
- vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC);
- if (!vxlan_work)
- return;
-
- if (add)
- INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_work);
- else
- INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_work);
-
- vxlan_work->priv = priv;
- vxlan_work->port = port;
- queue_work(priv->wq, &vxlan_work->work);
-}
-
-void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
-{
- struct mlx5e_priv *priv = netdev_priv(netdev);
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
- return;
-
- mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
-}
-
-void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
-{
- struct mlx5e_priv *priv = netdev_priv(netdev);
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
- return;
-
- mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
-}
-
static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
struct sk_buff *skb,
netdev_features_t features)
@@ -4348,8 +4265,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work)
{
struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
tx_timeout_work);
- bool report_failed = false;
- int err;
int i;
rtnl_lock();
@@ -4367,18 +4282,10 @@ static void mlx5e_tx_timeout_work(struct work_struct *work)
continue;
if (mlx5e_reporter_tx_timeout(sq))
- report_failed = true;
+ /* break if tried to reopened channels */
+ break;
}
- if (!report_failed)
- goto unlock;
-
- err = mlx5e_safe_reopen_channels(priv);
- if (err)
- netdev_err(priv->netdev,
- "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n",
- err);
-
unlock:
mutex_unlock(&priv->state_lock);
rtnl_unlock();
@@ -4511,29 +4418,11 @@ unlock:
return err;
}
-static u32 mlx5e_xdp_query(struct net_device *dev)
-{
- struct mlx5e_priv *priv = netdev_priv(dev);
- const struct bpf_prog *xdp_prog;
- u32 prog_id = 0;
-
- mutex_lock(&priv->state_lock);
- xdp_prog = priv->channels.params.xdp_prog;
- if (xdp_prog)
- prog_id = xdp_prog->aux->id;
- mutex_unlock(&priv->state_lock);
-
- return prog_id;
-}
-
static int mlx5e_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
switch (xdp->command) {
case XDP_SETUP_PROG:
return mlx5e_xdp_set(dev, xdp->prog);
- case XDP_QUERY_PROG:
- xdp->prog_id = mlx5e_xdp_query(dev);
- return 0;
case XDP_SETUP_XSK_UMEM:
return mlx5e_xsk_setup_umem(dev, xdp->xsk.umem,
xdp->xsk.queue_id);
@@ -4613,8 +4502,8 @@ const struct net_device_ops mlx5e_netdev_ops = {
.ndo_change_mtu = mlx5e_change_nic_mtu,
.ndo_do_ioctl = mlx5e_ioctl,
.ndo_set_tx_maxrate = mlx5e_set_tx_maxrate,
- .ndo_udp_tunnel_add = mlx5e_add_vxlan_port,
- .ndo_udp_tunnel_del = mlx5e_del_vxlan_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = mlx5e_features_check,
.ndo_tx_timeout = mlx5e_tx_timeout,
.ndo_bpf = mlx5e_xdp,
@@ -4885,6 +4774,39 @@ static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
}
}
+static int mlx5e_vxlan_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti)
+{
+ struct mlx5e_priv *priv = netdev_priv(netdev);
+
+ return mlx5_vxlan_add_port(priv->mdev->vxlan, ntohs(ti->port));
+}
+
+static int mlx5e_vxlan_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti)
+{
+ struct mlx5e_priv *priv = netdev_priv(netdev);
+
+ return mlx5_vxlan_del_port(priv->mdev->vxlan, ntohs(ti->port));
+}
+
+void mlx5e_vxlan_set_netdev_info(struct mlx5e_priv *priv)
+{
+ if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
+ return;
+
+ priv->nic_info.set_port = mlx5e_vxlan_set_port;
+ priv->nic_info.unset_port = mlx5e_vxlan_unset_port;
+ priv->nic_info.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
+ UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN;
+ priv->nic_info.tables[0].tunnel_types = UDP_TUNNEL_TYPE_VXLAN;
+ /* Don't count the space hard-coded to the IANA port */
+ priv->nic_info.tables[0].n_entries =
+ mlx5_vxlan_max_udp_ports(priv->mdev) - 1;
+
+ priv->netdev->udp_tunnel_nic_info = &priv->nic_info;
+}
+
static void mlx5e_build_nic_netdev(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4928,6 +4850,8 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
netdev->hw_features |= NETIF_F_HW_VLAN_STAG_TX;
+ mlx5e_vxlan_set_netdev_info(priv);
+
if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev) ||
mlx5e_any_tunnel_proto_supported(mdev)) {
netdev->hw_enc_features |= NETIF_F_HW_CSUM;
@@ -5077,6 +5001,9 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
if (err)
mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
mlx5e_build_nic_netdev(netdev);
+ err = mlx5e_devlink_port_register(priv);
+ if (err)
+ mlx5_core_err(mdev, "mlx5e_devlink_port_register failed, %d\n", err);
mlx5e_health_create_reporters(priv);
return 0;
@@ -5085,6 +5012,7 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
{
mlx5e_health_destroy_reporters(priv);
+ mlx5e_devlink_port_unregister(priv);
mlx5e_tls_cleanup(priv);
mlx5e_ipsec_cleanup(priv);
mlx5e_netdev_cleanup(priv->netdev, priv);
@@ -5137,12 +5065,18 @@ static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
if (err)
goto err_destroy_flow_steering;
+ err = mlx5e_accel_init_rx(priv);
+ if (err)
+ goto err_tc_nic_cleanup;
+
#ifdef CONFIG_MLX5_EN_ARFS
priv->netdev->rx_cpu_rmap = mlx5_eq_table_get_rmap(priv->mdev);
#endif
return 0;
+err_tc_nic_cleanup:
+ mlx5e_tc_nic_cleanup(priv);
err_destroy_flow_steering:
mlx5e_destroy_flow_steering(priv);
err_destroy_xsk_tirs:
@@ -5166,6 +5100,7 @@ err_destroy_q_counters:
static void mlx5e_cleanup_nic_rx(struct mlx5e_priv *priv)
{
+ mlx5e_accel_cleanup_rx(priv);
mlx5e_tc_nic_cleanup(priv);
mlx5e_destroy_flow_steering(priv);
mlx5e_destroy_direct_tirs(priv, priv->xsk_tir);
@@ -5222,8 +5157,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
rtnl_lock();
if (netif_running(netdev))
mlx5e_open(netdev);
- if (mlx5_vxlan_allowed(priv->mdev->vxlan))
- udp_tunnel_get_rx_info(netdev);
+ udp_tunnel_nic_reset_ntf(priv->netdev);
netif_device_attach(netdev);
rtnl_unlock();
}
@@ -5238,8 +5172,6 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
rtnl_lock();
if (netif_running(priv->netdev))
mlx5e_close(priv->netdev);
- if (mlx5_vxlan_allowed(priv->mdev->vxlan))
- udp_tunnel_drop_rx_info(priv->netdev);
netif_device_detach(priv->netdev);
rtnl_unlock();
@@ -5270,8 +5202,7 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
.update_rx = mlx5e_update_nic_rx,
.update_stats = mlx5e_update_ndo_stats,
.update_carrier = mlx5e_update_carrier,
- .rx_handlers.handle_rx_cqe = mlx5e_handle_rx_cqe,
- .rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
+ .rx_handlers = &mlx5e_rx_handlers_nic,
.max_tc = MLX5E_MAX_NUM_TC,
.rq_groups = MLX5E_NUM_RQ_GROUPS(XSK),
.stats_grps = mlx5e_nic_stats_grps,
@@ -5516,16 +5447,10 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
goto err_destroy_netdev;
}
- err = mlx5e_devlink_port_register(priv);
- if (err) {
- mlx5_core_err(mdev, "mlx5e_devlink_port_register failed, %d\n", err);
- goto err_detach;
- }
-
err = register_netdev(netdev);
if (err) {
mlx5_core_err(mdev, "register_netdev failed, %d\n", err);
- goto err_devlink_port_unregister;
+ goto err_detach;
}
mlx5e_devlink_port_type_eth_set(priv);
@@ -5533,8 +5458,6 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
mlx5e_dcbnl_init_app(priv);
return priv;
-err_devlink_port_unregister:
- mlx5e_devlink_port_unregister(priv);
err_detach:
mlx5e_detach(mdev, priv);
err_destroy_netdev:
@@ -5555,7 +5478,6 @@ static void mlx5e_remove(struct mlx5_core_dev *mdev, void *vpriv)
priv = vpriv;
mlx5e_dcbnl_delete_app(priv);
unregister_netdev(priv->netdev);
- mlx5e_devlink_port_unregister(priv);
mlx5e_detach(mdev, vpriv);
mlx5e_destroy_netdev(priv);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 9519a61bd8ec..e13e5d1b3eae 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -35,7 +35,6 @@
#include <net/switchdev.h>
#include <net/pkt_cls.h>
#include <net/act_api.h>
-#include <net/arp.h>
#include <net/devlink.h>
#include <net/ipv6_stubs.h>
@@ -43,6 +42,7 @@
#include "esw/chains.h"
#include "en.h"
#include "en_rep.h"
+#include "en/txrx.h"
#include "en_tc.h"
#include "en/rep/tc.h"
#include "en/rep/neigh.h"
@@ -611,6 +611,29 @@ static struct devlink_port *mlx5e_rep_get_devlink_port(struct net_device *dev)
return &rpriv->dl_port;
}
+static int mlx5e_rep_change_carrier(struct net_device *dev, bool new_carrier)
+{
+ struct mlx5e_priv *priv = netdev_priv(dev);
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
+ struct mlx5_eswitch_rep *rep = rpriv->rep;
+ int err;
+
+ if (new_carrier) {
+ err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
+ rep->vport, 1, MLX5_VPORT_ADMIN_STATE_UP);
+ if (err)
+ return err;
+ netif_carrier_on(dev);
+ } else {
+ err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
+ rep->vport, 1, MLX5_VPORT_ADMIN_STATE_DOWN);
+ if (err)
+ return err;
+ netif_carrier_off(dev);
+ }
+ return 0;
+}
+
static const struct net_device_ops mlx5e_netdev_ops_rep = {
.ndo_open = mlx5e_rep_open,
.ndo_stop = mlx5e_rep_close,
@@ -621,6 +644,7 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = {
.ndo_has_offload_stats = mlx5e_rep_has_offload_stats,
.ndo_get_offload_stats = mlx5e_rep_get_offload_stats,
.ndo_change_mtu = mlx5e_rep_change_mtu,
+ .ndo_change_carrier = mlx5e_rep_change_carrier,
};
static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
@@ -634,8 +658,8 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
.ndo_has_offload_stats = mlx5e_rep_has_offload_stats,
.ndo_get_offload_stats = mlx5e_rep_get_offload_stats,
.ndo_change_mtu = mlx5e_uplink_rep_change_mtu,
- .ndo_udp_tunnel_add = mlx5e_add_vxlan_port,
- .ndo_udp_tunnel_del = mlx5e_del_vxlan_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = mlx5e_features_check,
.ndo_set_vf_mac = mlx5e_set_vf_mac,
.ndo_set_vf_rate = mlx5e_set_vf_rate,
@@ -700,12 +724,13 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
struct mlx5_eswitch_rep *rep = rpriv->rep;
struct mlx5_core_dev *mdev = priv->mdev;
+ SET_NETDEV_DEV(netdev, mdev->device);
if (rep->vport == MLX5_VPORT_UPLINK) {
- SET_NETDEV_DEV(netdev, mdev->device);
netdev->netdev_ops = &mlx5e_netdev_ops_uplink_rep;
/* we want a persistent mac for the uplink rep */
mlx5_query_mac_address(mdev, netdev->dev_addr);
netdev->ethtool_ops = &mlx5e_uplink_rep_ethtool_ops;
+ mlx5e_vxlan_set_netdev_info(priv);
mlx5e_dcbnl_build_rep_netdev(netdev);
} else {
netdev->netdev_ops = &mlx5e_netdev_ops_rep;
@@ -1147,8 +1172,7 @@ static const struct mlx5e_profile mlx5e_rep_profile = {
.enable = mlx5e_rep_enable,
.update_rx = mlx5e_update_rep_rx,
.update_stats = mlx5e_update_ndo_stats,
- .rx_handlers.handle_rx_cqe = mlx5e_handle_rx_cqe_rep,
- .rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq_rep,
+ .rx_handlers = &mlx5e_rx_handlers_rep,
.max_tc = 1,
.rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
.stats_grps = mlx5e_rep_stats_grps,
@@ -1167,8 +1191,7 @@ static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
.update_rx = mlx5e_update_rep_rx,
.update_stats = mlx5e_update_ndo_stats,
.update_carrier = mlx5e_update_carrier,
- .rx_handlers.handle_rx_cqe = mlx5e_handle_rx_cqe_rep,
- .rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq_rep,
+ .rx_handlers = &mlx5e_rx_handlers_rep,
.max_tc = MLX5E_MAX_NUM_TC,
.rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
.stats_grps = mlx5e_ul_rep_stats_grps,
@@ -1184,17 +1207,12 @@ is_devlink_port_supported(const struct mlx5_core_dev *dev,
mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport);
}
-static unsigned int
-vport_to_devlink_port_index(const struct mlx5_core_dev *dev, u16 vport_num)
-{
- return (MLX5_CAP_GEN(dev, vhca_id) << 16) | vport_num;
-}
-
static int register_devlink_port(struct mlx5_core_dev *dev,
struct mlx5e_rep_priv *rpriv)
{
struct devlink *devlink = priv_to_devlink(dev);
struct mlx5_eswitch_rep *rep = rpriv->rep;
+ struct devlink_port_attrs attrs = {};
struct netdev_phys_item_id ppid = {};
unsigned int dl_port_index = 0;
u16 pfnum;
@@ -1203,23 +1221,24 @@ static int register_devlink_port(struct mlx5_core_dev *dev,
return 0;
mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid);
- dl_port_index = vport_to_devlink_port_index(dev, rep->vport);
+ dl_port_index = mlx5_esw_vport_to_devlink_port_index(dev, rep->vport);
pfnum = PCI_FUNC(dev->pdev->devfn);
-
- if (rep->vport == MLX5_VPORT_UPLINK)
- devlink_port_attrs_set(&rpriv->dl_port,
- DEVLINK_PORT_FLAVOUR_PHYSICAL,
- pfnum, false, 0,
- &ppid.id[0], ppid.id_len);
- else if (rep->vport == MLX5_VPORT_PF)
- devlink_port_attrs_pci_pf_set(&rpriv->dl_port,
- &ppid.id[0], ppid.id_len,
- pfnum);
- else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport))
+ if (rep->vport == MLX5_VPORT_UPLINK) {
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = pfnum;
+ memcpy(attrs.switch_id.id, &ppid.id[0], ppid.id_len);
+ attrs.switch_id.id_len = ppid.id_len;
+ devlink_port_attrs_set(&rpriv->dl_port, &attrs);
+ } else if (rep->vport == MLX5_VPORT_PF) {
+ memcpy(rpriv->dl_port.attrs.switch_id.id, &ppid.id[0], ppid.id_len);
+ rpriv->dl_port.attrs.switch_id.id_len = ppid.id_len;
+ devlink_port_attrs_pci_pf_set(&rpriv->dl_port, pfnum);
+ } else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport)) {
+ memcpy(rpriv->dl_port.attrs.switch_id.id, &ppid.id[0], ppid.id_len);
+ rpriv->dl_port.attrs.switch_id.id_len = ppid.id_len;
devlink_port_attrs_pci_vf_set(&rpriv->dl_port,
- &ppid.id[0], ppid.id_len,
pfnum, rep->vport - 1);
-
+ }
return devlink_port_register(devlink, &rpriv->dl_port, dl_port_index);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
index 1d5669801484..622c27ae4ac7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
@@ -41,6 +41,8 @@
#include "lib/port_tun.h"
#ifdef CONFIG_MLX5_ESWITCH
+extern const struct mlx5e_rx_handlers mlx5e_rx_handlers_rep;
+
struct mlx5e_neigh_update_table {
struct rhashtable neigh_ht;
/* Save the neigh hash entries in a list in addition to the hash table
@@ -223,10 +225,6 @@ bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv);
int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv);
void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv);
-void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
-void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq,
- struct mlx5_cqe64 *cqe);
-
void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv);
bool mlx5e_eswitch_vf_rep(struct net_device *netdev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index dbb1c6323967..65828af120b7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -34,22 +34,39 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/tcp.h>
-#include <linux/indirect_call_wrapper.h>
#include <net/ip6_checksum.h>
#include <net/page_pool.h>
#include <net/inet_ecn.h>
#include "en.h"
+#include "en/txrx.h"
#include "en_tc.h"
#include "eswitch.h"
#include "en_rep.h"
#include "en/rep/tc.h"
#include "ipoib/ipoib.h"
+#include "accel/ipsec.h"
+#include "fpga/ipsec.h"
#include "en_accel/ipsec_rxtx.h"
#include "en_accel/tls_rxtx.h"
#include "lib/clock.h"
#include "en/xdp.h"
#include "en/xsk/rx.h"
#include "en/health.h"
+#include "en/params.h"
+
+static struct sk_buff *
+mlx5e_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
+ u16 cqe_bcnt, u32 head_offset, u32 page_idx);
+static struct sk_buff *
+mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
+ u16 cqe_bcnt, u32 head_offset, u32 page_idx);
+static void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
+static void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
+
+const struct mlx5e_rx_handlers mlx5e_rx_handlers_nic = {
+ .handle_rx_cqe = mlx5e_handle_rx_cqe,
+ .handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
+};
static inline bool mlx5e_rx_hw_stamp(struct hwtstamp_config *config)
{
@@ -370,7 +387,7 @@ static inline void mlx5e_free_rx_wqe(struct mlx5e_rq *rq,
mlx5e_put_rx_frag(rq, wi, recycle);
}
-void mlx5e_dealloc_rx_wqe(struct mlx5e_rq *rq, u16 ix)
+static void mlx5e_dealloc_rx_wqe(struct mlx5e_rq *rq, u16 ix)
{
struct mlx5e_wqe_frag_info *wi = get_frag(rq, ix);
@@ -537,14 +554,14 @@ err:
return err;
}
-void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
+static void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
{
struct mlx5e_mpw_info *wi = &rq->mpwqe.info[ix];
/* Don't recycle, this function is called on rq/netdev close */
mlx5e_free_rx_mpwqe(rq, wi, false);
}
-bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
+INDIRECT_CALLABLE_SCOPE bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
{
struct mlx5_wq_cyc *wq = &rq->wqe.wq;
u8 wqe_bulk;
@@ -578,6 +595,33 @@ bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
return !!err;
}
+void mlx5e_free_icosq_descs(struct mlx5e_icosq *sq)
+{
+ u16 sqcc;
+
+ sqcc = sq->cc;
+
+ while (sqcc != sq->pc) {
+ struct mlx5e_icosq_wqe_info *wi;
+ u16 ci;
+
+ ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc);
+ wi = &sq->db.wqe_info[ci];
+ sqcc += wi->num_wqebbs;
+#ifdef CONFIG_MLX5_EN_TLS
+ switch (wi->wqe_type) {
+ case MLX5E_ICOSQ_WQE_SET_PSV_TLS:
+ mlx5e_ktls_handle_ctx_completion(wi);
+ break;
+ case MLX5E_ICOSQ_WQE_GET_PSV_TLS:
+ mlx5e_ktls_handle_get_psv_completion(wi, sq);
+ break;
+ }
+#endif
+ }
+ sq->cc = sqcc;
+}
+
int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
{
struct mlx5e_icosq *sq = container_of(cq, struct mlx5e_icosq, cq);
@@ -633,6 +677,16 @@ int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
break;
case MLX5E_ICOSQ_WQE_NOP:
break;
+#ifdef CONFIG_MLX5_EN_TLS
+ case MLX5E_ICOSQ_WQE_UMR_TLS:
+ break;
+ case MLX5E_ICOSQ_WQE_SET_PSV_TLS:
+ mlx5e_ktls_handle_ctx_completion(wi);
+ break;
+ case MLX5E_ICOSQ_WQE_GET_PSV_TLS:
+ mlx5e_ktls_handle_get_psv_completion(wi, sq);
+ break;
+#endif
default:
netdev_WARN_ONCE(cq->channel->netdev,
"Bad WQE type in ICOSQ WQE info: 0x%x\n",
@@ -648,7 +702,7 @@ int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
return i;
}
-bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq)
+INDIRECT_CALLABLE_SCOPE bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq)
{
struct mlx5e_icosq *sq = &rq->channel->icosq;
struct mlx5_wq_ll *wq = &rq->mpwqe.wq;
@@ -936,9 +990,14 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
goto csum_unnecessary;
if (likely(is_last_ethertype_ip(skb, &network_depth, &proto))) {
- if (unlikely(get_ip_proto(skb, network_depth, proto) == IPPROTO_SCTP))
+ u8 ipproto = get_ip_proto(skb, network_depth, proto);
+
+ if (unlikely(ipproto == IPPROTO_SCTP))
goto csum_unnecessary;
+ if (unlikely(mlx5_ipsec_is_rx_flow(cqe)))
+ goto csum_none;
+
stats->csum_complete++;
skb->ip_summed = CHECKSUM_COMPLETE;
skb->csum = csum_unfold((__force __sum16)cqe->check_sum);
@@ -982,9 +1041,10 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
skb->mac_len = ETH_HLEN;
-#ifdef CONFIG_MLX5_EN_TLS
- mlx5e_tls_handle_rx_skb(netdev, skb, &cqe_bcnt);
-#endif
+ mlx5e_tls_handle_rx_skb(rq, skb, cqe, &cqe_bcnt);
+
+ if (unlikely(mlx5_ipsec_is_rx_flow(cqe)))
+ mlx5e_ipsec_offload_handle_rx_skb(netdev, skb, cqe);
if (lro_num_seg > 1) {
mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);
@@ -1063,7 +1123,7 @@ static void mlx5e_fill_xdp_buff(struct mlx5e_rq *rq, void *va, u16 headroom,
xdp->frame_sz = rq->buff.frame0_sz;
}
-struct sk_buff *
+static struct sk_buff *
mlx5e_skb_from_cqe_linear(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
struct mlx5e_wqe_frag_info *wi, u32 cqe_bcnt)
{
@@ -1103,7 +1163,7 @@ mlx5e_skb_from_cqe_linear(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
return skb;
}
-struct sk_buff *
+static struct sk_buff *
mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
struct mlx5e_wqe_frag_info *wi, u32 cqe_bcnt)
{
@@ -1152,11 +1212,13 @@ static void trigger_report(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
struct mlx5_err_cqe *err_cqe = (struct mlx5_err_cqe *)cqe;
if (cqe_syndrome_needs_recover(err_cqe->syndrome) &&
- !test_and_set_bit(MLX5E_RQ_STATE_RECOVERING, &rq->state))
+ !test_and_set_bit(MLX5E_RQ_STATE_RECOVERING, &rq->state)) {
+ mlx5e_dump_error_cqe(&rq->cq, rq->rqn, err_cqe);
queue_work(rq->channel->priv->wq, &rq->recover_work);
+ }
}
-void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
+static void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
{
struct mlx5_wq_cyc *wq = &rq->wqe.wq;
struct mlx5e_wqe_frag_info *wi;
@@ -1199,7 +1261,7 @@ wq_cyc_pop:
}
#ifdef CONFIG_MLX5_ESWITCH
-void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
+static void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
{
struct net_device *netdev = rq->netdev;
struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -1221,7 +1283,10 @@ void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
goto free_wqe;
}
- skb = rq->wqe.skb_from_cqe(rq, cqe, wi, cqe_bcnt);
+ skb = INDIRECT_CALL_2(rq->wqe.skb_from_cqe,
+ mlx5e_skb_from_cqe_linear,
+ mlx5e_skb_from_cqe_nonlinear,
+ rq, cqe, wi, cqe_bcnt);
if (!skb) {
/* probably for XDP */
if (__test_and_clear_bit(MLX5E_RQ_FLAG_XDP_XMIT, rq->flags)) {
@@ -1251,8 +1316,7 @@ wq_cyc_pop:
mlx5_wq_cyc_pop(wq);
}
-void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq,
- struct mlx5_cqe64 *cqe)
+static void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
{
u16 cstrides = mpwrq_get_cqe_consumed_strides(cqe);
u16 wqe_id = be16_to_cpu(cqe->wqe_id);
@@ -1310,9 +1374,14 @@ mpwrq_cqe_out:
mlx5e_free_rx_mpwqe(rq, wi, true);
mlx5_wq_ll_pop(wq, cqe->wqe_id, &wqe->next.next_wqe_index);
}
+
+const struct mlx5e_rx_handlers mlx5e_rx_handlers_rep = {
+ .handle_rx_cqe = mlx5e_handle_rx_cqe_rep,
+ .handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq_rep,
+};
#endif
-struct sk_buff *
+static struct sk_buff *
mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
u16 cqe_bcnt, u32 head_offset, u32 page_idx)
{
@@ -1358,7 +1427,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
return skb;
}
-struct sk_buff *
+static struct sk_buff *
mlx5e_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
u16 cqe_bcnt, u32 head_offset, u32 page_idx)
{
@@ -1408,7 +1477,7 @@ mlx5e_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
return skb;
}
-void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
+static void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
{
u16 cstrides = mpwrq_get_cqe_consumed_strides(cqe);
u16 wqe_id = be16_to_cpu(cqe->wqe_id);
@@ -1604,7 +1673,7 @@ static inline void mlx5i_complete_rx_cqe(struct mlx5e_rq *rq,
stats->bytes += cqe_bcnt;
}
-void mlx5i_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
+static void mlx5i_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
{
struct mlx5_wq_cyc *wq = &rq->wqe.wq;
struct mlx5e_wqe_frag_info *wi;
@@ -1640,11 +1709,15 @@ wq_free_wqe:
mlx5_wq_cyc_pop(wq);
}
+const struct mlx5e_rx_handlers mlx5i_rx_handlers = {
+ .handle_rx_cqe = mlx5i_handle_rx_cqe,
+ .handle_rx_cqe_mpwqe = NULL, /* Not supported */
+};
#endif /* CONFIG_MLX5_CORE_IPOIB */
#ifdef CONFIG_MLX5_EN_IPSEC
-void mlx5e_ipsec_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
+static void mlx5e_ipsec_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
{
struct mlx5_wq_cyc *wq = &rq->wqe.wq;
struct mlx5e_wqe_frag_info *wi;
@@ -1681,3 +1754,55 @@ wq_free_wqe:
}
#endif /* CONFIG_MLX5_EN_IPSEC */
+
+int mlx5e_rq_set_handlers(struct mlx5e_rq *rq, struct mlx5e_params *params, bool xsk)
+{
+ struct mlx5_core_dev *mdev = rq->mdev;
+ struct mlx5e_channel *c = rq->channel;
+
+ switch (rq->wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ rq->mpwqe.skb_from_cqe_mpwrq = xsk ?
+ mlx5e_xsk_skb_from_cqe_mpwrq_linear :
+ mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL) ?
+ mlx5e_skb_from_cqe_mpwrq_linear :
+ mlx5e_skb_from_cqe_mpwrq_nonlinear;
+ rq->post_wqes = mlx5e_post_rx_mpwqes;
+ rq->dealloc_wqe = mlx5e_dealloc_rx_mpwqe;
+
+ rq->handle_rx_cqe = c->priv->profile->rx_handlers->handle_rx_cqe_mpwqe;
+#ifdef CONFIG_MLX5_EN_IPSEC
+ if (MLX5_IPSEC_DEV(mdev)) {
+ netdev_err(c->netdev, "MPWQE RQ with IPSec offload not supported\n");
+ return -EINVAL;
+ }
+#endif
+ if (!rq->handle_rx_cqe) {
+ netdev_err(c->netdev, "RX handler of MPWQE RQ is not set\n");
+ return -EINVAL;
+ }
+ break;
+ default: /* MLX5_WQ_TYPE_CYCLIC */
+ rq->wqe.skb_from_cqe = xsk ?
+ mlx5e_xsk_skb_from_cqe_linear :
+ mlx5e_rx_is_linear_skb(params, NULL) ?
+ mlx5e_skb_from_cqe_linear :
+ mlx5e_skb_from_cqe_nonlinear;
+ rq->post_wqes = mlx5e_post_rx_wqes;
+ rq->dealloc_wqe = mlx5e_dealloc_rx_wqe;
+
+#ifdef CONFIG_MLX5_EN_IPSEC
+ if ((mlx5_fpga_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_DEVICE) &&
+ c->priv->ipsec)
+ rq->handle_rx_cqe = mlx5e_ipsec_handle_rx_cqe;
+ else
+#endif
+ rq->handle_rx_cqe = c->priv->profile->rx_handlers->handle_rx_cqe;
+ if (!rq->handle_rx_cqe) {
+ netdev_err(c->netdev, "RX handler of RQ is not set\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
index f009fe09e99b..e3b2f59408e6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
@@ -163,6 +163,19 @@ static const struct counter_desc sw_stats_desc[] = {
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_congst_umr) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_arfs_err) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_recover) },
+#ifdef CONFIG_MLX5_EN_TLS
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_decrypted_packets) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_decrypted_bytes) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_ctx) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_del) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_resync_req_pkt) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_resync_req_start) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_resync_req_end) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_resync_req_skip) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_resync_res_ok) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_resync_res_skip) },
+ { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_tls_err) },
+#endif
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_events) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_poll) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_arm) },
@@ -275,6 +288,19 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw)
s->rx_congst_umr += rq_stats->congst_umr;
s->rx_arfs_err += rq_stats->arfs_err;
s->rx_recover += rq_stats->recover;
+#ifdef CONFIG_MLX5_EN_TLS
+ s->rx_tls_decrypted_packets += rq_stats->tls_decrypted_packets;
+ s->rx_tls_decrypted_bytes += rq_stats->tls_decrypted_bytes;
+ s->rx_tls_ctx += rq_stats->tls_ctx;
+ s->rx_tls_del += rq_stats->tls_del;
+ s->rx_tls_resync_req_pkt += rq_stats->tls_resync_req_pkt;
+ s->rx_tls_resync_req_start += rq_stats->tls_resync_req_start;
+ s->rx_tls_resync_req_end += rq_stats->tls_resync_req_end;
+ s->rx_tls_resync_req_skip += rq_stats->tls_resync_req_skip;
+ s->rx_tls_resync_res_ok += rq_stats->tls_resync_res_ok;
+ s->rx_tls_resync_res_skip += rq_stats->tls_resync_res_skip;
+ s->rx_tls_err += rq_stats->tls_err;
+#endif
s->ch_events += ch_stats->events;
s->ch_poll += ch_stats->poll;
s->ch_arm += ch_stats->arm;
@@ -1475,6 +1501,19 @@ static const struct counter_desc rq_stats_desc[] = {
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, congst_umr) },
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, arfs_err) },
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, recover) },
+#ifdef CONFIG_MLX5_EN_TLS
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_decrypted_packets) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_decrypted_bytes) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_ctx) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_del) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_resync_req_pkt) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_resync_req_start) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_resync_req_end) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_resync_req_skip) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_resync_res_ok) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_resync_res_skip) },
+ { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, tls_err) },
+#endif
};
static const struct counter_desc sq_stats_desc[] = {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
index 2b83ba990714..2e1cca1923b9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
@@ -186,6 +186,18 @@ struct mlx5e_sw_stats {
u64 tx_tls_skip_no_sync_data;
u64 tx_tls_drop_no_sync_data;
u64 tx_tls_drop_bypass_req;
+
+ u64 rx_tls_decrypted_packets;
+ u64 rx_tls_decrypted_bytes;
+ u64 rx_tls_ctx;
+ u64 rx_tls_del;
+ u64 rx_tls_resync_req_pkt;
+ u64 rx_tls_resync_req_start;
+ u64 rx_tls_resync_req_end;
+ u64 rx_tls_resync_req_skip;
+ u64 rx_tls_resync_res_ok;
+ u64 rx_tls_resync_res_skip;
+ u64 rx_tls_err;
#endif
u64 rx_xsk_packets;
@@ -305,6 +317,19 @@ struct mlx5e_rq_stats {
u64 congst_umr;
u64 arfs_err;
u64 recover;
+#ifdef CONFIG_MLX5_EN_TLS
+ u64 tls_decrypted_packets;
+ u64 tls_decrypted_bytes;
+ u64 tls_ctx;
+ u64 tls_del;
+ u64 tls_resync_req_pkt;
+ u64 tls_resync_req_start;
+ u64 tls_resync_req_end;
+ u64 tls_resync_req_skip;
+ u64 tls_resync_res_ok;
+ u64 tls_resync_res_skip;
+ u64 tls_err;
+#endif
};
struct mlx5e_sq_stats {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index fcedb5bdca9e..fd53d101d8fd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -63,6 +63,7 @@
#include "en/tc_tun.h"
#include "en/mapping.h"
#include "en/tc_ct.h"
+#include "en/mod_hdr.h"
#include "lib/devcom.h"
#include "lib/geneve.h"
#include "diag/en_tc_tracepoint.h"
@@ -140,8 +141,7 @@ struct mlx5e_tc_flow {
*/
struct encap_flow_item encaps[MLX5_MAX_FLOW_FWD_VPORTS];
struct mlx5e_tc_flow *peer_flow;
- struct mlx5e_mod_hdr_entry *mh; /* attached mod header instance */
- struct list_head mod_hdr; /* flows sharing the same mod hdr ID */
+ struct mlx5e_mod_hdr_handle *mh; /* attached mod header instance */
struct mlx5e_hairpin_entry *hpe; /* attached hairpin instance */
struct list_head hairpin; /* flows sharing the same hairpin */
struct list_head peer; /* flows with peer flow */
@@ -180,17 +180,17 @@ struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[] = {
},
[TUNNEL_TO_REG] = {
.mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_1,
- .moffset = 3,
- .mlen = 1,
+ .moffset = 1,
+ .mlen = 3,
.soffset = MLX5_BYTE_OFF(fte_match_param,
misc_parameters_2.metadata_reg_c_1),
},
[ZONE_TO_REG] = zone_to_reg_ct,
+ [ZONE_RESTORE_TO_REG] = zone_restore_to_reg_ct,
[CTSTATE_TO_REG] = ctstate_to_reg_ct,
[MARK_TO_REG] = mark_to_reg_ct,
[LABELS_TO_REG] = labels_to_reg_ct,
[FTEID_TO_REG] = fteid_to_reg_ct,
- [TUPLEID_TO_REG] = tupleid_to_reg_ct,
};
static void mlx5e_put_flow_tunnel_id(struct mlx5e_tc_flow *flow);
@@ -219,6 +219,28 @@ mlx5e_tc_match_to_reg_match(struct mlx5_flow_spec *spec,
spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_2;
}
+void
+mlx5e_tc_match_to_reg_get_match(struct mlx5_flow_spec *spec,
+ enum mlx5e_tc_attr_to_reg type,
+ u32 *data,
+ u32 *mask)
+{
+ int soffset = mlx5e_tc_attr_to_reg_mappings[type].soffset;
+ int match_len = mlx5e_tc_attr_to_reg_mappings[type].mlen;
+ void *headers_c = spec->match_criteria;
+ void *headers_v = spec->match_value;
+ void *fmask, *fval;
+
+ fmask = headers_c + soffset;
+ fval = headers_v + soffset;
+
+ memcpy(mask, fmask, match_len);
+ memcpy(data, fval, match_len);
+
+ *mask = be32_to_cpu((__force __be32)(*mask << (32 - (match_len * 8))));
+ *data = be32_to_cpu((__force __be32)(*data << (32 - (match_len * 8))));
+}
+
int
mlx5e_tc_match_to_reg_set(struct mlx5_core_dev *mdev,
struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts,
@@ -287,29 +309,6 @@ struct mlx5e_hairpin_entry {
struct completion res_ready;
};
-struct mod_hdr_key {
- int num_actions;
- void *actions;
-};
-
-struct mlx5e_mod_hdr_entry {
- /* a node of a hash table which keeps all the mod_hdr entries */
- struct hlist_node mod_hdr_hlist;
-
- /* protects flows list */
- spinlock_t flows_lock;
- /* flows sharing the same mod_hdr entry */
- struct list_head flows;
-
- struct mod_hdr_key key;
-
- struct mlx5_modify_hdr *modify_hdr;
-
- refcount_t refcnt;
- struct completion res_ready;
- int compl_result;
-};
-
static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow);
@@ -386,148 +385,43 @@ static bool mlx5e_is_offloaded_flow(struct mlx5e_tc_flow *flow)
return flow_flag_test(flow, OFFLOADED);
}
-static inline u32 hash_mod_hdr_info(struct mod_hdr_key *key)
-{
- return jhash(key->actions,
- key->num_actions * MLX5_MH_ACT_SZ, 0);
-}
-
-static inline int cmp_mod_hdr_info(struct mod_hdr_key *a,
- struct mod_hdr_key *b)
+static int get_flow_name_space(struct mlx5e_tc_flow *flow)
{
- if (a->num_actions != b->num_actions)
- return 1;
-
- return memcmp(a->actions, b->actions, a->num_actions * MLX5_MH_ACT_SZ);
+ return mlx5e_is_eswitch_flow(flow) ?
+ MLX5_FLOW_NAMESPACE_FDB : MLX5_FLOW_NAMESPACE_KERNEL;
}
static struct mod_hdr_tbl *
-get_mod_hdr_table(struct mlx5e_priv *priv, int namespace)
+get_mod_hdr_table(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow)
{
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
- return namespace == MLX5_FLOW_NAMESPACE_FDB ? &esw->offloads.mod_hdr :
+ return get_flow_name_space(flow) == MLX5_FLOW_NAMESPACE_FDB ?
+ &esw->offloads.mod_hdr :
&priv->fs.tc.mod_hdr;
}
-static struct mlx5e_mod_hdr_entry *
-mlx5e_mod_hdr_get(struct mod_hdr_tbl *tbl, struct mod_hdr_key *key, u32 hash_key)
-{
- struct mlx5e_mod_hdr_entry *mh, *found = NULL;
-
- hash_for_each_possible(tbl->hlist, mh, mod_hdr_hlist, hash_key) {
- if (!cmp_mod_hdr_info(&mh->key, key)) {
- refcount_inc(&mh->refcnt);
- found = mh;
- break;
- }
- }
-
- return found;
-}
-
-static void mlx5e_mod_hdr_put(struct mlx5e_priv *priv,
- struct mlx5e_mod_hdr_entry *mh,
- int namespace)
-{
- struct mod_hdr_tbl *tbl = get_mod_hdr_table(priv, namespace);
-
- if (!refcount_dec_and_mutex_lock(&mh->refcnt, &tbl->lock))
- return;
- hash_del(&mh->mod_hdr_hlist);
- mutex_unlock(&tbl->lock);
-
- WARN_ON(!list_empty(&mh->flows));
- if (mh->compl_result > 0)
- mlx5_modify_header_dealloc(priv->mdev, mh->modify_hdr);
-
- kfree(mh);
-}
-
-static int get_flow_name_space(struct mlx5e_tc_flow *flow)
-{
- return mlx5e_is_eswitch_flow(flow) ?
- MLX5_FLOW_NAMESPACE_FDB : MLX5_FLOW_NAMESPACE_KERNEL;
-}
static int mlx5e_attach_mod_hdr(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow,
struct mlx5e_tc_flow_parse_attr *parse_attr)
{
- int num_actions, actions_size, namespace, err;
- struct mlx5e_mod_hdr_entry *mh;
- struct mod_hdr_tbl *tbl;
- struct mod_hdr_key key;
- u32 hash_key;
-
- num_actions = parse_attr->mod_hdr_acts.num_actions;
- actions_size = MLX5_MH_ACT_SZ * num_actions;
-
- key.actions = parse_attr->mod_hdr_acts.actions;
- key.num_actions = num_actions;
-
- hash_key = hash_mod_hdr_info(&key);
-
- namespace = get_flow_name_space(flow);
- tbl = get_mod_hdr_table(priv, namespace);
-
- mutex_lock(&tbl->lock);
- mh = mlx5e_mod_hdr_get(tbl, &key, hash_key);
- if (mh) {
- mutex_unlock(&tbl->lock);
- wait_for_completion(&mh->res_ready);
-
- if (mh->compl_result < 0) {
- err = -EREMOTEIO;
- goto attach_header_err;
- }
- goto attach_flow;
- }
-
- mh = kzalloc(sizeof(*mh) + actions_size, GFP_KERNEL);
- if (!mh) {
- mutex_unlock(&tbl->lock);
- return -ENOMEM;
- }
-
- mh->key.actions = (void *)mh + sizeof(*mh);
- memcpy(mh->key.actions, key.actions, actions_size);
- mh->key.num_actions = num_actions;
- spin_lock_init(&mh->flows_lock);
- INIT_LIST_HEAD(&mh->flows);
- refcount_set(&mh->refcnt, 1);
- init_completion(&mh->res_ready);
-
- hash_add(tbl->hlist, &mh->mod_hdr_hlist, hash_key);
- mutex_unlock(&tbl->lock);
+ struct mlx5_modify_hdr *modify_hdr;
+ struct mlx5e_mod_hdr_handle *mh;
- mh->modify_hdr = mlx5_modify_header_alloc(priv->mdev, namespace,
- mh->key.num_actions,
- mh->key.actions);
- if (IS_ERR(mh->modify_hdr)) {
- err = PTR_ERR(mh->modify_hdr);
- mh->compl_result = err;
- goto alloc_header_err;
- }
- mh->compl_result = 1;
- complete_all(&mh->res_ready);
+ mh = mlx5e_mod_hdr_attach(priv->mdev, get_mod_hdr_table(priv, flow),
+ get_flow_name_space(flow),
+ &parse_attr->mod_hdr_acts);
+ if (IS_ERR(mh))
+ return PTR_ERR(mh);
-attach_flow:
- flow->mh = mh;
- spin_lock(&mh->flows_lock);
- list_add(&flow->mod_hdr, &mh->flows);
- spin_unlock(&mh->flows_lock);
+ modify_hdr = mlx5e_mod_hdr_get(mh);
if (mlx5e_is_eswitch_flow(flow))
- flow->esw_attr->modify_hdr = mh->modify_hdr;
+ flow->esw_attr->modify_hdr = modify_hdr;
else
- flow->nic_attr->modify_hdr = mh->modify_hdr;
+ flow->nic_attr->modify_hdr = modify_hdr;
+ flow->mh = mh;
return 0;
-
-alloc_header_err:
- complete_all(&mh->res_ready);
-attach_header_err:
- mlx5e_mod_hdr_put(priv, mh, namespace);
- return err;
}
static void mlx5e_detach_mod_hdr(struct mlx5e_priv *priv,
@@ -537,11 +431,8 @@ static void mlx5e_detach_mod_hdr(struct mlx5e_priv *priv,
if (!flow->mh)
return;
- spin_lock(&flow->mh->flows_lock);
- list_del(&flow->mod_hdr);
- spin_unlock(&flow->mh->flows_lock);
-
- mlx5e_mod_hdr_put(priv, flow->mh, get_flow_name_space(flow));
+ mlx5e_mod_hdr_detach(priv->mdev, get_mod_hdr_table(priv, flow),
+ flow->mh);
flow->mh = NULL;
}
@@ -3087,6 +2978,7 @@ struct ipv6_hoplimit_word {
static int is_action_keys_supported(const struct flow_action_entry *act,
bool ct_flow, bool *modify_ip_header,
+ bool *modify_tuple,
struct netlink_ext_ack *extack)
{
u32 mask, offset;
@@ -3109,7 +3001,10 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
*modify_ip_header = true;
}
- if (ct_flow && offset >= offsetof(struct iphdr, saddr)) {
+ if (offset >= offsetof(struct iphdr, saddr))
+ *modify_tuple = true;
+
+ if (ct_flow && *modify_tuple) {
NL_SET_ERR_MSG_MOD(extack,
"can't offload re-write of ipv4 address with action ct");
return -EOPNOTSUPP;
@@ -3124,28 +3019,36 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
*modify_ip_header = true;
}
- if (ct_flow && offset >= offsetof(struct ipv6hdr, saddr)) {
+ if (ct_flow && offset >= offsetof(struct ipv6hdr, saddr))
+ *modify_tuple = true;
+
+ if (ct_flow && *modify_tuple) {
NL_SET_ERR_MSG_MOD(extack,
"can't offload re-write of ipv6 address with action ct");
return -EOPNOTSUPP;
}
- } else if (ct_flow && (htype == FLOW_ACT_MANGLE_HDR_TYPE_TCP ||
- htype == FLOW_ACT_MANGLE_HDR_TYPE_UDP)) {
- NL_SET_ERR_MSG_MOD(extack,
- "can't offload re-write of transport header ports with action ct");
- return -EOPNOTSUPP;
+ } else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_TCP ||
+ htype == FLOW_ACT_MANGLE_HDR_TYPE_UDP) {
+ *modify_tuple = true;
+ if (ct_flow) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "can't offload re-write of transport header ports with action ct");
+ return -EOPNOTSUPP;
+ }
}
return 0;
}
-static bool modify_header_match_supported(struct mlx5_flow_spec *spec,
+static bool modify_header_match_supported(struct mlx5e_priv *priv,
+ struct mlx5_flow_spec *spec,
struct flow_action *flow_action,
u32 actions, bool ct_flow,
+ bool ct_clear,
struct netlink_ext_ack *extack)
{
const struct flow_action_entry *act;
- bool modify_ip_header;
+ bool modify_ip_header, modify_tuple;
void *headers_c;
void *headers_v;
u16 ethertype;
@@ -3162,23 +3065,39 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec,
goto out_ok;
modify_ip_header = false;
+ modify_tuple = false;
flow_action_for_each(i, act, flow_action) {
if (act->id != FLOW_ACTION_MANGLE &&
act->id != FLOW_ACTION_ADD)
continue;
err = is_action_keys_supported(act, ct_flow,
- &modify_ip_header, extack);
+ &modify_ip_header,
+ &modify_tuple, extack);
if (err)
return err;
}
+ /* Add ct_state=-trk match so it will be offloaded for non ct flows
+ * (or after clear action), as otherwise, since the tuple is changed,
+ * we can't restore ct state
+ */
+ if (!ct_clear && modify_tuple &&
+ mlx5_tc_ct_add_no_trk_match(priv, spec)) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "can't offload tuple modify header with ct matches");
+ netdev_info(priv->netdev,
+ "can't offload tuple modify header with ct matches");
+ return false;
+ }
+
ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol);
if (modify_ip_header && ip_proto != IPPROTO_TCP &&
ip_proto != IPPROTO_UDP && ip_proto != IPPROTO_ICMP) {
NL_SET_ERR_MSG_MOD(extack,
"can't offload re-write of non TCP/UDP");
- pr_info("can't offload re-write of ip proto %d\n", ip_proto);
+ netdev_info(priv->netdev, "can't offload re-write of ip proto %d\n",
+ ip_proto);
return false;
}
@@ -3192,13 +3111,14 @@ static bool actions_match_supported(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow,
struct netlink_ext_ack *extack)
{
- bool ct_flow;
+ bool ct_flow = false, ct_clear = false;
u32 actions;
- ct_flow = flow_flag_test(flow, CT);
if (mlx5e_is_eswitch_flow(flow)) {
actions = flow->esw_attr->action;
-
+ ct_clear = flow->esw_attr->ct_attr.ct_action &
+ TCA_CT_ACT_CLEAR;
+ ct_flow = flow_flag_test(flow, CT) && !ct_clear;
if (flow->esw_attr->split_count && ct_flow) {
/* All registers used by ct are cleared when using
* split rules.
@@ -3212,9 +3132,10 @@ static bool actions_match_supported(struct mlx5e_priv *priv,
}
if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
- return modify_header_match_supported(&parse_attr->spec,
+ return modify_header_match_supported(priv, &parse_attr->spec,
flow_action, actions,
- ct_flow, extack);
+ ct_flow, ct_clear,
+ extack);
return true;
}
@@ -4409,7 +4330,6 @@ mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size,
flow->priv = priv;
for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++)
INIT_LIST_HEAD(&flow->encaps[out_index].list);
- INIT_LIST_HEAD(&flow->mod_hdr);
INIT_LIST_HEAD(&flow->hairpin);
INIT_LIST_HEAD(&flow->l3_to_l2_reformat);
refcount_set(&flow->refcnt, 1);
@@ -4481,11 +4401,13 @@ __mlx5e_add_fdb_flow(struct mlx5e_priv *priv,
if (err)
goto err_free;
- err = parse_tc_fdb_actions(priv, &rule->action, flow, extack, filter_dev);
+ /* actions validation depends on parsing the ct matches first */
+ err = mlx5_tc_ct_parse_match(priv, &parse_attr->spec, f,
+ &flow->esw_attr->ct_attr, extack);
if (err)
goto err_free;
- err = mlx5_tc_ct_parse_match(priv, &parse_attr->spec, f, extack);
+ err = parse_tc_fdb_actions(priv, &rule->action, flow, extack, filter_dev);
if (err)
goto err_free;
@@ -4833,7 +4755,7 @@ int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
no_peer_counter:
mlx5_devcom_release_peer_data(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
out:
- flow_stats_update(&f->stats, bytes, packets, lastuse,
+ flow_stats_update(&f->stats, bytes, packets, 0, lastuse,
FLOW_ACTION_HW_STATS_DELAYED);
trace_mlx5e_stats_flower(f);
errout:
@@ -4951,7 +4873,7 @@ void mlx5e_tc_stats_matchall(struct mlx5e_priv *priv,
dpkts = cur_stats.rx_packets - rpriv->prev_vf_vport_stats.rx_packets;
dbytes = cur_stats.rx_bytes - rpriv->prev_vf_vport_stats.rx_bytes;
rpriv->prev_vf_vport_stats = cur_stats;
- flow_stats_update(&ma->stats, dbytes, dpkts, jiffies,
+ flow_stats_update(&ma->stats, dbytes, dpkts, 0, jiffies,
FLOW_ACTION_HW_STATS_DELAYED);
}
@@ -5016,9 +4938,8 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
struct mlx5e_tc_table *tc = &priv->fs.tc;
int err;
+ mlx5e_mod_hdr_tbl_init(&tc->mod_hdr);
mutex_init(&tc->t_lock);
- mutex_init(&tc->mod_hdr.lock);
- hash_init(tc->mod_hdr.hlist);
mutex_init(&tc->hairpin_tbl_lock);
hash_init(tc->hairpin_tbl);
@@ -5056,7 +4977,7 @@ void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv)
&tc->netdevice_nb,
&tc->netdevice_nn);
- mutex_destroy(&tc->mod_hdr.lock);
+ mlx5e_mod_hdr_tbl_destroy(&tc->mod_hdr);
mutex_destroy(&tc->hairpin_tbl_lock);
rhashtable_destroy(&tc->ht);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
index 5c330b0cae21..437f680728fd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
@@ -40,6 +40,14 @@
#ifdef CONFIG_MLX5_ESWITCH
+int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags);
+
+struct mlx5e_tc_update_priv {
+ struct net_device *tun_dev;
+};
+
+#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
+
struct tunnel_match_key {
struct flow_dissector_key_control enc_control;
struct flow_dissector_key_keyid enc_key_id;
@@ -62,9 +70,9 @@ struct tunnel_match_enc_opts {
* Upper TUNNEL_INFO_BITS for general tunnel info.
* Lower ENC_OPTS_BITS bits for enc_opts.
*/
-#define TUNNEL_INFO_BITS 6
+#define TUNNEL_INFO_BITS 12
#define TUNNEL_INFO_BITS_MASK GENMASK(TUNNEL_INFO_BITS - 1, 0)
-#define ENC_OPTS_BITS 2
+#define ENC_OPTS_BITS 12
#define ENC_OPTS_BITS_MASK GENMASK(ENC_OPTS_BITS - 1, 0)
#define TUNNEL_ID_BITS (TUNNEL_INFO_BITS + ENC_OPTS_BITS)
#define TUNNEL_ID_MASK GENMASK(TUNNEL_ID_BITS - 1, 0)
@@ -114,8 +122,6 @@ void mlx5e_put_encap_flow_list(struct mlx5e_priv *priv, struct list_head *flow_l
struct mlx5e_neigh_hash_entry;
void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe);
-int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags);
-
void mlx5e_tc_reoffload_flows_work(struct work_struct *work);
enum mlx5e_tc_attr_to_reg {
@@ -123,10 +129,10 @@ enum mlx5e_tc_attr_to_reg {
TUNNEL_TO_REG,
CTSTATE_TO_REG,
ZONE_TO_REG,
+ ZONE_RESTORE_TO_REG,
MARK_TO_REG,
LABELS_TO_REG,
FTEID_TO_REG,
- TUPLEID_TO_REG,
};
struct mlx5e_tc_attr_to_reg_mapping {
@@ -142,16 +148,6 @@ extern struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[];
bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv,
struct net_device *out_dev);
-struct mlx5e_tc_update_priv {
- struct net_device *tun_dev;
-};
-
-struct mlx5e_tc_mod_hdr_acts {
- int num_actions;
- int max_actions;
- void *actions;
-};
-
int mlx5e_tc_match_to_reg_set(struct mlx5_core_dev *mdev,
struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts,
enum mlx5e_tc_attr_to_reg type,
@@ -162,6 +158,11 @@ void mlx5e_tc_match_to_reg_match(struct mlx5_flow_spec *spec,
u32 data,
u32 mask);
+void mlx5e_tc_match_to_reg_get_match(struct mlx5_flow_spec *spec,
+ enum mlx5e_tc_attr_to_reg type,
+ u32 *data,
+ u32 *mask);
+
int alloc_mod_hdr_actions(struct mlx5_core_dev *mdev,
int namespace,
struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
@@ -174,8 +175,6 @@ void mlx5e_tc_set_ethertype(struct mlx5_core_dev *mdev,
struct flow_match_basic *match, bool outer,
void *headers_c, void *headers_v);
-#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
-
int mlx5e_tc_nic_init(struct mlx5e_priv *priv);
void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
index 6d406063aca4..da596de3abba 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
@@ -38,7 +38,6 @@
#include "en/txrx.h"
#include "ipoib/ipoib.h"
#include "en_accel/en_accel.h"
-#include "en_accel/ktls.h"
#include "lib/clock.h"
static void mlx5e_dma_unmap_wqe_err(struct mlx5e_txqsq *sq, u8 num_dma)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
index 8480278f2ee2..de10b06bade5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
@@ -31,8 +31,8 @@
*/
#include <linux/irq.h>
-#include <linux/indirect_call_wrapper.h>
#include "en.h"
+#include "en/txrx.h"
#include "en/xdp.h"
#include "en/xsk/rx.h"
#include "en/xsk/tx.h"
@@ -149,17 +149,17 @@ int mlx5e_napi_poll(struct napi_struct *napi, int budget)
}
mlx5e_poll_ico_cq(&c->icosq.cq);
+ if (mlx5e_poll_ico_cq(&c->async_icosq.cq))
+ /* Don't clear the flag if nothing was polled to prevent
+ * queueing more WQEs and overflowing the async ICOSQ.
+ */
+ clear_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->async_icosq.state);
busy |= INDIRECT_CALL_2(rq->post_wqes,
mlx5e_post_rx_mpwqes,
mlx5e_post_rx_wqes,
rq);
if (xsk_open) {
- if (mlx5e_poll_ico_cq(&c->xskicosq.cq))
- /* Don't clear the flag if nothing was polled to prevent
- * queueing more WQEs and overflowing XSKICOSQ.
- */
- clear_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->xskicosq.state);
busy |= mlx5e_poll_xdpsq_cq(&xsksq->cq);
busy_xsk |= mlx5e_napi_xsk_post(xsksq, xskrq);
}
@@ -189,11 +189,11 @@ int mlx5e_napi_poll(struct napi_struct *napi, int budget)
mlx5e_cq_arm(&rq->cq);
mlx5e_cq_arm(&c->icosq.cq);
+ mlx5e_cq_arm(&c->async_icosq.cq);
mlx5e_cq_arm(&c->xdpsq.cq);
if (xsk_open) {
mlx5e_handle_rx_dim(xskrq);
- mlx5e_cq_arm(&c->xskicosq.cq);
mlx5e_cq_arm(&xsksq->cq);
mlx5e_cq_arm(&xskrq->cq);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 43005caff09e..6e6a9a563992 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -42,6 +42,7 @@
#include "fs_core.h"
#include "devlink.h"
#include "ecpf.h"
+#include "en/mod_hdr.h"
enum {
MLX5_ACTION_NONE = 0,
@@ -63,6 +64,29 @@ struct vport_addr {
static void esw_destroy_legacy_fdb_table(struct mlx5_eswitch *esw);
static void esw_cleanup_vepa_rules(struct mlx5_eswitch *esw);
+static int mlx5_eswitch_check(const struct mlx5_core_dev *dev)
+{
+ if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
+ return -EOPNOTSUPP;
+
+ if (!MLX5_ESWITCH_MANAGER(dev))
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+struct mlx5_eswitch *mlx5_devlink_eswitch_get(struct devlink *devlink)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+ int err;
+
+ err = mlx5_eswitch_check(dev);
+ if (err)
+ return ERR_PTR(err);
+
+ return dev->priv.eswitch;
+}
+
struct mlx5_vport *__must_check
mlx5_eswitch_get_vport(struct mlx5_eswitch *esw, u16 vport_num)
{
@@ -1127,7 +1151,7 @@ int mlx5_esw_modify_vport_rate(struct mlx5_eswitch *esw, u16 vport_num,
MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW);
}
-static void node_guid_gen_from_mac(u64 *node_guid, u8 mac[ETH_ALEN])
+static void node_guid_gen_from_mac(u64 *node_guid, const u8 *mac)
{
((u8 *)node_guid)[7] = mac[0];
((u8 *)node_guid)[6] = mac[1];
@@ -1628,7 +1652,17 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
return 0;
mutex_lock(&esw->mode_lock);
- ret = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_LEGACY, num_vfs);
+ if (esw->mode == MLX5_ESWITCH_NONE) {
+ ret = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_LEGACY, num_vfs);
+ } else {
+ enum mlx5_eswitch_vport_event vport_events;
+
+ vport_events = (esw->mode == MLX5_ESWITCH_LEGACY) ?
+ MLX5_LEGACY_SRIOV_VPORT_EVENTS : MLX5_VPORT_UC_ADDR_CHANGE;
+ ret = mlx5_eswitch_load_vf_vports(esw, num_vfs, vport_events);
+ if (!ret)
+ esw->esw_funcs.num_vfs = num_vfs;
+ }
mutex_unlock(&esw->mode_lock);
return ret;
}
@@ -1675,6 +1709,7 @@ void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf)
mutex_lock(&esw->mode_lock);
mlx5_eswitch_disable_locked(esw, clear_vf);
+ esw->esw_funcs.num_vfs = 0;
mutex_unlock(&esw->mode_lock);
}
@@ -1725,10 +1760,9 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
mutex_init(&esw->offloads.encap_tbl_lock);
hash_init(esw->offloads.encap_tbl);
- mutex_init(&esw->offloads.mod_hdr.lock);
- hash_init(esw->offloads.mod_hdr.hlist);
mutex_init(&esw->offloads.decap_tbl_lock);
hash_init(esw->offloads.decap_tbl);
+ mlx5e_mod_hdr_tbl_init(&esw->offloads.mod_hdr);
atomic64_set(&esw->offloads.num_flows, 0);
ida_init(&esw->offloads.vport_metadata_ida);
mutex_init(&esw->state_lock);
@@ -1770,7 +1804,7 @@ void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw)
mutex_destroy(&esw->mode_lock);
mutex_destroy(&esw->state_lock);
ida_destroy(&esw->offloads.vport_metadata_ida);
- mutex_destroy(&esw->offloads.mod_hdr.lock);
+ mlx5e_mod_hdr_tbl_destroy(&esw->offloads.mod_hdr);
mutex_destroy(&esw->offloads.encap_tbl_lock);
mutex_destroy(&esw->offloads.decap_tbl_lock);
kfree(esw->vports);
@@ -1778,46 +1812,135 @@ void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw)
}
/* Vport Administration */
-int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
- u16 vport, u8 mac[ETH_ALEN])
+static int
+mlx5_esw_set_vport_mac_locked(struct mlx5_eswitch *esw,
+ struct mlx5_vport *evport, const u8 *mac)
{
- struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
+ u16 vport_num = evport->vport;
u64 node_guid;
int err = 0;
- if (IS_ERR(evport))
- return PTR_ERR(evport);
if (is_multicast_ether_addr(mac))
return -EINVAL;
- mutex_lock(&esw->state_lock);
-
if (evport->info.spoofchk && !is_valid_ether_addr(mac))
mlx5_core_warn(esw->dev,
"Set invalid MAC while spoofchk is on, vport(%d)\n",
- vport);
+ vport_num);
- err = mlx5_modify_nic_vport_mac_address(esw->dev, vport, mac);
+ err = mlx5_modify_nic_vport_mac_address(esw->dev, vport_num, mac);
if (err) {
mlx5_core_warn(esw->dev,
"Failed to mlx5_modify_nic_vport_mac vport(%d) err=(%d)\n",
- vport, err);
- goto unlock;
+ vport_num, err);
+ return err;
}
node_guid_gen_from_mac(&node_guid, mac);
- err = mlx5_modify_nic_vport_node_guid(esw->dev, vport, node_guid);
+ err = mlx5_modify_nic_vport_node_guid(esw->dev, vport_num, node_guid);
if (err)
mlx5_core_warn(esw->dev,
"Failed to set vport %d node guid, err = %d. RDMA_CM will not function properly for this VF.\n",
- vport, err);
+ vport_num, err);
ether_addr_copy(evport->info.mac, mac);
evport->info.node_guid = node_guid;
if (evport->enabled && esw->mode == MLX5_ESWITCH_LEGACY)
err = esw_acl_ingress_lgcy_setup(esw, evport);
-unlock:
+ return err;
+}
+
+int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
+ u16 vport, const u8 *mac)
+{
+ struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
+ int err = 0;
+
+ if (IS_ERR(evport))
+ return PTR_ERR(evport);
+
+ mutex_lock(&esw->state_lock);
+ err = mlx5_esw_set_vport_mac_locked(esw, evport, mac);
+ mutex_unlock(&esw->state_lock);
+ return err;
+}
+
+static bool
+is_port_function_supported(const struct mlx5_eswitch *esw, u16 vport_num)
+{
+ return vport_num == MLX5_VPORT_PF ||
+ mlx5_eswitch_is_vf_vport(esw, vport_num);
+}
+
+int mlx5_devlink_port_function_hw_addr_get(struct devlink *devlink,
+ struct devlink_port *port,
+ u8 *hw_addr, int *hw_addr_len,
+ struct netlink_ext_ack *extack)
+{
+ struct mlx5_eswitch *esw;
+ struct mlx5_vport *vport;
+ int err = -EOPNOTSUPP;
+ u16 vport_num;
+
+ esw = mlx5_devlink_eswitch_get(devlink);
+ if (IS_ERR(esw))
+ return PTR_ERR(esw);
+
+ vport_num = mlx5_esw_devlink_port_index_to_vport_num(port->index);
+ if (!is_port_function_supported(esw, vport_num))
+ return -EOPNOTSUPP;
+
+ vport = mlx5_eswitch_get_vport(esw, vport_num);
+ if (IS_ERR(vport)) {
+ NL_SET_ERR_MSG_MOD(extack, "Invalid port");
+ return PTR_ERR(vport);
+ }
+
+ mutex_lock(&esw->state_lock);
+ if (vport->enabled) {
+ ether_addr_copy(hw_addr, vport->info.mac);
+ *hw_addr_len = ETH_ALEN;
+ err = 0;
+ } else {
+ NL_SET_ERR_MSG_MOD(extack, "Eswitch vport is disabled");
+ }
+ mutex_unlock(&esw->state_lock);
+ return err;
+}
+
+int mlx5_devlink_port_function_hw_addr_set(struct devlink *devlink,
+ struct devlink_port *port,
+ const u8 *hw_addr, int hw_addr_len,
+ struct netlink_ext_ack *extack)
+{
+ struct mlx5_eswitch *esw;
+ struct mlx5_vport *vport;
+ int err = -EOPNOTSUPP;
+ u16 vport_num;
+
+ esw = mlx5_devlink_eswitch_get(devlink);
+ if (IS_ERR(esw)) {
+ NL_SET_ERR_MSG_MOD(extack, "Eswitch doesn't support set hw_addr");
+ return PTR_ERR(esw);
+ }
+
+ vport_num = mlx5_esw_devlink_port_index_to_vport_num(port->index);
+ if (!is_port_function_supported(esw, vport_num)) {
+ NL_SET_ERR_MSG_MOD(extack, "Port doesn't support set hw_addr");
+ return -EINVAL;
+ }
+ vport = mlx5_eswitch_get_vport(esw, vport_num);
+ if (IS_ERR(vport)) {
+ NL_SET_ERR_MSG_MOD(extack, "Invalid port");
+ return PTR_ERR(vport);
+ }
+
+ mutex_lock(&esw->state_lock);
+ if (vport->enabled)
+ err = mlx5_esw_set_vport_mac_locked(esw, vport, hw_addr);
+ else
+ NL_SET_ERR_MSG_MOD(extack, "Eswitch vport is disabled");
mutex_unlock(&esw->state_lock);
return err;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 5785596f13f5..867d8120b8a5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -44,16 +44,6 @@
#include "lib/mpfs.h"
#include "en/tc_ct.h"
-#define FDB_TC_MAX_CHAIN 3
-#define FDB_FT_CHAIN (FDB_TC_MAX_CHAIN + 1)
-#define FDB_TC_SLOW_PATH_CHAIN (FDB_FT_CHAIN + 1)
-
-/* The index of the last real chain (FT) + 1 as chain zero is valid as well */
-#define FDB_NUM_CHAINS (FDB_FT_CHAIN + 1)
-
-#define FDB_TC_MAX_PRIO 16
-#define FDB_TC_LEVELS_PER_PRIO 2
-
#ifdef CONFIG_MLX5_ESWITCH
#define ESW_OFFLOADS_DEFAULT_NUM_GROUPS 15
@@ -281,7 +271,6 @@ struct mlx5_eswitch {
struct mlx5_esw_offload offloads;
int mode;
- int nvports;
u16 manager_vport;
u16 first_host_vport;
struct mlx5_esw_functions esw_funcs;
@@ -311,7 +300,7 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs);
void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw, bool clear_vf);
void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf);
int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
- u16 vport, u8 mac[ETH_ALEN]);
+ u16 vport, const u8 *mac);
int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
u16 vport, int link_state);
int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
@@ -450,6 +439,15 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink,
struct netlink_ext_ack *extack);
int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink,
enum devlink_eswitch_encap_mode *encap);
+int mlx5_devlink_port_function_hw_addr_get(struct devlink *devlink,
+ struct devlink_port *port,
+ u8 *hw_addr, int *hw_addr_len,
+ struct netlink_ext_ack *extack);
+int mlx5_devlink_port_function_hw_addr_set(struct devlink *devlink,
+ struct devlink_port *port,
+ const u8 *hw_addr, int hw_addr_len,
+ struct netlink_ext_ack *extack);
+
void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type);
int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
@@ -514,16 +512,9 @@ static inline u16 mlx5_eswitch_first_host_vport_num(struct mlx5_core_dev *dev)
MLX5_VPORT_PF : MLX5_VPORT_FIRST_VF;
}
-static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev)
+static inline bool mlx5_eswitch_is_funcs_handler(const struct mlx5_core_dev *dev)
{
- /* Ideally device should have the functions changed supported
- * capability regardless of it being ECPF or PF wherever such
- * event should be processed such as on eswitch manager device.
- * However, some ECPF based device might not have this capability
- * set. Hence OR for ECPF check to cover such device.
- */
- return MLX5_CAP_ESW(dev, esw_functions_changed) ||
- mlx5_core_is_ecpf_esw_manager(dev);
+ return mlx5_core_is_ecpf_esw_manager(dev);
}
static inline int mlx5_eswitch_uplink_idx(struct mlx5_eswitch *esw)
@@ -565,6 +556,19 @@ static inline u16 mlx5_eswitch_index_to_vport_num(struct mlx5_eswitch *esw,
return index;
}
+static inline unsigned int
+mlx5_esw_vport_to_devlink_port_index(const struct mlx5_core_dev *dev,
+ u16 vport_num)
+{
+ return (MLX5_CAP_GEN(dev, vhca_id) << 16) | vport_num;
+}
+
+static inline u16
+mlx5_esw_devlink_port_index_to_vport_num(unsigned int dl_port_index)
+{
+ return dl_port_index & 0xffff;
+}
+
/* TODO: This mlx5e_tc function shouldn't be called by eswitch */
void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw);
@@ -634,6 +638,7 @@ void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw);
for ((vport) = (nvfs); \
(vport) >= (esw)->first_host_vport; (vport)--)
+struct mlx5_eswitch *mlx5_devlink_eswitch_get(struct devlink *devlink);
struct mlx5_vport *__must_check
mlx5_eswitch_get_vport(struct mlx5_eswitch *esw, u16 vport_num);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index ed75353c56b8..d2516922d867 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -1137,7 +1137,7 @@ static void esw_set_flow_group_source_port(struct mlx5_eswitch *esw,
}
}
-static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
+static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw)
{
int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
struct mlx5_flow_table_attr ft_attr = {};
@@ -1170,7 +1170,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
goto ns_err;
}
- table_size = nvports * MAX_SQ_NVPORTS + MAX_PF_SQ +
+ table_size = esw->total_vports * MAX_SQ_NVPORTS + MAX_PF_SQ +
MLX5_ESW_MISS_FLOWS + esw->total_vports;
/* create the slow path fdb with encap set, so further table instances
@@ -1207,7 +1207,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
MLX5_SET_TO_ONES(fte_match_param, match_criteria, misc_parameters.source_sqn);
MLX5_SET_TO_ONES(fte_match_param, match_criteria, misc_parameters.source_port);
- ix = nvports * MAX_SQ_NVPORTS + MAX_PF_SQ;
+ ix = esw->total_vports * MAX_SQ_NVPORTS + MAX_PF_SQ;
MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 0);
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, ix - 1);
@@ -1275,7 +1275,6 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw, int nvports)
if (err)
goto miss_rule_err;
- esw->nvports = nvports;
kvfree(flow_group_in);
return 0;
@@ -1316,7 +1315,7 @@ static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw)
MLX5_FLOW_STEERING_MODE_DMFS);
}
-static int esw_create_offloads_table(struct mlx5_eswitch *esw, int nvports)
+static int esw_create_offloads_table(struct mlx5_eswitch *esw)
{
struct mlx5_flow_table_attr ft_attr = {};
struct mlx5_core_dev *dev = esw->dev;
@@ -1330,7 +1329,7 @@ static int esw_create_offloads_table(struct mlx5_eswitch *esw, int nvports)
return -EOPNOTSUPP;
}
- ft_attr.max_fte = nvports + MLX5_ESW_MISS_FLOWS;
+ ft_attr.max_fte = esw->total_vports + MLX5_ESW_MISS_FLOWS;
ft_attr.prio = 1;
ft_offloads = mlx5_create_flow_table(ns, &ft_attr);
@@ -1351,14 +1350,15 @@ static void esw_destroy_offloads_table(struct mlx5_eswitch *esw)
mlx5_destroy_flow_table(offloads->ft_offloads);
}
-static int esw_create_vport_rx_group(struct mlx5_eswitch *esw, int nvports)
+static int esw_create_vport_rx_group(struct mlx5_eswitch *esw)
{
int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
struct mlx5_flow_group *g;
u32 *flow_group_in;
+ int nvports;
int err = 0;
- nvports = nvports + MLX5_ESW_MISS_FLOWS;
+ nvports = esw->total_vports + MLX5_ESW_MISS_FLOWS;
flow_group_in = kvzalloc(inlen, GFP_KERNEL);
if (!flow_group_in)
return -ENOMEM;
@@ -1583,13 +1583,6 @@ static int esw_offloads_start(struct mlx5_eswitch *esw,
{
int err, err1;
- if (esw->mode != MLX5_ESWITCH_LEGACY &&
- !mlx5_core_is_ecpf_esw_manager(esw->dev)) {
- NL_SET_ERR_MSG_MOD(extack,
- "Can't set offloads mode, SRIOV legacy not enabled");
- return -EINVAL;
- }
-
mlx5_eswitch_disable_locked(esw, false);
err = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_OFFLOADS,
esw->dev->priv.sriov.num_vfs);
@@ -1998,15 +1991,8 @@ static void esw_destroy_uplink_offloads_acl_tables(struct mlx5_eswitch *esw)
static int esw_offloads_steering_init(struct mlx5_eswitch *esw)
{
- int num_vfs = esw->esw_funcs.num_vfs;
- int total_vports;
int err;
- if (mlx5_core_is_ecpf_esw_manager(esw->dev))
- total_vports = esw->total_vports;
- else
- total_vports = num_vfs + MLX5_SPECIAL_VPORTS(esw->dev);
-
memset(&esw->fdb_table.offloads, 0, sizeof(struct offloads_fdb));
mutex_init(&esw->fdb_table.offloads.vports.lock);
hash_init(esw->fdb_table.offloads.vports.table);
@@ -2015,7 +2001,7 @@ static int esw_offloads_steering_init(struct mlx5_eswitch *esw)
if (err)
goto create_acl_err;
- err = esw_create_offloads_table(esw, total_vports);
+ err = esw_create_offloads_table(esw);
if (err)
goto create_offloads_err;
@@ -2023,11 +2009,11 @@ static int esw_offloads_steering_init(struct mlx5_eswitch *esw)
if (err)
goto create_restore_err;
- err = esw_create_offloads_fdb_tables(esw, total_vports);
+ err = esw_create_offloads_fdb_tables(esw);
if (err)
goto create_fdb_err;
- err = esw_create_vport_rx_group(esw, total_vports);
+ err = esw_create_vport_rx_group(esw);
if (err)
goto create_fg_err;
@@ -2284,17 +2270,6 @@ static int esw_inline_mode_to_devlink(u8 mlx5_mode, u8 *mode)
return 0;
}
-static int mlx5_eswitch_check(const struct mlx5_core_dev *dev)
-{
- if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
- return -EOPNOTSUPP;
-
- if(!MLX5_ESWITCH_MANAGER(dev))
- return -EPERM;
-
- return 0;
-}
-
static int eswitch_devlink_esw_mode_check(const struct mlx5_eswitch *esw)
{
/* devlink commands in NONE eswitch mode are currently supported only
@@ -2307,25 +2282,19 @@ static int eswitch_devlink_esw_mode_check(const struct mlx5_eswitch *esw)
int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
struct netlink_ext_ack *extack)
{
- struct mlx5_core_dev *dev = devlink_priv(devlink);
- struct mlx5_eswitch *esw = dev->priv.eswitch;
u16 cur_mlx5_mode, mlx5_mode = 0;
- int err;
+ struct mlx5_eswitch *esw;
+ int err = 0;
- err = mlx5_eswitch_check(dev);
- if (err)
- return err;
+ esw = mlx5_devlink_eswitch_get(devlink);
+ if (IS_ERR(esw))
+ return PTR_ERR(esw);
if (esw_mode_from_devlink(mode, &mlx5_mode))
return -EINVAL;
mutex_lock(&esw->mode_lock);
- err = eswitch_devlink_esw_mode_check(esw);
- if (err)
- goto unlock;
-
cur_mlx5_mode = esw->mode;
-
if (cur_mlx5_mode == mlx5_mode)
goto unlock;
@@ -2343,16 +2312,15 @@ unlock:
int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
{
- struct mlx5_core_dev *dev = devlink_priv(devlink);
- struct mlx5_eswitch *esw = dev->priv.eswitch;
+ struct mlx5_eswitch *esw;
int err;
- err = mlx5_eswitch_check(dev);
- if (err)
- return err;
+ esw = mlx5_devlink_eswitch_get(devlink);
+ if (IS_ERR(esw))
+ return PTR_ERR(esw);
mutex_lock(&esw->mode_lock);
- err = eswitch_devlink_esw_mode_check(dev->priv.eswitch);
+ err = eswitch_devlink_esw_mode_check(esw);
if (err)
goto unlock;
@@ -2366,13 +2334,13 @@ int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode,
struct netlink_ext_ack *extack)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
- struct mlx5_eswitch *esw = dev->priv.eswitch;
int err, vport, num_vport;
+ struct mlx5_eswitch *esw;
u8 mlx5_mode;
- err = mlx5_eswitch_check(dev);
- if (err)
- return err;
+ esw = mlx5_devlink_eswitch_get(devlink);
+ if (IS_ERR(esw))
+ return PTR_ERR(esw);
mutex_lock(&esw->mode_lock);
err = eswitch_devlink_esw_mode_check(esw);
@@ -2383,7 +2351,7 @@ int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode,
case MLX5_CAP_INLINE_MODE_NOT_REQUIRED:
if (mode == DEVLINK_ESWITCH_INLINE_MODE_NONE)
goto out;
- /* fall through */
+ fallthrough;
case MLX5_CAP_INLINE_MODE_L2:
NL_SET_ERR_MSG_MOD(extack, "Inline mode can't be set");
err = -EOPNOTSUPP;
@@ -2429,13 +2397,12 @@ out:
int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode)
{
- struct mlx5_core_dev *dev = devlink_priv(devlink);
- struct mlx5_eswitch *esw = dev->priv.eswitch;
+ struct mlx5_eswitch *esw;
int err;
- err = mlx5_eswitch_check(dev);
- if (err)
- return err;
+ esw = mlx5_devlink_eswitch_get(devlink);
+ if (IS_ERR(esw))
+ return PTR_ERR(esw);
mutex_lock(&esw->mode_lock);
err = eswitch_devlink_esw_mode_check(esw);
@@ -2453,12 +2420,12 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink,
struct netlink_ext_ack *extack)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
- struct mlx5_eswitch *esw = dev->priv.eswitch;
+ struct mlx5_eswitch *esw;
int err;
- err = mlx5_eswitch_check(dev);
- if (err)
- return err;
+ esw = mlx5_devlink_eswitch_get(devlink);
+ if (IS_ERR(esw))
+ return PTR_ERR(esw);
mutex_lock(&esw->mode_lock);
err = eswitch_devlink_esw_mode_check(esw);
@@ -2496,13 +2463,13 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink,
esw->offloads.encap = encap;
- err = esw_create_offloads_fdb_tables(esw, esw->nvports);
+ err = esw_create_offloads_fdb_tables(esw);
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"Failed re-creating fast FDB table");
esw->offloads.encap = !encap;
- (void)esw_create_offloads_fdb_tables(esw, esw->nvports);
+ (void)esw_create_offloads_fdb_tables(esw);
}
unlock:
@@ -2513,13 +2480,13 @@ unlock:
int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink,
enum devlink_eswitch_encap_mode *encap)
{
- struct mlx5_core_dev *dev = devlink_priv(devlink);
- struct mlx5_eswitch *esw = dev->priv.eswitch;
+ struct mlx5_eswitch *esw;
int err;
- err = mlx5_eswitch_check(dev);
- if (err)
- return err;
+ esw = mlx5_devlink_eswitch_get(devlink);
+ if (IS_ERR(esw))
+ return PTR_ERR(esw);
+
mutex_lock(&esw->mode_lock);
err = eswitch_devlink_esw_mode_check(esw);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
index 182d3ac3e73f..831d2c39e153 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c
@@ -339,14 +339,14 @@ static void mlx5_fpga_conn_handle_cqe(struct mlx5_fpga_conn *conn,
switch (opcode) {
case MLX5_CQE_REQ_ERR:
status = ((struct mlx5_err_cqe *)cqe)->syndrome;
- /* Fall through */
+ fallthrough;
case MLX5_CQE_REQ:
mlx5_fpga_conn_sq_cqe(conn, cqe, status);
break;
case MLX5_CQE_RESP_ERR:
status = ((struct mlx5_err_cqe *)cqe)->syndrome;
- /* Fall through */
+ fallthrough;
case MLX5_CQE_RESP_SEND:
mlx5_fpga_conn_rq_cqe(conn, cqe, status);
break;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
index b463787d6ca1..cc67366495b0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
@@ -359,7 +359,7 @@ u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev)
return ret;
}
-unsigned int mlx5_fpga_ipsec_counters_count(struct mlx5_core_dev *mdev)
+static unsigned int mlx5_fpga_ipsec_counters_count(struct mlx5_core_dev *mdev)
{
struct mlx5_fpga_device *fdev = mdev->fpga;
@@ -370,8 +370,8 @@ unsigned int mlx5_fpga_ipsec_counters_count(struct mlx5_core_dev *mdev)
number_of_ipsec_counters);
}
-int mlx5_fpga_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,
- unsigned int counters_count)
+static int mlx5_fpga_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,
+ unsigned int counters_count)
{
struct mlx5_fpga_device *fdev = mdev->fpga;
unsigned int i;
@@ -665,12 +665,10 @@ static bool mlx5_is_fpga_egress_ipsec_rule(struct mlx5_core_dev *dev,
return true;
}
-void *mlx5_fpga_ipsec_create_sa_ctx(struct mlx5_core_dev *mdev,
- struct mlx5_accel_esp_xfrm *accel_xfrm,
- const __be32 saddr[4],
- const __be32 daddr[4],
- const __be32 spi, bool is_ipv6,
- u32 *sa_handle)
+static void *mlx5_fpga_ipsec_create_sa_ctx(struct mlx5_core_dev *mdev,
+ struct mlx5_accel_esp_xfrm *accel_xfrm,
+ const __be32 saddr[4], const __be32 daddr[4],
+ const __be32 spi, bool is_ipv6, u32 *sa_handle)
{
struct mlx5_fpga_ipsec_sa_ctx *sa_ctx;
struct mlx5_fpga_esp_xfrm *fpga_xfrm =
@@ -862,7 +860,7 @@ mlx5_fpga_ipsec_release_sa_ctx(struct mlx5_fpga_ipsec_sa_ctx *sa_ctx)
mutex_unlock(&fipsec->sa_hash_lock);
}
-void mlx5_fpga_ipsec_delete_sa_ctx(void *context)
+static void mlx5_fpga_ipsec_delete_sa_ctx(void *context)
{
struct mlx5_fpga_esp_xfrm *fpga_xfrm =
((struct mlx5_fpga_ipsec_sa_ctx *)context)->fpga_xfrm;
@@ -1264,7 +1262,7 @@ const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default_ipsec_fpga_cmds(enum fs_flo
}
}
-int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev)
+static int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev)
{
struct mlx5_fpga_conn_attr init_attr = {0};
struct mlx5_fpga_device *fdev = mdev->fpga;
@@ -1346,7 +1344,7 @@ static void destroy_rules_rb(struct rb_root *root)
}
}
-void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev)
+static void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev)
{
struct mlx5_fpga_device *fdev = mdev->fpga;
@@ -1451,7 +1449,7 @@ mlx5_fpga_esp_validate_xfrm_attrs(struct mlx5_core_dev *mdev,
return 0;
}
-struct mlx5_accel_esp_xfrm *
+static struct mlx5_accel_esp_xfrm *
mlx5_fpga_esp_create_xfrm(struct mlx5_core_dev *mdev,
const struct mlx5_accel_esp_xfrm_attrs *attrs,
u32 flags)
@@ -1479,7 +1477,7 @@ mlx5_fpga_esp_create_xfrm(struct mlx5_core_dev *mdev,
return &fpga_xfrm->accel_xfrm;
}
-void mlx5_fpga_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm)
+static void mlx5_fpga_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm)
{
struct mlx5_fpga_esp_xfrm *fpga_xfrm =
container_of(xfrm, struct mlx5_fpga_esp_xfrm,
@@ -1488,8 +1486,8 @@ void mlx5_fpga_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm)
kfree(fpga_xfrm);
}
-int mlx5_fpga_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
- const struct mlx5_accel_esp_xfrm_attrs *attrs)
+static int mlx5_fpga_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
+ const struct mlx5_accel_esp_xfrm_attrs *attrs)
{
struct mlx5_core_dev *mdev = xfrm->mdev;
struct mlx5_fpga_device *fdev = mdev->fpga;
@@ -1560,3 +1558,24 @@ change_sw_xfrm_attrs:
mutex_unlock(&fpga_xfrm->lock);
return err;
}
+
+static const struct mlx5_accel_ipsec_ops fpga_ipsec_ops = {
+ .device_caps = mlx5_fpga_ipsec_device_caps,
+ .counters_count = mlx5_fpga_ipsec_counters_count,
+ .counters_read = mlx5_fpga_ipsec_counters_read,
+ .create_hw_context = mlx5_fpga_ipsec_create_sa_ctx,
+ .free_hw_context = mlx5_fpga_ipsec_delete_sa_ctx,
+ .init = mlx5_fpga_ipsec_init,
+ .cleanup = mlx5_fpga_ipsec_cleanup,
+ .esp_create_xfrm = mlx5_fpga_esp_create_xfrm,
+ .esp_modify_xfrm = mlx5_fpga_esp_modify_xfrm,
+ .esp_destroy_xfrm = mlx5_fpga_esp_destroy_xfrm,
+};
+
+const struct mlx5_accel_ipsec_ops *mlx5_fpga_ipsec_ops(struct mlx5_core_dev *mdev)
+{
+ if (!mlx5_fpga_is_ipsec_device(mdev))
+ return NULL;
+
+ return &fpga_ipsec_ops;
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
index 9ba637f0f0f2..db88eb4c49e3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
@@ -38,44 +38,23 @@
#include "fs_cmd.h"
#ifdef CONFIG_MLX5_FPGA_IPSEC
+const struct mlx5_accel_ipsec_ops *mlx5_fpga_ipsec_ops(struct mlx5_core_dev *mdev);
u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev);
-unsigned int mlx5_fpga_ipsec_counters_count(struct mlx5_core_dev *mdev);
-int mlx5_fpga_ipsec_counters_read(struct mlx5_core_dev *mdev, u64 *counters,
- unsigned int counters_count);
-
-void *mlx5_fpga_ipsec_create_sa_ctx(struct mlx5_core_dev *mdev,
- struct mlx5_accel_esp_xfrm *accel_xfrm,
- const __be32 saddr[4],
- const __be32 daddr[4],
- const __be32 spi, bool is_ipv6,
- u32 *sa_handle);
-void mlx5_fpga_ipsec_delete_sa_ctx(void *context);
-
-int mlx5_fpga_ipsec_init(struct mlx5_core_dev *mdev);
-void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev);
-void mlx5_fpga_ipsec_build_fs_cmds(void);
-
-struct mlx5_accel_esp_xfrm *
-mlx5_fpga_esp_create_xfrm(struct mlx5_core_dev *mdev,
- const struct mlx5_accel_esp_xfrm_attrs *attrs,
- u32 flags);
-void mlx5_fpga_esp_destroy_xfrm(struct mlx5_accel_esp_xfrm *xfrm);
-int mlx5_fpga_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
- const struct mlx5_accel_esp_xfrm_attrs *attrs);
-
const struct mlx5_flow_cmds *
mlx5_fs_cmd_get_default_ipsec_fpga_cmds(enum fs_flow_table_type type);
+void mlx5_fpga_ipsec_build_fs_cmds(void);
#else
-static inline u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev)
-{
- return 0;
-}
-
+static inline
+const struct mlx5_accel_ipsec_ops *mlx5_fpga_ipsec_ops(struct mlx5_core_dev *mdev)
+{ return NULL; }
+static inline u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev) { return 0; }
static inline const struct mlx5_flow_cmds *
mlx5_fs_cmd_get_default_ipsec_fpga_cmds(enum fs_flow_table_type type)
{
return mlx5_fs_cmd_get_default(type);
}
+static inline void mlx5_fpga_ipsec_build_fs_cmds(void) {};
+
#endif /* CONFIG_MLX5_FPGA_IPSEC */
#endif /* __MLX5_FPGA_IPSEC_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
index 465a1076a477..fee169732de7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
@@ -459,6 +459,8 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
MLX5_SET(flow_context, in_flow_context, modify_header_id,
fte->action.modify_hdr->id);
+ MLX5_SET(flow_context, in_flow_context, ipsec_obj_id, fte->action.ipsec_obj_id);
+
vlan = MLX5_ADDR_OF(flow_context, in_flow_context, push_vlan);
MLX5_SET(vlan, vlan, ethtype, fte->action.vlan[0].ethtype);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index 2569bb6228b6..7e70a8178a46 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -41,7 +41,6 @@
#include "diag/fs_tracepoint.h"
#include "accel/ipsec.h"
#include "fpga/ipsec.h"
-#include "eswitch.h"
#define INIT_TREE_NODE_ARRAY_SIZE(...) (sizeof((struct init_tree_node[]){__VA_ARGS__}) /\
sizeof(struct init_tree_node))
@@ -106,8 +105,8 @@
#define ETHTOOL_PRIO_NUM_LEVELS 1
#define ETHTOOL_NUM_PRIOS 11
#define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS)
-/* Vlan, mac, ttc, inner ttc, aRFS */
-#define KERNEL_NIC_PRIO_NUM_LEVELS 5
+/* Vlan, mac, ttc, inner ttc, {aRFS/accel and esp/esp_err} */
+#define KERNEL_NIC_PRIO_NUM_LEVELS 6
#define KERNEL_NIC_NUM_PRIOS 1
/* One more level for tc */
#define KERNEL_MIN_LEVEL (KERNEL_NIC_PRIO_NUM_LEVELS + 1)
@@ -847,18 +846,15 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev,
{
struct mlx5_flow_root_namespace *root = find_root(&prio->node);
struct mlx5_flow_table *iter;
- int i = 0;
int err;
fs_for_each_ft(iter, prio) {
- i++;
err = root->cmds->modify_flow_table(root, iter, ft);
if (err) {
- mlx5_core_warn(dev, "Failed to modify flow table %d\n",
- iter->id);
+ mlx5_core_err(dev,
+ "Failed to modify flow table id %d, type %d, err %d\n",
+ iter->id, iter->type, err);
/* The driver is out of sync with the FW */
- if (i > 1)
- WARN_ON(true);
return err;
}
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
index 825b662f809b..afe7f0bffb93 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
@@ -39,6 +39,16 @@
#include <linux/llist.h>
#include <steering/fs_dr.h>
+#define FDB_TC_MAX_CHAIN 3
+#define FDB_FT_CHAIN (FDB_TC_MAX_CHAIN + 1)
+#define FDB_TC_SLOW_PATH_CHAIN (FDB_FT_CHAIN + 1)
+
+/* The index of the last real chain (FT) + 1 as chain zero is valid as well */
+#define FDB_NUM_CHAINS (FDB_FT_CHAIN + 1)
+
+#define FDB_TC_MAX_PRIO 16
+#define FDB_TC_LEVELS_PER_PRIO 2
+
struct mlx5_modify_hdr {
enum mlx5_flow_namespace_type ns_type;
union {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
index a5fbe7343508..02558ac2ace6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
@@ -35,6 +35,7 @@
#include <linux/module.h>
#include "mlx5_core.h"
#include "../../mlxfw/mlxfw.h"
+#include "accel/tls.h"
enum {
MCQS_IDENTIFIER_BOOT_IMG = 0x1,
@@ -236,7 +237,7 @@ int mlx5_query_hca_caps(struct mlx5_core_dev *dev)
return err;
}
- if (MLX5_CAP_GEN(dev, tls_tx)) {
+ if (mlx5_accel_is_ktls_tx(dev) || mlx5_accel_is_ktls_rx(dev)) {
err = mlx5_core_get_caps(dev, MLX5_CAP_TLS);
if (err)
return err;
@@ -249,6 +250,12 @@ int mlx5_query_hca_caps(struct mlx5_core_dev *dev)
return err;
}
+ if (MLX5_CAP_GEN(dev, ipsec_offload)) {
+ err = mlx5_core_get_caps(dev, MLX5_CAP_IPSEC);
+ if (err)
+ return err;
+ }
+
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
index 690b822c6152..5763965d5ef3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
@@ -464,8 +464,7 @@ static const struct mlx5e_profile mlx5i_nic_profile = {
.update_rx = mlx5i_update_nic_rx,
.update_stats = NULL, /* mlx5i_update_stats */
.update_carrier = NULL, /* no HW update in IB link */
- .rx_handlers.handle_rx_cqe = mlx5i_handle_rx_cqe,
- .rx_handlers.handle_rx_cqe_mpwqe = NULL, /* Not supported */
+ .rx_handlers = &mlx5i_rx_handlers,
.max_tc = MLX5I_MAX_NUM_TC,
.rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
.stats_grps = mlx5i_stats_grps,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h
index 79071a15c4ca..b79dc1e28c41 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h
@@ -42,6 +42,7 @@
extern const struct ethtool_ops mlx5i_ethtool_ops;
extern const struct ethtool_ops mlx5i_pkey_ethtool_ops;
+extern const struct mlx5e_rx_handlers mlx5i_rx_handlers;
#define MLX5_IB_GRH_BYTES 40
#define MLX5_IPOIB_ENCAP_LEN 4
@@ -117,7 +118,6 @@ struct mlx5i_tx_wqe {
void mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
struct mlx5_av *av, u32 dqpn, u32 dqkey, bool xmit_more);
-void mlx5i_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
void mlx5i_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats);
#endif /* CONFIG_MLX5_CORE_IPOIB */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c
index f70367018862..7163d9f6c4a6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c
@@ -349,8 +349,7 @@ static const struct mlx5e_profile mlx5i_pkey_nic_profile = {
.disable = NULL,
.update_rx = mlx5i_update_nic_rx,
.update_stats = NULL,
- .rx_handlers.handle_rx_cqe = mlx5i_handle_rx_cqe,
- .rx_handlers.handle_rx_cqe_mpwqe = NULL, /* Not supported */
+ .rx_handlers = &mlx5i_rx_handlers,
.max_tc = MLX5I_MAX_NUM_TC,
.rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c b/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c
index e9089a793632..9e68f5926ab6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c
@@ -198,13 +198,13 @@ static void mlx5_lag_fib_update(struct work_struct *work)
/* Protect internal structures from changes */
rtnl_lock();
switch (fib_work->event) {
- case FIB_EVENT_ENTRY_REPLACE: /* fall through */
+ case FIB_EVENT_ENTRY_REPLACE:
case FIB_EVENT_ENTRY_DEL:
mlx5_lag_fib_route_event(ldev, fib_work->event,
fib_work->fen_info.fi);
fib_info_put(fib_work->fen_info.fi);
break;
- case FIB_EVENT_NH_ADD: /* fall through */
+ case FIB_EVENT_NH_ADD:
case FIB_EVENT_NH_DEL:
fib_nh = fib_work->fnh_info.fib_nh;
mlx5_lag_fib_nexthop_event(ldev,
@@ -255,7 +255,7 @@ static int mlx5_lag_fib_event(struct notifier_block *nb,
return NOTIFY_DONE;
switch (event) {
- case FIB_EVENT_ENTRY_REPLACE: /* fall through */
+ case FIB_EVENT_ENTRY_REPLACE:
case FIB_EVENT_ENTRY_DEL:
fen_info = container_of(info, struct fib_entry_notifier_info,
info);
@@ -278,7 +278,7 @@ static int mlx5_lag_fib_event(struct notifier_block *nb,
*/
fib_info_hold(fib_work->fen_info.fi);
break;
- case FIB_EVENT_NH_ADD: /* fall through */
+ case FIB_EVENT_NH_ADD:
case FIB_EVENT_NH_DEL:
fnh_info = container_of(info, struct fib_nh_notifier_info,
info);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c
index dcea87ec5977..57eb91bcbca7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c
@@ -6,7 +6,7 @@
int mlx5_create_encryption_key(struct mlx5_core_dev *mdev,
void *key, u32 sz_bytes,
- u32 *p_key_id)
+ u32 key_type, u32 *p_key_id)
{
u32 in[MLX5_ST_SZ_DW(create_encryption_key_in)] = {};
u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
@@ -41,8 +41,7 @@ int mlx5_create_encryption_key(struct mlx5_core_dev *mdev,
memcpy(key_p, key, sz_bytes);
MLX5_SET(encryption_key_obj, obj, key_size, general_obj_key_size);
- MLX5_SET(encryption_key_obj, obj, key_type,
- MLX5_GENERAL_OBJECT_TYPE_ENCRYPTION_KEY_TYPE_TLS);
+ MLX5_SET(encryption_key_obj, obj, key_type, key_type);
MLX5_SET(general_obj_in_cmd_hdr, in, opcode,
MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
MLX5_SET(general_obj_in_cmd_hdr, in, obj_type,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
index 249539247e2e..d046db7bb047 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
@@ -80,8 +80,14 @@ void mlx5_get_pme_stats(struct mlx5_core_dev *dev, struct mlx5_pme_stats *stats)
int mlx5_notifier_call_chain(struct mlx5_events *events, unsigned int event, void *data);
/* Crypto */
+enum {
+ MLX5_ACCEL_OBJ_TLS_KEY = MLX5_GENERAL_OBJECT_TYPE_ENCRYPTION_KEY_TYPE_TLS,
+ MLX5_ACCEL_OBJ_IPSEC_KEY = MLX5_GENERAL_OBJECT_TYPE_ENCRYPTION_KEY_TYPE_IPSEC,
+};
+
int mlx5_create_encryption_key(struct mlx5_core_dev *mdev,
- void *key, u32 sz_bytes, u32 *p_key_id);
+ void *key, u32 sz_bytes,
+ u32 key_type, u32 *p_key_id);
void mlx5_destroy_encryption_key(struct mlx5_core_dev *mdev, u32 key_id);
static inline struct net *mlx5_core_net(struct mlx5_core_dev *dev)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
index 82c766a95165..3315afe2f8dc 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
@@ -40,24 +40,16 @@
struct mlx5_vxlan {
struct mlx5_core_dev *mdev;
- spinlock_t lock; /* protect vxlan table */
/* max_num_ports is usuallly 4, 16 buckets is more than enough */
DECLARE_HASHTABLE(htable, 4);
- int num_ports;
struct mutex sync_lock; /* sync add/del port HW operations */
};
struct mlx5_vxlan_port {
struct hlist_node hlist;
- refcount_t refcount;
u16 udp_port;
};
-static inline u8 mlx5_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
-{
- return MLX5_CAP_ETH(mdev, max_vxlan_udp_ports) ?: 4;
-}
-
static int mlx5_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
{
u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)] = {};
@@ -78,113 +70,78 @@ static int mlx5_vxlan_core_del_port_cmd(struct mlx5_core_dev *mdev, u16 port)
return mlx5_cmd_exec_in(mdev, delete_vxlan_udp_dport, in);
}
-static struct mlx5_vxlan_port*
-mlx5_vxlan_lookup_port_locked(struct mlx5_vxlan *vxlan, u16 port)
+bool mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port)
{
struct mlx5_vxlan_port *vxlanp;
+ bool found = false;
- hash_for_each_possible(vxlan->htable, vxlanp, hlist, port) {
- if (vxlanp->udp_port == port)
- return vxlanp;
- }
+ if (!mlx5_vxlan_allowed(vxlan))
+ return NULL;
- return NULL;
+ rcu_read_lock();
+ hash_for_each_possible_rcu(vxlan->htable, vxlanp, hlist, port)
+ if (vxlanp->udp_port == port) {
+ found = true;
+ break;
+ }
+ rcu_read_unlock();
+
+ return found;
}
-struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port)
+static struct mlx5_vxlan_port *vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port)
{
struct mlx5_vxlan_port *vxlanp;
- if (!mlx5_vxlan_allowed(vxlan))
- return NULL;
-
- spin_lock_bh(&vxlan->lock);
- vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
- spin_unlock_bh(&vxlan->lock);
-
- return vxlanp;
+ hash_for_each_possible(vxlan->htable, vxlanp, hlist, port)
+ if (vxlanp->udp_port == port)
+ return vxlanp;
+ return NULL;
}
int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
{
struct mlx5_vxlan_port *vxlanp;
- int ret = -ENOSPC;
-
- vxlanp = mlx5_vxlan_lookup_port(vxlan, port);
- if (vxlanp) {
- refcount_inc(&vxlanp->refcount);
- return 0;
- }
-
- mutex_lock(&vxlan->sync_lock);
- if (vxlan->num_ports >= mlx5_vxlan_max_udp_ports(vxlan->mdev)) {
- mlx5_core_info(vxlan->mdev,
- "UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
- port, mlx5_vxlan_max_udp_ports(vxlan->mdev));
- ret = -ENOSPC;
- goto unlock;
- }
-
- ret = mlx5_vxlan_core_add_port_cmd(vxlan->mdev, port);
- if (ret)
- goto unlock;
+ int ret;
vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL);
- if (!vxlanp) {
- ret = -ENOMEM;
- goto err_delete_port;
- }
-
+ if (!vxlanp)
+ return -ENOMEM;
vxlanp->udp_port = port;
- refcount_set(&vxlanp->refcount, 1);
- spin_lock_bh(&vxlan->lock);
- hash_add(vxlan->htable, &vxlanp->hlist, port);
- spin_unlock_bh(&vxlan->lock);
+ ret = mlx5_vxlan_core_add_port_cmd(vxlan->mdev, port);
+ if (ret) {
+ kfree(vxlanp);
+ return ret;
+ }
- vxlan->num_ports++;
+ mutex_lock(&vxlan->sync_lock);
+ hash_add_rcu(vxlan->htable, &vxlanp->hlist, port);
mutex_unlock(&vxlan->sync_lock);
- return 0;
-
-err_delete_port:
- mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
-unlock:
- mutex_unlock(&vxlan->sync_lock);
- return ret;
+ return 0;
}
int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
{
struct mlx5_vxlan_port *vxlanp;
- bool remove = false;
int ret = 0;
mutex_lock(&vxlan->sync_lock);
- spin_lock_bh(&vxlan->lock);
- vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
- if (!vxlanp) {
+ vxlanp = vxlan_lookup_port(vxlan, port);
+ if (WARN_ON(!vxlanp)) {
ret = -ENOENT;
goto out_unlock;
}
- if (refcount_dec_and_test(&vxlanp->refcount)) {
- hash_del(&vxlanp->hlist);
- remove = true;
- }
+ hash_del_rcu(&vxlanp->hlist);
+ synchronize_rcu();
+ mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
+ kfree(vxlanp);
out_unlock:
- spin_unlock_bh(&vxlan->lock);
-
- if (remove) {
- mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
- kfree(vxlanp);
- vxlan->num_ports--;
- }
-
mutex_unlock(&vxlan->sync_lock);
-
return ret;
}
@@ -201,7 +158,6 @@ struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev)
vxlan->mdev = mdev;
mutex_init(&vxlan->sync_lock);
- spin_lock_init(&vxlan->lock);
hash_init(vxlan->htable);
/* Hardware adds 4789 (IANA_VXLAN_UDP_PORT) by default */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h
index 8fb0eb08fa6d..ec766529f49b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h
@@ -37,6 +37,11 @@
struct mlx5_vxlan;
struct mlx5_vxlan_port;
+static inline u8 mlx5_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
+{
+ return MLX5_CAP_ETH(mdev, max_vxlan_udp_ports) ?: 4;
+}
+
static inline bool mlx5_vxlan_allowed(struct mlx5_vxlan *vxlan)
{
/* not allowed reason is encoded in vxlan pointer as error,
@@ -50,15 +55,14 @@ struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev);
void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan);
int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port);
int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port);
-struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port);
+bool mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port);
#else
static inline struct mlx5_vxlan*
mlx5_vxlan_create(struct mlx5_core_dev *mdev) { return ERR_PTR(-EOPNOTSUPP); }
static inline void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan) { return; }
static inline int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port) { return -EOPNOTSUPP; }
static inline int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port) { return -EOPNOTSUPP; }
-static inline struct mx5_vxlan_port*
-mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port) { return NULL; }
+static inline bool mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port) { return false; }
#endif
#endif /* __MLX5_VXLAN_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 8b658908f044..e32d46c33701 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -1089,11 +1089,7 @@ static int mlx5_load(struct mlx5_core_dev *dev)
goto err_fpga_start;
}
- err = mlx5_accel_ipsec_init(dev);
- if (err) {
- mlx5_core_err(dev, "IPSec device start failed %d\n", err);
- goto err_ipsec_start;
- }
+ mlx5_accel_ipsec_init(dev);
err = mlx5_accel_tls_init(dev);
if (err) {
@@ -1135,7 +1131,6 @@ err_fs:
mlx5_accel_tls_cleanup(dev);
err_tls_start:
mlx5_accel_ipsec_cleanup(dev);
-err_ipsec_start:
mlx5_fpga_device_stop(dev);
err_fpga_start:
mlx5_rsc_dump_cleanup(dev);
@@ -1628,7 +1623,7 @@ static int __init init(void)
get_random_bytes(&sw_owner_id, sizeof(sw_owner_id));
mlx5_core_verify_params();
- mlx5_accel_ipsec_build_fs_cmds();
+ mlx5_fpga_ipsec_build_fs_cmds();
mlx5_register_debugfs();
err = pci_register_driver(&mlx5_core_driver);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
index c410a0ce35c8..f9b798af6335 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -35,6 +35,7 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/mlx5/driver.h>
+#include <linux/xarray.h>
#include "mlx5_core.h"
#include "lib/eq.h"
@@ -73,15 +74,45 @@ enum {
MLX5_NUM_4K_IN_PAGE = PAGE_SIZE / MLX5_ADAPTER_PAGE_SIZE,
};
+static struct rb_root *page_root_per_func_id(struct mlx5_core_dev *dev, u16 func_id)
+{
+ struct rb_root *root;
+ int err;
+
+ root = xa_load(&dev->priv.page_root_xa, func_id);
+ if (root)
+ return root;
+
+ root = kzalloc(sizeof(*root), GFP_KERNEL);
+ if (!root)
+ return ERR_PTR(-ENOMEM);
+
+ err = xa_insert(&dev->priv.page_root_xa, func_id, root, GFP_KERNEL);
+ if (err) {
+ kfree(root);
+ return ERR_PTR(err);
+ }
+
+ *root = RB_ROOT;
+
+ return root;
+}
+
static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u16 func_id)
{
- struct rb_root *root = &dev->priv.page_root;
- struct rb_node **new = &root->rb_node;
struct rb_node *parent = NULL;
+ struct rb_root *root;
+ struct rb_node **new;
struct fw_page *nfp;
struct fw_page *tfp;
int i;
+ root = page_root_per_func_id(dev, func_id);
+ if (IS_ERR(root))
+ return PTR_ERR(root);
+
+ new = &root->rb_node;
+
while (*new) {
parent = *new;
tfp = rb_entry(parent, struct fw_page, rb_node);
@@ -111,13 +142,20 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u
return 0;
}
-static struct fw_page *find_fw_page(struct mlx5_core_dev *dev, u64 addr)
+static struct fw_page *find_fw_page(struct mlx5_core_dev *dev, u64 addr,
+ u32 func_id)
{
- struct rb_root *root = &dev->priv.page_root;
- struct rb_node *tmp = root->rb_node;
struct fw_page *result = NULL;
+ struct rb_root *root;
+ struct rb_node *tmp;
struct fw_page *tfp;
+ root = xa_load(&dev->priv.page_root_xa, func_id);
+ if (WARN_ON_ONCE(!root))
+ return NULL;
+
+ tmp = root->rb_node;
+
while (tmp) {
tfp = rb_entry(tmp, struct fw_page, rb_node);
if (tfp->addr < addr) {
@@ -191,7 +229,13 @@ static int alloc_4k(struct mlx5_core_dev *dev, u64 *addr, u16 func_id)
static void free_fwp(struct mlx5_core_dev *dev, struct fw_page *fwp,
bool in_free_list)
{
- rb_erase(&fwp->rb_node, &dev->priv.page_root);
+ struct rb_root *root;
+
+ root = xa_load(&dev->priv.page_root_xa, fwp->func_id);
+ if (WARN_ON_ONCE(!root))
+ return;
+
+ rb_erase(&fwp->rb_node, root);
if (in_free_list)
list_del(&fwp->list);
dma_unmap_page(dev->device, fwp->addr & MLX5_U64_4K_PAGE_MASK,
@@ -200,12 +244,12 @@ static void free_fwp(struct mlx5_core_dev *dev, struct fw_page *fwp,
kfree(fwp);
}
-static void free_4k(struct mlx5_core_dev *dev, u64 addr)
+static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 func_id)
{
struct fw_page *fwp;
int n;
- fwp = find_fw_page(dev, addr & MLX5_U64_4K_PAGE_MASK);
+ fwp = find_fw_page(dev, addr & MLX5_U64_4K_PAGE_MASK, func_id);
if (!fwp) {
mlx5_core_warn_rl(dev, "page not found\n");
return;
@@ -340,7 +384,7 @@ retry:
out_4k:
for (i--; i >= 0; i--)
- free_4k(dev, MLX5_GET64(manage_pages_in, in, pas[i]));
+ free_4k(dev, MLX5_GET64(manage_pages_in, in, pas[i]), func_id);
out_free:
kvfree(in);
if (notify_fail)
@@ -351,16 +395,19 @@ out_free:
static void release_all_pages(struct mlx5_core_dev *dev, u32 func_id,
bool ec_function)
{
+ struct rb_root *root;
struct rb_node *p;
int npages = 0;
- p = rb_first(&dev->priv.page_root);
+ root = xa_load(&dev->priv.page_root_xa, func_id);
+ if (WARN_ON_ONCE(!root))
+ return;
+
+ p = rb_first(root);
while (p) {
struct fw_page *fwp = rb_entry(p, struct fw_page, rb_node);
p = rb_next(p);
- if (fwp->func_id != func_id)
- continue;
npages += (MLX5_NUM_4K_IN_PAGE - fwp->free_count);
free_fwp(dev, fwp, fwp->free_count);
}
@@ -378,6 +425,7 @@ static void release_all_pages(struct mlx5_core_dev *dev, u32 func_id,
static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
u32 *in, int in_size, u32 *out, int out_size)
{
+ struct rb_root *root;
struct fw_page *fwp;
struct rb_node *p;
u32 func_id;
@@ -391,12 +439,14 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
npages = MLX5_GET(manage_pages_in, in, input_num_entries);
func_id = MLX5_GET(manage_pages_in, in, function_id);
- p = rb_first(&dev->priv.page_root);
+ root = xa_load(&dev->priv.page_root_xa, func_id);
+ if (WARN_ON_ONCE(!root))
+ return -EEXIST;
+
+ p = rb_first(root);
while (p && i < npages) {
fwp = rb_entry(p, struct fw_page, rb_node);
p = rb_next(p);
- if (fwp->func_id != func_id)
- continue;
MLX5_ARRAY_SET64(manage_pages_out, out, pas, i, fwp->addr);
i++;
@@ -430,7 +480,8 @@ static int reclaim_pages(struct mlx5_core_dev *dev, u32 func_id, int npages,
MLX5_SET(manage_pages_in, in, input_num_entries, npages);
MLX5_SET(manage_pages_in, in, embedded_cpu_function, ec_function);
- mlx5_core_dbg(dev, "npages %d, outlen %d\n", npages, outlen);
+ mlx5_core_dbg(dev, "func 0x%x, npages %d, outlen %d\n",
+ func_id, npages, outlen);
err = reclaim_pages_cmd(dev, in, sizeof(in), out, outlen);
if (err) {
mlx5_core_err(dev, "failed reclaiming pages: err %d\n", err);
@@ -446,7 +497,7 @@ static int reclaim_pages(struct mlx5_core_dev *dev, u32 func_id, int npages,
}
for (i = 0; i < num_claimed; i++)
- free_4k(dev, MLX5_GET64(manage_pages_out, out, pas[i]));
+ free_4k(dev, MLX5_GET64(manage_pages_out, out, pas[i]), func_id);
if (nclaimed)
*nclaimed = num_claimed;
@@ -560,35 +611,49 @@ static int optimal_reclaimed_pages(void)
return ret;
}
-int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev)
+static int mlx5_reclaim_root_pages(struct mlx5_core_dev *dev,
+ struct rb_root *root, u16 func_id)
{
unsigned long end = jiffies + msecs_to_jiffies(MAX_RECLAIM_TIME_MSECS);
- struct fw_page *fwp;
- struct rb_node *p;
- int nclaimed = 0;
- int err = 0;
- do {
- p = rb_first(&dev->priv.page_root);
- if (p) {
- fwp = rb_entry(p, struct fw_page, rb_node);
- err = reclaim_pages(dev, fwp->func_id,
- optimal_reclaimed_pages(),
- &nclaimed, mlx5_core_is_ecpf(dev));
-
- if (err) {
- mlx5_core_warn(dev, "failed reclaiming pages (%d)\n",
- err);
- return err;
- }
- if (nclaimed)
- end = jiffies + msecs_to_jiffies(MAX_RECLAIM_TIME_MSECS);
+ while (!RB_EMPTY_ROOT(root)) {
+ int nclaimed;
+ int err;
+
+ err = reclaim_pages(dev, func_id, optimal_reclaimed_pages(),
+ &nclaimed, mlx5_core_is_ecpf(dev));
+ if (err) {
+ mlx5_core_warn(dev, "failed reclaiming pages (%d) for func id 0x%x\n",
+ err, func_id);
+ return err;
}
+
+ if (nclaimed)
+ end = jiffies + msecs_to_jiffies(MAX_RECLAIM_TIME_MSECS);
+
if (time_after(jiffies, end)) {
mlx5_core_warn(dev, "FW did not return all pages. giving up...\n");
break;
}
- } while (p);
+ }
+
+ return 0;
+}
+
+int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev)
+{
+ struct rb_root *root;
+ unsigned long id;
+ void *entry;
+
+ xa_for_each(&dev->priv.page_root_xa, id, entry) {
+ root = entry;
+ mlx5_reclaim_root_pages(dev, root, id);
+ xa_erase(&dev->priv.page_root_xa, id);
+ kfree(root);
+ }
+
+ WARN_ON(!xa_empty(&dev->priv.page_root_xa));
WARN(dev->priv.fw_pages,
"FW pages counter is %d after reclaiming all pages\n",
@@ -605,17 +670,19 @@ int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev)
int mlx5_pagealloc_init(struct mlx5_core_dev *dev)
{
- dev->priv.page_root = RB_ROOT;
INIT_LIST_HEAD(&dev->priv.free_list);
dev->priv.pg_wq = create_singlethread_workqueue("mlx5_page_allocator");
if (!dev->priv.pg_wq)
return -ENOMEM;
+ xa_init(&dev->priv.page_root_xa);
+
return 0;
}
void mlx5_pagealloc_cleanup(struct mlx5_core_dev *dev)
{
+ xa_destroy(&dev->priv.page_root_xa);
destroy_workqueue(dev->priv.pg_wq);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c
index 31abcbb95ca2..c63f727273d8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c
@@ -395,7 +395,7 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher,
/* Check that all mask fields were consumed */
for (i = 0; i < sizeof(struct mlx5dr_match_param); i++) {
if (((u8 *)&mask)[i] != 0) {
- mlx5dr_err(dmn, "Mask contains unsupported parameters\n");
+ mlx5dr_dbg(dmn, "Mask contains unsupported parameters\n");
return -EOPNOTSUPP;
}
}
@@ -474,14 +474,13 @@ static int dr_matcher_add_to_tbl(struct mlx5dr_matcher *matcher)
int ret;
next_matcher = NULL;
- if (!list_empty(&tbl->matcher_list))
- list_for_each_entry(tmp_matcher, &tbl->matcher_list, matcher_list) {
- if (tmp_matcher->prio >= matcher->prio) {
- next_matcher = tmp_matcher;
- break;
- }
- first = false;
+ list_for_each_entry(tmp_matcher, &tbl->matcher_list, matcher_list) {
+ if (tmp_matcher->prio >= matcher->prio) {
+ next_matcher = tmp_matcher;
+ break;
}
+ first = false;
+ }
prev_matcher = NULL;
if (next_matcher && !first)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
index cd708dcc2e3a..6ec5106bc472 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
@@ -574,9 +574,8 @@ void mlx5dr_rule_update_rule_member(struct mlx5dr_ste *ste,
{
struct mlx5dr_rule_member *rule_mem;
- if (!list_empty(&ste->rule_list))
- list_for_each_entry(rule_mem, &ste->rule_list, use_ste_list)
- rule_mem->ste = new_ste;
+ list_for_each_entry(rule_mem, &ste->rule_list, use_ste_list)
+ rule_mem->ste = new_ste;
}
static void dr_rule_clean_rule_members(struct mlx5dr_rule *rule,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c
index 8887b2440c7d..9b08eb557a31 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c
@@ -279,29 +279,9 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
/* The order of the actions are must to be keep, only the following
* order is supported by SW steering:
- * TX: push vlan -> modify header -> encap
+ * TX: modify header -> push vlan -> encap
* RX: decap -> pop vlan -> modify header
*/
- if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) {
- tmp_action = create_action_push_vlan(domain, &fte->action.vlan[0]);
- if (!tmp_action) {
- err = -ENOMEM;
- goto free_actions;
- }
- fs_dr_actions[fs_dr_num_actions++] = tmp_action;
- actions[num_actions++] = tmp_action;
- }
-
- if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2) {
- tmp_action = create_action_push_vlan(domain, &fte->action.vlan[1]);
- if (!tmp_action) {
- err = -ENOMEM;
- goto free_actions;
- }
- fs_dr_actions[fs_dr_num_actions++] = tmp_action;
- actions[num_actions++] = tmp_action;
- }
-
if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_DECAP) {
enum mlx5dr_action_reformat_type decap_type =
DR_ACTION_REFORMAT_TYP_TNL_L2_TO_L2;
@@ -354,6 +334,26 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
actions[num_actions++] =
fte->action.modify_hdr->action.dr_action;
+ if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) {
+ tmp_action = create_action_push_vlan(domain, &fte->action.vlan[0]);
+ if (!tmp_action) {
+ err = -ENOMEM;
+ goto free_actions;
+ }
+ fs_dr_actions[fs_dr_num_actions++] = tmp_action;
+ actions[num_actions++] = tmp_action;
+ }
+
+ if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2) {
+ tmp_action = create_action_push_vlan(domain, &fte->action.vlan[1]);
+ if (!tmp_action) {
+ err = -ENOMEM;
+ goto free_actions;
+ }
+ fs_dr_actions[fs_dr_num_actions++] = tmp_action;
+ actions[num_actions++] = tmp_action;
+ }
+
if (delay_encap_set)
actions[num_actions++] =
fte->action.pkt_reformat->action.dr_action;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
index c107d92dc118..bdafc85fd874 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
@@ -110,7 +110,7 @@ void mlx5_query_min_inline(struct mlx5_core_dev *mdev,
case MLX5_CAP_INLINE_MODE_VPORT_CONTEXT:
if (!mlx5_query_nic_vport_min_inline(mdev, 0, min_inline_mode))
break;
- /* fall through */
+ fallthrough;
case MLX5_CAP_INLINE_MODE_L2:
*min_inline_mode = MLX5_INLINE_MODE_L2;
break;
@@ -173,7 +173,7 @@ int mlx5_query_mac_address(struct mlx5_core_dev *mdev, u8 *addr)
EXPORT_SYMBOL_GPL(mlx5_query_mac_address);
int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev,
- u16 vport, u8 *addr)
+ u16 vport, const u8 *addr)
{
void *in;
int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wq.h b/drivers/net/ethernet/mellanox/mlx5/core/wq.h
index 4cadc336593f..e5c4dcd1425e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/wq.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/wq.h
@@ -172,6 +172,11 @@ static inline int mlx5_wq_cyc_cc_bigger(u16 cc1, u16 cc2)
return !equal && !smaller;
}
+static inline u16 mlx5_wq_cyc_get_counter(struct mlx5_wq_cyc *wq)
+{
+ return wq->wqe_ctr;
+}
+
static inline u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq)
{
return wq->fbc.sz_m1 + 1;
@@ -290,4 +295,14 @@ static inline void mlx5_wq_ll_update_db_record(struct mlx5_wq_ll *wq)
*wq->db = cpu_to_be32(wq->wqe_ctr);
}
+static inline u16 mlx5_wq_ll_get_head(struct mlx5_wq_ll *wq)
+{
+ return wq->head;
+}
+
+static inline u16 mlx5_wq_ll_get_counter(struct mlx5_wq_ll *wq)
+{
+ return wq->wqe_ctr;
+}
+
#endif /* __MLX5_WQ_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Makefile b/drivers/net/ethernet/mellanox/mlxsw/Makefile
index 4aeabb35c943..892724380ea2 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Makefile
+++ b/drivers/net/ethernet/mellanox/mlxsw/Makefile
@@ -30,7 +30,8 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
spectrum_mr_tcam.o spectrum_mr.o \
spectrum_qdisc.o spectrum_span.o \
spectrum_nve.o spectrum_nve_vxlan.o \
- spectrum_dpipe.o spectrum_trap.o
+ spectrum_dpipe.o spectrum_trap.o \
+ spectrum_ethtool.o spectrum_policer.o
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
mlxsw_spectrum-$(CONFIG_PTP_1588_CLOCK) += spectrum_ptp.o
obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 71b6185b4904..08d101138fbe 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -1177,14 +1177,15 @@ static void mlxsw_devlink_trap_fini(struct devlink *devlink,
static int mlxsw_devlink_trap_action_set(struct devlink *devlink,
const struct devlink_trap *trap,
- enum devlink_trap_action action)
+ enum devlink_trap_action action,
+ struct netlink_ext_ack *extack)
{
struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
if (!mlxsw_driver->trap_action_set)
return -EOPNOTSUPP;
- return mlxsw_driver->trap_action_set(mlxsw_core, trap, action);
+ return mlxsw_driver->trap_action_set(mlxsw_core, trap, action, extack);
}
static int
@@ -1202,14 +1203,15 @@ mlxsw_devlink_trap_group_init(struct devlink *devlink,
static int
mlxsw_devlink_trap_group_set(struct devlink *devlink,
const struct devlink_trap_group *group,
- const struct devlink_trap_policer *policer)
+ const struct devlink_trap_policer *policer,
+ struct netlink_ext_ack *extack)
{
struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
if (!mlxsw_driver->trap_group_set)
return -EOPNOTSUPP;
- return mlxsw_driver->trap_group_set(mlxsw_core, group, policer);
+ return mlxsw_driver->trap_group_set(mlxsw_core, group, policer, extack);
}
static int
@@ -1525,7 +1527,8 @@ static bool __is_rx_listener_equal(const struct mlxsw_rx_listener *rxl_a,
{
return (rxl_a->func == rxl_b->func &&
rxl_a->local_port == rxl_b->local_port &&
- rxl_a->trap_id == rxl_b->trap_id);
+ rxl_a->trap_id == rxl_b->trap_id &&
+ rxl_a->mirror_reason == rxl_b->mirror_reason);
}
static struct mlxsw_rx_listener_item *
@@ -2045,7 +2048,8 @@ void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
rxl = &rxl_item->rxl;
if ((rxl->local_port == MLXSW_PORT_DONT_CARE ||
rxl->local_port == local_port) &&
- rxl->trap_id == rx_info->trap_id) {
+ rxl->trap_id == rx_info->trap_id &&
+ rxl->mirror_reason == rx_info->mirror_reason) {
if (rxl_item->enabled)
found = true;
break;
@@ -2125,6 +2129,7 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
enum devlink_port_flavour flavour,
u32 port_number, bool split,
u32 split_port_subnumber,
+ bool splittable, u32 lanes,
const unsigned char *switch_id,
unsigned char switch_id_len)
{
@@ -2132,12 +2137,19 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
struct mlxsw_core_port *mlxsw_core_port =
&mlxsw_core->ports[local_port];
struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
+ struct devlink_port_attrs attrs = {};
int err;
+ attrs.split = split;
+ attrs.lanes = lanes;
+ attrs.splittable = splittable;
+ attrs.flavour = flavour;
+ attrs.phys.port_number = port_number;
+ attrs.phys.split_subport_number = split_port_subnumber;
+ memcpy(attrs.switch_id.id, switch_id, switch_id_len);
+ attrs.switch_id.id_len = switch_id_len;
mlxsw_core_port->local_port = local_port;
- devlink_port_attrs_set(devlink_port, flavour, port_number,
- split, split_port_subnumber,
- switch_id, switch_id_len);
+ devlink_port_attrs_set(devlink_port, &attrs);
err = devlink_port_register(devlink, devlink_port, local_port);
if (err)
memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
@@ -2157,12 +2169,14 @@ static void __mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
u32 port_number, bool split,
u32 split_port_subnumber,
+ bool splittable, u32 lanes,
const unsigned char *switch_id,
unsigned char switch_id_len)
{
return __mlxsw_core_port_init(mlxsw_core, local_port,
DEVLINK_PORT_FLAVOUR_PHYSICAL,
port_number, split, split_port_subnumber,
+ splittable, lanes,
switch_id, switch_id_len);
}
EXPORT_SYMBOL(mlxsw_core_port_init);
@@ -2184,7 +2198,7 @@ int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
err = __mlxsw_core_port_init(mlxsw_core, MLXSW_PORT_CPU_PORT,
DEVLINK_PORT_FLAVOUR_CPU,
- 0, false, 0,
+ 0, false, 0, false, 0,
switch_id, switch_id_len);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index 22b0dfa7cfae..11af3308f8cc 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -61,6 +61,7 @@ void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core,
struct mlxsw_rx_listener {
void (*func)(struct sk_buff *skb, u8 local_port, void *priv);
u8 local_port;
+ u8 mirror_reason;
u16 trap_id;
};
@@ -88,13 +89,15 @@ struct mlxsw_listener {
};
#define __MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \
- _dis_action, _enabled_on_register, _dis_trap_group) \
+ _dis_action, _enabled_on_register, _dis_trap_group, \
+ _mirror_reason) \
{ \
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
.rx_listener = \
{ \
.func = _func, \
.local_port = MLXSW_PORT_DONT_CARE, \
+ .mirror_reason = _mirror_reason, \
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
}, \
.en_action = MLXSW_REG_HPKT_ACTION_##_en_action, \
@@ -108,12 +111,17 @@ struct mlxsw_listener {
#define MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group, \
_dis_action) \
__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group, \
- _dis_action, true, _trap_group)
+ _dis_action, true, _trap_group, 0)
#define MLXSW_RXL_DIS(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \
_dis_action, _dis_trap_group) \
__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \
- _dis_action, false, _dis_trap_group)
+ _dis_action, false, _dis_trap_group, 0)
+
+#define MLXSW_RXL_MIRROR(_func, _session_id, _trap_group, _mirror_reason) \
+ __MLXSW_RXL(_func, MIRROR_SESSION##_session_id, TRAP_TO_CPU, false, \
+ _trap_group, TRAP_TO_CPU, true, _trap_group, \
+ _mirror_reason)
#define MLXSW_EVENTL(_func, _trap_id, _trap_group) \
{ \
@@ -176,6 +184,7 @@ struct mlxsw_rx_info {
u16 lag_id;
} u;
u8 lag_port_index;
+ u8 mirror_reason;
int trap_id;
};
@@ -191,8 +200,8 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
- u32 port_number, bool split,
- u32 split_port_subnumber,
+ u32 port_number, bool split, u32 split_port_subnumber,
+ bool splittable, u32 lanes,
const unsigned char *switch_id,
unsigned char switch_id_len);
void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
@@ -324,12 +333,14 @@ struct mlxsw_driver {
const struct devlink_trap *trap, void *trap_ctx);
int (*trap_action_set)(struct mlxsw_core *mlxsw_core,
const struct devlink_trap *trap,
- enum devlink_trap_action action);
+ enum devlink_trap_action action,
+ struct netlink_ext_ack *extack);
int (*trap_group_init)(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_group *group);
int (*trap_group_set)(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_group *group,
- const struct devlink_trap_policer *policer);
+ const struct devlink_trap_policer *policer,
+ struct netlink_ext_ack *extack);
int (*trap_policer_init)(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_policer *policer);
void (*trap_policer_fini)(struct mlxsw_core *mlxsw_core,
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 c3d04319ff44..4d699fe98cb6 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
@@ -67,7 +67,9 @@ struct mlxsw_afa {
struct rhashtable set_ht;
struct rhashtable fwd_entry_ht;
struct rhashtable cookie_ht;
+ struct rhashtable policer_ht;
struct idr cookie_idr;
+ struct list_head policer_list;
};
#define MLXSW_AFA_SET_LEN 0xA8
@@ -88,9 +90,11 @@ struct mlxsw_afa_set {
struct rhash_head ht_node;
struct mlxsw_afa_set_ht_key ht_key;
u32 kvdl_index;
- bool shared; /* Inserted in hashtable (doesn't mean that
+ u8 shared:1, /* Inserted in hashtable (doesn't mean that
* kvdl_index is valid).
*/
+ has_trap:1,
+ has_police:1;
unsigned int ref_count;
struct mlxsw_afa_set *next; /* Pointer to the next set. */
struct mlxsw_afa_set *prev; /* Pointer to the previous set,
@@ -175,6 +179,21 @@ static const struct rhashtable_params mlxsw_afa_cookie_ht_params = {
.automatic_shrinking = true,
};
+struct mlxsw_afa_policer {
+ struct rhash_head ht_node;
+ struct list_head list; /* Member of policer_list */
+ refcount_t ref_count;
+ u32 fa_index;
+ u16 policer_index;
+};
+
+static const struct rhashtable_params mlxsw_afa_policer_ht_params = {
+ .key_len = sizeof(u32),
+ .key_offset = offsetof(struct mlxsw_afa_policer, fa_index),
+ .head_offset = offsetof(struct mlxsw_afa_policer, ht_node),
+ .automatic_shrinking = true,
+};
+
struct mlxsw_afa *mlxsw_afa_create(unsigned int max_acts_per_set,
const struct mlxsw_afa_ops *ops,
void *ops_priv)
@@ -196,12 +215,19 @@ struct mlxsw_afa *mlxsw_afa_create(unsigned int max_acts_per_set,
&mlxsw_afa_cookie_ht_params);
if (err)
goto err_cookie_rhashtable_init;
+ err = rhashtable_init(&mlxsw_afa->policer_ht,
+ &mlxsw_afa_policer_ht_params);
+ if (err)
+ goto err_policer_rhashtable_init;
idr_init(&mlxsw_afa->cookie_idr);
+ INIT_LIST_HEAD(&mlxsw_afa->policer_list);
mlxsw_afa->max_acts_per_set = max_acts_per_set;
mlxsw_afa->ops = ops;
mlxsw_afa->ops_priv = ops_priv;
return mlxsw_afa;
+err_policer_rhashtable_init:
+ rhashtable_destroy(&mlxsw_afa->cookie_ht);
err_cookie_rhashtable_init:
rhashtable_destroy(&mlxsw_afa->fwd_entry_ht);
err_fwd_entry_rhashtable_init:
@@ -214,8 +240,10 @@ EXPORT_SYMBOL(mlxsw_afa_create);
void mlxsw_afa_destroy(struct mlxsw_afa *mlxsw_afa)
{
+ WARN_ON(!list_empty(&mlxsw_afa->policer_list));
WARN_ON(!idr_is_empty(&mlxsw_afa->cookie_idr));
idr_destroy(&mlxsw_afa->cookie_idr);
+ rhashtable_destroy(&mlxsw_afa->policer_ht);
rhashtable_destroy(&mlxsw_afa->cookie_ht);
rhashtable_destroy(&mlxsw_afa->fwd_entry_ht);
rhashtable_destroy(&mlxsw_afa->set_ht);
@@ -836,19 +864,172 @@ err_cookie_get:
return ERR_PTR(err);
}
+static struct mlxsw_afa_policer *
+mlxsw_afa_policer_create(struct mlxsw_afa *mlxsw_afa, u32 fa_index,
+ u64 rate_bytes_ps, u32 burst,
+ struct netlink_ext_ack *extack)
+{
+ struct mlxsw_afa_policer *policer;
+ int err;
+
+ policer = kzalloc(sizeof(*policer), GFP_KERNEL);
+ if (!policer)
+ return ERR_PTR(-ENOMEM);
+
+ err = mlxsw_afa->ops->policer_add(mlxsw_afa->ops_priv, rate_bytes_ps,
+ burst, &policer->policer_index,
+ extack);
+ if (err)
+ goto err_policer_add;
+
+ refcount_set(&policer->ref_count, 1);
+ policer->fa_index = fa_index;
+
+ err = rhashtable_insert_fast(&mlxsw_afa->policer_ht, &policer->ht_node,
+ mlxsw_afa_policer_ht_params);
+ if (err)
+ goto err_rhashtable_insert;
+
+ list_add_tail(&policer->list, &mlxsw_afa->policer_list);
+
+ return policer;
+
+err_rhashtable_insert:
+ mlxsw_afa->ops->policer_del(mlxsw_afa->ops_priv,
+ policer->policer_index);
+err_policer_add:
+ kfree(policer);
+ return ERR_PTR(err);
+}
+
+static void mlxsw_afa_policer_destroy(struct mlxsw_afa *mlxsw_afa,
+ struct mlxsw_afa_policer *policer)
+{
+ list_del(&policer->list);
+ rhashtable_remove_fast(&mlxsw_afa->policer_ht, &policer->ht_node,
+ mlxsw_afa_policer_ht_params);
+ mlxsw_afa->ops->policer_del(mlxsw_afa->ops_priv,
+ policer->policer_index);
+ kfree(policer);
+}
+
+static struct mlxsw_afa_policer *
+mlxsw_afa_policer_get(struct mlxsw_afa *mlxsw_afa, u32 fa_index,
+ u64 rate_bytes_ps, u32 burst,
+ struct netlink_ext_ack *extack)
+{
+ struct mlxsw_afa_policer *policer;
+
+ policer = rhashtable_lookup_fast(&mlxsw_afa->policer_ht, &fa_index,
+ mlxsw_afa_policer_ht_params);
+ if (policer) {
+ refcount_inc(&policer->ref_count);
+ return policer;
+ }
+
+ return mlxsw_afa_policer_create(mlxsw_afa, fa_index, rate_bytes_ps,
+ burst, extack);
+}
+
+static void mlxsw_afa_policer_put(struct mlxsw_afa *mlxsw_afa,
+ struct mlxsw_afa_policer *policer)
+{
+ if (!refcount_dec_and_test(&policer->ref_count))
+ return;
+ mlxsw_afa_policer_destroy(mlxsw_afa, policer);
+}
+
+struct mlxsw_afa_policer_ref {
+ struct mlxsw_afa_resource resource;
+ struct mlxsw_afa_policer *policer;
+};
+
+static void
+mlxsw_afa_policer_ref_destroy(struct mlxsw_afa_block *block,
+ struct mlxsw_afa_policer_ref *policer_ref)
+{
+ mlxsw_afa_resource_del(&policer_ref->resource);
+ mlxsw_afa_policer_put(block->afa, policer_ref->policer);
+ kfree(policer_ref);
+}
+
+static void
+mlxsw_afa_policer_ref_destructor(struct mlxsw_afa_block *block,
+ struct mlxsw_afa_resource *resource)
+{
+ struct mlxsw_afa_policer_ref *policer_ref;
+
+ policer_ref = container_of(resource, struct mlxsw_afa_policer_ref,
+ resource);
+ mlxsw_afa_policer_ref_destroy(block, policer_ref);
+}
+
+static struct mlxsw_afa_policer_ref *
+mlxsw_afa_policer_ref_create(struct mlxsw_afa_block *block, u32 fa_index,
+ u64 rate_bytes_ps, u32 burst,
+ struct netlink_ext_ack *extack)
+{
+ struct mlxsw_afa_policer_ref *policer_ref;
+ struct mlxsw_afa_policer *policer;
+ int err;
+
+ policer_ref = kzalloc(sizeof(*policer_ref), GFP_KERNEL);
+ if (!policer_ref)
+ return ERR_PTR(-ENOMEM);
+
+ policer = mlxsw_afa_policer_get(block->afa, fa_index, rate_bytes_ps,
+ burst, extack);
+ if (IS_ERR(policer)) {
+ err = PTR_ERR(policer);
+ goto err_policer_get;
+ }
+
+ policer_ref->policer = policer;
+ policer_ref->resource.destructor = mlxsw_afa_policer_ref_destructor;
+ mlxsw_afa_resource_add(block, &policer_ref->resource);
+
+ return policer_ref;
+
+err_policer_get:
+ kfree(policer_ref);
+ return ERR_PTR(err);
+}
+
#define MLXSW_AFA_ONE_ACTION_LEN 32
#define MLXSW_AFA_PAYLOAD_OFFSET 4
-static char *mlxsw_afa_block_append_action(struct mlxsw_afa_block *block,
- u8 action_code, u8 action_size)
+enum mlxsw_afa_action_type {
+ MLXSW_AFA_ACTION_TYPE_TRAP,
+ MLXSW_AFA_ACTION_TYPE_POLICE,
+ MLXSW_AFA_ACTION_TYPE_OTHER,
+};
+
+static bool
+mlxsw_afa_block_need_split(const struct mlxsw_afa_block *block,
+ enum mlxsw_afa_action_type type)
+{
+ struct mlxsw_afa_set *cur_set = block->cur_set;
+
+ /* Due to a hardware limitation, police action cannot be in the same
+ * action set with MLXSW_AFA_TRAP_CODE or MLXSW_AFA_TRAPWU_CODE
+ * actions. Work around this limitation by creating a new action set
+ * and place the new action there.
+ */
+ return (cur_set->has_trap && type == MLXSW_AFA_ACTION_TYPE_POLICE) ||
+ (cur_set->has_police && type == MLXSW_AFA_ACTION_TYPE_TRAP);
+}
+
+static char *mlxsw_afa_block_append_action_ext(struct mlxsw_afa_block *block,
+ u8 action_code, u8 action_size,
+ enum mlxsw_afa_action_type type)
{
char *oneact;
char *actions;
if (block->finished)
return ERR_PTR(-EINVAL);
- if (block->cur_act_index + action_size >
- block->afa->max_acts_per_set) {
+ if (block->cur_act_index + action_size > block->afa->max_acts_per_set ||
+ mlxsw_afa_block_need_split(block, type)) {
struct mlxsw_afa_set *set;
/* The appended action won't fit into the current action set,
@@ -863,6 +1044,17 @@ static char *mlxsw_afa_block_append_action(struct mlxsw_afa_block *block,
block->cur_set = set;
}
+ switch (type) {
+ case MLXSW_AFA_ACTION_TYPE_TRAP:
+ block->cur_set->has_trap = true;
+ break;
+ case MLXSW_AFA_ACTION_TYPE_POLICE:
+ block->cur_set->has_police = true;
+ break;
+ default:
+ break;
+ }
+
actions = block->cur_set->ht_key.enc_actions;
oneact = actions + block->cur_act_index * MLXSW_AFA_ONE_ACTION_LEN;
block->cur_act_index += action_size;
@@ -870,6 +1062,14 @@ static char *mlxsw_afa_block_append_action(struct mlxsw_afa_block *block,
return oneact + MLXSW_AFA_PAYLOAD_OFFSET;
}
+static char *mlxsw_afa_block_append_action(struct mlxsw_afa_block *block,
+ u8 action_code, u8 action_size)
+{
+ return mlxsw_afa_block_append_action_ext(block, action_code,
+ action_size,
+ MLXSW_AFA_ACTION_TYPE_OTHER);
+}
+
/* VLAN Action
* -----------
* VLAN action is used for manipulating VLANs. It can be used to implement QinQ,
@@ -1048,11 +1248,20 @@ mlxsw_afa_trap_mirror_pack(char *payload, bool mirror_enable,
mlxsw_afa_trap_mirror_agent_set(payload, mirror_agent);
}
+static char *mlxsw_afa_block_append_action_trap(struct mlxsw_afa_block *block,
+ u8 action_code, u8 action_size)
+{
+ return mlxsw_afa_block_append_action_ext(block, action_code,
+ action_size,
+ MLXSW_AFA_ACTION_TYPE_TRAP);
+}
+
static int mlxsw_afa_block_append_drop_plain(struct mlxsw_afa_block *block,
bool ingress)
{
- char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAP_CODE,
- MLXSW_AFA_TRAP_SIZE);
+ char *act = mlxsw_afa_block_append_action_trap(block,
+ MLXSW_AFA_TRAP_CODE,
+ MLXSW_AFA_TRAP_SIZE);
if (IS_ERR(act))
return PTR_ERR(act);
@@ -1081,8 +1290,8 @@ mlxsw_afa_block_append_drop_with_cookie(struct mlxsw_afa_block *block,
}
cookie_index = cookie_ref->cookie->cookie_index;
- act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAPWU_CODE,
- MLXSW_AFA_TRAPWU_SIZE);
+ act = mlxsw_afa_block_append_action_trap(block, MLXSW_AFA_TRAPWU_CODE,
+ MLXSW_AFA_TRAPWU_SIZE);
if (IS_ERR(act)) {
NL_SET_ERR_MSG_MOD(extack, "Cannot append drop with cookie action");
err = PTR_ERR(act);
@@ -1113,8 +1322,9 @@ EXPORT_SYMBOL(mlxsw_afa_block_append_drop);
int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id)
{
- char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAP_CODE,
- MLXSW_AFA_TRAP_SIZE);
+ char *act = mlxsw_afa_block_append_action_trap(block,
+ MLXSW_AFA_TRAP_CODE,
+ MLXSW_AFA_TRAP_SIZE);
if (IS_ERR(act))
return PTR_ERR(act);
@@ -1127,8 +1337,9 @@ EXPORT_SYMBOL(mlxsw_afa_block_append_trap);
int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
u16 trap_id)
{
- char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAP_CODE,
- MLXSW_AFA_TRAP_SIZE);
+ char *act = mlxsw_afa_block_append_action_trap(block,
+ MLXSW_AFA_TRAP_CODE,
+ MLXSW_AFA_TRAP_SIZE);
if (IS_ERR(act))
return PTR_ERR(act);
@@ -1199,9 +1410,10 @@ static int
mlxsw_afa_block_append_allocated_mirror(struct mlxsw_afa_block *block,
u8 mirror_agent)
{
- char *act = mlxsw_afa_block_append_action(block,
- MLXSW_AFA_TRAP_CODE,
- MLXSW_AFA_TRAP_SIZE);
+ char *act = mlxsw_afa_block_append_action_trap(block,
+ MLXSW_AFA_TRAP_CODE,
+ MLXSW_AFA_TRAP_SIZE);
+
if (IS_ERR(act))
return PTR_ERR(act);
mlxsw_afa_trap_pack(act, MLXSW_AFA_TRAP_TRAP_ACTION_NOP,
@@ -1496,6 +1708,19 @@ EXPORT_SYMBOL(mlxsw_afa_block_append_fwd);
#define MLXSW_AFA_POLCNT_CODE 0x08
#define MLXSW_AFA_POLCNT_SIZE 1
+enum {
+ MLXSW_AFA_POLCNT_COUNTER,
+ MLXSW_AFA_POLCNT_POLICER,
+};
+
+/* afa_polcnt_c_p
+ * Counter or policer.
+ * Indicates whether the action binds a policer or a counter to the flow.
+ * 0: Counter
+ * 1: Policer
+ */
+MLXSW_ITEM32(afa, polcnt, c_p, 0x00, 31, 1);
+
enum mlxsw_afa_polcnt_counter_set_type {
/* No count */
MLXSW_AFA_POLCNT_COUNTER_SET_TYPE_NO_COUNT = 0x00,
@@ -1515,15 +1740,28 @@ MLXSW_ITEM32(afa, polcnt, counter_set_type, 0x04, 24, 8);
*/
MLXSW_ITEM32(afa, polcnt, counter_index, 0x04, 0, 24);
+/* afa_polcnt_pid
+ * Policer ID.
+ * Reserved when c_p = 0
+ */
+MLXSW_ITEM32(afa, polcnt, pid, 0x08, 0, 14);
+
static inline void
mlxsw_afa_polcnt_pack(char *payload,
enum mlxsw_afa_polcnt_counter_set_type set_type,
u32 counter_index)
{
+ mlxsw_afa_polcnt_c_p_set(payload, MLXSW_AFA_POLCNT_COUNTER);
mlxsw_afa_polcnt_counter_set_type_set(payload, set_type);
mlxsw_afa_polcnt_counter_index_set(payload, counter_index);
}
+static void mlxsw_afa_polcnt_policer_pack(char *payload, u16 policer_index)
+{
+ mlxsw_afa_polcnt_c_p_set(payload, MLXSW_AFA_POLCNT_POLICER);
+ mlxsw_afa_polcnt_pid_set(payload, policer_index);
+}
+
int mlxsw_afa_block_append_allocated_counter(struct mlxsw_afa_block *block,
u32 counter_index)
{
@@ -1567,6 +1805,40 @@ err_append_allocated_counter:
}
EXPORT_SYMBOL(mlxsw_afa_block_append_counter);
+int mlxsw_afa_block_append_police(struct mlxsw_afa_block *block,
+ u32 fa_index, u64 rate_bytes_ps, u32 burst,
+ u16 *p_policer_index,
+ struct netlink_ext_ack *extack)
+{
+ struct mlxsw_afa_policer_ref *policer_ref;
+ char *act;
+ int err;
+
+ policer_ref = mlxsw_afa_policer_ref_create(block, fa_index,
+ rate_bytes_ps,
+ burst, extack);
+ if (IS_ERR(policer_ref))
+ return PTR_ERR(policer_ref);
+ *p_policer_index = policer_ref->policer->policer_index;
+
+ act = mlxsw_afa_block_append_action_ext(block, MLXSW_AFA_POLCNT_CODE,
+ MLXSW_AFA_POLCNT_SIZE,
+ MLXSW_AFA_ACTION_TYPE_POLICE);
+ if (IS_ERR(act)) {
+ NL_SET_ERR_MSG_MOD(extack, "Cannot append police action");
+ err = PTR_ERR(act);
+ goto err_append_action;
+ }
+ mlxsw_afa_polcnt_policer_pack(act, *p_policer_index);
+
+ return 0;
+
+err_append_action:
+ mlxsw_afa_policer_ref_destroy(block, policer_ref);
+ return err;
+}
+EXPORT_SYMBOL(mlxsw_afa_block_append_police);
+
/* Virtual Router and Forwarding Domain Action
* -------------------------------------------
* Virtual Switch action is used for manipulate the Virtual Router (VR),
@@ -1684,3 +1956,54 @@ int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
return 0;
}
EXPORT_SYMBOL(mlxsw_afa_block_append_mcrouter);
+
+/* L4 Port Action
+ * --------------
+ * The L4_PORT_ACTION is used for modifying the sport and dport fields of the packet, e.g. for NAT.
+ * If (the L4 is TCP) or if (the L4 is UDP and checksum field!=0) then the L4 checksum is updated.
+ */
+
+#define MLXSW_AFA_L4PORT_CODE 0x12
+#define MLXSW_AFA_L4PORT_SIZE 1
+
+enum mlxsw_afa_l4port_s_d {
+ /* configure src_l4_port */
+ MLXSW_AFA_L4PORT_S_D_SRC,
+ /* configure dst_l4_port */
+ MLXSW_AFA_L4PORT_S_D_DST,
+};
+
+/* afa_l4port_s_d
+ * Source or destination.
+ */
+MLXSW_ITEM32(afa, l4port, s_d, 0x00, 31, 1);
+
+/* afa_l4port_l4_port
+ * Number of port to change to.
+ */
+MLXSW_ITEM32(afa, l4port, l4_port, 0x08, 0, 16);
+
+static void mlxsw_afa_l4port_pack(char *payload, enum mlxsw_afa_l4port_s_d s_d, u16 l4_port)
+{
+ mlxsw_afa_l4port_s_d_set(payload, s_d);
+ mlxsw_afa_l4port_l4_port_set(payload, l4_port);
+}
+
+int mlxsw_afa_block_append_l4port(struct mlxsw_afa_block *block, bool is_dport, u16 l4_port,
+ struct netlink_ext_ack *extack)
+{
+ enum mlxsw_afa_l4port_s_d s_d = is_dport ? MLXSW_AFA_L4PORT_S_D_DST :
+ MLXSW_AFA_L4PORT_S_D_SRC;
+ char *act = mlxsw_afa_block_append_action(block,
+ MLXSW_AFA_L4PORT_CODE,
+ MLXSW_AFA_L4PORT_SIZE);
+
+ if (IS_ERR(act)) {
+ NL_SET_ERR_MSG_MOD(extack, "Cannot append L4_PORT action");
+ return PTR_ERR(act);
+ }
+
+ mlxsw_afa_l4port_pack(act, s_d, l4_port);
+ return 0;
+}
+EXPORT_SYMBOL(mlxsw_afa_block_append_l4port);
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 8c2705e16ef7..b652497b1002 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
@@ -26,6 +26,10 @@ struct mlxsw_afa_ops {
bool ingress, int *p_span_id);
void (*mirror_del)(void *priv, u8 local_in_port, int span_id,
bool ingress);
+ int (*policer_add)(void *priv, u64 rate_bytes_ps, u32 burst,
+ u16 *p_policer_index,
+ struct netlink_ext_ack *extack);
+ void (*policer_del)(void *priv, u16 policer_index);
bool dummy_first_set;
};
@@ -82,5 +86,11 @@ int mlxsw_afa_block_append_fid_set(struct mlxsw_afa_block *block, u16 fid,
int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
u16 expected_irif, u16 min_mtu,
bool rmid_valid, u32 kvdl_index);
+int mlxsw_afa_block_append_l4port(struct mlxsw_afa_block *block, bool is_dport, u16 l4_port,
+ struct netlink_ext_ack *extack);
+int mlxsw_afa_block_append_police(struct mlxsw_afa_block *block,
+ u32 fa_index, u64 rate_bytes_ps, u32 burst,
+ u16 *p_policer_index,
+ struct netlink_ext_ack *extack);
#endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
index a7d86df7123f..44fa02cbb683 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
@@ -11,7 +11,7 @@
#include "reg.h"
static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id,
- bool *qsfp)
+ bool *qsfp, bool *cmis)
{
char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE];
char mcia_pl[MLXSW_REG_MCIA_LEN];
@@ -25,15 +25,19 @@ static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id,
return err;
mlxsw_reg_mcia_eeprom_memcpy_from(mcia_pl, eeprom_tmp);
ident = eeprom_tmp[0];
+ *cmis = false;
switch (ident) {
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_SFP:
*qsfp = false;
break;
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP: /* fall-through */
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_PLUS: /* fall-through */
- case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP28: /* fall-through */
+ case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP28:
+ *qsfp = true;
+ break;
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_DD:
*qsfp = true;
+ *cmis = true;
break;
default:
return -EINVAL;
@@ -70,8 +74,9 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module,
if (qsfp) {
/* When reading upper pages 1, 2 and 3 the offset
* starts at 128. Please refer to "QSFP+ Memory Map"
- * figure in SFF-8436 specification for graphical
- * depiction.
+ * figure in SFF-8436 specification and to "CMIS Module
+ * Memory Map" figure in CMIS specification for
+ * graphical depiction.
*/
page = MLXSW_REG_MCIA_PAGE_GET(offset);
offset -= MLXSW_REG_MCIA_EEPROM_UP_PAGE_LENGTH * page;
@@ -116,7 +121,8 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
char mcia_pl[MLXSW_REG_MCIA_LEN] = {0};
char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int module_temp;
- bool qsfp;
+ bool qsfp, cmis;
+ int page;
int err;
mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
@@ -140,21 +146,28 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
*/
/* Validate module identifier value. */
- err = mlxsw_env_validate_cable_ident(core, module, &qsfp);
+ err = mlxsw_env_validate_cable_ident(core, module, &qsfp, &cmis);
if (err)
return err;
- if (qsfp)
- mlxsw_reg_mcia_pack(mcia_pl, module, 0,
- MLXSW_REG_MCIA_TH_PAGE_NUM,
+ if (qsfp) {
+ /* For QSFP/CMIS module-defined thresholds are located in page
+ * 02h, otherwise in page 03h.
+ */
+ if (cmis)
+ page = MLXSW_REG_MCIA_TH_PAGE_CMIS_NUM;
+ else
+ page = MLXSW_REG_MCIA_TH_PAGE_NUM;
+ mlxsw_reg_mcia_pack(mcia_pl, module, 0, page,
MLXSW_REG_MCIA_TH_PAGE_OFF + off,
MLXSW_REG_MCIA_TH_ITEM_SIZE,
MLXSW_REG_MCIA_I2C_ADDR_LOW);
- else
+ } else {
mlxsw_reg_mcia_pack(mcia_pl, module, 0,
MLXSW_REG_MCIA_PAGE0_LO,
off, MLXSW_REG_MCIA_TH_ITEM_SIZE,
MLXSW_REG_MCIA_I2C_ADDR_HIGH);
+ }
err = mlxsw_reg_query(core, MLXSW_REG(mcia), mcia_pl);
if (err)
@@ -221,6 +234,22 @@ int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module,
else
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN / 2;
break;
+ case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_DD:
+ /* Use SFF_8636 as base type. ethtool should recognize specific
+ * type through the identifier value.
+ */
+ modinfo->type = ETH_MODULE_SFF_8636;
+ /* Verify if module EEPROM is a flat memory. In case of flat
+ * memory only page 00h (0-255 bytes) can be read. Otherwise
+ * upper pages 01h and 02h can also be read. Upper pages 10h
+ * and 11h are currently not supported by the driver.
+ */
+ if (module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_TYPE_ID] &
+ MLXSW_REG_MCIA_EEPROM_CMIS_FLAT_MEMORY)
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
+ else
+ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+ break;
default:
return -EINVAL;
}
@@ -235,8 +264,8 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev,
{
int offset = ee->offset;
unsigned int read_size;
+ bool qsfp, cmis;
int i = 0;
- bool qsfp;
int err;
if (!ee->len)
@@ -244,7 +273,7 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
/* Validate module identifier value. */
- err = mlxsw_env_validate_cable_ident(mlxsw_core, module, &qsfp);
+ err = mlxsw_env_validate_cable_ident(mlxsw_core, module, &qsfp, &cmis);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
index c4caeeadcba9..c010db2c9dba 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
@@ -164,8 +164,8 @@ mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u8 local_port, u8 module)
int err;
err = mlxsw_core_port_init(mlxsw_m->core, local_port,
- module + 1, false, 0,
- mlxsw_m->base_mac,
+ module + 1, false, 0, false,
+ 0, mlxsw_m->base_mac,
sizeof(mlxsw_m->base_mac));
if (err) {
dev_err(mlxsw_m->bus_info->dev, "Port %d: Failed to init core port\n",
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index c04ec1a92826..1c64b03ff48e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -547,9 +547,9 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
{
struct pci_dev *pdev = mlxsw_pci->pdev;
struct mlxsw_pci_queue_elem_info *elem_info;
+ struct mlxsw_rx_info rx_info = {};
char *wqe;
struct sk_buff *skb;
- struct mlxsw_rx_info rx_info;
u16 byte_count;
int err;
@@ -582,6 +582,10 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
if (mlxsw_pci->max_cqe_ver >= MLXSW_PCI_CQE_V2)
cookie_index = mlxsw_pci_cqe2_user_def_val_orig_pkt_len_get(cqe);
mlxsw_skb_cb(skb)->cookie_index = cookie_index;
+ } else if (rx_info.trap_id >= MLXSW_TRAP_ID_MIRROR_SESSION0 &&
+ rx_info.trap_id <= MLXSW_TRAP_ID_MIRROR_SESSION7 &&
+ mlxsw_pci->max_cqe_ver >= MLXSW_PCI_CQE_V2) {
+ rx_info.mirror_reason = mlxsw_pci_cqe2_mirror_reason_get(cqe);
}
byte_count = mlxsw_pci_cqe_byte_count_get(cqe);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
index 32c7cabfb261..a2c1fbd3e0d1 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
@@ -176,7 +176,7 @@ MLXSW_ITEM32(pci, cqe, byte_count, 0x04, 0, 14);
/* pci_cqe_trap_id
* Trap ID that captured the packet.
*/
-MLXSW_ITEM32(pci, cqe, trap_id, 0x08, 0, 9);
+MLXSW_ITEM32(pci, cqe, trap_id, 0x08, 0, 10);
/* pci_cqe_crc
* Length include CRC. Indicates the length field includes
@@ -213,6 +213,11 @@ mlxsw_pci_cqe_item_helpers(dqn, 0, 12, 12);
*/
MLXSW_ITEM32(pci, cqe2, user_def_val_orig_pkt_len, 0x14, 0, 20);
+/* pci_cqe_mirror_reason
+ * Mirror reason.
+ */
+MLXSW_ITEM32(pci, cqe2, mirror_reason, 0x18, 24, 8);
+
/* pci_cqe_owner
* Ownership bit.
*/
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 8ac987c8c8bc..079b080de7f7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -3405,11 +3405,20 @@ MLXSW_ITEM32(reg, qpcr, violate_action, 0x18, 0, 4);
*/
MLXSW_ITEM64(reg, qpcr, violate_count, 0x20, 0, 64);
+/* Packets */
#define MLXSW_REG_QPCR_LOWEST_CIR 1
#define MLXSW_REG_QPCR_HIGHEST_CIR (2 * 1000 * 1000 * 1000) /* 2Gpps */
#define MLXSW_REG_QPCR_LOWEST_CBS 4
#define MLXSW_REG_QPCR_HIGHEST_CBS 24
+/* Bandwidth */
+#define MLXSW_REG_QPCR_LOWEST_CIR_BITS 1024 /* bps */
+#define MLXSW_REG_QPCR_HIGHEST_CIR_BITS 2000000000000ULL /* 2Tbps */
+#define MLXSW_REG_QPCR_LOWEST_CBS_BITS_SP1 4
+#define MLXSW_REG_QPCR_LOWEST_CBS_BITS_SP2 4
+#define MLXSW_REG_QPCR_HIGHEST_CBS_BITS_SP1 25
+#define MLXSW_REG_QPCR_HIGHEST_CBS_BITS_SP2 31
+
static inline void mlxsw_reg_qpcr_pack(char *payload, u16 pid,
enum mlxsw_reg_qpcr_ir_units ir_units,
bool bytes, u32 cir, u16 cbs)
@@ -5438,6 +5447,56 @@ static inline void mlxsw_reg_pplr_pack(char *payload, u8 local_port,
MLXSW_REG_PPLR_LB_TYPE_BIT_PHY_LOCAL : 0);
}
+/* PDDR - Port Diagnostics Database Register
+ * -----------------------------------------
+ * The PDDR enables to read the Phy debug database
+ */
+#define MLXSW_REG_PDDR_ID 0x5031
+#define MLXSW_REG_PDDR_LEN 0x100
+
+MLXSW_REG_DEFINE(pddr, MLXSW_REG_PDDR_ID, MLXSW_REG_PDDR_LEN);
+
+/* reg_pddr_local_port
+ * Local port number.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, pddr, local_port, 0x00, 16, 8);
+
+enum mlxsw_reg_pddr_page_select {
+ MLXSW_REG_PDDR_PAGE_SELECT_TROUBLESHOOTING_INFO = 1,
+};
+
+/* reg_pddr_page_select
+ * Page select index.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, pddr, page_select, 0x04, 0, 8);
+
+enum mlxsw_reg_pddr_trblsh_group_opcode {
+ /* Monitor opcodes */
+ MLXSW_REG_PDDR_TRBLSH_GROUP_OPCODE_MONITOR,
+};
+
+/* reg_pddr_group_opcode
+ * Group selector.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, pddr, trblsh_group_opcode, 0x08, 0, 16);
+
+/* reg_pddr_status_opcode
+ * Group selector.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, pddr, trblsh_status_opcode, 0x0C, 0, 16);
+
+static inline void mlxsw_reg_pddr_pack(char *payload, u8 local_port,
+ u8 page_select)
+{
+ MLXSW_REG_ZERO(pddr, payload);
+ mlxsw_reg_pddr_local_port_set(payload, local_port);
+ mlxsw_reg_pddr_page_select_set(payload, page_select);
+}
+
/* PMTM - Port Module Type Mapping Register
* ----------------------------------------
* The PMTM allows query or configuration of module types.
@@ -5555,6 +5614,7 @@ enum mlxsw_reg_htgt_trap_group {
MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_EXCEPTIONS,
MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS,
MLXSW_REG_HTGT_TRAP_GROUP_SP_ACL_DISCARDS,
+ MLXSW_REG_HTGT_TRAP_GROUP_SP_BUFFER_DISCARDS,
__MLXSW_REG_HTGT_TRAP_GROUP_MAX,
MLXSW_REG_HTGT_TRAP_GROUP_MAX = __MLXSW_REG_HTGT_TRAP_GROUP_MAX - 1
@@ -5729,7 +5789,7 @@ MLXSW_ITEM32(reg, hpkt, trap_group, 0x00, 12, 6);
* Note: A trap ID can only be associated with a single trap group. The device
* will associate the trap ID with the last trap group configured.
*/
-MLXSW_ITEM32(reg, hpkt, trap_id, 0x00, 0, 9);
+MLXSW_ITEM32(reg, hpkt, trap_id, 0x00, 0, 10);
enum {
MLXSW_REG_HPKT_CTRL_PACKET_DEFAULT,
@@ -8547,8 +8607,10 @@ MLXSW_ITEM32(reg, mcia, size, 0x08, 0, 16);
#define MLXSW_REG_MCIA_PAGE0_LO_OFF 0xa0
#define MLXSW_REG_MCIA_TH_ITEM_SIZE 2
#define MLXSW_REG_MCIA_TH_PAGE_NUM 3
+#define MLXSW_REG_MCIA_TH_PAGE_CMIS_NUM 2
#define MLXSW_REG_MCIA_PAGE0_LO 0
#define MLXSW_REG_MCIA_TH_PAGE_OFF 0x80
+#define MLXSW_REG_MCIA_EEPROM_CMIS_FLAT_MEMORY BIT(7)
enum mlxsw_reg_mcia_eeprom_module_info_rev_id {
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_REV_ID_UNSPC = 0x00,
@@ -8567,6 +8629,7 @@ enum mlxsw_reg_mcia_eeprom_module_info_id {
enum mlxsw_reg_mcia_eeprom_module_info {
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID,
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_REV_ID,
+ MLXSW_REG_MCIA_EEPROM_MODULE_INFO_TYPE_ID,
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE,
};
@@ -8613,6 +8676,13 @@ MLXSW_REG_DEFINE(mpat, MLXSW_REG_MPAT_ID, MLXSW_REG_MPAT_LEN);
*/
MLXSW_ITEM32(reg, mpat, pa_id, 0x00, 28, 4);
+/* reg_mpat_session_id
+ * Mirror Session ID.
+ * Used for MIRROR_SESSION<i> trap.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpat, session_id, 0x00, 24, 4);
+
/* reg_mpat_system_port
* A unique port identifier for the final destination of the packet.
* Access: RW
@@ -8670,6 +8740,18 @@ enum mlxsw_reg_mpat_span_type {
*/
MLXSW_ITEM32(reg, mpat, span_type, 0x04, 0, 4);
+/* reg_mpat_pide
+ * Policer enable.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpat, pide, 0x0C, 15, 1);
+
+/* reg_mpat_pid
+ * Policer ID.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpat, pid, 0x0C, 0, 14);
+
/* Remote SPAN - Ethernet VLAN
* - - - - - - - - - - - - - -
*/
@@ -9453,6 +9535,114 @@ MLXSW_ITEM32(reg, mogcr, ptp_iftc, 0x00, 1, 1);
*/
MLXSW_ITEM32(reg, mogcr, ptp_eftc, 0x00, 0, 1);
+/* reg_mogcr_mirroring_pid_base
+ * Base policer id for mirroring policers.
+ * Must have an even value (e.g. 1000, not 1001).
+ * Reserved when SwitchX/-2, Switch-IB/2, Spectrum-1 and Quantum.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mogcr, mirroring_pid_base, 0x0C, 0, 14);
+
+/* MPAGR - Monitoring Port Analyzer Global Register
+ * ------------------------------------------------
+ * This register is used for global port analyzer configurations.
+ * Note: This register is not supported by current FW versions for Spectrum-1.
+ */
+#define MLXSW_REG_MPAGR_ID 0x9089
+#define MLXSW_REG_MPAGR_LEN 0x0C
+
+MLXSW_REG_DEFINE(mpagr, MLXSW_REG_MPAGR_ID, MLXSW_REG_MPAGR_LEN);
+
+enum mlxsw_reg_mpagr_trigger {
+ MLXSW_REG_MPAGR_TRIGGER_EGRESS,
+ MLXSW_REG_MPAGR_TRIGGER_INGRESS,
+ MLXSW_REG_MPAGR_TRIGGER_INGRESS_WRED,
+ MLXSW_REG_MPAGR_TRIGGER_INGRESS_SHARED_BUFFER,
+ MLXSW_REG_MPAGR_TRIGGER_INGRESS_ING_CONG,
+ MLXSW_REG_MPAGR_TRIGGER_INGRESS_EGR_CONG,
+ MLXSW_REG_MPAGR_TRIGGER_EGRESS_ECN,
+ MLXSW_REG_MPAGR_TRIGGER_EGRESS_HIGH_LATENCY,
+};
+
+/* reg_mpagr_trigger
+ * Mirror trigger.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, mpagr, trigger, 0x00, 0, 4);
+
+/* reg_mpagr_pa_id
+ * Port analyzer ID.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpagr, pa_id, 0x04, 0, 4);
+
+/* reg_mpagr_probability_rate
+ * Sampling rate.
+ * Valid values are: 1 to 3.5*10^9
+ * Value of 1 means "sample all". Default is 1.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpagr, probability_rate, 0x08, 0, 32);
+
+static inline void mlxsw_reg_mpagr_pack(char *payload,
+ enum mlxsw_reg_mpagr_trigger trigger,
+ u8 pa_id, u32 probability_rate)
+{
+ MLXSW_REG_ZERO(mpagr, payload);
+ mlxsw_reg_mpagr_trigger_set(payload, trigger);
+ mlxsw_reg_mpagr_pa_id_set(payload, pa_id);
+ mlxsw_reg_mpagr_probability_rate_set(payload, probability_rate);
+}
+
+/* MOMTE - Monitoring Mirror Trigger Enable Register
+ * -------------------------------------------------
+ * This register is used to configure the mirror enable for different mirror
+ * reasons.
+ */
+#define MLXSW_REG_MOMTE_ID 0x908D
+#define MLXSW_REG_MOMTE_LEN 0x10
+
+MLXSW_REG_DEFINE(momte, MLXSW_REG_MOMTE_ID, MLXSW_REG_MOMTE_LEN);
+
+/* reg_momte_local_port
+ * Local port number.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, momte, local_port, 0x00, 16, 8);
+
+enum mlxsw_reg_momte_type {
+ MLXSW_REG_MOMTE_TYPE_WRED = 0x20,
+ MLXSW_REG_MOMTE_TYPE_SHARED_BUFFER_TCLASS = 0x31,
+ MLXSW_REG_MOMTE_TYPE_SHARED_BUFFER_TCLASS_DESCRIPTORS = 0x32,
+ MLXSW_REG_MOMTE_TYPE_SHARED_BUFFER_EGRESS_PORT = 0x33,
+ MLXSW_REG_MOMTE_TYPE_ING_CONG = 0x40,
+ MLXSW_REG_MOMTE_TYPE_EGR_CONG = 0x50,
+ MLXSW_REG_MOMTE_TYPE_ECN = 0x60,
+ MLXSW_REG_MOMTE_TYPE_HIGH_LATENCY = 0x70,
+};
+
+/* reg_momte_type
+ * Type of mirroring.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, momte, type, 0x04, 0, 8);
+
+/* reg_momte_tclass_en
+ * TClass/PG mirror enable. Each bit represents corresponding tclass.
+ * 0: disable (default)
+ * 1: enable
+ * Access: RW
+ */
+MLXSW_ITEM_BIT_ARRAY(reg, momte, tclass_en, 0x08, 0x08, 1);
+
+static inline void mlxsw_reg_momte_pack(char *payload, u8 local_port,
+ enum mlxsw_reg_momte_type type)
+{
+ MLXSW_REG_ZERO(momte, payload);
+ mlxsw_reg_momte_local_port_set(payload, local_port);
+ mlxsw_reg_momte_type_set(payload, type);
+}
+
/* MTPPPC - Time Precision Packet Port Configuration
* -------------------------------------------------
* This register serves for configuration of which PTP messages should be
@@ -10759,6 +10949,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(pbmc),
MLXSW_REG(pspa),
MLXSW_REG(pplr),
+ MLXSW_REG(pddr),
MLXSW_REG(pmtm),
MLXSW_REG(htgt),
MLXSW_REG(hpkt),
@@ -10803,6 +10994,8 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(mgpc),
MLXSW_REG(mprs),
MLXSW_REG(mogcr),
+ MLXSW_REG(mpagr),
+ MLXSW_REG(momte),
MLXSW_REG(mtpppc),
MLXSW_REG(mtpptr),
MLXSW_REG(mtptpt),
diff --git a/drivers/net/ethernet/mellanox/mlxsw/resources.h b/drivers/net/ethernet/mellanox/mlxsw/resources.h
index d62496ef299c..a56c9e19a390 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/resources.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/resources.h
@@ -47,6 +47,7 @@ enum mlxsw_res_id {
MLXSW_RES_ID_ACL_ERPT_ENTRIES_8KB,
MLXSW_RES_ID_ACL_ERPT_ENTRIES_12KB,
MLXSW_RES_ID_ACL_MAX_BF_LOG,
+ MLXSW_RES_ID_MAX_GLOBAL_POLICERS,
MLXSW_RES_ID_MAX_CPU_POLICERS,
MLXSW_RES_ID_MAX_VRS,
MLXSW_RES_ID_MAX_RIFS,
@@ -105,6 +106,7 @@ static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_ACL_ERPT_ENTRIES_8KB] = 0x2952,
[MLXSW_RES_ID_ACL_ERPT_ENTRIES_12KB] = 0x2953,
[MLXSW_RES_ID_ACL_MAX_BF_LOG] = 0x2960,
+ [MLXSW_RES_ID_MAX_GLOBAL_POLICERS] = 0x2A10,
[MLXSW_RES_ID_MAX_CPU_POLICERS] = 0x2A13,
[MLXSW_RES_ID_MAX_VRS] = 0x2C01,
[MLXSW_RES_ID_MAX_RIFS] = 0x2C02,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 029ea344ad65..fdf9aa8314b2 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -45,8 +45,8 @@
#include "../mlxfw/mlxfw.h"
#define MLXSW_SP1_FWREV_MAJOR 13
-#define MLXSW_SP1_FWREV_MINOR 2000
-#define MLXSW_SP1_FWREV_SUBMINOR 2714
+#define MLXSW_SP1_FWREV_MINOR 2007
+#define MLXSW_SP1_FWREV_SUBMINOR 1168
#define MLXSW_SP1_FWREV_CAN_RESET_MINOR 1702
static const struct mlxsw_fw_rev mlxsw_sp1_fw_rev = {
@@ -62,8 +62,8 @@ static const struct mlxsw_fw_rev mlxsw_sp1_fw_rev = {
"." __stringify(MLXSW_SP1_FWREV_SUBMINOR) ".mfa2"
#define MLXSW_SP2_FWREV_MAJOR 29
-#define MLXSW_SP2_FWREV_MINOR 2000
-#define MLXSW_SP2_FWREV_SUBMINOR 2714
+#define MLXSW_SP2_FWREV_MINOR 2007
+#define MLXSW_SP2_FWREV_SUBMINOR 1168
static const struct mlxsw_fw_rev mlxsw_sp2_fw_rev = {
.major = MLXSW_SP2_FWREV_MAJOR,
@@ -76,10 +76,24 @@ static const struct mlxsw_fw_rev mlxsw_sp2_fw_rev = {
"." __stringify(MLXSW_SP2_FWREV_MINOR) \
"." __stringify(MLXSW_SP2_FWREV_SUBMINOR) ".mfa2"
+#define MLXSW_SP3_FWREV_MAJOR 30
+#define MLXSW_SP3_FWREV_MINOR 2007
+#define MLXSW_SP3_FWREV_SUBMINOR 1168
+
+static const struct mlxsw_fw_rev mlxsw_sp3_fw_rev = {
+ .major = MLXSW_SP3_FWREV_MAJOR,
+ .minor = MLXSW_SP3_FWREV_MINOR,
+ .subminor = MLXSW_SP3_FWREV_SUBMINOR,
+};
+
+#define MLXSW_SP3_FW_FILENAME \
+ "mellanox/mlxsw_spectrum3-" __stringify(MLXSW_SP3_FWREV_MAJOR) \
+ "." __stringify(MLXSW_SP3_FWREV_MINOR) \
+ "." __stringify(MLXSW_SP3_FWREV_SUBMINOR) ".mfa2"
+
static const char mlxsw_sp1_driver_name[] = "mlxsw_spectrum";
static const char mlxsw_sp2_driver_name[] = "mlxsw_spectrum2";
static const char mlxsw_sp3_driver_name[] = "mlxsw_spectrum3";
-static const char mlxsw_sp_driver_version[] = "1.0";
static const unsigned char mlxsw_sp1_mac_mask[ETH_ALEN] = {
0xff, 0xff, 0xff, 0xff, 0xfc, 0x00
@@ -161,43 +175,6 @@ struct mlxsw_sp_mlxfw_dev {
struct mlxsw_sp *mlxsw_sp;
};
-struct mlxsw_sp_ptp_ops {
- struct mlxsw_sp_ptp_clock *
- (*clock_init)(struct mlxsw_sp *mlxsw_sp, struct device *dev);
- void (*clock_fini)(struct mlxsw_sp_ptp_clock *clock);
-
- struct mlxsw_sp_ptp_state *(*init)(struct mlxsw_sp *mlxsw_sp);
- void (*fini)(struct mlxsw_sp_ptp_state *ptp_state);
-
- /* Notify a driver that a packet that might be PTP was received. Driver
- * is responsible for freeing the passed-in SKB.
- */
- void (*receive)(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
- u8 local_port);
-
- /* Notify a driver that a timestamped packet was transmitted. Driver
- * is responsible for freeing the passed-in SKB.
- */
- void (*transmitted)(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
- u8 local_port);
-
- int (*hwtstamp_get)(struct mlxsw_sp_port *mlxsw_sp_port,
- struct hwtstamp_config *config);
- int (*hwtstamp_set)(struct mlxsw_sp_port *mlxsw_sp_port,
- struct hwtstamp_config *config);
- void (*shaper_work)(struct work_struct *work);
- int (*get_ts_info)(struct mlxsw_sp *mlxsw_sp,
- struct ethtool_ts_info *info);
- int (*get_stats_count)(void);
- void (*get_stats_strings)(u8 **p);
- void (*get_stats)(struct mlxsw_sp_port *mlxsw_sp_port,
- u64 *data, int data_index);
-};
-
-struct mlxsw_sp_span_ops {
- u32 (*buffsize_get)(int mtu, u32 speed);
-};
-
static int mlxsw_sp_component_query(struct mlxfw_dev *mlxfw_dev,
u16 component_index, u32 *p_max_size,
u8 *p_align_bits, u16 *p_max_write_size)
@@ -580,8 +557,8 @@ static int mlxsw_sp_base_mac_get(struct mlxsw_sp *mlxsw_sp)
return 0;
}
-static int mlxsw_sp_port_admin_status_set(struct mlxsw_sp_port *mlxsw_sp_port,
- bool is_up)
+int mlxsw_sp_port_admin_status_set(struct mlxsw_sp_port *mlxsw_sp_port,
+ bool is_up)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
char paos_pl[MLXSW_REG_PAOS_LEN];
@@ -995,8 +972,8 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
}
-static int mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
- int mtu, bool pause_en)
+int mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
+ int mtu, bool pause_en)
{
u8 def_prio_tc[IEEE_8021QAZ_MAX_TCS] = {0};
bool dcb_en = !!mlxsw_sp_port->dcb.ets;
@@ -1088,8 +1065,8 @@ static int mlxsw_sp_port_get_offload_stats(int attr_id, const struct net_device
return -EINVAL;
}
-static int mlxsw_sp_port_get_stats_raw(struct net_device *dev, int grp,
- int prio, char *ppcnt_pl)
+int mlxsw_sp_port_get_stats_raw(struct net_device *dev, int grp,
+ int prio, char *ppcnt_pl)
{
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
@@ -1352,6 +1329,21 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
return 0;
}
+static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct flow_block_offload *f)
+{
+ switch (f->binder_type) {
+ case FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS:
+ return mlxsw_sp_setup_tc_block_clsact(mlxsw_sp_port, f, true);
+ case FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS:
+ return mlxsw_sp_setup_tc_block_clsact(mlxsw_sp_port, f, false);
+ case FLOW_BLOCK_BINDER_TYPE_RED_EARLY_DROP:
+ return mlxsw_sp_setup_tc_block_qevent_early_drop(mlxsw_sp_port, f);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static int mlxsw_sp_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
@@ -1547,1500 +1539,6 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
.ndo_do_ioctl = mlxsw_sp_port_ioctl,
};
-static void mlxsw_sp_port_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-
- strlcpy(drvinfo->driver, mlxsw_sp->bus_info->device_kind,
- sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, mlxsw_sp_driver_version,
- sizeof(drvinfo->version));
- snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
- "%d.%d.%d",
- mlxsw_sp->bus_info->fw_rev.major,
- mlxsw_sp->bus_info->fw_rev.minor,
- mlxsw_sp->bus_info->fw_rev.subminor);
- strlcpy(drvinfo->bus_info, mlxsw_sp->bus_info->device_name,
- sizeof(drvinfo->bus_info));
-}
-
-static void mlxsw_sp_port_get_pauseparam(struct net_device *dev,
- struct ethtool_pauseparam *pause)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
-
- pause->rx_pause = mlxsw_sp_port->link.rx_pause;
- pause->tx_pause = mlxsw_sp_port->link.tx_pause;
-}
-
-static int mlxsw_sp_port_pause_set(struct mlxsw_sp_port *mlxsw_sp_port,
- struct ethtool_pauseparam *pause)
-{
- char pfcc_pl[MLXSW_REG_PFCC_LEN];
-
- mlxsw_reg_pfcc_pack(pfcc_pl, mlxsw_sp_port->local_port);
- mlxsw_reg_pfcc_pprx_set(pfcc_pl, pause->rx_pause);
- mlxsw_reg_pfcc_pptx_set(pfcc_pl, pause->tx_pause);
-
- return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pfcc),
- pfcc_pl);
-}
-
-static int mlxsw_sp_port_set_pauseparam(struct net_device *dev,
- struct ethtool_pauseparam *pause)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
- bool pause_en = pause->tx_pause || pause->rx_pause;
- int err;
-
- if (mlxsw_sp_port->dcb.pfc && mlxsw_sp_port->dcb.pfc->pfc_en) {
- netdev_err(dev, "PFC already enabled on port\n");
- return -EINVAL;
- }
-
- if (pause->autoneg) {
- netdev_err(dev, "PAUSE frames autonegotiation isn't supported\n");
- return -EINVAL;
- }
-
- err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
- if (err) {
- netdev_err(dev, "Failed to configure port's headroom\n");
- return err;
- }
-
- err = mlxsw_sp_port_pause_set(mlxsw_sp_port, pause);
- if (err) {
- netdev_err(dev, "Failed to set PAUSE parameters\n");
- goto err_port_pause_configure;
- }
-
- mlxsw_sp_port->link.rx_pause = pause->rx_pause;
- mlxsw_sp_port->link.tx_pause = pause->tx_pause;
-
- return 0;
-
-err_port_pause_configure:
- pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
- mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
- return err;
-}
-
-struct mlxsw_sp_port_hw_stats {
- char str[ETH_GSTRING_LEN];
- u64 (*getter)(const char *payload);
- bool cells_bytes;
-};
-
-static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = {
- {
- .str = "a_frames_transmitted_ok",
- .getter = mlxsw_reg_ppcnt_a_frames_transmitted_ok_get,
- },
- {
- .str = "a_frames_received_ok",
- .getter = mlxsw_reg_ppcnt_a_frames_received_ok_get,
- },
- {
- .str = "a_frame_check_sequence_errors",
- .getter = mlxsw_reg_ppcnt_a_frame_check_sequence_errors_get,
- },
- {
- .str = "a_alignment_errors",
- .getter = mlxsw_reg_ppcnt_a_alignment_errors_get,
- },
- {
- .str = "a_octets_transmitted_ok",
- .getter = mlxsw_reg_ppcnt_a_octets_transmitted_ok_get,
- },
- {
- .str = "a_octets_received_ok",
- .getter = mlxsw_reg_ppcnt_a_octets_received_ok_get,
- },
- {
- .str = "a_multicast_frames_xmitted_ok",
- .getter = mlxsw_reg_ppcnt_a_multicast_frames_xmitted_ok_get,
- },
- {
- .str = "a_broadcast_frames_xmitted_ok",
- .getter = mlxsw_reg_ppcnt_a_broadcast_frames_xmitted_ok_get,
- },
- {
- .str = "a_multicast_frames_received_ok",
- .getter = mlxsw_reg_ppcnt_a_multicast_frames_received_ok_get,
- },
- {
- .str = "a_broadcast_frames_received_ok",
- .getter = mlxsw_reg_ppcnt_a_broadcast_frames_received_ok_get,
- },
- {
- .str = "a_in_range_length_errors",
- .getter = mlxsw_reg_ppcnt_a_in_range_length_errors_get,
- },
- {
- .str = "a_out_of_range_length_field",
- .getter = mlxsw_reg_ppcnt_a_out_of_range_length_field_get,
- },
- {
- .str = "a_frame_too_long_errors",
- .getter = mlxsw_reg_ppcnt_a_frame_too_long_errors_get,
- },
- {
- .str = "a_symbol_error_during_carrier",
- .getter = mlxsw_reg_ppcnt_a_symbol_error_during_carrier_get,
- },
- {
- .str = "a_mac_control_frames_transmitted",
- .getter = mlxsw_reg_ppcnt_a_mac_control_frames_transmitted_get,
- },
- {
- .str = "a_mac_control_frames_received",
- .getter = mlxsw_reg_ppcnt_a_mac_control_frames_received_get,
- },
- {
- .str = "a_unsupported_opcodes_received",
- .getter = mlxsw_reg_ppcnt_a_unsupported_opcodes_received_get,
- },
- {
- .str = "a_pause_mac_ctrl_frames_received",
- .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_received_get,
- },
- {
- .str = "a_pause_mac_ctrl_frames_xmitted",
- .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_transmitted_get,
- },
-};
-
-#define MLXSW_SP_PORT_HW_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_stats)
-
-static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2863_stats[] = {
- {
- .str = "if_in_discards",
- .getter = mlxsw_reg_ppcnt_if_in_discards_get,
- },
- {
- .str = "if_out_discards",
- .getter = mlxsw_reg_ppcnt_if_out_discards_get,
- },
- {
- .str = "if_out_errors",
- .getter = mlxsw_reg_ppcnt_if_out_errors_get,
- },
-};
-
-#define MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN \
- ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2863_stats)
-
-static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2819_stats[] = {
- {
- .str = "ether_stats_undersize_pkts",
- .getter = mlxsw_reg_ppcnt_ether_stats_undersize_pkts_get,
- },
- {
- .str = "ether_stats_oversize_pkts",
- .getter = mlxsw_reg_ppcnt_ether_stats_oversize_pkts_get,
- },
- {
- .str = "ether_stats_fragments",
- .getter = mlxsw_reg_ppcnt_ether_stats_fragments_get,
- },
- {
- .str = "ether_pkts64octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts64octets_get,
- },
- {
- .str = "ether_pkts65to127octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts65to127octets_get,
- },
- {
- .str = "ether_pkts128to255octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts128to255octets_get,
- },
- {
- .str = "ether_pkts256to511octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts256to511octets_get,
- },
- {
- .str = "ether_pkts512to1023octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts512to1023octets_get,
- },
- {
- .str = "ether_pkts1024to1518octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts1024to1518octets_get,
- },
- {
- .str = "ether_pkts1519to2047octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts1519to2047octets_get,
- },
- {
- .str = "ether_pkts2048to4095octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts2048to4095octets_get,
- },
- {
- .str = "ether_pkts4096to8191octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts4096to8191octets_get,
- },
- {
- .str = "ether_pkts8192to10239octets",
- .getter = mlxsw_reg_ppcnt_ether_stats_pkts8192to10239octets_get,
- },
-};
-
-#define MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN \
- ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2819_stats)
-
-static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_3635_stats[] = {
- {
- .str = "dot3stats_fcs_errors",
- .getter = mlxsw_reg_ppcnt_dot3stats_fcs_errors_get,
- },
- {
- .str = "dot3stats_symbol_errors",
- .getter = mlxsw_reg_ppcnt_dot3stats_symbol_errors_get,
- },
- {
- .str = "dot3control_in_unknown_opcodes",
- .getter = mlxsw_reg_ppcnt_dot3control_in_unknown_opcodes_get,
- },
- {
- .str = "dot3in_pause_frames",
- .getter = mlxsw_reg_ppcnt_dot3in_pause_frames_get,
- },
-};
-
-#define MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN \
- ARRAY_SIZE(mlxsw_sp_port_hw_rfc_3635_stats)
-
-static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_ext_stats[] = {
- {
- .str = "ecn_marked",
- .getter = mlxsw_reg_ppcnt_ecn_marked_get,
- },
-};
-
-#define MLXSW_SP_PORT_HW_EXT_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_ext_stats)
-
-static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_discard_stats[] = {
- {
- .str = "discard_ingress_general",
- .getter = mlxsw_reg_ppcnt_ingress_general_get,
- },
- {
- .str = "discard_ingress_policy_engine",
- .getter = mlxsw_reg_ppcnt_ingress_policy_engine_get,
- },
- {
- .str = "discard_ingress_vlan_membership",
- .getter = mlxsw_reg_ppcnt_ingress_vlan_membership_get,
- },
- {
- .str = "discard_ingress_tag_frame_type",
- .getter = mlxsw_reg_ppcnt_ingress_tag_frame_type_get,
- },
- {
- .str = "discard_egress_vlan_membership",
- .getter = mlxsw_reg_ppcnt_egress_vlan_membership_get,
- },
- {
- .str = "discard_loopback_filter",
- .getter = mlxsw_reg_ppcnt_loopback_filter_get,
- },
- {
- .str = "discard_egress_general",
- .getter = mlxsw_reg_ppcnt_egress_general_get,
- },
- {
- .str = "discard_egress_hoq",
- .getter = mlxsw_reg_ppcnt_egress_hoq_get,
- },
- {
- .str = "discard_egress_policy_engine",
- .getter = mlxsw_reg_ppcnt_egress_policy_engine_get,
- },
- {
- .str = "discard_ingress_tx_link_down",
- .getter = mlxsw_reg_ppcnt_ingress_tx_link_down_get,
- },
- {
- .str = "discard_egress_stp_filter",
- .getter = mlxsw_reg_ppcnt_egress_stp_filter_get,
- },
- {
- .str = "discard_egress_sll",
- .getter = mlxsw_reg_ppcnt_egress_sll_get,
- },
-};
-
-#define MLXSW_SP_PORT_HW_DISCARD_STATS_LEN \
- ARRAY_SIZE(mlxsw_sp_port_hw_discard_stats)
-
-static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = {
- {
- .str = "rx_octets_prio",
- .getter = mlxsw_reg_ppcnt_rx_octets_get,
- },
- {
- .str = "rx_frames_prio",
- .getter = mlxsw_reg_ppcnt_rx_frames_get,
- },
- {
- .str = "tx_octets_prio",
- .getter = mlxsw_reg_ppcnt_tx_octets_get,
- },
- {
- .str = "tx_frames_prio",
- .getter = mlxsw_reg_ppcnt_tx_frames_get,
- },
- {
- .str = "rx_pause_prio",
- .getter = mlxsw_reg_ppcnt_rx_pause_get,
- },
- {
- .str = "rx_pause_duration_prio",
- .getter = mlxsw_reg_ppcnt_rx_pause_duration_get,
- },
- {
- .str = "tx_pause_prio",
- .getter = mlxsw_reg_ppcnt_tx_pause_get,
- },
- {
- .str = "tx_pause_duration_prio",
- .getter = mlxsw_reg_ppcnt_tx_pause_duration_get,
- },
-};
-
-#define MLXSW_SP_PORT_HW_PRIO_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_prio_stats)
-
-static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = {
- {
- .str = "tc_transmit_queue_tc",
- .getter = mlxsw_reg_ppcnt_tc_transmit_queue_get,
- .cells_bytes = true,
- },
- {
- .str = "tc_no_buffer_discard_uc_tc",
- .getter = mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get,
- },
-};
-
-#define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats)
-
-#define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \
- MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN + \
- MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN + \
- MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN + \
- MLXSW_SP_PORT_HW_EXT_STATS_LEN + \
- MLXSW_SP_PORT_HW_DISCARD_STATS_LEN + \
- (MLXSW_SP_PORT_HW_PRIO_STATS_LEN * \
- IEEE_8021QAZ_MAX_TCS) + \
- (MLXSW_SP_PORT_HW_TC_STATS_LEN * \
- TC_MAX_QUEUE))
-
-static void mlxsw_sp_port_get_prio_strings(u8 **p, int prio)
-{
- int i;
-
- for (i = 0; i < MLXSW_SP_PORT_HW_PRIO_STATS_LEN; i++) {
- snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d",
- mlxsw_sp_port_hw_prio_stats[i].str, prio);
- *p += ETH_GSTRING_LEN;
- }
-}
-
-static void mlxsw_sp_port_get_tc_strings(u8 **p, int tc)
-{
- int i;
-
- for (i = 0; i < MLXSW_SP_PORT_HW_TC_STATS_LEN; i++) {
- snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d",
- mlxsw_sp_port_hw_tc_stats[i].str, tc);
- *p += ETH_GSTRING_LEN;
- }
-}
-
-static void mlxsw_sp_port_get_strings(struct net_device *dev,
- u32 stringset, u8 *data)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
- u8 *p = data;
- int i;
-
- switch (stringset) {
- case ETH_SS_STATS:
- for (i = 0; i < MLXSW_SP_PORT_HW_STATS_LEN; i++) {
- memcpy(p, mlxsw_sp_port_hw_stats[i].str,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
-
- for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN; i++) {
- memcpy(p, mlxsw_sp_port_hw_rfc_2863_stats[i].str,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
-
- for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN; i++) {
- memcpy(p, mlxsw_sp_port_hw_rfc_2819_stats[i].str,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
-
- for (i = 0; i < MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN; i++) {
- memcpy(p, mlxsw_sp_port_hw_rfc_3635_stats[i].str,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
-
- for (i = 0; i < MLXSW_SP_PORT_HW_EXT_STATS_LEN; i++) {
- memcpy(p, mlxsw_sp_port_hw_ext_stats[i].str,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
-
- for (i = 0; i < MLXSW_SP_PORT_HW_DISCARD_STATS_LEN; i++) {
- memcpy(p, mlxsw_sp_port_hw_discard_stats[i].str,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
-
- for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
- mlxsw_sp_port_get_prio_strings(&p, i);
-
- for (i = 0; i < TC_MAX_QUEUE; i++)
- mlxsw_sp_port_get_tc_strings(&p, i);
-
- mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats_strings(&p);
- break;
- }
-}
-
-static int mlxsw_sp_port_set_phys_id(struct net_device *dev,
- enum ethtool_phys_id_state state)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
- char mlcr_pl[MLXSW_REG_MLCR_LEN];
- bool active;
-
- switch (state) {
- case ETHTOOL_ID_ACTIVE:
- active = true;
- break;
- case ETHTOOL_ID_INACTIVE:
- active = false;
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- mlxsw_reg_mlcr_pack(mlcr_pl, mlxsw_sp_port->local_port, active);
- return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mlcr), mlcr_pl);
-}
-
-static int
-mlxsw_sp_get_hw_stats_by_group(struct mlxsw_sp_port_hw_stats **p_hw_stats,
- int *p_len, enum mlxsw_reg_ppcnt_grp grp)
-{
- switch (grp) {
- case MLXSW_REG_PPCNT_IEEE_8023_CNT:
- *p_hw_stats = mlxsw_sp_port_hw_stats;
- *p_len = MLXSW_SP_PORT_HW_STATS_LEN;
- break;
- case MLXSW_REG_PPCNT_RFC_2863_CNT:
- *p_hw_stats = mlxsw_sp_port_hw_rfc_2863_stats;
- *p_len = MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN;
- break;
- case MLXSW_REG_PPCNT_RFC_2819_CNT:
- *p_hw_stats = mlxsw_sp_port_hw_rfc_2819_stats;
- *p_len = MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
- break;
- case MLXSW_REG_PPCNT_RFC_3635_CNT:
- *p_hw_stats = mlxsw_sp_port_hw_rfc_3635_stats;
- *p_len = MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN;
- break;
- case MLXSW_REG_PPCNT_EXT_CNT:
- *p_hw_stats = mlxsw_sp_port_hw_ext_stats;
- *p_len = MLXSW_SP_PORT_HW_EXT_STATS_LEN;
- break;
- case MLXSW_REG_PPCNT_DISCARD_CNT:
- *p_hw_stats = mlxsw_sp_port_hw_discard_stats;
- *p_len = MLXSW_SP_PORT_HW_DISCARD_STATS_LEN;
- break;
- case MLXSW_REG_PPCNT_PRIO_CNT:
- *p_hw_stats = mlxsw_sp_port_hw_prio_stats;
- *p_len = MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
- break;
- case MLXSW_REG_PPCNT_TC_CNT:
- *p_hw_stats = mlxsw_sp_port_hw_tc_stats;
- *p_len = MLXSW_SP_PORT_HW_TC_STATS_LEN;
- break;
- default:
- WARN_ON(1);
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-static void __mlxsw_sp_port_get_stats(struct net_device *dev,
- enum mlxsw_reg_ppcnt_grp grp, int prio,
- u64 *data, int data_index)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
- struct mlxsw_sp_port_hw_stats *hw_stats;
- char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
- int i, len;
- int err;
-
- err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp);
- if (err)
- return;
- mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl);
- for (i = 0; i < len; i++) {
- data[data_index + i] = hw_stats[i].getter(ppcnt_pl);
- if (!hw_stats[i].cells_bytes)
- continue;
- data[data_index + i] = mlxsw_sp_cells_bytes(mlxsw_sp,
- data[data_index + i]);
- }
-}
-
-static void mlxsw_sp_port_get_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
- int i, data_index = 0;
-
- /* IEEE 802.3 Counters */
- __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_IEEE_8023_CNT, 0,
- data, data_index);
- data_index = MLXSW_SP_PORT_HW_STATS_LEN;
-
- /* RFC 2863 Counters */
- __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2863_CNT, 0,
- data, data_index);
- data_index += MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN;
-
- /* RFC 2819 Counters */
- __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2819_CNT, 0,
- data, data_index);
- data_index += MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
-
- /* RFC 3635 Counters */
- __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_3635_CNT, 0,
- data, data_index);
- data_index += MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN;
-
- /* Extended Counters */
- __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_EXT_CNT, 0,
- data, data_index);
- data_index += MLXSW_SP_PORT_HW_EXT_STATS_LEN;
-
- /* Discard Counters */
- __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_DISCARD_CNT, 0,
- data, data_index);
- data_index += MLXSW_SP_PORT_HW_DISCARD_STATS_LEN;
-
- /* Per-Priority Counters */
- for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
- __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_PRIO_CNT, i,
- data, data_index);
- data_index += MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
- }
-
- /* Per-TC Counters */
- for (i = 0; i < TC_MAX_QUEUE; i++) {
- __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_TC_CNT, i,
- data, data_index);
- data_index += MLXSW_SP_PORT_HW_TC_STATS_LEN;
- }
-
- /* PTP counters */
- mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats(mlxsw_sp_port,
- data, data_index);
- data_index += mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats_count();
-}
-
-static int mlxsw_sp_port_get_sset_count(struct net_device *dev, int sset)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
-
- switch (sset) {
- case ETH_SS_STATS:
- return MLXSW_SP_PORT_ETHTOOL_STATS_LEN +
- mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats_count();
- default:
- return -EOPNOTSUPP;
- }
-}
-
-struct mlxsw_sp1_port_link_mode {
- enum ethtool_link_mode_bit_indices mask_ethtool;
- u32 mask;
- u32 speed;
-};
-
-static const struct mlxsw_sp1_port_link_mode mlxsw_sp1_port_link_mode[] = {
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_100BASE_T,
- .mask_ethtool = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
- .speed = SPEED_100,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_SGMII |
- MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX,
- .mask_ethtool = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
- .speed = SPEED_1000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_T,
- .mask_ethtool = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
- .speed = SPEED_10000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CX4 |
- MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4,
- .mask_ethtool = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
- .speed = SPEED_10000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
- MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
- MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
- MLXSW_REG_PTYS_ETH_SPEED_10GBASE_ER_LR,
- .mask_ethtool = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
- .speed = SPEED_10000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_20GBASE_KR2,
- .mask_ethtool = ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
- .speed = SPEED_20000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4,
- .mask_ethtool = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
- .speed = SPEED_40000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4,
- .mask_ethtool = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
- .speed = SPEED_40000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4,
- .mask_ethtool = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
- .speed = SPEED_40000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_LR4_ER4,
- .mask_ethtool = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
- .speed = SPEED_40000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR,
- .mask_ethtool = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
- .speed = SPEED_25000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR,
- .mask_ethtool = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
- .speed = SPEED_25000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR,
- .mask_ethtool = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
- .speed = SPEED_25000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_CR2,
- .mask_ethtool = ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
- .speed = SPEED_50000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR2,
- .mask_ethtool = ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
- .speed = SPEED_50000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_SR2,
- .mask_ethtool = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
- .speed = SPEED_50000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4,
- .mask_ethtool = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
- .speed = SPEED_100000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4,
- .mask_ethtool = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
- .speed = SPEED_100000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4,
- .mask_ethtool = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
- .speed = SPEED_100000,
- },
- {
- .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4,
- .mask_ethtool = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
- .speed = SPEED_100000,
- },
-};
-
-#define MLXSW_SP1_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp1_port_link_mode)
-
-static void
-mlxsw_sp1_from_ptys_supported_port(struct mlxsw_sp *mlxsw_sp,
- u32 ptys_eth_proto,
- struct ethtool_link_ksettings *cmd)
-{
- if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
- MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
- MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4 |
- MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4 |
- MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 |
- MLXSW_REG_PTYS_ETH_SPEED_SGMII))
- ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
-
- if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
- MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4 |
- MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4 |
- MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 |
- MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX))
- ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane);
-}
-
-static void
-mlxsw_sp1_from_ptys_link(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto,
- u8 width, unsigned long *mode)
-{
- int i;
-
- for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
- if (ptys_eth_proto & mlxsw_sp1_port_link_mode[i].mask)
- __set_bit(mlxsw_sp1_port_link_mode[i].mask_ethtool,
- mode);
- }
-}
-
-static u32
-mlxsw_sp1_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto)
-{
- int i;
-
- for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
- if (ptys_eth_proto & mlxsw_sp1_port_link_mode[i].mask)
- return mlxsw_sp1_port_link_mode[i].speed;
- }
-
- return SPEED_UNKNOWN;
-}
-
-static void
-mlxsw_sp1_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
- u32 ptys_eth_proto,
- struct ethtool_link_ksettings *cmd)
-{
- cmd->base.speed = SPEED_UNKNOWN;
- cmd->base.duplex = DUPLEX_UNKNOWN;
-
- if (!carrier_ok)
- return;
-
- cmd->base.speed = mlxsw_sp1_from_ptys_speed(mlxsw_sp, ptys_eth_proto);
- if (cmd->base.speed != SPEED_UNKNOWN)
- cmd->base.duplex = DUPLEX_FULL;
-}
-
-static u32
-mlxsw_sp1_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp, u8 width,
- const struct ethtool_link_ksettings *cmd)
-{
- u32 ptys_proto = 0;
- int i;
-
- for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
- if (test_bit(mlxsw_sp1_port_link_mode[i].mask_ethtool,
- cmd->link_modes.advertising))
- ptys_proto |= mlxsw_sp1_port_link_mode[i].mask;
- }
- return ptys_proto;
-}
-
-static u32 mlxsw_sp1_to_ptys_speed(struct mlxsw_sp *mlxsw_sp, u8 width,
- u32 speed)
-{
- u32 ptys_proto = 0;
- int i;
-
- for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
- if (speed == mlxsw_sp1_port_link_mode[i].speed)
- ptys_proto |= mlxsw_sp1_port_link_mode[i].mask;
- }
- return ptys_proto;
-}
-
-static void
-mlxsw_sp1_reg_ptys_eth_pack(struct mlxsw_sp *mlxsw_sp, char *payload,
- u8 local_port, u32 proto_admin, bool autoneg)
-{
- mlxsw_reg_ptys_eth_pack(payload, local_port, proto_admin, autoneg);
-}
-
-static void
-mlxsw_sp1_reg_ptys_eth_unpack(struct mlxsw_sp *mlxsw_sp, char *payload,
- u32 *p_eth_proto_cap, u32 *p_eth_proto_admin,
- u32 *p_eth_proto_oper)
-{
- mlxsw_reg_ptys_eth_unpack(payload, p_eth_proto_cap, p_eth_proto_admin,
- p_eth_proto_oper);
-}
-
-static const struct mlxsw_sp_port_type_speed_ops
-mlxsw_sp1_port_type_speed_ops = {
- .from_ptys_supported_port = mlxsw_sp1_from_ptys_supported_port,
- .from_ptys_link = mlxsw_sp1_from_ptys_link,
- .from_ptys_speed = mlxsw_sp1_from_ptys_speed,
- .from_ptys_speed_duplex = mlxsw_sp1_from_ptys_speed_duplex,
- .to_ptys_advert_link = mlxsw_sp1_to_ptys_advert_link,
- .to_ptys_speed = mlxsw_sp1_to_ptys_speed,
- .reg_ptys_eth_pack = mlxsw_sp1_reg_ptys_eth_pack,
- .reg_ptys_eth_unpack = mlxsw_sp1_reg_ptys_eth_unpack,
-};
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_sgmii_100m[] = {
- ETHTOOL_LINK_MODE_100baseT_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_sgmii_100m)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_1000base_x_sgmii[] = {
- ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
- ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_1000base_x_sgmii)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii[] = {
- ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_2_5GBASE_X_2_5GMII_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_5gbase_r[] = {
- ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_5gbase_r)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g[] = {
- ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
- ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
- ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
- ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
- ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
- ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
- ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g[] = {
- ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
- ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
- ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
- ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr[] = {
- ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
- ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
- ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2[] = {
- ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
- ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
- ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr[] = {
- ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
- ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
- ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
- ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
- ETHTOOL_LINK_MODE_50000baseDR_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4[] = {
- ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2[] = {
- ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4[] = {
- ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT,
- ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT,
- ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
- ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT,
- ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4)
-
-static const enum ethtool_link_mode_bit_indices
-mlxsw_sp2_mask_ethtool_400gaui_8[] = {
- ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT,
- ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT,
- ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT,
- ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT,
- ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT,
-};
-
-#define MLXSW_SP2_MASK_ETHTOOL_400GAUI_8_LEN \
- ARRAY_SIZE(mlxsw_sp2_mask_ethtool_400gaui_8)
-
-#define MLXSW_SP_PORT_MASK_WIDTH_1X BIT(0)
-#define MLXSW_SP_PORT_MASK_WIDTH_2X BIT(1)
-#define MLXSW_SP_PORT_MASK_WIDTH_4X BIT(2)
-#define MLXSW_SP_PORT_MASK_WIDTH_8X BIT(3)
-
-static u8 mlxsw_sp_port_mask_width_get(u8 width)
-{
- switch (width) {
- case 1:
- return MLXSW_SP_PORT_MASK_WIDTH_1X;
- case 2:
- return MLXSW_SP_PORT_MASK_WIDTH_2X;
- case 4:
- return MLXSW_SP_PORT_MASK_WIDTH_4X;
- case 8:
- return MLXSW_SP_PORT_MASK_WIDTH_8X;
- default:
- WARN_ON_ONCE(1);
- return 0;
- }
-}
-
-struct mlxsw_sp2_port_link_mode {
- const enum ethtool_link_mode_bit_indices *mask_ethtool;
- int m_ethtool_len;
- u32 mask;
- u32 speed;
- u8 mask_width;
-};
-
-static const struct mlxsw_sp2_port_link_mode mlxsw_sp2_port_link_mode[] = {
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_SGMII_100M,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_sgmii_100m,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
- MLXSW_SP_PORT_MASK_WIDTH_2X |
- MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_100,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_1000BASE_X_SGMII,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_1000base_x_sgmii,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
- MLXSW_SP_PORT_MASK_WIDTH_2X |
- MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_1000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_2_5GBASE_X_2_5GMII,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_2_5GBASE_X_2_5GMII_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
- MLXSW_SP_PORT_MASK_WIDTH_2X |
- MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_2500,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_5GBASE_R,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_5gbase_r,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
- MLXSW_SP_PORT_MASK_WIDTH_2X |
- MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_5000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XFI_XAUI_1_10G,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
- MLXSW_SP_PORT_MASK_WIDTH_2X |
- MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_10000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XLAUI_4_XLPPI_4_40G,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_40000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
- MLXSW_SP_PORT_MASK_WIDTH_2X |
- MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_25000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_2_LAUI_2_50GBASE_CR2_KR2,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_2X |
- MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_50000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_1_LAUI_1_50GBASE_CR_KR,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X,
- .speed = SPEED_50000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_CAUI_4_100GBASE_CR4_KR4,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_100000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_100GAUI_2_100GBASE_CR2_KR2,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_2X,
- .speed = SPEED_100000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_200GAUI_4_200GBASE_CR4_KR4,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X |
- MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_200000,
- },
- {
- .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_400GAUI_8,
- .mask_ethtool = mlxsw_sp2_mask_ethtool_400gaui_8,
- .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_400GAUI_8_LEN,
- .mask_width = MLXSW_SP_PORT_MASK_WIDTH_8X,
- .speed = SPEED_400000,
- },
-};
-
-#define MLXSW_SP2_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp2_port_link_mode)
-
-static void
-mlxsw_sp2_from_ptys_supported_port(struct mlxsw_sp *mlxsw_sp,
- u32 ptys_eth_proto,
- struct ethtool_link_ksettings *cmd)
-{
- ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
- ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane);
-}
-
-static void
-mlxsw_sp2_set_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode,
- unsigned long *mode)
-{
- int i;
-
- for (i = 0; i < link_mode->m_ethtool_len; i++)
- __set_bit(link_mode->mask_ethtool[i], mode);
-}
-
-static void
-mlxsw_sp2_from_ptys_link(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto,
- u8 width, unsigned long *mode)
-{
- u8 mask_width = mlxsw_sp_port_mask_width_get(width);
- int i;
-
- for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
- if ((ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask) &&
- (mask_width & mlxsw_sp2_port_link_mode[i].mask_width))
- mlxsw_sp2_set_bit_ethtool(&mlxsw_sp2_port_link_mode[i],
- mode);
- }
-}
-
-static u32
-mlxsw_sp2_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto)
-{
- int i;
-
- for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
- if (ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask)
- return mlxsw_sp2_port_link_mode[i].speed;
- }
-
- return SPEED_UNKNOWN;
-}
-
-static void
-mlxsw_sp2_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
- u32 ptys_eth_proto,
- struct ethtool_link_ksettings *cmd)
-{
- cmd->base.speed = SPEED_UNKNOWN;
- cmd->base.duplex = DUPLEX_UNKNOWN;
-
- if (!carrier_ok)
- return;
-
- cmd->base.speed = mlxsw_sp2_from_ptys_speed(mlxsw_sp, ptys_eth_proto);
- if (cmd->base.speed != SPEED_UNKNOWN)
- cmd->base.duplex = DUPLEX_FULL;
-}
-
-static bool
-mlxsw_sp2_test_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode,
- const unsigned long *mode)
-{
- int cnt = 0;
- int i;
-
- for (i = 0; i < link_mode->m_ethtool_len; i++) {
- if (test_bit(link_mode->mask_ethtool[i], mode))
- cnt++;
- }
-
- return cnt == link_mode->m_ethtool_len;
-}
-
-static u32
-mlxsw_sp2_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp, u8 width,
- const struct ethtool_link_ksettings *cmd)
-{
- u8 mask_width = mlxsw_sp_port_mask_width_get(width);
- u32 ptys_proto = 0;
- int i;
-
- for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
- if ((mask_width & mlxsw_sp2_port_link_mode[i].mask_width) &&
- mlxsw_sp2_test_bit_ethtool(&mlxsw_sp2_port_link_mode[i],
- cmd->link_modes.advertising))
- ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
- }
- return ptys_proto;
-}
-
-static u32 mlxsw_sp2_to_ptys_speed(struct mlxsw_sp *mlxsw_sp,
- u8 width, u32 speed)
-{
- u8 mask_width = mlxsw_sp_port_mask_width_get(width);
- u32 ptys_proto = 0;
- int i;
-
- for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
- if ((speed == mlxsw_sp2_port_link_mode[i].speed) &&
- (mask_width & mlxsw_sp2_port_link_mode[i].mask_width))
- ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
- }
- return ptys_proto;
-}
-
-static void
-mlxsw_sp2_reg_ptys_eth_pack(struct mlxsw_sp *mlxsw_sp, char *payload,
- u8 local_port, u32 proto_admin,
- bool autoneg)
-{
- mlxsw_reg_ptys_ext_eth_pack(payload, local_port, proto_admin, autoneg);
-}
-
-static void
-mlxsw_sp2_reg_ptys_eth_unpack(struct mlxsw_sp *mlxsw_sp, char *payload,
- u32 *p_eth_proto_cap, u32 *p_eth_proto_admin,
- u32 *p_eth_proto_oper)
-{
- mlxsw_reg_ptys_ext_eth_unpack(payload, p_eth_proto_cap,
- p_eth_proto_admin, p_eth_proto_oper);
-}
-
-static const struct mlxsw_sp_port_type_speed_ops
-mlxsw_sp2_port_type_speed_ops = {
- .from_ptys_supported_port = mlxsw_sp2_from_ptys_supported_port,
- .from_ptys_link = mlxsw_sp2_from_ptys_link,
- .from_ptys_speed = mlxsw_sp2_from_ptys_speed,
- .from_ptys_speed_duplex = mlxsw_sp2_from_ptys_speed_duplex,
- .to_ptys_advert_link = mlxsw_sp2_to_ptys_advert_link,
- .to_ptys_speed = mlxsw_sp2_to_ptys_speed,
- .reg_ptys_eth_pack = mlxsw_sp2_reg_ptys_eth_pack,
- .reg_ptys_eth_unpack = mlxsw_sp2_reg_ptys_eth_unpack,
-};
-
-static void
-mlxsw_sp_port_get_link_supported(struct mlxsw_sp *mlxsw_sp, u32 eth_proto_cap,
- u8 width, struct ethtool_link_ksettings *cmd)
-{
- const struct mlxsw_sp_port_type_speed_ops *ops;
-
- ops = mlxsw_sp->port_type_speed_ops;
-
- ethtool_link_ksettings_add_link_mode(cmd, supported, Asym_Pause);
- ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
- ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
-
- ops->from_ptys_supported_port(mlxsw_sp, eth_proto_cap, cmd);
- ops->from_ptys_link(mlxsw_sp, eth_proto_cap, width,
- cmd->link_modes.supported);
-}
-
-static void
-mlxsw_sp_port_get_link_advertise(struct mlxsw_sp *mlxsw_sp,
- u32 eth_proto_admin, bool autoneg, u8 width,
- struct ethtool_link_ksettings *cmd)
-{
- const struct mlxsw_sp_port_type_speed_ops *ops;
-
- ops = mlxsw_sp->port_type_speed_ops;
-
- if (!autoneg)
- return;
-
- ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
- ops->from_ptys_link(mlxsw_sp, eth_proto_admin, width,
- cmd->link_modes.advertising);
-}
-
-static u8
-mlxsw_sp_port_connector_port(enum mlxsw_reg_ptys_connector_type connector_type)
-{
- switch (connector_type) {
- case MLXSW_REG_PTYS_CONNECTOR_TYPE_UNKNOWN_OR_NO_CONNECTOR:
- return PORT_OTHER;
- case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_NONE:
- return PORT_NONE;
- case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_TP:
- return PORT_TP;
- case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_AUI:
- return PORT_AUI;
- case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_BNC:
- return PORT_BNC;
- case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_MII:
- return PORT_MII;
- case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_FIBRE:
- return PORT_FIBRE;
- case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_DA:
- return PORT_DA;
- case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_OTHER:
- return PORT_OTHER;
- default:
- WARN_ON_ONCE(1);
- return PORT_OTHER;
- }
-}
-
-static int mlxsw_sp_port_get_link_ksettings(struct net_device *dev,
- struct ethtool_link_ksettings *cmd)
-{
- u32 eth_proto_cap, eth_proto_admin, eth_proto_oper;
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
- const struct mlxsw_sp_port_type_speed_ops *ops;
- char ptys_pl[MLXSW_REG_PTYS_LEN];
- u8 connector_type;
- bool autoneg;
- int err;
-
- ops = mlxsw_sp->port_type_speed_ops;
-
- autoneg = mlxsw_sp_port->link.autoneg;
- ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
- 0, false);
- err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
- if (err)
- return err;
- ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, &eth_proto_cap,
- &eth_proto_admin, &eth_proto_oper);
-
- mlxsw_sp_port_get_link_supported(mlxsw_sp, eth_proto_cap,
- mlxsw_sp_port->mapping.width, cmd);
-
- mlxsw_sp_port_get_link_advertise(mlxsw_sp, eth_proto_admin, autoneg,
- mlxsw_sp_port->mapping.width, cmd);
-
- cmd->base.autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
- connector_type = mlxsw_reg_ptys_connector_type_get(ptys_pl);
- cmd->base.port = mlxsw_sp_port_connector_port(connector_type);
- ops->from_ptys_speed_duplex(mlxsw_sp, netif_carrier_ok(dev),
- eth_proto_oper, cmd);
-
- return 0;
-}
-
-static int
-mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
- const struct ethtool_link_ksettings *cmd)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
- const struct mlxsw_sp_port_type_speed_ops *ops;
- char ptys_pl[MLXSW_REG_PTYS_LEN];
- u32 eth_proto_cap, eth_proto_new;
- bool autoneg;
- int err;
-
- ops = mlxsw_sp->port_type_speed_ops;
-
- ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
- 0, false);
- err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
- if (err)
- return err;
- ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, &eth_proto_cap, NULL, NULL);
-
- autoneg = cmd->base.autoneg == AUTONEG_ENABLE;
- eth_proto_new = autoneg ?
- ops->to_ptys_advert_link(mlxsw_sp, mlxsw_sp_port->mapping.width,
- cmd) :
- ops->to_ptys_speed(mlxsw_sp, mlxsw_sp_port->mapping.width,
- cmd->base.speed);
-
- eth_proto_new = eth_proto_new & eth_proto_cap;
- if (!eth_proto_new) {
- netdev_err(dev, "No supported speed requested\n");
- return -EINVAL;
- }
-
- ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
- eth_proto_new, autoneg);
- err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
- if (err)
- return err;
-
- mlxsw_sp_port->link.autoneg = autoneg;
-
- if (!netif_running(dev))
- return 0;
-
- mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
- mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
-
- return 0;
-}
-
-static int mlxsw_sp_get_module_info(struct net_device *netdev,
- struct ethtool_modinfo *modinfo)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
- int err;
-
- err = mlxsw_env_get_module_info(mlxsw_sp->core,
- mlxsw_sp_port->mapping.module,
- modinfo);
-
- return err;
-}
-
-static int mlxsw_sp_get_module_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *ee,
- u8 *data)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
- int err;
-
- err = mlxsw_env_get_module_eeprom(netdev, mlxsw_sp->core,
- mlxsw_sp_port->mapping.module, ee,
- data);
-
- return err;
-}
-
-static int
-mlxsw_sp_get_ts_info(struct net_device *netdev, struct ethtool_ts_info *info)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-
- return mlxsw_sp->ptp_ops->get_ts_info(mlxsw_sp, info);
-}
-
-static const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
- .get_drvinfo = mlxsw_sp_port_get_drvinfo,
- .get_link = ethtool_op_get_link,
- .get_pauseparam = mlxsw_sp_port_get_pauseparam,
- .set_pauseparam = mlxsw_sp_port_set_pauseparam,
- .get_strings = mlxsw_sp_port_get_strings,
- .set_phys_id = mlxsw_sp_port_set_phys_id,
- .get_ethtool_stats = mlxsw_sp_port_get_stats,
- .get_sset_count = mlxsw_sp_port_get_sset_count,
- .get_link_ksettings = mlxsw_sp_port_get_link_ksettings,
- .set_link_ksettings = mlxsw_sp_port_set_link_ksettings,
- .get_module_info = mlxsw_sp_get_module_info,
- .get_module_eeprom = mlxsw_sp_get_module_eeprom,
- .get_ts_info = mlxsw_sp_get_ts_info,
-};
-
static int
mlxsw_sp_port_speed_by_width_set(struct mlxsw_sp_port *mlxsw_sp_port)
{
@@ -3246,12 +1744,16 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
bool split = !!split_base_local_port;
struct mlxsw_sp_port *mlxsw_sp_port;
+ u32 lanes = port_mapping->width;
struct net_device *dev;
+ bool splittable;
int err;
+ splittable = lanes > 1 && !split;
err = mlxsw_core_port_init(mlxsw_sp->core, local_port,
port_mapping->module + 1, split,
- port_mapping->lane / port_mapping->width,
+ port_mapping->lane / lanes,
+ splittable, lanes,
mlxsw_sp->base_mac,
sizeof(mlxsw_sp->base_mac));
if (err) {
@@ -3745,13 +2247,6 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
return -EINVAL;
}
- /* Split ports cannot be split. */
- if (mlxsw_sp_port->split) {
- netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n");
- NL_SET_ERR_MSG_MOD(extack, "Port cannot be split further");
- return -EINVAL;
- }
-
max_width = mlxsw_core_module_max_width(mlxsw_core,
mlxsw_sp_port->mapping.module);
if (max_width < 0) {
@@ -3760,19 +2255,13 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
return max_width;
}
- /* Split port with non-max and 1 module width cannot be split. */
- if (mlxsw_sp_port->mapping.width != max_width || max_width == 1) {
+ /* Split port with non-max cannot be split. */
+ if (mlxsw_sp_port->mapping.width != max_width) {
netdev_err(mlxsw_sp_port->dev, "Port cannot be split\n");
NL_SET_ERR_MSG_MOD(extack, "Port cannot be split");
return -EINVAL;
}
- if (count == 1 || !is_power_of_2(count) || count > max_width) {
- netdev_err(mlxsw_sp_port->dev, "Invalid split count\n");
- NL_SET_ERR_MSG_MOD(extack, "Invalid split count");
- return -EINVAL;
- }
-
offset = mlxsw_sp_local_ports_offset(mlxsw_core, count, max_width);
if (offset < 0) {
netdev_err(mlxsw_sp_port->dev, "Cannot obtain local port offset\n");
@@ -4334,52 +2823,6 @@ static const struct mlxsw_sp_ptp_ops mlxsw_sp2_ptp_ops = {
.get_stats = mlxsw_sp2_get_stats,
};
-static u32 mlxsw_sp1_span_buffsize_get(int mtu, u32 speed)
-{
- return mtu * 5 / 2;
-}
-
-static const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops = {
- .buffsize_get = mlxsw_sp1_span_buffsize_get,
-};
-
-#define MLXSW_SP2_SPAN_EG_MIRROR_BUFFER_FACTOR 38
-#define MLXSW_SP3_SPAN_EG_MIRROR_BUFFER_FACTOR 50
-
-static u32 __mlxsw_sp_span_buffsize_get(int mtu, u32 speed, u32 buffer_factor)
-{
- return 3 * mtu + buffer_factor * speed / 1000;
-}
-
-static u32 mlxsw_sp2_span_buffsize_get(int mtu, u32 speed)
-{
- int factor = MLXSW_SP2_SPAN_EG_MIRROR_BUFFER_FACTOR;
-
- return __mlxsw_sp_span_buffsize_get(mtu, speed, factor);
-}
-
-static const struct mlxsw_sp_span_ops mlxsw_sp2_span_ops = {
- .buffsize_get = mlxsw_sp2_span_buffsize_get,
-};
-
-static u32 mlxsw_sp3_span_buffsize_get(int mtu, u32 speed)
-{
- int factor = MLXSW_SP3_SPAN_EG_MIRROR_BUFFER_FACTOR;
-
- return __mlxsw_sp_span_buffsize_get(mtu, speed, factor);
-}
-
-static const struct mlxsw_sp_span_ops mlxsw_sp3_span_ops = {
- .buffsize_get = mlxsw_sp3_span_buffsize_get,
-};
-
-u32 mlxsw_sp_span_buffsize_get(struct mlxsw_sp *mlxsw_sp, int mtu, u32 speed)
-{
- u32 buffsize = mlxsw_sp->span_ops->buffsize_get(speed, mtu);
-
- return mlxsw_sp_bytes_cells(mlxsw_sp, buffsize) + 1;
-}
-
static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
unsigned long event, void *ptr);
@@ -4417,6 +2860,12 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
goto err_fids_init;
}
+ err = mlxsw_sp_policers_init(mlxsw_sp);
+ if (err) {
+ dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize policers\n");
+ goto err_policers_init;
+ }
+
err = mlxsw_sp_traps_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to set traps\n");
@@ -4576,6 +3025,8 @@ err_buffers_init:
err_devlink_traps_init:
mlxsw_sp_traps_fini(mlxsw_sp);
err_traps_init:
+ mlxsw_sp_policers_fini(mlxsw_sp);
+err_policers_init:
mlxsw_sp_fids_fini(mlxsw_sp);
err_fids_init:
mlxsw_sp_kvdl_fini(mlxsw_sp);
@@ -4594,6 +3045,7 @@ static int mlxsw_sp1_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->afa_ops = &mlxsw_sp1_act_afa_ops;
mlxsw_sp->afk_ops = &mlxsw_sp1_afk_ops;
mlxsw_sp->mr_tcam_ops = &mlxsw_sp1_mr_tcam_ops;
+ mlxsw_sp->acl_rulei_ops = &mlxsw_sp1_acl_rulei_ops;
mlxsw_sp->acl_tcam_ops = &mlxsw_sp1_acl_tcam_ops;
mlxsw_sp->nve_ops_arr = mlxsw_sp1_nve_ops_arr;
mlxsw_sp->mac_mask = mlxsw_sp1_mac_mask;
@@ -4602,6 +3054,8 @@ static int mlxsw_sp1_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->port_type_speed_ops = &mlxsw_sp1_port_type_speed_ops;
mlxsw_sp->ptp_ops = &mlxsw_sp1_ptp_ops;
mlxsw_sp->span_ops = &mlxsw_sp1_span_ops;
+ mlxsw_sp->policer_core_ops = &mlxsw_sp1_policer_core_ops;
+ mlxsw_sp->trap_ops = &mlxsw_sp1_trap_ops;
mlxsw_sp->listeners = mlxsw_sp1_listener;
mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp1_listener);
mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP1;
@@ -4621,6 +3075,7 @@ static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->afa_ops = &mlxsw_sp2_act_afa_ops;
mlxsw_sp->afk_ops = &mlxsw_sp2_afk_ops;
mlxsw_sp->mr_tcam_ops = &mlxsw_sp2_mr_tcam_ops;
+ mlxsw_sp->acl_rulei_ops = &mlxsw_sp2_acl_rulei_ops;
mlxsw_sp->acl_tcam_ops = &mlxsw_sp2_acl_tcam_ops;
mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
@@ -4629,6 +3084,8 @@ static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->port_type_speed_ops = &mlxsw_sp2_port_type_speed_ops;
mlxsw_sp->ptp_ops = &mlxsw_sp2_ptp_ops;
mlxsw_sp->span_ops = &mlxsw_sp2_span_ops;
+ mlxsw_sp->policer_core_ops = &mlxsw_sp2_policer_core_ops;
+ mlxsw_sp->trap_ops = &mlxsw_sp2_trap_ops;
mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP2;
return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
@@ -4640,10 +3097,13 @@ static int mlxsw_sp3_init(struct mlxsw_core *mlxsw_core,
{
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
+ mlxsw_sp->req_rev = &mlxsw_sp3_fw_rev;
+ mlxsw_sp->fw_filename = MLXSW_SP3_FW_FILENAME;
mlxsw_sp->kvdl_ops = &mlxsw_sp2_kvdl_ops;
mlxsw_sp->afa_ops = &mlxsw_sp2_act_afa_ops;
mlxsw_sp->afk_ops = &mlxsw_sp2_afk_ops;
mlxsw_sp->mr_tcam_ops = &mlxsw_sp2_mr_tcam_ops;
+ mlxsw_sp->acl_rulei_ops = &mlxsw_sp2_acl_rulei_ops;
mlxsw_sp->acl_tcam_ops = &mlxsw_sp2_acl_tcam_ops;
mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
@@ -4652,6 +3112,8 @@ static int mlxsw_sp3_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->port_type_speed_ops = &mlxsw_sp2_port_type_speed_ops;
mlxsw_sp->ptp_ops = &mlxsw_sp2_ptp_ops;
mlxsw_sp->span_ops = &mlxsw_sp3_span_ops;
+ mlxsw_sp->policer_core_ops = &mlxsw_sp2_policer_core_ops;
+ mlxsw_sp->trap_ops = &mlxsw_sp2_trap_ops;
mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP3;
return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
@@ -4681,6 +3143,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
mlxsw_sp_buffers_fini(mlxsw_sp);
mlxsw_sp_devlink_traps_fini(mlxsw_sp);
mlxsw_sp_traps_fini(mlxsw_sp);
+ mlxsw_sp_policers_fini(mlxsw_sp);
mlxsw_sp_fids_fini(mlxsw_sp);
mlxsw_sp_kvdl_fini(mlxsw_sp);
}
@@ -4892,6 +3355,10 @@ static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
if (err)
goto err_resources_counter_register;
+ err = mlxsw_sp_policer_resources_register(mlxsw_core);
+ if (err)
+ goto err_resources_counter_register;
+
return 0;
err_resources_counter_register:
@@ -4916,6 +3383,10 @@ static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
if (err)
goto err_resources_counter_register;
+ err = mlxsw_sp_policer_resources_register(mlxsw_core);
+ if (err)
+ goto err_resources_counter_register;
+
return 0;
err_resources_counter_register:
@@ -6330,3 +4801,4 @@ MODULE_DEVICE_TABLE(pci, mlxsw_sp2_pci_id_table);
MODULE_DEVICE_TABLE(pci, mlxsw_sp3_pci_id_table);
MODULE_FIRMWARE(MLXSW_SP1_FW_FILENAME);
MODULE_FIRMWARE(MLXSW_SP2_FW_FILENAME);
+MODULE_FIRMWARE(MLXSW_SP3_FW_FILENAME);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index 3abe3e7d89bc..f9ba59641b4d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -62,6 +62,8 @@ enum mlxsw_sp_resource_id {
MLXSW_SP_RESOURCE_COUNTERS,
MLXSW_SP_RESOURCE_COUNTERS_FLOW,
MLXSW_SP_RESOURCE_COUNTERS_RIF,
+ MLXSW_SP_RESOURCE_GLOBAL_POLICERS,
+ MLXSW_SP_RESOURCE_SINGLE_RATE_POLICERS,
};
struct mlxsw_sp_port;
@@ -120,6 +122,7 @@ struct mlxsw_sp_kvdl;
struct mlxsw_sp_nve;
struct mlxsw_sp_kvdl_ops;
struct mlxsw_sp_mr_tcam_ops;
+struct mlxsw_sp_acl_rulei_ops;
struct mlxsw_sp_acl_tcam_ops;
struct mlxsw_sp_nve_ops;
struct mlxsw_sp_sb_vals;
@@ -150,6 +153,7 @@ struct mlxsw_sp {
struct mlxsw_afa *afa;
struct mlxsw_sp_acl *acl;
struct mlxsw_sp_fid_core *fid_core;
+ struct mlxsw_sp_policer_core *policer_core;
struct mlxsw_sp_kvdl *kvdl;
struct mlxsw_sp_nve *nve;
struct notifier_block netdevice_nb;
@@ -164,6 +168,7 @@ struct mlxsw_sp {
const struct mlxsw_afa_ops *afa_ops;
const struct mlxsw_afk_ops *afk_ops;
const struct mlxsw_sp_mr_tcam_ops *mr_tcam_ops;
+ const struct mlxsw_sp_acl_rulei_ops *acl_rulei_ops;
const struct mlxsw_sp_acl_tcam_ops *acl_tcam_ops;
const struct mlxsw_sp_nve_ops **nve_ops_arr;
const struct mlxsw_sp_rif_ops **rif_ops_arr;
@@ -171,11 +176,46 @@ struct mlxsw_sp {
const struct mlxsw_sp_port_type_speed_ops *port_type_speed_ops;
const struct mlxsw_sp_ptp_ops *ptp_ops;
const struct mlxsw_sp_span_ops *span_ops;
+ const struct mlxsw_sp_policer_core_ops *policer_core_ops;
+ const struct mlxsw_sp_trap_ops *trap_ops;
const struct mlxsw_listener *listeners;
size_t listeners_count;
u32 lowest_shaper_bs;
};
+struct mlxsw_sp_ptp_ops {
+ struct mlxsw_sp_ptp_clock *
+ (*clock_init)(struct mlxsw_sp *mlxsw_sp, struct device *dev);
+ void (*clock_fini)(struct mlxsw_sp_ptp_clock *clock);
+
+ struct mlxsw_sp_ptp_state *(*init)(struct mlxsw_sp *mlxsw_sp);
+ void (*fini)(struct mlxsw_sp_ptp_state *ptp_state);
+
+ /* Notify a driver that a packet that might be PTP was received. Driver
+ * is responsible for freeing the passed-in SKB.
+ */
+ void (*receive)(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
+ u8 local_port);
+
+ /* Notify a driver that a timestamped packet was transmitted. Driver
+ * is responsible for freeing the passed-in SKB.
+ */
+ void (*transmitted)(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
+ u8 local_port);
+
+ int (*hwtstamp_get)(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct hwtstamp_config *config);
+ int (*hwtstamp_set)(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct hwtstamp_config *config);
+ void (*shaper_work)(struct work_struct *work);
+ int (*get_ts_info)(struct mlxsw_sp *mlxsw_sp,
+ struct ethtool_ts_info *info);
+ int (*get_stats_count)(void);
+ void (*get_stats_strings)(u8 **p);
+ void (*get_stats)(struct mlxsw_sp_port *mlxsw_sp_port,
+ u64 *data, int data_index);
+};
+
static inline struct mlxsw_sp_upper *
mlxsw_sp_lag_get(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
{
@@ -391,6 +431,13 @@ enum mlxsw_sp_flood_type {
MLXSW_SP_FLOOD_TYPE_MC,
};
+int mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
+ int mtu, bool pause_en);
+int mlxsw_sp_port_get_stats_raw(struct net_device *dev, int grp,
+ int prio, char *ppcnt_pl);
+int mlxsw_sp_port_admin_status_set(struct mlxsw_sp_port *mlxsw_sp_port,
+ bool is_up);
+
/* spectrum_buffers.c */
int mlxsw_sp_buffers_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_buffers_fini(struct mlxsw_sp *mlxsw_sp);
@@ -497,7 +544,6 @@ int mlxsw_sp_flow_counter_alloc(struct mlxsw_sp *mlxsw_sp,
unsigned int *p_counter_index);
void mlxsw_sp_flow_counter_free(struct mlxsw_sp *mlxsw_sp,
unsigned int counter_index);
-u32 mlxsw_sp_span_buffsize_get(struct mlxsw_sp *mlxsw_sp, int mtu, u32 speed);
bool mlxsw_sp_port_dev_check(const struct net_device *dev);
struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev);
struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev);
@@ -644,8 +690,10 @@ struct mlxsw_sp_acl_rule_info {
u8 action_created:1,
ingress_bind_blocker:1,
egress_bind_blocker:1,
- counter_valid:1;
+ counter_valid:1,
+ policer_index_valid:1;
unsigned int counter_index;
+ u16 policer_index;
};
/* spectrum_flow.c */
@@ -669,7 +717,6 @@ struct mlxsw_sp_flow_block {
struct mlxsw_sp_flow_block_binding {
struct list_head list;
- struct net_device *dev;
struct mlxsw_sp_port *mlxsw_sp_port;
bool ingress;
};
@@ -727,8 +774,9 @@ mlxsw_sp_flow_block_is_mixed_bound(const struct mlxsw_sp_flow_block *block)
struct mlxsw_sp_flow_block *mlxsw_sp_flow_block_create(struct mlxsw_sp *mlxsw_sp,
struct net *net);
void mlxsw_sp_flow_block_destroy(struct mlxsw_sp_flow_block *block);
-int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
- struct flow_block_offload *f);
+int mlxsw_sp_setup_tc_block_clsact(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct flow_block_offload *f,
+ bool ingress);
/* spectrum_acl.c */
struct mlxsw_sp_acl_ruleset;
@@ -806,6 +854,10 @@ int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp,
enum flow_action_mangle_base htype,
u32 offset, u32 mask, u32 val,
struct netlink_ext_ack *extack);
+int mlxsw_sp_acl_rulei_act_police(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_acl_rule_info *rulei,
+ u32 index, u64 rate_bytes_ps,
+ u32 burst, struct netlink_ext_ack *extack);
int mlxsw_sp_acl_rulei_act_count(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_rule_info *rulei,
struct netlink_ext_ack *extack);
@@ -838,7 +890,8 @@ struct mlxsw_sp_acl_rule_info *
mlxsw_sp_acl_rule_rulei(struct mlxsw_sp_acl_rule *rule);
int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_rule *rule,
- u64 *packets, u64 *bytes, u64 *last_use,
+ u64 *packets, u64 *bytes, u64 *drops,
+ u64 *last_use,
enum flow_action_hw_stats *used_hw_stats);
struct mlxsw_sp_fid *mlxsw_sp_acl_dummy_fid(struct mlxsw_sp *mlxsw_sp);
@@ -854,6 +907,17 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp);
u32 mlxsw_sp_acl_region_rehash_intrvl_get(struct mlxsw_sp *mlxsw_sp);
int mlxsw_sp_acl_region_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp, u32 val);
+struct mlxsw_sp_acl_mangle_action;
+
+struct mlxsw_sp_acl_rulei_ops {
+ int (*act_mangle_field)(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_rule_info *rulei,
+ struct mlxsw_sp_acl_mangle_action *mact, u32 val,
+ struct netlink_ext_ack *extack);
+};
+
+extern struct mlxsw_sp_acl_rulei_ops mlxsw_sp1_acl_rulei_ops;
+extern struct mlxsw_sp_acl_rulei_ops mlxsw_sp2_acl_rulei_ops;
+
/* spectrum_acl_tcam.c */
struct mlxsw_sp_acl_tcam;
struct mlxsw_sp_acl_tcam_region;
@@ -909,6 +973,35 @@ extern const struct mlxsw_afk_ops mlxsw_sp1_afk_ops;
extern const struct mlxsw_afk_ops mlxsw_sp2_afk_ops;
/* spectrum_matchall.c */
+enum mlxsw_sp_mall_action_type {
+ MLXSW_SP_MALL_ACTION_TYPE_MIRROR,
+ MLXSW_SP_MALL_ACTION_TYPE_SAMPLE,
+ MLXSW_SP_MALL_ACTION_TYPE_TRAP,
+};
+
+struct mlxsw_sp_mall_mirror_entry {
+ const struct net_device *to_dev;
+ int span_id;
+};
+
+struct mlxsw_sp_mall_trap_entry {
+ int span_id;
+};
+
+struct mlxsw_sp_mall_entry {
+ struct list_head list;
+ unsigned long cookie;
+ unsigned int priority;
+ enum mlxsw_sp_mall_action_type type;
+ bool ingress;
+ union {
+ struct mlxsw_sp_mall_mirror_entry mirror;
+ struct mlxsw_sp_mall_trap_entry trap;
+ struct mlxsw_sp_port_sample sample;
+ };
+ struct rcu_head rcu;
+};
+
int mlxsw_sp_mall_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_flow_block *block,
struct tc_cls_matchall_offload *f);
@@ -955,6 +1048,8 @@ int mlxsw_sp_setup_tc_tbf(struct mlxsw_sp_port *mlxsw_sp_port,
struct tc_tbf_qopt_offload *p);
int mlxsw_sp_setup_tc_fifo(struct mlxsw_sp_port *mlxsw_sp_port,
struct tc_fifo_qopt_offload *p);
+int mlxsw_sp_setup_tc_block_qevent_early_drop(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct flow_block_offload *f);
/* spectrum_fid.c */
bool mlxsw_sp_fid_is_dummy(struct mlxsw_sp *mlxsw_sp, u16 fid_index);
@@ -1088,12 +1183,14 @@ void mlxsw_sp_trap_fini(struct mlxsw_core *mlxsw_core,
const struct devlink_trap *trap, void *trap_ctx);
int mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core,
const struct devlink_trap *trap,
- enum devlink_trap_action action);
+ enum devlink_trap_action action,
+ struct netlink_ext_ack *extack);
int mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_group *group);
int mlxsw_sp_trap_group_set(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_group *group,
- const struct devlink_trap_policer *policer);
+ const struct devlink_trap_policer *policer,
+ struct netlink_ext_ack *extack);
int
mlxsw_sp_trap_policer_init(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_policer *policer);
@@ -1107,10 +1204,48 @@ int
mlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_policer *policer,
u64 *p_drops);
+int mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp *mlxsw_sp, u16 id,
+ bool *p_enabled, u16 *p_hw_id);
static inline struct net *mlxsw_sp_net(struct mlxsw_sp *mlxsw_sp)
{
return mlxsw_core_net(mlxsw_sp->core);
}
+/* spectrum_ethtool.c */
+extern const struct ethtool_ops mlxsw_sp_port_ethtool_ops;
+extern const struct mlxsw_sp_port_type_speed_ops mlxsw_sp1_port_type_speed_ops;
+extern const struct mlxsw_sp_port_type_speed_ops mlxsw_sp2_port_type_speed_ops;
+
+/* spectrum_policer.c */
+extern const struct mlxsw_sp_policer_core_ops mlxsw_sp1_policer_core_ops;
+extern const struct mlxsw_sp_policer_core_ops mlxsw_sp2_policer_core_ops;
+
+enum mlxsw_sp_policer_type {
+ MLXSW_SP_POLICER_TYPE_SINGLE_RATE,
+
+ __MLXSW_SP_POLICER_TYPE_MAX,
+ MLXSW_SP_POLICER_TYPE_MAX = __MLXSW_SP_POLICER_TYPE_MAX - 1,
+};
+
+struct mlxsw_sp_policer_params {
+ u64 rate;
+ u64 burst;
+ bool bytes;
+};
+
+int mlxsw_sp_policer_add(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_policer_type type,
+ const struct mlxsw_sp_policer_params *params,
+ struct netlink_ext_ack *extack, u16 *p_policer_index);
+void mlxsw_sp_policer_del(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_policer_type type,
+ u16 policer_index);
+int mlxsw_sp_policer_drops_counter_get(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_policer_type type,
+ u16 policer_index, u64 *p_drops);
+int mlxsw_sp_policers_init(struct mlxsw_sp *mlxsw_sp);
+void mlxsw_sp_policers_fini(struct mlxsw_sp *mlxsw_sp);
+int mlxsw_sp_policer_resources_register(struct mlxsw_core *mlxsw_core);
+
#endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
index 47da9ee0045d..8cfa03a75374 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
@@ -66,6 +66,7 @@ struct mlxsw_sp_acl_rule {
u64 last_used;
u64 last_packets;
u64 last_bytes;
+ u64 last_drops;
unsigned long priv[];
/* priv has to be always the last item */
};
@@ -508,6 +509,8 @@ enum mlxsw_sp_acl_mangle_field {
MLXSW_SP_ACL_MANGLE_FIELD_IP_DSFIELD,
MLXSW_SP_ACL_MANGLE_FIELD_IP_DSCP,
MLXSW_SP_ACL_MANGLE_FIELD_IP_ECN,
+ MLXSW_SP_ACL_MANGLE_FIELD_IP_SPORT,
+ MLXSW_SP_ACL_MANGLE_FIELD_IP_DPORT,
};
struct mlxsw_sp_acl_mangle_action {
@@ -538,13 +541,26 @@ struct mlxsw_sp_acl_mangle_action {
MLXSW_SP_ACL_MANGLE_ACTION(FLOW_ACT_MANGLE_HDR_TYPE_IP6, \
_offset, _mask, _shift, _field)
+#define MLXSW_SP_ACL_MANGLE_ACTION_TCP(_offset, _mask, _shift, _field) \
+ MLXSW_SP_ACL_MANGLE_ACTION(FLOW_ACT_MANGLE_HDR_TYPE_TCP, _offset, _mask, _shift, _field)
+
+#define MLXSW_SP_ACL_MANGLE_ACTION_UDP(_offset, _mask, _shift, _field) \
+ MLXSW_SP_ACL_MANGLE_ACTION(FLOW_ACT_MANGLE_HDR_TYPE_UDP, _offset, _mask, _shift, _field)
+
static struct mlxsw_sp_acl_mangle_action mlxsw_sp_acl_mangle_actions[] = {
MLXSW_SP_ACL_MANGLE_ACTION_IP4(0, 0xff00ffff, 16, IP_DSFIELD),
MLXSW_SP_ACL_MANGLE_ACTION_IP4(0, 0xff03ffff, 18, IP_DSCP),
MLXSW_SP_ACL_MANGLE_ACTION_IP4(0, 0xfffcffff, 16, IP_ECN),
+
MLXSW_SP_ACL_MANGLE_ACTION_IP6(0, 0xf00fffff, 20, IP_DSFIELD),
MLXSW_SP_ACL_MANGLE_ACTION_IP6(0, 0xf03fffff, 22, IP_DSCP),
MLXSW_SP_ACL_MANGLE_ACTION_IP6(0, 0xffcfffff, 20, IP_ECN),
+
+ MLXSW_SP_ACL_MANGLE_ACTION_TCP(0, 0x0000ffff, 16, IP_SPORT),
+ MLXSW_SP_ACL_MANGLE_ACTION_TCP(0, 0xffff0000, 0, IP_DPORT),
+
+ MLXSW_SP_ACL_MANGLE_ACTION_UDP(0, 0x0000ffff, 16, IP_SPORT),
+ MLXSW_SP_ACL_MANGLE_ACTION_UDP(0, 0xffff0000, 0, IP_DPORT),
};
static int
@@ -563,11 +579,48 @@ mlxsw_sp_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp,
case MLXSW_SP_ACL_MANGLE_FIELD_IP_ECN:
return mlxsw_afa_block_append_qos_ecn(rulei->act_block,
val, extack);
+ default:
+ return -EOPNOTSUPP;
}
+}
- /* We shouldn't have gotten a match in the first place! */
- WARN_ONCE(1, "Unhandled mangle field");
- return -EINVAL;
+static int mlxsw_sp1_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_acl_rule_info *rulei,
+ struct mlxsw_sp_acl_mangle_action *mact,
+ u32 val, struct netlink_ext_ack *extack)
+{
+ int err;
+
+ err = mlxsw_sp_acl_rulei_act_mangle_field(mlxsw_sp, rulei, mact, val, extack);
+ if (err != -EOPNOTSUPP)
+ return err;
+
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field");
+ return err;
+}
+
+static int mlxsw_sp2_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_acl_rule_info *rulei,
+ struct mlxsw_sp_acl_mangle_action *mact,
+ u32 val, struct netlink_ext_ack *extack)
+{
+ int err;
+
+ err = mlxsw_sp_acl_rulei_act_mangle_field(mlxsw_sp, rulei, mact, val, extack);
+ if (err != -EOPNOTSUPP)
+ return err;
+
+ switch (mact->field) {
+ case MLXSW_SP_ACL_MANGLE_FIELD_IP_SPORT:
+ return mlxsw_afa_block_append_l4port(rulei->act_block, false, val, extack);
+ case MLXSW_SP_ACL_MANGLE_FIELD_IP_DPORT:
+ return mlxsw_afa_block_append_l4port(rulei->act_block, true, val, extack);
+ default:
+ break;
+ }
+
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field");
+ return err;
}
int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp,
@@ -576,6 +629,7 @@ int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp,
u32 offset, u32 mask, u32 val,
struct netlink_ext_ack *extack)
{
+ const struct mlxsw_sp_acl_rulei_ops *acl_rulei_ops = mlxsw_sp->acl_rulei_ops;
struct mlxsw_sp_acl_mangle_action *mact;
size_t i;
@@ -585,16 +639,34 @@ int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp,
mact->offset == offset &&
mact->mask == mask) {
val >>= mact->shift;
- return mlxsw_sp_acl_rulei_act_mangle_field(mlxsw_sp,
- rulei, mact,
- val, extack);
+ return acl_rulei_ops->act_mangle_field(mlxsw_sp,
+ rulei, mact,
+ val, extack);
}
}
- NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field");
+ NL_SET_ERR_MSG_MOD(extack, "Unknown mangle field");
return -EINVAL;
}
+int mlxsw_sp_acl_rulei_act_police(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_acl_rule_info *rulei,
+ u32 index, u64 rate_bytes_ps,
+ u32 burst, struct netlink_ext_ack *extack)
+{
+ int err;
+
+ err = mlxsw_afa_block_append_police(rulei->act_block, index,
+ rate_bytes_ps, burst,
+ &rulei->policer_index, extack);
+ if (err)
+ return err;
+
+ rulei->policer_index_valid = true;
+
+ return 0;
+}
+
int mlxsw_sp_acl_rulei_act_count(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_rule_info *rulei,
struct netlink_ext_ack *extack)
@@ -815,13 +887,16 @@ static void mlxsw_sp_acl_rule_activity_update_work(struct work_struct *work)
int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_rule *rule,
- u64 *packets, u64 *bytes, u64 *last_use,
+ u64 *packets, u64 *bytes, u64 *drops,
+ u64 *last_use,
enum flow_action_hw_stats *used_hw_stats)
{
+ enum mlxsw_sp_policer_type type = MLXSW_SP_POLICER_TYPE_SINGLE_RATE;
struct mlxsw_sp_acl_rule_info *rulei;
u64 current_packets = 0;
u64 current_bytes = 0;
+ u64 current_drops = 0;
int err;
rulei = mlxsw_sp_acl_rule_rulei(rule);
@@ -833,12 +908,21 @@ int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
return err;
*used_hw_stats = FLOW_ACTION_HW_STATS_IMMEDIATE;
}
+ if (rulei->policer_index_valid) {
+ err = mlxsw_sp_policer_drops_counter_get(mlxsw_sp, type,
+ rulei->policer_index,
+ &current_drops);
+ if (err)
+ return err;
+ }
*packets = current_packets - rule->last_packets;
*bytes = current_bytes - rule->last_bytes;
+ *drops = current_drops - rule->last_drops;
*last_use = rule->last_used;
rule->last_bytes = current_bytes;
rule->last_packets = current_packets;
+ rule->last_drops = current_drops;
return 0;
}
@@ -930,3 +1014,11 @@ int mlxsw_sp_acl_region_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp, u32 val)
return mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(mlxsw_sp,
&acl->tcam, val);
}
+
+struct mlxsw_sp_acl_rulei_ops mlxsw_sp1_acl_rulei_ops = {
+ .act_mangle_field = mlxsw_sp1_acl_rulei_act_mangle_field,
+};
+
+struct mlxsw_sp_acl_rulei_ops mlxsw_sp2_acl_rulei_ops = {
+ .act_mangle_field = mlxsw_sp2_acl_rulei_act_mangle_field,
+};
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 73d56012654b..90372d1c28d4 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
@@ -136,11 +136,13 @@ mlxsw_sp_act_mirror_add(void *priv, u8 local_in_port,
const struct net_device *out_dev,
bool ingress, int *p_span_id)
{
+ struct mlxsw_sp_span_agent_parms agent_parms = {};
struct mlxsw_sp_port *mlxsw_sp_port;
struct mlxsw_sp *mlxsw_sp = priv;
int err;
- err = mlxsw_sp_span_agent_get(mlxsw_sp, out_dev, p_span_id);
+ agent_parms.to_dev = out_dev;
+ err = mlxsw_sp_span_agent_get(mlxsw_sp, p_span_id, &agent_parms);
if (err)
return err;
@@ -167,6 +169,29 @@ mlxsw_sp_act_mirror_del(void *priv, u8 local_in_port, int span_id, bool ingress)
mlxsw_sp_span_agent_put(mlxsw_sp, span_id);
}
+static int mlxsw_sp_act_policer_add(void *priv, u64 rate_bytes_ps, u32 burst,
+ u16 *p_policer_index,
+ struct netlink_ext_ack *extack)
+{
+ struct mlxsw_sp_policer_params params;
+ struct mlxsw_sp *mlxsw_sp = priv;
+
+ params.rate = rate_bytes_ps;
+ params.burst = burst;
+ params.bytes = true;
+ return mlxsw_sp_policer_add(mlxsw_sp,
+ MLXSW_SP_POLICER_TYPE_SINGLE_RATE,
+ &params, extack, p_policer_index);
+}
+
+static void mlxsw_sp_act_policer_del(void *priv, u16 policer_index)
+{
+ struct mlxsw_sp *mlxsw_sp = priv;
+
+ mlxsw_sp_policer_del(mlxsw_sp, MLXSW_SP_POLICER_TYPE_SINGLE_RATE,
+ policer_index);
+}
+
const struct mlxsw_afa_ops mlxsw_sp1_act_afa_ops = {
.kvdl_set_add = mlxsw_sp1_act_kvdl_set_add,
.kvdl_set_del = mlxsw_sp_act_kvdl_set_del,
@@ -177,6 +202,8 @@ const struct mlxsw_afa_ops mlxsw_sp1_act_afa_ops = {
.counter_index_put = mlxsw_sp_act_counter_index_put,
.mirror_add = mlxsw_sp_act_mirror_add,
.mirror_del = mlxsw_sp_act_mirror_del,
+ .policer_add = mlxsw_sp_act_policer_add,
+ .policer_del = mlxsw_sp_act_policer_del,
};
const struct mlxsw_afa_ops mlxsw_sp2_act_afa_ops = {
@@ -189,6 +216,8 @@ const struct mlxsw_afa_ops mlxsw_sp2_act_afa_ops = {
.counter_index_put = mlxsw_sp_act_counter_index_put,
.mirror_add = mlxsw_sp_act_mirror_add,
.mirror_del = mlxsw_sp_act_mirror_del,
+ .policer_add = mlxsw_sp_act_policer_add,
+ .policer_del = mlxsw_sp_act_policer_del,
.dummy_first_set = true,
};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
index 7974982533b5..b65b93a2b9bc 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
@@ -121,7 +121,6 @@ int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp)
{
unsigned int sub_pools_count = ARRAY_SIZE(mlxsw_sp_counter_sub_pools);
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
- struct mlxsw_sp_counter_sub_pool *sub_pool;
struct mlxsw_sp_counter_pool *pool;
unsigned int map_size;
int err;
@@ -131,9 +130,9 @@ int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp)
if (!pool)
return -ENOMEM;
mlxsw_sp->counter_pool = pool;
- memcpy(pool->sub_pools, mlxsw_sp_counter_sub_pools,
- sub_pools_count * sizeof(*sub_pool));
pool->sub_pools_count = sub_pools_count;
+ memcpy(pool->sub_pools, mlxsw_sp_counter_sub_pools,
+ flex_array_size(pool, sub_pools, pool->sub_pools_count));
spin_lock_init(&pool->counter_pool_lock);
atomic_set(&pool->active_entries_count, 0);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c
index 49a72a8f1f57..0d3fb2e51ea5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c
@@ -110,8 +110,8 @@ static int mlxsw_sp_port_pg_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
}
-static int mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
- struct ieee_ets *ets)
+static int mlxsw_sp_port_headroom_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct ieee_ets *ets)
{
bool pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
struct ieee_ets *my_ets = mlxsw_sp_port->dcb.ets;
@@ -138,7 +138,7 @@ static int mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
err = mlxsw_sp_port_pg_destroy(mlxsw_sp_port, my_ets->prio_tc,
ets->prio_tc);
if (err)
- netdev_warn(dev, "Failed to remove ununsed PGs\n");
+ netdev_warn(dev, "Failed to remove unused PGs\n");
return 0;
@@ -180,7 +180,7 @@ static int __mlxsw_sp_dcbnl_ieee_setets(struct mlxsw_sp_port *mlxsw_sp_port,
}
/* Ingress configuration. */
- err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, ets);
+ err = mlxsw_sp_port_headroom_ets_set(mlxsw_sp_port, ets);
if (err)
goto err_port_headroom_set;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c
new file mode 100644
index 000000000000..14c78f73bb65
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c
@@ -0,0 +1,1644 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/* Copyright (c) 2020 Mellanox Technologies. All rights reserved */
+
+#include "reg.h"
+#include "spectrum.h"
+#include "core_env.h"
+
+static const char mlxsw_sp_driver_version[] = "1.0";
+
+static void mlxsw_sp_port_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+
+ strlcpy(drvinfo->driver, mlxsw_sp->bus_info->device_kind,
+ sizeof(drvinfo->driver));
+ strlcpy(drvinfo->version, mlxsw_sp_driver_version,
+ sizeof(drvinfo->version));
+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
+ "%d.%d.%d",
+ mlxsw_sp->bus_info->fw_rev.major,
+ mlxsw_sp->bus_info->fw_rev.minor,
+ mlxsw_sp->bus_info->fw_rev.subminor);
+ strlcpy(drvinfo->bus_info, mlxsw_sp->bus_info->device_name,
+ sizeof(drvinfo->bus_info));
+}
+
+struct mlxsw_sp_ethtool_link_ext_state_opcode_mapping {
+ u32 status_opcode;
+ enum ethtool_link_ext_state link_ext_state;
+ u8 link_ext_substate;
+};
+
+static const struct mlxsw_sp_ethtool_link_ext_state_opcode_mapping
+mlxsw_sp_link_ext_state_opcode_map[] = {
+ {2, ETHTOOL_LINK_EXT_STATE_AUTONEG,
+ ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED},
+ {3, ETHTOOL_LINK_EXT_STATE_AUTONEG,
+ ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED},
+ {4, ETHTOOL_LINK_EXT_STATE_AUTONEG,
+ ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED},
+ {36, ETHTOOL_LINK_EXT_STATE_AUTONEG,
+ ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE},
+ {38, ETHTOOL_LINK_EXT_STATE_AUTONEG,
+ ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE},
+ {39, ETHTOOL_LINK_EXT_STATE_AUTONEG,
+ ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD},
+
+ {5, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
+ ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED},
+ {6, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
+ ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT},
+ {7, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
+ ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY},
+ {8, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE, 0},
+ {14, ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE,
+ ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT},
+
+ {9, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
+ ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK},
+ {10, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
+ ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK},
+ {11, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
+ ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS},
+ {12, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
+ ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED},
+ {13, ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH,
+ ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED},
+
+ {15, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY, 0},
+ {17, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY,
+ ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS},
+ {42, ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY,
+ ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE},
+
+ {1024, ETHTOOL_LINK_EXT_STATE_NO_CABLE, 0},
+
+ {16, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
+ ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
+ {20, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
+ ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
+ {29, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
+ ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
+ {1025, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
+ ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
+ {1029, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE,
+ ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE},
+ {1031, ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE, 0},
+
+ {1027, ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE, 0},
+
+ {23, ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE, 0},
+
+ {1032, ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED, 0},
+
+ {1030, ETHTOOL_LINK_EXT_STATE_OVERHEAT, 0},
+};
+
+static void
+mlxsw_sp_port_set_link_ext_state(struct mlxsw_sp_ethtool_link_ext_state_opcode_mapping
+ link_ext_state_mapping,
+ struct ethtool_link_ext_state_info *link_ext_state_info)
+{
+ switch (link_ext_state_mapping.link_ext_state) {
+ case ETHTOOL_LINK_EXT_STATE_AUTONEG:
+ link_ext_state_info->autoneg =
+ link_ext_state_mapping.link_ext_substate;
+ break;
+ case ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE:
+ link_ext_state_info->link_training =
+ link_ext_state_mapping.link_ext_substate;
+ break;
+ case ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH:
+ link_ext_state_info->link_logical_mismatch =
+ link_ext_state_mapping.link_ext_substate;
+ break;
+ case ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY:
+ link_ext_state_info->bad_signal_integrity =
+ link_ext_state_mapping.link_ext_substate;
+ break;
+ case ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE:
+ link_ext_state_info->cable_issue =
+ link_ext_state_mapping.link_ext_substate;
+ break;
+ default:
+ break;
+ }
+
+ link_ext_state_info->link_ext_state = link_ext_state_mapping.link_ext_state;
+}
+
+static int
+mlxsw_sp_port_get_link_ext_state(struct net_device *dev,
+ struct ethtool_link_ext_state_info *link_ext_state_info)
+{
+ struct mlxsw_sp_ethtool_link_ext_state_opcode_mapping link_ext_state_mapping;
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+ char pddr_pl[MLXSW_REG_PDDR_LEN];
+ int opcode, err, i;
+ u32 status_opcode;
+
+ if (netif_carrier_ok(dev))
+ return -ENODATA;
+
+ mlxsw_reg_pddr_pack(pddr_pl, mlxsw_sp_port->local_port,
+ MLXSW_REG_PDDR_PAGE_SELECT_TROUBLESHOOTING_INFO);
+
+ opcode = MLXSW_REG_PDDR_TRBLSH_GROUP_OPCODE_MONITOR;
+ mlxsw_reg_pddr_trblsh_group_opcode_set(pddr_pl, opcode);
+
+ err = mlxsw_reg_query(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pddr),
+ pddr_pl);
+ if (err)
+ return err;
+
+ status_opcode = mlxsw_reg_pddr_trblsh_status_opcode_get(pddr_pl);
+ if (!status_opcode)
+ return -ENODATA;
+
+ for (i = 0; i < ARRAY_SIZE(mlxsw_sp_link_ext_state_opcode_map); i++) {
+ link_ext_state_mapping = mlxsw_sp_link_ext_state_opcode_map[i];
+ if (link_ext_state_mapping.status_opcode == status_opcode) {
+ mlxsw_sp_port_set_link_ext_state(link_ext_state_mapping,
+ link_ext_state_info);
+ return 0;
+ }
+ }
+
+ return -ENODATA;
+}
+
+static void mlxsw_sp_port_get_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *pause)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+
+ pause->rx_pause = mlxsw_sp_port->link.rx_pause;
+ pause->tx_pause = mlxsw_sp_port->link.tx_pause;
+}
+
+static int mlxsw_sp_port_pause_set(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct ethtool_pauseparam *pause)
+{
+ char pfcc_pl[MLXSW_REG_PFCC_LEN];
+
+ mlxsw_reg_pfcc_pack(pfcc_pl, mlxsw_sp_port->local_port);
+ mlxsw_reg_pfcc_pprx_set(pfcc_pl, pause->rx_pause);
+ mlxsw_reg_pfcc_pptx_set(pfcc_pl, pause->tx_pause);
+
+ return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pfcc),
+ pfcc_pl);
+}
+
+static int mlxsw_sp_port_set_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *pause)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+ bool pause_en = pause->tx_pause || pause->rx_pause;
+ int err;
+
+ if (mlxsw_sp_port->dcb.pfc && mlxsw_sp_port->dcb.pfc->pfc_en) {
+ netdev_err(dev, "PFC already enabled on port\n");
+ return -EINVAL;
+ }
+
+ if (pause->autoneg) {
+ netdev_err(dev, "PAUSE frames autonegotiation isn't supported\n");
+ return -EINVAL;
+ }
+
+ err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
+ if (err) {
+ netdev_err(dev, "Failed to configure port's headroom\n");
+ return err;
+ }
+
+ err = mlxsw_sp_port_pause_set(mlxsw_sp_port, pause);
+ if (err) {
+ netdev_err(dev, "Failed to set PAUSE parameters\n");
+ goto err_port_pause_configure;
+ }
+
+ mlxsw_sp_port->link.rx_pause = pause->rx_pause;
+ mlxsw_sp_port->link.tx_pause = pause->tx_pause;
+
+ return 0;
+
+err_port_pause_configure:
+ pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
+ mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
+ return err;
+}
+
+struct mlxsw_sp_port_hw_stats {
+ char str[ETH_GSTRING_LEN];
+ u64 (*getter)(const char *payload);
+ bool cells_bytes;
+};
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = {
+ {
+ .str = "a_frames_transmitted_ok",
+ .getter = mlxsw_reg_ppcnt_a_frames_transmitted_ok_get,
+ },
+ {
+ .str = "a_frames_received_ok",
+ .getter = mlxsw_reg_ppcnt_a_frames_received_ok_get,
+ },
+ {
+ .str = "a_frame_check_sequence_errors",
+ .getter = mlxsw_reg_ppcnt_a_frame_check_sequence_errors_get,
+ },
+ {
+ .str = "a_alignment_errors",
+ .getter = mlxsw_reg_ppcnt_a_alignment_errors_get,
+ },
+ {
+ .str = "a_octets_transmitted_ok",
+ .getter = mlxsw_reg_ppcnt_a_octets_transmitted_ok_get,
+ },
+ {
+ .str = "a_octets_received_ok",
+ .getter = mlxsw_reg_ppcnt_a_octets_received_ok_get,
+ },
+ {
+ .str = "a_multicast_frames_xmitted_ok",
+ .getter = mlxsw_reg_ppcnt_a_multicast_frames_xmitted_ok_get,
+ },
+ {
+ .str = "a_broadcast_frames_xmitted_ok",
+ .getter = mlxsw_reg_ppcnt_a_broadcast_frames_xmitted_ok_get,
+ },
+ {
+ .str = "a_multicast_frames_received_ok",
+ .getter = mlxsw_reg_ppcnt_a_multicast_frames_received_ok_get,
+ },
+ {
+ .str = "a_broadcast_frames_received_ok",
+ .getter = mlxsw_reg_ppcnt_a_broadcast_frames_received_ok_get,
+ },
+ {
+ .str = "a_in_range_length_errors",
+ .getter = mlxsw_reg_ppcnt_a_in_range_length_errors_get,
+ },
+ {
+ .str = "a_out_of_range_length_field",
+ .getter = mlxsw_reg_ppcnt_a_out_of_range_length_field_get,
+ },
+ {
+ .str = "a_frame_too_long_errors",
+ .getter = mlxsw_reg_ppcnt_a_frame_too_long_errors_get,
+ },
+ {
+ .str = "a_symbol_error_during_carrier",
+ .getter = mlxsw_reg_ppcnt_a_symbol_error_during_carrier_get,
+ },
+ {
+ .str = "a_mac_control_frames_transmitted",
+ .getter = mlxsw_reg_ppcnt_a_mac_control_frames_transmitted_get,
+ },
+ {
+ .str = "a_mac_control_frames_received",
+ .getter = mlxsw_reg_ppcnt_a_mac_control_frames_received_get,
+ },
+ {
+ .str = "a_unsupported_opcodes_received",
+ .getter = mlxsw_reg_ppcnt_a_unsupported_opcodes_received_get,
+ },
+ {
+ .str = "a_pause_mac_ctrl_frames_received",
+ .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_received_get,
+ },
+ {
+ .str = "a_pause_mac_ctrl_frames_xmitted",
+ .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_transmitted_get,
+ },
+};
+
+#define MLXSW_SP_PORT_HW_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_stats)
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2863_stats[] = {
+ {
+ .str = "if_in_discards",
+ .getter = mlxsw_reg_ppcnt_if_in_discards_get,
+ },
+ {
+ .str = "if_out_discards",
+ .getter = mlxsw_reg_ppcnt_if_out_discards_get,
+ },
+ {
+ .str = "if_out_errors",
+ .getter = mlxsw_reg_ppcnt_if_out_errors_get,
+ },
+};
+
+#define MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN \
+ ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2863_stats)
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2819_stats[] = {
+ {
+ .str = "ether_stats_undersize_pkts",
+ .getter = mlxsw_reg_ppcnt_ether_stats_undersize_pkts_get,
+ },
+ {
+ .str = "ether_stats_oversize_pkts",
+ .getter = mlxsw_reg_ppcnt_ether_stats_oversize_pkts_get,
+ },
+ {
+ .str = "ether_stats_fragments",
+ .getter = mlxsw_reg_ppcnt_ether_stats_fragments_get,
+ },
+ {
+ .str = "ether_pkts64octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts64octets_get,
+ },
+ {
+ .str = "ether_pkts65to127octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts65to127octets_get,
+ },
+ {
+ .str = "ether_pkts128to255octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts128to255octets_get,
+ },
+ {
+ .str = "ether_pkts256to511octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts256to511octets_get,
+ },
+ {
+ .str = "ether_pkts512to1023octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts512to1023octets_get,
+ },
+ {
+ .str = "ether_pkts1024to1518octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts1024to1518octets_get,
+ },
+ {
+ .str = "ether_pkts1519to2047octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts1519to2047octets_get,
+ },
+ {
+ .str = "ether_pkts2048to4095octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts2048to4095octets_get,
+ },
+ {
+ .str = "ether_pkts4096to8191octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts4096to8191octets_get,
+ },
+ {
+ .str = "ether_pkts8192to10239octets",
+ .getter = mlxsw_reg_ppcnt_ether_stats_pkts8192to10239octets_get,
+ },
+};
+
+#define MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN \
+ ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2819_stats)
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_3635_stats[] = {
+ {
+ .str = "dot3stats_fcs_errors",
+ .getter = mlxsw_reg_ppcnt_dot3stats_fcs_errors_get,
+ },
+ {
+ .str = "dot3stats_symbol_errors",
+ .getter = mlxsw_reg_ppcnt_dot3stats_symbol_errors_get,
+ },
+ {
+ .str = "dot3control_in_unknown_opcodes",
+ .getter = mlxsw_reg_ppcnt_dot3control_in_unknown_opcodes_get,
+ },
+ {
+ .str = "dot3in_pause_frames",
+ .getter = mlxsw_reg_ppcnt_dot3in_pause_frames_get,
+ },
+};
+
+#define MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN \
+ ARRAY_SIZE(mlxsw_sp_port_hw_rfc_3635_stats)
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_ext_stats[] = {
+ {
+ .str = "ecn_marked",
+ .getter = mlxsw_reg_ppcnt_ecn_marked_get,
+ },
+};
+
+#define MLXSW_SP_PORT_HW_EXT_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_ext_stats)
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_discard_stats[] = {
+ {
+ .str = "discard_ingress_general",
+ .getter = mlxsw_reg_ppcnt_ingress_general_get,
+ },
+ {
+ .str = "discard_ingress_policy_engine",
+ .getter = mlxsw_reg_ppcnt_ingress_policy_engine_get,
+ },
+ {
+ .str = "discard_ingress_vlan_membership",
+ .getter = mlxsw_reg_ppcnt_ingress_vlan_membership_get,
+ },
+ {
+ .str = "discard_ingress_tag_frame_type",
+ .getter = mlxsw_reg_ppcnt_ingress_tag_frame_type_get,
+ },
+ {
+ .str = "discard_egress_vlan_membership",
+ .getter = mlxsw_reg_ppcnt_egress_vlan_membership_get,
+ },
+ {
+ .str = "discard_loopback_filter",
+ .getter = mlxsw_reg_ppcnt_loopback_filter_get,
+ },
+ {
+ .str = "discard_egress_general",
+ .getter = mlxsw_reg_ppcnt_egress_general_get,
+ },
+ {
+ .str = "discard_egress_hoq",
+ .getter = mlxsw_reg_ppcnt_egress_hoq_get,
+ },
+ {
+ .str = "discard_egress_policy_engine",
+ .getter = mlxsw_reg_ppcnt_egress_policy_engine_get,
+ },
+ {
+ .str = "discard_ingress_tx_link_down",
+ .getter = mlxsw_reg_ppcnt_ingress_tx_link_down_get,
+ },
+ {
+ .str = "discard_egress_stp_filter",
+ .getter = mlxsw_reg_ppcnt_egress_stp_filter_get,
+ },
+ {
+ .str = "discard_egress_sll",
+ .getter = mlxsw_reg_ppcnt_egress_sll_get,
+ },
+};
+
+#define MLXSW_SP_PORT_HW_DISCARD_STATS_LEN \
+ ARRAY_SIZE(mlxsw_sp_port_hw_discard_stats)
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = {
+ {
+ .str = "rx_octets_prio",
+ .getter = mlxsw_reg_ppcnt_rx_octets_get,
+ },
+ {
+ .str = "rx_frames_prio",
+ .getter = mlxsw_reg_ppcnt_rx_frames_get,
+ },
+ {
+ .str = "tx_octets_prio",
+ .getter = mlxsw_reg_ppcnt_tx_octets_get,
+ },
+ {
+ .str = "tx_frames_prio",
+ .getter = mlxsw_reg_ppcnt_tx_frames_get,
+ },
+ {
+ .str = "rx_pause_prio",
+ .getter = mlxsw_reg_ppcnt_rx_pause_get,
+ },
+ {
+ .str = "rx_pause_duration_prio",
+ .getter = mlxsw_reg_ppcnt_rx_pause_duration_get,
+ },
+ {
+ .str = "tx_pause_prio",
+ .getter = mlxsw_reg_ppcnt_tx_pause_get,
+ },
+ {
+ .str = "tx_pause_duration_prio",
+ .getter = mlxsw_reg_ppcnt_tx_pause_duration_get,
+ },
+};
+
+#define MLXSW_SP_PORT_HW_PRIO_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_prio_stats)
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = {
+ {
+ .str = "tc_transmit_queue_tc",
+ .getter = mlxsw_reg_ppcnt_tc_transmit_queue_get,
+ .cells_bytes = true,
+ },
+ {
+ .str = "tc_no_buffer_discard_uc_tc",
+ .getter = mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get,
+ },
+};
+
+#define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats)
+
+#define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \
+ MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN + \
+ MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN + \
+ MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN + \
+ MLXSW_SP_PORT_HW_EXT_STATS_LEN + \
+ MLXSW_SP_PORT_HW_DISCARD_STATS_LEN + \
+ (MLXSW_SP_PORT_HW_PRIO_STATS_LEN * \
+ IEEE_8021QAZ_MAX_TCS) + \
+ (MLXSW_SP_PORT_HW_TC_STATS_LEN * \
+ TC_MAX_QUEUE))
+
+static void mlxsw_sp_port_get_prio_strings(u8 **p, int prio)
+{
+ int i;
+
+ for (i = 0; i < MLXSW_SP_PORT_HW_PRIO_STATS_LEN; i++) {
+ snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d",
+ mlxsw_sp_port_hw_prio_stats[i].str, prio);
+ *p += ETH_GSTRING_LEN;
+ }
+}
+
+static void mlxsw_sp_port_get_tc_strings(u8 **p, int tc)
+{
+ int i;
+
+ for (i = 0; i < MLXSW_SP_PORT_HW_TC_STATS_LEN; i++) {
+ snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d",
+ mlxsw_sp_port_hw_tc_stats[i].str, tc);
+ *p += ETH_GSTRING_LEN;
+ }
+}
+
+static void mlxsw_sp_port_get_strings(struct net_device *dev,
+ u32 stringset, u8 *data)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+ u8 *p = data;
+ int i;
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < MLXSW_SP_PORT_HW_STATS_LEN; i++) {
+ memcpy(p, mlxsw_sp_port_hw_stats[i].str,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+
+ for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN; i++) {
+ memcpy(p, mlxsw_sp_port_hw_rfc_2863_stats[i].str,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+
+ for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN; i++) {
+ memcpy(p, mlxsw_sp_port_hw_rfc_2819_stats[i].str,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+
+ for (i = 0; i < MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN; i++) {
+ memcpy(p, mlxsw_sp_port_hw_rfc_3635_stats[i].str,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+
+ for (i = 0; i < MLXSW_SP_PORT_HW_EXT_STATS_LEN; i++) {
+ memcpy(p, mlxsw_sp_port_hw_ext_stats[i].str,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+
+ for (i = 0; i < MLXSW_SP_PORT_HW_DISCARD_STATS_LEN; i++) {
+ memcpy(p, mlxsw_sp_port_hw_discard_stats[i].str,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
+ mlxsw_sp_port_get_prio_strings(&p, i);
+
+ for (i = 0; i < TC_MAX_QUEUE; i++)
+ mlxsw_sp_port_get_tc_strings(&p, i);
+
+ mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats_strings(&p);
+ break;
+ }
+}
+
+static int mlxsw_sp_port_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ char mlcr_pl[MLXSW_REG_MLCR_LEN];
+ bool active;
+
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ active = true;
+ break;
+ case ETHTOOL_ID_INACTIVE:
+ active = false;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ mlxsw_reg_mlcr_pack(mlcr_pl, mlxsw_sp_port->local_port, active);
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mlcr), mlcr_pl);
+}
+
+static int
+mlxsw_sp_get_hw_stats_by_group(struct mlxsw_sp_port_hw_stats **p_hw_stats,
+ int *p_len, enum mlxsw_reg_ppcnt_grp grp)
+{
+ switch (grp) {
+ case MLXSW_REG_PPCNT_IEEE_8023_CNT:
+ *p_hw_stats = mlxsw_sp_port_hw_stats;
+ *p_len = MLXSW_SP_PORT_HW_STATS_LEN;
+ break;
+ case MLXSW_REG_PPCNT_RFC_2863_CNT:
+ *p_hw_stats = mlxsw_sp_port_hw_rfc_2863_stats;
+ *p_len = MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN;
+ break;
+ case MLXSW_REG_PPCNT_RFC_2819_CNT:
+ *p_hw_stats = mlxsw_sp_port_hw_rfc_2819_stats;
+ *p_len = MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
+ break;
+ case MLXSW_REG_PPCNT_RFC_3635_CNT:
+ *p_hw_stats = mlxsw_sp_port_hw_rfc_3635_stats;
+ *p_len = MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN;
+ break;
+ case MLXSW_REG_PPCNT_EXT_CNT:
+ *p_hw_stats = mlxsw_sp_port_hw_ext_stats;
+ *p_len = MLXSW_SP_PORT_HW_EXT_STATS_LEN;
+ break;
+ case MLXSW_REG_PPCNT_DISCARD_CNT:
+ *p_hw_stats = mlxsw_sp_port_hw_discard_stats;
+ *p_len = MLXSW_SP_PORT_HW_DISCARD_STATS_LEN;
+ break;
+ case MLXSW_REG_PPCNT_PRIO_CNT:
+ *p_hw_stats = mlxsw_sp_port_hw_prio_stats;
+ *p_len = MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
+ break;
+ case MLXSW_REG_PPCNT_TC_CNT:
+ *p_hw_stats = mlxsw_sp_port_hw_tc_stats;
+ *p_len = MLXSW_SP_PORT_HW_TC_STATS_LEN;
+ break;
+ default:
+ WARN_ON(1);
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static void __mlxsw_sp_port_get_stats(struct net_device *dev,
+ enum mlxsw_reg_ppcnt_grp grp, int prio,
+ u64 *data, int data_index)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ struct mlxsw_sp_port_hw_stats *hw_stats;
+ char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
+ int i, len;
+ int err;
+
+ err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp);
+ if (err)
+ return;
+ mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl);
+ for (i = 0; i < len; i++) {
+ data[data_index + i] = hw_stats[i].getter(ppcnt_pl);
+ if (!hw_stats[i].cells_bytes)
+ continue;
+ data[data_index + i] = mlxsw_sp_cells_bytes(mlxsw_sp,
+ data[data_index + i]);
+ }
+}
+
+static void mlxsw_sp_port_get_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+ int i, data_index = 0;
+
+ /* IEEE 802.3 Counters */
+ __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_IEEE_8023_CNT, 0,
+ data, data_index);
+ data_index = MLXSW_SP_PORT_HW_STATS_LEN;
+
+ /* RFC 2863 Counters */
+ __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2863_CNT, 0,
+ data, data_index);
+ data_index += MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN;
+
+ /* RFC 2819 Counters */
+ __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2819_CNT, 0,
+ data, data_index);
+ data_index += MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
+
+ /* RFC 3635 Counters */
+ __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_3635_CNT, 0,
+ data, data_index);
+ data_index += MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN;
+
+ /* Extended Counters */
+ __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_EXT_CNT, 0,
+ data, data_index);
+ data_index += MLXSW_SP_PORT_HW_EXT_STATS_LEN;
+
+ /* Discard Counters */
+ __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_DISCARD_CNT, 0,
+ data, data_index);
+ data_index += MLXSW_SP_PORT_HW_DISCARD_STATS_LEN;
+
+ /* Per-Priority Counters */
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+ __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_PRIO_CNT, i,
+ data, data_index);
+ data_index += MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
+ }
+
+ /* Per-TC Counters */
+ for (i = 0; i < TC_MAX_QUEUE; i++) {
+ __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_TC_CNT, i,
+ data, data_index);
+ data_index += MLXSW_SP_PORT_HW_TC_STATS_LEN;
+ }
+
+ /* PTP counters */
+ mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats(mlxsw_sp_port,
+ data, data_index);
+ data_index += mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats_count();
+}
+
+static int mlxsw_sp_port_get_sset_count(struct net_device *dev, int sset)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+
+ switch (sset) {
+ case ETH_SS_STATS:
+ return MLXSW_SP_PORT_ETHTOOL_STATS_LEN +
+ mlxsw_sp_port->mlxsw_sp->ptp_ops->get_stats_count();
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void
+mlxsw_sp_port_get_link_supported(struct mlxsw_sp *mlxsw_sp, u32 eth_proto_cap,
+ u8 width, struct ethtool_link_ksettings *cmd)
+{
+ const struct mlxsw_sp_port_type_speed_ops *ops;
+
+ ops = mlxsw_sp->port_type_speed_ops;
+
+ ethtool_link_ksettings_add_link_mode(cmd, supported, Asym_Pause);
+ ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
+ ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
+
+ ops->from_ptys_supported_port(mlxsw_sp, eth_proto_cap, cmd);
+ ops->from_ptys_link(mlxsw_sp, eth_proto_cap, width,
+ cmd->link_modes.supported);
+}
+
+static void
+mlxsw_sp_port_get_link_advertise(struct mlxsw_sp *mlxsw_sp,
+ u32 eth_proto_admin, bool autoneg, u8 width,
+ struct ethtool_link_ksettings *cmd)
+{
+ const struct mlxsw_sp_port_type_speed_ops *ops;
+
+ ops = mlxsw_sp->port_type_speed_ops;
+
+ if (!autoneg)
+ return;
+
+ ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
+ ops->from_ptys_link(mlxsw_sp, eth_proto_admin, width,
+ cmd->link_modes.advertising);
+}
+
+static u8
+mlxsw_sp_port_connector_port(enum mlxsw_reg_ptys_connector_type connector_type)
+{
+ switch (connector_type) {
+ case MLXSW_REG_PTYS_CONNECTOR_TYPE_UNKNOWN_OR_NO_CONNECTOR:
+ return PORT_OTHER;
+ case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_NONE:
+ return PORT_NONE;
+ case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_TP:
+ return PORT_TP;
+ case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_AUI:
+ return PORT_AUI;
+ case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_BNC:
+ return PORT_BNC;
+ case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_MII:
+ return PORT_MII;
+ case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_FIBRE:
+ return PORT_FIBRE;
+ case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_DA:
+ return PORT_DA;
+ case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_OTHER:
+ return PORT_OTHER;
+ default:
+ WARN_ON_ONCE(1);
+ return PORT_OTHER;
+ }
+}
+
+static int mlxsw_sp_port_get_link_ksettings(struct net_device *dev,
+ struct ethtool_link_ksettings *cmd)
+{
+ u32 eth_proto_cap, eth_proto_admin, eth_proto_oper;
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ const struct mlxsw_sp_port_type_speed_ops *ops;
+ char ptys_pl[MLXSW_REG_PTYS_LEN];
+ u8 connector_type;
+ bool autoneg;
+ int err;
+
+ ops = mlxsw_sp->port_type_speed_ops;
+
+ autoneg = mlxsw_sp_port->link.autoneg;
+ ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
+ 0, false);
+ err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
+ if (err)
+ return err;
+ ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, &eth_proto_cap,
+ &eth_proto_admin, &eth_proto_oper);
+
+ mlxsw_sp_port_get_link_supported(mlxsw_sp, eth_proto_cap,
+ mlxsw_sp_port->mapping.width, cmd);
+
+ mlxsw_sp_port_get_link_advertise(mlxsw_sp, eth_proto_admin, autoneg,
+ mlxsw_sp_port->mapping.width, cmd);
+
+ cmd->base.autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ connector_type = mlxsw_reg_ptys_connector_type_get(ptys_pl);
+ cmd->base.port = mlxsw_sp_port_connector_port(connector_type);
+ ops->from_ptys_speed_duplex(mlxsw_sp, netif_carrier_ok(dev),
+ eth_proto_oper, cmd);
+
+ return 0;
+}
+
+static int
+mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
+ const struct ethtool_link_ksettings *cmd)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ const struct mlxsw_sp_port_type_speed_ops *ops;
+ char ptys_pl[MLXSW_REG_PTYS_LEN];
+ u32 eth_proto_cap, eth_proto_new;
+ bool autoneg;
+ int err;
+
+ ops = mlxsw_sp->port_type_speed_ops;
+
+ ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
+ 0, false);
+ err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
+ if (err)
+ return err;
+ ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, &eth_proto_cap, NULL, NULL);
+
+ autoneg = cmd->base.autoneg == AUTONEG_ENABLE;
+ eth_proto_new = autoneg ?
+ ops->to_ptys_advert_link(mlxsw_sp, mlxsw_sp_port->mapping.width,
+ cmd) :
+ ops->to_ptys_speed(mlxsw_sp, mlxsw_sp_port->mapping.width,
+ cmd->base.speed);
+
+ eth_proto_new = eth_proto_new & eth_proto_cap;
+ if (!eth_proto_new) {
+ netdev_err(dev, "No supported speed requested\n");
+ return -EINVAL;
+ }
+
+ ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
+ eth_proto_new, autoneg);
+ err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
+ if (err)
+ return err;
+
+ mlxsw_sp_port->link.autoneg = autoneg;
+
+ if (!netif_running(dev))
+ return 0;
+
+ mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
+ mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
+
+ return 0;
+}
+
+static int mlxsw_sp_get_module_info(struct net_device *netdev,
+ struct ethtool_modinfo *modinfo)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ int err;
+
+ err = mlxsw_env_get_module_info(mlxsw_sp->core,
+ mlxsw_sp_port->mapping.module,
+ modinfo);
+
+ return err;
+}
+
+static int mlxsw_sp_get_module_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *ee, u8 *data)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ int err;
+
+ err = mlxsw_env_get_module_eeprom(netdev, mlxsw_sp->core,
+ mlxsw_sp_port->mapping.module, ee,
+ data);
+
+ return err;
+}
+
+static int
+mlxsw_sp_get_ts_info(struct net_device *netdev, struct ethtool_ts_info *info)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+
+ return mlxsw_sp->ptp_ops->get_ts_info(mlxsw_sp, info);
+}
+
+const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
+ .get_drvinfo = mlxsw_sp_port_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_link_ext_state = mlxsw_sp_port_get_link_ext_state,
+ .get_pauseparam = mlxsw_sp_port_get_pauseparam,
+ .set_pauseparam = mlxsw_sp_port_set_pauseparam,
+ .get_strings = mlxsw_sp_port_get_strings,
+ .set_phys_id = mlxsw_sp_port_set_phys_id,
+ .get_ethtool_stats = mlxsw_sp_port_get_stats,
+ .get_sset_count = mlxsw_sp_port_get_sset_count,
+ .get_link_ksettings = mlxsw_sp_port_get_link_ksettings,
+ .set_link_ksettings = mlxsw_sp_port_set_link_ksettings,
+ .get_module_info = mlxsw_sp_get_module_info,
+ .get_module_eeprom = mlxsw_sp_get_module_eeprom,
+ .get_ts_info = mlxsw_sp_get_ts_info,
+};
+
+struct mlxsw_sp1_port_link_mode {
+ enum ethtool_link_mode_bit_indices mask_ethtool;
+ u32 mask;
+ u32 speed;
+};
+
+static const struct mlxsw_sp1_port_link_mode mlxsw_sp1_port_link_mode[] = {
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_100BASE_T,
+ .mask_ethtool = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+ .speed = SPEED_100,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_SGMII |
+ MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX,
+ .mask_ethtool = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+ .speed = SPEED_1000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_T,
+ .mask_ethtool = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+ .speed = SPEED_10000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CX4 |
+ MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4,
+ .mask_ethtool = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+ .speed = SPEED_10000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
+ MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
+ MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
+ MLXSW_REG_PTYS_ETH_SPEED_10GBASE_ER_LR,
+ .mask_ethtool = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+ .speed = SPEED_10000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_20GBASE_KR2,
+ .mask_ethtool = ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
+ .speed = SPEED_20000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4,
+ .mask_ethtool = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
+ .speed = SPEED_40000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4,
+ .mask_ethtool = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
+ .speed = SPEED_40000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4,
+ .mask_ethtool = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
+ .speed = SPEED_40000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_LR4_ER4,
+ .mask_ethtool = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
+ .speed = SPEED_40000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR,
+ .mask_ethtool = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
+ .speed = SPEED_25000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR,
+ .mask_ethtool = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
+ .speed = SPEED_25000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR,
+ .mask_ethtool = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
+ .speed = SPEED_25000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_CR2,
+ .mask_ethtool = ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
+ .speed = SPEED_50000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR2,
+ .mask_ethtool = ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
+ .speed = SPEED_50000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_SR2,
+ .mask_ethtool = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
+ .speed = SPEED_50000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4,
+ .mask_ethtool = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
+ .speed = SPEED_100000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4,
+ .mask_ethtool = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
+ .speed = SPEED_100000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4,
+ .mask_ethtool = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
+ .speed = SPEED_100000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4,
+ .mask_ethtool = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
+ .speed = SPEED_100000,
+ },
+};
+
+#define MLXSW_SP1_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp1_port_link_mode)
+
+static void
+mlxsw_sp1_from_ptys_supported_port(struct mlxsw_sp *mlxsw_sp,
+ u32 ptys_eth_proto,
+ struct ethtool_link_ksettings *cmd)
+{
+ if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
+ MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
+ MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4 |
+ MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4 |
+ MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 |
+ MLXSW_REG_PTYS_ETH_SPEED_SGMII))
+ ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
+
+ if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
+ MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4 |
+ MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4 |
+ MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 |
+ MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX))
+ ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane);
+}
+
+static void
+mlxsw_sp1_from_ptys_link(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto,
+ u8 width, unsigned long *mode)
+{
+ int i;
+
+ for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
+ if (ptys_eth_proto & mlxsw_sp1_port_link_mode[i].mask)
+ __set_bit(mlxsw_sp1_port_link_mode[i].mask_ethtool,
+ mode);
+ }
+}
+
+static u32
+mlxsw_sp1_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto)
+{
+ int i;
+
+ for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
+ if (ptys_eth_proto & mlxsw_sp1_port_link_mode[i].mask)
+ return mlxsw_sp1_port_link_mode[i].speed;
+ }
+
+ return SPEED_UNKNOWN;
+}
+
+static void
+mlxsw_sp1_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
+ u32 ptys_eth_proto,
+ struct ethtool_link_ksettings *cmd)
+{
+ cmd->base.speed = SPEED_UNKNOWN;
+ cmd->base.duplex = DUPLEX_UNKNOWN;
+
+ if (!carrier_ok)
+ return;
+
+ cmd->base.speed = mlxsw_sp1_from_ptys_speed(mlxsw_sp, ptys_eth_proto);
+ if (cmd->base.speed != SPEED_UNKNOWN)
+ cmd->base.duplex = DUPLEX_FULL;
+}
+
+static u32
+mlxsw_sp1_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp, u8 width,
+ const struct ethtool_link_ksettings *cmd)
+{
+ u32 ptys_proto = 0;
+ int i;
+
+ for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
+ if (test_bit(mlxsw_sp1_port_link_mode[i].mask_ethtool,
+ cmd->link_modes.advertising))
+ ptys_proto |= mlxsw_sp1_port_link_mode[i].mask;
+ }
+ return ptys_proto;
+}
+
+static u32 mlxsw_sp1_to_ptys_speed(struct mlxsw_sp *mlxsw_sp, u8 width,
+ u32 speed)
+{
+ u32 ptys_proto = 0;
+ int i;
+
+ for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
+ if (speed == mlxsw_sp1_port_link_mode[i].speed)
+ ptys_proto |= mlxsw_sp1_port_link_mode[i].mask;
+ }
+ return ptys_proto;
+}
+
+static void
+mlxsw_sp1_reg_ptys_eth_pack(struct mlxsw_sp *mlxsw_sp, char *payload,
+ u8 local_port, u32 proto_admin, bool autoneg)
+{
+ mlxsw_reg_ptys_eth_pack(payload, local_port, proto_admin, autoneg);
+}
+
+static void
+mlxsw_sp1_reg_ptys_eth_unpack(struct mlxsw_sp *mlxsw_sp, char *payload,
+ u32 *p_eth_proto_cap, u32 *p_eth_proto_admin,
+ u32 *p_eth_proto_oper)
+{
+ mlxsw_reg_ptys_eth_unpack(payload, p_eth_proto_cap, p_eth_proto_admin,
+ p_eth_proto_oper);
+}
+
+const struct mlxsw_sp_port_type_speed_ops mlxsw_sp1_port_type_speed_ops = {
+ .from_ptys_supported_port = mlxsw_sp1_from_ptys_supported_port,
+ .from_ptys_link = mlxsw_sp1_from_ptys_link,
+ .from_ptys_speed = mlxsw_sp1_from_ptys_speed,
+ .from_ptys_speed_duplex = mlxsw_sp1_from_ptys_speed_duplex,
+ .to_ptys_advert_link = mlxsw_sp1_to_ptys_advert_link,
+ .to_ptys_speed = mlxsw_sp1_to_ptys_speed,
+ .reg_ptys_eth_pack = mlxsw_sp1_reg_ptys_eth_pack,
+ .reg_ptys_eth_unpack = mlxsw_sp1_reg_ptys_eth_unpack,
+};
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_sgmii_100m[] = {
+ ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_sgmii_100m)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_1000base_x_sgmii[] = {
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_1000base_x_sgmii)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii[] = {
+ ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_2_5GBASE_X_2_5GMII_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_5gbase_r[] = {
+ ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_5gbase_r)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g[] = {
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
+ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g[] = {
+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr[] = {
+ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2[] = {
+ ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr[] = {
+ ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseDR_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4[] = {
+ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2[] = {
+ ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4[] = {
+ ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
+ ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT,
+ ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4)
+
+static const enum ethtool_link_mode_bit_indices
+mlxsw_sp2_mask_ethtool_400gaui_8[] = {
+ ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT,
+ ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT,
+ ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT,
+ ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT,
+ ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT,
+};
+
+#define MLXSW_SP2_MASK_ETHTOOL_400GAUI_8_LEN \
+ ARRAY_SIZE(mlxsw_sp2_mask_ethtool_400gaui_8)
+
+#define MLXSW_SP_PORT_MASK_WIDTH_1X BIT(0)
+#define MLXSW_SP_PORT_MASK_WIDTH_2X BIT(1)
+#define MLXSW_SP_PORT_MASK_WIDTH_4X BIT(2)
+#define MLXSW_SP_PORT_MASK_WIDTH_8X BIT(3)
+
+static u8 mlxsw_sp_port_mask_width_get(u8 width)
+{
+ switch (width) {
+ case 1:
+ return MLXSW_SP_PORT_MASK_WIDTH_1X;
+ case 2:
+ return MLXSW_SP_PORT_MASK_WIDTH_2X;
+ case 4:
+ return MLXSW_SP_PORT_MASK_WIDTH_4X;
+ case 8:
+ return MLXSW_SP_PORT_MASK_WIDTH_8X;
+ default:
+ WARN_ON_ONCE(1);
+ return 0;
+ }
+}
+
+struct mlxsw_sp2_port_link_mode {
+ const enum ethtool_link_mode_bit_indices *mask_ethtool;
+ int m_ethtool_len;
+ u32 mask;
+ u32 speed;
+ u8 mask_width;
+};
+
+static const struct mlxsw_sp2_port_link_mode mlxsw_sp2_port_link_mode[] = {
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_SGMII_100M,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_sgmii_100m,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
+ MLXSW_SP_PORT_MASK_WIDTH_2X |
+ MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_100,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_1000BASE_X_SGMII,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_1000base_x_sgmii,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
+ MLXSW_SP_PORT_MASK_WIDTH_2X |
+ MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_1000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_2_5GBASE_X_2_5GMII,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_2_5GBASE_X_2_5GMII_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
+ MLXSW_SP_PORT_MASK_WIDTH_2X |
+ MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_2500,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_5GBASE_R,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_5gbase_r,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
+ MLXSW_SP_PORT_MASK_WIDTH_2X |
+ MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_5000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XFI_XAUI_1_10G,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
+ MLXSW_SP_PORT_MASK_WIDTH_2X |
+ MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_10000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_XLAUI_4_XLPPI_4_40G,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_40000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X |
+ MLXSW_SP_PORT_MASK_WIDTH_2X |
+ MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_25000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_2_LAUI_2_50GBASE_CR2_KR2,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_2X |
+ MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_50000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_1_LAUI_1_50GBASE_CR_KR,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_1X,
+ .speed = SPEED_50000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_CAUI_4_100GBASE_CR4_KR4,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_100000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_100GAUI_2_100GBASE_CR2_KR2,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_2X,
+ .speed = SPEED_100000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_200GAUI_4_200GBASE_CR4_KR4,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_4X |
+ MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_200000,
+ },
+ {
+ .mask = MLXSW_REG_PTYS_EXT_ETH_SPEED_400GAUI_8,
+ .mask_ethtool = mlxsw_sp2_mask_ethtool_400gaui_8,
+ .m_ethtool_len = MLXSW_SP2_MASK_ETHTOOL_400GAUI_8_LEN,
+ .mask_width = MLXSW_SP_PORT_MASK_WIDTH_8X,
+ .speed = SPEED_400000,
+ },
+};
+
+#define MLXSW_SP2_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp2_port_link_mode)
+
+static void
+mlxsw_sp2_from_ptys_supported_port(struct mlxsw_sp *mlxsw_sp,
+ u32 ptys_eth_proto,
+ struct ethtool_link_ksettings *cmd)
+{
+ ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
+ ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane);
+}
+
+static void
+mlxsw_sp2_set_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode,
+ unsigned long *mode)
+{
+ int i;
+
+ for (i = 0; i < link_mode->m_ethtool_len; i++)
+ __set_bit(link_mode->mask_ethtool[i], mode);
+}
+
+static void
+mlxsw_sp2_from_ptys_link(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto,
+ u8 width, unsigned long *mode)
+{
+ u8 mask_width = mlxsw_sp_port_mask_width_get(width);
+ int i;
+
+ for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
+ if ((ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask) &&
+ (mask_width & mlxsw_sp2_port_link_mode[i].mask_width))
+ mlxsw_sp2_set_bit_ethtool(&mlxsw_sp2_port_link_mode[i],
+ mode);
+ }
+}
+
+static u32
+mlxsw_sp2_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto)
+{
+ int i;
+
+ for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
+ if (ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask)
+ return mlxsw_sp2_port_link_mode[i].speed;
+ }
+
+ return SPEED_UNKNOWN;
+}
+
+static void
+mlxsw_sp2_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
+ u32 ptys_eth_proto,
+ struct ethtool_link_ksettings *cmd)
+{
+ cmd->base.speed = SPEED_UNKNOWN;
+ cmd->base.duplex = DUPLEX_UNKNOWN;
+
+ if (!carrier_ok)
+ return;
+
+ cmd->base.speed = mlxsw_sp2_from_ptys_speed(mlxsw_sp, ptys_eth_proto);
+ if (cmd->base.speed != SPEED_UNKNOWN)
+ cmd->base.duplex = DUPLEX_FULL;
+}
+
+static bool
+mlxsw_sp2_test_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode,
+ const unsigned long *mode)
+{
+ int cnt = 0;
+ int i;
+
+ for (i = 0; i < link_mode->m_ethtool_len; i++) {
+ if (test_bit(link_mode->mask_ethtool[i], mode))
+ cnt++;
+ }
+
+ return cnt == link_mode->m_ethtool_len;
+}
+
+static u32
+mlxsw_sp2_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp, u8 width,
+ const struct ethtool_link_ksettings *cmd)
+{
+ u8 mask_width = mlxsw_sp_port_mask_width_get(width);
+ u32 ptys_proto = 0;
+ int i;
+
+ for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
+ if ((mask_width & mlxsw_sp2_port_link_mode[i].mask_width) &&
+ mlxsw_sp2_test_bit_ethtool(&mlxsw_sp2_port_link_mode[i],
+ cmd->link_modes.advertising))
+ ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
+ }
+ return ptys_proto;
+}
+
+static u32 mlxsw_sp2_to_ptys_speed(struct mlxsw_sp *mlxsw_sp,
+ u8 width, u32 speed)
+{
+ u8 mask_width = mlxsw_sp_port_mask_width_get(width);
+ u32 ptys_proto = 0;
+ int i;
+
+ for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
+ if ((speed == mlxsw_sp2_port_link_mode[i].speed) &&
+ (mask_width & mlxsw_sp2_port_link_mode[i].mask_width))
+ ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
+ }
+ return ptys_proto;
+}
+
+static void
+mlxsw_sp2_reg_ptys_eth_pack(struct mlxsw_sp *mlxsw_sp, char *payload,
+ u8 local_port, u32 proto_admin,
+ bool autoneg)
+{
+ mlxsw_reg_ptys_ext_eth_pack(payload, local_port, proto_admin, autoneg);
+}
+
+static void
+mlxsw_sp2_reg_ptys_eth_unpack(struct mlxsw_sp *mlxsw_sp, char *payload,
+ u32 *p_eth_proto_cap, u32 *p_eth_proto_admin,
+ u32 *p_eth_proto_oper)
+{
+ mlxsw_reg_ptys_ext_eth_unpack(payload, p_eth_proto_cap,
+ p_eth_proto_admin, p_eth_proto_oper);
+}
+
+const struct mlxsw_sp_port_type_speed_ops mlxsw_sp2_port_type_speed_ops = {
+ .from_ptys_supported_port = mlxsw_sp2_from_ptys_supported_port,
+ .from_ptys_link = mlxsw_sp2_from_ptys_link,
+ .from_ptys_speed = mlxsw_sp2_from_ptys_speed,
+ .from_ptys_speed_duplex = mlxsw_sp2_from_ptys_speed_duplex,
+ .to_ptys_advert_link = mlxsw_sp2_to_ptys_advert_link,
+ .to_ptys_speed = mlxsw_sp2_to_ptys_speed,
+ .reg_ptys_eth_pack = mlxsw_sp2_reg_ptys_eth_pack,
+ .reg_ptys_eth_unpack = mlxsw_sp2_reg_ptys_eth_unpack,
+};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flow.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flow.c
index 47b66f347ff1..0456cda33808 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flow.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flow.c
@@ -219,8 +219,7 @@ static int mlxsw_sp_setup_tc_block_bind(struct mlxsw_sp_port *mlxsw_sp_port,
mlxsw_sp_tc_block_release);
if (IS_ERR(block_cb)) {
mlxsw_sp_flow_block_destroy(flow_block);
- err = PTR_ERR(block_cb);
- goto err_cb_register;
+ return PTR_ERR(block_cb);
}
register_block = true;
} else {
@@ -247,7 +246,6 @@ static int mlxsw_sp_setup_tc_block_bind(struct mlxsw_sp_port *mlxsw_sp_port,
err_block_bind:
if (!flow_block_cb_decref(block_cb))
flow_block_cb_free(block_cb);
-err_cb_register:
return err;
}
@@ -279,18 +277,10 @@ static void mlxsw_sp_setup_tc_block_unbind(struct mlxsw_sp_port *mlxsw_sp_port,
}
}
-int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
- struct flow_block_offload *f)
+int mlxsw_sp_setup_tc_block_clsact(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct flow_block_offload *f,
+ bool ingress)
{
- bool ingress;
-
- if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
- ingress = true;
- else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS)
- ingress = false;
- else
- return -EOPNOTSUPP;
-
f->driver_block_list = &mlxsw_sp_block_cb_list;
switch (f->command) {
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
index 51e1b3930c56..41855e58564b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
@@ -4,6 +4,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
+#include <linux/log2.h>
#include <net/net_namespace.h>
#include <net/flow_dissector.h>
#include <net/pkt_cls.h>
@@ -22,6 +23,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
{
const struct flow_action_entry *act;
int mirror_act_count = 0;
+ int police_act_count = 0;
int err, i;
if (!flow_action_has_entries(flow_action))
@@ -180,6 +182,28 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
return err;
break;
}
+ case FLOW_ACTION_POLICE: {
+ u32 burst;
+
+ if (police_act_count++) {
+ NL_SET_ERR_MSG_MOD(extack, "Multiple police actions per rule are not supported");
+ return -EOPNOTSUPP;
+ }
+
+ /* The kernel might adjust the requested burst size so
+ * that it is not exactly a power of two. Re-adjust it
+ * here since the hardware only supports burst sizes
+ * that are a power of two.
+ */
+ burst = roundup_pow_of_two(act->police.burst);
+ err = mlxsw_sp_acl_rulei_act_police(mlxsw_sp, rulei,
+ act->police.index,
+ act->police.rate_bytes_ps,
+ burst, extack);
+ if (err)
+ return err;
+ break;
+ }
default:
NL_SET_ERR_MSG_MOD(extack, "Unsupported action");
dev_err(mlxsw_sp->bus_info->dev, "Unsupported action\n");
@@ -616,6 +640,7 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
u64 packets;
u64 lastuse;
u64 bytes;
+ u64 drops;
int err;
ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
@@ -629,11 +654,12 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
return -EINVAL;
err = mlxsw_sp_acl_rule_get_stats(mlxsw_sp, rule, &packets, &bytes,
- &lastuse, &used_hw_stats);
+ &drops, &lastuse, &used_hw_stats);
if (err)
goto err_rule_get_stats;
- flow_stats_update(&f->stats, bytes, packets, lastuse, used_hw_stats);
+ flow_stats_update(&f->stats, bytes, packets, drops, lastuse,
+ used_hw_stats);
mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
index f1a44a8eda55..f30599ad6019 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
@@ -10,29 +10,6 @@
#include "spectrum_span.h"
#include "reg.h"
-enum mlxsw_sp_mall_action_type {
- MLXSW_SP_MALL_ACTION_TYPE_MIRROR,
- MLXSW_SP_MALL_ACTION_TYPE_SAMPLE,
-};
-
-struct mlxsw_sp_mall_mirror_entry {
- const struct net_device *to_dev;
- int span_id;
-};
-
-struct mlxsw_sp_mall_entry {
- struct list_head list;
- unsigned long cookie;
- unsigned int priority;
- enum mlxsw_sp_mall_action_type type;
- bool ingress;
- union {
- struct mlxsw_sp_mall_mirror_entry mirror;
- struct mlxsw_sp_port_sample sample;
- };
- struct rcu_head rcu;
-};
-
static struct mlxsw_sp_mall_entry *
mlxsw_sp_mall_entry_find(struct mlxsw_sp_flow_block *block, unsigned long cookie)
{
@@ -50,6 +27,7 @@ mlxsw_sp_mall_port_mirror_add(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_mall_entry *mall_entry)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ struct mlxsw_sp_span_agent_parms agent_parms = {};
struct mlxsw_sp_span_trigger_parms parms;
enum mlxsw_sp_span_trigger trigger;
int err;
@@ -59,8 +37,9 @@ mlxsw_sp_mall_port_mirror_add(struct mlxsw_sp_port *mlxsw_sp_port,
return -EINVAL;
}
- err = mlxsw_sp_span_agent_get(mlxsw_sp, mall_entry->mirror.to_dev,
- &mall_entry->mirror.span_id);
+ agent_parms.to_dev = mall_entry->mirror.to_dev;
+ err = mlxsw_sp_span_agent_get(mlxsw_sp, &mall_entry->mirror.span_id,
+ &agent_parms);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_policer.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_policer.c
new file mode 100644
index 000000000000..39052e5c12fd
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_policer.c
@@ -0,0 +1,468 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/* Copyright (c) 2020 Mellanox Technologies. All rights reserved */
+
+#include <linux/idr.h>
+#include <linux/log2.h>
+#include <linux/mutex.h>
+#include <linux/netlink.h>
+#include <net/devlink.h>
+
+#include "spectrum.h"
+
+struct mlxsw_sp_policer_family {
+ enum mlxsw_sp_policer_type type;
+ enum mlxsw_reg_qpcr_g qpcr_type;
+ struct mlxsw_sp *mlxsw_sp;
+ u16 start_index; /* Inclusive */
+ u16 end_index; /* Exclusive */
+ struct idr policer_idr;
+ struct mutex lock; /* Protects policer_idr */
+ atomic_t policers_count;
+ const struct mlxsw_sp_policer_family_ops *ops;
+};
+
+struct mlxsw_sp_policer {
+ struct mlxsw_sp_policer_params params;
+ u16 index;
+};
+
+struct mlxsw_sp_policer_family_ops {
+ int (*init)(struct mlxsw_sp_policer_family *family);
+ void (*fini)(struct mlxsw_sp_policer_family *family);
+ int (*policer_index_alloc)(struct mlxsw_sp_policer_family *family,
+ struct mlxsw_sp_policer *policer);
+ struct mlxsw_sp_policer * (*policer_index_free)(struct mlxsw_sp_policer_family *family,
+ u16 policer_index);
+ int (*policer_init)(struct mlxsw_sp_policer_family *family,
+ const struct mlxsw_sp_policer *policer);
+ int (*policer_params_check)(const struct mlxsw_sp_policer_family *family,
+ const struct mlxsw_sp_policer_params *params,
+ struct netlink_ext_ack *extack);
+};
+
+struct mlxsw_sp_policer_core {
+ struct mlxsw_sp_policer_family *family_arr[MLXSW_SP_POLICER_TYPE_MAX + 1];
+ const struct mlxsw_sp_policer_core_ops *ops;
+ u8 lowest_bs_bits;
+ u8 highest_bs_bits;
+};
+
+struct mlxsw_sp_policer_core_ops {
+ int (*init)(struct mlxsw_sp_policer_core *policer_core);
+};
+
+static u64 mlxsw_sp_policer_rate_bytes_ps_kbps(u64 rate_bytes_ps)
+{
+ return div_u64(rate_bytes_ps, 1000) * BITS_PER_BYTE;
+}
+
+static u8 mlxsw_sp_policer_burst_bytes_hw_units(u64 burst_bytes)
+{
+ /* Provided burst size is in bytes. The ASIC burst size value is
+ * (2 ^ bs) * 512 bits. Convert the provided size to 512-bit units.
+ */
+ u64 bs512 = div_u64(burst_bytes, 64);
+
+ if (!bs512)
+ return 0;
+
+ return fls64(bs512) - 1;
+}
+
+static u64 mlxsw_sp_policer_single_rate_occ_get(void *priv)
+{
+ struct mlxsw_sp_policer_family *family = priv;
+
+ return atomic_read(&family->policers_count);
+}
+
+static int
+mlxsw_sp_policer_single_rate_family_init(struct mlxsw_sp_policer_family *family)
+{
+ struct mlxsw_core *core = family->mlxsw_sp->core;
+ struct devlink *devlink;
+
+ /* CPU policers are allocated from the first N policers in the global
+ * range, so skip them.
+ */
+ if (!MLXSW_CORE_RES_VALID(core, MAX_GLOBAL_POLICERS) ||
+ !MLXSW_CORE_RES_VALID(core, MAX_CPU_POLICERS))
+ return -EIO;
+
+ family->start_index = MLXSW_CORE_RES_GET(core, MAX_CPU_POLICERS);
+ family->end_index = MLXSW_CORE_RES_GET(core, MAX_GLOBAL_POLICERS);
+
+ atomic_set(&family->policers_count, 0);
+ devlink = priv_to_devlink(core);
+ devlink_resource_occ_get_register(devlink,
+ MLXSW_SP_RESOURCE_SINGLE_RATE_POLICERS,
+ mlxsw_sp_policer_single_rate_occ_get,
+ family);
+
+ return 0;
+}
+
+static void
+mlxsw_sp_policer_single_rate_family_fini(struct mlxsw_sp_policer_family *family)
+{
+ struct devlink *devlink = priv_to_devlink(family->mlxsw_sp->core);
+
+ devlink_resource_occ_get_unregister(devlink,
+ MLXSW_SP_RESOURCE_SINGLE_RATE_POLICERS);
+ WARN_ON(atomic_read(&family->policers_count) != 0);
+}
+
+static int
+mlxsw_sp_policer_single_rate_index_alloc(struct mlxsw_sp_policer_family *family,
+ struct mlxsw_sp_policer *policer)
+{
+ int id;
+
+ mutex_lock(&family->lock);
+ id = idr_alloc(&family->policer_idr, policer, family->start_index,
+ family->end_index, GFP_KERNEL);
+ mutex_unlock(&family->lock);
+
+ if (id < 0)
+ return id;
+
+ atomic_inc(&family->policers_count);
+ policer->index = id;
+
+ return 0;
+}
+
+static struct mlxsw_sp_policer *
+mlxsw_sp_policer_single_rate_index_free(struct mlxsw_sp_policer_family *family,
+ u16 policer_index)
+{
+ struct mlxsw_sp_policer *policer;
+
+ atomic_dec(&family->policers_count);
+
+ mutex_lock(&family->lock);
+ policer = idr_remove(&family->policer_idr, policer_index);
+ mutex_unlock(&family->lock);
+
+ WARN_ON(!policer);
+
+ return policer;
+}
+
+static int
+mlxsw_sp_policer_single_rate_init(struct mlxsw_sp_policer_family *family,
+ const struct mlxsw_sp_policer *policer)
+{
+ u64 rate_kbps = mlxsw_sp_policer_rate_bytes_ps_kbps(policer->params.rate);
+ u8 bs = mlxsw_sp_policer_burst_bytes_hw_units(policer->params.burst);
+ struct mlxsw_sp *mlxsw_sp = family->mlxsw_sp;
+ char qpcr_pl[MLXSW_REG_QPCR_LEN];
+
+ mlxsw_reg_qpcr_pack(qpcr_pl, policer->index, MLXSW_REG_QPCR_IR_UNITS_K,
+ true, rate_kbps, bs);
+ mlxsw_reg_qpcr_clear_counter_set(qpcr_pl, true);
+
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
+}
+
+static int
+mlxsw_sp_policer_single_rate_params_check(const struct mlxsw_sp_policer_family *family,
+ const struct mlxsw_sp_policer_params *params,
+ struct netlink_ext_ack *extack)
+{
+ struct mlxsw_sp_policer_core *policer_core = family->mlxsw_sp->policer_core;
+ u64 rate_bps = params->rate * BITS_PER_BYTE;
+ u8 bs;
+
+ if (!params->bytes) {
+ NL_SET_ERR_MSG_MOD(extack, "Only bandwidth policing is currently supported by single rate policers");
+ return -EINVAL;
+ }
+
+ if (!is_power_of_2(params->burst)) {
+ NL_SET_ERR_MSG_MOD(extack, "Policer burst size is not power of two");
+ return -EINVAL;
+ }
+
+ bs = mlxsw_sp_policer_burst_bytes_hw_units(params->burst);
+
+ if (bs < policer_core->lowest_bs_bits) {
+ NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
+ return -EINVAL;
+ }
+
+ if (bs > policer_core->highest_bs_bits) {
+ NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
+ return -EINVAL;
+ }
+
+ if (rate_bps < MLXSW_REG_QPCR_LOWEST_CIR_BITS) {
+ NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
+ return -EINVAL;
+ }
+
+ if (rate_bps > MLXSW_REG_QPCR_HIGHEST_CIR_BITS) {
+ NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct mlxsw_sp_policer_family_ops mlxsw_sp_policer_single_rate_ops = {
+ .init = mlxsw_sp_policer_single_rate_family_init,
+ .fini = mlxsw_sp_policer_single_rate_family_fini,
+ .policer_index_alloc = mlxsw_sp_policer_single_rate_index_alloc,
+ .policer_index_free = mlxsw_sp_policer_single_rate_index_free,
+ .policer_init = mlxsw_sp_policer_single_rate_init,
+ .policer_params_check = mlxsw_sp_policer_single_rate_params_check,
+};
+
+static const struct mlxsw_sp_policer_family mlxsw_sp_policer_single_rate_family = {
+ .type = MLXSW_SP_POLICER_TYPE_SINGLE_RATE,
+ .qpcr_type = MLXSW_REG_QPCR_G_GLOBAL,
+ .ops = &mlxsw_sp_policer_single_rate_ops,
+};
+
+static const struct mlxsw_sp_policer_family *mlxsw_sp_policer_family_arr[] = {
+ [MLXSW_SP_POLICER_TYPE_SINGLE_RATE] = &mlxsw_sp_policer_single_rate_family,
+};
+
+int mlxsw_sp_policer_add(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_policer_type type,
+ const struct mlxsw_sp_policer_params *params,
+ struct netlink_ext_ack *extack, u16 *p_policer_index)
+{
+ struct mlxsw_sp_policer_family *family;
+ struct mlxsw_sp_policer *policer;
+ int err;
+
+ family = mlxsw_sp->policer_core->family_arr[type];
+
+ err = family->ops->policer_params_check(family, params, extack);
+ if (err)
+ return err;
+
+ policer = kmalloc(sizeof(*policer), GFP_KERNEL);
+ if (!policer)
+ return -ENOMEM;
+ policer->params = *params;
+
+ err = family->ops->policer_index_alloc(family, policer);
+ if (err) {
+ NL_SET_ERR_MSG_MOD(extack, "Failed to allocate policer index");
+ goto err_policer_index_alloc;
+ }
+
+ err = family->ops->policer_init(family, policer);
+ if (err) {
+ NL_SET_ERR_MSG_MOD(extack, "Failed to initialize policer");
+ goto err_policer_init;
+ }
+
+ *p_policer_index = policer->index;
+
+ return 0;
+
+err_policer_init:
+ family->ops->policer_index_free(family, policer->index);
+err_policer_index_alloc:
+ kfree(policer);
+ return err;
+}
+
+void mlxsw_sp_policer_del(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_policer_type type, u16 policer_index)
+{
+ struct mlxsw_sp_policer_family *family;
+ struct mlxsw_sp_policer *policer;
+
+ family = mlxsw_sp->policer_core->family_arr[type];
+ policer = family->ops->policer_index_free(family, policer_index);
+ kfree(policer);
+}
+
+int mlxsw_sp_policer_drops_counter_get(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_policer_type type,
+ u16 policer_index, u64 *p_drops)
+{
+ struct mlxsw_sp_policer_family *family;
+ char qpcr_pl[MLXSW_REG_QPCR_LEN];
+ int err;
+
+ family = mlxsw_sp->policer_core->family_arr[type];
+
+ MLXSW_REG_ZERO(qpcr, qpcr_pl);
+ mlxsw_reg_qpcr_pid_set(qpcr_pl, policer_index);
+ mlxsw_reg_qpcr_g_set(qpcr_pl, family->qpcr_type);
+ err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
+ if (err)
+ return err;
+
+ *p_drops = mlxsw_reg_qpcr_violate_count_get(qpcr_pl);
+
+ return 0;
+}
+
+static int
+mlxsw_sp_policer_family_register(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_policer_family *tmpl)
+{
+ struct mlxsw_sp_policer_family *family;
+ int err;
+
+ family = kmemdup(tmpl, sizeof(*family), GFP_KERNEL);
+ if (!family)
+ return -ENOMEM;
+
+ family->mlxsw_sp = mlxsw_sp;
+ idr_init(&family->policer_idr);
+ mutex_init(&family->lock);
+
+ err = family->ops->init(family);
+ if (err)
+ goto err_family_init;
+
+ if (WARN_ON(family->start_index >= family->end_index)) {
+ err = -EINVAL;
+ goto err_index_check;
+ }
+
+ mlxsw_sp->policer_core->family_arr[tmpl->type] = family;
+
+ return 0;
+
+err_index_check:
+ family->ops->fini(family);
+err_family_init:
+ mutex_destroy(&family->lock);
+ idr_destroy(&family->policer_idr);
+ kfree(family);
+ return err;
+}
+
+static void
+mlxsw_sp_policer_family_unregister(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_policer_family *family)
+{
+ family->ops->fini(family);
+ mutex_destroy(&family->lock);
+ WARN_ON(!idr_is_empty(&family->policer_idr));
+ idr_destroy(&family->policer_idr);
+ kfree(family);
+}
+
+int mlxsw_sp_policers_init(struct mlxsw_sp *mlxsw_sp)
+{
+ struct mlxsw_sp_policer_core *policer_core;
+ int i, err;
+
+ policer_core = kzalloc(sizeof(*policer_core), GFP_KERNEL);
+ if (!policer_core)
+ return -ENOMEM;
+ mlxsw_sp->policer_core = policer_core;
+ policer_core->ops = mlxsw_sp->policer_core_ops;
+
+ err = policer_core->ops->init(policer_core);
+ if (err)
+ goto err_init;
+
+ for (i = 0; i < MLXSW_SP_POLICER_TYPE_MAX + 1; i++) {
+ err = mlxsw_sp_policer_family_register(mlxsw_sp, mlxsw_sp_policer_family_arr[i]);
+ if (err)
+ goto err_family_register;
+ }
+
+ return 0;
+
+err_family_register:
+ for (i--; i >= 0; i--) {
+ struct mlxsw_sp_policer_family *family;
+
+ family = mlxsw_sp->policer_core->family_arr[i];
+ mlxsw_sp_policer_family_unregister(mlxsw_sp, family);
+ }
+err_init:
+ kfree(mlxsw_sp->policer_core);
+ return err;
+}
+
+void mlxsw_sp_policers_fini(struct mlxsw_sp *mlxsw_sp)
+{
+ int i;
+
+ for (i = MLXSW_SP_POLICER_TYPE_MAX; i >= 0; i--) {
+ struct mlxsw_sp_policer_family *family;
+
+ family = mlxsw_sp->policer_core->family_arr[i];
+ mlxsw_sp_policer_family_unregister(mlxsw_sp, family);
+ }
+
+ kfree(mlxsw_sp->policer_core);
+}
+
+int mlxsw_sp_policer_resources_register(struct mlxsw_core *mlxsw_core)
+{
+ u64 global_policers, cpu_policers, single_rate_policers;
+ struct devlink *devlink = priv_to_devlink(mlxsw_core);
+ struct devlink_resource_size_params size_params;
+ int err;
+
+ if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_GLOBAL_POLICERS) ||
+ !MLXSW_CORE_RES_VALID(mlxsw_core, MAX_CPU_POLICERS))
+ return -EIO;
+
+ global_policers = MLXSW_CORE_RES_GET(mlxsw_core, MAX_GLOBAL_POLICERS);
+ cpu_policers = MLXSW_CORE_RES_GET(mlxsw_core, MAX_CPU_POLICERS);
+ single_rate_policers = global_policers - cpu_policers;
+
+ devlink_resource_size_params_init(&size_params, global_policers,
+ global_policers, 1,
+ DEVLINK_RESOURCE_UNIT_ENTRY);
+ err = devlink_resource_register(devlink, "global_policers",
+ global_policers,
+ MLXSW_SP_RESOURCE_GLOBAL_POLICERS,
+ DEVLINK_RESOURCE_ID_PARENT_TOP,
+ &size_params);
+ if (err)
+ return err;
+
+ devlink_resource_size_params_init(&size_params, single_rate_policers,
+ single_rate_policers, 1,
+ DEVLINK_RESOURCE_UNIT_ENTRY);
+ err = devlink_resource_register(devlink, "single_rate_policers",
+ single_rate_policers,
+ MLXSW_SP_RESOURCE_SINGLE_RATE_POLICERS,
+ MLXSW_SP_RESOURCE_GLOBAL_POLICERS,
+ &size_params);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int
+mlxsw_sp1_policer_core_init(struct mlxsw_sp_policer_core *policer_core)
+{
+ policer_core->lowest_bs_bits = MLXSW_REG_QPCR_LOWEST_CBS_BITS_SP1;
+ policer_core->highest_bs_bits = MLXSW_REG_QPCR_HIGHEST_CBS_BITS_SP1;
+
+ return 0;
+}
+
+const struct mlxsw_sp_policer_core_ops mlxsw_sp1_policer_core_ops = {
+ .init = mlxsw_sp1_policer_core_init,
+};
+
+static int
+mlxsw_sp2_policer_core_init(struct mlxsw_sp_policer_core *policer_core)
+{
+ policer_core->lowest_bs_bits = MLXSW_REG_QPCR_LOWEST_CBS_BITS_SP2;
+ policer_core->highest_bs_bits = MLXSW_REG_QPCR_HIGHEST_CBS_BITS_SP2;
+
+ return 0;
+}
+
+const struct mlxsw_sp_policer_core_ops mlxsw_sp2_policer_core_ops = {
+ .init = mlxsw_sp2_policer_core_init,
+};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
index 670a43fe2a00..964fd444bb10 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
@@ -8,6 +8,7 @@
#include <net/red.h>
#include "spectrum.h"
+#include "spectrum_span.h"
#include "reg.h"
#define MLXSW_SP_PRIO_BAND_TO_TCLASS(band) (IEEE_8021QAZ_MAX_TCS - band - 1)
@@ -1272,6 +1273,529 @@ int mlxsw_sp_setup_tc_ets(struct mlxsw_sp_port *mlxsw_sp_port,
}
}
+struct mlxsw_sp_qevent_block {
+ struct list_head binding_list;
+ struct list_head mall_entry_list;
+ struct mlxsw_sp *mlxsw_sp;
+};
+
+struct mlxsw_sp_qevent_binding {
+ struct list_head list;
+ struct mlxsw_sp_port *mlxsw_sp_port;
+ u32 handle;
+ int tclass_num;
+ enum mlxsw_sp_span_trigger span_trigger;
+};
+
+static LIST_HEAD(mlxsw_sp_qevent_block_cb_list);
+
+static int mlxsw_sp_qevent_span_configure(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_mall_entry *mall_entry,
+ struct mlxsw_sp_qevent_binding *qevent_binding,
+ const struct mlxsw_sp_span_agent_parms *agent_parms,
+ int *p_span_id)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = qevent_binding->mlxsw_sp_port;
+ struct mlxsw_sp_span_trigger_parms trigger_parms = {};
+ int span_id;
+ int err;
+
+ err = mlxsw_sp_span_agent_get(mlxsw_sp, &span_id, agent_parms);
+ if (err)
+ return err;
+
+ err = mlxsw_sp_span_analyzed_port_get(mlxsw_sp_port, true);
+ if (err)
+ goto err_analyzed_port_get;
+
+ trigger_parms.span_id = span_id;
+ err = mlxsw_sp_span_agent_bind(mlxsw_sp, qevent_binding->span_trigger, mlxsw_sp_port,
+ &trigger_parms);
+ if (err)
+ goto err_agent_bind;
+
+ err = mlxsw_sp_span_trigger_enable(mlxsw_sp_port, qevent_binding->span_trigger,
+ qevent_binding->tclass_num);
+ if (err)
+ goto err_trigger_enable;
+
+ *p_span_id = span_id;
+ return 0;
+
+err_trigger_enable:
+ mlxsw_sp_span_agent_unbind(mlxsw_sp, qevent_binding->span_trigger, mlxsw_sp_port,
+ &trigger_parms);
+err_agent_bind:
+ mlxsw_sp_span_analyzed_port_put(mlxsw_sp_port, true);
+err_analyzed_port_get:
+ mlxsw_sp_span_agent_put(mlxsw_sp, span_id);
+ return err;
+}
+
+static void mlxsw_sp_qevent_span_deconfigure(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_qevent_binding *qevent_binding,
+ int span_id)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port = qevent_binding->mlxsw_sp_port;
+ struct mlxsw_sp_span_trigger_parms trigger_parms = {
+ .span_id = span_id,
+ };
+
+ mlxsw_sp_span_trigger_disable(mlxsw_sp_port, qevent_binding->span_trigger,
+ qevent_binding->tclass_num);
+ mlxsw_sp_span_agent_unbind(mlxsw_sp, qevent_binding->span_trigger, mlxsw_sp_port,
+ &trigger_parms);
+ mlxsw_sp_span_analyzed_port_put(mlxsw_sp_port, true);
+ mlxsw_sp_span_agent_put(mlxsw_sp, span_id);
+}
+
+static int mlxsw_sp_qevent_mirror_configure(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_mall_entry *mall_entry,
+ struct mlxsw_sp_qevent_binding *qevent_binding)
+{
+ struct mlxsw_sp_span_agent_parms agent_parms = {
+ .to_dev = mall_entry->mirror.to_dev,
+ };
+
+ return mlxsw_sp_qevent_span_configure(mlxsw_sp, mall_entry, qevent_binding,
+ &agent_parms, &mall_entry->mirror.span_id);
+}
+
+static void mlxsw_sp_qevent_mirror_deconfigure(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_mall_entry *mall_entry,
+ struct mlxsw_sp_qevent_binding *qevent_binding)
+{
+ mlxsw_sp_qevent_span_deconfigure(mlxsw_sp, qevent_binding, mall_entry->mirror.span_id);
+}
+
+static int mlxsw_sp_qevent_trap_configure(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_mall_entry *mall_entry,
+ struct mlxsw_sp_qevent_binding *qevent_binding)
+{
+ struct mlxsw_sp_span_agent_parms agent_parms = {};
+ int err;
+
+ err = mlxsw_sp_trap_group_policer_hw_id_get(mlxsw_sp,
+ DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS,
+ &agent_parms.policer_enable,
+ &agent_parms.policer_id);
+ if (err)
+ return err;
+
+ return mlxsw_sp_qevent_span_configure(mlxsw_sp, mall_entry, qevent_binding,
+ &agent_parms, &mall_entry->trap.span_id);
+}
+
+static void mlxsw_sp_qevent_trap_deconfigure(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_mall_entry *mall_entry,
+ struct mlxsw_sp_qevent_binding *qevent_binding)
+{
+ mlxsw_sp_qevent_span_deconfigure(mlxsw_sp, qevent_binding, mall_entry->trap.span_id);
+}
+
+static int mlxsw_sp_qevent_entry_configure(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_mall_entry *mall_entry,
+ struct mlxsw_sp_qevent_binding *qevent_binding)
+{
+ switch (mall_entry->type) {
+ case MLXSW_SP_MALL_ACTION_TYPE_MIRROR:
+ return mlxsw_sp_qevent_mirror_configure(mlxsw_sp, mall_entry, qevent_binding);
+ case MLXSW_SP_MALL_ACTION_TYPE_TRAP:
+ return mlxsw_sp_qevent_trap_configure(mlxsw_sp, mall_entry, qevent_binding);
+ default:
+ /* This should have been validated away. */
+ WARN_ON(1);
+ return -EOPNOTSUPP;
+ }
+}
+
+static void mlxsw_sp_qevent_entry_deconfigure(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_mall_entry *mall_entry,
+ struct mlxsw_sp_qevent_binding *qevent_binding)
+{
+ switch (mall_entry->type) {
+ case MLXSW_SP_MALL_ACTION_TYPE_MIRROR:
+ return mlxsw_sp_qevent_mirror_deconfigure(mlxsw_sp, mall_entry, qevent_binding);
+ case MLXSW_SP_MALL_ACTION_TYPE_TRAP:
+ return mlxsw_sp_qevent_trap_deconfigure(mlxsw_sp, mall_entry, qevent_binding);
+ default:
+ WARN_ON(1);
+ return;
+ }
+}
+
+static int mlxsw_sp_qevent_binding_configure(struct mlxsw_sp_qevent_block *qevent_block,
+ struct mlxsw_sp_qevent_binding *qevent_binding)
+{
+ struct mlxsw_sp_mall_entry *mall_entry;
+ int err;
+
+ list_for_each_entry(mall_entry, &qevent_block->mall_entry_list, list) {
+ err = mlxsw_sp_qevent_entry_configure(qevent_block->mlxsw_sp, mall_entry,
+ qevent_binding);
+ if (err)
+ goto err_entry_configure;
+ }
+
+ return 0;
+
+err_entry_configure:
+ list_for_each_entry_continue_reverse(mall_entry, &qevent_block->mall_entry_list, list)
+ mlxsw_sp_qevent_entry_deconfigure(qevent_block->mlxsw_sp, mall_entry,
+ qevent_binding);
+ return err;
+}
+
+static void mlxsw_sp_qevent_binding_deconfigure(struct mlxsw_sp_qevent_block *qevent_block,
+ struct mlxsw_sp_qevent_binding *qevent_binding)
+{
+ struct mlxsw_sp_mall_entry *mall_entry;
+
+ list_for_each_entry(mall_entry, &qevent_block->mall_entry_list, list)
+ mlxsw_sp_qevent_entry_deconfigure(qevent_block->mlxsw_sp, mall_entry,
+ qevent_binding);
+}
+
+static int mlxsw_sp_qevent_block_configure(struct mlxsw_sp_qevent_block *qevent_block)
+{
+ struct mlxsw_sp_qevent_binding *qevent_binding;
+ int err;
+
+ list_for_each_entry(qevent_binding, &qevent_block->binding_list, list) {
+ err = mlxsw_sp_qevent_binding_configure(qevent_block, qevent_binding);
+ if (err)
+ goto err_binding_configure;
+ }
+
+ return 0;
+
+err_binding_configure:
+ list_for_each_entry_continue_reverse(qevent_binding, &qevent_block->binding_list, list)
+ mlxsw_sp_qevent_binding_deconfigure(qevent_block, qevent_binding);
+ return err;
+}
+
+static void mlxsw_sp_qevent_block_deconfigure(struct mlxsw_sp_qevent_block *qevent_block)
+{
+ struct mlxsw_sp_qevent_binding *qevent_binding;
+
+ list_for_each_entry(qevent_binding, &qevent_block->binding_list, list)
+ mlxsw_sp_qevent_binding_deconfigure(qevent_block, qevent_binding);
+}
+
+static struct mlxsw_sp_mall_entry *
+mlxsw_sp_qevent_mall_entry_find(struct mlxsw_sp_qevent_block *block, unsigned long cookie)
+{
+ struct mlxsw_sp_mall_entry *mall_entry;
+
+ list_for_each_entry(mall_entry, &block->mall_entry_list, list)
+ if (mall_entry->cookie == cookie)
+ return mall_entry;
+
+ return NULL;
+}
+
+static int mlxsw_sp_qevent_mall_replace(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_qevent_block *qevent_block,
+ struct tc_cls_matchall_offload *f)
+{
+ struct mlxsw_sp_mall_entry *mall_entry;
+ struct flow_action_entry *act;
+ int err;
+
+ /* It should not currently be possible to replace a matchall rule. So
+ * this must be a new rule.
+ */
+ if (!list_empty(&qevent_block->mall_entry_list)) {
+ NL_SET_ERR_MSG(f->common.extack, "At most one filter supported");
+ return -EOPNOTSUPP;
+ }
+ if (f->rule->action.num_entries != 1) {
+ NL_SET_ERR_MSG(f->common.extack, "Only singular actions supported");
+ return -EOPNOTSUPP;
+ }
+ if (f->common.chain_index) {
+ NL_SET_ERR_MSG(f->common.extack, "Only chain 0 is supported");
+ return -EOPNOTSUPP;
+ }
+ if (f->common.protocol != htons(ETH_P_ALL)) {
+ NL_SET_ERR_MSG(f->common.extack, "Protocol matching not supported");
+ return -EOPNOTSUPP;
+ }
+
+ act = &f->rule->action.entries[0];
+ if (!(act->hw_stats & FLOW_ACTION_HW_STATS_DISABLED)) {
+ NL_SET_ERR_MSG(f->common.extack, "HW counters not supported on qevents");
+ return -EOPNOTSUPP;
+ }
+
+ mall_entry = kzalloc(sizeof(*mall_entry), GFP_KERNEL);
+ if (!mall_entry)
+ return -ENOMEM;
+ mall_entry->cookie = f->cookie;
+
+ if (act->id == FLOW_ACTION_MIRRED) {
+ mall_entry->type = MLXSW_SP_MALL_ACTION_TYPE_MIRROR;
+ mall_entry->mirror.to_dev = act->dev;
+ } else if (act->id == FLOW_ACTION_TRAP) {
+ mall_entry->type = MLXSW_SP_MALL_ACTION_TYPE_TRAP;
+ } else {
+ NL_SET_ERR_MSG(f->common.extack, "Unsupported action");
+ err = -EOPNOTSUPP;
+ goto err_unsupported_action;
+ }
+
+ list_add_tail(&mall_entry->list, &qevent_block->mall_entry_list);
+
+ err = mlxsw_sp_qevent_block_configure(qevent_block);
+ if (err)
+ goto err_block_configure;
+
+ return 0;
+
+err_block_configure:
+ list_del(&mall_entry->list);
+err_unsupported_action:
+ kfree(mall_entry);
+ return err;
+}
+
+static void mlxsw_sp_qevent_mall_destroy(struct mlxsw_sp_qevent_block *qevent_block,
+ struct tc_cls_matchall_offload *f)
+{
+ struct mlxsw_sp_mall_entry *mall_entry;
+
+ mall_entry = mlxsw_sp_qevent_mall_entry_find(qevent_block, f->cookie);
+ if (!mall_entry)
+ return;
+
+ mlxsw_sp_qevent_block_deconfigure(qevent_block);
+
+ list_del(&mall_entry->list);
+ kfree(mall_entry);
+}
+
+static int mlxsw_sp_qevent_block_mall_cb(struct mlxsw_sp_qevent_block *qevent_block,
+ struct tc_cls_matchall_offload *f)
+{
+ struct mlxsw_sp *mlxsw_sp = qevent_block->mlxsw_sp;
+
+ switch (f->command) {
+ case TC_CLSMATCHALL_REPLACE:
+ return mlxsw_sp_qevent_mall_replace(mlxsw_sp, qevent_block, f);
+ case TC_CLSMATCHALL_DESTROY:
+ mlxsw_sp_qevent_mall_destroy(qevent_block, f);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int mlxsw_sp_qevent_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
+{
+ struct mlxsw_sp_qevent_block *qevent_block = cb_priv;
+
+ switch (type) {
+ case TC_SETUP_CLSMATCHALL:
+ return mlxsw_sp_qevent_block_mall_cb(qevent_block, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static struct mlxsw_sp_qevent_block *mlxsw_sp_qevent_block_create(struct mlxsw_sp *mlxsw_sp,
+ struct net *net)
+{
+ struct mlxsw_sp_qevent_block *qevent_block;
+
+ qevent_block = kzalloc(sizeof(*qevent_block), GFP_KERNEL);
+ if (!qevent_block)
+ return NULL;
+
+ INIT_LIST_HEAD(&qevent_block->binding_list);
+ INIT_LIST_HEAD(&qevent_block->mall_entry_list);
+ qevent_block->mlxsw_sp = mlxsw_sp;
+ return qevent_block;
+}
+
+static void
+mlxsw_sp_qevent_block_destroy(struct mlxsw_sp_qevent_block *qevent_block)
+{
+ WARN_ON(!list_empty(&qevent_block->binding_list));
+ WARN_ON(!list_empty(&qevent_block->mall_entry_list));
+ kfree(qevent_block);
+}
+
+static void mlxsw_sp_qevent_block_release(void *cb_priv)
+{
+ struct mlxsw_sp_qevent_block *qevent_block = cb_priv;
+
+ mlxsw_sp_qevent_block_destroy(qevent_block);
+}
+
+static struct mlxsw_sp_qevent_binding *
+mlxsw_sp_qevent_binding_create(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle, int tclass_num,
+ enum mlxsw_sp_span_trigger span_trigger)
+{
+ struct mlxsw_sp_qevent_binding *binding;
+
+ binding = kzalloc(sizeof(*binding), GFP_KERNEL);
+ if (!binding)
+ return ERR_PTR(-ENOMEM);
+
+ binding->mlxsw_sp_port = mlxsw_sp_port;
+ binding->handle = handle;
+ binding->tclass_num = tclass_num;
+ binding->span_trigger = span_trigger;
+ return binding;
+}
+
+static void
+mlxsw_sp_qevent_binding_destroy(struct mlxsw_sp_qevent_binding *binding)
+{
+ kfree(binding);
+}
+
+static struct mlxsw_sp_qevent_binding *
+mlxsw_sp_qevent_binding_lookup(struct mlxsw_sp_qevent_block *block,
+ struct mlxsw_sp_port *mlxsw_sp_port,
+ u32 handle,
+ enum mlxsw_sp_span_trigger span_trigger)
+{
+ struct mlxsw_sp_qevent_binding *qevent_binding;
+
+ list_for_each_entry(qevent_binding, &block->binding_list, list)
+ if (qevent_binding->mlxsw_sp_port == mlxsw_sp_port &&
+ qevent_binding->handle == handle &&
+ qevent_binding->span_trigger == span_trigger)
+ return qevent_binding;
+ return NULL;
+}
+
+static int mlxsw_sp_setup_tc_block_qevent_bind(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct flow_block_offload *f,
+ enum mlxsw_sp_span_trigger span_trigger)
+{
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ struct mlxsw_sp_qevent_binding *qevent_binding;
+ struct mlxsw_sp_qevent_block *qevent_block;
+ struct flow_block_cb *block_cb;
+ struct mlxsw_sp_qdisc *qdisc;
+ bool register_block = false;
+ int err;
+
+ block_cb = flow_block_cb_lookup(f->block, mlxsw_sp_qevent_block_cb, mlxsw_sp);
+ if (!block_cb) {
+ qevent_block = mlxsw_sp_qevent_block_create(mlxsw_sp, f->net);
+ if (!qevent_block)
+ return -ENOMEM;
+ block_cb = flow_block_cb_alloc(mlxsw_sp_qevent_block_cb, mlxsw_sp, qevent_block,
+ mlxsw_sp_qevent_block_release);
+ if (IS_ERR(block_cb)) {
+ mlxsw_sp_qevent_block_destroy(qevent_block);
+ return PTR_ERR(block_cb);
+ }
+ register_block = true;
+ } else {
+ qevent_block = flow_block_cb_priv(block_cb);
+ }
+ flow_block_cb_incref(block_cb);
+
+ qdisc = mlxsw_sp_qdisc_find_by_handle(mlxsw_sp_port, f->sch->handle);
+ if (!qdisc) {
+ NL_SET_ERR_MSG(f->extack, "Qdisc not offloaded");
+ err = -ENOENT;
+ goto err_find_qdisc;
+ }
+
+ if (WARN_ON(mlxsw_sp_qevent_binding_lookup(qevent_block, mlxsw_sp_port, f->sch->handle,
+ span_trigger))) {
+ err = -EEXIST;
+ goto err_binding_exists;
+ }
+
+ qevent_binding = mlxsw_sp_qevent_binding_create(mlxsw_sp_port, f->sch->handle,
+ qdisc->tclass_num, span_trigger);
+ if (IS_ERR(qevent_binding)) {
+ err = PTR_ERR(qevent_binding);
+ goto err_binding_create;
+ }
+
+ err = mlxsw_sp_qevent_binding_configure(qevent_block, qevent_binding);
+ if (err)
+ goto err_binding_configure;
+
+ list_add(&qevent_binding->list, &qevent_block->binding_list);
+
+ if (register_block) {
+ flow_block_cb_add(block_cb, f);
+ list_add_tail(&block_cb->driver_list, &mlxsw_sp_qevent_block_cb_list);
+ }
+
+ return 0;
+
+err_binding_configure:
+ mlxsw_sp_qevent_binding_destroy(qevent_binding);
+err_binding_create:
+err_binding_exists:
+err_find_qdisc:
+ if (!flow_block_cb_decref(block_cb))
+ flow_block_cb_free(block_cb);
+ return err;
+}
+
+static void mlxsw_sp_setup_tc_block_qevent_unbind(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct flow_block_offload *f,
+ enum mlxsw_sp_span_trigger span_trigger)
+{
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ struct mlxsw_sp_qevent_binding *qevent_binding;
+ struct mlxsw_sp_qevent_block *qevent_block;
+ struct flow_block_cb *block_cb;
+
+ block_cb = flow_block_cb_lookup(f->block, mlxsw_sp_qevent_block_cb, mlxsw_sp);
+ if (!block_cb)
+ return;
+ qevent_block = flow_block_cb_priv(block_cb);
+
+ qevent_binding = mlxsw_sp_qevent_binding_lookup(qevent_block, mlxsw_sp_port, f->sch->handle,
+ span_trigger);
+ if (!qevent_binding)
+ return;
+
+ list_del(&qevent_binding->list);
+ mlxsw_sp_qevent_binding_deconfigure(qevent_block, qevent_binding);
+ mlxsw_sp_qevent_binding_destroy(qevent_binding);
+
+ if (!flow_block_cb_decref(block_cb)) {
+ flow_block_cb_remove(block_cb, f);
+ list_del(&block_cb->driver_list);
+ }
+}
+
+static int mlxsw_sp_setup_tc_block_qevent(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct flow_block_offload *f,
+ enum mlxsw_sp_span_trigger span_trigger)
+{
+ f->driver_block_list = &mlxsw_sp_qevent_block_cb_list;
+
+ switch (f->command) {
+ case FLOW_BLOCK_BIND:
+ return mlxsw_sp_setup_tc_block_qevent_bind(mlxsw_sp_port, f, span_trigger);
+ case FLOW_BLOCK_UNBIND:
+ mlxsw_sp_setup_tc_block_qevent_unbind(mlxsw_sp_port, f, span_trigger);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+int mlxsw_sp_setup_tc_block_qevent_early_drop(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct flow_block_offload *f)
+{
+ return mlxsw_sp_setup_tc_block_qevent(mlxsw_sp_port, f, MLXSW_SP_SPAN_TRIGGER_EARLY_DROP);
+}
+
int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port)
{
struct mlxsw_sp_qdisc_state *qdisc_state;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index 92351a79addc..5c959a995199 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -21,9 +21,14 @@
struct mlxsw_sp_span {
struct work_struct work;
struct mlxsw_sp *mlxsw_sp;
+ const struct mlxsw_sp_span_trigger_ops **span_trigger_ops_arr;
+ const struct mlxsw_sp_span_entry_ops **span_entry_ops_arr;
+ size_t span_entry_ops_arr_size;
struct list_head analyzed_ports_list;
struct mutex analyzed_ports_lock; /* Protects analyzed_ports_list */
struct list_head trigger_entries_list;
+ u16 policer_id_base;
+ refcount_t policer_id_base_ref_count;
atomic_t active_entries_count;
int entries_count;
struct mlxsw_sp_span_entry entries[];
@@ -38,12 +43,31 @@ struct mlxsw_sp_span_analyzed_port {
struct mlxsw_sp_span_trigger_entry {
struct list_head list; /* Member of trigger_entries_list */
+ struct mlxsw_sp_span *span;
+ const struct mlxsw_sp_span_trigger_ops *ops;
refcount_t ref_count;
u8 local_port;
enum mlxsw_sp_span_trigger trigger;
struct mlxsw_sp_span_trigger_parms parms;
};
+enum mlxsw_sp_span_trigger_type {
+ MLXSW_SP_SPAN_TRIGGER_TYPE_PORT,
+ MLXSW_SP_SPAN_TRIGGER_TYPE_GLOBAL,
+};
+
+struct mlxsw_sp_span_trigger_ops {
+ int (*bind)(struct mlxsw_sp_span_trigger_entry *trigger_entry);
+ void (*unbind)(struct mlxsw_sp_span_trigger_entry *trigger_entry);
+ bool (*matches)(struct mlxsw_sp_span_trigger_entry *trigger_entry,
+ enum mlxsw_sp_span_trigger trigger,
+ struct mlxsw_sp_port *mlxsw_sp_port);
+ int (*enable)(struct mlxsw_sp_span_trigger_entry *trigger_entry,
+ struct mlxsw_sp_port *mlxsw_sp_port, u8 tc);
+ void (*disable)(struct mlxsw_sp_span_trigger_entry *trigger_entry,
+ struct mlxsw_sp_port *mlxsw_sp_port, u8 tc);
+};
+
static void mlxsw_sp_span_respin_work(struct work_struct *work);
static u64 mlxsw_sp_span_occ_get(void *priv)
@@ -57,7 +81,7 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
{
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
struct mlxsw_sp_span *span;
- int i, entries_count;
+ int i, entries_count, err;
if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_SPAN))
return -EIO;
@@ -66,6 +90,7 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
span = kzalloc(struct_size(span, entries, entries_count), GFP_KERNEL);
if (!span)
return -ENOMEM;
+ refcount_set(&span->policer_id_base_ref_count, 0);
span->entries_count = entries_count;
atomic_set(&span->active_entries_count, 0);
mutex_init(&span->analyzed_ports_lock);
@@ -77,11 +102,20 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
for (i = 0; i < mlxsw_sp->span->entries_count; i++)
mlxsw_sp->span->entries[i].id = i;
+ err = mlxsw_sp->span_ops->init(mlxsw_sp);
+ if (err)
+ goto err_init;
+
devlink_resource_occ_get_register(devlink, MLXSW_SP_RESOURCE_SPAN,
mlxsw_sp_span_occ_get, mlxsw_sp);
INIT_WORK(&span->work, mlxsw_sp_span_respin_work);
return 0;
+
+err_init:
+ mutex_destroy(&mlxsw_sp->span->analyzed_ports_lock);
+ kfree(mlxsw_sp->span);
+ return err;
}
void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
@@ -97,8 +131,41 @@ void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
kfree(mlxsw_sp->span);
}
+static bool mlxsw_sp1_span_cpu_can_handle(const struct net_device *dev)
+{
+ return !dev;
+}
+
+static int mlxsw_sp1_span_entry_cpu_parms(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *to_dev,
+ struct mlxsw_sp_span_parms *sparmsp)
+{
+ return -EOPNOTSUPP;
+}
+
+static int
+mlxsw_sp1_span_entry_cpu_configure(struct mlxsw_sp_span_entry *span_entry,
+ struct mlxsw_sp_span_parms sparms)
+{
+ return -EOPNOTSUPP;
+}
+
+static void
+mlxsw_sp1_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry)
+{
+}
+
+static const
+struct mlxsw_sp_span_entry_ops mlxsw_sp1_span_entry_ops_cpu = {
+ .can_handle = mlxsw_sp1_span_cpu_can_handle,
+ .parms_set = mlxsw_sp1_span_entry_cpu_parms,
+ .configure = mlxsw_sp1_span_entry_cpu_configure,
+ .deconfigure = mlxsw_sp1_span_entry_cpu_deconfigure,
+};
+
static int
-mlxsw_sp_span_entry_phys_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_phys_parms(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{
sparmsp->dest_port = netdev_priv(to_dev);
@@ -118,6 +185,8 @@ mlxsw_sp_span_entry_phys_configure(struct mlxsw_sp_span_entry *span_entry,
/* Create a new port analayzer entry for local_port. */
mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH);
+ mlxsw_reg_mpat_pide_set(mpat_pl, sparms.policer_enable);
+ mlxsw_reg_mpat_pid_set(mpat_pl, sparms.policer_id);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
}
@@ -374,7 +443,8 @@ out:
}
static int
-mlxsw_sp_span_entry_gretap4_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_gretap4_parms(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{
struct ip_tunnel_parm tparm = mlxsw_sp_ipip_netdev_parms4(to_dev);
@@ -413,6 +483,8 @@ mlxsw_sp_span_entry_gretap4_configure(struct mlxsw_sp_span_entry *span_entry,
/* Create a new port analayzer entry for local_port. */
mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
+ mlxsw_reg_mpat_pide_set(mpat_pl, sparms.policer_enable);
+ mlxsw_reg_mpat_pid_set(mpat_pl, sparms.policer_id);
mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid);
mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl,
MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER,
@@ -475,7 +547,8 @@ out:
}
static int
-mlxsw_sp_span_entry_gretap6_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_gretap6_parms(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{
struct __ip6_tnl_parm tparm = mlxsw_sp_ipip_netdev_parms6(to_dev);
@@ -514,6 +587,8 @@ mlxsw_sp_span_entry_gretap6_configure(struct mlxsw_sp_span_entry *span_entry,
/* Create a new port analayzer entry for local_port. */
mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
+ mlxsw_reg_mpat_pide_set(mpat_pl, sparms.policer_enable);
+ mlxsw_reg_mpat_pid_set(mpat_pl, sparms.policer_id);
mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid);
mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl,
MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER,
@@ -549,7 +624,8 @@ mlxsw_sp_span_vlan_can_handle(const struct net_device *dev)
}
static int
-mlxsw_sp_span_entry_vlan_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_vlan_parms(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{
struct net_device *real_dev;
@@ -576,6 +652,8 @@ mlxsw_sp_span_entry_vlan_configure(struct mlxsw_sp_span_entry *span_entry,
mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH);
+ mlxsw_reg_mpat_pide_set(mpat_pl, sparms.policer_enable);
+ mlxsw_reg_mpat_pid_set(mpat_pl, sparms.policer_id);
mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
@@ -597,7 +675,61 @@ struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_vlan = {
};
static const
-struct mlxsw_sp_span_entry_ops *const mlxsw_sp_span_entry_types[] = {
+struct mlxsw_sp_span_entry_ops *mlxsw_sp1_span_entry_ops_arr[] = {
+ &mlxsw_sp1_span_entry_ops_cpu,
+ &mlxsw_sp_span_entry_ops_phys,
+#if IS_ENABLED(CONFIG_NET_IPGRE)
+ &mlxsw_sp_span_entry_ops_gretap4,
+#endif
+#if IS_ENABLED(CONFIG_IPV6_GRE)
+ &mlxsw_sp_span_entry_ops_gretap6,
+#endif
+ &mlxsw_sp_span_entry_ops_vlan,
+};
+
+static bool mlxsw_sp2_span_cpu_can_handle(const struct net_device *dev)
+{
+ return !dev;
+}
+
+static int mlxsw_sp2_span_entry_cpu_parms(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *to_dev,
+ struct mlxsw_sp_span_parms *sparmsp)
+{
+ sparmsp->dest_port = mlxsw_sp->ports[MLXSW_PORT_CPU_PORT];
+ return 0;
+}
+
+static int
+mlxsw_sp2_span_entry_cpu_configure(struct mlxsw_sp_span_entry *span_entry,
+ struct mlxsw_sp_span_parms sparms)
+{
+ /* Mirroring to the CPU port is like mirroring to any other physical
+ * port. Its local port is used instead of that of the physical port.
+ */
+ return mlxsw_sp_span_entry_phys_configure(span_entry, sparms);
+}
+
+static void
+mlxsw_sp2_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry)
+{
+ enum mlxsw_reg_mpat_span_type span_type;
+
+ span_type = MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH;
+ mlxsw_sp_span_entry_deconfigure_common(span_entry, span_type);
+}
+
+static const
+struct mlxsw_sp_span_entry_ops mlxsw_sp2_span_entry_ops_cpu = {
+ .can_handle = mlxsw_sp2_span_cpu_can_handle,
+ .parms_set = mlxsw_sp2_span_entry_cpu_parms,
+ .configure = mlxsw_sp2_span_entry_cpu_configure,
+ .deconfigure = mlxsw_sp2_span_entry_cpu_deconfigure,
+};
+
+static const
+struct mlxsw_sp_span_entry_ops *mlxsw_sp2_span_entry_ops_arr[] = {
+ &mlxsw_sp2_span_entry_ops_cpu,
&mlxsw_sp_span_entry_ops_phys,
#if IS_ENABLED(CONFIG_NET_IPGRE)
&mlxsw_sp_span_entry_ops_gretap4,
@@ -609,7 +741,8 @@ struct mlxsw_sp_span_entry_ops *const mlxsw_sp_span_entry_types[] = {
};
static int
-mlxsw_sp_span_entry_nop_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_nop_parms(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp)
{
return mlxsw_sp_span_entry_unoffloadable(sparmsp);
@@ -644,16 +777,15 @@ mlxsw_sp_span_entry_configure(struct mlxsw_sp *mlxsw_sp,
goto set_parms;
if (sparms.dest_port->mlxsw_sp != mlxsw_sp) {
- netdev_err(span_entry->to_dev, "Cannot mirror to %s, which belongs to a different mlxsw instance",
- sparms.dest_port->dev->name);
+ dev_err(mlxsw_sp->bus_info->dev,
+ "Cannot mirror to a port which belongs to a different mlxsw instance\n");
sparms.dest_port = NULL;
goto set_parms;
}
err = span_entry->ops->configure(span_entry, sparms);
if (err) {
- netdev_err(span_entry->to_dev, "Failed to offload mirror to %s",
- sparms.dest_port->dev->name);
+ dev_err(mlxsw_sp->bus_info->dev, "Failed to offload mirror\n");
sparms.dest_port = NULL;
goto set_parms;
}
@@ -669,6 +801,46 @@ mlxsw_sp_span_entry_deconfigure(struct mlxsw_sp_span_entry *span_entry)
span_entry->ops->deconfigure(span_entry);
}
+static int mlxsw_sp_span_policer_id_base_set(struct mlxsw_sp_span *span,
+ u16 policer_id)
+{
+ struct mlxsw_sp *mlxsw_sp = span->mlxsw_sp;
+ u16 policer_id_base;
+ int err;
+
+ /* Policers set on SPAN agents must be in the range of
+ * `policer_id_base .. policer_id_base + max_span_agents - 1`. If the
+ * base is set and the new policer is not within the range, then we
+ * must error out.
+ */
+ if (refcount_read(&span->policer_id_base_ref_count)) {
+ if (policer_id < span->policer_id_base ||
+ policer_id >= span->policer_id_base + span->entries_count)
+ return -EINVAL;
+
+ refcount_inc(&span->policer_id_base_ref_count);
+ return 0;
+ }
+
+ /* Base must be even. */
+ policer_id_base = policer_id % 2 == 0 ? policer_id : policer_id - 1;
+ err = mlxsw_sp->span_ops->policer_id_base_set(mlxsw_sp,
+ policer_id_base);
+ if (err)
+ return err;
+
+ span->policer_id_base = policer_id_base;
+ refcount_set(&span->policer_id_base_ref_count, 1);
+
+ return 0;
+}
+
+static void mlxsw_sp_span_policer_id_base_unset(struct mlxsw_sp_span *span)
+{
+ if (refcount_dec_and_test(&span->policer_id_base_ref_count))
+ span->policer_id_base = 0;
+}
+
static struct mlxsw_sp_span_entry *
mlxsw_sp_span_entry_create(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
@@ -688,6 +860,15 @@ mlxsw_sp_span_entry_create(struct mlxsw_sp *mlxsw_sp,
if (!span_entry)
return NULL;
+ if (sparms.policer_enable) {
+ int err;
+
+ err = mlxsw_sp_span_policer_id_base_set(mlxsw_sp->span,
+ sparms.policer_id);
+ if (err)
+ return NULL;
+ }
+
atomic_inc(&mlxsw_sp->span->active_entries_count);
span_entry->ops = ops;
refcount_set(&span_entry->ref_count, 1);
@@ -702,6 +883,8 @@ static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp,
{
mlxsw_sp_span_entry_deconfigure(span_entry);
atomic_dec(&mlxsw_sp->span->active_entries_count);
+ if (span_entry->parms.policer_enable)
+ mlxsw_sp_span_policer_id_base_unset(mlxsw_sp->span);
}
struct mlxsw_sp_span_entry *
@@ -741,6 +924,24 @@ mlxsw_sp_span_entry_find_by_id(struct mlxsw_sp *mlxsw_sp, int span_id)
}
static struct mlxsw_sp_span_entry *
+mlxsw_sp_span_entry_find_by_parms(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *to_dev,
+ const struct mlxsw_sp_span_parms *sparms)
+{
+ int i;
+
+ for (i = 0; i < mlxsw_sp->span->entries_count; i++) {
+ struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span->entries[i];
+
+ if (refcount_read(&curr->ref_count) && curr->to_dev == to_dev &&
+ curr->parms.policer_enable == sparms->policer_enable &&
+ curr->parms.policer_id == sparms->policer_id)
+ return curr;
+ }
+ return NULL;
+}
+
+static struct mlxsw_sp_span_entry *
mlxsw_sp_span_entry_get(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev,
const struct mlxsw_sp_span_entry_ops *ops,
@@ -748,7 +949,8 @@ mlxsw_sp_span_entry_get(struct mlxsw_sp *mlxsw_sp,
{
struct mlxsw_sp_span_entry *span_entry;
- span_entry = mlxsw_sp_span_entry_find_by_port(mlxsw_sp, to_dev);
+ span_entry = mlxsw_sp_span_entry_find_by_parms(mlxsw_sp, to_dev,
+ &sparms);
if (span_entry) {
/* Already exists, just take a reference */
refcount_inc(&span_entry->ref_count);
@@ -766,6 +968,14 @@ static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
return 0;
}
+static u32 mlxsw_sp_span_buffsize_get(struct mlxsw_sp *mlxsw_sp, int mtu,
+ u32 speed)
+{
+ u32 buffsize = mlxsw_sp->span_ops->buffsize_get(speed, mtu);
+
+ return mlxsw_sp_bytes_cells(mlxsw_sp, buffsize) + 1;
+}
+
static int
mlxsw_sp_span_port_buffer_update(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
{
@@ -857,11 +1067,12 @@ static const struct mlxsw_sp_span_entry_ops *
mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev)
{
+ struct mlxsw_sp_span *span = mlxsw_sp->span;
size_t i;
- for (i = 0; i < ARRAY_SIZE(mlxsw_sp_span_entry_types); ++i)
- if (mlxsw_sp_span_entry_types[i]->can_handle(to_dev))
- return mlxsw_sp_span_entry_types[i];
+ for (i = 0; i < span->span_entry_ops_arr_size; ++i)
+ if (span->span_entry_ops_arr[i]->can_handle(to_dev))
+ return span->span_entry_ops_arr[i];
return NULL;
}
@@ -883,7 +1094,7 @@ static void mlxsw_sp_span_respin_work(struct work_struct *work)
if (!refcount_read(&curr->ref_count))
continue;
- err = curr->ops->parms_set(curr->to_dev, &sparms);
+ err = curr->ops->parms_set(mlxsw_sp, curr->to_dev, &sparms);
if (err)
continue;
@@ -902,9 +1113,10 @@ void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp)
mlxsw_core_schedule_work(&mlxsw_sp->span->work);
}
-int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp,
- const struct net_device *to_dev, int *p_span_id)
+int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp, int *p_span_id,
+ const struct mlxsw_sp_span_agent_parms *parms)
{
+ const struct net_device *to_dev = parms->to_dev;
const struct mlxsw_sp_span_entry_ops *ops;
struct mlxsw_sp_span_entry *span_entry;
struct mlxsw_sp_span_parms sparms;
@@ -919,10 +1131,12 @@ int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp,
}
memset(&sparms, 0, sizeof(sparms));
- err = ops->parms_set(to_dev, &sparms);
+ err = ops->parms_set(mlxsw_sp, to_dev, &sparms);
if (err)
return err;
+ sparms.policer_id = parms->policer_id;
+ sparms.policer_enable = parms->policer_enable;
span_entry = mlxsw_sp_span_entry_get(mlxsw_sp, to_dev, ops, sparms);
if (!span_entry)
return -ENOBUFS;
@@ -1051,9 +1265,9 @@ out_unlock:
}
static int
-__mlxsw_sp_span_trigger_entry_bind(struct mlxsw_sp_span *span,
- struct mlxsw_sp_span_trigger_entry *
- trigger_entry, bool enable)
+__mlxsw_sp_span_trigger_port_bind(struct mlxsw_sp_span *span,
+ struct mlxsw_sp_span_trigger_entry *
+ trigger_entry, bool enable)
{
char mpar_pl[MLXSW_REG_MPAR_LEN];
enum mlxsw_reg_mpar_i_e i_e;
@@ -1076,19 +1290,254 @@ __mlxsw_sp_span_trigger_entry_bind(struct mlxsw_sp_span *span,
}
static int
-mlxsw_sp_span_trigger_entry_bind(struct mlxsw_sp_span *span,
- struct mlxsw_sp_span_trigger_entry *
- trigger_entry)
+mlxsw_sp_span_trigger_port_bind(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry)
+{
+ return __mlxsw_sp_span_trigger_port_bind(trigger_entry->span,
+ trigger_entry, true);
+}
+
+static void
+mlxsw_sp_span_trigger_port_unbind(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry)
+{
+ __mlxsw_sp_span_trigger_port_bind(trigger_entry->span, trigger_entry,
+ false);
+}
+
+static bool
+mlxsw_sp_span_trigger_port_matches(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ enum mlxsw_sp_span_trigger trigger,
+ struct mlxsw_sp_port *mlxsw_sp_port)
+{
+ return trigger_entry->trigger == trigger &&
+ trigger_entry->local_port == mlxsw_sp_port->local_port;
+}
+
+static int
+mlxsw_sp_span_trigger_port_enable(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ struct mlxsw_sp_port *mlxsw_sp_port, u8 tc)
{
- return __mlxsw_sp_span_trigger_entry_bind(span, trigger_entry, true);
+ /* Port trigger are enabled during binding. */
+ return 0;
}
static void
-mlxsw_sp_span_trigger_entry_unbind(struct mlxsw_sp_span *span,
- struct mlxsw_sp_span_trigger_entry *
+mlxsw_sp_span_trigger_port_disable(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ struct mlxsw_sp_port *mlxsw_sp_port, u8 tc)
+{
+}
+
+static const struct mlxsw_sp_span_trigger_ops
+mlxsw_sp_span_trigger_port_ops = {
+ .bind = mlxsw_sp_span_trigger_port_bind,
+ .unbind = mlxsw_sp_span_trigger_port_unbind,
+ .matches = mlxsw_sp_span_trigger_port_matches,
+ .enable = mlxsw_sp_span_trigger_port_enable,
+ .disable = mlxsw_sp_span_trigger_port_disable,
+};
+
+static int
+mlxsw_sp1_span_trigger_global_bind(struct mlxsw_sp_span_trigger_entry *
trigger_entry)
{
- __mlxsw_sp_span_trigger_entry_bind(span, trigger_entry, false);
+ return -EOPNOTSUPP;
+}
+
+static void
+mlxsw_sp1_span_trigger_global_unbind(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry)
+{
+}
+
+static bool
+mlxsw_sp1_span_trigger_global_matches(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ enum mlxsw_sp_span_trigger trigger,
+ struct mlxsw_sp_port *mlxsw_sp_port)
+{
+ WARN_ON_ONCE(1);
+ return false;
+}
+
+static int
+mlxsw_sp1_span_trigger_global_enable(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ struct mlxsw_sp_port *mlxsw_sp_port,
+ u8 tc)
+{
+ return -EOPNOTSUPP;
+}
+
+static void
+mlxsw_sp1_span_trigger_global_disable(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ struct mlxsw_sp_port *mlxsw_sp_port,
+ u8 tc)
+{
+}
+
+static const struct mlxsw_sp_span_trigger_ops
+mlxsw_sp1_span_trigger_global_ops = {
+ .bind = mlxsw_sp1_span_trigger_global_bind,
+ .unbind = mlxsw_sp1_span_trigger_global_unbind,
+ .matches = mlxsw_sp1_span_trigger_global_matches,
+ .enable = mlxsw_sp1_span_trigger_global_enable,
+ .disable = mlxsw_sp1_span_trigger_global_disable,
+};
+
+static const struct mlxsw_sp_span_trigger_ops *
+mlxsw_sp1_span_trigger_ops_arr[] = {
+ [MLXSW_SP_SPAN_TRIGGER_TYPE_PORT] = &mlxsw_sp_span_trigger_port_ops,
+ [MLXSW_SP_SPAN_TRIGGER_TYPE_GLOBAL] =
+ &mlxsw_sp1_span_trigger_global_ops,
+};
+
+static int
+mlxsw_sp2_span_trigger_global_bind(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry)
+{
+ struct mlxsw_sp *mlxsw_sp = trigger_entry->span->mlxsw_sp;
+ enum mlxsw_reg_mpagr_trigger trigger;
+ char mpagr_pl[MLXSW_REG_MPAGR_LEN];
+
+ switch (trigger_entry->trigger) {
+ case MLXSW_SP_SPAN_TRIGGER_TAIL_DROP:
+ trigger = MLXSW_REG_MPAGR_TRIGGER_INGRESS_SHARED_BUFFER;
+ break;
+ case MLXSW_SP_SPAN_TRIGGER_EARLY_DROP:
+ trigger = MLXSW_REG_MPAGR_TRIGGER_INGRESS_WRED;
+ break;
+ case MLXSW_SP_SPAN_TRIGGER_ECN:
+ trigger = MLXSW_REG_MPAGR_TRIGGER_EGRESS_ECN;
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
+ mlxsw_reg_mpagr_pack(mpagr_pl, trigger, trigger_entry->parms.span_id,
+ 1);
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpagr), mpagr_pl);
+}
+
+static void
+mlxsw_sp2_span_trigger_global_unbind(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry)
+{
+ /* There is no unbinding for global triggers. The trigger should be
+ * disabled on all ports by now.
+ */
+}
+
+static bool
+mlxsw_sp2_span_trigger_global_matches(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ enum mlxsw_sp_span_trigger trigger,
+ struct mlxsw_sp_port *mlxsw_sp_port)
+{
+ return trigger_entry->trigger == trigger;
+}
+
+static int
+__mlxsw_sp2_span_trigger_global_enable(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ struct mlxsw_sp_port *mlxsw_sp_port,
+ u8 tc, bool enable)
+{
+ struct mlxsw_sp *mlxsw_sp = trigger_entry->span->mlxsw_sp;
+ char momte_pl[MLXSW_REG_MOMTE_LEN];
+ enum mlxsw_reg_momte_type type;
+ int err;
+
+ switch (trigger_entry->trigger) {
+ case MLXSW_SP_SPAN_TRIGGER_TAIL_DROP:
+ type = MLXSW_REG_MOMTE_TYPE_SHARED_BUFFER_TCLASS;
+ break;
+ case MLXSW_SP_SPAN_TRIGGER_EARLY_DROP:
+ type = MLXSW_REG_MOMTE_TYPE_WRED;
+ break;
+ case MLXSW_SP_SPAN_TRIGGER_ECN:
+ type = MLXSW_REG_MOMTE_TYPE_ECN;
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
+ /* Query existing configuration in order to only change the state of
+ * the specified traffic class.
+ */
+ mlxsw_reg_momte_pack(momte_pl, mlxsw_sp_port->local_port, type);
+ err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(momte), momte_pl);
+ if (err)
+ return err;
+
+ mlxsw_reg_momte_tclass_en_set(momte_pl, tc, enable);
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(momte), momte_pl);
+}
+
+static int
+mlxsw_sp2_span_trigger_global_enable(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ struct mlxsw_sp_port *mlxsw_sp_port,
+ u8 tc)
+{
+ return __mlxsw_sp2_span_trigger_global_enable(trigger_entry,
+ mlxsw_sp_port, tc, true);
+}
+
+static void
+mlxsw_sp2_span_trigger_global_disable(struct mlxsw_sp_span_trigger_entry *
+ trigger_entry,
+ struct mlxsw_sp_port *mlxsw_sp_port,
+ u8 tc)
+{
+ __mlxsw_sp2_span_trigger_global_enable(trigger_entry, mlxsw_sp_port, tc,
+ false);
+}
+
+static const struct mlxsw_sp_span_trigger_ops
+mlxsw_sp2_span_trigger_global_ops = {
+ .bind = mlxsw_sp2_span_trigger_global_bind,
+ .unbind = mlxsw_sp2_span_trigger_global_unbind,
+ .matches = mlxsw_sp2_span_trigger_global_matches,
+ .enable = mlxsw_sp2_span_trigger_global_enable,
+ .disable = mlxsw_sp2_span_trigger_global_disable,
+};
+
+static const struct mlxsw_sp_span_trigger_ops *
+mlxsw_sp2_span_trigger_ops_arr[] = {
+ [MLXSW_SP_SPAN_TRIGGER_TYPE_PORT] = &mlxsw_sp_span_trigger_port_ops,
+ [MLXSW_SP_SPAN_TRIGGER_TYPE_GLOBAL] =
+ &mlxsw_sp2_span_trigger_global_ops,
+};
+
+static void
+mlxsw_sp_span_trigger_ops_set(struct mlxsw_sp_span_trigger_entry *trigger_entry)
+{
+ struct mlxsw_sp_span *span = trigger_entry->span;
+ enum mlxsw_sp_span_trigger_type type;
+
+ switch (trigger_entry->trigger) {
+ case MLXSW_SP_SPAN_TRIGGER_INGRESS: /* fall-through */
+ case MLXSW_SP_SPAN_TRIGGER_EGRESS:
+ type = MLXSW_SP_SPAN_TRIGGER_TYPE_PORT;
+ break;
+ case MLXSW_SP_SPAN_TRIGGER_TAIL_DROP: /* fall-through */
+ case MLXSW_SP_SPAN_TRIGGER_EARLY_DROP: /* fall-through */
+ case MLXSW_SP_SPAN_TRIGGER_ECN:
+ type = MLXSW_SP_SPAN_TRIGGER_TYPE_GLOBAL;
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ return;
+ }
+
+ trigger_entry->ops = span->span_trigger_ops_arr[type];
}
static struct mlxsw_sp_span_trigger_entry *
@@ -1106,12 +1555,15 @@ mlxsw_sp_span_trigger_entry_create(struct mlxsw_sp_span *span,
return ERR_PTR(-ENOMEM);
refcount_set(&trigger_entry->ref_count, 1);
- trigger_entry->local_port = mlxsw_sp_port->local_port;
+ trigger_entry->local_port = mlxsw_sp_port ? mlxsw_sp_port->local_port :
+ 0;
trigger_entry->trigger = trigger;
memcpy(&trigger_entry->parms, parms, sizeof(trigger_entry->parms));
+ trigger_entry->span = span;
+ mlxsw_sp_span_trigger_ops_set(trigger_entry);
list_add_tail(&trigger_entry->list, &span->trigger_entries_list);
- err = mlxsw_sp_span_trigger_entry_bind(span, trigger_entry);
+ err = trigger_entry->ops->bind(trigger_entry);
if (err)
goto err_trigger_entry_bind;
@@ -1128,7 +1580,7 @@ mlxsw_sp_span_trigger_entry_destroy(struct mlxsw_sp_span *span,
struct mlxsw_sp_span_trigger_entry *
trigger_entry)
{
- mlxsw_sp_span_trigger_entry_unbind(span, trigger_entry);
+ trigger_entry->ops->unbind(trigger_entry);
list_del(&trigger_entry->list);
kfree(trigger_entry);
}
@@ -1141,8 +1593,8 @@ mlxsw_sp_span_trigger_entry_find(struct mlxsw_sp_span *span,
struct mlxsw_sp_span_trigger_entry *trigger_entry;
list_for_each_entry(trigger_entry, &span->trigger_entries_list, list) {
- if (trigger_entry->trigger == trigger &&
- trigger_entry->local_port == mlxsw_sp_port->local_port)
+ if (trigger_entry->ops->matches(trigger_entry, trigger,
+ mlxsw_sp_port))
return trigger_entry;
}
@@ -1207,3 +1659,138 @@ void mlxsw_sp_span_agent_unbind(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_span_trigger_entry_destroy(mlxsw_sp->span, trigger_entry);
}
+
+int mlxsw_sp_span_trigger_enable(struct mlxsw_sp_port *mlxsw_sp_port,
+ enum mlxsw_sp_span_trigger trigger, u8 tc)
+{
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ struct mlxsw_sp_span_trigger_entry *trigger_entry;
+
+ ASSERT_RTNL();
+
+ trigger_entry = mlxsw_sp_span_trigger_entry_find(mlxsw_sp->span,
+ trigger,
+ mlxsw_sp_port);
+ if (WARN_ON_ONCE(!trigger_entry))
+ return -EINVAL;
+
+ return trigger_entry->ops->enable(trigger_entry, mlxsw_sp_port, tc);
+}
+
+void mlxsw_sp_span_trigger_disable(struct mlxsw_sp_port *mlxsw_sp_port,
+ enum mlxsw_sp_span_trigger trigger, u8 tc)
+{
+ struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+ struct mlxsw_sp_span_trigger_entry *trigger_entry;
+
+ ASSERT_RTNL();
+
+ trigger_entry = mlxsw_sp_span_trigger_entry_find(mlxsw_sp->span,
+ trigger,
+ mlxsw_sp_port);
+ if (WARN_ON_ONCE(!trigger_entry))
+ return;
+
+ return trigger_entry->ops->disable(trigger_entry, mlxsw_sp_port, tc);
+}
+
+static int mlxsw_sp1_span_init(struct mlxsw_sp *mlxsw_sp)
+{
+ size_t arr_size = ARRAY_SIZE(mlxsw_sp1_span_entry_ops_arr);
+
+ /* Must be first to avoid NULL pointer dereference by subsequent
+ * can_handle() callbacks.
+ */
+ if (WARN_ON(mlxsw_sp1_span_entry_ops_arr[0] !=
+ &mlxsw_sp1_span_entry_ops_cpu))
+ return -EINVAL;
+
+ mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp1_span_trigger_ops_arr;
+ mlxsw_sp->span->span_entry_ops_arr = mlxsw_sp1_span_entry_ops_arr;
+ mlxsw_sp->span->span_entry_ops_arr_size = arr_size;
+
+ return 0;
+}
+
+static u32 mlxsw_sp1_span_buffsize_get(int mtu, u32 speed)
+{
+ return mtu * 5 / 2;
+}
+
+static int mlxsw_sp1_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
+ u16 policer_id_base)
+{
+ return -EOPNOTSUPP;
+}
+
+const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops = {
+ .init = mlxsw_sp1_span_init,
+ .buffsize_get = mlxsw_sp1_span_buffsize_get,
+ .policer_id_base_set = mlxsw_sp1_span_policer_id_base_set,
+};
+
+static int mlxsw_sp2_span_init(struct mlxsw_sp *mlxsw_sp)
+{
+ size_t arr_size = ARRAY_SIZE(mlxsw_sp2_span_entry_ops_arr);
+
+ /* Must be first to avoid NULL pointer dereference by subsequent
+ * can_handle() callbacks.
+ */
+ if (WARN_ON(mlxsw_sp2_span_entry_ops_arr[0] !=
+ &mlxsw_sp2_span_entry_ops_cpu))
+ return -EINVAL;
+
+ mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp2_span_trigger_ops_arr;
+ mlxsw_sp->span->span_entry_ops_arr = mlxsw_sp2_span_entry_ops_arr;
+ mlxsw_sp->span->span_entry_ops_arr_size = arr_size;
+
+ return 0;
+}
+
+#define MLXSW_SP2_SPAN_EG_MIRROR_BUFFER_FACTOR 38
+#define MLXSW_SP3_SPAN_EG_MIRROR_BUFFER_FACTOR 50
+
+static u32 __mlxsw_sp_span_buffsize_get(int mtu, u32 speed, u32 buffer_factor)
+{
+ return 3 * mtu + buffer_factor * speed / 1000;
+}
+
+static u32 mlxsw_sp2_span_buffsize_get(int mtu, u32 speed)
+{
+ int factor = MLXSW_SP2_SPAN_EG_MIRROR_BUFFER_FACTOR;
+
+ return __mlxsw_sp_span_buffsize_get(mtu, speed, factor);
+}
+
+static int mlxsw_sp2_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
+ u16 policer_id_base)
+{
+ char mogcr_pl[MLXSW_REG_MOGCR_LEN];
+ int err;
+
+ err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mogcr), mogcr_pl);
+ if (err)
+ return err;
+
+ mlxsw_reg_mogcr_mirroring_pid_base_set(mogcr_pl, policer_id_base);
+ return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mogcr), mogcr_pl);
+}
+
+const struct mlxsw_sp_span_ops mlxsw_sp2_span_ops = {
+ .init = mlxsw_sp2_span_init,
+ .buffsize_get = mlxsw_sp2_span_buffsize_get,
+ .policer_id_base_set = mlxsw_sp2_span_policer_id_base_set,
+};
+
+static u32 mlxsw_sp3_span_buffsize_get(int mtu, u32 speed)
+{
+ int factor = MLXSW_SP3_SPAN_EG_MIRROR_BUFFER_FACTOR;
+
+ return __mlxsw_sp_span_buffsize_get(mtu, speed, factor);
+}
+
+const struct mlxsw_sp_span_ops mlxsw_sp3_span_ops = {
+ .init = mlxsw_sp2_span_init,
+ .buffsize_get = mlxsw_sp3_span_buffsize_get,
+ .policer_id_base_set = mlxsw_sp2_span_policer_id_base_set,
+};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
index 9f6dd2d0f4e6..1c746dd3b1bd 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
@@ -21,19 +21,37 @@ struct mlxsw_sp_span_parms {
union mlxsw_sp_l3addr daddr;
union mlxsw_sp_l3addr saddr;
u16 vid;
+ u16 policer_id;
+ bool policer_enable;
};
enum mlxsw_sp_span_trigger {
MLXSW_SP_SPAN_TRIGGER_INGRESS,
MLXSW_SP_SPAN_TRIGGER_EGRESS,
+ MLXSW_SP_SPAN_TRIGGER_TAIL_DROP,
+ MLXSW_SP_SPAN_TRIGGER_EARLY_DROP,
+ MLXSW_SP_SPAN_TRIGGER_ECN,
};
struct mlxsw_sp_span_trigger_parms {
int span_id;
};
+struct mlxsw_sp_span_agent_parms {
+ const struct net_device *to_dev;
+ u16 policer_id;
+ bool policer_enable;
+};
+
struct mlxsw_sp_span_entry_ops;
+struct mlxsw_sp_span_ops {
+ int (*init)(struct mlxsw_sp *mlxsw_sp);
+ u32 (*buffsize_get)(int mtu, u32 speed);
+ int (*policer_id_base_set)(struct mlxsw_sp *mlxsw_sp,
+ u16 policer_id_base);
+};
+
struct mlxsw_sp_span_entry {
const struct net_device *to_dev;
const struct mlxsw_sp_span_entry_ops *ops;
@@ -44,7 +62,8 @@ struct mlxsw_sp_span_entry {
struct mlxsw_sp_span_entry_ops {
bool (*can_handle)(const struct net_device *to_dev);
- int (*parms_set)(const struct net_device *to_dev,
+ int (*parms_set)(struct mlxsw_sp *mlxsw_sp,
+ const struct net_device *to_dev,
struct mlxsw_sp_span_parms *sparmsp);
int (*configure)(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms);
@@ -65,8 +84,8 @@ void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu);
void mlxsw_sp_span_speed_update_work(struct work_struct *work);
-int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp,
- const struct net_device *to_dev, int *p_span_id);
+int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp, int *p_span_id,
+ const struct mlxsw_sp_span_agent_parms *parms);
void mlxsw_sp_span_agent_put(struct mlxsw_sp *mlxsw_sp, int span_id);
int mlxsw_sp_span_analyzed_port_get(struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress);
@@ -81,5 +100,13 @@ mlxsw_sp_span_agent_unbind(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_span_trigger trigger,
struct mlxsw_sp_port *mlxsw_sp_port,
const struct mlxsw_sp_span_trigger_parms *parms);
+int mlxsw_sp_span_trigger_enable(struct mlxsw_sp_port *mlxsw_sp_port,
+ enum mlxsw_sp_span_trigger trigger, u8 tc);
+void mlxsw_sp_span_trigger_disable(struct mlxsw_sp_port *mlxsw_sp_port,
+ enum mlxsw_sp_span_trigger trigger, u8 tc);
+
+extern const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops;
+extern const struct mlxsw_sp_span_ops mlxsw_sp2_span_ops;
+extern const struct mlxsw_sp_span_ops mlxsw_sp3_span_ops;
#endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c
index 1e38dfe7cf64..2e41c5519c1b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c
@@ -21,6 +21,7 @@ struct mlxsw_sp_trap_group_item {
struct devlink_trap_group group;
u16 hw_group_id;
u8 priority;
+ u8 fixed_policer:1; /* Whether policer binding can change */
};
#define MLXSW_SP_TRAP_LISTENERS_MAX 3
@@ -28,6 +29,7 @@ struct mlxsw_sp_trap_group_item {
struct mlxsw_sp_trap_item {
struct devlink_trap trap;
struct mlxsw_listener listeners_arr[MLXSW_SP_TRAP_LISTENERS_MAX];
+ u8 is_source:1;
};
/* All driver-specific traps must be documented in
@@ -46,6 +48,11 @@ enum {
#define MLXSW_SP_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
+enum {
+ /* Packet was early dropped. */
+ MLXSW_SP_MIRROR_REASON_INGRESS_WRED = 9,
+};
+
static int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
u8 local_port,
struct mlxsw_sp_port *mlxsw_sp_port)
@@ -222,6 +229,11 @@ static void mlxsw_sp_rx_sample_listener(struct sk_buff *skb, u8 local_port,
DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
MLXSW_SP_TRAP_METADATA | (_metadata))
+#define MLXSW_SP_TRAP_BUFFER_DROP(_id) \
+ DEVLINK_TRAP_GENERIC(DROP, TRAP, _id, \
+ DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS, \
+ MLXSW_SP_TRAP_METADATA)
+
#define MLXSW_SP_TRAP_DRIVER_DROP(_id, _group_id) \
DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_MLXSW_TRAP_ID_##_id, \
DEVLINK_MLXSW_TRAP_NAME_##_id, \
@@ -248,6 +260,10 @@ static void mlxsw_sp_rx_sample_listener(struct sk_buff *skb, u8 local_port,
TRAP_EXCEPTION_TO_CPU, false, SP_##_en_group_id, \
SET_FW_DEFAULT, SP_##_dis_group_id)
+#define MLXSW_SP_RXL_BUFFER_DISCARD(_mirror_reason) \
+ MLXSW_RXL_MIRROR(mlxsw_sp_rx_drop_listener, 0, SP_BUFFER_DISCARDS, \
+ MLXSW_SP_MIRROR_REASON_##_mirror_reason)
+
#define MLXSW_SP_RXL_EXCEPTION(_id, _group_id, _action) \
MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, \
_action, false, SP_##_group_id, SET_FW_DEFAULT)
@@ -331,6 +347,9 @@ mlxsw_sp_trap_policer_items_arr[] = {
{
.policer = MLXSW_SP_TRAP_POLICER(19, 1024, 512),
},
+ {
+ .policer = MLXSW_SP_TRAP_POLICER(20, 10240, 4096),
+ },
};
static const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = {
@@ -1063,10 +1082,10 @@ static int mlxsw_sp_trap_dummy_group_init(struct mlxsw_sp *mlxsw_sp)
static int mlxsw_sp_trap_policer_items_arr_init(struct mlxsw_sp *mlxsw_sp)
{
+ size_t arr_size = ARRAY_SIZE(mlxsw_sp_trap_policer_items_arr);
size_t elem_size = sizeof(struct mlxsw_sp_trap_policer_item);
- u64 arr_size = ARRAY_SIZE(mlxsw_sp_trap_policer_items_arr);
struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
- u64 free_policers = 0;
+ size_t free_policers = 0;
u32 last_id;
int i;
@@ -1159,6 +1178,43 @@ static void mlxsw_sp_trap_policers_fini(struct mlxsw_sp *mlxsw_sp)
mlxsw_sp_trap_policer_items_arr_fini(mlxsw_sp);
}
+static int mlxsw_sp_trap_group_items_arr_init(struct mlxsw_sp *mlxsw_sp)
+{
+ size_t common_groups_count = ARRAY_SIZE(mlxsw_sp_trap_group_items_arr);
+ const struct mlxsw_sp_trap_group_item *spec_group_items_arr;
+ size_t elem_size = sizeof(struct mlxsw_sp_trap_group_item);
+ struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
+ size_t groups_count, spec_groups_count;
+ int err;
+
+ err = mlxsw_sp->trap_ops->groups_init(mlxsw_sp, &spec_group_items_arr,
+ &spec_groups_count);
+ if (err)
+ return err;
+
+ /* The group items array is created by concatenating the common trap
+ * group items and the ASIC-specific trap group items.
+ */
+ groups_count = common_groups_count + spec_groups_count;
+ trap->group_items_arr = kcalloc(groups_count, elem_size, GFP_KERNEL);
+ if (!trap->group_items_arr)
+ return -ENOMEM;
+
+ memcpy(trap->group_items_arr, mlxsw_sp_trap_group_items_arr,
+ elem_size * common_groups_count);
+ memcpy(trap->group_items_arr + common_groups_count,
+ spec_group_items_arr, elem_size * spec_groups_count);
+
+ trap->groups_count = groups_count;
+
+ return 0;
+}
+
+static void mlxsw_sp_trap_group_items_arr_fini(struct mlxsw_sp *mlxsw_sp)
+{
+ kfree(mlxsw_sp->trap->group_items_arr);
+}
+
static int mlxsw_sp_trap_groups_init(struct mlxsw_sp *mlxsw_sp)
{
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
@@ -1166,13 +1222,9 @@ static int mlxsw_sp_trap_groups_init(struct mlxsw_sp *mlxsw_sp)
struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
int err, i;
- trap->group_items_arr = kmemdup(mlxsw_sp_trap_group_items_arr,
- sizeof(mlxsw_sp_trap_group_items_arr),
- GFP_KERNEL);
- if (!trap->group_items_arr)
- return -ENOMEM;
-
- trap->groups_count = ARRAY_SIZE(mlxsw_sp_trap_group_items_arr);
+ err = mlxsw_sp_trap_group_items_arr_init(mlxsw_sp);
+ if (err)
+ return err;
for (i = 0; i < trap->groups_count; i++) {
group_item = &trap->group_items_arr[i];
@@ -1189,7 +1241,7 @@ err_trap_group_register:
group_item = &trap->group_items_arr[i];
devlink_trap_groups_unregister(devlink, &group_item->group, 1);
}
- kfree(trap->group_items_arr);
+ mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp);
return err;
}
@@ -1205,7 +1257,7 @@ static void mlxsw_sp_trap_groups_fini(struct mlxsw_sp *mlxsw_sp)
group_item = &trap->group_items_arr[i];
devlink_trap_groups_unregister(devlink, &group_item->group, 1);
}
- kfree(trap->group_items_arr);
+ mlxsw_sp_trap_group_items_arr_fini(mlxsw_sp);
}
static bool
@@ -1214,6 +1266,43 @@ mlxsw_sp_trap_listener_is_valid(const struct mlxsw_listener *listener)
return listener->trap_id != 0;
}
+static int mlxsw_sp_trap_items_arr_init(struct mlxsw_sp *mlxsw_sp)
+{
+ size_t common_traps_count = ARRAY_SIZE(mlxsw_sp_trap_items_arr);
+ const struct mlxsw_sp_trap_item *spec_trap_items_arr;
+ size_t elem_size = sizeof(struct mlxsw_sp_trap_item);
+ struct mlxsw_sp_trap *trap = mlxsw_sp->trap;
+ size_t traps_count, spec_traps_count;
+ int err;
+
+ err = mlxsw_sp->trap_ops->traps_init(mlxsw_sp, &spec_trap_items_arr,
+ &spec_traps_count);
+ if (err)
+ return err;
+
+ /* The trap items array is created by concatenating the common trap
+ * items and the ASIC-specific trap items.
+ */
+ traps_count = common_traps_count + spec_traps_count;
+ trap->trap_items_arr = kcalloc(traps_count, elem_size, GFP_KERNEL);
+ if (!trap->trap_items_arr)
+ return -ENOMEM;
+
+ memcpy(trap->trap_items_arr, mlxsw_sp_trap_items_arr,
+ elem_size * common_traps_count);
+ memcpy(trap->trap_items_arr + common_traps_count,
+ spec_trap_items_arr, elem_size * spec_traps_count);
+
+ trap->traps_count = traps_count;
+
+ return 0;
+}
+
+static void mlxsw_sp_trap_items_arr_fini(struct mlxsw_sp *mlxsw_sp)
+{
+ kfree(mlxsw_sp->trap->trap_items_arr);
+}
+
static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
{
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
@@ -1221,13 +1310,9 @@ static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
const struct mlxsw_sp_trap_item *trap_item;
int err, i;
- trap->trap_items_arr = kmemdup(mlxsw_sp_trap_items_arr,
- sizeof(mlxsw_sp_trap_items_arr),
- GFP_KERNEL);
- if (!trap->trap_items_arr)
- return -ENOMEM;
-
- trap->traps_count = ARRAY_SIZE(mlxsw_sp_trap_items_arr);
+ err = mlxsw_sp_trap_items_arr_init(mlxsw_sp);
+ if (err)
+ return err;
for (i = 0; i < trap->traps_count; i++) {
trap_item = &trap->trap_items_arr[i];
@@ -1244,7 +1329,7 @@ err_trap_register:
trap_item = &trap->trap_items_arr[i];
devlink_traps_unregister(devlink, &trap_item->trap, 1);
}
- kfree(trap->trap_items_arr);
+ mlxsw_sp_trap_items_arr_fini(mlxsw_sp);
return err;
}
@@ -1260,7 +1345,7 @@ static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
trap_item = &trap->trap_items_arr[i];
devlink_traps_unregister(devlink, &trap_item->trap, 1);
}
- kfree(trap->trap_items_arr);
+ mlxsw_sp_trap_items_arr_fini(mlxsw_sp);
}
int mlxsw_sp_devlink_traps_init(struct mlxsw_sp *mlxsw_sp)
@@ -1352,7 +1437,8 @@ void mlxsw_sp_trap_fini(struct mlxsw_core *mlxsw_core,
int mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core,
const struct devlink_trap *trap,
- enum devlink_trap_action action)
+ enum devlink_trap_action action,
+ struct netlink_ext_ack *extack)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
const struct mlxsw_sp_trap_item *trap_item;
@@ -1362,6 +1448,11 @@ int mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core,
if (WARN_ON(!trap_item))
return -EINVAL;
+ if (trap_item->is_source) {
+ NL_SET_ERR_MSG_MOD(extack, "Changing the action of source traps is not supported");
+ return -EOPNOTSUPP;
+ }
+
for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) {
const struct mlxsw_listener *listener;
bool enabled;
@@ -1392,7 +1483,7 @@ int mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core,
static int
__mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_group *group,
- u32 policer_id)
+ u32 policer_id, struct netlink_ext_ack *extack)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
u16 hw_policer_id = MLXSW_REG_HTGT_INVALID_POLICER;
@@ -1403,6 +1494,11 @@ __mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
if (WARN_ON(!group_item))
return -EINVAL;
+ if (group_item->fixed_policer && policer_id != group->init_policer_id) {
+ NL_SET_ERR_MSG_MOD(extack, "Changing the policer binding of this group is not supported");
+ return -EOPNOTSUPP;
+ }
+
if (policer_id) {
struct mlxsw_sp_trap_policer_item *policer_item;
@@ -1422,16 +1518,18 @@ int mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_group *group)
{
return __mlxsw_sp_trap_group_init(mlxsw_core, group,
- group->init_policer_id);
+ group->init_policer_id, NULL);
}
int mlxsw_sp_trap_group_set(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_group *group,
- const struct devlink_trap_policer *policer)
+ const struct devlink_trap_policer *policer,
+ struct netlink_ext_ack *extack)
{
u32 policer_id = policer ? policer->id : 0;
- return __mlxsw_sp_trap_group_init(mlxsw_core, group, policer_id);
+ return __mlxsw_sp_trap_group_init(mlxsw_core, group, policer_id,
+ extack);
}
static int
@@ -1576,3 +1674,110 @@ mlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core,
return 0;
}
+
+int mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp *mlxsw_sp, u16 id,
+ bool *p_enabled, u16 *p_hw_id)
+{
+ struct mlxsw_sp_trap_policer_item *pol_item;
+ struct mlxsw_sp_trap_group_item *gr_item;
+ u32 pol_id;
+
+ gr_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, id);
+ if (!gr_item)
+ return -ENOENT;
+
+ pol_id = gr_item->group.init_policer_id;
+ if (!pol_id) {
+ *p_enabled = false;
+ return 0;
+ }
+
+ pol_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, pol_id);
+ if (WARN_ON(!pol_item))
+ return -ENOENT;
+
+ *p_enabled = true;
+ *p_hw_id = pol_item->hw_id;
+ return 0;
+}
+
+static const struct mlxsw_sp_trap_group_item
+mlxsw_sp1_trap_group_items_arr[] = {
+};
+
+static const struct mlxsw_sp_trap_item
+mlxsw_sp1_trap_items_arr[] = {
+};
+
+static int
+mlxsw_sp1_trap_groups_init(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_trap_group_item **arr,
+ size_t *p_groups_count)
+{
+ *arr = mlxsw_sp1_trap_group_items_arr;
+ *p_groups_count = ARRAY_SIZE(mlxsw_sp1_trap_group_items_arr);
+
+ return 0;
+}
+
+static int mlxsw_sp1_traps_init(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_trap_item **arr,
+ size_t *p_traps_count)
+{
+ *arr = mlxsw_sp1_trap_items_arr;
+ *p_traps_count = ARRAY_SIZE(mlxsw_sp1_trap_items_arr);
+
+ return 0;
+}
+
+const struct mlxsw_sp_trap_ops mlxsw_sp1_trap_ops = {
+ .groups_init = mlxsw_sp1_trap_groups_init,
+ .traps_init = mlxsw_sp1_traps_init,
+};
+
+static const struct mlxsw_sp_trap_group_item
+mlxsw_sp2_trap_group_items_arr[] = {
+ {
+ .group = DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 20),
+ .hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BUFFER_DISCARDS,
+ .priority = 0,
+ .fixed_policer = true,
+ },
+};
+
+static const struct mlxsw_sp_trap_item
+mlxsw_sp2_trap_items_arr[] = {
+ {
+ .trap = MLXSW_SP_TRAP_BUFFER_DROP(EARLY_DROP),
+ .listeners_arr = {
+ MLXSW_SP_RXL_BUFFER_DISCARD(INGRESS_WRED),
+ },
+ .is_source = true,
+ },
+};
+
+static int
+mlxsw_sp2_trap_groups_init(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_trap_group_item **arr,
+ size_t *p_groups_count)
+{
+ *arr = mlxsw_sp2_trap_group_items_arr;
+ *p_groups_count = ARRAY_SIZE(mlxsw_sp2_trap_group_items_arr);
+
+ return 0;
+}
+
+static int mlxsw_sp2_traps_init(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_trap_item **arr,
+ size_t *p_traps_count)
+{
+ *arr = mlxsw_sp2_trap_items_arr;
+ *p_traps_count = ARRAY_SIZE(mlxsw_sp2_trap_items_arr);
+
+ return 0;
+}
+
+const struct mlxsw_sp_trap_ops mlxsw_sp2_trap_ops = {
+ .groups_init = mlxsw_sp2_trap_groups_init,
+ .traps_init = mlxsw_sp2_traps_init,
+};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.h
index 13ac412f4d53..b8df684bedef 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.h
@@ -9,13 +9,13 @@
struct mlxsw_sp_trap {
struct mlxsw_sp_trap_policer_item *policer_items_arr;
- u64 policers_count; /* Number of registered policers */
+ size_t policers_count; /* Number of registered policers */
struct mlxsw_sp_trap_group_item *group_items_arr;
- u64 groups_count; /* Number of registered groups */
+ size_t groups_count; /* Number of registered groups */
struct mlxsw_sp_trap_item *trap_items_arr;
- u64 traps_count; /* Number of registered traps */
+ size_t traps_count; /* Number of registered traps */
u16 thin_policer_hw_id;
@@ -23,4 +23,16 @@ struct mlxsw_sp_trap {
unsigned long policers_usage[]; /* Usage bitmap */
};
+struct mlxsw_sp_trap_ops {
+ int (*groups_init)(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_trap_group_item **arr,
+ size_t *p_groups_count);
+ int (*traps_init)(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_trap_item **arr,
+ size_t *p_traps_count);
+};
+
+extern const struct mlxsw_sp_trap_ops mlxsw_sp1_trap_ops;
+extern const struct mlxsw_sp_trap_ops mlxsw_sp2_trap_ops;
+
#endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchib.c b/drivers/net/ethernet/mellanox/mlxsw/switchib.c
index 4ff1e623aa76..1e561132eb1e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchib.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchib.c
@@ -281,7 +281,7 @@ static int mlxsw_sib_port_create(struct mlxsw_sib *mlxsw_sib, u8 local_port,
int err;
err = mlxsw_core_port_init(mlxsw_sib->core, local_port,
- module + 1, false, 0,
+ module + 1, false, 0, false, 0,
mlxsw_sib->hw_id, sizeof(mlxsw_sib->hw_id));
if (err) {
dev_err(mlxsw_sib->bus_info->dev, "Port %d: Failed to init core port\n",
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index b438f5576e18..6f9a725662fb 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -1107,7 +1107,7 @@ static int mlxsw_sx_port_eth_create(struct mlxsw_sx *mlxsw_sx, u8 local_port,
int err;
err = mlxsw_core_port_init(mlxsw_sx->core, local_port,
- module + 1, false, 0,
+ module + 1, false, 0, false, 0,
mlxsw_sx->hw_id, sizeof(mlxsw_sx->hw_id));
if (err) {
dev_err(mlxsw_sx->bus_info->dev, "Port %d: Failed to init core port\n",
diff --git a/drivers/net/ethernet/mellanox/mlxsw/trap.h b/drivers/net/ethernet/mellanox/mlxsw/trap.h
index 28e60697d14e..33909887d0ac 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/trap.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/trap.h
@@ -107,8 +107,16 @@ enum {
MLXSW_TRAP_ID_ACL2 = 0x1C2,
MLXSW_TRAP_ID_DISCARD_INGRESS_ACL = 0x1C3,
MLXSW_TRAP_ID_DISCARD_EGRESS_ACL = 0x1C4,
+ MLXSW_TRAP_ID_MIRROR_SESSION0 = 0x220,
+ MLXSW_TRAP_ID_MIRROR_SESSION1 = 0x221,
+ MLXSW_TRAP_ID_MIRROR_SESSION2 = 0x222,
+ MLXSW_TRAP_ID_MIRROR_SESSION3 = 0x223,
+ MLXSW_TRAP_ID_MIRROR_SESSION4 = 0x224,
+ MLXSW_TRAP_ID_MIRROR_SESSION5 = 0x225,
+ MLXSW_TRAP_ID_MIRROR_SESSION6 = 0x226,
+ MLXSW_TRAP_ID_MIRROR_SESSION7 = 0x227,
- MLXSW_TRAP_ID_MAX = 0x1FF
+ MLXSW_TRAP_ID_MAX = 0x3FF,
};
enum mlxsw_event_trap_id {
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index 4fe6aedca22f..bb646b65cc95 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -4390,9 +4390,9 @@ static int ksz_alloc_desc(struct dev_info *adapter)
DESC_ALIGNMENT;
adapter->desc_pool.alloc_virt =
- pci_zalloc_consistent(adapter->pdev,
- adapter->desc_pool.alloc_size,
- &adapter->desc_pool.dma_addr);
+ dma_alloc_coherent(&adapter->pdev->dev,
+ adapter->desc_pool.alloc_size,
+ &adapter->desc_pool.dma_addr, GFP_KERNEL);
if (adapter->desc_pool.alloc_virt == NULL) {
adapter->desc_pool.alloc_size = 0;
return 1;
@@ -4431,7 +4431,8 @@ static int ksz_alloc_desc(struct dev_info *adapter)
static void free_dma_buf(struct dev_info *adapter, struct ksz_dma_buf *dma_buf,
int direction)
{
- pci_unmap_single(adapter->pdev, dma_buf->dma, dma_buf->len, direction);
+ dma_unmap_single(&adapter->pdev->dev, dma_buf->dma, dma_buf->len,
+ direction);
dev_kfree_skb(dma_buf->skb);
dma_buf->skb = NULL;
dma_buf->dma = 0;
@@ -4456,16 +4457,15 @@ static void ksz_init_rx_buffers(struct dev_info *adapter)
dma_buf = DMA_BUFFER(desc);
if (dma_buf->skb && dma_buf->len != adapter->mtu)
- free_dma_buf(adapter, dma_buf, PCI_DMA_FROMDEVICE);
+ free_dma_buf(adapter, dma_buf, DMA_FROM_DEVICE);
dma_buf->len = adapter->mtu;
if (!dma_buf->skb)
dma_buf->skb = alloc_skb(dma_buf->len, GFP_ATOMIC);
if (dma_buf->skb && !dma_buf->dma)
- dma_buf->dma = pci_map_single(
- adapter->pdev,
- skb_tail_pointer(dma_buf->skb),
- dma_buf->len,
- PCI_DMA_FROMDEVICE);
+ dma_buf->dma = dma_map_single(&adapter->pdev->dev,
+ skb_tail_pointer(dma_buf->skb),
+ dma_buf->len,
+ DMA_FROM_DEVICE);
/* Set descriptor. */
set_rx_buf(desc, dma_buf->dma);
@@ -4543,11 +4543,10 @@ static void ksz_free_desc(struct dev_info *adapter)
/* Free memory. */
if (adapter->desc_pool.alloc_virt)
- pci_free_consistent(
- adapter->pdev,
- adapter->desc_pool.alloc_size,
- adapter->desc_pool.alloc_virt,
- adapter->desc_pool.dma_addr);
+ dma_free_coherent(&adapter->pdev->dev,
+ adapter->desc_pool.alloc_size,
+ adapter->desc_pool.alloc_virt,
+ adapter->desc_pool.dma_addr);
/* Reset resource pool. */
adapter->desc_pool.alloc_size = 0;
@@ -4590,12 +4589,10 @@ static void ksz_free_buffers(struct dev_info *adapter,
static void ksz_free_mem(struct dev_info *adapter)
{
/* Free transmit buffers. */
- ksz_free_buffers(adapter, &adapter->hw.tx_desc_info,
- PCI_DMA_TODEVICE);
+ ksz_free_buffers(adapter, &adapter->hw.tx_desc_info, DMA_TO_DEVICE);
/* Free receive buffers. */
- ksz_free_buffers(adapter, &adapter->hw.rx_desc_info,
- PCI_DMA_FROMDEVICE);
+ ksz_free_buffers(adapter, &adapter->hw.rx_desc_info, DMA_FROM_DEVICE);
/* Free descriptors. */
ksz_free_desc(adapter);
@@ -4657,9 +4654,8 @@ static void send_packet(struct sk_buff *skb, struct net_device *dev)
dma_buf->len = skb_headlen(skb);
- dma_buf->dma = pci_map_single(
- hw_priv->pdev, skb->data, dma_buf->len,
- PCI_DMA_TODEVICE);
+ dma_buf->dma = dma_map_single(&hw_priv->pdev->dev, skb->data,
+ dma_buf->len, DMA_TO_DEVICE);
set_tx_buf(desc, dma_buf->dma);
set_tx_len(desc, dma_buf->len);
@@ -4676,11 +4672,10 @@ static void send_packet(struct sk_buff *skb, struct net_device *dev)
dma_buf = DMA_BUFFER(desc);
dma_buf->len = skb_frag_size(this_frag);
- dma_buf->dma = pci_map_single(
- hw_priv->pdev,
- skb_frag_address(this_frag),
- dma_buf->len,
- PCI_DMA_TODEVICE);
+ dma_buf->dma = dma_map_single(&hw_priv->pdev->dev,
+ skb_frag_address(this_frag),
+ dma_buf->len,
+ DMA_TO_DEVICE);
set_tx_buf(desc, dma_buf->dma);
set_tx_len(desc, dma_buf->len);
@@ -4700,9 +4695,8 @@ static void send_packet(struct sk_buff *skb, struct net_device *dev)
} else {
dma_buf->len = len;
- dma_buf->dma = pci_map_single(
- hw_priv->pdev, skb->data, dma_buf->len,
- PCI_DMA_TODEVICE);
+ dma_buf->dma = dma_map_single(&hw_priv->pdev->dev, skb->data,
+ dma_buf->len, DMA_TO_DEVICE);
set_tx_buf(desc, dma_buf->dma);
set_tx_len(desc, dma_buf->len);
}
@@ -4756,9 +4750,8 @@ static void transmit_cleanup(struct dev_info *hw_priv, int normal)
}
dma_buf = DMA_BUFFER(desc);
- pci_unmap_single(
- hw_priv->pdev, dma_buf->dma, dma_buf->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&hw_priv->pdev->dev, dma_buf->dma,
+ dma_buf->len, DMA_TO_DEVICE);
/* This descriptor contains the last buffer in the packet. */
if (dma_buf->skb) {
@@ -4991,9 +4984,8 @@ static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw,
packet_len = status.rx.frame_len - 4;
dma_buf = DMA_BUFFER(desc);
- pci_dma_sync_single_for_cpu(
- hw_priv->pdev, dma_buf->dma, packet_len + 4,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&hw_priv->pdev->dev, dma_buf->dma,
+ packet_len + 4, DMA_FROM_DEVICE);
do {
/* skb->data != skb->head */
@@ -6935,8 +6927,8 @@ static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id)
result = -ENODEV;
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
- pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
+ if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)) ||
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)))
return result;
reg_base = pci_resource_start(pdev, 0);
@@ -7155,17 +7147,14 @@ static void pcidev_exit(struct pci_dev *pdev)
kfree(info);
}
-#ifdef CONFIG_PM
-static int pcidev_resume(struct pci_dev *pdev)
+static int __maybe_unused pcidev_resume(struct device *dev_d)
{
int i;
- struct platform_info *info = pci_get_drvdata(pdev);
+ struct platform_info *info = dev_get_drvdata(dev_d);
struct dev_info *hw_priv = &info->dev_info;
struct ksz_hw *hw = &hw_priv->hw;
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D0, 0);
+ device_wakeup_disable(dev_d);
if (hw_priv->wol_enable)
hw_cfg_wol_pme(hw, 0);
@@ -7182,10 +7171,10 @@ static int pcidev_resume(struct pci_dev *pdev)
return 0;
}
-static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused pcidev_suspend(struct device *dev_d)
{
int i;
- struct platform_info *info = pci_get_drvdata(pdev);
+ struct platform_info *info = dev_get_drvdata(dev_d);
struct dev_info *hw_priv = &info->dev_info;
struct ksz_hw *hw = &hw_priv->hw;
@@ -7207,12 +7196,9 @@ static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state)
hw_cfg_wol_pme(hw, 1);
}
- pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ device_wakeup_enable(dev_d);
return 0;
}
-#endif
static char pcidev_name[] = "ksz884xp";
@@ -7226,11 +7212,10 @@ static const struct pci_device_id pcidev_table[] = {
MODULE_DEVICE_TABLE(pci, pcidev_table);
+static SIMPLE_DEV_PM_OPS(pcidev_pm_ops, pcidev_suspend, pcidev_resume);
+
static struct pci_driver pci_device_driver = {
-#ifdef CONFIG_PM
- .suspend = pcidev_suspend,
- .resume = pcidev_resume,
-#endif
+ .driver.pm = &pcidev_pm_ops,
.name = pcidev_name,
.id_table = pcidev_table,
.probe = pcidev_init,
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index f1711ac86d0c..de93cc6ebc1a 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -807,26 +807,29 @@ static int lan743x_mac_init(struct lan743x_adapter *adapter)
data |= MAC_CR_CNTR_RST_;
lan743x_csr_write(adapter, MAC_CR, data);
- mac_addr_hi = lan743x_csr_read(adapter, MAC_RX_ADDRH);
- mac_addr_lo = lan743x_csr_read(adapter, MAC_RX_ADDRL);
- adapter->mac_address[0] = mac_addr_lo & 0xFF;
- adapter->mac_address[1] = (mac_addr_lo >> 8) & 0xFF;
- adapter->mac_address[2] = (mac_addr_lo >> 16) & 0xFF;
- adapter->mac_address[3] = (mac_addr_lo >> 24) & 0xFF;
- adapter->mac_address[4] = mac_addr_hi & 0xFF;
- adapter->mac_address[5] = (mac_addr_hi >> 8) & 0xFF;
-
- if (((mac_addr_hi & 0x0000FFFF) == 0x0000FFFF) &&
- mac_addr_lo == 0xFFFFFFFF) {
- mac_address_valid = false;
- } else if (!is_valid_ether_addr(adapter->mac_address)) {
- mac_address_valid = false;
- }
-
- if (!mac_address_valid)
- eth_random_addr(adapter->mac_address);
+ if (!is_valid_ether_addr(adapter->mac_address)) {
+ mac_addr_hi = lan743x_csr_read(adapter, MAC_RX_ADDRH);
+ mac_addr_lo = lan743x_csr_read(adapter, MAC_RX_ADDRL);
+ adapter->mac_address[0] = mac_addr_lo & 0xFF;
+ adapter->mac_address[1] = (mac_addr_lo >> 8) & 0xFF;
+ adapter->mac_address[2] = (mac_addr_lo >> 16) & 0xFF;
+ adapter->mac_address[3] = (mac_addr_lo >> 24) & 0xFF;
+ adapter->mac_address[4] = mac_addr_hi & 0xFF;
+ adapter->mac_address[5] = (mac_addr_hi >> 8) & 0xFF;
+
+ if (((mac_addr_hi & 0x0000FFFF) == 0x0000FFFF) &&
+ mac_addr_lo == 0xFFFFFFFF) {
+ mac_address_valid = false;
+ } else if (!is_valid_ether_addr(adapter->mac_address)) {
+ mac_address_valid = false;
+ }
+
+ if (!mac_address_valid)
+ eth_random_addr(adapter->mac_address);
+ }
lan743x_mac_set_address(adapter, adapter->mac_address);
ether_addr_copy(netdev->dev_addr, adapter->mac_address);
+
return 0;
}
@@ -1739,10 +1742,9 @@ done:
static void lan743x_tx_ring_cleanup(struct lan743x_tx *tx)
{
if (tx->head_cpu_ptr) {
- pci_free_consistent(tx->adapter->pdev,
- sizeof(*tx->head_cpu_ptr),
- (void *)(tx->head_cpu_ptr),
- tx->head_dma_ptr);
+ dma_free_coherent(&tx->adapter->pdev->dev,
+ sizeof(*tx->head_cpu_ptr), tx->head_cpu_ptr,
+ tx->head_dma_ptr);
tx->head_cpu_ptr = NULL;
tx->head_dma_ptr = 0;
}
@@ -1750,10 +1752,9 @@ static void lan743x_tx_ring_cleanup(struct lan743x_tx *tx)
tx->buffer_info = NULL;
if (tx->ring_cpu_ptr) {
- pci_free_consistent(tx->adapter->pdev,
- tx->ring_allocation_size,
- tx->ring_cpu_ptr,
- tx->ring_dma_ptr);
+ dma_free_coherent(&tx->adapter->pdev->dev,
+ tx->ring_allocation_size, tx->ring_cpu_ptr,
+ tx->ring_dma_ptr);
tx->ring_allocation_size = 0;
tx->ring_cpu_ptr = NULL;
tx->ring_dma_ptr = 0;
@@ -1777,8 +1778,8 @@ static int lan743x_tx_ring_init(struct lan743x_tx *tx)
sizeof(struct lan743x_tx_descriptor),
PAGE_SIZE);
dma_ptr = 0;
- cpu_ptr = pci_zalloc_consistent(tx->adapter->pdev,
- ring_allocation_size, &dma_ptr);
+ cpu_ptr = dma_alloc_coherent(&tx->adapter->pdev->dev,
+ ring_allocation_size, &dma_ptr, GFP_KERNEL);
if (!cpu_ptr) {
ret = -ENOMEM;
goto cleanup;
@@ -1795,8 +1796,9 @@ static int lan743x_tx_ring_init(struct lan743x_tx *tx)
}
tx->buffer_info = (struct lan743x_tx_buffer_info *)cpu_ptr;
dma_ptr = 0;
- cpu_ptr = pci_zalloc_consistent(tx->adapter->pdev,
- sizeof(*tx->head_cpu_ptr), &dma_ptr);
+ cpu_ptr = dma_alloc_coherent(&tx->adapter->pdev->dev,
+ sizeof(*tx->head_cpu_ptr), &dma_ptr,
+ GFP_KERNEL);
if (!cpu_ptr) {
ret = -ENOMEM;
goto cleanup;
@@ -2044,14 +2046,13 @@ static int lan743x_rx_process_packet(struct lan743x_rx *rx)
{
struct skb_shared_hwtstamps *hwtstamps = NULL;
int result = RX_PROCESS_RESULT_NOTHING_TO_DO;
+ int current_head_index = *rx->head_cpu_ptr;
struct lan743x_rx_buffer_info *buffer_info;
struct lan743x_rx_descriptor *descriptor;
- int current_head_index = -1;
int extension_index = -1;
int first_index = -1;
int last_index = -1;
- current_head_index = *rx->head_cpu_ptr;
if (current_head_index < 0 || current_head_index >= rx->ring_size)
goto done;
@@ -2278,10 +2279,9 @@ static void lan743x_rx_ring_cleanup(struct lan743x_rx *rx)
}
if (rx->head_cpu_ptr) {
- pci_free_consistent(rx->adapter->pdev,
- sizeof(*rx->head_cpu_ptr),
- rx->head_cpu_ptr,
- rx->head_dma_ptr);
+ dma_free_coherent(&rx->adapter->pdev->dev,
+ sizeof(*rx->head_cpu_ptr), rx->head_cpu_ptr,
+ rx->head_dma_ptr);
rx->head_cpu_ptr = NULL;
rx->head_dma_ptr = 0;
}
@@ -2290,10 +2290,9 @@ static void lan743x_rx_ring_cleanup(struct lan743x_rx *rx)
rx->buffer_info = NULL;
if (rx->ring_cpu_ptr) {
- pci_free_consistent(rx->adapter->pdev,
- rx->ring_allocation_size,
- rx->ring_cpu_ptr,
- rx->ring_dma_ptr);
+ dma_free_coherent(&rx->adapter->pdev->dev,
+ rx->ring_allocation_size, rx->ring_cpu_ptr,
+ rx->ring_dma_ptr);
rx->ring_allocation_size = 0;
rx->ring_cpu_ptr = NULL;
rx->ring_dma_ptr = 0;
@@ -2324,8 +2323,8 @@ static int lan743x_rx_ring_init(struct lan743x_rx *rx)
sizeof(struct lan743x_rx_descriptor),
PAGE_SIZE);
dma_ptr = 0;
- cpu_ptr = pci_zalloc_consistent(rx->adapter->pdev,
- ring_allocation_size, &dma_ptr);
+ cpu_ptr = dma_alloc_coherent(&rx->adapter->pdev->dev,
+ ring_allocation_size, &dma_ptr, GFP_KERNEL);
if (!cpu_ptr) {
ret = -ENOMEM;
goto cleanup;
@@ -2342,8 +2341,9 @@ static int lan743x_rx_ring_init(struct lan743x_rx *rx)
}
rx->buffer_info = (struct lan743x_rx_buffer_info *)cpu_ptr;
dma_ptr = 0;
- cpu_ptr = pci_zalloc_consistent(rx->adapter->pdev,
- sizeof(*rx->head_cpu_ptr), &dma_ptr);
+ cpu_ptr = dma_alloc_coherent(&rx->adapter->pdev->dev,
+ sizeof(*rx->head_cpu_ptr), &dma_ptr,
+ GFP_KERNEL);
if (!cpu_ptr) {
ret = -ENOMEM;
goto cleanup;
@@ -2817,6 +2817,7 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
{
struct lan743x_adapter *adapter = NULL;
struct net_device *netdev = NULL;
+ const void *mac_addr;
int ret = -ENODEV;
netdev = devm_alloc_etherdev(&pdev->dev,
@@ -2833,6 +2834,10 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
NETIF_MSG_IFDOWN | NETIF_MSG_TX_QUEUED;
netdev->max_mtu = LAN743X_MAX_FRAME_SIZE;
+ mac_addr = of_get_mac_address(pdev->dev.of_node);
+ if (!IS_ERR(mac_addr))
+ ether_addr_copy(adapter->mac_address, mac_addr);
+
ret = lan743x_pci_init(adapter, pdev);
if (ret)
goto return_error;
diff --git a/drivers/net/ethernet/mscc/Kconfig b/drivers/net/ethernet/mscc/Kconfig
index bcec0587cf61..ee7bb7e24e8e 100644
--- a/drivers/net/ethernet/mscc/Kconfig
+++ b/drivers/net/ethernet/mscc/Kconfig
@@ -11,22 +11,24 @@ config NET_VENDOR_MICROSEMI
if NET_VENDOR_MICROSEMI
+# Users should depend on NET_SWITCHDEV, HAS_IOMEM
+config MSCC_OCELOT_SWITCH_LIB
+ select REGMAP_MMIO
+ select PHYLIB
+ tristate
+ help
+ This is a hardware support library for Ocelot network switches. It is
+ used by switchdev as well as by DSA drivers.
+
config MSCC_OCELOT_SWITCH
tristate "Ocelot switch driver"
depends on NET_SWITCHDEV
depends on HAS_IOMEM
- select PHYLIB
- select REGMAP_MMIO
- help
- This driver supports the Ocelot network switch device.
-
-config MSCC_OCELOT_SWITCH_OCELOT
- tristate "Ocelot switch driver on Ocelot"
- depends on MSCC_OCELOT_SWITCH
- depends on GENERIC_PHY
depends on OF_NET
+ select MSCC_OCELOT_SWITCH_LIB
+ select GENERIC_PHY
help
This driver supports the Ocelot network switch device as present on
- the Ocelot SoCs.
+ the Ocelot SoCs (VSC7514).
endif # NET_VENDOR_MICROSEMI
diff --git a/drivers/net/ethernet/mscc/Makefile b/drivers/net/ethernet/mscc/Makefile
index 91b33b55054e..58f94c3d80f9 100644
--- a/drivers/net/ethernet/mscc/Makefile
+++ b/drivers/net/ethernet/mscc/Makefile
@@ -1,5 +1,13 @@
# SPDX-License-Identifier: (GPL-2.0 OR MIT)
-obj-$(CONFIG_MSCC_OCELOT_SWITCH) += mscc_ocelot_common.o
-mscc_ocelot_common-y := ocelot.o ocelot_io.o
-mscc_ocelot_common-y += ocelot_regs.o ocelot_tc.o ocelot_police.o ocelot_ace.o ocelot_flower.o ocelot_ptp.o
-obj-$(CONFIG_MSCC_OCELOT_SWITCH_OCELOT) += ocelot_board.o
+obj-$(CONFIG_MSCC_OCELOT_SWITCH_LIB) += mscc_ocelot_switch_lib.o
+mscc_ocelot_switch_lib-y := \
+ ocelot.o \
+ ocelot_io.o \
+ ocelot_police.o \
+ ocelot_vcap.o \
+ ocelot_flower.o \
+ ocelot_ptp.o
+obj-$(CONFIG_MSCC_OCELOT_SWITCH) += mscc_ocelot.o
+mscc_ocelot-y := \
+ ocelot_vsc7514.o \
+ ocelot_net.o
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index f17da67a4622..867c680f5917 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -4,42 +4,13 @@
*
* Copyright (c) 2017 Microsemi Corporation
*/
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
#include <linux/if_bridge.h>
-#include <linux/if_ether.h>
-#include <linux/if_vlan.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-#include <linux/skbuff.h>
-#include <linux/iopoll.h>
-#include <net/arp.h>
-#include <net/netevent.h>
-#include <net/rtnetlink.h>
-#include <net/switchdev.h>
-
#include "ocelot.h"
-#include "ocelot_ace.h"
+#include "ocelot_vcap.h"
#define TABLE_UPDATE_SLEEP_US 10
#define TABLE_UPDATE_TIMEOUT_US 100000
-/* MAC table entry types.
- * ENTRYTYPE_NORMAL is subject to aging.
- * ENTRYTYPE_LOCKED is not subject to aging.
- * ENTRYTYPE_MACv4 is not subject to aging. For IPv4 multicast.
- * ENTRYTYPE_MACv6 is not subject to aging. For IPv6 multicast.
- */
-enum macaccess_entry_type {
- ENTRYTYPE_NORMAL = 0,
- ENTRYTYPE_LOCKED,
- ENTRYTYPE_MACv4,
- ENTRYTYPE_MACv6,
-};
-
struct ocelot_mact_entry {
u8 mac[ETH_ALEN];
u16 vid;
@@ -84,10 +55,9 @@ static void ocelot_mact_select(struct ocelot *ocelot,
}
-static int ocelot_mact_learn(struct ocelot *ocelot, int port,
- const unsigned char mac[ETH_ALEN],
- unsigned int vid,
- enum macaccess_entry_type type)
+int ocelot_mact_learn(struct ocelot *ocelot, int port,
+ const unsigned char mac[ETH_ALEN],
+ unsigned int vid, enum macaccess_entry_type type)
{
ocelot_mact_select(ocelot, mac, vid);
@@ -100,10 +70,10 @@ static int ocelot_mact_learn(struct ocelot *ocelot, int port,
return ocelot_mact_wait_for_completion(ocelot);
}
+EXPORT_SYMBOL(ocelot_mact_learn);
-static int ocelot_mact_forget(struct ocelot *ocelot,
- const unsigned char mac[ETH_ALEN],
- unsigned int vid)
+int ocelot_mact_forget(struct ocelot *ocelot,
+ const unsigned char mac[ETH_ALEN], unsigned int vid)
{
ocelot_mact_select(ocelot, mac, vid);
@@ -114,6 +84,7 @@ static int ocelot_mact_forget(struct ocelot *ocelot,
return ocelot_mact_wait_for_completion(ocelot);
}
+EXPORT_SYMBOL(ocelot_mact_forget);
static void ocelot_mact_init(struct ocelot *ocelot)
{
@@ -168,20 +139,6 @@ static int ocelot_vlant_set_mask(struct ocelot *ocelot, u16 vid, u32 mask)
return ocelot_vlant_wait_for_completion(ocelot);
}
-static void ocelot_vlan_mode(struct ocelot *ocelot, int port,
- netdev_features_t features)
-{
- u32 val;
-
- /* Filtering */
- val = ocelot_read(ocelot, ANA_VLANMASK);
- if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
- val |= BIT(port);
- else
- val &= ~BIT(port);
- ocelot_write(ocelot, val, ANA_VLANMASK);
-}
-
static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port,
u16 vid)
{
@@ -295,26 +252,6 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
}
EXPORT_SYMBOL(ocelot_vlan_add);
-static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
- bool untagged)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot_port *ocelot_port = &priv->port;
- struct ocelot *ocelot = ocelot_port->ocelot;
- int port = priv->chip_port;
- int ret;
-
- ret = ocelot_vlan_add(ocelot, port, vid, pvid, untagged);
- if (ret)
- return ret;
-
- /* Add the port MAC address to with the right VLAN information */
- ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid,
- ENTRYTYPE_LOCKED);
-
- return 0;
-}
-
int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
{
struct ocelot_port *ocelot_port = ocelot->ports[port];
@@ -338,30 +275,6 @@ int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
}
EXPORT_SYMBOL(ocelot_vlan_del);
-static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
- int ret;
-
- /* 8021q removes VID 0 on module unload for all interfaces
- * with VLAN filtering feature. We need to keep it to receive
- * untagged traffic.
- */
- if (vid == 0)
- return 0;
-
- ret = ocelot_vlan_del(ocelot, port, vid);
- if (ret)
- return ret;
-
- /* Del the port MAC address to with the right VLAN information */
- ocelot_mact_forget(ocelot, dev->dev_addr, vid);
-
- return 0;
-}
-
static void ocelot_vlan_init(struct ocelot *ocelot)
{
u16 port, vid;
@@ -396,18 +309,6 @@ static void ocelot_vlan_init(struct ocelot *ocelot)
}
}
-/* Watermark encode
- * Bit 8: Unit; 0:1, 1:16
- * Bit 7-0: Value to be multiplied with unit
- */
-static u16 ocelot_wm_enc(u16 value)
-{
- if (value >= BIT(8))
- return BIT(8) | (value / 16);
-
- return value;
-}
-
void ocelot_adjust_link(struct ocelot *ocelot, int port,
struct phy_device *phydev)
{
@@ -476,10 +377,8 @@ void ocelot_adjust_link(struct ocelot *ocelot, int port,
ANA_PFC_PFC_CFG, port);
/* Core: Enable port for frame transfer */
- ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
- QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
- QSYS_SWITCH_PORT_MODE_PORT_ENA,
- QSYS_SWITCH_PORT_MODE, port);
+ ocelot_fields_write(ocelot, port,
+ QSYS_SWITCH_PORT_MODE_PORT_ENA, 1);
/* Flow control */
ocelot_write_rix(ocelot, SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) |
@@ -492,15 +391,6 @@ void ocelot_adjust_link(struct ocelot *ocelot, int port,
}
EXPORT_SYMBOL(ocelot_adjust_link);
-static void ocelot_port_adjust_link(struct net_device *dev)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- ocelot_adjust_link(ocelot, port, dev->phydev);
-}
-
void ocelot_port_enable(struct ocelot *ocelot, int port,
struct phy_device *phy)
{
@@ -514,85 +404,15 @@ void ocelot_port_enable(struct ocelot *ocelot, int port,
}
EXPORT_SYMBOL(ocelot_port_enable);
-static int ocelot_port_open(struct net_device *dev)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot_port *ocelot_port = &priv->port;
- struct ocelot *ocelot = ocelot_port->ocelot;
- int port = priv->chip_port;
- int err;
-
- if (priv->serdes) {
- err = phy_set_mode_ext(priv->serdes, PHY_MODE_ETHERNET,
- ocelot_port->phy_mode);
- if (err) {
- netdev_err(dev, "Could not set mode of SerDes\n");
- return err;
- }
- }
-
- err = phy_connect_direct(dev, priv->phy, &ocelot_port_adjust_link,
- ocelot_port->phy_mode);
- if (err) {
- netdev_err(dev, "Could not attach to PHY\n");
- return err;
- }
-
- dev->phydev = priv->phy;
-
- phy_attached_info(priv->phy);
- phy_start(priv->phy);
-
- ocelot_port_enable(ocelot, port, priv->phy);
-
- return 0;
-}
-
void ocelot_port_disable(struct ocelot *ocelot, int port)
{
struct ocelot_port *ocelot_port = ocelot->ports[port];
ocelot_port_writel(ocelot_port, 0, DEV_MAC_ENA_CFG);
- ocelot_rmw_rix(ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA,
- QSYS_SWITCH_PORT_MODE, port);
+ ocelot_fields_write(ocelot, port, QSYS_SWITCH_PORT_MODE_PORT_ENA, 0);
}
EXPORT_SYMBOL(ocelot_port_disable);
-static int ocelot_port_stop(struct net_device *dev)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- phy_disconnect(priv->phy);
-
- dev->phydev = NULL;
-
- ocelot_port_disable(ocelot, port);
-
- return 0;
-}
-
-/* Generate the IFH for frame injection
- *
- * The IFH is a 128bit-value
- * bit 127: bypass the analyzer processing
- * bit 56-67: destination mask
- * bit 28-29: pop_cnt: 3 disables all rewriting of the frame
- * bit 20-27: cpu extraction queue mask
- * bit 16: tag type 0: C-tag, 1: S-tag
- * bit 0-11: VID
- */
-static int ocelot_gen_ifh(u32 *ifh, struct frame_info *info)
-{
- ifh[0] = IFH_INJ_BYPASS | ((0x1ff & info->rew_op) << 21);
- ifh[1] = (0xf00 & info->port) >> 8;
- ifh[2] = (0xff & info->port) << 24;
- ifh[3] = (info->tag_type << 16) | info->vid;
-
- return 0;
-}
-
int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
struct sk_buff *skb)
{
@@ -611,77 +431,6 @@ int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
}
EXPORT_SYMBOL(ocelot_port_add_txtstamp_skb);
-static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct skb_shared_info *shinfo = skb_shinfo(skb);
- struct ocelot_port *ocelot_port = &priv->port;
- struct ocelot *ocelot = ocelot_port->ocelot;
- u32 val, ifh[OCELOT_TAG_LEN / 4];
- struct frame_info info = {};
- u8 grp = 0; /* Send everything on CPU group 0 */
- unsigned int i, count, last;
- int port = priv->chip_port;
-
- val = ocelot_read(ocelot, QS_INJ_STATUS);
- if (!(val & QS_INJ_STATUS_FIFO_RDY(BIT(grp))) ||
- (val & QS_INJ_STATUS_WMARK_REACHED(BIT(grp))))
- return NETDEV_TX_BUSY;
-
- ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
- QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp);
-
- info.port = BIT(port);
- info.tag_type = IFH_TAG_TYPE_C;
- info.vid = skb_vlan_tag_get(skb);
-
- /* Check if timestamping is needed */
- if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP) {
- info.rew_op = ocelot_port->ptp_cmd;
- if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP)
- info.rew_op |= (ocelot_port->ts_id % 4) << 3;
- }
-
- ocelot_gen_ifh(ifh, &info);
-
- for (i = 0; i < OCELOT_TAG_LEN / 4; i++)
- ocelot_write_rix(ocelot, (__force u32)cpu_to_be32(ifh[i]),
- QS_INJ_WR, grp);
-
- count = (skb->len + 3) / 4;
- last = skb->len % 4;
- for (i = 0; i < count; i++) {
- ocelot_write_rix(ocelot, ((u32 *)skb->data)[i], QS_INJ_WR, grp);
- }
-
- /* Add padding */
- while (i < (OCELOT_BUFFER_CELL_SZ / 4)) {
- ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp);
- i++;
- }
-
- /* Indicate EOF and valid bytes in last word */
- ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
- QS_INJ_CTRL_VLD_BYTES(skb->len < OCELOT_BUFFER_CELL_SZ ? 0 : last) |
- QS_INJ_CTRL_EOF,
- QS_INJ_CTRL, grp);
-
- /* Add dummy CRC */
- ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp);
- skb_tx_timestamp(skb);
-
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
-
- if (!ocelot_port_add_txtstamp_skb(ocelot_port, skb)) {
- ocelot_port->ts_id++;
- return NETDEV_TX_OK;
- }
-
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
-}
-
static void ocelot_get_hwtimestamp(struct ocelot *ocelot,
struct timespec64 *ts)
{
@@ -767,117 +516,14 @@ void ocelot_get_txtstamp(struct ocelot *ocelot)
}
EXPORT_SYMBOL(ocelot_get_txtstamp);
-static int ocelot_mc_unsync(struct net_device *dev, const unsigned char *addr)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot_port *ocelot_port = &priv->port;
- struct ocelot *ocelot = ocelot_port->ocelot;
-
- return ocelot_mact_forget(ocelot, addr, ocelot_port->pvid);
-}
-
-static int ocelot_mc_sync(struct net_device *dev, const unsigned char *addr)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot_port *ocelot_port = &priv->port;
- struct ocelot *ocelot = ocelot_port->ocelot;
-
- return ocelot_mact_learn(ocelot, PGID_CPU, addr, ocelot_port->pvid,
- ENTRYTYPE_LOCKED);
-}
-
-static void ocelot_set_rx_mode(struct net_device *dev)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- u32 val;
- int i;
-
- /* This doesn't handle promiscuous mode because the bridge core is
- * setting IFF_PROMISC on all slave interfaces and all frames would be
- * forwarded to the CPU port.
- */
- val = GENMASK(ocelot->num_phys_ports - 1, 0);
- for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++)
- ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i);
-
- __dev_mc_sync(dev, ocelot_mc_sync, ocelot_mc_unsync);
-}
-
-static int ocelot_port_get_phys_port_name(struct net_device *dev,
- char *buf, size_t len)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- int port = priv->chip_port;
- int ret;
-
- ret = snprintf(buf, len, "p%d", port);
- if (ret >= len)
- return -EINVAL;
-
- return 0;
-}
-
-static int ocelot_port_set_mac_address(struct net_device *dev, void *p)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot_port *ocelot_port = &priv->port;
- struct ocelot *ocelot = ocelot_port->ocelot;
- const struct sockaddr *addr = p;
-
- /* Learn the new net device MAC address in the mac table. */
- ocelot_mact_learn(ocelot, PGID_CPU, addr->sa_data, ocelot_port->pvid,
- ENTRYTYPE_LOCKED);
- /* Then forget the previous one. */
- ocelot_mact_forget(ocelot, dev->dev_addr, ocelot_port->pvid);
-
- ether_addr_copy(dev->dev_addr, addr->sa_data);
- return 0;
-}
-
-static void ocelot_get_stats64(struct net_device *dev,
- struct rtnl_link_stats64 *stats)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- /* Configure the port to read the stats from */
- ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port),
- SYS_STAT_CFG);
-
- /* Get Rx stats */
- stats->rx_bytes = ocelot_read(ocelot, SYS_COUNT_RX_OCTETS);
- stats->rx_packets = ocelot_read(ocelot, SYS_COUNT_RX_SHORTS) +
- ocelot_read(ocelot, SYS_COUNT_RX_FRAGMENTS) +
- ocelot_read(ocelot, SYS_COUNT_RX_JABBERS) +
- ocelot_read(ocelot, SYS_COUNT_RX_LONGS) +
- ocelot_read(ocelot, SYS_COUNT_RX_64) +
- ocelot_read(ocelot, SYS_COUNT_RX_65_127) +
- ocelot_read(ocelot, SYS_COUNT_RX_128_255) +
- ocelot_read(ocelot, SYS_COUNT_RX_256_1023) +
- ocelot_read(ocelot, SYS_COUNT_RX_1024_1526) +
- ocelot_read(ocelot, SYS_COUNT_RX_1527_MAX);
- stats->multicast = ocelot_read(ocelot, SYS_COUNT_RX_MULTICAST);
- stats->rx_dropped = dev->stats.rx_dropped;
-
- /* Get Tx stats */
- stats->tx_bytes = ocelot_read(ocelot, SYS_COUNT_TX_OCTETS);
- stats->tx_packets = ocelot_read(ocelot, SYS_COUNT_TX_64) +
- ocelot_read(ocelot, SYS_COUNT_TX_65_127) +
- ocelot_read(ocelot, SYS_COUNT_TX_128_511) +
- ocelot_read(ocelot, SYS_COUNT_TX_512_1023) +
- ocelot_read(ocelot, SYS_COUNT_TX_1024_1526) +
- ocelot_read(ocelot, SYS_COUNT_TX_1527_MAX);
- stats->tx_dropped = ocelot_read(ocelot, SYS_COUNT_TX_DROPS) +
- ocelot_read(ocelot, SYS_COUNT_TX_AGING);
- stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION);
-}
-
int ocelot_fdb_add(struct ocelot *ocelot, int port,
const unsigned char *addr, u16 vid)
{
struct ocelot_port *ocelot_port = ocelot->ports[port];
+ int pgid = port;
+
+ if (port == ocelot->npi)
+ pgid = PGID_CPU;
if (!vid) {
if (!ocelot_port->vlan_aware)
@@ -893,23 +539,10 @@ int ocelot_fdb_add(struct ocelot *ocelot, int port,
return -EINVAL;
}
- return ocelot_mact_learn(ocelot, port, addr, vid, ENTRYTYPE_LOCKED);
+ return ocelot_mact_learn(ocelot, pgid, addr, vid, ENTRYTYPE_LOCKED);
}
EXPORT_SYMBOL(ocelot_fdb_add);
-static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
- struct net_device *dev,
- const unsigned char *addr,
- u16 vid, u16 flags,
- struct netlink_ext_ack *extack)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- return ocelot_fdb_add(ocelot, port, addr, vid);
-}
-
int ocelot_fdb_del(struct ocelot *ocelot, int port,
const unsigned char *addr, u16 vid)
{
@@ -917,26 +550,8 @@ int ocelot_fdb_del(struct ocelot *ocelot, int port,
}
EXPORT_SYMBOL(ocelot_fdb_del);
-static int ocelot_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
- struct net_device *dev,
- const unsigned char *addr, u16 vid)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- return ocelot_fdb_del(ocelot, port, addr, vid);
-}
-
-struct ocelot_dump_ctx {
- struct net_device *dev;
- struct sk_buff *skb;
- struct netlink_callback *cb;
- int idx;
-};
-
-static int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid,
- bool is_static, void *data)
+int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid,
+ bool is_static, void *data)
{
struct ocelot_dump_ctx *dump = data;
u32 portid = NETLINK_CB(dump->cb->skb).portid;
@@ -977,6 +592,7 @@ nla_put_failure:
nlmsg_cancel(dump->skb, nlh);
return -EMSGSIZE;
}
+EXPORT_SYMBOL(ocelot_port_fdb_do_dump);
static int ocelot_mact_read(struct ocelot *ocelot, int port, int row, int col,
struct ocelot_mact_entry *entry)
@@ -1058,74 +674,6 @@ int ocelot_fdb_dump(struct ocelot *ocelot, int port,
}
EXPORT_SYMBOL(ocelot_fdb_dump);
-static int ocelot_port_fdb_dump(struct sk_buff *skb,
- struct netlink_callback *cb,
- struct net_device *dev,
- struct net_device *filter_dev, int *idx)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- struct ocelot_dump_ctx dump = {
- .dev = dev,
- .skb = skb,
- .cb = cb,
- .idx = *idx,
- };
- int port = priv->chip_port;
- int ret;
-
- ret = ocelot_fdb_dump(ocelot, port, ocelot_port_fdb_do_dump, &dump);
-
- *idx = dump.idx;
-
- return ret;
-}
-
-static int ocelot_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
- u16 vid)
-{
- return ocelot_vlan_vid_add(dev, vid, false, false);
-}
-
-static int ocelot_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
- u16 vid)
-{
- return ocelot_vlan_vid_del(dev, vid);
-}
-
-static int ocelot_set_features(struct net_device *dev,
- netdev_features_t features)
-{
- netdev_features_t changed = dev->features ^ features;
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
- priv->tc.offload_cnt) {
- netdev_err(dev,
- "Cannot disable HW TC offload while offloads active\n");
- return -EBUSY;
- }
-
- if (changed & NETIF_F_HW_VLAN_CTAG_FILTER)
- ocelot_vlan_mode(ocelot, port, features);
-
- return 0;
-}
-
-static int ocelot_get_port_parent_id(struct net_device *dev,
- struct netdev_phys_item_id *ppid)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
-
- ppid->id_len = sizeof(ocelot->base_mac);
- memcpy(&ppid->id, &ocelot->base_mac, ppid->id_len);
-
- return 0;
-}
-
int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr)
{
return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config,
@@ -1198,46 +746,6 @@ int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
}
EXPORT_SYMBOL(ocelot_hwstamp_set);
-static int ocelot_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- /* If the attached PHY device isn't capable of timestamping operations,
- * use our own (when possible).
- */
- if (!phy_has_hwtstamp(dev->phydev) && ocelot->ptp) {
- switch (cmd) {
- case SIOCSHWTSTAMP:
- return ocelot_hwstamp_set(ocelot, port, ifr);
- case SIOCGHWTSTAMP:
- return ocelot_hwstamp_get(ocelot, port, ifr);
- }
- }
-
- return phy_mii_ioctl(dev->phydev, ifr, cmd);
-}
-
-static const struct net_device_ops ocelot_port_netdev_ops = {
- .ndo_open = ocelot_port_open,
- .ndo_stop = ocelot_port_stop,
- .ndo_start_xmit = ocelot_port_xmit,
- .ndo_set_rx_mode = ocelot_set_rx_mode,
- .ndo_get_phys_port_name = ocelot_port_get_phys_port_name,
- .ndo_set_mac_address = ocelot_port_set_mac_address,
- .ndo_get_stats64 = ocelot_get_stats64,
- .ndo_fdb_add = ocelot_port_fdb_add,
- .ndo_fdb_del = ocelot_port_fdb_del,
- .ndo_fdb_dump = ocelot_port_fdb_dump,
- .ndo_vlan_rx_add_vid = ocelot_vlan_rx_add_vid,
- .ndo_vlan_rx_kill_vid = ocelot_vlan_rx_kill_vid,
- .ndo_set_features = ocelot_set_features,
- .ndo_get_port_parent_id = ocelot_get_port_parent_id,
- .ndo_setup_tc = ocelot_setup_tc,
- .ndo_do_ioctl = ocelot_ioctl,
-};
-
void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data)
{
int i;
@@ -1251,16 +759,6 @@ void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data)
}
EXPORT_SYMBOL(ocelot_get_strings);
-static void ocelot_port_get_strings(struct net_device *netdev, u32 sset,
- u8 *data)
-{
- struct ocelot_port_private *priv = netdev_priv(netdev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- ocelot_get_strings(ocelot, port, sset, data);
-}
-
static void ocelot_update_stats(struct ocelot *ocelot)
{
int i, j;
@@ -1314,17 +812,6 @@ void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)
}
EXPORT_SYMBOL(ocelot_get_ethtool_stats);
-static void ocelot_port_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats,
- u64 *data)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- ocelot_get_ethtool_stats(ocelot, port, data);
-}
-
int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset)
{
if (sset != ETH_SS_STATS)
@@ -1334,15 +821,6 @@ int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset)
}
EXPORT_SYMBOL(ocelot_get_sset_count);
-static int ocelot_port_get_sset_count(struct net_device *dev, int sset)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- return ocelot_get_sset_count(ocelot, port, sset);
-}
-
int ocelot_get_ts_info(struct ocelot *ocelot, int port,
struct ethtool_ts_info *info)
{
@@ -1368,28 +846,6 @@ int ocelot_get_ts_info(struct ocelot *ocelot, int port,
}
EXPORT_SYMBOL(ocelot_get_ts_info);
-static int ocelot_port_get_ts_info(struct net_device *dev,
- struct ethtool_ts_info *info)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- if (!ocelot->ptp)
- return ethtool_op_get_ts_info(dev, info);
-
- return ocelot_get_ts_info(ocelot, port, info);
-}
-
-static const struct ethtool_ops ocelot_ethtool_ops = {
- .get_strings = ocelot_port_get_strings,
- .get_ethtool_stats = ocelot_port_get_ethtool_stats,
- .get_sset_count = ocelot_port_get_sset_count,
- .get_link_ksettings = phy_ethtool_get_link_ksettings,
- .set_link_ksettings = phy_ethtool_set_link_ksettings,
- .get_ts_info = ocelot_port_get_ts_info,
-};
-
void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state)
{
u32 port_cfg;
@@ -1445,16 +901,6 @@ void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state)
}
EXPORT_SYMBOL(ocelot_bridge_stp_state_set);
-static void ocelot_port_attr_stp_state_set(struct ocelot *ocelot, int port,
- struct switchdev_trans *trans,
- u8 state)
-{
- if (switchdev_trans_ph_prepare(trans))
- return;
-
- ocelot_bridge_stp_state_set(ocelot, port, state);
-}
-
void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs)
{
unsigned int age_period = ANA_AUTOAGE_AGE_PERIOD(msecs / 2000);
@@ -1469,165 +915,142 @@ void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs)
}
EXPORT_SYMBOL(ocelot_set_ageing_time);
-static void ocelot_port_attr_ageing_set(struct ocelot *ocelot, int port,
- unsigned long ageing_clock_t)
-{
- unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
- u32 ageing_time = jiffies_to_msecs(ageing_jiffies);
-
- ocelot_set_ageing_time(ocelot, ageing_time);
-}
-
-static void ocelot_port_attr_mc_set(struct ocelot *ocelot, int port, bool mc)
+static struct ocelot_multicast *ocelot_multicast_get(struct ocelot *ocelot,
+ const unsigned char *addr,
+ u16 vid)
{
- u32 cpu_fwd_mcast = ANA_PORT_CPU_FWD_CFG_CPU_IGMP_REDIR_ENA |
- ANA_PORT_CPU_FWD_CFG_CPU_MLD_REDIR_ENA |
- ANA_PORT_CPU_FWD_CFG_CPU_IPMC_CTRL_COPY_ENA;
- u32 val = 0;
+ struct ocelot_multicast *mc;
- if (mc)
- val = cpu_fwd_mcast;
+ list_for_each_entry(mc, &ocelot->multicast, list) {
+ if (ether_addr_equal(mc->addr, addr) && mc->vid == vid)
+ return mc;
+ }
- ocelot_rmw_gix(ocelot, val, cpu_fwd_mcast,
- ANA_PORT_CPU_FWD_CFG, port);
+ return NULL;
}
-static int ocelot_port_attr_set(struct net_device *dev,
- const struct switchdev_attr *attr,
- struct switchdev_trans *trans)
+static enum macaccess_entry_type ocelot_classify_mdb(const unsigned char *addr)
{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
- int err = 0;
-
- switch (attr->id) {
- case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
- ocelot_port_attr_stp_state_set(ocelot, port, trans,
- attr->u.stp_state);
- break;
- case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
- ocelot_port_attr_ageing_set(ocelot, port, attr->u.ageing_time);
- break;
- case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
- ocelot_port_vlan_filtering(ocelot, port,
- attr->u.vlan_filtering);
- break;
- case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
- ocelot_port_attr_mc_set(ocelot, port, !attr->u.mc_disabled);
- break;
- default:
- err = -EOPNOTSUPP;
- break;
- }
-
- return err;
+ if (addr[0] == 0x01 && addr[1] == 0x00 && addr[2] == 0x5e)
+ return ENTRYTYPE_MACv4;
+ if (addr[0] == 0x33 && addr[1] == 0x33)
+ return ENTRYTYPE_MACv6;
+ return ENTRYTYPE_NORMAL;
}
-static int ocelot_port_obj_add_vlan(struct net_device *dev,
- const struct switchdev_obj_port_vlan *vlan,
- struct switchdev_trans *trans)
+static int ocelot_mdb_get_pgid(struct ocelot *ocelot,
+ enum macaccess_entry_type entry_type)
{
- int ret;
- u16 vid;
+ int pgid;
- for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
- ret = ocelot_vlan_vid_add(dev, vid,
- vlan->flags & BRIDGE_VLAN_INFO_PVID,
- vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED);
- if (ret)
- return ret;
- }
-
- return 0;
-}
+ /* According to VSC7514 datasheet 3.9.1.5 IPv4 Multicast Entries and
+ * 3.9.1.6 IPv6 Multicast Entries, "Instead of a lookup in the
+ * destination mask table (PGID), the destination set is programmed as
+ * part of the entry MAC address.", and the DEST_IDX is set to 0.
+ */
+ if (entry_type == ENTRYTYPE_MACv4 ||
+ entry_type == ENTRYTYPE_MACv6)
+ return 0;
-static int ocelot_port_vlan_del_vlan(struct net_device *dev,
- const struct switchdev_obj_port_vlan *vlan)
-{
- int ret;
- u16 vid;
+ for_each_nonreserved_multicast_dest_pgid(ocelot, pgid) {
+ struct ocelot_multicast *mc;
+ bool used = false;
- for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
- ret = ocelot_vlan_vid_del(dev, vid);
+ list_for_each_entry(mc, &ocelot->multicast, list) {
+ if (mc->pgid == pgid) {
+ used = true;
+ break;
+ }
+ }
- if (ret)
- return ret;
+ if (!used)
+ return pgid;
}
- return 0;
+ return -1;
}
-static struct ocelot_multicast *ocelot_multicast_get(struct ocelot *ocelot,
- const unsigned char *addr,
- u16 vid)
+static void ocelot_encode_ports_to_mdb(unsigned char *addr,
+ struct ocelot_multicast *mc,
+ enum macaccess_entry_type entry_type)
{
- struct ocelot_multicast *mc;
+ memcpy(addr, mc->addr, ETH_ALEN);
- list_for_each_entry(mc, &ocelot->multicast, list) {
- if (ether_addr_equal(mc->addr, addr) && mc->vid == vid)
- return mc;
+ if (entry_type == ENTRYTYPE_MACv4) {
+ addr[0] = 0;
+ addr[1] = mc->ports >> 8;
+ addr[2] = mc->ports & 0xff;
+ } else if (entry_type == ENTRYTYPE_MACv6) {
+ addr[0] = mc->ports >> 8;
+ addr[1] = mc->ports & 0xff;
}
-
- return NULL;
}
-static int ocelot_port_obj_add_mdb(struct net_device *dev,
- const struct switchdev_obj_port_mdb *mdb,
- struct switchdev_trans *trans)
+int ocelot_port_mdb_add(struct ocelot *ocelot, int port,
+ const struct switchdev_obj_port_mdb *mdb)
{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot_port *ocelot_port = &priv->port;
- struct ocelot *ocelot = ocelot_port->ocelot;
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ enum macaccess_entry_type entry_type;
unsigned char addr[ETH_ALEN];
struct ocelot_multicast *mc;
- int port = priv->chip_port;
u16 vid = mdb->vid;
bool new = false;
+ if (port == ocelot->npi)
+ port = ocelot->num_phys_ports;
+
if (!vid)
vid = ocelot_port->pvid;
+ entry_type = ocelot_classify_mdb(mdb->addr);
+
mc = ocelot_multicast_get(ocelot, mdb->addr, vid);
if (!mc) {
+ int pgid = ocelot_mdb_get_pgid(ocelot, entry_type);
+
+ if (pgid < 0) {
+ dev_err(ocelot->dev,
+ "No more PGIDs available for mdb %pM vid %d\n",
+ mdb->addr, vid);
+ return -ENOSPC;
+ }
+
mc = devm_kzalloc(ocelot->dev, sizeof(*mc), GFP_KERNEL);
if (!mc)
return -ENOMEM;
memcpy(mc->addr, mdb->addr, ETH_ALEN);
mc->vid = vid;
+ mc->pgid = pgid;
list_add_tail(&mc->list, &ocelot->multicast);
new = true;
}
- memcpy(addr, mc->addr, ETH_ALEN);
- addr[0] = 0;
-
if (!new) {
- addr[2] = mc->ports << 0;
- addr[1] = mc->ports << 8;
+ ocelot_encode_ports_to_mdb(addr, mc, entry_type);
ocelot_mact_forget(ocelot, addr, vid);
}
mc->ports |= BIT(port);
- addr[2] = mc->ports << 0;
- addr[1] = mc->ports << 8;
+ ocelot_encode_ports_to_mdb(addr, mc, entry_type);
- return ocelot_mact_learn(ocelot, 0, addr, vid, ENTRYTYPE_MACv4);
+ return ocelot_mact_learn(ocelot, mc->pgid, addr, vid, entry_type);
}
+EXPORT_SYMBOL(ocelot_port_mdb_add);
-static int ocelot_port_obj_del_mdb(struct net_device *dev,
- const struct switchdev_obj_port_mdb *mdb)
+int ocelot_port_mdb_del(struct ocelot *ocelot, int port,
+ const struct switchdev_obj_port_mdb *mdb)
{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot_port *ocelot_port = &priv->port;
- struct ocelot *ocelot = ocelot_port->ocelot;
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ enum macaccess_entry_type entry_type;
unsigned char addr[ETH_ALEN];
struct ocelot_multicast *mc;
- int port = priv->chip_port;
u16 vid = mdb->vid;
+ if (port == ocelot->npi)
+ port = ocelot->num_phys_ports;
+
if (!vid)
vid = ocelot_port->pvid;
@@ -1635,10 +1058,9 @@ static int ocelot_port_obj_del_mdb(struct net_device *dev,
if (!mc)
return -ENOENT;
- memcpy(addr, mc->addr, ETH_ALEN);
- addr[2] = mc->ports << 0;
- addr[1] = mc->ports << 8;
- addr[0] = 0;
+ entry_type = ocelot_classify_mdb(mdb->addr);
+
+ ocelot_encode_ports_to_mdb(addr, mc, entry_type);
ocelot_mact_forget(ocelot, addr, vid);
mc->ports &= ~BIT(port);
@@ -1648,55 +1070,11 @@ static int ocelot_port_obj_del_mdb(struct net_device *dev,
return 0;
}
- addr[2] = mc->ports << 0;
- addr[1] = mc->ports << 8;
-
- return ocelot_mact_learn(ocelot, 0, addr, vid, ENTRYTYPE_MACv4);
-}
-
-static int ocelot_port_obj_add(struct net_device *dev,
- const struct switchdev_obj *obj,
- struct switchdev_trans *trans,
- struct netlink_ext_ack *extack)
-{
- int ret = 0;
-
- switch (obj->id) {
- case SWITCHDEV_OBJ_ID_PORT_VLAN:
- ret = ocelot_port_obj_add_vlan(dev,
- SWITCHDEV_OBJ_PORT_VLAN(obj),
- trans);
- break;
- case SWITCHDEV_OBJ_ID_PORT_MDB:
- ret = ocelot_port_obj_add_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj),
- trans);
- break;
- default:
- return -EOPNOTSUPP;
- }
+ ocelot_encode_ports_to_mdb(addr, mc, entry_type);
- return ret;
-}
-
-static int ocelot_port_obj_del(struct net_device *dev,
- const struct switchdev_obj *obj)
-{
- int ret = 0;
-
- switch (obj->id) {
- case SWITCHDEV_OBJ_ID_PORT_VLAN:
- ret = ocelot_port_vlan_del_vlan(dev,
- SWITCHDEV_OBJ_PORT_VLAN(obj));
- break;
- case SWITCHDEV_OBJ_ID_PORT_MDB:
- ret = ocelot_port_obj_del_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj));
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- return ret;
+ return ocelot_mact_learn(ocelot, mc->pgid, addr, vid, entry_type);
}
+EXPORT_SYMBOL(ocelot_port_mdb_del);
int ocelot_port_bridge_join(struct ocelot *ocelot, int port,
struct net_device *bridge)
@@ -1735,10 +1113,10 @@ static void ocelot_set_aggr_pgids(struct ocelot *ocelot)
int i, port, lag;
/* Reset destination and aggregation PGIDS */
- for (port = 0; port < ocelot->num_phys_ports; port++)
+ for_each_unicast_dest_pgid(ocelot, port)
ocelot_write_rix(ocelot, BIT(port), ANA_PGID_PGID, port);
- for (i = PGID_AGGR; i < PGID_SRC; i++)
+ for_each_aggr_pgid(ocelot, i)
ocelot_write_rix(ocelot, GENMASK(ocelot->num_phys_ports - 1, 0),
ANA_PGID_PGID, i);
@@ -1760,7 +1138,7 @@ static void ocelot_set_aggr_pgids(struct ocelot *ocelot)
aggr_count++;
}
- for (i = PGID_AGGR; i < PGID_SRC; i++) {
+ for_each_aggr_pgid(ocelot, i) {
u32 ac;
ac = ocelot_read_rix(ocelot, ANA_PGID_PGID, i);
@@ -1788,8 +1166,8 @@ static void ocelot_setup_lag(struct ocelot *ocelot, int lag)
}
}
-static int ocelot_port_lag_join(struct ocelot *ocelot, int port,
- struct net_device *bond)
+int ocelot_port_lag_join(struct ocelot *ocelot, int port,
+ struct net_device *bond)
{
struct net_device *ndev;
u32 bond_mask = 0;
@@ -1826,9 +1204,10 @@ static int ocelot_port_lag_join(struct ocelot *ocelot, int port,
return 0;
}
+EXPORT_SYMBOL(ocelot_port_lag_join);
-static void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
- struct net_device *bond)
+void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
+ struct net_device *bond)
{
u32 port_cfg;
int i;
@@ -1856,151 +1235,7 @@ static void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
ocelot_set_aggr_pgids(ocelot);
}
-
-/* Checks if the net_device instance given to us originate from our driver. */
-static bool ocelot_netdevice_dev_check(const struct net_device *dev)
-{
- return dev->netdev_ops == &ocelot_port_netdev_ops;
-}
-
-static int ocelot_netdevice_port_event(struct net_device *dev,
- unsigned long event,
- struct netdev_notifier_changeupper_info *info)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
- struct ocelot_port *ocelot_port = &priv->port;
- struct ocelot *ocelot = ocelot_port->ocelot;
- int port = priv->chip_port;
- int err = 0;
-
- switch (event) {
- case NETDEV_CHANGEUPPER:
- if (netif_is_bridge_master(info->upper_dev)) {
- if (info->linking) {
- err = ocelot_port_bridge_join(ocelot, port,
- info->upper_dev);
- } else {
- err = ocelot_port_bridge_leave(ocelot, port,
- info->upper_dev);
- }
- }
- if (netif_is_lag_master(info->upper_dev)) {
- if (info->linking)
- err = ocelot_port_lag_join(ocelot, port,
- info->upper_dev);
- else
- ocelot_port_lag_leave(ocelot, port,
- info->upper_dev);
- }
- break;
- default:
- break;
- }
-
- return err;
-}
-
-static int ocelot_netdevice_event(struct notifier_block *unused,
- unsigned long event, void *ptr)
-{
- struct netdev_notifier_changeupper_info *info = ptr;
- struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- int ret = 0;
-
- if (!ocelot_netdevice_dev_check(dev))
- return 0;
-
- if (event == NETDEV_PRECHANGEUPPER &&
- netif_is_lag_master(info->upper_dev)) {
- struct netdev_lag_upper_info *lag_upper_info = info->upper_info;
- struct netlink_ext_ack *extack;
-
- if (lag_upper_info &&
- lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
- extack = netdev_notifier_info_to_extack(&info->info);
- NL_SET_ERR_MSG_MOD(extack, "LAG device using unsupported Tx type");
-
- ret = -EINVAL;
- goto notify;
- }
- }
-
- if (netif_is_lag_master(dev)) {
- struct net_device *slave;
- struct list_head *iter;
-
- netdev_for_each_lower_dev(dev, slave, iter) {
- ret = ocelot_netdevice_port_event(slave, event, info);
- if (ret)
- goto notify;
- }
- } else {
- ret = ocelot_netdevice_port_event(dev, event, info);
- }
-
-notify:
- return notifier_from_errno(ret);
-}
-
-struct notifier_block ocelot_netdevice_nb __read_mostly = {
- .notifier_call = ocelot_netdevice_event,
-};
-EXPORT_SYMBOL(ocelot_netdevice_nb);
-
-static int ocelot_switchdev_event(struct notifier_block *unused,
- unsigned long event, void *ptr)
-{
- struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
- int err;
-
- switch (event) {
- case SWITCHDEV_PORT_ATTR_SET:
- err = switchdev_handle_port_attr_set(dev, ptr,
- ocelot_netdevice_dev_check,
- ocelot_port_attr_set);
- return notifier_from_errno(err);
- }
-
- return NOTIFY_DONE;
-}
-
-struct notifier_block ocelot_switchdev_nb __read_mostly = {
- .notifier_call = ocelot_switchdev_event,
-};
-EXPORT_SYMBOL(ocelot_switchdev_nb);
-
-static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
- unsigned long event, void *ptr)
-{
- struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
- int err;
-
- switch (event) {
- /* Blocking events. */
- case SWITCHDEV_PORT_OBJ_ADD:
- err = switchdev_handle_port_obj_add(dev, ptr,
- ocelot_netdevice_dev_check,
- ocelot_port_obj_add);
- return notifier_from_errno(err);
- case SWITCHDEV_PORT_OBJ_DEL:
- err = switchdev_handle_port_obj_del(dev, ptr,
- ocelot_netdevice_dev_check,
- ocelot_port_obj_del);
- return notifier_from_errno(err);
- case SWITCHDEV_PORT_ATTR_SET:
- err = switchdev_handle_port_attr_set(dev, ptr,
- ocelot_netdevice_dev_check,
- ocelot_port_attr_set);
- return notifier_from_errno(err);
- }
-
- return NOTIFY_DONE;
-}
-
-struct notifier_block ocelot_switchdev_blocking_nb __read_mostly = {
- .notifier_call = ocelot_switchdev_blocking_event,
-};
-EXPORT_SYMBOL(ocelot_switchdev_blocking_nb);
+EXPORT_SYMBOL(ocelot_port_lag_leave);
/* Configure the maximum SDU (L2 payload) on RX to the value specified in @sdu.
* The length of VLAN tags is accounted for automatically via DEV_MAC_TAGS_CFG.
@@ -2012,6 +1247,7 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
{
struct ocelot_port *ocelot_port = ocelot->ports[port];
int maxlen = sdu + ETH_HLEN + ETH_FCS_LEN;
+ int pause_start, pause_stop;
int atop_wm;
if (port == ocelot->npi) {
@@ -2025,20 +1261,20 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
ocelot_port_writel(ocelot_port, maxlen, DEV_MAC_MAXLEN_CFG);
- /* Set Pause WM hysteresis
- * 152 = 6 * maxlen / OCELOT_BUFFER_CELL_SZ
- * 101 = 4 * maxlen / OCELOT_BUFFER_CELL_SZ
- */
- ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA |
- SYS_PAUSE_CFG_PAUSE_STOP(101) |
- SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port);
+ /* Set Pause watermark hysteresis */
+ pause_start = 6 * maxlen / OCELOT_BUFFER_CELL_SZ;
+ pause_stop = 4 * maxlen / OCELOT_BUFFER_CELL_SZ;
+ ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_START,
+ pause_start);
+ ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_STOP,
+ pause_stop);
/* Tail dropping watermark */
atop_wm = (ocelot->shared_queue_sz - 9 * maxlen) /
OCELOT_BUFFER_CELL_SZ;
- ocelot_write_rix(ocelot, ocelot_wm_enc(9 * maxlen),
+ ocelot_write_rix(ocelot, ocelot->ops->wm_enc(9 * maxlen),
SYS_ATOP, port);
- ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
+ ocelot_write(ocelot, ocelot->ops->wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
}
EXPORT_SYMBOL(ocelot_port_set_maxlen);
@@ -2094,6 +1330,9 @@ void ocelot_init_port(struct ocelot *ocelot, int port)
ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_HIGH_CFG);
ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_LOW_CFG);
+ /* Enable transmission of pause frames */
+ ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, 1);
+
/* Drop frames with multicast source address */
ocelot_rmw_gix(ocelot, ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA,
ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA,
@@ -2109,52 +1348,6 @@ void ocelot_init_port(struct ocelot *ocelot, int port)
}
EXPORT_SYMBOL(ocelot_init_port);
-int ocelot_probe_port(struct ocelot *ocelot, u8 port,
- void __iomem *regs,
- struct phy_device *phy)
-{
- struct ocelot_port_private *priv;
- struct ocelot_port *ocelot_port;
- struct net_device *dev;
- int err;
-
- dev = alloc_etherdev(sizeof(struct ocelot_port_private));
- if (!dev)
- return -ENOMEM;
- SET_NETDEV_DEV(dev, ocelot->dev);
- priv = netdev_priv(dev);
- priv->dev = dev;
- priv->phy = phy;
- priv->chip_port = port;
- ocelot_port = &priv->port;
- ocelot_port->ocelot = ocelot;
- ocelot_port->regs = regs;
- ocelot->ports[port] = ocelot_port;
-
- dev->netdev_ops = &ocelot_port_netdev_ops;
- dev->ethtool_ops = &ocelot_ethtool_ops;
-
- dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS |
- NETIF_F_HW_TC;
- dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
-
- memcpy(dev->dev_addr, ocelot->base_mac, ETH_ALEN);
- dev->dev_addr[ETH_ALEN - 1] += port;
- ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, ocelot_port->pvid,
- ENTRYTYPE_LOCKED);
-
- ocelot_init_port(ocelot, port);
-
- err = register_netdev(dev);
- if (err) {
- dev_err(ocelot->dev, "register_netdev failed\n");
- free_netdev(dev);
- }
-
- return err;
-}
-EXPORT_SYMBOL(ocelot_probe_port);
-
/* Configure and enable the CPU port module, which is a set of queues.
* If @npi contains a valid port index, the CPU port module is connected
* to the Node Processor Interface (NPI). This is the mode through which
@@ -2188,27 +1381,25 @@ void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
QSYS_EXT_CPU_CFG);
/* Enable NPI port */
- ocelot_write_rix(ocelot,
- QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
- QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
- QSYS_SWITCH_PORT_MODE_PORT_ENA,
- QSYS_SWITCH_PORT_MODE, npi);
+ ocelot_fields_write(ocelot, npi,
+ QSYS_SWITCH_PORT_MODE_PORT_ENA, 1);
/* NPI port Injection/Extraction configuration */
- ocelot_write_rix(ocelot,
- SYS_PORT_MODE_INCL_XTR_HDR(extraction) |
- SYS_PORT_MODE_INCL_INJ_HDR(injection),
- SYS_PORT_MODE, npi);
+ ocelot_fields_write(ocelot, npi, SYS_PORT_MODE_INCL_XTR_HDR,
+ extraction);
+ ocelot_fields_write(ocelot, npi, SYS_PORT_MODE_INCL_INJ_HDR,
+ injection);
+
+ /* Disable transmission of pause frames */
+ ocelot_fields_write(ocelot, npi, SYS_PAUSE_CFG_PAUSE_ENA, 0);
}
/* Enable CPU port module */
- ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
- QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
- QSYS_SWITCH_PORT_MODE_PORT_ENA,
- QSYS_SWITCH_PORT_MODE, cpu);
+ ocelot_fields_write(ocelot, cpu, QSYS_SWITCH_PORT_MODE_PORT_ENA, 1);
/* CPU port Injection/Extraction configuration */
- ocelot_write_rix(ocelot, SYS_PORT_MODE_INCL_XTR_HDR(extraction) |
- SYS_PORT_MODE_INCL_INJ_HDR(injection),
- SYS_PORT_MODE, cpu);
+ ocelot_fields_write(ocelot, cpu, SYS_PORT_MODE_INCL_XTR_HDR,
+ extraction);
+ ocelot_fields_write(ocelot, cpu, SYS_PORT_MODE_INCL_INJ_HDR,
+ injection);
/* Configure the CPU port to be VLAN aware */
ocelot_write_gix(ocelot, ANA_PORT_VLAN_CFG_VLAN_VID(0) |
@@ -2255,7 +1446,7 @@ int ocelot_init(struct ocelot *ocelot)
INIT_LIST_HEAD(&ocelot->multicast);
ocelot_mact_init(ocelot);
ocelot_vlan_init(ocelot);
- ocelot_ace_init(ocelot);
+ ocelot_vcap_init(ocelot);
for (port = 0; port < ocelot->num_phys_ports; port++) {
/* Clear all counters (5 groups) */
@@ -2311,7 +1502,7 @@ int ocelot_init(struct ocelot *ocelot)
}
/* Allow broadcast MAC frames. */
- for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++) {
+ for_each_nonreserved_multicast_dest_pgid(ocelot, i) {
u32 val = ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports - 1, 0));
ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i);
diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h
index f0a15aa187f2..dc29e05103a1 100644
--- a/drivers/net/ethernet/mscc/ocelot.h
+++ b/drivers/net/ethernet/mscc/ocelot.h
@@ -25,7 +25,6 @@
#include <soc/mscc/ocelot.h>
#include "ocelot_rew.h"
#include "ocelot_qs.h"
-#include "ocelot_tc.h"
#define OCELOT_BUFFER_CELL_SZ 60
@@ -47,6 +46,14 @@ struct ocelot_multicast {
unsigned char addr[ETH_ALEN];
u16 vid;
u16 ports;
+ int pgid;
+};
+
+struct ocelot_port_tc {
+ bool block_shared;
+ unsigned long offload_cnt;
+
+ unsigned long police_id;
};
struct ocelot_port_private {
@@ -60,15 +67,42 @@ struct ocelot_port_private {
struct ocelot_port_tc tc;
};
+struct ocelot_dump_ctx {
+ struct net_device *dev;
+ struct sk_buff *skb;
+ struct netlink_callback *cb;
+ int idx;
+};
+
+/* MAC table entry types.
+ * ENTRYTYPE_NORMAL is subject to aging.
+ * ENTRYTYPE_LOCKED is not subject to aging.
+ * ENTRYTYPE_MACv4 is not subject to aging. For IPv4 multicast.
+ * ENTRYTYPE_MACv6 is not subject to aging. For IPv6 multicast.
+ */
+enum macaccess_entry_type {
+ ENTRYTYPE_NORMAL = 0,
+ ENTRYTYPE_LOCKED,
+ ENTRYTYPE_MACv4,
+ ENTRYTYPE_MACv6,
+};
+
+int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid,
+ bool is_static, void *data);
+int ocelot_mact_learn(struct ocelot *ocelot, int port,
+ const unsigned char mac[ETH_ALEN],
+ unsigned int vid, enum macaccess_entry_type type);
+int ocelot_mact_forget(struct ocelot *ocelot,
+ const unsigned char mac[ETH_ALEN], unsigned int vid);
+int ocelot_port_lag_join(struct ocelot *ocelot, int port,
+ struct net_device *bond);
+void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
+ struct net_device *bond);
+
u32 ocelot_port_readl(struct ocelot_port *port, u32 reg);
void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg);
-#define ocelot_field_write(ocelot, reg, val) regmap_field_write((ocelot)->regfields[(reg)], (val))
-#define ocelot_field_read(ocelot, reg, val) regmap_field_read((ocelot)->regfields[(reg)], (val))
-
-int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops);
-int ocelot_probe_port(struct ocelot *ocelot, u8 port,
- void __iomem *regs,
+int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target,
struct phy_device *phy);
void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu,
@@ -79,7 +113,4 @@ extern struct notifier_block ocelot_netdevice_nb;
extern struct notifier_block ocelot_switchdev_nb;
extern struct notifier_block ocelot_switchdev_blocking_nb;
-#define ocelot_field_write(ocelot, reg, val) regmap_field_write((ocelot)->regfields[(reg)], (val))
-#define ocelot_field_read(ocelot, reg, val) regmap_field_read((ocelot)->regfields[(reg)], (val))
-
#endif
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
deleted file mode 100644
index 4a15d2ff8b70..000000000000
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ /dev/null
@@ -1,626 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Microsemi Ocelot Switch driver
- *
- * Copyright (c) 2017 Microsemi Corporation
- */
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/of_net.h>
-#include <linux/netdevice.h>
-#include <linux/of_mdio.h>
-#include <linux/of_platform.h>
-#include <linux/mfd/syscon.h>
-#include <linux/skbuff.h>
-#include <net/switchdev.h>
-
-#include <soc/mscc/ocelot_vcap.h>
-#include "ocelot.h"
-
-#define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
-#define VSC7514_VCAP_IS2_CNT 64
-#define VSC7514_VCAP_IS2_ENTRY_WIDTH 376
-#define VSC7514_VCAP_IS2_ACTION_WIDTH 99
-#define VSC7514_VCAP_PORT_CNT 11
-
-static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info)
-{
- u8 llen, wlen;
- u64 ifh[2];
-
- ifh[0] = be64_to_cpu(((__force __be64 *)_ifh)[0]);
- ifh[1] = be64_to_cpu(((__force __be64 *)_ifh)[1]);
-
- wlen = IFH_EXTRACT_BITFIELD64(ifh[0], 7, 8);
- llen = IFH_EXTRACT_BITFIELD64(ifh[0], 15, 6);
-
- info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80;
-
- info->timestamp = IFH_EXTRACT_BITFIELD64(ifh[0], 21, 32);
-
- info->port = IFH_EXTRACT_BITFIELD64(ifh[1], 43, 4);
-
- info->tag_type = IFH_EXTRACT_BITFIELD64(ifh[1], 16, 1);
- info->vid = IFH_EXTRACT_BITFIELD64(ifh[1], 0, 12);
-
- return 0;
-}
-
-static int ocelot_rx_frame_word(struct ocelot *ocelot, u8 grp, bool ifh,
- u32 *rval)
-{
- u32 val;
- u32 bytes_valid;
-
- val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
- if (val == XTR_NOT_READY) {
- if (ifh)
- return -EIO;
-
- do {
- val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
- } while (val == XTR_NOT_READY);
- }
-
- switch (val) {
- case XTR_ABORT:
- return -EIO;
- case XTR_EOF_0:
- case XTR_EOF_1:
- case XTR_EOF_2:
- case XTR_EOF_3:
- case XTR_PRUNED:
- bytes_valid = XTR_VALID_BYTES(val);
- val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
- if (val == XTR_ESCAPE)
- *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
- else
- *rval = val;
-
- return bytes_valid;
- case XTR_ESCAPE:
- *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
-
- return 4;
- default:
- *rval = val;
-
- return 4;
- }
-}
-
-static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
-{
- struct ocelot *ocelot = arg;
- int i = 0, grp = 0;
- int err = 0;
-
- if (!(ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)))
- return IRQ_NONE;
-
- do {
- struct skb_shared_hwtstamps *shhwtstamps;
- struct ocelot_port_private *priv;
- struct ocelot_port *ocelot_port;
- u64 tod_in_ns, full_ts_in_ns;
- struct frame_info info = {};
- struct net_device *dev;
- u32 ifh[4], val, *buf;
- struct timespec64 ts;
- int sz, len, buf_len;
- struct sk_buff *skb;
-
- for (i = 0; i < OCELOT_TAG_LEN / 4; i++) {
- err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]);
- if (err != 4)
- break;
- }
-
- if (err != 4)
- break;
-
- /* At this point the IFH was read correctly, so it is safe to
- * presume that there is no error. The err needs to be reset
- * otherwise a frame could come in CPU queue between the while
- * condition and the check for error later on. And in that case
- * the new frame is just removed and not processed.
- */
- err = 0;
-
- ocelot_parse_ifh(ifh, &info);
-
- ocelot_port = ocelot->ports[info.port];
- priv = container_of(ocelot_port, struct ocelot_port_private,
- port);
- dev = priv->dev;
-
- skb = netdev_alloc_skb(dev, info.len);
-
- if (unlikely(!skb)) {
- netdev_err(dev, "Unable to allocate sk_buff\n");
- err = -ENOMEM;
- break;
- }
- buf_len = info.len - ETH_FCS_LEN;
- buf = (u32 *)skb_put(skb, buf_len);
-
- len = 0;
- do {
- sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
- *buf++ = val;
- len += sz;
- } while (len < buf_len);
-
- /* Read the FCS */
- sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
- /* Update the statistics if part of the FCS was read before */
- len -= ETH_FCS_LEN - sz;
-
- if (unlikely(dev->features & NETIF_F_RXFCS)) {
- buf = (u32 *)skb_put(skb, ETH_FCS_LEN);
- *buf = val;
- }
-
- if (sz < 0) {
- err = sz;
- break;
- }
-
- if (ocelot->ptp) {
- ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
-
- tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec);
- if ((tod_in_ns & 0xffffffff) < info.timestamp)
- full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) |
- info.timestamp;
- else
- full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) |
- info.timestamp;
-
- shhwtstamps = skb_hwtstamps(skb);
- memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
- shhwtstamps->hwtstamp = full_ts_in_ns;
- }
-
- /* Everything we see on an interface that is in the HW bridge
- * has already been forwarded.
- */
- if (ocelot->bridge_mask & BIT(info.port))
- skb->offload_fwd_mark = 1;
-
- skb->protocol = eth_type_trans(skb, dev);
- if (!skb_defer_rx_timestamp(skb))
- netif_rx(skb);
- dev->stats.rx_bytes += len;
- dev->stats.rx_packets++;
- } while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp));
-
- if (err)
- while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp))
- ocelot_read_rix(ocelot, QS_XTR_RD, grp);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
-{
- struct ocelot *ocelot = arg;
-
- ocelot_get_txtstamp(ocelot);
-
- return IRQ_HANDLED;
-}
-
-static const struct of_device_id mscc_ocelot_match[] = {
- { .compatible = "mscc,vsc7514-switch" },
- { }
-};
-MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
-
-static int ocelot_reset(struct ocelot *ocelot)
-{
- int retries = 100;
- u32 val;
-
- regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
- regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
-
- do {
- msleep(1);
- regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
- &val);
- } while (val && --retries);
-
- if (!retries)
- return -ETIMEDOUT;
-
- regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
- regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
-
- return 0;
-}
-
-static const struct ocelot_ops ocelot_ops = {
- .reset = ocelot_reset,
-};
-
-static const struct vcap_field vsc7514_vcap_is2_keys[] = {
- /* Common: 46 bits */
- [VCAP_IS2_TYPE] = { 0, 4},
- [VCAP_IS2_HK_FIRST] = { 4, 1},
- [VCAP_IS2_HK_PAG] = { 5, 8},
- [VCAP_IS2_HK_IGR_PORT_MASK] = { 13, 12},
- [VCAP_IS2_HK_RSV2] = { 25, 1},
- [VCAP_IS2_HK_HOST_MATCH] = { 26, 1},
- [VCAP_IS2_HK_L2_MC] = { 27, 1},
- [VCAP_IS2_HK_L2_BC] = { 28, 1},
- [VCAP_IS2_HK_VLAN_TAGGED] = { 29, 1},
- [VCAP_IS2_HK_VID] = { 30, 12},
- [VCAP_IS2_HK_DEI] = { 42, 1},
- [VCAP_IS2_HK_PCP] = { 43, 3},
- /* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
- [VCAP_IS2_HK_L2_DMAC] = { 46, 48},
- [VCAP_IS2_HK_L2_SMAC] = { 94, 48},
- /* MAC_ETYPE (TYPE=000) */
- [VCAP_IS2_HK_MAC_ETYPE_ETYPE] = {142, 16},
- [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0] = {158, 16},
- [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1] = {174, 8},
- [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2] = {182, 3},
- /* MAC_LLC (TYPE=001) */
- [VCAP_IS2_HK_MAC_LLC_L2_LLC] = {142, 40},
- /* MAC_SNAP (TYPE=010) */
- [VCAP_IS2_HK_MAC_SNAP_L2_SNAP] = {142, 40},
- /* MAC_ARP (TYPE=011) */
- [VCAP_IS2_HK_MAC_ARP_SMAC] = { 46, 48},
- [VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK] = { 94, 1},
- [VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK] = { 95, 1},
- [VCAP_IS2_HK_MAC_ARP_LEN_OK] = { 96, 1},
- [VCAP_IS2_HK_MAC_ARP_TARGET_MATCH] = { 97, 1},
- [VCAP_IS2_HK_MAC_ARP_SENDER_MATCH] = { 98, 1},
- [VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN] = { 99, 1},
- [VCAP_IS2_HK_MAC_ARP_OPCODE] = {100, 2},
- [VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP] = {102, 32},
- [VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP] = {134, 32},
- [VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP] = {166, 1},
- /* IP4_TCP_UDP / IP4_OTHER common */
- [VCAP_IS2_HK_IP4] = { 46, 1},
- [VCAP_IS2_HK_L3_FRAGMENT] = { 47, 1},
- [VCAP_IS2_HK_L3_FRAG_OFS_GT0] = { 48, 1},
- [VCAP_IS2_HK_L3_OPTIONS] = { 49, 1},
- [VCAP_IS2_HK_IP4_L3_TTL_GT0] = { 50, 1},
- [VCAP_IS2_HK_L3_TOS] = { 51, 8},
- [VCAP_IS2_HK_L3_IP4_DIP] = { 59, 32},
- [VCAP_IS2_HK_L3_IP4_SIP] = { 91, 32},
- [VCAP_IS2_HK_DIP_EQ_SIP] = {123, 1},
- /* IP4_TCP_UDP (TYPE=100) */
- [VCAP_IS2_HK_TCP] = {124, 1},
- [VCAP_IS2_HK_L4_SPORT] = {125, 16},
- [VCAP_IS2_HK_L4_DPORT] = {141, 16},
- [VCAP_IS2_HK_L4_RNG] = {157, 8},
- [VCAP_IS2_HK_L4_SPORT_EQ_DPORT] = {165, 1},
- [VCAP_IS2_HK_L4_SEQUENCE_EQ0] = {166, 1},
- [VCAP_IS2_HK_L4_URG] = {167, 1},
- [VCAP_IS2_HK_L4_ACK] = {168, 1},
- [VCAP_IS2_HK_L4_PSH] = {169, 1},
- [VCAP_IS2_HK_L4_RST] = {170, 1},
- [VCAP_IS2_HK_L4_SYN] = {171, 1},
- [VCAP_IS2_HK_L4_FIN] = {172, 1},
- [VCAP_IS2_HK_L4_1588_DOM] = {173, 8},
- [VCAP_IS2_HK_L4_1588_VER] = {181, 4},
- /* IP4_OTHER (TYPE=101) */
- [VCAP_IS2_HK_IP4_L3_PROTO] = {124, 8},
- [VCAP_IS2_HK_L3_PAYLOAD] = {132, 56},
- /* IP6_STD (TYPE=110) */
- [VCAP_IS2_HK_IP6_L3_TTL_GT0] = { 46, 1},
- [VCAP_IS2_HK_L3_IP6_SIP] = { 47, 128},
- [VCAP_IS2_HK_IP6_L3_PROTO] = {175, 8},
- /* OAM (TYPE=111) */
- [VCAP_IS2_HK_OAM_MEL_FLAGS] = {142, 7},
- [VCAP_IS2_HK_OAM_VER] = {149, 5},
- [VCAP_IS2_HK_OAM_OPCODE] = {154, 8},
- [VCAP_IS2_HK_OAM_FLAGS] = {162, 8},
- [VCAP_IS2_HK_OAM_MEPID] = {170, 16},
- [VCAP_IS2_HK_OAM_CCM_CNTS_EQ0] = {186, 1},
- [VCAP_IS2_HK_OAM_IS_Y1731] = {187, 1},
-};
-
-static const struct vcap_field vsc7514_vcap_is2_actions[] = {
- [VCAP_IS2_ACT_HIT_ME_ONCE] = { 0, 1},
- [VCAP_IS2_ACT_CPU_COPY_ENA] = { 1, 1},
- [VCAP_IS2_ACT_CPU_QU_NUM] = { 2, 3},
- [VCAP_IS2_ACT_MASK_MODE] = { 5, 2},
- [VCAP_IS2_ACT_MIRROR_ENA] = { 7, 1},
- [VCAP_IS2_ACT_LRN_DIS] = { 8, 1},
- [VCAP_IS2_ACT_POLICE_ENA] = { 9, 1},
- [VCAP_IS2_ACT_POLICE_IDX] = { 10, 9},
- [VCAP_IS2_ACT_POLICE_VCAP_ONLY] = { 19, 1},
- [VCAP_IS2_ACT_PORT_MASK] = { 20, 11},
- [VCAP_IS2_ACT_REW_OP] = { 31, 9},
- [VCAP_IS2_ACT_SMAC_REPLACE_ENA] = { 40, 1},
- [VCAP_IS2_ACT_RSV] = { 41, 2},
- [VCAP_IS2_ACT_ACL_ID] = { 43, 6},
- [VCAP_IS2_ACT_HIT_CNT] = { 49, 32},
-};
-
-static const struct vcap_props vsc7514_vcap_props[] = {
- [VCAP_IS2] = {
- .tg_width = 2,
- .sw_count = 4,
- .entry_count = VSC7514_VCAP_IS2_CNT,
- .entry_width = VSC7514_VCAP_IS2_ENTRY_WIDTH,
- .action_count = VSC7514_VCAP_IS2_CNT +
- VSC7514_VCAP_PORT_CNT + 2,
- .action_width = 99,
- .action_type_width = 1,
- .action_table = {
- [IS2_ACTION_TYPE_NORMAL] = {
- .width = 49,
- .count = 2
- },
- [IS2_ACTION_TYPE_SMAC_SIP] = {
- .width = 6,
- .count = 4
- },
- },
- .counter_words = 4,
- .counter_width = 32,
- },
-};
-
-static struct ptp_clock_info ocelot_ptp_clock_info = {
- .owner = THIS_MODULE,
- .name = "ocelot ptp",
- .max_adj = 0x7fffffff,
- .n_alarm = 0,
- .n_ext_ts = 0,
- .n_per_out = OCELOT_PTP_PINS_NUM,
- .n_pins = OCELOT_PTP_PINS_NUM,
- .pps = 0,
- .gettime64 = ocelot_ptp_gettime64,
- .settime64 = ocelot_ptp_settime64,
- .adjtime = ocelot_ptp_adjtime,
- .adjfine = ocelot_ptp_adjfine,
- .verify = ocelot_ptp_verify,
- .enable = ocelot_ptp_enable,
-};
-
-static int mscc_ocelot_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct device_node *ports, *portnp;
- int err, irq_xtr, irq_ptp_rdy;
- struct ocelot *ocelot;
- struct regmap *hsio;
- unsigned int i;
-
- struct {
- enum ocelot_target id;
- char *name;
- u8 optional:1;
- } io_target[] = {
- { SYS, "sys" },
- { REW, "rew" },
- { QSYS, "qsys" },
- { ANA, "ana" },
- { QS, "qs" },
- { S2, "s2" },
- { PTP, "ptp", 1 },
- };
-
- if (!np && !pdev->dev.platform_data)
- return -ENODEV;
-
- ocelot = devm_kzalloc(&pdev->dev, sizeof(*ocelot), GFP_KERNEL);
- if (!ocelot)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, ocelot);
- ocelot->dev = &pdev->dev;
-
- for (i = 0; i < ARRAY_SIZE(io_target); i++) {
- struct regmap *target;
- struct resource *res;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- io_target[i].name);
-
- target = ocelot_regmap_init(ocelot, res);
- if (IS_ERR(target)) {
- if (io_target[i].optional) {
- ocelot->targets[io_target[i].id] = NULL;
- continue;
- }
- return PTR_ERR(target);
- }
-
- ocelot->targets[io_target[i].id] = target;
- }
-
- hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
- if (IS_ERR(hsio)) {
- dev_err(&pdev->dev, "missing hsio syscon\n");
- return PTR_ERR(hsio);
- }
-
- ocelot->targets[HSIO] = hsio;
-
- err = ocelot_chip_init(ocelot, &ocelot_ops);
- if (err)
- return err;
-
- irq_xtr = platform_get_irq_byname(pdev, "xtr");
- if (irq_xtr < 0)
- return -ENODEV;
-
- err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
- ocelot_xtr_irq_handler, IRQF_ONESHOT,
- "frame extraction", ocelot);
- if (err)
- return err;
-
- irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
- if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) {
- err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
- ocelot_ptp_rdy_irq_handler,
- IRQF_ONESHOT, "ptp ready",
- ocelot);
- if (err)
- return err;
-
- /* Both the PTP interrupt and the PTP bank are available */
- ocelot->ptp = 1;
- }
-
- ports = of_get_child_by_name(np, "ethernet-ports");
- if (!ports) {
- dev_err(&pdev->dev, "no ethernet-ports child node found\n");
- return -ENODEV;
- }
-
- ocelot->num_phys_ports = of_get_child_count(ports);
-
- ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
- sizeof(struct ocelot_port *), GFP_KERNEL);
-
- ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
- ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
- ocelot->vcap = vsc7514_vcap_props;
-
- ocelot_init(ocelot);
- if (ocelot->ptp) {
- err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info);
- if (err) {
- dev_err(ocelot->dev,
- "Timestamp initialization failed\n");
- ocelot->ptp = 0;
- }
- }
-
- /* No NPI port */
- ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
- OCELOT_TAG_PREFIX_NONE);
-
- for_each_available_child_of_node(ports, portnp) {
- struct ocelot_port_private *priv;
- struct ocelot_port *ocelot_port;
- struct device_node *phy_node;
- phy_interface_t phy_mode;
- struct phy_device *phy;
- struct resource *res;
- struct phy *serdes;
- void __iomem *regs;
- char res_name[8];
- u32 port;
-
- if (of_property_read_u32(portnp, "reg", &port))
- continue;
-
- snprintf(res_name, sizeof(res_name), "port%d", port);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- res_name);
- regs = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(regs))
- continue;
-
- phy_node = of_parse_phandle(portnp, "phy-handle", 0);
- if (!phy_node)
- continue;
-
- phy = of_phy_find_device(phy_node);
- of_node_put(phy_node);
- if (!phy)
- continue;
-
- err = ocelot_probe_port(ocelot, port, regs, phy);
- if (err) {
- of_node_put(portnp);
- goto out_put_ports;
- }
-
- ocelot_port = ocelot->ports[port];
- priv = container_of(ocelot_port, struct ocelot_port_private,
- port);
-
- of_get_phy_mode(portnp, &phy_mode);
-
- ocelot_port->phy_mode = phy_mode;
-
- switch (ocelot_port->phy_mode) {
- case PHY_INTERFACE_MODE_NA:
- continue;
- case PHY_INTERFACE_MODE_SGMII:
- break;
- case PHY_INTERFACE_MODE_QSGMII:
- /* Ensure clock signals and speed is set on all
- * QSGMII links
- */
- ocelot_port_writel(ocelot_port,
- DEV_CLOCK_CFG_LINK_SPEED
- (OCELOT_SPEED_1000),
- DEV_CLOCK_CFG);
- break;
- default:
- dev_err(ocelot->dev,
- "invalid phy mode for port%d, (Q)SGMII only\n",
- port);
- of_node_put(portnp);
- err = -EINVAL;
- goto out_put_ports;
- }
-
- serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
- if (IS_ERR(serdes)) {
- err = PTR_ERR(serdes);
- if (err == -EPROBE_DEFER)
- dev_dbg(ocelot->dev, "deferring probe\n");
- else
- dev_err(ocelot->dev,
- "missing SerDes phys for port%d\n",
- port);
-
- of_node_put(portnp);
- goto out_put_ports;
- }
-
- priv->serdes = serdes;
- }
-
- register_netdevice_notifier(&ocelot_netdevice_nb);
- register_switchdev_notifier(&ocelot_switchdev_nb);
- register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
-
- dev_info(&pdev->dev, "Ocelot switch probed\n");
-
-out_put_ports:
- of_node_put(ports);
- return err;
-}
-
-static int mscc_ocelot_remove(struct platform_device *pdev)
-{
- struct ocelot *ocelot = platform_get_drvdata(pdev);
-
- ocelot_deinit_timestamp(ocelot);
- ocelot_deinit(ocelot);
- unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
- unregister_switchdev_notifier(&ocelot_switchdev_nb);
- unregister_netdevice_notifier(&ocelot_netdevice_nb);
-
- return 0;
-}
-
-static struct platform_driver mscc_ocelot_driver = {
- .probe = mscc_ocelot_probe,
- .remove = mscc_ocelot_remove,
- .driver = {
- .name = "ocelot-switch",
- .of_match_table = mscc_ocelot_match,
- },
-};
-
-module_platform_driver(mscc_ocelot_driver);
-
-MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
-MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
-MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index 5ce172e22b43..ec1b6e2572ba 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -6,13 +6,12 @@
#include <net/pkt_cls.h>
#include <net/tc_act/tc_gact.h>
-#include "ocelot_ace.h"
+#include "ocelot_vcap.h"
static int ocelot_flower_parse_action(struct flow_cls_offload *f,
- struct ocelot_ace_rule *ace)
+ struct ocelot_vcap_filter *filter)
{
const struct flow_action_entry *a;
- s64 burst;
u64 rate;
int i;
@@ -26,17 +25,16 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f,
flow_action_for_each(i, a, &f->rule->action) {
switch (a->id) {
case FLOW_ACTION_DROP:
- ace->action = OCELOT_ACL_ACTION_DROP;
+ filter->action = OCELOT_VCAP_ACTION_DROP;
break;
case FLOW_ACTION_TRAP:
- ace->action = OCELOT_ACL_ACTION_TRAP;
+ filter->action = OCELOT_VCAP_ACTION_TRAP;
break;
case FLOW_ACTION_POLICE:
- ace->action = OCELOT_ACL_ACTION_POLICE;
+ filter->action = OCELOT_VCAP_ACTION_POLICE;
rate = a->police.rate_bytes_ps;
- ace->pol.rate = div_u64(rate, 1000) * 8;
- burst = rate * PSCHED_NS2TICKS(a->police.burst);
- ace->pol.burst = div_u64(burst, PSCHED_TICKS_PER_SEC);
+ filter->pol.rate = div_u64(rate, 1000) * 8;
+ filter->pol.burst = a->police.burst;
break;
default:
return -EOPNOTSUPP;
@@ -47,7 +45,7 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f,
}
static int ocelot_flower_parse(struct flow_cls_offload *f,
- struct ocelot_ace_rule *ace)
+ struct ocelot_vcap_filter *filter)
{
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
struct flow_dissector *dissector = rule->match.dissector;
@@ -88,14 +86,14 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
return -EOPNOTSUPP;
flow_rule_match_eth_addrs(rule, &match);
- ace->type = OCELOT_ACE_TYPE_ETYPE;
- ether_addr_copy(ace->frame.etype.dmac.value,
+ filter->key_type = OCELOT_VCAP_KEY_ETYPE;
+ ether_addr_copy(filter->key.etype.dmac.value,
match.key->dst);
- ether_addr_copy(ace->frame.etype.smac.value,
+ ether_addr_copy(filter->key.etype.smac.value,
match.key->src);
- ether_addr_copy(ace->frame.etype.dmac.mask,
+ ether_addr_copy(filter->key.etype.dmac.mask,
match.mask->dst);
- ether_addr_copy(ace->frame.etype.smac.mask,
+ ether_addr_copy(filter->key.etype.smac.mask,
match.mask->src);
goto finished_key_parsing;
}
@@ -105,18 +103,18 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
flow_rule_match_basic(rule, &match);
if (ntohs(match.key->n_proto) == ETH_P_IP) {
- ace->type = OCELOT_ACE_TYPE_IPV4;
- ace->frame.ipv4.proto.value[0] =
+ filter->key_type = OCELOT_VCAP_KEY_IPV4;
+ filter->key.ipv4.proto.value[0] =
match.key->ip_proto;
- ace->frame.ipv4.proto.mask[0] =
+ filter->key.ipv4.proto.mask[0] =
match.mask->ip_proto;
match_protocol = false;
}
if (ntohs(match.key->n_proto) == ETH_P_IPV6) {
- ace->type = OCELOT_ACE_TYPE_IPV6;
- ace->frame.ipv6.proto.value[0] =
+ filter->key_type = OCELOT_VCAP_KEY_IPV6;
+ filter->key.ipv6.proto.value[0] =
match.key->ip_proto;
- ace->frame.ipv6.proto.mask[0] =
+ filter->key.ipv6.proto.mask[0] =
match.mask->ip_proto;
match_protocol = false;
}
@@ -128,16 +126,16 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
u8 *tmp;
flow_rule_match_ipv4_addrs(rule, &match);
- tmp = &ace->frame.ipv4.sip.value.addr[0];
+ tmp = &filter->key.ipv4.sip.value.addr[0];
memcpy(tmp, &match.key->src, 4);
- tmp = &ace->frame.ipv4.sip.mask.addr[0];
+ tmp = &filter->key.ipv4.sip.mask.addr[0];
memcpy(tmp, &match.mask->src, 4);
- tmp = &ace->frame.ipv4.dip.value.addr[0];
+ tmp = &filter->key.ipv4.dip.value.addr[0];
memcpy(tmp, &match.key->dst, 4);
- tmp = &ace->frame.ipv4.dip.mask.addr[0];
+ tmp = &filter->key.ipv4.dip.mask.addr[0];
memcpy(tmp, &match.mask->dst, 4);
match_protocol = false;
}
@@ -151,10 +149,10 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
struct flow_match_ports match;
flow_rule_match_ports(rule, &match);
- ace->frame.ipv4.sport.value = ntohs(match.key->src);
- ace->frame.ipv4.sport.mask = ntohs(match.mask->src);
- ace->frame.ipv4.dport.value = ntohs(match.key->dst);
- ace->frame.ipv4.dport.mask = ntohs(match.mask->dst);
+ filter->key.ipv4.sport.value = ntohs(match.key->src);
+ filter->key.ipv4.sport.mask = ntohs(match.mask->src);
+ filter->key.ipv4.dport.value = ntohs(match.key->dst);
+ filter->key.ipv4.dport.mask = ntohs(match.mask->dst);
match_protocol = false;
}
@@ -162,11 +160,11 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
struct flow_match_vlan match;
flow_rule_match_vlan(rule, &match);
- ace->type = OCELOT_ACE_TYPE_ANY;
- ace->vlan.vid.value = match.key->vlan_id;
- ace->vlan.vid.mask = match.mask->vlan_id;
- ace->vlan.pcp.value[0] = match.key->vlan_priority;
- ace->vlan.pcp.mask[0] = match.mask->vlan_priority;
+ filter->key_type = OCELOT_VCAP_KEY_ANY;
+ filter->vlan.vid.value = match.key->vlan_id;
+ filter->vlan.vid.mask = match.mask->vlan_id;
+ filter->vlan.pcp.value[0] = match.key->vlan_priority;
+ filter->vlan.pcp.mask[0] = match.mask->vlan_priority;
match_protocol = false;
}
@@ -175,99 +173,77 @@ finished_key_parsing:
/* TODO: support SNAP, LLC etc */
if (proto < ETH_P_802_3_MIN)
return -EOPNOTSUPP;
- ace->type = OCELOT_ACE_TYPE_ETYPE;
- *(u16 *)ace->frame.etype.etype.value = htons(proto);
- *(u16 *)ace->frame.etype.etype.mask = 0xffff;
+ filter->key_type = OCELOT_VCAP_KEY_ETYPE;
+ *(__be16 *)filter->key.etype.etype.value = htons(proto);
+ *(__be16 *)filter->key.etype.etype.mask = htons(0xffff);
}
- /* else, a rule of type OCELOT_ACE_TYPE_ANY is implicitly added */
+ /* else, a filter of type OCELOT_VCAP_KEY_ANY is implicitly added */
- ace->prio = f->common.prio;
- ace->id = f->cookie;
- return ocelot_flower_parse_action(f, ace);
+ filter->prio = f->common.prio;
+ filter->id = f->cookie;
+ return ocelot_flower_parse_action(f, filter);
}
-static
-struct ocelot_ace_rule *ocelot_ace_rule_create(struct ocelot *ocelot, int port,
- struct flow_cls_offload *f)
+static struct ocelot_vcap_filter
+*ocelot_vcap_filter_create(struct ocelot *ocelot, int port,
+ struct flow_cls_offload *f)
{
- struct ocelot_ace_rule *ace;
+ struct ocelot_vcap_filter *filter;
- ace = kzalloc(sizeof(*ace), GFP_KERNEL);
- if (!ace)
+ filter = kzalloc(sizeof(*filter), GFP_KERNEL);
+ if (!filter)
return NULL;
- ace->ingress_port_mask = BIT(port);
- return ace;
+ filter->ingress_port_mask = BIT(port);
+ return filter;
}
int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
struct flow_cls_offload *f, bool ingress)
{
- struct ocelot_ace_rule *ace;
+ struct ocelot_vcap_filter *filter;
int ret;
- ace = ocelot_ace_rule_create(ocelot, port, f);
- if (!ace)
+ filter = ocelot_vcap_filter_create(ocelot, port, f);
+ if (!filter)
return -ENOMEM;
- ret = ocelot_flower_parse(f, ace);
+ ret = ocelot_flower_parse(f, filter);
if (ret) {
- kfree(ace);
+ kfree(filter);
return ret;
}
- return ocelot_ace_rule_offload_add(ocelot, ace, f->common.extack);
+ return ocelot_vcap_filter_add(ocelot, filter, f->common.extack);
}
EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace);
int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
struct flow_cls_offload *f, bool ingress)
{
- struct ocelot_ace_rule ace;
+ struct ocelot_vcap_filter filter;
- ace.prio = f->common.prio;
- ace.id = f->cookie;
+ filter.prio = f->common.prio;
+ filter.id = f->cookie;
- return ocelot_ace_rule_offload_del(ocelot, &ace);
+ return ocelot_vcap_filter_del(ocelot, &filter);
}
EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy);
int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
struct flow_cls_offload *f, bool ingress)
{
- struct ocelot_ace_rule ace;
+ struct ocelot_vcap_filter filter;
int ret;
- ace.prio = f->common.prio;
- ace.id = f->cookie;
- ret = ocelot_ace_rule_stats_update(ocelot, &ace);
+ filter.prio = f->common.prio;
+ filter.id = f->cookie;
+ ret = ocelot_vcap_filter_stats_update(ocelot, &filter);
if (ret)
return ret;
- flow_stats_update(&f->stats, 0x0, ace.stats.pkts, 0x0,
+ flow_stats_update(&f->stats, 0x0, filter.stats.pkts, 0, 0x0,
FLOW_ACTION_HW_STATS_IMMEDIATE);
return 0;
}
EXPORT_SYMBOL_GPL(ocelot_cls_flower_stats);
-
-int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
- struct flow_cls_offload *f,
- bool ingress)
-{
- struct ocelot *ocelot = priv->port.ocelot;
- int port = priv->chip_port;
-
- if (!ingress)
- return -EOPNOTSUPP;
-
- switch (f->command) {
- case FLOW_CLS_REPLACE:
- return ocelot_cls_flower_replace(ocelot, port, f, ingress);
- case FLOW_CLS_DESTROY:
- return ocelot_cls_flower_destroy(ocelot, port, f, ingress);
- case FLOW_CLS_STATS:
- return ocelot_cls_flower_stats(ocelot, port, f, ingress);
- default:
- return -EOPNOTSUPP;
- }
-}
diff --git a/drivers/net/ethernet/mscc/ocelot_io.c b/drivers/net/ethernet/mscc/ocelot_io.c
index b229b1cb68ef..d22711282183 100644
--- a/drivers/net/ethernet/mscc/ocelot_io.c
+++ b/drivers/net/ethernet/mscc/ocelot_io.c
@@ -49,13 +49,25 @@ EXPORT_SYMBOL(__ocelot_rmw_ix);
u32 ocelot_port_readl(struct ocelot_port *port, u32 reg)
{
- return readl(port->regs + reg);
+ struct ocelot *ocelot = port->ocelot;
+ u16 target = reg >> TARGET_OFFSET;
+ u32 val;
+
+ WARN_ON(!target);
+
+ regmap_read(port->target, ocelot->map[target][reg & REG_MASK], &val);
+ return val;
}
EXPORT_SYMBOL(ocelot_port_readl);
void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg)
{
- writel(val, port->regs + reg);
+ struct ocelot *ocelot = port->ocelot;
+ u16 target = reg >> TARGET_OFFSET;
+
+ WARN_ON(!target);
+
+ regmap_write(port->target, ocelot->map[target][reg & REG_MASK], val);
}
EXPORT_SYMBOL(ocelot_port_writel);
@@ -77,6 +89,8 @@ int ocelot_regfields_init(struct ocelot *ocelot,
regfield.reg = ocelot->map[target][reg & REG_MASK];
regfield.lsb = regfields[i].lsb;
regfield.msb = regfields[i].msb;
+ regfield.id_size = regfields[i].id_size;
+ regfield.id_offset = regfields[i].id_offset;
ocelot->regfields[i] =
devm_regmap_field_alloc(ocelot->dev,
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
new file mode 100644
index 000000000000..0668d23cdbfa
--- /dev/null
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -0,0 +1,1050 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/* Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2017, 2019 Microsemi Corporation
+ */
+
+#include <linux/if_bridge.h>
+#include "ocelot.h"
+#include "ocelot_vcap.h"
+
+int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
+ struct flow_cls_offload *f,
+ bool ingress)
+{
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ if (!ingress)
+ return -EOPNOTSUPP;
+
+ switch (f->command) {
+ case FLOW_CLS_REPLACE:
+ return ocelot_cls_flower_replace(ocelot, port, f, ingress);
+ case FLOW_CLS_DESTROY:
+ return ocelot_cls_flower_destroy(ocelot, port, f, ingress);
+ case FLOW_CLS_STATS:
+ return ocelot_cls_flower_stats(ocelot, port, f, ingress);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
+ struct tc_cls_matchall_offload *f,
+ bool ingress)
+{
+ struct netlink_ext_ack *extack = f->common.extack;
+ struct ocelot *ocelot = priv->port.ocelot;
+ struct ocelot_policer pol = { 0 };
+ struct flow_action_entry *action;
+ int port = priv->chip_port;
+ int err;
+
+ if (!ingress) {
+ NL_SET_ERR_MSG_MOD(extack, "Only ingress is supported");
+ return -EOPNOTSUPP;
+ }
+
+ switch (f->command) {
+ case TC_CLSMATCHALL_REPLACE:
+ if (!flow_offload_has_one_action(&f->rule->action)) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Only one action is supported");
+ return -EOPNOTSUPP;
+ }
+
+ if (priv->tc.block_shared) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Rate limit is not supported on shared blocks");
+ return -EOPNOTSUPP;
+ }
+
+ action = &f->rule->action.entries[0];
+
+ if (action->id != FLOW_ACTION_POLICE) {
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported action");
+ return -EOPNOTSUPP;
+ }
+
+ if (priv->tc.police_id && priv->tc.police_id != f->cookie) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Only one policer per port is supported");
+ return -EEXIST;
+ }
+
+ pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;
+ pol.burst = action->police.burst;
+
+ err = ocelot_port_policer_add(ocelot, port, &pol);
+ if (err) {
+ NL_SET_ERR_MSG_MOD(extack, "Could not add policer");
+ return err;
+ }
+
+ priv->tc.police_id = f->cookie;
+ priv->tc.offload_cnt++;
+ return 0;
+ case TC_CLSMATCHALL_DESTROY:
+ if (priv->tc.police_id != f->cookie)
+ return -ENOENT;
+
+ err = ocelot_port_policer_del(ocelot, port);
+ if (err) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Could not delete policer");
+ return err;
+ }
+ priv->tc.police_id = 0;
+ priv->tc.offload_cnt--;
+ return 0;
+ case TC_CLSMATCHALL_STATS:
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ocelot_setup_tc_block_cb(enum tc_setup_type type,
+ void *type_data,
+ void *cb_priv, bool ingress)
+{
+ struct ocelot_port_private *priv = cb_priv;
+
+ if (!tc_cls_can_offload_and_chain0(priv->dev, type_data))
+ return -EOPNOTSUPP;
+
+ switch (type) {
+ case TC_SETUP_CLSMATCHALL:
+ return ocelot_setup_tc_cls_matchall(priv, type_data, ingress);
+ case TC_SETUP_CLSFLOWER:
+ return ocelot_setup_tc_cls_flower(priv, type_data, ingress);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ocelot_setup_tc_block_cb_ig(enum tc_setup_type type,
+ void *type_data,
+ void *cb_priv)
+{
+ return ocelot_setup_tc_block_cb(type, type_data,
+ cb_priv, true);
+}
+
+static int ocelot_setup_tc_block_cb_eg(enum tc_setup_type type,
+ void *type_data,
+ void *cb_priv)
+{
+ return ocelot_setup_tc_block_cb(type, type_data,
+ cb_priv, false);
+}
+
+static LIST_HEAD(ocelot_block_cb_list);
+
+static int ocelot_setup_tc_block(struct ocelot_port_private *priv,
+ struct flow_block_offload *f)
+{
+ struct flow_block_cb *block_cb;
+ flow_setup_cb_t *cb;
+
+ if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) {
+ cb = ocelot_setup_tc_block_cb_ig;
+ priv->tc.block_shared = f->block_shared;
+ } else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) {
+ cb = ocelot_setup_tc_block_cb_eg;
+ } else {
+ return -EOPNOTSUPP;
+ }
+
+ f->driver_block_list = &ocelot_block_cb_list;
+
+ switch (f->command) {
+ case FLOW_BLOCK_BIND:
+ if (flow_block_cb_is_busy(cb, priv, &ocelot_block_cb_list))
+ return -EBUSY;
+
+ block_cb = flow_block_cb_alloc(cb, priv, priv, NULL);
+ if (IS_ERR(block_cb))
+ return PTR_ERR(block_cb);
+
+ flow_block_cb_add(block_cb, f);
+ list_add_tail(&block_cb->driver_list, f->driver_block_list);
+ return 0;
+ case FLOW_BLOCK_UNBIND:
+ block_cb = flow_block_cb_lookup(f->block, cb, priv);
+ if (!block_cb)
+ return -ENOENT;
+
+ flow_block_cb_remove(block_cb, f);
+ list_del(&block_cb->driver_list);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ocelot_setup_tc(struct net_device *dev, enum tc_setup_type type,
+ void *type_data)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+
+ switch (type) {
+ case TC_SETUP_BLOCK:
+ return ocelot_setup_tc_block(priv, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static void ocelot_port_adjust_link(struct net_device *dev)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ ocelot_adjust_link(ocelot, port, dev->phydev);
+}
+
+static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
+ bool untagged)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ int port = priv->chip_port;
+ int ret;
+
+ ret = ocelot_vlan_add(ocelot, port, vid, pvid, untagged);
+ if (ret)
+ return ret;
+
+ /* Add the port MAC address to with the right VLAN information */
+ ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid,
+ ENTRYTYPE_LOCKED);
+
+ return 0;
+}
+
+static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+ int ret;
+
+ /* 8021q removes VID 0 on module unload for all interfaces
+ * with VLAN filtering feature. We need to keep it to receive
+ * untagged traffic.
+ */
+ if (vid == 0)
+ return 0;
+
+ ret = ocelot_vlan_del(ocelot, port, vid);
+ if (ret)
+ return ret;
+
+ /* Del the port MAC address to with the right VLAN information */
+ ocelot_mact_forget(ocelot, dev->dev_addr, vid);
+
+ return 0;
+}
+
+static int ocelot_port_open(struct net_device *dev)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ int port = priv->chip_port;
+ int err;
+
+ if (priv->serdes) {
+ err = phy_set_mode_ext(priv->serdes, PHY_MODE_ETHERNET,
+ ocelot_port->phy_mode);
+ if (err) {
+ netdev_err(dev, "Could not set mode of SerDes\n");
+ return err;
+ }
+ }
+
+ err = phy_connect_direct(dev, priv->phy, &ocelot_port_adjust_link,
+ ocelot_port->phy_mode);
+ if (err) {
+ netdev_err(dev, "Could not attach to PHY\n");
+ return err;
+ }
+
+ dev->phydev = priv->phy;
+
+ phy_attached_info(priv->phy);
+ phy_start(priv->phy);
+
+ ocelot_port_enable(ocelot, port, priv->phy);
+
+ return 0;
+}
+
+static int ocelot_port_stop(struct net_device *dev)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ phy_disconnect(priv->phy);
+
+ dev->phydev = NULL;
+
+ ocelot_port_disable(ocelot, port);
+
+ return 0;
+}
+
+/* Generate the IFH for frame injection
+ *
+ * The IFH is a 128bit-value
+ * bit 127: bypass the analyzer processing
+ * bit 56-67: destination mask
+ * bit 28-29: pop_cnt: 3 disables all rewriting of the frame
+ * bit 20-27: cpu extraction queue mask
+ * bit 16: tag type 0: C-tag, 1: S-tag
+ * bit 0-11: VID
+ */
+static int ocelot_gen_ifh(u32 *ifh, struct frame_info *info)
+{
+ ifh[0] = IFH_INJ_BYPASS | ((0x1ff & info->rew_op) << 21);
+ ifh[1] = (0xf00 & info->port) >> 8;
+ ifh[2] = (0xff & info->port) << 24;
+ ifh[3] = (info->tag_type << 16) | info->vid;
+
+ return 0;
+}
+
+static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ u32 val, ifh[OCELOT_TAG_LEN / 4];
+ struct frame_info info = {};
+ u8 grp = 0; /* Send everything on CPU group 0 */
+ unsigned int i, count, last;
+ int port = priv->chip_port;
+
+ val = ocelot_read(ocelot, QS_INJ_STATUS);
+ if (!(val & QS_INJ_STATUS_FIFO_RDY(BIT(grp))) ||
+ (val & QS_INJ_STATUS_WMARK_REACHED(BIT(grp))))
+ return NETDEV_TX_BUSY;
+
+ ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
+ QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp);
+
+ info.port = BIT(port);
+ info.tag_type = IFH_TAG_TYPE_C;
+ info.vid = skb_vlan_tag_get(skb);
+
+ /* Check if timestamping is needed */
+ if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP) {
+ info.rew_op = ocelot_port->ptp_cmd;
+ if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP)
+ info.rew_op |= (ocelot_port->ts_id % 4) << 3;
+ }
+
+ ocelot_gen_ifh(ifh, &info);
+
+ for (i = 0; i < OCELOT_TAG_LEN / 4; i++)
+ ocelot_write_rix(ocelot, (__force u32)cpu_to_be32(ifh[i]),
+ QS_INJ_WR, grp);
+
+ count = (skb->len + 3) / 4;
+ last = skb->len % 4;
+ for (i = 0; i < count; i++)
+ ocelot_write_rix(ocelot, ((u32 *)skb->data)[i], QS_INJ_WR, grp);
+
+ /* Add padding */
+ while (i < (OCELOT_BUFFER_CELL_SZ / 4)) {
+ ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp);
+ i++;
+ }
+
+ /* Indicate EOF and valid bytes in last word */
+ ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
+ QS_INJ_CTRL_VLD_BYTES(skb->len < OCELOT_BUFFER_CELL_SZ ? 0 : last) |
+ QS_INJ_CTRL_EOF,
+ QS_INJ_CTRL, grp);
+
+ /* Add dummy CRC */
+ ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp);
+ skb_tx_timestamp(skb);
+
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
+
+ if (!ocelot_port_add_txtstamp_skb(ocelot_port, skb)) {
+ ocelot_port->ts_id++;
+ return NETDEV_TX_OK;
+ }
+
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+static int ocelot_mc_unsync(struct net_device *dev, const unsigned char *addr)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+
+ return ocelot_mact_forget(ocelot, addr, ocelot_port->pvid);
+}
+
+static int ocelot_mc_sync(struct net_device *dev, const unsigned char *addr)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+
+ return ocelot_mact_learn(ocelot, PGID_CPU, addr, ocelot_port->pvid,
+ ENTRYTYPE_LOCKED);
+}
+
+static void ocelot_set_rx_mode(struct net_device *dev)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ u32 val;
+ int i;
+
+ /* This doesn't handle promiscuous mode because the bridge core is
+ * setting IFF_PROMISC on all slave interfaces and all frames would be
+ * forwarded to the CPU port.
+ */
+ val = GENMASK(ocelot->num_phys_ports - 1, 0);
+ for_each_nonreserved_multicast_dest_pgid(ocelot, i)
+ ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i);
+
+ __dev_mc_sync(dev, ocelot_mc_sync, ocelot_mc_unsync);
+}
+
+static int ocelot_port_get_phys_port_name(struct net_device *dev,
+ char *buf, size_t len)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ int port = priv->chip_port;
+ int ret;
+
+ ret = snprintf(buf, len, "p%d", port);
+ if (ret >= len)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ocelot_port_set_mac_address(struct net_device *dev, void *p)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ const struct sockaddr *addr = p;
+
+ /* Learn the new net device MAC address in the mac table. */
+ ocelot_mact_learn(ocelot, PGID_CPU, addr->sa_data, ocelot_port->pvid,
+ ENTRYTYPE_LOCKED);
+ /* Then forget the previous one. */
+ ocelot_mact_forget(ocelot, dev->dev_addr, ocelot_port->pvid);
+
+ ether_addr_copy(dev->dev_addr, addr->sa_data);
+ return 0;
+}
+
+static void ocelot_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *stats)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ /* Configure the port to read the stats from */
+ ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port),
+ SYS_STAT_CFG);
+
+ /* Get Rx stats */
+ stats->rx_bytes = ocelot_read(ocelot, SYS_COUNT_RX_OCTETS);
+ stats->rx_packets = ocelot_read(ocelot, SYS_COUNT_RX_SHORTS) +
+ ocelot_read(ocelot, SYS_COUNT_RX_FRAGMENTS) +
+ ocelot_read(ocelot, SYS_COUNT_RX_JABBERS) +
+ ocelot_read(ocelot, SYS_COUNT_RX_LONGS) +
+ ocelot_read(ocelot, SYS_COUNT_RX_64) +
+ ocelot_read(ocelot, SYS_COUNT_RX_65_127) +
+ ocelot_read(ocelot, SYS_COUNT_RX_128_255) +
+ ocelot_read(ocelot, SYS_COUNT_RX_256_1023) +
+ ocelot_read(ocelot, SYS_COUNT_RX_1024_1526) +
+ ocelot_read(ocelot, SYS_COUNT_RX_1527_MAX);
+ stats->multicast = ocelot_read(ocelot, SYS_COUNT_RX_MULTICAST);
+ stats->rx_dropped = dev->stats.rx_dropped;
+
+ /* Get Tx stats */
+ stats->tx_bytes = ocelot_read(ocelot, SYS_COUNT_TX_OCTETS);
+ stats->tx_packets = ocelot_read(ocelot, SYS_COUNT_TX_64) +
+ ocelot_read(ocelot, SYS_COUNT_TX_65_127) +
+ ocelot_read(ocelot, SYS_COUNT_TX_128_511) +
+ ocelot_read(ocelot, SYS_COUNT_TX_512_1023) +
+ ocelot_read(ocelot, SYS_COUNT_TX_1024_1526) +
+ ocelot_read(ocelot, SYS_COUNT_TX_1527_MAX);
+ stats->tx_dropped = ocelot_read(ocelot, SYS_COUNT_TX_DROPS) +
+ ocelot_read(ocelot, SYS_COUNT_TX_AGING);
+ stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION);
+}
+
+static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+ struct net_device *dev,
+ const unsigned char *addr,
+ u16 vid, u16 flags,
+ struct netlink_ext_ack *extack)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ return ocelot_fdb_add(ocelot, port, addr, vid);
+}
+
+static int ocelot_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
+ struct net_device *dev,
+ const unsigned char *addr, u16 vid)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ return ocelot_fdb_del(ocelot, port, addr, vid);
+}
+
+static int ocelot_port_fdb_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ struct net_device *filter_dev, int *idx)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ struct ocelot_dump_ctx dump = {
+ .dev = dev,
+ .skb = skb,
+ .cb = cb,
+ .idx = *idx,
+ };
+ int port = priv->chip_port;
+ int ret;
+
+ ret = ocelot_fdb_dump(ocelot, port, ocelot_port_fdb_do_dump, &dump);
+
+ *idx = dump.idx;
+
+ return ret;
+}
+
+static int ocelot_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
+ u16 vid)
+{
+ return ocelot_vlan_vid_add(dev, vid, false, false);
+}
+
+static int ocelot_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
+ u16 vid)
+{
+ return ocelot_vlan_vid_del(dev, vid);
+}
+
+static void ocelot_vlan_mode(struct ocelot *ocelot, int port,
+ netdev_features_t features)
+{
+ u32 val;
+
+ /* Filtering */
+ val = ocelot_read(ocelot, ANA_VLANMASK);
+ if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
+ val |= BIT(port);
+ else
+ val &= ~BIT(port);
+ ocelot_write(ocelot, val, ANA_VLANMASK);
+}
+
+static int ocelot_set_features(struct net_device *dev,
+ netdev_features_t features)
+{
+ netdev_features_t changed = dev->features ^ features;
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
+ priv->tc.offload_cnt) {
+ netdev_err(dev,
+ "Cannot disable HW TC offload while offloads active\n");
+ return -EBUSY;
+ }
+
+ if (changed & NETIF_F_HW_VLAN_CTAG_FILTER)
+ ocelot_vlan_mode(ocelot, port, features);
+
+ return 0;
+}
+
+static int ocelot_get_port_parent_id(struct net_device *dev,
+ struct netdev_phys_item_id *ppid)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+
+ ppid->id_len = sizeof(ocelot->base_mac);
+ memcpy(&ppid->id, &ocelot->base_mac, ppid->id_len);
+
+ return 0;
+}
+
+static int ocelot_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ /* If the attached PHY device isn't capable of timestamping operations,
+ * use our own (when possible).
+ */
+ if (!phy_has_hwtstamp(dev->phydev) && ocelot->ptp) {
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+ return ocelot_hwstamp_set(ocelot, port, ifr);
+ case SIOCGHWTSTAMP:
+ return ocelot_hwstamp_get(ocelot, port, ifr);
+ }
+ }
+
+ return phy_mii_ioctl(dev->phydev, ifr, cmd);
+}
+
+static const struct net_device_ops ocelot_port_netdev_ops = {
+ .ndo_open = ocelot_port_open,
+ .ndo_stop = ocelot_port_stop,
+ .ndo_start_xmit = ocelot_port_xmit,
+ .ndo_set_rx_mode = ocelot_set_rx_mode,
+ .ndo_get_phys_port_name = ocelot_port_get_phys_port_name,
+ .ndo_set_mac_address = ocelot_port_set_mac_address,
+ .ndo_get_stats64 = ocelot_get_stats64,
+ .ndo_fdb_add = ocelot_port_fdb_add,
+ .ndo_fdb_del = ocelot_port_fdb_del,
+ .ndo_fdb_dump = ocelot_port_fdb_dump,
+ .ndo_vlan_rx_add_vid = ocelot_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = ocelot_vlan_rx_kill_vid,
+ .ndo_set_features = ocelot_set_features,
+ .ndo_get_port_parent_id = ocelot_get_port_parent_id,
+ .ndo_setup_tc = ocelot_setup_tc,
+ .ndo_do_ioctl = ocelot_ioctl,
+};
+
+static void ocelot_port_get_strings(struct net_device *netdev, u32 sset,
+ u8 *data)
+{
+ struct ocelot_port_private *priv = netdev_priv(netdev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ ocelot_get_strings(ocelot, port, sset, data);
+}
+
+static void ocelot_port_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats,
+ u64 *data)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ ocelot_get_ethtool_stats(ocelot, port, data);
+}
+
+static int ocelot_port_get_sset_count(struct net_device *dev, int sset)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ return ocelot_get_sset_count(ocelot, port, sset);
+}
+
+static int ocelot_port_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+
+ if (!ocelot->ptp)
+ return ethtool_op_get_ts_info(dev, info);
+
+ return ocelot_get_ts_info(ocelot, port, info);
+}
+
+static const struct ethtool_ops ocelot_ethtool_ops = {
+ .get_strings = ocelot_port_get_strings,
+ .get_ethtool_stats = ocelot_port_get_ethtool_stats,
+ .get_sset_count = ocelot_port_get_sset_count,
+ .get_link_ksettings = phy_ethtool_get_link_ksettings,
+ .set_link_ksettings = phy_ethtool_set_link_ksettings,
+ .get_ts_info = ocelot_port_get_ts_info,
+};
+
+static void ocelot_port_attr_stp_state_set(struct ocelot *ocelot, int port,
+ struct switchdev_trans *trans,
+ u8 state)
+{
+ if (switchdev_trans_ph_prepare(trans))
+ return;
+
+ ocelot_bridge_stp_state_set(ocelot, port, state);
+}
+
+static void ocelot_port_attr_ageing_set(struct ocelot *ocelot, int port,
+ unsigned long ageing_clock_t)
+{
+ unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
+ u32 ageing_time = jiffies_to_msecs(ageing_jiffies);
+
+ ocelot_set_ageing_time(ocelot, ageing_time);
+}
+
+static void ocelot_port_attr_mc_set(struct ocelot *ocelot, int port, bool mc)
+{
+ u32 cpu_fwd_mcast = ANA_PORT_CPU_FWD_CFG_CPU_IGMP_REDIR_ENA |
+ ANA_PORT_CPU_FWD_CFG_CPU_MLD_REDIR_ENA |
+ ANA_PORT_CPU_FWD_CFG_CPU_IPMC_CTRL_COPY_ENA;
+ u32 val = 0;
+
+ if (mc)
+ val = cpu_fwd_mcast;
+
+ ocelot_rmw_gix(ocelot, val, cpu_fwd_mcast,
+ ANA_PORT_CPU_FWD_CFG, port);
+}
+
+static int ocelot_port_attr_set(struct net_device *dev,
+ const struct switchdev_attr *attr,
+ struct switchdev_trans *trans)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot *ocelot = priv->port.ocelot;
+ int port = priv->chip_port;
+ int err = 0;
+
+ switch (attr->id) {
+ case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
+ ocelot_port_attr_stp_state_set(ocelot, port, trans,
+ attr->u.stp_state);
+ break;
+ case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
+ ocelot_port_attr_ageing_set(ocelot, port, attr->u.ageing_time);
+ break;
+ case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
+ ocelot_port_vlan_filtering(ocelot, port,
+ attr->u.vlan_filtering);
+ break;
+ case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
+ ocelot_port_attr_mc_set(ocelot, port, !attr->u.mc_disabled);
+ break;
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ return err;
+}
+
+static int ocelot_port_obj_add_vlan(struct net_device *dev,
+ const struct switchdev_obj_port_vlan *vlan,
+ struct switchdev_trans *trans)
+{
+ int ret;
+ u16 vid;
+
+ for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
+ ret = ocelot_vlan_vid_add(dev, vid,
+ vlan->flags & BRIDGE_VLAN_INFO_PVID,
+ vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ocelot_port_vlan_del_vlan(struct net_device *dev,
+ const struct switchdev_obj_port_vlan *vlan)
+{
+ int ret;
+ u16 vid;
+
+ for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
+ ret = ocelot_vlan_vid_del(dev, vid);
+
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ocelot_port_obj_add_mdb(struct net_device *dev,
+ const struct switchdev_obj_port_mdb *mdb,
+ struct switchdev_trans *trans)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ int port = priv->chip_port;
+
+ if (switchdev_trans_ph_prepare(trans))
+ return 0;
+
+ return ocelot_port_mdb_add(ocelot, port, mdb);
+}
+
+static int ocelot_port_obj_del_mdb(struct net_device *dev,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ int port = priv->chip_port;
+
+ return ocelot_port_mdb_del(ocelot, port, mdb);
+}
+
+static int ocelot_port_obj_add(struct net_device *dev,
+ const struct switchdev_obj *obj,
+ struct switchdev_trans *trans,
+ struct netlink_ext_ack *extack)
+{
+ int ret = 0;
+
+ switch (obj->id) {
+ case SWITCHDEV_OBJ_ID_PORT_VLAN:
+ ret = ocelot_port_obj_add_vlan(dev,
+ SWITCHDEV_OBJ_PORT_VLAN(obj),
+ trans);
+ break;
+ case SWITCHDEV_OBJ_ID_PORT_MDB:
+ ret = ocelot_port_obj_add_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj),
+ trans);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return ret;
+}
+
+static int ocelot_port_obj_del(struct net_device *dev,
+ const struct switchdev_obj *obj)
+{
+ int ret = 0;
+
+ switch (obj->id) {
+ case SWITCHDEV_OBJ_ID_PORT_VLAN:
+ ret = ocelot_port_vlan_del_vlan(dev,
+ SWITCHDEV_OBJ_PORT_VLAN(obj));
+ break;
+ case SWITCHDEV_OBJ_ID_PORT_MDB:
+ ret = ocelot_port_obj_del_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj));
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return ret;
+}
+
+/* Checks if the net_device instance given to us originate from our driver. */
+static bool ocelot_netdevice_dev_check(const struct net_device *dev)
+{
+ return dev->netdev_ops == &ocelot_port_netdev_ops;
+}
+
+static int ocelot_netdevice_port_event(struct net_device *dev,
+ unsigned long event,
+ struct netdev_notifier_changeupper_info *info)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ int port = priv->chip_port;
+ int err = 0;
+
+ switch (event) {
+ case NETDEV_CHANGEUPPER:
+ if (netif_is_bridge_master(info->upper_dev)) {
+ if (info->linking) {
+ err = ocelot_port_bridge_join(ocelot, port,
+ info->upper_dev);
+ } else {
+ err = ocelot_port_bridge_leave(ocelot, port,
+ info->upper_dev);
+ }
+ }
+ if (netif_is_lag_master(info->upper_dev)) {
+ if (info->linking)
+ err = ocelot_port_lag_join(ocelot, port,
+ info->upper_dev);
+ else
+ ocelot_port_lag_leave(ocelot, port,
+ info->upper_dev);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+static int ocelot_netdevice_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct netdev_notifier_changeupper_info *info = ptr;
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ int ret = 0;
+
+ if (!ocelot_netdevice_dev_check(dev))
+ return 0;
+
+ if (event == NETDEV_PRECHANGEUPPER &&
+ netif_is_lag_master(info->upper_dev)) {
+ struct netdev_lag_upper_info *lag_upper_info = info->upper_info;
+ struct netlink_ext_ack *extack;
+
+ if (lag_upper_info &&
+ lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
+ extack = netdev_notifier_info_to_extack(&info->info);
+ NL_SET_ERR_MSG_MOD(extack, "LAG device using unsupported Tx type");
+
+ ret = -EINVAL;
+ goto notify;
+ }
+ }
+
+ if (netif_is_lag_master(dev)) {
+ struct net_device *slave;
+ struct list_head *iter;
+
+ netdev_for_each_lower_dev(dev, slave, iter) {
+ ret = ocelot_netdevice_port_event(slave, event, info);
+ if (ret)
+ goto notify;
+ }
+ } else {
+ ret = ocelot_netdevice_port_event(dev, event, info);
+ }
+
+notify:
+ return notifier_from_errno(ret);
+}
+
+struct notifier_block ocelot_netdevice_nb __read_mostly = {
+ .notifier_call = ocelot_netdevice_event,
+};
+
+static int ocelot_switchdev_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+ int err;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_SET:
+ err = switchdev_handle_port_attr_set(dev, ptr,
+ ocelot_netdevice_dev_check,
+ ocelot_port_attr_set);
+ return notifier_from_errno(err);
+ }
+
+ return NOTIFY_DONE;
+}
+
+struct notifier_block ocelot_switchdev_nb __read_mostly = {
+ .notifier_call = ocelot_switchdev_event,
+};
+
+static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+ int err;
+
+ switch (event) {
+ /* Blocking events. */
+ case SWITCHDEV_PORT_OBJ_ADD:
+ err = switchdev_handle_port_obj_add(dev, ptr,
+ ocelot_netdevice_dev_check,
+ ocelot_port_obj_add);
+ return notifier_from_errno(err);
+ case SWITCHDEV_PORT_OBJ_DEL:
+ err = switchdev_handle_port_obj_del(dev, ptr,
+ ocelot_netdevice_dev_check,
+ ocelot_port_obj_del);
+ return notifier_from_errno(err);
+ case SWITCHDEV_PORT_ATTR_SET:
+ err = switchdev_handle_port_attr_set(dev, ptr,
+ ocelot_netdevice_dev_check,
+ ocelot_port_attr_set);
+ return notifier_from_errno(err);
+ }
+
+ return NOTIFY_DONE;
+}
+
+struct notifier_block ocelot_switchdev_blocking_nb __read_mostly = {
+ .notifier_call = ocelot_switchdev_blocking_event,
+};
+
+int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target,
+ struct phy_device *phy)
+{
+ struct ocelot_port_private *priv;
+ struct ocelot_port *ocelot_port;
+ struct net_device *dev;
+ int err;
+
+ dev = alloc_etherdev(sizeof(struct ocelot_port_private));
+ if (!dev)
+ return -ENOMEM;
+ SET_NETDEV_DEV(dev, ocelot->dev);
+ priv = netdev_priv(dev);
+ priv->dev = dev;
+ priv->phy = phy;
+ priv->chip_port = port;
+ ocelot_port = &priv->port;
+ ocelot_port->ocelot = ocelot;
+ ocelot_port->target = target;
+ ocelot->ports[port] = ocelot_port;
+
+ dev->netdev_ops = &ocelot_port_netdev_ops;
+ dev->ethtool_ops = &ocelot_ethtool_ops;
+
+ dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS |
+ NETIF_F_HW_TC;
+ dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
+
+ memcpy(dev->dev_addr, ocelot->base_mac, ETH_ALEN);
+ dev->dev_addr[ETH_ALEN - 1] += port;
+ ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, ocelot_port->pvid,
+ ENTRYTYPE_LOCKED);
+
+ ocelot_init_port(ocelot, port);
+
+ err = register_netdev(dev);
+ if (err) {
+ dev_err(ocelot->dev, "register_netdev failed\n");
+ free_netdev(dev);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/mscc/ocelot_police.c b/drivers/net/ethernet/mscc/ocelot_police.c
index 2e1d8e187332..6f5068c1041a 100644
--- a/drivers/net/ethernet/mscc/ocelot_police.c
+++ b/drivers/net/ethernet/mscc/ocelot_police.c
@@ -7,16 +7,6 @@
#include <soc/mscc/ocelot.h>
#include "ocelot_police.h"
-enum mscc_qos_rate_mode {
- MSCC_QOS_RATE_MODE_DISABLED, /* Policer/shaper disabled */
- MSCC_QOS_RATE_MODE_LINE, /* Measure line rate in kbps incl. IPG */
- MSCC_QOS_RATE_MODE_DATA, /* Measures data rate in kbps excl. IPG */
- MSCC_QOS_RATE_MODE_FRAME, /* Measures frame rate in fps */
- __MSCC_QOS_RATE_MODE_END,
- NUM_MSCC_QOS_RATE_MODE = __MSCC_QOS_RATE_MODE_END,
- MSCC_QOS_RATE_MODE_MAX = __MSCC_QOS_RATE_MODE_END - 1,
-};
-
/* Types for ANA:POL[0-192]:POL_MODE_CFG.FRM_MODE */
#define POL_MODE_LINERATE 0 /* Incl IPG. Unit: 33 1/3 kbps, 4096 bytes */
#define POL_MODE_DATARATE 1 /* Excl IPG. Unit: 33 1/3 kbps, 4096 bytes */
@@ -30,19 +20,8 @@ enum mscc_qos_rate_mode {
/* Default policer order */
#define POL_ORDER 0x1d3 /* Ocelot policer order: Serial (QoS -> Port -> VCAP) */
-struct qos_policer_conf {
- enum mscc_qos_rate_mode mode;
- bool dlb; /* Enable DLB (dual leaky bucket mode */
- bool cf; /* Coupling flag (ignored in SLB mode) */
- u32 cir; /* CIR in kbps/fps (ignored in SLB mode) */
- u32 cbs; /* CBS in bytes/frames (ignored in SLB mode) */
- u32 pir; /* PIR in kbps/fps */
- u32 pbs; /* PBS in bytes/frames */
- u8 ipg; /* Size of IPG when MSCC_QOS_RATE_MODE_LINE is chosen */
-};
-
-static int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix,
- struct qos_policer_conf *conf)
+int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix,
+ struct qos_policer_conf *conf)
{
u32 cf = 0, cir_ena = 0, frm_mode = POL_MODE_LINERATE;
u32 cir = 0, cbs = 0, pir = 0, pbs = 0;
@@ -228,27 +207,3 @@ int ocelot_port_policer_del(struct ocelot *ocelot, int port)
return 0;
}
EXPORT_SYMBOL(ocelot_port_policer_del);
-
-int ocelot_ace_policer_add(struct ocelot *ocelot, u32 pol_ix,
- struct ocelot_policer *pol)
-{
- struct qos_policer_conf pp = { 0 };
-
- if (!pol)
- return -EINVAL;
-
- pp.mode = MSCC_QOS_RATE_MODE_DATA;
- pp.pir = pol->rate;
- pp.pbs = pol->burst;
-
- return qos_policer_conf_set(ocelot, 0, pol_ix, &pp);
-}
-
-int ocelot_ace_policer_del(struct ocelot *ocelot, u32 pol_ix)
-{
- struct qos_policer_conf pp = { 0 };
-
- pp.mode = MSCC_QOS_RATE_MODE_DISABLED;
-
- return qos_policer_conf_set(ocelot, 0, pol_ix, &pp);
-}
diff --git a/drivers/net/ethernet/mscc/ocelot_police.h b/drivers/net/ethernet/mscc/ocelot_police.h
index 792abd28010a..7adb05f71999 100644
--- a/drivers/net/ethernet/mscc/ocelot_police.h
+++ b/drivers/net/ethernet/mscc/ocelot_police.h
@@ -9,9 +9,28 @@
#include "ocelot.h"
-int ocelot_ace_policer_add(struct ocelot *ocelot, u32 pol_ix,
- struct ocelot_policer *pol);
+enum mscc_qos_rate_mode {
+ MSCC_QOS_RATE_MODE_DISABLED, /* Policer/shaper disabled */
+ MSCC_QOS_RATE_MODE_LINE, /* Measure line rate in kbps incl. IPG */
+ MSCC_QOS_RATE_MODE_DATA, /* Measures data rate in kbps excl. IPG */
+ MSCC_QOS_RATE_MODE_FRAME, /* Measures frame rate in fps */
+ __MSCC_QOS_RATE_MODE_END,
+ NUM_MSCC_QOS_RATE_MODE = __MSCC_QOS_RATE_MODE_END,
+ MSCC_QOS_RATE_MODE_MAX = __MSCC_QOS_RATE_MODE_END - 1,
+};
-int ocelot_ace_policer_del(struct ocelot *ocelot, u32 pol_ix);
+struct qos_policer_conf {
+ enum mscc_qos_rate_mode mode;
+ bool dlb; /* Enable DLB (dual leaky bucket mode */
+ bool cf; /* Coupling flag (ignored in SLB mode) */
+ u32 cir; /* CIR in kbps/fps (ignored in SLB mode) */
+ u32 cbs; /* CBS in bytes/frames (ignored in SLB mode) */
+ u32 pir; /* PIR in kbps/fps */
+ u32 pbs; /* PBS in bytes/frames */
+ u8 ipg; /* Size of IPG when MSCC_QOS_RATE_MODE_LINE is chosen */
+};
+
+int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix,
+ struct qos_policer_conf *conf);
#endif /* _MSCC_OCELOT_POLICE_H_ */
diff --git a/drivers/net/ethernet/mscc/ocelot_ptp.c b/drivers/net/ethernet/mscc/ocelot_ptp.c
index a3088a1676ed..1e08fe4daaef 100644
--- a/drivers/net/ethernet/mscc/ocelot_ptp.c
+++ b/drivers/net/ethernet/mscc/ocelot_ptp.c
@@ -184,18 +184,20 @@ int ocelot_ptp_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on)
{
struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
- struct timespec64 ts_start, ts_period;
+ struct timespec64 ts_phase, ts_period;
enum ocelot_ptp_pins ptp_pin;
unsigned long flags;
bool pps = false;
int pin = -1;
+ s64 wf_high;
+ s64 wf_low;
u32 val;
- s64 ns;
switch (rq->type) {
case PTP_CLK_REQ_PEROUT:
/* Reject requests with unsupported flags */
- if (rq->perout.flags)
+ if (rq->perout.flags & ~(PTP_PEROUT_DUTY_CYCLE |
+ PTP_PEROUT_PHASE))
return -EOPNOTSUPP;
pin = ptp_find_pin(ocelot->ptp_clock, PTP_PF_PEROUT,
@@ -211,22 +213,12 @@ int ocelot_ptp_enable(struct ptp_clock_info *ptp,
else
return -EBUSY;
- ts_start.tv_sec = rq->perout.start.sec;
- ts_start.tv_nsec = rq->perout.start.nsec;
ts_period.tv_sec = rq->perout.period.sec;
ts_period.tv_nsec = rq->perout.period.nsec;
if (ts_period.tv_sec == 1 && ts_period.tv_nsec == 0)
pps = true;
- if (ts_start.tv_sec || (ts_start.tv_nsec && !pps)) {
- dev_warn(ocelot->dev,
- "Absolute start time not supported!\n");
- dev_warn(ocelot->dev,
- "Accept nsec for PPS phase adjustment, otherwise start time should be 0 0.\n");
- return -EINVAL;
- }
-
/* Handle turning off */
if (!on) {
spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
@@ -236,16 +228,48 @@ int ocelot_ptp_enable(struct ptp_clock_info *ptp,
break;
}
+ if (rq->perout.flags & PTP_PEROUT_PHASE) {
+ ts_phase.tv_sec = rq->perout.phase.sec;
+ ts_phase.tv_nsec = rq->perout.phase.nsec;
+ } else {
+ /* Compatibility */
+ ts_phase.tv_sec = rq->perout.start.sec;
+ ts_phase.tv_nsec = rq->perout.start.nsec;
+ }
+ if (ts_phase.tv_sec || (ts_phase.tv_nsec && !pps)) {
+ dev_warn(ocelot->dev,
+ "Absolute start time not supported!\n");
+ dev_warn(ocelot->dev,
+ "Accept nsec for PPS phase adjustment, otherwise start time should be 0 0.\n");
+ return -EINVAL;
+ }
+
+ /* Calculate waveform high and low times */
+ if (rq->perout.flags & PTP_PEROUT_DUTY_CYCLE) {
+ struct timespec64 ts_on;
+
+ ts_on.tv_sec = rq->perout.on.sec;
+ ts_on.tv_nsec = rq->perout.on.nsec;
+
+ wf_high = timespec64_to_ns(&ts_on);
+ } else {
+ if (pps) {
+ wf_high = 1000;
+ } else {
+ wf_high = timespec64_to_ns(&ts_period);
+ wf_high = div_s64(wf_high, 2);
+ }
+ }
+
+ wf_low = timespec64_to_ns(&ts_period);
+ wf_low -= wf_high;
+
/* Handle PPS request */
if (pps) {
spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
- /* Pulse generated perout.start.nsec after TOD has
- * increased seconds.
- * Pulse width is set to 1us.
- */
- ocelot_write_rix(ocelot, ts_start.tv_nsec,
+ ocelot_write_rix(ocelot, ts_phase.tv_nsec,
PTP_PIN_WF_LOW_PERIOD, ptp_pin);
- ocelot_write_rix(ocelot, 1000,
+ ocelot_write_rix(ocelot, wf_high,
PTP_PIN_WF_HIGH_PERIOD, ptp_pin);
val = PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_CLOCK);
val |= PTP_PIN_CFG_SYNC;
@@ -255,14 +279,16 @@ int ocelot_ptp_enable(struct ptp_clock_info *ptp,
}
/* Handle periodic clock */
- ns = timespec64_to_ns(&ts_period);
- ns = ns >> 1;
- if (ns > 0x3fffffff || ns <= 0x6)
+ if (wf_high > 0x3fffffff || wf_high <= 0x6)
+ return -EINVAL;
+ if (wf_low > 0x3fffffff || wf_low <= 0x6)
return -EINVAL;
spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
- ocelot_write_rix(ocelot, ns, PTP_PIN_WF_LOW_PERIOD, ptp_pin);
- ocelot_write_rix(ocelot, ns, PTP_PIN_WF_HIGH_PERIOD, ptp_pin);
+ ocelot_write_rix(ocelot, wf_low, PTP_PIN_WF_LOW_PERIOD,
+ ptp_pin);
+ ocelot_write_rix(ocelot, wf_high, PTP_PIN_WF_HIGH_PERIOD,
+ ptp_pin);
val = PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_CLOCK);
ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin);
spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
diff --git a/drivers/net/ethernet/mscc/ocelot_regs.c b/drivers/net/ethernet/mscc/ocelot_regs.c
deleted file mode 100644
index 81d81ff75646..000000000000
--- a/drivers/net/ethernet/mscc/ocelot_regs.c
+++ /dev/null
@@ -1,450 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Microsemi Ocelot Switch driver
- *
- * Copyright (c) 2017 Microsemi Corporation
- */
-#include "ocelot.h"
-#include <soc/mscc/ocelot_hsio.h>
-
-static const u32 ocelot_ana_regmap[] = {
- REG(ANA_ADVLEARN, 0x009000),
- REG(ANA_VLANMASK, 0x009004),
- REG(ANA_PORT_B_DOMAIN, 0x009008),
- REG(ANA_ANAGEFIL, 0x00900c),
- REG(ANA_ANEVENTS, 0x009010),
- REG(ANA_STORMLIMIT_BURST, 0x009014),
- REG(ANA_STORMLIMIT_CFG, 0x009018),
- REG(ANA_ISOLATED_PORTS, 0x009028),
- REG(ANA_COMMUNITY_PORTS, 0x00902c),
- REG(ANA_AUTOAGE, 0x009030),
- REG(ANA_MACTOPTIONS, 0x009034),
- REG(ANA_LEARNDISC, 0x009038),
- REG(ANA_AGENCTRL, 0x00903c),
- REG(ANA_MIRRORPORTS, 0x009040),
- REG(ANA_EMIRRORPORTS, 0x009044),
- REG(ANA_FLOODING, 0x009048),
- REG(ANA_FLOODING_IPMC, 0x00904c),
- REG(ANA_SFLOW_CFG, 0x009050),
- REG(ANA_PORT_MODE, 0x009080),
- REG(ANA_PGID_PGID, 0x008c00),
- REG(ANA_TABLES_ANMOVED, 0x008b30),
- REG(ANA_TABLES_MACHDATA, 0x008b34),
- REG(ANA_TABLES_MACLDATA, 0x008b38),
- REG(ANA_TABLES_MACACCESS, 0x008b3c),
- REG(ANA_TABLES_MACTINDX, 0x008b40),
- REG(ANA_TABLES_VLANACCESS, 0x008b44),
- REG(ANA_TABLES_VLANTIDX, 0x008b48),
- REG(ANA_TABLES_ISDXACCESS, 0x008b4c),
- REG(ANA_TABLES_ISDXTIDX, 0x008b50),
- REG(ANA_TABLES_ENTRYLIM, 0x008b00),
- REG(ANA_TABLES_PTP_ID_HIGH, 0x008b54),
- REG(ANA_TABLES_PTP_ID_LOW, 0x008b58),
- REG(ANA_MSTI_STATE, 0x008e00),
- REG(ANA_PORT_VLAN_CFG, 0x007000),
- REG(ANA_PORT_DROP_CFG, 0x007004),
- REG(ANA_PORT_QOS_CFG, 0x007008),
- REG(ANA_PORT_VCAP_CFG, 0x00700c),
- REG(ANA_PORT_VCAP_S1_KEY_CFG, 0x007010),
- REG(ANA_PORT_VCAP_S2_CFG, 0x00701c),
- REG(ANA_PORT_PCP_DEI_MAP, 0x007020),
- REG(ANA_PORT_CPU_FWD_CFG, 0x007060),
- REG(ANA_PORT_CPU_FWD_BPDU_CFG, 0x007064),
- REG(ANA_PORT_CPU_FWD_GARP_CFG, 0x007068),
- REG(ANA_PORT_CPU_FWD_CCM_CFG, 0x00706c),
- REG(ANA_PORT_PORT_CFG, 0x007070),
- REG(ANA_PORT_POL_CFG, 0x007074),
- REG(ANA_PORT_PTP_CFG, 0x007078),
- REG(ANA_PORT_PTP_DLY1_CFG, 0x00707c),
- REG(ANA_OAM_UPM_LM_CNT, 0x007c00),
- REG(ANA_PORT_PTP_DLY2_CFG, 0x007080),
- REG(ANA_PFC_PFC_CFG, 0x008800),
- REG(ANA_PFC_PFC_TIMER, 0x008804),
- REG(ANA_IPT_OAM_MEP_CFG, 0x008000),
- REG(ANA_IPT_IPT, 0x008004),
- REG(ANA_PPT_PPT, 0x008ac0),
- REG(ANA_FID_MAP_FID_MAP, 0x000000),
- REG(ANA_AGGR_CFG, 0x0090b4),
- REG(ANA_CPUQ_CFG, 0x0090b8),
- REG(ANA_CPUQ_CFG2, 0x0090bc),
- REG(ANA_CPUQ_8021_CFG, 0x0090c0),
- REG(ANA_DSCP_CFG, 0x009100),
- REG(ANA_DSCP_REWR_CFG, 0x009200),
- REG(ANA_VCAP_RNG_TYPE_CFG, 0x009240),
- REG(ANA_VCAP_RNG_VAL_CFG, 0x009260),
- REG(ANA_VRAP_CFG, 0x009280),
- REG(ANA_VRAP_HDR_DATA, 0x009284),
- REG(ANA_VRAP_HDR_MASK, 0x009288),
- REG(ANA_DISCARD_CFG, 0x00928c),
- REG(ANA_FID_CFG, 0x009290),
- REG(ANA_POL_PIR_CFG, 0x004000),
- REG(ANA_POL_CIR_CFG, 0x004004),
- REG(ANA_POL_MODE_CFG, 0x004008),
- REG(ANA_POL_PIR_STATE, 0x00400c),
- REG(ANA_POL_CIR_STATE, 0x004010),
- REG(ANA_POL_STATE, 0x004014),
- REG(ANA_POL_FLOWC, 0x008b80),
- REG(ANA_POL_HYST, 0x008bec),
- REG(ANA_POL_MISC_CFG, 0x008bf0),
-};
-
-static const u32 ocelot_qs_regmap[] = {
- REG(QS_XTR_GRP_CFG, 0x000000),
- REG(QS_XTR_RD, 0x000008),
- REG(QS_XTR_FRM_PRUNING, 0x000010),
- REG(QS_XTR_FLUSH, 0x000018),
- REG(QS_XTR_DATA_PRESENT, 0x00001c),
- REG(QS_XTR_CFG, 0x000020),
- REG(QS_INJ_GRP_CFG, 0x000024),
- REG(QS_INJ_WR, 0x00002c),
- REG(QS_INJ_CTRL, 0x000034),
- REG(QS_INJ_STATUS, 0x00003c),
- REG(QS_INJ_ERR, 0x000040),
- REG(QS_INH_DBG, 0x000048),
-};
-
-static const u32 ocelot_qsys_regmap[] = {
- REG(QSYS_PORT_MODE, 0x011200),
- REG(QSYS_SWITCH_PORT_MODE, 0x011234),
- REG(QSYS_STAT_CNT_CFG, 0x011264),
- REG(QSYS_EEE_CFG, 0x011268),
- REG(QSYS_EEE_THRES, 0x011294),
- REG(QSYS_IGR_NO_SHARING, 0x011298),
- REG(QSYS_EGR_NO_SHARING, 0x01129c),
- REG(QSYS_SW_STATUS, 0x0112a0),
- REG(QSYS_EXT_CPU_CFG, 0x0112d0),
- REG(QSYS_PAD_CFG, 0x0112d4),
- REG(QSYS_CPU_GROUP_MAP, 0x0112d8),
- REG(QSYS_QMAP, 0x0112dc),
- REG(QSYS_ISDX_SGRP, 0x011400),
- REG(QSYS_TIMED_FRAME_ENTRY, 0x014000),
- REG(QSYS_TFRM_MISC, 0x011310),
- REG(QSYS_TFRM_PORT_DLY, 0x011314),
- REG(QSYS_TFRM_TIMER_CFG_1, 0x011318),
- REG(QSYS_TFRM_TIMER_CFG_2, 0x01131c),
- REG(QSYS_TFRM_TIMER_CFG_3, 0x011320),
- REG(QSYS_TFRM_TIMER_CFG_4, 0x011324),
- REG(QSYS_TFRM_TIMER_CFG_5, 0x011328),
- REG(QSYS_TFRM_TIMER_CFG_6, 0x01132c),
- REG(QSYS_TFRM_TIMER_CFG_7, 0x011330),
- REG(QSYS_TFRM_TIMER_CFG_8, 0x011334),
- REG(QSYS_RED_PROFILE, 0x011338),
- REG(QSYS_RES_QOS_MODE, 0x011378),
- REG(QSYS_RES_CFG, 0x012000),
- REG(QSYS_RES_STAT, 0x012004),
- REG(QSYS_EGR_DROP_MODE, 0x01137c),
- REG(QSYS_EQ_CTRL, 0x011380),
- REG(QSYS_EVENTS_CORE, 0x011384),
- REG(QSYS_CIR_CFG, 0x000000),
- REG(QSYS_EIR_CFG, 0x000004),
- REG(QSYS_SE_CFG, 0x000008),
- REG(QSYS_SE_DWRR_CFG, 0x00000c),
- REG(QSYS_SE_CONNECT, 0x00003c),
- REG(QSYS_SE_DLB_SENSE, 0x000040),
- REG(QSYS_CIR_STATE, 0x000044),
- REG(QSYS_EIR_STATE, 0x000048),
- REG(QSYS_SE_STATE, 0x00004c),
- REG(QSYS_HSCH_MISC_CFG, 0x011388),
-};
-
-static const u32 ocelot_rew_regmap[] = {
- REG(REW_PORT_VLAN_CFG, 0x000000),
- REG(REW_TAG_CFG, 0x000004),
- REG(REW_PORT_CFG, 0x000008),
- REG(REW_DSCP_CFG, 0x00000c),
- REG(REW_PCP_DEI_QOS_MAP_CFG, 0x000010),
- REG(REW_PTP_CFG, 0x000050),
- REG(REW_PTP_DLY1_CFG, 0x000054),
- REG(REW_DSCP_REMAP_DP1_CFG, 0x000690),
- REG(REW_DSCP_REMAP_CFG, 0x000790),
- REG(REW_STAT_CFG, 0x000890),
- REG(REW_PPT, 0x000680),
-};
-
-static const u32 ocelot_sys_regmap[] = {
- REG(SYS_COUNT_RX_OCTETS, 0x000000),
- REG(SYS_COUNT_RX_UNICAST, 0x000004),
- REG(SYS_COUNT_RX_MULTICAST, 0x000008),
- REG(SYS_COUNT_RX_BROADCAST, 0x00000c),
- REG(SYS_COUNT_RX_SHORTS, 0x000010),
- REG(SYS_COUNT_RX_FRAGMENTS, 0x000014),
- REG(SYS_COUNT_RX_JABBERS, 0x000018),
- REG(SYS_COUNT_RX_CRC_ALIGN_ERRS, 0x00001c),
- REG(SYS_COUNT_RX_SYM_ERRS, 0x000020),
- REG(SYS_COUNT_RX_64, 0x000024),
- REG(SYS_COUNT_RX_65_127, 0x000028),
- REG(SYS_COUNT_RX_128_255, 0x00002c),
- REG(SYS_COUNT_RX_256_1023, 0x000030),
- REG(SYS_COUNT_RX_1024_1526, 0x000034),
- REG(SYS_COUNT_RX_1527_MAX, 0x000038),
- REG(SYS_COUNT_RX_PAUSE, 0x00003c),
- REG(SYS_COUNT_RX_CONTROL, 0x000040),
- REG(SYS_COUNT_RX_LONGS, 0x000044),
- REG(SYS_COUNT_RX_CLASSIFIED_DROPS, 0x000048),
- REG(SYS_COUNT_TX_OCTETS, 0x000100),
- REG(SYS_COUNT_TX_UNICAST, 0x000104),
- REG(SYS_COUNT_TX_MULTICAST, 0x000108),
- REG(SYS_COUNT_TX_BROADCAST, 0x00010c),
- REG(SYS_COUNT_TX_COLLISION, 0x000110),
- REG(SYS_COUNT_TX_DROPS, 0x000114),
- REG(SYS_COUNT_TX_PAUSE, 0x000118),
- REG(SYS_COUNT_TX_64, 0x00011c),
- REG(SYS_COUNT_TX_65_127, 0x000120),
- REG(SYS_COUNT_TX_128_511, 0x000124),
- REG(SYS_COUNT_TX_512_1023, 0x000128),
- REG(SYS_COUNT_TX_1024_1526, 0x00012c),
- REG(SYS_COUNT_TX_1527_MAX, 0x000130),
- REG(SYS_COUNT_TX_AGING, 0x000170),
- REG(SYS_RESET_CFG, 0x000508),
- REG(SYS_CMID, 0x00050c),
- REG(SYS_VLAN_ETYPE_CFG, 0x000510),
- REG(SYS_PORT_MODE, 0x000514),
- REG(SYS_FRONT_PORT_MODE, 0x000548),
- REG(SYS_FRM_AGING, 0x000574),
- REG(SYS_STAT_CFG, 0x000578),
- REG(SYS_SW_STATUS, 0x00057c),
- REG(SYS_MISC_CFG, 0x0005ac),
- REG(SYS_REW_MAC_HIGH_CFG, 0x0005b0),
- REG(SYS_REW_MAC_LOW_CFG, 0x0005dc),
- REG(SYS_CM_ADDR, 0x000500),
- REG(SYS_CM_DATA, 0x000504),
- REG(SYS_PAUSE_CFG, 0x000608),
- REG(SYS_PAUSE_TOT_CFG, 0x000638),
- REG(SYS_ATOP, 0x00063c),
- REG(SYS_ATOP_TOT_CFG, 0x00066c),
- REG(SYS_MAC_FC_CFG, 0x000670),
- REG(SYS_MMGT, 0x00069c),
- REG(SYS_MMGT_FAST, 0x0006a0),
- REG(SYS_EVENTS_DIF, 0x0006a4),
- REG(SYS_EVENTS_CORE, 0x0006b4),
- REG(SYS_CNT, 0x000000),
- REG(SYS_PTP_STATUS, 0x0006b8),
- REG(SYS_PTP_TXSTAMP, 0x0006bc),
- REG(SYS_PTP_NXT, 0x0006c0),
- REG(SYS_PTP_CFG, 0x0006c4),
-};
-
-static const u32 ocelot_s2_regmap[] = {
- REG(S2_CORE_UPDATE_CTRL, 0x000000),
- REG(S2_CORE_MV_CFG, 0x000004),
- REG(S2_CACHE_ENTRY_DAT, 0x000008),
- REG(S2_CACHE_MASK_DAT, 0x000108),
- REG(S2_CACHE_ACTION_DAT, 0x000208),
- REG(S2_CACHE_CNT_DAT, 0x000308),
- REG(S2_CACHE_TG_DAT, 0x000388),
-};
-
-static const u32 ocelot_ptp_regmap[] = {
- REG(PTP_PIN_CFG, 0x000000),
- REG(PTP_PIN_TOD_SEC_MSB, 0x000004),
- REG(PTP_PIN_TOD_SEC_LSB, 0x000008),
- REG(PTP_PIN_TOD_NSEC, 0x00000c),
- REG(PTP_PIN_WF_HIGH_PERIOD, 0x000014),
- REG(PTP_PIN_WF_LOW_PERIOD, 0x000018),
- REG(PTP_CFG_MISC, 0x0000a0),
- REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4),
- REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8),
-};
-
-static const u32 *ocelot_regmap[] = {
- [ANA] = ocelot_ana_regmap,
- [QS] = ocelot_qs_regmap,
- [QSYS] = ocelot_qsys_regmap,
- [REW] = ocelot_rew_regmap,
- [SYS] = ocelot_sys_regmap,
- [S2] = ocelot_s2_regmap,
- [PTP] = ocelot_ptp_regmap,
-};
-
-static const struct reg_field ocelot_regfields[] = {
- [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 11, 11),
- [ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 10),
- [ANA_ANEVENTS_MSTI_DROP] = REG_FIELD(ANA_ANEVENTS, 27, 27),
- [ANA_ANEVENTS_ACLKILL] = REG_FIELD(ANA_ANEVENTS, 26, 26),
- [ANA_ANEVENTS_ACLUSED] = REG_FIELD(ANA_ANEVENTS, 25, 25),
- [ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24),
- [ANA_ANEVENTS_VS2TTL1] = REG_FIELD(ANA_ANEVENTS, 23, 23),
- [ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22),
- [ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21),
- [ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20),
- [ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19),
- [ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
- [ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17),
- [ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16),
- [ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15),
- [ANA_ANEVENTS_DROPPED] = REG_FIELD(ANA_ANEVENTS, 14, 14),
- [ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13),
- [ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12),
- [ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
- [ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
- [ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9),
- [ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8),
- [ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7),
- [ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
- [ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
- [ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4),
- [ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3),
- [ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2),
- [ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1),
- [ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0),
- [ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 18, 18),
- [ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 10, 11),
- [ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 9),
- [QSYS_TIMED_FRAME_ENTRY_TFRM_VLD] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 20, 20),
- [QSYS_TIMED_FRAME_ENTRY_TFRM_FP] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 8, 19),
- [QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 4, 7),
- [QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 1, 3),
- [QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 0, 0),
- [SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 2, 2),
- [SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 1, 1),
- [SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 0, 0),
-};
-
-static const struct ocelot_stat_layout ocelot_stats_layout[] = {
- { .name = "rx_octets", .offset = 0x00, },
- { .name = "rx_unicast", .offset = 0x01, },
- { .name = "rx_multicast", .offset = 0x02, },
- { .name = "rx_broadcast", .offset = 0x03, },
- { .name = "rx_shorts", .offset = 0x04, },
- { .name = "rx_fragments", .offset = 0x05, },
- { .name = "rx_jabbers", .offset = 0x06, },
- { .name = "rx_crc_align_errs", .offset = 0x07, },
- { .name = "rx_sym_errs", .offset = 0x08, },
- { .name = "rx_frames_below_65_octets", .offset = 0x09, },
- { .name = "rx_frames_65_to_127_octets", .offset = 0x0A, },
- { .name = "rx_frames_128_to_255_octets", .offset = 0x0B, },
- { .name = "rx_frames_256_to_511_octets", .offset = 0x0C, },
- { .name = "rx_frames_512_to_1023_octets", .offset = 0x0D, },
- { .name = "rx_frames_1024_to_1526_octets", .offset = 0x0E, },
- { .name = "rx_frames_over_1526_octets", .offset = 0x0F, },
- { .name = "rx_pause", .offset = 0x10, },
- { .name = "rx_control", .offset = 0x11, },
- { .name = "rx_longs", .offset = 0x12, },
- { .name = "rx_classified_drops", .offset = 0x13, },
- { .name = "rx_red_prio_0", .offset = 0x14, },
- { .name = "rx_red_prio_1", .offset = 0x15, },
- { .name = "rx_red_prio_2", .offset = 0x16, },
- { .name = "rx_red_prio_3", .offset = 0x17, },
- { .name = "rx_red_prio_4", .offset = 0x18, },
- { .name = "rx_red_prio_5", .offset = 0x19, },
- { .name = "rx_red_prio_6", .offset = 0x1A, },
- { .name = "rx_red_prio_7", .offset = 0x1B, },
- { .name = "rx_yellow_prio_0", .offset = 0x1C, },
- { .name = "rx_yellow_prio_1", .offset = 0x1D, },
- { .name = "rx_yellow_prio_2", .offset = 0x1E, },
- { .name = "rx_yellow_prio_3", .offset = 0x1F, },
- { .name = "rx_yellow_prio_4", .offset = 0x20, },
- { .name = "rx_yellow_prio_5", .offset = 0x21, },
- { .name = "rx_yellow_prio_6", .offset = 0x22, },
- { .name = "rx_yellow_prio_7", .offset = 0x23, },
- { .name = "rx_green_prio_0", .offset = 0x24, },
- { .name = "rx_green_prio_1", .offset = 0x25, },
- { .name = "rx_green_prio_2", .offset = 0x26, },
- { .name = "rx_green_prio_3", .offset = 0x27, },
- { .name = "rx_green_prio_4", .offset = 0x28, },
- { .name = "rx_green_prio_5", .offset = 0x29, },
- { .name = "rx_green_prio_6", .offset = 0x2A, },
- { .name = "rx_green_prio_7", .offset = 0x2B, },
- { .name = "tx_octets", .offset = 0x40, },
- { .name = "tx_unicast", .offset = 0x41, },
- { .name = "tx_multicast", .offset = 0x42, },
- { .name = "tx_broadcast", .offset = 0x43, },
- { .name = "tx_collision", .offset = 0x44, },
- { .name = "tx_drops", .offset = 0x45, },
- { .name = "tx_pause", .offset = 0x46, },
- { .name = "tx_frames_below_65_octets", .offset = 0x47, },
- { .name = "tx_frames_65_to_127_octets", .offset = 0x48, },
- { .name = "tx_frames_128_255_octets", .offset = 0x49, },
- { .name = "tx_frames_256_511_octets", .offset = 0x4A, },
- { .name = "tx_frames_512_1023_octets", .offset = 0x4B, },
- { .name = "tx_frames_1024_1526_octets", .offset = 0x4C, },
- { .name = "tx_frames_over_1526_octets", .offset = 0x4D, },
- { .name = "tx_yellow_prio_0", .offset = 0x4E, },
- { .name = "tx_yellow_prio_1", .offset = 0x4F, },
- { .name = "tx_yellow_prio_2", .offset = 0x50, },
- { .name = "tx_yellow_prio_3", .offset = 0x51, },
- { .name = "tx_yellow_prio_4", .offset = 0x52, },
- { .name = "tx_yellow_prio_5", .offset = 0x53, },
- { .name = "tx_yellow_prio_6", .offset = 0x54, },
- { .name = "tx_yellow_prio_7", .offset = 0x55, },
- { .name = "tx_green_prio_0", .offset = 0x56, },
- { .name = "tx_green_prio_1", .offset = 0x57, },
- { .name = "tx_green_prio_2", .offset = 0x58, },
- { .name = "tx_green_prio_3", .offset = 0x59, },
- { .name = "tx_green_prio_4", .offset = 0x5A, },
- { .name = "tx_green_prio_5", .offset = 0x5B, },
- { .name = "tx_green_prio_6", .offset = 0x5C, },
- { .name = "tx_green_prio_7", .offset = 0x5D, },
- { .name = "tx_aged", .offset = 0x5E, },
- { .name = "drop_local", .offset = 0x80, },
- { .name = "drop_tail", .offset = 0x81, },
- { .name = "drop_yellow_prio_0", .offset = 0x82, },
- { .name = "drop_yellow_prio_1", .offset = 0x83, },
- { .name = "drop_yellow_prio_2", .offset = 0x84, },
- { .name = "drop_yellow_prio_3", .offset = 0x85, },
- { .name = "drop_yellow_prio_4", .offset = 0x86, },
- { .name = "drop_yellow_prio_5", .offset = 0x87, },
- { .name = "drop_yellow_prio_6", .offset = 0x88, },
- { .name = "drop_yellow_prio_7", .offset = 0x89, },
- { .name = "drop_green_prio_0", .offset = 0x8A, },
- { .name = "drop_green_prio_1", .offset = 0x8B, },
- { .name = "drop_green_prio_2", .offset = 0x8C, },
- { .name = "drop_green_prio_3", .offset = 0x8D, },
- { .name = "drop_green_prio_4", .offset = 0x8E, },
- { .name = "drop_green_prio_5", .offset = 0x8F, },
- { .name = "drop_green_prio_6", .offset = 0x90, },
- { .name = "drop_green_prio_7", .offset = 0x91, },
-};
-
-static void ocelot_pll5_init(struct ocelot *ocelot)
-{
- /* Configure PLL5. This will need a proper CCF driver
- * The values are coming from the VTSS API for Ocelot
- */
- regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG4,
- HSIO_PLL5G_CFG4_IB_CTRL(0x7600) |
- HSIO_PLL5G_CFG4_IB_BIAS_CTRL(0x8));
- regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG0,
- HSIO_PLL5G_CFG0_CORE_CLK_DIV(0x11) |
- HSIO_PLL5G_CFG0_CPU_CLK_DIV(2) |
- HSIO_PLL5G_CFG0_ENA_BIAS |
- HSIO_PLL5G_CFG0_ENA_VCO_BUF |
- HSIO_PLL5G_CFG0_ENA_CP1 |
- HSIO_PLL5G_CFG0_SELCPI(2) |
- HSIO_PLL5G_CFG0_LOOP_BW_RES(0xe) |
- HSIO_PLL5G_CFG0_SELBGV820(4) |
- HSIO_PLL5G_CFG0_DIV4 |
- HSIO_PLL5G_CFG0_ENA_CLKTREE |
- HSIO_PLL5G_CFG0_ENA_LANE);
- regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG2,
- HSIO_PLL5G_CFG2_EN_RESET_FRQ_DET |
- HSIO_PLL5G_CFG2_EN_RESET_OVERRUN |
- HSIO_PLL5G_CFG2_GAIN_TEST(0x8) |
- HSIO_PLL5G_CFG2_ENA_AMPCTRL |
- HSIO_PLL5G_CFG2_PWD_AMPCTRL_N |
- HSIO_PLL5G_CFG2_AMPC_SEL(0x10));
-}
-
-int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops)
-{
- int ret;
-
- ocelot->map = ocelot_regmap;
- ocelot->stats_layout = ocelot_stats_layout;
- ocelot->num_stats = ARRAY_SIZE(ocelot_stats_layout);
- ocelot->shared_queue_sz = 224 * 1024;
- ocelot->num_mact_rows = 1024;
- ocelot->ops = ops;
-
- ret = ocelot_regfields_init(ocelot, ocelot_regfields);
- if (ret)
- return ret;
-
- ocelot_pll5_init(ocelot);
-
- eth_random_addr(ocelot->base_mac);
- ocelot->base_mac[5] &= 0xf0;
-
- return 0;
-}
-EXPORT_SYMBOL(ocelot_chip_init);
diff --git a/drivers/net/ethernet/mscc/ocelot_tc.c b/drivers/net/ethernet/mscc/ocelot_tc.c
deleted file mode 100644
index b7baf7624e18..000000000000
--- a/drivers/net/ethernet/mscc/ocelot_tc.c
+++ /dev/null
@@ -1,179 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/* Microsemi Ocelot Switch TC driver
- *
- * Copyright (c) 2019 Microsemi Corporation
- */
-
-#include <soc/mscc/ocelot.h>
-#include "ocelot_tc.h"
-#include "ocelot_ace.h"
-#include <net/pkt_cls.h>
-
-static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
- struct tc_cls_matchall_offload *f,
- bool ingress)
-{
- struct netlink_ext_ack *extack = f->common.extack;
- struct ocelot *ocelot = priv->port.ocelot;
- struct ocelot_policer pol = { 0 };
- struct flow_action_entry *action;
- int port = priv->chip_port;
- int err;
-
- if (!ingress) {
- NL_SET_ERR_MSG_MOD(extack, "Only ingress is supported");
- return -EOPNOTSUPP;
- }
-
- switch (f->command) {
- case TC_CLSMATCHALL_REPLACE:
- if (!flow_offload_has_one_action(&f->rule->action)) {
- NL_SET_ERR_MSG_MOD(extack,
- "Only one action is supported");
- return -EOPNOTSUPP;
- }
-
- if (priv->tc.block_shared) {
- NL_SET_ERR_MSG_MOD(extack,
- "Rate limit is not supported on shared blocks");
- return -EOPNOTSUPP;
- }
-
- action = &f->rule->action.entries[0];
-
- if (action->id != FLOW_ACTION_POLICE) {
- NL_SET_ERR_MSG_MOD(extack, "Unsupported action");
- return -EOPNOTSUPP;
- }
-
- if (priv->tc.police_id && priv->tc.police_id != f->cookie) {
- NL_SET_ERR_MSG_MOD(extack,
- "Only one policer per port is supported");
- return -EEXIST;
- }
-
- pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;
- pol.burst = (u32)div_u64(action->police.rate_bytes_ps *
- PSCHED_NS2TICKS(action->police.burst),
- PSCHED_TICKS_PER_SEC);
-
- err = ocelot_port_policer_add(ocelot, port, &pol);
- if (err) {
- NL_SET_ERR_MSG_MOD(extack, "Could not add policer");
- return err;
- }
-
- priv->tc.police_id = f->cookie;
- priv->tc.offload_cnt++;
- return 0;
- case TC_CLSMATCHALL_DESTROY:
- if (priv->tc.police_id != f->cookie)
- return -ENOENT;
-
- err = ocelot_port_policer_del(ocelot, port);
- if (err) {
- NL_SET_ERR_MSG_MOD(extack,
- "Could not delete policer");
- return err;
- }
- priv->tc.police_id = 0;
- priv->tc.offload_cnt--;
- return 0;
- case TC_CLSMATCHALL_STATS: /* fall through */
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static int ocelot_setup_tc_block_cb(enum tc_setup_type type,
- void *type_data,
- void *cb_priv, bool ingress)
-{
- struct ocelot_port_private *priv = cb_priv;
-
- if (!tc_cls_can_offload_and_chain0(priv->dev, type_data))
- return -EOPNOTSUPP;
-
- switch (type) {
- case TC_SETUP_CLSMATCHALL:
- return ocelot_setup_tc_cls_matchall(priv, type_data, ingress);
- case TC_SETUP_CLSFLOWER:
- return ocelot_setup_tc_cls_flower(priv, type_data, ingress);
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static int ocelot_setup_tc_block_cb_ig(enum tc_setup_type type,
- void *type_data,
- void *cb_priv)
-{
- return ocelot_setup_tc_block_cb(type, type_data,
- cb_priv, true);
-}
-
-static int ocelot_setup_tc_block_cb_eg(enum tc_setup_type type,
- void *type_data,
- void *cb_priv)
-{
- return ocelot_setup_tc_block_cb(type, type_data,
- cb_priv, false);
-}
-
-static LIST_HEAD(ocelot_block_cb_list);
-
-static int ocelot_setup_tc_block(struct ocelot_port_private *priv,
- struct flow_block_offload *f)
-{
- struct flow_block_cb *block_cb;
- flow_setup_cb_t *cb;
-
- if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) {
- cb = ocelot_setup_tc_block_cb_ig;
- priv->tc.block_shared = f->block_shared;
- } else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) {
- cb = ocelot_setup_tc_block_cb_eg;
- } else {
- return -EOPNOTSUPP;
- }
-
- f->driver_block_list = &ocelot_block_cb_list;
-
- switch (f->command) {
- case FLOW_BLOCK_BIND:
- if (flow_block_cb_is_busy(cb, priv, &ocelot_block_cb_list))
- return -EBUSY;
-
- block_cb = flow_block_cb_alloc(cb, priv, priv, NULL);
- if (IS_ERR(block_cb))
- return PTR_ERR(block_cb);
-
- flow_block_cb_add(block_cb, f);
- list_add_tail(&block_cb->driver_list, f->driver_block_list);
- return 0;
- case FLOW_BLOCK_UNBIND:
- block_cb = flow_block_cb_lookup(f->block, cb, priv);
- if (!block_cb)
- return -ENOENT;
-
- flow_block_cb_remove(block_cb, f);
- list_del(&block_cb->driver_list);
- return 0;
- default:
- return -EOPNOTSUPP;
- }
-}
-
-int ocelot_setup_tc(struct net_device *dev, enum tc_setup_type type,
- void *type_data)
-{
- struct ocelot_port_private *priv = netdev_priv(dev);
-
- switch (type) {
- case TC_SETUP_BLOCK:
- return ocelot_setup_tc_block(priv, type_data);
- default:
- return -EOPNOTSUPP;
- }
- return 0;
-}
diff --git a/drivers/net/ethernet/mscc/ocelot_tc.h b/drivers/net/ethernet/mscc/ocelot_tc.h
deleted file mode 100644
index 61757c2250a6..000000000000
--- a/drivers/net/ethernet/mscc/ocelot_tc.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
-/* Microsemi Ocelot Switch driver
- *
- * Copyright (c) 2019 Microsemi Corporation
- */
-
-#ifndef _MSCC_OCELOT_TC_H_
-#define _MSCC_OCELOT_TC_H_
-
-#include <linux/netdevice.h>
-
-struct ocelot_port_tc {
- bool block_shared;
- unsigned long offload_cnt;
-
- unsigned long police_id;
-};
-
-int ocelot_setup_tc(struct net_device *dev, enum tc_setup_type type,
- void *type_data);
-
-#endif /* _MSCC_OCELOT_TC_H_ */
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_vcap.c
index dfd82a3baab2..3ef620faf995 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_vcap.c
@@ -8,7 +8,7 @@
#include <soc/mscc/ocelot_vcap.h>
#include "ocelot_police.h"
-#include "ocelot_ace.h"
+#include "ocelot_vcap.h"
#include "ocelot_s2.h"
#define OCELOT_POLICER_DISCARD 0x17f
@@ -119,7 +119,8 @@ static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data)
static void vcap_action2cache(struct ocelot *ocelot, struct vcap_data *data)
{
const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
- u32 action_words, i, width, mask;
+ u32 action_words, mask;
+ int i, width;
/* Encode action type */
width = vcap_is2->action_type_width;
@@ -141,7 +142,8 @@ static void vcap_action2cache(struct ocelot *ocelot, struct vcap_data *data)
static void vcap_cache2action(struct ocelot *ocelot, struct vcap_data *data)
{
const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
- u32 action_words, i, width;
+ u32 action_words;
+ int i, width;
action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH);
@@ -161,8 +163,8 @@ static void vcap_cache2action(struct ocelot *ocelot, struct vcap_data *data)
static void is2_data_get(struct ocelot *ocelot, struct vcap_data *data, int ix)
{
const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
- u32 i, col, offset, count, cnt, base;
- u32 width = vcap_is2->tg_width;
+ int i, col, offset, count, cnt, base;
+ int width = vcap_is2->tg_width;
count = (data->tg_sw == VCAP_TG_HALF ? 2 : 4);
col = (ix % 2);
@@ -300,10 +302,10 @@ static void vcap_action_set(struct ocelot *ocelot, struct vcap_data *data,
}
static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
- struct ocelot_ace_rule *ace)
+ struct ocelot_vcap_filter *filter)
{
- switch (ace->action) {
- case OCELOT_ACL_ACTION_DROP:
+ switch (filter->action) {
+ case OCELOT_VCAP_ACTION_DROP:
vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1);
@@ -312,7 +314,7 @@ static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0);
break;
- case OCELOT_ACL_ACTION_TRAP:
+ case OCELOT_VCAP_ACTION_TRAP:
vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 0);
@@ -320,12 +322,12 @@ static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 1);
break;
- case OCELOT_ACL_ACTION_POLICE:
+ case OCELOT_VCAP_ACTION_POLICE:
vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 0);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX,
- ace->pol_ix);
+ filter->pol_ix);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0);
break;
@@ -333,11 +335,11 @@ static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
}
static void is2_entry_set(struct ocelot *ocelot, int ix,
- struct ocelot_ace_rule *ace)
+ struct ocelot_vcap_filter *filter)
{
const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
+ struct ocelot_vcap_key_vlan *tag = &filter->vlan;
u32 val, msk, type, type_mask = 0xf, i, count;
- struct ocelot_ace_vlan *tag = &ace->vlan;
struct ocelot_vcap_u64 payload;
struct vcap_data data;
int row = (ix / 2);
@@ -353,19 +355,19 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
data.tg_sw = VCAP_TG_HALF;
is2_data_get(ocelot, &data, ix);
data.tg = (data.tg & ~data.tg_mask);
- if (ace->prio != 0)
+ if (filter->prio != 0)
data.tg |= data.tg_value;
data.type = IS2_ACTION_TYPE_NORMAL;
vcap_key_set(ocelot, &data, VCAP_IS2_HK_PAG, 0, 0);
vcap_key_set(ocelot, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0,
- ~ace->ingress_port_mask);
+ ~filter->ingress_port_mask);
vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_FIRST, OCELOT_VCAP_BIT_1);
vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_HOST_MATCH,
OCELOT_VCAP_BIT_ANY);
- vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_MC, ace->dmac_mc);
- vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_BC, ace->dmac_bc);
+ vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_MC, filter->dmac_mc);
+ vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_BC, filter->dmac_bc);
vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged);
vcap_key_set(ocelot, &data, VCAP_IS2_HK_VID,
tag->vid.value, tag->vid.mask);
@@ -373,9 +375,9 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
tag->pcp.value[0], tag->pcp.mask[0]);
vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DEI, tag->dei);
- switch (ace->type) {
- case OCELOT_ACE_TYPE_ETYPE: {
- struct ocelot_ace_frame_etype *etype = &ace->frame.etype;
+ switch (filter->key_type) {
+ case OCELOT_VCAP_KEY_ETYPE: {
+ struct ocelot_vcap_key_etype *etype = &filter->key.etype;
type = IS2_TYPE_ETYPE;
vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
@@ -396,8 +398,8 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
etype->data.value, etype->data.mask);
break;
}
- case OCELOT_ACE_TYPE_LLC: {
- struct ocelot_ace_frame_llc *llc = &ace->frame.llc;
+ case OCELOT_VCAP_KEY_LLC: {
+ struct ocelot_vcap_key_llc *llc = &filter->key.llc;
type = IS2_TYPE_LLC;
vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
@@ -412,8 +414,8 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
payload.value, payload.mask);
break;
}
- case OCELOT_ACE_TYPE_SNAP: {
- struct ocelot_ace_frame_snap *snap = &ace->frame.snap;
+ case OCELOT_VCAP_KEY_SNAP: {
+ struct ocelot_vcap_key_snap *snap = &filter->key.snap;
type = IS2_TYPE_SNAP;
vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
@@ -421,12 +423,12 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
snap->smac.value, snap->smac.mask);
vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
- ace->frame.snap.snap.value,
- ace->frame.snap.snap.mask);
+ filter->key.snap.snap.value,
+ filter->key.snap.snap.mask);
break;
}
- case OCELOT_ACE_TYPE_ARP: {
- struct ocelot_ace_frame_arp *arp = &ace->frame.arp;
+ case OCELOT_VCAP_KEY_ARP: {
+ struct ocelot_vcap_key_arp *arp = &filter->key.arp;
type = IS2_TYPE_ARP;
vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_SMAC,
@@ -467,20 +469,20 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
0, 0);
break;
}
- case OCELOT_ACE_TYPE_IPV4:
- case OCELOT_ACE_TYPE_IPV6: {
+ case OCELOT_VCAP_KEY_IPV4:
+ case OCELOT_VCAP_KEY_IPV6: {
enum ocelot_vcap_bit sip_eq_dip, sport_eq_dport, seq_zero, tcp;
enum ocelot_vcap_bit ttl, fragment, options, tcp_ack, tcp_urg;
enum ocelot_vcap_bit tcp_fin, tcp_syn, tcp_rst, tcp_psh;
- struct ocelot_ace_frame_ipv4 *ipv4 = NULL;
- struct ocelot_ace_frame_ipv6 *ipv6 = NULL;
+ struct ocelot_vcap_key_ipv4 *ipv4 = NULL;
+ struct ocelot_vcap_key_ipv6 *ipv6 = NULL;
struct ocelot_vcap_udp_tcp *sport, *dport;
struct ocelot_vcap_ipv4 sip, dip;
struct ocelot_vcap_u8 proto, ds;
struct ocelot_vcap_u48 *ip_data;
- if (ace->type == OCELOT_ACE_TYPE_IPV4) {
- ipv4 = &ace->frame.ipv4;
+ if (filter->key_type == OCELOT_VCAP_KEY_IPV4) {
+ ipv4 = &filter->key.ipv4;
ttl = ipv4->ttl;
fragment = ipv4->fragment;
options = ipv4->options;
@@ -501,7 +503,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
sport_eq_dport = ipv4->sport_eq_dport;
seq_zero = ipv4->seq_zero;
} else {
- ipv6 = &ace->frame.ipv6;
+ ipv6 = &filter->key.ipv6;
ttl = ipv6->ttl;
fragment = OCELOT_VCAP_BIT_ANY;
options = OCELOT_VCAP_BIT_ANY;
@@ -605,7 +607,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
}
break;
}
- case OCELOT_ACE_TYPE_ANY:
+ case OCELOT_VCAP_KEY_ANY:
default:
type = 0;
type_mask = 0;
@@ -621,9 +623,9 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
}
vcap_key_set(ocelot, &data, VCAP_IS2_TYPE, type, type_mask);
- is2_action_set(ocelot, &data, ace);
+ is2_action_set(ocelot, &data, filter);
vcap_data_set(data.counter, data.counter_offset,
- vcap_is2->counter_width, ace->stats.pkts);
+ vcap_is2->counter_width, filter->stats.pkts);
/* Write row */
vcap_entry2cache(ocelot, &data);
@@ -631,7 +633,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
vcap_row_cmd(ocelot, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
}
-static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule,
+static void is2_entry_get(struct ocelot *ocelot, struct ocelot_vcap_filter *filter,
int ix)
{
const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
@@ -646,55 +648,99 @@ static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule,
cnt = vcap_data_get(data.counter, data.counter_offset,
vcap_is2->counter_width);
- rule->stats.pkts = cnt;
+ filter->stats.pkts = cnt;
}
-static void ocelot_ace_rule_add(struct ocelot *ocelot,
- struct ocelot_acl_block *block,
- struct ocelot_ace_rule *rule)
+static int ocelot_vcap_policer_add(struct ocelot *ocelot, u32 pol_ix,
+ struct ocelot_policer *pol)
{
- struct ocelot_ace_rule *tmp;
+ struct qos_policer_conf pp = { 0 };
+
+ if (!pol)
+ return -EINVAL;
+
+ pp.mode = MSCC_QOS_RATE_MODE_DATA;
+ pp.pir = pol->rate;
+ pp.pbs = pol->burst;
+
+ return qos_policer_conf_set(ocelot, 0, pol_ix, &pp);
+}
+
+static void ocelot_vcap_policer_del(struct ocelot *ocelot,
+ struct ocelot_vcap_block *block,
+ u32 pol_ix)
+{
+ struct ocelot_vcap_filter *filter;
+ struct qos_policer_conf pp = {0};
+ int index = -1;
+
+ if (pol_ix < block->pol_lpr)
+ return;
+
+ list_for_each_entry(filter, &block->rules, list) {
+ index++;
+ if (filter->action == OCELOT_VCAP_ACTION_POLICE &&
+ filter->pol_ix < pol_ix) {
+ filter->pol_ix += 1;
+ ocelot_vcap_policer_add(ocelot, filter->pol_ix,
+ &filter->pol);
+ is2_entry_set(ocelot, index, filter);
+ }
+ }
+
+ pp.mode = MSCC_QOS_RATE_MODE_DISABLED;
+ qos_policer_conf_set(ocelot, 0, pol_ix, &pp);
+
+ block->pol_lpr++;
+}
+
+static void ocelot_vcap_filter_add_to_block(struct ocelot *ocelot,
+ struct ocelot_vcap_block *block,
+ struct ocelot_vcap_filter *filter)
+{
+ struct ocelot_vcap_filter *tmp;
struct list_head *pos, *n;
- if (rule->action == OCELOT_ACL_ACTION_POLICE) {
+ if (filter->action == OCELOT_VCAP_ACTION_POLICE) {
block->pol_lpr--;
- rule->pol_ix = block->pol_lpr;
- ocelot_ace_policer_add(ocelot, rule->pol_ix, &rule->pol);
+ filter->pol_ix = block->pol_lpr;
+ ocelot_vcap_policer_add(ocelot, filter->pol_ix, &filter->pol);
}
block->count++;
if (list_empty(&block->rules)) {
- list_add(&rule->list, &block->rules);
+ list_add(&filter->list, &block->rules);
return;
}
list_for_each_safe(pos, n, &block->rules) {
- tmp = list_entry(pos, struct ocelot_ace_rule, list);
- if (rule->prio < tmp->prio)
+ tmp = list_entry(pos, struct ocelot_vcap_filter, list);
+ if (filter->prio < tmp->prio)
break;
}
- list_add(&rule->list, pos->prev);
+ list_add(&filter->list, pos->prev);
}
-static int ocelot_ace_rule_get_index_id(struct ocelot_acl_block *block,
- struct ocelot_ace_rule *rule)
+static int ocelot_vcap_block_get_filter_index(struct ocelot_vcap_block *block,
+ struct ocelot_vcap_filter *filter)
{
- struct ocelot_ace_rule *tmp;
+ struct ocelot_vcap_filter *tmp;
int index = -1;
list_for_each_entry(tmp, &block->rules, list) {
++index;
- if (rule->id == tmp->id)
+ if (filter->id == tmp->id)
break;
}
return index;
}
-static struct ocelot_ace_rule*
-ocelot_ace_rule_get_rule_index(struct ocelot_acl_block *block, int index)
+static struct ocelot_vcap_filter*
+ocelot_vcap_block_find_filter(struct ocelot_vcap_block *block,
+ int index)
{
- struct ocelot_ace_rule *tmp;
+ struct ocelot_vcap_filter *tmp;
int i = 0;
list_for_each_entry(tmp, &block->rules, list) {
@@ -737,15 +783,16 @@ static void ocelot_match_all_as_mac_etype(struct ocelot *ocelot, int port,
ANA_PORT_VCAP_S2_CFG, port);
}
-static bool ocelot_ace_is_problematic_mac_etype(struct ocelot_ace_rule *ace)
+static bool
+ocelot_vcap_is_problematic_mac_etype(struct ocelot_vcap_filter *filter)
{
u16 proto, mask;
- if (ace->type != OCELOT_ACE_TYPE_ETYPE)
+ if (filter->key_type != OCELOT_VCAP_KEY_ETYPE)
return false;
- proto = ntohs(*(u16 *)ace->frame.etype.etype.value);
- mask = ntohs(*(u16 *)ace->frame.etype.etype.mask);
+ proto = ntohs(*(__be16 *)filter->key.etype.etype.value);
+ mask = ntohs(*(__be16 *)filter->key.etype.etype.mask);
/* ETH_P_ALL match, so all protocols below are included */
if (mask == 0)
@@ -760,49 +807,51 @@ static bool ocelot_ace_is_problematic_mac_etype(struct ocelot_ace_rule *ace)
return false;
}
-static bool ocelot_ace_is_problematic_non_mac_etype(struct ocelot_ace_rule *ace)
+static bool
+ocelot_vcap_is_problematic_non_mac_etype(struct ocelot_vcap_filter *filter)
{
- if (ace->type == OCELOT_ACE_TYPE_SNAP)
+ if (filter->key_type == OCELOT_VCAP_KEY_SNAP)
return true;
- if (ace->type == OCELOT_ACE_TYPE_ARP)
+ if (filter->key_type == OCELOT_VCAP_KEY_ARP)
return true;
- if (ace->type == OCELOT_ACE_TYPE_IPV4)
+ if (filter->key_type == OCELOT_VCAP_KEY_IPV4)
return true;
- if (ace->type == OCELOT_ACE_TYPE_IPV6)
+ if (filter->key_type == OCELOT_VCAP_KEY_IPV6)
return true;
return false;
}
-static bool ocelot_exclusive_mac_etype_ace_rules(struct ocelot *ocelot,
- struct ocelot_ace_rule *ace)
+static bool
+ocelot_exclusive_mac_etype_filter_rules(struct ocelot *ocelot,
+ struct ocelot_vcap_filter *filter)
{
- struct ocelot_acl_block *block = &ocelot->acl_block;
- struct ocelot_ace_rule *tmp;
+ struct ocelot_vcap_block *block = &ocelot->block;
+ struct ocelot_vcap_filter *tmp;
unsigned long port;
int i;
- if (ocelot_ace_is_problematic_mac_etype(ace)) {
+ if (ocelot_vcap_is_problematic_mac_etype(filter)) {
/* Search for any non-MAC_ETYPE rules on the port */
for (i = 0; i < block->count; i++) {
- tmp = ocelot_ace_rule_get_rule_index(block, i);
- if (tmp->ingress_port_mask & ace->ingress_port_mask &&
- ocelot_ace_is_problematic_non_mac_etype(tmp))
+ tmp = ocelot_vcap_block_find_filter(block, i);
+ if (tmp->ingress_port_mask & filter->ingress_port_mask &&
+ ocelot_vcap_is_problematic_non_mac_etype(tmp))
return false;
}
- for_each_set_bit(port, &ace->ingress_port_mask,
+ for_each_set_bit(port, &filter->ingress_port_mask,
ocelot->num_phys_ports)
ocelot_match_all_as_mac_etype(ocelot, port, true);
- } else if (ocelot_ace_is_problematic_non_mac_etype(ace)) {
+ } else if (ocelot_vcap_is_problematic_non_mac_etype(filter)) {
/* Search for any MAC_ETYPE rules on the port */
for (i = 0; i < block->count; i++) {
- tmp = ocelot_ace_rule_get_rule_index(block, i);
- if (tmp->ingress_port_mask & ace->ingress_port_mask &&
- ocelot_ace_is_problematic_mac_etype(tmp))
+ tmp = ocelot_vcap_block_find_filter(block, i);
+ if (tmp->ingress_port_mask & filter->ingress_port_mask &&
+ ocelot_vcap_is_problematic_mac_etype(tmp))
return false;
}
- for_each_set_bit(port, &ace->ingress_port_mask,
+ for_each_set_bit(port, &filter->ingress_port_mask,
ocelot->num_phys_ports)
ocelot_match_all_as_mac_etype(ocelot, port, false);
}
@@ -810,75 +859,51 @@ static bool ocelot_exclusive_mac_etype_ace_rules(struct ocelot *ocelot,
return true;
}
-int ocelot_ace_rule_offload_add(struct ocelot *ocelot,
- struct ocelot_ace_rule *rule,
- struct netlink_ext_ack *extack)
+int ocelot_vcap_filter_add(struct ocelot *ocelot,
+ struct ocelot_vcap_filter *filter,
+ struct netlink_ext_ack *extack)
{
- struct ocelot_acl_block *block = &ocelot->acl_block;
- struct ocelot_ace_rule *ace;
+ struct ocelot_vcap_block *block = &ocelot->block;
int i, index;
- if (!ocelot_exclusive_mac_etype_ace_rules(ocelot, rule)) {
+ if (!ocelot_exclusive_mac_etype_filter_rules(ocelot, filter)) {
NL_SET_ERR_MSG_MOD(extack,
"Cannot mix MAC_ETYPE with non-MAC_ETYPE rules");
return -EBUSY;
}
- /* Add rule to the linked list */
- ocelot_ace_rule_add(ocelot, block, rule);
+ /* Add filter to the linked list */
+ ocelot_vcap_filter_add_to_block(ocelot, block, filter);
- /* Get the index of the inserted rule */
- index = ocelot_ace_rule_get_index_id(block, rule);
+ /* Get the index of the inserted filter */
+ index = ocelot_vcap_block_get_filter_index(block, filter);
- /* Move down the rules to make place for the new rule */
+ /* Move down the rules to make place for the new filter */
for (i = block->count - 1; i > index; i--) {
- ace = ocelot_ace_rule_get_rule_index(block, i);
- is2_entry_set(ocelot, i, ace);
- }
-
- /* Now insert the new rule */
- is2_entry_set(ocelot, index, rule);
- return 0;
-}
-
-static void ocelot_ace_police_del(struct ocelot *ocelot,
- struct ocelot_acl_block *block,
- u32 ix)
-{
- struct ocelot_ace_rule *ace;
- int index = -1;
-
- if (ix < block->pol_lpr)
- return;
+ struct ocelot_vcap_filter *tmp;
- list_for_each_entry(ace, &block->rules, list) {
- index++;
- if (ace->action == OCELOT_ACL_ACTION_POLICE &&
- ace->pol_ix < ix) {
- ace->pol_ix += 1;
- ocelot_ace_policer_add(ocelot, ace->pol_ix,
- &ace->pol);
- is2_entry_set(ocelot, index, ace);
- }
+ tmp = ocelot_vcap_block_find_filter(block, i);
+ is2_entry_set(ocelot, i, tmp);
}
- ocelot_ace_policer_del(ocelot, block->pol_lpr);
- block->pol_lpr++;
+ /* Now insert the new filter */
+ is2_entry_set(ocelot, index, filter);
+ return 0;
}
-static void ocelot_ace_rule_del(struct ocelot *ocelot,
- struct ocelot_acl_block *block,
- struct ocelot_ace_rule *rule)
+static void ocelot_vcap_block_remove_filter(struct ocelot *ocelot,
+ struct ocelot_vcap_block *block,
+ struct ocelot_vcap_filter *filter)
{
- struct ocelot_ace_rule *tmp;
+ struct ocelot_vcap_filter *tmp;
struct list_head *pos, *q;
list_for_each_safe(pos, q, &block->rules) {
- tmp = list_entry(pos, struct ocelot_ace_rule, list);
- if (tmp->id == rule->id) {
- if (tmp->action == OCELOT_ACL_ACTION_POLICE)
- ocelot_ace_police_del(ocelot, block,
- tmp->pol_ix);
+ tmp = list_entry(pos, struct ocelot_vcap_filter, list);
+ if (tmp->id == filter->id) {
+ if (tmp->action == OCELOT_VCAP_ACTION_POLICE)
+ ocelot_vcap_policer_del(ocelot, block,
+ tmp->pol_ix);
list_del(pos);
kfree(tmp);
@@ -888,56 +913,57 @@ static void ocelot_ace_rule_del(struct ocelot *ocelot,
block->count--;
}
-int ocelot_ace_rule_offload_del(struct ocelot *ocelot,
- struct ocelot_ace_rule *rule)
+int ocelot_vcap_filter_del(struct ocelot *ocelot,
+ struct ocelot_vcap_filter *filter)
{
- struct ocelot_acl_block *block = &ocelot->acl_block;
- struct ocelot_ace_rule del_ace;
- struct ocelot_ace_rule *ace;
+ struct ocelot_vcap_block *block = &ocelot->block;
+ struct ocelot_vcap_filter del_filter;
int i, index;
- memset(&del_ace, 0, sizeof(del_ace));
+ memset(&del_filter, 0, sizeof(del_filter));
- /* Gets index of the rule */
- index = ocelot_ace_rule_get_index_id(block, rule);
+ /* Gets index of the filter */
+ index = ocelot_vcap_block_get_filter_index(block, filter);
- /* Delete rule */
- ocelot_ace_rule_del(ocelot, block, rule);
+ /* Delete filter */
+ ocelot_vcap_block_remove_filter(ocelot, block, filter);
- /* Move up all the blocks over the deleted rule */
+ /* Move up all the blocks over the deleted filter */
for (i = index; i < block->count; i++) {
- ace = ocelot_ace_rule_get_rule_index(block, i);
- is2_entry_set(ocelot, i, ace);
+ struct ocelot_vcap_filter *tmp;
+
+ tmp = ocelot_vcap_block_find_filter(block, i);
+ is2_entry_set(ocelot, i, tmp);
}
- /* Now delete the last rule, because it is duplicated */
- is2_entry_set(ocelot, block->count, &del_ace);
+ /* Now delete the last filter, because it is duplicated */
+ is2_entry_set(ocelot, block->count, &del_filter);
return 0;
}
-int ocelot_ace_rule_stats_update(struct ocelot *ocelot,
- struct ocelot_ace_rule *rule)
+int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
+ struct ocelot_vcap_filter *filter)
{
- struct ocelot_acl_block *block = &ocelot->acl_block;
- struct ocelot_ace_rule *tmp;
+ struct ocelot_vcap_block *block = &ocelot->block;
+ struct ocelot_vcap_filter *tmp;
int index;
- index = ocelot_ace_rule_get_index_id(block, rule);
- is2_entry_get(ocelot, rule, index);
+ index = ocelot_vcap_block_get_filter_index(block, filter);
+ is2_entry_get(ocelot, filter, index);
/* After we get the result we need to clear the counters */
- tmp = ocelot_ace_rule_get_rule_index(block, index);
+ tmp = ocelot_vcap_block_find_filter(block, index);
tmp->stats.pkts = 0;
is2_entry_set(ocelot, index, tmp);
return 0;
}
-int ocelot_ace_init(struct ocelot *ocelot)
+int ocelot_vcap_init(struct ocelot *ocelot)
{
const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
- struct ocelot_acl_block *block = &ocelot->acl_block;
+ struct ocelot_vcap_block *block = &ocelot->block;
struct vcap_data data;
memset(&data, 0, sizeof(data));
@@ -968,7 +994,7 @@ int ocelot_ace_init(struct ocelot *ocelot)
block->pol_lpr = OCELOT_POLICER_DISCARD - 1;
- INIT_LIST_HEAD(&ocelot->acl_block.rules);
+ INIT_LIST_HEAD(&ocelot->block.rules);
return 0;
}
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_vcap.h
index 099e177f2617..0dfbfc011b2e 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.h
+++ b/drivers/net/ethernet/mscc/ocelot_vcap.h
@@ -3,8 +3,8 @@
* Copyright (c) 2019 Microsemi Corporation
*/
-#ifndef _MSCC_OCELOT_ACE_H_
-#define _MSCC_OCELOT_ACE_H_
+#ifndef _MSCC_OCELOT_VCAP_H_
+#define _MSCC_OCELOT_VCAP_H_
#include "ocelot.h"
#include "ocelot_police.h"
@@ -76,31 +76,31 @@ struct ocelot_vcap_udp_tcp {
u16 mask;
};
-enum ocelot_ace_type {
- OCELOT_ACE_TYPE_ANY,
- OCELOT_ACE_TYPE_ETYPE,
- OCELOT_ACE_TYPE_LLC,
- OCELOT_ACE_TYPE_SNAP,
- OCELOT_ACE_TYPE_ARP,
- OCELOT_ACE_TYPE_IPV4,
- OCELOT_ACE_TYPE_IPV6
+enum ocelot_vcap_key_type {
+ OCELOT_VCAP_KEY_ANY,
+ OCELOT_VCAP_KEY_ETYPE,
+ OCELOT_VCAP_KEY_LLC,
+ OCELOT_VCAP_KEY_SNAP,
+ OCELOT_VCAP_KEY_ARP,
+ OCELOT_VCAP_KEY_IPV4,
+ OCELOT_VCAP_KEY_IPV6
};
-struct ocelot_ace_vlan {
+struct ocelot_vcap_key_vlan {
struct ocelot_vcap_vid vid; /* VLAN ID (12 bit) */
struct ocelot_vcap_u8 pcp; /* PCP (3 bit) */
enum ocelot_vcap_bit dei; /* DEI */
enum ocelot_vcap_bit tagged; /* Tagged/untagged frame */
};
-struct ocelot_ace_frame_etype {
+struct ocelot_vcap_key_etype {
struct ocelot_vcap_u48 dmac;
struct ocelot_vcap_u48 smac;
struct ocelot_vcap_u16 etype;
struct ocelot_vcap_u16 data; /* MAC data */
};
-struct ocelot_ace_frame_llc {
+struct ocelot_vcap_key_llc {
struct ocelot_vcap_u48 dmac;
struct ocelot_vcap_u48 smac;
@@ -108,7 +108,7 @@ struct ocelot_ace_frame_llc {
struct ocelot_vcap_u32 llc;
};
-struct ocelot_ace_frame_snap {
+struct ocelot_vcap_key_snap {
struct ocelot_vcap_u48 dmac;
struct ocelot_vcap_u48 smac;
@@ -116,7 +116,7 @@ struct ocelot_ace_frame_snap {
struct ocelot_vcap_u40 snap;
};
-struct ocelot_ace_frame_arp {
+struct ocelot_vcap_key_arp {
struct ocelot_vcap_u48 smac;
enum ocelot_vcap_bit arp; /* Opcode ARP/RARP */
enum ocelot_vcap_bit req; /* Opcode request/reply */
@@ -133,7 +133,7 @@ struct ocelot_ace_frame_arp {
struct ocelot_vcap_ipv4 dip; /* Target IP address */
};
-struct ocelot_ace_frame_ipv4 {
+struct ocelot_vcap_key_ipv4 {
enum ocelot_vcap_bit ttl; /* TTL zero */
enum ocelot_vcap_bit fragment; /* Fragment */
enum ocelot_vcap_bit options; /* Header options */
@@ -155,7 +155,7 @@ struct ocelot_ace_frame_ipv4 {
enum ocelot_vcap_bit seq_zero; /* TCP sequence number is zero */
};
-struct ocelot_ace_frame_ipv6 {
+struct ocelot_vcap_key_ipv6 {
struct ocelot_vcap_u8 proto; /* IPv6 protocol */
struct ocelot_vcap_u128 sip; /* IPv6 source (byte 0-7 ignored) */
enum ocelot_vcap_bit ttl; /* TTL zero */
@@ -174,58 +174,58 @@ struct ocelot_ace_frame_ipv6 {
enum ocelot_vcap_bit seq_zero; /* TCP sequence number is zero */
};
-enum ocelot_ace_action {
- OCELOT_ACL_ACTION_DROP,
- OCELOT_ACL_ACTION_TRAP,
- OCELOT_ACL_ACTION_POLICE,
+enum ocelot_vcap_action {
+ OCELOT_VCAP_ACTION_DROP,
+ OCELOT_VCAP_ACTION_TRAP,
+ OCELOT_VCAP_ACTION_POLICE,
};
-struct ocelot_ace_stats {
+struct ocelot_vcap_stats {
u64 bytes;
u64 pkts;
u64 used;
};
-struct ocelot_ace_rule {
+struct ocelot_vcap_filter {
struct list_head list;
u16 prio;
u32 id;
- enum ocelot_ace_action action;
- struct ocelot_ace_stats stats;
+ enum ocelot_vcap_action action;
+ struct ocelot_vcap_stats stats;
unsigned long ingress_port_mask;
enum ocelot_vcap_bit dmac_mc;
enum ocelot_vcap_bit dmac_bc;
- struct ocelot_ace_vlan vlan;
+ struct ocelot_vcap_key_vlan vlan;
- enum ocelot_ace_type type;
+ enum ocelot_vcap_key_type key_type;
union {
- /* ocelot_ACE_TYPE_ANY: No specific fields */
- struct ocelot_ace_frame_etype etype;
- struct ocelot_ace_frame_llc llc;
- struct ocelot_ace_frame_snap snap;
- struct ocelot_ace_frame_arp arp;
- struct ocelot_ace_frame_ipv4 ipv4;
- struct ocelot_ace_frame_ipv6 ipv6;
- } frame;
+ /* OCELOT_VCAP_KEY_ANY: No specific fields */
+ struct ocelot_vcap_key_etype etype;
+ struct ocelot_vcap_key_llc llc;
+ struct ocelot_vcap_key_snap snap;
+ struct ocelot_vcap_key_arp arp;
+ struct ocelot_vcap_key_ipv4 ipv4;
+ struct ocelot_vcap_key_ipv6 ipv6;
+ } key;
struct ocelot_policer pol;
u32 pol_ix;
};
-int ocelot_ace_rule_offload_add(struct ocelot *ocelot,
- struct ocelot_ace_rule *rule,
- struct netlink_ext_ack *extack);
-int ocelot_ace_rule_offload_del(struct ocelot *ocelot,
- struct ocelot_ace_rule *rule);
-int ocelot_ace_rule_stats_update(struct ocelot *ocelot,
- struct ocelot_ace_rule *rule);
+int ocelot_vcap_filter_add(struct ocelot *ocelot,
+ struct ocelot_vcap_filter *rule,
+ struct netlink_ext_ack *extack);
+int ocelot_vcap_filter_del(struct ocelot *ocelot,
+ struct ocelot_vcap_filter *rule);
+int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
+ struct ocelot_vcap_filter *rule);
-int ocelot_ace_init(struct ocelot *ocelot);
+int ocelot_vcap_init(struct ocelot *ocelot);
int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
struct flow_cls_offload *f,
bool ingress);
-#endif /* _MSCC_OCELOT_ACE_H_ */
+#endif /* _MSCC_OCELOT_VCAP_H_ */
diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
new file mode 100644
index 000000000000..65408bc994c4
--- /dev/null
+++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
@@ -0,0 +1,1138 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2017 Microsemi Corporation
+ */
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_net.h>
+#include <linux/netdevice.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <linux/mfd/syscon.h>
+#include <linux/skbuff.h>
+#include <net/switchdev.h>
+
+#include <soc/mscc/ocelot_vcap.h>
+#include <soc/mscc/ocelot_hsio.h>
+#include "ocelot.h"
+
+#define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
+#define VSC7514_VCAP_IS2_CNT 64
+#define VSC7514_VCAP_IS2_ENTRY_WIDTH 376
+#define VSC7514_VCAP_IS2_ACTION_WIDTH 99
+#define VSC7514_VCAP_PORT_CNT 11
+
+static const u32 ocelot_ana_regmap[] = {
+ REG(ANA_ADVLEARN, 0x009000),
+ REG(ANA_VLANMASK, 0x009004),
+ REG(ANA_PORT_B_DOMAIN, 0x009008),
+ REG(ANA_ANAGEFIL, 0x00900c),
+ REG(ANA_ANEVENTS, 0x009010),
+ REG(ANA_STORMLIMIT_BURST, 0x009014),
+ REG(ANA_STORMLIMIT_CFG, 0x009018),
+ REG(ANA_ISOLATED_PORTS, 0x009028),
+ REG(ANA_COMMUNITY_PORTS, 0x00902c),
+ REG(ANA_AUTOAGE, 0x009030),
+ REG(ANA_MACTOPTIONS, 0x009034),
+ REG(ANA_LEARNDISC, 0x009038),
+ REG(ANA_AGENCTRL, 0x00903c),
+ REG(ANA_MIRRORPORTS, 0x009040),
+ REG(ANA_EMIRRORPORTS, 0x009044),
+ REG(ANA_FLOODING, 0x009048),
+ REG(ANA_FLOODING_IPMC, 0x00904c),
+ REG(ANA_SFLOW_CFG, 0x009050),
+ REG(ANA_PORT_MODE, 0x009080),
+ REG(ANA_PGID_PGID, 0x008c00),
+ REG(ANA_TABLES_ANMOVED, 0x008b30),
+ REG(ANA_TABLES_MACHDATA, 0x008b34),
+ REG(ANA_TABLES_MACLDATA, 0x008b38),
+ REG(ANA_TABLES_MACACCESS, 0x008b3c),
+ REG(ANA_TABLES_MACTINDX, 0x008b40),
+ REG(ANA_TABLES_VLANACCESS, 0x008b44),
+ REG(ANA_TABLES_VLANTIDX, 0x008b48),
+ REG(ANA_TABLES_ISDXACCESS, 0x008b4c),
+ REG(ANA_TABLES_ISDXTIDX, 0x008b50),
+ REG(ANA_TABLES_ENTRYLIM, 0x008b00),
+ REG(ANA_TABLES_PTP_ID_HIGH, 0x008b54),
+ REG(ANA_TABLES_PTP_ID_LOW, 0x008b58),
+ REG(ANA_MSTI_STATE, 0x008e00),
+ REG(ANA_PORT_VLAN_CFG, 0x007000),
+ REG(ANA_PORT_DROP_CFG, 0x007004),
+ REG(ANA_PORT_QOS_CFG, 0x007008),
+ REG(ANA_PORT_VCAP_CFG, 0x00700c),
+ REG(ANA_PORT_VCAP_S1_KEY_CFG, 0x007010),
+ REG(ANA_PORT_VCAP_S2_CFG, 0x00701c),
+ REG(ANA_PORT_PCP_DEI_MAP, 0x007020),
+ REG(ANA_PORT_CPU_FWD_CFG, 0x007060),
+ REG(ANA_PORT_CPU_FWD_BPDU_CFG, 0x007064),
+ REG(ANA_PORT_CPU_FWD_GARP_CFG, 0x007068),
+ REG(ANA_PORT_CPU_FWD_CCM_CFG, 0x00706c),
+ REG(ANA_PORT_PORT_CFG, 0x007070),
+ REG(ANA_PORT_POL_CFG, 0x007074),
+ REG(ANA_PORT_PTP_CFG, 0x007078),
+ REG(ANA_PORT_PTP_DLY1_CFG, 0x00707c),
+ REG(ANA_OAM_UPM_LM_CNT, 0x007c00),
+ REG(ANA_PORT_PTP_DLY2_CFG, 0x007080),
+ REG(ANA_PFC_PFC_CFG, 0x008800),
+ REG(ANA_PFC_PFC_TIMER, 0x008804),
+ REG(ANA_IPT_OAM_MEP_CFG, 0x008000),
+ REG(ANA_IPT_IPT, 0x008004),
+ REG(ANA_PPT_PPT, 0x008ac0),
+ REG(ANA_FID_MAP_FID_MAP, 0x000000),
+ REG(ANA_AGGR_CFG, 0x0090b4),
+ REG(ANA_CPUQ_CFG, 0x0090b8),
+ REG(ANA_CPUQ_CFG2, 0x0090bc),
+ REG(ANA_CPUQ_8021_CFG, 0x0090c0),
+ REG(ANA_DSCP_CFG, 0x009100),
+ REG(ANA_DSCP_REWR_CFG, 0x009200),
+ REG(ANA_VCAP_RNG_TYPE_CFG, 0x009240),
+ REG(ANA_VCAP_RNG_VAL_CFG, 0x009260),
+ REG(ANA_VRAP_CFG, 0x009280),
+ REG(ANA_VRAP_HDR_DATA, 0x009284),
+ REG(ANA_VRAP_HDR_MASK, 0x009288),
+ REG(ANA_DISCARD_CFG, 0x00928c),
+ REG(ANA_FID_CFG, 0x009290),
+ REG(ANA_POL_PIR_CFG, 0x004000),
+ REG(ANA_POL_CIR_CFG, 0x004004),
+ REG(ANA_POL_MODE_CFG, 0x004008),
+ REG(ANA_POL_PIR_STATE, 0x00400c),
+ REG(ANA_POL_CIR_STATE, 0x004010),
+ REG(ANA_POL_STATE, 0x004014),
+ REG(ANA_POL_FLOWC, 0x008b80),
+ REG(ANA_POL_HYST, 0x008bec),
+ REG(ANA_POL_MISC_CFG, 0x008bf0),
+};
+
+static const u32 ocelot_qs_regmap[] = {
+ REG(QS_XTR_GRP_CFG, 0x000000),
+ REG(QS_XTR_RD, 0x000008),
+ REG(QS_XTR_FRM_PRUNING, 0x000010),
+ REG(QS_XTR_FLUSH, 0x000018),
+ REG(QS_XTR_DATA_PRESENT, 0x00001c),
+ REG(QS_XTR_CFG, 0x000020),
+ REG(QS_INJ_GRP_CFG, 0x000024),
+ REG(QS_INJ_WR, 0x00002c),
+ REG(QS_INJ_CTRL, 0x000034),
+ REG(QS_INJ_STATUS, 0x00003c),
+ REG(QS_INJ_ERR, 0x000040),
+ REG(QS_INH_DBG, 0x000048),
+};
+
+static const u32 ocelot_qsys_regmap[] = {
+ REG(QSYS_PORT_MODE, 0x011200),
+ REG(QSYS_SWITCH_PORT_MODE, 0x011234),
+ REG(QSYS_STAT_CNT_CFG, 0x011264),
+ REG(QSYS_EEE_CFG, 0x011268),
+ REG(QSYS_EEE_THRES, 0x011294),
+ REG(QSYS_IGR_NO_SHARING, 0x011298),
+ REG(QSYS_EGR_NO_SHARING, 0x01129c),
+ REG(QSYS_SW_STATUS, 0x0112a0),
+ REG(QSYS_EXT_CPU_CFG, 0x0112d0),
+ REG(QSYS_PAD_CFG, 0x0112d4),
+ REG(QSYS_CPU_GROUP_MAP, 0x0112d8),
+ REG(QSYS_QMAP, 0x0112dc),
+ REG(QSYS_ISDX_SGRP, 0x011400),
+ REG(QSYS_TIMED_FRAME_ENTRY, 0x014000),
+ REG(QSYS_TFRM_MISC, 0x011310),
+ REG(QSYS_TFRM_PORT_DLY, 0x011314),
+ REG(QSYS_TFRM_TIMER_CFG_1, 0x011318),
+ REG(QSYS_TFRM_TIMER_CFG_2, 0x01131c),
+ REG(QSYS_TFRM_TIMER_CFG_3, 0x011320),
+ REG(QSYS_TFRM_TIMER_CFG_4, 0x011324),
+ REG(QSYS_TFRM_TIMER_CFG_5, 0x011328),
+ REG(QSYS_TFRM_TIMER_CFG_6, 0x01132c),
+ REG(QSYS_TFRM_TIMER_CFG_7, 0x011330),
+ REG(QSYS_TFRM_TIMER_CFG_8, 0x011334),
+ REG(QSYS_RED_PROFILE, 0x011338),
+ REG(QSYS_RES_QOS_MODE, 0x011378),
+ REG(QSYS_RES_CFG, 0x012000),
+ REG(QSYS_RES_STAT, 0x012004),
+ REG(QSYS_EGR_DROP_MODE, 0x01137c),
+ REG(QSYS_EQ_CTRL, 0x011380),
+ REG(QSYS_EVENTS_CORE, 0x011384),
+ REG(QSYS_CIR_CFG, 0x000000),
+ REG(QSYS_EIR_CFG, 0x000004),
+ REG(QSYS_SE_CFG, 0x000008),
+ REG(QSYS_SE_DWRR_CFG, 0x00000c),
+ REG(QSYS_SE_CONNECT, 0x00003c),
+ REG(QSYS_SE_DLB_SENSE, 0x000040),
+ REG(QSYS_CIR_STATE, 0x000044),
+ REG(QSYS_EIR_STATE, 0x000048),
+ REG(QSYS_SE_STATE, 0x00004c),
+ REG(QSYS_HSCH_MISC_CFG, 0x011388),
+};
+
+static const u32 ocelot_rew_regmap[] = {
+ REG(REW_PORT_VLAN_CFG, 0x000000),
+ REG(REW_TAG_CFG, 0x000004),
+ REG(REW_PORT_CFG, 0x000008),
+ REG(REW_DSCP_CFG, 0x00000c),
+ REG(REW_PCP_DEI_QOS_MAP_CFG, 0x000010),
+ REG(REW_PTP_CFG, 0x000050),
+ REG(REW_PTP_DLY1_CFG, 0x000054),
+ REG(REW_DSCP_REMAP_DP1_CFG, 0x000690),
+ REG(REW_DSCP_REMAP_CFG, 0x000790),
+ REG(REW_STAT_CFG, 0x000890),
+ REG(REW_PPT, 0x000680),
+};
+
+static const u32 ocelot_sys_regmap[] = {
+ REG(SYS_COUNT_RX_OCTETS, 0x000000),
+ REG(SYS_COUNT_RX_UNICAST, 0x000004),
+ REG(SYS_COUNT_RX_MULTICAST, 0x000008),
+ REG(SYS_COUNT_RX_BROADCAST, 0x00000c),
+ REG(SYS_COUNT_RX_SHORTS, 0x000010),
+ REG(SYS_COUNT_RX_FRAGMENTS, 0x000014),
+ REG(SYS_COUNT_RX_JABBERS, 0x000018),
+ REG(SYS_COUNT_RX_CRC_ALIGN_ERRS, 0x00001c),
+ REG(SYS_COUNT_RX_SYM_ERRS, 0x000020),
+ REG(SYS_COUNT_RX_64, 0x000024),
+ REG(SYS_COUNT_RX_65_127, 0x000028),
+ REG(SYS_COUNT_RX_128_255, 0x00002c),
+ REG(SYS_COUNT_RX_256_1023, 0x000030),
+ REG(SYS_COUNT_RX_1024_1526, 0x000034),
+ REG(SYS_COUNT_RX_1527_MAX, 0x000038),
+ REG(SYS_COUNT_RX_PAUSE, 0x00003c),
+ REG(SYS_COUNT_RX_CONTROL, 0x000040),
+ REG(SYS_COUNT_RX_LONGS, 0x000044),
+ REG(SYS_COUNT_RX_CLASSIFIED_DROPS, 0x000048),
+ REG(SYS_COUNT_TX_OCTETS, 0x000100),
+ REG(SYS_COUNT_TX_UNICAST, 0x000104),
+ REG(SYS_COUNT_TX_MULTICAST, 0x000108),
+ REG(SYS_COUNT_TX_BROADCAST, 0x00010c),
+ REG(SYS_COUNT_TX_COLLISION, 0x000110),
+ REG(SYS_COUNT_TX_DROPS, 0x000114),
+ REG(SYS_COUNT_TX_PAUSE, 0x000118),
+ REG(SYS_COUNT_TX_64, 0x00011c),
+ REG(SYS_COUNT_TX_65_127, 0x000120),
+ REG(SYS_COUNT_TX_128_511, 0x000124),
+ REG(SYS_COUNT_TX_512_1023, 0x000128),
+ REG(SYS_COUNT_TX_1024_1526, 0x00012c),
+ REG(SYS_COUNT_TX_1527_MAX, 0x000130),
+ REG(SYS_COUNT_TX_AGING, 0x000170),
+ REG(SYS_RESET_CFG, 0x000508),
+ REG(SYS_CMID, 0x00050c),
+ REG(SYS_VLAN_ETYPE_CFG, 0x000510),
+ REG(SYS_PORT_MODE, 0x000514),
+ REG(SYS_FRONT_PORT_MODE, 0x000548),
+ REG(SYS_FRM_AGING, 0x000574),
+ REG(SYS_STAT_CFG, 0x000578),
+ REG(SYS_SW_STATUS, 0x00057c),
+ REG(SYS_MISC_CFG, 0x0005ac),
+ REG(SYS_REW_MAC_HIGH_CFG, 0x0005b0),
+ REG(SYS_REW_MAC_LOW_CFG, 0x0005dc),
+ REG(SYS_CM_ADDR, 0x000500),
+ REG(SYS_CM_DATA, 0x000504),
+ REG(SYS_PAUSE_CFG, 0x000608),
+ REG(SYS_PAUSE_TOT_CFG, 0x000638),
+ REG(SYS_ATOP, 0x00063c),
+ REG(SYS_ATOP_TOT_CFG, 0x00066c),
+ REG(SYS_MAC_FC_CFG, 0x000670),
+ REG(SYS_MMGT, 0x00069c),
+ REG(SYS_MMGT_FAST, 0x0006a0),
+ REG(SYS_EVENTS_DIF, 0x0006a4),
+ REG(SYS_EVENTS_CORE, 0x0006b4),
+ REG(SYS_CNT, 0x000000),
+ REG(SYS_PTP_STATUS, 0x0006b8),
+ REG(SYS_PTP_TXSTAMP, 0x0006bc),
+ REG(SYS_PTP_NXT, 0x0006c0),
+ REG(SYS_PTP_CFG, 0x0006c4),
+};
+
+static const u32 ocelot_s2_regmap[] = {
+ REG(S2_CORE_UPDATE_CTRL, 0x000000),
+ REG(S2_CORE_MV_CFG, 0x000004),
+ REG(S2_CACHE_ENTRY_DAT, 0x000008),
+ REG(S2_CACHE_MASK_DAT, 0x000108),
+ REG(S2_CACHE_ACTION_DAT, 0x000208),
+ REG(S2_CACHE_CNT_DAT, 0x000308),
+ REG(S2_CACHE_TG_DAT, 0x000388),
+};
+
+static const u32 ocelot_ptp_regmap[] = {
+ REG(PTP_PIN_CFG, 0x000000),
+ REG(PTP_PIN_TOD_SEC_MSB, 0x000004),
+ REG(PTP_PIN_TOD_SEC_LSB, 0x000008),
+ REG(PTP_PIN_TOD_NSEC, 0x00000c),
+ REG(PTP_PIN_WF_HIGH_PERIOD, 0x000014),
+ REG(PTP_PIN_WF_LOW_PERIOD, 0x000018),
+ REG(PTP_CFG_MISC, 0x0000a0),
+ REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4),
+ REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8),
+};
+
+static const u32 ocelot_dev_gmii_regmap[] = {
+ REG(DEV_CLOCK_CFG, 0x0),
+ REG(DEV_PORT_MISC, 0x4),
+ REG(DEV_EVENTS, 0x8),
+ REG(DEV_EEE_CFG, 0xc),
+ REG(DEV_RX_PATH_DELAY, 0x10),
+ REG(DEV_TX_PATH_DELAY, 0x14),
+ REG(DEV_PTP_PREDICT_CFG, 0x18),
+ REG(DEV_MAC_ENA_CFG, 0x1c),
+ REG(DEV_MAC_MODE_CFG, 0x20),
+ REG(DEV_MAC_MAXLEN_CFG, 0x24),
+ REG(DEV_MAC_TAGS_CFG, 0x28),
+ REG(DEV_MAC_ADV_CHK_CFG, 0x2c),
+ REG(DEV_MAC_IFG_CFG, 0x30),
+ REG(DEV_MAC_HDX_CFG, 0x34),
+ REG(DEV_MAC_DBG_CFG, 0x38),
+ REG(DEV_MAC_FC_MAC_LOW_CFG, 0x3c),
+ REG(DEV_MAC_FC_MAC_HIGH_CFG, 0x40),
+ REG(DEV_MAC_STICKY, 0x44),
+ REG(PCS1G_CFG, 0x48),
+ REG(PCS1G_MODE_CFG, 0x4c),
+ REG(PCS1G_SD_CFG, 0x50),
+ REG(PCS1G_ANEG_CFG, 0x54),
+ REG(PCS1G_ANEG_NP_CFG, 0x58),
+ REG(PCS1G_LB_CFG, 0x5c),
+ REG(PCS1G_DBG_CFG, 0x60),
+ REG(PCS1G_CDET_CFG, 0x64),
+ REG(PCS1G_ANEG_STATUS, 0x68),
+ REG(PCS1G_ANEG_NP_STATUS, 0x6c),
+ REG(PCS1G_LINK_STATUS, 0x70),
+ REG(PCS1G_LINK_DOWN_CNT, 0x74),
+ REG(PCS1G_STICKY, 0x78),
+ REG(PCS1G_DEBUG_STATUS, 0x7c),
+ REG(PCS1G_LPI_CFG, 0x80),
+ REG(PCS1G_LPI_WAKE_ERROR_CNT, 0x84),
+ REG(PCS1G_LPI_STATUS, 0x88),
+ REG(PCS1G_TSTPAT_MODE_CFG, 0x8c),
+ REG(PCS1G_TSTPAT_STATUS, 0x90),
+ REG(DEV_PCS_FX100_CFG, 0x94),
+ REG(DEV_PCS_FX100_STATUS, 0x98),
+};
+
+static const u32 *ocelot_regmap[TARGET_MAX] = {
+ [ANA] = ocelot_ana_regmap,
+ [QS] = ocelot_qs_regmap,
+ [QSYS] = ocelot_qsys_regmap,
+ [REW] = ocelot_rew_regmap,
+ [SYS] = ocelot_sys_regmap,
+ [S2] = ocelot_s2_regmap,
+ [PTP] = ocelot_ptp_regmap,
+ [DEV_GMII] = ocelot_dev_gmii_regmap,
+};
+
+static const struct reg_field ocelot_regfields[REGFIELD_MAX] = {
+ [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 11, 11),
+ [ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 10),
+ [ANA_ANEVENTS_MSTI_DROP] = REG_FIELD(ANA_ANEVENTS, 27, 27),
+ [ANA_ANEVENTS_ACLKILL] = REG_FIELD(ANA_ANEVENTS, 26, 26),
+ [ANA_ANEVENTS_ACLUSED] = REG_FIELD(ANA_ANEVENTS, 25, 25),
+ [ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24),
+ [ANA_ANEVENTS_VS2TTL1] = REG_FIELD(ANA_ANEVENTS, 23, 23),
+ [ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22),
+ [ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21),
+ [ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20),
+ [ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19),
+ [ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
+ [ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17),
+ [ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16),
+ [ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15),
+ [ANA_ANEVENTS_DROPPED] = REG_FIELD(ANA_ANEVENTS, 14, 14),
+ [ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13),
+ [ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12),
+ [ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
+ [ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
+ [ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9),
+ [ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8),
+ [ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7),
+ [ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
+ [ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
+ [ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4),
+ [ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3),
+ [ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2),
+ [ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1),
+ [ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0),
+ [ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 18, 18),
+ [ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 10, 11),
+ [ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 9),
+ [QSYS_TIMED_FRAME_ENTRY_TFRM_VLD] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 20, 20),
+ [QSYS_TIMED_FRAME_ENTRY_TFRM_FP] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 8, 19),
+ [QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 4, 7),
+ [QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 1, 3),
+ [QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 0, 0),
+ [SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 2, 2),
+ [SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 1, 1),
+ [SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 0, 0),
+ /* Replicated per number of ports (12), register size 4 per port */
+ [QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 14, 14, 12, 4),
+ [QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 11, 13, 12, 4),
+ [QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 12, 4),
+ [QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 12, 4),
+ [QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 12, 4),
+ [QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 12, 4),
+ [SYS_PORT_MODE_DATA_WO_TS] = REG_FIELD_ID(SYS_PORT_MODE, 5, 6, 12, 4),
+ [SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 3, 4, 12, 4),
+ [SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 1, 2, 12, 4),
+ [SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 12, 4),
+ [SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 10, 18, 12, 4),
+ [SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 9, 12, 4),
+ [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 12, 4),
+};
+
+static const struct ocelot_stat_layout ocelot_stats_layout[] = {
+ { .name = "rx_octets", .offset = 0x00, },
+ { .name = "rx_unicast", .offset = 0x01, },
+ { .name = "rx_multicast", .offset = 0x02, },
+ { .name = "rx_broadcast", .offset = 0x03, },
+ { .name = "rx_shorts", .offset = 0x04, },
+ { .name = "rx_fragments", .offset = 0x05, },
+ { .name = "rx_jabbers", .offset = 0x06, },
+ { .name = "rx_crc_align_errs", .offset = 0x07, },
+ { .name = "rx_sym_errs", .offset = 0x08, },
+ { .name = "rx_frames_below_65_octets", .offset = 0x09, },
+ { .name = "rx_frames_65_to_127_octets", .offset = 0x0A, },
+ { .name = "rx_frames_128_to_255_octets", .offset = 0x0B, },
+ { .name = "rx_frames_256_to_511_octets", .offset = 0x0C, },
+ { .name = "rx_frames_512_to_1023_octets", .offset = 0x0D, },
+ { .name = "rx_frames_1024_to_1526_octets", .offset = 0x0E, },
+ { .name = "rx_frames_over_1526_octets", .offset = 0x0F, },
+ { .name = "rx_pause", .offset = 0x10, },
+ { .name = "rx_control", .offset = 0x11, },
+ { .name = "rx_longs", .offset = 0x12, },
+ { .name = "rx_classified_drops", .offset = 0x13, },
+ { .name = "rx_red_prio_0", .offset = 0x14, },
+ { .name = "rx_red_prio_1", .offset = 0x15, },
+ { .name = "rx_red_prio_2", .offset = 0x16, },
+ { .name = "rx_red_prio_3", .offset = 0x17, },
+ { .name = "rx_red_prio_4", .offset = 0x18, },
+ { .name = "rx_red_prio_5", .offset = 0x19, },
+ { .name = "rx_red_prio_6", .offset = 0x1A, },
+ { .name = "rx_red_prio_7", .offset = 0x1B, },
+ { .name = "rx_yellow_prio_0", .offset = 0x1C, },
+ { .name = "rx_yellow_prio_1", .offset = 0x1D, },
+ { .name = "rx_yellow_prio_2", .offset = 0x1E, },
+ { .name = "rx_yellow_prio_3", .offset = 0x1F, },
+ { .name = "rx_yellow_prio_4", .offset = 0x20, },
+ { .name = "rx_yellow_prio_5", .offset = 0x21, },
+ { .name = "rx_yellow_prio_6", .offset = 0x22, },
+ { .name = "rx_yellow_prio_7", .offset = 0x23, },
+ { .name = "rx_green_prio_0", .offset = 0x24, },
+ { .name = "rx_green_prio_1", .offset = 0x25, },
+ { .name = "rx_green_prio_2", .offset = 0x26, },
+ { .name = "rx_green_prio_3", .offset = 0x27, },
+ { .name = "rx_green_prio_4", .offset = 0x28, },
+ { .name = "rx_green_prio_5", .offset = 0x29, },
+ { .name = "rx_green_prio_6", .offset = 0x2A, },
+ { .name = "rx_green_prio_7", .offset = 0x2B, },
+ { .name = "tx_octets", .offset = 0x40, },
+ { .name = "tx_unicast", .offset = 0x41, },
+ { .name = "tx_multicast", .offset = 0x42, },
+ { .name = "tx_broadcast", .offset = 0x43, },
+ { .name = "tx_collision", .offset = 0x44, },
+ { .name = "tx_drops", .offset = 0x45, },
+ { .name = "tx_pause", .offset = 0x46, },
+ { .name = "tx_frames_below_65_octets", .offset = 0x47, },
+ { .name = "tx_frames_65_to_127_octets", .offset = 0x48, },
+ { .name = "tx_frames_128_255_octets", .offset = 0x49, },
+ { .name = "tx_frames_256_511_octets", .offset = 0x4A, },
+ { .name = "tx_frames_512_1023_octets", .offset = 0x4B, },
+ { .name = "tx_frames_1024_1526_octets", .offset = 0x4C, },
+ { .name = "tx_frames_over_1526_octets", .offset = 0x4D, },
+ { .name = "tx_yellow_prio_0", .offset = 0x4E, },
+ { .name = "tx_yellow_prio_1", .offset = 0x4F, },
+ { .name = "tx_yellow_prio_2", .offset = 0x50, },
+ { .name = "tx_yellow_prio_3", .offset = 0x51, },
+ { .name = "tx_yellow_prio_4", .offset = 0x52, },
+ { .name = "tx_yellow_prio_5", .offset = 0x53, },
+ { .name = "tx_yellow_prio_6", .offset = 0x54, },
+ { .name = "tx_yellow_prio_7", .offset = 0x55, },
+ { .name = "tx_green_prio_0", .offset = 0x56, },
+ { .name = "tx_green_prio_1", .offset = 0x57, },
+ { .name = "tx_green_prio_2", .offset = 0x58, },
+ { .name = "tx_green_prio_3", .offset = 0x59, },
+ { .name = "tx_green_prio_4", .offset = 0x5A, },
+ { .name = "tx_green_prio_5", .offset = 0x5B, },
+ { .name = "tx_green_prio_6", .offset = 0x5C, },
+ { .name = "tx_green_prio_7", .offset = 0x5D, },
+ { .name = "tx_aged", .offset = 0x5E, },
+ { .name = "drop_local", .offset = 0x80, },
+ { .name = "drop_tail", .offset = 0x81, },
+ { .name = "drop_yellow_prio_0", .offset = 0x82, },
+ { .name = "drop_yellow_prio_1", .offset = 0x83, },
+ { .name = "drop_yellow_prio_2", .offset = 0x84, },
+ { .name = "drop_yellow_prio_3", .offset = 0x85, },
+ { .name = "drop_yellow_prio_4", .offset = 0x86, },
+ { .name = "drop_yellow_prio_5", .offset = 0x87, },
+ { .name = "drop_yellow_prio_6", .offset = 0x88, },
+ { .name = "drop_yellow_prio_7", .offset = 0x89, },
+ { .name = "drop_green_prio_0", .offset = 0x8A, },
+ { .name = "drop_green_prio_1", .offset = 0x8B, },
+ { .name = "drop_green_prio_2", .offset = 0x8C, },
+ { .name = "drop_green_prio_3", .offset = 0x8D, },
+ { .name = "drop_green_prio_4", .offset = 0x8E, },
+ { .name = "drop_green_prio_5", .offset = 0x8F, },
+ { .name = "drop_green_prio_6", .offset = 0x90, },
+ { .name = "drop_green_prio_7", .offset = 0x91, },
+};
+
+static void ocelot_pll5_init(struct ocelot *ocelot)
+{
+ /* Configure PLL5. This will need a proper CCF driver
+ * The values are coming from the VTSS API for Ocelot
+ */
+ regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG4,
+ HSIO_PLL5G_CFG4_IB_CTRL(0x7600) |
+ HSIO_PLL5G_CFG4_IB_BIAS_CTRL(0x8));
+ regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG0,
+ HSIO_PLL5G_CFG0_CORE_CLK_DIV(0x11) |
+ HSIO_PLL5G_CFG0_CPU_CLK_DIV(2) |
+ HSIO_PLL5G_CFG0_ENA_BIAS |
+ HSIO_PLL5G_CFG0_ENA_VCO_BUF |
+ HSIO_PLL5G_CFG0_ENA_CP1 |
+ HSIO_PLL5G_CFG0_SELCPI(2) |
+ HSIO_PLL5G_CFG0_LOOP_BW_RES(0xe) |
+ HSIO_PLL5G_CFG0_SELBGV820(4) |
+ HSIO_PLL5G_CFG0_DIV4 |
+ HSIO_PLL5G_CFG0_ENA_CLKTREE |
+ HSIO_PLL5G_CFG0_ENA_LANE);
+ regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG2,
+ HSIO_PLL5G_CFG2_EN_RESET_FRQ_DET |
+ HSIO_PLL5G_CFG2_EN_RESET_OVERRUN |
+ HSIO_PLL5G_CFG2_GAIN_TEST(0x8) |
+ HSIO_PLL5G_CFG2_ENA_AMPCTRL |
+ HSIO_PLL5G_CFG2_PWD_AMPCTRL_N |
+ HSIO_PLL5G_CFG2_AMPC_SEL(0x10));
+}
+
+static int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops)
+{
+ int ret;
+
+ ocelot->map = ocelot_regmap;
+ ocelot->stats_layout = ocelot_stats_layout;
+ ocelot->num_stats = ARRAY_SIZE(ocelot_stats_layout);
+ ocelot->shared_queue_sz = 224 * 1024;
+ ocelot->num_mact_rows = 1024;
+ ocelot->ops = ops;
+
+ ret = ocelot_regfields_init(ocelot, ocelot_regfields);
+ if (ret)
+ return ret;
+
+ ocelot_pll5_init(ocelot);
+
+ eth_random_addr(ocelot->base_mac);
+ ocelot->base_mac[5] &= 0xf0;
+
+ return 0;
+}
+
+static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info)
+{
+ u8 llen, wlen;
+ u64 ifh[2];
+
+ ifh[0] = be64_to_cpu(((__force __be64 *)_ifh)[0]);
+ ifh[1] = be64_to_cpu(((__force __be64 *)_ifh)[1]);
+
+ wlen = IFH_EXTRACT_BITFIELD64(ifh[0], 7, 8);
+ llen = IFH_EXTRACT_BITFIELD64(ifh[0], 15, 6);
+
+ info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80;
+
+ info->timestamp = IFH_EXTRACT_BITFIELD64(ifh[0], 21, 32);
+
+ info->port = IFH_EXTRACT_BITFIELD64(ifh[1], 43, 4);
+
+ info->tag_type = IFH_EXTRACT_BITFIELD64(ifh[1], 16, 1);
+ info->vid = IFH_EXTRACT_BITFIELD64(ifh[1], 0, 12);
+
+ return 0;
+}
+
+static int ocelot_rx_frame_word(struct ocelot *ocelot, u8 grp, bool ifh,
+ u32 *rval)
+{
+ u32 val;
+ u32 bytes_valid;
+
+ val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
+ if (val == XTR_NOT_READY) {
+ if (ifh)
+ return -EIO;
+
+ do {
+ val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
+ } while (val == XTR_NOT_READY);
+ }
+
+ switch (val) {
+ case XTR_ABORT:
+ return -EIO;
+ case XTR_EOF_0:
+ case XTR_EOF_1:
+ case XTR_EOF_2:
+ case XTR_EOF_3:
+ case XTR_PRUNED:
+ bytes_valid = XTR_VALID_BYTES(val);
+ val = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
+ if (val == XTR_ESCAPE)
+ *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
+ else
+ *rval = val;
+
+ return bytes_valid;
+ case XTR_ESCAPE:
+ *rval = ocelot_read_rix(ocelot, QS_XTR_RD, grp);
+
+ return 4;
+ default:
+ *rval = val;
+
+ return 4;
+ }
+}
+
+static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
+{
+ struct ocelot *ocelot = arg;
+ int i = 0, grp = 0;
+ int err = 0;
+
+ if (!(ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)))
+ return IRQ_NONE;
+
+ do {
+ struct skb_shared_hwtstamps *shhwtstamps;
+ struct ocelot_port_private *priv;
+ struct ocelot_port *ocelot_port;
+ u64 tod_in_ns, full_ts_in_ns;
+ struct frame_info info = {};
+ struct net_device *dev;
+ u32 ifh[4], val, *buf;
+ struct timespec64 ts;
+ int sz, len, buf_len;
+ struct sk_buff *skb;
+
+ for (i = 0; i < OCELOT_TAG_LEN / 4; i++) {
+ err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]);
+ if (err != 4)
+ break;
+ }
+
+ if (err != 4)
+ break;
+
+ /* At this point the IFH was read correctly, so it is safe to
+ * presume that there is no error. The err needs to be reset
+ * otherwise a frame could come in CPU queue between the while
+ * condition and the check for error later on. And in that case
+ * the new frame is just removed and not processed.
+ */
+ err = 0;
+
+ ocelot_parse_ifh(ifh, &info);
+
+ ocelot_port = ocelot->ports[info.port];
+ priv = container_of(ocelot_port, struct ocelot_port_private,
+ port);
+ dev = priv->dev;
+
+ skb = netdev_alloc_skb(dev, info.len);
+
+ if (unlikely(!skb)) {
+ netdev_err(dev, "Unable to allocate sk_buff\n");
+ err = -ENOMEM;
+ break;
+ }
+ buf_len = info.len - ETH_FCS_LEN;
+ buf = (u32 *)skb_put(skb, buf_len);
+
+ len = 0;
+ do {
+ sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
+ *buf++ = val;
+ len += sz;
+ } while (len < buf_len);
+
+ /* Read the FCS */
+ sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
+ /* Update the statistics if part of the FCS was read before */
+ len -= ETH_FCS_LEN - sz;
+
+ if (unlikely(dev->features & NETIF_F_RXFCS)) {
+ buf = (u32 *)skb_put(skb, ETH_FCS_LEN);
+ *buf = val;
+ }
+
+ if (sz < 0) {
+ err = sz;
+ break;
+ }
+
+ if (ocelot->ptp) {
+ ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
+
+ tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec);
+ if ((tod_in_ns & 0xffffffff) < info.timestamp)
+ full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) |
+ info.timestamp;
+ else
+ full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) |
+ info.timestamp;
+
+ shhwtstamps = skb_hwtstamps(skb);
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+ shhwtstamps->hwtstamp = full_ts_in_ns;
+ }
+
+ /* Everything we see on an interface that is in the HW bridge
+ * has already been forwarded.
+ */
+ if (ocelot->bridge_mask & BIT(info.port))
+ skb->offload_fwd_mark = 1;
+
+ skb->protocol = eth_type_trans(skb, dev);
+ if (!skb_defer_rx_timestamp(skb))
+ netif_rx(skb);
+ dev->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ } while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp));
+
+ if (err)
+ while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp))
+ ocelot_read_rix(ocelot, QS_XTR_RD, grp);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
+{
+ struct ocelot *ocelot = arg;
+
+ ocelot_get_txtstamp(ocelot);
+
+ return IRQ_HANDLED;
+}
+
+static const struct of_device_id mscc_ocelot_match[] = {
+ { .compatible = "mscc,vsc7514-switch" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
+
+static int ocelot_reset(struct ocelot *ocelot)
+{
+ int retries = 100;
+ u32 val;
+
+ regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
+ regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
+
+ do {
+ msleep(1);
+ regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
+ &val);
+ } while (val && --retries);
+
+ if (!retries)
+ return -ETIMEDOUT;
+
+ regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
+ regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
+
+ return 0;
+}
+
+/* Watermark encode
+ * Bit 8: Unit; 0:1, 1:16
+ * Bit 7-0: Value to be multiplied with unit
+ */
+static u16 ocelot_wm_enc(u16 value)
+{
+ if (value >= BIT(8))
+ return BIT(8) | (value / 16);
+
+ return value;
+}
+
+static const struct ocelot_ops ocelot_ops = {
+ .reset = ocelot_reset,
+ .wm_enc = ocelot_wm_enc,
+};
+
+static const struct vcap_field vsc7514_vcap_is2_keys[] = {
+ /* Common: 46 bits */
+ [VCAP_IS2_TYPE] = { 0, 4},
+ [VCAP_IS2_HK_FIRST] = { 4, 1},
+ [VCAP_IS2_HK_PAG] = { 5, 8},
+ [VCAP_IS2_HK_IGR_PORT_MASK] = { 13, 12},
+ [VCAP_IS2_HK_RSV2] = { 25, 1},
+ [VCAP_IS2_HK_HOST_MATCH] = { 26, 1},
+ [VCAP_IS2_HK_L2_MC] = { 27, 1},
+ [VCAP_IS2_HK_L2_BC] = { 28, 1},
+ [VCAP_IS2_HK_VLAN_TAGGED] = { 29, 1},
+ [VCAP_IS2_HK_VID] = { 30, 12},
+ [VCAP_IS2_HK_DEI] = { 42, 1},
+ [VCAP_IS2_HK_PCP] = { 43, 3},
+ /* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
+ [VCAP_IS2_HK_L2_DMAC] = { 46, 48},
+ [VCAP_IS2_HK_L2_SMAC] = { 94, 48},
+ /* MAC_ETYPE (TYPE=000) */
+ [VCAP_IS2_HK_MAC_ETYPE_ETYPE] = {142, 16},
+ [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0] = {158, 16},
+ [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1] = {174, 8},
+ [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2] = {182, 3},
+ /* MAC_LLC (TYPE=001) */
+ [VCAP_IS2_HK_MAC_LLC_L2_LLC] = {142, 40},
+ /* MAC_SNAP (TYPE=010) */
+ [VCAP_IS2_HK_MAC_SNAP_L2_SNAP] = {142, 40},
+ /* MAC_ARP (TYPE=011) */
+ [VCAP_IS2_HK_MAC_ARP_SMAC] = { 46, 48},
+ [VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK] = { 94, 1},
+ [VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK] = { 95, 1},
+ [VCAP_IS2_HK_MAC_ARP_LEN_OK] = { 96, 1},
+ [VCAP_IS2_HK_MAC_ARP_TARGET_MATCH] = { 97, 1},
+ [VCAP_IS2_HK_MAC_ARP_SENDER_MATCH] = { 98, 1},
+ [VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN] = { 99, 1},
+ [VCAP_IS2_HK_MAC_ARP_OPCODE] = {100, 2},
+ [VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP] = {102, 32},
+ [VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP] = {134, 32},
+ [VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP] = {166, 1},
+ /* IP4_TCP_UDP / IP4_OTHER common */
+ [VCAP_IS2_HK_IP4] = { 46, 1},
+ [VCAP_IS2_HK_L3_FRAGMENT] = { 47, 1},
+ [VCAP_IS2_HK_L3_FRAG_OFS_GT0] = { 48, 1},
+ [VCAP_IS2_HK_L3_OPTIONS] = { 49, 1},
+ [VCAP_IS2_HK_IP4_L3_TTL_GT0] = { 50, 1},
+ [VCAP_IS2_HK_L3_TOS] = { 51, 8},
+ [VCAP_IS2_HK_L3_IP4_DIP] = { 59, 32},
+ [VCAP_IS2_HK_L3_IP4_SIP] = { 91, 32},
+ [VCAP_IS2_HK_DIP_EQ_SIP] = {123, 1},
+ /* IP4_TCP_UDP (TYPE=100) */
+ [VCAP_IS2_HK_TCP] = {124, 1},
+ [VCAP_IS2_HK_L4_SPORT] = {125, 16},
+ [VCAP_IS2_HK_L4_DPORT] = {141, 16},
+ [VCAP_IS2_HK_L4_RNG] = {157, 8},
+ [VCAP_IS2_HK_L4_SPORT_EQ_DPORT] = {165, 1},
+ [VCAP_IS2_HK_L4_SEQUENCE_EQ0] = {166, 1},
+ [VCAP_IS2_HK_L4_URG] = {167, 1},
+ [VCAP_IS2_HK_L4_ACK] = {168, 1},
+ [VCAP_IS2_HK_L4_PSH] = {169, 1},
+ [VCAP_IS2_HK_L4_RST] = {170, 1},
+ [VCAP_IS2_HK_L4_SYN] = {171, 1},
+ [VCAP_IS2_HK_L4_FIN] = {172, 1},
+ [VCAP_IS2_HK_L4_1588_DOM] = {173, 8},
+ [VCAP_IS2_HK_L4_1588_VER] = {181, 4},
+ /* IP4_OTHER (TYPE=101) */
+ [VCAP_IS2_HK_IP4_L3_PROTO] = {124, 8},
+ [VCAP_IS2_HK_L3_PAYLOAD] = {132, 56},
+ /* IP6_STD (TYPE=110) */
+ [VCAP_IS2_HK_IP6_L3_TTL_GT0] = { 46, 1},
+ [VCAP_IS2_HK_L3_IP6_SIP] = { 47, 128},
+ [VCAP_IS2_HK_IP6_L3_PROTO] = {175, 8},
+ /* OAM (TYPE=111) */
+ [VCAP_IS2_HK_OAM_MEL_FLAGS] = {142, 7},
+ [VCAP_IS2_HK_OAM_VER] = {149, 5},
+ [VCAP_IS2_HK_OAM_OPCODE] = {154, 8},
+ [VCAP_IS2_HK_OAM_FLAGS] = {162, 8},
+ [VCAP_IS2_HK_OAM_MEPID] = {170, 16},
+ [VCAP_IS2_HK_OAM_CCM_CNTS_EQ0] = {186, 1},
+ [VCAP_IS2_HK_OAM_IS_Y1731] = {187, 1},
+};
+
+static const struct vcap_field vsc7514_vcap_is2_actions[] = {
+ [VCAP_IS2_ACT_HIT_ME_ONCE] = { 0, 1},
+ [VCAP_IS2_ACT_CPU_COPY_ENA] = { 1, 1},
+ [VCAP_IS2_ACT_CPU_QU_NUM] = { 2, 3},
+ [VCAP_IS2_ACT_MASK_MODE] = { 5, 2},
+ [VCAP_IS2_ACT_MIRROR_ENA] = { 7, 1},
+ [VCAP_IS2_ACT_LRN_DIS] = { 8, 1},
+ [VCAP_IS2_ACT_POLICE_ENA] = { 9, 1},
+ [VCAP_IS2_ACT_POLICE_IDX] = { 10, 9},
+ [VCAP_IS2_ACT_POLICE_VCAP_ONLY] = { 19, 1},
+ [VCAP_IS2_ACT_PORT_MASK] = { 20, 11},
+ [VCAP_IS2_ACT_REW_OP] = { 31, 9},
+ [VCAP_IS2_ACT_SMAC_REPLACE_ENA] = { 40, 1},
+ [VCAP_IS2_ACT_RSV] = { 41, 2},
+ [VCAP_IS2_ACT_ACL_ID] = { 43, 6},
+ [VCAP_IS2_ACT_HIT_CNT] = { 49, 32},
+};
+
+static const struct vcap_props vsc7514_vcap_props[] = {
+ [VCAP_IS2] = {
+ .tg_width = 2,
+ .sw_count = 4,
+ .entry_count = VSC7514_VCAP_IS2_CNT,
+ .entry_width = VSC7514_VCAP_IS2_ENTRY_WIDTH,
+ .action_count = VSC7514_VCAP_IS2_CNT +
+ VSC7514_VCAP_PORT_CNT + 2,
+ .action_width = 99,
+ .action_type_width = 1,
+ .action_table = {
+ [IS2_ACTION_TYPE_NORMAL] = {
+ .width = 49,
+ .count = 2
+ },
+ [IS2_ACTION_TYPE_SMAC_SIP] = {
+ .width = 6,
+ .count = 4
+ },
+ },
+ .counter_words = 4,
+ .counter_width = 32,
+ },
+};
+
+static struct ptp_clock_info ocelot_ptp_clock_info = {
+ .owner = THIS_MODULE,
+ .name = "ocelot ptp",
+ .max_adj = 0x7fffffff,
+ .n_alarm = 0,
+ .n_ext_ts = 0,
+ .n_per_out = OCELOT_PTP_PINS_NUM,
+ .n_pins = OCELOT_PTP_PINS_NUM,
+ .pps = 0,
+ .gettime64 = ocelot_ptp_gettime64,
+ .settime64 = ocelot_ptp_settime64,
+ .adjtime = ocelot_ptp_adjtime,
+ .adjfine = ocelot_ptp_adjfine,
+ .verify = ocelot_ptp_verify,
+ .enable = ocelot_ptp_enable,
+};
+
+static int mscc_ocelot_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *ports, *portnp;
+ int err, irq_xtr, irq_ptp_rdy;
+ struct ocelot *ocelot;
+ struct regmap *hsio;
+ unsigned int i;
+
+ struct {
+ enum ocelot_target id;
+ char *name;
+ u8 optional:1;
+ } io_target[] = {
+ { SYS, "sys" },
+ { REW, "rew" },
+ { QSYS, "qsys" },
+ { ANA, "ana" },
+ { QS, "qs" },
+ { S2, "s2" },
+ { PTP, "ptp", 1 },
+ };
+
+ if (!np && !pdev->dev.platform_data)
+ return -ENODEV;
+
+ ocelot = devm_kzalloc(&pdev->dev, sizeof(*ocelot), GFP_KERNEL);
+ if (!ocelot)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ocelot);
+ ocelot->dev = &pdev->dev;
+
+ for (i = 0; i < ARRAY_SIZE(io_target); i++) {
+ struct regmap *target;
+ struct resource *res;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ io_target[i].name);
+
+ target = ocelot_regmap_init(ocelot, res);
+ if (IS_ERR(target)) {
+ if (io_target[i].optional) {
+ ocelot->targets[io_target[i].id] = NULL;
+ continue;
+ }
+ return PTR_ERR(target);
+ }
+
+ ocelot->targets[io_target[i].id] = target;
+ }
+
+ hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
+ if (IS_ERR(hsio)) {
+ dev_err(&pdev->dev, "missing hsio syscon\n");
+ return PTR_ERR(hsio);
+ }
+
+ ocelot->targets[HSIO] = hsio;
+
+ err = ocelot_chip_init(ocelot, &ocelot_ops);
+ if (err)
+ return err;
+
+ irq_xtr = platform_get_irq_byname(pdev, "xtr");
+ if (irq_xtr < 0)
+ return -ENODEV;
+
+ err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
+ ocelot_xtr_irq_handler, IRQF_ONESHOT,
+ "frame extraction", ocelot);
+ if (err)
+ return err;
+
+ irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
+ if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) {
+ err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
+ ocelot_ptp_rdy_irq_handler,
+ IRQF_ONESHOT, "ptp ready",
+ ocelot);
+ if (err)
+ return err;
+
+ /* Both the PTP interrupt and the PTP bank are available */
+ ocelot->ptp = 1;
+ }
+
+ ports = of_get_child_by_name(np, "ethernet-ports");
+ if (!ports) {
+ dev_err(&pdev->dev, "no ethernet-ports child node found\n");
+ return -ENODEV;
+ }
+
+ ocelot->num_phys_ports = of_get_child_count(ports);
+
+ ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
+ sizeof(struct ocelot_port *), GFP_KERNEL);
+
+ ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
+ ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
+ ocelot->vcap = vsc7514_vcap_props;
+
+ ocelot_init(ocelot);
+ if (ocelot->ptp) {
+ err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info);
+ if (err) {
+ dev_err(ocelot->dev,
+ "Timestamp initialization failed\n");
+ ocelot->ptp = 0;
+ }
+ }
+
+ /* No NPI port */
+ ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
+ OCELOT_TAG_PREFIX_NONE);
+
+ for_each_available_child_of_node(ports, portnp) {
+ struct ocelot_port_private *priv;
+ struct ocelot_port *ocelot_port;
+ struct device_node *phy_node;
+ phy_interface_t phy_mode;
+ struct phy_device *phy;
+ struct regmap *target;
+ struct resource *res;
+ struct phy *serdes;
+ char res_name[8];
+ u32 port;
+
+ if (of_property_read_u32(portnp, "reg", &port))
+ continue;
+
+ snprintf(res_name, sizeof(res_name), "port%d", port);
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ res_name);
+ target = ocelot_regmap_init(ocelot, res);
+ if (IS_ERR(target))
+ continue;
+
+ phy_node = of_parse_phandle(portnp, "phy-handle", 0);
+ if (!phy_node)
+ continue;
+
+ phy = of_phy_find_device(phy_node);
+ of_node_put(phy_node);
+ if (!phy)
+ continue;
+
+ err = ocelot_probe_port(ocelot, port, target, phy);
+ if (err) {
+ of_node_put(portnp);
+ goto out_put_ports;
+ }
+
+ ocelot_port = ocelot->ports[port];
+ priv = container_of(ocelot_port, struct ocelot_port_private,
+ port);
+
+ of_get_phy_mode(portnp, &phy_mode);
+
+ ocelot_port->phy_mode = phy_mode;
+
+ switch (ocelot_port->phy_mode) {
+ case PHY_INTERFACE_MODE_NA:
+ continue;
+ case PHY_INTERFACE_MODE_SGMII:
+ break;
+ case PHY_INTERFACE_MODE_QSGMII:
+ /* Ensure clock signals and speed is set on all
+ * QSGMII links
+ */
+ ocelot_port_writel(ocelot_port,
+ DEV_CLOCK_CFG_LINK_SPEED
+ (OCELOT_SPEED_1000),
+ DEV_CLOCK_CFG);
+ break;
+ default:
+ dev_err(ocelot->dev,
+ "invalid phy mode for port%d, (Q)SGMII only\n",
+ port);
+ of_node_put(portnp);
+ err = -EINVAL;
+ goto out_put_ports;
+ }
+
+ serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
+ if (IS_ERR(serdes)) {
+ err = PTR_ERR(serdes);
+ if (err == -EPROBE_DEFER)
+ dev_dbg(ocelot->dev, "deferring probe\n");
+ else
+ dev_err(ocelot->dev,
+ "missing SerDes phys for port%d\n",
+ port);
+
+ of_node_put(portnp);
+ goto out_put_ports;
+ }
+
+ priv->serdes = serdes;
+ }
+
+ register_netdevice_notifier(&ocelot_netdevice_nb);
+ register_switchdev_notifier(&ocelot_switchdev_nb);
+ register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
+
+ dev_info(&pdev->dev, "Ocelot switch probed\n");
+
+out_put_ports:
+ of_node_put(ports);
+ return err;
+}
+
+static int mscc_ocelot_remove(struct platform_device *pdev)
+{
+ struct ocelot *ocelot = platform_get_drvdata(pdev);
+
+ ocelot_deinit_timestamp(ocelot);
+ ocelot_deinit(ocelot);
+ unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
+ unregister_switchdev_notifier(&ocelot_switchdev_nb);
+ unregister_netdevice_notifier(&ocelot_netdevice_nb);
+
+ return 0;
+}
+
+static struct platform_driver mscc_ocelot_driver = {
+ .probe = mscc_ocelot_probe,
+ .remove = mscc_ocelot_remove,
+ .driver = {
+ .name = "ocelot-switch",
+ .of_match_table = mscc_ocelot_match,
+ },
+};
+
+module_platform_driver(mscc_ocelot_driver);
+
+MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
+MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index e1e1f4e3639e..4a5beafa0493 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -3257,13 +3257,12 @@ static void myri10ge_mask_surprise_down(struct pci_dev *pdev)
}
}
-#ifdef CONFIG_PM
-static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused myri10ge_suspend(struct device *dev)
{
struct myri10ge_priv *mgp;
struct net_device *netdev;
- mgp = pci_get_drvdata(pdev);
+ mgp = dev_get_drvdata(dev);
if (mgp == NULL)
return -EINVAL;
netdev = mgp->dev;
@@ -3276,14 +3275,13 @@ static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state)
rtnl_unlock();
}
myri10ge_dummy_rdma(mgp, 0);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- return pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ return 0;
}
-static int myri10ge_resume(struct pci_dev *pdev)
+static int __maybe_unused myri10ge_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct myri10ge_priv *mgp;
struct net_device *netdev;
int status;
@@ -3293,7 +3291,6 @@ static int myri10ge_resume(struct pci_dev *pdev)
if (mgp == NULL)
return -EINVAL;
netdev = mgp->dev;
- pci_set_power_state(pdev, PCI_D0); /* zeros conf space as a side effect */
msleep(5); /* give card time to respond */
pci_read_config_word(mgp->pdev, PCI_VENDOR_ID, &vendor);
if (vendor == 0xffff) {
@@ -3301,23 +3298,9 @@ static int myri10ge_resume(struct pci_dev *pdev)
return -EIO;
}
- pci_restore_state(pdev);
-
- status = pci_enable_device(pdev);
- if (status) {
- dev_err(&pdev->dev, "failed to enable device\n");
- return status;
- }
-
- pci_set_master(pdev);
-
myri10ge_reset(mgp);
myri10ge_dummy_rdma(mgp, 1);
- /* Save configuration space to be restored if the
- * nic resets due to a parity error */
- pci_save_state(pdev);
-
if (netif_running(netdev)) {
rtnl_lock();
status = myri10ge_open(netdev);
@@ -3331,11 +3314,8 @@ static int myri10ge_resume(struct pci_dev *pdev)
return 0;
abort_with_enabled:
- pci_disable_device(pdev);
return -EIO;
-
}
-#endif /* CONFIG_PM */
static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp)
{
@@ -4017,15 +3997,14 @@ static const struct pci_device_id myri10ge_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, myri10ge_pci_tbl);
+static SIMPLE_DEV_PM_OPS(myri10ge_pm_ops, myri10ge_suspend, myri10ge_resume);
+
static struct pci_driver myri10ge_driver = {
.name = "myri10ge",
.probe = myri10ge_probe,
.remove = myri10ge_remove,
.id_table = myri10ge_pci_tbl,
-#ifdef CONFIG_PM
- .suspend = myri10ge_suspend,
- .resume = myri10ge_resume,
-#endif
+ .driver.pm = &myri10ge_pm_ops,
};
#ifdef CONFIG_MYRI10GE_DCA
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index d21d706b83a7..c2867fe995bc 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -3247,8 +3247,6 @@ static void natsemi_remove1(struct pci_dev *pdev)
free_netdev (dev);
}
-#ifdef CONFIG_PM
-
/*
* The ns83815 chip doesn't have explicit RxStop bits.
* Kicking the Rx or Tx process for a new packet reenables the Rx process
@@ -3275,9 +3273,9 @@ static void natsemi_remove1(struct pci_dev *pdev)
* Interrupts must be disabled, otherwise hands_off can cause irq storms.
*/
-static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused natsemi_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata (pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev);
void __iomem * ioaddr = ns_ioaddr(dev);
@@ -3326,11 +3324,10 @@ static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state)
}
-static int natsemi_resume (struct pci_dev *pdev)
+static int __maybe_unused natsemi_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata (pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct netdev_private *np = netdev_priv(dev);
- int ret = 0;
rtnl_lock();
if (netif_device_present(dev))
@@ -3339,12 +3336,6 @@ static int natsemi_resume (struct pci_dev *pdev)
const int irq = np->pci_dev->irq;
BUG_ON(!np->hands_off);
- ret = pci_enable_device(pdev);
- if (ret < 0) {
- dev_err(&pdev->dev,
- "pci_enable_device() failed: %d\n", ret);
- goto out;
- }
/* pci_power_on(pdev); */
napi_enable(&np->napi);
@@ -3364,20 +3355,17 @@ static int natsemi_resume (struct pci_dev *pdev)
netif_device_attach(dev);
out:
rtnl_unlock();
- return ret;
+ return 0;
}
-#endif /* CONFIG_PM */
+static SIMPLE_DEV_PM_OPS(natsemi_pm_ops, natsemi_suspend, natsemi_resume);
static struct pci_driver natsemi_driver = {
.name = DRV_NAME,
.id_table = natsemi_pci_tbl,
.probe = natsemi_probe1,
.remove = natsemi_remove1,
-#ifdef CONFIG_PM
- .suspend = natsemi_suspend,
- .resume = natsemi_resume,
-#endif
+ .driver.pm = &natsemi_pm_ops,
};
static int __init natsemi_init_mod (void)
diff --git a/drivers/net/ethernet/neterion/Kconfig b/drivers/net/ethernet/neterion/Kconfig
index 5484f18f272e..0c0d127906dd 100644
--- a/drivers/net/ethernet/neterion/Kconfig
+++ b/drivers/net/ethernet/neterion/Kconfig
@@ -27,7 +27,7 @@ config S2IO
on its age.
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/neterion/s2io.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/neterion/s2io.rst>.
To compile this driver as a module, choose M here. The module
will be called s2io.
@@ -42,7 +42,7 @@ config VXGE
labeled as either one, depending on its age.
More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/neterion/vxge.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/neterion/vxge.rst>.
To compile this driver as a module, choose M here. The module
will be called vxge.
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index 15b8b1bf8163..bc94970bea45 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -640,11 +640,11 @@ static int init_shared_mem(struct s2io_nic *nic)
int k = 0;
dma_addr_t tmp_p;
void *tmp_v;
- tmp_v = pci_alloc_consistent(nic->pdev,
- PAGE_SIZE, &tmp_p);
+ tmp_v = dma_alloc_coherent(&nic->pdev->dev, PAGE_SIZE,
+ &tmp_p, GFP_KERNEL);
if (!tmp_v) {
DBG_PRINT(INFO_DBG,
- "pci_alloc_consistent failed for TxDL\n");
+ "dma_alloc_coherent failed for TxDL\n");
return -ENOMEM;
}
/* If we got a zero DMA address(can happen on
@@ -658,11 +658,12 @@ static int init_shared_mem(struct s2io_nic *nic)
"%s: Zero DMA address for TxDL. "
"Virtual address %p\n",
dev->name, tmp_v);
- tmp_v = pci_alloc_consistent(nic->pdev,
- PAGE_SIZE, &tmp_p);
+ tmp_v = dma_alloc_coherent(&nic->pdev->dev,
+ PAGE_SIZE, &tmp_p,
+ GFP_KERNEL);
if (!tmp_v) {
DBG_PRINT(INFO_DBG,
- "pci_alloc_consistent failed for TxDL\n");
+ "dma_alloc_coherent failed for TxDL\n");
return -ENOMEM;
}
mem_allocated += PAGE_SIZE;
@@ -734,8 +735,8 @@ static int init_shared_mem(struct s2io_nic *nic)
rx_blocks = &ring->rx_blocks[j];
size = SIZE_OF_BLOCK; /* size is always page size */
- tmp_v_addr = pci_alloc_consistent(nic->pdev, size,
- &tmp_p_addr);
+ tmp_v_addr = dma_alloc_coherent(&nic->pdev->dev, size,
+ &tmp_p_addr, GFP_KERNEL);
if (tmp_v_addr == NULL) {
/*
* In case of failure, free_shared_mem()
@@ -835,8 +836,8 @@ static int init_shared_mem(struct s2io_nic *nic)
/* Allocation and initialization of Statistics block */
size = sizeof(struct stat_block);
mac_control->stats_mem =
- pci_alloc_consistent(nic->pdev, size,
- &mac_control->stats_mem_phy);
+ dma_alloc_coherent(&nic->pdev->dev, size,
+ &mac_control->stats_mem_phy, GFP_KERNEL);
if (!mac_control->stats_mem) {
/*
@@ -906,18 +907,18 @@ static void free_shared_mem(struct s2io_nic *nic)
fli = &fifo->list_info[mem_blks];
if (!fli->list_virt_addr)
break;
- pci_free_consistent(nic->pdev, PAGE_SIZE,
- fli->list_virt_addr,
- fli->list_phy_addr);
+ dma_free_coherent(&nic->pdev->dev, PAGE_SIZE,
+ fli->list_virt_addr,
+ fli->list_phy_addr);
swstats->mem_freed += PAGE_SIZE;
}
/* If we got a zero DMA address during allocation,
* free the page now
*/
if (mac_control->zerodma_virt_addr) {
- pci_free_consistent(nic->pdev, PAGE_SIZE,
- mac_control->zerodma_virt_addr,
- (dma_addr_t)0);
+ dma_free_coherent(&nic->pdev->dev, PAGE_SIZE,
+ mac_control->zerodma_virt_addr,
+ (dma_addr_t)0);
DBG_PRINT(INIT_DBG,
"%s: Freeing TxDL with zero DMA address. "
"Virtual address %p\n",
@@ -939,8 +940,8 @@ static void free_shared_mem(struct s2io_nic *nic)
tmp_p_addr = ring->rx_blocks[j].block_dma_addr;
if (tmp_v_addr == NULL)
break;
- pci_free_consistent(nic->pdev, size,
- tmp_v_addr, tmp_p_addr);
+ dma_free_coherent(&nic->pdev->dev, size, tmp_v_addr,
+ tmp_p_addr);
swstats->mem_freed += size;
kfree(ring->rx_blocks[j].rxds);
swstats->mem_freed += sizeof(struct rxd_info) *
@@ -993,10 +994,9 @@ static void free_shared_mem(struct s2io_nic *nic)
if (mac_control->stats_mem) {
swstats->mem_freed += mac_control->stats_mem_sz;
- pci_free_consistent(nic->pdev,
- mac_control->stats_mem_sz,
- mac_control->stats_mem,
- mac_control->stats_mem_phy);
+ dma_free_coherent(&nic->pdev->dev, mac_control->stats_mem_sz,
+ mac_control->stats_mem,
+ mac_control->stats_mem_phy);
}
}
@@ -2316,8 +2316,9 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data,
txds = txdlp;
if (txds->Host_Control == (u64)(long)fifo_data->ufo_in_band_v) {
- pci_unmap_single(nic->pdev, (dma_addr_t)txds->Buffer_Pointer,
- sizeof(u64), PCI_DMA_TODEVICE);
+ dma_unmap_single(&nic->pdev->dev,
+ (dma_addr_t)txds->Buffer_Pointer,
+ sizeof(u64), DMA_TO_DEVICE);
txds++;
}
@@ -2326,8 +2327,8 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data,
memset(txdlp, 0, (sizeof(struct TxD) * fifo_data->max_txds));
return NULL;
}
- pci_unmap_single(nic->pdev, (dma_addr_t)txds->Buffer_Pointer,
- skb_headlen(skb), PCI_DMA_TODEVICE);
+ dma_unmap_single(&nic->pdev->dev, (dma_addr_t)txds->Buffer_Pointer,
+ skb_headlen(skb), DMA_TO_DEVICE);
frg_cnt = skb_shinfo(skb)->nr_frags;
if (frg_cnt) {
txds++;
@@ -2335,9 +2336,9 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data,
const skb_frag_t *frag = &skb_shinfo(skb)->frags[j];
if (!txds->Buffer_Pointer)
break;
- pci_unmap_page(nic->pdev,
+ dma_unmap_page(&nic->pdev->dev,
(dma_addr_t)txds->Buffer_Pointer,
- skb_frag_size(frag), PCI_DMA_TODEVICE);
+ skb_frag_size(frag), DMA_TO_DEVICE);
}
}
memset(txdlp, 0, (sizeof(struct TxD) * fifo_data->max_txds));
@@ -2521,11 +2522,10 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
memset(rxdp, 0, sizeof(struct RxD1));
skb_reserve(skb, NET_IP_ALIGN);
rxdp1->Buffer0_ptr =
- pci_map_single(ring->pdev, skb->data,
+ dma_map_single(&ring->pdev->dev, skb->data,
size - NET_IP_ALIGN,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(nic->pdev,
- rxdp1->Buffer0_ptr))
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&nic->pdev->dev, rxdp1->Buffer0_ptr))
goto pci_map_failed;
rxdp->Control_2 =
@@ -2557,17 +2557,16 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
if (from_card_up) {
rxdp3->Buffer0_ptr =
- pci_map_single(ring->pdev, ba->ba_0,
- BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(nic->pdev,
- rxdp3->Buffer0_ptr))
+ dma_map_single(&ring->pdev->dev,
+ ba->ba_0, BUF0_LEN,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&nic->pdev->dev, rxdp3->Buffer0_ptr))
goto pci_map_failed;
} else
- pci_dma_sync_single_for_device(ring->pdev,
- (dma_addr_t)rxdp3->Buffer0_ptr,
- BUF0_LEN,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&ring->pdev->dev,
+ (dma_addr_t)rxdp3->Buffer0_ptr,
+ BUF0_LEN,
+ DMA_FROM_DEVICE);
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
if (ring->rxd_mode == RXD_MODE_3B) {
@@ -2577,29 +2576,28 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
* Buffer2 will have L3/L4 header plus
* L4 payload
*/
- rxdp3->Buffer2_ptr = pci_map_single(ring->pdev,
+ rxdp3->Buffer2_ptr = dma_map_single(&ring->pdev->dev,
skb->data,
ring->mtu + 4,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
- if (pci_dma_mapping_error(nic->pdev,
- rxdp3->Buffer2_ptr))
+ if (dma_mapping_error(&nic->pdev->dev, rxdp3->Buffer2_ptr))
goto pci_map_failed;
if (from_card_up) {
rxdp3->Buffer1_ptr =
- pci_map_single(ring->pdev,
+ dma_map_single(&ring->pdev->dev,
ba->ba_1,
BUF1_LEN,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
- if (pci_dma_mapping_error(nic->pdev,
- rxdp3->Buffer1_ptr)) {
- pci_unmap_single(ring->pdev,
+ if (dma_mapping_error(&nic->pdev->dev,
+ rxdp3->Buffer1_ptr)) {
+ dma_unmap_single(&ring->pdev->dev,
(dma_addr_t)(unsigned long)
skb->data,
ring->mtu + 4,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
goto pci_map_failed;
}
}
@@ -2668,27 +2666,24 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
continue;
if (sp->rxd_mode == RXD_MODE_1) {
rxdp1 = (struct RxD1 *)rxdp;
- pci_unmap_single(sp->pdev,
+ dma_unmap_single(&sp->pdev->dev,
(dma_addr_t)rxdp1->Buffer0_ptr,
dev->mtu +
HEADER_ETHERNET_II_802_3_SIZE +
HEADER_802_2_SIZE + HEADER_SNAP_SIZE,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
memset(rxdp, 0, sizeof(struct RxD1));
} else if (sp->rxd_mode == RXD_MODE_3B) {
rxdp3 = (struct RxD3 *)rxdp;
- pci_unmap_single(sp->pdev,
+ dma_unmap_single(&sp->pdev->dev,
(dma_addr_t)rxdp3->Buffer0_ptr,
- BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(sp->pdev,
+ BUF0_LEN, DMA_FROM_DEVICE);
+ dma_unmap_single(&sp->pdev->dev,
(dma_addr_t)rxdp3->Buffer1_ptr,
- BUF1_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(sp->pdev,
+ BUF1_LEN, DMA_FROM_DEVICE);
+ dma_unmap_single(&sp->pdev->dev,
(dma_addr_t)rxdp3->Buffer2_ptr,
- dev->mtu + 4,
- PCI_DMA_FROMDEVICE);
+ dev->mtu + 4, DMA_FROM_DEVICE);
memset(rxdp, 0, sizeof(struct RxD3));
}
swstats->mem_freed += skb->truesize;
@@ -2919,23 +2914,21 @@ static int rx_intr_handler(struct ring_info *ring_data, int budget)
}
if (ring_data->rxd_mode == RXD_MODE_1) {
rxdp1 = (struct RxD1 *)rxdp;
- pci_unmap_single(ring_data->pdev, (dma_addr_t)
- rxdp1->Buffer0_ptr,
+ dma_unmap_single(&ring_data->pdev->dev,
+ (dma_addr_t)rxdp1->Buffer0_ptr,
ring_data->mtu +
HEADER_ETHERNET_II_802_3_SIZE +
HEADER_802_2_SIZE +
HEADER_SNAP_SIZE,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
} else if (ring_data->rxd_mode == RXD_MODE_3B) {
rxdp3 = (struct RxD3 *)rxdp;
- pci_dma_sync_single_for_cpu(ring_data->pdev,
- (dma_addr_t)rxdp3->Buffer0_ptr,
- BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(ring_data->pdev,
+ dma_sync_single_for_cpu(&ring_data->pdev->dev,
+ (dma_addr_t)rxdp3->Buffer0_ptr,
+ BUF0_LEN, DMA_FROM_DEVICE);
+ dma_unmap_single(&ring_data->pdev->dev,
(dma_addr_t)rxdp3->Buffer2_ptr,
- ring_data->mtu + 4,
- PCI_DMA_FROMDEVICE);
+ ring_data->mtu + 4, DMA_FROM_DEVICE);
}
prefetch(skb->data);
rx_osm_handler(ring_data, rxdp);
@@ -4117,9 +4110,9 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev)
}
frg_len = skb_headlen(skb);
- txdp->Buffer_Pointer = pci_map_single(sp->pdev, skb->data,
- frg_len, PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer))
+ txdp->Buffer_Pointer = dma_map_single(&sp->pdev->dev, skb->data,
+ frg_len, DMA_TO_DEVICE);
+ if (dma_mapping_error(&sp->pdev->dev, txdp->Buffer_Pointer))
goto pci_map_failed;
txdp->Host_Control = (unsigned long)skb;
@@ -6772,10 +6765,10 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
* Host Control is NULL
*/
rxdp1->Buffer0_ptr = *temp0 =
- pci_map_single(sp->pdev, (*skb)->data,
+ dma_map_single(&sp->pdev->dev, (*skb)->data,
size - NET_IP_ALIGN,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(sp->pdev, rxdp1->Buffer0_ptr))
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&sp->pdev->dev, rxdp1->Buffer0_ptr))
goto memalloc_failed;
rxdp->Host_Control = (unsigned long) (*skb);
}
@@ -6798,37 +6791,34 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
}
stats->mem_allocated += (*skb)->truesize;
rxdp3->Buffer2_ptr = *temp2 =
- pci_map_single(sp->pdev, (*skb)->data,
- dev->mtu + 4,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(sp->pdev, rxdp3->Buffer2_ptr))
+ dma_map_single(&sp->pdev->dev, (*skb)->data,
+ dev->mtu + 4, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&sp->pdev->dev, rxdp3->Buffer2_ptr))
goto memalloc_failed;
rxdp3->Buffer0_ptr = *temp0 =
- pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(sp->pdev,
- rxdp3->Buffer0_ptr)) {
- pci_unmap_single(sp->pdev,
+ dma_map_single(&sp->pdev->dev, ba->ba_0,
+ BUF0_LEN, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&sp->pdev->dev, rxdp3->Buffer0_ptr)) {
+ dma_unmap_single(&sp->pdev->dev,
(dma_addr_t)rxdp3->Buffer2_ptr,
dev->mtu + 4,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
goto memalloc_failed;
}
rxdp->Host_Control = (unsigned long) (*skb);
/* Buffer-1 will be dummy buffer not used */
rxdp3->Buffer1_ptr = *temp1 =
- pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(sp->pdev,
- rxdp3->Buffer1_ptr)) {
- pci_unmap_single(sp->pdev,
+ dma_map_single(&sp->pdev->dev, ba->ba_1,
+ BUF1_LEN, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&sp->pdev->dev, rxdp3->Buffer1_ptr)) {
+ dma_unmap_single(&sp->pdev->dev,
(dma_addr_t)rxdp3->Buffer0_ptr,
- BUF0_LEN, PCI_DMA_FROMDEVICE);
- pci_unmap_single(sp->pdev,
+ BUF0_LEN, DMA_FROM_DEVICE);
+ dma_unmap_single(&sp->pdev->dev,
(dma_addr_t)rxdp3->Buffer2_ptr,
dev->mtu + 4,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
goto memalloc_failed;
}
}
@@ -7675,17 +7665,16 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
return ret;
}
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
DBG_PRINT(INIT_DBG, "%s: Using 64bit DMA\n", __func__);
dma_flag = true;
- if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
DBG_PRINT(ERR_DBG,
- "Unable to obtain 64bit DMA "
- "for consistent allocations\n");
+ "Unable to obtain 64bit DMA for coherent allocations\n");
pci_disable_device(pdev);
return -ENOMEM;
}
- } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
DBG_PRINT(INIT_DBG, "%s: Using 32bit DMA\n", __func__);
} else {
pci_disable_device(pdev);
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.c b/drivers/net/ethernet/neterion/vxge/vxge-config.c
index 51cd57ab3d95..4f1f90f5e178 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-config.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-config.c
@@ -1102,10 +1102,10 @@ static void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool)
hldev = blockpool->hldev;
list_for_each_safe(p, n, &blockpool->free_block_list) {
- pci_unmap_single(hldev->pdev,
- ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
- ((struct __vxge_hw_blockpool_entry *)p)->length,
- PCI_DMA_BIDIRECTIONAL);
+ dma_unmap_single(&hldev->pdev->dev,
+ ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
+ ((struct __vxge_hw_blockpool_entry *)p)->length,
+ DMA_BIDIRECTIONAL);
vxge_os_dma_free(hldev->pdev,
((struct __vxge_hw_blockpool_entry *)p)->memblock,
@@ -1178,10 +1178,10 @@ __vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
goto blockpool_create_exit;
}
- dma_addr = pci_map_single(hldev->pdev, memblock,
- VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL);
- if (unlikely(pci_dma_mapping_error(hldev->pdev,
- dma_addr))) {
+ dma_addr = dma_map_single(&hldev->pdev->dev, memblock,
+ VXGE_HW_BLOCK_SIZE,
+ DMA_BIDIRECTIONAL);
+ if (unlikely(dma_mapping_error(&hldev->pdev->dev, dma_addr))) {
vxge_os_dma_free(hldev->pdev, memblock, &acc_handle);
__vxge_hw_blockpool_destroy(blockpool);
status = VXGE_HW_ERR_OUT_OF_MEMORY;
@@ -2264,10 +2264,10 @@ static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh,
goto exit;
}
- dma_addr = pci_map_single(devh->pdev, block_addr, length,
- PCI_DMA_BIDIRECTIONAL);
+ dma_addr = dma_map_single(&devh->pdev->dev, block_addr, length,
+ DMA_BIDIRECTIONAL);
- if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) {
+ if (unlikely(dma_mapping_error(&devh->pdev->dev, dma_addr))) {
vxge_os_dma_free(devh->pdev, block_addr, &acc_handle);
blockpool->req_out--;
goto exit;
@@ -2359,11 +2359,10 @@ static void *__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size,
if (!memblock)
goto exit;
- dma_object->addr = pci_map_single(devh->pdev, memblock, size,
- PCI_DMA_BIDIRECTIONAL);
+ dma_object->addr = dma_map_single(&devh->pdev->dev, memblock,
+ size, DMA_BIDIRECTIONAL);
- if (unlikely(pci_dma_mapping_error(devh->pdev,
- dma_object->addr))) {
+ if (unlikely(dma_mapping_error(&devh->pdev->dev, dma_object->addr))) {
vxge_os_dma_free(devh->pdev, memblock,
&dma_object->acc_handle);
memblock = NULL;
@@ -2410,11 +2409,10 @@ __vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool)
if (blockpool->pool_size < blockpool->pool_max)
break;
- pci_unmap_single(
- (blockpool->hldev)->pdev,
- ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
- ((struct __vxge_hw_blockpool_entry *)p)->length,
- PCI_DMA_BIDIRECTIONAL);
+ dma_unmap_single(&(blockpool->hldev)->pdev->dev,
+ ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
+ ((struct __vxge_hw_blockpool_entry *)p)->length,
+ DMA_BIDIRECTIONAL);
vxge_os_dma_free(
(blockpool->hldev)->pdev,
@@ -2445,8 +2443,8 @@ static void __vxge_hw_blockpool_free(struct __vxge_hw_device *devh,
blockpool = &devh->block_pool;
if (size != blockpool->block_size) {
- pci_unmap_single(devh->pdev, dma_object->addr, size,
- PCI_DMA_BIDIRECTIONAL);
+ dma_unmap_single(&devh->pdev->dev, dma_object->addr, size,
+ DMA_BIDIRECTIONAL);
vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle);
} else {
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
index b5f1849fd280..1ded4e275086 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -241,10 +241,10 @@ static int vxge_rx_map(void *dtrh, struct vxge_ring *ring)
rx_priv = vxge_hw_ring_rxd_private_get(dtrh);
rx_priv->skb_data = rx_priv->skb->data;
- dma_addr = pci_map_single(ring->pdev, rx_priv->skb_data,
- rx_priv->data_size, PCI_DMA_FROMDEVICE);
+ dma_addr = dma_map_single(&ring->pdev->dev, rx_priv->skb_data,
+ rx_priv->data_size, DMA_FROM_DEVICE);
- if (unlikely(pci_dma_mapping_error(ring->pdev, dma_addr))) {
+ if (unlikely(dma_mapping_error(&ring->pdev->dev, dma_addr))) {
ring->stats.pci_map_fail++;
return -EIO;
}
@@ -323,8 +323,8 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan,
static inline void vxge_re_pre_post(void *dtr, struct vxge_ring *ring,
struct vxge_rx_priv *rx_priv)
{
- pci_dma_sync_single_for_device(ring->pdev,
- rx_priv->data_dma, rx_priv->data_size, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&ring->pdev->dev, rx_priv->data_dma,
+ rx_priv->data_size, DMA_FROM_DEVICE);
vxge_hw_ring_rxd_1b_set(dtr, rx_priv->data_dma, rx_priv->data_size);
vxge_hw_ring_rxd_pre_post(ring->handle, dtr);
@@ -425,8 +425,9 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
if (!vxge_rx_map(dtr, ring)) {
skb_put(skb, pkt_length);
- pci_unmap_single(ring->pdev, data_dma,
- data_size, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&ring->pdev->dev,
+ data_dma, data_size,
+ DMA_FROM_DEVICE);
vxge_hw_ring_rxd_pre_post(ringh, dtr);
vxge_post(&dtr_cnt, &first_dtr, dtr,
@@ -458,9 +459,9 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
skb_reserve(skb_up,
VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
- pci_dma_sync_single_for_cpu(ring->pdev,
- data_dma, data_size,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&ring->pdev->dev,
+ data_dma, data_size,
+ DMA_FROM_DEVICE);
vxge_debug_mem(VXGE_TRACE,
"%s: %s:%d skb_up = %p",
@@ -585,13 +586,13 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
}
/* for unfragmented skb */
- pci_unmap_single(fifo->pdev, txd_priv->dma_buffers[i++],
- skb_headlen(skb), PCI_DMA_TODEVICE);
+ dma_unmap_single(&fifo->pdev->dev, txd_priv->dma_buffers[i++],
+ skb_headlen(skb), DMA_TO_DEVICE);
for (j = 0; j < frg_cnt; j++) {
- pci_unmap_page(fifo->pdev,
- txd_priv->dma_buffers[i++],
- skb_frag_size(frag), PCI_DMA_TODEVICE);
+ dma_unmap_page(&fifo->pdev->dev,
+ txd_priv->dma_buffers[i++],
+ skb_frag_size(frag), DMA_TO_DEVICE);
frag += 1;
}
@@ -897,10 +898,10 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
first_frg_len = skb_headlen(skb);
- dma_pointer = pci_map_single(fifo->pdev, skb->data, first_frg_len,
- PCI_DMA_TODEVICE);
+ dma_pointer = dma_map_single(&fifo->pdev->dev, skb->data,
+ first_frg_len, DMA_TO_DEVICE);
- if (unlikely(pci_dma_mapping_error(fifo->pdev, dma_pointer))) {
+ if (unlikely(dma_mapping_error(&fifo->pdev->dev, dma_pointer))) {
vxge_hw_fifo_txdl_free(fifo_hw, dtr);
fifo->stats.pci_map_fail++;
goto _exit0;
@@ -977,12 +978,12 @@ _exit1:
j = 0;
frag = &skb_shinfo(skb)->frags[0];
- pci_unmap_single(fifo->pdev, txdl_priv->dma_buffers[j++],
- skb_headlen(skb), PCI_DMA_TODEVICE);
+ dma_unmap_single(&fifo->pdev->dev, txdl_priv->dma_buffers[j++],
+ skb_headlen(skb), DMA_TO_DEVICE);
for (; j < i; j++) {
- pci_unmap_page(fifo->pdev, txdl_priv->dma_buffers[j],
- skb_frag_size(frag), PCI_DMA_TODEVICE);
+ dma_unmap_page(&fifo->pdev->dev, txdl_priv->dma_buffers[j],
+ skb_frag_size(frag), DMA_TO_DEVICE);
frag += 1;
}
@@ -1012,8 +1013,8 @@ vxge_rx_term(void *dtrh, enum vxge_hw_rxd_state state, void *userdata)
if (state != VXGE_HW_RXD_STATE_POSTED)
return;
- pci_unmap_single(ring->pdev, rx_priv->data_dma,
- rx_priv->data_size, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&ring->pdev->dev, rx_priv->data_dma,
+ rx_priv->data_size, DMA_FROM_DEVICE);
dev_kfree_skb(rx_priv->skb);
rx_priv->skb_data = NULL;
@@ -1048,12 +1049,12 @@ vxge_tx_term(void *dtrh, enum vxge_hw_txdl_state state, void *userdata)
frag = &skb_shinfo(skb)->frags[0];
/* for unfragmented skb */
- pci_unmap_single(fifo->pdev, txd_priv->dma_buffers[i++],
- skb_headlen(skb), PCI_DMA_TODEVICE);
+ dma_unmap_single(&fifo->pdev->dev, txd_priv->dma_buffers[i++],
+ skb_headlen(skb), DMA_TO_DEVICE);
for (j = 0; j < frg_cnt; j++) {
- pci_unmap_page(fifo->pdev, txd_priv->dma_buffers[i++],
- skb_frag_size(frag), PCI_DMA_TODEVICE);
+ dma_unmap_page(&fifo->pdev->dev, txd_priv->dma_buffers[i++],
+ skb_frag_size(frag), DMA_TO_DEVICE);
frag += 1;
}
@@ -1075,7 +1076,7 @@ static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac)
list_for_each_safe(entry, next, &vpath->mac_addr_list) {
if (((struct vxge_mac_addrs *)entry)->macaddr == del_mac) {
list_del(entry);
- kfree((struct vxge_mac_addrs *)entry);
+ kfree(entry);
vpath->mac_addr_cnt--;
if (is_multicast_ether_addr(mac->macaddr))
@@ -2912,7 +2913,7 @@ static void vxge_free_mac_add_list(struct vxge_vpath *vpath)
list_for_each_safe(entry, next, &vpath->mac_addr_list) {
list_del(entry);
- kfree((struct vxge_mac_addrs *)entry);
+ kfree(entry);
}
}
@@ -3999,12 +4000,11 @@ static void vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask)
}
}
-#ifdef CONFIG_PM
/**
* vxge_pm_suspend - vxge power management suspend entry point
*
*/
-static int vxge_pm_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused vxge_pm_suspend(struct device *dev_d)
{
return -ENOSYS;
}
@@ -4012,13 +4012,11 @@ static int vxge_pm_suspend(struct pci_dev *pdev, pm_message_t state)
* vxge_pm_resume - vxge power management resume entry point
*
*/
-static int vxge_pm_resume(struct pci_dev *pdev)
+static int __maybe_unused vxge_pm_resume(struct device *dev_d)
{
return -ENOSYS;
}
-#endif
-
/**
* vxge_io_error_detected - called when PCI error is detected
* @pdev: Pointer to PCI device
@@ -4390,21 +4388,20 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
goto _exit0;
}
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
vxge_debug_ll_config(VXGE_TRACE,
"%s : using 64bit DMA", __func__);
high_dma = 1;
- if (pci_set_consistent_dma_mask(pdev,
- DMA_BIT_MASK(64))) {
+ if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
vxge_debug_init(VXGE_ERR,
"%s : unable to obtain 64bit DMA for "
"consistent allocations", __func__);
ret = -ENOMEM;
goto _exit1;
}
- } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
vxge_debug_ll_config(VXGE_TRACE,
"%s : using 32bit DMA", __func__);
} else {
@@ -4796,15 +4793,14 @@ static const struct pci_error_handlers vxge_err_handler = {
.resume = vxge_io_resume,
};
+static SIMPLE_DEV_PM_OPS(vxge_pm_ops, vxge_pm_suspend, vxge_pm_resume);
+
static struct pci_driver vxge_driver = {
.name = VXGE_DRIVER_NAME,
.id_table = vxge_id_table,
.probe = vxge_probe,
.remove = vxge_remove,
-#ifdef CONFIG_PM
- .suspend = vxge_pm_suspend,
- .resume = vxge_pm_resume,
-#endif
+ .driver.pm = &vxge_pm_ops,
.err_handler = &vxge_err_handler,
};
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h
index 7f54a620acad..3bf9c1afa45e 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -458,7 +458,7 @@ void nfp_flower_qos_cleanup(struct nfp_app *app);
int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,
struct tc_cls_matchall_offload *flow);
void nfp_flower_stats_rlim_reply(struct nfp_app *app, struct sk_buff *skb);
-int nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
+int nfp_flower_indr_setup_tc_cb(struct net_device *netdev, struct Qdisc *sch, void *cb_priv,
enum tc_setup_type type, void *type_data,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb));
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index d7340dc09b4c..4651fe417b7f 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -1491,7 +1491,7 @@ nfp_flower_get_stats(struct nfp_app *app, struct net_device *netdev,
nfp_flower_update_merge_stats(app, nfp_flow);
flow_stats_update(&flow->stats, priv->stats[ctx_id].bytes,
- priv->stats[ctx_id].pkts, priv->stats[ctx_id].used,
+ priv->stats[ctx_id].pkts, 0, priv->stats[ctx_id].used,
FLOW_ACTION_HW_STATS_DELAYED);
priv->stats[ctx_id].pkts = 0;
@@ -1646,7 +1646,7 @@ void nfp_flower_setup_indr_tc_release(void *cb_priv)
}
static int
-nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
+nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct Qdisc *sch, struct nfp_app *app,
struct flow_block_offload *f, void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
{
@@ -1680,7 +1680,7 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
block_cb = flow_indr_block_cb_alloc(nfp_flower_setup_indr_block_cb,
cb_priv, cb_priv,
nfp_flower_setup_indr_tc_release,
- f, netdev, data, app, cleanup);
+ f, netdev, sch, data, app, cleanup);
if (IS_ERR(block_cb)) {
list_del(&cb_priv->list);
kfree(cb_priv);
@@ -1711,7 +1711,7 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
}
int
-nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
+nfp_flower_indr_setup_tc_cb(struct net_device *netdev, struct Qdisc *sch, void *cb_priv,
enum tc_setup_type type, void *type_data,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
@@ -1721,7 +1721,7 @@ nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
switch (type) {
case TC_SETUP_BLOCK:
- return nfp_flower_setup_indr_tc_block(netdev, cb_priv,
+ return nfp_flower_setup_indr_tc_block(netdev, sch, cb_priv,
type_data, data, cleanup);
default:
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
index d18a830e4264..d4ce8f9ef3cc 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
@@ -69,7 +69,8 @@ nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev,
struct nfp_repr *repr;
struct sk_buff *skb;
u32 netdev_port_id;
- u64 burst, rate;
+ u32 burst;
+ u64 rate;
if (!nfp_netdev_is_nfp_repr(netdev)) {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: qos rate limit offload not supported on higher level port");
@@ -104,8 +105,7 @@ nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev,
}
rate = action->police.rate_bytes_ps;
- burst = div_u64(rate * PSCHED_NS2TICKS(action->police.burst),
- PSCHED_TICKS_PER_SEC);
+ burst = action->police.burst;
netdev_port_id = nfp_repr_get_port_id(netdev);
skb = nfp_flower_cmsg_alloc(repr->app, sizeof(struct nfp_police_config),
@@ -319,7 +319,7 @@ nfp_flower_stats_rate_limiter(struct nfp_app *app, struct net_device *netdev,
prev_stats->bytes = curr_stats->bytes;
spin_unlock_bh(&fl_priv->qos_stats_lock);
- flow_stats_update(&flow->stats, diff_bytes, diff_pkts,
+ flow_stats_update(&flow->stats, diff_bytes, diff_pkts, 0,
repr_priv->qos_table.last_update,
FLOW_ACTION_HW_STATS_DELAYED);
return 0;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index 07dbf4d72227..be52510d446b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -70,9 +70,6 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
unsigned int lanes;
int ret;
- if (count < 2)
- return -EINVAL;
-
mutex_lock(&pf->lock);
rtnl_lock();
@@ -81,7 +78,7 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
if (ret)
goto out;
- if (eth_port.is_split || eth_port.port_lanes % count) {
+ if (eth_port.port_lanes % count) {
ret = -EINVAL;
goto out;
}
@@ -353,6 +350,7 @@ const struct devlink_ops nfp_devlink_ops = {
int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
{
+ struct devlink_port_attrs attrs = {};
struct nfp_eth_table_port eth_port;
struct devlink *devlink;
const u8 *serial;
@@ -365,10 +363,15 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
if (ret)
return ret;
+ attrs.split = eth_port.is_split;
+ attrs.splittable = !attrs.split;
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = eth_port.label_port;
+ attrs.phys.split_subport_number = eth_port.label_subport;
serial_len = nfp_cpp_serial(port->app->cpp, &serial);
- devlink_port_attrs_set(&port->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- eth_port.label_port, eth_port.is_split,
- eth_port.label_subport, serial, serial_len);
+ memcpy(attrs.switch_id.id, serial, serial_len);
+ attrs.switch_id.id_len = serial_len;
+ devlink_port_attrs_set(&port->dl_port, &attrs);
devlink = priv_to_devlink(app->pf);
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index ff4438478ea9..df5b748be068 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -575,8 +575,6 @@ struct nfp_net_dp {
* @rx_coalesce_max_frames: RX interrupt moderation frame count parameter
* @tx_coalesce_usecs: TX interrupt moderation usecs delay parameter
* @tx_coalesce_max_frames: TX interrupt moderation frame count parameter
- * @vxlan_ports: VXLAN ports for RX inner csum offload communicated to HW
- * @vxlan_usecnt: IPv4/IPv6 VXLAN port use counts
* @qcp_cfg: Pointer to QCP queue used for configuration notification
* @tx_bar: Pointer to mapped TX queues
* @rx_bar: Pointer to mapped FL/RX queues
@@ -661,9 +659,6 @@ struct nfp_net {
u32 tx_coalesce_usecs;
u32 tx_coalesce_max_frames;
- __be16 vxlan_ports[NFP_NET_N_VXLAN_PORTS];
- u8 vxlan_usecnt[NFP_NET_N_VXLAN_PORTS];
-
u8 __iomem *qcp_cfg;
u8 __iomem *tx_bar;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 0e0cc3d58bdc..39ee23e8c0bf 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -974,7 +974,7 @@ static int nfp_net_prep_tx_meta(struct sk_buff *skb, u64 tls_handle)
*
* Return: NETDEV_TX_OK on success.
*/
-static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
{
struct nfp_net *nn = netdev_priv(netdev);
const skb_frag_t *frag;
@@ -2867,15 +2867,6 @@ static int nfp_net_set_config_and_enable(struct nfp_net *nn)
for (r = 0; r < nn->dp.num_rx_rings; r++)
nfp_net_rx_ring_fill_freelist(&nn->dp, &nn->dp.rx_rings[r]);
- /* Since reconfiguration requests while NFP is down are ignored we
- * have to wipe the entire VXLAN configuration and reinitialize it.
- */
- if (nn->dp.ctrl & NFP_NET_CFG_CTRL_VXLAN) {
- memset(&nn->vxlan_ports, 0, sizeof(nn->vxlan_ports));
- memset(&nn->vxlan_usecnt, 0, sizeof(nn->vxlan_usecnt));
- udp_tunnel_get_rx_info(nn->dp.netdev);
- }
-
return 0;
}
@@ -3566,87 +3557,6 @@ nfp_net_get_phys_port_name(struct net_device *netdev, char *name, size_t len)
return 0;
}
-/**
- * nfp_net_set_vxlan_port() - set vxlan port in SW and reconfigure HW
- * @nn: NFP Net device to reconfigure
- * @idx: Index into the port table where new port should be written
- * @port: UDP port to configure (pass zero to remove VXLAN port)
- */
-static void nfp_net_set_vxlan_port(struct nfp_net *nn, int idx, __be16 port)
-{
- int i;
-
- nn->vxlan_ports[idx] = port;
-
- if (!(nn->dp.ctrl & NFP_NET_CFG_CTRL_VXLAN))
- return;
-
- BUILD_BUG_ON(NFP_NET_N_VXLAN_PORTS & 1);
- for (i = 0; i < NFP_NET_N_VXLAN_PORTS; i += 2)
- nn_writel(nn, NFP_NET_CFG_VXLAN_PORT + i * sizeof(port),
- be16_to_cpu(nn->vxlan_ports[i + 1]) << 16 |
- be16_to_cpu(nn->vxlan_ports[i]));
-
- nfp_net_reconfig_post(nn, NFP_NET_CFG_UPDATE_VXLAN);
-}
-
-/**
- * nfp_net_find_vxlan_idx() - find table entry of the port or a free one
- * @nn: NFP Network structure
- * @port: UDP port to look for
- *
- * Return: if the port is already in the table -- it's position;
- * if the port is not in the table -- free position to use;
- * if the table is full -- -ENOSPC.
- */
-static int nfp_net_find_vxlan_idx(struct nfp_net *nn, __be16 port)
-{
- int i, free_idx = -ENOSPC;
-
- for (i = 0; i < NFP_NET_N_VXLAN_PORTS; i++) {
- if (nn->vxlan_ports[i] == port)
- return i;
- if (!nn->vxlan_usecnt[i])
- free_idx = i;
- }
-
- return free_idx;
-}
-
-static void nfp_net_add_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- struct nfp_net *nn = netdev_priv(netdev);
- int idx;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- idx = nfp_net_find_vxlan_idx(nn, ti->port);
- if (idx == -ENOSPC)
- return;
-
- if (!nn->vxlan_usecnt[idx]++)
- nfp_net_set_vxlan_port(nn, idx, ti->port);
-}
-
-static void nfp_net_del_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- struct nfp_net *nn = netdev_priv(netdev);
- int idx;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- idx = nfp_net_find_vxlan_idx(nn, ti->port);
- if (idx == -ENOSPC || !nn->vxlan_usecnt[idx])
- return;
-
- if (!--nn->vxlan_usecnt[idx])
- nfp_net_set_vxlan_port(nn, idx, 0);
-}
-
static int nfp_net_xdp_setup_drv(struct nfp_net *nn, struct netdev_bpf *bpf)
{
struct bpf_prog *prog = bpf->prog;
@@ -3704,10 +3614,6 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_bpf *xdp)
return nfp_net_xdp_setup_drv(nn, xdp);
case XDP_SETUP_PROG_HW:
return nfp_net_xdp_setup_hw(nn, xdp);
- case XDP_QUERY_PROG:
- return xdp_attachment_query(&nn->xdp, xdp);
- case XDP_QUERY_PROG_HW:
- return xdp_attachment_query(&nn->xdp_hw, xdp);
default:
return nfp_app_bpf(nn->app, nn, xdp);
}
@@ -3757,12 +3663,43 @@ const struct net_device_ops nfp_net_netdev_ops = {
.ndo_set_features = nfp_net_set_features,
.ndo_features_check = nfp_net_features_check,
.ndo_get_phys_port_name = nfp_net_get_phys_port_name,
- .ndo_udp_tunnel_add = nfp_net_add_vxlan_port,
- .ndo_udp_tunnel_del = nfp_net_del_vxlan_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_bpf = nfp_net_xdp,
.ndo_get_devlink_port = nfp_devlink_get_devlink_port,
};
+static int nfp_udp_tunnel_sync(struct net_device *netdev, unsigned int table)
+{
+ struct nfp_net *nn = netdev_priv(netdev);
+ int i;
+
+ BUILD_BUG_ON(NFP_NET_N_VXLAN_PORTS & 1);
+ for (i = 0; i < NFP_NET_N_VXLAN_PORTS; i += 2) {
+ struct udp_tunnel_info ti0, ti1;
+
+ udp_tunnel_nic_get_port(netdev, table, i, &ti0);
+ udp_tunnel_nic_get_port(netdev, table, i + 1, &ti1);
+
+ nn_writel(nn, NFP_NET_CFG_VXLAN_PORT + i * sizeof(ti0.port),
+ be16_to_cpu(ti1.port) << 16 | be16_to_cpu(ti0.port));
+ }
+
+ return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_VXLAN);
+}
+
+static const struct udp_tunnel_nic_info nfp_udp_tunnels = {
+ .sync_table = nfp_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
+ UDP_TUNNEL_NIC_INFO_OPEN_ONLY,
+ .tables = {
+ {
+ .n_entries = NFP_NET_N_VXLAN_PORTS,
+ .tunnel_types = UDP_TUNNEL_TYPE_VXLAN,
+ },
+ },
+};
+
/**
* nfp_net_info() - Print general info about the NIC
* @nn: NFP Net device to reconfigure
@@ -4010,6 +3947,7 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
if (nn->cap & NFP_NET_CFG_CTRL_VXLAN) {
if (nn->cap & NFP_NET_CFG_CTRL_LSO)
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
+ netdev->udp_tunnel_nic_info = &nfp_udp_tunnels;
nn->dp.ctrl |= NFP_NET_CFG_CTRL_VXLAN;
}
if (nn->cap & NFP_NET_CFG_CTRL_NVGRE) {
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 73ec195fbc30..23f7c76737c9 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -2064,7 +2064,7 @@ static int pch_gbe_stop(struct net_device *netdev)
* - NETDEV_TX_OK: Normal end
* - NETDEV_TX_BUSY: Error end
*/
-static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c
index 70816d2e2990..d058a63602a9 100644
--- a/drivers/net/ethernet/packetengines/hamachi.c
+++ b/drivers/net/ethernet/packetengines/hamachi.c
@@ -644,13 +644,15 @@ static int hamachi_init_one(struct pci_dev *pdev,
hmp->mii_if.phy_id_mask = 0x1f;
hmp->mii_if.reg_num_mask = 0x1f;
- ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE, &ring_dma,
+ GFP_KERNEL);
if (!ring_space)
goto err_out_cleardev;
hmp->tx_ring = ring_space;
hmp->tx_ring_dma = ring_dma;
- ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE, &ring_dma,
+ GFP_KERNEL);
if (!ring_space)
goto err_out_unmap_tx;
hmp->rx_ring = ring_space;
@@ -773,11 +775,11 @@ static int hamachi_init_one(struct pci_dev *pdev,
return 0;
err_out_unmap_rx:
- pci_free_consistent(pdev, RX_TOTAL_SIZE, hmp->rx_ring,
- hmp->rx_ring_dma);
+ dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, hmp->rx_ring,
+ hmp->rx_ring_dma);
err_out_unmap_tx:
- pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring,
- hmp->tx_ring_dma);
+ dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, hmp->tx_ring,
+ hmp->tx_ring_dma);
err_out_cleardev:
free_netdev (dev);
err_out_iounmap:
@@ -1001,9 +1003,9 @@ static inline int hamachi_tx(struct net_device *dev)
/* Free the original skb. */
skb = hmp->tx_skbuff[entry];
if (skb) {
- pci_unmap_single(hmp->pci_dev,
- leXX_to_cpu(hmp->tx_ring[entry].addr),
- skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&hmp->pci_dev->dev,
+ leXX_to_cpu(hmp->tx_ring[entry].addr),
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb(skb);
hmp->tx_skbuff[entry] = NULL;
}
@@ -1093,8 +1095,9 @@ static void hamachi_tx_timeout(struct net_device *dev, unsigned int txqueue)
hmp->tx_ring[i].status_n_length &= cpu_to_le32(0x0000ffff);
skb = hmp->tx_skbuff[i];
if (skb){
- pci_unmap_single(hmp->pci_dev, leXX_to_cpu(hmp->tx_ring[i].addr),
- skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&hmp->pci_dev->dev,
+ leXX_to_cpu(hmp->tx_ring[i].addr),
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb(skb);
hmp->tx_skbuff[i] = NULL;
}
@@ -1115,9 +1118,9 @@ static void hamachi_tx_timeout(struct net_device *dev, unsigned int txqueue)
struct sk_buff *skb = hmp->rx_skbuff[i];
if (skb){
- pci_unmap_single(hmp->pci_dev,
- leXX_to_cpu(hmp->rx_ring[i].addr),
- hmp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&hmp->pci_dev->dev,
+ leXX_to_cpu(hmp->rx_ring[i].addr),
+ hmp->rx_buf_sz, DMA_FROM_DEVICE);
dev_kfree_skb(skb);
hmp->rx_skbuff[i] = NULL;
}
@@ -1131,8 +1134,10 @@ static void hamachi_tx_timeout(struct net_device *dev, unsigned int txqueue)
if (skb == NULL)
break;
- hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
- skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ hmp->rx_ring[i].addr = cpu_to_leXX(dma_map_single(&hmp->pci_dev->dev,
+ skb->data,
+ hmp->rx_buf_sz,
+ DMA_FROM_DEVICE));
hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2));
}
@@ -1183,8 +1188,10 @@ static void hamachi_init_ring(struct net_device *dev)
if (skb == NULL)
break;
skb_reserve(skb, 2); /* 16 byte align the IP header. */
- hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
- skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ hmp->rx_ring[i].addr = cpu_to_leXX(dma_map_single(&hmp->pci_dev->dev,
+ skb->data,
+ hmp->rx_buf_sz,
+ DMA_FROM_DEVICE));
/* -2 because it doesn't REALLY have that first 2 bytes -KDU */
hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
DescEndPacket | DescIntr | (hmp->rx_buf_sz -2));
@@ -1233,8 +1240,10 @@ static netdev_tx_t hamachi_start_xmit(struct sk_buff *skb,
hmp->tx_skbuff[entry] = skb;
- hmp->tx_ring[entry].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
- skb->data, skb->len, PCI_DMA_TODEVICE));
+ hmp->tx_ring[entry].addr = cpu_to_leXX(dma_map_single(&hmp->pci_dev->dev,
+ skb->data,
+ skb->len,
+ DMA_TO_DEVICE));
/* Hmmmm, could probably put a DescIntr on these, but the way
the driver is currently coded makes Tx interrupts unnecessary
@@ -1333,10 +1342,10 @@ static irqreturn_t hamachi_interrupt(int irq, void *dev_instance)
skb = hmp->tx_skbuff[entry];
/* Free the original skb. */
if (skb){
- pci_unmap_single(hmp->pci_dev,
- leXX_to_cpu(hmp->tx_ring[entry].addr),
- skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&hmp->pci_dev->dev,
+ leXX_to_cpu(hmp->tx_ring[entry].addr),
+ skb->len,
+ DMA_TO_DEVICE);
dev_consume_skb_irq(skb);
hmp->tx_skbuff[entry] = NULL;
}
@@ -1413,10 +1422,9 @@ static int hamachi_rx(struct net_device *dev)
if (desc_status & DescOwn)
break;
- pci_dma_sync_single_for_cpu(hmp->pci_dev,
- leXX_to_cpu(desc->addr),
- hmp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&hmp->pci_dev->dev,
+ leXX_to_cpu(desc->addr),
+ hmp->rx_buf_sz, DMA_FROM_DEVICE);
buf_addr = (u8 *) hmp->rx_skbuff[entry]->data;
frame_status = get_unaligned_le32(&(buf_addr[data_size - 12]));
if (hamachi_debug > 4)
@@ -1483,10 +1491,10 @@ static int hamachi_rx(struct net_device *dev)
"not good with RX_CHECKSUM\n", dev->name);
#endif
skb_reserve(skb, 2); /* 16 byte align the IP header */
- pci_dma_sync_single_for_cpu(hmp->pci_dev,
- leXX_to_cpu(hmp->rx_ring[entry].addr),
- hmp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&hmp->pci_dev->dev,
+ leXX_to_cpu(hmp->rx_ring[entry].addr),
+ hmp->rx_buf_sz,
+ DMA_FROM_DEVICE);
/* Call copy + cksum if available. */
#if 1 || USE_IP_COPYSUM
skb_copy_to_linear_data(skb,
@@ -1496,14 +1504,15 @@ static int hamachi_rx(struct net_device *dev)
skb_put_data(skb, hmp->rx_ring_dma
+ entry*sizeof(*desc), pkt_len);
#endif
- pci_dma_sync_single_for_device(hmp->pci_dev,
- leXX_to_cpu(hmp->rx_ring[entry].addr),
- hmp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&hmp->pci_dev->dev,
+ leXX_to_cpu(hmp->rx_ring[entry].addr),
+ hmp->rx_buf_sz,
+ DMA_FROM_DEVICE);
} else {
- pci_unmap_single(hmp->pci_dev,
+ dma_unmap_single(&hmp->pci_dev->dev,
leXX_to_cpu(hmp->rx_ring[entry].addr),
- hmp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ hmp->rx_buf_sz,
+ DMA_FROM_DEVICE);
skb_put(skb = hmp->rx_skbuff[entry], pkt_len);
hmp->rx_skbuff[entry] = NULL;
}
@@ -1586,8 +1595,10 @@ static int hamachi_rx(struct net_device *dev)
if (skb == NULL)
break; /* Better luck next round. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
- skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ desc->addr = cpu_to_leXX(dma_map_single(&hmp->pci_dev->dev,
+ skb->data,
+ hmp->rx_buf_sz,
+ DMA_FROM_DEVICE));
}
desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz);
if (entry >= RX_RING_SIZE-1)
@@ -1704,9 +1715,9 @@ static int hamachi_close(struct net_device *dev)
skb = hmp->rx_skbuff[i];
hmp->rx_ring[i].status_n_length = 0;
if (skb) {
- pci_unmap_single(hmp->pci_dev,
- leXX_to_cpu(hmp->rx_ring[i].addr),
- hmp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&hmp->pci_dev->dev,
+ leXX_to_cpu(hmp->rx_ring[i].addr),
+ hmp->rx_buf_sz, DMA_FROM_DEVICE);
dev_kfree_skb(skb);
hmp->rx_skbuff[i] = NULL;
}
@@ -1715,9 +1726,9 @@ static int hamachi_close(struct net_device *dev)
for (i = 0; i < TX_RING_SIZE; i++) {
skb = hmp->tx_skbuff[i];
if (skb) {
- pci_unmap_single(hmp->pci_dev,
- leXX_to_cpu(hmp->tx_ring[i].addr),
- skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&hmp->pci_dev->dev,
+ leXX_to_cpu(hmp->tx_ring[i].addr),
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb(skb);
hmp->tx_skbuff[i] = NULL;
}
@@ -1899,10 +1910,10 @@ static void hamachi_remove_one(struct pci_dev *pdev)
if (dev) {
struct hamachi_private *hmp = netdev_priv(dev);
- pci_free_consistent(pdev, RX_TOTAL_SIZE, hmp->rx_ring,
- hmp->rx_ring_dma);
- pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring,
- hmp->tx_ring_dma);
+ dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, hmp->rx_ring,
+ hmp->rx_ring_dma);
+ dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, hmp->tx_ring,
+ hmp->tx_ring_dma);
unregister_netdev(dev);
iounmap(hmp->base);
free_netdev(dev);
diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c
index 520779f05e1a..647a1431b359 100644
--- a/drivers/net/ethernet/packetengines/yellowfin.c
+++ b/drivers/net/ethernet/packetengines/yellowfin.c
@@ -434,19 +434,22 @@ static int yellowfin_init_one(struct pci_dev *pdev,
np->drv_flags = drv_flags;
np->base = ioaddr;
- ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE, &ring_dma,
+ GFP_KERNEL);
if (!ring_space)
goto err_out_cleardev;
np->tx_ring = ring_space;
np->tx_ring_dma = ring_dma;
- ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE, &ring_dma,
+ GFP_KERNEL);
if (!ring_space)
goto err_out_unmap_tx;
np->rx_ring = ring_space;
np->rx_ring_dma = ring_dma;
- ring_space = pci_alloc_consistent(pdev, STATUS_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pdev->dev, STATUS_TOTAL_SIZE,
+ &ring_dma, GFP_KERNEL);
if (!ring_space)
goto err_out_unmap_rx;
np->tx_status = ring_space;
@@ -505,12 +508,14 @@ static int yellowfin_init_one(struct pci_dev *pdev,
return 0;
err_out_unmap_status:
- pci_free_consistent(pdev, STATUS_TOTAL_SIZE, np->tx_status,
- np->tx_status_dma);
+ dma_free_coherent(&pdev->dev, STATUS_TOTAL_SIZE, np->tx_status,
+ np->tx_status_dma);
err_out_unmap_rx:
- pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
+ dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring,
+ np->rx_ring_dma);
err_out_unmap_tx:
- pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
+ dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring,
+ np->tx_ring_dma);
err_out_cleardev:
pci_iounmap(pdev, ioaddr);
err_out_free_res:
@@ -740,8 +745,10 @@ static int yellowfin_init_ring(struct net_device *dev)
if (skb == NULL)
break;
skb_reserve(skb, 2); /* 16 byte align the IP header. */
- yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
- skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ yp->rx_ring[i].addr = cpu_to_le32(dma_map_single(&yp->pci_dev->dev,
+ skb->data,
+ yp->rx_buf_sz,
+ DMA_FROM_DEVICE));
}
if (i != RX_RING_SIZE) {
for (j = 0; j < i; j++)
@@ -831,8 +838,9 @@ static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb,
yp->tx_skbuff[entry] = skb;
#ifdef NO_TXSTATS
- yp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
- skb->data, len, PCI_DMA_TODEVICE));
+ yp->tx_ring[entry].addr = cpu_to_le32(dma_map_single(&yp->pci_dev->dev,
+ skb->data,
+ len, DMA_TO_DEVICE));
yp->tx_ring[entry].result_status = 0;
if (entry >= TX_RING_SIZE-1) {
/* New stop command. */
@@ -847,8 +855,9 @@ static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb,
yp->cur_tx++;
#else
yp->tx_ring[entry<<1].request_cnt = len;
- yp->tx_ring[entry<<1].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
- skb->data, len, PCI_DMA_TODEVICE));
+ yp->tx_ring[entry<<1].addr = cpu_to_le32(dma_map_single(&yp->pci_dev->dev,
+ skb->data,
+ len, DMA_TO_DEVICE));
/* The input_last (status-write) command is constant, but we must
rewrite the subsequent 'stop' command. */
@@ -923,8 +932,9 @@ static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance)
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
/* Free the original skb. */
- pci_unmap_single(yp->pci_dev, le32_to_cpu(yp->tx_ring[entry].addr),
- skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&yp->pci_dev->dev,
+ le32_to_cpu(yp->tx_ring[entry].addr),
+ skb->len, DMA_TO_DEVICE);
dev_consume_skb_irq(skb);
yp->tx_skbuff[entry] = NULL;
}
@@ -980,9 +990,9 @@ static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance)
dev->stats.tx_packets++;
}
/* Free the original skb. */
- pci_unmap_single(yp->pci_dev,
- yp->tx_ring[entry<<1].addr, skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&yp->pci_dev->dev,
+ yp->tx_ring[entry << 1].addr,
+ skb->len, DMA_TO_DEVICE);
dev_consume_skb_irq(skb);
yp->tx_skbuff[entry] = 0;
/* Mark status as empty. */
@@ -1055,8 +1065,9 @@ static int yellowfin_rx(struct net_device *dev)
if(!desc->result_status)
break;
- pci_dma_sync_single_for_cpu(yp->pci_dev, le32_to_cpu(desc->addr),
- yp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&yp->pci_dev->dev,
+ le32_to_cpu(desc->addr),
+ yp->rx_buf_sz, DMA_FROM_DEVICE);
desc_status = le32_to_cpu(desc->result_status) >> 16;
buf_addr = rx_skb->data;
data_size = (le32_to_cpu(desc->dbdma_cmd) -
@@ -1121,10 +1132,10 @@ static int yellowfin_rx(struct net_device *dev)
without copying to a properly sized skbuff. */
if (pkt_len > rx_copybreak) {
skb_put(skb = rx_skb, pkt_len);
- pci_unmap_single(yp->pci_dev,
- le32_to_cpu(yp->rx_ring[entry].addr),
- yp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&yp->pci_dev->dev,
+ le32_to_cpu(yp->rx_ring[entry].addr),
+ yp->rx_buf_sz,
+ DMA_FROM_DEVICE);
yp->rx_skbuff[entry] = NULL;
} else {
skb = netdev_alloc_skb(dev, pkt_len + 2);
@@ -1133,10 +1144,10 @@ static int yellowfin_rx(struct net_device *dev)
skb_reserve(skb, 2); /* 16 byte align the IP header */
skb_copy_to_linear_data(skb, rx_skb->data, pkt_len);
skb_put(skb, pkt_len);
- pci_dma_sync_single_for_device(yp->pci_dev,
- le32_to_cpu(desc->addr),
- yp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&yp->pci_dev->dev,
+ le32_to_cpu(desc->addr),
+ yp->rx_buf_sz,
+ DMA_FROM_DEVICE);
}
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
@@ -1155,8 +1166,10 @@ static int yellowfin_rx(struct net_device *dev)
break; /* Better luck next round. */
yp->rx_skbuff[entry] = skb;
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
- skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ yp->rx_ring[entry].addr = cpu_to_le32(dma_map_single(&yp->pci_dev->dev,
+ skb->data,
+ yp->rx_buf_sz,
+ DMA_FROM_DEVICE));
}
yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP);
yp->rx_ring[entry].result_status = 0; /* Clear complete bit. */
@@ -1379,10 +1392,12 @@ static void yellowfin_remove_one(struct pci_dev *pdev)
BUG_ON(!dev);
np = netdev_priv(dev);
- pci_free_consistent(pdev, STATUS_TOTAL_SIZE, np->tx_status,
- np->tx_status_dma);
- pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
- pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
+ dma_free_coherent(&pdev->dev, STATUS_TOTAL_SIZE, np->tx_status,
+ np->tx_status_dma);
+ dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring,
+ np->rx_ring_dma);
+ dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring,
+ np->tx_ring_dma);
unregister_netdev (dev);
pci_iounmap(pdev, np->base);
diff --git a/drivers/net/ethernet/pensando/Kconfig b/drivers/net/ethernet/pensando/Kconfig
index d25b88f53de4..76f8cc502bf9 100644
--- a/drivers/net/ethernet/pensando/Kconfig
+++ b/drivers/net/ethernet/pensando/Kconfig
@@ -25,7 +25,7 @@ config IONIC
This enables the support for the Pensando family of Ethernet
adapters. More specific information on this driver can be
found in
- <file:Documentation/networking/device_drivers/pensando/ionic.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/pensando/ionic.rst>.
To compile this driver as a module, choose M here. The module
will be called ionic.
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
index 2924cde440aa..85c686c16741 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
@@ -247,12 +247,11 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_pci_disable_device;
}
- pci_set_master(pdev);
pcie_print_link_status(pdev);
err = ionic_map_bars(ionic);
if (err)
- goto err_out_pci_clear_master;
+ goto err_out_pci_disable_device;
/* Configure the device */
err = ionic_setup(ionic);
@@ -260,6 +259,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_err(dev, "Cannot setup device: %d, aborting\n", err);
goto err_out_unmap_bars;
}
+ pci_set_master(pdev);
err = ionic_identify(ionic);
if (err) {
@@ -350,6 +350,7 @@ err_out_reset:
ionic_reset(ionic);
err_out_teardown:
ionic_dev_teardown(ionic);
+ pci_clear_master(pdev);
/* Don't fail the probe for these errors, keep
* the hw interface around for inspection
*/
@@ -358,8 +359,6 @@ err_out_teardown:
err_out_unmap_bars:
ionic_unmap_bars(ionic);
pci_release_regions(pdev);
-err_out_pci_clear_master:
- pci_clear_master(pdev);
err_out_pci_disable_device:
pci_disable_device(pdev);
err_out_debugfs_del_dev:
@@ -389,9 +388,9 @@ static void ionic_remove(struct pci_dev *pdev)
ionic_port_reset(ionic);
ionic_reset(ionic);
ionic_dev_teardown(ionic);
+ pci_clear_master(pdev);
ionic_unmap_bars(ionic);
pci_release_regions(pdev);
- pci_clear_master(pdev);
pci_disable_device(pdev);
ionic_debugfs_del_dev(ionic);
mutex_destroy(&ionic->dev_cmd_lock);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 525434f10025..d5cba502abca 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -10,8 +10,6 @@
#include "ionic_if.h"
#include "ionic_regs.h"
-#define IONIC_MIN_MTU ETH_MIN_MTU
-#define IONIC_MAX_MTU 9194
#define IONIC_MAX_TX_DESC 8192
#define IONIC_MAX_RX_DESC 16384
#define IONIC_MIN_TXRX_DESC 16
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c
index 2d590e571133..c4f4fd469fe3 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c
@@ -69,6 +69,7 @@ void ionic_devlink_free(struct ionic *ionic)
int ionic_devlink_register(struct ionic *ionic)
{
struct devlink *dl = priv_to_devlink(ionic);
+ struct devlink_port_attrs attrs = {};
int err;
err = devlink_register(dl, ionic->dev);
@@ -77,8 +78,8 @@ int ionic_devlink_register(struct ionic *ionic)
return err;
}
- devlink_port_attrs_set(&ionic->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- 0, false, 0, NULL, 0);
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ devlink_port_attrs_set(&ionic->dl_port, &attrs);
err = devlink_port_register(dl, &ionic->dl_port, 0);
if (err)
dev_err(ionic->dev, "devlink_port_register failed: %d\n", err);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index 095561924bdc..3c57c331729f 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -403,8 +403,7 @@ static int ionic_get_coalesce(struct net_device *netdev,
{
struct ionic_lif *lif = netdev_priv(netdev);
- /* Tx uses Rx interrupt */
- coalesce->tx_coalesce_usecs = lif->rx_coalesce_usecs;
+ coalesce->tx_coalesce_usecs = lif->tx_coalesce_usecs;
coalesce->rx_coalesce_usecs = lif->rx_coalesce_usecs;
return 0;
@@ -417,7 +416,8 @@ static int ionic_set_coalesce(struct net_device *netdev,
struct ionic_identity *ident;
struct ionic_qcq *qcq;
unsigned int i;
- u32 coal;
+ u32 rx_coal;
+ u32 tx_coal;
ident = &lif->ionic->ident;
if (ident->dev.intr_coal_div == 0) {
@@ -426,26 +426,31 @@ static int ionic_set_coalesce(struct net_device *netdev,
return -EIO;
}
- /* Tx uses Rx interrupt, so only change Rx */
- if (coalesce->tx_coalesce_usecs != lif->rx_coalesce_usecs) {
+ /* Tx normally shares Rx interrupt, so only change Rx */
+ if (!test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state) &&
+ coalesce->tx_coalesce_usecs != lif->rx_coalesce_usecs) {
netdev_warn(netdev, "only the rx-usecs can be changed\n");
return -EINVAL;
}
- /* Convert the usec request to a HW useable value. If they asked
+ /* Convert the usec request to a HW usable value. If they asked
* for non-zero and it resolved to zero, bump it up
*/
- coal = ionic_coal_usec_to_hw(lif->ionic, coalesce->rx_coalesce_usecs);
- if (!coal && coalesce->rx_coalesce_usecs)
- coal = 1;
-
- if (coal > IONIC_INTR_CTRL_COAL_MAX)
+ rx_coal = ionic_coal_usec_to_hw(lif->ionic, coalesce->rx_coalesce_usecs);
+ if (!rx_coal && coalesce->rx_coalesce_usecs)
+ rx_coal = 1;
+ tx_coal = ionic_coal_usec_to_hw(lif->ionic, coalesce->tx_coalesce_usecs);
+ if (!tx_coal && coalesce->tx_coalesce_usecs)
+ tx_coal = 1;
+
+ if (rx_coal > IONIC_INTR_CTRL_COAL_MAX ||
+ tx_coal > IONIC_INTR_CTRL_COAL_MAX)
return -ERANGE;
- /* Save the new value */
+ /* Save the new values */
lif->rx_coalesce_usecs = coalesce->rx_coalesce_usecs;
- if (coal != lif->rx_coalesce_hw) {
- lif->rx_coalesce_hw = coal;
+ if (rx_coal != lif->rx_coalesce_hw) {
+ lif->rx_coalesce_hw = rx_coal;
if (test_bit(IONIC_LIF_F_UP, lif->state)) {
for (i = 0; i < lif->nxqs; i++) {
@@ -457,6 +462,23 @@ static int ionic_set_coalesce(struct net_device *netdev,
}
}
+ if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
+ lif->tx_coalesce_usecs = coalesce->tx_coalesce_usecs;
+ else
+ lif->tx_coalesce_usecs = coalesce->rx_coalesce_usecs;
+ if (tx_coal != lif->tx_coalesce_hw) {
+ lif->tx_coalesce_hw = tx_coal;
+
+ if (test_bit(IONIC_LIF_F_UP, lif->state)) {
+ for (i = 0; i < lif->nxqs; i++) {
+ qcq = lif->txqcqs[i].qcq;
+ ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
+ qcq->intr.index,
+ lif->tx_coalesce_hw);
+ }
+ }
+ }
+
return 0;
}
@@ -510,29 +532,63 @@ static void ionic_get_channels(struct net_device *netdev,
/* report maximum channels */
ch->max_combined = lif->ionic->ntxqs_per_lif;
+ ch->max_rx = lif->ionic->ntxqs_per_lif / 2;
+ ch->max_tx = lif->ionic->ntxqs_per_lif / 2;
/* report current channels */
- ch->combined_count = lif->nxqs;
+ if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) {
+ ch->rx_count = lif->nxqs;
+ ch->tx_count = lif->nxqs;
+ } else {
+ ch->combined_count = lif->nxqs;
+ }
}
static void ionic_set_queuecount(struct ionic_lif *lif, void *arg)
{
struct ethtool_channels *ch = arg;
- lif->nxqs = ch->combined_count;
+ if (ch->combined_count) {
+ lif->nxqs = ch->combined_count;
+ if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) {
+ clear_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
+ lif->tx_coalesce_usecs = lif->rx_coalesce_usecs;
+ lif->tx_coalesce_hw = lif->rx_coalesce_hw;
+ netdev_info(lif->netdev, "Sharing queue interrupts\n");
+ }
+ } else {
+ lif->nxqs = ch->rx_count;
+ if (!test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) {
+ set_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
+ netdev_info(lif->netdev, "Splitting queue interrupts\n");
+ }
+ }
}
static int ionic_set_channels(struct net_device *netdev,
struct ethtool_channels *ch)
{
struct ionic_lif *lif = netdev_priv(netdev);
+ int new_cnt;
- if (!ch->combined_count || ch->other_count ||
- ch->rx_count || ch->tx_count)
+ if (ch->rx_count != ch->tx_count) {
+ netdev_info(netdev, "The rx and tx count must be equal\n");
return -EINVAL;
+ }
- if (ch->combined_count == lif->nxqs)
- return 0;
+ if (ch->combined_count && ch->rx_count) {
+ netdev_info(netdev, "Use either combined_count or rx/tx_count, not both\n");
+ return -EINVAL;
+ }
+
+ if (ch->combined_count)
+ new_cnt = ch->combined_count;
+ else
+ new_cnt = ch->rx_count;
+
+ if (lif->nxqs != new_cnt)
+ netdev_info(netdev, "Changing queue count from %d to %d\n",
+ lif->nxqs, new_cnt);
return ionic_reset_queues(lif, ionic_set_queuecount, ch);
}
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 7e22ba4ed915..acc94b244cf3 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -59,6 +59,8 @@ enum ionic_cmd_opcode {
IONIC_CMD_QOS_CLASS_INIT = 241,
IONIC_CMD_QOS_CLASS_RESET = 242,
IONIC_CMD_QOS_CLASS_UPDATE = 243,
+ IONIC_CMD_QOS_CLEAR_STATS = 244,
+ IONIC_CMD_QOS_RESET = 245,
/* Firmware commands */
IONIC_CMD_FW_DOWNLOAD = 254,
@@ -90,8 +92,8 @@ enum ionic_status_code {
IONIC_RC_DEV_CMD = 18, /* Device cmd attempted on AdminQ */
IONIC_RC_ENOSUPP = 19, /* Operation not supported */
IONIC_RC_ERROR = 29, /* Generic error */
-
IONIC_RC_ERDMA = 30, /* Generic RDMA error */
+ IONIC_RC_EVFID = 31, /* VF ID does not exist */
};
enum ionic_notifyq_opcode {
@@ -103,7 +105,7 @@ enum ionic_notifyq_opcode {
};
/**
- * struct cmd - General admin command format
+ * struct ionic_admin_cmd - General admin command format
* @opcode: Opcode for the command
* @lif_index: LIF index
* @cmd_data: Opcode-specific command bytes
@@ -167,7 +169,7 @@ struct ionic_dev_init_cmd {
};
/**
- * struct init_comp - Device init command completion
+ * struct ionic_dev_init_comp - Device init command completion
* @status: Status of the command (enum ionic_status_code)
*/
struct ionic_dev_init_comp {
@@ -185,7 +187,7 @@ struct ionic_dev_reset_cmd {
};
/**
- * struct reset_comp - Reset command completion
+ * struct ionic_dev_reset_comp - Reset command completion
* @status: Status of the command (enum ionic_status_code)
*/
struct ionic_dev_reset_comp {
@@ -357,12 +359,12 @@ struct ionic_lif_logical_qtype {
* enum ionic_lif_state - LIF state
* @IONIC_LIF_DISABLE: LIF disabled
* @IONIC_LIF_ENABLE: LIF enabled
- * @IONIC_LIF_HANG_RESET: LIF hung, being reset
+ * @IONIC_LIF_QUIESCE: LIF Quiesced
*/
enum ionic_lif_state {
- IONIC_LIF_DISABLE = 0,
+ IONIC_LIF_QUIESCE = 0,
IONIC_LIF_ENABLE = 1,
- IONIC_LIF_HANG_RESET = 2,
+ IONIC_LIF_DISABLE = 2,
};
/**
@@ -371,6 +373,7 @@ enum ionic_lif_state {
* @name: LIF name
* @mtu: MTU
* @mac: Station MAC address
+ * @vlan: Default Vlan ID
* @features: Features (enum ionic_eth_hw_features)
* @queue_count: Queue counts per queue-type
*/
@@ -381,7 +384,7 @@ union ionic_lif_config {
char name[IONIC_IFNAMSIZ];
__le32 mtu;
u8 mac[6];
- u8 rsvd2[2];
+ __le16 vlan;
__le64 features;
__le32 queue_count[IONIC_QTYPE_MAX];
} __packed;
@@ -489,13 +492,13 @@ struct ionic_lif_init_comp {
u8 rsvd2[12];
};
- /**
- * struct ionic_q_identify_cmd - queue identify command
- * @opcode: opcode
- * @lif_type: LIF type (enum ionic_lif_type)
- * @type: Logical queue type (enum ionic_logical_qtype)
- * @ver: Highest queue type version that the driver supports
- */
+/**
+ * struct ionic_q_identify_cmd - queue identify command
+ * @opcode: opcode
+ * @lif_type: LIF type (enum ionic_lif_type)
+ * @type: Logical queue type (enum ionic_logical_qtype)
+ * @ver: Highest queue type version that the driver supports
+ */
struct ionic_q_identify_cmd {
u8 opcode;
u8 rsvd;
@@ -983,6 +986,14 @@ enum ionic_pkt_type {
IONIC_PKT_TYPE_IPV6 = 0x008,
IONIC_PKT_TYPE_IPV6_TCP = 0x018,
IONIC_PKT_TYPE_IPV6_UDP = 0x028,
+ /* below types are only used if encap offloads are enabled on lif */
+ IONIC_PKT_TYPE_ENCAP_NON_IP = 0x40,
+ IONIC_PKT_TYPE_ENCAP_IPV4 = 0x41,
+ IONIC_PKT_TYPE_ENCAP_IPV4_TCP = 0x43,
+ IONIC_PKT_TYPE_ENCAP_IPV4_UDP = 0x45,
+ IONIC_PKT_TYPE_ENCAP_IPV6 = 0x48,
+ IONIC_PKT_TYPE_ENCAP_IPV6_TCP = 0x58,
+ IONIC_PKT_TYPE_ENCAP_IPV6_UDP = 0x68,
};
enum ionic_eth_hw_features {
@@ -1003,6 +1014,9 @@ enum ionic_eth_hw_features {
IONIC_ETH_HW_TSO_IPXIP6 = BIT(14),
IONIC_ETH_HW_TSO_UDP = BIT(15),
IONIC_ETH_HW_TSO_UDP_CSUM = BIT(16),
+ IONIC_ETH_HW_RX_CSUM_GENEVE = BIT(17),
+ IONIC_ETH_HW_TX_CSUM_GENEVE = BIT(18),
+ IONIC_ETH_HW_TSO_GENEVE = BIT(19)
};
/**
@@ -1011,7 +1025,7 @@ enum ionic_eth_hw_features {
* @type: Queue type
* @lif_index: LIF index
* @index: Queue index
- * @oper: Operation (enum q_control_oper)
+ * @oper: Operation (enum ionic_q_control_oper)
*/
struct ionic_q_control_cmd {
u8 opcode;
@@ -1172,7 +1186,7 @@ enum ionic_port_loopback_mode {
* struct ionic_xcvr_status - Transceiver Status information
* @state: Transceiver status (enum ionic_xcvr_state)
* @phy: Physical connection type (enum ionic_phy_type)
- * @pid: Transceiver link mode (enum pid)
+ * @pid: Transceiver link mode (enum ionic_xcvr_pid)
* @sprom: Transceiver sprom contents
*/
struct ionic_xcvr_status {
@@ -1186,7 +1200,7 @@ struct ionic_xcvr_status {
* union ionic_port_config - Port configuration
* @speed: port speed (in Mbps)
* @mtu: mtu
- * @state: port admin state (enum port_admin_state)
+ * @state: port admin state (enum ionic_port_admin_state)
* @an_enable: autoneg enable
* @fec_type: fec type (enum ionic_port_fec_type)
* @pause_type: pause type (enum ionic_port_pause_type)
@@ -1874,12 +1888,14 @@ struct ionic_qos_identify_comp {
};
#define IONIC_QOS_TC_MAX 8
+#define IONIC_QOS_ALL_TC 0xFF
/* Capri max supported, should be renamed. */
#define IONIC_QOS_CLASS_MAX 7
#define IONIC_QOS_PCP_MAX 8
#define IONIC_QOS_CLASS_NAME_SZ 32
#define IONIC_QOS_DSCP_MAX 64
#define IONIC_QOS_ALL_PCP 0xFF
+#define IONIC_DSCP_BLOCK_SIZE 8
/**
* enum ionic_qos_class
@@ -1923,6 +1939,7 @@ enum ionic_qos_sched_type {
* IONIC_QOS_CONFIG_F_NO_DROP drop/nodrop
* IONIC_QOS_CONFIG_F_RW_DOT1Q_PCP enable dot1q pcp rewrite
* IONIC_QOS_CONFIG_F_RW_IP_DSCP enable ip dscp rewrite
+ * IONIC_QOS_CONFIG_F_NON_DISRUPTIVE Non-disruptive TC update
* @sched_type: QoS class scheduling type (enum ionic_qos_sched_type)
* @class_type: QoS class type (enum ionic_qos_class_type)
* @pause_type: QoS pause type (enum ionic_qos_pause_type)
@@ -1944,6 +1961,8 @@ union ionic_qos_config {
/* Used to rewrite PCP or DSCP value. */
#define IONIC_QOS_CONFIG_F_RW_DOT1Q_PCP BIT(2)
#define IONIC_QOS_CONFIG_F_RW_IP_DSCP BIT(3)
+/* Non-disruptive TC update */
+#define IONIC_QOS_CONFIG_F_NON_DISRUPTIVE BIT(4)
u8 flags;
u8 sched_type;
u8 class_type;
@@ -2019,6 +2038,16 @@ struct ionic_qos_reset_cmd {
u8 rsvd[62];
};
+/**
+ * struct ionic_qos_clear_port_stats_cmd - Qos config reset command
+ * @opcode: Opcode
+ */
+struct ionic_qos_clear_stats_cmd {
+ u8 opcode;
+ u8 group_bitmap;
+ u8 rsvd[62];
+};
+
typedef struct ionic_admin_comp ionic_qos_reset_comp;
/**
@@ -2164,7 +2193,7 @@ struct ionic_notifyq_event {
* struct ionic_link_change_event - Link change event notification
* @eid: event number
* @ecode: event code = IONIC_EVENT_LINK_CHANGE
- * @link_status: link up or down, with error bits (enum port_status)
+ * @link_status: link up/down, with error bits (enum ionic_port_status)
* @link_speed: speed of the network link
*
* Sent when the network link state changes between UP and DOWN
@@ -2377,6 +2406,16 @@ enum ionic_pb_buffer_drop_stats {
IONIC_BUFFER_DROP_MAX,
};
+enum ionic_oflow_drop_stats {
+ IONIC_OFLOW_OCCUPANCY_DROP,
+ IONIC_OFLOW_EMERGENCY_STOP_DROP,
+ IONIC_OFLOW_WRITE_BUFFER_ACK_FILL_UP_DROP,
+ IONIC_OFLOW_WRITE_BUFFER_ACK_FULL_DROP,
+ IONIC_OFLOW_WRITE_BUFFER_FULL_DROP,
+ IONIC_OFLOW_CONTROL_FIFO_FULL_DROP,
+ IONIC_OFLOW_DROP_MAX,
+};
+
/**
* struct port_pb_stats - packet buffers system stats
* uses ionic_pb_buffer_drop_stats for drop_counts[]
@@ -2390,12 +2429,20 @@ struct ionic_port_pb_stats {
__le64 input_queue_buffer_occupancy[IONIC_QOS_TC_MAX];
__le64 input_queue_port_monitor[IONIC_QOS_TC_MAX];
__le64 output_queue_port_monitor[IONIC_QOS_TC_MAX];
+ __le64 oflow_drop_counts[IONIC_OFLOW_DROP_MAX];
+ __le64 input_queue_good_pkts_in[IONIC_QOS_TC_MAX];
+ __le64 input_queue_good_pkts_out[IONIC_QOS_TC_MAX];
+ __le64 input_queue_err_pkts_in[IONIC_QOS_TC_MAX];
+ __le64 input_queue_fifo_depth[IONIC_QOS_TC_MAX];
+ __le64 input_queue_max_fifo_depth[IONIC_QOS_TC_MAX];
+ __le64 input_queue_peak_occupancy[IONIC_QOS_TC_MAX];
+ __le64 output_queue_buffer_occupancy[IONIC_QOS_TC_MAX];
};
/**
* struct ionic_port_identity - port identity structure
* @version: identity structure version
- * @type: type of port (enum port_type)
+ * @type: type of port (enum ionic_port_type)
* @num_lanes: number of lanes for the port
* @autoneg: autoneg supported
* @min_frame_size: minimum frame size supported
@@ -2637,6 +2684,7 @@ union ionic_dev_cmd {
struct ionic_qos_identify_cmd qos_identify;
struct ionic_qos_init_cmd qos_init;
struct ionic_qos_reset_cmd qos_reset;
+ struct ionic_qos_clear_stats_cmd qos_clear_stats;
struct ionic_q_identify_cmd q_identify;
struct ionic_q_init_cmd q_init;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index e55d41546cff..1944bf5264db 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -5,6 +5,7 @@
#include <linux/dynamic_debug.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
@@ -615,7 +616,6 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
.index = cpu_to_le32(q->index),
.flags = cpu_to_le16(IONIC_QINIT_F_IRQ |
IONIC_QINIT_F_SG),
- .intr_index = cpu_to_le16(lif->rxqcqs[q->index].qcq->intr.index),
.pid = cpu_to_le16(q->pid),
.ring_size = ilog2(q->num_descs),
.ring_base = cpu_to_le64(q->base_pa),
@@ -623,14 +623,22 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
.sg_ring_base = cpu_to_le64(q->sg_base_pa),
},
};
+ unsigned int intr_index;
int err;
+ if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
+ intr_index = qcq->intr.index;
+ else
+ intr_index = lif->rxqcqs[q->index].qcq->intr.index;
+ ctx.cmd.q_init.intr_index = cpu_to_le16(intr_index);
+
dev_dbg(dev, "txq_init.pid %d\n", ctx.cmd.q_init.pid);
dev_dbg(dev, "txq_init.index %d\n", ctx.cmd.q_init.index);
dev_dbg(dev, "txq_init.ring_base 0x%llx\n", ctx.cmd.q_init.ring_base);
dev_dbg(dev, "txq_init.ring_size %d\n", ctx.cmd.q_init.ring_size);
dev_dbg(dev, "txq_init.flags 0x%x\n", ctx.cmd.q_init.flags);
dev_dbg(dev, "txq_init.ver %d\n", ctx.cmd.q_init.ver);
+ dev_dbg(dev, "txq_init.intr_index %d\n", ctx.cmd.q_init.intr_index);
q->tail = q->info;
q->head = q->tail;
@@ -647,6 +655,10 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
dev_dbg(dev, "txq->hw_type %d\n", q->hw_type);
dev_dbg(dev, "txq->hw_index %d\n", q->hw_index);
+ if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
+ netif_napi_add(lif->netdev, &qcq->napi, ionic_tx_napi,
+ NAPI_POLL_WEIGHT);
+
qcq->flags |= IONIC_QCQ_F_INITED;
return 0;
@@ -683,6 +695,7 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
dev_dbg(dev, "rxq_init.ring_size %d\n", ctx.cmd.q_init.ring_size);
dev_dbg(dev, "rxq_init.flags 0x%x\n", ctx.cmd.q_init.flags);
dev_dbg(dev, "rxq_init.ver %d\n", ctx.cmd.q_init.ver);
+ dev_dbg(dev, "rxq_init.intr_index %d\n", ctx.cmd.q_init.intr_index);
q->tail = q->info;
q->head = q->tail;
@@ -699,8 +712,12 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
dev_dbg(dev, "rxq->hw_type %d\n", q->hw_type);
dev_dbg(dev, "rxq->hw_index %d\n", q->hw_index);
- netif_napi_add(lif->netdev, &qcq->napi, ionic_rx_napi,
- NAPI_POLL_WEIGHT);
+ if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
+ netif_napi_add(lif->netdev, &qcq->napi, ionic_rx_napi,
+ NAPI_POLL_WEIGHT);
+ else
+ netif_napi_add(lif->netdev, &qcq->napi, ionic_txrx_napi,
+ NAPI_POLL_WEIGHT);
qcq->flags |= IONIC_QCQ_F_INITED;
@@ -723,7 +740,7 @@ static bool ionic_notifyq_service(struct ionic_cq *cq,
eid = le64_to_cpu(comp->event.eid);
/* Have we run out of new completions to process? */
- if (eid <= lif->last_eid)
+ if ((s64)(eid - lif->last_eid) <= 0)
return false;
lif->last_eid = eid;
@@ -1536,6 +1553,8 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
sg_desc_sz = sizeof(struct ionic_txq_sg_desc);
flags = IONIC_QCQ_F_TX_STATS | IONIC_QCQ_F_SG;
+ if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
+ flags |= IONIC_QCQ_F_INTR;
for (i = 0; i < lif->nxqs; i++) {
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
lif->ntxq_descs,
@@ -1546,6 +1565,11 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
if (err)
goto err_out;
+ if (flags & IONIC_QCQ_F_INTR)
+ ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
+ lif->txqcqs[i].qcq->intr.index,
+ lif->tx_coalesce_hw);
+
lif->txqcqs[i].qcq->stats = lif->txqcqs[i].stats;
ionic_debugfs_add_qcq(lif, lif->txqcqs[i].qcq);
}
@@ -1561,13 +1585,15 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
if (err)
goto err_out;
- lif->rxqcqs[i].qcq->stats = lif->rxqcqs[i].stats;
-
ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
lif->rxqcqs[i].qcq->intr.index,
lif->rx_coalesce_hw);
- ionic_link_qcq_interrupts(lif->rxqcqs[i].qcq,
- lif->txqcqs[i].qcq);
+
+ if (!test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
+ ionic_link_qcq_interrupts(lif->rxqcqs[i].qcq,
+ lif->txqcqs[i].qcq);
+
+ lif->rxqcqs[i].qcq->stats = lif->rxqcqs[i].stats;
ionic_debugfs_add_qcq(lif, lif->rxqcqs[i].qcq);
}
@@ -2021,16 +2047,22 @@ reset_out:
static struct ionic_lif *ionic_lif_alloc(struct ionic *ionic, unsigned int index)
{
struct device *dev = ionic->dev;
+ union ionic_lif_identity *lid;
struct net_device *netdev;
struct ionic_lif *lif;
int tbl_sz;
int err;
+ lid = kzalloc(sizeof(*lid), GFP_KERNEL);
+ if (!lid)
+ return ERR_PTR(-ENOMEM);
+
netdev = alloc_etherdev_mqs(sizeof(*lif),
ionic->ntxqs_per_lif, ionic->ntxqs_per_lif);
if (!netdev) {
dev_err(dev, "Cannot allocate netdev, aborting\n");
- return ERR_PTR(-ENOMEM);
+ err = -ENOMEM;
+ goto err_out_free_lid;
}
SET_NETDEV_DEV(netdev, dev);
@@ -2044,8 +2076,12 @@ static struct ionic_lif *ionic_lif_alloc(struct ionic *ionic, unsigned int index
netdev->watchdog_timeo = 2 * HZ;
netif_carrier_off(netdev);
- netdev->min_mtu = IONIC_MIN_MTU;
- netdev->max_mtu = IONIC_MAX_MTU;
+ lif->identity = lid;
+ lif->lif_type = IONIC_LIF_TYPE_CLASSIC;
+ ionic_lif_identify(ionic, lif->lif_type, lif->identity);
+ lif->netdev->min_mtu = le32_to_cpu(lif->identity->eth.min_frame_size);
+ lif->netdev->max_mtu =
+ le32_to_cpu(lif->identity->eth.max_frame_size) - ETH_HLEN - VLAN_HLEN;
lif->neqs = ionic->neqs_per_lif;
lif->nxqs = ionic->ntxqs_per_lif;
@@ -2054,11 +2090,14 @@ static struct ionic_lif *ionic_lif_alloc(struct ionic *ionic, unsigned int index
lif->index = index;
lif->ntxq_descs = IONIC_DEF_TXRX_DESC;
lif->nrxq_descs = IONIC_DEF_TXRX_DESC;
+ lif->tx_budget = IONIC_TX_BUDGET_DEFAULT;
/* Convert the default coalesce value to actual hw resolution */
lif->rx_coalesce_usecs = IONIC_ITR_COAL_USEC_DEFAULT;
lif->rx_coalesce_hw = ionic_coal_usec_to_hw(lif->ionic,
lif->rx_coalesce_usecs);
+ lif->tx_coalesce_usecs = lif->rx_coalesce_usecs;
+ lif->tx_coalesce_hw = lif->rx_coalesce_hw;
snprintf(lif->name, sizeof(lif->name), "lif%u", index);
@@ -2112,6 +2151,8 @@ err_out_free_lif_info:
err_out_free_netdev:
free_netdev(lif->netdev);
lif = NULL;
+err_out_free_lid:
+ kfree(lid);
return ERR_PTR(err);
}
@@ -2131,7 +2172,6 @@ int ionic_lifs_alloc(struct ionic *ionic)
return -ENOMEM;
}
- lif->lif_type = IONIC_LIF_TYPE_CLASSIC;
ionic_lif_queue_identify(lif);
return 0;
@@ -2244,6 +2284,7 @@ static void ionic_lif_free(struct ionic_lif *lif)
ionic_lif_reset(lif);
/* free lif info */
+ kfree(lif->identity);
dma_free_coherent(dev, lif->info_sz, lif->info, lif->info_pa);
lif->info = NULL;
lif->info_pa = 0;
@@ -2622,6 +2663,7 @@ int ionic_lifs_register(struct ionic *ionic)
return err;
}
ionic->master_lif->registered = true;
+ ionic_lif_set_netdev_info(ionic->master_lif);
return 0;
}
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index 8dc2c5d77424..1ee3b14c8d50 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -13,6 +13,7 @@
#define IONIC_MAX_NUM_NAPI_CNTR (NAPI_POLL_WEIGHT + 1)
#define IONIC_MAX_NUM_SG_CNTR (IONIC_TX_MAX_SG_ELEMS + 1)
#define IONIC_RX_COPYBREAK_DEFAULT 256
+#define IONIC_TX_BUDGET_DEFAULT 256
struct ionic_tx_stats {
u64 dma_map_err;
@@ -136,6 +137,7 @@ enum ionic_lif_state_flags {
IONIC_LIF_F_UP,
IONIC_LIF_F_LINK_CHECK_REQUESTED,
IONIC_LIF_F_FW_RESET,
+ IONIC_LIF_F_SPLIT_INTR,
/* leave this as last */
IONIC_LIF_F_STATE_SIZE
@@ -176,6 +178,7 @@ struct ionic_lif {
unsigned int ntxq_descs;
unsigned int nrxq_descs;
u32 rx_copybreak;
+ u32 tx_budget;
unsigned int rx_mode;
u64 hw_features;
bool mc_overflow;
@@ -184,6 +187,7 @@ struct ionic_lif {
u16 lif_type;
unsigned int nucast;
+ union ionic_lif_identity *identity;
struct ionic_lif_info *info;
dma_addr_t info_pa;
u32 info_sz;
@@ -202,6 +206,8 @@ struct ionic_lif {
struct dentry *dentry;
u32 rx_coalesce_usecs; /* what the user asked for */
u32 rx_coalesce_hw; /* what the hw is using */
+ u32 tx_coalesce_usecs; /* what the user asked for */
+ u32 tx_coalesce_hw; /* what the hw is using */
struct work_struct tx_timeout_work;
};
@@ -229,19 +235,6 @@ static inline u32 ionic_coal_usec_to_hw(struct ionic *ionic, u32 usecs)
return (usecs * mult) / div;
}
-static inline u32 ionic_coal_hw_to_usec(struct ionic *ionic, u32 units)
-{
- u32 mult = le32_to_cpu(ionic->ident.dev.intr_coal_mult);
- u32 div = le32_to_cpu(ionic->ident.dev.intr_coal_div);
-
- /* Div-by-zero should never be an issue, but check anyway */
- if (!div || !mult)
- return 0;
-
- /* Convert from device units to usec */
- return (units * div) / mult;
-}
-
typedef void (*ionic_reset_cb)(struct ionic_lif *lif, void *arg);
void ionic_link_status_check_request(struct ionic_lif *lif);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 85eb8f276a37..8107d32c2767 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -15,6 +15,10 @@ static void ionic_rx_clean(struct ionic_queue *q,
struct ionic_cq_info *cq_info,
void *cb_arg);
+static bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info);
+
+static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info);
+
static inline void ionic_txq_post(struct ionic_queue *q, bool ring_dbell,
ionic_desc_cb cb_func, void *cb_arg)
{
@@ -249,29 +253,13 @@ static bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
return true;
}
-static u32 ionic_rx_walk_cq(struct ionic_cq *rxcq, u32 limit)
-{
- u32 work_done = 0;
-
- while (ionic_rx_service(rxcq, rxcq->tail)) {
- if (rxcq->tail->last)
- rxcq->done_color = !rxcq->done_color;
- rxcq->tail = rxcq->tail->next;
- DEBUG_STATS_CQE_CNT(rxcq);
-
- if (++work_done >= limit)
- break;
- }
-
- return work_done;
-}
-
void ionic_rx_flush(struct ionic_cq *cq)
{
struct ionic_dev *idev = &cq->lif->ionic->idev;
u32 work_done;
- work_done = ionic_rx_walk_cq(cq, cq->num_descs);
+ work_done = ionic_cq_service(cq, cq->num_descs,
+ ionic_rx_service, NULL, NULL);
if (work_done)
ionic_intr_credits(idev->intr_ctrl, cq->bound_intr->index,
@@ -331,9 +319,6 @@ static void ionic_rx_page_free(struct ionic_queue *q, struct page *page,
__free_page(page);
}
-#define IONIC_RX_RING_DOORBELL_STRIDE ((1 << 5) - 1)
-#define IONIC_RX_RING_HEAD_BUF_SZ 2048
-
void ionic_rx_fill(struct ionic_queue *q)
{
struct net_device *netdev = q->lif->netdev;
@@ -345,7 +330,6 @@ void ionic_rx_fill(struct ionic_queue *q)
unsigned int remain_len;
unsigned int seg_len;
unsigned int nfrags;
- bool ring_doorbell;
unsigned int i, j;
unsigned int len;
@@ -360,9 +344,7 @@ void ionic_rx_fill(struct ionic_queue *q)
page_info = &desc_info->pages[0];
if (page_info->page) { /* recycle the buffer */
- ring_doorbell = ((q->head->index + 1) &
- IONIC_RX_RING_DOORBELL_STRIDE) == 0;
- ionic_rxq_post(q, ring_doorbell, ionic_rx_clean, NULL);
+ ionic_rxq_post(q, false, ionic_rx_clean, NULL);
continue;
}
@@ -401,10 +383,11 @@ void ionic_rx_fill(struct ionic_queue *q)
page_info++;
}
- ring_doorbell = ((q->head->index + 1) &
- IONIC_RX_RING_DOORBELL_STRIDE) == 0;
- ionic_rxq_post(q, ring_doorbell, ionic_rx_clean, NULL);
+ ionic_rxq_post(q, false, ionic_rx_clean, NULL);
}
+
+ ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type,
+ q->dbval | q->head->index);
}
static void ionic_rx_fill_cb(void *arg)
@@ -436,40 +419,117 @@ void ionic_rx_empty(struct ionic_queue *q)
}
}
+int ionic_tx_napi(struct napi_struct *napi, int budget)
+{
+ struct ionic_qcq *qcq = napi_to_qcq(napi);
+ struct ionic_cq *cq = napi_to_cq(napi);
+ struct ionic_dev *idev;
+ struct ionic_lif *lif;
+ u32 work_done = 0;
+ u32 flags = 0;
+
+ lif = cq->bound_q->lif;
+ idev = &lif->ionic->idev;
+
+ work_done = ionic_cq_service(cq, budget,
+ ionic_tx_service, NULL, NULL);
+
+ if (work_done < budget && napi_complete_done(napi, work_done)) {
+ flags |= IONIC_INTR_CRED_UNMASK;
+ DEBUG_STATS_INTR_REARM(cq->bound_intr);
+ }
+
+ if (work_done || flags) {
+ flags |= IONIC_INTR_CRED_RESET_COALESCE;
+ ionic_intr_credits(idev->intr_ctrl,
+ cq->bound_intr->index,
+ work_done, flags);
+ }
+
+ DEBUG_STATS_NAPI_POLL(qcq, work_done);
+
+ return work_done;
+}
+
int ionic_rx_napi(struct napi_struct *napi, int budget)
{
struct ionic_qcq *qcq = napi_to_qcq(napi);
+ struct ionic_cq *cq = napi_to_cq(napi);
+ struct ionic_dev *idev;
+ struct ionic_lif *lif;
+ u32 work_done = 0;
+ u32 flags = 0;
+
+ lif = cq->bound_q->lif;
+ idev = &lif->ionic->idev;
+
+ work_done = ionic_cq_service(cq, budget,
+ ionic_rx_service, NULL, NULL);
+
+ if (work_done)
+ ionic_rx_fill(cq->bound_q);
+
+ if (work_done < budget && napi_complete_done(napi, work_done)) {
+ flags |= IONIC_INTR_CRED_UNMASK;
+ DEBUG_STATS_INTR_REARM(cq->bound_intr);
+ }
+
+ if (work_done || flags) {
+ flags |= IONIC_INTR_CRED_RESET_COALESCE;
+ ionic_intr_credits(idev->intr_ctrl,
+ cq->bound_intr->index,
+ work_done, flags);
+ }
+
+ DEBUG_STATS_NAPI_POLL(qcq, work_done);
+
+ return work_done;
+}
+
+int ionic_txrx_napi(struct napi_struct *napi, int budget)
+{
+ struct ionic_qcq *qcq = napi_to_qcq(napi);
struct ionic_cq *rxcq = napi_to_cq(napi);
unsigned int qi = rxcq->bound_q->index;
struct ionic_dev *idev;
struct ionic_lif *lif;
struct ionic_cq *txcq;
+ u32 rx_work_done = 0;
+ u32 tx_work_done = 0;
u32 work_done = 0;
u32 flags = 0;
+ bool unmask;
lif = rxcq->bound_q->lif;
idev = &lif->ionic->idev;
txcq = &lif->txqcqs[qi].qcq->cq;
- ionic_tx_flush(txcq);
+ tx_work_done = ionic_cq_service(txcq, lif->tx_budget,
+ ionic_tx_service, NULL, NULL);
- work_done = ionic_rx_walk_cq(rxcq, budget);
-
- if (work_done)
+ rx_work_done = ionic_cq_service(rxcq, budget,
+ ionic_rx_service, NULL, NULL);
+ if (rx_work_done)
ionic_rx_fill_cb(rxcq->bound_q);
- if (work_done < budget && napi_complete_done(napi, work_done)) {
+ unmask = (rx_work_done < budget) && (tx_work_done < lif->tx_budget);
+
+ if (unmask && napi_complete_done(napi, rx_work_done)) {
flags |= IONIC_INTR_CRED_UNMASK;
DEBUG_STATS_INTR_REARM(rxcq->bound_intr);
+ work_done = rx_work_done;
+ } else {
+ work_done = budget;
}
if (work_done || flags) {
flags |= IONIC_INTR_CRED_RESET_COALESCE;
ionic_intr_credits(idev->intr_ctrl, rxcq->bound_intr->index,
- work_done, flags);
+ tx_work_done + rx_work_done, flags);
}
- DEBUG_STATS_NAPI_POLL(qcq, work_done);
+ DEBUG_STATS_NAPI_POLL(qcq, rx_work_done);
+ DEBUG_STATS_NAPI_POLL(qcq, tx_work_done);
return work_done;
}
@@ -557,43 +617,39 @@ static void ionic_tx_clean(struct ionic_queue *q,
}
}
-void ionic_tx_flush(struct ionic_cq *cq)
+static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
{
- struct ionic_txq_comp *comp = cq->tail->cq_desc;
- struct ionic_dev *idev = &cq->lif->ionic->idev;
+ struct ionic_txq_comp *comp = cq_info->cq_desc;
struct ionic_queue *q = cq->bound_q;
struct ionic_desc_info *desc_info;
- unsigned int work_done = 0;
-
- /* walk the completed cq entries */
- while (work_done < cq->num_descs &&
- color_match(comp->color, cq->done_color)) {
-
- /* clean the related q entries, there could be
- * several q entries completed for each cq completion
- */
- do {
- desc_info = q->tail;
- q->tail = desc_info->next;
- ionic_tx_clean(q, desc_info, cq->tail,
- desc_info->cb_arg);
- desc_info->cb = NULL;
- desc_info->cb_arg = NULL;
- } while (desc_info->index != le16_to_cpu(comp->comp_index));
-
- if (cq->tail->last)
- cq->done_color = !cq->done_color;
-
- cq->tail = cq->tail->next;
- comp = cq->tail->cq_desc;
- DEBUG_STATS_CQE_CNT(cq);
-
- work_done++;
- }
+ if (!color_match(comp->color, cq->done_color))
+ return false;
+
+ /* clean the related q entries, there could be
+ * several q entries completed for each cq completion
+ */
+ do {
+ desc_info = q->tail;
+ q->tail = desc_info->next;
+ ionic_tx_clean(q, desc_info, cq->tail, desc_info->cb_arg);
+ desc_info->cb = NULL;
+ desc_info->cb_arg = NULL;
+ } while (desc_info->index != le16_to_cpu(comp->comp_index));
+
+ return true;
+}
+
+void ionic_tx_flush(struct ionic_cq *cq)
+{
+ struct ionic_dev *idev = &cq->lif->ionic->idev;
+ u32 work_done;
+
+ work_done = ionic_cq_service(cq, cq->num_descs,
+ ionic_tx_service, NULL, NULL);
if (work_done)
ionic_intr_credits(idev->intr_ctrl, cq->bound_intr->index,
- work_done, 0);
+ work_done, IONIC_INTR_CRED_RESET_COALESCE);
}
void ionic_tx_empty(struct ionic_queue *q)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.h b/drivers/net/ethernet/pensando/ionic/ionic_txrx.h
index 71973e3c35a6..a5883be0413f 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.h
@@ -11,6 +11,8 @@ void ionic_rx_fill(struct ionic_queue *q);
void ionic_rx_empty(struct ionic_queue *q);
void ionic_tx_empty(struct ionic_queue *q);
int ionic_rx_napi(struct napi_struct *napi, int budget);
+int ionic_tx_napi(struct napi_struct *napi, int budget);
+int ionic_txrx_napi(struct napi_struct *napi, int budget);
netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev);
#endif /* _IONIC_TXRX_H_ */
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 8067ea04d455..f21847739ef1 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -1695,19 +1695,13 @@ static void netxen_nic_detach_func(struct netxen_adapter *adapter)
clear_bit(__NX_RESETTING, &adapter->state);
}
-static int netxen_nic_attach_func(struct pci_dev *pdev)
+static int netxen_nic_attach_late_func(struct pci_dev *pdev)
{
struct netxen_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *netdev = adapter->netdev;
int err;
- err = pci_enable_device(pdev);
- if (err)
- return err;
-
- pci_set_power_state(pdev, PCI_D0);
pci_set_master(pdev);
- pci_restore_state(pdev);
adapter->ahw.crb_win = -1;
adapter->ahw.ocm_win = -1;
@@ -1741,6 +1735,20 @@ err_out:
return err;
}
+static int netxen_nic_attach_func(struct pci_dev *pdev)
+{
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ return netxen_nic_attach_late_func(pdev);
+}
+
static pci_ers_result_t netxen_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
@@ -1785,36 +1793,24 @@ static void netxen_nic_shutdown(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-#ifdef CONFIG_PM
-static int
-netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused
+netxen_nic_suspend(struct device *dev_d)
{
- struct netxen_adapter *adapter = pci_get_drvdata(pdev);
- int retval;
+ struct netxen_adapter *adapter = dev_get_drvdata(dev_d);
netxen_nic_detach_func(adapter);
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-
- if (netxen_nic_wol_supported(adapter)) {
- pci_enable_wake(pdev, PCI_D3cold, 1);
- pci_enable_wake(pdev, PCI_D3hot, 1);
- }
-
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ if (netxen_nic_wol_supported(adapter))
+ device_wakeup_enable(dev_d);
return 0;
}
-static int
-netxen_nic_resume(struct pci_dev *pdev)
+static int __maybe_unused
+netxen_nic_resume(struct device *dev_d)
{
- return netxen_nic_attach_func(pdev);
+ return netxen_nic_attach_late_func(to_pci_dev(dev_d));
}
-#endif
static int netxen_nic_open(struct net_device *netdev)
{
@@ -3448,15 +3444,16 @@ static const struct pci_error_handlers netxen_err_handler = {
.slot_reset = netxen_io_slot_reset,
};
+static SIMPLE_DEV_PM_OPS(netxen_nic_pm_ops,
+ netxen_nic_suspend,
+ netxen_nic_resume);
+
static struct pci_driver netxen_driver = {
.name = netxen_nic_driver_name,
.id_table = netxen_pci_tbl,
.probe = netxen_nic_probe,
.remove = netxen_nic_remove,
-#ifdef CONFIG_PM
- .suspend = netxen_nic_suspend,
- .resume = netxen_nic_resume,
-#endif
+ .driver.pm = &netxen_nic_pm_ops,
.shutdown = netxen_nic_shutdown,
.err_handler = &netxen_err_handler
};
diff --git a/drivers/net/ethernet/qlogic/qed/Makefile b/drivers/net/ethernet/qlogic/qed/Makefile
index a0acb94d65f0..f947b105cf14 100644
--- a/drivers/net/ethernet/qlogic/qed/Makefile
+++ b/drivers/net/ethernet/qlogic/qed/Makefile
@@ -1,12 +1,37 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+# Copyright (c) 2019-2020 Marvell International Ltd.
+
obj-$(CONFIG_QED) := qed.o
-qed-y := qed_cxt.o qed_dev.o qed_hw.o qed_init_fw_funcs.o qed_init_ops.o \
- qed_int.o qed_main.o qed_mcp.o qed_sp_commands.o qed_spq.o qed_l2.o \
- qed_selftest.o qed_dcbx.o qed_debug.o qed_ptp.o qed_mng_tlv.o
-qed-$(CONFIG_QED_SRIOV) += qed_sriov.o qed_vf.o
-qed-$(CONFIG_QED_LL2) += qed_ll2.o
-qed-$(CONFIG_QED_RDMA) += qed_roce.o qed_rdma.o qed_iwarp.o
-qed-$(CONFIG_QED_ISCSI) += qed_iscsi.o
+qed-y := \
+ qed_chain.o \
+ qed_cxt.o \
+ qed_dcbx.o \
+ qed_debug.o \
+ qed_dev.o \
+ qed_hw.o \
+ qed_init_fw_funcs.o \
+ qed_init_ops.o \
+ qed_int.o \
+ qed_l2.o \
+ qed_main.o \
+ qed_mcp.o \
+ qed_mng_tlv.o \
+ qed_ptp.o \
+ qed_selftest.o \
+ qed_sp_commands.o \
+ qed_spq.o
+
qed-$(CONFIG_QED_FCOE) += qed_fcoe.o
+qed-$(CONFIG_QED_ISCSI) += qed_iscsi.o
+qed-$(CONFIG_QED_LL2) += qed_ll2.o
qed-$(CONFIG_QED_OOO) += qed_ooo.o
+
+qed-$(CONFIG_QED_RDMA) += \
+ qed_iwarp.o \
+ qed_rdma.o \
+ qed_roce.o
+
+qed-$(CONFIG_QED_SRIOV) += \
+ qed_sriov.o \
+ qed_vf.o
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 6c2f9ff4a53e..b2a7b53ee760 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_H
@@ -271,20 +245,6 @@ enum QED_FEATURE {
QED_MAX_FEATURES,
};
-enum QED_PORT_MODE {
- QED_PORT_MODE_DE_2X40G,
- QED_PORT_MODE_DE_2X50G,
- QED_PORT_MODE_DE_1X100G,
- QED_PORT_MODE_DE_4X10G_F,
- QED_PORT_MODE_DE_4X10G_E,
- QED_PORT_MODE_DE_4X20G,
- QED_PORT_MODE_DE_1X40G,
- QED_PORT_MODE_DE_2X25G,
- QED_PORT_MODE_DE_1X25G,
- QED_PORT_MODE_DE_4X25G,
- QED_PORT_MODE_DE_2X10G,
-};
-
enum qed_dev_cap {
QED_DEV_CAP_ETH,
QED_DEV_CAP_FCOE,
@@ -306,48 +266,49 @@ enum qed_db_rec_exec {
struct qed_hw_info {
/* PCI personality */
- enum qed_pci_personality personality;
-#define QED_IS_RDMA_PERSONALITY(dev) \
- ((dev)->hw_info.personality == QED_PCI_ETH_ROCE || \
- (dev)->hw_info.personality == QED_PCI_ETH_IWARP || \
+ enum qed_pci_personality personality;
+#define QED_IS_RDMA_PERSONALITY(dev) \
+ ((dev)->hw_info.personality == QED_PCI_ETH_ROCE || \
+ (dev)->hw_info.personality == QED_PCI_ETH_IWARP || \
(dev)->hw_info.personality == QED_PCI_ETH_RDMA)
-#define QED_IS_ROCE_PERSONALITY(dev) \
- ((dev)->hw_info.personality == QED_PCI_ETH_ROCE || \
+#define QED_IS_ROCE_PERSONALITY(dev) \
+ ((dev)->hw_info.personality == QED_PCI_ETH_ROCE || \
(dev)->hw_info.personality == QED_PCI_ETH_RDMA)
-#define QED_IS_IWARP_PERSONALITY(dev) \
- ((dev)->hw_info.personality == QED_PCI_ETH_IWARP || \
+#define QED_IS_IWARP_PERSONALITY(dev) \
+ ((dev)->hw_info.personality == QED_PCI_ETH_IWARP || \
(dev)->hw_info.personality == QED_PCI_ETH_RDMA)
-#define QED_IS_L2_PERSONALITY(dev) \
- ((dev)->hw_info.personality == QED_PCI_ETH || \
+#define QED_IS_L2_PERSONALITY(dev) \
+ ((dev)->hw_info.personality == QED_PCI_ETH || \
QED_IS_RDMA_PERSONALITY(dev))
-#define QED_IS_FCOE_PERSONALITY(dev) \
+#define QED_IS_FCOE_PERSONALITY(dev) \
((dev)->hw_info.personality == QED_PCI_FCOE)
-#define QED_IS_ISCSI_PERSONALITY(dev) \
+#define QED_IS_ISCSI_PERSONALITY(dev) \
((dev)->hw_info.personality == QED_PCI_ISCSI)
/* Resource Allocation scheme results */
u32 resc_start[QED_MAX_RESC];
u32 resc_num[QED_MAX_RESC];
- u32 feat_num[QED_MAX_FEATURES];
+#define RESC_START(_p_hwfn, resc) ((_p_hwfn)->hw_info.resc_start[resc])
+#define RESC_NUM(_p_hwfn, resc) ((_p_hwfn)->hw_info.resc_num[resc])
+#define RESC_END(_p_hwfn, resc) (RESC_START(_p_hwfn, resc) + \
+ RESC_NUM(_p_hwfn, resc))
-#define RESC_START(_p_hwfn, resc) ((_p_hwfn)->hw_info.resc_start[resc])
-#define RESC_NUM(_p_hwfn, resc) ((_p_hwfn)->hw_info.resc_num[resc])
-#define RESC_END(_p_hwfn, resc) (RESC_START(_p_hwfn, resc) + \
- RESC_NUM(_p_hwfn, resc))
-#define FEAT_NUM(_p_hwfn, resc) ((_p_hwfn)->hw_info.feat_num[resc])
+ u32 feat_num[QED_MAX_FEATURES];
+#define FEAT_NUM(_p_hwfn, resc) ((_p_hwfn)->hw_info.feat_num[resc])
/* Amount of traffic classes HW supports */
- u8 num_hw_tc;
+ u8 num_hw_tc;
/* Amount of TCs which should be active according to DCBx or upper
* layer driver configuration.
*/
- u8 num_active_tc;
+ u8 num_active_tc;
+
u8 offload_tc;
bool offload_tc_set;
bool multi_tc_roce_en;
-#define IS_QED_MULTI_TC_ROCE(p_hwfn) (((p_hwfn)->hw_info.multi_tc_roce_en))
+#define IS_QED_MULTI_TC_ROCE(p_hwfn) ((p_hwfn)->hw_info.multi_tc_roce_en)
u32 concrete_fid;
u16 opaque_fid;
@@ -362,12 +323,11 @@ struct qed_hw_info {
struct qed_igu_info *p_igu_info;
- u32 port_mode;
u32 hw_mode;
- unsigned long device_capabilities;
+ unsigned long device_capabilities;
u16 mtu;
- enum qed_wol_support b_wol_support;
+ enum qed_wol_support b_wol_support;
};
/* maximun size of read/write commands (HW limit) */
@@ -741,41 +701,42 @@ struct qed_dbg_feature {
};
struct qed_dev {
- u32 dp_module;
- u8 dp_level;
- char name[NAME_SIZE];
-
- enum qed_dev_type type;
-/* Translate type/revision combo into the proper conditions */
-#define QED_IS_BB(dev) ((dev)->type == QED_DEV_TYPE_BB)
-#define QED_IS_BB_B0(dev) (QED_IS_BB(dev) && \
- CHIP_REV_IS_B0(dev))
-#define QED_IS_AH(dev) ((dev)->type == QED_DEV_TYPE_AH)
-#define QED_IS_K2(dev) QED_IS_AH(dev)
-
- u16 vendor_id;
- u16 device_id;
-#define QED_DEV_ID_MASK 0xff00
-#define QED_DEV_ID_MASK_BB 0x1600
-#define QED_DEV_ID_MASK_AH 0x8000
-#define QED_IS_E4(dev) (QED_IS_BB(dev) || QED_IS_AH(dev))
-
- u16 chip_num;
-#define CHIP_NUM_MASK 0xffff
-#define CHIP_NUM_SHIFT 16
-
- u16 chip_rev;
-#define CHIP_REV_MASK 0xf
-#define CHIP_REV_SHIFT 12
-#define CHIP_REV_IS_B0(_cdev) ((_cdev)->chip_rev == 1)
+ u32 dp_module;
+ u8 dp_level;
+ char name[NAME_SIZE];
+
+ enum qed_dev_type type;
+ /* Translate type/revision combo into the proper conditions */
+#define QED_IS_BB(dev) ((dev)->type == QED_DEV_TYPE_BB)
+#define QED_IS_BB_B0(dev) (QED_IS_BB(dev) && CHIP_REV_IS_B0(dev))
+#define QED_IS_AH(dev) ((dev)->type == QED_DEV_TYPE_AH)
+#define QED_IS_K2(dev) QED_IS_AH(dev)
+#define QED_IS_E4(dev) (QED_IS_BB(dev) || QED_IS_AH(dev))
+#define QED_IS_E5(dev) ((dev)->type == QED_DEV_TYPE_E5)
+
+ u16 vendor_id;
+
+ u16 device_id;
+#define QED_DEV_ID_MASK 0xff00
+#define QED_DEV_ID_MASK_BB 0x1600
+#define QED_DEV_ID_MASK_AH 0x8000
+
+ u16 chip_num;
+#define CHIP_NUM_MASK 0xffff
+#define CHIP_NUM_SHIFT 16
+
+ u16 chip_rev;
+#define CHIP_REV_MASK 0xf
+#define CHIP_REV_SHIFT 12
+#define CHIP_REV_IS_B0(_cdev) ((_cdev)->chip_rev == 1)
u16 chip_metal;
-#define CHIP_METAL_MASK 0xff
-#define CHIP_METAL_SHIFT 4
+#define CHIP_METAL_MASK 0xff
+#define CHIP_METAL_SHIFT 4
u16 chip_bond_id;
-#define CHIP_BOND_ID_MASK 0xf
-#define CHIP_BOND_ID_SHIFT 0
+#define CHIP_BOND_ID_MASK 0xf
+#define CHIP_BOND_ID_SHIFT 0
u8 num_engines;
u8 num_ports;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_chain.c b/drivers/net/ethernet/qlogic/qed/qed_chain.c
new file mode 100644
index 000000000000..b83d17b14e85
--- /dev/null
+++ b/drivers/net/ethernet/qlogic/qed/qed_chain.c
@@ -0,0 +1,371 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/* Copyright (c) 2020 Marvell International Ltd. */
+
+#include <linux/dma-mapping.h>
+#include <linux/qed/qed_chain.h>
+#include <linux/vmalloc.h>
+
+#include "qed_dev_api.h"
+
+static void qed_chain_init(struct qed_chain *chain,
+ const struct qed_chain_init_params *params,
+ u32 page_cnt)
+{
+ memset(chain, 0, sizeof(*chain));
+
+ chain->elem_size = params->elem_size;
+ chain->intended_use = params->intended_use;
+ chain->mode = params->mode;
+ chain->cnt_type = params->cnt_type;
+
+ chain->elem_per_page = ELEMS_PER_PAGE(params->elem_size,
+ params->page_size);
+ chain->usable_per_page = USABLE_ELEMS_PER_PAGE(params->elem_size,
+ params->page_size,
+ params->mode);
+ chain->elem_unusable = UNUSABLE_ELEMS_PER_PAGE(params->elem_size,
+ params->mode);
+
+ chain->elem_per_page_mask = chain->elem_per_page - 1;
+ chain->next_page_mask = chain->usable_per_page &
+ chain->elem_per_page_mask;
+
+ chain->page_size = params->page_size;
+ chain->page_cnt = page_cnt;
+ chain->capacity = chain->usable_per_page * page_cnt;
+ chain->size = chain->elem_per_page * page_cnt;
+
+ if (params->ext_pbl_virt) {
+ chain->pbl_sp.table_virt = params->ext_pbl_virt;
+ chain->pbl_sp.table_phys = params->ext_pbl_phys;
+
+ chain->b_external_pbl = true;
+ }
+}
+
+static void qed_chain_init_next_ptr_elem(const struct qed_chain *chain,
+ void *virt_curr, void *virt_next,
+ dma_addr_t phys_next)
+{
+ struct qed_chain_next *next;
+ u32 size;
+
+ size = chain->elem_size * chain->usable_per_page;
+ next = virt_curr + size;
+
+ DMA_REGPAIR_LE(next->next_phys, phys_next);
+ next->next_virt = virt_next;
+}
+
+static void qed_chain_init_mem(struct qed_chain *chain, void *virt_addr,
+ dma_addr_t phys_addr)
+{
+ chain->p_virt_addr = virt_addr;
+ chain->p_phys_addr = phys_addr;
+}
+
+static void qed_chain_free_next_ptr(struct qed_dev *cdev,
+ struct qed_chain *chain)
+{
+ struct device *dev = &cdev->pdev->dev;
+ struct qed_chain_next *next;
+ dma_addr_t phys, phys_next;
+ void *virt, *virt_next;
+ u32 size, i;
+
+ size = chain->elem_size * chain->usable_per_page;
+ virt = chain->p_virt_addr;
+ phys = chain->p_phys_addr;
+
+ for (i = 0; i < chain->page_cnt; i++) {
+ if (!virt)
+ break;
+
+ next = virt + size;
+ virt_next = next->next_virt;
+ phys_next = HILO_DMA_REGPAIR(next->next_phys);
+
+ dma_free_coherent(dev, chain->page_size, virt, phys);
+
+ virt = virt_next;
+ phys = phys_next;
+ }
+}
+
+static void qed_chain_free_single(struct qed_dev *cdev,
+ struct qed_chain *chain)
+{
+ if (!chain->p_virt_addr)
+ return;
+
+ dma_free_coherent(&cdev->pdev->dev, chain->page_size,
+ chain->p_virt_addr, chain->p_phys_addr);
+}
+
+static void qed_chain_free_pbl(struct qed_dev *cdev, struct qed_chain *chain)
+{
+ struct device *dev = &cdev->pdev->dev;
+ struct addr_tbl_entry *entry;
+ u32 i;
+
+ if (!chain->pbl.pp_addr_tbl)
+ return;
+
+ for (i = 0; i < chain->page_cnt; i++) {
+ entry = chain->pbl.pp_addr_tbl + i;
+ if (!entry->virt_addr)
+ break;
+
+ dma_free_coherent(dev, chain->page_size, entry->virt_addr,
+ entry->dma_map);
+ }
+
+ if (!chain->b_external_pbl)
+ dma_free_coherent(dev, chain->pbl_sp.table_size,
+ chain->pbl_sp.table_virt,
+ chain->pbl_sp.table_phys);
+
+ vfree(chain->pbl.pp_addr_tbl);
+ chain->pbl.pp_addr_tbl = NULL;
+}
+
+/**
+ * qed_chain_free() - Free chain DMA memory.
+ *
+ * @cdev: Main device structure.
+ * @chain: Chain to free.
+ */
+void qed_chain_free(struct qed_dev *cdev, struct qed_chain *chain)
+{
+ switch (chain->mode) {
+ case QED_CHAIN_MODE_NEXT_PTR:
+ qed_chain_free_next_ptr(cdev, chain);
+ break;
+ case QED_CHAIN_MODE_SINGLE:
+ qed_chain_free_single(cdev, chain);
+ break;
+ case QED_CHAIN_MODE_PBL:
+ qed_chain_free_pbl(cdev, chain);
+ break;
+ default:
+ return;
+ }
+
+ qed_chain_init_mem(chain, NULL, 0);
+}
+
+static int
+qed_chain_alloc_sanity_check(struct qed_dev *cdev,
+ const struct qed_chain_init_params *params,
+ u32 page_cnt)
+{
+ u64 chain_size;
+
+ chain_size = ELEMS_PER_PAGE(params->elem_size, params->page_size);
+ chain_size *= page_cnt;
+
+ if (!chain_size)
+ return -EINVAL;
+
+ /* The actual chain size can be larger than the maximal possible value
+ * after rounding up the requested elements number to pages, and after
+ * taking into account the unusuable elements (next-ptr elements).
+ * The size of a "u16" chain can be (U16_MAX + 1) since the chain
+ * size/capacity fields are of u32 type.
+ */
+ switch (params->cnt_type) {
+ case QED_CHAIN_CNT_TYPE_U16:
+ if (chain_size > U16_MAX + 1)
+ break;
+
+ return 0;
+ case QED_CHAIN_CNT_TYPE_U32:
+ if (chain_size > U32_MAX)
+ break;
+
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ DP_NOTICE(cdev,
+ "The actual chain size (0x%llx) is larger than the maximal possible value\n",
+ chain_size);
+
+ return -EINVAL;
+}
+
+static int qed_chain_alloc_next_ptr(struct qed_dev *cdev,
+ struct qed_chain *chain)
+{
+ struct device *dev = &cdev->pdev->dev;
+ void *virt, *virt_prev = NULL;
+ dma_addr_t phys;
+ u32 i;
+
+ for (i = 0; i < chain->page_cnt; i++) {
+ virt = dma_alloc_coherent(dev, chain->page_size, &phys,
+ GFP_KERNEL);
+ if (!virt)
+ return -ENOMEM;
+
+ if (i == 0) {
+ qed_chain_init_mem(chain, virt, phys);
+ qed_chain_reset(chain);
+ } else {
+ qed_chain_init_next_ptr_elem(chain, virt_prev, virt,
+ phys);
+ }
+
+ virt_prev = virt;
+ }
+
+ /* Last page's next element should point to the beginning of the
+ * chain.
+ */
+ qed_chain_init_next_ptr_elem(chain, virt_prev, chain->p_virt_addr,
+ chain->p_phys_addr);
+
+ return 0;
+}
+
+static int qed_chain_alloc_single(struct qed_dev *cdev,
+ struct qed_chain *chain)
+{
+ dma_addr_t phys;
+ void *virt;
+
+ virt = dma_alloc_coherent(&cdev->pdev->dev, chain->page_size,
+ &phys, GFP_KERNEL);
+ if (!virt)
+ return -ENOMEM;
+
+ qed_chain_init_mem(chain, virt, phys);
+ qed_chain_reset(chain);
+
+ return 0;
+}
+
+static int qed_chain_alloc_pbl(struct qed_dev *cdev, struct qed_chain *chain)
+{
+ struct device *dev = &cdev->pdev->dev;
+ struct addr_tbl_entry *addr_tbl;
+ dma_addr_t phys, pbl_phys;
+ __le64 *pbl_virt;
+ u32 page_cnt, i;
+ size_t size;
+ void *virt;
+
+ page_cnt = chain->page_cnt;
+
+ size = array_size(page_cnt, sizeof(*addr_tbl));
+ if (unlikely(size == SIZE_MAX))
+ return -EOVERFLOW;
+
+ addr_tbl = vzalloc(size);
+ if (!addr_tbl)
+ return -ENOMEM;
+
+ chain->pbl.pp_addr_tbl = addr_tbl;
+
+ if (chain->b_external_pbl) {
+ pbl_virt = chain->pbl_sp.table_virt;
+ goto alloc_pages;
+ }
+
+ size = array_size(page_cnt, sizeof(*pbl_virt));
+ if (unlikely(size == SIZE_MAX))
+ return -EOVERFLOW;
+
+ pbl_virt = dma_alloc_coherent(dev, size, &pbl_phys, GFP_KERNEL);
+ if (!pbl_virt)
+ return -ENOMEM;
+
+ chain->pbl_sp.table_virt = pbl_virt;
+ chain->pbl_sp.table_phys = pbl_phys;
+ chain->pbl_sp.table_size = size;
+
+alloc_pages:
+ for (i = 0; i < page_cnt; i++) {
+ virt = dma_alloc_coherent(dev, chain->page_size, &phys,
+ GFP_KERNEL);
+ if (!virt)
+ return -ENOMEM;
+
+ if (i == 0) {
+ qed_chain_init_mem(chain, virt, phys);
+ qed_chain_reset(chain);
+ }
+
+ /* Fill the PBL table with the physical address of the page */
+ pbl_virt[i] = cpu_to_le64(phys);
+
+ /* Keep the virtual address of the page */
+ addr_tbl[i].virt_addr = virt;
+ addr_tbl[i].dma_map = phys;
+ }
+
+ return 0;
+}
+
+/**
+ * qed_chain_alloc() - Allocate and initialize a chain.
+ *
+ * @cdev: Main device structure.
+ * @chain: Chain to be processed.
+ * @params: Chain initialization parameters.
+ *
+ * Return: 0 on success, negative errno otherwise.
+ */
+int qed_chain_alloc(struct qed_dev *cdev, struct qed_chain *chain,
+ struct qed_chain_init_params *params)
+{
+ u32 page_cnt;
+ int rc;
+
+ if (!params->page_size)
+ params->page_size = QED_CHAIN_PAGE_SIZE;
+
+ if (params->mode == QED_CHAIN_MODE_SINGLE)
+ page_cnt = 1;
+ else
+ page_cnt = QED_CHAIN_PAGE_CNT(params->num_elems,
+ params->elem_size,
+ params->page_size,
+ params->mode);
+
+ rc = qed_chain_alloc_sanity_check(cdev, params, page_cnt);
+ if (rc) {
+ DP_NOTICE(cdev,
+ "Cannot allocate a chain with the given arguments:\n");
+ DP_NOTICE(cdev,
+ "[use_mode %d, mode %d, cnt_type %d, num_elems %d, elem_size %zu, page_size %u]\n",
+ params->intended_use, params->mode, params->cnt_type,
+ params->num_elems, params->elem_size,
+ params->page_size);
+ return rc;
+ }
+
+ qed_chain_init(chain, params, page_cnt);
+
+ switch (params->mode) {
+ case QED_CHAIN_MODE_NEXT_PTR:
+ rc = qed_chain_alloc_next_ptr(cdev, chain);
+ break;
+ case QED_CHAIN_MODE_SINGLE:
+ rc = qed_chain_alloc_single(cdev, chain);
+ break;
+ case QED_CHAIN_MODE_PBL:
+ rc = qed_chain_alloc_pbl(cdev, chain);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!rc)
+ return 0;
+
+ qed_chain_free(cdev, chain);
+
+ return rc;
+}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
index d13ec88313c3..876743a79c1f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -99,8 +73,8 @@ union type1_task_context {
};
struct src_ent {
- u8 opaque[56];
- u64 next;
+ __u8 opaque[56];
+ __be64 next;
};
#define CDUT_SEG_ALIGNMET 3 /* in 4k chunks */
@@ -2196,12 +2170,14 @@ qed_cxt_dynamic_ilt_alloc(struct qed_hwfn *p_hwfn,
enum qed_cxt_elem_type elem_type, u32 iid)
{
u32 reg_offset, shadow_line, elem_size, hw_p_size, elems_per_p, line;
+ struct tdif_task_context *tdif_context;
struct qed_ilt_client_cfg *p_cli;
struct qed_ilt_cli_blk *p_blk;
struct qed_ptt *p_ptt;
dma_addr_t p_phys;
u64 ilt_hw_entry;
void *p_virt;
+ u32 flags1;
int rc = 0;
switch (elem_type) {
@@ -2278,8 +2254,12 @@ qed_cxt_dynamic_ilt_alloc(struct qed_hwfn *p_hwfn,
for (elem_i = 0; elem_i < elems_per_p; elem_i++) {
elem = (union type1_task_context *)elem_start;
- SET_FIELD(elem->roce_ctx.tdif_context.flags1,
- TDIF_TASK_CONTEXT_REF_TAG_MASK, 0xf);
+ tdif_context = &elem->roce_ctx.tdif_context;
+
+ flags1 = le32_to_cpu(tdif_context->flags1);
+ SET_FIELD(flags1, TDIF_TASK_CONTEXT_REF_TAG_MASK, 0xf);
+ tdif_context->flags1 = cpu_to_le32(flags1);
+
elem_start += TYPE1_TASK_CXT_SIZE(p_hwfn);
}
}
@@ -2355,6 +2335,11 @@ qed_cxt_free_ilt_range(struct qed_hwfn *p_hwfn,
elem_size = SRQ_CXT_SIZE;
p_blk = &p_cli->pf_blks[SRQ_BLK];
break;
+ case QED_ELEM_XRC_SRQ:
+ p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_TSDM];
+ elem_size = XRC_SRQ_CXT_SIZE;
+ p_blk = &p_cli->pf_blks[SRQ_BLK];
+ break;
case QED_ELEM_TASK:
p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUT];
elem_size = TYPE1_TASK_CXT_SIZE(p_hwfn);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.h b/drivers/net/ethernet/qlogic/qed/qed_cxt.h
index ce08ae8d8498..8b64495f8745 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_CXT_H
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index 5c6a276f69ac..17d5b649eb36 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -573,7 +547,8 @@ qed_dcbx_get_ets_data(struct qed_hwfn *p_hwfn,
struct dcbx_ets_feature *p_ets,
struct qed_dcbx_params *p_params)
{
- u32 bw_map[2], tsa_map[2], pri_map;
+ __be32 bw_map[2], tsa_map[2];
+ u32 pri_map;
int i;
p_params->ets_willing = QED_MFW_GET_FIELD(p_ets->flags,
@@ -599,11 +574,10 @@ qed_dcbx_get_ets_data(struct qed_hwfn *p_hwfn,
/* 8 bit tsa and bw data corresponding to each of the 8 TC's are
* encoded in a type u32 array of size 2.
*/
- bw_map[0] = be32_to_cpu(p_ets->tc_bw_tbl[0]);
- bw_map[1] = be32_to_cpu(p_ets->tc_bw_tbl[1]);
- tsa_map[0] = be32_to_cpu(p_ets->tc_tsa_tbl[0]);
- tsa_map[1] = be32_to_cpu(p_ets->tc_tsa_tbl[1]);
+ cpu_to_be32_array(bw_map, p_ets->tc_bw_tbl, 2);
+ cpu_to_be32_array(tsa_map, p_ets->tc_tsa_tbl, 2);
pri_map = p_ets->pri_tc_tbl[0];
+
for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) {
p_params->ets_tc_bw_tbl[i] = ((u8 *)bw_map)[i];
p_params->ets_tc_tsa_tbl[i] = ((u8 *)tsa_map)[i];
@@ -1080,7 +1054,7 @@ qed_dcbx_set_ets_data(struct qed_hwfn *p_hwfn,
struct dcbx_ets_feature *p_ets,
struct qed_dcbx_params *p_params)
{
- u8 *bw_map, *tsa_map;
+ __be32 bw_map[2], tsa_map[2];
u32 val;
int i;
@@ -1102,22 +1076,21 @@ qed_dcbx_set_ets_data(struct qed_hwfn *p_hwfn,
p_ets->flags &= ~DCBX_ETS_MAX_TCS_MASK;
p_ets->flags |= (u32)p_params->max_ets_tc << DCBX_ETS_MAX_TCS_SHIFT;
- bw_map = (u8 *)&p_ets->tc_bw_tbl[0];
- tsa_map = (u8 *)&p_ets->tc_tsa_tbl[0];
p_ets->pri_tc_tbl[0] = 0;
+
for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) {
- bw_map[i] = p_params->ets_tc_bw_tbl[i];
- tsa_map[i] = p_params->ets_tc_tsa_tbl[i];
+ ((u8 *)bw_map)[i] = p_params->ets_tc_bw_tbl[i];
+ ((u8 *)tsa_map)[i] = p_params->ets_tc_tsa_tbl[i];
+
/* Copy the priority value to the corresponding 4 bits in the
* traffic class table.
*/
val = (((u32)p_params->ets_pri_tc_tbl[i]) << ((7 - i) * 4));
p_ets->pri_tc_tbl[0] |= val;
}
- for (i = 0; i < 2; i++) {
- p_ets->tc_bw_tbl[i] = cpu_to_be32(p_ets->tc_bw_tbl[i]);
- p_ets->tc_tsa_tbl[i] = cpu_to_be32(p_ets->tc_tsa_tbl[i]);
- }
+
+ be32_to_cpu_array(p_ets->tc_bw_tbl, bw_map, 2);
+ be32_to_cpu_array(p_ets->tc_tsa_tbl, tsa_map, 2);
}
static void
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h
index 01f253ea4b22..e1798925b444 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_DCBX_H
@@ -107,6 +81,8 @@ struct qed_dcbx_mib_meta_data {
u32 addr;
};
+extern const struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass;
+
#ifdef CONFIG_DCB
int qed_dcbx_get_config_params(struct qed_hwfn *, struct qed_dcbx_set *);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c
index 3b9bbafafe68..6ab3e60d4928 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
@@ -1,6 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015 QLogic Corporation
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/module.h>
@@ -971,7 +972,7 @@ static void qed_read_storm_fw_info(struct qed_hwfn *p_hwfn,
{
struct storm_defs *storm = &s_storm_defs[storm_id];
struct fw_info_location fw_info_location;
- u32 addr, i, *dest;
+ u32 addr, i, size, *dest;
memset(&fw_info_location, 0, sizeof(fw_info_location));
memset(fw_info, 0, sizeof(*fw_info));
@@ -984,20 +985,29 @@ static void qed_read_storm_fw_info(struct qed_hwfn *p_hwfn,
sizeof(fw_info_location);
dest = (u32 *)&fw_info_location;
+ size = BYTES_TO_DWORDS(sizeof(fw_info_location));
- for (i = 0; i < BYTES_TO_DWORDS(sizeof(fw_info_location));
- i++, addr += BYTES_IN_DWORD)
+ for (i = 0; i < size; i++, addr += BYTES_IN_DWORD)
dest[i] = qed_rd(p_hwfn, p_ptt, addr);
+ /* qed_rq() fetches data in CPU byteorder. Swap it back to
+ * the device's to get right structure layout.
+ */
+ cpu_to_le32_array(dest, size);
+
/* Read FW version info from Storm RAM */
- if (fw_info_location.size > 0 && fw_info_location.size <=
- sizeof(*fw_info)) {
- addr = fw_info_location.grc_addr;
- dest = (u32 *)fw_info;
- for (i = 0; i < BYTES_TO_DWORDS(fw_info_location.size);
- i++, addr += BYTES_IN_DWORD)
- dest[i] = qed_rd(p_hwfn, p_ptt, addr);
- }
+ size = le32_to_cpu(fw_info_location.size);
+ if (!size || size > sizeof(*fw_info))
+ return;
+
+ addr = le32_to_cpu(fw_info_location.grc_addr);
+ dest = (u32 *)fw_info;
+ size = BYTES_TO_DWORDS(size);
+
+ for (i = 0; i < size; i++, addr += BYTES_IN_DWORD)
+ dest[i] = qed_rd(p_hwfn, p_ptt, addr);
+
+ cpu_to_le32_array(dest, size);
}
/* Dumps the specified string to the specified buffer.
@@ -1121,9 +1131,8 @@ static u32 qed_dump_fw_ver_param(struct qed_hwfn *p_hwfn,
dump, "fw-version", fw_ver_str);
offset += qed_dump_str_param(dump_buf + offset,
dump, "fw-image", fw_img_str);
- offset += qed_dump_num_param(dump_buf + offset,
- dump,
- "fw-timestamp", fw_info.ver.timestamp);
+ offset += qed_dump_num_param(dump_buf + offset, dump, "fw-timestamp",
+ le32_to_cpu(fw_info.ver.timestamp));
return offset;
}
@@ -4440,9 +4449,11 @@ static u32 qed_fw_asserts_dump(struct qed_hwfn *p_hwfn,
continue;
}
+ addr = le16_to_cpu(asserts->section_ram_line_offset);
fw_asserts_section_addr = storm->sem_fast_mem_addr +
- SEM_FAST_REG_INT_RAM +
- RAM_LINES_TO_BYTES(asserts->section_ram_line_offset);
+ SEM_FAST_REG_INT_RAM +
+ RAM_LINES_TO_BYTES(addr);
+
next_list_idx_addr = fw_asserts_section_addr +
DWORDS_TO_BYTES(asserts->list_next_index_dword_offset);
next_list_idx = qed_rd(p_hwfn, p_ptt, next_list_idx_addr);
@@ -7656,8 +7667,7 @@ static int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer,
{
struct qed_hwfn *p_hwfn =
&cdev->hwfns[cdev->engine_for_debug];
- u32 len_rounded, i;
- __be32 val;
+ u32 len_rounded;
int rc;
*num_dumped_bytes = 0;
@@ -7676,10 +7686,9 @@ static int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer,
/* QED_NVM_IMAGE_NVM_META image is not swapped like other images */
if (image_id != QED_NVM_IMAGE_NVM_META)
- for (i = 0; i < len_rounded; i += 4) {
- val = cpu_to_be32(*(u32 *)(buffer + i));
- *(u32 *)(buffer + i) = val;
- }
+ cpu_to_be32_array((__force __be32 *)buffer,
+ (const u32 *)buffer,
+ len_rounded / sizeof(u32));
*num_dumped_bytes = len_rounded;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.h b/drivers/net/ethernet/qlogic/qed/qed_debug.h
index edf99d296bd1..e71af82d3200 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_debug.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_debug.h
@@ -1,6 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015 QLogic Corporation
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_DEBUGFS_H
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index dbdac983ccde..b3c9ebaf2280 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -3994,8 +3968,9 @@ unlock_and_exit:
static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
- u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities;
+ u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities, fld;
u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg;
+ struct qed_mcp_link_speed_params *ext_speed;
struct qed_mcp_link_capabilities *p_caps;
struct qed_mcp_link_params *link;
@@ -4020,37 +3995,21 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
switch ((core_cfg & NVM_CFG1_GLOB_NETWORK_PORT_MODE_MASK) >>
NVM_CFG1_GLOB_NETWORK_PORT_MODE_OFFSET) {
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_2X40G:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X40G;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X50G:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X50G;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_1X100G:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X100G;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X10G_F:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X10G_F;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X10G_E:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X10G_E;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X20G:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X20G;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X40G:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X40G;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X25G:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X25G;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X10G;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X25G;
- break;
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G:
- p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X25G;
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1:
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1:
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2:
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2:
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4:
break;
default:
DP_NOTICE(p_hwfn, "Unknown port mode in 0x%08x\n", core_cfg);
@@ -4068,8 +4027,7 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
link_temp &= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_MASK;
link->speed.advertised_speeds = link_temp;
- link_temp = link->speed.advertised_speeds;
- p_hwfn->mcp_info->link_capabilities.speed_capabilities = link_temp;
+ p_caps->speed_capabilities = link->speed.advertised_speeds;
link_temp = qed_rd(p_hwfn, p_ptt,
port_cfg_addr +
@@ -4104,19 +4062,40 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
DP_NOTICE(p_hwfn, "Unknown Speed in 0x%08x\n", link_temp);
}
- p_hwfn->mcp_info->link_capabilities.default_speed_autoneg =
- link->speed.autoneg;
+ p_caps->default_speed_autoneg = link->speed.autoneg;
- link_temp &= NVM_CFG1_PORT_DRV_FLOW_CONTROL_MASK;
- link_temp >>= NVM_CFG1_PORT_DRV_FLOW_CONTROL_OFFSET;
- link->pause.autoneg = !!(link_temp &
- NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG);
- link->pause.forced_rx = !!(link_temp &
- NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX);
- link->pause.forced_tx = !!(link_temp &
- NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX);
+ fld = GET_MFW_FIELD(link_temp, NVM_CFG1_PORT_DRV_FLOW_CONTROL);
+ link->pause.autoneg = !!(fld & NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG);
+ link->pause.forced_rx = !!(fld & NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX);
+ link->pause.forced_tx = !!(fld & NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX);
link->loopback_mode = 0;
+ if (p_hwfn->mcp_info->capabilities &
+ FW_MB_PARAM_FEATURE_SUPPORT_FEC_CONTROL) {
+ switch (GET_MFW_FIELD(link_temp,
+ NVM_CFG1_PORT_FEC_FORCE_MODE)) {
+ case NVM_CFG1_PORT_FEC_FORCE_MODE_NONE:
+ p_caps->fec_default |= QED_FEC_MODE_NONE;
+ break;
+ case NVM_CFG1_PORT_FEC_FORCE_MODE_FIRECODE:
+ p_caps->fec_default |= QED_FEC_MODE_FIRECODE;
+ break;
+ case NVM_CFG1_PORT_FEC_FORCE_MODE_RS:
+ p_caps->fec_default |= QED_FEC_MODE_RS;
+ break;
+ case NVM_CFG1_PORT_FEC_FORCE_MODE_AUTO:
+ p_caps->fec_default |= QED_FEC_MODE_AUTO;
+ break;
+ default:
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+ "unknown FEC mode in 0x%08x\n", link_temp);
+ }
+ } else {
+ p_caps->fec_default = QED_FEC_MODE_UNSUPPORTED;
+ }
+
+ link->fec = p_caps->fec_default;
+
if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE) {
link_temp = qed_rd(p_hwfn, p_ptt, port_cfg_addr +
offsetof(struct nvm_cfg1_port, ext_phy));
@@ -4148,14 +4127,97 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
p_caps->default_eee = QED_MCP_EEE_UNSUPPORTED;
}
- DP_VERBOSE(p_hwfn,
- NETIF_MSG_LINK,
- "Read default link: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, PAUSE AN: 0x%02x EEE: %02x [%08x usec]\n",
- link->speed.forced_speed,
- link->speed.advertised_speeds,
- link->speed.autoneg,
- link->pause.autoneg,
- p_caps->default_eee, p_caps->eee_lpi_timer);
+ if (p_hwfn->mcp_info->capabilities &
+ FW_MB_PARAM_FEATURE_SUPPORT_EXT_SPEED_FEC_CONTROL) {
+ ext_speed = &link->ext_speed;
+
+ link_temp = qed_rd(p_hwfn, p_ptt,
+ port_cfg_addr +
+ offsetof(struct nvm_cfg1_port,
+ extended_speed));
+
+ fld = GET_MFW_FIELD(link_temp, NVM_CFG1_PORT_EXTENDED_SPEED);
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_AN)
+ ext_speed->autoneg = true;
+
+ ext_speed->forced_speed = 0;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_1G)
+ ext_speed->forced_speed |= QED_EXT_SPEED_1G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_10G)
+ ext_speed->forced_speed |= QED_EXT_SPEED_10G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_20G)
+ ext_speed->forced_speed |= QED_EXT_SPEED_20G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_25G)
+ ext_speed->forced_speed |= QED_EXT_SPEED_25G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_40G)
+ ext_speed->forced_speed |= QED_EXT_SPEED_40G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_50G_R)
+ ext_speed->forced_speed |= QED_EXT_SPEED_50G_R;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_50G_R2)
+ ext_speed->forced_speed |= QED_EXT_SPEED_50G_R2;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_R2)
+ ext_speed->forced_speed |= QED_EXT_SPEED_100G_R2;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_R4)
+ ext_speed->forced_speed |= QED_EXT_SPEED_100G_R4;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_P4)
+ ext_speed->forced_speed |= QED_EXT_SPEED_100G_P4;
+
+ fld = GET_MFW_FIELD(link_temp,
+ NVM_CFG1_PORT_EXTENDED_SPEED_CAP);
+
+ ext_speed->advertised_speeds = 0;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_RESERVED)
+ ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_RES;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_1G)
+ ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_1G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_10G)
+ ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_10G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_20G)
+ ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_20G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_25G)
+ ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_25G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_40G)
+ ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_40G;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_50G_R)
+ ext_speed->advertised_speeds |=
+ QED_EXT_SPEED_MASK_50G_R;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_50G_R2)
+ ext_speed->advertised_speeds |=
+ QED_EXT_SPEED_MASK_50G_R2;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_R2)
+ ext_speed->advertised_speeds |=
+ QED_EXT_SPEED_MASK_100G_R2;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_R4)
+ ext_speed->advertised_speeds |=
+ QED_EXT_SPEED_MASK_100G_R4;
+ if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_P4)
+ ext_speed->advertised_speeds |=
+ QED_EXT_SPEED_MASK_100G_P4;
+
+ link_temp = qed_rd(p_hwfn, p_ptt,
+ port_cfg_addr +
+ offsetof(struct nvm_cfg1_port,
+ extended_fec_mode));
+ link->ext_fec_mode = link_temp;
+
+ p_caps->default_ext_speed_caps = ext_speed->advertised_speeds;
+ p_caps->default_ext_speed = ext_speed->forced_speed;
+ p_caps->default_ext_autoneg = ext_speed->autoneg;
+ p_caps->default_ext_fec = link->ext_fec_mode;
+
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+ "Read default extended link config: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, FEC: 0x%02x\n",
+ ext_speed->forced_speed,
+ ext_speed->advertised_speeds, ext_speed->autoneg,
+ p_caps->default_ext_fec);
+ }
+
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
+ "Read default link: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, PAUSE AN: 0x%02x, EEE: 0x%02x [0x%08x usec], FEC: 0x%02x\n",
+ link->speed.forced_speed, link->speed.advertised_speeds,
+ link->speed.autoneg, link->pause.autoneg,
+ p_caps->default_eee, p_caps->eee_lpi_timer,
+ p_caps->fec_default);
if (IS_LEAD_HWFN(p_hwfn)) {
struct qed_dev *cdev = p_hwfn->cdev;
@@ -4654,279 +4716,6 @@ void qed_hw_remove(struct qed_dev *cdev)
qed_mcp_nvm_info_free(p_hwfn);
}
-static void qed_chain_free_next_ptr(struct qed_dev *cdev,
- struct qed_chain *p_chain)
-{
- void *p_virt = p_chain->p_virt_addr, *p_virt_next = NULL;
- dma_addr_t p_phys = p_chain->p_phys_addr, p_phys_next = 0;
- struct qed_chain_next *p_next;
- u32 size, i;
-
- if (!p_virt)
- return;
-
- size = p_chain->elem_size * p_chain->usable_per_page;
-
- for (i = 0; i < p_chain->page_cnt; i++) {
- if (!p_virt)
- break;
-
- p_next = (struct qed_chain_next *)((u8 *)p_virt + size);
- p_virt_next = p_next->next_virt;
- p_phys_next = HILO_DMA_REGPAIR(p_next->next_phys);
-
- dma_free_coherent(&cdev->pdev->dev,
- QED_CHAIN_PAGE_SIZE, p_virt, p_phys);
-
- p_virt = p_virt_next;
- p_phys = p_phys_next;
- }
-}
-
-static void qed_chain_free_single(struct qed_dev *cdev,
- struct qed_chain *p_chain)
-{
- if (!p_chain->p_virt_addr)
- return;
-
- dma_free_coherent(&cdev->pdev->dev,
- QED_CHAIN_PAGE_SIZE,
- p_chain->p_virt_addr, p_chain->p_phys_addr);
-}
-
-static void qed_chain_free_pbl(struct qed_dev *cdev, struct qed_chain *p_chain)
-{
- struct addr_tbl_entry *pp_addr_tbl = p_chain->pbl.pp_addr_tbl;
- u32 page_cnt = p_chain->page_cnt, i, pbl_size;
-
- if (!pp_addr_tbl)
- return;
-
- for (i = 0; i < page_cnt; i++) {
- if (!pp_addr_tbl[i].virt_addr || !pp_addr_tbl[i].dma_map)
- break;
-
- dma_free_coherent(&cdev->pdev->dev,
- QED_CHAIN_PAGE_SIZE,
- pp_addr_tbl[i].virt_addr,
- pp_addr_tbl[i].dma_map);
- }
-
- pbl_size = page_cnt * QED_CHAIN_PBL_ENTRY_SIZE;
-
- if (!p_chain->b_external_pbl)
- dma_free_coherent(&cdev->pdev->dev,
- pbl_size,
- p_chain->pbl_sp.p_virt_table,
- p_chain->pbl_sp.p_phys_table);
-
- vfree(p_chain->pbl.pp_addr_tbl);
- p_chain->pbl.pp_addr_tbl = NULL;
-}
-
-void qed_chain_free(struct qed_dev *cdev, struct qed_chain *p_chain)
-{
- switch (p_chain->mode) {
- case QED_CHAIN_MODE_NEXT_PTR:
- qed_chain_free_next_ptr(cdev, p_chain);
- break;
- case QED_CHAIN_MODE_SINGLE:
- qed_chain_free_single(cdev, p_chain);
- break;
- case QED_CHAIN_MODE_PBL:
- qed_chain_free_pbl(cdev, p_chain);
- break;
- }
-}
-
-static int
-qed_chain_alloc_sanity_check(struct qed_dev *cdev,
- enum qed_chain_cnt_type cnt_type,
- size_t elem_size, u32 page_cnt)
-{
- u64 chain_size = ELEMS_PER_PAGE(elem_size) * page_cnt;
-
- /* The actual chain size can be larger than the maximal possible value
- * after rounding up the requested elements number to pages, and after
- * taking into acount the unusuable elements (next-ptr elements).
- * The size of a "u16" chain can be (U16_MAX + 1) since the chain
- * size/capacity fields are of a u32 type.
- */
- if ((cnt_type == QED_CHAIN_CNT_TYPE_U16 &&
- chain_size > ((u32)U16_MAX + 1)) ||
- (cnt_type == QED_CHAIN_CNT_TYPE_U32 && chain_size > U32_MAX)) {
- DP_NOTICE(cdev,
- "The actual chain size (0x%llx) is larger than the maximal possible value\n",
- chain_size);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-qed_chain_alloc_next_ptr(struct qed_dev *cdev, struct qed_chain *p_chain)
-{
- void *p_virt = NULL, *p_virt_prev = NULL;
- dma_addr_t p_phys = 0;
- u32 i;
-
- for (i = 0; i < p_chain->page_cnt; i++) {
- p_virt = dma_alloc_coherent(&cdev->pdev->dev,
- QED_CHAIN_PAGE_SIZE,
- &p_phys, GFP_KERNEL);
- if (!p_virt)
- return -ENOMEM;
-
- if (i == 0) {
- qed_chain_init_mem(p_chain, p_virt, p_phys);
- qed_chain_reset(p_chain);
- } else {
- qed_chain_init_next_ptr_elem(p_chain, p_virt_prev,
- p_virt, p_phys);
- }
-
- p_virt_prev = p_virt;
- }
- /* Last page's next element should point to the beginning of the
- * chain.
- */
- qed_chain_init_next_ptr_elem(p_chain, p_virt_prev,
- p_chain->p_virt_addr,
- p_chain->p_phys_addr);
-
- return 0;
-}
-
-static int
-qed_chain_alloc_single(struct qed_dev *cdev, struct qed_chain *p_chain)
-{
- dma_addr_t p_phys = 0;
- void *p_virt = NULL;
-
- p_virt = dma_alloc_coherent(&cdev->pdev->dev,
- QED_CHAIN_PAGE_SIZE, &p_phys, GFP_KERNEL);
- if (!p_virt)
- return -ENOMEM;
-
- qed_chain_init_mem(p_chain, p_virt, p_phys);
- qed_chain_reset(p_chain);
-
- return 0;
-}
-
-static int
-qed_chain_alloc_pbl(struct qed_dev *cdev,
- struct qed_chain *p_chain,
- struct qed_chain_ext_pbl *ext_pbl)
-{
- u32 page_cnt = p_chain->page_cnt, size, i;
- dma_addr_t p_phys = 0, p_pbl_phys = 0;
- struct addr_tbl_entry *pp_addr_tbl;
- u8 *p_pbl_virt = NULL;
- void *p_virt = NULL;
-
- size = page_cnt * sizeof(*pp_addr_tbl);
- pp_addr_tbl = vzalloc(size);
- if (!pp_addr_tbl)
- return -ENOMEM;
-
- /* The allocation of the PBL table is done with its full size, since it
- * is expected to be successive.
- * qed_chain_init_pbl_mem() is called even in a case of an allocation
- * failure, since tbl was previously allocated, and it
- * should be saved to allow its freeing during the error flow.
- */
- size = page_cnt * QED_CHAIN_PBL_ENTRY_SIZE;
-
- if (!ext_pbl) {
- p_pbl_virt = dma_alloc_coherent(&cdev->pdev->dev,
- size, &p_pbl_phys, GFP_KERNEL);
- } else {
- p_pbl_virt = ext_pbl->p_pbl_virt;
- p_pbl_phys = ext_pbl->p_pbl_phys;
- p_chain->b_external_pbl = true;
- }
-
- qed_chain_init_pbl_mem(p_chain, p_pbl_virt, p_pbl_phys, pp_addr_tbl);
- if (!p_pbl_virt)
- return -ENOMEM;
-
- for (i = 0; i < page_cnt; i++) {
- p_virt = dma_alloc_coherent(&cdev->pdev->dev,
- QED_CHAIN_PAGE_SIZE,
- &p_phys, GFP_KERNEL);
- if (!p_virt)
- return -ENOMEM;
-
- if (i == 0) {
- qed_chain_init_mem(p_chain, p_virt, p_phys);
- qed_chain_reset(p_chain);
- }
-
- /* Fill the PBL table with the physical address of the page */
- *(dma_addr_t *)p_pbl_virt = p_phys;
- /* Keep the virtual address of the page */
- p_chain->pbl.pp_addr_tbl[i].virt_addr = p_virt;
- p_chain->pbl.pp_addr_tbl[i].dma_map = p_phys;
-
- p_pbl_virt += QED_CHAIN_PBL_ENTRY_SIZE;
- }
-
- return 0;
-}
-
-int qed_chain_alloc(struct qed_dev *cdev,
- enum qed_chain_use_mode intended_use,
- enum qed_chain_mode mode,
- enum qed_chain_cnt_type cnt_type,
- u32 num_elems,
- size_t elem_size,
- struct qed_chain *p_chain,
- struct qed_chain_ext_pbl *ext_pbl)
-{
- u32 page_cnt;
- int rc = 0;
-
- if (mode == QED_CHAIN_MODE_SINGLE)
- page_cnt = 1;
- else
- page_cnt = QED_CHAIN_PAGE_CNT(num_elems, elem_size, mode);
-
- rc = qed_chain_alloc_sanity_check(cdev, cnt_type, elem_size, page_cnt);
- if (rc) {
- DP_NOTICE(cdev,
- "Cannot allocate a chain with the given arguments:\n");
- DP_NOTICE(cdev,
- "[use_mode %d, mode %d, cnt_type %d, num_elems %d, elem_size %zu]\n",
- intended_use, mode, cnt_type, num_elems, elem_size);
- return rc;
- }
-
- qed_chain_init_params(p_chain, page_cnt, (u8) elem_size, intended_use,
- mode, cnt_type);
-
- switch (mode) {
- case QED_CHAIN_MODE_NEXT_PTR:
- rc = qed_chain_alloc_next_ptr(cdev, p_chain);
- break;
- case QED_CHAIN_MODE_SINGLE:
- rc = qed_chain_alloc_single(cdev, p_chain);
- break;
- case QED_CHAIN_MODE_PBL:
- rc = qed_chain_alloc_pbl(cdev, p_chain, ext_pbl);
- break;
- }
- if (rc)
- goto nomem;
-
- return 0;
-
-nomem:
- qed_chain_free(cdev, p_chain);
- return rc;
-}
-
int qed_fw_l2_queue(struct qed_hwfn *p_hwfn, u16 src_id, u16 *dst_id)
{
if (src_id >= RESC_NUM(p_hwfn, QED_L2_QUEUE)) {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
index eb4808b3bf67..d3c1f3879be8 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_DEV_API_H
@@ -280,35 +254,9 @@ int qed_dmae_host2host(struct qed_hwfn *p_hwfn,
dma_addr_t dest_addr,
u32 size_in_dwords, struct qed_dmae_params *p_params);
-/**
- * @brief qed_chain_alloc - Allocate and initialize a chain
- *
- * @param p_hwfn
- * @param intended_use
- * @param mode
- * @param num_elems
- * @param elem_size
- * @param p_chain
- * @param ext_pbl - a possible external PBL
- *
- * @return int
- */
-int
-qed_chain_alloc(struct qed_dev *cdev,
- enum qed_chain_use_mode intended_use,
- enum qed_chain_mode mode,
- enum qed_chain_cnt_type cnt_type,
- u32 num_elems,
- size_t elem_size,
- struct qed_chain *p_chain, struct qed_chain_ext_pbl *ext_pbl);
-
-/**
- * @brief qed_chain_free - Free chain DMA memory
- *
- * @param p_hwfn
- * @param p_chain
- */
-void qed_chain_free(struct qed_dev *cdev, struct qed_chain *p_chain);
+int qed_chain_alloc(struct qed_dev *cdev, struct qed_chain *chain,
+ struct qed_chain_init_params *params);
+void qed_chain_free(struct qed_dev *cdev, struct qed_chain *chain);
/**
* @@brief qed_fw_l2_queue - Get absolute L2 queue ID
diff --git a/drivers/net/ethernet/qlogic/qed/qed_fcoe.c b/drivers/net/ethernet/qlogic/qed/qed_fcoe.c
index 4c7fa391fd33..b768f0698170 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_fcoe.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_fcoe.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -121,7 +95,7 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
struct qed_cxt_info cxt_info;
u32 dummy_cid;
int rc = 0;
- u16 tmp;
+ __le16 tmp;
u8 i;
/* Get SPQ entry */
@@ -188,17 +162,13 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
tmp = cpu_to_le16(fcoe_pf_params->cmdq_num_entries);
p_data->q_params.cmdq_num_entries = tmp;
- tmp = fcoe_pf_params->num_cqs;
- p_data->q_params.num_queues = (u8)tmp;
+ p_data->q_params.num_queues = fcoe_pf_params->num_cqs;
- tmp = (u16)p_hwfn->hw_info.resc_start[QED_CMDQS_CQS];
- p_data->q_params.queue_relative_offset = (u8)tmp;
+ tmp = (__force __le16)p_hwfn->hw_info.resc_start[QED_CMDQS_CQS];
+ p_data->q_params.queue_relative_offset = (__force u8)tmp;
for (i = 0; i < fcoe_pf_params->num_cqs; i++) {
- u16 igu_sb_id;
-
- igu_sb_id = qed_get_igu_sb_id(p_hwfn, i);
- tmp = cpu_to_le16(igu_sb_id);
+ tmp = cpu_to_le16(qed_get_igu_sb_id(p_hwfn, i));
p_data->q_params.cq_cmdq_sb_num_arr[i] = tmp;
}
@@ -211,21 +181,21 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
fcoe_pf_params->bdq_pbl_base_addr[BDQ_ID_RQ]);
p_data->q_params.bdq_pbl_num_entries[BDQ_ID_RQ] =
fcoe_pf_params->bdq_pbl_num_entries[BDQ_ID_RQ];
- tmp = fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_RQ];
- p_data->q_params.bdq_xoff_threshold[BDQ_ID_RQ] = cpu_to_le16(tmp);
- tmp = fcoe_pf_params->bdq_xon_threshold[BDQ_ID_RQ];
- p_data->q_params.bdq_xon_threshold[BDQ_ID_RQ] = cpu_to_le16(tmp);
+ tmp = cpu_to_le16(fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_RQ]);
+ p_data->q_params.bdq_xoff_threshold[BDQ_ID_RQ] = tmp;
+ tmp = cpu_to_le16(fcoe_pf_params->bdq_xon_threshold[BDQ_ID_RQ]);
+ p_data->q_params.bdq_xon_threshold[BDQ_ID_RQ] = tmp;
DMA_REGPAIR_LE(p_data->q_params.bdq_pbl_base_address[BDQ_ID_IMM_DATA],
fcoe_pf_params->bdq_pbl_base_addr[BDQ_ID_IMM_DATA]);
p_data->q_params.bdq_pbl_num_entries[BDQ_ID_IMM_DATA] =
fcoe_pf_params->bdq_pbl_num_entries[BDQ_ID_IMM_DATA];
- tmp = fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_IMM_DATA];
- p_data->q_params.bdq_xoff_threshold[BDQ_ID_IMM_DATA] = cpu_to_le16(tmp);
- tmp = fcoe_pf_params->bdq_xon_threshold[BDQ_ID_IMM_DATA];
- p_data->q_params.bdq_xon_threshold[BDQ_ID_IMM_DATA] = cpu_to_le16(tmp);
- tmp = fcoe_pf_params->rq_buffer_size;
- p_data->q_params.rq_buffer_size = cpu_to_le16(tmp);
+ tmp = cpu_to_le16(fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_IMM_DATA]);
+ p_data->q_params.bdq_xoff_threshold[BDQ_ID_IMM_DATA] = tmp;
+ tmp = cpu_to_le16(fcoe_pf_params->bdq_xon_threshold[BDQ_ID_IMM_DATA]);
+ p_data->q_params.bdq_xon_threshold[BDQ_ID_IMM_DATA] = tmp;
+ tmp = cpu_to_le16(fcoe_pf_params->rq_buffer_size);
+ p_data->q_params.rq_buffer_size = tmp;
if (fcoe_pf_params->is_target) {
SET_FIELD(p_data->q_params.q_validity,
@@ -259,7 +229,8 @@ qed_sp_fcoe_conn_offload(struct qed_hwfn *p_hwfn,
struct fcoe_conn_offload_ramrod_data *p_data;
struct qed_spq_entry *p_ent = NULL;
struct qed_sp_init_data init_data;
- u16 physical_q0, tmp;
+ u16 physical_q0;
+ __le16 tmp;
int rc;
/* Get SPQ entry */
@@ -280,7 +251,7 @@ qed_sp_fcoe_conn_offload(struct qed_hwfn *p_hwfn,
/* Transmission PQ is the first of the PF */
physical_q0 = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_OFLD);
- p_conn->physical_q0 = cpu_to_le16(physical_q0);
+ p_conn->physical_q0 = physical_q0;
p_data->physical_q0 = cpu_to_le16(physical_q0);
p_data->conn_id = cpu_to_le16(p_conn->conn_id);
@@ -579,8 +550,8 @@ int qed_fcoe_alloc(struct qed_hwfn *p_hwfn)
void qed_fcoe_setup(struct qed_hwfn *p_hwfn)
{
struct e4_fcoe_task_context *p_task_ctx = NULL;
+ u32 i, lc;
int rc;
- u32 i;
spin_lock_init(&p_hwfn->p_fcoe_info->lock);
for (i = 0; i < p_hwfn->pf_params.fcoe_pf_params.num_tasks; i++) {
@@ -591,10 +562,15 @@ void qed_fcoe_setup(struct qed_hwfn *p_hwfn)
continue;
memset(p_task_ctx, 0, sizeof(struct e4_fcoe_task_context));
- SET_FIELD(p_task_ctx->timer_context.logical_client_0,
- TIMERS_CONTEXT_VALIDLC0, 1);
- SET_FIELD(p_task_ctx->timer_context.logical_client_1,
- TIMERS_CONTEXT_VALIDLC1, 1);
+
+ lc = 0;
+ SET_FIELD(lc, TIMERS_CONTEXT_VALIDLC0, 1);
+ p_task_ctx->timer_context.logical_client_0 = cpu_to_le32(lc);
+
+ lc = 0;
+ SET_FIELD(lc, TIMERS_CONTEXT_VALIDLC1, 1);
+ p_task_ctx->timer_context.logical_client_1 = cpu_to_le32(lc);
+
SET_FIELD(p_task_ctx->tstorm_ag_context.flags0,
E4_TSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE, 1);
}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_fcoe.h b/drivers/net/ethernet/qlogic/qed/qed_fcoe.h
index 027a76ac839a..19c85adf4ceb 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_fcoe.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_fcoe.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_FCOE_H
@@ -71,9 +45,4 @@ static inline void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
}
#endif /* CONFIG_QED_FCOE */
-#ifdef CONFIG_QED_LL2
-extern const struct qed_common_ops qed_common_ops_pass;
-extern const struct qed_ll2_ops qed_ll2_ops_pass;
-#endif
-
#endif /* _QED_FCOE_H */
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index f00460d00cab..559df9f4d656 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_HSI_H
@@ -387,7 +361,7 @@ struct core_tx_update_ramrod_data {
u8 update_qm_pq_id_flg;
u8 reserved0;
__le16 qm_pq_id;
- __le32 reserved1[1];
+ __le32 reserved1;
};
/* Enum flag for what type of dcb data to update */
@@ -2819,34 +2793,34 @@ struct fw_overlay_buf_hdr {
/* init array header: raw */
struct init_array_raw_hdr {
- u32 data;
-#define INIT_ARRAY_RAW_HDR_TYPE_MASK 0xF
-#define INIT_ARRAY_RAW_HDR_TYPE_SHIFT 0
-#define INIT_ARRAY_RAW_HDR_PARAMS_MASK 0xFFFFFFF
-#define INIT_ARRAY_RAW_HDR_PARAMS_SHIFT 4
+ __le32 data;
+#define INIT_ARRAY_RAW_HDR_TYPE_MASK 0xF
+#define INIT_ARRAY_RAW_HDR_TYPE_SHIFT 0
+#define INIT_ARRAY_RAW_HDR_PARAMS_MASK 0xFFFFFFF
+#define INIT_ARRAY_RAW_HDR_PARAMS_SHIFT 4
};
/* init array header: standard */
struct init_array_standard_hdr {
- u32 data;
-#define INIT_ARRAY_STANDARD_HDR_TYPE_MASK 0xF
-#define INIT_ARRAY_STANDARD_HDR_TYPE_SHIFT 0
-#define INIT_ARRAY_STANDARD_HDR_SIZE_MASK 0xFFFFFFF
-#define INIT_ARRAY_STANDARD_HDR_SIZE_SHIFT 4
+ __le32 data;
+#define INIT_ARRAY_STANDARD_HDR_TYPE_MASK 0xF
+#define INIT_ARRAY_STANDARD_HDR_TYPE_SHIFT 0
+#define INIT_ARRAY_STANDARD_HDR_SIZE_MASK 0xFFFFFFF
+#define INIT_ARRAY_STANDARD_HDR_SIZE_SHIFT 4
};
/* init array header: zipped */
struct init_array_zipped_hdr {
- u32 data;
-#define INIT_ARRAY_ZIPPED_HDR_TYPE_MASK 0xF
-#define INIT_ARRAY_ZIPPED_HDR_TYPE_SHIFT 0
-#define INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE_MASK 0xFFFFFFF
-#define INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE_SHIFT 4
+ __le32 data;
+#define INIT_ARRAY_ZIPPED_HDR_TYPE_MASK 0xF
+#define INIT_ARRAY_ZIPPED_HDR_TYPE_SHIFT 0
+#define INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE_MASK 0xFFFFFFF
+#define INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE_SHIFT 4
};
/* init array header: pattern */
struct init_array_pattern_hdr {
- u32 data;
+ __le32 data;
#define INIT_ARRAY_PATTERN_HDR_TYPE_MASK 0xF
#define INIT_ARRAY_PATTERN_HDR_TYPE_SHIFT 0
#define INIT_ARRAY_PATTERN_HDR_PATTERN_SIZE_MASK 0xF
@@ -2857,10 +2831,10 @@ struct init_array_pattern_hdr {
/* init array header union */
union init_array_hdr {
- struct init_array_raw_hdr raw;
- struct init_array_standard_hdr standard;
- struct init_array_zipped_hdr zipped;
- struct init_array_pattern_hdr pattern;
+ struct init_array_raw_hdr raw;
+ struct init_array_standard_hdr standard;
+ struct init_array_zipped_hdr zipped;
+ struct init_array_pattern_hdr pattern;
};
/* init array types */
@@ -2873,54 +2847,54 @@ enum init_array_types {
/* init operation: callback */
struct init_callback_op {
- u32 op_data;
-#define INIT_CALLBACK_OP_OP_MASK 0xF
-#define INIT_CALLBACK_OP_OP_SHIFT 0
-#define INIT_CALLBACK_OP_RESERVED_MASK 0xFFFFFFF
-#define INIT_CALLBACK_OP_RESERVED_SHIFT 4
- u16 callback_id;
- u16 block_id;
+ __le32 op_data;
+#define INIT_CALLBACK_OP_OP_MASK 0xF
+#define INIT_CALLBACK_OP_OP_SHIFT 0
+#define INIT_CALLBACK_OP_RESERVED_MASK 0xFFFFFFF
+#define INIT_CALLBACK_OP_RESERVED_SHIFT 4
+ __le16 callback_id;
+ __le16 block_id;
};
/* init operation: delay */
struct init_delay_op {
- u32 op_data;
-#define INIT_DELAY_OP_OP_MASK 0xF
-#define INIT_DELAY_OP_OP_SHIFT 0
-#define INIT_DELAY_OP_RESERVED_MASK 0xFFFFFFF
-#define INIT_DELAY_OP_RESERVED_SHIFT 4
- u32 delay;
+ __le32 op_data;
+#define INIT_DELAY_OP_OP_MASK 0xF
+#define INIT_DELAY_OP_OP_SHIFT 0
+#define INIT_DELAY_OP_RESERVED_MASK 0xFFFFFFF
+#define INIT_DELAY_OP_RESERVED_SHIFT 4
+ __le32 delay;
};
/* init operation: if_mode */
struct init_if_mode_op {
- u32 op_data;
-#define INIT_IF_MODE_OP_OP_MASK 0xF
-#define INIT_IF_MODE_OP_OP_SHIFT 0
-#define INIT_IF_MODE_OP_RESERVED1_MASK 0xFFF
-#define INIT_IF_MODE_OP_RESERVED1_SHIFT 4
-#define INIT_IF_MODE_OP_CMD_OFFSET_MASK 0xFFFF
-#define INIT_IF_MODE_OP_CMD_OFFSET_SHIFT 16
- u16 reserved2;
- u16 modes_buf_offset;
+ __le32 op_data;
+#define INIT_IF_MODE_OP_OP_MASK 0xF
+#define INIT_IF_MODE_OP_OP_SHIFT 0
+#define INIT_IF_MODE_OP_RESERVED1_MASK 0xFFF
+#define INIT_IF_MODE_OP_RESERVED1_SHIFT 4
+#define INIT_IF_MODE_OP_CMD_OFFSET_MASK 0xFFFF
+#define INIT_IF_MODE_OP_CMD_OFFSET_SHIFT 16
+ __le16 reserved2;
+ __le16 modes_buf_offset;
};
/* init operation: if_phase */
struct init_if_phase_op {
- u32 op_data;
-#define INIT_IF_PHASE_OP_OP_MASK 0xF
-#define INIT_IF_PHASE_OP_OP_SHIFT 0
-#define INIT_IF_PHASE_OP_RESERVED1_MASK 0xFFF
-#define INIT_IF_PHASE_OP_RESERVED1_SHIFT 4
-#define INIT_IF_PHASE_OP_CMD_OFFSET_MASK 0xFFFF
-#define INIT_IF_PHASE_OP_CMD_OFFSET_SHIFT 16
- u32 phase_data;
-#define INIT_IF_PHASE_OP_PHASE_MASK 0xFF
-#define INIT_IF_PHASE_OP_PHASE_SHIFT 0
-#define INIT_IF_PHASE_OP_RESERVED2_MASK 0xFF
-#define INIT_IF_PHASE_OP_RESERVED2_SHIFT 8
-#define INIT_IF_PHASE_OP_PHASE_ID_MASK 0xFFFF
-#define INIT_IF_PHASE_OP_PHASE_ID_SHIFT 16
+ __le32 op_data;
+#define INIT_IF_PHASE_OP_OP_MASK 0xF
+#define INIT_IF_PHASE_OP_OP_SHIFT 0
+#define INIT_IF_PHASE_OP_RESERVED1_MASK 0xFFF
+#define INIT_IF_PHASE_OP_RESERVED1_SHIFT 4
+#define INIT_IF_PHASE_OP_CMD_OFFSET_MASK 0xFFFF
+#define INIT_IF_PHASE_OP_CMD_OFFSET_SHIFT 16
+ __le32 phase_data;
+#define INIT_IF_PHASE_OP_PHASE_MASK 0xFF
+#define INIT_IF_PHASE_OP_PHASE_SHIFT 0
+#define INIT_IF_PHASE_OP_RESERVED2_MASK 0xFF
+#define INIT_IF_PHASE_OP_RESERVED2_SHIFT 8
+#define INIT_IF_PHASE_OP_PHASE_ID_MASK 0xFFFF
+#define INIT_IF_PHASE_OP_PHASE_ID_SHIFT 16
};
/* init mode operators */
@@ -2933,67 +2907,67 @@ enum init_mode_ops {
/* init operation: raw */
struct init_raw_op {
- u32 op_data;
-#define INIT_RAW_OP_OP_MASK 0xF
-#define INIT_RAW_OP_OP_SHIFT 0
-#define INIT_RAW_OP_PARAM1_MASK 0xFFFFFFF
-#define INIT_RAW_OP_PARAM1_SHIFT 4
- u32 param2;
+ __le32 op_data;
+#define INIT_RAW_OP_OP_MASK 0xF
+#define INIT_RAW_OP_OP_SHIFT 0
+#define INIT_RAW_OP_PARAM1_MASK 0xFFFFFFF
+#define INIT_RAW_OP_PARAM1_SHIFT 4
+ __le32 param2;
};
/* init array params */
struct init_op_array_params {
- u16 size;
- u16 offset;
+ __le16 size;
+ __le16 offset;
};
/* Write init operation arguments */
union init_write_args {
- u32 inline_val;
- u32 zeros_count;
- u32 array_offset;
- struct init_op_array_params runtime;
+ __le32 inline_val;
+ __le32 zeros_count;
+ __le32 array_offset;
+ struct init_op_array_params runtime;
};
/* init operation: write */
struct init_write_op {
- u32 data;
-#define INIT_WRITE_OP_OP_MASK 0xF
-#define INIT_WRITE_OP_OP_SHIFT 0
-#define INIT_WRITE_OP_SOURCE_MASK 0x7
-#define INIT_WRITE_OP_SOURCE_SHIFT 4
-#define INIT_WRITE_OP_RESERVED_MASK 0x1
-#define INIT_WRITE_OP_RESERVED_SHIFT 7
-#define INIT_WRITE_OP_WIDE_BUS_MASK 0x1
-#define INIT_WRITE_OP_WIDE_BUS_SHIFT 8
-#define INIT_WRITE_OP_ADDRESS_MASK 0x7FFFFF
-#define INIT_WRITE_OP_ADDRESS_SHIFT 9
- union init_write_args args;
+ __le32 data;
+#define INIT_WRITE_OP_OP_MASK 0xF
+#define INIT_WRITE_OP_OP_SHIFT 0
+#define INIT_WRITE_OP_SOURCE_MASK 0x7
+#define INIT_WRITE_OP_SOURCE_SHIFT 4
+#define INIT_WRITE_OP_RESERVED_MASK 0x1
+#define INIT_WRITE_OP_RESERVED_SHIFT 7
+#define INIT_WRITE_OP_WIDE_BUS_MASK 0x1
+#define INIT_WRITE_OP_WIDE_BUS_SHIFT 8
+#define INIT_WRITE_OP_ADDRESS_MASK 0x7FFFFF
+#define INIT_WRITE_OP_ADDRESS_SHIFT 9
+ union init_write_args args;
};
/* init operation: read */
struct init_read_op {
- u32 op_data;
-#define INIT_READ_OP_OP_MASK 0xF
-#define INIT_READ_OP_OP_SHIFT 0
-#define INIT_READ_OP_POLL_TYPE_MASK 0xF
-#define INIT_READ_OP_POLL_TYPE_SHIFT 4
-#define INIT_READ_OP_RESERVED_MASK 0x1
-#define INIT_READ_OP_RESERVED_SHIFT 8
-#define INIT_READ_OP_ADDRESS_MASK 0x7FFFFF
-#define INIT_READ_OP_ADDRESS_SHIFT 9
- u32 expected_val;
+ __le32 op_data;
+#define INIT_READ_OP_OP_MASK 0xF
+#define INIT_READ_OP_OP_SHIFT 0
+#define INIT_READ_OP_POLL_TYPE_MASK 0xF
+#define INIT_READ_OP_POLL_TYPE_SHIFT 4
+#define INIT_READ_OP_RESERVED_MASK 0x1
+#define INIT_READ_OP_RESERVED_SHIFT 8
+#define INIT_READ_OP_ADDRESS_MASK 0x7FFFFF
+#define INIT_READ_OP_ADDRESS_SHIFT 9
+ __le32 expected_val;
};
/* Init operations union */
union init_op {
- struct init_raw_op raw;
- struct init_write_op write;
- struct init_read_op read;
- struct init_if_mode_op if_mode;
- struct init_if_phase_op if_phase;
- struct init_callback_op callback;
- struct init_delay_op delay;
+ struct init_raw_op raw;
+ struct init_write_op write;
+ struct init_read_op read;
+ struct init_if_mode_op if_mode;
+ struct init_if_phase_op if_phase;
+ struct init_callback_op callback;
+ struct init_delay_op delay;
};
/* Init command operation types */
@@ -4417,79 +4391,6 @@ void qed_fw_overlay_mem_free(struct qed_hwfn *p_hwfn,
(IRO[66].base + ((roce_pf_id) * IRO[66].m1))
#define USTORM_ROCE_CQE_STATS_SIZE (IRO[66].size)
-/* IRO Array */
-static const u32 iro_arr[] = {
- 0x00000000, 0x00000000, 0x00080000,
- 0x00003288, 0x00000088, 0x00880000,
- 0x000058e8, 0x00000020, 0x00200000,
- 0x00000b00, 0x00000008, 0x00040000,
- 0x00000a80, 0x00000008, 0x00040000,
- 0x00000000, 0x00000008, 0x00020000,
- 0x00000080, 0x00000008, 0x00040000,
- 0x00000084, 0x00000008, 0x00020000,
- 0x00005718, 0x00000004, 0x00040000,
- 0x00004dd0, 0x00000000, 0x00780000,
- 0x00003e40, 0x00000000, 0x00780000,
- 0x00004480, 0x00000000, 0x00780000,
- 0x00003210, 0x00000000, 0x00780000,
- 0x00003b50, 0x00000000, 0x00780000,
- 0x00007f58, 0x00000000, 0x00780000,
- 0x00005f58, 0x00000000, 0x00080000,
- 0x00007100, 0x00000000, 0x00080000,
- 0x0000aea0, 0x00000000, 0x00080000,
- 0x00004398, 0x00000000, 0x00080000,
- 0x0000a5a0, 0x00000000, 0x00080000,
- 0x0000bde8, 0x00000000, 0x00080000,
- 0x00000020, 0x00000004, 0x00040000,
- 0x000056c8, 0x00000010, 0x00100000,
- 0x0000c210, 0x00000030, 0x00300000,
- 0x0000b088, 0x00000038, 0x00380000,
- 0x00003d20, 0x00000080, 0x00400000,
- 0x0000bf60, 0x00000000, 0x00040000,
- 0x00004560, 0x00040080, 0x00040000,
- 0x000001f8, 0x00000004, 0x00040000,
- 0x00003d60, 0x00000080, 0x00200000,
- 0x00008960, 0x00000040, 0x00300000,
- 0x0000e840, 0x00000060, 0x00600000,
- 0x00004618, 0x00000080, 0x00380000,
- 0x00010738, 0x000000c0, 0x00c00000,
- 0x000001f8, 0x00000002, 0x00020000,
- 0x0000a2a0, 0x00000000, 0x01080000,
- 0x0000a3a8, 0x00000008, 0x00080000,
- 0x000001c0, 0x00000008, 0x00080000,
- 0x000001f8, 0x00000008, 0x00080000,
- 0x00000ac0, 0x00000008, 0x00080000,
- 0x00002578, 0x00000008, 0x00080000,
- 0x000024f8, 0x00000008, 0x00080000,
- 0x00000280, 0x00000008, 0x00080000,
- 0x00000680, 0x00080018, 0x00080000,
- 0x00000b78, 0x00080018, 0x00020000,
- 0x0000c640, 0x00000050, 0x003c0000,
- 0x00012038, 0x00000018, 0x00100000,
- 0x00011b00, 0x00000040, 0x00180000,
- 0x000095d0, 0x00000050, 0x00200000,
- 0x00008b10, 0x00000040, 0x00280000,
- 0x00011640, 0x00000018, 0x00100000,
- 0x0000c828, 0x00000048, 0x00380000,
- 0x00011710, 0x00000020, 0x00200000,
- 0x00004650, 0x00000080, 0x00100000,
- 0x00003618, 0x00000010, 0x00100000,
- 0x0000a968, 0x00000008, 0x00010000,
- 0x000097a0, 0x00000008, 0x00010000,
- 0x00011990, 0x00000008, 0x00010000,
- 0x0000f018, 0x00000008, 0x00010000,
- 0x00012628, 0x00000008, 0x00010000,
- 0x00011da8, 0x00000008, 0x00010000,
- 0x0000aa78, 0x00000030, 0x00100000,
- 0x0000d768, 0x00000028, 0x00280000,
- 0x00009a58, 0x00000018, 0x00180000,
- 0x00009bd8, 0x00000008, 0x00080000,
- 0x00013a18, 0x00000008, 0x00080000,
- 0x000126e8, 0x00000018, 0x00180000,
- 0x0000e608, 0x00500288, 0x00100000,
- 0x00012970, 0x00000138, 0x00280000,
-};
-
/* Runtime array offsets */
#define DORQ_REG_PF_MAX_ICID_0_RT_OFFSET 0
#define DORQ_REG_PF_MAX_ICID_1_RT_OFFSET 1
@@ -11635,37 +11536,98 @@ typedef u32 offsize_t; /* In DWORDS !!! */
/* PHY configuration */
struct eth_phy_cfg {
- u32 speed;
-#define ETH_SPEED_AUTONEG 0
-#define ETH_SPEED_SMARTLINQ 0x8
-
- u32 pause;
-#define ETH_PAUSE_NONE 0x0
-#define ETH_PAUSE_AUTONEG 0x1
-#define ETH_PAUSE_RX 0x2
-#define ETH_PAUSE_TX 0x4
-
- u32 adv_speed;
- u32 loopback_mode;
-#define ETH_LOOPBACK_NONE (0)
-#define ETH_LOOPBACK_INT_PHY (1)
-#define ETH_LOOPBACK_EXT_PHY (2)
-#define ETH_LOOPBACK_EXT (3)
-#define ETH_LOOPBACK_MAC (4)
-
- u32 eee_cfg;
+ u32 speed;
+#define ETH_SPEED_AUTONEG 0x0
+#define ETH_SPEED_SMARTLINQ 0x8
+
+ u32 pause;
+#define ETH_PAUSE_NONE 0x0
+#define ETH_PAUSE_AUTONEG 0x1
+#define ETH_PAUSE_RX 0x2
+#define ETH_PAUSE_TX 0x4
+
+ u32 adv_speed;
+
+ u32 loopback_mode;
+#define ETH_LOOPBACK_NONE 0x0
+#define ETH_LOOPBACK_INT_PHY 0x1
+#define ETH_LOOPBACK_EXT_PHY 0x2
+#define ETH_LOOPBACK_EXT 0x3
+#define ETH_LOOPBACK_MAC 0x4
+#define ETH_LOOPBACK_CNIG_AH_ONLY_0123 0x5
+#define ETH_LOOPBACK_CNIG_AH_ONLY_2301 0x6
+#define ETH_LOOPBACK_PCS_AH_ONLY 0x7
+#define ETH_LOOPBACK_REVERSE_MAC_AH_ONLY 0x8
+#define ETH_LOOPBACK_INT_PHY_FEA_AH_ONLY 0x9
+
+ u32 eee_cfg;
#define EEE_CFG_EEE_ENABLED BIT(0)
#define EEE_CFG_TX_LPI BIT(1)
#define EEE_CFG_ADV_SPEED_1G BIT(2)
#define EEE_CFG_ADV_SPEED_10G BIT(3)
-#define EEE_TX_TIMER_USEC_MASK (0xfffffff0)
+#define EEE_TX_TIMER_USEC_MASK 0xfffffff0
#define EEE_TX_TIMER_USEC_OFFSET 4
-#define EEE_TX_TIMER_USEC_BALANCED_TIME (0xa00)
-#define EEE_TX_TIMER_USEC_AGGRESSIVE_TIME (0x100)
-#define EEE_TX_TIMER_USEC_LATENCY_TIME (0x6000)
-
- u32 feature_config_flags;
-#define ETH_EEE_MODE_ADV_LPI (1 << 0)
+#define EEE_TX_TIMER_USEC_BALANCED_TIME 0xa00
+#define EEE_TX_TIMER_USEC_AGGRESSIVE_TIME 0x100
+#define EEE_TX_TIMER_USEC_LATENCY_TIME 0x6000
+
+ u32 deprecated;
+
+ u32 fec_mode;
+#define FEC_FORCE_MODE_MASK 0x000000ff
+#define FEC_FORCE_MODE_OFFSET 0
+#define FEC_FORCE_MODE_NONE 0x00
+#define FEC_FORCE_MODE_FIRECODE 0x01
+#define FEC_FORCE_MODE_RS 0x02
+#define FEC_FORCE_MODE_AUTO 0x07
+#define FEC_EXTENDED_MODE_MASK 0xffffff00
+#define FEC_EXTENDED_MODE_OFFSET 8
+#define ETH_EXT_FEC_NONE 0x00000100
+#define ETH_EXT_FEC_10G_NONE 0x00000200
+#define ETH_EXT_FEC_10G_BASE_R 0x00000400
+#define ETH_EXT_FEC_20G_NONE 0x00000800
+#define ETH_EXT_FEC_20G_BASE_R 0x00001000
+#define ETH_EXT_FEC_25G_NONE 0x00002000
+#define ETH_EXT_FEC_25G_BASE_R 0x00004000
+#define ETH_EXT_FEC_25G_RS528 0x00008000
+#define ETH_EXT_FEC_40G_NONE 0x00010000
+#define ETH_EXT_FEC_40G_BASE_R 0x00020000
+#define ETH_EXT_FEC_50G_NONE 0x00040000
+#define ETH_EXT_FEC_50G_BASE_R 0x00080000
+#define ETH_EXT_FEC_50G_RS528 0x00100000
+#define ETH_EXT_FEC_50G_RS544 0x00200000
+#define ETH_EXT_FEC_100G_NONE 0x00400000
+#define ETH_EXT_FEC_100G_BASE_R 0x00800000
+#define ETH_EXT_FEC_100G_RS528 0x01000000
+#define ETH_EXT_FEC_100G_RS544 0x02000000
+
+ u32 extended_speed;
+#define ETH_EXT_SPEED_MASK 0x0000ffff
+#define ETH_EXT_SPEED_OFFSET 0
+#define ETH_EXT_SPEED_AN 0x00000001
+#define ETH_EXT_SPEED_1G 0x00000002
+#define ETH_EXT_SPEED_10G 0x00000004
+#define ETH_EXT_SPEED_20G 0x00000008
+#define ETH_EXT_SPEED_25G 0x00000010
+#define ETH_EXT_SPEED_40G 0x00000020
+#define ETH_EXT_SPEED_50G_BASE_R 0x00000040
+#define ETH_EXT_SPEED_50G_BASE_R2 0x00000080
+#define ETH_EXT_SPEED_100G_BASE_R2 0x00000100
+#define ETH_EXT_SPEED_100G_BASE_R4 0x00000200
+#define ETH_EXT_SPEED_100G_BASE_P4 0x00000400
+#define ETH_EXT_ADV_SPEED_MASK 0xffff0000
+#define ETH_EXT_ADV_SPEED_OFFSET 16
+#define ETH_EXT_ADV_SPEED_RESERVED 0x00010000
+#define ETH_EXT_ADV_SPEED_1G 0x00020000
+#define ETH_EXT_ADV_SPEED_10G 0x00040000
+#define ETH_EXT_ADV_SPEED_20G 0x00080000
+#define ETH_EXT_ADV_SPEED_25G 0x00100000
+#define ETH_EXT_ADV_SPEED_40G 0x00200000
+#define ETH_EXT_ADV_SPEED_50G_BASE_R 0x00400000
+#define ETH_EXT_ADV_SPEED_50G_BASE_R2 0x00800000
+#define ETH_EXT_ADV_SPEED_100G_BASE_R2 0x01000000
+#define ETH_EXT_ADV_SPEED_100G_BASE_R4 0x02000000
+#define ETH_EXT_ADV_SPEED_100G_BASE_P4 0x04000000
};
struct port_mf_cfg {
@@ -11994,41 +11956,36 @@ struct public_path {
};
struct public_port {
- u32 validity_map;
-
- u32 link_status;
-#define LINK_STATUS_LINK_UP 0x00000001
-#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001e
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (1 << 1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (2 << 1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10G (3 << 1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_20G (4 << 1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_40G (5 << 1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_50G (6 << 1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100G (7 << 1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_25G (8 << 1)
-
-#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020
-
-#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040
-#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080
-
+ u32 validity_map;
+
+ u32 link_status;
+#define LINK_STATUS_LINK_UP 0x00000001
+#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001e
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (1 << 1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (2 << 1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10G (3 << 1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_20G (4 << 1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_40G (5 << 1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_50G (6 << 1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100G (7 << 1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_25G (8 << 1)
+#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020
+#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040
+#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080
#define LINK_STATUS_PFC_ENABLED 0x00000100
-#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200
-#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400
+#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200
+#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400
#define LINK_STATUS_LINK_PARTNER_10G_CAPABLE 0x00000800
#define LINK_STATUS_LINK_PARTNER_20G_CAPABLE 0x00001000
#define LINK_STATUS_LINK_PARTNER_40G_CAPABLE 0x00002000
#define LINK_STATUS_LINK_PARTNER_50G_CAPABLE 0x00004000
#define LINK_STATUS_LINK_PARTNER_100G_CAPABLE 0x00008000
#define LINK_STATUS_LINK_PARTNER_25G_CAPABLE 0x00010000
-
-#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000
+#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000c0000
#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0 << 18)
#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1 << 18)
#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2 << 18)
#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3 << 18)
-
#define LINK_STATUS_SFP_TX_FAULT 0x00100000
#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00200000
#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00400000
@@ -12037,6 +11994,11 @@ struct public_port {
#define LINK_STATUS_MAC_REMOTE_FAULT 0x02000000
#define LINK_STATUS_UNSUPPORTED_SPD_REQ 0x04000000
+#define LINK_STATUS_FEC_MODE_MASK 0x38000000
+#define LINK_STATUS_FEC_MODE_NONE (0 << 27)
+#define LINK_STATUS_FEC_MODE_FIRECODE_CL74 (1 << 27)
+#define LINK_STATUS_FEC_MODE_RS_CL91 (2 << 27)
+
u32 link_status1;
u32 ext_phy_fw_version;
u32 drv_phy_cfg_addr;
@@ -12072,59 +12034,65 @@ struct public_port {
struct dcbx_mib operational_dcbx_mib;
u32 reserved[2];
- u32 transceiver_data;
-#define ETH_TRANSCEIVER_STATE_MASK 0x000000FF
-#define ETH_TRANSCEIVER_STATE_SHIFT 0x00000000
-#define ETH_TRANSCEIVER_STATE_OFFSET 0x00000000
-#define ETH_TRANSCEIVER_STATE_UNPLUGGED 0x00000000
-#define ETH_TRANSCEIVER_STATE_PRESENT 0x00000001
-#define ETH_TRANSCEIVER_STATE_VALID 0x00000003
-#define ETH_TRANSCEIVER_STATE_UPDATING 0x00000008
-#define ETH_TRANSCEIVER_TYPE_MASK 0x0000FF00
-#define ETH_TRANSCEIVER_TYPE_OFFSET 0x8
-#define ETH_TRANSCEIVER_TYPE_NONE 0x00
-#define ETH_TRANSCEIVER_TYPE_UNKNOWN 0xFF
-#define ETH_TRANSCEIVER_TYPE_1G_PCC 0x01
-#define ETH_TRANSCEIVER_TYPE_1G_ACC 0x02
-#define ETH_TRANSCEIVER_TYPE_1G_LX 0x03
-#define ETH_TRANSCEIVER_TYPE_1G_SX 0x04
-#define ETH_TRANSCEIVER_TYPE_10G_SR 0x05
-#define ETH_TRANSCEIVER_TYPE_10G_LR 0x06
-#define ETH_TRANSCEIVER_TYPE_10G_LRM 0x07
-#define ETH_TRANSCEIVER_TYPE_10G_ER 0x08
-#define ETH_TRANSCEIVER_TYPE_10G_PCC 0x09
-#define ETH_TRANSCEIVER_TYPE_10G_ACC 0x0a
-#define ETH_TRANSCEIVER_TYPE_XLPPI 0x0b
-#define ETH_TRANSCEIVER_TYPE_40G_LR4 0x0c
-#define ETH_TRANSCEIVER_TYPE_40G_SR4 0x0d
-#define ETH_TRANSCEIVER_TYPE_40G_CR4 0x0e
-#define ETH_TRANSCEIVER_TYPE_100G_AOC 0x0f
-#define ETH_TRANSCEIVER_TYPE_100G_SR4 0x10
-#define ETH_TRANSCEIVER_TYPE_100G_LR4 0x11
-#define ETH_TRANSCEIVER_TYPE_100G_ER4 0x12
-#define ETH_TRANSCEIVER_TYPE_100G_ACC 0x13
-#define ETH_TRANSCEIVER_TYPE_100G_CR4 0x14
-#define ETH_TRANSCEIVER_TYPE_4x10G_SR 0x15
-#define ETH_TRANSCEIVER_TYPE_25G_CA_N 0x16
-#define ETH_TRANSCEIVER_TYPE_25G_ACC_S 0x17
-#define ETH_TRANSCEIVER_TYPE_25G_CA_S 0x18
-#define ETH_TRANSCEIVER_TYPE_25G_ACC_M 0x19
-#define ETH_TRANSCEIVER_TYPE_25G_CA_L 0x1a
-#define ETH_TRANSCEIVER_TYPE_25G_ACC_L 0x1b
-#define ETH_TRANSCEIVER_TYPE_25G_SR 0x1c
-#define ETH_TRANSCEIVER_TYPE_25G_LR 0x1d
-#define ETH_TRANSCEIVER_TYPE_25G_AOC 0x1e
-#define ETH_TRANSCEIVER_TYPE_4x10G 0x1f
-#define ETH_TRANSCEIVER_TYPE_4x25G_CR 0x20
-#define ETH_TRANSCEIVER_TYPE_1000BASET 0x21
-#define ETH_TRANSCEIVER_TYPE_10G_BASET 0x22
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR 0x30
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR 0x31
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR 0x32
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR 0x33
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR 0x34
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR 0x35
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_AOC 0x36
+
+ u32 transceiver_data;
+#define ETH_TRANSCEIVER_STATE_MASK 0x000000ff
+#define ETH_TRANSCEIVER_STATE_SHIFT 0x00000000
+#define ETH_TRANSCEIVER_STATE_OFFSET 0x00000000
+#define ETH_TRANSCEIVER_STATE_UNPLUGGED 0x00000000
+#define ETH_TRANSCEIVER_STATE_PRESENT 0x00000001
+#define ETH_TRANSCEIVER_STATE_VALID 0x00000003
+#define ETH_TRANSCEIVER_STATE_UPDATING 0x00000008
+#define ETH_TRANSCEIVER_TYPE_MASK 0x0000ff00
+#define ETH_TRANSCEIVER_TYPE_OFFSET 0x8
+#define ETH_TRANSCEIVER_TYPE_NONE 0x00
+#define ETH_TRANSCEIVER_TYPE_UNKNOWN 0xff
+#define ETH_TRANSCEIVER_TYPE_1G_PCC 0x01
+#define ETH_TRANSCEIVER_TYPE_1G_ACC 0x02
+#define ETH_TRANSCEIVER_TYPE_1G_LX 0x03
+#define ETH_TRANSCEIVER_TYPE_1G_SX 0x04
+#define ETH_TRANSCEIVER_TYPE_10G_SR 0x05
+#define ETH_TRANSCEIVER_TYPE_10G_LR 0x06
+#define ETH_TRANSCEIVER_TYPE_10G_LRM 0x07
+#define ETH_TRANSCEIVER_TYPE_10G_ER 0x08
+#define ETH_TRANSCEIVER_TYPE_10G_PCC 0x09
+#define ETH_TRANSCEIVER_TYPE_10G_ACC 0x0a
+#define ETH_TRANSCEIVER_TYPE_XLPPI 0x0b
+#define ETH_TRANSCEIVER_TYPE_40G_LR4 0x0c
+#define ETH_TRANSCEIVER_TYPE_40G_SR4 0x0d
+#define ETH_TRANSCEIVER_TYPE_40G_CR4 0x0e
+#define ETH_TRANSCEIVER_TYPE_100G_AOC 0x0f
+#define ETH_TRANSCEIVER_TYPE_100G_SR4 0x10
+#define ETH_TRANSCEIVER_TYPE_100G_LR4 0x11
+#define ETH_TRANSCEIVER_TYPE_100G_ER4 0x12
+#define ETH_TRANSCEIVER_TYPE_100G_ACC 0x13
+#define ETH_TRANSCEIVER_TYPE_100G_CR4 0x14
+#define ETH_TRANSCEIVER_TYPE_4x10G_SR 0x15
+#define ETH_TRANSCEIVER_TYPE_25G_CA_N 0x16
+#define ETH_TRANSCEIVER_TYPE_25G_ACC_S 0x17
+#define ETH_TRANSCEIVER_TYPE_25G_CA_S 0x18
+#define ETH_TRANSCEIVER_TYPE_25G_ACC_M 0x19
+#define ETH_TRANSCEIVER_TYPE_25G_CA_L 0x1a
+#define ETH_TRANSCEIVER_TYPE_25G_ACC_L 0x1b
+#define ETH_TRANSCEIVER_TYPE_25G_SR 0x1c
+#define ETH_TRANSCEIVER_TYPE_25G_LR 0x1d
+#define ETH_TRANSCEIVER_TYPE_25G_AOC 0x1e
+#define ETH_TRANSCEIVER_TYPE_4x10G 0x1f
+#define ETH_TRANSCEIVER_TYPE_4x25G_CR 0x20
+#define ETH_TRANSCEIVER_TYPE_1000BASET 0x21
+#define ETH_TRANSCEIVER_TYPE_10G_BASET 0x22
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR 0x30
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR 0x31
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR 0x32
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR 0x33
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR 0x34
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR 0x35
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_AOC 0x36
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR 0x37
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR 0x38
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR 0x39
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR 0x3a
+
u32 wol_info;
u32 wol_pkt_len;
u32 wol_pkt_details;
@@ -12617,66 +12585,68 @@ struct public_drv_mb {
#define DRV_MB_PARAM_SET_LED_MODE_ON 0x1
#define DRV_MB_PARAM_SET_LED_MODE_OFF 0x2
-#define DRV_MB_PARAM_TRANSCEIVER_PORT_OFFSET 0
-#define DRV_MB_PARAM_TRANSCEIVER_PORT_MASK 0x00000003
-#define DRV_MB_PARAM_TRANSCEIVER_SIZE_OFFSET 2
-#define DRV_MB_PARAM_TRANSCEIVER_SIZE_MASK 0x000000FC
-#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_OFFSET 8
-#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK 0x0000FF00
-#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_OFFSET 16
-#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_MASK 0xFFFF0000
+#define DRV_MB_PARAM_TRANSCEIVER_PORT_OFFSET 0
+#define DRV_MB_PARAM_TRANSCEIVER_PORT_MASK 0x00000003
+#define DRV_MB_PARAM_TRANSCEIVER_SIZE_OFFSET 2
+#define DRV_MB_PARAM_TRANSCEIVER_SIZE_MASK 0x000000fc
+#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_OFFSET 8
+#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK 0x0000ff00
+#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_OFFSET 16
+#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_MASK 0xffff0000
/* Resource Allocation params - Driver version support */
-#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xFFFF0000
-#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16
-#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_MASK 0x0000FFFF
-#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_SHIFT 0
-
-#define DRV_MB_PARAM_BIST_REGISTER_TEST 1
-#define DRV_MB_PARAM_BIST_CLOCK_TEST 2
-#define DRV_MB_PARAM_BIST_NVM_TEST_NUM_IMAGES 3
-#define DRV_MB_PARAM_BIST_NVM_TEST_IMAGE_BY_INDEX 4
-
-#define DRV_MB_PARAM_BIST_RC_UNKNOWN 0
-#define DRV_MB_PARAM_BIST_RC_PASSED 1
-#define DRV_MB_PARAM_BIST_RC_FAILED 2
-#define DRV_MB_PARAM_BIST_RC_INVALID_PARAMETER 3
-
-#define DRV_MB_PARAM_BIST_TEST_INDEX_SHIFT 0
-#define DRV_MB_PARAM_BIST_TEST_INDEX_MASK 0x000000FF
-#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_SHIFT 8
-#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_MASK 0x0000FF00
-
-#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_MASK 0x0000FFFF
-#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_OFFSET 0
-#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE 0x00000002
-#define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK 0x00010000
+#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xffff0000
+#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16
+#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_MASK 0x0000ffff
+#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_SHIFT 0
+
+#define DRV_MB_PARAM_BIST_REGISTER_TEST 1
+#define DRV_MB_PARAM_BIST_CLOCK_TEST 2
+#define DRV_MB_PARAM_BIST_NVM_TEST_NUM_IMAGES 3
+#define DRV_MB_PARAM_BIST_NVM_TEST_IMAGE_BY_INDEX 4
+
+#define DRV_MB_PARAM_BIST_RC_UNKNOWN 0
+#define DRV_MB_PARAM_BIST_RC_PASSED 1
+#define DRV_MB_PARAM_BIST_RC_FAILED 2
+#define DRV_MB_PARAM_BIST_RC_INVALID_PARAMETER 3
+
+#define DRV_MB_PARAM_BIST_TEST_INDEX_SHIFT 0
+#define DRV_MB_PARAM_BIST_TEST_INDEX_MASK 0x000000ff
+#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_SHIFT 8
+#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_MASK 0x0000ff00
+
+#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_MASK 0x0000ffff
+#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_OFFSET 0
+#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE 0x00000002
+#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_FEC_CONTROL 0x00000004
+#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EXT_SPEED_FEC_CONTROL 0x00000008
+#define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK 0x00010000
/* DRV_MSG_CODE_DEBUG_DATA_SEND parameters */
-#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_OFFSET 0
-#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_MASK 0xFF
+#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_OFFSET 0
+#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_MASK 0xff
/* Driver attributes params */
-#define DRV_MB_PARAM_ATTRIBUTE_KEY_OFFSET 0
-#define DRV_MB_PARAM_ATTRIBUTE_KEY_MASK 0x00FFFFFF
-#define DRV_MB_PARAM_ATTRIBUTE_CMD_OFFSET 24
-#define DRV_MB_PARAM_ATTRIBUTE_CMD_MASK 0xFF000000
-
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_OFFSET 0
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_SHIFT 0
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_MASK 0x0000FFFF
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_SHIFT 16
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_MASK 0x00010000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_SHIFT 17
-#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_MASK 0x00020000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_SHIFT 18
-#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_MASK 0x00040000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_SHIFT 19
-#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_MASK 0x00080000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_SHIFT 20
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_MASK 0x00100000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_SHIFT 24
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_MASK 0x0f000000
+#define DRV_MB_PARAM_ATTRIBUTE_KEY_OFFSET 0
+#define DRV_MB_PARAM_ATTRIBUTE_KEY_MASK 0x00ffffff
+#define DRV_MB_PARAM_ATTRIBUTE_CMD_OFFSET 24
+#define DRV_MB_PARAM_ATTRIBUTE_CMD_MASK 0xff000000
+
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_OFFSET 0
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_SHIFT 0
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_MASK 0x0000ffff
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_SHIFT 16
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_MASK 0x00010000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_SHIFT 17
+#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_MASK 0x00020000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_SHIFT 18
+#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_MASK 0x00040000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_SHIFT 19
+#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_MASK 0x00080000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_SHIFT 20
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_MASK 0x00100000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_SHIFT 24
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_MASK 0x0f000000
u32 fw_mb_header;
#define FW_MSG_CODE_MASK 0xffff0000
@@ -12723,55 +12693,57 @@ struct public_drv_mb {
#define FW_MSG_CODE_MDUMP_INVALID_CMD 0x00030000
- u32 fw_mb_param;
-#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xFFFF0000
-#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16
-#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_MASK 0x0000FFFF
-#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_SHIFT 0
-
- /* get pf rdma protocol command responce */
-#define FW_MB_PARAM_GET_PF_RDMA_NONE 0x0
-#define FW_MB_PARAM_GET_PF_RDMA_ROCE 0x1
-#define FW_MB_PARAM_GET_PF_RDMA_IWARP 0x2
-#define FW_MB_PARAM_GET_PF_RDMA_BOTH 0x3
-
-/* get MFW feature support response */
-#define FW_MB_PARAM_FEATURE_SUPPORT_SMARTLINQ 0x00000001
-#define FW_MB_PARAM_FEATURE_SUPPORT_EEE 0x00000002
-#define FW_MB_PARAM_FEATURE_SUPPORT_VLINK 0x00010000
-
-#define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR (1 << 0)
-
-#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_MASK 0x00000001
-#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_SHIFT 0
-#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_MASK 0x00000002
-#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_SHIFT 1
-#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_MASK 0x00000004
-#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_SHIFT 2
-#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_MASK 0x00000008
-#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_SHIFT 3
-
-#define FW_MB_PARAM_PPFID_BITMAP_MASK 0xFF
-#define FW_MB_PARAM_PPFID_BITMAP_SHIFT 0
-
- u32 drv_pulse_mb;
-#define DRV_PULSE_SEQ_MASK 0x00007fff
-#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000
-#define DRV_PULSE_ALWAYS_ALIVE 0x00008000
-
- u32 mcp_pulse_mb;
-#define MCP_PULSE_SEQ_MASK 0x00007fff
-#define MCP_PULSE_ALWAYS_ALIVE 0x00008000
-#define MCP_EVENT_MASK 0xffff0000
-#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000
-
- union drv_union_data union_data;
-};
-
-#define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_MASK 0x00ffffff
-#define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_SHIFT 0
-#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_MASK 0xff000000
-#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_SHIFT 24
+ u32 fw_mb_param;
+#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xffff0000
+#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16
+#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_MASK 0x0000ffff
+#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_SHIFT 0
+
+ /* Get PF RDMA protocol command response */
+#define FW_MB_PARAM_GET_PF_RDMA_NONE 0x0
+#define FW_MB_PARAM_GET_PF_RDMA_ROCE 0x1
+#define FW_MB_PARAM_GET_PF_RDMA_IWARP 0x2
+#define FW_MB_PARAM_GET_PF_RDMA_BOTH 0x3
+
+ /* Get MFW feature support response */
+#define FW_MB_PARAM_FEATURE_SUPPORT_SMARTLINQ BIT(0)
+#define FW_MB_PARAM_FEATURE_SUPPORT_EEE BIT(1)
+#define FW_MB_PARAM_FEATURE_SUPPORT_FEC_CONTROL BIT(5)
+#define FW_MB_PARAM_FEATURE_SUPPORT_EXT_SPEED_FEC_CONTROL BIT(6)
+#define FW_MB_PARAM_FEATURE_SUPPORT_VLINK BIT(16)
+
+#define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR BIT(0)
+
+#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_MASK 0x00000001
+#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_SHIFT 0
+#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_MASK 0x00000002
+#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_SHIFT 1
+#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_MASK 0x00000004
+#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_SHIFT 2
+#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_MASK 0x00000008
+#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_SHIFT 3
+
+#define FW_MB_PARAM_PPFID_BITMAP_MASK 0xff
+#define FW_MB_PARAM_PPFID_BITMAP_SHIFT 0
+
+ u32 drv_pulse_mb;
+#define DRV_PULSE_SEQ_MASK 0x00007fff
+#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000
+#define DRV_PULSE_ALWAYS_ALIVE 0x00008000
+
+ u32 mcp_pulse_mb;
+#define MCP_PULSE_SEQ_MASK 0x00007fff
+#define MCP_PULSE_ALWAYS_ALIVE 0x00008000
+#define MCP_EVENT_MASK 0xffff0000
+#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000
+
+ union drv_union_data union_data;
+};
+
+#define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_MASK 0x00ffffff
+#define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_SHIFT 0
+#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_MASK 0xff000000
+#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_SHIFT 24
enum MFW_DRV_MSG_TYPE {
MFW_DRV_MSG_LINK_CHANGE,
@@ -13058,122 +13030,138 @@ enum tlvs {
};
struct nvm_cfg_mac_address {
- u32 mac_addr_hi;
-#define NVM_CFG_MAC_ADDRESS_HI_MASK 0x0000FFFF
-#define NVM_CFG_MAC_ADDRESS_HI_OFFSET 0
- u32 mac_addr_lo;
+ u32 mac_addr_hi;
+#define NVM_CFG_MAC_ADDRESS_HI_MASK 0x0000ffff
+#define NVM_CFG_MAC_ADDRESS_HI_OFFSET 0
+
+ u32 mac_addr_lo;
};
struct nvm_cfg1_glob {
- u32 generic_cont0;
-#define NVM_CFG1_GLOB_MF_MODE_MASK 0x00000FF0
-#define NVM_CFG1_GLOB_MF_MODE_OFFSET 4
-#define NVM_CFG1_GLOB_MF_MODE_MF_ALLOWED 0x0
-#define NVM_CFG1_GLOB_MF_MODE_DEFAULT 0x1
-#define NVM_CFG1_GLOB_MF_MODE_SPIO4 0x2
-#define NVM_CFG1_GLOB_MF_MODE_NPAR1_0 0x3
-#define NVM_CFG1_GLOB_MF_MODE_NPAR1_5 0x4
-#define NVM_CFG1_GLOB_MF_MODE_NPAR2_0 0x5
-#define NVM_CFG1_GLOB_MF_MODE_BD 0x6
-#define NVM_CFG1_GLOB_MF_MODE_UFP 0x7
- u32 engineering_change[3];
- u32 manufacturing_id;
- u32 serial_number[4];
- u32 pcie_cfg;
- u32 mgmt_traffic;
- u32 core_cfg;
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_MASK 0x000000FF
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_OFFSET 0
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_2X40G 0x0
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X50G 0x1
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_1X100G 0x2
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X10G_F 0x3
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X10G_E 0x4
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X20G 0x5
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X40G 0xB
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X25G 0xC
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G 0xD
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G 0xE
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G 0xF
-
- u32 e_lane_cfg1;
- u32 e_lane_cfg2;
- u32 f_lane_cfg1;
- u32 f_lane_cfg2;
- u32 mps10_preemphasis;
- u32 mps10_driver_current;
- u32 mps25_preemphasis;
- u32 mps25_driver_current;
- u32 pci_id;
- u32 pci_subsys_id;
- u32 bar;
- u32 mps10_txfir_main;
- u32 mps10_txfir_post;
- u32 mps25_txfir_main;
- u32 mps25_txfir_post;
- u32 manufacture_ver;
- u32 manufacture_time;
- u32 led_global_settings;
- u32 generic_cont1;
- u32 mbi_version;
-#define NVM_CFG1_GLOB_MBI_VERSION_0_MASK 0x000000FF
-#define NVM_CFG1_GLOB_MBI_VERSION_0_OFFSET 0
-#define NVM_CFG1_GLOB_MBI_VERSION_1_MASK 0x0000FF00
-#define NVM_CFG1_GLOB_MBI_VERSION_1_OFFSET 8
-#define NVM_CFG1_GLOB_MBI_VERSION_2_MASK 0x00FF0000
-#define NVM_CFG1_GLOB_MBI_VERSION_2_OFFSET 16
- u32 mbi_date;
- u32 misc_sig;
- u32 device_capabilities;
-#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ETHERNET 0x1
-#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_FCOE 0x2
-#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ISCSI 0x4
-#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ROCE 0x8
- u32 power_dissipated;
- u32 power_consumed;
- u32 efi_version;
- u32 multi_network_modes_capability;
- u32 reserved[41];
+ u32 generic_cont0;
+#define NVM_CFG1_GLOB_MF_MODE_MASK 0x00000ff0
+#define NVM_CFG1_GLOB_MF_MODE_OFFSET 4
+#define NVM_CFG1_GLOB_MF_MODE_MF_ALLOWED 0x0
+#define NVM_CFG1_GLOB_MF_MODE_DEFAULT 0x1
+#define NVM_CFG1_GLOB_MF_MODE_SPIO4 0x2
+#define NVM_CFG1_GLOB_MF_MODE_NPAR1_0 0x3
+#define NVM_CFG1_GLOB_MF_MODE_NPAR1_5 0x4
+#define NVM_CFG1_GLOB_MF_MODE_NPAR2_0 0x5
+#define NVM_CFG1_GLOB_MF_MODE_BD 0x6
+#define NVM_CFG1_GLOB_MF_MODE_UFP 0x7
+
+ u32 engineering_change[3];
+ u32 manufacturing_id;
+ u32 serial_number[4];
+ u32 pcie_cfg;
+ u32 mgmt_traffic;
+
+ u32 core_cfg;
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_MASK 0x000000ff
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_OFFSET 0
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_2X40G 0x0
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X50G 0x1
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_1X100G 0x2
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X10G_F 0x3
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X10G_E 0x4
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X20G 0x5
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X40G 0xb
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X25G 0xc
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G 0xd
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G 0xe
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G 0xf
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1 0x11
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1 0x12
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2 0x13
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2 0x14
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4 0x15
+
+ u32 e_lane_cfg1;
+ u32 e_lane_cfg2;
+ u32 f_lane_cfg1;
+ u32 f_lane_cfg2;
+ u32 mps10_preemphasis;
+ u32 mps10_driver_current;
+ u32 mps25_preemphasis;
+ u32 mps25_driver_current;
+ u32 pci_id;
+ u32 pci_subsys_id;
+ u32 bar;
+ u32 mps10_txfir_main;
+ u32 mps10_txfir_post;
+ u32 mps25_txfir_main;
+ u32 mps25_txfir_post;
+ u32 manufacture_ver;
+ u32 manufacture_time;
+ u32 led_global_settings;
+ u32 generic_cont1;
+
+ u32 mbi_version;
+#define NVM_CFG1_GLOB_MBI_VERSION_0_MASK 0x000000ff
+#define NVM_CFG1_GLOB_MBI_VERSION_0_OFFSET 0
+#define NVM_CFG1_GLOB_MBI_VERSION_1_MASK 0x0000ff00
+#define NVM_CFG1_GLOB_MBI_VERSION_1_OFFSET 8
+#define NVM_CFG1_GLOB_MBI_VERSION_2_MASK 0x00ff0000
+#define NVM_CFG1_GLOB_MBI_VERSION_2_OFFSET 16
+
+ u32 mbi_date;
+ u32 misc_sig;
+
+ u32 device_capabilities;
+#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ETHERNET 0x1
+#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_FCOE 0x2
+#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ISCSI 0x4
+#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ROCE 0x8
+
+ u32 power_dissipated;
+ u32 power_consumed;
+ u32 efi_version;
+ u32 multi_net_modes_cap;
+ u32 reserved[41];
};
struct nvm_cfg1_path {
- u32 reserved[30];
+ u32 reserved[30];
};
struct nvm_cfg1_port {
- u32 reserved__m_relocated_to_option_123;
- u32 reserved__m_relocated_to_option_124;
- u32 generic_cont0;
-#define NVM_CFG1_PORT_DCBX_MODE_MASK 0x000F0000
+ u32 rel_to_opt123;
+ u32 rel_to_opt124;
+
+ u32 generic_cont0;
+#define NVM_CFG1_PORT_DCBX_MODE_MASK 0x000f0000
#define NVM_CFG1_PORT_DCBX_MODE_OFFSET 16
#define NVM_CFG1_PORT_DCBX_MODE_DISABLED 0x0
#define NVM_CFG1_PORT_DCBX_MODE_IEEE 0x1
#define NVM_CFG1_PORT_DCBX_MODE_CEE 0x2
#define NVM_CFG1_PORT_DCBX_MODE_DYNAMIC 0x3
-#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_MASK 0x00F00000
+#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_MASK 0x00f00000
#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_OFFSET 20
#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_ETHERNET 0x1
#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_FCOE 0x2
#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_ISCSI 0x4
- u32 pcie_cfg;
- u32 features;
- u32 speed_cap_mask;
-#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_MASK 0x0000FFFF
+
+ u32 pcie_cfg;
+ u32 features;
+
+ u32 speed_cap_mask;
+#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_MASK 0x0000ffff
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_OFFSET 0
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G 0x1
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G 0x2
-#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G 0x4
+#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G 0x4
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G 0x8
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G 0x10
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G 0x20
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G 0x40
- u32 link_settings;
-#define NVM_CFG1_PORT_DRV_LINK_SPEED_MASK 0x0000000F
+
+ u32 link_settings;
+#define NVM_CFG1_PORT_DRV_LINK_SPEED_MASK 0x0000000f
#define NVM_CFG1_PORT_DRV_LINK_SPEED_OFFSET 0
#define NVM_CFG1_PORT_DRV_LINK_SPEED_AUTONEG 0x0
#define NVM_CFG1_PORT_DRV_LINK_SPEED_1G 0x1
#define NVM_CFG1_PORT_DRV_LINK_SPEED_10G 0x2
-#define NVM_CFG1_PORT_DRV_LINK_SPEED_20G 0x3
+#define NVM_CFG1_PORT_DRV_LINK_SPEED_20G 0x3
#define NVM_CFG1_PORT_DRV_LINK_SPEED_25G 0x4
#define NVM_CFG1_PORT_DRV_LINK_SPEED_40G 0x5
#define NVM_CFG1_PORT_DRV_LINK_SPEED_50G 0x6
@@ -13184,49 +13172,92 @@ struct nvm_cfg1_port {
#define NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG 0x1
#define NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX 0x2
#define NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX 0x4
- u32 phy_cfg;
- u32 mgmt_traffic;
+#define NVM_CFG1_PORT_FEC_FORCE_MODE_MASK 0x000e0000
+#define NVM_CFG1_PORT_FEC_FORCE_MODE_OFFSET 17
+#define NVM_CFG1_PORT_FEC_FORCE_MODE_NONE 0x0
+#define NVM_CFG1_PORT_FEC_FORCE_MODE_FIRECODE 0x1
+#define NVM_CFG1_PORT_FEC_FORCE_MODE_RS 0x2
+#define NVM_CFG1_PORT_FEC_FORCE_MODE_AUTO 0x7
+
+ u32 phy_cfg;
+ u32 mgmt_traffic;
- u32 ext_phy;
+ u32 ext_phy;
/* EEE power saving mode */
-#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_MASK 0x00FF0000
+#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_MASK 0x00ff0000
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_OFFSET 16
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_DISABLED 0x0
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_BALANCED 0x1
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_AGGRESSIVE 0x2
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_LOW_LATENCY 0x3
- u32 mba_cfg1;
- u32 mba_cfg2;
- u32 vf_cfg;
- struct nvm_cfg_mac_address lldp_mac_address;
- u32 led_port_settings;
- u32 transceiver_00;
- u32 device_ids;
- u32 board_cfg;
-#define NVM_CFG1_PORT_PORT_TYPE_MASK 0x000000FF
-#define NVM_CFG1_PORT_PORT_TYPE_OFFSET 0
-#define NVM_CFG1_PORT_PORT_TYPE_UNDEFINED 0x0
-#define NVM_CFG1_PORT_PORT_TYPE_MODULE 0x1
-#define NVM_CFG1_PORT_PORT_TYPE_BACKPLANE 0x2
-#define NVM_CFG1_PORT_PORT_TYPE_EXT_PHY 0x3
-#define NVM_CFG1_PORT_PORT_TYPE_MODULE_SLAVE 0x4
- u32 mnm_10g_cap;
- u32 mnm_10g_ctrl;
- u32 mnm_10g_misc;
- u32 mnm_25g_cap;
- u32 mnm_25g_ctrl;
- u32 mnm_25g_misc;
- u32 mnm_40g_cap;
- u32 mnm_40g_ctrl;
- u32 mnm_40g_misc;
- u32 mnm_50g_cap;
- u32 mnm_50g_ctrl;
- u32 mnm_50g_misc;
- u32 mnm_100g_cap;
- u32 mnm_100g_ctrl;
- u32 mnm_100g_misc;
- u32 reserved[116];
+ u32 mba_cfg1;
+ u32 mba_cfg2;
+ u32 vf_cfg;
+ struct nvm_cfg_mac_address lldp_mac_address;
+ u32 led_port_settings;
+ u32 transceiver_00;
+ u32 device_ids;
+
+ u32 board_cfg;
+#define NVM_CFG1_PORT_PORT_TYPE_MASK 0x000000ff
+#define NVM_CFG1_PORT_PORT_TYPE_OFFSET 0
+#define NVM_CFG1_PORT_PORT_TYPE_UNDEFINED 0x0
+#define NVM_CFG1_PORT_PORT_TYPE_MODULE 0x1
+#define NVM_CFG1_PORT_PORT_TYPE_BACKPLANE 0x2
+#define NVM_CFG1_PORT_PORT_TYPE_EXT_PHY 0x3
+#define NVM_CFG1_PORT_PORT_TYPE_MODULE_SLAVE 0x4
+
+ u32 mnm_10g_cap;
+ u32 mnm_10g_ctrl;
+ u32 mnm_10g_misc;
+ u32 mnm_25g_cap;
+ u32 mnm_25g_ctrl;
+ u32 mnm_25g_misc;
+ u32 mnm_40g_cap;
+ u32 mnm_40g_ctrl;
+ u32 mnm_40g_misc;
+ u32 mnm_50g_cap;
+ u32 mnm_50g_ctrl;
+ u32 mnm_50g_misc;
+ u32 mnm_100g_cap;
+ u32 mnm_100g_ctrl;
+ u32 mnm_100g_misc;
+
+ u32 temperature;
+ u32 ext_phy_cfg1;
+
+ u32 extended_speed;
+#define NVM_CFG1_PORT_EXTENDED_SPEED_MASK 0x0000ffff
+#define NVM_CFG1_PORT_EXTENDED_SPEED_OFFSET 0
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_AN 0x1
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_1G 0x2
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_10G 0x4
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_20G 0x8
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_25G 0x10
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_40G 0x20
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_50G_R 0x40
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_50G_R2 0x80
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_R2 0x100
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_R4 0x200
+#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_P4 0x400
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_MASK 0xffff0000
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_OFFSET 16
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_RESERVED 0x1
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_1G 0x2
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_10G 0x4
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_20G 0x8
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_25G 0x10
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_40G 0x20
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_50G_R 0x40
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_50G_R2 0x80
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_R2 0x100
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_R4 0x200
+#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_P4 0x400
+
+ u32 extended_fec_mode;
+
+ u32 reserved[112];
};
struct nvm_cfg1_func {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hw.c b/drivers/net/ethernet/qlogic/qed/qed_hw.c
index 5fa251489536..554f30b0cfd5 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hw.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_hw.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -838,9 +812,8 @@ int qed_dmae_host2host(struct qed_hwfn *p_hwfn,
return rc;
}
-void qed_hw_err_notify(struct qed_hwfn *p_hwfn,
- struct qed_ptt *p_ptt,
- enum qed_hw_err_type err_type, char *fmt, ...)
+void qed_hw_err_notify(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+ enum qed_hw_err_type err_type, const char *fmt, ...)
{
char buf[QED_HW_ERR_MAX_STR_SIZE];
va_list vl;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hw.h b/drivers/net/ethernet/qlogic/qed/qed_hw.h
index f5b109b04b66..2734f49956f7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hw.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hw.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_HW_H
@@ -327,7 +301,8 @@ int qed_dmae_sanity(struct qed_hwfn *p_hwfn,
* @param fmt - debug data buffer to send to the MFW
* @param ... - buffer format args
*/
-void qed_hw_err_notify(struct qed_hwfn *p_hwfn,
- struct qed_ptt *p_ptt,
- enum qed_hw_err_type err_type, char *fmt, ...);
+void __printf(4, 5) __cold qed_hw_err_notify(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ enum qed_hw_err_type err_type,
+ const char *fmt, ...);
#endif
diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
index 2f1049b0b93a..ea888a2c6ddb 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -182,23 +156,25 @@ static u16 task_region_offsets[1][NUM_OF_CONNECTION_TYPES_E4] = {
cmd ## _ ## field, \
value)
-#define QM_INIT_TX_PQ_MAP(p_hwfn, map, chip, pq_id, vp_pq_id, rl_valid, rl_id, \
- ext_voq, wrr) \
- do { \
- typeof(map) __map; \
- memset(&__map, 0, sizeof(__map)); \
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _PQ_VALID, 1); \
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _RL_VALID, \
- rl_valid ? 1 : 0);\
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _VP_PQ_ID, \
- vp_pq_id); \
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _RL_ID, rl_id); \
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _VOQ, ext_voq); \
- SET_FIELD(__map.reg, \
- QM_RF_PQ_MAP_ ## chip ## _WRR_WEIGHT_GROUP, wrr); \
- STORE_RT_REG(p_hwfn, QM_REG_TXPQMAP_RT_OFFSET + (pq_id), \
- *((u32 *)&__map)); \
- (map) = __map; \
+#define QM_INIT_TX_PQ_MAP(p_hwfn, map, chip, pq_id, vp_pq_id, rl_valid, \
+ rl_id, ext_voq, wrr) \
+ do { \
+ u32 __reg = 0; \
+ \
+ BUILD_BUG_ON(sizeof((map).reg) != sizeof(__reg)); \
+ \
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_PQ_VALID, 1); \
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_RL_VALID, \
+ !!(rl_valid)); \
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_VP_PQ_ID, (vp_pq_id)); \
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_RL_ID, (rl_id)); \
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_VOQ, (ext_voq)); \
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_WRR_WEIGHT_GROUP, \
+ (wrr)); \
+ \
+ STORE_RT_REG((p_hwfn), QM_REG_TXPQMAP_RT_OFFSET + (pq_id), \
+ __reg); \
+ (map).reg = cpu_to_le32(__reg); \
} while (0)
#define WRITE_PQ_INFO_TO_RAM 1
@@ -1022,20 +998,23 @@ bool qed_send_qm_stop_cmd(struct qed_hwfn *p_hwfn,
} while (0)
/**
- * @brief qed_dmae_to_grc - is an internal function - writes from host to
- * wide-bus registers (split registers are not supported yet)
+ * qed_dmae_to_grc() - Internal function for writing from host to
+ * wide-bus registers (split registers are not supported yet).
+ *
+ * @p_hwfn: HW device data.
+ * @p_ptt: PTT window used for writing the registers.
+ * @p_data: Pointer to source data.
+ * @addr: Destination register address.
+ * @len_in_dwords: Data length in dwords (u32).
*
- * @param p_hwfn - HW device data
- * @param p_ptt - ptt window used for writing the registers.
- * @param p_data - pointer to source data.
- * @param addr - Destination register address.
- * @param len_in_dwords - data length in DWARDS (u32)
+ * Return: Length of the written data in dwords (u32) or -1 on invalid
+ * input.
*/
-static int qed_dmae_to_grc(struct qed_hwfn *p_hwfn,
- struct qed_ptt *p_ptt,
- u32 *p_data, u32 addr, u32 len_in_dwords)
+static int qed_dmae_to_grc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+ __le32 *p_data, u32 addr, u32 len_in_dwords)
{
struct qed_dmae_params params = {};
+ u32 *data_cpu;
int rc;
if (!p_data)
@@ -1054,8 +1033,13 @@ static int qed_dmae_to_grc(struct qed_hwfn *p_hwfn,
DP_VERBOSE(p_hwfn,
QED_MSG_DEBUG,
"Failed writing to chip using DMAE, using GRC instead\n");
- /* write to registers using GRC */
- ARR_REG_WR(p_hwfn, p_ptt, addr, p_data, len_in_dwords);
+
+ /* Swap to CPU byteorder and write to registers using GRC */
+ data_cpu = (__force u32 *)p_data;
+ le32_to_cpu_array(data_cpu, len_in_dwords);
+
+ ARR_REG_WR(p_hwfn, p_ptt, addr, data_cpu, len_in_dwords);
+ cpu_to_le32_array(data_cpu, len_in_dwords);
}
return len_in_dwords;
@@ -1256,7 +1240,7 @@ void qed_gft_disable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u16 pf_id)
qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id, 0);
/* Zero ramline */
- qed_dmae_to_grc(p_hwfn, p_ptt, (u32 *)&ram_line,
+ qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
sizeof(ram_line) / REG_SIZE);
}
@@ -1268,8 +1252,10 @@ void qed_gft_config(struct qed_hwfn *p_hwfn,
bool udp,
bool ipv4, bool ipv6, enum gft_profile_type profile_type)
{
- u32 reg_val, cam_line, search_non_ip_as_gft;
- struct regpair ram_line = { };
+ struct regpair ram_line;
+ u32 search_non_ip_as_gft;
+ u32 reg_val, cam_line;
+ u32 lo = 0, hi = 0;
if (!ipv6 && !ipv4)
DP_NOTICE(p_hwfn,
@@ -1340,43 +1326,46 @@ void qed_gft_config(struct qed_hwfn *p_hwfn,
search_non_ip_as_gft = 0;
/* Tunnel type */
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_TUNNEL_DST_PORT, 1);
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_TUNNEL_OVER_IP_PROTOCOL, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_DST_PORT, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_OVER_IP_PROTOCOL, 1);
if (profile_type == GFT_PROFILE_TYPE_4_TUPLE) {
- SET_FIELD(ram_line.hi, GFT_RAM_LINE_DST_IP, 1);
- SET_FIELD(ram_line.hi, GFT_RAM_LINE_SRC_IP, 1);
- SET_FIELD(ram_line.hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_ETHERTYPE, 1);
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_SRC_PORT, 1);
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_DST_PORT, 1);
+ SET_FIELD(hi, GFT_RAM_LINE_DST_IP, 1);
+ SET_FIELD(hi, GFT_RAM_LINE_SRC_IP, 1);
+ SET_FIELD(hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_SRC_PORT, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_DST_PORT, 1);
} else if (profile_type == GFT_PROFILE_TYPE_L4_DST_PORT) {
- SET_FIELD(ram_line.hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_ETHERTYPE, 1);
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_DST_PORT, 1);
+ SET_FIELD(hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_DST_PORT, 1);
} else if (profile_type == GFT_PROFILE_TYPE_IP_DST_ADDR) {
- SET_FIELD(ram_line.hi, GFT_RAM_LINE_DST_IP, 1);
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_ETHERTYPE, 1);
+ SET_FIELD(hi, GFT_RAM_LINE_DST_IP, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
} else if (profile_type == GFT_PROFILE_TYPE_IP_SRC_ADDR) {
- SET_FIELD(ram_line.hi, GFT_RAM_LINE_SRC_IP, 1);
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_ETHERTYPE, 1);
+ SET_FIELD(hi, GFT_RAM_LINE_SRC_IP, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
} else if (profile_type == GFT_PROFILE_TYPE_TUNNEL_TYPE) {
- SET_FIELD(ram_line.lo, GFT_RAM_LINE_TUNNEL_ETHERTYPE, 1);
+ SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_ETHERTYPE, 1);
/* Allow tunneled traffic without inner IP */
search_non_ip_as_gft = 1;
}
+ ram_line.lo = cpu_to_le32(lo);
+ ram_line.hi = cpu_to_le32(hi);
+
qed_wr(p_hwfn,
p_ptt, PRS_REG_SEARCH_NON_IP_AS_GFT, search_non_ip_as_gft);
- qed_dmae_to_grc(p_hwfn, p_ptt, (u32 *)&ram_line,
+ qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
sizeof(ram_line) / REG_SIZE);
/* Set default profile so that no filter match will happen */
- ram_line.lo = 0xffffffff;
- ram_line.hi = 0x3ff;
- qed_dmae_to_grc(p_hwfn, p_ptt, (u32 *)&ram_line,
+ ram_line.lo = cpu_to_le32(0xffffffff);
+ ram_line.hi = cpu_to_le32(0x3ff);
+ qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
PRS_GFT_CAM_LINES_NO_MATCH,
sizeof(ram_line) / REG_SIZE);
@@ -1394,7 +1383,7 @@ static u8 qed_calc_cdu_validation_byte(u8 conn_type, u8 region, u32 cid)
u8 crc, validation_byte = 0;
static u8 crc8_table_valid; /* automatically initialized to 0 */
u32 validation_string = 0;
- u32 data_to_crc;
+ __be32 data_to_crc;
if (!crc8_table_valid) {
crc8_populate_msb(cdu_crc8_table, 0x07);
@@ -1416,10 +1405,9 @@ static u8 qed_calc_cdu_validation_byte(u8 conn_type, u8 region, u32 cid)
validation_string |= (conn_type & 0xF);
/* Convert to big-endian and calculate CRC8 */
- data_to_crc = be32_to_cpu(validation_string);
-
- crc = crc8(cdu_crc8_table,
- (u8 *)&data_to_crc, sizeof(data_to_crc), CRC8_INIT_VALUE);
+ data_to_crc = cpu_to_be32(validation_string);
+ crc = crc8(cdu_crc8_table, (u8 *)&data_to_crc, sizeof(data_to_crc),
+ CRC8_INIT_VALUE);
/* The validation byte [7:0] is composed:
* for type A validation
diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_ops.c b/drivers/net/ethernet/qlogic/qed/qed_init_ops.c
index 5a6e4ac4fef4..7e6c6389523b 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_init_ops.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_init_ops.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -69,6 +43,79 @@ static u32 pxp_global_win[] = {
0,
};
+/* IRO Array */
+static const u32 iro_arr[] = {
+ 0x00000000, 0x00000000, 0x00080000,
+ 0x00003288, 0x00000088, 0x00880000,
+ 0x000058e8, 0x00000020, 0x00200000,
+ 0x00000b00, 0x00000008, 0x00040000,
+ 0x00000a80, 0x00000008, 0x00040000,
+ 0x00000000, 0x00000008, 0x00020000,
+ 0x00000080, 0x00000008, 0x00040000,
+ 0x00000084, 0x00000008, 0x00020000,
+ 0x00005718, 0x00000004, 0x00040000,
+ 0x00004dd0, 0x00000000, 0x00780000,
+ 0x00003e40, 0x00000000, 0x00780000,
+ 0x00004480, 0x00000000, 0x00780000,
+ 0x00003210, 0x00000000, 0x00780000,
+ 0x00003b50, 0x00000000, 0x00780000,
+ 0x00007f58, 0x00000000, 0x00780000,
+ 0x00005f58, 0x00000000, 0x00080000,
+ 0x00007100, 0x00000000, 0x00080000,
+ 0x0000aea0, 0x00000000, 0x00080000,
+ 0x00004398, 0x00000000, 0x00080000,
+ 0x0000a5a0, 0x00000000, 0x00080000,
+ 0x0000bde8, 0x00000000, 0x00080000,
+ 0x00000020, 0x00000004, 0x00040000,
+ 0x000056c8, 0x00000010, 0x00100000,
+ 0x0000c210, 0x00000030, 0x00300000,
+ 0x0000b088, 0x00000038, 0x00380000,
+ 0x00003d20, 0x00000080, 0x00400000,
+ 0x0000bf60, 0x00000000, 0x00040000,
+ 0x00004560, 0x00040080, 0x00040000,
+ 0x000001f8, 0x00000004, 0x00040000,
+ 0x00003d60, 0x00000080, 0x00200000,
+ 0x00008960, 0x00000040, 0x00300000,
+ 0x0000e840, 0x00000060, 0x00600000,
+ 0x00004618, 0x00000080, 0x00380000,
+ 0x00010738, 0x000000c0, 0x00c00000,
+ 0x000001f8, 0x00000002, 0x00020000,
+ 0x0000a2a0, 0x00000000, 0x01080000,
+ 0x0000a3a8, 0x00000008, 0x00080000,
+ 0x000001c0, 0x00000008, 0x00080000,
+ 0x000001f8, 0x00000008, 0x00080000,
+ 0x00000ac0, 0x00000008, 0x00080000,
+ 0x00002578, 0x00000008, 0x00080000,
+ 0x000024f8, 0x00000008, 0x00080000,
+ 0x00000280, 0x00000008, 0x00080000,
+ 0x00000680, 0x00080018, 0x00080000,
+ 0x00000b78, 0x00080018, 0x00020000,
+ 0x0000c640, 0x00000050, 0x003c0000,
+ 0x00012038, 0x00000018, 0x00100000,
+ 0x00011b00, 0x00000040, 0x00180000,
+ 0x000095d0, 0x00000050, 0x00200000,
+ 0x00008b10, 0x00000040, 0x00280000,
+ 0x00011640, 0x00000018, 0x00100000,
+ 0x0000c828, 0x00000048, 0x00380000,
+ 0x00011710, 0x00000020, 0x00200000,
+ 0x00004650, 0x00000080, 0x00100000,
+ 0x00003618, 0x00000010, 0x00100000,
+ 0x0000a968, 0x00000008, 0x00010000,
+ 0x000097a0, 0x00000008, 0x00010000,
+ 0x00011990, 0x00000008, 0x00010000,
+ 0x0000f018, 0x00000008, 0x00010000,
+ 0x00012628, 0x00000008, 0x00010000,
+ 0x00011da8, 0x00000008, 0x00010000,
+ 0x0000aa78, 0x00000030, 0x00100000,
+ 0x0000d768, 0x00000028, 0x00280000,
+ 0x00009a58, 0x00000018, 0x00180000,
+ 0x00009bd8, 0x00000008, 0x00080000,
+ 0x00013a18, 0x00000008, 0x00080000,
+ 0x000126e8, 0x00000018, 0x00180000,
+ 0x0000e608, 0x00500288, 0x00100000,
+ 0x00012970, 0x00000138, 0x00280000,
+};
+
void qed_init_iro_array(struct qed_dev *cdev)
{
cdev->iro_arr = iro_arr;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_ops.h b/drivers/net/ethernet/qlogic/qed/qed_init_ops.h
index e9e8ade50ed3..a573c8921982 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_init_ops.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_init_ops.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_INIT_OPS_H
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c
index 5eec1fc6229d..f8c5a864812d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -850,11 +824,12 @@ static inline u16 qed_attn_update_idx(struct qed_hwfn *p_hwfn,
}
/**
- * @brief qed_int_assertion - handles asserted attention bits
+ * qed_int_assertion() - Handle asserted attention bits.
*
- * @param p_hwfn
- * @param asserted_bits newly asserted bits
- * @return int
+ * @p_hwfn: HW device data.
+ * @asserted_bits: Newly asserted bits.
+ *
+ * Return: Zero value.
*/
static int qed_int_assertion(struct qed_hwfn *p_hwfn, u16 asserted_bits)
{
@@ -914,16 +889,17 @@ static void qed_int_attn_print(struct qed_hwfn *p_hwfn,
}
/**
- * @brief qed_int_deassertion_aeu_bit - handles the effects of a single
- * cause of the attention
+ * qed_int_deassertion_aeu_bit() - Handles the effects of a single
+ * cause of the attention.
*
- * @param p_hwfn
- * @param p_aeu - descriptor of an AEU bit which caused the attention
- * @param aeu_en_reg - register offset of the AEU enable reg. which configured
- * this bit to this group.
- * @param bit_index - index of this bit in the aeu_en_reg
+ * @p_hwfn: HW device data.
+ * @p_aeu: Descriptor of an AEU bit which caused the attention.
+ * @aeu_en_reg: Register offset of the AEU enable reg. which configured
+ * this bit to this group.
+ * @p_bit_name: AEU bit description for logging purposes.
+ * @bitmask: Index of this bit in the aeu_en_reg.
*
- * @return int
+ * Return: Zero on success, negative errno otherwise.
*/
static int
qed_int_deassertion_aeu_bit(struct qed_hwfn *p_hwfn,
@@ -972,12 +948,12 @@ out:
}
/**
- * @brief qed_int_deassertion_parity - handle a single parity AEU source
+ * qed_int_deassertion_parity() - Handle a single parity AEU source.
*
- * @param p_hwfn
- * @param p_aeu - descriptor of an AEU bit which caused the parity
- * @param aeu_en_reg - address of the AEU enable register
- * @param bit_index
+ * @p_hwfn: HW device data.
+ * @p_aeu: Descriptor of an AEU bit which caused the parity.
+ * @aeu_en_reg: Address of the AEU enable register.
+ * @bit_index: Index (0-31) of an AEU bit.
*/
static void qed_int_deassertion_parity(struct qed_hwfn *p_hwfn,
struct aeu_invert_reg_bit *p_aeu,
@@ -1010,12 +986,13 @@ static void qed_int_deassertion_parity(struct qed_hwfn *p_hwfn,
}
/**
- * @brief - handles deassertion of previously asserted attentions.
+ * qed_int_deassertion() - Handle deassertion of previously asserted
+ * attentions.
*
- * @param p_hwfn
- * @param deasserted_bits - newly deasserted bits
- * @return int
+ * @p_hwfn: HW device data.
+ * @deasserted_bits: newly deasserted bits.
*
+ * Return: Zero value.
*/
static int qed_int_deassertion(struct qed_hwfn *p_hwfn,
u16 deasserted_bits)
@@ -1223,16 +1200,15 @@ static int qed_int_attentions(struct qed_hwfn *p_hwfn)
static void qed_sb_ack_attn(struct qed_hwfn *p_hwfn,
void __iomem *igu_addr, u32 ack_cons)
{
- struct igu_prod_cons_update igu_ack = { 0 };
+ u32 igu_ack;
- igu_ack.sb_id_and_flags =
- ((ack_cons << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) |
- (1 << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) |
- (IGU_INT_NOP << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) |
- (IGU_SEG_ACCESS_ATTN <<
- IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT));
+ igu_ack = ((ack_cons << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) |
+ (1 << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) |
+ (IGU_INT_NOP << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) |
+ (IGU_SEG_ACCESS_ATTN <<
+ IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT));
- DIRECT_REG_WR(igu_addr, igu_ack.sb_id_and_flags);
+ DIRECT_REG_WR(igu_addr, igu_ack);
/* Both segments (interrupts & acks) are written to same place address;
* Need to guarantee all commands will be received (in-order) by HW.
@@ -1446,16 +1422,16 @@ void qed_init_cau_sb_entry(struct qed_hwfn *p_hwfn,
u8 pf_id, u16 vf_number, u8 vf_valid)
{
struct qed_dev *cdev = p_hwfn->cdev;
- u32 cau_state;
+ u32 cau_state, params = 0, data = 0;
u8 timer_res;
memset(p_sb_entry, 0, sizeof(*p_sb_entry));
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_PF_NUMBER, pf_id);
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_VF_NUMBER, vf_number);
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_VF_VALID, vf_valid);
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_SB_TIMESET0, 0x7F);
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_SB_TIMESET1, 0x7F);
+ SET_FIELD(params, CAU_SB_ENTRY_PF_NUMBER, pf_id);
+ SET_FIELD(params, CAU_SB_ENTRY_VF_NUMBER, vf_number);
+ SET_FIELD(params, CAU_SB_ENTRY_VF_VALID, vf_valid);
+ SET_FIELD(params, CAU_SB_ENTRY_SB_TIMESET0, 0x7F);
+ SET_FIELD(params, CAU_SB_ENTRY_SB_TIMESET1, 0x7F);
cau_state = CAU_HC_DISABLE_STATE;
@@ -1474,7 +1450,8 @@ void qed_init_cau_sb_entry(struct qed_hwfn *p_hwfn,
timer_res = 1;
else
timer_res = 2;
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
+
+ SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
if (cdev->tx_coalesce_usecs <= 0x7F)
timer_res = 0;
@@ -1482,10 +1459,13 @@ void qed_init_cau_sb_entry(struct qed_hwfn *p_hwfn,
timer_res = 1;
else
timer_res = 2;
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
- SET_FIELD(p_sb_entry->data, CAU_SB_ENTRY_STATE0, cau_state);
- SET_FIELD(p_sb_entry->data, CAU_SB_ENTRY_STATE1, cau_state);
+ SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
+ p_sb_entry->params = cpu_to_le32(params);
+
+ SET_FIELD(data, CAU_SB_ENTRY_STATE0, cau_state);
+ SET_FIELD(data, CAU_SB_ENTRY_STATE1, cau_state);
+ p_sb_entry->data = cpu_to_le32(data);
}
static void qed_int_cau_conf_pi(struct qed_hwfn *p_hwfn,
@@ -1495,31 +1475,27 @@ static void qed_int_cau_conf_pi(struct qed_hwfn *p_hwfn,
enum qed_coalescing_fsm coalescing_fsm,
u8 timeset)
{
- struct cau_pi_entry pi_entry;
u32 sb_offset, pi_offset;
+ u32 prod = 0;
if (IS_VF(p_hwfn->cdev))
return;
- sb_offset = igu_sb_id * PIS_PER_SB_E4;
- memset(&pi_entry, 0, sizeof(struct cau_pi_entry));
-
- SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_PI_TIMESET, timeset);
+ SET_FIELD(prod, CAU_PI_ENTRY_PI_TIMESET, timeset);
if (coalescing_fsm == QED_COAL_RX_STATE_MACHINE)
- SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 0);
+ SET_FIELD(prod, CAU_PI_ENTRY_FSM_SEL, 0);
else
- SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 1);
+ SET_FIELD(prod, CAU_PI_ENTRY_FSM_SEL, 1);
+ sb_offset = igu_sb_id * PIS_PER_SB_E4;
pi_offset = sb_offset + pi_index;
- if (p_hwfn->hw_init_done) {
+
+ if (p_hwfn->hw_init_done)
qed_wr(p_hwfn, p_ptt,
- CAU_REG_PI_MEMORY + pi_offset * sizeof(u32),
- *((u32 *)&(pi_entry)));
- } else {
- STORE_RT_REG(p_hwfn,
- CAU_REG_PI_MEMORY_RT_OFFSET + pi_offset,
- *((u32 *)&(pi_entry)));
- }
+ CAU_REG_PI_MEMORY + pi_offset * sizeof(u32), prod);
+ else
+ STORE_RT_REG(p_hwfn, CAU_REG_PI_MEMORY_RT_OFFSET + pi_offset,
+ prod);
}
void qed_int_cau_conf_sb(struct qed_hwfn *p_hwfn,
@@ -2276,9 +2252,9 @@ int qed_int_igu_read_cam(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
}
/**
- * @brief Initialize igu runtime registers
+ * qed_int_igu_init_rt() - Initialize IGU runtime registers.
*
- * @param p_hwfn
+ * @p_hwfn: HW device data.
*/
void qed_int_igu_init_rt(struct qed_hwfn *p_hwfn)
{
@@ -2388,6 +2364,7 @@ int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
u8 timer_res, u16 sb_id, bool tx)
{
struct cau_sb_entry sb_entry;
+ u32 params;
int rc;
if (!p_hwfn->hw_init_done) {
@@ -2403,10 +2380,14 @@ int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
return rc;
}
+ params = le32_to_cpu(sb_entry.params);
+
if (tx)
- SET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
+ SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
else
- SET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
+ SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
+
+ sb_entry.params = cpu_to_le32(params);
rc = qed_dmae_host2grc(p_hwfn, p_ptt,
(u64)(uintptr_t)&sb_entry,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.h b/drivers/net/ethernet/qlogic/qed/qed_int.h
index 110169e90121..86809d7bc2de 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_INT_H
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iscsi.c b/drivers/net/ethernet/qlogic/qed/qed_iscsi.c
index 7245a615517a..4eae4ee3538f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iscsi.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_iscsi.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -143,10 +117,9 @@ struct qed_iscsi_conn {
u8 abortive_dsconnect;
};
-static int
-qed_iscsi_async_event(struct qed_hwfn *p_hwfn,
- u8 fw_event_code,
- u16 echo, union event_ring_data *data, u8 fw_return_code)
+static int qed_iscsi_async_event(struct qed_hwfn *p_hwfn, u8 fw_event_code,
+ __le16 echo, union event_ring_data *data,
+ u8 fw_return_code)
{
if (p_hwfn->p_iscsi_info->event_cb) {
struct qed_iscsi_info *p_iscsi = p_hwfn->p_iscsi_info;
@@ -297,6 +270,7 @@ static int qed_sp_iscsi_conn_offload(struct qed_hwfn *p_hwfn,
dma_addr_t xhq_pbl_addr;
dma_addr_t uhq_pbl_addr;
u16 physical_q;
+ __le16 tmp;
int rc = 0;
u32 dval;
u16 wval;
@@ -320,12 +294,12 @@ static int qed_sp_iscsi_conn_offload(struct qed_hwfn *p_hwfn,
/* Transmission PQ is the first of the PF */
physical_q = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_OFLD);
- p_conn->physical_q0 = cpu_to_le16(physical_q);
+ p_conn->physical_q0 = physical_q;
p_ramrod->iscsi.physical_q0 = cpu_to_le16(physical_q);
/* iSCSI Pure-ACK PQ */
physical_q = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_ACK);
- p_conn->physical_q1 = cpu_to_le16(physical_q);
+ p_conn->physical_q1 = physical_q;
p_ramrod->iscsi.physical_q1 = cpu_to_le16(physical_q);
p_ramrod->conn_id = cpu_to_le16(p_conn->conn_id);
@@ -351,14 +325,20 @@ static int qed_sp_iscsi_conn_offload(struct qed_hwfn *p_hwfn,
p_tcp = &p_ramrod->tcp;
p = (u16 *)p_conn->local_mac;
- p_tcp->local_mac_addr_hi = swab16(get_unaligned(p));
- p_tcp->local_mac_addr_mid = swab16(get_unaligned(p + 1));
- p_tcp->local_mac_addr_lo = swab16(get_unaligned(p + 2));
+ tmp = cpu_to_le16(get_unaligned_be16(p));
+ p_tcp->local_mac_addr_hi = tmp;
+ tmp = cpu_to_le16(get_unaligned_be16(p + 1));
+ p_tcp->local_mac_addr_mid = tmp;
+ tmp = cpu_to_le16(get_unaligned_be16(p + 2));
+ p_tcp->local_mac_addr_lo = tmp;
p = (u16 *)p_conn->remote_mac;
- p_tcp->remote_mac_addr_hi = swab16(get_unaligned(p));
- p_tcp->remote_mac_addr_mid = swab16(get_unaligned(p + 1));
- p_tcp->remote_mac_addr_lo = swab16(get_unaligned(p + 2));
+ tmp = cpu_to_le16(get_unaligned_be16(p));
+ p_tcp->remote_mac_addr_hi = tmp;
+ tmp = cpu_to_le16(get_unaligned_be16(p + 1));
+ p_tcp->remote_mac_addr_mid = tmp;
+ tmp = cpu_to_le16(get_unaligned_be16(p + 2));
+ p_tcp->remote_mac_addr_lo = tmp;
p_tcp->vlan_id = cpu_to_le16(p_conn->vlan_id);
@@ -417,14 +397,20 @@ static int qed_sp_iscsi_conn_offload(struct qed_hwfn *p_hwfn,
&((struct iscsi_spe_conn_offload_option2 *)p_ramrod)->tcp;
p = (u16 *)p_conn->local_mac;
- p_tcp2->local_mac_addr_hi = swab16(get_unaligned(p));
- p_tcp2->local_mac_addr_mid = swab16(get_unaligned(p + 1));
- p_tcp2->local_mac_addr_lo = swab16(get_unaligned(p + 2));
+ tmp = cpu_to_le16(get_unaligned_be16(p));
+ p_tcp2->local_mac_addr_hi = tmp;
+ tmp = cpu_to_le16(get_unaligned_be16(p + 1));
+ p_tcp2->local_mac_addr_mid = tmp;
+ tmp = cpu_to_le16(get_unaligned_be16(p + 2));
+ p_tcp2->local_mac_addr_lo = tmp;
p = (u16 *)p_conn->remote_mac;
- p_tcp2->remote_mac_addr_hi = swab16(get_unaligned(p));
- p_tcp2->remote_mac_addr_mid = swab16(get_unaligned(p + 1));
- p_tcp2->remote_mac_addr_lo = swab16(get_unaligned(p + 2));
+ tmp = cpu_to_le16(get_unaligned_be16(p));
+ p_tcp2->remote_mac_addr_hi = tmp;
+ tmp = cpu_to_le16(get_unaligned_be16(p + 1));
+ p_tcp2->remote_mac_addr_mid = tmp;
+ tmp = cpu_to_le16(get_unaligned_be16(p + 2));
+ p_tcp2->remote_mac_addr_lo = tmp;
p_tcp2->vlan_id = cpu_to_le16(p_conn->vlan_id);
p_tcp2->flags = cpu_to_le16(p_conn->tcp_flags);
@@ -698,9 +684,13 @@ nomem:
static int qed_iscsi_allocate_connection(struct qed_hwfn *p_hwfn,
struct qed_iscsi_conn **p_out_conn)
{
- u16 uhq_num_elements = 0, xhq_num_elements = 0, r2tq_num_elements = 0;
struct scsi_terminate_extra_params *p_q_cnts = NULL;
struct qed_iscsi_pf_params *p_params = NULL;
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
+ };
struct tcp_upload_params *p_tcp = NULL;
struct qed_iscsi_conn *p_conn = NULL;
int rc = 0;
@@ -741,34 +731,25 @@ static int qed_iscsi_allocate_connection(struct qed_hwfn *p_hwfn,
goto nomem_upload_param;
p_conn->tcp_upload_params_virt_addr = p_tcp;
- r2tq_num_elements = p_params->num_r2tq_pages_in_ring *
- QED_CHAIN_PAGE_SIZE / 0x80;
- rc = qed_chain_alloc(p_hwfn->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- r2tq_num_elements, 0x80, &p_conn->r2tq, NULL);
+ params.num_elems = p_params->num_r2tq_pages_in_ring *
+ QED_CHAIN_PAGE_SIZE / sizeof(struct iscsi_wqe);
+ params.elem_size = sizeof(struct iscsi_wqe);
+
+ rc = qed_chain_alloc(p_hwfn->cdev, &p_conn->r2tq, &params);
if (rc)
goto nomem_r2tq;
- uhq_num_elements = p_params->num_uhq_pages_in_ring *
+ params.num_elems = p_params->num_uhq_pages_in_ring *
QED_CHAIN_PAGE_SIZE / sizeof(struct iscsi_uhqe);
- rc = qed_chain_alloc(p_hwfn->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- uhq_num_elements,
- sizeof(struct iscsi_uhqe), &p_conn->uhq, NULL);
+ params.elem_size = sizeof(struct iscsi_uhqe);
+
+ rc = qed_chain_alloc(p_hwfn->cdev, &p_conn->uhq, &params);
if (rc)
goto nomem_uhq;
- xhq_num_elements = uhq_num_elements;
- rc = qed_chain_alloc(p_hwfn->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- xhq_num_elements,
- sizeof(struct iscsi_xhqe), &p_conn->xhq, NULL);
+ params.elem_size = sizeof(struct iscsi_xhqe);
+
+ rc = qed_chain_alloc(p_hwfn->cdev, &p_conn->xhq, &params);
if (rc)
goto nomem;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iscsi.h b/drivers/net/ethernet/qlogic/qed/qed_iscsi.h
index 225c75b02a06..dab7a5d09f87 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iscsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_iscsi.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_ISCSI_H
@@ -52,10 +26,6 @@ struct qed_iscsi_info {
iscsi_event_cb_t event_cb;
};
-#ifdef CONFIG_QED_LL2
-extern const struct qed_ll2_ops qed_ll2_ops_pass;
-#endif
-
#if IS_ENABLED(CONFIG_QED_ISCSI)
int qed_iscsi_alloc(struct qed_hwfn *p_hwfn);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
index 5409a2da6106..512cbef24097 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
@@ -1,34 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
@@ -84,9 +59,8 @@ struct mpa_v2_hdr {
#define QED_IWARP_DEF_KA_TIMEOUT (1200000) /* 20 min */
#define QED_IWARP_DEF_KA_INTERVAL (1000) /* 1 sec */
-static int qed_iwarp_async_event(struct qed_hwfn *p_hwfn,
- u8 fw_event_code, u16 echo,
- union event_ring_data *data,
+static int qed_iwarp_async_event(struct qed_hwfn *p_hwfn, u8 fw_event_code,
+ __le16 echo, union event_ring_data *data,
u8 fw_return_code);
/* Override devinfo with iWARP specific values */
@@ -272,14 +246,14 @@ int qed_iwarp_create_qp(struct qed_hwfn *p_hwfn,
SET_FIELD(p_ramrod->flags,
IWARP_CREATE_QP_RAMROD_DATA_SRQ_FLG, qp->use_srq);
- p_ramrod->pd = qp->pd;
- p_ramrod->sq_num_pages = qp->sq_num_pages;
- p_ramrod->rq_num_pages = qp->rq_num_pages;
+ p_ramrod->pd = cpu_to_le16(qp->pd);
+ p_ramrod->sq_num_pages = cpu_to_le16(qp->sq_num_pages);
+ p_ramrod->rq_num_pages = cpu_to_le16(qp->rq_num_pages);
p_ramrod->srq_id.srq_idx = cpu_to_le16(qp->srq_id);
p_ramrod->srq_id.opaque_fid = cpu_to_le16(p_hwfn->hw_info.opaque_fid);
- p_ramrod->qp_handle_for_cqe.hi = cpu_to_le32(qp->qp_handle.hi);
- p_ramrod->qp_handle_for_cqe.lo = cpu_to_le32(qp->qp_handle.lo);
+ p_ramrod->qp_handle_for_cqe.hi = qp->qp_handle.hi;
+ p_ramrod->qp_handle_for_cqe.lo = qp->qp_handle.lo;
p_ramrod->cq_cid_for_sq =
cpu_to_le32((p_hwfn->hw_info.opaque_fid << 16) | qp->sq_cq_id);
@@ -314,6 +288,7 @@ static int qed_iwarp_modify_fw(struct qed_hwfn *p_hwfn, struct qed_rdma_qp *qp)
struct iwarp_modify_qp_ramrod_data *p_ramrod;
struct qed_sp_init_data init_data;
struct qed_spq_entry *p_ent;
+ u16 flags, trans_to_state;
int rc;
/* Get SPQ entry */
@@ -329,12 +304,17 @@ static int qed_iwarp_modify_fw(struct qed_hwfn *p_hwfn, struct qed_rdma_qp *qp)
return rc;
p_ramrod = &p_ent->ramrod.iwarp_modify_qp;
- SET_FIELD(p_ramrod->flags, IWARP_MODIFY_QP_RAMROD_DATA_STATE_TRANS_EN,
- 0x1);
+
+ flags = le16_to_cpu(p_ramrod->flags);
+ SET_FIELD(flags, IWARP_MODIFY_QP_RAMROD_DATA_STATE_TRANS_EN, 0x1);
+ p_ramrod->flags = cpu_to_le16(flags);
+
if (qp->iwarp_state == QED_IWARP_QP_STATE_CLOSING)
- p_ramrod->transition_to_state = IWARP_MODIFY_QP_STATE_CLOSING;
+ trans_to_state = IWARP_MODIFY_QP_STATE_CLOSING;
else
- p_ramrod->transition_to_state = IWARP_MODIFY_QP_STATE_ERROR;
+ trans_to_state = IWARP_MODIFY_QP_STATE_ERROR;
+
+ p_ramrod->transition_to_state = cpu_to_le16(trans_to_state);
rc = qed_spq_post(p_hwfn, p_ent, NULL);
@@ -647,6 +627,7 @@ qed_iwarp_tcp_offload(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
dma_addr_t async_output_phys;
dma_addr_t in_pdata_phys;
u16 physical_q;
+ u16 flags = 0;
u8 tcp_flags;
int rc;
int i;
@@ -699,13 +680,14 @@ qed_iwarp_tcp_offload(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
tcp->vlan_id = cpu_to_le16(ep->cm_info.vlan);
tcp_flags = p_hwfn->p_rdma_info->iwarp.tcp_flags;
- tcp->flags = 0;
- SET_FIELD(tcp->flags, TCP_OFFLOAD_PARAMS_OPT2_TS_EN,
+
+ SET_FIELD(flags, TCP_OFFLOAD_PARAMS_OPT2_TS_EN,
!!(tcp_flags & QED_IWARP_TS_EN));
- SET_FIELD(tcp->flags, TCP_OFFLOAD_PARAMS_OPT2_DA_EN,
+ SET_FIELD(flags, TCP_OFFLOAD_PARAMS_OPT2_DA_EN,
!!(tcp_flags & QED_IWARP_DA_EN));
+ tcp->flags = cpu_to_le16(flags);
tcp->ip_version = ep->cm_info.ip_version;
for (i = 0; i < 4; i++) {
@@ -721,10 +703,10 @@ qed_iwarp_tcp_offload(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
tcp->tos_or_tc = 0;
tcp->max_rt_time = QED_IWARP_DEF_MAX_RT_TIME;
- tcp->cwnd = QED_IWARP_DEF_CWND_FACTOR * tcp->mss;
+ tcp->cwnd = cpu_to_le32(QED_IWARP_DEF_CWND_FACTOR * ep->mss);
tcp->ka_max_probe_cnt = QED_IWARP_DEF_KA_MAX_PROBE_CNT;
- tcp->ka_timeout = QED_IWARP_DEF_KA_TIMEOUT;
- tcp->ka_interval = QED_IWARP_DEF_KA_INTERVAL;
+ tcp->ka_timeout = cpu_to_le32(QED_IWARP_DEF_KA_TIMEOUT);
+ tcp->ka_interval = cpu_to_le32(QED_IWARP_DEF_KA_INTERVAL);
tcp->rcv_wnd_scale = (u8)p_hwfn->p_rdma_info->iwarp.rcv_wnd_scale;
tcp->connect_mode = ep->connect_mode;
@@ -755,6 +737,7 @@ qed_iwarp_mpa_received(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
union async_output *async_data;
u16 mpa_ord, mpa_ird;
u8 mpa_hdr_size = 0;
+ u16 ulp_data_len;
u8 mpa_rev;
async_data = &ep->ep_buffer_virt->async_output;
@@ -818,8 +801,8 @@ qed_iwarp_mpa_received(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
/* Strip mpa v2 hdr from private data before sending to upper layer */
ep->cm_info.private_data = ep->ep_buffer_virt->in_pdata + mpa_hdr_size;
- ep->cm_info.private_data_len = async_data->mpa_request.ulp_data_len -
- mpa_hdr_size;
+ ulp_data_len = le16_to_cpu(async_data->mpa_request.ulp_data_len);
+ ep->cm_info.private_data_len = ulp_data_len - mpa_hdr_size;
params.event = QED_IWARP_EVENT_MPA_REQUEST;
params.cm_info = &ep->cm_info;
@@ -834,6 +817,7 @@ static int
qed_iwarp_mpa_offload(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
{
struct iwarp_mpa_offload_ramrod_data *p_mpa_ramrod;
+ struct mpa_outgoing_params *common;
struct qed_iwarp_info *iwarp_info;
struct qed_sp_init_data init_data;
dma_addr_t async_output_phys;
@@ -842,6 +826,7 @@ qed_iwarp_mpa_offload(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
dma_addr_t in_pdata_phys;
struct qed_rdma_qp *qp;
bool reject;
+ u32 val;
int rc;
if (!ep)
@@ -866,18 +851,21 @@ qed_iwarp_mpa_offload(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
return rc;
p_mpa_ramrod = &p_ent->ramrod.iwarp_mpa_offload;
+ common = &p_mpa_ramrod->common;
+
out_pdata_phys = ep->ep_buffer_phys +
offsetof(struct qed_iwarp_ep_memory, out_pdata);
- DMA_REGPAIR_LE(p_mpa_ramrod->common.outgoing_ulp_buffer.addr,
- out_pdata_phys);
- p_mpa_ramrod->common.outgoing_ulp_buffer.len =
- ep->cm_info.private_data_len;
- p_mpa_ramrod->common.crc_needed = p_hwfn->p_rdma_info->iwarp.crc_needed;
+ DMA_REGPAIR_LE(common->outgoing_ulp_buffer.addr, out_pdata_phys);
+
+ val = ep->cm_info.private_data_len;
+ common->outgoing_ulp_buffer.len = cpu_to_le16(val);
+ common->crc_needed = p_hwfn->p_rdma_info->iwarp.crc_needed;
- p_mpa_ramrod->common.out_rq.ord = ep->cm_info.ord;
- p_mpa_ramrod->common.out_rq.ird = ep->cm_info.ird;
+ common->out_rq.ord = cpu_to_le32(ep->cm_info.ord);
+ common->out_rq.ird = cpu_to_le32(ep->cm_info.ird);
- p_mpa_ramrod->tcp_cid = p_hwfn->hw_info.opaque_fid << 16 | ep->tcp_cid;
+ val = p_hwfn->hw_info.opaque_fid << 16 | ep->tcp_cid;
+ p_mpa_ramrod->tcp_cid = cpu_to_le32(val);
in_pdata_phys = ep->ep_buffer_phys +
offsetof(struct qed_iwarp_ep_memory, in_pdata);
@@ -899,11 +887,11 @@ qed_iwarp_mpa_offload(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
p_mpa_ramrod->stats_counter_id =
RESC_START(p_hwfn, QED_RDMA_STATS_QUEUE) + qp->stats_queue;
} else {
- p_mpa_ramrod->common.reject = 1;
+ common->reject = 1;
}
iwarp_info = &p_hwfn->p_rdma_info->iwarp;
- p_mpa_ramrod->rcv_wnd = iwarp_info->rcv_wnd_size;
+ p_mpa_ramrod->rcv_wnd = cpu_to_le16(iwarp_info->rcv_wnd_size);
p_mpa_ramrod->mode = ep->mpa_rev;
SET_FIELD(p_mpa_ramrod->rtr_pref,
IWARP_MPA_OFFLOAD_RAMROD_DATA_RTR_SUPPORTED, ep->rtr_type);
@@ -954,6 +942,7 @@ qed_iwarp_parse_private_data(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
union async_output *async_data;
u16 mpa_ird, mpa_ord;
u8 mpa_data_size = 0;
+ u16 ulp_data_len;
if (MPA_REV2(p_hwfn->p_rdma_info->iwarp.mpa_rev)) {
mpa_v2_params =
@@ -965,11 +954,12 @@ qed_iwarp_parse_private_data(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
ep->cm_info.ird = (u8)(mpa_ord & MPA_V2_IRD_ORD_MASK);
ep->cm_info.ord = (u8)(mpa_ird & MPA_V2_IRD_ORD_MASK);
}
- async_data = &ep->ep_buffer_virt->async_output;
+ async_data = &ep->ep_buffer_virt->async_output;
ep->cm_info.private_data = ep->ep_buffer_virt->in_pdata + mpa_data_size;
- ep->cm_info.private_data_len = async_data->mpa_response.ulp_data_len -
- mpa_data_size;
+
+ ulp_data_len = le16_to_cpu(async_data->mpa_response.ulp_data_len);
+ ep->cm_info.private_data_len = ulp_data_len - mpa_data_size;
}
static void
@@ -1846,7 +1836,7 @@ qed_iwarp_mpa_classify(struct qed_hwfn *p_hwfn,
goto out;
}
- mpa_len = ntohs(*((u16 *)(mpa_data)));
+ mpa_len = ntohs(*(__force __be16 *)mpa_data);
fpdu->fpdu_length = QED_IWARP_FPDU_LEN_WITH_PAD(mpa_len);
if (fpdu->fpdu_length <= tcp_payload_len)
@@ -1868,11 +1858,13 @@ qed_iwarp_init_fpdu(struct qed_iwarp_ll2_buff *buf,
struct unaligned_opaque_data *pkt_data,
u16 tcp_payload_size, u8 placement_offset)
{
+ u16 first_mpa_offset = le16_to_cpu(pkt_data->first_mpa_offset);
+
fpdu->mpa_buf = buf;
fpdu->pkt_hdr = buf->data_phys_addr + placement_offset;
fpdu->pkt_hdr_size = pkt_data->tcp_payload_offset;
- fpdu->mpa_frag = buf->data_phys_addr + pkt_data->first_mpa_offset;
- fpdu->mpa_frag_virt = (u8 *)(buf->data) + pkt_data->first_mpa_offset;
+ fpdu->mpa_frag = buf->data_phys_addr + first_mpa_offset;
+ fpdu->mpa_frag_virt = (u8 *)(buf->data) + first_mpa_offset;
if (tcp_payload_size == 1)
fpdu->incomplete_bytes = QED_IWARP_INVALID_FPDU_LENGTH;
@@ -1890,6 +1882,7 @@ qed_iwarp_cp_pkt(struct qed_hwfn *p_hwfn,
struct unaligned_opaque_data *pkt_data,
struct qed_iwarp_ll2_buff *buf, u16 tcp_payload_size)
{
+ u16 first_mpa_offset = le16_to_cpu(pkt_data->first_mpa_offset);
u8 *tmp_buf = p_hwfn->p_rdma_info->iwarp.mpa_intermediate_buf;
int rc;
@@ -1910,13 +1903,11 @@ qed_iwarp_cp_pkt(struct qed_hwfn *p_hwfn,
DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
"MPA ALIGN Copying fpdu: [%p, %d] [%p, %d]\n",
fpdu->mpa_frag_virt, fpdu->mpa_frag_len,
- (u8 *)(buf->data) + pkt_data->first_mpa_offset,
- tcp_payload_size);
+ (u8 *)(buf->data) + first_mpa_offset, tcp_payload_size);
memcpy(tmp_buf, fpdu->mpa_frag_virt, fpdu->mpa_frag_len);
memcpy(tmp_buf + fpdu->mpa_frag_len,
- (u8 *)(buf->data) + pkt_data->first_mpa_offset,
- tcp_payload_size);
+ (u8 *)(buf->data) + first_mpa_offset, tcp_payload_size);
rc = qed_iwarp_recycle_pkt(p_hwfn, fpdu, fpdu->mpa_buf);
if (rc)
@@ -2059,6 +2050,7 @@ qed_iwarp_send_fpdu(struct qed_hwfn *p_hwfn,
u16 tcp_payload_size, enum qed_iwarp_mpa_pkt_type pkt_type)
{
struct qed_ll2_tx_pkt_info tx_pkt;
+ u16 first_mpa_offset;
u8 ll2_handle;
int rc;
@@ -2110,11 +2102,13 @@ qed_iwarp_send_fpdu(struct qed_hwfn *p_hwfn,
if (!fpdu->incomplete_bytes)
goto out;
+ first_mpa_offset = le16_to_cpu(curr_pkt->first_mpa_offset);
+
/* Set third fragment to second part of the packet */
rc = qed_ll2_set_fragment_of_tx_packet(p_hwfn,
ll2_handle,
buf->data_phys_addr +
- curr_pkt->first_mpa_offset,
+ first_mpa_offset,
fpdu->incomplete_bytes);
out:
DP_VERBOSE(p_hwfn,
@@ -2135,12 +2129,12 @@ qed_iwarp_mpa_get_data(struct qed_hwfn *p_hwfn,
{
u64 opaque_data;
- opaque_data = HILO_64(opaque_data1, opaque_data0);
+ opaque_data = HILO_64(cpu_to_le32(opaque_data1),
+ cpu_to_le32(opaque_data0));
*curr_pkt = *((struct unaligned_opaque_data *)&opaque_data);
- curr_pkt->first_mpa_offset = curr_pkt->tcp_payload_offset +
- le16_to_cpu(curr_pkt->first_mpa_offset);
- curr_pkt->cid = le32_to_cpu(curr_pkt->cid);
+ le16_add_cpu(&curr_pkt->first_mpa_offset,
+ curr_pkt->tcp_payload_offset);
}
/* This function is called when an unaligned or incomplete MPA packet arrives
@@ -2155,18 +2149,22 @@ qed_iwarp_process_mpa_pkt(struct qed_hwfn *p_hwfn,
struct qed_iwarp_ll2_buff *buf = mpa_buf->ll2_buf;
enum qed_iwarp_mpa_pkt_type pkt_type;
struct qed_iwarp_fpdu *fpdu;
+ u16 cid, first_mpa_offset;
int rc = -EINVAL;
u8 *mpa_data;
- fpdu = qed_iwarp_get_curr_fpdu(p_hwfn, curr_pkt->cid & 0xffff);
+ cid = le32_to_cpu(curr_pkt->cid);
+
+ fpdu = qed_iwarp_get_curr_fpdu(p_hwfn, (u16)cid);
if (!fpdu) { /* something corrupt with cid, post rx back */
DP_ERR(p_hwfn, "Invalid cid, drop and post back to rx cid=%x\n",
- curr_pkt->cid);
+ cid);
goto err;
}
do {
- mpa_data = ((u8 *)(buf->data) + curr_pkt->first_mpa_offset);
+ first_mpa_offset = le16_to_cpu(curr_pkt->first_mpa_offset);
+ mpa_data = ((u8 *)(buf->data) + first_mpa_offset);
pkt_type = qed_iwarp_mpa_classify(p_hwfn, fpdu,
mpa_buf->tcp_payload_len,
@@ -2212,7 +2210,8 @@ qed_iwarp_process_mpa_pkt(struct qed_hwfn *p_hwfn,
}
mpa_buf->tcp_payload_len -= fpdu->fpdu_length;
- curr_pkt->first_mpa_offset += fpdu->fpdu_length;
+ le16_add_cpu(&curr_pkt->first_mpa_offset,
+ fpdu->fpdu_length);
break;
case QED_IWARP_MPA_PKT_UNALIGNED:
qed_iwarp_update_fpdu_length(p_hwfn, fpdu, mpa_data);
@@ -2251,7 +2250,9 @@ qed_iwarp_process_mpa_pkt(struct qed_hwfn *p_hwfn,
}
mpa_buf->tcp_payload_len -= fpdu->incomplete_bytes;
- curr_pkt->first_mpa_offset += fpdu->incomplete_bytes;
+ le16_add_cpu(&curr_pkt->first_mpa_offset,
+ fpdu->incomplete_bytes);
+
/* The framed PDU was sent - no more incomplete bytes */
fpdu->incomplete_bytes = 0;
break;
@@ -2302,6 +2303,7 @@ qed_iwarp_ll2_comp_mpa_pkt(void *cxt, struct qed_ll2_comp_rx_data *data)
struct qed_iwarp_ll2_mpa_buf *mpa_buf;
struct qed_iwarp_info *iwarp_info;
struct qed_hwfn *p_hwfn = cxt;
+ u16 first_mpa_offset;
iwarp_info = &p_hwfn->p_rdma_info->iwarp;
mpa_buf = list_first_entry(&iwarp_info->mpa_buf_list,
@@ -2315,17 +2317,21 @@ qed_iwarp_ll2_comp_mpa_pkt(void *cxt, struct qed_ll2_comp_rx_data *data)
qed_iwarp_mpa_get_data(p_hwfn, &mpa_buf->data,
data->opaque_data_0, data->opaque_data_1);
+ first_mpa_offset = le16_to_cpu(mpa_buf->data.first_mpa_offset);
+
DP_VERBOSE(p_hwfn,
QED_MSG_RDMA,
"LL2 MPA CompRx payload_len:0x%x\tfirst_mpa_offset:0x%x\ttcp_payload_offset:0x%x\tflags:0x%x\tcid:0x%x\n",
- data->length.packet_length, mpa_buf->data.first_mpa_offset,
+ data->length.packet_length, first_mpa_offset,
mpa_buf->data.tcp_payload_offset, mpa_buf->data.flags,
mpa_buf->data.cid);
mpa_buf->ll2_buf = data->cookie;
mpa_buf->tcp_payload_len = data->length.packet_length -
- mpa_buf->data.first_mpa_offset;
- mpa_buf->data.first_mpa_offset += data->u.placement_offset;
+ first_mpa_offset;
+
+ first_mpa_offset += data->u.placement_offset;
+ mpa_buf->data.first_mpa_offset = cpu_to_le16(first_mpa_offset);
mpa_buf->placement_offset = data->u.placement_offset;
list_add_tail(&mpa_buf->list_entry, &iwarp_info->mpa_buf_pending_list);
@@ -2524,14 +2530,16 @@ qed_iwarp_ll2_slowpath(void *cxt,
struct unaligned_opaque_data unalign_data;
struct qed_hwfn *p_hwfn = cxt;
struct qed_iwarp_fpdu *fpdu;
+ u32 cid;
qed_iwarp_mpa_get_data(p_hwfn, &unalign_data,
opaque_data_0, opaque_data_1);
- DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "(0x%x) Flush fpdu\n",
- unalign_data.cid);
+ cid = le32_to_cpu(unalign_data.cid);
+
+ DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "(0x%x) Flush fpdu\n", cid);
- fpdu = qed_iwarp_get_curr_fpdu(p_hwfn, (u16)unalign_data.cid);
+ fpdu = qed_iwarp_get_curr_fpdu(p_hwfn, (u16)cid);
if (fpdu)
memset(fpdu, 0, sizeof(*fpdu));
}
@@ -3033,9 +3041,8 @@ qed_iwarp_check_ep_ok(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
return true;
}
-static int qed_iwarp_async_event(struct qed_hwfn *p_hwfn,
- u8 fw_event_code, u16 echo,
- union event_ring_data *data,
+static int qed_iwarp_async_event(struct qed_hwfn *p_hwfn, u8 fw_event_code,
+ __le16 echo, union event_ring_data *data,
u8 fw_return_code)
{
struct qed_rdma_events events = p_hwfn->p_rdma_info->events;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
index c1b2057d23b8..c3872cd9457f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
@@ -1,34 +1,9 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#ifndef _QED_IWARP_H
#define _QED_IWARP_H
diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c
index 29810a1aa210..4c6ac8862744 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_l2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -50,6 +24,7 @@
#include "qed.h"
#include <linux/qed/qed_chain.h>
#include "qed_cxt.h"
+#include "qed_dcbx.h"
#include "qed_dev_api.h"
#include <linux/qed/qed_eth_if.h>
#include "qed_hsi.h"
@@ -57,6 +32,7 @@
#include "qed_int.h"
#include "qed_l2.h"
#include "qed_mcp.h"
+#include "qed_ptp.h"
#include "qed_reg_addr.h"
#include "qed_sp.h"
#include "qed_sriov.h"
@@ -366,10 +342,11 @@ int qed_sp_eth_vport_start(struct qed_hwfn *p_hwfn,
struct qed_sp_vport_start_params *p_params)
{
struct vport_start_ramrod_data *p_ramrod = NULL;
+ struct eth_vport_tpa_param *tpa_param;
struct qed_spq_entry *p_ent = NULL;
struct qed_sp_init_data init_data;
+ u16 min_size, rx_mode = 0;
u8 abs_vport_id = 0;
- u16 rx_mode = 0;
int rc;
rc = qed_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
@@ -402,21 +379,23 @@ int qed_sp_eth_vport_start(struct qed_hwfn *p_hwfn,
p_ramrod->rx_mode.state = cpu_to_le16(rx_mode);
/* TPA related fields */
- memset(&p_ramrod->tpa_param, 0, sizeof(struct eth_vport_tpa_param));
+ tpa_param = &p_ramrod->tpa_param;
+ memset(tpa_param, 0, sizeof(*tpa_param));
- p_ramrod->tpa_param.max_buff_num = p_params->max_buffers_per_cqe;
+ tpa_param->max_buff_num = p_params->max_buffers_per_cqe;
switch (p_params->tpa_mode) {
case QED_TPA_MODE_GRO:
- p_ramrod->tpa_param.tpa_max_aggs_num = ETH_TPA_MAX_AGGS_NUM;
- p_ramrod->tpa_param.tpa_max_size = (u16)-1;
- p_ramrod->tpa_param.tpa_min_size_to_cont = p_params->mtu / 2;
- p_ramrod->tpa_param.tpa_min_size_to_start = p_params->mtu / 2;
- p_ramrod->tpa_param.tpa_ipv4_en_flg = 1;
- p_ramrod->tpa_param.tpa_ipv6_en_flg = 1;
- p_ramrod->tpa_param.tpa_pkt_split_flg = 1;
- p_ramrod->tpa_param.tpa_gro_consistent_flg = 1;
- break;
+ min_size = p_params->mtu / 2;
+
+ tpa_param->tpa_max_aggs_num = ETH_TPA_MAX_AGGS_NUM;
+ tpa_param->tpa_max_size = cpu_to_le16(U16_MAX);
+ tpa_param->tpa_min_size_to_cont = cpu_to_le16(min_size);
+ tpa_param->tpa_min_size_to_start = cpu_to_le16(min_size);
+ tpa_param->tpa_ipv4_en_flg = 1;
+ tpa_param->tpa_ipv6_en_flg = 1;
+ tpa_param->tpa_pkt_split_flg = 1;
+ tpa_param->tpa_gro_consistent_flg = 1;
default:
break;
}
@@ -625,33 +604,33 @@ qed_sp_update_accept_mode(struct qed_hwfn *p_hwfn,
static void
qed_sp_vport_update_sge_tpa(struct qed_hwfn *p_hwfn,
struct vport_update_ramrod_data *p_ramrod,
- struct qed_sge_tpa_params *p_params)
+ const struct qed_sge_tpa_params *param)
{
- struct eth_vport_tpa_param *p_tpa;
+ struct eth_vport_tpa_param *tpa;
- if (!p_params) {
+ if (!param) {
p_ramrod->common.update_tpa_param_flg = 0;
p_ramrod->common.update_tpa_en_flg = 0;
p_ramrod->common.update_tpa_param_flg = 0;
return;
}
- p_ramrod->common.update_tpa_en_flg = p_params->update_tpa_en_flg;
- p_tpa = &p_ramrod->tpa_param;
- p_tpa->tpa_ipv4_en_flg = p_params->tpa_ipv4_en_flg;
- p_tpa->tpa_ipv6_en_flg = p_params->tpa_ipv6_en_flg;
- p_tpa->tpa_ipv4_tunn_en_flg = p_params->tpa_ipv4_tunn_en_flg;
- p_tpa->tpa_ipv6_tunn_en_flg = p_params->tpa_ipv6_tunn_en_flg;
+ p_ramrod->common.update_tpa_en_flg = param->update_tpa_en_flg;
+ tpa = &p_ramrod->tpa_param;
+ tpa->tpa_ipv4_en_flg = param->tpa_ipv4_en_flg;
+ tpa->tpa_ipv6_en_flg = param->tpa_ipv6_en_flg;
+ tpa->tpa_ipv4_tunn_en_flg = param->tpa_ipv4_tunn_en_flg;
+ tpa->tpa_ipv6_tunn_en_flg = param->tpa_ipv6_tunn_en_flg;
- p_ramrod->common.update_tpa_param_flg = p_params->update_tpa_param_flg;
- p_tpa->max_buff_num = p_params->max_buffers_per_cqe;
- p_tpa->tpa_pkt_split_flg = p_params->tpa_pkt_split_flg;
- p_tpa->tpa_hdr_data_split_flg = p_params->tpa_hdr_data_split_flg;
- p_tpa->tpa_gro_consistent_flg = p_params->tpa_gro_consistent_flg;
- p_tpa->tpa_max_aggs_num = p_params->tpa_max_aggs_num;
- p_tpa->tpa_max_size = p_params->tpa_max_size;
- p_tpa->tpa_min_size_to_start = p_params->tpa_min_size_to_start;
- p_tpa->tpa_min_size_to_cont = p_params->tpa_min_size_to_cont;
+ p_ramrod->common.update_tpa_param_flg = param->update_tpa_param_flg;
+ tpa->max_buff_num = param->max_buffers_per_cqe;
+ tpa->tpa_pkt_split_flg = param->tpa_pkt_split_flg;
+ tpa->tpa_hdr_data_split_flg = param->tpa_hdr_data_split_flg;
+ tpa->tpa_gro_consistent_flg = param->tpa_gro_consistent_flg;
+ tpa->tpa_max_aggs_num = param->tpa_max_aggs_num;
+ tpa->tpa_max_size = cpu_to_le16(param->tpa_max_size);
+ tpa->tpa_min_size_to_start = cpu_to_le16(param->tpa_min_size_to_start);
+ tpa->tpa_min_size_to_cont = cpu_to_le16(param->tpa_min_size_to_cont);
}
static void
@@ -2113,7 +2092,8 @@ int qed_get_rxq_coalesce(struct qed_hwfn *p_hwfn,
return rc;
}
- timer_res = GET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES0);
+ timer_res = GET_FIELD(le32_to_cpu(sb_entry.params),
+ CAU_SB_ENTRY_TIMER_RES0);
address = BAR0_MAP_REG_USDM_RAM +
USTORM_ETH_QUEUE_ZONE_OFFSET(p_cid->abs.queue_id);
@@ -2146,7 +2126,8 @@ int qed_get_txq_coalesce(struct qed_hwfn *p_hwfn,
return rc;
}
- timer_res = GET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES1);
+ timer_res = GET_FIELD(le32_to_cpu(sb_entry.params),
+ CAU_SB_ENTRY_TIMER_RES1);
address = BAR0_MAP_REG_XSDM_RAM +
XSTORM_ETH_QUEUE_ZONE_OFFSET(p_cid->abs.queue_id);
@@ -2900,16 +2881,6 @@ static int qed_req_bulletin_update_mac(struct qed_dev *cdev, u8 *mac)
return 0;
}
-#ifdef CONFIG_QED_SRIOV
-extern const struct qed_iov_hv_ops qed_iov_ops_pass;
-#endif
-
-#ifdef CONFIG_DCB
-extern const struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass;
-#endif
-
-extern const struct qed_eth_ptp_ops qed_ptp_ops_pass;
-
static const struct qed_eth_ops qed_eth_ops_pass = {
.common = &qed_common_ops_pass,
#ifdef CONFIG_QED_SRIOV
diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.h b/drivers/net/ethernet/qlogic/qed/qed_l2.h
index 7127d5aaac42..8eceeebb1a7b 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_l2.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_l2.h
@@ -1,34 +1,9 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#ifndef _QED_L2_H
#define _QED_L2_H
#include <linux/types.h>
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index 4afd8572ada6..0452b728c527 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -1151,6 +1125,12 @@ static int
qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_info)
{
+ struct qed_chain_init_params params = {
+ .intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
+ .num_elems = p_ll2_info->input.rx_num_desc,
+ };
+ struct qed_dev *cdev = p_hwfn->cdev;
struct qed_ll2_rx_packet *p_descq;
u32 capacity;
int rc = 0;
@@ -1158,13 +1138,10 @@ qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn,
if (!p_ll2_info->input.rx_num_desc)
goto out;
- rc = qed_chain_alloc(p_hwfn->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_NEXT_PTR,
- QED_CHAIN_CNT_TYPE_U16,
- p_ll2_info->input.rx_num_desc,
- sizeof(struct core_rx_bd),
- &p_ll2_info->rx_queue.rxq_chain, NULL);
+ params.mode = QED_CHAIN_MODE_NEXT_PTR;
+ params.elem_size = sizeof(struct core_rx_bd);
+
+ rc = qed_chain_alloc(cdev, &p_ll2_info->rx_queue.rxq_chain, &params);
if (rc) {
DP_NOTICE(p_hwfn, "Failed to allocate ll2 rxq chain\n");
goto out;
@@ -1180,13 +1157,10 @@ qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn,
}
p_ll2_info->rx_queue.descq_array = p_descq;
- rc = qed_chain_alloc(p_hwfn->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- p_ll2_info->input.rx_num_desc,
- sizeof(struct core_rx_fast_path_cqe),
- &p_ll2_info->rx_queue.rcq_chain, NULL);
+ params.mode = QED_CHAIN_MODE_PBL;
+ params.elem_size = sizeof(struct core_rx_fast_path_cqe);
+
+ rc = qed_chain_alloc(cdev, &p_ll2_info->rx_queue.rcq_chain, &params);
if (rc) {
DP_NOTICE(p_hwfn, "Failed to allocate ll2 rcq chain\n");
goto out;
@@ -1203,6 +1177,13 @@ out:
static int qed_ll2_acquire_connection_tx(struct qed_hwfn *p_hwfn,
struct qed_ll2_info *p_ll2_info)
{
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
+ .num_elems = p_ll2_info->input.tx_num_desc,
+ .elem_size = sizeof(struct core_tx_bd),
+ };
struct qed_ll2_tx_packet *p_descq;
u32 desc_size;
u32 capacity;
@@ -1211,13 +1192,8 @@ static int qed_ll2_acquire_connection_tx(struct qed_hwfn *p_hwfn,
if (!p_ll2_info->input.tx_num_desc)
goto out;
- rc = qed_chain_alloc(p_hwfn->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- p_ll2_info->input.tx_num_desc,
- sizeof(struct core_tx_bd),
- &p_ll2_info->tx_queue.txq_chain, NULL);
+ rc = qed_chain_alloc(p_hwfn->cdev, &p_ll2_info->tx_queue.txq_chain,
+ &params);
if (rc)
goto out;
@@ -1824,6 +1800,7 @@ qed_ll2_prepare_tx_packet_set_bd(struct qed_hwfn *p_hwfn,
enum core_roce_flavor_type roce_flavor;
enum core_tx_dest tx_dest;
u16 bd_data = 0, frag_idx;
+ u16 bitfield1;
roce_flavor = (pkt->qed_roce_flavor == QED_LL2_ROCE) ? CORE_ROCE
: CORE_RROCE;
@@ -1855,9 +1832,11 @@ qed_ll2_prepare_tx_packet_set_bd(struct qed_hwfn *p_hwfn,
pkt->remove_stag = true;
}
- SET_FIELD(start_bd->bitfield1, CORE_TX_BD_L4_HDR_OFFSET_W,
- cpu_to_le16(pkt->l4_hdr_offset_w));
- SET_FIELD(start_bd->bitfield1, CORE_TX_BD_TX_DST, tx_dest);
+ bitfield1 = le16_to_cpu(start_bd->bitfield1);
+ SET_FIELD(bitfield1, CORE_TX_BD_L4_HDR_OFFSET_W, pkt->l4_hdr_offset_w);
+ SET_FIELD(bitfield1, CORE_TX_BD_TX_DST, tx_dest);
+ start_bd->bitfield1 = cpu_to_le16(bitfield1);
+
bd_data |= pkt->bd_flags;
SET_FIELD(bd_data, CORE_TX_BD_DATA_START_BD, 0x1);
SET_FIELD(bd_data, CORE_TX_BD_DATA_NBDS, pkt->num_of_bds);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.h b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
index 288642d526b7..500d0c4f8077 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_LL2_H
@@ -142,6 +116,8 @@ struct qed_ll2_info {
struct qed_ll2_cbs cbs;
};
+extern const struct qed_ll2_ops qed_ll2_ops_pass;
+
/**
* @brief qed_ll2_acquire_connection - allocate resources,
* starts rx & tx (if relevant) queues pair. Provides
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 11367a248d55..2558cb680db3 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/stddef.h>
@@ -50,6 +24,7 @@
#include <linux/qed/qed_ll2_if.h>
#include <net/devlink.h>
#include <linux/aer.h>
+#include <linux/phylink.h>
#include "qed.h"
#include "qed_sriov.h"
@@ -90,20 +65,200 @@ MODULE_VERSION(DRV_MODULE_VERSION);
MODULE_FIRMWARE(QED_FW_FILE_NAME);
+/* MFW speed capabilities maps */
+
+struct qed_mfw_speed_map {
+ u32 mfw_val;
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(caps);
+
+ const u32 *cap_arr;
+ u32 arr_size;
+};
+
+#define QED_MFW_SPEED_MAP(type, arr) \
+{ \
+ .mfw_val = (type), \
+ .cap_arr = (arr), \
+ .arr_size = ARRAY_SIZE(arr), \
+}
+
+static const u32 qed_mfw_ext_1g[] __initconst = {
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
+};
+
+static const u32 qed_mfw_ext_10g[] __initconst = {
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
+ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
+};
+
+static const u32 qed_mfw_ext_20g[] __initconst = {
+ ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
+};
+
+static const u32 qed_mfw_ext_25g[] __initconst = {
+ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
+};
+
+static const u32 qed_mfw_ext_40g[] __initconst = {
+ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
+};
+
+static const u32 qed_mfw_ext_50g_base_r[] __initconst = {
+ ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseDR_Full_BIT,
+};
+
+static const u32 qed_mfw_ext_50g_base_r2[] __initconst = {
+ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
+};
+
+static const u32 qed_mfw_ext_100g_base_r2[] __initconst = {
+ ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
+};
+
+static const u32 qed_mfw_ext_100g_base_r4[] __initconst = {
+ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
+};
+
+static struct qed_mfw_speed_map qed_mfw_ext_maps[] __ro_after_init = {
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_1G, qed_mfw_ext_1g),
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_10G, qed_mfw_ext_10g),
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_20G, qed_mfw_ext_20g),
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_25G, qed_mfw_ext_25g),
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_40G, qed_mfw_ext_40g),
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_50G_BASE_R,
+ qed_mfw_ext_50g_base_r),
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_50G_BASE_R2,
+ qed_mfw_ext_50g_base_r2),
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_100G_BASE_R2,
+ qed_mfw_ext_100g_base_r2),
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_100G_BASE_R4,
+ qed_mfw_ext_100g_base_r4),
+};
+
+static const u32 qed_mfw_legacy_1g[] __initconst = {
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
+};
+
+static const u32 qed_mfw_legacy_10g[] __initconst = {
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
+ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
+};
+
+static const u32 qed_mfw_legacy_20g[] __initconst = {
+ ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
+};
+
+static const u32 qed_mfw_legacy_25g[] __initconst = {
+ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
+};
+
+static const u32 qed_mfw_legacy_40g[] __initconst = {
+ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
+};
+
+static const u32 qed_mfw_legacy_50g[] __initconst = {
+ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
+};
+
+static const u32 qed_mfw_legacy_bb_100g[] __initconst = {
+ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
+};
+
+static struct qed_mfw_speed_map qed_mfw_legacy_maps[] __ro_after_init = {
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G,
+ qed_mfw_legacy_1g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G,
+ qed_mfw_legacy_10g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G,
+ qed_mfw_legacy_20g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G,
+ qed_mfw_legacy_25g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G,
+ qed_mfw_legacy_40g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G,
+ qed_mfw_legacy_50g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G,
+ qed_mfw_legacy_bb_100g),
+};
+
+static void __init qed_mfw_speed_map_populate(struct qed_mfw_speed_map *map)
+{
+ linkmode_set_bit_array(map->cap_arr, map->arr_size, map->caps);
+
+ map->cap_arr = NULL;
+ map->arr_size = 0;
+}
+
+static void __init qed_mfw_speed_maps_init(void)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_ext_maps); i++)
+ qed_mfw_speed_map_populate(qed_mfw_ext_maps + i);
+
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_legacy_maps); i++)
+ qed_mfw_speed_map_populate(qed_mfw_legacy_maps + i);
+}
+
static int __init qed_init(void)
{
pr_info("%s", version);
+ qed_mfw_speed_maps_init();
+
return 0;
}
+module_init(qed_init);
-static void __exit qed_cleanup(void)
+static void __exit qed_exit(void)
{
- pr_notice("qed_cleanup called\n");
+ /* To prevent marking this module as "permanent" */
}
-
-module_init(qed_init);
-module_exit(qed_cleanup);
+module_exit(qed_exit);
/* Check if the DMA controller on the machine can properly handle the DMA
* addressing required by the device.
@@ -1480,13 +1635,156 @@ static bool qed_can_link_change(struct qed_dev *cdev)
return true;
}
+static void qed_set_ext_speed_params(struct qed_mcp_link_params *link_params,
+ const struct qed_link_params *params)
+{
+ struct qed_mcp_link_speed_params *ext_speed = &link_params->ext_speed;
+ const struct qed_mfw_speed_map *map;
+ u32 i;
+
+ if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG)
+ ext_speed->autoneg = !!params->autoneg;
+
+ if (params->override_flags & QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS) {
+ ext_speed->advertised_speeds = 0;
+
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_ext_maps); i++) {
+ map = qed_mfw_ext_maps + i;
+
+ if (linkmode_intersects(params->adv_speeds, map->caps))
+ ext_speed->advertised_speeds |= map->mfw_val;
+ }
+ }
+
+ if (params->override_flags & QED_LINK_OVERRIDE_SPEED_FORCED_SPEED) {
+ switch (params->forced_speed) {
+ case SPEED_1000:
+ ext_speed->forced_speed = QED_EXT_SPEED_1G;
+ break;
+ case SPEED_10000:
+ ext_speed->forced_speed = QED_EXT_SPEED_10G;
+ break;
+ case SPEED_20000:
+ ext_speed->forced_speed = QED_EXT_SPEED_20G;
+ break;
+ case SPEED_25000:
+ ext_speed->forced_speed = QED_EXT_SPEED_25G;
+ break;
+ case SPEED_40000:
+ ext_speed->forced_speed = QED_EXT_SPEED_40G;
+ break;
+ case SPEED_50000:
+ ext_speed->forced_speed = QED_EXT_SPEED_50G_R |
+ QED_EXT_SPEED_50G_R2;
+ break;
+ case SPEED_100000:
+ ext_speed->forced_speed = QED_EXT_SPEED_100G_R2 |
+ QED_EXT_SPEED_100G_R4 |
+ QED_EXT_SPEED_100G_P4;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!(params->override_flags & QED_LINK_OVERRIDE_FEC_CONFIG))
+ return;
+
+ switch (params->forced_speed) {
+ case SPEED_25000:
+ switch (params->fec) {
+ case FEC_FORCE_MODE_NONE:
+ link_params->ext_fec_mode = ETH_EXT_FEC_25G_NONE;
+ break;
+ case FEC_FORCE_MODE_FIRECODE:
+ link_params->ext_fec_mode = ETH_EXT_FEC_25G_BASE_R;
+ break;
+ case FEC_FORCE_MODE_RS:
+ link_params->ext_fec_mode = ETH_EXT_FEC_25G_RS528;
+ break;
+ case FEC_FORCE_MODE_AUTO:
+ link_params->ext_fec_mode = ETH_EXT_FEC_25G_RS528 |
+ ETH_EXT_FEC_25G_BASE_R |
+ ETH_EXT_FEC_25G_NONE;
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case SPEED_40000:
+ switch (params->fec) {
+ case FEC_FORCE_MODE_NONE:
+ link_params->ext_fec_mode = ETH_EXT_FEC_40G_NONE;
+ break;
+ case FEC_FORCE_MODE_FIRECODE:
+ link_params->ext_fec_mode = ETH_EXT_FEC_40G_BASE_R;
+ break;
+ case FEC_FORCE_MODE_AUTO:
+ link_params->ext_fec_mode = ETH_EXT_FEC_40G_BASE_R |
+ ETH_EXT_FEC_40G_NONE;
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case SPEED_50000:
+ switch (params->fec) {
+ case FEC_FORCE_MODE_NONE:
+ link_params->ext_fec_mode = ETH_EXT_FEC_50G_NONE;
+ break;
+ case FEC_FORCE_MODE_FIRECODE:
+ link_params->ext_fec_mode = ETH_EXT_FEC_50G_BASE_R;
+ break;
+ case FEC_FORCE_MODE_RS:
+ link_params->ext_fec_mode = ETH_EXT_FEC_50G_RS528;
+ break;
+ case FEC_FORCE_MODE_AUTO:
+ link_params->ext_fec_mode = ETH_EXT_FEC_50G_RS528 |
+ ETH_EXT_FEC_50G_BASE_R |
+ ETH_EXT_FEC_50G_NONE;
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case SPEED_100000:
+ switch (params->fec) {
+ case FEC_FORCE_MODE_NONE:
+ link_params->ext_fec_mode = ETH_EXT_FEC_100G_NONE;
+ break;
+ case FEC_FORCE_MODE_FIRECODE:
+ link_params->ext_fec_mode = ETH_EXT_FEC_100G_BASE_R;
+ break;
+ case FEC_FORCE_MODE_RS:
+ link_params->ext_fec_mode = ETH_EXT_FEC_100G_RS528;
+ break;
+ case FEC_FORCE_MODE_AUTO:
+ link_params->ext_fec_mode = ETH_EXT_FEC_100G_RS528 |
+ ETH_EXT_FEC_100G_BASE_R |
+ ETH_EXT_FEC_100G_NONE;
+ break;
+ default:
+ break;
+ }
+
+ break;
+ default:
+ break;
+ }
+}
+
static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
{
- struct qed_hwfn *hwfn;
struct qed_mcp_link_params *link_params;
+ struct qed_mcp_link_speed_params *speed;
+ const struct qed_mfw_speed_map *map;
+ struct qed_hwfn *hwfn;
struct qed_ptt *ptt;
- u32 sup_caps;
int rc;
+ u32 i;
if (!cdev)
return -ENODEV;
@@ -1508,59 +1806,31 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
return -EBUSY;
link_params = qed_mcp_get_link_params(hwfn);
+ if (!link_params)
+ return -ENODATA;
+
+ speed = &link_params->speed;
+
if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG)
- link_params->speed.autoneg = params->autoneg;
+ speed->autoneg = !!params->autoneg;
+
if (params->override_flags & QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS) {
- link_params->speed.advertised_speeds = 0;
- sup_caps = QED_LM_1000baseT_Full_BIT |
- QED_LM_1000baseKX_Full_BIT |
- QED_LM_1000baseX_Full_BIT;
- if (params->adv_speeds & sup_caps)
- link_params->speed.advertised_speeds |=
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
- sup_caps = QED_LM_10000baseT_Full_BIT |
- QED_LM_10000baseKR_Full_BIT |
- QED_LM_10000baseKX4_Full_BIT |
- QED_LM_10000baseR_FEC_BIT |
- QED_LM_10000baseCR_Full_BIT |
- QED_LM_10000baseSR_Full_BIT |
- QED_LM_10000baseLR_Full_BIT |
- QED_LM_10000baseLRM_Full_BIT;
- if (params->adv_speeds & sup_caps)
- link_params->speed.advertised_speeds |=
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
- if (params->adv_speeds & QED_LM_20000baseKR2_Full_BIT)
- link_params->speed.advertised_speeds |=
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G;
- sup_caps = QED_LM_25000baseKR_Full_BIT |
- QED_LM_25000baseCR_Full_BIT |
- QED_LM_25000baseSR_Full_BIT;
- if (params->adv_speeds & sup_caps)
- link_params->speed.advertised_speeds |=
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G;
- sup_caps = QED_LM_40000baseLR4_Full_BIT |
- QED_LM_40000baseKR4_Full_BIT |
- QED_LM_40000baseCR4_Full_BIT |
- QED_LM_40000baseSR4_Full_BIT;
- if (params->adv_speeds & sup_caps)
- link_params->speed.advertised_speeds |=
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
- sup_caps = QED_LM_50000baseKR2_Full_BIT |
- QED_LM_50000baseCR2_Full_BIT |
- QED_LM_50000baseSR2_Full_BIT;
- if (params->adv_speeds & sup_caps)
- link_params->speed.advertised_speeds |=
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G;
- sup_caps = QED_LM_100000baseKR4_Full_BIT |
- QED_LM_100000baseSR4_Full_BIT |
- QED_LM_100000baseCR4_Full_BIT |
- QED_LM_100000baseLR4_ER4_Full_BIT;
- if (params->adv_speeds & sup_caps)
- link_params->speed.advertised_speeds |=
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G;
+ speed->advertised_speeds = 0;
+
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_legacy_maps); i++) {
+ map = qed_mfw_legacy_maps + i;
+
+ if (linkmode_intersects(params->adv_speeds, map->caps))
+ speed->advertised_speeds |= map->mfw_val;
+ }
}
+
if (params->override_flags & QED_LINK_OVERRIDE_SPEED_FORCED_SPEED)
- link_params->speed.forced_speed = params->forced_speed;
+ speed->forced_speed = params->forced_speed;
+
+ if (qed_mcp_is_ext_speed_supported(hwfn))
+ qed_set_ext_speed_params(link_params, params);
+
if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) {
if (params->pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
link_params->pause.autoneg = true;
@@ -1575,6 +1845,7 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
else
link_params->pause.forced_tx = false;
}
+
if (params->override_flags & QED_LINK_OVERRIDE_LOOPBACK_MODE) {
switch (params->loopback_mode) {
case QED_LINK_LOOPBACK_INT_PHY:
@@ -1589,6 +1860,25 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
case QED_LINK_LOOPBACK_MAC:
link_params->loopback_mode = ETH_LOOPBACK_MAC;
break;
+ case QED_LINK_LOOPBACK_CNIG_AH_ONLY_0123:
+ link_params->loopback_mode =
+ ETH_LOOPBACK_CNIG_AH_ONLY_0123;
+ break;
+ case QED_LINK_LOOPBACK_CNIG_AH_ONLY_2301:
+ link_params->loopback_mode =
+ ETH_LOOPBACK_CNIG_AH_ONLY_2301;
+ break;
+ case QED_LINK_LOOPBACK_PCS_AH_ONLY:
+ link_params->loopback_mode = ETH_LOOPBACK_PCS_AH_ONLY;
+ break;
+ case QED_LINK_LOOPBACK_REVERSE_MAC_AH_ONLY:
+ link_params->loopback_mode =
+ ETH_LOOPBACK_REVERSE_MAC_AH_ONLY;
+ break;
+ case QED_LINK_LOOPBACK_INT_PHY_FEA_AH_ONLY:
+ link_params->loopback_mode =
+ ETH_LOOPBACK_INT_PHY_FEA_AH_ONLY;
+ break;
default:
link_params->loopback_mode = ETH_LOOPBACK_NONE;
break;
@@ -1599,6 +1889,9 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
memcpy(&link_params->eee, &params->eee,
sizeof(link_params->eee));
+ if (params->override_flags & QED_LINK_OVERRIDE_FEC_CONFIG)
+ link_params->fec = params->fec;
+
rc = qed_mcp_set_link(hwfn, ptt, params->link_up);
qed_ptt_release(hwfn, ptt);
@@ -1615,7 +1908,6 @@ static int qed_get_port_type(u32 media_type)
case MEDIA_SFP_1G_FIBER:
case MEDIA_XFP_FIBER:
case MEDIA_MODULE_FIBER:
- case MEDIA_KR:
port_type = PORT_FIBRE;
break;
case MEDIA_DA_TWINAX:
@@ -1624,6 +1916,7 @@ static int qed_get_port_type(u32 media_type)
case MEDIA_BASE_T:
port_type = PORT_TP;
break;
+ case MEDIA_KR:
case MEDIA_NOT_PRESENT:
port_type = PORT_NONE;
break;
@@ -1670,7 +1963,7 @@ static int qed_get_link_data(struct qed_hwfn *hwfn,
static void qed_fill_link_capability(struct qed_hwfn *hwfn,
struct qed_ptt *ptt, u32 capability,
- u32 *if_capability)
+ unsigned long *if_caps)
{
u32 media_type, tcvr_state, tcvr_type;
u32 speed_mask, board_cfg;
@@ -1693,122 +1986,215 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,
switch (media_type) {
case MEDIA_DA_TWINAX:
- *if_capability |= QED_LM_FIBRE_BIT;
+ phylink_set(if_caps, FIBRE);
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
- *if_capability |= QED_LM_20000baseKR2_Full_BIT;
- /* For DAC media multiple speed capabilities are supported*/
- capability = capability & speed_mask;
+ phylink_set(if_caps, 20000baseKR2_Full);
+
+ /* For DAC media multiple speed capabilities are supported */
+ capability |= speed_mask;
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
- *if_capability |= QED_LM_1000baseKX_Full_BIT;
+ phylink_set(if_caps, 1000baseKX_Full);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
- *if_capability |= QED_LM_10000baseCR_Full_BIT;
+ phylink_set(if_caps, 10000baseCR_Full);
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
- *if_capability |= QED_LM_40000baseCR4_Full_BIT;
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_40G_CR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR:
+ phylink_set(if_caps, 40000baseCR4_Full);
+ break;
+ default:
+ break;
+ }
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
- *if_capability |= QED_LM_25000baseCR_Full_BIT;
+ phylink_set(if_caps, 25000baseCR_Full);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
- *if_capability |= QED_LM_50000baseCR2_Full_BIT;
+ phylink_set(if_caps, 50000baseCR2_Full);
+
if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
- *if_capability |= QED_LM_100000baseCR4_Full_BIT;
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_100G_CR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR:
+ phylink_set(if_caps, 100000baseCR4_Full);
+ break;
+ default:
+ break;
+ }
+
break;
case MEDIA_BASE_T:
- *if_capability |= QED_LM_TP_BIT;
+ phylink_set(if_caps, TP);
+
if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_EXT_PHY) {
if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) {
- *if_capability |= QED_LM_1000baseT_Full_BIT;
- }
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
+ phylink_set(if_caps, 1000baseT_Full);
if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) {
- *if_capability |= QED_LM_10000baseT_Full_BIT;
- }
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
+ phylink_set(if_caps, 10000baseT_Full);
}
+
if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_MODULE) {
- *if_capability |= QED_LM_FIBRE_BIT;
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_1000BASET)
- *if_capability |= QED_LM_1000baseT_Full_BIT;
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_BASET)
- *if_capability |= QED_LM_10000baseT_Full_BIT;
+ phylink_set(if_caps, FIBRE);
+
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_1000BASET:
+ phylink_set(if_caps, 1000baseT_Full);
+ break;
+ case ETH_TRANSCEIVER_TYPE_10G_BASET:
+ phylink_set(if_caps, 10000baseT_Full);
+ break;
+ default:
+ break;
+ }
}
+
break;
case MEDIA_SFP_1G_FIBER:
case MEDIA_SFPP_10G_FIBER:
case MEDIA_XFP_FIBER:
case MEDIA_MODULE_FIBER:
- *if_capability |= QED_LM_FIBRE_BIT;
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) {
- if ((tcvr_type == ETH_TRANSCEIVER_TYPE_1G_LX) ||
- (tcvr_type == ETH_TRANSCEIVER_TYPE_1G_SX))
- *if_capability |= QED_LM_1000baseKX_Full_BIT;
- }
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) {
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_SR)
- *if_capability |= QED_LM_10000baseSR_Full_BIT;
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LR)
- *if_capability |= QED_LM_10000baseLR_Full_BIT;
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LRM)
- *if_capability |= QED_LM_10000baseLRM_Full_BIT;
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_ER)
- *if_capability |= QED_LM_10000baseR_FEC_BIT;
- }
+ phylink_set(if_caps, FIBRE);
+ capability |= speed_mask;
+
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_1G_LX:
+ case ETH_TRANSCEIVER_TYPE_1G_SX:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
+ phylink_set(if_caps, 1000baseKX_Full);
+ break;
+ default:
+ break;
+ }
+
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_10G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
+ phylink_set(if_caps, 10000baseSR_Full);
+ break;
+ case ETH_TRANSCEIVER_TYPE_10G_LR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
+ phylink_set(if_caps, 10000baseLR_Full);
+ break;
+ case ETH_TRANSCEIVER_TYPE_10G_LRM:
+ phylink_set(if_caps, 10000baseLRM_Full);
+ break;
+ case ETH_TRANSCEIVER_TYPE_10G_ER:
+ phylink_set(if_caps, 10000baseR_FEC);
+ break;
+ default:
+ break;
+ }
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
- *if_capability |= QED_LM_20000baseKR2_Full_BIT;
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) {
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_25G_SR)
- *if_capability |= QED_LM_25000baseSR_Full_BIT;
- }
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) {
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_LR4)
- *if_capability |= QED_LM_40000baseLR4_Full_BIT;
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_SR4)
- *if_capability |= QED_LM_40000baseSR4_Full_BIT;
- }
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
- *if_capability |= QED_LM_50000baseKR2_Full_BIT;
+ phylink_set(if_caps, 20000baseKR2_Full);
+
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_25G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
+ phylink_set(if_caps, 25000baseSR_Full);
+ break;
+ default:
+ break;
+ }
+
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_40G_LR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR:
+ phylink_set(if_caps, 40000baseLR4_Full);
+ break;
+ case ETH_TRANSCEIVER_TYPE_40G_SR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR:
+ phylink_set(if_caps, 40000baseSR4_Full);
+ break;
+ default:
+ break;
+ }
+
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
+ phylink_set(if_caps, 50000baseKR2_Full);
+
if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) {
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_100G_SR4)
- *if_capability |= QED_LM_100000baseSR4_Full_BIT;
- }
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_100G_SR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR:
+ phylink_set(if_caps, 100000baseSR4_Full);
+ break;
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR:
+ phylink_set(if_caps, 100000baseLR4_ER4_Full);
+ break;
+ default:
+ break;
+ }
break;
case MEDIA_KR:
- *if_capability |= QED_LM_Backplane_BIT;
+ phylink_set(if_caps, Backplane);
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
- *if_capability |= QED_LM_20000baseKR2_Full_BIT;
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
- *if_capability |= QED_LM_1000baseKX_Full_BIT;
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
- *if_capability |= QED_LM_10000baseKR_Full_BIT;
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
- *if_capability |= QED_LM_25000baseKR_Full_BIT;
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
- *if_capability |= QED_LM_40000baseKR4_Full_BIT;
- if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
- *if_capability |= QED_LM_50000baseKR2_Full_BIT;
+ phylink_set(if_caps, 20000baseKR2_Full);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
+ phylink_set(if_caps, 1000baseKX_Full);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
+ phylink_set(if_caps, 10000baseKR_Full);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
+ phylink_set(if_caps, 25000baseKR_Full);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
+ phylink_set(if_caps, 40000baseKR4_Full);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
+ phylink_set(if_caps, 50000baseKR2_Full);
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
- *if_capability |= QED_LM_100000baseKR4_Full_BIT;
+ phylink_set(if_caps, 100000baseKR4_Full);
+
break;
case MEDIA_UNSPECIFIED:
case MEDIA_NOT_PRESENT:
+ default:
DP_VERBOSE(hwfn->cdev, QED_MSG_DEBUG,
"Unknown media and transceiver type;\n");
break;
}
}
+static void qed_lp_caps_to_speed_mask(u32 caps, u32 *speed_mask)
+{
+ *speed_mask = 0;
+
+ if (caps &
+ (QED_LINK_PARTNER_SPEED_1G_FD | QED_LINK_PARTNER_SPEED_1G_HD))
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
+ if (caps & QED_LINK_PARTNER_SPEED_10G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
+ if (caps & QED_LINK_PARTNER_SPEED_20G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G;
+ if (caps & QED_LINK_PARTNER_SPEED_25G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G;
+ if (caps & QED_LINK_PARTNER_SPEED_40G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
+ if (caps & QED_LINK_PARTNER_SPEED_50G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G;
+ if (caps & QED_LINK_PARTNER_SPEED_100G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G;
+}
+
static void qed_fill_link(struct qed_hwfn *hwfn,
struct qed_ptt *ptt,
struct qed_link_output *if_link)
@@ -1816,7 +2202,7 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
struct qed_mcp_link_capabilities link_caps;
struct qed_mcp_link_params params;
struct qed_mcp_link_state link;
- u32 media_type;
+ u32 media_type, speed_mask;
memset(if_link, 0, sizeof(*if_link));
@@ -1830,28 +2216,53 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
if (link.link_up)
if_link->link_up = true;
- /* TODO - at the moment assume supported and advertised speed equal */
- if (link_caps.default_speed_autoneg)
- if_link->supported_caps |= QED_LM_Autoneg_BIT;
+ if (IS_PF(hwfn->cdev) && qed_mcp_is_ext_speed_supported(hwfn)) {
+ if (link_caps.default_ext_autoneg)
+ phylink_set(if_link->supported_caps, Autoneg);
+
+ linkmode_copy(if_link->advertised_caps, if_link->supported_caps);
+
+ if (params.ext_speed.autoneg)
+ phylink_set(if_link->advertised_caps, Autoneg);
+ else
+ phylink_clear(if_link->advertised_caps, Autoneg);
+
+ qed_fill_link_capability(hwfn, ptt,
+ params.ext_speed.advertised_speeds,
+ if_link->advertised_caps);
+ } else {
+ if (link_caps.default_speed_autoneg)
+ phylink_set(if_link->supported_caps, Autoneg);
+
+ linkmode_copy(if_link->advertised_caps, if_link->supported_caps);
+
+ if (params.speed.autoneg)
+ phylink_set(if_link->advertised_caps, Autoneg);
+ else
+ phylink_clear(if_link->advertised_caps, Autoneg);
+ }
+
if (params.pause.autoneg ||
(params.pause.forced_rx && params.pause.forced_tx))
- if_link->supported_caps |= QED_LM_Asym_Pause_BIT;
+ phylink_set(if_link->supported_caps, Asym_Pause);
if (params.pause.autoneg || params.pause.forced_rx ||
params.pause.forced_tx)
- if_link->supported_caps |= QED_LM_Pause_BIT;
+ phylink_set(if_link->supported_caps, Pause);
- if_link->advertised_caps = if_link->supported_caps;
- if (params.speed.autoneg)
- if_link->advertised_caps |= QED_LM_Autoneg_BIT;
- else
- if_link->advertised_caps &= ~QED_LM_Autoneg_BIT;
+ if_link->sup_fec = link_caps.fec_default;
+ if_link->active_fec = params.fec;
- /* Fill link advertised capability*/
+ /* Fill link advertised capability */
qed_fill_link_capability(hwfn, ptt, params.speed.advertised_speeds,
- &if_link->advertised_caps);
- /* Fill link supported capability*/
+ if_link->advertised_caps);
+
+ /* Fill link supported capability */
qed_fill_link_capability(hwfn, ptt, link_caps.speed_capabilities,
- &if_link->supported_caps);
+ if_link->supported_caps);
+
+ /* Fill partner advertised capability */
+ qed_lp_caps_to_speed_mask(link.partner_adv_speed, &speed_mask);
+ qed_fill_link_capability(hwfn, ptt, speed_mask, if_link->lp_caps);
if (link.link_up)
if_link->speed = link.speed;
@@ -1870,31 +2281,13 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
if (params.pause.forced_tx)
if_link->pause_config |= QED_LINK_PAUSE_TX_ENABLE;
- /* Link partner capabilities */
- if (link.partner_adv_speed &
- QED_LINK_PARTNER_SPEED_1G_FD)
- if_link->lp_caps |= QED_LM_1000baseT_Full_BIT;
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_10G)
- if_link->lp_caps |= QED_LM_10000baseKR_Full_BIT;
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_20G)
- if_link->lp_caps |= QED_LM_20000baseKR2_Full_BIT;
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_25G)
- if_link->lp_caps |= QED_LM_25000baseKR_Full_BIT;
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_40G)
- if_link->lp_caps |= QED_LM_40000baseLR4_Full_BIT;
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_50G)
- if_link->lp_caps |= QED_LM_50000baseKR2_Full_BIT;
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_100G)
- if_link->lp_caps |= QED_LM_100000baseKR4_Full_BIT;
-
if (link.an_complete)
- if_link->lp_caps |= QED_LM_Autoneg_BIT;
-
+ phylink_set(if_link->lp_caps, Autoneg);
if (link.partner_adv_pause)
- if_link->lp_caps |= QED_LM_Pause_BIT;
+ phylink_set(if_link->lp_caps, Pause);
if (link.partner_adv_pause == QED_LINK_PARTNER_ASYMMETRIC_PAUSE ||
link.partner_adv_pause == QED_LINK_PARTNER_BOTH_PAUSE)
- if_link->lp_caps |= QED_LM_Asym_Pause_BIT;
+ phylink_set(if_link->lp_caps, Asym_Pause);
if (link_caps.default_eee == QED_MCP_EEE_UNSUPPORTED) {
if_link->eee_supported = false;
@@ -1988,8 +2381,7 @@ static u32 qed_nvm_flash_image_access_crc(struct qed_dev *cdev,
u32 *crc)
{
u8 *buf = NULL;
- int rc, j;
- u32 val;
+ int rc;
/* Allocate a buffer for holding the nvram image */
buf = kzalloc(nvm_image->length, GFP_KERNEL);
@@ -2007,15 +2399,14 @@ static u32 qed_nvm_flash_image_access_crc(struct qed_dev *cdev,
/* Convert the buffer into big-endian format (excluding the
* closing 4 bytes of CRC).
*/
- for (j = 0; j < nvm_image->length - 4; j += 4) {
- val = cpu_to_be32(*(u32 *)&buf[j]);
- *(u32 *)&buf[j] = val;
- }
+ cpu_to_be32_array((__force __be32 *)buf, (const u32 *)buf,
+ DIV_ROUND_UP(nvm_image->length - 4, 4));
/* Calc CRC for the "actual" image buffer, i.e. not including
* the last 4 CRC bytes.
*/
- *crc = (~cpu_to_be32(crc32(0xffffffff, buf, nvm_image->length - 4)));
+ *crc = ~crc32(~0U, buf, nvm_image->length - 4);
+ *crc = (__force u32)cpu_to_be32p(crc);
out:
kfree(buf);
@@ -2477,7 +2868,7 @@ void qed_schedule_recovery_handler(struct qed_hwfn *p_hwfn)
ops->schedule_recovery_handler(cookie);
}
-char *qed_hw_err_type_descr[] = {
+static const char * const qed_hw_err_type_descr[] = {
[QED_HW_ERR_FAN_FAIL] = "Fan Failure",
[QED_HW_ERR_MFW_RESP_FAIL] = "MFW Response Failure",
[QED_HW_ERR_HW_ATTN] = "HW Attention",
@@ -2492,7 +2883,7 @@ void qed_hw_error_occurred(struct qed_hwfn *p_hwfn,
{
struct qed_common_cb_ops *ops = p_hwfn->cdev->protocol_ops.common;
void *cookie = p_hwfn->cdev->ops_cookie;
- char *err_str;
+ const char *err_str;
if (err_type > QED_HW_ERR_LAST)
err_type = QED_HW_ERR_LAST;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 0fd4520d0666..5be08f83e0aa 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -1472,6 +1446,25 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE)
qed_mcp_read_eee_config(p_hwfn, p_ptt, p_link);
+ if (p_hwfn->mcp_info->capabilities &
+ FW_MB_PARAM_FEATURE_SUPPORT_FEC_CONTROL) {
+ switch (status & LINK_STATUS_FEC_MODE_MASK) {
+ case LINK_STATUS_FEC_MODE_NONE:
+ p_link->fec_active = QED_FEC_MODE_NONE;
+ break;
+ case LINK_STATUS_FEC_MODE_FIRECODE_CL74:
+ p_link->fec_active = QED_FEC_MODE_FIRECODE;
+ break;
+ case LINK_STATUS_FEC_MODE_RS_CL91:
+ p_link->fec_active = QED_FEC_MODE_RS;
+ break;
+ default:
+ p_link->fec_active = QED_FEC_MODE_AUTO;
+ }
+ } else {
+ p_link->fec_active = QED_FEC_MODE_UNSUPPORTED;
+ }
+
qed_link_update(p_hwfn, p_ptt);
out:
spin_unlock_bh(&p_hwfn->mcp_info->link_lock);
@@ -1482,8 +1475,9 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool b_up)
struct qed_mcp_link_params *params = &p_hwfn->mcp_info->link_input;
struct qed_mcp_mb_params mb_params;
struct eth_phy_cfg phy_cfg;
+ u32 cmd, fec_bit = 0;
+ u32 val, ext_speed;
int rc = 0;
- u32 cmd;
/* Set the shmem configuration according to params */
memset(&phy_cfg, 0, sizeof(phy_cfg));
@@ -1515,19 +1509,91 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool b_up)
EEE_TX_TIMER_USEC_MASK;
}
+ if (p_hwfn->mcp_info->capabilities &
+ FW_MB_PARAM_FEATURE_SUPPORT_FEC_CONTROL) {
+ if (params->fec & QED_FEC_MODE_NONE)
+ fec_bit |= FEC_FORCE_MODE_NONE;
+ else if (params->fec & QED_FEC_MODE_FIRECODE)
+ fec_bit |= FEC_FORCE_MODE_FIRECODE;
+ else if (params->fec & QED_FEC_MODE_RS)
+ fec_bit |= FEC_FORCE_MODE_RS;
+ else if (params->fec & QED_FEC_MODE_AUTO)
+ fec_bit |= FEC_FORCE_MODE_AUTO;
+
+ SET_MFW_FIELD(phy_cfg.fec_mode, FEC_FORCE_MODE, fec_bit);
+ }
+
+ if (p_hwfn->mcp_info->capabilities &
+ FW_MB_PARAM_FEATURE_SUPPORT_EXT_SPEED_FEC_CONTROL) {
+ ext_speed = 0;
+ if (params->ext_speed.autoneg)
+ ext_speed |= ETH_EXT_SPEED_AN;
+
+ val = params->ext_speed.forced_speed;
+ if (val & QED_EXT_SPEED_1G)
+ ext_speed |= ETH_EXT_SPEED_1G;
+ if (val & QED_EXT_SPEED_10G)
+ ext_speed |= ETH_EXT_SPEED_10G;
+ if (val & QED_EXT_SPEED_20G)
+ ext_speed |= ETH_EXT_SPEED_20G;
+ if (val & QED_EXT_SPEED_25G)
+ ext_speed |= ETH_EXT_SPEED_25G;
+ if (val & QED_EXT_SPEED_40G)
+ ext_speed |= ETH_EXT_SPEED_40G;
+ if (val & QED_EXT_SPEED_50G_R)
+ ext_speed |= ETH_EXT_SPEED_50G_BASE_R;
+ if (val & QED_EXT_SPEED_50G_R2)
+ ext_speed |= ETH_EXT_SPEED_50G_BASE_R2;
+ if (val & QED_EXT_SPEED_100G_R2)
+ ext_speed |= ETH_EXT_SPEED_100G_BASE_R2;
+ if (val & QED_EXT_SPEED_100G_R4)
+ ext_speed |= ETH_EXT_SPEED_100G_BASE_R4;
+ if (val & QED_EXT_SPEED_100G_P4)
+ ext_speed |= ETH_EXT_SPEED_100G_BASE_P4;
+
+ SET_MFW_FIELD(phy_cfg.extended_speed, ETH_EXT_SPEED,
+ ext_speed);
+
+ ext_speed = 0;
+
+ val = params->ext_speed.advertised_speeds;
+ if (val & QED_EXT_SPEED_MASK_1G)
+ ext_speed |= ETH_EXT_ADV_SPEED_1G;
+ if (val & QED_EXT_SPEED_MASK_10G)
+ ext_speed |= ETH_EXT_ADV_SPEED_10G;
+ if (val & QED_EXT_SPEED_MASK_20G)
+ ext_speed |= ETH_EXT_ADV_SPEED_20G;
+ if (val & QED_EXT_SPEED_MASK_25G)
+ ext_speed |= ETH_EXT_ADV_SPEED_25G;
+ if (val & QED_EXT_SPEED_MASK_40G)
+ ext_speed |= ETH_EXT_ADV_SPEED_40G;
+ if (val & QED_EXT_SPEED_MASK_50G_R)
+ ext_speed |= ETH_EXT_ADV_SPEED_50G_BASE_R;
+ if (val & QED_EXT_SPEED_MASK_50G_R2)
+ ext_speed |= ETH_EXT_ADV_SPEED_50G_BASE_R2;
+ if (val & QED_EXT_SPEED_MASK_100G_R2)
+ ext_speed |= ETH_EXT_ADV_SPEED_100G_BASE_R2;
+ if (val & QED_EXT_SPEED_MASK_100G_R4)
+ ext_speed |= ETH_EXT_ADV_SPEED_100G_BASE_R4;
+ if (val & QED_EXT_SPEED_MASK_100G_P4)
+ ext_speed |= ETH_EXT_ADV_SPEED_100G_BASE_P4;
+
+ phy_cfg.extended_speed |= ext_speed;
+
+ SET_MFW_FIELD(phy_cfg.fec_mode, FEC_EXTENDED_MODE,
+ params->ext_fec_mode);
+ }
+
p_hwfn->b_drv_link_init = b_up;
if (b_up) {
DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
- "Configuring Link: Speed 0x%08x, Pause 0x%08x, adv_speed 0x%08x, loopback 0x%08x, features 0x%08x\n",
- phy_cfg.speed,
- phy_cfg.pause,
- phy_cfg.adv_speed,
- phy_cfg.loopback_mode,
- phy_cfg.feature_config_flags);
+ "Configuring Link: Speed 0x%08x, Pause 0x%08x, Adv. Speed 0x%08x, Loopback 0x%08x, FEC 0x%08x, Ext. Speed 0x%08x\n",
+ phy_cfg.speed, phy_cfg.pause, phy_cfg.adv_speed,
+ phy_cfg.loopback_mode, phy_cfg.fec_mode,
+ phy_cfg.extended_speed);
} else {
- DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
- "Resetting link\n");
+ DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, "Resetting link\n");
}
memset(&mb_params, 0, sizeof(mb_params));
@@ -2219,6 +2285,11 @@ int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn,
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break;
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR:
+ *p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G |
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
+ break;
case ETH_TRANSCEIVER_TYPE_40G_CR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G |
@@ -2249,8 +2320,10 @@ int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn,
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
break;
case ETH_TRANSCEIVER_TYPE_10G_BASET:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break;
default:
DP_INFO(p_hwfn, "Unknown transceiver type 0x%x\n",
@@ -2445,11 +2518,10 @@ int qed_mcp_fill_shmem_func_info(struct qed_hwfn *p_hwfn,
}
DP_VERBOSE(p_hwfn, (QED_MSG_SP | NETIF_MSG_IFUP),
- "Read configuration from shmem: pause_on_host %02x protocol %02x BW [%02x - %02x] MAC %02x:%02x:%02x:%02x:%02x:%02x wwn port %llx node %llx ovlan %04x wol %02x\n",
+ "Read configuration from shmem: pause_on_host %02x protocol %02x BW [%02x - %02x] MAC %pM wwn port %llx node %llx ovlan %04x wol %02x\n",
info->pause_on_host, info->protocol,
info->bandwidth_min, info->bandwidth_max,
- info->mac[0], info->mac[1], info->mac[2],
- info->mac[3], info->mac[4], info->mac[5],
+ info->mac,
info->wwn_port, info->wwn_node,
info->ovlan, (u8)p_hwfn->hw_info.b_wol_support);
@@ -3824,7 +3896,12 @@ int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
u32 mcp_resp, mcp_param, features;
features = DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE |
- DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK;
+ DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK |
+ DRV_MB_PARAM_FEATURE_SUPPORT_PORT_FEC_CONTROL;
+
+ if (QED_IS_E5(p_hwfn->cdev))
+ features |=
+ DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EXT_SPEED_FEC_CONTROL;
return qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_FEATURE_SUPPORT,
features, &mcp_resp, &mcp_param);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
index 12a705ed4bac..8edb450d0abf 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_MCP_H
@@ -42,15 +16,38 @@
#include "qed_dev_api.h"
struct qed_mcp_link_speed_params {
- bool autoneg;
- u32 advertised_speeds; /* bitmask of DRV_SPEED_CAPABILITY */
- u32 forced_speed; /* In Mb/s */
+ bool autoneg;
+
+ u32 advertised_speeds;
+#define QED_EXT_SPEED_MASK_RES 0x1
+#define QED_EXT_SPEED_MASK_1G 0x2
+#define QED_EXT_SPEED_MASK_10G 0x4
+#define QED_EXT_SPEED_MASK_20G 0x8
+#define QED_EXT_SPEED_MASK_25G 0x10
+#define QED_EXT_SPEED_MASK_40G 0x20
+#define QED_EXT_SPEED_MASK_50G_R 0x40
+#define QED_EXT_SPEED_MASK_50G_R2 0x80
+#define QED_EXT_SPEED_MASK_100G_R2 0x100
+#define QED_EXT_SPEED_MASK_100G_R4 0x200
+#define QED_EXT_SPEED_MASK_100G_P4 0x400
+
+ u32 forced_speed; /* In Mb/s */
+#define QED_EXT_SPEED_1G 0x1
+#define QED_EXT_SPEED_10G 0x2
+#define QED_EXT_SPEED_20G 0x4
+#define QED_EXT_SPEED_25G 0x8
+#define QED_EXT_SPEED_40G 0x10
+#define QED_EXT_SPEED_50G_R 0x20
+#define QED_EXT_SPEED_50G_R2 0x40
+#define QED_EXT_SPEED_100G_R2 0x80
+#define QED_EXT_SPEED_100G_R4 0x100
+#define QED_EXT_SPEED_100G_P4 0x200
};
struct qed_mcp_link_pause_params {
- bool autoneg;
- bool forced_rx;
- bool forced_tx;
+ bool autoneg;
+ bool forced_rx;
+ bool forced_tx;
};
enum qed_mcp_eee_mode {
@@ -60,61 +57,72 @@ enum qed_mcp_eee_mode {
};
struct qed_mcp_link_params {
- struct qed_mcp_link_speed_params speed;
- struct qed_mcp_link_pause_params pause;
- u32 loopback_mode;
- struct qed_link_eee_params eee;
+ struct qed_mcp_link_speed_params speed;
+ struct qed_mcp_link_pause_params pause;
+ u32 loopback_mode;
+ struct qed_link_eee_params eee;
+ u32 fec;
+
+ struct qed_mcp_link_speed_params ext_speed;
+ u32 ext_fec_mode;
};
struct qed_mcp_link_capabilities {
- u32 speed_capabilities;
- bool default_speed_autoneg;
- enum qed_mcp_eee_mode default_eee;
- u32 eee_lpi_timer;
- u8 eee_speed_caps;
+ u32 speed_capabilities;
+ bool default_speed_autoneg;
+ u32 fec_default;
+ enum qed_mcp_eee_mode default_eee;
+ u32 eee_lpi_timer;
+ u8 eee_speed_caps;
+
+ u32 default_ext_speed_caps;
+ u32 default_ext_autoneg;
+ u32 default_ext_speed;
+ u32 default_ext_fec;
};
struct qed_mcp_link_state {
- bool link_up;
-
- u32 min_pf_rate;
+ bool link_up;
+ u32 min_pf_rate;
/* Actual link speed in Mb/s */
- u32 line_speed;
+ u32 line_speed;
/* PF max speed in Mb/s, deduced from line_speed
* according to PF max bandwidth configuration.
*/
- u32 speed;
- bool full_duplex;
-
- bool an;
- bool an_complete;
- bool parallel_detection;
- bool pfc_enabled;
-
-#define QED_LINK_PARTNER_SPEED_1G_HD BIT(0)
-#define QED_LINK_PARTNER_SPEED_1G_FD BIT(1)
-#define QED_LINK_PARTNER_SPEED_10G BIT(2)
-#define QED_LINK_PARTNER_SPEED_20G BIT(3)
-#define QED_LINK_PARTNER_SPEED_25G BIT(4)
-#define QED_LINK_PARTNER_SPEED_40G BIT(5)
-#define QED_LINK_PARTNER_SPEED_50G BIT(6)
-#define QED_LINK_PARTNER_SPEED_100G BIT(7)
- u32 partner_adv_speed;
-
- bool partner_tx_flow_ctrl_en;
- bool partner_rx_flow_ctrl_en;
-
-#define QED_LINK_PARTNER_SYMMETRIC_PAUSE (1)
-#define QED_LINK_PARTNER_ASYMMETRIC_PAUSE (2)
-#define QED_LINK_PARTNER_BOTH_PAUSE (3)
- u8 partner_adv_pause;
-
- bool sfp_tx_fault;
- bool eee_active;
- u8 eee_adv_caps;
- u8 eee_lp_adv_caps;
+ u32 speed;
+
+ bool full_duplex;
+ bool an;
+ bool an_complete;
+ bool parallel_detection;
+ bool pfc_enabled;
+
+ u32 partner_adv_speed;
+#define QED_LINK_PARTNER_SPEED_1G_HD BIT(0)
+#define QED_LINK_PARTNER_SPEED_1G_FD BIT(1)
+#define QED_LINK_PARTNER_SPEED_10G BIT(2)
+#define QED_LINK_PARTNER_SPEED_20G BIT(3)
+#define QED_LINK_PARTNER_SPEED_25G BIT(4)
+#define QED_LINK_PARTNER_SPEED_40G BIT(5)
+#define QED_LINK_PARTNER_SPEED_50G BIT(6)
+#define QED_LINK_PARTNER_SPEED_100G BIT(7)
+
+ bool partner_tx_flow_ctrl_en;
+ bool partner_rx_flow_ctrl_en;
+
+ u8 partner_adv_pause;
+#define QED_LINK_PARTNER_SYMMETRIC_PAUSE 0x1
+#define QED_LINK_PARTNER_ASYMMETRIC_PAUSE 0x2
+#define QED_LINK_PARTNER_BOTH_PAUSE 0x3
+
+ bool sfp_tx_fault;
+ bool eee_active;
+ u8 eee_adv_caps;
+ u8 eee_lp_adv_caps;
+
+ u32 fec_active;
};
struct qed_mcp_function_info {
@@ -774,6 +782,20 @@ struct qed_drv_tlv_hdr {
};
/**
+ * qed_mcp_is_ext_speed_supported() - Check if management firmware supports
+ * extended speeds.
+ * @p_hwfn: HW device data.
+ *
+ * Return: true if supported, false otherwise.
+ */
+static inline bool
+qed_mcp_is_ext_speed_supported(const struct qed_hwfn *p_hwfn)
+{
+ return !!(p_hwfn->mcp_info->capabilities &
+ FW_MB_PARAM_FEATURE_SUPPORT_EXT_SPEED_FEC_CONTROL);
+}
+
+/**
* @brief Initialize the interface with the MCP
*
* @param p_hwfn - HW func
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c b/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c
index 6c16158d8090..3e3192a3ad9b 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c
@@ -1,4 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/* Copyright (c) 2019-2020 Marvell International Ltd. */
+
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/bug.h>
@@ -1274,7 +1276,7 @@ int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
*/
for (offset = 0; offset < size; offset += sizeof(u32)) {
val = qed_rd(p_hwfn, p_ptt, addr + offset);
- val = be32_to_cpu(val);
+ val = be32_to_cpu((__force __be32)val);
memcpy(&p_mfw_buf[offset], &val, sizeof(u32));
}
@@ -1323,7 +1325,7 @@ int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
*/
for (offset = 0; offset < size; offset += sizeof(u32)) {
memcpy(&val, &p_mfw_buf[offset], sizeof(u32));
- val = cpu_to_be32(val);
+ val = (__force u32)cpu_to_be32(val);
qed_wr(p_hwfn, p_ptt, addr + offset, val);
}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ooo.c b/drivers/net/ethernet/qlogic/qed/qed_ooo.c
index ffac4ac87394..88353aa404dc 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ooo.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ooo.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ooo.h b/drivers/net/ethernet/qlogic/qed/qed_ooo.h
index 49c4e75b15b1..3a7e1b59d6fc 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ooo.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_ooo.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_OOO_H
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ptp.c b/drivers/net/ethernet/qlogic/qed/qed_ptp.c
index 3e613058e225..2c62d732e5c2 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ptp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ptp.c
@@ -1,40 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include <linux/types.h>
#include "qed.h"
#include "qed_dev_api.h"
#include "qed_hw.h"
#include "qed_l2.h"
#include "qed_mcp.h"
+#include "qed_ptp.h"
#include "qed_reg_addr.h"
/* 16 nano second time quantas to wait before making a Drift adjustment */
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ptp.h b/drivers/net/ethernet/qlogic/qed/qed_ptp.h
new file mode 100644
index 000000000000..40a11c0e1185
--- /dev/null
+++ b/drivers/net/ethernet/qlogic/qed/qed_ptp.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/* Copyright (c) 2020 Marvell International Ltd. */
+
+#ifndef __QED_PTP_H
+#define __QED_PTP_H
+
+extern const struct qed_eth_ptp_ops qed_ptp_ops_pass;
+
+#endif /* __QED_PTP_H */
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
index 19c0c8864da1..a4bcde522cdf 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
@@ -1,34 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/bitops.h>
@@ -404,6 +379,7 @@ static void qed_rdma_resc_free(struct qed_hwfn *p_hwfn)
qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->srq_map, 1);
qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->real_cid_map, 1);
qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->xrc_srq_map, 1);
+ qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->xrcd_map, 1);
kfree(p_rdma_info->port);
kfree(p_rdma_info->dev);
@@ -1131,7 +1107,7 @@ static int qed_rdma_create_cq(void *rdma_cxt,
p_ramrod->pbl_num_pages = cpu_to_le16(params->pbl_num_pages);
p_ramrod->cnq_id = (u8)RESC_START(p_hwfn, QED_RDMA_CNQ_RAM) +
params->cnq_id;
- p_ramrod->int_timeout = params->int_timeout;
+ p_ramrod->int_timeout = cpu_to_le16(params->int_timeout);
/* toggle the bit for every resize or create cq for a given icid */
toggle_bit = qed_rdma_toggle_bit_create_resize_cq(p_hwfn, *icid);
@@ -1231,7 +1207,7 @@ err: dma_free_coherent(&p_hwfn->cdev->pdev->dev,
return rc;
}
-void qed_rdma_set_fw_mac(u16 *p_fw_mac, u8 *p_qed_mac)
+void qed_rdma_set_fw_mac(__le16 *p_fw_mac, const u8 *p_qed_mac)
{
p_fw_mac[0] = cpu_to_le16((p_qed_mac[0] << 8) + p_qed_mac[1]);
p_fw_mac[1] = cpu_to_le16((p_qed_mac[2] << 8) + p_qed_mac[3]);
@@ -1520,6 +1496,7 @@ qed_rdma_register_tid(void *rdma_cxt,
struct qed_spq_entry *p_ent;
enum rdma_tid_type tid_type;
u8 fw_return_code;
+ u16 flags = 0;
int rc;
DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "itid = %08x\n", params->itid);
@@ -1539,54 +1516,46 @@ qed_rdma_register_tid(void *rdma_cxt,
if (p_hwfn->p_rdma_info->last_tid < params->itid)
p_hwfn->p_rdma_info->last_tid = params->itid;
- p_ramrod = &p_ent->ramrod.rdma_register_tid;
-
- p_ramrod->flags = 0;
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_TWO_LEVEL_PBL,
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_TWO_LEVEL_PBL,
params->pbl_two_level);
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_ZERO_BASED, params->zbva);
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_ZERO_BASED,
+ params->zbva);
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_PHY_MR, params->phy_mr);
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_PHY_MR, params->phy_mr);
/* Don't initialize D/C field, as it may override other bits. */
if (!(params->tid_type == QED_RDMA_TID_FMR) && !(params->dma_mr))
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_PAGE_SIZE_LOG,
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_PAGE_SIZE_LOG,
params->page_size_log - 12);
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_REMOTE_READ,
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_REMOTE_READ,
params->remote_read);
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_REMOTE_WRITE,
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_REMOTE_WRITE,
params->remote_write);
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_REMOTE_ATOMIC,
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_REMOTE_ATOMIC,
params->remote_atomic);
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_LOCAL_WRITE,
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_LOCAL_WRITE,
params->local_write);
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_LOCAL_READ, params->local_read);
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_LOCAL_READ,
+ params->local_read);
- SET_FIELD(p_ramrod->flags,
- RDMA_REGISTER_TID_RAMROD_DATA_ENABLE_MW_BIND,
+ SET_FIELD(flags, RDMA_REGISTER_TID_RAMROD_DATA_ENABLE_MW_BIND,
params->mw_bind);
+ p_ramrod = &p_ent->ramrod.rdma_register_tid;
+ p_ramrod->flags = cpu_to_le16(flags);
+
SET_FIELD(p_ramrod->flags1,
RDMA_REGISTER_TID_RAMROD_DATA_PBL_PAGE_SIZE_LOG,
params->pbl_page_size_log - 12);
- SET_FIELD(p_ramrod->flags2,
- RDMA_REGISTER_TID_RAMROD_DATA_DMA_MR, params->dma_mr);
+ SET_FIELD(p_ramrod->flags2, RDMA_REGISTER_TID_RAMROD_DATA_DMA_MR,
+ params->dma_mr);
switch (params->tid_type) {
case QED_RDMA_TID_REGISTERED_MR:
@@ -1604,8 +1573,9 @@ qed_rdma_register_tid(void *rdma_cxt,
qed_sp_destroy_request(p_hwfn, p_ent);
return rc;
}
- SET_FIELD(p_ramrod->flags1,
- RDMA_REGISTER_TID_RAMROD_DATA_TID_TYPE, tid_type);
+
+ SET_FIELD(p_ramrod->flags1, RDMA_REGISTER_TID_RAMROD_DATA_TID_TYPE,
+ tid_type);
p_ramrod->itid = cpu_to_le32(params->itid);
p_ramrod->key = params->key;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.h b/drivers/net/ethernet/qlogic/qed/qed_rdma.h
index 1e69d5bb0a70..6a1de3a25257 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.h
@@ -1,34 +1,9 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#ifndef _QED_RDMA_H
#define _QED_RDMA_H
#include <linux/types.h>
@@ -226,7 +201,7 @@ qed_bmap_release_id(struct qed_hwfn *p_hwfn, struct qed_bmap *bmap, u32 id_num);
int
qed_bmap_test_id(struct qed_hwfn *p_hwfn, struct qed_bmap *bmap, u32 id_num);
-void qed_rdma_set_fw_mac(u16 *p_fw_mac, u8 *p_qed_mac);
+void qed_rdma_set_fw_mac(__le16 *p_fw_mac, const u8 *p_qed_mac);
bool qed_rdma_allocated_qps(struct qed_hwfn *p_hwfn);
#endif
diff --git a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
index 3dcb6ff58e73..9db22be42476 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef REG_ADDR_H
diff --git a/drivers/net/ethernet/qlogic/qed/qed_roce.c b/drivers/net/ethernet/qlogic/qed/qed_roce.c
index 7271dd7166e5..f16a157bb95a 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_roce.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c
@@ -1,34 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/bitops.h>
@@ -62,35 +37,30 @@
static void qed_roce_free_real_icid(struct qed_hwfn *p_hwfn, u16 icid);
-static int
-qed_roce_async_event(struct qed_hwfn *p_hwfn,
- u8 fw_event_code,
- u16 echo, union event_ring_data *data, u8 fw_return_code)
+static int qed_roce_async_event(struct qed_hwfn *p_hwfn, u8 fw_event_code,
+ __le16 echo, union event_ring_data *data,
+ u8 fw_return_code)
{
struct qed_rdma_events events = p_hwfn->p_rdma_info->events;
+ union rdma_eqe_data *rdata = &data->rdma_data;
if (fw_event_code == ROCE_ASYNC_EVENT_DESTROY_QP_DONE) {
- u16 icid =
- (u16)le32_to_cpu(data->rdma_data.rdma_destroy_qp_data.cid);
+ u16 icid = (u16)le32_to_cpu(rdata->rdma_destroy_qp_data.cid);
/* icid release in this async event can occur only if the icid
* was offloaded to the FW. In case it wasn't offloaded this is
* handled in qed_roce_sp_destroy_qp.
*/
qed_roce_free_real_icid(p_hwfn, icid);
- } else {
- if (fw_event_code == ROCE_ASYNC_EVENT_SRQ_EMPTY ||
- fw_event_code == ROCE_ASYNC_EVENT_SRQ_LIMIT) {
- u16 srq_id = (u16)data->rdma_data.async_handle.lo;
+ } else if (fw_event_code == ROCE_ASYNC_EVENT_SRQ_EMPTY ||
+ fw_event_code == ROCE_ASYNC_EVENT_SRQ_LIMIT) {
+ u16 srq_id = (u16)le32_to_cpu(rdata->async_handle.lo);
- events.affiliated_event(events.context, fw_event_code,
- &srq_id);
- } else {
- union rdma_eqe_data rdata = data->rdma_data;
-
- events.affiliated_event(events.context, fw_event_code,
- (void *)&rdata.async_handle);
- }
+ events.affiliated_event(events.context, fw_event_code,
+ &srq_id);
+ } else {
+ events.affiliated_event(events.context, fw_event_code,
+ (void *)&rdata->async_handle);
}
return 0;
@@ -247,9 +217,9 @@ static int qed_roce_sp_create_responder(struct qed_hwfn *p_hwfn,
struct roce_create_qp_resp_ramrod_data *p_ramrod;
u16 regular_latency_queue, low_latency_queue;
struct qed_sp_init_data init_data;
- enum roce_flavor roce_flavor;
struct qed_spq_entry *p_ent;
enum protocol_type proto;
+ u32 flags = 0;
int rc;
u8 tc;
@@ -282,45 +252,34 @@ static int qed_roce_sp_create_responder(struct qed_hwfn *p_hwfn,
if (rc)
goto err;
- p_ramrod = &p_ent->ramrod.roce_create_qp_resp;
-
- p_ramrod->flags = 0;
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_ROCE_FLAVOR,
+ qed_roce_mode_to_flavor(qp->roce_mode));
- roce_flavor = qed_roce_mode_to_flavor(qp->roce_mode);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_ROCE_FLAVOR, roce_flavor);
-
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_RDMA_RD_EN,
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_RDMA_RD_EN,
qp->incoming_rdma_read_en);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_RDMA_WR_EN,
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_RDMA_WR_EN,
qp->incoming_rdma_write_en);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_ATOMIC_EN,
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_ATOMIC_EN,
qp->incoming_atomic_en);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_E2E_FLOW_CONTROL_EN,
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_E2E_FLOW_CONTROL_EN,
qp->e2e_flow_control_en);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_SRQ_FLG, qp->use_srq);
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_SRQ_FLG, qp->use_srq);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_RESERVED_KEY_EN,
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_RESERVED_KEY_EN,
qp->fmr_and_reserved_lkey);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_MIN_RNR_NAK_TIMER,
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_MIN_RNR_NAK_TIMER,
qp->min_rnr_nak_timer);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_XRC_FLAG,
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_XRC_FLAG,
qed_rdma_is_xrc_qp(qp));
+ p_ramrod = &p_ent->ramrod.roce_create_qp_resp;
+ p_ramrod->flags = cpu_to_le32(flags);
p_ramrod->max_ird = qp->max_rd_atomic_resp;
p_ramrod->traffic_class = qp->traffic_class_tos;
p_ramrod->hop_limit = qp->hop_limit_ttl;
@@ -335,10 +294,10 @@ static int qed_roce_sp_create_responder(struct qed_hwfn *p_hwfn,
DMA_REGPAIR_LE(p_ramrod->rq_pbl_addr, qp->rq_pbl_ptr);
DMA_REGPAIR_LE(p_ramrod->irq_pbl_addr, qp->irq_phys_addr);
qed_rdma_copy_gids(qp, p_ramrod->src_gid, p_ramrod->dst_gid);
- p_ramrod->qp_handle_for_async.hi = cpu_to_le32(qp->qp_handle_async.hi);
- p_ramrod->qp_handle_for_async.lo = cpu_to_le32(qp->qp_handle_async.lo);
- p_ramrod->qp_handle_for_cqe.hi = cpu_to_le32(qp->qp_handle.hi);
- p_ramrod->qp_handle_for_cqe.lo = cpu_to_le32(qp->qp_handle.lo);
+ p_ramrod->qp_handle_for_async.hi = qp->qp_handle_async.hi;
+ p_ramrod->qp_handle_for_async.lo = qp->qp_handle_async.lo;
+ p_ramrod->qp_handle_for_cqe.hi = qp->qp_handle.hi;
+ p_ramrod->qp_handle_for_cqe.lo = qp->qp_handle.lo;
p_ramrod->cq_cid = cpu_to_le32((p_hwfn->hw_info.opaque_fid << 16) |
qp->rq_cq_id);
p_ramrod->xrc_domain = cpu_to_le16(qp->xrcd_id);
@@ -360,7 +319,7 @@ static int qed_roce_sp_create_responder(struct qed_hwfn *p_hwfn,
qed_rdma_set_fw_mac(p_ramrod->remote_mac_addr, qp->remote_mac_addr);
qed_rdma_set_fw_mac(p_ramrod->local_mac_addr, qp->local_mac_addr);
- p_ramrod->udp_src_port = qp->udp_src_port;
+ p_ramrod->udp_src_port = cpu_to_le16(qp->udp_src_port);
p_ramrod->vlan_id = cpu_to_le16(qp->vlan_id);
p_ramrod->srq_id.srq_idx = cpu_to_le16(qp->srq_id);
p_ramrod->srq_id.opaque_fid = cpu_to_le16(p_hwfn->hw_info.opaque_fid);
@@ -396,9 +355,9 @@ static int qed_roce_sp_create_requester(struct qed_hwfn *p_hwfn,
struct roce_create_qp_req_ramrod_data *p_ramrod;
u16 regular_latency_queue, low_latency_queue;
struct qed_sp_init_data init_data;
- enum roce_flavor roce_flavor;
struct qed_spq_entry *p_ent;
enum protocol_type proto;
+ u16 flags = 0;
int rc;
u8 tc;
@@ -432,34 +391,29 @@ static int qed_roce_sp_create_requester(struct qed_hwfn *p_hwfn,
if (rc)
goto err;
- p_ramrod = &p_ent->ramrod.roce_create_qp_req;
-
- p_ramrod->flags = 0;
+ SET_FIELD(flags, ROCE_CREATE_QP_REQ_RAMROD_DATA_ROCE_FLAVOR,
+ qed_roce_mode_to_flavor(qp->roce_mode));
- roce_flavor = qed_roce_mode_to_flavor(qp->roce_mode);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_REQ_RAMROD_DATA_ROCE_FLAVOR, roce_flavor);
-
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_REQ_RAMROD_DATA_FMR_AND_RESERVED_EN,
+ SET_FIELD(flags, ROCE_CREATE_QP_REQ_RAMROD_DATA_FMR_AND_RESERVED_EN,
qp->fmr_and_reserved_lkey);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_REQ_RAMROD_DATA_SIGNALED_COMP, qp->signal_all);
+ SET_FIELD(flags, ROCE_CREATE_QP_REQ_RAMROD_DATA_SIGNALED_COMP,
+ qp->signal_all);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_REQ_RAMROD_DATA_ERR_RETRY_CNT, qp->retry_cnt);
+ SET_FIELD(flags, ROCE_CREATE_QP_REQ_RAMROD_DATA_ERR_RETRY_CNT,
+ qp->retry_cnt);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_REQ_RAMROD_DATA_RNR_NAK_CNT,
+ SET_FIELD(flags, ROCE_CREATE_QP_REQ_RAMROD_DATA_RNR_NAK_CNT,
qp->rnr_retry_cnt);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_REQ_RAMROD_DATA_XRC_FLAG,
+ SET_FIELD(flags, ROCE_CREATE_QP_REQ_RAMROD_DATA_XRC_FLAG,
qed_rdma_is_xrc_qp(qp));
- SET_FIELD(p_ramrod->flags2,
- ROCE_CREATE_QP_REQ_RAMROD_DATA_EDPM_MODE, qp->edpm_mode);
+ p_ramrod = &p_ent->ramrod.roce_create_qp_req;
+ p_ramrod->flags = cpu_to_le16(flags);
+
+ SET_FIELD(p_ramrod->flags2, ROCE_CREATE_QP_REQ_RAMROD_DATA_EDPM_MODE,
+ qp->edpm_mode);
p_ramrod->max_ord = qp->max_rd_atomic_req;
p_ramrod->traffic_class = qp->traffic_class_tos;
@@ -476,10 +430,10 @@ static int qed_roce_sp_create_requester(struct qed_hwfn *p_hwfn,
DMA_REGPAIR_LE(p_ramrod->sq_pbl_addr, qp->sq_pbl_ptr);
DMA_REGPAIR_LE(p_ramrod->orq_pbl_addr, qp->orq_phys_addr);
qed_rdma_copy_gids(qp, p_ramrod->src_gid, p_ramrod->dst_gid);
- p_ramrod->qp_handle_for_async.hi = cpu_to_le32(qp->qp_handle_async.hi);
- p_ramrod->qp_handle_for_async.lo = cpu_to_le32(qp->qp_handle_async.lo);
- p_ramrod->qp_handle_for_cqe.hi = cpu_to_le32(qp->qp_handle.hi);
- p_ramrod->qp_handle_for_cqe.lo = cpu_to_le32(qp->qp_handle.lo);
+ p_ramrod->qp_handle_for_async.hi = qp->qp_handle_async.hi;
+ p_ramrod->qp_handle_for_async.lo = qp->qp_handle_async.lo;
+ p_ramrod->qp_handle_for_cqe.hi = qp->qp_handle.hi;
+ p_ramrod->qp_handle_for_cqe.lo = qp->qp_handle.lo;
p_ramrod->cq_cid =
cpu_to_le32((p_hwfn->hw_info.opaque_fid << 16) | qp->sq_cq_id);
@@ -500,7 +454,7 @@ static int qed_roce_sp_create_requester(struct qed_hwfn *p_hwfn,
qed_rdma_set_fw_mac(p_ramrod->remote_mac_addr, qp->remote_mac_addr);
qed_rdma_set_fw_mac(p_ramrod->local_mac_addr, qp->local_mac_addr);
- p_ramrod->udp_src_port = qp->udp_src_port;
+ p_ramrod->udp_src_port = cpu_to_le16(qp->udp_src_port);
p_ramrod->vlan_id = cpu_to_le16(qp->vlan_id);
p_ramrod->stats_counter_id = RESC_START(p_hwfn, QED_RDMA_STATS_QUEUE) +
qp->stats_queue;
@@ -532,6 +486,7 @@ static int qed_roce_sp_modify_responder(struct qed_hwfn *p_hwfn,
struct roce_modify_qp_resp_ramrod_data *p_ramrod;
struct qed_sp_init_data init_data;
struct qed_spq_entry *p_ent;
+ u16 flags = 0;
int rc;
if (!qp->has_resp)
@@ -556,53 +511,43 @@ static int qed_roce_sp_modify_responder(struct qed_hwfn *p_hwfn,
return rc;
}
- p_ramrod = &p_ent->ramrod.roce_modify_qp_resp;
-
- p_ramrod->flags = 0;
+ SET_FIELD(flags, ROCE_MODIFY_QP_RESP_RAMROD_DATA_MOVE_TO_ERR_FLG,
+ !!move_to_err);
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_RESP_RAMROD_DATA_MOVE_TO_ERR_FLG, move_to_err);
-
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_RESP_RAMROD_DATA_RDMA_RD_EN,
+ SET_FIELD(flags, ROCE_MODIFY_QP_RESP_RAMROD_DATA_RDMA_RD_EN,
qp->incoming_rdma_read_en);
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_RESP_RAMROD_DATA_RDMA_WR_EN,
+ SET_FIELD(flags, ROCE_MODIFY_QP_RESP_RAMROD_DATA_RDMA_WR_EN,
qp->incoming_rdma_write_en);
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_RESP_RAMROD_DATA_ATOMIC_EN,
+ SET_FIELD(flags, ROCE_MODIFY_QP_RESP_RAMROD_DATA_ATOMIC_EN,
qp->incoming_atomic_en);
- SET_FIELD(p_ramrod->flags,
- ROCE_CREATE_QP_RESP_RAMROD_DATA_E2E_FLOW_CONTROL_EN,
+ SET_FIELD(flags, ROCE_CREATE_QP_RESP_RAMROD_DATA_E2E_FLOW_CONTROL_EN,
qp->e2e_flow_control_en);
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_RESP_RAMROD_DATA_RDMA_OPS_EN_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_RESP_RAMROD_DATA_RDMA_OPS_EN_FLG,
GET_FIELD(modify_flags,
QED_RDMA_MODIFY_QP_VALID_RDMA_OPS_EN));
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_RESP_RAMROD_DATA_P_KEY_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_RESP_RAMROD_DATA_P_KEY_FLG,
GET_FIELD(modify_flags, QED_ROCE_MODIFY_QP_VALID_PKEY));
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_RESP_RAMROD_DATA_ADDRESS_VECTOR_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_RESP_RAMROD_DATA_ADDRESS_VECTOR_FLG,
GET_FIELD(modify_flags,
QED_ROCE_MODIFY_QP_VALID_ADDRESS_VECTOR));
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_RESP_RAMROD_DATA_MAX_IRD_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_RESP_RAMROD_DATA_MAX_IRD_FLG,
GET_FIELD(modify_flags,
QED_RDMA_MODIFY_QP_VALID_MAX_RD_ATOMIC_RESP));
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_RESP_RAMROD_DATA_MIN_RNR_NAK_TIMER_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_RESP_RAMROD_DATA_MIN_RNR_NAK_TIMER_FLG,
GET_FIELD(modify_flags,
QED_ROCE_MODIFY_QP_VALID_MIN_RNR_NAK_TIMER));
+ p_ramrod = &p_ent->ramrod.roce_modify_qp_resp;
+ p_ramrod->flags = cpu_to_le16(flags);
+
p_ramrod->fields = 0;
SET_FIELD(p_ramrod->fields,
ROCE_MODIFY_QP_RESP_RAMROD_DATA_MIN_RNR_NAK_TIMER,
@@ -629,6 +574,7 @@ static int qed_roce_sp_modify_requester(struct qed_hwfn *p_hwfn,
struct roce_modify_qp_req_ramrod_data *p_ramrod;
struct qed_sp_init_data init_data;
struct qed_spq_entry *p_ent;
+ u16 flags = 0;
int rc;
if (!qp->has_req)
@@ -653,54 +599,44 @@ static int qed_roce_sp_modify_requester(struct qed_hwfn *p_hwfn,
return rc;
}
- p_ramrod = &p_ent->ramrod.roce_modify_qp_req;
-
- p_ramrod->flags = 0;
+ SET_FIELD(flags, ROCE_MODIFY_QP_REQ_RAMROD_DATA_MOVE_TO_ERR_FLG,
+ !!move_to_err);
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_MOVE_TO_ERR_FLG, move_to_err);
+ SET_FIELD(flags, ROCE_MODIFY_QP_REQ_RAMROD_DATA_MOVE_TO_SQD_FLG,
+ !!move_to_sqd);
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_MOVE_TO_SQD_FLG, move_to_sqd);
-
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_EN_SQD_ASYNC_NOTIFY,
+ SET_FIELD(flags, ROCE_MODIFY_QP_REQ_RAMROD_DATA_EN_SQD_ASYNC_NOTIFY,
qp->sqd_async);
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_P_KEY_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_REQ_RAMROD_DATA_P_KEY_FLG,
GET_FIELD(modify_flags, QED_ROCE_MODIFY_QP_VALID_PKEY));
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_ADDRESS_VECTOR_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_REQ_RAMROD_DATA_ADDRESS_VECTOR_FLG,
GET_FIELD(modify_flags,
QED_ROCE_MODIFY_QP_VALID_ADDRESS_VECTOR));
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_MAX_ORD_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_REQ_RAMROD_DATA_MAX_ORD_FLG,
GET_FIELD(modify_flags,
QED_RDMA_MODIFY_QP_VALID_MAX_RD_ATOMIC_REQ));
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_RNR_NAK_CNT_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_REQ_RAMROD_DATA_RNR_NAK_CNT_FLG,
GET_FIELD(modify_flags,
QED_ROCE_MODIFY_QP_VALID_RNR_RETRY_CNT));
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_ERR_RETRY_CNT_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_REQ_RAMROD_DATA_ERR_RETRY_CNT_FLG,
GET_FIELD(modify_flags, QED_ROCE_MODIFY_QP_VALID_RETRY_CNT));
- SET_FIELD(p_ramrod->flags,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_ACK_TIMEOUT_FLG,
+ SET_FIELD(flags, ROCE_MODIFY_QP_REQ_RAMROD_DATA_ACK_TIMEOUT_FLG,
GET_FIELD(modify_flags,
QED_ROCE_MODIFY_QP_VALID_ACK_TIMEOUT));
+ p_ramrod = &p_ent->ramrod.roce_modify_qp_req;
+ p_ramrod->flags = cpu_to_le16(flags);
+
p_ramrod->fields = 0;
SET_FIELD(p_ramrod->fields,
ROCE_MODIFY_QP_REQ_RAMROD_DATA_ERR_RETRY_CNT, qp->retry_cnt);
-
- SET_FIELD(p_ramrod->fields,
- ROCE_MODIFY_QP_REQ_RAMROD_DATA_RNR_NAK_CNT,
+ SET_FIELD(p_ramrod->fields, ROCE_MODIFY_QP_REQ_RAMROD_DATA_RNR_NAK_CNT,
qp->rnr_retry_cnt);
p_ramrod->max_ord = qp->max_rd_atomic_req;
@@ -821,8 +757,7 @@ static int qed_roce_sp_destroy_qp_requester(struct qed_hwfn *p_hwfn,
if (!qp->req_offloaded)
return 0;
- p_ramrod_res = (struct roce_destroy_qp_req_output_params *)
- dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
+ p_ramrod_res = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
sizeof(*p_ramrod_res),
&ramrod_res_phys, GFP_KERNEL);
if (!p_ramrod_res) {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_roce.h b/drivers/net/ethernet/qlogic/qed/qed_roce.h
index f801f39fde61..3a4a2d72a826 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_roce.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_roce.h
@@ -1,34 +1,9 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#ifndef _QED_ROCE_H
#define _QED_ROCE_H
#include <linux/types.h>
diff --git a/drivers/net/ethernet/qlogic/qed/qed_selftest.c b/drivers/net/ethernet/qlogic/qed/qed_selftest.c
index cf1d4476f9d8..6e70781ab87c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_selftest.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_selftest.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2016 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/crc32.h>
diff --git a/drivers/net/ethernet/qlogic/qed/qed_selftest.h b/drivers/net/ethernet/qlogic/qed/qed_selftest.h
index ad00d082fec8..e27dd9a4547e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_selftest.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_selftest.h
@@ -1,4 +1,6 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/* Copyright (c) 2019-2020 Marvell International Ltd. */
+
#ifndef _QED_SELFTEST_API_H
#define _QED_SELFTEST_API_H
#include <linux/types.h>
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp.h b/drivers/net/ethernet/qlogic/qed/qed_sp.h
index b7b4fbbbccfe..993f1357b6fc 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_sp.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_SP_H
@@ -180,12 +154,9 @@ struct qed_consq {
struct qed_chain chain;
};
-typedef int
-(*qed_spq_async_comp_cb)(struct qed_hwfn *p_hwfn,
- u8 opcode,
- u16 echo,
- union event_ring_data *data,
- u8 fw_return_code);
+typedef int (*qed_spq_async_comp_cb)(struct qed_hwfn *p_hwfn, u8 opcode,
+ __le16 echo, union event_ring_data *data,
+ u8 fw_return_code);
int
qed_spq_register_async_cb(struct qed_hwfn *p_hwfn,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
index 900bc603e30a..aa71adcf31ee 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -326,6 +300,7 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
struct qed_tunnel_info *p_tunn,
bool allow_npar_tx_switch)
{
+ struct outer_tag_config_struct *outer_tag_config;
struct pf_start_ramrod_data *p_ramrod = NULL;
u16 sb = qed_int_get_sp_sb_id(p_hwfn);
u8 sb_index = p_hwfn->p_eq->eq_sb_index;
@@ -362,39 +337,40 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
else
p_ramrod->mf_mode = MF_NPAR;
- p_ramrod->outer_tag_config.outer_tag.tci =
- cpu_to_le16(p_hwfn->hw_info.ovlan);
+ outer_tag_config = &p_ramrod->outer_tag_config;
+ outer_tag_config->outer_tag.tci = cpu_to_le16(p_hwfn->hw_info.ovlan);
+
if (test_bit(QED_MF_8021Q_TAGGING, &p_hwfn->cdev->mf_bits)) {
- p_ramrod->outer_tag_config.outer_tag.tpid = ETH_P_8021Q;
+ outer_tag_config->outer_tag.tpid = cpu_to_le16(ETH_P_8021Q);
} else if (test_bit(QED_MF_8021AD_TAGGING, &p_hwfn->cdev->mf_bits)) {
- p_ramrod->outer_tag_config.outer_tag.tpid = ETH_P_8021AD;
- p_ramrod->outer_tag_config.enable_stag_pri_change = 1;
+ outer_tag_config->outer_tag.tpid = cpu_to_le16(ETH_P_8021AD);
+ outer_tag_config->enable_stag_pri_change = 1;
}
- p_ramrod->outer_tag_config.pri_map_valid = 1;
+ outer_tag_config->pri_map_valid = 1;
for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++)
- p_ramrod->outer_tag_config.inner_to_outer_pri_map[i] = i;
+ outer_tag_config->inner_to_outer_pri_map[i] = i;
/* enable_stag_pri_change should be set if port is in BD mode or,
* UFP with Host Control mode.
*/
if (test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits)) {
if (p_hwfn->ufp_info.pri_type == QED_UFP_PRI_OS)
- p_ramrod->outer_tag_config.enable_stag_pri_change = 1;
+ outer_tag_config->enable_stag_pri_change = 1;
else
- p_ramrod->outer_tag_config.enable_stag_pri_change = 0;
+ outer_tag_config->enable_stag_pri_change = 0;
- p_ramrod->outer_tag_config.outer_tag.tci |=
+ outer_tag_config->outer_tag.tci |=
cpu_to_le16(((u16)p_hwfn->ufp_info.tc << 13));
}
/* Place EQ address in RAMROD */
DMA_REGPAIR_LE(p_ramrod->event_ring_pbl_addr,
- p_hwfn->p_eq->chain.pbl_sp.p_phys_table);
+ qed_chain_get_pbl_phys(&p_hwfn->p_eq->chain));
page_cnt = (u8)qed_chain_get_page_cnt(&p_hwfn->p_eq->chain);
p_ramrod->event_ring_num_pages = page_cnt;
DMA_REGPAIR_LE(p_ramrod->consolid_q_pbl_addr,
- p_hwfn->p_consq->chain.pbl_sp.p_phys_table);
+ qed_chain_get_pbl_phys(&p_hwfn->p_consq->chain));
qed_tunn_set_pf_start_params(p_hwfn, p_tunn, &p_ramrod->tunnel_config);
@@ -432,7 +408,7 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
"Setting event_ring_sb [id %04x index %02x], outer_tag.tci [%d]\n",
- sb, sb_index, p_ramrod->outer_tag_config.outer_tag.tci);
+ sb, sb_index, outer_tag_config->outer_tag.tci);
rc = qed_spq_post(p_hwfn, p_ent, NULL);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c
index 790c28d696a0..0bc1a0aeb56e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_spq.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/types.h>
@@ -408,22 +382,26 @@ int qed_eq_completion(struct qed_hwfn *p_hwfn, void *cookie)
int qed_eq_alloc(struct qed_hwfn *p_hwfn, u16 num_elem)
{
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .intended_use = QED_CHAIN_USE_TO_PRODUCE,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
+ .num_elems = num_elem,
+ .elem_size = sizeof(union event_ring_element),
+ };
struct qed_eq *p_eq;
+ int ret;
/* Allocate EQ struct */
p_eq = kzalloc(sizeof(*p_eq), GFP_KERNEL);
if (!p_eq)
return -ENOMEM;
- /* Allocate and initialize EQ chain*/
- if (qed_chain_alloc(p_hwfn->cdev,
- QED_CHAIN_USE_TO_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- num_elem,
- sizeof(union event_ring_element),
- &p_eq->chain, NULL))
+ ret = qed_chain_alloc(p_hwfn->cdev, &p_eq->chain, &params);
+ if (ret) {
+ DP_NOTICE(p_hwfn, "Failed to allocate EQ chain\n");
goto eq_allocate_fail;
+ }
/* register EQ completion on the SP SB */
qed_int_register_cb(p_hwfn, qed_eq_completion,
@@ -434,7 +412,8 @@ int qed_eq_alloc(struct qed_hwfn *p_hwfn, u16 num_elem)
eq_allocate_fail:
kfree(p_eq);
- return -ENOMEM;
+
+ return ret;
}
void qed_eq_setup(struct qed_hwfn *p_hwfn)
@@ -555,33 +534,40 @@ void qed_spq_setup(struct qed_hwfn *p_hwfn)
int qed_spq_alloc(struct qed_hwfn *p_hwfn)
{
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_SINGLE,
+ .intended_use = QED_CHAIN_USE_TO_PRODUCE,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
+ .elem_size = sizeof(struct slow_path_element),
+ };
+ struct qed_dev *cdev = p_hwfn->cdev;
struct qed_spq_entry *p_virt = NULL;
struct qed_spq *p_spq = NULL;
dma_addr_t p_phys = 0;
u32 capacity;
+ int ret;
/* SPQ struct */
p_spq = kzalloc(sizeof(struct qed_spq), GFP_KERNEL);
if (!p_spq)
return -ENOMEM;
- /* SPQ ring */
- if (qed_chain_alloc(p_hwfn->cdev,
- QED_CHAIN_USE_TO_PRODUCE,
- QED_CHAIN_MODE_SINGLE,
- QED_CHAIN_CNT_TYPE_U16,
- 0, /* N/A when the mode is SINGLE */
- sizeof(struct slow_path_element),
- &p_spq->chain, NULL))
- goto spq_allocate_fail;
+ /* SPQ ring */
+ ret = qed_chain_alloc(cdev, &p_spq->chain, &params);
+ if (ret) {
+ DP_NOTICE(p_hwfn, "Failed to allocate SPQ chain\n");
+ goto spq_chain_alloc_fail;
+ }
/* allocate and fill the SPQ elements (incl. ramrod data list) */
capacity = qed_chain_get_capacity(&p_spq->chain);
- p_virt = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
+ ret = -ENOMEM;
+
+ p_virt = dma_alloc_coherent(&cdev->pdev->dev,
capacity * sizeof(struct qed_spq_entry),
&p_phys, GFP_KERNEL);
if (!p_virt)
- goto spq_allocate_fail;
+ goto spq_alloc_fail;
p_spq->p_virt = p_virt;
p_spq->p_phys = p_phys;
@@ -589,10 +575,12 @@ int qed_spq_alloc(struct qed_hwfn *p_hwfn)
return 0;
-spq_allocate_fail:
- qed_chain_free(p_hwfn->cdev, &p_spq->chain);
+spq_alloc_fail:
+ qed_chain_free(cdev, &p_spq->chain);
+spq_chain_alloc_fail:
kfree(p_spq);
- return -ENOMEM;
+
+ return ret;
}
void qed_spq_free(struct qed_hwfn *p_hwfn)
@@ -668,18 +656,18 @@ void qed_spq_return_entry(struct qed_hwfn *p_hwfn, struct qed_spq_entry *p_ent)
}
/**
- * @brief qed_spq_add_entry - adds a new entry to the pending
- * list. Should be used while lock is being held.
+ * qed_spq_add_entry() - Add a new entry to the pending list.
+ * Should be used while lock is being held.
*
- * Addes an entry to the pending list is there is room (en empty
+ * @p_hwfn: HW device data.
+ * @p_ent: An entry to add.
+ * @priority: Desired priority.
+ *
+ * Adds an entry to the pending list is there is room (an empty
* element is available in the free_pool), or else places the
* entry in the unlimited_pending pool.
*
- * @param p_hwfn
- * @param p_ent
- * @param priority
- *
- * @return int
+ * Return: zero on success, -EINVAL on invalid @priority.
*/
static int qed_spq_add_entry(struct qed_hwfn *p_hwfn,
struct qed_spq_entry *p_ent,
@@ -993,30 +981,40 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn,
return 0;
}
+#define QED_SPQ_CONSQ_ELEM_SIZE 0x80
+
int qed_consq_alloc(struct qed_hwfn *p_hwfn)
{
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .intended_use = QED_CHAIN_USE_TO_PRODUCE,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
+ .num_elems = QED_CHAIN_PAGE_SIZE / QED_SPQ_CONSQ_ELEM_SIZE,
+ .elem_size = QED_SPQ_CONSQ_ELEM_SIZE,
+ };
struct qed_consq *p_consq;
+ int ret;
/* Allocate ConsQ struct */
p_consq = kzalloc(sizeof(*p_consq), GFP_KERNEL);
if (!p_consq)
return -ENOMEM;
- /* Allocate and initialize EQ chain*/
- if (qed_chain_alloc(p_hwfn->cdev,
- QED_CHAIN_USE_TO_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- QED_CHAIN_PAGE_SIZE / 0x80,
- 0x80, &p_consq->chain, NULL))
- goto consq_allocate_fail;
+ /* Allocate and initialize ConsQ chain */
+ ret = qed_chain_alloc(p_hwfn->cdev, &p_consq->chain, &params);
+ if (ret) {
+ DP_NOTICE(p_hwfn, "Failed to allocate ConsQ chain");
+ goto consq_alloc_fail;
+ }
p_hwfn->p_consq = p_consq;
+
return 0;
-consq_allocate_fail:
+consq_alloc_fail:
kfree(p_consq);
- return -ENOMEM;
+
+ return ret;
}
void qed_consq_setup(struct qed_hwfn *p_hwfn)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
index 20679fd4204b..f1f75b6d0421 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/etherdevice.h>
@@ -849,16 +823,17 @@ static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn,
}
/**
- * @brief qed_iov_config_perm_table - configure the permission
- * zone table.
- * In E4, queue zone permission table size is 320x9. There
- * are 320 VF queues for single engine device (256 for dual
- * engine device), and each entry has the following format:
- * {Valid, VF[7:0]}
- * @param p_hwfn
- * @param p_ptt
- * @param vf
- * @param enable
+ * qed_iov_config_perm_table() - Configure the permission zone table.
+ *
+ * @p_hwfn: HW device data.
+ * @p_ptt: PTT window for writing the registers.
+ * @vf: VF info data.
+ * @enable: The actual permision for this VF.
+ *
+ * In E4, queue zone permission table size is 320x9. There
+ * are 320 VF queues for single engine device (256 for dual
+ * engine device), and each entry has the following format:
+ * {Valid, VF[7:0]}
*/
static void qed_iov_config_perm_table(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
@@ -3301,14 +3276,12 @@ static void qed_iov_vf_mbx_ucast_filter(struct qed_hwfn *p_hwfn,
DP_VERBOSE(p_hwfn,
QED_MSG_IOV,
- "VF[%d]: opcode 0x%02x type 0x%02x [%s %s] [vport 0x%02x] MAC %02x:%02x:%02x:%02x:%02x:%02x, vlan 0x%04x\n",
+ "VF[%d]: opcode 0x%02x type 0x%02x [%s %s] [vport 0x%02x] MAC %pM, vlan 0x%04x\n",
vf->abs_vf_id, params.opcode, params.type,
params.is_rx_filter ? "RX" : "",
params.is_tx_filter ? "TX" : "",
params.vport_to_add_to,
- params.mac[0], params.mac[1],
- params.mac[2], params.mac[3],
- params.mac[4], params.mac[5], params.vlan);
+ params.mac, params.vlan);
if (!vf->vport_instance) {
DP_VERBOSE(p_hwfn,
@@ -4030,7 +4003,7 @@ static int qed_sriov_vfpf_msg(struct qed_hwfn *p_hwfn,
/* List the physical address of the request so that handler
* could later on copy the message from it.
*/
- p_vf->vf_mbx.pending_req = (((u64)vf_msg->hi) << 32) | vf_msg->lo;
+ p_vf->vf_mbx.pending_req = HILO_64(vf_msg->hi, vf_msg->lo);
/* Mark the event and schedule the workqueue */
p_vf->vf_mbx.b_pending_msg = true;
@@ -4062,9 +4035,7 @@ static void qed_sriov_vfpf_malicious(struct qed_hwfn *p_hwfn,
}
}
-static int qed_sriov_eqe_event(struct qed_hwfn *p_hwfn,
- u8 opcode,
- __le16 echo,
+static int qed_sriov_eqe_event(struct qed_hwfn *p_hwfn, u8 opcode, __le16 echo,
union event_ring_data *data, u8 fw_return_code)
{
switch (opcode) {
@@ -5067,8 +5038,7 @@ static void qed_update_mac_for_vf_trust_change(struct qed_hwfn *hwfn, int vf_id)
for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++) {
if (ether_addr_equal(vf->shadow_config.macs[i],
vf_info->mac)) {
- memset(vf->shadow_config.macs[i], 0,
- ETH_ALEN);
+ eth_zero_addr(vf->shadow_config.macs[i]);
DP_VERBOSE(hwfn, QED_MSG_IOV,
"Shadow MAC %pM removed for VF 0x%02x, VF trust mode is ON\n",
vf_info->mac, vf_id);
@@ -5077,7 +5047,7 @@ static void qed_update_mac_for_vf_trust_change(struct qed_hwfn *hwfn, int vf_id)
}
ether_addr_copy(vf_info->mac, force_mac);
- memset(vf_info->forced_mac, 0, ETH_ALEN);
+ eth_zero_addr(vf_info->forced_mac);
vf->bulletin.p_virt->valid_bitmap &=
~BIT(MAC_ADDR_FORCED);
qed_schedule_iov(hwfn, QED_IOV_WQ_BULLETIN_UPDATE_FLAG);
@@ -5088,7 +5058,7 @@ static void qed_update_mac_for_vf_trust_change(struct qed_hwfn *hwfn, int vf_id)
if (!vf_info->is_trusted_configured) {
u8 empty_mac[ETH_ALEN];
- memset(empty_mac, 0, ETH_ALEN);
+ eth_zero_addr(empty_mac);
for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++) {
if (ether_addr_equal(vf->shadow_config.macs[i],
empty_mac)) {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.h b/drivers/net/ethernet/qlogic/qed/qed_sriov.h
index 368e88565783..eacd6457f195 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.h
@@ -1,33 +1,7 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#ifndef _QED_SRIOV_H
@@ -272,6 +246,8 @@ enum qed_iov_wq_flag {
QED_IOV_WQ_VF_FORCE_LINK_QUERY_FLAG,
};
+extern const struct qed_iov_hv_ops qed_iov_ops_pass;
+
#ifdef CONFIG_QED_SRIOV
/**
* @brief Check if given VF ID @vfid is valid
diff --git a/drivers/net/ethernet/qlogic/qed/qed_vf.c b/drivers/net/ethernet/qlogic/qed/qed_vf.c
index adc2c8f3d48e..72a38d53d33f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_vf.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_vf.c
@@ -1,33 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
#include <linux/crc32.h>
diff --git a/drivers/net/ethernet/qlogic/qed/qed_vf.h b/drivers/net/ethernet/qlogic/qed/qed_vf.h
index 033409db86ae..60d2bb64e65f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_vf.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_vf.h
@@ -1,33 +1,6 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qed NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
*/
#ifndef _QED_VF_H
diff --git a/drivers/net/ethernet/qlogic/qede/Makefile b/drivers/net/ethernet/qlogic/qede/Makefile
index 3fc91d12413f..a6e8d9fc8832 100644
--- a/drivers/net/ethernet/qlogic/qede/Makefile
+++ b/drivers/net/ethernet/qlogic/qede/Makefile
@@ -1,4 +1,6 @@
-# SPDX-License-Identifier: GPL-2.0-only
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+# Copyright (c) 2019-2020 Marvell International Ltd.
+
obj-$(CONFIG_QEDE) := qede.o
qede-y := qede_main.o qede_fp.o qede_filter.o qede_ethtool.o qede_ptp.o
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index 8857da1208d7..803c1fcca8ad 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -1,34 +1,9 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qede NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#ifndef _QEDE_H_
#define _QEDE_H_
#include <linux/compiler.h>
@@ -201,16 +176,17 @@ struct qede_dev {
u32 dp_module;
u8 dp_level;
- unsigned long flags;
-#define IS_VF(edev) (test_bit(QEDE_FLAGS_IS_VF, &(edev)->flags))
+ unsigned long flags;
+#define IS_VF(edev) test_bit(QEDE_FLAGS_IS_VF, \
+ &(edev)->flags)
const struct qed_eth_ops *ops;
struct qede_ptp *ptp;
u64 ptp_skip_txts;
- struct qed_dev_eth_info dev_info;
-#define QEDE_MAX_RSS_CNT(edev) ((edev)->dev_info.num_queues)
-#define QEDE_MAX_TSS_CNT(edev) ((edev)->dev_info.num_queues)
+ struct qed_dev_eth_info dev_info;
+#define QEDE_MAX_RSS_CNT(edev) ((edev)->dev_info.num_queues)
+#define QEDE_MAX_TSS_CNT(edev) ((edev)->dev_info.num_queues)
#define QEDE_IS_BB(edev) \
((edev)->dev_info.common.dev_type == QED_DEV_TYPE_BB)
#define QEDE_IS_AH(edev) \
@@ -223,14 +199,16 @@ struct qede_dev {
u8 fp_num_rx;
u16 req_queues;
u16 num_queues;
-#define QEDE_QUEUE_CNT(edev) ((edev)->num_queues)
-#define QEDE_RSS_COUNT(edev) ((edev)->num_queues - (edev)->fp_num_tx)
+ u16 total_xdp_queues;
+
+#define QEDE_QUEUE_CNT(edev) ((edev)->num_queues)
+#define QEDE_RSS_COUNT(edev) ((edev)->num_queues - (edev)->fp_num_tx)
#define QEDE_RX_QUEUE_IDX(edev, i) (i)
-#define QEDE_TSS_COUNT(edev) ((edev)->num_queues - (edev)->fp_num_rx)
+#define QEDE_TSS_COUNT(edev) ((edev)->num_queues - (edev)->fp_num_rx)
struct qed_int_info int_info;
- /* Smaller private varaiant of the RTNL lock */
+ /* Smaller private variant of the RTNL lock */
struct mutex qede_lock;
u32 state; /* Protected by qede_lock */
u16 rx_buf_size;
@@ -251,22 +229,28 @@ struct qede_dev {
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
struct qede_stats stats;
-#define QEDE_RSS_INDIR_INITED BIT(0)
-#define QEDE_RSS_KEY_INITED BIT(1)
-#define QEDE_RSS_CAPS_INITED BIT(2)
- u32 rss_params_inited; /* bit-field to track initialized rss params */
- u16 rss_ind_table[128];
- u32 rss_key[10];
- u8 rss_caps;
-
- u16 q_num_rx_buffers; /* Must be a power of two */
- u16 q_num_tx_buffers; /* Must be a power of two */
-
- bool gro_disable;
- struct list_head vlan_list;
- u16 configured_vlans;
- u16 non_configured_vlans;
- bool accept_any_vlan;
+
+ /* Bitfield to track initialized RSS params */
+ u32 rss_params_inited;
+#define QEDE_RSS_INDIR_INITED BIT(0)
+#define QEDE_RSS_KEY_INITED BIT(1)
+#define QEDE_RSS_CAPS_INITED BIT(2)
+
+ u16 rss_ind_table[128];
+ u32 rss_key[10];
+ u8 rss_caps;
+
+ /* Both must be a power of two */
+ u16 q_num_rx_buffers;
+ u16 q_num_tx_buffers;
+
+ bool gro_disable;
+
+ struct list_head vlan_list;
+ u16 configured_vlans;
+ u16 non_configured_vlans;
+ bool accept_any_vlan;
+
struct delayed_work sp_task;
unsigned long sp_flags;
u16 vxlan_dst_port;
@@ -277,14 +261,14 @@ struct qede_dev {
struct qede_rdma_dev rdma_info;
- struct bpf_prog *xdp_prog;
+ struct bpf_prog *xdp_prog;
- unsigned long err_flags;
-#define QEDE_ERR_IS_HANDLED 31
-#define QEDE_ERR_ATTN_CLR_EN 0
-#define QEDE_ERR_GET_DBG_INFO 1
-#define QEDE_ERR_IS_RECOVERABLE 2
-#define QEDE_ERR_WARN 3
+ unsigned long err_flags;
+#define QEDE_ERR_IS_HANDLED 31
+#define QEDE_ERR_ATTN_CLR_EN 0
+#define QEDE_ERR_GET_DBG_INFO 1
+#define QEDE_ERR_IS_RECOVERABLE 2
+#define QEDE_ERR_WARN 3
struct qede_dump_info dump_info;
};
@@ -397,29 +381,34 @@ struct sw_tx_bd {
};
struct sw_tx_xdp {
- struct page *page;
- dma_addr_t mapping;
+ struct page *page;
+ struct xdp_frame *xdpf;
+ dma_addr_t mapping;
};
struct qede_tx_queue {
- u8 is_xdp;
- bool is_legacy;
- u16 sw_tx_cons;
- u16 sw_tx_prod;
- u16 num_tx_buffers; /* Slowpath only */
+ u8 is_xdp;
+ bool is_legacy;
+ u16 sw_tx_cons;
+ u16 sw_tx_prod;
+ u16 num_tx_buffers; /* Slowpath only */
- u64 xmit_pkts;
- u64 stopped_cnt;
- u64 tx_mem_alloc_err;
+ u64 xmit_pkts;
+ u64 stopped_cnt;
+ u64 tx_mem_alloc_err;
- __le16 *hw_cons_ptr;
+ __le16 *hw_cons_ptr;
/* Needed for the mapping of packets */
- struct device *dev;
+ struct device *dev;
+
+ void __iomem *doorbell_addr;
+ union db_prod tx_db;
+
+ /* Spinlock for XDP queues in case of XDP_REDIRECT */
+ spinlock_t xdp_tx_lock;
- void __iomem *doorbell_addr;
- union db_prod tx_db;
- int index; /* Slowpath only */
+ int index; /* Slowpath only */
#define QEDE_TXQ_XDP_TO_IDX(edev, txq) ((txq)->index - \
QEDE_MAX_TSS_CNT(edev))
#define QEDE_TXQ_IDX_TO_XDP(edev, idx) ((idx) + QEDE_MAX_TSS_CNT(edev))
@@ -431,22 +420,22 @@ struct qede_tx_queue {
#define QEDE_NDEV_TXQ_ID_TO_TXQ(edev, idx) \
(&((edev)->fp_array[QEDE_NDEV_TXQ_ID_TO_FP_ID(edev, idx)].txq \
[QEDE_NDEV_TXQ_ID_TO_TXQ_COS(edev, idx)]))
-#define QEDE_FP_TC0_TXQ(fp) (&((fp)->txq[0]))
+#define QEDE_FP_TC0_TXQ(fp) (&((fp)->txq[0]))
/* Regular Tx requires skb + metadata for release purpose,
* while XDP requires the pages and the mapped address.
*/
union {
- struct sw_tx_bd *skbs;
- struct sw_tx_xdp *xdp;
- } sw_tx_ring;
+ struct sw_tx_bd *skbs;
+ struct sw_tx_xdp *xdp;
+ } sw_tx_ring;
- struct qed_chain tx_pbl;
+ struct qed_chain tx_pbl;
/* Slowpath; Should be kept in end [unless missing padding] */
- void *handle;
- u16 cos;
- u16 ndev_txq_id;
+ void *handle;
+ u16 cos;
+ u16 ndev_txq_id;
};
#define BD_UNMAP_ADDR(bd) HILO_U64(le32_to_cpu((bd)->addr.hi), \
@@ -460,32 +449,37 @@ struct qede_tx_queue {
#define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes))
struct qede_fastpath {
- struct qede_dev *edev;
-#define QEDE_FASTPATH_TX BIT(0)
-#define QEDE_FASTPATH_RX BIT(1)
-#define QEDE_FASTPATH_XDP BIT(2)
-#define QEDE_FASTPATH_COMBINED (QEDE_FASTPATH_TX | QEDE_FASTPATH_RX)
- u8 type;
- u8 id;
- u8 xdp_xmit;
- struct napi_struct napi;
- struct qed_sb_info *sb_info;
- struct qede_rx_queue *rxq;
- struct qede_tx_queue *txq;
- struct qede_tx_queue *xdp_tx;
-
-#define VEC_NAME_SIZE (sizeof_field(struct net_device, name) + 8)
- char name[VEC_NAME_SIZE];
+ struct qede_dev *edev;
+
+ u8 type;
+#define QEDE_FASTPATH_TX BIT(0)
+#define QEDE_FASTPATH_RX BIT(1)
+#define QEDE_FASTPATH_XDP BIT(2)
+#define QEDE_FASTPATH_COMBINED (QEDE_FASTPATH_TX | QEDE_FASTPATH_RX)
+
+ u8 id;
+
+ u8 xdp_xmit;
+#define QEDE_XDP_TX BIT(0)
+#define QEDE_XDP_REDIRECT BIT(1)
+
+ struct napi_struct napi;
+ struct qed_sb_info *sb_info;
+ struct qede_rx_queue *rxq;
+ struct qede_tx_queue *txq;
+ struct qede_tx_queue *xdp_tx;
+
+ char name[IFNAMSIZ + 8];
};
/* Debug print definitions */
-#define DP_NAME(edev) ((edev)->ndev->name)
+#define DP_NAME(edev) netdev_name((edev)->ndev)
-#define XMIT_PLAIN 0
-#define XMIT_L4_CSUM BIT(0)
-#define XMIT_LSO BIT(1)
-#define XMIT_ENC BIT(2)
-#define XMIT_ENC_GSO_L4_CSUM BIT(3)
+#define XMIT_PLAIN 0
+#define XMIT_L4_CSUM BIT(0)
+#define XMIT_LSO BIT(1)
+#define XMIT_ENC BIT(2)
+#define XMIT_ENC_GSO_L4_CSUM BIT(3)
#define QEDE_CSUM_ERROR BIT(0)
#define QEDE_CSUM_UNNECESSARY BIT(1)
@@ -528,6 +522,8 @@ struct qede_reload_args {
/* Datapath functions definition */
netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev);
+int qede_xdp_transmit(struct net_device *dev, int n_frames,
+ struct xdp_frame **frames, u32 flags);
u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev);
netdev_features_t qede_features_check(struct sk_buff *skb,
@@ -568,6 +564,7 @@ void qede_set_dcbnl_ops(struct net_device *ndev);
void qede_config_debug(uint debug, u32 *p_dp_module, u8 *p_dp_level);
void qede_set_ethtool_ops(struct net_device *netdev);
+void qede_set_udp_tunnels(struct qede_dev *edev);
void qede_reload(struct qede_dev *edev,
struct qede_reload_args *args, bool is_locked);
int qede_change_mtu(struct net_device *dev, int new_mtu);
@@ -581,6 +578,8 @@ void qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq);
int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
struct flow_cls_offload *f);
+void qede_forced_speed_maps_init(void);
+
#define RX_RING_SIZE_POW 13
#define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW))
#define NUM_RX_BDS_MAX (RX_RING_SIZE - 1)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_dcbnl.c b/drivers/net/ethernet/qlogic/qede/qede_dcbnl.c
index e6e844a8cbc7..2763369bbc61 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_dcbnl.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_dcbnl.c
@@ -1,7 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qede NIC Driver
-* Copyright (c) 2015 QLogic Corporation
-*/
+ * Copyright (c) 2015 QLogic Corporation
+ * Copyright (c) 2019-2020 Marvell International Ltd.
+ */
#include <linux/types.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index 24cc68391ac4..b9aa6384563b 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -1,34 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qede NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include <linux/version.h>
#include <linux/types.h>
#include <linux/netdevice.h>
@@ -38,6 +13,8 @@
#include <linux/pci.h>
#include <linux/capability.h>
#include <linux/vmalloc.h>
+#include <linux/phylink.h>
+
#include "qede.h"
#include "qede_ptp.h"
@@ -219,6 +196,96 @@ static const char qede_tests_str_arr[QEDE_ETHTOOL_TEST_MAX][ETH_GSTRING_LEN] = {
"Nvram (online)\t\t",
};
+/* Forced speed capabilities maps */
+
+struct qede_forced_speed_map {
+ u32 speed;
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(caps);
+
+ const u32 *cap_arr;
+ u32 arr_size;
+};
+
+#define QEDE_FORCED_SPEED_MAP(value) \
+{ \
+ .speed = SPEED_##value, \
+ .cap_arr = qede_forced_speed_##value, \
+ .arr_size = ARRAY_SIZE(qede_forced_speed_##value), \
+}
+
+static const u32 qede_forced_speed_1000[] __initconst = {
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
+};
+
+static const u32 qede_forced_speed_10000[] __initconst = {
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
+ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
+};
+
+static const u32 qede_forced_speed_20000[] __initconst = {
+ ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
+};
+
+static const u32 qede_forced_speed_25000[] __initconst = {
+ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
+};
+
+static const u32 qede_forced_speed_40000[] __initconst = {
+ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
+};
+
+static const u32 qede_forced_speed_50000[] __initconst = {
+ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
+};
+
+static const u32 qede_forced_speed_100000[] __initconst = {
+ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
+};
+
+static struct qede_forced_speed_map qede_forced_speed_maps[] __ro_after_init = {
+ QEDE_FORCED_SPEED_MAP(1000),
+ QEDE_FORCED_SPEED_MAP(10000),
+ QEDE_FORCED_SPEED_MAP(20000),
+ QEDE_FORCED_SPEED_MAP(25000),
+ QEDE_FORCED_SPEED_MAP(40000),
+ QEDE_FORCED_SPEED_MAP(50000),
+ QEDE_FORCED_SPEED_MAP(100000),
+};
+
+void __init qede_forced_speed_maps_init(void)
+{
+ struct qede_forced_speed_map *map;
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) {
+ map = qede_forced_speed_maps + i;
+
+ linkmode_set_bit_array(map->cap_arr, map->arr_size, map->caps);
+ map->cap_arr = NULL;
+ map->arr_size = 0;
+ }
+}
+
+/* Ethtool callbacks */
+
static void qede_get_strings_stats_txq(struct qede_dev *edev,
struct qede_tx_queue *txq, u8 **buf)
{
@@ -443,76 +510,10 @@ static int qede_set_priv_flags(struct net_device *dev, u32 flags)
return 0;
}
-struct qede_link_mode_mapping {
- u32 qed_link_mode;
- u32 ethtool_link_mode;
-};
-
-static const struct qede_link_mode_mapping qed_lm_map[] = {
- {QED_LM_FIBRE_BIT, ETHTOOL_LINK_MODE_FIBRE_BIT},
- {QED_LM_Autoneg_BIT, ETHTOOL_LINK_MODE_Autoneg_BIT},
- {QED_LM_Asym_Pause_BIT, ETHTOOL_LINK_MODE_Asym_Pause_BIT},
- {QED_LM_Pause_BIT, ETHTOOL_LINK_MODE_Pause_BIT},
- {QED_LM_1000baseT_Full_BIT, ETHTOOL_LINK_MODE_1000baseT_Full_BIT},
- {QED_LM_10000baseT_Full_BIT, ETHTOOL_LINK_MODE_10000baseT_Full_BIT},
- {QED_LM_TP_BIT, ETHTOOL_LINK_MODE_TP_BIT},
- {QED_LM_Backplane_BIT, ETHTOOL_LINK_MODE_Backplane_BIT},
- {QED_LM_1000baseKX_Full_BIT, ETHTOOL_LINK_MODE_1000baseKX_Full_BIT},
- {QED_LM_10000baseKX4_Full_BIT, ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT},
- {QED_LM_10000baseKR_Full_BIT, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT},
- {QED_LM_10000baseKR_Full_BIT, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT},
- {QED_LM_10000baseR_FEC_BIT, ETHTOOL_LINK_MODE_10000baseR_FEC_BIT},
- {QED_LM_20000baseKR2_Full_BIT, ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT},
- {QED_LM_40000baseKR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT},
- {QED_LM_40000baseCR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT},
- {QED_LM_40000baseSR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT},
- {QED_LM_40000baseLR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT},
- {QED_LM_25000baseCR_Full_BIT, ETHTOOL_LINK_MODE_25000baseCR_Full_BIT},
- {QED_LM_25000baseKR_Full_BIT, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT},
- {QED_LM_25000baseSR_Full_BIT, ETHTOOL_LINK_MODE_25000baseSR_Full_BIT},
- {QED_LM_50000baseCR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT},
- {QED_LM_50000baseKR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT},
- {QED_LM_100000baseKR4_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT},
- {QED_LM_100000baseSR4_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT},
- {QED_LM_100000baseCR4_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT},
- {QED_LM_100000baseLR4_ER4_Full_BIT,
- ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT},
- {QED_LM_50000baseSR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT},
- {QED_LM_1000baseX_Full_BIT, ETHTOOL_LINK_MODE_1000baseX_Full_BIT},
- {QED_LM_10000baseCR_Full_BIT, ETHTOOL_LINK_MODE_10000baseCR_Full_BIT},
- {QED_LM_10000baseSR_Full_BIT, ETHTOOL_LINK_MODE_10000baseSR_Full_BIT},
- {QED_LM_10000baseLR_Full_BIT, ETHTOOL_LINK_MODE_10000baseLR_Full_BIT},
- {QED_LM_10000baseLRM_Full_BIT, ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT},
-};
-
-#define QEDE_DRV_TO_ETHTOOL_CAPS(caps, lk_ksettings, name) \
-{ \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++) { \
- if ((caps) & (qed_lm_map[i].qed_link_mode)) \
- __set_bit(qed_lm_map[i].ethtool_link_mode,\
- lk_ksettings->link_modes.name); \
- } \
-}
-
-#define QEDE_ETHTOOL_TO_DRV_CAPS(caps, lk_ksettings, name) \
-{ \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++) { \
- if (test_bit(qed_lm_map[i].ethtool_link_mode, \
- lk_ksettings->link_modes.name)) \
- caps |= qed_lm_map[i].qed_link_mode; \
- } \
-}
-
static int qede_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{
+ typeof(cmd->link_modes) *link_modes = &cmd->link_modes;
struct ethtool_link_settings *base = &cmd->base;
struct qede_dev *edev = netdev_priv(dev);
struct qed_link_output current_link;
@@ -522,14 +523,9 @@ static int qede_get_link_ksettings(struct net_device *dev,
memset(&current_link, 0, sizeof(current_link));
edev->ops->common->get_link(edev->cdev, &current_link);
- ethtool_link_ksettings_zero_link_mode(cmd, supported);
- QEDE_DRV_TO_ETHTOOL_CAPS(current_link.supported_caps, cmd, supported)
-
- ethtool_link_ksettings_zero_link_mode(cmd, advertising);
- QEDE_DRV_TO_ETHTOOL_CAPS(current_link.advertised_caps, cmd, advertising)
-
- ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising);
- QEDE_DRV_TO_ETHTOOL_CAPS(current_link.lp_caps, cmd, lp_advertising)
+ linkmode_copy(link_modes->supported, current_link.supported_caps);
+ linkmode_copy(link_modes->advertising, current_link.advertised_caps);
+ linkmode_copy(link_modes->lp_advertising, current_link.lp_caps);
if ((edev->state == QEDE_STATE_OPEN) && (current_link.link_up)) {
base->speed = current_link.speed;
@@ -553,9 +549,10 @@ static int qede_set_link_ksettings(struct net_device *dev,
{
const struct ethtool_link_settings *base = &cmd->base;
struct qede_dev *edev = netdev_priv(dev);
+ const struct qede_forced_speed_map *map;
struct qed_link_output current_link;
struct qed_link_params params;
- u32 sup_caps;
+ u32 i;
if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
DP_INFO(edev, "Link settings are not allowed to be changed\n");
@@ -567,107 +564,40 @@ static int qede_set_link_ksettings(struct net_device *dev,
params.override_flags |= QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS;
params.override_flags |= QED_LINK_OVERRIDE_SPEED_AUTONEG;
+
if (base->autoneg == AUTONEG_ENABLE) {
- if (!(current_link.supported_caps & QED_LM_Autoneg_BIT)) {
+ if (!phylink_test(current_link.supported_caps, Autoneg)) {
DP_INFO(edev, "Auto negotiation is not supported\n");
return -EOPNOTSUPP;
}
params.autoneg = true;
params.forced_speed = 0;
- QEDE_ETHTOOL_TO_DRV_CAPS(params.adv_speeds, cmd, advertising)
+
+ linkmode_copy(params.adv_speeds, cmd->link_modes.advertising);
} else { /* forced speed */
params.override_flags |= QED_LINK_OVERRIDE_SPEED_FORCED_SPEED;
params.autoneg = false;
params.forced_speed = base->speed;
- switch (base->speed) {
- case SPEED_1000:
- sup_caps = QED_LM_1000baseT_Full_BIT |
- QED_LM_1000baseKX_Full_BIT |
- QED_LM_1000baseX_Full_BIT;
- if (!(current_link.supported_caps & sup_caps)) {
- DP_INFO(edev, "1G speed not supported\n");
- return -EINVAL;
- }
- params.adv_speeds = current_link.supported_caps &
- sup_caps;
- break;
- case SPEED_10000:
- sup_caps = QED_LM_10000baseT_Full_BIT |
- QED_LM_10000baseKR_Full_BIT |
- QED_LM_10000baseKX4_Full_BIT |
- QED_LM_10000baseR_FEC_BIT |
- QED_LM_10000baseCR_Full_BIT |
- QED_LM_10000baseSR_Full_BIT |
- QED_LM_10000baseLR_Full_BIT |
- QED_LM_10000baseLRM_Full_BIT;
- if (!(current_link.supported_caps & sup_caps)) {
- DP_INFO(edev, "10G speed not supported\n");
- return -EINVAL;
- }
- params.adv_speeds = current_link.supported_caps &
- sup_caps;
- break;
- case SPEED_20000:
- if (!(current_link.supported_caps &
- QED_LM_20000baseKR2_Full_BIT)) {
- DP_INFO(edev, "20G speed not supported\n");
- return -EINVAL;
- }
- params.adv_speeds = QED_LM_20000baseKR2_Full_BIT;
- break;
- case SPEED_25000:
- sup_caps = QED_LM_25000baseKR_Full_BIT |
- QED_LM_25000baseCR_Full_BIT |
- QED_LM_25000baseSR_Full_BIT;
- if (!(current_link.supported_caps & sup_caps)) {
- DP_INFO(edev, "25G speed not supported\n");
- return -EINVAL;
- }
- params.adv_speeds = current_link.supported_caps &
- sup_caps;
- break;
- case SPEED_40000:
- sup_caps = QED_LM_40000baseLR4_Full_BIT |
- QED_LM_40000baseKR4_Full_BIT |
- QED_LM_40000baseCR4_Full_BIT |
- QED_LM_40000baseSR4_Full_BIT;
- if (!(current_link.supported_caps & sup_caps)) {
- DP_INFO(edev, "40G speed not supported\n");
- return -EINVAL;
- }
- params.adv_speeds = current_link.supported_caps &
- sup_caps;
- break;
- case SPEED_50000:
- sup_caps = QED_LM_50000baseKR2_Full_BIT |
- QED_LM_50000baseCR2_Full_BIT |
- QED_LM_50000baseSR2_Full_BIT;
- if (!(current_link.supported_caps & sup_caps)) {
- DP_INFO(edev, "50G speed not supported\n");
- return -EINVAL;
- }
- params.adv_speeds = current_link.supported_caps &
- sup_caps;
- break;
- case SPEED_100000:
- sup_caps = QED_LM_100000baseKR4_Full_BIT |
- QED_LM_100000baseSR4_Full_BIT |
- QED_LM_100000baseCR4_Full_BIT |
- QED_LM_100000baseLR4_ER4_Full_BIT;
- if (!(current_link.supported_caps & sup_caps)) {
- DP_INFO(edev, "100G speed not supported\n");
- return -EINVAL;
- }
- params.adv_speeds = current_link.supported_caps &
- sup_caps;
- break;
- default:
- DP_INFO(edev, "Unsupported speed %u\n", base->speed);
- return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) {
+ map = qede_forced_speed_maps + i;
+
+ if (base->speed != map->speed ||
+ !linkmode_intersects(current_link.supported_caps,
+ map->caps))
+ continue;
+
+ linkmode_and(params.adv_speeds,
+ current_link.supported_caps, map->caps);
+ goto set_link;
}
+
+ DP_INFO(edev, "Unsupported speed %u\n", base->speed);
+ return -EINVAL;
}
+set_link:
params.link_up = true;
edev->ops->common->set_link(edev->cdev, &params);
@@ -1031,13 +961,16 @@ static int qede_set_pauseparam(struct net_device *dev,
memset(&params, 0, sizeof(params));
params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG;
+
if (epause->autoneg) {
- if (!(current_link.supported_caps & QED_LM_Autoneg_BIT)) {
+ if (!phylink_test(current_link.supported_caps, Autoneg)) {
DP_INFO(edev, "autoneg not supported\n");
return -EINVAL;
}
+
params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE;
}
+
if (epause->rx_pause)
params.pause_config |= QED_LINK_PAUSE_RX_ENABLE;
if (epause->tx_pause)
@@ -1901,6 +1834,78 @@ static int qede_set_eee(struct net_device *dev, struct ethtool_eee *edata)
return 0;
}
+static u32 qede_link_to_ethtool_fec(u32 link_fec)
+{
+ u32 eth_fec = 0;
+
+ if (link_fec & QED_FEC_MODE_NONE)
+ eth_fec |= ETHTOOL_FEC_OFF;
+ if (link_fec & QED_FEC_MODE_FIRECODE)
+ eth_fec |= ETHTOOL_FEC_BASER;
+ if (link_fec & QED_FEC_MODE_RS)
+ eth_fec |= ETHTOOL_FEC_RS;
+ if (link_fec & QED_FEC_MODE_AUTO)
+ eth_fec |= ETHTOOL_FEC_AUTO;
+ if (link_fec & QED_FEC_MODE_UNSUPPORTED)
+ eth_fec |= ETHTOOL_FEC_NONE;
+
+ return eth_fec;
+}
+
+static u32 qede_ethtool_to_link_fec(u32 eth_fec)
+{
+ u32 link_fec = 0;
+
+ if (eth_fec & ETHTOOL_FEC_OFF)
+ link_fec |= QED_FEC_MODE_NONE;
+ if (eth_fec & ETHTOOL_FEC_BASER)
+ link_fec |= QED_FEC_MODE_FIRECODE;
+ if (eth_fec & ETHTOOL_FEC_RS)
+ link_fec |= QED_FEC_MODE_RS;
+ if (eth_fec & ETHTOOL_FEC_AUTO)
+ link_fec |= QED_FEC_MODE_AUTO;
+ if (eth_fec & ETHTOOL_FEC_NONE)
+ link_fec |= QED_FEC_MODE_UNSUPPORTED;
+
+ return link_fec;
+}
+
+static int qede_get_fecparam(struct net_device *dev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct qede_dev *edev = netdev_priv(dev);
+ struct qed_link_output curr_link;
+
+ memset(&curr_link, 0, sizeof(curr_link));
+ edev->ops->common->get_link(edev->cdev, &curr_link);
+
+ fecparam->active_fec = qede_link_to_ethtool_fec(curr_link.active_fec);
+ fecparam->fec = qede_link_to_ethtool_fec(curr_link.sup_fec);
+
+ return 0;
+}
+
+static int qede_set_fecparam(struct net_device *dev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct qede_dev *edev = netdev_priv(dev);
+ struct qed_link_params params;
+
+ if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
+ DP_INFO(edev, "Link settings are not allowed to be changed\n");
+ return -EOPNOTSUPP;
+ }
+
+ memset(&params, 0, sizeof(params));
+ params.override_flags |= QED_LINK_OVERRIDE_FEC_CONFIG;
+ params.fec = qede_ethtool_to_link_fec(fecparam->fec);
+ params.link_up = true;
+
+ edev->ops->common->set_link(edev->cdev, &params);
+
+ return 0;
+}
+
static int qede_get_module_info(struct net_device *dev,
struct ethtool_modinfo *modinfo)
{
@@ -2099,78 +2104,79 @@ err:
}
static const struct ethtool_ops qede_ethtool_ops = {
- .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
- .get_link_ksettings = qede_get_link_ksettings,
- .set_link_ksettings = qede_set_link_ksettings,
- .get_drvinfo = qede_get_drvinfo,
- .get_regs_len = qede_get_regs_len,
- .get_regs = qede_get_regs,
- .get_wol = qede_get_wol,
- .set_wol = qede_set_wol,
- .get_msglevel = qede_get_msglevel,
- .set_msglevel = qede_set_msglevel,
- .nway_reset = qede_nway_reset,
- .get_link = qede_get_link,
- .get_coalesce = qede_get_coalesce,
- .set_coalesce = qede_set_coalesce,
- .get_ringparam = qede_get_ringparam,
- .set_ringparam = qede_set_ringparam,
- .get_pauseparam = qede_get_pauseparam,
- .set_pauseparam = qede_set_pauseparam,
- .get_strings = qede_get_strings,
- .set_phys_id = qede_set_phys_id,
- .get_ethtool_stats = qede_get_ethtool_stats,
- .get_priv_flags = qede_get_priv_flags,
- .set_priv_flags = qede_set_priv_flags,
- .get_sset_count = qede_get_sset_count,
- .get_rxnfc = qede_get_rxnfc,
- .set_rxnfc = qede_set_rxnfc,
- .get_rxfh_indir_size = qede_get_rxfh_indir_size,
- .get_rxfh_key_size = qede_get_rxfh_key_size,
- .get_rxfh = qede_get_rxfh,
- .set_rxfh = qede_set_rxfh,
- .get_ts_info = qede_get_ts_info,
- .get_channels = qede_get_channels,
- .set_channels = qede_set_channels,
- .self_test = qede_self_test,
- .get_module_info = qede_get_module_info,
- .get_module_eeprom = qede_get_module_eeprom,
- .get_eee = qede_get_eee,
- .set_eee = qede_set_eee,
-
- .get_tunable = qede_get_tunable,
- .set_tunable = qede_set_tunable,
- .flash_device = qede_flash_device,
- .get_dump_flag = qede_get_dump_flag,
- .get_dump_data = qede_get_dump_data,
- .set_dump = qede_set_dump,
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
+ .get_link_ksettings = qede_get_link_ksettings,
+ .set_link_ksettings = qede_set_link_ksettings,
+ .get_drvinfo = qede_get_drvinfo,
+ .get_regs_len = qede_get_regs_len,
+ .get_regs = qede_get_regs,
+ .get_wol = qede_get_wol,
+ .set_wol = qede_set_wol,
+ .get_msglevel = qede_get_msglevel,
+ .set_msglevel = qede_set_msglevel,
+ .nway_reset = qede_nway_reset,
+ .get_link = qede_get_link,
+ .get_coalesce = qede_get_coalesce,
+ .set_coalesce = qede_set_coalesce,
+ .get_ringparam = qede_get_ringparam,
+ .set_ringparam = qede_set_ringparam,
+ .get_pauseparam = qede_get_pauseparam,
+ .set_pauseparam = qede_set_pauseparam,
+ .get_strings = qede_get_strings,
+ .set_phys_id = qede_set_phys_id,
+ .get_ethtool_stats = qede_get_ethtool_stats,
+ .get_priv_flags = qede_get_priv_flags,
+ .set_priv_flags = qede_set_priv_flags,
+ .get_sset_count = qede_get_sset_count,
+ .get_rxnfc = qede_get_rxnfc,
+ .set_rxnfc = qede_set_rxnfc,
+ .get_rxfh_indir_size = qede_get_rxfh_indir_size,
+ .get_rxfh_key_size = qede_get_rxfh_key_size,
+ .get_rxfh = qede_get_rxfh,
+ .set_rxfh = qede_set_rxfh,
+ .get_ts_info = qede_get_ts_info,
+ .get_channels = qede_get_channels,
+ .set_channels = qede_set_channels,
+ .self_test = qede_self_test,
+ .get_module_info = qede_get_module_info,
+ .get_module_eeprom = qede_get_module_eeprom,
+ .get_eee = qede_get_eee,
+ .set_eee = qede_set_eee,
+ .get_fecparam = qede_get_fecparam,
+ .set_fecparam = qede_set_fecparam,
+ .get_tunable = qede_get_tunable,
+ .set_tunable = qede_set_tunable,
+ .flash_device = qede_flash_device,
+ .get_dump_flag = qede_get_dump_flag,
+ .get_dump_data = qede_get_dump_data,
+ .set_dump = qede_set_dump,
};
static const struct ethtool_ops qede_vf_ethtool_ops = {
- .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
- .get_link_ksettings = qede_get_link_ksettings,
- .get_drvinfo = qede_get_drvinfo,
- .get_msglevel = qede_get_msglevel,
- .set_msglevel = qede_set_msglevel,
- .get_link = qede_get_link,
- .get_coalesce = qede_get_coalesce,
- .set_coalesce = qede_set_coalesce,
- .get_ringparam = qede_get_ringparam,
- .set_ringparam = qede_set_ringparam,
- .get_strings = qede_get_strings,
- .get_ethtool_stats = qede_get_ethtool_stats,
- .get_priv_flags = qede_get_priv_flags,
- .get_sset_count = qede_get_sset_count,
- .get_rxnfc = qede_get_rxnfc,
- .set_rxnfc = qede_set_rxnfc,
- .get_rxfh_indir_size = qede_get_rxfh_indir_size,
- .get_rxfh_key_size = qede_get_rxfh_key_size,
- .get_rxfh = qede_get_rxfh,
- .set_rxfh = qede_set_rxfh,
- .get_channels = qede_get_channels,
- .set_channels = qede_set_channels,
- .get_tunable = qede_get_tunable,
- .set_tunable = qede_set_tunable,
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
+ .get_link_ksettings = qede_get_link_ksettings,
+ .get_drvinfo = qede_get_drvinfo,
+ .get_msglevel = qede_get_msglevel,
+ .set_msglevel = qede_set_msglevel,
+ .get_link = qede_get_link,
+ .get_coalesce = qede_get_coalesce,
+ .set_coalesce = qede_set_coalesce,
+ .get_ringparam = qede_get_ringparam,
+ .set_ringparam = qede_set_ringparam,
+ .get_strings = qede_get_strings,
+ .get_ethtool_stats = qede_get_ethtool_stats,
+ .get_priv_flags = qede_get_priv_flags,
+ .get_sset_count = qede_get_sset_count,
+ .get_rxnfc = qede_get_rxnfc,
+ .set_rxnfc = qede_set_rxnfc,
+ .get_rxfh_indir_size = qede_get_rxfh_indir_size,
+ .get_rxfh_key_size = qede_get_rxfh_key_size,
+ .get_rxfh = qede_get_rxfh,
+ .set_rxfh = qede_set_rxfh,
+ .get_channels = qede_get_channels,
+ .set_channels = qede_set_channels,
+ .get_tunable = qede_get_tunable,
+ .set_tunable = qede_set_tunable,
};
void qede_set_ethtool_ops(struct net_device *dev)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c
index fe72bb6c9455..f961f65d9372 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c
@@ -1,34 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qede NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <net/udp_tunnel.h>
@@ -978,115 +953,67 @@ int qede_set_features(struct net_device *dev, netdev_features_t features)
return 0;
}
-void qede_udp_tunnel_add(struct net_device *dev, struct udp_tunnel_info *ti)
+static int qede_udp_tunnel_sync(struct net_device *dev, unsigned int table)
{
struct qede_dev *edev = netdev_priv(dev);
struct qed_tunn_params tunn_params;
- u16 t_port = ntohs(ti->port);
+ struct udp_tunnel_info ti;
+ u16 *save_port;
int rc;
memset(&tunn_params, 0, sizeof(tunn_params));
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- if (!edev->dev_info.common.vxlan_enable)
- return;
-
- if (edev->vxlan_dst_port)
- return;
-
+ udp_tunnel_nic_get_port(dev, table, 0, &ti);
+ if (ti.type == UDP_TUNNEL_TYPE_VXLAN) {
tunn_params.update_vxlan_port = 1;
- tunn_params.vxlan_port = t_port;
-
- __qede_lock(edev);
- rc = edev->ops->tunn_config(edev->cdev, &tunn_params);
- __qede_unlock(edev);
-
- if (!rc) {
- edev->vxlan_dst_port = t_port;
- DP_VERBOSE(edev, QED_MSG_DEBUG, "Added vxlan port=%d\n",
- t_port);
- } else {
- DP_NOTICE(edev, "Failed to add vxlan UDP port=%d\n",
- t_port);
- }
-
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- if (!edev->dev_info.common.geneve_enable)
- return;
-
- if (edev->geneve_dst_port)
- return;
-
+ tunn_params.vxlan_port = ntohs(ti.port);
+ save_port = &edev->vxlan_dst_port;
+ } else {
tunn_params.update_geneve_port = 1;
- tunn_params.geneve_port = t_port;
-
- __qede_lock(edev);
- rc = edev->ops->tunn_config(edev->cdev, &tunn_params);
- __qede_unlock(edev);
-
- if (!rc) {
- edev->geneve_dst_port = t_port;
- DP_VERBOSE(edev, QED_MSG_DEBUG,
- "Added geneve port=%d\n", t_port);
- } else {
- DP_NOTICE(edev, "Failed to add geneve UDP port=%d\n",
- t_port);
- }
-
- break;
- default:
- return;
+ tunn_params.geneve_port = ntohs(ti.port);
+ save_port = &edev->geneve_dst_port;
}
-}
-
-void qede_udp_tunnel_del(struct net_device *dev,
- struct udp_tunnel_info *ti)
-{
- struct qede_dev *edev = netdev_priv(dev);
- struct qed_tunn_params tunn_params;
- u16 t_port = ntohs(ti->port);
- memset(&tunn_params, 0, sizeof(tunn_params));
-
- switch (ti->type) {
- case UDP_TUNNEL_TYPE_VXLAN:
- if (t_port != edev->vxlan_dst_port)
- return;
-
- tunn_params.update_vxlan_port = 1;
- tunn_params.vxlan_port = 0;
-
- __qede_lock(edev);
- edev->ops->tunn_config(edev->cdev, &tunn_params);
- __qede_unlock(edev);
-
- edev->vxlan_dst_port = 0;
-
- DP_VERBOSE(edev, QED_MSG_DEBUG, "Deleted vxlan port=%d\n",
- t_port);
-
- break;
- case UDP_TUNNEL_TYPE_GENEVE:
- if (t_port != edev->geneve_dst_port)
- return;
-
- tunn_params.update_geneve_port = 1;
- tunn_params.geneve_port = 0;
+ __qede_lock(edev);
+ rc = edev->ops->tunn_config(edev->cdev, &tunn_params);
+ __qede_unlock(edev);
+ if (rc)
+ return rc;
- __qede_lock(edev);
- edev->ops->tunn_config(edev->cdev, &tunn_params);
- __qede_unlock(edev);
+ *save_port = ntohs(ti.port);
+ return 0;
+}
- edev->geneve_dst_port = 0;
+static const struct udp_tunnel_nic_info qede_udp_tunnels_both = {
+ .sync_table = qede_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+ },
+}, qede_udp_tunnels_vxlan = {
+ .sync_table = qede_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+}, qede_udp_tunnels_geneve = {
+ .sync_table = qede_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, },
+ },
+};
- DP_VERBOSE(edev, QED_MSG_DEBUG, "Deleted geneve port=%d\n",
- t_port);
- break;
- default:
- return;
- }
+void qede_set_udp_tunnels(struct qede_dev *edev)
+{
+ if (edev->dev_info.common.vxlan_enable &&
+ edev->dev_info.common.geneve_enable)
+ edev->ndev->udp_tunnel_nic_info = &qede_udp_tunnels_both;
+ else if (edev->dev_info.common.vxlan_enable)
+ edev->ndev->udp_tunnel_nic_info = &qede_udp_tunnels_vxlan;
+ else if (edev->dev_info.common.geneve_enable)
+ edev->ndev->udp_tunnel_nic_info = &qede_udp_tunnels_geneve;
}
static void qede_xdp_reload_func(struct qede_dev *edev,
@@ -1118,9 +1045,6 @@ int qede_xdp(struct net_device *dev, struct netdev_bpf *xdp)
switch (xdp->command) {
case XDP_SETUP_PROG:
return qede_xdp_set(edev, xdp->prog);
- case XDP_QUERY_PROG:
- xdp->prog_id = edev->xdp_prog ? edev->xdp_prog->aux->id : 0;
- return 0;
default:
return -EINVAL;
}
@@ -1789,8 +1713,8 @@ qede_flow_parse_ports(struct qede_dev *edev, struct flow_rule *rule,
struct flow_match_ports match;
flow_rule_match_ports(rule, &match);
- if ((match.key->src && match.mask->src != U16_MAX) ||
- (match.key->dst && match.mask->dst != U16_MAX)) {
+ if ((match.key->src && match.mask->src != htons(U16_MAX)) ||
+ (match.key->dst && match.mask->dst != htons(U16_MAX))) {
DP_NOTICE(edev, "Do not support ports masks\n");
return -EINVAL;
}
@@ -1842,8 +1766,8 @@ qede_flow_parse_v4_common(struct qede_dev *edev, struct flow_rule *rule,
struct flow_match_ipv4_addrs match;
flow_rule_match_ipv4_addrs(rule, &match);
- if ((match.key->src && match.mask->src != U32_MAX) ||
- (match.key->dst && match.mask->dst != U32_MAX)) {
+ if ((match.key->src && match.mask->src != htonl(U32_MAX)) ||
+ (match.key->dst && match.mask->dst != htonl(U32_MAX))) {
DP_NOTICE(edev, "Do not support ipv4 prefix/masks\n");
return -EINVAL;
}
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c
index 7598ebe0962a..a2494bf85007 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -1,34 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qede NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
@@ -327,51 +302,94 @@ static inline void qede_update_tx_producer(struct qede_tx_queue *txq)
wmb();
}
-static int qede_xdp_xmit(struct qede_dev *edev, struct qede_fastpath *fp,
- struct sw_rx_data *metadata, u16 padding, u16 length)
+static int qede_xdp_xmit(struct qede_tx_queue *txq, dma_addr_t dma, u16 pad,
+ u16 len, struct page *page, struct xdp_frame *xdpf)
{
- struct qede_tx_queue *txq = fp->xdp_tx;
- struct eth_tx_1st_bd *first_bd;
- u16 idx = txq->sw_tx_prod;
+ struct eth_tx_1st_bd *bd;
+ struct sw_tx_xdp *xdp;
u16 val;
- if (!qed_chain_get_elem_left(&txq->tx_pbl)) {
+ if (unlikely(qed_chain_get_elem_used(&txq->tx_pbl) >=
+ txq->num_tx_buffers)) {
txq->stopped_cnt++;
return -ENOMEM;
}
- first_bd = (struct eth_tx_1st_bd *)qed_chain_produce(&txq->tx_pbl);
-
- memset(first_bd, 0, sizeof(*first_bd));
- first_bd->data.bd_flags.bitfields =
- BIT(ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT);
+ bd = qed_chain_produce(&txq->tx_pbl);
+ bd->data.nbds = 1;
+ bd->data.bd_flags.bitfields = BIT(ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT);
- val = (length & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) <<
+ val = (len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) <<
ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT;
- first_bd->data.bitfields |= cpu_to_le16(val);
- first_bd->data.nbds = 1;
+ bd->data.bitfields = cpu_to_le16(val);
/* We can safely ignore the offset, as it's 0 for XDP */
- BD_SET_UNMAP_ADDR_LEN(first_bd, metadata->mapping + padding, length);
+ BD_SET_UNMAP_ADDR_LEN(bd, dma + pad, len);
- /* Synchronize the buffer back to device, as program [probably]
- * has changed it.
- */
- dma_sync_single_for_device(&edev->pdev->dev,
- metadata->mapping + padding,
- length, PCI_DMA_TODEVICE);
+ xdp = txq->sw_tx_ring.xdp + txq->sw_tx_prod;
+ xdp->mapping = dma;
+ xdp->page = page;
+ xdp->xdpf = xdpf;
- txq->sw_tx_ring.xdp[idx].page = metadata->data;
- txq->sw_tx_ring.xdp[idx].mapping = metadata->mapping;
txq->sw_tx_prod = (txq->sw_tx_prod + 1) % txq->num_tx_buffers;
- /* Mark the fastpath for future XDP doorbell */
- fp->xdp_xmit = 1;
-
return 0;
}
+int qede_xdp_transmit(struct net_device *dev, int n_frames,
+ struct xdp_frame **frames, u32 flags)
+{
+ struct qede_dev *edev = netdev_priv(dev);
+ struct device *dmadev = &edev->pdev->dev;
+ struct qede_tx_queue *xdp_tx;
+ struct xdp_frame *xdpf;
+ dma_addr_t mapping;
+ int i, drops = 0;
+ u16 xdp_prod;
+
+ if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
+ return -EINVAL;
+
+ if (unlikely(!netif_running(dev)))
+ return -ENETDOWN;
+
+ i = smp_processor_id() % edev->total_xdp_queues;
+ xdp_tx = edev->fp_array[i].xdp_tx;
+
+ spin_lock(&xdp_tx->xdp_tx_lock);
+
+ for (i = 0; i < n_frames; i++) {
+ xdpf = frames[i];
+
+ mapping = dma_map_single(dmadev, xdpf->data, xdpf->len,
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dmadev, mapping))) {
+ xdp_return_frame_rx_napi(xdpf);
+ drops++;
+
+ continue;
+ }
+
+ if (unlikely(qede_xdp_xmit(xdp_tx, mapping, 0, xdpf->len,
+ NULL, xdpf))) {
+ xdp_return_frame_rx_napi(xdpf);
+ drops++;
+ }
+ }
+
+ if (flags & XDP_XMIT_FLUSH) {
+ xdp_prod = qed_chain_get_prod_idx(&xdp_tx->tx_pbl);
+
+ xdp_tx->tx_db.data.bd_prod = cpu_to_le16(xdp_prod);
+ qede_update_tx_producer(xdp_tx);
+ }
+
+ spin_unlock(&xdp_tx->xdp_tx_lock);
+
+ return n_frames - drops;
+}
+
int qede_txq_has_work(struct qede_tx_queue *txq)
{
u16 hw_bd_cons;
@@ -387,20 +405,31 @@ int qede_txq_has_work(struct qede_tx_queue *txq)
static void qede_xdp_tx_int(struct qede_dev *edev, struct qede_tx_queue *txq)
{
- u16 hw_bd_cons, idx;
+ struct sw_tx_xdp *xdp_info, *xdp_arr = txq->sw_tx_ring.xdp;
+ struct device *dev = &edev->pdev->dev;
+ struct xdp_frame *xdpf;
+ u16 hw_bd_cons;
hw_bd_cons = le16_to_cpu(*txq->hw_cons_ptr);
barrier();
while (hw_bd_cons != qed_chain_get_cons_idx(&txq->tx_pbl)) {
- qed_chain_consume(&txq->tx_pbl);
- idx = txq->sw_tx_cons;
+ xdp_info = xdp_arr + txq->sw_tx_cons;
+ xdpf = xdp_info->xdpf;
+
+ if (xdpf) {
+ dma_unmap_single(dev, xdp_info->mapping, xdpf->len,
+ DMA_TO_DEVICE);
+ xdp_return_frame(xdpf);
- dma_unmap_page(&edev->pdev->dev,
- txq->sw_tx_ring.xdp[idx].mapping,
- PAGE_SIZE, DMA_BIDIRECTIONAL);
- __free_page(txq->sw_tx_ring.xdp[idx].page);
+ xdp_info->xdpf = NULL;
+ } else {
+ dma_unmap_page(dev, xdp_info->mapping, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+ __free_page(xdp_info->page);
+ }
+ qed_chain_consume(&txq->tx_pbl);
txq->sw_tx_cons = (txq->sw_tx_cons + 1) % txq->num_tx_buffers;
txq->xmit_pkts++;
}
@@ -1089,32 +1118,59 @@ static bool qede_rx_xdp(struct qede_dev *edev,
switch (act) {
case XDP_TX:
/* We need the replacement buffer before transmit. */
- if (qede_alloc_rx_buffer(rxq, true)) {
+ if (unlikely(qede_alloc_rx_buffer(rxq, true))) {
qede_recycle_rx_bd_ring(rxq, 1);
+
trace_xdp_exception(edev->ndev, prog, act);
- return false;
+ break;
}
/* Now if there's a transmission problem, we'd still have to
* throw current buffer, as replacement was already allocated.
*/
- if (qede_xdp_xmit(edev, fp, bd, *data_offset, *len)) {
- dma_unmap_page(rxq->dev, bd->mapping,
- PAGE_SIZE, DMA_BIDIRECTIONAL);
+ if (unlikely(qede_xdp_xmit(fp->xdp_tx, bd->mapping,
+ *data_offset, *len, bd->data,
+ NULL))) {
+ dma_unmap_page(rxq->dev, bd->mapping, PAGE_SIZE,
+ rxq->data_direction);
__free_page(bd->data);
+
trace_xdp_exception(edev->ndev, prog, act);
+ } else {
+ dma_sync_single_for_device(rxq->dev,
+ bd->mapping + *data_offset,
+ *len, rxq->data_direction);
+ fp->xdp_xmit |= QEDE_XDP_TX;
}
/* Regardless, we've consumed an Rx BD */
qede_rx_bd_ring_consume(rxq);
- return false;
+ break;
+ case XDP_REDIRECT:
+ /* We need the replacement buffer before transmit. */
+ if (unlikely(qede_alloc_rx_buffer(rxq, true))) {
+ qede_recycle_rx_bd_ring(rxq, 1);
+
+ trace_xdp_exception(edev->ndev, prog, act);
+ break;
+ }
+ dma_unmap_page(rxq->dev, bd->mapping, PAGE_SIZE,
+ rxq->data_direction);
+
+ if (unlikely(xdp_do_redirect(edev->ndev, &xdp, prog)))
+ DP_NOTICE(edev, "Failed to redirect the packet\n");
+ else
+ fp->xdp_xmit |= QEDE_XDP_REDIRECT;
+
+ qede_rx_bd_ring_consume(rxq);
+ break;
default:
bpf_warn_invalid_xdp_action(act);
- /* Fall through */
+ fallthrough;
case XDP_ABORTED:
trace_xdp_exception(edev->ndev, prog, act);
- /* Fall through */
+ fallthrough;
case XDP_DROP:
qede_recycle_rx_bd_ring(rxq, cqe->bd_num);
}
@@ -1378,6 +1434,9 @@ int qede_poll(struct napi_struct *napi, int budget)
napi);
struct qede_dev *edev = fp->edev;
int rx_work_done = 0;
+ u16 xdp_prod;
+
+ fp->xdp_xmit = 0;
if (likely(fp->type & QEDE_FASTPATH_TX)) {
int cos;
@@ -1405,14 +1464,16 @@ int qede_poll(struct napi_struct *napi, int budget)
}
}
- if (fp->xdp_xmit) {
- u16 xdp_prod = qed_chain_get_prod_idx(&fp->xdp_tx->tx_pbl);
+ if (fp->xdp_xmit & QEDE_XDP_TX) {
+ xdp_prod = qed_chain_get_prod_idx(&fp->xdp_tx->tx_pbl);
- fp->xdp_xmit = 0;
fp->xdp_tx->tx_db.data.bd_prod = cpu_to_le16(xdp_prod);
qede_update_tx_producer(fp->xdp_tx);
}
+ if (fp->xdp_xmit & QEDE_XDP_REDIRECT)
+ xdp_do_flush_map();
+
return rx_work_done;
}
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 29e285430f99..140a392a81bb 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -1,34 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qede NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include <linux/crash_dump.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -169,9 +144,7 @@ static int qede_set_vf_mac(struct net_device *ndev, int vfidx, u8 *mac)
{
struct qede_dev *edev = netdev_priv(ndev);
- DP_VERBOSE(edev, QED_MSG_IOV,
- "Setting MAC %02x:%02x:%02x:%02x:%02x:%02x to VF [%d]\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], vfidx);
+ DP_VERBOSE(edev, QED_MSG_IOV, "Setting MAC %pM to VF [%d]\n", mac, vfidx);
if (!is_valid_ether_addr(mac)) {
DP_VERBOSE(edev, QED_MSG_IOV, "MAC address isn't valid\n");
@@ -288,6 +261,8 @@ int __init qede_init(void)
pr_info("qede_init: %s\n", version);
+ qede_forced_speed_maps_init();
+
qed_ops = qed_get_eth_ops();
if (!qed_ops) {
pr_notice("Failed to get qed ethtool operations\n");
@@ -662,79 +637,81 @@ qede_setup_tc_offload(struct net_device *dev, enum tc_setup_type type,
}
static const struct net_device_ops qede_netdev_ops = {
- .ndo_open = qede_open,
- .ndo_stop = qede_close,
- .ndo_start_xmit = qede_start_xmit,
- .ndo_select_queue = qede_select_queue,
- .ndo_set_rx_mode = qede_set_rx_mode,
- .ndo_set_mac_address = qede_set_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = qede_change_mtu,
- .ndo_do_ioctl = qede_ioctl,
- .ndo_tx_timeout = qede_tx_timeout,
+ .ndo_open = qede_open,
+ .ndo_stop = qede_close,
+ .ndo_start_xmit = qede_start_xmit,
+ .ndo_select_queue = qede_select_queue,
+ .ndo_set_rx_mode = qede_set_rx_mode,
+ .ndo_set_mac_address = qede_set_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = qede_change_mtu,
+ .ndo_do_ioctl = qede_ioctl,
+ .ndo_tx_timeout = qede_tx_timeout,
#ifdef CONFIG_QED_SRIOV
- .ndo_set_vf_mac = qede_set_vf_mac,
- .ndo_set_vf_vlan = qede_set_vf_vlan,
- .ndo_set_vf_trust = qede_set_vf_trust,
+ .ndo_set_vf_mac = qede_set_vf_mac,
+ .ndo_set_vf_vlan = qede_set_vf_vlan,
+ .ndo_set_vf_trust = qede_set_vf_trust,
#endif
- .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid,
- .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid,
- .ndo_fix_features = qede_fix_features,
- .ndo_set_features = qede_set_features,
- .ndo_get_stats64 = qede_get_stats64,
+ .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid,
+ .ndo_fix_features = qede_fix_features,
+ .ndo_set_features = qede_set_features,
+ .ndo_get_stats64 = qede_get_stats64,
#ifdef CONFIG_QED_SRIOV
- .ndo_set_vf_link_state = qede_set_vf_link_state,
- .ndo_set_vf_spoofchk = qede_set_vf_spoofchk,
- .ndo_get_vf_config = qede_get_vf_config,
- .ndo_set_vf_rate = qede_set_vf_rate,
+ .ndo_set_vf_link_state = qede_set_vf_link_state,
+ .ndo_set_vf_spoofchk = qede_set_vf_spoofchk,
+ .ndo_get_vf_config = qede_get_vf_config,
+ .ndo_set_vf_rate = qede_set_vf_rate,
#endif
- .ndo_udp_tunnel_add = qede_udp_tunnel_add,
- .ndo_udp_tunnel_del = qede_udp_tunnel_del,
- .ndo_features_check = qede_features_check,
- .ndo_bpf = qede_xdp,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
+ .ndo_features_check = qede_features_check,
+ .ndo_bpf = qede_xdp,
#ifdef CONFIG_RFS_ACCEL
- .ndo_rx_flow_steer = qede_rx_flow_steer,
+ .ndo_rx_flow_steer = qede_rx_flow_steer,
#endif
- .ndo_setup_tc = qede_setup_tc_offload,
+ .ndo_xdp_xmit = qede_xdp_transmit,
+ .ndo_setup_tc = qede_setup_tc_offload,
};
static const struct net_device_ops qede_netdev_vf_ops = {
- .ndo_open = qede_open,
- .ndo_stop = qede_close,
- .ndo_start_xmit = qede_start_xmit,
- .ndo_select_queue = qede_select_queue,
- .ndo_set_rx_mode = qede_set_rx_mode,
- .ndo_set_mac_address = qede_set_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = qede_change_mtu,
- .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid,
- .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid,
- .ndo_fix_features = qede_fix_features,
- .ndo_set_features = qede_set_features,
- .ndo_get_stats64 = qede_get_stats64,
- .ndo_udp_tunnel_add = qede_udp_tunnel_add,
- .ndo_udp_tunnel_del = qede_udp_tunnel_del,
- .ndo_features_check = qede_features_check,
+ .ndo_open = qede_open,
+ .ndo_stop = qede_close,
+ .ndo_start_xmit = qede_start_xmit,
+ .ndo_select_queue = qede_select_queue,
+ .ndo_set_rx_mode = qede_set_rx_mode,
+ .ndo_set_mac_address = qede_set_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = qede_change_mtu,
+ .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid,
+ .ndo_fix_features = qede_fix_features,
+ .ndo_set_features = qede_set_features,
+ .ndo_get_stats64 = qede_get_stats64,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
+ .ndo_features_check = qede_features_check,
};
static const struct net_device_ops qede_netdev_vf_xdp_ops = {
- .ndo_open = qede_open,
- .ndo_stop = qede_close,
- .ndo_start_xmit = qede_start_xmit,
- .ndo_select_queue = qede_select_queue,
- .ndo_set_rx_mode = qede_set_rx_mode,
- .ndo_set_mac_address = qede_set_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = qede_change_mtu,
- .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid,
- .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid,
- .ndo_fix_features = qede_fix_features,
- .ndo_set_features = qede_set_features,
- .ndo_get_stats64 = qede_get_stats64,
- .ndo_udp_tunnel_add = qede_udp_tunnel_add,
- .ndo_udp_tunnel_del = qede_udp_tunnel_del,
- .ndo_features_check = qede_features_check,
- .ndo_bpf = qede_xdp,
+ .ndo_open = qede_open,
+ .ndo_stop = qede_close,
+ .ndo_start_xmit = qede_start_xmit,
+ .ndo_select_queue = qede_select_queue,
+ .ndo_set_rx_mode = qede_set_rx_mode,
+ .ndo_set_mac_address = qede_set_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = qede_change_mtu,
+ .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid,
+ .ndo_fix_features = qede_fix_features,
+ .ndo_set_features = qede_set_features,
+ .ndo_get_stats64 = qede_get_stats64,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
+ .ndo_features_check = qede_features_check,
+ .ndo_bpf = qede_xdp,
+ .ndo_xdp_xmit = qede_xdp_transmit,
};
/* -------------------------------------------------------------------------
@@ -847,6 +824,8 @@ static void qede_init_ndev(struct qede_dev *edev)
NETIF_F_GSO_UDP_TUNNEL_CSUM);
ndev->hw_enc_features |= (NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM);
+
+ qede_set_udp_tunnels(edev);
}
if (edev->dev_info.common.gre_enable) {
@@ -1463,6 +1442,11 @@ static void qede_set_tpa_param(struct qede_rx_queue *rxq)
/* This function allocates all memory needed per Rx queue */
static int qede_alloc_mem_rxq(struct qede_dev *edev, struct qede_rx_queue *rxq)
{
+ struct qed_chain_init_params params = {
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
+ .num_elems = RX_RING_SIZE,
+ };
+ struct qed_dev *cdev = edev->cdev;
int i, rc, size;
rxq->num_rx_buffers = edev->q_num_rx_buffers;
@@ -1498,24 +1482,20 @@ static int qede_alloc_mem_rxq(struct qede_dev *edev, struct qede_rx_queue *rxq)
}
/* Allocate FW Rx ring */
- rc = edev->ops->common->chain_alloc(edev->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_NEXT_PTR,
- QED_CHAIN_CNT_TYPE_U16,
- RX_RING_SIZE,
- sizeof(struct eth_rx_bd),
- &rxq->rx_bd_ring, NULL);
+ params.mode = QED_CHAIN_MODE_NEXT_PTR;
+ params.intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE;
+ params.elem_size = sizeof(struct eth_rx_bd);
+
+ rc = edev->ops->common->chain_alloc(cdev, &rxq->rx_bd_ring, &params);
if (rc)
goto err;
/* Allocate FW completion ring */
- rc = edev->ops->common->chain_alloc(edev->cdev,
- QED_CHAIN_USE_TO_CONSUME,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- RX_RING_SIZE,
- sizeof(union eth_rx_cqe),
- &rxq->rx_comp_ring, NULL);
+ params.mode = QED_CHAIN_MODE_PBL;
+ params.intended_use = QED_CHAIN_USE_TO_CONSUME;
+ params.elem_size = sizeof(union eth_rx_cqe);
+
+ rc = edev->ops->common->chain_alloc(cdev, &rxq->rx_comp_ring, &params);
if (rc)
goto err;
@@ -1552,7 +1532,13 @@ static void qede_free_mem_txq(struct qede_dev *edev, struct qede_tx_queue *txq)
/* This function allocates all memory needed per Tx queue */
static int qede_alloc_mem_txq(struct qede_dev *edev, struct qede_tx_queue *txq)
{
- union eth_tx_bd_types *p_virt;
+ struct qed_chain_init_params params = {
+ .mode = QED_CHAIN_MODE_PBL,
+ .intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE,
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
+ .num_elems = edev->q_num_tx_buffers,
+ .elem_size = sizeof(union eth_tx_bd_types),
+ };
int size, rc;
txq->num_tx_buffers = edev->q_num_tx_buffers;
@@ -1570,13 +1556,7 @@ static int qede_alloc_mem_txq(struct qede_dev *edev, struct qede_tx_queue *txq)
goto err;
}
- rc = edev->ops->common->chain_alloc(edev->cdev,
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
- QED_CHAIN_MODE_PBL,
- QED_CHAIN_CNT_TYPE_U16,
- txq->num_tx_buffers,
- sizeof(*p_virt),
- &txq->tx_pbl, NULL);
+ rc = edev->ops->common->chain_alloc(edev->cdev, &txq->tx_pbl, &params);
if (rc)
goto err;
@@ -1732,6 +1712,7 @@ static void qede_init_fp(struct qede_dev *edev)
{
int queue_id, rxq_index = 0, txq_index = 0;
struct qede_fastpath *fp;
+ bool init_xdp = false;
for_each_queue(queue_id) {
fp = &edev->fp_array[queue_id];
@@ -1743,6 +1724,9 @@ static void qede_init_fp(struct qede_dev *edev)
fp->xdp_tx->index = QEDE_TXQ_IDX_TO_XDP(edev,
rxq_index);
fp->xdp_tx->is_xdp = 1;
+
+ spin_lock_init(&fp->xdp_tx->xdp_tx_lock);
+ init_xdp = true;
}
if (fp->type & QEDE_FASTPATH_RX) {
@@ -1758,6 +1742,13 @@ static void qede_init_fp(struct qede_dev *edev)
/* Driver have no error path from here */
WARN_ON(xdp_rxq_info_reg(&fp->rxq->xdp_rxq, edev->ndev,
fp->rxq->rxq_id) < 0);
+
+ if (xdp_rxq_info_reg_mem_model(&fp->rxq->xdp_rxq,
+ MEM_TYPE_PAGE_ORDER0,
+ NULL)) {
+ DP_NOTICE(edev,
+ "Failed to register XDP memory model\n");
+ }
}
if (fp->type & QEDE_FASTPATH_TX) {
@@ -1783,6 +1774,11 @@ static void qede_init_fp(struct qede_dev *edev)
snprintf(fp->name, sizeof(fp->name), "%s-fp-%d",
edev->ndev->name, queue_id);
}
+
+ if (init_xdp) {
+ edev->total_xdp_queues = QEDE_RSS_COUNT(edev);
+ DP_INFO(edev, "Total XDP queues: %u\n", edev->total_xdp_queues);
+ }
}
static int qede_set_real_num_queues(struct qede_dev *edev)
@@ -2446,7 +2442,7 @@ static int qede_open(struct net_device *ndev)
if (rc)
return rc;
- udp_tunnel_get_rx_info(ndev);
+ udp_tunnel_nic_reset_ntf(ndev);
edev->ops->common->update_drv_state(edev->cdev, true);
@@ -2548,7 +2544,7 @@ static void qede_recovery_handler(struct qede_dev *edev)
goto err;
qede_config_rx_mode(edev->ndev);
- udp_tunnel_get_rx_info(edev->ndev);
+ udp_tunnel_nic_reset_ntf(edev->ndev);
}
edev->state = curr_state;
@@ -2678,8 +2674,8 @@ static void qede_get_generic_tlv_data(void *dev, struct qed_generic_tlvs *data)
data->feat_flags |= QED_TLV_LSO;
ether_addr_copy(data->mac[0], edev->ndev->dev_addr);
- memset(data->mac[1], 0, ETH_ALEN);
- memset(data->mac[2], 0, ETH_ALEN);
+ eth_zero_addr(data->mac[1]);
+ eth_zero_addr(data->mac[2]);
/* Copy the first two UC macs */
netif_addr_lock_bh(edev->ndev);
i = 1;
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
index cd5841a9415e..8c28fabb0ff6 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c
@@ -1,34 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qede NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include "qede_ptp.h"
#define QEDE_PTP_TX_TIMEOUT (2 * HZ)
@@ -53,12 +28,12 @@ struct qede_ptp {
};
/**
- * qede_ptp_adjfreq
- * @ptp: the ptp clock structure
- * @ppb: parts per billion adjustment from base
+ * qede_ptp_adjfreq() - Adjust the frequency of the PTP cycle counter.
+ *
+ * @info: The PTP clock info structure.
+ * @ppb: Parts per billion adjustment from base.
*
- * Adjust the frequency of the ptp cycle counter by the
- * indicated ppb from the base frequency.
+ * Return: Zero on success, negative errno otherwise.
*/
static int qede_ptp_adjfreq(struct ptp_clock_info *info, s32 ppb)
{
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.h b/drivers/net/ethernet/qlogic/qede/qede_ptp.h
index 89c7f3cf3ee2..1db0f021c645 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ptp.h
+++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.h
@@ -1,34 +1,9 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/* QLogic qede NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#ifndef _QEDE_PTP_H_
#define _QEDE_PTP_H_
diff --git a/drivers/net/ethernet/qlogic/qede/qede_rdma.c b/drivers/net/ethernet/qlogic/qede/qede_rdma.c
index 668ccc9d49f8..769ec2f4d0b7 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_rdma.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_rdma.c
@@ -1,34 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qedr NIC Driver
* Copyright (c) 2015-2017 QLogic Corporation
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and /or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright (c) 2019-2020 Marvell International Ltd.
*/
+
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/list.h>
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index d838774af5a6..d67f8265724a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -536,8 +536,6 @@ struct qlcnic_hardware_context {
u8 extend_lb_time;
u8 phys_port_id[ETH_ALEN];
u8 lb_mode;
- u8 vxlan_port_count;
- u16 vxlan_port;
struct device *hwmon_dev;
u32 post_mode;
bool run_post;
@@ -1026,9 +1024,6 @@ struct qlcnic_ipaddr {
#define QLCNIC_HAS_PHYS_PORT_ID 0x40000
#define QLCNIC_TSS_RSS 0x80000
-#define QLCNIC_ADD_VXLAN_PORT 0x100000
-#define QLCNIC_DEL_VXLAN_PORT 0x200000
-
#define QLCNIC_VLAN_FILTERING 0x800000
#define QLCNIC_IS_MSI_FAMILY(adapter) \
@@ -1700,6 +1695,8 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *);
int qlcnic_set_default_offload_settings(struct qlcnic_adapter *);
int qlcnic_reset_npar_config(struct qlcnic_adapter *);
int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *);
+int qlcnic_set_vxlan_port(struct qlcnic_adapter *adapter, u16 port);
+int qlcnic_set_vxlan_parsing(struct qlcnic_adapter *adapter, u16 port);
int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
int qlcnic_read_mac_addr(struct qlcnic_adapter *);
int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index cda5b0a9e948..0e2f2fb6c3a9 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -1028,9 +1028,8 @@ static int qlcnic_83xx_idc_check_state_validity(struct qlcnic_adapter *adapter,
#define QLCNIC_ENABLE_INGRESS_ENCAP_PARSING 1
#define QLCNIC_DISABLE_INGRESS_ENCAP_PARSING 0
-static int qlcnic_set_vxlan_port(struct qlcnic_adapter *adapter)
+int qlcnic_set_vxlan_port(struct qlcnic_adapter *adapter, u16 port)
{
- u16 port = adapter->ahw->vxlan_port;
struct qlcnic_cmd_args cmd;
int ret = 0;
@@ -1057,10 +1056,8 @@ static int qlcnic_set_vxlan_port(struct qlcnic_adapter *adapter)
return ret;
}
-static int qlcnic_set_vxlan_parsing(struct qlcnic_adapter *adapter,
- bool state)
+int qlcnic_set_vxlan_parsing(struct qlcnic_adapter *adapter, u16 port)
{
- u16 vxlan_port = adapter->ahw->vxlan_port;
struct qlcnic_cmd_args cmd;
int ret = 0;
@@ -1071,18 +1068,18 @@ static int qlcnic_set_vxlan_parsing(struct qlcnic_adapter *adapter,
if (ret)
return ret;
- cmd.req.arg[1] = state ? QLCNIC_ENABLE_INGRESS_ENCAP_PARSING :
- QLCNIC_DISABLE_INGRESS_ENCAP_PARSING;
+ cmd.req.arg[1] = port ? QLCNIC_ENABLE_INGRESS_ENCAP_PARSING :
+ QLCNIC_DISABLE_INGRESS_ENCAP_PARSING;
ret = qlcnic_issue_cmd(adapter, &cmd);
if (ret)
netdev_err(adapter->netdev,
"Failed to %s VXLAN parsing for port %d\n",
- state ? "enable" : "disable", vxlan_port);
+ port ? "enable" : "disable", port);
else
netdev_info(adapter->netdev,
"%s VXLAN parsing for port %d\n",
- state ? "Enabled" : "Disabled", vxlan_port);
+ port ? "Enabled" : "Disabled", port);
qlcnic_free_mbx_args(&cmd);
@@ -1093,22 +1090,6 @@ static void qlcnic_83xx_periodic_tasks(struct qlcnic_adapter *adapter)
{
if (adapter->fhash.fnum)
qlcnic_prune_lb_filters(adapter);
-
- if (adapter->flags & QLCNIC_ADD_VXLAN_PORT) {
- if (qlcnic_set_vxlan_port(adapter))
- return;
-
- if (qlcnic_set_vxlan_parsing(adapter, true))
- return;
-
- adapter->flags &= ~QLCNIC_ADD_VXLAN_PORT;
- } else if (adapter->flags & QLCNIC_DEL_VXLAN_PORT) {
- if (qlcnic_set_vxlan_parsing(adapter, false))
- return;
-
- adapter->ahw->vxlan_port = 0;
- adapter->flags &= ~QLCNIC_DEL_VXLAN_PORT;
- }
}
/**
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 822aa393c370..35d891f4655a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -1649,7 +1649,6 @@ int qlcnic_82xx_shutdown(struct pci_dev *pdev)
{
struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *netdev = adapter->netdev;
- int retval;
netif_device_detach(netdev);
@@ -1662,14 +1661,8 @@ int qlcnic_82xx_shutdown(struct pci_dev *pdev)
clear_bit(__QLCNIC_RESETTING, &adapter->state);
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-
- if (qlcnic_wol_supported(adapter)) {
- pci_enable_wake(pdev, PCI_D3cold, 1);
- pci_enable_wake(pdev, PCI_D3hot, 1);
- }
+ if (qlcnic_wol_supported(adapter))
+ device_wakeup_enable(&pdev->dev);
return 0;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 9dd6cb36f366..173c7300cdf7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -471,48 +471,29 @@ static int qlcnic_get_phys_port_id(struct net_device *netdev,
return 0;
}
-static void qlcnic_add_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
+static int qlcnic_udp_tunnel_sync(struct net_device *dev, unsigned int table)
{
- struct qlcnic_adapter *adapter = netdev_priv(netdev);
- struct qlcnic_hardware_context *ahw = adapter->ahw;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
+ struct qlcnic_adapter *adapter = netdev_priv(dev);
+ struct udp_tunnel_info ti;
+ int err;
- /* Adapter supports only one VXLAN port. Use very first port
- * for enabling offload
- */
- if (!qlcnic_encap_rx_offload(adapter))
- return;
- if (!ahw->vxlan_port_count) {
- ahw->vxlan_port_count = 1;
- ahw->vxlan_port = ntohs(ti->port);
- adapter->flags |= QLCNIC_ADD_VXLAN_PORT;
- return;
+ udp_tunnel_nic_get_port(dev, table, 0, &ti);
+ if (ti.port) {
+ err = qlcnic_set_vxlan_port(adapter, ntohs(ti.port));
+ if (err)
+ return err;
}
- if (ahw->vxlan_port == ntohs(ti->port))
- ahw->vxlan_port_count++;
+ return qlcnic_set_vxlan_parsing(adapter, ntohs(ti.port));
}
-static void qlcnic_del_vxlan_port(struct net_device *netdev,
- struct udp_tunnel_info *ti)
-{
- struct qlcnic_adapter *adapter = netdev_priv(netdev);
- struct qlcnic_hardware_context *ahw = adapter->ahw;
-
- if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
- return;
-
- if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port_count ||
- (ahw->vxlan_port != ntohs(ti->port)))
- return;
-
- ahw->vxlan_port_count--;
- if (!ahw->vxlan_port_count)
- adapter->flags |= QLCNIC_DEL_VXLAN_PORT;
-}
+static const struct udp_tunnel_nic_info qlcnic_udp_tunnels = {
+ .sync_table = qlcnic_udp_tunnel_sync,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
static netdev_features_t qlcnic_features_check(struct sk_buff *skb,
struct net_device *dev,
@@ -540,8 +521,8 @@ static const struct net_device_ops qlcnic_netdev_ops = {
.ndo_fdb_del = qlcnic_fdb_del,
.ndo_fdb_dump = qlcnic_fdb_dump,
.ndo_get_phys_port_id = qlcnic_get_phys_port_id,
- .ndo_udp_tunnel_add = qlcnic_add_vxlan_port,
- .ndo_udp_tunnel_del = qlcnic_del_vxlan_port,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_features_check = qlcnic_features_check,
#ifdef CONFIG_QLCNIC_SRIOV
.ndo_set_vf_mac = qlcnic_sriov_set_vf_mac,
@@ -2017,7 +1998,7 @@ qlcnic_attach(struct qlcnic_adapter *adapter)
qlcnic_create_sysfs_entries(adapter);
if (qlcnic_encap_rx_offload(adapter))
- udp_tunnel_get_rx_info(netdev);
+ udp_tunnel_nic_reset_ntf(netdev);
adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC;
return 0;
@@ -2335,9 +2316,12 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
NETIF_F_TSO6;
}
- if (qlcnic_encap_rx_offload(adapter))
+ if (qlcnic_encap_rx_offload(adapter)) {
netdev->hw_enc_features |= NETIF_F_RXCSUM;
+ netdev->udp_tunnel_nic_info = &qlcnic_udp_tunnels;
+ }
+
netdev->hw_features = netdev->features;
netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->irq = adapter->msix_entries[0].vector;
@@ -2811,35 +2795,17 @@ static void qlcnic_shutdown(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-#ifdef CONFIG_PM
-static int qlcnic_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused qlcnic_suspend(struct device *dev_d)
{
- int retval;
-
- retval = __qlcnic_shutdown(pdev);
- if (retval)
- return retval;
-
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return 0;
+ return __qlcnic_shutdown(to_pci_dev(dev_d));
}
-static int qlcnic_resume(struct pci_dev *pdev)
+static int __maybe_unused qlcnic_resume(struct device *dev_d)
{
- struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
- int err;
-
- err = pci_enable_device(pdev);
- if (err)
- return err;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_set_master(pdev);
- pci_restore_state(pdev);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev_d);
return __qlcnic_resume(adapter);
}
-#endif
static int qlcnic_open(struct net_device *netdev)
{
@@ -4258,15 +4224,14 @@ static const struct pci_error_handlers qlcnic_err_handler = {
.resume = qlcnic_io_resume,
};
+static SIMPLE_DEV_PM_OPS(qlcnic_pm_ops, qlcnic_suspend, qlcnic_resume);
+
static struct pci_driver qlcnic_driver = {
.name = qlcnic_driver_name,
.id_table = qlcnic_pci_tbl,
.probe = qlcnic_probe,
.remove = qlcnic_remove,
-#ifdef CONFIG_PM
- .suspend = qlcnic_suspend,
- .resume = qlcnic_resume,
-#endif
+ .driver.pm = &qlcnic_pm_ops,
.shutdown = qlcnic_shutdown,
.err_handler = &qlcnic_err_handler,
#ifdef CONFIG_QLCNIC_SRIOV
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
index f5ecc410ff85..7c74318620b1 100644
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -262,9 +262,9 @@ static void r6040_free_txbufs(struct net_device *dev)
for (i = 0; i < TX_DCNT; i++) {
if (lp->tx_insert_ptr->skb_ptr) {
- pci_unmap_single(lp->pdev,
- le32_to_cpu(lp->tx_insert_ptr->buf),
- MAX_BUF_SIZE, PCI_DMA_TODEVICE);
+ dma_unmap_single(&lp->pdev->dev,
+ le32_to_cpu(lp->tx_insert_ptr->buf),
+ MAX_BUF_SIZE, DMA_TO_DEVICE);
dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
lp->tx_insert_ptr->skb_ptr = NULL;
}
@@ -279,9 +279,9 @@ static void r6040_free_rxbufs(struct net_device *dev)
for (i = 0; i < RX_DCNT; i++) {
if (lp->rx_insert_ptr->skb_ptr) {
- pci_unmap_single(lp->pdev,
- le32_to_cpu(lp->rx_insert_ptr->buf),
- MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&lp->pdev->dev,
+ le32_to_cpu(lp->rx_insert_ptr->buf),
+ MAX_BUF_SIZE, DMA_FROM_DEVICE);
dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
lp->rx_insert_ptr->skb_ptr = NULL;
}
@@ -335,9 +335,10 @@ static int r6040_alloc_rxbufs(struct net_device *dev)
goto err_exit;
}
desc->skb_ptr = skb;
- desc->buf = cpu_to_le32(pci_map_single(lp->pdev,
- desc->skb_ptr->data,
- MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
+ desc->buf = cpu_to_le32(dma_map_single(&lp->pdev->dev,
+ desc->skb_ptr->data,
+ MAX_BUF_SIZE,
+ DMA_FROM_DEVICE));
desc->status = DSC_OWNER_MAC;
desc = desc->vndescp;
} while (desc != lp->rx_ring);
@@ -484,14 +485,14 @@ static int r6040_close(struct net_device *dev)
/* Free Descriptor memory */
if (lp->rx_ring) {
- pci_free_consistent(pdev,
- RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
+ dma_free_coherent(&pdev->dev, RX_DESC_SIZE, lp->rx_ring,
+ lp->rx_ring_dma);
lp->rx_ring = NULL;
}
if (lp->tx_ring) {
- pci_free_consistent(pdev,
- TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
+ dma_free_coherent(&pdev->dev, TX_DESC_SIZE, lp->tx_ring,
+ lp->tx_ring_dma);
lp->tx_ring = NULL;
}
@@ -544,8 +545,8 @@ static int r6040_rx(struct net_device *dev, int limit)
/* Do not count the CRC */
skb_put(skb_ptr, descptr->len - 4);
- pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
- MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&priv->pdev->dev, le32_to_cpu(descptr->buf),
+ MAX_BUF_SIZE, DMA_FROM_DEVICE);
skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev);
/* Send to upper layer */
@@ -555,9 +556,10 @@ static int r6040_rx(struct net_device *dev, int limit)
/* put new skb into descriptor */
descptr->skb_ptr = new_skb;
- descptr->buf = cpu_to_le32(pci_map_single(priv->pdev,
- descptr->skb_ptr->data,
- MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
+ descptr->buf = cpu_to_le32(dma_map_single(&priv->pdev->dev,
+ descptr->skb_ptr->data,
+ MAX_BUF_SIZE,
+ DMA_FROM_DEVICE));
next_descr:
/* put the descriptor back to the MAC */
@@ -597,8 +599,8 @@ static void r6040_tx(struct net_device *dev)
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb_ptr->len;
- pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
- skb_ptr->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&priv->pdev->dev, le32_to_cpu(descptr->buf),
+ skb_ptr->len, DMA_TO_DEVICE);
/* Free buffer */
dev_kfree_skb(skb_ptr);
descptr->skb_ptr = NULL;
@@ -750,14 +752,16 @@ static int r6040_open(struct net_device *dev)
/* Allocate Descriptor memory */
lp->rx_ring =
- pci_alloc_consistent(lp->pdev, RX_DESC_SIZE, &lp->rx_ring_dma);
+ dma_alloc_coherent(&lp->pdev->dev, RX_DESC_SIZE,
+ &lp->rx_ring_dma, GFP_KERNEL);
if (!lp->rx_ring) {
ret = -ENOMEM;
goto err_free_irq;
}
lp->tx_ring =
- pci_alloc_consistent(lp->pdev, TX_DESC_SIZE, &lp->tx_ring_dma);
+ dma_alloc_coherent(&lp->pdev->dev, TX_DESC_SIZE,
+ &lp->tx_ring_dma, GFP_KERNEL);
if (!lp->tx_ring) {
ret = -ENOMEM;
goto err_free_rx_ring;
@@ -773,11 +777,11 @@ static int r6040_open(struct net_device *dev)
return 0;
err_free_tx_ring:
- pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring,
- lp->tx_ring_dma);
+ dma_free_coherent(&lp->pdev->dev, TX_DESC_SIZE, lp->tx_ring,
+ lp->tx_ring_dma);
err_free_rx_ring:
- pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
- lp->rx_ring_dma);
+ dma_free_coherent(&lp->pdev->dev, RX_DESC_SIZE, lp->rx_ring,
+ lp->rx_ring_dma);
err_free_irq:
free_irq(dev->irq, dev);
out:
@@ -811,8 +815,8 @@ static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
descptr = lp->tx_insert_ptr;
descptr->len = skb->len;
descptr->skb_ptr = skb;
- descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
- skb->data, skb->len, PCI_DMA_TODEVICE));
+ descptr->buf = cpu_to_le32(dma_map_single(&lp->pdev->dev, skb->data,
+ skb->len, DMA_TO_DEVICE));
descptr->status = DSC_OWNER_MAC;
skb_tx_timestamp(skb);
@@ -1029,12 +1033,12 @@ static int r6040_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out;
/* this should always be supported */
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "32-bit PCI DMA addresses not supported by the card\n");
goto err_out_disable_dev;
}
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "32-bit PCI DMA addresses not supported by the card\n");
goto err_out_disable_dev;
diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h
index 22a6a057b11e..7be86ef5a584 100644
--- a/drivers/net/ethernet/realtek/r8169.h
+++ b/drivers/net/ethernet/realtek/r8169.h
@@ -26,7 +26,6 @@ enum mac_version {
RTL_GIGA_MAC_VER_12,
RTL_GIGA_MAC_VER_13,
RTL_GIGA_MAC_VER_14,
- RTL_GIGA_MAC_VER_15,
RTL_GIGA_MAC_VER_16,
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
@@ -66,6 +65,7 @@ enum mac_version {
RTL_GIGA_MAC_VER_52,
RTL_GIGA_MAC_VER_60,
RTL_GIGA_MAC_VER_61,
+ RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_NONE
};
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
index b660ddbe4025..d1da92ac7fbe 100644
--- a/drivers/net/ethernet/realtek/r8169_main.c
+++ b/drivers/net/ethernet/realtek/r8169_main.c
@@ -56,6 +56,7 @@
#define FIRMWARE_8107E_1 "rtl_nic/rtl8107e-1.fw"
#define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
#define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
+#define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
The RTL chips use a 64 element hash table based on the Ethernet CRC. */
@@ -105,9 +106,8 @@ static const struct {
[RTL_GIGA_MAC_VER_10] = {"RTL8101e" },
[RTL_GIGA_MAC_VER_11] = {"RTL8168b/8111b" },
[RTL_GIGA_MAC_VER_12] = {"RTL8168b/8111b" },
- [RTL_GIGA_MAC_VER_13] = {"RTL8101e" },
- [RTL_GIGA_MAC_VER_14] = {"RTL8100e" },
- [RTL_GIGA_MAC_VER_15] = {"RTL8100e" },
+ [RTL_GIGA_MAC_VER_13] = {"RTL8101e/RTL8100e" },
+ [RTL_GIGA_MAC_VER_14] = {"RTL8401" },
[RTL_GIGA_MAC_VER_16] = {"RTL8101e" },
[RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b" },
[RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp" },
@@ -145,8 +145,10 @@ static const struct {
[RTL_GIGA_MAC_VER_50] = {"RTL8168ep/8111ep" },
[RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep" },
[RTL_GIGA_MAC_VER_52] = {"RTL8168fp/RTL8117", FIRMWARE_8168FP_3},
- [RTL_GIGA_MAC_VER_60] = {"RTL8125" },
- [RTL_GIGA_MAC_VER_61] = {"RTL8125", FIRMWARE_8125A_3},
+ [RTL_GIGA_MAC_VER_60] = {"RTL8125A" },
+ [RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3},
+ /* reserve 62 for CFG_METHOD_4 in the vendor driver */
+ [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
};
static const struct pci_device_id rtl8169_pci_tbl[] = {
@@ -336,6 +338,7 @@ enum rtl8125_registers {
IntrStatus_8125 = 0x3c,
TxPoll_8125 = 0x90,
MAC0_BKP = 0x19e0,
+ EEE_TXIDLE_TIMER_8125 = 0x6048,
};
#define RX_VLAN_INNER_8125 BIT(22)
@@ -529,8 +532,6 @@ enum rtl_rx_desc_bit {
RxVlanTag = (1 << 16), /* VLAN tag available */
};
-#define RsvdMask 0x3fffc000
-
#define RTL_GSO_MAX_SIZE_V1 32000
#define RTL_GSO_MAX_SEGS_V1 24
#define RTL_GSO_MAX_SIZE_V2 64000
@@ -613,7 +614,6 @@ struct rtl8169_private {
struct {
DECLARE_BITMAP(flags, RTL_FLAG_MAX);
- struct mutex mutex;
struct work_struct work;
} wk;
@@ -659,22 +659,13 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
MODULE_FIRMWARE(FIRMWARE_8107E_1);
MODULE_FIRMWARE(FIRMWARE_8107E_2);
MODULE_FIRMWARE(FIRMWARE_8125A_3);
+MODULE_FIRMWARE(FIRMWARE_8125B_2);
static inline struct device *tp_to_dev(struct rtl8169_private *tp)
{
return &tp->pci_dev->dev;
}
-static void rtl_lock_work(struct rtl8169_private *tp)
-{
- mutex_lock(&tp->wk.mutex);
-}
-
-static void rtl_unlock_work(struct rtl8169_private *tp)
-{
- mutex_unlock(&tp->wk.mutex);
-}
-
static void rtl_lock_config_regs(struct rtl8169_private *tp)
{
RTL_W8(tp, Cfg9346, Cfg9346_Lock);
@@ -980,7 +971,7 @@ static void rtl_writephy(struct rtl8169_private *tp, int location, int val)
case RTL_GIGA_MAC_VER_31:
r8168dp_2_mdio_write(tp, location, val);
break;
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
r8168g_mdio_write(tp, location, val);
break;
default:
@@ -997,7 +988,7 @@ static int rtl_readphy(struct rtl8169_private *tp, int location)
case RTL_GIGA_MAC_VER_28:
case RTL_GIGA_MAC_VER_31:
return r8168dp_2_mdio_read(tp, location);
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
return r8168g_mdio_read(tp, location);
default:
return r8169_mdio_read(tp, location);
@@ -1350,10 +1341,8 @@ static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct rtl8169_private *tp = netdev_priv(dev);
- rtl_lock_work(tp);
wol->supported = WAKE_ANY;
wol->wolopts = tp->saved_wolopts;
- rtl_unlock_work(tp);
}
static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
@@ -1405,7 +1394,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
break;
case RTL_GIGA_MAC_VER_34:
case RTL_GIGA_MAC_VER_37:
- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
options = RTL_R8(tp, Config2) & ~PME_SIGNAL;
if (wolopts)
options |= PME_SIGNAL;
@@ -1424,23 +1413,12 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct rtl8169_private *tp = netdev_priv(dev);
- struct device *d = tp_to_dev(tp);
if (wol->wolopts & ~WAKE_ANY)
return -EINVAL;
- pm_runtime_get_noresume(d);
-
- rtl_lock_work(tp);
-
tp->saved_wolopts = wol->wolopts;
-
- if (pm_runtime_active(d))
- __rtl8169_set_wol(tp, tp->saved_wolopts);
-
- rtl_unlock_work(tp);
-
- pm_runtime_put_noidle(d);
+ __rtl8169_set_wol(tp, tp->saved_wolopts);
return 0;
}
@@ -1504,8 +1482,6 @@ static int rtl8169_set_features(struct net_device *dev,
{
struct rtl8169_private *tp = netdev_priv(dev);
- rtl_lock_work(tp);
-
rtl_set_rx_config_features(tp, features);
if (features & NETIF_F_RXCSUM)
@@ -1523,8 +1499,6 @@ static int rtl8169_set_features(struct net_device *dev,
RTL_W16(tp, CPlusCmd, tp->cp_cmd);
rtl_pci_commit(tp);
- rtl_unlock_work(tp);
-
return 0;
}
@@ -1550,10 +1524,8 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
u32 *dw = p;
int i;
- rtl_lock_work(tp);
for (i = 0; i < R8169_REGS_SIZE; i += 4)
memcpy_fromio(dw++, data++, 4);
- rtl_unlock_work(tp);
}
static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
@@ -1659,17 +1631,10 @@ static void rtl8169_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct rtl8169_private *tp = netdev_priv(dev);
- struct device *d = tp_to_dev(tp);
- struct rtl8169_counters *counters = tp->counters;
-
- ASSERT_RTNL();
-
- pm_runtime_get_noresume(d);
-
- if (pm_runtime_active(d))
- rtl8169_update_counters(tp);
+ struct rtl8169_counters *counters;
- pm_runtime_put_noidle(d);
+ counters = tp->counters;
+ rtl8169_update_counters(tp);
data[0] = le64_to_cpu(counters->tx_packets);
data[1] = le64_to_cpu(counters->rx_packets);
@@ -1733,16 +1698,16 @@ struct rtl_coalesce_info {
#define COALESCE_DELAY(d) { (d), 8 * (d), 16 * (d), 32 * (d) }
static const struct rtl_coalesce_info rtl_coalesce_info_8169[] = {
- { SPEED_10, COALESCE_DELAY(40960) },
- { SPEED_100, COALESCE_DELAY(2560) },
{ SPEED_1000, COALESCE_DELAY(320) },
+ { SPEED_100, COALESCE_DELAY(2560) },
+ { SPEED_10, COALESCE_DELAY(40960) },
{ 0 },
};
static const struct rtl_coalesce_info rtl_coalesce_info_8168_8136[] = {
- { SPEED_10, COALESCE_DELAY(40960) },
- { SPEED_100, COALESCE_DELAY(2560) },
{ SPEED_1000, COALESCE_DELAY(5000) },
+ { SPEED_100, COALESCE_DELAY(2560) },
+ { SPEED_10, COALESCE_DELAY(40960) },
{ 0 },
};
#undef COALESCE_DELAY
@@ -1758,6 +1723,10 @@ rtl_coalesce_info(struct rtl8169_private *tp)
else
ci = rtl_coalesce_info_8168_8136;
+ /* if speed is unknown assume highest one */
+ if (tp->phydev->speed == SPEED_UNKNOWN)
+ return ci;
+
for (; ci->speed; ci++) {
if (tp->phydev->speed == ci->speed)
return ci;
@@ -1872,8 +1841,6 @@ static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
units = DIV_ROUND_UP(ec->rx_coalesce_usecs * 1000U, scale);
w |= FIELD_PREP(RTL_COALESCE_RX_USECS, units);
- rtl_lock_work(tp);
-
RTL_W16(tp, IntrMitigate, w);
/* Meaning of PktCntrDisable bit changed from RTL8168e-vl */
@@ -1889,56 +1856,32 @@ static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
RTL_W16(tp, CPlusCmd, tp->cp_cmd);
rtl_pci_commit(tp);
- rtl_unlock_work(tp);
-
return 0;
}
static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data)
{
struct rtl8169_private *tp = netdev_priv(dev);
- struct device *d = tp_to_dev(tp);
- int ret;
if (!rtl_supports_eee(tp))
return -EOPNOTSUPP;
- pm_runtime_get_noresume(d);
-
- if (!pm_runtime_active(d)) {
- ret = -EOPNOTSUPP;
- } else {
- ret = phy_ethtool_get_eee(tp->phydev, data);
- }
-
- pm_runtime_put_noidle(d);
-
- return ret;
+ return phy_ethtool_get_eee(tp->phydev, data);
}
static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
{
struct rtl8169_private *tp = netdev_priv(dev);
- struct device *d = tp_to_dev(tp);
int ret;
if (!rtl_supports_eee(tp))
return -EOPNOTSUPP;
- pm_runtime_get_noresume(d);
-
- if (!pm_runtime_active(d)) {
- ret = -EOPNOTSUPP;
- goto out;
- }
-
ret = phy_ethtool_set_eee(tp->phydev, data);
if (!ret)
tp->eee_adv = phy_read_mmd(dev->phydev, MDIO_MMD_AN,
MDIO_AN_EEE_ADV);
-out:
- pm_runtime_put_noidle(d);
return ret;
}
@@ -1997,7 +1940,10 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
u16 val;
enum mac_version ver;
} mac_info[] = {
- /* 8125 family. */
+ /* 8125B family. */
+ { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
+
+ /* 8125A family. */
{ 0x7cf, 0x608, RTL_GIGA_MAC_VER_60 },
{ 0x7c8, 0x608, RTL_GIGA_MAC_VER_61 },
@@ -2062,16 +2008,15 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
{ 0x7cf, 0x348, RTL_GIGA_MAC_VER_07 },
{ 0x7cf, 0x248, RTL_GIGA_MAC_VER_07 },
{ 0x7cf, 0x340, RTL_GIGA_MAC_VER_13 },
- /* RTL8401, reportedly works if treated as RTL8101e */
- { 0x7cf, 0x240, RTL_GIGA_MAC_VER_13 },
+ { 0x7cf, 0x240, RTL_GIGA_MAC_VER_14 },
{ 0x7cf, 0x343, RTL_GIGA_MAC_VER_10 },
{ 0x7cf, 0x342, RTL_GIGA_MAC_VER_16 },
{ 0x7c8, 0x348, RTL_GIGA_MAC_VER_09 },
{ 0x7c8, 0x248, RTL_GIGA_MAC_VER_09 },
{ 0x7c8, 0x340, RTL_GIGA_MAC_VER_16 },
/* FIXME: where did these entries come from ? -- FR */
- { 0xfc8, 0x388, RTL_GIGA_MAC_VER_15 },
- { 0xfc8, 0x308, RTL_GIGA_MAC_VER_14 },
+ { 0xfc8, 0x388, RTL_GIGA_MAC_VER_13 },
+ { 0xfc8, 0x308, RTL_GIGA_MAC_VER_13 },
/* 8110 family. */
{ 0xfc8, 0x980, RTL_GIGA_MAC_VER_06 },
@@ -2130,12 +2075,23 @@ static void rtl8168_config_eee_mac(struct rtl8169_private *tp)
rtl_eri_set_bits(tp, 0x1b0, 0x0003);
}
-static void rtl8125_config_eee_mac(struct rtl8169_private *tp)
+static void rtl8125a_config_eee_mac(struct rtl8169_private *tp)
{
r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0));
r8168_mac_ocp_modify(tp, 0xeb62, 0, BIT(2) | BIT(1));
}
+static void rtl8125_set_eee_txidle_timer(struct rtl8169_private *tp)
+{
+ RTL_W16(tp, EEE_TXIDLE_TIMER_8125, tp->dev->mtu + ETH_HLEN + 0x20);
+}
+
+static void rtl8125b_config_eee_mac(struct rtl8169_private *tp)
+{
+ rtl8125_set_eee_txidle_timer(tp);
+ r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0));
+}
+
static void rtl_rar_exgmac_set(struct rtl8169_private *tp, u8 *addr)
{
const u16 w[] = {
@@ -2199,8 +2155,6 @@ static void rtl8169_init_phy(struct rtl8169_private *tp)
static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
{
- rtl_lock_work(tp);
-
rtl_unlock_config_regs(tp);
RTL_W32(tp, MAC4, addr[4] | addr[5] << 8);
@@ -2213,26 +2167,18 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
rtl_rar_exgmac_set(tp, addr);
rtl_lock_config_regs(tp);
-
- rtl_unlock_work(tp);
}
static int rtl_set_mac_address(struct net_device *dev, void *p)
{
struct rtl8169_private *tp = netdev_priv(dev);
- struct device *d = tp_to_dev(tp);
int ret;
ret = eth_mac_addr(dev, p);
if (ret)
return ret;
- pm_runtime_get_noresume(d);
-
- if (pm_runtime_active(d))
- rtl_rar_set(tp, dev->dev_addr);
-
- pm_runtime_put_noidle(d);
+ rtl_rar_set(tp, dev->dev_addr);
return 0;
}
@@ -2247,7 +2193,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_32:
case RTL_GIGA_MAC_VER_33:
case RTL_GIGA_MAC_VER_34:
- case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_63:
RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) |
AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
break;
@@ -2281,11 +2227,7 @@ static void rtl_pll_power_down(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
- case RTL_GIGA_MAC_VER_50:
- case RTL_GIGA_MAC_VER_51:
- case RTL_GIGA_MAC_VER_52:
- case RTL_GIGA_MAC_VER_60:
- case RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_50 ... RTL_GIGA_MAC_VER_63:
RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80);
break;
case RTL_GIGA_MAC_VER_40:
@@ -2297,10 +2239,14 @@ static void rtl_pll_power_down(struct rtl8169_private *tp)
default:
break;
}
+
+ clk_disable_unprepare(tp->clk);
}
static void rtl_pll_power_up(struct rtl8169_private *tp)
{
+ clk_prepare_enable(tp->clk);
+
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33:
case RTL_GIGA_MAC_VER_37:
@@ -2313,11 +2259,7 @@ static void rtl_pll_power_up(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
- case RTL_GIGA_MAC_VER_50:
- case RTL_GIGA_MAC_VER_51:
- case RTL_GIGA_MAC_VER_52:
- case RTL_GIGA_MAC_VER_60:
- case RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_50 ... RTL_GIGA_MAC_VER_63:
RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0);
break;
case RTL_GIGA_MAC_VER_40:
@@ -2348,7 +2290,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52:
RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
break;
- case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_63:
RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
break;
default:
@@ -2511,6 +2453,12 @@ DECLARE_RTL_COND(rtl_rxtx_empty_cond)
return (RTL_R8(tp, MCU) & RXTX_EMPTY) == RXTX_EMPTY;
}
+DECLARE_RTL_COND(rtl_rxtx_empty_cond_2)
+{
+ /* IntrMitigate has new functionality on RTL8125 */
+ return (RTL_R16(tp, IntrMitigate) & 0x0103) == 0x0103;
+}
+
static void rtl_wait_txrx_fifo_empty(struct rtl8169_private *tp)
{
switch (tp->mac_version) {
@@ -2521,6 +2469,11 @@ static void rtl_wait_txrx_fifo_empty(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61:
rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
break;
+ case RTL_GIGA_MAC_VER_63:
+ RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
+ break;
default:
break;
}
@@ -3470,6 +3423,19 @@ static void rtl_hw_start_8102e_3(struct rtl8169_private *tp)
rtl_ephy_write(tp, 0x03, 0xc2f9);
}
+static void rtl_hw_start_8401(struct rtl8169_private *tp)
+{
+ static const struct ephy_info e_info_8401[] = {
+ { 0x01, 0xffff, 0x6fe5 },
+ { 0x03, 0xffff, 0x0599 },
+ { 0x06, 0xffff, 0xaf25 },
+ { 0x07, 0xffff, 0x8e68 },
+ };
+
+ rtl_ephy_init(tp, e_info_8401);
+ RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
+}
+
static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
{
static const struct ephy_info e_info_8105e_1[] = {
@@ -3579,18 +3545,27 @@ static void rtl_hw_start_8125_common(struct rtl8169_private *tp)
/* disable new tx descriptor format */
r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
- r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
- r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0020);
+ if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
+ else
+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
+
+ if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+ r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0000);
+ else
+ r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0020);
+
r8168_mac_ocp_modify(tp, 0xc0b4, 0x0000, 0x000c);
r8168_mac_ocp_modify(tp, 0xeb6a, 0x00ff, 0x0033);
r8168_mac_ocp_modify(tp, 0xeb50, 0x03e0, 0x0040);
r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030);
r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403);
- r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0067);
+ r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0068);
r8168_mac_ocp_modify(tp, 0xc0ac, 0x0080, 0x1f00);
r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f);
- r8168_mac_ocp_modify(tp, 0xe84c, 0x0000, 0x00c0);
+
r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
r8168_mac_ocp_modify(tp, 0xeb54, 0x0000, 0x0001);
udelay(1);
@@ -3601,15 +3576,18 @@ static void rtl_hw_start_8125_common(struct rtl8169_private *tp)
rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10);
- rtl8125_config_eee_mac(tp);
+ if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+ rtl8125b_config_eee_mac(tp);
+ else
+ rtl8125a_config_eee_mac(tp);
RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN);
udelay(10);
}
-static void rtl_hw_start_8125_1(struct rtl8169_private *tp)
+static void rtl_hw_start_8125a_1(struct rtl8169_private *tp)
{
- static const struct ephy_info e_info_8125_1[] = {
+ static const struct ephy_info e_info_8125a_1[] = {
{ 0x01, 0xffff, 0xa812 },
{ 0x09, 0xffff, 0x520c },
{ 0x04, 0xffff, 0xd000 },
@@ -3641,14 +3619,15 @@ static void rtl_hw_start_8125_1(struct rtl8169_private *tp)
/* disable aspm and clock request before access ephy */
rtl_hw_aspm_clkreq_enable(tp, false);
- rtl_ephy_init(tp, e_info_8125_1);
+ rtl_ephy_init(tp, e_info_8125a_1);
rtl_hw_start_8125_common(tp);
+ rtl_hw_aspm_clkreq_enable(tp, true);
}
-static void rtl_hw_start_8125_2(struct rtl8169_private *tp)
+static void rtl_hw_start_8125a_2(struct rtl8169_private *tp)
{
- static const struct ephy_info e_info_8125_2[] = {
+ static const struct ephy_info e_info_8125a_2[] = {
{ 0x04, 0xffff, 0xd000 },
{ 0x0a, 0xffff, 0x8653 },
{ 0x23, 0xffff, 0xab66 },
@@ -3668,9 +3647,30 @@ static void rtl_hw_start_8125_2(struct rtl8169_private *tp)
/* disable aspm and clock request before access ephy */
rtl_hw_aspm_clkreq_enable(tp, false);
- rtl_ephy_init(tp, e_info_8125_2);
+ rtl_ephy_init(tp, e_info_8125a_2);
rtl_hw_start_8125_common(tp);
+ rtl_hw_aspm_clkreq_enable(tp, true);
+}
+
+static void rtl_hw_start_8125b(struct rtl8169_private *tp)
+{
+ static const struct ephy_info e_info_8125b[] = {
+ { 0x0b, 0xffff, 0xa908 },
+ { 0x1e, 0xffff, 0x20eb },
+ { 0x4b, 0xffff, 0xa908 },
+ { 0x5e, 0xffff, 0x20eb },
+ { 0x22, 0x0030, 0x0020 },
+ { 0x62, 0x0030, 0x0020 },
+ };
+
+ rtl_set_def_aspm_entry_latency(tp);
+ rtl_hw_aspm_clkreq_enable(tp, false);
+
+ rtl_ephy_init(tp, e_info_8125b);
+ rtl_hw_start_8125_common(tp);
+
+ rtl_hw_aspm_clkreq_enable(tp, true);
}
static void rtl_hw_config(struct rtl8169_private *tp)
@@ -3683,8 +3683,7 @@ static void rtl_hw_config(struct rtl8169_private *tp)
[RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168b,
[RTL_GIGA_MAC_VER_12] = rtl_hw_start_8168b,
[RTL_GIGA_MAC_VER_13] = NULL,
- [RTL_GIGA_MAC_VER_14] = NULL,
- [RTL_GIGA_MAC_VER_15] = NULL,
+ [RTL_GIGA_MAC_VER_14] = rtl_hw_start_8401,
[RTL_GIGA_MAC_VER_16] = NULL,
[RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168b,
[RTL_GIGA_MAC_VER_18] = rtl_hw_start_8168cp_1,
@@ -3722,8 +3721,9 @@ static void rtl_hw_config(struct rtl8169_private *tp)
[RTL_GIGA_MAC_VER_50] = rtl_hw_start_8168ep_2,
[RTL_GIGA_MAC_VER_51] = rtl_hw_start_8168ep_3,
[RTL_GIGA_MAC_VER_52] = rtl_hw_start_8117,
- [RTL_GIGA_MAC_VER_60] = rtl_hw_start_8125_1,
- [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125_2,
+ [RTL_GIGA_MAC_VER_60] = rtl_hw_start_8125a_1,
+ [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
+ [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
};
if (hw_configs[tp->mac_version])
@@ -3810,6 +3810,15 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
netdev_update_features(dev);
rtl_jumbo_config(tp);
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_63:
+ rtl8125_set_eee_txidle_timer(tp);
+ break;
+ default:
+ break;
+ }
+
return 0;
}
@@ -3931,10 +3940,12 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
netdev_reset_queue(tp->dev);
}
-static void rtl8169_hw_reset(struct rtl8169_private *tp, bool going_down)
+static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down)
{
+ napi_disable(&tp->napi);
+
/* Give a racing hard_start_xmit a few cycles to complete. */
- synchronize_rcu();
+ synchronize_net();
/* Disable interrupts */
rtl8169_irq_mask_and_ack(tp);
@@ -3954,7 +3965,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp, bool going_down)
RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
break;
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
rtl_enable_rxdvgate(tp);
fsleep(2000);
break;
@@ -3972,20 +3983,17 @@ no_reset:
static void rtl_reset_work(struct rtl8169_private *tp)
{
- struct net_device *dev = tp->dev;
int i;
- napi_disable(&tp->napi);
- netif_stop_queue(dev);
+ netif_stop_queue(tp->dev);
- rtl8169_hw_reset(tp, false);
+ rtl8169_cleanup(tp, false);
for (i = 0; i < NUM_RX_DESC; i++)
rtl8169_mark_to_asic(tp->RxDescArray + i);
napi_enable(&tp->napi);
rtl_hw_start(tp);
- netif_wake_queue(dev);
}
static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue)
@@ -4564,16 +4572,18 @@ static void rtl_task(struct work_struct *work)
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, wk.work);
- rtl_lock_work(tp);
+ rtnl_lock();
if (!netif_running(tp->dev) ||
!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
goto out_unlock;
- if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags))
+ if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) {
rtl_reset_work(tp);
+ netif_wake_queue(tp->dev);
+ }
out_unlock:
- rtl_unlock_work(tp);
+ rtnl_unlock();
}
static int rtl8169_poll(struct napi_struct *napi, int budget)
@@ -4635,19 +4645,27 @@ static int r8169_phy_connect(struct rtl8169_private *tp)
static void rtl8169_down(struct rtl8169_private *tp)
{
- rtl_lock_work(tp);
-
/* Clear all task flags */
bitmap_zero(tp->wk.flags, RTL_FLAG_MAX);
phy_stop(tp->phydev);
- napi_disable(&tp->napi);
- rtl8169_hw_reset(tp, true);
+ rtl8169_update_counters(tp);
+
+ rtl8169_cleanup(tp, true);
rtl_pll_power_down(tp);
+}
+
+static void rtl8169_up(struct rtl8169_private *tp)
+{
+ rtl_pll_power_up(tp);
+ rtl8169_init_phy(tp);
+ napi_enable(&tp->napi);
+ set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
+ rtl_reset_work(tp);
- rtl_unlock_work(tp);
+ phy_start(tp->phydev);
}
static int rtl8169_close(struct net_device *dev)
@@ -4657,9 +4675,6 @@ static int rtl8169_close(struct net_device *dev)
pm_runtime_get_sync(&pdev->dev);
- /* Update counters before going down */
- rtl8169_update_counters(tp);
-
netif_stop_queue(dev);
rtl8169_down(tp);
rtl8169_rx_clear(tp);
@@ -4728,25 +4743,10 @@ static int rtl_open(struct net_device *dev)
if (retval)
goto err_free_irq;
- rtl_lock_work(tp);
-
- set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
-
- napi_enable(&tp->napi);
-
- rtl8169_init_phy(tp);
-
- rtl_pll_power_up(tp);
-
- rtl_hw_start(tp);
-
+ rtl8169_up(tp);
rtl8169_init_counter_offsets(tp);
-
- phy_start(tp->phydev);
netif_start_queue(dev);
- rtl_unlock_work(tp);
-
pm_runtime_put_sync(&pdev->dev);
out:
return retval;
@@ -4818,11 +4818,10 @@ rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
static void rtl8169_net_suspend(struct rtl8169_private *tp)
{
- if (!netif_running(tp->dev))
- return;
-
netif_device_detach(tp->dev);
- rtl8169_down(tp);
+
+ if (netif_running(tp->dev))
+ rtl8169_down(tp);
}
#ifdef CONFIG_PM
@@ -4831,38 +4830,23 @@ static int __maybe_unused rtl8169_suspend(struct device *device)
{
struct rtl8169_private *tp = dev_get_drvdata(device);
+ rtnl_lock();
rtl8169_net_suspend(tp);
- clk_disable_unprepare(tp->clk);
+ rtnl_unlock();
return 0;
}
-static void __rtl8169_resume(struct rtl8169_private *tp)
-{
- netif_device_attach(tp->dev);
-
- rtl_pll_power_up(tp);
- rtl8169_init_phy(tp);
-
- phy_start(tp->phydev);
-
- rtl_lock_work(tp);
- napi_enable(&tp->napi);
- set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
- rtl_reset_work(tp);
- rtl_unlock_work(tp);
-}
-
-static int __maybe_unused rtl8169_resume(struct device *device)
+static int rtl8169_resume(struct device *device)
{
struct rtl8169_private *tp = dev_get_drvdata(device);
rtl_rar_set(tp, tp->dev->dev_addr);
- clk_prepare_enable(tp->clk);
+ if (tp->TxDescArray)
+ rtl8169_up(tp);
- if (netif_running(tp->dev))
- __rtl8169_resume(tp);
+ netif_device_attach(tp->dev);
return 0;
}
@@ -4871,17 +4855,15 @@ static int rtl8169_runtime_suspend(struct device *device)
{
struct rtl8169_private *tp = dev_get_drvdata(device);
- if (!tp->TxDescArray)
+ if (!tp->TxDescArray) {
+ netif_device_detach(tp->dev);
return 0;
+ }
- rtl_lock_work(tp);
+ rtnl_lock();
__rtl8169_set_wol(tp, WAKE_PHY);
- rtl_unlock_work(tp);
-
rtl8169_net_suspend(tp);
-
- /* Update counters before going runtime suspend */
- rtl8169_update_counters(tp);
+ rtnl_unlock();
return 0;
}
@@ -4890,18 +4872,9 @@ static int rtl8169_runtime_resume(struct device *device)
{
struct rtl8169_private *tp = dev_get_drvdata(device);
- rtl_rar_set(tp, tp->dev->dev_addr);
-
- if (!tp->TxDescArray)
- return 0;
-
- rtl_lock_work(tp);
__rtl8169_set_wol(tp, tp->saved_wolopts);
- rtl_unlock_work(tp);
- __rtl8169_resume(tp);
-
- return 0;
+ return rtl8169_resume(device);
}
static int rtl8169_runtime_idle(struct device *device)
@@ -4943,7 +4916,9 @@ static void rtl_shutdown(struct pci_dev *pdev)
{
struct rtl8169_private *tp = pci_get_drvdata(pdev);
+ rtnl_lock();
rtl8169_net_suspend(tp);
+ rtnl_unlock();
/* Restore original MAC address */
rtl_rar_set(tp, tp->dev->perm_addr);
@@ -5103,7 +5078,7 @@ static int r8169_mdio_register(struct rtl8169_private *tp)
new_bus->read = r8169_mdio_read_reg;
new_bus->write = r8169_mdio_write_reg;
- ret = devm_mdiobus_register(new_bus);
+ ret = devm_mdiobus_register(&pdev->dev, new_bus);
if (ret)
return ret;
@@ -5166,7 +5141,7 @@ static void rtl_hw_initialize(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
rtl_hw_init_8168g(tp);
break;
- case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_63:
rtl_hw_init_8125(tp);
break;
default:
@@ -5349,7 +5324,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
}
- mutex_init(&tp->wk.mutex);
INIT_WORK(&tp->wk.work, rtl_task);
u64_stats_init(&tp->rx_stats.syncp);
u64_stats_init(&tp->tx_stats.syncp);
@@ -5435,8 +5409,10 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
jumbo_max, tp->mac_version <= RTL_GIGA_MAC_VER_06 ?
"ok" : "ko");
- if (r8168_check_dash(tp))
+ if (r8168_check_dash(tp)) {
+ netdev_info(dev, "DASH enabled\n");
rtl8168_driver_start(tp);
+ }
if (pci_dev_run_wake(pdev))
pm_runtime_put_sync(&pdev->dev);
diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c
index b73f7d023e99..913d030d73eb 100644
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
@@ -89,7 +89,7 @@ static void rtl8168h_config_eee_phy(struct phy_device *phydev)
phy_modify_paged(phydev, 0xa42, 0x14, 0x0000, 0x0080);
}
-static void rtl8125_config_eee_phy(struct phy_device *phydev)
+static void rtl8125a_config_eee_phy(struct phy_device *phydev)
{
rtl8168h_config_eee_phy(phydev);
@@ -97,6 +97,14 @@ static void rtl8125_config_eee_phy(struct phy_device *phydev)
phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
}
+static void rtl8125b_config_eee_phy(struct phy_device *phydev)
+{
+ phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000);
+ phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
+ phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000);
+ phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000);
+}
+
static void rtl8169s_hw_phy_config(struct rtl8169_private *tp,
struct phy_device *phydev)
{
@@ -1091,6 +1099,13 @@ static void rtl8102e_hw_phy_config(struct rtl8169_private *tp,
rtl_writephy_batch(phydev, phy_reg_init);
}
+static void rtl8401_hw_phy_config(struct rtl8169_private *tp,
+ struct phy_device *phydev)
+{
+ phy_set_bits(phydev, 0x11, BIT(12));
+ phy_modify_paged(phydev, 0x0002, 0x0f, 0x0000, 0x0003);
+}
+
static void rtl8105e_hw_phy_config(struct rtl8169_private *tp,
struct phy_device *phydev)
{
@@ -1140,8 +1155,13 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp,
rtl_writephy_batch(phydev, phy_reg_init);
}
-static void rtl8125_1_hw_phy_config(struct rtl8169_private *tp,
- struct phy_device *phydev)
+static void rtl8125_legacy_force_mode(struct phy_device *phydev)
+{
+ phy_modify_paged(phydev, 0xa5b, 0x12, BIT(15), 0);
+}
+
+static void rtl8125a_1_hw_phy_config(struct rtl8169_private *tp,
+ struct phy_device *phydev)
{
phy_modify_paged(phydev, 0xad4, 0x10, 0x03ff, 0x0084);
phy_modify_paged(phydev, 0xad4, 0x17, 0x0000, 0x0010);
@@ -1175,11 +1195,11 @@ static void rtl8125_1_hw_phy_config(struct rtl8169_private *tp,
phy_modify_paged(phydev, 0xa5c, 0x10, 0x0400, 0x0000);
rtl8168g_enable_gphy_10m(phydev);
- rtl8125_config_eee_phy(phydev);
+ rtl8125a_config_eee_phy(phydev);
}
-static void rtl8125_2_hw_phy_config(struct rtl8169_private *tp,
- struct phy_device *phydev)
+static void rtl8125a_2_hw_phy_config(struct rtl8169_private *tp,
+ struct phy_device *phydev)
{
int i;
@@ -1240,7 +1260,46 @@ static void rtl8125_2_hw_phy_config(struct rtl8169_private *tp,
phy_modify_paged(phydev, 0xa86, 0x15, 0x0001, 0x0000);
rtl8168g_enable_gphy_10m(phydev);
- rtl8125_config_eee_phy(phydev);
+ rtl8125a_config_eee_phy(phydev);
+}
+
+static void rtl8125b_hw_phy_config(struct rtl8169_private *tp,
+ struct phy_device *phydev)
+{
+ r8169_apply_firmware(tp);
+
+ phy_modify_paged(phydev, 0xa44, 0x11, 0x0000, 0x0800);
+ phy_modify_paged(phydev, 0xac4, 0x13, 0x00f0, 0x0090);
+ phy_modify_paged(phydev, 0xad3, 0x10, 0x0003, 0x0001);
+
+ phy_write(phydev, 0x1f, 0x0b87);
+ phy_write(phydev, 0x16, 0x80f5);
+ phy_write(phydev, 0x17, 0x760e);
+ phy_write(phydev, 0x16, 0x8107);
+ phy_write(phydev, 0x17, 0x360e);
+ phy_write(phydev, 0x16, 0x8551);
+ phy_modify(phydev, 0x17, 0xff00, 0x0800);
+ phy_write(phydev, 0x1f, 0x0000);
+
+ phy_modify_paged(phydev, 0xbf0, 0x10, 0xe000, 0xa000);
+ phy_modify_paged(phydev, 0xbf4, 0x13, 0x0f00, 0x0300);
+
+ r8168g_phy_param(phydev, 0x8044, 0xffff, 0x2417);
+ r8168g_phy_param(phydev, 0x804a, 0xffff, 0x2417);
+ r8168g_phy_param(phydev, 0x8050, 0xffff, 0x2417);
+ r8168g_phy_param(phydev, 0x8056, 0xffff, 0x2417);
+ r8168g_phy_param(phydev, 0x805c, 0xffff, 0x2417);
+ r8168g_phy_param(phydev, 0x8062, 0xffff, 0x2417);
+ r8168g_phy_param(phydev, 0x8068, 0xffff, 0x2417);
+ r8168g_phy_param(phydev, 0x806e, 0xffff, 0x2417);
+ r8168g_phy_param(phydev, 0x8074, 0xffff, 0x2417);
+ r8168g_phy_param(phydev, 0x807a, 0xffff, 0x2417);
+
+ phy_modify_paged(phydev, 0xa4c, 0x15, 0x0000, 0x0040);
+ phy_modify_paged(phydev, 0xbf8, 0x12, 0xe000, 0xa000);
+
+ rtl8125_legacy_force_mode(phydev);
+ rtl8125b_config_eee_phy(phydev);
}
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
@@ -1261,8 +1320,7 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
[RTL_GIGA_MAC_VER_11] = rtl8168bb_hw_phy_config,
[RTL_GIGA_MAC_VER_12] = rtl8168bef_hw_phy_config,
[RTL_GIGA_MAC_VER_13] = NULL,
- [RTL_GIGA_MAC_VER_14] = NULL,
- [RTL_GIGA_MAC_VER_15] = NULL,
+ [RTL_GIGA_MAC_VER_14] = rtl8401_hw_phy_config,
[RTL_GIGA_MAC_VER_16] = NULL,
[RTL_GIGA_MAC_VER_17] = rtl8168bef_hw_phy_config,
[RTL_GIGA_MAC_VER_18] = rtl8168cp_1_hw_phy_config,
@@ -1300,8 +1358,9 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
[RTL_GIGA_MAC_VER_50] = rtl8168ep_2_hw_phy_config,
[RTL_GIGA_MAC_VER_51] = rtl8168ep_2_hw_phy_config,
[RTL_GIGA_MAC_VER_52] = rtl8117_hw_phy_config,
- [RTL_GIGA_MAC_VER_60] = rtl8125_1_hw_phy_config,
- [RTL_GIGA_MAC_VER_61] = rtl8125_2_hw_phy_config,
+ [RTL_GIGA_MAC_VER_60] = rtl8125a_1_hw_phy_config,
+ [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
+ [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
};
if (phy_configs[ver])
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index 81b0f7d3a025..5e37c8313725 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -17,7 +17,7 @@ config NET_VENDOR_SOLARFLARE
if NET_VENDOR_SOLARFLARE
config SFC
- tristate "Solarflare SFC9000/SFC9100-family support"
+ tristate "Solarflare SFC9000/SFC9100/EF100-family support"
depends on PCI
select MDIO
select CRC32
@@ -26,6 +26,9 @@ config SFC
This driver supports 10/40-gigabit Ethernet cards based on
the Solarflare SFC9000-family and SFC9100-family controllers.
+ It also supports 10/25/40/100-gigabit Ethernet cards based
+ on the Solarflare EF100 networking IP in Xilinx FPGAs.
+
To compile this driver as a module, choose M here. The module
will be called sfc.
config SFC_MTD
diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile
index 87d093da22ca..8bd01c429f91 100644
--- a/drivers/net/ethernet/sfc/Makefile
+++ b/drivers/net/ethernet/sfc/Makefile
@@ -4,7 +4,9 @@ sfc-y += efx.o efx_common.o efx_channels.o nic.o \
tx.o tx_common.o tx_tso.o rx.o rx_common.o \
selftest.o ethtool.o ethtool_common.o ptp.o \
mcdi.o mcdi_port.o mcdi_port_common.o \
- mcdi_functions.o mcdi_filters.o mcdi_mon.o
+ mcdi_functions.o mcdi_filters.o mcdi_mon.o \
+ ef100.o ef100_nic.o ef100_netdev.o \
+ ef100_ethtool.o ef100_rx.o ef100_tx.o
sfc-$(CONFIG_SFC_MTD) += mtd.o
sfc-$(CONFIG_SFC_SRIOV) += sriov.o siena_sriov.o ef10_sriov.o
diff --git a/drivers/net/ethernet/sfc/bitfield.h b/drivers/net/ethernet/sfc/bitfield.h
index 1b59e9fe58b4..2590cab53e54 100644
--- a/drivers/net/ethernet/sfc/bitfield.h
+++ b/drivers/net/ethernet/sfc/bitfield.h
@@ -282,7 +282,10 @@ typedef union efx_oword {
field7, value7, \
field8, value8, \
field9, value9, \
- field10, value10) \
+ field10, value10, \
+ field11, value11, \
+ field12, value12, \
+ field13, value13) \
(EFX_INSERT_FIELD_NATIVE((min), (max), field1, (value1)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field2, (value2)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field3, (value3)) | \
@@ -292,7 +295,10 @@ typedef union efx_oword {
EFX_INSERT_FIELD_NATIVE((min), (max), field7, (value7)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field8, (value8)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field9, (value9)) | \
- EFX_INSERT_FIELD_NATIVE((min), (max), field10, (value10)))
+ EFX_INSERT_FIELD_NATIVE((min), (max), field10, (value10)) | \
+ EFX_INSERT_FIELD_NATIVE((min), (max), field11, (value11)) | \
+ EFX_INSERT_FIELD_NATIVE((min), (max), field12, (value12)) | \
+ EFX_INSERT_FIELD_NATIVE((min), (max), field13, (value13)))
#define EFX_INSERT_FIELDS64(...) \
cpu_to_le64(EFX_INSERT_FIELDS_NATIVE(__VA_ARGS__))
@@ -334,7 +340,13 @@ typedef union efx_oword {
#endif
/* Populate an octword field with various numbers of arguments */
-#define EFX_POPULATE_OWORD_10 EFX_POPULATE_OWORD
+#define EFX_POPULATE_OWORD_13 EFX_POPULATE_OWORD
+#define EFX_POPULATE_OWORD_12(oword, ...) \
+ EFX_POPULATE_OWORD_13(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
+#define EFX_POPULATE_OWORD_11(oword, ...) \
+ EFX_POPULATE_OWORD_12(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
+#define EFX_POPULATE_OWORD_10(oword, ...) \
+ EFX_POPULATE_OWORD_11(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_OWORD_9(oword, ...) \
EFX_POPULATE_OWORD_10(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_OWORD_8(oword, ...) \
@@ -363,7 +375,13 @@ typedef union efx_oword {
EFX_DWORD_3, 0xffffffff)
/* Populate a quadword field with various numbers of arguments */
-#define EFX_POPULATE_QWORD_10 EFX_POPULATE_QWORD
+#define EFX_POPULATE_QWORD_13 EFX_POPULATE_QWORD
+#define EFX_POPULATE_QWORD_12(qword, ...) \
+ EFX_POPULATE_QWORD_13(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
+#define EFX_POPULATE_QWORD_11(qword, ...) \
+ EFX_POPULATE_QWORD_12(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
+#define EFX_POPULATE_QWORD_10(qword, ...) \
+ EFX_POPULATE_QWORD_11(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_QWORD_9(qword, ...) \
EFX_POPULATE_QWORD_10(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_QWORD_8(qword, ...) \
@@ -390,7 +408,13 @@ typedef union efx_oword {
EFX_DWORD_1, 0xffffffff)
/* Populate a dword field with various numbers of arguments */
-#define EFX_POPULATE_DWORD_10 EFX_POPULATE_DWORD
+#define EFX_POPULATE_DWORD_13 EFX_POPULATE_DWORD
+#define EFX_POPULATE_DWORD_12(dword, ...) \
+ EFX_POPULATE_DWORD_13(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
+#define EFX_POPULATE_DWORD_11(dword, ...) \
+ EFX_POPULATE_DWORD_12(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
+#define EFX_POPULATE_DWORD_10(dword, ...) \
+ EFX_POPULATE_DWORD_11(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_DWORD_9(dword, ...) \
EFX_POPULATE_DWORD_10(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_DWORD_8(dword, ...) \
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 4b0e3695a71a..4b0b2cf026a5 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -6,10 +6,12 @@
#include "net_driver.h"
#include "rx_common.h"
+#include "tx_common.h"
#include "ef10_regs.h"
#include "io.h"
#include "mcdi.h"
#include "mcdi_pcol.h"
+#include "mcdi_port.h"
#include "mcdi_port_common.h"
#include "mcdi_functions.h"
#include "nic.h"
@@ -21,6 +23,7 @@
#include <linux/jhash.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
+#include <net/udp_tunnel.h>
/* Hardware control for EF10 architecture including 'Huntington'. */
@@ -37,6 +40,7 @@ struct efx_ef10_vlan {
};
static int efx_ef10_set_udp_tnl_ports(struct efx_nic *efx, bool unloading);
+static const struct udp_tunnel_nic_info efx_ef10_udp_tunnels;
static int efx_ef10_get_warm_boot_count(struct efx_nic *efx)
{
@@ -551,10 +555,6 @@ static int efx_ef10_probe(struct efx_nic *efx)
}
nic_data->warm_boot_count = rc;
- efx->rss_context.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
-
- efx->vport_id = EVB_PORT_ID_ASSIGNED;
-
/* In case we're recovering from a crash (kexec), we want to
* cancel any outstanding request by the previous user of this
* function. We send a special message using the least
@@ -567,6 +567,9 @@ static int efx_ef10_probe(struct efx_nic *efx)
goto fail2;
mutex_init(&nic_data->udp_tunnels_lock);
+ for (i = 0; i < ARRAY_SIZE(nic_data->udp_tunnels); ++i)
+ nic_data->udp_tunnels[i].type =
+ TUNNEL_ENCAP_UDP_PORT_ENTRY_INVALID;
/* Reset (most) configuration for this function */
rc = efx_mcdi_reset(efx, RESET_TYPE_ALL);
@@ -601,10 +604,15 @@ static int efx_ef10_probe(struct efx_nic *efx)
* However, until we use TX option descriptors we need two TX queues
* per channel.
*/
- efx->max_channels = min_t(unsigned int,
- EFX_MAX_CHANNELS,
- efx_ef10_mem_map_size(efx) /
- (efx->vi_stride * EFX_TXQ_TYPES));
+ efx->tx_queues_per_channel = 2;
+ efx->max_vis = efx_ef10_mem_map_size(efx) / efx->vi_stride;
+ if (!efx->max_vis) {
+ netif_err(efx, drv, efx->net_dev, "error determining max VIs\n");
+ rc = -EIO;
+ goto fail5;
+ }
+ efx->max_channels = min_t(unsigned int, EFX_MAX_CHANNELS,
+ efx->max_vis / efx->tx_queues_per_channel);
efx->max_tx_channels = efx->max_channels;
if (WARN_ON(efx->max_channels == 0)) {
rc = -EIO;
@@ -663,6 +671,12 @@ static int efx_ef10_probe(struct efx_nic *efx)
if (rc)
goto fail_add_vid_0;
+ if (nic_data->datapath_caps &
+ (1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN) &&
+ efx->mcdi->fn_flags &
+ (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TRUSTED))
+ efx->net_dev->udp_tunnel_nic_info = &efx_ef10_udp_tunnels;
+
return 0;
fail_add_vid_0:
@@ -1117,18 +1131,24 @@ static int efx_ef10_alloc_vis(struct efx_nic *efx,
*/
static int efx_ef10_dimension_resources(struct efx_nic *efx)
{
+ unsigned int min_vis = max_t(unsigned int, efx->tx_queues_per_channel,
+ efx_separate_tx_channels ? 2 : 1);
+ unsigned int channel_vis, pio_write_vi_base, max_vis;
struct efx_ef10_nic_data *nic_data = efx->nic_data;
unsigned int uc_mem_map_size, wc_mem_map_size;
- unsigned int min_vis = max(EFX_TXQ_TYPES,
- efx_separate_tx_channels ? 2 : 1);
- unsigned int channel_vis, pio_write_vi_base, max_vis;
void __iomem *membase;
int rc;
channel_vis = max(efx->n_channels,
((efx->n_tx_channels + efx->n_extra_tx_channels) *
- EFX_TXQ_TYPES) +
+ efx->tx_queues_per_channel) +
efx->n_xdp_channels * efx->xdp_tx_per_channel);
+ if (efx->max_vis && efx->max_vis < channel_vis) {
+ netif_dbg(efx, drv, efx->net_dev,
+ "Reducing channel VIs from %u to %u\n",
+ channel_vis, efx->max_vis);
+ channel_vis = efx->max_vis;
+ }
#ifdef EFX_USE_PIO
/* Try to allocate PIO buffers if wanted and if the full
@@ -1210,7 +1230,7 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
*/
efx->max_channels = nic_data->n_allocated_vis;
efx->max_tx_channels =
- nic_data->n_allocated_vis / EFX_TXQ_TYPES;
+ nic_data->n_allocated_vis / efx->tx_queues_per_channel;
efx_mcdi_free_vis(efx);
return -EAGAIN;
@@ -1269,6 +1289,14 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
return 0;
}
+static void efx_ef10_fini_nic(struct efx_nic *efx)
+{
+ struct efx_ef10_nic_data *nic_data = efx->nic_data;
+
+ kfree(nic_data->mc_stats);
+ nic_data->mc_stats = NULL;
+}
+
static int efx_ef10_init_nic(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
@@ -1290,6 +1318,11 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
efx->must_realloc_vis = false;
}
+ nic_data->mc_stats = kmalloc(efx->num_mac_stats * sizeof(__le64),
+ GFP_KERNEL);
+ if (!nic_data->mc_stats)
+ return -ENOMEM;
+
if (nic_data->must_restore_piobufs && nic_data->n_piobufs) {
rc = efx_ef10_alloc_piobufs(efx, nic_data->n_piobufs);
if (rc == 0) {
@@ -1410,8 +1443,6 @@ static int efx_ef10_reset(struct efx_nic *efx, enum reset_type reset_type)
{ NULL, 64, 8 * MC_CMD_MAC_ ## mcdi_name }
#define EF10_OTHER_STAT(ext_name) \
[EF10_STAT_ ## ext_name] = { #ext_name, 0, 0 }
-#define GENERIC_SW_STAT(ext_name) \
- [GENERIC_STAT_ ## ext_name] = { #ext_name, 0, 0 }
static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
EF10_DMA_STAT(port_tx_bytes, TX_BYTES),
@@ -1455,8 +1486,8 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
EF10_DMA_STAT(port_rx_align_error, RX_ALIGN_ERROR_PKTS),
EF10_DMA_STAT(port_rx_length_error, RX_LENGTH_ERROR_PKTS),
EF10_DMA_STAT(port_rx_nodesc_drops, RX_NODESC_DROPS),
- GENERIC_SW_STAT(rx_nodesc_trunc),
- GENERIC_SW_STAT(rx_noskb_drops),
+ EFX_GENERIC_SW_STAT(rx_nodesc_trunc),
+ EFX_GENERIC_SW_STAT(rx_noskb_drops),
EF10_DMA_STAT(port_rx_pm_trunc_bb_overflow, PM_TRUNC_BB_OVERFLOW),
EF10_DMA_STAT(port_rx_pm_discard_bb_overflow, PM_DISCARD_BB_OVERFLOW),
EF10_DMA_STAT(port_rx_pm_trunc_vfifo_full, PM_TRUNC_VFIFO_FULL),
@@ -1765,55 +1796,42 @@ static size_t efx_ef10_update_stats_common(struct efx_nic *efx, u64 *full_stats,
return stats_count;
}
-static int efx_ef10_try_update_nic_stats_pf(struct efx_nic *efx)
+static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats,
+ struct rtnl_link_stats64 *core_stats)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
DECLARE_BITMAP(mask, EF10_STAT_COUNT);
- __le64 generation_start, generation_end;
u64 *stats = nic_data->stats;
- __le64 *dma_stats;
efx_ef10_get_stat_mask(efx, mask);
- dma_stats = efx->stats_buffer.addr;
-
- generation_end = dma_stats[efx->num_mac_stats - 1];
- if (generation_end == EFX_MC_STATS_GENERATION_INVALID)
- return 0;
- rmb();
- efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, mask,
- stats, efx->stats_buffer.addr, false);
- rmb();
- generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
- if (generation_end != generation_start)
- return -EAGAIN;
+ efx_nic_copy_stats(efx, nic_data->mc_stats);
+ efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT,
+ mask, stats, nic_data->mc_stats, false);
/* Update derived statistics */
efx_nic_fix_nodesc_drop_stat(efx,
&stats[EF10_STAT_port_rx_nodesc_drops]);
+ /* MC Firmware reads RX_BYTES and RX_GOOD_BYTES from the MAC.
+ * It then calculates RX_BAD_BYTES and DMAs it to us with RX_BYTES.
+ * We report these as port_rx_ stats. We are not given RX_GOOD_BYTES.
+ * Here we calculate port_rx_good_bytes.
+ */
stats[EF10_STAT_port_rx_good_bytes] =
stats[EF10_STAT_port_rx_bytes] -
stats[EF10_STAT_port_rx_bytes_minus_good_bytes];
+
+ /* The asynchronous reads used to calculate RX_BAD_BYTES in
+ * MC Firmware are done such that we should not see an increase in
+ * RX_BAD_BYTES when a good packet has arrived. Unfortunately this
+ * does mean that the stat can decrease at times. Here we do not
+ * update the stat unless it has increased or has gone to zero
+ * (In the case of the NIC rebooting).
+ * Please see Bug 33781 for a discussion of why things work this way.
+ */
efx_update_diff_stat(&stats[EF10_STAT_port_rx_bad_bytes],
stats[EF10_STAT_port_rx_bytes_minus_good_bytes]);
efx_update_sw_stats(efx, stats);
- return 0;
-}
-
-
-static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats,
- struct rtnl_link_stats64 *core_stats)
-{
- int retry;
-
- /* If we're unlucky enough to read statistics during the DMA, wait
- * up to 10ms for it to finish (typically takes <500us)
- */
- for (retry = 0; retry < 100; ++retry) {
- if (efx_ef10_try_update_nic_stats_pf(efx) == 0)
- break;
- udelay(100);
- }
return efx_ef10_update_stats_common(efx, full_stats, core_stats);
}
@@ -2236,7 +2254,7 @@ static u32 efx_ef10_tso_versions(struct efx_nic *efx)
static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
{
- bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
+ bool csum_offload = tx_queue->label & EFX_TXQ_TYPE_OFFLOAD;
struct efx_channel *channel = tx_queue->channel;
struct efx_nic *efx = tx_queue->efx;
struct efx_ef10_nic_data *nic_data;
@@ -3109,52 +3127,6 @@ fail:
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
}
-void efx_ef10_handle_drain_event(struct efx_nic *efx)
-{
- if (atomic_dec_and_test(&efx->active_queues))
- wake_up(&efx->flush_wq);
-
- WARN_ON(atomic_read(&efx->active_queues) < 0);
-}
-
-static int efx_ef10_fini_dmaq(struct efx_nic *efx)
-{
- struct efx_tx_queue *tx_queue;
- struct efx_rx_queue *rx_queue;
- struct efx_channel *channel;
- int pending;
-
- /* If the MC has just rebooted, the TX/RX queues will have already been
- * torn down, but efx->active_queues needs to be set to zero.
- */
- if (efx->must_realloc_vis) {
- atomic_set(&efx->active_queues, 0);
- return 0;
- }
-
- /* Do not attempt to write to the NIC during EEH recovery */
- if (efx->state != STATE_RECOVERY) {
- efx_for_each_channel(channel, efx) {
- efx_for_each_channel_rx_queue(rx_queue, channel)
- efx_mcdi_rx_fini(rx_queue);
- efx_for_each_channel_tx_queue(tx_queue, channel)
- efx_mcdi_tx_fini(tx_queue);
- }
-
- wait_event_timeout(efx->flush_wq,
- atomic_read(&efx->active_queues) == 0,
- msecs_to_jiffies(EFX_MAX_FLUSH_TIME));
- pending = atomic_read(&efx->active_queues);
- if (pending) {
- netif_err(efx, hw, efx->net_dev, "failed to flush %d queues\n",
- pending);
- return -ETIMEDOUT;
- }
- }
-
- return 0;
-}
-
static void efx_ef10_prepare_flr(struct efx_nic *efx)
{
atomic_set(&efx->active_queues, 0);
@@ -3307,18 +3279,15 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
return rc;
}
-static int efx_ef10_mac_reconfigure(struct efx_nic *efx)
+static int efx_ef10_mac_reconfigure(struct efx_nic *efx, bool mtu_only)
{
- efx_mcdi_filter_sync_rx_mode(efx);
-
- return efx_mcdi_set_mac(efx);
-}
+ WARN_ON(!mutex_is_locked(&efx->mac_lock));
-static int efx_ef10_mac_reconfigure_vf(struct efx_nic *efx)
-{
efx_mcdi_filter_sync_rx_mode(efx);
- return 0;
+ if (mtu_only && efx_has_cap(efx, SET_MAC_ENHANCED))
+ return efx_mcdi_set_mtu(efx);
+ return efx_mcdi_set_mac(efx);
}
static int efx_ef10_start_bist(struct efx_nic *efx, u32 bist_type)
@@ -3745,8 +3714,8 @@ static int efx_ef10_set_udp_tnl_ports(struct efx_nic *efx, bool unloading)
MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM);
for (i = 0; i < ARRAY_SIZE(nic_data->udp_tunnels); ++i) {
- if (nic_data->udp_tunnels[i].count &&
- nic_data->udp_tunnels[i].port) {
+ if (nic_data->udp_tunnels[i].type !=
+ TUNNEL_ENCAP_UDP_PORT_ENTRY_INVALID) {
efx_dword_t entry;
EFX_POPULATE_DWORD_2(entry,
@@ -3832,79 +3801,34 @@ static int efx_ef10_udp_tnl_push_ports(struct efx_nic *efx)
return rc;
}
-static struct efx_udp_tunnel *__efx_ef10_udp_tnl_lookup_port(struct efx_nic *efx,
- __be16 port)
+static int efx_ef10_udp_tnl_set_port(struct net_device *dev,
+ unsigned int table, unsigned int entry,
+ struct udp_tunnel_info *ti)
{
- struct efx_ef10_nic_data *nic_data = efx->nic_data;
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(nic_data->udp_tunnels); ++i) {
- if (!nic_data->udp_tunnels[i].count)
- continue;
- if (nic_data->udp_tunnels[i].port == port)
- return &nic_data->udp_tunnels[i];
- }
- return NULL;
-}
+ struct efx_nic *efx = netdev_priv(dev);
+ struct efx_ef10_nic_data *nic_data;
+ int efx_tunnel_type, rc;
-static int efx_ef10_udp_tnl_add_port(struct efx_nic *efx,
- struct efx_udp_tunnel tnl)
-{
- struct efx_ef10_nic_data *nic_data = efx->nic_data;
- struct efx_udp_tunnel *match;
- char typebuf[8];
- size_t i;
- int rc;
+ if (ti->type == UDP_TUNNEL_TYPE_VXLAN)
+ efx_tunnel_type = TUNNEL_ENCAP_UDP_PORT_ENTRY_VXLAN;
+ else
+ efx_tunnel_type = TUNNEL_ENCAP_UDP_PORT_ENTRY_GENEVE;
+ nic_data = efx->nic_data;
if (!(nic_data->datapath_caps &
(1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN)))
- return 0;
-
- efx_get_udp_tunnel_type_name(tnl.type, typebuf, sizeof(typebuf));
- netif_dbg(efx, drv, efx->net_dev, "Adding UDP tunnel (%s) port %d\n",
- typebuf, ntohs(tnl.port));
+ return -EOPNOTSUPP;
mutex_lock(&nic_data->udp_tunnels_lock);
/* Make sure all TX are stopped while we add to the table, else we
* might race against an efx_features_check().
*/
efx_device_detach_sync(efx);
-
- match = __efx_ef10_udp_tnl_lookup_port(efx, tnl.port);
- if (match != NULL) {
- if (match->type == tnl.type) {
- netif_dbg(efx, drv, efx->net_dev,
- "Referencing existing tunnel entry\n");
- match->count++;
- /* No need to cause an MCDI update */
- rc = 0;
- goto unlock_out;
- }
- efx_get_udp_tunnel_type_name(match->type,
- typebuf, sizeof(typebuf));
- netif_dbg(efx, drv, efx->net_dev,
- "UDP port %d is already in use by %s\n",
- ntohs(tnl.port), typebuf);
- rc = -EEXIST;
- goto unlock_out;
- }
-
- for (i = 0; i < ARRAY_SIZE(nic_data->udp_tunnels); ++i)
- if (!nic_data->udp_tunnels[i].count) {
- nic_data->udp_tunnels[i] = tnl;
- nic_data->udp_tunnels[i].count = 1;
- rc = efx_ef10_set_udp_tnl_ports(efx, false);
- goto unlock_out;
- }
-
- netif_dbg(efx, drv, efx->net_dev,
- "Unable to add UDP tunnel (%s) port %d; insufficient resources.\n",
- typebuf, ntohs(tnl.port));
-
- rc = -ENOMEM;
-
-unlock_out:
+ nic_data->udp_tunnels[entry].type = efx_tunnel_type;
+ nic_data->udp_tunnels[entry].port = ti->port;
+ rc = efx_ef10_set_udp_tnl_ports(efx, false);
mutex_unlock(&nic_data->udp_tunnels_lock);
+
return rc;
}
@@ -3916,6 +3840,7 @@ unlock_out:
static bool efx_ef10_udp_tnl_has_port(struct efx_nic *efx, __be16 port)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
+ size_t i;
if (!(nic_data->datapath_caps &
(1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN)))
@@ -3927,58 +3852,51 @@ static bool efx_ef10_udp_tnl_has_port(struct efx_nic *efx, __be16 port)
*/
return false;
- return __efx_ef10_udp_tnl_lookup_port(efx, port) != NULL;
+ for (i = 0; i < ARRAY_SIZE(nic_data->udp_tunnels); ++i)
+ if (nic_data->udp_tunnels[i].type !=
+ TUNNEL_ENCAP_UDP_PORT_ENTRY_INVALID &&
+ nic_data->udp_tunnels[i].port == port)
+ return true;
+
+ return false;
}
-static int efx_ef10_udp_tnl_del_port(struct efx_nic *efx,
- struct efx_udp_tunnel tnl)
+static int efx_ef10_udp_tnl_unset_port(struct net_device *dev,
+ unsigned int table, unsigned int entry,
+ struct udp_tunnel_info *ti)
{
- struct efx_ef10_nic_data *nic_data = efx->nic_data;
- struct efx_udp_tunnel *match;
- char typebuf[8];
+ struct efx_nic *efx = netdev_priv(dev);
+ struct efx_ef10_nic_data *nic_data;
int rc;
- if (!(nic_data->datapath_caps &
- (1 << MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN)))
- return 0;
-
- efx_get_udp_tunnel_type_name(tnl.type, typebuf, sizeof(typebuf));
- netif_dbg(efx, drv, efx->net_dev, "Removing UDP tunnel (%s) port %d\n",
- typebuf, ntohs(tnl.port));
+ nic_data = efx->nic_data;
mutex_lock(&nic_data->udp_tunnels_lock);
/* Make sure all TX are stopped while we remove from the table, else we
* might race against an efx_features_check().
*/
efx_device_detach_sync(efx);
-
- match = __efx_ef10_udp_tnl_lookup_port(efx, tnl.port);
- if (match != NULL) {
- if (match->type == tnl.type) {
- if (--match->count) {
- /* Port is still in use, so nothing to do */
- netif_dbg(efx, drv, efx->net_dev,
- "UDP tunnel port %d remains active\n",
- ntohs(tnl.port));
- rc = 0;
- goto out_unlock;
- }
- rc = efx_ef10_set_udp_tnl_ports(efx, false);
- goto out_unlock;
- }
- efx_get_udp_tunnel_type_name(match->type,
- typebuf, sizeof(typebuf));
- netif_warn(efx, drv, efx->net_dev,
- "UDP port %d is actually in use by %s, not removing\n",
- ntohs(tnl.port), typebuf);
- }
- rc = -ENOENT;
-
-out_unlock:
+ nic_data->udp_tunnels[entry].type = TUNNEL_ENCAP_UDP_PORT_ENTRY_INVALID;
+ nic_data->udp_tunnels[entry].port = 0;
+ rc = efx_ef10_set_udp_tnl_ports(efx, false);
mutex_unlock(&nic_data->udp_tunnels_lock);
+
return rc;
}
+static const struct udp_tunnel_nic_info efx_ef10_udp_tunnels = {
+ .set_port = efx_ef10_udp_tnl_set_port,
+ .unset_port = efx_ef10_udp_tnl_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ {
+ .n_entries = 16,
+ .tunnel_types = UDP_TUNNEL_TYPE_VXLAN |
+ UDP_TUNNEL_TYPE_GENEVE,
+ },
+ },
+};
+
/* EF10 may have multiple datapath firmware variants within a
* single version. Report which variants are running.
*/
@@ -4023,13 +3941,13 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.remove = efx_ef10_remove,
.dimension_resources = efx_ef10_dimension_resources,
.init = efx_ef10_init_nic,
- .fini = efx_port_dummy_op_void,
+ .fini = efx_ef10_fini_nic,
.map_reset_reason = efx_ef10_map_reset_reason,
.map_reset_flags = efx_ef10_map_reset_flags,
.reset = efx_ef10_reset,
.probe_port = efx_mcdi_port_probe,
.remove_port = efx_mcdi_port_remove,
- .fini_dmaq = efx_ef10_fini_dmaq,
+ .fini_dmaq = efx_fini_dmaq,
.prepare_flr = efx_ef10_prepare_flr,
.finish_flr = efx_port_dummy_op_void,
.describe_stats = efx_ef10_describe_stats,
@@ -4039,7 +3957,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.stop_stats = efx_port_dummy_op_void,
.set_id_led = efx_mcdi_set_id_led,
.push_irq_moderation = efx_ef10_push_irq_moderation,
- .reconfigure_mac = efx_ef10_mac_reconfigure_vf,
+ .reconfigure_mac = efx_ef10_mac_reconfigure,
.check_mac_fault = efx_mcdi_mac_check_fault,
.reconfigure_port = efx_mcdi_port_reconfigure,
.get_wol = efx_ef10_get_wol_vf,
@@ -4060,6 +3978,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.tx_remove = efx_mcdi_tx_remove,
.tx_write = efx_ef10_tx_write,
.tx_limit_len = efx_ef10_tx_limit_len,
+ .tx_enqueue = __efx_enqueue_skb,
.rx_push_rss_config = efx_mcdi_vf_rx_push_rss_config,
.rx_pull_rss_config = efx_mcdi_rx_pull_rss_config,
.rx_probe = efx_mcdi_rx_probe,
@@ -4067,6 +3986,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.rx_remove = efx_mcdi_rx_remove,
.rx_write = efx_ef10_rx_write,
.rx_defer_refill = efx_ef10_rx_defer_refill,
+ .rx_packet = __efx_rx_packet,
.ev_probe = efx_mcdi_ev_probe,
.ev_init = efx_ef10_ev_init,
.ev_fini = efx_mcdi_ev_fini,
@@ -4112,7 +4032,6 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.can_rx_scatter = true,
.always_rx_scatter = true,
.min_interrupt_mode = EFX_INT_MODE_MSIX,
- .max_interrupt_mode = EFX_INT_MODE_MSIX,
.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
.offload_features = EF10_OFFLOAD_FEATURES,
.mcdi_max_ver = 2,
@@ -4122,6 +4041,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.rx_hash_key_size = 40,
.check_caps = ef10_check_caps,
.print_additional_fwver = efx_ef10_print_additional_fwver,
+ .sensor_event = efx_mcdi_sensor_event,
};
const struct efx_nic_type efx_hunt_a0_nic_type = {
@@ -4132,13 +4052,13 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.remove = efx_ef10_remove,
.dimension_resources = efx_ef10_dimension_resources,
.init = efx_ef10_init_nic,
- .fini = efx_port_dummy_op_void,
+ .fini = efx_ef10_fini_nic,
.map_reset_reason = efx_ef10_map_reset_reason,
.map_reset_flags = efx_ef10_map_reset_flags,
.reset = efx_ef10_reset,
.probe_port = efx_mcdi_port_probe,
.remove_port = efx_mcdi_port_remove,
- .fini_dmaq = efx_ef10_fini_dmaq,
+ .fini_dmaq = efx_fini_dmaq,
.prepare_flr = efx_ef10_prepare_flr,
.finish_flr = efx_port_dummy_op_void,
.describe_stats = efx_ef10_describe_stats,
@@ -4171,6 +4091,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.tx_remove = efx_mcdi_tx_remove,
.tx_write = efx_ef10_tx_write,
.tx_limit_len = efx_ef10_tx_limit_len,
+ .tx_enqueue = __efx_enqueue_skb,
.rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config,
.rx_pull_rss_config = efx_mcdi_rx_pull_rss_config,
.rx_push_rss_context_config = efx_mcdi_rx_push_rss_context_config,
@@ -4181,6 +4102,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.rx_remove = efx_mcdi_rx_remove,
.rx_write = efx_ef10_rx_write,
.rx_defer_refill = efx_ef10_rx_defer_refill,
+ .rx_packet = __efx_rx_packet,
.ev_probe = efx_mcdi_ev_probe,
.ev_init = efx_ef10_ev_init,
.ev_fini = efx_mcdi_ev_fini,
@@ -4216,9 +4138,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.vlan_rx_add_vid = efx_ef10_vlan_rx_add_vid,
.vlan_rx_kill_vid = efx_ef10_vlan_rx_kill_vid,
.udp_tnl_push_ports = efx_ef10_udp_tnl_push_ports,
- .udp_tnl_add_port = efx_ef10_udp_tnl_add_port,
.udp_tnl_has_port = efx_ef10_udp_tnl_has_port,
- .udp_tnl_del_port = efx_ef10_udp_tnl_del_port,
#ifdef CONFIG_SFC_SRIOV
.sriov_configure = efx_ef10_sriov_configure,
.sriov_init = efx_ef10_sriov_init,
@@ -4249,7 +4169,6 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.always_rx_scatter = true,
.option_descriptors = true,
.min_interrupt_mode = EFX_INT_MODE_LEGACY,
- .max_interrupt_mode = EFX_INT_MODE_MSIX,
.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
.offload_features = EF10_OFFLOAD_FEATURES,
.mcdi_max_ver = 2,
@@ -4259,4 +4178,5 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.rx_hash_key_size = 40,
.check_caps = ef10_check_caps,
.print_additional_fwver = efx_ef10_print_additional_fwver,
+ .sensor_event = efx_mcdi_sensor_event,
};
diff --git a/drivers/net/ethernet/sfc/ef100.c b/drivers/net/ethernet/sfc/ef100.c
new file mode 100644
index 000000000000..9729983f4840
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100.c
@@ -0,0 +1,543 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2005-2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "net_driver.h"
+#include <linux/module.h>
+#include <linux/aer.h>
+#include "efx_common.h"
+#include "efx_channels.h"
+#include "io.h"
+#include "ef100_nic.h"
+#include "ef100_netdev.h"
+#include "ef100_regs.h"
+#include "ef100.h"
+
+#define EFX_EF100_PCI_DEFAULT_BAR 2
+
+/* Number of bytes at start of vendor specified extended capability that indicate
+ * that the capability is vendor specified. i.e. offset from value returned by
+ * pci_find_next_ext_capability() to beginning of vendor specified capability
+ * header.
+ */
+#define PCI_EXT_CAP_HDR_LENGTH 4
+
+/* Expected size of a Xilinx continuation address table entry. */
+#define ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH 16
+
+struct ef100_func_ctl_window {
+ bool valid;
+ unsigned int bar;
+ u64 offset;
+};
+
+static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset,
+ struct ef100_func_ctl_window *result);
+
+/* Number of bytes to offset when reading bit position x with dword accessors. */
+#define ROUND_DOWN_TO_DWORD(x) (((x) & (~31)) >> 3)
+
+#define EXTRACT_BITS(x, lbn, width) \
+ (((x) >> ((lbn) & 31)) & ((1ull << (width)) - 1))
+
+static u32 _ef100_pci_get_bar_bits_with_width(struct efx_nic *efx,
+ int structure_start,
+ int lbn, int width)
+{
+ efx_dword_t dword;
+
+ efx_readd(efx, &dword, structure_start + ROUND_DOWN_TO_DWORD(lbn));
+
+ return EXTRACT_BITS(le32_to_cpu(dword.u32[0]), lbn, width);
+}
+
+#define ef100_pci_get_bar_bits(efx, entry_location, bitdef) \
+ _ef100_pci_get_bar_bits_with_width(efx, entry_location, \
+ ESF_GZ_CFGBAR_ ## bitdef ## _LBN, \
+ ESF_GZ_CFGBAR_ ## bitdef ## _WIDTH)
+
+static int ef100_pci_parse_ef100_entry(struct efx_nic *efx, int entry_location,
+ struct ef100_func_ctl_window *result)
+{
+ u64 offset = ef100_pci_get_bar_bits(efx, entry_location, EF100_FUNC_CTL_WIN_OFF) <<
+ ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT;
+ u32 bar = ef100_pci_get_bar_bits(efx, entry_location, EF100_BAR);
+
+ netif_dbg(efx, probe, efx->net_dev,
+ "Found EF100 function control window bar=%d offset=0x%llx\n",
+ bar, offset);
+
+ if (result->valid) {
+ netif_err(efx, probe, efx->net_dev,
+ "Duplicated EF100 table entry.\n");
+ return -EINVAL;
+ }
+
+ if (bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_EXPANSION_ROM ||
+ bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_INVALID) {
+ netif_err(efx, probe, efx->net_dev,
+ "Bad BAR value of %d in Xilinx capabilities EF100 entry.\n",
+ bar);
+ return -EINVAL;
+ }
+
+ result->bar = bar;
+ result->offset = offset;
+ result->valid = true;
+ return 0;
+}
+
+static bool ef100_pci_does_bar_overflow(struct efx_nic *efx, int bar,
+ u64 next_entry)
+{
+ return next_entry + ESE_GZ_CFGBAR_ENTRY_HEADER_SIZE >
+ pci_resource_len(efx->pci_dev, bar);
+}
+
+/* Parse a Xilinx capabilities table entry describing a continuation to a new
+ * sub-table.
+ */
+static int ef100_pci_parse_continue_entry(struct efx_nic *efx, int entry_location,
+ struct ef100_func_ctl_window *result)
+{
+ unsigned int previous_bar;
+ efx_oword_t entry;
+ u64 offset;
+ int rc = 0;
+ u32 bar;
+
+ efx_reado(efx, &entry, entry_location);
+
+ bar = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_CONT_CAP_BAR);
+
+ offset = EFX_OWORD_FIELD64(entry, ESF_GZ_CFGBAR_CONT_CAP_OFFSET) <<
+ ESE_GZ_CONT_CAP_OFFSET_BYTES_SHIFT;
+
+ previous_bar = efx->mem_bar;
+
+ if (bar == ESE_GZ_VSEC_BAR_NUM_EXPANSION_ROM ||
+ bar == ESE_GZ_VSEC_BAR_NUM_INVALID) {
+ netif_err(efx, probe, efx->net_dev,
+ "Bad BAR value of %d in Xilinx capabilities sub-table.\n",
+ bar);
+ return -EINVAL;
+ }
+
+ if (bar != previous_bar) {
+ efx_fini_io(efx);
+
+ if (ef100_pci_does_bar_overflow(efx, bar, offset)) {
+ netif_err(efx, probe, efx->net_dev,
+ "Xilinx table will overrun BAR[%d] offset=0x%llx\n",
+ bar, offset);
+ return -EINVAL;
+ }
+
+ /* Temporarily map new BAR. */
+ rc = efx_init_io(efx, bar,
+ DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
+ pci_resource_len(efx->pci_dev, bar));
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Mapping new BAR for Xilinx table failed, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ rc = ef100_pci_walk_xilinx_table(efx, offset, result);
+ if (rc)
+ return rc;
+
+ if (bar != previous_bar) {
+ efx_fini_io(efx);
+
+ /* Put old BAR back. */
+ rc = efx_init_io(efx, previous_bar,
+ DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
+ pci_resource_len(efx->pci_dev, previous_bar));
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Putting old BAR back failed, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+/* Iterate over the Xilinx capabilities table in the currently mapped BAR and
+ * call ef100_pci_parse_ef100_entry() on any EF100 entries and
+ * ef100_pci_parse_continue_entry() on any table continuations.
+ */
+static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset,
+ struct ef100_func_ctl_window *result)
+{
+ u64 current_entry = offset;
+ int rc = 0;
+
+ while (true) {
+ u32 id = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_FORMAT);
+ u32 last = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_LAST);
+ u32 rev = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_REV);
+ u32 entry_size;
+
+ if (id == ESE_GZ_CFGBAR_ENTRY_LAST)
+ return 0;
+
+ entry_size = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_SIZE);
+
+ netif_dbg(efx, probe, efx->net_dev,
+ "Seen Xilinx table entry 0x%x size 0x%x at 0x%llx in BAR[%d]\n",
+ id, entry_size, current_entry, efx->mem_bar);
+
+ if (entry_size < sizeof(u32) * 2) {
+ netif_err(efx, probe, efx->net_dev,
+ "Xilinx table entry too short len=0x%x\n", entry_size);
+ return -EINVAL;
+ }
+
+ switch (id) {
+ case ESE_GZ_CFGBAR_ENTRY_EF100:
+ if (rev != ESE_GZ_CFGBAR_ENTRY_REV_EF100 ||
+ entry_size < ESE_GZ_CFGBAR_ENTRY_SIZE_EF100) {
+ netif_err(efx, probe, efx->net_dev,
+ "Bad length or rev for EF100 entry in Xilinx capabilities table. entry_size=%d rev=%d.\n",
+ entry_size, rev);
+ return -EINVAL;
+ }
+
+ rc = ef100_pci_parse_ef100_entry(efx, current_entry,
+ result);
+ if (rc)
+ return rc;
+ break;
+ case ESE_GZ_CFGBAR_ENTRY_CONT_CAP_ADDR:
+ if (rev != 0 || entry_size < ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH) {
+ netif_err(efx, probe, efx->net_dev,
+ "Bad length or rev for continue entry in Xilinx capabilities table. entry_size=%d rev=%d.\n",
+ entry_size, rev);
+ return -EINVAL;
+ }
+
+ rc = ef100_pci_parse_continue_entry(efx, current_entry, result);
+ if (rc)
+ return rc;
+ break;
+ default:
+ /* Ignore unknown table entries. */
+ break;
+ }
+
+ if (last)
+ return 0;
+
+ current_entry += entry_size;
+
+ if (ef100_pci_does_bar_overflow(efx, efx->mem_bar, current_entry)) {
+ netif_err(efx, probe, efx->net_dev,
+ "Xilinx table overrun at position=0x%llx.\n",
+ current_entry);
+ return -EINVAL;
+ }
+ }
+}
+
+static int _ef100_pci_get_config_bits_with_width(struct efx_nic *efx,
+ int structure_start, int lbn,
+ int width, u32 *result)
+{
+ int rc, pos = structure_start + ROUND_DOWN_TO_DWORD(lbn);
+ u32 temp;
+
+ rc = pci_read_config_dword(efx->pci_dev, pos, &temp);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Failed to read PCI config dword at %d\n",
+ pos);
+ return rc;
+ }
+
+ *result = EXTRACT_BITS(temp, lbn, width);
+
+ return 0;
+}
+
+#define ef100_pci_get_config_bits(efx, entry_location, bitdef, result) \
+ _ef100_pci_get_config_bits_with_width(efx, entry_location, \
+ ESF_GZ_VSEC_ ## bitdef ## _LBN, \
+ ESF_GZ_VSEC_ ## bitdef ## _WIDTH, result)
+
+/* Call ef100_pci_walk_xilinx_table() for the Xilinx capabilities table pointed
+ * to by this PCI_EXT_CAP_ID_VNDR.
+ */
+static int ef100_pci_parse_xilinx_cap(struct efx_nic *efx, int vndr_cap,
+ bool has_offset_hi,
+ struct ef100_func_ctl_window *result)
+{
+ u32 offset_high = 0;
+ u32 offset_lo = 0;
+ u64 offset = 0;
+ u32 bar = 0;
+ int rc = 0;
+
+ rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_BAR, &bar);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Failed to read ESF_GZ_VSEC_TBL_BAR, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ if (bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_EXPANSION_ROM ||
+ bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_INVALID) {
+ netif_err(efx, probe, efx->net_dev,
+ "Bad BAR value of %d in Xilinx capabilities sub-table.\n",
+ bar);
+ return -EINVAL;
+ }
+
+ rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_OFF_LO, &offset_lo);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Failed to read ESF_GZ_VSEC_TBL_OFF_LO, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ /* Get optional extension to 64bit offset. */
+ if (has_offset_hi) {
+ rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_OFF_HI, &offset_high);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Failed to read ESF_GZ_VSEC_TBL_OFF_HI, rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ offset = (((u64)offset_lo) << ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT) |
+ (((u64)offset_high) << ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT);
+
+ if (offset > pci_resource_len(efx->pci_dev, bar) - sizeof(u32) * 2) {
+ netif_err(efx, probe, efx->net_dev,
+ "Xilinx table will overrun BAR[%d] offset=0x%llx\n",
+ bar, offset);
+ return -EINVAL;
+ }
+
+ /* Temporarily map BAR. */
+ rc = efx_init_io(efx, bar,
+ DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
+ pci_resource_len(efx->pci_dev, bar));
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "efx_init_io failed, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = ef100_pci_walk_xilinx_table(efx, offset, result);
+
+ /* Unmap temporarily mapped BAR. */
+ efx_fini_io(efx);
+ return rc;
+}
+
+/* Call ef100_pci_parse_ef100_entry() for each Xilinx PCI_EXT_CAP_ID_VNDR
+ * capability.
+ */
+static int ef100_pci_find_func_ctrl_window(struct efx_nic *efx,
+ struct ef100_func_ctl_window *result)
+{
+ int num_xilinx_caps = 0;
+ int cap = 0;
+
+ result->valid = false;
+
+ while ((cap = pci_find_next_ext_capability(efx->pci_dev, cap, PCI_EXT_CAP_ID_VNDR)) != 0) {
+ int vndr_cap = cap + PCI_EXT_CAP_HDR_LENGTH;
+ u32 vsec_ver = 0;
+ u32 vsec_len = 0;
+ u32 vsec_id = 0;
+ int rc = 0;
+
+ num_xilinx_caps++;
+
+ rc = ef100_pci_get_config_bits(efx, vndr_cap, ID, &vsec_id);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Failed to read ESF_GZ_VSEC_ID, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ rc = ef100_pci_get_config_bits(efx, vndr_cap, VER, &vsec_ver);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Failed to read ESF_GZ_VSEC_VER, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ /* Get length of whole capability - i.e. starting at cap */
+ rc = ef100_pci_get_config_bits(efx, vndr_cap, LEN, &vsec_len);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Failed to read ESF_GZ_VSEC_LEN, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ if (vsec_id == ESE_GZ_XILINX_VSEC_ID &&
+ vsec_ver == ESE_GZ_VSEC_VER_XIL_CFGBAR &&
+ vsec_len >= ESE_GZ_VSEC_LEN_MIN) {
+ bool has_offset_hi = (vsec_len >= ESE_GZ_VSEC_LEN_HIGH_OFFT);
+
+ rc = ef100_pci_parse_xilinx_cap(efx, vndr_cap,
+ has_offset_hi, result);
+ if (rc)
+ return rc;
+ }
+ }
+
+ if (num_xilinx_caps && !result->valid) {
+ netif_err(efx, probe, efx->net_dev,
+ "Seen %d Xilinx tables, but no EF100 entry.\n",
+ num_xilinx_caps);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Final NIC shutdown
+ * This is called only at module unload (or hotplug removal). A PF can call
+ * this on its VFs to ensure they are unbound first.
+ */
+static void ef100_pci_remove(struct pci_dev *pci_dev)
+{
+ struct efx_nic *efx;
+
+ efx = pci_get_drvdata(pci_dev);
+ if (!efx)
+ return;
+
+ rtnl_lock();
+ dev_close(efx->net_dev);
+ rtnl_unlock();
+
+ /* Unregistering our netdev notifier triggers unbinding of TC indirect
+ * blocks, so we have to do it before PCI removal.
+ */
+ unregister_netdevice_notifier(&efx->netdev_notifier);
+ ef100_remove(efx);
+ efx_fini_io(efx);
+ netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n");
+
+ pci_set_drvdata(pci_dev, NULL);
+ efx_fini_struct(efx);
+ free_netdev(efx->net_dev);
+
+ pci_disable_pcie_error_reporting(pci_dev);
+};
+
+static int ef100_pci_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *entry)
+{
+ struct ef100_func_ctl_window fcw = { 0 };
+ struct net_device *net_dev;
+ struct efx_nic *efx;
+ int rc;
+
+ /* Allocate and initialise a struct net_device and struct efx_nic */
+ net_dev = alloc_etherdev_mq(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES);
+ if (!net_dev)
+ return -ENOMEM;
+ efx = netdev_priv(net_dev);
+ efx->type = (const struct efx_nic_type *)entry->driver_data;
+
+ pci_set_drvdata(pci_dev, efx);
+ SET_NETDEV_DEV(net_dev, &pci_dev->dev);
+ rc = efx_init_struct(efx, pci_dev, net_dev);
+ if (rc)
+ goto fail;
+
+ efx->vi_stride = EF100_DEFAULT_VI_STRIDE;
+ netif_info(efx, probe, efx->net_dev,
+ "Solarflare EF100 NIC detected\n");
+
+ rc = ef100_pci_find_func_ctrl_window(efx, &fcw);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Error looking for ef100 function control window, rc=%d\n",
+ rc);
+ goto fail;
+ }
+
+ if (!fcw.valid) {
+ /* Extended capability not found - use defaults. */
+ fcw.bar = EFX_EF100_PCI_DEFAULT_BAR;
+ fcw.offset = 0;
+ fcw.valid = true;
+ }
+
+ if (fcw.offset > pci_resource_len(efx->pci_dev, fcw.bar) - ESE_GZ_FCW_LEN) {
+ netif_err(efx, probe, efx->net_dev,
+ "Func control window overruns BAR\n");
+ goto fail;
+ }
+
+ /* Set up basic I/O (BAR mappings etc) */
+ rc = efx_init_io(efx, fcw.bar,
+ DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
+ pci_resource_len(efx->pci_dev, fcw.bar));
+ if (rc)
+ goto fail;
+
+ efx->reg_base = fcw.offset;
+
+ efx->netdev_notifier.notifier_call = ef100_netdev_event;
+ rc = register_netdevice_notifier(&efx->netdev_notifier);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Failed to register netdevice notifier, rc=%d\n", rc);
+ goto fail;
+ }
+
+ rc = efx->type->probe(efx);
+ if (rc)
+ goto fail;
+
+ netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n");
+
+ return 0;
+
+fail:
+ ef100_pci_remove(pci_dev);
+ return rc;
+}
+
+/* PCI device ID table */
+static const struct pci_device_id ef100_pci_table[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_XILINX, 0x0100), /* Riverhead PF */
+ .driver_data = (unsigned long) &ef100_pf_nic_type },
+ {PCI_DEVICE(PCI_VENDOR_ID_XILINX, 0x1100), /* Riverhead VF */
+ .driver_data = (unsigned long) &ef100_vf_nic_type },
+ {0} /* end of list */
+};
+
+struct pci_driver ef100_pci_driver = {
+ .name = "sfc_ef100",
+ .id_table = ef100_pci_table,
+ .probe = ef100_pci_probe,
+ .remove = ef100_pci_remove,
+ .err_handler = &efx_err_handlers,
+};
+
+MODULE_DEVICE_TABLE(pci, ef100_pci_table);
diff --git a/drivers/net/ethernet/sfc/ef100.h b/drivers/net/ethernet/sfc/ef100.h
new file mode 100644
index 000000000000..a63f0ff6641b
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+extern struct pci_driver ef100_pci_driver;
diff --git a/drivers/net/ethernet/sfc/ef100_ethtool.c b/drivers/net/ethernet/sfc/ef100_ethtool.c
new file mode 100644
index 000000000000..729c425d0f78
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_ethtool.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include "net_driver.h"
+#include "efx.h"
+#include "mcdi_port_common.h"
+#include "ethtool_common.h"
+#include "ef100_ethtool.h"
+#include "mcdi_functions.h"
+
+/* Ethtool options available
+ */
+const struct ethtool_ops ef100_ethtool_ops = {
+ .get_drvinfo = efx_ethtool_get_drvinfo,
+};
diff --git a/drivers/net/ethernet/sfc/ef100_ethtool.h b/drivers/net/ethernet/sfc/ef100_ethtool.h
new file mode 100644
index 000000000000..6efda72dfc6c
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_ethtool.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+extern const struct ethtool_ops ef100_ethtool_ops;
diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
new file mode 100644
index 000000000000..63c311ba28b9
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_netdev.c
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+#include "net_driver.h"
+#include "mcdi_port_common.h"
+#include "mcdi_functions.h"
+#include "efx_common.h"
+#include "efx_channels.h"
+#include "tx_common.h"
+#include "ef100_netdev.h"
+#include "ef100_ethtool.h"
+#include "nic_common.h"
+#include "ef100_nic.h"
+#include "ef100_tx.h"
+#include "ef100_regs.h"
+#include "mcdi_filters.h"
+#include "rx_common.h"
+
+static void ef100_update_name(struct efx_nic *efx)
+{
+ strcpy(efx->name, efx->net_dev->name);
+}
+
+static int ef100_alloc_vis(struct efx_nic *efx, unsigned int *allocated_vis)
+{
+ /* EF100 uses a single TXQ per channel, as all checksum offloading
+ * is configured in the TX descriptor, and there is no TX Pacer for
+ * HIGHPRI queues.
+ */
+ unsigned int tx_vis = efx->n_tx_channels + efx->n_extra_tx_channels;
+ unsigned int rx_vis = efx->n_rx_channels;
+ unsigned int min_vis, max_vis;
+
+ EFX_WARN_ON_PARANOID(efx->tx_queues_per_channel != 1);
+
+ tx_vis += efx->n_xdp_channels * efx->xdp_tx_per_channel;
+
+ max_vis = max(rx_vis, tx_vis);
+ /* Currently don't handle resource starvation and only accept
+ * our maximum needs and no less.
+ */
+ min_vis = max_vis;
+
+ return efx_mcdi_alloc_vis(efx, min_vis, max_vis,
+ NULL, allocated_vis);
+}
+
+static int ef100_remap_bar(struct efx_nic *efx, int max_vis)
+{
+ unsigned int uc_mem_map_size;
+ void __iomem *membase;
+
+ efx->max_vis = max_vis;
+ uc_mem_map_size = PAGE_ALIGN(max_vis * efx->vi_stride);
+
+ /* Extend the original UC mapping of the memory BAR */
+ membase = ioremap(efx->membase_phys, uc_mem_map_size);
+ if (!membase) {
+ netif_err(efx, probe, efx->net_dev,
+ "could not extend memory BAR to %x\n",
+ uc_mem_map_size);
+ return -ENOMEM;
+ }
+ iounmap(efx->membase);
+ efx->membase = membase;
+ return 0;
+}
+
+/* Context: process, rtnl_lock() held.
+ * Note that the kernel will ignore our return code; this method
+ * should really be a void.
+ */
+static int ef100_net_stop(struct net_device *net_dev)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ netif_dbg(efx, ifdown, efx->net_dev, "closing on CPU %d\n",
+ raw_smp_processor_id());
+
+ netif_stop_queue(net_dev);
+ efx_stop_all(efx);
+ efx_mcdi_mac_fini_stats(efx);
+ efx_disable_interrupts(efx);
+ efx_clear_interrupt_affinity(efx);
+ efx_nic_fini_interrupt(efx);
+ efx_remove_filters(efx);
+ efx_fini_napi(efx);
+ efx_remove_channels(efx);
+ efx_mcdi_free_vis(efx);
+ efx_remove_interrupts(efx);
+
+ return 0;
+}
+
+/* Context: process, rtnl_lock() held. */
+static int ef100_net_open(struct net_device *net_dev)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ unsigned int allocated_vis;
+ int rc;
+
+ ef100_update_name(efx);
+ netif_dbg(efx, ifup, net_dev, "opening device on CPU %d\n",
+ raw_smp_processor_id());
+
+ rc = efx_check_disabled(efx);
+ if (rc)
+ goto fail;
+
+ rc = efx_probe_interrupts(efx);
+ if (rc)
+ goto fail;
+
+ rc = efx_set_channels(efx);
+ if (rc)
+ goto fail;
+
+ rc = efx_mcdi_free_vis(efx);
+ if (rc)
+ goto fail;
+
+ rc = ef100_alloc_vis(efx, &allocated_vis);
+ if (rc)
+ goto fail;
+
+ rc = efx_probe_channels(efx);
+ if (rc)
+ return rc;
+
+ rc = ef100_remap_bar(efx, allocated_vis);
+ if (rc)
+ goto fail;
+
+ efx_init_napi(efx);
+
+ rc = efx_probe_filters(efx);
+ if (rc)
+ goto fail;
+
+ rc = efx_nic_init_interrupt(efx);
+ if (rc)
+ goto fail;
+ efx_set_interrupt_affinity(efx);
+
+ rc = efx_enable_interrupts(efx);
+ if (rc)
+ goto fail;
+
+ /* in case the MC rebooted while we were stopped, consume the change
+ * to the warm reboot count
+ */
+ (void) efx_mcdi_poll_reboot(efx);
+
+ rc = efx_mcdi_mac_init_stats(efx);
+ if (rc)
+ goto fail;
+
+ efx_start_all(efx);
+
+ /* Link state detection is normally event-driven; we have
+ * to poll now because we could have missed a change
+ */
+ mutex_lock(&efx->mac_lock);
+ if (efx_mcdi_phy_poll(efx))
+ efx_link_status_changed(efx);
+ mutex_unlock(&efx->mac_lock);
+
+ return 0;
+
+fail:
+ ef100_net_stop(net_dev);
+ return rc;
+}
+
+/* Initiate a packet transmission. We use one channel per CPU
+ * (sharing when we have more CPUs than channels).
+ *
+ * Context: non-blocking.
+ * Note that returning anything other than NETDEV_TX_OK will cause the
+ * OS to free the skb.
+ */
+static netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb,
+ struct net_device *net_dev)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_tx_queue *tx_queue;
+ struct efx_channel *channel;
+ int rc;
+
+ channel = efx_get_tx_channel(efx, skb_get_queue_mapping(skb));
+ netif_vdbg(efx, tx_queued, efx->net_dev,
+ "%s len %d data %d channel %d\n", __func__,
+ skb->len, skb->data_len, channel->channel);
+ if (!efx->n_channels || !efx->n_tx_channels || !channel) {
+ netif_stop_queue(net_dev);
+ goto err;
+ }
+
+ tx_queue = &channel->tx_queue[0];
+ rc = ef100_enqueue_skb(tx_queue, skb);
+ if (rc == 0)
+ return NETDEV_TX_OK;
+
+err:
+ net_dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops ef100_netdev_ops = {
+ .ndo_open = ef100_net_open,
+ .ndo_stop = ef100_net_stop,
+ .ndo_start_xmit = ef100_hard_start_xmit,
+ .ndo_get_stats64 = efx_net_stats,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_rx_mode = efx_set_rx_mode, /* Lookout */
+ .ndo_get_phys_port_id = efx_get_phys_port_id,
+ .ndo_get_phys_port_name = efx_get_phys_port_name,
+#ifdef CONFIG_RFS_ACCEL
+ .ndo_rx_flow_steer = efx_filter_rfs,
+#endif
+};
+
+/* Netdev registration
+ */
+int ef100_netdev_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct efx_nic *efx = container_of(this, struct efx_nic, netdev_notifier);
+ struct net_device *net_dev = netdev_notifier_info_to_dev(ptr);
+
+ if (netdev_priv(net_dev) == efx && event == NETDEV_CHANGENAME)
+ ef100_update_name(efx);
+
+ return NOTIFY_DONE;
+}
+
+int ef100_register_netdev(struct efx_nic *efx)
+{
+ struct net_device *net_dev = efx->net_dev;
+ int rc;
+
+ net_dev->watchdog_timeo = 5 * HZ;
+ net_dev->irq = efx->pci_dev->irq;
+ net_dev->netdev_ops = &ef100_netdev_ops;
+ net_dev->min_mtu = EFX_MIN_MTU;
+ net_dev->max_mtu = EFX_MAX_MTU;
+ net_dev->ethtool_ops = &ef100_ethtool_ops;
+
+ rtnl_lock();
+
+ rc = dev_alloc_name(net_dev, net_dev->name);
+ if (rc < 0)
+ goto fail_locked;
+ ef100_update_name(efx);
+
+ rc = register_netdevice(net_dev);
+ if (rc)
+ goto fail_locked;
+
+ /* Always start with carrier off; PHY events will detect the link */
+ netif_carrier_off(net_dev);
+
+ efx->state = STATE_READY;
+ rtnl_unlock();
+ efx_init_mcdi_logging(efx);
+
+ return 0;
+
+fail_locked:
+ rtnl_unlock();
+ netif_err(efx, drv, efx->net_dev, "could not register net dev\n");
+ return rc;
+}
+
+void ef100_unregister_netdev(struct efx_nic *efx)
+{
+ if (efx_dev_registered(efx)) {
+ efx_fini_mcdi_logging(efx);
+ efx->state = STATE_UNINIT;
+ unregister_netdev(efx->net_dev);
+ }
+}
diff --git a/drivers/net/ethernet/sfc/ef100_netdev.h b/drivers/net/ethernet/sfc/ef100_netdev.h
new file mode 100644
index 000000000000..d40abb7cc086
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_netdev.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include <linux/netdevice.h>
+
+int ef100_netdev_event(struct notifier_block *this,
+ unsigned long event, void *ptr);
+int ef100_register_netdev(struct efx_nic *efx);
+void ef100_unregister_netdev(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
new file mode 100644
index 000000000000..36598d0542ed
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -0,0 +1,1278 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "ef100_nic.h"
+#include "efx_common.h"
+#include "efx_channels.h"
+#include "io.h"
+#include "selftest.h"
+#include "ef100_regs.h"
+#include "mcdi.h"
+#include "mcdi_pcol.h"
+#include "mcdi_port_common.h"
+#include "mcdi_functions.h"
+#include "mcdi_filters.h"
+#include "ef100_rx.h"
+#include "ef100_tx.h"
+#include "ef100_netdev.h"
+
+#define EF100_MAX_VIS 4096
+#define EF100_NUM_MCDI_BUFFERS 1
+#define MCDI_BUF_LEN (8 + MCDI_CTL_SDU_LEN_MAX)
+
+#define EF100_RESET_PORT ((ETH_RESET_MAC | ETH_RESET_PHY) << ETH_RESET_SHARED_SHIFT)
+
+/* MCDI
+ */
+static u8 *ef100_mcdi_buf(struct efx_nic *efx, u8 bufid, dma_addr_t *dma_addr)
+{
+ struct ef100_nic_data *nic_data = efx->nic_data;
+
+ if (dma_addr)
+ *dma_addr = nic_data->mcdi_buf.dma_addr +
+ bufid * ALIGN(MCDI_BUF_LEN, 256);
+ return nic_data->mcdi_buf.addr + bufid * ALIGN(MCDI_BUF_LEN, 256);
+}
+
+static int ef100_get_warm_boot_count(struct efx_nic *efx)
+{
+ efx_dword_t reg;
+
+ efx_readd(efx, &reg, efx_reg(efx, ER_GZ_MC_SFT_STATUS));
+
+ if (EFX_DWORD_FIELD(reg, EFX_DWORD_0) == 0xffffffff) {
+ netif_err(efx, hw, efx->net_dev, "Hardware unavailable\n");
+ efx->state = STATE_DISABLED;
+ return -ENETDOWN;
+ } else {
+ return EFX_DWORD_FIELD(reg, EFX_WORD_1) == 0xb007 ?
+ EFX_DWORD_FIELD(reg, EFX_WORD_0) : -EIO;
+ }
+}
+
+static void ef100_mcdi_request(struct efx_nic *efx,
+ const efx_dword_t *hdr, size_t hdr_len,
+ const efx_dword_t *sdu, size_t sdu_len)
+{
+ dma_addr_t dma_addr;
+ u8 *pdu = ef100_mcdi_buf(efx, 0, &dma_addr);
+
+ memcpy(pdu, hdr, hdr_len);
+ memcpy(pdu + hdr_len, sdu, sdu_len);
+ wmb();
+
+ /* The hardware provides 'low' and 'high' (doorbell) registers
+ * for passing the 64-bit address of an MCDI request to
+ * firmware. However the dwords are swapped by firmware. The
+ * least significant bits of the doorbell are then 0 for all
+ * MCDI requests due to alignment.
+ */
+ _efx_writed(efx, cpu_to_le32((u64)dma_addr >> 32), efx_reg(efx, ER_GZ_MC_DB_LWRD));
+ _efx_writed(efx, cpu_to_le32((u32)dma_addr), efx_reg(efx, ER_GZ_MC_DB_HWRD));
+}
+
+static bool ef100_mcdi_poll_response(struct efx_nic *efx)
+{
+ const efx_dword_t hdr =
+ *(const efx_dword_t *)(ef100_mcdi_buf(efx, 0, NULL));
+
+ rmb();
+ return EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE);
+}
+
+static void ef100_mcdi_read_response(struct efx_nic *efx,
+ efx_dword_t *outbuf, size_t offset,
+ size_t outlen)
+{
+ const u8 *pdu = ef100_mcdi_buf(efx, 0, NULL);
+
+ memcpy(outbuf, pdu + offset, outlen);
+}
+
+static int ef100_mcdi_poll_reboot(struct efx_nic *efx)
+{
+ struct ef100_nic_data *nic_data = efx->nic_data;
+ int rc;
+
+ rc = ef100_get_warm_boot_count(efx);
+ if (rc < 0) {
+ /* The firmware is presumably in the process of
+ * rebooting. However, we are supposed to report each
+ * reboot just once, so we must only do that once we
+ * can read and store the updated warm boot count.
+ */
+ return 0;
+ }
+
+ if (rc == nic_data->warm_boot_count)
+ return 0;
+
+ nic_data->warm_boot_count = rc;
+
+ return -EIO;
+}
+
+static void ef100_mcdi_reboot_detected(struct efx_nic *efx)
+{
+}
+
+/* MCDI calls
+ */
+static int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address)
+{
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
+ size_t outlen;
+ int rc;
+
+ BUILD_BUG_ON(MC_CMD_GET_MAC_ADDRESSES_IN_LEN != 0);
+
+ rc = efx_mcdi_rpc(efx, MC_CMD_GET_MAC_ADDRESSES, NULL, 0,
+ outbuf, sizeof(outbuf), &outlen);
+ if (rc)
+ return rc;
+ if (outlen < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)
+ return -EIO;
+
+ ether_addr_copy(mac_address,
+ MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE));
+ return 0;
+}
+
+static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
+{
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN);
+ struct ef100_nic_data *nic_data = efx->nic_data;
+ u8 vi_window_mode;
+ size_t outlen;
+ int rc;
+
+ BUILD_BUG_ON(MC_CMD_GET_CAPABILITIES_IN_LEN != 0);
+
+ rc = efx_mcdi_rpc(efx, MC_CMD_GET_CAPABILITIES, NULL, 0,
+ outbuf, sizeof(outbuf), &outlen);
+ if (rc)
+ return rc;
+ if (outlen < MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) {
+ netif_err(efx, drv, efx->net_dev,
+ "unable to read datapath firmware capabilities\n");
+ return -EIO;
+ }
+
+ nic_data->datapath_caps = MCDI_DWORD(outbuf,
+ GET_CAPABILITIES_OUT_FLAGS1);
+ nic_data->datapath_caps2 = MCDI_DWORD(outbuf,
+ GET_CAPABILITIES_V2_OUT_FLAGS2);
+ if (outlen < MC_CMD_GET_CAPABILITIES_V7_OUT_LEN)
+ nic_data->datapath_caps3 = 0;
+ else
+ nic_data->datapath_caps3 = MCDI_DWORD(outbuf,
+ GET_CAPABILITIES_V7_OUT_FLAGS3);
+
+ vi_window_mode = MCDI_BYTE(outbuf,
+ GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE);
+ rc = efx_mcdi_window_mode_to_stride(efx, vi_window_mode);
+ if (rc)
+ return rc;
+
+ if (efx_ef100_has_cap(nic_data->datapath_caps2, TX_TSO_V3))
+ efx->net_dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+ efx->num_mac_stats = MCDI_WORD(outbuf,
+ GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS);
+ netif_dbg(efx, probe, efx->net_dev,
+ "firmware reports num_mac_stats = %u\n",
+ efx->num_mac_stats);
+ return 0;
+}
+
+/* Event handling
+ */
+static int ef100_ev_probe(struct efx_channel *channel)
+{
+ /* Allocate an extra descriptor for the QMDA status completion entry */
+ return efx_nic_alloc_buffer(channel->efx, &channel->eventq.buf,
+ (channel->eventq_mask + 2) *
+ sizeof(efx_qword_t),
+ GFP_KERNEL);
+}
+
+static int ef100_ev_init(struct efx_channel *channel)
+{
+ struct ef100_nic_data *nic_data = channel->efx->nic_data;
+
+ /* initial phase is 0 */
+ clear_bit(channel->channel, nic_data->evq_phases);
+
+ return efx_mcdi_ev_init(channel, false, false);
+}
+
+static void ef100_ev_read_ack(struct efx_channel *channel)
+{
+ efx_dword_t evq_prime;
+
+ EFX_POPULATE_DWORD_2(evq_prime,
+ ERF_GZ_EVQ_ID, channel->channel,
+ ERF_GZ_IDX, channel->eventq_read_ptr &
+ channel->eventq_mask);
+
+ efx_writed(channel->efx, &evq_prime,
+ efx_reg(channel->efx, ER_GZ_EVQ_INT_PRIME));
+}
+
+static int ef100_ev_process(struct efx_channel *channel, int quota)
+{
+ struct efx_nic *efx = channel->efx;
+ struct ef100_nic_data *nic_data;
+ bool evq_phase, old_evq_phase;
+ unsigned int read_ptr;
+ efx_qword_t *p_event;
+ int spent = 0;
+ bool ev_phase;
+ int ev_type;
+
+ if (unlikely(!channel->enabled))
+ return 0;
+
+ nic_data = efx->nic_data;
+ evq_phase = test_bit(channel->channel, nic_data->evq_phases);
+ old_evq_phase = evq_phase;
+ read_ptr = channel->eventq_read_ptr;
+ BUILD_BUG_ON(ESF_GZ_EV_RXPKTS_PHASE_LBN != ESF_GZ_EV_TXCMPL_PHASE_LBN);
+
+ while (spent < quota) {
+ p_event = efx_event(channel, read_ptr);
+
+ ev_phase = !!EFX_QWORD_FIELD(*p_event, ESF_GZ_EV_RXPKTS_PHASE);
+ if (ev_phase != evq_phase)
+ break;
+
+ netif_vdbg(efx, drv, efx->net_dev,
+ "processing event on %d " EFX_QWORD_FMT "\n",
+ channel->channel, EFX_QWORD_VAL(*p_event));
+
+ ev_type = EFX_QWORD_FIELD(*p_event, ESF_GZ_E_TYPE);
+
+ switch (ev_type) {
+ case ESE_GZ_EF100_EV_RX_PKTS:
+ efx_ef100_ev_rx(channel, p_event);
+ ++spent;
+ break;
+ case ESE_GZ_EF100_EV_MCDI:
+ efx_mcdi_process_event(channel, p_event);
+ break;
+ case ESE_GZ_EF100_EV_TX_COMPLETION:
+ ef100_ev_tx(channel, p_event);
+ break;
+ case ESE_GZ_EF100_EV_DRIVER:
+ netif_info(efx, drv, efx->net_dev,
+ "Driver initiated event " EFX_QWORD_FMT "\n",
+ EFX_QWORD_VAL(*p_event));
+ break;
+ default:
+ netif_info(efx, drv, efx->net_dev,
+ "Unhandled event " EFX_QWORD_FMT "\n",
+ EFX_QWORD_VAL(*p_event));
+ }
+
+ ++read_ptr;
+ if ((read_ptr & channel->eventq_mask) == 0)
+ evq_phase = !evq_phase;
+ }
+
+ channel->eventq_read_ptr = read_ptr;
+ if (evq_phase != old_evq_phase)
+ change_bit(channel->channel, nic_data->evq_phases);
+
+ return spent;
+}
+
+static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id)
+{
+ struct efx_msi_context *context = dev_id;
+ struct efx_nic *efx = context->efx;
+
+ netif_vdbg(efx, intr, efx->net_dev,
+ "IRQ %d on CPU %d\n", irq, raw_smp_processor_id());
+
+ if (likely(READ_ONCE(efx->irq_soft_enabled))) {
+ /* Note test interrupts */
+ if (context->index == efx->irq_level)
+ efx->last_irq_cpu = raw_smp_processor_id();
+
+ /* Schedule processing of the channel */
+ efx_schedule_channel_irq(efx->channel[context->index]);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int ef100_phy_probe(struct efx_nic *efx)
+{
+ struct efx_mcdi_phy_data *phy_data;
+ int rc;
+
+ /* Probe for the PHY */
+ efx->phy_data = kzalloc(sizeof(struct efx_mcdi_phy_data), GFP_KERNEL);
+ if (!efx->phy_data)
+ return -ENOMEM;
+
+ rc = efx_mcdi_get_phy_cfg(efx, efx->phy_data);
+ if (rc)
+ return rc;
+
+ /* Populate driver and ethtool settings */
+ phy_data = efx->phy_data;
+ mcdi_to_ethtool_linkset(phy_data->media, phy_data->supported_cap,
+ efx->link_advertising);
+ efx->fec_config = mcdi_fec_caps_to_ethtool(phy_data->supported_cap,
+ false);
+
+ /* Default to Autonegotiated flow control if the PHY supports it */
+ efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
+ if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
+ efx->wanted_fc |= EFX_FC_AUTO;
+ efx_link_set_wanted_fc(efx, efx->wanted_fc);
+
+ /* Push settings to the PHY. Failure is not fatal, the user can try to
+ * fix it using ethtool.
+ */
+ rc = efx_mcdi_port_reconfigure(efx);
+ if (rc && rc != -EPERM)
+ netif_warn(efx, drv, efx->net_dev,
+ "could not initialise PHY settings\n");
+
+ return 0;
+}
+
+static int ef100_filter_table_probe(struct efx_nic *efx)
+{
+ return efx_mcdi_filter_table_probe(efx, true);
+}
+
+static int ef100_filter_table_up(struct efx_nic *efx)
+{
+ int rc;
+
+ rc = efx_mcdi_filter_add_vlan(efx, EFX_FILTER_VID_UNSPEC);
+ if (rc) {
+ efx_mcdi_filter_table_down(efx);
+ return rc;
+ }
+
+ rc = efx_mcdi_filter_add_vlan(efx, 0);
+ if (rc) {
+ efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
+ efx_mcdi_filter_table_down(efx);
+ }
+
+ return rc;
+}
+
+static void ef100_filter_table_down(struct efx_nic *efx)
+{
+ efx_mcdi_filter_del_vlan(efx, 0);
+ efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
+ efx_mcdi_filter_table_down(efx);
+}
+
+/* Other
+ */
+static int ef100_reconfigure_mac(struct efx_nic *efx, bool mtu_only)
+{
+ WARN_ON(!mutex_is_locked(&efx->mac_lock));
+
+ efx_mcdi_filter_sync_rx_mode(efx);
+
+ if (mtu_only && efx_has_cap(efx, SET_MAC_ENHANCED))
+ return efx_mcdi_set_mtu(efx);
+ return efx_mcdi_set_mac(efx);
+}
+
+static enum reset_type ef100_map_reset_reason(enum reset_type reason)
+{
+ if (reason == RESET_TYPE_TX_WATCHDOG)
+ return reason;
+ return RESET_TYPE_DISABLE;
+}
+
+static int ef100_map_reset_flags(u32 *flags)
+{
+ /* Only perform a RESET_TYPE_ALL because we don't support MC_REBOOTs */
+ if ((*flags & EF100_RESET_PORT)) {
+ *flags &= ~EF100_RESET_PORT;
+ return RESET_TYPE_ALL;
+ }
+ if (*flags & ETH_RESET_MGMT) {
+ *flags &= ~ETH_RESET_MGMT;
+ return RESET_TYPE_DISABLE;
+ }
+
+ return -EINVAL;
+}
+
+static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
+{
+ int rc;
+
+ dev_close(efx->net_dev);
+
+ if (reset_type == RESET_TYPE_TX_WATCHDOG) {
+ netif_device_attach(efx->net_dev);
+ __clear_bit(reset_type, &efx->reset_pending);
+ rc = dev_open(efx->net_dev, NULL);
+ } else if (reset_type == RESET_TYPE_ALL) {
+ /* A RESET_TYPE_ALL will cause filters to be removed, so we remove filters
+ * and reprobe after reset to avoid removing filters twice
+ */
+ down_read(&efx->filter_sem);
+ ef100_filter_table_down(efx);
+ up_read(&efx->filter_sem);
+ rc = efx_mcdi_reset(efx, reset_type);
+ if (rc)
+ return rc;
+
+ netif_device_attach(efx->net_dev);
+
+ down_read(&efx->filter_sem);
+ rc = ef100_filter_table_up(efx);
+ up_read(&efx->filter_sem);
+ if (rc)
+ return rc;
+
+ rc = dev_open(efx->net_dev, NULL);
+ } else {
+ rc = 1; /* Leave the device closed */
+ }
+ return rc;
+}
+
+static void ef100_common_stat_mask(unsigned long *mask)
+{
+ __set_bit(EF100_STAT_port_rx_packets, mask);
+ __set_bit(EF100_STAT_port_tx_packets, mask);
+ __set_bit(EF100_STAT_port_rx_bytes, mask);
+ __set_bit(EF100_STAT_port_tx_bytes, mask);
+ __set_bit(EF100_STAT_port_rx_multicast, mask);
+ __set_bit(EF100_STAT_port_rx_bad, mask);
+ __set_bit(EF100_STAT_port_rx_align_error, mask);
+ __set_bit(EF100_STAT_port_rx_overflow, mask);
+}
+
+static void ef100_ethtool_stat_mask(unsigned long *mask)
+{
+ __set_bit(EF100_STAT_port_tx_pause, mask);
+ __set_bit(EF100_STAT_port_tx_unicast, mask);
+ __set_bit(EF100_STAT_port_tx_multicast, mask);
+ __set_bit(EF100_STAT_port_tx_broadcast, mask);
+ __set_bit(EF100_STAT_port_tx_lt64, mask);
+ __set_bit(EF100_STAT_port_tx_64, mask);
+ __set_bit(EF100_STAT_port_tx_65_to_127, mask);
+ __set_bit(EF100_STAT_port_tx_128_to_255, mask);
+ __set_bit(EF100_STAT_port_tx_256_to_511, mask);
+ __set_bit(EF100_STAT_port_tx_512_to_1023, mask);
+ __set_bit(EF100_STAT_port_tx_1024_to_15xx, mask);
+ __set_bit(EF100_STAT_port_tx_15xx_to_jumbo, mask);
+ __set_bit(EF100_STAT_port_rx_good, mask);
+ __set_bit(EF100_STAT_port_rx_pause, mask);
+ __set_bit(EF100_STAT_port_rx_unicast, mask);
+ __set_bit(EF100_STAT_port_rx_broadcast, mask);
+ __set_bit(EF100_STAT_port_rx_lt64, mask);
+ __set_bit(EF100_STAT_port_rx_64, mask);
+ __set_bit(EF100_STAT_port_rx_65_to_127, mask);
+ __set_bit(EF100_STAT_port_rx_128_to_255, mask);
+ __set_bit(EF100_STAT_port_rx_256_to_511, mask);
+ __set_bit(EF100_STAT_port_rx_512_to_1023, mask);
+ __set_bit(EF100_STAT_port_rx_1024_to_15xx, mask);
+ __set_bit(EF100_STAT_port_rx_15xx_to_jumbo, mask);
+ __set_bit(EF100_STAT_port_rx_gtjumbo, mask);
+ __set_bit(EF100_STAT_port_rx_bad_gtjumbo, mask);
+ __set_bit(EF100_STAT_port_rx_length_error, mask);
+ __set_bit(EF100_STAT_port_rx_nodesc_drops, mask);
+ __set_bit(GENERIC_STAT_rx_nodesc_trunc, mask);
+ __set_bit(GENERIC_STAT_rx_noskb_drops, mask);
+}
+
+#define EF100_DMA_STAT(ext_name, mcdi_name) \
+ [EF100_STAT_ ## ext_name] = \
+ { #ext_name, 64, 8 * MC_CMD_MAC_ ## mcdi_name }
+
+static const struct efx_hw_stat_desc ef100_stat_desc[EF100_STAT_COUNT] = {
+ EF100_DMA_STAT(port_tx_bytes, TX_BYTES),
+ EF100_DMA_STAT(port_tx_packets, TX_PKTS),
+ EF100_DMA_STAT(port_tx_pause, TX_PAUSE_PKTS),
+ EF100_DMA_STAT(port_tx_unicast, TX_UNICAST_PKTS),
+ EF100_DMA_STAT(port_tx_multicast, TX_MULTICAST_PKTS),
+ EF100_DMA_STAT(port_tx_broadcast, TX_BROADCAST_PKTS),
+ EF100_DMA_STAT(port_tx_lt64, TX_LT64_PKTS),
+ EF100_DMA_STAT(port_tx_64, TX_64_PKTS),
+ EF100_DMA_STAT(port_tx_65_to_127, TX_65_TO_127_PKTS),
+ EF100_DMA_STAT(port_tx_128_to_255, TX_128_TO_255_PKTS),
+ EF100_DMA_STAT(port_tx_256_to_511, TX_256_TO_511_PKTS),
+ EF100_DMA_STAT(port_tx_512_to_1023, TX_512_TO_1023_PKTS),
+ EF100_DMA_STAT(port_tx_1024_to_15xx, TX_1024_TO_15XX_PKTS),
+ EF100_DMA_STAT(port_tx_15xx_to_jumbo, TX_15XX_TO_JUMBO_PKTS),
+ EF100_DMA_STAT(port_rx_bytes, RX_BYTES),
+ EF100_DMA_STAT(port_rx_packets, RX_PKTS),
+ EF100_DMA_STAT(port_rx_good, RX_GOOD_PKTS),
+ EF100_DMA_STAT(port_rx_bad, RX_BAD_FCS_PKTS),
+ EF100_DMA_STAT(port_rx_pause, RX_PAUSE_PKTS),
+ EF100_DMA_STAT(port_rx_unicast, RX_UNICAST_PKTS),
+ EF100_DMA_STAT(port_rx_multicast, RX_MULTICAST_PKTS),
+ EF100_DMA_STAT(port_rx_broadcast, RX_BROADCAST_PKTS),
+ EF100_DMA_STAT(port_rx_lt64, RX_UNDERSIZE_PKTS),
+ EF100_DMA_STAT(port_rx_64, RX_64_PKTS),
+ EF100_DMA_STAT(port_rx_65_to_127, RX_65_TO_127_PKTS),
+ EF100_DMA_STAT(port_rx_128_to_255, RX_128_TO_255_PKTS),
+ EF100_DMA_STAT(port_rx_256_to_511, RX_256_TO_511_PKTS),
+ EF100_DMA_STAT(port_rx_512_to_1023, RX_512_TO_1023_PKTS),
+ EF100_DMA_STAT(port_rx_1024_to_15xx, RX_1024_TO_15XX_PKTS),
+ EF100_DMA_STAT(port_rx_15xx_to_jumbo, RX_15XX_TO_JUMBO_PKTS),
+ EF100_DMA_STAT(port_rx_gtjumbo, RX_GTJUMBO_PKTS),
+ EF100_DMA_STAT(port_rx_bad_gtjumbo, RX_JABBER_PKTS),
+ EF100_DMA_STAT(port_rx_align_error, RX_ALIGN_ERROR_PKTS),
+ EF100_DMA_STAT(port_rx_length_error, RX_LENGTH_ERROR_PKTS),
+ EF100_DMA_STAT(port_rx_overflow, RX_OVERFLOW_PKTS),
+ EF100_DMA_STAT(port_rx_nodesc_drops, RX_NODESC_DROPS),
+ EFX_GENERIC_SW_STAT(rx_nodesc_trunc),
+ EFX_GENERIC_SW_STAT(rx_noskb_drops),
+};
+
+static size_t ef100_describe_stats(struct efx_nic *efx, u8 *names)
+{
+ DECLARE_BITMAP(mask, EF100_STAT_COUNT) = {};
+
+ ef100_ethtool_stat_mask(mask);
+ return efx_nic_describe_stats(ef100_stat_desc, EF100_STAT_COUNT,
+ mask, names);
+}
+
+static size_t ef100_update_stats_common(struct efx_nic *efx, u64 *full_stats,
+ struct rtnl_link_stats64 *core_stats)
+{
+ struct ef100_nic_data *nic_data = efx->nic_data;
+ DECLARE_BITMAP(mask, EF100_STAT_COUNT) = {};
+ size_t stats_count = 0, index;
+ u64 *stats = nic_data->stats;
+
+ ef100_ethtool_stat_mask(mask);
+
+ if (full_stats) {
+ for_each_set_bit(index, mask, EF100_STAT_COUNT) {
+ if (ef100_stat_desc[index].name) {
+ *full_stats++ = stats[index];
+ ++stats_count;
+ }
+ }
+ }
+
+ if (!core_stats)
+ return stats_count;
+
+ core_stats->rx_packets = stats[EF100_STAT_port_rx_packets];
+ core_stats->tx_packets = stats[EF100_STAT_port_tx_packets];
+ core_stats->rx_bytes = stats[EF100_STAT_port_rx_bytes];
+ core_stats->tx_bytes = stats[EF100_STAT_port_tx_bytes];
+ core_stats->rx_dropped = stats[EF100_STAT_port_rx_nodesc_drops] +
+ stats[GENERIC_STAT_rx_nodesc_trunc] +
+ stats[GENERIC_STAT_rx_noskb_drops];
+ core_stats->multicast = stats[EF100_STAT_port_rx_multicast];
+ core_stats->rx_length_errors =
+ stats[EF100_STAT_port_rx_gtjumbo] +
+ stats[EF100_STAT_port_rx_length_error];
+ core_stats->rx_crc_errors = stats[EF100_STAT_port_rx_bad];
+ core_stats->rx_frame_errors =
+ stats[EF100_STAT_port_rx_align_error];
+ core_stats->rx_fifo_errors = stats[EF100_STAT_port_rx_overflow];
+ core_stats->rx_errors = (core_stats->rx_length_errors +
+ core_stats->rx_crc_errors +
+ core_stats->rx_frame_errors);
+
+ return stats_count;
+}
+
+static size_t ef100_update_stats(struct efx_nic *efx,
+ u64 *full_stats,
+ struct rtnl_link_stats64 *core_stats)
+{
+ __le64 *mc_stats = kmalloc(array_size(efx->num_mac_stats, sizeof(__le64)), GFP_ATOMIC);
+ struct ef100_nic_data *nic_data = efx->nic_data;
+ DECLARE_BITMAP(mask, EF100_STAT_COUNT) = {};
+ u64 *stats = nic_data->stats;
+
+ ef100_common_stat_mask(mask);
+ ef100_ethtool_stat_mask(mask);
+
+ efx_nic_copy_stats(efx, mc_stats);
+ efx_nic_update_stats(ef100_stat_desc, EF100_STAT_COUNT, mask,
+ stats, mc_stats, false);
+
+ kfree(mc_stats);
+
+ return ef100_update_stats_common(efx, full_stats, core_stats);
+}
+
+static int efx_ef100_get_phys_port_id(struct efx_nic *efx,
+ struct netdev_phys_item_id *ppid)
+{
+ struct ef100_nic_data *nic_data = efx->nic_data;
+
+ if (!is_valid_ether_addr(nic_data->port_id))
+ return -EOPNOTSUPP;
+
+ ppid->id_len = ETH_ALEN;
+ memcpy(ppid->id, nic_data->port_id, ppid->id_len);
+
+ return 0;
+}
+
+static int efx_ef100_irq_test_generate(struct efx_nic *efx)
+{
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_TRIGGER_INTERRUPT_IN_LEN);
+
+ BUILD_BUG_ON(MC_CMD_TRIGGER_INTERRUPT_OUT_LEN != 0);
+
+ MCDI_SET_DWORD(inbuf, TRIGGER_INTERRUPT_IN_INTR_LEVEL, efx->irq_level);
+ return efx_mcdi_rpc_quiet(efx, MC_CMD_TRIGGER_INTERRUPT,
+ inbuf, sizeof(inbuf), NULL, 0, NULL);
+}
+
+#define EFX_EF100_TEST 1
+
+static void efx_ef100_ev_test_generate(struct efx_channel *channel)
+{
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_DRIVER_EVENT_IN_LEN);
+ struct efx_nic *efx = channel->efx;
+ efx_qword_t event;
+ int rc;
+
+ EFX_POPULATE_QWORD_2(event,
+ ESF_GZ_E_TYPE, ESE_GZ_EF100_EV_DRIVER,
+ ESF_GZ_DRIVER_DATA, EFX_EF100_TEST);
+
+ MCDI_SET_DWORD(inbuf, DRIVER_EVENT_IN_EVQ, channel->channel);
+
+ /* MCDI_SET_QWORD is not appropriate here since EFX_POPULATE_* has
+ * already swapped the data to little-endian order.
+ */
+ memcpy(MCDI_PTR(inbuf, DRIVER_EVENT_IN_DATA), &event.u64[0],
+ sizeof(efx_qword_t));
+
+ rc = efx_mcdi_rpc(efx, MC_CMD_DRIVER_EVENT, inbuf, sizeof(inbuf),
+ NULL, 0, NULL);
+ if (rc && (rc != -ENETDOWN))
+ goto fail;
+
+ return;
+
+fail:
+ WARN_ON(true);
+ netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
+}
+
+static unsigned int ef100_check_caps(const struct efx_nic *efx,
+ u8 flag, u32 offset)
+{
+ const struct ef100_nic_data *nic_data = efx->nic_data;
+
+ switch (offset) {
+ case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS1_OFST:
+ return nic_data->datapath_caps & BIT_ULL(flag);
+ case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS2_OFST:
+ return nic_data->datapath_caps2 & BIT_ULL(flag);
+ case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS3_OFST:
+ return nic_data->datapath_caps3 & BIT_ULL(flag);
+ default:
+ return 0;
+ }
+}
+
+/* NIC level access functions
+ */
+#define EF100_OFFLOAD_FEATURES (NETIF_F_HW_CSUM | NETIF_F_RXCSUM | \
+ NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_FRAGLIST | \
+ NETIF_F_RXHASH | NETIF_F_RXFCS | NETIF_F_TSO_ECN | NETIF_F_RXALL | \
+ NETIF_F_TSO_MANGLEID | NETIF_F_HW_VLAN_CTAG_TX)
+
+const struct efx_nic_type ef100_pf_nic_type = {
+ .revision = EFX_REV_EF100,
+ .is_vf = false,
+ .probe = ef100_probe_pf,
+ .offload_features = EF100_OFFLOAD_FEATURES,
+ .mcdi_max_ver = 2,
+ .mcdi_request = ef100_mcdi_request,
+ .mcdi_poll_response = ef100_mcdi_poll_response,
+ .mcdi_read_response = ef100_mcdi_read_response,
+ .mcdi_poll_reboot = ef100_mcdi_poll_reboot,
+ .mcdi_reboot_detected = ef100_mcdi_reboot_detected,
+ .irq_enable_master = efx_port_dummy_op_void,
+ .irq_test_generate = efx_ef100_irq_test_generate,
+ .irq_disable_non_ev = efx_port_dummy_op_void,
+ .push_irq_moderation = efx_channel_dummy_op_void,
+ .min_interrupt_mode = EFX_INT_MODE_MSIX,
+ .map_reset_reason = ef100_map_reset_reason,
+ .map_reset_flags = ef100_map_reset_flags,
+ .reset = ef100_reset,
+
+ .check_caps = ef100_check_caps,
+
+ .ev_probe = ef100_ev_probe,
+ .ev_init = ef100_ev_init,
+ .ev_fini = efx_mcdi_ev_fini,
+ .ev_remove = efx_mcdi_ev_remove,
+ .irq_handle_msi = ef100_msi_interrupt,
+ .ev_process = ef100_ev_process,
+ .ev_read_ack = ef100_ev_read_ack,
+ .ev_test_generate = efx_ef100_ev_test_generate,
+ .tx_probe = ef100_tx_probe,
+ .tx_init = ef100_tx_init,
+ .tx_write = ef100_tx_write,
+ .tx_enqueue = ef100_enqueue_skb,
+ .rx_probe = efx_mcdi_rx_probe,
+ .rx_init = efx_mcdi_rx_init,
+ .rx_remove = efx_mcdi_rx_remove,
+ .rx_write = ef100_rx_write,
+ .rx_packet = __ef100_rx_packet,
+ .fini_dmaq = efx_fini_dmaq,
+ .max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
+ .filter_table_probe = ef100_filter_table_up,
+ .filter_table_restore = efx_mcdi_filter_table_restore,
+ .filter_table_remove = ef100_filter_table_down,
+ .filter_insert = efx_mcdi_filter_insert,
+ .filter_remove_safe = efx_mcdi_filter_remove_safe,
+ .filter_get_safe = efx_mcdi_filter_get_safe,
+ .filter_clear_rx = efx_mcdi_filter_clear_rx,
+ .filter_count_rx_used = efx_mcdi_filter_count_rx_used,
+ .filter_get_rx_id_limit = efx_mcdi_filter_get_rx_id_limit,
+ .filter_get_rx_ids = efx_mcdi_filter_get_rx_ids,
+#ifdef CONFIG_RFS_ACCEL
+ .filter_rfs_expire_one = efx_mcdi_filter_rfs_expire_one,
+#endif
+
+ .get_phys_port_id = efx_ef100_get_phys_port_id,
+
+ .rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN,
+ .rx_hash_offset = ESF_GZ_RX_PREFIX_RSS_HASH_LBN / 8,
+ .rx_ts_offset = ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN / 8,
+ .rx_hash_key_size = 40,
+ .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config,
+ .rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config,
+ .rx_push_rss_context_config = efx_mcdi_rx_push_rss_context_config,
+ .rx_pull_rss_context_config = efx_mcdi_rx_pull_rss_context_config,
+ .rx_restore_rss_contexts = efx_mcdi_rx_restore_rss_contexts,
+
+ .reconfigure_mac = ef100_reconfigure_mac,
+ .test_nvram = efx_new_mcdi_nvram_test_all,
+ .describe_stats = ef100_describe_stats,
+ .start_stats = efx_mcdi_mac_start_stats,
+ .update_stats = ef100_update_stats,
+ .pull_stats = efx_mcdi_mac_pull_stats,
+ .stop_stats = efx_mcdi_mac_stop_stats,
+
+ /* Per-type bar/size configuration not used on ef100. Location of
+ * registers is defined by extended capabilities.
+ */
+ .mem_bar = NULL,
+ .mem_map_size = NULL,
+
+};
+
+const struct efx_nic_type ef100_vf_nic_type = {
+ .revision = EFX_REV_EF100,
+ .is_vf = true,
+ .probe = ef100_probe_vf,
+ .offload_features = EF100_OFFLOAD_FEATURES,
+ .mcdi_max_ver = 2,
+ .mcdi_request = ef100_mcdi_request,
+ .mcdi_poll_response = ef100_mcdi_poll_response,
+ .mcdi_read_response = ef100_mcdi_read_response,
+ .mcdi_poll_reboot = ef100_mcdi_poll_reboot,
+ .mcdi_reboot_detected = ef100_mcdi_reboot_detected,
+ .irq_enable_master = efx_port_dummy_op_void,
+ .irq_test_generate = efx_ef100_irq_test_generate,
+ .irq_disable_non_ev = efx_port_dummy_op_void,
+ .push_irq_moderation = efx_channel_dummy_op_void,
+ .min_interrupt_mode = EFX_INT_MODE_MSIX,
+ .map_reset_reason = ef100_map_reset_reason,
+ .map_reset_flags = ef100_map_reset_flags,
+ .reset = ef100_reset,
+ .check_caps = ef100_check_caps,
+ .ev_probe = ef100_ev_probe,
+ .ev_init = ef100_ev_init,
+ .ev_fini = efx_mcdi_ev_fini,
+ .ev_remove = efx_mcdi_ev_remove,
+ .irq_handle_msi = ef100_msi_interrupt,
+ .ev_process = ef100_ev_process,
+ .ev_read_ack = ef100_ev_read_ack,
+ .ev_test_generate = efx_ef100_ev_test_generate,
+ .tx_probe = ef100_tx_probe,
+ .tx_init = ef100_tx_init,
+ .tx_write = ef100_tx_write,
+ .tx_enqueue = ef100_enqueue_skb,
+ .rx_probe = efx_mcdi_rx_probe,
+ .rx_init = efx_mcdi_rx_init,
+ .rx_remove = efx_mcdi_rx_remove,
+ .rx_write = ef100_rx_write,
+ .rx_packet = __ef100_rx_packet,
+ .fini_dmaq = efx_fini_dmaq,
+ .max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
+ .filter_table_probe = ef100_filter_table_up,
+ .filter_table_restore = efx_mcdi_filter_table_restore,
+ .filter_table_remove = ef100_filter_table_down,
+ .filter_insert = efx_mcdi_filter_insert,
+ .filter_remove_safe = efx_mcdi_filter_remove_safe,
+ .filter_get_safe = efx_mcdi_filter_get_safe,
+ .filter_clear_rx = efx_mcdi_filter_clear_rx,
+ .filter_count_rx_used = efx_mcdi_filter_count_rx_used,
+ .filter_get_rx_id_limit = efx_mcdi_filter_get_rx_id_limit,
+ .filter_get_rx_ids = efx_mcdi_filter_get_rx_ids,
+#ifdef CONFIG_RFS_ACCEL
+ .filter_rfs_expire_one = efx_mcdi_filter_rfs_expire_one,
+#endif
+
+ .rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN,
+ .rx_hash_offset = ESF_GZ_RX_PREFIX_RSS_HASH_LBN / 8,
+ .rx_ts_offset = ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN / 8,
+ .rx_hash_key_size = 40,
+ .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config,
+ .rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config,
+ .rx_restore_rss_contexts = efx_mcdi_rx_restore_rss_contexts,
+
+ .reconfigure_mac = ef100_reconfigure_mac,
+ .test_nvram = efx_new_mcdi_nvram_test_all,
+ .describe_stats = ef100_describe_stats,
+ .start_stats = efx_mcdi_mac_start_stats,
+ .update_stats = ef100_update_stats,
+ .pull_stats = efx_mcdi_mac_pull_stats,
+ .stop_stats = efx_mcdi_mac_stop_stats,
+
+ .mem_bar = NULL,
+ .mem_map_size = NULL,
+
+};
+
+static int compare_versions(const char *a, const char *b)
+{
+ int a_major, a_minor, a_point, a_patch;
+ int b_major, b_minor, b_point, b_patch;
+ int a_matched, b_matched;
+
+ a_matched = sscanf(a, "%d.%d.%d.%d", &a_major, &a_minor, &a_point, &a_patch);
+ b_matched = sscanf(b, "%d.%d.%d.%d", &b_major, &b_minor, &b_point, &b_patch);
+
+ if (a_matched == 4 && b_matched != 4)
+ return +1;
+
+ if (a_matched != 4 && b_matched == 4)
+ return -1;
+
+ if (a_matched != 4 && b_matched != 4)
+ return 0;
+
+ if (a_major != b_major)
+ return a_major - b_major;
+
+ if (a_minor != b_minor)
+ return a_minor - b_minor;
+
+ if (a_point != b_point)
+ return a_point - b_point;
+
+ return a_patch - b_patch;
+}
+
+enum ef100_tlv_state_machine {
+ EF100_TLV_TYPE,
+ EF100_TLV_TYPE_CONT,
+ EF100_TLV_LENGTH,
+ EF100_TLV_VALUE
+};
+
+struct ef100_tlv_state {
+ enum ef100_tlv_state_machine state;
+ u64 value;
+ u32 value_offset;
+ u16 type;
+ u8 len;
+};
+
+static int ef100_tlv_feed(struct ef100_tlv_state *state, u8 byte)
+{
+ switch (state->state) {
+ case EF100_TLV_TYPE:
+ state->type = byte & 0x7f;
+ state->state = (byte & 0x80) ? EF100_TLV_TYPE_CONT
+ : EF100_TLV_LENGTH;
+ /* Clear ready to read in a new entry */
+ state->value = 0;
+ state->value_offset = 0;
+ return 0;
+ case EF100_TLV_TYPE_CONT:
+ state->type |= byte << 7;
+ state->state = EF100_TLV_LENGTH;
+ return 0;
+ case EF100_TLV_LENGTH:
+ state->len = byte;
+ /* We only handle TLVs that fit in a u64 */
+ if (state->len > sizeof(state->value))
+ return -EOPNOTSUPP;
+ /* len may be zero, implying a value of zero */
+ state->state = state->len ? EF100_TLV_VALUE : EF100_TLV_TYPE;
+ return 0;
+ case EF100_TLV_VALUE:
+ state->value |= ((u64)byte) << (state->value_offset * 8);
+ state->value_offset++;
+ if (state->value_offset >= state->len)
+ state->state = EF100_TLV_TYPE;
+ return 0;
+ default: /* state machine error, can't happen */
+ WARN_ON_ONCE(1);
+ return -EIO;
+ }
+}
+
+static int ef100_process_design_param(struct efx_nic *efx,
+ const struct ef100_tlv_state *reader)
+{
+ struct ef100_nic_data *nic_data = efx->nic_data;
+
+ switch (reader->type) {
+ case ESE_EF100_DP_GZ_PAD: /* padding, skip it */
+ return 0;
+ case ESE_EF100_DP_GZ_PARTIAL_TSTAMP_SUB_NANO_BITS:
+ /* Driver doesn't support timestamping yet, so we don't care */
+ return 0;
+ case ESE_EF100_DP_GZ_EVQ_UNSOL_CREDIT_SEQ_BITS:
+ /* Driver doesn't support unsolicited-event credits yet, so
+ * we don't care
+ */
+ return 0;
+ case ESE_EF100_DP_GZ_NMMU_GROUP_SIZE:
+ /* Driver doesn't manage the NMMU (so we don't care) */
+ return 0;
+ case ESE_EF100_DP_GZ_RX_L4_CSUM_PROTOCOLS:
+ /* Driver uses CHECKSUM_COMPLETE, so we don't care about
+ * protocol checksum validation
+ */
+ return 0;
+ case ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN:
+ nic_data->tso_max_hdr_len = min_t(u64, reader->value, 0xffff);
+ return 0;
+ case ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS:
+ /* We always put HDR_NUM_SEGS=1 in our TSO descriptors */
+ if (!reader->value) {
+ netif_err(efx, probe, efx->net_dev,
+ "TSO_MAX_HDR_NUM_SEGS < 1\n");
+ return -EOPNOTSUPP;
+ }
+ return 0;
+ case ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY:
+ case ESE_EF100_DP_GZ_TXQ_SIZE_GRANULARITY:
+ /* Our TXQ and RXQ sizes are always power-of-two and thus divisible by
+ * EFX_MIN_DMAQ_SIZE, so we just need to check that
+ * EFX_MIN_DMAQ_SIZE is divisible by GRANULARITY.
+ * This is very unlikely to fail.
+ */
+ if (EFX_MIN_DMAQ_SIZE % reader->value) {
+ netif_err(efx, probe, efx->net_dev,
+ "%s size granularity is %llu, can't guarantee safety\n",
+ reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
+ reader->value);
+ return -EOPNOTSUPP;
+ }
+ return 0;
+ case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN:
+ nic_data->tso_max_payload_len = min_t(u64, reader->value, GSO_MAX_SIZE);
+ efx->net_dev->gso_max_size = nic_data->tso_max_payload_len;
+ return 0;
+ case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS:
+ nic_data->tso_max_payload_num_segs = min_t(u64, reader->value, 0xffff);
+ efx->net_dev->gso_max_segs = nic_data->tso_max_payload_num_segs;
+ return 0;
+ case ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES:
+ nic_data->tso_max_frames = min_t(u64, reader->value, 0xffff);
+ return 0;
+ case ESE_EF100_DP_GZ_COMPAT:
+ if (reader->value) {
+ netif_err(efx, probe, efx->net_dev,
+ "DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n",
+ reader->value);
+ return -EOPNOTSUPP;
+ }
+ return 0;
+ case ESE_EF100_DP_GZ_MEM2MEM_MAX_LEN:
+ /* Driver doesn't use mem2mem transfers */
+ return 0;
+ case ESE_EF100_DP_GZ_EVQ_TIMER_TICK_NANOS:
+ /* Driver doesn't currently use EVQ_TIMER */
+ return 0;
+ case ESE_EF100_DP_GZ_NMMU_PAGE_SIZES:
+ /* Driver doesn't manage the NMMU (so we don't care) */
+ return 0;
+ case ESE_EF100_DP_GZ_VI_STRIDES:
+ /* We never try to set the VI stride, and we don't rely on
+ * being able to find VIs past VI 0 until after we've learned
+ * the current stride from MC_CMD_GET_CAPABILITIES.
+ * So the value of this shouldn't matter.
+ */
+ if (reader->value != ESE_EF100_DP_GZ_VI_STRIDES_DEFAULT)
+ netif_dbg(efx, probe, efx->net_dev,
+ "NIC has other than default VI_STRIDES (mask "
+ "%#llx), early probing might use wrong one\n",
+ reader->value);
+ return 0;
+ case ESE_EF100_DP_GZ_RX_MAX_RUNT:
+ /* Driver doesn't look at L2_STATUS:LEN_ERR bit, so we don't
+ * care whether it indicates runt or overlength for any given
+ * packet, so we don't care about this parameter.
+ */
+ return 0;
+ default:
+ /* Host interface says "Drivers should ignore design parameters
+ * that they do not recognise."
+ */
+ netif_dbg(efx, probe, efx->net_dev,
+ "Ignoring unrecognised design parameter %u\n",
+ reader->type);
+ return 0;
+ }
+}
+
+static int ef100_check_design_params(struct efx_nic *efx)
+{
+ struct ef100_tlv_state reader = {};
+ u32 total_len, offset = 0;
+ efx_dword_t reg;
+ int rc = 0, i;
+ u32 data;
+
+ efx_readd(efx, &reg, ER_GZ_PARAMS_TLV_LEN);
+ total_len = EFX_DWORD_FIELD(reg, EFX_DWORD_0);
+ netif_dbg(efx, probe, efx->net_dev, "%u bytes of design parameters\n",
+ total_len);
+ while (offset < total_len) {
+ efx_readd(efx, &reg, ER_GZ_PARAMS_TLV + offset);
+ data = EFX_DWORD_FIELD(reg, EFX_DWORD_0);
+ for (i = 0; i < sizeof(data); i++) {
+ rc = ef100_tlv_feed(&reader, data);
+ /* Got a complete value? */
+ if (!rc && reader.state == EF100_TLV_TYPE)
+ rc = ef100_process_design_param(efx, &reader);
+ if (rc)
+ goto out;
+ data >>= 8;
+ offset++;
+ }
+ }
+ /* Check we didn't end halfway through a TLV entry, which could either
+ * mean that the TLV stream is truncated or just that it's corrupted
+ * and our state machine is out of sync.
+ */
+ if (reader.state != EF100_TLV_TYPE) {
+ if (reader.state == EF100_TLV_TYPE_CONT)
+ netif_err(efx, probe, efx->net_dev,
+ "truncated design parameter (incomplete type %u)\n",
+ reader.type);
+ else
+ netif_err(efx, probe, efx->net_dev,
+ "truncated design parameter %u\n",
+ reader.type);
+ rc = -EIO;
+ }
+out:
+ return rc;
+}
+
+/* NIC probe and remove
+ */
+static int ef100_probe_main(struct efx_nic *efx)
+{
+ unsigned int bar_size = resource_size(&efx->pci_dev->resource[efx->mem_bar]);
+ struct net_device *net_dev = efx->net_dev;
+ struct ef100_nic_data *nic_data;
+ char fw_version[32];
+ int i, rc;
+
+ if (WARN_ON(bar_size == 0))
+ return -EIO;
+
+ nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
+ if (!nic_data)
+ return -ENOMEM;
+ efx->nic_data = nic_data;
+ nic_data->efx = efx;
+ net_dev->features |= efx->type->offload_features;
+ net_dev->hw_features |= efx->type->offload_features;
+
+ /* Populate design-parameter defaults */
+ nic_data->tso_max_hdr_len = ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT;
+ nic_data->tso_max_frames = ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES_DEFAULT;
+ nic_data->tso_max_payload_num_segs = ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT;
+ nic_data->tso_max_payload_len = ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT;
+ net_dev->gso_max_segs = ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT;
+ /* Read design parameters */
+ rc = ef100_check_design_params(efx);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "Unsupported design parameters\n");
+ goto fail;
+ }
+
+ /* we assume later that we can copy from this buffer in dwords */
+ BUILD_BUG_ON(MCDI_CTL_SDU_LEN_MAX_V2 % 4);
+
+ /* MCDI buffers must be 256 byte aligned. */
+ rc = efx_nic_alloc_buffer(efx, &nic_data->mcdi_buf, MCDI_BUF_LEN,
+ GFP_KERNEL);
+ if (rc)
+ goto fail;
+
+ /* Get the MC's warm boot count. In case it's rebooting right
+ * now, be prepared to retry.
+ */
+ i = 0;
+ for (;;) {
+ rc = ef100_get_warm_boot_count(efx);
+ if (rc >= 0)
+ break;
+ if (++i == 5)
+ goto fail;
+ ssleep(1);
+ }
+ nic_data->warm_boot_count = rc;
+
+ /* In case we're recovering from a crash (kexec), we want to
+ * cancel any outstanding request by the previous user of this
+ * function. We send a special message using the least
+ * significant bits of the 'high' (doorbell) register.
+ */
+ _efx_writed(efx, cpu_to_le32(1), efx_reg(efx, ER_GZ_MC_DB_HWRD));
+
+ /* Post-IO section. */
+
+ rc = efx_mcdi_init(efx);
+ if (!rc && efx->mcdi->fn_flags &
+ (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT)) {
+ netif_info(efx, probe, efx->net_dev,
+ "No network port on this PCI function");
+ rc = -ENODEV;
+ }
+ if (rc)
+ goto fail;
+ /* Reset (most) configuration for this function */
+ rc = efx_mcdi_reset(efx, RESET_TYPE_ALL);
+ if (rc)
+ goto fail;
+
+ rc = efx_get_pf_index(efx, &nic_data->pf_index);
+ if (rc)
+ goto fail;
+
+ rc = efx_ef100_init_datapath_caps(efx);
+ if (rc < 0)
+ goto fail;
+
+ efx->max_vis = EF100_MAX_VIS;
+
+ rc = efx_mcdi_port_get_number(efx);
+ if (rc < 0)
+ goto fail;
+ efx->port_num = rc;
+
+ efx_mcdi_print_fwver(efx, fw_version, sizeof(fw_version));
+ netif_dbg(efx, drv, efx->net_dev, "Firmware version %s\n", fw_version);
+
+ if (compare_versions(fw_version, "1.1.0.1000") < 0) {
+ netif_info(efx, drv, efx->net_dev, "Firmware uses old event descriptors\n");
+ rc = -EINVAL;
+ goto fail;
+ }
+
+ if (efx_has_cap(efx, UNSOL_EV_CREDIT_SUPPORTED)) {
+ netif_info(efx, drv, efx->net_dev, "Firmware uses unsolicited-event credits\n");
+ rc = -EINVAL;
+ goto fail;
+ }
+
+ rc = ef100_phy_probe(efx);
+ if (rc)
+ goto fail;
+
+ rc = efx_init_channels(efx);
+ if (rc)
+ goto fail;
+
+ down_write(&efx->filter_sem);
+ rc = ef100_filter_table_probe(efx);
+ up_write(&efx->filter_sem);
+ if (rc)
+ goto fail;
+
+ netdev_rss_key_fill(efx->rss_context.rx_hash_key,
+ sizeof(efx->rss_context.rx_hash_key));
+
+ /* Don't fail init if RSS setup doesn't work. */
+ efx_mcdi_push_default_indir_table(efx, efx->n_rx_channels);
+
+ rc = ef100_register_netdev(efx);
+ if (rc)
+ goto fail;
+
+ return 0;
+fail:
+ return rc;
+}
+
+int ef100_probe_pf(struct efx_nic *efx)
+{
+ struct net_device *net_dev = efx->net_dev;
+ struct ef100_nic_data *nic_data;
+ int rc = ef100_probe_main(efx);
+
+ if (rc)
+ goto fail;
+
+ nic_data = efx->nic_data;
+ rc = ef100_get_mac_address(efx, net_dev->perm_addr);
+ if (rc)
+ goto fail;
+ /* Assign MAC address */
+ memcpy(net_dev->dev_addr, net_dev->perm_addr, ETH_ALEN);
+ memcpy(nic_data->port_id, net_dev->perm_addr, ETH_ALEN);
+
+ return 0;
+
+fail:
+ return rc;
+}
+
+int ef100_probe_vf(struct efx_nic *efx)
+{
+ return ef100_probe_main(efx);
+}
+
+void ef100_remove(struct efx_nic *efx)
+{
+ struct ef100_nic_data *nic_data = efx->nic_data;
+
+ ef100_unregister_netdev(efx);
+
+ down_write(&efx->filter_sem);
+ efx_mcdi_filter_table_remove(efx);
+ up_write(&efx->filter_sem);
+ efx_fini_channels(efx);
+ kfree(efx->phy_data);
+ efx->phy_data = NULL;
+ efx_mcdi_detach(efx);
+ efx_mcdi_fini(efx);
+ if (nic_data)
+ efx_nic_free_buffer(efx, &nic_data->mcdi_buf);
+ kfree(nic_data);
+ efx->nic_data = NULL;
+}
diff --git a/drivers/net/ethernet/sfc/ef100_nic.h b/drivers/net/ethernet/sfc/ef100_nic.h
new file mode 100644
index 000000000000..e799688d5264
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_nic.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "net_driver.h"
+#include "nic_common.h"
+
+extern const struct efx_nic_type ef100_pf_nic_type;
+extern const struct efx_nic_type ef100_vf_nic_type;
+
+int ef100_probe_pf(struct efx_nic *efx);
+int ef100_probe_vf(struct efx_nic *efx);
+void ef100_remove(struct efx_nic *efx);
+
+enum {
+ EF100_STAT_port_tx_bytes = GENERIC_STAT_COUNT,
+ EF100_STAT_port_tx_packets,
+ EF100_STAT_port_tx_pause,
+ EF100_STAT_port_tx_unicast,
+ EF100_STAT_port_tx_multicast,
+ EF100_STAT_port_tx_broadcast,
+ EF100_STAT_port_tx_lt64,
+ EF100_STAT_port_tx_64,
+ EF100_STAT_port_tx_65_to_127,
+ EF100_STAT_port_tx_128_to_255,
+ EF100_STAT_port_tx_256_to_511,
+ EF100_STAT_port_tx_512_to_1023,
+ EF100_STAT_port_tx_1024_to_15xx,
+ EF100_STAT_port_tx_15xx_to_jumbo,
+ EF100_STAT_port_rx_bytes,
+ EF100_STAT_port_rx_packets,
+ EF100_STAT_port_rx_good,
+ EF100_STAT_port_rx_bad,
+ EF100_STAT_port_rx_pause,
+ EF100_STAT_port_rx_unicast,
+ EF100_STAT_port_rx_multicast,
+ EF100_STAT_port_rx_broadcast,
+ EF100_STAT_port_rx_lt64,
+ EF100_STAT_port_rx_64,
+ EF100_STAT_port_rx_65_to_127,
+ EF100_STAT_port_rx_128_to_255,
+ EF100_STAT_port_rx_256_to_511,
+ EF100_STAT_port_rx_512_to_1023,
+ EF100_STAT_port_rx_1024_to_15xx,
+ EF100_STAT_port_rx_15xx_to_jumbo,
+ EF100_STAT_port_rx_gtjumbo,
+ EF100_STAT_port_rx_bad_gtjumbo,
+ EF100_STAT_port_rx_align_error,
+ EF100_STAT_port_rx_length_error,
+ EF100_STAT_port_rx_overflow,
+ EF100_STAT_port_rx_nodesc_drops,
+ EF100_STAT_COUNT
+};
+
+struct ef100_nic_data {
+ struct efx_nic *efx;
+ struct efx_buffer mcdi_buf;
+ u32 datapath_caps;
+ u32 datapath_caps2;
+ u32 datapath_caps3;
+ unsigned int pf_index;
+ u16 warm_boot_count;
+ u8 port_id[ETH_ALEN];
+ DECLARE_BITMAP(evq_phases, EFX_MAX_CHANNELS);
+ u64 stats[EF100_STAT_COUNT];
+ u16 tso_max_hdr_len;
+ u16 tso_max_payload_num_segs;
+ u16 tso_max_frames;
+ unsigned int tso_max_payload_len;
+};
+
+#define efx_ef100_has_cap(caps, flag) \
+ (!!((caps) & BIT_ULL(MC_CMD_GET_CAPABILITIES_V4_OUT_ ## flag ## _LBN)))
diff --git a/drivers/net/ethernet/sfc/ef100_regs.h b/drivers/net/ethernet/sfc/ef100_regs.h
new file mode 100644
index 000000000000..710bbdb19885
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_regs.h
@@ -0,0 +1,693 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_EF100_REGS_H
+#define EFX_EF100_REGS_H
+
+/* EF100 hardware architecture definitions have a name prefix following
+ * the format:
+ *
+ * E<type>_<min-rev><max-rev>_
+ *
+ * The following <type> strings are used:
+ *
+ * MMIO register Host memory structure
+ * -------------------------------------------------------------
+ * Address R
+ * Bitfield RF SF
+ * Enumerator FE SE
+ *
+ * <min-rev> is the first revision to which the definition applies:
+ *
+ * G: Riverhead
+ *
+ * If the definition has been changed or removed in later revisions
+ * then <max-rev> is the last revision to which the definition applies;
+ * otherwise it is "Z".
+ */
+
+/**************************************************************************
+ *
+ * EF100 registers and descriptors
+ *
+ **************************************************************************
+ */
+
+/* HW_REV_ID_REG: Hardware revision info register */
+#define ER_GZ_HW_REV_ID 0x00000000
+
+/* NIC_REV_ID: SoftNIC revision info register */
+#define ER_GZ_NIC_REV_ID 0x00000004
+
+/* NIC_MAGIC: Signature register that should contain a well-known value */
+#define ER_GZ_NIC_MAGIC 0x00000008
+#define ERF_GZ_NIC_MAGIC_LBN 0
+#define ERF_GZ_NIC_MAGIC_WIDTH 32
+#define EFE_GZ_NIC_MAGIC_EXPECTED 0xEF100FCB
+
+/* MC_SFT_STATUS: MC soft status */
+#define ER_GZ_MC_SFT_STATUS 0x00000010
+#define ER_GZ_MC_SFT_STATUS_STEP 4
+#define ER_GZ_MC_SFT_STATUS_ROWS 2
+
+/* MC_DB_LWRD_REG: MC doorbell register, low word */
+#define ER_GZ_MC_DB_LWRD 0x00000020
+
+/* MC_DB_HWRD_REG: MC doorbell register, high word */
+#define ER_GZ_MC_DB_HWRD 0x00000024
+
+/* EVQ_INT_PRIME: Prime EVQ */
+#define ER_GZ_EVQ_INT_PRIME 0x00000040
+#define ERF_GZ_IDX_LBN 16
+#define ERF_GZ_IDX_WIDTH 16
+#define ERF_GZ_EVQ_ID_LBN 0
+#define ERF_GZ_EVQ_ID_WIDTH 16
+
+/* INT_AGG_RING_PRIME: Prime interrupt aggregation ring. */
+#define ER_GZ_INT_AGG_RING_PRIME 0x00000048
+/* defined as ERF_GZ_IDX_LBN 16; access=WO reset=0x0 */
+/* defined as ERF_GZ_IDX_WIDTH 16 */
+#define ERF_GZ_RING_ID_LBN 0
+#define ERF_GZ_RING_ID_WIDTH 16
+
+/* EVQ_TMR: EVQ timer control */
+#define ER_GZ_EVQ_TMR 0x00000104
+#define ER_GZ_EVQ_TMR_STEP 65536
+#define ER_GZ_EVQ_TMR_ROWS 1024
+
+/* EVQ_UNSOL_CREDIT_GRANT_SEQ: Grant credits for unsolicited events. */
+#define ER_GZ_EVQ_UNSOL_CREDIT_GRANT_SEQ 0x00000108
+#define ER_GZ_EVQ_UNSOL_CREDIT_GRANT_SEQ_STEP 65536
+#define ER_GZ_EVQ_UNSOL_CREDIT_GRANT_SEQ_ROWS 1024
+
+/* EVQ_DESC_CREDIT_GRANT_SEQ: Grant credits for descriptor proxy events. */
+#define ER_GZ_EVQ_DESC_CREDIT_GRANT_SEQ 0x00000110
+#define ER_GZ_EVQ_DESC_CREDIT_GRANT_SEQ_STEP 65536
+#define ER_GZ_EVQ_DESC_CREDIT_GRANT_SEQ_ROWS 1024
+
+/* RX_RING_DOORBELL: Ring Rx doorbell. */
+#define ER_GZ_RX_RING_DOORBELL 0x00000180
+#define ER_GZ_RX_RING_DOORBELL_STEP 65536
+#define ER_GZ_RX_RING_DOORBELL_ROWS 1024
+#define ERF_GZ_RX_RING_PIDX_LBN 16
+#define ERF_GZ_RX_RING_PIDX_WIDTH 16
+
+/* TX_RING_DOORBELL: Ring Tx doorbell. */
+#define ER_GZ_TX_RING_DOORBELL 0x00000200
+#define ER_GZ_TX_RING_DOORBELL_STEP 65536
+#define ER_GZ_TX_RING_DOORBELL_ROWS 1024
+#define ERF_GZ_TX_RING_PIDX_LBN 16
+#define ERF_GZ_TX_RING_PIDX_WIDTH 16
+
+/* TX_DESC_PUSH: Tx ring descriptor push. Reserved for future use. */
+#define ER_GZ_TX_DESC_PUSH 0x00000210
+#define ER_GZ_TX_DESC_PUSH_STEP 65536
+#define ER_GZ_TX_DESC_PUSH_ROWS 1024
+
+/* THE_TIME: NIC hardware time */
+#define ER_GZ_THE_TIME 0x00000280
+#define ER_GZ_THE_TIME_STEP 65536
+#define ER_GZ_THE_TIME_ROWS 1024
+#define ERF_GZ_THE_TIME_SECS_LBN 32
+#define ERF_GZ_THE_TIME_SECS_WIDTH 32
+#define ERF_GZ_THE_TIME_NANOS_LBN 2
+#define ERF_GZ_THE_TIME_NANOS_WIDTH 30
+#define ERF_GZ_THE_TIME_CLOCK_IN_SYNC_LBN 1
+#define ERF_GZ_THE_TIME_CLOCK_IN_SYNC_WIDTH 1
+#define ERF_GZ_THE_TIME_CLOCK_IS_SET_LBN 0
+#define ERF_GZ_THE_TIME_CLOCK_IS_SET_WIDTH 1
+
+/* PARAMS_TLV_LEN: Size of design parameters area in bytes */
+#define ER_GZ_PARAMS_TLV_LEN 0x00000c00
+#define ER_GZ_PARAMS_TLV_LEN_STEP 65536
+#define ER_GZ_PARAMS_TLV_LEN_ROWS 1024
+
+/* PARAMS_TLV: Design parameters */
+#define ER_GZ_PARAMS_TLV 0x00000c04
+#define ER_GZ_PARAMS_TLV_STEP 65536
+#define ER_GZ_PARAMS_TLV_ROWS 1024
+
+/* EW_EMBEDDED_EVENT */
+#define ESF_GZ_EV_256_EVENT_LBN 0
+#define ESF_GZ_EV_256_EVENT_WIDTH 64
+#define ESE_GZ_EW_EMBEDDED_EVENT_STRUCT_SIZE 64
+
+/* NMMU_PAGESZ_2M_ADDR */
+#define ESF_GZ_NMMU_2M_PAGE_SIZE_ID_LBN 59
+#define ESF_GZ_NMMU_2M_PAGE_SIZE_ID_WIDTH 5
+#define ESE_GZ_NMMU_PAGE_SIZE_2M 9
+#define ESF_GZ_NMMU_2M_PAGE_ID_LBN 21
+#define ESF_GZ_NMMU_2M_PAGE_ID_WIDTH 38
+#define ESF_GZ_NMMU_2M_PAGE_OFFSET_LBN 0
+#define ESF_GZ_NMMU_2M_PAGE_OFFSET_WIDTH 21
+#define ESE_GZ_NMMU_PAGESZ_2M_ADDR_STRUCT_SIZE 64
+
+/* PARAM_TLV */
+#define ESF_GZ_TLV_VALUE_LBN 16
+#define ESF_GZ_TLV_VALUE_WIDTH 8
+#define ESE_GZ_TLV_VALUE_LENMIN 8
+#define ESE_GZ_TLV_VALUE_LENMAX 2040
+#define ESF_GZ_TLV_LEN_LBN 8
+#define ESF_GZ_TLV_LEN_WIDTH 8
+#define ESF_GZ_TLV_TYPE_LBN 0
+#define ESF_GZ_TLV_TYPE_WIDTH 8
+#define ESE_GZ_DP_NMMU_GROUP_SIZE 5
+#define ESE_GZ_DP_EVQ_UNSOL_CREDIT_SEQ_BITS 4
+#define ESE_GZ_DP_TX_EV_NUM_DESCS_BITS 3
+#define ESE_GZ_DP_RX_EV_NUM_PACKETS_BITS 2
+#define ESE_GZ_DP_PARTIAL_TSTAMP_SUB_NANO_BITS 1
+#define ESE_GZ_DP_PAD 0
+#define ESE_GZ_PARAM_TLV_STRUCT_SIZE 24
+
+/* PCI_EXPRESS_XCAP_HDR */
+#define ESF_GZ_PCI_EXPRESS_XCAP_NEXT_LBN 20
+#define ESF_GZ_PCI_EXPRESS_XCAP_NEXT_WIDTH 12
+#define ESF_GZ_PCI_EXPRESS_XCAP_VER_LBN 16
+#define ESF_GZ_PCI_EXPRESS_XCAP_VER_WIDTH 4
+#define ESE_GZ_PCI_EXPRESS_XCAP_VER_VSEC 1
+#define ESF_GZ_PCI_EXPRESS_XCAP_ID_LBN 0
+#define ESF_GZ_PCI_EXPRESS_XCAP_ID_WIDTH 16
+#define ESE_GZ_PCI_EXPRESS_XCAP_ID_VNDR 0xb
+#define ESE_GZ_PCI_EXPRESS_XCAP_HDR_STRUCT_SIZE 32
+
+/* RHEAD_BASE_EVENT */
+#define ESF_GZ_E_TYPE_LBN 60
+#define ESF_GZ_E_TYPE_WIDTH 4
+#define ESE_GZ_EF100_EV_DRIVER 5
+#define ESE_GZ_EF100_EV_MCDI 4
+#define ESE_GZ_EF100_EV_CONTROL 3
+#define ESE_GZ_EF100_EV_TX_TIMESTAMP 2
+#define ESE_GZ_EF100_EV_TX_COMPLETION 1
+#define ESE_GZ_EF100_EV_RX_PKTS 0
+#define ESF_GZ_EV_EVQ_PHASE_LBN 59
+#define ESF_GZ_EV_EVQ_PHASE_WIDTH 1
+#define ESE_GZ_RHEAD_BASE_EVENT_STRUCT_SIZE 64
+
+/* RHEAD_EW_EVENT */
+#define ESF_GZ_EV_256_EV32_PHASE_LBN 255
+#define ESF_GZ_EV_256_EV32_PHASE_WIDTH 1
+#define ESF_GZ_EV_256_EV32_TYPE_LBN 251
+#define ESF_GZ_EV_256_EV32_TYPE_WIDTH 4
+#define ESE_GZ_EF100_EVEW_VIRTQ_DESC 2
+#define ESE_GZ_EF100_EVEW_TXQ_DESC 1
+#define ESE_GZ_EF100_EVEW_64BIT 0
+#define ESE_GZ_RHEAD_EW_EVENT_STRUCT_SIZE 256
+
+/* RX_DESC */
+#define ESF_GZ_RX_BUF_ADDR_LBN 0
+#define ESF_GZ_RX_BUF_ADDR_WIDTH 64
+#define ESE_GZ_RX_DESC_STRUCT_SIZE 64
+
+/* TXQ_DESC_PROXY_EVENT */
+#define ESF_GZ_EV_TXQ_DP_VI_ID_LBN 128
+#define ESF_GZ_EV_TXQ_DP_VI_ID_WIDTH 16
+#define ESF_GZ_EV_TXQ_DP_TXQ_DESC_LBN 0
+#define ESF_GZ_EV_TXQ_DP_TXQ_DESC_WIDTH 128
+#define ESE_GZ_TXQ_DESC_PROXY_EVENT_STRUCT_SIZE 144
+
+/* TX_DESC_TYPE */
+#define ESF_GZ_TX_DESC_TYPE_LBN 124
+#define ESF_GZ_TX_DESC_TYPE_WIDTH 4
+#define ESE_GZ_TX_DESC_TYPE_DESC2CMPT 7
+#define ESE_GZ_TX_DESC_TYPE_MEM2MEM 4
+#define ESE_GZ_TX_DESC_TYPE_SEG 3
+#define ESE_GZ_TX_DESC_TYPE_TSO 2
+#define ESE_GZ_TX_DESC_TYPE_PREFIX 1
+#define ESE_GZ_TX_DESC_TYPE_SEND 0
+#define ESE_GZ_TX_DESC_TYPE_STRUCT_SIZE 128
+
+/* VIRTQ_DESC_PROXY_EVENT */
+#define ESF_GZ_EV_VQ_DP_AVAIL_ENTRY_LBN 144
+#define ESF_GZ_EV_VQ_DP_AVAIL_ENTRY_WIDTH 16
+#define ESF_GZ_EV_VQ_DP_VI_ID_LBN 128
+#define ESF_GZ_EV_VQ_DP_VI_ID_WIDTH 16
+#define ESF_GZ_EV_VQ_DP_VIRTQ_DESC_LBN 0
+#define ESF_GZ_EV_VQ_DP_VIRTQ_DESC_WIDTH 128
+#define ESE_GZ_VIRTQ_DESC_PROXY_EVENT_STRUCT_SIZE 160
+
+/* XIL_CFGBAR_TBL_ENTRY */
+#define ESF_GZ_CFGBAR_CONT_CAP_OFF_HI_LBN 96
+#define ESF_GZ_CFGBAR_CONT_CAP_OFF_HI_WIDTH 32
+#define ESF_GZ_CFGBAR_CONT_CAP_OFFSET_LBN 68
+#define ESF_GZ_CFGBAR_CONT_CAP_OFFSET_WIDTH 60
+#define ESE_GZ_CONT_CAP_OFFSET_BYTES_SHIFT 4
+#define ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF_LBN 67
+#define ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF_WIDTH 29
+#define ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT 4
+#define ESF_GZ_CFGBAR_CONT_CAP_OFF_LO_LBN 68
+#define ESF_GZ_CFGBAR_CONT_CAP_OFF_LO_WIDTH 28
+#define ESF_GZ_CFGBAR_CONT_CAP_RSV_LBN 67
+#define ESF_GZ_CFGBAR_CONT_CAP_RSV_WIDTH 1
+#define ESF_GZ_CFGBAR_EF100_BAR_LBN 64
+#define ESF_GZ_CFGBAR_EF100_BAR_WIDTH 3
+#define ESE_GZ_CFGBAR_EF100_BAR_NUM_INVALID 7
+#define ESE_GZ_CFGBAR_EF100_BAR_NUM_EXPANSION_ROM 6
+#define ESF_GZ_CFGBAR_CONT_CAP_BAR_LBN 64
+#define ESF_GZ_CFGBAR_CONT_CAP_BAR_WIDTH 3
+#define ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_INVALID 7
+#define ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_EXPANSION_ROM 6
+#define ESF_GZ_CFGBAR_ENTRY_SIZE_LBN 32
+#define ESF_GZ_CFGBAR_ENTRY_SIZE_WIDTH 32
+#define ESE_GZ_CFGBAR_ENTRY_SIZE_EF100 12
+#define ESE_GZ_CFGBAR_ENTRY_HEADER_SIZE 8
+#define ESF_GZ_CFGBAR_ENTRY_LAST_LBN 28
+#define ESF_GZ_CFGBAR_ENTRY_LAST_WIDTH 1
+#define ESF_GZ_CFGBAR_ENTRY_REV_LBN 20
+#define ESF_GZ_CFGBAR_ENTRY_REV_WIDTH 8
+#define ESE_GZ_CFGBAR_ENTRY_REV_EF100 0
+#define ESF_GZ_CFGBAR_ENTRY_FORMAT_LBN 0
+#define ESF_GZ_CFGBAR_ENTRY_FORMAT_WIDTH 20
+#define ESE_GZ_CFGBAR_ENTRY_LAST 0xfffff
+#define ESE_GZ_CFGBAR_ENTRY_CONT_CAP_ADDR 0xffffe
+#define ESE_GZ_CFGBAR_ENTRY_EF100 0xef100
+#define ESE_GZ_XIL_CFGBAR_TBL_ENTRY_STRUCT_SIZE 128
+
+/* XIL_CFGBAR_VSEC */
+#define ESF_GZ_VSEC_TBL_OFF_HI_LBN 64
+#define ESF_GZ_VSEC_TBL_OFF_HI_WIDTH 32
+#define ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT 32
+#define ESF_GZ_VSEC_TBL_OFF_LO_LBN 36
+#define ESF_GZ_VSEC_TBL_OFF_LO_WIDTH 28
+#define ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT 4
+#define ESF_GZ_VSEC_TBL_BAR_LBN 32
+#define ESF_GZ_VSEC_TBL_BAR_WIDTH 4
+#define ESE_GZ_VSEC_BAR_NUM_INVALID 7
+#define ESE_GZ_VSEC_BAR_NUM_EXPANSION_ROM 6
+#define ESF_GZ_VSEC_LEN_LBN 20
+#define ESF_GZ_VSEC_LEN_WIDTH 12
+#define ESE_GZ_VSEC_LEN_HIGH_OFFT 16
+#define ESE_GZ_VSEC_LEN_MIN 12
+#define ESF_GZ_VSEC_VER_LBN 16
+#define ESF_GZ_VSEC_VER_WIDTH 4
+#define ESE_GZ_VSEC_VER_XIL_CFGBAR 0
+#define ESF_GZ_VSEC_ID_LBN 0
+#define ESF_GZ_VSEC_ID_WIDTH 16
+#define ESE_GZ_XILINX_VSEC_ID 0x20
+#define ESE_GZ_XIL_CFGBAR_VSEC_STRUCT_SIZE 96
+
+/* rh_egres_hclass */
+#define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L4_CSUM_LBN 15
+#define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L4_CSUM_WIDTH 1
+#define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L3_CLASS_LBN 13
+#define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L3_CLASS_WIDTH 2
+#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CSUM_LBN 12
+#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CSUM_WIDTH 1
+#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CLASS_LBN 10
+#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CLASS_WIDTH 2
+#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_LBN 8
+#define ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_WIDTH 2
+#define ESF_GZ_RX_PREFIX_HCLASS_TUNNEL_CLASS_LBN 5
+#define ESF_GZ_RX_PREFIX_HCLASS_TUNNEL_CLASS_WIDTH 3
+#define ESF_GZ_RX_PREFIX_HCLASS_L2_N_VLAN_LBN 3
+#define ESF_GZ_RX_PREFIX_HCLASS_L2_N_VLAN_WIDTH 2
+#define ESF_GZ_RX_PREFIX_HCLASS_L2_CLASS_LBN 2
+#define ESF_GZ_RX_PREFIX_HCLASS_L2_CLASS_WIDTH 1
+#define ESF_GZ_RX_PREFIX_HCLASS_L2_STATUS_LBN 0
+#define ESF_GZ_RX_PREFIX_HCLASS_L2_STATUS_WIDTH 2
+#define ESE_GZ_RH_EGRES_HCLASS_STRUCT_SIZE 16
+
+/* sf_driver */
+#define ESF_GZ_DRIVER_E_TYPE_LBN 60
+#define ESF_GZ_DRIVER_E_TYPE_WIDTH 4
+#define ESF_GZ_DRIVER_PHASE_LBN 59
+#define ESF_GZ_DRIVER_PHASE_WIDTH 1
+#define ESF_GZ_DRIVER_DATA_LBN 0
+#define ESF_GZ_DRIVER_DATA_WIDTH 59
+#define ESE_GZ_SF_DRIVER_STRUCT_SIZE 64
+
+/* sf_ev_rsvd */
+#define ESF_GZ_EV_RSVD_TBD_NEXT_LBN 34
+#define ESF_GZ_EV_RSVD_TBD_NEXT_WIDTH 3
+#define ESF_GZ_EV_RSVD_EVENT_GEN_FLAGS_LBN 30
+#define ESF_GZ_EV_RSVD_EVENT_GEN_FLAGS_WIDTH 4
+#define ESF_GZ_EV_RSVD_SRC_QID_LBN 18
+#define ESF_GZ_EV_RSVD_SRC_QID_WIDTH 12
+#define ESF_GZ_EV_RSVD_SEQ_NUM_LBN 2
+#define ESF_GZ_EV_RSVD_SEQ_NUM_WIDTH 16
+#define ESF_GZ_EV_RSVD_TBD_LBN 0
+#define ESF_GZ_EV_RSVD_TBD_WIDTH 2
+#define ESE_GZ_SF_EV_RSVD_STRUCT_SIZE 37
+
+/* sf_flush_evnt */
+#define ESF_GZ_EV_FLSH_E_TYPE_LBN 60
+#define ESF_GZ_EV_FLSH_E_TYPE_WIDTH 4
+#define ESF_GZ_EV_FLSH_PHASE_LBN 59
+#define ESF_GZ_EV_FLSH_PHASE_WIDTH 1
+#define ESF_GZ_EV_FLSH_SUB_TYPE_LBN 53
+#define ESF_GZ_EV_FLSH_SUB_TYPE_WIDTH 6
+#define ESF_GZ_EV_FLSH_RSVD_LBN 10
+#define ESF_GZ_EV_FLSH_RSVD_WIDTH 43
+#define ESF_GZ_EV_FLSH_LABEL_LBN 4
+#define ESF_GZ_EV_FLSH_LABEL_WIDTH 6
+#define ESF_GZ_EV_FLSH_FLUSH_TYPE_LBN 0
+#define ESF_GZ_EV_FLSH_FLUSH_TYPE_WIDTH 4
+#define ESE_GZ_SF_FLUSH_EVNT_STRUCT_SIZE 64
+
+/* sf_rx_pkts */
+#define ESF_GZ_EV_RXPKTS_E_TYPE_LBN 60
+#define ESF_GZ_EV_RXPKTS_E_TYPE_WIDTH 4
+#define ESF_GZ_EV_RXPKTS_PHASE_LBN 59
+#define ESF_GZ_EV_RXPKTS_PHASE_WIDTH 1
+#define ESF_GZ_EV_RXPKTS_RSVD_LBN 22
+#define ESF_GZ_EV_RXPKTS_RSVD_WIDTH 37
+#define ESF_GZ_EV_RXPKTS_Q_LABEL_LBN 16
+#define ESF_GZ_EV_RXPKTS_Q_LABEL_WIDTH 6
+#define ESF_GZ_EV_RXPKTS_NUM_PKT_LBN 0
+#define ESF_GZ_EV_RXPKTS_NUM_PKT_WIDTH 16
+#define ESE_GZ_SF_RX_PKTS_STRUCT_SIZE 64
+
+/* sf_rx_prefix */
+#define ESF_GZ_RX_PREFIX_VLAN_STRIP_TCI_LBN 160
+#define ESF_GZ_RX_PREFIX_VLAN_STRIP_TCI_WIDTH 16
+#define ESF_GZ_RX_PREFIX_CSUM_FRAME_LBN 144
+#define ESF_GZ_RX_PREFIX_CSUM_FRAME_WIDTH 16
+#define ESF_GZ_RX_PREFIX_INGRESS_VPORT_LBN 128
+#define ESF_GZ_RX_PREFIX_INGRESS_VPORT_WIDTH 16
+#define ESF_GZ_RX_PREFIX_USER_MARK_LBN 96
+#define ESF_GZ_RX_PREFIX_USER_MARK_WIDTH 32
+#define ESF_GZ_RX_PREFIX_RSS_HASH_LBN 64
+#define ESF_GZ_RX_PREFIX_RSS_HASH_WIDTH 32
+#define ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN 32
+#define ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_WIDTH 32
+#define ESF_GZ_RX_PREFIX_CLASS_LBN 16
+#define ESF_GZ_RX_PREFIX_CLASS_WIDTH 16
+#define ESF_GZ_RX_PREFIX_USER_FLAG_LBN 15
+#define ESF_GZ_RX_PREFIX_USER_FLAG_WIDTH 1
+#define ESF_GZ_RX_PREFIX_RSS_HASH_VALID_LBN 14
+#define ESF_GZ_RX_PREFIX_RSS_HASH_VALID_WIDTH 1
+#define ESF_GZ_RX_PREFIX_LENGTH_LBN 0
+#define ESF_GZ_RX_PREFIX_LENGTH_WIDTH 14
+#define ESE_GZ_SF_RX_PREFIX_STRUCT_SIZE 176
+
+/* sf_rxtx_generic */
+#define ESF_GZ_EV_BARRIER_LBN 167
+#define ESF_GZ_EV_BARRIER_WIDTH 1
+#define ESF_GZ_EV_RSVD_LBN 130
+#define ESF_GZ_EV_RSVD_WIDTH 37
+#define ESF_GZ_EV_DPRXY_LBN 129
+#define ESF_GZ_EV_DPRXY_WIDTH 1
+#define ESF_GZ_EV_VIRTIO_LBN 128
+#define ESF_GZ_EV_VIRTIO_WIDTH 1
+#define ESF_GZ_EV_COUNT_LBN 0
+#define ESF_GZ_EV_COUNT_WIDTH 128
+#define ESE_GZ_SF_RXTX_GENERIC_STRUCT_SIZE 168
+
+/* sf_ts_stamp */
+#define ESF_GZ_EV_TS_E_TYPE_LBN 60
+#define ESF_GZ_EV_TS_E_TYPE_WIDTH 4
+#define ESF_GZ_EV_TS_PHASE_LBN 59
+#define ESF_GZ_EV_TS_PHASE_WIDTH 1
+#define ESF_GZ_EV_TS_RSVD_LBN 56
+#define ESF_GZ_EV_TS_RSVD_WIDTH 3
+#define ESF_GZ_EV_TS_STATUS_LBN 54
+#define ESF_GZ_EV_TS_STATUS_WIDTH 2
+#define ESF_GZ_EV_TS_Q_LABEL_LBN 48
+#define ESF_GZ_EV_TS_Q_LABEL_WIDTH 6
+#define ESF_GZ_EV_TS_DESC_ID_LBN 32
+#define ESF_GZ_EV_TS_DESC_ID_WIDTH 16
+#define ESF_GZ_EV_TS_PARTIAL_STAMP_LBN 0
+#define ESF_GZ_EV_TS_PARTIAL_STAMP_WIDTH 32
+#define ESE_GZ_SF_TS_STAMP_STRUCT_SIZE 64
+
+/* sf_tx_cmplt */
+#define ESF_GZ_EV_TXCMPL_E_TYPE_LBN 60
+#define ESF_GZ_EV_TXCMPL_E_TYPE_WIDTH 4
+#define ESF_GZ_EV_TXCMPL_PHASE_LBN 59
+#define ESF_GZ_EV_TXCMPL_PHASE_WIDTH 1
+#define ESF_GZ_EV_TXCMPL_RSVD_LBN 22
+#define ESF_GZ_EV_TXCMPL_RSVD_WIDTH 37
+#define ESF_GZ_EV_TXCMPL_Q_LABEL_LBN 16
+#define ESF_GZ_EV_TXCMPL_Q_LABEL_WIDTH 6
+#define ESF_GZ_EV_TXCMPL_NUM_DESC_LBN 0
+#define ESF_GZ_EV_TXCMPL_NUM_DESC_WIDTH 16
+#define ESE_GZ_SF_TX_CMPLT_STRUCT_SIZE 64
+
+/* sf_tx_desc2cmpt_dsc_fmt */
+#define ESF_GZ_D2C_TGT_VI_ID_LBN 108
+#define ESF_GZ_D2C_TGT_VI_ID_WIDTH 16
+#define ESF_GZ_D2C_CMPT2_LBN 107
+#define ESF_GZ_D2C_CMPT2_WIDTH 1
+#define ESF_GZ_D2C_ABS_VI_ID_LBN 106
+#define ESF_GZ_D2C_ABS_VI_ID_WIDTH 1
+#define ESF_GZ_D2C_ORDERED_LBN 105
+#define ESF_GZ_D2C_ORDERED_WIDTH 1
+#define ESF_GZ_D2C_SKIP_N_LBN 97
+#define ESF_GZ_D2C_SKIP_N_WIDTH 8
+#define ESF_GZ_D2C_RSVD_LBN 64
+#define ESF_GZ_D2C_RSVD_WIDTH 33
+#define ESF_GZ_D2C_COMPLETION_LBN 0
+#define ESF_GZ_D2C_COMPLETION_WIDTH 64
+#define ESE_GZ_SF_TX_DESC2CMPT_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_mem2mem_dsc_fmt */
+#define ESF_GZ_M2M_ADDR_SPC_EN_LBN 123
+#define ESF_GZ_M2M_ADDR_SPC_EN_WIDTH 1
+#define ESF_GZ_M2M_TRANSLATE_ADDR_LBN 122
+#define ESF_GZ_M2M_TRANSLATE_ADDR_WIDTH 1
+#define ESF_GZ_M2M_RSVD_LBN 120
+#define ESF_GZ_M2M_RSVD_WIDTH 2
+#define ESF_GZ_M2M_ADDR_SPC_LBN 108
+#define ESF_GZ_M2M_ADDR_SPC_WIDTH 12
+#define ESF_GZ_M2M_ADDR_SPC_PASID_LBN 86
+#define ESF_GZ_M2M_ADDR_SPC_PASID_WIDTH 22
+#define ESF_GZ_M2M_ADDR_SPC_MODE_LBN 84
+#define ESF_GZ_M2M_ADDR_SPC_MODE_WIDTH 2
+#define ESF_GZ_M2M_LEN_MINUS_1_LBN 64
+#define ESF_GZ_M2M_LEN_MINUS_1_WIDTH 20
+#define ESF_GZ_M2M_ADDR_LBN 0
+#define ESF_GZ_M2M_ADDR_WIDTH 64
+#define ESE_GZ_SF_TX_MEM2MEM_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_ovr_dsc_fmt */
+#define ESF_GZ_TX_PREFIX_MARK_EN_LBN 123
+#define ESF_GZ_TX_PREFIX_MARK_EN_WIDTH 1
+#define ESF_GZ_TX_PREFIX_INGRESS_MPORT_EN_LBN 122
+#define ESF_GZ_TX_PREFIX_INGRESS_MPORT_EN_WIDTH 1
+#define ESF_GZ_TX_PREFIX_INLINE_CAPSULE_META_LBN 121
+#define ESF_GZ_TX_PREFIX_INLINE_CAPSULE_META_WIDTH 1
+#define ESF_GZ_TX_PREFIX_EGRESS_MPORT_EN_LBN 120
+#define ESF_GZ_TX_PREFIX_EGRESS_MPORT_EN_WIDTH 1
+#define ESF_GZ_TX_PREFIX_RSRVD_LBN 64
+#define ESF_GZ_TX_PREFIX_RSRVD_WIDTH 56
+#define ESF_GZ_TX_PREFIX_EGRESS_MPORT_LBN 48
+#define ESF_GZ_TX_PREFIX_EGRESS_MPORT_WIDTH 16
+#define ESF_GZ_TX_PREFIX_INGRESS_MPORT_LBN 32
+#define ESF_GZ_TX_PREFIX_INGRESS_MPORT_WIDTH 16
+#define ESF_GZ_TX_PREFIX_MARK_LBN 0
+#define ESF_GZ_TX_PREFIX_MARK_WIDTH 32
+#define ESE_GZ_SF_TX_OVR_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_seg_dsc_fmt */
+#define ESF_GZ_TX_SEG_ADDR_SPC_EN_LBN 123
+#define ESF_GZ_TX_SEG_ADDR_SPC_EN_WIDTH 1
+#define ESF_GZ_TX_SEG_TRANSLATE_ADDR_LBN 122
+#define ESF_GZ_TX_SEG_TRANSLATE_ADDR_WIDTH 1
+#define ESF_GZ_TX_SEG_RSVD2_LBN 120
+#define ESF_GZ_TX_SEG_RSVD2_WIDTH 2
+#define ESF_GZ_TX_SEG_ADDR_SPC_LBN 108
+#define ESF_GZ_TX_SEG_ADDR_SPC_WIDTH 12
+#define ESF_GZ_TX_SEG_ADDR_SPC_PASID_LBN 86
+#define ESF_GZ_TX_SEG_ADDR_SPC_PASID_WIDTH 22
+#define ESF_GZ_TX_SEG_ADDR_SPC_MODE_LBN 84
+#define ESF_GZ_TX_SEG_ADDR_SPC_MODE_WIDTH 2
+#define ESF_GZ_TX_SEG_RSVD_LBN 80
+#define ESF_GZ_TX_SEG_RSVD_WIDTH 4
+#define ESF_GZ_TX_SEG_LEN_LBN 64
+#define ESF_GZ_TX_SEG_LEN_WIDTH 16
+#define ESF_GZ_TX_SEG_ADDR_LBN 0
+#define ESF_GZ_TX_SEG_ADDR_WIDTH 64
+#define ESE_GZ_SF_TX_SEG_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_std_dsc_fmt */
+#define ESF_GZ_TX_SEND_VLAN_INSERT_TCI_LBN 108
+#define ESF_GZ_TX_SEND_VLAN_INSERT_TCI_WIDTH 16
+#define ESF_GZ_TX_SEND_VLAN_INSERT_EN_LBN 107
+#define ESF_GZ_TX_SEND_VLAN_INSERT_EN_WIDTH 1
+#define ESF_GZ_TX_SEND_TSTAMP_REQ_LBN 106
+#define ESF_GZ_TX_SEND_TSTAMP_REQ_WIDTH 1
+#define ESF_GZ_TX_SEND_CSO_OUTER_L4_LBN 105
+#define ESF_GZ_TX_SEND_CSO_OUTER_L4_WIDTH 1
+#define ESF_GZ_TX_SEND_CSO_OUTER_L3_LBN 104
+#define ESF_GZ_TX_SEND_CSO_OUTER_L3_WIDTH 1
+#define ESF_GZ_TX_SEND_CSO_INNER_L3_LBN 101
+#define ESF_GZ_TX_SEND_CSO_INNER_L3_WIDTH 3
+#define ESF_GZ_TX_SEND_RSVD_LBN 99
+#define ESF_GZ_TX_SEND_RSVD_WIDTH 2
+#define ESF_GZ_TX_SEND_CSO_PARTIAL_EN_LBN 97
+#define ESF_GZ_TX_SEND_CSO_PARTIAL_EN_WIDTH 2
+#define ESF_GZ_TX_SEND_CSO_PARTIAL_CSUM_W_LBN 92
+#define ESF_GZ_TX_SEND_CSO_PARTIAL_CSUM_W_WIDTH 5
+#define ESF_GZ_TX_SEND_CSO_PARTIAL_START_W_LBN 83
+#define ESF_GZ_TX_SEND_CSO_PARTIAL_START_W_WIDTH 9
+#define ESF_GZ_TX_SEND_NUM_SEGS_LBN 78
+#define ESF_GZ_TX_SEND_NUM_SEGS_WIDTH 5
+#define ESF_GZ_TX_SEND_LEN_LBN 64
+#define ESF_GZ_TX_SEND_LEN_WIDTH 14
+#define ESF_GZ_TX_SEND_ADDR_LBN 0
+#define ESF_GZ_TX_SEND_ADDR_WIDTH 64
+#define ESE_GZ_SF_TX_STD_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_tso_dsc_fmt */
+#define ESF_GZ_TX_TSO_VLAN_INSERT_TCI_LBN 108
+#define ESF_GZ_TX_TSO_VLAN_INSERT_TCI_WIDTH 16
+#define ESF_GZ_TX_TSO_VLAN_INSERT_EN_LBN 107
+#define ESF_GZ_TX_TSO_VLAN_INSERT_EN_WIDTH 1
+#define ESF_GZ_TX_TSO_TSTAMP_REQ_LBN 106
+#define ESF_GZ_TX_TSO_TSTAMP_REQ_WIDTH 1
+#define ESF_GZ_TX_TSO_CSO_OUTER_L4_LBN 105
+#define ESF_GZ_TX_TSO_CSO_OUTER_L4_WIDTH 1
+#define ESF_GZ_TX_TSO_CSO_OUTER_L3_LBN 104
+#define ESF_GZ_TX_TSO_CSO_OUTER_L3_WIDTH 1
+#define ESF_GZ_TX_TSO_CSO_INNER_L3_LBN 101
+#define ESF_GZ_TX_TSO_CSO_INNER_L3_WIDTH 3
+#define ESF_GZ_TX_TSO_RSVD_LBN 94
+#define ESF_GZ_TX_TSO_RSVD_WIDTH 7
+#define ESF_GZ_TX_TSO_CSO_INNER_L4_LBN 93
+#define ESF_GZ_TX_TSO_CSO_INNER_L4_WIDTH 1
+#define ESF_GZ_TX_TSO_INNER_L4_OFF_W_LBN 85
+#define ESF_GZ_TX_TSO_INNER_L4_OFF_W_WIDTH 8
+#define ESF_GZ_TX_TSO_INNER_L3_OFF_W_LBN 77
+#define ESF_GZ_TX_TSO_INNER_L3_OFF_W_WIDTH 8
+#define ESF_GZ_TX_TSO_OUTER_L4_OFF_W_LBN 69
+#define ESF_GZ_TX_TSO_OUTER_L4_OFF_W_WIDTH 8
+#define ESF_GZ_TX_TSO_OUTER_L3_OFF_W_LBN 64
+#define ESF_GZ_TX_TSO_OUTER_L3_OFF_W_WIDTH 5
+#define ESF_GZ_TX_TSO_PAYLOAD_LEN_LBN 42
+#define ESF_GZ_TX_TSO_PAYLOAD_LEN_WIDTH 22
+#define ESF_GZ_TX_TSO_HDR_LEN_W_LBN 34
+#define ESF_GZ_TX_TSO_HDR_LEN_W_WIDTH 8
+#define ESF_GZ_TX_TSO_ED_OUTER_UDP_LEN_LBN 33
+#define ESF_GZ_TX_TSO_ED_OUTER_UDP_LEN_WIDTH 1
+#define ESF_GZ_TX_TSO_ED_INNER_IP_LEN_LBN 32
+#define ESF_GZ_TX_TSO_ED_INNER_IP_LEN_WIDTH 1
+#define ESF_GZ_TX_TSO_ED_OUTER_IP_LEN_LBN 31
+#define ESF_GZ_TX_TSO_ED_OUTER_IP_LEN_WIDTH 1
+#define ESF_GZ_TX_TSO_ED_INNER_IP4_ID_LBN 29
+#define ESF_GZ_TX_TSO_ED_INNER_IP4_ID_WIDTH 2
+#define ESF_GZ_TX_TSO_ED_OUTER_IP4_ID_LBN 27
+#define ESF_GZ_TX_TSO_ED_OUTER_IP4_ID_WIDTH 2
+#define ESF_GZ_TX_TSO_PAYLOAD_NUM_SEGS_LBN 17
+#define ESF_GZ_TX_TSO_PAYLOAD_NUM_SEGS_WIDTH 10
+#define ESF_GZ_TX_TSO_HDR_NUM_SEGS_LBN 14
+#define ESF_GZ_TX_TSO_HDR_NUM_SEGS_WIDTH 3
+#define ESF_GZ_TX_TSO_MSS_LBN 0
+#define ESF_GZ_TX_TSO_MSS_WIDTH 14
+#define ESE_GZ_SF_TX_TSO_DSC_FMT_STRUCT_SIZE 124
+
+
+/* Enum DESIGN_PARAMS */
+#define ESE_EF100_DP_GZ_RX_MAX_RUNT 17
+#define ESE_EF100_DP_GZ_VI_STRIDES 16
+#define ESE_EF100_DP_GZ_NMMU_PAGE_SIZES 15
+#define ESE_EF100_DP_GZ_EVQ_TIMER_TICK_NANOS 14
+#define ESE_EF100_DP_GZ_MEM2MEM_MAX_LEN 13
+#define ESE_EF100_DP_GZ_COMPAT 12
+#define ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES 11
+#define ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS 10
+#define ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN 9
+#define ESE_EF100_DP_GZ_TXQ_SIZE_GRANULARITY 8
+#define ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY 7
+#define ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS 6
+#define ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN 5
+#define ESE_EF100_DP_GZ_RX_L4_CSUM_PROTOCOLS 4
+#define ESE_EF100_DP_GZ_NMMU_GROUP_SIZE 3
+#define ESE_EF100_DP_GZ_EVQ_UNSOL_CREDIT_SEQ_BITS 2
+#define ESE_EF100_DP_GZ_PARTIAL_TSTAMP_SUB_NANO_BITS 1
+#define ESE_EF100_DP_GZ_PAD 0
+
+/* Enum DESIGN_PARAM_DEFAULTS */
+#define ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT 0x3fffff
+#define ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES_DEFAULT 8192
+#define ESE_EF100_DP_GZ_MEM2MEM_MAX_LEN_DEFAULT 8192
+#define ESE_EF100_DP_GZ_RX_L4_CSUM_PROTOCOLS_DEFAULT 0x1106
+#define ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT 0x3ff
+#define ESE_EF100_DP_GZ_RX_MAX_RUNT_DEFAULT 640
+#define ESE_EF100_DP_GZ_EVQ_TIMER_TICK_NANOS_DEFAULT 512
+#define ESE_EF100_DP_GZ_NMMU_PAGE_SIZES_DEFAULT 512
+#define ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT 192
+#define ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY_DEFAULT 64
+#define ESE_EF100_DP_GZ_TXQ_SIZE_GRANULARITY_DEFAULT 64
+#define ESE_EF100_DP_GZ_NMMU_GROUP_SIZE_DEFAULT 32
+#define ESE_EF100_DP_GZ_VI_STRIDES_DEFAULT 16
+#define ESE_EF100_DP_GZ_EVQ_UNSOL_CREDIT_SEQ_BITS_DEFAULT 7
+#define ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT 4
+#define ESE_EF100_DP_GZ_PARTIAL_TSTAMP_SUB_NANO_BITS_DEFAULT 2
+#define ESE_EF100_DP_GZ_COMPAT_DEFAULT 0
+
+/* Enum HOST_IF_CONSTANTS */
+#define ESE_GZ_FCW_LEN 0x4C
+#define ESE_GZ_RX_PKT_PREFIX_LEN 22
+
+/* Enum PCI_CONSTANTS */
+#define ESE_GZ_PCI_BASE_CONFIG_SPACE_SIZE 256
+#define ESE_GZ_PCI_EXPRESS_XCAP_HDR_SIZE 4
+
+/* Enum RH_HCLASS_L2_CLASS */
+#define ESE_GZ_RH_HCLASS_L2_CLASS_E2_0123VLAN 1
+#define ESE_GZ_RH_HCLASS_L2_CLASS_OTHER 0
+
+/* Enum RH_HCLASS_L2_STATUS */
+#define ESE_GZ_RH_HCLASS_L2_STATUS_RESERVED 3
+#define ESE_GZ_RH_HCLASS_L2_STATUS_FCS_ERR 2
+#define ESE_GZ_RH_HCLASS_L2_STATUS_LEN_ERR 1
+#define ESE_GZ_RH_HCLASS_L2_STATUS_OK 0
+
+/* Enum RH_HCLASS_L3_CLASS */
+#define ESE_GZ_RH_HCLASS_L3_CLASS_OTHER 3
+#define ESE_GZ_RH_HCLASS_L3_CLASS_IP6 2
+#define ESE_GZ_RH_HCLASS_L3_CLASS_IP4BAD 1
+#define ESE_GZ_RH_HCLASS_L3_CLASS_IP4GOOD 0
+
+/* Enum RH_HCLASS_L4_CLASS */
+#define ESE_GZ_RH_HCLASS_L4_CLASS_OTHER 3
+#define ESE_GZ_RH_HCLASS_L4_CLASS_FRAG 2
+#define ESE_GZ_RH_HCLASS_L4_CLASS_UDP 1
+#define ESE_GZ_RH_HCLASS_L4_CLASS_TCP 0
+
+/* Enum RH_HCLASS_L4_CSUM */
+#define ESE_GZ_RH_HCLASS_L4_CSUM_GOOD 1
+#define ESE_GZ_RH_HCLASS_L4_CSUM_BAD_OR_UNKNOWN 0
+
+/* Enum RH_HCLASS_TUNNEL_CLASS */
+#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_7 7
+#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_6 6
+#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_5 5
+#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_4 4
+#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_GENEVE 3
+#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_NVGRE 2
+#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_VXLAN 1
+#define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_NONE 0
+
+/* Enum TX_DESC_CSO_PARTIAL_EN */
+#define ESE_GZ_TX_DESC_CSO_PARTIAL_EN_TCP 2
+#define ESE_GZ_TX_DESC_CSO_PARTIAL_EN_UDP 1
+#define ESE_GZ_TX_DESC_CSO_PARTIAL_EN_OFF 0
+
+/* Enum TX_DESC_CS_INNER_L3 */
+#define ESE_GZ_TX_DESC_CS_INNER_L3_GENEVE 3
+#define ESE_GZ_TX_DESC_CS_INNER_L3_NVGRE 2
+#define ESE_GZ_TX_DESC_CS_INNER_L3_VXLAN 1
+#define ESE_GZ_TX_DESC_CS_INNER_L3_OFF 0
+
+/* Enum TX_DESC_IP4_ID */
+#define ESE_GZ_TX_DESC_IP4_ID_INC_MOD16 2
+#define ESE_GZ_TX_DESC_IP4_ID_INC_MOD15 1
+#define ESE_GZ_TX_DESC_IP4_ID_NO_OP 0
+/**************************************************************************/
+
+#define ESF_GZ_EV_DEBUG_EVENT_GEN_FLAGS_LBN 44
+#define ESF_GZ_EV_DEBUG_EVENT_GEN_FLAGS_WIDTH 4
+#define ESF_GZ_EV_DEBUG_SRC_QID_LBN 32
+#define ESF_GZ_EV_DEBUG_SRC_QID_WIDTH 12
+#define ESF_GZ_EV_DEBUG_SEQ_NUM_LBN 16
+#define ESF_GZ_EV_DEBUG_SEQ_NUM_WIDTH 16
+
+#endif /* EFX_EF100_REGS_H */
diff --git a/drivers/net/ethernet/sfc/ef100_rx.c b/drivers/net/ethernet/sfc/ef100_rx.c
new file mode 100644
index 000000000000..13ba1a4f66fc
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_rx.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2005-2019 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "net_driver.h"
+#include "ef100_rx.h"
+#include "rx_common.h"
+#include "efx.h"
+#include "nic_common.h"
+#include "mcdi_functions.h"
+#include "ef100_regs.h"
+#include "ef100_nic.h"
+#include "io.h"
+
+/* Get the value of a field in the RX prefix */
+#define PREFIX_OFFSET_W(_f) (ESF_GZ_RX_PREFIX_ ## _f ## _LBN / 32)
+#define PREFIX_OFFSET_B(_f) (ESF_GZ_RX_PREFIX_ ## _f ## _LBN % 32)
+#define PREFIX_WIDTH_MASK(_f) ((1UL << ESF_GZ_RX_PREFIX_ ## _f ## _WIDTH) - 1)
+#define PREFIX_WORD(_p, _f) le32_to_cpu((__force __le32)(_p)[PREFIX_OFFSET_W(_f)])
+#define PREFIX_FIELD(_p, _f) ((PREFIX_WORD(_p, _f) >> PREFIX_OFFSET_B(_f)) & \
+ PREFIX_WIDTH_MASK(_f))
+
+#define ESF_GZ_RX_PREFIX_NT_OR_INNER_L3_CLASS_LBN \
+ (ESF_GZ_RX_PREFIX_CLASS_LBN + ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_LBN)
+#define ESF_GZ_RX_PREFIX_NT_OR_INNER_L3_CLASS_WIDTH \
+ ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_WIDTH
+
+static bool check_fcs(struct efx_channel *channel, u32 *prefix)
+{
+ u16 rxclass;
+ u8 l2status;
+
+ rxclass = le16_to_cpu((__force __le16)PREFIX_FIELD(prefix, CLASS));
+ l2status = PREFIX_FIELD(&rxclass, HCLASS_L2_STATUS);
+
+ if (likely(l2status == ESE_GZ_RH_HCLASS_L2_STATUS_OK))
+ /* Everything is ok */
+ return 0;
+
+ if (l2status == ESE_GZ_RH_HCLASS_L2_STATUS_FCS_ERR)
+ channel->n_rx_eth_crc_err++;
+ return 1;
+}
+
+void __ef100_rx_packet(struct efx_channel *channel)
+{
+ struct efx_rx_buffer *rx_buf = efx_rx_buffer(&channel->rx_queue, channel->rx_pkt_index);
+ struct efx_nic *efx = channel->efx;
+ u8 *eh = efx_rx_buf_va(rx_buf);
+ __wsum csum = 0;
+ u32 *prefix;
+
+ prefix = (u32 *)(eh - ESE_GZ_RX_PKT_PREFIX_LEN);
+
+ if (check_fcs(channel, prefix) &&
+ unlikely(!(efx->net_dev->features & NETIF_F_RXALL)))
+ goto out;
+
+ rx_buf->len = le16_to_cpu((__force __le16)PREFIX_FIELD(prefix, LENGTH));
+ if (rx_buf->len <= sizeof(struct ethhdr)) {
+ if (net_ratelimit())
+ netif_err(channel->efx, rx_err, channel->efx->net_dev,
+ "RX packet too small (%d)\n", rx_buf->len);
+ ++channel->n_rx_frm_trunc;
+ goto out;
+ }
+
+ if (likely(efx->net_dev->features & NETIF_F_RXCSUM)) {
+ if (PREFIX_FIELD(prefix, NT_OR_INNER_L3_CLASS) == 1) {
+ ++channel->n_rx_ip_hdr_chksum_err;
+ } else {
+ u16 sum = be16_to_cpu((__force __be16)PREFIX_FIELD(prefix, CSUM_FRAME));
+
+ csum = (__force __wsum) sum;
+ }
+ }
+
+ if (channel->type->receive_skb) {
+ struct efx_rx_queue *rx_queue =
+ efx_channel_get_rx_queue(channel);
+
+ /* no support for special channels yet, so just discard */
+ WARN_ON_ONCE(1);
+ efx_free_rx_buffers(rx_queue, rx_buf, 1);
+ goto out;
+ }
+
+ efx_rx_packet_gro(channel, rx_buf, channel->rx_pkt_n_frags, eh, csum);
+
+out:
+ channel->rx_pkt_n_frags = 0;
+}
+
+static void ef100_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index)
+{
+ struct efx_rx_buffer *rx_buf = efx_rx_buffer(rx_queue, index);
+ struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
+ struct efx_nic *efx = rx_queue->efx;
+
+ ++rx_queue->rx_packets;
+
+ netif_vdbg(efx, rx_status, efx->net_dev,
+ "RX queue %d received id %x\n",
+ efx_rx_queue_index(rx_queue), index);
+
+ efx_sync_rx_buffer(efx, rx_buf, efx->rx_dma_len);
+
+ prefetch(efx_rx_buf_va(rx_buf));
+
+ rx_buf->page_offset += efx->rx_prefix_size;
+
+ efx_recycle_rx_pages(channel, rx_buf, 1);
+
+ efx_rx_flush_packet(channel);
+ channel->rx_pkt_n_frags = 1;
+ channel->rx_pkt_index = index;
+}
+
+void efx_ef100_ev_rx(struct efx_channel *channel, const efx_qword_t *p_event)
+{
+ struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
+ unsigned int n_packets =
+ EFX_QWORD_FIELD(*p_event, ESF_GZ_EV_RXPKTS_NUM_PKT);
+ int i;
+
+ WARN_ON_ONCE(!n_packets);
+ if (n_packets > 1)
+ ++channel->n_rx_merge_events;
+
+ channel->irq_mod_score += 2 * n_packets;
+
+ for (i = 0; i < n_packets; ++i) {
+ ef100_rx_packet(rx_queue,
+ rx_queue->removed_count & rx_queue->ptr_mask);
+ ++rx_queue->removed_count;
+ }
+}
+
+void ef100_rx_write(struct efx_rx_queue *rx_queue)
+{
+ struct efx_rx_buffer *rx_buf;
+ unsigned int idx;
+ efx_qword_t *rxd;
+ efx_dword_t rxdb;
+
+ while (rx_queue->notified_count != rx_queue->added_count) {
+ idx = rx_queue->notified_count & rx_queue->ptr_mask;
+ rx_buf = efx_rx_buffer(rx_queue, idx);
+ rxd = efx_rx_desc(rx_queue, idx);
+
+ EFX_POPULATE_QWORD_1(*rxd, ESF_GZ_RX_BUF_ADDR, rx_buf->dma_addr);
+
+ ++rx_queue->notified_count;
+ }
+
+ wmb();
+ EFX_POPULATE_DWORD_1(rxdb, ERF_GZ_RX_RING_PIDX,
+ rx_queue->added_count & rx_queue->ptr_mask);
+ efx_writed_page(rx_queue->efx, &rxdb,
+ ER_GZ_RX_RING_DOORBELL, efx_rx_queue_index(rx_queue));
+}
diff --git a/drivers/net/ethernet/sfc/ef100_rx.h b/drivers/net/ethernet/sfc/ef100_rx.h
new file mode 100644
index 000000000000..f2f266863966
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_rx.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2019 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_EF100_RX_H
+#define EFX_EF100_RX_H
+
+#include "net_driver.h"
+
+void efx_ef100_ev_rx(struct efx_channel *channel, const efx_qword_t *p_event);
+void ef100_rx_write(struct efx_rx_queue *rx_queue);
+void __ef100_rx_packet(struct efx_channel *channel);
+
+#endif
diff --git a/drivers/net/ethernet/sfc/ef100_tx.c b/drivers/net/ethernet/sfc/ef100_tx.c
new file mode 100644
index 000000000000..a09546e43408
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_tx.c
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include <net/ip6_checksum.h>
+
+#include "net_driver.h"
+#include "tx_common.h"
+#include "nic_common.h"
+#include "mcdi_functions.h"
+#include "ef100_regs.h"
+#include "io.h"
+#include "ef100_tx.h"
+#include "ef100_nic.h"
+
+int ef100_tx_probe(struct efx_tx_queue *tx_queue)
+{
+ /* Allocate an extra descriptor for the QMDA status completion entry */
+ return efx_nic_alloc_buffer(tx_queue->efx, &tx_queue->txd.buf,
+ (tx_queue->ptr_mask + 2) *
+ sizeof(efx_oword_t),
+ GFP_KERNEL);
+ return 0;
+}
+
+void ef100_tx_init(struct efx_tx_queue *tx_queue)
+{
+ /* must be the inverse of lookup in efx_get_tx_channel */
+ tx_queue->core_txq =
+ netdev_get_tx_queue(tx_queue->efx->net_dev,
+ tx_queue->channel->channel -
+ tx_queue->efx->tx_channel_offset);
+
+ if (efx_mcdi_tx_init(tx_queue, false))
+ netdev_WARN(tx_queue->efx->net_dev,
+ "failed to initialise TXQ %d\n", tx_queue->queue);
+}
+
+static bool ef100_tx_can_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+{
+ struct efx_nic *efx = tx_queue->efx;
+ struct ef100_nic_data *nic_data;
+ struct efx_tx_buffer *buffer;
+ struct tcphdr *tcphdr;
+ struct iphdr *iphdr;
+ size_t header_len;
+ u32 mss;
+
+ nic_data = efx->nic_data;
+
+ if (!skb_is_gso_tcp(skb))
+ return false;
+ if (!(efx->net_dev->features & NETIF_F_TSO))
+ return false;
+
+ mss = skb_shinfo(skb)->gso_size;
+ if (unlikely(mss < 4)) {
+ WARN_ONCE(1, "MSS of %u is too small for TSO\n", mss);
+ return false;
+ }
+
+ header_len = efx_tx_tso_header_length(skb);
+ if (header_len > nic_data->tso_max_hdr_len)
+ return false;
+
+ if (skb_shinfo(skb)->gso_segs > nic_data->tso_max_payload_num_segs) {
+ /* net_dev->gso_max_segs should've caught this */
+ WARN_ON_ONCE(1);
+ return false;
+ }
+
+ if (skb->data_len / mss > nic_data->tso_max_frames)
+ return false;
+
+ /* net_dev->gso_max_size should've caught this */
+ if (WARN_ON_ONCE(skb->data_len > nic_data->tso_max_payload_len))
+ return false;
+
+ /* Reserve an empty buffer for the TSO V3 descriptor.
+ * Convey the length of the header since we already know it.
+ */
+ buffer = efx_tx_queue_get_insert_buffer(tx_queue);
+ buffer->flags = EFX_TX_BUF_TSO_V3 | EFX_TX_BUF_CONT;
+ buffer->len = header_len;
+ buffer->unmap_len = 0;
+ buffer->skb = skb;
+ ++tx_queue->insert_count;
+
+ /* Adjust the TCP checksum to exclude the total length, since we set
+ * ED_INNER_IP_LEN in the descriptor.
+ */
+ tcphdr = tcp_hdr(skb);
+ if (skb_is_gso_v6(skb)) {
+ tcphdr->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
+ } else {
+ iphdr = ip_hdr(skb);
+ tcphdr->check = ~csum_tcpudp_magic(iphdr->saddr, iphdr->daddr,
+ 0, IPPROTO_TCP, 0);
+ }
+ return true;
+}
+
+static efx_oword_t *ef100_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
+{
+ if (likely(tx_queue->txd.buf.addr))
+ return ((efx_oword_t *)tx_queue->txd.buf.addr) + index;
+ else
+ return NULL;
+}
+
+void ef100_notify_tx_desc(struct efx_tx_queue *tx_queue)
+{
+ unsigned int write_ptr;
+ efx_dword_t reg;
+
+ if (unlikely(tx_queue->notify_count == tx_queue->write_count))
+ return;
+
+ write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
+ /* The write pointer goes into the high word */
+ EFX_POPULATE_DWORD_1(reg, ERF_GZ_TX_RING_PIDX, write_ptr);
+ efx_writed_page(tx_queue->efx, &reg,
+ ER_GZ_TX_RING_DOORBELL, tx_queue->queue);
+ tx_queue->notify_count = tx_queue->write_count;
+ tx_queue->xmit_more_available = false;
+}
+
+static void ef100_tx_push_buffers(struct efx_tx_queue *tx_queue)
+{
+ ef100_notify_tx_desc(tx_queue);
+ ++tx_queue->pushes;
+}
+
+static void ef100_set_tx_csum_partial(const struct sk_buff *skb,
+ struct efx_tx_buffer *buffer, efx_oword_t *txd)
+{
+ efx_oword_t csum;
+ int csum_start;
+
+ if (!skb || skb->ip_summed != CHECKSUM_PARTIAL)
+ return;
+
+ /* skb->csum_start has the offset from head, but we need the offset
+ * from data.
+ */
+ csum_start = skb_checksum_start_offset(skb);
+ EFX_POPULATE_OWORD_3(csum,
+ ESF_GZ_TX_SEND_CSO_PARTIAL_EN, 1,
+ ESF_GZ_TX_SEND_CSO_PARTIAL_START_W,
+ csum_start >> 1,
+ ESF_GZ_TX_SEND_CSO_PARTIAL_CSUM_W,
+ skb->csum_offset >> 1);
+ EFX_OR_OWORD(*txd, *txd, csum);
+}
+
+static void ef100_set_tx_hw_vlan(const struct sk_buff *skb, efx_oword_t *txd)
+{
+ u16 vlan_tci = skb_vlan_tag_get(skb);
+ efx_oword_t vlan;
+
+ EFX_POPULATE_OWORD_2(vlan,
+ ESF_GZ_TX_SEND_VLAN_INSERT_EN, 1,
+ ESF_GZ_TX_SEND_VLAN_INSERT_TCI, vlan_tci);
+ EFX_OR_OWORD(*txd, *txd, vlan);
+}
+
+static void ef100_make_send_desc(struct efx_nic *efx,
+ const struct sk_buff *skb,
+ struct efx_tx_buffer *buffer, efx_oword_t *txd,
+ unsigned int segment_count)
+{
+ /* TX send descriptor */
+ EFX_POPULATE_OWORD_3(*txd,
+ ESF_GZ_TX_SEND_NUM_SEGS, segment_count,
+ ESF_GZ_TX_SEND_LEN, buffer->len,
+ ESF_GZ_TX_SEND_ADDR, buffer->dma_addr);
+
+ if (likely(efx->net_dev->features & NETIF_F_HW_CSUM))
+ ef100_set_tx_csum_partial(skb, buffer, txd);
+ if (efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_TX &&
+ skb && skb_vlan_tag_present(skb))
+ ef100_set_tx_hw_vlan(skb, txd);
+}
+
+static void ef100_make_tso_desc(struct efx_nic *efx,
+ const struct sk_buff *skb,
+ struct efx_tx_buffer *buffer, efx_oword_t *txd,
+ unsigned int segment_count)
+{
+ u32 mangleid = (efx->net_dev->features & NETIF_F_TSO_MANGLEID) ||
+ skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID ?
+ ESE_GZ_TX_DESC_IP4_ID_NO_OP :
+ ESE_GZ_TX_DESC_IP4_ID_INC_MOD16;
+ u16 vlan_enable = efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_TX ?
+ skb_vlan_tag_present(skb) : 0;
+ unsigned int len, ip_offset, tcp_offset, payload_segs;
+ u16 vlan_tci = skb_vlan_tag_get(skb);
+ u32 mss = skb_shinfo(skb)->gso_size;
+
+ len = skb->len - buffer->len;
+ /* We use 1 for the TSO descriptor and 1 for the header */
+ payload_segs = segment_count - 2;
+ ip_offset = skb_network_offset(skb);
+ tcp_offset = skb_transport_offset(skb);
+
+ EFX_POPULATE_OWORD_13(*txd,
+ ESF_GZ_TX_DESC_TYPE, ESE_GZ_TX_DESC_TYPE_TSO,
+ ESF_GZ_TX_TSO_MSS, mss,
+ ESF_GZ_TX_TSO_HDR_NUM_SEGS, 1,
+ ESF_GZ_TX_TSO_PAYLOAD_NUM_SEGS, payload_segs,
+ ESF_GZ_TX_TSO_HDR_LEN_W, buffer->len >> 1,
+ ESF_GZ_TX_TSO_PAYLOAD_LEN, len,
+ ESF_GZ_TX_TSO_CSO_INNER_L4, 1,
+ ESF_GZ_TX_TSO_INNER_L3_OFF_W, ip_offset >> 1,
+ ESF_GZ_TX_TSO_INNER_L4_OFF_W, tcp_offset >> 1,
+ ESF_GZ_TX_TSO_ED_INNER_IP4_ID, mangleid,
+ ESF_GZ_TX_TSO_ED_INNER_IP_LEN, 1,
+ ESF_GZ_TX_TSO_VLAN_INSERT_EN, vlan_enable,
+ ESF_GZ_TX_TSO_VLAN_INSERT_TCI, vlan_tci
+ );
+}
+
+static void ef100_tx_make_descriptors(struct efx_tx_queue *tx_queue,
+ const struct sk_buff *skb,
+ unsigned int segment_count)
+{
+ unsigned int old_write_count = tx_queue->write_count;
+ unsigned int new_write_count = old_write_count;
+ struct efx_tx_buffer *buffer;
+ unsigned int next_desc_type;
+ unsigned int write_ptr;
+ efx_oword_t *txd;
+ unsigned int nr_descs = tx_queue->insert_count - old_write_count;
+
+ if (unlikely(nr_descs == 0))
+ return;
+
+ if (segment_count)
+ next_desc_type = ESE_GZ_TX_DESC_TYPE_TSO;
+ else
+ next_desc_type = ESE_GZ_TX_DESC_TYPE_SEND;
+
+ /* if it's a raw write (such as XDP) then always SEND single frames */
+ if (!skb)
+ nr_descs = 1;
+
+ do {
+ write_ptr = new_write_count & tx_queue->ptr_mask;
+ buffer = &tx_queue->buffer[write_ptr];
+ txd = ef100_tx_desc(tx_queue, write_ptr);
+ ++new_write_count;
+
+ /* Create TX descriptor ring entry */
+ tx_queue->packet_write_count = new_write_count;
+
+ switch (next_desc_type) {
+ case ESE_GZ_TX_DESC_TYPE_SEND:
+ ef100_make_send_desc(tx_queue->efx, skb,
+ buffer, txd, nr_descs);
+ break;
+ case ESE_GZ_TX_DESC_TYPE_TSO:
+ /* TX TSO descriptor */
+ WARN_ON_ONCE(!(buffer->flags & EFX_TX_BUF_TSO_V3));
+ ef100_make_tso_desc(tx_queue->efx, skb,
+ buffer, txd, nr_descs);
+ break;
+ default:
+ /* TX segment descriptor */
+ EFX_POPULATE_OWORD_3(*txd,
+ ESF_GZ_TX_DESC_TYPE, ESE_GZ_TX_DESC_TYPE_SEG,
+ ESF_GZ_TX_SEG_LEN, buffer->len,
+ ESF_GZ_TX_SEG_ADDR, buffer->dma_addr);
+ }
+ /* if it's a raw write (such as XDP) then always SEND */
+ next_desc_type = skb ? ESE_GZ_TX_DESC_TYPE_SEG :
+ ESE_GZ_TX_DESC_TYPE_SEND;
+
+ } while (new_write_count != tx_queue->insert_count);
+
+ wmb(); /* Ensure descriptors are written before they are fetched */
+
+ tx_queue->write_count = new_write_count;
+
+ /* The write_count above must be updated before reading
+ * channel->holdoff_doorbell to avoid a race with the
+ * completion path, so ensure these operations are not
+ * re-ordered. This also flushes the update of write_count
+ * back into the cache.
+ */
+ smp_mb();
+}
+
+void ef100_tx_write(struct efx_tx_queue *tx_queue)
+{
+ ef100_tx_make_descriptors(tx_queue, NULL, 0);
+ ef100_tx_push_buffers(tx_queue);
+}
+
+void ef100_ev_tx(struct efx_channel *channel, const efx_qword_t *p_event)
+{
+ unsigned int tx_done =
+ EFX_QWORD_FIELD(*p_event, ESF_GZ_EV_TXCMPL_NUM_DESC);
+ unsigned int qlabel =
+ EFX_QWORD_FIELD(*p_event, ESF_GZ_EV_TXCMPL_Q_LABEL);
+ struct efx_tx_queue *tx_queue =
+ efx_channel_get_tx_queue(channel, qlabel);
+ unsigned int tx_index = (tx_queue->read_count + tx_done - 1) &
+ tx_queue->ptr_mask;
+
+ efx_xmit_done(tx_queue, tx_index);
+}
+
+/* Add a socket buffer to a TX queue
+ *
+ * You must hold netif_tx_lock() to call this function.
+ *
+ * Returns 0 on success, error code otherwise. In case of an error this
+ * function will free the SKB.
+ */
+int ef100_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+{
+ unsigned int old_insert_count = tx_queue->insert_count;
+ struct efx_nic *efx = tx_queue->efx;
+ bool xmit_more = netdev_xmit_more();
+ unsigned int fill_level;
+ unsigned int segments;
+ int rc;
+
+ if (!tx_queue->buffer || !tx_queue->ptr_mask) {
+ netif_stop_queue(efx->net_dev);
+ dev_kfree_skb_any(skb);
+ return -ENODEV;
+ }
+
+ segments = skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 0;
+ if (segments == 1)
+ segments = 0; /* Don't use TSO/GSO for a single segment. */
+ if (segments && !ef100_tx_can_tso(tx_queue, skb)) {
+ rc = efx_tx_tso_fallback(tx_queue, skb);
+ tx_queue->tso_fallbacks++;
+ if (rc)
+ goto err;
+ else
+ return 0;
+ }
+
+ /* Map for DMA and create descriptors */
+ rc = efx_tx_map_data(tx_queue, skb, segments);
+ if (rc)
+ goto err;
+ ef100_tx_make_descriptors(tx_queue, skb, segments);
+
+ fill_level = efx_channel_tx_fill_level(tx_queue->channel);
+ if (fill_level > efx->txq_stop_thresh) {
+ netif_tx_stop_queue(tx_queue->core_txq);
+ /* Re-read after a memory barrier in case we've raced with
+ * the completion path. Otherwise there's a danger we'll never
+ * restart the queue if all completions have just happened.
+ */
+ smp_mb();
+ fill_level = efx_channel_tx_fill_level(tx_queue->channel);
+ if (fill_level < efx->txq_stop_thresh)
+ netif_tx_start_queue(tx_queue->core_txq);
+ }
+
+ if (__netdev_tx_sent_queue(tx_queue->core_txq, skb->len, xmit_more))
+ tx_queue->xmit_more_available = false; /* push doorbell */
+ else if (tx_queue->write_count - tx_queue->notify_count > 255)
+ /* Ensure we never push more than 256 packets at once */
+ tx_queue->xmit_more_available = false; /* push */
+ else
+ tx_queue->xmit_more_available = true; /* don't push yet */
+
+ if (!tx_queue->xmit_more_available)
+ ef100_tx_push_buffers(tx_queue);
+
+ if (segments) {
+ tx_queue->tso_bursts++;
+ tx_queue->tso_packets += segments;
+ tx_queue->tx_packets += segments;
+ } else {
+ tx_queue->tx_packets++;
+ }
+ return 0;
+
+err:
+ efx_enqueue_unwind(tx_queue, old_insert_count);
+ if (!IS_ERR_OR_NULL(skb))
+ dev_kfree_skb_any(skb);
+
+ /* If we're not expecting another transmit and we had something to push
+ * on this queue then we need to push here to get the previous packets
+ * out. We only enter this branch from before the 'Update BQL' section
+ * above, so xmit_more_available still refers to the old state.
+ */
+ if (tx_queue->xmit_more_available && !xmit_more)
+ ef100_tx_push_buffers(tx_queue);
+ return rc;
+}
diff --git a/drivers/net/ethernet/sfc/ef100_tx.h b/drivers/net/ethernet/sfc/ef100_tx.h
new file mode 100644
index 000000000000..fa23e430bdd7
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_tx.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2019 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_EF100_TX_H
+#define EFX_EF100_TX_H
+
+#include "net_driver.h"
+
+int ef100_tx_probe(struct efx_tx_queue *tx_queue);
+void ef100_tx_init(struct efx_tx_queue *tx_queue);
+void ef100_tx_write(struct efx_tx_queue *tx_queue);
+void ef100_notify_tx_desc(struct efx_tx_queue *tx_queue);
+unsigned int ef100_tx_max_skb_descs(struct efx_nic *efx);
+
+void ef100_ev_tx(struct efx_channel *channel, const efx_qword_t *p_event);
+
+netdev_tx_t ef100_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
+#endif
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 256807c28ff7..e06fa89f2d72 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -25,6 +25,7 @@
#include "efx.h"
#include "efx_common.h"
#include "efx_channels.h"
+#include "ef100.h"
#include "rx_common.h"
#include "tx_common.h"
#include "nic.h"
@@ -38,32 +39,17 @@
/**************************************************************************
*
- * Type name strings
- *
- **************************************************************************
- */
-
-/* UDP tunnel type names */
-static const char *const efx_udp_tunnel_type_names[] = {
- [TUNNEL_ENCAP_UDP_PORT_ENTRY_VXLAN] = "vxlan",
- [TUNNEL_ENCAP_UDP_PORT_ENTRY_GENEVE] = "geneve",
-};
-
-void efx_get_udp_tunnel_type_name(u16 type, char *buf, size_t buflen)
-{
- if (type < ARRAY_SIZE(efx_udp_tunnel_type_names) &&
- efx_udp_tunnel_type_names[type] != NULL)
- snprintf(buf, buflen, "%s", efx_udp_tunnel_type_names[type]);
- else
- snprintf(buf, buflen, "type %d", type);
-}
-
-/**************************************************************************
- *
* Configurable values
*
*************************************************************************/
+module_param_named(interrupt_mode, efx_interrupt_mode, uint, 0444);
+MODULE_PARM_DESC(interrupt_mode,
+ "Interrupt mode (0=>MSIX 1=>MSI 2=>legacy)");
+
+module_param(rss_cpus, uint, 0444);
+MODULE_PARM_DESC(rss_cpus, "Number of CPUs to use for Receive-Side Scaling");
+
/*
* Use separate channels for TX and RX events
*
@@ -133,30 +119,6 @@ static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs,
*
**************************************************************************/
-/* Equivalent to efx_link_set_advertising with all-zeroes, except does not
- * force the Autoneg bit on.
- */
-void efx_link_clear_advertising(struct efx_nic *efx)
-{
- bitmap_zero(efx->link_advertising, __ETHTOOL_LINK_MODE_MASK_NBITS);
- efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
-}
-
-void efx_link_set_wanted_fc(struct efx_nic *efx, u8 wanted_fc)
-{
- efx->wanted_fc = wanted_fc;
- if (efx->link_advertising[0]) {
- if (wanted_fc & EFX_FC_RX)
- efx->link_advertising[0] |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- else
- efx->link_advertising[0] &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- if (wanted_fc & EFX_FC_TX)
- efx->link_advertising[0] ^= ADVERTISED_Asym_Pause;
- }
-}
-
static void efx_fini_port(struct efx_nic *efx);
static int efx_probe_port(struct efx_nic *efx)
@@ -193,10 +155,6 @@ static int efx_init_port(struct efx_nic *efx)
efx->port_initialized = true;
- /* Reconfigure the MAC before creating dma queues (required for
- * Falcon/A1 where RX_INGR_EN/TX_DRAIN_EN isn't supported) */
- efx_mac_reconfigure(efx);
-
/* Ensure the PHY advertises the correct flow control settings */
rc = efx->phy_op->reconfigure(efx);
if (rc && rc != -EPERM)
@@ -357,9 +315,6 @@ static int efx_probe_nic(struct efx_nic *efx)
sizeof(efx->rss_context.rx_hash_key));
efx_set_default_rx_indir_table(efx, &efx->rss_context);
- netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
- netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels);
-
/* Initialise the interrupt moderation settings */
efx->irq_mod_step_us = DIV_ROUND_UP(efx->timer_quantum_ns, 1000);
efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true,
@@ -409,7 +364,6 @@ static int efx_probe_all(struct efx_nic *efx)
rc = -EINVAL;
goto fail3;
}
- efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
#ifdef CONFIG_SFC_SRIOV
rc = efx->type->vswitching_probe(efx);
@@ -617,109 +571,6 @@ int efx_net_stop(struct net_device *net_dev)
return 0;
}
-/* Context: netif_tx_lock held, BHs disabled. */
-static void efx_watchdog(struct net_device *net_dev, unsigned int txqueue)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- netif_err(efx, tx_err, efx->net_dev,
- "TX stuck with port_enabled=%d: resetting channels\n",
- efx->port_enabled);
-
- efx_schedule_reset(efx, RESET_TYPE_TX_WATCHDOG);
-}
-
-static int efx_set_mac_address(struct net_device *net_dev, void *data)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- struct sockaddr *addr = data;
- u8 *new_addr = addr->sa_data;
- u8 old_addr[6];
- int rc;
-
- if (!is_valid_ether_addr(new_addr)) {
- netif_err(efx, drv, efx->net_dev,
- "invalid ethernet MAC address requested: %pM\n",
- new_addr);
- return -EADDRNOTAVAIL;
- }
-
- /* save old address */
- ether_addr_copy(old_addr, net_dev->dev_addr);
- ether_addr_copy(net_dev->dev_addr, new_addr);
- if (efx->type->set_mac_address) {
- rc = efx->type->set_mac_address(efx);
- if (rc) {
- ether_addr_copy(net_dev->dev_addr, old_addr);
- return rc;
- }
- }
-
- /* Reconfigure the MAC */
- mutex_lock(&efx->mac_lock);
- efx_mac_reconfigure(efx);
- mutex_unlock(&efx->mac_lock);
-
- return 0;
-}
-
-/* Context: netif_addr_lock held, BHs disabled. */
-static void efx_set_rx_mode(struct net_device *net_dev)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- if (efx->port_enabled)
- queue_work(efx->workqueue, &efx->mac_work);
- /* Otherwise efx_start_port() will do this */
-}
-
-static int efx_set_features(struct net_device *net_dev, netdev_features_t data)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- int rc;
-
- /* If disabling RX n-tuple filtering, clear existing filters */
- if (net_dev->features & ~data & NETIF_F_NTUPLE) {
- rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
- if (rc)
- return rc;
- }
-
- /* If Rx VLAN filter is changed, update filters via mac_reconfigure.
- * If rx-fcs is changed, mac_reconfigure updates that too.
- */
- if ((net_dev->features ^ data) & (NETIF_F_HW_VLAN_CTAG_FILTER |
- NETIF_F_RXFCS)) {
- /* efx_set_rx_mode() will schedule MAC work to update filters
- * when a new features are finally set in net_dev.
- */
- efx_set_rx_mode(net_dev);
- }
-
- return 0;
-}
-
-static int efx_get_phys_port_id(struct net_device *net_dev,
- struct netdev_phys_item_id *ppid)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- if (efx->type->get_phys_port_id)
- return efx->type->get_phys_port_id(efx, ppid);
- else
- return -EOPNOTSUPP;
-}
-
-static int efx_get_phys_port_name(struct net_device *net_dev,
- char *name, size_t len)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- if (snprintf(name, len, "p%u", efx->port_num) >= len)
- return -EINVAL;
- return 0;
-}
-
static int efx_vlan_rx_add_vid(struct net_device *net_dev, __be16 proto, u16 vid)
{
struct efx_nic *efx = netdev_priv(net_dev);
@@ -740,52 +591,6 @@ static int efx_vlan_rx_kill_vid(struct net_device *net_dev, __be16 proto, u16 vi
return -EOPNOTSUPP;
}
-static int efx_udp_tunnel_type_map(enum udp_parsable_tunnel_type in)
-{
- switch (in) {
- case UDP_TUNNEL_TYPE_VXLAN:
- return TUNNEL_ENCAP_UDP_PORT_ENTRY_VXLAN;
- case UDP_TUNNEL_TYPE_GENEVE:
- return TUNNEL_ENCAP_UDP_PORT_ENTRY_GENEVE;
- default:
- return -1;
- }
-}
-
-static void efx_udp_tunnel_add(struct net_device *dev, struct udp_tunnel_info *ti)
-{
- struct efx_nic *efx = netdev_priv(dev);
- struct efx_udp_tunnel tnl;
- int efx_tunnel_type;
-
- efx_tunnel_type = efx_udp_tunnel_type_map(ti->type);
- if (efx_tunnel_type < 0)
- return;
-
- tnl.type = (u16)efx_tunnel_type;
- tnl.port = ti->port;
-
- if (efx->type->udp_tnl_add_port)
- (void)efx->type->udp_tnl_add_port(efx, tnl);
-}
-
-static void efx_udp_tunnel_del(struct net_device *dev, struct udp_tunnel_info *ti)
-{
- struct efx_nic *efx = netdev_priv(dev);
- struct efx_udp_tunnel tnl;
- int efx_tunnel_type;
-
- efx_tunnel_type = efx_udp_tunnel_type_map(ti->type);
- if (efx_tunnel_type < 0)
- return;
-
- tnl.type = (u16)efx_tunnel_type;
- tnl.port = ti->port;
-
- if (efx->type->udp_tnl_del_port)
- (void)efx->type->udp_tnl_del_port(efx, tnl);
-}
-
static const struct net_device_ops efx_netdev_ops = {
.ndo_open = efx_net_open,
.ndo_stop = efx_net_stop,
@@ -813,8 +618,8 @@ static const struct net_device_ops efx_netdev_ops = {
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = efx_filter_rfs,
#endif
- .ndo_udp_tunnel_add = efx_udp_tunnel_add,
- .ndo_udp_tunnel_del = efx_udp_tunnel_del,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_xdp_xmit = efx_xdp_xmit,
.ndo_bpf = efx_xdp
};
@@ -849,15 +654,10 @@ static int efx_xdp_setup_prog(struct efx_nic *efx, struct bpf_prog *prog)
static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
struct efx_nic *efx = netdev_priv(dev);
- struct bpf_prog *xdp_prog;
switch (xdp->command) {
case XDP_SETUP_PROG:
return efx_xdp_setup_prog(efx, xdp->prog);
- case XDP_QUERY_PROG:
- xdp_prog = rtnl_dereference(efx->xdp_prog);
- xdp->prog_id = xdp_prog ? xdp_prog->aux->id : 0;
- return 0;
default:
return -EINVAL;
}
@@ -1098,7 +898,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
efx_pci_remove_main(efx);
- efx_fini_io(efx, efx->type->mem_bar(efx));
+ efx_fini_io(efx);
netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n");
efx_fini_struct(efx);
@@ -1366,7 +1166,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
return 0;
fail3:
- efx_fini_io(efx, efx->type->mem_bar(efx));
+ efx_fini_io(efx);
fail2:
efx_fini_struct(efx);
fail1:
@@ -1514,97 +1314,6 @@ static const struct dev_pm_ops efx_pm_ops = {
.restore = efx_pm_resume,
};
-/* A PCI error affecting this device was detected.
- * At this point MMIO and DMA may be disabled.
- * Stop the software path and request a slot reset.
- */
-static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev,
- enum pci_channel_state state)
-{
- pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
- struct efx_nic *efx = pci_get_drvdata(pdev);
-
- if (state == pci_channel_io_perm_failure)
- return PCI_ERS_RESULT_DISCONNECT;
-
- rtnl_lock();
-
- if (efx->state != STATE_DISABLED) {
- efx->state = STATE_RECOVERY;
- efx->reset_pending = 0;
-
- efx_device_detach_sync(efx);
-
- efx_stop_all(efx);
- efx_disable_interrupts(efx);
-
- status = PCI_ERS_RESULT_NEED_RESET;
- } else {
- /* If the interface is disabled we don't want to do anything
- * with it.
- */
- status = PCI_ERS_RESULT_RECOVERED;
- }
-
- rtnl_unlock();
-
- pci_disable_device(pdev);
-
- return status;
-}
-
-/* Fake a successful reset, which will be performed later in efx_io_resume. */
-static pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev)
-{
- struct efx_nic *efx = pci_get_drvdata(pdev);
- pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
-
- if (pci_enable_device(pdev)) {
- netif_err(efx, hw, efx->net_dev,
- "Cannot re-enable PCI device after reset.\n");
- status = PCI_ERS_RESULT_DISCONNECT;
- }
-
- return status;
-}
-
-/* Perform the actual reset and resume I/O operations. */
-static void efx_io_resume(struct pci_dev *pdev)
-{
- struct efx_nic *efx = pci_get_drvdata(pdev);
- int rc;
-
- rtnl_lock();
-
- if (efx->state == STATE_DISABLED)
- goto out;
-
- rc = efx_reset(efx, RESET_TYPE_ALL);
- if (rc) {
- netif_err(efx, hw, efx->net_dev,
- "efx_reset failed after PCI error (%d)\n", rc);
- } else {
- efx->state = STATE_READY;
- netif_dbg(efx, hw, efx->net_dev,
- "Done resetting and resuming IO after PCI error.\n");
- }
-
-out:
- rtnl_unlock();
-}
-
-/* For simplicity and reliability, we always require a slot reset and try to
- * reset the hardware when a pci error affecting the device is detected.
- * We leave both the link_reset and mmio_enabled callback unimplemented:
- * with our request for slot reset the mmio_enabled callback will never be
- * called, and the link_reset callback is not used by AER or EEH mechanisms.
- */
-static const struct pci_error_handlers efx_err_handlers = {
- .error_detected = efx_io_error_detected,
- .slot_reset = efx_io_slot_reset,
- .resume = efx_io_resume,
-};
-
static struct pci_driver efx_pci_driver = {
.name = KBUILD_MODNAME,
.id_table = efx_pci_table,
@@ -1647,8 +1356,14 @@ static int __init efx_init_module(void)
if (rc < 0)
goto err_pci;
+ rc = pci_register_driver(&ef100_pci_driver);
+ if (rc < 0)
+ goto err_pci_ef100;
+
return 0;
+ err_pci_ef100:
+ pci_unregister_driver(&efx_pci_driver);
err_pci:
efx_destroy_reset_workqueue();
err_reset:
@@ -1665,6 +1380,7 @@ static void __exit efx_exit_module(void)
{
printk(KERN_INFO "Solarflare NET driver unloading\n");
+ pci_unregister_driver(&ef100_pci_driver);
pci_unregister_driver(&efx_pci_driver);
efx_destroy_reset_workqueue();
#ifdef CONFIG_SFC_SRIOV
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 66dcab140449..a9808e86068d 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -8,7 +8,10 @@
#ifndef EFX_EFX_H
#define EFX_EFX_H
+#include <linux/indirect_call_wrapper.h>
#include "net_driver.h"
+#include "ef100_rx.h"
+#include "ef100_tx.h"
#include "filter.h"
int efx_net_open(struct net_device *net_dev);
@@ -18,13 +21,18 @@ int efx_net_stop(struct net_device *net_dev);
void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue);
netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
struct net_device *net_dev);
-netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
+netdev_tx_t __efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
+static inline netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+{
+ return INDIRECT_CALL_2(tx_queue->efx->type->tx_enqueue,
+ ef100_enqueue_skb, __efx_enqueue_skb,
+ tx_queue, skb);
+}
void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
void efx_xmit_done_single(struct efx_tx_queue *tx_queue);
int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
void *type_data);
extern unsigned int efx_piobuf_size;
-extern bool efx_separate_tx_channels;
/* RX */
void __efx_rx_packet(struct efx_channel *channel);
@@ -33,16 +41,11 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
static inline void efx_rx_flush_packet(struct efx_channel *channel)
{
if (channel->rx_pkt_n_frags)
- __efx_rx_packet(channel);
+ INDIRECT_CALL_2(channel->efx->type->rx_packet,
+ __ef100_rx_packet, __efx_rx_packet,
+ channel);
}
-#define EFX_MAX_DMAQ_SIZE 4096UL
-#define EFX_DEFAULT_DMAQ_SIZE 1024UL
-#define EFX_MIN_DMAQ_SIZE 512UL
-
-#define EFX_MAX_EVQ_SIZE 16384UL
-#define EFX_MIN_EVQ_SIZE 512UL
-
/* Maximum number of TCP segments we support for soft-TSO */
#define EFX_TSO_MAX_SEGS 100
@@ -147,11 +150,6 @@ static inline s32 efx_filter_get_rx_ids(struct efx_nic *efx,
{
return efx->type->filter_get_rx_ids(efx, priority, buf, size);
}
-#ifdef CONFIG_RFS_ACCEL
-int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
- u16 rxq_index, u32 flow_id);
-bool __efx_filter_rfs_expire(struct efx_channel *channel, unsigned int quota);
-#endif
/* RSS contexts */
static inline bool efx_rss_active(struct efx_rss_context *ctx)
@@ -171,10 +169,6 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
unsigned int *rx_usecs, bool *rx_adaptive);
-/* Dummy PHY ops for PHY drivers */
-int efx_port_dummy_op_int(struct efx_nic *efx);
-void efx_port_dummy_op_void(struct efx_nic *efx);
-
/* Update the generic software stats in the passed stats array */
void efx_update_sw_stats(struct efx_nic *efx, u64 *stats);
@@ -201,24 +195,6 @@ static inline unsigned int efx_vf_size(struct efx_nic *efx)
}
#endif
-static inline void efx_schedule_channel(struct efx_channel *channel)
-{
- netif_vdbg(channel->efx, intr, channel->efx->net_dev,
- "channel %d scheduling NAPI poll on CPU%d\n",
- channel->channel, raw_smp_processor_id());
-
- napi_schedule(&channel->napi_str);
-}
-
-static inline void efx_schedule_channel_irq(struct efx_channel *channel)
-{
- channel->event_test_cpu = raw_smp_processor_id();
- efx_schedule_channel(channel);
-}
-
-void efx_link_clear_advertising(struct efx_nic *efx);
-void efx_link_set_wanted_fc(struct efx_nic *efx, u8);
-
static inline void efx_device_detach_sync(struct efx_nic *efx)
{
struct net_device *dev = efx->net_dev;
diff --git a/drivers/net/ethernet/sfc/efx_channels.c b/drivers/net/ethernet/sfc/efx_channels.c
index c492523b986c..dd4f30ea48a8 100644
--- a/drivers/net/ethernet/sfc/efx_channels.c
+++ b/drivers/net/ethernet/sfc/efx_channels.c
@@ -23,10 +23,7 @@
* 1 => MSI
* 2 => legacy
*/
-static unsigned int interrupt_mode;
-module_param(interrupt_mode, uint, 0444);
-MODULE_PARM_DESC(interrupt_mode,
- "Interrupt mode (0=>MSIX 1=>MSI 2=>legacy)");
+unsigned int efx_interrupt_mode = EFX_INT_MODE_MSIX;
/* This is the requested number of CPUs to use for Receive-Side Scaling (RSS),
* i.e. the number of CPUs among which we may distribute simultaneous
@@ -35,9 +32,7 @@ MODULE_PARM_DESC(interrupt_mode,
* Cards without MSI-X will only target one CPU via legacy or MSI interrupt.
* The default (0) means to assign an interrupt to each core.
*/
-static unsigned int rss_cpus;
-module_param(rss_cpus, uint, 0444);
-MODULE_PARM_DESC(rss_cpus, "Number of CPUs to use for Receive-Side Scaling");
+unsigned int rss_cpus;
static unsigned int irq_adapt_low_thresh = 8000;
module_param(irq_adapt_low_thresh, uint, 0644);
@@ -175,6 +170,13 @@ static int efx_allocate_msix_channels(struct efx_nic *efx,
efx->n_xdp_channels = 0;
efx->xdp_tx_per_channel = 0;
efx->xdp_tx_queue_count = 0;
+ } else if (n_channels + n_xdp_tx > efx->max_vis) {
+ netif_err(efx, drv, efx->net_dev,
+ "Insufficient resources for %d XDP TX queues (%d other channels, max VIs %d)\n",
+ n_xdp_tx, n_channels, efx->max_vis);
+ efx->n_xdp_channels = 0;
+ efx->xdp_tx_per_channel = 0;
+ efx->xdp_tx_queue_count = 0;
} else {
efx->n_xdp_channels = n_xdp_ev;
efx->xdp_tx_per_channel = EFX_TXQ_TYPES;
@@ -522,7 +524,8 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
for (j = 0; j < EFX_TXQ_TYPES; j++) {
tx_queue = &channel->tx_queue[j];
tx_queue->efx = efx;
- tx_queue->queue = i * EFX_TXQ_TYPES + j;
+ tx_queue->queue = -1;
+ tx_queue->label = j;
tx_queue->channel = channel;
}
@@ -550,14 +553,11 @@ int efx_init_channels(struct efx_nic *efx)
}
/* Higher numbered interrupt modes are less capable! */
- if (WARN_ON_ONCE(efx->type->max_interrupt_mode >
- efx->type->min_interrupt_mode)) {
- return -EIO;
- }
- efx->interrupt_mode = max(efx->type->max_interrupt_mode,
- interrupt_mode);
efx->interrupt_mode = min(efx->type->min_interrupt_mode,
- interrupt_mode);
+ efx_interrupt_mode);
+
+ efx->max_channels = EFX_MAX_CHANNELS;
+ efx->max_tx_channels = EFX_MAX_CHANNELS;
return 0;
}
@@ -727,7 +727,7 @@ void efx_remove_channel(struct efx_channel *channel)
efx_for_each_channel_rx_queue(rx_queue, channel)
efx_remove_rx_queue(rx_queue);
- efx_for_each_possible_channel_tx_queue(tx_queue, channel)
+ efx_for_each_channel_tx_queue(tx_queue, channel)
efx_remove_tx_queue(tx_queue);
efx_remove_eventq(channel);
channel->type->post_remove(channel);
@@ -854,9 +854,11 @@ rollback:
int efx_set_channels(struct efx_nic *efx)
{
- struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
+ struct efx_channel *channel;
+ unsigned int next_queue = 0;
int xdp_queue_number;
+ int rc;
efx->tx_channel_offset =
efx_separate_tx_channels ?
@@ -884,18 +886,38 @@ int efx_set_channels(struct efx_nic *efx)
else
channel->rx_queue.core_index = -1;
- efx_for_each_channel_tx_queue(tx_queue, channel) {
- tx_queue->queue -= (efx->tx_channel_offset *
- EFX_TXQ_TYPES);
-
- if (efx_channel_is_xdp_tx(channel) &&
- xdp_queue_number < efx->xdp_tx_queue_count) {
- efx->xdp_tx_queues[xdp_queue_number] = tx_queue;
- xdp_queue_number++;
+ if (channel->channel >= efx->tx_channel_offset) {
+ if (efx_channel_is_xdp_tx(channel)) {
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
+ tx_queue->queue = next_queue++;
+ netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is XDP %u, HW %u\n",
+ channel->channel, tx_queue->label,
+ xdp_queue_number, tx_queue->queue);
+ /* We may have a few left-over XDP TX
+ * queues owing to xdp_tx_queue_count
+ * not dividing evenly by EFX_TXQ_TYPES.
+ * We still allocate and probe those
+ * TXQs, but never use them.
+ */
+ if (xdp_queue_number < efx->xdp_tx_queue_count)
+ efx->xdp_tx_queues[xdp_queue_number] = tx_queue;
+ xdp_queue_number++;
+ }
+ } else {
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
+ tx_queue->queue = next_queue++;
+ netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is HW %u\n",
+ channel->channel, tx_queue->label,
+ tx_queue->queue);
+ }
}
}
}
- return 0;
+
+ rc = netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
+ if (rc)
+ return rc;
+ return netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels);
}
bool efx_default_channel_want_txqs(struct efx_channel *channel)
@@ -1091,7 +1113,7 @@ void efx_stop_channels(struct efx_nic *efx)
efx_for_each_channel(channel, efx) {
efx_for_each_channel_rx_queue(rx_queue, channel)
efx_fini_rx_queue(rx_queue);
- efx_for_each_possible_channel_tx_queue(tx_queue, channel)
+ efx_for_each_channel_tx_queue(tx_queue, channel)
efx_fini_tx_queue(tx_queue);
}
}
diff --git a/drivers/net/ethernet/sfc/efx_channels.h b/drivers/net/ethernet/sfc/efx_channels.h
index 8d7b8c4142d7..2d71dc9a33dd 100644
--- a/drivers/net/ethernet/sfc/efx_channels.h
+++ b/drivers/net/ethernet/sfc/efx_channels.h
@@ -11,6 +11,9 @@
#ifndef EFX_CHANNELS_H
#define EFX_CHANNELS_H
+extern unsigned int efx_interrupt_mode;
+extern unsigned int rss_cpus;
+
int efx_probe_interrupts(struct efx_nic *efx);
void efx_remove_interrupts(struct efx_nic *efx);
int efx_soft_enable_interrupts(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 1799ff9a45d9..26b05ec4e712 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -139,11 +139,11 @@ void efx_destroy_reset_workqueue(void)
/* We assume that efx->type->reconfigure_mac will always try to sync RX
* filters and therefore needs to read-lock the filter table against freeing
*/
-void efx_mac_reconfigure(struct efx_nic *efx)
+void efx_mac_reconfigure(struct efx_nic *efx, bool mtu_only)
{
if (efx->type->reconfigure_mac) {
down_read(&efx->filter_sem);
- efx->type->reconfigure_mac(efx);
+ efx->type->reconfigure_mac(efx, mtu_only);
up_read(&efx->filter_sem);
}
}
@@ -158,10 +158,80 @@ static void efx_mac_work(struct work_struct *data)
mutex_lock(&efx->mac_lock);
if (efx->port_enabled)
- efx_mac_reconfigure(efx);
+ efx_mac_reconfigure(efx, false);
mutex_unlock(&efx->mac_lock);
}
+int efx_set_mac_address(struct net_device *net_dev, void *data)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct sockaddr *addr = data;
+ u8 *new_addr = addr->sa_data;
+ u8 old_addr[6];
+ int rc;
+
+ if (!is_valid_ether_addr(new_addr)) {
+ netif_err(efx, drv, efx->net_dev,
+ "invalid ethernet MAC address requested: %pM\n",
+ new_addr);
+ return -EADDRNOTAVAIL;
+ }
+
+ /* save old address */
+ ether_addr_copy(old_addr, net_dev->dev_addr);
+ ether_addr_copy(net_dev->dev_addr, new_addr);
+ if (efx->type->set_mac_address) {
+ rc = efx->type->set_mac_address(efx);
+ if (rc) {
+ ether_addr_copy(net_dev->dev_addr, old_addr);
+ return rc;
+ }
+ }
+
+ /* Reconfigure the MAC */
+ mutex_lock(&efx->mac_lock);
+ efx_mac_reconfigure(efx, false);
+ mutex_unlock(&efx->mac_lock);
+
+ return 0;
+}
+
+/* Context: netif_addr_lock held, BHs disabled. */
+void efx_set_rx_mode(struct net_device *net_dev)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ if (efx->port_enabled)
+ queue_work(efx->workqueue, &efx->mac_work);
+ /* Otherwise efx_start_port() will do this */
+}
+
+int efx_set_features(struct net_device *net_dev, netdev_features_t data)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int rc;
+
+ /* If disabling RX n-tuple filtering, clear existing filters */
+ if (net_dev->features & ~data & NETIF_F_NTUPLE) {
+ rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
+ if (rc)
+ return rc;
+ }
+
+ /* If Rx VLAN filter is changed, update filters via mac_reconfigure.
+ * If rx-fcs is changed, mac_reconfigure updates that too.
+ */
+ if ((net_dev->features ^ data) & (NETIF_F_HW_VLAN_CTAG_FILTER |
+ NETIF_F_RXFCS)) {
+ /* efx_set_rx_mode() will schedule MAC work to update filters
+ * when a new features are finally set in net_dev.
+ */
+ efx_set_rx_mode(net_dev);
+ }
+
+ return 0;
+}
+
/* This ensures that the kernel is kept informed (via
* netif_carrier_on/off) of the link status, and also maintains the
* link status's stop on the port's TX queue.
@@ -234,7 +304,7 @@ int efx_change_mtu(struct net_device *net_dev, int new_mtu)
mutex_lock(&efx->mac_lock);
net_dev->mtu = new_mtu;
- efx_mac_reconfigure(efx);
+ efx_mac_reconfigure(efx, true);
mutex_unlock(&efx->mac_lock);
efx_start_all(efx);
@@ -383,6 +453,30 @@ static void efx_stop_datapath(struct efx_nic *efx)
*
**************************************************************************/
+/* Equivalent to efx_link_set_advertising with all-zeroes, except does not
+ * force the Autoneg bit on.
+ */
+void efx_link_clear_advertising(struct efx_nic *efx)
+{
+ bitmap_zero(efx->link_advertising, __ETHTOOL_LINK_MODE_MASK_NBITS);
+ efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
+}
+
+void efx_link_set_wanted_fc(struct efx_nic *efx, u8 wanted_fc)
+{
+ efx->wanted_fc = wanted_fc;
+ if (efx->link_advertising[0]) {
+ if (wanted_fc & EFX_FC_RX)
+ efx->link_advertising[0] |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ else
+ efx->link_advertising[0] &= ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ if (wanted_fc & EFX_FC_TX)
+ efx->link_advertising[0] ^= ADVERTISED_Asym_Pause;
+ }
+}
+
static void efx_start_port(struct efx_nic *efx)
{
netif_dbg(efx, ifup, efx->net_dev, "start port\n");
@@ -392,7 +486,7 @@ static void efx_start_port(struct efx_nic *efx)
efx->port_enabled = true;
/* Ensure MAC ingress/egress is enabled */
- efx_mac_reconfigure(efx);
+ efx_mac_reconfigure(efx, false);
mutex_unlock(&efx->mac_lock);
}
@@ -626,6 +720,18 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method)
efx->type->fini(efx);
}
+/* Context: netif_tx_lock held, BHs disabled. */
+void efx_watchdog(struct net_device *net_dev, unsigned int txqueue)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ netif_err(efx, tx_err, efx->net_dev,
+ "TX stuck with port_enabled=%d: resetting channels\n",
+ efx->port_enabled);
+
+ efx_schedule_reset(efx, RESET_TYPE_TX_WATCHDOG);
+}
+
/* This function will always ensure that the locks acquired in
* efx_reset_down() are released. A failure return code indicates
* that we were unable to reinitialise the hardware, and the
@@ -708,14 +814,18 @@ fail:
*/
int efx_reset(struct efx_nic *efx, enum reset_type method)
{
+ int rc, rc2 = 0;
bool disabled;
- int rc, rc2;
netif_info(efx, drv, efx->net_dev, "resetting (%s)\n",
RESET_TYPE(method));
efx_device_detach_sync(efx);
- efx_reset_down(efx, method);
+ /* efx_reset_down() grabs locks that prevent recovery on EF100.
+ * EF100 reset is handled in the efx_nic_type callback below.
+ */
+ if (efx_nic_rev(efx) != EFX_REV_EF100)
+ efx_reset_down(efx, method);
rc = efx->type->reset(efx, method);
if (rc) {
@@ -743,7 +853,8 @@ out:
disabled = rc ||
method == RESET_TYPE_DISABLE ||
method == RESET_TYPE_RECOVER_OR_DISABLE;
- rc2 = efx_reset_up(efx, method, !disabled);
+ if (efx_nic_rev(efx) != EFX_REV_EF100)
+ rc2 = efx_reset_up(efx, method, !disabled);
if (rc2) {
disabled = true;
if (!rc)
@@ -911,7 +1022,9 @@ int efx_init_struct(struct efx_nic *efx,
efx->rx_packet_ts_offset =
efx->type->rx_ts_offset - efx->type->rx_prefix_size;
INIT_LIST_HEAD(&efx->rss_context.list);
+ efx->rss_context.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
mutex_init(&efx->rss_lock);
+ efx->vport_id = EVB_PORT_ID_ASSIGNED;
spin_lock_init(&efx->stats_lock);
efx->vi_stride = EFX_DEFAULT_VI_STRIDE;
efx->num_mac_stats = MC_CMD_MAC_NSTATS;
@@ -929,6 +1042,12 @@ int efx_init_struct(struct efx_nic *efx,
INIT_WORK(&efx->mac_work, efx_mac_work);
init_waitqueue_head(&efx->flush_wq);
+ efx->tx_queues_per_channel = 1;
+ efx->rxq_entries = EFX_DEFAULT_DMAQ_SIZE;
+ efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
+
+ efx->mem_bar = UINT_MAX;
+
rc = efx_init_channels(efx);
if (rc)
goto fail;
@@ -972,7 +1091,9 @@ int efx_init_io(struct efx_nic *efx, int bar, dma_addr_t dma_mask,
struct pci_dev *pci_dev = efx->pci_dev;
int rc;
- netif_dbg(efx, probe, efx->net_dev, "initialising I/O\n");
+ efx->mem_bar = UINT_MAX;
+
+ netif_dbg(efx, probe, efx->net_dev, "initialising I/O bar=%d\n", bar);
rc = pci_enable_device(pci_dev);
if (rc) {
@@ -1014,21 +1135,21 @@ int efx_init_io(struct efx_nic *efx, int bar, dma_addr_t dma_mask,
rc = pci_request_region(pci_dev, bar, "sfc");
if (rc) {
netif_err(efx, probe, efx->net_dev,
- "request for memory BAR failed\n");
+ "request for memory BAR[%d] failed\n", bar);
rc = -EIO;
goto fail3;
}
-
+ efx->mem_bar = bar;
efx->membase = ioremap(efx->membase_phys, mem_map_size);
if (!efx->membase) {
netif_err(efx, probe, efx->net_dev,
- "could not map memory BAR at %llx+%x\n",
+ "could not map memory BAR[%d] at %llx+%x\n", bar,
(unsigned long long)efx->membase_phys, mem_map_size);
rc = -ENOMEM;
goto fail4;
}
netif_dbg(efx, probe, efx->net_dev,
- "memory BAR at %llx+%x (virtual %p)\n",
+ "memory BAR[%d] at %llx+%x (virtual %p)\n", bar,
(unsigned long long)efx->membase_phys, mem_map_size,
efx->membase);
@@ -1044,7 +1165,7 @@ fail1:
return rc;
}
-void efx_fini_io(struct efx_nic *efx, int bar)
+void efx_fini_io(struct efx_nic *efx)
{
netif_dbg(efx, drv, efx->net_dev, "shutting down I/O\n");
@@ -1054,8 +1175,9 @@ void efx_fini_io(struct efx_nic *efx, int bar)
}
if (efx->membase_phys) {
- pci_release_region(efx->pci_dev, bar);
+ pci_release_region(efx->pci_dev, efx->mem_bar);
efx->membase_phys = 0;
+ efx->mem_bar = UINT_MAX;
}
/* Don't disable bus-mastering if VFs are assigned */
@@ -1101,3 +1223,114 @@ void efx_fini_mcdi_logging(struct efx_nic *efx)
device_remove_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging);
}
#endif
+
+/* A PCI error affecting this device was detected.
+ * At this point MMIO and DMA may be disabled.
+ * Stop the software path and request a slot reset.
+ */
+static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev,
+ enum pci_channel_state state)
+{
+ pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
+ struct efx_nic *efx = pci_get_drvdata(pdev);
+
+ if (state == pci_channel_io_perm_failure)
+ return PCI_ERS_RESULT_DISCONNECT;
+
+ rtnl_lock();
+
+ if (efx->state != STATE_DISABLED) {
+ efx->state = STATE_RECOVERY;
+ efx->reset_pending = 0;
+
+ efx_device_detach_sync(efx);
+
+ efx_stop_all(efx);
+ efx_disable_interrupts(efx);
+
+ status = PCI_ERS_RESULT_NEED_RESET;
+ } else {
+ /* If the interface is disabled we don't want to do anything
+ * with it.
+ */
+ status = PCI_ERS_RESULT_RECOVERED;
+ }
+
+ rtnl_unlock();
+
+ pci_disable_device(pdev);
+
+ return status;
+}
+
+/* Fake a successful reset, which will be performed later in efx_io_resume. */
+static pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev)
+{
+ struct efx_nic *efx = pci_get_drvdata(pdev);
+ pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
+
+ if (pci_enable_device(pdev)) {
+ netif_err(efx, hw, efx->net_dev,
+ "Cannot re-enable PCI device after reset.\n");
+ status = PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ return status;
+}
+
+/* Perform the actual reset and resume I/O operations. */
+static void efx_io_resume(struct pci_dev *pdev)
+{
+ struct efx_nic *efx = pci_get_drvdata(pdev);
+ int rc;
+
+ rtnl_lock();
+
+ if (efx->state == STATE_DISABLED)
+ goto out;
+
+ rc = efx_reset(efx, RESET_TYPE_ALL);
+ if (rc) {
+ netif_err(efx, hw, efx->net_dev,
+ "efx_reset failed after PCI error (%d)\n", rc);
+ } else {
+ efx->state = STATE_READY;
+ netif_dbg(efx, hw, efx->net_dev,
+ "Done resetting and resuming IO after PCI error.\n");
+ }
+
+out:
+ rtnl_unlock();
+}
+
+/* For simplicity and reliability, we always require a slot reset and try to
+ * reset the hardware when a pci error affecting the device is detected.
+ * We leave both the link_reset and mmio_enabled callback unimplemented:
+ * with our request for slot reset the mmio_enabled callback will never be
+ * called, and the link_reset callback is not used by AER or EEH mechanisms.
+ */
+const struct pci_error_handlers efx_err_handlers = {
+ .error_detected = efx_io_error_detected,
+ .slot_reset = efx_io_slot_reset,
+ .resume = efx_io_resume,
+};
+
+int efx_get_phys_port_id(struct net_device *net_dev,
+ struct netdev_phys_item_id *ppid)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ if (efx->type->get_phys_port_id)
+ return efx->type->get_phys_port_id(efx, ppid);
+ else
+ return -EOPNOTSUPP;
+}
+
+int efx_get_phys_port_name(struct net_device *net_dev, char *name, size_t len)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ if (snprintf(name, len, "p%u", efx->port_num) >= len)
+ return -EINVAL;
+ return 0;
+}
diff --git a/drivers/net/ethernet/sfc/efx_common.h b/drivers/net/ethernet/sfc/efx_common.h
index fa2fc681e7f9..4056f68f04e5 100644
--- a/drivers/net/ethernet/sfc/efx_common.h
+++ b/drivers/net/ethernet/sfc/efx_common.h
@@ -13,11 +13,21 @@
int efx_init_io(struct efx_nic *efx, int bar, dma_addr_t dma_mask,
unsigned int mem_map_size);
-void efx_fini_io(struct efx_nic *efx, int bar);
+void efx_fini_io(struct efx_nic *efx);
int efx_init_struct(struct efx_nic *efx, struct pci_dev *pci_dev,
struct net_device *net_dev);
void efx_fini_struct(struct efx_nic *efx);
+#define EFX_MAX_DMAQ_SIZE 4096UL
+#define EFX_DEFAULT_DMAQ_SIZE 1024UL
+#define EFX_MIN_DMAQ_SIZE 512UL
+
+#define EFX_MAX_EVQ_SIZE 16384UL
+#define EFX_MIN_EVQ_SIZE 512UL
+
+void efx_link_clear_advertising(struct efx_nic *efx);
+void efx_link_set_wanted_fc(struct efx_nic *efx, u8);
+
void efx_start_all(struct efx_nic *efx);
void efx_stop_all(struct efx_nic *efx);
@@ -43,10 +53,15 @@ int efx_reconfigure_port(struct efx_nic *efx);
int efx_try_recovery(struct efx_nic *efx);
void efx_reset_down(struct efx_nic *efx, enum reset_type method);
+void efx_watchdog(struct net_device *net_dev, unsigned int txqueue);
int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok);
int efx_reset(struct efx_nic *efx, enum reset_type method);
void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
+/* Dummy PHY ops for PHY drivers */
+int efx_port_dummy_op_int(struct efx_nic *efx);
+void efx_port_dummy_op_void(struct efx_nic *efx);
+
static inline int efx_check_disabled(struct efx_nic *efx)
{
if (efx->state == STATE_DISABLED || efx->state == STATE_RECOVERY) {
@@ -57,6 +72,21 @@ static inline int efx_check_disabled(struct efx_nic *efx)
return 0;
}
+static inline void efx_schedule_channel(struct efx_channel *channel)
+{
+ netif_vdbg(channel->efx, intr, channel->efx->net_dev,
+ "channel %d scheduling NAPI poll on CPU%d\n",
+ channel->channel, raw_smp_processor_id());
+
+ napi_schedule(&channel->napi_str);
+}
+
+static inline void efx_schedule_channel_irq(struct efx_channel *channel)
+{
+ channel->event_test_cpu = raw_smp_processor_id();
+ efx_schedule_channel(channel);
+}
+
#ifdef CONFIG_SFC_MCDI_LOGGING
void efx_init_mcdi_logging(struct efx_nic *efx);
void efx_fini_mcdi_logging(struct efx_nic *efx);
@@ -65,9 +95,19 @@ static inline void efx_init_mcdi_logging(struct efx_nic *efx) {}
static inline void efx_fini_mcdi_logging(struct efx_nic *efx) {}
#endif
-void efx_mac_reconfigure(struct efx_nic *efx);
+void efx_mac_reconfigure(struct efx_nic *efx, bool mtu_only);
+int efx_set_mac_address(struct net_device *net_dev, void *data);
+void efx_set_rx_mode(struct net_device *net_dev);
+int efx_set_features(struct net_device *net_dev, netdev_features_t data);
void efx_link_status_changed(struct efx_nic *efx);
unsigned int efx_xdp_max_mtu(struct efx_nic *efx);
int efx_change_mtu(struct net_device *net_dev, int new_mtu);
+extern const struct pci_error_handlers efx_err_handlers;
+
+int efx_get_phys_port_id(struct net_device *net_dev,
+ struct netdev_phys_item_id *ppid);
+
+int efx_get_phys_port_name(struct net_device *net_dev,
+ char *name, size_t len);
#endif
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 04e88d05e8ff..4ffda7782f68 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -54,58 +54,6 @@ static int efx_ethtool_phys_id(struct net_device *net_dev,
return 0;
}
-/* This must be called with rtnl_lock held. */
-static int
-efx_ethtool_get_link_ksettings(struct net_device *net_dev,
- struct ethtool_link_ksettings *cmd)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_link_state *link_state = &efx->link_state;
- u32 supported;
-
- mutex_lock(&efx->mac_lock);
- efx->phy_op->get_link_ksettings(efx, cmd);
- mutex_unlock(&efx->mac_lock);
-
- /* Both MACs support pause frames (bidirectional and respond-only) */
- ethtool_convert_link_mode_to_legacy_u32(&supported,
- cmd->link_modes.supported);
-
- supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
-
- ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
- supported);
-
- if (LOOPBACK_INTERNAL(efx)) {
- cmd->base.speed = link_state->speed;
- cmd->base.duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
- }
-
- return 0;
-}
-
-/* This must be called with rtnl_lock held. */
-static int
-efx_ethtool_set_link_ksettings(struct net_device *net_dev,
- const struct ethtool_link_ksettings *cmd)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- int rc;
-
- /* GMAC does not support 1000Mbps HD */
- if ((cmd->base.speed == SPEED_1000) &&
- (cmd->base.duplex != DUPLEX_FULL)) {
- netif_dbg(efx, drv, efx->net_dev,
- "rejecting unsupported 1000Mbps HD setting\n");
- return -EINVAL;
- }
-
- mutex_lock(&efx->mac_lock);
- rc = efx->phy_op->set_link_ksettings(efx, cmd);
- mutex_unlock(&efx->mac_lock);
- return rc;
-}
-
static int efx_ethtool_get_regs_len(struct net_device *net_dev)
{
return efx_nic_get_regs_len(netdev_priv(net_dev));
@@ -120,62 +68,6 @@ static void efx_ethtool_get_regs(struct net_device *net_dev,
efx_nic_get_regs(efx, buf);
}
-static void efx_ethtool_self_test(struct net_device *net_dev,
- struct ethtool_test *test, u64 *data)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_self_tests *efx_tests;
- bool already_up;
- int rc = -ENOMEM;
-
- efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL);
- if (!efx_tests)
- goto fail;
-
- if (efx->state != STATE_READY) {
- rc = -EBUSY;
- goto out;
- }
-
- netif_info(efx, drv, efx->net_dev, "starting %sline testing\n",
- (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
-
- /* We need rx buffers and interrupts. */
- already_up = (efx->net_dev->flags & IFF_UP);
- if (!already_up) {
- rc = dev_open(efx->net_dev, NULL);
- if (rc) {
- netif_err(efx, drv, efx->net_dev,
- "failed opening device.\n");
- goto out;
- }
- }
-
- rc = efx_selftest(efx, efx_tests, test->flags);
-
- if (!already_up)
- dev_close(efx->net_dev);
-
- netif_info(efx, drv, efx->net_dev, "%s %sline self-tests\n",
- rc == 0 ? "passed" : "failed",
- (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
-
-out:
- efx_ethtool_fill_self_tests(efx, efx_tests, NULL, data);
- kfree(efx_tests);
-fail:
- if (rc)
- test->flags |= ETH_TEST_FL_FAILED;
-}
-
-/* Restart autonegotiation */
-static int efx_ethtool_nway_reset(struct net_device *net_dev)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- return mdio45_nway_restart(&efx->mdio);
-}
-
/*
* Each channel has a single IRQ and moderation timer, started by any
* completion (or other event). Unless the module parameter
@@ -300,64 +192,6 @@ static int efx_ethtool_set_ringparam(struct net_device *net_dev,
return efx_realloc_channels(efx, ring->rx_pending, txq_entries);
}
-static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
- struct ethtool_pauseparam *pause)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- u8 wanted_fc, old_fc;
- u32 old_adv;
- int rc = 0;
-
- mutex_lock(&efx->mac_lock);
-
- wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) |
- (pause->tx_pause ? EFX_FC_TX : 0) |
- (pause->autoneg ? EFX_FC_AUTO : 0));
-
- if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) {
- netif_dbg(efx, drv, efx->net_dev,
- "Flow control unsupported: tx ON rx OFF\n");
- rc = -EINVAL;
- goto out;
- }
-
- if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising[0]) {
- netif_dbg(efx, drv, efx->net_dev,
- "Autonegotiation is disabled\n");
- rc = -EINVAL;
- goto out;
- }
-
- /* Hook for Falcon bug 11482 workaround */
- if (efx->type->prepare_enable_fc_tx &&
- (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX))
- efx->type->prepare_enable_fc_tx(efx);
-
- old_adv = efx->link_advertising[0];
- old_fc = efx->wanted_fc;
- efx_link_set_wanted_fc(efx, wanted_fc);
- if (efx->link_advertising[0] != old_adv ||
- (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) {
- rc = efx->phy_op->reconfigure(efx);
- if (rc) {
- netif_err(efx, drv, efx->net_dev,
- "Unable to advertise requested flow "
- "control setting\n");
- goto out;
- }
- }
-
- /* Reconfigure the MAC. The PHY *may* generate a link state change event
- * if the user just changed the advertised capabilities, but there's no
- * harm doing this twice */
- efx_mac_reconfigure(efx);
-
-out:
- mutex_unlock(&efx->mac_lock);
-
- return rc;
-}
-
static void efx_ethtool_get_wol(struct net_device *net_dev,
struct ethtool_wolinfo *wol)
{
@@ -373,690 +207,6 @@ static int efx_ethtool_set_wol(struct net_device *net_dev,
return efx->type->set_wol(efx, wol->wolopts);
}
-static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- int rc;
-
- rc = efx->type->map_reset_flags(flags);
- if (rc < 0)
- return rc;
-
- return efx_reset(efx, rc);
-}
-
-/* MAC address mask including only I/G bit */
-static const u8 mac_addr_ig_mask[ETH_ALEN] __aligned(2) = {0x01, 0, 0, 0, 0, 0};
-
-#define IP4_ADDR_FULL_MASK ((__force __be32)~0)
-#define IP_PROTO_FULL_MASK 0xFF
-#define PORT_FULL_MASK ((__force __be16)~0)
-#define ETHER_TYPE_FULL_MASK ((__force __be16)~0)
-
-static inline void ip6_fill_mask(__be32 *mask)
-{
- mask[0] = mask[1] = mask[2] = mask[3] = ~(__be32)0;
-}
-
-static int efx_ethtool_get_class_rule(struct efx_nic *efx,
- struct ethtool_rx_flow_spec *rule,
- u32 *rss_context)
-{
- struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
- struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
- struct ethtool_usrip4_spec *uip_entry = &rule->h_u.usr_ip4_spec;
- struct ethtool_usrip4_spec *uip_mask = &rule->m_u.usr_ip4_spec;
- struct ethtool_tcpip6_spec *ip6_entry = &rule->h_u.tcp_ip6_spec;
- struct ethtool_tcpip6_spec *ip6_mask = &rule->m_u.tcp_ip6_spec;
- struct ethtool_usrip6_spec *uip6_entry = &rule->h_u.usr_ip6_spec;
- struct ethtool_usrip6_spec *uip6_mask = &rule->m_u.usr_ip6_spec;
- struct ethhdr *mac_entry = &rule->h_u.ether_spec;
- struct ethhdr *mac_mask = &rule->m_u.ether_spec;
- struct efx_filter_spec spec;
- int rc;
-
- rc = efx_filter_get_filter_safe(efx, EFX_FILTER_PRI_MANUAL,
- rule->location, &spec);
- if (rc)
- return rc;
-
- if (spec.dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP)
- rule->ring_cookie = RX_CLS_FLOW_DISC;
- else
- rule->ring_cookie = spec.dmaq_id;
-
- if ((spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) &&
- spec.ether_type == htons(ETH_P_IP) &&
- (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) &&
- (spec.ip_proto == IPPROTO_TCP || spec.ip_proto == IPPROTO_UDP) &&
- !(spec.match_flags &
- ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
- EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
- EFX_FILTER_MATCH_IP_PROTO |
- EFX_FILTER_MATCH_LOC_PORT | EFX_FILTER_MATCH_REM_PORT))) {
- rule->flow_type = ((spec.ip_proto == IPPROTO_TCP) ?
- TCP_V4_FLOW : UDP_V4_FLOW);
- if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
- ip_entry->ip4dst = spec.loc_host[0];
- ip_mask->ip4dst = IP4_ADDR_FULL_MASK;
- }
- if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
- ip_entry->ip4src = spec.rem_host[0];
- ip_mask->ip4src = IP4_ADDR_FULL_MASK;
- }
- if (spec.match_flags & EFX_FILTER_MATCH_LOC_PORT) {
- ip_entry->pdst = spec.loc_port;
- ip_mask->pdst = PORT_FULL_MASK;
- }
- if (spec.match_flags & EFX_FILTER_MATCH_REM_PORT) {
- ip_entry->psrc = spec.rem_port;
- ip_mask->psrc = PORT_FULL_MASK;
- }
- } else if ((spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) &&
- spec.ether_type == htons(ETH_P_IPV6) &&
- (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) &&
- (spec.ip_proto == IPPROTO_TCP || spec.ip_proto == IPPROTO_UDP) &&
- !(spec.match_flags &
- ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
- EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
- EFX_FILTER_MATCH_IP_PROTO |
- EFX_FILTER_MATCH_LOC_PORT | EFX_FILTER_MATCH_REM_PORT))) {
- rule->flow_type = ((spec.ip_proto == IPPROTO_TCP) ?
- TCP_V6_FLOW : UDP_V6_FLOW);
- if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
- memcpy(ip6_entry->ip6dst, spec.loc_host,
- sizeof(ip6_entry->ip6dst));
- ip6_fill_mask(ip6_mask->ip6dst);
- }
- if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
- memcpy(ip6_entry->ip6src, spec.rem_host,
- sizeof(ip6_entry->ip6src));
- ip6_fill_mask(ip6_mask->ip6src);
- }
- if (spec.match_flags & EFX_FILTER_MATCH_LOC_PORT) {
- ip6_entry->pdst = spec.loc_port;
- ip6_mask->pdst = PORT_FULL_MASK;
- }
- if (spec.match_flags & EFX_FILTER_MATCH_REM_PORT) {
- ip6_entry->psrc = spec.rem_port;
- ip6_mask->psrc = PORT_FULL_MASK;
- }
- } else if (!(spec.match_flags &
- ~(EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_LOC_MAC_IG |
- EFX_FILTER_MATCH_REM_MAC | EFX_FILTER_MATCH_ETHER_TYPE |
- EFX_FILTER_MATCH_OUTER_VID))) {
- rule->flow_type = ETHER_FLOW;
- if (spec.match_flags &
- (EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_LOC_MAC_IG)) {
- ether_addr_copy(mac_entry->h_dest, spec.loc_mac);
- if (spec.match_flags & EFX_FILTER_MATCH_LOC_MAC)
- eth_broadcast_addr(mac_mask->h_dest);
- else
- ether_addr_copy(mac_mask->h_dest,
- mac_addr_ig_mask);
- }
- if (spec.match_flags & EFX_FILTER_MATCH_REM_MAC) {
- ether_addr_copy(mac_entry->h_source, spec.rem_mac);
- eth_broadcast_addr(mac_mask->h_source);
- }
- if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) {
- mac_entry->h_proto = spec.ether_type;
- mac_mask->h_proto = ETHER_TYPE_FULL_MASK;
- }
- } else if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE &&
- spec.ether_type == htons(ETH_P_IP) &&
- !(spec.match_flags &
- ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
- EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
- EFX_FILTER_MATCH_IP_PROTO))) {
- rule->flow_type = IPV4_USER_FLOW;
- uip_entry->ip_ver = ETH_RX_NFC_IP4;
- if (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) {
- uip_mask->proto = IP_PROTO_FULL_MASK;
- uip_entry->proto = spec.ip_proto;
- }
- if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
- uip_entry->ip4dst = spec.loc_host[0];
- uip_mask->ip4dst = IP4_ADDR_FULL_MASK;
- }
- if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
- uip_entry->ip4src = spec.rem_host[0];
- uip_mask->ip4src = IP4_ADDR_FULL_MASK;
- }
- } else if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE &&
- spec.ether_type == htons(ETH_P_IPV6) &&
- !(spec.match_flags &
- ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
- EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
- EFX_FILTER_MATCH_IP_PROTO))) {
- rule->flow_type = IPV6_USER_FLOW;
- if (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) {
- uip6_mask->l4_proto = IP_PROTO_FULL_MASK;
- uip6_entry->l4_proto = spec.ip_proto;
- }
- if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
- memcpy(uip6_entry->ip6dst, spec.loc_host,
- sizeof(uip6_entry->ip6dst));
- ip6_fill_mask(uip6_mask->ip6dst);
- }
- if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
- memcpy(uip6_entry->ip6src, spec.rem_host,
- sizeof(uip6_entry->ip6src));
- ip6_fill_mask(uip6_mask->ip6src);
- }
- } else {
- /* The above should handle all filters that we insert */
- WARN_ON(1);
- return -EINVAL;
- }
-
- if (spec.match_flags & EFX_FILTER_MATCH_OUTER_VID) {
- rule->flow_type |= FLOW_EXT;
- rule->h_ext.vlan_tci = spec.outer_vid;
- rule->m_ext.vlan_tci = htons(0xfff);
- }
-
- if (spec.flags & EFX_FILTER_FLAG_RX_RSS) {
- rule->flow_type |= FLOW_RSS;
- *rss_context = spec.rss_context;
- }
-
- return rc;
-}
-
-static int
-efx_ethtool_get_rxnfc(struct net_device *net_dev,
- struct ethtool_rxnfc *info, u32 *rule_locs)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- u32 rss_context = 0;
- s32 rc = 0;
-
- switch (info->cmd) {
- case ETHTOOL_GRXRINGS:
- info->data = efx->n_rx_channels;
- return 0;
-
- case ETHTOOL_GRXFH: {
- struct efx_rss_context *ctx = &efx->rss_context;
- __u64 data;
-
- mutex_lock(&efx->rss_lock);
- if (info->flow_type & FLOW_RSS && info->rss_context) {
- ctx = efx_find_rss_context_entry(efx, info->rss_context);
- if (!ctx) {
- rc = -ENOENT;
- goto out_unlock;
- }
- }
-
- data = 0;
- if (!efx_rss_active(ctx)) /* No RSS */
- goto out_setdata_unlock;
-
- switch (info->flow_type & ~FLOW_RSS) {
- case UDP_V4_FLOW:
- case UDP_V6_FLOW:
- if (ctx->rx_hash_udp_4tuple)
- data = (RXH_L4_B_0_1 | RXH_L4_B_2_3 |
- RXH_IP_SRC | RXH_IP_DST);
- else
- data = RXH_IP_SRC | RXH_IP_DST;
- break;
- case TCP_V4_FLOW:
- case TCP_V6_FLOW:
- data = (RXH_L4_B_0_1 | RXH_L4_B_2_3 |
- RXH_IP_SRC | RXH_IP_DST);
- break;
- case SCTP_V4_FLOW:
- case SCTP_V6_FLOW:
- case AH_ESP_V4_FLOW:
- case AH_ESP_V6_FLOW:
- case IPV4_FLOW:
- case IPV6_FLOW:
- data = RXH_IP_SRC | RXH_IP_DST;
- break;
- default:
- break;
- }
-out_setdata_unlock:
- info->data = data;
-out_unlock:
- mutex_unlock(&efx->rss_lock);
- return rc;
- }
-
- case ETHTOOL_GRXCLSRLCNT:
- info->data = efx_filter_get_rx_id_limit(efx);
- if (info->data == 0)
- return -EOPNOTSUPP;
- info->data |= RX_CLS_LOC_SPECIAL;
- info->rule_cnt =
- efx_filter_count_rx_used(efx, EFX_FILTER_PRI_MANUAL);
- return 0;
-
- case ETHTOOL_GRXCLSRULE:
- if (efx_filter_get_rx_id_limit(efx) == 0)
- return -EOPNOTSUPP;
- rc = efx_ethtool_get_class_rule(efx, &info->fs, &rss_context);
- if (rc < 0)
- return rc;
- if (info->fs.flow_type & FLOW_RSS)
- info->rss_context = rss_context;
- return 0;
-
- case ETHTOOL_GRXCLSRLALL:
- info->data = efx_filter_get_rx_id_limit(efx);
- if (info->data == 0)
- return -EOPNOTSUPP;
- rc = efx_filter_get_rx_ids(efx, EFX_FILTER_PRI_MANUAL,
- rule_locs, info->rule_cnt);
- if (rc < 0)
- return rc;
- info->rule_cnt = rc;
- return 0;
-
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static inline bool ip6_mask_is_full(__be32 mask[4])
-{
- return !~(mask[0] & mask[1] & mask[2] & mask[3]);
-}
-
-static inline bool ip6_mask_is_empty(__be32 mask[4])
-{
- return !(mask[0] | mask[1] | mask[2] | mask[3]);
-}
-
-static int efx_ethtool_set_class_rule(struct efx_nic *efx,
- struct ethtool_rx_flow_spec *rule,
- u32 rss_context)
-{
- struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
- struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
- struct ethtool_usrip4_spec *uip_entry = &rule->h_u.usr_ip4_spec;
- struct ethtool_usrip4_spec *uip_mask = &rule->m_u.usr_ip4_spec;
- struct ethtool_tcpip6_spec *ip6_entry = &rule->h_u.tcp_ip6_spec;
- struct ethtool_tcpip6_spec *ip6_mask = &rule->m_u.tcp_ip6_spec;
- struct ethtool_usrip6_spec *uip6_entry = &rule->h_u.usr_ip6_spec;
- struct ethtool_usrip6_spec *uip6_mask = &rule->m_u.usr_ip6_spec;
- u32 flow_type = rule->flow_type & ~(FLOW_EXT | FLOW_RSS);
- struct ethhdr *mac_entry = &rule->h_u.ether_spec;
- struct ethhdr *mac_mask = &rule->m_u.ether_spec;
- enum efx_filter_flags flags = 0;
- struct efx_filter_spec spec;
- int rc;
-
- /* Check that user wants us to choose the location */
- if (rule->location != RX_CLS_LOC_ANY)
- return -EINVAL;
-
- /* Range-check ring_cookie */
- if (rule->ring_cookie >= efx->n_rx_channels &&
- rule->ring_cookie != RX_CLS_FLOW_DISC)
- return -EINVAL;
-
- /* Check for unsupported extensions */
- if ((rule->flow_type & FLOW_EXT) &&
- (rule->m_ext.vlan_etype || rule->m_ext.data[0] ||
- rule->m_ext.data[1]))
- return -EINVAL;
-
- if (efx->rx_scatter)
- flags |= EFX_FILTER_FLAG_RX_SCATTER;
- if (rule->flow_type & FLOW_RSS)
- flags |= EFX_FILTER_FLAG_RX_RSS;
-
- efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, flags,
- (rule->ring_cookie == RX_CLS_FLOW_DISC) ?
- EFX_FILTER_RX_DMAQ_ID_DROP : rule->ring_cookie);
-
- if (rule->flow_type & FLOW_RSS)
- spec.rss_context = rss_context;
-
- switch (flow_type) {
- case TCP_V4_FLOW:
- case UDP_V4_FLOW:
- spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE |
- EFX_FILTER_MATCH_IP_PROTO);
- spec.ether_type = htons(ETH_P_IP);
- spec.ip_proto = flow_type == TCP_V4_FLOW ? IPPROTO_TCP
- : IPPROTO_UDP;
- if (ip_mask->ip4dst) {
- if (ip_mask->ip4dst != IP4_ADDR_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
- spec.loc_host[0] = ip_entry->ip4dst;
- }
- if (ip_mask->ip4src) {
- if (ip_mask->ip4src != IP4_ADDR_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
- spec.rem_host[0] = ip_entry->ip4src;
- }
- if (ip_mask->pdst) {
- if (ip_mask->pdst != PORT_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_LOC_PORT;
- spec.loc_port = ip_entry->pdst;
- }
- if (ip_mask->psrc) {
- if (ip_mask->psrc != PORT_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_REM_PORT;
- spec.rem_port = ip_entry->psrc;
- }
- if (ip_mask->tos)
- return -EINVAL;
- break;
-
- case TCP_V6_FLOW:
- case UDP_V6_FLOW:
- spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE |
- EFX_FILTER_MATCH_IP_PROTO);
- spec.ether_type = htons(ETH_P_IPV6);
- spec.ip_proto = flow_type == TCP_V6_FLOW ? IPPROTO_TCP
- : IPPROTO_UDP;
- if (!ip6_mask_is_empty(ip6_mask->ip6dst)) {
- if (!ip6_mask_is_full(ip6_mask->ip6dst))
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
- memcpy(spec.loc_host, ip6_entry->ip6dst, sizeof(spec.loc_host));
- }
- if (!ip6_mask_is_empty(ip6_mask->ip6src)) {
- if (!ip6_mask_is_full(ip6_mask->ip6src))
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
- memcpy(spec.rem_host, ip6_entry->ip6src, sizeof(spec.rem_host));
- }
- if (ip6_mask->pdst) {
- if (ip6_mask->pdst != PORT_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_LOC_PORT;
- spec.loc_port = ip6_entry->pdst;
- }
- if (ip6_mask->psrc) {
- if (ip6_mask->psrc != PORT_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_REM_PORT;
- spec.rem_port = ip6_entry->psrc;
- }
- if (ip6_mask->tclass)
- return -EINVAL;
- break;
-
- case IPV4_USER_FLOW:
- if (uip_mask->l4_4_bytes || uip_mask->tos || uip_mask->ip_ver ||
- uip_entry->ip_ver != ETH_RX_NFC_IP4)
- return -EINVAL;
- spec.match_flags = EFX_FILTER_MATCH_ETHER_TYPE;
- spec.ether_type = htons(ETH_P_IP);
- if (uip_mask->ip4dst) {
- if (uip_mask->ip4dst != IP4_ADDR_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
- spec.loc_host[0] = uip_entry->ip4dst;
- }
- if (uip_mask->ip4src) {
- if (uip_mask->ip4src != IP4_ADDR_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
- spec.rem_host[0] = uip_entry->ip4src;
- }
- if (uip_mask->proto) {
- if (uip_mask->proto != IP_PROTO_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_IP_PROTO;
- spec.ip_proto = uip_entry->proto;
- }
- break;
-
- case IPV6_USER_FLOW:
- if (uip6_mask->l4_4_bytes || uip6_mask->tclass)
- return -EINVAL;
- spec.match_flags = EFX_FILTER_MATCH_ETHER_TYPE;
- spec.ether_type = htons(ETH_P_IPV6);
- if (!ip6_mask_is_empty(uip6_mask->ip6dst)) {
- if (!ip6_mask_is_full(uip6_mask->ip6dst))
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
- memcpy(spec.loc_host, uip6_entry->ip6dst, sizeof(spec.loc_host));
- }
- if (!ip6_mask_is_empty(uip6_mask->ip6src)) {
- if (!ip6_mask_is_full(uip6_mask->ip6src))
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
- memcpy(spec.rem_host, uip6_entry->ip6src, sizeof(spec.rem_host));
- }
- if (uip6_mask->l4_proto) {
- if (uip6_mask->l4_proto != IP_PROTO_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_IP_PROTO;
- spec.ip_proto = uip6_entry->l4_proto;
- }
- break;
-
- case ETHER_FLOW:
- if (!is_zero_ether_addr(mac_mask->h_dest)) {
- if (ether_addr_equal(mac_mask->h_dest,
- mac_addr_ig_mask))
- spec.match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
- else if (is_broadcast_ether_addr(mac_mask->h_dest))
- spec.match_flags |= EFX_FILTER_MATCH_LOC_MAC;
- else
- return -EINVAL;
- ether_addr_copy(spec.loc_mac, mac_entry->h_dest);
- }
- if (!is_zero_ether_addr(mac_mask->h_source)) {
- if (!is_broadcast_ether_addr(mac_mask->h_source))
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_REM_MAC;
- ether_addr_copy(spec.rem_mac, mac_entry->h_source);
- }
- if (mac_mask->h_proto) {
- if (mac_mask->h_proto != ETHER_TYPE_FULL_MASK)
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
- spec.ether_type = mac_entry->h_proto;
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- if ((rule->flow_type & FLOW_EXT) && rule->m_ext.vlan_tci) {
- if (rule->m_ext.vlan_tci != htons(0xfff))
- return -EINVAL;
- spec.match_flags |= EFX_FILTER_MATCH_OUTER_VID;
- spec.outer_vid = rule->h_ext.vlan_tci;
- }
-
- rc = efx_filter_insert_filter(efx, &spec, true);
- if (rc < 0)
- return rc;
-
- rule->location = rc;
- return 0;
-}
-
-static int efx_ethtool_set_rxnfc(struct net_device *net_dev,
- struct ethtool_rxnfc *info)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- if (efx_filter_get_rx_id_limit(efx) == 0)
- return -EOPNOTSUPP;
-
- switch (info->cmd) {
- case ETHTOOL_SRXCLSRLINS:
- return efx_ethtool_set_class_rule(efx, &info->fs,
- info->rss_context);
-
- case ETHTOOL_SRXCLSRLDEL:
- return efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_MANUAL,
- info->fs.location);
-
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- if (efx->n_rx_channels == 1)
- return 0;
- return ARRAY_SIZE(efx->rss_context.rx_indir_table);
-}
-
-static u32 efx_ethtool_get_rxfh_key_size(struct net_device *net_dev)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- return efx->type->rx_hash_key_size;
-}
-
-static int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key,
- u8 *hfunc)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- int rc;
-
- rc = efx->type->rx_pull_rss_config(efx);
- if (rc)
- return rc;
-
- if (hfunc)
- *hfunc = ETH_RSS_HASH_TOP;
- if (indir)
- memcpy(indir, efx->rss_context.rx_indir_table,
- sizeof(efx->rss_context.rx_indir_table));
- if (key)
- memcpy(key, efx->rss_context.rx_hash_key,
- efx->type->rx_hash_key_size);
- return 0;
-}
-
-static int efx_ethtool_set_rxfh(struct net_device *net_dev, const u32 *indir,
- const u8 *key, const u8 hfunc)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- /* Hash function is Toeplitz, cannot be changed */
- if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
- return -EOPNOTSUPP;
- if (!indir && !key)
- return 0;
-
- if (!key)
- key = efx->rss_context.rx_hash_key;
- if (!indir)
- indir = efx->rss_context.rx_indir_table;
-
- return efx->type->rx_push_rss_config(efx, true, indir, key);
-}
-
-static int efx_ethtool_get_rxfh_context(struct net_device *net_dev, u32 *indir,
- u8 *key, u8 *hfunc, u32 rss_context)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_rss_context *ctx;
- int rc = 0;
-
- if (!efx->type->rx_pull_rss_context_config)
- return -EOPNOTSUPP;
-
- mutex_lock(&efx->rss_lock);
- ctx = efx_find_rss_context_entry(efx, rss_context);
- if (!ctx) {
- rc = -ENOENT;
- goto out_unlock;
- }
- rc = efx->type->rx_pull_rss_context_config(efx, ctx);
- if (rc)
- goto out_unlock;
-
- if (hfunc)
- *hfunc = ETH_RSS_HASH_TOP;
- if (indir)
- memcpy(indir, ctx->rx_indir_table, sizeof(ctx->rx_indir_table));
- if (key)
- memcpy(key, ctx->rx_hash_key, efx->type->rx_hash_key_size);
-out_unlock:
- mutex_unlock(&efx->rss_lock);
- return rc;
-}
-
-static int efx_ethtool_set_rxfh_context(struct net_device *net_dev,
- const u32 *indir, const u8 *key,
- const u8 hfunc, u32 *rss_context,
- bool delete)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_rss_context *ctx;
- bool allocated = false;
- int rc;
-
- if (!efx->type->rx_push_rss_context_config)
- return -EOPNOTSUPP;
- /* Hash function is Toeplitz, cannot be changed */
- if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
- return -EOPNOTSUPP;
-
- mutex_lock(&efx->rss_lock);
-
- if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
- if (delete) {
- /* alloc + delete == Nothing to do */
- rc = -EINVAL;
- goto out_unlock;
- }
- ctx = efx_alloc_rss_context_entry(efx);
- if (!ctx) {
- rc = -ENOMEM;
- goto out_unlock;
- }
- ctx->context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
- /* Initialise indir table and key to defaults */
- efx_set_default_rx_indir_table(efx, ctx);
- netdev_rss_key_fill(ctx->rx_hash_key, sizeof(ctx->rx_hash_key));
- allocated = true;
- } else {
- ctx = efx_find_rss_context_entry(efx, *rss_context);
- if (!ctx) {
- rc = -ENOENT;
- goto out_unlock;
- }
- }
-
- if (delete) {
- /* delete this context */
- rc = efx->type->rx_push_rss_context_config(efx, ctx, NULL, NULL);
- if (!rc)
- efx_free_rss_context_entry(ctx);
- goto out_unlock;
- }
-
- if (!key)
- key = ctx->rx_hash_key;
- if (!indir)
- indir = ctx->rx_indir_table;
-
- rc = efx->type->rx_push_rss_context_config(efx, ctx, indir, key);
- if (rc && allocated)
- efx_free_rss_context_entry(ctx);
- else
- *rss_context = ctx->user_id;
-out_unlock:
- mutex_unlock(&efx->rss_lock);
- return rc;
-}
-
static int efx_ethtool_get_ts_info(struct net_device *net_dev,
struct ethtool_ts_info *ts_info)
{
@@ -1071,69 +221,6 @@ static int efx_ethtool_get_ts_info(struct net_device *net_dev,
return 0;
}
-static int efx_ethtool_get_module_eeprom(struct net_device *net_dev,
- struct ethtool_eeprom *ee,
- u8 *data)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- int ret;
-
- if (!efx->phy_op || !efx->phy_op->get_module_eeprom)
- return -EOPNOTSUPP;
-
- mutex_lock(&efx->mac_lock);
- ret = efx->phy_op->get_module_eeprom(efx, ee, data);
- mutex_unlock(&efx->mac_lock);
-
- return ret;
-}
-
-static int efx_ethtool_get_module_info(struct net_device *net_dev,
- struct ethtool_modinfo *modinfo)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- int ret;
-
- if (!efx->phy_op || !efx->phy_op->get_module_info)
- return -EOPNOTSUPP;
-
- mutex_lock(&efx->mac_lock);
- ret = efx->phy_op->get_module_info(efx, modinfo);
- mutex_unlock(&efx->mac_lock);
-
- return ret;
-}
-
-static int efx_ethtool_get_fecparam(struct net_device *net_dev,
- struct ethtool_fecparam *fecparam)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- int rc;
-
- if (!efx->phy_op || !efx->phy_op->get_fecparam)
- return -EOPNOTSUPP;
- mutex_lock(&efx->mac_lock);
- rc = efx->phy_op->get_fecparam(efx, fecparam);
- mutex_unlock(&efx->mac_lock);
-
- return rc;
-}
-
-static int efx_ethtool_set_fecparam(struct net_device *net_dev,
- struct ethtool_fecparam *fecparam)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- int rc;
-
- if (!efx->phy_op || !efx->phy_op->get_fecparam)
- return -EOPNOTSUPP;
- mutex_lock(&efx->mac_lock);
- rc = efx->phy_op->set_fecparam(efx, fecparam);
- mutex_unlock(&efx->mac_lock);
-
- return rc;
-}
-
const struct ethtool_ops efx_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_USECS_IRQ |
@@ -1143,7 +230,6 @@ const struct ethtool_ops efx_ethtool_ops = {
.get_regs = efx_ethtool_get_regs,
.get_msglevel = efx_ethtool_get_msglevel,
.set_msglevel = efx_ethtool_set_msglevel,
- .nway_reset = efx_ethtool_nway_reset,
.get_link = ethtool_op_get_link,
.get_coalesce = efx_ethtool_get_coalesce,
.set_coalesce = efx_ethtool_set_coalesce,
diff --git a/drivers/net/ethernet/sfc/ethtool_common.c b/drivers/net/ethernet/sfc/ethtool_common.c
index b8d281ab6c7a..05ac87807929 100644
--- a/drivers/net/ethernet/sfc/ethtool_common.c
+++ b/drivers/net/ethernet/sfc/ethtool_common.c
@@ -13,6 +13,7 @@
#include "mcdi.h"
#include "nic.h"
#include "selftest.h"
+#include "rx_common.h"
#include "ethtool_common.h"
struct efx_sw_stat_desc {
@@ -124,6 +125,54 @@ void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable)
efx->msg_enable = msg_enable;
}
+void efx_ethtool_self_test(struct net_device *net_dev,
+ struct ethtool_test *test, u64 *data)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_self_tests *efx_tests;
+ bool already_up;
+ int rc = -ENOMEM;
+
+ efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL);
+ if (!efx_tests)
+ goto fail;
+
+ if (efx->state != STATE_READY) {
+ rc = -EBUSY;
+ goto out;
+ }
+
+ netif_info(efx, drv, efx->net_dev, "starting %sline testing\n",
+ (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
+
+ /* We need rx buffers and interrupts. */
+ already_up = (efx->net_dev->flags & IFF_UP);
+ if (!already_up) {
+ rc = dev_open(efx->net_dev, NULL);
+ if (rc) {
+ netif_err(efx, drv, efx->net_dev,
+ "failed opening device.\n");
+ goto out;
+ }
+ }
+
+ rc = efx_selftest(efx, efx_tests, test->flags);
+
+ if (!already_up)
+ dev_close(efx->net_dev);
+
+ netif_info(efx, drv, efx->net_dev, "%s %sline self-tests\n",
+ rc == 0 ? "passed" : "failed",
+ (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
+
+out:
+ efx_ethtool_fill_self_tests(efx, efx_tests, NULL, data);
+ kfree(efx_tests);
+fail:
+ if (rc)
+ test->flags |= ETH_TEST_FL_FAILED;
+}
+
void efx_ethtool_get_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause)
{
@@ -134,6 +183,64 @@ void efx_ethtool_get_pauseparam(struct net_device *net_dev,
pause->autoneg = !!(efx->wanted_fc & EFX_FC_AUTO);
}
+int efx_ethtool_set_pauseparam(struct net_device *net_dev,
+ struct ethtool_pauseparam *pause)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ u8 wanted_fc, old_fc;
+ u32 old_adv;
+ int rc = 0;
+
+ mutex_lock(&efx->mac_lock);
+
+ wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) |
+ (pause->tx_pause ? EFX_FC_TX : 0) |
+ (pause->autoneg ? EFX_FC_AUTO : 0));
+
+ if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) {
+ netif_dbg(efx, drv, efx->net_dev,
+ "Flow control unsupported: tx ON rx OFF\n");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising[0]) {
+ netif_dbg(efx, drv, efx->net_dev,
+ "Autonegotiation is disabled\n");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ /* Hook for Falcon bug 11482 workaround */
+ if (efx->type->prepare_enable_fc_tx &&
+ (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX))
+ efx->type->prepare_enable_fc_tx(efx);
+
+ old_adv = efx->link_advertising[0];
+ old_fc = efx->wanted_fc;
+ efx_link_set_wanted_fc(efx, wanted_fc);
+ if (efx->link_advertising[0] != old_adv ||
+ (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) {
+ rc = efx->phy_op->reconfigure(efx);
+ if (rc) {
+ netif_err(efx, drv, efx->net_dev,
+ "Unable to advertise requested flow "
+ "control setting\n");
+ goto out;
+ }
+ }
+
+ /* Reconfigure the MAC. The PHY *may* generate a link state change event
+ * if the user just changed the advertised capabilities, but there's no
+ * harm doing this twice */
+ efx_mac_reconfigure(efx, false);
+
+out:
+ mutex_unlock(&efx->mac_lock);
+
+ return rc;
+}
+
/**
* efx_fill_test - fill in an individual self-test entry
* @test_index: Index of the test
@@ -172,8 +279,7 @@ static void efx_fill_test(unsigned int test_index, u8 *strings, u64 *data,
}
#define EFX_CHANNEL_NAME(_channel) "chan%d", _channel->channel
-#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue
-#define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue
+#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->label
#define EFX_LOOPBACK_NAME(_mode, _counter) \
"loopback.%s." _counter, STRING_TABLE_LOOKUP(_mode, efx_loopback_mode)
@@ -201,11 +307,11 @@ static int efx_fill_loopback_test(struct efx_nic *efx,
efx_for_each_channel_tx_queue(tx_queue, channel) {
efx_fill_test(test_index++, strings, data,
- &lb_tests->tx_sent[tx_queue->queue],
+ &lb_tests->tx_sent[tx_queue->label],
EFX_TX_QUEUE_NAME(tx_queue),
EFX_LOOPBACK_NAME(mode, "tx_sent"));
efx_fill_test(test_index++, strings, data,
- &lb_tests->tx_done[tx_queue->queue],
+ &lb_tests->tx_done[tx_queue->label],
EFX_TX_QUEUE_NAME(tx_queue),
EFX_LOOPBACK_NAME(mode, "tx_done"));
}
@@ -455,3 +561,799 @@ void efx_ethtool_get_stats(struct net_device *net_dev,
efx_ptp_update_stats(efx, data);
}
+
+/* This must be called with rtnl_lock held. */
+int efx_ethtool_get_link_ksettings(struct net_device *net_dev,
+ struct ethtool_link_ksettings *cmd)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_link_state *link_state = &efx->link_state;
+ u32 supported;
+
+ mutex_lock(&efx->mac_lock);
+ efx->phy_op->get_link_ksettings(efx, cmd);
+ mutex_unlock(&efx->mac_lock);
+
+ /* Both MACs support pause frames (bidirectional and respond-only) */
+ ethtool_convert_link_mode_to_legacy_u32(&supported,
+ cmd->link_modes.supported);
+
+ supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+
+ ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
+ supported);
+
+ if (LOOPBACK_INTERNAL(efx)) {
+ cmd->base.speed = link_state->speed;
+ cmd->base.duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
+ }
+
+ return 0;
+}
+
+/* This must be called with rtnl_lock held. */
+int efx_ethtool_set_link_ksettings(struct net_device *net_dev,
+ const struct ethtool_link_ksettings *cmd)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int rc;
+
+ /* GMAC does not support 1000Mbps HD */
+ if ((cmd->base.speed == SPEED_1000) &&
+ (cmd->base.duplex != DUPLEX_FULL)) {
+ netif_dbg(efx, drv, efx->net_dev,
+ "rejecting unsupported 1000Mbps HD setting\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&efx->mac_lock);
+ rc = efx->phy_op->set_link_ksettings(efx, cmd);
+ mutex_unlock(&efx->mac_lock);
+ return rc;
+}
+
+int efx_ethtool_get_fecparam(struct net_device *net_dev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int rc;
+
+ if (!efx->phy_op || !efx->phy_op->get_fecparam)
+ return -EOPNOTSUPP;
+ mutex_lock(&efx->mac_lock);
+ rc = efx->phy_op->get_fecparam(efx, fecparam);
+ mutex_unlock(&efx->mac_lock);
+
+ return rc;
+}
+
+int efx_ethtool_set_fecparam(struct net_device *net_dev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int rc;
+
+ if (!efx->phy_op || !efx->phy_op->get_fecparam)
+ return -EOPNOTSUPP;
+ mutex_lock(&efx->mac_lock);
+ rc = efx->phy_op->set_fecparam(efx, fecparam);
+ mutex_unlock(&efx->mac_lock);
+
+ return rc;
+}
+
+/* MAC address mask including only I/G bit */
+static const u8 mac_addr_ig_mask[ETH_ALEN] __aligned(2) = {0x01, 0, 0, 0, 0, 0};
+
+#define IP4_ADDR_FULL_MASK ((__force __be32)~0)
+#define IP_PROTO_FULL_MASK 0xFF
+#define PORT_FULL_MASK ((__force __be16)~0)
+#define ETHER_TYPE_FULL_MASK ((__force __be16)~0)
+
+static inline void ip6_fill_mask(__be32 *mask)
+{
+ mask[0] = mask[1] = mask[2] = mask[3] = ~(__be32)0;
+}
+
+static int efx_ethtool_get_class_rule(struct efx_nic *efx,
+ struct ethtool_rx_flow_spec *rule,
+ u32 *rss_context)
+{
+ struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
+ struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
+ struct ethtool_usrip4_spec *uip_entry = &rule->h_u.usr_ip4_spec;
+ struct ethtool_usrip4_spec *uip_mask = &rule->m_u.usr_ip4_spec;
+ struct ethtool_tcpip6_spec *ip6_entry = &rule->h_u.tcp_ip6_spec;
+ struct ethtool_tcpip6_spec *ip6_mask = &rule->m_u.tcp_ip6_spec;
+ struct ethtool_usrip6_spec *uip6_entry = &rule->h_u.usr_ip6_spec;
+ struct ethtool_usrip6_spec *uip6_mask = &rule->m_u.usr_ip6_spec;
+ struct ethhdr *mac_entry = &rule->h_u.ether_spec;
+ struct ethhdr *mac_mask = &rule->m_u.ether_spec;
+ struct efx_filter_spec spec;
+ int rc;
+
+ rc = efx_filter_get_filter_safe(efx, EFX_FILTER_PRI_MANUAL,
+ rule->location, &spec);
+ if (rc)
+ return rc;
+
+ if (spec.dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP)
+ rule->ring_cookie = RX_CLS_FLOW_DISC;
+ else
+ rule->ring_cookie = spec.dmaq_id;
+
+ if ((spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) &&
+ spec.ether_type == htons(ETH_P_IP) &&
+ (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) &&
+ (spec.ip_proto == IPPROTO_TCP || spec.ip_proto == IPPROTO_UDP) &&
+ !(spec.match_flags &
+ ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
+ EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_PORT | EFX_FILTER_MATCH_REM_PORT))) {
+ rule->flow_type = ((spec.ip_proto == IPPROTO_TCP) ?
+ TCP_V4_FLOW : UDP_V4_FLOW);
+ if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
+ ip_entry->ip4dst = spec.loc_host[0];
+ ip_mask->ip4dst = IP4_ADDR_FULL_MASK;
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
+ ip_entry->ip4src = spec.rem_host[0];
+ ip_mask->ip4src = IP4_ADDR_FULL_MASK;
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_LOC_PORT) {
+ ip_entry->pdst = spec.loc_port;
+ ip_mask->pdst = PORT_FULL_MASK;
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_REM_PORT) {
+ ip_entry->psrc = spec.rem_port;
+ ip_mask->psrc = PORT_FULL_MASK;
+ }
+ } else if ((spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) &&
+ spec.ether_type == htons(ETH_P_IPV6) &&
+ (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) &&
+ (spec.ip_proto == IPPROTO_TCP || spec.ip_proto == IPPROTO_UDP) &&
+ !(spec.match_flags &
+ ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
+ EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_PORT | EFX_FILTER_MATCH_REM_PORT))) {
+ rule->flow_type = ((spec.ip_proto == IPPROTO_TCP) ?
+ TCP_V6_FLOW : UDP_V6_FLOW);
+ if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
+ memcpy(ip6_entry->ip6dst, spec.loc_host,
+ sizeof(ip6_entry->ip6dst));
+ ip6_fill_mask(ip6_mask->ip6dst);
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
+ memcpy(ip6_entry->ip6src, spec.rem_host,
+ sizeof(ip6_entry->ip6src));
+ ip6_fill_mask(ip6_mask->ip6src);
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_LOC_PORT) {
+ ip6_entry->pdst = spec.loc_port;
+ ip6_mask->pdst = PORT_FULL_MASK;
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_REM_PORT) {
+ ip6_entry->psrc = spec.rem_port;
+ ip6_mask->psrc = PORT_FULL_MASK;
+ }
+ } else if (!(spec.match_flags &
+ ~(EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_LOC_MAC_IG |
+ EFX_FILTER_MATCH_REM_MAC | EFX_FILTER_MATCH_ETHER_TYPE |
+ EFX_FILTER_MATCH_OUTER_VID))) {
+ rule->flow_type = ETHER_FLOW;
+ if (spec.match_flags &
+ (EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_LOC_MAC_IG)) {
+ ether_addr_copy(mac_entry->h_dest, spec.loc_mac);
+ if (spec.match_flags & EFX_FILTER_MATCH_LOC_MAC)
+ eth_broadcast_addr(mac_mask->h_dest);
+ else
+ ether_addr_copy(mac_mask->h_dest,
+ mac_addr_ig_mask);
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_REM_MAC) {
+ ether_addr_copy(mac_entry->h_source, spec.rem_mac);
+ eth_broadcast_addr(mac_mask->h_source);
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) {
+ mac_entry->h_proto = spec.ether_type;
+ mac_mask->h_proto = ETHER_TYPE_FULL_MASK;
+ }
+ } else if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE &&
+ spec.ether_type == htons(ETH_P_IP) &&
+ !(spec.match_flags &
+ ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
+ EFX_FILTER_MATCH_IP_PROTO))) {
+ rule->flow_type = IPV4_USER_FLOW;
+ uip_entry->ip_ver = ETH_RX_NFC_IP4;
+ if (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) {
+ uip_mask->proto = IP_PROTO_FULL_MASK;
+ uip_entry->proto = spec.ip_proto;
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
+ uip_entry->ip4dst = spec.loc_host[0];
+ uip_mask->ip4dst = IP4_ADDR_FULL_MASK;
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
+ uip_entry->ip4src = spec.rem_host[0];
+ uip_mask->ip4src = IP4_ADDR_FULL_MASK;
+ }
+ } else if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE &&
+ spec.ether_type == htons(ETH_P_IPV6) &&
+ !(spec.match_flags &
+ ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
+ EFX_FILTER_MATCH_IP_PROTO))) {
+ rule->flow_type = IPV6_USER_FLOW;
+ if (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) {
+ uip6_mask->l4_proto = IP_PROTO_FULL_MASK;
+ uip6_entry->l4_proto = spec.ip_proto;
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
+ memcpy(uip6_entry->ip6dst, spec.loc_host,
+ sizeof(uip6_entry->ip6dst));
+ ip6_fill_mask(uip6_mask->ip6dst);
+ }
+ if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
+ memcpy(uip6_entry->ip6src, spec.rem_host,
+ sizeof(uip6_entry->ip6src));
+ ip6_fill_mask(uip6_mask->ip6src);
+ }
+ } else {
+ /* The above should handle all filters that we insert */
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ if (spec.match_flags & EFX_FILTER_MATCH_OUTER_VID) {
+ rule->flow_type |= FLOW_EXT;
+ rule->h_ext.vlan_tci = spec.outer_vid;
+ rule->m_ext.vlan_tci = htons(0xfff);
+ }
+
+ if (spec.flags & EFX_FILTER_FLAG_RX_RSS) {
+ rule->flow_type |= FLOW_RSS;
+ *rss_context = spec.rss_context;
+ }
+
+ return rc;
+}
+
+int efx_ethtool_get_rxnfc(struct net_device *net_dev,
+ struct ethtool_rxnfc *info, u32 *rule_locs)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ u32 rss_context = 0;
+ s32 rc = 0;
+
+ switch (info->cmd) {
+ case ETHTOOL_GRXRINGS:
+ info->data = efx->n_rx_channels;
+ return 0;
+
+ case ETHTOOL_GRXFH: {
+ struct efx_rss_context *ctx = &efx->rss_context;
+ __u64 data;
+
+ mutex_lock(&efx->rss_lock);
+ if (info->flow_type & FLOW_RSS && info->rss_context) {
+ ctx = efx_find_rss_context_entry(efx, info->rss_context);
+ if (!ctx) {
+ rc = -ENOENT;
+ goto out_unlock;
+ }
+ }
+
+ data = 0;
+ if (!efx_rss_active(ctx)) /* No RSS */
+ goto out_setdata_unlock;
+
+ switch (info->flow_type & ~FLOW_RSS) {
+ case UDP_V4_FLOW:
+ case UDP_V6_FLOW:
+ if (ctx->rx_hash_udp_4tuple)
+ data = (RXH_L4_B_0_1 | RXH_L4_B_2_3 |
+ RXH_IP_SRC | RXH_IP_DST);
+ else
+ data = RXH_IP_SRC | RXH_IP_DST;
+ break;
+ case TCP_V4_FLOW:
+ case TCP_V6_FLOW:
+ data = (RXH_L4_B_0_1 | RXH_L4_B_2_3 |
+ RXH_IP_SRC | RXH_IP_DST);
+ break;
+ case SCTP_V4_FLOW:
+ case SCTP_V6_FLOW:
+ case AH_ESP_V4_FLOW:
+ case AH_ESP_V6_FLOW:
+ case IPV4_FLOW:
+ case IPV6_FLOW:
+ data = RXH_IP_SRC | RXH_IP_DST;
+ break;
+ default:
+ break;
+ }
+out_setdata_unlock:
+ info->data = data;
+out_unlock:
+ mutex_unlock(&efx->rss_lock);
+ return rc;
+ }
+
+ case ETHTOOL_GRXCLSRLCNT:
+ info->data = efx_filter_get_rx_id_limit(efx);
+ if (info->data == 0)
+ return -EOPNOTSUPP;
+ info->data |= RX_CLS_LOC_SPECIAL;
+ info->rule_cnt =
+ efx_filter_count_rx_used(efx, EFX_FILTER_PRI_MANUAL);
+ return 0;
+
+ case ETHTOOL_GRXCLSRULE:
+ if (efx_filter_get_rx_id_limit(efx) == 0)
+ return -EOPNOTSUPP;
+ rc = efx_ethtool_get_class_rule(efx, &info->fs, &rss_context);
+ if (rc < 0)
+ return rc;
+ if (info->fs.flow_type & FLOW_RSS)
+ info->rss_context = rss_context;
+ return 0;
+
+ case ETHTOOL_GRXCLSRLALL:
+ info->data = efx_filter_get_rx_id_limit(efx);
+ if (info->data == 0)
+ return -EOPNOTSUPP;
+ rc = efx_filter_get_rx_ids(efx, EFX_FILTER_PRI_MANUAL,
+ rule_locs, info->rule_cnt);
+ if (rc < 0)
+ return rc;
+ info->rule_cnt = rc;
+ return 0;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static inline bool ip6_mask_is_full(__be32 mask[4])
+{
+ return !~(mask[0] & mask[1] & mask[2] & mask[3]);
+}
+
+static inline bool ip6_mask_is_empty(__be32 mask[4])
+{
+ return !(mask[0] | mask[1] | mask[2] | mask[3]);
+}
+
+static int efx_ethtool_set_class_rule(struct efx_nic *efx,
+ struct ethtool_rx_flow_spec *rule,
+ u32 rss_context)
+{
+ struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
+ struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
+ struct ethtool_usrip4_spec *uip_entry = &rule->h_u.usr_ip4_spec;
+ struct ethtool_usrip4_spec *uip_mask = &rule->m_u.usr_ip4_spec;
+ struct ethtool_tcpip6_spec *ip6_entry = &rule->h_u.tcp_ip6_spec;
+ struct ethtool_tcpip6_spec *ip6_mask = &rule->m_u.tcp_ip6_spec;
+ struct ethtool_usrip6_spec *uip6_entry = &rule->h_u.usr_ip6_spec;
+ struct ethtool_usrip6_spec *uip6_mask = &rule->m_u.usr_ip6_spec;
+ u32 flow_type = rule->flow_type & ~(FLOW_EXT | FLOW_RSS);
+ struct ethhdr *mac_entry = &rule->h_u.ether_spec;
+ struct ethhdr *mac_mask = &rule->m_u.ether_spec;
+ enum efx_filter_flags flags = 0;
+ struct efx_filter_spec spec;
+ int rc;
+
+ /* Check that user wants us to choose the location */
+ if (rule->location != RX_CLS_LOC_ANY)
+ return -EINVAL;
+
+ /* Range-check ring_cookie */
+ if (rule->ring_cookie >= efx->n_rx_channels &&
+ rule->ring_cookie != RX_CLS_FLOW_DISC)
+ return -EINVAL;
+
+ /* Check for unsupported extensions */
+ if ((rule->flow_type & FLOW_EXT) &&
+ (rule->m_ext.vlan_etype || rule->m_ext.data[0] ||
+ rule->m_ext.data[1]))
+ return -EINVAL;
+
+ if (efx->rx_scatter)
+ flags |= EFX_FILTER_FLAG_RX_SCATTER;
+ if (rule->flow_type & FLOW_RSS)
+ flags |= EFX_FILTER_FLAG_RX_RSS;
+
+ efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, flags,
+ (rule->ring_cookie == RX_CLS_FLOW_DISC) ?
+ EFX_FILTER_RX_DMAQ_ID_DROP : rule->ring_cookie);
+
+ if (rule->flow_type & FLOW_RSS)
+ spec.rss_context = rss_context;
+
+ switch (flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE |
+ EFX_FILTER_MATCH_IP_PROTO);
+ spec.ether_type = htons(ETH_P_IP);
+ spec.ip_proto = flow_type == TCP_V4_FLOW ? IPPROTO_TCP
+ : IPPROTO_UDP;
+ if (ip_mask->ip4dst) {
+ if (ip_mask->ip4dst != IP4_ADDR_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
+ spec.loc_host[0] = ip_entry->ip4dst;
+ }
+ if (ip_mask->ip4src) {
+ if (ip_mask->ip4src != IP4_ADDR_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
+ spec.rem_host[0] = ip_entry->ip4src;
+ }
+ if (ip_mask->pdst) {
+ if (ip_mask->pdst != PORT_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_LOC_PORT;
+ spec.loc_port = ip_entry->pdst;
+ }
+ if (ip_mask->psrc) {
+ if (ip_mask->psrc != PORT_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_REM_PORT;
+ spec.rem_port = ip_entry->psrc;
+ }
+ if (ip_mask->tos)
+ return -EINVAL;
+ break;
+
+ case TCP_V6_FLOW:
+ case UDP_V6_FLOW:
+ spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE |
+ EFX_FILTER_MATCH_IP_PROTO);
+ spec.ether_type = htons(ETH_P_IPV6);
+ spec.ip_proto = flow_type == TCP_V6_FLOW ? IPPROTO_TCP
+ : IPPROTO_UDP;
+ if (!ip6_mask_is_empty(ip6_mask->ip6dst)) {
+ if (!ip6_mask_is_full(ip6_mask->ip6dst))
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
+ memcpy(spec.loc_host, ip6_entry->ip6dst, sizeof(spec.loc_host));
+ }
+ if (!ip6_mask_is_empty(ip6_mask->ip6src)) {
+ if (!ip6_mask_is_full(ip6_mask->ip6src))
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
+ memcpy(spec.rem_host, ip6_entry->ip6src, sizeof(spec.rem_host));
+ }
+ if (ip6_mask->pdst) {
+ if (ip6_mask->pdst != PORT_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_LOC_PORT;
+ spec.loc_port = ip6_entry->pdst;
+ }
+ if (ip6_mask->psrc) {
+ if (ip6_mask->psrc != PORT_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_REM_PORT;
+ spec.rem_port = ip6_entry->psrc;
+ }
+ if (ip6_mask->tclass)
+ return -EINVAL;
+ break;
+
+ case IPV4_USER_FLOW:
+ if (uip_mask->l4_4_bytes || uip_mask->tos || uip_mask->ip_ver ||
+ uip_entry->ip_ver != ETH_RX_NFC_IP4)
+ return -EINVAL;
+ spec.match_flags = EFX_FILTER_MATCH_ETHER_TYPE;
+ spec.ether_type = htons(ETH_P_IP);
+ if (uip_mask->ip4dst) {
+ if (uip_mask->ip4dst != IP4_ADDR_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
+ spec.loc_host[0] = uip_entry->ip4dst;
+ }
+ if (uip_mask->ip4src) {
+ if (uip_mask->ip4src != IP4_ADDR_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
+ spec.rem_host[0] = uip_entry->ip4src;
+ }
+ if (uip_mask->proto) {
+ if (uip_mask->proto != IP_PROTO_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_IP_PROTO;
+ spec.ip_proto = uip_entry->proto;
+ }
+ break;
+
+ case IPV6_USER_FLOW:
+ if (uip6_mask->l4_4_bytes || uip6_mask->tclass)
+ return -EINVAL;
+ spec.match_flags = EFX_FILTER_MATCH_ETHER_TYPE;
+ spec.ether_type = htons(ETH_P_IPV6);
+ if (!ip6_mask_is_empty(uip6_mask->ip6dst)) {
+ if (!ip6_mask_is_full(uip6_mask->ip6dst))
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
+ memcpy(spec.loc_host, uip6_entry->ip6dst, sizeof(spec.loc_host));
+ }
+ if (!ip6_mask_is_empty(uip6_mask->ip6src)) {
+ if (!ip6_mask_is_full(uip6_mask->ip6src))
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
+ memcpy(spec.rem_host, uip6_entry->ip6src, sizeof(spec.rem_host));
+ }
+ if (uip6_mask->l4_proto) {
+ if (uip6_mask->l4_proto != IP_PROTO_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_IP_PROTO;
+ spec.ip_proto = uip6_entry->l4_proto;
+ }
+ break;
+
+ case ETHER_FLOW:
+ if (!is_zero_ether_addr(mac_mask->h_dest)) {
+ if (ether_addr_equal(mac_mask->h_dest,
+ mac_addr_ig_mask))
+ spec.match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
+ else if (is_broadcast_ether_addr(mac_mask->h_dest))
+ spec.match_flags |= EFX_FILTER_MATCH_LOC_MAC;
+ else
+ return -EINVAL;
+ ether_addr_copy(spec.loc_mac, mac_entry->h_dest);
+ }
+ if (!is_zero_ether_addr(mac_mask->h_source)) {
+ if (!is_broadcast_ether_addr(mac_mask->h_source))
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_REM_MAC;
+ ether_addr_copy(spec.rem_mac, mac_entry->h_source);
+ }
+ if (mac_mask->h_proto) {
+ if (mac_mask->h_proto != ETHER_TYPE_FULL_MASK)
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
+ spec.ether_type = mac_entry->h_proto;
+ }
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if ((rule->flow_type & FLOW_EXT) && rule->m_ext.vlan_tci) {
+ if (rule->m_ext.vlan_tci != htons(0xfff))
+ return -EINVAL;
+ spec.match_flags |= EFX_FILTER_MATCH_OUTER_VID;
+ spec.outer_vid = rule->h_ext.vlan_tci;
+ }
+
+ rc = efx_filter_insert_filter(efx, &spec, true);
+ if (rc < 0)
+ return rc;
+
+ rule->location = rc;
+ return 0;
+}
+
+int efx_ethtool_set_rxnfc(struct net_device *net_dev,
+ struct ethtool_rxnfc *info)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ if (efx_filter_get_rx_id_limit(efx) == 0)
+ return -EOPNOTSUPP;
+
+ switch (info->cmd) {
+ case ETHTOOL_SRXCLSRLINS:
+ return efx_ethtool_set_class_rule(efx, &info->fs,
+ info->rss_context);
+
+ case ETHTOOL_SRXCLSRLDEL:
+ return efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_MANUAL,
+ info->fs.location);
+
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ if (efx->n_rx_channels == 1)
+ return 0;
+ return ARRAY_SIZE(efx->rss_context.rx_indir_table);
+}
+
+u32 efx_ethtool_get_rxfh_key_size(struct net_device *net_dev)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ return efx->type->rx_hash_key_size;
+}
+
+int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key,
+ u8 *hfunc)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int rc;
+
+ rc = efx->type->rx_pull_rss_config(efx);
+ if (rc)
+ return rc;
+
+ if (hfunc)
+ *hfunc = ETH_RSS_HASH_TOP;
+ if (indir)
+ memcpy(indir, efx->rss_context.rx_indir_table,
+ sizeof(efx->rss_context.rx_indir_table));
+ if (key)
+ memcpy(key, efx->rss_context.rx_hash_key,
+ efx->type->rx_hash_key_size);
+ return 0;
+}
+
+int efx_ethtool_set_rxfh(struct net_device *net_dev, const u32 *indir,
+ const u8 *key, const u8 hfunc)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ /* Hash function is Toeplitz, cannot be changed */
+ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
+ return -EOPNOTSUPP;
+ if (!indir && !key)
+ return 0;
+
+ if (!key)
+ key = efx->rss_context.rx_hash_key;
+ if (!indir)
+ indir = efx->rss_context.rx_indir_table;
+
+ return efx->type->rx_push_rss_config(efx, true, indir, key);
+}
+
+int efx_ethtool_get_rxfh_context(struct net_device *net_dev, u32 *indir,
+ u8 *key, u8 *hfunc, u32 rss_context)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_rss_context *ctx;
+ int rc = 0;
+
+ if (!efx->type->rx_pull_rss_context_config)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&efx->rss_lock);
+ ctx = efx_find_rss_context_entry(efx, rss_context);
+ if (!ctx) {
+ rc = -ENOENT;
+ goto out_unlock;
+ }
+ rc = efx->type->rx_pull_rss_context_config(efx, ctx);
+ if (rc)
+ goto out_unlock;
+
+ if (hfunc)
+ *hfunc = ETH_RSS_HASH_TOP;
+ if (indir)
+ memcpy(indir, ctx->rx_indir_table, sizeof(ctx->rx_indir_table));
+ if (key)
+ memcpy(key, ctx->rx_hash_key, efx->type->rx_hash_key_size);
+out_unlock:
+ mutex_unlock(&efx->rss_lock);
+ return rc;
+}
+
+int efx_ethtool_set_rxfh_context(struct net_device *net_dev,
+ const u32 *indir, const u8 *key,
+ const u8 hfunc, u32 *rss_context,
+ bool delete)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_rss_context *ctx;
+ bool allocated = false;
+ int rc;
+
+ if (!efx->type->rx_push_rss_context_config)
+ return -EOPNOTSUPP;
+ /* Hash function is Toeplitz, cannot be changed */
+ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&efx->rss_lock);
+
+ if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
+ if (delete) {
+ /* alloc + delete == Nothing to do */
+ rc = -EINVAL;
+ goto out_unlock;
+ }
+ ctx = efx_alloc_rss_context_entry(efx);
+ if (!ctx) {
+ rc = -ENOMEM;
+ goto out_unlock;
+ }
+ ctx->context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
+ /* Initialise indir table and key to defaults */
+ efx_set_default_rx_indir_table(efx, ctx);
+ netdev_rss_key_fill(ctx->rx_hash_key, sizeof(ctx->rx_hash_key));
+ allocated = true;
+ } else {
+ ctx = efx_find_rss_context_entry(efx, *rss_context);
+ if (!ctx) {
+ rc = -ENOENT;
+ goto out_unlock;
+ }
+ }
+
+ if (delete) {
+ /* delete this context */
+ rc = efx->type->rx_push_rss_context_config(efx, ctx, NULL, NULL);
+ if (!rc)
+ efx_free_rss_context_entry(ctx);
+ goto out_unlock;
+ }
+
+ if (!key)
+ key = ctx->rx_hash_key;
+ if (!indir)
+ indir = ctx->rx_indir_table;
+
+ rc = efx->type->rx_push_rss_context_config(efx, ctx, indir, key);
+ if (rc && allocated)
+ efx_free_rss_context_entry(ctx);
+ else
+ *rss_context = ctx->user_id;
+out_unlock:
+ mutex_unlock(&efx->rss_lock);
+ return rc;
+}
+
+int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int rc;
+
+ rc = efx->type->map_reset_flags(flags);
+ if (rc < 0)
+ return rc;
+
+ return efx_reset(efx, rc);
+}
+
+int efx_ethtool_get_module_eeprom(struct net_device *net_dev,
+ struct ethtool_eeprom *ee,
+ u8 *data)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int ret;
+
+ if (!efx->phy_op || !efx->phy_op->get_module_eeprom)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&efx->mac_lock);
+ ret = efx->phy_op->get_module_eeprom(efx, ee, data);
+ mutex_unlock(&efx->mac_lock);
+
+ return ret;
+}
+
+int efx_ethtool_get_module_info(struct net_device *net_dev,
+ struct ethtool_modinfo *modinfo)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int ret;
+
+ if (!efx->phy_op || !efx->phy_op->get_module_info)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&efx->mac_lock);
+ ret = efx->phy_op->get_module_info(efx, modinfo);
+ mutex_unlock(&efx->mac_lock);
+
+ return ret;
+}
diff --git a/drivers/net/ethernet/sfc/ethtool_common.h b/drivers/net/ethernet/sfc/ethtool_common.h
index fa624313f330..659491932101 100644
--- a/drivers/net/ethernet/sfc/ethtool_common.h
+++ b/drivers/net/ethernet/sfc/ethtool_common.h
@@ -15,8 +15,12 @@ void efx_ethtool_get_drvinfo(struct net_device *net_dev,
struct ethtool_drvinfo *info);
u32 efx_ethtool_get_msglevel(struct net_device *net_dev);
void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable);
+void efx_ethtool_self_test(struct net_device *net_dev,
+ struct ethtool_test *test, u64 *data);
void efx_ethtool_get_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause);
+int efx_ethtool_set_pauseparam(struct net_device *net_dev,
+ struct ethtool_pauseparam *pause);
int efx_ethtool_fill_self_tests(struct efx_nic *efx,
struct efx_self_tests *tests,
u8 *strings, u64 *data);
@@ -26,5 +30,34 @@ void efx_ethtool_get_strings(struct net_device *net_dev, u32 string_set,
void efx_ethtool_get_stats(struct net_device *net_dev,
struct ethtool_stats *stats __attribute__ ((unused)),
u64 *data);
-
+int efx_ethtool_get_link_ksettings(struct net_device *net_dev,
+ struct ethtool_link_ksettings *out);
+int efx_ethtool_set_link_ksettings(struct net_device *net_dev,
+ const struct ethtool_link_ksettings *settings);
+int efx_ethtool_get_fecparam(struct net_device *net_dev,
+ struct ethtool_fecparam *fecparam);
+int efx_ethtool_set_fecparam(struct net_device *net_dev,
+ struct ethtool_fecparam *fecparam);
+int efx_ethtool_get_rxnfc(struct net_device *net_dev,
+ struct ethtool_rxnfc *info, u32 *rule_locs);
+int efx_ethtool_set_rxnfc(struct net_device *net_dev,
+ struct ethtool_rxnfc *info);
+u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev);
+u32 efx_ethtool_get_rxfh_key_size(struct net_device *net_dev);
+int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key,
+ u8 *hfunc);
+int efx_ethtool_set_rxfh(struct net_device *net_dev,
+ const u32 *indir, const u8 *key, const u8 hfunc);
+int efx_ethtool_get_rxfh_context(struct net_device *net_dev, u32 *indir,
+ u8 *key, u8 *hfunc, u32 rss_context);
+int efx_ethtool_set_rxfh_context(struct net_device *net_dev,
+ const u32 *indir, const u8 *key,
+ const u8 hfunc, u32 *rss_context,
+ bool delete);
+int efx_ethtool_reset(struct net_device *net_dev, u32 *flags);
+int efx_ethtool_get_module_eeprom(struct net_device *net_dev,
+ struct ethtool_eeprom *ee,
+ u8 *data);
+int efx_ethtool_get_module_info(struct net_device *net_dev,
+ struct ethtool_modinfo *modinfo);
#endif
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c
index dbbb898adddb..d07eeaad9bdf 100644
--- a/drivers/net/ethernet/sfc/farch.c
+++ b/drivers/net/ethernet/sfc/farch.c
@@ -379,7 +379,7 @@ int efx_farch_tx_probe(struct efx_tx_queue *tx_queue)
void efx_farch_tx_init(struct efx_tx_queue *tx_queue)
{
- int csum = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
+ int csum = tx_queue->label & EFX_TXQ_TYPE_OFFLOAD;
struct efx_nic *efx = tx_queue->efx;
efx_oword_t reg;
@@ -395,7 +395,7 @@ void efx_farch_tx_init(struct efx_tx_queue *tx_queue)
FRF_AZ_TX_DESCQ_EVQ_ID,
tx_queue->channel->channel,
FRF_AZ_TX_DESCQ_OWNER_ID, 0,
- FRF_AZ_TX_DESCQ_LABEL, tx_queue->queue,
+ FRF_AZ_TX_DESCQ_LABEL, tx_queue->label,
FRF_AZ_TX_DESCQ_SIZE,
__ffs(tx_queue->txd.entries),
FRF_AZ_TX_DESCQ_TYPE, 0,
@@ -409,7 +409,7 @@ void efx_farch_tx_init(struct efx_tx_queue *tx_queue)
EFX_POPULATE_OWORD_1(reg,
FRF_BZ_TX_PACE,
- (tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ?
+ (tx_queue->label & EFX_TXQ_TYPE_HIGHPRI) ?
FFE_BZ_TX_PACE_OFF :
FFE_BZ_TX_PACE_RESERVED);
efx_writeo_table(efx, &reg, FR_BZ_TX_PACE_TBL, tx_queue->queue);
diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h
index c3c011bc6a68..30439cc83a89 100644
--- a/drivers/net/ethernet/sfc/io.h
+++ b/drivers/net/ethernet/sfc/io.h
@@ -75,6 +75,11 @@
#endif
#endif
+static inline u32 efx_reg(struct efx_nic *efx, unsigned int reg)
+{
+ return efx->reg_base + reg;
+}
+
#ifdef EFX_USE_QWORD_IO
static inline void _efx_writeq(struct efx_nic *efx, __le64 value,
unsigned int reg)
@@ -217,8 +222,11 @@ static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value,
efx_reado(efx, value, reg + index * sizeof(efx_oword_t));
}
-/* default VI stride (step between per-VI registers) is 8K */
-#define EFX_DEFAULT_VI_STRIDE 0x2000
+/* default VI stride (step between per-VI registers) is 8K on EF10 and
+ * 64K on EF100
+ */
+#define EFX_DEFAULT_VI_STRIDE 0x2000
+#define EF100_DEFAULT_VI_STRIDE 0x10000
/* Calculate offset to page-mapped register */
static inline unsigned int efx_paged_reg(struct efx_nic *efx, unsigned int page,
@@ -265,7 +273,9 @@ _efx_writed_page(struct efx_nic *efx, const efx_dword_t *value,
#define efx_writed_page(efx, value, reg, page) \
_efx_writed_page(efx, value, \
reg + \
- BUILD_BUG_ON_ZERO((reg) != 0x400 && \
+ BUILD_BUG_ON_ZERO((reg) != 0x180 && \
+ (reg) != 0x200 && \
+ (reg) != 0x400 && \
(reg) != 0x420 && \
(reg) != 0x830 && \
(reg) != 0x83c && \
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index a8cc3881edce..5467819aef6e 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -1299,6 +1299,14 @@ static void efx_mcdi_abandon(struct efx_nic *efx)
efx_schedule_reset(efx, RESET_TYPE_MCDI_TIMEOUT);
}
+static void efx_handle_drain_event(struct efx_nic *efx)
+{
+ if (atomic_dec_and_test(&efx->active_queues))
+ wake_up(&efx->flush_wq);
+
+ WARN_ON(atomic_read(&efx->active_queues) < 0);
+}
+
/* Called from efx_farch_ev_process and efx_ef10_ev_process for MCDI events */
void efx_mcdi_process_event(struct efx_channel *channel,
efx_qword_t *event)
@@ -1329,7 +1337,7 @@ void efx_mcdi_process_event(struct efx_channel *channel,
efx_mcdi_process_link_change(efx, event);
break;
case MCDI_EVENT_CODE_SENSOREVT:
- efx_mcdi_sensor_event(efx, event);
+ efx_sensor_event(efx, event);
break;
case MCDI_EVENT_CODE_SCHEDERR:
netif_dbg(efx, hw, efx->net_dev,
@@ -1371,7 +1379,7 @@ void efx_mcdi_process_event(struct efx_channel *channel,
BUILD_BUG_ON(MCDI_EVENT_TX_FLUSH_TO_DRIVER_LBN !=
MCDI_EVENT_RX_FLUSH_TO_DRIVER_LBN);
if (!MCDI_EVENT_FIELD(*event, TX_FLUSH_TO_DRIVER))
- efx_ef10_handle_drain_event(efx);
+ efx_handle_drain_event(efx);
break;
case MCDI_EVENT_CODE_TX_ERR:
case MCDI_EVENT_CODE_RX_ERR:
@@ -1613,6 +1621,35 @@ fail:
return rc;
}
+/* This function finds types using the new NVRAM_PARTITIONS mcdi. */
+static int efx_new_mcdi_nvram_types(struct efx_nic *efx, u32 *number,
+ u32 *nvram_types)
+{
+ efx_dword_t *outbuf = kzalloc(MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2,
+ GFP_KERNEL);
+ size_t outlen;
+ int rc;
+
+ if (!outbuf)
+ return -ENOMEM;
+
+ BUILD_BUG_ON(MC_CMD_NVRAM_PARTITIONS_IN_LEN != 0);
+
+ rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_PARTITIONS, NULL, 0,
+ outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2, &outlen);
+ if (rc)
+ goto fail;
+
+ *number = MCDI_DWORD(outbuf, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
+
+ memcpy(nvram_types, MCDI_PTR(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID),
+ *number * sizeof(u32));
+
+fail:
+ kfree(outbuf);
+ return rc;
+}
+
int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
size_t *size_out, size_t *erase_size_out,
bool *protected_out)
@@ -1666,6 +1703,39 @@ static int efx_mcdi_nvram_test(struct efx_nic *efx, unsigned int type)
}
}
+/* This function tests nvram partitions using the new mcdi partition lookup scheme */
+int efx_new_mcdi_nvram_test_all(struct efx_nic *efx)
+{
+ u32 *nvram_types = kzalloc(MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2,
+ GFP_KERNEL);
+ unsigned int number;
+ int rc, i;
+
+ if (!nvram_types)
+ return -ENOMEM;
+
+ rc = efx_new_mcdi_nvram_types(efx, &number, nvram_types);
+ if (rc)
+ goto fail;
+
+ /* Require at least one check */
+ rc = -EAGAIN;
+
+ for (i = 0; i < number; i++) {
+ if (nvram_types[i] == NVRAM_PARTITION_TYPE_PARTITION_MAP ||
+ nvram_types[i] == NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG)
+ continue;
+
+ rc = efx_mcdi_nvram_test(efx, nvram_types[i]);
+ if (rc)
+ goto fail;
+ }
+
+fail:
+ kfree(nvram_types);
+ return rc;
+}
+
int efx_mcdi_nvram_test_all(struct efx_nic *efx)
{
u32 nvram_types;
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index b107e4c00285..658cf345420d 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -327,15 +327,14 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
#define MCDI_CAPABILITY(field) \
- MC_CMD_GET_CAPABILITIES_V4_OUT_ ## field ## _LBN
+ MC_CMD_GET_CAPABILITIES_V8_OUT_ ## field ## _LBN
#define MCDI_CAPABILITY_OFST(field) \
- MC_CMD_GET_CAPABILITIES_V4_OUT_ ## field ## _OFST
+ MC_CMD_GET_CAPABILITIES_V8_OUT_ ## field ## _OFST
-/* field is FLAGS1 or FLAGS2 */
-#define efx_has_cap(efx, flag, field) \
+#define efx_has_cap(efx, field) \
efx->type->check_caps(efx, \
- MCDI_CAPABILITY(flag), \
+ MCDI_CAPABILITY(field), \
MCDI_CAPABILITY_OFST(field))
void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len);
@@ -346,6 +345,7 @@ int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out);
int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
size_t *size_out, size_t *erase_size_out,
bool *protected_out);
+int efx_new_mcdi_nvram_test_all(struct efx_nic *efx);
int efx_mcdi_nvram_test_all(struct efx_nic *efx);
int efx_mcdi_handle_assertion(struct efx_nic *efx);
void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
@@ -355,15 +355,11 @@ int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out);
int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id);
int efx_mcdi_wol_filter_reset(struct efx_nic *efx);
int efx_mcdi_flush_rxqs(struct efx_nic *efx);
-int efx_mcdi_port_probe(struct efx_nic *efx);
-void efx_mcdi_port_remove(struct efx_nic *efx);
int efx_mcdi_port_reconfigure(struct efx_nic *efx);
-u32 efx_mcdi_phy_get_caps(struct efx_nic *efx);
void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev);
void efx_mcdi_mac_start_stats(struct efx_nic *efx);
void efx_mcdi_mac_stop_stats(struct efx_nic *efx);
void efx_mcdi_mac_pull_stats(struct efx_nic *efx);
-bool efx_mcdi_mac_check_fault(struct efx_nic *efx);
enum reset_type efx_mcdi_map_reset_reason(enum reset_type reason);
int efx_mcdi_reset(struct efx_nic *efx, enum reset_type method);
int efx_mcdi_set_workaround(struct efx_nic *efx, u32 type, bool enabled,
diff --git a/drivers/net/ethernet/sfc/mcdi_filters.c b/drivers/net/ethernet/sfc/mcdi_filters.c
index 455a62814fb9..5a74d880b733 100644
--- a/drivers/net/ethernet/sfc/mcdi_filters.c
+++ b/drivers/net/ethernet/sfc/mcdi_filters.c
@@ -1,3 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2005-2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
#include "mcdi_filters.h"
#include "mcdi.h"
#include "nic.h"
@@ -828,7 +839,7 @@ static int efx_mcdi_filter_insert_def(struct efx_nic *efx,
efx_filter_set_uc_def(&spec);
if (encap_type) {
- if (efx_has_cap(efx, VXLAN_NVGRE, FLAGS1))
+ if (efx_has_cap(efx, VXLAN_NVGRE))
efx_filter_set_encap_type(&spec, encap_type);
else
/*
@@ -1304,7 +1315,7 @@ int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining)
rc = efx_mcdi_filter_table_probe_matches(efx, table, false);
if (rc)
goto fail;
- if (efx_has_cap(efx, VXLAN_NVGRE, FLAGS1))
+ if (efx_has_cap(efx, VXLAN_NVGRE))
rc = efx_mcdi_filter_table_probe_matches(efx, table, true);
if (rc)
goto fail;
@@ -1448,7 +1459,7 @@ not_restored:
table->must_restore_filters = false;
}
-void efx_mcdi_filter_table_remove(struct efx_nic *efx)
+void efx_mcdi_filter_table_down(struct efx_nic *efx)
{
struct efx_mcdi_filter_table *table = efx->filter_state;
MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
@@ -1456,21 +1467,11 @@ void efx_mcdi_filter_table_remove(struct efx_nic *efx)
unsigned int filter_idx;
int rc;
- efx_mcdi_filter_cleanup_vlans(efx);
- efx->filter_state = NULL;
- /*
- * If we were called without locking, then it's not safe to free
- * the table as others might be using it. So we just WARN, leak
- * the memory, and potentially get an inconsistent filter table
- * state.
- * This should never actually happen.
- */
- if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
- return;
-
if (!table)
return;
+ efx_mcdi_filter_cleanup_vlans(efx);
+
for (filter_idx = 0; filter_idx < EFX_MCDI_FILTER_TBL_ROWS; filter_idx++) {
spec = efx_mcdi_filter_entry_spec(table, filter_idx);
if (!spec)
@@ -1490,6 +1491,27 @@ void efx_mcdi_filter_table_remove(struct efx_nic *efx)
__func__, filter_idx);
kfree(spec);
}
+}
+
+void efx_mcdi_filter_table_remove(struct efx_nic *efx)
+{
+ struct efx_mcdi_filter_table *table = efx->filter_state;
+
+ efx_mcdi_filter_table_down(efx);
+
+ efx->filter_state = NULL;
+ /*
+ * If we were called without locking, then it's not safe to free
+ * the table as others might be using it. So we just WARN, leak
+ * the memory, and potentially get an inconsistent filter table
+ * state.
+ * This should never actually happen.
+ */
+ if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
+ return;
+
+ if (!table)
+ return;
vfree(table->entry);
kfree(table);
@@ -1927,7 +1949,7 @@ static int efx_mcdi_filter_alloc_rss_context(struct efx_nic *efx, bool exclusive
return 0;
}
- if (efx_has_cap(efx, RX_RSS_LIMITED, FLAGS1))
+ if (efx_has_cap(efx, RX_RSS_LIMITED))
return -EOPNOTSUPP;
MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID,
@@ -1948,7 +1970,7 @@ static int efx_mcdi_filter_alloc_rss_context(struct efx_nic *efx, bool exclusive
if (context_size)
*context_size = rss_spread;
- if (efx_has_cap(efx, ADDITIONAL_RSS_MODES, FLAGS1))
+ if (efx_has_cap(efx, ADDITIONAL_RSS_MODES))
efx_mcdi_set_rss_context_flags(efx, ctx);
return 0;
@@ -2254,3 +2276,24 @@ int efx_mcdi_vf_rx_push_rss_config(struct efx_nic *efx, bool user,
return 0;
return efx_mcdi_filter_rx_push_shared_rss_config(efx, NULL);
}
+
+int efx_mcdi_push_default_indir_table(struct efx_nic *efx,
+ unsigned int rss_spread)
+{
+ int rc = 0;
+
+ if (efx->rss_spread == rss_spread)
+ return 0;
+
+ efx->rss_spread = rss_spread;
+ if (!efx->filter_state)
+ return 0;
+
+ efx_mcdi_rx_free_indir_table(efx);
+ if (rss_spread > 1) {
+ efx_set_default_rx_indir_table(efx, &efx->rss_context);
+ rc = efx->type->rx_push_rss_config(efx, false,
+ efx->rss_context.rx_indir_table, NULL);
+ }
+ return rc;
+}
diff --git a/drivers/net/ethernet/sfc/mcdi_filters.h b/drivers/net/ethernet/sfc/mcdi_filters.h
index 03a8bf74c733..06426aa9f2f3 100644
--- a/drivers/net/ethernet/sfc/mcdi_filters.h
+++ b/drivers/net/ethernet/sfc/mcdi_filters.h
@@ -93,6 +93,7 @@ struct efx_mcdi_filter_table {
};
int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining);
+void efx_mcdi_filter_table_down(struct efx_nic *efx);
void efx_mcdi_filter_table_remove(struct efx_nic *efx);
void efx_mcdi_filter_table_restore(struct efx_nic *efx);
@@ -154,6 +155,8 @@ int efx_mcdi_vf_rx_push_rss_config(struct efx_nic *efx, bool user,
__attribute__ ((unused)),
const u8 *key
__attribute__ ((unused)));
+int efx_mcdi_push_default_indir_table(struct efx_nic *efx,
+ unsigned int rss_spread);
int efx_mcdi_rx_pull_rss_config(struct efx_nic *efx);
int efx_mcdi_rx_pull_rss_context_config(struct efx_nic *efx,
struct efx_rss_context *ctx);
diff --git a/drivers/net/ethernet/sfc/mcdi_functions.c b/drivers/net/ethernet/sfc/mcdi_functions.c
index 962d8395d958..d8a3af86ef78 100644
--- a/drivers/net/ethernet/sfc/mcdi_functions.c
+++ b/drivers/net/ethernet/sfc/mcdi_functions.c
@@ -164,7 +164,7 @@ int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue, bool tso_v2)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_TXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 /
EFX_BUF_SIZE));
- bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
+ bool csum_offload = tx_queue->label & EFX_TXQ_TYPE_OFFLOAD;
size_t entries = tx_queue->txd.buf.len / EFX_BUF_SIZE;
struct efx_channel *channel = tx_queue->channel;
struct efx_nic *efx = tx_queue->efx;
@@ -176,7 +176,7 @@ int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue, bool tso_v2)
MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_SIZE, tx_queue->ptr_mask + 1);
MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_TARGET_EVQ, channel->channel);
- MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_LABEL, tx_queue->queue);
+ MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_LABEL, tx_queue->label);
MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_INSTANCE, tx_queue->queue);
MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_OWNER_ID, 0);
MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_PORT_ID, efx->vport_id);
@@ -267,20 +267,22 @@ int efx_mcdi_rx_probe(struct efx_rx_queue *rx_queue)
void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue)
{
- MCDI_DECLARE_BUF(inbuf,
- MC_CMD_INIT_RXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 /
- EFX_BUF_SIZE));
struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
size_t entries = rx_queue->rxd.buf.len / EFX_BUF_SIZE;
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_RXQ_V4_IN_LEN);
struct efx_nic *efx = rx_queue->efx;
+ unsigned int buffer_size;
dma_addr_t dma_addr;
- size_t inlen;
int rc;
int i;
BUILD_BUG_ON(MC_CMD_INIT_RXQ_OUT_LEN != 0);
rx_queue->scatter_n = 0;
rx_queue->scatter_len = 0;
+ if (efx->type->revision == EFX_REV_EF100)
+ buffer_size = efx->rx_page_buf_step;
+ else
+ buffer_size = 0;
MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_SIZE, rx_queue->ptr_mask + 1);
MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_TARGET_EVQ, channel->channel);
@@ -292,6 +294,7 @@ void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue)
INIT_RXQ_IN_FLAG_TIMESTAMP, 1);
MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_OWNER_ID, 0);
MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_PORT_ID, efx->vport_id);
+ MCDI_SET_DWORD(inbuf, INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES, buffer_size);
dma_addr = rx_queue->rxd.buf.dma_addr;
@@ -303,9 +306,7 @@ void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue)
dma_addr += EFX_BUF_SIZE;
}
- inlen = MC_CMD_INIT_RXQ_IN_LEN(entries);
-
- rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen,
+ rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, sizeof(inbuf),
NULL, 0, NULL);
if (rc)
netdev_WARN(efx->net_dev, "failed to initialise RXQ %d\n",
@@ -341,6 +342,44 @@ fail:
outbuf, outlen, rc);
}
+int efx_fini_dmaq(struct efx_nic *efx)
+{
+ struct efx_tx_queue *tx_queue;
+ struct efx_rx_queue *rx_queue;
+ struct efx_channel *channel;
+ int pending;
+
+ /* If the MC has just rebooted, the TX/RX queues will have already been
+ * torn down, but efx->active_queues needs to be set to zero.
+ */
+ if (efx->must_realloc_vis) {
+ atomic_set(&efx->active_queues, 0);
+ return 0;
+ }
+
+ /* Do not attempt to write to the NIC during EEH recovery */
+ if (efx->state != STATE_RECOVERY) {
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_rx_queue(rx_queue, channel)
+ efx_mcdi_rx_fini(rx_queue);
+ efx_for_each_channel_tx_queue(tx_queue, channel)
+ efx_mcdi_tx_fini(tx_queue);
+ }
+
+ wait_event_timeout(efx->flush_wq,
+ atomic_read(&efx->active_queues) == 0,
+ msecs_to_jiffies(EFX_MAX_FLUSH_TIME));
+ pending = atomic_read(&efx->active_queues);
+ if (pending) {
+ netif_err(efx, hw, efx->net_dev, "failed to flush %d queues\n",
+ pending);
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
int efx_mcdi_window_mode_to_stride(struct efx_nic *efx, u8 vi_window_mode)
{
switch (vi_window_mode) {
diff --git a/drivers/net/ethernet/sfc/mcdi_functions.h b/drivers/net/ethernet/sfc/mcdi_functions.h
index ca4a5ac1a66b..687be8b00cd8 100644
--- a/drivers/net/ethernet/sfc/mcdi_functions.h
+++ b/drivers/net/ethernet/sfc/mcdi_functions.h
@@ -26,6 +26,7 @@ int efx_mcdi_rx_probe(struct efx_rx_queue *rx_queue);
void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue);
void efx_mcdi_rx_remove(struct efx_rx_queue *rx_queue);
void efx_mcdi_rx_fini(struct efx_rx_queue *rx_queue);
+int efx_fini_dmaq(struct efx_nic *efx);
int efx_mcdi_window_mode_to_stride(struct efx_nic *efx, u8 vi_window_mode);
int efx_get_pf_index(struct efx_nic *efx, unsigned int *pf_index);
diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h
index 79d834a4ae49..d3fcbf930dba 100644
--- a/drivers/net/ethernet/sfc/mcdi_pcol.h
+++ b/drivers/net/ethernet/sfc/mcdi_pcol.h
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/****************************************************************************
* Driver for Solarflare network controllers and boards
- * Copyright 2009-2013 Solarflare Communications Inc.
+ * Copyright 2009-2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
*/
@@ -383,14 +384,19 @@
#define MCDI_EVENT_LEVEL_FATAL 0x3
#define MCDI_EVENT_DATA_OFST 0
#define MCDI_EVENT_DATA_LEN 4
+#define MCDI_EVENT_CMDDONE_SEQ_OFST 0
#define MCDI_EVENT_CMDDONE_SEQ_LBN 0
#define MCDI_EVENT_CMDDONE_SEQ_WIDTH 8
+#define MCDI_EVENT_CMDDONE_DATALEN_OFST 0
#define MCDI_EVENT_CMDDONE_DATALEN_LBN 8
#define MCDI_EVENT_CMDDONE_DATALEN_WIDTH 8
+#define MCDI_EVENT_CMDDONE_ERRNO_OFST 0
#define MCDI_EVENT_CMDDONE_ERRNO_LBN 16
#define MCDI_EVENT_CMDDONE_ERRNO_WIDTH 8
+#define MCDI_EVENT_LINKCHANGE_LP_CAP_OFST 0
#define MCDI_EVENT_LINKCHANGE_LP_CAP_LBN 0
#define MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16
+#define MCDI_EVENT_LINKCHANGE_SPEED_OFST 0
#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16
#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4
/* enum: Link is down or link speed could not be determined */
@@ -409,26 +415,36 @@
#define MCDI_EVENT_LINKCHANGE_SPEED_50G 0x6
/* enum: 100Gbs */
#define MCDI_EVENT_LINKCHANGE_SPEED_100G 0x7
+#define MCDI_EVENT_LINKCHANGE_FCNTL_OFST 0
#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20
#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4
+#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_OFST 0
#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24
#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_WIDTH 8
+#define MCDI_EVENT_SENSOREVT_MONITOR_OFST 0
#define MCDI_EVENT_SENSOREVT_MONITOR_LBN 0
#define MCDI_EVENT_SENSOREVT_MONITOR_WIDTH 8
+#define MCDI_EVENT_SENSOREVT_STATE_OFST 0
#define MCDI_EVENT_SENSOREVT_STATE_LBN 8
#define MCDI_EVENT_SENSOREVT_STATE_WIDTH 8
+#define MCDI_EVENT_SENSOREVT_VALUE_OFST 0
#define MCDI_EVENT_SENSOREVT_VALUE_LBN 16
#define MCDI_EVENT_SENSOREVT_VALUE_WIDTH 16
+#define MCDI_EVENT_FWALERT_DATA_OFST 0
#define MCDI_EVENT_FWALERT_DATA_LBN 8
#define MCDI_EVENT_FWALERT_DATA_WIDTH 24
+#define MCDI_EVENT_FWALERT_REASON_OFST 0
#define MCDI_EVENT_FWALERT_REASON_LBN 0
#define MCDI_EVENT_FWALERT_REASON_WIDTH 8
/* enum: SRAM Access. */
#define MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS 0x1
+#define MCDI_EVENT_FLR_VF_OFST 0
#define MCDI_EVENT_FLR_VF_LBN 0
#define MCDI_EVENT_FLR_VF_WIDTH 8
+#define MCDI_EVENT_TX_ERR_TXQ_OFST 0
#define MCDI_EVENT_TX_ERR_TXQ_LBN 0
#define MCDI_EVENT_TX_ERR_TXQ_WIDTH 12
+#define MCDI_EVENT_TX_ERR_TYPE_OFST 0
#define MCDI_EVENT_TX_ERR_TYPE_LBN 12
#define MCDI_EVENT_TX_ERR_TYPE_WIDTH 4
/* enum: Descriptor loader reported failure */
@@ -443,12 +459,16 @@
#define MCDI_EVENT_TX_OPT_IN_PKT 0x8
/* enum: DMA or PIO data access error */
#define MCDI_EVENT_TX_ERR_BAD_DMA_OR_PIO 0x9
+#define MCDI_EVENT_TX_ERR_INFO_OFST 0
#define MCDI_EVENT_TX_ERR_INFO_LBN 16
#define MCDI_EVENT_TX_ERR_INFO_WIDTH 16
+#define MCDI_EVENT_TX_FLUSH_TO_DRIVER_OFST 0
#define MCDI_EVENT_TX_FLUSH_TO_DRIVER_LBN 12
#define MCDI_EVENT_TX_FLUSH_TO_DRIVER_WIDTH 1
+#define MCDI_EVENT_TX_FLUSH_TXQ_OFST 0
#define MCDI_EVENT_TX_FLUSH_TXQ_LBN 0
#define MCDI_EVENT_TX_FLUSH_TXQ_WIDTH 12
+#define MCDI_EVENT_PTP_ERR_TYPE_OFST 0
#define MCDI_EVENT_PTP_ERR_TYPE_LBN 0
#define MCDI_EVENT_PTP_ERR_TYPE_WIDTH 8
/* enum: PLL lost lock */
@@ -459,6 +479,7 @@
#define MCDI_EVENT_PTP_ERR_FIFO 0x3
/* enum: Merge queue overflow */
#define MCDI_EVENT_PTP_ERR_QUEUE 0x4
+#define MCDI_EVENT_AOE_ERR_TYPE_OFST 0
#define MCDI_EVENT_AOE_ERR_TYPE_LBN 0
#define MCDI_EVENT_AOE_ERR_TYPE_WIDTH 8
/* enum: AOE failed to load - no valid image? */
@@ -505,8 +526,10 @@
#define MCDI_EVENT_AOE_FPGA_CLOCKS_PROGRAM_FAILED 0x13
/* enum: Notify that FPGA Controller is alive to serve MCDI requests */
#define MCDI_EVENT_AOE_FC_RUNNING 0x14
+#define MCDI_EVENT_AOE_ERR_DATA_OFST 0
#define MCDI_EVENT_AOE_ERR_DATA_LBN 8
#define MCDI_EVENT_AOE_ERR_DATA_WIDTH 8
+#define MCDI_EVENT_AOE_ERR_FC_ASSERT_INFO_OFST 0
#define MCDI_EVENT_AOE_ERR_FC_ASSERT_INFO_LBN 8
#define MCDI_EVENT_AOE_ERR_FC_ASSERT_INFO_WIDTH 8
/* enum: FC Assert happened, but the register information is not available */
@@ -514,6 +537,7 @@
/* enum: The register information for FC Assert is ready for readinng by driver
*/
#define MCDI_EVENT_AOE_ERR_FC_ASSERT_DATA_READY 0x1
+#define MCDI_EVENT_AOE_ERR_CODE_FPGA_HEADER_VERIFY_FAILED_OFST 0
#define MCDI_EVENT_AOE_ERR_CODE_FPGA_HEADER_VERIFY_FAILED_LBN 8
#define MCDI_EVENT_AOE_ERR_CODE_FPGA_HEADER_VERIFY_FAILED_WIDTH 8
/* enum: Reading from NV failed */
@@ -534,28 +558,38 @@
#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_DDR_SIZE 0x7
/* enum: Unsupported DDR rank */
#define MCDI_EVENT_AOE_ERR_FPGA_HEADER_DDR_RANK 0x8
+#define MCDI_EVENT_AOE_ERR_CODE_INVALID_FPGA_FLASH_TYPE_INFO_OFST 0
#define MCDI_EVENT_AOE_ERR_CODE_INVALID_FPGA_FLASH_TYPE_INFO_LBN 8
#define MCDI_EVENT_AOE_ERR_CODE_INVALID_FPGA_FLASH_TYPE_INFO_WIDTH 8
/* enum: Primary boot flash */
#define MCDI_EVENT_AOE_FLASH_TYPE_BOOT_PRIMARY 0x0
/* enum: Secondary boot flash */
#define MCDI_EVENT_AOE_FLASH_TYPE_BOOT_SECONDARY 0x1
+#define MCDI_EVENT_AOE_ERR_CODE_FPGA_POWER_OFF_OFST 0
#define MCDI_EVENT_AOE_ERR_CODE_FPGA_POWER_OFF_LBN 8
#define MCDI_EVENT_AOE_ERR_CODE_FPGA_POWER_OFF_WIDTH 8
+#define MCDI_EVENT_AOE_ERR_CODE_FPGA_LOAD_FAILED_OFST 0
#define MCDI_EVENT_AOE_ERR_CODE_FPGA_LOAD_FAILED_LBN 8
#define MCDI_EVENT_AOE_ERR_CODE_FPGA_LOAD_FAILED_WIDTH 8
+#define MCDI_EVENT_RX_ERR_RXQ_OFST 0
#define MCDI_EVENT_RX_ERR_RXQ_LBN 0
#define MCDI_EVENT_RX_ERR_RXQ_WIDTH 12
+#define MCDI_EVENT_RX_ERR_TYPE_OFST 0
#define MCDI_EVENT_RX_ERR_TYPE_LBN 12
#define MCDI_EVENT_RX_ERR_TYPE_WIDTH 4
+#define MCDI_EVENT_RX_ERR_INFO_OFST 0
#define MCDI_EVENT_RX_ERR_INFO_LBN 16
#define MCDI_EVENT_RX_ERR_INFO_WIDTH 16
+#define MCDI_EVENT_RX_FLUSH_TO_DRIVER_OFST 0
#define MCDI_EVENT_RX_FLUSH_TO_DRIVER_LBN 12
#define MCDI_EVENT_RX_FLUSH_TO_DRIVER_WIDTH 1
+#define MCDI_EVENT_RX_FLUSH_RXQ_OFST 0
#define MCDI_EVENT_RX_FLUSH_RXQ_LBN 0
#define MCDI_EVENT_RX_FLUSH_RXQ_WIDTH 12
+#define MCDI_EVENT_MC_REBOOT_COUNT_OFST 0
#define MCDI_EVENT_MC_REBOOT_COUNT_LBN 0
#define MCDI_EVENT_MC_REBOOT_COUNT_WIDTH 16
+#define MCDI_EVENT_MUM_ERR_TYPE_OFST 0
#define MCDI_EVENT_MUM_ERR_TYPE_LBN 0
#define MCDI_EVENT_MUM_ERR_TYPE_WIDTH 8
/* enum: MUM failed to load - no valid image? */
@@ -564,10 +598,13 @@
#define MCDI_EVENT_MUM_ASSERT 0x2
/* enum: MUM not kicking watchdog */
#define MCDI_EVENT_MUM_WATCHDOG 0x3
+#define MCDI_EVENT_MUM_ERR_DATA_OFST 0
#define MCDI_EVENT_MUM_ERR_DATA_LBN 8
#define MCDI_EVENT_MUM_ERR_DATA_WIDTH 8
+#define MCDI_EVENT_DBRET_SEQ_OFST 0
#define MCDI_EVENT_DBRET_SEQ_LBN 0
#define MCDI_EVENT_DBRET_SEQ_WIDTH 8
+#define MCDI_EVENT_SUC_ERR_TYPE_OFST 0
#define MCDI_EVENT_SUC_ERR_TYPE_LBN 0
#define MCDI_EVENT_SUC_ERR_TYPE_WIDTH 8
/* enum: Corrupted or bad SUC application. */
@@ -578,14 +615,48 @@
#define MCDI_EVENT_SUC_EXCEPTION 0x3
/* enum: SUC watchdog timer expired. */
#define MCDI_EVENT_SUC_WATCHDOG 0x4
+#define MCDI_EVENT_SUC_ERR_ADDRESS_OFST 0
#define MCDI_EVENT_SUC_ERR_ADDRESS_LBN 8
#define MCDI_EVENT_SUC_ERR_ADDRESS_WIDTH 24
+#define MCDI_EVENT_SUC_ERR_DATA_OFST 0
#define MCDI_EVENT_SUC_ERR_DATA_LBN 8
#define MCDI_EVENT_SUC_ERR_DATA_WIDTH 24
+#define MCDI_EVENT_LINKCHANGE_V2_LP_CAP_OFST 0
+#define MCDI_EVENT_LINKCHANGE_V2_LP_CAP_LBN 0
+#define MCDI_EVENT_LINKCHANGE_V2_LP_CAP_WIDTH 24
+#define MCDI_EVENT_LINKCHANGE_V2_SPEED_OFST 0
+#define MCDI_EVENT_LINKCHANGE_V2_SPEED_LBN 24
+#define MCDI_EVENT_LINKCHANGE_V2_SPEED_WIDTH 4
+/* Enum values, see field(s): */
+/* MCDI_EVENT/LINKCHANGE_SPEED */
+#define MCDI_EVENT_LINKCHANGE_V2_FLAGS_LINK_UP_OFST 0
+#define MCDI_EVENT_LINKCHANGE_V2_FLAGS_LINK_UP_LBN 28
+#define MCDI_EVENT_LINKCHANGE_V2_FLAGS_LINK_UP_WIDTH 1
+#define MCDI_EVENT_LINKCHANGE_V2_FCNTL_OFST 0
+#define MCDI_EVENT_LINKCHANGE_V2_FCNTL_LBN 29
+#define MCDI_EVENT_LINKCHANGE_V2_FCNTL_WIDTH 3
+/* Enum values, see field(s): */
+/* MC_CMD_SET_MAC/MC_CMD_SET_MAC_IN/FCNTL */
+#define MCDI_EVENT_MODULECHANGE_LD_CAP_OFST 0
+#define MCDI_EVENT_MODULECHANGE_LD_CAP_LBN 0
+#define MCDI_EVENT_MODULECHANGE_LD_CAP_WIDTH 30
+#define MCDI_EVENT_MODULECHANGE_SEQ_OFST 0
+#define MCDI_EVENT_MODULECHANGE_SEQ_LBN 30
+#define MCDI_EVENT_MODULECHANGE_SEQ_WIDTH 2
#define MCDI_EVENT_DATA_LBN 0
#define MCDI_EVENT_DATA_WIDTH 32
+/* Alias for PTP_DATA. */
#define MCDI_EVENT_SRC_LBN 36
#define MCDI_EVENT_SRC_WIDTH 8
+/* Data associated with PTP events which doesn't fit into the main DATA field
+ */
+#define MCDI_EVENT_PTP_DATA_LBN 36
+#define MCDI_EVENT_PTP_DATA_WIDTH 8
+/* EF100 specific. Defined by QDMA. The phase bit, changes each time round the
+ * event ring
+ */
+#define MCDI_EVENT_EV_EVQ_PHASE_LBN 59
+#define MCDI_EVENT_EV_EVQ_PHASE_WIDTH 1
#define MCDI_EVENT_EV_CODE_LBN 60
#define MCDI_EVENT_EV_CODE_WIDTH 4
#define MCDI_EVENT_CODE_LBN 44
@@ -660,6 +731,48 @@
#define MCDI_EVENT_CODE_DBRET 0x1e
/* enum: The MC has detected a fault on the SUC */
#define MCDI_EVENT_CODE_SUC 0x1f
+/* enum: Link change. This event is sent instead of LINKCHANGE if
+ * WANT_V2_LINKCHANGES was set on driver attach.
+ */
+#define MCDI_EVENT_CODE_LINKCHANGE_V2 0x20
+/* enum: This event is sent if WANT_V2_LINKCHANGES was set on driver attach
+ * when the local device capabilities changes. This will usually correspond to
+ * a module change.
+ */
+#define MCDI_EVENT_CODE_MODULECHANGE 0x21
+/* enum: Notification that the sensors have been added and/or removed from the
+ * sensor table. This event includes the new sensor table generation count, if
+ * this does not match the driver's local copy it is expected to call
+ * DYNAMIC_SENSORS_LIST to refresh it.
+ */
+#define MCDI_EVENT_CODE_DYNAMIC_SENSORS_CHANGE 0x22
+/* enum: Notification that a sensor has changed state as a result of a reading
+ * crossing a threshold. This is sent as two events, the first event contains
+ * the handle and the sensor's state (in the SRC field), and the second
+ * contains the value.
+ */
+#define MCDI_EVENT_CODE_DYNAMIC_SENSORS_STATE_CHANGE 0x23
+/* enum: Notification that a descriptor proxy function configuration has been
+ * pushed to "live" status (visible to host). SRC field contains the handle of
+ * the affected descriptor proxy function. DATA field contains the generation
+ * count of configuration set applied. See MC_CMD_DESC_PROXY_FUNC_CONFIG_SET /
+ * MC_CMD_DESC_PROXY_FUNC_CONFIG_COMMIT and SF-122927-TC for details.
+ */
+#define MCDI_EVENT_CODE_DESC_PROXY_FUNC_CONFIG_COMMITTED 0x24
+/* enum: Notification that a descriptor proxy function has been reset. SRC
+ * field contains the handle of the affected descriptor proxy function. See
+ * SF-122927-TC for details.
+ */
+#define MCDI_EVENT_CODE_DESC_PROXY_FUNC_RESET 0x25
+/* enum: Notification that a driver attached to a descriptor proxy function.
+ * SRC field contains the handle of the affected descriptor proxy function. For
+ * Virtio proxy functions this message consists of two MCDI events, where the
+ * first event's (CONT=1) DATA field carries negotiated virtio feature bits 0
+ * to 31 and the second (CONT=0) carries bits 32 to 63. For EF100 proxy
+ * functions event length and meaning of DATA field is not yet defined. See
+ * SF-122927-TC for details.
+ */
+#define MCDI_EVENT_CODE_DESC_PROXY_FUNC_DRIVER_ATTACH 0x26
/* enum: Artificial event generated by host and posted via MC for test
* purposes.
*/
@@ -785,6 +898,48 @@
#define MCDI_EVENT_DBRET_DATA_LEN 4
#define MCDI_EVENT_DBRET_DATA_LBN 0
#define MCDI_EVENT_DBRET_DATA_WIDTH 32
+#define MCDI_EVENT_LINKCHANGE_V2_DATA_OFST 0
+#define MCDI_EVENT_LINKCHANGE_V2_DATA_LEN 4
+#define MCDI_EVENT_LINKCHANGE_V2_DATA_LBN 0
+#define MCDI_EVENT_LINKCHANGE_V2_DATA_WIDTH 32
+#define MCDI_EVENT_MODULECHANGE_DATA_OFST 0
+#define MCDI_EVENT_MODULECHANGE_DATA_LEN 4
+#define MCDI_EVENT_MODULECHANGE_DATA_LBN 0
+#define MCDI_EVENT_MODULECHANGE_DATA_WIDTH 32
+/* The new generation count after a sensor has been added or deleted. */
+#define MCDI_EVENT_DYNAMIC_SENSORS_GENERATION_OFST 0
+#define MCDI_EVENT_DYNAMIC_SENSORS_GENERATION_LEN 4
+#define MCDI_EVENT_DYNAMIC_SENSORS_GENERATION_LBN 0
+#define MCDI_EVENT_DYNAMIC_SENSORS_GENERATION_WIDTH 32
+/* The handle of a dynamic sensor. */
+#define MCDI_EVENT_DYNAMIC_SENSORS_HANDLE_OFST 0
+#define MCDI_EVENT_DYNAMIC_SENSORS_HANDLE_LEN 4
+#define MCDI_EVENT_DYNAMIC_SENSORS_HANDLE_LBN 0
+#define MCDI_EVENT_DYNAMIC_SENSORS_HANDLE_WIDTH 32
+/* The current values of a sensor. */
+#define MCDI_EVENT_DYNAMIC_SENSORS_VALUE_OFST 0
+#define MCDI_EVENT_DYNAMIC_SENSORS_VALUE_LEN 4
+#define MCDI_EVENT_DYNAMIC_SENSORS_VALUE_LBN 0
+#define MCDI_EVENT_DYNAMIC_SENSORS_VALUE_WIDTH 32
+/* The current state of a sensor. */
+#define MCDI_EVENT_DYNAMIC_SENSORS_STATE_LBN 36
+#define MCDI_EVENT_DYNAMIC_SENSORS_STATE_WIDTH 8
+#define MCDI_EVENT_DESC_PROXY_DATA_OFST 0
+#define MCDI_EVENT_DESC_PROXY_DATA_LEN 4
+#define MCDI_EVENT_DESC_PROXY_DATA_LBN 0
+#define MCDI_EVENT_DESC_PROXY_DATA_WIDTH 32
+/* Generation count of applied configuration set */
+#define MCDI_EVENT_DESC_PROXY_GENERATION_OFST 0
+#define MCDI_EVENT_DESC_PROXY_GENERATION_LEN 4
+#define MCDI_EVENT_DESC_PROXY_GENERATION_LBN 0
+#define MCDI_EVENT_DESC_PROXY_GENERATION_WIDTH 32
+/* Virtio features negotiated with the host driver. First event (CONT=1)
+ * carries bits 0 to 31. Second event (CONT=0) carries bits 32 to 63.
+ */
+#define MCDI_EVENT_DESC_PROXY_VIRTIO_FEATURES_OFST 0
+#define MCDI_EVENT_DESC_PROXY_VIRTIO_FEATURES_LEN 4
+#define MCDI_EVENT_DESC_PROXY_VIRTIO_FEATURES_LBN 0
+#define MCDI_EVENT_DESC_PROXY_VIRTIO_FEATURES_WIDTH 32
/* FCDI_EVENT structuredef */
#define FCDI_EVENT_LEN 8
@@ -802,6 +957,7 @@
#define FCDI_EVENT_LEVEL_FATAL 0x3
#define FCDI_EVENT_DATA_OFST 0
#define FCDI_EVENT_DATA_LEN 4
+#define FCDI_EVENT_LINK_STATE_STATUS_OFST 0
#define FCDI_EVENT_LINK_STATE_STATUS_LBN 0
#define FCDI_EVENT_LINK_STATE_STATUS_WIDTH 1
#define FCDI_EVENT_LINK_DOWN 0x0 /* enum */
@@ -892,7 +1048,9 @@
*/
#define FCDI_EXTENDED_EVENT_PPS_LENMIN 16
#define FCDI_EXTENDED_EVENT_PPS_LENMAX 248
+#define FCDI_EXTENDED_EVENT_PPS_LENMAX_MCDI2 1016
#define FCDI_EXTENDED_EVENT_PPS_LEN(num) (8+8*(num))
+#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_NUM(len) (((len)-8)/8)
/* Number of timestamps following */
#define FCDI_EXTENDED_EVENT_PPS_COUNT_OFST 0
#define FCDI_EXTENDED_EVENT_PPS_COUNT_LEN 4
@@ -915,6 +1073,7 @@
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_HI_OFST 12
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_MINNUM 1
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_MAXNUM 30
+#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_MAXNUM_MCDI2 126
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LBN 64
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_WIDTH 64
@@ -934,24 +1093,33 @@
#define MUM_EVENT_LEVEL_FATAL 0x3
#define MUM_EVENT_DATA_OFST 0
#define MUM_EVENT_DATA_LEN 4
+#define MUM_EVENT_SENSOR_ID_OFST 0
#define MUM_EVENT_SENSOR_ID_LBN 0
#define MUM_EVENT_SENSOR_ID_WIDTH 8
/* Enum values, see field(s): */
/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */
+#define MUM_EVENT_SENSOR_STATE_OFST 0
#define MUM_EVENT_SENSOR_STATE_LBN 8
#define MUM_EVENT_SENSOR_STATE_WIDTH 8
+#define MUM_EVENT_PORT_PHY_READY_OFST 0
#define MUM_EVENT_PORT_PHY_READY_LBN 0
#define MUM_EVENT_PORT_PHY_READY_WIDTH 1
+#define MUM_EVENT_PORT_PHY_LINK_UP_OFST 0
#define MUM_EVENT_PORT_PHY_LINK_UP_LBN 1
#define MUM_EVENT_PORT_PHY_LINK_UP_WIDTH 1
+#define MUM_EVENT_PORT_PHY_TX_LOL_OFST 0
#define MUM_EVENT_PORT_PHY_TX_LOL_LBN 2
#define MUM_EVENT_PORT_PHY_TX_LOL_WIDTH 1
+#define MUM_EVENT_PORT_PHY_RX_LOL_OFST 0
#define MUM_EVENT_PORT_PHY_RX_LOL_LBN 3
#define MUM_EVENT_PORT_PHY_RX_LOL_WIDTH 1
+#define MUM_EVENT_PORT_PHY_TX_LOS_OFST 0
#define MUM_EVENT_PORT_PHY_TX_LOS_LBN 4
#define MUM_EVENT_PORT_PHY_TX_LOS_WIDTH 1
+#define MUM_EVENT_PORT_PHY_RX_LOS_OFST 0
#define MUM_EVENT_PORT_PHY_RX_LOS_LBN 5
#define MUM_EVENT_PORT_PHY_RX_LOS_WIDTH 1
+#define MUM_EVENT_PORT_PHY_TX_FAULT_OFST 0
#define MUM_EVENT_PORT_PHY_TX_FAULT_LBN 6
#define MUM_EVENT_PORT_PHY_TX_FAULT_WIDTH 1
#define MUM_EVENT_DATA_LBN 0
@@ -1016,6 +1184,7 @@
* has additional checks to reject insecure calls.
*/
#define MC_CMD_READ32 0x1
+#undef MC_CMD_0x1_PRIVILEGE_CTG
#define MC_CMD_0x1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -1029,11 +1198,14 @@
/* MC_CMD_READ32_OUT msgresponse */
#define MC_CMD_READ32_OUT_LENMIN 4
#define MC_CMD_READ32_OUT_LENMAX 252
+#define MC_CMD_READ32_OUT_LENMAX_MCDI2 1020
#define MC_CMD_READ32_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_READ32_OUT_BUFFER_NUM(len) (((len)-0)/4)
#define MC_CMD_READ32_OUT_BUFFER_OFST 0
#define MC_CMD_READ32_OUT_BUFFER_LEN 4
#define MC_CMD_READ32_OUT_BUFFER_MINNUM 1
#define MC_CMD_READ32_OUT_BUFFER_MAXNUM 63
+#define MC_CMD_READ32_OUT_BUFFER_MAXNUM_MCDI2 255
/***********************************/
@@ -1041,19 +1213,23 @@
* Write multiple 32byte words to MC memory.
*/
#define MC_CMD_WRITE32 0x2
+#undef MC_CMD_0x2_PRIVILEGE_CTG
#define MC_CMD_0x2_PRIVILEGE_CTG SRIOV_CTG_INSECURE
/* MC_CMD_WRITE32_IN msgrequest */
#define MC_CMD_WRITE32_IN_LENMIN 8
#define MC_CMD_WRITE32_IN_LENMAX 252
+#define MC_CMD_WRITE32_IN_LENMAX_MCDI2 1020
#define MC_CMD_WRITE32_IN_LEN(num) (4+4*(num))
+#define MC_CMD_WRITE32_IN_BUFFER_NUM(len) (((len)-4)/4)
#define MC_CMD_WRITE32_IN_ADDR_OFST 0
#define MC_CMD_WRITE32_IN_ADDR_LEN 4
#define MC_CMD_WRITE32_IN_BUFFER_OFST 4
#define MC_CMD_WRITE32_IN_BUFFER_LEN 4
#define MC_CMD_WRITE32_IN_BUFFER_MINNUM 1
#define MC_CMD_WRITE32_IN_BUFFER_MAXNUM 62
+#define MC_CMD_WRITE32_IN_BUFFER_MAXNUM_MCDI2 254
/* MC_CMD_WRITE32_OUT msgresponse */
#define MC_CMD_WRITE32_OUT_LEN 0
@@ -1066,6 +1242,7 @@
* has additional checks to reject insecure calls.
*/
#define MC_CMD_COPYCODE 0x3
+#undef MC_CMD_0x3_PRIVILEGE_CTG
#define MC_CMD_0x3_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -1090,16 +1267,22 @@
* below)
*/
#define MC_CMD_COPYCODE_HUNT_IGNORE_CONFIG_MAGIC_ADDR 0x1badc
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_PRESENT_OFST 0
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_PRESENT_LBN 17
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_PRESENT_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED_OFST 0
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED_LBN 2
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_IGNORE_CONFIG_OFST 0
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_IGNORE_CONFIG_LBN 3
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_IGNORE_CONFIG_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SKIP_BOOT_ICORE_SYNC_OFST 0
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SKIP_BOOT_ICORE_SYNC_LBN 4
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SKIP_BOOT_ICORE_SYNC_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_FORCE_STANDALONE_OFST 0
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_FORCE_STANDALONE_LBN 5
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_FORCE_STANDALONE_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_DISABLE_XIP_OFST 0
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_DISABLE_XIP_LBN 6
#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_DISABLE_XIP_WIDTH 1
/* Destination address */
@@ -1122,6 +1305,7 @@
* Select function for function-specific commands.
*/
#define MC_CMD_SET_FUNC 0x4
+#undef MC_CMD_0x4_PRIVILEGE_CTG
#define MC_CMD_0x4_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -1140,6 +1324,7 @@
* Get the instruction address from which the MC booted.
*/
#define MC_CMD_GET_BOOT_STATUS 0x5
+#undef MC_CMD_0x5_PRIVILEGE_CTG
#define MC_CMD_0x5_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -1155,10 +1340,13 @@
#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_NULL 0xdeadbeef
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_LEN 4
+#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_OFST 4
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_WIDTH 1
+#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_OFST 4
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_LBN 1
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_WIDTH 1
+#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_OFST 4
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_LBN 2
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_WIDTH 1
@@ -1170,6 +1358,7 @@
* fields will only be present if OUT.GLOBAL_FLAGS != NO_FAILS
*/
#define MC_CMD_GET_ASSERTS 0x6
+#undef MC_CMD_0x6_PRIVILEGE_CTG
#define MC_CMD_0x6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -1211,6 +1400,104 @@
#define MC_CMD_GET_ASSERTS_OUT_RESERVED_OFST 136
#define MC_CMD_GET_ASSERTS_OUT_RESERVED_LEN 4
+/* MC_CMD_GET_ASSERTS_OUT_V2 msgresponse: Extended response for MicroBlaze CPUs
+ * found on Riverhead designs
+ */
+#define MC_CMD_GET_ASSERTS_OUT_V2_LEN 240
+/* Assertion status flag. */
+#define MC_CMD_GET_ASSERTS_OUT_V2_GLOBAL_FLAGS_OFST 0
+#define MC_CMD_GET_ASSERTS_OUT_V2_GLOBAL_FLAGS_LEN 4
+/* enum: No assertions have failed. */
+/* MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1 */
+/* enum: A system-level assertion has failed. */
+/* MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2 */
+/* enum: A thread-level assertion has failed. */
+/* MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3 */
+/* enum: The system was reset by the watchdog. */
+/* MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4 */
+/* enum: An illegal address trap stopped the system (huntington and later) */
+/* MC_CMD_GET_ASSERTS_FLAGS_ADDR_TRAP 0x5 */
+/* Failing PC value */
+#define MC_CMD_GET_ASSERTS_OUT_V2_SAVED_PC_OFFS_OFST 4
+#define MC_CMD_GET_ASSERTS_OUT_V2_SAVED_PC_OFFS_LEN 4
+/* Saved GP regs */
+#define MC_CMD_GET_ASSERTS_OUT_V2_GP_REGS_OFFS_OFST 8
+#define MC_CMD_GET_ASSERTS_OUT_V2_GP_REGS_OFFS_LEN 4
+#define MC_CMD_GET_ASSERTS_OUT_V2_GP_REGS_OFFS_NUM 31
+/* enum: A magic value hinting that the value in this register at the time of
+ * the failure has likely been lost.
+ */
+/* MC_CMD_GET_ASSERTS_REG_NO_DATA 0xda7a1057 */
+/* Failing thread address */
+#define MC_CMD_GET_ASSERTS_OUT_V2_THREAD_OFFS_OFST 132
+#define MC_CMD_GET_ASSERTS_OUT_V2_THREAD_OFFS_LEN 4
+#define MC_CMD_GET_ASSERTS_OUT_V2_RESERVED_OFST 136
+#define MC_CMD_GET_ASSERTS_OUT_V2_RESERVED_LEN 4
+/* Saved Special Function Registers */
+#define MC_CMD_GET_ASSERTS_OUT_V2_SF_REGS_OFFS_OFST 136
+#define MC_CMD_GET_ASSERTS_OUT_V2_SF_REGS_OFFS_LEN 4
+#define MC_CMD_GET_ASSERTS_OUT_V2_SF_REGS_OFFS_NUM 26
+
+/* MC_CMD_GET_ASSERTS_OUT_V3 msgresponse: Extended response with asserted
+ * firmware version information
+ */
+#define MC_CMD_GET_ASSERTS_OUT_V3_LEN 360
+/* Assertion status flag. */
+#define MC_CMD_GET_ASSERTS_OUT_V3_GLOBAL_FLAGS_OFST 0
+#define MC_CMD_GET_ASSERTS_OUT_V3_GLOBAL_FLAGS_LEN 4
+/* enum: No assertions have failed. */
+/* MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1 */
+/* enum: A system-level assertion has failed. */
+/* MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2 */
+/* enum: A thread-level assertion has failed. */
+/* MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3 */
+/* enum: The system was reset by the watchdog. */
+/* MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4 */
+/* enum: An illegal address trap stopped the system (huntington and later) */
+/* MC_CMD_GET_ASSERTS_FLAGS_ADDR_TRAP 0x5 */
+/* Failing PC value */
+#define MC_CMD_GET_ASSERTS_OUT_V3_SAVED_PC_OFFS_OFST 4
+#define MC_CMD_GET_ASSERTS_OUT_V3_SAVED_PC_OFFS_LEN 4
+/* Saved GP regs */
+#define MC_CMD_GET_ASSERTS_OUT_V3_GP_REGS_OFFS_OFST 8
+#define MC_CMD_GET_ASSERTS_OUT_V3_GP_REGS_OFFS_LEN 4
+#define MC_CMD_GET_ASSERTS_OUT_V3_GP_REGS_OFFS_NUM 31
+/* enum: A magic value hinting that the value in this register at the time of
+ * the failure has likely been lost.
+ */
+/* MC_CMD_GET_ASSERTS_REG_NO_DATA 0xda7a1057 */
+/* Failing thread address */
+#define MC_CMD_GET_ASSERTS_OUT_V3_THREAD_OFFS_OFST 132
+#define MC_CMD_GET_ASSERTS_OUT_V3_THREAD_OFFS_LEN 4
+#define MC_CMD_GET_ASSERTS_OUT_V3_RESERVED_OFST 136
+#define MC_CMD_GET_ASSERTS_OUT_V3_RESERVED_LEN 4
+/* Saved Special Function Registers */
+#define MC_CMD_GET_ASSERTS_OUT_V3_SF_REGS_OFFS_OFST 136
+#define MC_CMD_GET_ASSERTS_OUT_V3_SF_REGS_OFFS_LEN 4
+#define MC_CMD_GET_ASSERTS_OUT_V3_SF_REGS_OFFS_NUM 26
+/* MC firmware unique build ID (as binary SHA-1 value) */
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_BUILD_ID_OFST 240
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_BUILD_ID_LEN 20
+/* MC firmware build date (as Unix timestamp) */
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_BUILD_TIMESTAMP_OFST 260
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_BUILD_TIMESTAMP_LEN 8
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_BUILD_TIMESTAMP_LO_OFST 260
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_BUILD_TIMESTAMP_HI_OFST 264
+/* MC firmware version number */
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_VERSION_OFST 268
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_VERSION_LEN 8
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_VERSION_LO_OFST 268
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_VERSION_HI_OFST 272
+/* MC firmware security level */
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_SECURITY_LEVEL_OFST 276
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_SECURITY_LEVEL_LEN 4
+/* MC firmware extra version info (as null-terminated US-ASCII string) */
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_EXTRA_INFO_OFST 280
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_EXTRA_INFO_LEN 16
+/* MC firmware build name (as null-terminated US-ASCII string) */
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_BUILD_NAME_OFST 296
+#define MC_CMD_GET_ASSERTS_OUT_V3_MC_FW_BUILD_NAME_LEN 64
+
/***********************************/
/* MC_CMD_LOG_CTRL
@@ -1218,6 +1505,7 @@
* sensor notifications and MCDI completions
*/
#define MC_CMD_LOG_CTRL 0x7
+#undef MC_CMD_0x7_PRIVILEGE_CTG
#define MC_CMD_0x7_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -1240,9 +1528,10 @@
/***********************************/
/* MC_CMD_GET_VERSION
- * Get version information about the MC firmware.
+ * Get version information about adapter components.
*/
#define MC_CMD_GET_VERSION 0x8
+#undef MC_CMD_0x8_PRIVILEGE_CTG
#define MC_CMD_0x8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -1303,12 +1592,107 @@
#define MC_CMD_GET_VERSION_EXT_OUT_EXTRA_OFST 32
#define MC_CMD_GET_VERSION_EXT_OUT_EXTRA_LEN 16
+/* MC_CMD_GET_VERSION_V2_OUT msgresponse: Extended response providing version
+ * information for all adapter components. For Riverhead based designs, base MC
+ * firmware version fields refer to NMC firmware, while CMC firmware data is in
+ * dedicated CMC fields. Flags indicate which data is present in the response
+ * (depending on which components exist on a particular adapter)
+ */
+#define MC_CMD_GET_VERSION_V2_OUT_LEN 304
+/* MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 */
+/* MC_CMD_GET_VERSION_OUT_FIRMWARE_LEN 4 */
+/* Enum values, see field(s): */
+/* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */
+#define MC_CMD_GET_VERSION_V2_OUT_PCOL_OFST 4
+#define MC_CMD_GET_VERSION_V2_OUT_PCOL_LEN 4
+/* 128bit mask of functions supported by the current firmware */
+#define MC_CMD_GET_VERSION_V2_OUT_SUPPORTED_FUNCS_OFST 8
+#define MC_CMD_GET_VERSION_V2_OUT_SUPPORTED_FUNCS_LEN 16
+#define MC_CMD_GET_VERSION_V2_OUT_VERSION_OFST 24
+#define MC_CMD_GET_VERSION_V2_OUT_VERSION_LEN 8
+#define MC_CMD_GET_VERSION_V2_OUT_VERSION_LO_OFST 24
+#define MC_CMD_GET_VERSION_V2_OUT_VERSION_HI_OFST 28
+/* extra info */
+#define MC_CMD_GET_VERSION_V2_OUT_EXTRA_OFST 32
+#define MC_CMD_GET_VERSION_V2_OUT_EXTRA_LEN 16
+/* Flags indicating which extended fields are valid */
+#define MC_CMD_GET_VERSION_V2_OUT_FLAGS_OFST 48
+#define MC_CMD_GET_VERSION_V2_OUT_FLAGS_LEN 4
+#define MC_CMD_GET_VERSION_V2_OUT_MCFW_EXT_INFO_PRESENT_OFST 48
+#define MC_CMD_GET_VERSION_V2_OUT_MCFW_EXT_INFO_PRESENT_LBN 0
+#define MC_CMD_GET_VERSION_V2_OUT_MCFW_EXT_INFO_PRESENT_WIDTH 1
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_EXT_INFO_PRESENT_OFST 48
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_EXT_INFO_PRESENT_LBN 1
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_EXT_INFO_PRESENT_WIDTH 1
+#define MC_CMD_GET_VERSION_V2_OUT_CMC_EXT_INFO_PRESENT_OFST 48
+#define MC_CMD_GET_VERSION_V2_OUT_CMC_EXT_INFO_PRESENT_LBN 2
+#define MC_CMD_GET_VERSION_V2_OUT_CMC_EXT_INFO_PRESENT_WIDTH 1
+#define MC_CMD_GET_VERSION_V2_OUT_FPGA_EXT_INFO_PRESENT_OFST 48
+#define MC_CMD_GET_VERSION_V2_OUT_FPGA_EXT_INFO_PRESENT_LBN 3
+#define MC_CMD_GET_VERSION_V2_OUT_FPGA_EXT_INFO_PRESENT_WIDTH 1
+#define MC_CMD_GET_VERSION_V2_OUT_BOARD_EXT_INFO_PRESENT_OFST 48
+#define MC_CMD_GET_VERSION_V2_OUT_BOARD_EXT_INFO_PRESENT_LBN 4
+#define MC_CMD_GET_VERSION_V2_OUT_BOARD_EXT_INFO_PRESENT_WIDTH 1
+/* MC firmware unique build ID (as binary SHA-1 value) */
+#define MC_CMD_GET_VERSION_V2_OUT_MCFW_BUILD_ID_OFST 52
+#define MC_CMD_GET_VERSION_V2_OUT_MCFW_BUILD_ID_LEN 20
+/* MC firmware security level */
+#define MC_CMD_GET_VERSION_V2_OUT_MCFW_SECURITY_LEVEL_OFST 72
+#define MC_CMD_GET_VERSION_V2_OUT_MCFW_SECURITY_LEVEL_LEN 4
+/* MC firmware build name (as null-terminated US-ASCII string) */
+#define MC_CMD_GET_VERSION_V2_OUT_MCFW_BUILD_NAME_OFST 76
+#define MC_CMD_GET_VERSION_V2_OUT_MCFW_BUILD_NAME_LEN 64
+/* The SUC firmware version as four numbers - a.b.c.d */
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_VERSION_OFST 140
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_VERSION_LEN 4
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_VERSION_NUM 4
+/* SUC firmware build date (as 64-bit Unix timestamp) */
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_BUILD_DATE_OFST 156
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_BUILD_DATE_LEN 8
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_BUILD_DATE_LO_OFST 156
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_BUILD_DATE_HI_OFST 160
+/* The ID of the SUC chip. This is specific to the platform but typically
+ * indicates family, memory sizes etc. See SF-116728-SW for further details.
+ */
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_CHIP_ID_OFST 164
+#define MC_CMD_GET_VERSION_V2_OUT_SUCFW_CHIP_ID_LEN 4
+/* The CMC firmware version as four numbers - a.b.c.d */
+#define MC_CMD_GET_VERSION_V2_OUT_CMCFW_VERSION_OFST 168
+#define MC_CMD_GET_VERSION_V2_OUT_CMCFW_VERSION_LEN 4
+#define MC_CMD_GET_VERSION_V2_OUT_CMCFW_VERSION_NUM 4
+/* CMC firmware build date (as 64-bit Unix timestamp) */
+#define MC_CMD_GET_VERSION_V2_OUT_CMCFW_BUILD_DATE_OFST 184
+#define MC_CMD_GET_VERSION_V2_OUT_CMCFW_BUILD_DATE_LEN 8
+#define MC_CMD_GET_VERSION_V2_OUT_CMCFW_BUILD_DATE_LO_OFST 184
+#define MC_CMD_GET_VERSION_V2_OUT_CMCFW_BUILD_DATE_HI_OFST 188
+/* FPGA version as three numbers. On Riverhead based systems this field uses
+ * the same encoding as hardware version ID registers (MC_FPGA_BUILD_HWRD_REG):
+ * FPGA_VERSION[0]: x => Image H{x} FPGA_VERSION[1]: Revision letter (0 => A, 1
+ * => B, ...) FPGA_VERSION[2]: Sub-revision number
+ */
+#define MC_CMD_GET_VERSION_V2_OUT_FPGA_VERSION_OFST 192
+#define MC_CMD_GET_VERSION_V2_OUT_FPGA_VERSION_LEN 4
+#define MC_CMD_GET_VERSION_V2_OUT_FPGA_VERSION_NUM 3
+/* Extra FPGA revision information (as null-terminated US-ASCII string) */
+#define MC_CMD_GET_VERSION_V2_OUT_FPGA_EXTRA_OFST 204
+#define MC_CMD_GET_VERSION_V2_OUT_FPGA_EXTRA_LEN 16
+/* Board name / adapter model (as null-terminated US-ASCII string) */
+#define MC_CMD_GET_VERSION_V2_OUT_BOARD_NAME_OFST 220
+#define MC_CMD_GET_VERSION_V2_OUT_BOARD_NAME_LEN 16
+/* Board revision number */
+#define MC_CMD_GET_VERSION_V2_OUT_BOARD_REVISION_OFST 236
+#define MC_CMD_GET_VERSION_V2_OUT_BOARD_REVISION_LEN 4
+/* Board serial number (as null-terminated US-ASCII string) */
+#define MC_CMD_GET_VERSION_V2_OUT_BOARD_SERIAL_OFST 240
+#define MC_CMD_GET_VERSION_V2_OUT_BOARD_SERIAL_LEN 64
+
/***********************************/
/* MC_CMD_PTP
* Perform PTP operation
*/
#define MC_CMD_PTP 0xb
+#undef MC_CMD_0xb_PRIVILEGE_CTG
#define MC_CMD_0xb_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -1434,7 +1818,9 @@
/* MC_CMD_PTP_IN_TRANSMIT msgrequest */
#define MC_CMD_PTP_IN_TRANSMIT_LENMIN 13
#define MC_CMD_PTP_IN_TRANSMIT_LENMAX 252
+#define MC_CMD_PTP_IN_TRANSMIT_LENMAX_MCDI2 1020
#define MC_CMD_PTP_IN_TRANSMIT_LEN(num) (12+1*(num))
+#define MC_CMD_PTP_IN_TRANSMIT_PACKET_NUM(len) (((len)-12)/1)
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_CMD_LEN 4 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
@@ -1447,6 +1833,7 @@
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_LEN 1
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MINNUM 1
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM 240
+#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM_MCDI2 1008
/* MC_CMD_PTP_IN_READ_NIC_TIME msgrequest */
#define MC_CMD_PTP_IN_READ_NIC_TIME_LEN 8
@@ -1599,7 +1986,9 @@
/* MC_CMD_PTP_IN_FPGAWRITE msgrequest */
#define MC_CMD_PTP_IN_FPGAWRITE_LENMIN 13
#define MC_CMD_PTP_IN_FPGAWRITE_LENMAX 252
+#define MC_CMD_PTP_IN_FPGAWRITE_LENMAX_MCDI2 1020
#define MC_CMD_PTP_IN_FPGAWRITE_LEN(num) (12+1*(num))
+#define MC_CMD_PTP_IN_FPGAWRITE_BUFFER_NUM(len) (((len)-12)/1)
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_CMD_LEN 4 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
@@ -1610,6 +1999,7 @@
#define MC_CMD_PTP_IN_FPGAWRITE_BUFFER_LEN 1
#define MC_CMD_PTP_IN_FPGAWRITE_BUFFER_MINNUM 1
#define MC_CMD_PTP_IN_FPGAWRITE_BUFFER_MAXNUM 240
+#define MC_CMD_PTP_IN_FPGAWRITE_BUFFER_MAXNUM_MCDI2 1008
/* MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST msgrequest */
#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_LEN 16
@@ -1774,8 +2164,10 @@
/* Original field containing queue ID. Now extended to include flags. */
#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_OFST 8
#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_LEN 4
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_ID_OFST 8
#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_ID_LBN 0
#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_ID_WIDTH 16
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_REPORT_SYNC_STATUS_OFST 8
#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_REPORT_SYNC_STATUS_LBN 31
#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_REPORT_SYNC_STATUS_WIDTH 1
@@ -1940,12 +2332,15 @@
/* MC_CMD_PTP_OUT_SYNCHRONIZE msgresponse */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMIN 20
#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMAX 240
+#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMAX_MCDI2 1020
#define MC_CMD_PTP_OUT_SYNCHRONIZE_LEN(num) (0+20*(num))
+#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_NUM(len) (((len)-0)/20)
/* A set of host and NIC times */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_OFST 0
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN 20
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MINNUM 1
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM 12
+#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM_MCDI2 51
/* Host time immediately before NIC's hardware clock read */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_OFST 0
#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_LEN 4
@@ -2022,11 +2417,14 @@
/* MC_CMD_PTP_OUT_FPGAREAD msgresponse */
#define MC_CMD_PTP_OUT_FPGAREAD_LENMIN 1
#define MC_CMD_PTP_OUT_FPGAREAD_LENMAX 252
+#define MC_CMD_PTP_OUT_FPGAREAD_LENMAX_MCDI2 1020
#define MC_CMD_PTP_OUT_FPGAREAD_LEN(num) (0+1*(num))
+#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_NUM(len) (((len)-0)/1)
#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_OFST 0
#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_LEN 1
#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MINNUM 1
#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MAXNUM 252
+#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MAXNUM_MCDI2 1020
/* MC_CMD_PTP_OUT_GET_TIME_FORMAT msgresponse */
#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_LEN 4
@@ -2075,12 +2473,16 @@
/* Various PTP capabilities */
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_CAPABILITIES_OFST 8
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_CAPABILITIES_LEN 4
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_REPORT_SYNC_STATUS_OFST 8
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_REPORT_SYNC_STATUS_LBN 0
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_REPORT_SYNC_STATUS_WIDTH 1
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RX_TSTAMP_OOB_OFST 8
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RX_TSTAMP_OOB_LBN 1
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RX_TSTAMP_OOB_WIDTH 1
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_64BIT_SECONDS_OFST 8
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_64BIT_SECONDS_LBN 2
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_64BIT_SECONDS_WIDTH 1
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_FP44_FREQ_ADJ_OFST 8
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_FP44_FREQ_ADJ_LBN 3
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_FP44_FREQ_ADJ_WIDTH 1
#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED0_OFST 12
@@ -2143,6 +2545,7 @@
* Read 32bit words from the indirect memory map.
*/
#define MC_CMD_CSR_READ32 0xc
+#undef MC_CMD_0xc_PRIVILEGE_CTG
#define MC_CMD_0xc_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -2159,12 +2562,15 @@
/* MC_CMD_CSR_READ32_OUT msgresponse */
#define MC_CMD_CSR_READ32_OUT_LENMIN 4
#define MC_CMD_CSR_READ32_OUT_LENMAX 252
+#define MC_CMD_CSR_READ32_OUT_LENMAX_MCDI2 1020
#define MC_CMD_CSR_READ32_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_CSR_READ32_OUT_BUFFER_NUM(len) (((len)-0)/4)
/* The last dword is the status, not a value read */
#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0
#define MC_CMD_CSR_READ32_OUT_BUFFER_LEN 4
#define MC_CMD_CSR_READ32_OUT_BUFFER_MINNUM 1
#define MC_CMD_CSR_READ32_OUT_BUFFER_MAXNUM 63
+#define MC_CMD_CSR_READ32_OUT_BUFFER_MAXNUM_MCDI2 255
/***********************************/
@@ -2172,13 +2578,16 @@
* Write 32bit dwords to the indirect memory map.
*/
#define MC_CMD_CSR_WRITE32 0xd
+#undef MC_CMD_0xd_PRIVILEGE_CTG
#define MC_CMD_0xd_PRIVILEGE_CTG SRIOV_CTG_INSECURE
/* MC_CMD_CSR_WRITE32_IN msgrequest */
#define MC_CMD_CSR_WRITE32_IN_LENMIN 12
#define MC_CMD_CSR_WRITE32_IN_LENMAX 252
+#define MC_CMD_CSR_WRITE32_IN_LENMAX_MCDI2 1020
#define MC_CMD_CSR_WRITE32_IN_LEN(num) (8+4*(num))
+#define MC_CMD_CSR_WRITE32_IN_BUFFER_NUM(len) (((len)-8)/4)
/* Address */
#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0
#define MC_CMD_CSR_WRITE32_IN_ADDR_LEN 4
@@ -2188,6 +2597,7 @@
#define MC_CMD_CSR_WRITE32_IN_BUFFER_LEN 4
#define MC_CMD_CSR_WRITE32_IN_BUFFER_MINNUM 1
#define MC_CMD_CSR_WRITE32_IN_BUFFER_MAXNUM 61
+#define MC_CMD_CSR_WRITE32_IN_BUFFER_MAXNUM_MCDI2 253
/* MC_CMD_CSR_WRITE32_OUT msgresponse */
#define MC_CMD_CSR_WRITE32_OUT_LEN 4
@@ -2201,6 +2611,7 @@
* MCDI command to avoid creating too many MCDI commands.
*/
#define MC_CMD_HP 0x54
+#undef MC_CMD_0x54_PRIVILEGE_CTG
#define MC_CMD_0x54_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -2247,6 +2658,7 @@
* Get stack information.
*/
#define MC_CMD_STACKINFO 0xf
+#undef MC_CMD_0xf_PRIVILEGE_CTG
#define MC_CMD_0xf_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -2256,12 +2668,15 @@
/* MC_CMD_STACKINFO_OUT msgresponse */
#define MC_CMD_STACKINFO_OUT_LENMIN 12
#define MC_CMD_STACKINFO_OUT_LENMAX 252
+#define MC_CMD_STACKINFO_OUT_LENMAX_MCDI2 1020
#define MC_CMD_STACKINFO_OUT_LEN(num) (0+12*(num))
+#define MC_CMD_STACKINFO_OUT_THREAD_INFO_NUM(len) (((len)-0)/12)
/* (thread ptr, stack size, free space) for each thread in system */
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_OFST 0
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_LEN 12
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MINNUM 1
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MAXNUM 21
+#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MAXNUM_MCDI2 85
/***********************************/
@@ -2269,6 +2684,7 @@
* MDIO register read.
*/
#define MC_CMD_MDIO_READ 0x10
+#undef MC_CMD_0x10_PRIVILEGE_CTG
#define MC_CMD_0x10_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -2316,6 +2732,7 @@
* MDIO register write.
*/
#define MC_CMD_MDIO_WRITE 0x11
+#undef MC_CMD_0x11_PRIVILEGE_CTG
#define MC_CMD_0x11_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -2363,13 +2780,16 @@
* Write DBI register(s).
*/
#define MC_CMD_DBI_WRITE 0x12
+#undef MC_CMD_0x12_PRIVILEGE_CTG
#define MC_CMD_0x12_PRIVILEGE_CTG SRIOV_CTG_INSECURE
/* MC_CMD_DBI_WRITE_IN msgrequest */
#define MC_CMD_DBI_WRITE_IN_LENMIN 12
#define MC_CMD_DBI_WRITE_IN_LENMAX 252
+#define MC_CMD_DBI_WRITE_IN_LENMAX_MCDI2 1020
#define MC_CMD_DBI_WRITE_IN_LEN(num) (0+12*(num))
+#define MC_CMD_DBI_WRITE_IN_DBIWROP_NUM(len) (((len)-0)/12)
/* Each write op consists of an address (offset 0), byte enable/VF/CS2 (offset
* 32) and value (offset 64). See MC_CMD_DBIWROP_TYPEDEF.
*/
@@ -2377,6 +2797,7 @@
#define MC_CMD_DBI_WRITE_IN_DBIWROP_LEN 12
#define MC_CMD_DBI_WRITE_IN_DBIWROP_MINNUM 1
#define MC_CMD_DBI_WRITE_IN_DBIWROP_MAXNUM 21
+#define MC_CMD_DBI_WRITE_IN_DBIWROP_MAXNUM_MCDI2 85
/* MC_CMD_DBI_WRITE_OUT msgresponse */
#define MC_CMD_DBI_WRITE_OUT_LEN 0
@@ -2389,10 +2810,13 @@
#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_WIDTH 32
#define MC_CMD_DBIWROP_TYPEDEF_PARMS_OFST 4
#define MC_CMD_DBIWROP_TYPEDEF_PARMS_LEN 4
+#define MC_CMD_DBIWROP_TYPEDEF_VF_NUM_OFST 4
#define MC_CMD_DBIWROP_TYPEDEF_VF_NUM_LBN 16
#define MC_CMD_DBIWROP_TYPEDEF_VF_NUM_WIDTH 16
+#define MC_CMD_DBIWROP_TYPEDEF_VF_ACTIVE_OFST 4
#define MC_CMD_DBIWROP_TYPEDEF_VF_ACTIVE_LBN 15
#define MC_CMD_DBIWROP_TYPEDEF_VF_ACTIVE_WIDTH 1
+#define MC_CMD_DBIWROP_TYPEDEF_CS2_OFST 4
#define MC_CMD_DBIWROP_TYPEDEF_CS2_LBN 14
#define MC_CMD_DBIWROP_TYPEDEF_CS2_WIDTH 1
#define MC_CMD_DBIWROP_TYPEDEF_PARMS_LBN 32
@@ -2526,6 +2950,7 @@
* Returns the MC firmware configuration structure.
*/
#define MC_CMD_GET_BOARD_CFG 0x18
+#undef MC_CMD_0x18_PRIVILEGE_CTG
#define MC_CMD_0x18_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -2535,7 +2960,9 @@
/* MC_CMD_GET_BOARD_CFG_OUT msgresponse */
#define MC_CMD_GET_BOARD_CFG_OUT_LENMIN 96
#define MC_CMD_GET_BOARD_CFG_OUT_LENMAX 136
+#define MC_CMD_GET_BOARD_CFG_OUT_LENMAX_MCDI2 136
#define MC_CMD_GET_BOARD_CFG_OUT_LEN(num) (72+2*(num))
+#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_NUM(len) (((len)-72)/2)
#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0
#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_LEN 4
#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4
@@ -2590,6 +3017,7 @@
#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 2
#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM 12
#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM 32
+#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM_MCDI2 32
/***********************************/
@@ -2597,13 +3025,16 @@
* Read DBI register(s) -- extended functionality
*/
#define MC_CMD_DBI_READX 0x19
+#undef MC_CMD_0x19_PRIVILEGE_CTG
#define MC_CMD_0x19_PRIVILEGE_CTG SRIOV_CTG_INSECURE
/* MC_CMD_DBI_READX_IN msgrequest */
#define MC_CMD_DBI_READX_IN_LENMIN 8
#define MC_CMD_DBI_READX_IN_LENMAX 248
+#define MC_CMD_DBI_READX_IN_LENMAX_MCDI2 1016
#define MC_CMD_DBI_READX_IN_LEN(num) (0+8*(num))
+#define MC_CMD_DBI_READX_IN_DBIRDOP_NUM(len) (((len)-0)/8)
/* Each Read op consists of an address (offset 0), VF/CS2) */
#define MC_CMD_DBI_READX_IN_DBIRDOP_OFST 0
#define MC_CMD_DBI_READX_IN_DBIRDOP_LEN 8
@@ -2611,16 +3042,20 @@
#define MC_CMD_DBI_READX_IN_DBIRDOP_HI_OFST 4
#define MC_CMD_DBI_READX_IN_DBIRDOP_MINNUM 1
#define MC_CMD_DBI_READX_IN_DBIRDOP_MAXNUM 31
+#define MC_CMD_DBI_READX_IN_DBIRDOP_MAXNUM_MCDI2 127
/* MC_CMD_DBI_READX_OUT msgresponse */
#define MC_CMD_DBI_READX_OUT_LENMIN 4
#define MC_CMD_DBI_READX_OUT_LENMAX 252
+#define MC_CMD_DBI_READX_OUT_LENMAX_MCDI2 1020
#define MC_CMD_DBI_READX_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_DBI_READX_OUT_VALUE_NUM(len) (((len)-0)/4)
/* Value */
#define MC_CMD_DBI_READX_OUT_VALUE_OFST 0
#define MC_CMD_DBI_READX_OUT_VALUE_LEN 4
#define MC_CMD_DBI_READX_OUT_VALUE_MINNUM 1
#define MC_CMD_DBI_READX_OUT_VALUE_MAXNUM 63
+#define MC_CMD_DBI_READX_OUT_VALUE_MAXNUM_MCDI2 255
/* MC_CMD_DBIRDOP_TYPEDEF structuredef */
#define MC_CMD_DBIRDOP_TYPEDEF_LEN 8
@@ -2630,10 +3065,13 @@
#define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_WIDTH 32
#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_OFST 4
#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_LEN 4
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_NUM_OFST 4
#define MC_CMD_DBIRDOP_TYPEDEF_VF_NUM_LBN 16
#define MC_CMD_DBIRDOP_TYPEDEF_VF_NUM_WIDTH 16
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_ACTIVE_OFST 4
#define MC_CMD_DBIRDOP_TYPEDEF_VF_ACTIVE_LBN 15
#define MC_CMD_DBIRDOP_TYPEDEF_VF_ACTIVE_WIDTH 1
+#define MC_CMD_DBIRDOP_TYPEDEF_CS2_OFST 4
#define MC_CMD_DBIRDOP_TYPEDEF_CS2_LBN 14
#define MC_CMD_DBIRDOP_TYPEDEF_CS2_WIDTH 1
#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_LBN 32
@@ -2645,6 +3083,7 @@
* Set the 16byte seed for the MC pseudo-random generator.
*/
#define MC_CMD_SET_RAND_SEED 0x1a
+#undef MC_CMD_0x1a_PRIVILEGE_CTG
#define MC_CMD_0x1a_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -2670,12 +3109,15 @@
/* MC_CMD_LTSSM_HIST_OUT msgresponse */
#define MC_CMD_LTSSM_HIST_OUT_LENMIN 0
#define MC_CMD_LTSSM_HIST_OUT_LENMAX 252
+#define MC_CMD_LTSSM_HIST_OUT_LENMAX_MCDI2 1020
#define MC_CMD_LTSSM_HIST_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_LTSSM_HIST_OUT_DATA_NUM(len) (((len)-0)/4)
/* variable number of LTSSM values, as bytes. The history is read-to-clear. */
#define MC_CMD_LTSSM_HIST_OUT_DATA_OFST 0
#define MC_CMD_LTSSM_HIST_OUT_DATA_LEN 4
#define MC_CMD_LTSSM_HIST_OUT_DATA_MINNUM 0
#define MC_CMD_LTSSM_HIST_OUT_DATA_MAXNUM 63
+#define MC_CMD_LTSSM_HIST_OUT_DATA_MAXNUM_MCDI2 255
/***********************************/
@@ -2688,6 +3130,7 @@
* platforms.
*/
#define MC_CMD_DRV_ATTACH 0x1c
+#undef MC_CMD_0x1c_PRIVILEGE_CTG
#define MC_CMD_0x1c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -2696,18 +3139,33 @@
/* new state to set if UPDATE=1 */
#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0
#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_LEN 4
+#define MC_CMD_DRV_ATTACH_OFST 0
#define MC_CMD_DRV_ATTACH_LBN 0
#define MC_CMD_DRV_ATTACH_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_ATTACH_OFST 0
#define MC_CMD_DRV_ATTACH_IN_ATTACH_LBN 0
#define MC_CMD_DRV_ATTACH_IN_ATTACH_WIDTH 1
+#define MC_CMD_DRV_PREBOOT_OFST 0
#define MC_CMD_DRV_PREBOOT_LBN 1
#define MC_CMD_DRV_PREBOOT_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_PREBOOT_OFST 0
#define MC_CMD_DRV_ATTACH_IN_PREBOOT_LBN 1
#define MC_CMD_DRV_ATTACH_IN_PREBOOT_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_SUBVARIANT_AWARE_OFST 0
#define MC_CMD_DRV_ATTACH_IN_SUBVARIANT_AWARE_LBN 2
#define MC_CMD_DRV_ATTACH_IN_SUBVARIANT_AWARE_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_WANT_VI_SPREADING_OFST 0
#define MC_CMD_DRV_ATTACH_IN_WANT_VI_SPREADING_LBN 3
#define MC_CMD_DRV_ATTACH_IN_WANT_VI_SPREADING_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_WANT_V2_LINKCHANGES_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_WANT_V2_LINKCHANGES_LBN 4
+#define MC_CMD_DRV_ATTACH_IN_WANT_V2_LINKCHANGES_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_WANT_RX_VI_SPREADING_INHIBIT_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_WANT_RX_VI_SPREADING_INHIBIT_LBN 5
+#define MC_CMD_DRV_ATTACH_IN_WANT_RX_VI_SPREADING_INHIBIT_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_WANT_TX_ONLY_SPREADING_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_WANT_TX_ONLY_SPREADING_LBN 5
+#define MC_CMD_DRV_ATTACH_IN_WANT_TX_ONLY_SPREADING_WIDTH 1
/* 1 to set new state, or 0 to just report the existing state */
#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4
#define MC_CMD_DRV_ATTACH_IN_UPDATE_LEN 4
@@ -2736,9 +3194,91 @@
* bug69716)
*/
#define MC_CMD_FW_L3XUDP 0x7
+/* enum: Requests that the MC keep whatever datapath firmware is currently
+ * running. It's used for test purposes, where we want to be able to shmboot
+ * special test firmware variants. This option is only recognised in eftest
+ * (i.e. non-production) builds.
+ */
+#define MC_CMD_FW_KEEP_CURRENT_EFTEST_ONLY 0xfffffffe
/* enum: Only this option is allowed for non-admin functions */
#define MC_CMD_FW_DONT_CARE 0xffffffff
+/* MC_CMD_DRV_ATTACH_IN_V2 msgrequest: Updated DRV_ATTACH to include driver
+ * version
+ */
+#define MC_CMD_DRV_ATTACH_IN_V2_LEN 32
+/* new state to set if UPDATE=1 */
+#define MC_CMD_DRV_ATTACH_IN_V2_NEW_STATE_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_V2_NEW_STATE_LEN 4
+/* MC_CMD_DRV_ATTACH_OFST 0 */
+/* MC_CMD_DRV_ATTACH_LBN 0 */
+/* MC_CMD_DRV_ATTACH_WIDTH 1 */
+#define MC_CMD_DRV_ATTACH_IN_V2_ATTACH_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_V2_ATTACH_LBN 0
+#define MC_CMD_DRV_ATTACH_IN_V2_ATTACH_WIDTH 1
+/* MC_CMD_DRV_PREBOOT_OFST 0 */
+/* MC_CMD_DRV_PREBOOT_LBN 1 */
+/* MC_CMD_DRV_PREBOOT_WIDTH 1 */
+#define MC_CMD_DRV_ATTACH_IN_V2_PREBOOT_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_V2_PREBOOT_LBN 1
+#define MC_CMD_DRV_ATTACH_IN_V2_PREBOOT_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_V2_SUBVARIANT_AWARE_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_V2_SUBVARIANT_AWARE_LBN 2
+#define MC_CMD_DRV_ATTACH_IN_V2_SUBVARIANT_AWARE_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_VI_SPREADING_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_VI_SPREADING_LBN 3
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_VI_SPREADING_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_V2_LINKCHANGES_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_V2_LINKCHANGES_LBN 4
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_V2_LINKCHANGES_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_RX_VI_SPREADING_INHIBIT_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_RX_VI_SPREADING_INHIBIT_LBN 5
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_RX_VI_SPREADING_INHIBIT_WIDTH 1
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_TX_ONLY_SPREADING_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_TX_ONLY_SPREADING_LBN 5
+#define MC_CMD_DRV_ATTACH_IN_V2_WANT_TX_ONLY_SPREADING_WIDTH 1
+/* 1 to set new state, or 0 to just report the existing state */
+#define MC_CMD_DRV_ATTACH_IN_V2_UPDATE_OFST 4
+#define MC_CMD_DRV_ATTACH_IN_V2_UPDATE_LEN 4
+/* preferred datapath firmware (for Huntington; ignored for Siena) */
+#define MC_CMD_DRV_ATTACH_IN_V2_FIRMWARE_ID_OFST 8
+#define MC_CMD_DRV_ATTACH_IN_V2_FIRMWARE_ID_LEN 4
+/* enum: Prefer to use full featured firmware */
+/* MC_CMD_FW_FULL_FEATURED 0x0 */
+/* enum: Prefer to use firmware with fewer features but lower latency */
+/* MC_CMD_FW_LOW_LATENCY 0x1 */
+/* enum: Prefer to use firmware for SolarCapture packed stream mode */
+/* MC_CMD_FW_PACKED_STREAM 0x2 */
+/* enum: Prefer to use firmware with fewer features and simpler TX event
+ * batching but higher TX packet rate
+ */
+/* MC_CMD_FW_HIGH_TX_RATE 0x3 */
+/* enum: Reserved value */
+/* MC_CMD_FW_PACKED_STREAM_HASH_MODE_1 0x4 */
+/* enum: Prefer to use firmware with additional "rules engine" filtering
+ * support
+ */
+/* MC_CMD_FW_RULES_ENGINE 0x5 */
+/* enum: Prefer to use firmware with additional DPDK support */
+/* MC_CMD_FW_DPDK 0x6 */
+/* enum: Prefer to use "l3xudp" custom datapath firmware (see SF-119495-PD and
+ * bug69716)
+ */
+/* MC_CMD_FW_L3XUDP 0x7 */
+/* enum: Requests that the MC keep whatever datapath firmware is currently
+ * running. It's used for test purposes, where we want to be able to shmboot
+ * special test firmware variants. This option is only recognised in eftest
+ * (i.e. non-production) builds.
+ */
+/* MC_CMD_FW_KEEP_CURRENT_EFTEST_ONLY 0xfffffffe */
+/* enum: Only this option is allowed for non-admin functions */
+/* MC_CMD_FW_DONT_CARE 0xffffffff */
+/* Version of the driver to be reported by management protocols (e.g. NC-SI)
+ * handled by the NIC. This is a zero-terminated ASCII string.
+ */
+#define MC_CMD_DRV_ATTACH_IN_V2_DRIVER_VERSION_OFST 12
+#define MC_CMD_DRV_ATTACH_IN_V2_DRIVER_VERSION_LEN 20
+
/* MC_CMD_DRV_ATTACH_OUT msgresponse */
#define MC_CMD_DRV_ATTACH_OUT_LEN 4
/* previous or existing state, see the bitmask at NEW_STATE */
@@ -2770,6 +3310,13 @@
* input.
*/
#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_VI_SPREADING_ENABLED 0x4
+/* enum: Used during development only. Should no longer be used. */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_RX_VI_SPREADING_INHIBITED 0x5
+/* enum: If set, indicates that TX only spreading is enabled. Even-numbered
+ * TXQs will use one engine, and odd-numbered TXQs will use the other. This
+ * also has the effect that only even-numbered RXQs will receive traffic.
+ */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TX_ONLY_VI_SPREADING_ENABLED 0x5
/***********************************/
@@ -2795,6 +3342,7 @@
* use MC_CMD_ENTITY_RESET instead.
*/
#define MC_CMD_PORT_RESET 0x20
+#undef MC_CMD_0x20_PRIVILEGE_CTG
#define MC_CMD_0x20_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -2821,6 +3369,7 @@
*/
#define MC_CMD_ENTITY_RESET_IN_FLAG_OFST 0
#define MC_CMD_ENTITY_RESET_IN_FLAG_LEN 4
+#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_OFST 0
#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_LBN 0
#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_WIDTH 1
@@ -2927,17 +3476,22 @@
* Copy the given ASCII string out onto UART and/or out of the network port.
*/
#define MC_CMD_PUTS 0x23
+#undef MC_CMD_0x23_PRIVILEGE_CTG
#define MC_CMD_0x23_PRIVILEGE_CTG SRIOV_CTG_INSECURE
/* MC_CMD_PUTS_IN msgrequest */
#define MC_CMD_PUTS_IN_LENMIN 13
#define MC_CMD_PUTS_IN_LENMAX 252
+#define MC_CMD_PUTS_IN_LENMAX_MCDI2 1020
#define MC_CMD_PUTS_IN_LEN(num) (12+1*(num))
+#define MC_CMD_PUTS_IN_STRING_NUM(len) (((len)-12)/1)
#define MC_CMD_PUTS_IN_DEST_OFST 0
#define MC_CMD_PUTS_IN_DEST_LEN 4
+#define MC_CMD_PUTS_IN_UART_OFST 0
#define MC_CMD_PUTS_IN_UART_LBN 0
#define MC_CMD_PUTS_IN_UART_WIDTH 1
+#define MC_CMD_PUTS_IN_PORT_OFST 0
#define MC_CMD_PUTS_IN_PORT_LBN 1
#define MC_CMD_PUTS_IN_PORT_WIDTH 1
#define MC_CMD_PUTS_IN_DHOST_OFST 4
@@ -2946,6 +3500,7 @@
#define MC_CMD_PUTS_IN_STRING_LEN 1
#define MC_CMD_PUTS_IN_STRING_MINNUM 1
#define MC_CMD_PUTS_IN_STRING_MAXNUM 240
+#define MC_CMD_PUTS_IN_STRING_MAXNUM_MCDI2 1008
/* MC_CMD_PUTS_OUT msgresponse */
#define MC_CMD_PUTS_OUT_LEN 0
@@ -2957,6 +3512,7 @@
* 'zombie' state. Locks required: None
*/
#define MC_CMD_GET_PHY_CFG 0x24
+#undef MC_CMD_0x24_PRIVILEGE_CTG
#define MC_CMD_0x24_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -2968,18 +3524,25 @@
/* flags */
#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_LEN 4
+#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_LBN 0
#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN 1
#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN 2
#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN 3
#define MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_OUT_POWEROFF_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN 4
#define MC_CMD_GET_PHY_CFG_OUT_POWEROFF_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN 5
#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_OUT_BIST_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_BIST_LBN 6
#define MC_CMD_GET_PHY_CFG_OUT_BIST_WIDTH 1
/* ?? */
@@ -2988,46 +3551,67 @@
/* Bitmask of supported capabilities */
#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8
#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_LEN 4
+#define MC_CMD_PHY_CAP_10HDX_OFST 8
#define MC_CMD_PHY_CAP_10HDX_LBN 1
#define MC_CMD_PHY_CAP_10HDX_WIDTH 1
+#define MC_CMD_PHY_CAP_10FDX_OFST 8
#define MC_CMD_PHY_CAP_10FDX_LBN 2
#define MC_CMD_PHY_CAP_10FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_100HDX_OFST 8
#define MC_CMD_PHY_CAP_100HDX_LBN 3
#define MC_CMD_PHY_CAP_100HDX_WIDTH 1
+#define MC_CMD_PHY_CAP_100FDX_OFST 8
#define MC_CMD_PHY_CAP_100FDX_LBN 4
#define MC_CMD_PHY_CAP_100FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_1000HDX_OFST 8
#define MC_CMD_PHY_CAP_1000HDX_LBN 5
#define MC_CMD_PHY_CAP_1000HDX_WIDTH 1
+#define MC_CMD_PHY_CAP_1000FDX_OFST 8
#define MC_CMD_PHY_CAP_1000FDX_LBN 6
#define MC_CMD_PHY_CAP_1000FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_10000FDX_OFST 8
#define MC_CMD_PHY_CAP_10000FDX_LBN 7
#define MC_CMD_PHY_CAP_10000FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_PAUSE_OFST 8
#define MC_CMD_PHY_CAP_PAUSE_LBN 8
#define MC_CMD_PHY_CAP_PAUSE_WIDTH 1
+#define MC_CMD_PHY_CAP_ASYM_OFST 8
#define MC_CMD_PHY_CAP_ASYM_LBN 9
#define MC_CMD_PHY_CAP_ASYM_WIDTH 1
+#define MC_CMD_PHY_CAP_AN_OFST 8
#define MC_CMD_PHY_CAP_AN_LBN 10
#define MC_CMD_PHY_CAP_AN_WIDTH 1
+#define MC_CMD_PHY_CAP_40000FDX_OFST 8
#define MC_CMD_PHY_CAP_40000FDX_LBN 11
#define MC_CMD_PHY_CAP_40000FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_DDM_OFST 8
#define MC_CMD_PHY_CAP_DDM_LBN 12
#define MC_CMD_PHY_CAP_DDM_WIDTH 1
+#define MC_CMD_PHY_CAP_100000FDX_OFST 8
#define MC_CMD_PHY_CAP_100000FDX_LBN 13
#define MC_CMD_PHY_CAP_100000FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_25000FDX_OFST 8
#define MC_CMD_PHY_CAP_25000FDX_LBN 14
#define MC_CMD_PHY_CAP_25000FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_50000FDX_OFST 8
#define MC_CMD_PHY_CAP_50000FDX_LBN 15
#define MC_CMD_PHY_CAP_50000FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_BASER_FEC_OFST 8
#define MC_CMD_PHY_CAP_BASER_FEC_LBN 16
#define MC_CMD_PHY_CAP_BASER_FEC_WIDTH 1
+#define MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_OFST 8
#define MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_LBN 17
#define MC_CMD_PHY_CAP_BASER_FEC_REQUESTED_WIDTH 1
+#define MC_CMD_PHY_CAP_RS_FEC_OFST 8
#define MC_CMD_PHY_CAP_RS_FEC_LBN 18
#define MC_CMD_PHY_CAP_RS_FEC_WIDTH 1
+#define MC_CMD_PHY_CAP_RS_FEC_REQUESTED_OFST 8
#define MC_CMD_PHY_CAP_RS_FEC_REQUESTED_LBN 19
#define MC_CMD_PHY_CAP_RS_FEC_REQUESTED_WIDTH 1
+#define MC_CMD_PHY_CAP_25G_BASER_FEC_OFST 8
#define MC_CMD_PHY_CAP_25G_BASER_FEC_LBN 20
#define MC_CMD_PHY_CAP_25G_BASER_FEC_WIDTH 1
+#define MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_OFST 8
#define MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_LBN 21
#define MC_CMD_PHY_CAP_25G_BASER_FEC_REQUESTED_WIDTH 1
/* ?? */
@@ -3084,6 +3668,7 @@
* Return code: 0, EINVAL, EACCES (if PHY_LOCK is not held)
*/
#define MC_CMD_START_BIST 0x25
+#undef MC_CMD_0x25_PRIVILEGE_CTG
#define MC_CMD_0x25_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -3123,6 +3708,7 @@
* EACCES (if PHY_LOCK is not held).
*/
#define MC_CMD_POLL_BIST 0x26
+#undef MC_CMD_0x26_PRIVILEGE_CTG
#define MC_CMD_0x26_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -3295,11 +3881,14 @@
/* MC_CMD_FLUSH_RX_QUEUES_IN msgrequest */
#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMIN 4
#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMAX 252
+#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMAX_MCDI2 1020
#define MC_CMD_FLUSH_RX_QUEUES_IN_LEN(num) (0+4*(num))
+#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_NUM(len) (((len)-0)/4)
#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_OFST 0
#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_LEN 4
#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MINNUM 1
#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM 63
+#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM_MCDI2 255
/* MC_CMD_FLUSH_RX_QUEUES_OUT msgresponse */
#define MC_CMD_FLUSH_RX_QUEUES_OUT_LEN 0
@@ -3310,6 +3899,7 @@
* Returns a bitmask of loopback modes available at each speed.
*/
#define MC_CMD_GET_LOOPBACK_MODES 0x28
+#undef MC_CMD_0x28_PRIVILEGE_CTG
#define MC_CMD_0x28_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -3605,6 +4195,7 @@
* ETIME.
*/
#define MC_CMD_GET_LINK 0x29
+#undef MC_CMD_0x29_PRIVILEGE_CTG
#define MC_CMD_0x29_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -3635,18 +4226,30 @@
/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
#define MC_CMD_GET_LINK_OUT_FLAGS_OFST 16
#define MC_CMD_GET_LINK_OUT_FLAGS_LEN 4
+#define MC_CMD_GET_LINK_OUT_LINK_UP_OFST 16
#define MC_CMD_GET_LINK_OUT_LINK_UP_LBN 0
#define MC_CMD_GET_LINK_OUT_LINK_UP_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_OFST 16
#define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN 1
#define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_BPX_LINK_OFST 16
#define MC_CMD_GET_LINK_OUT_BPX_LINK_LBN 2
#define MC_CMD_GET_LINK_OUT_BPX_LINK_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_PHY_LINK_OFST 16
#define MC_CMD_GET_LINK_OUT_PHY_LINK_LBN 3
#define MC_CMD_GET_LINK_OUT_PHY_LINK_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_LINK_FAULT_RX_OFST 16
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_RX_LBN 6
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_RX_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_OFST 16
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_LBN 7
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_MODULE_UP_VALID_OFST 16
+#define MC_CMD_GET_LINK_OUT_MODULE_UP_VALID_LBN 8
+#define MC_CMD_GET_LINK_OUT_MODULE_UP_VALID_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_MODULE_UP_OFST 16
+#define MC_CMD_GET_LINK_OUT_MODULE_UP_LBN 9
+#define MC_CMD_GET_LINK_OUT_MODULE_UP_WIDTH 1
/* This returns the negotiated flow control value. */
#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20
#define MC_CMD_GET_LINK_OUT_FCNTL_LEN 4
@@ -3654,12 +4257,16 @@
/* MC_CMD_SET_MAC/MC_CMD_SET_MAC_IN/FCNTL */
#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24
#define MC_CMD_GET_LINK_OUT_MAC_FAULT_LEN 4
+#define MC_CMD_MAC_FAULT_XGMII_LOCAL_OFST 24
#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0
#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1
+#define MC_CMD_MAC_FAULT_XGMII_REMOTE_OFST 24
#define MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1
#define MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1
+#define MC_CMD_MAC_FAULT_SGMII_REMOTE_OFST 24
#define MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2
#define MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1
+#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_OFST 24
#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_LBN 3
#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_WIDTH 1
@@ -3687,18 +4294,30 @@
/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
#define MC_CMD_GET_LINK_OUT_V2_FLAGS_OFST 16
#define MC_CMD_GET_LINK_OUT_V2_FLAGS_LEN 4
+#define MC_CMD_GET_LINK_OUT_V2_LINK_UP_OFST 16
#define MC_CMD_GET_LINK_OUT_V2_LINK_UP_LBN 0
#define MC_CMD_GET_LINK_OUT_V2_LINK_UP_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_FULL_DUPLEX_OFST 16
#define MC_CMD_GET_LINK_OUT_V2_FULL_DUPLEX_LBN 1
#define MC_CMD_GET_LINK_OUT_V2_FULL_DUPLEX_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_BPX_LINK_OFST 16
#define MC_CMD_GET_LINK_OUT_V2_BPX_LINK_LBN 2
#define MC_CMD_GET_LINK_OUT_V2_BPX_LINK_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_PHY_LINK_OFST 16
#define MC_CMD_GET_LINK_OUT_V2_PHY_LINK_LBN 3
#define MC_CMD_GET_LINK_OUT_V2_PHY_LINK_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_RX_OFST 16
#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_RX_LBN 6
#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_RX_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_TX_OFST 16
#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_TX_LBN 7
#define MC_CMD_GET_LINK_OUT_V2_LINK_FAULT_TX_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_MODULE_UP_VALID_OFST 16
+#define MC_CMD_GET_LINK_OUT_V2_MODULE_UP_VALID_LBN 8
+#define MC_CMD_GET_LINK_OUT_V2_MODULE_UP_VALID_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_MODULE_UP_OFST 16
+#define MC_CMD_GET_LINK_OUT_V2_MODULE_UP_LBN 9
+#define MC_CMD_GET_LINK_OUT_V2_MODULE_UP_WIDTH 1
/* This returns the negotiated flow control value. */
#define MC_CMD_GET_LINK_OUT_V2_FCNTL_OFST 20
#define MC_CMD_GET_LINK_OUT_V2_FCNTL_LEN 4
@@ -3706,12 +4325,16 @@
/* MC_CMD_SET_MAC/MC_CMD_SET_MAC_IN/FCNTL */
#define MC_CMD_GET_LINK_OUT_V2_MAC_FAULT_OFST 24
#define MC_CMD_GET_LINK_OUT_V2_MAC_FAULT_LEN 4
+/* MC_CMD_MAC_FAULT_XGMII_LOCAL_OFST 24 */
/* MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0 */
/* MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1 */
+/* MC_CMD_MAC_FAULT_XGMII_REMOTE_OFST 24 */
/* MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1 */
/* MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1 */
+/* MC_CMD_MAC_FAULT_SGMII_REMOTE_OFST 24 */
/* MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2 */
/* MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1 */
+/* MC_CMD_MAC_FAULT_PENDING_RECONFIG_OFST 24 */
/* MC_CMD_MAC_FAULT_PENDING_RECONFIG_LBN 3 */
/* MC_CMD_MAC_FAULT_PENDING_RECONFIG_WIDTH 1 */
/* True local device capabilities (taking into account currently used PMD/MDI,
@@ -3735,32 +4358,45 @@
/* FEC_TYPE/TYPE */
#define MC_CMD_GET_LINK_OUT_V2_EXT_FLAGS_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_EXT_FLAGS_LEN 4
+#define MC_CMD_GET_LINK_OUT_V2_PMD_MDI_CONNECTED_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_PMD_MDI_CONNECTED_LBN 0
#define MC_CMD_GET_LINK_OUT_V2_PMD_MDI_CONNECTED_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_PMD_READY_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_PMD_READY_LBN 1
#define MC_CMD_GET_LINK_OUT_V2_PMD_READY_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_PMD_LINK_UP_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_PMD_LINK_UP_LBN 2
#define MC_CMD_GET_LINK_OUT_V2_PMD_LINK_UP_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_PMA_LINK_UP_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_PMA_LINK_UP_LBN 3
#define MC_CMD_GET_LINK_OUT_V2_PMA_LINK_UP_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_PCS_LOCK_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_PCS_LOCK_LBN 4
#define MC_CMD_GET_LINK_OUT_V2_PCS_LOCK_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_ALIGN_LOCK_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_ALIGN_LOCK_LBN 5
#define MC_CMD_GET_LINK_OUT_V2_ALIGN_LOCK_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_HI_BER_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_HI_BER_LBN 6
#define MC_CMD_GET_LINK_OUT_V2_HI_BER_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_FEC_LOCK_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_FEC_LOCK_LBN 7
#define MC_CMD_GET_LINK_OUT_V2_FEC_LOCK_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_AN_DONE_OFST 40
#define MC_CMD_GET_LINK_OUT_V2_AN_DONE_LBN 8
#define MC_CMD_GET_LINK_OUT_V2_AN_DONE_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_V2_PORT_SHUTDOWN_OFST 40
+#define MC_CMD_GET_LINK_OUT_V2_PORT_SHUTDOWN_LBN 9
+#define MC_CMD_GET_LINK_OUT_V2_PORT_SHUTDOWN_WIDTH 1
/***********************************/
/* MC_CMD_SET_LINK
* Write the unified MAC/PHY link configuration. Locks required: None. Return
- * code: 0, EINVAL, ETIME
+ * code: 0, EINVAL, ETIME, EAGAIN
*/
#define MC_CMD_SET_LINK 0x2a
+#undef MC_CMD_0x2a_PRIVILEGE_CTG
#define MC_CMD_0x2a_PRIVILEGE_CTG SRIOV_CTG_LINK
@@ -3774,12 +4410,18 @@
/* Flags */
#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4
#define MC_CMD_SET_LINK_IN_FLAGS_LEN 4
+#define MC_CMD_SET_LINK_IN_LOWPOWER_OFST 4
#define MC_CMD_SET_LINK_IN_LOWPOWER_LBN 0
#define MC_CMD_SET_LINK_IN_LOWPOWER_WIDTH 1
+#define MC_CMD_SET_LINK_IN_POWEROFF_OFST 4
#define MC_CMD_SET_LINK_IN_POWEROFF_LBN 1
#define MC_CMD_SET_LINK_IN_POWEROFF_WIDTH 1
+#define MC_CMD_SET_LINK_IN_TXDIS_OFST 4
#define MC_CMD_SET_LINK_IN_TXDIS_LBN 2
#define MC_CMD_SET_LINK_IN_TXDIS_WIDTH 1
+#define MC_CMD_SET_LINK_IN_LINKDOWN_OFST 4
+#define MC_CMD_SET_LINK_IN_LINKDOWN_LBN 3
+#define MC_CMD_SET_LINK_IN_LINKDOWN_WIDTH 1
/* Loopback mode. */
#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8
#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_LEN 4
@@ -3791,6 +4433,50 @@
#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12
#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_LEN 4
+/* MC_CMD_SET_LINK_IN_V2 msgrequest: Updated SET_LINK to include sequence
+ * number to ensure this SET_LINK command corresponds to the latest
+ * MODULECHANGE event.
+ */
+#define MC_CMD_SET_LINK_IN_V2_LEN 17
+/* Near-side advertised capabilities. Refer to
+ * MC_CMD_GET_PHY_CFG_OUT/SUPPORTED_CAP for bit definitions.
+ */
+#define MC_CMD_SET_LINK_IN_V2_CAP_OFST 0
+#define MC_CMD_SET_LINK_IN_V2_CAP_LEN 4
+/* Flags */
+#define MC_CMD_SET_LINK_IN_V2_FLAGS_OFST 4
+#define MC_CMD_SET_LINK_IN_V2_FLAGS_LEN 4
+#define MC_CMD_SET_LINK_IN_V2_LOWPOWER_OFST 4
+#define MC_CMD_SET_LINK_IN_V2_LOWPOWER_LBN 0
+#define MC_CMD_SET_LINK_IN_V2_LOWPOWER_WIDTH 1
+#define MC_CMD_SET_LINK_IN_V2_POWEROFF_OFST 4
+#define MC_CMD_SET_LINK_IN_V2_POWEROFF_LBN 1
+#define MC_CMD_SET_LINK_IN_V2_POWEROFF_WIDTH 1
+#define MC_CMD_SET_LINK_IN_V2_TXDIS_OFST 4
+#define MC_CMD_SET_LINK_IN_V2_TXDIS_LBN 2
+#define MC_CMD_SET_LINK_IN_V2_TXDIS_WIDTH 1
+#define MC_CMD_SET_LINK_IN_V2_LINKDOWN_OFST 4
+#define MC_CMD_SET_LINK_IN_V2_LINKDOWN_LBN 3
+#define MC_CMD_SET_LINK_IN_V2_LINKDOWN_WIDTH 1
+/* Loopback mode. */
+#define MC_CMD_SET_LINK_IN_V2_LOOPBACK_MODE_OFST 8
+#define MC_CMD_SET_LINK_IN_V2_LOOPBACK_MODE_LEN 4
+/* Enum values, see field(s): */
+/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
+/* A loopback speed of "0" is supported, and means (choose any available
+ * speed).
+ */
+#define MC_CMD_SET_LINK_IN_V2_LOOPBACK_SPEED_OFST 12
+#define MC_CMD_SET_LINK_IN_V2_LOOPBACK_SPEED_LEN 4
+#define MC_CMD_SET_LINK_IN_V2_MODULE_SEQ_OFST 16
+#define MC_CMD_SET_LINK_IN_V2_MODULE_SEQ_LEN 1
+#define MC_CMD_SET_LINK_IN_V2_MODULE_SEQ_NUMBER_OFST 16
+#define MC_CMD_SET_LINK_IN_V2_MODULE_SEQ_NUMBER_LBN 0
+#define MC_CMD_SET_LINK_IN_V2_MODULE_SEQ_NUMBER_WIDTH 7
+#define MC_CMD_SET_LINK_IN_V2_MODULE_SEQ_IGNORE_OFST 16
+#define MC_CMD_SET_LINK_IN_V2_MODULE_SEQ_IGNORE_LBN 7
+#define MC_CMD_SET_LINK_IN_V2_MODULE_SEQ_IGNORE_WIDTH 1
+
/* MC_CMD_SET_LINK_OUT msgresponse */
#define MC_CMD_SET_LINK_OUT_LEN 0
@@ -3800,6 +4486,7 @@
* Set identification LED state. Locks required: None. Return code: 0, EINVAL
*/
#define MC_CMD_SET_ID_LED 0x2b
+#undef MC_CMD_0x2b_PRIVILEGE_CTG
#define MC_CMD_0x2b_PRIVILEGE_CTG SRIOV_CTG_LINK
@@ -3821,6 +4508,7 @@
* Set MAC configuration. Locks required: None. Return code: 0, EINVAL
*/
#define MC_CMD_SET_MAC 0x2c
+#undef MC_CMD_0x2c_PRIVILEGE_CTG
#define MC_CMD_0x2c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -3839,8 +4527,10 @@
#define MC_CMD_SET_MAC_IN_ADDR_HI_OFST 12
#define MC_CMD_SET_MAC_IN_REJECT_OFST 16
#define MC_CMD_SET_MAC_IN_REJECT_LEN 4
+#define MC_CMD_SET_MAC_IN_REJECT_UNCST_OFST 16
#define MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0
#define MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1
+#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_OFST 16
#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1
#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1
#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20
@@ -3859,6 +4549,7 @@
#define MC_CMD_FCNTL_GENERATE 0x5
#define MC_CMD_SET_MAC_IN_FLAGS_OFST 24
#define MC_CMD_SET_MAC_IN_FLAGS_LEN 4
+#define MC_CMD_SET_MAC_IN_FLAG_INCLUDE_FCS_OFST 24
#define MC_CMD_SET_MAC_IN_FLAG_INCLUDE_FCS_LBN 0
#define MC_CMD_SET_MAC_IN_FLAG_INCLUDE_FCS_WIDTH 1
@@ -3877,8 +4568,10 @@
#define MC_CMD_SET_MAC_EXT_IN_ADDR_HI_OFST 12
#define MC_CMD_SET_MAC_EXT_IN_REJECT_OFST 16
#define MC_CMD_SET_MAC_EXT_IN_REJECT_LEN 4
+#define MC_CMD_SET_MAC_EXT_IN_REJECT_UNCST_OFST 16
#define MC_CMD_SET_MAC_EXT_IN_REJECT_UNCST_LBN 0
#define MC_CMD_SET_MAC_EXT_IN_REJECT_UNCST_WIDTH 1
+#define MC_CMD_SET_MAC_EXT_IN_REJECT_BRDCST_OFST 16
#define MC_CMD_SET_MAC_EXT_IN_REJECT_BRDCST_LBN 1
#define MC_CMD_SET_MAC_EXT_IN_REJECT_BRDCST_WIDTH 1
#define MC_CMD_SET_MAC_EXT_IN_FCNTL_OFST 20
@@ -3897,6 +4590,7 @@
/* MC_CMD_FCNTL_GENERATE 0x5 */
#define MC_CMD_SET_MAC_EXT_IN_FLAGS_OFST 24
#define MC_CMD_SET_MAC_EXT_IN_FLAGS_LEN 4
+#define MC_CMD_SET_MAC_EXT_IN_FLAG_INCLUDE_FCS_OFST 24
#define MC_CMD_SET_MAC_EXT_IN_FLAG_INCLUDE_FCS_LBN 0
#define MC_CMD_SET_MAC_EXT_IN_FLAG_INCLUDE_FCS_WIDTH 1
/* Select which parameters to configure. A parameter will only be modified if
@@ -3906,14 +4600,19 @@
*/
#define MC_CMD_SET_MAC_EXT_IN_CONTROL_OFST 28
#define MC_CMD_SET_MAC_EXT_IN_CONTROL_LEN 4
+#define MC_CMD_SET_MAC_EXT_IN_CFG_MTU_OFST 28
#define MC_CMD_SET_MAC_EXT_IN_CFG_MTU_LBN 0
#define MC_CMD_SET_MAC_EXT_IN_CFG_MTU_WIDTH 1
+#define MC_CMD_SET_MAC_EXT_IN_CFG_DRAIN_OFST 28
#define MC_CMD_SET_MAC_EXT_IN_CFG_DRAIN_LBN 1
#define MC_CMD_SET_MAC_EXT_IN_CFG_DRAIN_WIDTH 1
+#define MC_CMD_SET_MAC_EXT_IN_CFG_REJECT_OFST 28
#define MC_CMD_SET_MAC_EXT_IN_CFG_REJECT_LBN 2
#define MC_CMD_SET_MAC_EXT_IN_CFG_REJECT_WIDTH 1
+#define MC_CMD_SET_MAC_EXT_IN_CFG_FCNTL_OFST 28
#define MC_CMD_SET_MAC_EXT_IN_CFG_FCNTL_LBN 3
#define MC_CMD_SET_MAC_EXT_IN_CFG_FCNTL_WIDTH 1
+#define MC_CMD_SET_MAC_EXT_IN_CFG_FCS_OFST 28
#define MC_CMD_SET_MAC_EXT_IN_CFG_FCS_LBN 4
#define MC_CMD_SET_MAC_EXT_IN_CFG_FCS_WIDTH 1
@@ -3940,6 +4639,7 @@
* Returns: 0, ETIME
*/
#define MC_CMD_PHY_STATS 0x2d
+#undef MC_CMD_0x2d_PRIVILEGE_CTG
#define MC_CMD_0x2d_PRIVILEGE_CTG SRIOV_CTG_LINK
@@ -4021,6 +4721,7 @@
* effect. Returns: 0, ETIME
*/
#define MC_CMD_MAC_STATS 0x2e
+#undef MC_CMD_0x2e_PRIVILEGE_CTG
#define MC_CMD_0x2e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -4033,18 +4734,25 @@
#define MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4
#define MC_CMD_MAC_STATS_IN_CMD_OFST 8
#define MC_CMD_MAC_STATS_IN_CMD_LEN 4
+#define MC_CMD_MAC_STATS_IN_DMA_OFST 8
#define MC_CMD_MAC_STATS_IN_DMA_LBN 0
#define MC_CMD_MAC_STATS_IN_DMA_WIDTH 1
+#define MC_CMD_MAC_STATS_IN_CLEAR_OFST 8
#define MC_CMD_MAC_STATS_IN_CLEAR_LBN 1
#define MC_CMD_MAC_STATS_IN_CLEAR_WIDTH 1
+#define MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_OFST 8
#define MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_LBN 2
#define MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_WIDTH 1
+#define MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_OFST 8
#define MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_LBN 3
#define MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_WIDTH 1
+#define MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_OFST 8
#define MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_LBN 4
#define MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_WIDTH 1
+#define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_OFST 8
#define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_LBN 5
#define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_WIDTH 1
+#define MC_CMD_MAC_STATS_IN_PERIOD_MS_OFST 8
#define MC_CMD_MAC_STATS_IN_PERIOD_MS_LBN 16
#define MC_CMD_MAC_STATS_IN_PERIOD_MS_WIDTH 16
/* DMA length. Should be set to MAC_STATS_NUM_STATS * sizeof(uint64_t), as
@@ -4321,6 +5029,37 @@
/* Other enum values, see field(s): */
/* MC_CMD_MAC_STATS_V2_OUT_NO_DMA/STATISTICS */
+/* MC_CMD_MAC_STATS_V4_OUT_DMA msgresponse */
+#define MC_CMD_MAC_STATS_V4_OUT_DMA_LEN 0
+
+/* MC_CMD_MAC_STATS_V4_OUT_NO_DMA msgresponse */
+#define MC_CMD_MAC_STATS_V4_OUT_NO_DMA_LEN (((MC_CMD_MAC_NSTATS_V4*64))>>3)
+#define MC_CMD_MAC_STATS_V4_OUT_NO_DMA_STATISTICS_OFST 0
+#define MC_CMD_MAC_STATS_V4_OUT_NO_DMA_STATISTICS_LEN 8
+#define MC_CMD_MAC_STATS_V4_OUT_NO_DMA_STATISTICS_LO_OFST 0
+#define MC_CMD_MAC_STATS_V4_OUT_NO_DMA_STATISTICS_HI_OFST 4
+#define MC_CMD_MAC_STATS_V4_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS_V4
+/* enum: Start of V4 stats buffer space */
+#define MC_CMD_MAC_V4_DMABUF_START 0x79
+/* enum: RXDP counter: Number of packets truncated because scattering was
+ * disabled.
+ */
+#define MC_CMD_MAC_RXDP_SCATTER_DISABLED_TRUNC 0x79
+/* enum: RXDP counter: Number of times the RXDP head of line blocked waiting
+ * for descriptors. Will be zero unless RXDP_HLB_IDLE capability is set.
+ */
+#define MC_CMD_MAC_RXDP_HLB_IDLE 0x7a
+/* enum: RXDP counter: Number of times the RXDP timed out while head of line
+ * blocking. Will be zero unless RXDP_HLB_IDLE capability is set.
+ */
+#define MC_CMD_MAC_RXDP_HLB_TIMEOUT 0x7b
+/* enum: This includes the space at offset 124 which is the final
+ * GENERATION_END in a MAC_STATS_V4 response and otherwise unused.
+ */
+#define MC_CMD_MAC_NSTATS_V4 0x7d
+/* Other enum values, see field(s): */
+/* MC_CMD_MAC_STATS_V3_OUT_NO_DMA/STATISTICS */
+
/***********************************/
/* MC_CMD_SRIOV
@@ -4403,12 +5142,15 @@
/* MC_CMD_MEMCPY_IN msgrequest */
#define MC_CMD_MEMCPY_IN_LENMIN 32
#define MC_CMD_MEMCPY_IN_LENMAX 224
+#define MC_CMD_MEMCPY_IN_LENMAX_MCDI2 992
#define MC_CMD_MEMCPY_IN_LEN(num) (0+32*(num))
+#define MC_CMD_MEMCPY_IN_RECORD_NUM(len) (((len)-0)/32)
/* see MC_CMD_MEMCPY_RECORD_TYPEDEF */
#define MC_CMD_MEMCPY_IN_RECORD_OFST 0
#define MC_CMD_MEMCPY_IN_RECORD_LEN 32
#define MC_CMD_MEMCPY_IN_RECORD_MINNUM 1
#define MC_CMD_MEMCPY_IN_RECORD_MAXNUM 7
+#define MC_CMD_MEMCPY_IN_RECORD_MAXNUM_MCDI2 31
/* MC_CMD_MEMCPY_OUT msgresponse */
#define MC_CMD_MEMCPY_OUT_LEN 0
@@ -4419,6 +5161,7 @@
* Set a WoL filter.
*/
#define MC_CMD_WOL_FILTER_SET 0x32
+#undef MC_CMD_0x32_PRIVILEGE_CTG
#define MC_CMD_0x32_PRIVILEGE_CTG SRIOV_CTG_LINK
@@ -4515,8 +5258,10 @@
/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_LEN 4 */
#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST 8
#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_LEN 4
+#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_OFST 8
#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN 0
#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH 1
+#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_OFST 8
#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN 1
#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_WIDTH 1
@@ -4531,6 +5276,7 @@
* Remove a WoL filter. Locks required: None. Returns: 0, EINVAL, ENOSYS
*/
#define MC_CMD_WOL_FILTER_REMOVE 0x33
+#undef MC_CMD_0x33_PRIVILEGE_CTG
#define MC_CMD_0x33_PRIVILEGE_CTG SRIOV_CTG_LINK
@@ -4549,6 +5295,7 @@
* ENOSYS
*/
#define MC_CMD_WOL_FILTER_RESET 0x34
+#undef MC_CMD_0x34_PRIVILEGE_CTG
#define MC_CMD_0x34_PRIVILEGE_CTG SRIOV_CTG_LINK
@@ -4586,6 +5333,7 @@
* Locks required: none. Returns: 0
*/
#define MC_CMD_NVRAM_TYPES 0x36
+#undef MC_CMD_0x36_PRIVILEGE_CTG
#define MC_CMD_0x36_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -4647,6 +5395,7 @@
* EINVAL (bad type).
*/
#define MC_CMD_NVRAM_INFO 0x37
+#undef MC_CMD_0x37_PRIVILEGE_CTG
#define MC_CMD_0x37_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -4669,16 +5418,25 @@
#define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_LEN 4
#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12
#define MC_CMD_NVRAM_INFO_OUT_FLAGS_LEN 4
+#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_OFST 12
#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN 0
#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_TLV_OFST 12
#define MC_CMD_NVRAM_INFO_OUT_TLV_LBN 1
#define MC_CMD_NVRAM_INFO_OUT_TLV_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_IF_TSA_BOUND_OFST 12
#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_IF_TSA_BOUND_LBN 2
#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_IF_TSA_BOUND_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_CRC_OFST 12
+#define MC_CMD_NVRAM_INFO_OUT_CRC_LBN 3
+#define MC_CMD_NVRAM_INFO_OUT_CRC_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_OFST 12
#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_LBN 5
#define MC_CMD_NVRAM_INFO_OUT_READ_ONLY_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_CMAC_OFST 12
#define MC_CMD_NVRAM_INFO_OUT_CMAC_LBN 6
#define MC_CMD_NVRAM_INFO_OUT_CMAC_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_A_B_OFST 12
#define MC_CMD_NVRAM_INFO_OUT_A_B_LBN 7
#define MC_CMD_NVRAM_INFO_OUT_A_B_WIDTH 1
#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16
@@ -4698,14 +5456,19 @@
#define MC_CMD_NVRAM_INFO_V2_OUT_ERASESIZE_LEN 4
#define MC_CMD_NVRAM_INFO_V2_OUT_FLAGS_OFST 12
#define MC_CMD_NVRAM_INFO_V2_OUT_FLAGS_LEN 4
+#define MC_CMD_NVRAM_INFO_V2_OUT_PROTECTED_OFST 12
#define MC_CMD_NVRAM_INFO_V2_OUT_PROTECTED_LBN 0
#define MC_CMD_NVRAM_INFO_V2_OUT_PROTECTED_WIDTH 1
+#define MC_CMD_NVRAM_INFO_V2_OUT_TLV_OFST 12
#define MC_CMD_NVRAM_INFO_V2_OUT_TLV_LBN 1
#define MC_CMD_NVRAM_INFO_V2_OUT_TLV_WIDTH 1
+#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_IF_TSA_BOUND_OFST 12
#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_IF_TSA_BOUND_LBN 2
#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_IF_TSA_BOUND_WIDTH 1
+#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_OFST 12
#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_LBN 5
#define MC_CMD_NVRAM_INFO_V2_OUT_READ_ONLY_WIDTH 1
+#define MC_CMD_NVRAM_INFO_V2_OUT_A_B_OFST 12
#define MC_CMD_NVRAM_INFO_V2_OUT_A_B_LBN 7
#define MC_CMD_NVRAM_INFO_V2_OUT_A_B_WIDTH 1
#define MC_CMD_NVRAM_INFO_V2_OUT_PHYSDEV_OFST 16
@@ -4729,6 +5492,7 @@
* EPERM.
*/
#define MC_CMD_NVRAM_UPDATE_START 0x38
+#undef MC_CMD_0x38_PRIVILEGE_CTG
#define MC_CMD_0x38_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -4753,6 +5517,7 @@
/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
#define MC_CMD_NVRAM_UPDATE_START_V2_IN_FLAGS_OFST 4
#define MC_CMD_NVRAM_UPDATE_START_V2_IN_FLAGS_LEN 4
+#define MC_CMD_NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT_OFST 4
#define MC_CMD_NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT_LBN 0
#define MC_CMD_NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT_WIDTH 1
@@ -4767,6 +5532,7 @@
* PHY_LOCK required and not held)
*/
#define MC_CMD_NVRAM_READ 0x39
+#undef MC_CMD_0x39_PRIVILEGE_CTG
#define MC_CMD_0x39_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -4820,11 +5586,14 @@
/* MC_CMD_NVRAM_READ_OUT msgresponse */
#define MC_CMD_NVRAM_READ_OUT_LENMIN 1
#define MC_CMD_NVRAM_READ_OUT_LENMAX 252
+#define MC_CMD_NVRAM_READ_OUT_LENMAX_MCDI2 1020
#define MC_CMD_NVRAM_READ_OUT_LEN(num) (0+1*(num))
+#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_NUM(len) (((len)-0)/1)
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_LEN 1
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MINNUM 1
#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MAXNUM 252
+#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MAXNUM_MCDI2 1020
/***********************************/
@@ -4834,13 +5603,16 @@
* PHY_LOCK required and not held)
*/
#define MC_CMD_NVRAM_WRITE 0x3a
+#undef MC_CMD_0x3a_PRIVILEGE_CTG
#define MC_CMD_0x3a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_WRITE_IN msgrequest */
#define MC_CMD_NVRAM_WRITE_IN_LENMIN 13
#define MC_CMD_NVRAM_WRITE_IN_LENMAX 252
+#define MC_CMD_NVRAM_WRITE_IN_LENMAX_MCDI2 1020
#define MC_CMD_NVRAM_WRITE_IN_LEN(num) (12+1*(num))
+#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_NUM(len) (((len)-12)/1)
#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0
#define MC_CMD_NVRAM_WRITE_IN_TYPE_LEN 4
/* Enum values, see field(s): */
@@ -4853,6 +5625,7 @@
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN 1
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MINNUM 1
#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM 240
+#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM_MCDI2 1008
/* MC_CMD_NVRAM_WRITE_OUT msgresponse */
#define MC_CMD_NVRAM_WRITE_OUT_LEN 0
@@ -4865,6 +5638,7 @@
* PHY_LOCK required and not held)
*/
#define MC_CMD_NVRAM_ERASE 0x3b
+#undef MC_CMD_0x3b_PRIVILEGE_CTG
#define MC_CMD_0x3b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -4894,6 +5668,7 @@
* the error EPERM.
*/
#define MC_CMD_NVRAM_UPDATE_FINISH 0x3c
+#undef MC_CMD_0x3c_PRIVILEGE_CTG
#define MC_CMD_0x3c_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -4922,8 +5697,15 @@
#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_REBOOT_LEN 4
#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAGS_OFST 8
#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAGS_LEN 4
+#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT_OFST 8
#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT_LBN 0
#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT_WIDTH 1
+#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_RUN_IN_BACKGROUND_OFST 8
+#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_RUN_IN_BACKGROUND_LBN 1
+#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_RUN_IN_BACKGROUND_WIDTH 1
+#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_POLL_VERIFY_RESULT_OFST 8
+#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_POLL_VERIFY_RESULT_LBN 2
+#define MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_FLAG_POLL_VERIFY_RESULT_WIDTH 1
/* MC_CMD_NVRAM_UPDATE_FINISH_OUT msgresponse: Legacy NVRAM_UPDATE_FINISH
* response. Use NVRAM_UPDATE_FINISH_V2_OUT in new code
@@ -4946,7 +5728,10 @@
* has completed.
*/
#define MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN 4
-/* Result of nvram update completion processing */
+/* Result of nvram update completion processing. Result codes that indicate an
+ * internal build failure and therefore not expected to be seen by customers in
+ * the field are marked with a prefix 'Internal-error'.
+ */
#define MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE_OFST 0
#define MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE_LEN 4
/* enum: Invalid return code; only non-zero values are defined. Defined as
@@ -4985,6 +5770,51 @@
#define MC_CMD_NVRAM_VERIFY_RC_REJECT_TEST_SIGNED 0xc
/* enum: The image has a lower security level than the current firmware. */
#define MC_CMD_NVRAM_VERIFY_RC_SECURITY_LEVEL_DOWNGRADE 0xd
+/* enum: Internal-error. The signed image is missing the 'contents' section,
+ * where the 'contents' section holds the actual image payload to be applied.
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_CONTENT_NOT_FOUND 0xe
+/* enum: Internal-error. The bundle header is invalid. */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_CONTENT_HEADER_INVALID 0xf
+/* enum: Internal-error. The bundle does not have a valid reflash image layout.
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_REFLASH_IMAGE_INVALID 0x10
+/* enum: Internal-error. The bundle has an inconsistent layout of components or
+ * incorrect checksum.
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_IMAGE_LAYOUT_INVALID 0x11
+/* enum: Internal-error. The bundle manifest is inconsistent with components in
+ * the bundle.
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_MANIFEST_INVALID 0x12
+/* enum: Internal-error. The number of components in a bundle do not match the
+ * number of components advertised by the bundle manifest.
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_MANIFEST_NUM_COMPONENTS_MISMATCH 0x13
+/* enum: Internal-error. The bundle contains too many components for the MC
+ * firmware to process
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_MANIFEST_TOO_MANY_COMPONENTS 0x14
+/* enum: Internal-error. The bundle manifest has an invalid/inconsistent
+ * component.
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_MANIFEST_COMPONENT_INVALID 0x15
+/* enum: Internal-error. The hash of a component does not match the hash stored
+ * in the bundle manifest.
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_MANIFEST_COMPONENT_HASH_MISMATCH 0x16
+/* enum: Internal-error. Component hash calculation failed. */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_MANIFEST_COMPONENT_HASH_FAILED 0x17
+/* enum: Internal-error. The component does not have a valid reflash image
+ * layout.
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_COMPONENT_REFLASH_IMAGE_INVALID 0x18
+/* enum: The bundle processing code failed to copy a component to its target
+ * partition.
+ */
+#define MC_CMD_NVRAM_VERIFY_RC_BUNDLE_COMPONENT_COPY_FAILED 0x19
+/* enum: The update operation is in-progress. */
+#define MC_CMD_NVRAM_VERIFY_RC_PENDING 0x1a
/***********************************/
@@ -5006,6 +5836,7 @@
* DATALEN=0
*/
#define MC_CMD_REBOOT 0x3d
+#undef MC_CMD_0x3d_PRIVILEGE_CTG
#define MC_CMD_0x3d_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -5026,6 +5857,7 @@
* thread address.
*/
#define MC_CMD_SCHEDINFO 0x3e
+#undef MC_CMD_0x3e_PRIVILEGE_CTG
#define MC_CMD_0x3e_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -5035,11 +5867,14 @@
/* MC_CMD_SCHEDINFO_OUT msgresponse */
#define MC_CMD_SCHEDINFO_OUT_LENMIN 4
#define MC_CMD_SCHEDINFO_OUT_LENMAX 252
+#define MC_CMD_SCHEDINFO_OUT_LENMAX_MCDI2 1020
#define MC_CMD_SCHEDINFO_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_SCHEDINFO_OUT_DATA_NUM(len) (((len)-0)/4)
#define MC_CMD_SCHEDINFO_OUT_DATA_OFST 0
#define MC_CMD_SCHEDINFO_OUT_DATA_LEN 4
#define MC_CMD_SCHEDINFO_OUT_DATA_MINNUM 1
#define MC_CMD_SCHEDINFO_OUT_DATA_MAXNUM 63
+#define MC_CMD_SCHEDINFO_OUT_DATA_MAXNUM_MCDI2 255
/***********************************/
@@ -5048,6 +5883,7 @@
* mode to the specified value. Returns the old mode.
*/
#define MC_CMD_REBOOT_MODE 0x3f
+#undef MC_CMD_0x3f_PRIVILEGE_CTG
#define MC_CMD_0x3f_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -5063,6 +5899,7 @@
#define MC_CMD_REBOOT_MODE_SNAPPER 0x3
/* enum: snapper fake POR */
#define MC_CMD_REBOOT_MODE_SNAPPER_POR 0x4
+#define MC_CMD_REBOOT_MODE_IN_FAKE_OFST 0
#define MC_CMD_REBOOT_MODE_IN_FAKE_LBN 7
#define MC_CMD_REBOOT_MODE_IN_FAKE_WIDTH 1
@@ -5104,6 +5941,7 @@
* Locks required: None Returns: 0
*/
#define MC_CMD_SENSOR_INFO 0x41
+#undef MC_CMD_0x41_PRIVILEGE_CTG
#define MC_CMD_0x41_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -5121,10 +5959,29 @@
#define MC_CMD_SENSOR_INFO_EXT_IN_PAGE_OFST 0
#define MC_CMD_SENSOR_INFO_EXT_IN_PAGE_LEN 4
+/* MC_CMD_SENSOR_INFO_EXT_IN_V2 msgrequest */
+#define MC_CMD_SENSOR_INFO_EXT_IN_V2_LEN 8
+/* Which page of sensors to report.
+ *
+ * Page 0 contains sensors 0 to 30 (sensor 31 is the next page bit).
+ *
+ * Page 1 contains sensors 32 to 62 (sensor 63 is the next page bit). etc.
+ */
+#define MC_CMD_SENSOR_INFO_EXT_IN_V2_PAGE_OFST 0
+#define MC_CMD_SENSOR_INFO_EXT_IN_V2_PAGE_LEN 4
+/* Flags controlling information retrieved */
+#define MC_CMD_SENSOR_INFO_EXT_IN_V2_FLAGS_OFST 4
+#define MC_CMD_SENSOR_INFO_EXT_IN_V2_FLAGS_LEN 4
+#define MC_CMD_SENSOR_INFO_EXT_IN_V2_ENGINEERING_OFST 4
+#define MC_CMD_SENSOR_INFO_EXT_IN_V2_ENGINEERING_LBN 0
+#define MC_CMD_SENSOR_INFO_EXT_IN_V2_ENGINEERING_WIDTH 1
+
/* MC_CMD_SENSOR_INFO_OUT msgresponse */
#define MC_CMD_SENSOR_INFO_OUT_LENMIN 4
#define MC_CMD_SENSOR_INFO_OUT_LENMAX 252
+#define MC_CMD_SENSOR_INFO_OUT_LENMAX_MCDI2 1020
#define MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num))
+#define MC_CMD_SENSOR_INFO_OUT_MC_CMD_SENSOR_ENTRY_NUM(len) (((len)-4)/8)
#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0
#define MC_CMD_SENSOR_INFO_OUT_MASK_LEN 4
/* enum: Controller temperature: degC */
@@ -5301,6 +6158,22 @@
#define MC_CMD_SENSOR_IN_1V3 0x55
/* enum: 1.3v power current: mA */
#define MC_CMD_SENSOR_IN_I1V3 0x56
+/* enum: Engineering sensor 1 */
+#define MC_CMD_SENSOR_ENGINEERING_1 0x57
+/* enum: Engineering sensor 2 */
+#define MC_CMD_SENSOR_ENGINEERING_2 0x58
+/* enum: Engineering sensor 3 */
+#define MC_CMD_SENSOR_ENGINEERING_3 0x59
+/* enum: Engineering sensor 4 */
+#define MC_CMD_SENSOR_ENGINEERING_4 0x5a
+/* enum: Engineering sensor 5 */
+#define MC_CMD_SENSOR_ENGINEERING_5 0x5b
+/* enum: Engineering sensor 6 */
+#define MC_CMD_SENSOR_ENGINEERING_6 0x5c
+/* enum: Engineering sensor 7 */
+#define MC_CMD_SENSOR_ENGINEERING_7 0x5d
+/* enum: Engineering sensor 8 */
+#define MC_CMD_SENSOR_ENGINEERING_8 0x5e
/* enum: Not a sensor: reserved for the next page flag */
#define MC_CMD_SENSOR_PAGE2_NEXT 0x5f
/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */
@@ -5310,15 +6183,19 @@
#define MC_CMD_SENSOR_ENTRY_HI_OFST 8
#define MC_CMD_SENSOR_ENTRY_MINNUM 0
#define MC_CMD_SENSOR_ENTRY_MAXNUM 31
+#define MC_CMD_SENSOR_ENTRY_MAXNUM_MCDI2 127
/* MC_CMD_SENSOR_INFO_EXT_OUT msgresponse */
#define MC_CMD_SENSOR_INFO_EXT_OUT_LENMIN 4
#define MC_CMD_SENSOR_INFO_EXT_OUT_LENMAX 252
+#define MC_CMD_SENSOR_INFO_EXT_OUT_LENMAX_MCDI2 1020
#define MC_CMD_SENSOR_INFO_EXT_OUT_LEN(num) (4+8*(num))
+#define MC_CMD_SENSOR_INFO_EXT_OUT_MC_CMD_SENSOR_ENTRY_NUM(len) (((len)-4)/8)
#define MC_CMD_SENSOR_INFO_EXT_OUT_MASK_OFST 0
#define MC_CMD_SENSOR_INFO_EXT_OUT_MASK_LEN 4
/* Enum values, see field(s): */
/* MC_CMD_SENSOR_INFO_OUT */
+#define MC_CMD_SENSOR_INFO_EXT_OUT_NEXT_PAGE_OFST 0
#define MC_CMD_SENSOR_INFO_EXT_OUT_NEXT_PAGE_LBN 31
#define MC_CMD_SENSOR_INFO_EXT_OUT_NEXT_PAGE_WIDTH 1
/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */
@@ -5328,6 +6205,7 @@
/* MC_CMD_SENSOR_ENTRY_HI_OFST 8 */
/* MC_CMD_SENSOR_ENTRY_MINNUM 0 */
/* MC_CMD_SENSOR_ENTRY_MAXNUM 31 */
+/* MC_CMD_SENSOR_ENTRY_MAXNUM_MCDI2 127 */
/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF structuredef */
#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN 8
@@ -5367,12 +6245,17 @@
* STATE_WARNING. Otherwise the board should not be expected to function.
*/
#define MC_CMD_READ_SENSORS 0x42
+#undef MC_CMD_0x42_PRIVILEGE_CTG
#define MC_CMD_0x42_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_READ_SENSORS_IN msgrequest */
#define MC_CMD_READ_SENSORS_IN_LEN 8
-/* DMA address of host buffer for sensor readings (must be 4Kbyte aligned). */
+/* DMA address of host buffer for sensor readings (must be 4Kbyte aligned).
+ *
+ * If the address is 0xffffffffffffffff send the readings in the response (used
+ * by cmdclient).
+ */
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_OFST 0
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LEN 8
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0
@@ -5380,7 +6263,11 @@
/* MC_CMD_READ_SENSORS_EXT_IN msgrequest */
#define MC_CMD_READ_SENSORS_EXT_IN_LEN 12
-/* DMA address of host buffer for sensor readings (must be 4Kbyte aligned). */
+/* DMA address of host buffer for sensor readings (must be 4Kbyte aligned).
+ *
+ * If the address is 0xffffffffffffffff send the readings in the response (used
+ * by cmdclient).
+ */
#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_OFST 0
#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_LEN 8
#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_LO_OFST 0
@@ -5389,6 +6276,27 @@
#define MC_CMD_READ_SENSORS_EXT_IN_LENGTH_OFST 8
#define MC_CMD_READ_SENSORS_EXT_IN_LENGTH_LEN 4
+/* MC_CMD_READ_SENSORS_EXT_IN_V2 msgrequest */
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_LEN 16
+/* DMA address of host buffer for sensor readings (must be 4Kbyte aligned).
+ *
+ * If the address is 0xffffffffffffffff send the readings in the response (used
+ * by cmdclient).
+ */
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_DMA_ADDR_OFST 0
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_DMA_ADDR_LEN 8
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_DMA_ADDR_LO_OFST 0
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_DMA_ADDR_HI_OFST 4
+/* Size in bytes of host buffer. */
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_LENGTH_OFST 8
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_LENGTH_LEN 4
+/* Flags controlling information retrieved */
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_FLAGS_OFST 12
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_FLAGS_LEN 4
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_ENGINEERING_OFST 12
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_ENGINEERING_LBN 0
+#define MC_CMD_READ_SENSORS_EXT_IN_V2_ENGINEERING_WIDTH 1
+
/* MC_CMD_READ_SENSORS_OUT msgresponse */
#define MC_CMD_READ_SENSORS_OUT_LEN 0
@@ -5432,6 +6340,7 @@
* code: 0
*/
#define MC_CMD_GET_PHY_STATE 0x43
+#undef MC_CMD_0x43_PRIVILEGE_CTG
#define MC_CMD_0x43_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -5469,6 +6378,7 @@
* Retrieve ID of any WoL filters. Locks required: None. Returns: 0, ENOSYS
*/
#define MC_CMD_WOL_FILTER_GET 0x45
+#undef MC_CMD_0x45_PRIVILEGE_CTG
#define MC_CMD_0x45_PRIVILEGE_CTG SRIOV_CTG_LINK
@@ -5487,13 +6397,16 @@
* Returns: 0, ENOSYS
*/
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46
+#undef MC_CMD_0x46_PRIVILEGE_CTG
#define MC_CMD_0x46_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN msgrequest */
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMIN 8
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMAX 252
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMAX_MCDI2 1020
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN(num) (4+4*(num))
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_NUM(len) (((len)-4)/4)
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_LEN 4
#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 /* enum */
@@ -5502,6 +6415,7 @@
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_LEN 4
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MINNUM 1
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MAXNUM 62
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MAXNUM_MCDI2 254
/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP msgrequest */
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN 14
@@ -5535,6 +6449,7 @@
* None. Returns: 0, ENOSYS
*/
#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47
+#undef MC_CMD_0x47_PRIVILEGE_CTG
#define MC_CMD_0x47_PRIVILEGE_CTG SRIOV_CTG_LINK
@@ -5569,6 +6484,7 @@
* required: None Returns: 0
*/
#define MC_CMD_TESTASSERT 0x49
+#undef MC_CMD_0x49_PRIVILEGE_CTG
#define MC_CMD_0x49_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -5611,6 +6527,7 @@
* basis. Locks required: None. Returns: 0, EINVAL .
*/
#define MC_CMD_WORKAROUND 0x4a
+#undef MC_CMD_0x4a_PRIVILEGE_CTG
#define MC_CMD_0x4a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -5658,6 +6575,7 @@
#define MC_CMD_WORKAROUND_EXT_OUT_LEN 4
#define MC_CMD_WORKAROUND_EXT_OUT_FLAGS_OFST 0
#define MC_CMD_WORKAROUND_EXT_OUT_FLAGS_LEN 4
+#define MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_OFST 0
#define MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN 0
#define MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_WIDTH 1
@@ -5672,6 +6590,7 @@
* Anything else: currently undefined. Locks required: None. Return code: 0.
*/
#define MC_CMD_GET_PHY_MEDIA_INFO 0x4b
+#undef MC_CMD_0x4b_PRIVILEGE_CTG
#define MC_CMD_0x4b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -5683,7 +6602,9 @@
/* MC_CMD_GET_PHY_MEDIA_INFO_OUT msgresponse */
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX 252
+#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX_MCDI2 1020
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num))
+#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_NUM(len) (((len)-4)/1)
/* in bytes */
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_LEN 4
@@ -5691,6 +6612,7 @@
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MINNUM 1
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MAXNUM 248
+#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MAXNUM_MCDI2 1016
/***********************************/
@@ -5699,6 +6621,7 @@
* on the type of partition).
*/
#define MC_CMD_NVRAM_TEST 0x4c
+#undef MC_CMD_0x4c_PRIVILEGE_CTG
#define MC_CMD_0x4c_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -5771,6 +6694,7 @@
* of range.
*/
#define MC_CMD_SENSOR_SET_LIMS 0x4e
+#undef MC_CMD_0x4e_PRIVILEGE_CTG
#define MC_CMD_0x4e_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -5823,6 +6747,7 @@
* none. Returns: 0, EINVAL (bad type).
*/
#define MC_CMD_NVRAM_PARTITIONS 0x51
+#undef MC_CMD_0x51_PRIVILEGE_CTG
#define MC_CMD_0x51_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -5832,7 +6757,9 @@
/* MC_CMD_NVRAM_PARTITIONS_OUT msgresponse */
#define MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN 4
#define MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX 252
+#define MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX_MCDI2 1020
#define MC_CMD_NVRAM_PARTITIONS_OUT_LEN(num) (4+4*(num))
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_NUM(len) (((len)-4)/4)
/* total number of partitions */
#define MC_CMD_NVRAM_PARTITIONS_OUT_NUM_PARTITIONS_OFST 0
#define MC_CMD_NVRAM_PARTITIONS_OUT_NUM_PARTITIONS_LEN 4
@@ -5841,6 +6768,7 @@
#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_LEN 4
#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_MINNUM 0
#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_MAXNUM 62
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_MAXNUM_MCDI2 254
/***********************************/
@@ -5849,6 +6777,7 @@
* none. Returns: 0, EINVAL (bad type).
*/
#define MC_CMD_NVRAM_METADATA 0x52
+#undef MC_CMD_0x52_PRIVILEGE_CTG
#define MC_CMD_0x52_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -5861,16 +6790,21 @@
/* MC_CMD_NVRAM_METADATA_OUT msgresponse */
#define MC_CMD_NVRAM_METADATA_OUT_LENMIN 20
#define MC_CMD_NVRAM_METADATA_OUT_LENMAX 252
+#define MC_CMD_NVRAM_METADATA_OUT_LENMAX_MCDI2 1020
#define MC_CMD_NVRAM_METADATA_OUT_LEN(num) (20+1*(num))
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_NUM(len) (((len)-20)/1)
/* Partition type ID code */
#define MC_CMD_NVRAM_METADATA_OUT_TYPE_OFST 0
#define MC_CMD_NVRAM_METADATA_OUT_TYPE_LEN 4
#define MC_CMD_NVRAM_METADATA_OUT_FLAGS_OFST 4
#define MC_CMD_NVRAM_METADATA_OUT_FLAGS_LEN 4
+#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_OFST 4
#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_LBN 0
#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_WIDTH 1
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_OFST 4
#define MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_LBN 1
#define MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_WIDTH 1
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_OFST 4
#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_LBN 2
#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_WIDTH 1
/* Subtype ID code for content of this partition */
@@ -5893,6 +6827,7 @@
#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_LEN 1
#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MINNUM 0
#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM 232
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM_MCDI2 1000
/***********************************/
@@ -5900,6 +6835,7 @@
* Returns the base MAC, count and stride for the requesting function
*/
#define MC_CMD_GET_MAC_ADDRESSES 0x55
+#undef MC_CMD_0x55_PRIVILEGE_CTG
#define MC_CMD_0x55_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -5924,9 +6860,13 @@
/***********************************/
/* MC_CMD_CLP
- * Perform a CLP related operation
+ * Perform a CLP related operation, see SF-110495-PS for details of CLP
+ * processing. This command has been extended to accomodate the requirements of
+ * different manufacturers which are to be found in SF-119187-TC, SF-119186-TC,
+ * SF-120509-TC and SF-117282-PS.
*/
#define MC_CMD_CLP 0x56
+#undef MC_CMD_0x56_PRIVILEGE_CTG
#define MC_CMD_0x56_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -5961,7 +6901,10 @@
#define MC_CMD_CLP_IN_SET_MAC_LEN 12
/* MC_CMD_CLP_IN_OP_OFST 0 */
/* MC_CMD_CLP_IN_OP_LEN 4 */
-/* MAC address assigned to port */
+/* The MAC address assigned to port. A zero MAC address of 00:00:00:00:00:00
+ * restores the permanent (factory-programmed) MAC address associated with the
+ * port. A non-zero MAC address persists until a PCIe reset or a power cycle.
+ */
#define MC_CMD_CLP_IN_SET_MAC_ADDR_OFST 4
#define MC_CMD_CLP_IN_SET_MAC_ADDR_LEN 6
/* Padding */
@@ -5971,11 +6914,40 @@
/* MC_CMD_CLP_OUT_SET_MAC msgresponse */
#define MC_CMD_CLP_OUT_SET_MAC_LEN 0
+/* MC_CMD_CLP_IN_SET_MAC_V2 msgrequest */
+#define MC_CMD_CLP_IN_SET_MAC_V2_LEN 16
+/* MC_CMD_CLP_IN_OP_OFST 0 */
+/* MC_CMD_CLP_IN_OP_LEN 4 */
+/* The MAC address assigned to port. A zero MAC address of 00:00:00:00:00:00
+ * restores the permanent (factory-programmed) MAC address associated with the
+ * port. A non-zero MAC address persists until a PCIe reset or a power cycle.
+ */
+#define MC_CMD_CLP_IN_SET_MAC_V2_ADDR_OFST 4
+#define MC_CMD_CLP_IN_SET_MAC_V2_ADDR_LEN 6
+/* Padding */
+#define MC_CMD_CLP_IN_SET_MAC_V2_RESERVED_OFST 10
+#define MC_CMD_CLP_IN_SET_MAC_V2_RESERVED_LEN 2
+#define MC_CMD_CLP_IN_SET_MAC_V2_FLAGS_OFST 12
+#define MC_CMD_CLP_IN_SET_MAC_V2_FLAGS_LEN 4
+#define MC_CMD_CLP_IN_SET_MAC_V2_VIRTUAL_OFST 12
+#define MC_CMD_CLP_IN_SET_MAC_V2_VIRTUAL_LBN 0
+#define MC_CMD_CLP_IN_SET_MAC_V2_VIRTUAL_WIDTH 1
+
/* MC_CMD_CLP_IN_GET_MAC msgrequest */
#define MC_CMD_CLP_IN_GET_MAC_LEN 4
/* MC_CMD_CLP_IN_OP_OFST 0 */
/* MC_CMD_CLP_IN_OP_LEN 4 */
+/* MC_CMD_CLP_IN_GET_MAC_V2 msgrequest */
+#define MC_CMD_CLP_IN_GET_MAC_V2_LEN 8
+/* MC_CMD_CLP_IN_OP_OFST 0 */
+/* MC_CMD_CLP_IN_OP_LEN 4 */
+#define MC_CMD_CLP_IN_GET_MAC_V2_FLAGS_OFST 4
+#define MC_CMD_CLP_IN_GET_MAC_V2_FLAGS_LEN 4
+#define MC_CMD_CLP_IN_GET_MAC_V2_PERMANENT_OFST 4
+#define MC_CMD_CLP_IN_GET_MAC_V2_PERMANENT_LBN 0
+#define MC_CMD_CLP_IN_GET_MAC_V2_PERMANENT_WIDTH 1
+
/* MC_CMD_CLP_OUT_GET_MAC msgresponse */
#define MC_CMD_CLP_OUT_GET_MAC_LEN 8
/* MAC address assigned to port */
@@ -6016,6 +6988,7 @@
* Perform a MUM operation
*/
#define MC_CMD_MUM 0x57
+#undef MC_CMD_0x57_PRIVILEGE_CTG
#define MC_CMD_0x57_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -6023,6 +6996,7 @@
#define MC_CMD_MUM_IN_LEN 4
#define MC_CMD_MUM_IN_OP_HDR_OFST 0
#define MC_CMD_MUM_IN_OP_HDR_LEN 4
+#define MC_CMD_MUM_IN_OP_OFST 0
#define MC_CMD_MUM_IN_OP_LBN 0
#define MC_CMD_MUM_IN_OP_WIDTH 8
/* enum: NULL MCDI command to MUM */
@@ -6092,7 +7066,9 @@
/* MC_CMD_MUM_IN_WRITE msgrequest */
#define MC_CMD_MUM_IN_WRITE_LENMIN 16
#define MC_CMD_MUM_IN_WRITE_LENMAX 252
+#define MC_CMD_MUM_IN_WRITE_LENMAX_MCDI2 1020
#define MC_CMD_MUM_IN_WRITE_LEN(num) (12+4*(num))
+#define MC_CMD_MUM_IN_WRITE_BUFFER_NUM(len) (((len)-12)/4)
/* MUM cmd header */
/* MC_CMD_MUM_IN_CMD_OFST 0 */
/* MC_CMD_MUM_IN_CMD_LEN 4 */
@@ -6109,11 +7085,14 @@
#define MC_CMD_MUM_IN_WRITE_BUFFER_LEN 4
#define MC_CMD_MUM_IN_WRITE_BUFFER_MINNUM 1
#define MC_CMD_MUM_IN_WRITE_BUFFER_MAXNUM 60
+#define MC_CMD_MUM_IN_WRITE_BUFFER_MAXNUM_MCDI2 252
/* MC_CMD_MUM_IN_RAW_CMD msgrequest */
#define MC_CMD_MUM_IN_RAW_CMD_LENMIN 17
#define MC_CMD_MUM_IN_RAW_CMD_LENMAX 252
+#define MC_CMD_MUM_IN_RAW_CMD_LENMAX_MCDI2 1020
#define MC_CMD_MUM_IN_RAW_CMD_LEN(num) (16+1*(num))
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_NUM(len) (((len)-16)/1)
/* MUM cmd header */
/* MC_CMD_MUM_IN_CMD_OFST 0 */
/* MC_CMD_MUM_IN_CMD_LEN 4 */
@@ -6131,6 +7110,7 @@
#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_LEN 1
#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_MINNUM 1
#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_MAXNUM 236
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_MAXNUM_MCDI2 1004
/* MC_CMD_MUM_IN_LOG msgrequest */
#define MC_CMD_MUM_IN_LOG_LEN 8
@@ -6158,6 +7138,7 @@
/* MC_CMD_MUM_IN_CMD_LEN 4 */
#define MC_CMD_MUM_IN_GPIO_HDR_OFST 4
#define MC_CMD_MUM_IN_GPIO_HDR_LEN 4
+#define MC_CMD_MUM_IN_GPIO_OPCODE_OFST 4
#define MC_CMD_MUM_IN_GPIO_OPCODE_LBN 0
#define MC_CMD_MUM_IN_GPIO_OPCODE_WIDTH 8
#define MC_CMD_MUM_IN_GPIO_IN_READ 0x0 /* enum */
@@ -6220,12 +7201,14 @@
/* MC_CMD_MUM_IN_CMD_LEN 4 */
#define MC_CMD_MUM_IN_GPIO_OP_HDR_OFST 4
#define MC_CMD_MUM_IN_GPIO_OP_HDR_LEN 4
+#define MC_CMD_MUM_IN_GPIO_OP_BITWISE_OP_OFST 4
#define MC_CMD_MUM_IN_GPIO_OP_BITWISE_OP_LBN 8
#define MC_CMD_MUM_IN_GPIO_OP_BITWISE_OP_WIDTH 8
#define MC_CMD_MUM_IN_GPIO_OP_OUT_READ 0x0 /* enum */
#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE 0x1 /* enum */
#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG 0x2 /* enum */
#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE 0x3 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP_GPIO_NUMBER_OFST 4
#define MC_CMD_MUM_IN_GPIO_OP_GPIO_NUMBER_LBN 16
#define MC_CMD_MUM_IN_GPIO_OP_GPIO_NUMBER_WIDTH 8
@@ -6242,6 +7225,7 @@
/* MC_CMD_MUM_IN_CMD_LEN 4 */
#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_HDR_OFST 4
#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_HDR_LEN 4
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_WRITEBIT_OFST 4
#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_WRITEBIT_LBN 24
#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_WRITEBIT_WIDTH 8
@@ -6251,6 +7235,7 @@
/* MC_CMD_MUM_IN_CMD_LEN 4 */
#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_HDR_OFST 4
#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_HDR_LEN 4
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_CFG_OFST 4
#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_CFG_LBN 24
#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_CFG_WIDTH 8
@@ -6260,6 +7245,7 @@
/* MC_CMD_MUM_IN_CMD_LEN 4 */
#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_HDR_OFST 4
#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_HDR_LEN 4
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_ENABLEBIT_OFST 4
#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_ENABLEBIT_LBN 24
#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_ENABLEBIT_WIDTH 8
@@ -6270,8 +7256,10 @@
/* MC_CMD_MUM_IN_CMD_LEN 4 */
#define MC_CMD_MUM_IN_READ_SENSORS_PARAMS_OFST 4
#define MC_CMD_MUM_IN_READ_SENSORS_PARAMS_LEN 4
+#define MC_CMD_MUM_IN_READ_SENSORS_SENSOR_ID_OFST 4
#define MC_CMD_MUM_IN_READ_SENSORS_SENSOR_ID_LBN 0
#define MC_CMD_MUM_IN_READ_SENSORS_SENSOR_ID_WIDTH 8
+#define MC_CMD_MUM_IN_READ_SENSORS_NUM_SENSORS_OFST 4
#define MC_CMD_MUM_IN_READ_SENSORS_NUM_SENSORS_LBN 8
#define MC_CMD_MUM_IN_READ_SENSORS_NUM_SENSORS_WIDTH 8
@@ -6289,10 +7277,13 @@
/* Control flags for clock programming */
#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_FLAGS_OFST 8
#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_FLAGS_LEN 4
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_OVERCLOCK_110_OFST 8
#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_OVERCLOCK_110_LBN 0
#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_OVERCLOCK_110_WIDTH 1
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_CLOCK_NIC_FROM_FPGA_OFST 8
#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_CLOCK_NIC_FROM_FPGA_LBN 1
#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_CLOCK_NIC_FROM_FPGA_WIDTH 1
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_CLOCK_REF_FROM_XO_OFST 8
#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_CLOCK_REF_FROM_XO_LBN 2
#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_CLOCK_REF_FROM_XO_WIDTH 1
@@ -6318,6 +7309,7 @@
/* MC_CMD_MUM_IN_CMD_LEN 4 */
#define MC_CMD_MUM_IN_QSFP_HDR_OFST 4
#define MC_CMD_MUM_IN_QSFP_HDR_LEN 4
+#define MC_CMD_MUM_IN_QSFP_OPCODE_OFST 4
#define MC_CMD_MUM_IN_QSFP_OPCODE_LBN 0
#define MC_CMD_MUM_IN_QSFP_OPCODE_WIDTH 4
#define MC_CMD_MUM_IN_QSFP_INIT 0x0 /* enum */
@@ -6417,21 +7409,27 @@
/* MC_CMD_MUM_OUT_RAW_CMD msgresponse */
#define MC_CMD_MUM_OUT_RAW_CMD_LENMIN 1
#define MC_CMD_MUM_OUT_RAW_CMD_LENMAX 252
+#define MC_CMD_MUM_OUT_RAW_CMD_LENMAX_MCDI2 1020
#define MC_CMD_MUM_OUT_RAW_CMD_LEN(num) (0+1*(num))
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_NUM(len) (((len)-0)/1)
/* returned data */
#define MC_CMD_MUM_OUT_RAW_CMD_DATA_OFST 0
#define MC_CMD_MUM_OUT_RAW_CMD_DATA_LEN 1
#define MC_CMD_MUM_OUT_RAW_CMD_DATA_MINNUM 1
#define MC_CMD_MUM_OUT_RAW_CMD_DATA_MAXNUM 252
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_MAXNUM_MCDI2 1020
/* MC_CMD_MUM_OUT_READ msgresponse */
#define MC_CMD_MUM_OUT_READ_LENMIN 4
#define MC_CMD_MUM_OUT_READ_LENMAX 252
+#define MC_CMD_MUM_OUT_READ_LENMAX_MCDI2 1020
#define MC_CMD_MUM_OUT_READ_LEN(num) (0+4*(num))
+#define MC_CMD_MUM_OUT_READ_BUFFER_NUM(len) (((len)-0)/4)
#define MC_CMD_MUM_OUT_READ_BUFFER_OFST 0
#define MC_CMD_MUM_OUT_READ_BUFFER_LEN 4
#define MC_CMD_MUM_OUT_READ_BUFFER_MINNUM 1
#define MC_CMD_MUM_OUT_READ_BUFFER_MAXNUM 63
+#define MC_CMD_MUM_OUT_READ_BUFFER_MAXNUM_MCDI2 255
/* MC_CMD_MUM_OUT_WRITE msgresponse */
#define MC_CMD_MUM_OUT_WRITE_LEN 0
@@ -6490,15 +7488,21 @@
/* MC_CMD_MUM_OUT_READ_SENSORS msgresponse */
#define MC_CMD_MUM_OUT_READ_SENSORS_LENMIN 4
#define MC_CMD_MUM_OUT_READ_SENSORS_LENMAX 252
+#define MC_CMD_MUM_OUT_READ_SENSORS_LENMAX_MCDI2 1020
#define MC_CMD_MUM_OUT_READ_SENSORS_LEN(num) (0+4*(num))
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_NUM(len) (((len)-0)/4)
#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_OFST 0
#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_LEN 4
#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_MINNUM 1
#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_MAXNUM 63
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_MAXNUM_MCDI2 255
+#define MC_CMD_MUM_OUT_READ_SENSORS_READING_OFST 0
#define MC_CMD_MUM_OUT_READ_SENSORS_READING_LBN 0
#define MC_CMD_MUM_OUT_READ_SENSORS_READING_WIDTH 16
+#define MC_CMD_MUM_OUT_READ_SENSORS_STATE_OFST 0
#define MC_CMD_MUM_OUT_READ_SENSORS_STATE_LBN 16
#define MC_CMD_MUM_OUT_READ_SENSORS_STATE_WIDTH 8
+#define MC_CMD_MUM_OUT_READ_SENSORS_TYPE_OFST 0
#define MC_CMD_MUM_OUT_READ_SENSORS_TYPE_LBN 24
#define MC_CMD_MUM_OUT_READ_SENSORS_TYPE_WIDTH 8
@@ -6524,8 +7528,10 @@
#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LP_CAP_LEN 4
#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_FLAGS_OFST 4
#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_FLAGS_LEN 4
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_READY_OFST 4
#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_READY_LBN 0
#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_READY_WIDTH 1
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LINK_UP_OFST 4
#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LINK_UP_LBN 1
#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LINK_UP_WIDTH 1
@@ -6537,7 +7543,9 @@
/* MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO msgresponse */
#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LENMIN 5
#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LENMAX 252
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LENMAX_MCDI2 1020
#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LEN(num) (4+1*(num))
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_NUM(len) (((len)-4)/1)
/* in bytes */
#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATALEN_OFST 0
#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATALEN_LEN 4
@@ -6545,6 +7553,7 @@
#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_LEN 1
#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_MINNUM 1
#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_MAXNUM 248
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_MAXNUM_MCDI2 1016
/* MC_CMD_MUM_OUT_QSFP_FILL_STATS msgresponse */
#define MC_CMD_MUM_OUT_QSFP_FILL_STATS_LEN 8
@@ -6561,12 +7570,16 @@
/* MC_CMD_MUM_OUT_READ_DDR_INFO msgresponse */
#define MC_CMD_MUM_OUT_READ_DDR_INFO_LENMIN 24
#define MC_CMD_MUM_OUT_READ_DDR_INFO_LENMAX 248
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_LENMAX_MCDI2 1016
#define MC_CMD_MUM_OUT_READ_DDR_INFO_LEN(num) (8+8*(num))
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_SODIMM_INFO_RECORD_NUM(len) (((len)-8)/8)
/* Discrete (soldered) DDR resistor strap info */
#define MC_CMD_MUM_OUT_READ_DDR_INFO_DISCRETE_DDR_INFO_OFST 0
#define MC_CMD_MUM_OUT_READ_DDR_INFO_DISCRETE_DDR_INFO_LEN 4
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_VRATIO_OFST 0
#define MC_CMD_MUM_OUT_READ_DDR_INFO_VRATIO_LBN 0
#define MC_CMD_MUM_OUT_READ_DDR_INFO_VRATIO_WIDTH 16
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_RESERVED1_OFST 0
#define MC_CMD_MUM_OUT_READ_DDR_INFO_RESERVED1_LBN 16
#define MC_CMD_MUM_OUT_READ_DDR_INFO_RESERVED1_WIDTH 16
/* Number of SODIMM info records */
@@ -6579,6 +7592,8 @@
#define MC_CMD_MUM_OUT_READ_DDR_INFO_SODIMM_INFO_RECORD_HI_OFST 12
#define MC_CMD_MUM_OUT_READ_DDR_INFO_SODIMM_INFO_RECORD_MINNUM 2
#define MC_CMD_MUM_OUT_READ_DDR_INFO_SODIMM_INFO_RECORD_MAXNUM 30
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_SODIMM_INFO_RECORD_MAXNUM_MCDI2 126
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_BANK_ID_OFST 8
#define MC_CMD_MUM_OUT_READ_DDR_INFO_BANK_ID_LBN 0
#define MC_CMD_MUM_OUT_READ_DDR_INFO_BANK_ID_WIDTH 8
/* enum: SODIMM bank 1 (Top SODIMM for Sorrento) */
@@ -6587,10 +7602,13 @@
#define MC_CMD_MUM_OUT_READ_DDR_INFO_BANK2 0x1
/* enum: Total number of SODIMM banks */
#define MC_CMD_MUM_OUT_READ_DDR_INFO_NUM_BANKS 0x2
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_TYPE_OFST 8
#define MC_CMD_MUM_OUT_READ_DDR_INFO_TYPE_LBN 8
#define MC_CMD_MUM_OUT_READ_DDR_INFO_TYPE_WIDTH 8
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_RANK_OFST 8
#define MC_CMD_MUM_OUT_READ_DDR_INFO_RANK_LBN 16
#define MC_CMD_MUM_OUT_READ_DDR_INFO_RANK_WIDTH 4
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_VOLTAGE_OFST 8
#define MC_CMD_MUM_OUT_READ_DDR_INFO_VOLTAGE_LBN 20
#define MC_CMD_MUM_OUT_READ_DDR_INFO_VOLTAGE_WIDTH 4
#define MC_CMD_MUM_OUT_READ_DDR_INFO_NOT_POWERED 0x0 /* enum */
@@ -6599,10 +7617,13 @@
#define MC_CMD_MUM_OUT_READ_DDR_INFO_1V5 0x3 /* enum */
/* enum: Values 5-15 are reserved for future usage */
#define MC_CMD_MUM_OUT_READ_DDR_INFO_1V8 0x4
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_SIZE_OFST 8
#define MC_CMD_MUM_OUT_READ_DDR_INFO_SIZE_LBN 24
#define MC_CMD_MUM_OUT_READ_DDR_INFO_SIZE_WIDTH 8
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_SPEED_OFST 8
#define MC_CMD_MUM_OUT_READ_DDR_INFO_SPEED_LBN 32
#define MC_CMD_MUM_OUT_READ_DDR_INFO_SPEED_WIDTH 16
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_STATE_OFST 8
#define MC_CMD_MUM_OUT_READ_DDR_INFO_STATE_LBN 48
#define MC_CMD_MUM_OUT_READ_DDR_INFO_STATE_WIDTH 4
/* enum: No module present */
@@ -6620,14 +7641,314 @@
/* enum: Modules may or may not be present, but cannot establish contact by I2C
*/
#define MC_CMD_MUM_OUT_READ_DDR_INFO_NOT_REACHABLE 0x6
+#define MC_CMD_MUM_OUT_READ_DDR_INFO_RESERVED2_OFST 8
#define MC_CMD_MUM_OUT_READ_DDR_INFO_RESERVED2_LBN 52
#define MC_CMD_MUM_OUT_READ_DDR_INFO_RESERVED2_WIDTH 12
-/* MC_CMD_RESOURCE_SPECIFIER enum */
-/* enum: Any */
-#define MC_CMD_RESOURCE_INSTANCE_ANY 0xffffffff
-/* enum: None */
-#define MC_CMD_RESOURCE_INSTANCE_NONE 0xfffffffe
+/* MC_CMD_DYNAMIC_SENSORS_LIMITS structuredef: Set of sensor limits. This
+ * should match the equivalent structure in the sensor_query SPHINX service.
+ */
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LEN 24
+/* A value below this will trigger a warning event. */
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_WARNING_OFST 0
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_WARNING_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_WARNING_LBN 0
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_WARNING_WIDTH 32
+/* A value below this will trigger a critical event. */
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_CRITICAL_OFST 4
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_CRITICAL_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_CRITICAL_LBN 32
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_CRITICAL_WIDTH 32
+/* A value below this will shut down the card. */
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_FATAL_OFST 8
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_FATAL_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_FATAL_LBN 64
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_LO_FATAL_WIDTH 32
+/* A value above this will trigger a warning event. */
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_WARNING_OFST 12
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_WARNING_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_WARNING_LBN 96
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_WARNING_WIDTH 32
+/* A value above this will trigger a critical event. */
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_CRITICAL_OFST 16
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_CRITICAL_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_CRITICAL_LBN 128
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_CRITICAL_WIDTH 32
+/* A value above this will shut down the card. */
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_FATAL_OFST 20
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_FATAL_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_FATAL_LBN 160
+#define MC_CMD_DYNAMIC_SENSORS_LIMITS_HI_FATAL_WIDTH 32
+
+/* MC_CMD_DYNAMIC_SENSORS_DESCRIPTION structuredef: Description of a sensor.
+ * This should match the equivalent structure in the sensor_query SPHINX
+ * service.
+ */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_LEN 64
+/* The handle used to identify the sensor in calls to
+ * MC_CMD_DYNAMIC_SENSORS_GET_VALUES
+ */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_HANDLE_OFST 0
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_HANDLE_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_HANDLE_LBN 0
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_HANDLE_WIDTH 32
+/* A human-readable name for the sensor (zero terminated string, max 32 bytes)
+ */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_NAME_OFST 4
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_NAME_LEN 32
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_NAME_LBN 32
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_NAME_WIDTH 256
+/* The type of the sensor device, and by implication the unit of that the
+ * values will be reported in
+ */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_TYPE_OFST 36
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_TYPE_LEN 4
+/* enum: A voltage sensor. Unit is mV */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_VOLTAGE 0x0
+/* enum: A current sensor. Unit is mA */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_CURRENT 0x1
+/* enum: A power sensor. Unit is mW */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_POWER 0x2
+/* enum: A temperature sensor. Unit is Celsius */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_TEMPERATURE 0x3
+/* enum: A cooling fan sensor. Unit is RPM */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_FAN 0x4
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_TYPE_LBN 288
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_TYPE_WIDTH 32
+/* A single MC_CMD_DYNAMIC_SENSORS_LIMITS structure */
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_LIMITS_OFST 40
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_LIMITS_LEN 24
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_LIMITS_LBN 320
+#define MC_CMD_DYNAMIC_SENSORS_DESCRIPTION_LIMITS_WIDTH 192
+
+/* MC_CMD_DYNAMIC_SENSORS_READING structuredef: State and value of a sensor.
+ * This should match the equivalent structure in the sensor_query SPHINX
+ * service.
+ */
+#define MC_CMD_DYNAMIC_SENSORS_READING_LEN 12
+/* The handle used to identify the sensor */
+#define MC_CMD_DYNAMIC_SENSORS_READING_HANDLE_OFST 0
+#define MC_CMD_DYNAMIC_SENSORS_READING_HANDLE_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_READING_HANDLE_LBN 0
+#define MC_CMD_DYNAMIC_SENSORS_READING_HANDLE_WIDTH 32
+/* The current value of the sensor */
+#define MC_CMD_DYNAMIC_SENSORS_READING_VALUE_OFST 4
+#define MC_CMD_DYNAMIC_SENSORS_READING_VALUE_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_READING_VALUE_LBN 32
+#define MC_CMD_DYNAMIC_SENSORS_READING_VALUE_WIDTH 32
+/* The sensor's condition, e.g. good, broken or removed */
+#define MC_CMD_DYNAMIC_SENSORS_READING_STATE_OFST 8
+#define MC_CMD_DYNAMIC_SENSORS_READING_STATE_LEN 4
+/* enum: Sensor working normally within limits */
+#define MC_CMD_DYNAMIC_SENSORS_READING_OK 0x0
+/* enum: Warning threshold breached */
+#define MC_CMD_DYNAMIC_SENSORS_READING_WARNING 0x1
+/* enum: Critical threshold breached */
+#define MC_CMD_DYNAMIC_SENSORS_READING_CRITICAL 0x2
+/* enum: Fatal threshold breached */
+#define MC_CMD_DYNAMIC_SENSORS_READING_FATAL 0x3
+/* enum: Sensor not working */
+#define MC_CMD_DYNAMIC_SENSORS_READING_BROKEN 0x4
+/* enum: Sensor working but no reading available */
+#define MC_CMD_DYNAMIC_SENSORS_READING_NO_READING 0x5
+/* enum: Sensor initialization failed */
+#define MC_CMD_DYNAMIC_SENSORS_READING_INIT_FAILED 0x6
+#define MC_CMD_DYNAMIC_SENSORS_READING_STATE_LBN 64
+#define MC_CMD_DYNAMIC_SENSORS_READING_STATE_WIDTH 32
+
+
+/***********************************/
+/* MC_CMD_DYNAMIC_SENSORS_LIST
+ * Return a complete list of handles for sensors currently managed by the MC,
+ * and a generation count for this version of the sensor table. On systems
+ * advertising the DYNAMIC_SENSORS capability bit, this replaces the
+ * MC_CMD_READ_SENSORS command. On multi-MC systems this may include sensors
+ * added by the NMC.
+ *
+ * Sensor handles are persistent for the lifetime of the sensor and are used to
+ * identify sensors in MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS and
+ * MC_CMD_DYNAMIC_SENSORS_GET_VALUES.
+ *
+ * The generation count is maintained by the MC, is persistent across reboots
+ * and will be incremented each time the sensor table is modified. When the
+ * table is modified, a CODE_DYNAMIC_SENSORS_CHANGE event will be generated
+ * containing the new generation count. The driver should compare this against
+ * the current generation count, and if it is different, call
+ * MC_CMD_DYNAMIC_SENSORS_LIST again to update it's copy of the sensor table.
+ *
+ * The sensor count is provided to allow a future path to supporting more than
+ * MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_HANDLES_MAXNUM_MCDI2 sensors, i.e.
+ * the maximum number that will fit in a single response. As this is a fairly
+ * large number (253) it is not anticipated that this will be needed in the
+ * near future, so can currently be ignored.
+ *
+ * On Riverhead this command is implemented as a a wrapper for `list` in the
+ * sensor_query SPHINX service.
+ */
+#define MC_CMD_DYNAMIC_SENSORS_LIST 0x66
+#undef MC_CMD_0x66_PRIVILEGE_CTG
+
+#define MC_CMD_0x66_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_DYNAMIC_SENSORS_LIST_IN msgrequest */
+#define MC_CMD_DYNAMIC_SENSORS_LIST_IN_LEN 0
+
+/* MC_CMD_DYNAMIC_SENSORS_LIST_OUT msgresponse */
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_LENMIN 8
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_LENMAX 252
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_LENMAX_MCDI2 1020
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_LEN(num) (8+4*(num))
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_HANDLES_NUM(len) (((len)-8)/4)
+/* Generation count, which will be updated each time a sensor is added to or
+ * removed from the MC sensor table.
+ */
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_GENERATION_OFST 0
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_GENERATION_LEN 4
+/* Number of sensors managed by the MC. Note that in principle, this can be
+ * larger than the size of the HANDLES array.
+ */
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_COUNT_OFST 4
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_COUNT_LEN 4
+/* Array of sensor handles */
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_HANDLES_OFST 8
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_HANDLES_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_HANDLES_MINNUM 0
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_HANDLES_MAXNUM 61
+#define MC_CMD_DYNAMIC_SENSORS_LIST_OUT_HANDLES_MAXNUM_MCDI2 253
+
+
+/***********************************/
+/* MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS
+ * Get descriptions for a set of sensors, specified as an array of sensor
+ * handles as returned by MC_CMD_DYNAMIC_SENSORS_LIST
+ *
+ * Any handles which do not correspond to a sensor currently managed by the MC
+ * will be dropped from from the response. This may happen when a sensor table
+ * update is in progress, and effectively means the set of usable sensors is
+ * the intersection between the sets of sensors known to the driver and the MC.
+ *
+ * On Riverhead this command is implemented as a a wrapper for
+ * `get_descriptions` in the sensor_query SPHINX service.
+ */
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS 0x67
+#undef MC_CMD_0x67_PRIVILEGE_CTG
+
+#define MC_CMD_0x67_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN msgrequest */
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_LENMIN 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_LENMAX 252
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_LENMAX_MCDI2 1020
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_LEN(num) (0+4*(num))
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_HANDLES_NUM(len) (((len)-0)/4)
+/* Array of sensor handles */
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_HANDLES_OFST 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_HANDLES_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_HANDLES_MINNUM 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_HANDLES_MAXNUM 63
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_IN_HANDLES_MAXNUM_MCDI2 255
+
+/* MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT msgresponse */
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_LENMIN 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_LENMAX 192
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_LENMAX_MCDI2 960
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_LEN(num) (0+64*(num))
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_SENSORS_NUM(len) (((len)-0)/64)
+/* Array of MC_CMD_DYNAMIC_SENSORS_DESCRIPTION structures */
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_SENSORS_OFST 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_SENSORS_LEN 64
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_SENSORS_MINNUM 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_SENSORS_MAXNUM 3
+#define MC_CMD_DYNAMIC_SENSORS_GET_DESCRIPTIONS_OUT_SENSORS_MAXNUM_MCDI2 15
+
+
+/***********************************/
+/* MC_CMD_DYNAMIC_SENSORS_GET_READINGS
+ * Read the state and value for a set of sensors, specified as an array of
+ * sensor handles as returned by MC_CMD_DYNAMIC_SENSORS_LIST.
+ *
+ * In the case of a broken sensor, then the state of the response's
+ * MC_CMD_DYNAMIC_SENSORS_VALUE entry will be set to BROKEN, and any value
+ * provided should be treated as erroneous.
+ *
+ * Any handles which do not correspond to a sensor currently managed by the MC
+ * will be dropped from from the response. This may happen when a sensor table
+ * update is in progress, and effectively means the set of usable sensors is
+ * the intersection between the sets of sensors known to the driver and the MC.
+ *
+ * On Riverhead this command is implemented as a a wrapper for `get_readings`
+ * in the sensor_query SPHINX service.
+ */
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS 0x68
+#undef MC_CMD_0x68_PRIVILEGE_CTG
+
+#define MC_CMD_0x68_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN msgrequest */
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_LENMIN 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_LENMAX 252
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_LENMAX_MCDI2 1020
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_LEN(num) (0+4*(num))
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_HANDLES_NUM(len) (((len)-0)/4)
+/* Array of sensor handles */
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_HANDLES_OFST 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_HANDLES_LEN 4
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_HANDLES_MINNUM 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_HANDLES_MAXNUM 63
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_IN_HANDLES_MAXNUM_MCDI2 255
+
+/* MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT msgresponse */
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_LENMIN 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_LENMAX 252
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_LENMAX_MCDI2 1020
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_LEN(num) (0+12*(num))
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_VALUES_NUM(len) (((len)-0)/12)
+/* Array of MC_CMD_DYNAMIC_SENSORS_READING structures */
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_VALUES_OFST 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_VALUES_LEN 12
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_VALUES_MINNUM 0
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_VALUES_MAXNUM 21
+#define MC_CMD_DYNAMIC_SENSORS_GET_READINGS_OUT_VALUES_MAXNUM_MCDI2 85
+
+
+/***********************************/
+/* MC_CMD_EVENT_CTRL
+ * Configure which categories of unsolicited events the driver expects to
+ * receive (Riverhead).
+ */
+#define MC_CMD_EVENT_CTRL 0x69
+#undef MC_CMD_0x69_PRIVILEGE_CTG
+
+#define MC_CMD_0x69_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_EVENT_CTRL_IN msgrequest */
+#define MC_CMD_EVENT_CTRL_IN_LENMIN 0
+#define MC_CMD_EVENT_CTRL_IN_LENMAX 252
+#define MC_CMD_EVENT_CTRL_IN_LENMAX_MCDI2 1020
+#define MC_CMD_EVENT_CTRL_IN_LEN(num) (0+4*(num))
+#define MC_CMD_EVENT_CTRL_IN_EVENT_TYPE_NUM(len) (((len)-0)/4)
+/* Array of event categories for which the driver wishes to receive events. */
+#define MC_CMD_EVENT_CTRL_IN_EVENT_TYPE_OFST 0
+#define MC_CMD_EVENT_CTRL_IN_EVENT_TYPE_LEN 4
+#define MC_CMD_EVENT_CTRL_IN_EVENT_TYPE_MINNUM 0
+#define MC_CMD_EVENT_CTRL_IN_EVENT_TYPE_MAXNUM 63
+#define MC_CMD_EVENT_CTRL_IN_EVENT_TYPE_MAXNUM_MCDI2 255
+/* enum: Driver wishes to receive LINKCHANGE events. */
+#define MC_CMD_EVENT_CTRL_IN_MCDI_EVENT_CODE_LINKCHANGE 0x0
+/* enum: Driver wishes to receive SENSOR_CHANGE and SENSOR_STATE_CHANGE events.
+ */
+#define MC_CMD_EVENT_CTRL_IN_MCDI_EVENT_CODE_SENSOREVT 0x1
+/* enum: Driver wishes to receive receive errors. */
+#define MC_CMD_EVENT_CTRL_IN_MCDI_EVENT_CODE_RX_ERR 0x2
+/* enum: Driver wishes to receive transmit errors. */
+#define MC_CMD_EVENT_CTRL_IN_MCDI_EVENT_CODE_TX_ERR 0x3
+/* enum: Driver wishes to receive firmware alerts. */
+#define MC_CMD_EVENT_CTRL_IN_MCDI_EVENT_CODE_FWALERT 0x4
+/* enum: Driver wishes to receive reboot events. */
+#define MC_CMD_EVENT_CTRL_IN_MCDI_EVENT_CODE_MC_REBOOT 0x5
+
+/* MC_CMD_EVENT_CTRL_OUT msgrequest */
+#define MC_CMD_EVENT_CTRL_OUT_LEN 0
/* EVB_PORT_ID structuredef */
#define EVB_PORT_ID_LEN 4
@@ -6789,6 +8110,8 @@
#define NVRAM_PARTITION_TYPE_BUNDLE_METADATA 0x1e01
/* enum: Bundle update non-volatile log output partition */
#define NVRAM_PARTITION_TYPE_BUNDLE_LOG 0x1e02
+/* enum: Partition for Solarflare gPXE bootrom installed via Bundle update. */
+#define NVRAM_PARTITION_TYPE_EXPANSION_ROM_INTERNAL 0x1e03
/* enum: Start of reserved value range (firmware may use for any purpose) */
#define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MIN 0xff00
/* enum: End of reserved value range (firmware may use for any purpose) */
@@ -6846,24 +8169,34 @@
#define LICENSED_FEATURES_MASK_LEN 8
#define LICENSED_FEATURES_MASK_LO_OFST 0
#define LICENSED_FEATURES_MASK_HI_OFST 4
+#define LICENSED_FEATURES_RX_CUT_THROUGH_OFST 0
#define LICENSED_FEATURES_RX_CUT_THROUGH_LBN 0
#define LICENSED_FEATURES_RX_CUT_THROUGH_WIDTH 1
+#define LICENSED_FEATURES_PIO_OFST 0
#define LICENSED_FEATURES_PIO_LBN 1
#define LICENSED_FEATURES_PIO_WIDTH 1
+#define LICENSED_FEATURES_EVQ_TIMER_OFST 0
#define LICENSED_FEATURES_EVQ_TIMER_LBN 2
#define LICENSED_FEATURES_EVQ_TIMER_WIDTH 1
+#define LICENSED_FEATURES_CLOCK_OFST 0
#define LICENSED_FEATURES_CLOCK_LBN 3
#define LICENSED_FEATURES_CLOCK_WIDTH 1
+#define LICENSED_FEATURES_RX_TIMESTAMPS_OFST 0
#define LICENSED_FEATURES_RX_TIMESTAMPS_LBN 4
#define LICENSED_FEATURES_RX_TIMESTAMPS_WIDTH 1
+#define LICENSED_FEATURES_TX_TIMESTAMPS_OFST 0
#define LICENSED_FEATURES_TX_TIMESTAMPS_LBN 5
#define LICENSED_FEATURES_TX_TIMESTAMPS_WIDTH 1
+#define LICENSED_FEATURES_RX_SNIFF_OFST 0
#define LICENSED_FEATURES_RX_SNIFF_LBN 6
#define LICENSED_FEATURES_RX_SNIFF_WIDTH 1
+#define LICENSED_FEATURES_TX_SNIFF_OFST 0
#define LICENSED_FEATURES_TX_SNIFF_LBN 7
#define LICENSED_FEATURES_TX_SNIFF_WIDTH 1
+#define LICENSED_FEATURES_PROXY_FILTER_OPS_OFST 0
#define LICENSED_FEATURES_PROXY_FILTER_OPS_LBN 8
#define LICENSED_FEATURES_PROXY_FILTER_OPS_WIDTH 1
+#define LICENSED_FEATURES_EVENT_CUT_THROUGH_OFST 0
#define LICENSED_FEATURES_EVENT_CUT_THROUGH_LBN 9
#define LICENSED_FEATURES_EVENT_CUT_THROUGH_WIDTH 1
#define LICENSED_FEATURES_MASK_LBN 0
@@ -6876,36 +8209,52 @@
#define LICENSED_V3_APPS_MASK_LEN 8
#define LICENSED_V3_APPS_MASK_LO_OFST 0
#define LICENSED_V3_APPS_MASK_HI_OFST 4
+#define LICENSED_V3_APPS_ONLOAD_OFST 0
#define LICENSED_V3_APPS_ONLOAD_LBN 0
#define LICENSED_V3_APPS_ONLOAD_WIDTH 1
+#define LICENSED_V3_APPS_PTP_OFST 0
#define LICENSED_V3_APPS_PTP_LBN 1
#define LICENSED_V3_APPS_PTP_WIDTH 1
+#define LICENSED_V3_APPS_SOLARCAPTURE_PRO_OFST 0
#define LICENSED_V3_APPS_SOLARCAPTURE_PRO_LBN 2
#define LICENSED_V3_APPS_SOLARCAPTURE_PRO_WIDTH 1
+#define LICENSED_V3_APPS_SOLARSECURE_OFST 0
#define LICENSED_V3_APPS_SOLARSECURE_LBN 3
#define LICENSED_V3_APPS_SOLARSECURE_WIDTH 1
+#define LICENSED_V3_APPS_PERF_MONITOR_OFST 0
#define LICENSED_V3_APPS_PERF_MONITOR_LBN 4
#define LICENSED_V3_APPS_PERF_MONITOR_WIDTH 1
+#define LICENSED_V3_APPS_SOLARCAPTURE_LIVE_OFST 0
#define LICENSED_V3_APPS_SOLARCAPTURE_LIVE_LBN 5
#define LICENSED_V3_APPS_SOLARCAPTURE_LIVE_WIDTH 1
+#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_OFST 0
#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_LBN 6
#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_WIDTH 1
+#define LICENSED_V3_APPS_NETWORK_ACCESS_CONTROL_OFST 0
#define LICENSED_V3_APPS_NETWORK_ACCESS_CONTROL_LBN 7
#define LICENSED_V3_APPS_NETWORK_ACCESS_CONTROL_WIDTH 1
+#define LICENSED_V3_APPS_TCP_DIRECT_OFST 0
#define LICENSED_V3_APPS_TCP_DIRECT_LBN 8
#define LICENSED_V3_APPS_TCP_DIRECT_WIDTH 1
+#define LICENSED_V3_APPS_LOW_LATENCY_OFST 0
#define LICENSED_V3_APPS_LOW_LATENCY_LBN 9
#define LICENSED_V3_APPS_LOW_LATENCY_WIDTH 1
+#define LICENSED_V3_APPS_SOLARCAPTURE_TAP_OFST 0
#define LICENSED_V3_APPS_SOLARCAPTURE_TAP_LBN 10
#define LICENSED_V3_APPS_SOLARCAPTURE_TAP_WIDTH 1
+#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_40G_OFST 0
#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_40G_LBN 11
#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_40G_WIDTH 1
+#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_1G_OFST 0
#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_1G_LBN 12
#define LICENSED_V3_APPS_CAPTURE_SOLARSYSTEM_1G_WIDTH 1
+#define LICENSED_V3_APPS_SCALEOUT_ONLOAD_OFST 0
#define LICENSED_V3_APPS_SCALEOUT_ONLOAD_LBN 13
#define LICENSED_V3_APPS_SCALEOUT_ONLOAD_WIDTH 1
+#define LICENSED_V3_APPS_DSHBRD_OFST 0
#define LICENSED_V3_APPS_DSHBRD_LBN 14
#define LICENSED_V3_APPS_DSHBRD_WIDTH 1
+#define LICENSED_V3_APPS_SCATRD_OFST 0
#define LICENSED_V3_APPS_SCATRD_LBN 15
#define LICENSED_V3_APPS_SCATRD_WIDTH 1
#define LICENSED_V3_APPS_MASK_LBN 0
@@ -6918,24 +8267,34 @@
#define LICENSED_V3_FEATURES_MASK_LEN 8
#define LICENSED_V3_FEATURES_MASK_LO_OFST 0
#define LICENSED_V3_FEATURES_MASK_HI_OFST 4
+#define LICENSED_V3_FEATURES_RX_CUT_THROUGH_OFST 0
#define LICENSED_V3_FEATURES_RX_CUT_THROUGH_LBN 0
#define LICENSED_V3_FEATURES_RX_CUT_THROUGH_WIDTH 1
+#define LICENSED_V3_FEATURES_PIO_OFST 0
#define LICENSED_V3_FEATURES_PIO_LBN 1
#define LICENSED_V3_FEATURES_PIO_WIDTH 1
+#define LICENSED_V3_FEATURES_EVQ_TIMER_OFST 0
#define LICENSED_V3_FEATURES_EVQ_TIMER_LBN 2
#define LICENSED_V3_FEATURES_EVQ_TIMER_WIDTH 1
+#define LICENSED_V3_FEATURES_CLOCK_OFST 0
#define LICENSED_V3_FEATURES_CLOCK_LBN 3
#define LICENSED_V3_FEATURES_CLOCK_WIDTH 1
+#define LICENSED_V3_FEATURES_RX_TIMESTAMPS_OFST 0
#define LICENSED_V3_FEATURES_RX_TIMESTAMPS_LBN 4
#define LICENSED_V3_FEATURES_RX_TIMESTAMPS_WIDTH 1
+#define LICENSED_V3_FEATURES_TX_TIMESTAMPS_OFST 0
#define LICENSED_V3_FEATURES_TX_TIMESTAMPS_LBN 5
#define LICENSED_V3_FEATURES_TX_TIMESTAMPS_WIDTH 1
+#define LICENSED_V3_FEATURES_RX_SNIFF_OFST 0
#define LICENSED_V3_FEATURES_RX_SNIFF_LBN 6
#define LICENSED_V3_FEATURES_RX_SNIFF_WIDTH 1
+#define LICENSED_V3_FEATURES_TX_SNIFF_OFST 0
#define LICENSED_V3_FEATURES_TX_SNIFF_LBN 7
#define LICENSED_V3_FEATURES_TX_SNIFF_WIDTH 1
+#define LICENSED_V3_FEATURES_PROXY_FILTER_OPS_OFST 0
#define LICENSED_V3_FEATURES_PROXY_FILTER_OPS_LBN 8
#define LICENSED_V3_FEATURES_PROXY_FILTER_OPS_WIDTH 1
+#define LICENSED_V3_FEATURES_EVENT_CUT_THROUGH_OFST 0
#define LICENSED_V3_FEATURES_EVENT_CUT_THROUGH_LBN 9
#define LICENSED_V3_FEATURES_EVENT_CUT_THROUGH_WIDTH 1
#define LICENSED_V3_FEATURES_MASK_LBN 0
@@ -6988,12 +8347,16 @@
*/
#define RSS_MODE_HASH_SELECTOR_OFST 0
#define RSS_MODE_HASH_SELECTOR_LEN 1
+#define RSS_MODE_HASH_SRC_ADDR_OFST 0
#define RSS_MODE_HASH_SRC_ADDR_LBN 0
#define RSS_MODE_HASH_SRC_ADDR_WIDTH 1
+#define RSS_MODE_HASH_DST_ADDR_OFST 0
#define RSS_MODE_HASH_DST_ADDR_LBN 1
#define RSS_MODE_HASH_DST_ADDR_WIDTH 1
+#define RSS_MODE_HASH_SRC_PORT_OFST 0
#define RSS_MODE_HASH_SRC_PORT_LBN 2
#define RSS_MODE_HASH_SRC_PORT_WIDTH 1
+#define RSS_MODE_HASH_DST_PORT_OFST 0
#define RSS_MODE_HASH_DST_PORT_LBN 3
#define RSS_MODE_HASH_DST_PORT_WIDTH 1
#define RSS_MODE_HASH_SELECTOR_LBN 0
@@ -7018,6 +8381,7 @@
* Get a dump of the MCPU registers
*/
#define MC_CMD_READ_REGS 0x50
+#undef MC_CMD_0x50_PRIVILEGE_CTG
#define MC_CMD_0x50_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -7043,13 +8407,16 @@
* end with an address for each 4k of host memory required to back the EVQ.
*/
#define MC_CMD_INIT_EVQ 0x80
+#undef MC_CMD_0x80_PRIVILEGE_CTG
#define MC_CMD_0x80_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_INIT_EVQ_IN msgrequest */
#define MC_CMD_INIT_EVQ_IN_LENMIN 44
#define MC_CMD_INIT_EVQ_IN_LENMAX 548
+#define MC_CMD_INIT_EVQ_IN_LENMAX_MCDI2 548
#define MC_CMD_INIT_EVQ_IN_LEN(num) (36+8*(num))
+#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_NUM(len) (((len)-36)/8)
/* Size, in entries */
#define MC_CMD_INIT_EVQ_IN_SIZE_OFST 0
#define MC_CMD_INIT_EVQ_IN_SIZE_LEN 4
@@ -7068,18 +8435,25 @@
/* tbd */
#define MC_CMD_INIT_EVQ_IN_FLAGS_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAGS_LEN 4
+#define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_LBN 0
#define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_LBN 1
#define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_INT_ARMD_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAG_INT_ARMD_LBN 2
#define MC_CMD_INIT_EVQ_IN_FLAG_INT_ARMD_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_CUT_THRU_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAG_CUT_THRU_LBN 3
#define MC_CMD_INIT_EVQ_IN_FLAG_CUT_THRU_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_RX_MERGE_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAG_RX_MERGE_LBN 4
#define MC_CMD_INIT_EVQ_IN_FLAG_RX_MERGE_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_TX_MERGE_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAG_TX_MERGE_LBN 5
#define MC_CMD_INIT_EVQ_IN_FLAG_TX_MERGE_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_USE_TIMER_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAG_USE_TIMER_LBN 6
#define MC_CMD_INIT_EVQ_IN_FLAG_USE_TIMER_WIDTH 1
#define MC_CMD_INIT_EVQ_IN_TMR_MODE_OFST 20
@@ -7122,6 +8496,7 @@
#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_HI_OFST 40
#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_MAXNUM 64
+#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_MAXNUM_MCDI2 64
/* MC_CMD_INIT_EVQ_OUT msgresponse */
#define MC_CMD_INIT_EVQ_OUT_LEN 4
@@ -7132,7 +8507,9 @@
/* MC_CMD_INIT_EVQ_V2_IN msgrequest */
#define MC_CMD_INIT_EVQ_V2_IN_LENMIN 44
#define MC_CMD_INIT_EVQ_V2_IN_LENMAX 548
+#define MC_CMD_INIT_EVQ_V2_IN_LENMAX_MCDI2 548
#define MC_CMD_INIT_EVQ_V2_IN_LEN(num) (36+8*(num))
+#define MC_CMD_INIT_EVQ_V2_IN_DMA_ADDR_NUM(len) (((len)-36)/8)
/* Size, in entries */
#define MC_CMD_INIT_EVQ_V2_IN_SIZE_OFST 0
#define MC_CMD_INIT_EVQ_V2_IN_SIZE_LEN 4
@@ -7151,20 +8528,28 @@
/* tbd */
#define MC_CMD_INIT_EVQ_V2_IN_FLAGS_OFST 16
#define MC_CMD_INIT_EVQ_V2_IN_FLAGS_LEN 4
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_INTERRUPTING_OFST 16
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_INTERRUPTING_LBN 0
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_INTERRUPTING_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_RPTR_DOS_OFST 16
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_RPTR_DOS_LBN 1
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_RPTR_DOS_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_INT_ARMD_OFST 16
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_INT_ARMD_LBN 2
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_INT_ARMD_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_CUT_THRU_OFST 16
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_CUT_THRU_LBN 3
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_CUT_THRU_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_RX_MERGE_OFST 16
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_RX_MERGE_LBN 4
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_RX_MERGE_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_TX_MERGE_OFST 16
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_TX_MERGE_LBN 5
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_TX_MERGE_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_USE_TIMER_OFST 16
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_USE_TIMER_LBN 6
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_USE_TIMER_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_OFST 16
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_LBN 7
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_WIDTH 4
/* enum: All initialisation flags specified by host. */
@@ -7186,6 +8571,9 @@
* MC_CMD_INIT_EVQ_V2/MC_CMD_INIT_EVQ_V2_OUT/FLAGS for list of affected flags.
*/
#define MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_AUTO 0x3
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_EXT_WIDTH_OFST 16
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_EXT_WIDTH_LBN 11
+#define MC_CMD_INIT_EVQ_V2_IN_FLAG_EXT_WIDTH_WIDTH 1
#define MC_CMD_INIT_EVQ_V2_IN_TMR_MODE_OFST 20
#define MC_CMD_INIT_EVQ_V2_IN_TMR_MODE_LEN 4
/* enum: Disabled */
@@ -7226,6 +8614,7 @@
#define MC_CMD_INIT_EVQ_V2_IN_DMA_ADDR_HI_OFST 40
#define MC_CMD_INIT_EVQ_V2_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_EVQ_V2_IN_DMA_ADDR_MAXNUM 64
+#define MC_CMD_INIT_EVQ_V2_IN_DMA_ADDR_MAXNUM_MCDI2 64
/* MC_CMD_INIT_EVQ_V2_OUT msgresponse */
#define MC_CMD_INIT_EVQ_V2_OUT_LEN 8
@@ -7235,12 +8624,16 @@
/* Actual configuration applied on the card */
#define MC_CMD_INIT_EVQ_V2_OUT_FLAGS_OFST 4
#define MC_CMD_INIT_EVQ_V2_OUT_FLAGS_LEN 4
+#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_CUT_THRU_OFST 4
#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_CUT_THRU_LBN 0
#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_CUT_THRU_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_RX_MERGE_OFST 4
#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_RX_MERGE_LBN 1
#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_RX_MERGE_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_TX_MERGE_OFST 4
#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_TX_MERGE_LBN 2
#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_TX_MERGE_WIDTH 1
+#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_RXQ_FORCE_EV_MERGING_OFST 4
#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_RXQ_FORCE_EV_MERGING_LBN 3
#define MC_CMD_INIT_EVQ_V2_OUT_FLAG_RXQ_FORCE_EV_MERGING_WIDTH 1
@@ -7271,6 +8664,7 @@
* the RXQ.
*/
#define MC_CMD_INIT_RXQ 0x81
+#undef MC_CMD_0x81_PRIVILEGE_CTG
#define MC_CMD_0x81_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -7279,7 +8673,9 @@
*/
#define MC_CMD_INIT_RXQ_IN_LENMIN 36
#define MC_CMD_INIT_RXQ_IN_LENMAX 252
+#define MC_CMD_INIT_RXQ_IN_LENMAX_MCDI2 1020
#define MC_CMD_INIT_RXQ_IN_LEN(num) (28+8*(num))
+#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_NUM(len) (((len)-28)/8)
/* Size, in entries */
#define MC_CMD_INIT_RXQ_IN_SIZE_OFST 0
#define MC_CMD_INIT_RXQ_IN_SIZE_LEN 4
@@ -7298,20 +8694,28 @@
/* There will be more flags here. */
#define MC_CMD_INIT_RXQ_IN_FLAGS_OFST 16
#define MC_CMD_INIT_RXQ_IN_FLAGS_LEN 4
+#define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_OFST 16
#define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_LBN 0
#define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_OFST 16
#define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_LBN 1
#define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_TIMESTAMP_OFST 16
#define MC_CMD_INIT_RXQ_IN_FLAG_TIMESTAMP_LBN 2
#define MC_CMD_INIT_RXQ_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_CRC_MODE_OFST 16
#define MC_CMD_INIT_RXQ_IN_CRC_MODE_LBN 3
#define MC_CMD_INIT_RXQ_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_RXQ_IN_FLAG_CHAIN_OFST 16
#define MC_CMD_INIT_RXQ_IN_FLAG_CHAIN_LBN 7
#define MC_CMD_INIT_RXQ_IN_FLAG_CHAIN_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_OFST 16
#define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_LBN 8
#define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_DISABLE_SCATTER_OFST 16
#define MC_CMD_INIT_RXQ_IN_FLAG_DISABLE_SCATTER_LBN 9
#define MC_CMD_INIT_RXQ_IN_FLAG_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_UNUSED_OFST 16
#define MC_CMD_INIT_RXQ_IN_UNUSED_LBN 10
#define MC_CMD_INIT_RXQ_IN_UNUSED_WIDTH 1
/* Owner ID to use if in buffer mode (zero if physical) */
@@ -7327,6 +8731,7 @@
#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_HI_OFST 32
#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_MAXNUM 28
+#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_MAXNUM_MCDI2 124
/* MC_CMD_INIT_RXQ_EXT_IN msgrequest: Extended RXQ_INIT with additional mode
* flags
@@ -7341,7 +8746,7 @@
#define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_OFST 4
#define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_LEN 4
/* The value to put in the event data. Check hardware spec. for valid range.
- * This field is ignored if DMA_MODE == EQUAL_STRIDE_PACKED_STREAM or DMA_MODE
+ * This field is ignored if DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER or DMA_MODE
* == PACKED_STREAM.
*/
#define MC_CMD_INIT_RXQ_EXT_IN_LABEL_OFST 8
@@ -7354,20 +8759,28 @@
/* There will be more flags here. */
#define MC_CMD_INIT_RXQ_EXT_IN_FLAGS_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAGS_LEN 4
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_BUFF_MODE_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_BUFF_MODE_LBN 0
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT_LBN 1
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_TIMESTAMP_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_TIMESTAMP_LBN 2
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_CRC_MODE_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_CRC_MODE_LBN 3
#define MC_CMD_INIT_RXQ_EXT_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_CHAIN_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_CHAIN_LBN 7
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_CHAIN_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_PREFIX_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_PREFIX_LBN 8
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_PREFIX_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_DISABLE_SCATTER_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_DISABLE_SCATTER_LBN 9
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_LBN 10
#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_WIDTH 4
/* enum: One packet per descriptor (for normal networking) */
@@ -7380,9 +8793,13 @@
* description see SF-119419-TC. This mode is only supported by "dpdk" datapath
* firmware.
*/
+#define MC_CMD_INIT_RXQ_EXT_IN_EQUAL_STRIDE_SUPER_BUFFER 0x2
+/* enum: Deprecated name for EQUAL_STRIDE_SUPER_BUFFER. */
#define MC_CMD_INIT_RXQ_EXT_IN_EQUAL_STRIDE_PACKED_STREAM 0x2
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_LBN 14
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_LBN 15
#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_WIDTH 3
#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M 0x0 /* enum */
@@ -7390,10 +8807,15 @@
#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K 0x2 /* enum */
#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K 0x3 /* enum */
#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K 0x4 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_LBN 18
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_FORCE_EV_MERGING_OFST 16
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_FORCE_EV_MERGING_LBN 19
#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_FORCE_EV_MERGING_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_NO_CONT_EV_OFST 16
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_NO_CONT_EV_LBN 20
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_NO_CONT_EV_WIDTH 1
/* Owner ID to use if in buffer mode (zero if physical) */
#define MC_CMD_INIT_RXQ_EXT_IN_OWNER_ID_OFST 20
#define MC_CMD_INIT_RXQ_EXT_IN_OWNER_ID_LEN 4
@@ -7421,7 +8843,7 @@
#define MC_CMD_INIT_RXQ_V3_IN_TARGET_EVQ_OFST 4
#define MC_CMD_INIT_RXQ_V3_IN_TARGET_EVQ_LEN 4
/* The value to put in the event data. Check hardware spec. for valid range.
- * This field is ignored if DMA_MODE == EQUAL_STRIDE_PACKED_STREAM or DMA_MODE
+ * This field is ignored if DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER or DMA_MODE
* == PACKED_STREAM.
*/
#define MC_CMD_INIT_RXQ_V3_IN_LABEL_OFST 8
@@ -7434,20 +8856,28 @@
/* There will be more flags here. */
#define MC_CMD_INIT_RXQ_V3_IN_FLAGS_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAGS_LEN 4
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_BUFF_MODE_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_BUFF_MODE_LBN 0
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_HDR_SPLIT_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_HDR_SPLIT_LBN 1
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_HDR_SPLIT_WIDTH 1
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_TIMESTAMP_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_TIMESTAMP_LBN 2
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_RXQ_V3_IN_CRC_MODE_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_CRC_MODE_LBN 3
#define MC_CMD_INIT_RXQ_V3_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_CHAIN_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_CHAIN_LBN 7
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_CHAIN_WIDTH 1
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_PREFIX_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_PREFIX_LBN 8
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_PREFIX_WIDTH 1
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_DISABLE_SCATTER_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_DISABLE_SCATTER_LBN 9
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_INIT_RXQ_V3_IN_DMA_MODE_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_DMA_MODE_LBN 10
#define MC_CMD_INIT_RXQ_V3_IN_DMA_MODE_WIDTH 4
/* enum: One packet per descriptor (for normal networking) */
@@ -7460,9 +8890,13 @@
* description see SF-119419-TC. This mode is only supported by "dpdk" datapath
* firmware.
*/
+#define MC_CMD_INIT_RXQ_V3_IN_EQUAL_STRIDE_SUPER_BUFFER 0x2
+/* enum: Deprecated name for EQUAL_STRIDE_SUPER_BUFFER. */
#define MC_CMD_INIT_RXQ_V3_IN_EQUAL_STRIDE_PACKED_STREAM 0x2
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_SNAPSHOT_MODE_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_SNAPSHOT_MODE_LBN 14
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_SNAPSHOT_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_V3_IN_PACKED_STREAM_BUFF_SIZE_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_PACKED_STREAM_BUFF_SIZE_LBN 15
#define MC_CMD_INIT_RXQ_V3_IN_PACKED_STREAM_BUFF_SIZE_WIDTH 3
#define MC_CMD_INIT_RXQ_V3_IN_PS_BUFF_1M 0x0 /* enum */
@@ -7470,10 +8904,15 @@
#define MC_CMD_INIT_RXQ_V3_IN_PS_BUFF_256K 0x2 /* enum */
#define MC_CMD_INIT_RXQ_V3_IN_PS_BUFF_128K 0x3 /* enum */
#define MC_CMD_INIT_RXQ_V3_IN_PS_BUFF_64K 0x4 /* enum */
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_WANT_OUTER_CLASSES_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_WANT_OUTER_CLASSES_LBN 18
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_WANT_OUTER_CLASSES_WIDTH 1
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_FORCE_EV_MERGING_OFST 16
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_FORCE_EV_MERGING_LBN 19
#define MC_CMD_INIT_RXQ_V3_IN_FLAG_FORCE_EV_MERGING_WIDTH 1
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_NO_CONT_EV_OFST 16
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_NO_CONT_EV_LBN 20
+#define MC_CMD_INIT_RXQ_V3_IN_FLAG_NO_CONT_EV_WIDTH 1
/* Owner ID to use if in buffer mode (zero if physical) */
#define MC_CMD_INIT_RXQ_V3_IN_OWNER_ID_OFST 20
#define MC_CMD_INIT_RXQ_V3_IN_OWNER_ID_LEN 4
@@ -7490,21 +8929,21 @@
#define MC_CMD_INIT_RXQ_V3_IN_SNAPSHOT_LENGTH_OFST 540
#define MC_CMD_INIT_RXQ_V3_IN_SNAPSHOT_LENGTH_LEN 4
/* The number of packet buffers that will be contained within each
- * EQUAL_STRIDE_PACKED_STREAM format bucket supplied by the driver. This field
- * is ignored unless DMA_MODE == EQUAL_STRIDE_PACKED_STREAM.
+ * EQUAL_STRIDE_SUPER_BUFFER format bucket supplied by the driver. This field
+ * is ignored unless DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
*/
#define MC_CMD_INIT_RXQ_V3_IN_ES_PACKET_BUFFERS_PER_BUCKET_OFST 544
#define MC_CMD_INIT_RXQ_V3_IN_ES_PACKET_BUFFERS_PER_BUCKET_LEN 4
/* The length in bytes of the area in each packet buffer that can be written to
* by the adapter. This is used to store the packet prefix and the packet
* payload. This length does not include any end padding added by the driver.
- * This field is ignored unless DMA_MODE == EQUAL_STRIDE_PACKED_STREAM.
+ * This field is ignored unless DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
*/
#define MC_CMD_INIT_RXQ_V3_IN_ES_MAX_DMA_LEN_OFST 548
#define MC_CMD_INIT_RXQ_V3_IN_ES_MAX_DMA_LEN_LEN 4
/* The length in bytes of a single packet buffer within a
- * EQUAL_STRIDE_PACKED_STREAM format bucket. This field is ignored unless
- * DMA_MODE == EQUAL_STRIDE_PACKED_STREAM.
+ * EQUAL_STRIDE_SUPER_BUFFER format bucket. This field is ignored unless
+ * DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
*/
#define MC_CMD_INIT_RXQ_V3_IN_ES_PACKET_STRIDE_OFST 552
#define MC_CMD_INIT_RXQ_V3_IN_ES_PACKET_STRIDE_LEN 4
@@ -7512,11 +8951,296 @@
* there are no RX descriptors available. If the timeout is reached and there
* are still no descriptors then the packet will be dropped. A timeout of 0
* means the datapath will never be blocked. This field is ignored unless
- * DMA_MODE == EQUAL_STRIDE_PACKED_STREAM.
+ * DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
*/
#define MC_CMD_INIT_RXQ_V3_IN_ES_HEAD_OF_LINE_BLOCK_TIMEOUT_OFST 556
#define MC_CMD_INIT_RXQ_V3_IN_ES_HEAD_OF_LINE_BLOCK_TIMEOUT_LEN 4
+/* MC_CMD_INIT_RXQ_V4_IN msgrequest: INIT_RXQ request with new field required
+ * for systems with a QDMA (currently, Riverhead)
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_LEN 564
+/* Size, in entries */
+#define MC_CMD_INIT_RXQ_V4_IN_SIZE_OFST 0
+#define MC_CMD_INIT_RXQ_V4_IN_SIZE_LEN 4
+/* The EVQ to send events to. This is an index originally specified to
+ * INIT_EVQ. If DMA_MODE == PACKED_STREAM this must be equal to INSTANCE.
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_TARGET_EVQ_OFST 4
+#define MC_CMD_INIT_RXQ_V4_IN_TARGET_EVQ_LEN 4
+/* The value to put in the event data. Check hardware spec. for valid range.
+ * This field is ignored if DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER or DMA_MODE
+ * == PACKED_STREAM.
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_LABEL_OFST 8
+#define MC_CMD_INIT_RXQ_V4_IN_LABEL_LEN 4
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_INSTANCE_OFST 12
+#define MC_CMD_INIT_RXQ_V4_IN_INSTANCE_LEN 4
+/* There will be more flags here. */
+#define MC_CMD_INIT_RXQ_V4_IN_FLAGS_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAGS_LEN 4
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_BUFF_MODE_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_BUFF_MODE_LBN 0
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_HDR_SPLIT_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_HDR_SPLIT_LBN 1
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_HDR_SPLIT_WIDTH 1
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_TIMESTAMP_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_TIMESTAMP_LBN 2
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_RXQ_V4_IN_CRC_MODE_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_CRC_MODE_LBN 3
+#define MC_CMD_INIT_RXQ_V4_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_CHAIN_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_CHAIN_LBN 7
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_CHAIN_WIDTH 1
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_PREFIX_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_PREFIX_LBN 8
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_PREFIX_WIDTH 1
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_DISABLE_SCATTER_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_DISABLE_SCATTER_LBN 9
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_INIT_RXQ_V4_IN_DMA_MODE_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_DMA_MODE_LBN 10
+#define MC_CMD_INIT_RXQ_V4_IN_DMA_MODE_WIDTH 4
+/* enum: One packet per descriptor (for normal networking) */
+#define MC_CMD_INIT_RXQ_V4_IN_SINGLE_PACKET 0x0
+/* enum: Pack multiple packets into large descriptors (for SolarCapture) */
+#define MC_CMD_INIT_RXQ_V4_IN_PACKED_STREAM 0x1
+/* enum: Pack multiple packets into large descriptors using the format designed
+ * to maximise packet rate. This mode uses 1 "bucket" per descriptor with
+ * multiple fixed-size packet buffers within each bucket. For a full
+ * description see SF-119419-TC. This mode is only supported by "dpdk" datapath
+ * firmware.
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_EQUAL_STRIDE_SUPER_BUFFER 0x2
+/* enum: Deprecated name for EQUAL_STRIDE_SUPER_BUFFER. */
+#define MC_CMD_INIT_RXQ_V4_IN_EQUAL_STRIDE_PACKED_STREAM 0x2
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_SNAPSHOT_MODE_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_SNAPSHOT_MODE_LBN 14
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_SNAPSHOT_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_V4_IN_PACKED_STREAM_BUFF_SIZE_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_PACKED_STREAM_BUFF_SIZE_LBN 15
+#define MC_CMD_INIT_RXQ_V4_IN_PACKED_STREAM_BUFF_SIZE_WIDTH 3
+#define MC_CMD_INIT_RXQ_V4_IN_PS_BUFF_1M 0x0 /* enum */
+#define MC_CMD_INIT_RXQ_V4_IN_PS_BUFF_512K 0x1 /* enum */
+#define MC_CMD_INIT_RXQ_V4_IN_PS_BUFF_256K 0x2 /* enum */
+#define MC_CMD_INIT_RXQ_V4_IN_PS_BUFF_128K 0x3 /* enum */
+#define MC_CMD_INIT_RXQ_V4_IN_PS_BUFF_64K 0x4 /* enum */
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_WANT_OUTER_CLASSES_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_WANT_OUTER_CLASSES_LBN 18
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_WANT_OUTER_CLASSES_WIDTH 1
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_FORCE_EV_MERGING_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_FORCE_EV_MERGING_LBN 19
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_FORCE_EV_MERGING_WIDTH 1
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_NO_CONT_EV_OFST 16
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_NO_CONT_EV_LBN 20
+#define MC_CMD_INIT_RXQ_V4_IN_FLAG_NO_CONT_EV_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
+#define MC_CMD_INIT_RXQ_V4_IN_OWNER_ID_OFST 20
+#define MC_CMD_INIT_RXQ_V4_IN_OWNER_ID_LEN 4
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_RXQ_V4_IN_PORT_ID_OFST 24
+#define MC_CMD_INIT_RXQ_V4_IN_PORT_ID_LEN 4
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_OFST 28
+#define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_LEN 8
+#define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_HI_OFST 32
+#define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_NUM 64
+/* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */
+#define MC_CMD_INIT_RXQ_V4_IN_SNAPSHOT_LENGTH_OFST 540
+#define MC_CMD_INIT_RXQ_V4_IN_SNAPSHOT_LENGTH_LEN 4
+/* The number of packet buffers that will be contained within each
+ * EQUAL_STRIDE_SUPER_BUFFER format bucket supplied by the driver. This field
+ * is ignored unless DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_ES_PACKET_BUFFERS_PER_BUCKET_OFST 544
+#define MC_CMD_INIT_RXQ_V4_IN_ES_PACKET_BUFFERS_PER_BUCKET_LEN 4
+/* The length in bytes of the area in each packet buffer that can be written to
+ * by the adapter. This is used to store the packet prefix and the packet
+ * payload. This length does not include any end padding added by the driver.
+ * This field is ignored unless DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_ES_MAX_DMA_LEN_OFST 548
+#define MC_CMD_INIT_RXQ_V4_IN_ES_MAX_DMA_LEN_LEN 4
+/* The length in bytes of a single packet buffer within a
+ * EQUAL_STRIDE_SUPER_BUFFER format bucket. This field is ignored unless
+ * DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_ES_PACKET_STRIDE_OFST 552
+#define MC_CMD_INIT_RXQ_V4_IN_ES_PACKET_STRIDE_LEN 4
+/* The maximum time in nanoseconds that the datapath will be backpressured if
+ * there are no RX descriptors available. If the timeout is reached and there
+ * are still no descriptors then the packet will be dropped. A timeout of 0
+ * means the datapath will never be blocked. This field is ignored unless
+ * DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_ES_HEAD_OF_LINE_BLOCK_TIMEOUT_OFST 556
+#define MC_CMD_INIT_RXQ_V4_IN_ES_HEAD_OF_LINE_BLOCK_TIMEOUT_LEN 4
+/* V4 message data */
+#define MC_CMD_INIT_RXQ_V4_IN_V4_DATA_OFST 560
+#define MC_CMD_INIT_RXQ_V4_IN_V4_DATA_LEN 4
+/* Size in bytes of buffers attached to descriptors posted to this queue. Set
+ * to zero if using this message on non-QDMA based platforms. Currently in
+ * Riverhead there is a global limit of eight different buffer sizes across all
+ * active queues. A 2KB and 4KB buffer is guaranteed to be available, but a
+ * request for a different buffer size will fail if there are already eight
+ * other buffer sizes in use. In future Riverhead this limit will go away and
+ * any size will be accepted.
+ */
+#define MC_CMD_INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES_OFST 560
+#define MC_CMD_INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES_LEN 4
+
+/* MC_CMD_INIT_RXQ_V5_IN msgrequest: INIT_RXQ request with ability to request a
+ * different RX packet prefix
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_LEN 568
+/* Size, in entries */
+#define MC_CMD_INIT_RXQ_V5_IN_SIZE_OFST 0
+#define MC_CMD_INIT_RXQ_V5_IN_SIZE_LEN 4
+/* The EVQ to send events to. This is an index originally specified to
+ * INIT_EVQ. If DMA_MODE == PACKED_STREAM this must be equal to INSTANCE.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_TARGET_EVQ_OFST 4
+#define MC_CMD_INIT_RXQ_V5_IN_TARGET_EVQ_LEN 4
+/* The value to put in the event data. Check hardware spec. for valid range.
+ * This field is ignored if DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER or DMA_MODE
+ * == PACKED_STREAM.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_LABEL_OFST 8
+#define MC_CMD_INIT_RXQ_V5_IN_LABEL_LEN 4
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_INSTANCE_OFST 12
+#define MC_CMD_INIT_RXQ_V5_IN_INSTANCE_LEN 4
+/* There will be more flags here. */
+#define MC_CMD_INIT_RXQ_V5_IN_FLAGS_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAGS_LEN 4
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_BUFF_MODE_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_BUFF_MODE_LBN 0
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_HDR_SPLIT_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_HDR_SPLIT_LBN 1
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_HDR_SPLIT_WIDTH 1
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_TIMESTAMP_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_TIMESTAMP_LBN 2
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_RXQ_V5_IN_CRC_MODE_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_CRC_MODE_LBN 3
+#define MC_CMD_INIT_RXQ_V5_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_CHAIN_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_CHAIN_LBN 7
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_CHAIN_WIDTH 1
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_PREFIX_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_PREFIX_LBN 8
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_PREFIX_WIDTH 1
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_DISABLE_SCATTER_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_DISABLE_SCATTER_LBN 9
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_INIT_RXQ_V5_IN_DMA_MODE_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_DMA_MODE_LBN 10
+#define MC_CMD_INIT_RXQ_V5_IN_DMA_MODE_WIDTH 4
+/* enum: One packet per descriptor (for normal networking) */
+#define MC_CMD_INIT_RXQ_V5_IN_SINGLE_PACKET 0x0
+/* enum: Pack multiple packets into large descriptors (for SolarCapture) */
+#define MC_CMD_INIT_RXQ_V5_IN_PACKED_STREAM 0x1
+/* enum: Pack multiple packets into large descriptors using the format designed
+ * to maximise packet rate. This mode uses 1 "bucket" per descriptor with
+ * multiple fixed-size packet buffers within each bucket. For a full
+ * description see SF-119419-TC. This mode is only supported by "dpdk" datapath
+ * firmware.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_EQUAL_STRIDE_SUPER_BUFFER 0x2
+/* enum: Deprecated name for EQUAL_STRIDE_SUPER_BUFFER. */
+#define MC_CMD_INIT_RXQ_V5_IN_EQUAL_STRIDE_PACKED_STREAM 0x2
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_SNAPSHOT_MODE_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_SNAPSHOT_MODE_LBN 14
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_SNAPSHOT_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_V5_IN_PACKED_STREAM_BUFF_SIZE_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_PACKED_STREAM_BUFF_SIZE_LBN 15
+#define MC_CMD_INIT_RXQ_V5_IN_PACKED_STREAM_BUFF_SIZE_WIDTH 3
+#define MC_CMD_INIT_RXQ_V5_IN_PS_BUFF_1M 0x0 /* enum */
+#define MC_CMD_INIT_RXQ_V5_IN_PS_BUFF_512K 0x1 /* enum */
+#define MC_CMD_INIT_RXQ_V5_IN_PS_BUFF_256K 0x2 /* enum */
+#define MC_CMD_INIT_RXQ_V5_IN_PS_BUFF_128K 0x3 /* enum */
+#define MC_CMD_INIT_RXQ_V5_IN_PS_BUFF_64K 0x4 /* enum */
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_WANT_OUTER_CLASSES_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_WANT_OUTER_CLASSES_LBN 18
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_WANT_OUTER_CLASSES_WIDTH 1
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_FORCE_EV_MERGING_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_FORCE_EV_MERGING_LBN 19
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_FORCE_EV_MERGING_WIDTH 1
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_NO_CONT_EV_OFST 16
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_NO_CONT_EV_LBN 20
+#define MC_CMD_INIT_RXQ_V5_IN_FLAG_NO_CONT_EV_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
+#define MC_CMD_INIT_RXQ_V5_IN_OWNER_ID_OFST 20
+#define MC_CMD_INIT_RXQ_V5_IN_OWNER_ID_LEN 4
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_RXQ_V5_IN_PORT_ID_OFST 24
+#define MC_CMD_INIT_RXQ_V5_IN_PORT_ID_LEN 4
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_OFST 28
+#define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_LEN 8
+#define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_HI_OFST 32
+#define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_NUM 64
+/* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */
+#define MC_CMD_INIT_RXQ_V5_IN_SNAPSHOT_LENGTH_OFST 540
+#define MC_CMD_INIT_RXQ_V5_IN_SNAPSHOT_LENGTH_LEN 4
+/* The number of packet buffers that will be contained within each
+ * EQUAL_STRIDE_SUPER_BUFFER format bucket supplied by the driver. This field
+ * is ignored unless DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_ES_PACKET_BUFFERS_PER_BUCKET_OFST 544
+#define MC_CMD_INIT_RXQ_V5_IN_ES_PACKET_BUFFERS_PER_BUCKET_LEN 4
+/* The length in bytes of the area in each packet buffer that can be written to
+ * by the adapter. This is used to store the packet prefix and the packet
+ * payload. This length does not include any end padding added by the driver.
+ * This field is ignored unless DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_ES_MAX_DMA_LEN_OFST 548
+#define MC_CMD_INIT_RXQ_V5_IN_ES_MAX_DMA_LEN_LEN 4
+/* The length in bytes of a single packet buffer within a
+ * EQUAL_STRIDE_SUPER_BUFFER format bucket. This field is ignored unless
+ * DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_ES_PACKET_STRIDE_OFST 552
+#define MC_CMD_INIT_RXQ_V5_IN_ES_PACKET_STRIDE_LEN 4
+/* The maximum time in nanoseconds that the datapath will be backpressured if
+ * there are no RX descriptors available. If the timeout is reached and there
+ * are still no descriptors then the packet will be dropped. A timeout of 0
+ * means the datapath will never be blocked. This field is ignored unless
+ * DMA_MODE == EQUAL_STRIDE_SUPER_BUFFER.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_ES_HEAD_OF_LINE_BLOCK_TIMEOUT_OFST 556
+#define MC_CMD_INIT_RXQ_V5_IN_ES_HEAD_OF_LINE_BLOCK_TIMEOUT_LEN 4
+/* V4 message data */
+#define MC_CMD_INIT_RXQ_V5_IN_V4_DATA_OFST 560
+#define MC_CMD_INIT_RXQ_V5_IN_V4_DATA_LEN 4
+/* Size in bytes of buffers attached to descriptors posted to this queue. Set
+ * to zero if using this message on non-QDMA based platforms. Currently in
+ * Riverhead there is a global limit of eight different buffer sizes across all
+ * active queues. A 2KB and 4KB buffer is guaranteed to be available, but a
+ * request for a different buffer size will fail if there are already eight
+ * other buffer sizes in use. In future Riverhead this limit will go away and
+ * any size will be accepted.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_BUFFER_SIZE_BYTES_OFST 560
+#define MC_CMD_INIT_RXQ_V5_IN_BUFFER_SIZE_BYTES_LEN 4
+/* Prefix id for the RX prefix format to use on packets delivered this queue.
+ * Zero is always a valid prefix id and means the default prefix format
+ * documented for the platform. Other prefix ids can be obtained by calling
+ * MC_CMD_GET_RX_PREFIX_ID with a requested set of prefix fields.
+ */
+#define MC_CMD_INIT_RXQ_V5_IN_RX_PREFIX_ID_OFST 564
+#define MC_CMD_INIT_RXQ_V5_IN_RX_PREFIX_ID_LEN 4
+
/* MC_CMD_INIT_RXQ_OUT msgresponse */
#define MC_CMD_INIT_RXQ_OUT_LEN 0
@@ -7526,11 +9250,18 @@
/* MC_CMD_INIT_RXQ_V3_OUT msgresponse */
#define MC_CMD_INIT_RXQ_V3_OUT_LEN 0
+/* MC_CMD_INIT_RXQ_V4_OUT msgresponse */
+#define MC_CMD_INIT_RXQ_V4_OUT_LEN 0
+
+/* MC_CMD_INIT_RXQ_V5_OUT msgresponse */
+#define MC_CMD_INIT_RXQ_V5_OUT_LEN 0
+
/***********************************/
/* MC_CMD_INIT_TXQ
*/
#define MC_CMD_INIT_TXQ 0x82
+#undef MC_CMD_0x82_PRIVILEGE_CTG
#define MC_CMD_0x82_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -7539,7 +9270,9 @@
*/
#define MC_CMD_INIT_TXQ_IN_LENMIN 36
#define MC_CMD_INIT_TXQ_IN_LENMAX 252
+#define MC_CMD_INIT_TXQ_IN_LENMAX_MCDI2 1020
#define MC_CMD_INIT_TXQ_IN_LEN(num) (28+8*(num))
+#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_NUM(len) (((len)-28)/8)
/* Size, in entries */
#define MC_CMD_INIT_TXQ_IN_SIZE_OFST 0
#define MC_CMD_INIT_TXQ_IN_SIZE_LEN 4
@@ -7559,22 +9292,31 @@
/* There will be more flags here. */
#define MC_CMD_INIT_TXQ_IN_FLAGS_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAGS_LEN 4
+#define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_LBN 0
#define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_IP_CSUM_DIS_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_IP_CSUM_DIS_LBN 1
#define MC_CMD_INIT_TXQ_IN_FLAG_IP_CSUM_DIS_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_CSUM_DIS_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_CSUM_DIS_LBN 2
#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_CSUM_DIS_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_UDP_ONLY_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_UDP_ONLY_LBN 3
#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_UDP_ONLY_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_CRC_MODE_OFST 16
#define MC_CMD_INIT_TXQ_IN_CRC_MODE_LBN 4
#define MC_CMD_INIT_TXQ_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_TXQ_IN_FLAG_TIMESTAMP_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_TIMESTAMP_LBN 8
#define MC_CMD_INIT_TXQ_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_PACER_BYPASS_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_PACER_BYPASS_LBN 9
#define MC_CMD_INIT_TXQ_IN_FLAG_PACER_BYPASS_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_IP_CSUM_EN_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_IP_CSUM_EN_LBN 10
#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_IP_CSUM_EN_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_TCP_CSUM_EN_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_TCP_CSUM_EN_LBN 11
#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_TCP_CSUM_EN_WIDTH 1
/* Owner ID to use if in buffer mode (zero if physical) */
@@ -7590,6 +9332,7 @@
#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_HI_OFST 32
#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_MAXNUM 28
+#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_MAXNUM_MCDI2 124
/* MC_CMD_INIT_TXQ_EXT_IN msgrequest: Extended INIT_TXQ with additional mode
* flags
@@ -7614,30 +9357,48 @@
/* There will be more flags here. */
#define MC_CMD_INIT_TXQ_EXT_IN_FLAGS_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAGS_LEN 4
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_BUFF_MODE_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_BUFF_MODE_LBN 0
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_IP_CSUM_DIS_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_IP_CSUM_DIS_LBN 1
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_IP_CSUM_DIS_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_CSUM_DIS_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_CSUM_DIS_LBN 2
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_CSUM_DIS_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_UDP_ONLY_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_UDP_ONLY_LBN 3
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_UDP_ONLY_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_CRC_MODE_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_CRC_MODE_LBN 4
#define MC_CMD_INIT_TXQ_EXT_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TIMESTAMP_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TIMESTAMP_LBN 8
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_PACER_BYPASS_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_PACER_BYPASS_LBN 9
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_PACER_BYPASS_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_IP_CSUM_EN_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_IP_CSUM_EN_LBN 10
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_IP_CSUM_EN_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_TCP_CSUM_EN_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_TCP_CSUM_EN_LBN 11
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_TCP_CSUM_EN_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TSOV2_EN_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TSOV2_EN_LBN 12
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TSOV2_EN_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_LBN 13
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_UTHRESH_OFST 16
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_UTHRESH_LBN 14
#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_CTPIO_UTHRESH_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_M2M_D2C_OFST 16
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_M2M_D2C_LBN 15
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_M2M_D2C_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_DESC_PROXY_OFST 16
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_DESC_PROXY_LBN 16
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_DESC_PROXY_WIDTH 1
/* Owner ID to use if in buffer mode (zero if physical) */
#define MC_CMD_INIT_TXQ_EXT_IN_OWNER_ID_OFST 20
#define MC_CMD_INIT_TXQ_EXT_IN_OWNER_ID_LEN 4
@@ -7651,11 +9412,14 @@
#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_HI_OFST 32
#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MAXNUM 64
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MAXNUM_MCDI2 64
/* Flags related to Qbb flow control mode. */
#define MC_CMD_INIT_TXQ_EXT_IN_QBB_FLAGS_OFST 540
#define MC_CMD_INIT_TXQ_EXT_IN_QBB_FLAGS_LEN 4
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_ENABLE_OFST 540
#define MC_CMD_INIT_TXQ_EXT_IN_QBB_ENABLE_LBN 0
#define MC_CMD_INIT_TXQ_EXT_IN_QBB_ENABLE_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_PRIORITY_OFST 540
#define MC_CMD_INIT_TXQ_EXT_IN_QBB_PRIORITY_LBN 1
#define MC_CMD_INIT_TXQ_EXT_IN_QBB_PRIORITY_WIDTH 3
@@ -7671,6 +9435,7 @@
* or the operation will fail with EBUSY
*/
#define MC_CMD_FINI_EVQ 0x83
+#undef MC_CMD_0x83_PRIVILEGE_CTG
#define MC_CMD_0x83_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -7691,6 +9456,7 @@
* Teardown a RXQ.
*/
#define MC_CMD_FINI_RXQ 0x84
+#undef MC_CMD_0x84_PRIVILEGE_CTG
#define MC_CMD_0x84_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -7709,6 +9475,7 @@
* Teardown a TXQ.
*/
#define MC_CMD_FINI_TXQ 0x85
+#undef MC_CMD_0x85_PRIVILEGE_CTG
#define MC_CMD_0x85_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -7727,6 +9494,7 @@
* Generate an event on an EVQ belonging to the function issuing the command.
*/
#define MC_CMD_DRIVER_EVENT 0x86
+#undef MC_CMD_0x86_PRIVILEGE_CTG
#define MC_CMD_0x86_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -7753,6 +9521,7 @@
* MC_CMD_SET_FUNC, which remains available for Siena but now deprecated.
*/
#define MC_CMD_PROXY_CMD 0x5b
+#undef MC_CMD_0x5b_PRIVILEGE_CTG
#define MC_CMD_0x5b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -7761,8 +9530,10 @@
/* The handle of the target function. */
#define MC_CMD_PROXY_CMD_IN_TARGET_OFST 0
#define MC_CMD_PROXY_CMD_IN_TARGET_LEN 4
+#define MC_CMD_PROXY_CMD_IN_TARGET_PF_OFST 0
#define MC_CMD_PROXY_CMD_IN_TARGET_PF_LBN 0
#define MC_CMD_PROXY_CMD_IN_TARGET_PF_WIDTH 16
+#define MC_CMD_PROXY_CMD_IN_TARGET_VF_OFST 0
#define MC_CMD_PROXY_CMD_IN_TARGET_VF_LBN 16
#define MC_CMD_PROXY_CMD_IN_TARGET_VF_WIDTH 16
#define MC_CMD_PROXY_CMD_IN_VF_NULL 0xffff /* enum */
@@ -7818,6 +9589,7 @@
* a designated admin function
*/
#define MC_CMD_PROXY_CONFIGURE 0x58
+#undef MC_CMD_0x58_PRIVILEGE_CTG
#define MC_CMD_0x58_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -7825,6 +9597,7 @@
#define MC_CMD_PROXY_CONFIGURE_IN_LEN 108
#define MC_CMD_PROXY_CONFIGURE_IN_FLAGS_OFST 0
#define MC_CMD_PROXY_CONFIGURE_IN_FLAGS_LEN 4
+#define MC_CMD_PROXY_CONFIGURE_IN_ENABLE_OFST 0
#define MC_CMD_PROXY_CONFIGURE_IN_ENABLE_LBN 0
#define MC_CMD_PROXY_CONFIGURE_IN_ENABLE_WIDTH 1
/* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS
@@ -7869,6 +9642,7 @@
#define MC_CMD_PROXY_CONFIGURE_EXT_IN_LEN 112
#define MC_CMD_PROXY_CONFIGURE_EXT_IN_FLAGS_OFST 0
#define MC_CMD_PROXY_CONFIGURE_EXT_IN_FLAGS_LEN 4
+#define MC_CMD_PROXY_CONFIGURE_EXT_IN_ENABLE_OFST 0
#define MC_CMD_PROXY_CONFIGURE_EXT_IN_ENABLE_LBN 0
#define MC_CMD_PROXY_CONFIGURE_EXT_IN_ENABLE_WIDTH 1
/* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS
@@ -7923,6 +9697,7 @@
* MC_CMD_PROXY_CONFIGURE).
*/
#define MC_CMD_PROXY_COMPLETE 0x5f
+#undef MC_CMD_0x5f_PRIVILEGE_CTG
#define MC_CMD_0x5f_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -7960,6 +9735,7 @@
* cannot do so). The buffer table entries will initially be zeroed.
*/
#define MC_CMD_ALLOC_BUFTBL_CHUNK 0x87
+#undef MC_CMD_0x87_PRIVILEGE_CTG
#define MC_CMD_0x87_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
@@ -7990,13 +9766,16 @@
* Reprogram a set of buffer table entries in the specified chunk.
*/
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES 0x88
+#undef MC_CMD_0x88_PRIVILEGE_CTG
#define MC_CMD_0x88_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN msgrequest */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMIN 20
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX 268
+#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX_MCDI2 268
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LEN(num) (12+8*(num))
+#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_NUM(len) (((len)-12)/8)
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_HANDLE_OFST 0
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_HANDLE_LEN 4
/* ID */
@@ -8012,6 +9791,7 @@
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_HI_OFST 16
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MINNUM 1
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MAXNUM 32
+#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MAXNUM_MCDI2 32
/* MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT msgresponse */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT_LEN 0
@@ -8021,6 +9801,7 @@
/* MC_CMD_FREE_BUFTBL_CHUNK
*/
#define MC_CMD_FREE_BUFTBL_CHUNK 0x89
+#undef MC_CMD_0x89_PRIVILEGE_CTG
#define MC_CMD_0x89_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
@@ -8038,6 +9819,7 @@
* Multiplexed MCDI call for filter operations
*/
#define MC_CMD_FILTER_OP 0x8a
+#undef MC_CMD_0x8a_PRIVILEGE_CTG
#define MC_CMD_0x8a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -8070,32 +9852,46 @@
/* fields to include in match criteria */
#define MC_CMD_FILTER_OP_IN_MATCH_FIELDS_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_FIELDS_LEN 4
+#define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_LBN 0
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_DST_IP_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_DST_IP_LBN 1
#define MC_CMD_FILTER_OP_IN_MATCH_DST_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_SRC_MAC_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_MAC_LBN 2
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_SRC_PORT_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_PORT_LBN 3
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_DST_MAC_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_DST_MAC_LBN 4
#define MC_CMD_FILTER_OP_IN_MATCH_DST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_DST_PORT_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_DST_PORT_LBN 5
#define MC_CMD_FILTER_OP_IN_MATCH_DST_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_ETHER_TYPE_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_ETHER_TYPE_LBN 6
#define MC_CMD_FILTER_OP_IN_MATCH_ETHER_TYPE_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_INNER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_INNER_VLAN_LBN 7
#define MC_CMD_FILTER_OP_IN_MATCH_INNER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_OUTER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_OUTER_VLAN_LBN 8
#define MC_CMD_FILTER_OP_IN_MATCH_OUTER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_IP_PROTO_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_IP_PROTO_LBN 9
#define MC_CMD_FILTER_OP_IN_MATCH_IP_PROTO_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF0_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF0_LBN 10
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF0_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF1_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF1_LBN 11
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF1_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_LBN 30
#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_LBN 31
#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1
/* receive destination */
@@ -8143,8 +9939,10 @@
#define MC_CMD_FILTER_OP_IN_TX_DEST_LEN 4
/* enum: request default behaviour (based on filter type) */
#define MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT 0xffffffff
+#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_OFST 40
#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_LBN 0
#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_OFST 40
#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_LBN 1
#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_WIDTH 1
/* source MAC address to match (as bytes in network order) */
@@ -8210,60 +10008,88 @@
/* fields to include in match criteria */
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FIELDS_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FIELDS_LEN 4
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_IP_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_IP_LBN 0
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_IP_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_IP_LBN 1
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_MAC_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_MAC_LBN 2
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_PORT_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_PORT_LBN 3
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_MAC_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_MAC_LBN 4
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_PORT_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_PORT_LBN 5
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_LBN 6
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_INNER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_INNER_VLAN_LBN 7
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_INNER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_OUTER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_OUTER_VLAN_LBN 8
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_OUTER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_LBN 9
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FWDEF0_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FWDEF0_LBN 10
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FWDEF0_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_VNI_OR_VSID_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_VNI_OR_VSID_LBN 11
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_VNI_OR_VSID_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_IP_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_IP_LBN 12
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_IP_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_IP_LBN 13
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_MAC_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_MAC_LBN 14
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_PORT_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_PORT_LBN 15
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_MAC_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_MAC_LBN 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_PORT_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_PORT_LBN 17
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_ETHER_TYPE_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_ETHER_TYPE_LBN 18
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_ETHER_TYPE_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_INNER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_INNER_VLAN_LBN 19
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_INNER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_OUTER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_OUTER_VLAN_LBN 20
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_OUTER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_IP_PROTO_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_IP_PROTO_LBN 21
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_IP_PROTO_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF0_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF0_LBN 22
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF0_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF1_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF1_LBN 23
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF1_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_LBN 24
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_LBN 25
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_LBN 30
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_LBN 31
#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1
/* receive destination */
@@ -8311,8 +10137,10 @@
#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_LEN 4
/* enum: request default behaviour (based on filter type) */
#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_DEFAULT 0xffffffff
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_OFST 40
#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_LBN 0
#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_PM_OFST 40
#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_PM_LBN 1
#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_PM_WIDTH 1
/* source MAC address to match (as bytes in network order) */
@@ -8348,8 +10176,10 @@
*/
#define MC_CMD_FILTER_OP_EXT_IN_VNI_OR_VSID_OFST 72
#define MC_CMD_FILTER_OP_EXT_IN_VNI_OR_VSID_LEN 4
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_VALUE_OFST 72
#define MC_CMD_FILTER_OP_EXT_IN_VNI_VALUE_LBN 0
#define MC_CMD_FILTER_OP_EXT_IN_VNI_VALUE_WIDTH 24
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_OFST 72
#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_LBN 24
#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_WIDTH 8
/* enum: Match VXLAN traffic with this VNI */
@@ -8358,8 +10188,10 @@
#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_GENEVE 0x1
/* enum: Reserved for experimental development use */
#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_EXPERIMENTAL 0xfe
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_OFST 72
#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_LBN 0
#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_WIDTH 24
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_OFST 72
#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_LBN 24
#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_WIDTH 8
/* enum: Match NVGRE traffic with this VSID */
@@ -8454,60 +10286,88 @@
/* fields to include in match criteria */
#define MC_CMD_FILTER_OP_V3_IN_MATCH_FIELDS_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_FIELDS_LEN 4
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_IP_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_IP_LBN 0
#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_IP_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_IP_LBN 1
#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_MAC_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_MAC_LBN 2
#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_PORT_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_PORT_LBN 3
#define MC_CMD_FILTER_OP_V3_IN_MATCH_SRC_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_MAC_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_MAC_LBN 4
#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_PORT_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_PORT_LBN 5
#define MC_CMD_FILTER_OP_V3_IN_MATCH_DST_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_ETHER_TYPE_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_ETHER_TYPE_LBN 6
#define MC_CMD_FILTER_OP_V3_IN_MATCH_ETHER_TYPE_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_INNER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_INNER_VLAN_LBN 7
#define MC_CMD_FILTER_OP_V3_IN_MATCH_INNER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_OUTER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_OUTER_VLAN_LBN 8
#define MC_CMD_FILTER_OP_V3_IN_MATCH_OUTER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IP_PROTO_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IP_PROTO_LBN 9
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IP_PROTO_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_FWDEF0_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_FWDEF0_LBN 10
#define MC_CMD_FILTER_OP_V3_IN_MATCH_FWDEF0_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_VNI_OR_VSID_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_VNI_OR_VSID_LBN 11
#define MC_CMD_FILTER_OP_V3_IN_MATCH_VNI_OR_VSID_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_IP_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_IP_LBN 12
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_IP_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_IP_LBN 13
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_MAC_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_MAC_LBN 14
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_PORT_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_PORT_LBN 15
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_SRC_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_MAC_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_MAC_LBN 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_PORT_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_PORT_LBN 17
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_DST_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_ETHER_TYPE_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_ETHER_TYPE_LBN 18
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_ETHER_TYPE_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_INNER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_INNER_VLAN_LBN 19
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_INNER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_OUTER_VLAN_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_OUTER_VLAN_LBN 20
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_OUTER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_IP_PROTO_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_IP_PROTO_LBN 21
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_IP_PROTO_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF0_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF0_LBN 22
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF0_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF1_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF1_LBN 23
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_FWDEF1_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_LBN 24
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_LBN 25
#define MC_CMD_FILTER_OP_V3_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_MCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_MCAST_DST_LBN 30
#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_UCAST_DST_OFST 16
#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_UCAST_DST_LBN 31
#define MC_CMD_FILTER_OP_V3_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1
/* receive destination */
@@ -8555,8 +10415,10 @@
#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_LEN 4
/* enum: request default behaviour (based on filter type) */
#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_DEFAULT 0xffffffff
+#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_MAC_OFST 40
#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_MAC_LBN 0
#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_PM_OFST 40
#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_PM_LBN 1
#define MC_CMD_FILTER_OP_V3_IN_TX_DEST_PM_WIDTH 1
/* source MAC address to match (as bytes in network order) */
@@ -8592,8 +10454,10 @@
*/
#define MC_CMD_FILTER_OP_V3_IN_VNI_OR_VSID_OFST 72
#define MC_CMD_FILTER_OP_V3_IN_VNI_OR_VSID_LEN 4
+#define MC_CMD_FILTER_OP_V3_IN_VNI_VALUE_OFST 72
#define MC_CMD_FILTER_OP_V3_IN_VNI_VALUE_LBN 0
#define MC_CMD_FILTER_OP_V3_IN_VNI_VALUE_WIDTH 24
+#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_OFST 72
#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_LBN 24
#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_WIDTH 8
/* enum: Match VXLAN traffic with this VNI */
@@ -8602,8 +10466,10 @@
#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_GENEVE 0x1
/* enum: Reserved for experimental development use */
#define MC_CMD_FILTER_OP_V3_IN_VNI_TYPE_EXPERIMENTAL 0xfe
+#define MC_CMD_FILTER_OP_V3_IN_VSID_VALUE_OFST 72
#define MC_CMD_FILTER_OP_V3_IN_VSID_VALUE_LBN 0
#define MC_CMD_FILTER_OP_V3_IN_VSID_VALUE_WIDTH 24
+#define MC_CMD_FILTER_OP_V3_IN_VSID_TYPE_OFST 72
#define MC_CMD_FILTER_OP_V3_IN_VSID_TYPE_LBN 24
#define MC_CMD_FILTER_OP_V3_IN_VSID_TYPE_WIDTH 8
/* enum: Match NVGRE traffic with this VSID */
@@ -8693,7 +10559,10 @@
* support the DPDK rte_flow "MARK" action.
*/
#define MC_CMD_FILTER_OP_V3_IN_MATCH_ACTION_MARK 0x2
-/* the mark value for MATCH_ACTION_MARK */
+/* the mark value for MATCH_ACTION_MARK. Requesting a value larger than the
+ * maximum (obtained from MC_CMD_GET_CAPABILITIES_V5/FILTER_ACTION_MARK_MAX)
+ * will cause the filter insertion to fail with EINVAL.
+ */
#define MC_CMD_FILTER_OP_V3_IN_MATCH_MARK_VALUE_OFST 176
#define MC_CMD_FILTER_OP_V3_IN_MATCH_MARK_VALUE_LEN 4
@@ -8741,6 +10610,7 @@
* Get information related to the parser-dispatcher subsystem
*/
#define MC_CMD_GET_PARSER_DISP_INFO 0xe4
+#undef MC_CMD_0xe4_PRIVILEGE_CTG
#define MC_CMD_0xe4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -8764,11 +10634,17 @@
* frames (Medford only)
*/
#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_ENCAP_RX_MATCHES 0x4
+/* enum: read the list of supported matches for the encapsulation detection
+ * rules inserted by MC_CMD_VNIC_ENCAP_RULE_ADD. (ef100 and later)
+ */
+#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_VNIC_ENCAP_MATCHES 0x5
/* MC_CMD_GET_PARSER_DISP_INFO_OUT msgresponse */
#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMIN 8
#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX 252
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX_MCDI2 1020
#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LEN(num) (8+4*(num))
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_NUM(len) (((len)-8)/4)
/* identifies the type of operation requested */
#define MC_CMD_GET_PARSER_DISP_INFO_OUT_OP_OFST 0
#define MC_CMD_GET_PARSER_DISP_INFO_OUT_OP_LEN 4
@@ -8784,6 +10660,7 @@
#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_LEN 4
#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MINNUM 0
#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MAXNUM 61
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MAXNUM_MCDI2 253
/* MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT msgresponse */
#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_LEN 8
@@ -8795,9 +10672,38 @@
/* bitfield of filter insertion restrictions */
#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_RESTRICTION_FLAGS_OFST 4
#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_RESTRICTION_FLAGS_LEN 4
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_DST_IP_MCAST_ONLY_OFST 4
#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_DST_IP_MCAST_ONLY_LBN 0
#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_DST_IP_MCAST_ONLY_WIDTH 1
+/* MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT msgresponse: This response is
+ * returned if a MC_CMD_GET_PARSER_DISP_INFO_IN request is sent with OP value
+ * OP_GET_SUPPORTED_VNIC_ENCAP_MATCHES. It contains information about the
+ * supported match types that can be used in the encapsulation detection rules
+ * inserted by MC_CMD_VNIC_ENCAP_RULE_ADD.
+ */
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_LENMIN 8
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_LENMAX 252
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_LENMAX_MCDI2 1020
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_LEN(num) (8+4*(num))
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_SUPPORTED_MATCHES_NUM(len) (((len)-8)/4)
+/* The op code OP_GET_SUPPORTED_VNIC_ENCAP_MATCHES is returned. */
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_OP_OFST 0
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_OP_LEN 4
+/* Enum values, see field(s): */
+/* MC_CMD_GET_PARSER_DISP_INFO_IN/OP */
+/* number of supported match types */
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_NUM_SUPPORTED_MATCHES_OFST 4
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_NUM_SUPPORTED_MATCHES_LEN 4
+/* array of supported match types (valid MATCH_FLAGS values for
+ * MC_CMD_VNIC_ENCAP_RULE_ADD) sorted in decreasing priority order
+ */
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_SUPPORTED_MATCHES_OFST 8
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_SUPPORTED_MATCHES_LEN 4
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_SUPPORTED_MATCHES_MINNUM 0
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_SUPPORTED_MATCHES_MAXNUM 61
+#define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_SUPPORTED_MATCHES_MAXNUM_MCDI2 253
+
/***********************************/
/* MC_CMD_PARSER_DISP_RW
@@ -8809,6 +10715,7 @@
* permitted.
*/
#define MC_CMD_PARSER_DISP_RW 0xe5
+#undef MC_CMD_0xe5_PRIVILEGE_CTG
#define MC_CMD_0xe5_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -8898,6 +10805,7 @@
* Get number of PFs on the device.
*/
#define MC_CMD_GET_PF_COUNT 0xb6
+#undef MC_CMD_0xb6_PRIVILEGE_CTG
#define MC_CMD_0xb6_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -8932,6 +10840,7 @@
* Get port assignment for current PCI function.
*/
#define MC_CMD_GET_PORT_ASSIGNMENT 0xb8
+#undef MC_CMD_0xb8_PRIVILEGE_CTG
#define MC_CMD_0xb8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -8950,6 +10859,7 @@
* Set port assignment for current PCI function.
*/
#define MC_CMD_SET_PORT_ASSIGNMENT 0xb9
+#undef MC_CMD_0xb9_PRIVILEGE_CTG
#define MC_CMD_0xb9_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -8968,6 +10878,7 @@
* Allocate VIs for current PCI function.
*/
#define MC_CMD_ALLOC_VIS 0x8b
+#undef MC_CMD_0x8b_PRIVILEGE_CTG
#define MC_CMD_0x8b_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -9014,6 +10925,7 @@
* but not freed.
*/
#define MC_CMD_FREE_VIS 0x8c
+#undef MC_CMD_0x8c_PRIVILEGE_CTG
#define MC_CMD_0x8c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -9029,6 +10941,7 @@
* Get SRIOV config for this PF.
*/
#define MC_CMD_GET_SRIOV_CFG 0xba
+#undef MC_CMD_0xba_PRIVILEGE_CTG
#define MC_CMD_0xba_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -9045,6 +10958,7 @@
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_MAX_LEN 4
#define MC_CMD_GET_SRIOV_CFG_OUT_FLAGS_OFST 8
#define MC_CMD_GET_SRIOV_CFG_OUT_FLAGS_LEN 4
+#define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_OFST 8
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_LBN 0
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_WIDTH 1
/* RID offset of first VF from PF. */
@@ -9060,6 +10974,7 @@
* Set SRIOV config for this PF.
*/
#define MC_CMD_SET_SRIOV_CFG 0xbb
+#undef MC_CMD_0xbb_PRIVILEGE_CTG
#define MC_CMD_0xbb_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -9073,6 +10988,7 @@
#define MC_CMD_SET_SRIOV_CFG_IN_VF_MAX_LEN 4
#define MC_CMD_SET_SRIOV_CFG_IN_FLAGS_OFST 8
#define MC_CMD_SET_SRIOV_CFG_IN_FLAGS_LEN 4
+#define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_OFST 8
#define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_LBN 0
#define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_WIDTH 1
/* RID offset of first VF from PF, or 0 for no change, or
@@ -9096,6 +11012,7 @@
* function.
*/
#define MC_CMD_GET_VI_ALLOC_INFO 0x8d
+#undef MC_CMD_0x8d_PRIVILEGE_CTG
#define MC_CMD_0x8d_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -9122,6 +11039,7 @@
* For CmdClient use. Dump pertinent information on a specific absolute VI.
*/
#define MC_CMD_DUMP_VI_STATE 0x8e
+#undef MC_CMD_0x8e_PRIVILEGE_CTG
#define MC_CMD_0x8e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -9164,10 +11082,13 @@
/* Combined metadata field. */
#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_OFST 28
#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_LEN 4
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_BASE_OFST 28
#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_BASE_LBN 0
#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_BASE_WIDTH 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_NPAGES_OFST 28
#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_NPAGES_LBN 16
#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_NPAGES_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_WKUP_REF_OFST 28
#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_WKUP_REF_LBN 24
#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_WKUP_REF_WIDTH 8
/* TXDPCPU raw table data for queue. */
@@ -9190,14 +11111,19 @@
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_LEN 8
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_LO_OFST 56
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_HI_OFST 60
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_BASE_OFST 56
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_BASE_LBN 0
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_BASE_WIDTH 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_NPAGES_OFST 56
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_NPAGES_LBN 16
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_NPAGES_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_QSTATE_OFST 56
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_QSTATE_LBN 24
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_QSTATE_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_WAITCOUNT_OFST 56
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_WAITCOUNT_LBN 32
#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_WAITCOUNT_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_PADDING_OFST 56
#define MC_CMD_DUMP_VI_STATE_OUT_VI_PADDING_LBN 40
#define MC_CMD_DUMP_VI_STATE_OUT_VI_PADDING_WIDTH 24
/* RXDPCPU raw table data for queue. */
@@ -9220,12 +11146,16 @@
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_LEN 8
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_LO_OFST 88
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_HI_OFST 92
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_BASE_OFST 88
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_BASE_LBN 0
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_BASE_WIDTH 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_NPAGES_OFST 88
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_NPAGES_LBN 16
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_NPAGES_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_QSTATE_OFST 88
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_QSTATE_LBN 24
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_QSTATE_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_WAITCOUNT_OFST 88
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_WAITCOUNT_LBN 32
#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_WAITCOUNT_WIDTH 8
@@ -9235,6 +11165,7 @@
* Allocate a push I/O buffer for later use with a tx queue.
*/
#define MC_CMD_ALLOC_PIOBUF 0x8f
+#undef MC_CMD_0x8f_PRIVILEGE_CTG
#define MC_CMD_0x8f_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
@@ -9253,6 +11184,7 @@
* Free a push I/O buffer.
*/
#define MC_CMD_FREE_PIOBUF 0x90
+#undef MC_CMD_0x90_PRIVILEGE_CTG
#define MC_CMD_0x90_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
@@ -9271,6 +11203,7 @@
* Get TLP steering and ordering information for a VI.
*/
#define MC_CMD_GET_VI_TLP_PROCESSING 0xb0
+#undef MC_CMD_0xb0_PRIVILEGE_CTG
#define MC_CMD_0xb0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -9309,6 +11242,7 @@
* Set TLP steering and ordering information for a VI.
*/
#define MC_CMD_SET_VI_TLP_PROCESSING 0xb1
+#undef MC_CMD_0xb1_PRIVILEGE_CTG
#define MC_CMD_0xb1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -9347,6 +11281,7 @@
* Get global PCIe steering and transaction processing configuration.
*/
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS 0xbc
+#undef MC_CMD_0xbc_PRIVILEGE_CTG
#define MC_CMD_0xbc_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -9372,38 +11307,55 @@
/* Amalgamated TLP info word. */
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_WORD_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_WORD_LEN 4
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_WTAG_EN_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_WTAG_EN_LBN 0
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_WTAG_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_SPARE_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_SPARE_LBN 1
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_SPARE_WIDTH 31
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_DL_EN_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_DL_EN_LBN 0
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_DL_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_TX_EN_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_TX_EN_LBN 1
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_TX_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_EV_EN_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_EV_EN_LBN 2
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_EV_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_RX_EN_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_RX_EN_LBN 3
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_RX_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_SPARE_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_SPARE_LBN 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_SPARE_WIDTH 28
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_RXDMA_EN_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_RXDMA_EN_LBN 0
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_RXDMA_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_TXDMA_EN_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_TXDMA_EN_LBN 1
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_TXDMA_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_DL_EN_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_DL_EN_LBN 2
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_DL_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_SPARE_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_SPARE_LBN 3
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_SPARE_WIDTH 29
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_MSIX_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_MSIX_LBN 0
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_MSIX_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_DL_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_DL_LBN 2
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_DL_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_TX_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_TX_LBN 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_TX_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_EV_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_EV_LBN 6
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_EV_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_RX_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_RX_LBN 8
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_RX_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TLP_TYPE_SPARE_OFST 4
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TLP_TYPE_SPARE_LBN 9
#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TLP_TYPE_SPARE_WIDTH 23
@@ -9413,6 +11365,7 @@
* Set global PCIe steering and transaction processing configuration.
*/
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS 0xbd
+#undef MC_CMD_0xbd_PRIVILEGE_CTG
#define MC_CMD_0xbd_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -9425,32 +11378,46 @@
/* Amalgamated TLP info word. */
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_WORD_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_WORD_LEN 4
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_MISC_WTAG_EN_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_MISC_WTAG_EN_LBN 0
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_MISC_WTAG_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_DL_EN_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_DL_EN_LBN 0
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_DL_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_TX_EN_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_TX_EN_LBN 1
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_TX_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_EV_EN_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_EV_EN_LBN 2
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_EV_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_RX_EN_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_RX_EN_LBN 3
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_RX_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_RXDMA_EN_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_RXDMA_EN_LBN 0
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_RXDMA_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_TXDMA_EN_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_TXDMA_EN_LBN 1
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_TXDMA_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_DL_EN_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_DL_EN_LBN 2
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_DL_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_MSIX_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_MSIX_LBN 0
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_MSIX_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_DL_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_DL_LBN 2
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_DL_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_TX_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_TX_LBN 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_TX_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_EV_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_EV_LBN 6
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_EV_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_RX_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_RX_LBN 8
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_RX_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_SPARE_OFST 4
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_SPARE_LBN 10
#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_SPARE_WIDTH 22
@@ -9463,6 +11430,7 @@
* Download a new set of images to the satellite CPUs from the host.
*/
#define MC_CMD_SATELLITE_DOWNLOAD 0x91
+#undef MC_CMD_0x91_PRIVILEGE_CTG
#define MC_CMD_0x91_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -9486,7 +11454,9 @@
*/
#define MC_CMD_SATELLITE_DOWNLOAD_IN_LENMIN 20
#define MC_CMD_SATELLITE_DOWNLOAD_IN_LENMAX 252
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_LENMAX_MCDI2 1020
#define MC_CMD_SATELLITE_DOWNLOAD_IN_LEN(num) (16+4*(num))
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_NUM(len) (((len)-16)/4)
/* Download phase. (Note: the IDLE phase is used internally and is never valid
* in a command from the host.)
*/
@@ -9551,6 +11521,7 @@
#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_LEN 4
#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_MINNUM 1
#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_MAXNUM 59
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_MAXNUM_MCDI2 251
/* MC_CMD_SATELLITE_DOWNLOAD_OUT msgresponse */
#define MC_CMD_SATELLITE_DOWNLOAD_OUT_LEN 8
@@ -9586,6 +11557,7 @@
* reference inherent device capabilities as opposed to current NVRAM config.
*/
#define MC_CMD_GET_CAPABILITIES 0xbe
+#undef MC_CMD_0xbe_PRIVILEGE_CTG
#define MC_CMD_0xbe_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -9597,62 +11569,91 @@
/* First word of flags. */
#define MC_CMD_GET_CAPABILITIES_OUT_FLAGS1_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_FLAGS1_LEN 4
+#define MC_CMD_GET_CAPABILITIES_OUT_VPORT_RECONFIGURE_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_VPORT_RECONFIGURE_LBN 3
#define MC_CMD_GET_CAPABILITIES_OUT_VPORT_RECONFIGURE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_STRIPING_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_TX_STRIPING_LBN 4
#define MC_CMD_GET_CAPABILITIES_OUT_TX_STRIPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_VADAPTOR_QUERY_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_VADAPTOR_QUERY_LBN 5
#define MC_CMD_GET_CAPABILITIES_OUT_VADAPTOR_QUERY_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_EVB_PORT_VLAN_RESTRICT_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6
#define MC_CMD_GET_CAPABILITIES_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_DRV_ATTACH_PREBOOT_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_DRV_ATTACH_PREBOOT_LBN 7
#define MC_CMD_GET_CAPABILITIES_OUT_DRV_ATTACH_PREBOOT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_FORCE_EVENT_MERGING_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_FORCE_EVENT_MERGING_LBN 8
#define MC_CMD_GET_CAPABILITIES_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_SET_MAC_ENHANCED_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_SET_MAC_ENHANCED_LBN 9
#define MC_CMD_GET_CAPABILITIES_OUT_SET_MAC_ENHANCED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10
#define MC_CMD_GET_CAPABILITIES_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11
#define MC_CMD_GET_CAPABILITIES_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MAC_SECURITY_FILTERING_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
#define MC_CMD_GET_CAPABILITIES_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_LBN 13
#define MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_QBB_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_QBB_LBN 14
#define MC_CMD_GET_CAPABILITIES_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_VAR_BUFFERS_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_LBN 16
#define MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_LBN 17
#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_LBN 18
#define MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_VLAN_INSERTION_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_TX_VLAN_INSERTION_LBN 19
#define MC_CMD_GET_CAPABILITIES_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_VLAN_STRIPPING_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_VLAN_STRIPPING_LBN 20
#define MC_CMD_GET_CAPABILITIES_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN 21
#define MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_0_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_0_LBN 22
#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_LBN 23
#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_TIMESTAMP_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_TIMESTAMP_LBN 24
#define MC_CMD_GET_CAPABILITIES_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN 25
#define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_LBN 26
#define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_LBN 27
#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER_LBN 28
#define MC_CMD_GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MCAST_UDP_LOOPBACK_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
#define MC_CMD_GET_CAPABILITIES_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_EVB_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_EVB_LBN 30
#define MC_CMD_GET_CAPABILITIES_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_OFST 0
#define MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN 31
#define MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_WIDTH 1
/* RxDPCPU firmware id. */
@@ -9713,8 +11714,10 @@
#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_CSR 0x103
#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_OFST 8
#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_REV_OFST 8
#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_REV_LBN 0
#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_TYPE_OFST 8
#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_TYPE_LBN 12
#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
/* enum: reserved value - do not use (may indicate alternative interpretation
@@ -9725,6 +11728,9 @@
* development only)
*/
#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
/* enum: RX PD firmware with approximately Siena-compatible behaviour
* (Huntington development only)
*/
@@ -9759,8 +11765,10 @@
#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_OFST 10
#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_REV_OFST 10
#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_REV_LBN 0
#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_TYPE_OFST 10
#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_TYPE_LBN 12
#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
/* enum: reserved value - do not use (may indicate alternative interpretation
@@ -9771,6 +11779,9 @@
* development only)
*/
#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
/* enum: TX PD firmware with approximately Siena-compatible behaviour
* (Huntington development only)
*/
@@ -9811,62 +11822,91 @@
/* First word of flags. */
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FLAGS1_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FLAGS1_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_VPORT_RECONFIGURE_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VPORT_RECONFIGURE_LBN 3
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VPORT_RECONFIGURE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_STRIPING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_STRIPING_LBN 4
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_STRIPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_VADAPTOR_QUERY_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VADAPTOR_QUERY_LBN 5
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VADAPTOR_QUERY_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVB_PORT_VLAN_RESTRICT_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_DRV_ATTACH_PREBOOT_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_DRV_ATTACH_PREBOOT_LBN 7
#define MC_CMD_GET_CAPABILITIES_V2_OUT_DRV_ATTACH_PREBOOT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_FORCE_EVENT_MERGING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_FORCE_EVENT_MERGING_LBN 8
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_SET_MAC_ENHANCED_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_SET_MAC_ENHANCED_LBN 9
#define MC_CMD_GET_CAPABILITIES_V2_OUT_SET_MAC_ENHANCED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10
#define MC_CMD_GET_CAPABILITIES_V2_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MAC_SECURITY_FILTERING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_ADDITIONAL_RSS_MODES_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_ADDITIONAL_RSS_MODES_LBN 13
#define MC_CMD_GET_CAPABILITIES_V2_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_QBB_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_QBB_LBN 14
#define MC_CMD_GET_CAPABILITIES_V2_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PACKED_STREAM_VAR_BUFFERS_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_RSS_LIMITED_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_RSS_LIMITED_LBN 16
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PACKED_STREAM_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PACKED_STREAM_LBN 17
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_INCLUDE_FCS_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_INCLUDE_FCS_LBN 18
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_VLAN_INSERTION_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_VLAN_INSERTION_LBN 19
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_VLAN_STRIPPING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_VLAN_STRIPPING_LBN 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_LBN 21
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PREFIX_LEN_0_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PREFIX_LEN_0_LBN 22
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PREFIX_LEN_14_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PREFIX_LEN_14_LBN 23
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_TIMESTAMP_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_TIMESTAMP_LBN 24
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_BATCHING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_BATCHING_LBN 25
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCAST_FILTER_CHAINING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCAST_FILTER_CHAINING_LBN 26
#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_PM_AND_RXDP_COUNTERS_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_PM_AND_RXDP_COUNTERS_LBN 27
#define MC_CMD_GET_CAPABILITIES_V2_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_DISABLE_SCATTER_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_DISABLE_SCATTER_LBN 28
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MCAST_UDP_LOOPBACK_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVB_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVB_LBN 30
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_VXLAN_NVGRE_OFST 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VXLAN_NVGRE_LBN 31
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VXLAN_NVGRE_WIDTH 1
/* RxDPCPU firmware id. */
@@ -9927,8 +11967,10 @@
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXDP_TEST_FW_CSR 0x103
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_OFST 8
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_REV_OFST 8
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_REV_LBN 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_TYPE_OFST 8
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_TYPE_LBN 12
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
/* enum: reserved value - do not use (may indicate alternative interpretation
@@ -9939,6 +11981,9 @@
* development only)
*/
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
/* enum: RX PD firmware with approximately Siena-compatible behaviour
* (Huntington development only)
*/
@@ -9973,8 +12018,10 @@
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_OFST 10
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_REV_OFST 10
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_REV_LBN 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_TYPE_OFST 10
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_TYPE_LBN 12
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
/* enum: reserved value - do not use (may indicate alternative interpretation
@@ -9985,6 +12032,9 @@
* development only)
*/
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
/* enum: TX PD firmware with approximately Siena-compatible behaviour
* (Huntington development only)
*/
@@ -10019,58 +12069,110 @@
/* Second word of flags. Not present on older firmware (check the length). */
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FLAGS2_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FLAGS2_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_LBN 0
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_ENCAP_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_ENCAP_LBN 1
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_ENCAP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVQ_TIMER_CTRL_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVQ_TIMER_CTRL_LBN 2
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVQ_TIMER_CTRL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVENT_CUT_THROUGH_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVENT_CUT_THROUGH_LBN 3
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EVENT_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_CUT_THROUGH_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_CUT_THROUGH_LBN 4
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_VFIFO_ULL_MODE_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_VFIFO_ULL_MODE_LBN 5
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_VFIFO_ULL_MODE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_MAC_STATS_40G_TX_SIZE_BINS_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN 6
#define MC_CMD_GET_CAPABILITIES_V2_OUT_MAC_STATS_40G_TX_SIZE_BINS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_TYPE_SUPPORTED_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_TYPE_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_TYPE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_V2_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_V2_LBN 7
#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MAC_TIMESTAMPING_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MAC_TIMESTAMPING_LBN 8
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_MAC_TIMESTAMPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TIMESTAMP_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TIMESTAMP_LBN 9
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_SNIFF_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_SNIFF_LBN 10
#define MC_CMD_GET_CAPABILITIES_V2_OUT_RX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_SNIFF_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_SNIFF_LBN 11
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12
#define MC_CMD_GET_CAPABILITIES_V2_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_BACKGROUND_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_BACKGROUND_LBN 13
#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_BACKGROUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_DB_RETURN_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_DB_RETURN_LBN 14
#define MC_CMD_GET_CAPABILITIES_V2_OUT_MCDI_DB_RETURN_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_CTPIO_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_CTPIO_LBN 15
#define MC_CMD_GET_CAPABILITIES_V2_OUT_CTPIO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_SUPPORT_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_SUPPORT_LBN 16
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_BOUND_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_BOUND_LBN 17
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TSA_BOUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_SF_ADAPTER_AUTHENTICATION_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
#define MC_CMD_GET_CAPABILITIES_V2_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_FLAG_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_FLAG_LBN 19
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_FLAG_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_MARK_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_MARK_LBN 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FILTER_ACTION_MARK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_EQUAL_STRIDE_SUPER_BUFFER_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_EQUAL_STRIDE_SUPER_BUFFER_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_EQUAL_STRIDE_SUPER_BUFFER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_EQUAL_STRIDE_PACKED_STREAM_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
#define MC_CMD_GET_CAPABILITIES_V2_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_L3XUDP_SUPPORT_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_L3XUDP_SUPPORT_LBN 22
#define MC_CMD_GET_CAPABILITIES_V2_OUT_L3XUDP_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_FW_SUBVARIANT_NO_TX_CSUM_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
#define MC_CMD_GET_CAPABILITIES_V2_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_VI_SPREADING_OFST 20
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VI_SPREADING_LBN 24
#define MC_CMD_GET_CAPABILITIES_V2_OUT_VI_SPREADING_WIDTH 1
-/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present
- * on older firmware (check the length).
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_HLB_IDLE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_HLB_IDLE_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_RXDP_HLB_IDLE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_RXQ_NO_CONT_EV_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_RXQ_NO_CONT_EV_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_RXQ_NO_CONT_EV_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_RXQ_WITH_BUFFER_SIZE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_RXQ_WITH_BUFFER_SIZE_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_RXQ_WITH_BUFFER_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_BUNDLE_UPDATE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_BUNDLE_UPDATE_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_BUNDLE_UPDATE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V3_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V3_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V3_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_DYNAMIC_SENSORS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_DYNAMIC_SENSORS_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_DYNAMIC_SENSORS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V2_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_WIDTH 1
+/* Number of FATSOv2 contexts per datapath supported by this NIC (when
+ * TX_TSO_V2 == 1). Not present on older firmware (check the length).
*/
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_N_CONTEXTS_OFST 24
#define MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_N_CONTEXTS_LEN 2
@@ -10130,62 +12232,91 @@
/* First word of flags. */
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FLAGS1_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FLAGS1_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_VPORT_RECONFIGURE_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VPORT_RECONFIGURE_LBN 3
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VPORT_RECONFIGURE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_STRIPING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_STRIPING_LBN 4
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_STRIPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_VADAPTOR_QUERY_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VADAPTOR_QUERY_LBN 5
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VADAPTOR_QUERY_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVB_PORT_VLAN_RESTRICT_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_DRV_ATTACH_PREBOOT_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_DRV_ATTACH_PREBOOT_LBN 7
#define MC_CMD_GET_CAPABILITIES_V3_OUT_DRV_ATTACH_PREBOOT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_FORCE_EVENT_MERGING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_FORCE_EVENT_MERGING_LBN 8
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_SET_MAC_ENHANCED_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_SET_MAC_ENHANCED_LBN 9
#define MC_CMD_GET_CAPABILITIES_V3_OUT_SET_MAC_ENHANCED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10
#define MC_CMD_GET_CAPABILITIES_V3_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_MAC_SECURITY_FILTERING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_ADDITIONAL_RSS_MODES_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_ADDITIONAL_RSS_MODES_LBN 13
#define MC_CMD_GET_CAPABILITIES_V3_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_QBB_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_QBB_LBN 14
#define MC_CMD_GET_CAPABILITIES_V3_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PACKED_STREAM_VAR_BUFFERS_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_RSS_LIMITED_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_RSS_LIMITED_LBN 16
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PACKED_STREAM_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PACKED_STREAM_LBN 17
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_INCLUDE_FCS_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_INCLUDE_FCS_LBN 18
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_VLAN_INSERTION_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_VLAN_INSERTION_LBN 19
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_VLAN_STRIPPING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_VLAN_STRIPPING_LBN 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_LBN 21
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PREFIX_LEN_0_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PREFIX_LEN_0_LBN 22
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PREFIX_LEN_14_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PREFIX_LEN_14_LBN 23
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_TIMESTAMP_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_TIMESTAMP_LBN 24
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_BATCHING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_BATCHING_LBN 25
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCAST_FILTER_CHAINING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCAST_FILTER_CHAINING_LBN 26
#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_PM_AND_RXDP_COUNTERS_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_PM_AND_RXDP_COUNTERS_LBN 27
#define MC_CMD_GET_CAPABILITIES_V3_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_DISABLE_SCATTER_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_DISABLE_SCATTER_LBN 28
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_MCAST_UDP_LOOPBACK_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVB_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVB_LBN 30
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_VXLAN_NVGRE_OFST 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VXLAN_NVGRE_LBN 31
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VXLAN_NVGRE_WIDTH 1
/* RxDPCPU firmware id. */
@@ -10246,8 +12377,10 @@
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXDP_TEST_FW_CSR 0x103
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_OFST 8
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_REV_OFST 8
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_REV_LBN 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_TYPE_OFST 8
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_TYPE_LBN 12
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
/* enum: reserved value - do not use (may indicate alternative interpretation
@@ -10258,6 +12391,9 @@
* development only)
*/
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
/* enum: RX PD firmware with approximately Siena-compatible behaviour
* (Huntington development only)
*/
@@ -10292,8 +12428,10 @@
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_OFST 10
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_REV_OFST 10
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_REV_LBN 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_TYPE_OFST 10
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_TYPE_LBN 12
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
/* enum: reserved value - do not use (may indicate alternative interpretation
@@ -10304,6 +12442,9 @@
* development only)
*/
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
/* enum: TX PD firmware with approximately Siena-compatible behaviour
* (Huntington development only)
*/
@@ -10338,58 +12479,110 @@
/* Second word of flags. Not present on older firmware (check the length). */
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FLAGS2_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FLAGS2_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_LBN 0
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_ENCAP_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_ENCAP_LBN 1
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_ENCAP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVQ_TIMER_CTRL_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVQ_TIMER_CTRL_LBN 2
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVQ_TIMER_CTRL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVENT_CUT_THROUGH_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVENT_CUT_THROUGH_LBN 3
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EVENT_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_CUT_THROUGH_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_CUT_THROUGH_LBN 4
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_VFIFO_ULL_MODE_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_VFIFO_ULL_MODE_LBN 5
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_VFIFO_ULL_MODE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_MAC_STATS_40G_TX_SIZE_BINS_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN 6
#define MC_CMD_GET_CAPABILITIES_V3_OUT_MAC_STATS_40G_TX_SIZE_BINS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_EVQ_TYPE_SUPPORTED_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_EVQ_TYPE_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_EVQ_TYPE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_EVQ_V2_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_EVQ_V2_LBN 7
#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_EVQ_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_MAC_TIMESTAMPING_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_MAC_TIMESTAMPING_LBN 8
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_MAC_TIMESTAMPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TIMESTAMP_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TIMESTAMP_LBN 9
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_SNIFF_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_SNIFF_LBN 10
#define MC_CMD_GET_CAPABILITIES_V3_OUT_RX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_SNIFF_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_SNIFF_LBN 11
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12
#define MC_CMD_GET_CAPABILITIES_V3_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_BACKGROUND_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_BACKGROUND_LBN 13
#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_BACKGROUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_DB_RETURN_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_DB_RETURN_LBN 14
#define MC_CMD_GET_CAPABILITIES_V3_OUT_MCDI_DB_RETURN_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_CTPIO_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_CTPIO_LBN 15
#define MC_CMD_GET_CAPABILITIES_V3_OUT_CTPIO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_SUPPORT_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_SUPPORT_LBN 16
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_BOUND_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_BOUND_LBN 17
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TSA_BOUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_SF_ADAPTER_AUTHENTICATION_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
#define MC_CMD_GET_CAPABILITIES_V3_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_FLAG_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_FLAG_LBN 19
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_FLAG_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_MARK_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_MARK_LBN 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FILTER_ACTION_MARK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_EQUAL_STRIDE_SUPER_BUFFER_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_EQUAL_STRIDE_SUPER_BUFFER_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_EQUAL_STRIDE_SUPER_BUFFER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_EQUAL_STRIDE_PACKED_STREAM_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
#define MC_CMD_GET_CAPABILITIES_V3_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_L3XUDP_SUPPORT_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_L3XUDP_SUPPORT_LBN 22
#define MC_CMD_GET_CAPABILITIES_V3_OUT_L3XUDP_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_FW_SUBVARIANT_NO_TX_CSUM_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
#define MC_CMD_GET_CAPABILITIES_V3_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_SPREADING_OFST 20
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_SPREADING_LBN 24
#define MC_CMD_GET_CAPABILITIES_V3_OUT_VI_SPREADING_WIDTH 1
-/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present
- * on older firmware (check the length).
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_HLB_IDLE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_HLB_IDLE_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_RXDP_HLB_IDLE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_RXQ_NO_CONT_EV_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_RXQ_NO_CONT_EV_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_RXQ_NO_CONT_EV_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_RXQ_WITH_BUFFER_SIZE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_RXQ_WITH_BUFFER_SIZE_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_INIT_RXQ_WITH_BUFFER_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_BUNDLE_UPDATE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_BUNDLE_UPDATE_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_BUNDLE_UPDATE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V3_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V3_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V3_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_DYNAMIC_SENSORS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_DYNAMIC_SENSORS_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_DYNAMIC_SENSORS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V3_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_WIDTH 1
+/* Number of FATSOv2 contexts per datapath supported by this NIC (when
+ * TX_TSO_V2 == 1). Not present on older firmware (check the length).
*/
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_N_CONTEXTS_OFST 24
#define MC_CMD_GET_CAPABILITIES_V3_OUT_TX_TSO_V2_N_CONTEXTS_LEN 2
@@ -10474,62 +12667,91 @@
/* First word of flags. */
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS1_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS1_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_VPORT_RECONFIGURE_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VPORT_RECONFIGURE_LBN 3
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VPORT_RECONFIGURE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_STRIPING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_STRIPING_LBN 4
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_STRIPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_QUERY_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_QUERY_LBN 5
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_QUERY_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_PORT_VLAN_RESTRICT_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_DRV_ATTACH_PREBOOT_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_DRV_ATTACH_PREBOOT_LBN 7
#define MC_CMD_GET_CAPABILITIES_V4_OUT_DRV_ATTACH_PREBOOT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_FORCE_EVENT_MERGING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_FORCE_EVENT_MERGING_LBN 8
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_SET_MAC_ENHANCED_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_SET_MAC_ENHANCED_LBN 9
#define MC_CMD_GET_CAPABILITIES_V4_OUT_SET_MAC_ENHANCED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10
#define MC_CMD_GET_CAPABILITIES_V4_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_SECURITY_FILTERING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_ADDITIONAL_RSS_MODES_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_ADDITIONAL_RSS_MODES_LBN 13
#define MC_CMD_GET_CAPABILITIES_V4_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_QBB_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_QBB_LBN 14
#define MC_CMD_GET_CAPABILITIES_V4_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_VAR_BUFFERS_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_RSS_LIMITED_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_RSS_LIMITED_LBN 16
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_LBN 17
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_INCLUDE_FCS_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_INCLUDE_FCS_LBN 18
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VLAN_INSERTION_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VLAN_INSERTION_LBN 19
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_VLAN_STRIPPING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_VLAN_STRIPPING_LBN 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_LBN 21
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_0_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_0_LBN 22
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_14_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_14_LBN 23
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_TIMESTAMP_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_TIMESTAMP_LBN 24
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_BATCHING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_BATCHING_LBN 25
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCAST_FILTER_CHAINING_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCAST_FILTER_CHAINING_LBN 26
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_PM_AND_RXDP_COUNTERS_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_PM_AND_RXDP_COUNTERS_LBN 27
#define MC_CMD_GET_CAPABILITIES_V4_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DISABLE_SCATTER_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DISABLE_SCATTER_LBN 28
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MCAST_UDP_LOOPBACK_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_LBN 30
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_VXLAN_NVGRE_OFST 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VXLAN_NVGRE_LBN 31
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VXLAN_NVGRE_WIDTH 1
/* RxDPCPU firmware id. */
@@ -10590,8 +12812,10 @@
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXDP_TEST_FW_CSR 0x103
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_OFST 8
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_REV_OFST 8
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_REV_LBN 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_TYPE_OFST 8
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_TYPE_LBN 12
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
/* enum: reserved value - do not use (may indicate alternative interpretation
@@ -10602,6 +12826,9 @@
* development only)
*/
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
/* enum: RX PD firmware with approximately Siena-compatible behaviour
* (Huntington development only)
*/
@@ -10636,8 +12863,10 @@
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_OFST 10
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_REV_OFST 10
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_REV_LBN 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_TYPE_OFST 10
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_TYPE_LBN 12
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
/* enum: reserved value - do not use (may indicate alternative interpretation
@@ -10648,6 +12877,9 @@
* development only)
*/
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
/* enum: TX PD firmware with approximately Siena-compatible behaviour
* (Huntington development only)
*/
@@ -10682,58 +12914,110 @@
/* Second word of flags. Not present on older firmware (check the length). */
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS2_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS2_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_LBN 0
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_ENCAP_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_ENCAP_LBN 1
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_ENCAP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVQ_TIMER_CTRL_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVQ_TIMER_CTRL_LBN 2
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVQ_TIMER_CTRL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVENT_CUT_THROUGH_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVENT_CUT_THROUGH_LBN 3
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EVENT_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_CUT_THROUGH_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_CUT_THROUGH_LBN 4
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VFIFO_ULL_MODE_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VFIFO_ULL_MODE_LBN 5
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_VFIFO_ULL_MODE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_40G_TX_SIZE_BINS_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN 6
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_40G_TX_SIZE_BINS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_EVQ_TYPE_SUPPORTED_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_EVQ_TYPE_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_EVQ_TYPE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_EVQ_V2_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_EVQ_V2_LBN 7
#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_EVQ_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_TIMESTAMPING_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_TIMESTAMPING_LBN 8
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_MAC_TIMESTAMPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TIMESTAMP_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TIMESTAMP_LBN 9
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_SNIFF_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_SNIFF_LBN 10
#define MC_CMD_GET_CAPABILITIES_V4_OUT_RX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_SNIFF_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_SNIFF_LBN 11
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12
#define MC_CMD_GET_CAPABILITIES_V4_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_BACKGROUND_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_BACKGROUND_LBN 13
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_BACKGROUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_DB_RETURN_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_DB_RETURN_LBN 14
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MCDI_DB_RETURN_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_CTPIO_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_CTPIO_LBN 15
#define MC_CMD_GET_CAPABILITIES_V4_OUT_CTPIO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_SUPPORT_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_SUPPORT_LBN 16
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_BOUND_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_BOUND_LBN 17
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TSA_BOUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_SF_ADAPTER_AUTHENTICATION_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
#define MC_CMD_GET_CAPABILITIES_V4_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_FLAG_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_FLAG_LBN 19
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_FLAG_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_MARK_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_MARK_LBN 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FILTER_ACTION_MARK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_EQUAL_STRIDE_SUPER_BUFFER_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_EQUAL_STRIDE_SUPER_BUFFER_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_EQUAL_STRIDE_SUPER_BUFFER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_EQUAL_STRIDE_PACKED_STREAM_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
#define MC_CMD_GET_CAPABILITIES_V4_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_L3XUDP_SUPPORT_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_L3XUDP_SUPPORT_LBN 22
#define MC_CMD_GET_CAPABILITIES_V4_OUT_L3XUDP_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_FW_SUBVARIANT_NO_TX_CSUM_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
#define MC_CMD_GET_CAPABILITIES_V4_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_SPREADING_OFST 20
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_SPREADING_LBN 24
#define MC_CMD_GET_CAPABILITIES_V4_OUT_VI_SPREADING_WIDTH 1
-/* Number of FATSOv2 contexts per datapath supported by this NIC. Not present
- * on older firmware (check the length).
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_HLB_IDLE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_HLB_IDLE_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_RXDP_HLB_IDLE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_RXQ_NO_CONT_EV_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_RXQ_NO_CONT_EV_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_RXQ_NO_CONT_EV_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_RXQ_WITH_BUFFER_SIZE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_RXQ_WITH_BUFFER_SIZE_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_INIT_RXQ_WITH_BUFFER_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_BUNDLE_UPDATE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_BUNDLE_UPDATE_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_BUNDLE_UPDATE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V3_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V3_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V3_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_DYNAMIC_SENSORS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_DYNAMIC_SENSORS_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_DYNAMIC_SENSORS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V4_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_WIDTH 1
+/* Number of FATSOv2 contexts per datapath supported by this NIC (when
+ * TX_TSO_V2 == 1). Not present on older firmware (check the length).
*/
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_N_CONTEXTS_OFST 24
#define MC_CMD_GET_CAPABILITIES_V4_OUT_TX_TSO_V2_N_CONTEXTS_LEN 2
@@ -10821,6 +13105,2422 @@
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS_OFST 76
#define MC_CMD_GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS_LEN 2
+/* MC_CMD_GET_CAPABILITIES_V5_OUT msgresponse */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_LEN 84
+/* First word of flags. */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FLAGS1_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FLAGS1_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VPORT_RECONFIGURE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VPORT_RECONFIGURE_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VPORT_RECONFIGURE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_STRIPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_STRIPING_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_STRIPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VADAPTOR_QUERY_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VADAPTOR_QUERY_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VADAPTOR_QUERY_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVB_PORT_VLAN_RESTRICT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_DRV_ATTACH_PREBOOT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_DRV_ATTACH_PREBOOT_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_DRV_ATTACH_PREBOOT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_FORCE_EVENT_MERGING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_FORCE_EVENT_MERGING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_SET_MAC_ENHANCED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_SET_MAC_ENHANCED_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_SET_MAC_ENHANCED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_MAC_SECURITY_FILTERING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_ADDITIONAL_RSS_MODES_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_ADDITIONAL_RSS_MODES_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_QBB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_QBB_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PACKED_STREAM_VAR_BUFFERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_RSS_LIMITED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_RSS_LIMITED_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PACKED_STREAM_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PACKED_STREAM_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_INCLUDE_FCS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_INCLUDE_FCS_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_VLAN_INSERTION_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_VLAN_INSERTION_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_VLAN_STRIPPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_VLAN_STRIPPING_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PREFIX_LEN_0_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PREFIX_LEN_0_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PREFIX_LEN_14_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PREFIX_LEN_14_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_TIMESTAMP_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_TIMESTAMP_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_BATCHING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_BATCHING_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MCAST_FILTER_CHAINING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MCAST_FILTER_CHAINING_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_PM_AND_RXDP_COUNTERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_PM_AND_RXDP_COUNTERS_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_DISABLE_SCATTER_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_DISABLE_SCATTER_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_MCAST_UDP_LOOPBACK_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVB_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VXLAN_NVGRE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VXLAN_NVGRE_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VXLAN_NVGRE_WIDTH 1
+/* RxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_DPCPU_FW_ID_OFST 4
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_DPCPU_FW_ID_LEN 2
+/* enum: Standard RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP 0x0
+/* enum: Low latency RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_LOW_LATENCY 0x1
+/* enum: Packed stream RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_PACKED_STREAM 0x2
+/* enum: Rules engine RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_RULES_ENGINE 0x5
+/* enum: DPDK RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_DPDK 0x6
+/* enum: BIST RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_BIST 0x10a
+/* enum: RXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
+/* enum: RXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
+/* enum: RXDP Test firmware image 3 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
+/* enum: RXDP Test firmware image 4 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
+/* enum: RXDP Test firmware image 5 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_BACKPRESSURE 0x105
+/* enum: RXDP Test firmware image 6 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
+/* enum: RXDP Test firmware image 7 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
+/* enum: RXDP Test firmware image 8 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
+/* enum: RXDP Test firmware image 9 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b
+/* enum: RXDP Test firmware image 10 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_TEST_FW_SLOW 0x10c
+/* TxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_DPCPU_FW_ID_OFST 6
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_DPCPU_FW_ID_LEN 2
+/* enum: Standard TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXDP 0x0
+/* enum: Low latency TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXDP_LOW_LATENCY 0x1
+/* enum: High packet rate TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXDP_HIGH_PACKET_RATE 0x3
+/* enum: Rules engine TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXDP_RULES_ENGINE 0x5
+/* enum: DPDK TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXDP_DPDK 0x6
+/* enum: BIST TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXDP_BIST 0x12d
+/* enum: TXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
+/* enum: TXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
+/* enum: TXDP CSR bus test firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXDP_TEST_FW_CSR 0x103
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_VERSION_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_VERSION_REV_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_VERSION_TYPE_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial RX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: RX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant RX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+/* enum: Low latency RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
+/* enum: Packed stream RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
+/* enum: RX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* enum: RX PD firmware parsing but not filtering network overlay tunnel
+ * encapsulations (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_VERSION_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_VERSION_REV_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_VERSION_TYPE_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial TX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: TX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant TX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
+/* enum: TX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* Hardware capabilities of NIC */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_HW_CAPABILITIES_OFST 12
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_HW_CAPABILITIES_LEN 4
+/* Licensed capabilities */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_LICENSE_CAPABILITIES_OFST 16
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_LICENSE_CAPABILITIES_LEN 4
+/* Second word of flags. Not present on older firmware (check the length). */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FLAGS2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FLAGS2_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V2_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V2_ENCAP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V2_ENCAP_LBN 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V2_ENCAP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVQ_TIMER_CTRL_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVQ_TIMER_CTRL_LBN 2
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVQ_TIMER_CTRL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVENT_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVENT_CUT_THROUGH_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EVENT_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_CUT_THROUGH_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_VFIFO_ULL_MODE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_VFIFO_ULL_MODE_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_VFIFO_ULL_MODE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MAC_STATS_40G_TX_SIZE_BINS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MAC_STATS_40G_TX_SIZE_BINS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_EVQ_TYPE_SUPPORTED_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_EVQ_TYPE_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_EVQ_TYPE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_EVQ_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_EVQ_V2_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_EVQ_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_MAC_TIMESTAMPING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_MAC_TIMESTAMPING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_MAC_TIMESTAMPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TIMESTAMP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TIMESTAMP_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_SNIFF_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_SNIFF_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MCDI_BACKGROUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MCDI_BACKGROUND_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MCDI_BACKGROUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MCDI_DB_RETURN_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MCDI_DB_RETURN_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MCDI_DB_RETURN_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_CTPIO_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_CTPIO_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_CTPIO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TSA_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TSA_SUPPORT_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TSA_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TSA_BOUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TSA_BOUND_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TSA_BOUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_SF_ADAPTER_AUTHENTICATION_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FILTER_ACTION_FLAG_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FILTER_ACTION_FLAG_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FILTER_ACTION_FLAG_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EQUAL_STRIDE_SUPER_BUFFER_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EQUAL_STRIDE_SUPER_BUFFER_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EQUAL_STRIDE_SUPER_BUFFER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EQUAL_STRIDE_PACKED_STREAM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_L3XUDP_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_L3XUDP_SUPPORT_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_L3XUDP_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FW_SUBVARIANT_NO_TX_CSUM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VI_SPREADING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VI_SPREADING_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VI_SPREADING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_HLB_IDLE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_HLB_IDLE_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RXDP_HLB_IDLE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_RXQ_NO_CONT_EV_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_RXQ_NO_CONT_EV_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_RXQ_NO_CONT_EV_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_RXQ_WITH_BUFFER_SIZE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_RXQ_WITH_BUFFER_SIZE_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INIT_RXQ_WITH_BUFFER_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_BUNDLE_UPDATE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_BUNDLE_UPDATE_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_BUNDLE_UPDATE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V3_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V3_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V3_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_DYNAMIC_SENSORS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_DYNAMIC_SENSORS_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_DYNAMIC_SENSORS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_WIDTH 1
+/* Number of FATSOv2 contexts per datapath supported by this NIC (when
+ * TX_TSO_V2 == 1). Not present on older firmware (check the length).
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V2_N_CONTEXTS_OFST 24
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_TSO_V2_N_CONTEXTS_LEN 2
+/* One byte per PF containing the number of the external port assigned to this
+ * PF, indexed by PF number. Special values indicate that a PF is either not
+ * present or not assigned.
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_PFS_TO_PORTS_ASSIGNMENT_OFST 26
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_ACCESS_NOT_PERMITTED 0xff
+/* enum: PF does not exist. */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_PF_NOT_PRESENT 0xfe
+/* enum: PF does exist but is not assigned to any external port. */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_PF_NOT_ASSIGNED 0xfd
+/* enum: This value indicates that PF is assigned, but it cannot be expressed
+ * in this field. It is intended for a possible future situation where a more
+ * complex scheme of PFs to ports mapping is being used. The future driver
+ * should look for a new field supporting the new scheme. The current/old
+ * driver should treat this value as PF_NOT_ASSIGNED.
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc
+/* One byte per PF containing the number of its VFs, indexed by PF number. A
+ * special value indicates that a PF is not present.
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NUM_VFS_PER_PF_OFST 42
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NUM_VFS_PER_PF_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NUM_VFS_PER_PF_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+/* MC_CMD_GET_CAPABILITIES_V5_OUT_ACCESS_NOT_PERMITTED 0xff */
+/* enum: PF does not exist. */
+/* MC_CMD_GET_CAPABILITIES_V5_OUT_PF_NOT_PRESENT 0xfe */
+/* Number of VIs available for each external port */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NUM_VIS_PER_PORT_OFST 58
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NUM_VIS_PER_PORT_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NUM_VIS_PER_PORT_NUM 4
+/* Size of RX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ RX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_DESC_CACHE_SIZE_OFST 66
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_RX_DESC_CACHE_SIZE_LEN 1
+/* Size of TX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ TX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_DESC_CACHE_SIZE_OFST 67
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_TX_DESC_CACHE_SIZE_LEN 1
+/* Total number of available PIO buffers */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NUM_PIO_BUFFS_OFST 68
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_NUM_PIO_BUFFS_LEN 2
+/* Size of a single PIO buffer */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_SIZE_PIO_BUFF_OFST 70
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_SIZE_PIO_BUFF_LEN 2
+/* On chips later than Medford the amount of address space assigned to each VI
+ * is configurable. This is a global setting that the driver must query to
+ * discover the VI to address mapping. Cut-through PIO (CTPIO) is not available
+ * with 8k VI windows.
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VI_WINDOW_MODE_OFST 72
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VI_WINDOW_MODE_LEN 1
+/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k.
+ * CTPIO is not mapped.
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VI_WINDOW_MODE_8K 0x0
+/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VI_WINDOW_MODE_16K 0x1
+/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VI_WINDOW_MODE_64K 0x2
+/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VFIFO_STUFFING_NUM_VFIFOS_OFST 73
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VFIFO_STUFFING_NUM_VFIFOS_LEN 1
+/* Number of buffers per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_OFST 74
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_LEN 2
+/* Entry count in the MAC stats array, including the final GENERATION_END
+ * entry. For MAC stats DMA, drivers should allocate a buffer large enough to
+ * hold at least this many 64-bit stats values, if they wish to receive all
+ * available stats. If the buffer is shorter than MAC_STATS_NUM_STATS * 8, the
+ * stats array returned will be truncated.
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MAC_STATS_NUM_STATS_OFST 76
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_MAC_STATS_NUM_STATS_LEN 2
+/* Maximum supported value for MC_CMD_FILTER_OP_V3/MATCH_MARK_VALUE. This field
+ * will only be non-zero if MC_CMD_GET_CAPABILITIES/FILTER_ACTION_MARK is set.
+ */
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_MAX_OFST 80
+#define MC_CMD_GET_CAPABILITIES_V5_OUT_FILTER_ACTION_MARK_MAX_LEN 4
+
+/* MC_CMD_GET_CAPABILITIES_V6_OUT msgresponse */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_LEN 148
+/* First word of flags. */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FLAGS1_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FLAGS1_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VPORT_RECONFIGURE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VPORT_RECONFIGURE_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VPORT_RECONFIGURE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_STRIPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_STRIPING_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_STRIPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VADAPTOR_QUERY_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VADAPTOR_QUERY_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VADAPTOR_QUERY_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVB_PORT_VLAN_RESTRICT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_DRV_ATTACH_PREBOOT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_DRV_ATTACH_PREBOOT_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_DRV_ATTACH_PREBOOT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_FORCE_EVENT_MERGING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_FORCE_EVENT_MERGING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_SET_MAC_ENHANCED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_SET_MAC_ENHANCED_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_SET_MAC_ENHANCED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_MAC_SECURITY_FILTERING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_ADDITIONAL_RSS_MODES_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_ADDITIONAL_RSS_MODES_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_QBB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_QBB_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PACKED_STREAM_VAR_BUFFERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_RSS_LIMITED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_RSS_LIMITED_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PACKED_STREAM_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PACKED_STREAM_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_INCLUDE_FCS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_INCLUDE_FCS_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_VLAN_INSERTION_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_VLAN_INSERTION_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_VLAN_STRIPPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_VLAN_STRIPPING_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PREFIX_LEN_0_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PREFIX_LEN_0_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PREFIX_LEN_14_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PREFIX_LEN_14_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_TIMESTAMP_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_TIMESTAMP_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_BATCHING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_BATCHING_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MCAST_FILTER_CHAINING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MCAST_FILTER_CHAINING_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_PM_AND_RXDP_COUNTERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_PM_AND_RXDP_COUNTERS_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_DISABLE_SCATTER_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_DISABLE_SCATTER_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_MCAST_UDP_LOOPBACK_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVB_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VXLAN_NVGRE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VXLAN_NVGRE_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VXLAN_NVGRE_WIDTH 1
+/* RxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_DPCPU_FW_ID_OFST 4
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_DPCPU_FW_ID_LEN 2
+/* enum: Standard RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP 0x0
+/* enum: Low latency RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_LOW_LATENCY 0x1
+/* enum: Packed stream RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_PACKED_STREAM 0x2
+/* enum: Rules engine RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_RULES_ENGINE 0x5
+/* enum: DPDK RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_DPDK 0x6
+/* enum: BIST RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_BIST 0x10a
+/* enum: RXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
+/* enum: RXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
+/* enum: RXDP Test firmware image 3 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
+/* enum: RXDP Test firmware image 4 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
+/* enum: RXDP Test firmware image 5 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_BACKPRESSURE 0x105
+/* enum: RXDP Test firmware image 6 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
+/* enum: RXDP Test firmware image 7 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
+/* enum: RXDP Test firmware image 8 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
+/* enum: RXDP Test firmware image 9 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b
+/* enum: RXDP Test firmware image 10 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_TEST_FW_SLOW 0x10c
+/* TxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_DPCPU_FW_ID_OFST 6
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_DPCPU_FW_ID_LEN 2
+/* enum: Standard TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXDP 0x0
+/* enum: Low latency TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXDP_LOW_LATENCY 0x1
+/* enum: High packet rate TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXDP_HIGH_PACKET_RATE 0x3
+/* enum: Rules engine TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXDP_RULES_ENGINE 0x5
+/* enum: DPDK TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXDP_DPDK 0x6
+/* enum: BIST TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXDP_BIST 0x12d
+/* enum: TXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
+/* enum: TXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
+/* enum: TXDP CSR bus test firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXDP_TEST_FW_CSR 0x103
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_VERSION_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_VERSION_REV_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_VERSION_TYPE_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial RX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: RX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant RX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+/* enum: Low latency RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
+/* enum: Packed stream RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
+/* enum: RX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* enum: RX PD firmware parsing but not filtering network overlay tunnel
+ * encapsulations (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_VERSION_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_VERSION_REV_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_VERSION_TYPE_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial TX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: TX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant TX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
+/* enum: TX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* Hardware capabilities of NIC */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_HW_CAPABILITIES_OFST 12
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_HW_CAPABILITIES_LEN 4
+/* Licensed capabilities */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_LICENSE_CAPABILITIES_OFST 16
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_LICENSE_CAPABILITIES_LEN 4
+/* Second word of flags. Not present on older firmware (check the length). */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FLAGS2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FLAGS2_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V2_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V2_ENCAP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V2_ENCAP_LBN 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V2_ENCAP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVQ_TIMER_CTRL_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVQ_TIMER_CTRL_LBN 2
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVQ_TIMER_CTRL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVENT_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVENT_CUT_THROUGH_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EVENT_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_CUT_THROUGH_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_VFIFO_ULL_MODE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_VFIFO_ULL_MODE_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_VFIFO_ULL_MODE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MAC_STATS_40G_TX_SIZE_BINS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MAC_STATS_40G_TX_SIZE_BINS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_EVQ_TYPE_SUPPORTED_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_EVQ_TYPE_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_EVQ_TYPE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_EVQ_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_EVQ_V2_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_EVQ_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_MAC_TIMESTAMPING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_MAC_TIMESTAMPING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_MAC_TIMESTAMPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TIMESTAMP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TIMESTAMP_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_SNIFF_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_SNIFF_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MCDI_BACKGROUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MCDI_BACKGROUND_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MCDI_BACKGROUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MCDI_DB_RETURN_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MCDI_DB_RETURN_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MCDI_DB_RETURN_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_CTPIO_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_CTPIO_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_CTPIO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TSA_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TSA_SUPPORT_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TSA_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TSA_BOUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TSA_BOUND_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TSA_BOUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_SF_ADAPTER_AUTHENTICATION_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FILTER_ACTION_FLAG_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FILTER_ACTION_FLAG_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FILTER_ACTION_FLAG_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FILTER_ACTION_MARK_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FILTER_ACTION_MARK_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FILTER_ACTION_MARK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EQUAL_STRIDE_SUPER_BUFFER_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EQUAL_STRIDE_SUPER_BUFFER_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EQUAL_STRIDE_SUPER_BUFFER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EQUAL_STRIDE_PACKED_STREAM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_L3XUDP_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_L3XUDP_SUPPORT_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_L3XUDP_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FW_SUBVARIANT_NO_TX_CSUM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VI_SPREADING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VI_SPREADING_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VI_SPREADING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_HLB_IDLE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_HLB_IDLE_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RXDP_HLB_IDLE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_RXQ_NO_CONT_EV_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_RXQ_NO_CONT_EV_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_RXQ_NO_CONT_EV_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_RXQ_WITH_BUFFER_SIZE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_RXQ_WITH_BUFFER_SIZE_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INIT_RXQ_WITH_BUFFER_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_BUNDLE_UPDATE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_BUNDLE_UPDATE_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_BUNDLE_UPDATE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V3_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V3_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V3_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_DYNAMIC_SENSORS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_DYNAMIC_SENSORS_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_DYNAMIC_SENSORS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_WIDTH 1
+/* Number of FATSOv2 contexts per datapath supported by this NIC (when
+ * TX_TSO_V2 == 1). Not present on older firmware (check the length).
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V2_N_CONTEXTS_OFST 24
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_TSO_V2_N_CONTEXTS_LEN 2
+/* One byte per PF containing the number of the external port assigned to this
+ * PF, indexed by PF number. Special values indicate that a PF is either not
+ * present or not assigned.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_PFS_TO_PORTS_ASSIGNMENT_OFST 26
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_ACCESS_NOT_PERMITTED 0xff
+/* enum: PF does not exist. */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_PF_NOT_PRESENT 0xfe
+/* enum: PF does exist but is not assigned to any external port. */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_PF_NOT_ASSIGNED 0xfd
+/* enum: This value indicates that PF is assigned, but it cannot be expressed
+ * in this field. It is intended for a possible future situation where a more
+ * complex scheme of PFs to ports mapping is being used. The future driver
+ * should look for a new field supporting the new scheme. The current/old
+ * driver should treat this value as PF_NOT_ASSIGNED.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc
+/* One byte per PF containing the number of its VFs, indexed by PF number. A
+ * special value indicates that a PF is not present.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NUM_VFS_PER_PF_OFST 42
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NUM_VFS_PER_PF_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NUM_VFS_PER_PF_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+/* MC_CMD_GET_CAPABILITIES_V6_OUT_ACCESS_NOT_PERMITTED 0xff */
+/* enum: PF does not exist. */
+/* MC_CMD_GET_CAPABILITIES_V6_OUT_PF_NOT_PRESENT 0xfe */
+/* Number of VIs available for each external port */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NUM_VIS_PER_PORT_OFST 58
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NUM_VIS_PER_PORT_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NUM_VIS_PER_PORT_NUM 4
+/* Size of RX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ RX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_DESC_CACHE_SIZE_OFST 66
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_RX_DESC_CACHE_SIZE_LEN 1
+/* Size of TX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ TX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_DESC_CACHE_SIZE_OFST 67
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_TX_DESC_CACHE_SIZE_LEN 1
+/* Total number of available PIO buffers */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NUM_PIO_BUFFS_OFST 68
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_NUM_PIO_BUFFS_LEN 2
+/* Size of a single PIO buffer */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_SIZE_PIO_BUFF_OFST 70
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_SIZE_PIO_BUFF_LEN 2
+/* On chips later than Medford the amount of address space assigned to each VI
+ * is configurable. This is a global setting that the driver must query to
+ * discover the VI to address mapping. Cut-through PIO (CTPIO) is not available
+ * with 8k VI windows.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VI_WINDOW_MODE_OFST 72
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VI_WINDOW_MODE_LEN 1
+/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k.
+ * CTPIO is not mapped.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VI_WINDOW_MODE_8K 0x0
+/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VI_WINDOW_MODE_16K 0x1
+/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VI_WINDOW_MODE_64K 0x2
+/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VFIFO_STUFFING_NUM_VFIFOS_OFST 73
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VFIFO_STUFFING_NUM_VFIFOS_LEN 1
+/* Number of buffers per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_OFST 74
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_LEN 2
+/* Entry count in the MAC stats array, including the final GENERATION_END
+ * entry. For MAC stats DMA, drivers should allocate a buffer large enough to
+ * hold at least this many 64-bit stats values, if they wish to receive all
+ * available stats. If the buffer is shorter than MAC_STATS_NUM_STATS * 8, the
+ * stats array returned will be truncated.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MAC_STATS_NUM_STATS_OFST 76
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_MAC_STATS_NUM_STATS_LEN 2
+/* Maximum supported value for MC_CMD_FILTER_OP_V3/MATCH_MARK_VALUE. This field
+ * will only be non-zero if MC_CMD_GET_CAPABILITIES/FILTER_ACTION_MARK is set.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FILTER_ACTION_MARK_MAX_OFST 80
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_FILTER_ACTION_MARK_MAX_LEN 4
+/* On devices where the INIT_RXQ_WITH_BUFFER_SIZE flag (in
+ * GET_CAPABILITIES_OUT_V2) is set, drivers have to specify a buffer size when
+ * they create an RX queue. Due to hardware limitations, only a small number of
+ * different buffer sizes may be available concurrently. Nonzero entries in
+ * this array are the sizes of buffers which the system guarantees will be
+ * available for use. If the list is empty, there are no limitations on
+ * concurrent buffer sizes.
+ */
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_GUARANTEED_RX_BUFFER_SIZES_OFST 84
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_GUARANTEED_RX_BUFFER_SIZES_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V6_OUT_GUARANTEED_RX_BUFFER_SIZES_NUM 16
+
+/* MC_CMD_GET_CAPABILITIES_V7_OUT msgresponse */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_LEN 152
+/* First word of flags. */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FLAGS1_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FLAGS1_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VPORT_RECONFIGURE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VPORT_RECONFIGURE_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VPORT_RECONFIGURE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_STRIPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_STRIPING_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_STRIPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VADAPTOR_QUERY_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VADAPTOR_QUERY_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VADAPTOR_QUERY_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVB_PORT_VLAN_RESTRICT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_DRV_ATTACH_PREBOOT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_DRV_ATTACH_PREBOOT_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_DRV_ATTACH_PREBOOT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_FORCE_EVENT_MERGING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_FORCE_EVENT_MERGING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_SET_MAC_ENHANCED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_SET_MAC_ENHANCED_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_SET_MAC_ENHANCED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_MAC_SECURITY_FILTERING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_ADDITIONAL_RSS_MODES_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_ADDITIONAL_RSS_MODES_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_QBB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_QBB_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PACKED_STREAM_VAR_BUFFERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_RSS_LIMITED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_RSS_LIMITED_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PACKED_STREAM_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PACKED_STREAM_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_INCLUDE_FCS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_INCLUDE_FCS_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_VLAN_INSERTION_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_VLAN_INSERTION_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_VLAN_STRIPPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_VLAN_STRIPPING_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PREFIX_LEN_0_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PREFIX_LEN_0_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PREFIX_LEN_14_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PREFIX_LEN_14_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_TIMESTAMP_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_TIMESTAMP_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_BATCHING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_BATCHING_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MCAST_FILTER_CHAINING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MCAST_FILTER_CHAINING_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_PM_AND_RXDP_COUNTERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_PM_AND_RXDP_COUNTERS_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_DISABLE_SCATTER_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_DISABLE_SCATTER_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_MCAST_UDP_LOOPBACK_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVB_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VXLAN_NVGRE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VXLAN_NVGRE_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VXLAN_NVGRE_WIDTH 1
+/* RxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_DPCPU_FW_ID_OFST 4
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_DPCPU_FW_ID_LEN 2
+/* enum: Standard RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP 0x0
+/* enum: Low latency RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_LOW_LATENCY 0x1
+/* enum: Packed stream RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_PACKED_STREAM 0x2
+/* enum: Rules engine RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_RULES_ENGINE 0x5
+/* enum: DPDK RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_DPDK 0x6
+/* enum: BIST RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_BIST 0x10a
+/* enum: RXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
+/* enum: RXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
+/* enum: RXDP Test firmware image 3 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
+/* enum: RXDP Test firmware image 4 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
+/* enum: RXDP Test firmware image 5 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_BACKPRESSURE 0x105
+/* enum: RXDP Test firmware image 6 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
+/* enum: RXDP Test firmware image 7 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
+/* enum: RXDP Test firmware image 8 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
+/* enum: RXDP Test firmware image 9 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b
+/* enum: RXDP Test firmware image 10 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_TEST_FW_SLOW 0x10c
+/* TxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_DPCPU_FW_ID_OFST 6
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_DPCPU_FW_ID_LEN 2
+/* enum: Standard TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXDP 0x0
+/* enum: Low latency TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXDP_LOW_LATENCY 0x1
+/* enum: High packet rate TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXDP_HIGH_PACKET_RATE 0x3
+/* enum: Rules engine TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXDP_RULES_ENGINE 0x5
+/* enum: DPDK TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXDP_DPDK 0x6
+/* enum: BIST TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXDP_BIST 0x12d
+/* enum: TXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
+/* enum: TXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
+/* enum: TXDP CSR bus test firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXDP_TEST_FW_CSR 0x103
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_VERSION_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_VERSION_REV_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_VERSION_TYPE_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial RX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: RX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant RX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+/* enum: Low latency RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
+/* enum: Packed stream RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
+/* enum: RX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* enum: RX PD firmware parsing but not filtering network overlay tunnel
+ * encapsulations (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_VERSION_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_VERSION_REV_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_VERSION_TYPE_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial TX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: TX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant TX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
+/* enum: TX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* Hardware capabilities of NIC */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_HW_CAPABILITIES_OFST 12
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_HW_CAPABILITIES_LEN 4
+/* Licensed capabilities */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_LICENSE_CAPABILITIES_OFST 16
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_LICENSE_CAPABILITIES_LEN 4
+/* Second word of flags. Not present on older firmware (check the length). */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FLAGS2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FLAGS2_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V2_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V2_ENCAP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V2_ENCAP_LBN 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V2_ENCAP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVQ_TIMER_CTRL_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVQ_TIMER_CTRL_LBN 2
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVQ_TIMER_CTRL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVENT_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVENT_CUT_THROUGH_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EVENT_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_CUT_THROUGH_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_VFIFO_ULL_MODE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_VFIFO_ULL_MODE_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_VFIFO_ULL_MODE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MAC_STATS_40G_TX_SIZE_BINS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MAC_STATS_40G_TX_SIZE_BINS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_EVQ_TYPE_SUPPORTED_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_EVQ_TYPE_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_EVQ_TYPE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_EVQ_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_EVQ_V2_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_EVQ_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_MAC_TIMESTAMPING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_MAC_TIMESTAMPING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_MAC_TIMESTAMPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TIMESTAMP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TIMESTAMP_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_SNIFF_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_SNIFF_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MCDI_BACKGROUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MCDI_BACKGROUND_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MCDI_BACKGROUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MCDI_DB_RETURN_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MCDI_DB_RETURN_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MCDI_DB_RETURN_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_CTPIO_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_CTPIO_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_CTPIO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TSA_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TSA_SUPPORT_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TSA_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TSA_BOUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TSA_BOUND_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TSA_BOUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_SF_ADAPTER_AUTHENTICATION_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FILTER_ACTION_FLAG_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FILTER_ACTION_FLAG_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FILTER_ACTION_FLAG_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FILTER_ACTION_MARK_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FILTER_ACTION_MARK_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FILTER_ACTION_MARK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EQUAL_STRIDE_SUPER_BUFFER_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EQUAL_STRIDE_SUPER_BUFFER_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EQUAL_STRIDE_SUPER_BUFFER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EQUAL_STRIDE_PACKED_STREAM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_L3XUDP_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_L3XUDP_SUPPORT_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_L3XUDP_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FW_SUBVARIANT_NO_TX_CSUM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VI_SPREADING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VI_SPREADING_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VI_SPREADING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_HLB_IDLE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_HLB_IDLE_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RXDP_HLB_IDLE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_RXQ_NO_CONT_EV_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_RXQ_NO_CONT_EV_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_RXQ_NO_CONT_EV_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_RXQ_WITH_BUFFER_SIZE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_RXQ_WITH_BUFFER_SIZE_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INIT_RXQ_WITH_BUFFER_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_BUNDLE_UPDATE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_BUNDLE_UPDATE_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_BUNDLE_UPDATE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V3_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V3_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V3_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_DYNAMIC_SENSORS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_DYNAMIC_SENSORS_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_DYNAMIC_SENSORS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_WIDTH 1
+/* Number of FATSOv2 contexts per datapath supported by this NIC (when
+ * TX_TSO_V2 == 1). Not present on older firmware (check the length).
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V2_N_CONTEXTS_OFST 24
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_TSO_V2_N_CONTEXTS_LEN 2
+/* One byte per PF containing the number of the external port assigned to this
+ * PF, indexed by PF number. Special values indicate that a PF is either not
+ * present or not assigned.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_PFS_TO_PORTS_ASSIGNMENT_OFST 26
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_ACCESS_NOT_PERMITTED 0xff
+/* enum: PF does not exist. */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_PF_NOT_PRESENT 0xfe
+/* enum: PF does exist but is not assigned to any external port. */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_PF_NOT_ASSIGNED 0xfd
+/* enum: This value indicates that PF is assigned, but it cannot be expressed
+ * in this field. It is intended for a possible future situation where a more
+ * complex scheme of PFs to ports mapping is being used. The future driver
+ * should look for a new field supporting the new scheme. The current/old
+ * driver should treat this value as PF_NOT_ASSIGNED.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc
+/* One byte per PF containing the number of its VFs, indexed by PF number. A
+ * special value indicates that a PF is not present.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NUM_VFS_PER_PF_OFST 42
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NUM_VFS_PER_PF_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NUM_VFS_PER_PF_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+/* MC_CMD_GET_CAPABILITIES_V7_OUT_ACCESS_NOT_PERMITTED 0xff */
+/* enum: PF does not exist. */
+/* MC_CMD_GET_CAPABILITIES_V7_OUT_PF_NOT_PRESENT 0xfe */
+/* Number of VIs available for each external port */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NUM_VIS_PER_PORT_OFST 58
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NUM_VIS_PER_PORT_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NUM_VIS_PER_PORT_NUM 4
+/* Size of RX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ RX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_DESC_CACHE_SIZE_OFST 66
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_DESC_CACHE_SIZE_LEN 1
+/* Size of TX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ TX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_DESC_CACHE_SIZE_OFST 67
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_TX_DESC_CACHE_SIZE_LEN 1
+/* Total number of available PIO buffers */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NUM_PIO_BUFFS_OFST 68
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_NUM_PIO_BUFFS_LEN 2
+/* Size of a single PIO buffer */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_SIZE_PIO_BUFF_OFST 70
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_SIZE_PIO_BUFF_LEN 2
+/* On chips later than Medford the amount of address space assigned to each VI
+ * is configurable. This is a global setting that the driver must query to
+ * discover the VI to address mapping. Cut-through PIO (CTPIO) is not available
+ * with 8k VI windows.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VI_WINDOW_MODE_OFST 72
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VI_WINDOW_MODE_LEN 1
+/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k.
+ * CTPIO is not mapped.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VI_WINDOW_MODE_8K 0x0
+/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VI_WINDOW_MODE_16K 0x1
+/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VI_WINDOW_MODE_64K 0x2
+/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VFIFO_STUFFING_NUM_VFIFOS_OFST 73
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VFIFO_STUFFING_NUM_VFIFOS_LEN 1
+/* Number of buffers per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_OFST 74
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_LEN 2
+/* Entry count in the MAC stats array, including the final GENERATION_END
+ * entry. For MAC stats DMA, drivers should allocate a buffer large enough to
+ * hold at least this many 64-bit stats values, if they wish to receive all
+ * available stats. If the buffer is shorter than MAC_STATS_NUM_STATS * 8, the
+ * stats array returned will be truncated.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MAC_STATS_NUM_STATS_OFST 76
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MAC_STATS_NUM_STATS_LEN 2
+/* Maximum supported value for MC_CMD_FILTER_OP_V3/MATCH_MARK_VALUE. This field
+ * will only be non-zero if MC_CMD_GET_CAPABILITIES/FILTER_ACTION_MARK is set.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FILTER_ACTION_MARK_MAX_OFST 80
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FILTER_ACTION_MARK_MAX_LEN 4
+/* On devices where the INIT_RXQ_WITH_BUFFER_SIZE flag (in
+ * GET_CAPABILITIES_OUT_V2) is set, drivers have to specify a buffer size when
+ * they create an RX queue. Due to hardware limitations, only a small number of
+ * different buffer sizes may be available concurrently. Nonzero entries in
+ * this array are the sizes of buffers which the system guarantees will be
+ * available for use. If the list is empty, there are no limitations on
+ * concurrent buffer sizes.
+ */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_GUARANTEED_RX_BUFFER_SIZES_OFST 84
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_GUARANTEED_RX_BUFFER_SIZES_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_GUARANTEED_RX_BUFFER_SIZES_NUM 16
+/* Third word of flags. Not present on older firmware (check the length). */
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FLAGS3_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_FLAGS3_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_WOL_ETHERWAKE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_WOL_ETHERWAKE_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_WOL_ETHERWAKE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RSS_EVEN_SPREADING_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RSS_EVEN_SPREADING_LBN 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RSS_EVEN_SPREADING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RSS_SELECTABLE_TABLE_SIZE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RSS_SELECTABLE_TABLE_SIZE_LBN 2
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RSS_SELECTABLE_TABLE_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MAE_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MAE_SUPPORTED_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_MAE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VDPA_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VDPA_SUPPORTED_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_VDPA_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_VLAN_STRIPPING_PER_ENCAP_RULE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_VLAN_STRIPPING_PER_ENCAP_RULE_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_RX_VLAN_STRIPPING_PER_ENCAP_RULE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EXTENDED_WIDTH_EVQS_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EXTENDED_WIDTH_EVQS_SUPPORTED_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_EXTENDED_WIDTH_EVQS_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_UNSOL_EV_CREDIT_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_UNSOL_EV_CREDIT_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V7_OUT_UNSOL_EV_CREDIT_SUPPORTED_WIDTH 1
+
+/* MC_CMD_GET_CAPABILITIES_V8_OUT msgresponse */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_LEN 160
+/* First word of flags. */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS1_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS1_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VPORT_RECONFIGURE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VPORT_RECONFIGURE_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VPORT_RECONFIGURE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_STRIPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_STRIPING_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_STRIPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VADAPTOR_QUERY_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VADAPTOR_QUERY_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VADAPTOR_QUERY_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVB_PORT_VLAN_RESTRICT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_DRV_ATTACH_PREBOOT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_DRV_ATTACH_PREBOOT_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_DRV_ATTACH_PREBOOT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_FORCE_EVENT_MERGING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_FORCE_EVENT_MERGING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_SET_MAC_ENHANCED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_SET_MAC_ENHANCED_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_SET_MAC_ENHANCED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_MAC_SECURITY_FILTERING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_ADDITIONAL_RSS_MODES_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_ADDITIONAL_RSS_MODES_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_QBB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_QBB_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PACKED_STREAM_VAR_BUFFERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_RSS_LIMITED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_RSS_LIMITED_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PACKED_STREAM_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PACKED_STREAM_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_INCLUDE_FCS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_INCLUDE_FCS_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_VLAN_INSERTION_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_VLAN_INSERTION_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_VLAN_STRIPPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_VLAN_STRIPPING_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PREFIX_LEN_0_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PREFIX_LEN_0_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PREFIX_LEN_14_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PREFIX_LEN_14_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_TIMESTAMP_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_TIMESTAMP_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_BATCHING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_BATCHING_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MCAST_FILTER_CHAINING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MCAST_FILTER_CHAINING_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_PM_AND_RXDP_COUNTERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_PM_AND_RXDP_COUNTERS_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_DISABLE_SCATTER_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_DISABLE_SCATTER_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_MCAST_UDP_LOOPBACK_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVB_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VXLAN_NVGRE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VXLAN_NVGRE_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VXLAN_NVGRE_WIDTH 1
+/* RxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_DPCPU_FW_ID_OFST 4
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_DPCPU_FW_ID_LEN 2
+/* enum: Standard RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP 0x0
+/* enum: Low latency RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_LOW_LATENCY 0x1
+/* enum: Packed stream RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_PACKED_STREAM 0x2
+/* enum: Rules engine RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_RULES_ENGINE 0x5
+/* enum: DPDK RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_DPDK 0x6
+/* enum: BIST RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_BIST 0x10a
+/* enum: RXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
+/* enum: RXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
+/* enum: RXDP Test firmware image 3 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
+/* enum: RXDP Test firmware image 4 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
+/* enum: RXDP Test firmware image 5 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_BACKPRESSURE 0x105
+/* enum: RXDP Test firmware image 6 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
+/* enum: RXDP Test firmware image 7 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
+/* enum: RXDP Test firmware image 8 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
+/* enum: RXDP Test firmware image 9 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b
+/* enum: RXDP Test firmware image 10 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_TEST_FW_SLOW 0x10c
+/* TxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_DPCPU_FW_ID_OFST 6
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_DPCPU_FW_ID_LEN 2
+/* enum: Standard TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXDP 0x0
+/* enum: Low latency TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXDP_LOW_LATENCY 0x1
+/* enum: High packet rate TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXDP_HIGH_PACKET_RATE 0x3
+/* enum: Rules engine TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXDP_RULES_ENGINE 0x5
+/* enum: DPDK TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXDP_DPDK 0x6
+/* enum: BIST TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXDP_BIST 0x12d
+/* enum: TXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
+/* enum: TXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
+/* enum: TXDP CSR bus test firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXDP_TEST_FW_CSR 0x103
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_VERSION_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_VERSION_REV_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_VERSION_TYPE_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial RX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: RX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant RX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+/* enum: Low latency RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
+/* enum: Packed stream RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
+/* enum: RX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* enum: RX PD firmware parsing but not filtering network overlay tunnel
+ * encapsulations (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_VERSION_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_VERSION_REV_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_VERSION_TYPE_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial TX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: TX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant TX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
+/* enum: TX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* Hardware capabilities of NIC */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_HW_CAPABILITIES_OFST 12
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_HW_CAPABILITIES_LEN 4
+/* Licensed capabilities */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_LICENSE_CAPABILITIES_OFST 16
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_LICENSE_CAPABILITIES_LEN 4
+/* Second word of flags. Not present on older firmware (check the length). */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS2_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V2_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V2_ENCAP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V2_ENCAP_LBN 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V2_ENCAP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVQ_TIMER_CTRL_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVQ_TIMER_CTRL_LBN 2
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVQ_TIMER_CTRL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVENT_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVENT_CUT_THROUGH_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EVENT_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_CUT_THROUGH_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_VFIFO_ULL_MODE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_VFIFO_ULL_MODE_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_VFIFO_ULL_MODE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MAC_STATS_40G_TX_SIZE_BINS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MAC_STATS_40G_TX_SIZE_BINS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_EVQ_TYPE_SUPPORTED_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_EVQ_TYPE_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_EVQ_TYPE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_EVQ_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_EVQ_V2_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_EVQ_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_MAC_TIMESTAMPING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_MAC_TIMESTAMPING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_MAC_TIMESTAMPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TIMESTAMP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TIMESTAMP_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_SNIFF_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_SNIFF_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MCDI_BACKGROUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MCDI_BACKGROUND_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MCDI_BACKGROUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MCDI_DB_RETURN_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MCDI_DB_RETURN_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MCDI_DB_RETURN_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_CTPIO_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_CTPIO_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_CTPIO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TSA_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TSA_SUPPORT_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TSA_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TSA_BOUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TSA_BOUND_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TSA_BOUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_SF_ADAPTER_AUTHENTICATION_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FILTER_ACTION_FLAG_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FILTER_ACTION_FLAG_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FILTER_ACTION_FLAG_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FILTER_ACTION_MARK_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FILTER_ACTION_MARK_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FILTER_ACTION_MARK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EQUAL_STRIDE_SUPER_BUFFER_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EQUAL_STRIDE_SUPER_BUFFER_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EQUAL_STRIDE_SUPER_BUFFER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EQUAL_STRIDE_PACKED_STREAM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_L3XUDP_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_L3XUDP_SUPPORT_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_L3XUDP_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FW_SUBVARIANT_NO_TX_CSUM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VI_SPREADING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VI_SPREADING_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VI_SPREADING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_HLB_IDLE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_HLB_IDLE_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RXDP_HLB_IDLE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_RXQ_NO_CONT_EV_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_RXQ_NO_CONT_EV_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_RXQ_NO_CONT_EV_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_RXQ_WITH_BUFFER_SIZE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_RXQ_WITH_BUFFER_SIZE_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INIT_RXQ_WITH_BUFFER_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_BUNDLE_UPDATE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_BUNDLE_UPDATE_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_BUNDLE_UPDATE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V3_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V3_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V3_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_DYNAMIC_SENSORS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_DYNAMIC_SENSORS_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_DYNAMIC_SENSORS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_WIDTH 1
+/* Number of FATSOv2 contexts per datapath supported by this NIC (when
+ * TX_TSO_V2 == 1). Not present on older firmware (check the length).
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V2_N_CONTEXTS_OFST 24
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_TSO_V2_N_CONTEXTS_LEN 2
+/* One byte per PF containing the number of the external port assigned to this
+ * PF, indexed by PF number. Special values indicate that a PF is either not
+ * present or not assigned.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_PFS_TO_PORTS_ASSIGNMENT_OFST 26
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_ACCESS_NOT_PERMITTED 0xff
+/* enum: PF does not exist. */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_PF_NOT_PRESENT 0xfe
+/* enum: PF does exist but is not assigned to any external port. */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_PF_NOT_ASSIGNED 0xfd
+/* enum: This value indicates that PF is assigned, but it cannot be expressed
+ * in this field. It is intended for a possible future situation where a more
+ * complex scheme of PFs to ports mapping is being used. The future driver
+ * should look for a new field supporting the new scheme. The current/old
+ * driver should treat this value as PF_NOT_ASSIGNED.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc
+/* One byte per PF containing the number of its VFs, indexed by PF number. A
+ * special value indicates that a PF is not present.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NUM_VFS_PER_PF_OFST 42
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NUM_VFS_PER_PF_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NUM_VFS_PER_PF_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+/* MC_CMD_GET_CAPABILITIES_V8_OUT_ACCESS_NOT_PERMITTED 0xff */
+/* enum: PF does not exist. */
+/* MC_CMD_GET_CAPABILITIES_V8_OUT_PF_NOT_PRESENT 0xfe */
+/* Number of VIs available for each external port */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NUM_VIS_PER_PORT_OFST 58
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NUM_VIS_PER_PORT_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NUM_VIS_PER_PORT_NUM 4
+/* Size of RX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ RX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_DESC_CACHE_SIZE_OFST 66
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_DESC_CACHE_SIZE_LEN 1
+/* Size of TX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ TX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_DESC_CACHE_SIZE_OFST 67
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TX_DESC_CACHE_SIZE_LEN 1
+/* Total number of available PIO buffers */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NUM_PIO_BUFFS_OFST 68
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_NUM_PIO_BUFFS_LEN 2
+/* Size of a single PIO buffer */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_SIZE_PIO_BUFF_OFST 70
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_SIZE_PIO_BUFF_LEN 2
+/* On chips later than Medford the amount of address space assigned to each VI
+ * is configurable. This is a global setting that the driver must query to
+ * discover the VI to address mapping. Cut-through PIO (CTPIO) is not available
+ * with 8k VI windows.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VI_WINDOW_MODE_OFST 72
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VI_WINDOW_MODE_LEN 1
+/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k.
+ * CTPIO is not mapped.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VI_WINDOW_MODE_8K 0x0
+/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VI_WINDOW_MODE_16K 0x1
+/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VI_WINDOW_MODE_64K 0x2
+/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VFIFO_STUFFING_NUM_VFIFOS_OFST 73
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VFIFO_STUFFING_NUM_VFIFOS_LEN 1
+/* Number of buffers per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_OFST 74
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_LEN 2
+/* Entry count in the MAC stats array, including the final GENERATION_END
+ * entry. For MAC stats DMA, drivers should allocate a buffer large enough to
+ * hold at least this many 64-bit stats values, if they wish to receive all
+ * available stats. If the buffer is shorter than MAC_STATS_NUM_STATS * 8, the
+ * stats array returned will be truncated.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MAC_STATS_NUM_STATS_OFST 76
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MAC_STATS_NUM_STATS_LEN 2
+/* Maximum supported value for MC_CMD_FILTER_OP_V3/MATCH_MARK_VALUE. This field
+ * will only be non-zero if MC_CMD_GET_CAPABILITIES/FILTER_ACTION_MARK is set.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FILTER_ACTION_MARK_MAX_OFST 80
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FILTER_ACTION_MARK_MAX_LEN 4
+/* On devices where the INIT_RXQ_WITH_BUFFER_SIZE flag (in
+ * GET_CAPABILITIES_OUT_V2) is set, drivers have to specify a buffer size when
+ * they create an RX queue. Due to hardware limitations, only a small number of
+ * different buffer sizes may be available concurrently. Nonzero entries in
+ * this array are the sizes of buffers which the system guarantees will be
+ * available for use. If the list is empty, there are no limitations on
+ * concurrent buffer sizes.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_GUARANTEED_RX_BUFFER_SIZES_OFST 84
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_GUARANTEED_RX_BUFFER_SIZES_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_GUARANTEED_RX_BUFFER_SIZES_NUM 16
+/* Third word of flags. Not present on older firmware (check the length). */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS3_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS3_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_WOL_ETHERWAKE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_WOL_ETHERWAKE_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_WOL_ETHERWAKE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RSS_EVEN_SPREADING_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RSS_EVEN_SPREADING_LBN 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RSS_EVEN_SPREADING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RSS_SELECTABLE_TABLE_SIZE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RSS_SELECTABLE_TABLE_SIZE_LBN 2
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RSS_SELECTABLE_TABLE_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MAE_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MAE_SUPPORTED_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_MAE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VDPA_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VDPA_SUPPORTED_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_VDPA_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_VLAN_STRIPPING_PER_ENCAP_RULE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_VLAN_STRIPPING_PER_ENCAP_RULE_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_RX_VLAN_STRIPPING_PER_ENCAP_RULE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EXTENDED_WIDTH_EVQS_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EXTENDED_WIDTH_EVQS_SUPPORTED_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_EXTENDED_WIDTH_EVQS_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_UNSOL_EV_CREDIT_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_UNSOL_EV_CREDIT_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_UNSOL_EV_CREDIT_SUPPORTED_WIDTH 1
+/* These bits are reserved for communicating test-specific capabilities to
+ * host-side test software. All production drivers should treat this field as
+ * opaque.
+ */
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TEST_RESERVED_OFST 152
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TEST_RESERVED_LEN 8
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TEST_RESERVED_LO_OFST 152
+#define MC_CMD_GET_CAPABILITIES_V8_OUT_TEST_RESERVED_HI_OFST 156
+
+/* MC_CMD_GET_CAPABILITIES_V9_OUT msgresponse */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_LEN 184
+/* First word of flags. */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FLAGS1_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FLAGS1_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VPORT_RECONFIGURE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VPORT_RECONFIGURE_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VPORT_RECONFIGURE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_STRIPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_STRIPING_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_STRIPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VADAPTOR_QUERY_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VADAPTOR_QUERY_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VADAPTOR_QUERY_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVB_PORT_VLAN_RESTRICT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVB_PORT_VLAN_RESTRICT_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVB_PORT_VLAN_RESTRICT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_DRV_ATTACH_PREBOOT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_DRV_ATTACH_PREBOOT_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_DRV_ATTACH_PREBOOT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_FORCE_EVENT_MERGING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_FORCE_EVENT_MERGING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_FORCE_EVENT_MERGING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_SET_MAC_ENHANCED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_SET_MAC_ENHANCED_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_SET_MAC_ENHANCED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_UNKNOWN_UCAST_DST_FILTER_ALWAYS_MULTI_RECIPIENT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VADAPTOR_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_MAC_SECURITY_FILTERING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_ADDITIONAL_RSS_MODES_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_ADDITIONAL_RSS_MODES_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_QBB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_QBB_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PACKED_STREAM_VAR_BUFFERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_RSS_LIMITED_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_RSS_LIMITED_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PACKED_STREAM_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PACKED_STREAM_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_INCLUDE_FCS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_INCLUDE_FCS_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_VLAN_INSERTION_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_VLAN_INSERTION_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_VLAN_STRIPPING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_VLAN_STRIPPING_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PREFIX_LEN_0_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PREFIX_LEN_0_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PREFIX_LEN_14_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PREFIX_LEN_14_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_TIMESTAMP_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_TIMESTAMP_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_BATCHING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_BATCHING_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MCAST_FILTER_CHAINING_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MCAST_FILTER_CHAINING_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_PM_AND_RXDP_COUNTERS_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_PM_AND_RXDP_COUNTERS_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_DISABLE_SCATTER_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_DISABLE_SCATTER_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_MCAST_UDP_LOOPBACK_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVB_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVB_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VXLAN_NVGRE_OFST 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VXLAN_NVGRE_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VXLAN_NVGRE_WIDTH 1
+/* RxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_DPCPU_FW_ID_OFST 4
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_DPCPU_FW_ID_LEN 2
+/* enum: Standard RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP 0x0
+/* enum: Low latency RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_LOW_LATENCY 0x1
+/* enum: Packed stream RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_PACKED_STREAM 0x2
+/* enum: Rules engine RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_RULES_ENGINE 0x5
+/* enum: DPDK RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_DPDK 0x6
+/* enum: BIST RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_BIST 0x10a
+/* enum: RXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
+/* enum: RXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
+/* enum: RXDP Test firmware image 3 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
+/* enum: RXDP Test firmware image 4 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
+/* enum: RXDP Test firmware image 5 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_BACKPRESSURE 0x105
+/* enum: RXDP Test firmware image 6 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
+/* enum: RXDP Test firmware image 7 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
+/* enum: RXDP Test firmware image 8 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
+/* enum: RXDP Test firmware image 9 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_FW_DOORBELL_DELAY 0x10b
+/* enum: RXDP Test firmware image 10 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_TEST_FW_SLOW 0x10c
+/* TxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_DPCPU_FW_ID_OFST 6
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_DPCPU_FW_ID_LEN 2
+/* enum: Standard TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXDP 0x0
+/* enum: Low latency TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXDP_LOW_LATENCY 0x1
+/* enum: High packet rate TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXDP_HIGH_PACKET_RATE 0x3
+/* enum: Rules engine TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXDP_RULES_ENGINE 0x5
+/* enum: DPDK TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXDP_DPDK 0x6
+/* enum: BIST TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXDP_BIST 0x12d
+/* enum: TXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
+/* enum: TXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
+/* enum: TXDP CSR bus test firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXDP_TEST_FW_CSR 0x103
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_VERSION_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_VERSION_REV_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_VERSION_TYPE_OFST 8
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial RX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: RX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant RX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+/* enum: Low latency RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
+/* enum: Packed stream RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
+/* enum: RX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* enum: RX PD firmware parsing but not filtering network overlay tunnel
+ * encapsulations (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_VERSION_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_VERSION_REV_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_VERSION_TYPE_OFST 10
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial TX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware for telemetry prototyping (Medford2 development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_TESTFW_TELEMETRY 0x1
+/* enum: TX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Full featured TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_FULL_FEATURED 0x3
+/* enum: (deprecated original name for the FULL_FEATURED variant) */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant TX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
+/* enum: TX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: Rules engine TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_RULES_ENGINE 0x8
+/* enum: Custom firmware variant (see SF-119495-PD and bug69716) */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_L3XUDP 0x9
+/* enum: DPDK TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_DPDK 0xa
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* Hardware capabilities of NIC */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_HW_CAPABILITIES_OFST 12
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_HW_CAPABILITIES_LEN 4
+/* Licensed capabilities */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_LICENSE_CAPABILITIES_OFST 16
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_LICENSE_CAPABILITIES_LEN 4
+/* Second word of flags. Not present on older firmware (check the length). */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FLAGS2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FLAGS2_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V2_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V2_ENCAP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V2_ENCAP_LBN 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V2_ENCAP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVQ_TIMER_CTRL_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVQ_TIMER_CTRL_LBN 2
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVQ_TIMER_CTRL_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVENT_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVENT_CUT_THROUGH_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EVENT_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_CUT_THROUGH_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_CUT_THROUGH_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_CUT_THROUGH_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_VFIFO_ULL_MODE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_VFIFO_ULL_MODE_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_VFIFO_ULL_MODE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MAC_STATS_40G_TX_SIZE_BINS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MAC_STATS_40G_TX_SIZE_BINS_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MAC_STATS_40G_TX_SIZE_BINS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_EVQ_TYPE_SUPPORTED_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_EVQ_TYPE_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_EVQ_TYPE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_EVQ_V2_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_EVQ_V2_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_EVQ_V2_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_MAC_TIMESTAMPING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_MAC_TIMESTAMPING_LBN 8
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_MAC_TIMESTAMPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TIMESTAMP_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TIMESTAMP_LBN 9
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_SNIFF_LBN 10
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_SNIFF_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_SNIFF_LBN 11
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_SNIFF_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_LBN 12
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NVRAM_UPDATE_REPORT_VERIFY_RESULT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MCDI_BACKGROUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MCDI_BACKGROUND_LBN 13
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MCDI_BACKGROUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MCDI_DB_RETURN_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MCDI_DB_RETURN_LBN 14
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MCDI_DB_RETURN_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_CTPIO_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_CTPIO_LBN 15
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_CTPIO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TSA_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TSA_SUPPORT_LBN 16
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TSA_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TSA_BOUND_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TSA_BOUND_LBN 17
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TSA_BOUND_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_SF_ADAPTER_AUTHENTICATION_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_SF_ADAPTER_AUTHENTICATION_LBN 18
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_SF_ADAPTER_AUTHENTICATION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FILTER_ACTION_FLAG_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FILTER_ACTION_FLAG_LBN 19
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FILTER_ACTION_FLAG_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FILTER_ACTION_MARK_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FILTER_ACTION_MARK_LBN 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FILTER_ACTION_MARK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EQUAL_STRIDE_SUPER_BUFFER_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EQUAL_STRIDE_SUPER_BUFFER_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EQUAL_STRIDE_SUPER_BUFFER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EQUAL_STRIDE_PACKED_STREAM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EQUAL_STRIDE_PACKED_STREAM_LBN 21
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EQUAL_STRIDE_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_L3XUDP_SUPPORT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_L3XUDP_SUPPORT_LBN 22
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_L3XUDP_SUPPORT_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FW_SUBVARIANT_NO_TX_CSUM_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FW_SUBVARIANT_NO_TX_CSUM_LBN 23
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FW_SUBVARIANT_NO_TX_CSUM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VI_SPREADING_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VI_SPREADING_LBN 24
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VI_SPREADING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_HLB_IDLE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_HLB_IDLE_LBN 25
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RXDP_HLB_IDLE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_RXQ_NO_CONT_EV_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_RXQ_NO_CONT_EV_LBN 26
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_RXQ_NO_CONT_EV_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_RXQ_WITH_BUFFER_SIZE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_RXQ_WITH_BUFFER_SIZE_LBN 27
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INIT_RXQ_WITH_BUFFER_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_BUNDLE_UPDATE_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_BUNDLE_UPDATE_LBN 28
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_BUNDLE_UPDATE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V3_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V3_LBN 29
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V3_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_DYNAMIC_SENSORS_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_DYNAMIC_SENSORS_LBN 30
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_DYNAMIC_SENSORS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_OFST 20
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_LBN 31
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NVRAM_UPDATE_POLL_VERIFY_RESULT_WIDTH 1
+/* Number of FATSOv2 contexts per datapath supported by this NIC (when
+ * TX_TSO_V2 == 1). Not present on older firmware (check the length).
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V2_N_CONTEXTS_OFST 24
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_TSO_V2_N_CONTEXTS_LEN 2
+/* One byte per PF containing the number of the external port assigned to this
+ * PF, indexed by PF number. Special values indicate that a PF is either not
+ * present or not assigned.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_PFS_TO_PORTS_ASSIGNMENT_OFST 26
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_PFS_TO_PORTS_ASSIGNMENT_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_PFS_TO_PORTS_ASSIGNMENT_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_ACCESS_NOT_PERMITTED 0xff
+/* enum: PF does not exist. */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_PF_NOT_PRESENT 0xfe
+/* enum: PF does exist but is not assigned to any external port. */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_PF_NOT_ASSIGNED 0xfd
+/* enum: This value indicates that PF is assigned, but it cannot be expressed
+ * in this field. It is intended for a possible future situation where a more
+ * complex scheme of PFs to ports mapping is being used. The future driver
+ * should look for a new field supporting the new scheme. The current/old
+ * driver should treat this value as PF_NOT_ASSIGNED.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_INCOMPATIBLE_ASSIGNMENT 0xfc
+/* One byte per PF containing the number of its VFs, indexed by PF number. A
+ * special value indicates that a PF is not present.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NUM_VFS_PER_PF_OFST 42
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NUM_VFS_PER_PF_LEN 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NUM_VFS_PER_PF_NUM 16
+/* enum: The caller is not permitted to access information on this PF. */
+/* MC_CMD_GET_CAPABILITIES_V9_OUT_ACCESS_NOT_PERMITTED 0xff */
+/* enum: PF does not exist. */
+/* MC_CMD_GET_CAPABILITIES_V9_OUT_PF_NOT_PRESENT 0xfe */
+/* Number of VIs available for each external port */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NUM_VIS_PER_PORT_OFST 58
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NUM_VIS_PER_PORT_LEN 2
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NUM_VIS_PER_PORT_NUM 4
+/* Size of RX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ RX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_DESC_CACHE_SIZE_OFST 66
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_DESC_CACHE_SIZE_LEN 1
+/* Size of TX descriptor cache expressed as binary logarithm The actual size
+ * equals (2 ^ TX_DESC_CACHE_SIZE)
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_DESC_CACHE_SIZE_OFST 67
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TX_DESC_CACHE_SIZE_LEN 1
+/* Total number of available PIO buffers */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NUM_PIO_BUFFS_OFST 68
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_NUM_PIO_BUFFS_LEN 2
+/* Size of a single PIO buffer */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_SIZE_PIO_BUFF_OFST 70
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_SIZE_PIO_BUFF_LEN 2
+/* On chips later than Medford the amount of address space assigned to each VI
+ * is configurable. This is a global setting that the driver must query to
+ * discover the VI to address mapping. Cut-through PIO (CTPIO) is not available
+ * with 8k VI windows.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VI_WINDOW_MODE_OFST 72
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VI_WINDOW_MODE_LEN 1
+/* enum: Each VI occupies 8k as on Huntington and Medford. PIO is at offset 4k.
+ * CTPIO is not mapped.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VI_WINDOW_MODE_8K 0x0
+/* enum: Each VI occupies 16k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VI_WINDOW_MODE_16K 0x1
+/* enum: Each VI occupies 64k. PIO is at offset 4k. CTPIO is at offset 12k. */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VI_WINDOW_MODE_64K 0x2
+/* Number of vFIFOs per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VFIFO_STUFFING_NUM_VFIFOS_OFST 73
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VFIFO_STUFFING_NUM_VFIFOS_LEN 1
+/* Number of buffers per adapter that can be used for VFIFO Stuffing
+ * (SF-115995-SW) in the present configuration of firmware and port mode.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_OFST 74
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VFIFO_STUFFING_NUM_CP_BUFFERS_LEN 2
+/* Entry count in the MAC stats array, including the final GENERATION_END
+ * entry. For MAC stats DMA, drivers should allocate a buffer large enough to
+ * hold at least this many 64-bit stats values, if they wish to receive all
+ * available stats. If the buffer is shorter than MAC_STATS_NUM_STATS * 8, the
+ * stats array returned will be truncated.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MAC_STATS_NUM_STATS_OFST 76
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MAC_STATS_NUM_STATS_LEN 2
+/* Maximum supported value for MC_CMD_FILTER_OP_V3/MATCH_MARK_VALUE. This field
+ * will only be non-zero if MC_CMD_GET_CAPABILITIES/FILTER_ACTION_MARK is set.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FILTER_ACTION_MARK_MAX_OFST 80
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FILTER_ACTION_MARK_MAX_LEN 4
+/* On devices where the INIT_RXQ_WITH_BUFFER_SIZE flag (in
+ * GET_CAPABILITIES_OUT_V2) is set, drivers have to specify a buffer size when
+ * they create an RX queue. Due to hardware limitations, only a small number of
+ * different buffer sizes may be available concurrently. Nonzero entries in
+ * this array are the sizes of buffers which the system guarantees will be
+ * available for use. If the list is empty, there are no limitations on
+ * concurrent buffer sizes.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_GUARANTEED_RX_BUFFER_SIZES_OFST 84
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_GUARANTEED_RX_BUFFER_SIZES_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_GUARANTEED_RX_BUFFER_SIZES_NUM 16
+/* Third word of flags. Not present on older firmware (check the length). */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FLAGS3_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_FLAGS3_LEN 4
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_WOL_ETHERWAKE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_WOL_ETHERWAKE_LBN 0
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_WOL_ETHERWAKE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_EVEN_SPREADING_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_EVEN_SPREADING_LBN 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_EVEN_SPREADING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_SELECTABLE_TABLE_SIZE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_SELECTABLE_TABLE_SIZE_LBN 2
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_SELECTABLE_TABLE_SIZE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MAE_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MAE_SUPPORTED_LBN 3
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_MAE_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VDPA_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VDPA_SUPPORTED_LBN 4
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_VDPA_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_VLAN_STRIPPING_PER_ENCAP_RULE_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_VLAN_STRIPPING_PER_ENCAP_RULE_LBN 5
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RX_VLAN_STRIPPING_PER_ENCAP_RULE_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EXTENDED_WIDTH_EVQS_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EXTENDED_WIDTH_EVQS_SUPPORTED_LBN 6
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_EXTENDED_WIDTH_EVQS_SUPPORTED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_UNSOL_EV_CREDIT_SUPPORTED_OFST 148
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_UNSOL_EV_CREDIT_SUPPORTED_LBN 7
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_UNSOL_EV_CREDIT_SUPPORTED_WIDTH 1
+/* These bits are reserved for communicating test-specific capabilities to
+ * host-side test software. All production drivers should treat this field as
+ * opaque.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TEST_RESERVED_OFST 152
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TEST_RESERVED_LEN 8
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TEST_RESERVED_LO_OFST 152
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_TEST_RESERVED_HI_OFST 156
+/* The minimum size (in table entries) of indirection table to be allocated
+ * from the pool for an RSS context. Note that the table size used must be a
+ * power of 2.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_MIN_INDIRECTION_TABLE_SIZE_OFST 160
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_MIN_INDIRECTION_TABLE_SIZE_LEN 4
+/* The maximum size (in table entries) of indirection table to be allocated
+ * from the pool for an RSS context. Note that the table size used must be a
+ * power of 2.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_TABLE_SIZE_OFST 164
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_TABLE_SIZE_LEN 4
+/* The maximum number of queues that can be used by an RSS context in exclusive
+ * mode. In exclusive mode the context has a configurable indirection table and
+ * a configurable RSS key.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_QUEUES_OFST 168
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_QUEUES_LEN 4
+/* The maximum number of queues that can be used by an RSS context in even-
+ * spreading mode. In even-spreading mode the context has no indirection table
+ * but it does have a configurable RSS key.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_MAX_EVEN_SPREADING_QUEUES_OFST 172
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_MAX_EVEN_SPREADING_QUEUES_LEN 4
+/* The total number of RSS contexts supported. Note that the number of
+ * available contexts using indirection tables is also limited by the
+ * availability of indirection table space allocated from a common pool.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_NUM_CONTEXTS_OFST 176
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_NUM_CONTEXTS_LEN 4
+/* The total amount of indirection table space that can be shared between RSS
+ * contexts.
+ */
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_TABLE_POOL_SIZE_OFST 180
+#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_TABLE_POOL_SIZE_LEN 4
+
/***********************************/
/* MC_CMD_V2_EXTN
@@ -10858,6 +15558,7 @@
* Allocate a pacer bucket (for qau rp or a snapper test)
*/
#define MC_CMD_TCM_BUCKET_ALLOC 0xb2
+#undef MC_CMD_0xb2_PRIVILEGE_CTG
#define MC_CMD_0xb2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -10876,6 +15577,7 @@
* Free a pacer bucket
*/
#define MC_CMD_TCM_BUCKET_FREE 0xb3
+#undef MC_CMD_0xb3_PRIVILEGE_CTG
#define MC_CMD_0xb3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -10894,6 +15596,7 @@
* Initialise pacer bucket with a given rate
*/
#define MC_CMD_TCM_BUCKET_INIT 0xb4
+#undef MC_CMD_0xb4_PRIVILEGE_CTG
#define MC_CMD_0xb4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -10927,6 +15630,7 @@
* Initialise txq in pacer with given options or set options
*/
#define MC_CMD_TCM_TXQ_INIT 0xb5
+#undef MC_CMD_0xb5_PRIVILEGE_CTG
#define MC_CMD_0xb5_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -10941,10 +15645,13 @@
/* bitmask of the priority queues this txq is inserted into when inserted. */
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAGS_OFST 8
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAGS_LEN 4
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_GUARANTEED_OFST 8
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_GUARANTEED_LBN 0
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_GUARANTEED_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_NORMAL_OFST 8
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_NORMAL_LBN 1
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_NORMAL_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_LOW_OFST 8
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_LOW_LBN 2
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_LOW_WIDTH 1
/* the reaction point (RP) bucket */
@@ -10975,10 +15682,13 @@
/* bitmask of the priority queues this txq is inserted into when inserted. */
#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAGS_OFST 8
#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAGS_LEN 4
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_GUARANTEED_OFST 8
#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_GUARANTEED_LBN 0
#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_GUARANTEED_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_NORMAL_OFST 8
#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_NORMAL_LBN 1
#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_NORMAL_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_LOW_OFST 8
#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_LOW_LBN 2
#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_LOW_WIDTH 1
/* the reaction point (RP) bucket */
@@ -11010,6 +15720,7 @@
* Link a push I/O buffer to a TxQ
*/
#define MC_CMD_LINK_PIOBUF 0x92
+#undef MC_CMD_0x92_PRIVILEGE_CTG
#define MC_CMD_0x92_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
@@ -11031,6 +15742,7 @@
* Unlink a push I/O buffer from a TxQ
*/
#define MC_CMD_UNLINK_PIOBUF 0x93
+#undef MC_CMD_0x93_PRIVILEGE_CTG
#define MC_CMD_0x93_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
@@ -11049,6 +15761,7 @@
* allocate and initialise a v-switch.
*/
#define MC_CMD_VSWITCH_ALLOC 0x94
+#undef MC_CMD_0x94_PRIVILEGE_CTG
#define MC_CMD_0x94_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11073,6 +15786,7 @@
/* Flags controlling v-port creation */
#define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_OFST 8
#define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_LEN 4
+#define MC_CMD_VSWITCH_ALLOC_IN_FLAG_AUTO_PORT_OFST 8
#define MC_CMD_VSWITCH_ALLOC_IN_FLAG_AUTO_PORT_LBN 0
#define MC_CMD_VSWITCH_ALLOC_IN_FLAG_AUTO_PORT_WIDTH 1
/* The number of VLAN tags to allow for attached v-ports. For VLAN aggregators,
@@ -11094,6 +15808,7 @@
* de-allocate a v-switch.
*/
#define MC_CMD_VSWITCH_FREE 0x95
+#undef MC_CMD_0x95_PRIVILEGE_CTG
#define MC_CMD_0x95_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11114,6 +15829,7 @@
* not, then the command returns ENOENT).
*/
#define MC_CMD_VSWITCH_QUERY 0x63
+#undef MC_CMD_0x63_PRIVILEGE_CTG
#define MC_CMD_0x63_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11132,6 +15848,7 @@
* allocate a v-port.
*/
#define MC_CMD_VPORT_ALLOC 0x96
+#undef MC_CMD_0x96_PRIVILEGE_CTG
#define MC_CMD_0x96_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11164,8 +15881,10 @@
/* Flags controlling v-port creation */
#define MC_CMD_VPORT_ALLOC_IN_FLAGS_OFST 8
#define MC_CMD_VPORT_ALLOC_IN_FLAGS_LEN 4
+#define MC_CMD_VPORT_ALLOC_IN_FLAG_AUTO_PORT_OFST 8
#define MC_CMD_VPORT_ALLOC_IN_FLAG_AUTO_PORT_LBN 0
#define MC_CMD_VPORT_ALLOC_IN_FLAG_AUTO_PORT_WIDTH 1
+#define MC_CMD_VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT_OFST 8
#define MC_CMD_VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT_LBN 1
#define MC_CMD_VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT_WIDTH 1
/* The number of VLAN tags to insert/remove. An error will be returned if
@@ -11177,8 +15896,10 @@
/* The actual VLAN tags to insert/remove */
#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAGS_OFST 16
#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAGS_LEN 4
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_0_OFST 16
#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_0_LBN 0
#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_0_WIDTH 16
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_1_OFST 16
#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_1_LBN 16
#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_1_WIDTH 16
@@ -11194,6 +15915,7 @@
* de-allocate a v-port.
*/
#define MC_CMD_VPORT_FREE 0x97
+#undef MC_CMD_0x97_PRIVILEGE_CTG
#define MC_CMD_0x97_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11212,6 +15934,7 @@
* allocate a v-adaptor.
*/
#define MC_CMD_VADAPTOR_ALLOC 0x98
+#undef MC_CMD_0x98_PRIVILEGE_CTG
#define MC_CMD_0x98_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11223,8 +15946,10 @@
/* Flags controlling v-adaptor creation */
#define MC_CMD_VADAPTOR_ALLOC_IN_FLAGS_OFST 8
#define MC_CMD_VADAPTOR_ALLOC_IN_FLAGS_LEN 4
+#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_AUTO_VADAPTOR_OFST 8
#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_AUTO_VADAPTOR_LBN 0
#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_AUTO_VADAPTOR_WIDTH 1
+#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_OFST 8
#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_LBN 1
#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_PERMIT_SET_MAC_WHEN_FILTERS_INSTALLED_WIDTH 1
/* The number of VLAN tags to strip on receive */
@@ -11236,8 +15961,10 @@
/* The actual VLAN tags to insert/remove */
#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAGS_OFST 20
#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAGS_LEN 4
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_0_OFST 20
#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_0_LBN 0
#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_0_WIDTH 16
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_1_OFST 20
#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_1_LBN 16
#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_1_WIDTH 16
/* The MAC address to assign to this v-adaptor */
@@ -11255,6 +15982,7 @@
* de-allocate a v-adaptor.
*/
#define MC_CMD_VADAPTOR_FREE 0x99
+#undef MC_CMD_0x99_PRIVILEGE_CTG
#define MC_CMD_0x99_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11273,6 +16001,7 @@
* assign a new MAC address to a v-adaptor.
*/
#define MC_CMD_VADAPTOR_SET_MAC 0x5d
+#undef MC_CMD_0x5d_PRIVILEGE_CTG
#define MC_CMD_0x5d_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11294,6 +16023,7 @@
* read the MAC address assigned to a v-adaptor.
*/
#define MC_CMD_VADAPTOR_GET_MAC 0x5e
+#undef MC_CMD_0x5e_PRIVILEGE_CTG
#define MC_CMD_0x5e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11315,6 +16045,7 @@
* read some config of v-adaptor.
*/
#define MC_CMD_VADAPTOR_QUERY 0x61
+#undef MC_CMD_0x61_PRIVILEGE_CTG
#define MC_CMD_0x61_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11342,6 +16073,7 @@
* assign a port to a PCI function.
*/
#define MC_CMD_EVB_PORT_ASSIGN 0x9a
+#undef MC_CMD_0x9a_PRIVILEGE_CTG
#define MC_CMD_0x9a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11353,8 +16085,10 @@
/* The target function to modify. */
#define MC_CMD_EVB_PORT_ASSIGN_IN_FUNCTION_OFST 4
#define MC_CMD_EVB_PORT_ASSIGN_IN_FUNCTION_LEN 4
+#define MC_CMD_EVB_PORT_ASSIGN_IN_PF_OFST 4
#define MC_CMD_EVB_PORT_ASSIGN_IN_PF_LBN 0
#define MC_CMD_EVB_PORT_ASSIGN_IN_PF_WIDTH 16
+#define MC_CMD_EVB_PORT_ASSIGN_IN_VF_OFST 4
#define MC_CMD_EVB_PORT_ASSIGN_IN_VF_LBN 16
#define MC_CMD_EVB_PORT_ASSIGN_IN_VF_WIDTH 16
@@ -11367,6 +16101,7 @@
* Assign the 64 bit region addresses.
*/
#define MC_CMD_RDWR_A64_REGIONS 0x9b
+#undef MC_CMD_0x9b_PRIVILEGE_CTG
#define MC_CMD_0x9b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -11405,6 +16140,7 @@
* Allocate an Onload stack ID.
*/
#define MC_CMD_ONLOAD_STACK_ALLOC 0x9c
+#undef MC_CMD_0x9c_PRIVILEGE_CTG
#define MC_CMD_0x9c_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
@@ -11426,6 +16162,7 @@
* Free an Onload stack ID.
*/
#define MC_CMD_ONLOAD_STACK_FREE 0x9d
+#undef MC_CMD_0x9d_PRIVILEGE_CTG
#define MC_CMD_0x9d_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
@@ -11444,6 +16181,7 @@
* Allocate an RSS context.
*/
#define MC_CMD_RSS_CONTEXT_ALLOC 0x9e
+#undef MC_CMD_0x9e_PRIVILEGE_CTG
#define MC_CMD_0x9e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11464,12 +16202,68 @@
* changed. For this mode, NUM_QUEUES must 2, 4, 8, 16, 32 or 64.
*/
#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED 0x1
-/* Number of queues spanned by this context, in the range 1-64; valid offsets
- * in the indirection table will be in the range 0 to NUM_QUEUES-1.
+/* enum: Allocate a context to spread evenly across an arbitrary number of
+ * queues. No indirection table space is allocated for this context. (EF100 and
+ * later)
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EVEN_SPREADING 0x2
+/* Number of queues spanned by this context. For exclusive contexts this must
+ * be in the range 1 to RSS_MAX_INDIRECTION_QUEUES, where
+ * RSS_MAX_INDIRECTION_QUEUES is queried from MC_CMD_GET_CAPABILITIES_V9 or if
+ * V9 is not supported then RSS_MAX_INDIRECTION_QUEUES is 64. Valid entries in
+ * the indirection table will be in the range 0 to NUM_QUEUES-1. For even-
+ * spreading contexts this must be in the range 1 to
+ * RSS_MAX_EVEN_SPREADING_QUEUES as queried from MC_CMD_GET_CAPABILITIES. Note
+ * that specifying NUM_QUEUES = 1 will not perform any spreading but may still
+ * be useful as a way of obtaining the Toeplitz hash.
*/
#define MC_CMD_RSS_CONTEXT_ALLOC_IN_NUM_QUEUES_OFST 8
#define MC_CMD_RSS_CONTEXT_ALLOC_IN_NUM_QUEUES_LEN 4
+/* MC_CMD_RSS_CONTEXT_ALLOC_V2_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_LEN 16
+/* The handle of the owning upstream port */
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_UPSTREAM_PORT_ID_OFST 0
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_UPSTREAM_PORT_ID_LEN 4
+/* The type of context to allocate */
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_TYPE_OFST 4
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_TYPE_LEN 4
+/* enum: Allocate a context for exclusive use. The key and indirection table
+ * must be explicitly configured.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_TYPE_EXCLUSIVE 0x0
+/* enum: Allocate a context for shared use; this will spread across a range of
+ * queues, but the key and indirection table are pre-configured and may not be
+ * changed. For this mode, NUM_QUEUES must 2, 4, 8, 16, 32 or 64.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_TYPE_SHARED 0x1
+/* enum: Allocate a context to spread evenly across an arbitrary number of
+ * queues. No indirection table space is allocated for this context. (EF100 and
+ * later)
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_TYPE_EVEN_SPREADING 0x2
+/* Number of queues spanned by this context. For exclusive contexts this must
+ * be in the range 1 to RSS_MAX_INDIRECTION_QUEUES, where
+ * RSS_MAX_INDIRECTION_QUEUES is queried from MC_CMD_GET_CAPABILITIES_V9 or if
+ * V9 is not supported then RSS_MAX_INDIRECTION_QUEUES is 64. Valid entries in
+ * the indirection table will be in the range 0 to NUM_QUEUES-1. For even-
+ * spreading contexts this must be in the range 1 to
+ * RSS_MAX_EVEN_SPREADING_QUEUES as queried from MC_CMD_GET_CAPABILITIES. Note
+ * that specifying NUM_QUEUES = 1 will not perform any spreading but may still
+ * be useful as a way of obtaining the Toeplitz hash.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_NUM_QUEUES_OFST 8
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_NUM_QUEUES_LEN 4
+/* Size of indirection table to be allocated to this context from the pool.
+ * Must be a power of 2. The minimum and maximum table size can be queried
+ * using MC_CMD_GET_CAPABILITIES_V9. If there is not enough space remaining in
+ * the common pool to allocate the requested table size, due to allocating
+ * table space to other RSS contexts, then the command will fail with
+ * MC_CMD_ERR_ENOSPC.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_INDIRECTION_TABLE_SIZE_OFST 12
+#define MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_INDIRECTION_TABLE_SIZE_LEN 4
+
/* MC_CMD_RSS_CONTEXT_ALLOC_OUT msgresponse */
#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN 4
/* The handle of the new RSS context. This should be considered opaque to the
@@ -11487,6 +16281,7 @@
* Free an RSS context.
*/
#define MC_CMD_RSS_CONTEXT_FREE 0x9f
+#undef MC_CMD_0x9f_PRIVILEGE_CTG
#define MC_CMD_0x9f_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11505,6 +16300,7 @@
* Set the Toeplitz hash key for an RSS context.
*/
#define MC_CMD_RSS_CONTEXT_SET_KEY 0xa0
+#undef MC_CMD_0xa0_PRIVILEGE_CTG
#define MC_CMD_0xa0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11526,6 +16322,7 @@
* Get the Toeplitz hash key for an RSS context.
*/
#define MC_CMD_RSS_CONTEXT_GET_KEY 0xa1
+#undef MC_CMD_0xa1_PRIVILEGE_CTG
#define MC_CMD_0xa1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11544,9 +16341,12 @@
/***********************************/
/* MC_CMD_RSS_CONTEXT_SET_TABLE
- * Set the indirection table for an RSS context.
+ * Set the indirection table for an RSS context. This command should only be
+ * used with indirection tables containing 128 entries, which is the default
+ * when the RSS context is allocated without specifying a table size.
*/
#define MC_CMD_RSS_CONTEXT_SET_TABLE 0xa2
+#undef MC_CMD_0xa2_PRIVILEGE_CTG
#define MC_CMD_0xa2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11565,9 +16365,12 @@
/***********************************/
/* MC_CMD_RSS_CONTEXT_GET_TABLE
- * Get the indirection table for an RSS context.
+ * Get the indirection table for an RSS context. This command should only be
+ * used with indirection tables containing 128 entries, which is the default
+ * when the RSS context is allocated without specifying a table size.
*/
#define MC_CMD_RSS_CONTEXT_GET_TABLE 0xa3
+#undef MC_CMD_0xa3_PRIVILEGE_CTG
#define MC_CMD_0xa3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11585,10 +16388,98 @@
/***********************************/
+/* MC_CMD_RSS_CONTEXT_WRITE_TABLE
+ * Write a portion of a selectable-size indirection table for an RSS context.
+ * This command must be used instead of MC_CMD_RSS_CONTEXT_SET_TABLE if the
+ * RSS_SELECTABLE_TABLE_SIZE bit is set in MC_CMD_GET_CAPABILITIES.
+ */
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE 0x13e
+#undef MC_CMD_0x13e_PRIVILEGE_CTG
+
+#define MC_CMD_0x13e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_LENMIN 8
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_LENMAX 252
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_LENMAX_MCDI2 1020
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_LEN(num) (4+4*(num))
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_NUM(len) (((len)-4)/4)
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_RSS_CONTEXT_ID_OFST 0
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_RSS_CONTEXT_ID_LEN 4
+/* An array of index-value pairs to be written to the table. Structure is
+ * MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY.
+ */
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_OFST 4
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_LEN 4
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_MINNUM 1
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_MAXNUM 62
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_MAXNUM_MCDI2 254
+
+/* MC_CMD_RSS_CONTEXT_WRITE_TABLE_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_OUT_LEN 0
+
+/* MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY structuredef */
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY_LEN 4
+/* The index of the table entry to be written. */
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY_INDEX_OFST 0
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY_INDEX_LEN 2
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY_INDEX_LBN 0
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY_INDEX_WIDTH 16
+/* The value to write into the table entry. */
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY_VALUE_OFST 2
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY_VALUE_LEN 2
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY_VALUE_LBN 16
+#define MC_CMD_RSS_CONTEXT_WRITE_TABLE_ENTRY_VALUE_WIDTH 16
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_READ_TABLE
+ * Read a portion of a selectable-size indirection table for an RSS context.
+ * This command must be used instead of MC_CMD_RSS_CONTEXT_GET_TABLE if the
+ * RSS_SELECTABLE_TABLE_SIZE bit is set in MC_CMD_GET_CAPABILITIES.
+ */
+#define MC_CMD_RSS_CONTEXT_READ_TABLE 0x13f
+#undef MC_CMD_0x13f_PRIVILEGE_CTG
+
+#define MC_CMD_0x13f_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_READ_TABLE_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_LENMIN 6
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_LENMAX 252
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_LENMAX_MCDI2 1020
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_LEN(num) (4+2*(num))
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_INDICES_NUM(len) (((len)-4)/2)
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_RSS_CONTEXT_ID_OFST 0
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_RSS_CONTEXT_ID_LEN 4
+/* An array containing the indices of the entries to be read. */
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_INDICES_OFST 4
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_INDICES_LEN 2
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_INDICES_MINNUM 1
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_INDICES_MAXNUM 124
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_IN_INDICES_MAXNUM_MCDI2 508
+
+/* MC_CMD_RSS_CONTEXT_READ_TABLE_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_LENMIN 2
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_LENMAX 252
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_LENMAX_MCDI2 1020
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_LEN(num) (0+2*(num))
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_DATA_NUM(len) (((len)-0)/2)
+/* A buffer containing the requested entries read from the table. */
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_DATA_OFST 0
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_DATA_LEN 2
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_DATA_MINNUM 1
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_DATA_MAXNUM 126
+#define MC_CMD_RSS_CONTEXT_READ_TABLE_OUT_DATA_MAXNUM_MCDI2 510
+
+
+/***********************************/
/* MC_CMD_RSS_CONTEXT_SET_FLAGS
* Set various control flags for an RSS context.
*/
#define MC_CMD_RSS_CONTEXT_SET_FLAGS 0xe1
+#undef MC_CMD_0xe1_PRIVILEGE_CTG
#define MC_CMD_0xe1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11611,26 +16502,37 @@
*/
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_FLAGS_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_FLAGS_LEN 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN_LBN 0
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN_LBN 1
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN_LBN 2
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN_LBN 3
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RESERVED_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RESERVED_LBN 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RESERVED_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_LBN 8
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE_LBN 12
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_LBN 16
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_LBN 20
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE_LBN 24
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_LBN 28
#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_WIDTH 4
@@ -11643,6 +16545,7 @@
* Get various control flags for an RSS context.
*/
#define MC_CMD_RSS_CONTEXT_GET_FLAGS 0xe2
+#undef MC_CMD_0xe2_PRIVILEGE_CTG
#define MC_CMD_0xe2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11669,26 +16572,37 @@
*/
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_FLAGS_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_FLAGS_LEN 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_LBN 0
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_LBN 1
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV6_EN_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV6_EN_LBN 2
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV6_EN_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV6_EN_LBN 3
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_RESERVED_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_RESERVED_LBN 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_RESERVED_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV4_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV4_RSS_MODE_LBN 8
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_LBN 12
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV4_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV4_RSS_MODE_LBN 16
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV6_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV6_RSS_MODE_LBN 20
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_LBN 24
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV6_RSS_MODE_OFST 4
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV6_RSS_MODE_LBN 28
#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV6_RSS_MODE_WIDTH 4
@@ -11698,6 +16612,7 @@
* Allocate a .1p mapping.
*/
#define MC_CMD_DOT1P_MAPPING_ALLOC 0xa4
+#undef MC_CMD_0xa4_PRIVILEGE_CTG
#define MC_CMD_0xa4_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -11730,6 +16645,7 @@
* Free a .1p mapping.
*/
#define MC_CMD_DOT1P_MAPPING_FREE 0xa5
+#undef MC_CMD_0xa5_PRIVILEGE_CTG
#define MC_CMD_0xa5_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -11748,6 +16664,7 @@
* Set the mapping table for a .1p mapping.
*/
#define MC_CMD_DOT1P_MAPPING_SET_TABLE 0xa6
+#undef MC_CMD_0xa6_PRIVILEGE_CTG
#define MC_CMD_0xa6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -11771,6 +16688,7 @@
* Get the mapping table for a .1p mapping.
*/
#define MC_CMD_DOT1P_MAPPING_GET_TABLE 0xa7
+#undef MC_CMD_0xa7_PRIVILEGE_CTG
#define MC_CMD_0xa7_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -11794,6 +16712,7 @@
* Get Interrupt Vector config for this PF.
*/
#define MC_CMD_GET_VECTOR_CFG 0xbf
+#undef MC_CMD_0xbf_PRIVILEGE_CTG
#define MC_CMD_0xbf_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11818,6 +16737,7 @@
* Set Interrupt Vector config for this PF.
*/
#define MC_CMD_SET_VECTOR_CFG 0xc0
+#undef MC_CMD_0xc0_PRIVILEGE_CTG
#define MC_CMD_0xc0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11844,6 +16764,7 @@
* Add a MAC address to a v-port
*/
#define MC_CMD_VPORT_ADD_MAC_ADDRESS 0xa8
+#undef MC_CMD_0xa8_PRIVILEGE_CTG
#define MC_CMD_0xa8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11865,6 +16786,7 @@
* Delete a MAC address from a v-port
*/
#define MC_CMD_VPORT_DEL_MAC_ADDRESS 0xa9
+#undef MC_CMD_0xa9_PRIVILEGE_CTG
#define MC_CMD_0xa9_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11886,6 +16808,7 @@
* Delete a MAC address from a v-port
*/
#define MC_CMD_VPORT_GET_MAC_ADDRESSES 0xaa
+#undef MC_CMD_0xaa_PRIVILEGE_CTG
#define MC_CMD_0xaa_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11898,7 +16821,9 @@
/* MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT msgresponse */
#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN 4
#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX 250
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX_MCDI2 1018
#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LEN(num) (4+6*(num))
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_NUM(len) (((len)-4)/6)
/* The number of MAC addresses returned */
#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT_OFST 0
#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT_LEN 4
@@ -11907,6 +16832,7 @@
#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_LEN 6
#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_MINNUM 0
#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_MAXNUM 41
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_MAXNUM_MCDI2 169
/***********************************/
@@ -11916,6 +16842,7 @@
* function will be reset before applying the changes.
*/
#define MC_CMD_VPORT_RECONFIGURE 0xeb
+#undef MC_CMD_0xeb_PRIVILEGE_CTG
#define MC_CMD_0xeb_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11927,8 +16854,10 @@
/* Flags requesting what should be changed. */
#define MC_CMD_VPORT_RECONFIGURE_IN_FLAGS_OFST 4
#define MC_CMD_VPORT_RECONFIGURE_IN_FLAGS_LEN 4
+#define MC_CMD_VPORT_RECONFIGURE_IN_REPLACE_VLAN_TAGS_OFST 4
#define MC_CMD_VPORT_RECONFIGURE_IN_REPLACE_VLAN_TAGS_LBN 0
#define MC_CMD_VPORT_RECONFIGURE_IN_REPLACE_VLAN_TAGS_WIDTH 1
+#define MC_CMD_VPORT_RECONFIGURE_IN_REPLACE_MACADDRS_OFST 4
#define MC_CMD_VPORT_RECONFIGURE_IN_REPLACE_MACADDRS_LBN 1
#define MC_CMD_VPORT_RECONFIGURE_IN_REPLACE_MACADDRS_WIDTH 1
/* The number of VLAN tags to insert/remove. An error will be returned if
@@ -11940,8 +16869,10 @@
/* The actual VLAN tags to insert/remove */
#define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAGS_OFST 12
#define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAGS_LEN 4
+#define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_0_OFST 12
#define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_0_LBN 0
#define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_0_WIDTH 16
+#define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_1_OFST 12
#define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_1_LBN 16
#define MC_CMD_VPORT_RECONFIGURE_IN_VLAN_TAG_1_WIDTH 16
/* The number of MAC addresses to add */
@@ -11956,6 +16887,7 @@
#define MC_CMD_VPORT_RECONFIGURE_OUT_LEN 4
#define MC_CMD_VPORT_RECONFIGURE_OUT_FLAGS_OFST 0
#define MC_CMD_VPORT_RECONFIGURE_OUT_FLAGS_LEN 4
+#define MC_CMD_VPORT_RECONFIGURE_OUT_RESET_DONE_OFST 0
#define MC_CMD_VPORT_RECONFIGURE_OUT_RESET_DONE_LBN 0
#define MC_CMD_VPORT_RECONFIGURE_OUT_RESET_DONE_WIDTH 1
@@ -11965,6 +16897,7 @@
* read some config of v-port.
*/
#define MC_CMD_EVB_PORT_QUERY 0x62
+#undef MC_CMD_0x62_PRIVILEGE_CTG
#define MC_CMD_0x62_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -11994,6 +16927,7 @@
* lifted in future.
*/
#define MC_CMD_DUMP_BUFTBL_ENTRIES 0xab
+#undef MC_CMD_0xab_PRIVILEGE_CTG
#define MC_CMD_0xab_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -12009,12 +16943,15 @@
/* MC_CMD_DUMP_BUFTBL_ENTRIES_OUT msgresponse */
#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMIN 12
#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMAX 252
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMAX_MCDI2 1020
#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LEN(num) (0+12*(num))
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_NUM(len) (((len)-0)/12)
/* Raw buffer table entries, layed out as BUFTBL_ENTRY. */
#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_OFST 0
#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_LEN 12
#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_MINNUM 1
#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_MAXNUM 21
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_MAXNUM_MCDI2 85
/***********************************/
@@ -12022,6 +16959,7 @@
* Set global RXDP configuration settings
*/
#define MC_CMD_SET_RXDP_CONFIG 0xc1
+#undef MC_CMD_0xc1_PRIVILEGE_CTG
#define MC_CMD_0xc1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -12029,8 +16967,10 @@
#define MC_CMD_SET_RXDP_CONFIG_IN_LEN 4
#define MC_CMD_SET_RXDP_CONFIG_IN_DATA_OFST 0
#define MC_CMD_SET_RXDP_CONFIG_IN_DATA_LEN 4
+#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_DMA_OFST 0
#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_DMA_LBN 0
#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_DMA_WIDTH 1
+#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_LEN_OFST 0
#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_LEN_LBN 1
#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_LEN_WIDTH 2
/* enum: pad to 64 bytes */
@@ -12049,6 +16989,7 @@
* Get global RXDP configuration settings
*/
#define MC_CMD_GET_RXDP_CONFIG 0xc2
+#undef MC_CMD_0xc2_PRIVILEGE_CTG
#define MC_CMD_0xc2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -12059,8 +17000,10 @@
#define MC_CMD_GET_RXDP_CONFIG_OUT_LEN 4
#define MC_CMD_GET_RXDP_CONFIG_OUT_DATA_OFST 0
#define MC_CMD_GET_RXDP_CONFIG_OUT_DATA_LEN 4
+#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_DMA_OFST 0
#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_DMA_LBN 0
#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_DMA_WIDTH 1
+#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_LEN_OFST 0
#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_LEN_LBN 1
#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_LEN_WIDTH 2
/* Enum values, see field(s): */
@@ -12072,6 +17015,7 @@
* Return the system and PDCPU clock frequencies.
*/
#define MC_CMD_GET_CLOCK 0xac
+#undef MC_CMD_0xac_PRIVILEGE_CTG
#define MC_CMD_0xac_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -12093,6 +17037,7 @@
* Control the system and DPCPU clock frequencies. Changes are lost reboot.
*/
#define MC_CMD_SET_CLOCK 0xad
+#undef MC_CMD_0xad_PRIVILEGE_CTG
#define MC_CMD_0xad_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -12178,6 +17123,7 @@
* Send an arbitrary DPCPU message.
*/
#define MC_CMD_DPCPU_RPC 0xae
+#undef MC_CMD_0xae_PRIVILEGE_CTG
#define MC_CMD_0xae_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -12206,6 +17152,7 @@
*/
#define MC_CMD_DPCPU_RPC_IN_DATA_OFST 4
#define MC_CMD_DPCPU_RPC_IN_DATA_LEN 32
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_OFST 4
#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_LBN 8
#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_WIDTH 8
#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_READ 0x6 /* enum */
@@ -12217,14 +17164,19 @@
#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SELF_TEST 0x4a /* enum */
#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_CSR_ACCESS 0x4c /* enum */
#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SET_MC_REPLAY_CNTXT 0x4d /* enum */
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_OFST 4
#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_LBN 16
#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_ADDR_OFST 4
#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_ADDR_LBN 16
#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_ADDR_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_COUNT_OFST 4
#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_COUNT_LBN 48
#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_COUNT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_INFO_OFST 4
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_INFO_LBN 16
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_INFO_WIDTH 240
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_OFST 4
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_LBN 16
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_WIDTH 16
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_STOP_RETURN_RESULT 0x0 /* enum */
@@ -12232,17 +17184,22 @@
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE 0x2 /* enum */
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE_READ 0x3 /* enum */
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_PIPELINED_READ 0x4 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_OFST 4
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_LBN 48
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_RPT_COUNT_OFST 4
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_RPT_COUNT_LBN 64
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_RPT_COUNT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_GAP_DELAY_OFST 4
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_GAP_DELAY_LBN 80
#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_GAP_DELAY_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_OFST 4
#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_LBN 16
#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_WIDTH 16
#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_CUT_THROUGH 0x1 /* enum */
#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD 0x2 /* enum */
#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD_FIRST 0x3 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_OFST 4
#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_LBN 64
#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_WIDTH 16
#define MC_CMD_DPCPU_RPC_IN_WDATA_OFST 12
@@ -12261,8 +17218,10 @@
/* DATA */
#define MC_CMD_DPCPU_RPC_OUT_DATA_OFST 4
#define MC_CMD_DPCPU_RPC_OUT_DATA_LEN 32
+#define MC_CMD_DPCPU_RPC_OUT_HDR_CMD_RESP_ERRCODE_OFST 4
#define MC_CMD_DPCPU_RPC_OUT_HDR_CMD_RESP_ERRCODE_LBN 32
#define MC_CMD_DPCPU_RPC_OUT_HDR_CMD_RESP_ERRCODE_WIDTH 16
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_COUNT_OFST 4
#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_COUNT_LBN 48
#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_COUNT_WIDTH 16
#define MC_CMD_DPCPU_RPC_OUT_RDATA_OFST 12
@@ -12282,6 +17241,7 @@
* Trigger an interrupt by prodding the BIU.
*/
#define MC_CMD_TRIGGER_INTERRUPT 0xe3
+#undef MC_CMD_0xe3_PRIVILEGE_CTG
#define MC_CMD_0xe3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -12300,6 +17260,7 @@
* Special operations to support (for now) shmboot.
*/
#define MC_CMD_SHMBOOT_OP 0xe6
+#undef MC_CMD_0xe6_PRIVILEGE_CTG
#define MC_CMD_0xe6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -12320,6 +17281,7 @@
* Read multiple 64bit words from capture block memory
*/
#define MC_CMD_CAP_BLK_READ 0xe7
+#undef MC_CMD_0xe7_PRIVILEGE_CTG
#define MC_CMD_0xe7_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -12335,13 +17297,16 @@
/* MC_CMD_CAP_BLK_READ_OUT msgresponse */
#define MC_CMD_CAP_BLK_READ_OUT_LENMIN 8
#define MC_CMD_CAP_BLK_READ_OUT_LENMAX 248
+#define MC_CMD_CAP_BLK_READ_OUT_LENMAX_MCDI2 1016
#define MC_CMD_CAP_BLK_READ_OUT_LEN(num) (0+8*(num))
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_NUM(len) (((len)-0)/8)
#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_OFST 0
#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_LEN 8
#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_LO_OFST 0
#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_HI_OFST 4
#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_MINNUM 1
#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_MAXNUM 31
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_MAXNUM_MCDI2 127
/***********************************/
@@ -12349,6 +17314,7 @@
* Take a dump of the DUT state
*/
#define MC_CMD_DUMP_DO 0xe8
+#undef MC_CMD_0xe8_PRIVILEGE_CTG
#define MC_CMD_0xe8_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -12428,6 +17394,7 @@
* Configure unsolicited dumps
*/
#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED 0xe9
+#undef MC_CMD_0xe9_PRIVILEGE_CTG
#define MC_CMD_0xe9_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -12496,6 +17463,7 @@
* the parameter is out of range.
*/
#define MC_CMD_SET_PSU 0xea
+#undef MC_CMD_0xea_PRIVILEGE_CTG
#define MC_CMD_0xea_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -12521,6 +17489,7 @@
* Get function information. PF and VF number.
*/
#define MC_CMD_GET_FUNCTION_INFO 0xec
+#undef MC_CMD_0xec_PRIVILEGE_CTG
#define MC_CMD_0xec_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -12542,6 +17511,7 @@
* reboot.
*/
#define MC_CMD_ENABLE_OFFLINE_BIST 0xed
+#undef MC_CMD_0xed_PRIVILEGE_CTG
#define MC_CMD_0xed_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -12559,13 +17529,16 @@
* forget.
*/
#define MC_CMD_UART_SEND_DATA 0xee
+#undef MC_CMD_0xee_PRIVILEGE_CTG
#define MC_CMD_0xee_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_UART_SEND_DATA_OUT msgrequest */
#define MC_CMD_UART_SEND_DATA_OUT_LENMIN 16
#define MC_CMD_UART_SEND_DATA_OUT_LENMAX 252
+#define MC_CMD_UART_SEND_DATA_OUT_LENMAX_MCDI2 1020
#define MC_CMD_UART_SEND_DATA_OUT_LEN(num) (16+1*(num))
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_NUM(len) (((len)-16)/1)
/* CRC32 over OFFSET, LENGTH, RESERVED, DATA */
#define MC_CMD_UART_SEND_DATA_OUT_CHECKSUM_OFST 0
#define MC_CMD_UART_SEND_DATA_OUT_CHECKSUM_LEN 4
@@ -12582,6 +17555,7 @@
#define MC_CMD_UART_SEND_DATA_OUT_DATA_LEN 1
#define MC_CMD_UART_SEND_DATA_OUT_DATA_MINNUM 0
#define MC_CMD_UART_SEND_DATA_OUT_DATA_MAXNUM 236
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_MAXNUM_MCDI2 1004
/* MC_CMD_UART_SEND_DATA_IN msgresponse */
#define MC_CMD_UART_SEND_DATA_IN_LEN 0
@@ -12593,6 +17567,7 @@
* subject to change and not currently implemented.
*/
#define MC_CMD_UART_RECV_DATA 0xef
+#undef MC_CMD_0xef_PRIVILEGE_CTG
#define MC_CMD_0xef_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -12614,7 +17589,9 @@
/* MC_CMD_UART_RECV_DATA_IN msgresponse */
#define MC_CMD_UART_RECV_DATA_IN_LENMIN 16
#define MC_CMD_UART_RECV_DATA_IN_LENMAX 252
+#define MC_CMD_UART_RECV_DATA_IN_LENMAX_MCDI2 1020
#define MC_CMD_UART_RECV_DATA_IN_LEN(num) (16+1*(num))
+#define MC_CMD_UART_RECV_DATA_IN_DATA_NUM(len) (((len)-16)/1)
/* CRC32 over RESERVED1, RESERVED2, RESERVED3, DATA */
#define MC_CMD_UART_RECV_DATA_IN_CHECKSUM_OFST 0
#define MC_CMD_UART_RECV_DATA_IN_CHECKSUM_LEN 4
@@ -12631,6 +17608,7 @@
#define MC_CMD_UART_RECV_DATA_IN_DATA_LEN 1
#define MC_CMD_UART_RECV_DATA_IN_DATA_MINNUM 0
#define MC_CMD_UART_RECV_DATA_IN_DATA_MAXNUM 236
+#define MC_CMD_UART_RECV_DATA_IN_DATA_MAXNUM_MCDI2 1004
/***********************************/
@@ -12638,6 +17616,7 @@
* Read data programmed into the device One-Time-Programmable (OTP) Fuses
*/
#define MC_CMD_READ_FUSES 0xf0
+#undef MC_CMD_0xf0_PRIVILEGE_CTG
#define MC_CMD_0xf0_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -12653,7 +17632,9 @@
/* MC_CMD_READ_FUSES_OUT msgresponse */
#define MC_CMD_READ_FUSES_OUT_LENMIN 4
#define MC_CMD_READ_FUSES_OUT_LENMAX 252
+#define MC_CMD_READ_FUSES_OUT_LENMAX_MCDI2 1020
#define MC_CMD_READ_FUSES_OUT_LEN(num) (4+1*(num))
+#define MC_CMD_READ_FUSES_OUT_DATA_NUM(len) (((len)-4)/1)
/* Length of returned OTP data in bytes */
#define MC_CMD_READ_FUSES_OUT_LENGTH_OFST 0
#define MC_CMD_READ_FUSES_OUT_LENGTH_LEN 4
@@ -12662,6 +17643,7 @@
#define MC_CMD_READ_FUSES_OUT_DATA_LEN 1
#define MC_CMD_READ_FUSES_OUT_DATA_MINNUM 0
#define MC_CMD_READ_FUSES_OUT_DATA_MAXNUM 248
+#define MC_CMD_READ_FUSES_OUT_DATA_MAXNUM_MCDI2 1016
/***********************************/
@@ -12669,13 +17651,16 @@
* Get or set KR Serdes RXEQ and TX Driver settings
*/
#define MC_CMD_KR_TUNE 0xf1
+#undef MC_CMD_0xf1_PRIVILEGE_CTG
#define MC_CMD_0xf1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_KR_TUNE_IN msgrequest */
#define MC_CMD_KR_TUNE_IN_LENMIN 4
#define MC_CMD_KR_TUNE_IN_LENMAX 252
+#define MC_CMD_KR_TUNE_IN_LENMAX_MCDI2 1020
#define MC_CMD_KR_TUNE_IN_LEN(num) (4+4*(num))
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_NUM(len) (((len)-4)/4)
/* Requested operation */
#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_OFST 0
#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_LEN 1
@@ -12712,6 +17697,7 @@
#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_LEN 4
#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_MINNUM 0
#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_MAXNUM 62
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_MAXNUM_MCDI2 254
/* MC_CMD_KR_TUNE_OUT msgresponse */
#define MC_CMD_KR_TUNE_OUT_LEN 0
@@ -12728,12 +17714,16 @@
/* MC_CMD_KR_TUNE_RXEQ_GET_OUT msgresponse */
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LENMIN 4
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LENMAX_MCDI2 1020
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_NUM(len) (((len)-0)/4)
/* RXEQ Parameter */
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_OFST 0
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LEN 4
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_MINNUM 1
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_MAXNUM_MCDI2 255
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_OFST 0
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8
/* enum: Attenuation (0-15, Huntington) */
@@ -12822,6 +17812,45 @@
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CDR_PVT 0x20
/* enum: CDR integral loop code (Medford2) */
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_CDR_INTEG 0x21
+/* enum: CTLE Boost stages - retimer lineside (Medford2 with DS250x retimer - 4
+ * stages, 2 bits per stage)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_BOOST_RT_LS 0x22
+/* enum: DFE Tap1 - retimer lineside (Medford2 with DS250x retimer (-31 - 31))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP1_RT_LS 0x23
+/* enum: DFE Tap2 - retimer lineside (Medford2 with DS250x retimer (-15 - 15))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP2_RT_LS 0x24
+/* enum: DFE Tap3 - retimer lineside (Medford2 with DS250x retimer (-15 - 15))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP3_RT_LS 0x25
+/* enum: DFE Tap4 - retimer lineside (Medford2 with DS250x retimer (-15 - 15))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP4_RT_LS 0x26
+/* enum: DFE Tap5 - retimer lineside (Medford2 with DS250x retimer (-15 - 15))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP5_RT_LS 0x27
+/* enum: CTLE Boost stages - retimer hostside (Medford2 with DS250x retimer - 4
+ * stages, 2 bits per stage)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_BOOST_RT_HS 0x28
+/* enum: DFE Tap1 - retimer hostside (Medford2 with DS250x retimer (-31 - 31))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP1_RT_HS 0x29
+/* enum: DFE Tap2 - retimer hostside (Medford2 with DS250x retimer (-15 - 15))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP2_RT_HS 0x2a
+/* enum: DFE Tap3 - retimer hostside (Medford2 with DS250x retimer (-15 - 15))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP3_RT_HS 0x2b
+/* enum: DFE Tap4 - retimer hostside (Medford2 with DS250x retimer (-15 - 15))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP4_RT_HS 0x2c
+/* enum: DFE Tap5 - retimer hostside (Medford2 with DS250x retimer (-15 - 15))
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_DFE_TAP5_RT_HS 0x2d
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_OFST 0
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 3
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */
@@ -12829,19 +17858,25 @@
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_2 0x2 /* enum */
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_3 0x3 /* enum */
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_ALL 0x4 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_OFST 0
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_LBN 11
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_WIDTH 1
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_RESERVED_OFST 0
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_RESERVED_LBN 12
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_RESERVED_WIDTH 4
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_INITIAL_OFST 0
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_INITIAL_LBN 16
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_OFST 0
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_LBN 24
#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8
/* MC_CMD_KR_TUNE_RXEQ_SET_IN msgrequest */
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LENMIN 8
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LENMAX 252
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LENMAX_MCDI2 1020
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LEN(num) (4+4*(num))
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_NUM(len) (((len)-4)/4)
/* Requested operation */
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_OP_OFST 0
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_OP_LEN 1
@@ -12853,20 +17888,27 @@
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LEN 4
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_MINNUM 1
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_MAXNUM 62
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_MAXNUM_MCDI2 254
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_ID_OFST 4
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_ID_LBN 0
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_ID_WIDTH 8
/* Enum values, see field(s): */
/* MC_CMD_KR_TUNE_RXEQ_GET_OUT/PARAM_ID */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LANE_OFST 4
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LANE_LBN 8
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LANE_WIDTH 3
/* Enum values, see field(s): */
/* MC_CMD_KR_TUNE_RXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_OFST 4
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_LBN 11
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_WIDTH 1
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED_OFST 4
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED_LBN 12
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED_WIDTH 4
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_INITIAL_OFST 4
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_INITIAL_LBN 16
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED2_OFST 4
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED2_LBN 24
#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED2_WIDTH 8
@@ -12885,12 +17927,16 @@
/* MC_CMD_KR_TUNE_TXEQ_GET_OUT msgresponse */
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LENMIN 4
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LENMAX_MCDI2 1020
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_NUM(len) (((len)-0)/4)
/* TXEQ Parameter */
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_OFST 0
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LEN 4
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MINNUM 1
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM_MCDI2 255
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_OFST 0
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8
/* enum: TX Amplitude (Huntington, Medford, Medford2) */
@@ -12915,10 +17961,23 @@
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_RT_SET 0x9
/* enum: TX Amplitude Fine control (Medford) */
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV_FINE 0xa
-/* enum: Pre-shoot Tap (Medford, Medford2) */
+/* enum: Pre-cursor Tap (Medford, Medford2) */
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_ADV 0xb
-/* enum: De-emphasis Tap (Medford, Medford2) */
+/* enum: Post-cursor Tap (Medford, Medford2) */
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_DLY 0xc
+/* enum: TX Amplitude (Retimer Lineside) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV_RT_LS 0xd
+/* enum: Pre-cursor Tap (Retimer Lineside) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_ADV_RT_LS 0xe
+/* enum: Post-cursor Tap (Retimer Lineside) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_DLY_RT_LS 0xf
+/* enum: TX Amplitude (Retimer Hostside) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV_RT_HS 0x10
+/* enum: Pre-cursor Tap (Retimer Hostside) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_ADV_RT_HS 0x11
+/* enum: Post-cursor Tap (Retimer Hostside) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TAP_DLY_RT_HS 0x12
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_OFST 0
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 3
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_0 0x0 /* enum */
@@ -12926,17 +17985,22 @@
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_2 0x2 /* enum */
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_3 0x3 /* enum */
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_ALL 0x4 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_OFST 0
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_LBN 11
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_WIDTH 5
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_OFST 0
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_LBN 16
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED2_OFST 0
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED2_LBN 24
#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED2_WIDTH 8
/* MC_CMD_KR_TUNE_TXEQ_SET_IN msgrequest */
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LENMIN 8
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LENMAX 252
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LENMAX_MCDI2 1020
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LEN(num) (4+4*(num))
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_NUM(len) (((len)-4)/4)
/* Requested operation */
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_OP_OFST 0
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_OP_LEN 1
@@ -12948,18 +18012,24 @@
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LEN 4
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_MINNUM 1
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_MAXNUM 62
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_MAXNUM_MCDI2 254
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_ID_OFST 4
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_ID_LBN 0
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_ID_WIDTH 8
/* Enum values, see field(s): */
/* MC_CMD_KR_TUNE_TXEQ_GET_OUT/PARAM_ID */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LANE_OFST 4
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LANE_LBN 8
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LANE_WIDTH 3
/* Enum values, see field(s): */
/* MC_CMD_KR_TUNE_TXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED_OFST 4
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED_LBN 11
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED_WIDTH 5
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_INITIAL_OFST 4
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_INITIAL_LBN 16
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED2_OFST 4
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED2_LBN 24
#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED2_WIDTH 8
@@ -13000,8 +18070,10 @@
#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_KR_TUNE_RSVD_LEN 3
#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_OFST 4
#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_LEN 4
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_NUM_OFST 4
#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_NUM_LBN 0
#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_NUM_WIDTH 8
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_ABS_REL_OFST 4
#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_ABS_REL_LBN 31
#define MC_CMD_KR_TUNE_START_EYE_PLOT_V2_IN_LANE_ABS_REL_WIDTH 1
/* Scan duration / cycle count */
@@ -13023,11 +18095,14 @@
/* MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT msgresponse */
#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LENMIN 0
#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LENMAX 252
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LENMAX_MCDI2 1020
#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LEN(num) (0+2*(num))
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_NUM(len) (((len)-0)/2)
#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_OFST 0
#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_LEN 2
#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MINNUM 0
#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM 126
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM_MCDI2 510
/* MC_CMD_KR_TUNE_READ_FOM_IN msgrequest */
#define MC_CMD_KR_TUNE_READ_FOM_IN_LEN 8
@@ -13039,8 +18114,10 @@
#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_RSVD_LEN 3
#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_OFST 4
#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_LEN 4
+#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_NUM_OFST 4
#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_NUM_LBN 0
#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_NUM_WIDTH 8
+#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_ABS_REL_OFST 4
#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_ABS_REL_LBN 31
#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_ABS_REL_WIDTH 1
@@ -13130,13 +18207,16 @@
* Get or set PCIE Serdes RXEQ and TX Driver settings
*/
#define MC_CMD_PCIE_TUNE 0xf2
+#undef MC_CMD_0xf2_PRIVILEGE_CTG
#define MC_CMD_0xf2_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_PCIE_TUNE_IN msgrequest */
#define MC_CMD_PCIE_TUNE_IN_LENMIN 4
#define MC_CMD_PCIE_TUNE_IN_LENMAX 252
+#define MC_CMD_PCIE_TUNE_IN_LENMAX_MCDI2 1020
#define MC_CMD_PCIE_TUNE_IN_LEN(num) (4+4*(num))
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_NUM(len) (((len)-4)/4)
/* Requested operation */
#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_OFST 0
#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_LEN 1
@@ -13165,6 +18245,7 @@
#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_LEN 4
#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_MINNUM 0
#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_MAXNUM 62
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_MAXNUM_MCDI2 254
/* MC_CMD_PCIE_TUNE_OUT msgresponse */
#define MC_CMD_PCIE_TUNE_OUT_LEN 0
@@ -13181,12 +18262,16 @@
/* MC_CMD_PCIE_TUNE_RXEQ_GET_OUT msgresponse */
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LENMIN 4
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LENMAX_MCDI2 1020
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_NUM(len) (((len)-0)/4)
/* RXEQ Parameter */
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_OFST 0
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LEN 4
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_MINNUM 1
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_MAXNUM_MCDI2 255
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_OFST 0
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8
/* enum: Attenuation (0-15) */
@@ -13211,6 +18296,7 @@
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_CTLE_EQC 0x9
/* enum: CTLE EQ Resistor (DC Gain) */
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_CTLE_EQRES 0xa
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_OFST 0
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 5
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */
@@ -13230,17 +18316,22 @@
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_14 0xe /* enum */
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_15 0xf /* enum */
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_ALL 0x10 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_OFST 0
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_LBN 13
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_WIDTH 1
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_RESERVED_OFST 0
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_RESERVED_LBN 14
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_RESERVED_WIDTH 10
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_OFST 0
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_LBN 24
#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8
/* MC_CMD_PCIE_TUNE_RXEQ_SET_IN msgrequest */
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_LENMIN 8
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_LENMAX 252
+#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_LENMAX_MCDI2 1020
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_LEN(num) (4+4*(num))
+#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_NUM(len) (((len)-4)/4)
/* Requested operation */
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PCIE_TUNE_OP_OFST 0
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PCIE_TUNE_OP_LEN 1
@@ -13252,20 +18343,27 @@
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_LEN 4
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_MINNUM 1
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_MAXNUM 62
+#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_MAXNUM_MCDI2 254
+#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_ID_OFST 4
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_ID_LBN 0
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_ID_WIDTH 8
/* Enum values, see field(s): */
/* MC_CMD_PCIE_TUNE_RXEQ_GET_OUT/PARAM_ID */
+#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_LANE_OFST 4
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_LANE_LBN 8
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_LANE_WIDTH 5
/* Enum values, see field(s): */
/* MC_CMD_PCIE_TUNE_RXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_OFST 4
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_LBN 13
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_WIDTH 1
+#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_RESERVED_OFST 4
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_RESERVED_LBN 14
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_RESERVED_WIDTH 2
+#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_INITIAL_OFST 4
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_INITIAL_LBN 16
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_RESERVED2_OFST 4
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_RESERVED2_LBN 24
#define MC_CMD_PCIE_TUNE_RXEQ_SET_IN_RESERVED2_WIDTH 8
@@ -13284,12 +18382,16 @@
/* MC_CMD_PCIE_TUNE_TXEQ_GET_OUT msgresponse */
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LENMIN 4
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LENMAX_MCDI2 1020
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_NUM(len) (((len)-0)/4)
/* RXEQ Parameter */
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_OFST 0
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LEN 4
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_MINNUM 1
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM_MCDI2 255
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_OFST 0
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8
/* enum: TxMargin (PIPE) */
@@ -13302,12 +18404,15 @@
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_C0 0x3
/* enum: De-emphasis coefficient C(+1) (PIPE) */
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_CP1 0x4
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_OFST 0
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 4
/* Enum values, see field(s): */
/* MC_CMD_PCIE_TUNE_RXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_RESERVED_OFST 0
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_RESERVED_LBN 12
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_RESERVED_WIDTH 12
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_OFST 0
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_LBN 24
#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8
@@ -13337,11 +18442,14 @@
/* MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT msgresponse */
#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LENMIN 0
#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LENMAX 252
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LENMAX_MCDI2 1020
#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LEN(num) (0+2*(num))
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_NUM(len) (((len)-0)/2)
#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_OFST 0
#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_LEN 2
#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MINNUM 0
#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM 126
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM_MCDI2 510
/* MC_CMD_PCIE_TUNE_BIST_SQUARE_WAVE_IN msgrequest */
#define MC_CMD_PCIE_TUNE_BIST_SQUARE_WAVE_IN_LEN 0
@@ -13356,6 +18464,7 @@
* - not used for V3 licensing
*/
#define MC_CMD_LICENSING 0xf3
+#undef MC_CMD_0xf3_PRIVILEGE_CTG
#define MC_CMD_0xf3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13411,6 +18520,7 @@
* - V3 licensing (Medford)
*/
#define MC_CMD_LICENSING_V3 0xd0
+#undef MC_CMD_0xd0_PRIVILEGE_CTG
#define MC_CMD_0xd0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13480,6 +18590,7 @@
* partition - V3 licensing (Medford)
*/
#define MC_CMD_LICENSING_GET_ID_V3 0xd1
+#undef MC_CMD_0xd1_PRIVILEGE_CTG
#define MC_CMD_0xd1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13489,7 +18600,9 @@
/* MC_CMD_LICENSING_GET_ID_V3_OUT msgresponse */
#define MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN 8
#define MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX 252
+#define MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX_MCDI2 1020
#define MC_CMD_LICENSING_GET_ID_V3_OUT_LEN(num) (8+1*(num))
+#define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_NUM(len) (((len)-8)/1)
/* type of license (eg 3) */
#define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_TYPE_OFST 0
#define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_TYPE_LEN 4
@@ -13501,6 +18614,7 @@
#define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_LEN 1
#define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_MINNUM 0
#define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_MAXNUM 244
+#define MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_MAXNUM_MCDI2 1012
/***********************************/
@@ -13509,6 +18623,7 @@
* This will fail on a single-core system.
*/
#define MC_CMD_MC2MC_PROXY 0xf4
+#undef MC_CMD_0xf4_PRIVILEGE_CTG
#define MC_CMD_0xf4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13526,6 +18641,7 @@
* or a reboot of the MC.) Not used for V3 licensing
*/
#define MC_CMD_GET_LICENSED_APP_STATE 0xf5
+#undef MC_CMD_0xf5_PRIVILEGE_CTG
#define MC_CMD_0xf5_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13553,6 +18669,7 @@
* operation or a reboot of the MC.) Used for V3 licensing (Medford)
*/
#define MC_CMD_GET_LICENSED_V3_APP_STATE 0xd2
+#undef MC_CMD_0xd2_PRIVILEGE_CTG
#define MC_CMD_0xd2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13579,11 +18696,12 @@
/***********************************/
/* MC_CMD_GET_LICENSED_V3_FEATURE_STATES
- * Query the state of one or more licensed features. (Note that the actual
+ * Query the state of an one or more licensed features. (Note that the actual
* state may be invalidated by the MC_CMD_LICENSING_V3 OP_UPDATE_LICENSE
* operation or a reboot of the MC.) Used for V3 licensing (Medford)
*/
#define MC_CMD_GET_LICENSED_V3_FEATURE_STATES 0xd3
+#undef MC_CMD_0xd3_PRIVILEGE_CTG
#define MC_CMD_0xd3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13612,13 +18730,16 @@
* licensing.
*/
#define MC_CMD_LICENSED_APP_OP 0xf6
+#undef MC_CMD_0xf6_PRIVILEGE_CTG
#define MC_CMD_0xf6_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_LICENSED_APP_OP_IN msgrequest */
#define MC_CMD_LICENSED_APP_OP_IN_LENMIN 8
#define MC_CMD_LICENSED_APP_OP_IN_LENMAX 252
+#define MC_CMD_LICENSED_APP_OP_IN_LENMAX_MCDI2 1020
#define MC_CMD_LICENSED_APP_OP_IN_LEN(num) (8+4*(num))
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_NUM(len) (((len)-8)/4)
/* application ID */
#define MC_CMD_LICENSED_APP_OP_IN_APP_ID_OFST 0
#define MC_CMD_LICENSED_APP_OP_IN_APP_ID_LEN 4
@@ -13634,16 +18755,20 @@
#define MC_CMD_LICENSED_APP_OP_IN_ARGS_LEN 4
#define MC_CMD_LICENSED_APP_OP_IN_ARGS_MINNUM 0
#define MC_CMD_LICENSED_APP_OP_IN_ARGS_MAXNUM 61
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_MAXNUM_MCDI2 253
/* MC_CMD_LICENSED_APP_OP_OUT msgresponse */
#define MC_CMD_LICENSED_APP_OP_OUT_LENMIN 0
#define MC_CMD_LICENSED_APP_OP_OUT_LENMAX 252
+#define MC_CMD_LICENSED_APP_OP_OUT_LENMAX_MCDI2 1020
#define MC_CMD_LICENSED_APP_OP_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_NUM(len) (((len)-0)/4)
/* result specific to this particular operation */
#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_OFST 0
#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_LEN 4
#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_MINNUM 0
#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_MAXNUM 63
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_MAXNUM_MCDI2 255
/* MC_CMD_LICENSED_APP_OP_VALIDATE_IN msgrequest */
#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_LEN 72
@@ -13688,6 +18813,7 @@
* (Medford)
*/
#define MC_CMD_LICENSED_V3_VALIDATE_APP 0xd4
+#undef MC_CMD_0xd4_PRIVILEGE_CTG
#define MC_CMD_0xd4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13740,6 +18866,7 @@
* Mask features - V3 licensing (Medford)
*/
#define MC_CMD_LICENSED_V3_MASK_FEATURES 0xd5
+#undef MC_CMD_0xd5_PRIVILEGE_CTG
#define MC_CMD_0xd5_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -13771,6 +18898,7 @@
* erased when the adapter is power cycled
*/
#define MC_CMD_LICENSING_V3_TEMPORARY 0xd6
+#undef MC_CMD_0xd6_PRIVILEGE_CTG
#define MC_CMD_0xd6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -13840,6 +18968,7 @@
* delivered to a specific queue, or a set of queues with RSS.
*/
#define MC_CMD_SET_PORT_SNIFF_CONFIG 0xf7
+#undef MC_CMD_0xf7_PRIVILEGE_CTG
#define MC_CMD_0xf7_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -13848,8 +18977,10 @@
/* configuration flags */
#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_FLAGS_OFST 0
#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_FLAGS_LEN 4
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_OFST 0
#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_LBN 0
#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_WIDTH 1
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_OFST 0
#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_LBN 1
#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_WIDTH 1
/* receive queue handle (for RSS mode, this is the base queue) */
@@ -13880,6 +19011,7 @@
* the configuration.
*/
#define MC_CMD_GET_PORT_SNIFF_CONFIG 0xf8
+#undef MC_CMD_0xf8_PRIVILEGE_CTG
#define MC_CMD_0xf8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13891,8 +19023,10 @@
/* configuration flags */
#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_FLAGS_OFST 0
#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_FLAGS_LEN 4
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_OFST 0
#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_LBN 0
#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_WIDTH 1
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_OFST 0
#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_LBN 1
#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_WIDTH 1
/* receiving queue handle (for RSS mode, this is the base queue) */
@@ -13915,13 +19049,16 @@
* Change configuration related to the parser-dispatcher subsystem.
*/
#define MC_CMD_SET_PARSER_DISP_CONFIG 0xf9
+#undef MC_CMD_0xf9_PRIVILEGE_CTG
#define MC_CMD_0xf9_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_SET_PARSER_DISP_CONFIG_IN msgrequest */
#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LENMIN 12
#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LENMAX 252
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LENMAX_MCDI2 1020
#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LEN(num) (8+4*(num))
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_NUM(len) (((len)-8)/4)
/* the type of configuration setting to change */
#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TYPE_OFST 0
#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TYPE_LEN 4
@@ -13946,6 +19083,7 @@
#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_LEN 4
#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_MINNUM 1
#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_MAXNUM 61
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_MAXNUM_MCDI2 253
/* MC_CMD_SET_PARSER_DISP_CONFIG_OUT msgresponse */
#define MC_CMD_SET_PARSER_DISP_CONFIG_OUT_LEN 0
@@ -13956,6 +19094,7 @@
* Read configuration related to the parser-dispatcher subsystem.
*/
#define MC_CMD_GET_PARSER_DISP_CONFIG 0xfa
+#undef MC_CMD_0xfa_PRIVILEGE_CTG
#define MC_CMD_0xfa_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -13975,7 +19114,9 @@
/* MC_CMD_GET_PARSER_DISP_CONFIG_OUT msgresponse */
#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LENMIN 4
#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LENMAX 252
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LENMAX_MCDI2 1020
#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LEN(num) (0+4*(num))
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_NUM(len) (((len)-0)/4)
/* current value: the details depend on the type of configuration setting being
* read
*/
@@ -13983,6 +19124,7 @@
#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_LEN 4
#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_MINNUM 1
#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_MAXNUM 63
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_MAXNUM_MCDI2 255
/***********************************/
@@ -13996,6 +19138,7 @@
* dedicated as TX sniff receivers.
*/
#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG 0xfb
+#undef MC_CMD_0xfb_PRIVILEGE_CTG
#define MC_CMD_0xfb_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -14004,6 +19147,7 @@
/* configuration flags */
#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_FLAGS_OFST 0
#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_FLAGS_LEN 4
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_ENABLE_OFST 0
#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_ENABLE_LBN 0
#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_ENABLE_WIDTH 1
/* receive queue handle (for RSS mode, this is the base queue) */
@@ -14034,6 +19178,7 @@
* the configuration.
*/
#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG 0xfc
+#undef MC_CMD_0xfc_PRIVILEGE_CTG
#define MC_CMD_0xfc_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -14045,6 +19190,7 @@
/* configuration flags */
#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_FLAGS_OFST 0
#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_FLAGS_LEN 4
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_ENABLE_OFST 0
#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_ENABLE_LBN 0
#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_ENABLE_WIDTH 1
/* receiving queue handle (for RSS mode, this is the base queue) */
@@ -14067,6 +19213,7 @@
* Per queue rx error stats.
*/
#define MC_CMD_RMON_STATS_RX_ERRORS 0xfe
+#undef MC_CMD_0xfe_PRIVILEGE_CTG
#define MC_CMD_0xfe_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -14077,6 +19224,7 @@
#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RX_QUEUE_LEN 4
#define MC_CMD_RMON_STATS_RX_ERRORS_IN_FLAGS_OFST 4
#define MC_CMD_RMON_STATS_RX_ERRORS_IN_FLAGS_LEN 4
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RST_OFST 4
#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RST_LBN 0
#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RST_WIDTH 1
@@ -14097,6 +19245,7 @@
* Find out about available PCIE resources
*/
#define MC_CMD_GET_PCIE_RESOURCE_INFO 0xfd
+#undef MC_CMD_0xfd_PRIVILEGE_CTG
#define MC_CMD_0xfd_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -14135,6 +19284,7 @@
* Find out about available port modes
*/
#define MC_CMD_GET_PORT_MODES 0xff
+#undef MC_CMD_0xff_PRIVILEGE_CTG
#define MC_CMD_0xff_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -14143,7 +19293,9 @@
/* MC_CMD_GET_PORT_MODES_OUT msgresponse */
#define MC_CMD_GET_PORT_MODES_OUT_LEN 12
-/* Bitmask of port modes available on the board (indexed by TLV_PORT_MODE_*) */
+/* Bitmask of port modes available on the board (indexed by TLV_PORT_MODE_*)
+ * that are supported for customer use in production firmware.
+ */
#define MC_CMD_GET_PORT_MODES_OUT_MODES_OFST 0
#define MC_CMD_GET_PORT_MODES_OUT_MODES_LEN 4
/* Default (canonical) board mode */
@@ -14153,12 +19305,66 @@
#define MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST 8
#define MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_LEN 4
+/* MC_CMD_GET_PORT_MODES_OUT_V2 msgresponse */
+#define MC_CMD_GET_PORT_MODES_OUT_V2_LEN 16
+/* Bitmask of port modes available on the board (indexed by TLV_PORT_MODE_*)
+ * that are supported for customer use in production firmware.
+ */
+#define MC_CMD_GET_PORT_MODES_OUT_V2_MODES_OFST 0
+#define MC_CMD_GET_PORT_MODES_OUT_V2_MODES_LEN 4
+/* Default (canonical) board mode */
+#define MC_CMD_GET_PORT_MODES_OUT_V2_DEFAULT_MODE_OFST 4
+#define MC_CMD_GET_PORT_MODES_OUT_V2_DEFAULT_MODE_LEN 4
+/* Current board mode */
+#define MC_CMD_GET_PORT_MODES_OUT_V2_CURRENT_MODE_OFST 8
+#define MC_CMD_GET_PORT_MODES_OUT_V2_CURRENT_MODE_LEN 4
+/* Bitmask of engineering port modes available on the board (indexed by
+ * TLV_PORT_MODE_*). A superset of MC_CMD_GET_PORT_MODES_OUT/MODES that
+ * contains all modes implemented in firmware for a particular board. Modes
+ * listed in MODES are considered production modes and should be exposed in
+ * userland tools. Modes listed in in ENGINEERING_MODES, but not in MODES
+ * should be considered hidden (not to be exposed in userland tools) and for
+ * engineering use only. There are no other semantic differences and any mode
+ * listed in either MODES or ENGINEERING_MODES can be set on the board.
+ */
+#define MC_CMD_GET_PORT_MODES_OUT_V2_ENGINEERING_MODES_OFST 12
+#define MC_CMD_GET_PORT_MODES_OUT_V2_ENGINEERING_MODES_LEN 4
+
+
+/***********************************/
+/* MC_CMD_OVERRIDE_PORT_MODE
+ * Override flash config port mode for subsequent MC reboot(s). Override data
+ * is stored in the presistent data section of DMEM and activated on next MC
+ * warm reboot. A cold reboot resets the override. It is assumed that a
+ * sufficient number of PFs are available and that port mapping is valid for
+ * the new port mode, as the override does not affect PF configuration.
+ */
+#define MC_CMD_OVERRIDE_PORT_MODE 0x137
+#undef MC_CMD_0x137_PRIVILEGE_CTG
+
+#define MC_CMD_0x137_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_OVERRIDE_PORT_MODE_IN msgrequest */
+#define MC_CMD_OVERRIDE_PORT_MODE_IN_LEN 8
+#define MC_CMD_OVERRIDE_PORT_MODE_IN_FLAGS_OFST 0
+#define MC_CMD_OVERRIDE_PORT_MODE_IN_FLAGS_LEN 4
+#define MC_CMD_OVERRIDE_PORT_MODE_IN_ENABLE_OFST 0
+#define MC_CMD_OVERRIDE_PORT_MODE_IN_ENABLE_LBN 0
+#define MC_CMD_OVERRIDE_PORT_MODE_IN_ENABLE_WIDTH 1
+/* New mode (TLV_PORT_MODE_*) to set, if override enabled */
+#define MC_CMD_OVERRIDE_PORT_MODE_IN_MODE_OFST 4
+#define MC_CMD_OVERRIDE_PORT_MODE_IN_MODE_LEN 4
+
+/* MC_CMD_OVERRIDE_PORT_MODE_OUT msgresponse */
+#define MC_CMD_OVERRIDE_PORT_MODE_OUT_LEN 0
+
/***********************************/
/* MC_CMD_READ_ATB
* Sample voltages on the ATB
*/
#define MC_CMD_READ_ATB 0x100
+#undef MC_CMD_0x100_PRIVILEGE_CTG
#define MC_CMD_0x100_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -14188,6 +19394,7 @@
* enums here must correspond with those in MC_CMD_WORKAROUND.
*/
#define MC_CMD_GET_WORKAROUNDS 0x59
+#undef MC_CMD_0x59_PRIVILEGE_CTG
#define MC_CMD_0x59_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -14224,6 +19431,7 @@
* Read/set privileges of an arbitrary PCIe function
*/
#define MC_CMD_PRIVILEGE_MASK 0x5a
+#undef MC_CMD_0x5a_PRIVILEGE_CTG
#define MC_CMD_0x5a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -14234,8 +19442,10 @@
*/
#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_OFST 0
#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_LEN 4
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_OFST 0
#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_LBN 0
#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_WIDTH 16
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_OFST 0
#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_LBN 16
#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_WIDTH 16
#define MC_CMD_PRIVILEGE_MASK_IN_VF_NULL 0xffff /* enum */
@@ -14274,6 +19484,12 @@
* are not permitted on secure adapters regardless of the privilege mask.
*/
#define MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE 0x4000
+/* enum: Trusted Server Adapter (TSA) / ServerLock. Privilege for
+ * administrator-level operations that are not allowed from the local host once
+ * an adapter has Bound to a remote ServerLock Controller (see doxbox
+ * SF-117064-DG for background).
+ */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN_TSA_UNBOUND 0x8000
/* enum: Set this bit to indicate that a new privilege mask is to be set,
* otherwise the command will only read the existing mask.
*/
@@ -14291,6 +19507,7 @@
* Read/set link state mode of a VF
*/
#define MC_CMD_LINK_STATE_MODE 0x5c
+#undef MC_CMD_0x5c_PRIVILEGE_CTG
#define MC_CMD_0x5c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -14301,8 +19518,10 @@
*/
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_OFST 0
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_LEN 4
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_OFST 0
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_LBN 0
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_WIDTH 16
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_OFST 0
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_LBN 16
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_WIDTH 16
/* New link state mode to be set */
@@ -14327,6 +19546,7 @@
* parameter to MC_CMD_INIT_RXQ.
*/
#define MC_CMD_GET_SNAPSHOT_LENGTH 0x101
+#undef MC_CMD_0x101_PRIVILEGE_CTG
#define MC_CMD_0x101_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -14348,6 +19568,7 @@
* Additional fuse diagnostics
*/
#define MC_CMD_FUSE_DIAGS 0x102
+#undef MC_CMD_0x102_PRIVILEGE_CTG
#define MC_CMD_0x102_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -14401,6 +19622,7 @@
* included in one of the masks provided.
*/
#define MC_CMD_PRIVILEGE_MODIFY 0x60
+#undef MC_CMD_0x60_PRIVILEGE_CTG
#define MC_CMD_0x60_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -14418,8 +19640,10 @@
/* For VFS_OF_PF specify the PF, for ONE specify the target function */
#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_OFST 4
#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_LEN 4
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_PF_OFST 4
#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_PF_LBN 0
#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_PF_WIDTH 16
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_VF_OFST 4
#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_VF_LBN 16
#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_VF_WIDTH 16
/* Privileges to be added to the target functions. For privilege definitions
@@ -14442,6 +19666,7 @@
* Read XPM memory
*/
#define MC_CMD_XPM_READ_BYTES 0x103
+#undef MC_CMD_0x103_PRIVILEGE_CTG
#define MC_CMD_0x103_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -14457,12 +19682,15 @@
/* MC_CMD_XPM_READ_BYTES_OUT msgresponse */
#define MC_CMD_XPM_READ_BYTES_OUT_LENMIN 0
#define MC_CMD_XPM_READ_BYTES_OUT_LENMAX 252
+#define MC_CMD_XPM_READ_BYTES_OUT_LENMAX_MCDI2 1020
#define MC_CMD_XPM_READ_BYTES_OUT_LEN(num) (0+1*(num))
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_NUM(len) (((len)-0)/1)
/* Data */
#define MC_CMD_XPM_READ_BYTES_OUT_DATA_OFST 0
#define MC_CMD_XPM_READ_BYTES_OUT_DATA_LEN 1
#define MC_CMD_XPM_READ_BYTES_OUT_DATA_MINNUM 0
#define MC_CMD_XPM_READ_BYTES_OUT_DATA_MAXNUM 252
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_MAXNUM_MCDI2 1020
/***********************************/
@@ -14470,13 +19698,16 @@
* Write XPM memory
*/
#define MC_CMD_XPM_WRITE_BYTES 0x104
+#undef MC_CMD_0x104_PRIVILEGE_CTG
#define MC_CMD_0x104_PRIVILEGE_CTG SRIOV_CTG_INSECURE
/* MC_CMD_XPM_WRITE_BYTES_IN msgrequest */
#define MC_CMD_XPM_WRITE_BYTES_IN_LENMIN 8
#define MC_CMD_XPM_WRITE_BYTES_IN_LENMAX 252
+#define MC_CMD_XPM_WRITE_BYTES_IN_LENMAX_MCDI2 1020
#define MC_CMD_XPM_WRITE_BYTES_IN_LEN(num) (8+1*(num))
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_NUM(len) (((len)-8)/1)
/* Start address (byte) */
#define MC_CMD_XPM_WRITE_BYTES_IN_ADDR_OFST 0
#define MC_CMD_XPM_WRITE_BYTES_IN_ADDR_LEN 4
@@ -14488,6 +19719,7 @@
#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_LEN 1
#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_MINNUM 0
#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_MAXNUM 244
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_MAXNUM_MCDI2 1012
/* MC_CMD_XPM_WRITE_BYTES_OUT msgresponse */
#define MC_CMD_XPM_WRITE_BYTES_OUT_LEN 0
@@ -14498,6 +19730,7 @@
* Read XPM sector
*/
#define MC_CMD_XPM_READ_SECTOR 0x105
+#undef MC_CMD_0x105_PRIVILEGE_CTG
#define MC_CMD_0x105_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -14513,7 +19746,9 @@
/* MC_CMD_XPM_READ_SECTOR_OUT msgresponse */
#define MC_CMD_XPM_READ_SECTOR_OUT_LENMIN 4
#define MC_CMD_XPM_READ_SECTOR_OUT_LENMAX 36
+#define MC_CMD_XPM_READ_SECTOR_OUT_LENMAX_MCDI2 36
#define MC_CMD_XPM_READ_SECTOR_OUT_LEN(num) (4+1*(num))
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_NUM(len) (((len)-4)/1)
/* Sector type */
#define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_OFST 0
#define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_LEN 4
@@ -14527,6 +19762,7 @@
#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_LEN 1
#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_MINNUM 0
#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_MAXNUM 32
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_MAXNUM_MCDI2 32
/***********************************/
@@ -14534,13 +19770,16 @@
* Write XPM sector
*/
#define MC_CMD_XPM_WRITE_SECTOR 0x106
+#undef MC_CMD_0x106_PRIVILEGE_CTG
#define MC_CMD_0x106_PRIVILEGE_CTG SRIOV_CTG_INSECURE
/* MC_CMD_XPM_WRITE_SECTOR_IN msgrequest */
#define MC_CMD_XPM_WRITE_SECTOR_IN_LENMIN 12
#define MC_CMD_XPM_WRITE_SECTOR_IN_LENMAX 44
+#define MC_CMD_XPM_WRITE_SECTOR_IN_LENMAX_MCDI2 44
#define MC_CMD_XPM_WRITE_SECTOR_IN_LEN(num) (12+1*(num))
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_NUM(len) (((len)-12)/1)
/* If writing fails due to an uncorrectable error, try up to RETRIES following
* sectors (or until no more space available). If 0, only one write attempt is
* made. Note that uncorrectable errors are unlikely, thanks to XPM self-repair
@@ -14563,6 +19802,7 @@
#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_LEN 1
#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_MINNUM 0
#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_MAXNUM 32
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_MAXNUM_MCDI2 32
/* MC_CMD_XPM_WRITE_SECTOR_OUT msgresponse */
#define MC_CMD_XPM_WRITE_SECTOR_OUT_LEN 4
@@ -14576,6 +19816,7 @@
* Invalidate XPM sector
*/
#define MC_CMD_XPM_INVALIDATE_SECTOR 0x107
+#undef MC_CMD_0x107_PRIVILEGE_CTG
#define MC_CMD_0x107_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -14594,6 +19835,7 @@
* Blank-check XPM memory and report bad locations
*/
#define MC_CMD_XPM_BLANK_CHECK 0x108
+#undef MC_CMD_0x108_PRIVILEGE_CTG
#define MC_CMD_0x108_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -14609,7 +19851,9 @@
/* MC_CMD_XPM_BLANK_CHECK_OUT msgresponse */
#define MC_CMD_XPM_BLANK_CHECK_OUT_LENMIN 4
#define MC_CMD_XPM_BLANK_CHECK_OUT_LENMAX 252
+#define MC_CMD_XPM_BLANK_CHECK_OUT_LENMAX_MCDI2 1020
#define MC_CMD_XPM_BLANK_CHECK_OUT_LEN(num) (4+2*(num))
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_NUM(len) (((len)-4)/2)
/* Total number of bad (non-blank) locations */
#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_COUNT_OFST 0
#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_COUNT_LEN 4
@@ -14620,6 +19864,7 @@
#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_LEN 2
#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_MINNUM 0
#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_MAXNUM 124
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_MAXNUM_MCDI2 508
/***********************************/
@@ -14627,6 +19872,7 @@
* Blank-check and repair XPM memory
*/
#define MC_CMD_XPM_REPAIR 0x109
+#undef MC_CMD_0x109_PRIVILEGE_CTG
#define MC_CMD_0x109_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -14649,6 +19895,7 @@
* be performed on an unprogrammed part.
*/
#define MC_CMD_XPM_DECODER_TEST 0x10a
+#undef MC_CMD_0x10a_PRIVILEGE_CTG
#define MC_CMD_0x10a_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -14668,6 +19915,7 @@
* first available location to use, or fail with ENOSPC if none left.
*/
#define MC_CMD_XPM_WRITE_TEST 0x10b
+#undef MC_CMD_0x10b_PRIVILEGE_CTG
#define MC_CMD_0x10b_PRIVILEGE_CTG SRIOV_CTG_INSECURE
@@ -14688,6 +19936,7 @@
* does match, otherwise it will respond with success before it jumps to IMEM.
*/
#define MC_CMD_EXEC_SIGNED 0x10c
+#undef MC_CMD_0x10c_PRIVILEGE_CTG
#define MC_CMD_0x10c_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -14717,6 +19966,7 @@
* MC_CMD_EXEC_SIGNED.
*/
#define MC_CMD_PREPARE_SIGNED 0x10d
+#undef MC_CMD_0x10d_PRIVILEGE_CTG
#define MC_CMD_0x10d_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -14761,16 +20011,20 @@
* cause all functions to see a reset. (Available on Medford only.)
*/
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS 0x117
+#undef MC_CMD_0x117_PRIVILEGE_CTG
#define MC_CMD_0x117_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN msgrequest */
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMIN 4
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX 68
+#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX_MCDI2 68
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LEN(num) (4+4*(num))
+#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_NUM(len) (((len)-4)/4)
/* Flags */
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_FLAGS_OFST 0
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_FLAGS_LEN 2
+#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_UNLOADING_OFST 0
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_UNLOADING_LBN 0
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_UNLOADING_WIDTH 1
/* The number of entries in the ENTRIES array */
@@ -14783,12 +20037,14 @@
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_LEN 4
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MINNUM 0
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM 16
+#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM_MCDI2 16
/* MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT msgresponse */
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN 2
/* Flags */
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_FLAGS_OFST 0
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_FLAGS_LEN 2
+#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_OFST 0
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_LBN 0
#define MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING_WIDTH 1
@@ -14801,6 +20057,7 @@
* priority.
*/
#define MC_CMD_RX_BALANCING 0x118
+#undef MC_CMD_0x118_PRIVILEGE_CTG
#define MC_CMD_0x118_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -14829,13 +20086,16 @@
* if the tag is already present.
*/
#define MC_CMD_NVRAM_PRIVATE_APPEND 0x11c
+#undef MC_CMD_0x11c_PRIVILEGE_CTG
#define MC_CMD_0x11c_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_PRIVATE_APPEND_IN msgrequest */
#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_LENMIN 9
#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_LENMAX 252
+#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_LENMAX_MCDI2 1020
#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_LEN(num) (8+1*(num))
+#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_DATA_BUFFER_NUM(len) (((len)-8)/1)
/* The tag to be appended */
#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_TAG_OFST 0
#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_TAG_LEN 4
@@ -14847,6 +20107,7 @@
#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_DATA_BUFFER_LEN 1
#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_DATA_BUFFER_MINNUM 1
#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_DATA_BUFFER_MAXNUM 244
+#define MC_CMD_NVRAM_PRIVATE_APPEND_IN_DATA_BUFFER_MAXNUM_MCDI2 1012
/* MC_CMD_NVRAM_PRIVATE_APPEND_OUT msgresponse */
#define MC_CMD_NVRAM_PRIVATE_APPEND_OUT_LEN 0
@@ -14859,6 +20120,7 @@
* correctly at ATE.
*/
#define MC_CMD_XPM_VERIFY_CONTENTS 0x11b
+#undef MC_CMD_0x11b_PRIVILEGE_CTG
#define MC_CMD_0x11b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
@@ -14871,7 +20133,9 @@
/* MC_CMD_XPM_VERIFY_CONTENTS_OUT msgresponse */
#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_LENMIN 12
#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_LENMAX 252
+#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_LENMAX_MCDI2 1020
#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_LEN(num) (12+1*(num))
+#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_SIGNATURE_NUM(len) (((len)-12)/1)
/* Number of sectors found (test builds only) */
#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_NUM_SECTORS_OFST 0
#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_NUM_SECTORS_LEN 4
@@ -14886,6 +20150,7 @@
#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_SIGNATURE_LEN 1
#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_SIGNATURE_MINNUM 0
#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_SIGNATURE_MAXNUM 240
+#define MC_CMD_XPM_VERIFY_CONTENTS_OUT_SIGNATURE_MAXNUM_MCDI2 1008
/***********************************/
@@ -14898,6 +20163,7 @@
* and TMR_RELOAD_ACT_NS).
*/
#define MC_CMD_SET_EVQ_TMR 0x120
+#undef MC_CMD_0x120_PRIVILEGE_CTG
#define MC_CMD_0x120_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -14935,6 +20201,7 @@
* Query properties about the event queue timers.
*/
#define MC_CMD_GET_EVQ_TMR_PROPERTIES 0x122
+#undef MC_CMD_0x122_PRIVILEGE_CTG
#define MC_CMD_0x122_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -15003,6 +20270,7 @@
* non used switch buffers.
*/
#define MC_CMD_ALLOCATE_TX_VFIFO_CP 0x11d
+#undef MC_CMD_0x11d_PRIVILEGE_CTG
#define MC_CMD_0x11d_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -15054,6 +20322,7 @@
* previously allocated common pools.
*/
#define MC_CMD_ALLOCATE_TX_VFIFO_VFIFO 0x11e
+#undef MC_CMD_0x11e_PRIVILEGE_CTG
#define MC_CMD_0x11e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -15106,6 +20375,7 @@
* ready to be re-used.
*/
#define MC_CMD_TEARDOWN_TX_VFIFO_VF 0x11f
+#undef MC_CMD_0x11f_PRIVILEGE_CTG
#define MC_CMD_0x11f_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -15125,6 +20395,7 @@
* it ready to be re-used.
*/
#define MC_CMD_DEALLOCATE_TX_VFIFO_CP 0x121
+#undef MC_CMD_0x121_PRIVILEGE_CTG
#define MC_CMD_0x121_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -15144,6 +20415,7 @@
* not yet assigned.
*/
#define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS 0x124
+#undef MC_CMD_0x124_PRIVILEGE_CTG
#define MC_CMD_0x124_PRIVILEGE_CTG SRIOV_CTG_GENERAL
@@ -15160,4 +20432,1537 @@
#define MC_CMD_SWITCH_GET_UNASSIGNED_BUFFERS_OUT_ENG_LEN 4
+/***********************************/
+/* MC_CMD_SUC_VERSION
+ * Get the version of the SUC
+ */
+#define MC_CMD_SUC_VERSION 0x134
+#undef MC_CMD_0x134_PRIVILEGE_CTG
+
+#define MC_CMD_0x134_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_SUC_VERSION_IN msgrequest */
+#define MC_CMD_SUC_VERSION_IN_LEN 0
+
+/* MC_CMD_SUC_VERSION_OUT msgresponse */
+#define MC_CMD_SUC_VERSION_OUT_LEN 24
+/* The SUC firmware version as four numbers - a.b.c.d */
+#define MC_CMD_SUC_VERSION_OUT_VERSION_OFST 0
+#define MC_CMD_SUC_VERSION_OUT_VERSION_LEN 4
+#define MC_CMD_SUC_VERSION_OUT_VERSION_NUM 4
+/* The date, in seconds since the Unix epoch, when the firmware image was
+ * built.
+ */
+#define MC_CMD_SUC_VERSION_OUT_BUILD_DATE_OFST 16
+#define MC_CMD_SUC_VERSION_OUT_BUILD_DATE_LEN 4
+/* The ID of the SUC chip. This is specific to the platform but typically
+ * indicates family, memory sizes etc. See SF-116728-SW for further details.
+ */
+#define MC_CMD_SUC_VERSION_OUT_CHIP_ID_OFST 20
+#define MC_CMD_SUC_VERSION_OUT_CHIP_ID_LEN 4
+
+/* MC_CMD_SUC_BOOT_VERSION_IN msgrequest: Get the version of the SUC boot
+ * loader.
+ */
+#define MC_CMD_SUC_BOOT_VERSION_IN_LEN 4
+#define MC_CMD_SUC_BOOT_VERSION_IN_MAGIC_OFST 0
+#define MC_CMD_SUC_BOOT_VERSION_IN_MAGIC_LEN 4
+/* enum: Requests the SUC boot version. */
+#define MC_CMD_SUC_VERSION_GET_BOOT_VERSION 0xb007700b
+
+/* MC_CMD_SUC_BOOT_VERSION_OUT msgresponse */
+#define MC_CMD_SUC_BOOT_VERSION_OUT_LEN 4
+/* The SUC boot version */
+#define MC_CMD_SUC_BOOT_VERSION_OUT_VERSION_OFST 0
+#define MC_CMD_SUC_BOOT_VERSION_OUT_VERSION_LEN 4
+
+
+/***********************************/
+/* MC_CMD_GET_RX_PREFIX_ID
+ * This command is part of the mechanism for configuring the format of the RX
+ * packet prefix. It takes as input a bitmask of the fields the host would like
+ * to be in the prefix. If the hardware supports RX prefixes with that
+ * combination of fields, then this command returns a list of prefix-ids,
+ * opaque identifiers suitable for use in the RX_PREFIX_ID field of a
+ * MC_CMD_INIT_RXQ_V5_IN message. If the combination of fields is not
+ * supported, returns ENOTSUP. If the firmware can't create any new prefix-ids
+ * due to resource constraints, returns ENOSPC.
+ */
+#define MC_CMD_GET_RX_PREFIX_ID 0x13b
+#undef MC_CMD_0x13b_PRIVILEGE_CTG
+
+#define MC_CMD_0x13b_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_RX_PREFIX_ID_IN msgrequest */
+#define MC_CMD_GET_RX_PREFIX_ID_IN_LEN 8
+/* Field bitmask. */
+#define MC_CMD_GET_RX_PREFIX_ID_IN_FIELDS_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_FIELDS_LEN 8
+#define MC_CMD_GET_RX_PREFIX_ID_IN_FIELDS_LO_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_FIELDS_HI_OFST 4
+#define MC_CMD_GET_RX_PREFIX_ID_IN_LENGTH_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_LENGTH_LBN 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_LENGTH_WIDTH 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH_VALID_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH_VALID_LBN 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH_VALID_WIDTH 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_USER_FLAG_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_USER_FLAG_LBN 2
+#define MC_CMD_GET_RX_PREFIX_ID_IN_USER_FLAG_WIDTH 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_CLASS_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_CLASS_LBN 3
+#define MC_CMD_GET_RX_PREFIX_ID_IN_CLASS_WIDTH 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_PARTIAL_TSTAMP_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_PARTIAL_TSTAMP_LBN 4
+#define MC_CMD_GET_RX_PREFIX_ID_IN_PARTIAL_TSTAMP_WIDTH 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH_LBN 5
+#define MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH_WIDTH 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_USER_MARK_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_USER_MARK_LBN 6
+#define MC_CMD_GET_RX_PREFIX_ID_IN_USER_MARK_WIDTH 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_VPORT_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_VPORT_LBN 7
+#define MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_VPORT_WIDTH 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_CSUM_FRAME_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_CSUM_FRAME_LBN 8
+#define MC_CMD_GET_RX_PREFIX_ID_IN_CSUM_FRAME_WIDTH 1
+#define MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIP_TCI_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIP_TCI_LBN 9
+#define MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIP_TCI_WIDTH 1
+
+/* MC_CMD_GET_RX_PREFIX_ID_OUT msgresponse */
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_LENMIN 8
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_LENMAX 252
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_LENMAX_MCDI2 1020
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_LEN(num) (4+4*(num))
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID_NUM(len) (((len)-4)/4)
+/* Number of prefix-ids returned */
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_NUM_RX_PREFIX_IDS_OFST 0
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_NUM_RX_PREFIX_IDS_LEN 4
+/* Opaque prefix identifiers which can be passed into MC_CMD_INIT_RXQ_V5 or
+ * MC_CMD_QUERY_PREFIX_ID
+ */
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID_OFST 4
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID_LEN 4
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID_MINNUM 1
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID_MAXNUM 62
+#define MC_CMD_GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID_MAXNUM_MCDI2 254
+
+/* RX_PREFIX_FIELD_INFO structuredef: Information about a single RX prefix
+ * field
+ */
+#define RX_PREFIX_FIELD_INFO_LEN 4
+/* The offset of the field from the start of the prefix, in bits */
+#define RX_PREFIX_FIELD_INFO_OFFSET_BITS_OFST 0
+#define RX_PREFIX_FIELD_INFO_OFFSET_BITS_LEN 2
+#define RX_PREFIX_FIELD_INFO_OFFSET_BITS_LBN 0
+#define RX_PREFIX_FIELD_INFO_OFFSET_BITS_WIDTH 16
+/* The width of the field, in bits */
+#define RX_PREFIX_FIELD_INFO_WIDTH_BITS_OFST 2
+#define RX_PREFIX_FIELD_INFO_WIDTH_BITS_LEN 1
+#define RX_PREFIX_FIELD_INFO_WIDTH_BITS_LBN 16
+#define RX_PREFIX_FIELD_INFO_WIDTH_BITS_WIDTH 8
+/* The type of the field. These enum values are in the same order as the fields
+ * in the MC_CMD_GET_RX_PREFIX_ID_IN bitmask
+ */
+#define RX_PREFIX_FIELD_INFO_TYPE_OFST 3
+#define RX_PREFIX_FIELD_INFO_TYPE_LEN 1
+#define RX_PREFIX_FIELD_INFO_LENGTH 0x0 /* enum */
+#define RX_PREFIX_FIELD_INFO_RSS_HASH_VALID 0x1 /* enum */
+#define RX_PREFIX_FIELD_INFO_USER_FLAG 0x2 /* enum */
+#define RX_PREFIX_FIELD_INFO_CLASS 0x3 /* enum */
+#define RX_PREFIX_FIELD_INFO_PARTIAL_TSTAMP 0x4 /* enum */
+#define RX_PREFIX_FIELD_INFO_RSS_HASH 0x5 /* enum */
+#define RX_PREFIX_FIELD_INFO_USER_MARK 0x6 /* enum */
+#define RX_PREFIX_FIELD_INFO_INGRESS_VPORT 0x7 /* enum */
+#define RX_PREFIX_FIELD_INFO_CSUM_FRAME 0x8 /* enum */
+#define RX_PREFIX_FIELD_INFO_VLAN_STRIP_TCI 0x9 /* enum */
+#define RX_PREFIX_FIELD_INFO_TYPE_LBN 24
+#define RX_PREFIX_FIELD_INFO_TYPE_WIDTH 8
+
+/* RX_PREFIX_FIXED_RESPONSE structuredef: Information about an RX prefix in
+ * which every field has a fixed offset and width
+ */
+#define RX_PREFIX_FIXED_RESPONSE_LENMIN 4
+#define RX_PREFIX_FIXED_RESPONSE_LENMAX 252
+#define RX_PREFIX_FIXED_RESPONSE_LENMAX_MCDI2 1020
+#define RX_PREFIX_FIXED_RESPONSE_LEN(num) (4+4*(num))
+#define RX_PREFIX_FIXED_RESPONSE_FIELDS_NUM(len) (((len)-4)/4)
+/* Length of the RX prefix in bytes */
+#define RX_PREFIX_FIXED_RESPONSE_PREFIX_LENGTH_BYTES_OFST 0
+#define RX_PREFIX_FIXED_RESPONSE_PREFIX_LENGTH_BYTES_LEN 1
+#define RX_PREFIX_FIXED_RESPONSE_PREFIX_LENGTH_BYTES_LBN 0
+#define RX_PREFIX_FIXED_RESPONSE_PREFIX_LENGTH_BYTES_WIDTH 8
+/* Number of fields present in the prefix */
+#define RX_PREFIX_FIXED_RESPONSE_FIELD_COUNT_OFST 1
+#define RX_PREFIX_FIXED_RESPONSE_FIELD_COUNT_LEN 1
+#define RX_PREFIX_FIXED_RESPONSE_FIELD_COUNT_LBN 8
+#define RX_PREFIX_FIXED_RESPONSE_FIELD_COUNT_WIDTH 8
+#define RX_PREFIX_FIXED_RESPONSE_RESERVED_OFST 2
+#define RX_PREFIX_FIXED_RESPONSE_RESERVED_LEN 2
+#define RX_PREFIX_FIXED_RESPONSE_RESERVED_LBN 16
+#define RX_PREFIX_FIXED_RESPONSE_RESERVED_WIDTH 16
+/* Array of RX_PREFIX_FIELD_INFO structures, of length FIELD_COUNT */
+#define RX_PREFIX_FIXED_RESPONSE_FIELDS_OFST 4
+#define RX_PREFIX_FIXED_RESPONSE_FIELDS_LEN 4
+#define RX_PREFIX_FIXED_RESPONSE_FIELDS_MINNUM 0
+#define RX_PREFIX_FIXED_RESPONSE_FIELDS_MAXNUM 62
+#define RX_PREFIX_FIXED_RESPONSE_FIELDS_MAXNUM_MCDI2 254
+#define RX_PREFIX_FIXED_RESPONSE_FIELDS_LBN 32
+#define RX_PREFIX_FIXED_RESPONSE_FIELDS_WIDTH 32
+
+
+/***********************************/
+/* MC_CMD_QUERY_RX_PREFIX_ID
+ * This command takes an RX prefix id (obtained from MC_CMD_GET_RX_PREFIX_ID)
+ * and returns a description of the RX prefix of packets delievered to an RXQ
+ * created with that prefix id
+ */
+#define MC_CMD_QUERY_RX_PREFIX_ID 0x13c
+#undef MC_CMD_0x13c_PRIVILEGE_CTG
+
+#define MC_CMD_0x13c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_QUERY_RX_PREFIX_ID_IN msgrequest */
+#define MC_CMD_QUERY_RX_PREFIX_ID_IN_LEN 4
+/* Prefix id to query */
+#define MC_CMD_QUERY_RX_PREFIX_ID_IN_RX_PREFIX_ID_OFST 0
+#define MC_CMD_QUERY_RX_PREFIX_ID_IN_RX_PREFIX_ID_LEN 4
+
+/* MC_CMD_QUERY_RX_PREFIX_ID_OUT msgresponse */
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMIN 4
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMAX 252
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMAX_MCDI2 1020
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_LEN(num) (4+1*(num))
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_NUM(len) (((len)-4)/1)
+/* An enum describing the structure of this response. */
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_TYPE_OFST 0
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_TYPE_LEN 1
+/* enum: The response is of format RX_PREFIX_FIXED_RESPONSE */
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_TYPE_FIXED 0x0
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESERVED_OFST 1
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESERVED_LEN 3
+/* The response. Its format is as defined by the RESPONSE_TYPE value */
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_OFST 4
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_LEN 1
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_MINNUM 0
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_MAXNUM 248
+#define MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_MAXNUM_MCDI2 1016
+
+
+/***********************************/
+/* MC_CMD_BUNDLE
+ * A command to perform various bundle-related operations on insecure cards.
+ */
+#define MC_CMD_BUNDLE 0x13d
+#undef MC_CMD_0x13d_PRIVILEGE_CTG
+
+#define MC_CMD_0x13d_PRIVILEGE_CTG SRIOV_CTG_INSECURE
+
+/* MC_CMD_BUNDLE_IN msgrequest */
+#define MC_CMD_BUNDLE_IN_LEN 4
+/* Sub-command code */
+#define MC_CMD_BUNDLE_IN_OP_OFST 0
+#define MC_CMD_BUNDLE_IN_OP_LEN 4
+/* enum: Get the current host access mode set on component partitions. */
+#define MC_CMD_BUNDLE_IN_OP_COMPONENT_ACCESS_GET 0x0
+/* enum: Set the host access mode set on component partitions. */
+#define MC_CMD_BUNDLE_IN_OP_COMPONENT_ACCESS_SET 0x1
+
+/* MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_GET_IN msgrequest: Retrieve the current
+ * access mode on component partitions such as MC_FIRMWARE, SUC_FIRMWARE and
+ * EXPANSION_UEFI. This command only works on engineering (insecure) cards. On
+ * secure adapters, this command returns MC_CMD_ERR_EPERM.
+ */
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_GET_IN_LEN 4
+/* Sub-command code. Must be OP_COMPONENT_ACCESS_GET. */
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_GET_IN_OP_OFST 0
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_GET_IN_OP_LEN 4
+
+/* MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_GET_OUT msgresponse: Returns the access
+ * control mode.
+ */
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_GET_OUT_LEN 4
+/* Access mode of component partitions. */
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_GET_OUT_ACCESS_MODE_OFST 0
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_GET_OUT_ACCESS_MODE_LEN 4
+/* enum: Component partitions are read-only from the host. */
+#define MC_CMD_BUNDLE_COMPONENTS_READ_ONLY 0x0
+/* enum: Component partitions can read read-from written-to by the host. */
+#define MC_CMD_BUNDLE_COMPONENTS_READ_WRITE 0x1
+
+/* MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_SET_IN msgrequest: The component
+ * partitions such as MC_FIRMWARE, SUC_FIRMWARE, EXPANSION_UEFI are set as
+ * read-only on firmware built with bundle support. This command marks these
+ * partitions as read/writeable. The access status set by this command does not
+ * persist across MC reboots. This command only works on engineering (insecure)
+ * cards. On secure adapters, this command returns MC_CMD_ERR_EPERM.
+ */
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_SET_IN_LEN 8
+/* Sub-command code. Must be OP_COMPONENT_ACCESS_SET. */
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_SET_IN_OP_OFST 0
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_SET_IN_OP_LEN 4
+/* Access mode of component partitions. */
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_SET_IN_ACCESS_MODE_OFST 4
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_SET_IN_ACCESS_MODE_LEN 4
+/* Enum values, see field(s): */
+/* MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_GET_OUT/ACCESS_MODE */
+
+/* MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_SET_OUT msgresponse */
+#define MC_CMD_BUNDLE_OP_COMPONENT_ACCESS_SET_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_VPD
+ * Read all VPD starting from a given address
+ */
+#define MC_CMD_GET_VPD 0x165
+#undef MC_CMD_0x165_PRIVILEGE_CTG
+
+#define MC_CMD_0x165_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_VPD_IN msgresponse */
+#define MC_CMD_GET_VPD_IN_LEN 4
+/* VPD address to start from. In case VPD is longer than MCDI buffer
+ * (unlikely), user can make multiple calls with different starting addresses.
+ */
+#define MC_CMD_GET_VPD_IN_ADDR_OFST 0
+#define MC_CMD_GET_VPD_IN_ADDR_LEN 4
+
+/* MC_CMD_GET_VPD_OUT msgresponse */
+#define MC_CMD_GET_VPD_OUT_LENMIN 0
+#define MC_CMD_GET_VPD_OUT_LENMAX 252
+#define MC_CMD_GET_VPD_OUT_LENMAX_MCDI2 1020
+#define MC_CMD_GET_VPD_OUT_LEN(num) (0+1*(num))
+#define MC_CMD_GET_VPD_OUT_DATA_NUM(len) (((len)-0)/1)
+/* VPD data returned. */
+#define MC_CMD_GET_VPD_OUT_DATA_OFST 0
+#define MC_CMD_GET_VPD_OUT_DATA_LEN 1
+#define MC_CMD_GET_VPD_OUT_DATA_MINNUM 0
+#define MC_CMD_GET_VPD_OUT_DATA_MAXNUM 252
+#define MC_CMD_GET_VPD_OUT_DATA_MAXNUM_MCDI2 1020
+
+
+/***********************************/
+/* MC_CMD_GET_NCSI_INFO
+ * Provide information about the NC-SI stack
+ */
+#define MC_CMD_GET_NCSI_INFO 0x167
+#undef MC_CMD_0x167_PRIVILEGE_CTG
+
+#define MC_CMD_0x167_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_NCSI_INFO_IN msgrequest */
+#define MC_CMD_GET_NCSI_INFO_IN_LEN 8
+/* Operation to be performed */
+#define MC_CMD_GET_NCSI_INFO_IN_OP_OFST 0
+#define MC_CMD_GET_NCSI_INFO_IN_OP_LEN 4
+/* enum: Information on the link settings. */
+#define MC_CMD_GET_NCSI_INFO_IN_OP_LINK 0x0
+/* enum: Statistics associated with the channel */
+#define MC_CMD_GET_NCSI_INFO_IN_OP_STATISTICS 0x1
+/* The NC-SI channel on which the operation is to be performed */
+#define MC_CMD_GET_NCSI_INFO_IN_CHANNEL_OFST 4
+#define MC_CMD_GET_NCSI_INFO_IN_CHANNEL_LEN 4
+
+/* MC_CMD_GET_NCSI_INFO_LINK_OUT msgresponse */
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_LEN 12
+/* Settings as received from BMC. */
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_SETTINGS_OFST 0
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_SETTINGS_LEN 4
+/* Advertised capabilities applied to channel. */
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_ADV_CAP_OFST 4
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_ADV_CAP_LEN 4
+/* General status */
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_STATUS_OFST 8
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_STATUS_LEN 4
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_STATE_OFST 8
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_STATE_LBN 0
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_STATE_WIDTH 2
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_ENABLE_OFST 8
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_ENABLE_LBN 2
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_ENABLE_WIDTH 1
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_NETWORK_TX_OFST 8
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_NETWORK_TX_LBN 3
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_NETWORK_TX_WIDTH 1
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_ATTACHED_OFST 8
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_ATTACHED_LBN 4
+#define MC_CMD_GET_NCSI_INFO_LINK_OUT_ATTACHED_WIDTH 1
+
+/* MC_CMD_GET_NCSI_INFO_STATISTICS_OUT msgresponse */
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_LEN 28
+/* The number of NC-SI commands received. */
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_CMDS_RX_OFST 0
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_CMDS_RX_LEN 4
+/* The number of NC-SI commands dropped. */
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_PKTS_DROPPED_OFST 4
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_PKTS_DROPPED_LEN 4
+/* The number of invalid NC-SI commands received. */
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_CMD_TYPE_ERRS_OFST 8
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_CMD_TYPE_ERRS_LEN 4
+/* The number of checksum errors seen. */
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_CMD_CSUM_ERRS_OFST 12
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_CMD_CSUM_ERRS_LEN 4
+/* The number of NC-SI requests received. */
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_RX_PKTS_OFST 16
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_RX_PKTS_LEN 4
+/* The number of NC-SI responses sent (includes AENs) */
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_TX_PKTS_OFST 20
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_NCSI_TX_PKTS_LEN 4
+/* The number of NC-SI AENs sent */
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_AENS_SENT_OFST 24
+#define MC_CMD_GET_NCSI_INFO_STATISTICS_OUT_AENS_SENT_LEN 4
+
+
+/* CLOCK_INFO structuredef: Information about a single hardware clock */
+#define CLOCK_INFO_LEN 28
+/* Enumeration that uniquely identifies the clock */
+#define CLOCK_INFO_CLOCK_ID_OFST 0
+#define CLOCK_INFO_CLOCK_ID_LEN 2
+/* enum: The Riverhead CMC (card MC) */
+#define CLOCK_INFO_CLOCK_CMC 0x0
+/* enum: The Riverhead NMC (network MC) */
+#define CLOCK_INFO_CLOCK_NMC 0x1
+/* enum: The Riverhead SDNET slice main logic */
+#define CLOCK_INFO_CLOCK_SDNET 0x2
+/* enum: The Riverhead SDNET LUT */
+#define CLOCK_INFO_CLOCK_SDNET_LUT 0x3
+/* enum: The Riverhead SDNET control logic */
+#define CLOCK_INFO_CLOCK_SDNET_CTRL 0x4
+/* enum: The Riverhead Streaming SubSystem */
+#define CLOCK_INFO_CLOCK_SSS 0x5
+/* enum: The Riverhead network MAC and associated CSR registers */
+#define CLOCK_INFO_CLOCK_MAC 0x6
+#define CLOCK_INFO_CLOCK_ID_LBN 0
+#define CLOCK_INFO_CLOCK_ID_WIDTH 16
+/* Assorted flags */
+#define CLOCK_INFO_FLAGS_OFST 2
+#define CLOCK_INFO_FLAGS_LEN 2
+#define CLOCK_INFO_SETTABLE_OFST 2
+#define CLOCK_INFO_SETTABLE_LBN 0
+#define CLOCK_INFO_SETTABLE_WIDTH 1
+#define CLOCK_INFO_FLAGS_LBN 16
+#define CLOCK_INFO_FLAGS_WIDTH 16
+/* The frequency in HZ */
+#define CLOCK_INFO_FREQUENCY_OFST 4
+#define CLOCK_INFO_FREQUENCY_LEN 8
+#define CLOCK_INFO_FREQUENCY_LO_OFST 4
+#define CLOCK_INFO_FREQUENCY_HI_OFST 8
+#define CLOCK_INFO_FREQUENCY_LBN 32
+#define CLOCK_INFO_FREQUENCY_WIDTH 64
+/* Human-readable ASCII name for clock, with NUL termination */
+#define CLOCK_INFO_NAME_OFST 12
+#define CLOCK_INFO_NAME_LEN 1
+#define CLOCK_INFO_NAME_NUM 16
+#define CLOCK_INFO_NAME_LBN 96
+#define CLOCK_INFO_NAME_WIDTH 8
+
+
+/***********************************/
+/* MC_CMD_GET_CLOCKS_INFO
+ * Get information about the device clocks
+ */
+#define MC_CMD_GET_CLOCKS_INFO 0x166
+#undef MC_CMD_0x166_PRIVILEGE_CTG
+
+#define MC_CMD_0x166_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_CLOCKS_INFO_IN msgrequest */
+#define MC_CMD_GET_CLOCKS_INFO_IN_LEN 0
+
+/* MC_CMD_GET_CLOCKS_INFO_OUT msgresponse */
+#define MC_CMD_GET_CLOCKS_INFO_OUT_LENMIN 0
+#define MC_CMD_GET_CLOCKS_INFO_OUT_LENMAX 252
+#define MC_CMD_GET_CLOCKS_INFO_OUT_LENMAX_MCDI2 1008
+#define MC_CMD_GET_CLOCKS_INFO_OUT_LEN(num) (0+28*(num))
+#define MC_CMD_GET_CLOCKS_INFO_OUT_INFOS_NUM(len) (((len)-0)/28)
+/* An array of CLOCK_INFO structures. */
+#define MC_CMD_GET_CLOCKS_INFO_OUT_INFOS_OFST 0
+#define MC_CMD_GET_CLOCKS_INFO_OUT_INFOS_LEN 28
+#define MC_CMD_GET_CLOCKS_INFO_OUT_INFOS_MINNUM 0
+#define MC_CMD_GET_CLOCKS_INFO_OUT_INFOS_MAXNUM 9
+#define MC_CMD_GET_CLOCKS_INFO_OUT_INFOS_MAXNUM_MCDI2 36
+
+
+/***********************************/
+/* MC_CMD_VNIC_ENCAP_RULE_ADD
+ * Add a rule for detecting encapsulations in the VNIC stage. Currently this only affects checksum validation in VNIC RX - on TX the send descriptor explicitly specifies encapsulation. These rules are per-VNIC, i.e. only apply to the current driver. If a rule matches, then the packet is considered to have the corresponding encapsulation type, and the inner packet is parsed. It is up to the driver to ensure that overlapping rules are not inserted. (If a packet would match multiple rules, a random one of them will be used.) A rule with the exact same match criteria may not be inserted twice (EALREADY). Only a limited number MATCH_FLAGS values are supported, use MC_CMD_GET_PARSER_DISP_INFO with OP OP_GET_SUPPORTED_VNIC_ENCAP_RULE_MATCHES to get a list of supported combinations. Each driver may only have a limited set of active rules - returns ENOSPC if the caller's table is full.
+ */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD 0x16d
+#undef MC_CMD_0x16d_PRIVILEGE_CTG
+
+#define MC_CMD_0x16d_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VNIC_ENCAP_RULE_ADD_IN msgrequest */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_LEN 36
+/* Set to MAE_MPORT_SELECTOR_ASSIGNED. In the future this may be relaxed. */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MPORT_SELECTOR_OFST 0
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MPORT_SELECTOR_LEN 4
+/* Any non-zero bits other than the ones named below or an unsupported
+ * combination will cause the NIC to return EOPNOTSUPP. In the future more
+ * flags may be added.
+ */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_FLAGS_OFST 4
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_FLAGS_LEN 4
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_ETHER_TYPE_OFST 4
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_ETHER_TYPE_LBN 0
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_ETHER_TYPE_WIDTH 1
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_OUTER_VLAN_OFST 4
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_OUTER_VLAN_LBN 1
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_OUTER_VLAN_WIDTH 1
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_DST_IP_OFST 4
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_DST_IP_LBN 2
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_DST_IP_WIDTH 1
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_IP_PROTO_OFST 4
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_IP_PROTO_LBN 3
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_IP_PROTO_WIDTH 1
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_DST_PORT_OFST 4
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_DST_PORT_LBN 4
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_MATCH_DST_PORT_WIDTH 1
+/* Only if MATCH_ETHER_TYPE is set. Ethertype value as bytes in network order.
+ * Currently only IPv4 (0x0800) and IPv6 (0x86DD) ethertypes may be used.
+ */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_ETHER_TYPE_OFST 8
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_ETHER_TYPE_LEN 2
+/* Only if MATCH_OUTER_VLAN is set. VID value as bytes in network order.
+ * (Deprecated)
+ */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_OUTER_VLAN_LBN 80
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_OUTER_VLAN_WIDTH 12
+/* Only if MATCH_OUTER_VLAN is set. Aligned wrapper for OUTER_VLAN_VID. */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_OUTER_VLAN_WORD_OFST 10
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_OUTER_VLAN_WORD_LEN 2
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_OUTER_VLAN_VID_OFST 10
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_OUTER_VLAN_VID_LBN 0
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_OUTER_VLAN_VID_WIDTH 12
+/* Only if MATCH_DST_IP is set. IP address as bytes in network order. In the
+ * case of IPv4, the IP should be in the first 4 bytes and all other bytes
+ * should be zero.
+ */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_DST_IP_OFST 12
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_DST_IP_LEN 16
+/* Only if MATCH_IP_PROTO is set. Currently only UDP proto (17) may be used. */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_IP_PROTO_OFST 28
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_IP_PROTO_LEN 1
+/* Actions that should be applied to packets match the rule. */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_ACTION_FLAGS_OFST 29
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_ACTION_FLAGS_LEN 1
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_STRIP_OUTER_VLAN_OFST 29
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_STRIP_OUTER_VLAN_LBN 0
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_STRIP_OUTER_VLAN_WIDTH 1
+/* Only if MATCH_DST_PORT is set. Port number as bytes in network order. */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_DST_PORT_OFST 30
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_DST_PORT_LEN 2
+/* Resulting encapsulation type, as per MAE_MCDI_ENCAP_TYPE enumeration. */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_ENCAP_TYPE_OFST 32
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_ENCAP_TYPE_LEN 4
+
+/* MC_CMD_VNIC_ENCAP_RULE_ADD_OUT msgresponse */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_OUT_LEN 4
+/* Handle to inserted rule. Used for removing the rule. */
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_OUT_HANDLE_OFST 0
+#define MC_CMD_VNIC_ENCAP_RULE_ADD_OUT_HANDLE_LEN 4
+
+
+/***********************************/
+/* MC_CMD_VNIC_ENCAP_RULE_REMOVE
+ * Remove a VNIC encapsulation rule. Packets which would have previously matched the rule will then be considered as unencapsulated. Returns EALREADY if the input HANDLE doesn't correspond to an existing rule.
+ */
+#define MC_CMD_VNIC_ENCAP_RULE_REMOVE 0x16e
+#undef MC_CMD_0x16e_PRIVILEGE_CTG
+
+#define MC_CMD_0x16e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VNIC_ENCAP_RULE_REMOVE_IN msgrequest */
+#define MC_CMD_VNIC_ENCAP_RULE_REMOVE_IN_LEN 4
+/* Handle which was returned by MC_CMD_VNIC_ENCAP_RULE_ADD. */
+#define MC_CMD_VNIC_ENCAP_RULE_REMOVE_IN_HANDLE_OFST 0
+#define MC_CMD_VNIC_ENCAP_RULE_REMOVE_IN_HANDLE_LEN 4
+
+/* MC_CMD_VNIC_ENCAP_RULE_REMOVE_OUT msgresponse */
+#define MC_CMD_VNIC_ENCAP_RULE_REMOVE_OUT_LEN 0
+
+/* FUNCTION_PERSONALITY structuredef: The meanings of the personalities are
+ * defined in SF-120734-TC with more information in SF-122717-TC.
+ */
+#define FUNCTION_PERSONALITY_LEN 4
+#define FUNCTION_PERSONALITY_ID_OFST 0
+#define FUNCTION_PERSONALITY_ID_LEN 4
+/* enum: Function has no assigned personality */
+#define FUNCTION_PERSONALITY_NULL 0x0
+/* enum: Function has an EF100-style function control window and VI windows
+ * with both EF100 and vDPA doorbells.
+ */
+#define FUNCTION_PERSONALITY_EF100 0x1
+/* enum: Function has virtio net device configuration registers and doorbells
+ * for virtio queue pairs.
+ */
+#define FUNCTION_PERSONALITY_VIRTIO_NET 0x2
+/* enum: Function has virtio block device configuration registers and a
+ * doorbell for a single virtqueue.
+ */
+#define FUNCTION_PERSONALITY_VIRTIO_BLK 0x3
+/* enum: Function is a Xilinx acceleration device - management function */
+#define FUNCTION_PERSONALITY_ACCEL_MGMT 0x4
+/* enum: Function is a Xilinx acceleration device - user function */
+#define FUNCTION_PERSONALITY_ACCEL_USR 0x5
+#define FUNCTION_PERSONALITY_ID_LBN 0
+#define FUNCTION_PERSONALITY_ID_WIDTH 32
+
+
+/***********************************/
+/* MC_CMD_VIRTIO_GET_FEATURES
+ * Get a list of the virtio features supported by the device.
+ */
+#define MC_CMD_VIRTIO_GET_FEATURES 0x168
+#undef MC_CMD_0x168_PRIVILEGE_CTG
+
+#define MC_CMD_0x168_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VIRTIO_GET_FEATURES_IN msgrequest */
+#define MC_CMD_VIRTIO_GET_FEATURES_IN_LEN 4
+/* Type of device to get features for. Matches the device id as defined by the
+ * virtio spec.
+ */
+#define MC_CMD_VIRTIO_GET_FEATURES_IN_DEVICE_ID_OFST 0
+#define MC_CMD_VIRTIO_GET_FEATURES_IN_DEVICE_ID_LEN 4
+/* enum: Reserved. Do not use. */
+#define MC_CMD_VIRTIO_GET_FEATURES_IN_RESERVED 0x0
+/* enum: Net device. */
+#define MC_CMD_VIRTIO_GET_FEATURES_IN_NET 0x1
+/* enum: Block device. */
+#define MC_CMD_VIRTIO_GET_FEATURES_IN_BLOCK 0x2
+
+/* MC_CMD_VIRTIO_GET_FEATURES_OUT msgresponse */
+#define MC_CMD_VIRTIO_GET_FEATURES_OUT_LEN 8
+/* Features supported by the device. The result is a bitfield in the format of
+ * the feature bits of the specified device type as defined in the virtIO 1.1
+ * specification ( https://docs.oasis-
+ * open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.pdf )
+ */
+#define MC_CMD_VIRTIO_GET_FEATURES_OUT_FEATURES_OFST 0
+#define MC_CMD_VIRTIO_GET_FEATURES_OUT_FEATURES_LEN 8
+#define MC_CMD_VIRTIO_GET_FEATURES_OUT_FEATURES_LO_OFST 0
+#define MC_CMD_VIRTIO_GET_FEATURES_OUT_FEATURES_HI_OFST 4
+
+
+/***********************************/
+/* MC_CMD_VIRTIO_TEST_FEATURES
+ * Query whether a given set of features is supported. Fails with ENOSUP if the
+ * driver requests a feature the device doesn't support. Fails with EINVAL if
+ * the driver fails to request a feature which the device requires.
+ */
+#define MC_CMD_VIRTIO_TEST_FEATURES 0x169
+#undef MC_CMD_0x169_PRIVILEGE_CTG
+
+#define MC_CMD_0x169_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VIRTIO_TEST_FEATURES_IN msgrequest */
+#define MC_CMD_VIRTIO_TEST_FEATURES_IN_LEN 16
+/* Type of device to test features for. Matches the device id as defined by the
+ * virtio spec.
+ */
+#define MC_CMD_VIRTIO_TEST_FEATURES_IN_DEVICE_ID_OFST 0
+#define MC_CMD_VIRTIO_TEST_FEATURES_IN_DEVICE_ID_LEN 4
+/* Enum values, see field(s): */
+/* MC_CMD_VIRTIO_GET_FEATURES/MC_CMD_VIRTIO_GET_FEATURES_IN/DEVICE_ID */
+#define MC_CMD_VIRTIO_TEST_FEATURES_IN_RESERVED_OFST 4
+#define MC_CMD_VIRTIO_TEST_FEATURES_IN_RESERVED_LEN 4
+/* Features requested. Same format as the returned value from
+ * MC_CMD_VIRTIO_GET_FEATURES.
+ */
+#define MC_CMD_VIRTIO_TEST_FEATURES_IN_FEATURES_OFST 8
+#define MC_CMD_VIRTIO_TEST_FEATURES_IN_FEATURES_LEN 8
+#define MC_CMD_VIRTIO_TEST_FEATURES_IN_FEATURES_LO_OFST 8
+#define MC_CMD_VIRTIO_TEST_FEATURES_IN_FEATURES_HI_OFST 12
+
+/* MC_CMD_VIRTIO_TEST_FEATURES_OUT msgresponse */
+#define MC_CMD_VIRTIO_TEST_FEATURES_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VIRTIO_INIT_QUEUE
+ * Create a virtio virtqueue. Fails with EALREADY if the queue already exists.
+ * Fails with ENOSUP if a feature is requested that isn't supported. Fails with
+ * EINVAL if a required feature isn't requested, or any other parameter is
+ * invalid.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE 0x16a
+#undef MC_CMD_0x16a_PRIVILEGE_CTG
+
+#define MC_CMD_0x16a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VIRTIO_INIT_QUEUE_REQ msgrequest */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_LEN 68
+/* Type of virtqueue to create. A network rxq and a txq can exist at the same
+ * time on a single VI.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_QUEUE_TYPE_OFST 0
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_QUEUE_TYPE_LEN 1
+/* enum: A network device receive queue */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_NET_RXQ 0x0
+/* enum: A network device transmit queue */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_NET_TXQ 0x1
+/* enum: A block device request queue */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_BLOCK 0x2
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_RESERVED_OFST 1
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_RESERVED_LEN 1
+/* If the calling function is a PF and this field is not VF_NULL, create the
+ * queue on the specified child VF instead of on the PF.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_TARGET_VF_OFST 2
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_TARGET_VF_LEN 2
+/* enum: No VF, create queue on the PF. */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_VF_NULL 0xffff
+/* Desired instance. This is the function-local index of the associated VI, not
+ * the virtqueue number as counted by the virtqueue spec.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_INSTANCE_OFST 4
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_INSTANCE_LEN 4
+/* Queue size, in entries. Must be a power of two. */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_SIZE_OFST 8
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_SIZE_LEN 4
+/* Flags */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_FLAGS_OFST 12
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_FLAGS_LEN 4
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_USE_PASID_OFST 12
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_USE_PASID_LBN 0
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_USE_PASID_WIDTH 1
+/* Address of the descriptor table in the virtqueue. */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_DESC_TBL_ADDR_OFST 16
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_DESC_TBL_ADDR_LEN 8
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_DESC_TBL_ADDR_LO_OFST 16
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_DESC_TBL_ADDR_HI_OFST 20
+/* Address of the available ring in the virtqueue. */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_AVAIL_RING_ADDR_OFST 24
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_AVAIL_RING_ADDR_LEN 8
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_AVAIL_RING_ADDR_LO_OFST 24
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_AVAIL_RING_ADDR_HI_OFST 28
+/* Address of the used ring in the virtqueue. */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_USED_RING_ADDR_OFST 32
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_USED_RING_ADDR_LEN 8
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_USED_RING_ADDR_LO_OFST 32
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_USED_RING_ADDR_HI_OFST 36
+/* PASID to use on PCIe transactions involving this queue. Ignored if the
+ * USE_PASID flag is not set.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_PASID_OFST 40
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_PASID_LEN 4
+/* Which MSIX vector to use for this virtqueue, or NO_VECTOR if MSIX should not
+ * be used.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_MSIX_VECTOR_OFST 44
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_MSIX_VECTOR_LEN 2
+/* enum: Do not enable interrupts for this virtqueue */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_NO_VECTOR 0xffff
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_RESERVED2_OFST 46
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_RESERVED2_LEN 2
+/* Virtio features to apply to this queue. Same format as the in the virtio
+ * spec and in the return from MC_CMD_VIRTIO_GET_FEATURES. Must be a subset of
+ * the features returned from MC_CMD_VIRTIO_GET_FEATURES. Features are per-
+ * queue because with vDPA multiple queues on the same function can be passed
+ * through to different virtual hosts as independent devices.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_FEATURES_OFST 48
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_FEATURES_LEN 8
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_FEATURES_LO_OFST 48
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_FEATURES_HI_OFST 52
+/* Enum values, see field(s): */
+/* MC_CMD_VIRTIO_GET_FEATURES/MC_CMD_VIRTIO_GET_FEATURES_OUT/FEATURES */
+/* The inital producer index for this queue's used ring. If this queue is being
+ * created to be migrated into, this should be the FINAL_PIDX value returned by
+ * MC_CMD_VIRTIO_FINI_QUEUE of the queue being migrated from. Otherwise, it
+ * should be zero.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_INITIAL_PIDX_OFST 56
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_INITIAL_PIDX_LEN 4
+/* The inital consumer index for this queue's available ring. If this queue is
+ * being created to be migrated into, this should be the FINAL_CIDX value
+ * returned by MC_CMD_VIRTIO_FINI_QUEUE of the queue being migrated from.
+ * Otherwise, it should be zero.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_INITIAL_CIDX_OFST 60
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_INITIAL_CIDX_LEN 4
+/* A MAE_MPORT_SELECTOR defining which mport this queue should be associated
+ * with. Use MAE_MPORT_SELECTOR_ASSIGNED to request the default mport for the
+ * function this queue is being created on.
+ */
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_MPORT_SELECTOR_OFST 64
+#define MC_CMD_VIRTIO_INIT_QUEUE_REQ_MPORT_SELECTOR_LEN 4
+
+/* MC_CMD_VIRTIO_INIT_QUEUE_RESP msgresponse */
+#define MC_CMD_VIRTIO_INIT_QUEUE_RESP_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VIRTIO_FINI_QUEUE
+ * Destroy a virtio virtqueue
+ */
+#define MC_CMD_VIRTIO_FINI_QUEUE 0x16b
+#undef MC_CMD_0x16b_PRIVILEGE_CTG
+
+#define MC_CMD_0x16b_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VIRTIO_FINI_QUEUE_REQ msgrequest */
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_LEN 8
+/* Type of virtqueue to destroy. */
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_QUEUE_TYPE_OFST 0
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_QUEUE_TYPE_LEN 1
+/* Enum values, see field(s): */
+/* MC_CMD_VIRTIO_INIT_QUEUE/MC_CMD_VIRTIO_INIT_QUEUE_REQ/QUEUE_TYPE */
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_RESERVED_OFST 1
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_RESERVED_LEN 1
+/* If the calling function is a PF and this field is not VF_NULL, destroy the
+ * queue on the specified child VF instead of on the PF.
+ */
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_TARGET_VF_OFST 2
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_TARGET_VF_LEN 2
+/* enum: No VF, destroy the queue on the PF. */
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_VF_NULL 0xffff
+/* Instance to destroy */
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_INSTANCE_OFST 4
+#define MC_CMD_VIRTIO_FINI_QUEUE_REQ_INSTANCE_LEN 4
+
+/* MC_CMD_VIRTIO_FINI_QUEUE_RESP msgresponse */
+#define MC_CMD_VIRTIO_FINI_QUEUE_RESP_LEN 8
+/* The producer index of the used ring when the queue was stopped. */
+#define MC_CMD_VIRTIO_FINI_QUEUE_RESP_FINAL_PIDX_OFST 0
+#define MC_CMD_VIRTIO_FINI_QUEUE_RESP_FINAL_PIDX_LEN 4
+/* The consumer index of the available ring when the queue was stopped. */
+#define MC_CMD_VIRTIO_FINI_QUEUE_RESP_FINAL_CIDX_OFST 4
+#define MC_CMD_VIRTIO_FINI_QUEUE_RESP_FINAL_CIDX_LEN 4
+
+
+/***********************************/
+/* MC_CMD_VIRTIO_GET_DOORBELL_OFFSET
+ * Get the offset in the BAR of the doorbells for a VI. Doesn't require the
+ * queue(s) to be allocated.
+ */
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET 0x16c
+#undef MC_CMD_0x16c_PRIVILEGE_CTG
+
+#define MC_CMD_0x16c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ msgrequest */
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_LEN 8
+/* Type of device to get information for. Matches the device id as defined by
+ * the virtio spec.
+ */
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_DEVICE_ID_OFST 0
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_DEVICE_ID_LEN 1
+/* Enum values, see field(s): */
+/* MC_CMD_VIRTIO_GET_FEATURES/MC_CMD_VIRTIO_GET_FEATURES_IN/DEVICE_ID */
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_RESERVED_OFST 1
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_RESERVED_LEN 1
+/* If the calling function is a PF and this field is not VF_NULL, query the VI
+ * on the specified child VF instead of on the PF.
+ */
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_TARGET_VF_OFST 2
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_TARGET_VF_LEN 2
+/* enum: No VF, query the PF. */
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_VF_NULL 0xffff
+/* VI instance to query */
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_INSTANCE_OFST 4
+#define MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_INSTANCE_LEN 4
+
+/* MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP msgresponse */
+#define MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_LEN 8
+/* Offset of RX doorbell in BAR */
+#define MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_RX_DBL_OFFSET_OFST 0
+#define MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_RX_DBL_OFFSET_LEN 4
+/* Offset of TX doorbell in BAR */
+#define MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_TX_DBL_OFFSET_OFST 4
+#define MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_TX_DBL_OFFSET_LEN 4
+
+/* MC_CMD_VIRTIO_GET_BLOCK_DOORBELL_OFFSET_RESP msgresponse */
+#define MC_CMD_VIRTIO_GET_BLOCK_DOORBELL_OFFSET_RESP_LEN 4
+/* Offset of request doorbell in BAR */
+#define MC_CMD_VIRTIO_GET_BLOCK_DOORBELL_OFFSET_RESP_DBL_OFFSET_OFST 0
+#define MC_CMD_VIRTIO_GET_BLOCK_DOORBELL_OFFSET_RESP_DBL_OFFSET_LEN 4
+
+/* PCIE_FUNCTION structuredef: Structure representing a PCIe function ID
+ * (interface/PF/VF tuple)
+ */
+#define PCIE_FUNCTION_LEN 8
+/* PCIe PF function number */
+#define PCIE_FUNCTION_PF_OFST 0
+#define PCIE_FUNCTION_PF_LEN 2
+/* enum: Wildcard value representing any available function (e.g in resource
+ * allocation requests)
+ */
+#define PCIE_FUNCTION_PF_ANY 0xfffe
+/* enum: Value representing invalid (null) function */
+#define PCIE_FUNCTION_PF_NULL 0xffff
+#define PCIE_FUNCTION_PF_LBN 0
+#define PCIE_FUNCTION_PF_WIDTH 16
+/* PCIe VF Function number (PF relative) */
+#define PCIE_FUNCTION_VF_OFST 2
+#define PCIE_FUNCTION_VF_LEN 2
+/* enum: Wildcard value representing any available function (e.g in resource
+ * allocation requests)
+ */
+#define PCIE_FUNCTION_VF_ANY 0xfffe
+/* enum: Function is a PF (when PF != PF_NULL) or invalid function (when PF ==
+ * PF_NULL)
+ */
+#define PCIE_FUNCTION_VF_NULL 0xffff
+#define PCIE_FUNCTION_VF_LBN 16
+#define PCIE_FUNCTION_VF_WIDTH 16
+/* PCIe interface of the function */
+#define PCIE_FUNCTION_INTF_OFST 4
+#define PCIE_FUNCTION_INTF_LEN 4
+/* enum: Host PCIe interface */
+#define PCIE_FUNCTION_INTF_HOST 0x0
+/* enum: Application Processor interface */
+#define PCIE_FUNCTION_INTF_AP 0x1
+#define PCIE_FUNCTION_INTF_LBN 32
+#define PCIE_FUNCTION_INTF_WIDTH 32
+
+
+/***********************************/
+/* MC_CMD_DESC_PROXY_FUNC_CREATE
+ * Descriptor proxy functions are abstract devices that forward all request
+ * submitted to the host PCIe function (descriptors submitted to Virtio or
+ * EF100 queues) to be handled on another function (most commonly on the
+ * embedded Application Processor), via EF100 descriptor proxy, memory-to-
+ * memory and descriptor-to-completion mechanisms. Primary user is Virtio-blk
+ * subsystem, see SF-122927-TC. This function allocates a new descriptor proxy
+ * function on the host and assigns a user-defined label. The actual function
+ * configuration is not persisted until the caller configures it with
+ * MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN and commits with
+ * MC_CMD_DESC_PROXY_FUNC_COMMIT_IN.
+ */
+#define MC_CMD_DESC_PROXY_FUNC_CREATE 0x172
+#undef MC_CMD_0x172_PRIVILEGE_CTG
+
+#define MC_CMD_0x172_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DESC_PROXY_FUNC_CREATE_IN msgrequest */
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_IN_LEN 52
+/* PCIe Function ID to allocate (as struct PCIE_FUNCTION). Set to
+ * {PF_ANY,VF_ANY,interface} for "any available function" Set to
+ * {PF_ANY,VF_NULL,interface} for "any available PF"
+ */
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_IN_FUNC_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_IN_FUNC_LEN 8
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_IN_FUNC_LO_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_IN_FUNC_HI_OFST 4
+/* The personality to set. The meanings of the personalities are defined in
+ * SF-120734-TC with more information in SF-122717-TC. At present, we only
+ * support proxying for VIRTIO_BLK
+ */
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_IN_PERSONALITY_OFST 8
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_IN_PERSONALITY_LEN 4
+/* Enum values, see field(s): */
+/* FUNCTION_PERSONALITY/ID */
+/* User-defined label (zero-terminated ASCII string) to uniquely identify the
+ * function
+ */
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_IN_LABEL_OFST 12
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_IN_LABEL_LEN 40
+
+/* MC_CMD_DESC_PROXY_FUNC_CREATE_OUT msgresponse */
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_OUT_LEN 12
+/* Handle to the descriptor proxy function */
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_OUT_HANDLE_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_OUT_HANDLE_LEN 4
+/* Allocated function ID (as struct PCIE_FUNCTION) */
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_OUT_FUNC_OFST 4
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_OUT_FUNC_LEN 8
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_OUT_FUNC_LO_OFST 4
+#define MC_CMD_DESC_PROXY_FUNC_CREATE_OUT_FUNC_HI_OFST 8
+
+
+/***********************************/
+/* MC_CMD_DESC_PROXY_FUNC_DESTROY
+ * Remove an existing descriptor proxy function. Underlying function
+ * personality and configuration reverts back to factory default. Function
+ * configuration is committed immediately to specified store and any function
+ * ownership is released.
+ */
+#define MC_CMD_DESC_PROXY_FUNC_DESTROY 0x173
+#undef MC_CMD_0x173_PRIVILEGE_CTG
+
+#define MC_CMD_0x173_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DESC_PROXY_FUNC_DESTROY_IN msgrequest */
+#define MC_CMD_DESC_PROXY_FUNC_DESTROY_IN_LEN 44
+/* User-defined label (zero-terminated ASCII string) to uniquely identify the
+ * function
+ */
+#define MC_CMD_DESC_PROXY_FUNC_DESTROY_IN_LABEL_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_DESTROY_IN_LABEL_LEN 40
+/* Store from which to remove function configuration */
+#define MC_CMD_DESC_PROXY_FUNC_DESTROY_IN_STORE_OFST 40
+#define MC_CMD_DESC_PROXY_FUNC_DESTROY_IN_STORE_LEN 4
+/* Enum values, see field(s): */
+/* MC_CMD_DESC_PROXY_FUNC_COMMIT/MC_CMD_DESC_PROXY_FUNC_COMMIT_IN/STORE */
+
+/* MC_CMD_DESC_PROXY_FUNC_DESTROY_OUT msgresponse */
+#define MC_CMD_DESC_PROXY_FUNC_DESTROY_OUT_LEN 0
+
+/* VIRTIO_BLK_CONFIG structuredef: Virtio block device configuration. See
+ * Virtio specification v1.1, Sections 5.2.3 and 6 for definition of feature
+ * bits. See Virtio specification v1.1, Section 5.2.4 (struct
+ * virtio_blk_config) for definition of remaining configuration fields
+ */
+#define VIRTIO_BLK_CONFIG_LEN 68
+/* Virtio block device features to advertise, per Virtio 1.1, 5.2.3 and 6 */
+#define VIRTIO_BLK_CONFIG_FEATURES_OFST 0
+#define VIRTIO_BLK_CONFIG_FEATURES_LEN 8
+#define VIRTIO_BLK_CONFIG_FEATURES_LO_OFST 0
+#define VIRTIO_BLK_CONFIG_FEATURES_HI_OFST 4
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_BARRIER_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_BARRIER_LBN 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_BARRIER_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_SIZE_MAX_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_SIZE_MAX_LBN 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_SIZE_MAX_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_SEG_MAX_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_SEG_MAX_LBN 2
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_SEG_MAX_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_GEOMETRY_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_GEOMETRY_LBN 4
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_GEOMETRY_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_RO_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_RO_LBN 5
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_RO_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_BLK_SIZE_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_BLK_SIZE_LBN 6
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_BLK_SIZE_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_SCSI_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_SCSI_LBN 7
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_SCSI_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_FLUSH_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_FLUSH_LBN 9
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_FLUSH_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_TOPOLOGY_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_TOPOLOGY_LBN 10
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_TOPOLOGY_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_CONFIG_WCE_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_CONFIG_WCE_LBN 11
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_CONFIG_WCE_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_MQ_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_MQ_LBN 12
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_MQ_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_DISCARD_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_DISCARD_LBN 13
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_DISCARD_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_WRITE_ZEROES_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_WRITE_ZEROES_LBN 14
+#define VIRTIO_BLK_CONFIG_VIRTIO_BLK_F_WRITE_ZEROES_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_RING_INDIRECT_DESC_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_RING_INDIRECT_DESC_LBN 28
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_RING_INDIRECT_DESC_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_RING_EVENT_IDX_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_RING_EVENT_IDX_LBN 29
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_RING_EVENT_IDX_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_VERSION_1_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_VERSION_1_LBN 32
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_VERSION_1_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_ACCESS_PLATFORM_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_ACCESS_PLATFORM_LBN 33
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_ACCESS_PLATFORM_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_RING_PACKED_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_RING_PACKED_LBN 34
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_RING_PACKED_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_IN_ORDER_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_IN_ORDER_LBN 35
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_IN_ORDER_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_ORDER_PLATFORM_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_ORDER_PLATFORM_LBN 36
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_ORDER_PLATFORM_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_SR_IOV_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_SR_IOV_LBN 37
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_SR_IOV_WIDTH 1
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_NOTIFICATION_DATA_OFST 0
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_NOTIFICATION_DATA_LBN 38
+#define VIRTIO_BLK_CONFIG_VIRTIO_F_NOTIFICATION_DATA_WIDTH 1
+#define VIRTIO_BLK_CONFIG_FEATURES_LBN 0
+#define VIRTIO_BLK_CONFIG_FEATURES_WIDTH 64
+/* The capacity of the device (expressed in 512-byte sectors) */
+#define VIRTIO_BLK_CONFIG_CAPACITY_OFST 8
+#define VIRTIO_BLK_CONFIG_CAPACITY_LEN 8
+#define VIRTIO_BLK_CONFIG_CAPACITY_LO_OFST 8
+#define VIRTIO_BLK_CONFIG_CAPACITY_HI_OFST 12
+#define VIRTIO_BLK_CONFIG_CAPACITY_LBN 64
+#define VIRTIO_BLK_CONFIG_CAPACITY_WIDTH 64
+/* Maximum size of any single segment. Only valid when VIRTIO_BLK_F_SIZE_MAX is
+ * set.
+ */
+#define VIRTIO_BLK_CONFIG_SIZE_MAX_OFST 16
+#define VIRTIO_BLK_CONFIG_SIZE_MAX_LEN 4
+#define VIRTIO_BLK_CONFIG_SIZE_MAX_LBN 128
+#define VIRTIO_BLK_CONFIG_SIZE_MAX_WIDTH 32
+/* Maximum number of segments in a request. Only valid when
+ * VIRTIO_BLK_F_SEG_MAX is set.
+ */
+#define VIRTIO_BLK_CONFIG_SEG_MAX_OFST 20
+#define VIRTIO_BLK_CONFIG_SEG_MAX_LEN 4
+#define VIRTIO_BLK_CONFIG_SEG_MAX_LBN 160
+#define VIRTIO_BLK_CONFIG_SEG_MAX_WIDTH 32
+/* Disk-style geometry - cylinders. Only valid when VIRTIO_BLK_F_GEOMETRY is
+ * set.
+ */
+#define VIRTIO_BLK_CONFIG_CYLINDERS_OFST 24
+#define VIRTIO_BLK_CONFIG_CYLINDERS_LEN 2
+#define VIRTIO_BLK_CONFIG_CYLINDERS_LBN 192
+#define VIRTIO_BLK_CONFIG_CYLINDERS_WIDTH 16
+/* Disk-style geometry - heads. Only valid when VIRTIO_BLK_F_GEOMETRY is set.
+ */
+#define VIRTIO_BLK_CONFIG_HEADS_OFST 26
+#define VIRTIO_BLK_CONFIG_HEADS_LEN 1
+#define VIRTIO_BLK_CONFIG_HEADS_LBN 208
+#define VIRTIO_BLK_CONFIG_HEADS_WIDTH 8
+/* Disk-style geometry - sectors. Only valid when VIRTIO_BLK_F_GEOMETRY is set.
+ */
+#define VIRTIO_BLK_CONFIG_SECTORS_OFST 27
+#define VIRTIO_BLK_CONFIG_SECTORS_LEN 1
+#define VIRTIO_BLK_CONFIG_SECTORS_LBN 216
+#define VIRTIO_BLK_CONFIG_SECTORS_WIDTH 8
+/* Block size of disk. Only valid when VIRTIO_BLK_F_BLK_SIZE is set. */
+#define VIRTIO_BLK_CONFIG_BLK_SIZE_OFST 28
+#define VIRTIO_BLK_CONFIG_BLK_SIZE_LEN 4
+#define VIRTIO_BLK_CONFIG_BLK_SIZE_LBN 224
+#define VIRTIO_BLK_CONFIG_BLK_SIZE_WIDTH 32
+/* Block topology - number of logical blocks per physical block (log2). Only
+ * valid when VIRTIO_BLK_F_TOPOLOGY is set.
+ */
+#define VIRTIO_BLK_CONFIG_PHYSICAL_BLOCK_EXP_OFST 32
+#define VIRTIO_BLK_CONFIG_PHYSICAL_BLOCK_EXP_LEN 1
+#define VIRTIO_BLK_CONFIG_PHYSICAL_BLOCK_EXP_LBN 256
+#define VIRTIO_BLK_CONFIG_PHYSICAL_BLOCK_EXP_WIDTH 8
+/* Block topology - offset of first aligned logical block. Only valid when
+ * VIRTIO_BLK_F_TOPOLOGY is set.
+ */
+#define VIRTIO_BLK_CONFIG_ALIGNMENT_OFFSET_OFST 33
+#define VIRTIO_BLK_CONFIG_ALIGNMENT_OFFSET_LEN 1
+#define VIRTIO_BLK_CONFIG_ALIGNMENT_OFFSET_LBN 264
+#define VIRTIO_BLK_CONFIG_ALIGNMENT_OFFSET_WIDTH 8
+/* Block topology - suggested minimum I/O size in blocks. Only valid when
+ * VIRTIO_BLK_F_TOPOLOGY is set.
+ */
+#define VIRTIO_BLK_CONFIG_MIN_IO_SIZE_OFST 34
+#define VIRTIO_BLK_CONFIG_MIN_IO_SIZE_LEN 2
+#define VIRTIO_BLK_CONFIG_MIN_IO_SIZE_LBN 272
+#define VIRTIO_BLK_CONFIG_MIN_IO_SIZE_WIDTH 16
+/* Block topology - optimal (suggested maximum) I/O size in blocks. Only valid
+ * when VIRTIO_BLK_F_TOPOLOGY is set.
+ */
+#define VIRTIO_BLK_CONFIG_OPT_IO_SIZE_OFST 36
+#define VIRTIO_BLK_CONFIG_OPT_IO_SIZE_LEN 4
+#define VIRTIO_BLK_CONFIG_OPT_IO_SIZE_LBN 288
+#define VIRTIO_BLK_CONFIG_OPT_IO_SIZE_WIDTH 32
+/* Unused, set to zero. Note that virtio_blk_config.writeback is volatile and
+ * not carried in config data.
+ */
+#define VIRTIO_BLK_CONFIG_UNUSED0_OFST 40
+#define VIRTIO_BLK_CONFIG_UNUSED0_LEN 2
+#define VIRTIO_BLK_CONFIG_UNUSED0_LBN 320
+#define VIRTIO_BLK_CONFIG_UNUSED0_WIDTH 16
+/* Number of queues. Only valid if the VIRTIO_BLK_F_MQ feature is negotiated.
+ */
+#define VIRTIO_BLK_CONFIG_NUM_QUEUES_OFST 42
+#define VIRTIO_BLK_CONFIG_NUM_QUEUES_LEN 2
+#define VIRTIO_BLK_CONFIG_NUM_QUEUES_LBN 336
+#define VIRTIO_BLK_CONFIG_NUM_QUEUES_WIDTH 16
+/* Maximum discard sectors size, in 512-byte units. Only valid if
+ * VIRTIO_BLK_F_DISCARD is set.
+ */
+#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SECTORS_OFST 44
+#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SECTORS_LEN 4
+#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SECTORS_LBN 352
+#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SECTORS_WIDTH 32
+/* Maximum discard segment number. Only valid if VIRTIO_BLK_F_DISCARD is set.
+ */
+#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SEG_OFST 48
+#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SEG_LEN 4
+#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SEG_LBN 384
+#define VIRTIO_BLK_CONFIG_MAX_DISCARD_SEG_WIDTH 32
+/* Discard sector alignment, in 512-byte units. Only valid if
+ * VIRTIO_BLK_F_DISCARD is set.
+ */
+#define VIRTIO_BLK_CONFIG_DISCARD_SECTOR_ALIGNMENT_OFST 52
+#define VIRTIO_BLK_CONFIG_DISCARD_SECTOR_ALIGNMENT_LEN 4
+#define VIRTIO_BLK_CONFIG_DISCARD_SECTOR_ALIGNMENT_LBN 416
+#define VIRTIO_BLK_CONFIG_DISCARD_SECTOR_ALIGNMENT_WIDTH 32
+/* Maximum write zeroes sectors size, in 512-byte units. Only valid if
+ * VIRTIO_BLK_F_WRITE_ZEROES is set.
+ */
+#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZEROES_SECTORS_OFST 56
+#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZEROES_SECTORS_LEN 4
+#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZEROES_SECTORS_LBN 448
+#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZEROES_SECTORS_WIDTH 32
+/* Maximum write zeroes segment number. Only valid if VIRTIO_BLK_F_WRITE_ZEROES
+ * is set.
+ */
+#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZEROES_SEG_OFST 60
+#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZEROES_SEG_LEN 4
+#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZEROES_SEG_LBN 480
+#define VIRTIO_BLK_CONFIG_MAX_WRITE_ZEROES_SEG_WIDTH 32
+/* Write zeroes request can result in deallocating one or more sectors. Only
+ * valid if VIRTIO_BLK_F_WRITE_ZEROES is set.
+ */
+#define VIRTIO_BLK_CONFIG_WRITE_ZEROES_MAY_UNMAP_OFST 64
+#define VIRTIO_BLK_CONFIG_WRITE_ZEROES_MAY_UNMAP_LEN 1
+#define VIRTIO_BLK_CONFIG_WRITE_ZEROES_MAY_UNMAP_LBN 512
+#define VIRTIO_BLK_CONFIG_WRITE_ZEROES_MAY_UNMAP_WIDTH 8
+/* Unused, set to zero. */
+#define VIRTIO_BLK_CONFIG_UNUSED1_OFST 65
+#define VIRTIO_BLK_CONFIG_UNUSED1_LEN 3
+#define VIRTIO_BLK_CONFIG_UNUSED1_LBN 520
+#define VIRTIO_BLK_CONFIG_UNUSED1_WIDTH 24
+
+
+/***********************************/
+/* MC_CMD_DESC_PROXY_FUNC_CONFIG_SET
+ * Set configuration for an existing descriptor proxy function. Configuration
+ * data must match function personality. The actual function configuration is
+ * not persisted until the caller commits with MC_CMD_DESC_PROXY_FUNC_COMMIT_IN
+ */
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET 0x174
+#undef MC_CMD_0x174_PRIVILEGE_CTG
+
+#define MC_CMD_0x174_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN msgrequest */
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_LENMIN 20
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_LENMAX 252
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_LENMAX_MCDI2 1020
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_LEN(num) (20+1*(num))
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_CONFIG_NUM(len) (((len)-20)/1)
+/* Handle to descriptor proxy function (as returned by
+ * MC_CMD_DESC_PROXY_FUNC_OPEN)
+ */
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_HANDLE_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_HANDLE_LEN 4
+/* Reserved for future extension, set to zero. */
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_RESERVED_OFST 4
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_RESERVED_LEN 16
+/* Configuration data. Format of configuration data is determined implicitly
+ * from function personality referred to by HANDLE. Currently, only supported
+ * format is VIRTIO_BLK_CONFIG.
+ */
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_CONFIG_OFST 20
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_CONFIG_LEN 1
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_CONFIG_MINNUM 0
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_CONFIG_MAXNUM 232
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_IN_CONFIG_MAXNUM_MCDI2 1000
+
+/* MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_OUT msgresponse */
+#define MC_CMD_DESC_PROXY_FUNC_CONFIG_SET_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_DESC_PROXY_FUNC_COMMIT
+ * Commit function configuration to non-volatile or volatile store. Once
+ * configuration is applied to hardware (which may happen immediately or on
+ * next function/device reset) a DESC_PROXY_FUNC_CONFIG_SET MCDI event will be
+ * delivered to callers MCDI event queue.
+ */
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT 0x175
+#undef MC_CMD_0x175_PRIVILEGE_CTG
+
+#define MC_CMD_0x175_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DESC_PROXY_FUNC_COMMIT_IN msgrequest */
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_IN_LEN 8
+/* Handle to descriptor proxy function (as returned by
+ * MC_CMD_DESC_PROXY_FUNC_OPEN)
+ */
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_IN_HANDLE_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_IN_HANDLE_LEN 4
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_IN_STORE_OFST 4
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_IN_STORE_LEN 4
+/* enum: Store into non-volatile (dynamic) config */
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_IN_NON_VOLATILE 0x0
+/* enum: Store into volatile (ephemeral) config */
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_IN_VOLATILE 0x1
+
+/* MC_CMD_DESC_PROXY_FUNC_COMMIT_OUT msgresponse */
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_OUT_LEN 4
+/* Generation count to be delivered in an event once configuration becomes live
+ */
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_OUT_CONFIG_GENERATION_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_COMMIT_OUT_CONFIG_GENERATION_LEN 4
+
+
+/***********************************/
+/* MC_CMD_DESC_PROXY_FUNC_OPEN
+ * Retrieve a handle for an existing descriptor proxy function. Returns an
+ * integer handle, valid until function is deallocated, MC rebooted or power-
+ * cycle. Returns ENODEV if no function with given label exists.
+ */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN 0x176
+#undef MC_CMD_0x176_PRIVILEGE_CTG
+
+#define MC_CMD_0x176_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DESC_PROXY_FUNC_OPEN_IN msgrequest */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_IN_LEN 40
+/* User-defined label (zero-terminated ASCII string) to uniquely identify the
+ * function
+ */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_IN_LABEL_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_IN_LABEL_LEN 40
+
+/* MC_CMD_DESC_PROXY_FUNC_OPEN_OUT msgresponse */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_LENMIN 40
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_LENMAX 252
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_LENMAX_MCDI2 1020
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_LEN(num) (40+1*(num))
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_NUM(len) (((len)-40)/1)
+/* Handle to the descriptor proxy function */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_HANDLE_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_HANDLE_LEN 4
+/* PCIe Function ID (as struct PCIE_FUNCTION) */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_FUNC_OFST 4
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_FUNC_LEN 8
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_FUNC_LO_OFST 4
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_FUNC_HI_OFST 8
+/* Function personality */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_PERSONALITY_OFST 12
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_PERSONALITY_LEN 4
+/* Enum values, see field(s): */
+/* FUNCTION_PERSONALITY/ID */
+/* Function configuration state */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_STATUS_OFST 16
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_STATUS_LEN 4
+/* enum: Function configuration is visible to the host (live) */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_LIVE 0x0
+/* enum: Function configuration is pending reset */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_PENDING 0x1
+/* Generation count to be delivered in an event once the configuration becomes
+ * live (if status is "pending")
+ */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_GENERATION_OFST 20
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_GENERATION_LEN 4
+/* Reserved for future extension, set to zero. */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_RESERVED_OFST 24
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_RESERVED_LEN 16
+/* Configuration data corresponding to function personality. Currently, only
+ * supported format is VIRTIO_BLK_CONFIG
+ */
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_OFST 40
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_LEN 1
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_MINNUM 0
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_MAXNUM 212
+#define MC_CMD_DESC_PROXY_FUNC_OPEN_OUT_CONFIG_MAXNUM_MCDI2 980
+
+
+/***********************************/
+/* MC_CMD_DESC_PROXY_FUNC_CLOSE
+ * Releases a handle for an open descriptor proxy function. If proxying was
+ * enabled on the device, the caller is expected to gracefully stop it using
+ * MC_CMD_DESC_PROXY_FUNC_DISABLE prior to calling this function. Closing an
+ * active device without disabling proxying will result in forced close, which
+ * will put the device into a failed state and signal the host driver of the
+ * error (for virtio, DEVICE_NEEDS_RESET flag would be set on the host side)
+ */
+#define MC_CMD_DESC_PROXY_FUNC_CLOSE 0x1a1
+#undef MC_CMD_0x1a1_PRIVILEGE_CTG
+
+#define MC_CMD_0x1a1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DESC_PROXY_FUNC_CLOSE_IN msgrequest */
+#define MC_CMD_DESC_PROXY_FUNC_CLOSE_IN_LEN 4
+/* Handle to the descriptor proxy function */
+#define MC_CMD_DESC_PROXY_FUNC_CLOSE_IN_HANDLE_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_CLOSE_IN_HANDLE_LEN 4
+
+/* MC_CMD_DESC_PROXY_FUNC_CLOSE_OUT msgresponse */
+#define MC_CMD_DESC_PROXY_FUNC_CLOSE_OUT_LEN 0
+
+/* DESC_PROXY_FUNC_MAP structuredef */
+#define DESC_PROXY_FUNC_MAP_LEN 52
+/* PCIe function ID (as struct PCIE_FUNCTION) */
+#define DESC_PROXY_FUNC_MAP_FUNC_OFST 0
+#define DESC_PROXY_FUNC_MAP_FUNC_LEN 8
+#define DESC_PROXY_FUNC_MAP_FUNC_LO_OFST 0
+#define DESC_PROXY_FUNC_MAP_FUNC_HI_OFST 4
+#define DESC_PROXY_FUNC_MAP_FUNC_LBN 0
+#define DESC_PROXY_FUNC_MAP_FUNC_WIDTH 64
+/* Function personality */
+#define DESC_PROXY_FUNC_MAP_PERSONALITY_OFST 8
+#define DESC_PROXY_FUNC_MAP_PERSONALITY_LEN 4
+/* Enum values, see field(s): */
+/* FUNCTION_PERSONALITY/ID */
+#define DESC_PROXY_FUNC_MAP_PERSONALITY_LBN 64
+#define DESC_PROXY_FUNC_MAP_PERSONALITY_WIDTH 32
+/* User-defined label (zero-terminated ASCII string) to uniquely identify the
+ * function
+ */
+#define DESC_PROXY_FUNC_MAP_LABEL_OFST 12
+#define DESC_PROXY_FUNC_MAP_LABEL_LEN 40
+#define DESC_PROXY_FUNC_MAP_LABEL_LBN 96
+#define DESC_PROXY_FUNC_MAP_LABEL_WIDTH 320
+
+
+/***********************************/
+/* MC_CMD_DESC_PROXY_FUNC_ENUM
+ * Enumerate existing descriptor proxy functions
+ */
+#define MC_CMD_DESC_PROXY_FUNC_ENUM 0x177
+#undef MC_CMD_0x177_PRIVILEGE_CTG
+
+#define MC_CMD_0x177_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DESC_PROXY_FUNC_ENUM_IN msgrequest */
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_IN_LEN 4
+/* Starting index, set to 0 on first request. See
+ * MC_CMD_DESC_PROXY_FUNC_ENUM_OUT/FLAGS.
+ */
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_IN_START_IDX_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_IN_START_IDX_LEN 4
+
+/* MC_CMD_DESC_PROXY_FUNC_ENUM_OUT msgresponse */
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_LENMIN 4
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_LENMAX 212
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_LENMAX_MCDI2 992
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_LEN(num) (4+52*(num))
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_FUNC_MAP_NUM(len) (((len)-4)/52)
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_FLAGS_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_FLAGS_LEN 4
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_MORE_DATA_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_MORE_DATA_LBN 0
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_MORE_DATA_WIDTH 1
+/* Function map, as array of DESC_PROXY_FUNC_MAP */
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_FUNC_MAP_OFST 4
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_FUNC_MAP_LEN 52
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_FUNC_MAP_MINNUM 0
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_FUNC_MAP_MAXNUM 4
+#define MC_CMD_DESC_PROXY_FUNC_ENUM_OUT_FUNC_MAP_MAXNUM_MCDI2 19
+
+
+/***********************************/
+/* MC_CMD_DESC_PROXY_FUNC_ENABLE
+ * Enable descriptor proxying for function into target event queue. Returns VI
+ * allocation info for the proxy source function, so that the caller can map
+ * absolute VI IDs from descriptor proxy events back to the originating
+ * function.
+ */
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE 0x178
+#undef MC_CMD_0x178_PRIVILEGE_CTG
+
+#define MC_CMD_0x178_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DESC_PROXY_FUNC_ENABLE_IN msgrequest */
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_IN_LEN 8
+/* Handle to descriptor proxy function (as returned by
+ * MC_CMD_DESC_PROXY_FUNC_OPEN)
+ */
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_IN_HANDLE_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_IN_HANDLE_LEN 4
+/* Descriptor proxy sink queue (caller function relative). Must be extended
+ * width event queue
+ */
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_IN_TARGET_EVQ_OFST 4
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_IN_TARGET_EVQ_LEN 4
+
+/* MC_CMD_DESC_PROXY_FUNC_ENABLE_OUT msgresponse */
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_OUT_LEN 8
+/* The number of VIs allocated on the function */
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_OUT_VI_COUNT_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_OUT_VI_COUNT_LEN 4
+/* The base absolute VI number allocated to the function. */
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_OUT_VI_BASE_OFST 4
+#define MC_CMD_DESC_PROXY_FUNC_ENABLE_OUT_VI_BASE_LEN 4
+
+
+/***********************************/
+/* MC_CMD_DESC_PROXY_FUNC_DISABLE
+ * Disable descriptor proxying for function
+ */
+#define MC_CMD_DESC_PROXY_FUNC_DISABLE 0x179
+#undef MC_CMD_0x179_PRIVILEGE_CTG
+
+#define MC_CMD_0x179_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DESC_PROXY_FUNC_DISABLE_IN msgrequest */
+#define MC_CMD_DESC_PROXY_FUNC_DISABLE_IN_LEN 4
+/* Handle to descriptor proxy function (as returned by
+ * MC_CMD_DESC_PROXY_FUNC_OPEN)
+ */
+#define MC_CMD_DESC_PROXY_FUNC_DISABLE_IN_HANDLE_OFST 0
+#define MC_CMD_DESC_PROXY_FUNC_DISABLE_IN_HANDLE_LEN 4
+
+/* MC_CMD_DESC_PROXY_FUNC_DISABLE_OUT msgresponse */
+#define MC_CMD_DESC_PROXY_FUNC_DISABLE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_ADDR_SPC_ID
+ * Get Address space identifier for use in mem2mem descriptors for a given
+ * target. See SF-120734-TC for details on ADDR_SPC_IDs and mem2mem
+ * descriptors.
+ */
+#define MC_CMD_GET_ADDR_SPC_ID 0x1a0
+#undef MC_CMD_0x1a0_PRIVILEGE_CTG
+
+#define MC_CMD_0x1a0_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_GET_ADDR_SPC_ID_IN msgrequest */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_LEN 16
+/* Resource type to get ADDR_SPC_ID for */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_TYPE_OFST 0
+#define MC_CMD_GET_ADDR_SPC_ID_IN_TYPE_LEN 4
+/* enum: Address space ID for host/AP memory DMA over the same interface this
+ * MCDI was called on
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_SELF 0x0
+/* enum: Address space ID for host/AP memory DMA via PCI interface and function
+ * specified by FUNC
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_PCI_FUNC 0x1
+/* enum: Address space ID for host/AP memory DMA via PCI interface and function
+ * specified by FUNC with PASID value specified by PASID
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_PCI_FUNC_PASID 0x2
+/* enum: Address space ID for host/AP memory DMA via PCI interface and function
+ * specified by FUNC with PASID value of relative VI specified by VI
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_REL_VI 0x3
+/* enum: Address space ID for host/AP memory DMA via PCI interface, function
+ * and PASID value of absolute VI specified by VI
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_ABS_VI 0x4
+/* enum: Address space ID for host memory DMA via PCI interface and function of
+ * descriptor proxy function specified by HANDLE
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_DESC_PROXY_HANDLE 0x5
+/* enum: Address space ID for DMA to/from MC memory */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_MC_MEM 0x6
+/* enum: Address space ID for DMA to/from other SmartNIC memory (on-chip, DDR)
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_NIC_MEM 0x7
+/* PCIe Function ID (as struct PCIE_FUNCTION). Only valid if TYPE is PCI_FUNC,
+ * PCI_FUNC_PASID or REL_VI.
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_FUNC_OFST 4
+#define MC_CMD_GET_ADDR_SPC_ID_IN_FUNC_LEN 8
+#define MC_CMD_GET_ADDR_SPC_ID_IN_FUNC_LO_OFST 4
+#define MC_CMD_GET_ADDR_SPC_ID_IN_FUNC_HI_OFST 8
+/* PASID value. Only valid if TYPE is PCI_FUNC_PASID. */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_PASID_OFST 12
+#define MC_CMD_GET_ADDR_SPC_ID_IN_PASID_LEN 4
+/* Relative or absolute VI number. Only valid if TYPE is REL_VI or ABS_VI */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_VI_OFST 12
+#define MC_CMD_GET_ADDR_SPC_ID_IN_VI_LEN 4
+/* Descriptor proxy function handle. Only valid if TYPE is DESC_PROXY_HANDLE.
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_IN_HANDLE_OFST 4
+#define MC_CMD_GET_ADDR_SPC_ID_IN_HANDLE_LEN 4
+
+/* MC_CMD_GET_ADDR_SPC_ID_OUT msgresponse */
+#define MC_CMD_GET_ADDR_SPC_ID_OUT_LEN 8
+/* Address Space ID for the requested target. Only the lower 36 bits are valid
+ * in the current SmartNIC implementation.
+ */
+#define MC_CMD_GET_ADDR_SPC_ID_OUT_ADDR_SPC_ID_OFST 0
+#define MC_CMD_GET_ADDR_SPC_ID_OUT_ADDR_SPC_ID_LEN 8
+#define MC_CMD_GET_ADDR_SPC_ID_OUT_ADDR_SPC_ID_LO_OFST 0
+#define MC_CMD_GET_ADDR_SPC_ID_OUT_ADDR_SPC_ID_HI_OFST 4
+
+
#endif /* MCDI_PCOL_H */
diff --git a/drivers/net/ethernet/sfc/mcdi_port.c b/drivers/net/ethernet/sfc/mcdi_port.c
index b807871d8f69..98eeb404f68d 100644
--- a/drivers/net/ethernet/sfc/mcdi_port.c
+++ b/drivers/net/ethernet/sfc/mcdi_port.c
@@ -10,6 +10,7 @@
#include <linux/slab.h>
#include "efx.h"
+#include "mcdi_port.h"
#include "mcdi.h"
#include "mcdi_pcol.h"
#include "nic.h"
@@ -175,19 +176,6 @@ fail:
return rc;
}
-int efx_mcdi_port_reconfigure(struct efx_nic *efx)
-{
- struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
- u32 caps = (efx->link_advertising[0] ?
- ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
- phy_cfg->forced_cap);
-
- caps |= ethtool_fec_caps_to_mcdi(efx->fec_config);
-
- return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
- efx->loopback_mode, 0);
-}
-
static void efx_mcdi_phy_remove(struct efx_nic *efx)
{
struct efx_mcdi_phy_data *phy_data = efx->phy_data;
@@ -691,80 +679,6 @@ bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
}
-enum efx_stats_action {
- EFX_STATS_ENABLE,
- EFX_STATS_DISABLE,
- EFX_STATS_PULL,
-};
-
-static int efx_mcdi_mac_stats(struct efx_nic *efx,
- enum efx_stats_action action, int clear)
-{
- MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
- int rc;
- int change = action == EFX_STATS_PULL ? 0 : 1;
- int enable = action == EFX_STATS_ENABLE ? 1 : 0;
- int period = action == EFX_STATS_ENABLE ? 1000 : 0;
- dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
- u32 dma_len = action != EFX_STATS_DISABLE ?
- efx->num_mac_stats * sizeof(u64) : 0;
-
- BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
-
- MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, dma_addr);
- MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
- MAC_STATS_IN_DMA, !!enable,
- MAC_STATS_IN_CLEAR, clear,
- MAC_STATS_IN_PERIODIC_CHANGE, change,
- MAC_STATS_IN_PERIODIC_ENABLE, enable,
- MAC_STATS_IN_PERIODIC_CLEAR, 0,
- MAC_STATS_IN_PERIODIC_NOEVENT, 1,
- MAC_STATS_IN_PERIOD_MS, period);
- MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
-
- if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0)
- MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, efx->vport_id);
-
- rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
- NULL, 0, NULL);
- /* Expect ENOENT if DMA queues have not been set up */
- if (rc && (rc != -ENOENT || atomic_read(&efx->active_queues)))
- efx_mcdi_display_error(efx, MC_CMD_MAC_STATS, sizeof(inbuf),
- NULL, 0, rc);
- return rc;
-}
-
-void efx_mcdi_mac_start_stats(struct efx_nic *efx)
-{
- __le64 *dma_stats = efx->stats_buffer.addr;
-
- dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
-
- efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
-}
-
-void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
-{
- efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
-}
-
-#define EFX_MAC_STATS_WAIT_US 100
-#define EFX_MAC_STATS_WAIT_ATTEMPTS 10
-
-void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
-{
- __le64 *dma_stats = efx->stats_buffer.addr;
- int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
-
- dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
- efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
-
- while (dma_stats[efx->num_mac_stats - 1] ==
- EFX_MC_STATS_GENERATION_INVALID &&
- attempts-- != 0)
- udelay(EFX_MAC_STATS_WAIT_US);
-}
-
int efx_mcdi_port_probe(struct efx_nic *efx)
{
int rc;
@@ -782,24 +696,11 @@ int efx_mcdi_port_probe(struct efx_nic *efx)
if (rc != 0)
return rc;
- /* Allocate buffer for stats */
- rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
- efx->num_mac_stats * sizeof(u64), GFP_KERNEL);
- if (rc)
- return rc;
- netif_dbg(efx, probe, efx->net_dev,
- "stats buffer at %llx (virt %p phys %llx)\n",
- (u64)efx->stats_buffer.dma_addr,
- efx->stats_buffer.addr,
- (u64)virt_to_phys(efx->stats_buffer.addr));
-
- efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 1);
-
- return 0;
+ return efx_mcdi_mac_init_stats(efx);
}
void efx_mcdi_port_remove(struct efx_nic *efx)
{
efx->phy_op->remove(efx);
- efx_nic_free_buffer(efx, &efx->stats_buffer);
+ efx_mcdi_mac_fini_stats(efx);
}
diff --git a/drivers/net/ethernet/sfc/mcdi_port.h b/drivers/net/ethernet/sfc/mcdi_port.h
new file mode 100644
index 000000000000..07863ddbe740
--- /dev/null
+++ b/drivers/net/ethernet/sfc/mcdi_port.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2008-2013 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ */
+
+#ifndef EFX_MCDI_PORT_H
+#define EFX_MCDI_PORT_H
+
+#include "net_driver.h"
+
+u32 efx_mcdi_phy_get_caps(struct efx_nic *efx);
+bool efx_mcdi_mac_check_fault(struct efx_nic *efx);
+int efx_mcdi_port_probe(struct efx_nic *efx);
+void efx_mcdi_port_remove(struct efx_nic *efx);
+
+#endif /* EFX_MCDI_PORT_H */
diff --git a/drivers/net/ethernet/sfc/mcdi_port_common.c b/drivers/net/ethernet/sfc/mcdi_port_common.c
index a6a072ba46d3..56af8b54a864 100644
--- a/drivers/net/ethernet/sfc/mcdi_port_common.c
+++ b/drivers/net/ethernet/sfc/mcdi_port_common.c
@@ -10,6 +10,7 @@
#include "mcdi_port_common.h"
#include "efx_common.h"
+#include "nic.h"
int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg)
{
@@ -475,6 +476,24 @@ int efx_mcdi_phy_test_alive(struct efx_nic *efx)
return 0;
}
+int efx_mcdi_port_reconfigure(struct efx_nic *efx)
+{
+ struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
+ u32 caps = (efx->link_advertising[0] ?
+ ethtool_linkset_to_mcdi_cap(efx->link_advertising) :
+ phy_cfg->forced_cap);
+
+ caps |= ethtool_fec_caps_to_mcdi(efx->fec_config);
+
+ return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
+ efx->loopback_mode, 0);
+}
+
+static unsigned int efx_calc_mac_mtu(struct efx_nic *efx)
+{
+ return EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
+}
+
int efx_mcdi_set_mac(struct efx_nic *efx)
{
u32 fcntl;
@@ -486,8 +505,7 @@ int efx_mcdi_set_mac(struct efx_nic *efx)
ether_addr_copy(MCDI_PTR(cmdbytes, SET_MAC_IN_ADDR),
efx->net_dev->dev_addr);
- MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU,
- EFX_MAX_FRAME_LEN(efx->net_dev->mtu));
+ MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU, efx_calc_mac_mtu(efx));
MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0);
/* Set simple MAC filter for Siena */
@@ -520,6 +538,125 @@ int efx_mcdi_set_mac(struct efx_nic *efx)
NULL, 0, NULL);
}
+int efx_mcdi_set_mtu(struct efx_nic *efx)
+{
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_MAC_EXT_IN_LEN);
+
+ BUILD_BUG_ON(MC_CMD_SET_MAC_OUT_LEN != 0);
+
+ MCDI_SET_DWORD(inbuf, SET_MAC_EXT_IN_MTU, efx_calc_mac_mtu(efx));
+
+ MCDI_POPULATE_DWORD_1(inbuf, SET_MAC_EXT_IN_CONTROL,
+ SET_MAC_EXT_IN_CFG_MTU, 1);
+
+ return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, inbuf, sizeof(inbuf),
+ NULL, 0, NULL);
+}
+
+enum efx_stats_action {
+ EFX_STATS_ENABLE,
+ EFX_STATS_DISABLE,
+ EFX_STATS_PULL,
+};
+
+static int efx_mcdi_mac_stats(struct efx_nic *efx,
+ enum efx_stats_action action, int clear)
+{
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
+ int rc;
+ int change = action == EFX_STATS_PULL ? 0 : 1;
+ int enable = action == EFX_STATS_ENABLE ? 1 : 0;
+ int period = action == EFX_STATS_ENABLE ? 1000 : 0;
+ dma_addr_t dma_addr = efx->stats_buffer.dma_addr;
+ u32 dma_len = action != EFX_STATS_DISABLE ?
+ efx->num_mac_stats * sizeof(u64) : 0;
+
+ BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
+
+ MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, dma_addr);
+ MCDI_POPULATE_DWORD_7(inbuf, MAC_STATS_IN_CMD,
+ MAC_STATS_IN_DMA, !!enable,
+ MAC_STATS_IN_CLEAR, clear,
+ MAC_STATS_IN_PERIODIC_CHANGE, change,
+ MAC_STATS_IN_PERIODIC_ENABLE, enable,
+ MAC_STATS_IN_PERIODIC_CLEAR, 0,
+ MAC_STATS_IN_PERIODIC_NOEVENT, 1,
+ MAC_STATS_IN_PERIOD_MS, period);
+ MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
+
+ if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0)
+ MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, efx->vport_id);
+
+ rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
+ NULL, 0, NULL);
+ /* Expect ENOENT if DMA queues have not been set up */
+ if (rc && (rc != -ENOENT || atomic_read(&efx->active_queues)))
+ efx_mcdi_display_error(efx, MC_CMD_MAC_STATS, sizeof(inbuf),
+ NULL, 0, rc);
+ return rc;
+}
+
+void efx_mcdi_mac_start_stats(struct efx_nic *efx)
+{
+ __le64 *dma_stats = efx->stats_buffer.addr;
+
+ dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
+
+ efx_mcdi_mac_stats(efx, EFX_STATS_ENABLE, 0);
+}
+
+void efx_mcdi_mac_stop_stats(struct efx_nic *efx)
+{
+ efx_mcdi_mac_stats(efx, EFX_STATS_DISABLE, 0);
+}
+
+#define EFX_MAC_STATS_WAIT_US 100
+#define EFX_MAC_STATS_WAIT_ATTEMPTS 10
+
+void efx_mcdi_mac_pull_stats(struct efx_nic *efx)
+{
+ __le64 *dma_stats = efx->stats_buffer.addr;
+ int attempts = EFX_MAC_STATS_WAIT_ATTEMPTS;
+
+ dma_stats[efx->num_mac_stats - 1] = EFX_MC_STATS_GENERATION_INVALID;
+ efx_mcdi_mac_stats(efx, EFX_STATS_PULL, 0);
+
+ while (dma_stats[efx->num_mac_stats - 1] ==
+ EFX_MC_STATS_GENERATION_INVALID &&
+ attempts-- != 0)
+ udelay(EFX_MAC_STATS_WAIT_US);
+}
+
+int efx_mcdi_mac_init_stats(struct efx_nic *efx)
+{
+ int rc;
+
+ if (!efx->num_mac_stats)
+ return 0;
+
+ /* Allocate buffer for stats */
+ rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
+ efx->num_mac_stats * sizeof(u64), GFP_KERNEL);
+ if (rc) {
+ netif_warn(efx, probe, efx->net_dev,
+ "failed to allocate DMA buffer: %d\n", rc);
+ return rc;
+ }
+
+ netif_dbg(efx, probe, efx->net_dev,
+ "stats buffer at %llx (virt %p phys %llx)\n",
+ (u64) efx->stats_buffer.dma_addr,
+ efx->stats_buffer.addr,
+ (u64) virt_to_phys(efx->stats_buffer.addr));
+
+ return 0;
+}
+
+void efx_mcdi_mac_fini_stats(struct efx_nic *efx)
+{
+ efx_nic_free_buffer(efx, &efx->stats_buffer);
+}
+
/* Get physical port number (EF10 only; on Siena it is same as PF number) */
int efx_mcdi_port_get_number(struct efx_nic *efx)
{
diff --git a/drivers/net/ethernet/sfc/mcdi_port_common.h b/drivers/net/ethernet/sfc/mcdi_port_common.h
index b16f11265269..9dbeee83266f 100644
--- a/drivers/net/ethernet/sfc/mcdi_port_common.h
+++ b/drivers/net/ethernet/sfc/mcdi_port_common.h
@@ -28,8 +28,6 @@ struct efx_mcdi_phy_data {
u32 forced_cap;
};
-#define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1))
-
int efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_data *cfg);
void efx_link_set_advertising(struct efx_nic *efx,
const unsigned long *advertising);
@@ -51,6 +49,9 @@ int efx_mcdi_phy_get_fecparam(struct efx_nic *efx,
struct ethtool_fecparam *fec);
int efx_mcdi_phy_test_alive(struct efx_nic *efx);
int efx_mcdi_set_mac(struct efx_nic *efx);
+int efx_mcdi_set_mtu(struct efx_nic *efx);
+int efx_mcdi_mac_init_stats(struct efx_nic *efx);
+void efx_mcdi_mac_fini_stats(struct efx_nic *efx);
int efx_mcdi_port_get_number(struct efx_nic *efx);
void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev);
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 1afb58feb9ab..7bb7ecb480ae 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -173,6 +173,7 @@ struct efx_tx_buffer {
#define EFX_TX_BUF_MAP_SINGLE 8 /* buffer was mapped with dma_map_single() */
#define EFX_TX_BUF_OPTION 0x10 /* empty buffer for option descriptor */
#define EFX_TX_BUF_XDP 0x20 /* buffer was sent with XDP */
+#define EFX_TX_BUF_TSO_V3 0x40 /* empty buffer for a TSO_V3 descriptor */
/**
* struct efx_tx_queue - An Efx TX queue
@@ -189,6 +190,8 @@ struct efx_tx_buffer {
*
* @efx: The associated Efx NIC
* @queue: DMA queue number
+ * @label: Label for TX completion events.
+ * Is our index within @channel->tx_queue array.
* @tso_version: Version of TSO in use for this queue.
* @channel: The associated channel
* @core_txq: The networking core TX queue structure
@@ -243,6 +246,7 @@ struct efx_tx_buffer {
* @pio_packets: Number of times the TX PIO feature has been used
* @xmit_more_available: Are any packets waiting to be pushed to the NIC
* @cb_packets: Number of times the TX copybreak feature has been used
+ * @notify_count: Count of notified descriptors to the NIC
* @empty_read_count: If the completion path has seen the queue as empty
* and the transmission path has not yet checked this, the value of
* @read_count bitwise-added to %EFX_EMPTY_COUNT_VALID; otherwise 0.
@@ -250,7 +254,8 @@ struct efx_tx_buffer {
struct efx_tx_queue {
/* Members which don't change on the fast path */
struct efx_nic *efx ____cacheline_aligned_in_smp;
- unsigned queue;
+ unsigned int queue;
+ unsigned int label;
unsigned int tso_version;
struct efx_channel *channel;
struct netdev_queue *core_txq;
@@ -289,6 +294,7 @@ struct efx_tx_queue {
unsigned int pio_packets;
bool xmit_more_available;
unsigned int cb_packets;
+ unsigned int notify_count;
/* Statistics to supplement MAC stats */
unsigned long tx_packets;
@@ -606,8 +612,6 @@ extern const unsigned int efx_reset_type_max;
#define RESET_TYPE(type) \
STRING_TABLE_LOOKUP(type, efx_reset_type)
-void efx_get_udp_tunnel_type_name(u16 type, char *buf, size_t buflen);
-
enum efx_int_mode {
/* Be careful if altering to correct macro below */
EFX_INT_MODE_MSIX = 0,
@@ -867,6 +871,7 @@ struct efx_async_filter_insertion {
* @n_rx_channels: Number of channels used for RX (= number of RX queues)
* @n_tx_channels: Number of channels used for TX
* @n_extra_tx_channels: Number of extra channels with TX queues
+ * @tx_queues_per_channel: number of TX queues probed on each channel
* @n_xdp_channels: Number of channels used for XDP TX
* @xdp_channel_offset: Offset of zeroth channel used for XPD TX.
* @xdp_tx_per_channel: Max number of TX queues on an XDP TX channel.
@@ -961,6 +966,9 @@ struct efx_async_filter_insertion {
* @vpd_sn: Serial number read from VPD
* @xdp_rxq_info_failed: Have any of the rx queues failed to initialise their
* xdp_rxq_info structures?
+ * @netdev_notifier: Netdevice notifier.
+ * @mem_bar: The BAR that is mapped into membase.
+ * @reg_base: Offset from the start of the bar to the function control window.
* @monitor_work: Hardware monitor workitem
* @biu_lock: BIU (bus interface unit) lock
* @last_irq_cpu: Last CPU to handle a possible test interrupt. This
@@ -1022,6 +1030,7 @@ struct efx_nic {
unsigned next_buffer_table;
unsigned int max_channels;
+ unsigned int max_vis;
unsigned int max_tx_channels;
unsigned n_channels;
unsigned n_rx_channels;
@@ -1029,6 +1038,7 @@ struct efx_nic {
unsigned tx_channel_offset;
unsigned n_tx_channels;
unsigned n_extra_tx_channels;
+ unsigned int tx_queues_per_channel;
unsigned int n_xdp_channels;
unsigned int xdp_channel_offset;
unsigned int xdp_tx_per_channel;
@@ -1136,6 +1146,11 @@ struct efx_nic {
char *vpd_sn;
bool xdp_rxq_info_failed;
+ struct notifier_block netdev_notifier;
+
+ unsigned int mem_bar;
+ u32 reg_base;
+
/* The following fields may be written more often */
struct delayed_work monitor_work ____cacheline_aligned_in_smp;
@@ -1164,12 +1179,9 @@ struct efx_mtd_partition {
};
struct efx_udp_tunnel {
+#define TUNNEL_ENCAP_UDP_PORT_ENTRY_INVALID 0xffff
u16 type; /* TUNNEL_ENCAP_UDP_PORT_ENTRY_foo, see mcdi_pcol.h */
__be16 port;
- /* Count of repeated adds of the same port. Used only inside the list,
- * not in request arguments.
- */
- u16 count;
};
/**
@@ -1240,6 +1252,7 @@ struct efx_udp_tunnel {
* @tx_init: Initialise TX queue on the NIC
* @tx_remove: Free resources for TX queue
* @tx_write: Write TX descriptors and doorbell
+ * @tx_enqueue: Add an SKB to TX queue
* @rx_push_rss_config: Write RSS hash key and indirection table to the NIC
* @rx_pull_rss_config: Read RSS hash key and indirection table back from the NIC
* @rx_push_rss_context_config: Write RSS hash key and indirection table for
@@ -1251,6 +1264,7 @@ struct efx_udp_tunnel {
* @rx_remove: Free resources for RX queue
* @rx_write: Write RX descriptors and doorbell
* @rx_defer_refill: Generate a refill reminder event
+ * @rx_packet: Receive the queued RX buffer on a channel
* @ev_probe: Allocate resources for event queue
* @ev_init: Initialise event queue on the NIC
* @ev_fini: Deinitialise event queue on the NIC
@@ -1293,10 +1307,9 @@ struct efx_udp_tunnel {
* @tso_versions: Returns mask of firmware-assisted TSO versions supported.
* If %NULL, then device does not support any TSO version.
* @udp_tnl_push_ports: Push the list of UDP tunnel ports to the NIC if required.
- * @udp_tnl_add_port: Add a UDP tunnel port
* @udp_tnl_has_port: Check if a port has been added as UDP tunnel
- * @udp_tnl_del_port: Remove a UDP tunnel port
* @print_additional_fwver: Dump NIC-specific additional FW version info
+ * @sensor_event: Handle a sensor event from MCDI
* @revision: Hardware architecture revision
* @txd_ptr_tbl_base: TX descriptor ring base address
* @rxd_ptr_tbl_base: RX descriptor ring base address
@@ -1313,8 +1326,6 @@ struct efx_udp_tunnel {
* @option_descriptors: NIC supports TX option descriptors
* @min_interrupt_mode: Lowest capability interrupt mode supported
* from &enum efx_int_mode.
- * @max_interrupt_mode: Highest capability interrupt mode supported
- * from &enum efx_int_mode.
* @timer_period_max: Maximum period of interrupt timer (in ticks)
* @offload_features: net_device feature flags for protocol offload
* features implemented in hardware
@@ -1352,7 +1363,7 @@ struct efx_nic_type {
void (*push_irq_moderation)(struct efx_channel *channel);
int (*reconfigure_port)(struct efx_nic *efx);
void (*prepare_enable_fc_tx)(struct efx_nic *efx);
- int (*reconfigure_mac)(struct efx_nic *efx);
+ int (*reconfigure_mac)(struct efx_nic *efx, bool mtu_only);
bool (*check_mac_fault)(struct efx_nic *efx);
void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol);
int (*set_wol)(struct efx_nic *efx, u32 type);
@@ -1379,6 +1390,7 @@ struct efx_nic_type {
void (*tx_init)(struct efx_tx_queue *tx_queue);
void (*tx_remove)(struct efx_tx_queue *tx_queue);
void (*tx_write)(struct efx_tx_queue *tx_queue);
+ netdev_tx_t (*tx_enqueue)(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
unsigned int (*tx_limit_len)(struct efx_tx_queue *tx_queue,
dma_addr_t dma_addr, unsigned int len);
int (*rx_push_rss_config)(struct efx_nic *efx, bool user,
@@ -1396,6 +1408,7 @@ struct efx_nic_type {
void (*rx_remove)(struct efx_rx_queue *rx_queue);
void (*rx_write)(struct efx_rx_queue *rx_queue);
void (*rx_defer_refill)(struct efx_rx_queue *rx_queue);
+ void (*rx_packet)(struct efx_channel *channel);
int (*ev_probe)(struct efx_channel *channel);
int (*ev_init)(struct efx_channel *channel);
void (*ev_fini)(struct efx_channel *channel);
@@ -1467,11 +1480,10 @@ struct efx_nic_type {
int (*set_mac_address)(struct efx_nic *efx);
u32 (*tso_versions)(struct efx_nic *efx);
int (*udp_tnl_push_ports)(struct efx_nic *efx);
- int (*udp_tnl_add_port)(struct efx_nic *efx, struct efx_udp_tunnel tnl);
bool (*udp_tnl_has_port)(struct efx_nic *efx, __be16 port);
- int (*udp_tnl_del_port)(struct efx_nic *efx, struct efx_udp_tunnel tnl);
size_t (*print_additional_fwver)(struct efx_nic *efx, char *buf,
size_t len);
+ void (*sensor_event)(struct efx_nic *efx, efx_qword_t *ev);
int revision;
unsigned int txd_ptr_tbl_base;
@@ -1488,7 +1500,6 @@ struct efx_nic_type {
bool always_rx_scatter;
bool option_descriptors;
unsigned int min_interrupt_mode;
- unsigned int max_interrupt_mode;
unsigned int timer_period_max;
netdev_features_t offload_features;
int mcdi_max_ver;
@@ -1524,11 +1535,18 @@ efx_get_channel(struct efx_nic *efx, unsigned index)
_channel = _channel->channel ? \
(_efx)->channel[_channel->channel - 1] : NULL)
+static inline struct efx_channel *
+efx_get_tx_channel(struct efx_nic *efx, unsigned int index)
+{
+ EFX_WARN_ON_ONCE_PARANOID(index >= efx->n_tx_channels);
+ return efx->channel[efx->tx_channel_offset + index];
+}
+
static inline struct efx_tx_queue *
efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
{
EFX_WARN_ON_ONCE_PARANOID(index >= efx->n_tx_channels ||
- type >= EFX_TXQ_TYPES);
+ type >= efx->tx_queues_per_channel);
return &efx->channel[efx->tx_channel_offset + index]->tx_queue[type];
}
@@ -1550,18 +1568,18 @@ static inline bool efx_channel_has_tx_queues(struct efx_channel *channel)
return true;
}
-static inline struct efx_tx_queue *
-efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type)
+static inline unsigned int efx_channel_num_tx_queues(struct efx_channel *channel)
{
- EFX_WARN_ON_ONCE_PARANOID(!efx_channel_has_tx_queues(channel) ||
- type >= EFX_TXQ_TYPES);
- return &channel->tx_queue[type];
+ if (efx_channel_is_xdp_tx(channel))
+ return channel->efx->xdp_tx_per_channel;
+ return channel->efx->tx_queues_per_channel;
}
-static inline bool efx_tx_queue_used(struct efx_tx_queue *tx_queue)
+static inline struct efx_tx_queue *
+efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type)
{
- return !(tx_queue->efx->net_dev->num_tc < 2 &&
- tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI);
+ EFX_WARN_ON_ONCE_PARANOID(type >= efx_channel_num_tx_queues(channel));
+ return &channel->tx_queue[type];
}
/* Iterate over all TX queues belonging to a channel */
@@ -1570,18 +1588,8 @@ static inline bool efx_tx_queue_used(struct efx_tx_queue *tx_queue)
; \
else \
for (_tx_queue = (_channel)->tx_queue; \
- _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES && \
- (efx_tx_queue_used(_tx_queue) || \
- efx_channel_is_xdp_tx(_channel)); \
- _tx_queue++)
-
-/* Iterate over all possible TX queues belonging to a channel */
-#define efx_for_each_possible_channel_tx_queue(_tx_queue, _channel) \
- if (!efx_channel_has_tx_queues(_channel)) \
- ; \
- else \
- for (_tx_queue = (_channel)->tx_queue; \
- _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \
+ _tx_queue < (_channel)->tx_queue + \
+ efx_channel_num_tx_queues(_channel); \
_tx_queue++)
static inline bool efx_channel_has_rx_queue(struct efx_channel *channel)
@@ -1664,6 +1672,24 @@ static inline void efx_xmit_hwtstamp_pending(struct sk_buff *skb)
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
}
+/* Get the max fill level of the TX queues on this channel */
+static inline unsigned int
+efx_channel_tx_fill_level(struct efx_channel *channel)
+{
+ struct efx_tx_queue *tx_queue;
+ unsigned int fill_level = 0;
+
+ /* This function is currently only used by EF100, which maybe
+ * could do something simpler and just compute the fill level
+ * of the single TXQ that's really in use.
+ */
+ efx_for_each_channel_tx_queue(tx_queue, channel)
+ fill_level = max(fill_level,
+ tx_queue->insert_count - tx_queue->read_count);
+
+ return fill_level;
+}
+
/* Get all supported features.
* If a feature is not fixed, it is present in hw_features.
* If a feature is fixed, it does not present in hw_features, but
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index b0baa70fbba7..d994d136bb03 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -20,6 +20,7 @@
#include "farch_regs.h"
#include "io.h"
#include "workarounds.h"
+#include "mcdi_pcol.h"
/**************************************************************************
*
@@ -471,6 +472,49 @@ size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count,
}
/**
+ * efx_nic_copy_stats - Copy stats from the DMA buffer in to an
+ * intermediate buffer. This is used to get a consistent
+ * set of stats while the DMA buffer can be written at any time
+ * by the NIC.
+ * @efx: The associated NIC.
+ * @dest: Destination buffer. Must be the same size as the DMA buffer.
+ */
+int efx_nic_copy_stats(struct efx_nic *efx, __le64 *dest)
+{
+ __le64 *dma_stats = efx->stats_buffer.addr;
+ __le64 generation_start, generation_end;
+ int rc = 0, retry;
+
+ if (!dest)
+ return 0;
+
+ if (!dma_stats)
+ goto return_zeroes;
+
+ /* If we're unlucky enough to read statistics during the DMA, wait
+ * up to 10ms for it to finish (typically takes <500us)
+ */
+ for (retry = 0; retry < 100; ++retry) {
+ generation_end = dma_stats[efx->num_mac_stats - 1];
+ if (generation_end == EFX_MC_STATS_GENERATION_INVALID)
+ goto return_zeroes;
+ rmb();
+ memcpy(dest, dma_stats, efx->num_mac_stats * sizeof(__le64));
+ rmb();
+ generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
+ if (generation_end == generation_start)
+ return 0; /* return good data */
+ udelay(100);
+ }
+
+ rc = -EIO;
+
+return_zeroes:
+ memset(dest, 0, efx->num_mac_stats * sizeof(u64));
+ return rc;
+}
+
+/**
* efx_nic_update_stats - Convert statistics DMA buffer to array of u64
* @desc: Array of &struct efx_hw_stat_desc describing the DMA buffer
* layout. DMA widths of 0, 16, 32 and 64 are supported; where
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 8f73c5d996eb..724e2776b585 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -8,133 +8,11 @@
#ifndef EFX_NIC_H
#define EFX_NIC_H
-#include <linux/net_tstamp.h>
-#include "net_driver.h"
+#include "nic_common.h"
#include "efx.h"
-#include "efx_common.h"
-#include "mcdi.h"
-
-enum {
- /* Revisions 0-2 were Falcon A0, A1 and B0 respectively.
- * They are not supported by this driver but these revision numbers
- * form part of the ethtool API for register dumping.
- */
- EFX_REV_SIENA_A0 = 3,
- EFX_REV_HUNT_A0 = 4,
-};
-
-static inline int efx_nic_rev(struct efx_nic *efx)
-{
- return efx->type->revision;
-}
u32 efx_farch_fpga_ver(struct efx_nic *efx);
-/* Read the current event from the event queue */
-static inline efx_qword_t *efx_event(struct efx_channel *channel,
- unsigned int index)
-{
- return ((efx_qword_t *) (channel->eventq.buf.addr)) +
- (index & channel->eventq_mask);
-}
-
-/* See if an event is present
- *
- * We check both the high and low dword of the event for all ones. We
- * wrote all ones when we cleared the event, and no valid event can
- * have all ones in either its high or low dwords. This approach is
- * robust against reordering.
- *
- * Note that using a single 64-bit comparison is incorrect; even
- * though the CPU read will be atomic, the DMA write may not be.
- */
-static inline int efx_event_present(efx_qword_t *event)
-{
- return !(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
- EFX_DWORD_IS_ALL_ONES(event->dword[1]));
-}
-
-/* Returns a pointer to the specified transmit descriptor in the TX
- * descriptor queue belonging to the specified channel.
- */
-static inline efx_qword_t *
-efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
-{
- return ((efx_qword_t *) (tx_queue->txd.buf.addr)) + index;
-}
-
-/* Get partner of a TX queue, seen as part of the same net core queue */
-static struct efx_tx_queue *efx_tx_queue_partner(struct efx_tx_queue *tx_queue)
-{
- if (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD)
- return tx_queue - EFX_TXQ_TYPE_OFFLOAD;
- else
- return tx_queue + EFX_TXQ_TYPE_OFFLOAD;
-}
-
-/* Report whether this TX queue would be empty for the given write_count.
- * May return false negative.
- */
-static inline bool __efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue,
- unsigned int write_count)
-{
- unsigned int empty_read_count = READ_ONCE(tx_queue->empty_read_count);
-
- if (empty_read_count == 0)
- return false;
-
- return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
-}
-
-/* Report whether the NIC considers this TX queue empty, using
- * packet_write_count (the write count recorded for the last completable
- * doorbell push). May return false negative. EF10 only, which is OK
- * because only EF10 supports PIO.
- */
-static inline bool efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue)
-{
- EFX_WARN_ON_ONCE_PARANOID(!tx_queue->efx->type->option_descriptors);
- return __efx_nic_tx_is_empty(tx_queue, tx_queue->packet_write_count);
-}
-
-/* Decide whether we can use TX PIO, ie. write packet data directly into
- * a buffer on the device. This can reduce latency at the expense of
- * throughput, so we only do this if both hardware and software TX rings
- * are empty. This also ensures that only one packet at a time can be
- * using the PIO buffer.
- */
-static inline bool efx_nic_may_tx_pio(struct efx_tx_queue *tx_queue)
-{
- struct efx_tx_queue *partner = efx_tx_queue_partner(tx_queue);
-
- return tx_queue->piobuf && efx_nic_tx_is_empty(tx_queue) &&
- efx_nic_tx_is_empty(partner);
-}
-
-/* Decide whether to push a TX descriptor to the NIC vs merely writing
- * the doorbell. This can reduce latency when we are adding a single
- * descriptor to an empty queue, but is otherwise pointless. Further,
- * Falcon and Siena have hardware bugs (SF bug 33851) that may be
- * triggered if we don't check this.
- * We use the write_count used for the last doorbell push, to get the
- * NIC's view of the tx queue.
- */
-static inline bool efx_nic_may_push_tx_desc(struct efx_tx_queue *tx_queue,
- unsigned int write_count)
-{
- bool was_empty = __efx_nic_tx_is_empty(tx_queue, write_count);
-
- tx_queue->empty_read_count = 0;
- return was_empty && tx_queue->write_count - write_count == 1;
-}
-
-/* Returns a pointer to the specified descriptor in the RX descriptor queue */
-static inline efx_qword_t *
-efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
-{
- return ((efx_qword_t *) (rx_queue->rxd.buf.addr)) + index;
-}
-
enum {
PHY_TYPE_NONE = 0,
PHY_TYPE_TXC43128 = 1,
@@ -147,18 +25,6 @@ enum {
PHY_TYPE_SFT9001B = 10,
};
-/* Alignment of PCIe DMA boundaries (4KB) */
-#define EFX_PAGE_SIZE 4096
-/* Size and alignment of buffer table entries (same) */
-#define EFX_BUF_SIZE EFX_PAGE_SIZE
-
-/* NIC-generic software stats */
-enum {
- GENERIC_STAT_rx_noskb_drops,
- GENERIC_STAT_rx_nodesc_trunc,
- GENERIC_STAT_COUNT
-};
-
enum {
SIENA_STAT_tx_bytes = GENERIC_STAT_COUNT,
SIENA_STAT_tx_good_bytes,
@@ -368,6 +234,7 @@ enum {
* @piobuf_size: size of a single PIO buffer
* @must_restore_piobufs: Flag: PIO buffers have yet to be restored after MC
* reboot
+ * @mc_stats: Scratch buffer for converting statistics to the kernel's format
* @stats: Hardware statistics
* @workaround_35388: Flag: firmware supports workaround for bug 35388
* @workaround_26807: Flag: firmware supports workaround for bug 26807
@@ -404,6 +271,7 @@ struct efx_ef10_nic_data {
unsigned int piobuf_handle[EF10_TX_PIOBUF_COUNT];
u16 piobuf_size;
bool must_restore_piobufs;
+ __le64 *mc_stats;
u64 stats[EF10_STAT_COUNT];
bool workaround_35388;
bool workaround_26807;
@@ -432,123 +300,12 @@ struct efx_ef10_nic_data {
int efx_init_sriov(void);
void efx_fini_sriov(void);
-struct ethtool_ts_info;
-int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel);
-void efx_ptp_defer_probe_with_channel(struct efx_nic *efx);
-struct efx_channel *efx_ptp_channel(struct efx_nic *efx);
-void efx_ptp_remove(struct efx_nic *efx);
-int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr);
-int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr);
-void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
-bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
-int efx_ptp_get_mode(struct efx_nic *efx);
-int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
- unsigned int new_mode);
-int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
-void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
-size_t efx_ptp_describe_stats(struct efx_nic *efx, u8 *strings);
-size_t efx_ptp_update_stats(struct efx_nic *efx, u64 *stats);
-void efx_time_sync_event(struct efx_channel *channel, efx_qword_t *ev);
-void __efx_rx_skb_attach_timestamp(struct efx_channel *channel,
- struct sk_buff *skb);
-static inline void efx_rx_skb_attach_timestamp(struct efx_channel *channel,
- struct sk_buff *skb)
-{
- if (channel->sync_events_state == SYNC_EVENTS_VALID)
- __efx_rx_skb_attach_timestamp(channel, skb);
-}
-void efx_ptp_start_datapath(struct efx_nic *efx);
-void efx_ptp_stop_datapath(struct efx_nic *efx);
-bool efx_ptp_use_mac_tx_timestamps(struct efx_nic *efx);
-ktime_t efx_ptp_nic_to_kernel_time(struct efx_tx_queue *tx_queue);
-
-extern const struct efx_nic_type falcon_a1_nic_type;
-extern const struct efx_nic_type falcon_b0_nic_type;
extern const struct efx_nic_type siena_a0_nic_type;
extern const struct efx_nic_type efx_hunt_a0_nic_type;
extern const struct efx_nic_type efx_hunt_a0_vf_nic_type;
-/**************************************************************************
- *
- * Externs
- *
- **************************************************************************
- */
-
int falcon_probe_board(struct efx_nic *efx, u16 revision_info);
-/* TX data path */
-static inline int efx_nic_probe_tx(struct efx_tx_queue *tx_queue)
-{
- return tx_queue->efx->type->tx_probe(tx_queue);
-}
-static inline void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
-{
- tx_queue->efx->type->tx_init(tx_queue);
-}
-static inline void efx_nic_remove_tx(struct efx_tx_queue *tx_queue)
-{
- tx_queue->efx->type->tx_remove(tx_queue);
-}
-static inline void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
-{
- tx_queue->efx->type->tx_write(tx_queue);
-}
-
-int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
- bool *data_mapped);
-
-/* RX data path */
-static inline int efx_nic_probe_rx(struct efx_rx_queue *rx_queue)
-{
- return rx_queue->efx->type->rx_probe(rx_queue);
-}
-static inline void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
-{
- rx_queue->efx->type->rx_init(rx_queue);
-}
-static inline void efx_nic_remove_rx(struct efx_rx_queue *rx_queue)
-{
- rx_queue->efx->type->rx_remove(rx_queue);
-}
-static inline void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue)
-{
- rx_queue->efx->type->rx_write(rx_queue);
-}
-static inline void efx_nic_generate_fill_event(struct efx_rx_queue *rx_queue)
-{
- rx_queue->efx->type->rx_defer_refill(rx_queue);
-}
-
-/* Event data path */
-static inline int efx_nic_probe_eventq(struct efx_channel *channel)
-{
- return channel->efx->type->ev_probe(channel);
-}
-static inline int efx_nic_init_eventq(struct efx_channel *channel)
-{
- return channel->efx->type->ev_init(channel);
-}
-static inline void efx_nic_fini_eventq(struct efx_channel *channel)
-{
- channel->efx->type->ev_fini(channel);
-}
-static inline void efx_nic_remove_eventq(struct efx_channel *channel)
-{
- channel->efx->type->ev_remove(channel);
-}
-static inline int
-efx_nic_process_eventq(struct efx_channel *channel, int quota)
-{
- return channel->efx->type->ev_process(channel, quota);
-}
-static inline void efx_nic_eventq_read_ack(struct efx_channel *channel)
-{
- channel->efx->type->ev_read_ack(channel);
-}
-
-void efx_nic_event_test_start(struct efx_channel *channel);
-
/* Falcon/Siena queue operations */
int efx_farch_tx_probe(struct efx_tx_queue *tx_queue);
void efx_farch_tx_init(struct efx_tx_queue *tx_queue);
@@ -598,31 +355,6 @@ bool efx_farch_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
#endif
void efx_farch_filter_sync_rx_mode(struct efx_nic *efx);
-bool efx_nic_event_present(struct efx_channel *channel);
-
-/* Some statistics are computed as A - B where A and B each increase
- * linearly with some hardware counter(s) and the counters are read
- * asynchronously. If the counters contributing to B are always read
- * after those contributing to A, the computed value may be lower than
- * the true value by some variable amount, and may decrease between
- * subsequent computations.
- *
- * We should never allow statistics to decrease or to exceed the true
- * value. Since the computed value will never be greater than the
- * true value, we can achieve this by only storing the computed value
- * when it increases.
- */
-static inline void efx_update_diff_stat(u64 *stat, u64 diff)
-{
- if ((s64)(diff - *stat) > 0)
- *stat = diff;
-}
-
-/* Interrupts */
-int efx_nic_init_interrupt(struct efx_nic *efx);
-int efx_nic_irq_test_start(struct efx_nic *efx);
-void efx_nic_fini_interrupt(struct efx_nic *efx);
-
/* Falcon/Siena interrupts */
void efx_farch_irq_enable_master(struct efx_nic *efx);
int efx_farch_irq_test_generate(struct efx_nic *efx);
@@ -631,17 +363,7 @@ irqreturn_t efx_farch_msi_interrupt(int irq, void *dev_id);
irqreturn_t efx_farch_legacy_interrupt(int irq, void *dev_id);
irqreturn_t efx_farch_fatal_interrupt(struct efx_nic *efx);
-static inline int efx_nic_event_test_irq_cpu(struct efx_channel *channel)
-{
- return READ_ONCE(channel->event_test_cpu);
-}
-static inline int efx_nic_irq_test_irq_cpu(struct efx_nic *efx)
-{
- return READ_ONCE(efx->last_irq_cpu);
-}
-
/* Global Resources */
-int efx_nic_flush_queues(struct efx_nic *efx);
void siena_prepare_flush(struct efx_nic *efx);
int efx_farch_fini_dmaq(struct efx_nic *efx);
void efx_farch_finish_flr(struct efx_nic *efx);
@@ -651,14 +373,9 @@ void falcon_stop_nic_stats(struct efx_nic *efx);
int falcon_reset_xaui(struct efx_nic *efx);
void efx_farch_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw);
void efx_farch_init_common(struct efx_nic *efx);
-void efx_ef10_handle_drain_event(struct efx_nic *efx);
void efx_farch_rx_push_indir_table(struct efx_nic *efx);
void efx_farch_rx_pull_indir_table(struct efx_nic *efx);
-int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer,
- unsigned int len, gfp_t gfp_flags);
-void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer);
-
/* Tests */
struct efx_farch_register_test {
unsigned address;
@@ -669,18 +386,6 @@ int efx_farch_test_registers(struct efx_nic *efx,
const struct efx_farch_register_test *regs,
size_t n_regs);
-size_t efx_nic_get_regs_len(struct efx_nic *efx);
-void efx_nic_get_regs(struct efx_nic *efx, void *buf);
-
-size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count,
- const unsigned long *mask, u8 *names);
-void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count,
- const unsigned long *mask, u64 *stats,
- const void *dma_buf, bool accumulate);
-void efx_nic_fix_nodesc_drop_stat(struct efx_nic *efx, u64 *stat);
-
-#define EFX_MAX_FLUSH_TIME 5000
-
void efx_farch_generate_event(struct efx_nic *efx, unsigned int evq,
efx_qword_t *event);
diff --git a/drivers/net/ethernet/sfc/nic_common.h b/drivers/net/ethernet/sfc/nic_common.h
new file mode 100644
index 000000000000..974107354087
--- /dev/null
+++ b/drivers/net/ethernet/sfc/nic_common.h
@@ -0,0 +1,286 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2013 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ */
+
+#ifndef EFX_NIC_COMMON_H
+#define EFX_NIC_COMMON_H
+
+#include "net_driver.h"
+#include "efx_common.h"
+#include "mcdi.h"
+#include "ptp.h"
+
+enum {
+ /* Revisions 0-2 were Falcon A0, A1 and B0 respectively.
+ * They are not supported by this driver but these revision numbers
+ * form part of the ethtool API for register dumping.
+ */
+ EFX_REV_SIENA_A0 = 3,
+ EFX_REV_HUNT_A0 = 4,
+ EFX_REV_EF100 = 5,
+};
+
+static inline int efx_nic_rev(struct efx_nic *efx)
+{
+ return efx->type->revision;
+}
+
+/* Read the current event from the event queue */
+static inline efx_qword_t *efx_event(struct efx_channel *channel,
+ unsigned int index)
+{
+ return ((efx_qword_t *) (channel->eventq.buf.addr)) +
+ (index & channel->eventq_mask);
+}
+
+/* See if an event is present
+ *
+ * We check both the high and low dword of the event for all ones. We
+ * wrote all ones when we cleared the event, and no valid event can
+ * have all ones in either its high or low dwords. This approach is
+ * robust against reordering.
+ *
+ * Note that using a single 64-bit comparison is incorrect; even
+ * though the CPU read will be atomic, the DMA write may not be.
+ */
+static inline int efx_event_present(efx_qword_t *event)
+{
+ return !(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
+ EFX_DWORD_IS_ALL_ONES(event->dword[1]));
+}
+
+/* Returns a pointer to the specified transmit descriptor in the TX
+ * descriptor queue belonging to the specified channel.
+ */
+static inline efx_qword_t *
+efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
+{
+ return ((efx_qword_t *) (tx_queue->txd.buf.addr)) + index;
+}
+
+/* Report whether this TX queue would be empty for the given write_count.
+ * May return false negative.
+ */
+static inline bool __efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue,
+ unsigned int write_count)
+{
+ unsigned int empty_read_count = READ_ONCE(tx_queue->empty_read_count);
+
+ if (empty_read_count == 0)
+ return false;
+
+ return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
+}
+
+/* Report whether the NIC considers this TX queue empty, using
+ * packet_write_count (the write count recorded for the last completable
+ * doorbell push). May return false negative. EF10 only, which is OK
+ * because only EF10 supports PIO.
+ */
+static inline bool efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue)
+{
+ EFX_WARN_ON_ONCE_PARANOID(!tx_queue->efx->type->option_descriptors);
+ return __efx_nic_tx_is_empty(tx_queue, tx_queue->packet_write_count);
+}
+
+/* Get partner of a TX queue, seen as part of the same net core queue */
+/* XXX is this a thing on EF100? */
+static inline struct efx_tx_queue *efx_tx_queue_partner(struct efx_tx_queue *tx_queue)
+{
+ if (tx_queue->label & EFX_TXQ_TYPE_OFFLOAD)
+ return tx_queue - EFX_TXQ_TYPE_OFFLOAD;
+ else
+ return tx_queue + EFX_TXQ_TYPE_OFFLOAD;
+}
+
+/* Decide whether we can use TX PIO, ie. write packet data directly into
+ * a buffer on the device. This can reduce latency at the expense of
+ * throughput, so we only do this if both hardware and software TX rings
+ * are empty. This also ensures that only one packet at a time can be
+ * using the PIO buffer.
+ */
+static inline bool efx_nic_may_tx_pio(struct efx_tx_queue *tx_queue)
+{
+ struct efx_tx_queue *partner = efx_tx_queue_partner(tx_queue);
+
+ return tx_queue->piobuf && efx_nic_tx_is_empty(tx_queue) &&
+ efx_nic_tx_is_empty(partner);
+}
+
+int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
+ bool *data_mapped);
+
+/* Decide whether to push a TX descriptor to the NIC vs merely writing
+ * the doorbell. This can reduce latency when we are adding a single
+ * descriptor to an empty queue, but is otherwise pointless. Further,
+ * Falcon and Siena have hardware bugs (SF bug 33851) that may be
+ * triggered if we don't check this.
+ * We use the write_count used for the last doorbell push, to get the
+ * NIC's view of the tx queue.
+ */
+static inline bool efx_nic_may_push_tx_desc(struct efx_tx_queue *tx_queue,
+ unsigned int write_count)
+{
+ bool was_empty = __efx_nic_tx_is_empty(tx_queue, write_count);
+
+ tx_queue->empty_read_count = 0;
+ return was_empty && tx_queue->write_count - write_count == 1;
+}
+
+/* Returns a pointer to the specified descriptor in the RX descriptor queue */
+static inline efx_qword_t *
+efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
+{
+ return ((efx_qword_t *) (rx_queue->rxd.buf.addr)) + index;
+}
+
+/* Alignment of PCIe DMA boundaries (4KB) */
+#define EFX_PAGE_SIZE 4096
+/* Size and alignment of buffer table entries (same) */
+#define EFX_BUF_SIZE EFX_PAGE_SIZE
+
+/* NIC-generic software stats */
+enum {
+ GENERIC_STAT_rx_noskb_drops,
+ GENERIC_STAT_rx_nodesc_trunc,
+ GENERIC_STAT_COUNT
+};
+
+#define EFX_GENERIC_SW_STAT(ext_name) \
+ [GENERIC_STAT_ ## ext_name] = { #ext_name, 0, 0 }
+
+/* TX data path */
+static inline int efx_nic_probe_tx(struct efx_tx_queue *tx_queue)
+{
+ return tx_queue->efx->type->tx_probe(tx_queue);
+}
+static inline void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
+{
+ tx_queue->efx->type->tx_init(tx_queue);
+}
+static inline void efx_nic_remove_tx(struct efx_tx_queue *tx_queue)
+{
+ if (tx_queue->efx->type->tx_remove)
+ tx_queue->efx->type->tx_remove(tx_queue);
+}
+static inline void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
+{
+ tx_queue->efx->type->tx_write(tx_queue);
+}
+
+/* RX data path */
+static inline int efx_nic_probe_rx(struct efx_rx_queue *rx_queue)
+{
+ return rx_queue->efx->type->rx_probe(rx_queue);
+}
+static inline void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
+{
+ rx_queue->efx->type->rx_init(rx_queue);
+}
+static inline void efx_nic_remove_rx(struct efx_rx_queue *rx_queue)
+{
+ rx_queue->efx->type->rx_remove(rx_queue);
+}
+static inline void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue)
+{
+ rx_queue->efx->type->rx_write(rx_queue);
+}
+static inline void efx_nic_generate_fill_event(struct efx_rx_queue *rx_queue)
+{
+ rx_queue->efx->type->rx_defer_refill(rx_queue);
+}
+
+/* Event data path */
+static inline int efx_nic_probe_eventq(struct efx_channel *channel)
+{
+ return channel->efx->type->ev_probe(channel);
+}
+static inline int efx_nic_init_eventq(struct efx_channel *channel)
+{
+ return channel->efx->type->ev_init(channel);
+}
+static inline void efx_nic_fini_eventq(struct efx_channel *channel)
+{
+ channel->efx->type->ev_fini(channel);
+}
+static inline void efx_nic_remove_eventq(struct efx_channel *channel)
+{
+ channel->efx->type->ev_remove(channel);
+}
+static inline int
+efx_nic_process_eventq(struct efx_channel *channel, int quota)
+{
+ return channel->efx->type->ev_process(channel, quota);
+}
+static inline void efx_nic_eventq_read_ack(struct efx_channel *channel)
+{
+ channel->efx->type->ev_read_ack(channel);
+}
+
+void efx_nic_event_test_start(struct efx_channel *channel);
+
+bool efx_nic_event_present(struct efx_channel *channel);
+
+static inline void efx_sensor_event(struct efx_nic *efx, efx_qword_t *ev)
+{
+ if (efx->type->sensor_event)
+ efx->type->sensor_event(efx, ev);
+}
+
+/* Some statistics are computed as A - B where A and B each increase
+ * linearly with some hardware counter(s) and the counters are read
+ * asynchronously. If the counters contributing to B are always read
+ * after those contributing to A, the computed value may be lower than
+ * the true value by some variable amount, and may decrease between
+ * subsequent computations.
+ *
+ * We should never allow statistics to decrease or to exceed the true
+ * value. Since the computed value will never be greater than the
+ * true value, we can achieve this by only storing the computed value
+ * when it increases.
+ */
+static inline void efx_update_diff_stat(u64 *stat, u64 diff)
+{
+ if ((s64)(diff - *stat) > 0)
+ *stat = diff;
+}
+
+/* Interrupts */
+int efx_nic_init_interrupt(struct efx_nic *efx);
+int efx_nic_irq_test_start(struct efx_nic *efx);
+void efx_nic_fini_interrupt(struct efx_nic *efx);
+
+static inline int efx_nic_event_test_irq_cpu(struct efx_channel *channel)
+{
+ return READ_ONCE(channel->event_test_cpu);
+}
+static inline int efx_nic_irq_test_irq_cpu(struct efx_nic *efx)
+{
+ return READ_ONCE(efx->last_irq_cpu);
+}
+
+/* Global Resources */
+int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer,
+ unsigned int len, gfp_t gfp_flags);
+void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer);
+
+size_t efx_nic_get_regs_len(struct efx_nic *efx);
+void efx_nic_get_regs(struct efx_nic *efx, void *buf);
+
+#define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1))
+
+size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count,
+ const unsigned long *mask, u8 *names);
+int efx_nic_copy_stats(struct efx_nic *efx, __le64 *dest);
+void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count,
+ const unsigned long *mask, u64 *stats,
+ const void *dma_buf, bool accumulate);
+void efx_nic_fix_nodesc_drop_stat(struct efx_nic *efx, u64 *stat);
+
+#define EFX_MAX_FLUSH_TIME 5000
+
+#endif /* EFX_NIC_COMMON_H */
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 04c7283d205e..bea4725a4499 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -35,7 +35,6 @@
#include <linux/time.h>
#include <linux/ktime.h>
#include <linux/module.h>
-#include <linux/net_tstamp.h>
#include <linux/pps_kernel.h>
#include <linux/ptp_clock_kernel.h>
#include "net_driver.h"
@@ -44,7 +43,7 @@
#include "mcdi_pcol.h"
#include "io.h"
#include "farch_regs.h"
-#include "nic.h"
+#include "nic.h" /* indirectly includes ptp.h */
/* Maximum number of events expected to make up a PTP event */
#define MAX_EVENT_FRAGS 3
@@ -352,7 +351,7 @@ static int efx_phc_enable(struct ptp_clock_info *ptp,
bool efx_ptp_use_mac_tx_timestamps(struct efx_nic *efx)
{
- return efx_has_cap(efx, TX_MAC_TIMESTAMPING, FLAGS2);
+ return efx_has_cap(efx, TX_MAC_TIMESTAMPING);
}
/* PTP 'extra' channel is still a traffic channel, but we only create TX queues
@@ -1155,17 +1154,15 @@ static void efx_ptp_drop_time_expired_events(struct efx_nic *efx)
/* Drop time-expired events */
spin_lock_bh(&ptp->evt_lock);
- if (!list_empty(&ptp->evt_list)) {
- list_for_each_safe(cursor, next, &ptp->evt_list) {
- struct efx_ptp_event_rx *evt;
-
- evt = list_entry(cursor, struct efx_ptp_event_rx,
- link);
- if (time_after(jiffies, evt->expiry)) {
- list_move(&evt->link, &ptp->evt_free_list);
- netif_warn(efx, hw, efx->net_dev,
- "PTP rx event dropped\n");
- }
+ list_for_each_safe(cursor, next, &ptp->evt_list) {
+ struct efx_ptp_event_rx *evt;
+
+ evt = list_entry(cursor, struct efx_ptp_event_rx,
+ link);
+ if (time_after(jiffies, evt->expiry)) {
+ list_move(&evt->link, &ptp->evt_free_list);
+ netif_warn(efx, hw, efx->net_dev,
+ "PTP rx event dropped\n");
}
}
spin_unlock_bh(&ptp->evt_lock);
diff --git a/drivers/net/ethernet/sfc/ptp.h b/drivers/net/ethernet/sfc/ptp.h
new file mode 100644
index 000000000000..9855e8c9e544
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ptp.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2013 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx Inc.
+ */
+
+#ifndef EFX_PTP_H
+#define EFX_PTP_H
+
+#include <linux/net_tstamp.h>
+#include "net_driver.h"
+
+struct ethtool_ts_info;
+int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel);
+void efx_ptp_defer_probe_with_channel(struct efx_nic *efx);
+struct efx_channel *efx_ptp_channel(struct efx_nic *efx);
+void efx_ptp_remove(struct efx_nic *efx);
+int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr);
+int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr);
+void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
+bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
+int efx_ptp_get_mode(struct efx_nic *efx);
+int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
+ unsigned int new_mode);
+int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
+void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
+size_t efx_ptp_describe_stats(struct efx_nic *efx, u8 *strings);
+size_t efx_ptp_update_stats(struct efx_nic *efx, u64 *stats);
+void efx_time_sync_event(struct efx_channel *channel, efx_qword_t *ev);
+void __efx_rx_skb_attach_timestamp(struct efx_channel *channel,
+ struct sk_buff *skb);
+static inline void efx_rx_skb_attach_timestamp(struct efx_channel *channel,
+ struct sk_buff *skb)
+{
+ if (channel->sync_events_state == SYNC_EVENTS_VALID)
+ __efx_rx_skb_attach_timestamp(channel, skb);
+}
+void efx_ptp_start_datapath(struct efx_nic *efx);
+void efx_ptp_stop_datapath(struct efx_nic *efx);
+bool efx_ptp_use_mac_tx_timestamps(struct efx_nic *efx);
+ktime_t efx_ptp_nic_to_kernel_time(struct efx_tx_queue *tx_queue);
+
+#endif /* EFX_PTP_H */
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index c01916cff507..59a43d586967 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -40,14 +40,6 @@
#define EFX_RX_MAX_FRAGS DIV_ROUND_UP(EFX_MAX_FRAME_LEN(EFX_MAX_MTU), \
EFX_RX_USR_BUF_SIZE)
-static inline void efx_sync_rx_buffer(struct efx_nic *efx,
- struct efx_rx_buffer *rx_buf,
- unsigned int len)
-{
- dma_sync_single_for_cpu(&efx->pci_dev->dev, rx_buf->dma_addr, len,
- DMA_FROM_DEVICE);
-}
-
static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
struct efx_rx_buffer *rx_buf,
int len)
@@ -411,243 +403,9 @@ void __efx_rx_packet(struct efx_channel *channel)
rx_buf->flags &= ~EFX_RX_PKT_CSUMMED;
if ((rx_buf->flags & EFX_RX_PKT_TCP) && !channel->type->receive_skb)
- efx_rx_packet_gro(channel, rx_buf, channel->rx_pkt_n_frags, eh);
+ efx_rx_packet_gro(channel, rx_buf, channel->rx_pkt_n_frags, eh, 0);
else
efx_rx_deliver(channel, eh, rx_buf, channel->rx_pkt_n_frags);
out:
channel->rx_pkt_n_frags = 0;
}
-
-#ifdef CONFIG_RFS_ACCEL
-
-static void efx_filter_rfs_work(struct work_struct *data)
-{
- struct efx_async_filter_insertion *req = container_of(data, struct efx_async_filter_insertion,
- work);
- struct efx_nic *efx = netdev_priv(req->net_dev);
- struct efx_channel *channel = efx_get_channel(efx, req->rxq_index);
- int slot_idx = req - efx->rps_slot;
- struct efx_arfs_rule *rule;
- u16 arfs_id = 0;
- int rc;
-
- rc = efx->type->filter_insert(efx, &req->spec, true);
- if (rc >= 0)
- /* Discard 'priority' part of EF10+ filter ID (mcdi_filters) */
- rc %= efx->type->max_rx_ip_filters;
- if (efx->rps_hash_table) {
- spin_lock_bh(&efx->rps_hash_lock);
- rule = efx_rps_hash_find(efx, &req->spec);
- /* The rule might have already gone, if someone else's request
- * for the same spec was already worked and then expired before
- * we got around to our work. In that case we have nothing
- * tying us to an arfs_id, meaning that as soon as the filter
- * is considered for expiry it will be removed.
- */
- if (rule) {
- if (rc < 0)
- rule->filter_id = EFX_ARFS_FILTER_ID_ERROR;
- else
- rule->filter_id = rc;
- arfs_id = rule->arfs_id;
- }
- spin_unlock_bh(&efx->rps_hash_lock);
- }
- if (rc >= 0) {
- /* Remember this so we can check whether to expire the filter
- * later.
- */
- mutex_lock(&efx->rps_mutex);
- if (channel->rps_flow_id[rc] == RPS_FLOW_ID_INVALID)
- channel->rfs_filter_count++;
- channel->rps_flow_id[rc] = req->flow_id;
- mutex_unlock(&efx->rps_mutex);
-
- if (req->spec.ether_type == htons(ETH_P_IP))
- netif_info(efx, rx_status, efx->net_dev,
- "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d id %u]\n",
- (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
- req->spec.rem_host, ntohs(req->spec.rem_port),
- req->spec.loc_host, ntohs(req->spec.loc_port),
- req->rxq_index, req->flow_id, rc, arfs_id);
- else
- netif_info(efx, rx_status, efx->net_dev,
- "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d id %u]\n",
- (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
- req->spec.rem_host, ntohs(req->spec.rem_port),
- req->spec.loc_host, ntohs(req->spec.loc_port),
- req->rxq_index, req->flow_id, rc, arfs_id);
- channel->n_rfs_succeeded++;
- } else {
- if (req->spec.ether_type == htons(ETH_P_IP))
- netif_dbg(efx, rx_status, efx->net_dev,
- "failed to steer %s %pI4:%u:%pI4:%u to queue %u [flow %u rc %d id %u]\n",
- (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
- req->spec.rem_host, ntohs(req->spec.rem_port),
- req->spec.loc_host, ntohs(req->spec.loc_port),
- req->rxq_index, req->flow_id, rc, arfs_id);
- else
- netif_dbg(efx, rx_status, efx->net_dev,
- "failed to steer %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u rc %d id %u]\n",
- (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
- req->spec.rem_host, ntohs(req->spec.rem_port),
- req->spec.loc_host, ntohs(req->spec.loc_port),
- req->rxq_index, req->flow_id, rc, arfs_id);
- channel->n_rfs_failed++;
- /* We're overloading the NIC's filter tables, so let's do a
- * chunk of extra expiry work.
- */
- __efx_filter_rfs_expire(channel, min(channel->rfs_filter_count,
- 100u));
- }
-
- /* Release references */
- clear_bit(slot_idx, &efx->rps_slot_map);
- dev_put(req->net_dev);
-}
-
-int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
- u16 rxq_index, u32 flow_id)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_async_filter_insertion *req;
- struct efx_arfs_rule *rule;
- struct flow_keys fk;
- int slot_idx;
- bool new;
- int rc;
-
- /* find a free slot */
- for (slot_idx = 0; slot_idx < EFX_RPS_MAX_IN_FLIGHT; slot_idx++)
- if (!test_and_set_bit(slot_idx, &efx->rps_slot_map))
- break;
- if (slot_idx >= EFX_RPS_MAX_IN_FLIGHT)
- return -EBUSY;
-
- if (flow_id == RPS_FLOW_ID_INVALID) {
- rc = -EINVAL;
- goto out_clear;
- }
-
- if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) {
- rc = -EPROTONOSUPPORT;
- goto out_clear;
- }
-
- if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6)) {
- rc = -EPROTONOSUPPORT;
- goto out_clear;
- }
- if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) {
- rc = -EPROTONOSUPPORT;
- goto out_clear;
- }
-
- req = efx->rps_slot + slot_idx;
- efx_filter_init_rx(&req->spec, EFX_FILTER_PRI_HINT,
- efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0,
- rxq_index);
- req->spec.match_flags =
- EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
- EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
- EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
- req->spec.ether_type = fk.basic.n_proto;
- req->spec.ip_proto = fk.basic.ip_proto;
-
- if (fk.basic.n_proto == htons(ETH_P_IP)) {
- req->spec.rem_host[0] = fk.addrs.v4addrs.src;
- req->spec.loc_host[0] = fk.addrs.v4addrs.dst;
- } else {
- memcpy(req->spec.rem_host, &fk.addrs.v6addrs.src,
- sizeof(struct in6_addr));
- memcpy(req->spec.loc_host, &fk.addrs.v6addrs.dst,
- sizeof(struct in6_addr));
- }
-
- req->spec.rem_port = fk.ports.src;
- req->spec.loc_port = fk.ports.dst;
-
- if (efx->rps_hash_table) {
- /* Add it to ARFS hash table */
- spin_lock(&efx->rps_hash_lock);
- rule = efx_rps_hash_add(efx, &req->spec, &new);
- if (!rule) {
- rc = -ENOMEM;
- goto out_unlock;
- }
- if (new)
- rule->arfs_id = efx->rps_next_id++ % RPS_NO_FILTER;
- rc = rule->arfs_id;
- /* Skip if existing or pending filter already does the right thing */
- if (!new && rule->rxq_index == rxq_index &&
- rule->filter_id >= EFX_ARFS_FILTER_ID_PENDING)
- goto out_unlock;
- rule->rxq_index = rxq_index;
- rule->filter_id = EFX_ARFS_FILTER_ID_PENDING;
- spin_unlock(&efx->rps_hash_lock);
- } else {
- /* Without an ARFS hash table, we just use arfs_id 0 for all
- * filters. This means if multiple flows hash to the same
- * flow_id, all but the most recently touched will be eligible
- * for expiry.
- */
- rc = 0;
- }
-
- /* Queue the request */
- dev_hold(req->net_dev = net_dev);
- INIT_WORK(&req->work, efx_filter_rfs_work);
- req->rxq_index = rxq_index;
- req->flow_id = flow_id;
- schedule_work(&req->work);
- return rc;
-out_unlock:
- spin_unlock(&efx->rps_hash_lock);
-out_clear:
- clear_bit(slot_idx, &efx->rps_slot_map);
- return rc;
-}
-
-bool __efx_filter_rfs_expire(struct efx_channel *channel, unsigned int quota)
-{
- bool (*expire_one)(struct efx_nic *efx, u32 flow_id, unsigned int index);
- struct efx_nic *efx = channel->efx;
- unsigned int index, size, start;
- u32 flow_id;
-
- if (!mutex_trylock(&efx->rps_mutex))
- return false;
- expire_one = efx->type->filter_rfs_expire_one;
- index = channel->rfs_expire_index;
- start = index;
- size = efx->type->max_rx_ip_filters;
- while (quota) {
- flow_id = channel->rps_flow_id[index];
-
- if (flow_id != RPS_FLOW_ID_INVALID) {
- quota--;
- if (expire_one(efx, flow_id, index)) {
- netif_info(efx, rx_status, efx->net_dev,
- "expired filter %d [channel %u flow %u]\n",
- index, channel->channel, flow_id);
- channel->rps_flow_id[index] = RPS_FLOW_ID_INVALID;
- channel->rfs_filter_count--;
- }
- }
- if (++index == size)
- index = 0;
- /* If we were called with a quota that exceeds the total number
- * of filters in the table (which shouldn't happen, but could
- * if two callers race), ensure that we don't loop forever -
- * stop when we've examined every row of the table.
- */
- if (index == start)
- break;
- }
-
- channel->rfs_expire_index = index;
- mutex_unlock(&efx->rps_mutex);
- return true;
-}
-
-#endif /* CONFIG_RFS_ACCEL */
diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c
index e10c23833515..fb77c7bbe4af 100644
--- a/drivers/net/ethernet/sfc/rx_common.c
+++ b/drivers/net/ethernet/sfc/rx_common.c
@@ -510,7 +510,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic)
*/
void
efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
- unsigned int n_frags, u8 *eh)
+ unsigned int n_frags, u8 *eh, __wsum csum)
{
struct napi_struct *napi = &channel->napi_str;
struct efx_nic *efx = channel->efx;
@@ -528,8 +528,13 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
if (efx->net_dev->features & NETIF_F_RXHASH)
skb_set_hash(skb, efx_rx_buf_hash(efx, eh),
PKT_HASH_TYPE_L3);
- skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ?
- CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
+ if (csum) {
+ skb->csum = csum;
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ } else {
+ skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ?
+ CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
+ }
skb->csum_level = !!(rx_buf->flags & EFX_RX_PKT_CSUM_LEVEL);
for (;;) {
@@ -849,3 +854,237 @@ void efx_remove_filters(struct efx_nic *efx)
efx->type->filter_table_remove(efx);
up_write(&efx->filter_sem);
}
+
+#ifdef CONFIG_RFS_ACCEL
+
+static void efx_filter_rfs_work(struct work_struct *data)
+{
+ struct efx_async_filter_insertion *req = container_of(data, struct efx_async_filter_insertion,
+ work);
+ struct efx_nic *efx = netdev_priv(req->net_dev);
+ struct efx_channel *channel = efx_get_channel(efx, req->rxq_index);
+ int slot_idx = req - efx->rps_slot;
+ struct efx_arfs_rule *rule;
+ u16 arfs_id = 0;
+ int rc;
+
+ rc = efx->type->filter_insert(efx, &req->spec, true);
+ if (rc >= 0)
+ /* Discard 'priority' part of EF10+ filter ID (mcdi_filters) */
+ rc %= efx->type->max_rx_ip_filters;
+ if (efx->rps_hash_table) {
+ spin_lock_bh(&efx->rps_hash_lock);
+ rule = efx_rps_hash_find(efx, &req->spec);
+ /* The rule might have already gone, if someone else's request
+ * for the same spec was already worked and then expired before
+ * we got around to our work. In that case we have nothing
+ * tying us to an arfs_id, meaning that as soon as the filter
+ * is considered for expiry it will be removed.
+ */
+ if (rule) {
+ if (rc < 0)
+ rule->filter_id = EFX_ARFS_FILTER_ID_ERROR;
+ else
+ rule->filter_id = rc;
+ arfs_id = rule->arfs_id;
+ }
+ spin_unlock_bh(&efx->rps_hash_lock);
+ }
+ if (rc >= 0) {
+ /* Remember this so we can check whether to expire the filter
+ * later.
+ */
+ mutex_lock(&efx->rps_mutex);
+ if (channel->rps_flow_id[rc] == RPS_FLOW_ID_INVALID)
+ channel->rfs_filter_count++;
+ channel->rps_flow_id[rc] = req->flow_id;
+ mutex_unlock(&efx->rps_mutex);
+
+ if (req->spec.ether_type == htons(ETH_P_IP))
+ netif_info(efx, rx_status, efx->net_dev,
+ "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d id %u]\n",
+ (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
+ req->spec.rem_host, ntohs(req->spec.rem_port),
+ req->spec.loc_host, ntohs(req->spec.loc_port),
+ req->rxq_index, req->flow_id, rc, arfs_id);
+ else
+ netif_info(efx, rx_status, efx->net_dev,
+ "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d id %u]\n",
+ (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
+ req->spec.rem_host, ntohs(req->spec.rem_port),
+ req->spec.loc_host, ntohs(req->spec.loc_port),
+ req->rxq_index, req->flow_id, rc, arfs_id);
+ channel->n_rfs_succeeded++;
+ } else {
+ if (req->spec.ether_type == htons(ETH_P_IP))
+ netif_dbg(efx, rx_status, efx->net_dev,
+ "failed to steer %s %pI4:%u:%pI4:%u to queue %u [flow %u rc %d id %u]\n",
+ (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
+ req->spec.rem_host, ntohs(req->spec.rem_port),
+ req->spec.loc_host, ntohs(req->spec.loc_port),
+ req->rxq_index, req->flow_id, rc, arfs_id);
+ else
+ netif_dbg(efx, rx_status, efx->net_dev,
+ "failed to steer %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u rc %d id %u]\n",
+ (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
+ req->spec.rem_host, ntohs(req->spec.rem_port),
+ req->spec.loc_host, ntohs(req->spec.loc_port),
+ req->rxq_index, req->flow_id, rc, arfs_id);
+ channel->n_rfs_failed++;
+ /* We're overloading the NIC's filter tables, so let's do a
+ * chunk of extra expiry work.
+ */
+ __efx_filter_rfs_expire(channel, min(channel->rfs_filter_count,
+ 100u));
+ }
+
+ /* Release references */
+ clear_bit(slot_idx, &efx->rps_slot_map);
+ dev_put(req->net_dev);
+}
+
+int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
+ u16 rxq_index, u32 flow_id)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_async_filter_insertion *req;
+ struct efx_arfs_rule *rule;
+ struct flow_keys fk;
+ int slot_idx;
+ bool new;
+ int rc;
+
+ /* find a free slot */
+ for (slot_idx = 0; slot_idx < EFX_RPS_MAX_IN_FLIGHT; slot_idx++)
+ if (!test_and_set_bit(slot_idx, &efx->rps_slot_map))
+ break;
+ if (slot_idx >= EFX_RPS_MAX_IN_FLIGHT)
+ return -EBUSY;
+
+ if (flow_id == RPS_FLOW_ID_INVALID) {
+ rc = -EINVAL;
+ goto out_clear;
+ }
+
+ if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) {
+ rc = -EPROTONOSUPPORT;
+ goto out_clear;
+ }
+
+ if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6)) {
+ rc = -EPROTONOSUPPORT;
+ goto out_clear;
+ }
+ if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) {
+ rc = -EPROTONOSUPPORT;
+ goto out_clear;
+ }
+
+ req = efx->rps_slot + slot_idx;
+ efx_filter_init_rx(&req->spec, EFX_FILTER_PRI_HINT,
+ efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0,
+ rxq_index);
+ req->spec.match_flags =
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+ EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
+ req->spec.ether_type = fk.basic.n_proto;
+ req->spec.ip_proto = fk.basic.ip_proto;
+
+ if (fk.basic.n_proto == htons(ETH_P_IP)) {
+ req->spec.rem_host[0] = fk.addrs.v4addrs.src;
+ req->spec.loc_host[0] = fk.addrs.v4addrs.dst;
+ } else {
+ memcpy(req->spec.rem_host, &fk.addrs.v6addrs.src,
+ sizeof(struct in6_addr));
+ memcpy(req->spec.loc_host, &fk.addrs.v6addrs.dst,
+ sizeof(struct in6_addr));
+ }
+
+ req->spec.rem_port = fk.ports.src;
+ req->spec.loc_port = fk.ports.dst;
+
+ if (efx->rps_hash_table) {
+ /* Add it to ARFS hash table */
+ spin_lock(&efx->rps_hash_lock);
+ rule = efx_rps_hash_add(efx, &req->spec, &new);
+ if (!rule) {
+ rc = -ENOMEM;
+ goto out_unlock;
+ }
+ if (new)
+ rule->arfs_id = efx->rps_next_id++ % RPS_NO_FILTER;
+ rc = rule->arfs_id;
+ /* Skip if existing or pending filter already does the right thing */
+ if (!new && rule->rxq_index == rxq_index &&
+ rule->filter_id >= EFX_ARFS_FILTER_ID_PENDING)
+ goto out_unlock;
+ rule->rxq_index = rxq_index;
+ rule->filter_id = EFX_ARFS_FILTER_ID_PENDING;
+ spin_unlock(&efx->rps_hash_lock);
+ } else {
+ /* Without an ARFS hash table, we just use arfs_id 0 for all
+ * filters. This means if multiple flows hash to the same
+ * flow_id, all but the most recently touched will be eligible
+ * for expiry.
+ */
+ rc = 0;
+ }
+
+ /* Queue the request */
+ dev_hold(req->net_dev = net_dev);
+ INIT_WORK(&req->work, efx_filter_rfs_work);
+ req->rxq_index = rxq_index;
+ req->flow_id = flow_id;
+ schedule_work(&req->work);
+ return rc;
+out_unlock:
+ spin_unlock(&efx->rps_hash_lock);
+out_clear:
+ clear_bit(slot_idx, &efx->rps_slot_map);
+ return rc;
+}
+
+bool __efx_filter_rfs_expire(struct efx_channel *channel, unsigned int quota)
+{
+ bool (*expire_one)(struct efx_nic *efx, u32 flow_id, unsigned int index);
+ struct efx_nic *efx = channel->efx;
+ unsigned int index, size, start;
+ u32 flow_id;
+
+ if (!mutex_trylock(&efx->rps_mutex))
+ return false;
+ expire_one = efx->type->filter_rfs_expire_one;
+ index = channel->rfs_expire_index;
+ start = index;
+ size = efx->type->max_rx_ip_filters;
+ while (quota) {
+ flow_id = channel->rps_flow_id[index];
+
+ if (flow_id != RPS_FLOW_ID_INVALID) {
+ quota--;
+ if (expire_one(efx, flow_id, index)) {
+ netif_info(efx, rx_status, efx->net_dev,
+ "expired filter %d [channel %u flow %u]\n",
+ index, channel->channel, flow_id);
+ channel->rps_flow_id[index] = RPS_FLOW_ID_INVALID;
+ channel->rfs_filter_count--;
+ }
+ }
+ if (++index == size)
+ index = 0;
+ /* If we were called with a quota that exceeds the total number
+ * of filters in the table (which shouldn't happen, but could
+ * if two callers race), ensure that we don't loop forever -
+ * stop when we've examined every row of the table.
+ */
+ if (index == start)
+ break;
+ }
+
+ channel->rfs_expire_index = index;
+ mutex_unlock(&efx->rps_mutex);
+ return true;
+}
+
+#endif /* CONFIG_RFS_ACCEL */
diff --git a/drivers/net/ethernet/sfc/rx_common.h b/drivers/net/ethernet/sfc/rx_common.h
index c41f12a89477..207ccd8ba062 100644
--- a/drivers/net/ethernet/sfc/rx_common.h
+++ b/drivers/net/ethernet/sfc/rx_common.h
@@ -57,6 +57,15 @@ void efx_init_rx_buffer(struct efx_rx_queue *rx_queue,
unsigned int page_offset,
u16 flags);
void efx_unmap_rx_buffer(struct efx_nic *efx, struct efx_rx_buffer *rx_buf);
+
+static inline void efx_sync_rx_buffer(struct efx_nic *efx,
+ struct efx_rx_buffer *rx_buf,
+ unsigned int len)
+{
+ dma_sync_single_for_cpu(&efx->pci_dev->dev, rx_buf->dma_addr, len,
+ DMA_FROM_DEVICE);
+}
+
void efx_free_rx_buffers(struct efx_rx_queue *rx_queue,
struct efx_rx_buffer *rx_buf,
unsigned int num_bufs);
@@ -67,7 +76,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic);
void
efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
- unsigned int n_frags, u8 *eh);
+ unsigned int n_frags, u8 *eh, __wsum csum);
struct efx_rss_context *efx_alloc_rss_context_entry(struct efx_nic *efx);
struct efx_rss_context *efx_find_rss_context_entry(struct efx_nic *efx, u32 id);
@@ -89,6 +98,10 @@ struct efx_arfs_rule *efx_rps_hash_add(struct efx_nic *efx,
const struct efx_filter_spec *spec,
bool *new);
void efx_rps_hash_del(struct efx_nic *efx, const struct efx_filter_spec *spec);
+
+int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
+ u16 rxq_index, u32 flow_id);
+bool __efx_filter_rfs_expire(struct efx_channel *channel, unsigned int quota);
#endif
int efx_probe_filters(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c
index 1ae369022d7d..e71d6d37a317 100644
--- a/drivers/net/ethernet/sfc/selftest.c
+++ b/drivers/net/ethernet/sfc/selftest.c
@@ -445,7 +445,7 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
if (rc != NETDEV_TX_OK) {
netif_err(efx, drv, efx->net_dev,
"TX queue %d could not transmit packet %d of "
- "%d in %s loopback test\n", tx_queue->queue,
+ "%d in %s loopback test\n", tx_queue->label,
i + 1, state->packet_count,
LOOPBACK_MODE(efx));
@@ -497,7 +497,7 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue,
netif_err(efx, drv, efx->net_dev,
"TX queue %d saw only %d out of an expected %d "
"TX completion events in %s loopback test\n",
- tx_queue->queue, tx_done, state->packet_count,
+ tx_queue->label, tx_done, state->packet_count,
LOOPBACK_MODE(efx));
rc = -ETIMEDOUT;
/* Allow to fall through so we see the RX errors as well */
@@ -508,15 +508,15 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue,
netif_dbg(efx, drv, efx->net_dev,
"TX queue %d saw only %d out of an expected %d "
"received packets in %s loopback test\n",
- tx_queue->queue, rx_good, state->packet_count,
+ tx_queue->label, rx_good, state->packet_count,
LOOPBACK_MODE(efx));
rc = -ETIMEDOUT;
/* Fall through */
}
/* Update loopback test structure */
- lb_tests->tx_sent[tx_queue->queue] += state->packet_count;
- lb_tests->tx_done[tx_queue->queue] += tx_done;
+ lb_tests->tx_sent[tx_queue->label] += state->packet_count;
+ lb_tests->tx_done[tx_queue->label] += tx_done;
lb_tests->rx_good += rx_good;
lb_tests->rx_bad += rx_bad;
@@ -542,8 +542,8 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
state->flush = false;
netif_dbg(efx, drv, efx->net_dev,
- "TX queue %d testing %s loopback with %d packets\n",
- tx_queue->queue, LOOPBACK_MODE(efx),
+ "TX queue %d (hw %d) testing %s loopback with %d packets\n",
+ tx_queue->label, tx_queue->queue, LOOPBACK_MODE(efx),
state->packet_count);
efx_iterate_state(efx);
@@ -570,7 +570,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
netif_dbg(efx, drv, efx->net_dev,
"TX queue %d passed %s loopback test with a burst length "
- "of %d packets\n", tx_queue->queue, LOOPBACK_MODE(efx),
+ "of %d packets\n", tx_queue->label, LOOPBACK_MODE(efx),
state->packet_count);
return 0;
@@ -660,7 +660,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
/* Test all enabled types of TX queue */
efx_for_each_channel_tx_queue(tx_queue, channel) {
- state->offload_csum = (tx_queue->queue &
+ state->offload_csum = (tx_queue->label &
EFX_TXQ_TYPE_OFFLOAD);
rc = efx_test_loopback(tx_queue,
&tests->loopback[mode]);
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index 891e9fb6abec..a7ea630bb5e6 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -21,6 +21,7 @@
#include "workarounds.h"
#include "mcdi.h"
#include "mcdi_pcol.h"
+#include "mcdi_port.h"
#include "mcdi_port_common.h"
#include "selftest.h"
#include "siena_sriov.h"
@@ -276,7 +277,9 @@ static int siena_probe_nic(struct efx_nic *efx)
}
efx->max_channels = EFX_MAX_CHANNELS;
+ efx->max_vis = EFX_MAX_CHANNELS;
efx->max_tx_channels = EFX_MAX_CHANNELS;
+ efx->tx_queues_per_channel = 4;
efx_reado(efx, &reg, FR_AZ_CS_DEBUG);
efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
@@ -631,7 +634,7 @@ static size_t siena_update_nic_stats(struct efx_nic *efx, u64 *full_stats,
return SIENA_STAT_COUNT;
}
-static int siena_mac_reconfigure(struct efx_nic *efx)
+static int siena_mac_reconfigure(struct efx_nic *efx, bool mtu_only __always_unused)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_MCAST_HASH_IN_LEN);
int rc;
@@ -1015,6 +1018,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.tx_remove = efx_farch_tx_remove,
.tx_write = efx_farch_tx_write,
.tx_limit_len = efx_farch_tx_limit_len,
+ .tx_enqueue = __efx_enqueue_skb,
.rx_push_rss_config = siena_rx_push_rss_config,
.rx_pull_rss_config = siena_rx_pull_rss_config,
.rx_probe = efx_farch_rx_probe,
@@ -1022,6 +1026,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.rx_remove = efx_farch_rx_remove,
.rx_write = efx_farch_rx_write,
.rx_defer_refill = efx_farch_rx_defer_refill,
+ .rx_packet = __efx_rx_packet,
.ev_probe = efx_farch_ev_probe,
.ev_init = efx_farch_ev_init,
.ev_fini = efx_farch_ev_fini,
@@ -1083,7 +1088,6 @@ const struct efx_nic_type siena_a0_nic_type = {
.can_rx_scatter = true,
.option_descriptors = false,
.min_interrupt_mode = EFX_INT_MODE_LEGACY,
- .max_interrupt_mode = EFX_INT_MODE_MSIX,
.timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH,
.offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXHASH | NETIF_F_NTUPLE),
@@ -1094,4 +1098,5 @@ const struct efx_nic_type siena_a0_nic_type = {
1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT),
.rx_hash_key_size = 16,
.check_caps = siena_check_caps,
+ .sensor_event = efx_mcdi_sensor_event,
};
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index 19b58563cb78..727201d5eb24 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -269,34 +269,6 @@ static int efx_enqueue_skb_pio(struct efx_tx_queue *tx_queue,
#endif /* EFX_USE_PIO */
/*
- * Fallback to software TSO.
- *
- * This is used if we are unable to send a GSO packet through hardware TSO.
- * This should only ever happen due to per-queue restrictions - unsupported
- * packets should first be filtered by the feature flags.
- *
- * Returns 0 on success, error code otherwise.
- */
-static int efx_tx_tso_fallback(struct efx_tx_queue *tx_queue,
- struct sk_buff *skb)
-{
- struct sk_buff *segments, *next;
-
- segments = skb_gso_segment(skb, 0);
- if (IS_ERR(segments))
- return PTR_ERR(segments);
-
- dev_consume_skb_any(skb);
-
- skb_list_walk_safe(segments, skb, next) {
- skb_mark_not_on_list(skb);
- efx_enqueue_skb(tx_queue, skb);
- }
-
- return 0;
-}
-
-/*
* Add a socket buffer to a TX queue
*
* This maps all fragments of a socket buffer for DMA and adds them to
@@ -312,7 +284,7 @@ static int efx_tx_tso_fallback(struct efx_tx_queue *tx_queue,
* Returns NETDEV_TX_OK.
* You must hold netif_tx_lock() to call this function.
*/
-netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+netdev_tx_t __efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
{
unsigned int old_insert_count = tx_queue->insert_count;
bool xmit_more = netdev_xmit_more();
@@ -531,7 +503,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
}
tx_queue = efx_get_tx_queue(efx, index, type);
- return efx_enqueue_skb(tx_queue, skb);
+ return __efx_enqueue_skb(tx_queue, skb);
}
void efx_xmit_done_single(struct efx_tx_queue *tx_queue)
@@ -579,8 +551,8 @@ void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue)
/* Must be inverse of queue lookup in efx_hard_start_xmit() */
tx_queue->core_txq =
netdev_get_tx_queue(efx->net_dev,
- tx_queue->queue / EFX_TXQ_TYPES +
- ((tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ?
+ tx_queue->channel->channel +
+ ((tx_queue->label & EFX_TXQ_TYPE_HIGHPRI) ?
efx->n_tx_channels : 0));
}
@@ -589,14 +561,15 @@ int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
{
struct efx_nic *efx = netdev_priv(net_dev);
struct tc_mqprio_qopt *mqprio = type_data;
- struct efx_channel *channel;
- struct efx_tx_queue *tx_queue;
unsigned tc, num_tc;
- int rc;
if (type != TC_SETUP_QDISC_MQPRIO)
return -EOPNOTSUPP;
+ /* Only Siena supported highpri queues */
+ if (efx_nic_rev(efx) > EFX_REV_SIENA_A0)
+ return -EOPNOTSUPP;
+
num_tc = mqprio->num_tc;
if (num_tc > EFX_MAX_TX_TC)
@@ -612,40 +585,9 @@ int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
net_dev->tc_to_txq[tc].count = efx->n_tx_channels;
}
- if (num_tc > net_dev->num_tc) {
- /* Initialise high-priority queues as necessary */
- efx_for_each_channel(channel, efx) {
- efx_for_each_possible_channel_tx_queue(tx_queue,
- channel) {
- if (!(tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI))
- continue;
- if (!tx_queue->buffer) {
- rc = efx_probe_tx_queue(tx_queue);
- if (rc)
- return rc;
- }
- if (!tx_queue->initialised)
- efx_init_tx_queue(tx_queue);
- efx_init_tx_queue_core_txq(tx_queue);
- }
- }
- } else {
- /* Reduce number of classes before number of queues */
- net_dev->num_tc = num_tc;
- }
-
- rc = netif_set_real_num_tx_queues(net_dev,
- max_t(int, num_tc, 1) *
- efx->n_tx_channels);
- if (rc)
- return rc;
-
- /* Do not destroy high-priority queues when they become
- * unused. We would have to flush them first, and it is
- * fairly difficult to flush a subset of TX queues. Leave
- * it to efx_fini_channels().
- */
-
net_dev->num_tc = num_tc;
- return 0;
+
+ return netif_set_real_num_tx_queues(net_dev,
+ max_t(int, num_tc, 1) *
+ efx->n_tx_channels);
}
diff --git a/drivers/net/ethernet/sfc/tx.h b/drivers/net/ethernet/sfc/tx.h
index e04d5ddeb32c..a3cf06c5570d 100644
--- a/drivers/net/ethernet/sfc/tx.h
+++ b/drivers/net/ethernet/sfc/tx.h
@@ -18,7 +18,4 @@ unsigned int efx_tx_limit_len(struct efx_tx_queue *tx_queue,
u8 *efx_tx_get_copy_buffer_limited(struct efx_tx_queue *tx_queue,
struct efx_tx_buffer *buffer, size_t len);
-int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
- bool *data_mapped);
-
#endif /* EFX_TX_H */
diff --git a/drivers/net/ethernet/sfc/tx_common.c b/drivers/net/ethernet/sfc/tx_common.c
index 70876df1da69..793e234819a8 100644
--- a/drivers/net/ethernet/sfc/tx_common.c
+++ b/drivers/net/ethernet/sfc/tx_common.c
@@ -10,7 +10,7 @@
#include "net_driver.h"
#include "efx.h"
-#include "nic.h"
+#include "nic_common.h"
#include "tx_common.h"
static unsigned int efx_tx_cb_page_count(struct efx_tx_queue *tx_queue)
@@ -71,6 +71,7 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue)
"initialising TX queue %d\n", tx_queue->queue);
tx_queue->insert_count = 0;
+ tx_queue->notify_count = 0;
tx_queue->write_count = 0;
tx_queue->packet_write_count = 0;
tx_queue->old_write_count = 0;
@@ -298,7 +299,11 @@ struct efx_tx_buffer *efx_tx_map_chunk(struct efx_tx_queue *tx_queue,
/* Map the fragment taking account of NIC-dependent DMA limits. */
do {
buffer = efx_tx_queue_get_insert_buffer(tx_queue);
- dma_len = nic_type->tx_limit_len(tx_queue, dma_addr, len);
+
+ if (nic_type->tx_limit_len)
+ dma_len = nic_type->tx_limit_len(tx_queue, dma_addr, len);
+ else
+ dma_len = len;
buffer->len = dma_len;
buffer->dma_addr = dma_addr;
@@ -311,6 +316,20 @@ struct efx_tx_buffer *efx_tx_map_chunk(struct efx_tx_queue *tx_queue,
return buffer;
}
+int efx_tx_tso_header_length(struct sk_buff *skb)
+{
+ size_t header_len;
+
+ if (skb->encapsulation)
+ header_len = skb_inner_transport_header(skb) -
+ skb->data +
+ (inner_tcp_hdr(skb)->doff << 2u);
+ else
+ header_len = skb_transport_header(skb) - skb->data +
+ (tcp_hdr(skb)->doff << 2u);
+ return header_len;
+}
+
/* Map all data from an SKB for DMA and create descriptors on the queue. */
int efx_tx_map_data(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
unsigned int segment_count)
@@ -339,8 +358,7 @@ int efx_tx_map_data(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
/* For TSO we need to put the header in to a separate
* descriptor. Map this separately if necessary.
*/
- size_t header_len = skb_transport_header(skb) - skb->data +
- (tcp_hdr(skb)->doff << 2u);
+ size_t header_len = efx_tx_tso_header_length(skb);
if (header_len != len) {
tx_queue->tso_long_headers++;
@@ -405,3 +423,30 @@ unsigned int efx_tx_max_skb_descs(struct efx_nic *efx)
return max_descs;
}
+
+/*
+ * Fallback to software TSO.
+ *
+ * This is used if we are unable to send a GSO packet through hardware TSO.
+ * This should only ever happen due to per-queue restrictions - unsupported
+ * packets should first be filtered by the feature flags.
+ *
+ * Returns 0 on success, error code otherwise.
+ */
+int efx_tx_tso_fallback(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+{
+ struct sk_buff *segments, *next;
+
+ segments = skb_gso_segment(skb, 0);
+ if (IS_ERR(segments))
+ return PTR_ERR(segments);
+
+ dev_consume_skb_any(skb);
+
+ skb_list_walk_safe(segments, skb, next) {
+ skb_mark_not_on_list(skb);
+ efx_enqueue_skb(tx_queue, skb);
+ }
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/sfc/tx_common.h b/drivers/net/ethernet/sfc/tx_common.h
index 99cf7ce2f36c..bbab7f248250 100644
--- a/drivers/net/ethernet/sfc/tx_common.h
+++ b/drivers/net/ethernet/sfc/tx_common.h
@@ -34,9 +34,12 @@ void efx_enqueue_unwind(struct efx_tx_queue *tx_queue,
struct efx_tx_buffer *efx_tx_map_chunk(struct efx_tx_queue *tx_queue,
dma_addr_t dma_addr, size_t len);
+int efx_tx_tso_header_length(struct sk_buff *skb);
int efx_tx_map_data(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
unsigned int segment_count);
unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);
+int efx_tx_tso_fallback(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
+extern bool efx_separate_tx_channels;
#endif
diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c
index 6646eba9f57f..6eef0f45b133 100644
--- a/drivers/net/ethernet/sgi/ioc3-eth.c
+++ b/drivers/net/ethernet/sgi/ioc3-eth.c
@@ -951,7 +951,7 @@ out_stop:
dma_free_coherent(ip->dma_dev, RX_RING_SIZE, ip->rxr,
ip->rxr_dma);
if (ip->tx_ring)
- dma_free_coherent(ip->dma_dev, TX_RING_SIZE, ip->tx_ring,
+ dma_free_coherent(ip->dma_dev, TX_RING_SIZE + SZ_16K - 1, ip->tx_ring,
ip->txr_dma);
out_free:
free_netdev(dev);
@@ -964,7 +964,7 @@ static int ioc3eth_remove(struct platform_device *pdev)
struct ioc3_private *ip = netdev_priv(dev);
dma_free_coherent(ip->dma_dev, RX_RING_SIZE, ip->rxr, ip->rxr_dma);
- dma_free_coherent(ip->dma_dev, TX_RING_SIZE, ip->tx_ring, ip->txr_dma);
+ dma_free_coherent(ip->dma_dev, TX_RING_SIZE + SZ_16K - 1, ip->tx_ring, ip->txr_dma);
unregister_netdev(dev);
del_timer_sync(&ip->ioc3_timer);
diff --git a/drivers/net/ethernet/silan/sc92031.c b/drivers/net/ethernet/silan/sc92031.c
index cb043eb1bdc1..f94078f8ebe5 100644
--- a/drivers/net/ethernet/silan/sc92031.c
+++ b/drivers/net/ethernet/silan/sc92031.c
@@ -1499,15 +1499,13 @@ static void sc92031_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-static int sc92031_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused sc92031_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct sc92031_priv *priv = netdev_priv(dev);
- pci_save_state(pdev);
-
if (!netif_running(dev))
- goto out;
+ return 0;
netif_device_detach(dev);
@@ -1521,22 +1519,16 @@ static int sc92031_suspend(struct pci_dev *pdev, pm_message_t state)
spin_unlock_bh(&priv->lock);
-out:
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
return 0;
}
-static int sc92031_resume(struct pci_dev *pdev)
+static int __maybe_unused sc92031_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct sc92031_priv *priv = netdev_priv(dev);
- pci_restore_state(pdev);
- pci_set_power_state(pdev, PCI_D0);
-
if (!netif_running(dev))
- goto out;
+ return 0;
/* Interrupts already disabled by sc92031_suspend */
spin_lock_bh(&priv->lock);
@@ -1553,7 +1545,6 @@ static int sc92031_resume(struct pci_dev *pdev)
else
netif_tx_disable(dev);
-out:
return 0;
}
@@ -1565,13 +1556,14 @@ static const struct pci_device_id sc92031_pci_device_id_table[] = {
};
MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table);
+static SIMPLE_DEV_PM_OPS(sc92031_pm_ops, sc92031_suspend, sc92031_resume);
+
static struct pci_driver sc92031_pci_driver = {
.name = SC92031_NAME,
.id_table = sc92031_pci_device_id_table,
.probe = sc92031_probe,
.remove = sc92031_remove,
- .suspend = sc92031_suspend,
- .resume = sc92031_resume,
+ .driver.pm = &sc92031_pm_ops,
};
module_pci_driver(sc92031_pci_driver);
diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c
index 5a4b6e3ab38f..676b193833c0 100644
--- a/drivers/net/ethernet/sis/sis190.c
+++ b/drivers/net/ethernet/sis/sis190.c
@@ -494,9 +494,9 @@ static struct sk_buff *sis190_alloc_rx_skb(struct sis190_private *tp,
skb = netdev_alloc_skb(tp->dev, rx_buf_sz);
if (unlikely(!skb))
goto skb_alloc_failed;
- mapping = pci_map_single(tp->pci_dev, skb->data, tp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(tp->pci_dev, mapping))
+ mapping = dma_map_single(&tp->pci_dev->dev, skb->data, tp->rx_buf_sz,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&tp->pci_dev->dev, mapping))
goto out;
sis190_map_to_asic(desc, mapping, rx_buf_sz);
@@ -542,8 +542,8 @@ static bool sis190_try_rx_copy(struct sis190_private *tp,
if (!skb)
goto out;
- pci_dma_sync_single_for_cpu(tp->pci_dev, addr, tp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, tp->rx_buf_sz,
+ DMA_FROM_DEVICE);
skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size);
*sk_buff = skb;
done = true;
@@ -612,12 +612,14 @@ static int sis190_rx_interrupt(struct net_device *dev,
if (sis190_try_rx_copy(tp, &skb, pkt_size, addr)) {
- pci_dma_sync_single_for_device(pdev, addr,
- tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&pdev->dev, addr,
+ tp->rx_buf_sz,
+ DMA_FROM_DEVICE);
sis190_give_to_asic(desc, tp->rx_buf_sz);
} else {
- pci_unmap_single(pdev, addr, tp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&pdev->dev, addr,
+ tp->rx_buf_sz,
+ DMA_FROM_DEVICE);
tp->Rx_skbuff[entry] = NULL;
sis190_make_unusable_by_asic(desc);
}
@@ -654,7 +656,8 @@ static void sis190_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff *skb,
len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
- pci_unmap_single(pdev, le32_to_cpu(desc->addr), len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&pdev->dev, le32_to_cpu(desc->addr), len,
+ DMA_TO_DEVICE);
memset(desc, 0x00, sizeof(*desc));
}
@@ -785,8 +788,8 @@ static void sis190_free_rx_skb(struct sis190_private *tp,
{
struct pci_dev *pdev = tp->pci_dev;
- pci_unmap_single(pdev, le32_to_cpu(desc->addr), tp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&pdev->dev, le32_to_cpu(desc->addr), tp->rx_buf_sz,
+ DMA_FROM_DEVICE);
dev_kfree_skb(*sk_buff);
*sk_buff = NULL;
sis190_make_unusable_by_asic(desc);
@@ -1069,11 +1072,13 @@ static int sis190_open(struct net_device *dev)
* Rx and Tx descriptors need 256 bytes alignment.
* pci_alloc_consistent() guarantees a stronger alignment.
*/
- tp->TxDescRing = pci_alloc_consistent(pdev, TX_RING_BYTES, &tp->tx_dma);
+ tp->TxDescRing = dma_alloc_coherent(&pdev->dev, TX_RING_BYTES,
+ &tp->tx_dma, GFP_KERNEL);
if (!tp->TxDescRing)
goto out;
- tp->RxDescRing = pci_alloc_consistent(pdev, RX_RING_BYTES, &tp->rx_dma);
+ tp->RxDescRing = dma_alloc_coherent(&pdev->dev, RX_RING_BYTES,
+ &tp->rx_dma, GFP_KERNEL);
if (!tp->RxDescRing)
goto err_free_tx_0;
@@ -1095,9 +1100,11 @@ err_release_timer_2:
sis190_delete_timer(dev);
sis190_rx_clear(tp);
err_free_rx_1:
- pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
+ dma_free_coherent(&pdev->dev, RX_RING_BYTES, tp->RxDescRing,
+ tp->rx_dma);
err_free_tx_0:
- pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
+ dma_free_coherent(&pdev->dev, TX_RING_BYTES, tp->TxDescRing,
+ tp->tx_dma);
goto out;
}
@@ -1159,8 +1166,10 @@ static int sis190_close(struct net_device *dev)
free_irq(pdev->irq, dev);
- pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
- pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
+ dma_free_coherent(&pdev->dev, TX_RING_BYTES, tp->TxDescRing,
+ tp->tx_dma);
+ dma_free_coherent(&pdev->dev, RX_RING_BYTES, tp->RxDescRing,
+ tp->rx_dma);
tp->TxDescRing = NULL;
tp->RxDescRing = NULL;
@@ -1197,8 +1206,9 @@ static netdev_tx_t sis190_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
- mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(tp->pci_dev, mapping)) {
+ mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&tp->pci_dev->dev, mapping)) {
netif_err(tp, tx_err, dev,
"PCI mapping failed, dropping packet");
return NETDEV_TX_BUSY;
@@ -1498,7 +1508,7 @@ static struct net_device *sis190_init_board(struct pci_dev *pdev)
goto err_pci_disable_2;
}
- rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc < 0) {
if (netif_msg_probe(tp))
pr_err("%s: DMA configuration failed\n",
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index 81ed7589e33c..336105f77313 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -446,7 +446,7 @@ static int sis900_probe(struct pci_dev *pci_dev,
ret = pci_enable_device(pci_dev);
if(ret) return ret;
- i = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
+ i = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32));
if(i){
printk(KERN_ERR "sis900.c: architecture does not support "
"32bit PCI busmaster DMA\n");
@@ -481,7 +481,8 @@ static int sis900_probe(struct pci_dev *pci_dev,
pci_set_drvdata(pci_dev, net_dev);
- ring_space = pci_alloc_consistent(pci_dev, TX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pci_dev->dev, TX_TOTAL_SIZE,
+ &ring_dma, GFP_KERNEL);
if (!ring_space) {
ret = -ENOMEM;
goto err_out_unmap;
@@ -489,7 +490,8 @@ static int sis900_probe(struct pci_dev *pci_dev,
sis_priv->tx_ring = ring_space;
sis_priv->tx_ring_dma = ring_dma;
- ring_space = pci_alloc_consistent(pci_dev, RX_TOTAL_SIZE, &ring_dma);
+ ring_space = dma_alloc_coherent(&pci_dev->dev, RX_TOTAL_SIZE,
+ &ring_dma, GFP_KERNEL);
if (!ring_space) {
ret = -ENOMEM;
goto err_unmap_tx;
@@ -572,11 +574,11 @@ static int sis900_probe(struct pci_dev *pci_dev,
return 0;
err_unmap_rx:
- pci_free_consistent(pci_dev, RX_TOTAL_SIZE, sis_priv->rx_ring,
- sis_priv->rx_ring_dma);
+ dma_free_coherent(&pci_dev->dev, RX_TOTAL_SIZE, sis_priv->rx_ring,
+ sis_priv->rx_ring_dma);
err_unmap_tx:
- pci_free_consistent(pci_dev, TX_TOTAL_SIZE, sis_priv->tx_ring,
- sis_priv->tx_ring_dma);
+ dma_free_coherent(&pci_dev->dev, TX_TOTAL_SIZE, sis_priv->tx_ring,
+ sis_priv->tx_ring_dma);
err_out_unmap:
pci_iounmap(pci_dev, ioaddr);
err_out_cleardev:
@@ -1188,10 +1190,12 @@ sis900_init_rx_ring(struct net_device *net_dev)
}
sis_priv->rx_skbuff[i] = skb;
sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
- sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev,
- skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sis_priv->pci_dev,
- sis_priv->rx_ring[i].bufptr))) {
+ sis_priv->rx_ring[i].bufptr = dma_map_single(&sis_priv->pci_dev->dev,
+ skb->data,
+ RX_BUF_SIZE,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(&sis_priv->pci_dev->dev,
+ sis_priv->rx_ring[i].bufptr))) {
dev_kfree_skb(skb);
sis_priv->rx_skbuff[i] = NULL;
break;
@@ -1561,9 +1565,9 @@ static void sis900_tx_timeout(struct net_device *net_dev, unsigned int txqueue)
struct sk_buff *skb = sis_priv->tx_skbuff[i];
if (skb) {
- pci_unmap_single(sis_priv->pci_dev,
- sis_priv->tx_ring[i].bufptr, skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&sis_priv->pci_dev->dev,
+ sis_priv->tx_ring[i].bufptr,
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_irq(skb);
sis_priv->tx_skbuff[i] = NULL;
sis_priv->tx_ring[i].cmdsts = 0;
@@ -1612,10 +1616,11 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
sis_priv->tx_skbuff[entry] = skb;
/* set the transmit buffer descriptor and enable Transmit State Machine */
- sis_priv->tx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev,
- skb->data, skb->len, PCI_DMA_TODEVICE);
- if (unlikely(pci_dma_mapping_error(sis_priv->pci_dev,
- sis_priv->tx_ring[entry].bufptr))) {
+ sis_priv->tx_ring[entry].bufptr = dma_map_single(&sis_priv->pci_dev->dev,
+ skb->data, skb->len,
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(&sis_priv->pci_dev->dev,
+ sis_priv->tx_ring[entry].bufptr))) {
dev_kfree_skb_any(skb);
sis_priv->tx_skbuff[entry] = NULL;
net_dev->stats.tx_dropped++;
@@ -1778,9 +1783,9 @@ static int sis900_rx(struct net_device *net_dev)
struct sk_buff * skb;
struct sk_buff * rx_skb;
- pci_unmap_single(sis_priv->pci_dev,
- sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&sis_priv->pci_dev->dev,
+ sis_priv->rx_ring[entry].bufptr,
+ RX_BUF_SIZE, DMA_FROM_DEVICE);
/* refill the Rx buffer, what if there is not enough
* memory for new socket buffer ?? */
@@ -1826,10 +1831,11 @@ refill_rx_ring:
sis_priv->rx_skbuff[entry] = skb;
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
sis_priv->rx_ring[entry].bufptr =
- pci_map_single(sis_priv->pci_dev, skb->data,
- RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sis_priv->pci_dev,
- sis_priv->rx_ring[entry].bufptr))) {
+ dma_map_single(&sis_priv->pci_dev->dev,
+ skb->data, RX_BUF_SIZE,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(&sis_priv->pci_dev->dev,
+ sis_priv->rx_ring[entry].bufptr))) {
dev_kfree_skb_irq(skb);
sis_priv->rx_skbuff[entry] = NULL;
break;
@@ -1860,10 +1866,11 @@ refill_rx_ring:
sis_priv->rx_skbuff[entry] = skb;
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
sis_priv->rx_ring[entry].bufptr =
- pci_map_single(sis_priv->pci_dev, skb->data,
- RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sis_priv->pci_dev,
- sis_priv->rx_ring[entry].bufptr))) {
+ dma_map_single(&sis_priv->pci_dev->dev,
+ skb->data, RX_BUF_SIZE,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(&sis_priv->pci_dev->dev,
+ sis_priv->rx_ring[entry].bufptr))) {
dev_kfree_skb_irq(skb);
sis_priv->rx_skbuff[entry] = NULL;
break;
@@ -1928,9 +1935,9 @@ static void sis900_finish_xmit (struct net_device *net_dev)
}
/* Free the original skb. */
skb = sis_priv->tx_skbuff[entry];
- pci_unmap_single(sis_priv->pci_dev,
- sis_priv->tx_ring[entry].bufptr, skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&sis_priv->pci_dev->dev,
+ sis_priv->tx_ring[entry].bufptr, skb->len,
+ DMA_TO_DEVICE);
dev_consume_skb_irq(skb);
sis_priv->tx_skbuff[entry] = NULL;
sis_priv->tx_ring[entry].bufptr = 0;
@@ -1979,8 +1986,9 @@ static int sis900_close(struct net_device *net_dev)
for (i = 0; i < NUM_RX_DESC; i++) {
skb = sis_priv->rx_skbuff[i];
if (skb) {
- pci_unmap_single(pdev, sis_priv->rx_ring[i].bufptr,
- RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&pdev->dev,
+ sis_priv->rx_ring[i].bufptr,
+ RX_BUF_SIZE, DMA_FROM_DEVICE);
dev_kfree_skb(skb);
sis_priv->rx_skbuff[i] = NULL;
}
@@ -1988,8 +1996,9 @@ static int sis900_close(struct net_device *net_dev)
for (i = 0; i < NUM_TX_DESC; i++) {
skb = sis_priv->tx_skbuff[i];
if (skb) {
- pci_unmap_single(pdev, sis_priv->tx_ring[i].bufptr,
- skb->len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&pdev->dev,
+ sis_priv->tx_ring[i].bufptr,
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb(skb);
sis_priv->tx_skbuff[i] = NULL;
}
@@ -2484,20 +2493,18 @@ static void sis900_remove(struct pci_dev *pci_dev)
kfree(phy);
}
- pci_free_consistent(pci_dev, RX_TOTAL_SIZE, sis_priv->rx_ring,
- sis_priv->rx_ring_dma);
- pci_free_consistent(pci_dev, TX_TOTAL_SIZE, sis_priv->tx_ring,
- sis_priv->tx_ring_dma);
+ dma_free_coherent(&pci_dev->dev, RX_TOTAL_SIZE, sis_priv->rx_ring,
+ sis_priv->rx_ring_dma);
+ dma_free_coherent(&pci_dev->dev, TX_TOTAL_SIZE, sis_priv->tx_ring,
+ sis_priv->tx_ring_dma);
pci_iounmap(pci_dev, sis_priv->ioaddr);
free_netdev(net_dev);
pci_release_regions(pci_dev);
}
-#ifdef CONFIG_PM
-
-static int sis900_suspend(struct pci_dev *pci_dev, pm_message_t state)
+static int __maybe_unused sis900_suspend(struct device *dev)
{
- struct net_device *net_dev = pci_get_drvdata(pci_dev);
+ struct net_device *net_dev = dev_get_drvdata(dev);
struct sis900_private *sis_priv = netdev_priv(net_dev);
void __iomem *ioaddr = sis_priv->ioaddr;
@@ -2510,22 +2517,17 @@ static int sis900_suspend(struct pci_dev *pci_dev, pm_message_t state)
/* Stop the chip's Tx and Rx Status Machine */
sw32(cr, RxDIS | TxDIS | sr32(cr));
- pci_set_power_state(pci_dev, PCI_D3hot);
- pci_save_state(pci_dev);
-
return 0;
}
-static int sis900_resume(struct pci_dev *pci_dev)
+static int __maybe_unused sis900_resume(struct device *dev)
{
- struct net_device *net_dev = pci_get_drvdata(pci_dev);
+ struct net_device *net_dev = dev_get_drvdata(dev);
struct sis900_private *sis_priv = netdev_priv(net_dev);
void __iomem *ioaddr = sis_priv->ioaddr;
if(!netif_running(net_dev))
return 0;
- pci_restore_state(pci_dev);
- pci_set_power_state(pci_dev, PCI_D0);
sis900_init_rxfilter(net_dev);
@@ -2549,17 +2551,15 @@ static int sis900_resume(struct pci_dev *pci_dev)
return 0;
}
-#endif /* CONFIG_PM */
+
+static SIMPLE_DEV_PM_OPS(sis900_pm_ops, sis900_suspend, sis900_resume);
static struct pci_driver sis900_pci_driver = {
.name = SIS900_MODULE_NAME,
.id_table = sis900_pci_tbl,
.probe = sis900_probe,
.remove = sis900_remove,
-#ifdef CONFIG_PM
- .suspend = sis900_suspend,
- .resume = sis900_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &sis900_pm_ops,
};
static int __init sis900_init_module(void)
diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig
index 6293b1e6c772..b77e427e6729 100644
--- a/drivers/net/ethernet/smsc/Kconfig
+++ b/drivers/net/ethernet/smsc/Kconfig
@@ -28,7 +28,7 @@ config SMC9194
option if you have a DELL laptop with the docking station, or
another SMC9192/9194 based chipset. Say Y if you want it compiled
into the kernel, and read the file
- <file:Documentation/networking/device_drivers/smsc/smc9.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/smsc/smc9.rst>.
To compile this driver as a module, choose M here. The module
will be called smc9194.
@@ -44,7 +44,7 @@ config SMC91X
This is a driver for SMC's 91x series of Ethernet chipsets,
including the SMC91C94 and the SMC91C111. Say Y if you want it
compiled into the kernel, and read the file
- <file:Documentation/networking/device_drivers/smsc/smc9.rst>.
+ <file:Documentation/networking/device_drivers/ethernet/smsc/smc9.rst>.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c
index 61ddee0c2a2e..d950b312c418 100644
--- a/drivers/net/ethernet/smsc/epic100.c
+++ b/drivers/net/ethernet/smsc/epic100.c
@@ -1512,12 +1512,9 @@ static void epic_remove_one(struct pci_dev *pdev)
/* pci_power_off(pdev, -1); */
}
-
-#ifdef CONFIG_PM
-
-static int epic_suspend (struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused epic_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct epic_private *ep = netdev_priv(dev);
void __iomem *ioaddr = ep->ioaddr;
@@ -1531,9 +1528,9 @@ static int epic_suspend (struct pci_dev *pdev, pm_message_t state)
}
-static int epic_resume (struct pci_dev *pdev)
+static int __maybe_unused epic_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
if (!netif_running(dev))
return 0;
@@ -1542,18 +1539,14 @@ static int epic_resume (struct pci_dev *pdev)
return 0;
}
-#endif /* CONFIG_PM */
-
+static SIMPLE_DEV_PM_OPS(epic_pm_ops, epic_suspend, epic_resume);
static struct pci_driver epic_driver = {
.name = DRV_NAME,
.id_table = epic_pci_tbl,
.probe = epic_init_one,
.remove = epic_remove_one,
-#ifdef CONFIG_PM
- .suspend = epic_suspend,
- .resume = epic_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &epic_pm_ops,
};
diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c
index 7312e522c022..42bef04d65ba 100644
--- a/drivers/net/ethernet/smsc/smsc9420.c
+++ b/drivers/net/ethernet/smsc/smsc9420.c
@@ -1422,11 +1422,9 @@ out_0:
return result;
}
-#ifdef CONFIG_PM
-
-static int smsc9420_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused smsc9420_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct smsc9420_pdata *pd = netdev_priv(dev);
u32 int_cfg;
ulong flags;
@@ -1451,34 +1449,21 @@ static int smsc9420_suspend(struct pci_dev *pdev, pm_message_t state)
netif_device_detach(dev);
}
- pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ device_wakeup_disable(dev_d);
return 0;
}
-static int smsc9420_resume(struct pci_dev *pdev)
+static int __maybe_unused smsc9420_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct smsc9420_pdata *pd = netdev_priv(dev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
int err;
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
- err = pci_enable_device(pdev);
- if (err)
- return err;
+ pci_set_master(to_pci_dev(dev_d));
- pci_set_master(pdev);
-
- err = pci_enable_wake(pdev, PCI_D0, 0);
- if (err)
- netif_warn(pd, ifup, pd->dev, "pci_enable_wake failed: %d\n",
- err);
+ device_wakeup_disable(dev_d);
+ err = 0;
if (netif_running(dev)) {
/* FIXME: gross. It looks like ancient PM relic.*/
err = smsc9420_open(dev);
@@ -1487,8 +1472,6 @@ static int smsc9420_resume(struct pci_dev *pdev)
return err;
}
-#endif /* CONFIG_PM */
-
static const struct net_device_ops smsc9420_netdev_ops = {
.ndo_open = smsc9420_open,
.ndo_stop = smsc9420_stop,
@@ -1658,15 +1641,14 @@ static void smsc9420_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
+static SIMPLE_DEV_PM_OPS(smsc9420_pm_ops, smsc9420_suspend, smsc9420_resume);
+
static struct pci_driver smsc9420_driver = {
.name = DRV_NAME,
.id_table = smsc9420_id_table,
.probe = smsc9420_probe,
.remove = smsc9420_remove,
-#ifdef CONFIG_PM
- .suspend = smsc9420_suspend,
- .resume = smsc9420_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &smsc9420_pm_ops,
};
static int __init smsc9420_init_module(void)
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 0f366cc50b74..25db667fa879 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -1811,9 +1811,6 @@ static int netsec_xdp(struct net_device *ndev, struct netdev_bpf *xdp)
switch (xdp->command) {
case XDP_SETUP_PROG:
return netsec_xdp_setup(priv, xdp->prog, xdp->extack);
- case XDP_QUERY_PROG:
- xdp->prog_id = priv->xdp_prog ? priv->xdp_prog->aux->id : 0;
- return 0;
default:
return -EINVAL;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 234e8b6816ce..5afcf05bbf9c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -69,8 +69,6 @@
*/
#define PRG_ETH0_ADJ_SKEW GENMASK(24, 20)
-#define MUX_CLK_NUM_PARENTS 2
-
struct meson8b_dwmac;
struct meson8b_dwmac_data {
@@ -110,12 +108,12 @@ static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
static struct clk *meson8b_dwmac_register_clk(struct meson8b_dwmac *dwmac,
const char *name_suffix,
- const char **parent_names,
+ const struct clk_parent_data *parents,
int num_parents,
const struct clk_ops *ops,
struct clk_hw *hw)
{
- struct clk_init_data init;
+ struct clk_init_data init = { };
char clk_name[32];
snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(dwmac->dev),
@@ -124,7 +122,7 @@ static struct clk *meson8b_dwmac_register_clk(struct meson8b_dwmac *dwmac,
init.name = clk_name;
init.ops = ops;
init.flags = CLK_SET_RATE_PARENT;
- init.parent_names = parent_names;
+ init.parent_data = parents;
init.num_parents = num_parents;
hw->init = &init;
@@ -134,11 +132,12 @@ static struct clk *meson8b_dwmac_register_clk(struct meson8b_dwmac *dwmac,
static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
{
- int i, ret;
struct clk *clk;
struct device *dev = dwmac->dev;
- const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS];
- struct meson8b_dwmac_clk_configs *clk_configs;
+ static const struct clk_parent_data mux_parents[] = {
+ { .fw_name = "clkin0", },
+ { .fw_name = "clkin1", },
+ };
static const struct clk_div_table div_table[] = {
{ .div = 2, .val = 2, },
{ .div = 3, .val = 3, },
@@ -148,62 +147,48 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
{ .div = 7, .val = 7, },
{ /* end of array */ }
};
+ struct meson8b_dwmac_clk_configs *clk_configs;
+ struct clk_parent_data parent_data = { };
clk_configs = devm_kzalloc(dev, sizeof(*clk_configs), GFP_KERNEL);
if (!clk_configs)
return -ENOMEM;
- /* get the mux parents from DT */
- for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
- char name[16];
-
- snprintf(name, sizeof(name), "clkin%d", i);
- clk = devm_clk_get(dev, name);
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "Missing clock %s\n", name);
- return ret;
- }
-
- mux_parent_names[i] = __clk_get_name(clk);
- }
-
clk_configs->m250_mux.reg = dwmac->regs + PRG_ETH0;
clk_configs->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT;
clk_configs->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK;
- clk = meson8b_dwmac_register_clk(dwmac, "m250_sel", mux_parent_names,
- MUX_CLK_NUM_PARENTS, &clk_mux_ops,
+ clk = meson8b_dwmac_register_clk(dwmac, "m250_sel", mux_parents,
+ ARRAY_SIZE(mux_parents), &clk_mux_ops,
&clk_configs->m250_mux.hw);
if (WARN_ON(IS_ERR(clk)))
return PTR_ERR(clk);
- parent_name = __clk_get_name(clk);
+ parent_data.hw = &clk_configs->m250_mux.hw;
clk_configs->m250_div.reg = dwmac->regs + PRG_ETH0;
clk_configs->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
clk_configs->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
clk_configs->m250_div.table = div_table;
clk_configs->m250_div.flags = CLK_DIVIDER_ALLOW_ZERO |
CLK_DIVIDER_ROUND_CLOSEST;
- clk = meson8b_dwmac_register_clk(dwmac, "m250_div", &parent_name, 1,
+ clk = meson8b_dwmac_register_clk(dwmac, "m250_div", &parent_data, 1,
&clk_divider_ops,
&clk_configs->m250_div.hw);
if (WARN_ON(IS_ERR(clk)))
return PTR_ERR(clk);
- parent_name = __clk_get_name(clk);
+ parent_data.hw = &clk_configs->m250_div.hw;
clk_configs->fixed_div2.mult = 1;
clk_configs->fixed_div2.div = 2;
- clk = meson8b_dwmac_register_clk(dwmac, "fixed_div2", &parent_name, 1,
+ clk = meson8b_dwmac_register_clk(dwmac, "fixed_div2", &parent_data, 1,
&clk_fixed_factor_ops,
&clk_configs->fixed_div2.hw);
if (WARN_ON(IS_ERR(clk)))
return PTR_ERR(clk);
- parent_name = __clk_get_name(clk);
+ parent_data.hw = &clk_configs->fixed_div2.hw;
clk_configs->rgmii_tx_en.reg = dwmac->regs + PRG_ETH0;
clk_configs->rgmii_tx_en.bit_idx = PRG_ETH0_RGMII_TX_CLK_EN;
- clk = meson8b_dwmac_register_clk(dwmac, "rgmii_tx_en", &parent_name, 1,
+ clk = meson8b_dwmac_register_clk(dwmac, "rgmii_tx_en", &parent_data, 1,
&clk_gate_ops,
&clk_configs->rgmii_tx_en.hw);
if (WARN_ON(IS_ERR(clk)))
@@ -491,6 +476,10 @@ static const struct of_device_id meson8b_dwmac_match[] = {
.compatible = "amlogic,meson-axg-dwmac",
.data = &meson_axg_dwmac_data,
},
+ {
+ .compatible = "amlogic,meson-g12a-dwmac",
+ .data = &meson_axg_dwmac_data,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, meson8b_dwmac_match);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index eae11c585025..ac5e8cc5fb9f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -600,9 +600,14 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct stmmac_priv *priv = netdev_priv(dev);
+ if (!priv->plat->pmt)
+ return phylink_ethtool_get_wol(priv->phylink, wol);
+
mutex_lock(&priv->lock);
if (device_can_wakeup(priv->device)) {
wol->supported = WAKE_MAGIC | WAKE_UCAST;
+ if (priv->hw_cap_support && !priv->dma_cap.pmt_magic_frame)
+ wol->supported &= ~WAKE_MAGIC;
wol->wolopts = priv->wolopts;
}
mutex_unlock(&priv->lock);
@@ -613,15 +618,23 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
struct stmmac_priv *priv = netdev_priv(dev);
u32 support = WAKE_MAGIC | WAKE_UCAST;
+ if (!device_can_wakeup(priv->device))
+ return -EOPNOTSUPP;
+
+ if (!priv->plat->pmt) {
+ int ret = phylink_ethtool_set_wol(priv->phylink, wol);
+
+ if (!ret)
+ device_set_wakeup_enable(priv->device, !!wol->wolopts);
+ return ret;
+ }
+
/* By default almost all GMAC devices support the WoL via
* magic frame but we can disable it if the HW capability
* register shows no support for pmt_magic_frame. */
if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame))
wol->wolopts &= ~WAKE_MAGIC;
- if (!device_can_wakeup(priv->device))
- return -EINVAL;
-
if (wol->wolopts & ~support)
return -EINVAL;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 73677c3b33b6..89b2b3472852 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1075,6 +1075,7 @@ static void stmmac_check_pcs_mode(struct stmmac_priv *priv)
*/
static int stmmac_init_phy(struct net_device *dev)
{
+ struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
struct stmmac_priv *priv = netdev_priv(dev);
struct device_node *node;
int ret;
@@ -1100,6 +1101,9 @@ static int stmmac_init_phy(struct net_device *dev)
ret = phylink_connect_phy(priv->phylink, phydev);
}
+ phylink_ethtool_get_wol(priv->phylink, &wol);
+ device_set_wakeup_capable(priv->device, !!wol.supported);
+
return ret;
}
@@ -2819,6 +2823,8 @@ static int stmmac_open(struct net_device *dev)
stmmac_init_coalesce(priv);
phylink_start(priv->phylink);
+ /* We may have called phylink_speed_down before */
+ phylink_speed_up(priv->phylink);
/* Request the IRQ lines */
ret = request_irq(dev->irq, stmmac_interrupt,
@@ -2892,6 +2898,8 @@ static int stmmac_release(struct net_device *dev)
if (priv->eee_enabled)
del_timer_sync(&priv->eee_ctrl_timer);
+ if (device_may_wakeup(priv->device))
+ phylink_speed_down(priv->phylink, false);
/* Stop and disconnect the PHY */
phylink_stop(priv->phylink);
phylink_disconnect_phy(priv->phylink);
@@ -5085,12 +5093,14 @@ int stmmac_suspend(struct device *dev)
priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv);
/* Enable Power down mode by programming the PMT regs */
- if (device_may_wakeup(priv->device)) {
+ if (device_may_wakeup(priv->device) && priv->plat->pmt) {
stmmac_pmt(priv, priv->hw, priv->wolopts);
priv->irq_wake = 1;
} else {
mutex_unlock(&priv->lock);
rtnl_lock();
+ if (device_may_wakeup(priv->device))
+ phylink_speed_down(priv->phylink, false);
phylink_stop(priv->phylink);
rtnl_unlock();
mutex_lock(&priv->lock);
@@ -5157,7 +5167,7 @@ int stmmac_resume(struct device *dev)
* this bit because it can generate problems while resuming
* from another devices (e.g. serial console).
*/
- if (device_may_wakeup(priv->device)) {
+ if (device_may_wakeup(priv->device) && priv->plat->pmt) {
mutex_lock(&priv->lock);
stmmac_pmt(priv, priv->hw, 0);
mutex_unlock(&priv->lock);
@@ -5200,9 +5210,11 @@ int stmmac_resume(struct device *dev)
mutex_unlock(&priv->lock);
- if (!device_may_wakeup(priv->device)) {
+ if (!device_may_wakeup(priv->device) || !priv->plat->pmt) {
rtnl_lock();
phylink_start(priv->phylink);
+ /* We may have called phylink_speed_down before */
+ phylink_speed_up(priv->phylink);
rtnl_unlock();
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index e6696495f126..e113b1376fdd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -1094,7 +1094,7 @@ static int stmmac_test_rxp(struct stmmac_priv *priv)
if (!priv->dma_cap.frpsel)
return -EOPNOTSUPP;
- sel = kzalloc(sizeof(*sel) + nk * sizeof(struct tc_u32_key), GFP_KERNEL);
+ sel = kzalloc(struct_size(sel, keys, nk), GFP_KERNEL);
if (!sel)
return -ENOMEM;
diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c
index 015fdb851cdb..e2bc7a25f6d1 100644
--- a/drivers/net/ethernet/sun/cassini.c
+++ b/drivers/net/ethernet/sun/cassini.c
@@ -443,8 +443,8 @@ static void cas_phy_powerdown(struct cas *cp)
/* cp->lock held. note: the last put_page will free the buffer */
static int cas_page_free(struct cas *cp, cas_page_t *page)
{
- pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_page(&cp->pdev->dev, page->dma_addr, cp->page_size,
+ DMA_FROM_DEVICE);
__free_pages(page->buffer, cp->page_order);
kfree(page);
return 0;
@@ -474,8 +474,8 @@ static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags)
page->buffer = alloc_pages(flags, cp->page_order);
if (!page->buffer)
goto page_err;
- page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0,
- cp->page_size, PCI_DMA_FROMDEVICE);
+ page->dma_addr = dma_map_page(&cp->pdev->dev, page->buffer, 0,
+ cp->page_size, DMA_FROM_DEVICE);
return page;
page_err:
@@ -1863,8 +1863,8 @@ static inline void cas_tx_ringN(struct cas *cp, int ring, int limit)
daddr = le64_to_cpu(txd->buffer);
dlen = CAS_VAL(TX_DESC_BUFLEN,
le64_to_cpu(txd->control));
- pci_unmap_page(cp->pdev, daddr, dlen,
- PCI_DMA_TODEVICE);
+ dma_unmap_page(&cp->pdev->dev, daddr, dlen,
+ DMA_TO_DEVICE);
entry = TX_DESC_NEXT(ring, entry);
/* tiny buffer may follow */
@@ -1957,12 +1957,13 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
i = hlen;
if (!dlen) /* attach FCS */
i += cp->crc_size;
- pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&cp->pdev->dev, page->dma_addr + off,
+ i, DMA_FROM_DEVICE);
addr = cas_page_map(page->buffer);
memcpy(p, addr + off, i);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&cp->pdev->dev,
+ page->dma_addr + off, i,
+ DMA_FROM_DEVICE);
cas_page_unmap(addr);
RX_USED_ADD(page, 0x100);
p += hlen;
@@ -1988,16 +1989,17 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
i = hlen;
if (i == dlen) /* attach FCS */
i += cp->crc_size;
- pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&cp->pdev->dev, page->dma_addr + off,
+ i, DMA_FROM_DEVICE);
/* make sure we always copy a header */
swivel = 0;
if (p == (char *) skb->data) { /* not split */
addr = cas_page_map(page->buffer);
memcpy(p, addr + off, RX_COPY_MIN);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&cp->pdev->dev,
+ page->dma_addr + off, i,
+ DMA_FROM_DEVICE);
cas_page_unmap(addr);
off += RX_COPY_MIN;
swivel = RX_COPY_MIN;
@@ -2024,12 +2026,14 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
i = CAS_VAL(RX_COMP2_NEXT_INDEX, words[1]);
page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)];
- pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr,
- hlen + cp->crc_size,
- PCI_DMA_FROMDEVICE);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr,
- hlen + cp->crc_size,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&cp->pdev->dev,
+ page->dma_addr,
+ hlen + cp->crc_size,
+ DMA_FROM_DEVICE);
+ dma_sync_single_for_device(&cp->pdev->dev,
+ page->dma_addr,
+ hlen + cp->crc_size,
+ DMA_FROM_DEVICE);
skb_shinfo(skb)->nr_frags++;
skb->data_len += hlen;
@@ -2066,12 +2070,13 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
i = hlen;
if (i == dlen) /* attach FCS */
i += cp->crc_size;
- pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&cp->pdev->dev, page->dma_addr + off,
+ i, DMA_FROM_DEVICE);
addr = cas_page_map(page->buffer);
memcpy(p, addr + off, i);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&cp->pdev->dev,
+ page->dma_addr + off, i,
+ DMA_FROM_DEVICE);
cas_page_unmap(addr);
if (p == (char *) skb->data) /* not split */
RX_USED_ADD(page, cp->mtu_stride);
@@ -2083,14 +2088,16 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
p += hlen;
i = CAS_VAL(RX_COMP2_NEXT_INDEX, words[1]);
page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)];
- pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr,
- dlen + cp->crc_size,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&cp->pdev->dev,
+ page->dma_addr,
+ dlen + cp->crc_size,
+ DMA_FROM_DEVICE);
addr = cas_page_map(page->buffer);
memcpy(p, addr, dlen + cp->crc_size);
- pci_dma_sync_single_for_device(cp->pdev, page->dma_addr,
- dlen + cp->crc_size,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&cp->pdev->dev,
+ page->dma_addr,
+ dlen + cp->crc_size,
+ DMA_FROM_DEVICE);
cas_page_unmap(addr);
RX_USED_ADD(page, dlen + cp->crc_size);
}
@@ -2766,9 +2773,8 @@ static inline int cas_xmit_tx_ringN(struct cas *cp, int ring,
nr_frags = skb_shinfo(skb)->nr_frags;
len = skb_headlen(skb);
- mapping = pci_map_page(cp->pdev, virt_to_page(skb->data),
- offset_in_page(skb->data), len,
- PCI_DMA_TODEVICE);
+ mapping = dma_map_page(&cp->pdev->dev, virt_to_page(skb->data),
+ offset_in_page(skb->data), len, DMA_TO_DEVICE);
tentry = entry;
tabort = cas_calc_tabort(cp, (unsigned long) skb->data, len);
@@ -3882,8 +3888,8 @@ static void cas_clean_txd(struct cas *cp, int ring)
daddr = le64_to_cpu(txd[ent].buffer);
dlen = CAS_VAL(TX_DESC_BUFLEN,
le64_to_cpu(txd[ent].control));
- pci_unmap_page(cp->pdev, daddr, dlen,
- PCI_DMA_TODEVICE);
+ dma_unmap_page(&cp->pdev->dev, daddr, dlen,
+ DMA_TO_DEVICE);
if (frag != skb_shinfo(skb)->nr_frags) {
i++;
@@ -4181,9 +4187,8 @@ static void cas_tx_tiny_free(struct cas *cp)
if (!cp->tx_tiny_bufs[i])
continue;
- pci_free_consistent(pdev, TX_TINY_BUF_BLOCK,
- cp->tx_tiny_bufs[i],
- cp->tx_tiny_dvma[i]);
+ dma_free_coherent(&pdev->dev, TX_TINY_BUF_BLOCK,
+ cp->tx_tiny_bufs[i], cp->tx_tiny_dvma[i]);
cp->tx_tiny_bufs[i] = NULL;
}
}
@@ -4195,8 +4200,8 @@ static int cas_tx_tiny_alloc(struct cas *cp)
for (i = 0; i < N_TX_RINGS; i++) {
cp->tx_tiny_bufs[i] =
- pci_alloc_consistent(pdev, TX_TINY_BUF_BLOCK,
- &cp->tx_tiny_dvma[i]);
+ dma_alloc_coherent(&pdev->dev, TX_TINY_BUF_BLOCK,
+ &cp->tx_tiny_dvma[i], GFP_KERNEL);
if (!cp->tx_tiny_bufs[i]) {
cas_tx_tiny_free(cp);
return -1;
@@ -4958,10 +4963,9 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Configure DMA attributes. */
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev,
- DMA_BIT_MASK(64));
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (err < 0) {
dev_err(&pdev->dev, "Unable to obtain 64-bit DMA "
"for consistent allocations\n");
@@ -4969,7 +4973,7 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
} else {
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "No usable DMA configuration, "
"aborting\n");
@@ -5048,8 +5052,8 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
cas_saturn_firmware_init(cp);
cp->init_block =
- pci_alloc_consistent(pdev, sizeof(struct cas_init_block),
- &cp->block_dvma);
+ dma_alloc_coherent(&pdev->dev, sizeof(struct cas_init_block),
+ &cp->block_dvma, GFP_KERNEL);
if (!cp->init_block) {
dev_err(&pdev->dev, "Cannot allocate init block, aborting\n");
goto err_out_iounmap;
@@ -5109,8 +5113,8 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
err_out_free_consistent:
- pci_free_consistent(pdev, sizeof(struct cas_init_block),
- cp->init_block, cp->block_dvma);
+ dma_free_coherent(&pdev->dev, sizeof(struct cas_init_block),
+ cp->init_block, cp->block_dvma);
err_out_iounmap:
mutex_lock(&cp->pm_mutex);
@@ -5164,18 +5168,17 @@ static void cas_remove_one(struct pci_dev *pdev)
cp->orig_cacheline_size);
}
#endif
- pci_free_consistent(pdev, sizeof(struct cas_init_block),
- cp->init_block, cp->block_dvma);
+ dma_free_coherent(&pdev->dev, sizeof(struct cas_init_block),
+ cp->init_block, cp->block_dvma);
pci_iounmap(pdev, cp->regs);
free_netdev(dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
}
-#ifdef CONFIG_PM
-static int cas_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused cas_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct cas *cp = netdev_priv(dev);
unsigned long flags;
@@ -5204,9 +5207,9 @@ static int cas_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-static int cas_resume(struct pci_dev *pdev)
+static int __maybe_unused cas_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct cas *cp = netdev_priv(dev);
netdev_info(dev, "resuming\n");
@@ -5227,17 +5230,15 @@ static int cas_resume(struct pci_dev *pdev)
mutex_unlock(&cp->pm_mutex);
return 0;
}
-#endif /* CONFIG_PM */
+
+static SIMPLE_DEV_PM_OPS(cas_pm_ops, cas_suspend, cas_resume);
static struct pci_driver cas_driver = {
.name = DRV_MODULE_NAME,
.id_table = cas_pci_tbl,
.probe = cas_init_one,
.remove = cas_remove_one,
-#ifdef CONFIG_PM
- .suspend = cas_suspend,
- .resume = cas_resume
-#endif
+ .driver.pm = &cas_pm_ops,
};
static int __init cas_init(void)
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 1b697e4cd7dc..9b5effb72657 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -9873,9 +9873,9 @@ static void niu_pci_remove_one(struct pci_dev *pdev)
}
}
-static int niu_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused niu_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct niu *np = netdev_priv(dev);
unsigned long flags;
@@ -9897,14 +9897,12 @@ static int niu_suspend(struct pci_dev *pdev, pm_message_t state)
niu_stop_hw(np);
spin_unlock_irqrestore(&np->lock, flags);
- pci_save_state(pdev);
-
return 0;
}
-static int niu_resume(struct pci_dev *pdev)
+static int __maybe_unused niu_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct niu *np = netdev_priv(dev);
unsigned long flags;
int err;
@@ -9912,8 +9910,6 @@ static int niu_resume(struct pci_dev *pdev)
if (!netif_running(dev))
return 0;
- pci_restore_state(pdev);
-
netif_device_attach(dev);
spin_lock_irqsave(&np->lock, flags);
@@ -9930,13 +9926,14 @@ static int niu_resume(struct pci_dev *pdev)
return err;
}
+static SIMPLE_DEV_PM_OPS(niu_pm_ops, niu_suspend, niu_resume);
+
static struct pci_driver niu_pci_driver = {
.name = DRV_MODULE_NAME,
.id_table = niu_pci_tbl,
.probe = niu_pci_init_one,
.remove = niu_pci_remove_one,
- .suspend = niu_suspend,
- .resume = niu_resume,
+ .driver.pm = &niu_pm_ops,
};
#ifdef CONFIG_SPARC64
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index 2d392a7b179a..eeb8518c8a84 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -670,7 +670,8 @@ static __inline__ void gem_tx(struct net_device *dev, struct gem *gp, u32 gem_st
dma_addr = le64_to_cpu(txd->buffer);
dma_len = le64_to_cpu(txd->control_word) & TXDCTRL_BUFSZ;
- pci_unmap_page(gp->pdev, dma_addr, dma_len, PCI_DMA_TODEVICE);
+ dma_unmap_page(&gp->pdev->dev, dma_addr, dma_len,
+ DMA_TO_DEVICE);
entry = NEXT_TX(entry);
}
@@ -809,16 +810,15 @@ static int gem_rx(struct gem *gp, int work_to_do)
drops++;
goto drop_it;
}
- pci_unmap_page(gp->pdev, dma_addr,
- RX_BUF_ALLOC_SIZE(gp),
- PCI_DMA_FROMDEVICE);
+ dma_unmap_page(&gp->pdev->dev, dma_addr,
+ RX_BUF_ALLOC_SIZE(gp), DMA_FROM_DEVICE);
gp->rx_skbs[entry] = new_skb;
skb_put(new_skb, (gp->rx_buf_sz + RX_OFFSET));
- rxd->buffer = cpu_to_le64(pci_map_page(gp->pdev,
+ rxd->buffer = cpu_to_le64(dma_map_page(&gp->pdev->dev,
virt_to_page(new_skb->data),
offset_in_page(new_skb->data),
RX_BUF_ALLOC_SIZE(gp),
- PCI_DMA_FROMDEVICE));
+ DMA_FROM_DEVICE));
skb_reserve(new_skb, RX_OFFSET);
/* Trim the original skb for the netif. */
@@ -833,9 +833,11 @@ static int gem_rx(struct gem *gp, int work_to_do)
skb_reserve(copy_skb, 2);
skb_put(copy_skb, len);
- pci_dma_sync_single_for_cpu(gp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&gp->pdev->dev, dma_addr, len,
+ DMA_FROM_DEVICE);
skb_copy_from_linear_data(skb, copy_skb->data, len);
- pci_dma_sync_single_for_device(gp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&gp->pdev->dev, dma_addr,
+ len, DMA_FROM_DEVICE);
/* We'll reuse the original ring buffer. */
skb = copy_skb;
@@ -1020,10 +1022,10 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb,
u32 len;
len = skb->len;
- mapping = pci_map_page(gp->pdev,
+ mapping = dma_map_page(&gp->pdev->dev,
virt_to_page(skb->data),
offset_in_page(skb->data),
- len, PCI_DMA_TODEVICE);
+ len, DMA_TO_DEVICE);
ctrl |= TXDCTRL_SOF | TXDCTRL_EOF | len;
if (gem_intme(entry))
ctrl |= TXDCTRL_INTME;
@@ -1046,9 +1048,10 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb,
* Otherwise we could race with the device.
*/
first_len = skb_headlen(skb);
- first_mapping = pci_map_page(gp->pdev, virt_to_page(skb->data),
+ first_mapping = dma_map_page(&gp->pdev->dev,
+ virt_to_page(skb->data),
offset_in_page(skb->data),
- first_len, PCI_DMA_TODEVICE);
+ first_len, DMA_TO_DEVICE);
entry = NEXT_TX(entry);
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
@@ -1574,9 +1577,9 @@ static void gem_clean_rings(struct gem *gp)
if (gp->rx_skbs[i] != NULL) {
skb = gp->rx_skbs[i];
dma_addr = le64_to_cpu(rxd->buffer);
- pci_unmap_page(gp->pdev, dma_addr,
+ dma_unmap_page(&gp->pdev->dev, dma_addr,
RX_BUF_ALLOC_SIZE(gp),
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
gp->rx_skbs[i] = NULL;
}
@@ -1598,9 +1601,9 @@ static void gem_clean_rings(struct gem *gp)
txd = &gb->txd[ent];
dma_addr = le64_to_cpu(txd->buffer);
- pci_unmap_page(gp->pdev, dma_addr,
+ dma_unmap_page(&gp->pdev->dev, dma_addr,
le64_to_cpu(txd->control_word) &
- TXDCTRL_BUFSZ, PCI_DMA_TODEVICE);
+ TXDCTRL_BUFSZ, DMA_TO_DEVICE);
if (frag != skb_shinfo(skb)->nr_frags)
i++;
@@ -1637,11 +1640,11 @@ static void gem_init_rings(struct gem *gp)
gp->rx_skbs[i] = skb;
skb_put(skb, (gp->rx_buf_sz + RX_OFFSET));
- dma_addr = pci_map_page(gp->pdev,
+ dma_addr = dma_map_page(&gp->pdev->dev,
virt_to_page(skb->data),
offset_in_page(skb->data),
RX_BUF_ALLOC_SIZE(gp),
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
rxd->buffer = cpu_to_le64(dma_addr);
dma_wmb();
rxd->status_word = cpu_to_le64(RXDCTRL_FRESH(gp));
@@ -2139,20 +2142,6 @@ static int gem_do_start(struct net_device *dev)
struct gem *gp = netdev_priv(dev);
int rc;
- /* Enable the cell */
- gem_get_cell(gp);
-
- /* Make sure PCI access and bus master are enabled */
- rc = pci_enable_device(gp->pdev);
- if (rc) {
- netdev_err(dev, "Failed to enable chip on PCI bus !\n");
-
- /* Put cell and forget it for now, it will be considered as
- * still asleep, a new sleep cycle may bring it back
- */
- gem_put_cell(gp);
- return -ENXIO;
- }
pci_set_master(gp->pdev);
/* Init & setup chip hardware */
@@ -2230,13 +2219,6 @@ static void gem_do_stop(struct net_device *dev, int wol)
/* Shut the PHY down eventually and setup WOL */
gem_stop_phy(gp, wol);
-
- /* Make sure bus master is disabled */
- pci_disable_device(gp->pdev);
-
- /* Cell not needed neither if no WOL */
- if (!wol)
- gem_put_cell(gp);
}
static void gem_reset_task(struct work_struct *work)
@@ -2288,26 +2270,53 @@ static void gem_reset_task(struct work_struct *work)
static int gem_open(struct net_device *dev)
{
+ struct gem *gp = netdev_priv(dev);
+ int rc;
+
/* We allow open while suspended, we just do nothing,
* the chip will be initialized in resume()
*/
- if (netif_device_present(dev))
+ if (netif_device_present(dev)) {
+ /* Enable the cell */
+ gem_get_cell(gp);
+
+ /* Make sure PCI access and bus master are enabled */
+ rc = pci_enable_device(gp->pdev);
+ if (rc) {
+ netdev_err(dev, "Failed to enable chip on PCI bus !\n");
+
+ /* Put cell and forget it for now, it will be considered
+ *as still asleep, a new sleep cycle may bring it back
+ */
+ gem_put_cell(gp);
+ return -ENXIO;
+ }
return gem_do_start(dev);
+ }
+
return 0;
}
static int gem_close(struct net_device *dev)
{
- if (netif_device_present(dev))
+ struct gem *gp = netdev_priv(dev);
+
+ if (netif_device_present(dev)) {
gem_do_stop(dev, 0);
+ /* Make sure bus master is disabled */
+ pci_disable_device(gp->pdev);
+
+ /* Cell not needed neither if no WOL */
+ if (!gp->asleep_wol)
+ gem_put_cell(gp);
+ }
return 0;
}
-#ifdef CONFIG_PM
-static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused gem_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct gem *gp = netdev_priv(dev);
/* Lock the network stack first to avoid racing with open/close,
@@ -2336,15 +2345,19 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
gp->asleep_wol = !!gp->wake_on_lan;
gem_do_stop(dev, gp->asleep_wol);
+ /* Cell not needed neither if no WOL */
+ if (!gp->asleep_wol)
+ gem_put_cell(gp);
+
/* Unlock the network stack */
rtnl_unlock();
return 0;
}
-static int gem_resume(struct pci_dev *pdev)
+static int __maybe_unused gem_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct gem *gp = netdev_priv(dev);
/* See locking comment in gem_suspend */
@@ -2359,6 +2372,9 @@ static int gem_resume(struct pci_dev *pdev)
return 0;
}
+ /* Enable the cell */
+ gem_get_cell(gp);
+
/* Restart chip. If that fails there isn't much we can do, we
* leave things stopped.
*/
@@ -2375,7 +2391,6 @@ static int gem_resume(struct pci_dev *pdev)
return 0;
}
-#endif /* CONFIG_PM */
static struct net_device_stats *gem_get_stats(struct net_device *dev)
{
@@ -2802,10 +2817,8 @@ static void gem_remove_one(struct pci_dev *pdev)
cancel_work_sync(&gp->reset_task);
/* Free resources */
- pci_free_consistent(pdev,
- sizeof(struct gem_init_block),
- gp->init_block,
- gp->gblock_dvma);
+ dma_free_coherent(&pdev->dev, sizeof(struct gem_init_block),
+ gp->init_block, gp->gblock_dvma);
iounmap(gp->regs);
pci_release_regions(pdev);
free_netdev(dev);
@@ -2861,10 +2874,10 @@ static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
if (pdev->vendor == PCI_VENDOR_ID_SUN &&
pdev->device == PCI_DEVICE_ID_SUN_GEM &&
- !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
} else {
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
pr_err("No usable DMA configuration, aborting\n");
goto err_disable_device;
@@ -2953,8 +2966,8 @@ static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
* PAGE_SIZE aligned.
*/
gp->init_block = (struct gem_init_block *)
- pci_alloc_consistent(pdev, sizeof(struct gem_init_block),
- &gp->gblock_dvma);
+ dma_alloc_coherent(&pdev->dev, sizeof(struct gem_init_block),
+ &gp->gblock_dvma, GFP_KERNEL);
if (!gp->init_block) {
pr_err("Cannot allocate init block, aborting\n");
err = -ENOMEM;
@@ -3019,16 +3032,14 @@ err_disable_device:
}
+static SIMPLE_DEV_PM_OPS(gem_pm_ops, gem_suspend, gem_resume);
static struct pci_driver gem_driver = {
.name = GEM_MODULE_NAME,
.id_table = gem_pci_tbl,
.probe = gem_init_one,
.remove = gem_remove_one,
-#ifdef CONFIG_PM
- .suspend = gem_suspend,
- .resume = gem_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &gem_pm_ops,
};
module_pci_driver(gem_driver);
diff --git a/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c b/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c
index 07046a2370b3..26aa7f32151f 100644
--- a/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c
+++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c
@@ -697,7 +697,7 @@ static void xlgmac_tx_timeout(struct net_device *netdev, unsigned int txqueue)
schedule_work(&pdata->restart_work);
}
-static int xlgmac_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t xlgmac_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct xlgmac_pdata *pdata = netdev_priv(netdev);
struct xlgmac_pkt_info *tx_pkt_info;
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index 50f55364d4fb..abfc4c435d59 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -156,7 +156,7 @@ config TLAN
Devices currently supported by this driver are Compaq Netelligent,
Compaq NetFlex and Olicom cards. Please read the file
- <file:Documentation/networking/device_drivers/ti/tlan.rst>
+ <file:Documentation/networking/device_drivers/ethernet/ti/tlan.rst>
for more details.
To compile this driver as a module, choose M here. The module
diff --git a/drivers/net/ethernet/ti/am65-cpsw-ethtool.c b/drivers/net/ethernet/ti/am65-cpsw-ethtool.c
index 8c4690f3ebcb..496dafb25128 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-ethtool.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-ethtool.c
@@ -445,7 +445,7 @@ static int am65_cpsw_set_channels(struct net_device *ndev,
/* Check if interface is up. Can change the num queues when
* the interface is down.
*/
- if (netif_running(ndev))
+ if (common->usage_count)
return -EBUSY;
am65_cpsw_nuss_remove_tx_chns(common);
@@ -734,6 +734,9 @@ static int am65_cpsw_set_ethtool_priv_flags(struct net_device *ndev, u32 flags)
rrobin = !!(flags & AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN);
+ if (common->usage_count)
+ return -EBUSY;
+
if (common->est_enabled && rrobin) {
netdev_err(ndev,
"p0-rx-ptype-rrobin flag conflicts with QOS\n");
@@ -741,7 +744,6 @@ static int am65_cpsw_set_ethtool_priv_flags(struct net_device *ndev, u32 flags)
}
common->pf_p0_rx_ptype_rrobin = rrobin;
- am65_cpsw_nuss_set_p0_ptype(common);
return 0;
}
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index 6d778bc3d012..cb994f66c3be 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -23,6 +23,7 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
+#include <linux/sys_soc.h>
#include <linux/dma/ti-cppi5.h>
#include <linux/dma/k3-udma-glue.h>
@@ -148,10 +149,11 @@ static void am65_cpsw_nuss_get_ver(struct am65_cpsw_common *common)
common->nuss_ver = readl(common->ss_base);
common->cpsw_ver = readl(common->cpsw_base);
dev_info(common->dev,
- "initializing am65 cpsw nuss version 0x%08X, cpsw version 0x%08X Ports: %u\n",
+ "initializing am65 cpsw nuss version 0x%08X, cpsw version 0x%08X Ports: %u quirks:%08x\n",
common->nuss_ver,
common->cpsw_ver,
- common->port_num + 1);
+ common->port_num + 1,
+ common->pdata.quirks);
}
void am65_cpsw_nuss_adjust_link(struct net_device *ndev)
@@ -223,6 +225,9 @@ static int am65_cpsw_nuss_ndo_slave_add_vid(struct net_device *ndev,
u32 port_mask, unreg_mcast = 0;
int ret;
+ if (!netif_running(ndev) || !vid)
+ return 0;
+
ret = pm_runtime_get_sync(common->dev);
if (ret < 0) {
pm_runtime_put_noidle(common->dev);
@@ -246,6 +251,9 @@ static int am65_cpsw_nuss_ndo_slave_kill_vid(struct net_device *ndev,
struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
int ret;
+ if (!netif_running(ndev) || !vid)
+ return 0;
+
ret = pm_runtime_get_sync(common->dev);
if (ret < 0) {
pm_runtime_put_noidle(common->dev);
@@ -571,6 +579,16 @@ static int am65_cpsw_nuss_ndo_slave_stop(struct net_device *ndev)
return 0;
}
+static int cpsw_restore_vlans(struct net_device *vdev, int vid, void *arg)
+{
+ struct am65_cpsw_port *port = arg;
+
+ if (!vdev)
+ return 0;
+
+ return am65_cpsw_nuss_ndo_slave_add_vid(port->ndev, 0, vid);
+}
+
static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev)
{
struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
@@ -644,6 +662,9 @@ static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev)
}
}
+ /* restore vlan configurations */
+ vlan_for_each(ndev, cpsw_restore_vlans, port);
+
phy_attached_info(port->slave.phy);
phy_start(port->slave.phy);
@@ -1749,6 +1770,10 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
common->cpsw_base + AM65_CPSW_NU_FRAM_BASE +
(AM65_CPSW_NU_FRAM_PORT_OFFSET * (port_id - 1));
+ port->slave.mac_sl = cpsw_sl_get("am65", dev, port->port_base);
+ if (IS_ERR(port->slave.mac_sl))
+ return PTR_ERR(port->slave.mac_sl);
+
port->disabled = !of_device_is_available(port_np);
if (port->disabled)
continue;
@@ -1792,10 +1817,6 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
return ret;
}
- port->slave.mac_sl = cpsw_sl_get("am65", dev, port->port_base);
- if (IS_ERR(port->slave.mac_sl))
- return PTR_ERR(port->slave.mac_sl);
-
mac_addr = of_get_mac_address(port_np);
if (!IS_ERR(mac_addr)) {
ether_addr_copy(port->slave.mac_addr, mac_addr);
@@ -1859,7 +1880,7 @@ static int am65_cpsw_nuss_init_ndev_2g(struct am65_cpsw_common *common)
port->ndev->ethtool_ops = &am65_cpsw_ethtool_ops_slave;
/* Disable TX checksum offload by default due to HW bug */
- if (common->pdata->quirks & AM65_CPSW_QUIRK_I2027_NO_TX_CSUM)
+ if (common->pdata.quirks & AM65_CPSW_QUIRK_I2027_NO_TX_CSUM)
port->ndev->features &= ~NETIF_F_HW_CSUM;
ndev_priv->stats = netdev_alloc_pcpu_stats(struct am65_cpsw_ndev_stats);
@@ -1876,8 +1897,6 @@ static int am65_cpsw_nuss_init_ndev_2g(struct am65_cpsw_common *common)
netif_napi_add(port->ndev, &common->napi_rx,
am65_cpsw_nuss_rx_poll, NAPI_POLL_WEIGHT);
- common->pf_p0_rx_ptype_rrobin = false;
-
return ret;
}
@@ -1965,21 +1984,50 @@ static void am65_cpsw_nuss_cleanup_ndev(struct am65_cpsw_common *common)
}
}
+struct am65_cpsw_soc_pdata {
+ u32 quirks_dis;
+};
+
+static const struct am65_cpsw_soc_pdata am65x_soc_sr2_0 = {
+ .quirks_dis = AM65_CPSW_QUIRK_I2027_NO_TX_CSUM,
+};
+
+static const struct soc_device_attribute am65_cpsw_socinfo[] = {
+ { .family = "AM65X",
+ .revision = "SR2.0",
+ .data = &am65x_soc_sr2_0
+ },
+ {/* sentinel */}
+};
+
static const struct am65_cpsw_pdata am65x_sr1_0 = {
.quirks = AM65_CPSW_QUIRK_I2027_NO_TX_CSUM,
};
-static const struct am65_cpsw_pdata j721e_sr1_0 = {
+static const struct am65_cpsw_pdata j721e_pdata = {
.quirks = 0,
};
static const struct of_device_id am65_cpsw_nuss_of_mtable[] = {
- { .compatible = "ti,am654-cpsw-nuss", .data = &am65x_sr1_0 },
- { .compatible = "ti,j721e-cpsw-nuss", .data = &j721e_sr1_0 },
+ { .compatible = "ti,am654-cpsw-nuss", .data = &am65x_sr1_0},
+ { .compatible = "ti,j721e-cpsw-nuss", .data = &j721e_pdata},
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, am65_cpsw_nuss_of_mtable);
+static void am65_cpsw_nuss_apply_socinfo(struct am65_cpsw_common *common)
+{
+ const struct soc_device_attribute *soc;
+
+ soc = soc_device_match(am65_cpsw_socinfo);
+ if (soc && soc->data) {
+ const struct am65_cpsw_soc_pdata *socdata = soc->data;
+
+ /* disable quirks */
+ common->pdata.quirks &= ~socdata->quirks_dis;
+ }
+}
+
static int am65_cpsw_nuss_probe(struct platform_device *pdev)
{
struct cpsw_ale_params ale_params = { 0 };
@@ -1998,7 +2046,9 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
of_id = of_match_device(am65_cpsw_nuss_of_mtable, dev);
if (!of_id)
return -EINVAL;
- common->pdata = of_id->data;
+ common->pdata = *(const struct am65_cpsw_pdata *)of_id->data;
+
+ am65_cpsw_nuss_apply_socinfo(common);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cpsw_nuss");
common->ss_base = devm_ioremap_resource(&pdev->dev, res);
@@ -2020,6 +2070,7 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
common->rx_flow_id_base = -1;
init_completion(&common->tdown_complete);
common->tx_ch_num = 1;
+ common->pf_p0_rx_ptype_rrobin = false;
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(48));
if (ret) {
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.h b/drivers/net/ethernet/ti/am65-cpsw-nuss.h
index 9faf4fb1409b..94f666ea0e53 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.h
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.h
@@ -82,7 +82,7 @@ struct am65_cpsw_pdata {
struct am65_cpsw_common {
struct device *dev;
struct device *mdio_dev;
- const struct am65_cpsw_pdata *pdata;
+ struct am65_cpsw_pdata pdata;
void __iomem *ss_base;
void __iomem *cpsw_base;
diff --git a/drivers/net/ethernet/ti/am65-cpsw-qos.c b/drivers/net/ethernet/ti/am65-cpsw-qos.c
index 32eac04468bb..3bdd4dbcd2ff 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-qos.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-qos.c
@@ -505,7 +505,6 @@ static int am65_cpsw_set_taprio(struct net_device *ndev, void *type_data)
struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
struct tc_taprio_qopt_offload *taprio = type_data;
struct am65_cpsw_est *est_new;
- size_t size;
int ret = 0;
if (taprio->cycle_time_extension) {
@@ -513,10 +512,9 @@ static int am65_cpsw_set_taprio(struct net_device *ndev, void *type_data)
return -EOPNOTSUPP;
}
- size = sizeof(struct tc_taprio_sched_entry) * taprio->num_entries +
- sizeof(struct am65_cpsw_est);
-
- est_new = devm_kzalloc(&ndev->dev, size, GFP_KERNEL);
+ est_new = devm_kzalloc(&ndev->dev,
+ struct_size(est_new, taprio.entries, taprio->num_entries),
+ GFP_KERNEL);
if (!est_new)
return -ENOMEM;
diff --git a/drivers/net/ethernet/ti/cpsw_priv.c b/drivers/net/ethernet/ti/cpsw_priv.c
index a399f3659346..d6d7a7d9c7ad 100644
--- a/drivers/net/ethernet/ti/cpsw_priv.c
+++ b/drivers/net/ethernet/ti/cpsw_priv.c
@@ -1286,9 +1286,6 @@ int cpsw_ndo_bpf(struct net_device *ndev, struct netdev_bpf *bpf)
case XDP_SETUP_PROG:
return cpsw_xdp_prog_setup(priv, bpf);
- case XDP_QUERY_PROG:
- return xdp_attachment_query(&priv->xdpi, bpf);
-
default:
return -EINVAL;
}
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c
index 857709828058..58623e974a0c 100644
--- a/drivers/net/ethernet/ti/tlan.c
+++ b/drivers/net/ethernet/ti/tlan.c
@@ -70,7 +70,7 @@ MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
MODULE_LICENSE("GPL");
/* Turn on debugging.
- * See Documentation/networking/device_drivers/ti/tlan.rst for details
+ * See Documentation/networking/device_drivers/ethernet/ti/tlan.rst for details
*/
static int debug;
module_param(debug, int, 0);
@@ -345,33 +345,21 @@ static void tlan_stop(struct net_device *dev)
}
}
-#ifdef CONFIG_PM
-
-static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused tlan_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
if (netif_running(dev))
tlan_stop(dev);
netif_device_detach(dev);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_wake_from_d3(pdev, false);
- pci_set_power_state(pdev, PCI_D3hot);
return 0;
}
-static int tlan_resume(struct pci_dev *pdev)
+static int __maybe_unused tlan_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
- int rc = pci_enable_device(pdev);
-
- if (rc)
- return rc;
- pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D0, 0);
+ struct net_device *dev = dev_get_drvdata(dev_d);
netif_device_attach(dev);
if (netif_running(dev))
@@ -380,21 +368,14 @@ static int tlan_resume(struct pci_dev *pdev)
return 0;
}
-#else /* CONFIG_PM */
-
-#define tlan_suspend NULL
-#define tlan_resume NULL
-
-#endif /* CONFIG_PM */
-
+static SIMPLE_DEV_PM_OPS(tlan_pm_ops, tlan_suspend, tlan_resume);
static struct pci_driver tlan_driver = {
.name = "tlan",
.id_table = tlan_pci_tbl,
.probe = tlan_init_one,
.remove = tlan_remove_one,
- .suspend = tlan_suspend,
- .resume = tlan_resume,
+ .driver.pm = &tlan_pm_ops,
};
static int __init tlan_probe(void)
diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c
index 3902b3aeb0c2..07389702a540 100644
--- a/drivers/net/ethernet/toshiba/spider_net.c
+++ b/drivers/net/ethernet/toshiba/spider_net.c
@@ -283,8 +283,8 @@ spider_net_free_chain(struct spider_net_card *card,
descr = descr->next;
} while (descr != chain->ring);
- dma_free_coherent(&card->pdev->dev, chain->num_desc,
- chain->hwring, chain->dma_addr);
+ dma_free_coherent(&card->pdev->dev, chain->num_desc * sizeof(struct spider_net_hw_descr),
+ chain->hwring, chain->dma_addr);
}
/**
@@ -314,8 +314,6 @@ spider_net_init_chain(struct spider_net_card *card,
if (!chain->hwring)
return -ENOMEM;
- memset(chain->ring, 0, chain->num_desc * sizeof(struct spider_net_descr));
-
/* Set up the hardware pointers in each descriptor */
descr = chain->ring;
hwdescr = chain->hwring;
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index 713dbc04b25b..6d2a31488a74 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -32,6 +32,8 @@
* MODULE_LICENSE("GPL");
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/types.h>
#include <linux/bitops.h>
@@ -80,7 +82,6 @@ enum velocity_bus_type {
};
static int velocity_nics;
-static int msglevel = MSG_LEVEL_INFO;
static void velocity_set_power_state(struct velocity_info *vptr, char state)
{
@@ -405,24 +406,22 @@ static const char *get_chip_name(enum chip_type chip_id)
* @max: highest value allowed
* @def: default value
* @name: property name
- * @dev: device name
*
* Set an integer property in the module options. This function does
* all the verification and checking as well as reporting so that
* we don't duplicate code for each option.
*/
static void velocity_set_int_opt(int *opt, int val, int min, int max, int def,
- char *name, const char *devname)
+ char *name)
{
if (val == -1)
*opt = def;
else if (val < min || val > max) {
- VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n",
- devname, name, min, max);
+ pr_notice("the value of parameter %s is invalid, the valid range is (%d-%d)\n",
+ name, min, max);
*opt = def;
} else {
- VELOCITY_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n",
- devname, name, val);
+ pr_info("set value of parameter %s to %d\n", name, val);
*opt = val;
}
}
@@ -434,25 +433,24 @@ static void velocity_set_int_opt(int *opt, int val, int min, int max, int def,
* @def: default value (yes/no)
* @flag: numeric value to set for true.
* @name: property name
- * @dev: device name
*
* Set a boolean property in the module options. This function does
* all the verification and checking as well as reporting so that
* we don't duplicate code for each option.
*/
static void velocity_set_bool_opt(u32 *opt, int val, int def, u32 flag,
- char *name, const char *devname)
+ char *name)
{
(*opt) &= (~flag);
if (val == -1)
*opt |= (def ? flag : 0);
else if (val < 0 || val > 1) {
- printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
- devname, name);
+ pr_notice("the value of parameter %s is invalid, the valid range is (%d-%d)\n",
+ name, 0, 1);
*opt |= (def ? flag : 0);
} else {
- printk(KERN_INFO "%s: set parameter %s to %s\n",
- devname, name, val ? "TRUE" : "FALSE");
+ pr_info("set parameter %s to %s\n",
+ name, val ? "TRUE" : "FALSE");
*opt |= (val ? flag : 0);
}
}
@@ -461,24 +459,38 @@ static void velocity_set_bool_opt(u32 *opt, int val, int def, u32 flag,
* velocity_get_options - set options on device
* @opts: option structure for the device
* @index: index of option to use in module options array
- * @devname: device name
*
* Turn the module and command options into a single structure
* for the current device
*/
-static void velocity_get_options(struct velocity_opt *opts, int index,
- const char *devname)
-{
-
- velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname);
- velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname);
- velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
- velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname);
-
- velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
- velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
- velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname);
- velocity_set_int_opt(&opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname);
+static void velocity_get_options(struct velocity_opt *opts, int index)
+{
+
+ velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index],
+ RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF,
+ "rx_thresh");
+ velocity_set_int_opt(&opts->DMA_length, DMA_length[index],
+ DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF,
+ "DMA_length");
+ velocity_set_int_opt(&opts->numrx, RxDescriptors[index],
+ RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF,
+ "RxDescriptors");
+ velocity_set_int_opt(&opts->numtx, TxDescriptors[index],
+ TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF,
+ "TxDescriptors");
+
+ velocity_set_int_opt(&opts->flow_cntl, flow_control[index],
+ FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF,
+ "flow_control");
+ velocity_set_bool_opt(&opts->flags, IP_byte_align[index],
+ IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN,
+ "IP_byte_align");
+ velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index],
+ MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF,
+ "Media link mode");
+ velocity_set_int_opt(&opts->wol_opts, wol_opts[index],
+ WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF,
+ "Wake On Lan options");
opts->numrx = (opts->numrx & ~3);
}
@@ -880,7 +892,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
(mii_status==curr_status)) {
vptr->mii_status=mii_check_media_mode(vptr->mac_regs);
vptr->mii_status=check_connection_type(vptr->mac_regs);
- VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n");
+ netdev_info(vptr->netdev, "Velocity link no change\n");
return 0;
}
*/
@@ -892,7 +904,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
* If connection type is AUTO
*/
if (mii_status & VELOCITY_AUTONEG_ENABLE) {
- VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity is AUTO mode\n");
+ netdev_info(vptr->netdev, "Velocity is in AUTO mode\n");
/* clear force MAC mode bit */
BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
/* set duplex mode of MAC according to duplex mode of MII */
@@ -927,12 +939,14 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
if (mii_status & VELOCITY_DUPLEX_FULL) {
CHIPGCR |= CHIPGCR_FCFDX;
writeb(CHIPGCR, &regs->CHIPGCR);
- VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced full mode\n");
+ netdev_info(vptr->netdev,
+ "set Velocity to forced full mode\n");
if (vptr->rev_id < REV_ID_VT3216_A0)
BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
} else {
CHIPGCR &= ~CHIPGCR_FCFDX;
- VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced half mode\n");
+ netdev_info(vptr->netdev,
+ "set Velocity to forced half mode\n");
writeb(CHIPGCR, &regs->CHIPGCR);
if (vptr->rev_id < REV_ID_VT3216_A0)
BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
@@ -985,45 +999,61 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
*/
static void velocity_print_link_status(struct velocity_info *vptr)
{
+ const char *link;
+ const char *speed;
+ const char *duplex;
if (vptr->mii_status & VELOCITY_LINK_FAIL) {
- VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->netdev->name);
- } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
- VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->netdev->name);
+ netdev_notice(vptr->netdev, "failed to detect cable link\n");
+ return;
+ }
+
+ if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
+ link = "auto-negotiation";
if (vptr->mii_status & VELOCITY_SPEED_1000)
- VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
+ speed = "1000";
else if (vptr->mii_status & VELOCITY_SPEED_100)
- VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps");
+ speed = "100";
else
- VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps");
+ speed = "10";
if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
- VELOCITY_PRT(MSG_LEVEL_INFO, " full duplex\n");
+ duplex = "full";
else
- VELOCITY_PRT(MSG_LEVEL_INFO, " half duplex\n");
+ duplex = "half";
} else {
- VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->netdev->name);
+ link = "forced";
+
switch (vptr->options.spd_dpx) {
case SPD_DPX_1000_FULL:
- VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps full duplex\n");
+ speed = "1000";
+ duplex = "full";
break;
case SPD_DPX_100_HALF:
- VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n");
+ speed = "100";
+ duplex = "half";
break;
case SPD_DPX_100_FULL:
- VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps full duplex\n");
+ speed = "100";
+ duplex = "full";
break;
case SPD_DPX_10_HALF:
- VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps half duplex\n");
+ speed = "10";
+ duplex = "half";
break;
case SPD_DPX_10_FULL:
- VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps full duplex\n");
+ speed = "10";
+ duplex = "full";
break;
default:
+ speed = "unknown";
+ duplex = "unknown";
break;
}
}
+ netdev_notice(vptr->netdev, "Link %s speed %sM bps %s duplex\n",
+ link, speed, duplex);
}
/**
@@ -1621,8 +1651,7 @@ static int velocity_init_rd_ring(struct velocity_info *vptr)
velocity_init_rx_ring_indexes(vptr);
if (velocity_rx_refill(vptr) != vptr->options.numrx) {
- VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
- "%s: failed to allocate RX buffer.\n", vptr->netdev->name);
+ netdev_err(vptr->netdev, "failed to allocate RX buffer\n");
velocity_free_rd_ring(vptr);
goto out;
}
@@ -1805,7 +1834,8 @@ static void velocity_error(struct velocity_info *vptr, int status)
if (status & ISR_TXSTLI) {
struct mac_regs __iomem *regs = vptr->mac_regs;
- printk(KERN_ERR "TD structure error TDindex=%hx\n", readw(&regs->TDIdx[0]));
+ netdev_err(vptr->netdev, "TD structure error TDindex=%hx\n",
+ readw(&regs->TDIdx[0]));
BYTE_REG_BITS_ON(TXESR_TDSTR, &regs->TXESR);
writew(TRDCSR_RUN, &regs->TDCSRClr);
netif_stop_queue(vptr->netdev);
@@ -2036,7 +2066,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
if (unlikely(rd->rdesc0.RSR & (RSR_STP | RSR_EDP | RSR_RL))) {
if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP))
- VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame spans multiple RDs.\n", vptr->netdev->name);
+ netdev_err(vptr->netdev, "received frame spans multiple RDs\n");
stats->rx_length_errors++;
return -EINVAL;
}
@@ -2721,11 +2751,8 @@ static int velocity_get_platform_info(struct velocity_info *vptr)
*/
static void velocity_print_info(struct velocity_info *vptr)
{
- struct net_device *dev = vptr->netdev;
-
- printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
- printk(KERN_INFO "%s: Ethernet Address: %pM\n",
- dev->name, dev->dev_addr);
+ netdev_info(vptr->netdev, "%s - Ethernet Address: %pM\n",
+ get_chip_name(vptr->chip_id), vptr->netdev->dev_addr);
}
static u32 velocity_get_link(struct net_device *dev)
@@ -2748,10 +2775,8 @@ static int velocity_probe(struct device *dev, int irq,
const struct velocity_info_tbl *info,
enum velocity_bus_type bustype)
{
- static int first = 1;
struct net_device *netdev;
int i;
- const char *drv_string;
struct velocity_info *vptr;
struct mac_regs __iomem *regs;
int ret = -ENOMEM;
@@ -2773,13 +2798,9 @@ static int velocity_probe(struct device *dev, int irq,
SET_NETDEV_DEV(netdev, dev);
vptr = netdev_priv(netdev);
- if (first) {
- printk(KERN_INFO "%s Ver. %s\n",
- VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
- printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
- printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
- first = 0;
- }
+ pr_info_once("%s Ver. %s\n", VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
+ pr_info_once("Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
+ pr_info_once("Copyright (c) 2004 Red Hat Inc.\n");
netdev->irq = irq;
vptr->netdev = netdev;
@@ -2815,9 +2836,7 @@ static int velocity_probe(struct device *dev, int irq,
netdev->dev_addr[i] = readb(&regs->PAR[i]);
- drv_string = dev_driver_string(dev);
-
- velocity_get_options(&vptr->options, velocity_nics, drv_string);
+ velocity_get_options(&vptr->options, velocity_nics);
/*
* Mask out the options cannot be set to the chip
@@ -3469,16 +3488,6 @@ static int velocity_ethtool_set_wol(struct net_device *dev, struct ethtool_wolin
return 0;
}
-static u32 velocity_get_msglevel(struct net_device *dev)
-{
- return msglevel;
-}
-
-static void velocity_set_msglevel(struct net_device *dev, u32 value)
-{
- msglevel = value;
-}
-
static int get_pending_timer_val(int val)
{
int mult_bits = val >> 6;
@@ -3653,8 +3662,6 @@ static const struct ethtool_ops velocity_ethtool_ops = {
.get_drvinfo = velocity_get_drvinfo,
.get_wol = velocity_ethtool_get_wol,
.set_wol = velocity_ethtool_set_wol,
- .get_msglevel = velocity_get_msglevel,
- .set_msglevel = velocity_set_msglevel,
.get_link = velocity_get_link,
.get_strings = velocity_get_strings,
.get_sset_count = velocity_get_sset_count,
diff --git a/drivers/net/ethernet/via/via-velocity.h b/drivers/net/ethernet/via/via-velocity.h
index f196e71d2c04..d3f960cc7c6e 100644
--- a/drivers/net/ethernet/via/via-velocity.h
+++ b/drivers/net/ethernet/via/via-velocity.h
@@ -1286,50 +1286,6 @@ struct velocity_context {
velocity_mii_read((p),MII_PHYSID1,((u16 *) &id)+1);\
(id);})
-/*
- * Inline debug routine
- */
-
-
-enum velocity_msg_level {
- MSG_LEVEL_ERR = 0, //Errors that will cause abnormal operation.
- MSG_LEVEL_NOTICE = 1, //Some errors need users to be notified.
- MSG_LEVEL_INFO = 2, //Normal message.
- MSG_LEVEL_VERBOSE = 3, //Will report all trival errors.
- MSG_LEVEL_DEBUG = 4 //Only for debug purpose.
-};
-
-#ifdef VELOCITY_DEBUG
-#define ASSERT(x) { \
- if (!(x)) { \
- printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\
- __func__, __LINE__);\
- BUG(); \
- }\
-}
-#define VELOCITY_DBG(p,args...) printk(p, ##args)
-#else
-#define ASSERT(x)
-#define VELOCITY_DBG(x)
-#endif
-
-#define VELOCITY_PRT(l, p, args...) do {if (l<=msglevel) printk( p ,##args);} while (0)
-
-#define VELOCITY_PRT_CAMMASK(p,t) {\
- int i;\
- if ((t)==VELOCITY_MULTICAST_CAM) {\
- for (i=0;i<(MCAM_SIZE/8);i++)\
- printk("%02X",(p)->mCAMmask[i]);\
- }\
- else {\
- for (i=0;i<(VCAM_SIZE/8);i++)\
- printk("%02X",(p)->vCAMmask[i]);\
- }\
- printk("\n");\
-}
-
-
-
#define VELOCITY_WOL_MAGIC 0x00000000UL
#define VELOCITY_WOL_PHY 0x00000001UL
#define VELOCITY_WOL_ARP 0x00000002UL
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 929244064abd..9a15f14daa47 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -1407,10 +1407,8 @@ static int temac_probe(struct platform_device *pdev)
}
/* map device registers */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- lp->regs = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (!lp->regs) {
+ lp->regs = devm_platform_ioremap_resource_byname(pdev, 0);
+ if (IS_ERR(lp->regs)) {
dev_err(&pdev->dev, "could not map TEMAC registers\n");
return -ENOMEM;
}
diff --git a/drivers/net/ethernet/xircom/xirc2ps_cs.c b/drivers/net/ethernet/xircom/xirc2ps_cs.c
index 480ab7251515..3e3883ad88b0 100644
--- a/drivers/net/ethernet/xircom/xirc2ps_cs.c
+++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c
@@ -1473,7 +1473,7 @@ do_reset(struct net_device *dev, int full)
unsigned int ioaddr = dev->base_addr;
unsigned value;
- pr_debug("%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
+ pr_debug("%s: do_reset(%p,%d)\n", dev->name, dev, full);
hardreset(dev);
PutByte(XIRCREG_CR, SoftReset); /* set */
diff --git a/drivers/net/fddi/Kconfig b/drivers/net/fddi/Kconfig
index 60cc7524520c..f722079dfb6a 100644
--- a/drivers/net/fddi/Kconfig
+++ b/drivers/net/fddi/Kconfig
@@ -77,8 +77,8 @@ config SKFP
- Netelligent 100 FDDI SAS UTP
- Netelligent 100 FDDI SAS Fibre MIC
- Read <file:Documentation/networking/skfp.rst> for information about
- the driver.
+ Read <file:Documentation/networking/device_drivers/fddi/skfp.rst>
+ for information about the driver.
Questions concerning this driver can be addressed to:
<linux@syskonnect.de>
diff --git a/drivers/net/fddi/skfp/ess.c b/drivers/net/fddi/skfp/ess.c
index a546eaf071f7..afd5ca39f43b 100644
--- a/drivers/net/fddi/skfp/ess.c
+++ b/drivers/net/fddi/skfp/ess.c
@@ -148,7 +148,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
DB_ESSN(2, "fc %x ft %x", sm->smt_class, sm->smt_type);
DB_ESSN(2, "ver %x tran %x", sm->smt_version, sm->smt_tid);
- DB_ESSN(2, "stn_id %s", addr_to_string(&sm->smt_source));
+ DB_ESSN(2, "stn_id %pM", &sm->smt_source);
DB_ESSN(2, "infolen %x res %lx", sm->smt_len, msg_res_type);
DB_ESSN(2, "sbacmd %x", cmd->sba_cmd);
@@ -308,8 +308,8 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
overhead = ((struct smt_p_3210 *)p)->mib_overhead ;
- DB_ESSN(2, "ESS: Change Request from %s",
- addr_to_string(&sm->smt_source));
+ DB_ESSN(2, "ESS: Change Request from %pM",
+ &sm->smt_source);
DB_ESSN(2, "payload= %lx overhead= %lx",
payload, overhead);
@@ -339,8 +339,8 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
return fs;
}
- DB_ESSN(2, "ESS: Report Request from %s",
- addr_to_string(&sm->smt_source));
+ DB_ESSN(2, "ESS: Report Request from %pM",
+ &sm->smt_source);
/*
* verify that the resource type is sync bw only
diff --git a/drivers/net/fddi/skfp/h/cmtdef.h b/drivers/net/fddi/skfp/h/cmtdef.h
index 3a1ceb7cb8d2..4dd590d65d76 100644
--- a/drivers/net/fddi/skfp/h/cmtdef.h
+++ b/drivers/net/fddi/skfp/h/cmtdef.h
@@ -640,7 +640,6 @@ void dump_smt(struct s_smc *smc, struct smt_header *sm, char *text);
#define dump_smt(smc,sm,text)
#endif
-char* addr_to_string(struct fddi_addr *addr);
#ifdef DEBUG
void dump_hex(char *p, int len);
#endif
diff --git a/drivers/net/fddi/skfp/smt.c b/drivers/net/fddi/skfp/smt.c
index 47c48202a68c..b8c59d803ce6 100644
--- a/drivers/net/fddi/skfp/smt.c
+++ b/drivers/net/fddi/skfp/smt.c
@@ -520,8 +520,8 @@ void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
* ignore any packet with NSA and A-indicator set
*/
if ( (fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) {
- DB_SMT("SMT : ignoring NSA with A-indicator set from %s",
- addr_to_string(&sm->smt_source));
+ DB_SMT("SMT : ignoring NSA with A-indicator set from %pM",
+ &sm->smt_source);
smt_free_mbuf(smc,mb) ;
return ;
}
@@ -552,8 +552,8 @@ void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
break ;
}
if (illegal) {
- DB_SMT("SMT : version = %d, dest = %s",
- sm->smt_version, addr_to_string(&sm->smt_source));
+ DB_SMT("SMT : version = %d, dest = %pM",
+ sm->smt_version, &sm->smt_source);
smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_VERSION,local) ;
smt_free_mbuf(smc,mb) ;
return ;
@@ -582,8 +582,8 @@ void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
if (!is_equal(
&smc->mib.m[MAC0].fddiMACUpstreamNbr,
&sm->smt_source)) {
- DB_SMT("SMT : updated my UNA = %s",
- addr_to_string(&sm->smt_source));
+ DB_SMT("SMT : updated my UNA = %pM",
+ &sm->smt_source);
if (!is_equal(&smc->mib.m[MAC0].
fddiMACUpstreamNbr,&SMT_Unknown)){
/* Do not update unknown address */
@@ -612,8 +612,8 @@ void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
is_individual(&sm->smt_source) &&
((!(fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) ||
(m_fc(mb) != FC_SMT_NSA))) {
- DB_SMT("SMT : replying to NIF request %s",
- addr_to_string(&sm->smt_source));
+ DB_SMT("SMT : replying to NIF request %pM",
+ &sm->smt_source);
smt_send_nif(smc,&sm->smt_source,
FC_SMT_INFO,
sm->smt_tid,
@@ -621,8 +621,8 @@ void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
}
break ;
case SMT_REPLY :
- DB_SMT("SMT : received NIF response from %s",
- addr_to_string(&sm->smt_source));
+ DB_SMT("SMT : received NIF response from %pM",
+ &sm->smt_source);
if (fs & A_INDICATOR) {
smc->sm.pend[SMT_TID_NIF] = 0 ;
DB_SMT("SMT : duplicate address");
@@ -682,23 +682,23 @@ void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
case SMT_SIF_CONFIG : /* station information */
if (sm->smt_type != SMT_REQUEST)
break ;
- DB_SMT("SMT : replying to SIF Config request from %s",
- addr_to_string(&sm->smt_source));
+ DB_SMT("SMT : replying to SIF Config request from %pM",
+ &sm->smt_source);
smt_send_sif_config(smc,&sm->smt_source,sm->smt_tid,local) ;
break ;
case SMT_SIF_OPER : /* station information */
if (sm->smt_type != SMT_REQUEST)
break ;
- DB_SMT("SMT : replying to SIF Operation request from %s",
- addr_to_string(&sm->smt_source));
+ DB_SMT("SMT : replying to SIF Operation request from %pM",
+ &sm->smt_source);
smt_send_sif_operation(smc,&sm->smt_source,sm->smt_tid,local) ;
break ;
case SMT_ECF : /* echo frame */
switch (sm->smt_type) {
case SMT_REPLY :
smc->mib.priv.fddiPRIVECF_Reply_Rx++ ;
- DB_SMT("SMT: received ECF reply from %s",
- addr_to_string(&sm->smt_source));
+ DB_SMT("SMT: received ECF reply from %pM",
+ &sm->smt_source);
if (sm_to_para(smc,sm,SMT_P_ECHODATA) == NULL) {
DB_SMT("SMT: ECHODATA missing");
break ;
@@ -727,8 +727,8 @@ void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
local) ;
break ;
}
- DB_SMT("SMT - sending ECF reply to %s",
- addr_to_string(&sm->smt_source));
+ DB_SMT("SMT - sending ECF reply to %pM",
+ &sm->smt_source);
/* set destination addr. & reply */
sm->smt_dest = sm->smt_source ;
@@ -794,8 +794,8 @@ void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
* we need to send a RDF frame according to 8.1.3.1.1,
* only if it is a REQUEST.
*/
- DB_SMT("SMT : class = %d, send RDF to %s",
- sm->smt_class, addr_to_string(&sm->smt_source));
+ DB_SMT("SMT : class = %d, send RDF to %pM",
+ sm->smt_class, &sm->smt_source);
smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_CLASS,local) ;
break ;
@@ -864,8 +864,8 @@ static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,
if (sm->smt_type != SMT_REQUEST)
return ;
- DB_SMT("SMT: sending RDF to %s,reason = 0x%x",
- addr_to_string(&sm->smt_source), reason);
+ DB_SMT("SMT: sending RDF to %pM,reason = 0x%x",
+ &sm->smt_source, reason);
/*
@@ -1715,22 +1715,6 @@ void fddi_send_antc(struct s_smc *smc, struct fddi_addr *dest)
}
#endif
-#ifdef DEBUG
-char *addr_to_string(struct fddi_addr *addr)
-{
- int i ;
- static char string[6*3] = "****" ;
-
- for (i = 0 ; i < 6 ; i++) {
- string[i * 3] = hex_asc_hi(addr->a[i]);
- string[i * 3 + 1] = hex_asc_lo(addr->a[i]);
- string[i * 3 + 2] = ':';
- }
- string[5 * 3 + 2] = 0;
- return string;
-}
-#endif
-
/*
* return static mac index
*/
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index dec52b763d50..c71f994fbc73 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -48,6 +48,14 @@ struct geneve_dev_node {
struct geneve_dev *geneve;
};
+struct geneve_config {
+ struct ip_tunnel_info info;
+ bool collect_md;
+ bool use_udp6_rx_checksums;
+ bool ttl_inherit;
+ enum ifla_geneve_df df;
+};
+
/* Pseudo network device */
struct geneve_dev {
struct geneve_dev_node hlist4; /* vni hash table for IPv4 socket */
@@ -56,17 +64,13 @@ struct geneve_dev {
#endif
struct net *net; /* netns for packet i/o */
struct net_device *dev; /* netdev for geneve tunnel */
- struct ip_tunnel_info info;
struct geneve_sock __rcu *sock4; /* IPv4 socket used for geneve tunnel */
#if IS_ENABLED(CONFIG_IPV6)
struct geneve_sock __rcu *sock6; /* IPv6 socket used for geneve tunnel */
#endif
struct list_head next; /* geneve's per namespace list */
struct gro_cells gro_cells;
- bool collect_md;
- bool use_udp6_rx_checksums;
- bool ttl_inherit;
- enum ifla_geneve_df df;
+ struct geneve_config cfg;
};
struct geneve_sock {
@@ -132,8 +136,8 @@ static struct geneve_dev *geneve_lookup(struct geneve_sock *gs,
hash = geneve_net_vni_hash(vni);
vni_list_head = &gs->vni_list[hash];
hlist_for_each_entry_rcu(node, vni_list_head, hlist) {
- if (eq_tun_id_and_vni((u8 *)&node->geneve->info.key.tun_id, vni) &&
- addr == node->geneve->info.key.u.ipv4.dst)
+ if (eq_tun_id_and_vni((u8 *)&node->geneve->cfg.info.key.tun_id, vni) &&
+ addr == node->geneve->cfg.info.key.u.ipv4.dst)
return node->geneve;
}
return NULL;
@@ -151,8 +155,8 @@ static struct geneve_dev *geneve6_lookup(struct geneve_sock *gs,
hash = geneve_net_vni_hash(vni);
vni_list_head = &gs->vni_list[hash];
hlist_for_each_entry_rcu(node, vni_list_head, hlist) {
- if (eq_tun_id_and_vni((u8 *)&node->geneve->info.key.tun_id, vni) &&
- ipv6_addr_equal(&addr6, &node->geneve->info.key.u.ipv6.dst))
+ if (eq_tun_id_and_vni((u8 *)&node->geneve->cfg.info.key.tun_id, vni) &&
+ ipv6_addr_equal(&addr6, &node->geneve->cfg.info.key.u.ipv6.dst))
return node->geneve;
}
return NULL;
@@ -321,7 +325,7 @@ static int geneve_init(struct net_device *dev)
return err;
}
- err = dst_cache_init(&geneve->info.dst_cache, GFP_KERNEL);
+ err = dst_cache_init(&geneve->cfg.info.dst_cache, GFP_KERNEL);
if (err) {
free_percpu(dev->tstats);
gro_cells_destroy(&geneve->gro_cells);
@@ -334,7 +338,7 @@ static void geneve_uninit(struct net_device *dev)
{
struct geneve_dev *geneve = netdev_priv(dev);
- dst_cache_destroy(&geneve->info.dst_cache);
+ dst_cache_destroy(&geneve->cfg.info.dst_cache);
gro_cells_destroy(&geneve->gro_cells);
free_percpu(dev->tstats);
}
@@ -654,19 +658,19 @@ static int geneve_sock_add(struct geneve_dev *geneve, bool ipv6)
__u8 vni[3];
__u32 hash;
- gs = geneve_find_sock(gn, ipv6 ? AF_INET6 : AF_INET, geneve->info.key.tp_dst);
+ gs = geneve_find_sock(gn, ipv6 ? AF_INET6 : AF_INET, geneve->cfg.info.key.tp_dst);
if (gs) {
gs->refcnt++;
goto out;
}
- gs = geneve_socket_create(net, geneve->info.key.tp_dst, ipv6,
- geneve->use_udp6_rx_checksums);
+ gs = geneve_socket_create(net, geneve->cfg.info.key.tp_dst, ipv6,
+ geneve->cfg.use_udp6_rx_checksums);
if (IS_ERR(gs))
return PTR_ERR(gs);
out:
- gs->collect_md = geneve->collect_md;
+ gs->collect_md = geneve->cfg.collect_md;
#if IS_ENABLED(CONFIG_IPV6)
if (ipv6) {
rcu_assign_pointer(geneve->sock6, gs);
@@ -679,7 +683,7 @@ out:
}
node->geneve = geneve;
- tunnel_id_to_vni(geneve->info.key.tun_id, vni);
+ tunnel_id_to_vni(geneve->cfg.info.key.tun_id, vni);
hash = geneve_net_vni_hash(vni);
hlist_add_head_rcu(&node->hlist, &gs->vni_list[hash]);
return 0;
@@ -688,11 +692,11 @@ out:
static int geneve_open(struct net_device *dev)
{
struct geneve_dev *geneve = netdev_priv(dev);
- bool metadata = geneve->collect_md;
+ bool metadata = geneve->cfg.collect_md;
bool ipv4, ipv6;
int ret = 0;
- ipv6 = geneve->info.mode & IP_TUNNEL_INFO_IPV6 || metadata;
+ ipv6 = geneve->cfg.info.mode & IP_TUNNEL_INFO_IPV6 || metadata;
ipv4 = !ipv6 || metadata;
#if IS_ENABLED(CONFIG_IPV6)
if (ipv6) {
@@ -791,7 +795,7 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
fl4->saddr = info->key.u.ipv4.src;
tos = info->key.tos;
- if ((tos == 1) && !geneve->collect_md) {
+ if ((tos == 1) && !geneve->cfg.collect_md) {
tos = ip_tunnel_get_dsfield(ip_hdr(skb), skb);
use_cache = false;
}
@@ -840,7 +844,7 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
fl6->daddr = info->key.u.ipv6.dst;
fl6->saddr = info->key.u.ipv6.src;
prio = info->key.tos;
- if ((prio == 1) && !geneve->collect_md) {
+ if ((prio == 1) && !geneve->cfg.collect_md) {
prio = ip_tunnel_get_dsfield(ip_hdr(skb), skb);
use_cache = false;
}
@@ -889,26 +893,49 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (IS_ERR(rt))
return PTR_ERR(rt);
- skb_tunnel_check_pmtu(skb, &rt->dst,
- GENEVE_IPV4_HLEN + info->options_len);
+ err = skb_tunnel_check_pmtu(skb, &rt->dst,
+ GENEVE_IPV4_HLEN + info->options_len,
+ netif_is_any_bridge_port(dev));
+ if (err < 0) {
+ dst_release(&rt->dst);
+ return err;
+ } else if (err) {
+ struct ip_tunnel_info *info;
+
+ info = skb_tunnel_info(skb);
+ if (info) {
+ info->key.u.ipv4.dst = fl4.saddr;
+ info->key.u.ipv4.src = fl4.daddr;
+ }
+
+ if (!pskb_may_pull(skb, ETH_HLEN)) {
+ dst_release(&rt->dst);
+ return -EINVAL;
+ }
+
+ skb->protocol = eth_type_trans(skb, geneve->dev);
+ netif_rx(skb);
+ dst_release(&rt->dst);
+ return -EMSGSIZE;
+ }
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
- if (geneve->collect_md) {
+ if (geneve->cfg.collect_md) {
tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
ttl = key->ttl;
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
} else {
tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
- if (geneve->ttl_inherit)
+ if (geneve->cfg.ttl_inherit)
ttl = ip_tunnel_get_ttl(ip_hdr(skb), skb);
else
ttl = key->ttl;
ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
- if (geneve->df == GENEVE_DF_SET) {
+ if (geneve->cfg.df == GENEVE_DF_SET) {
df = htons(IP_DF);
- } else if (geneve->df == GENEVE_DF_INHERIT) {
+ } else if (geneve->cfg.df == GENEVE_DF_INHERIT) {
struct ethhdr *eth = eth_hdr(skb);
if (ntohs(eth->h_proto) == ETH_P_IPV6) {
@@ -927,7 +954,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
return err;
udp_tunnel_xmit_skb(rt, gs4->sock->sk, skb, fl4.saddr, fl4.daddr,
- tos, ttl, df, sport, geneve->info.key.tp_dst,
+ tos, ttl, df, sport, geneve->cfg.info.key.tp_dst,
!net_eq(geneve->net, dev_net(geneve->dev)),
!(info->key.tun_flags & TUNNEL_CSUM));
return 0;
@@ -951,16 +978,39 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (IS_ERR(dst))
return PTR_ERR(dst);
- skb_tunnel_check_pmtu(skb, dst, GENEVE_IPV6_HLEN + info->options_len);
+ err = skb_tunnel_check_pmtu(skb, dst,
+ GENEVE_IPV6_HLEN + info->options_len,
+ netif_is_any_bridge_port(dev));
+ if (err < 0) {
+ dst_release(dst);
+ return err;
+ } else if (err) {
+ struct ip_tunnel_info *info = skb_tunnel_info(skb);
+
+ if (info) {
+ info->key.u.ipv6.dst = fl6.saddr;
+ info->key.u.ipv6.src = fl6.daddr;
+ }
+
+ if (!pskb_may_pull(skb, ETH_HLEN)) {
+ dst_release(dst);
+ return -EINVAL;
+ }
+
+ skb->protocol = eth_type_trans(skb, geneve->dev);
+ netif_rx(skb);
+ dst_release(dst);
+ return -EMSGSIZE;
+ }
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
- if (geneve->collect_md) {
+ if (geneve->cfg.collect_md) {
prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
ttl = key->ttl;
} else {
prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel),
ip_hdr(skb), skb);
- if (geneve->ttl_inherit)
+ if (geneve->cfg.ttl_inherit)
ttl = ip_tunnel_get_ttl(ip_hdr(skb), skb);
else
ttl = key->ttl;
@@ -972,7 +1022,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,
&fl6.saddr, &fl6.daddr, prio, ttl,
- info->key.label, sport, geneve->info.key.tp_dst,
+ info->key.label, sport, geneve->cfg.info.key.tp_dst,
!(info->key.tun_flags & TUNNEL_CSUM));
return 0;
}
@@ -984,7 +1034,7 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
struct ip_tunnel_info *info = NULL;
int err;
- if (geneve->collect_md) {
+ if (geneve->cfg.collect_md) {
info = skb_tunnel_info(skb);
if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) {
netdev_dbg(dev, "no tunnel metadata\n");
@@ -993,7 +1043,7 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
} else {
- info = &geneve->info;
+ info = &geneve->cfg.info;
}
rcu_read_lock();
@@ -1008,7 +1058,8 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
if (likely(!err))
return NETDEV_TX_OK;
- dev_kfree_skb(skb);
+ if (err != -EMSGSIZE)
+ dev_kfree_skb(skb);
if (err == -ELOOP)
dev->stats.collisions++;
@@ -1065,7 +1116,7 @@ static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
info->key.tp_src = udp_flow_src_port(geneve->net, skb,
1, USHRT_MAX, true);
- info->key.tp_dst = geneve->info.key.tp_dst;
+ info->key.tp_dst = geneve->cfg.info.key.tp_dst;
return 0;
}
@@ -1227,13 +1278,13 @@ static struct geneve_dev *geneve_find_dev(struct geneve_net *gn,
*tun_on_same_port = false;
*tun_collect_md = false;
list_for_each_entry(geneve, &gn->geneve_list, next) {
- if (info->key.tp_dst == geneve->info.key.tp_dst) {
- *tun_collect_md = geneve->collect_md;
+ if (info->key.tp_dst == geneve->cfg.info.key.tp_dst) {
+ *tun_collect_md = geneve->cfg.collect_md;
*tun_on_same_port = true;
}
- if (info->key.tun_id == geneve->info.key.tun_id &&
- info->key.tp_dst == geneve->info.key.tp_dst &&
- !memcmp(&info->key.u, &geneve->info.key.u, sizeof(info->key.u)))
+ if (info->key.tun_id == geneve->cfg.info.key.tun_id &&
+ info->key.tp_dst == geneve->cfg.info.key.tp_dst &&
+ !memcmp(&info->key.u, &geneve->cfg.info.key.u, sizeof(info->key.u)))
t = geneve;
}
return t;
@@ -1257,16 +1308,15 @@ static bool geneve_dst_addr_equal(struct ip_tunnel_info *a,
static int geneve_configure(struct net *net, struct net_device *dev,
struct netlink_ext_ack *extack,
- const struct ip_tunnel_info *info,
- bool metadata, bool ipv6_rx_csum,
- bool ttl_inherit, enum ifla_geneve_df df)
+ const struct geneve_config *cfg)
{
struct geneve_net *gn = net_generic(net, geneve_net_id);
struct geneve_dev *t, *geneve = netdev_priv(dev);
+ const struct ip_tunnel_info *info = &cfg->info;
bool tun_collect_md, tun_on_same_port;
int err, encap_len;
- if (metadata && !is_tnl_info_zero(info)) {
+ if (cfg->collect_md && !is_tnl_info_zero(info)) {
NL_SET_ERR_MSG(extack,
"Device is externally controlled, so attributes (VNI, Port, and so on) must not be specified");
return -EINVAL;
@@ -1281,7 +1331,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
/* make enough headroom for basic scenario */
encap_len = GENEVE_BASE_HLEN + ETH_HLEN;
- if (!metadata && ip_tunnel_info_af(info) == AF_INET) {
+ if (!cfg->collect_md && ip_tunnel_info_af(info) == AF_INET) {
encap_len += sizeof(struct iphdr);
dev->max_mtu -= sizeof(struct iphdr);
} else {
@@ -1290,7 +1340,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
}
dev->needed_headroom = encap_len + ETH_HLEN;
- if (metadata) {
+ if (cfg->collect_md) {
if (tun_on_same_port) {
NL_SET_ERR_MSG(extack,
"There can be only one externally controlled device on a destination port");
@@ -1304,12 +1354,8 @@ static int geneve_configure(struct net *net, struct net_device *dev,
}
}
- dst_cache_reset(&geneve->info.dst_cache);
- geneve->info = *info;
- geneve->collect_md = metadata;
- geneve->use_udp6_rx_checksums = ipv6_rx_csum;
- geneve->ttl_inherit = ttl_inherit;
- geneve->df = df;
+ dst_cache_reset(&geneve->cfg.info.dst_cache);
+ memcpy(&geneve->cfg, cfg, sizeof(*cfg));
err = register_netdevice(dev);
if (err)
@@ -1327,10 +1373,9 @@ static void init_tnl_info(struct ip_tunnel_info *info, __u16 dst_port)
static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack,
- struct ip_tunnel_info *info, bool *metadata,
- bool *use_udp6_rx_checksums, bool *ttl_inherit,
- enum ifla_geneve_df *df, bool changelink)
+ struct geneve_config *cfg, bool changelink)
{
+ struct ip_tunnel_info *info = &cfg->info;
int attrtype;
if (data[IFLA_GENEVE_REMOTE] && data[IFLA_GENEVE_REMOTE6]) {
@@ -1378,7 +1423,7 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
return -EINVAL;
}
info->key.tun_flags |= TUNNEL_CSUM;
- *use_udp6_rx_checksums = true;
+ cfg->use_udp6_rx_checksums = true;
#else
NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_REMOTE6],
"IPv6 support not enabled in the kernel");
@@ -1406,19 +1451,19 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
if (data[IFLA_GENEVE_TTL_INHERIT]) {
if (nla_get_u8(data[IFLA_GENEVE_TTL_INHERIT]))
- *ttl_inherit = true;
+ cfg->ttl_inherit = true;
else
- *ttl_inherit = false;
+ cfg->ttl_inherit = false;
} else if (data[IFLA_GENEVE_TTL]) {
info->key.ttl = nla_get_u8(data[IFLA_GENEVE_TTL]);
- *ttl_inherit = false;
+ cfg->ttl_inherit = false;
}
if (data[IFLA_GENEVE_TOS])
info->key.tos = nla_get_u8(data[IFLA_GENEVE_TOS]);
if (data[IFLA_GENEVE_DF])
- *df = nla_get_u8(data[IFLA_GENEVE_DF]);
+ cfg->df = nla_get_u8(data[IFLA_GENEVE_DF]);
if (data[IFLA_GENEVE_LABEL]) {
info->key.label = nla_get_be32(data[IFLA_GENEVE_LABEL]) &
@@ -1443,7 +1488,7 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
attrtype = IFLA_GENEVE_COLLECT_METADATA;
goto change_notsup;
}
- *metadata = true;
+ cfg->collect_md = true;
}
if (data[IFLA_GENEVE_UDP_CSUM]) {
@@ -1477,7 +1522,7 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
goto change_notsup;
}
if (nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]))
- *use_udp6_rx_checksums = false;
+ cfg->use_udp6_rx_checksums = false;
#else
NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX],
"IPv6 support not enabled in the kernel");
@@ -1542,25 +1587,24 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
- enum ifla_geneve_df df = GENEVE_DF_UNSET;
- bool use_udp6_rx_checksums = false;
- struct ip_tunnel_info info;
- bool ttl_inherit = false;
- bool metadata = false;
+ struct geneve_config cfg = {
+ .df = GENEVE_DF_UNSET,
+ .use_udp6_rx_checksums = false,
+ .ttl_inherit = false,
+ .collect_md = false,
+ };
int err;
- init_tnl_info(&info, GENEVE_UDP_PORT);
- err = geneve_nl2info(tb, data, extack, &info, &metadata,
- &use_udp6_rx_checksums, &ttl_inherit, &df, false);
+ init_tnl_info(&cfg.info, GENEVE_UDP_PORT);
+ err = geneve_nl2info(tb, data, extack, &cfg, false);
if (err)
return err;
- err = geneve_configure(net, dev, extack, &info, metadata,
- use_udp6_rx_checksums, ttl_inherit, df);
+ err = geneve_configure(net, dev, extack, &cfg);
if (err)
return err;
- geneve_link_config(dev, &info, tb);
+ geneve_link_config(dev, &cfg.info, tb);
return 0;
}
@@ -1615,41 +1659,29 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
struct netlink_ext_ack *extack)
{
struct geneve_dev *geneve = netdev_priv(dev);
- enum ifla_geneve_df df = geneve->df;
struct geneve_sock *gs4, *gs6;
- struct ip_tunnel_info info;
- bool metadata;
- bool use_udp6_rx_checksums;
- bool ttl_inherit;
+ struct geneve_config cfg;
int err;
/* If the geneve device is configured for metadata (or externally
* controlled, for example, OVS), then nothing can be changed.
*/
- if (geneve->collect_md)
+ if (geneve->cfg.collect_md)
return -EOPNOTSUPP;
/* Start with the existing info. */
- memcpy(&info, &geneve->info, sizeof(info));
- metadata = geneve->collect_md;
- use_udp6_rx_checksums = geneve->use_udp6_rx_checksums;
- ttl_inherit = geneve->ttl_inherit;
- err = geneve_nl2info(tb, data, extack, &info, &metadata,
- &use_udp6_rx_checksums, &ttl_inherit, &df, true);
+ memcpy(&cfg, &geneve->cfg, sizeof(cfg));
+ err = geneve_nl2info(tb, data, extack, &cfg, true);
if (err)
return err;
- if (!geneve_dst_addr_equal(&geneve->info, &info)) {
- dst_cache_reset(&info.dst_cache);
- geneve_link_config(dev, &info, tb);
+ if (!geneve_dst_addr_equal(&geneve->cfg.info, &cfg.info)) {
+ dst_cache_reset(&cfg.info.dst_cache);
+ geneve_link_config(dev, &cfg.info, tb);
}
geneve_quiesce(geneve, &gs4, &gs6);
- geneve->info = info;
- geneve->collect_md = metadata;
- geneve->use_udp6_rx_checksums = use_udp6_rx_checksums;
- geneve->ttl_inherit = ttl_inherit;
- geneve->df = df;
+ memcpy(&geneve->cfg, &cfg, sizeof(cfg));
geneve_unquiesce(geneve, gs4, gs6);
return 0;
@@ -1683,9 +1715,9 @@ static size_t geneve_get_size(const struct net_device *dev)
static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
struct geneve_dev *geneve = netdev_priv(dev);
- struct ip_tunnel_info *info = &geneve->info;
- bool ttl_inherit = geneve->ttl_inherit;
- bool metadata = geneve->collect_md;
+ struct ip_tunnel_info *info = &geneve->cfg.info;
+ bool ttl_inherit = geneve->cfg.ttl_inherit;
+ bool metadata = geneve->cfg.collect_md;
__u8 tmp_vni[3];
__u32 vni;
@@ -1718,7 +1750,7 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
nla_put_be32(skb, IFLA_GENEVE_LABEL, info->key.label))
goto nla_put_failure;
- if (nla_put_u8(skb, IFLA_GENEVE_DF, geneve->df))
+ if (nla_put_u8(skb, IFLA_GENEVE_DF, geneve->cfg.df))
goto nla_put_failure;
if (nla_put_be16(skb, IFLA_GENEVE_PORT, info->key.tp_dst))
@@ -1729,7 +1761,7 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
#if IS_ENABLED(CONFIG_IPV6)
if (nla_put_u8(skb, IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
- !geneve->use_udp6_rx_checksums))
+ !geneve->cfg.use_udp6_rx_checksums))
goto nla_put_failure;
#endif
@@ -1760,10 +1792,15 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
u8 name_assign_type, u16 dst_port)
{
struct nlattr *tb[IFLA_MAX + 1];
- struct ip_tunnel_info info;
struct net_device *dev;
LIST_HEAD(list_kill);
int err;
+ struct geneve_config cfg = {
+ .df = GENEVE_DF_UNSET,
+ .use_udp6_rx_checksums = true,
+ .ttl_inherit = false,
+ .collect_md = true,
+ };
memset(tb, 0, sizeof(tb));
dev = rtnl_create_link(net, name, name_assign_type,
@@ -1771,9 +1808,8 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
if (IS_ERR(dev))
return dev;
- init_tnl_info(&info, dst_port);
- err = geneve_configure(net, dev, NULL, &info,
- true, true, false, GENEVE_DF_UNSET);
+ init_tnl_info(&cfg.info, dst_port);
+ err = geneve_configure(net, dev, NULL, &cfg);
if (err) {
free_netdev(dev);
return ERR_PTR(err);
@@ -1807,9 +1843,11 @@ static int geneve_netdevice_event(struct notifier_block *unused,
event == NETDEV_UDP_TUNNEL_DROP_INFO) {
geneve_offload_rx_ports(dev, event == NETDEV_UDP_TUNNEL_PUSH_INFO);
} else if (event == NETDEV_UNREGISTER) {
- geneve_offload_rx_ports(dev, false);
+ if (!dev->udp_tunnel_nic_info)
+ geneve_offload_rx_ports(dev, false);
} else if (event == NETDEV_REGISTER) {
- geneve_offload_rx_ports(dev, true);
+ if (!dev->udp_tunnel_nic_info)
+ geneve_offload_rx_ports(dev, true);
}
return NOTIFY_DONE;
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index 70f754abbeca..f4843f9672c1 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -84,8 +84,9 @@ config SCC
help
These cards are used to connect your Linux box to an amateur radio
in order to communicate with other computers. If you want to use
- this, read <file:Documentation/networking/z8530drv.rst> and the
- AX25-HOWTO, available from
+ this, read
+ <file:Documentation/networking/device_drivers/hamradio/z8530drv.rst>
+ and the AX25-HOWTO, available from
<http://www.tldp.org/docs.html#howto>. Also make sure to say Y
to "Amateur Radio AX.25 Level 2" support.
@@ -98,7 +99,8 @@ config SCC_DELAY
help
Say Y here if you experience problems with the SCC driver not
working properly; please read
- <file:Documentation/networking/z8530drv.rst> for details.
+ <file:Documentation/networking/device_drivers/hamradio/z8530drv.rst>
+ for details.
If unsure, say N.
@@ -127,7 +129,7 @@ config BAYCOM_SER_FDX
your serial interface chip. To configure the driver, use the sethdlc
utility available in the standard ax25 utilities package. For
information on the modems, see <http://www.baycom.de/> and
- <file:Documentation/networking/baycom.rst>.
+ <file:Documentation/networking/device_drivers/hamradio/baycom.rst>.
To compile this driver as a module, choose M here: the module
will be called baycom_ser_fdx. This is recommended.
@@ -145,7 +147,7 @@ config BAYCOM_SER_HDX
the driver, use the sethdlc utility available in the standard ax25
utilities package. For information on the modems, see
<http://www.baycom.de/> and
- <file:Documentation/networking/baycom.rst>.
+ <file:Documentation/networking/device_drivers/hamradio/baycom.rst>.
To compile this driver as a module, choose M here: the module
will be called baycom_ser_hdx. This is recommended.
@@ -160,7 +162,7 @@ config BAYCOM_PAR
par96 designs. To configure the driver, use the sethdlc utility
available in the standard ax25 utilities package. For information on
the modems, see <http://www.baycom.de/> and the file
- <file:Documentation/networking/baycom.rst>.
+ <file:Documentation/networking/device_drivers/hamradio/baycom.rst>.
To compile this driver as a module, choose M here: the module
will be called baycom_par. This is recommended.
@@ -175,7 +177,7 @@ config BAYCOM_EPP
designs. To configure the driver, use the sethdlc utility available
in the standard ax25 utilities package. For information on the
modems, see <http://www.baycom.de/> and the file
- <file:Documentation/networking/baycom.rst>.
+ <file:Documentation/networking/device_drivers/hamradio/baycom.rst>.
To compile this driver as a module, choose M here: the module
will be called baycom_epp. This is recommended.
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 33fdd55c6122..1e915871baa7 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -7,7 +7,7 @@
* ------------------
*
* You can find a subset of the documentation in
- * Documentation/networking/z8530drv.rst.
+ * Documentation/networking/device_drivers/wan/z8530drv.rst.
*/
/*
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index abda736e7c7d..2181d4538ab7 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -897,6 +897,7 @@ struct netvsc_ethtool_stats {
unsigned long rx_no_memory;
unsigned long stop_queue;
unsigned long wake_queue;
+ unsigned long vlan_error;
};
struct netvsc_ethtool_pcpu_stats {
diff --git a/drivers/net/hyperv/netvsc_bpf.c b/drivers/net/hyperv/netvsc_bpf.c
index 8e4141552423..440486d9c999 100644
--- a/drivers/net/hyperv/netvsc_bpf.c
+++ b/drivers/net/hyperv/netvsc_bpf.c
@@ -163,16 +163,6 @@ int netvsc_vf_setxdp(struct net_device *vf_netdev, struct bpf_prog *prog)
return ret;
}
-static u32 netvsc_xdp_query(struct netvsc_device *nvdev)
-{
- struct bpf_prog *prog = netvsc_xdp_get(nvdev);
-
- if (prog)
- return prog->aux->id;
-
- return 0;
-}
-
int netvsc_bpf(struct net_device *dev, struct netdev_bpf *bpf)
{
struct net_device_context *ndevctx = netdev_priv(dev);
@@ -182,12 +172,7 @@ int netvsc_bpf(struct net_device *dev, struct netdev_bpf *bpf)
int ret;
if (!nvdev || nvdev->destroy) {
- if (bpf->command == XDP_QUERY_PROG) {
- bpf->prog_id = 0;
- return 0; /* Query must always succeed */
- } else {
- return -ENODEV;
- }
+ return -ENODEV;
}
switch (bpf->command) {
@@ -208,10 +193,6 @@ int netvsc_bpf(struct net_device *dev, struct netdev_bpf *bpf)
return ret;
- case XDP_QUERY_PROG:
- bpf->prog_id = netvsc_xdp_query(nvdev);
- return 0;
-
default:
return -EINVAL;
}
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 6267f706e8ee..787f17e2a971 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -532,12 +532,13 @@ static int netvsc_xmit(struct sk_buff *skb, struct net_device *net, bool xdp_tx)
u32 hash;
struct hv_page_buffer pb[MAX_PAGE_BUFFER_COUNT];
- /* if VF is present and up then redirect packets
- * already called with rcu_read_lock_bh
+ /* If VF is present and up then redirect packets to it.
+ * Skip the VF if it is marked down or has no carrier.
+ * If netpoll is in uses, then VF can not be used either.
*/
vf_netdev = rcu_dereference_bh(net_device_ctx->vf_netdev);
if (vf_netdev && netif_running(vf_netdev) &&
- !netpoll_tx_running(net))
+ netif_carrier_ok(vf_netdev) && !netpoll_tx_running(net))
return netvsc_vf_xmit(net, vf_netdev, skb);
/* We will atmost need two pages to describe the rndis
@@ -605,6 +606,29 @@ static int netvsc_xmit(struct sk_buff *skb, struct net_device *net, bool xdp_tx)
*hash_info = hash;
}
+ /* When using AF_PACKET we need to drop VLAN header from
+ * the frame and update the SKB to allow the HOST OS
+ * to transmit the 802.1Q packet
+ */
+ if (skb->protocol == htons(ETH_P_8021Q)) {
+ u16 vlan_tci;
+
+ skb_reset_mac_header(skb);
+ if (eth_type_vlan(eth_hdr(skb)->h_proto)) {
+ if (unlikely(__skb_vlan_pop(skb, &vlan_tci) != 0)) {
+ ++net_device_ctx->eth_stats.vlan_error;
+ goto drop;
+ }
+
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci);
+ /* Update the NDIS header pkt lengths */
+ packet->total_data_buflen -= VLAN_HLEN;
+ packet->total_bytes -= VLAN_HLEN;
+ rndis_msg->msg_len = packet->total_data_buflen;
+ rndis_msg->msg.pkt.data_len = packet->total_data_buflen;
+ }
+ }
+
if (skb_vlan_tag_present(skb)) {
struct ndis_pkt_8021q_info *vlan;
@@ -1427,6 +1451,7 @@ static const struct {
{ "rx_no_memory", offsetof(struct netvsc_ethtool_stats, rx_no_memory) },
{ "stop_queue", offsetof(struct netvsc_ethtool_stats, stop_queue) },
{ "wake_queue", offsetof(struct netvsc_ethtool_stats, wake_queue) },
+ { "vlan_error", offsetof(struct netvsc_ethtool_stats, vlan_error) },
}, pcpu_stats[] = {
{ "cpu%u_rx_packets",
offsetof(struct netvsc_ethtool_pcpu_stats, rx_packets) },
@@ -1934,6 +1959,23 @@ syncvf:
return ret;
}
+static int netvsc_get_regs_len(struct net_device *netdev)
+{
+ return VRSS_SEND_TAB_SIZE * sizeof(u32);
+}
+
+static void netvsc_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct net_device_context *ndc = netdev_priv(netdev);
+ u32 *regs_buff = p;
+
+ /* increase the version, if buffer format is changed. */
+ regs->version = 1;
+
+ memcpy(regs_buff, ndc->tx_table, VRSS_SEND_TAB_SIZE * sizeof(u32));
+}
+
static u32 netvsc_get_msglevel(struct net_device *ndev)
{
struct net_device_context *ndev_ctx = netdev_priv(ndev);
@@ -1950,6 +1992,8 @@ static void netvsc_set_msglevel(struct net_device *ndev, u32 val)
static const struct ethtool_ops ethtool_ops = {
.get_drvinfo = netvsc_get_drvinfo,
+ .get_regs_len = netvsc_get_regs_len,
+ .get_regs = netvsc_get_regs,
.get_msglevel = netvsc_get_msglevel,
.set_msglevel = netvsc_set_msglevel,
.get_link = ethtool_op_get_link,
diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index ac7e5a04c8ac..0e63d35320aa 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -336,6 +336,7 @@ static int evt_ring_command(struct gsi *gsi, u32 evt_ring_id,
{
struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id];
struct completion *completion = &evt_ring->completion;
+ struct device *dev = gsi->dev;
u32 val;
val = u32_encode_bits(evt_ring_id, EV_CHID_FMASK);
@@ -344,8 +345,8 @@ static int evt_ring_command(struct gsi *gsi, u32 evt_ring_id,
if (gsi_command(gsi, GSI_EV_CH_CMD_OFFSET, val, completion))
return 0; /* Success! */
- dev_err(gsi->dev, "GSI command %u to event ring %u timed out "
- "(state is %u)\n", opcode, evt_ring_id, evt_ring->state);
+ dev_err(dev, "GSI command %u for event ring %u timed out, state %u\n",
+ opcode, evt_ring_id, evt_ring->state);
return -ETIMEDOUT;
}
@@ -358,13 +359,15 @@ static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id)
/* Get initial event ring state */
evt_ring->state = gsi_evt_ring_state(gsi, evt_ring_id);
-
- if (evt_ring->state != GSI_EVT_RING_STATE_NOT_ALLOCATED)
+ if (evt_ring->state != GSI_EVT_RING_STATE_NOT_ALLOCATED) {
+ dev_err(gsi->dev, "bad event ring state %u before alloc\n",
+ evt_ring->state);
return -EINVAL;
+ }
ret = evt_ring_command(gsi, evt_ring_id, GSI_EVT_ALLOCATE);
if (!ret && evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED) {
- dev_err(gsi->dev, "bad event ring state (%u) after alloc\n",
+ dev_err(gsi->dev, "bad event ring state %u after alloc\n",
evt_ring->state);
ret = -EIO;
}
@@ -381,14 +384,14 @@ static void gsi_evt_ring_reset_command(struct gsi *gsi, u32 evt_ring_id)
if (state != GSI_EVT_RING_STATE_ALLOCATED &&
state != GSI_EVT_RING_STATE_ERROR) {
- dev_err(gsi->dev, "bad event ring state (%u) before reset\n",
+ dev_err(gsi->dev, "bad event ring state %u before reset\n",
evt_ring->state);
return;
}
ret = evt_ring_command(gsi, evt_ring_id, GSI_EVT_RESET);
if (!ret && evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED)
- dev_err(gsi->dev, "bad event ring state (%u) after reset\n",
+ dev_err(gsi->dev, "bad event ring state %u after reset\n",
evt_ring->state);
}
@@ -399,14 +402,14 @@ static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id)
int ret;
if (evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED) {
- dev_err(gsi->dev, "bad event ring state (%u) before dealloc\n",
+ dev_err(gsi->dev, "bad event ring state %u before dealloc\n",
evt_ring->state);
return;
}
ret = evt_ring_command(gsi, evt_ring_id, GSI_EVT_DE_ALLOC);
if (!ret && evt_ring->state != GSI_EVT_RING_STATE_NOT_ALLOCATED)
- dev_err(gsi->dev, "bad event ring state (%u) after dealloc\n",
+ dev_err(gsi->dev, "bad event ring state %u after dealloc\n",
evt_ring->state);
}
@@ -429,6 +432,7 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode)
struct completion *completion = &channel->completion;
u32 channel_id = gsi_channel_id(channel);
struct gsi *gsi = channel->gsi;
+ struct device *dev = gsi->dev;
u32 val;
val = u32_encode_bits(channel_id, CH_CHID_FMASK);
@@ -437,8 +441,7 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode)
if (gsi_command(gsi, GSI_CH_CMD_OFFSET, val, completion))
return 0; /* Success! */
- dev_err(gsi->dev,
- "GSI command %u to channel %u timed out (state is %u)\n",
+ dev_err(dev, "GSI command %u for channel %u timed out, state %u\n",
opcode, channel_id, gsi_channel_state(channel));
return -ETIMEDOUT;
@@ -448,21 +451,23 @@ gsi_channel_command(struct gsi_channel *channel, enum gsi_ch_cmd_opcode opcode)
static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id)
{
struct gsi_channel *channel = &gsi->channel[channel_id];
+ struct device *dev = gsi->dev;
enum gsi_channel_state state;
int ret;
/* Get initial channel state */
state = gsi_channel_state(channel);
- if (state != GSI_CHANNEL_STATE_NOT_ALLOCATED)
+ if (state != GSI_CHANNEL_STATE_NOT_ALLOCATED) {
+ dev_err(dev, "bad channel state %u before alloc\n", state);
return -EINVAL;
+ }
ret = gsi_channel_command(channel, GSI_CH_ALLOCATE);
/* Channel state will normally have been updated */
state = gsi_channel_state(channel);
if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED) {
- dev_err(gsi->dev, "bad channel state (%u) after alloc\n",
- state);
+ dev_err(dev, "bad channel state %u after alloc\n", state);
ret = -EIO;
}
@@ -472,21 +477,23 @@ static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id)
/* Start an ALLOCATED channel */
static int gsi_channel_start_command(struct gsi_channel *channel)
{
+ struct device *dev = channel->gsi->dev;
enum gsi_channel_state state;
int ret;
state = gsi_channel_state(channel);
if (state != GSI_CHANNEL_STATE_ALLOCATED &&
- state != GSI_CHANNEL_STATE_STOPPED)
+ state != GSI_CHANNEL_STATE_STOPPED) {
+ dev_err(dev, "bad channel state %u before start\n", state);
return -EINVAL;
+ }
ret = gsi_channel_command(channel, GSI_CH_START);
/* Channel state will normally have been updated */
state = gsi_channel_state(channel);
if (!ret && state != GSI_CHANNEL_STATE_STARTED) {
- dev_err(channel->gsi->dev,
- "bad channel state (%u) after start\n", state);
+ dev_err(dev, "bad channel state %u after start\n", state);
ret = -EIO;
}
@@ -496,6 +503,7 @@ static int gsi_channel_start_command(struct gsi_channel *channel)
/* Stop a GSI channel in STARTED state */
static int gsi_channel_stop_command(struct gsi_channel *channel)
{
+ struct device *dev = channel->gsi->dev;
enum gsi_channel_state state;
int ret;
@@ -508,8 +516,10 @@ static int gsi_channel_stop_command(struct gsi_channel *channel)
return 0;
if (state != GSI_CHANNEL_STATE_STARTED &&
- state != GSI_CHANNEL_STATE_STOP_IN_PROC)
+ state != GSI_CHANNEL_STATE_STOP_IN_PROC) {
+ dev_err(dev, "bad channel state %u before stop\n", state);
return -EINVAL;
+ }
ret = gsi_channel_command(channel, GSI_CH_STOP);
@@ -522,8 +532,7 @@ static int gsi_channel_stop_command(struct gsi_channel *channel)
if (state == GSI_CHANNEL_STATE_STOP_IN_PROC)
return -EAGAIN;
- dev_err(channel->gsi->dev,
- "bad channel state (%u) after stop\n", state);
+ dev_err(dev, "bad channel state %u after stop\n", state);
return -EIO;
}
@@ -531,6 +540,7 @@ static int gsi_channel_stop_command(struct gsi_channel *channel)
/* Reset a GSI channel in ALLOCATED or ERROR state. */
static void gsi_channel_reset_command(struct gsi_channel *channel)
{
+ struct device *dev = channel->gsi->dev;
enum gsi_channel_state state;
int ret;
@@ -539,8 +549,7 @@ static void gsi_channel_reset_command(struct gsi_channel *channel)
state = gsi_channel_state(channel);
if (state != GSI_CHANNEL_STATE_STOPPED &&
state != GSI_CHANNEL_STATE_ERROR) {
- dev_err(channel->gsi->dev,
- "bad channel state (%u) before reset\n", state);
+ dev_err(dev, "bad channel state %u before reset\n", state);
return;
}
@@ -549,21 +558,20 @@ static void gsi_channel_reset_command(struct gsi_channel *channel)
/* Channel state will normally have been updated */
state = gsi_channel_state(channel);
if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED)
- dev_err(channel->gsi->dev,
- "bad channel state (%u) after reset\n", state);
+ dev_err(dev, "bad channel state %u after reset\n", state);
}
/* Deallocate an ALLOCATED GSI channel */
static void gsi_channel_de_alloc_command(struct gsi *gsi, u32 channel_id)
{
struct gsi_channel *channel = &gsi->channel[channel_id];
+ struct device *dev = gsi->dev;
enum gsi_channel_state state;
int ret;
state = gsi_channel_state(channel);
if (state != GSI_CHANNEL_STATE_ALLOCATED) {
- dev_err(gsi->dev,
- "bad channel state (%u) before dealloc\n", state);
+ dev_err(dev, "bad channel state %u before dealloc\n", state);
return;
}
@@ -572,8 +580,7 @@ static void gsi_channel_de_alloc_command(struct gsi *gsi, u32 channel_id)
/* Channel state will normally have been updated */
state = gsi_channel_state(channel);
if (!ret && state != GSI_CHANNEL_STATE_NOT_ALLOCATED)
- dev_err(gsi->dev,
- "bad channel state (%u) after dealloc\n", state);
+ dev_err(dev, "bad channel state %u after dealloc\n", state);
}
/* Ring an event ring doorbell, reporting the last entry processed by the AP.
@@ -1146,8 +1153,8 @@ static irqreturn_t gsi_isr(int irq, void *dev_id)
break;
default:
dev_err(gsi->dev,
- "%s: unrecognized type 0x%08x\n",
- __func__, gsi_intr);
+ "unrecognized interrupt type 0x%08x\n",
+ gsi_intr);
break;
}
} while (intr_mask);
@@ -1251,7 +1258,7 @@ static int gsi_ring_alloc(struct gsi *gsi, struct gsi_ring *ring, u32 count)
if (ring->virt && addr % size) {
dma_free_coherent(dev, size, ring->virt, ring->addr);
dev_err(dev, "unable to alloc 0x%zx-aligned ring buffer\n",
- size);
+ size);
return -EINVAL; /* Not a good error value, but distinct */
} else if (!ring->virt) {
return -ENOMEM;
@@ -1356,7 +1363,7 @@ static void gsi_channel_update(struct gsi_channel *channel)
* gsi_channel_poll_one() - Return a single completed transaction on a channel
* @channel: Channel to be polled
*
- * @Return: Transaction pointer, or null if none are available
+ * Return: Transaction pointer, or null if none are available
*
* This function returns the first entry on a channel's completed transaction
* list. If that list is empty, the hardware is consulted to determine
@@ -1386,8 +1393,8 @@ static struct gsi_trans *gsi_channel_poll_one(struct gsi_channel *channel)
* gsi_channel_poll() - NAPI poll function for a channel
* @napi: NAPI structure for the channel
* @budget: Budget supplied by NAPI core
-
- * @Return: Number of items polled (<= budget)
+ *
+ * Return: Number of items polled (<= budget)
*
* Single transactions completed by hardware are polled until either
* the budget is exhausted, or there are no more. Each transaction
@@ -1642,12 +1649,13 @@ static void gsi_channel_teardown(struct gsi *gsi)
/* Setup function for GSI. GSI firmware must be loaded and initialized */
int gsi_setup(struct gsi *gsi, bool legacy)
{
+ struct device *dev = gsi->dev;
u32 val;
/* Here is where we first touch the GSI hardware */
val = ioread32(gsi->virt + GSI_GSI_STATUS_OFFSET);
if (!(val & ENABLED_FMASK)) {
- dev_err(gsi->dev, "GSI has not been enabled\n");
+ dev_err(dev, "GSI has not been enabled\n");
return -EIO;
}
@@ -1655,24 +1663,24 @@ int gsi_setup(struct gsi *gsi, bool legacy)
gsi->channel_count = u32_get_bits(val, NUM_CH_PER_EE_FMASK);
if (!gsi->channel_count) {
- dev_err(gsi->dev, "GSI reports zero channels supported\n");
+ dev_err(dev, "GSI reports zero channels supported\n");
return -EINVAL;
}
if (gsi->channel_count > GSI_CHANNEL_COUNT_MAX) {
- dev_warn(gsi->dev,
- "limiting to %u channels (hardware supports %u)\n",
+ dev_warn(dev,
+ "limiting to %u channels; hardware supports %u\n",
GSI_CHANNEL_COUNT_MAX, gsi->channel_count);
gsi->channel_count = GSI_CHANNEL_COUNT_MAX;
}
gsi->evt_ring_count = u32_get_bits(val, NUM_EV_PER_EE_FMASK);
if (!gsi->evt_ring_count) {
- dev_err(gsi->dev, "GSI reports zero event rings supported\n");
+ dev_err(dev, "GSI reports zero event rings supported\n");
return -EINVAL;
}
if (gsi->evt_ring_count > GSI_EVT_RING_COUNT_MAX) {
- dev_warn(gsi->dev,
- "limiting to %u event rings (hardware supports %u)\n",
+ dev_warn(dev,
+ "limiting to %u event rings; hardware supports %u\n",
GSI_EVT_RING_COUNT_MAX, gsi->evt_ring_count);
gsi->evt_ring_count = GSI_EVT_RING_COUNT_MAX;
}
@@ -1758,19 +1766,19 @@ static bool gsi_channel_data_valid(struct gsi *gsi,
/* Make sure channel ids are in the range driver supports */
if (channel_id >= GSI_CHANNEL_COUNT_MAX) {
- dev_err(dev, "bad channel id %u (must be less than %u)\n",
+ dev_err(dev, "bad channel id %u; must be less than %u\n",
channel_id, GSI_CHANNEL_COUNT_MAX);
return false;
}
if (data->ee_id != GSI_EE_AP && data->ee_id != GSI_EE_MODEM) {
- dev_err(dev, "bad EE id %u (AP or modem)\n", data->ee_id);
+ dev_err(dev, "bad EE id %u; not AP or modem\n", data->ee_id);
return false;
}
if (!data->channel.tlv_count ||
data->channel.tlv_count > GSI_TLV_MAX) {
- dev_err(dev, "channel %u bad tlv_count %u (must be 1..%u)\n",
+ dev_err(dev, "channel %u bad tlv_count %u; must be 1..%u\n",
channel_id, data->channel.tlv_count, GSI_TLV_MAX);
return false;
}
@@ -1788,13 +1796,13 @@ static bool gsi_channel_data_valid(struct gsi *gsi,
}
if (!is_power_of_2(data->channel.tre_count)) {
- dev_err(dev, "channel %u bad tre_count %u (not power of 2)\n",
+ dev_err(dev, "channel %u bad tre_count %u; not power of 2\n",
channel_id, data->channel.tre_count);
return false;
}
if (!is_power_of_2(data->channel.event_count)) {
- dev_err(dev, "channel %u bad event_count %u (not power of 2)\n",
+ dev_err(dev, "channel %u bad event_count %u; not power of 2\n",
channel_id, data->channel.event_count);
return false;
}
@@ -1948,6 +1956,7 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev, bool prefetch,
u32 count, const struct ipa_gsi_endpoint_data *data,
bool modem_alloc)
{
+ struct device *dev = &pdev->dev;
struct resource *res;
resource_size_t size;
unsigned int irq;
@@ -1955,7 +1964,7 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev, bool prefetch,
gsi_validate_build();
- gsi->dev = &pdev->dev;
+ gsi->dev = dev;
/* The GSI layer performs NAPI on all endpoints. NAPI requires a
* network device structure, but the GSI layer does not have one,
@@ -1966,43 +1975,41 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev, bool prefetch,
/* Get the GSI IRQ and request for it to wake the system */
ret = platform_get_irq_byname(pdev, "gsi");
if (ret <= 0) {
- dev_err(gsi->dev,
- "DT error %d getting \"gsi\" IRQ property\n", ret);
+ dev_err(dev, "DT error %d getting \"gsi\" IRQ property\n", ret);
return ret ? : -EINVAL;
}
irq = ret;
ret = request_irq(irq, gsi_isr, 0, "gsi", gsi);
if (ret) {
- dev_err(gsi->dev, "error %d requesting \"gsi\" IRQ\n", ret);
+ dev_err(dev, "error %d requesting \"gsi\" IRQ\n", ret);
return ret;
}
gsi->irq = irq;
ret = enable_irq_wake(gsi->irq);
if (ret)
- dev_warn(gsi->dev, "error %d enabling gsi wake irq\n", ret);
+ dev_warn(dev, "error %d enabling gsi wake irq\n", ret);
gsi->irq_wake_enabled = !ret;
/* Get GSI memory range and map it */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsi");
if (!res) {
- dev_err(gsi->dev,
- "DT error getting \"gsi\" memory property\n");
+ dev_err(dev, "DT error getting \"gsi\" memory property\n");
ret = -ENODEV;
goto err_disable_irq_wake;
}
size = resource_size(res);
if (res->start > U32_MAX || size > U32_MAX - res->start) {
- dev_err(gsi->dev, "DT memory resource \"gsi\" out of range\n");
+ dev_err(dev, "DT memory resource \"gsi\" out of range\n");
ret = -EINVAL;
goto err_disable_irq_wake;
}
gsi->virt = ioremap(res->start, size);
if (!gsi->virt) {
- dev_err(gsi->dev, "unable to remap \"gsi\" memory\n");
+ dev_err(dev, "unable to remap \"gsi\" memory\n");
ret = -ENOMEM;
goto err_disable_irq_wake;
}
diff --git a/drivers/net/ipa/gsi.h b/drivers/net/ipa/gsi.h
index 90a02194e7ad..061312773df0 100644
--- a/drivers/net/ipa/gsi.h
+++ b/drivers/net/ipa/gsi.h
@@ -167,7 +167,7 @@ struct gsi {
* @gsi: Address of GSI structure embedded in an IPA structure
* @legacy: Set up for legacy hardware
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*
* Performs initialization that must wait until the GSI hardware is
* ready (including firmware loaded).
@@ -185,7 +185,7 @@ void gsi_teardown(struct gsi *gsi);
* @gsi: GSI pointer
* @channel_id: Channel whose limit is to be returned
*
- * @Return: The maximum number of TREs oustanding on the channel
+ * Return: The maximum number of TREs oustanding on the channel
*/
u32 gsi_channel_tre_max(struct gsi *gsi, u32 channel_id);
@@ -194,7 +194,7 @@ u32 gsi_channel_tre_max(struct gsi *gsi, u32 channel_id);
* @gsi: GSI pointer
* @channel_id: Channel whose limit is to be returned
*
- * @Return: The maximum TRE count per transaction on the channel
+ * Return: The maximum TRE count per transaction on the channel
*/
u32 gsi_channel_trans_tre_max(struct gsi *gsi, u32 channel_id);
@@ -203,7 +203,7 @@ u32 gsi_channel_trans_tre_max(struct gsi *gsi, u32 channel_id);
* @gsi: GSI pointer
* @channel_id: Channel to start
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*/
int gsi_channel_start(struct gsi *gsi, u32 channel_id);
@@ -212,7 +212,7 @@ int gsi_channel_start(struct gsi *gsi, u32 channel_id);
* @gsi: GSI pointer returned by gsi_setup()
* @channel_id: Channel to stop
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*/
int gsi_channel_stop(struct gsi *gsi, u32 channel_id);
@@ -238,7 +238,7 @@ int gsi_channel_resume(struct gsi *gsi, u32 channel_id, bool start);
* @gsi: Address of GSI structure embedded in an IPA structure
* @pdev: IPA platform device
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*
* Early stage initialization of the GSI subsystem, performing tasks
* that can be done before the GSI hardware is ready to use.
diff --git a/drivers/net/ipa/gsi_private.h b/drivers/net/ipa/gsi_private.h
index b57d0198ebc1..1785c9d3344d 100644
--- a/drivers/net/ipa/gsi_private.h
+++ b/drivers/net/ipa/gsi_private.h
@@ -44,7 +44,7 @@ void gsi_trans_complete(struct gsi_trans *trans);
* @channel: Channel associated with the transaction
* @index: Index of the TRE having a transaction
*
- * @Return: The GSI transaction pointer associated with the TRE index
+ * Return: The GSI transaction pointer associated with the TRE index
*/
struct gsi_trans *gsi_channel_trans_mapped(struct gsi_channel *channel,
u32 index);
@@ -53,7 +53,7 @@ struct gsi_trans *gsi_channel_trans_mapped(struct gsi_channel *channel,
* gsi_channel_trans_complete() - Return a channel's next completed transaction
* @channel: Channel whose next transaction is to be returned
*
- * @Return: The next completed transaction, or NULL if nothing new
+ * Return: The next completed transaction, or NULL if nothing new
*/
struct gsi_trans *gsi_channel_trans_complete(struct gsi_channel *channel);
@@ -76,7 +76,7 @@ void gsi_channel_trans_cancel_pending(struct gsi_channel *channel);
* @gsi: GSI pointer
* @channel_id: Channel number
*
- * @Return: 0 if successful, or -ENOMEM on allocation failure
+ * Return: 0 if successful, or -ENOMEM on allocation failure
*
* Creates and sets up information for managing transactions on a channel
*/
diff --git a/drivers/net/ipa/gsi_trans.h b/drivers/net/ipa/gsi_trans.h
index 1477fc15b30a..4d4606b5fa95 100644
--- a/drivers/net/ipa/gsi_trans.h
+++ b/drivers/net/ipa/gsi_trans.h
@@ -75,7 +75,7 @@ struct gsi_trans {
* @count: Minimum number of elements in the pool
* @max_alloc: Maximum number of elements allocated at a time from pool
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*/
int gsi_trans_pool_init(struct gsi_trans_pool *pool, size_t size, u32 count,
u32 max_alloc);
@@ -85,7 +85,7 @@ int gsi_trans_pool_init(struct gsi_trans_pool *pool, size_t size, u32 count,
* @pool: Pool pointer
* @count: Number of elements to allocate from the pool
*
- * @Return: Virtual address of element(s) allocated from the pool
+ * Return: Virtual address of element(s) allocated from the pool
*/
void *gsi_trans_pool_alloc(struct gsi_trans_pool *pool, u32 count);
@@ -103,7 +103,7 @@ void gsi_trans_pool_exit(struct gsi_trans_pool *pool);
* @count: Minimum number of elements in the pool
* @max_alloc: Maximum number of elements allocated at a time from pool
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*
* Structures in this pool reside in DMA-coherent memory.
*/
@@ -115,7 +115,7 @@ int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool,
* @pool: DMA pool pointer
* @addr: DMA address "handle" associated with the allocation
*
- * @Return: Virtual address of element allocated from the pool
+ * Return: Virtual address of element allocated from the pool
*
* Only one element at a time may be allocated from a DMA pool.
*/
@@ -134,7 +134,7 @@ void gsi_trans_pool_exit_dma(struct device *dev, struct gsi_trans_pool *pool);
* @tre_count: Number of elements in the transaction
* @direction: DMA direction for entire SGL (or DMA_NONE)
*
- * @Return: A GSI transaction structure, or a null pointer if all
+ * Return: A GSI transaction structure, or a null pointer if all
* available transactions are in use
*/
struct gsi_trans *gsi_channel_trans_alloc(struct gsi *gsi, u32 channel_id,
@@ -175,7 +175,7 @@ int gsi_trans_page_add(struct gsi_trans *trans, struct page *page, u32 size,
* @trans: Transaction
* @skb: Socket buffer for transfer (outbound)
*
- * @Return: 0, or -EMSGSIZE if socket data won't fit in transaction.
+ * Return: 0, or -EMSGSIZE if socket data won't fit in transaction.
*/
int gsi_trans_skb_add(struct gsi_trans *trans, struct sk_buff *skb);
diff --git a/drivers/net/ipa/ipa_clock.c b/drivers/net/ipa/ipa_clock.c
index c5204fd58ac4..398f2e47043d 100644
--- a/drivers/net/ipa/ipa_clock.c
+++ b/drivers/net/ipa/ipa_clock.c
@@ -44,7 +44,7 @@
/**
* struct ipa_clock - IPA clocking information
* @count: Clocking reference count
- * @mutex; Protects clock enable/disable
+ * @mutex: Protects clock enable/disable
* @core: IPA core clock
* @memory_path: Memory interconnect
* @imem_path: Internal memory interconnect
@@ -256,6 +256,12 @@ void ipa_clock_put(struct ipa *ipa)
mutex_unlock(&clock->mutex);
}
+/* Return the current IPA core clock rate */
+u32 ipa_clock_rate(struct ipa *ipa)
+{
+ return ipa->clock ? (u32)clk_get_rate(ipa->clock->core) : 0;
+}
+
/* Initialize IPA clocking */
struct ipa_clock *ipa_clock_init(struct device *dev)
{
diff --git a/drivers/net/ipa/ipa_clock.h b/drivers/net/ipa/ipa_clock.h
index bc52b35e6bb2..1d70f1de3875 100644
--- a/drivers/net/ipa/ipa_clock.h
+++ b/drivers/net/ipa/ipa_clock.h
@@ -11,10 +11,18 @@ struct device;
struct ipa;
/**
+ * ipa_clock_rate() - Return the current IPA core clock rate
+ * @ipa: IPA structure
+ *
+ * Return: The current clock rate (in Hz), or 0.
+ */
+u32 ipa_clock_rate(struct ipa *ipa);
+
+/**
* ipa_clock_init() - Initialize IPA clocking
* @dev: IPA device
*
- * @Return: A pointer to an ipa_clock structure, or a pointer-coded error
+ * Return: A pointer to an ipa_clock structure, or a pointer-coded error
*/
struct ipa_clock *ipa_clock_init(struct device *dev);
diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h
index 1a646e0264a0..f7e6f87facf7 100644
--- a/drivers/net/ipa/ipa_cmd.h
+++ b/drivers/net/ipa/ipa_cmd.h
@@ -61,7 +61,7 @@ struct ipa_cmd_info {
* @ipv6: - Whether the table is for IPv6 or IPv4
* @hashed: - Whether the table is hashed or non-hashed
*
- * @Return: true if region is valid, false otherwise
+ * Return: true if region is valid, false otherwise
*/
bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem,
bool route, bool ipv6, bool hashed);
@@ -70,7 +70,7 @@ bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem,
* ipa_cmd_data_valid() - Validate command-realted configuration is valid
* @ipa: - IPA pointer
*
- * @Return: true if assumptions required for command are valid
+ * Return: true if assumptions required for command are valid
*/
bool ipa_cmd_data_valid(struct ipa *ipa);
@@ -95,7 +95,7 @@ static inline bool ipa_cmd_data_valid(struct ipa *ipa)
* @channel: AP->IPA command TX GSI channel pointer
* @tre_count: Number of pool elements to allocate
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*/
int ipa_cmd_pool_init(struct gsi_channel *gsi_channel, u32 tre_count);
@@ -166,7 +166,7 @@ void ipa_cmd_tag_process_add(struct gsi_trans *trans);
/**
* ipa_cmd_tag_process_add_count() - Number of commands in a tag process
*
- * @Return: The number of elements to allocate in a transaction
+ * Return: The number of elements to allocate in a transaction
* to hold tag process commands
*/
u32 ipa_cmd_tag_process_count(void);
@@ -184,7 +184,7 @@ void ipa_cmd_tag_process(struct ipa *ipa);
* @ipa: IPA pointer
* @tre_count: Number of elements in the transaction
*
- * @Return: A GSI transaction structure, or a null pointer if all
+ * Return: A GSI transaction structure, or a null pointer if all
* available transactions are in use
*/
struct gsi_trans *ipa_cmd_trans_alloc(struct ipa *ipa, u32 tre_count);
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index 9e58e495d373..b7efd7c95e9c 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -21,6 +21,7 @@
#include "ipa_modem.h"
#include "ipa_table.h"
#include "ipa_gsi.h"
+#include "ipa_clock.h"
#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
@@ -36,7 +37,7 @@
#define IPA_ENDPOINT_QMAP_METADATA_MASK 0x000000ff /* host byte order */
#define IPA_ENDPOINT_RESET_AGGR_RETRY_MAX 3
-#define IPA_AGGR_TIME_LIMIT_DEFAULT 1000 /* microseconds */
+#define IPA_AGGR_TIME_LIMIT_DEFAULT 500 /* microseconds */
/** enum ipa_status_opcode - status element opcode hardware values */
enum ipa_status_opcode {
@@ -318,41 +319,102 @@ ipa_endpoint_program_delay(struct ipa_endpoint *endpoint, bool enable)
{
/* assert(endpoint->toward_ipa); */
- (void)ipa_endpoint_init_ctrl(endpoint, enable);
+ /* Delay mode doesn't work properly for IPA v4.2 */
+ if (endpoint->ipa->version != IPA_VERSION_4_2)
+ (void)ipa_endpoint_init_ctrl(endpoint, enable);
}
-/* Returns previous suspend state (true means it was enabled) */
+static bool ipa_endpoint_aggr_active(struct ipa_endpoint *endpoint)
+{
+ u32 mask = BIT(endpoint->endpoint_id);
+ struct ipa *ipa = endpoint->ipa;
+ u32 offset;
+ u32 val;
+
+ /* assert(mask & ipa->available); */
+ offset = ipa_reg_state_aggr_active_offset(ipa->version);
+ val = ioread32(ipa->reg_virt + offset);
+
+ return !!(val & mask);
+}
+
+static void ipa_endpoint_force_close(struct ipa_endpoint *endpoint)
+{
+ u32 mask = BIT(endpoint->endpoint_id);
+ struct ipa *ipa = endpoint->ipa;
+
+ /* assert(mask & ipa->available); */
+ iowrite32(mask, ipa->reg_virt + IPA_REG_AGGR_FORCE_CLOSE_OFFSET);
+}
+
+/**
+ * ipa_endpoint_suspend_aggr() - Emulate suspend interrupt
+ * @endpoint: Endpoint on which to emulate a suspend
+ *
+ * Emulate suspend IPA interrupt to unsuspend an endpoint suspended
+ * with an open aggregation frame. This is to work around a hardware
+ * issue in IPA version 3.5.1 where the suspend interrupt will not be
+ * generated when it should be.
+ */
+static void ipa_endpoint_suspend_aggr(struct ipa_endpoint *endpoint)
+{
+ struct ipa *ipa = endpoint->ipa;
+
+ if (!endpoint->data->aggregation)
+ return;
+
+ /* Nothing to do if the endpoint doesn't have aggregation open */
+ if (!ipa_endpoint_aggr_active(endpoint))
+ return;
+
+ /* Force close aggregation */
+ ipa_endpoint_force_close(endpoint);
+
+ ipa_interrupt_simulate_suspend(ipa->interrupt);
+}
+
+/* Returns previous suspend state (true means suspend was enabled) */
static bool
ipa_endpoint_program_suspend(struct ipa_endpoint *endpoint, bool enable)
{
+ bool suspended;
+
+ if (endpoint->ipa->version != IPA_VERSION_3_5_1)
+ return enable; /* For IPA v4.0+, no change made */
+
/* assert(!endpoint->toward_ipa); */
- return ipa_endpoint_init_ctrl(endpoint, enable);
+ suspended = ipa_endpoint_init_ctrl(endpoint, enable);
+
+ /* A client suspended with an open aggregation frame will not
+ * generate a SUSPEND IPA interrupt. If enabling suspend, have
+ * ipa_endpoint_suspend_aggr() handle this.
+ */
+ if (enable && !suspended)
+ ipa_endpoint_suspend_aggr(endpoint);
+
+ return suspended;
}
/* Enable or disable delay or suspend mode on all modem endpoints */
void ipa_endpoint_modem_pause_all(struct ipa *ipa, bool enable)
{
- bool support_suspend;
u32 endpoint_id;
/* DELAY mode doesn't work correctly on IPA v4.2 */
if (ipa->version == IPA_VERSION_4_2)
return;
- /* Only IPA v3.5.1 supports SUSPEND mode on RX endpoints */
- support_suspend = ipa->version == IPA_VERSION_3_5_1;
-
for (endpoint_id = 0; endpoint_id < IPA_ENDPOINT_MAX; endpoint_id++) {
struct ipa_endpoint *endpoint = &ipa->endpoint[endpoint_id];
if (endpoint->ee_id != GSI_EE_MODEM)
continue;
- /* Set TX delay mode, or for IPA v3.5.1 RX suspend mode */
+ /* Set TX delay mode or RX suspend mode */
if (endpoint->toward_ipa)
ipa_endpoint_program_delay(endpoint, enable);
- else if (support_suspend)
+ else
(void)ipa_endpoint_program_suspend(endpoint, enable);
}
}
@@ -437,6 +499,9 @@ static void ipa_endpoint_init_cfg(struct ipa_endpoint *endpoint)
}
/**
+ * ipa_endpoint_init_hdr() - Initialize HDR endpoint configuration register
+ * @endpoint: Endpoint pointer
+ *
* We program QMAP endpoints so each packet received is preceded by a QMAP
* header structure. The QMAP header contains a 1-byte mux_id and 2-byte
* packet size field, and we have the IPA hardware populate both for each
@@ -527,10 +592,13 @@ static void ipa_endpoint_init_hdr_metadata_mask(struct ipa_endpoint *endpoint)
u32 val = 0;
u32 offset;
+ if (endpoint->toward_ipa)
+ return; /* Register not valid for TX endpoints */
+
offset = IPA_REG_ENDP_INIT_HDR_METADATA_MASK_N_OFFSET(endpoint_id);
/* Note that HDR_ENDIANNESS indicates big endian header fields */
- if (!endpoint->toward_ipa && endpoint->data->qmap)
+ if (endpoint->data->qmap)
val = cpu_to_be32(IPA_ENDPOINT_QMAP_METADATA_MASK);
iowrite32(val, endpoint->ipa->reg_virt + offset);
@@ -541,7 +609,10 @@ static void ipa_endpoint_init_mode(struct ipa_endpoint *endpoint)
u32 offset = IPA_REG_ENDP_INIT_MODE_N_OFFSET(endpoint->endpoint_id);
u32 val;
- if (endpoint->toward_ipa && endpoint->data->dma_mode) {
+ if (!endpoint->toward_ipa)
+ return; /* Register not valid for RX endpoints */
+
+ if (endpoint->data->dma_mode) {
enum ipa_endpoint_name name = endpoint->data->dma_endpoint;
u32 dma_endpoint_id;
@@ -552,7 +623,7 @@ static void ipa_endpoint_init_mode(struct ipa_endpoint *endpoint)
} else {
val = u32_encode_bits(IPA_BASIC, MODE_FMASK);
}
- /* Other bitfields unspecified (and 0) */
+ /* All other bits unspecified (and 0) */
iowrite32(val, endpoint->ipa->reg_virt + offset);
}
@@ -576,17 +647,20 @@ static void ipa_endpoint_init_aggr(struct ipa_endpoint *endpoint)
if (endpoint->data->aggregation) {
if (!endpoint->toward_ipa) {
- u32 aggr_size = ipa_aggr_size_kb(IPA_RX_BUFFER_SIZE);
u32 limit;
val |= u32_encode_bits(IPA_ENABLE_AGGR, AGGR_EN_FMASK);
val |= u32_encode_bits(IPA_GENERIC, AGGR_TYPE_FMASK);
- val |= u32_encode_bits(aggr_size,
- AGGR_BYTE_LIMIT_FMASK);
+
+ limit = ipa_aggr_size_kb(IPA_RX_BUFFER_SIZE);
+ val |= u32_encode_bits(limit, AGGR_BYTE_LIMIT_FMASK);
+
limit = IPA_AGGR_TIME_LIMIT_DEFAULT;
- val |= u32_encode_bits(limit / IPA_AGGR_GRANULARITY,
- AGGR_TIME_LIMIT_FMASK);
- val |= u32_encode_bits(0, AGGR_PKT_LIMIT_FMASK);
+ limit = DIV_ROUND_CLOSEST(limit, IPA_AGGR_GRANULARITY);
+ val |= u32_encode_bits(limit, AGGR_TIME_LIMIT_FMASK);
+
+ /* AGGR_PKT_LIMIT is 0 (unlimited) */
+
if (endpoint->data->rx.aggr_close_eof)
val |= AGGR_SW_EOF_ACTIVE_FMASK;
/* AGGR_HARD_BYTE_LIMIT_ENABLE is 0 */
@@ -605,63 +679,70 @@ static void ipa_endpoint_init_aggr(struct ipa_endpoint *endpoint)
iowrite32(val, endpoint->ipa->reg_virt + offset);
}
-/* A return value of 0 indicates an error */
+/* The head-of-line blocking timer is defined as a tick count, where each
+ * tick represents 128 cycles of the IPA core clock. Return the value
+ * that should be written to that register that represents the timeout
+ * period provided.
+ */
static u32 ipa_reg_init_hol_block_timer_val(struct ipa *ipa, u32 microseconds)
{
+ u32 width;
u32 scale;
- u32 base;
+ u64 ticks;
+ u64 rate;
+ u32 high;
u32 val;
if (!microseconds)
- return 0; /* invalid delay */
-
- /* Timer is represented in units of clock ticks. */
- if (ipa->version < IPA_VERSION_4_2)
- return microseconds; /* XXX Needs to be computed */
-
- /* IPA v4.2 represents the tick count as base * scale */
- scale = 1; /* XXX Needs to be computed */
- if (scale > field_max(SCALE_FMASK))
- return 0; /* scale too big */
-
- base = DIV_ROUND_CLOSEST(microseconds, scale);
- if (base > field_max(BASE_VALUE_FMASK))
- return 0; /* microseconds too big */
+ return 0; /* Nothing to compute if timer period is 0 */
+
+ /* Use 64 bit arithmetic to avoid overflow... */
+ rate = ipa_clock_rate(ipa);
+ ticks = DIV_ROUND_CLOSEST(microseconds * rate, 128 * USEC_PER_SEC);
+ /* ...but we still need to fit into a 32-bit register */
+ WARN_ON(ticks > U32_MAX);
+
+ /* IPA v3.5.1 just records the tick count */
+ if (ipa->version == IPA_VERSION_3_5_1)
+ return (u32)ticks;
+
+ /* For IPA v4.2, the tick count is represented by base and
+ * scale fields within the 32-bit timer register, where:
+ * ticks = base << scale;
+ * The best precision is achieved when the base value is as
+ * large as possible. Find the highest set bit in the tick
+ * count, and extract the number of bits in the base field
+ * such that that high bit is included.
+ */
+ high = fls(ticks); /* 1..32 */
+ width = HWEIGHT32(BASE_VALUE_FMASK);
+ scale = high > width ? high - width : 0;
+ if (scale) {
+ /* If we're scaling, round up to get a closer result */
+ ticks += 1 << (scale - 1);
+ /* High bit was set, so rounding might have affected it */
+ if (fls(ticks) != high)
+ scale++;
+ }
val = u32_encode_bits(scale, SCALE_FMASK);
- val |= u32_encode_bits(base, BASE_VALUE_FMASK);
+ val |= u32_encode_bits(ticks >> scale, BASE_VALUE_FMASK);
return val;
}
-static int ipa_endpoint_init_hol_block_timer(struct ipa_endpoint *endpoint,
- u32 microseconds)
+/* If microseconds is 0, timeout is immediate */
+static void ipa_endpoint_init_hol_block_timer(struct ipa_endpoint *endpoint,
+ u32 microseconds)
{
u32 endpoint_id = endpoint->endpoint_id;
struct ipa *ipa = endpoint->ipa;
u32 offset;
u32 val;
- /* XXX We'll fix this when the register definition is clear */
- if (microseconds) {
- struct device *dev = &ipa->pdev->dev;
-
- dev_err(dev, "endpoint %u non-zero HOLB period (ignoring)\n",
- endpoint_id);
- microseconds = 0;
- }
-
- if (microseconds) {
- val = ipa_reg_init_hol_block_timer_val(ipa, microseconds);
- if (!val)
- return -EINVAL;
- } else {
- val = 0; /* timeout is immediate */
- }
offset = IPA_REG_ENDP_INIT_HOL_BLOCK_TIMER_N_OFFSET(endpoint_id);
+ val = ipa_reg_init_hol_block_timer_val(ipa, microseconds);
iowrite32(val, ipa->reg_virt + offset);
-
- return 0;
}
static void
@@ -671,7 +752,7 @@ ipa_endpoint_init_hol_block_enable(struct ipa_endpoint *endpoint, bool enable)
u32 offset;
u32 val;
- val = u32_encode_bits(enable ? 1 : 0, HOL_BLOCK_EN_FMASK);
+ val = enable ? HOL_BLOCK_EN_FMASK : 0;
offset = IPA_REG_ENDP_INIT_HOL_BLOCK_EN_N_OFFSET(endpoint_id);
iowrite32(val, endpoint->ipa->reg_virt + offset);
}
@@ -683,10 +764,10 @@ void ipa_endpoint_modem_hol_block_clear_all(struct ipa *ipa)
for (i = 0; i < IPA_ENDPOINT_MAX; i++) {
struct ipa_endpoint *endpoint = &ipa->endpoint[i];
- if (endpoint->ee_id != GSI_EE_MODEM)
+ if (endpoint->toward_ipa || endpoint->ee_id != GSI_EE_MODEM)
continue;
- (void)ipa_endpoint_init_hol_block_timer(endpoint, 0);
+ ipa_endpoint_init_hol_block_timer(endpoint, 0);
ipa_endpoint_init_hol_block_enable(endpoint, true);
}
}
@@ -696,6 +777,9 @@ static void ipa_endpoint_init_deaggr(struct ipa_endpoint *endpoint)
u32 offset = IPA_REG_ENDP_INIT_DEAGGR_N_OFFSET(endpoint->endpoint_id);
u32 val = 0;
+ if (!endpoint->toward_ipa)
+ return; /* Register not valid for RX endpoints */
+
/* DEAGGR_HDR_LEN is 0 */
/* PACKET_OFFSET_VALID is 0 */
/* PACKET_OFFSET_LOCATION is ignored (not valid) */
@@ -710,6 +794,9 @@ static void ipa_endpoint_init_seq(struct ipa_endpoint *endpoint)
u32 seq_type = endpoint->seq_type;
u32 val = 0;
+ if (!endpoint->toward_ipa)
+ return; /* Register not valid for RX endpoints */
+
/* Sequencer type is made up of four nibbles */
val |= u32_encode_bits(seq_type & 0xf, HPS_SEQ_TYPE_FMASK);
val |= u32_encode_bits((seq_type >> 4) & 0xf, DPS_SEQ_TYPE_FMASK);
@@ -837,6 +924,8 @@ err_free_pages:
/**
* ipa_endpoint_replenish() - Replenish the Rx packets cache.
+ * @endpoint: Endpoint to be replenished
+ * @count: Number of buffers to send to hardware
*
* Allocate RX packet wrapper structures with maximal socket buffers
* for an endpoint. These are supplied to the hardware, which fills
@@ -1139,29 +1228,6 @@ void ipa_endpoint_default_route_clear(struct ipa *ipa)
ipa_endpoint_default_route_set(ipa, 0);
}
-static bool ipa_endpoint_aggr_active(struct ipa_endpoint *endpoint)
-{
- u32 mask = BIT(endpoint->endpoint_id);
- struct ipa *ipa = endpoint->ipa;
- u32 offset;
- u32 val;
-
- /* assert(mask & ipa->available); */
- offset = ipa_reg_state_aggr_active_offset(ipa->version);
- val = ioread32(ipa->reg_virt + offset);
-
- return !!(val & mask);
-}
-
-static void ipa_endpoint_force_close(struct ipa_endpoint *endpoint)
-{
- u32 mask = BIT(endpoint->endpoint_id);
- struct ipa *ipa = endpoint->ipa;
-
- /* assert(mask & ipa->available); */
- iowrite32(mask, ipa->reg_virt + IPA_REG_AGGR_FORCE_CLOSE_OFFSET);
-}
-
/**
* ipa_endpoint_reset_rx_aggr() - Reset RX endpoint with aggregation active
* @endpoint: Endpoint to be reset
@@ -1170,7 +1236,7 @@ static void ipa_endpoint_force_close(struct ipa_endpoint *endpoint)
* on its underlying GSI channel, a special sequence of actions must be
* taken to ensure the IPA pipeline is properly cleared.
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*/
static int ipa_endpoint_reset_rx_aggr(struct ipa_endpoint *endpoint)
{
@@ -1206,8 +1272,7 @@ static int ipa_endpoint_reset_rx_aggr(struct ipa_endpoint *endpoint)
gsi_channel_reset(gsi, endpoint->channel_id, false);
/* Make sure the channel isn't suspended */
- if (endpoint->ipa->version == IPA_VERSION_3_5_1)
- suspended = ipa_endpoint_program_suspend(endpoint, false);
+ suspended = ipa_endpoint_program_suspend(endpoint, false);
/* Start channel and do a 1 byte read */
ret = gsi_channel_start(gsi, endpoint->channel_id);
@@ -1290,23 +1355,18 @@ static void ipa_endpoint_reset(struct ipa_endpoint *endpoint)
static void ipa_endpoint_program(struct ipa_endpoint *endpoint)
{
- if (endpoint->toward_ipa) {
- if (endpoint->ipa->version != IPA_VERSION_4_2)
- ipa_endpoint_program_delay(endpoint, false);
- ipa_endpoint_init_hdr_ext(endpoint);
- ipa_endpoint_init_aggr(endpoint);
- ipa_endpoint_init_deaggr(endpoint);
- ipa_endpoint_init_seq(endpoint);
- } else {
- if (endpoint->ipa->version == IPA_VERSION_3_5_1)
- (void)ipa_endpoint_program_suspend(endpoint, false);
- ipa_endpoint_init_hdr_ext(endpoint);
- ipa_endpoint_init_aggr(endpoint);
- }
+ if (endpoint->toward_ipa)
+ ipa_endpoint_program_delay(endpoint, false);
+ else
+ (void)ipa_endpoint_program_suspend(endpoint, false);
ipa_endpoint_init_cfg(endpoint);
ipa_endpoint_init_hdr(endpoint);
+ ipa_endpoint_init_hdr_ext(endpoint);
ipa_endpoint_init_hdr_metadata_mask(endpoint);
ipa_endpoint_init_mode(endpoint);
+ ipa_endpoint_init_aggr(endpoint);
+ ipa_endpoint_init_deaggr(endpoint);
+ ipa_endpoint_init_seq(endpoint);
ipa_endpoint_status(endpoint);
}
@@ -1362,34 +1422,6 @@ void ipa_endpoint_disable_one(struct ipa_endpoint *endpoint)
endpoint->endpoint_id);
}
-/**
- * ipa_endpoint_suspend_aggr() - Emulate suspend interrupt
- * @endpoint_id: Endpoint on which to emulate a suspend
- *
- * Emulate suspend IPA interrupt to unsuspend an endpoint suspended
- * with an open aggregation frame. This is to work around a hardware
- * issue in IPA version 3.5.1 where the suspend interrupt will not be
- * generated when it should be.
- */
-static void ipa_endpoint_suspend_aggr(struct ipa_endpoint *endpoint)
-{
- struct ipa *ipa = endpoint->ipa;
-
- /* assert(ipa->version == IPA_VERSION_3_5_1); */
-
- if (!endpoint->data->aggregation)
- return;
-
- /* Nothing to do if the endpoint doesn't have aggregation open */
- if (!ipa_endpoint_aggr_active(endpoint))
- return;
-
- /* Force close aggregation */
- ipa_endpoint_force_close(endpoint);
-
- ipa_interrupt_simulate_suspend(ipa->interrupt);
-}
-
void ipa_endpoint_suspend_one(struct ipa_endpoint *endpoint)
{
struct device *dev = &endpoint->ipa->pdev->dev;
@@ -1403,19 +1435,11 @@ void ipa_endpoint_suspend_one(struct ipa_endpoint *endpoint)
if (!endpoint->toward_ipa)
ipa_endpoint_replenish_disable(endpoint);
- /* IPA v3.5.1 doesn't use channel stop for suspend */
- stop_channel = endpoint->ipa->version != IPA_VERSION_3_5_1;
- if (!endpoint->toward_ipa && !stop_channel) {
- /* Due to a hardware bug, a client suspended with an open
- * aggregation frame will not generate a SUSPEND IPA
- * interrupt. We work around this by force-closing the
- * aggregation frame, then simulating the arrival of such
- * an interrupt.
- */
+ if (!endpoint->toward_ipa)
(void)ipa_endpoint_program_suspend(endpoint, true);
- ipa_endpoint_suspend_aggr(endpoint);
- }
+ /* IPA v3.5.1 doesn't use channel stop for suspend */
+ stop_channel = endpoint->ipa->version != IPA_VERSION_3_5_1;
ret = gsi_channel_suspend(gsi, endpoint->channel_id, stop_channel);
if (ret)
dev_err(dev, "error %d suspending channel %u\n", ret,
@@ -1432,11 +1456,11 @@ void ipa_endpoint_resume_one(struct ipa_endpoint *endpoint)
if (!(endpoint->ipa->enabled & BIT(endpoint->endpoint_id)))
return;
- /* IPA v3.5.1 doesn't use channel start for resume */
- start_channel = endpoint->ipa->version != IPA_VERSION_3_5_1;
- if (!endpoint->toward_ipa && !start_channel)
+ if (!endpoint->toward_ipa)
(void)ipa_endpoint_program_suspend(endpoint, false);
+ /* IPA v3.5.1 doesn't use channel start for resume */
+ start_channel = endpoint->ipa->version != IPA_VERSION_3_5_1;
ret = gsi_channel_resume(gsi, endpoint->channel_id, start_channel);
if (ret)
dev_err(dev, "error %d resuming channel %u\n", ret,
diff --git a/drivers/net/ipa/ipa_gsi.h b/drivers/net/ipa/ipa_gsi.h
index 0a40f3dc55fc..c02cb6f3a2e1 100644
--- a/drivers/net/ipa/ipa_gsi.h
+++ b/drivers/net/ipa/ipa_gsi.h
@@ -43,9 +43,9 @@ void ipa_gsi_trans_release(struct gsi_trans *trans);
*/
void ipa_gsi_channel_tx_queued(struct gsi *gsi, u32 channel_id, u32 count,
u32 byte_count);
+
/**
- * ipa_gsi_trans_complete() - GSI transaction completion callback
-ipa_gsi_channel_tx_completed()
+ * ipa_gsi_channel_tx_completed() - GSI transaction completion callback
* @gsi: GSI pointer
* @channel_id: Channel number
* @count: Number of transactions completed since last report
@@ -57,6 +57,15 @@ ipa_gsi_channel_tx_completed()
void ipa_gsi_channel_tx_completed(struct gsi *gsi, u32 channel_id, u32 count,
u32 byte_count);
+/* ipa_gsi_endpoint_data_empty() - Empty endpoint config data test
+ * @data: endpoint configuration data
+ *
+ * Determines whether an endpoint configuration data entry is empty,
+ * meaning it contains no valid configuration information and should
+ * be ignored.
+ *
+ * Return: true if empty; false otherwise
+ */
bool ipa_gsi_endpoint_data_empty(const struct ipa_gsi_endpoint_data *data);
#endif /* _IPA_GSI_TRANS_H_ */
diff --git a/drivers/net/ipa/ipa_interrupt.h b/drivers/net/ipa/ipa_interrupt.h
index d4f4c1c9f0b1..727e9c5044d1 100644
--- a/drivers/net/ipa/ipa_interrupt.h
+++ b/drivers/net/ipa/ipa_interrupt.h
@@ -104,7 +104,7 @@ void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt);
* ipa_interrupt_setup() - Set up the IPA interrupt framework
* @ipa: IPA pointer
*
- * @Return: Pointer to IPA SMP2P info, or a pointer-coded error
+ * Return: Pointer to IPA SMP2P info, or a pointer-coded error
*/
struct ipa_interrupt *ipa_interrupt_setup(struct ipa *ipa);
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index 76d5108b8403..1fdfec41e442 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -277,6 +277,7 @@ static void ipa_idle_indication_cfg(struct ipa *ipa,
/**
* ipa_hardware_dcd_config() - Enable dynamic clock division on IPA
+ * @ipa: IPA pointer
*
* Configures when the IPA signals it is idle to the global clock
* controller, which can respond by scalling down the clock to
@@ -495,6 +496,7 @@ static void ipa_resource_deconfig(struct ipa *ipa)
/**
* ipa_config() - Configure IPA hardware
* @ipa: IPA pointer
+ * @data: IPA configuration data
*
* Perform initialization requiring IPA clock to be enabled.
*/
@@ -674,6 +676,11 @@ static void ipa_validate_build(void)
/* This is used as a divisor */
BUILD_BUG_ON(!IPA_AGGR_GRANULARITY);
+
+ /* Aggregation granularity value can't be 0, and must fit */
+ BUILD_BUG_ON(!ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY));
+ BUILD_BUG_ON(ipa_aggr_granularity_val(IPA_AGGR_GRANULARITY) >
+ field_max(AGGR_GRANULARITY));
#endif /* IPA_VALIDATE */
}
@@ -681,7 +688,7 @@ static void ipa_validate_build(void)
* ipa_probe() - IPA platform driver probe function
* @pdev: Platform device pointer
*
- * @Return: 0 if successful, or a negative error code (possibly
+ * Return: 0 if successful, or a negative error code (possibly
* EPROBE_DEFER)
*
* This is the main entry point for the IPA driver. Initialization proceeds
@@ -897,7 +904,7 @@ static int ipa_remove(struct platform_device *pdev)
* ipa_suspend() - Power management system suspend callback
* @dev: IPA device structure
*
- * @Return: Zero
+ * Return: Always returns zero
*
* Called by the PM framework when a system suspend operation is invoked.
*/
@@ -915,7 +922,7 @@ static int ipa_suspend(struct device *dev)
* ipa_resume() - Power management system resume callback
* @dev: IPA device structure
*
- * @Return: Always returns 0
+ * Return: Always returns 0
*
* Called by the PM framework when a system resume operation is invoked.
*/
diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c
index 3ef814119aab..2d45c444a67f 100644
--- a/drivers/net/ipa/ipa_mem.c
+++ b/drivers/net/ipa/ipa_mem.c
@@ -41,6 +41,7 @@ ipa_mem_zero_region_add(struct gsi_trans *trans, const struct ipa_mem *mem)
/**
* ipa_mem_setup() - Set up IPA AP and modem shared memory areas
+ * @ipa: IPA pointer
*
* Set up the shared memory regions in IPA local memory. This involves
* zero-filling memory regions, and in the case of header memory, telling
@@ -52,7 +53,7 @@ ipa_mem_zero_region_add(struct gsi_trans *trans, const struct ipa_mem *mem)
* The AP informs the modem where its portions of memory are located
* in a QMI exchange that occurs at modem startup.
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*/
int ipa_mem_setup(struct ipa *ipa)
{
@@ -137,8 +138,9 @@ static bool ipa_mem_valid(struct ipa *ipa, enum ipa_mem_id mem_id)
/**
* ipa_mem_config() - Configure IPA shared memory
+ * @ipa: IPA pointer
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*/
int ipa_mem_config(struct ipa *ipa)
{
@@ -238,6 +240,7 @@ void ipa_mem_deconfig(struct ipa *ipa)
/**
* ipa_mem_zero_modem() - Zero IPA-local memory regions owned by the modem
+ * @ipa: IPA pointer
*
* Zero regions of IPA-local memory used by the modem. These are configured
* (and initially zeroed) by ipa_mem_setup(), but if the modem crashes and
diff --git a/drivers/net/ipa/ipa_reg.h b/drivers/net/ipa/ipa_reg.h
index 0a688d8c1d7c..eb4e39fa7d4b 100644
--- a/drivers/net/ipa/ipa_reg.h
+++ b/drivers/net/ipa/ipa_reg.h
@@ -32,10 +32,12 @@ struct ipa;
* parameter is supplied to the offset macro. The "ee" value is a member of
* the gsi_ee enumerated type.
*
- * The offset of a register dependent on endpoint id is computed by a macro
- * that is supplied a parameter "ep". The "ep" value is assumed to be less
- * than the maximum endpoint value for the current hardware, and that will
- * not exceed IPA_ENDPOINT_MAX.
+ * The offset of a register dependent on endpoint ID is computed by a macro
+ * that is supplied a parameter "ep", "txep", or "rxep". A register with an
+ * "ep" parameter is valid for any endpoint; a register with a "txep" or
+ * "rxep" parameter is valid only for TX or RX endpoints, respectively. The
+ * "*ep" value is assumed to be less than the maximum valid endpoint ID
+ * for the current hardware, and that will not exceed IPA_ENDPOINT_MAX.
*
* The offset of registers related to filter and route tables is computed
* by a macro that is supplied a parameter "er". The "er" represents an
@@ -190,24 +192,23 @@ static inline u32 ipa_reg_bcr_val(enum ipa_version version)
return 0x00000000;
}
-
#define IPA_REG_LOCAL_PKT_PROC_CNTXT_BASE_OFFSET 0x000001e8
#define IPA_REG_AGGR_FORCE_CLOSE_OFFSET 0x000001ec
/* ipa->available defines the valid bits in the AGGR_FORCE_CLOSE register */
+/* The internal inactivity timer clock is used for the aggregation timer */
+#define TIMER_FREQUENCY 32000 /* 32 KHz inactivity timer clock */
+
#define IPA_REG_COUNTER_CFG_OFFSET 0x000001f0
#define AGGR_GRANULARITY GENMASK(8, 4)
-/* Compute the value to use in the AGGR_GRANULARITY field representing
- * the given number of microseconds (up to 1 millisecond).
- * x = (32 * usec) / 1000 - 1
+/* Compute the value to use in the AGGR_GRANULARITY field representing the
+ * given number of microseconds. The value is one less than the number of
+ * timer ticks in the requested period. Zero not a valid granularity value.
*/
-static inline u32 ipa_aggr_granularity_val(u32 microseconds)
+static inline u32 ipa_aggr_granularity_val(u32 usec)
{
- /* assert(microseconds >= 16); (?) */
- /* assert(microseconds <= 1015); */
-
- return DIV_ROUND_CLOSEST(32 * microseconds, 1000) - 1;
+ return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1;
}
#define IPA_REG_TX_CFG_OFFSET 0x000001fc
@@ -293,11 +294,13 @@ static inline u32 ipa_reg_idle_indication_cfg_offset(enum ipa_version version)
#define HDR_TOTAL_LEN_OR_PAD_OFFSET_FMASK GENMASK(9, 4)
#define HDR_PAD_TO_ALIGNMENT_FMASK GENMASK(13, 10)
-#define IPA_REG_ENDP_INIT_HDR_METADATA_MASK_N_OFFSET(ep) \
- (0x00000818 + 0x0070 * (ep))
+/* Valid only for RX (IPA producer) endpoints */
+#define IPA_REG_ENDP_INIT_HDR_METADATA_MASK_N_OFFSET(rxep) \
+ (0x00000818 + 0x0070 * (rxep))
-#define IPA_REG_ENDP_INIT_MODE_N_OFFSET(ep) \
- (0x00000820 + 0x0070 * (ep))
+/* Valid only for TX (IPA consumer) endpoints */
+#define IPA_REG_ENDP_INIT_MODE_N_OFFSET(txep) \
+ (0x00000820 + 0x0070 * (txep))
#define MODE_FMASK GENMASK(2, 0)
#define DEST_PIPE_INDEX_FMASK GENMASK(8, 4)
#define BYTE_THRESHOLD_FMASK GENMASK(27, 12)
@@ -316,19 +319,21 @@ static inline u32 ipa_reg_idle_indication_cfg_offset(enum ipa_version version)
#define AGGR_FORCE_CLOSE_FMASK GENMASK(22, 22)
#define AGGR_HARD_BYTE_LIMIT_ENABLE_FMASK GENMASK(24, 24)
-#define IPA_REG_ENDP_INIT_HOL_BLOCK_EN_N_OFFSET(ep) \
- (0x0000082c + 0x0070 * (ep))
+/* Valid only for RX (IPA producer) endpoints */
+#define IPA_REG_ENDP_INIT_HOL_BLOCK_EN_N_OFFSET(rxep) \
+ (0x0000082c + 0x0070 * (rxep))
#define HOL_BLOCK_EN_FMASK GENMASK(0, 0)
-/* The next register is valid only for RX (IPA producer) endpoints */
-#define IPA_REG_ENDP_INIT_HOL_BLOCK_TIMER_N_OFFSET(ep) \
- (0x00000830 + 0x0070 * (ep))
+/* Valid only for RX (IPA producer) endpoints */
+#define IPA_REG_ENDP_INIT_HOL_BLOCK_TIMER_N_OFFSET(rxep) \
+ (0x00000830 + 0x0070 * (rxep))
/* The next fields are present for IPA v4.2 only */
#define BASE_VALUE_FMASK GENMASK(4, 0)
#define SCALE_FMASK GENMASK(12, 8)
-#define IPA_REG_ENDP_INIT_DEAGGR_N_OFFSET(ep) \
- (0x00000834 + 0x0070 * (ep))
+/* Valid only for TX (IPA consumer) endpoints */
+#define IPA_REG_ENDP_INIT_DEAGGR_N_OFFSET(txep) \
+ (0x00000834 + 0x0070 * (txep))
#define DEAGGR_HDR_LEN_FMASK GENMASK(5, 0)
#define PACKET_OFFSET_VALID_FMASK GENMASK(7, 7)
#define PACKET_OFFSET_LOCATION_FMASK GENMASK(13, 8)
@@ -338,8 +343,9 @@ static inline u32 ipa_reg_idle_indication_cfg_offset(enum ipa_version version)
(0x00000838 + 0x0070 * (ep))
#define RSRC_GRP_FMASK GENMASK(1, 0)
-#define IPA_REG_ENDP_INIT_SEQ_N_OFFSET(ep) \
- (0x0000083c + 0x0070 * (ep))
+/* Valid only for TX (IPA consumer) endpoints */
+#define IPA_REG_ENDP_INIT_SEQ_N_OFFSET(txep) \
+ (0x0000083c + 0x0070 * (txep))
#define HPS_SEQ_TYPE_FMASK GENMASK(3, 0)
#define DPS_SEQ_TYPE_FMASK GENMASK(7, 4)
#define HPS_REP_SEQ_TYPE_FMASK GENMASK(11, 8)
@@ -353,7 +359,7 @@ static inline u32 ipa_reg_idle_indication_cfg_offset(enum ipa_version version)
/* The next field is present for IPA v4.0 and above */
#define STATUS_PKT_SUPPRESS_FMASK GENMASK(9, 9)
-/* "er" is either an endpoint id (for filters) or a route id (for routes) */
+/* "er" is either an endpoint ID (for filters) or a route ID (for routes) */
#define IPA_REG_ENDP_FILTER_ROUTER_HSH_CFG_N_OFFSET(er) \
(0x0000085c + 0x0070 * (er))
#define FILTER_HASH_MSK_SRC_ID_FMASK GENMASK(0, 0)
diff --git a/drivers/net/ipa/ipa_smp2p.h b/drivers/net/ipa/ipa_smp2p.h
index 1f65cdc9d406..bf0e4063cfd9 100644
--- a/drivers/net/ipa/ipa_smp2p.h
+++ b/drivers/net/ipa/ipa_smp2p.h
@@ -15,7 +15,7 @@ struct ipa;
* @ipa: IPA pointer
* @modem_init: Whether the modem is responsible for GSI initialization
*
- * @Return: 0 if successful, or a negative error code
+ * Return: 0 if successful, or a negative error code
*
*/
int ipa_smp2p_init(struct ipa *ipa, bool modem_init);
diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 9df2a3e78c98..2098ca2f2c90 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -505,7 +505,7 @@ void ipa_table_teardown(struct ipa *ipa)
/**
* ipa_filter_tuple_zero() - Zero an endpoint's hashed filter tuple
- * @endpoint_id: Endpoint whose filter hash tuple should be zeroed
+ * @endpoint: Endpoint whose filter hash tuple should be zeroed
*
* Endpoint must be for the AP (not modem) and support filtering. Updates
* the filter hash values without changing route ones.
@@ -560,6 +560,7 @@ static bool ipa_route_id_modem(u32 route_id)
/**
* ipa_route_tuple_zero() - Zero a hashed route table entry tuple
+ * @ipa: IPA pointer
* @route_id: Route table entry whose hash tuple should be zeroed
*
* Updates the route hash values without changing filter ones.
diff --git a/drivers/net/ipa/ipa_table.h b/drivers/net/ipa/ipa_table.h
index 64ea0221441a..78038d14fcea 100644
--- a/drivers/net/ipa/ipa_table.h
+++ b/drivers/net/ipa/ipa_table.h
@@ -25,7 +25,7 @@ struct ipa;
* ipa_table_valid() - Validate route and filter table memory regions
* @ipa: IPA pointer
- * @Return: true if all regions are valid, false otherwise
+ * Return: true if all regions are valid, false otherwise
*/
bool ipa_table_valid(struct ipa *ipa);
@@ -33,7 +33,7 @@ bool ipa_table_valid(struct ipa *ipa);
* ipa_filter_map_valid() - Validate a filter table endpoint bitmap
* @ipa: IPA pointer
*
- * @Return: true if all regions are valid, false otherwise
+ * Return: true if all regions are valid, false otherwise
*/
bool ipa_filter_map_valid(struct ipa *ipa, u32 filter_mask);
diff --git a/drivers/net/ipa/ipa_uc.c b/drivers/net/ipa/ipa_uc.c
index a1f8db00d55a..1a0b04e0ab74 100644
--- a/drivers/net/ipa/ipa_uc.c
+++ b/drivers/net/ipa/ipa_uc.c
@@ -35,31 +35,34 @@
*/
/* Supports hardware interface version 0x2000 */
-/* Offset relative to the base of the IPA shared address space of the
- * shared region used for communication with the microcontroller. The
- * region is 128 bytes in size, but only the first 40 bytes are used.
- */
-#define IPA_MEM_UC_OFFSET 0x0000
-
/* Delay to allow a the microcontroller to save state when crashing */
#define IPA_SEND_DELAY 100 /* microseconds */
/**
* struct ipa_uc_mem_area - AP/microcontroller shared memory area
* @command: command code (AP->microcontroller)
+ * @reserved0: reserved bytes; avoid reading or writing
* @command_param: low 32 bits of command parameter (AP->microcontroller)
* @command_param_hi: high 32 bits of command parameter (AP->microcontroller)
*
* @response: response code (microcontroller->AP)
+ * @reserved1: reserved bytes; avoid reading or writing
* @response_param: response parameter (microcontroller->AP)
*
* @event: event code (microcontroller->AP)
+ * @reserved2: reserved bytes; avoid reading or writing
* @event_param: event parameter (microcontroller->AP)
*
* @first_error_address: address of first error-source on SNOC
* @hw_state: state of hardware (including error type information)
* @warning_counter: counter of non-fatal hardware errors
+ * @reserved3: reserved bytes; avoid reading or writing
* @interface_version: hardware-reported interface version
+ * @reserved4: reserved bytes; avoid reading or writing
+ *
+ * A shared memory area at the base of IPA resident memory is used for
+ * communication with the microcontroller. The region is 128 bytes in
+ * size, but only the first 40 bytes (structured this way) are used.
*/
struct ipa_uc_mem_area {
u8 command; /* enum ipa_uc_command */
diff --git a/drivers/net/netdevsim/Makefile b/drivers/net/netdevsim/Makefile
index f4d8f62f28c2..4dfb389dbfd8 100644
--- a/drivers/net/netdevsim/Makefile
+++ b/drivers/net/netdevsim/Makefile
@@ -3,7 +3,7 @@
obj-$(CONFIG_NETDEVSIM) += netdevsim.o
netdevsim-objs := \
- netdev.o dev.o fib.o bus.o health.o
+ netdev.o dev.o fib.o bus.o health.o udp_tunnels.o
ifeq ($(CONFIG_BPF_SYSCALL),y)
netdevsim-objs += \
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c
index 0b362b8dac17..2e90512f3bbe 100644
--- a/drivers/net/netdevsim/bpf.c
+++ b/drivers/net/netdevsim/bpf.c
@@ -551,10 +551,6 @@ int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf)
ASSERT_RTNL();
switch (bpf->command) {
- case XDP_QUERY_PROG:
- return xdp_attachment_query(&ns->xdp, bpf);
- case XDP_QUERY_PROG_HW:
- return xdp_attachment_query(&ns->xdp_hw, bpf);
case XDP_SETUP_PROG:
err = nsim_setup_prog_checks(ns, bpf);
if (err)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index ec6b6f7818ac..32f339fedb21 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -225,6 +225,7 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
debugfs_create_bool("fail_trap_policer_counter_get", 0600,
nsim_dev->ddir,
&nsim_dev->fail_trap_policer_counter_get);
+ nsim_udp_tunnels_debugfs_create(nsim_dev);
return 0;
}
@@ -809,7 +810,8 @@ static int nsim_dev_devlink_trap_init(struct devlink *devlink,
static int
nsim_dev_devlink_trap_action_set(struct devlink *devlink,
const struct devlink_trap *trap,
- enum devlink_trap_action action)
+ enum devlink_trap_action action,
+ struct netlink_ext_ack *extack)
{
struct nsim_dev *nsim_dev = devlink_priv(devlink);
struct nsim_trap_item *nsim_trap_item;
@@ -828,7 +830,8 @@ nsim_dev_devlink_trap_action_set(struct devlink *devlink,
static int
nsim_dev_devlink_trap_group_set(struct devlink *devlink,
const struct devlink_trap_group *group,
- const struct devlink_trap_policer *policer)
+ const struct devlink_trap_policer *policer,
+ struct netlink_ext_ack *extack)
{
struct nsim_dev *nsim_dev = devlink_priv(devlink);
@@ -889,6 +892,7 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
unsigned int port_index)
{
+ struct devlink_port_attrs attrs = {};
struct nsim_dev_port *nsim_dev_port;
struct devlink_port *devlink_port;
int err;
@@ -899,10 +903,11 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
nsim_dev_port->port_index = port_index;
devlink_port = &nsim_dev_port->devlink_port;
- devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- port_index + 1, 0, 0,
- nsim_dev->switch_id.id,
- nsim_dev->switch_id.id_len);
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ attrs.phys.port_number = port_index + 1;
+ memcpy(attrs.switch_id.id, nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
+ attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
+ devlink_port_attrs_set(devlink_port, &attrs);
err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port,
port_index);
if (err)
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 23950e7a0f81..97cfb015a50b 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -22,6 +22,7 @@
#include <net/netlink.h>
#include <net/pkt_cls.h>
#include <net/rtnetlink.h>
+#include <net/udp_tunnel.h>
#include "netdevsim.h"
@@ -257,6 +258,8 @@ static const struct net_device_ops nsim_netdev_ops = {
.ndo_setup_tc = nsim_setup_tc,
.ndo_set_features = nsim_set_features,
.ndo_bpf = nsim_bpf,
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
.ndo_get_devlink_port = nsim_get_devlink_port,
};
@@ -299,10 +302,14 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
SET_NETDEV_DEV(dev, &ns->nsim_bus_dev->dev);
dev->netdev_ops = &nsim_netdev_ops;
+ err = nsim_udp_tunnels_info_create(nsim_dev, dev);
+ if (err)
+ goto err_free_netdev;
+
rtnl_lock();
err = nsim_bpf_init(ns);
if (err)
- goto err_rtnl_unlock;
+ goto err_utn_destroy;
nsim_ipsec_init(ns);
@@ -316,8 +323,10 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
err_ipsec_teardown:
nsim_ipsec_teardown(ns);
nsim_bpf_uninit(ns);
-err_rtnl_unlock:
+err_utn_destroy:
rtnl_unlock();
+ nsim_udp_tunnels_info_destroy(dev);
+err_free_netdev:
free_netdev(dev);
return ERR_PTR(err);
}
@@ -331,6 +340,7 @@ void nsim_destroy(struct netdevsim *ns)
nsim_ipsec_teardown(ns);
nsim_bpf_uninit(ns);
rtnl_unlock();
+ nsim_udp_tunnels_info_destroy(dev);
free_netdev(dev);
}
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 4ded54a21e1e..284f7092241d 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -13,6 +13,7 @@
* THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
*/
+#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/list.h>
@@ -29,6 +30,7 @@
#define NSIM_IPSEC_MAX_SA_COUNT 33
#define NSIM_IPSEC_VALID BIT(31)
+#define NSIM_UDP_TUNNEL_N_PORTS 4
struct nsim_sa {
struct xfrm_state *xs;
@@ -72,12 +74,23 @@ struct netdevsim {
bool bpf_map_accept;
struct nsim_ipsec ipsec;
+ struct {
+ u32 inject_error;
+ u32 sleep;
+ u32 ports[2][NSIM_UDP_TUNNEL_N_PORTS];
+ struct debugfs_u32_array dfs_ports[2];
+ } udp_ports;
};
struct netdevsim *
nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port);
void nsim_destroy(struct netdevsim *ns);
+void nsim_udp_tunnels_debugfs_create(struct nsim_dev *nsim_dev);
+int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev,
+ struct net_device *dev);
+void nsim_udp_tunnels_info_destroy(struct net_device *dev);
+
#ifdef CONFIG_BPF_SYSCALL
int nsim_bpf_dev_init(struct nsim_dev *nsim_dev);
void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev);
@@ -108,7 +121,7 @@ static inline void nsim_bpf_uninit(struct netdevsim *ns)
static inline int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf)
{
- return bpf->command == XDP_QUERY_PROG ? 0 : -EOPNOTSUPP;
+ return -EOPNOTSUPP;
}
static inline int nsim_bpf_disable_tc(struct netdevsim *ns)
@@ -183,6 +196,12 @@ struct nsim_dev {
bool fail_trap_group_set;
bool fail_trap_policer_set;
bool fail_trap_policer_counter_get;
+ struct {
+ bool sync_all;
+ bool open_only;
+ bool ipv4_only;
+ u32 sleep;
+ } udp_ports;
};
static inline struct net *nsim_dev_net(struct nsim_dev *nsim_dev)
diff --git a/drivers/net/netdevsim/udp_tunnels.c b/drivers/net/netdevsim/udp_tunnels.c
new file mode 100644
index 000000000000..22c06a76033c
--- /dev/null
+++ b/drivers/net/netdevsim/udp_tunnels.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2020 Facebook Inc.
+
+#include <linux/debugfs.h>
+#include <linux/netdevice.h>
+#include <linux/slab.h>
+#include <net/udp_tunnel.h>
+
+#include "netdevsim.h"
+
+static int
+nsim_udp_tunnel_set_port(struct net_device *dev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti)
+{
+ struct netdevsim *ns = netdev_priv(dev);
+ int ret;
+
+ ret = -ns->udp_ports.inject_error;
+ ns->udp_ports.inject_error = 0;
+
+ if (ns->udp_ports.sleep)
+ msleep(ns->udp_ports.sleep);
+
+ if (!ret) {
+ if (ns->udp_ports.ports[table][entry])
+ ret = -EBUSY;
+ else
+ ns->udp_ports.ports[table][entry] =
+ be16_to_cpu(ti->port) << 16 | ti->type;
+ }
+
+ netdev_info(dev, "set [%d, %d] type %d family %d port %d - %d\n",
+ table, entry, ti->type, ti->sa_family, ntohs(ti->port),
+ ret);
+ return ret;
+}
+
+static int
+nsim_udp_tunnel_unset_port(struct net_device *dev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti)
+{
+ struct netdevsim *ns = netdev_priv(dev);
+ int ret;
+
+ ret = -ns->udp_ports.inject_error;
+ ns->udp_ports.inject_error = 0;
+
+ if (ns->udp_ports.sleep)
+ msleep(ns->udp_ports.sleep);
+ if (!ret) {
+ u32 val = be16_to_cpu(ti->port) << 16 | ti->type;
+
+ if (val == ns->udp_ports.ports[table][entry])
+ ns->udp_ports.ports[table][entry] = 0;
+ else
+ ret = -ENOENT;
+ }
+
+ netdev_info(dev, "unset [%d, %d] type %d family %d port %d - %d\n",
+ table, entry, ti->type, ti->sa_family, ntohs(ti->port),
+ ret);
+ return ret;
+}
+
+static int
+nsim_udp_tunnel_sync_table(struct net_device *dev, unsigned int table)
+{
+ struct netdevsim *ns = netdev_priv(dev);
+ struct udp_tunnel_info ti;
+ unsigned int i;
+ int ret;
+
+ ret = -ns->udp_ports.inject_error;
+ ns->udp_ports.inject_error = 0;
+
+ for (i = 0; i < NSIM_UDP_TUNNEL_N_PORTS; i++) {
+ udp_tunnel_nic_get_port(dev, table, i, &ti);
+ ns->udp_ports.ports[table][i] =
+ be16_to_cpu(ti.port) << 16 | ti.type;
+ }
+
+ return ret;
+}
+
+static const struct udp_tunnel_nic_info nsim_udp_tunnel_info = {
+ .set_port = nsim_udp_tunnel_set_port,
+ .unset_port = nsim_udp_tunnel_unset_port,
+ .sync_table = nsim_udp_tunnel_sync_table,
+
+ .tables = {
+ {
+ .n_entries = NSIM_UDP_TUNNEL_N_PORTS,
+ .tunnel_types = UDP_TUNNEL_TYPE_VXLAN,
+ },
+ {
+ .n_entries = NSIM_UDP_TUNNEL_N_PORTS,
+ .tunnel_types = UDP_TUNNEL_TYPE_GENEVE |
+ UDP_TUNNEL_TYPE_VXLAN_GPE,
+ },
+ },
+};
+
+static ssize_t
+nsim_udp_tunnels_info_reset_write(struct file *file, const char __user *data,
+ size_t count, loff_t *ppos)
+{
+ struct net_device *dev = file->private_data;
+ struct netdevsim *ns = netdev_priv(dev);
+
+ memset(&ns->udp_ports.ports, 0, sizeof(ns->udp_ports.ports));
+ rtnl_lock();
+ udp_tunnel_nic_reset_ntf(dev);
+ rtnl_unlock();
+
+ return count;
+}
+
+static const struct file_operations nsim_udp_tunnels_info_reset_fops = {
+ .open = simple_open,
+ .write = nsim_udp_tunnels_info_reset_write,
+ .llseek = generic_file_llseek,
+};
+
+int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev,
+ struct net_device *dev)
+{
+ struct netdevsim *ns = netdev_priv(dev);
+ struct udp_tunnel_nic_info *info;
+
+ debugfs_create_u32("udp_ports_inject_error", 0600,
+ ns->nsim_dev_port->ddir,
+ &ns->udp_ports.inject_error);
+
+ ns->udp_ports.dfs_ports[0].array = ns->udp_ports.ports[0];
+ ns->udp_ports.dfs_ports[0].n_elements = NSIM_UDP_TUNNEL_N_PORTS;
+ debugfs_create_u32_array("udp_ports_table0", 0400,
+ ns->nsim_dev_port->ddir,
+ &ns->udp_ports.dfs_ports[0]);
+
+ ns->udp_ports.dfs_ports[1].array = ns->udp_ports.ports[1];
+ ns->udp_ports.dfs_ports[1].n_elements = NSIM_UDP_TUNNEL_N_PORTS;
+ debugfs_create_u32_array("udp_ports_table1", 0400,
+ ns->nsim_dev_port->ddir,
+ &ns->udp_ports.dfs_ports[1]);
+
+ debugfs_create_file("udp_ports_reset", 0200, ns->nsim_dev_port->ddir,
+ dev, &nsim_udp_tunnels_info_reset_fops);
+
+ /* Note: it's not normal to allocate the info struct like this!
+ * Drivers are expected to use a static const one, here we're testing.
+ */
+ info = kmemdup(&nsim_udp_tunnel_info, sizeof(nsim_udp_tunnel_info),
+ GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ ns->udp_ports.sleep = nsim_dev->udp_ports.sleep;
+
+ if (nsim_dev->udp_ports.sync_all) {
+ info->set_port = NULL;
+ info->unset_port = NULL;
+ } else {
+ info->sync_table = NULL;
+ }
+
+ if (ns->udp_ports.sleep)
+ info->flags |= UDP_TUNNEL_NIC_INFO_MAY_SLEEP;
+ if (nsim_dev->udp_ports.open_only)
+ info->flags |= UDP_TUNNEL_NIC_INFO_OPEN_ONLY;
+ if (nsim_dev->udp_ports.ipv4_only)
+ info->flags |= UDP_TUNNEL_NIC_INFO_IPV4_ONLY;
+
+ dev->udp_tunnel_nic_info = info;
+ return 0;
+}
+
+void nsim_udp_tunnels_info_destroy(struct net_device *dev)
+{
+ kfree(dev->udp_tunnel_nic_info);
+ dev->udp_tunnel_nic_info = NULL;
+}
+
+void nsim_udp_tunnels_debugfs_create(struct nsim_dev *nsim_dev)
+{
+ debugfs_create_bool("udp_ports_sync_all", 0600, nsim_dev->ddir,
+ &nsim_dev->udp_ports.sync_all);
+ debugfs_create_bool("udp_ports_open_only", 0600, nsim_dev->ddir,
+ &nsim_dev->udp_ports.open_only);
+ debugfs_create_bool("udp_ports_ipv4_only", 0600, nsim_dev->ddir,
+ &nsim_dev->udp_ports.ipv4_only);
+ debugfs_create_u32("udp_ports_sleep", 0600, nsim_dev->ddir,
+ &nsim_dev->udp_ports.sleep);
+}
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index e351d65533aa..726e4b240e7e 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -21,6 +21,9 @@ config MDIO_BUS
if MDIO_BUS
+config MDIO_DEVRES
+ tristate
+
config MDIO_ASPEED
tristate "ASPEED MDIO bus controller"
depends on ARCH_ASPEED || COMPILE_TEST
@@ -182,6 +185,7 @@ config MDIO_MOXART
config MDIO_MSCC_MIIM
tristate "Microsemi MIIM interface support"
depends on HAS_IOMEM
+ select MDIO_DEVRES
help
This driver supports the MIIM (MDIO) interface found in the network
switches of the Microsemi SoCs; it is recommended to switch on
@@ -190,6 +194,7 @@ config MDIO_MSCC_MIIM
config MDIO_MVUSB
tristate "Marvell USB to MDIO Adapter"
depends on USB
+ select MDIO_DEVRES
help
A USB to MDIO converter present on development boards for
Marvell's Link Street family of Ethernet switches.
@@ -252,6 +257,7 @@ menuconfig PHYLIB
tristate "PHY Device support and infrastructure"
depends on NETDEVICES
select MDIO_DEVICE
+ select MDIO_DEVRES
help
Ethernet controllers are usually attached to PHY
devices. This option provides infrastructure for
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index dc9e53b511d6..d84bab489a53 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -17,6 +17,7 @@ libphy-y += $(mdio-bus-y)
else
obj-$(CONFIG_MDIO_DEVICE) += mdio-bus.o
endif
+obj-$(CONFIG_MDIO_DEVRES) += mdio_devres.o
libphy-$(CONFIG_SWPHY) += swphy.o
libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_led_triggers.o
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index c7eabe4382fb..7471a8b90873 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -106,8 +106,8 @@
/**
* struct adin_cfg_reg_map - map a config value to aregister value
- * @cfg value in device configuration
- * @reg value in the register
+ * @cfg: value in device configuration
+ * @reg: value in the register
*/
struct adin_cfg_reg_map {
int cfg;
@@ -135,9 +135,9 @@ static const struct adin_cfg_reg_map adin_rmii_fifo_depths[] = {
/**
* struct adin_clause45_mmd_map - map to convert Clause 45 regs to Clause 22
- * @devad device address used in Clause 45 access
- * @cl45_regnum register address defined by Clause 45
- * @adin_regnum equivalent register address accessible via Clause 22
+ * @devad: device address used in Clause 45 access
+ * @cl45_regnum: register address defined by Clause 45
+ * @adin_regnum: equivalent register address accessible via Clause 22
*/
struct adin_clause45_mmd_map {
int devad;
@@ -174,7 +174,7 @@ static const struct adin_hw_stat adin_hw_stats[] = {
/**
* struct adin_priv - ADIN PHY driver private data
- * stats statistic counters for the PHY
+ * @stats: statistic counters for the PHY
*/
struct adin_priv {
u64 stats[ARRAY_SIZE(adin_hw_stats)];
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 97cbe593f0ea..101651b2de54 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -21,6 +21,17 @@
#include <linux/regulator/consumer.h>
#include <dt-bindings/net/qca-ar803x.h>
+#define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10
+#define AT803X_SFC_ASSERT_CRS BIT(11)
+#define AT803X_SFC_FORCE_LINK BIT(10)
+#define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5)
+#define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3
+#define AT803X_SFC_MANUAL_MDIX 0x1
+#define AT803X_SFC_MANUAL_MDI 0x0
+#define AT803X_SFC_SQE_TEST BIT(2)
+#define AT803X_SFC_POLARITY_REVERSAL BIT(1)
+#define AT803X_SFC_DISABLE_JABBER BIT(0)
+
#define AT803X_SPECIFIC_STATUS 0x11
#define AT803X_SS_SPEED_MASK (3 << 14)
#define AT803X_SS_SPEED_1000 (2 << 14)
@@ -400,8 +411,8 @@ static int at803x_parse_dt(struct phy_device *phydev)
{
struct device_node *node = phydev->mdio.dev.of_node;
struct at803x_priv *priv = phydev->priv;
- unsigned int sel, mask;
u32 freq, strength;
+ unsigned int sel;
int ret;
if (!IS_ENABLED(CONFIG_OF_MDIO))
@@ -409,7 +420,6 @@ static int at803x_parse_dt(struct phy_device *phydev)
ret = of_property_read_u32(node, "qca,clk-out-frequency", &freq);
if (!ret) {
- mask = AT803X_CLK_OUT_MASK;
switch (freq) {
case 25000000:
sel = AT803X_CLK_OUT_25MHZ_XTAL;
@@ -428,8 +438,8 @@ static int at803x_parse_dt(struct phy_device *phydev)
return -EINVAL;
}
- priv->clk_25m_reg |= FIELD_PREP(mask, sel);
- priv->clk_25m_mask |= mask;
+ priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel);
+ priv->clk_25m_mask |= AT803X_CLK_OUT_MASK;
/* Fixup for the AR8030/AR8035. This chip has another mask and
* doesn't support the DSP reference. Eg. the lowest bit of the
@@ -704,6 +714,12 @@ static int at803x_read_status(struct phy_device *phydev)
return ss;
if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
+ int sfc;
+
+ sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL);
+ if (sfc < 0)
+ return sfc;
+
switch (ss & AT803X_SS_SPEED_MASK) {
case AT803X_SS_SPEED_10:
phydev->speed = SPEED_10;
@@ -719,10 +735,23 @@ static int at803x_read_status(struct phy_device *phydev)
phydev->duplex = DUPLEX_FULL;
else
phydev->duplex = DUPLEX_HALF;
+
if (ss & AT803X_SS_MDIX)
phydev->mdix = ETH_TP_MDI_X;
else
phydev->mdix = ETH_TP_MDI;
+
+ switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) {
+ case AT803X_SFC_MANUAL_MDI:
+ phydev->mdix_ctrl = ETH_TP_MDI;
+ break;
+ case AT803X_SFC_MANUAL_MDIX:
+ phydev->mdix_ctrl = ETH_TP_MDI_X;
+ break;
+ case AT803X_SFC_AUTOMATIC_CROSSOVER:
+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
+ break;
+ }
}
if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
@@ -731,6 +760,50 @@ static int at803x_read_status(struct phy_device *phydev)
return 0;
}
+static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl)
+{
+ u16 val;
+
+ switch (ctrl) {
+ case ETH_TP_MDI:
+ val = AT803X_SFC_MANUAL_MDI;
+ break;
+ case ETH_TP_MDI_X:
+ val = AT803X_SFC_MANUAL_MDIX;
+ break;
+ case ETH_TP_MDI_AUTO:
+ val = AT803X_SFC_AUTOMATIC_CROSSOVER;
+ break;
+ default:
+ return 0;
+ }
+
+ return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL,
+ AT803X_SFC_MDI_CROSSOVER_MODE_M,
+ FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val));
+}
+
+static int at803x_config_aneg(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
+ if (ret < 0)
+ return ret;
+
+ /* Changes of the midx bits are disruptive to the normal operation;
+ * therefore any changes to these registers must be followed by a
+ * software reset to take effect.
+ */
+ if (ret == 1) {
+ ret = genphy_soft_reset(phydev);
+ if (ret < 0)
+ return ret;
+ }
+
+ return genphy_config_aneg(phydev);
+}
+
static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
{
int val;
@@ -980,6 +1053,7 @@ static struct phy_driver at803x_driver[] = {
.flags = PHY_POLL_CABLE_TEST,
.probe = at803x_probe,
.remove = at803x_remove,
+ .config_aneg = at803x_config_aneg,
.config_init = at803x_config_init,
.soft_reset = genphy_soft_reset,
.set_wol = at803x_set_wol,
@@ -1062,6 +1136,9 @@ static struct phy_driver at803x_driver[] = {
.config_intr = &at803x_config_intr,
.cable_test_start = at803x_cable_test_start,
.cable_test_get_status = at803x_cable_test_get_status,
+ .read_status = at803x_read_status,
+ .soft_reset = genphy_soft_reset,
+ .config_aneg = at803x_config_aneg,
} };
module_phy_driver(at803x_driver);
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index acb0aae60755..50fb7d16b75a 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -803,9 +803,10 @@ static int decode_evnt(struct dp83640_private *dp83640,
static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts)
{
- u16 *seqid, hash;
unsigned int offset = 0;
u8 *msgtype, *data = skb_mac_header(skb);
+ __be16 *seqid;
+ u16 hash;
/* check sequenceID, messageType, 12 bit hash of offset 20-29 */
@@ -836,7 +837,7 @@ static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts)
if (rxts->msgtype != (*msgtype & 0xf))
return 0;
- seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
+ seqid = (__be16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
if (rxts->seqid != ntohs(*seqid))
return 0;
diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
index 1dd19d0cb269..37643c468e19 100644
--- a/drivers/net/phy/dp83822.c
+++ b/drivers/net/phy/dp83822.c
@@ -26,7 +26,9 @@
#define MII_DP83822_PHYSCR 0x11
#define MII_DP83822_MISR1 0x12
#define MII_DP83822_MISR2 0x13
+#define MII_DP83822_RCSR 0x17
#define MII_DP83822_RESET_CTRL 0x1f
+#define MII_DP83822_GENCFG 0x465
#define DP83822_HW_RESET BIT(15)
#define DP83822_SW_RESET BIT(14)
@@ -77,6 +79,10 @@
#define DP83822_WOL_INDICATION_SEL BIT(8)
#define DP83822_WOL_CLR_INDICATION BIT(11)
+/* RSCR bits */
+#define DP83822_RX_CLK_SHIFT BIT(12)
+#define DP83822_TX_CLK_SHIFT BIT(11)
+
static int dp83822_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -255,7 +261,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
}
-static int dp83822_config_init(struct phy_device *phydev)
+static int dp8382x_disable_wol(struct phy_device *phydev)
{
int value = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN |
DP83822_WOL_SECURE_ON;
@@ -264,6 +270,46 @@ static int dp83822_config_init(struct phy_device *phydev)
MII_DP83822_WOL_CFG, value);
}
+static int dp83822_config_init(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int rgmii_delay;
+ s32 rx_int_delay;
+ s32 tx_int_delay;
+ int err = 0;
+
+ if (phy_interface_is_rgmii(phydev)) {
+ rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
+ true);
+
+ if (rx_int_delay <= 0)
+ rgmii_delay = 0;
+ else
+ rgmii_delay = DP83822_RX_CLK_SHIFT;
+
+ tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
+ false);
+ if (tx_int_delay <= 0)
+ rgmii_delay &= ~DP83822_TX_CLK_SHIFT;
+ else
+ rgmii_delay |= DP83822_TX_CLK_SHIFT;
+
+ if (rgmii_delay) {
+ err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
+ MII_DP83822_RCSR, rgmii_delay);
+ if (err)
+ return err;
+ }
+ }
+
+ return dp8382x_disable_wol(phydev);
+}
+
+static int dp8382x_config_init(struct phy_device *phydev)
+{
+ return dp8382x_disable_wol(phydev);
+}
+
static int dp83822_phy_reset(struct phy_device *phydev)
{
int err;
@@ -272,9 +318,7 @@ static int dp83822_phy_reset(struct phy_device *phydev)
if (err < 0)
return err;
- dp83822_config_init(phydev);
-
- return 0;
+ return phydev->drv->config_init(phydev);
}
static int dp83822_suspend(struct phy_device *phydev)
@@ -318,14 +362,29 @@ static int dp83822_resume(struct phy_device *phydev)
.resume = dp83822_resume, \
}
+#define DP8382X_PHY_DRIVER(_id, _name) \
+ { \
+ PHY_ID_MATCH_MODEL(_id), \
+ .name = (_name), \
+ /* PHY_BASIC_FEATURES */ \
+ .soft_reset = dp83822_phy_reset, \
+ .config_init = dp8382x_config_init, \
+ .get_wol = dp83822_get_wol, \
+ .set_wol = dp83822_set_wol, \
+ .ack_interrupt = dp83822_ack_interrupt, \
+ .config_intr = dp83822_config_intr, \
+ .suspend = dp83822_suspend, \
+ .resume = dp83822_resume, \
+ }
+
static struct phy_driver dp83822_driver[] = {
DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"),
- DP83822_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
- DP83822_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
- DP83822_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
- DP83822_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
- DP83822_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
- DP83822_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
+ DP8382X_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
+ DP8382X_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
+ DP8382X_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
+ DP8382X_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
+ DP8382X_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
+ DP8382X_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
};
module_phy_driver(dp83822_driver);
diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c
index 53ed3abc26c9..58103152c601 100644
--- a/drivers/net/phy/dp83869.c
+++ b/drivers/net/phy/dp83869.c
@@ -64,6 +64,10 @@
#define DP83869_RGMII_TX_CLK_DELAY_EN BIT(1)
#define DP83869_RGMII_RX_CLK_DELAY_EN BIT(0)
+/* RGMIIDCTL */
+#define DP83869_RGMII_CLK_DELAY_SHIFT 4
+#define DP83869_CLK_DELAY_DEF 7
+
/* STRAP_STS1 bits */
#define DP83869_STRAP_OP_MODE_MASK GENMASK(2, 0)
#define DP83869_STRAP_STS1_RESERVED BIT(11)
@@ -78,9 +82,6 @@
#define DP83869_PHYCR_FIFO_DEPTH_MASK GENMASK(15, 12)
#define DP83869_PHYCR_RESERVED_MASK BIT(11)
-/* RGMIIDCTL bits */
-#define DP83869_RGMII_TX_CLK_DELAY_SHIFT 4
-
/* IO_MUX_CFG bits */
#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL 0x1f
@@ -108,6 +109,8 @@ enum {
struct dp83869_private {
int tx_fifo_depth;
int rx_fifo_depth;
+ s32 rx_int_delay;
+ s32 tx_int_delay;
int io_impedance;
int port_mirroring;
bool rxctrl_strap_quirk;
@@ -177,11 +180,16 @@ static int dp83869_set_strapped_mode(struct phy_device *phydev)
}
#if IS_ENABLED(CONFIG_OF_MDIO)
+static const int dp83869_internal_delay[] = {250, 500, 750, 1000, 1250, 1500,
+ 1750, 2000, 2250, 2500, 2750, 3000,
+ 3250, 3500, 3750, 4000};
+
static int dp83869_of_init(struct phy_device *phydev)
{
struct dp83869_private *dp83869 = phydev->priv;
struct device *dev = &phydev->mdio.dev;
struct device_node *of_node = dev->of_node;
+ int delay_size = ARRAY_SIZE(dp83869_internal_delay);
int ret;
if (!of_node)
@@ -235,6 +243,20 @@ static int dp83869_of_init(struct phy_device *phydev)
&dp83869->tx_fifo_depth))
dp83869->tx_fifo_depth = DP83869_PHYCR_FIFO_DEPTH_4_B_NIB;
+ dp83869->rx_int_delay = phy_get_internal_delay(phydev, dev,
+ &dp83869_internal_delay[0],
+ delay_size, true);
+ if (dp83869->rx_int_delay < 0)
+ dp83869->rx_int_delay =
+ dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
+
+ dp83869->tx_int_delay = phy_get_internal_delay(phydev, dev,
+ &dp83869_internal_delay[0],
+ delay_size, false);
+ if (dp83869->tx_int_delay < 0)
+ dp83869->tx_int_delay =
+ dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
+
return ret;
}
#else
@@ -397,6 +419,31 @@ static int dp83869_config_init(struct phy_device *phydev)
dp83869->clk_output_sel <<
DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT);
+ if (phy_interface_is_rgmii(phydev)) {
+ ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIIDCTL,
+ dp83869->rx_int_delay |
+ dp83869->tx_int_delay << DP83869_RGMII_CLK_DELAY_SHIFT);
+ if (ret)
+ return ret;
+
+ val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL);
+ val &= ~(DP83869_RGMII_TX_CLK_DELAY_EN |
+ DP83869_RGMII_RX_CLK_DELAY_EN);
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+ val |= (DP83869_RGMII_TX_CLK_DELAY_EN |
+ DP83869_RGMII_RX_CLK_DELAY_EN);
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ val |= DP83869_RGMII_TX_CLK_DELAY_EN;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ val |= DP83869_RGMII_RX_CLK_DELAY_EN;
+
+ ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL,
+ val);
+ }
+
return ret;
}
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index c9ecf3c8c3fd..bb86ac0bd092 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -2625,12 +2625,12 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1101",
/* PHY_GBIT_FEATURES */
.probe = marvell_probe,
- .config_init = &marvell_config_init,
- .config_aneg = &m88e1101_config_aneg,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = marvell_config_init,
+ .config_aneg = m88e1101_config_aneg,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2643,12 +2643,12 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1112",
/* PHY_GBIT_FEATURES */
.probe = marvell_probe,
- .config_init = &m88e1111_config_init,
- .config_aneg = &marvell_config_aneg,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = m88e1111_config_init,
+ .config_aneg = marvell_config_aneg,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2663,13 +2663,13 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1111",
/* PHY_GBIT_FEATURES */
.probe = marvell_probe,
- .config_init = &m88e1111_config_init,
- .config_aneg = &marvell_config_aneg,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = m88e1111_config_init,
+ .config_aneg = marvell_config_aneg,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2684,12 +2684,12 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1118",
/* PHY_GBIT_FEATURES */
.probe = marvell_probe,
- .config_init = &m88e1118_config_init,
- .config_aneg = &m88e1118_config_aneg,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = m88e1118_config_init,
+ .config_aneg = m88e1118_config_aneg,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2701,15 +2701,15 @@ static struct phy_driver marvell_drivers[] = {
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "Marvell 88E1121R",
/* PHY_GBIT_FEATURES */
- .probe = &m88e1121_probe,
- .config_init = &marvell_config_init,
- .config_aneg = &m88e1121_config_aneg,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .did_interrupt = &m88e1121_did_interrupt,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .probe = m88e1121_probe,
+ .config_init = marvell_config_init,
+ .config_aneg = m88e1121_config_aneg,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .did_interrupt = m88e1121_did_interrupt,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2724,16 +2724,16 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1318S",
/* PHY_GBIT_FEATURES */
.probe = marvell_probe,
- .config_init = &m88e1318_config_init,
- .config_aneg = &m88e1318_config_aneg,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .did_interrupt = &m88e1121_did_interrupt,
- .get_wol = &m88e1318_get_wol,
- .set_wol = &m88e1318_set_wol,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = m88e1318_config_init,
+ .config_aneg = m88e1318_config_aneg,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .did_interrupt = m88e1121_did_interrupt,
+ .get_wol = m88e1318_get_wol,
+ .set_wol = m88e1318_set_wol,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2746,13 +2746,13 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1145",
/* PHY_GBIT_FEATURES */
.probe = marvell_probe,
- .config_init = &m88e1145_config_init,
- .config_aneg = &m88e1101_config_aneg,
- .read_status = &genphy_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = m88e1145_config_init,
+ .config_aneg = m88e1101_config_aneg,
+ .read_status = genphy_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2767,12 +2767,12 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1149R",
/* PHY_GBIT_FEATURES */
.probe = marvell_probe,
- .config_init = &m88e1149_config_init,
- .config_aneg = &m88e1118_config_aneg,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = m88e1149_config_init,
+ .config_aneg = m88e1118_config_aneg,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2785,12 +2785,12 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1240",
/* PHY_GBIT_FEATURES */
.probe = marvell_probe,
- .config_init = &m88e1111_config_init,
- .config_aneg = &marvell_config_aneg,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = m88e1111_config_init,
+ .config_aneg = marvell_config_aneg,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2803,11 +2803,11 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1116R",
/* PHY_GBIT_FEATURES */
.probe = marvell_probe,
- .config_init = &m88e1116r_config_init,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = m88e1116r_config_init,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2822,17 +2822,17 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1510",
.features = PHY_GBIT_FIBRE_FEATURES,
.flags = PHY_POLL_CABLE_TEST,
- .probe = &m88e1510_probe,
- .config_init = &m88e1510_config_init,
- .config_aneg = &m88e1510_config_aneg,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .did_interrupt = &m88e1121_did_interrupt,
- .get_wol = &m88e1318_get_wol,
- .set_wol = &m88e1318_set_wol,
- .resume = &marvell_resume,
- .suspend = &marvell_suspend,
+ .probe = m88e1510_probe,
+ .config_init = m88e1510_config_init,
+ .config_aneg = m88e1510_config_aneg,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .did_interrupt = m88e1121_did_interrupt,
+ .get_wol = m88e1318_get_wol,
+ .set_wol = m88e1318_set_wol,
+ .resume = marvell_resume,
+ .suspend = marvell_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2852,14 +2852,14 @@ static struct phy_driver marvell_drivers[] = {
/* PHY_GBIT_FEATURES */
.flags = PHY_POLL_CABLE_TEST,
.probe = m88e1510_probe,
- .config_init = &marvell_config_init,
- .config_aneg = &m88e1510_config_aneg,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .did_interrupt = &m88e1121_did_interrupt,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = marvell_config_init,
+ .config_aneg = m88e1510_config_aneg,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .did_interrupt = m88e1121_did_interrupt,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2878,14 +2878,14 @@ static struct phy_driver marvell_drivers[] = {
.probe = m88e1510_probe,
/* PHY_GBIT_FEATURES */
.flags = PHY_POLL_CABLE_TEST,
- .config_init = &marvell_config_init,
- .config_aneg = &m88e1510_config_aneg,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .did_interrupt = &m88e1121_did_interrupt,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = marvell_config_init,
+ .config_aneg = m88e1510_config_aneg,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .did_interrupt = m88e1121_did_interrupt,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2903,14 +2903,14 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E3016",
/* PHY_BASIC_FEATURES */
.probe = marvell_probe,
- .config_init = &m88e3016_config_init,
- .aneg_done = &marvell_aneg_done,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .did_interrupt = &m88e1121_did_interrupt,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = m88e3016_config_init,
+ .aneg_done = marvell_aneg_done,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .did_interrupt = m88e1121_did_interrupt,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2924,14 +2924,14 @@ static struct phy_driver marvell_drivers[] = {
/* PHY_GBIT_FEATURES */
.flags = PHY_POLL_CABLE_TEST,
.probe = m88e6390_probe,
- .config_init = &marvell_config_init,
- .config_aneg = &m88e6390_config_aneg,
- .read_status = &marvell_read_status,
- .ack_interrupt = &marvell_ack_interrupt,
- .config_intr = &marvell_config_intr,
- .did_interrupt = &m88e1121_did_interrupt,
- .resume = &genphy_resume,
- .suspend = &genphy_suspend,
+ .config_init = marvell_config_init,
+ .config_aneg = m88e6390_config_aneg,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .did_interrupt = m88e1121_did_interrupt,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
.read_page = marvell_read_page,
.write_page = marvell_write_page,
.get_sset_count = marvell_get_sset_count,
@@ -2943,6 +2943,50 @@ static struct phy_driver marvell_drivers[] = {
.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
.cable_test_get_status = marvell_vct7_cable_test_get_status,
},
+ {
+ .phy_id = MARVELL_PHY_ID_88E1340S,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "Marvell 88E1340S",
+ .probe = m88e1510_probe,
+ /* PHY_GBIT_FEATURES */
+ .config_init = marvell_config_init,
+ .config_aneg = m88e1510_config_aneg,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .did_interrupt = m88e1121_did_interrupt,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
+ .read_page = marvell_read_page,
+ .write_page = marvell_write_page,
+ .get_sset_count = marvell_get_sset_count,
+ .get_strings = marvell_get_strings,
+ .get_stats = marvell_get_stats,
+ .get_tunable = m88e1540_get_tunable,
+ .set_tunable = m88e1540_set_tunable,
+ },
+ {
+ .phy_id = MARVELL_PHY_ID_88E1548P,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "Marvell 88E1548P",
+ .probe = m88e1510_probe,
+ .features = PHY_GBIT_FIBRE_FEATURES,
+ .config_init = marvell_config_init,
+ .config_aneg = m88e1510_config_aneg,
+ .read_status = marvell_read_status,
+ .ack_interrupt = marvell_ack_interrupt,
+ .config_intr = marvell_config_intr,
+ .did_interrupt = m88e1121_did_interrupt,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
+ .read_page = marvell_read_page,
+ .write_page = marvell_write_page,
+ .get_sset_count = marvell_get_sset_count,
+ .get_strings = marvell_get_strings,
+ .get_stats = marvell_get_stats,
+ .get_tunable = m88e1540_get_tunable,
+ .set_tunable = m88e1540_set_tunable,
+ },
};
module_phy_driver(marvell_drivers);
@@ -2963,6 +3007,8 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = {
{ MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E6390, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E1340S, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E1548P, MARVELL_PHY_ID_MASK },
{ }
};
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index d4c2e62b2439..a7610eb55f30 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -80,6 +80,8 @@ enum {
MV_V2_PORT_CTRL = 0xf001,
MV_V2_PORT_CTRL_SWRST = BIT(15),
MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
+ MV_V2_PORT_MAC_TYPE_MASK = 0x7,
+ MV_V2_PORT_MAC_TYPE_RATE_MATCH = 0x6,
/* Temperature control/read registers (88X3310 only) */
MV_V2_TEMP_CTRL = 0xf08a,
MV_V2_TEMP_CTRL_MASK = 0xc000,
@@ -91,6 +93,7 @@ enum {
struct mv3310_priv {
u32 firmware_ver;
+ bool rate_match;
struct device *hwmon_dev;
char *hwmon_name;
@@ -458,7 +461,9 @@ static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev)
static int mv3310_config_init(struct phy_device *phydev)
{
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
int err;
+ int val;
/* Check that the PHY interface type is compatible */
if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
@@ -475,6 +480,12 @@ static int mv3310_config_init(struct phy_device *phydev)
if (err)
return err;
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
+ if (val < 0)
+ return val;
+ priv->rate_match = ((val & MV_V2_PORT_MAC_TYPE_MASK) ==
+ MV_V2_PORT_MAC_TYPE_RATE_MATCH);
+
/* Enable EDPD mode - saving 600mW */
return mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS);
}
@@ -581,6 +592,17 @@ static int mv3310_aneg_done(struct phy_device *phydev)
static void mv3310_update_interface(struct phy_device *phydev)
{
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
+
+ /* In "XFI with Rate Matching" mode the PHY interface is fixed at
+ * 10Gb. The PHY adapts the rate to actual wire speed with help of
+ * internal 16KB buffer.
+ */
+ if (priv->rate_match) {
+ phydev->interface = PHY_INTERFACE_MODE_10GBASER;
+ return;
+ }
+
if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
phydev->interface == PHY_INTERFACE_MODE_10GBASER) &&
diff --git a/drivers/net/phy/mdio-boardinfo.c b/drivers/net/phy/mdio-boardinfo.c
index d9b54c67ef9f..033df435f76c 100644
--- a/drivers/net/phy/mdio-boardinfo.c
+++ b/drivers/net/phy/mdio-boardinfo.c
@@ -17,7 +17,8 @@ static DEFINE_MUTEX(mdio_board_lock);
/**
* mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices
* from pre-collected board specific MDIO information
- * @mdiodev: MDIO device pointer
+ * @bus: Bus the board_info belongs to
+ * @cb: Callback to create device on bus
* Context: can sleep
*/
void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus,
diff --git a/drivers/net/phy/mdio-cavium.h b/drivers/net/phy/mdio-cavium.h
index e33d3ea9a907..a2245d436f5d 100644
--- a/drivers/net/phy/mdio-cavium.h
+++ b/drivers/net/phy/mdio-cavium.h
@@ -90,7 +90,7 @@ union cvmx_smix_wr_dat {
struct cavium_mdiobus {
struct mii_bus *mii_bus;
- u64 register_base;
+ void __iomem *register_base;
enum cavium_mdiobus_mode mode;
};
@@ -98,20 +98,20 @@ struct cavium_mdiobus {
#include <asm/octeon/octeon.h>
-static inline void oct_mdio_writeq(u64 val, u64 addr)
+static inline void oct_mdio_writeq(u64 val, void __iomem *addr)
{
- cvmx_write_csr(addr, val);
+ cvmx_write_csr((u64 __force)addr, val);
}
-static inline u64 oct_mdio_readq(u64 addr)
+static inline u64 oct_mdio_readq(void __iomem *addr)
{
- return cvmx_read_csr(addr);
+ return cvmx_read_csr((u64 __force)addr);
}
#else
#include <linux/io-64-nonatomic-lo-hi.h>
-#define oct_mdio_writeq(val, addr) writeq(val, (void *)addr)
-#define oct_mdio_readq(addr) readq((void *)addr)
+#define oct_mdio_writeq(val, addr) writeq(val, addr)
+#define oct_mdio_readq(addr) readq(addr)
#endif
int cavium_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum);
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c
index 6c8960df43b0..10a758fdc9e6 100644
--- a/drivers/net/phy/mdio-mux-gpio.c
+++ b/drivers/net/phy/mdio-mux-gpio.c
@@ -42,25 +42,21 @@ static int mdio_mux_gpio_probe(struct platform_device *pdev)
struct gpio_descs *gpios;
int r;
- gpios = gpiod_get_array(&pdev->dev, NULL, GPIOD_OUT_LOW);
+ gpios = devm_gpiod_get_array(&pdev->dev, NULL, GPIOD_OUT_LOW);
if (IS_ERR(gpios))
return PTR_ERR(gpios);
s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
- if (!s) {
- gpiod_put_array(gpios);
+ if (!s)
return -ENOMEM;
- }
s->gpios = gpios;
r = mdio_mux_init(&pdev->dev, pdev->dev.of_node,
mdio_mux_gpio_switch_fn, &s->mux_handle, s, NULL);
- if (r != 0) {
- gpiod_put_array(s->gpios);
+ if (r != 0)
return r;
- }
pdev->dev.platform_data = s;
return 0;
@@ -70,7 +66,6 @@ static int mdio_mux_gpio_remove(struct platform_device *pdev)
{
struct mdio_mux_gpio_state *s = dev_get_platdata(&pdev->dev);
mdio_mux_uninit(s->mux_handle);
- gpiod_put_array(s->gpios);
return 0;
}
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index 8327382aa568..d1e1009d51af 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -44,8 +44,7 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
return -ENXIO;
}
- bus->register_base =
- (u64)devm_ioremap(&pdev->dev, mdio_phys, regsize);
+ bus->register_base = devm_ioremap(&pdev->dev, mdio_phys, regsize);
if (!bus->register_base) {
dev_err(&pdev->dev, "dev_ioremap failed\n");
return -ENOMEM;
@@ -56,7 +55,7 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN);
bus->mii_bus->name = KBUILD_MODNAME;
- snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", bus->register_base);
+ snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%px", bus->register_base);
bus->mii_bus->parent = &pdev->dev;
bus->mii_bus->read = cavium_mdiobus_read;
@@ -109,12 +108,6 @@ static struct platform_driver octeon_mdiobus_driver = {
.remove = octeon_mdiobus_remove,
};
-void octeon_mdiobus_force_mod_depencency(void)
-{
- /* Let ethernet drivers force us to be loaded. */
-}
-EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency);
-
module_platform_driver(octeon_mdiobus_driver);
MODULE_DESCRIPTION("Cavium OCTEON MDIO bus driver");
diff --git a/drivers/net/phy/mdio-thunder.c b/drivers/net/phy/mdio-thunder.c
index 2a97938d1972..3d7eda99d34e 100644
--- a/drivers/net/phy/mdio-thunder.c
+++ b/drivers/net/phy/mdio-thunder.c
@@ -84,7 +84,7 @@ static int thunder_mdiobus_pci_probe(struct pci_dev *pdev,
nexus->buses[i] = bus;
i++;
- bus->register_base = (u64)nexus->bar0 +
+ bus->register_base = nexus->bar0 +
r.start - pci_resource_start(pdev, 0);
smi_en.u64 = 0;
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 6ceee82b2839..0af20faad69d 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -8,32 +8,32 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mii.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
#include <linux/of_device.h>
-#include <linux/of_mdio.h>
#include <linux/of_gpio.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
#include <linux/reset.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/phy.h>
-#include <linux/io.h>
+#include <linux/string.h>
#include <linux/uaccess.h>
+#include <linux/unistd.h>
#define CREATE_TRACE_POINTS
#include <trace/events/mdio.h>
@@ -165,79 +165,6 @@ struct mii_bus *mdiobus_alloc_size(size_t size)
}
EXPORT_SYMBOL(mdiobus_alloc_size);
-static void _devm_mdiobus_free(struct device *dev, void *res)
-{
- struct mii_bus *bus = *(struct mii_bus **)res;
-
- if (bus->is_managed_registered && bus->state == MDIOBUS_REGISTERED)
- mdiobus_unregister(bus);
-
- mdiobus_free(bus);
-}
-
-static int devm_mdiobus_match(struct device *dev, void *res, void *data)
-{
- struct mii_bus **r = res;
-
- if (WARN_ON(!r || !*r))
- return 0;
-
- return *r == data;
-}
-
-/**
- * devm_mdiobus_alloc_size - Resource-managed mdiobus_alloc_size()
- * @dev: Device to allocate mii_bus for
- * @sizeof_priv: Space to allocate for private structure.
- *
- * Managed mdiobus_alloc_size. mii_bus allocated with this function is
- * automatically freed on driver detach.
- *
- * If an mii_bus allocated with this function needs to be freed separately,
- * devm_mdiobus_free() must be used.
- *
- * RETURNS:
- * Pointer to allocated mii_bus on success, NULL on failure.
- */
-struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv)
-{
- struct mii_bus **ptr, *bus;
-
- ptr = devres_alloc(_devm_mdiobus_free, sizeof(*ptr), GFP_KERNEL);
- if (!ptr)
- return NULL;
-
- /* use raw alloc_dr for kmalloc caller tracing */
- bus = mdiobus_alloc_size(sizeof_priv);
- if (bus) {
- *ptr = bus;
- devres_add(dev, ptr);
- bus->is_managed = 1;
- } else {
- devres_free(ptr);
- }
-
- return bus;
-}
-EXPORT_SYMBOL_GPL(devm_mdiobus_alloc_size);
-
-/**
- * devm_mdiobus_free - Resource-managed mdiobus_free()
- * @dev: Device this mii_bus belongs to
- * @bus: the mii_bus associated with the device
- *
- * Free mii_bus allocated with devm_mdiobus_alloc_size().
- */
-void devm_mdiobus_free(struct device *dev, struct mii_bus *bus)
-{
- int rc;
-
- rc = devres_release(dev, _devm_mdiobus_free,
- devm_mdiobus_match, bus);
- WARN_ON(rc);
-}
-EXPORT_SYMBOL_GPL(devm_mdiobus_free);
-
/**
* mdiobus_release - mii_bus device release callback
* @d: the target struct device that contains the mii_bus
@@ -627,8 +554,10 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
bus->reset_gpiod = gpiod;
gpiod_set_value_cansleep(gpiod, 1);
- udelay(bus->reset_delay_us);
+ fsleep(bus->reset_delay_us);
gpiod_set_value_cansleep(gpiod, 0);
+ if (bus->reset_post_delay_us > 0)
+ fsleep(bus->reset_post_delay_us);
}
if (bus->reset) {
@@ -739,10 +668,24 @@ EXPORT_SYMBOL(mdiobus_free);
*/
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
{
- struct phy_device *phydev;
+ struct phy_device *phydev = ERR_PTR(-ENODEV);
int err;
- phydev = get_phy_device(bus, addr, false);
+ switch (bus->probe_capabilities) {
+ case MDIOBUS_NO_CAP:
+ case MDIOBUS_C22:
+ phydev = get_phy_device(bus, addr, false);
+ break;
+ case MDIOBUS_C45:
+ phydev = get_phy_device(bus, addr, true);
+ break;
+ case MDIOBUS_C22_C45:
+ phydev = get_phy_device(bus, addr, false);
+ if (IS_ERR(phydev))
+ phydev = get_phy_device(bus, addr, true);
+ break;
+ }
+
if (IS_ERR(phydev))
return phydev;
diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
index c1d345c3cab3..0837319a52d7 100644
--- a/drivers/net/phy/mdio_device.c
+++ b/drivers/net/phy/mdio_device.c
@@ -6,6 +6,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
@@ -20,7 +21,6 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/unistd.h>
-#include <linux/delay.h>
void mdio_device_free(struct mdio_device *mdiodev)
{
@@ -132,7 +132,7 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value)
d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay;
if (d)
- usleep_range(d, d + max_t(unsigned int, d / 10, 100));
+ fsleep(d);
}
EXPORT_SYMBOL(mdio_device_reset);
@@ -150,10 +150,10 @@ static int mdio_probe(struct device *dev)
struct mdio_driver *mdiodrv = to_mdio_driver(drv);
int err = 0;
- if (mdiodrv->probe) {
- /* Deassert the reset signal */
- mdio_device_reset(mdiodev, 0);
+ /* Deassert the reset signal */
+ mdio_device_reset(mdiodev, 0);
+ if (mdiodrv->probe) {
err = mdiodrv->probe(mdiodev);
if (err) {
/* Assert the reset signal */
@@ -170,19 +170,18 @@ static int mdio_remove(struct device *dev)
struct device_driver *drv = mdiodev->dev.driver;
struct mdio_driver *mdiodrv = to_mdio_driver(drv);
- if (mdiodrv->remove) {
+ if (mdiodrv->remove)
mdiodrv->remove(mdiodev);
- /* Assert the reset signal */
- mdio_device_reset(mdiodev, 1);
- }
+ /* Assert the reset signal */
+ mdio_device_reset(mdiodev, 1);
return 0;
}
/**
* mdio_driver_register - register an mdio_driver with the MDIO layer
- * @new_driver: new mdio_driver to register
+ * @drv: new mdio_driver to register
*/
int mdio_driver_register(struct mdio_driver *drv)
{
diff --git a/drivers/net/phy/mdio_devres.c b/drivers/net/phy/mdio_devres.c
new file mode 100644
index 000000000000..b560e99695df
--- /dev/null
+++ b/drivers/net/phy/mdio_devres.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/device.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/stddef.h>
+
+struct mdiobus_devres {
+ struct mii_bus *mii;
+};
+
+static void devm_mdiobus_free(struct device *dev, void *this)
+{
+ struct mdiobus_devres *dr = this;
+
+ mdiobus_free(dr->mii);
+}
+
+/**
+ * devm_mdiobus_alloc_size - Resource-managed mdiobus_alloc_size()
+ * @dev: Device to allocate mii_bus for
+ * @sizeof_priv: Space to allocate for private structure
+ *
+ * Managed mdiobus_alloc_size. mii_bus allocated with this function is
+ * automatically freed on driver detach.
+ *
+ * RETURNS:
+ * Pointer to allocated mii_bus on success, NULL on out-of-memory error.
+ */
+struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv)
+{
+ struct mdiobus_devres *dr;
+
+ dr = devres_alloc(devm_mdiobus_free, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return NULL;
+
+ dr->mii = mdiobus_alloc_size(sizeof_priv);
+ if (!dr->mii) {
+ devres_free(dr);
+ return NULL;
+ }
+
+ devres_add(dev, dr);
+ return dr->mii;
+}
+EXPORT_SYMBOL(devm_mdiobus_alloc_size);
+
+static void devm_mdiobus_unregister(struct device *dev, void *this)
+{
+ struct mdiobus_devres *dr = this;
+
+ mdiobus_unregister(dr->mii);
+}
+
+static int mdiobus_devres_match(struct device *dev,
+ void *this, void *match_data)
+{
+ struct mdiobus_devres *res = this;
+ struct mii_bus *mii = match_data;
+
+ return mii == res->mii;
+}
+
+/**
+ * __devm_mdiobus_register - Resource-managed variant of mdiobus_register()
+ * @dev: Device to register mii_bus for
+ * @bus: MII bus structure to register
+ * @owner: Owning module
+ *
+ * Returns 0 on success, negative error number on failure.
+ */
+int __devm_mdiobus_register(struct device *dev, struct mii_bus *bus,
+ struct module *owner)
+{
+ struct mdiobus_devres *dr;
+ int ret;
+
+ if (WARN_ON(!devres_find(dev, devm_mdiobus_free,
+ mdiobus_devres_match, bus)))
+ return -EINVAL;
+
+ dr = devres_alloc(devm_mdiobus_unregister, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return -ENOMEM;
+
+ ret = __mdiobus_register(bus, owner);
+ if (ret) {
+ devres_free(dr);
+ return ret;
+ }
+
+ dr->mii = bus;
+ devres_add(dev, dr);
+ return 0;
+}
+EXPORT_SYMBOL(__devm_mdiobus_register);
+
+#if IS_ENABLED(CONFIG_OF_MDIO)
+/**
+ * devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register()
+ * @dev: Device to register mii_bus for
+ * @mdio: MII bus structure to register
+ * @np: Device node to parse
+ */
+int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
+ struct device_node *np)
+{
+ struct mdiobus_devres *dr;
+ int ret;
+
+ if (WARN_ON(!devres_find(dev, devm_mdiobus_free,
+ mdiobus_devres_match, mdio)))
+ return -EINVAL;
+
+ dr = devres_alloc(devm_mdiobus_unregister, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return -ENOMEM;
+
+ ret = of_mdiobus_register(mdio, np);
+ if (ret) {
+ devres_free(dr);
+ return ret;
+ }
+
+ dr->mii = mdio;
+ devres_add(dev, dr);
+ return 0;
+}
+EXPORT_SYMBOL(devm_of_mdiobus_register);
+#endif /* CONFIG_OF_MDIO */
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/phy/mscc/Makefile b/drivers/net/phy/mscc/Makefile
index 10af42cd9839..d8e22a4eeeff 100644
--- a/drivers/net/phy/mscc/Makefile
+++ b/drivers/net/phy/mscc/Makefile
@@ -8,3 +8,7 @@ mscc-objs := mscc_main.o
ifdef CONFIG_MACSEC
mscc-objs += mscc_macsec.o
endif
+
+ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
+mscc-objs += mscc_ptp.o
+endif
diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
index fbcee5fce7b2..9481bce94c2e 100644
--- a/drivers/net/phy/mscc/mscc.h
+++ b/drivers/net/phy/mscc/mscc.h
@@ -133,6 +133,7 @@ enum rgmii_clock_delay {
* in the same package.
*/
#define MSCC_PHY_PAGE_EXTENDED_GPIO 0x0010 /* Extended reg - GPIO */
+#define MSCC_PHY_PAGE_1588 0x1588 /* PTP (1588) */
#define MSCC_PHY_PAGE_TEST 0x2a30 /* Test reg */
#define MSCC_PHY_PAGE_TR 0x52b5 /* Token ring registers */
@@ -252,6 +253,7 @@ enum rgmii_clock_delay {
/* Test page Registers */
#define MSCC_PHY_TEST_PAGE_5 5
#define MSCC_PHY_TEST_PAGE_8 8
+#define TR_CLK_DISABLE 0x8000
#define MSCC_PHY_TEST_PAGE_9 9
#define MSCC_PHY_TEST_PAGE_20 20
#define MSCC_PHY_TEST_PAGE_24 24
@@ -372,6 +374,35 @@ struct vsc8531_private {
unsigned long ingr_flows;
unsigned long egr_flows;
#endif
+
+ struct mii_timestamper mii_ts;
+
+ bool input_clk_init;
+ struct vsc85xx_ptp *ptp;
+ /* LOAD/SAVE GPIO pin, used for retrieving or setting time to the PHC. */
+ struct gpio_desc *load_save;
+
+ /* For multiple port PHYs; the MDIO address of the base PHY in the
+ * pair of two PHYs that share a 1588 engine. PHY0 and PHY2 are coupled.
+ * PHY1 and PHY3 as well. PHY0 and PHY1 are base PHYs for their
+ * respective pair.
+ */
+ unsigned int ts_base_addr;
+ u8 ts_base_phy;
+
+ /* ts_lock: used for per-PHY timestamping operations.
+ * phc_lock: used for per-PHY PHC opertations.
+ */
+ struct mutex ts_lock;
+ struct mutex phc_lock;
+};
+
+/* Shared structure between the PHYs of the same package.
+ * gpio_lock: used for PHC operations. Common for all PHYs as the load/save GPIO
+ * is shared.
+ */
+struct vsc85xx_shared_private {
+ struct mutex gpio_lock;
};
#if IS_ENABLED(CONFIG_OF_MDIO)
@@ -398,4 +429,36 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
}
#endif
+#if IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING)
+void vsc85xx_link_change_notify(struct phy_device *phydev);
+void vsc8584_config_ts_intr(struct phy_device *phydev);
+int vsc8584_ptp_init(struct phy_device *phydev);
+int vsc8584_ptp_probe_once(struct phy_device *phydev);
+int vsc8584_ptp_probe(struct phy_device *phydev);
+irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+#else
+static inline void vsc85xx_link_change_notify(struct phy_device *phydev)
+{
+}
+static inline void vsc8584_config_ts_intr(struct phy_device *phydev)
+{
+}
+static inline int vsc8584_ptp_init(struct phy_device *phydev)
+{
+ return 0;
+}
+static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+{
+ return 0;
+}
+static inline int vsc8584_ptp_probe(struct phy_device *phydev)
+{
+ return 0;
+}
+static inline irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+{
+ return IRQ_NONE;
+}
+#endif
+
#endif /* _MSCC_PHY_H_ */
diff --git a/drivers/net/phy/mscc/mscc_fc_buffer.h b/drivers/net/phy/mscc/mscc_fc_buffer.h
index 3803e826c37d..399e803395a5 100644
--- a/drivers/net/phy/mscc/mscc_fc_buffer.h
+++ b/drivers/net/phy/mscc/mscc_fc_buffer.h
@@ -2,7 +2,7 @@
/*
* Driver for Microsemi VSC85xx PHYs
*
- * Copyright (C) 2019 Microsemi Corporation
+ * Copyright (C) 2020 Microsemi Corporation
*/
#ifndef _MSCC_PHY_FC_BUFFER_H_
diff --git a/drivers/net/phy/mscc/mscc_mac.h b/drivers/net/phy/mscc/mscc_mac.h
index 59b6837c60b3..8dd38dc6edbf 100644
--- a/drivers/net/phy/mscc/mscc_mac.h
+++ b/drivers/net/phy/mscc/mscc_mac.h
@@ -2,7 +2,7 @@
/*
* Driver for Microsemi VSC85xx PHYs
*
- * Copyright (c) 2017 Microsemi Corporation
+ * Copyright (c) 2020 Microsemi Corporation
*/
#ifndef _MSCC_PHY_LINE_MAC_H_
diff --git a/drivers/net/phy/mscc/mscc_macsec.c b/drivers/net/phy/mscc/mscc_macsec.c
index d53ca884b5c9..1d4c012194e9 100644
--- a/drivers/net/phy/mscc/mscc_macsec.c
+++ b/drivers/net/phy/mscc/mscc_macsec.c
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
- * Driver for Microsemi VSC85xx PHYs
+ * Driver for Microsemi VSC85xx PHYs - MACsec support
*
- * Author: Nagaraju Lakkaraju
+ * Author: Antoine Tenart
* License: Dual MIT/GPL
- * Copyright (c) 2016 Microsemi Corporation
+ * Copyright (c) 2020 Microsemi Corporation
*/
#include <linux/phy.h>
@@ -285,7 +285,9 @@ static void vsc8584_macsec_mac_init(struct phy_device *phydev,
MSCC_MAC_CFG_PKTINF_CFG_STRIP_PREAMBLE_ENA |
MSCC_MAC_CFG_PKTINF_CFG_INSERT_PREAMBLE_ENA |
(bank == HOST_MAC ?
- MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING : 0));
+ MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING : 0) |
+ (IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING) ?
+ MSCC_MAC_CFG_PKTINF_CFG_MACSEC_BYPASS_NUM_PTP_STALL_CLKS(0x8) : 0));
val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MODE_CFG);
val &= ~MSCC_MAC_CFG_MODE_CFG_DISABLE_DIC;
@@ -383,21 +385,23 @@ static void vsc8584_macsec_flow(struct phy_device *phydev,
}
if (bank == MACSEC_INGR && flow->match.sci && flow->rx_sa->sc->sci) {
+ u64 sci = (__force u64)flow->rx_sa->sc->sci;
+
match |= MSCC_MS_SAM_MISC_MATCH_TCI(BIT(3));
mask |= MSCC_MS_SAM_MASK_TCI_MASK(BIT(3)) |
MSCC_MS_SAM_MASK_SCI_MASK;
vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MATCH_SCI_LO(idx),
- lower_32_bits(flow->rx_sa->sc->sci));
+ lower_32_bits(sci));
vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MATCH_SCI_HI(idx),
- upper_32_bits(flow->rx_sa->sc->sci));
+ upper_32_bits(sci));
}
if (flow->match.etype) {
mask |= MSCC_MS_SAM_MASK_MAC_ETYPE_MASK;
vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_MAC_SA_MATCH_HI(idx),
- MSCC_MS_SAM_MAC_SA_MATCH_HI_ETYPE(htons(flow->etype)));
+ MSCC_MS_SAM_MAC_SA_MATCH_HI_ETYPE((__force u32)htons(flow->etype)));
}
match |= MSCC_MS_SAM_MISC_MATCH_PRIORITY(flow->priority);
@@ -521,7 +525,7 @@ static int vsc8584_macsec_transformation(struct phy_device *phydev,
int i, ret, index = flow->index;
u32 rec = 0, control = 0;
u8 hkey[16];
- sci_t sci;
+ u64 sci;
ret = vsc8584_macsec_derive_key(flow->key, priv->secy->key_len, hkey);
if (ret)
@@ -579,7 +583,7 @@ static int vsc8584_macsec_transformation(struct phy_device *phydev,
priv->secy->replay_window);
/* Set the input vectors */
- sci = bank == MACSEC_INGR ? flow->rx_sa->sc->sci : priv->secy->sci;
+ sci = (__force u64)(bank == MACSEC_INGR ? flow->rx_sa->sc->sci : priv->secy->sci);
vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
lower_32_bits(sci));
vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_XFORM_REC(index, rec++),
diff --git a/drivers/net/phy/mscc/mscc_macsec.h b/drivers/net/phy/mscc/mscc_macsec.h
index d751f2946b79..9c6d25e36de2 100644
--- a/drivers/net/phy/mscc/mscc_macsec.h
+++ b/drivers/net/phy/mscc/mscc_macsec.h
@@ -2,7 +2,7 @@
/*
* Driver for Microsemi VSC85xx PHYs
*
- * Copyright (c) 2018 Microsemi Corporation
+ * Copyright (c) 2020 Microsemi Corporation
*/
#ifndef _MSCC_PHY_MACSEC_H_
diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
index 5ddc44f87eaf..a4fbf3a4fa97 100644
--- a/drivers/net/phy/mscc/mscc_main.c
+++ b/drivers/net/phy/mscc/mscc_main.c
@@ -629,7 +629,7 @@ static int vsc8531_pre_init_seq_set(struct phy_device *phydev)
if (rc < 0)
return rc;
rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_TEST,
- MSCC_PHY_TEST_PAGE_8, 0x8000, 0x8000);
+ MSCC_PHY_TEST_PAGE_8, TR_CLK_DISABLE, TR_CLK_DISABLE);
if (rc < 0)
return rc;
@@ -1026,7 +1026,7 @@ static int vsc8574_config_pre_init(struct phy_device *phydev)
phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1b20);
reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
- reg |= 0x8000;
+ reg |= TR_CLK_DISABLE;
phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
@@ -1046,7 +1046,7 @@ static int vsc8574_config_pre_init(struct phy_device *phydev)
phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
- reg &= ~0x8000;
+ reg &= ~TR_CLK_DISABLE;
phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
@@ -1196,7 +1196,7 @@ static int vsc8584_config_pre_init(struct phy_device *phydev)
phy_base_write(phydev, MSCC_PHY_TEST_PAGE_5, 0x1f20);
reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
- reg |= 0x8000;
+ reg |= TR_CLK_DISABLE;
phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
@@ -1225,7 +1225,7 @@ static int vsc8584_config_pre_init(struct phy_device *phydev)
phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
reg = phy_base_read(phydev, MSCC_PHY_TEST_PAGE_8);
- reg &= ~0x8000;
+ reg &= ~TR_CLK_DISABLE;
phy_base_write(phydev, MSCC_PHY_TEST_PAGE_8, reg);
phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
@@ -1288,7 +1288,7 @@ static void vsc8584_get_base_addr(struct phy_device *phydev)
struct vsc8531_private *vsc8531 = phydev->priv;
u16 val, addr;
- mutex_lock(&phydev->mdio.bus->mdio_lock);
+ phy_lock_mdio_bus(phydev);
__phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
addr = __phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_4);
@@ -1297,12 +1297,28 @@ static void vsc8584_get_base_addr(struct phy_device *phydev)
val = __phy_read(phydev, MSCC_PHY_ACTIPHY_CNTL);
__phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
+ phy_unlock_mdio_bus(phydev);
- if (val & PHY_ADDR_REVERSED)
+ /* In the package, there are two pairs of PHYs (PHY0 + PHY2 and
+ * PHY1 + PHY3). The first PHY of each pair (PHY0 and PHY1) is
+ * the base PHY for timestamping operations.
+ */
+ vsc8531->ts_base_addr = phydev->mdio.addr;
+ vsc8531->ts_base_phy = addr;
+
+ if (val & PHY_ADDR_REVERSED) {
vsc8531->base_addr = phydev->mdio.addr + addr;
- else
+ if (addr > 1) {
+ vsc8531->ts_base_addr += 2;
+ vsc8531->ts_base_phy += 2;
+ }
+ } else {
vsc8531->base_addr = phydev->mdio.addr - addr;
+ if (addr > 1) {
+ vsc8531->ts_base_addr -= 2;
+ vsc8531->ts_base_phy -= 2;
+ }
+ }
vsc8531->addr = addr;
}
@@ -1315,7 +1331,7 @@ static int vsc8584_config_init(struct phy_device *phydev)
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
- mutex_lock(&phydev->mdio.bus->mdio_lock);
+ phy_lock_mdio_bus(phydev);
/* Some parts of the init sequence are identical for every PHY in the
* package. Some parts are modifying the GPIO register bank which is a
@@ -1359,8 +1375,10 @@ static int vsc8584_config_init(struct phy_device *phydev)
goto err;
}
- phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
- MSCC_PHY_PAGE_EXTENDED_GPIO);
+ ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXTENDED_GPIO);
+ if (ret)
+ goto err;
val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
val &= ~MAC_CFG_MASK;
@@ -1379,6 +1397,11 @@ static int vsc8584_config_init(struct phy_device *phydev)
if (ret)
goto err;
+ ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STANDARD);
+ if (ret)
+ goto err;
+
if (!phy_interface_is_rgmii(phydev)) {
val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
PROC_CMD_READ_MOD_WRITE_PORT;
@@ -1412,13 +1435,15 @@ static int vsc8584_config_init(struct phy_device *phydev)
if (ret)
goto err;
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
+ phy_unlock_mdio_bus(phydev);
ret = vsc8584_macsec_init(phydev);
if (ret)
return ret;
- phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+ ret = vsc8584_ptp_init(phydev);
+ if (ret)
+ return ret;
val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
@@ -1449,18 +1474,26 @@ static int vsc8584_config_init(struct phy_device *phydev)
return 0;
err:
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
+ phy_unlock_mdio_bus(phydev);
return ret;
}
static irqreturn_t vsc8584_handle_interrupt(struct phy_device *phydev)
{
+ irqreturn_t ret;
int irq_status;
irq_status = phy_read(phydev, MII_VSC85XX_INT_STATUS);
- if (irq_status < 0 || !(irq_status & MII_VSC85XX_INT_MASK_MASK))
+ if (irq_status < 0)
return IRQ_NONE;
+ /* Timestamping IRQ does not set a bit in the global INT_STATUS, so
+ * irq_status would be 0.
+ */
+ ret = vsc8584_handle_ts_interrupt(phydev);
+ if (!(irq_status & MII_VSC85XX_INT_MASK_MASK))
+ return ret;
+
if (irq_status & MII_VSC85XX_INT_MASK_EXT)
vsc8584_handle_macsec_interrupt(phydev);
@@ -1727,7 +1760,7 @@ static int vsc8514_config_init(struct phy_device *phydev)
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
- mutex_lock(&phydev->mdio.bus->mdio_lock);
+ phy_lock_mdio_bus(phydev);
/* Some parts of the init sequence are identical for every PHY in the
* package. Some parts are modifying the GPIO register bank which is a
@@ -1743,15 +1776,21 @@ static int vsc8514_config_init(struct phy_device *phydev)
if (phy_package_init_once(phydev))
vsc8514_config_pre_init(phydev);
- phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
- MSCC_PHY_PAGE_EXTENDED_GPIO);
+ ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXTENDED_GPIO);
+ if (ret)
+ goto err;
val = phy_base_read(phydev, MSCC_PHY_MAC_CFG_FASTLINK);
val &= ~MAC_CFG_MASK;
val |= MAC_CFG_QSGMII;
ret = phy_base_write(phydev, MSCC_PHY_MAC_CFG_FASTLINK, val);
+ if (ret)
+ goto err;
+ ret = phy_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STANDARD);
if (ret)
goto err;
@@ -1815,14 +1854,14 @@ static int vsc8514_config_init(struct phy_device *phydev)
reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
PHY_S6G_PLL_STATUS);
if (reg == 0xffffffff) {
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
+ phy_unlock_mdio_bus(phydev);
return -EIO;
}
} while (time_before(jiffies, deadline) && (reg & BIT(12)));
if (reg & BIT(12)) {
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
+ phy_unlock_mdio_bus(phydev);
return -ETIMEDOUT;
}
@@ -1842,23 +1881,18 @@ static int vsc8514_config_init(struct phy_device *phydev)
reg = vsc85xx_csr_ctrl_phy_read(phydev, PHY_MCB_TARGET,
PHY_S6G_IB_STATUS0);
if (reg == 0xffffffff) {
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
+ phy_unlock_mdio_bus(phydev);
return -EIO;
}
} while (time_before(jiffies, deadline) && !(reg & BIT(8)));
if (!(reg & BIT(8))) {
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
+ phy_unlock_mdio_bus(phydev);
return -ETIMEDOUT;
}
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
-
- ret = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
-
- if (ret)
- return ret;
+ phy_unlock_mdio_bus(phydev);
ret = phy_modify(phydev, MSCC_PHY_EXT_PHY_CNTL_1, MEDIA_OP_MODE_MASK,
MEDIA_OP_MODE_COPPER << MEDIA_OP_MODE_POS);
@@ -1880,7 +1914,7 @@ static int vsc8514_config_init(struct phy_device *phydev)
return ret;
err:
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
+ phy_unlock_mdio_bus(phydev);
return ret;
}
@@ -1900,6 +1934,7 @@ static int vsc85xx_config_intr(struct phy_device *phydev)
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
vsc8584_config_macsec_intr(phydev);
+ vsc8584_config_ts_intr(phydev);
rc = phy_write(phydev, MII_VSC85XX_INT_MASK,
MII_VSC85XX_INT_MASK_MASK);
@@ -1999,6 +2034,7 @@ static int vsc8584_probe(struct phy_device *phydev)
u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
VSC8531_DUPLEX_COLLISION};
+ int ret;
if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
@@ -2012,8 +2048,8 @@ static int vsc8584_probe(struct phy_device *phydev)
phydev->priv = vsc8531;
vsc8584_get_base_addr(phydev);
- devm_phy_package_join(&phydev->mdio.dev, phydev,
- vsc8531->base_addr, 0);
+ devm_phy_package_join(&phydev->mdio.dev, phydev, vsc8531->base_addr,
+ sizeof(struct vsc85xx_shared_private));
vsc8531->nleds = 4;
vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
@@ -2024,6 +2060,16 @@ static int vsc8584_probe(struct phy_device *phydev)
if (!vsc8531->stats)
return -ENOMEM;
+ if (phy_package_probe_once(phydev)) {
+ ret = vsc8584_ptp_probe_once(phydev);
+ if (ret)
+ return ret;
+ }
+
+ ret = vsc8584_ptp_probe(phydev);
+ if (ret)
+ return ret;
+
return vsc85xx_dt_led_modes_get(phydev, default_mode);
}
@@ -2403,6 +2449,7 @@ static struct phy_driver vsc85xx_driver[] = {
.get_sset_count = &vsc85xx_get_sset_count,
.get_strings = &vsc85xx_get_strings,
.get_stats = &vsc85xx_get_stats,
+ .link_change_notify = &vsc85xx_link_change_notify,
}
};
diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
new file mode 100644
index 000000000000..b97ee79f3cdf
--- /dev/null
+++ b/drivers/net/phy/mscc/mscc_ptp.c
@@ -0,0 +1,1590 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Driver for Microsemi VSC85xx PHYs - timestamping and PHC support
+ *
+ * Authors: Quentin Schulz & Antoine Tenart
+ * License: Dual MIT/GPL
+ * Copyright (c) 2020 Microsemi Corporation
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/ip.h>
+#include <linux/net_tstamp.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/ptp_classify.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/udp.h>
+#include <asm/unaligned.h>
+
+#include "mscc.h"
+#include "mscc_ptp.h"
+
+/* Two PHYs share the same 1588 processor and it's to be entirely configured
+ * through the base PHY of this processor.
+ */
+/* phydev->bus->mdio_lock should be locked when using this function */
+static int phy_ts_base_write(struct phy_device *phydev, u32 regnum, u16 val)
+{
+ struct vsc8531_private *priv = phydev->priv;
+
+ WARN_ON_ONCE(!mutex_is_locked(&phydev->mdio.bus->mdio_lock));
+ return __mdiobus_write(phydev->mdio.bus, priv->ts_base_addr, regnum,
+ val);
+}
+
+/* phydev->bus->mdio_lock should be locked when using this function */
+static int phy_ts_base_read(struct phy_device *phydev, u32 regnum)
+{
+ struct vsc8531_private *priv = phydev->priv;
+
+ WARN_ON_ONCE(!mutex_is_locked(&phydev->mdio.bus->mdio_lock));
+ return __mdiobus_read(phydev->mdio.bus, priv->ts_base_addr, regnum);
+}
+
+enum ts_blk_hw {
+ INGRESS_ENGINE_0,
+ EGRESS_ENGINE_0,
+ INGRESS_ENGINE_1,
+ EGRESS_ENGINE_1,
+ INGRESS_ENGINE_2,
+ EGRESS_ENGINE_2,
+ PROCESSOR_0,
+ PROCESSOR_1,
+};
+
+enum ts_blk {
+ INGRESS,
+ EGRESS,
+ PROCESSOR,
+};
+
+static u32 vsc85xx_ts_read_csr(struct phy_device *phydev, enum ts_blk blk,
+ u16 addr)
+{
+ struct vsc8531_private *priv = phydev->priv;
+ bool base_port = phydev->mdio.addr == priv->ts_base_addr;
+ u32 val, cnt = 0;
+ enum ts_blk_hw blk_hw;
+
+ switch (blk) {
+ case INGRESS:
+ blk_hw = base_port ? INGRESS_ENGINE_0 : INGRESS_ENGINE_1;
+ break;
+ case EGRESS:
+ blk_hw = base_port ? EGRESS_ENGINE_0 : EGRESS_ENGINE_1;
+ break;
+ case PROCESSOR:
+ default:
+ blk_hw = base_port ? PROCESSOR_0 : PROCESSOR_1;
+ break;
+ }
+
+ phy_lock_mdio_bus(phydev);
+
+ phy_ts_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_1588);
+
+ phy_ts_base_write(phydev, MSCC_PHY_TS_BIU_ADDR_CNTL, BIU_ADDR_EXE |
+ BIU_ADDR_READ | BIU_BLK_ID(blk_hw) |
+ BIU_CSR_ADDR(addr));
+
+ do {
+ val = phy_ts_base_read(phydev, MSCC_PHY_TS_BIU_ADDR_CNTL);
+ } while (!(val & BIU_ADDR_EXE) && cnt++ < BIU_ADDR_CNT_MAX);
+
+ val = phy_ts_base_read(phydev, MSCC_PHY_TS_CSR_DATA_MSB);
+ val <<= 16;
+ val |= phy_ts_base_read(phydev, MSCC_PHY_TS_CSR_DATA_LSB);
+
+ phy_ts_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ phy_unlock_mdio_bus(phydev);
+
+ return val;
+}
+
+static void vsc85xx_ts_write_csr(struct phy_device *phydev, enum ts_blk blk,
+ u16 addr, u32 val)
+{
+ struct vsc8531_private *priv = phydev->priv;
+ bool base_port = phydev->mdio.addr == priv->ts_base_addr;
+ u32 reg, bypass, cnt = 0, lower = val & 0xffff, upper = val >> 16;
+ bool cond = (addr == MSCC_PHY_PTP_LTC_CTRL ||
+ addr == MSCC_PHY_1588_INGR_VSC85XX_INT_MASK ||
+ addr == MSCC_PHY_1588_VSC85XX_INT_MASK ||
+ addr == MSCC_PHY_1588_INGR_VSC85XX_INT_STATUS ||
+ addr == MSCC_PHY_1588_VSC85XX_INT_STATUS) &&
+ blk == PROCESSOR;
+ enum ts_blk_hw blk_hw;
+
+ switch (blk) {
+ case INGRESS:
+ blk_hw = base_port ? INGRESS_ENGINE_0 : INGRESS_ENGINE_1;
+ break;
+ case EGRESS:
+ blk_hw = base_port ? EGRESS_ENGINE_0 : EGRESS_ENGINE_1;
+ break;
+ case PROCESSOR:
+ default:
+ blk_hw = base_port ? PROCESSOR_0 : PROCESSOR_1;
+ break;
+ }
+
+ phy_lock_mdio_bus(phydev);
+
+ bypass = phy_ts_base_read(phydev, MSCC_PHY_BYPASS_CONTROL);
+
+ phy_ts_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_1588);
+
+ if (!cond || (cond && upper))
+ phy_ts_base_write(phydev, MSCC_PHY_TS_CSR_DATA_MSB, upper);
+
+ phy_ts_base_write(phydev, MSCC_PHY_TS_CSR_DATA_LSB, lower);
+
+ phy_ts_base_write(phydev, MSCC_PHY_TS_BIU_ADDR_CNTL, BIU_ADDR_EXE |
+ BIU_ADDR_WRITE | BIU_BLK_ID(blk_hw) |
+ BIU_CSR_ADDR(addr));
+
+ do {
+ reg = phy_ts_base_read(phydev, MSCC_PHY_TS_BIU_ADDR_CNTL);
+ } while (!(reg & BIU_ADDR_EXE) && cnt++ < BIU_ADDR_CNT_MAX);
+
+ phy_ts_base_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ if (cond && upper)
+ phy_ts_base_write(phydev, MSCC_PHY_BYPASS_CONTROL, bypass);
+
+ phy_unlock_mdio_bus(phydev);
+}
+
+/* Pick bytes from PTP header */
+#define PTP_HEADER_TRNSP_MSG 26
+#define PTP_HEADER_DOMAIN_NUM 25
+#define PTP_HEADER_BYTE_8_31(x) (31 - (x))
+#define MAC_ADDRESS_BYTE(x) ((x) + (35 - ETH_ALEN + 1))
+
+static int vsc85xx_ts_fsb_init(struct phy_device *phydev)
+{
+ u8 sig_sel[16] = {};
+ signed char i, pos = 0;
+
+ /* Seq ID is 2B long and starts at 30th byte */
+ for (i = 1; i >= 0; i--)
+ sig_sel[pos++] = PTP_HEADER_BYTE_8_31(30 + i);
+
+ /* DomainNum */
+ sig_sel[pos++] = PTP_HEADER_DOMAIN_NUM;
+
+ /* MsgType */
+ sig_sel[pos++] = PTP_HEADER_TRNSP_MSG;
+
+ /* MAC address is 6B long */
+ for (i = ETH_ALEN - 1; i >= 0; i--)
+ sig_sel[pos++] = MAC_ADDRESS_BYTE(i);
+
+ /* Fill the last bytes of the signature to reach a 16B signature */
+ for (; pos < ARRAY_SIZE(sig_sel); pos++)
+ sig_sel[pos] = PTP_HEADER_TRNSP_MSG;
+
+ for (i = 0; i <= 2; i++) {
+ u32 val = 0;
+
+ for (pos = i * 5 + 4; pos >= i * 5; pos--)
+ val = (val << 6) | sig_sel[pos];
+
+ vsc85xx_ts_write_csr(phydev, EGRESS, MSCC_PHY_ANA_FSB_REG(i),
+ val);
+ }
+
+ vsc85xx_ts_write_csr(phydev, EGRESS, MSCC_PHY_ANA_FSB_REG(3),
+ sig_sel[15]);
+
+ return 0;
+}
+
+static const u32 vsc85xx_egr_latency[] = {
+ /* Copper Egress */
+ 1272, /* 1000Mbps */
+ 12516, /* 100Mbps */
+ 125444, /* 10Mbps */
+ /* Fiber Egress */
+ 1277, /* 1000Mbps */
+ 12537, /* 100Mbps */
+};
+
+static const u32 vsc85xx_egr_latency_macsec[] = {
+ /* Copper Egress ON */
+ 3496, /* 1000Mbps */
+ 34760, /* 100Mbps */
+ 347844, /* 10Mbps */
+ /* Fiber Egress ON */
+ 3502, /* 1000Mbps */
+ 34780, /* 100Mbps */
+};
+
+static const u32 vsc85xx_ingr_latency[] = {
+ /* Copper Ingress */
+ 208, /* 1000Mbps */
+ 304, /* 100Mbps */
+ 2023, /* 10Mbps */
+ /* Fiber Ingress */
+ 98, /* 1000Mbps */
+ 197, /* 100Mbps */
+};
+
+static const u32 vsc85xx_ingr_latency_macsec[] = {
+ /* Copper Ingress */
+ 2408, /* 1000Mbps */
+ 22300, /* 100Mbps */
+ 222009, /* 10Mbps */
+ /* Fiber Ingress */
+ 2299, /* 1000Mbps */
+ 22192, /* 100Mbps */
+};
+
+static void vsc85xx_ts_set_latencies(struct phy_device *phydev)
+{
+ u32 val, ingr_latency, egr_latency;
+ u8 idx;
+
+ /* No need to set latencies of packets if the PHY is not connected */
+ if (!phydev->link)
+ return;
+
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_STALL_LATENCY,
+ STALL_EGR_LATENCY(phydev->speed));
+
+ switch (phydev->speed) {
+ case SPEED_100:
+ idx = 1;
+ break;
+ case SPEED_1000:
+ idx = 0;
+ break;
+ default:
+ idx = 2;
+ break;
+ }
+
+ ingr_latency = IS_ENABLED(CONFIG_MACSEC) ?
+ vsc85xx_ingr_latency_macsec[idx] : vsc85xx_ingr_latency[idx];
+ egr_latency = IS_ENABLED(CONFIG_MACSEC) ?
+ vsc85xx_egr_latency_macsec[idx] : vsc85xx_egr_latency[idx];
+
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_INGR_LOCAL_LATENCY,
+ PTP_INGR_LOCAL_LATENCY(ingr_latency));
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_INGR_TSP_CTRL);
+ val |= PHY_PTP_INGR_TSP_CTRL_LOAD_DELAYS;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_INGR_TSP_CTRL,
+ val);
+
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_LOCAL_LATENCY,
+ PTP_EGR_LOCAL_LATENCY(egr_latency));
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_TSP_CTRL);
+ val |= PHY_PTP_EGR_TSP_CTRL_LOAD_DELAYS;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_TSP_CTRL, val);
+}
+
+static int vsc85xx_ts_disable_flows(struct phy_device *phydev, enum ts_blk blk)
+{
+ u8 i;
+
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_NXT_COMP, 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_UDP_CHKSUM,
+ IP1_NXT_PROT_UDP_CHKSUM_WIDTH(2));
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP2_NXT_PROT_NXT_COMP, 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP2_NXT_PROT_UDP_CHKSUM,
+ IP2_NXT_PROT_UDP_CHKSUM_WIDTH(2));
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_PHY_ANA_MPLS_COMP_NXT_COMP, 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_PHY_ANA_ETH1_NTX_PROT, 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_PHY_ANA_ETH2_NTX_PROT, 0);
+
+ for (i = 0; i < COMP_MAX_FLOWS; i++) {
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_ENA(i),
+ IP1_FLOW_VALID_CH0 | IP1_FLOW_VALID_CH1);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP2_FLOW_ENA(i),
+ IP2_FLOW_VALID_CH0 | IP2_FLOW_VALID_CH1);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_ETH1_FLOW_ENA(i),
+ ETH1_FLOW_VALID_CH0 | ETH1_FLOW_VALID_CH1);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_ETH2_FLOW_ENA(i),
+ ETH2_FLOW_VALID_CH0 | ETH2_FLOW_VALID_CH1);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_MPLS_FLOW_CTRL(i),
+ MPLS_FLOW_VALID_CH0 | MPLS_FLOW_VALID_CH1);
+
+ if (i >= PTP_COMP_MAX_FLOWS)
+ continue;
+
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_PTP_FLOW_ENA(i), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_DOMAIN_RANGE(i), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_MASK_UPPER(i), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_MASK_LOWER(i), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_MATCH_UPPER(i), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_MATCH_LOWER(i), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_PTP_ACTION(i), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_PTP_ACTION2(i), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_PTP_0_FIELD(i), 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_OAM_PTP_FLOW_ENA(i),
+ 0);
+ }
+
+ return 0;
+}
+
+static int vsc85xx_ts_eth_cmp1_sig(struct phy_device *phydev)
+{
+ u32 val;
+
+ val = vsc85xx_ts_read_csr(phydev, EGRESS, MSCC_PHY_ANA_ETH1_NTX_PROT);
+ val &= ~ANA_ETH1_NTX_PROT_SIG_OFF_MASK;
+ val |= ANA_ETH1_NTX_PROT_SIG_OFF(0);
+ vsc85xx_ts_write_csr(phydev, EGRESS, MSCC_PHY_ANA_ETH1_NTX_PROT, val);
+
+ val = vsc85xx_ts_read_csr(phydev, EGRESS, MSCC_PHY_ANA_FSB_CFG);
+ val &= ~ANA_FSB_ADDR_FROM_BLOCK_SEL_MASK;
+ val |= ANA_FSB_ADDR_FROM_ETH1;
+ vsc85xx_ts_write_csr(phydev, EGRESS, MSCC_PHY_ANA_FSB_CFG, val);
+
+ return 0;
+}
+
+static struct vsc85xx_ptphdr *get_ptp_header_l4(struct sk_buff *skb,
+ struct iphdr *iphdr,
+ struct udphdr *udphdr)
+{
+ if (iphdr->version != 4 || iphdr->protocol != IPPROTO_UDP)
+ return NULL;
+
+ return (struct vsc85xx_ptphdr *)(((unsigned char *)udphdr) + UDP_HLEN);
+}
+
+static struct vsc85xx_ptphdr *get_ptp_header_tx(struct sk_buff *skb)
+{
+ struct ethhdr *ethhdr = eth_hdr(skb);
+ struct udphdr *udphdr;
+ struct iphdr *iphdr;
+
+ if (ethhdr->h_proto == htons(ETH_P_1588))
+ return (struct vsc85xx_ptphdr *)(((unsigned char *)ethhdr) +
+ skb_mac_header_len(skb));
+
+ if (ethhdr->h_proto != htons(ETH_P_IP))
+ return NULL;
+
+ iphdr = ip_hdr(skb);
+ udphdr = udp_hdr(skb);
+
+ return get_ptp_header_l4(skb, iphdr, udphdr);
+}
+
+static struct vsc85xx_ptphdr *get_ptp_header_rx(struct sk_buff *skb,
+ enum hwtstamp_rx_filters rx_filter)
+{
+ struct udphdr *udphdr;
+ struct iphdr *iphdr;
+
+ if (rx_filter == HWTSTAMP_FILTER_PTP_V2_L2_EVENT)
+ return (struct vsc85xx_ptphdr *)skb->data;
+
+ iphdr = (struct iphdr *)skb->data;
+ udphdr = (struct udphdr *)(skb->data + iphdr->ihl * 4);
+
+ return get_ptp_header_l4(skb, iphdr, udphdr);
+}
+
+static int get_sig(struct sk_buff *skb, u8 *sig)
+{
+ struct vsc85xx_ptphdr *ptphdr = get_ptp_header_tx(skb);
+ struct ethhdr *ethhdr = eth_hdr(skb);
+ unsigned int i;
+
+ if (!ptphdr)
+ return -EOPNOTSUPP;
+
+ sig[0] = (__force u16)ptphdr->seq_id >> 8;
+ sig[1] = (__force u16)ptphdr->seq_id & GENMASK(7, 0);
+ sig[2] = ptphdr->domain;
+ sig[3] = ptphdr->tsmt & GENMASK(3, 0);
+
+ memcpy(&sig[4], ethhdr->h_dest, ETH_ALEN);
+
+ /* Fill the last bytes of the signature to reach a 16B signature */
+ for (i = 10; i < 16; i++)
+ sig[i] = ptphdr->tsmt & GENMASK(3, 0);
+
+ return 0;
+}
+
+static void vsc85xx_dequeue_skb(struct vsc85xx_ptp *ptp)
+{
+ struct skb_shared_hwtstamps shhwtstamps;
+ struct vsc85xx_ts_fifo fifo;
+ struct sk_buff *skb;
+ u8 skb_sig[16], *p;
+ int i, len;
+ u32 reg;
+
+ memset(&fifo, 0, sizeof(fifo));
+ p = (u8 *)&fifo;
+
+ reg = vsc85xx_ts_read_csr(ptp->phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_TS_FIFO(0));
+ if (reg & PTP_EGR_TS_FIFO_EMPTY)
+ return;
+
+ *p++ = reg & 0xff;
+ *p++ = (reg >> 8) & 0xff;
+
+ /* Read the current FIFO item. Reading FIFO6 pops the next one. */
+ for (i = 1; i < 7; i++) {
+ reg = vsc85xx_ts_read_csr(ptp->phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_TS_FIFO(i));
+ *p++ = reg & 0xff;
+ *p++ = (reg >> 8) & 0xff;
+ *p++ = (reg >> 16) & 0xff;
+ *p++ = (reg >> 24) & 0xff;
+ }
+
+ len = skb_queue_len(&ptp->tx_queue);
+ if (len < 1)
+ return;
+
+ while (len--) {
+ skb = __skb_dequeue(&ptp->tx_queue);
+ if (!skb)
+ return;
+
+ /* Can't get the signature of the packet, won't ever
+ * be able to have one so let's dequeue the packet.
+ */
+ if (get_sig(skb, skb_sig) < 0) {
+ kfree_skb(skb);
+ continue;
+ }
+
+ /* Check if we found the signature we were looking for. */
+ if (!memcmp(skb_sig, fifo.sig, sizeof(fifo.sig))) {
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+ shhwtstamps.hwtstamp = ktime_set(fifo.secs, fifo.ns);
+ skb_complete_tx_timestamp(skb, &shhwtstamps);
+
+ return;
+ }
+
+ /* Valid signature but does not match the one of the
+ * packet in the FIFO right now, reschedule it for later
+ * packets.
+ */
+ __skb_queue_tail(&ptp->tx_queue, skb);
+ }
+}
+
+static void vsc85xx_get_tx_ts(struct vsc85xx_ptp *ptp)
+{
+ u32 reg;
+
+ do {
+ vsc85xx_dequeue_skb(ptp);
+
+ /* If other timestamps are available in the FIFO, process them. */
+ reg = vsc85xx_ts_read_csr(ptp->phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_TS_FIFO_CTRL);
+ } while (PTP_EGR_FIFO_LEVEL_LAST_READ(reg) > 1);
+}
+
+static int vsc85xx_ptp_cmp_init(struct phy_device *phydev, enum ts_blk blk)
+{
+ struct vsc8531_private *vsc8531 = phydev->priv;
+ bool base = phydev->mdio.addr == vsc8531->ts_base_addr;
+ enum vsc85xx_ptp_msg_type msgs[] = {
+ PTP_MSG_TYPE_SYNC,
+ PTP_MSG_TYPE_DELAY_REQ
+ };
+ u32 val;
+ u8 i;
+
+ for (i = 0; i < ARRAY_SIZE(msgs); i++) {
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_PTP_FLOW_ENA(i),
+ base ? PTP_FLOW_VALID_CH0 :
+ PTP_FLOW_VALID_CH1);
+
+ val = vsc85xx_ts_read_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_DOMAIN_RANGE(i));
+ val &= ~PTP_FLOW_DOMAIN_RANGE_ENA;
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_DOMAIN_RANGE(i), val);
+
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_MATCH_UPPER(i),
+ msgs[i] << 24);
+
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_MASK_UPPER(i),
+ PTP_FLOW_MSG_TYPE_MASK);
+ }
+
+ return 0;
+}
+
+static int vsc85xx_eth_cmp1_init(struct phy_device *phydev, enum ts_blk blk)
+{
+ struct vsc8531_private *vsc8531 = phydev->priv;
+ bool base = phydev->mdio.addr == vsc8531->ts_base_addr;
+ u32 val;
+
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_PHY_ANA_ETH1_NXT_PROT_TAG, 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_PHY_ANA_ETH1_NTX_PROT_VLAN_TPID,
+ ANA_ETH1_NTX_PROT_VLAN_TPID(ETH_P_8021AD));
+
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_ETH1_FLOW_ENA(0),
+ base ? ETH1_FLOW_VALID_CH0 : ETH1_FLOW_VALID_CH1);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_ETH1_FLOW_MATCH_MODE(0),
+ ANA_ETH1_FLOW_MATCH_VLAN_TAG2);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_ETH1_FLOW_ADDR_MATCH1(0), 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_ETH1_FLOW_ADDR_MATCH2(0), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_ETH1_FLOW_VLAN_RANGE_I_TAG(0), 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_ETH1_FLOW_VLAN_TAG1(0), 0);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_ETH1_FLOW_VLAN_TAG2_I_TAG(0), 0);
+
+ val = vsc85xx_ts_read_csr(phydev, blk,
+ MSCC_ANA_ETH1_FLOW_MATCH_MODE(0));
+ val &= ~ANA_ETH1_FLOW_MATCH_VLAN_TAG_MASK;
+ val |= ANA_ETH1_FLOW_MATCH_VLAN_VERIFY;
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_ETH1_FLOW_MATCH_MODE(0),
+ val);
+
+ return 0;
+}
+
+static int vsc85xx_ip_cmp1_init(struct phy_device *phydev, enum ts_blk blk)
+{
+ struct vsc8531_private *vsc8531 = phydev->priv;
+ bool base = phydev->mdio.addr == vsc8531->ts_base_addr;
+ u32 val;
+
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_MATCH2_UPPER,
+ PTP_EV_PORT);
+ /* Match on dest port only, ignore src */
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_MASK2_UPPER,
+ 0xffff);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_MATCH2_LOWER,
+ 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_MASK2_LOWER, 0);
+
+ val = vsc85xx_ts_read_csr(phydev, blk, MSCC_ANA_IP1_FLOW_ENA(0));
+ val &= ~IP1_FLOW_ENA_CHANNEL_MASK_MASK;
+ val |= base ? IP1_FLOW_VALID_CH0 : IP1_FLOW_VALID_CH1;
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_ENA(0), val);
+
+ /* Match all IPs */
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_MATCH_UPPER(0), 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_MASK_UPPER(0), 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_MATCH_UPPER_MID(0),
+ 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_MASK_UPPER_MID(0),
+ 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_MATCH_LOWER_MID(0),
+ 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_MASK_LOWER_MID(0),
+ 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_MATCH_LOWER(0), 0);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_MASK_LOWER(0), 0);
+
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_PTP_IP_CHKSUM_SEL, 0);
+
+ return 0;
+}
+
+static int vsc85xx_adjfine(struct ptp_clock_info *info, long scaled_ppm)
+{
+ struct vsc85xx_ptp *ptp = container_of(info, struct vsc85xx_ptp, caps);
+ struct phy_device *phydev = ptp->phydev;
+ struct vsc8531_private *priv = phydev->priv;
+ u64 adj = 0;
+ u32 val;
+
+ if (abs(scaled_ppm) < 66 || abs(scaled_ppm) > 65536UL * 1000000UL)
+ return 0;
+
+ adj = div64_u64(1000000ULL * 65536ULL, abs(scaled_ppm));
+ if (adj > 1000000000L)
+ adj = 1000000000L;
+
+ val = PTP_AUTO_ADJ_NS_ROLLOVER(adj);
+ val |= scaled_ppm > 0 ? PTP_AUTO_ADJ_ADD_1NS : PTP_AUTO_ADJ_SUB_1NS;
+
+ mutex_lock(&priv->phc_lock);
+
+ /* Update the ppb val in nano seconds to the auto adjust reg. */
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_AUTO_ADJ,
+ val);
+
+ /* The auto adjust update val is set to 0 after write operation. */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_CTRL);
+ val |= PTP_LTC_CTRL_AUTO_ADJ_UPDATE;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_CTRL, val);
+
+ mutex_unlock(&priv->phc_lock);
+
+ return 0;
+}
+
+static int __vsc85xx_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
+{
+ struct vsc85xx_ptp *ptp = container_of(info, struct vsc85xx_ptp, caps);
+ struct phy_device *phydev = ptp->phydev;
+ struct vsc85xx_shared_private *shared =
+ (struct vsc85xx_shared_private *)phydev->shared->priv;
+ struct vsc8531_private *priv = phydev->priv;
+ u32 val;
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_CTRL);
+ val |= PTP_LTC_CTRL_SAVE_ENA;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_CTRL, val);
+
+ /* Local Time Counter (LTC) is put in SAVE* regs on rising edge of
+ * LOAD_SAVE pin.
+ */
+ mutex_lock(&shared->gpio_lock);
+ gpiod_set_value(priv->load_save, 1);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_LTC_SAVED_SEC_MSB);
+
+ ts->tv_sec = ((time64_t)val) << 32;
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_LTC_SAVED_SEC_LSB);
+ ts->tv_sec += val;
+
+ ts->tv_nsec = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_LTC_SAVED_NS);
+
+ gpiod_set_value(priv->load_save, 0);
+ mutex_unlock(&shared->gpio_lock);
+
+ return 0;
+}
+
+static int vsc85xx_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
+{
+ struct vsc85xx_ptp *ptp = container_of(info, struct vsc85xx_ptp, caps);
+ struct phy_device *phydev = ptp->phydev;
+ struct vsc8531_private *priv = phydev->priv;
+
+ mutex_lock(&priv->phc_lock);
+ __vsc85xx_gettime(info, ts);
+ mutex_unlock(&priv->phc_lock);
+
+ return 0;
+}
+
+static int __vsc85xx_settime(struct ptp_clock_info *info,
+ const struct timespec64 *ts)
+{
+ struct vsc85xx_ptp *ptp = container_of(info, struct vsc85xx_ptp, caps);
+ struct phy_device *phydev = ptp->phydev;
+ struct vsc85xx_shared_private *shared =
+ (struct vsc85xx_shared_private *)phydev->shared->priv;
+ struct vsc8531_private *priv = phydev->priv;
+ u32 val;
+
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_LOAD_SEC_MSB,
+ PTP_LTC_LOAD_SEC_MSB(ts->tv_sec));
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_LOAD_SEC_LSB,
+ PTP_LTC_LOAD_SEC_LSB(ts->tv_sec));
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_LOAD_NS,
+ PTP_LTC_LOAD_NS(ts->tv_nsec));
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_CTRL);
+ val |= PTP_LTC_CTRL_LOAD_ENA;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_CTRL, val);
+
+ /* Local Time Counter (LTC) is set from LOAD* regs on rising edge of
+ * LOAD_SAVE pin.
+ */
+ mutex_lock(&shared->gpio_lock);
+ gpiod_set_value(priv->load_save, 1);
+
+ val &= ~PTP_LTC_CTRL_LOAD_ENA;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_CTRL, val);
+
+ gpiod_set_value(priv->load_save, 0);
+ mutex_unlock(&shared->gpio_lock);
+
+ return 0;
+}
+
+static int vsc85xx_settime(struct ptp_clock_info *info,
+ const struct timespec64 *ts)
+{
+ struct vsc85xx_ptp *ptp = container_of(info, struct vsc85xx_ptp, caps);
+ struct phy_device *phydev = ptp->phydev;
+ struct vsc8531_private *priv = phydev->priv;
+
+ mutex_lock(&priv->phc_lock);
+ __vsc85xx_settime(info, ts);
+ mutex_unlock(&priv->phc_lock);
+
+ return 0;
+}
+
+static int vsc85xx_adjtime(struct ptp_clock_info *info, s64 delta)
+{
+ struct vsc85xx_ptp *ptp = container_of(info, struct vsc85xx_ptp, caps);
+ struct phy_device *phydev = ptp->phydev;
+ struct vsc8531_private *priv = phydev->priv;
+ u32 val;
+
+ /* Can't recover that big of an offset. Let's set the time directly. */
+ if (abs(delta) >= NSEC_PER_SEC) {
+ struct timespec64 ts;
+ u64 now;
+
+ mutex_lock(&priv->phc_lock);
+
+ __vsc85xx_gettime(info, &ts);
+ now = ktime_to_ns(timespec64_to_ktime(ts));
+ ts = ns_to_timespec64(now + delta);
+ __vsc85xx_settime(info, &ts);
+
+ mutex_unlock(&priv->phc_lock);
+
+ return 0;
+ }
+
+ mutex_lock(&priv->phc_lock);
+
+ val = PTP_LTC_OFFSET_VAL(abs(delta)) | PTP_LTC_OFFSET_ADJ;
+ if (delta > 0)
+ val |= PTP_LTC_OFFSET_ADD;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_OFFSET, val);
+
+ mutex_unlock(&priv->phc_lock);
+
+ return 0;
+}
+
+static int vsc85xx_eth1_next_comp(struct phy_device *phydev, enum ts_blk blk,
+ u32 next_comp, u32 etype)
+{
+ u32 val;
+
+ val = vsc85xx_ts_read_csr(phydev, blk, MSCC_PHY_ANA_ETH1_NTX_PROT);
+ val &= ~ANA_ETH1_NTX_PROT_COMPARATOR_MASK;
+ val |= next_comp;
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_PHY_ANA_ETH1_NTX_PROT, val);
+
+ val = ANA_ETH1_NXT_PROT_ETYPE_MATCH(etype) |
+ ANA_ETH1_NXT_PROT_ETYPE_MATCH_ENA;
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_PHY_ANA_ETH1_NXT_PROT_ETYPE_MATCH, val);
+
+ return 0;
+}
+
+static int vsc85xx_ip1_next_comp(struct phy_device *phydev, enum ts_blk blk,
+ u32 next_comp, u32 header)
+{
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_NXT_COMP,
+ ANA_IP1_NXT_PROT_NXT_COMP_BYTES_HDR(header) |
+ next_comp);
+
+ return 0;
+}
+
+static int vsc85xx_ts_ptp_action_flow(struct phy_device *phydev, enum ts_blk blk, u8 flow, enum ptp_cmd cmd)
+{
+ u32 val;
+
+ /* Check non-zero reserved field */
+ val = PTP_FLOW_PTP_0_FIELD_PTP_FRAME | PTP_FLOW_PTP_0_FIELD_RSVRD_CHECK;
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_PTP_0_FIELD(flow), val);
+
+ val = PTP_FLOW_PTP_ACTION_CORR_OFFSET(8) |
+ PTP_FLOW_PTP_ACTION_TIME_OFFSET(8) |
+ PTP_FLOW_PTP_ACTION_PTP_CMD(cmd == PTP_SAVE_IN_TS_FIFO ?
+ PTP_NOP : cmd);
+ if (cmd == PTP_SAVE_IN_TS_FIFO)
+ val |= PTP_FLOW_PTP_ACTION_SAVE_LOCAL_TIME;
+ else if (cmd == PTP_WRITE_NS)
+ val |= PTP_FLOW_PTP_ACTION_MOD_FRAME_STATUS_UPDATE |
+ PTP_FLOW_PTP_ACTION_MOD_FRAME_STATUS_BYTE_OFFSET(6);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_PTP_FLOW_PTP_ACTION(flow),
+ val);
+
+ if (cmd == PTP_WRITE_1588)
+ /* Rewrite timestamp directly in frame */
+ val = PTP_FLOW_PTP_ACTION2_REWRITE_OFFSET(34) |
+ PTP_FLOW_PTP_ACTION2_REWRITE_BYTES(10);
+ else if (cmd == PTP_SAVE_IN_TS_FIFO)
+ /* no rewrite */
+ val = PTP_FLOW_PTP_ACTION2_REWRITE_OFFSET(0) |
+ PTP_FLOW_PTP_ACTION2_REWRITE_BYTES(0);
+ else
+ /* Write in reserved field */
+ val = PTP_FLOW_PTP_ACTION2_REWRITE_OFFSET(16) |
+ PTP_FLOW_PTP_ACTION2_REWRITE_BYTES(4);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_PTP_ACTION2(flow), val);
+
+ return 0;
+}
+
+static int vsc85xx_ptp_conf(struct phy_device *phydev, enum ts_blk blk,
+ bool one_step, bool enable)
+{
+ enum vsc85xx_ptp_msg_type msgs[] = {
+ PTP_MSG_TYPE_SYNC,
+ PTP_MSG_TYPE_DELAY_REQ
+ };
+ u32 val;
+ u8 i;
+
+ for (i = 0; i < ARRAY_SIZE(msgs); i++) {
+ if (blk == INGRESS)
+ vsc85xx_ts_ptp_action_flow(phydev, blk, msgs[i],
+ PTP_WRITE_NS);
+ else if (msgs[i] == PTP_MSG_TYPE_SYNC && one_step)
+ /* no need to know Sync t when sending in one_step */
+ vsc85xx_ts_ptp_action_flow(phydev, blk, msgs[i],
+ PTP_WRITE_1588);
+ else
+ vsc85xx_ts_ptp_action_flow(phydev, blk, msgs[i],
+ PTP_SAVE_IN_TS_FIFO);
+
+ val = vsc85xx_ts_read_csr(phydev, blk,
+ MSCC_ANA_PTP_FLOW_ENA(i));
+ val &= ~PTP_FLOW_ENA;
+ if (enable)
+ val |= PTP_FLOW_ENA;
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_PTP_FLOW_ENA(i),
+ val);
+ }
+
+ return 0;
+}
+
+static int vsc85xx_eth1_conf(struct phy_device *phydev, enum ts_blk blk,
+ bool enable)
+{
+ struct vsc8531_private *vsc8531 = phydev->priv;
+ u32 val = ANA_ETH1_FLOW_ADDR_MATCH2_DEST;
+
+ if (vsc8531->ptp->rx_filter == HWTSTAMP_FILTER_PTP_V2_L2_EVENT) {
+ /* PTP over Ethernet multicast address for SYNC and DELAY msg */
+ u8 ptp_multicast[6] = {0x01, 0x1b, 0x19, 0x00, 0x00, 0x00};
+
+ val |= ANA_ETH1_FLOW_ADDR_MATCH2_FULL_ADDR |
+ get_unaligned_be16(&ptp_multicast[4]);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_ETH1_FLOW_ADDR_MATCH2(0), val);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_ETH1_FLOW_ADDR_MATCH1(0),
+ get_unaligned_be32(ptp_multicast));
+ } else {
+ val |= ANA_ETH1_FLOW_ADDR_MATCH2_ANY_MULTICAST;
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_ETH1_FLOW_ADDR_MATCH2(0), val);
+ vsc85xx_ts_write_csr(phydev, blk,
+ MSCC_ANA_ETH1_FLOW_ADDR_MATCH1(0), 0);
+ }
+
+ val = vsc85xx_ts_read_csr(phydev, blk, MSCC_ANA_ETH1_FLOW_ENA(0));
+ val &= ~ETH1_FLOW_ENA;
+ if (enable)
+ val |= ETH1_FLOW_ENA;
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_ETH1_FLOW_ENA(0), val);
+
+ return 0;
+}
+
+static int vsc85xx_ip1_conf(struct phy_device *phydev, enum ts_blk blk,
+ bool enable)
+{
+ u32 val;
+
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_IP1_MODE,
+ ANA_IP1_NXT_PROT_IPV4 |
+ ANA_IP1_NXT_PROT_FLOW_OFFSET_IPV4);
+
+ /* Matching UDP protocol number */
+ val = ANA_IP1_NXT_PROT_IP_MATCH1_PROT_MASK(0xff) |
+ ANA_IP1_NXT_PROT_IP_MATCH1_PROT_MATCH(IPPROTO_UDP) |
+ ANA_IP1_NXT_PROT_IP_MATCH1_PROT_OFF(9);
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_IP_MATCH1,
+ val);
+
+ /* End of IP protocol, start of next protocol (UDP) */
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_OFFSET2,
+ ANA_IP1_NXT_PROT_OFFSET2(20));
+
+ val = vsc85xx_ts_read_csr(phydev, blk,
+ MSCC_ANA_IP1_NXT_PROT_UDP_CHKSUM);
+ val &= ~(IP1_NXT_PROT_UDP_CHKSUM_OFF_MASK |
+ IP1_NXT_PROT_UDP_CHKSUM_WIDTH_MASK);
+ val |= IP1_NXT_PROT_UDP_CHKSUM_WIDTH(2);
+
+ val &= ~(IP1_NXT_PROT_UDP_CHKSUM_UPDATE |
+ IP1_NXT_PROT_UDP_CHKSUM_CLEAR);
+ /* UDP checksum offset in IPv4 packet
+ * according to: https://tools.ietf.org/html/rfc768
+ */
+ val |= IP1_NXT_PROT_UDP_CHKSUM_OFF(26) | IP1_NXT_PROT_UDP_CHKSUM_CLEAR;
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_UDP_CHKSUM,
+ val);
+
+ val = vsc85xx_ts_read_csr(phydev, blk, MSCC_ANA_IP1_FLOW_ENA(0));
+ val &= ~(IP1_FLOW_MATCH_ADDR_MASK | IP1_FLOW_ENA);
+ val |= IP1_FLOW_MATCH_DEST_SRC_ADDR;
+ if (enable)
+ val |= IP1_FLOW_ENA;
+ vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_FLOW_ENA(0), val);
+
+ return 0;
+}
+
+static int vsc85xx_ts_engine_init(struct phy_device *phydev, bool one_step)
+{
+ struct vsc8531_private *vsc8531 = phydev->priv;
+ bool ptp_l4, base = phydev->mdio.addr == vsc8531->ts_base_addr;
+ u8 eng_id = base ? 0 : 1;
+ u32 val;
+
+ ptp_l4 = vsc8531->ptp->rx_filter == HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_ANALYZER_MODE);
+ /* Disable INGRESS and EGRESS so engine eng_id can be reconfigured */
+ val &= ~(PTP_ANALYZER_MODE_EGR_ENA(BIT(eng_id)) |
+ PTP_ANALYZER_MODE_INGR_ENA(BIT(eng_id)));
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_ANALYZER_MODE,
+ val);
+
+ if (vsc8531->ptp->rx_filter == HWTSTAMP_FILTER_PTP_V2_L2_EVENT) {
+ vsc85xx_eth1_next_comp(phydev, INGRESS,
+ ANA_ETH1_NTX_PROT_PTP_OAM, ETH_P_1588);
+ vsc85xx_eth1_next_comp(phydev, EGRESS,
+ ANA_ETH1_NTX_PROT_PTP_OAM, ETH_P_1588);
+ } else {
+ vsc85xx_eth1_next_comp(phydev, INGRESS,
+ ANA_ETH1_NTX_PROT_IP_UDP_ACH_1,
+ ETH_P_IP);
+ vsc85xx_eth1_next_comp(phydev, EGRESS,
+ ANA_ETH1_NTX_PROT_IP_UDP_ACH_1,
+ ETH_P_IP);
+ /* Header length of IPv[4/6] + UDP */
+ vsc85xx_ip1_next_comp(phydev, INGRESS,
+ ANA_ETH1_NTX_PROT_PTP_OAM, 28);
+ vsc85xx_ip1_next_comp(phydev, EGRESS,
+ ANA_ETH1_NTX_PROT_PTP_OAM, 28);
+ }
+
+ vsc85xx_eth1_conf(phydev, INGRESS,
+ vsc8531->ptp->rx_filter != HWTSTAMP_FILTER_NONE);
+ vsc85xx_ip1_conf(phydev, INGRESS,
+ ptp_l4 && vsc8531->ptp->rx_filter != HWTSTAMP_FILTER_NONE);
+ vsc85xx_ptp_conf(phydev, INGRESS, one_step,
+ vsc8531->ptp->rx_filter != HWTSTAMP_FILTER_NONE);
+
+ vsc85xx_eth1_conf(phydev, EGRESS,
+ vsc8531->ptp->tx_type != HWTSTAMP_TX_OFF);
+ vsc85xx_ip1_conf(phydev, EGRESS,
+ ptp_l4 && vsc8531->ptp->tx_type != HWTSTAMP_TX_OFF);
+ vsc85xx_ptp_conf(phydev, EGRESS, one_step,
+ vsc8531->ptp->tx_type != HWTSTAMP_TX_OFF);
+
+ val &= ~PTP_ANALYZER_MODE_EGR_ENA(BIT(eng_id));
+ if (vsc8531->ptp->tx_type != HWTSTAMP_TX_OFF)
+ val |= PTP_ANALYZER_MODE_EGR_ENA(BIT(eng_id));
+
+ val &= ~PTP_ANALYZER_MODE_INGR_ENA(BIT(eng_id));
+ if (vsc8531->ptp->rx_filter != HWTSTAMP_FILTER_NONE)
+ val |= PTP_ANALYZER_MODE_INGR_ENA(BIT(eng_id));
+
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_ANALYZER_MODE,
+ val);
+
+ return 0;
+}
+
+void vsc85xx_link_change_notify(struct phy_device *phydev)
+{
+ struct vsc8531_private *priv = phydev->priv;
+
+ mutex_lock(&priv->ts_lock);
+ vsc85xx_ts_set_latencies(phydev);
+ mutex_unlock(&priv->ts_lock);
+}
+
+static void vsc85xx_ts_reset_fifo(struct phy_device *phydev)
+{
+ u32 val;
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_TS_FIFO_CTRL);
+ val |= PTP_EGR_TS_FIFO_RESET;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_TS_FIFO_CTRL,
+ val);
+
+ val &= ~PTP_EGR_TS_FIFO_RESET;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_TS_FIFO_CTRL,
+ val);
+}
+
+static int vsc85xx_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr)
+{
+ struct vsc8531_private *vsc8531 =
+ container_of(mii_ts, struct vsc8531_private, mii_ts);
+ struct phy_device *phydev = vsc8531->ptp->phydev;
+ struct hwtstamp_config cfg;
+ bool one_step = false;
+ u32 val;
+
+ if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
+ return -EFAULT;
+
+ if (cfg.flags)
+ return -EINVAL;
+
+ switch (cfg.tx_type) {
+ case HWTSTAMP_TX_ONESTEP_SYNC:
+ one_step = true;
+ break;
+ case HWTSTAMP_TX_ON:
+ break;
+ case HWTSTAMP_TX_OFF:
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ vsc8531->ptp->tx_type = cfg.tx_type;
+
+ switch (cfg.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ /* ETH->IP->UDP->PTP */
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ /* ETH->PTP */
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ vsc8531->ptp->rx_filter = cfg.rx_filter;
+
+ mutex_lock(&vsc8531->ts_lock);
+
+ __skb_queue_purge(&vsc8531->ptp->tx_queue);
+ __skb_queue_head_init(&vsc8531->ptp->tx_queue);
+
+ /* Disable predictor while configuring the 1588 block */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_INGR_PREDICTOR);
+ val &= ~PTP_INGR_PREDICTOR_EN;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_INGR_PREDICTOR,
+ val);
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_PREDICTOR);
+ val &= ~PTP_EGR_PREDICTOR_EN;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_PREDICTOR,
+ val);
+
+ /* Bypass egress or ingress blocks if timestamping isn't used */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_IFACE_CTRL);
+ val &= ~(PTP_IFACE_CTRL_EGR_BYPASS | PTP_IFACE_CTRL_INGR_BYPASS);
+ if (vsc8531->ptp->tx_type == HWTSTAMP_TX_OFF)
+ val |= PTP_IFACE_CTRL_EGR_BYPASS;
+ if (vsc8531->ptp->rx_filter == HWTSTAMP_FILTER_NONE)
+ val |= PTP_IFACE_CTRL_INGR_BYPASS;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_IFACE_CTRL, val);
+
+ /* Resetting FIFO so that it's empty after reconfiguration */
+ vsc85xx_ts_reset_fifo(phydev);
+
+ vsc85xx_ts_engine_init(phydev, one_step);
+
+ /* Re-enable predictors now */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_INGR_PREDICTOR);
+ val |= PTP_INGR_PREDICTOR_EN;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_INGR_PREDICTOR,
+ val);
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_PREDICTOR);
+ val |= PTP_EGR_PREDICTOR_EN;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_PREDICTOR,
+ val);
+
+ vsc8531->ptp->configured = 1;
+ mutex_unlock(&vsc8531->ts_lock);
+
+ return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+}
+
+static int vsc85xx_ts_info(struct mii_timestamper *mii_ts,
+ struct ethtool_ts_info *info)
+{
+ struct vsc8531_private *vsc8531 =
+ container_of(mii_ts, struct vsc8531_private, mii_ts);
+
+ info->phc_index = ptp_clock_index(vsc8531->ptp->ptp_clock);
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->tx_types =
+ (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON) |
+ (1 << HWTSTAMP_TX_ONESTEP_SYNC);
+ info->rx_filters =
+ (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
+
+ return 0;
+}
+
+static void vsc85xx_txtstamp(struct mii_timestamper *mii_ts,
+ struct sk_buff *skb, int type)
+{
+ struct vsc8531_private *vsc8531 =
+ container_of(mii_ts, struct vsc8531_private, mii_ts);
+
+ if (!vsc8531->ptp->configured)
+ return;
+
+ if (vsc8531->ptp->tx_type == HWTSTAMP_TX_OFF) {
+ kfree_skb(skb);
+ return;
+ }
+
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
+ mutex_lock(&vsc8531->ts_lock);
+ __skb_queue_tail(&vsc8531->ptp->tx_queue, skb);
+ mutex_unlock(&vsc8531->ts_lock);
+}
+
+static bool vsc85xx_rxtstamp(struct mii_timestamper *mii_ts,
+ struct sk_buff *skb, int type)
+{
+ struct vsc8531_private *vsc8531 =
+ container_of(mii_ts, struct vsc8531_private, mii_ts);
+ struct skb_shared_hwtstamps *shhwtstamps = NULL;
+ struct vsc85xx_ptphdr *ptphdr;
+ struct timespec64 ts;
+ unsigned long ns;
+
+ if (!vsc8531->ptp->configured)
+ return false;
+
+ if (vsc8531->ptp->rx_filter == HWTSTAMP_FILTER_NONE ||
+ type == PTP_CLASS_NONE)
+ return false;
+
+ vsc85xx_gettime(&vsc8531->ptp->caps, &ts);
+
+ ptphdr = get_ptp_header_rx(skb, vsc8531->ptp->rx_filter);
+ if (!ptphdr)
+ return false;
+
+ shhwtstamps = skb_hwtstamps(skb);
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+
+ ns = ntohl(ptphdr->rsrvd2);
+
+ /* nsec is in reserved field */
+ if (ts.tv_nsec < ns)
+ ts.tv_sec--;
+
+ shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ns);
+ netif_rx_ni(skb);
+
+ return true;
+}
+
+static const struct ptp_clock_info vsc85xx_clk_caps = {
+ .owner = THIS_MODULE,
+ .name = "VSC85xx timer",
+ .max_adj = S32_MAX,
+ .n_alarm = 0,
+ .n_pins = 0,
+ .n_ext_ts = 0,
+ .n_per_out = 0,
+ .pps = 0,
+ .adjtime = &vsc85xx_adjtime,
+ .adjfine = &vsc85xx_adjfine,
+ .gettime64 = &vsc85xx_gettime,
+ .settime64 = &vsc85xx_settime,
+};
+
+static struct vsc8531_private *vsc8584_base_priv(struct phy_device *phydev)
+{
+ struct vsc8531_private *vsc8531 = phydev->priv;
+
+ if (vsc8531->ts_base_addr != phydev->mdio.addr) {
+ struct mdio_device *dev;
+
+ dev = phydev->mdio.bus->mdio_map[vsc8531->ts_base_addr];
+ phydev = container_of(dev, struct phy_device, mdio);
+
+ return phydev->priv;
+ }
+
+ return vsc8531;
+}
+
+static bool vsc8584_is_1588_input_clk_configured(struct phy_device *phydev)
+{
+ struct vsc8531_private *vsc8531 = vsc8584_base_priv(phydev);
+
+ return vsc8531->input_clk_init;
+}
+
+static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+{
+ struct vsc8531_private *vsc8531 = vsc8584_base_priv(phydev);
+
+ vsc8531->input_clk_init = true;
+}
+
+static int __vsc8584_init_ptp(struct phy_device *phydev)
+{
+ struct vsc8531_private *vsc8531 = phydev->priv;
+ u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+ u8 ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+ u32 val;
+
+ if (!vsc8584_is_1588_input_clk_configured(phydev)) {
+ phy_lock_mdio_bus(phydev);
+
+ /* 1588_DIFF_INPUT_CLK configuration: Use an external clock for
+ * the LTC, as per 3.13.29 in the VSC8584 datasheet.
+ */
+ phy_ts_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_1588);
+ phy_ts_base_write(phydev, 29, 0x7ae0);
+ phy_ts_base_write(phydev, 30, 0xb71c);
+ phy_ts_base_write(phydev, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STANDARD);
+
+ phy_unlock_mdio_bus(phydev);
+
+ vsc8584_set_input_clk_configured(phydev);
+ }
+
+ /* Disable predictor before configuring the 1588 block */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_INGR_PREDICTOR);
+ val &= ~PTP_INGR_PREDICTOR_EN;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_INGR_PREDICTOR,
+ val);
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_PREDICTOR);
+ val &= ~PTP_EGR_PREDICTOR_EN;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_PREDICTOR,
+ val);
+
+ /* By default, the internal clock of fixed rate 250MHz is used */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_CTRL);
+ val &= ~PTP_LTC_CTRL_CLK_SEL_MASK;
+ val |= PTP_LTC_CTRL_CLK_SEL_INTERNAL_250;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_CTRL, val);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_SEQUENCE);
+ val &= ~PTP_LTC_SEQUENCE_A_MASK;
+ val |= PTP_LTC_SEQUENCE_A(ltc_seq_a[PHC_CLK_250MHZ]);
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_SEQUENCE, val);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_SEQ);
+ val &= ~(PTP_LTC_SEQ_ERR_MASK | PTP_LTC_SEQ_ADD_SUB);
+ if (ltc_seq_e[PHC_CLK_250MHZ])
+ val |= PTP_LTC_SEQ_ADD_SUB;
+ val |= PTP_LTC_SEQ_ERR(ltc_seq_e[PHC_CLK_250MHZ]);
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_SEQ, val);
+
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_LTC_1PPS_WIDTH_ADJ,
+ PPS_WIDTH_ADJ);
+
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_INGR_DELAY_FIFO,
+ IS_ENABLED(CONFIG_MACSEC) ?
+ PTP_INGR_DELAY_FIFO_DEPTH_MACSEC :
+ PTP_INGR_DELAY_FIFO_DEPTH_DEFAULT);
+
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_DELAY_FIFO,
+ IS_ENABLED(CONFIG_MACSEC) ?
+ PTP_EGR_DELAY_FIFO_DEPTH_MACSEC :
+ PTP_EGR_DELAY_FIFO_DEPTH_DEFAULT);
+
+ /* Enable n-phase sampler for Viper Rev-B */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_ACCUR_CFG_STATUS);
+ val &= ~(PTP_ACCUR_PPS_OUT_BYPASS | PTP_ACCUR_PPS_IN_BYPASS |
+ PTP_ACCUR_EGR_SOF_BYPASS | PTP_ACCUR_INGR_SOF_BYPASS |
+ PTP_ACCUR_LOAD_SAVE_BYPASS);
+ val |= PTP_ACCUR_PPS_OUT_CALIB_ERR | PTP_ACCUR_PPS_OUT_CALIB_DONE |
+ PTP_ACCUR_PPS_IN_CALIB_ERR | PTP_ACCUR_PPS_IN_CALIB_DONE |
+ PTP_ACCUR_EGR_SOF_CALIB_ERR | PTP_ACCUR_EGR_SOF_CALIB_DONE |
+ PTP_ACCUR_INGR_SOF_CALIB_ERR | PTP_ACCUR_INGR_SOF_CALIB_DONE |
+ PTP_ACCUR_LOAD_SAVE_CALIB_ERR | PTP_ACCUR_LOAD_SAVE_CALIB_DONE;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_ACCUR_CFG_STATUS,
+ val);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_ACCUR_CFG_STATUS);
+ val |= PTP_ACCUR_CALIB_TRIGG;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_ACCUR_CFG_STATUS,
+ val);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_ACCUR_CFG_STATUS);
+ val &= ~PTP_ACCUR_CALIB_TRIGG;
+ val |= PTP_ACCUR_PPS_OUT_CALIB_ERR | PTP_ACCUR_PPS_OUT_CALIB_DONE |
+ PTP_ACCUR_PPS_IN_CALIB_ERR | PTP_ACCUR_PPS_IN_CALIB_DONE |
+ PTP_ACCUR_EGR_SOF_CALIB_ERR | PTP_ACCUR_EGR_SOF_CALIB_DONE |
+ PTP_ACCUR_INGR_SOF_CALIB_ERR | PTP_ACCUR_INGR_SOF_CALIB_DONE |
+ PTP_ACCUR_LOAD_SAVE_CALIB_ERR | PTP_ACCUR_LOAD_SAVE_CALIB_DONE;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_ACCUR_CFG_STATUS,
+ val);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_ACCUR_CFG_STATUS);
+ val |= PTP_ACCUR_CALIB_TRIGG;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_ACCUR_CFG_STATUS,
+ val);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_ACCUR_CFG_STATUS);
+ val &= ~PTP_ACCUR_CALIB_TRIGG;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_ACCUR_CFG_STATUS,
+ val);
+
+ /* Do not access FIFO via SI */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_TSTAMP_FIFO_SI);
+ val &= ~PTP_TSTAMP_FIFO_SI_EN;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_TSTAMP_FIFO_SI,
+ val);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_INGR_REWRITER_CTRL);
+ val &= ~PTP_INGR_REWRITER_REDUCE_PREAMBLE;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_INGR_REWRITER_CTRL,
+ val);
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_REWRITER_CTRL);
+ val &= ~PTP_EGR_REWRITER_REDUCE_PREAMBLE;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_REWRITER_CTRL,
+ val);
+
+ /* Put the flag that indicates the frame has been modified to bit 7 */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_INGR_REWRITER_CTRL);
+ val |= PTP_INGR_REWRITER_FLAG_BIT_OFF(7) | PTP_INGR_REWRITER_FLAG_VAL;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_INGR_REWRITER_CTRL,
+ val);
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_REWRITER_CTRL);
+ val |= PTP_EGR_REWRITER_FLAG_BIT_OFF(7);
+ val &= ~PTP_EGR_REWRITER_FLAG_VAL;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_REWRITER_CTRL,
+ val);
+
+ /* 30bit mode for RX timestamp, only the nanoseconds are kept in
+ * reserved field.
+ */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_INGR_TSP_CTRL);
+ val |= PHY_PTP_INGR_TSP_CTRL_FRACT_NS;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_INGR_TSP_CTRL,
+ val);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_TSP_CTRL);
+ val |= PHY_PTP_EGR_TSP_CTRL_FRACT_NS;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_TSP_CTRL, val);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_SERIAL_TOD_IFACE);
+ val |= PTP_SERIAL_TOD_IFACE_LS_AUTO_CLR;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_SERIAL_TOD_IFACE,
+ val);
+
+ vsc85xx_ts_fsb_init(phydev);
+
+ /* Set the Egress timestamp FIFO configuration and status register */
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_EGR_TS_FIFO_CTRL);
+ val &= ~(PTP_EGR_TS_FIFO_SIG_BYTES_MASK | PTP_EGR_TS_FIFO_THRESH_MASK);
+ /* 16 bytes for the signature, 10 for the timestamp in the TS FIFO */
+ val |= PTP_EGR_TS_FIFO_SIG_BYTES(16) | PTP_EGR_TS_FIFO_THRESH(7);
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_EGR_TS_FIFO_CTRL,
+ val);
+
+ vsc85xx_ts_reset_fifo(phydev);
+
+ val = PTP_IFACE_CTRL_CLK_ENA;
+ if (!IS_ENABLED(CONFIG_MACSEC))
+ val |= PTP_IFACE_CTRL_GMII_PROT;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_IFACE_CTRL, val);
+
+ vsc85xx_ts_set_latencies(phydev);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_VERSION_CODE);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR, MSCC_PHY_PTP_IFACE_CTRL);
+ val |= PTP_IFACE_CTRL_EGR_BYPASS;
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_IFACE_CTRL, val);
+
+ vsc85xx_ts_disable_flows(phydev, EGRESS);
+ vsc85xx_ts_disable_flows(phydev, INGRESS);
+
+ val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_PTP_ANALYZER_MODE);
+ /* Disable INGRESS and EGRESS so engine eng_id can be reconfigured */
+ val &= ~(PTP_ANALYZER_MODE_EGR_ENA_MASK |
+ PTP_ANALYZER_MODE_INGR_ENA_MASK |
+ PTP_ANA_INGR_ENCAP_FLOW_MODE_MASK |
+ PTP_ANA_EGR_ENCAP_FLOW_MODE_MASK);
+ /* Strict matching in flow (packets should match flows from the same
+ * index in all enabled comparators (except PTP)).
+ */
+ val |= PTP_ANA_SPLIT_ENCAP_FLOW | PTP_ANA_INGR_ENCAP_FLOW_MODE(0x7) |
+ PTP_ANA_EGR_ENCAP_FLOW_MODE(0x7);
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_PTP_ANALYZER_MODE,
+ val);
+
+ /* Initialized for ingress and egress flows:
+ * - The Ethernet comparator.
+ * - The IP comparator.
+ * - The PTP comparator.
+ */
+ vsc85xx_eth_cmp1_init(phydev, INGRESS);
+ vsc85xx_ip_cmp1_init(phydev, INGRESS);
+ vsc85xx_ptp_cmp_init(phydev, INGRESS);
+ vsc85xx_eth_cmp1_init(phydev, EGRESS);
+ vsc85xx_ip_cmp1_init(phydev, EGRESS);
+ vsc85xx_ptp_cmp_init(phydev, EGRESS);
+
+ vsc85xx_ts_eth_cmp1_sig(phydev);
+
+ vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+ vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+ vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+ vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
+ phydev->mii_ts = &vsc8531->mii_ts;
+
+ memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+
+ vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+ &phydev->mdio.dev);
+ return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+}
+
+void vsc8584_config_ts_intr(struct phy_device *phydev)
+{
+ struct vsc8531_private *priv = phydev->priv;
+
+ mutex_lock(&priv->ts_lock);
+ vsc85xx_ts_write_csr(phydev, PROCESSOR, MSCC_PHY_1588_VSC85XX_INT_MASK,
+ VSC85XX_1588_INT_MASK_MASK);
+ mutex_unlock(&priv->ts_lock);
+}
+
+int vsc8584_ptp_init(struct phy_device *phydev)
+{
+ switch (phydev->phy_id & phydev->drv->phy_id_mask) {
+ case PHY_ID_VSC8575:
+ case PHY_ID_VSC8582:
+ case PHY_ID_VSC8584:
+ return __vsc8584_init_ptp(phydev);
+ }
+
+ return 0;
+}
+
+irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+{
+ struct vsc8531_private *priv = phydev->priv;
+ int rc;
+
+ mutex_lock(&priv->ts_lock);
+ rc = vsc85xx_ts_read_csr(phydev, PROCESSOR,
+ MSCC_PHY_1588_VSC85XX_INT_STATUS);
+ /* Ack the PTP interrupt */
+ vsc85xx_ts_write_csr(phydev, PROCESSOR,
+ MSCC_PHY_1588_VSC85XX_INT_STATUS, rc);
+
+ if (!(rc & VSC85XX_1588_INT_MASK_MASK)) {
+ mutex_unlock(&priv->ts_lock);
+ return IRQ_NONE;
+ }
+
+ if (rc & VSC85XX_1588_INT_FIFO_ADD) {
+ vsc85xx_get_tx_ts(priv->ptp);
+ } else if (rc & VSC85XX_1588_INT_FIFO_OVERFLOW) {
+ __skb_queue_purge(&priv->ptp->tx_queue);
+ vsc85xx_ts_reset_fifo(phydev);
+ }
+
+ mutex_unlock(&priv->ts_lock);
+ return IRQ_HANDLED;
+}
+
+int vsc8584_ptp_probe(struct phy_device *phydev)
+{
+ struct vsc8531_private *vsc8531 = phydev->priv;
+
+ vsc8531->ptp = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531->ptp),
+ GFP_KERNEL);
+ if (!vsc8531->ptp)
+ return -ENOMEM;
+
+ mutex_init(&vsc8531->phc_lock);
+ mutex_init(&vsc8531->ts_lock);
+
+ /* Retrieve the shared load/save GPIO. Request it as non exclusive as
+ * the same GPIO can be requested by all the PHYs of the same package.
+ * This GPIO must be used with the gpio_lock taken (the lock is shared
+ * between all PHYs).
+ */
+ vsc8531->load_save = devm_gpiod_get_optional(&phydev->mdio.dev, "load-save",
+ GPIOD_FLAGS_BIT_NONEXCLUSIVE |
+ GPIOD_OUT_LOW);
+ if (IS_ERR(vsc8531->load_save)) {
+ phydev_err(phydev, "Can't get load-save GPIO (%ld)\n",
+ PTR_ERR(vsc8531->load_save));
+ return PTR_ERR(vsc8531->load_save);
+ }
+
+ vsc8531->ptp->phydev = phydev;
+
+ return 0;
+}
+
+int vsc8584_ptp_probe_once(struct phy_device *phydev)
+{
+ struct vsc85xx_shared_private *shared =
+ (struct vsc85xx_shared_private *)phydev->shared->priv;
+
+ /* Initialize shared GPIO lock */
+ mutex_init(&shared->gpio_lock);
+
+ return 0;
+}
diff --git a/drivers/net/phy/mscc/mscc_ptp.h b/drivers/net/phy/mscc/mscc_ptp.h
new file mode 100644
index 000000000000..3ea163af0f4f
--- /dev/null
+++ b/drivers/net/phy/mscc/mscc_ptp.h
@@ -0,0 +1,477 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Driver for Microsemi VSC85xx PHYs
+ *
+ * Copyright (c) 2020 Microsemi Corporation
+ */
+
+#ifndef _MSCC_PHY_PTP_H_
+#define _MSCC_PHY_PTP_H_
+
+/* 1588 page Registers */
+#define MSCC_PHY_TS_BIU_ADDR_CNTL 16
+#define BIU_ADDR_EXE 0x8000
+#define BIU_ADDR_READ 0x4000
+#define BIU_ADDR_WRITE 0x0000
+#define BIU_BLK_ID(x) ((x) << 11)
+#define BIU_CSR_ADDR(x) (x)
+#define BIU_ADDR_CNT_MAX 8
+
+#define MSCC_PHY_TS_CSR_DATA_LSB 17
+#define MSCC_PHY_TS_CSR_DATA_MSB 18
+
+#define MSCC_PHY_1588_INGR_VSC85XX_INT_STATUS 0x002d
+#define MSCC_PHY_1588_VSC85XX_INT_STATUS 0x004d
+#define VSC85XX_1588_INT_FIFO_ADD 0x0004
+#define VSC85XX_1588_INT_FIFO_OVERFLOW 0x0001
+
+#define MSCC_PHY_1588_INGR_VSC85XX_INT_MASK 0x002e
+#define MSCC_PHY_1588_VSC85XX_INT_MASK 0x004e
+#define VSC85XX_1588_INT_MASK_MASK (VSC85XX_1588_INT_FIFO_ADD | \
+ VSC85XX_1588_INT_FIFO_OVERFLOW)
+
+/* TS CSR addresses */
+#define MSCC_PHY_ANA_ETH1_NTX_PROT 0x0000
+#define ANA_ETH1_NTX_PROT_SIG_OFF_MASK GENMASK(20, 16)
+#define ANA_ETH1_NTX_PROT_SIG_OFF(x) (((x) << 16) & ANA_ETH1_NTX_PROT_SIG_OFF_MASK)
+#define ANA_ETH1_NTX_PROT_COMPARATOR_MASK GENMASK(2, 0)
+#define ANA_ETH1_NTX_PROT_PTP_OAM 0x0005
+#define ANA_ETH1_NTX_PROT_MPLS 0x0004
+#define ANA_ETH1_NTX_PROT_IP_UDP_ACH_2 0x0003
+#define ANA_ETH1_NTX_PROT_IP_UDP_ACH_1 0x0002
+#define ANA_ETH1_NTX_PROT_ETH2 0x0001
+
+#define MSCC_PHY_PTP_IFACE_CTRL 0x0000
+#define PTP_IFACE_CTRL_CLK_ENA 0x0040
+#define PTP_IFACE_CTRL_INGR_BYPASS 0x0008
+#define PTP_IFACE_CTRL_EGR_BYPASS 0x0004
+#define PTP_IFACE_CTRL_MII_PROT 0x0003
+#define PTP_IFACE_CTRL_GMII_PROT 0x0002
+#define PTP_IFACE_CTRL_XGMII_64_PROT 0x0000
+
+#define MSCC_PHY_ANA_ETH1_NTX_PROT_VLAN_TPID 0x0001
+#define ANA_ETH1_NTX_PROT_VLAN_TPID_MASK GENMASK(31, 16)
+#define ANA_ETH1_NTX_PROT_VLAN_TPID(x) (((x) << 16) & ANA_ETH1_NTX_PROT_VLAN_TPID_MASK)
+
+#define MSCC_PHY_PTP_ANALYZER_MODE 0x0001
+#define PTP_ANA_SPLIT_ENCAP_FLOW 0x1000000
+#define PTP_ANA_EGR_ENCAP_FLOW_MODE_MASK GENMASK(22, 20)
+#define PTP_ANA_EGR_ENCAP_FLOW_MODE(x) (((x) << 20) & PTP_ANA_EGR_ENCAP_FLOW_MODE_MASK)
+#define PTP_ANA_INGR_ENCAP_FLOW_MODE_MASK GENMASK(18, 16)
+#define PTP_ANA_INGR_ENCAP_FLOW_MODE(x) (((x) << 16) & PTP_ANA_INGR_ENCAP_FLOW_MODE_MASK)
+#define PTP_ANALYZER_MODE_EGR_ENA_MASK GENMASK(6, 4)
+#define PTP_ANALYZER_MODE_EGR_ENA(x) (((x) << 4) & PTP_ANALYZER_MODE_EGR_ENA_MASK)
+#define PTP_ANALYZER_MODE_INGR_ENA_MASK GENMASK(2, 0)
+#define PTP_ANALYZER_MODE_INGR_ENA(x) ((x) & PTP_ANALYZER_MODE_INGR_ENA_MASK)
+
+#define MSCC_PHY_ANA_ETH1_NXT_PROT_TAG 0x0002
+#define ANA_ETH1_NXT_PROT_TAG_ENA 0x0001
+
+#define MSCC_PHY_PTP_MODE_CTRL 0x0002
+#define PTP_MODE_CTRL_MODE_MASK GENMASK(2, 0)
+#define PTP_MODE_CTRL_PKT_MODE 0x0004
+
+#define MSCC_PHY_ANA_ETH1_NXT_PROT_ETYPE_MATCH 0x0003
+#define ANA_ETH1_NXT_PROT_ETYPE_MATCH_ENA 0x10000
+#define ANA_ETH1_NXT_PROT_ETYPE_MATCH_MASK GENMASK(15, 0)
+#define ANA_ETH1_NXT_PROT_ETYPE_MATCH(x) ((x) & ANA_ETH1_NXT_PROT_ETYPE_MATCH_MASK)
+
+#define MSCC_PHY_PTP_VERSION_CODE 0x0003
+#define PTP_IP_VERSION_MASK GENMASK(7, 0)
+#define PTP_IP_VERSION_2_1 0x0021
+
+#define MSCC_ANA_ETH1_FLOW_ENA(x) (0x0010 + ((x) << 4))
+#define ETH1_FLOW_ENA_CHANNEL_MASK_MASK GENMASK(9, 8)
+#define ETH1_FLOW_ENA_CHANNEL_MASK(x) (((x) << 8) & ETH1_FLOW_ENA_CHANNEL_MASK_MASK)
+#define ETH1_FLOW_VALID_CH1 ETH1_FLOW_ENA_CHANNEL_MASK(2)
+#define ETH1_FLOW_VALID_CH0 ETH1_FLOW_ENA_CHANNEL_MASK(1)
+#define ETH1_FLOW_ENA 0x0001
+
+#define MSCC_ANA_ETH1_FLOW_MATCH_MODE(x) (MSCC_ANA_ETH1_FLOW_ENA(x) + 1)
+#define ANA_ETH1_FLOW_MATCH_VLAN_TAG_MASK GENMASK(7, 6)
+#define ANA_ETH1_FLOW_MATCH_VLAN_TAG(x) (((x) << 6) & ANA_ETH1_FLOW_MATCH_VLAN_TAG_MASK)
+#define ANA_ETH1_FLOW_MATCH_VLAN_TAG2 0x0200
+#define ANA_ETH1_FLOW_MATCH_VLAN_VERIFY 0x0010
+
+#define MSCC_ANA_ETH1_FLOW_ADDR_MATCH1(x) (MSCC_ANA_ETH1_FLOW_ENA(x) + 2)
+
+#define MSCC_ANA_ETH1_FLOW_ADDR_MATCH2(x) (MSCC_ANA_ETH1_FLOW_ENA(x) + 3)
+#define ANA_ETH1_FLOW_ADDR_MATCH2_MASK_MASK GENMASK(22, 20)
+#define ANA_ETH1_FLOW_ADDR_MATCH2_ANY_MULTICAST 0x400000
+#define ANA_ETH1_FLOW_ADDR_MATCH2_FULL_ADDR 0x100000
+#define ANA_ETH1_FLOW_ADDR_MATCH2_SRC_DEST_MASK GENMASK(17, 16)
+#define ANA_ETH1_FLOW_ADDR_MATCH2_SRC_DEST 0x020000
+#define ANA_ETH1_FLOW_ADDR_MATCH2_SRC 0x010000
+#define ANA_ETH1_FLOW_ADDR_MATCH2_DEST 0x000000
+
+#define MSCC_ANA_ETH1_FLOW_VLAN_RANGE_I_TAG(x) (MSCC_ANA_ETH1_FLOW_ENA(x) + 4)
+#define MSCC_ANA_ETH1_FLOW_VLAN_TAG1(x) (MSCC_ANA_ETH1_FLOW_ENA(x) + 5)
+#define MSCC_ANA_ETH1_FLOW_VLAN_TAG2_I_TAG(x) (MSCC_ANA_ETH1_FLOW_ENA(x) + 6)
+
+#define MSCC_PHY_PTP_LTC_CTRL 0x0010
+#define PTP_LTC_CTRL_CLK_SEL_MASK GENMASK(14, 12)
+#define PTP_LTC_CTRL_CLK_SEL(x) (((x) << 12) & PTP_LTC_CTRL_CLK_SEL_MASK)
+#define PTP_LTC_CTRL_CLK_SEL_INTERNAL_250 PTP_LTC_CTRL_CLK_SEL(5)
+#define PTP_LTC_CTRL_AUTO_ADJ_UPDATE 0x0010
+#define PTP_LTC_CTRL_ADD_SUB_1NS_REQ 0x0008
+#define PTP_LTC_CTRL_ADD_1NS 0x0004
+#define PTP_LTC_CTRL_SAVE_ENA 0x0002
+#define PTP_LTC_CTRL_LOAD_ENA 0x0001
+
+#define MSCC_PHY_PTP_LTC_LOAD_SEC_MSB 0x0011
+#define PTP_LTC_LOAD_SEC_MSB(x) (((x) & GENMASK_ULL(47, 32)) >> 32)
+
+#define MSCC_PHY_PTP_LTC_LOAD_SEC_LSB 0x0012
+#define PTP_LTC_LOAD_SEC_LSB(x) ((x) & GENMASK(31, 0))
+
+#define MSCC_PHY_PTP_LTC_LOAD_NS 0x0013
+#define PTP_LTC_LOAD_NS(x) ((x) & GENMASK(31, 0))
+
+#define MSCC_PHY_PTP_LTC_SAVED_SEC_MSB 0x0014
+#define MSCC_PHY_PTP_LTC_SAVED_SEC_LSB 0x0015
+#define MSCC_PHY_PTP_LTC_SAVED_NS 0x0016
+
+#define MSCC_PHY_PTP_LTC_SEQUENCE 0x0017
+#define PTP_LTC_SEQUENCE_A_MASK GENMASK(3, 0)
+#define PTP_LTC_SEQUENCE_A(x) ((x) & PTP_LTC_SEQUENCE_A_MASK)
+
+#define MSCC_PHY_PTP_LTC_SEQ 0x0018
+#define PTP_LTC_SEQ_ADD_SUB 0x80000
+#define PTP_LTC_SEQ_ERR_MASK GENMASK(18, 0)
+#define PTP_LTC_SEQ_ERR(x) ((x) & PTP_LTC_SEQ_ERR_MASK)
+
+#define MSCC_PHY_PTP_LTC_AUTO_ADJ 0x001a
+#define PTP_AUTO_ADJ_NS_ROLLOVER(x) ((x) & GENMASK(29, 0))
+#define PTP_AUTO_ADJ_ADD_SUB_1NS_MASK GENMASK(31, 30)
+#define PTP_AUTO_ADJ_SUB_1NS 0x80000000
+#define PTP_AUTO_ADJ_ADD_1NS 0x40000000
+
+#define MSCC_PHY_PTP_LTC_1PPS_WIDTH_ADJ 0x001b
+#define PTP_LTC_1PPS_WIDTH_ADJ_MASK GENMASK(29, 0)
+
+#define MSCC_PHY_PTP_TSTAMP_FIFO_SI 0x0020
+#define PTP_TSTAMP_FIFO_SI_EN 0x0001
+
+#define MSCC_PHY_PTP_INGR_PREDICTOR 0x0022
+#define PTP_INGR_PREDICTOR_EN 0x0001
+
+#define MSCC_PHY_PTP_EGR_PREDICTOR 0x0026
+#define PTP_EGR_PREDICTOR_EN 0x0001
+
+#define MSCC_PHY_PTP_INGR_TSP_CTRL 0x0035
+#define PHY_PTP_INGR_TSP_CTRL_FRACT_NS 0x0004
+#define PHY_PTP_INGR_TSP_CTRL_LOAD_DELAYS 0x0001
+
+#define MSCC_PHY_PTP_INGR_LOCAL_LATENCY 0x0037
+#define PTP_INGR_LOCAL_LATENCY_MASK GENMASK(22, 0)
+#define PTP_INGR_LOCAL_LATENCY(x) ((x) & PTP_INGR_LOCAL_LATENCY_MASK)
+
+#define MSCC_PHY_PTP_INGR_DELAY_FIFO 0x003a
+#define PTP_INGR_DELAY_FIFO_DEPTH_MACSEC 0x0013
+#define PTP_INGR_DELAY_FIFO_DEPTH_DEFAULT 0x000f
+
+#define MSCC_PHY_PTP_INGR_TS_FIFO(x) (0x005c + (x))
+#define PTP_INGR_TS_FIFO_EMPTY 0x80000000
+
+#define MSCC_PHY_PTP_INGR_REWRITER_CTRL 0x0044
+#define PTP_INGR_REWRITER_REDUCE_PREAMBLE 0x0010
+#define PTP_INGR_REWRITER_FLAG_VAL 0x0008
+#define PTP_INGR_REWRITER_FLAG_BIT_OFF_M GENMASK(2, 0)
+#define PTP_INGR_REWRITER_FLAG_BIT_OFF(x) ((x) & PTP_INGR_REWRITER_FLAG_BIT_OFF_M)
+
+#define MSCC_PHY_PTP_EGR_STALL_LATENCY 0x004f
+
+#define MSCC_PHY_PTP_EGR_TSP_CTRL 0x0055
+#define PHY_PTP_EGR_TSP_CTRL_FRACT_NS 0x0004
+#define PHY_PTP_EGR_TSP_CTRL_LOAD_DELAYS 0x0001
+
+#define MSCC_PHY_PTP_EGR_LOCAL_LATENCY 0x0057
+#define PTP_EGR_LOCAL_LATENCY_MASK GENMASK(22, 0)
+#define PTP_EGR_LOCAL_LATENCY(x) ((x) & PTP_EGR_LOCAL_LATENCY_MASK)
+
+#define MSCC_PHY_PTP_EGR_DELAY_FIFO 0x005a
+#define PTP_EGR_DELAY_FIFO_DEPTH_MACSEC 0x0013
+#define PTP_EGR_DELAY_FIFO_DEPTH_DEFAULT 0x000f
+
+#define MSCC_PHY_PTP_EGR_TS_FIFO_CTRL 0x005b
+#define PTP_EGR_TS_FIFO_RESET 0x10000
+#define PTP_EGR_FIFO_LEVEL_LAST_READ_MASK GENMASK(15, 12)
+#define PTP_EGR_FIFO_LEVEL_LAST_READ(x) (((x) & PTP_EGR_FIFO_LEVEL_LAST_READ_MASK) >> 12)
+#define PTP_EGR_TS_FIFO_THRESH_MASK GENMASK(11, 8)
+#define PTP_EGR_TS_FIFO_THRESH(x) (((x) << 8) & PTP_EGR_TS_FIFO_THRESH_MASK)
+#define PTP_EGR_TS_FIFO_SIG_BYTES_MASK GENMASK(4, 0)
+#define PTP_EGR_TS_FIFO_SIG_BYTES(x) ((x) & PTP_EGR_TS_FIFO_SIG_BYTES_MASK)
+
+#define MSCC_PHY_PTP_EGR_TS_FIFO(x) (0x005c + (x))
+#define PTP_EGR_TS_FIFO_EMPTY 0x80000000
+#define PTP_EGR_TS_FIFO_0_MASK GENMASK(15, 0)
+
+#define MSCC_PHY_PTP_EGR_REWRITER_CTRL 0x0064
+#define PTP_EGR_REWRITER_REDUCE_PREAMBLE 0x0010
+#define PTP_EGR_REWRITER_FLAG_VAL 0x0008
+#define PTP_EGR_REWRITER_FLAG_BIT_OFF_M GENMASK(2, 0)
+#define PTP_EGR_REWRITER_FLAG_BIT_OFF(x) ((x) & PTP_EGR_REWRITER_FLAG_BIT_OFF_M)
+
+#define MSCC_PHY_PTP_SERIAL_TOD_IFACE 0x006e
+#define PTP_SERIAL_TOD_IFACE_LS_AUTO_CLR 0x0004
+
+#define MSCC_PHY_PTP_LTC_OFFSET 0x0070
+#define PTP_LTC_OFFSET_ADJ BIT(31)
+#define PTP_LTC_OFFSET_ADD BIT(30)
+#define PTP_LTC_OFFSET_VAL(x) (x)
+
+#define MSCC_PHY_PTP_ACCUR_CFG_STATUS 0x0074
+#define PTP_ACCUR_PPS_OUT_CALIB_ERR 0x20000
+#define PTP_ACCUR_PPS_OUT_CALIB_DONE 0x10000
+#define PTP_ACCUR_PPS_IN_CALIB_ERR 0x4000
+#define PTP_ACCUR_PPS_IN_CALIB_DONE 0x2000
+#define PTP_ACCUR_EGR_SOF_CALIB_ERR 0x1000
+#define PTP_ACCUR_EGR_SOF_CALIB_DONE 0x0800
+#define PTP_ACCUR_INGR_SOF_CALIB_ERR 0x0400
+#define PTP_ACCUR_INGR_SOF_CALIB_DONE 0x0200
+#define PTP_ACCUR_LOAD_SAVE_CALIB_ERR 0x0100
+#define PTP_ACCUR_LOAD_SAVE_CALIB_DONE 0x0080
+#define PTP_ACCUR_CALIB_TRIGG 0x0040
+#define PTP_ACCUR_PPS_OUT_BYPASS 0x0010
+#define PTP_ACCUR_PPS_IN_BYPASS 0x0008
+#define PTP_ACCUR_EGR_SOF_BYPASS 0x0004
+#define PTP_ACCUR_INGR_SOF_BYPASS 0x0002
+#define PTP_ACCUR_LOAD_SAVE_BYPASS 0x0001
+
+#define MSCC_PHY_ANA_ETH2_NTX_PROT 0x0090
+#define ANA_ETH2_NTX_PROT_COMPARATOR_MASK GENMASK(2, 0)
+#define ANA_ETH2_NTX_PROT_PTP_OAM 0x0005
+#define ANA_ETH2_NTX_PROT_MPLS 0x0004
+#define ANA_ETH2_NTX_PROT_IP_UDP_ACH_2 0x0003
+#define ANA_ETH2_NTX_PROT_IP_UDP_ACH_1 0x0002
+#define ANA_ETH2_NTX_PROT_ETH2 0x0001
+
+#define MSCC_PHY_ANA_ETH2_NXT_PROT_ETYPE_MATCH 0x0003
+#define ANA_ETH2_NXT_PROT_ETYPE_MATCH_ENA 0x10000
+#define ANA_ETH2_NXT_PROT_ETYPE_MATCH_MASK GENMASK(15, 0)
+#define ANA_ETH2_NXT_PROT_ETYPE_MATCH(x) ((x) & ANA_ETH2_NXT_PROT_ETYPE_MATCH_MASK)
+
+#define MSCC_ANA_ETH2_FLOW_ENA(x) (0x00a0 + ((x) << 4))
+#define ETH2_FLOW_ENA_CHANNEL_MASK_MASK GENMASK(9, 8)
+#define ETH2_FLOW_ENA_CHANNEL_MASK(x) (((x) << 8) & ETH2_FLOW_ENA_CHANNEL_MASK_MASK)
+#define ETH2_FLOW_VALID_CH1 ETH2_FLOW_ENA_CHANNEL_MASK(2)
+#define ETH2_FLOW_VALID_CH0 ETH2_FLOW_ENA_CHANNEL_MASK(1)
+
+#define MSCC_PHY_ANA_MPLS_COMP_NXT_COMP 0x0120
+#define ANA_MPLS_NTX_PROT_COMPARATOR_MASK GENMASK(2, 0)
+#define ANA_MPLS_NTX_PROT_PTP_OAM 0x0005
+#define ANA_MPLS_NTX_PROT_MPLS 0x0004
+#define ANA_MPLS_NTX_PROT_IP_UDP_ACH_2 0x0003
+#define ANA_MPLS_NTX_PROT_IP_UDP_ACH_1 0x0002
+#define ANA_MPLS_NTX_PROT_ETH2 0x0001
+
+#define MSCC_ANA_MPLS_FLOW_CTRL(x) (0x0130 + ((x) << 4))
+#define MPLS_FLOW_CTRL_CHANNEL_MASK_MASK GENMASK(25, 24)
+#define MPLS_FLOW_CTRL_CHANNEL_MASK(x) (((x) << 24) & MPLS_FLOW_CTRL_CHANNEL_MASK_MASK)
+#define MPLS_FLOW_VALID_CH1 MPLS_FLOW_CTRL_CHANNEL_MASK(2)
+#define MPLS_FLOW_VALID_CH0 MPLS_FLOW_CTRL_CHANNEL_MASK(1)
+
+#define MSCC_ANA_IP1_NXT_PROT_NXT_COMP 0x01b0
+#define ANA_IP1_NXT_PROT_NXT_COMP_BYTES_HDR_MASK GENMASK(15, 8)
+#define ANA_IP1_NXT_PROT_NXT_COMP_BYTES_HDR(x) (((x) << 8) & ANA_IP1_NXT_PROT_NXT_COMP_BYTES_HDR_MASK)
+#define ANA_IP1_NXT_PROT_NXT_COMP_PTP_OAM 0x0005
+#define ANA_IP1_NXT_PROT_NXT_COMP_IP_UDP_ACH2 0x0003
+
+#define MSCC_ANA_IP1_NXT_PROT_IP1_MODE 0x01b1
+#define ANA_IP1_NXT_PROT_FLOW_OFFSET_IPV4 0x0c00
+#define ANA_IP1_NXT_PROT_FLOW_OFFSET_IPV6 0x0800
+#define ANA_IP1_NXT_PROT_IPV6 0x0001
+#define ANA_IP1_NXT_PROT_IPV4 0x0000
+
+#define MSCC_ANA_IP1_NXT_PROT_IP_MATCH1 0x01b2
+#define ANA_IP1_NXT_PROT_IP_MATCH1_PROT_OFF_MASK GENMASK(20, 16)
+#define ANA_IP1_NXT_PROT_IP_MATCH1_PROT_OFF(x) (((x) << 16) & ANA_IP1_NXT_PROT_IP_MATCH1_PROT_OFF_MASK)
+#define ANA_IP1_NXT_PROT_IP_MATCH1_PROT_MASK_MASK GENMASK(15, 8)
+#define ANA_IP1_NXT_PROT_IP_MATCH1_PROT_MASK(x) (((x) << 15) & ANA_IP1_NXT_PROT_IP_MATCH1_PROT_MASK_MASK)
+#define ANA_IP1_NXT_PROT_IP_MATCH1_PROT_MATCH_MASK GENMASK(7, 0)
+#define ANA_IP1_NXT_PROT_IP_MATCH1_PROT_MATCH(x) ((x) & ANA_IP1_NXT_PROT_IP_MATCH1_PROT_MATCH_MASK)
+
+#define MSCC_ANA_IP1_NXT_PROT_MATCH2_UPPER 0x01b3
+#define MSCC_ANA_IP1_NXT_PROT_MATCH2_LOWER 0x01b4
+#define MSCC_ANA_IP1_NXT_PROT_MASK2_UPPER 0x01b5
+#define MSCC_ANA_IP1_NXT_PROT_MASK2_LOWER 0x01b6
+
+#define MSCC_ANA_IP1_NXT_PROT_OFFSET2 0x01b7
+#define ANA_IP1_NXT_PROT_OFFSET2_MASK GENMASK(6, 0)
+#define ANA_IP1_NXT_PROT_OFFSET2(x) ((x) & ANA_IP1_NXT_PROT_OFFSET2_MASK)
+
+#define MSCC_ANA_IP1_NXT_PROT_UDP_CHKSUM 0x01b8
+#define IP1_NXT_PROT_UDP_CHKSUM_OFF_MASK GENMASK(15, 8)
+#define IP1_NXT_PROT_UDP_CHKSUM_OFF(x) (((x) << 8) & IP1_NXT_PROT_UDP_CHKSUM_OFF_MASK)
+#define IP1_NXT_PROT_UDP_CHKSUM_WIDTH_MASK GENMASK(5, 4)
+#define IP1_NXT_PROT_UDP_CHKSUM_WIDTH(x) (((x) << 4) & IP1_NXT_PROT_UDP_CHKSUM_WIDTH_MASK)
+#define IP1_NXT_PROT_UDP_CHKSUM_UPDATE 0x0002
+#define IP1_NXT_PROT_UDP_CHKSUM_CLEAR 0x0001
+
+#define MSCC_ANA_IP1_FLOW_ENA(x) (0x01c0 + ((x) << 4))
+#define IP1_FLOW_MATCH_ADDR_MASK GENMASK(9, 8)
+#define IP1_FLOW_MATCH_DEST_SRC_ADDR 0x0200
+#define IP1_FLOW_MATCH_DEST_ADDR 0x0100
+#define IP1_FLOW_MATCH_SRC_ADDR 0x0000
+#define IP1_FLOW_ENA_CHANNEL_MASK_MASK GENMASK(5, 4)
+#define IP1_FLOW_ENA_CHANNEL_MASK(x) (((x) << 4) & IP1_FLOW_ENA_CHANNEL_MASK_MASK)
+#define IP1_FLOW_VALID_CH1 IP1_FLOW_ENA_CHANNEL_MASK(2)
+#define IP1_FLOW_VALID_CH0 IP1_FLOW_ENA_CHANNEL_MASK(1)
+#define IP1_FLOW_ENA 0x0001
+
+#define MSCC_ANA_OAM_PTP_FLOW_ENA(x) (0x1e0 + ((x) << 4))
+#define MSCC_ANA_OAM_PTP_FLOW_MATCH_LOWER(x) (MSCC_ANA_OAM_PTP_FLOW_ENA(x) + 2)
+#define MSCC_ANA_OAM_PTP_FLOW_MASK_LOWER(x) (MSCC_ANA_OAM_PTP_FLOW_ENA(x) + 4)
+
+#define MSCC_ANA_OAM_PTP_FLOW_PTP_0_FIELD(x) (MSCC_ANA_OAM_PTP_FLOW_ENA(x) + 8)
+
+#define MSCC_ANA_IP1_FLOW_MATCH_UPPER(x) (MSCC_ANA_IP1_FLOW_ENA(x) + 1)
+#define MSCC_ANA_IP1_FLOW_MATCH_UPPER_MID(x) (MSCC_ANA_IP1_FLOW_ENA(x) + 2)
+#define MSCC_ANA_IP1_FLOW_MATCH_LOWER_MID(x) (MSCC_ANA_IP1_FLOW_ENA(x) + 3)
+#define MSCC_ANA_IP1_FLOW_MATCH_LOWER(x) (MSCC_ANA_IP1_FLOW_ENA(x) + 4)
+#define MSCC_ANA_IP1_FLOW_MASK_UPPER(x) (MSCC_ANA_IP1_FLOW_ENA(x) + 5)
+#define MSCC_ANA_IP1_FLOW_MASK_UPPER_MID(x) (MSCC_ANA_IP1_FLOW_ENA(x) + 6)
+#define MSCC_ANA_IP1_FLOW_MASK_LOWER_MID(x) (MSCC_ANA_IP1_FLOW_ENA(x) + 7)
+#define MSCC_ANA_IP1_FLOW_MASK_LOWER(x) (MSCC_ANA_IP1_FLOW_ENA(x) + 8)
+
+#define MSCC_ANA_IP2_NXT_PROT_NXT_COMP 0x0240
+#define ANA_IP2_NXT_PROT_NXT_COMP_BYTES_HDR_MASK GENMASK(15, 8)
+#define ANA_IP2_NXT_PROT_NXT_COMP_BYTES_HDR(x) (((x) << 8) & ANA_IP2_NXT_PROT_NXT_COMP_BYTES_HDR_MASK)
+#define ANA_IP2_NXT_PROT_NXT_COMP_PTP_OAM 0x0005
+#define ANA_IP2_NXT_PROT_NXT_COMP_IP_UDP_ACH2 0x0003
+
+#define MSCC_ANA_IP2_NXT_PROT_UDP_CHKSUM 0x0248
+#define IP2_NXT_PROT_UDP_CHKSUM_OFF_MASK GENMASK(15, 8)
+#define IP2_NXT_PROT_UDP_CHKSUM_OFF(x) (((x) << 8) & IP2_NXT_PROT_UDP_CHKSUM_OFF_MASK)
+#define IP2_NXT_PROT_UDP_CHKSUM_WIDTH_MASK GENMASK(5, 4)
+#define IP2_NXT_PROT_UDP_CHKSUM_WIDTH(x) (((x) << 4) & IP2_NXT_PROT_UDP_CHKSUM_WIDTH_MASK)
+
+#define MSCC_ANA_IP2_FLOW_ENA(x) (0x0250 + ((x) << 4))
+#define IP2_FLOW_ENA_CHANNEL_MASK_MASK GENMASK(5, 4)
+#define IP2_FLOW_ENA_CHANNEL_MASK(x) (((x) << 4) & IP2_FLOW_ENA_CHANNEL_MASK_MASK)
+#define IP2_FLOW_VALID_CH1 IP2_FLOW_ENA_CHANNEL_MASK(2)
+#define IP2_FLOW_VALID_CH0 IP2_FLOW_ENA_CHANNEL_MASK(1)
+
+#define MSCC_ANA_PTP_FLOW_ENA(x) (0x02d0 + ((x) << 4))
+#define PTP_FLOW_ENA_CHANNEL_MASK_MASK GENMASK(5, 4)
+#define PTP_FLOW_ENA_CHANNEL_MASK(x) (((x) << 4) & PTP_FLOW_ENA_CHANNEL_MASK_MASK)
+#define PTP_FLOW_VALID_CH1 PTP_FLOW_ENA_CHANNEL_MASK(2)
+#define PTP_FLOW_VALID_CH0 PTP_FLOW_ENA_CHANNEL_MASK(1)
+#define PTP_FLOW_ENA 0x0001
+
+#define MSCC_ANA_PTP_FLOW_MATCH_UPPER(x) (MSCC_ANA_PTP_FLOW_ENA(x) + 1)
+#define PTP_FLOW_MSG_TYPE_MASK 0x0F000000
+#define PTP_FLOW_MSG_PDELAY_RESP 0x04000000
+#define PTP_FLOW_MSG_PDELAY_REQ 0x02000000
+#define PTP_FLOW_MSG_DELAY_REQ 0x01000000
+#define PTP_FLOW_MSG_SYNC 0x00000000
+
+#define MSCC_ANA_PTP_FLOW_MATCH_LOWER(x) (MSCC_ANA_PTP_FLOW_ENA(x) + 2)
+#define MSCC_ANA_PTP_FLOW_MASK_UPPER(x) (MSCC_ANA_PTP_FLOW_ENA(x) + 3)
+#define MSCC_ANA_PTP_FLOW_MASK_LOWER(x) (MSCC_ANA_PTP_FLOW_ENA(x) + 4)
+
+#define MSCC_ANA_PTP_FLOW_DOMAIN_RANGE(x) (MSCC_ANA_PTP_FLOW_ENA(x) + 5)
+#define PTP_FLOW_DOMAIN_RANGE_ENA 0x0001
+
+#define MSCC_ANA_PTP_FLOW_PTP_ACTION(x) (MSCC_ANA_PTP_FLOW_ENA(x) + 6)
+#define PTP_FLOW_PTP_ACTION_MOD_FRAME_STATUS_UPDATE 0x10000000
+#define PTP_FLOW_PTP_ACTION_MOD_FRAME_STATUS_BYTE_OFFSET_MASK GENMASK(26, 24)
+#define PTP_FLOW_PTP_ACTION_MOD_FRAME_STATUS_BYTE_OFFSET(x) (((x) << 24) & PTP_FLOW_PTP_ACTION_MOD_FRAME_STATUS_BYTE_OFFSET_MASK)
+#define PTP_FLOW_PTP_ACTION_PTP_CMD_MASK GENMASK(3, 0)
+#define PTP_FLOW_PTP_ACTION_PTP_CMD(x) ((x) & PTP_FLOW_PTP_ACTION_PTP_CMD_MASK)
+#define PTP_FLOW_PTP_ACTION_SUB_DELAY_ASYM 0x00200000
+#define PTP_FLOW_PTP_ACTION_ADD_DELAY_ASYM 0x00100000
+#define PTP_FLOW_PTP_ACTION_TIME_OFFSET_MASK GENMASK(15, 10)
+#define PTP_FLOW_PTP_ACTION_TIME_OFFSET(x) (((x) << 10) & PTP_FLOW_PTP_ACTION_TIME_OFFSET_MASK)
+#define PTP_FLOW_PTP_ACTION_CORR_OFFSET_MASK GENMASK(9, 5)
+#define PTP_FLOW_PTP_ACTION_CORR_OFFSET(x) (((x) << 5) & PTP_FLOW_PTP_ACTION_CORR_OFFSET_MASK)
+#define PTP_FLOW_PTP_ACTION_SAVE_LOCAL_TIME 0x00000010
+
+#define MSCC_ANA_PTP_FLOW_PTP_ACTION2(x) (MSCC_ANA_PTP_FLOW_ENA(x) + 7)
+#define PTP_FLOW_PTP_ACTION2_REWRITE_OFFSET_MASK GENMASK(15, 8)
+#define PTP_FLOW_PTP_ACTION2_REWRITE_OFFSET(x) (((x) << 8) & PTP_FLOW_PTP_ACTION2_REWRITE_OFFSET_MASK)
+#define PTP_FLOW_PTP_ACTION2_REWRITE_BYTES_MASK GENMASK(3, 0)
+#define PTP_FLOW_PTP_ACTION2_REWRITE_BYTES(x) ((x) & PTP_FLOW_PTP_ACTION2_REWRITE_BYTES_MASK)
+
+#define MSCC_ANA_PTP_FLOW_PTP_0_FIELD(x) (MSCC_ANA_PTP_FLOW_ENA(x) + 8)
+#define PTP_FLOW_PTP_0_FIELD_PTP_FRAME 0x8000
+#define PTP_FLOW_PTP_0_FIELD_RSVRD_CHECK 0x4000
+#define PTP_FLOW_PTP_0_FIELD_OFFSET_MASK GENMASK(13, 8)
+#define PTP_FLOW_PTP_0_FIELD_OFFSET(x) (((x) << 8) & PTP_FLOW_PTP_0_FIELD_OFFSET_MASK)
+#define PTP_FLOW_PTP_0_FIELD_BYTES_MASK GENMASK(3, 0)
+#define PTP_FLOW_PTP_0_FIELD_BYTES(x) ((x) & PTP_FLOW_PTP_0_FIELD_BYTES_MASK)
+
+#define MSCC_ANA_PTP_IP_CHKSUM_SEL 0x0330
+#define ANA_PTP_IP_CHKSUM_SEL_IP_COMP_2 0x0001
+#define ANA_PTP_IP_CHKSUM_SEL_IP_COMP_1 0x0000
+
+#define MSCC_PHY_ANA_FSB_CFG 0x331
+#define ANA_FSB_ADDR_FROM_BLOCK_SEL_MASK GENMASK(1, 0)
+#define ANA_FSB_ADDR_FROM_IP2 0x0003
+#define ANA_FSB_ADDR_FROM_IP1 0x0002
+#define ANA_FSB_ADDR_FROM_ETH2 0x0001
+#define ANA_FSB_ADDR_FROM_ETH1 0x0000
+
+#define MSCC_PHY_ANA_FSB_REG(x) (0x332 + (x))
+
+#define COMP_MAX_FLOWS 8
+#define PTP_COMP_MAX_FLOWS 6
+
+#define PPS_WIDTH_ADJ 0x1dcd6500
+#define STALL_EGR_LATENCY(x) (1536000 / (x))
+
+/* PHC clock available frequencies. */
+enum {
+ PHC_CLK_125MHZ,
+ PHC_CLK_156_25MHZ,
+ PHC_CLK_200MHZ,
+ PHC_CLK_250MHZ,
+ PHC_CLK_500MHZ,
+};
+
+enum ptp_cmd {
+ PTP_NOP = 0,
+ PTP_WRITE_1588 = 5,
+ PTP_WRITE_NS = 7,
+ PTP_SAVE_IN_TS_FIFO = 11, /* invalid when writing in reg */
+};
+
+enum vsc85xx_ptp_msg_type {
+ PTP_MSG_TYPE_SYNC,
+ PTP_MSG_TYPE_DELAY_REQ,
+};
+
+struct vsc85xx_ptphdr {
+ u8 tsmt; /* transportSpecific | messageType */
+ u8 ver; /* reserved0 | versionPTP */
+ __be16 msglen;
+ u8 domain;
+ u8 rsrvd1;
+ __be16 flags;
+ __be64 correction;
+ __be32 rsrvd2;
+ __be64 clk_identity;
+ __be16 src_port_id;
+ __be16 seq_id;
+ u8 ctrl;
+ u8 log_interval;
+} __attribute__((__packed__));
+
+/* Represents an entry in the timestamping FIFO */
+struct vsc85xx_ts_fifo {
+ u32 ns;
+ u64 secs:48;
+ u8 sig[16];
+} __attribute__((__packed__));
+
+struct vsc85xx_ptp {
+ struct phy_device *phydev;
+ struct ptp_clock *ptp_clock;
+ struct ptp_clock_info caps;
+ struct sk_buff_head tx_queue;
+ enum hwtstamp_tx_types tx_type;
+ enum hwtstamp_rx_filters rx_filter;
+ u8 configured:1;
+};
+
+#endif /* _MSCC_PHY_PTP_H_ */
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index defe09d94422..bd11e62bfdfe 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -219,7 +219,7 @@ int genphy_c45_read_link(struct phy_device *phydev)
int val, devad;
bool link = true;
- if (phydev->c45_ids.devices_in_package & MDIO_DEVS_AN) {
+ if (phydev->c45_ids.mmds_present & MDIO_DEVS_AN) {
val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
if (val < 0)
return val;
@@ -409,7 +409,7 @@ int genphy_c45_pma_read_abilities(struct phy_device *phydev)
int val;
linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
- if (phydev->c45_ids.devices_in_package & MDIO_DEVS_AN) {
+ if (phydev->c45_ids.mmds_present & MDIO_DEVS_AN) {
val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
if (val < 0)
return val;
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index 46bd68e9ecfa..ff8e14b01eeb 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -8,7 +8,7 @@
const char *phy_speed_to_str(int speed)
{
- BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 75,
+ BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 90,
"Enum ethtool_link_mode_bit_indices and phylib are out of sync. "
"If a speed or mode has been added please update phy_speed_to_str "
"and the PHY settings array.\n");
@@ -78,12 +78,22 @@ static const struct phy_setting settings[] = {
PHY_SETTING( 400000, FULL, 400000baseLR8_ER8_FR8_Full ),
PHY_SETTING( 400000, FULL, 400000baseDR8_Full ),
PHY_SETTING( 400000, FULL, 400000baseSR8_Full ),
+ PHY_SETTING( 400000, FULL, 400000baseCR4_Full ),
+ PHY_SETTING( 400000, FULL, 400000baseKR4_Full ),
+ PHY_SETTING( 400000, FULL, 400000baseLR4_ER4_FR4_Full ),
+ PHY_SETTING( 400000, FULL, 400000baseDR4_Full ),
+ PHY_SETTING( 400000, FULL, 400000baseSR4_Full ),
/* 200G */
PHY_SETTING( 200000, FULL, 200000baseCR4_Full ),
PHY_SETTING( 200000, FULL, 200000baseKR4_Full ),
PHY_SETTING( 200000, FULL, 200000baseLR4_ER4_FR4_Full ),
PHY_SETTING( 200000, FULL, 200000baseDR4_Full ),
PHY_SETTING( 200000, FULL, 200000baseSR4_Full ),
+ PHY_SETTING( 200000, FULL, 200000baseCR2_Full ),
+ PHY_SETTING( 200000, FULL, 200000baseKR2_Full ),
+ PHY_SETTING( 200000, FULL, 200000baseLR2_ER2_FR2_Full ),
+ PHY_SETTING( 200000, FULL, 200000baseDR2_Full ),
+ PHY_SETTING( 200000, FULL, 200000baseSR2_Full ),
/* 100G */
PHY_SETTING( 100000, FULL, 100000baseCR4_Full ),
PHY_SETTING( 100000, FULL, 100000baseKR4_Full ),
@@ -94,6 +104,11 @@ static const struct phy_setting settings[] = {
PHY_SETTING( 100000, FULL, 100000baseLR2_ER2_FR2_Full ),
PHY_SETTING( 100000, FULL, 100000baseDR2_Full ),
PHY_SETTING( 100000, FULL, 100000baseSR2_Full ),
+ PHY_SETTING( 100000, FULL, 100000baseCR_Full ),
+ PHY_SETTING( 100000, FULL, 100000baseKR_Full ),
+ PHY_SETTING( 100000, FULL, 100000baseLR_ER_FR_Full ),
+ PHY_SETTING( 100000, FULL, 100000baseDR_Full ),
+ PHY_SETTING( 100000, FULL, 100000baseSR_Full ),
/* 56G */
PHY_SETTING( 56000, FULL, 56000baseCR4_Full ),
PHY_SETTING( 56000, FULL, 56000baseKR4_Full ),
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 56cfae950472..79b4f35d151e 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -489,6 +489,54 @@ static void phy_abort_cable_test(struct phy_device *phydev)
phydev_err(phydev, "Error while aborting cable test");
}
+int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data)
+{
+ if (!phydev->drv)
+ return -EIO;
+
+ mutex_lock(&phydev->lock);
+ phydev->drv->get_strings(phydev, data);
+ mutex_unlock(&phydev->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(phy_ethtool_get_strings);
+
+int phy_ethtool_get_sset_count(struct phy_device *phydev)
+{
+ int ret;
+
+ if (!phydev->drv)
+ return -EIO;
+
+ if (phydev->drv->get_sset_count &&
+ phydev->drv->get_strings &&
+ phydev->drv->get_stats) {
+ mutex_lock(&phydev->lock);
+ ret = phydev->drv->get_sset_count(phydev);
+ mutex_unlock(&phydev->lock);
+
+ return ret;
+ }
+
+ return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(phy_ethtool_get_sset_count);
+
+int phy_ethtool_get_stats(struct phy_device *phydev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ if (!phydev->drv)
+ return -EIO;
+
+ mutex_lock(&phydev->lock);
+ phydev->drv->get_stats(phydev, stats, data);
+ mutex_unlock(&phydev->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(phy_ethtool_get_stats);
+
int phy_start_cable_test(struct phy_device *phydev,
struct netlink_ext_ack *extack)
{
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index b4978c5fb2ca..1b9523595839 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -9,28 +9,29 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
+#include <linux/bitmap.h>
#include <linux/delay.h>
-#include <linux/netdevice.h>
+#include <linux/errno.h>
#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mdio.h>
+#include <linux/mii.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/bitmap.h>
+#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/phy_led_triggers.h>
+#include <linux/property.h>
#include <linux/sfp.h>
-#include <linux/mdio.h>
-#include <linux/io.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/uaccess.h>
+#include <linux/unistd.h>
MODULE_DESCRIPTION("PHY library");
MODULE_AUTHOR("Andy Fleming");
@@ -105,10 +106,9 @@ const int phy_10gbit_features_array[1] = {
};
EXPORT_SYMBOL_GPL(phy_10gbit_features_array);
-const int phy_10gbit_fec_features_array[1] = {
+static const int phy_10gbit_fec_features_array[1] = {
ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
};
-EXPORT_SYMBOL_GPL(phy_10gbit_fec_features_array);
__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init;
EXPORT_SYMBOL_GPL(phy_10gbit_full_features);
@@ -226,7 +226,6 @@ static void phy_mdio_device_remove(struct mdio_device *mdiodev)
}
static struct phy_driver genphy_driver;
-extern struct phy_driver genphy_c45_driver;
static LIST_HEAD(phy_fixup_list);
static DEFINE_MUTEX(phy_fixup_lock);
@@ -661,6 +660,28 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
}
EXPORT_SYMBOL(phy_device_create);
+/* phy_c45_probe_present - checks to see if a MMD is present in the package
+ * @bus: the target MII bus
+ * @prtad: PHY package address on the MII bus
+ * @devad: PHY device (MMD) address
+ *
+ * Read the MDIO_STAT2 register, and check whether a device is responding
+ * at this address.
+ *
+ * Returns: negative error number on bus access error, zero if no device
+ * is responding, or positive if a device is present.
+ */
+static int phy_c45_probe_present(struct mii_bus *bus, int prtad, int devad)
+{
+ int stat2;
+
+ stat2 = mdiobus_c45_read(bus, prtad, devad, MDIO_STAT2);
+ if (stat2 < 0)
+ return stat2;
+
+ return (stat2 & MDIO_STAT2_DEVPRST) == MDIO_STAT2_DEVPRST_VAL;
+}
+
/* get_phy_c45_devs_in_pkg - reads a MMD's devices in package registers.
* @bus: the target MII bus
* @addr: PHY address on the MII bus
@@ -687,9 +708,6 @@ static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr,
return -EIO;
*devices_in_package |= phy_reg;
- /* Bit 0 doesn't represent a device, it indicates c22 regs presence */
- *devices_in_package &= ~BIT(0);
-
return 0;
}
@@ -697,54 +715,78 @@ static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr,
* get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs.
* @bus: the target MII bus
* @addr: PHY address on the MII bus
- * @phy_id: where to store the ID retrieved.
* @c45_ids: where to store the c45 ID information.
*
- * If the PHY devices-in-package appears to be valid, it and the
- * corresponding identifiers are stored in @c45_ids, zero is stored
- * in @phy_id. Otherwise 0xffffffff is stored in @phy_id. Returns
- * zero on success.
+ * Read the PHY "devices in package". If this appears to be valid, read
+ * the PHY identifiers for each device. Return the "devices in package"
+ * and identifiers in @c45_ids.
*
+ * Returns zero on success, %-EIO on bus access error, or %-ENODEV if
+ * the "devices in package" is invalid.
*/
-static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id,
+static int get_phy_c45_ids(struct mii_bus *bus, int addr,
struct phy_c45_device_ids *c45_ids)
{
const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
- u32 *devs = &c45_ids->devices_in_package;
- int i, phy_reg;
+ u32 devs_in_pkg = 0;
+ int i, ret, phy_reg;
/* Find first non-zero Devices In package. Device zero is reserved
* for 802.3 c45 complied PHYs, so don't probe it at first.
*/
- for (i = 1; i < num_ids && *devs == 0; i++) {
- phy_reg = get_phy_c45_devs_in_pkg(bus, addr, i, devs);
- if (phy_reg < 0)
- return -EIO;
-
- if ((*devs & 0x1fffffff) == 0x1fffffff) {
- /* If mostly Fs, there is no device there,
- * then let's continue to probe more, as some
- * 10G PHYs have zero Devices In package,
- * e.g. Cortina CS4315/CS4340 PHY.
+ for (i = 1; i < MDIO_MMD_NUM && (devs_in_pkg == 0 ||
+ (devs_in_pkg & 0x1fffffff) == 0x1fffffff); i++) {
+ if (i == MDIO_MMD_VEND1 || i == MDIO_MMD_VEND2) {
+ /* Check that there is a device present at this
+ * address before reading the devices-in-package
+ * register to avoid reading garbage from the PHY.
+ * Some PHYs (88x3310) vendor space is not IEEE802.3
+ * compliant.
*/
- phy_reg = get_phy_c45_devs_in_pkg(bus, addr, 0, devs);
- if (phy_reg < 0)
+ ret = phy_c45_probe_present(bus, addr, i);
+ if (ret < 0)
return -EIO;
- /* no device there, let's get out of here */
- if ((*devs & 0x1fffffff) == 0x1fffffff) {
- *phy_id = 0xffffffff;
- return 0;
- } else {
- break;
- }
+
+ if (!ret)
+ continue;
}
+ phy_reg = get_phy_c45_devs_in_pkg(bus, addr, i, &devs_in_pkg);
+ if (phy_reg < 0)
+ return -EIO;
+ }
+
+ if ((devs_in_pkg & 0x1fffffff) == 0x1fffffff) {
+ /* If mostly Fs, there is no device there, then let's probe
+ * MMD 0, as some 10G PHYs have zero Devices In package,
+ * e.g. Cortina CS4315/CS4340 PHY.
+ */
+ phy_reg = get_phy_c45_devs_in_pkg(bus, addr, 0, &devs_in_pkg);
+ if (phy_reg < 0)
+ return -EIO;
+
+ /* no device there, let's get out of here */
+ if ((devs_in_pkg & 0x1fffffff) == 0x1fffffff)
+ return -ENODEV;
}
/* Now probe Device Identifiers for each device present. */
for (i = 1; i < num_ids; i++) {
- if (!(c45_ids->devices_in_package & (1 << i)))
+ if (!(devs_in_pkg & (1 << i)))
continue;
+ if (i == MDIO_MMD_VEND1 || i == MDIO_MMD_VEND2) {
+ /* Probe the "Device Present" bits for the vendor MMDs
+ * to ignore these if they do not contain IEEE 802.3
+ * registers.
+ */
+ ret = phy_c45_probe_present(bus, addr, i);
+ if (ret < 0)
+ return ret;
+
+ if (!ret)
+ continue;
+ }
+
phy_reg = mdiobus_c45_read(bus, addr, i, MII_PHYSID1);
if (phy_reg < 0)
return -EIO;
@@ -755,34 +797,29 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id,
return -EIO;
c45_ids->device_ids[i] |= phy_reg;
}
- *phy_id = 0;
+
+ c45_ids->devices_in_package = devs_in_pkg;
+ /* Bit 0 doesn't represent a device, it indicates c22 regs presence */
+ c45_ids->mmds_present = devs_in_pkg & ~BIT(0);
+
return 0;
}
/**
- * get_phy_id - reads the specified addr for its ID.
+ * get_phy_c22_id - reads the specified addr for its clause 22 ID.
* @bus: the target MII bus
* @addr: PHY address on the MII bus
* @phy_id: where to store the ID retrieved.
- * @is_c45: If true the PHY uses the 802.3 clause 45 protocol
- * @c45_ids: where to store the c45 ID information.
- *
- * Description: In the case of a 802.3-c22 PHY, reads the ID registers
- * of the PHY at @addr on the @bus, stores it in @phy_id and returns
- * zero on success.
- *
- * In the case of a 802.3-c45 PHY, get_phy_c45_ids() is invoked, and
- * its return value is in turn returned.
*
+ * Read the 802.3 clause 22 PHY ID from the PHY at @addr on the @bus,
+ * placing it in @phy_id. Return zero on successful read and the ID is
+ * valid, %-EIO on bus access error, or %-ENODEV if no device responds
+ * or invalid ID.
*/
-static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
- bool is_c45, struct phy_c45_device_ids *c45_ids)
+static int get_phy_c22_id(struct mii_bus *bus, int addr, u32 *phy_id)
{
int phy_reg;
- if (is_c45)
- return get_phy_c45_ids(bus, addr, phy_id, c45_ids);
-
/* Grab the bits from PHYIR1, and put them in the upper half */
phy_reg = mdiobus_read(bus, addr, MII_PHYSID1);
if (phy_reg < 0) {
@@ -801,6 +838,10 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
*phy_id |= phy_reg;
+ /* If the phy_id is mostly Fs, there is no device there */
+ if ((*phy_id & 0x1fffffff) == 0x1fffffff)
+ return -ENODEV;
+
return 0;
}
@@ -811,8 +852,17 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
* @addr: PHY address on the MII bus
* @is_c45: If true the PHY uses the 802.3 clause 45 protocol
*
- * Description: Reads the ID registers of the PHY at @addr on the
- * @bus, then allocates and returns the phy_device to represent it.
+ * Probe for a PHY at @addr on @bus.
+ *
+ * When probing for a clause 22 PHY, then read the ID registers. If we find
+ * a valid ID, allocate and return a &struct phy_device.
+ *
+ * When probing for a clause 45 PHY, read the "devices in package" registers.
+ * If the "devices in package" appears valid, read the ID registers for each
+ * MMD, allocate and return a &struct phy_device.
+ *
+ * Returns an allocated &struct phy_device on success, %-ENODEV if there is
+ * no PHY present, or %-EIO on bus access error.
*/
struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
{
@@ -821,16 +871,17 @@ struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
int r;
c45_ids.devices_in_package = 0;
+ c45_ids.mmds_present = 0;
memset(c45_ids.device_ids, 0xff, sizeof(c45_ids.device_ids));
- r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids);
+ if (is_c45)
+ r = get_phy_c45_ids(bus, addr, &c45_ids);
+ else
+ r = get_phy_c22_id(bus, addr, &phy_id);
+
if (r)
return ERR_PTR(r);
- /* If the phy_id is mostly Fs, there is no device there */
- if ((phy_id & 0x1fffffff) == 0x1fffffff)
- return ERR_PTR(-ENODEV);
-
return phy_device_create(bus, addr, phy_id, is_c45, &c45_ids);
}
EXPORT_SYMBOL(get_phy_device);
@@ -2663,6 +2714,104 @@ void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause)
}
EXPORT_SYMBOL(phy_get_pause);
+#if IS_ENABLED(CONFIG_OF_MDIO)
+static int phy_get_int_delay_property(struct device *dev, const char *name)
+{
+ s32 int_delay;
+ int ret;
+
+ ret = device_property_read_u32(dev, name, &int_delay);
+ if (ret)
+ return ret;
+
+ return int_delay;
+}
+#else
+static int phy_get_int_delay_property(struct device *dev, const char *name)
+{
+ return -EINVAL;
+}
+#endif
+
+/**
+ * phy_get_delay_index - returns the index of the internal delay
+ * @phydev: phy_device struct
+ * @dev: pointer to the devices device struct
+ * @delay_values: array of delays the PHY supports
+ * @size: the size of the delay array
+ * @is_rx: boolean to indicate to get the rx internal delay
+ *
+ * Returns the index within the array of internal delay passed in.
+ * If the device property is not present then the interface type is checked
+ * if the interface defines use of internal delay then a 1 is returned otherwise
+ * a 0 is returned.
+ * The array must be in ascending order. If PHY does not have an ascending order
+ * array then size = 0 and the value of the delay property is returned.
+ * Return -EINVAL if the delay is invalid or cannot be found.
+ */
+s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
+ const int *delay_values, int size, bool is_rx)
+{
+ s32 delay;
+ int i;
+
+ if (is_rx) {
+ delay = phy_get_int_delay_property(dev, "rx-internal-delay-ps");
+ if (delay < 0 && size == 0) {
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ return 1;
+ else
+ return 0;
+ }
+
+ } else {
+ delay = phy_get_int_delay_property(dev, "tx-internal-delay-ps");
+ if (delay < 0 && size == 0) {
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ return 1;
+ else
+ return 0;
+ }
+ }
+
+ if (delay < 0)
+ return delay;
+
+ if (delay && size == 0)
+ return delay;
+
+ if (delay < delay_values[0] || delay > delay_values[size - 1]) {
+ phydev_err(phydev, "Delay %d is out of range\n", delay);
+ return -EINVAL;
+ }
+
+ if (delay == delay_values[0])
+ return 0;
+
+ for (i = 1; i < size; i++) {
+ if (delay == delay_values[i])
+ return i;
+
+ /* Find an approximate index by looking up the table */
+ if (delay > delay_values[i - 1] &&
+ delay < delay_values[i]) {
+ if (delay - delay_values[i - 1] <
+ delay_values[i] - delay)
+ return i - 1;
+ else
+ return i;
+ }
+ }
+
+ phydev_err(phydev, "error finding internal delay index for %d\n",
+ delay);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(phy_get_internal_delay);
+
static bool phy_drv_supports_irq(struct phy_driver *phydrv)
{
return phydrv->config_intr && phydrv->ack_interrupt;
@@ -2696,16 +2845,13 @@ static int phy_probe(struct device *dev)
mutex_lock(&phydev->lock);
- if (phydev->drv->probe) {
- /* Deassert the reset signal */
- phy_device_reset(phydev, 0);
+ /* Deassert the reset signal */
+ phy_device_reset(phydev, 0);
+ if (phydev->drv->probe) {
err = phydev->drv->probe(phydev);
- if (err) {
- /* Assert the reset signal */
- phy_device_reset(phydev, 1);
+ if (err)
goto out;
- }
}
/* Start out supporting everything. Eventually,
@@ -2767,6 +2913,10 @@ static int phy_probe(struct device *dev)
phydev->state = PHY_READY;
out:
+ /* Assert the reset signal */
+ if (err)
+ phy_device_reset(phydev, 1);
+
mutex_unlock(&phydev->lock);
return err;
@@ -2785,12 +2935,12 @@ static int phy_remove(struct device *dev)
sfp_bus_del_upstream(phydev->sfp_bus);
phydev->sfp_bus = NULL;
- if (phydev->drv && phydev->drv->remove) {
+ if (phydev->drv && phydev->drv->remove)
phydev->drv->remove(phydev);
- /* Assert the reset signal */
- phy_device_reset(phydev, 1);
- }
+ /* Assert the reset signal */
+ phy_device_reset(phydev, 1);
+
phydev->drv = NULL;
return 0;
@@ -2878,6 +3028,14 @@ static struct phy_driver genphy_driver = {
.set_loopback = genphy_loopback,
};
+static const struct ethtool_phy_ops phy_ethtool_phy_ops = {
+ .get_sset_count = phy_ethtool_get_sset_count,
+ .get_strings = phy_ethtool_get_strings,
+ .get_stats = phy_ethtool_get_stats,
+ .start_cable_test = phy_start_cable_test,
+ .start_cable_test_tdr = phy_start_cable_test_tdr,
+};
+
static int __init phy_init(void)
{
int rc;
@@ -2886,6 +3044,7 @@ static int __init phy_init(void)
if (rc)
return rc;
+ ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops);
features_init();
rc = phy_driver_register(&genphy_c45_driver, THIS_MODULE);
@@ -2907,6 +3066,7 @@ static void __exit phy_exit(void)
phy_driver_unregister(&genphy_c45_driver);
phy_driver_unregister(&genphy_driver);
mdio_bus_exit();
+ ethtool_set_ethtool_phy_ops(NULL);
}
subsys_initcall(phy_init);
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 3b7c70e6c5dd..32b4bd6a5b55 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -43,6 +43,7 @@ struct phylink {
const struct phylink_mac_ops *mac_ops;
const struct phylink_pcs_ops *pcs_ops;
struct phylink_config *config;
+ struct phylink_pcs *pcs;
struct device *dev;
unsigned int old_link_state:1;
@@ -241,8 +242,10 @@ static int phylink_parse_fixedlink(struct phylink *pl,
phylink_set(pl->supported, MII);
phylink_set(pl->supported, Pause);
phylink_set(pl->supported, Asym_Pause);
+ phylink_set(pl->supported, Autoneg);
if (s) {
__set_bit(s->bit, pl->supported);
+ __set_bit(s->bit, pl->link_config.lp_advertising);
} else {
phylink_warn(pl, "fixed link %s duplex %dMbps not recognised\n",
pl->link_config.duplex == DUPLEX_FULL ? "full" : "half",
@@ -419,39 +422,102 @@ static void phylink_mac_config(struct phylink *pl,
pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, state);
}
-static void phylink_mac_config_up(struct phylink *pl,
- const struct phylink_link_state *state)
-{
- if (state->link)
- phylink_mac_config(pl, state);
-}
-
static void phylink_mac_pcs_an_restart(struct phylink *pl)
{
if (pl->link_config.an_enabled &&
- phy_interface_mode_is_8023z(pl->link_config.interface)) {
+ phy_interface_mode_is_8023z(pl->link_config.interface) &&
+ phylink_autoneg_inband(pl->cur_link_an_mode)) {
if (pl->pcs_ops)
- pl->pcs_ops->pcs_an_restart(pl->config);
+ pl->pcs_ops->pcs_an_restart(pl->pcs);
else
pl->mac_ops->mac_an_restart(pl->config);
}
}
-static void phylink_pcs_config(struct phylink *pl, bool force_restart,
- const struct phylink_link_state *state)
+static void phylink_major_config(struct phylink *pl, bool restart,
+ const struct phylink_link_state *state)
{
- bool restart = force_restart;
+ int err;
+
+ phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
- if (pl->pcs_ops && pl->pcs_ops->pcs_config(pl->config,
- pl->cur_link_an_mode,
- state->interface,
- state->advertising))
- restart = true;
+ if (pl->mac_ops->mac_prepare) {
+ err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
+ state->interface);
+ if (err < 0) {
+ phylink_err(pl, "mac_prepare failed: %pe\n",
+ ERR_PTR(err));
+ return;
+ }
+ }
phylink_mac_config(pl, state);
+ if (pl->pcs_ops) {
+ err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
+ state->interface,
+ state->advertising,
+ !!(pl->link_config.pause &
+ MLO_PAUSE_AN));
+ if (err < 0)
+ phylink_err(pl, "pcs_config failed: %pe\n",
+ ERR_PTR(err));
+ if (err > 0)
+ restart = true;
+ }
if (restart)
phylink_mac_pcs_an_restart(pl);
+
+ if (pl->mac_ops->mac_finish) {
+ err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode,
+ state->interface);
+ if (err < 0)
+ phylink_err(pl, "mac_prepare failed: %pe\n",
+ ERR_PTR(err));
+ }
+}
+
+/*
+ * Reconfigure for a change of inband advertisement.
+ * If we have a separate PCS, we only need to call its pcs_config() method,
+ * and then restart AN if it indicates something changed. Otherwise, we do
+ * the full MAC reconfiguration.
+ */
+static int phylink_change_inband_advert(struct phylink *pl)
+{
+ int ret;
+
+ if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
+ return 0;
+
+ if (!pl->pcs_ops) {
+ /* Legacy method */
+ phylink_mac_config(pl, &pl->link_config);
+ phylink_mac_pcs_an_restart(pl);
+ return 0;
+ }
+
+ phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__,
+ phylink_an_mode_str(pl->cur_link_an_mode),
+ phy_modes(pl->link_config.interface),
+ __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising,
+ pl->link_config.pause);
+
+ /* Modern PCS-based method; update the advert at the PCS, and
+ * restart negotiation if the pcs_config() helper indicates that
+ * the programmed advertisement has changed.
+ */
+ ret = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
+ pl->link_config.interface,
+ pl->link_config.advertising,
+ !!(pl->link_config.pause & MLO_PAUSE_AN));
+ if (ret < 0)
+ return ret;
+
+ if (ret > 0)
+ phylink_mac_pcs_an_restart(pl);
+
+ return 0;
}
static void phylink_mac_pcs_get_state(struct phylink *pl,
@@ -468,7 +534,7 @@ static void phylink_mac_pcs_get_state(struct phylink *pl,
state->link = 1;
if (pl->pcs_ops)
- pl->pcs_ops->pcs_get_state(pl->config, state);
+ pl->pcs_ops->pcs_get_state(pl->pcs, state);
else
pl->mac_ops->mac_pcs_get_state(pl->config, state);
}
@@ -514,7 +580,7 @@ static void phylink_mac_initial_config(struct phylink *pl, bool force_restart)
link_state.link = false;
phylink_apply_manual_flow(pl, &link_state);
- phylink_pcs_config(pl, force_restart, &link_state);
+ phylink_major_config(pl, force_restart, &link_state);
}
static const char *phylink_pause_to_str(int pause)
@@ -539,7 +605,7 @@ static void phylink_link_up(struct phylink *pl,
pl->cur_interface = link_state.interface;
if (pl->pcs_ops && pl->pcs_ops->pcs_link_up)
- pl->pcs_ops->pcs_link_up(pl->config, pl->cur_link_an_mode,
+ pl->pcs_ops->pcs_link_up(pl->pcs, pl->cur_link_an_mode,
pl->cur_interface,
link_state.speed, link_state.duplex);
@@ -575,9 +641,15 @@ static void phylink_resolve(struct work_struct *w)
struct phylink *pl = container_of(w, struct phylink, resolve);
struct phylink_link_state link_state;
struct net_device *ndev = pl->netdev;
- int link_changed;
+ bool mac_config = false;
+ bool cur_link_state;
mutex_lock(&pl->state_mutex);
+ if (pl->netdev)
+ cur_link_state = netif_carrier_ok(ndev);
+ else
+ cur_link_state = pl->old_link_state;
+
if (pl->phylink_disable_state) {
pl->mac_link_dropped = false;
link_state.link = false;
@@ -588,12 +660,12 @@ static void phylink_resolve(struct work_struct *w)
case MLO_AN_PHY:
link_state = pl->phy_state;
phylink_apply_manual_flow(pl, &link_state);
- phylink_mac_config_up(pl, &link_state);
+ mac_config = link_state.link;
break;
case MLO_AN_FIXED:
phylink_get_fixed_state(pl, &link_state);
- phylink_mac_config_up(pl, &link_state);
+ mac_config = link_state.link;
break;
case MLO_AN_INBAND:
@@ -611,21 +683,36 @@ static void phylink_resolve(struct work_struct *w)
/* If we have a PHY, we need to update with
* the PHY flow control bits. */
link_state.pause = pl->phy_state.pause;
- phylink_apply_manual_flow(pl, &link_state);
- phylink_mac_config(pl, &link_state);
- } else {
- phylink_apply_manual_flow(pl, &link_state);
+ mac_config = true;
}
+ phylink_apply_manual_flow(pl, &link_state);
break;
}
}
- if (pl->netdev)
- link_changed = (link_state.link != netif_carrier_ok(ndev));
- else
- link_changed = (link_state.link != pl->old_link_state);
+ if (mac_config) {
+ if (link_state.interface != pl->link_config.interface) {
+ /* The interface has changed, force the link down and
+ * then reconfigure.
+ */
+ if (cur_link_state) {
+ phylink_link_down(pl);
+ cur_link_state = false;
+ }
+ phylink_major_config(pl, false, &link_state);
+ pl->link_config.interface = link_state.interface;
+ } else if (!pl->pcs_ops) {
+ /* The interface remains unchanged, only the speed,
+ * duplex or pause settings have changed. Call the
+ * old mac_config() method to configure the MAC/PCS
+ * only if we do not have a PCS installed (an
+ * unconverted user.)
+ */
+ phylink_mac_config(pl, &link_state);
+ }
+ }
- if (link_changed) {
+ if (link_state.link != cur_link_state) {
pl->old_link_state = link_state.link;
if (!link_state.link)
phylink_link_down(pl);
@@ -777,11 +864,26 @@ struct phylink *phylink_create(struct phylink_config *config,
}
EXPORT_SYMBOL_GPL(phylink_create);
-void phylink_add_pcs(struct phylink *pl, const struct phylink_pcs_ops *ops)
+/**
+ * phylink_set_pcs() - set the current PCS for phylink to use
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @pcs: a pointer to the &struct phylink_pcs
+ *
+ * Bind the MAC PCS to phylink. This may be called after phylink_create(),
+ * in mac_prepare() or mac_config() methods if it is desired to dynamically
+ * change the PCS.
+ *
+ * Please note that there are behavioural changes with the mac_config()
+ * callback if a PCS is present (denoting a newer setup) so removing a PCS
+ * is not supported, and if a PCS is going to be used, it must be registered
+ * by calling phylink_set_pcs() at the latest in the first mac_config() call.
+ */
+void phylink_set_pcs(struct phylink *pl, struct phylink_pcs *pcs)
{
- pl->pcs_ops = ops;
+ pl->pcs = pcs;
+ pl->pcs_ops = pcs->ops;
}
-EXPORT_SYMBOL_GPL(phylink_add_pcs);
+EXPORT_SYMBOL_GPL(phylink_set_pcs);
/**
* phylink_destroy() - cleanup and destroy the phylink instance
@@ -1126,6 +1228,8 @@ void phylink_start(struct phylink *pl)
break;
case MLO_AN_INBAND:
poll |= pl->config->pcs_poll;
+ if (pl->pcs)
+ poll |= pl->pcs->poll;
break;
}
if (poll)
@@ -1295,27 +1399,46 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
const struct ethtool_link_ksettings *kset)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(support);
- struct ethtool_link_ksettings our_kset;
struct phylink_link_state config;
- int ret;
+ const struct phy_setting *s;
ASSERT_RTNL();
- if (kset->base.autoneg != AUTONEG_DISABLE &&
- kset->base.autoneg != AUTONEG_ENABLE)
- return -EINVAL;
+ if (pl->phydev) {
+ /* We can rely on phylib for this update; we also do not need
+ * to update the pl->link_config settings:
+ * - the configuration returned via ksettings_get() will come
+ * from phylib whenever a PHY is present.
+ * - link_config.interface will be updated by the PHY calling
+ * back via phylink_phy_change() and a subsequent resolve.
+ * - initial link configuration for PHY mode comes from the
+ * last phy state updated via phylink_phy_change().
+ * - other configuration changes (e.g. pause modes) are
+ * performed directly via phylib.
+ * - if in in-band mode with a PHY, the link configuration
+ * is passed on the link from the PHY, and all of
+ * link_config.{speed,duplex,an_enabled,pause} are not used.
+ * - the only possible use would be link_config.advertising
+ * pause modes when in 1000base-X mode with a PHY, but in
+ * the presence of a PHY, this should not be changed as that
+ * should be determined from the media side advertisement.
+ */
+ return phy_ethtool_ksettings_set(pl->phydev, kset);
+ }
linkmode_copy(support, pl->supported);
config = pl->link_config;
+ config.an_enabled = kset->base.autoneg == AUTONEG_ENABLE;
- /* Mask out unsupported advertisements */
+ /* Mask out unsupported advertisements, and force the autoneg bit */
linkmode_and(config.advertising, kset->link_modes.advertising,
support);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising,
+ config.an_enabled);
/* FIXME: should we reject autoneg if phy/mac does not support it? */
- if (kset->base.autoneg == AUTONEG_DISABLE) {
- const struct phy_setting *s;
-
+ switch (kset->base.autoneg) {
+ case AUTONEG_DISABLE:
/* Autonegotiation disabled, select a suitable speed and
* duplex.
*/
@@ -1324,90 +1447,73 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
if (!s)
return -EINVAL;
- /* If we have a fixed link (as specified by firmware), refuse
- * to change link parameters.
+ /* If we have a fixed link, refuse to change link parameters.
+ * If the link parameters match, accept them but do nothing.
*/
- if (pl->cur_link_an_mode == MLO_AN_FIXED &&
- (s->speed != pl->link_config.speed ||
- s->duplex != pl->link_config.duplex))
- return -EINVAL;
+ if (pl->cur_link_an_mode == MLO_AN_FIXED) {
+ if (s->speed != pl->link_config.speed ||
+ s->duplex != pl->link_config.duplex)
+ return -EINVAL;
+ return 0;
+ }
config.speed = s->speed;
config.duplex = s->duplex;
- config.an_enabled = false;
+ break;
- __clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising);
- } else {
- /* If we have a fixed link, refuse to enable autonegotiation */
- if (pl->cur_link_an_mode == MLO_AN_FIXED)
- return -EINVAL;
+ case AUTONEG_ENABLE:
+ /* If we have a fixed link, allow autonegotiation (since that
+ * is our default case) but do not allow the advertisement to
+ * be changed. If the advertisement matches, simply return.
+ */
+ if (pl->cur_link_an_mode == MLO_AN_FIXED) {
+ if (!linkmode_equal(config.advertising,
+ pl->link_config.advertising))
+ return -EINVAL;
+ return 0;
+ }
config.speed = SPEED_UNKNOWN;
config.duplex = DUPLEX_UNKNOWN;
- config.an_enabled = true;
+ break;
- __set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising);
+ default:
+ return -EINVAL;
}
- if (pl->phydev) {
- /* If we have a PHY, we process the kset change via phylib.
- * phylib will call our link state function if the PHY
- * parameters have changed, which will trigger a resolve
- * and update the MAC configuration.
- */
- our_kset = *kset;
- linkmode_copy(our_kset.link_modes.advertising,
- config.advertising);
- our_kset.base.speed = config.speed;
- our_kset.base.duplex = config.duplex;
+ /* We have ruled out the case with a PHY attached, and the
+ * fixed-link cases. All that is left are in-band links.
+ */
+ if (phylink_validate(pl, support, &config))
+ return -EINVAL;
- ret = phy_ethtool_ksettings_set(pl->phydev, &our_kset);
- if (ret)
- return ret;
+ /* If autonegotiation is enabled, we must have an advertisement */
+ if (config.an_enabled && phylink_is_empty_linkmode(config.advertising))
+ return -EINVAL;
- mutex_lock(&pl->state_mutex);
- /* Save the new configuration */
- linkmode_copy(pl->link_config.advertising,
- our_kset.link_modes.advertising);
+ mutex_lock(&pl->state_mutex);
+ pl->link_config.speed = config.speed;
+ pl->link_config.duplex = config.duplex;
+ pl->link_config.an_enabled = config.an_enabled;
+
+ if (pl->link_config.interface != config.interface) {
+ /* The interface changed, e.g. 1000base-X <-> 2500base-X */
+ /* We need to force the link down, then change the interface */
+ if (pl->old_link_state) {
+ phylink_link_down(pl);
+ pl->old_link_state = false;
+ }
+ if (!test_bit(PHYLINK_DISABLE_STOPPED,
+ &pl->phylink_disable_state))
+ phylink_major_config(pl, false, &config);
pl->link_config.interface = config.interface;
- pl->link_config.speed = our_kset.base.speed;
- pl->link_config.duplex = our_kset.base.duplex;
- pl->link_config.an_enabled = our_kset.base.autoneg !=
- AUTONEG_DISABLE;
- mutex_unlock(&pl->state_mutex);
- } else {
- /* For a fixed link, this isn't able to change any parameters,
- * which just leaves inband mode.
- */
- if (phylink_validate(pl, support, &config))
- return -EINVAL;
-
- /* If autonegotiation is enabled, we must have an advertisement */
- if (config.an_enabled &&
- phylink_is_empty_linkmode(config.advertising))
- return -EINVAL;
-
- mutex_lock(&pl->state_mutex);
linkmode_copy(pl->link_config.advertising, config.advertising);
- pl->link_config.interface = config.interface;
- pl->link_config.speed = config.speed;
- pl->link_config.duplex = config.duplex;
- pl->link_config.an_enabled = kset->base.autoneg !=
- AUTONEG_DISABLE;
-
- if (pl->cur_link_an_mode == MLO_AN_INBAND &&
- !test_bit(PHYLINK_DISABLE_STOPPED,
- &pl->phylink_disable_state)) {
- /* If in 802.3z mode, this updates the advertisement.
- *
- * If we are in SGMII mode without a PHY, there is no
- * advertisement; the only thing we have is the pause
- * modes which can only come from a PHY.
- */
- phylink_pcs_config(pl, true, &pl->link_config);
- }
- mutex_unlock(&pl->state_mutex);
+ } else if (!linkmode_equal(pl->link_config.advertising,
+ config.advertising)) {
+ linkmode_copy(pl->link_config.advertising, config.advertising);
+ phylink_change_inband_advert(pl);
}
+ mutex_unlock(&pl->state_mutex);
return 0;
}
@@ -1510,9 +1616,11 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
config->pause = pause_state;
- if (!pl->phydev && !test_bit(PHYLINK_DISABLE_STOPPED,
- &pl->phylink_disable_state))
- phylink_pcs_config(pl, true, &pl->link_config);
+ /* Update our in-band advertisement, triggering a renegotiation if
+ * the advertisement changed.
+ */
+ if (!pl->phydev)
+ phylink_change_inband_advert(pl);
mutex_unlock(&pl->state_mutex);
@@ -1657,11 +1765,11 @@ static int phylink_phy_read(struct phylink *pl, unsigned int phy_id,
case MII_BMSR:
case MII_PHYSID1:
case MII_PHYSID2:
- devad = __ffs(phydev->c45_ids.devices_in_package);
+ devad = __ffs(phydev->c45_ids.mmds_present);
break;
case MII_ADVERTISE:
case MII_LPA:
- if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN))
+ if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN))
return -EINVAL;
devad = MDIO_MMD_AN;
if (reg == MII_ADVERTISE)
@@ -1697,11 +1805,11 @@ static int phylink_phy_write(struct phylink *pl, unsigned int phy_id,
case MII_BMSR:
case MII_PHYSID1:
case MII_PHYSID2:
- devad = __ffs(phydev->c45_ids.devices_in_package);
+ devad = __ffs(phydev->c45_ids.mmds_present);
break;
case MII_ADVERTISE:
case MII_LPA:
- if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN))
+ if (!(phydev->c45_ids.mmds_present & MDIO_DEVS_AN))
return -EINVAL;
devad = MDIO_MMD_AN;
if (reg == MII_ADVERTISE)
@@ -1845,6 +1953,54 @@ int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd)
}
EXPORT_SYMBOL_GPL(phylink_mii_ioctl);
+/**
+ * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both
+ * link partners
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ * @sync: perform action synchronously
+ *
+ * If we have a PHY that is not part of a SFP module, then set the speed
+ * as described in the phy_speed_down() function. Please see this function
+ * for a description of the @sync parameter.
+ *
+ * Returns zero if there is no PHY, otherwise as per phy_speed_down().
+ */
+int phylink_speed_down(struct phylink *pl, bool sync)
+{
+ int ret = 0;
+
+ ASSERT_RTNL();
+
+ if (!pl->sfp_bus && pl->phydev)
+ ret = phy_speed_down(pl->phydev, sync);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phylink_speed_down);
+
+/**
+ * phylink_speed_up() - restore the advertised speeds prior to the call to
+ * phylink_speed_down()
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
+ *
+ * If we have a PHY that is not part of a SFP module, then restore the
+ * PHY speeds as per phy_speed_up().
+ *
+ * Returns zero if there is no PHY, otherwise as per phy_speed_up().
+ */
+int phylink_speed_up(struct phylink *pl)
+{
+ int ret = 0;
+
+ ASSERT_RTNL();
+
+ if (!pl->sfp_bus && pl->phydev)
+ ret = phy_speed_up(pl->phydev);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phylink_speed_up);
+
static void phylink_sfp_attach(void *upstream, struct sfp_bus *bus)
{
struct phylink *pl = upstream;
@@ -2287,6 +2443,43 @@ int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs,
EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
/**
+ * phylink_mii_c22_pcs_config() - configure clause 22 PCS
+ * @pcs: a pointer to a &struct mdio_device.
+ * @mode: link autonegotiation mode
+ * @interface: the PHY interface mode being configured
+ * @advertising: the ethtool advertisement mask
+ *
+ * Configure a Clause 22 PCS PHY with the appropriate negotiation
+ * parameters for the @mode, @interface and @advertising parameters.
+ * Returns negative error number on failure, zero if the advertisement
+ * has not changed, or positive if there is a change.
+ */
+int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode,
+ phy_interface_t interface,
+ const unsigned long *advertising)
+{
+ bool changed;
+ u16 bmcr;
+ int ret;
+
+ ret = phylink_mii_c22_pcs_set_advertisement(pcs, interface,
+ advertising);
+ if (ret < 0)
+ return ret;
+
+ changed = ret > 0;
+
+ bmcr = mode == MLO_AN_INBAND ? BMCR_ANENABLE : 0;
+ ret = mdiobus_modify(pcs->bus, pcs->addr, MII_BMCR,
+ BMCR_ANENABLE, bmcr);
+ if (ret < 0)
+ return ret;
+
+ return changed ? 1 : 0;
+}
+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_config);
+
+/**
* phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation
* @pcs: a pointer to a &struct mdio_device.
*
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index c7229d022a27..95dbe5e8e1d8 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -638,6 +638,18 @@ static struct phy_driver realtek_drvs[] = {
.read_mmd = rtl8125_read_mmd,
.write_mmd = rtl8125_write_mmd,
}, {
+ PHY_ID_MATCH_EXACT(0x001cc840),
+ .name = "RTL8125B 2.5Gbps internal",
+ .get_features = rtl8125_get_features,
+ .config_aneg = rtl8125_config_aneg,
+ .read_status = rtl8125_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .read_mmd = rtl8125_read_mmd,
+ .write_mmd = rtl8125_write_mmd,
+ }, {
PHY_ID_MATCH_EXACT(0x001cc961),
.name = "RTL8366RB Gigabit Ethernet",
.config_init = &rtl8366rb_config_init,
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 73c2969f11a4..c24b0e83dd32 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1632,10 +1632,43 @@ static int sfp_sm_mod_hpower(struct sfp *sfp, bool enable)
return 0;
}
+static int sfp_cotsworks_fixup_check(struct sfp *sfp, struct sfp_eeprom_id *id)
+{
+ u8 check;
+ int err;
+
+ if (id->base.phys_id != SFF8024_ID_SFF_8472 ||
+ id->base.phys_ext_id != SFP_PHYS_EXT_ID_SFP ||
+ id->base.connector != SFF8024_CONNECTOR_LC) {
+ dev_warn(sfp->dev, "Rewriting fiber module EEPROM with corrected values\n");
+ id->base.phys_id = SFF8024_ID_SFF_8472;
+ id->base.phys_ext_id = SFP_PHYS_EXT_ID_SFP;
+ id->base.connector = SFF8024_CONNECTOR_LC;
+ err = sfp_write(sfp, false, SFP_PHYS_ID, &id->base, 3);
+ if (err != 3) {
+ dev_err(sfp->dev, "Failed to rewrite module EEPROM: %d\n", err);
+ return err;
+ }
+
+ /* Cotsworks modules have been found to require a delay between write operations. */
+ mdelay(50);
+
+ /* Update base structure checksum */
+ check = sfp_check(&id->base, sizeof(id->base) - 1);
+ err = sfp_write(sfp, false, SFP_CC_BASE, &check, 1);
+ if (err != 1) {
+ dev_err(sfp->dev, "Failed to update base structure checksum in fiber module EEPROM: %d\n", err);
+ return err;
+ }
+ }
+ return 0;
+}
+
static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
{
/* SFP module inserted - read I2C data */
struct sfp_eeprom_id id;
+ bool cotsworks_sfbg;
bool cotsworks;
u8 check;
int ret;
@@ -1657,6 +1690,17 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
* serial number and date code.
*/
cotsworks = !memcmp(id.base.vendor_name, "COTSWORKS ", 16);
+ cotsworks_sfbg = !memcmp(id.base.vendor_pn, "SFBG", 4);
+
+ /* Cotsworks SFF module EEPROM do not always have valid phys_id,
+ * phys_ext_id, and connector bytes. Rewrite SFF EEPROM bytes if
+ * Cotsworks PN matches and bytes are not correct.
+ */
+ if (cotsworks && cotsworks_sfbg) {
+ ret = sfp_cotsworks_fixup_check(sfp, &id);
+ if (ret < 0)
+ return ret;
+ }
/* Validate the checksum over the base structure */
check = sfp_check(&id.base, sizeof(id.base) - 1);
@@ -2238,6 +2282,7 @@ static int sfp_probe(struct platform_device *pdev)
{
const struct sff_data *sff;
struct i2c_adapter *i2c;
+ char *sfp_irq_name;
struct sfp *sfp;
int err, i;
@@ -2349,12 +2394,19 @@ static int sfp_probe(struct platform_device *pdev)
continue;
}
+ sfp_irq_name = devm_kasprintf(sfp->dev, GFP_KERNEL,
+ "%s-%s", dev_name(sfp->dev),
+ gpio_of_names[i]);
+
+ if (!sfp_irq_name)
+ return -ENOMEM;
+
err = devm_request_threaded_irq(sfp->dev, sfp->gpio_irq[i],
NULL, sfp_irq,
IRQF_ONESHOT |
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING,
- dev_name(sfp->dev), sfp);
+ sfp_irq_name, sfp);
if (err) {
sfp->gpio_irq[i] = 0;
sfp->need_poll = true;
diff --git a/drivers/net/plip/plip.c b/drivers/net/plip/plip.c
index e89cdebae6f1..d82016dcde3b 100644
--- a/drivers/net/plip/plip.c
+++ b/drivers/net/plip/plip.c
@@ -142,7 +142,7 @@ static void plip_timer_bh(struct work_struct *work);
static void plip_interrupt(void *dev_id);
/* Functions for DEV methods */
-static int plip_tx_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t plip_tx_packet(struct sk_buff *skb, struct net_device *dev);
static int plip_hard_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *daddr,
const void *saddr, unsigned len);
@@ -958,7 +958,7 @@ plip_interrupt(void *dev_id)
spin_unlock_irqrestore(&nl->lock, flags);
}
-static int
+static netdev_tx_t
plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
{
struct net_local *nl = netdev_priv(dev);
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index beedaad08255..d7f50b835050 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -1110,8 +1110,6 @@ static const struct proto_ops pppoe_ops = {
.poll = datagram_poll,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = pppoe_sendmsg,
.recvmsg = pppoe_recvmsg,
.mmap = sock_no_mmap,
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index acccb747aeda..ee5058445d06 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -618,8 +618,6 @@ static const struct proto_ops pptp_ops = {
.getname = pptp_getname,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
.sendmsg = sock_no_sendmsg,
.recvmsg = sock_no_recvmsg,
.mmap = sock_no_mmap,
diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c
index a812726703a4..3160443ef3b9 100644
--- a/drivers/net/thunderbolt.c
+++ b/drivers/net/thunderbolt.c
@@ -1335,6 +1335,10 @@ static int __init tbnet_init(void)
tb_property_add_immediate(tbnet_dir, "prtcid", 1);
tb_property_add_immediate(tbnet_dir, "prtcvers", 1);
tb_property_add_immediate(tbnet_dir, "prtcrevs", 1);
+ /* Currently only announce support for match frags ID (bit 1). Bit 0
+ * is reserved for full E2E flow control which we do not support at
+ * the moment.
+ */
tb_property_add_immediate(tbnet_dir, "prtcstns",
TBNET_MATCH_FRAGS_ID);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 7adeb91bd368..3c11a77f5709 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1184,26 +1184,11 @@ static int tun_xdp_set(struct net_device *dev, struct bpf_prog *prog,
return 0;
}
-static u32 tun_xdp_query(struct net_device *dev)
-{
- struct tun_struct *tun = netdev_priv(dev);
- const struct bpf_prog *xdp_prog;
-
- xdp_prog = rtnl_dereference(tun->xdp_prog);
- if (xdp_prog)
- return xdp_prog->aux->id;
-
- return 0;
-}
-
static int tun_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
switch (xdp->command) {
case XDP_SETUP_PROG:
return tun_xdp_set(dev, xdp->prog, xdp->extack);
- case XDP_QUERY_PROG:
- xdp->prog_id = tun_xdp_query(dev);
- return 0;
default:
return -EINVAL;
}
@@ -2983,7 +2968,7 @@ unlock:
return ret;
}
-static int tun_set_ebpf(struct tun_struct *tun, struct tun_prog **prog_p,
+static int tun_set_ebpf(struct tun_struct *tun, struct tun_prog __rcu **prog_p,
void __user *data)
{
struct bpf_prog *prog;
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index a657943c9f01..8c1d61c2cbac 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -63,10 +63,8 @@ static const u8 mbm_guid[16] = {
0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a,
};
-static void usbnet_cdc_update_filter(struct usbnet *dev)
+void usbnet_cdc_update_filter(struct usbnet *dev)
{
- struct cdc_state *info = (void *) &dev->data;
- struct usb_interface *intf = info->control;
struct net_device *net = dev->net;
u16 cdc_filter = USB_CDC_PACKET_TYPE_DIRECTED
@@ -86,12 +84,13 @@ static void usbnet_cdc_update_filter(struct usbnet *dev)
USB_CDC_SET_ETHERNET_PACKET_FILTER,
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
cdc_filter,
- intf->cur_altsetting->desc.bInterfaceNumber,
+ dev->intf->cur_altsetting->desc.bInterfaceNumber,
NULL,
0,
USB_CTRL_SET_TIMEOUT
);
}
+EXPORT_SYMBOL_GPL(usbnet_cdc_update_filter);
/* probes control interface, claims data interface, collects the bulk
* endpoints, activates data interface (if needed), maybe sets MTU.
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 8929669b5e6d..e04f588538cc 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -792,6 +792,7 @@ static const struct net_device_ops cdc_ncm_netdev_ops = {
.ndo_stop = usbnet_stop,
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_set_rx_mode = usbnet_set_rx_mode,
.ndo_get_stats64 = usbnet_get_stats64,
.ndo_change_mtu = cdc_ncm_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
@@ -1895,6 +1896,7 @@ static const struct driver_info cdc_ncm_info = {
.status = cdc_ncm_status,
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
+ .set_rx_mode = usbnet_cdc_update_filter,
};
/* Same as cdc_ncm_info, but with FLAG_WWAN */
@@ -1908,6 +1910,7 @@ static const struct driver_info wwan_info = {
.status = cdc_ncm_status,
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
+ .set_rx_mode = usbnet_cdc_update_filter,
};
/* Same as wwan_info, but with FLAG_NOARP */
@@ -1921,6 +1924,7 @@ static const struct driver_info wwan_noarp_info = {
.status = cdc_ncm_status,
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
+ .set_rx_mode = usbnet_cdc_update_filter,
};
static const struct usb_device_id cdc_devs[] = {
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index d2fdb5430d27..2bb28db89432 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -831,8 +831,7 @@ static void hso_net_tx_timeout(struct net_device *net, unsigned int txqueue)
dev_warn(&net->dev, "Tx timed out.\n");
/* Tear the waiting frame off the list */
- if (odev->mux_bulk_tx_urb &&
- (odev->mux_bulk_tx_urb->status == -EINPROGRESS))
+ if (odev->mux_bulk_tx_urb)
usb_unlink_urb(odev->mux_bulk_tx_urb);
/* Update statistics */
@@ -2357,7 +2356,7 @@ static int remove_net_device(struct hso_device *hso_dev)
}
/* Frees our network device */
-static void hso_free_net_device(struct hso_device *hso_dev)
+static void hso_free_net_device(struct hso_device *hso_dev, bool bailout)
{
int i;
struct hso_net *hso_net = dev2net(hso_dev);
@@ -2380,7 +2379,7 @@ static void hso_free_net_device(struct hso_device *hso_dev)
kfree(hso_net->mux_bulk_tx_buf);
hso_net->mux_bulk_tx_buf = NULL;
- if (hso_net->net)
+ if (hso_net->net && !bailout)
free_netdev(hso_net->net);
kfree(hso_dev);
@@ -2465,10 +2464,9 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
&interface_to_usbdev(interface)->dev,
RFKILL_TYPE_WWAN,
&hso_rfkill_ops, hso_dev);
- if (!hso_net->rfkill) {
- dev_err(dev, "%s - Out of memory\n", __func__);
+ if (!hso_net->rfkill)
return;
- }
+
if (rfkill_register(hso_net->rfkill) < 0) {
rfkill_destroy(hso_net->rfkill);
hso_net->rfkill = NULL;
@@ -2556,7 +2554,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface,
return hso_dev;
exit:
- hso_free_net_device(hso_dev);
+ hso_free_net_device(hso_dev, true);
return NULL;
}
@@ -3133,7 +3131,7 @@ static void hso_free_interface(struct usb_interface *interface)
rfkill_unregister(rfk);
rfkill_destroy(rfk);
}
- hso_free_net_device(network_table[i]);
+ hso_free_net_device(network_table[i], false);
}
}
}
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index c792d65dd7b4..b09b45382faf 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -358,7 +358,7 @@ static int ipheth_close(struct net_device *net)
return 0;
}
-static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
+static netdev_tx_t ipheth_tx(struct sk_buff *skb, struct net_device *net)
{
struct ipheth_device *dev = netdev_priv(net);
struct usb_device *udev = dev->udev;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 5ec97def3513..e45935a5856a 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1108,12 +1108,13 @@ static void __handle_link_change(struct usbnet *dev)
clear_bit(EVENT_LINK_CHANGE, &dev->flags);
}
-static void usbnet_set_rx_mode(struct net_device *net)
+void usbnet_set_rx_mode(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
usbnet_defer_kevent(dev, EVENT_SET_RX_MODE);
}
+EXPORT_SYMBOL_GPL(usbnet_set_rx_mode);
static void __handle_set_rx_mode(struct usbnet *dev)
{
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index b594f03eeddb..e56cd562a664 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1198,26 +1198,11 @@ err:
return err;
}
-static u32 veth_xdp_query(struct net_device *dev)
-{
- struct veth_priv *priv = netdev_priv(dev);
- const struct bpf_prog *xdp_prog;
-
- xdp_prog = priv->_xdp_prog;
- if (xdp_prog)
- return xdp_prog->aux->id;
-
- return 0;
-}
-
static int veth_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
switch (xdp->command) {
case XDP_SETUP_PROG:
return veth_xdp_set(dev, xdp->prog, xdp->extack);
- case XDP_QUERY_PROG:
- xdp->prog_id = veth_xdp_query(dev);
- return 0;
default:
return -EINVAL;
}
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index ba38765dc490..6fa8fe5ef160 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2490,28 +2490,11 @@ err:
return err;
}
-static u32 virtnet_xdp_query(struct net_device *dev)
-{
- struct virtnet_info *vi = netdev_priv(dev);
- const struct bpf_prog *xdp_prog;
- int i;
-
- for (i = 0; i < vi->max_queue_pairs; i++) {
- xdp_prog = rtnl_dereference(vi->rq[i].xdp_prog);
- if (xdp_prog)
- return xdp_prog->aux->id;
- }
- return 0;
-}
-
static int virtnet_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
switch (xdp->command) {
case XDP_SETUP_PROG:
return virtnet_xdp_set(dev, xdp->prog, xdp->extack);
- case XDP_QUERY_PROG:
- xdp->prog_id = virtnet_xdp_query(dev);
- return 0;
default:
return -EINVAL;
}
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 43928a1c2f2a..60c1aadece89 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -21,6 +21,7 @@
#include <net/rtnetlink.h>
#include <linux/u64_stats_sync.h>
#include <linux/hashtable.h>
+#include <linux/spinlock_types.h>
#include <linux/inetdevice.h>
#include <net/arp.h>
@@ -35,12 +36,76 @@
#include <net/netns/generic.h>
#define DRV_NAME "vrf"
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "1.1"
#define FIB_RULE_PREF 1000 /* default preference for FIB rules */
+#define HT_MAP_BITS 4
+#define HASH_INITVAL ((u32)0xcafef00d)
+
+struct vrf_map {
+ DECLARE_HASHTABLE(ht, HT_MAP_BITS);
+ spinlock_t vmap_lock;
+
+ /* shared_tables:
+ * count how many distinct tables do not comply with the strict mode
+ * requirement.
+ * shared_tables value must be 0 in order to enable the strict mode.
+ *
+ * example of the evolution of shared_tables:
+ * | time
+ * add vrf0 --> table 100 shared_tables = 0 | t0
+ * add vrf1 --> table 101 shared_tables = 0 | t1
+ * add vrf2 --> table 100 shared_tables = 1 | t2
+ * add vrf3 --> table 100 shared_tables = 1 | t3
+ * add vrf4 --> table 101 shared_tables = 2 v t4
+ *
+ * shared_tables is a "step function" (or "staircase function")
+ * and it is increased by one when the second vrf is associated to a
+ * table.
+ *
+ * at t2, vrf0 and vrf2 are bound to table 100: shared_tables = 1.
+ *
+ * at t3, another dev (vrf3) is bound to the same table 100 but the
+ * value of shared_tables is still 1.
+ * This means that no matter how many new vrfs will register on the
+ * table 100, the shared_tables will not increase (considering only
+ * table 100).
+ *
+ * at t4, vrf4 is bound to table 101, and shared_tables = 2.
+ *
+ * Looking at the value of shared_tables we can immediately know if
+ * the strict_mode can or cannot be enforced. Indeed, strict_mode
+ * can be enforced iff shared_tables = 0.
+ *
+ * Conversely, shared_tables is decreased when a vrf is de-associated
+ * from a table with exactly two associated vrfs.
+ */
+ u32 shared_tables;
+
+ bool strict_mode;
+};
+
+struct vrf_map_elem {
+ struct hlist_node hnode;
+ struct list_head vrf_list; /* VRFs registered to this table */
+
+ u32 table_id;
+ int users;
+ int ifindex;
+};
+
static unsigned int vrf_net_id;
+/* per netns vrf data */
+struct netns_vrf {
+ /* protected by rtnl lock */
+ bool add_fib_rules;
+
+ struct vrf_map vmap;
+ struct ctl_table_header *ctl_hdr;
+};
+
struct net_vrf {
struct rtable __rcu *rth;
struct rt6_info __rcu *rt6;
@@ -48,6 +113,9 @@ struct net_vrf {
struct fib6_table *fib6_table;
#endif
u32 tb_id;
+
+ struct list_head me_list; /* entry in vrf_map_elem */
+ int ifindex;
};
struct pcpu_dstats {
@@ -103,6 +171,214 @@ static void vrf_get_stats64(struct net_device *dev,
}
}
+static struct vrf_map *netns_vrf_map(struct net *net)
+{
+ struct netns_vrf *nn_vrf = net_generic(net, vrf_net_id);
+
+ return &nn_vrf->vmap;
+}
+
+static struct vrf_map *netns_vrf_map_by_dev(struct net_device *dev)
+{
+ return netns_vrf_map(dev_net(dev));
+}
+
+static int vrf_map_elem_get_vrf_ifindex(struct vrf_map_elem *me)
+{
+ struct list_head *me_head = &me->vrf_list;
+ struct net_vrf *vrf;
+
+ if (list_empty(me_head))
+ return -ENODEV;
+
+ vrf = list_first_entry(me_head, struct net_vrf, me_list);
+
+ return vrf->ifindex;
+}
+
+static struct vrf_map_elem *vrf_map_elem_alloc(gfp_t flags)
+{
+ struct vrf_map_elem *me;
+
+ me = kmalloc(sizeof(*me), flags);
+ if (!me)
+ return NULL;
+
+ return me;
+}
+
+static void vrf_map_elem_free(struct vrf_map_elem *me)
+{
+ kfree(me);
+}
+
+static void vrf_map_elem_init(struct vrf_map_elem *me, int table_id,
+ int ifindex, int users)
+{
+ me->table_id = table_id;
+ me->ifindex = ifindex;
+ me->users = users;
+ INIT_LIST_HEAD(&me->vrf_list);
+}
+
+static struct vrf_map_elem *vrf_map_lookup_elem(struct vrf_map *vmap,
+ u32 table_id)
+{
+ struct vrf_map_elem *me;
+ u32 key;
+
+ key = jhash_1word(table_id, HASH_INITVAL);
+ hash_for_each_possible(vmap->ht, me, hnode, key) {
+ if (me->table_id == table_id)
+ return me;
+ }
+
+ return NULL;
+}
+
+static void vrf_map_add_elem(struct vrf_map *vmap, struct vrf_map_elem *me)
+{
+ u32 table_id = me->table_id;
+ u32 key;
+
+ key = jhash_1word(table_id, HASH_INITVAL);
+ hash_add(vmap->ht, &me->hnode, key);
+}
+
+static void vrf_map_del_elem(struct vrf_map_elem *me)
+{
+ hash_del(&me->hnode);
+}
+
+static void vrf_map_lock(struct vrf_map *vmap) __acquires(&vmap->vmap_lock)
+{
+ spin_lock(&vmap->vmap_lock);
+}
+
+static void vrf_map_unlock(struct vrf_map *vmap) __releases(&vmap->vmap_lock)
+{
+ spin_unlock(&vmap->vmap_lock);
+}
+
+/* called with rtnl lock held */
+static int
+vrf_map_register_dev(struct net_device *dev, struct netlink_ext_ack *extack)
+{
+ struct vrf_map *vmap = netns_vrf_map_by_dev(dev);
+ struct net_vrf *vrf = netdev_priv(dev);
+ struct vrf_map_elem *new_me, *me;
+ u32 table_id = vrf->tb_id;
+ bool free_new_me = false;
+ int users;
+ int res;
+
+ /* we pre-allocate elements used in the spin-locked section (so that we
+ * keep the spinlock as short as possibile).
+ */
+ new_me = vrf_map_elem_alloc(GFP_KERNEL);
+ if (!new_me)
+ return -ENOMEM;
+
+ vrf_map_elem_init(new_me, table_id, dev->ifindex, 0);
+
+ vrf_map_lock(vmap);
+
+ me = vrf_map_lookup_elem(vmap, table_id);
+ if (!me) {
+ me = new_me;
+ vrf_map_add_elem(vmap, me);
+ goto link_vrf;
+ }
+
+ /* we already have an entry in the vrf_map, so it means there is (at
+ * least) a vrf registered on the specific table.
+ */
+ free_new_me = true;
+ if (vmap->strict_mode) {
+ /* vrfs cannot share the same table */
+ NL_SET_ERR_MSG(extack, "Table is used by another VRF");
+ res = -EBUSY;
+ goto unlock;
+ }
+
+link_vrf:
+ users = ++me->users;
+ if (users == 2)
+ ++vmap->shared_tables;
+
+ list_add(&vrf->me_list, &me->vrf_list);
+
+ res = 0;
+
+unlock:
+ vrf_map_unlock(vmap);
+
+ /* clean-up, if needed */
+ if (free_new_me)
+ vrf_map_elem_free(new_me);
+
+ return res;
+}
+
+/* called with rtnl lock held */
+static void vrf_map_unregister_dev(struct net_device *dev)
+{
+ struct vrf_map *vmap = netns_vrf_map_by_dev(dev);
+ struct net_vrf *vrf = netdev_priv(dev);
+ u32 table_id = vrf->tb_id;
+ struct vrf_map_elem *me;
+ int users;
+
+ vrf_map_lock(vmap);
+
+ me = vrf_map_lookup_elem(vmap, table_id);
+ if (!me)
+ goto unlock;
+
+ list_del(&vrf->me_list);
+
+ users = --me->users;
+ if (users == 1) {
+ --vmap->shared_tables;
+ } else if (users == 0) {
+ vrf_map_del_elem(me);
+
+ /* no one will refer to this element anymore */
+ vrf_map_elem_free(me);
+ }
+
+unlock:
+ vrf_map_unlock(vmap);
+}
+
+/* return the vrf device index associated with the table_id */
+static int vrf_ifindex_lookup_by_table_id(struct net *net, u32 table_id)
+{
+ struct vrf_map *vmap = netns_vrf_map(net);
+ struct vrf_map_elem *me;
+ int ifindex;
+
+ vrf_map_lock(vmap);
+
+ if (!vmap->strict_mode) {
+ ifindex = -EPERM;
+ goto unlock;
+ }
+
+ me = vrf_map_lookup_elem(vmap, table_id);
+ if (!me) {
+ ifindex = -ENODEV;
+ goto unlock;
+ }
+
+ ifindex = vrf_map_elem_get_vrf_ifindex(me);
+
+unlock:
+ vrf_map_unlock(vmap);
+
+ return ifindex;
+}
+
/* by default VRF devices do not have a qdisc and are expected
* to be created with only a single queue.
*/
@@ -1319,6 +1595,8 @@ static void vrf_dellink(struct net_device *dev, struct list_head *head)
netdev_for_each_lower_dev(dev, port_dev, iter)
vrf_del_slave(dev, port_dev);
+ vrf_map_unregister_dev(dev);
+
unregister_netdevice_queue(dev, head);
}
@@ -1327,6 +1605,7 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
struct netlink_ext_ack *extack)
{
struct net_vrf *vrf = netdev_priv(dev);
+ struct netns_vrf *nn_vrf;
bool *add_fib_rules;
struct net *net;
int err;
@@ -1349,11 +1628,26 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
if (err)
goto out;
+ /* mapping between table_id and vrf;
+ * note: such binding could not be done in the dev init function
+ * because dev->ifindex id is not available yet.
+ */
+ vrf->ifindex = dev->ifindex;
+
+ err = vrf_map_register_dev(dev, extack);
+ if (err) {
+ unregister_netdevice(dev);
+ goto out;
+ }
+
net = dev_net(dev);
- add_fib_rules = net_generic(net, vrf_net_id);
+ nn_vrf = net_generic(net, vrf_net_id);
+
+ add_fib_rules = &nn_vrf->add_fib_rules;
if (*add_fib_rules) {
err = vrf_add_fib_rules(dev);
if (err) {
+ vrf_map_unregister_dev(dev);
unregister_netdevice(dev);
goto out;
}
@@ -1440,20 +1734,164 @@ static struct notifier_block vrf_notifier_block __read_mostly = {
.notifier_call = vrf_device_event,
};
+static int vrf_map_init(struct vrf_map *vmap)
+{
+ spin_lock_init(&vmap->vmap_lock);
+ hash_init(vmap->ht);
+
+ vmap->strict_mode = false;
+
+ return 0;
+}
+
+#ifdef CONFIG_SYSCTL
+static bool vrf_strict_mode(struct vrf_map *vmap)
+{
+ bool strict_mode;
+
+ vrf_map_lock(vmap);
+ strict_mode = vmap->strict_mode;
+ vrf_map_unlock(vmap);
+
+ return strict_mode;
+}
+
+static int vrf_strict_mode_change(struct vrf_map *vmap, bool new_mode)
+{
+ bool *cur_mode;
+ int res = 0;
+
+ vrf_map_lock(vmap);
+
+ cur_mode = &vmap->strict_mode;
+ if (*cur_mode == new_mode)
+ goto unlock;
+
+ if (*cur_mode) {
+ /* disable strict mode */
+ *cur_mode = false;
+ } else {
+ if (vmap->shared_tables) {
+ /* we cannot allow strict_mode because there are some
+ * vrfs that share one or more tables.
+ */
+ res = -EBUSY;
+ goto unlock;
+ }
+
+ /* no tables are shared among vrfs, so we can go back
+ * to 1:1 association between a vrf with its table.
+ */
+ *cur_mode = true;
+ }
+
+unlock:
+ vrf_map_unlock(vmap);
+
+ return res;
+}
+
+static int vrf_shared_table_handler(struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct net *net = (struct net *)table->extra1;
+ struct vrf_map *vmap = netns_vrf_map(net);
+ int proc_strict_mode = 0;
+ struct ctl_table tmp = {
+ .procname = table->procname,
+ .data = &proc_strict_mode,
+ .maxlen = sizeof(int),
+ .mode = table->mode,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE,
+ };
+ int ret;
+
+ if (!write)
+ proc_strict_mode = vrf_strict_mode(vmap);
+
+ ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+
+ if (write && ret == 0)
+ ret = vrf_strict_mode_change(vmap, (bool)proc_strict_mode);
+
+ return ret;
+}
+
+static const struct ctl_table vrf_table[] = {
+ {
+ .procname = "strict_mode",
+ .data = NULL,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = vrf_shared_table_handler,
+ /* set by the vrf_netns_init */
+ .extra1 = NULL,
+ },
+ { },
+};
+
+static int vrf_netns_init_sysctl(struct net *net, struct netns_vrf *nn_vrf)
+{
+ struct ctl_table *table;
+
+ table = kmemdup(vrf_table, sizeof(vrf_table), GFP_KERNEL);
+ if (!table)
+ return -ENOMEM;
+
+ /* init the extra1 parameter with the reference to current netns */
+ table[0].extra1 = net;
+
+ nn_vrf->ctl_hdr = register_net_sysctl(net, "net/vrf", table);
+ if (!nn_vrf->ctl_hdr) {
+ kfree(table);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void vrf_netns_exit_sysctl(struct net *net)
+{
+ struct netns_vrf *nn_vrf = net_generic(net, vrf_net_id);
+ struct ctl_table *table;
+
+ table = nn_vrf->ctl_hdr->ctl_table_arg;
+ unregister_net_sysctl_table(nn_vrf->ctl_hdr);
+ kfree(table);
+}
+#else
+static int vrf_netns_init_sysctl(struct net *net, struct netns_vrf *nn_vrf)
+{
+ return 0;
+}
+
+static void vrf_netns_exit_sysctl(struct net *net)
+{
+}
+#endif
+
/* Initialize per network namespace state */
static int __net_init vrf_netns_init(struct net *net)
{
- bool *add_fib_rules = net_generic(net, vrf_net_id);
+ struct netns_vrf *nn_vrf = net_generic(net, vrf_net_id);
- *add_fib_rules = true;
+ nn_vrf->add_fib_rules = true;
+ vrf_map_init(&nn_vrf->vmap);
- return 0;
+ return vrf_netns_init_sysctl(net, nn_vrf);
+}
+
+static void __net_exit vrf_netns_exit(struct net *net)
+{
+ vrf_netns_exit_sysctl(net);
}
static struct pernet_operations vrf_net_ops __net_initdata = {
.init = vrf_netns_init,
+ .exit = vrf_netns_exit,
.id = &vrf_net_id,
- .size = sizeof(bool),
+ .size = sizeof(struct netns_vrf),
};
static int __init vrf_init_module(void)
@@ -1466,14 +1904,24 @@ static int __init vrf_init_module(void)
if (rc < 0)
goto error;
+ rc = l3mdev_table_lookup_register(L3MDEV_TYPE_VRF,
+ vrf_ifindex_lookup_by_table_id);
+ if (rc < 0)
+ goto unreg_pernet;
+
rc = rtnl_link_register(&vrf_link_ops);
- if (rc < 0) {
- unregister_pernet_subsys(&vrf_net_ops);
- goto error;
- }
+ if (rc < 0)
+ goto table_lookup_unreg;
return 0;
+table_lookup_unreg:
+ l3mdev_table_lookup_unregister(L3MDEV_TYPE_VRF,
+ vrf_ifindex_lookup_by_table_id);
+
+unreg_pernet:
+ unregister_pernet_subsys(&vrf_net_ops);
+
error:
unregister_netdevice_notifier(&vrf_notifier_block);
return rc;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index a7c3939264b0..b9fefe27e3e8 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2500,7 +2500,8 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
/* Bypass encapsulation if the destination is local */
static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
- struct vxlan_dev *dst_vxlan, __be32 vni)
+ struct vxlan_dev *dst_vxlan, __be32 vni,
+ bool snoop)
{
struct pcpu_sw_netstats *tx_stats, *rx_stats;
union vxlan_addr loopback;
@@ -2532,7 +2533,7 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
goto drop;
}
- if (dst_vxlan->cfg.flags & VXLAN_F_LEARN)
+ if ((dst_vxlan->cfg.flags & VXLAN_F_LEARN) && snoop)
vxlan_snoop(dev, &loopback, eth_hdr(skb)->h_source, 0, vni);
u64_stats_update_begin(&tx_stats->syncp);
@@ -2581,7 +2582,7 @@ static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev,
return -ENOENT;
}
- vxlan_encap_bypass(skb, vxlan, dst_vxlan, vni);
+ vxlan_encap_bypass(skb, vxlan, dst_vxlan, vni, true);
return 1;
}
@@ -2617,7 +2618,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
if (vxlan_addr_any(dst)) {
if (did_rsc) {
/* short-circuited back to local bridge */
- vxlan_encap_bypass(skb, vxlan, vxlan, default_vni);
+ vxlan_encap_bypass(skb, vxlan, vxlan,
+ default_vni, true);
return;
}
goto drop;
@@ -2720,9 +2722,25 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
}
ndst = &rt->dst;
- skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM);
+ err = skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM,
+ netif_is_any_bridge_port(dev));
+ if (err < 0) {
+ goto tx_error;
+ } else if (err) {
+ if (info) {
+ struct in_addr src, dst;
+
+ src = remote_ip.sin.sin_addr;
+ dst = local_ip.sin.sin_addr;
+ info->key.u.ipv4.src = src.s_addr;
+ info->key.u.ipv4.dst = dst.s_addr;
+ }
+ vxlan_encap_bypass(skb, vxlan, vxlan, vni, false);
+ dst_release(ndst);
+ goto out_unlock;
+ }
- tos = ip_tunnel_ecn_encap(RT_TOS(tos), old_iph, skb);
+ tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
vni, md, flags, udp_sum);
@@ -2760,9 +2778,26 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
goto out_unlock;
}
- skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM);
+ err = skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM,
+ netif_is_any_bridge_port(dev));
+ if (err < 0) {
+ goto tx_error;
+ } else if (err) {
+ if (info) {
+ struct in6_addr src, dst;
+
+ src = remote_ip.sin6.sin6_addr;
+ dst = local_ip.sin6.sin6_addr;
+ info->key.u.ipv6.src = src;
+ info->key.u.ipv6.dst = dst;
+ }
+
+ vxlan_encap_bypass(skb, vxlan, vxlan, vni, false);
+ dst_release(ndst);
+ goto out_unlock;
+ }
- tos = ip_tunnel_ecn_encap(RT_TOS(tos), old_iph, skb);
+ tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
ttl = ttl ? : ip6_dst_hoplimit(ndst);
skb_scrub_packet(skb, xnet);
err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
@@ -4485,10 +4520,12 @@ static int vxlan_netdevice_event(struct notifier_block *unused,
struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
if (event == NETDEV_UNREGISTER) {
- vxlan_offload_rx_ports(dev, false);
+ if (!dev->udp_tunnel_nic_info)
+ vxlan_offload_rx_ports(dev, false);
vxlan_handle_lowerdev_unregister(vn, dev);
} else if (event == NETDEV_REGISTER) {
- vxlan_offload_rx_ports(dev, true);
+ if (!dev->udp_tunnel_nic_info)
+ vxlan_offload_rx_ports(dev, true);
} else if (event == NETDEV_UDP_TUNNEL_PUSH_INFO ||
event == NETDEV_UDP_TUNNEL_DROP_INFO) {
vxlan_offload_rx_ports(dev, event == NETDEV_UDP_TUNNEL_PUSH_INFO);
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index cb57f9124ab1..c354a5143e99 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 2000-2003 Krzysztof Halasa <khc@pm.waw.pl>
*
- * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/>
+ * For information see <https://www.kernel.org/pub/linux/utils/net/hdlc/>
*
* Sources of information:
* Hitachi HD64570 SCA User's Manual
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 5d6532ad6b78..f8aed0696d77 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -12,7 +12,7 @@
* HARDWARE INFO
*
* Both cards are developed at the Institute of Computer Science,
- * Masaryk University (http://www.ics.muni.cz/). The hardware is
+ * Masaryk University (https://www.ics.muni.cz/). The hardware is
* developed by Jiri Novotny <novotny@ics.muni.cz>. More information
* and the photo of both cards is available at
* http://www.pavoucek.cz/cosa.html. The card documentation, firmwares
@@ -35,7 +35,7 @@
*
* SOFTWARE INFO
*
- * The homepage of the Linux driver is at http://www.fi.muni.cz/~kas/cosa/.
+ * The homepage of the Linux driver is at https://www.fi.muni.cz/~kas/cosa/.
* The CVS tree of Linux driver can be viewed there, as well as the
* firmware binaries and user-space utilities for downloading the firmware
* into the card and setting up the card.
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index f5198a391417..b50cf11d197d 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -124,7 +124,7 @@ module_param_array(fst_excluded_list, int, NULL, 0);
/* The Am186CH/CC processors support a SmartDMA mode using circular pools
* of buffer descriptors. The structure is almost identical to that used
* in the LANCE Ethernet controllers. Details available as PDF from the
- * AMD web site: http://www.amd.com/products/epd/processors/\
+ * AMD web site: https://www.amd.com/products/epd/processors/\
* 2.16bitcont/3.am186cxfa/a21914/21914.pdf
*/
struct txdesc { /* Transmit descriptor */
@@ -2553,16 +2553,16 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
* Allocate a dma buffer for transmit and receives
*/
card->rx_dma_handle_host =
- pci_alloc_consistent(card->device, FST_MAX_MTU,
- &card->rx_dma_handle_card);
+ dma_alloc_coherent(&card->device->dev, FST_MAX_MTU,
+ &card->rx_dma_handle_card, GFP_KERNEL);
if (card->rx_dma_handle_host == NULL) {
pr_err("Could not allocate rx dma buffer\n");
err = -ENOMEM;
goto rx_dma_fail;
}
card->tx_dma_handle_host =
- pci_alloc_consistent(card->device, FST_MAX_MTU,
- &card->tx_dma_handle_card);
+ dma_alloc_coherent(&card->device->dev, FST_MAX_MTU,
+ &card->tx_dma_handle_card, GFP_KERNEL);
if (card->tx_dma_handle_host == NULL) {
pr_err("Could not allocate tx dma buffer\n");
err = -ENOMEM;
@@ -2572,9 +2572,8 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0; /* Success */
tx_dma_fail:
- pci_free_consistent(card->device, FST_MAX_MTU,
- card->rx_dma_handle_host,
- card->rx_dma_handle_card);
+ dma_free_coherent(&card->device->dev, FST_MAX_MTU,
+ card->rx_dma_handle_host, card->rx_dma_handle_card);
rx_dma_fail:
fst_disable_intr(card);
for (i = 0 ; i < card->nports ; i++)
@@ -2625,23 +2624,21 @@ fst_remove_one(struct pci_dev *pdev)
/*
* Free dma buffers
*/
- pci_free_consistent(card->device, FST_MAX_MTU,
- card->rx_dma_handle_host,
- card->rx_dma_handle_card);
- pci_free_consistent(card->device, FST_MAX_MTU,
- card->tx_dma_handle_host,
- card->tx_dma_handle_card);
+ dma_free_coherent(&card->device->dev, FST_MAX_MTU,
+ card->rx_dma_handle_host,
+ card->rx_dma_handle_card);
+ dma_free_coherent(&card->device->dev, FST_MAX_MTU,
+ card->tx_dma_handle_host,
+ card->tx_dma_handle_card);
}
fst_card_array[card->card_no] = NULL;
}
static struct pci_driver fst_driver = {
- .name = FST_NAME,
- .id_table = fst_pci_dev_id,
- .probe = fst_add_one,
- .remove = fst_remove_one,
- .suspend = NULL,
- .resume = NULL,
+ .name = FST_NAME,
+ .id_table = fst_pci_dev_id,
+ .probe = fst_add_one,
+ .remove = fst_remove_one,
};
static int __init
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index a20f467ca48a..842def21e089 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -2063,7 +2063,7 @@ static void lmc_driver_timeout(struct net_device *dev, unsigned int txqueue)
/*
* Chip seems to have locked up
* Reset it
- * This whips out all our decriptor
+ * This whips out all our descriptor
* table and starts from scartch
*/
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index f9e7fc7e9978..5bf4463873b1 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl>
*
- * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/>
+ * For information see <https://www.kernel.org/pub/linux/utils/net/hdlc/>
*
* Note: integrated CSU/DSU/DDS are not supported by this driver
*
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c
index 190735604b2e..001fd378d417 100644
--- a/drivers/net/wan/pc300too.c
+++ b/drivers/net/wan/pc300too.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 2000-2008 Krzysztof Halasa <khc@pm.waw.pl>
*
- * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/>.
+ * For information see <https://www.kernel.org/pub/linux/utils/net/hdlc/>.
*
* Sources of information:
* Hitachi HD64572 SCA-II User's Manual
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index b5f8aaca5f06..d0062224b216 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 2002-2008 Krzysztof Halasa <khc@pm.waw.pl>
*
- * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/>
+ * For information see <https://www.kernel.org/pub/linux/utils/net/hdlc/>
*
* Sources of information:
* Hitachi HD64572 SCA-II User's Manual
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index 499f7cd19a4a..a83133388de9 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -99,7 +99,7 @@ static inline port_status_t *get_status(struct port *port)
static inline dma_addr_t pci_map_single_debug(struct pci_dev *pdev, void *ptr,
size_t size, int direction)
{
- dma_addr_t addr = pci_map_single(pdev, ptr, size, direction);
+ dma_addr_t addr = dma_map_single(&pdev->dev, ptr, size, direction);
if (addr + size > 0x100000000LL)
pr_crit("%s: pci_map_single() returned memory at 0x%llx!\n",
pci_name(pdev), (unsigned long long)addr);
@@ -180,8 +180,8 @@ static inline void wanxl_tx_intr(struct port *port)
dev->stats.tx_bytes += skb->len;
}
desc->stat = PACKET_EMPTY; /* Free descriptor */
- pci_unmap_single(port->card->pdev, desc->address, skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&port->card->pdev->dev, desc->address,
+ skb->len, DMA_TO_DEVICE);
dev_consume_skb_irq(skb);
port->tx_in = (port->tx_in + 1) % TX_BUFFERS;
}
@@ -207,9 +207,9 @@ static inline void wanxl_rx_intr(struct card *card)
if (!skb)
dev->stats.rx_dropped++;
else {
- pci_unmap_single(card->pdev, desc->address,
- BUFFER_LENGTH,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&card->pdev->dev,
+ desc->address, BUFFER_LENGTH,
+ DMA_FROM_DEVICE);
skb_put(skb, desc->length);
#ifdef DEBUG_PKT
@@ -227,9 +227,10 @@ static inline void wanxl_rx_intr(struct card *card)
if (!skb) {
skb = dev_alloc_skb(BUFFER_LENGTH);
desc->address = skb ?
- pci_map_single(card->pdev, skb->data,
+ dma_map_single(&card->pdev->dev,
+ skb->data,
BUFFER_LENGTH,
- PCI_DMA_FROMDEVICE) : 0;
+ DMA_FROM_DEVICE) : 0;
card->rx_skbs[card->rx_in] = skb;
}
}
@@ -291,8 +292,8 @@ static netdev_tx_t wanxl_xmit(struct sk_buff *skb, struct net_device *dev)
#endif
port->tx_skbs[port->tx_out] = skb;
- desc->address = pci_map_single(port->card->pdev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
+ desc->address = dma_map_single(&port->card->pdev->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
desc->length = skb->len;
desc->stat = PACKET_FULL;
writel(1 << (DOORBELL_TO_CARD_TX_0 + port->node),
@@ -451,9 +452,9 @@ static int wanxl_close(struct net_device *dev)
if (desc->stat != PACKET_EMPTY) {
desc->stat = PACKET_EMPTY;
- pci_unmap_single(port->card->pdev, desc->address,
- port->tx_skbs[i]->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&port->card->pdev->dev,
+ desc->address, port->tx_skbs[i]->len,
+ DMA_TO_DEVICE);
dev_kfree_skb(port->tx_skbs[i]);
}
}
@@ -524,9 +525,9 @@ static void wanxl_pci_remove_one(struct pci_dev *pdev)
for (i = 0; i < RX_QUEUE_LENGTH; i++)
if (card->rx_skbs[i]) {
- pci_unmap_single(card->pdev,
+ dma_unmap_single(&card->pdev->dev,
card->status->rx_descs[i].address,
- BUFFER_LENGTH, PCI_DMA_FROMDEVICE);
+ BUFFER_LENGTH, DMA_FROM_DEVICE);
dev_kfree_skb(card->rx_skbs[i]);
}
@@ -534,8 +535,8 @@ static void wanxl_pci_remove_one(struct pci_dev *pdev)
iounmap(card->plx);
if (card->status)
- pci_free_consistent(pdev, sizeof(struct card_status),
- card->status, card->status_address);
+ dma_free_coherent(&pdev->dev, sizeof(struct card_status),
+ card->status, card->status_address);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -579,8 +580,8 @@ static int wanxl_pci_init_one(struct pci_dev *pdev,
We set both dma_mask and consistent_dma_mask to 28 bits
and pray pci_alloc_consistent() will use this info. It should
work on most platforms */
- if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(28)) ||
- pci_set_dma_mask(pdev, DMA_BIT_MASK(28))) {
+ if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(28)) ||
+ dma_set_mask(&pdev->dev, DMA_BIT_MASK(28))) {
pr_err("No usable DMA configuration\n");
pci_disable_device(pdev);
return -EIO;
@@ -608,9 +609,9 @@ static int wanxl_pci_init_one(struct pci_dev *pdev,
pci_set_drvdata(pdev, card);
card->pdev = pdev;
- card->status = pci_alloc_consistent(pdev,
- sizeof(struct card_status),
- &card->status_address);
+ card->status = dma_alloc_coherent(&pdev->dev,
+ sizeof(struct card_status),
+ &card->status_address, GFP_KERNEL);
if (card->status == NULL) {
wanxl_pci_remove_one(pdev);
return -ENOBUFS;
@@ -625,8 +626,8 @@ static int wanxl_pci_init_one(struct pci_dev *pdev,
/* FIXME when PCI/DMA subsystems are fixed.
We set both dma_mask and consistent_dma_mask back to 32 bits
to indicate the card can do 32-bit DMA addressing */
- if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) ||
- pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)) ||
+ dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
pr_err("No usable DMA configuration\n");
wanxl_pci_remove_one(pdev);
return -EIO;
@@ -699,9 +700,8 @@ static int wanxl_pci_init_one(struct pci_dev *pdev,
card->rx_skbs[i] = skb;
if (skb)
card->status->rx_descs[i].address =
- pci_map_single(card->pdev, skb->data,
- BUFFER_LENGTH,
- PCI_DMA_FROMDEVICE);
+ dma_map_single(&card->pdev->dev, skb->data,
+ BUFFER_LENGTH, DMA_FROM_DEVICE);
}
mem = ioremap(mem_phy, PDM_OFFSET + sizeof(firmware));
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 8ab62bb6b853..170a64e67709 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -14,7 +14,7 @@ menuconfig WLAN
device drivers. For a complete list of drivers and documentation
on them refer to the wireless wiki:
- http://wireless.kernel.org/en/users/Drivers
+ https://wireless.wiki.kernel.org/en/users/Drivers
if WLAN
@@ -40,6 +40,7 @@ source "drivers/net/wireless/intel/Kconfig"
source "drivers/net/wireless/intersil/Kconfig"
source "drivers/net/wireless/marvell/Kconfig"
source "drivers/net/wireless/mediatek/Kconfig"
+source "drivers/net/wireless/microchip/Kconfig"
source "drivers/net/wireless/ralink/Kconfig"
source "drivers/net/wireless/realtek/Kconfig"
source "drivers/net/wireless/rsi/Kconfig"
@@ -57,7 +58,8 @@ config PCMCIA_RAYCS
help
Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
(PC-card) wireless Ethernet networking card to your computer.
- Please read the file <file:Documentation/networking/ray_cs.rst> for
+ Please read the file
+ <file:Documentation/networking/device_drivers/wifi/ray_cs.rst> for
details.
To compile this driver as a module, choose M here: the module will be
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 6cfe74515c95..80b324499786 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_WLAN_VENDOR_INTEL) += intel/
obj-$(CONFIG_WLAN_VENDOR_INTERSIL) += intersil/
obj-$(CONFIG_WLAN_VENDOR_MARVELL) += marvell/
obj-$(CONFIG_WLAN_VENDOR_MEDIATEK) += mediatek/
+obj-$(CONFIG_WLAN_VENDOR_MICROCHIP) += microchip/
obj-$(CONFIG_WLAN_VENDOR_RALINK) += ralink/
obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/
obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/
diff --git a/drivers/net/wireless/admtek/adm8211.c b/drivers/net/wireless/admtek/adm8211.c
index ba326f6c1214..22f9f2f8af10 100644
--- a/drivers/net/wireless/admtek/adm8211.c
+++ b/drivers/net/wireless/admtek/adm8211.c
@@ -1976,35 +1976,20 @@ static void adm8211_remove(struct pci_dev *pdev)
}
-#ifdef CONFIG_PM
-static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- pci_save_state(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return 0;
-}
-
-static int adm8211_resume(struct pci_dev *pdev)
-{
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- return 0;
-}
-#endif /* CONFIG_PM */
-
+#define adm8211_suspend NULL
+#define adm8211_resume NULL
MODULE_DEVICE_TABLE(pci, adm8211_pci_id_table);
+static SIMPLE_DEV_PM_OPS(adm8211_pm_ops, adm8211_suspend, adm8211_resume);
+
/* TODO: implement enable_wake */
static struct pci_driver adm8211_driver = {
.name = "adm8211",
.id_table = adm8211_pci_id_table,
.probe = adm8211_probe,
.remove = adm8211_remove,
-#ifdef CONFIG_PM
- .suspend = adm8211_suspend,
- .resume = adm8211_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &adm8211_pm_ops,
};
module_pci_driver(adm8211_driver);
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 6e9d46b96555..d88edbf1bea3 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -15,11 +15,11 @@ config WLAN_VENDOR_ATH
For more information and documentation on this module you can visit:
- http://wireless.kernel.org/en/users/Drivers/ath
+ https://wireless.wiki.kernel.org/en/users/Drivers/ath
For information on all Atheros wireless drivers visit:
- http://wireless.kernel.org/en/users/Drivers/Atheros
+ https://wireless.wiki.kernel.org/en/users/Drivers/Atheros
if WLAN_VENDOR_ATH
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 4fd10ac3a941..bbe869575855 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -1591,7 +1591,9 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
err_unmap_msdu:
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
err_free_msdu_id:
+ spin_lock_bh(&htt->tx_lock);
ath10k_htt_tx_free_msdu_id(htt, msdu_id);
+ spin_unlock_bh(&htt->tx_lock);
err:
return res;
}
@@ -1798,7 +1800,9 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
err_unmap_msdu:
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
err_free_msdu_id:
+ spin_lock_bh(&htt->tx_lock);
ath10k_htt_tx_free_msdu_id(htt, msdu_id);
+ spin_unlock_bh(&htt->tx_lock);
err:
return res;
}
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 919d15584d4a..3c0c33a9f30c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -568,11 +568,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
case NL80211_CHAN_WIDTH_40:
phymode = MODE_11NG_HT40;
break;
- case NL80211_CHAN_WIDTH_5:
- case NL80211_CHAN_WIDTH_10:
- case NL80211_CHAN_WIDTH_80:
- case NL80211_CHAN_WIDTH_80P80:
- case NL80211_CHAN_WIDTH_160:
+ default:
phymode = MODE_UNKNOWN;
break;
}
@@ -597,8 +593,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
case NL80211_CHAN_WIDTH_80P80:
phymode = MODE_11AC_VHT80_80;
break;
- case NL80211_CHAN_WIDTH_5:
- case NL80211_CHAN_WIDTH_10:
+ default:
phymode = MODE_UNKNOWN;
break;
}
diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c
index b7daf344d012..05a620ff6fe2 100644
--- a/drivers/net/wireless/ath/ath10k/usb.c
+++ b/drivers/net/wireless/ath/ath10k/usb.c
@@ -824,7 +824,7 @@ static int ath10k_usb_setup_pipe_resources(struct ath10k *ar,
ath10k_dbg(ar, ATH10K_DBG_USB, "usb setting up pipes using interface\n");
- /* walk decriptors and setup pipes */
+ /* walk descriptors and setup pipes */
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
diff --git a/drivers/net/wireless/ath/ath11k/Kconfig b/drivers/net/wireless/ath/ath11k/Kconfig
index 7acb42e2e6e2..88a97356f0a1 100644
--- a/drivers/net/wireless/ath/ath11k/Kconfig
+++ b/drivers/net/wireless/ath/ath11k/Kconfig
@@ -34,3 +34,12 @@ config ATH11K_TRACING
depends on ATH11K && EVENT_TRACING
help
Select this to use ath11k tracing infrastructure.
+
+config ATH11K_SPECTRAL
+ bool "QCA ath11k spectral scan support"
+ depends on ATH11K_DEBUGFS
+ depends on RELAY
+ help
+ Enable ath11k spectral scan support
+
+ Say Y to enable access to the FFT/spectral data via debugfs.
diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile
index fe7736e53583..104186373c9e 100644
--- a/drivers/net/wireless/ath/ath11k/Makefile
+++ b/drivers/net/wireless/ath/ath11k/Makefile
@@ -15,12 +15,14 @@ ath11k-y += core.o \
dp_rx.o \
debug.o \
ce.o \
- peer.o
+ peer.o \
+ dbring.o
ath11k-$(CONFIG_ATH11K_DEBUGFS) += debug_htt_stats.o debugfs_sta.o
ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o
ath11k-$(CONFIG_ATH11K_TRACING) += trace.o
ath11k-$(CONFIG_THERMAL) += thermal.o
+ath11k-$(CONFIG_ATH11K_SPECTRAL) += spectral.o
# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 02501cc154fe..905cd8beaf28 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -400,8 +400,16 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
goto err_dp_pdev_free;
}
+ ret = ath11k_spectral_init(ab);
+ if (ret) {
+ ath11k_err(ab, "failed to init spectral %d\n", ret);
+ goto err_thermal_unregister;
+ }
+
return 0;
+err_thermal_unregister:
+ ath11k_thermal_unregister(ab);
err_dp_pdev_free:
ath11k_dp_pdev_free(ab);
err_mac_unregister:
@@ -414,6 +422,7 @@ err_pdev_debug:
static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
{
+ ath11k_spectral_deinit(ab);
ath11k_thermal_unregister(ab);
ath11k_mac_unregister(ab);
ath11k_hif_irq_disable(ab);
@@ -582,6 +591,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
ath11k_thermal_unregister(ab);
ath11k_hif_irq_disable(ab);
ath11k_dp_pdev_free(ab);
+ ath11k_spectral_deinit(ab);
ath11k_hif_stop(ab);
ath11k_wmi_detach(ab);
ath11k_dp_pdev_reo_cleanup(ab);
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index e04f0e711779..e5c4e19020ee 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -21,6 +21,8 @@
#include "hal_rx.h"
#include "reg.h"
#include "thermal.h"
+#include "dbring.h"
+#include "spectral.h"
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
@@ -215,12 +217,15 @@ struct ath11k_vif {
bool is_started;
bool is_up;
+ bool spectral_enabled;
u32 aid;
u8 bssid[ETH_ALEN];
struct cfg80211_bitrate_mask bitrate_mask;
int num_legacy_stations;
int rtscts_prot_mode;
int txpower;
+ bool rsnie_present;
+ bool wpaie_present;
};
struct ath11k_vif_iter {
@@ -353,7 +358,10 @@ struct ath11k_sta {
#endif
};
-#define ATH11K_NUM_CHANS 41
+#define ATH11K_MIN_5G_FREQ 4150
+#define ATH11K_MIN_6G_FREQ 5945
+#define ATH11K_MAX_6G_FREQ 7115
+#define ATH11K_NUM_CHANS 100
#define ATH11K_MAX_5G_CHAN 173
enum ath11k_state {
@@ -431,6 +439,7 @@ struct ath11k {
u32 vht_cap_info;
struct ath11k_he ar_he;
enum ath11k_state state;
+ bool supports_6ghz;
struct {
struct completion started;
struct completion completed;
@@ -537,6 +546,9 @@ struct ath11k {
#ifdef CONFIG_ATH11K_DEBUGFS
struct ath11k_debug debug;
#endif
+#ifdef CONFIG_ATH11K_SPECTRAL
+ struct ath11k_spectral spectral;
+#endif
bool dfs_block_radar_events;
struct ath11k_thermal thermal;
};
@@ -548,6 +560,7 @@ struct ath11k_band_cap {
u32 he_mcs;
u32 he_cap_phy_info[PSOC_HOST_MAX_PHY_SIZE];
struct ath11k_ppe_threshold he_ppet;
+ u16 he_6ghz_capa;
};
struct ath11k_pdev_cap {
@@ -579,12 +592,42 @@ struct ath11k_board_data {
/* IPQ8074 HW channel counters frequency value in hertz */
#define IPQ8074_CC_FREQ_HERTZ 320000
-struct ath11k_soc_dp_rx_stats {
+struct ath11k_bp_stats {
+ /* Head Pointer reported by the last HTT Backpressure event for the ring */
+ u16 hp;
+
+ /* Tail Pointer reported by the last HTT Backpressure event for the ring */
+ u16 tp;
+
+ /* Number of Backpressure events received for the ring */
+ u32 count;
+
+ /* Last recorded event timestamp */
+ unsigned long jiffies;
+};
+
+struct ath11k_dp_ring_bp_stats {
+ struct ath11k_bp_stats umac_ring_bp_stats[HTT_SW_UMAC_RING_IDX_MAX];
+ struct ath11k_bp_stats lmac_ring_bp_stats[HTT_SW_LMAC_RING_IDX_MAX][MAX_RADIOS];
+};
+
+struct ath11k_soc_dp_tx_err_stats {
+ /* TCL Ring Descriptor unavailable */
+ u32 desc_na[DP_TCL_NUM_RING_MAX];
+ /* Other failures during dp_tx due to mem allocation failure
+ * idr unavailable etc.
+ */
+ atomic_t misc_fail;
+};
+
+struct ath11k_soc_dp_stats {
u32 err_ring_pkts;
u32 invalid_rbm;
u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];
u32 hal_reo_error[DP_REO_DST_RING_MAX];
+ struct ath11k_soc_dp_tx_err_stats tx_err;
+ struct ath11k_dp_ring_bp_stats bp_stats;
};
/* Master structure to hold the hw data which may be used in core module */
@@ -653,7 +696,7 @@ struct ath11k_base {
struct dentry *debugfs_soc;
struct dentry *debugfs_ath11k;
#endif
- struct ath11k_soc_dp_rx_stats soc_stats;
+ struct ath11k_soc_dp_stats soc_stats;
unsigned long dev_flags;
struct completion driver_recovery;
@@ -668,6 +711,9 @@ struct ath11k_base {
/* Round robbin based TCL ring selector */
atomic_t tcl_ring_selector;
+ struct ath11k_dbring_cap *db_caps;
+ u32 num_db_cap;
+
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c
new file mode 100644
index 000000000000..cf20db370123
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/dbring.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ */
+
+#include "core.h"
+#include "debug.h"
+
+static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
+ struct ath11k_dbring *ring,
+ struct ath11k_dbring_element *buff,
+ gfp_t gfp)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct hal_srng *srng;
+ dma_addr_t paddr;
+ void *ptr_aligned, *ptr_unaligned, *desc;
+ int ret;
+ int buf_id;
+ u32 cookie;
+
+ srng = &ab->hal.srng_list[ring->refill_srng.ring_id];
+
+ lockdep_assert_held(&srng->lock);
+
+ ath11k_hal_srng_access_begin(ab, srng);
+
+ ptr_unaligned = buff->payload;
+ ptr_aligned = PTR_ALIGN(ptr_unaligned, ring->buf_align);
+ paddr = dma_map_single(ab->dev, ptr_aligned, ring->buf_sz,
+ DMA_FROM_DEVICE);
+
+ ret = dma_mapping_error(ab->dev, paddr);
+ if (ret)
+ goto err;
+
+ spin_lock_bh(&ring->idr_lock);
+ buf_id = idr_alloc(&ring->bufs_idr, buff, 0, ring->bufs_max, gfp);
+ spin_unlock_bh(&ring->idr_lock);
+ if (buf_id < 0) {
+ ret = -ENOBUFS;
+ goto err_dma_unmap;
+ }
+
+ desc = ath11k_hal_srng_src_get_next_entry(ab, srng);
+ if (!desc) {
+ ret = -ENOENT;
+ goto err_idr_remove;
+ }
+
+ buff->paddr = paddr;
+
+ cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, ar->pdev_idx) |
+ FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);
+
+ ath11k_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0);
+
+ ath11k_hal_srng_access_end(ab, srng);
+
+ return 0;
+
+err_idr_remove:
+ spin_lock_bh(&ring->idr_lock);
+ idr_remove(&ring->bufs_idr, buf_id);
+ spin_unlock_bh(&ring->idr_lock);
+err_dma_unmap:
+ dma_unmap_single(ab->dev, paddr, ring->buf_sz,
+ DMA_FROM_DEVICE);
+err:
+ ath11k_hal_srng_access_end(ab, srng);
+ return ret;
+}
+
+static int ath11k_dbring_fill_bufs(struct ath11k *ar,
+ struct ath11k_dbring *ring,
+ gfp_t gfp)
+{
+ struct ath11k_dbring_element *buff;
+ struct hal_srng *srng;
+ int num_remain, req_entries, num_free;
+ u32 align;
+ int size, ret;
+
+ srng = &ar->ab->hal.srng_list[ring->refill_srng.ring_id];
+
+ spin_lock_bh(&srng->lock);
+
+ num_free = ath11k_hal_srng_src_num_free(ar->ab, srng, true);
+ req_entries = min(num_free, ring->bufs_max);
+ num_remain = req_entries;
+ align = ring->buf_align;
+ size = sizeof(*buff) + ring->buf_sz + align - 1;
+
+ while (num_remain > 0) {
+ buff = kzalloc(size, gfp);
+ if (!buff)
+ break;
+
+ ret = ath11k_dbring_bufs_replenish(ar, ring, buff, gfp);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n",
+ num_remain, req_entries);
+ kfree(buff);
+ break;
+ }
+ num_remain--;
+ }
+
+ spin_unlock_bh(&srng->lock);
+
+ return num_remain;
+}
+
+int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
+ struct ath11k_dbring *ring,
+ enum wmi_direct_buffer_module id)
+{
+ struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd param = {0};
+ int ret;
+
+ if (id >= WMI_DIRECT_BUF_MAX)
+ return -EINVAL;
+
+ param.pdev_id = DP_SW2HW_MACID(ring->pdev_id);
+ param.module_id = id;
+ param.base_paddr_lo = lower_32_bits(ring->refill_srng.paddr);
+ param.base_paddr_hi = upper_32_bits(ring->refill_srng.paddr);
+ param.head_idx_paddr_lo = lower_32_bits(ring->hp_addr);
+ param.head_idx_paddr_hi = upper_32_bits(ring->hp_addr);
+ param.tail_idx_paddr_lo = lower_32_bits(ring->tp_addr);
+ param.tail_idx_paddr_hi = upper_32_bits(ring->tp_addr);
+ param.num_elems = ring->bufs_max;
+ param.buf_size = ring->buf_sz;
+ param.num_resp_per_event = ring->num_resp_per_event;
+ param.event_timeout_ms = ring->event_timeout_ms;
+
+ ret = ath11k_wmi_pdev_dma_ring_cfg(ar, &param);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int ath11k_dbring_set_cfg(struct ath11k *ar, struct ath11k_dbring *ring,
+ u32 num_resp_per_event, u32 event_timeout_ms,
+ int (*handler)(struct ath11k *,
+ struct ath11k_dbring_data *))
+{
+ if (WARN_ON(!ring))
+ return -EINVAL;
+
+ ring->num_resp_per_event = num_resp_per_event;
+ ring->event_timeout_ms = event_timeout_ms;
+ ring->handler = handler;
+
+ return 0;
+}
+
+int ath11k_dbring_buf_setup(struct ath11k *ar,
+ struct ath11k_dbring *ring,
+ struct ath11k_dbring_cap *db_cap)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct hal_srng *srng;
+ int ret;
+
+ srng = &ab->hal.srng_list[ring->refill_srng.ring_id];
+ ring->bufs_max = ring->refill_srng.size /
+ ath11k_hal_srng_get_entrysize(HAL_RXDMA_DIR_BUF);
+
+ ring->buf_sz = db_cap->min_buf_sz;
+ ring->buf_align = db_cap->min_buf_align;
+ ring->pdev_id = db_cap->pdev_id;
+ ring->hp_addr = ath11k_hal_srng_get_hp_addr(ar->ab, srng);
+ ring->tp_addr = ath11k_hal_srng_get_tp_addr(ar->ab, srng);
+
+ ret = ath11k_dbring_fill_bufs(ar, ring, GFP_KERNEL);
+
+ return ret;
+}
+
+int ath11k_dbring_srng_setup(struct ath11k *ar, struct ath11k_dbring *ring,
+ int ring_num, int num_entries)
+{
+ int ret;
+
+ ret = ath11k_dp_srng_setup(ar->ab, &ring->refill_srng, HAL_RXDMA_DIR_BUF,
+ ring_num, ar->pdev_idx, num_entries);
+ if (ret < 0) {
+ ath11k_warn(ar->ab, "failed to setup srng: %d ring_id %d\n",
+ ret, ring_num);
+ goto err;
+ }
+
+ return 0;
+err:
+ ath11k_dp_srng_cleanup(ar->ab, &ring->refill_srng);
+ return ret;
+}
+
+int ath11k_dbring_get_cap(struct ath11k_base *ab,
+ u8 pdev_idx,
+ enum wmi_direct_buffer_module id,
+ struct ath11k_dbring_cap *db_cap)
+{
+ int i;
+
+ if (!ab->num_db_cap || !ab->db_caps)
+ return -ENOENT;
+
+ if (id >= WMI_DIRECT_BUF_MAX)
+ return -EINVAL;
+
+ for (i = 0; i < ab->num_db_cap; i++) {
+ if (pdev_idx == ab->db_caps[i].pdev_id &&
+ id == ab->db_caps[i].id) {
+ *db_cap = ab->db_caps[i];
+
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
+ struct ath11k_dbring_buf_release_event *ev)
+{
+ struct ath11k_dbring *ring;
+ struct hal_srng *srng;
+ struct ath11k *ar;
+ struct ath11k_dbring_element *buff;
+ struct ath11k_dbring_data handler_data;
+ struct ath11k_buffer_addr desc;
+ u8 *vaddr_unalign;
+ u32 num_entry, num_buff_reaped;
+ u8 pdev_idx, rbm;
+ u32 cookie;
+ int buf_id;
+ int size;
+ dma_addr_t paddr;
+ int ret = 0;
+
+ pdev_idx = ev->fixed.pdev_id;
+
+ if (pdev_idx >= ab->num_radios) {
+ ath11k_warn(ab, "Invalid pdev id %d\n", pdev_idx);
+ return -EINVAL;
+ }
+
+ if (ev->fixed.num_buf_release_entry !=
+ ev->fixed.num_meta_data_entry) {
+ ath11k_warn(ab, "Buffer entry %d mismatch meta entry %d\n",
+ ev->fixed.num_buf_release_entry,
+ ev->fixed.num_meta_data_entry);
+ return -EINVAL;
+ }
+
+ ar = ab->pdevs[pdev_idx].ar;
+
+ rcu_read_lock();
+ if (!rcu_dereference(ab->pdevs_active[pdev_idx])) {
+ ret = -EINVAL;
+ goto rcu_unlock;
+ }
+
+ switch (ev->fixed.module_id) {
+ case WMI_DIRECT_BUF_SPECTRAL:
+ ring = ath11k_spectral_get_dbring(ar);
+ break;
+ default:
+ ring = NULL;
+ ath11k_warn(ab, "Recv dma buffer release ev on unsupp module %d\n",
+ ev->fixed.module_id);
+ break;
+ }
+
+ if (!ring) {
+ ret = -EINVAL;
+ goto rcu_unlock;
+ }
+
+ srng = &ab->hal.srng_list[ring->refill_srng.ring_id];
+ num_entry = ev->fixed.num_buf_release_entry;
+ size = sizeof(*buff) + ring->buf_sz + ring->buf_align - 1;
+ num_buff_reaped = 0;
+
+ spin_lock_bh(&srng->lock);
+
+ while (num_buff_reaped < num_entry) {
+ desc.info0 = ev->buf_entry[num_buff_reaped].paddr_lo;
+ desc.info1 = ev->buf_entry[num_buff_reaped].paddr_hi;
+ handler_data.meta = ev->meta_data[num_buff_reaped];
+
+ num_buff_reaped++;
+
+ ath11k_hal_rx_buf_addr_info_get(&desc, &paddr, &cookie, &rbm);
+
+ buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, cookie);
+
+ spin_lock_bh(&ring->idr_lock);
+ buff = idr_find(&ring->bufs_idr, buf_id);
+ if (!buff) {
+ spin_unlock_bh(&ring->idr_lock);
+ continue;
+ }
+ idr_remove(&ring->bufs_idr, buf_id);
+ spin_unlock_bh(&ring->idr_lock);
+
+ dma_unmap_single(ab->dev, buff->paddr, ring->buf_sz,
+ DMA_FROM_DEVICE);
+
+ if (ring->handler) {
+ vaddr_unalign = buff->payload;
+ handler_data.data = PTR_ALIGN(vaddr_unalign,
+ ring->buf_align);
+ handler_data.data_sz = ring->buf_sz;
+
+ ring->handler(ar, &handler_data);
+ }
+
+ memset(buff, 0, size);
+ ath11k_dbring_bufs_replenish(ar, ring, buff, GFP_ATOMIC);
+ }
+
+ spin_unlock_bh(&srng->lock);
+
+rcu_unlock:
+ rcu_read_unlock();
+
+ return ret;
+}
+
+void ath11k_dbring_srng_cleanup(struct ath11k *ar, struct ath11k_dbring *ring)
+{
+ ath11k_dp_srng_cleanup(ar->ab, &ring->refill_srng);
+}
+
+void ath11k_dbring_buf_cleanup(struct ath11k *ar, struct ath11k_dbring *ring)
+{
+ struct ath11k_dbring_element *buff;
+ int buf_id;
+
+ spin_lock_bh(&ring->idr_lock);
+ idr_for_each_entry(&ring->bufs_idr, buff, buf_id) {
+ idr_remove(&ring->bufs_idr, buf_id);
+ dma_unmap_single(ar->ab->dev, buff->paddr,
+ ring->buf_sz, DMA_FROM_DEVICE);
+ kfree(buff);
+ }
+
+ idr_destroy(&ring->bufs_idr);
+ spin_unlock_bh(&ring->idr_lock);
+}
diff --git a/drivers/net/wireless/ath/ath11k/dbring.h b/drivers/net/wireless/ath/ath11k/dbring.h
new file mode 100644
index 000000000000..f7fce9ef9c36
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/dbring.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef ATH11K_DBRING_H
+#define ATH11K_DBRING_H
+
+#include <linux/types.h>
+#include <linux/idr.h>
+#include <linux/spinlock.h>
+#include "dp.h"
+
+struct ath11k_dbring_element {
+ dma_addr_t paddr;
+ u8 payload[0];
+};
+
+struct ath11k_dbring_data {
+ void *data;
+ u32 data_sz;
+ struct wmi_dma_buf_release_meta_data meta;
+};
+
+struct ath11k_dbring_buf_release_event {
+ struct ath11k_wmi_dma_buf_release_fixed_param fixed;
+ struct wmi_dma_buf_release_entry *buf_entry;
+ struct wmi_dma_buf_release_meta_data *meta_data;
+ u32 num_buf_entry;
+ u32 num_meta;
+};
+
+struct ath11k_dbring_cap {
+ u32 pdev_id;
+ enum wmi_direct_buffer_module id;
+ u32 min_elem;
+ u32 min_buf_sz;
+ u32 min_buf_align;
+};
+
+struct ath11k_dbring {
+ struct dp_srng refill_srng;
+ struct idr bufs_idr;
+ /* Protects bufs_idr */
+ spinlock_t idr_lock;
+ dma_addr_t tp_addr;
+ dma_addr_t hp_addr;
+ int bufs_max;
+ u32 pdev_id;
+ u32 buf_sz;
+ u32 buf_align;
+ u32 num_resp_per_event;
+ u32 event_timeout_ms;
+ int (*handler)(struct ath11k *, struct ath11k_dbring_data *);
+};
+
+int ath11k_dbring_set_cfg(struct ath11k *ar,
+ struct ath11k_dbring *ring,
+ u32 num_resp_per_event,
+ u32 event_timeout_ms,
+ int (*handler)(struct ath11k *,
+ struct ath11k_dbring_data *));
+int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
+ struct ath11k_dbring *ring,
+ enum wmi_direct_buffer_module id);
+int ath11k_dbring_buf_setup(struct ath11k *ar,
+ struct ath11k_dbring *ring,
+ struct ath11k_dbring_cap *db_cap);
+int ath11k_dbring_srng_setup(struct ath11k *ar, struct ath11k_dbring *ring,
+ int ring_num, int num_entries);
+int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
+ struct ath11k_dbring_buf_release_event *ev);
+int ath11k_dbring_get_cap(struct ath11k_base *ab,
+ u8 pdev_idx,
+ enum wmi_direct_buffer_module id,
+ struct ath11k_dbring_cap *db_cap);
+void ath11k_dbring_srng_cleanup(struct ath11k *ar, struct ath11k_dbring *ring);
+void ath11k_dbring_buf_cleanup(struct ath11k *ar, struct ath11k_dbring *ring);
+#endif /* ATH11K_DBRING_H */
diff --git a/drivers/net/wireless/ath/ath11k/debug.c b/drivers/net/wireless/ath/ath11k/debug.c
index 3fd6b5af073b..62a1aa0565a9 100644
--- a/drivers/net/wireless/ath/ath11k/debug.c
+++ b/drivers/net/wireless/ath/ath11k/debug.c
@@ -12,6 +12,43 @@
#include "debug_htt_stats.h"
#include "peer.h"
+static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
+ "REO2SW1_RING",
+ "REO2SW2_RING",
+ "REO2SW3_RING",
+ "REO2SW4_RING",
+ "WBM2REO_LINK_RING",
+ "REO2TCL_RING",
+ "REO2FW_RING",
+ "RELEASE_RING",
+ "PPE_RELEASE_RING",
+ "TCL2TQM_RING",
+ "TQM_RELEASE_RING",
+ "REO_RELEASE_RING",
+ "WBM2SW0_RELEASE_RING",
+ "WBM2SW1_RELEASE_RING",
+ "WBM2SW2_RELEASE_RING",
+ "WBM2SW3_RELEASE_RING",
+ "REO_CMD_RING",
+ "REO_STATUS_RING",
+};
+
+static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
+ "FW2RXDMA_BUF_RING",
+ "FW2RXDMA_STATUS_RING",
+ "FW2RXDMA_LINK_RING",
+ "SW2RXDMA_BUF_RING",
+ "WBM2RXDMA_LINK_RING",
+ "RXDMA2FW_RING",
+ "RXDMA2SW_RING",
+ "RXDMA2RELEASE_RING",
+ "RXDMA2REO_RING",
+ "MONITOR_STATUS_RING",
+ "MONITOR_BUF_RING",
+ "MONITOR_DESC_RING",
+ "MONITOR_DEST_RING",
+};
+
void ath11k_info(struct ath11k_base *ab, const char *fmt, ...)
{
struct va_format vaf = {
@@ -739,12 +776,78 @@ static const struct file_operations fops_extd_rx_stats = {
.open = simple_open,
};
-static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file,
+static int ath11k_fill_bp_stats(struct ath11k_base *ab,
+ struct ath11k_bp_stats *bp_stats,
+ char *buf, int len, int size)
+{
+ lockdep_assert_held(&ab->base_lock);
+
+ len += scnprintf(buf + len, size - len, "count: %u\n",
+ bp_stats->count);
+ len += scnprintf(buf + len, size - len, "hp: %u\n",
+ bp_stats->hp);
+ len += scnprintf(buf + len, size - len, "tp: %u\n",
+ bp_stats->tp);
+ len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
+ jiffies_to_msecs(jiffies - bp_stats->jiffies));
+ return len;
+}
+
+static ssize_t ath11k_debug_dump_soc_ring_bp_stats(struct ath11k_base *ab,
+ char *buf, int size)
+{
+ struct ath11k_bp_stats *bp_stats;
+ bool stats_rxd = false;
+ u8 i, pdev_idx;
+ int len = 0;
+
+ len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
+ len += scnprintf(buf + len, size - len, "==================\n");
+
+ spin_lock_bh(&ab->base_lock);
+ for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
+ bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
+
+ if (!bp_stats->count)
+ continue;
+
+ len += scnprintf(buf + len, size - len, "Ring: %s\n",
+ htt_bp_umac_ring[i]);
+ len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
+ stats_rxd = true;
+ }
+
+ for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
+ for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
+ bp_stats =
+ &ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
+
+ if (!bp_stats->count)
+ continue;
+
+ len += scnprintf(buf + len, size - len, "Ring: %s\n",
+ htt_bp_lmac_ring[i]);
+ len += scnprintf(buf + len, size - len, "pdev: %d\n",
+ pdev_idx);
+ len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
+ stats_rxd = true;
+ }
+ }
+ spin_unlock_bh(&ab->base_lock);
+
+ if (!stats_rxd)
+ len += scnprintf(buf + len, size - len,
+ "No Ring Backpressure stats received\n\n");
+
+ return len;
+}
+
+static ssize_t ath11k_debug_dump_soc_dp_stats(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath11k_base *ab = file->private_data;
- struct ath11k_soc_dp_rx_stats *soc_stats = &ab->soc_stats;
+ struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
int len = 0, i, retval;
const int size = 4096;
static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
@@ -788,6 +891,19 @@ static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file,
soc_stats->hal_reo_error[2],
soc_stats->hal_reo_error[3]);
+ len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
+ len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
+
+ for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
+ len += scnprintf(buf + len, size - len, "ring%d: %u\n",
+ i, soc_stats->tx_err.desc_na[i]);
+
+ len += scnprintf(buf + len, size - len,
+ "\nMisc Transmit Failures: %d\n",
+ atomic_read(&soc_stats->tx_err.misc_fail));
+
+ len += ath11k_debug_dump_soc_ring_bp_stats(ab, buf + len, size - len);
+
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
@@ -796,8 +912,8 @@ static ssize_t ath11k_debug_dump_soc_rx_stats(struct file *file,
return retval;
}
-static const struct file_operations fops_soc_rx_stats = {
- .read = ath11k_debug_dump_soc_rx_stats,
+static const struct file_operations fops_soc_dp_stats = {
+ .read = ath11k_debug_dump_soc_dp_stats,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
@@ -819,8 +935,8 @@ int ath11k_debug_pdev_create(struct ath11k_base *ab)
debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
&fops_simulate_fw_crash);
- debugfs_create_file("soc_rx_stats", 0600, ab->debugfs_soc, ab,
- &fops_soc_rx_stats);
+ debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
+ &fops_soc_dp_stats);
return 0;
}
diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
index 9ae743e528af..1d64c3c51ac9 100644
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -172,11 +172,12 @@ int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring,
case HAL_RXDMA_DST:
case HAL_RXDMA_MONITOR_DST:
case HAL_RXDMA_MONITOR_DESC:
- case HAL_RXDMA_DIR_BUF:
params.intr_batch_cntr_thres_entries =
HAL_SRNG_INT_BATCH_THRESHOLD_OTHER;
params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_OTHER;
break;
+ case HAL_RXDMA_DIR_BUF:
+ break;
default:
ath11k_warn(ab, "Not a valid ring type in dp :%d\n", type);
return -EINVAL;
diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h
index 058a5c1d86ff..7587862d2e32 100644
--- a/drivers/net/wireless/ath/ath11k/dp.h
+++ b/drivers/net/wireless/ath/ath11k/dp.h
@@ -999,6 +999,48 @@ struct htt_resp_msg {
#define HTT_BACKPRESSURE_EVENT_HP_M GENMASK(15, 0)
#define HTT_BACKPRESSURE_EVENT_TP_M GENMASK(31, 16)
+#define HTT_BACKPRESSURE_UMAC_RING_TYPE 0
+#define HTT_BACKPRESSURE_LMAC_RING_TYPE 1
+
+enum htt_backpressure_umac_ringid {
+ HTT_SW_RING_IDX_REO_REO2SW1_RING,
+ HTT_SW_RING_IDX_REO_REO2SW2_RING,
+ HTT_SW_RING_IDX_REO_REO2SW3_RING,
+ HTT_SW_RING_IDX_REO_REO2SW4_RING,
+ HTT_SW_RING_IDX_REO_WBM2REO_LINK_RING,
+ HTT_SW_RING_IDX_REO_REO2TCL_RING,
+ HTT_SW_RING_IDX_REO_REO2FW_RING,
+ HTT_SW_RING_IDX_REO_REO_RELEASE_RING,
+ HTT_SW_RING_IDX_WBM_PPE_RELEASE_RING,
+ HTT_SW_RING_IDX_TCL_TCL2TQM_RING,
+ HTT_SW_RING_IDX_WBM_TQM_RELEASE_RING,
+ HTT_SW_RING_IDX_WBM_REO_RELEASE_RING,
+ HTT_SW_RING_IDX_WBM_WBM2SW0_RELEASE_RING,
+ HTT_SW_RING_IDX_WBM_WBM2SW1_RELEASE_RING,
+ HTT_SW_RING_IDX_WBM_WBM2SW2_RELEASE_RING,
+ HTT_SW_RING_IDX_WBM_WBM2SW3_RELEASE_RING,
+ HTT_SW_RING_IDX_REO_REO_CMD_RING,
+ HTT_SW_RING_IDX_REO_REO_STATUS_RING,
+ HTT_SW_UMAC_RING_IDX_MAX,
+};
+
+enum htt_backpressure_lmac_ringid {
+ HTT_SW_RING_IDX_FW2RXDMA_BUF_RING,
+ HTT_SW_RING_IDX_FW2RXDMA_STATUS_RING,
+ HTT_SW_RING_IDX_FW2RXDMA_LINK_RING,
+ HTT_SW_RING_IDX_SW2RXDMA_BUF_RING,
+ HTT_SW_RING_IDX_WBM2RXDMA_LINK_RING,
+ HTT_SW_RING_IDX_RXDMA2FW_RING,
+ HTT_SW_RING_IDX_RXDMA2SW_RING,
+ HTT_SW_RING_IDX_RXDMA2RELEASE_RING,
+ HTT_SW_RING_IDX_RXDMA2REO_RING,
+ HTT_SW_RING_IDX_MONITOR_STATUS_RING,
+ HTT_SW_RING_IDX_MONITOR_BUF_RING,
+ HTT_SW_RING_IDX_MONITOR_DESC_RING,
+ HTT_SW_RING_IDX_MONITOR_DEST_RING,
+ HTT_SW_LMAC_RING_IDX_MAX,
+};
+
/* ppdu stats
*
* @details
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index a54610d75c40..791d971784ce 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -653,10 +653,8 @@ static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx,
spin_lock_bh(&dp->reo_cmd_lock);
list_add_tail(&elem->list, &dp->reo_cmd_cache_flush_list);
dp->reo_cmd_cache_flush_count++;
- spin_unlock_bh(&dp->reo_cmd_lock);
/* Flush and invalidate aged REO desc from HW cache */
- spin_lock_bh(&dp->reo_cmd_lock);
list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_cache_flush_list,
list) {
if (dp->reo_cmd_cache_flush_count > DP_REO_DESC_FREE_THRESHOLD ||
@@ -1503,9 +1501,10 @@ static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab,
struct sk_buff *skb)
{
u32 *data = (u32 *)skb->data;
- u8 pdev_id, ring_type, ring_id;
+ u8 pdev_id, ring_type, ring_id, pdev_idx;
u16 hp, tp;
u32 backpressure_time;
+ struct ath11k_bp_stats *bp_stats;
pdev_id = FIELD_GET(HTT_BACKPRESSURE_EVENT_PDEV_ID_M, *data);
ring_type = FIELD_GET(HTT_BACKPRESSURE_EVENT_RING_TYPE_M, *data);
@@ -1520,6 +1519,31 @@ static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab,
ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt backpressure event, pdev %d, ring type %d,ring id %d, hp %d tp %d, backpressure time %d\n",
pdev_id, ring_type, ring_id, hp, tp, backpressure_time);
+
+ if (ring_type == HTT_BACKPRESSURE_UMAC_RING_TYPE) {
+ if (ring_id >= HTT_SW_UMAC_RING_IDX_MAX)
+ return;
+
+ bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[ring_id];
+ } else if (ring_type == HTT_BACKPRESSURE_LMAC_RING_TYPE) {
+ pdev_idx = DP_HW2SW_MACID(pdev_id);
+
+ if (ring_id >= HTT_SW_LMAC_RING_IDX_MAX || pdev_idx >= MAX_RADIOS)
+ return;
+
+ bp_stats = &ab->soc_stats.bp_stats.lmac_ring_bp_stats[ring_id][pdev_idx];
+ } else {
+ ath11k_warn(ab, "unknown ring type received in htt bp event %d\n",
+ ring_type);
+ return;
+ }
+
+ spin_lock_bh(&ab->base_lock);
+ bp_stats->hp = hp;
+ bp_stats->tp = tp;
+ bp_stats->count++;
+ bp_stats->jiffies = jiffies;
+ spin_unlock_bh(&ab->base_lock);
}
void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab,
@@ -2162,6 +2186,7 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
struct ieee80211_rx_status *rx_status)
{
u8 channel_num;
+ u32 center_freq;
rx_status->freq = 0;
rx_status->rate_idx = 0;
@@ -2172,8 +2197,11 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
channel_num = ath11k_dp_rx_h_msdu_start_freq(rx_desc);
+ center_freq = ath11k_dp_rx_h_msdu_start_freq(rx_desc) >> 16;
- if (channel_num >= 1 && channel_num <= 14) {
+ if (center_freq >= 5935 && center_freq <= 7105) {
+ rx_status->band = NL80211_BAND_6GHZ;
+ } else if (channel_num >= 1 && channel_num <= 14) {
rx_status->band = NL80211_BAND_2GHZ;
} else if (channel_num >= 36 && channel_num <= 173) {
rx_status->band = NL80211_BAND_5GHZ;
diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c
index 41c990aec6b7..1af76775b1a8 100644
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
@@ -121,8 +121,10 @@ tcl_ring_sel:
spin_unlock_bh(&tx_ring->tx_idr_lock);
if (ret < 0) {
- if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1))
+ if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1)) {
+ atomic_inc(&ab->soc_stats.tx_err.misc_fail);
return -ENOSPC;
+ }
/* Check if the next ring is available */
ring_selector++;
@@ -180,11 +182,13 @@ tcl_ring_sel:
default:
/* TODO: Take care of other encap modes as well */
ret = -EINVAL;
+ atomic_inc(&ab->soc_stats.tx_err.misc_fail);
goto fail_remove_idr;
}
ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(ab->dev, ti.paddr)) {
+ atomic_inc(&ab->soc_stats.tx_err.misc_fail);
ath11k_warn(ab, "failed to DMA map data Tx buffer\n");
ret = -ENOMEM;
goto fail_remove_idr;
@@ -208,6 +212,7 @@ tcl_ring_sel:
* desc because the desc is directly enqueued onto hw queue.
*/
ath11k_hal_srng_access_end(ab, tcl_ring);
+ ab->soc_stats.tx_err.desc_na[ti.ring_id]++;
spin_unlock_bh(&tcl_ring->lock);
ret = -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 2836a0f197ab..94ae2b9ea663 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -33,6 +33,15 @@
.max_power = 30, \
}
+#define CHAN6G(_channel, _freq, _flags) { \
+ .band = NL80211_BAND_6GHZ, \
+ .hw_value = (_channel), \
+ .center_freq = (_freq), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
static unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
@@ -86,6 +95,68 @@ static const struct ieee80211_channel ath11k_5ghz_channels[] = {
CHAN5G(173, 5865, 0),
};
+static const struct ieee80211_channel ath11k_6ghz_channels[] = {
+ CHAN6G(1, 5955, 0),
+ CHAN6G(5, 5975, 0),
+ CHAN6G(9, 5995, 0),
+ CHAN6G(13, 6015, 0),
+ CHAN6G(17, 6035, 0),
+ CHAN6G(21, 6055, 0),
+ CHAN6G(25, 6075, 0),
+ CHAN6G(29, 6095, 0),
+ CHAN6G(33, 6115, 0),
+ CHAN6G(37, 6135, 0),
+ CHAN6G(41, 6155, 0),
+ CHAN6G(45, 6175, 0),
+ CHAN6G(49, 6195, 0),
+ CHAN6G(53, 6215, 0),
+ CHAN6G(57, 6235, 0),
+ CHAN6G(61, 6255, 0),
+ CHAN6G(65, 6275, 0),
+ CHAN6G(69, 6295, 0),
+ CHAN6G(73, 6315, 0),
+ CHAN6G(77, 6335, 0),
+ CHAN6G(81, 6355, 0),
+ CHAN6G(85, 6375, 0),
+ CHAN6G(89, 6395, 0),
+ CHAN6G(93, 6415, 0),
+ CHAN6G(97, 6435, 0),
+ CHAN6G(101, 6455, 0),
+ CHAN6G(105, 6475, 0),
+ CHAN6G(109, 6495, 0),
+ CHAN6G(113, 6515, 0),
+ CHAN6G(117, 6535, 0),
+ CHAN6G(121, 6555, 0),
+ CHAN6G(125, 6575, 0),
+ CHAN6G(129, 6595, 0),
+ CHAN6G(133, 6615, 0),
+ CHAN6G(137, 6635, 0),
+ CHAN6G(141, 6655, 0),
+ CHAN6G(145, 6675, 0),
+ CHAN6G(149, 6695, 0),
+ CHAN6G(153, 6715, 0),
+ CHAN6G(157, 6735, 0),
+ CHAN6G(161, 6755, 0),
+ CHAN6G(165, 6775, 0),
+ CHAN6G(169, 6795, 0),
+ CHAN6G(173, 6815, 0),
+ CHAN6G(177, 6835, 0),
+ CHAN6G(181, 6855, 0),
+ CHAN6G(185, 6875, 0),
+ CHAN6G(189, 6895, 0),
+ CHAN6G(193, 6915, 0),
+ CHAN6G(197, 6935, 0),
+ CHAN6G(201, 6955, 0),
+ CHAN6G(205, 6975, 0),
+ CHAN6G(209, 6995, 0),
+ CHAN6G(213, 7015, 0),
+ CHAN6G(217, 7035, 0),
+ CHAN6G(221, 7055, 0),
+ CHAN6G(225, 7075, 0),
+ CHAN6G(229, 7095, 0),
+ CHAN6G(233, 7115, 0),
+};
+
static struct ieee80211_rate ath11k_legacy_rates[] = {
{ .bitrate = 10,
.hw_value = ATH11K_HW_RATE_CCK_LP_1M },
@@ -134,6 +205,17 @@ ath11k_phymodes[NUM_NL80211_BANDS][ATH11K_CHAN_WIDTH_NUM] = {
[NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
[NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,
},
+ [NL80211_BAND_6GHZ] = {
+ [NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20,
+ [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20,
+ [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40,
+ [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80,
+ [NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
+ [NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,
+ },
+
};
const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default = {
@@ -698,6 +780,8 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
struct ieee80211_vif *vif = arvif->vif;
struct ieee80211_mutable_offsets offs = {};
struct sk_buff *bcn;
+ struct ieee80211_mgmt *mgmt;
+ u8 *ies;
int ret;
if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
@@ -709,6 +793,17 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
return -EPERM;
}
+ ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
+ ies += sizeof(mgmt->u.beacon);
+
+ if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies)))
+ arvif->rsnie_present = true;
+
+ if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPA,
+ ies, (skb_tail_pointer(bcn) - ies)))
+ arvif->wpaie_present = true;
+
ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
kfree_skb(bcn);
@@ -798,6 +893,7 @@ static void ath11k_peer_assoc_h_crypto(struct ath11k *ar,
struct ieee80211_bss_conf *info = &vif->bss_conf;
struct cfg80211_chan_def def;
struct cfg80211_bss *bss;
+ struct ath11k_vif *arvif = (struct ath11k_vif *)vif->drv_priv;
const u8 *rsnie = NULL;
const u8 *wpaie = NULL;
@@ -808,7 +904,12 @@ static void ath11k_peer_assoc_h_crypto(struct ath11k *ar,
bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
- if (bss) {
+
+ if (arvif->rsnie_present || arvif->wpaie_present) {
+ arg->need_ptk_4_way = true;
+ if (arvif->wpaie_present)
+ arg->need_gtk_2_way = true;
+ } else if (bss) {
const struct cfg80211_bss_ies *ies;
rcu_read_lock();
@@ -1489,6 +1590,7 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
}
break;
case NL80211_BAND_5GHZ:
+ case NL80211_BAND_6GHZ:
/* Check HE first */
if (sta->he_cap.has_he) {
phymode = ath11k_mac_get_phymode_he(ar, sta);
@@ -1970,7 +2072,7 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
ret = ath11k_wmi_send_obss_color_collision_cfg_cmd(
ar, arvif->vdev_id, info->he_bss_color.color,
ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS,
- !info->he_bss_color.disabled);
+ info->he_bss_color.enabled);
if (ret)
ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",
arvif->vdev_id, ret);
@@ -2125,6 +2227,9 @@ static int ath11k_start_scan(struct ath11k *ar,
lockdep_assert_held(&ar->conf_mutex);
+ if (ath11k_spectral_get_mode(ar) == ATH11K_SPECTRAL_BACKGROUND)
+ ath11k_spectral_reset_buffer(ar);
+
ret = ath11k_wmi_send_scan_start_cmd(ar, arg);
if (ret)
return ret;
@@ -3411,7 +3516,7 @@ static void ath11k_mac_setup_ht_vht_cap(struct ath11k *ar,
rate_cap_rx_chainmask);
}
- if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {
+ if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && !ar->supports_6ghz) {
band = &ar->mac.sbands[NL80211_BAND_5GHZ];
ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info;
if (ht_cap_info)
@@ -3532,6 +3637,35 @@ ath11k_mac_filter_he_cap_mesh(struct ieee80211_he_cap_elem *he_cap_elem)
he_cap_elem->phy_cap_info[9] &= ~m;
}
+static __le16 ath11k_mac_setup_he_6ghz_cap(struct ath11k_pdev_cap *pcap,
+ struct ath11k_band_cap *bcap)
+{
+ u8 val;
+
+ bcap->he_6ghz_capa = IEEE80211_HT_MPDU_DENSITY_NONE;
+ if (bcap->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
+ bcap->he_6ghz_capa |=
+ FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS,
+ WLAN_HT_CAP_SM_PS_DYNAMIC);
+ else
+ bcap->he_6ghz_capa |=
+ FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS,
+ WLAN_HT_CAP_SM_PS_DISABLED);
+ val = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
+ pcap->vht_cap);
+ bcap->he_6ghz_capa |=
+ FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, val);
+ val = FIELD_GET(IEEE80211_VHT_CAP_MAX_MPDU_MASK, pcap->vht_cap);
+ bcap->he_6ghz_capa |=
+ FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, val);
+ if (pcap->vht_cap & IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN)
+ bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
+ if (pcap->vht_cap & IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN)
+ bcap->he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS;
+
+ return cpu_to_le16(bcap->he_6ghz_capa);
+}
+
static int ath11k_mac_copy_he_cap(struct ath11k *ar,
struct ath11k_pdev_cap *cap,
struct ieee80211_sband_iftype_data *data,
@@ -3614,6 +3748,11 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar,
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
ath11k_gen_ppe_thresh(&band_cap->he_ppet,
he_cap->ppe_thres);
+
+ if (band == NL80211_BAND_6GHZ) {
+ data[idx].he_6ghz_capa.capa =
+ ath11k_mac_setup_he_6ghz_cap(cap, band_cap);
+ }
idx++;
}
@@ -3643,6 +3782,16 @@ static void ath11k_mac_setup_he_cap(struct ath11k *ar,
band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ];
band->n_iftype_data = count;
}
+
+ if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
+ ar->supports_6ghz) {
+ count = ath11k_mac_copy_he_cap(ar, cap,
+ ar->mac.iftype[NL80211_BAND_6GHZ],
+ NL80211_BAND_6GHZ);
+ band = &ar->mac.sbands[NL80211_BAND_6GHZ];
+ band->iftype_data = ar->mac.iftype[NL80211_BAND_6GHZ];
+ band->n_iftype_data = count;
+ }
}
static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant)
@@ -4085,6 +4234,11 @@ ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
params->chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;
params->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;
}
+ if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP &&
+ ar->supports_6ghz) {
+ params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains;
+ params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains;
+ }
}
static u32
@@ -5217,7 +5371,7 @@ ath11k_mac_get_single_legacy_rate(struct ath11k *ar,
rate_idx = ffs(mask->control[band].legacy) - 1;
- if (band == NL80211_BAND_5GHZ)
+ if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ)
rate_idx += ATH11K_MAC_FIRST_OFDM_RATE_IDX;
hw_rate = ath11k_legacy_rates[rate_idx].hw_value;
@@ -5683,7 +5837,8 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
void *channels;
BUILD_BUG_ON((ARRAY_SIZE(ath11k_2ghz_channels) +
- ARRAY_SIZE(ath11k_5ghz_channels)) !=
+ ARRAY_SIZE(ath11k_5ghz_channels) +
+ ARRAY_SIZE(ath11k_6ghz_channels)) !=
ATH11K_NUM_CHANS);
reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx];
@@ -5696,6 +5851,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
return -ENOMEM;
band = &ar->mac.sbands[NL80211_BAND_2GHZ];
+ band->band = NL80211_BAND_2GHZ;
band->n_channels = ARRAY_SIZE(ath11k_2ghz_channels);
band->channels = channels;
band->n_bitrates = ath11k_g_rates_size;
@@ -5707,23 +5863,48 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
}
if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
- channels = kmemdup(ath11k_5ghz_channels,
- sizeof(ath11k_5ghz_channels),
- GFP_KERNEL);
- if (!channels) {
- kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
- return -ENOMEM;
+ if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) {
+ channels = kmemdup(ath11k_6ghz_channels,
+ sizeof(ath11k_6ghz_channels), GFP_KERNEL);
+ if (!channels) {
+ kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
+ return -ENOMEM;
+ }
+
+ ar->supports_6ghz = true;
+ band = &ar->mac.sbands[NL80211_BAND_6GHZ];
+ band->band = NL80211_BAND_6GHZ;
+ band->n_channels = ARRAY_SIZE(ath11k_6ghz_channels);
+ band->channels = channels;
+ band->n_bitrates = ath11k_a_rates_size;
+ band->bitrates = ath11k_a_rates;
+ ar->hw->wiphy->bands[NL80211_BAND_6GHZ] = band;
+ ath11k_mac_update_ch_list(ar, band,
+ reg_cap->low_5ghz_chan,
+ reg_cap->high_5ghz_chan);
}
- band = &ar->mac.sbands[NL80211_BAND_5GHZ];
- band->n_channels = ARRAY_SIZE(ath11k_5ghz_channels);
- band->channels = channels;
- band->n_bitrates = ath11k_a_rates_size;
- band->bitrates = ath11k_a_rates;
- ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
- ath11k_mac_update_ch_list(ar, band,
- reg_cap->low_5ghz_chan,
- reg_cap->high_5ghz_chan);
+ if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ) {
+ channels = kmemdup(ath11k_5ghz_channels,
+ sizeof(ath11k_5ghz_channels),
+ GFP_KERNEL);
+ if (!channels) {
+ kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
+ kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
+ return -ENOMEM;
+ }
+
+ band = &ar->mac.sbands[NL80211_BAND_5GHZ];
+ band->band = NL80211_BAND_5GHZ;
+ band->n_channels = ARRAY_SIZE(ath11k_5ghz_channels);
+ band->channels = channels;
+ band->n_bitrates = ath11k_a_rates_size;
+ band->bitrates = ath11k_a_rates;
+ ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
+ ath11k_mac_update_ch_list(ar, band,
+ reg_cap->low_5ghz_chan,
+ reg_cap->high_5ghz_chan);
+ }
}
return 0;
@@ -5777,6 +5958,7 @@ static void __ath11k_mac_unregister(struct ath11k *ar)
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
+ kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
SET_IEEE80211_DEV(ar->hw, NULL);
}
diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
index 453aa9c06969..7c9dc91cc48a 100644
--- a/drivers/net/wireless/ath/ath11k/reg.c
+++ b/drivers/net/wireless/ath/ath11k/reg.c
@@ -161,6 +161,10 @@ int ath11k_reg_update_chan_list(struct ath11k *ar)
else
ch->phy_mode = MODE_11A;
+ if (channel->band == NL80211_BAND_6GHZ &&
+ cfg80211_channel_is_psc(channel))
+ ch->psc_channel = true;
+
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
"mac channel [%d/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
i, params->nallchans,
diff --git a/drivers/net/wireless/ath/ath11k/spectral.c b/drivers/net/wireless/ath/ath11k/spectral.c
new file mode 100644
index 000000000000..1c5d65bb411f
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/spectral.c
@@ -0,0 +1,1023 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/relay.h>
+#include "core.h"
+#include "debug.h"
+
+#define ATH11K_SPECTRAL_NUM_RESP_PER_EVENT 2
+#define ATH11K_SPECTRAL_EVENT_TIMEOUT_MS 1
+
+#define ATH11K_SPECTRAL_DWORD_SIZE 4
+/* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes */
+#define ATH11K_SPECTRAL_BIN_SIZE 4
+#define ATH11K_SPECTRAL_ATH11K_MIN_BINS 64
+#define ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS 32
+#define ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS 256
+
+#define ATH11K_SPECTRAL_SAMPLE_FFT_BIN_MASK 0xFF
+
+#define ATH11K_SPECTRAL_SCAN_COUNT_MAX 4095
+
+/* Max channel computed by sum of 2g and 5g band channels */
+#define ATH11K_SPECTRAL_TOTAL_CHANNEL 41
+#define ATH11K_SPECTRAL_SAMPLES_PER_CHANNEL 70
+#define ATH11K_SPECTRAL_PER_SAMPLE_SIZE (sizeof(struct fft_sample_ath11k) + \
+ ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS)
+#define ATH11K_SPECTRAL_TOTAL_SAMPLE (ATH11K_SPECTRAL_TOTAL_CHANNEL * \
+ ATH11K_SPECTRAL_SAMPLES_PER_CHANNEL)
+#define ATH11K_SPECTRAL_SUB_BUFF_SIZE ATH11K_SPECTRAL_PER_SAMPLE_SIZE
+#define ATH11K_SPECTRAL_NUM_SUB_BUF ATH11K_SPECTRAL_TOTAL_SAMPLE
+
+#define ATH11K_SPECTRAL_20MHZ 20
+#define ATH11K_SPECTRAL_40MHZ 40
+#define ATH11K_SPECTRAL_80MHZ 80
+
+#define ATH11K_SPECTRAL_SIGNATURE 0xFA
+
+#define ATH11K_SPECTRAL_TAG_RADAR_SUMMARY 0x0
+#define ATH11K_SPECTRAL_TAG_RADAR_FFT 0x1
+#define ATH11K_SPECTRAL_TAG_SCAN_SUMMARY 0x2
+#define ATH11K_SPECTRAL_TAG_SCAN_SEARCH 0x3
+
+#define SPECTRAL_TLV_HDR_LEN GENMASK(15, 0)
+#define SPECTRAL_TLV_HDR_TAG GENMASK(23, 16)
+#define SPECTRAL_TLV_HDR_SIGN GENMASK(31, 24)
+
+#define SPECTRAL_SUMMARY_INFO0_AGC_TOTAL_GAIN GENMASK(7, 0)
+#define SPECTRAL_SUMMARY_INFO0_OB_FLAG BIT(8)
+#define SPECTRAL_SUMMARY_INFO0_GRP_IDX GENMASK(16, 9)
+#define SPECTRAL_SUMMARY_INFO0_RECENT_RFSAT BIT(17)
+#define SPECTRAL_SUMMARY_INFO0_INBAND_PWR_DB GENMASK(27, 18)
+#define SPECTRAL_SUMMARY_INFO0_FALSE_SCAN BIT(28)
+#define SPECTRAL_SUMMARY_INFO0_DETECTOR_ID GENMASK(30, 29)
+#define SPECTRAL_SUMMARY_INFO0_PRI80 BIT(31)
+
+#define SPECTRAL_SUMMARY_INFO2_PEAK_SIGNED_IDX GENMASK(11, 0)
+#define SPECTRAL_SUMMARY_INFO2_PEAK_MAGNITUDE GENMASK(21, 12)
+#define SPECTRAL_SUMMARY_INFO2_NARROWBAND_MASK GENMASK(29, 22)
+#define SPECTRAL_SUMMARY_INFO2_GAIN_CHANGE BIT(30)
+
+struct spectral_tlv {
+ __le32 timestamp;
+ __le32 header;
+} __packed;
+
+struct spectral_summary_fft_report {
+ __le32 timestamp;
+ __le32 tlv_header;
+ __le32 info0;
+ __le32 reserve0;
+ __le32 info2;
+ __le32 reserve1;
+} __packed;
+
+struct ath11k_spectral_summary_report {
+ struct wmi_dma_buf_release_meta_data meta;
+ u32 timestamp;
+ u8 agc_total_gain;
+ u8 grp_idx;
+ u16 inb_pwr_db;
+ s16 peak_idx;
+ u16 peak_mag;
+ u8 detector_id;
+ bool out_of_band_flag;
+ bool rf_saturation;
+ bool primary80;
+ bool gain_change;
+ bool false_scan;
+};
+
+#define SPECTRAL_FFT_REPORT_INFO0_DETECTOR_ID GENMASK(1, 0)
+#define SPECTRAL_FFT_REPORT_INFO0_FFT_NUM GENMASK(4, 2)
+#define SPECTRAL_FFT_REPORT_INFO0_RADAR_CHECK GENMASK(16, 5)
+#define SPECTRAL_FFT_REPORT_INFO0_PEAK_SIGNED_IDX GENMASK(27, 17)
+#define SPECTRAL_FFT_REPORT_INFO0_CHAIN_IDX GENMASK(30, 28)
+
+#define SPECTRAL_FFT_REPORT_INFO1_BASE_PWR_DB GENMASK(8, 0)
+#define SPECTRAL_FFT_REPORT_INFO1_TOTAL_GAIN_DB GENMASK(16, 9)
+
+#define SPECTRAL_FFT_REPORT_INFO2_NUM_STRONG_BINS GENMASK(7, 0)
+#define SPECTRAL_FFT_REPORT_INFO2_PEAK_MAGNITUDE GENMASK(17, 8)
+#define SPECTRAL_FFT_REPORT_INFO2_AVG_PWR_DB GENMASK(24, 18)
+#define SPECTRAL_FFT_REPORT_INFO2_REL_PWR_DB GENMASK(31, 25)
+
+struct spectral_search_fft_report {
+ __le32 timestamp;
+ __le32 tlv_header;
+ __le32 info0;
+ __le32 info1;
+ __le32 info2;
+ __le32 reserve0;
+ u8 bins[0];
+} __packed;
+
+struct ath11k_spectral_search_report {
+ u32 timestamp;
+ u8 detector_id;
+ u8 fft_count;
+ u16 radar_check;
+ s16 peak_idx;
+ u8 chain_idx;
+ u16 base_pwr_db;
+ u8 total_gain_db;
+ u8 strong_bin_count;
+ u16 peak_mag;
+ u8 avg_pwr_db;
+ u8 rel_pwr_db;
+};
+
+static struct dentry *create_buf_file_handler(const char *filename,
+ struct dentry *parent,
+ umode_t mode,
+ struct rchan_buf *buf,
+ int *is_global)
+{
+ struct dentry *buf_file;
+
+ buf_file = debugfs_create_file(filename, mode, parent, buf,
+ &relay_file_operations);
+ *is_global = 1;
+ return buf_file;
+}
+
+static int remove_buf_file_handler(struct dentry *dentry)
+{
+ debugfs_remove(dentry);
+
+ return 0;
+}
+
+static struct rchan_callbacks rfs_scan_cb = {
+ .create_buf_file = create_buf_file_handler,
+ .remove_buf_file = remove_buf_file_handler,
+};
+
+static struct ath11k_vif *ath11k_spectral_get_vdev(struct ath11k *ar)
+{
+ struct ath11k_vif *arvif;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ if (list_empty(&ar->arvifs))
+ return NULL;
+
+ /* if there already is a vif doing spectral, return that. */
+ list_for_each_entry(arvif, &ar->arvifs, list)
+ if (arvif->spectral_enabled)
+ return arvif;
+
+ /* otherwise, return the first vif. */
+ return list_first_entry(&ar->arvifs, typeof(*arvif), list);
+}
+
+static int ath11k_spectral_scan_trigger(struct ath11k *ar)
+{
+ struct ath11k_vif *arvif;
+ int ret;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ arvif = ath11k_spectral_get_vdev(ar);
+ if (!arvif)
+ return -ENODEV;
+
+ if (ar->spectral.mode == ATH11K_SPECTRAL_DISABLED)
+ return 0;
+
+ ret = ath11k_wmi_vdev_spectral_enable(ar, arvif->vdev_id,
+ ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR,
+ ATH11K_WMI_SPECTRAL_ENABLE_CMD_ENABLE);
+ if (ret)
+ return ret;
+
+ ret = ath11k_wmi_vdev_spectral_enable(ar, arvif->vdev_id,
+ ATH11K_WMI_SPECTRAL_TRIGGER_CMD_TRIGGER,
+ ATH11K_WMI_SPECTRAL_ENABLE_CMD_ENABLE);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ath11k_spectral_scan_config(struct ath11k *ar,
+ enum ath11k_spectral_mode mode)
+{
+ struct ath11k_wmi_vdev_spectral_conf_param param = { 0 };
+ struct ath11k_vif *arvif;
+ int ret, count;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ arvif = ath11k_spectral_get_vdev(ar);
+ if (!arvif)
+ return -ENODEV;
+
+ arvif->spectral_enabled = (mode != ATH11K_SPECTRAL_DISABLED);
+ ar->spectral.mode = mode;
+
+ ret = ath11k_wmi_vdev_spectral_enable(ar, arvif->vdev_id,
+ ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR,
+ ATH11K_WMI_SPECTRAL_ENABLE_CMD_DISABLE);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to enable spectral scan: %d\n", ret);
+ return ret;
+ }
+
+ if (mode == ATH11K_SPECTRAL_DISABLED)
+ return 0;
+
+ if (mode == ATH11K_SPECTRAL_BACKGROUND)
+ count = ATH11K_WMI_SPECTRAL_COUNT_DEFAULT;
+ else
+ count = max_t(u16, 1, ar->spectral.count);
+
+ param.vdev_id = arvif->vdev_id;
+ param.scan_count = count;
+ param.scan_fft_size = ar->spectral.fft_size;
+ param.scan_period = ATH11K_WMI_SPECTRAL_PERIOD_DEFAULT;
+ param.scan_priority = ATH11K_WMI_SPECTRAL_PRIORITY_DEFAULT;
+ param.scan_gc_ena = ATH11K_WMI_SPECTRAL_GC_ENA_DEFAULT;
+ param.scan_restart_ena = ATH11K_WMI_SPECTRAL_RESTART_ENA_DEFAULT;
+ param.scan_noise_floor_ref = ATH11K_WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT;
+ param.scan_init_delay = ATH11K_WMI_SPECTRAL_INIT_DELAY_DEFAULT;
+ param.scan_nb_tone_thr = ATH11K_WMI_SPECTRAL_NB_TONE_THR_DEFAULT;
+ param.scan_str_bin_thr = ATH11K_WMI_SPECTRAL_STR_BIN_THR_DEFAULT;
+ param.scan_wb_rpt_mode = ATH11K_WMI_SPECTRAL_WB_RPT_MODE_DEFAULT;
+ param.scan_rssi_rpt_mode = ATH11K_WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT;
+ param.scan_rssi_thr = ATH11K_WMI_SPECTRAL_RSSI_THR_DEFAULT;
+ param.scan_pwr_format = ATH11K_WMI_SPECTRAL_PWR_FORMAT_DEFAULT;
+ param.scan_rpt_mode = ATH11K_WMI_SPECTRAL_RPT_MODE_DEFAULT;
+ param.scan_bin_scale = ATH11K_WMI_SPECTRAL_BIN_SCALE_DEFAULT;
+ param.scan_dbm_adj = ATH11K_WMI_SPECTRAL_DBM_ADJ_DEFAULT;
+ param.scan_chn_mask = ATH11K_WMI_SPECTRAL_CHN_MASK_DEFAULT;
+
+ ret = ath11k_wmi_vdev_spectral_conf(ar, &param);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to configure spectral scan: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static ssize_t ath11k_read_file_spec_scan_ctl(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k *ar = file->private_data;
+ char *mode = "";
+ size_t len;
+ enum ath11k_spectral_mode spectral_mode;
+
+ mutex_lock(&ar->conf_mutex);
+ spectral_mode = ar->spectral.mode;
+ mutex_unlock(&ar->conf_mutex);
+
+ switch (spectral_mode) {
+ case ATH11K_SPECTRAL_DISABLED:
+ mode = "disable";
+ break;
+ case ATH11K_SPECTRAL_BACKGROUND:
+ mode = "background";
+ break;
+ case ATH11K_SPECTRAL_MANUAL:
+ mode = "manual";
+ break;
+ }
+
+ len = strlen(mode);
+ return simple_read_from_buffer(user_buf, count, ppos, mode, len);
+}
+
+static ssize_t ath11k_write_file_spec_scan_ctl(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k *ar = file->private_data;
+ char buf[32];
+ ssize_t len;
+ int ret;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+
+ mutex_lock(&ar->conf_mutex);
+
+ if (strncmp("trigger", buf, 7) == 0) {
+ if (ar->spectral.mode == ATH11K_SPECTRAL_MANUAL ||
+ ar->spectral.mode == ATH11K_SPECTRAL_BACKGROUND) {
+ /* reset the configuration to adopt possibly changed
+ * debugfs parameters
+ */
+ ret = ath11k_spectral_scan_config(ar, ar->spectral.mode);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to reconfigure spectral scan: %d\n",
+ ret);
+ goto unlock;
+ }
+
+ ret = ath11k_spectral_scan_trigger(ar);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to trigger spectral scan: %d\n",
+ ret);
+ }
+ } else {
+ ret = -EINVAL;
+ }
+ } else if (strncmp("background", buf, 10) == 0) {
+ ret = ath11k_spectral_scan_config(ar, ATH11K_SPECTRAL_BACKGROUND);
+ } else if (strncmp("manual", buf, 6) == 0) {
+ ret = ath11k_spectral_scan_config(ar, ATH11K_SPECTRAL_MANUAL);
+ } else if (strncmp("disable", buf, 7) == 0) {
+ ret = ath11k_spectral_scan_config(ar, ATH11K_SPECTRAL_DISABLED);
+ } else {
+ ret = -EINVAL;
+ }
+
+unlock:
+ mutex_unlock(&ar->conf_mutex);
+
+ if (ret)
+ return ret;
+
+ return count;
+}
+
+static const struct file_operations fops_scan_ctl = {
+ .read = ath11k_read_file_spec_scan_ctl,
+ .write = ath11k_write_file_spec_scan_ctl,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t ath11k_read_file_spectral_count(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k *ar = file->private_data;
+ char buf[32];
+ size_t len;
+ u16 spectral_count;
+
+ mutex_lock(&ar->conf_mutex);
+ spectral_count = ar->spectral.count;
+ mutex_unlock(&ar->conf_mutex);
+
+ len = sprintf(buf, "%d\n", spectral_count);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath11k_write_file_spectral_count(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k *ar = file->private_data;
+ unsigned long val;
+ char buf[32];
+ ssize_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ if (val > ATH11K_SPECTRAL_SCAN_COUNT_MAX)
+ return -EINVAL;
+
+ mutex_lock(&ar->conf_mutex);
+ ar->spectral.count = val;
+ mutex_unlock(&ar->conf_mutex);
+
+ return count;
+}
+
+static const struct file_operations fops_scan_count = {
+ .read = ath11k_read_file_spectral_count,
+ .write = ath11k_write_file_spectral_count,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t ath11k_read_file_spectral_bins(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k *ar = file->private_data;
+ char buf[32];
+ unsigned int bins, fft_size;
+ size_t len;
+
+ mutex_lock(&ar->conf_mutex);
+
+ fft_size = ar->spectral.fft_size;
+ bins = 1 << fft_size;
+
+ mutex_unlock(&ar->conf_mutex);
+
+ len = sprintf(buf, "%d\n", bins);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath11k_write_file_spectral_bins(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k *ar = file->private_data;
+ unsigned long val;
+ char buf[32];
+ ssize_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ if (val < ATH11K_SPECTRAL_ATH11K_MIN_BINS ||
+ val > SPECTRAL_ATH11K_MAX_NUM_BINS)
+ return -EINVAL;
+
+ if (!is_power_of_2(val))
+ return -EINVAL;
+
+ mutex_lock(&ar->conf_mutex);
+ ar->spectral.fft_size = ilog2(val);
+ mutex_unlock(&ar->conf_mutex);
+
+ return count;
+}
+
+static const struct file_operations fops_scan_bins = {
+ .read = ath11k_read_file_spectral_bins,
+ .write = ath11k_write_file_spectral_bins,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static int ath11k_spectral_pull_summary(struct ath11k *ar,
+ struct wmi_dma_buf_release_meta_data *meta,
+ struct spectral_summary_fft_report *summary,
+ struct ath11k_spectral_summary_report *report)
+{
+ report->timestamp = __le32_to_cpu(summary->timestamp);
+ report->agc_total_gain = FIELD_GET(SPECTRAL_SUMMARY_INFO0_AGC_TOTAL_GAIN,
+ __le32_to_cpu(summary->info0));
+ report->out_of_band_flag = FIELD_GET(SPECTRAL_SUMMARY_INFO0_OB_FLAG,
+ __le32_to_cpu(summary->info0));
+ report->grp_idx = FIELD_GET(SPECTRAL_SUMMARY_INFO0_GRP_IDX,
+ __le32_to_cpu(summary->info0));
+ report->rf_saturation = FIELD_GET(SPECTRAL_SUMMARY_INFO0_RECENT_RFSAT,
+ __le32_to_cpu(summary->info0));
+ report->inb_pwr_db = FIELD_GET(SPECTRAL_SUMMARY_INFO0_INBAND_PWR_DB,
+ __le32_to_cpu(summary->info0));
+ report->false_scan = FIELD_GET(SPECTRAL_SUMMARY_INFO0_FALSE_SCAN,
+ __le32_to_cpu(summary->info0));
+ report->detector_id = FIELD_GET(SPECTRAL_SUMMARY_INFO0_DETECTOR_ID,
+ __le32_to_cpu(summary->info0));
+ report->primary80 = FIELD_GET(SPECTRAL_SUMMARY_INFO0_PRI80,
+ __le32_to_cpu(summary->info0));
+ report->peak_idx = FIELD_GET(SPECTRAL_SUMMARY_INFO2_PEAK_SIGNED_IDX,
+ __le32_to_cpu(summary->info2));
+ report->peak_mag = FIELD_GET(SPECTRAL_SUMMARY_INFO2_PEAK_MAGNITUDE,
+ __le32_to_cpu(summary->info2));
+ report->gain_change = FIELD_GET(SPECTRAL_SUMMARY_INFO2_GAIN_CHANGE,
+ __le32_to_cpu(summary->info2));
+
+ memcpy(&report->meta, meta, sizeof(*meta));
+
+ return 0;
+}
+
+static int ath11k_spectral_pull_search(struct ath11k *ar,
+ struct spectral_search_fft_report *search,
+ struct ath11k_spectral_search_report *report)
+{
+ report->timestamp = __le32_to_cpu(search->timestamp);
+ report->detector_id = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_DETECTOR_ID,
+ __le32_to_cpu(search->info0));
+ report->fft_count = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_FFT_NUM,
+ __le32_to_cpu(search->info0));
+ report->radar_check = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_RADAR_CHECK,
+ __le32_to_cpu(search->info0));
+ report->peak_idx = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_PEAK_SIGNED_IDX,
+ __le32_to_cpu(search->info0));
+ report->chain_idx = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_CHAIN_IDX,
+ __le32_to_cpu(search->info0));
+ report->base_pwr_db = FIELD_GET(SPECTRAL_FFT_REPORT_INFO1_BASE_PWR_DB,
+ __le32_to_cpu(search->info1));
+ report->total_gain_db = FIELD_GET(SPECTRAL_FFT_REPORT_INFO1_TOTAL_GAIN_DB,
+ __le32_to_cpu(search->info1));
+ report->strong_bin_count = FIELD_GET(SPECTRAL_FFT_REPORT_INFO2_NUM_STRONG_BINS,
+ __le32_to_cpu(search->info2));
+ report->peak_mag = FIELD_GET(SPECTRAL_FFT_REPORT_INFO2_PEAK_MAGNITUDE,
+ __le32_to_cpu(search->info2));
+ report->avg_pwr_db = FIELD_GET(SPECTRAL_FFT_REPORT_INFO2_AVG_PWR_DB,
+ __le32_to_cpu(search->info2));
+ report->rel_pwr_db = FIELD_GET(SPECTRAL_FFT_REPORT_INFO2_REL_PWR_DB,
+ __le32_to_cpu(search->info2));
+
+ return 0;
+}
+
+static u8 ath11k_spectral_get_max_exp(s8 max_index, u8 max_magnitude,
+ int bin_len, u8 *bins)
+{
+ int dc_pos;
+ u8 max_exp;
+
+ dc_pos = bin_len / 2;
+
+ /* peak index outside of bins */
+ if (dc_pos <= max_index || -dc_pos >= max_index)
+ return 0;
+
+ for (max_exp = 0; max_exp < 8; max_exp++) {
+ if (bins[dc_pos + max_index] == (max_magnitude >> max_exp))
+ break;
+ }
+
+ /* max_exp not found */
+ if (bins[dc_pos + max_index] != (max_magnitude >> max_exp))
+ return 0;
+
+ return max_exp;
+}
+
+static void ath11k_spectral_parse_16bit_fft(u8 *outbins, u8 *inbins, int num_bins)
+{
+ int i;
+ __le16 *data = (__le16 *)inbins;
+
+ i = 0;
+ while (i < num_bins) {
+ outbins[i] = (__le16_to_cpu(data[i])) &
+ ATH11K_SPECTRAL_SAMPLE_FFT_BIN_MASK;
+ i++;
+ }
+}
+
+static
+int ath11k_spectral_process_fft(struct ath11k *ar,
+ struct ath11k_spectral_summary_report *summary,
+ void *data,
+ struct fft_sample_ath11k *fft_sample,
+ u32 data_len)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct spectral_search_fft_report *fft_report = data;
+ struct ath11k_spectral_search_report search;
+ struct spectral_tlv *tlv;
+ int tlv_len, bin_len, num_bins;
+ u16 length, freq;
+ u8 chan_width_mhz;
+ int ret;
+
+ lockdep_assert_held(&ar->spectral.lock);
+
+ tlv = (struct spectral_tlv *)data;
+ tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN, __le32_to_cpu(tlv->header));
+ /* convert Dword into bytes */
+ tlv_len *= ATH11K_SPECTRAL_DWORD_SIZE;
+ bin_len = tlv_len - (sizeof(*fft_report) - sizeof(*tlv));
+
+ if (data_len < (bin_len + sizeof(*fft_report))) {
+ ath11k_warn(ab, "mismatch in expected bin len %d and data len %d\n",
+ bin_len, data_len);
+ return -EINVAL;
+ }
+
+ num_bins = bin_len / ATH11K_SPECTRAL_BIN_SIZE;
+ /* Only In-band bins are useful to user for visualize */
+ num_bins >>= 1;
+
+ if (num_bins < ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS ||
+ num_bins > ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS ||
+ !is_power_of_2(num_bins)) {
+ ath11k_warn(ab, "Invalid num of bins %d\n", num_bins);
+ return -EINVAL;
+ }
+
+ ret = ath11k_spectral_pull_search(ar, data, &search);
+ if (ret) {
+ ath11k_warn(ab, "failed to pull search report %d\n", ret);
+ return ret;
+ }
+
+ chan_width_mhz = summary->meta.ch_width;
+
+ switch (chan_width_mhz) {
+ case ATH11K_SPECTRAL_20MHZ:
+ case ATH11K_SPECTRAL_40MHZ:
+ case ATH11K_SPECTRAL_80MHZ:
+ fft_sample->chan_width_mhz = chan_width_mhz;
+ break;
+ default:
+ ath11k_warn(ab, "invalid channel width %d\n", chan_width_mhz);
+ return -EINVAL;
+ }
+
+ length = sizeof(*fft_sample) - sizeof(struct fft_sample_tlv) + num_bins;
+ fft_sample->tlv.type = ATH_FFT_SAMPLE_ATH11K;
+ fft_sample->tlv.length = __cpu_to_be16(length);
+
+ fft_sample->tsf = __cpu_to_be32(search.timestamp);
+ fft_sample->max_magnitude = __cpu_to_be16(search.peak_mag);
+ fft_sample->max_index = FIELD_GET(SPECTRAL_FFT_REPORT_INFO0_PEAK_SIGNED_IDX,
+ __le32_to_cpu(fft_report->info0));
+
+ summary->inb_pwr_db >>= 1;
+ fft_sample->rssi = __cpu_to_be16(summary->inb_pwr_db);
+ fft_sample->noise = __cpu_to_be32(summary->meta.noise_floor[search.chain_idx]);
+
+ freq = summary->meta.freq1;
+ fft_sample->freq1 = __cpu_to_be16(freq);
+
+ freq = summary->meta.freq2;
+ fft_sample->freq2 = __cpu_to_be16(freq);
+
+ ath11k_spectral_parse_16bit_fft(fft_sample->data,
+ fft_report->bins,
+ num_bins);
+
+ fft_sample->max_exp = ath11k_spectral_get_max_exp(fft_sample->max_index,
+ search.peak_mag,
+ num_bins,
+ fft_sample->data);
+
+ if (ar->spectral.rfs_scan)
+ relay_write(ar->spectral.rfs_scan, fft_sample,
+ length + sizeof(struct fft_sample_tlv));
+
+ return 0;
+}
+
+static int ath11k_spectral_process_data(struct ath11k *ar,
+ struct ath11k_dbring_data *param)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct spectral_tlv *tlv;
+ struct spectral_summary_fft_report *summary = NULL;
+ struct ath11k_spectral_summary_report summ_rpt;
+ struct fft_sample_ath11k *fft_sample = NULL;
+ u8 *data;
+ u32 data_len, i;
+ u8 sign, tag;
+ int tlv_len, sample_sz;
+ int ret;
+ bool quit = false;
+
+ spin_lock_bh(&ar->spectral.lock);
+
+ if (!ar->spectral.enabled) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ sample_sz = sizeof(*fft_sample) + ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS;
+ fft_sample = kmalloc(sample_sz, GFP_ATOMIC);
+ if (!fft_sample) {
+ ret = -ENOBUFS;
+ goto unlock;
+ }
+
+ data = param->data;
+ data_len = param->data_sz;
+ i = 0;
+ while (!quit && (i < data_len)) {
+ if ((i + sizeof(*tlv)) > data_len) {
+ ath11k_warn(ab, "failed to parse spectral tlv hdr at bytes %d\n",
+ i);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ tlv = (struct spectral_tlv *)&data[i];
+ sign = FIELD_GET(SPECTRAL_TLV_HDR_SIGN,
+ __le32_to_cpu(tlv->header));
+ if (sign != ATH11K_SPECTRAL_SIGNATURE) {
+ ath11k_warn(ab, "Invalid sign 0x%x at bytes %d\n",
+ sign, i);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN,
+ __le32_to_cpu(tlv->header));
+ /* convert Dword into bytes */
+ tlv_len *= ATH11K_SPECTRAL_DWORD_SIZE;
+ if ((i + sizeof(*tlv) + tlv_len) > data_len) {
+ ath11k_warn(ab, "failed to parse spectral tlv payload at bytes %d tlv_len:%d data_len:%d\n",
+ i, tlv_len, data_len);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ tag = FIELD_GET(SPECTRAL_TLV_HDR_TAG,
+ __le32_to_cpu(tlv->header));
+ switch (tag) {
+ case ATH11K_SPECTRAL_TAG_SCAN_SUMMARY:
+ /* HW bug in tlv length of summary report,
+ * HW report 3 DWORD size but the data payload
+ * is 4 DWORD size (16 bytes).
+ * Need to remove this workaround once HW bug fixed
+ */
+ tlv_len = sizeof(*summary) - sizeof(*tlv);
+
+ if (tlv_len < (sizeof(*summary) - sizeof(*tlv))) {
+ ath11k_warn(ab, "failed to parse spectral summary at bytes %d tlv_len:%d\n",
+ i, tlv_len);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ summary = (struct spectral_summary_fft_report *)tlv;
+ ath11k_spectral_pull_summary(ar, &param->meta,
+ summary, &summ_rpt);
+ break;
+ case ATH11K_SPECTRAL_TAG_SCAN_SEARCH:
+ if (tlv_len < (sizeof(struct spectral_search_fft_report) -
+ sizeof(*tlv))) {
+ ath11k_warn(ab, "failed to parse spectral search fft at bytes %d\n",
+ i);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ memset(fft_sample, 0, sample_sz);
+ ret = ath11k_spectral_process_fft(ar, &summ_rpt, tlv,
+ fft_sample,
+ data_len - i);
+ if (ret) {
+ ath11k_warn(ab, "failed to process spectral fft at bytes %d\n",
+ i);
+ goto err;
+ }
+ quit = true;
+ break;
+ }
+
+ i += sizeof(*tlv) + tlv_len;
+ }
+
+err:
+ kfree(fft_sample);
+unlock:
+ spin_unlock_bh(&ar->spectral.lock);
+ return ret;
+}
+
+static int ath11k_spectral_ring_alloc(struct ath11k *ar,
+ struct ath11k_dbring_cap *db_cap)
+{
+ struct ath11k_spectral *sp = &ar->spectral;
+ int ret;
+
+ ret = ath11k_dbring_srng_setup(ar, &sp->rx_ring,
+ 0, db_cap->min_elem);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to setup db ring\n");
+ return ret;
+ }
+
+ ath11k_dbring_set_cfg(ar, &sp->rx_ring,
+ ATH11K_SPECTRAL_NUM_RESP_PER_EVENT,
+ ATH11K_SPECTRAL_EVENT_TIMEOUT_MS,
+ ath11k_spectral_process_data);
+
+ ret = ath11k_dbring_buf_setup(ar, &sp->rx_ring, db_cap);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to setup db ring buffer\n");
+ goto srng_cleanup;
+ }
+
+ ret = ath11k_dbring_wmi_cfg_setup(ar, &sp->rx_ring,
+ WMI_DIRECT_BUF_SPECTRAL);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
+ goto buffer_cleanup;
+ }
+
+ return 0;
+
+buffer_cleanup:
+ ath11k_dbring_buf_cleanup(ar, &sp->rx_ring);
+srng_cleanup:
+ ath11k_dbring_srng_cleanup(ar, &sp->rx_ring);
+ return ret;
+}
+
+static inline void ath11k_spectral_ring_free(struct ath11k *ar)
+{
+ struct ath11k_spectral *sp = &ar->spectral;
+
+ if (!sp->enabled)
+ return;
+
+ ath11k_dbring_srng_cleanup(ar, &sp->rx_ring);
+ ath11k_dbring_buf_cleanup(ar, &sp->rx_ring);
+}
+
+static inline void ath11k_spectral_debug_unregister(struct ath11k *ar)
+{
+ debugfs_remove(ar->spectral.scan_bins);
+ ar->spectral.scan_bins = NULL;
+
+ debugfs_remove(ar->spectral.scan_count);
+ ar->spectral.scan_count = NULL;
+
+ debugfs_remove(ar->spectral.scan_ctl);
+ ar->spectral.scan_ctl = NULL;
+
+ if (ar->spectral.rfs_scan) {
+ relay_close(ar->spectral.rfs_scan);
+ ar->spectral.rfs_scan = NULL;
+ }
+}
+
+int ath11k_spectral_vif_stop(struct ath11k_vif *arvif)
+{
+ if (!arvif->spectral_enabled)
+ return 0;
+
+ return ath11k_spectral_scan_config(arvif->ar, ATH11K_SPECTRAL_DISABLED);
+}
+
+void ath11k_spectral_reset_buffer(struct ath11k *ar)
+{
+ if (!ar->spectral.enabled)
+ return;
+
+ if (ar->spectral.rfs_scan)
+ relay_reset(ar->spectral.rfs_scan);
+}
+
+void ath11k_spectral_deinit(struct ath11k_base *ab)
+{
+ struct ath11k *ar;
+ struct ath11k_spectral *sp;
+ int i;
+
+ for (i = 0; i < ab->num_radios; i++) {
+ ar = ab->pdevs[i].ar;
+ sp = &ar->spectral;
+
+ if (!sp->enabled)
+ continue;
+
+ ath11k_spectral_debug_unregister(ar);
+ ath11k_spectral_ring_free(ar);
+
+ spin_lock_bh(&sp->lock);
+
+ sp->mode = ATH11K_SPECTRAL_DISABLED;
+ sp->enabled = false;
+
+ spin_unlock_bh(&sp->lock);
+ }
+}
+
+static inline int ath11k_spectral_debug_register(struct ath11k *ar)
+{
+ int ret;
+
+ ar->spectral.rfs_scan = relay_open("spectral_scan",
+ ar->debug.debugfs_pdev,
+ ATH11K_SPECTRAL_SUB_BUFF_SIZE,
+ ATH11K_SPECTRAL_NUM_SUB_BUF,
+ &rfs_scan_cb, NULL);
+ if (!ar->spectral.rfs_scan) {
+ ath11k_warn(ar->ab, "failed to open relay in pdev %d\n",
+ ar->pdev_idx);
+ return -EINVAL;
+ }
+
+ ar->spectral.scan_ctl = debugfs_create_file("spectral_scan_ctl",
+ 0600,
+ ar->debug.debugfs_pdev, ar,
+ &fops_scan_ctl);
+ if (!ar->spectral.scan_ctl) {
+ ath11k_warn(ar->ab, "failed to open debugfs in pdev %d\n",
+ ar->pdev_idx);
+ ret = -EINVAL;
+ goto debug_unregister;
+ }
+
+ ar->spectral.scan_count = debugfs_create_file("spectral_count",
+ 0600,
+ ar->debug.debugfs_pdev, ar,
+ &fops_scan_count);
+ if (!ar->spectral.scan_count) {
+ ath11k_warn(ar->ab, "failed to open debugfs in pdev %d\n",
+ ar->pdev_idx);
+ ret = -EINVAL;
+ goto debug_unregister;
+ }
+
+ ar->spectral.scan_bins = debugfs_create_file("spectral_bins",
+ 0600,
+ ar->debug.debugfs_pdev, ar,
+ &fops_scan_bins);
+ if (!ar->spectral.scan_bins) {
+ ath11k_warn(ar->ab, "failed to open debugfs in pdev %d\n",
+ ar->pdev_idx);
+ ret = -EINVAL;
+ goto debug_unregister;
+ }
+
+ return 0;
+
+debug_unregister:
+ ath11k_spectral_debug_unregister(ar);
+ return ret;
+}
+
+int ath11k_spectral_init(struct ath11k_base *ab)
+{
+ struct ath11k *ar;
+ struct ath11k_spectral *sp;
+ struct ath11k_dbring_cap db_cap;
+ int ret;
+ int i;
+
+ if (!test_bit(WMI_TLV_SERVICE_FREQINFO_IN_METADATA,
+ ab->wmi_ab.svc_map)) {
+ ath11k_info(ab, "spectral not supported\n");
+ return 0;
+ }
+
+ for (i = 0; i < ab->num_radios; i++) {
+ ar = ab->pdevs[i].ar;
+ sp = &ar->spectral;
+
+ ret = ath11k_dbring_get_cap(ar->ab, ar->pdev_idx,
+ WMI_DIRECT_BUF_SPECTRAL,
+ &db_cap);
+ if (ret) {
+ ath11k_info(ab, "spectral not enabled for pdev %d\n", i);
+ continue;
+ }
+
+ idr_init(&sp->rx_ring.bufs_idr);
+ spin_lock_init(&sp->rx_ring.idr_lock);
+ spin_lock_init(&sp->lock);
+
+ ret = ath11k_spectral_ring_alloc(ar, &db_cap);
+ if (ret) {
+ ath11k_warn(ab, "failed to init spectral ring for pdev %d\n",
+ i);
+ goto deinit;
+ }
+
+ spin_lock_bh(&sp->lock);
+
+ sp->mode = ATH11K_SPECTRAL_DISABLED;
+ sp->count = ATH11K_WMI_SPECTRAL_COUNT_DEFAULT;
+ sp->fft_size = ATH11K_WMI_SPECTRAL_FFT_SIZE_DEFAULT;
+ sp->enabled = true;
+
+ spin_unlock_bh(&sp->lock);
+
+ ret = ath11k_spectral_debug_register(ar);
+ if (ret) {
+ ath11k_warn(ab, "failed to register spectral for pdev %d\n",
+ i);
+ goto deinit;
+ }
+ }
+
+ return 0;
+
+deinit:
+ ath11k_spectral_deinit(ab);
+ return ret;
+}
+
+enum ath11k_spectral_mode ath11k_spectral_get_mode(struct ath11k *ar)
+{
+ if (ar->spectral.enabled)
+ return ar->spectral.mode;
+ else
+ return ATH11K_SPECTRAL_DISABLED;
+}
+
+struct ath11k_dbring *ath11k_spectral_get_dbring(struct ath11k *ar)
+{
+ if (ar->spectral.enabled)
+ return &ar->spectral.rx_ring;
+ else
+ return NULL;
+}
diff --git a/drivers/net/wireless/ath/ath11k/spectral.h b/drivers/net/wireless/ath/ath11k/spectral.h
new file mode 100644
index 000000000000..081744265f2a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/spectral.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef ATH11K_SPECTRAL_H
+#define ATH11K_SPECTRAL_H
+
+#include "../spectral_common.h"
+#include "dbring.h"
+
+/* enum ath11k_spectral_mode:
+ *
+ * @SPECTRAL_DISABLED: spectral mode is disabled
+ * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with
+ * something else.
+ * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples
+ * is performed manually.
+ */
+enum ath11k_spectral_mode {
+ ATH11K_SPECTRAL_DISABLED = 0,
+ ATH11K_SPECTRAL_BACKGROUND,
+ ATH11K_SPECTRAL_MANUAL,
+};
+
+struct ath11k_spectral {
+ struct ath11k_dbring rx_ring;
+ /* Protects enabled */
+ spinlock_t lock;
+ struct rchan *rfs_scan; /* relay(fs) channel for spectral scan */
+ struct dentry *scan_ctl;
+ struct dentry *scan_count;
+ struct dentry *scan_bins;
+ enum ath11k_spectral_mode mode;
+ u16 count;
+ u8 fft_size;
+ bool enabled;
+};
+
+#ifdef CONFIG_ATH11K_SPECTRAL
+
+int ath11k_spectral_init(struct ath11k_base *ab);
+void ath11k_spectral_deinit(struct ath11k_base *ab);
+int ath11k_spectral_vif_stop(struct ath11k_vif *arvif);
+void ath11k_spectral_reset_buffer(struct ath11k *ar);
+enum ath11k_spectral_mode ath11k_spectral_get_mode(struct ath11k *ar);
+struct ath11k_dbring *ath11k_spectral_get_dbring(struct ath11k *ar);
+
+#else
+
+static inline int ath11k_spectral_init(struct ath11k_base *ab)
+{
+ return 0;
+}
+
+static inline void ath11k_spectral_deinit(struct ath11k_base *ab)
+{
+}
+
+static inline int ath11k_spectral_vif_stop(struct ath11k_vif *arvif)
+{
+ return 0;
+}
+
+static inline void ath11k_spectral_reset_buffer(struct ath11k *ar)
+{
+}
+
+static inline
+enum ath11k_spectral_mode ath11k_spectral_get_mode(struct ath11k *ar)
+{
+ return ATH11K_SPECTRAL_DISABLED;
+}
+
+static inline
+struct ath11k_dbring *ath11k_spectral_get_dbring(struct ath11k *ar)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_ATH11K_SPECTRAL */
+#endif /* ATH11K_SPECTRAL_H */
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index c2a972377687..8e3437a65673 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -27,6 +27,11 @@ struct wmi_tlv_svc_ready_parse {
bool wmi_svc_bitmap_done;
};
+struct wmi_tlv_dma_ring_caps_parse {
+ struct wmi_dma_ring_capabilities *dma_ring_caps;
+ u32 n_dma_ring_caps;
+};
+
struct wmi_tlv_svc_rdy_ext_parse {
struct ath11k_service_ext_param param;
struct wmi_soc_mac_phy_hw_mode_caps *hw_caps;
@@ -39,15 +44,35 @@ struct wmi_tlv_svc_rdy_ext_parse {
struct wmi_soc_hal_reg_capabilities *soc_hal_reg_caps;
struct wmi_hal_reg_capabilities_ext *ext_hal_reg_caps;
u32 n_ext_hal_reg_caps;
+ struct wmi_tlv_dma_ring_caps_parse dma_caps_parse;
bool hw_mode_done;
bool mac_phy_done;
bool ext_hal_reg_done;
+ bool mac_phy_chainmask_combo_done;
+ bool mac_phy_chainmask_cap_done;
+ bool oem_dma_ring_cap_done;
+ bool dma_ring_cap_done;
+};
+
+struct wmi_tlv_svc_rdy_ext2_parse {
+ struct wmi_tlv_dma_ring_caps_parse dma_caps_parse;
+ bool dma_ring_cap_done;
};
struct wmi_tlv_rdy_parse {
u32 num_extra_mac_addr;
};
+struct wmi_tlv_dma_buf_release_parse {
+ struct ath11k_wmi_dma_buf_release_fixed_param fixed;
+ struct wmi_dma_buf_release_entry *buf_entry;
+ struct wmi_dma_buf_release_meta_data *meta_data;
+ u32 num_buf_entry;
+ u32 num_meta;
+ bool buf_entry_done;
+ bool meta_data_done;
+};
+
static const struct wmi_tlv_policy wmi_tlv_policies[] = {
[WMI_TAG_ARRAY_BYTE]
= { .min_len = 0 },
@@ -368,6 +393,17 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle,
memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
sizeof(struct ath11k_ppe_threshold));
+ cap_band = &pdev_cap->band[NL80211_BAND_6GHZ];
+ cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g;
+ cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g;
+ cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g;
+ cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext;
+ cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g;
+ memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g,
+ sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
+ memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
+ sizeof(struct ath11k_ppe_threshold));
+
return 0;
}
@@ -1692,10 +1728,10 @@ ath11k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
*/
if (param->auth_flag)
cmd->peer_flags |= WMI_PEER_AUTH;
- if (param->need_ptk_4_way)
+ if (param->need_ptk_4_way) {
cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
- else
- cmd->peer_flags &= ~WMI_PEER_NEED_PTK_4_WAY;
+ cmd->peer_flags &= ~WMI_PEER_AUTH;
+ }
if (param->need_gtk_2_way)
cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
/* safe mode bypass the 4-way handshake */
@@ -1778,6 +1814,7 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
cmd->peer_he_cap_info = param->peer_he_cap_macinfo[0];
cmd->peer_he_cap_info_ext = param->peer_he_cap_macinfo[1];
cmd->peer_he_cap_info_internal = param->peer_he_cap_macinfo_internal;
+ cmd->peer_he_caps_6ghz = param->peer_he_caps_6ghz;
cmd->peer_he_ops = param->peer_he_ops;
memcpy(&cmd->peer_he_cap_phy, &param->peer_he_cap_phyinfo,
sizeof(param->peer_he_cap_phyinfo));
@@ -1831,6 +1868,7 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
/* HE Rates */
cmd->peer_he_mcs = param->peer_he_mcs_count;
+ cmd->min_data_rate = param->min_data_rate;
ptr += sizeof(*mcs);
@@ -1886,6 +1924,8 @@ void ath11k_wmi_start_scan_init(struct ath11k *ar,
arg->dwell_time_active = 50;
arg->dwell_time_active_2g = 0;
arg->dwell_time_passive = 150;
+ arg->dwell_time_active_6g = 40;
+ arg->dwell_time_passive_6g = 30;
arg->min_rest_time = 50;
arg->max_rest_time = 500;
arg->repeat_probe_time = 0;
@@ -1990,6 +2030,8 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
int i, ret, len;
u32 *tmp_ptr;
u8 extraie_len_with_pad = 0;
+ struct hint_short_ssid *s_ssid = NULL;
+ struct hint_bssid *hint_bssid = NULL;
len = sizeof(*cmd);
@@ -2011,6 +2053,14 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
roundup(params->extraie.len, sizeof(u32));
len += extraie_len_with_pad;
+ if (params->num_hint_bssid)
+ len += TLV_HDR_SIZE +
+ params->num_hint_bssid * sizeof(struct hint_bssid);
+
+ if (params->num_hint_s_ssid)
+ len += TLV_HDR_SIZE +
+ params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
+
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
if (!skb)
return -ENOMEM;
@@ -2032,6 +2082,8 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
cmd->dwell_time_active = params->dwell_time_active;
cmd->dwell_time_active_2g = params->dwell_time_active_2g;
cmd->dwell_time_passive = params->dwell_time_passive;
+ cmd->dwell_time_active_6g = params->dwell_time_active_6g;
+ cmd->dwell_time_passive_6g = params->dwell_time_passive_6g;
cmd->min_rest_time = params->min_rest_time;
cmd->max_rest_time = params->max_rest_time;
cmd->repeat_probe_time = params->repeat_probe_time;
@@ -2109,6 +2161,68 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
ptr += extraie_len_with_pad;
+ if (params->num_hint_s_ssid) {
+ len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
+ tlv = ptr;
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
+ FIELD_PREP(WMI_TLV_LEN, len);
+ ptr += TLV_HDR_SIZE;
+ s_ssid = ptr;
+ for (i = 0; i < params->num_hint_s_ssid; ++i) {
+ s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags;
+ s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid;
+ s_ssid++;
+ }
+ ptr += len;
+ }
+
+ if (params->num_hint_bssid) {
+ len = params->num_hint_bssid * sizeof(struct hint_bssid);
+ tlv = ptr;
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
+ FIELD_PREP(WMI_TLV_LEN, len);
+ ptr += TLV_HDR_SIZE;
+ hint_bssid = ptr;
+ for (i = 0; i < params->num_hint_bssid; ++i) {
+ hint_bssid->freq_flags =
+ params->hint_bssid[i].freq_flags;
+ ether_addr_copy(&params->hint_bssid[i].bssid.addr[0],
+ &hint_bssid->bssid.addr[0]);
+ hint_bssid++;
+ }
+ }
+
+ len = params->num_hint_s_ssid * sizeof(struct hint_short_ssid);
+ tlv = ptr;
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
+ FIELD_PREP(WMI_TLV_LEN, len);
+ ptr += TLV_HDR_SIZE;
+ if (params->num_hint_s_ssid) {
+ s_ssid = ptr;
+ for (i = 0; i < params->num_hint_s_ssid; ++i) {
+ s_ssid->freq_flags = params->hint_s_ssid[i].freq_flags;
+ s_ssid->short_ssid = params->hint_s_ssid[i].short_ssid;
+ s_ssid++;
+ }
+ }
+ ptr += len;
+
+ len = params->num_hint_bssid * sizeof(struct hint_bssid);
+ tlv = ptr;
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_FIXED_STRUCT) |
+ FIELD_PREP(WMI_TLV_LEN, len);
+ ptr += TLV_HDR_SIZE;
+ if (params->num_hint_bssid) {
+ hint_bssid = ptr;
+ for (i = 0; i < params->num_hint_bssid; ++i) {
+ hint_bssid->freq_flags =
+ params->hint_bssid[i].freq_flags;
+ ether_addr_copy(&params->hint_bssid[i].bssid.addr[0],
+ &hint_bssid->bssid.addr[0]);
+ hint_bssid++;
+ }
+ }
+
ret = ath11k_wmi_cmd_send(wmi, skb,
WMI_START_SCAN_CMDID);
if (ret) {
@@ -2178,91 +2292,110 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
struct wmi_tlv *tlv;
void *ptr;
int i, ret, len;
+ u16 num_send_chans, num_sends = 0, max_chan_limit = 0;
u32 *reg1, *reg2;
- len = sizeof(*cmd) + TLV_HDR_SIZE +
- sizeof(*chan_info) * chan_list->nallchans;
+ tchan_info = &chan_list->ch_param[0];
+ while (chan_list->nallchans) {
+ len = sizeof(*cmd) + TLV_HDR_SIZE;
+ max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) /
+ sizeof(*chan_info);
- skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
- if (!skb)
- return -ENOMEM;
+ if (chan_list->nallchans > max_chan_limit)
+ num_send_chans = max_chan_limit;
+ else
+ num_send_chans = chan_list->nallchans;
- cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
- cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) |
- FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+ chan_list->nallchans -= num_send_chans;
+ len += sizeof(*chan_info) * num_send_chans;
- ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
- "WMI no.of chan = %d len = %d\n", chan_list->nallchans, len);
- cmd->pdev_id = chan_list->pdev_id;
- cmd->num_scan_chans = chan_list->nallchans;
-
- ptr = skb->data + sizeof(*cmd);
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
+ if (!skb)
+ return -ENOMEM;
- len = sizeof(*chan_info) * chan_list->nallchans;
- tlv = ptr;
- tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
- FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
- ptr += TLV_HDR_SIZE;
+ cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_SCAN_CHAN_LIST_CMD) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+ cmd->pdev_id = chan_list->pdev_id;
+ cmd->num_scan_chans = num_send_chans;
+ if (num_sends)
+ cmd->flags |= WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG;
- tchan_info = &chan_list->ch_param[0];
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI no.of chan = %d len = %d pdev_id = %d num_sends = %d\n",
+ num_send_chans, len, cmd->pdev_id, num_sends);
- for (i = 0; i < chan_list->nallchans; ++i) {
- chan_info = ptr;
- memset(chan_info, 0, sizeof(*chan_info));
- len = sizeof(*chan_info);
- chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG,
- WMI_TAG_CHANNEL) |
- FIELD_PREP(WMI_TLV_LEN,
- len - TLV_HDR_SIZE);
-
- reg1 = &chan_info->reg_info_1;
- reg2 = &chan_info->reg_info_2;
- chan_info->mhz = tchan_info->mhz;
- chan_info->band_center_freq1 = tchan_info->cfreq1;
- chan_info->band_center_freq2 = tchan_info->cfreq2;
-
- if (tchan_info->is_chan_passive)
- chan_info->info |= WMI_CHAN_INFO_PASSIVE;
- if (tchan_info->allow_he)
- chan_info->info |= WMI_CHAN_INFO_ALLOW_HE;
- else if (tchan_info->allow_vht)
- chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT;
- else if (tchan_info->allow_ht)
- chan_info->info |= WMI_CHAN_INFO_ALLOW_HT;
- if (tchan_info->half_rate)
- chan_info->info |= WMI_CHAN_INFO_HALF_RATE;
- if (tchan_info->quarter_rate)
- chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE;
-
- chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE,
- tchan_info->phy_mode);
- *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR,
- tchan_info->minpower);
- *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR,
- tchan_info->maxpower);
- *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR,
- tchan_info->maxregpower);
- *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS,
- tchan_info->reg_class_id);
- *reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX,
- tchan_info->antennamax);
+ ptr = skb->data + sizeof(*cmd);
- ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
- "WMI chan scan list chan[%d] = %u\n",
- i, chan_info->mhz);
+ len = sizeof(*chan_info) * num_send_chans;
+ tlv = ptr;
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
+ FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
+ ptr += TLV_HDR_SIZE;
- ptr += sizeof(*chan_info);
+ for (i = 0; i < num_send_chans; ++i) {
+ chan_info = ptr;
+ memset(chan_info, 0, sizeof(*chan_info));
+ len = sizeof(*chan_info);
+ chan_info->tlv_header = FIELD_PREP(WMI_TLV_TAG,
+ WMI_TAG_CHANNEL) |
+ FIELD_PREP(WMI_TLV_LEN,
+ len - TLV_HDR_SIZE);
+
+ reg1 = &chan_info->reg_info_1;
+ reg2 = &chan_info->reg_info_2;
+ chan_info->mhz = tchan_info->mhz;
+ chan_info->band_center_freq1 = tchan_info->cfreq1;
+ chan_info->band_center_freq2 = tchan_info->cfreq2;
+
+ if (tchan_info->is_chan_passive)
+ chan_info->info |= WMI_CHAN_INFO_PASSIVE;
+ if (tchan_info->allow_he)
+ chan_info->info |= WMI_CHAN_INFO_ALLOW_HE;
+ else if (tchan_info->allow_vht)
+ chan_info->info |= WMI_CHAN_INFO_ALLOW_VHT;
+ else if (tchan_info->allow_ht)
+ chan_info->info |= WMI_CHAN_INFO_ALLOW_HT;
+ if (tchan_info->half_rate)
+ chan_info->info |= WMI_CHAN_INFO_HALF_RATE;
+ if (tchan_info->quarter_rate)
+ chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE;
+ if (tchan_info->psc_channel)
+ chan_info->info |= WMI_CHAN_INFO_PSC;
+
+ chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE,
+ tchan_info->phy_mode);
+ *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MIN_PWR,
+ tchan_info->minpower);
+ *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_PWR,
+ tchan_info->maxpower);
+ *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_MAX_REG_PWR,
+ tchan_info->maxregpower);
+ *reg1 |= FIELD_PREP(WMI_CHAN_REG_INFO1_REG_CLS,
+ tchan_info->reg_class_id);
+ *reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX,
+ tchan_info->antennamax);
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI chan scan list chan[%d] = %u, chan_info->info %8x\n",
+ i, chan_info->mhz, chan_info->info);
+
+ ptr += sizeof(*chan_info);
+
+ tchan_info++;
+ }
- tchan_info++;
- }
+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n");
+ dev_kfree_skb(skb);
+ return ret;
+ }
- ret = ath11k_wmi_cmd_send(wmi, skb, WMI_SCAN_CHAN_LIST_CMDID);
- if (ret) {
- ath11k_warn(ar->ab, "failed to send WMI_SCAN_CHAN_LIST cmd\n");
- dev_kfree_skb(skb);
+ num_sends++;
}
- return ret;
+ return 0;
}
int ath11k_wmi_send_wmm_update_cmd_tlv(struct ath11k *ar, u32 vdev_id,
@@ -3265,6 +3398,236 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab)
return ath11k_init_cmd_send(&wmi_sc->wmi[0], &init_param);
}
+int ath11k_wmi_vdev_spectral_conf(struct ath11k *ar,
+ struct ath11k_wmi_vdev_spectral_conf_param *param)
+{
+ struct ath11k_wmi_vdev_spectral_conf_cmd *cmd;
+ struct sk_buff *skb;
+ int ret;
+
+ skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct ath11k_wmi_vdev_spectral_conf_cmd *)skb->data;
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
+ WMI_TAG_VDEV_SPECTRAL_CONFIGURE_CMD) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+
+ memcpy(&cmd->param, param, sizeof(*param));
+
+ ret = ath11k_wmi_cmd_send(ar->wmi, skb,
+ WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID);
+ if (ret) {
+ ath11k_warn(ar->ab,
+ "failed to send spectral scan config wmi cmd\n");
+ goto err;
+ }
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI spectral scan config cmd vdev_id 0x%x\n",
+ param->vdev_id);
+
+ return 0;
+err:
+ dev_kfree_skb(skb);
+ return ret;
+}
+
+int ath11k_wmi_vdev_spectral_enable(struct ath11k *ar, u32 vdev_id,
+ u32 trigger, u32 enable)
+{
+ struct ath11k_wmi_vdev_spectral_enable_cmd *cmd;
+ struct sk_buff *skb;
+ int ret;
+
+ skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct ath11k_wmi_vdev_spectral_enable_cmd *)skb->data;
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
+ WMI_TAG_VDEV_SPECTRAL_ENABLE_CMD) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+
+ cmd->vdev_id = vdev_id;
+ cmd->trigger_cmd = trigger;
+ cmd->enable_cmd = enable;
+
+ ret = ath11k_wmi_cmd_send(ar->wmi, skb,
+ WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID);
+ if (ret) {
+ ath11k_warn(ar->ab,
+ "failed to send spectral enable wmi cmd\n");
+ goto err;
+ }
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI spectral enable cmd vdev id 0x%x\n",
+ vdev_id);
+
+ return 0;
+err:
+ dev_kfree_skb(skb);
+ return ret;
+}
+
+int ath11k_wmi_pdev_dma_ring_cfg(struct ath11k *ar,
+ struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *param)
+{
+ struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *cmd;
+ struct sk_buff *skb;
+ int ret;
+
+ skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *)skb->data;
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DMA_RING_CFG_REQ) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+
+ cmd->pdev_id = param->pdev_id;
+ cmd->module_id = param->module_id;
+ cmd->base_paddr_lo = param->base_paddr_lo;
+ cmd->base_paddr_hi = param->base_paddr_hi;
+ cmd->head_idx_paddr_lo = param->head_idx_paddr_lo;
+ cmd->head_idx_paddr_hi = param->head_idx_paddr_hi;
+ cmd->tail_idx_paddr_lo = param->tail_idx_paddr_lo;
+ cmd->tail_idx_paddr_hi = param->tail_idx_paddr_hi;
+ cmd->num_elems = param->num_elems;
+ cmd->buf_size = param->buf_size;
+ cmd->num_resp_per_event = param->num_resp_per_event;
+ cmd->event_timeout_ms = param->event_timeout_ms;
+
+ ret = ath11k_wmi_cmd_send(ar->wmi, skb,
+ WMI_PDEV_DMA_RING_CFG_REQ_CMDID);
+ if (ret) {
+ ath11k_warn(ar->ab,
+ "failed to send dma ring cfg req wmi cmd\n");
+ goto err;
+ }
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI DMA ring cfg req cmd pdev_id 0x%x\n",
+ param->pdev_id);
+
+ return 0;
+err:
+ dev_kfree_skb(skb);
+ return ret;
+}
+
+static int ath11k_wmi_tlv_dma_buf_entry_parse(struct ath11k_base *soc,
+ u16 tag, u16 len,
+ const void *ptr, void *data)
+{
+ struct wmi_tlv_dma_buf_release_parse *parse = data;
+
+ if (tag != WMI_TAG_DMA_BUF_RELEASE_ENTRY)
+ return -EPROTO;
+
+ if (parse->num_buf_entry >= parse->fixed.num_buf_release_entry)
+ return -ENOBUFS;
+
+ parse->num_buf_entry++;
+ return 0;
+}
+
+static int ath11k_wmi_tlv_dma_buf_meta_parse(struct ath11k_base *soc,
+ u16 tag, u16 len,
+ const void *ptr, void *data)
+{
+ struct wmi_tlv_dma_buf_release_parse *parse = data;
+
+ if (tag != WMI_TAG_DMA_BUF_RELEASE_SPECTRAL_META_DATA)
+ return -EPROTO;
+
+ if (parse->num_meta >= parse->fixed.num_meta_data_entry)
+ return -ENOBUFS;
+
+ parse->num_meta++;
+ return 0;
+}
+
+static int ath11k_wmi_tlv_dma_buf_parse(struct ath11k_base *ab,
+ u16 tag, u16 len,
+ const void *ptr, void *data)
+{
+ struct wmi_tlv_dma_buf_release_parse *parse = data;
+ int ret;
+
+ switch (tag) {
+ case WMI_TAG_DMA_BUF_RELEASE:
+ memcpy(&parse->fixed, ptr,
+ sizeof(struct ath11k_wmi_dma_buf_release_fixed_param));
+ parse->fixed.pdev_id = DP_HW2SW_MACID(parse->fixed.pdev_id);
+ break;
+ case WMI_TAG_ARRAY_STRUCT:
+ if (!parse->buf_entry_done) {
+ parse->num_buf_entry = 0;
+ parse->buf_entry = (struct wmi_dma_buf_release_entry *)ptr;
+
+ ret = ath11k_wmi_tlv_iter(ab, ptr, len,
+ ath11k_wmi_tlv_dma_buf_entry_parse,
+ parse);
+ if (ret) {
+ ath11k_warn(ab, "failed to parse dma buf entry tlv %d\n",
+ ret);
+ return ret;
+ }
+
+ parse->buf_entry_done = true;
+ } else if (!parse->meta_data_done) {
+ parse->num_meta = 0;
+ parse->meta_data = (struct wmi_dma_buf_release_meta_data *)ptr;
+
+ ret = ath11k_wmi_tlv_iter(ab, ptr, len,
+ ath11k_wmi_tlv_dma_buf_meta_parse,
+ parse);
+ if (ret) {
+ ath11k_warn(ab, "failed to parse dma buf meta tlv %d\n",
+ ret);
+ return ret;
+ }
+
+ parse->meta_data_done = true;
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static void ath11k_wmi_pdev_dma_ring_buf_release_event(struct ath11k_base *ab,
+ struct sk_buff *skb)
+{
+ struct wmi_tlv_dma_buf_release_parse parse = { };
+ struct ath11k_dbring_buf_release_event param;
+ int ret;
+
+ ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
+ ath11k_wmi_tlv_dma_buf_parse,
+ &parse);
+ if (ret) {
+ ath11k_warn(ab, "failed to parse dma buf release tlv %d\n", ret);
+ return;
+ }
+
+ param.fixed = parse.fixed;
+ param.buf_entry = parse.buf_entry;
+ param.num_buf_entry = parse.num_buf_entry;
+ param.meta_data = parse.meta_data;
+ param.num_meta = parse.num_meta;
+
+ ret = ath11k_dbring_buffer_release_event(ab, &param);
+ if (ret) {
+ ath11k_warn(ab, "failed to handle dma buf release event %d\n", ret);
+ return;
+ }
+}
+
static int ath11k_wmi_tlv_hw_mode_caps_parse(struct ath11k_base *soc,
u16 tag, u16 len,
const void *ptr, void *data)
@@ -3445,6 +3808,95 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc,
return 0;
}
+static int ath11k_wmi_tlv_dma_ring_caps_parse(struct ath11k_base *soc,
+ u16 tag, u16 len,
+ const void *ptr, void *data)
+{
+ struct wmi_tlv_dma_ring_caps_parse *parse = data;
+
+ if (tag != WMI_TAG_DMA_RING_CAPABILITIES)
+ return -EPROTO;
+
+ parse->n_dma_ring_caps++;
+ return 0;
+}
+
+static int ath11k_wmi_alloc_dbring_caps(struct ath11k_base *ab,
+ u32 num_cap)
+{
+ size_t sz;
+ void *ptr;
+
+ sz = num_cap * sizeof(struct ath11k_dbring_cap);
+ ptr = kzalloc(sz, GFP_ATOMIC);
+ if (!ptr)
+ return -ENOMEM;
+
+ ab->db_caps = ptr;
+ ab->num_db_cap = num_cap;
+
+ return 0;
+}
+
+static void ath11k_wmi_free_dbring_caps(struct ath11k_base *ab)
+{
+ kfree(ab->db_caps);
+ ab->db_caps = NULL;
+}
+
+static int ath11k_wmi_tlv_dma_ring_caps(struct ath11k_base *ab,
+ u16 len, const void *ptr, void *data)
+{
+ struct wmi_tlv_dma_ring_caps_parse *dma_caps_parse = data;
+ struct wmi_dma_ring_capabilities *dma_caps;
+ struct ath11k_dbring_cap *dir_buff_caps;
+ int ret;
+ u32 i;
+
+ dma_caps_parse->n_dma_ring_caps = 0;
+ dma_caps = (struct wmi_dma_ring_capabilities *)ptr;
+ ret = ath11k_wmi_tlv_iter(ab, ptr, len,
+ ath11k_wmi_tlv_dma_ring_caps_parse,
+ dma_caps_parse);
+ if (ret) {
+ ath11k_warn(ab, "failed to parse dma ring caps tlv %d\n", ret);
+ return ret;
+ }
+
+ if (!dma_caps_parse->n_dma_ring_caps)
+ return 0;
+
+ if (ab->num_db_cap) {
+ ath11k_warn(ab, "Already processed, so ignoring dma ring caps\n");
+ return 0;
+ }
+
+ ret = ath11k_wmi_alloc_dbring_caps(ab, dma_caps_parse->n_dma_ring_caps);
+ if (ret)
+ return ret;
+
+ dir_buff_caps = ab->db_caps;
+ for (i = 0; i < dma_caps_parse->n_dma_ring_caps; i++) {
+ if (dma_caps[i].module_id >= WMI_DIRECT_BUF_MAX) {
+ ath11k_warn(ab, "Invalid module id %d\n", dma_caps[i].module_id);
+ ret = -EINVAL;
+ goto free_dir_buff;
+ }
+
+ dir_buff_caps[i].id = dma_caps[i].module_id;
+ dir_buff_caps[i].pdev_id = DP_HW2SW_MACID(dma_caps[i].pdev_id);
+ dir_buff_caps[i].min_elem = dma_caps[i].min_elem;
+ dir_buff_caps[i].min_buf_sz = dma_caps[i].min_buf_sz;
+ dir_buff_caps[i].min_buf_align = dma_caps[i].min_buf_align;
+ }
+
+ return 0;
+
+free_dir_buff:
+ ath11k_wmi_free_dbring_caps(ab);
+ return ret;
+}
+
static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab,
u16 tag, u16 len,
const void *ptr, void *data)
@@ -3501,7 +3953,19 @@ static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab,
return ret;
svc_rdy_ext->ext_hal_reg_done = true;
- complete(&ab->wmi_ab.service_ready);
+ } else if (!svc_rdy_ext->mac_phy_chainmask_combo_done) {
+ svc_rdy_ext->mac_phy_chainmask_combo_done = true;
+ } else if (!svc_rdy_ext->mac_phy_chainmask_cap_done) {
+ svc_rdy_ext->mac_phy_chainmask_cap_done = true;
+ } else if (!svc_rdy_ext->oem_dma_ring_cap_done) {
+ svc_rdy_ext->oem_dma_ring_cap_done = true;
+ } else if (!svc_rdy_ext->dma_ring_cap_done) {
+ ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr,
+ &svc_rdy_ext->dma_caps_parse);
+ if (ret)
+ return ret;
+
+ svc_rdy_ext->dma_ring_cap_done = true;
}
break;
@@ -3522,11 +3986,66 @@ static int ath11k_service_ready_ext_event(struct ath11k_base *ab,
&svc_rdy_ext);
if (ret) {
ath11k_warn(ab, "failed to parse tlv %d\n", ret);
- return ret;
+ goto err;
}
+ if (!test_bit(WMI_TLV_SERVICE_EXT2_MSG, ab->wmi_ab.svc_map))
+ complete(&ab->wmi_ab.service_ready);
+
kfree(svc_rdy_ext.mac_phy_caps);
return 0;
+
+err:
+ ath11k_wmi_free_dbring_caps(ab);
+ return ret;
+}
+
+static int ath11k_wmi_tlv_svc_rdy_ext2_parse(struct ath11k_base *ab,
+ u16 tag, u16 len,
+ const void *ptr, void *data)
+{
+ struct wmi_tlv_svc_rdy_ext2_parse *parse = data;
+ int ret;
+
+ switch (tag) {
+ case WMI_TAG_ARRAY_STRUCT:
+ if (!parse->dma_ring_cap_done) {
+ ret = ath11k_wmi_tlv_dma_ring_caps(ab, len, ptr,
+ &parse->dma_caps_parse);
+ if (ret)
+ return ret;
+
+ parse->dma_ring_cap_done = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int ath11k_service_ready_ext2_event(struct ath11k_base *ab,
+ struct sk_buff *skb)
+{
+ struct wmi_tlv_svc_rdy_ext2_parse svc_rdy_ext2 = { };
+ int ret;
+
+ ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
+ ath11k_wmi_tlv_svc_rdy_ext2_parse,
+ &svc_rdy_ext2);
+ if (ret) {
+ ath11k_warn(ab, "failed to parse ext2 event tlv %d\n", ret);
+ goto err;
+ }
+
+ complete(&ab->wmi_ab.service_ready);
+
+ return 0;
+
+err:
+ ath11k_wmi_free_dbring_caps(ab);
+ return ret;
}
static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buff *skb,
@@ -3822,6 +4341,7 @@ static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
}
hdr->pdev_id = ev->pdev_id;
+ hdr->chan_freq = ev->chan_freq;
hdr->channel = ev->channel;
hdr->snr = ev->snr;
hdr->rate = ev->rate;
@@ -5193,7 +5713,9 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
if (rx_ev.status & WMI_RX_STATUS_ERR_MIC)
status->flag |= RX_FLAG_MMIC_ERROR;
- if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
+ if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ) {
+ status->band = NL80211_BAND_6GHZ;
+ } else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
status->band = NL80211_BAND_2GHZ;
} else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH11K_MAX_5G_CHAN) {
status->band = NL80211_BAND_5GHZ;
@@ -5206,9 +5728,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
goto exit;
}
- if (rx_ev.phy_mode == MODE_11B && status->band == NL80211_BAND_5GHZ)
+ if (rx_ev.phy_mode == MODE_11B &&
+ (status->band == NL80211_BAND_5GHZ || status->band == NL80211_BAND_6GHZ))
ath11k_dbg(ab, ATH11K_DBG_WMI,
- "wmi mgmt rx 11b (CCK) on 5GHz\n");
+ "wmi mgmt rx 11b (CCK) on 5/6GHz, band = %d\n", status->band);
sband = &ar->mac.sbands[status->band];
@@ -5933,6 +6456,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
case WMI_SERVICE_READY_EXT_EVENTID:
ath11k_service_ready_ext_event(ab, skb);
break;
+ case WMI_SERVICE_READY_EXT2_EVENTID:
+ ath11k_service_ready_ext2_event(ab, skb);
+ break;
case WMI_REG_CHAN_LIST_CC_EVENTID:
ath11k_reg_chan_list_event(ab, skb);
break;
@@ -5994,12 +6520,16 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
case WMI_PDEV_TEMPERATURE_EVENTID:
ath11k_wmi_pdev_temperature_event(ab, skb);
break;
+ case WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID:
+ ath11k_wmi_pdev_dma_ring_buf_release_event(ab, skb);
+ break;
/* add Unsupported events here */
case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
case WMI_VDEV_DELETE_RESP_EVENTID:
case WMI_PEER_OPER_MODE_CHANGE_EVENTID:
case WMI_TWT_ENABLE_EVENTID:
case WMI_TWT_DISABLE_EVENTID:
+ case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID:
ath11k_dbg(ab, ATH11K_DBG_WMI,
"ignoring unsupported event 0x%x\n", id);
break;
@@ -6213,4 +6743,6 @@ void ath11k_wmi_detach(struct ath11k_base *ab)
for (i = 0; i < ab->htc.wmi_ep_count; i++)
ath11k_wmi_pdev_detach(ab, i);
+
+ ath11k_wmi_free_dbring_caps(ab);
}
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index b9f3e559ced7..5a32ba0eb4f5 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -24,6 +24,8 @@ struct ath11k_fw_stats;
#define HE_PET_8_USEC 1
#define HE_PET_16_USEC 2
+#define WMI_MAX_CHAINS 8
+
#define WMI_MAX_NUM_SS MAX_HE_NSS
#define WMI_MAX_NUM_RU MAX_HE_RU
@@ -50,10 +52,20 @@ struct wmi_tlv {
#define WMI_MAX_MEM_REQS 32
#define ATH11K_MAX_HW_LISTEN_INTERVAL 5
+#define WLAN_SCAN_MAX_HINT_S_SSID 10
+#define WLAN_SCAN_MAX_HINT_BSSID 10
+#define MAX_RNR_BSS 5
+
+#define WLAN_SCAN_MAX_HINT_S_SSID 10
+#define WLAN_SCAN_MAX_HINT_BSSID 10
+#define MAX_RNR_BSS 5
+
#define WLAN_SCAN_PARAMS_MAX_SSID 16
#define WLAN_SCAN_PARAMS_MAX_BSSID 4
#define WLAN_SCAN_PARAMS_MAX_IE_LEN 256
+#define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1
+
#define WMI_BA_MODE_BUFFER_SIZE_256 3
/*
* HW mode config type replicated from FW header
@@ -586,6 +598,11 @@ enum wmi_tlv_event_id {
WMI_PDEV_DMA_RING_CFG_RSP_EVENTID,
WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID,
WMI_PDEV_CTL_FAILSAFE_CHECK_EVENTID,
+ WMI_PDEV_CSC_SWITCH_COUNT_STATUS_EVENTID,
+ WMI_PDEV_COLD_BOOT_CAL_DATA_EVENTID,
+ WMI_PDEV_RAP_INFO_EVENTID,
+ WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID,
+ WMI_SERVICE_READY_EXT2_EVENTID,
WMI_VDEV_START_RESP_EVENTID = WMI_TLV_CMD(WMI_GRP_VDEV),
WMI_VDEV_STOPPED_EVENTID,
WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID,
@@ -1011,6 +1028,7 @@ enum wmi_tlv_vdev_param {
WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
WMI_VDEV_PARAM_BA_MODE = 0x7e,
WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87,
+ WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99,
WMI_VDEV_PARAM_PROTOTYPE = 0x8000,
WMI_VDEV_PARAM_BSS_COLOR,
WMI_VDEV_PARAM_SET_HEMU_MODE,
@@ -2013,9 +2031,10 @@ enum wmi_tlv_service {
WMI_TLV_SERVICE_DSM_ROAM_FILTER = 211,
WMI_TLV_SERVICE_PACKET_CAPTURE_SUPPORT = 212,
WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET = 213,
+ WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219,
+ WMI_TLV_SERVICE_EXT2_MSG = 220,
WMI_MAX_EXT_SERVICE
-
};
enum {
@@ -2076,6 +2095,14 @@ enum wmi_beacon_gen_mode {
WMI_BEACON_BURST_MODE = 1
};
+enum wmi_direct_buffer_module {
+ WMI_DIRECT_BUF_SPECTRAL = 0,
+ WMI_DIRECT_BUF_CFR = 1,
+
+ /* keep it last */
+ WMI_DIRECT_BUF_MAX
+};
+
struct wmi_host_pdev_band_to_mac {
u32 pdev_id;
u32 start_freq;
@@ -2382,6 +2409,15 @@ struct wmi_mac_addr {
} __packed;
} __packed;
+struct wmi_dma_ring_capabilities {
+ u32 tlv_header;
+ u32 pdev_id;
+ u32 module_id;
+ u32 min_elem;
+ u32 min_buf_sz;
+ u32 min_buf_align;
+} __packed;
+
struct wmi_ready_event_min {
struct wmi_abi_version fw_abi_vers;
struct wmi_mac_addr mac_addr;
@@ -2519,7 +2555,8 @@ struct channel_param {
allow_ht:1,
allow_vht:1,
allow_he:1,
- set_agile:1;
+ set_agile:1,
+ psc_channel:1;
u32 phy_mode;
u32 cfreq1;
u32 cfreq2;
@@ -3059,6 +3096,9 @@ struct wmi_start_scan_cmd {
u32 num_vendor_oui;
u32 scan_ctrl_flags_ext;
u32 dwell_time_active_2g;
+ u32 dwell_time_active_6g;
+ u32 dwell_time_passive_6g;
+ u32 scan_start_offset;
} __packed;
#define WMI_SCAN_FLAG_PASSIVE 0x1
@@ -3098,6 +3138,16 @@ enum {
((flag) |= (((mode) << WMI_SCAN_DWELL_MODE_SHIFT) & \
WMI_SCAN_DWELL_MODE_MASK))
+struct hint_short_ssid {
+ u32 freq_flags;
+ u32 short_ssid;
+};
+
+struct hint_bssid {
+ u32 freq_flags;
+ struct wmi_mac_addr bssid;
+};
+
struct scan_req_params {
u32 scan_id;
u32 scan_req_id;
@@ -3125,6 +3175,8 @@ struct scan_req_params {
u32 dwell_time_active;
u32 dwell_time_active_2g;
u32 dwell_time_passive;
+ u32 dwell_time_active_6g;
+ u32 dwell_time_passive_6g;
u32 min_rest_time;
u32 max_rest_time;
u32 repeat_probe_time;
@@ -3175,6 +3227,10 @@ struct scan_req_params {
struct element_info extraie;
struct element_info htcap;
struct element_info vhtcap;
+ u32 num_hint_s_ssid;
+ u32 num_hint_bssid;
+ struct hint_short_ssid hint_s_ssid[WLAN_SCAN_MAX_HINT_S_SSID];
+ struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID];
};
struct wmi_ssid_arg {
@@ -3264,6 +3320,7 @@ struct wmi_bcn_send_from_host_cmd {
#define WMI_CHAN_INFO_QUARTER_RATE BIT(15)
#define WMI_CHAN_INFO_DFS_FREQ2 BIT(16)
#define WMI_CHAN_INFO_ALLOW_HE BIT(17)
+#define WMI_CHAN_INFO_PSC BIT(18)
#define WMI_CHAN_REG_INFO1_MIN_PWR GENMASK(7, 0)
#define WMI_CHAN_REG_INFO1_MAX_PWR GENMASK(15, 8)
@@ -3444,6 +3501,7 @@ struct peer_assoc_params {
u32 tx_max_rate;
u32 tx_mcs_set;
u8 vht_capable;
+ u8 min_data_rate;
u32 tx_max_mcs_nss;
u32 peer_bw_rxnss_override;
bool is_pmf_enabled;
@@ -3472,6 +3530,7 @@ struct peer_assoc_params {
bool he_flag;
u32 peer_he_cap_macinfo[2];
u32 peer_he_cap_macinfo_internal;
+ u32 peer_he_caps_6ghz;
u32 peer_he_ops;
u32 peer_he_cap_phyinfo[WMI_HOST_MAX_HECAP_PHY_SIZE];
u32 peer_he_mcs_count;
@@ -3509,6 +3568,8 @@ struct wmi_peer_assoc_complete_cmd {
u32 peer_he_mcs;
u32 peer_he_cap_info_ext;
u32 peer_he_cap_info_internal;
+ u32 min_data_rate;
+ u32 peer_he_caps_6ghz;
} __packed;
struct wmi_stop_scan_cmd {
@@ -4228,6 +4289,7 @@ struct wmi_pdev_temperature_event {
#define WLAN_MGMT_TXRX_HOST_MAX_ANTENNA 4
struct mgmt_rx_event_params {
+ u32 chan_freq;
u32 channel;
u32 snr;
u8 rssi_ctl[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
@@ -4257,6 +4319,7 @@ struct wmi_mgmt_rx_hdr {
u32 rx_tsf_l32;
u32 rx_tsf_u32;
u32 pdev_id;
+ u32 chan_freq;
} __packed;
#define MAX_ANTENNA_EIGHT 8
@@ -4734,6 +4797,117 @@ struct ath11k_wmi_pdev_lro_config_cmd {
u32 pdev_id;
} __packed;
+#define ATH11K_WMI_SPECTRAL_COUNT_DEFAULT 0
+#define ATH11K_WMI_SPECTRAL_PERIOD_DEFAULT 224
+#define ATH11K_WMI_SPECTRAL_PRIORITY_DEFAULT 1
+#define ATH11K_WMI_SPECTRAL_FFT_SIZE_DEFAULT 7
+#define ATH11K_WMI_SPECTRAL_GC_ENA_DEFAULT 1
+#define ATH11K_WMI_SPECTRAL_RESTART_ENA_DEFAULT 0
+#define ATH11K_WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT -96
+#define ATH11K_WMI_SPECTRAL_INIT_DELAY_DEFAULT 80
+#define ATH11K_WMI_SPECTRAL_NB_TONE_THR_DEFAULT 12
+#define ATH11K_WMI_SPECTRAL_STR_BIN_THR_DEFAULT 8
+#define ATH11K_WMI_SPECTRAL_WB_RPT_MODE_DEFAULT 0
+#define ATH11K_WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT 0
+#define ATH11K_WMI_SPECTRAL_RSSI_THR_DEFAULT 0xf0
+#define ATH11K_WMI_SPECTRAL_PWR_FORMAT_DEFAULT 0
+#define ATH11K_WMI_SPECTRAL_RPT_MODE_DEFAULT 2
+#define ATH11K_WMI_SPECTRAL_BIN_SCALE_DEFAULT 1
+#define ATH11K_WMI_SPECTRAL_DBM_ADJ_DEFAULT 1
+#define ATH11K_WMI_SPECTRAL_CHN_MASK_DEFAULT 1
+
+struct ath11k_wmi_vdev_spectral_conf_param {
+ u32 vdev_id;
+ u32 scan_count;
+ u32 scan_period;
+ u32 scan_priority;
+ u32 scan_fft_size;
+ u32 scan_gc_ena;
+ u32 scan_restart_ena;
+ u32 scan_noise_floor_ref;
+ u32 scan_init_delay;
+ u32 scan_nb_tone_thr;
+ u32 scan_str_bin_thr;
+ u32 scan_wb_rpt_mode;
+ u32 scan_rssi_rpt_mode;
+ u32 scan_rssi_thr;
+ u32 scan_pwr_format;
+ u32 scan_rpt_mode;
+ u32 scan_bin_scale;
+ u32 scan_dbm_adj;
+ u32 scan_chn_mask;
+} __packed;
+
+struct ath11k_wmi_vdev_spectral_conf_cmd {
+ u32 tlv_header;
+ struct ath11k_wmi_vdev_spectral_conf_param param;
+} __packed;
+
+#define ATH11K_WMI_SPECTRAL_TRIGGER_CMD_TRIGGER 1
+#define ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR 2
+#define ATH11K_WMI_SPECTRAL_ENABLE_CMD_ENABLE 1
+#define ATH11K_WMI_SPECTRAL_ENABLE_CMD_DISABLE 2
+
+struct ath11k_wmi_vdev_spectral_enable_cmd {
+ u32 tlv_header;
+ u32 vdev_id;
+ u32 trigger_cmd;
+ u32 enable_cmd;
+} __packed;
+
+struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd {
+ u32 tlv_header;
+ u32 pdev_id;
+ u32 module_id; /* see enum wmi_direct_buffer_module */
+ u32 base_paddr_lo;
+ u32 base_paddr_hi;
+ u32 head_idx_paddr_lo;
+ u32 head_idx_paddr_hi;
+ u32 tail_idx_paddr_lo;
+ u32 tail_idx_paddr_hi;
+ u32 num_elems; /* Number of elems in the ring */
+ u32 buf_size; /* size of allocated buffer in bytes */
+
+ /* Number of wmi_dma_buf_release_entry packed together */
+ u32 num_resp_per_event;
+
+ /* Target should timeout and send whatever resp
+ * it has if this time expires, units in milliseconds
+ */
+ u32 event_timeout_ms;
+} __packed;
+
+struct ath11k_wmi_dma_buf_release_fixed_param {
+ u32 pdev_id;
+ u32 module_id;
+ u32 num_buf_release_entry;
+ u32 num_meta_data_entry;
+} __packed;
+
+struct wmi_dma_buf_release_entry {
+ u32 tlv_header;
+ u32 paddr_lo;
+
+ /* Bits 11:0: address of data
+ * Bits 31:12: host context data
+ */
+ u32 paddr_hi;
+} __packed;
+
+#define WMI_SPECTRAL_META_INFO1_FREQ1 GENMASK(15, 0)
+#define WMI_SPECTRAL_META_INFO1_FREQ2 GENMASK(31, 16)
+
+#define WMI_SPECTRAL_META_INFO2_CHN_WIDTH GENMASK(7, 0)
+
+struct wmi_dma_buf_release_meta_data {
+ u32 tlv_header;
+ s32 noise_floor[WMI_MAX_CHAINS];
+ u32 reset_delay;
+ u32 freq1;
+ u32 freq2;
+ u32 ch_width;
+} __packed;
+
struct target_resource_config {
u32 num_vdevs;
u32 num_peers;
@@ -4941,4 +5115,10 @@ int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id,
int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id,
bool enable);
int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar, int pdev_id);
+int ath11k_wmi_pdev_dma_ring_cfg(struct ath11k *ar,
+ struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd *param);
+int ath11k_wmi_vdev_spectral_enable(struct ath11k *ar, u32 vdev_id,
+ u32 trigger, u32 enable);
+int ath11k_wmi_vdev_spectral_conf(struct ath11k *ar,
+ struct ath11k_wmi_vdev_spectral_conf_param *param);
#endif
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 53b66e9434c9..5372e948e761 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -311,7 +311,7 @@ static int ath6kl_usb_setup_pipe_resources(struct ath6kl_usb *ar_usb)
ath6kl_dbg(ATH6KL_DBG_USB, "setting up USB Pipes using interface\n");
- /* walk decriptors and setup pipes */
+ /* walk descriptors and setup pipes */
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 42bfdb4a6214..d5e9af2dddd8 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -34,7 +34,7 @@ config ATH9K
APs that come with these cards refer to ath9k wiki
products page:
- http://wireless.kernel.org/en/users/Drivers/ath9k/products
+ https://wireless.wiki.kernel.org/en/users/Drivers/ath9k/products
If you choose to build a module, it'll be called ath9k.
@@ -185,7 +185,8 @@ config ATH9K_HTC
Support for Atheros HTC based cards.
Chipsets supported: AR9271
- For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc
+ For more information:
+ https://wireless.wiki.kernel.org/en/users/Drivers/ath9k_htc
The built module will be ath9k_htc.
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 052deffb4c9d..8c97db73e34c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2410,7 +2410,7 @@ static u8 fixup_chainmask(u8 chip_chainmask, u8 eeprom_chainmask)
* of tests. The testing requirements are going to be documented. Desired
* test requirements are documented at:
*
- * http://wireless.kernel.org/en/users/Drivers/ath9k/dfs
+ * https://wireless.wiki.kernel.org/en/users/Drivers/ath9k/dfs
*
* Once a new chipset gets properly tested an individual commit can be used
* to document the testing for DFS for that chipset.
diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig
index b1bce7aad399..b2d760873992 100644
--- a/drivers/net/wireless/ath/carl9170/Kconfig
+++ b/drivers/net/wireless/ath/carl9170/Kconfig
@@ -10,7 +10,7 @@ config CARL9170
It needs a special firmware (carl9170-1.fw), which can be downloaded
from our wiki here:
- <http://wireless.kernel.org/en/users/Drivers/carl9170>
+ <https://wireless.wiki.kernel.org/en/users/Drivers/carl9170>
If you choose to build a module, it'll be called carl9170.
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 486957a04bd1..ead79335823a 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -61,7 +61,7 @@ MODULE_ALIAS("arusb_lnx");
* Note:
*
* Always update our wiki's device list (located at:
- * http://wireless.kernel.org/en/users/Drivers/ar9170/devices ),
+ * https://wireless.wiki.kernel.org/en/users/Drivers/ar9170/devices ),
* whenever you add a new device.
*/
static const struct usb_device_id carl9170_usb_ids[] = {
diff --git a/drivers/net/wireless/ath/spectral_common.h b/drivers/net/wireless/ath/spectral_common.h
index 0d742acb1599..9c2e5458e425 100644
--- a/drivers/net/wireless/ath/spectral_common.h
+++ b/drivers/net/wireless/ath/spectral_common.h
@@ -24,6 +24,7 @@
* could be acquired so far.
*/
#define SPECTRAL_ATH10K_MAX_NUM_BINS 256
+#define SPECTRAL_ATH11K_MAX_NUM_BINS 512
/* FFT sample format given to userspace via debugfs.
*
@@ -37,6 +38,7 @@ enum ath_fft_sample_type {
ATH_FFT_SAMPLE_HT20 = 1,
ATH_FFT_SAMPLE_HT20_40,
ATH_FFT_SAMPLE_ATH10K,
+ ATH_FFT_SAMPLE_ATH11K
};
struct fft_sample_tlv {
@@ -110,4 +112,19 @@ struct fft_sample_ath10k {
u8 data[0];
} __packed;
+struct fft_sample_ath11k {
+ struct fft_sample_tlv tlv;
+ u8 chan_width_mhz;
+ s8 max_index;
+ u8 max_exp;
+ __be16 freq1;
+ __be16 freq2;
+ __be16 max_magnitude;
+ __be16 rssi;
+ __be32 tsf;
+ __be32 noise;
+
+ u8 data[0];
+} __packed;
+
#endif /* SPECTRAL_COMMON_H */
diff --git a/drivers/net/wireless/ath/wil6210/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig
index dadba2d41bbb..6a95b199bf62 100644
--- a/drivers/net/wireless/ath/wil6210/Kconfig
+++ b/drivers/net/wireless/ath/wil6210/Kconfig
@@ -10,7 +10,7 @@ config WIL6210
wil6210 chip by Wilocity. It supports operation on the
60 GHz band, covered by the IEEE802.11ad standard.
- http://wireless.kernel.org/en/users/Drivers/wil6210
+ https://wireless.wiki.kernel.org/en/users/Drivers/wil6210
If you choose to build it as a module, it will be called
wil6210
diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c b/drivers/net/wireless/atmel/at76c50x-usb.c
index 3b2680772f03..a63b5c2f1e17 100644
--- a/drivers/net/wireless/atmel/at76c50x-usb.c
+++ b/drivers/net/wireless/atmel/at76c50x-usb.c
@@ -17,7 +17,7 @@
*
* TODO list is at the wiki:
*
- * http://wireless.kernel.org/en/users/Drivers/at76c50x-usb#TODO
+ * https://wireless.wiki.kernel.org/en/users/Drivers/at76c50x-usb#TODO
*/
#include <linux/init.h>
diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c
index 3ad94dad2d89..a54dd4f7fa54 100644
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -734,7 +734,7 @@ static void b43_short_slot_timing_disable(struct b43_wldev *dev)
}
/* DummyTransmission function, as documented on
- * http://bcm-v4.sipsolutions.net/802.11/DummyTransmission
+ * https://bcm-v4.sipsolutions.net/802.11/DummyTransmission
*/
void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
{
@@ -1198,7 +1198,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/BmacCorePllReset */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/BmacCorePllReset */
void b43_wireless_core_phy_pll_reset(struct b43_wldev *dev)
{
struct bcma_drv_cc *bcma_cc __maybe_unused;
@@ -2164,7 +2164,7 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
{
const char text[] =
"You must go to " \
- "http://wireless.kernel.org/en/users/Drivers/b43#devicefirmware " \
+ "https://wireless.wiki.kernel.org/en/users/Drivers/b43#devicefirmware " \
"and download the correct firmware for this driver version. " \
"Please carefully read all instructions on this website.\n";
@@ -2290,7 +2290,7 @@ err_format:
return -EPROTO;
}
-/* http://bcm-v4.sipsolutions.net/802.11/Init/Firmware */
+/* https://bcm-v4.sipsolutions.net/802.11/Init/Firmware */
static int b43_try_request_fw(struct b43_request_fw_context *ctx)
{
struct b43_wldev *dev = ctx->dev;
@@ -2843,7 +2843,7 @@ static int b43_upload_initvals_band(struct b43_wldev *dev)
}
/* Initialize the GPIOs
- * http://bcm-specs.sipsolutions.net/GPIO
+ * https://bcm-specs.sipsolutions.net/GPIO
*/
#ifdef CONFIG_B43_SSB
@@ -2971,7 +2971,7 @@ void b43_mac_enable(struct b43_wldev *dev)
}
}
-/* http://bcm-specs.sipsolutions.net/SuspendMAC */
+/* https://bcm-specs.sipsolutions.net/SuspendMAC */
void b43_mac_suspend(struct b43_wldev *dev)
{
int i;
@@ -3004,7 +3004,7 @@ out:
dev->mac_suspended++;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
{
u32 tmp;
@@ -3231,7 +3231,7 @@ static void b43_chip_exit(struct b43_wldev *dev)
}
/* Initialize the chip
- * http://bcm-specs.sipsolutions.net/ChipInit
+ * https://bcm-specs.sipsolutions.net/ChipInit
*/
static int b43_chip_init(struct b43_wldev *dev)
{
diff --git a/drivers/net/wireless/broadcom/b43/phy_common.c b/drivers/net/wireless/broadcom/b43/phy_common.c
index 923d4cb9fc30..1de4de094d61 100644
--- a/drivers/net/wireless/broadcom/b43/phy_common.c
+++ b/drivers/net/wireless/broadcom/b43/phy_common.c
@@ -559,7 +559,7 @@ bool b43_is_40mhz(struct b43_wldev *dev)
return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
void b43_phy_force_clock(struct b43_wldev *dev, bool force)
{
u32 tmp;
diff --git a/drivers/net/wireless/broadcom/b43/phy_g.c b/drivers/net/wireless/broadcom/b43/phy_g.c
index 1e022ec733a3..d5a1a5c58236 100644
--- a/drivers/net/wireless/broadcom/b43/phy_g.c
+++ b/drivers/net/wireless/broadcom/b43/phy_g.c
@@ -357,14 +357,14 @@ static void b43_set_original_gains(struct b43_wldev *dev)
b43_dummy_transmission(dev, false, true);
}
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
+/* https://bcm-specs.sipsolutions.net/NRSSILookupTable */
static void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val)
{
b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset);
b43_phy_write(dev, B43_PHY_NRSSILT_DATA, (u16) val);
}
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
+/* https://bcm-specs.sipsolutions.net/NRSSILookupTable */
static s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset)
{
u16 val;
@@ -375,7 +375,7 @@ static s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset)
return (s16) val;
}
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
+/* https://bcm-specs.sipsolutions.net/NRSSILookupTable */
static void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val)
{
u16 i;
@@ -389,7 +389,7 @@ static void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val)
}
}
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
+/* https://bcm-specs.sipsolutions.net/NRSSILookupTable */
static void b43_nrssi_mem_update(struct b43_wldev *dev)
{
struct b43_phy_g *gphy = dev->phy.g;
@@ -1575,7 +1575,7 @@ static void b43_phy_initb5(struct b43_wldev *dev)
b43_write16(dev, 0x03E4, (b43_read16(dev, 0x03E4) & 0xFFC0) | 0x0004);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/B6 */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/Init/B6 */
static void b43_phy_initb6(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -2746,7 +2746,7 @@ static int b43_gphy_op_interf_mitigation(struct b43_wldev *dev,
return 0;
}
-/* http://bcm-specs.sipsolutions.net/EstimatePowerOut
+/* https://bcm-specs.sipsolutions.net/EstimatePowerOut
* This function converts a TSSI value to dBm in Q5.2
*/
static s8 b43_gphy_estimate_power_out(struct b43_wldev *dev, s8 tssi)
diff --git a/drivers/net/wireless/broadcom/b43/phy_ht.c b/drivers/net/wireless/broadcom/b43/phy_ht.c
index 6033df1c3053..c685b4bb5ed6 100644
--- a/drivers/net/wireless/broadcom/b43/phy_ht.c
+++ b/drivers/net/wireless/broadcom/b43/phy_ht.c
@@ -1018,7 +1018,7 @@ static void b43_phy_ht_op_free(struct b43_wldev *dev)
phy->ht = NULL;
}
-/* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */
+/* https://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */
static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
bool blocked)
{
diff --git a/drivers/net/wireless/broadcom/b43/phy_lp.c b/drivers/net/wireless/broadcom/b43/phy_lp.c
index cfb953d61dc5..0e5c076e7544 100644
--- a/drivers/net/wireless/broadcom/b43/phy_lp.c
+++ b/drivers/net/wireless/broadcom/b43/phy_lp.c
@@ -70,7 +70,7 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
dev->phy.lp = NULL;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */
static void lpphy_read_band_sprom(struct b43_wldev *dev)
{
struct ssb_sprom *sprom = dev->dev->bus_sprom;
diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c
index 39de18d3ce91..ca2018da9753 100644
--- a/drivers/net/wireless/broadcom/b43/phy_n.c
+++ b/drivers/net/wireless/broadcom/b43/phy_n.c
@@ -98,7 +98,7 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev)
(dev->phy.n->ipa5g_on && band == NL80211_BAND_5GHZ));
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreGetState */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreGetState */
static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev)
{
return (b43_phy_read(dev, B43_NPHY_RFSEQCA) & B43_NPHY_RFSEQCA_RXEN) >>
@@ -109,7 +109,7 @@ static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev)
* RF (just without b43_nphy_rf_ctl_intc_override)
**************************************************/
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */
static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
enum b43_nphy_rf_sequence seq)
{
@@ -146,7 +146,7 @@ static void b43_nphy_rf_ctl_override_rev19(struct b43_wldev *dev, u16 field,
/* TODO */
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
u16 value, u8 core, bool off,
u8 override)
@@ -193,7 +193,7 @@ static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverideOneToMany */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverideOneToMany */
static void b43_nphy_rf_ctl_override_one_to_many(struct b43_wldev *dev,
enum n_rf_ctl_over_cmd cmd,
u16 value, u8 core, bool off)
@@ -237,7 +237,7 @@ static void b43_nphy_rf_ctl_override_one_to_many(struct b43_wldev *dev,
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field,
u16 value, u8 core, bool off)
{
@@ -382,7 +382,7 @@ static void b43_nphy_rf_ctl_intc_override_rev7(struct b43_wldev *dev,
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */
static void b43_nphy_rf_ctl_intc_override(struct b43_wldev *dev,
enum n_intc_override intc_override,
u16 value, u8 core)
@@ -490,7 +490,7 @@ static void b43_nphy_rf_ctl_intc_override(struct b43_wldev *dev,
* Various PHY ops
**************************************************/
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
static void b43_nphy_write_clip_detection(struct b43_wldev *dev,
const u16 *clip_st)
{
@@ -498,14 +498,14 @@ static void b43_nphy_write_clip_detection(struct b43_wldev *dev,
b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
{
clip_st[0] = b43_phy_read(dev, B43_NPHY_C1_CLIP1THRES);
clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */
static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
{
u16 tmp;
@@ -526,7 +526,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
return tmp;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
static void b43_nphy_reset_cca(struct b43_wldev *dev)
{
u16 bbcfg;
@@ -540,7 +540,7 @@ static void b43_nphy_reset_cca(struct b43_wldev *dev)
b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/carriersearch */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/carriersearch */
static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
{
struct b43_phy *phy = &dev->phy;
@@ -564,7 +564,7 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
}
}
-/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
+/* https://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
{
if (!offset)
@@ -572,7 +572,7 @@ static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
@@ -628,7 +628,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
b43_nphy_stay_in_carrier_search(dev, 0);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */
static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
u8 *events, u8 *delays, u8 length)
{
@@ -805,7 +805,7 @@ static void b43_radio_2057_setup(struct b43_wldev *dev,
}
/* Calibrate resistors in LPF of PLL?
- * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
+ * https://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
*/
static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
{
@@ -919,7 +919,7 @@ static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
}
/* Calibrate the internal RC oscillator?
- * http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
+ * https://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
*/
static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
{
@@ -1030,7 +1030,7 @@ static void b43_radio_2057_init_post(struct b43_wldev *dev)
b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
}
-/* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
+/* https://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
static void b43_radio_2057_init(struct b43_wldev *dev)
{
b43_radio_2057_init_pre(dev);
@@ -1117,7 +1117,7 @@ static void b43_chantab_radio_2056_upload(struct b43_wldev *dev,
e->radio_tx1_mixg_boost_tune);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2056Setup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2056Setup */
static void b43_radio_2056_setup(struct b43_wldev *dev,
const struct b43_nphy_channeltab_entry_rev3 *e)
{
@@ -1356,7 +1356,7 @@ static void b43_radio_init2056_post(struct b43_wldev *dev)
/*
* Initialize a Broadcom 2056 N-radio
- * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init
+ * https://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init
*/
static void b43_radio_init2056(struct b43_wldev *dev)
{
@@ -1406,7 +1406,7 @@ static void b43_chantab_radio_upload(struct b43_wldev *dev,
b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */
static void b43_radio_2055_setup(struct b43_wldev *dev,
const struct b43_nphy_channeltab_entry_rev2 *e)
{
@@ -1480,7 +1480,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
/*
* Initialize a Broadcom 2055 N-radio
- * http://bcm-v4.sipsolutions.net/802.11/Radio/2055/Init
+ * https://bcm-v4.sipsolutions.net/802.11/Radio/2055/Init
*/
static void b43_radio_init2055(struct b43_wldev *dev)
{
@@ -1499,7 +1499,7 @@ static void b43_radio_init2055(struct b43_wldev *dev)
* Samples
**************************************************/
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */
static int b43_nphy_load_samples(struct b43_wldev *dev,
struct cordic_iq *samples, u16 len) {
struct b43_phy_n *nphy = dev->phy.n;
@@ -1526,7 +1526,7 @@ static int b43_nphy_load_samples(struct b43_wldev *dev,
return 0;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */
static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
bool test)
{
@@ -1569,7 +1569,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
return (i < 0) ? 0 : len;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
u16 wait, bool iqmode, bool dac_test,
bool modify_bbmult)
@@ -1650,7 +1650,7 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
* RSSI
**************************************************/
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
s8 offset, u8 core,
enum n_rail_type rail,
@@ -1895,7 +1895,7 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code,
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */
static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code,
enum n_rssi_type type)
{
@@ -1907,7 +1907,7 @@ static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code,
b43_nphy_rev2_rssi_select(dev, code, type);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev,
enum n_rssi_type rssi_type, u8 *buf)
{
@@ -1936,7 +1936,7 @@ static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev,
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
static int b43_nphy_poll_rssi(struct b43_wldev *dev, enum n_rssi_type rssi_type,
s32 *buf, u8 nsamp)
{
@@ -2025,7 +2025,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, enum n_rssi_type rssi_type,
return out;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -2287,7 +2287,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
b43_nphy_write_clip_detection(dev, clip_state);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, enum n_rssi_type type)
{
int i, j, vcm;
@@ -2453,7 +2453,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, enum n_rssi_type type)
/*
* RSSI Calibration
- * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
+ * https://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
*/
static void b43_nphy_rssi_cal(struct b43_wldev *dev)
{
@@ -2680,7 +2680,7 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
b43_phy_maskset(dev, B43_PHY_N(0xC5D), 0xFF80, 4);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev)
{
if (dev->phy.rev >= 19)
@@ -3433,7 +3433,7 @@ static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev)
B43_NPHY_FINERX2_CGC_DECGC);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
static void b43_nphy_workarounds(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -3468,7 +3468,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
/*
* Transmits a known value for LO calibration
- * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
+ * https://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
*/
static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
bool iqmode, bool dac_test, bool modify_bbmult)
@@ -3481,7 +3481,7 @@ static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
return 0;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */
static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
@@ -3509,7 +3509,7 @@ static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
~B43_NPHY_RFSEQMODE_CAOVER);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
static void b43_nphy_stop_playback(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -3546,7 +3546,7 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev)
b43_nphy_stay_in_carrier_search(dev, 0);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */
static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
struct nphy_txgains target,
struct nphy_iqcal_params *params)
@@ -3595,7 +3595,7 @@ static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
* Tx and Rx
**************************************************/
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
{
struct b43_phy *phy = &dev->phy;
@@ -3732,7 +3732,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
b43_nphy_stay_in_carrier_search(dev, 0);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -3926,7 +3926,7 @@ static void b43_nphy_ipa_internal_tssi_setup(struct b43_wldev *dev)
/*
* Stop radio and transmit known signal. Then check received signal strength to
* get TSSI (Transmit Signal Strength Indicator).
- * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlIdleTssi
+ * https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlIdleTssi
*/
static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
{
@@ -3978,7 +3978,7 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF;
}
-/* http://bcm-v4.sipsolutions.net/PHY/N/TxPwrLimitToTbl */
+/* https://bcm-v4.sipsolutions.net/PHY/N/TxPwrLimitToTbl */
static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
@@ -4039,7 +4039,7 @@ static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -4272,7 +4272,7 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */
static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
{
struct b43_phy_n *nphy = dev->phy.n;
@@ -4310,7 +4310,7 @@ static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
/*
* TX low-pass filter bandwidth setup
- * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
+ * https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
*/
static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
{
@@ -4333,7 +4333,7 @@ static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */
static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est,
u16 samps, u8 time, bool wait)
{
@@ -4372,7 +4372,7 @@ static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est,
memset(est, 0, sizeof(*est));
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqCoeffs */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqCoeffs */
static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
struct b43_phy_n_iq_comp *pcomp)
{
@@ -4391,7 +4391,7 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
#if 0
/* Ready but not used anywhere */
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
{
u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
@@ -4414,7 +4414,7 @@ static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */
static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
{
u8 rxval, txval;
@@ -4476,7 +4476,7 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
}
#endif
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
{
int i;
@@ -4574,7 +4574,7 @@ static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
b43_nphy_rx_iq_coeffs(dev, true, &new);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxIqWar */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxIqWar */
static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
{
u16 array[4];
@@ -4586,7 +4586,7 @@ static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */
static void b43_nphy_spur_workaround(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
@@ -4645,7 +4645,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
b43_nphy_stay_in_carrier_search(dev, 0);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */
static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
@@ -4713,7 +4713,7 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
/*
* Restore RSSI Calibration
- * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal
+ * https://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal
*/
static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
{
@@ -4822,7 +4822,7 @@ static void b43_nphy_tx_cal_radio_setup_rev7(struct b43_wldev *dev)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -4921,7 +4921,7 @@ static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */
static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core)
{
struct b43_phy_n *nphy = dev->phy.n;
@@ -4955,14 +4955,14 @@ static void b43_nphy_pa_set_tx_dig_filter(struct b43_wldev *dev, u16 offset,
b43_phy_write(dev, offset, filter[i]);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
{
b43_nphy_pa_set_tx_dig_filter(dev, 0x2C5,
tbl_tx_filter_coef_rev4[2]);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
{
/* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
@@ -5002,7 +5002,7 @@ static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
@@ -5077,7 +5077,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
return target;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */
static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev)
{
u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
@@ -5106,7 +5106,7 @@ static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -5207,7 +5207,7 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
static void b43_nphy_save_cal(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -5278,7 +5278,7 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
b43_nphy_stay_in_carrier_search(dev, 0);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
static void b43_nphy_restore_cal(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -5366,7 +5366,7 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
b43_nphy_rx_iq_coeffs(dev, true, rxcal_coeffs);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalTxIqlo */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/CalTxIqlo */
static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
struct nphy_txgains target,
bool full, bool mphase)
@@ -5599,7 +5599,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
return error;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ReapplyTxCalCoeffs */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/ReapplyTxCalCoeffs */
static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
@@ -5634,7 +5634,7 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */
static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
struct nphy_txgains target, u8 type, bool debug)
{
@@ -5821,7 +5821,7 @@ static int b43_nphy_rev3_cal_rx_iq(struct b43_wldev *dev,
return -1;
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIq */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIq */
static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
struct nphy_txgains target, u8 type, bool debug)
{
@@ -5834,7 +5834,7 @@ static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */
static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
{
struct b43_phy *phy = &dev->phy;
@@ -5939,7 +5939,7 @@ static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
* N-PHY init
**************************************************/
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */
static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble)
{
u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG);
@@ -5953,7 +5953,7 @@ static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble)
b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BPHYInit */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/BPHYInit */
static void b43_nphy_bphy_init(struct b43_wldev *dev)
{
unsigned int i;
@@ -5972,7 +5972,7 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
{
if (dev->phy.rev >= 7)
@@ -6246,7 +6246,7 @@ static void b43_chantab_phy_upload(struct b43_wldev *dev,
b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */
+/* https://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */
static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
{
switch (dev->dev->bus_type) {
@@ -6265,7 +6265,7 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
static void b43_nphy_channel_setup(struct b43_wldev *dev,
const struct b43_phy_n_sfo_cfg *e,
struct ieee80211_channel *new_channel)
@@ -6372,7 +6372,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
b43_nphy_spur_workaround(dev);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
static int b43_nphy_set_channel(struct b43_wldev *dev,
struct ieee80211_channel *channel,
enum nl80211_channel_type channel_type)
@@ -6589,7 +6589,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
}
-/* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */
+/* https://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */
static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
bool blocked)
{
@@ -6643,7 +6643,7 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
{
struct b43_phy *phy = &dev->phy;
diff --git a/drivers/net/wireless/broadcom/b43/radio_2056.c b/drivers/net/wireless/broadcom/b43/radio_2056.c
index 575c696b7cdf..94f5e626acba 100644
--- a/drivers/net/wireless/broadcom/b43/radio_2056.c
+++ b/drivers/net/wireless/broadcom/b43/radio_2056.c
@@ -3072,7 +3072,7 @@ INITTABSPTS(b2056_inittab_radio_rev11);
.phy_regs.phy_bw5 = r4, \
.phy_regs.phy_bw6 = r5
-/* http://bcm-v4.sipsolutions.net/802.11/Radio/2056/ChannelTable */
+/* https://bcm-v4.sipsolutions.net/802.11/Radio/2056/ChannelTable */
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_phy_rev3[] = {
{ .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
diff --git a/drivers/net/wireless/broadcom/b43/tables_nphy.c b/drivers/net/wireless/broadcom/b43/tables_nphy.c
index dad405abf9b1..7957db94e84c 100644
--- a/drivers/net/wireless/broadcom/b43/tables_nphy.c
+++ b/drivers/net/wireless/broadcom/b43/tables_nphy.c
@@ -3620,7 +3620,7 @@ static void b43_nphy_tables_init_rev0(struct b43_wldev *dev)
ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
void b43_nphy_tables_init(struct b43_wldev *dev)
{
if (dev->phy.rev >= 16)
@@ -3633,7 +3633,7 @@ void b43_nphy_tables_init(struct b43_wldev *dev)
b43_nphy_tables_init_rev0(dev);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
+/* https://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c
index 220c11d34c23..2eaf481f03f1 100644
--- a/drivers/net/wireless/broadcom/b43legacy/main.c
+++ b/drivers/net/wireless/broadcom/b43legacy/main.c
@@ -591,7 +591,7 @@ static void b43legacy_synchronize_irq(struct b43legacy_wldev *dev)
}
/* DummyTransmission function, as documented on
- * http://bcm-specs.sipsolutions.net/DummyTransmission
+ * https://bcm-specs.sipsolutions.net/DummyTransmission
*/
void b43legacy_dummy_transmission(struct b43legacy_wldev *dev)
{
@@ -1477,8 +1477,8 @@ static void b43legacy_release_firmware(struct b43legacy_wldev *dev)
static void b43legacy_print_fw_helptext(struct b43legacy_wl *wl)
{
- b43legacyerr(wl, "You must go to http://wireless.kernel.org/en/users/"
- "Drivers/b43#devicefirmware "
+ b43legacyerr(wl, "You must go to https://wireless.wiki.kernel.org/en/"
+ "users/Drivers/b43#devicefirmware "
"and download the correct firmware (version 3).\n");
}
@@ -1870,7 +1870,7 @@ out:
}
/* Initialize the GPIOs
- * http://bcm-specs.sipsolutions.net/GPIO
+ * https://bcm-specs.sipsolutions.net/GPIO
*/
static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
{
@@ -1960,7 +1960,7 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
}
}
-/* http://bcm-specs.sipsolutions.net/SuspendMAC */
+/* https://bcm-specs.sipsolutions.net/SuspendMAC */
void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
{
int i;
@@ -2141,7 +2141,7 @@ static void b43legacy_chip_exit(struct b43legacy_wldev *dev)
}
/* Initialize the chip
- * http://bcm-specs.sipsolutions.net/ChipInit
+ * https://bcm-specs.sipsolutions.net/ChipInit
*/
static int b43legacy_chip_init(struct b43legacy_wldev *dev)
{
diff --git a/drivers/net/wireless/broadcom/b43legacy/phy.c b/drivers/net/wireless/broadcom/b43legacy/phy.c
index a659259bc51a..05404fbd1e70 100644
--- a/drivers/net/wireless/broadcom/b43legacy/phy.c
+++ b/drivers/net/wireless/broadcom/b43legacy/phy.c
@@ -129,7 +129,7 @@ void b43legacy_phy_calibrate(struct b43legacy_wldev *dev)
}
/* initialize B PHY power control
- * as described in http://bcm-specs.sipsolutions.net/InitPowerControl
+ * as described in https://bcm-specs.sipsolutions.net/InitPowerControl
*/
static void b43legacy_phy_init_pctl(struct b43legacy_wldev *dev)
{
@@ -1461,7 +1461,7 @@ void b43legacy_phy_set_baseband_attenuation(struct b43legacy_wldev *dev,
b43legacy_phy_write(dev, 0x0060, value);
}
-/* http://bcm-specs.sipsolutions.net/LocalOscillator/Measure */
+/* https://bcm-specs.sipsolutions.net/LocalOscillator/Measure */
void b43legacy_phy_lo_g_measure(struct b43legacy_wldev *dev)
{
static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 };
@@ -1721,7 +1721,7 @@ void b43legacy_phy_lo_mark_all_unused(struct b43legacy_wldev *dev)
}
}
-/* http://bcm-specs.sipsolutions.net/EstimatePowerOut
+/* https://bcm-specs.sipsolutions.net/EstimatePowerOut
* This function converts a TSSI value to dBm in Q5.2
*/
static s8 b43legacy_phy_estimate_power_out(struct b43legacy_wldev *dev, s8 tssi)
@@ -1747,7 +1747,7 @@ static s8 b43legacy_phy_estimate_power_out(struct b43legacy_wldev *dev, s8 tssi)
return dbm;
}
-/* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */
+/* https://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */
void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
{
struct b43legacy_phy *phy = &dev->phy;
diff --git a/drivers/net/wireless/broadcom/b43legacy/radio.c b/drivers/net/wireless/broadcom/b43legacy/radio.c
index da40d1ca8723..06891b4f837b 100644
--- a/drivers/net/wireless/broadcom/b43legacy/radio.c
+++ b/drivers/net/wireless/broadcom/b43legacy/radio.c
@@ -313,14 +313,14 @@ u8 b43legacy_radio_aci_scan(struct b43legacy_wldev *dev)
return ret[channel - 1];
}
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
+/* https://bcm-specs.sipsolutions.net/NRSSILookupTable */
void b43legacy_nrssi_hw_write(struct b43legacy_wldev *dev, u16 offset, s16 val)
{
b43legacy_phy_write(dev, B43legacy_PHY_NRSSILT_CTRL, offset);
b43legacy_phy_write(dev, B43legacy_PHY_NRSSILT_DATA, (u16)val);
}
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
+/* https://bcm-specs.sipsolutions.net/NRSSILookupTable */
s16 b43legacy_nrssi_hw_read(struct b43legacy_wldev *dev, u16 offset)
{
u16 val;
@@ -331,7 +331,7 @@ s16 b43legacy_nrssi_hw_read(struct b43legacy_wldev *dev, u16 offset)
return (s16)val;
}
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
+/* https://bcm-specs.sipsolutions.net/NRSSILookupTable */
void b43legacy_nrssi_hw_update(struct b43legacy_wldev *dev, u16 val)
{
u16 i;
@@ -345,7 +345,7 @@ void b43legacy_nrssi_hw_update(struct b43legacy_wldev *dev, u16 val)
}
}
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
+/* https://bcm-specs.sipsolutions.net/NRSSILookupTable */
void b43legacy_nrssi_mem_update(struct b43legacy_wldev *dev)
{
struct b43legacy_phy *phy = &dev->phy;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 46346cb3bc84..1a7ab49295aa 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -863,7 +863,7 @@ static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
}
#endif /* CONFIG_PM_SLEEP */
-static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
+int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
{
sdiodev->state = BRCMF_SDIOD_DOWN;
if (sdiodev->bus) {
@@ -898,7 +898,7 @@ static void brcmf_sdiod_host_fixup(struct mmc_host *host)
host->caps |= MMC_CAP_NONREMOVABLE;
}
-static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
+int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
{
int ret = 0;
unsigned int f2_blksz = SDIO_FUNC2_BLOCKSIZE;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index a757abd7a599..ab0da2ff982e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -84,6 +84,8 @@
#define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000)
+#define BRCMF_PS_MAX_TIMEOUT_MS 2000
+
#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
@@ -1387,7 +1389,8 @@ static int brcmf_set_sae_password(struct brcmf_if *ifp, const u8 *pwd_data,
return err;
}
-static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
+static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason,
+ bool locally_generated)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
struct brcmf_pub *drvr = cfg->pub;
@@ -1409,7 +1412,7 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
(vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
- true, GFP_KERNEL);
+ locally_generated, GFP_KERNEL);
}
clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
@@ -1588,7 +1591,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
return 0;
}
- brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
+ brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING, true);
brcmf_net_setcarrier(ifp, false);
brcmf_dbg(TRACE, "Exit\n");
@@ -2941,6 +2944,12 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
else
bphy_err(drvr, "error (%d)\n", err);
}
+
+ err = brcmf_fil_iovar_int_set(ifp, "pm2_sleep_ret",
+ min_t(u32, timeout, BRCMF_PS_MAX_TIMEOUT_MS));
+ if (err)
+ bphy_err(drvr, "Unable to set pm timeout, (%d)\n", err);
+
done:
brcmf_dbg(TRACE, "Exit\n");
return err;
@@ -3907,7 +3916,7 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
* disassociate from AP to save power while system is
* in suspended state
*/
- brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
+ brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED, true);
/* Make sure WPA_Supplicant receives all the event
* generated due to DISASSOC call to the fw to keep
* the state fw and WPA_Supplicant state consistent
@@ -4835,12 +4844,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
}
- if (settings->hidden_ssid) {
- err = brcmf_fil_iovar_int_set(ifp, "closednet", 1);
- if (err) {
- bphy_err(drvr, "closednet error (%d)\n", err);
- goto exit;
- }
+ err = brcmf_fil_iovar_int_set(ifp, "closednet",
+ settings->hidden_ssid);
+ if (err) {
+ bphy_err(drvr, "%s closednet error (%d)\n",
+ settings->hidden_ssid ?
+ "enabled" : "disabled",
+ err);
+ goto exit;
}
brcmf_dbg(TRACE, "AP mode configuration complete\n");
@@ -5129,7 +5140,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
&freq);
chan_nr = ieee80211_frequency_to_channel(freq);
af_params->channel = cpu_to_le32(chan_nr);
-
+ af_params->dwell_time = cpu_to_le32(params->wait);
memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
le16_to_cpu(action_frame->len));
@@ -6024,10 +6035,19 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
brcmf_net_setcarrier(ifp, true);
} else if (brcmf_is_linkdown(e)) {
brcmf_dbg(CONN, "Linkdown\n");
- if (!brcmf_is_ibssmode(ifp->vif)) {
+ if (!brcmf_is_ibssmode(ifp->vif) &&
+ test_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state)) {
+ if (memcmp(profile->bssid, e->addr, ETH_ALEN))
+ return err;
+
brcmf_bss_connect_done(cfg, ndev, e, false);
brcmf_link_down(ifp->vif,
- brcmf_map_fw_linkdown_reason(e));
+ brcmf_map_fw_linkdown_reason(e),
+ e->event_code &
+ (BRCMF_E_DEAUTH_IND |
+ BRCMF_E_DISASSOC_IND)
+ ? false : true);
brcmf_init_prof(ndev_to_prof(ndev));
if (ndev != cfg_to_ndev(cfg))
complete(&cfg->vif_disabled);
@@ -6801,7 +6821,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
* #AP <= 4, matching BI, channels = 1, 4 total
*
* no p2p and rsdb:
- * #STA <= 2, #AP <= 2, channels = 2, 4 total
+ * #STA <= 1, #AP <= 2, channels = 2, 4 total
*
* p2p, no mchan, and mbss:
*
@@ -6816,7 +6836,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
* #AP <= 4, matching BI, channels = 1, 4 total
*
* p2p, rsdb, and no mbss:
- * #STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
+ * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
* channels = 2, 4 total
*/
static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
@@ -6857,7 +6877,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
goto err;
combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
- c0_limits[i].max = 1 + rsdb;
+ c0_limits[i].max = 1;
c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
if (mon_flag) {
c0_limits[i].max = 1;
@@ -6873,7 +6893,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
if (p2p && rsdb) {
c0_limits[i].max = 2;
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
- combo[c].max_interfaces = 5;
+ combo[c].max_interfaces = 4;
} else if (p2p) {
combo[c].max_interfaces = i;
} else if (rsdb) {
@@ -7180,7 +7200,7 @@ static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
* from AP to save power
*/
if (check_vif_up(ifp->vif)) {
- brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
+ brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED, true);
/* Make sure WPA_Supplicant receives all the event
generated due to DISASSOC call to the fw to keep
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index dec25e415619..e3758bd86acf 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -209,8 +209,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
bphy_err(drvr, "Retrieving cur_etheraddr failed, %d\n", err);
goto done;
}
- memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
+ memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
bus = ifp->drvr->bus_if;
ri = &ifp->drvr->revinfo;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index c88655acc78c..f89010a81ffb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -352,6 +352,9 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
if ((skb->priority == 0) || (skb->priority > 7))
skb->priority = cfg80211_classify8021d(skb, NULL);
+ /* set pacing shift for packet aggregation */
+ sk_pacing_shift_update(skb->sk, 8);
+
ret = brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb);
if (ret < 0)
brcmf_txfinalize(ifp, skb, false);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index de0ef1b545c4..2e31cc10c195 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -19,7 +19,7 @@
#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008
#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
-#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002
+#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0004
#define BRCMF_STA_BRCM 0x00000001 /* Running a Broadcom driver */
#define BRCMF_STA_WME 0x00000002 /* WMM association */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
index 09701262330d..2df6811c066e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -323,6 +323,10 @@ struct brcmf_skbuff_cb {
* firmware suppress the packet as device is already in PS mode.
* @BRCMF_FWS_TXSTATUS_FW_TOSSED:
* firmware tossed the packet.
+ * @BRCMF_FWS_TXSTATUS_FW_DISCARD_NOACK:
+ * firmware tossed the packet after retries.
+ * @BRCMF_FWS_TXSTATUS_FW_SUPPRESS_ACKED:
+ * firmware wrongly reported suppressed previously, now fixing to acked.
* @BRCMF_FWS_TXSTATUS_HOST_TOSSED:
* host tossed the packet.
*/
@@ -331,6 +335,8 @@ enum brcmf_fws_txstatus {
BRCMF_FWS_TXSTATUS_CORE_SUPPRESS,
BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS,
BRCMF_FWS_TXSTATUS_FW_TOSSED,
+ BRCMF_FWS_TXSTATUS_FW_DISCARD_NOACK,
+ BRCMF_FWS_TXSTATUS_FW_SUPPRESS_ACKED,
BRCMF_FWS_TXSTATUS_HOST_TOSSED
};
@@ -383,6 +389,7 @@ struct brcmf_fws_mac_descriptor {
};
#define BRCMF_FWS_HANGER_MAXITEMS 3072
+#define BRCMF_BORROW_RATIO 3
/**
* enum brcmf_fws_hanger_item_state - state of hanger item.
@@ -479,7 +486,8 @@ struct brcmf_fws_info {
u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT];
int fifo_credit[BRCMF_FWS_FIFO_COUNT];
int init_fifo_credit[BRCMF_FWS_FIFO_COUNT];
- int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1];
+ int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1]
+ [BRCMF_FWS_FIFO_AC_VO + 1];
int deq_node_pos[BRCMF_FWS_FIFO_COUNT];
u32 fifo_credit_map;
u32 fifo_delay_map;
@@ -621,6 +629,7 @@ static inline int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h,
static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q,
int ifidx)
{
+ struct brcmf_fws_hanger_item *hi;
bool (*matchfn)(struct sk_buff *, void *) = NULL;
struct sk_buff *skb;
int prec;
@@ -632,6 +641,9 @@ static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q,
skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx);
while (skb) {
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
+ hi = &fws->hanger.items[hslot];
+ WARN_ON(skb != hi->pkt);
+ hi->state = BRCMF_FWS_HANGER_ITEM_STATE_FREE;
brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
true);
brcmu_pkt_buf_free_skb(skb);
@@ -1187,11 +1199,11 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
fws->fifo_credit_map |= 1 << fifo;
- if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
- (fws->credits_borrowed[0])) {
+ if (fifo > BRCMF_FWS_FIFO_AC_BK &&
+ fifo <= BRCMF_FWS_FIFO_AC_VO) {
for (lender_ac = BRCMF_FWS_FIFO_AC_VO; lender_ac >= 0;
lender_ac--) {
- borrowed = &fws->credits_borrowed[lender_ac];
+ borrowed = &fws->credits_borrowed[fifo][lender_ac];
if (*borrowed) {
fws->fifo_credit_map |= (1 << lender_ac);
fifo_credit = &fws->fifo_credit[lender_ac];
@@ -1208,7 +1220,10 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
}
}
- fws->fifo_credit[fifo] += credits;
+ if (credits) {
+ fws->fifo_credit[fifo] += credits;
+ }
+
if (fws->fifo_credit[fifo] > fws->init_fifo_credit[fifo])
fws->fifo_credit[fifo] = fws->init_fifo_credit[fifo];
@@ -1451,6 +1466,10 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
remove_from_hanger = false;
} else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED)
fws->stats.txs_tossed += compcnt;
+ else if (flags == BRCMF_FWS_TXSTATUS_FW_DISCARD_NOACK)
+ fws->stats.txs_discard += compcnt;
+ else if (flags == BRCMF_FWS_TXSTATUS_FW_SUPPRESS_ACKED)
+ fws->stats.txs_discard += compcnt;
else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)
fws->stats.txs_host_tossed += compcnt;
else
@@ -1843,6 +1862,9 @@ void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
WARN_ON(siglen > skb->len);
+ if (siglen > skb->len)
+ siglen = skb->len;
+
if (!siglen)
return;
/* if flow control disabled, skip to packet data and leave */
@@ -2005,27 +2027,31 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
}
}
-static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
+static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws,
+ int highest_lender_ac, int borrower_ac,
+ bool borrow_all)
{
- int lender_ac;
+ int lender_ac, borrow_limit = 0;
- if (time_after(fws->borrow_defer_timestamp, jiffies)) {
- fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE);
- return -ENAVAIL;
- }
+ for (lender_ac = 0; lender_ac <= highest_lender_ac; lender_ac++) {
- for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) {
- if (fws->fifo_credit[lender_ac] > 0) {
- fws->credits_borrowed[lender_ac]++;
+ if (!borrow_all)
+ borrow_limit =
+ fws->init_fifo_credit[lender_ac] / BRCMF_BORROW_RATIO;
+ else
+ borrow_limit = 0;
+
+ if (fws->fifo_credit[lender_ac] > borrow_limit) {
+ fws->credits_borrowed[borrower_ac][lender_ac]++;
fws->fifo_credit[lender_ac]--;
if (fws->fifo_credit[lender_ac] == 0)
fws->fifo_credit_map &= ~(1 << lender_ac);
- fws->fifo_credit_map |= (1 << BRCMF_FWS_FIFO_AC_BE);
+ fws->fifo_credit_map |= (1 << borrower_ac);
brcmf_dbg(DATA, "borrow credit from: %d\n", lender_ac);
return 0;
}
}
- fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE);
+ fws->fifo_credit_map &= ~(1 << borrower_ac);
return -ENAVAIL;
}
@@ -2216,9 +2242,10 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
}
continue;
}
- while ((fws->fifo_credit[fifo] > 0) ||
+
+ while ((fws->fifo_credit[fifo]) ||
((!fws->bcmc_credit_check) &&
- (fifo == BRCMF_FWS_FIFO_BCMC))) {
+ (fifo == BRCMF_FWS_FIFO_BCMC))) {
skb = brcmf_fws_deq(fws, fifo);
if (!skb)
break;
@@ -2228,10 +2255,14 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
if (fws->bus_flow_blocked)
break;
}
- if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
- (fws->fifo_credit[fifo] <= 0) &&
- (!fws->bus_flow_blocked)) {
- while (brcmf_fws_borrow_credit(fws) == 0) {
+
+ if (fifo >= BRCMF_FWS_FIFO_AC_BE &&
+ fifo <= BRCMF_FWS_FIFO_AC_VO &&
+ fws->fifo_credit[fifo] == 0 &&
+ !fws->bus_flow_blocked) {
+ while (brcmf_fws_borrow_credit(fws,
+ fifo - 1, fifo,
+ true) == 0) {
skb = brcmf_fws_deq(fws, fifo);
if (!skb) {
brcmf_fws_return_credits(fws, fifo, 1);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index 8bb4f1fa790e..f1a20db8daab 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -54,6 +54,7 @@
#define BRCMF_IOCTL_REQ_PKTID 0xFFFE
#define BRCMF_MSGBUF_MAX_PKT_SIZE 2048
+#define BRCMF_MSGBUF_MAX_CTL_PKT_SIZE 8192
#define BRCMF_MSGBUF_RXBUFPOST_THRESHOLD 32
#define BRCMF_MSGBUF_MAX_IOCTLRESPBUF_POST 8
#define BRCMF_MSGBUF_MAX_EVENTBUF_POST 8
@@ -1028,7 +1029,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
rx_bufpost = (struct msgbuf_rx_ioctl_resp_or_event *)ret_ptr;
memset(rx_bufpost, 0, sizeof(*rx_bufpost));
- skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
+ skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_CTL_PKT_SIZE);
if (skb == NULL) {
bphy_err(drvr, "Failed to alloc SKB\n");
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
index b886b56a5e5a..a7554265f95f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -17,7 +17,6 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
{
struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
struct device_node *root, *np = dev->of_node;
- struct property *prop;
int irq;
u32 irqf;
u32 val;
@@ -25,8 +24,22 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
/* Set board-type to the first string of the machine compatible prop */
root = of_find_node_by_path("/");
if (root) {
- prop = of_find_property(root, "compatible", NULL);
- settings->board_type = of_prop_next_string(prop, NULL);
+ int i, len;
+ char *board_type;
+ const char *tmp;
+
+ of_property_read_string_index(root, "compatible", 0, &tmp);
+
+ /* get rid of '/' in the compatible string to be able to find the FW */
+ len = strlen(tmp) + 1;
+ board_type = devm_kzalloc(dev, len, GFP_KERNEL);
+ strscpy(board_type, tmp, len);
+ for (i = 0; i < board_type[i]; i++) {
+ if (board_type[i] == '/')
+ board_type[i] = '-';
+ }
+ settings->board_type = board_type;
+
of_node_put(root);
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index d2795dc17c46..debd887e159e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -1700,7 +1700,7 @@ static s32 brcmf_p2p_pub_af_tx(struct brcmf_cfg80211_info *cfg,
return err;
}
-static bool brcmf_p2p_check_dwell_overflow(s32 requested_dwell,
+static bool brcmf_p2p_check_dwell_overflow(u32 requested_dwell,
unsigned long dwell_jiffies)
{
if ((requested_dwell & CUSTOM_RETRY_MASK) &&
@@ -1738,8 +1738,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
unsigned long dwell_jiffies = 0;
bool dwell_overflow = false;
- s32 requested_dwell = af_params->dwell_time;
-
+ u32 requested_dwell = le32_to_cpu(af_params->dwell_time);
action_frame = &af_params->action_frame;
action_frame_len = le16_to_cpu(action_frame->len);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 310d8075f5d7..e8712ad3ac45 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -16,6 +16,7 @@
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/card.h>
+#include <linux/mmc/core.h>
#include <linux/semaphore.h>
#include <linux/firmware.h>
#include <linux/module.h>
@@ -648,6 +649,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012)
};
+#define TXCTL_CREDITS 2
+
static void pkt_align(struct sk_buff *p, int len, int align)
{
uint datalign;
@@ -661,8 +664,16 @@ static void pkt_align(struct sk_buff *p, int len, int align)
/* To check if there's window offered */
static bool data_ok(struct brcmf_sdio *bus)
{
- return (u8)(bus->tx_max - bus->tx_seq) != 0 &&
- ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
+ /* Reserve TXCTL_CREDITS credits for txctl */
+ return (bus->tx_max - bus->tx_seq) > TXCTL_CREDITS &&
+ ((bus->tx_max - bus->tx_seq) & 0x80) == 0;
+}
+
+/* To check if there's window offered */
+static bool txctl_ok(struct brcmf_sdio *bus)
+{
+ return (bus->tx_max - bus->tx_seq) != 0 &&
+ ((bus->tx_max - bus->tx_seq) & 0x80) == 0;
}
static int
@@ -2668,7 +2679,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
brcmf_sdio_clrintr(bus);
if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
- data_ok(bus)) {
+ txctl_ok(bus)) {
sdio_claim_host(bus->sdiodev->func1);
if (bus->ctrl_frame_stat) {
err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
@@ -2676,6 +2687,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
bus->ctrl_frame_err = err;
wmb();
bus->ctrl_frame_stat = false;
+ if (err)
+ brcmf_err("sdio ctrlframe tx failed err=%d\n",
+ err);
}
sdio_release_host(bus->sdiodev->func1);
brcmf_sdio_wait_event_wakeup(bus);
@@ -3699,7 +3713,11 @@ static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
if (bus->idlecount > bus->idletime) {
brcmf_dbg(SDIO, "idle\n");
sdio_claim_host(bus->sdiodev->func1);
- brcmf_sdio_wd_timer(bus, false);
+#ifdef DEBUG
+ if (!BRCMF_FWCON_ON() ||
+ bus->console_interval == 0)
+#endif
+ brcmf_sdio_wd_timer(bus, false);
bus->idlecount = 0;
brcmf_sdio_bus_sleep(bus, true, false);
sdio_release_host(bus->sdiodev->func1);
@@ -4109,6 +4127,36 @@ int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
return 0;
}
+static int brcmf_sdio_bus_reset(struct device *dev)
+{
+ int ret = 0;
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+
+ brcmf_dbg(SDIO, "Enter\n");
+
+ /* start by unregistering irqs */
+ brcmf_sdiod_intr_unregister(sdiodev);
+
+ brcmf_sdiod_remove(sdiodev);
+
+ /* reset the adapter */
+ sdio_claim_host(sdiodev->func1);
+ mmc_hw_reset(sdiodev->func1->card->host);
+ sdio_release_host(sdiodev->func1);
+
+ brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
+
+ ret = brcmf_sdiod_probe(sdiodev);
+ if (ret) {
+ brcmf_err("Failed to probe after sdio device reset: ret %d\n",
+ ret);
+ brcmf_sdiod_remove(sdiodev);
+ }
+
+ return ret;
+}
+
static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.stop = brcmf_sdio_bus_stop,
.preinit = brcmf_sdio_bus_preinit,
@@ -4120,7 +4168,8 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.get_ramsize = brcmf_sdio_bus_get_ramsize,
.get_memdump = brcmf_sdio_bus_get_memdump,
.get_fwname = brcmf_sdio_get_fwname,
- .debugfs_create = brcmf_sdio_debugfs_create
+ .debugfs_create = brcmf_sdio_debugfs_create,
+ .reset = brcmf_sdio_bus_reset
};
#define BRCMF_SDIO_FW_CODE 0
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 163fd664780a..12108927fb50 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -367,6 +367,9 @@ static inline void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)
}
#endif /* CONFIG_PM_SLEEP */
+int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev);
+int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev);
+
struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
void brcmf_sdio_remove(struct brcmf_sdio *bus);
void brcmf_sdio_isr(struct brcmf_sdio *bus);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
index c0a5449ed72c..c1b9ac692d26 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
#include <net/mac80211.h>
#include <linux/bcma/bcma_driver_chipcommon.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio/machine.h>
+#include <linux/gpio/consumer.h>
#include "mac80211_if.h"
#include "pub.h"
@@ -19,16 +21,13 @@
static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state)
{
- if (wl->radio_led.gpio == -1)
+ if (!wl->radio_led.gpiod)
return;
- if (wl->radio_led.active_low)
- state = !state;
-
if (state)
- gpio_set_value(wl->radio_led.gpio, 1);
+ gpiod_set_value(wl->radio_led.gpiod, 1);
else
- gpio_set_value(wl->radio_led.gpio, 0);
+ gpiod_set_value(wl->radio_led.gpiod, 0);
}
@@ -45,8 +44,8 @@ void brcms_led_unregister(struct brcms_info *wl)
{
if (wl->led_dev.dev)
led_classdev_unregister(&wl->led_dev);
- if (wl->radio_led.gpio != -1)
- gpio_free(wl->radio_led.gpio);
+ if (wl->radio_led.gpiod)
+ gpiochip_free_own_desc(wl->radio_led.gpiod);
}
int brcms_led_register(struct brcms_info *wl)
@@ -61,12 +60,8 @@ int brcms_led_register(struct brcms_info *wl)
&sprom->gpio1,
&sprom->gpio2,
&sprom->gpio3 };
- unsigned gpio = -1;
- bool active_low = false;
-
- /* none by default */
- radio_led->gpio = -1;
- radio_led->active_low = false;
+ int hwnum = -1;
+ enum gpio_lookup_flags lflags = GPIO_ACTIVE_HIGH;
if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
return -ENODEV;
@@ -75,30 +70,26 @@ int brcms_led_register(struct brcms_info *wl)
for (i = 0; i < BRCMS_LED_NO; i++) {
u8 led = *leds[i];
if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {
- gpio = bcma_gpio->base + i;
+ hwnum = i;
if (led & BRCMS_LED_AL_MASK)
- active_low = true;
+ lflags = GPIO_ACTIVE_LOW;
break;
}
}
- if (gpio == -1 || !gpio_is_valid(gpio))
+ /* No LED, bail out */
+ if (hwnum == -1)
return -ENODEV;
- /* request and configure LED gpio */
- err = gpio_request_one(gpio,
- active_low ? GPIOF_OUT_INIT_HIGH
- : GPIOF_OUT_INIT_LOW,
- "radio on");
- if (err) {
- wiphy_err(wl->wiphy, "requesting led gpio %d failed (err: %d)\n",
- gpio, err);
- return err;
- }
- err = gpio_direction_output(gpio, 1);
- if (err) {
- wiphy_err(wl->wiphy, "cannot set led gpio %d to output (err: %d)\n",
- gpio, err);
+ /* Try to obtain this LED GPIO line */
+ radio_led->gpiod = gpiochip_request_own_desc(bcma_gpio, hwnum,
+ "radio on", lflags,
+ GPIOD_OUT_LOW);
+
+ if (IS_ERR(radio_led->gpiod)) {
+ err = PTR_ERR(radio_led->gpiod);
+ wiphy_err(wl->wiphy, "requesting led GPIO failed (err: %d)\n",
+ err);
return err;
}
@@ -117,11 +108,8 @@ int brcms_led_register(struct brcms_info *wl)
return err;
}
- wiphy_info(wl->wiphy, "registered radio enabled led device: %s gpio: %d\n",
- wl->radio_led.name,
- gpio);
- radio_led->gpio = gpio;
- radio_led->active_low = active_low;
+ wiphy_info(wl->wiphy, "registered radio enabled led device: %s\n",
+ wl->radio_led.name);
return 0;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
index 17a0b1f5dbcf..d65f5c268fd7 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
@@ -16,10 +16,12 @@
#ifndef _BRCM_LED_H_
#define _BRCM_LED_H_
+
+struct gpio_desc;
+
struct brcms_led {
char name[32];
- unsigned gpio;
- bool active_low;
+ struct gpio_desc *gpiod;
};
#ifdef CONFIG_BCMA_DRIVER_GPIO
diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c
index 827bb6d74815..316672486d82 100644
--- a/drivers/net/wireless/cisco/airo.c
+++ b/drivers/net/wireless/cisco/airo.c
@@ -74,16 +74,19 @@ MODULE_DEVICE_TABLE(pci, card_ids);
static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
static void airo_pci_remove(struct pci_dev *);
-static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state);
-static int airo_pci_resume(struct pci_dev *pdev);
+static int __maybe_unused airo_pci_suspend(struct device *dev);
+static int __maybe_unused airo_pci_resume(struct device *dev);
+
+static SIMPLE_DEV_PM_OPS(airo_pci_pm_ops,
+ airo_pci_suspend,
+ airo_pci_resume);
static struct pci_driver airo_driver = {
- .name = DRV_NAME,
- .id_table = card_ids,
- .probe = airo_pci_probe,
- .remove = airo_pci_remove,
- .suspend = airo_pci_suspend,
- .resume = airo_pci_resume,
+ .name = DRV_NAME,
+ .id_table = card_ids,
+ .probe = airo_pci_probe,
+ .remove = airo_pci_remove,
+ .driver.pm = &airo_pci_pm_ops,
};
#endif /* CONFIG_PCI */
@@ -2450,7 +2453,7 @@ static void mpi_unmap_card(struct pci_dev *pci)
/*************************************************************
* This routine assumes that descriptors have been setup .
- * Run at insmod time or after reset when the decriptors
+ * Run at insmod time or after reset when the descriptors
* have been initialized . Returns 0 if all is well nz
* otherwise . Does not allocate memory but sets up card
* using previously allocated descriptors.
@@ -3113,7 +3116,7 @@ static int airo_thread(void *data) {
}
break;
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&ai->thr_wait, &wait);
locked = 1;
}
@@ -5573,9 +5576,9 @@ static void airo_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused airo_pci_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct airo_info *ai = dev->ml_priv;
Cmd cmd;
Resp rsp;
@@ -5591,25 +5594,21 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
return -EAGAIN;
disable_MAC(ai, 0);
netif_device_detach(dev);
- ai->power = state;
+ ai->power = PMSG_SUSPEND;
cmd.cmd = HOSTSLEEP;
issuecommand(ai, &cmd, &rsp);
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
- pci_save_state(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ device_wakeup_enable(dev_d);
return 0;
}
-static int airo_pci_resume(struct pci_dev *pdev)
+static int __maybe_unused airo_pci_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
struct airo_info *ai = dev->ml_priv;
- pci_power_t prev_state = pdev->current_state;
+ pci_power_t prev_state = to_pci_dev(dev_d)->current_state;
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D0, 0);
+ device_wakeup_disable(dev_d);
if (prev_state != PCI_D1) {
reset_card(dev, 0);
diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig
index d00386915a9d..b1e7b4470842 100644
--- a/drivers/net/wireless/intel/ipw2x00/Kconfig
+++ b/drivers/net/wireless/intel/ipw2x00/Kconfig
@@ -16,7 +16,7 @@ config IPW2100
A driver for the Intel PRO/Wireless 2100 Network
Connection 802.11b wireless network adapter.
- See <file:Documentation/networking/device_drivers/intel/ipw2100.rst>
+ See <file:Documentation/networking/device_drivers/wifi/intel/ipw2100.rst>
for information on the capabilities currently enabled in this driver
and for tips for debugging issues and problems.
@@ -28,7 +28,7 @@ config IPW2100
You will also very likely need the Wireless Tools in order to
configure your card:
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+ <https://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
It is recommended that you compile this driver as a module (M)
rather than built-in (Y). This driver requires firmware at device
@@ -78,7 +78,7 @@ config IPW2200
A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
Connection adapters.
- See <file:Documentation/networking/device_drivers/intel/ipw2200.rst>
+ See <file:Documentation/networking/device_drivers/wifi/intel/ipw2200.rst>
for information on the capabilities currently enabled in this
driver and for tips for debugging issues and problems.
@@ -90,7 +90,7 @@ config IPW2200
You will also very likely need the Wireless Tools in order to
configure your card:
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+ <https://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
It is recommended that you compile this driver as a module (M)
rather than built-in (Y). This driver requires firmware at device
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
index 624fe721e2b5..461e955aa259 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
@@ -2295,10 +2295,11 @@ static int ipw2100_alloc_skb(struct ipw2100_priv *priv,
return -ENOMEM;
packet->rxp = (struct ipw2100_rx *)packet->skb->data;
- packet->dma_addr = pci_map_single(priv->pci_dev, packet->skb->data,
+ packet->dma_addr = dma_map_single(&priv->pci_dev->dev,
+ packet->skb->data,
sizeof(struct ipw2100_rx),
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(priv->pci_dev, packet->dma_addr)) {
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&priv->pci_dev->dev, packet->dma_addr)) {
dev_kfree_skb(packet->skb);
return -ENOMEM;
}
@@ -2479,9 +2480,8 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
return;
}
- pci_unmap_single(priv->pci_dev,
- packet->dma_addr,
- sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&priv->pci_dev->dev, packet->dma_addr,
+ sizeof(struct ipw2100_rx), DMA_FROM_DEVICE);
skb_put(packet->skb, status->frame_size);
@@ -2563,8 +2563,8 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
return;
}
- pci_unmap_single(priv->pci_dev, packet->dma_addr,
- sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&priv->pci_dev->dev, packet->dma_addr,
+ sizeof(struct ipw2100_rx), DMA_FROM_DEVICE);
memmove(packet->skb->data + sizeof(struct ipw_rt_hdr),
packet->skb->data, status->frame_size);
@@ -2689,9 +2689,9 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
/* Sync the DMA for the RX buffer so CPU is sure to get
* the correct values */
- pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr,
- sizeof(struct ipw2100_rx),
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&priv->pci_dev->dev, packet->dma_addr,
+ sizeof(struct ipw2100_rx),
+ DMA_FROM_DEVICE);
if (unlikely(ipw2100_corruption_check(priv, i))) {
ipw2100_corruption_detected(priv, i);
@@ -2923,9 +2923,8 @@ static int __ipw2100_tx_process(struct ipw2100_priv *priv)
(packet->index + 1 + i) % txq->entries,
tbd->host_addr, tbd->buf_length);
- pci_unmap_single(priv->pci_dev,
- tbd->host_addr,
- tbd->buf_length, PCI_DMA_TODEVICE);
+ dma_unmap_single(&priv->pci_dev->dev, tbd->host_addr,
+ tbd->buf_length, DMA_TO_DEVICE);
}
libipw_txb_free(packet->info.d_struct.txb);
@@ -3165,15 +3164,13 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
tbd->buf_length = packet->info.d_struct.txb->
fragments[i]->len - LIBIPW_3ADDR_LEN;
- tbd->host_addr = pci_map_single(priv->pci_dev,
+ tbd->host_addr = dma_map_single(&priv->pci_dev->dev,
packet->info.d_struct.
- txb->fragments[i]->
- data +
+ txb->fragments[i]->data +
LIBIPW_3ADDR_LEN,
tbd->buf_length,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(priv->pci_dev,
- tbd->host_addr)) {
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&priv->pci_dev->dev, tbd->host_addr)) {
IPW_DEBUG_TX("dma mapping error\n");
break;
}
@@ -3182,10 +3179,10 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
txq->next, tbd->host_addr,
tbd->buf_length);
- pci_dma_sync_single_for_device(priv->pci_dev,
- tbd->host_addr,
- tbd->buf_length,
- PCI_DMA_TODEVICE);
+ dma_sync_single_for_device(&priv->pci_dev->dev,
+ tbd->host_addr,
+ tbd->buf_length,
+ DMA_TO_DEVICE);
txq->next++;
txq->next %= txq->entries;
@@ -3440,9 +3437,9 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
return -ENOMEM;
for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
- v = pci_zalloc_consistent(priv->pci_dev,
- sizeof(struct ipw2100_cmd_header),
- &p);
+ v = dma_alloc_coherent(&priv->pci_dev->dev,
+ sizeof(struct ipw2100_cmd_header), &p,
+ GFP_KERNEL);
if (!v) {
printk(KERN_ERR DRV_NAME ": "
"%s: PCI alloc failed for msg "
@@ -3461,11 +3458,10 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
return 0;
for (j = 0; j < i; j++) {
- pci_free_consistent(priv->pci_dev,
- sizeof(struct ipw2100_cmd_header),
- priv->msg_buffers[j].info.c_struct.cmd,
- priv->msg_buffers[j].info.c_struct.
- cmd_phys);
+ dma_free_coherent(&priv->pci_dev->dev,
+ sizeof(struct ipw2100_cmd_header),
+ priv->msg_buffers[j].info.c_struct.cmd,
+ priv->msg_buffers[j].info.c_struct.cmd_phys);
}
kfree(priv->msg_buffers);
@@ -3496,11 +3492,10 @@ static void ipw2100_msg_free(struct ipw2100_priv *priv)
return;
for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
- pci_free_consistent(priv->pci_dev,
- sizeof(struct ipw2100_cmd_header),
- priv->msg_buffers[i].info.c_struct.cmd,
- priv->msg_buffers[i].info.c_struct.
- cmd_phys);
+ dma_free_coherent(&priv->pci_dev->dev,
+ sizeof(struct ipw2100_cmd_header),
+ priv->msg_buffers[i].info.c_struct.cmd,
+ priv->msg_buffers[i].info.c_struct.cmd_phys);
}
kfree(priv->msg_buffers);
@@ -4323,7 +4318,8 @@ static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
IPW_DEBUG_INFO("enter\n");
q->size = entries * sizeof(struct ipw2100_status);
- q->drv = pci_zalloc_consistent(priv->pci_dev, q->size, &q->nic);
+ q->drv = dma_alloc_coherent(&priv->pci_dev->dev, q->size, &q->nic,
+ GFP_KERNEL);
if (!q->drv) {
IPW_DEBUG_WARNING("Can not allocate status queue.\n");
return -ENOMEM;
@@ -4339,9 +4335,10 @@ static void status_queue_free(struct ipw2100_priv *priv)
IPW_DEBUG_INFO("enter\n");
if (priv->status_queue.drv) {
- pci_free_consistent(priv->pci_dev, priv->status_queue.size,
- priv->status_queue.drv,
- priv->status_queue.nic);
+ dma_free_coherent(&priv->pci_dev->dev,
+ priv->status_queue.size,
+ priv->status_queue.drv,
+ priv->status_queue.nic);
priv->status_queue.drv = NULL;
}
@@ -4357,7 +4354,8 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
q->entries = entries;
q->size = entries * sizeof(struct ipw2100_bd);
- q->drv = pci_zalloc_consistent(priv->pci_dev, q->size, &q->nic);
+ q->drv = dma_alloc_coherent(&priv->pci_dev->dev, q->size, &q->nic,
+ GFP_KERNEL);
if (!q->drv) {
IPW_DEBUG_INFO
("can't allocate shared memory for buffer descriptors\n");
@@ -4377,7 +4375,8 @@ static void bd_queue_free(struct ipw2100_priv *priv, struct ipw2100_bd_queue *q)
return;
if (q->drv) {
- pci_free_consistent(priv->pci_dev, q->size, q->drv, q->nic);
+ dma_free_coherent(&priv->pci_dev->dev, q->size, q->drv,
+ q->nic);
q->drv = NULL;
}
@@ -4430,16 +4429,16 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
priv->tx_buffers = kmalloc_array(TX_PENDED_QUEUE_LENGTH,
sizeof(struct ipw2100_tx_packet),
- GFP_ATOMIC);
+ GFP_KERNEL);
if (!priv->tx_buffers) {
bd_queue_free(priv, &priv->tx_queue);
return -ENOMEM;
}
for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
- v = pci_alloc_consistent(priv->pci_dev,
- sizeof(struct ipw2100_data_header),
- &p);
+ v = dma_alloc_coherent(&priv->pci_dev->dev,
+ sizeof(struct ipw2100_data_header), &p,
+ GFP_KERNEL);
if (!v) {
printk(KERN_ERR DRV_NAME
": %s: PCI alloc failed for tx " "buffers.\n",
@@ -4459,11 +4458,10 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
return 0;
for (j = 0; j < i; j++) {
- pci_free_consistent(priv->pci_dev,
- sizeof(struct ipw2100_data_header),
- priv->tx_buffers[j].info.d_struct.data,
- priv->tx_buffers[j].info.d_struct.
- data_phys);
+ dma_free_coherent(&priv->pci_dev->dev,
+ sizeof(struct ipw2100_data_header),
+ priv->tx_buffers[j].info.d_struct.data,
+ priv->tx_buffers[j].info.d_struct.data_phys);
}
kfree(priv->tx_buffers);
@@ -4540,12 +4538,10 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
priv->tx_buffers[i].info.d_struct.txb = NULL;
}
if (priv->tx_buffers[i].info.d_struct.data)
- pci_free_consistent(priv->pci_dev,
- sizeof(struct ipw2100_data_header),
- priv->tx_buffers[i].info.d_struct.
- data,
- priv->tx_buffers[i].info.d_struct.
- data_phys);
+ dma_free_coherent(&priv->pci_dev->dev,
+ sizeof(struct ipw2100_data_header),
+ priv->tx_buffers[i].info.d_struct.data,
+ priv->tx_buffers[i].info.d_struct.data_phys);
}
kfree(priv->tx_buffers);
@@ -4608,9 +4604,10 @@ static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
return 0;
for (j = 0; j < i; j++) {
- pci_unmap_single(priv->pci_dev, priv->rx_buffers[j].dma_addr,
+ dma_unmap_single(&priv->pci_dev->dev,
+ priv->rx_buffers[j].dma_addr,
sizeof(struct ipw2100_rx_packet),
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
dev_kfree_skb(priv->rx_buffers[j].skb);
}
@@ -4662,10 +4659,10 @@ static void ipw2100_rx_free(struct ipw2100_priv *priv)
for (i = 0; i < RX_QUEUE_LENGTH; i++) {
if (priv->rx_buffers[i].rxp) {
- pci_unmap_single(priv->pci_dev,
+ dma_unmap_single(&priv->pci_dev->dev,
priv->rx_buffers[i].dma_addr,
sizeof(struct ipw2100_rx),
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
dev_kfree_skb(priv->rx_buffers[i].skb);
}
}
@@ -6196,7 +6193,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
pci_set_master(pci_dev);
pci_set_drvdata(pci_dev, priv);
- err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
+ err = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_WARNING DRV_NAME
"Error calling pci_set_dma_mask.\n");
@@ -6397,10 +6394,9 @@ static void ipw2100_pci_remove_one(struct pci_dev *pci_dev)
IPW_DEBUG_INFO("exit\n");
}
-#ifdef CONFIG_PM
-static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
+static int __maybe_unused ipw2100_suspend(struct device *dev_d)
{
- struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
+ struct ipw2100_priv *priv = dev_get_drvdata(dev_d);
struct net_device *dev = priv->net_dev;
IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
@@ -6414,10 +6410,6 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
/* Remove the PRESENT state of the device */
netif_device_detach(dev);
- pci_save_state(pci_dev);
- pci_disable_device(pci_dev);
- pci_set_power_state(pci_dev, PCI_D3hot);
-
priv->suspend_at = ktime_get_boottime_seconds();
mutex_unlock(&priv->action_mutex);
@@ -6425,11 +6417,11 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
return 0;
}
-static int ipw2100_resume(struct pci_dev *pci_dev)
+static int __maybe_unused ipw2100_resume(struct device *dev_d)
{
+ struct pci_dev *pci_dev = to_pci_dev(dev_d);
struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
struct net_device *dev = priv->net_dev;
- int err;
u32 val;
if (IPW2100_PM_DISABLED)
@@ -6439,16 +6431,6 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
- pci_set_power_state(pci_dev, PCI_D0);
- err = pci_enable_device(pci_dev);
- if (err) {
- printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
- dev->name);
- mutex_unlock(&priv->action_mutex);
- return err;
- }
- pci_restore_state(pci_dev);
-
/*
* Suspend/Resume resets the PCI configuration space, so we have to
* re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -6473,7 +6455,6 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
return 0;
}
-#endif
static void ipw2100_shutdown(struct pci_dev *pci_dev)
{
@@ -6539,15 +6520,14 @@ static const struct pci_device_id ipw2100_pci_id_table[] = {
MODULE_DEVICE_TABLE(pci, ipw2100_pci_id_table);
+static SIMPLE_DEV_PM_OPS(ipw2100_pm_ops, ipw2100_suspend, ipw2100_resume);
+
static struct pci_driver ipw2100_pci_driver = {
.name = DRV_NAME,
.id_table = ipw2100_pci_id_table,
.probe = ipw2100_pci_init_one,
.remove = ipw2100_pci_remove_one,
-#ifdef CONFIG_PM
- .suspend = ipw2100_suspend,
- .resume = ipw2100_resume,
-#endif
+ .driver.pm = &ipw2100_pm_ops,
.shutdown = ipw2100_shutdown,
};
@@ -8352,7 +8332,7 @@ static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) {
printk(KERN_WARNING DRV_NAME ": Firmware image not compatible "
"(detected version id of %u). "
- "See Documentation/networking/device_drivers/intel/ipw2100.rst\n",
+ "See Documentation/networking/device_drivers/wifi/intel/ipw2100.rst\n",
h->version);
return 1;
}
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index 661e63bfc892..129ef2f6248a 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -3442,8 +3442,9 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv,
/* In the reset function, these buffers may have been allocated
* to an SKB, so we need to unmap and free potential storage */
if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
- IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&priv->pci_dev->dev,
+ rxq->pool[i].dma_addr,
+ IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);
dev_kfree_skb(rxq->pool[i].skb);
rxq->pool[i].skb = NULL;
}
@@ -3774,7 +3775,8 @@ static int ipw_queue_tx_init(struct ipw_priv *priv,
return -ENOMEM;
q->bd =
- pci_alloc_consistent(dev, sizeof(q->bd[0]) * count, &q->q.dma_addr);
+ dma_alloc_coherent(&dev->dev, sizeof(q->bd[0]) * count,
+ &q->q.dma_addr, GFP_KERNEL);
if (!q->bd) {
IPW_ERROR("pci_alloc_consistent(%zd) failed\n",
sizeof(q->bd[0]) * count);
@@ -3816,9 +3818,10 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
/* unmap chunks if any */
for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
- pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
+ dma_unmap_single(&dev->dev,
+ le32_to_cpu(bd->u.data.chunk_ptr[i]),
le16_to_cpu(bd->u.data.chunk_len[i]),
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
if (txq->txb[txq->q.last_used]) {
libipw_txb_free(txq->txb[txq->q.last_used]);
txq->txb[txq->q.last_used] = NULL;
@@ -3850,8 +3853,8 @@ static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_tx_queue *txq)
}
/* free buffers belonging to queue itself */
- pci_free_consistent(dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd,
- q->dma_addr);
+ dma_free_coherent(&dev->dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd,
+ q->dma_addr);
kfree(txq->txb);
/* 0 fill whole structure */
@@ -5196,8 +5199,8 @@ static void ipw_rx_queue_replenish(void *data)
list_del(element);
rxb->dma_addr =
- pci_map_single(priv->pci_dev, rxb->skb->data,
- IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ dma_map_single(&priv->pci_dev->dev, rxb->skb->data,
+ IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);
list_add_tail(&rxb->list, &rxq->rx_free);
rxq->free_count++;
@@ -5230,8 +5233,9 @@ static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
- IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&priv->pci_dev->dev,
+ rxq->pool[i].dma_addr,
+ IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);
dev_kfree_skb(rxq->pool[i].skb);
}
}
@@ -8263,9 +8267,8 @@ static void ipw_rx(struct ipw_priv *priv)
}
priv->rxq->queue[i] = NULL;
- pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
- IPW_RX_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&priv->pci_dev->dev, rxb->dma_addr,
+ IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);
pkt = (struct ipw_rx_packet *)rxb->skb->data;
IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n",
@@ -8417,8 +8420,8 @@ static void ipw_rx(struct ipw_priv *priv)
rxb->skb = NULL;
}
- pci_unmap_single(priv->pci_dev, rxb->dma_addr,
- IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&priv->pci_dev->dev, rxb->dma_addr,
+ IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);
list_add_tail(&rxb->list, &priv->rxq->rx_used);
i = (i + 1) % RX_QUEUE_SIZE;
@@ -10217,11 +10220,10 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct libipw_txb *txb,
txb->fragments[i]->len - hdr_len);
tfd->u.data.chunk_ptr[i] =
- cpu_to_le32(pci_map_single
- (priv->pci_dev,
- txb->fragments[i]->data + hdr_len,
- txb->fragments[i]->len - hdr_len,
- PCI_DMA_TODEVICE));
+ cpu_to_le32(dma_map_single(&priv->pci_dev->dev,
+ txb->fragments[i]->data + hdr_len,
+ txb->fragments[i]->len - hdr_len,
+ DMA_TO_DEVICE));
tfd->u.data.chunk_len[i] =
cpu_to_le16(txb->fragments[i]->len - hdr_len);
}
@@ -10251,10 +10253,10 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct libipw_txb *txb,
dev_kfree_skb_any(txb->fragments[i]);
txb->fragments[i] = skb;
tfd->u.data.chunk_ptr[i] =
- cpu_to_le32(pci_map_single
- (priv->pci_dev, skb->data,
- remaining_bytes,
- PCI_DMA_TODEVICE));
+ cpu_to_le32(dma_map_single(&priv->pci_dev->dev,
+ skb->data,
+ remaining_bytes,
+ DMA_TO_DEVICE));
le32_add_cpu(&tfd->u.data.num_chunks, 1);
}
@@ -11620,9 +11622,9 @@ static int ipw_pci_probe(struct pci_dev *pdev,
pci_set_master(pdev);
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
goto out_pci_disable_device;
@@ -11838,10 +11840,9 @@ static void ipw_pci_remove(struct pci_dev *pdev)
free_firmware();
}
-#ifdef CONFIG_PM
-static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused ipw_pci_suspend(struct device *dev_d)
{
- struct ipw_priv *priv = pci_get_drvdata(pdev);
+ struct ipw_priv *priv = dev_get_drvdata(dev_d);
struct net_device *dev = priv->net_dev;
printk(KERN_INFO "%s: Going into suspend...\n", dev->name);
@@ -11852,33 +11853,20 @@ static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
/* Remove the PRESENT state of the device */
netif_device_detach(dev);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
priv->suspend_at = ktime_get_boottime_seconds();
return 0;
}
-static int ipw_pci_resume(struct pci_dev *pdev)
+static int __maybe_unused ipw_pci_resume(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct ipw_priv *priv = pci_get_drvdata(pdev);
struct net_device *dev = priv->net_dev;
- int err;
u32 val;
printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
- pci_set_power_state(pdev, PCI_D0);
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
- dev->name);
- return err;
- }
- pci_restore_state(pdev);
-
/*
* Suspend/Resume resets the PCI configuration space, so we have to
* re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -11900,7 +11888,6 @@ static int ipw_pci_resume(struct pci_dev *pdev)
return 0;
}
-#endif
static void ipw_pci_shutdown(struct pci_dev *pdev)
{
@@ -11912,16 +11899,15 @@ static void ipw_pci_shutdown(struct pci_dev *pdev)
pci_disable_device(pdev);
}
+static SIMPLE_DEV_PM_OPS(ipw_pci_pm_ops, ipw_pci_suspend, ipw_pci_resume);
+
/* driver initialization stuff */
static struct pci_driver ipw_driver = {
.name = DRV_NAME,
.id_table = card_ids,
.probe = ipw_pci_probe,
.remove = ipw_pci_remove,
-#ifdef CONFIG_PM
- .suspend = ipw_pci_suspend,
- .resume = ipw_pci_resume,
-#endif
+ .driver.pm = &ipw_pci_pm_ops,
.shutdown = ipw_pci_shutdown,
};
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
index a159d1d18c2c..e73c223a7d28 100644
--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
@@ -1415,7 +1415,7 @@ il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb)
/*
* mac80211 queues, ACs, hardware queues, FIFOs.
*
- * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
+ * Cf. https://wireless.wiki.kernel.org/en/developers/Documentation/mac80211/queues
*
* Mac80211 uses the following numbers, which we get as from it
* by way of skb_get_queue_mapping(skb):
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c
index 0a02d8aca320..1f196665d21f 100644
--- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c
+++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c
@@ -1749,7 +1749,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
u8 done_search = 0;
u16 high_low;
s32 sr;
- u8 tid = MAX_TID_COUNT;
+ u8 tid;
struct il_tid_data *tid_data;
D_RATE("rate scale calculate new rate for skb\n");
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
index 348c17ce72f5..f78e062df572 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -4286,8 +4286,8 @@ il_apm_init(struct il_priv *il)
* power savings, even without L1.
*/
if (il->cfg->set_l0s) {
- pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl);
- if (lctl & PCI_EXP_LNKCTL_ASPM_L1) {
+ ret = pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl);
+ if (!ret && (lctl & PCI_EXP_LNKCTL_ASPM_L1)) {
/* L1-ASPM enabled; disable(!) L0S */
il_set_bit(il, CSR_GIO_REG,
CSR_GIO_REG_VAL_L0S_ENABLED);
diff --git a/drivers/net/wireless/intel/iwlwifi/Kconfig b/drivers/net/wireless/intel/iwlwifi/Kconfig
index 36153fa5f96a..1085afbefba8 100644
--- a/drivers/net/wireless/intel/iwlwifi/Kconfig
+++ b/drivers/net/wireless/intel/iwlwifi/Kconfig
@@ -31,7 +31,7 @@ config IWLWIFI
In order to use this driver, you will need a firmware
image for it. You can obtain the microcode from:
- <http://wireless.kernel.org/en/users/Drivers/iwlwifi>.
+ <https://wireless.wiki.kernel.org/en/users/Drivers/iwlwifi>.
The firmware is typically installed in /lib/firmware. You can
look in the hotplug script /etc/hotplug/firmware.agent to
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h
index 0f4be4be181c..fdcc1292a92b 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h
@@ -1023,7 +1023,7 @@ struct iwl_wep_cmd {
u8 global_key_type;
u8 flags;
u8 reserved;
- struct iwl_wep_key key[0];
+ struct iwl_wep_key key[];
} __packed;
#define WEP_KEY_WEP_TYPE 1
@@ -1305,7 +1305,7 @@ struct iwl_tx_cmd {
* length is 26 or 30 bytes, followed by payload data
*/
u8 payload[0];
- struct ieee80211_hdr hdr[0];
+ struct ieee80211_hdr hdr[];
} __packed;
/*
@@ -2380,7 +2380,7 @@ struct iwl_scan_cmd {
* for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
* before requesting another scan.
*/
- u8 data[0];
+ u8 data[];
} __packed;
/* Can abort will notify by complete notification with abort status. */
@@ -2475,7 +2475,7 @@ struct iwl_tx_beacon_cmd {
__le16 tim_idx;
u8 tim_size;
u8 reserved1;
- struct ieee80211_hdr frame[0]; /* beacon frame */
+ struct ieee80211_hdr frame[]; /* beacon frame */
} __packed;
/******************************************************************************
@@ -3188,7 +3188,7 @@ struct iwl_calib_hdr {
struct iwl_calib_cmd {
struct iwl_calib_hdr hdr;
- u8 data[0];
+ u8 data[];
} __packed;
struct iwl_calib_xtal_freq_cmd {
@@ -3216,7 +3216,7 @@ struct iwl_calib_temperature_offset_v2_cmd {
/* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
struct iwl_calib_chain_noise_reset_cmd {
struct iwl_calib_hdr hdr;
- u8 data[0];
+ u8 data[];
};
/* IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
index 6512d25e3563..423d3c396b2d 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
@@ -200,6 +200,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
iwl_leds_init(priv);
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
+ wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_EXT_KEY_ID);
ret = ieee80211_register_hw(priv->hw);
if (ret) {
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
index fd719c37428c..b6c31f01ea9e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -361,7 +361,7 @@ struct iwl_mcc_update_resp_v3 {
__le16 time;
__le16 geo_info;
__le32 n_channels;
- __le32 channels[0];
+ __le32 channels[];
} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_3 */
/**
@@ -390,7 +390,7 @@ struct iwl_mcc_update_resp {
u8 source_id;
u8 reserved[3];
__le32 n_channels;
- __le32 channels[0];
+ __le32 channels[];
} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_4 */
/**
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
index f1d1fe96fecc..82d59b5a5f8c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
@@ -293,7 +293,7 @@ struct iwl_tx_cmd {
__le16 pm_frame_timeout;
__le16 reserved4;
u8 payload[0];
- struct ieee80211_hdr hdr[0];
+ struct ieee80211_hdr hdr[];
} __packed; /* TX_CMD_API_S_VER_6 */
struct iwl_dram_sec_info {
@@ -319,7 +319,7 @@ struct iwl_tx_cmd_gen2 {
__le32 flags;
struct iwl_dram_sec_info dram_info;
__le32 rate_n_flags;
- struct ieee80211_hdr hdr[0];
+ struct ieee80211_hdr hdr[];
} __packed; /* TX_CMD_API_S_VER_7 */
/**
@@ -342,7 +342,7 @@ struct iwl_tx_cmd_gen3 {
struct iwl_dram_sec_info dram_info;
__le32 rate_n_flags;
__le64 ttl;
- struct ieee80211_hdr hdr[0];
+ struct ieee80211_hdr hdr[];
} __packed; /* TX_CMD_API_S_VER_8 */
/*
@@ -766,8 +766,8 @@ struct iwl_mvm_compressed_ba_notif {
__le32 tx_rate;
__le16 tfd_cnt;
__le16 ra_tid_cnt;
- struct iwl_mvm_compressed_ba_tfd tfd[0];
struct iwl_mvm_compressed_ba_ratid ra_tid[0];
+ struct iwl_mvm_compressed_ba_tfd tfd[];
} __packed; /* COMPRESSED_BA_RES_API_S_VER_4 */
/**
@@ -784,7 +784,7 @@ struct iwl_mac_beacon_cmd_v6 {
__le32 template_id;
__le32 tim_idx;
__le32 tim_size;
- struct ieee80211_hdr frame[0];
+ struct ieee80211_hdr frame[];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_6 */
/**
@@ -805,7 +805,7 @@ struct iwl_mac_beacon_cmd_v7 {
__le32 tim_size;
__le32 ecsa_offset;
__le32 csa_offset;
- struct ieee80211_hdr frame[0];
+ struct ieee80211_hdr frame[];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */
enum iwl_mac_beacon_flags {
@@ -840,7 +840,7 @@ struct iwl_mac_beacon_cmd {
__le32 tim_size;
__le32 ecsa_offset;
__le32 csa_offset;
- struct ieee80211_hdr frame[0];
+ struct ieee80211_hdr frame[];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10 */
struct iwl_beacon_notif {
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 4d3687cc83a4..7ea55cfdd8a8 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -2554,7 +2554,7 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 conf_id)
return -EINVAL;
if (fwrt->dump.conf != FW_DBG_INVALID)
- IWL_WARN(fwrt, "FW already configured (%d) - re-configuring\n",
+ IWL_INFO(fwrt, "FW already configured (%d) - re-configuring\n",
fwrt->dump.conf);
/* Send all HCMDs for configuring the FW debug */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
index 6e72c27f527b..267ad4eddb5c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
@@ -260,7 +260,7 @@ struct hcmd_write_data {
__be32 cmd_id;
__be32 flags;
__be16 length;
- u8 data[0];
+ u8 data[];
} __packed;
static ssize_t iwl_dbgfs_send_hcmd_write(struct iwl_fw_runtime *fwrt, char *buf,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 244899f3f3bf..e27c13263a23 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -641,6 +641,6 @@ extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0;
extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0_long;
extern const struct iwl_cfg iwlax411_2ax_cfg_sosnj_gf4_a0;
extern const struct iwl_cfg iwlax211_cfg_snj_gf_a0;
-#endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */
+#endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 27116c7d3f4f..9ce7207d9ec5 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -480,7 +480,7 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
if (!iwlwifi_mod_params.enable_ini)
return;
- res = request_firmware(&fw, "iwl-debug-yoyo.bin", dev);
+ res = firmware_request_nowarn(&fw, "iwl-debug-yoyo.bin", dev);
if (res)
return;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
index 3008a5246be8..b35b8920941b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
@@ -175,7 +175,7 @@ void iwl_opmode_deregister(const char *name);
struct iwl_op_mode {
const struct iwl_op_mode_ops *ops;
- char op_mode_specific[0] __aligned(sizeof(void *));
+ char op_mode_specific[] __aligned(sizeof(void *));
};
static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index a301e2484cdb..34788e7afc7b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -1006,7 +1006,7 @@ struct iwl_trans {
/* pointer to trans specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */
- char trans_specific[0] __aligned(sizeof(void *));
+ char trans_specific[] __aligned(sizeof(void *));
};
const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 77916231ff7d..9374c85c5caf 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -543,6 +543,14 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
+
+ /* The new Tx API does not allow to pass the key or keyid of a MPDU to
+ * the hw, preventing us to control which key(id) to use per MPDU.
+ * Till that's fixed we can't use Extended Key ID for the newer cards.
+ */
+ if (!iwl_mvm_has_new_tx_api(mvm))
+ wiphy_ext_feature_set(hw->wiphy,
+ NL80211_EXT_FEATURE_EXT_KEY_ID);
hw->wiphy->features |= NL80211_FEATURE_HT_IBSS;
hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
@@ -4903,7 +4911,7 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
if (mvmsta->avg_energy) {
- sinfo->signal_avg = mvmsta->avg_energy;
+ sinfo->signal_avg = -(s8)mvmsta->avg_energy;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index a7264b282d79..86b2ebb5d5fb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -603,7 +603,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
struct iwl_lq_sta *lq_data, u8 tid,
struct ieee80211_sta *sta)
{
- int ret = -EAGAIN;
+ int ret;
IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 27977992fd7f..9e124755a3ce 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1367,14 +1367,6 @@ out_err:
return ret;
}
-static inline u8 iwl_mvm_tid_to_ac_queue(int tid)
-{
- if (tid == IWL_MAX_TID_COUNT)
- return IEEE80211_AC_VO; /* MGMT */
-
- return tid_to_mac80211_ac[tid];
-}
-
void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk)
{
struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm,
diff --git a/drivers/net/wireless/intersil/Kconfig b/drivers/net/wireless/intersil/Kconfig
index 6a6ce9d4aeee..c52d9b535623 100644
--- a/drivers/net/wireless/intersil/Kconfig
+++ b/drivers/net/wireless/intersil/Kconfig
@@ -30,7 +30,7 @@ config PRISM54
For more information refer to the p54 wiki:
- http://wireless.kernel.org/en/users/Drivers/p54
+ http://wireless.wiki.kernel.org/en/users/Drivers/p54
Note: You need a motherboard with DMA support to use any of these cards
diff --git a/drivers/net/wireless/intersil/hostap/hostap_hw.c b/drivers/net/wireless/intersil/hostap/hostap_hw.c
index 2ab34cf74ecc..b6c497ce12e1 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_hw.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_hw.c
@@ -3366,8 +3366,8 @@ static void prism2_free_local_data(struct net_device *dev)
}
-#if (defined(PRISM2_PCI) && defined(CONFIG_PM)) || defined(PRISM2_PCCARD)
-static void prism2_suspend(struct net_device *dev)
+#if defined(PRISM2_PCI) || defined(PRISM2_PCCARD)
+static void __maybe_unused prism2_suspend(struct net_device *dev)
{
struct hostap_interface *iface;
struct local_info *local;
@@ -3385,7 +3385,7 @@ static void prism2_suspend(struct net_device *dev)
/* Disable hardware and firmware */
prism2_hw_shutdown(dev, 0);
}
-#endif /* (PRISM2_PCI && CONFIG_PM) || PRISM2_PCCARD */
+#endif /* PRISM2_PCI || PRISM2_PCCARD */
/* These might at some point be compiled separately and used as separate
diff --git a/drivers/net/wireless/intersil/hostap/hostap_pci.c b/drivers/net/wireless/intersil/hostap/hostap_pci.c
index 0c2aa880e32a..101887e6bd0f 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_pci.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_pci.c
@@ -403,36 +403,23 @@ static void prism2_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-
-#ifdef CONFIG_PM
-static int prism2_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused prism2_pci_suspend(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
if (netif_running(dev)) {
netif_stop_queue(dev);
netif_device_detach(dev);
}
prism2_suspend(dev);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
return 0;
}
-static int prism2_pci_resume(struct pci_dev *pdev)
+static int __maybe_unused prism2_pci_resume(struct device *dev_d)
{
- struct net_device *dev = pci_get_drvdata(pdev);
- int err;
-
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
- dev->name);
- return err;
- }
- pci_restore_state(pdev);
+ struct net_device *dev = dev_get_drvdata(dev_d);
+
prism2_hw_config(dev, 0);
if (netif_running(dev)) {
netif_device_attach(dev);
@@ -441,20 +428,19 @@ static int prism2_pci_resume(struct pci_dev *pdev)
return 0;
}
-#endif /* CONFIG_PM */
-
MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
+static SIMPLE_DEV_PM_OPS(prism2_pci_pm_ops,
+ prism2_pci_suspend,
+ prism2_pci_resume);
+
static struct pci_driver prism2_pci_driver = {
.name = "hostap_pci",
.id_table = prism2_pci_id_table,
.probe = prism2_pci_probe,
.remove = prism2_pci_remove,
-#ifdef CONFIG_PM
- .suspend = prism2_pci_suspend,
- .resume = prism2_pci_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &prism2_pci_pm_ops,
};
module_pci_driver(prism2_pci_driver);
diff --git a/drivers/net/wireless/intersil/orinoco/Kconfig b/drivers/net/wireless/intersil/orinoco/Kconfig
index c470ee23673f..f62730aa7be3 100644
--- a/drivers/net/wireless/intersil/orinoco/Kconfig
+++ b/drivers/net/wireless/intersil/orinoco/Kconfig
@@ -27,7 +27,7 @@ config HERMES
You will also very likely also need the Wireless Tools in order to
configure your card and that /etc/pcmcia/wireless.opts works :
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
+ <https://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
config HERMES_PRISM
bool "Support Prism 2/2.5 chipset"
@@ -120,7 +120,7 @@ config PCMCIA_HERMES
You will very likely need the Wireless Tools in order to
configure your card and that /etc/pcmcia/wireless.opts works:
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+ <https://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
config PCMCIA_SPECTRUM
tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_nortel.c b/drivers/net/wireless/intersil/orinoco/orinoco_nortel.c
index 048693b6c6c2..96a03d10a080 100644
--- a/drivers/net/wireless/intersil/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/intersil/orinoco/orinoco_nortel.c
@@ -290,8 +290,7 @@ static struct pci_driver orinoco_nortel_driver = {
.id_table = orinoco_nortel_id_table,
.probe = orinoco_nortel_init_one,
.remove = orinoco_nortel_remove_one,
- .suspend = orinoco_pci_suspend,
- .resume = orinoco_pci_resume,
+ .driver.pm = &orinoco_pci_pm_ops,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_pci.c b/drivers/net/wireless/intersil/orinoco/orinoco_pci.c
index 4938a2208a37..f3c86b07b1b9 100644
--- a/drivers/net/wireless/intersil/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/intersil/orinoco/orinoco_pci.c
@@ -230,8 +230,7 @@ static struct pci_driver orinoco_pci_driver = {
.id_table = orinoco_pci_id_table,
.probe = orinoco_pci_init_one,
.remove = orinoco_pci_remove_one,
- .suspend = orinoco_pci_suspend,
- .resume = orinoco_pci_resume,
+ .driver.pm = &orinoco_pci_pm_ops,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_pci.h b/drivers/net/wireless/intersil/orinoco/orinoco_pci.h
index 43f5b9f5a0b0..d49d940864b4 100644
--- a/drivers/net/wireless/intersil/orinoco/orinoco_pci.h
+++ b/drivers/net/wireless/intersil/orinoco/orinoco_pci.h
@@ -18,51 +18,37 @@ struct orinoco_pci_card {
void __iomem *attr_io;
};
-#ifdef CONFIG_PM
-static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused orinoco_pci_suspend(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct orinoco_private *priv = pci_get_drvdata(pdev);
orinoco_down(priv);
free_irq(pdev->irq, priv);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
return 0;
}
-static int orinoco_pci_resume(struct pci_dev *pdev)
+static int __maybe_unused orinoco_pci_resume(struct device *dev_d)
{
+ struct pci_dev *pdev = to_pci_dev(dev_d);
struct orinoco_private *priv = pci_get_drvdata(pdev);
struct net_device *dev = priv->ndev;
int err;
- pci_set_power_state(pdev, PCI_D0);
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
- dev->name);
- return err;
- }
- pci_restore_state(pdev);
-
err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
dev->name, priv);
if (err) {
printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
dev->name);
- pci_disable_device(pdev);
return -EBUSY;
}
- err = orinoco_up(priv);
-
- return err;
+ return orinoco_up(priv);
}
-#else
-#define orinoco_pci_suspend NULL
-#define orinoco_pci_resume NULL
-#endif
+
+static SIMPLE_DEV_PM_OPS(orinoco_pci_pm_ops,
+ orinoco_pci_suspend,
+ orinoco_pci_resume);
#endif /* _ORINOCO_PCI_H */
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_plx.c b/drivers/net/wireless/intersil/orinoco/orinoco_plx.c
index 221352027779..16dada94c774 100644
--- a/drivers/net/wireless/intersil/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/intersil/orinoco/orinoco_plx.c
@@ -336,8 +336,7 @@ static struct pci_driver orinoco_plx_driver = {
.id_table = orinoco_plx_id_table,
.probe = orinoco_plx_init_one,
.remove = orinoco_plx_remove_one,
- .suspend = orinoco_pci_suspend,
- .resume = orinoco_pci_resume,
+ .driver.pm = &orinoco_pci_pm_ops,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_tmd.c b/drivers/net/wireless/intersil/orinoco/orinoco_tmd.c
index 20ce569b8a43..9a9d335611ac 100644
--- a/drivers/net/wireless/intersil/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/intersil/orinoco/orinoco_tmd.c
@@ -213,8 +213,7 @@ static struct pci_driver orinoco_tmd_driver = {
.id_table = orinoco_tmd_id_table,
.probe = orinoco_tmd_init_one,
.remove = orinoco_tmd_remove_one,
- .suspend = orinoco_pci_suspend,
- .resume = orinoco_pci_resume,
+ .driver.pm = &orinoco_pci_pm_ops,
};
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
index 651c676b5506..11fa38fedd87 100644
--- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
@@ -158,7 +158,7 @@ MODULE_FIRMWARE("orinoco_ezusb_fw");
#define EZUSB_REQUEST_FW_TRANS 0xA0
-#define EZUSB_REQUEST_TRIGER 0xAA
+#define EZUSB_REQUEST_TRIGGER 0xAA
#define EZUSB_REQUEST_TRIG_AC 0xAC
#define EZUSB_CPUCS_REG 0x7F92
@@ -1318,12 +1318,12 @@ static int ezusb_hard_reset(struct orinoco_private *priv)
netdev_dbg(upriv->dev, "sending control message\n");
retval = usb_control_msg(upriv->udev,
usb_sndctrlpipe(upriv->udev, 0),
- EZUSB_REQUEST_TRIGER,
+ EZUSB_REQUEST_TRIGGER,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_DIR_OUT, 0x0, 0x0, NULL, 0,
DEF_TIMEOUT);
if (retval < 0) {
- err("EZUSB_REQUEST_TRIGER failed retval %d", retval);
+ err("EZUSB_REQUEST_TRIGGER failed retval %d", retval);
return retval;
}
#if 0
diff --git a/drivers/net/wireless/intersil/p54/Kconfig b/drivers/net/wireless/intersil/p54/Kconfig
index 024be5507daf..003c378ed131 100644
--- a/drivers/net/wireless/intersil/p54/Kconfig
+++ b/drivers/net/wireless/intersil/p54/Kconfig
@@ -10,7 +10,7 @@ config P54_COMMON
also need to be enabled in order to support any devices.
These devices require softmac firmware which can be found at
- <http://wireless.kernel.org/en/users/Drivers/p54>
+ <http://wireless.wiki.kernel.org/en/users/Drivers/p54>
If you choose to build a module, it'll be called p54common.
@@ -22,7 +22,7 @@ config P54_USB
This driver is for USB isl38xx based wireless cards.
These devices require softmac firmware which can be found at
- <http://wireless.kernel.org/en/users/Drivers/p54>
+ <http://wireless.wiki.kernel.org/en/users/Drivers/p54>
If you choose to build a module, it'll be called p54usb.
@@ -36,7 +36,7 @@ config P54_PCI
supported by the fullmac driver/firmware.
This driver requires softmac firmware which can be found at
- <http://wireless.kernel.org/en/users/Drivers/p54>
+ <http://wireless.wiki.kernel.org/en/users/Drivers/p54>
If you choose to build a module, it'll be called p54pci.
diff --git a/drivers/net/wireless/intersil/p54/fwio.c b/drivers/net/wireless/intersil/p54/fwio.c
index a5afcc865196..bece14e4ff0d 100644
--- a/drivers/net/wireless/intersil/p54/fwio.c
+++ b/drivers/net/wireless/intersil/p54/fwio.c
@@ -132,7 +132,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
if (priv->fw_var < 0x500)
wiphy_info(priv->hw->wiphy,
"you are using an obsolete firmware. "
- "visit http://wireless.kernel.org/en/users/Drivers/p54 "
+ "visit http://wireless.wiki.kernel.org/en/users/Drivers/p54 "
"and grab one for \"kernel >= 2.6.28\"!\n");
if (priv->fw_var >= 0x300) {
diff --git a/drivers/net/wireless/intersil/p54/p54pci.c b/drivers/net/wireless/intersil/p54/p54pci.c
index 80ad0b7eaef4..9d96c8b8409d 100644
--- a/drivers/net/wireless/intersil/p54/p54pci.c
+++ b/drivers/net/wireless/intersil/p54/p54pci.c
@@ -153,12 +153,12 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
if (!skb)
break;
- mapping = pci_map_single(priv->pdev,
+ mapping = dma_map_single(&priv->pdev->dev,
skb_tail_pointer(skb),
priv->common.rx_mtu + 32,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
- if (pci_dma_mapping_error(priv->pdev, mapping)) {
+ if (dma_mapping_error(&priv->pdev->dev, mapping)) {
dev_kfree_skb_any(skb);
dev_err(&priv->pdev->dev,
"RX DMA Mapping error\n");
@@ -215,19 +215,22 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
len = priv->common.rx_mtu;
}
dma_addr = le32_to_cpu(desc->host_addr);
- pci_dma_sync_single_for_cpu(priv->pdev, dma_addr,
- priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&priv->pdev->dev, dma_addr,
+ priv->common.rx_mtu + 32,
+ DMA_FROM_DEVICE);
skb_put(skb, len);
if (p54_rx(dev, skb)) {
- pci_unmap_single(priv->pdev, dma_addr,
- priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&priv->pdev->dev, dma_addr,
+ priv->common.rx_mtu + 32,
+ DMA_FROM_DEVICE);
rx_buf[i] = NULL;
desc->host_addr = cpu_to_le32(0);
} else {
skb_trim(skb, 0);
- pci_dma_sync_single_for_device(priv->pdev, dma_addr,
- priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&priv->pdev->dev, dma_addr,
+ priv->common.rx_mtu + 32,
+ DMA_FROM_DEVICE);
desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
}
@@ -258,8 +261,9 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
skb = tx_buf[i];
tx_buf[i] = NULL;
- pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
- le16_to_cpu(desc->len), PCI_DMA_TODEVICE);
+ dma_unmap_single(&priv->pdev->dev,
+ le32_to_cpu(desc->host_addr),
+ le16_to_cpu(desc->len), DMA_TO_DEVICE);
desc->host_addr = 0;
desc->device_addr = 0;
@@ -334,9 +338,9 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
idx = le32_to_cpu(ring_control->host_idx[1]);
i = idx % ARRAY_SIZE(ring_control->tx_data);
- mapping = pci_map_single(priv->pdev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(priv->pdev, mapping)) {
+ mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&priv->pdev->dev, mapping)) {
spin_unlock_irqrestore(&priv->lock, flags);
p54_free_skb(dev, skb);
dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
@@ -378,10 +382,10 @@ static void p54p_stop(struct ieee80211_hw *dev)
for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {
desc = &ring_control->rx_data[i];
if (desc->host_addr)
- pci_unmap_single(priv->pdev,
+ dma_unmap_single(&priv->pdev->dev,
le32_to_cpu(desc->host_addr),
priv->common.rx_mtu + 32,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
kfree_skb(priv->rx_buf_data[i]);
priv->rx_buf_data[i] = NULL;
}
@@ -389,10 +393,10 @@ static void p54p_stop(struct ieee80211_hw *dev)
for (i = 0; i < ARRAY_SIZE(priv->rx_buf_mgmt); i++) {
desc = &ring_control->rx_mgmt[i];
if (desc->host_addr)
- pci_unmap_single(priv->pdev,
+ dma_unmap_single(&priv->pdev->dev,
le32_to_cpu(desc->host_addr),
priv->common.rx_mtu + 32,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
kfree_skb(priv->rx_buf_mgmt[i]);
priv->rx_buf_mgmt[i] = NULL;
}
@@ -400,10 +404,10 @@ static void p54p_stop(struct ieee80211_hw *dev)
for (i = 0; i < ARRAY_SIZE(priv->tx_buf_data); i++) {
desc = &ring_control->tx_data[i];
if (desc->host_addr)
- pci_unmap_single(priv->pdev,
+ dma_unmap_single(&priv->pdev->dev,
le32_to_cpu(desc->host_addr),
le16_to_cpu(desc->len),
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
p54_free_skb(dev, priv->tx_buf_data[i]);
priv->tx_buf_data[i] = NULL;
@@ -412,10 +416,10 @@ static void p54p_stop(struct ieee80211_hw *dev)
for (i = 0; i < ARRAY_SIZE(priv->tx_buf_mgmt); i++) {
desc = &ring_control->tx_mgmt[i];
if (desc->host_addr)
- pci_unmap_single(priv->pdev,
+ dma_unmap_single(&priv->pdev->dev,
le32_to_cpu(desc->host_addr),
le16_to_cpu(desc->len),
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
p54_free_skb(dev, priv->tx_buf_mgmt[i]);
priv->tx_buf_mgmt[i] = NULL;
@@ -568,9 +572,9 @@ static int p54p_probe(struct pci_dev *pdev,
goto err_disable_dev;
}
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "No suitable DMA available\n");
goto err_free_reg;
@@ -603,8 +607,9 @@ static int p54p_probe(struct pci_dev *pdev,
goto err_free_dev;
}
- priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
- &priv->ring_control_dma);
+ priv->ring_control = dma_alloc_coherent(&pdev->dev,
+ sizeof(*priv->ring_control),
+ &priv->ring_control_dma, GFP_KERNEL);
if (!priv->ring_control) {
dev_err(&pdev->dev, "Cannot allocate rings\n");
err = -ENOMEM;
@@ -623,8 +628,8 @@ static int p54p_probe(struct pci_dev *pdev,
if (!err)
return 0;
- pci_free_consistent(pdev, sizeof(*priv->ring_control),
- priv->ring_control, priv->ring_control_dma);
+ dma_free_coherent(&pdev->dev, sizeof(*priv->ring_control),
+ priv->ring_control, priv->ring_control_dma);
err_iounmap:
iounmap(priv->map);
@@ -653,8 +658,8 @@ static void p54p_remove(struct pci_dev *pdev)
wait_for_completion(&priv->fw_loaded);
p54_unregister_common(dev);
release_firmware(priv->firmware);
- pci_free_consistent(pdev, sizeof(*priv->ring_control),
- priv->ring_control, priv->ring_control_dma);
+ dma_free_coherent(&pdev->dev, sizeof(*priv->ring_control),
+ priv->ring_control, priv->ring_control_dma);
iounmap(priv->map);
pci_release_regions(pdev);
pci_disable_device(pdev);
diff --git a/drivers/net/wireless/intersil/p54/p54usb.c b/drivers/net/wireless/intersil/p54/p54usb.c
index ff0e30c0c14c..cae47663b17b 100644
--- a/drivers/net/wireless/intersil/p54/p54usb.c
+++ b/drivers/net/wireless/intersil/p54/p54usb.c
@@ -36,7 +36,7 @@ static struct usb_driver p54u_driver;
* Note:
*
* Always update our wiki's device list (located at:
- * http://wireless.kernel.org/en/users/Drivers/p54/devices ),
+ * http://wireless.wiki.kernel.org/en/users/Drivers/p54/devices ),
* whenever you add a new device.
*/
diff --git a/drivers/net/wireless/intersil/prism54/isl_oid.h b/drivers/net/wireless/intersil/prism54/isl_oid.h
index 1afc2ccf94ca..b889bb73a485 100644
--- a/drivers/net/wireless/intersil/prism54/isl_oid.h
+++ b/drivers/net/wireless/intersil/prism54/isl_oid.h
@@ -143,7 +143,7 @@ enum dot11_priv_t {
* together with a CSMA contention. Without this all frames are
* sent with a CSMA contention.
* Bibliography:
- * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Papers/Packet.Frame.Grouping.html
+ * https://www.hpl.hp.com/personal/Jean_Tourrilhes/Papers/Packet.Frame.Grouping.html
*/
enum dot11_maxframeburst_t {
/* Values for DOT11_OID_MAXFRAMEBURST */
diff --git a/drivers/net/wireless/intersil/prism54/islpci_dev.c b/drivers/net/wireless/intersil/prism54/islpci_dev.c
index a9bae69222dc..efd64e555bb5 100644
--- a/drivers/net/wireless/intersil/prism54/islpci_dev.c
+++ b/drivers/net/wireless/intersil/prism54/islpci_dev.c
@@ -636,10 +636,10 @@ islpci_alloc_memory(islpci_private *priv)
*/
/* perform the allocation */
- priv->driver_mem_address = pci_alloc_consistent(priv->pdev,
- HOST_MEM_BLOCK,
- &priv->
- device_host_address);
+ priv->driver_mem_address = dma_alloc_coherent(&priv->pdev->dev,
+ HOST_MEM_BLOCK,
+ &priv->device_host_address,
+ GFP_KERNEL);
if (!priv->driver_mem_address) {
/* error allocating the block of PCI memory */
@@ -692,11 +692,9 @@ islpci_alloc_memory(islpci_private *priv)
/* map the allocated skb data area to pci */
priv->pci_map_rx_address[counter] =
- pci_map_single(priv->pdev, (void *) skb->data,
- MAX_FRAGMENT_SIZE_RX + 2,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(priv->pdev,
- priv->pci_map_rx_address[counter])) {
+ dma_map_single(&priv->pdev->dev, (void *)skb->data,
+ MAX_FRAGMENT_SIZE_RX + 2, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&priv->pdev->dev, priv->pci_map_rx_address[counter])) {
priv->pci_map_rx_address[counter] = 0;
/* error mapping the buffer to device
accessible memory address */
@@ -727,9 +725,9 @@ islpci_free_memory(islpci_private *priv)
/* free consistent DMA area... */
if (priv->driver_mem_address)
- pci_free_consistent(priv->pdev, HOST_MEM_BLOCK,
- priv->driver_mem_address,
- priv->device_host_address);
+ dma_free_coherent(&priv->pdev->dev, HOST_MEM_BLOCK,
+ priv->driver_mem_address,
+ priv->device_host_address);
/* clear some dangling pointers */
priv->driver_mem_address = NULL;
@@ -741,8 +739,8 @@ islpci_free_memory(islpci_private *priv)
for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) {
struct islpci_membuf *buf = &priv->mgmt_rx[counter];
if (buf->pci_addr)
- pci_unmap_single(priv->pdev, buf->pci_addr,
- buf->size, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&priv->pdev->dev, buf->pci_addr,
+ buf->size, DMA_FROM_DEVICE);
buf->pci_addr = 0;
kfree(buf->mem);
buf->size = 0;
@@ -752,10 +750,10 @@ islpci_free_memory(islpci_private *priv)
/* clean up data rx buffers */
for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) {
if (priv->pci_map_rx_address[counter])
- pci_unmap_single(priv->pdev,
+ dma_unmap_single(&priv->pdev->dev,
priv->pci_map_rx_address[counter],
MAX_FRAGMENT_SIZE_RX + 2,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
priv->pci_map_rx_address[counter] = 0;
if (priv->data_low_rx[counter])
diff --git a/drivers/net/wireless/intersil/prism54/islpci_eth.c b/drivers/net/wireless/intersil/prism54/islpci_eth.c
index 8d680250a281..74dd65716afd 100644
--- a/drivers/net/wireless/intersil/prism54/islpci_eth.c
+++ b/drivers/net/wireless/intersil/prism54/islpci_eth.c
@@ -50,9 +50,9 @@ islpci_eth_cleanup_transmit(islpci_private *priv,
skb, skb->data, skb->len, skb->truesize);
#endif
- pci_unmap_single(priv->pdev,
+ dma_unmap_single(&priv->pdev->dev,
priv->pci_map_tx_address[index],
- skb->len, PCI_DMA_TODEVICE);
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_irq(skb);
skb = NULL;
}
@@ -176,10 +176,9 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
#endif
/* map the skb buffer to pci memory for DMA operation */
- pci_map_address = pci_map_single(priv->pdev,
- (void *) skb->data, skb->len,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(priv->pdev, pci_map_address)) {
+ pci_map_address = dma_map_single(&priv->pdev->dev, (void *)skb->data,
+ skb->len, DMA_TO_DEVICE);
+ if (dma_mapping_error(&priv->pdev->dev, pci_map_address)) {
printk(KERN_WARNING "%s: cannot map buffer to PCI\n",
ndev->name);
goto drop_free;
@@ -323,9 +322,8 @@ islpci_eth_receive(islpci_private *priv)
#endif
/* delete the streaming DMA mapping before processing the skb */
- pci_unmap_single(priv->pdev,
- priv->pci_map_rx_address[index],
- MAX_FRAGMENT_SIZE_RX + 2, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&priv->pdev->dev, priv->pci_map_rx_address[index],
+ MAX_FRAGMENT_SIZE_RX + 2, DMA_FROM_DEVICE);
/* update the skb structure and align the buffer */
skb_put(skb, size);
@@ -431,11 +429,9 @@ islpci_eth_receive(islpci_private *priv)
/* set the streaming DMA mapping for proper PCI bus operation */
priv->pci_map_rx_address[index] =
- pci_map_single(priv->pdev, (void *) skb->data,
- MAX_FRAGMENT_SIZE_RX + 2,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(priv->pdev,
- priv->pci_map_rx_address[index])) {
+ dma_map_single(&priv->pdev->dev, (void *)skb->data,
+ MAX_FRAGMENT_SIZE_RX + 2, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&priv->pdev->dev, priv->pci_map_rx_address[index])) {
/* error mapping the buffer to device accessible memory address */
DEBUG(SHOW_ERROR_MESSAGES,
"Error mapping DMA address\n");
diff --git a/drivers/net/wireless/intersil/prism54/islpci_hotplug.c b/drivers/net/wireless/intersil/prism54/islpci_hotplug.c
index 20291c0d962d..31a1e61326ff 100644
--- a/drivers/net/wireless/intersil/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/intersil/prism54/islpci_hotplug.c
@@ -26,7 +26,8 @@ module_param(init_pcitm, int, 0);
/* In this order: vendor, device, subvendor, subdevice, class, class_mask,
* driver_data
* If you have an update for this please contact prism54-devel@prism54.org
- * The latest list can be found at http://wireless.kernel.org/en/users/Drivers/p54 */
+ * The latest list can be found at http://wireless.wiki.kernel.org/en/users/Drivers/p54
+ */
static const struct pci_device_id prism54_id_tbl[] = {
/* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
{
@@ -63,16 +64,17 @@ MODULE_DEVICE_TABLE(pci, prism54_id_tbl);
static int prism54_probe(struct pci_dev *, const struct pci_device_id *);
static void prism54_remove(struct pci_dev *);
-static int prism54_suspend(struct pci_dev *, pm_message_t state);
-static int prism54_resume(struct pci_dev *);
+static int __maybe_unused prism54_suspend(struct device *);
+static int __maybe_unused prism54_resume(struct device *);
+
+static SIMPLE_DEV_PM_OPS(prism54_pm_ops, prism54_suspend, prism54_resume);
static struct pci_driver prism54_driver = {
.name = DRV_NAME,
.id_table = prism54_id_tbl,
.probe = prism54_probe,
.remove = prism54_remove,
- .suspend = prism54_suspend,
- .resume = prism54_resume,
+ .driver.pm = &prism54_pm_ops,
};
/******************************************************************************
@@ -106,7 +108,7 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* enable PCI DMA */
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME);
goto do_pci_disable_device;
}
@@ -243,16 +245,13 @@ prism54_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-static int
-prism54_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused
+prism54_suspend(struct device *dev)
{
- struct net_device *ndev = pci_get_drvdata(pdev);
+ struct net_device *ndev = dev_get_drvdata(dev);
islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
BUG_ON(!priv);
-
- pci_save_state(pdev);
-
/* tell the device not to trigger interrupts for now... */
isl38xx_disable_interrupts(priv->device_base);
@@ -266,26 +265,16 @@ prism54_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-static int
-prism54_resume(struct pci_dev *pdev)
+static int __maybe_unused
+prism54_resume(struct device *dev)
{
- struct net_device *ndev = pci_get_drvdata(pdev);
+ struct net_device *ndev = dev_get_drvdata(dev);
islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
- int err;
BUG_ON(!priv);
printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
- ndev->name);
- return err;
- }
-
- pci_restore_state(pdev);
-
/* alright let's go into the PREBOOT state */
islpci_reset(priv, 1);
diff --git a/drivers/net/wireless/intersil/prism54/islpci_mgt.c b/drivers/net/wireless/intersil/prism54/islpci_mgt.c
index e336eb106429..0c7fb76c7d1c 100644
--- a/drivers/net/wireless/intersil/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/intersil/prism54/islpci_mgt.c
@@ -115,10 +115,11 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
buf->size = MGMT_FRAME_SIZE;
}
if (buf->pci_addr == 0) {
- buf->pci_addr = pci_map_single(priv->pdev, buf->mem,
+ buf->pci_addr = dma_map_single(&priv->pdev->dev,
+ buf->mem,
MGMT_FRAME_SIZE,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(priv->pdev, buf->pci_addr)) {
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&priv->pdev->dev, buf->pci_addr)) {
printk(KERN_WARNING
"Failed to make memory DMA'able.\n");
return -ENOMEM;
@@ -203,9 +204,9 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
#endif
err = -ENOMEM;
- buf.pci_addr = pci_map_single(priv->pdev, buf.mem, frag_len,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(priv->pdev, buf.pci_addr)) {
+ buf.pci_addr = dma_map_single(&priv->pdev->dev, buf.mem, frag_len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&priv->pdev->dev, buf.pci_addr)) {
printk(KERN_WARNING "%s: cannot map PCI memory for mgmt\n",
ndev->name);
goto error_free;
@@ -302,8 +303,8 @@ islpci_mgt_receive(struct net_device *ndev)
}
/* Ensure the results of device DMA are visible to the CPU. */
- pci_dma_sync_single_for_cpu(priv->pdev, buf->pci_addr,
- buf->size, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&priv->pdev->dev, buf->pci_addr,
+ buf->size, DMA_FROM_DEVICE);
/* Perform endianess conversion for PIMFOR header in-place. */
header = pimfor_decode_header(buf->mem, frag_len);
@@ -414,8 +415,8 @@ islpci_mgt_cleanup_transmit(struct net_device *ndev)
for (; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) {
int index = priv->index_mgmt_tx % ISL38XX_CB_MGMT_QSIZE;
struct islpci_membuf *buf = &priv->mgmt_tx[index];
- pci_unmap_single(priv->pdev, buf->pci_addr, buf->size,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&priv->pdev->dev, buf->pci_addr, buf->size,
+ DMA_TO_DEVICE);
buf->pci_addr = 0;
kfree(buf->mem);
buf->mem = NULL;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 1356e8cbe617..9dd9d73f4484 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -4334,7 +4334,7 @@ static int __init init_mac80211_hwsim(void)
break;
case HWSIM_REGTEST_STRICT_ALL:
param.reg_strict = true;
- /* fall through */
+ fallthrough;
case HWSIM_REGTEST_DRIVER_REG_ALL:
param.reg_alpha2 = hwsim_alpha2s[0];
break;
diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
index 0bdafe9f66db..1046b59647f5 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
@@ -398,7 +398,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
new_node->rx_reorder_ptr = kcalloc(win_size, sizeof(void *),
GFP_KERNEL);
if (!new_node->rx_reorder_ptr) {
- kfree((u8 *) new_node);
+ kfree(new_node);
mwifiex_dbg(priv->adapter, ERROR,
"%s: failed to alloc reorder_ptr\n", __func__);
return;
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 4e4f59c17ded..96848fa0e417 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -27,7 +27,8 @@ module_param(reg_alpha2, charp, 0);
static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
{
- .max = 3, .types = BIT(NL80211_IFTYPE_STATION) |
+ .max = MWIFIEX_MAX_BSS_NUM,
+ .types = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_AP),
@@ -3726,11 +3727,11 @@ mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
int ret;
if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
/* make sure we are in station mode and connected */
if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
switch (action_code) {
case WLAN_TDLS_SETUP_REQUEST:
@@ -3798,11 +3799,11 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
!(wiphy->flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
/* make sure we are in station mode and connected */
if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
mwifiex_dbg(priv->adapter, MSG,
"TDLS peer=%pM, oper=%d\n", peer, action);
@@ -3832,7 +3833,7 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
default:
mwifiex_dbg(priv->adapter, ERROR,
"tdls_oper: operation not supported\n");
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
return mwifiex_tdls_oper(priv, peer, action);
@@ -3913,11 +3914,11 @@ mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev,
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
/* make sure we are in station mode and connected */
if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
return mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CREATE_LINK);
}
@@ -4150,11 +4151,11 @@ mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
/* we support change_station handler only for TDLS peers*/
if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
/* make sure we are in station mode and connected */
if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
priv->sta_params = params;
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index 529099137644..9ee5600351a7 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -953,7 +953,7 @@ int mwifiex_set_mac_address(struct mwifiex_private *priv,
} else {
/* Internal mac address change */
if (priv->bss_type == MWIFIEX_BSS_TYPE_ANY)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
mac_addr = old_mac_addr;
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h
index 71cd8629b28e..8b476b007c5e 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.h
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.h
@@ -36,9 +36,9 @@
#define SD8897_DEFAULT_FW_NAME "mrvl/sd8897_uapsta.bin"
#define SD8887_DEFAULT_FW_NAME "mrvl/sd8887_uapsta.bin"
#define SD8801_DEFAULT_FW_NAME "mrvl/sd8801_uapsta.bin"
-#define SD8977_DEFAULT_FW_NAME "mrvl/sd8977_uapsta.bin"
+#define SD8977_DEFAULT_FW_NAME "mrvl/sdsd8977_combo_v2.bin"
#define SD8987_DEFAULT_FW_NAME "mrvl/sd8987_uapsta.bin"
-#define SD8997_DEFAULT_FW_NAME "mrvl/sd8997_uapsta.bin"
+#define SD8997_DEFAULT_FW_NAME "mrvl/sdsd8997_combo_v4.bin"
#define BLOCK_MODE 1
#define BYTE_MODE 0
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index 8bd355d7974e..d3a968ef21ef 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -1723,7 +1723,7 @@ mwifiex_cmd_tdls_config(struct mwifiex_private *priv,
default:
mwifiex_dbg(priv->adapter, ERROR,
"Unknown TDLS configuration\n");
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
le16_unaligned_add_cpu(&cmd->size, len);
@@ -1849,7 +1849,7 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
break;
default:
mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS operation\n");
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
le16_unaligned_add_cpu(&cmd->size, config_len);
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
index f21660149f58..962d8bfe6f10 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
@@ -580,6 +580,11 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv,
{
struct host_cmd_ds_802_11_key_material *key =
&resp->params.key_material;
+ int len;
+
+ len = le16_to_cpu(key->key_param_set.key_len);
+ if (len > sizeof(key->key_param_set.key))
+ return -EINVAL;
if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) {
@@ -593,9 +598,8 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv,
memset(priv->aes_key.key_param_set.key, 0,
sizeof(key->key_param_set.key));
- priv->aes_key.key_param_set.key_len = key->key_param_set.key_len;
- memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key,
- le16_to_cpu(priv->aes_key.key_param_set.key_len));
+ priv->aes_key.key_param_set.key_len = cpu_to_le16(len);
+ memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key, len);
return 0;
}
@@ -610,9 +614,14 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp)
{
struct host_cmd_ds_802_11_key_material_v2 *key_v2;
- __le16 len;
+ int len;
key_v2 = &resp->params.key_material_v2;
+
+ len = le16_to_cpu(key_v2->key_param_set.key_params.aes.key_len);
+ if (len > WLAN_KEY_LEN_CCMP)
+ return -EINVAL;
+
if (le16_to_cpu(key_v2->action) == HostCmd_ACT_GEN_SET) {
if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) {
mwifiex_dbg(priv->adapter, INFO, "info: key: GTK is set\n");
@@ -628,10 +637,9 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0,
WLAN_KEY_LEN_CCMP);
priv->aes_key_v2.key_param_set.key_params.aes.key_len =
- key_v2->key_param_set.key_params.aes.key_len;
- len = priv->aes_key_v2.key_param_set.key_params.aes.key_len;
+ cpu_to_le16(len);
memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key,
- key_v2->key_param_set.key_params.aes.key, le16_to_cpu(len));
+ key_v2->key_param_set.key_params.aes.key, len);
return 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig b/drivers/net/wireless/mediatek/mt76/Kconfig
index 41533a0e1720..31015d2a8e7d 100644
--- a/drivers/net/wireless/mediatek/mt76/Kconfig
+++ b/drivers/net/wireless/mediatek/mt76/Kconfig
@@ -12,6 +12,10 @@ config MT76_USB
tristate
depends on MT76_CORE
+config MT76_SDIO
+ tristate
+ depends on MT76_CORE
+
config MT76x02_LIB
tristate
select MT76_CORE
diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile
index ef663b873b0b..e53584db0756 100644
--- a/drivers/net/wireless/mediatek/mt76/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_MT76_CORE) += mt76.o
obj-$(CONFIG_MT76_USB) += mt76-usb.o
+obj-$(CONFIG_MT76_SDIO) += mt76-sdio.o
obj-$(CONFIG_MT76x02_LIB) += mt76x02-lib.o
obj-$(CONFIG_MT76x02_USB) += mt76x02-usb.o
@@ -9,8 +10,10 @@ mt76-y := \
tx.o agg-rx.o mcu.o
mt76-$(CONFIG_PCI) += pci.o
+mt76-$(CONFIG_NL80211_TESTMODE) += testmode.o
mt76-usb-y := usb.o usb_trace.o
+mt76-sdio-y := sdio.o
CFLAGS_trace.o := -I$(src)
CFLAGS_usb_trace.o := -I$(src)
diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c
index 3a5de1d1b121..5d58b16bfe9f 100644
--- a/drivers/net/wireless/mediatek/mt76/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/debugfs.c
@@ -9,7 +9,7 @@ mt76_reg_set(void *data, u64 val)
{
struct mt76_dev *dev = data;
- dev->bus->wr(dev, dev->debugfs_reg, val);
+ __mt76_wr(dev, dev->debugfs_reg, val);
return 0;
}
@@ -18,7 +18,7 @@ mt76_reg_get(void *data, u64 *val)
{
struct mt76_dev *dev = data;
- *val = dev->bus->rr(dev, dev->debugfs_reg);
+ *val = __mt76_rr(dev, dev->debugfs_reg);
return 0;
}
@@ -54,9 +54,6 @@ static int mt76_rx_queues_read(struct seq_file *s, void *data)
mt76_for_each_q_rx(dev, i) {
struct mt76_queue *q = &dev->q_rx[i];
- if (!q->ndesc)
- continue;
-
queued = mt76_is_usb(dev) ? q->ndesc - q->queued : q->queued;
seq_printf(s, "%d: queued=%d head=%d tail=%d\n",
i, queued, q->head, q->tail);
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index f4d6074fe32a..6c25859dd386 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -370,6 +370,12 @@ unmap:
tx_info.buf[n].len, DMA_TO_DEVICE);
free:
+#ifdef CONFIG_NL80211_TESTMODE
+ /* fix tx_done accounting on queue overflow */
+ if (tx_info.skb == dev->test.tx_skb)
+ dev->test.tx_done--;
+#endif
+
e.skb = tx_info.skb;
e.txwi = t;
dev->drv->tx_complete_skb(dev, qid, &e);
diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
index c236e303ccfd..3044e0069991 100644
--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
@@ -74,6 +74,11 @@ mt76_get_of_eeprom(struct mt76_dev *dev, int len)
&data[i]);
}
+#ifdef CONFIG_NL80211_TESTMODE
+ dev->test.mtd_name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
+ dev->test.mtd_offset = offset;
+#endif
+
out_put_node:
of_node_put(np);
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 907098101898..3d4bf72700a5 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -58,12 +58,15 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
CHAN5G(132, 5660),
CHAN5G(136, 5680),
CHAN5G(140, 5700),
+ CHAN5G(144, 5720),
CHAN5G(149, 5745),
CHAN5G(153, 5765),
CHAN5G(157, 5785),
CHAN5G(161, 5805),
CHAN5G(165, 5825),
+ CHAN5G(169, 5845),
+ CHAN5G(173, 5865),
};
static const struct ieee80211_tpt_blink mt76_tpt_blink[] = {
@@ -279,7 +282,8 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
- WIPHY_FLAG_SUPPORTS_TDLS;
+ WIPHY_FLAG_SUPPORTS_TDLS |
+ WIPHY_FLAG_AP_UAPSD;
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
@@ -289,6 +293,7 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
wiphy->available_antennas_rx = dev->phy.antenna_mask;
hw->txq_data_size = sizeof(struct mt76_txq);
+ hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
if (!hw->max_tx_fragments)
hw->max_tx_fragments = 16;
@@ -300,7 +305,11 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
ieee80211_hw_set(hw, TX_AMSDU);
- ieee80211_hw_set(hw, TX_FRAG_LIST);
+
+ /* TODO: avoid linearization for SDIO */
+ if (!mt76_is_sdio(dev))
+ ieee80211_hw_set(hw, TX_FRAG_LIST);
+
ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, AP_LINK_PS);
ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
@@ -432,6 +441,12 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
tasklet_init(&dev->tx_tasklet, mt76_tx_tasklet, (unsigned long)dev);
+ dev->wq = alloc_ordered_workqueue("mt76", 0);
+ if (!dev->wq) {
+ ieee80211_free_hw(hw);
+ return NULL;
+ }
+
return dev;
}
EXPORT_SYMBOL_GPL(mt76_alloc_device);
@@ -485,7 +500,12 @@ EXPORT_SYMBOL_GPL(mt76_unregister_device);
void mt76_free_device(struct mt76_dev *dev)
{
- mt76_tx_free(dev);
+ if (dev->wq) {
+ destroy_workqueue(dev->wq);
+ dev->wq = NULL;
+ }
+ if (mt76_is_mmio(dev))
+ mt76_tx_free(dev);
ieee80211_free_hw(dev->hw);
}
EXPORT_SYMBOL_GPL(mt76_free_device);
@@ -500,6 +520,13 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
return;
}
+#ifdef CONFIG_NL80211_TESTMODE
+ if (dev->test.state == MT76_TM_STATE_RX_FRAMES) {
+ dev->test.rx_stats.packets[q]++;
+ if (status->flag & RX_FLAG_FAILED_FCS_CRC)
+ dev->test.rx_stats.fcs_error[q]++;
+ }
+#endif
__skb_queue_tail(&dev->rx_skb[q], skb);
}
EXPORT_SYMBOL_GPL(mt76_rx);
@@ -537,8 +564,7 @@ mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c)
return &msband->chan[idx];
}
-static void
-mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
+void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
{
struct mt76_channel_state *state = phy->chan_state;
@@ -546,6 +572,7 @@ mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
phy->survey_time));
phy->survey_time = time;
}
+EXPORT_SYMBOL_GPL(mt76_update_survey_active_time);
void mt76_update_survey(struct mt76_dev *dev)
{
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 3d7db6ffb599..af35bc388ae2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -15,6 +15,7 @@
#include <linux/average.h>
#include <net/mac80211.h>
#include "util.h"
+#include "testmode.h"
#define MT_TX_RING_SIZE 256
#define MT_MCU_RING_SIZE 32
@@ -33,6 +34,7 @@ struct mt76_reg_pair {
enum mt76_bus_type {
MT76_BUS_MMIO,
MT76_BUS_USB,
+ MT76_BUS_SDIO,
};
struct mt76_bus_ops {
@@ -52,6 +54,7 @@ struct mt76_bus_ops {
#define mt76_is_usb(dev) ((dev)->bus->type == MT76_BUS_USB)
#define mt76_is_mmio(dev) ((dev)->bus->type == MT76_BUS_MMIO)
+#define mt76_is_sdio(dev) ((dev)->bus->type == MT76_BUS_SDIO)
enum mt76_txq_id {
MT_TXQ_VO = IEEE80211_AC_VO,
@@ -94,6 +97,7 @@ struct mt76_queue_entry {
union {
struct mt76_txwi_cache *txwi;
struct urb *urb;
+ int buf_sz;
};
enum mt76_txq_id qid;
bool skip_buf0:1;
@@ -146,6 +150,8 @@ struct mt76_mcu_ops {
int len, bool wait_resp);
int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb,
int cmd, bool wait_resp);
+ u32 (*mcu_rr)(struct mt76_dev *dev, u32 offset);
+ void (*mcu_wr)(struct mt76_dev *dev, u32 offset, u32 val);
int (*mcu_wr_rp)(struct mt76_dev *dev, u32 base,
const struct mt76_reg_pair *rp, int len);
int (*mcu_rd_rp)(struct mt76_dev *dev, u32 base,
@@ -290,6 +296,7 @@ enum {
MT76_STATE_POWER_OFF,
MT76_STATE_SUSPEND,
MT76_STATE_ROC,
+ MT76_STATE_PM,
};
struct mt76_hw_cap {
@@ -422,7 +429,6 @@ struct mt76_usb {
u16 data_len;
struct tasklet_struct rx_tasklet;
- struct workqueue_struct *wq;
struct work_struct stat_work;
u8 out_ep[__MT_EP_OUT_MAX];
@@ -439,6 +445,24 @@ struct mt76_usb {
} mcu;
};
+struct mt76_sdio {
+ struct task_struct *tx_kthread;
+ struct task_struct *kthread;
+ struct work_struct stat_work;
+
+ unsigned long state;
+
+ struct sdio_func *func;
+
+ struct {
+ struct mutex lock;
+ int pse_data_quota;
+ int ple_data_quota;
+ int pse_mcu_quota;
+ int deficit;
+ } sched;
+};
+
struct mt76_mmio {
void __iomem *regs;
spinlock_t irq_lock;
@@ -475,6 +499,47 @@ struct mt76_rx_status {
s8 chain_signal[IEEE80211_MAX_CHAINS];
};
+struct mt76_testmode_ops {
+ int (*set_state)(struct mt76_dev *dev, enum mt76_testmode_state state);
+ int (*set_params)(struct mt76_dev *dev, struct nlattr **tb,
+ enum mt76_testmode_state new_state);
+ int (*dump_stats)(struct mt76_dev *dev, struct sk_buff *msg);
+};
+
+struct mt76_testmode_data {
+ enum mt76_testmode_state state;
+
+ u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)];
+ struct sk_buff *tx_skb;
+
+ u32 tx_count;
+ u16 tx_msdu_len;
+
+ u8 tx_rate_mode;
+ u8 tx_rate_idx;
+ u8 tx_rate_nss;
+ u8 tx_rate_sgi;
+ u8 tx_rate_ldpc;
+
+ u8 tx_antenna_mask;
+
+ u32 freq_offset;
+
+ u8 tx_power[4];
+ u8 tx_power_control;
+
+ const char *mtd_name;
+ u32 mtd_offset;
+
+ u32 tx_pending;
+ u32 tx_queued;
+ u32 tx_done;
+ struct {
+ u64 packets[__MT_RXQ_MAX];
+ u64 fcs_error[__MT_RXQ_MAX];
+ } rx_stats;
+};
+
struct mt76_phy {
struct ieee80211_hw *hw;
struct mt76_dev *dev;
@@ -491,6 +556,8 @@ struct mt76_phy {
struct mt76_sband sband_2g;
struct mt76_sband sband_5g;
+ u32 vif_mask;
+
int txpower_cur;
u8 antenna_mask;
};
@@ -572,9 +639,17 @@ struct mt76_dev {
u32 rxfilter;
+#ifdef CONFIG_NL80211_TESTMODE
+ const struct mt76_testmode_ops *test_ops;
+ struct mt76_testmode_data test;
+#endif
+
+ struct workqueue_struct *wq;
+
union {
struct mt76_mmio mmio;
struct mt76_usb usb;
+ struct mt76_sdio sdio;
};
};
@@ -805,6 +880,15 @@ static inline u8 mt76_tx_power_nss_delta(u8 nss)
return nss_delta[nss - 1];
}
+static inline bool mt76_testmode_enabled(struct mt76_dev *dev)
+{
+#ifdef CONFIG_NL80211_TESTMODE
+ return dev->test.state != MT76_TM_STATE_OFF;
+#else
+ return false;
+#endif
+}
+
void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb);
void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta,
struct mt76_wcid *wcid, struct sk_buff *skb);
@@ -824,6 +908,7 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw,
bool mt76_has_tx_pending(struct mt76_phy *phy);
void mt76_set_channel(struct mt76_phy *phy);
void mt76_update_survey(struct mt76_dev *dev);
+void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time);
int mt76_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey);
void mt76_set_stream_caps(struct mt76_phy *phy, bool vht);
@@ -877,6 +962,24 @@ void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const u8 *mac);
void mt76_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
+int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ void *data, int len);
+int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct netlink_callback *cb, void *data, int len);
+int mt76_testmode_set_state(struct mt76_dev *dev, enum mt76_testmode_state state);
+
+static inline void mt76_testmode_reset(struct mt76_dev *dev, bool disable)
+{
+#ifdef CONFIG_NL80211_TESTMODE
+ enum mt76_testmode_state state = MT76_TM_STATE_IDLE;
+
+ if (disable || dev->test.state == MT76_TM_STATE_OFF)
+ state = MT76_TM_STATE_OFF;
+
+ mt76_testmode_set_state(dev, state);
+#endif
+}
+
/* internal */
static inline struct ieee80211_hw *
@@ -901,6 +1004,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
struct napi_struct *napi);
void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames);
+void mt76_testmode_tx_pending(struct mt76_dev *dev);
/* usb */
static inline bool mt76u_urb_error(struct urb *urb)
@@ -935,13 +1039,12 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout);
}
-int mt76u_skb_dma_info(struct sk_buff *skb, u32 info);
+int mt76_skb_adjust_pad(struct sk_buff *skb);
int mt76u_vendor_request(struct mt76_dev *dev, u8 req,
u8 req_type, u16 val, u16 offset,
void *buf, size_t len);
void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
const u16 offset, const u32 val);
-void mt76u_deinit(struct mt76_dev *dev);
int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf,
bool ext);
int mt76u_alloc_mcu_queue(struct mt76_dev *dev);
@@ -951,6 +1054,12 @@ void mt76u_stop_rx(struct mt76_dev *dev);
int mt76u_resume_rx(struct mt76_dev *dev);
void mt76u_queues_deinit(struct mt76_dev *dev);
+int mt76s_init(struct mt76_dev *dev, struct sdio_func *func,
+ const struct mt76_bus_ops *bus_ops);
+int mt76s_alloc_queues(struct mt76_dev *dev);
+void mt76s_stop_txrx(struct mt76_dev *dev);
+void mt76s_deinit(struct mt76_dev *dev);
+
struct sk_buff *
mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data,
int data_len);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index 83dfa6da4761..447f2c63ef38 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -44,7 +44,7 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
mutex_lock(&dev->mt76.mutex);
- mvif->idx = ffs(~dev->vif_mask) - 1;
+ mvif->idx = ffs(~dev->mphy.vif_mask) - 1;
if (mvif->idx >= MT7603_MAX_INTERFACES) {
ret = -ENOSPC;
goto out;
@@ -65,7 +65,7 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
}
idx = MT7603_WTBL_RESERVED - 1 - mvif->idx;
- dev->vif_mask |= BIT(mvif->idx);
+ dev->mphy.vif_mask |= BIT(mvif->idx);
INIT_LIST_HEAD(&mvif->sta.poll_list);
mvif->sta.wcid.idx = idx;
mvif->sta.wcid.hw_key_idx = -1;
@@ -107,7 +107,7 @@ mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
spin_unlock_bh(&dev->sta_poll_lock);
mutex_lock(&dev->mt76.mutex);
- dev->vif_mask &= ~BIT(mvif->idx);
+ dev->mphy.vif_mask &= ~BIT(mvif->idx);
mutex_unlock(&dev->mt76.mutex);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 7fadf094e9be..c86305241e66 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -108,8 +108,6 @@ struct mt7603_dev {
u32 rxfilter;
- u8 vif_mask;
-
struct list_head sta_poll_list;
spinlock_t sta_poll_lock;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/Kconfig b/drivers/net/wireless/mediatek/mt76/mt7615/Kconfig
index e25db1135eda..f372fb629caf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/Kconfig
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/Kconfig
@@ -28,13 +28,28 @@ config MT7622_WMAC
which has the same feature set as a MT7615, but limited to
2.4 GHz only.
+config MT7663_USB_SDIO_COMMON
+ tristate
+ select MT7615_COMMON
+
config MT7663U
tristate "MediaTek MT7663U (USB) support"
select MT76_USB
- select MT7615_COMMON
+ select MT7663_USB_SDIO_COMMON
depends on MAC80211
depends on USB
help
- This adds support for MT7663U 802.11ax 2x2:2 wireless devices.
+ This adds support for MT7663U 802.11ac 2x2:2 wireless devices.
+
+ To compile this driver as a module, choose M here.
+
+config MT7663S
+ tristate "MediaTek MT7663S (SDIO) support"
+ select MT76_SDIO
+ select MT7663_USB_SDIO_COMMON
+ depends on MAC80211
+ depends on MMC
+ help
+ This adds support for MT7663S 802.11ac 2x2:2 wireless devices.
To compile this driver as a module, choose M here.
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/Makefile b/drivers/net/wireless/mediatek/mt76/mt7615/Makefile
index 99f353b8b9aa..e8fc4a7ae9bc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/Makefile
@@ -2,14 +2,19 @@
obj-$(CONFIG_MT7615_COMMON) += mt7615-common.o
obj-$(CONFIG_MT7615E) += mt7615e.o
+obj-$(CONFIG_MT7663_USB_SDIO_COMMON) += mt7663-usb-sdio-common.o
obj-$(CONFIG_MT7663U) += mt7663u.o
+obj-$(CONFIG_MT7663S) += mt7663s.o
CFLAGS_trace.o := -I$(src)
mt7615-common-y := main.o init.o mcu.o eeprom.o mac.o \
debugfs.o trace.o
+mt7615-common-$(CONFIG_NL80211_TESTMODE) += testmode.o
mt7615e-y := pci.o pci_init.o dma.o pci_mac.o mmio.o
mt7615e-$(CONFIG_MT7622_WMAC) += soc.o
-mt7663u-y := usb.o usb_mcu.o usb_init.o
+mt7663-usb-sdio-common-y := usb_sdio.o
+mt7663u-y := usb.o usb_mcu.o
+mt7663s-y := sdio.o sdio_mcu.o sdio_txrx.o
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
index d06afcf46d67..88931658a9fb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
@@ -6,11 +6,16 @@ static int
mt7615_radar_pattern_set(void *data, u64 val)
{
struct mt7615_dev *dev = data;
+ int err;
if (!mt7615_wait_for_mcu_init(dev))
return 0;
- return mt7615_mcu_rdd_send_pattern(dev);
+ mt7615_mutex_acquire(dev);
+ err = mt7615_mcu_rdd_send_pattern(dev);
+ mt7615_mutex_release(dev);
+
+ return err;
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
@@ -47,6 +52,52 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,
mt7615_scs_set, "%lld\n");
static int
+mt7615_pm_set(void *data, u64 val)
+{
+ struct mt7615_dev *dev = data;
+
+ if (!mt7615_wait_for_mcu_init(dev))
+ return 0;
+
+ return mt7615_pm_set_enable(dev, val);
+}
+
+static int
+mt7615_pm_get(void *data, u64 *val)
+{
+ struct mt7615_dev *dev = data;
+
+ *val = dev->pm.enable;
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7615_pm_get, mt7615_pm_set, "%lld\n");
+
+static int
+mt7615_pm_idle_timeout_set(void *data, u64 val)
+{
+ struct mt7615_dev *dev = data;
+
+ dev->pm.idle_timeout = msecs_to_jiffies(val);
+
+ return 0;
+}
+
+static int
+mt7615_pm_idle_timeout_get(void *data, u64 *val)
+{
+ struct mt7615_dev *dev = data;
+
+ *val = jiffies_to_msecs(dev->pm.idle_timeout);
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7615_pm_idle_timeout_get,
+ mt7615_pm_idle_timeout_set, "%lld\n");
+
+static int
mt7615_dbdc_set(void *data, u64 val)
{
struct mt7615_dev *dev = data;
@@ -84,7 +135,10 @@ mt7615_fw_debug_set(void *data, u64 val)
return 0;
dev->fw_debug = val;
+
+ mt7615_mutex_acquire(dev);
mt7615_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0);
+ mt7615_mutex_release(dev);
return 0;
}
@@ -111,6 +165,8 @@ mt7615_reset_test_set(void *data, u64 val)
if (!mt7615_wait_for_mcu_init(dev))
return 0;
+ mt7615_mutex_acquire(dev);
+
skb = alloc_skb(1, GFP_KERNEL);
if (!skb)
return -ENOMEM;
@@ -118,6 +174,8 @@ mt7615_reset_test_set(void *data, u64 val)
skb_put(skb, 1);
mt76_tx_queue_skb_raw(dev, 0, skb, 0);
+ mt7615_mutex_release(dev);
+
return 0;
}
@@ -167,9 +225,13 @@ mt7615_ampdu_stat_read(struct seq_file *file, void *data)
{
struct mt7615_dev *dev = file->private;
+ mt7615_mutex_acquire(dev);
+
mt7615_ampdu_stat_read_phy(&dev->phy, file);
mt7615_ampdu_stat_read_phy(mt7615_ext_phy(dev), file);
+ mt7615_mutex_release(dev);
+
return 0;
}
@@ -221,7 +283,10 @@ static int mt7615_read_temperature(struct seq_file *s, void *data)
return 0;
/* cpu */
+ mt7615_mutex_acquire(dev);
temp = mt7615_mcu_get_temperature(dev, 0);
+ mt7615_mutex_release(dev);
+
seq_printf(s, "Temperature: %d\n", temp);
return 0;
@@ -233,6 +298,8 @@ mt7615_queues_acq(struct seq_file *s, void *data)
struct mt7615_dev *dev = dev_get_drvdata(s->private);
int i;
+ mt7615_mutex_acquire(dev);
+
for (i = 0; i < 16; i++) {
int j, wmm_idx = i % MT7615_MAX_WMM_SETS;
int acs = i / MT7615_MAX_WMM_SETS;
@@ -253,6 +320,8 @@ mt7615_queues_acq(struct seq_file *s, void *data)
seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen);
}
+ mt7615_mutex_release(dev);
+
return 0;
}
@@ -285,6 +354,29 @@ mt7615_queues_read(struct seq_file *s, void *data)
return 0;
}
+static int
+mt7615_rf_reg_set(void *data, u64 val)
+{
+ struct mt7615_dev *dev = data;
+
+ mt7615_rf_wr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg, val);
+
+ return 0;
+}
+
+static int
+mt7615_rf_reg_get(void *data, u64 *val)
+{
+ struct mt7615_dev *dev = data;
+
+ *val = mt7615_rf_rr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg);
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_reg, mt7615_rf_reg_get, mt7615_rf_reg_set,
+ "0x%08llx\n");
+
int mt7615_init_debugfs(struct mt7615_dev *dev)
{
struct dentry *dir;
@@ -305,6 +397,9 @@ int mt7615_init_debugfs(struct mt7615_dev *dev)
debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
debugfs_create_file("dbdc", 0600, dir, dev, &fops_dbdc);
debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
+ debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm);
+ debugfs_create_file("idle-timeout", 0600, dir, dev,
+ &fops_pm_idle_timeout);
debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
mt7615_radio_read);
debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
@@ -324,6 +419,11 @@ int mt7615_init_debugfs(struct mt7615_dev *dev)
debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir,
mt7615_read_temperature);
+ debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf);
+ debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg);
+ debugfs_create_file_unsafe("rf_regval", 0600, dir, dev,
+ &fops_rf_reg);
+
return 0;
}
EXPORT_SYMBOL_GPL(mt7615_init_debugfs);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
index e5a965df899a..1231a5ddf9ea 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
@@ -122,10 +122,6 @@ static int mt7615_poll_tx(struct napi_struct *napi, int budget)
mt7615_tx_cleanup(dev);
- rcu_read_lock();
- mt7615_mac_sta_poll(dev);
- rcu_read_unlock();
-
tasklet_schedule(&dev->mt76.tx_tasklet);
return 0;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
index e2d80518e5af..fc1ebabfebac 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
@@ -285,7 +285,9 @@ mt7615_regd_notifier(struct wiphy *wiphy,
if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR))
return;
+ mt7615_mutex_acquire(dev);
mt7615_dfs_init_radar_detector(phy);
+ mt7615_mutex_release(dev);
}
static void
@@ -321,6 +323,7 @@ mt7615_init_wiphy(struct ieee80211_hw *hw)
ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
+ ieee80211_hw_set(hw, WANT_MONITOR_VIF);
if (is_mt7615(&phy->dev->mt76))
hw->max_tx_fragments = MT_TXP_MAX_BUF_NUM;
@@ -405,9 +408,6 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
mphy->sband_2g.sband.n_channels = 0;
mphy->hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL;
- /* The second interface does not get any packets unless it has a vif */
- ieee80211_hw_set(mphy->hw, WANT_MONITOR_VIF);
-
ret = mt76_register_phy(mphy);
if (ret)
ieee80211_free_hw(mphy->hw);
@@ -437,6 +437,12 @@ void mt7615_init_device(struct mt7615_dev *dev)
dev->phy.dev = dev;
dev->phy.mt76 = &dev->mt76.phy;
dev->mt76.phy.priv = &dev->phy;
+
+ INIT_DELAYED_WORK(&dev->pm.ps_work, mt7615_pm_power_save_work);
+ INIT_WORK(&dev->pm.wake_work, mt7615_pm_wake_work);
+ init_completion(&dev->pm.wake_cmpl);
+ spin_lock_init(&dev->pm.txq_lock);
+ set_bit(MT76_STATE_PM, &dev->mphy.state);
INIT_DELAYED_WORK(&dev->phy.mac_work, mt7615_mac_work);
INIT_DELAYED_WORK(&dev->phy.scan_work, mt7615_scan_work);
skb_queue_head_init(&dev->phy.scan_event_list);
@@ -450,6 +456,7 @@ void mt7615_init_device(struct mt7615_dev *dev)
timer_setup(&dev->phy.roc_timer, mt7615_roc_timer, 0);
mt7615_init_wiphy(hw);
+ dev->pm.idle_timeout = MT7615_PM_TIMEOUT;
dev->mphy.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
dev->mphy.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
dev->mphy.sband_5g.sband.vht_cap.cap |=
@@ -457,5 +464,9 @@ void mt7615_init_device(struct mt7615_dev *dev)
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
mt7615_cap_dbdc_disable(dev);
dev->phy.dfs_state = -1;
+
+#ifdef CONFIG_NL80211_TESTMODE
+ dev->mt76.test_ops = &mt7615_testmode_ops;
+#endif
}
EXPORT_SYMBOL_GPL(mt7615_init_device);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index d97315ec7265..3dd8dd28690e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -186,6 +186,40 @@ mt7615_get_status_freq_info(struct mt7615_dev *dev, struct mt76_phy *mphy,
status->freq = ieee80211_channel_to_frequency(chfreq, status->band);
}
+static void mt7615_mac_fill_tm_rx(struct mt7615_dev *dev, __le32 *rxv)
+{
+#ifdef CONFIG_NL80211_TESTMODE
+ u32 rxv1 = le32_to_cpu(rxv[0]);
+ u32 rxv3 = le32_to_cpu(rxv[2]);
+ u32 rxv4 = le32_to_cpu(rxv[3]);
+ u32 rxv5 = le32_to_cpu(rxv[4]);
+ u8 cbw = FIELD_GET(MT_RXV1_FRAME_MODE, rxv1);
+ u8 mode = FIELD_GET(MT_RXV1_TX_MODE, rxv1);
+ s16 foe = FIELD_GET(MT_RXV5_FOE, rxv5);
+ u32 foe_const = (BIT(cbw + 1) & 0xf) * 10000;
+
+ if (!mode) {
+ /* CCK */
+ foe &= ~BIT(11);
+ foe *= 1000;
+ foe >>= 11;
+ } else {
+ if (foe > 2048)
+ foe -= 4096;
+
+ foe = (foe * foe_const) >> 15;
+ }
+
+ dev->test.last_freq_offset = foe;
+ dev->test.last_rcpi[0] = FIELD_GET(MT_RXV4_RCPI0, rxv4);
+ dev->test.last_rcpi[1] = FIELD_GET(MT_RXV4_RCPI1, rxv4);
+ dev->test.last_rcpi[2] = FIELD_GET(MT_RXV4_RCPI2, rxv4);
+ dev->test.last_rcpi[3] = FIELD_GET(MT_RXV4_RCPI3, rxv4);
+ dev->test.last_ib_rssi = FIELD_GET(MT_RXV3_IB_RSSI, rxv3);
+ dev->test.last_wb_rssi = FIELD_GET(MT_RXV3_WB_RSSI, rxv3);
+#endif
+}
+
static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
@@ -401,6 +435,8 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
status->chain_signal[i]);
}
+ mt7615_mac_fill_tm_rx(dev, rxd);
+
rxd += 6;
if ((u8 *)rxd - skb->data >= skb->len)
return -EINVAL;
@@ -493,18 +529,18 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
struct ieee80211_sta *sta, int pid,
struct ieee80211_key_conf *key, bool beacon)
{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ u8 fc_type, fc_stype, p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rate = &info->control.rates[0];
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ bool ext_phy = info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY;
bool multicast = is_multicast_ether_addr(hdr->addr1);
struct ieee80211_vif *vif = info->control.vif;
+ bool is_mmio = mt76_is_mmio(&dev->mt76);
+ u32 val, sz_txd = is_mmio ? MT_TXD_SIZE : MT_USB_TXD_SIZE;
struct mt76_phy *mphy = &dev->mphy;
- bool ext_phy = info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY;
- bool is_usb = mt76_is_usb(&dev->mt76);
- int tx_count = 8;
- u8 fc_type, fc_stype, p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
__le16 fc = hdr->frame_control;
- u32 val, sz_txd = is_usb ? MT_USB_TXD_SIZE : MT_TXD_SIZE;
+ int tx_count = 8;
u16 seqno = 0;
if (vif) {
@@ -530,10 +566,10 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
p_fmt = MT_TX_TYPE_FW;
q_idx = ext_phy ? MT_LMAC_BCN1 : MT_LMAC_BCN0;
} else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
- p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT;
+ p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
q_idx = ext_phy ? MT_LMAC_ALTX1 : MT_LMAC_ALTX0;
} else {
- p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT;
+ p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
q_idx = wmm_idx * MT7615_MAX_WMM_SETS +
mt7615_lmac_mapping(dev, skb_get_queue_mapping(skb));
}
@@ -617,16 +653,19 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
}
val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count);
- if (ieee80211_is_data_qos(hdr->frame_control)) {
- seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
- val |= MT_TXD3_SN_VALID;
- } else if (ieee80211_is_back_req(hdr->frame_control)) {
- struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data;
+ if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+ seqno = le16_to_cpu(hdr->seq_ctrl);
+
+ if (ieee80211_is_back_req(hdr->frame_control)) {
+ struct ieee80211_bar *bar;
- seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(bar->start_seq_num));
- val |= MT_TXD3_SN_VALID;
+ bar = (struct ieee80211_bar *)skb->data;
+ seqno = le16_to_cpu(bar->start_seq_num);
+ }
+
+ val |= MT_TXD3_SN_VALID |
+ FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno));
}
- val |= FIELD_PREP(MT_TXD3_SEQ, seqno);
txwi[3] |= cpu_to_le32(val);
@@ -636,7 +675,7 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
txwi[7] = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype) |
FIELD_PREP(MT_TXD7_SPE_IDX, 0x18);
- if (is_usb)
+ if (!is_mmio)
txwi[8] = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) |
FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype);
@@ -878,6 +917,9 @@ mt7615_mac_queue_rate_update(struct mt7615_phy *phy, struct mt7615_sta *sta,
struct mt7615_dev *dev = phy->dev;
struct mt7615_wtbl_desc *wd;
+ if (work_pending(&dev->wtbl_work))
+ return -EBUSY;
+
wd = kzalloc(sizeof(*wd), GFP_ATOMIC);
if (!wd)
return -ENOMEM;
@@ -888,11 +930,34 @@ mt7615_mac_queue_rate_update(struct mt7615_phy *phy, struct mt7615_sta *sta,
mt7615_mac_update_rate_desc(phy, sta, probe_rate, rates,
&wd->rate);
list_add_tail(&wd->node, &dev->wd_head);
- queue_work(dev->mt76.usb.wq, &dev->wtbl_work);
+ queue_work(dev->mt76.wq, &dev->wtbl_work);
return 0;
}
+u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid)
+{
+ u32 addr, val, val2;
+ u8 offset;
+
+ addr = mt7615_mac_wtbl_addr(dev, wcid) + 11 * 4;
+
+ offset = tid * 12;
+ addr += 4 * (offset / 32);
+ offset %= 32;
+
+ val = mt76_rr(dev, addr);
+ val >>= (tid % 32);
+
+ if (offset > 20) {
+ addr += 4;
+ val2 = mt76_rr(dev, addr);
+ val |= val2 << (32 - offset);
+ }
+
+ return val & GENMASK(11, 0);
+}
+
void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
struct ieee80211_tx_rate *probe_rate,
struct ieee80211_tx_rate *rates)
@@ -902,7 +967,7 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
struct mt7615_rate_desc rd;
u32 w5, w27, addr;
- if (mt76_is_usb(&dev->mt76)) {
+ if (!mt76_is_mmio(&dev->mt76)) {
mt7615_mac_queue_rate_update(phy, sta, probe_rate, rates);
return;
}
@@ -961,6 +1026,7 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
sta->rate_count = 2 * MT7615_RATE_RETRY * n_rates;
sta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
+ sta->rate_probe = !!probe_rate;
}
EXPORT_SYMBOL_GPL(mt7615_mac_set_rates);
@@ -1169,7 +1235,6 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta,
phy = dev->mt76.phy2->priv;
mt7615_mac_set_rates(phy, sta, NULL, sta->rates);
- sta->rate_probe = false;
}
spin_unlock_bh(&dev->mt76.lock);
} else {
@@ -1373,6 +1438,12 @@ static void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
}
dev_kfree_skb(skb);
+
+ rcu_read_lock();
+ mt7615_mac_sta_poll(dev);
+ rcu_read_unlock();
+
+ tasklet_schedule(&dev->mt76.tx_tasklet);
}
void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
@@ -1462,7 +1533,7 @@ void mt7615_mac_set_scs(struct mt7615_phy *phy, bool enable)
bool ext_phy = phy != &dev->phy;
u32 reg, mask;
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
if (phy->scs_en == enable)
goto out;
@@ -1489,7 +1560,7 @@ void mt7615_mac_set_scs(struct mt7615_phy *phy, bool enable)
phy->scs_en = enable;
out:
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
}
void mt7615_mac_enable_nf(struct mt7615_dev *dev, bool ext_phy)
@@ -1679,9 +1750,9 @@ mt7615_phy_update_channel(struct mt76_phy *mphy, int idx)
state->noise = -(phy->noise >> 4);
}
-void mt7615_update_channel(struct mt76_dev *mdev)
+static void __mt7615_update_channel(struct mt7615_dev *dev)
{
- struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ struct mt76_dev *mdev = &dev->mt76;
mt7615_phy_update_channel(&mdev->phy, 0);
if (mdev->phy2)
@@ -1690,8 +1761,32 @@ void mt7615_update_channel(struct mt76_dev *mdev)
/* reset obss airtime */
mt76_set(dev, MT_WF_RMAC_MIB_TIME0, MT_WF_RMAC_MIB_RXTIME_CLR);
}
+
+void mt7615_update_channel(struct mt76_dev *mdev)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+
+ if (mt7615_pm_wake(dev))
+ return;
+
+ __mt7615_update_channel(dev);
+ mt7615_pm_power_save_sched(dev);
+}
EXPORT_SYMBOL_GPL(mt7615_update_channel);
+static void mt7615_update_survey(struct mt7615_dev *dev)
+{
+ struct mt76_dev *mdev = &dev->mt76;
+ ktime_t cur_time;
+
+ __mt7615_update_channel(dev);
+ cur_time = ktime_get_boottime();
+
+ mt76_update_survey_active_time(&mdev->phy, cur_time);
+ if (mdev->phy2)
+ mt76_update_survey_active_time(mdev->phy2, cur_time);
+}
+
static void
mt7615_mac_update_mib_stats(struct mt7615_phy *phy)
{
@@ -1740,6 +1835,163 @@ mt7615_mac_update_mib_stats(struct mt7615_phy *phy)
}
}
+void mt7615_pm_wake_work(struct work_struct *work)
+{
+ struct mt7615_dev *dev;
+ struct mt76_phy *mphy;
+ int i;
+
+ dev = (struct mt7615_dev *)container_of(work, struct mt7615_dev,
+ pm.wake_work);
+ mphy = dev->phy.mt76;
+
+ if (mt7615_driver_own(dev)) {
+ dev_err(mphy->dev->dev, "failed to wake device\n");
+ goto out;
+ }
+
+ spin_lock_bh(&dev->pm.txq_lock);
+ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ struct mt7615_sta *msta = dev->pm.tx_q[i].msta;
+ struct mt76_wcid *wcid = msta ? &msta->wcid : NULL;
+ struct ieee80211_sta *sta = NULL;
+
+ if (!dev->pm.tx_q[i].skb)
+ continue;
+
+ if (msta && wcid->sta)
+ sta = container_of((void *)msta, struct ieee80211_sta,
+ drv_priv);
+
+ mt76_tx(mphy, sta, wcid, dev->pm.tx_q[i].skb);
+ dev->pm.tx_q[i].skb = NULL;
+ }
+ spin_unlock_bh(&dev->pm.txq_lock);
+
+ tasklet_schedule(&dev->mt76.tx_tasklet);
+
+out:
+ ieee80211_wake_queues(mphy->hw);
+ complete_all(&dev->pm.wake_cmpl);
+}
+
+int mt7615_pm_wake(struct mt7615_dev *dev)
+{
+ struct mt76_phy *mphy = dev->phy.mt76;
+
+ if (!mt7615_firmware_offload(dev))
+ return 0;
+
+ if (!mt76_is_mmio(mphy->dev))
+ return 0;
+
+ if (!test_bit(MT76_STATE_PM, &mphy->state))
+ return 0;
+
+ if (test_bit(MT76_HW_SCANNING, &mphy->state) ||
+ test_bit(MT76_HW_SCHED_SCANNING, &mphy->state))
+ return 0;
+
+ if (queue_work(dev->mt76.wq, &dev->pm.wake_work))
+ reinit_completion(&dev->pm.wake_cmpl);
+
+ if (!wait_for_completion_timeout(&dev->pm.wake_cmpl, 3 * HZ)) {
+ ieee80211_wake_queues(mphy->hw);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mt7615_pm_wake);
+
+void mt7615_pm_power_save_sched(struct mt7615_dev *dev)
+{
+ struct mt76_phy *mphy = dev->phy.mt76;
+
+ if (!mt7615_firmware_offload(dev))
+ return;
+
+ if (!mt76_is_mmio(mphy->dev))
+ return;
+
+ if (!dev->pm.enable || !test_bit(MT76_STATE_RUNNING, &mphy->state))
+ return;
+
+ dev->pm.last_activity = jiffies;
+
+ if (test_bit(MT76_HW_SCANNING, &mphy->state) ||
+ test_bit(MT76_HW_SCHED_SCANNING, &mphy->state))
+ return;
+
+ if (!test_bit(MT76_STATE_PM, &mphy->state))
+ queue_delayed_work(dev->mt76.wq, &dev->pm.ps_work,
+ dev->pm.idle_timeout);
+}
+EXPORT_SYMBOL_GPL(mt7615_pm_power_save_sched);
+
+void mt7615_pm_power_save_work(struct work_struct *work)
+{
+ struct mt7615_dev *dev;
+ unsigned long delta;
+
+ dev = (struct mt7615_dev *)container_of(work, struct mt7615_dev,
+ pm.ps_work.work);
+
+ delta = dev->pm.idle_timeout;
+ if (time_is_after_jiffies(dev->pm.last_activity + delta)) {
+ delta = dev->pm.last_activity + delta - jiffies;
+ goto out;
+ }
+
+ if (!mt7615_firmware_own(dev))
+ return;
+out:
+ queue_delayed_work(dev->mt76.wq, &dev->pm.ps_work, delta);
+}
+
+static void
+mt7615_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct mt7615_phy *phy = priv;
+ struct mt7615_dev *dev = phy->dev;
+ bool ext_phy = phy != &dev->phy;
+
+ if (mt7615_mcu_set_bss_pm(dev, vif, dev->pm.enable))
+ return;
+
+ if (dev->pm.enable) {
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+ mt76_set(dev, MT_WF_RFCR(ext_phy),
+ MT_WF_RFCR_DROP_OTHER_BEACON);
+ } else {
+ vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
+ mt76_clear(dev, MT_WF_RFCR(ext_phy),
+ MT_WF_RFCR_DROP_OTHER_BEACON);
+ }
+}
+
+int mt7615_pm_set_enable(struct mt7615_dev *dev, bool enable)
+{
+ struct mt76_phy *mphy = dev->phy.mt76;
+
+ if (!mt7615_firmware_offload(dev) || !mt76_is_mmio(&dev->mt76))
+ return -EOPNOTSUPP;
+
+ mt7615_mutex_acquire(dev);
+
+ if (dev->pm.enable == enable)
+ goto out;
+
+ dev->pm.enable = enable;
+ ieee80211_iterate_active_interfaces(mphy->hw,
+ IEEE80211_IFACE_ITER_RESUME_ALL,
+ mt7615_pm_interface_iter, mphy->priv);
+out:
+ mt7615_mutex_release(dev);
+
+ return 0;
+}
+
void mt7615_mac_work(struct work_struct *work)
{
struct mt7615_phy *phy;
@@ -1749,9 +2001,9 @@ void mt7615_mac_work(struct work_struct *work)
mac_work.work);
mdev = &phy->dev->mt76;
- mutex_lock(&mdev->mutex);
+ mt7615_mutex_acquire(phy->dev);
- mt76_update_survey(mdev);
+ mt7615_update_survey(phy->dev);
if (++phy->mac_work_count == 5) {
phy->mac_work_count = 0;
@@ -1759,7 +2011,7 @@ void mt7615_mac_work(struct work_struct *work)
mt7615_mac_scs_check(phy);
}
- mutex_unlock(&mdev->mutex);
+ mt7615_mutex_release(phy->dev);
mt76_tx_status_check(mdev, NULL, false);
ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
@@ -1863,7 +2115,7 @@ void mt7615_mac_reset_work(struct work_struct *work)
napi_disable(&dev->mt76.napi[1]);
napi_disable(&dev->mt76.tx_napi);
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_PDMA_STOPPED);
@@ -1896,10 +2148,10 @@ void mt7615_mac_reset_work(struct work_struct *work)
mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
mt7615_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
- mutex_unlock(&dev->mt76.mutex);
-
mt7615_update_beacons(dev);
+ mt7615_mutex_release(dev);
+
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->phy.mac_work,
MT7615_WATCHDOG_TIME);
if (phy2)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.h b/drivers/net/wireless/mediatek/mt76/mt7615/mac.h
index 81608ab656b8..169f4e17b5b4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.h
@@ -100,11 +100,16 @@ enum rx_pkt_type {
#define MT_RXV2_GROUP_ID GENMASK(26, 21)
#define MT_RXV2_LENGTH GENMASK(20, 0)
+#define MT_RXV3_WB_RSSI GENMASK(31, 24)
+#define MT_RXV3_IB_RSSI GENMASK(23, 16)
+
#define MT_RXV4_RCPI3 GENMASK(31, 24)
#define MT_RXV4_RCPI2 GENMASK(23, 16)
#define MT_RXV4_RCPI1 GENMASK(15, 8)
#define MT_RXV4_RCPI0 GENMASK(7, 0)
+#define MT_RXV5_FOE GENMASK(11, 0)
+
#define MT_RXV6_NF3 GENMASK(31, 24)
#define MT_RXV6_NF2 GENMASK(23, 16)
#define MT_RXV6_NF1 GENMASK(15, 8)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index beaca8127680..2d0b1f49fdbc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -24,6 +24,22 @@ static bool mt7615_dev_running(struct mt7615_dev *dev)
return phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state);
}
+static void mt7615_free_pending_tx_skbs(struct mt7615_dev *dev,
+ struct mt7615_sta *msta)
+{
+ int i;
+
+ spin_lock_bh(&dev->pm.txq_lock);
+ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ if (msta && dev->pm.tx_q[i].msta != msta)
+ continue;
+
+ dev_kfree_skb(dev->pm.tx_q[i].skb);
+ dev->pm.tx_q[i].skb = NULL;
+ }
+ spin_unlock_bh(&dev->pm.txq_lock);
+}
+
static int mt7615_start(struct ieee80211_hw *hw)
{
struct mt7615_dev *dev = mt7615_hw_dev(hw);
@@ -33,7 +49,7 @@ static int mt7615_start(struct ieee80211_hw *hw)
if (!mt7615_wait_for_mcu_init(dev))
return -EIO;
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
running = mt7615_dev_running(dev);
@@ -60,7 +76,7 @@ static int mt7615_start(struct ieee80211_hw *hw)
if (!running)
mt7615_mac_reset_counters(dev);
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return 0;
}
@@ -74,7 +90,14 @@ static void mt7615_stop(struct ieee80211_hw *hw)
del_timer_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
- mutex_lock(&dev->mt76.mutex);
+ cancel_delayed_work_sync(&dev->pm.ps_work);
+ cancel_work_sync(&dev->pm.wake_work);
+
+ mt7615_free_pending_tx_skbs(dev, NULL);
+
+ mt7615_mutex_acquire(dev);
+
+ mt76_testmode_reset(&dev->mt76, true);
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
cancel_delayed_work_sync(&phy->scan_work);
@@ -89,7 +112,7 @@ static void mt7615_stop(struct ieee80211_hw *hw)
mt7615_mcu_set_mac_enable(dev, 0, false);
}
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
}
static int get_omac_idx(enum nl80211_iftype type, u32 mask)
@@ -135,9 +158,15 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
bool ext_phy = phy != &dev->phy;
int idx, ret = 0;
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
+
+ mt76_testmode_reset(&dev->mt76, true);
- mvif->idx = ffs(~dev->vif_mask) - 1;
+ if (vif->type == NL80211_IFTYPE_MONITOR &&
+ is_zero_ether_addr(vif->addr))
+ phy->monitor_vif = vif;
+
+ mvif->idx = ffs(~dev->mphy.vif_mask) - 1;
if (mvif->idx >= MT7615_MAX_INTERFACES) {
ret = -ENOSPC;
goto out;
@@ -157,7 +186,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
else
mvif->wmm_idx = mvif->idx % MT7615_MAX_WMM_SETS;
- dev->vif_mask |= BIT(mvif->idx);
+ dev->mphy.vif_mask |= BIT(mvif->idx);
dev->omac_mask |= BIT(mvif->omac_idx);
phy->omac_mask |= BIT(mvif->omac_idx);
@@ -180,8 +209,20 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
}
ret = mt7615_mcu_add_dev_info(dev, vif, true);
+ if (ret)
+ goto out;
+
+ if (dev->pm.enable) {
+ ret = mt7615_mcu_set_bss_pm(dev, vif, true);
+ if (ret)
+ goto out;
+
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+ mt76_set(dev, MT_WF_RFCR(ext_phy),
+ MT_WF_RFCR_DROP_OTHER_BEACON);
+ }
out:
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return ret;
}
@@ -197,17 +238,32 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,
/* TODO: disable beacon for the bss */
+ mt7615_mutex_acquire(dev);
+
+ mt76_testmode_reset(&dev->mt76, true);
+ if (vif == phy->monitor_vif)
+ phy->monitor_vif = NULL;
+
+ mt7615_free_pending_tx_skbs(dev, msta);
+
+ if (dev->pm.enable) {
+ bool ext_phy = phy != &dev->phy;
+
+ mt7615_mcu_set_bss_pm(dev, vif, false);
+ mt76_clear(dev, MT_WF_RFCR(ext_phy),
+ MT_WF_RFCR_DROP_OTHER_BEACON);
+ }
mt7615_mcu_add_dev_info(dev, vif, false);
rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
if (vif->txq)
mt76_txq_remove(&dev->mt76, vif->txq);
- mutex_lock(&dev->mt76.mutex);
- dev->vif_mask &= ~BIT(mvif->idx);
+ dev->mphy.vif_mask &= ~BIT(mvif->idx);
dev->omac_mask &= ~BIT(mvif->omac_idx);
phy->omac_mask &= ~BIT(mvif->omac_idx);
- mutex_unlock(&dev->mt76.mutex);
+
+ mt7615_mutex_release(dev);
spin_lock_bh(&dev->sta_poll_lock);
if (!list_empty(&msta->poll_list))
@@ -234,7 +290,7 @@ static void mt7615_init_dfs_state(struct mt7615_phy *phy)
phy->dfs_state = -1;
}
-static int mt7615_set_channel(struct mt7615_phy *phy)
+int mt7615_set_channel(struct mt7615_phy *phy)
{
struct mt7615_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy;
@@ -242,7 +298,8 @@ static int mt7615_set_channel(struct mt7615_phy *phy)
cancel_delayed_work_sync(&phy->mac_work);
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
+
set_bit(MT76_RESET, &phy->mt76->state);
mt7615_init_dfs_state(phy);
@@ -260,7 +317,7 @@ static int mt7615_set_channel(struct mt7615_phy *phy)
mt7615_mac_set_timing(phy);
ret = mt7615_dfs_init_radar_detector(phy);
mt7615_mac_cca_stats_reset(phy);
- mt7615_mcu_set_sku_en(phy, true);
+ mt7615_mcu_set_sku_en(phy, !mt76_testmode_enabled(&dev->mt76));
mt7615_mac_reset_counters(dev);
phy->noise = 0;
@@ -268,11 +325,15 @@ static int mt7615_set_channel(struct mt7615_phy *phy)
out:
clear_bit(MT76_RESET, &phy->mt76->state);
- mutex_unlock(&dev->mt76.mutex);
+
+ mt7615_mutex_release(dev);
mt76_txq_schedule_all(phy->mt76);
- ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
- MT7615_WATCHDOG_TIME);
+
+ if (!mt76_testmode_enabled(&dev->mt76))
+ ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
+ MT7615_WATCHDOG_TIME);
+
return ret;
}
@@ -301,7 +362,7 @@ mt7615_queue_key_update(struct mt7615_dev *dev, enum set_key_cmd cmd,
wd->key.cmd = cmd;
list_add_tail(&wd->node, &dev->wd_head);
- queue_work(dev->mt76.usb.wq, &dev->wtbl_work);
+ queue_work(dev->mt76.wq, &dev->wtbl_work);
return 0;
}
@@ -315,7 +376,7 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct mt7615_sta *msta = sta ? (struct mt7615_sta *)sta->drv_priv :
&mvif->sta;
struct mt76_wcid *wcid = &msta->wcid;
- int idx = key->keyidx;
+ int idx = key->keyidx, err;
/* The hardware does not support per-STA RX GTK, fallback
* to software mode for these.
@@ -345,6 +406,8 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}
+ mt7615_mutex_acquire(dev);
+
if (cmd == SET_KEY) {
key->hw_key_idx = wcid->idx;
wcid->hw_key_idx = idx;
@@ -354,10 +417,14 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
mt76_wcid_key_setup(&dev->mt76, wcid,
cmd == SET_KEY ? key : NULL);
- if (mt76_is_usb(&dev->mt76))
- return mt7615_queue_key_update(dev, cmd, msta, key);
+ if (mt76_is_mmio(&dev->mt76))
+ err = mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
+ else
+ err = mt7615_queue_key_update(dev, cmd, msta, key);
+
+ mt7615_mutex_release(dev);
- return mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
+ return err;
}
static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
@@ -369,14 +436,23 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
IEEE80211_CONF_CHANGE_POWER)) {
+#ifdef CONFIG_NL80211_TESTMODE
+ if (dev->mt76.test.state != MT76_TM_STATE_OFF) {
+ mt7615_mutex_acquire(dev);
+ mt76_testmode_reset(&dev->mt76, false);
+ mt7615_mutex_release(dev);
+ }
+#endif
ieee80211_stop_queues(hw);
ret = mt7615_set_channel(phy);
ieee80211_wake_queues(hw);
}
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+ mt76_testmode_reset(&dev->mt76, true);
+
if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
else
@@ -385,7 +461,7 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
}
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return ret;
}
@@ -396,11 +472,17 @@ mt7615_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
{
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
struct mt7615_dev *dev = mt7615_hw_dev(hw);
+ int err;
+
+ mt7615_mutex_acquire(dev);
queue = mt7615_lmac_mapping(dev, queue);
queue += mvif->wmm_idx * MT7615_MAX_WMM_SETS;
+ err = mt7615_mcu_set_wmm(dev, queue, params);
- return mt7615_mcu_set_wmm(dev, queue, params);
+ mt7615_mutex_release(dev);
+
+ return err;
}
static void mt7615_configure_filter(struct ieee80211_hw *hw,
@@ -419,10 +501,13 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw,
MT_WF_RFCR1_DROP_CFACK;
u32 flags = 0;
+ mt7615_mutex_acquire(dev);
+
#define MT76_FILTER(_flag, _hw) do { \
flags |= *total_flags & FIF_##_flag; \
phy->rxfilter &= ~(_hw); \
- phy->rxfilter |= !(flags & FIF_##_flag) * (_hw); \
+ if (!mt76_testmode_enabled(&dev->mt76)) \
+ phy->rxfilter |= !(flags & FIF_##_flag) * (_hw);\
} while (0)
phy->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |
@@ -455,6 +540,8 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw,
mt76_clear(dev, MT_WF_RFCR1(band), ctl_flags);
else
mt76_set(dev, MT_WF_RFCR1(band), ctl_flags);
+
+ mt7615_mutex_release(dev);
}
static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
@@ -465,7 +552,7 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt7615_phy *phy = mt7615_hw_phy(hw);
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
if (changed & BSS_CHANGED_ERP_SLOT) {
int slottime = info->use_short_slot ? 9 : 20;
@@ -491,7 +578,10 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_PS)
mt7615_mcu_set_vif_ps(dev, vif);
- mutex_unlock(&dev->mt76.mutex);
+ if (changed & BSS_CHANGED_ARP_FILTER)
+ mt7615_mcu_update_arp_filter(hw, vif, info);
+
+ mt7615_mutex_release(dev);
}
static void
@@ -501,9 +591,9 @@ mt7615_channel_switch_beacon(struct ieee80211_hw *hw,
{
struct mt7615_dev *dev = mt7615_hw_dev(hw);
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
mt7615_mcu_add_beacon(dev, hw, vif, true);
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
}
int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -512,7 +602,7 @@ int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
- int idx;
+ int idx, err;
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);
if (idx < 0)
@@ -524,6 +614,10 @@ int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
msta->wcid.idx = idx;
msta->wcid.ext_phy = mvif->band_idx;
+ err = mt7615_pm_wake(dev);
+ if (err)
+ return err;
+
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
struct mt7615_phy *phy;
@@ -534,6 +628,8 @@ int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
mt7615_mcu_sta_add(dev, vif, sta, true);
+ mt7615_pm_power_save_sched(dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(mt7615_mac_sta_add);
@@ -544,6 +640,9 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
+ mt7615_free_pending_tx_skbs(dev, msta);
+ mt7615_pm_wake(dev);
+
mt7615_mcu_sta_add(dev, vif, sta, false);
mt7615_mac_wtbl_update(dev, msta->wcid.idx,
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
@@ -559,6 +658,8 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
if (!list_empty(&msta->poll_list))
list_del_init(&msta->poll_list);
spin_unlock_bh(&dev->sta_poll_lock);
+
+ mt7615_pm_power_save_sched(dev);
}
EXPORT_SYMBOL_GPL(mt7615_mac_sta_remove);
@@ -582,11 +683,29 @@ static void mt7615_sta_rate_tbl_update(struct ieee80211_hw *hw,
break;
}
msta->n_rates = i;
- mt7615_mac_set_rates(phy, msta, NULL, msta->rates);
- msta->rate_probe = false;
+ if (!test_bit(MT76_STATE_PM, &phy->mt76->state))
+ mt7615_mac_set_rates(phy, msta, NULL, msta->rates);
spin_unlock_bh(&dev->mt76.lock);
}
+static void
+mt7615_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
+{
+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
+ struct mt7615_phy *phy = mt7615_hw_phy(hw);
+ struct mt76_phy *mphy = phy->mt76;
+
+ if (!test_bit(MT76_STATE_RUNNING, &mphy->state))
+ return;
+
+ if (test_bit(MT76_STATE_PM, &mphy->state)) {
+ queue_work(dev->mt76.wq, &dev->pm.wake_work);
+ return;
+ }
+
+ tasklet_schedule(&dev->mt76.tx_tasklet);
+}
+
static void mt7615_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
@@ -596,22 +715,43 @@ static void mt7615_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
struct mt76_wcid *wcid = &dev->mt76.global_wcid;
+ struct mt7615_sta *msta = NULL;
+ int qid;
if (control->sta) {
- struct mt7615_sta *sta;
-
- sta = (struct mt7615_sta *)control->sta->drv_priv;
- wcid = &sta->wcid;
+ msta = (struct mt7615_sta *)control->sta->drv_priv;
+ wcid = &msta->wcid;
}
if (vif && !control->sta) {
struct mt7615_vif *mvif;
mvif = (struct mt7615_vif *)vif->drv_priv;
- wcid = &mvif->sta.wcid;
+ msta = &mvif->sta;
+ wcid = &msta->wcid;
+ }
+
+ if (!test_bit(MT76_STATE_PM, &mphy->state)) {
+ mt76_tx(mphy, control->sta, wcid, skb);
+ return;
+ }
+
+ qid = skb_get_queue_mapping(skb);
+ if (qid >= MT_TXQ_PSD) {
+ qid = IEEE80211_AC_BE;
+ skb_set_queue_mapping(skb, qid);
}
- mt76_tx(mphy, control->sta, wcid, skb);
+ spin_lock_bh(&dev->pm.txq_lock);
+ if (!dev->pm.tx_q[qid].skb) {
+ ieee80211_stop_queues(hw);
+ dev->pm.tx_q[qid].msta = msta;
+ dev->pm.tx_q[qid].skb = skb;
+ queue_work(dev->mt76.wq, &dev->pm.wake_work);
+ } else {
+ dev_kfree_skb(skb);
+ }
+ spin_unlock_bh(&dev->pm.txq_lock);
}
static int mt7615_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
@@ -619,9 +759,9 @@ static int mt7615_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt7615_phy *phy = mt7615_hw_phy(hw);
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
mt7615_mcu_set_rts_thresh(phy, val);
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return 0;
}
@@ -645,7 +785,8 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mtxq = (struct mt76_txq *)txq->drv_priv;
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
+
switch (action) {
case IEEE80211_AMPDU_RX_START:
mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,
@@ -660,6 +801,9 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mtxq->aggr = true;
mtxq->send_bar = false;
mt7615_mcu_add_tx_ba(dev, params, true);
+ ssn = mt7615_mac_get_sta_tid_sn(dev, msta->wcid.idx, tid);
+ ieee80211_send_bar(vif, sta->addr, tid,
+ IEEE80211_SN_TO_SEQ(ssn));
break;
case IEEE80211_AMPDU_TX_STOP_FLUSH:
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
@@ -667,6 +811,8 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mt7615_mcu_add_tx_ba(dev, params, false);
break;
case IEEE80211_AMPDU_TX_START:
+ ssn = mt7615_mac_get_sta_tid_sn(dev, msta->wcid.idx, tid);
+ params->ssn = ssn;
mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
break;
@@ -676,7 +822,7 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
break;
}
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return ret;
}
@@ -721,27 +867,47 @@ mt7615_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
u32 t32[2];
} tsf;
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
mt76_set(dev, MT_LPON_T0CR, MT_LPON_T0CR_MODE); /* TSF read */
tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0);
tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1);
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return tsf.t64;
}
static void
+mt7615_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ u64 timestamp)
+{
+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
+ union {
+ u64 t64;
+ u32 t32[2];
+ } tsf = { .t64 = timestamp, };
+
+ mt7615_mutex_acquire(dev);
+
+ mt76_wr(dev, MT_LPON_UTTR0, tsf.t32[0]);
+ mt76_wr(dev, MT_LPON_UTTR1, tsf.t32[1]);
+ /* TSF software overwrite */
+ mt76_set(dev, MT_LPON_T0CR, MT_LPON_T0CR_WRITE);
+
+ mt7615_mutex_release(dev);
+}
+
+static void
mt7615_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
{
struct mt7615_phy *phy = mt7615_hw_phy(hw);
struct mt7615_dev *dev = phy->dev;
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
phy->coverage_class = max_t(s16, coverage_class, 0);
mt7615_mac_set_timing(phy);
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
}
static int
@@ -758,7 +924,7 @@ mt7615_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
if ((BIT(hweight8(tx_ant)) - 1) != tx_ant)
tx_ant = BIT(ffs(tx_ant) - 1) - 1;
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
phy->mt76->antenna_mask = tx_ant;
if (ext_phy) {
@@ -771,7 +937,7 @@ mt7615_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
mt76_set_stream_caps(phy->mt76, true);
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return 0;
}
@@ -794,9 +960,11 @@ void mt7615_roc_work(struct work_struct *work)
if (!test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state))
return;
+ mt7615_mutex_acquire(phy->dev);
ieee80211_iterate_active_interfaces(phy->mt76->hw,
IEEE80211_IFACE_ITER_RESUME_ALL,
mt7615_roc_iter, phy);
+ mt7615_mutex_release(phy->dev);
ieee80211_remain_on_channel_expired(phy->mt76->hw);
}
@@ -844,17 +1012,26 @@ static int
mt7615_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_scan_request *req)
{
+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt76_phy *mphy = hw->priv;
+ int err;
+
+ mt7615_mutex_acquire(dev);
+ err = mt7615_mcu_hw_scan(mphy->priv, vif, req);
+ mt7615_mutex_release(dev);
- return mt7615_mcu_hw_scan(mphy->priv, vif, req);
+ return err;
}
static void
mt7615_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt76_phy *mphy = hw->priv;
+ mt7615_mutex_acquire(dev);
mt7615_mcu_cancel_hw_scan(mphy->priv, vif);
+ mt7615_mutex_release(dev);
}
static int
@@ -862,22 +1039,35 @@ mt7615_start_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *req,
struct ieee80211_scan_ies *ies)
{
+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt76_phy *mphy = hw->priv;
int err;
+ mt7615_mutex_acquire(dev);
+
err = mt7615_mcu_sched_scan_req(mphy->priv, vif, req);
if (err < 0)
- return err;
+ goto out;
+
+ err = mt7615_mcu_sched_scan_enable(mphy->priv, vif, true);
+out:
+ mt7615_mutex_release(dev);
- return mt7615_mcu_sched_scan_enable(mphy->priv, vif, true);
+ return err;
}
static int
mt7615_stop_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt76_phy *mphy = hw->priv;
+ int err;
- return mt7615_mcu_sched_scan_enable(mphy->priv, vif, false);
+ mt7615_mutex_acquire(dev);
+ err = mt7615_mcu_sched_scan_enable(mphy->priv, vif, false);
+ mt7615_mutex_release(dev);
+
+ return err;
}
static int mt7615_remain_on_channel(struct ieee80211_hw *hw,
@@ -892,20 +1082,24 @@ static int mt7615_remain_on_channel(struct ieee80211_hw *hw,
if (test_and_set_bit(MT76_STATE_ROC, &phy->mt76->state))
return 0;
+ mt7615_mutex_acquire(phy->dev);
+
err = mt7615_mcu_set_roc(phy, vif, chan, duration);
if (err < 0) {
clear_bit(MT76_STATE_ROC, &phy->mt76->state);
- return err;
+ goto out;
}
if (!wait_event_timeout(phy->roc_wait, phy->roc_grant, HZ)) {
mt7615_mcu_set_roc(phy, vif, NULL, 0);
clear_bit(MT76_STATE_ROC, &phy->mt76->state);
-
- return -ETIMEDOUT;
+ err = -ETIMEDOUT;
}
- return 0;
+out:
+ mt7615_mutex_release(phy->dev);
+
+ return err;
}
static int mt7615_cancel_remain_on_channel(struct ieee80211_hw *hw,
@@ -919,7 +1113,9 @@ static int mt7615_cancel_remain_on_channel(struct ieee80211_hw *hw,
del_timer_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
+ mt7615_mutex_acquire(phy->dev);
mt7615_mcu_set_roc(phy, vif, NULL, 0);
+ mt7615_mutex_release(phy->dev);
return 0;
}
@@ -933,7 +1129,10 @@ static int mt7615_suspend(struct ieee80211_hw *hw,
bool ext_phy = phy != &dev->phy;
int err = 0;
- mutex_lock(&dev->mt76.mutex);
+ cancel_delayed_work_sync(&dev->pm.ps_work);
+ mt7615_free_pending_tx_skbs(dev, NULL);
+
+ mt7615_mutex_acquire(dev);
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
cancel_delayed_work_sync(&phy->scan_work);
@@ -949,7 +1148,7 @@ static int mt7615_suspend(struct ieee80211_hw *hw,
if (!mt7615_dev_running(dev))
err = mt7615_mcu_set_hif_suspend(dev, true);
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return err;
}
@@ -960,7 +1159,7 @@ static int mt7615_resume(struct ieee80211_hw *hw)
struct mt7615_phy *phy = mt7615_hw_phy(hw);
bool running, ext_phy = phy != &dev->phy;
- mutex_lock(&dev->mt76.mutex);
+ mt7615_mutex_acquire(dev);
running = mt7615_dev_running(dev);
set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
@@ -970,7 +1169,7 @@ static int mt7615_resume(struct ieee80211_hw *hw)
err = mt7615_mcu_set_hif_suspend(dev, false);
if (err < 0) {
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return err;
}
}
@@ -984,7 +1183,7 @@ static int mt7615_resume(struct ieee80211_hw *hw)
MT7615_WATCHDOG_TIME);
mt76_clear(dev, MT_WF_RFCR(ext_phy), MT_WF_RFCR_DROP_OTHER_BEACON);
- mutex_unlock(&dev->mt76.mutex);
+ mt7615_mutex_release(dev);
return 0;
}
@@ -1001,7 +1200,11 @@ static void mt7615_set_rekey_data(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_gtk_rekey_data *data)
{
+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
+
+ mt7615_mutex_acquire(dev);
mt7615_mcu_update_gtk_rekey(hw, vif, data);
+ mt7615_mutex_release(dev);
}
#endif /* CONFIG_PM */
@@ -1021,7 +1224,7 @@ const struct ieee80211_ops mt7615_ops = {
.set_key = mt7615_set_key,
.ampdu_action = mt7615_ampdu_action,
.set_rts_threshold = mt7615_set_rts_threshold,
- .wake_tx_queue = mt76_wake_tx_queue,
+ .wake_tx_queue = mt7615_wake_tx_queue,
.sta_rate_tbl_update = mt7615_sta_rate_tbl_update,
.sw_scan_start = mt76_sw_scan,
.sw_scan_complete = mt76_sw_scan_complete,
@@ -1030,6 +1233,7 @@ const struct ieee80211_ops mt7615_ops = {
.channel_switch_beacon = mt7615_channel_switch_beacon,
.get_stats = mt7615_get_stats,
.get_tsf = mt7615_get_tsf,
+ .set_tsf = mt7615_set_tsf,
.get_survey = mt76_get_survey,
.get_antenna = mt76_get_antenna,
.set_antenna = mt7615_set_antenna,
@@ -1040,6 +1244,8 @@ const struct ieee80211_ops mt7615_ops = {
.sched_scan_stop = mt7615_stop_sched_scan,
.remain_on_channel = mt7615_remain_on_channel,
.cancel_remain_on_channel = mt7615_cancel_remain_on_channel,
+ CFG80211_TESTMODE_CMD(mt76_testmode_cmd)
+ CFG80211_TESTMODE_DUMP(mt76_testmode_dump)
#ifdef CONFIG_PM
.suspend = mt7615_suspend,
.resume = mt7615_resume,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
index 6e869b8c5e26..d0cbb283982f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
@@ -146,13 +146,19 @@ void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,
mcu_txd->cid = mcu_cmd;
break;
case MCU_CE_PREFIX:
- mcu_txd->set_query = MCU_Q_SET;
+ if (cmd & MCU_QUERY_MASK)
+ mcu_txd->set_query = MCU_Q_QUERY;
+ else
+ mcu_txd->set_query = MCU_Q_SET;
mcu_txd->cid = mcu_cmd;
break;
default:
mcu_txd->cid = MCU_CMD_EXT_CID;
- mcu_txd->set_query = MCU_Q_SET;
- mcu_txd->ext_cid = cmd;
+ if (cmd & MCU_QUERY_PREFIX)
+ mcu_txd->set_query = MCU_Q_QUERY;
+ else
+ mcu_txd->set_query = MCU_Q_SET;
+ mcu_txd->ext_cid = mcu_cmd;
mcu_txd->ext_cid_ack = 1;
break;
}
@@ -180,8 +186,10 @@ mt7615_mcu_parse_response(struct mt7615_dev *dev, int cmd,
struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;
int ret = 0;
- if (seq != rxd->seq)
- return -EAGAIN;
+ if (seq != rxd->seq) {
+ ret = -EAGAIN;
+ goto out;
+ }
switch (cmd) {
case MCU_CMD_PATCH_SEM_CONTROL:
@@ -192,6 +200,10 @@ mt7615_mcu_parse_response(struct mt7615_dev *dev, int cmd,
skb_pull(skb, sizeof(*rxd));
ret = le32_to_cpu(*(__le32 *)skb->data);
break;
+ case MCU_EXT_CMD_RF_REG_ACCESS | MCU_QUERY_PREFIX:
+ skb_pull(skb, sizeof(*rxd));
+ ret = le32_to_cpu(*(__le32 *)&skb->data[8]);
+ break;
case MCU_UNI_CMD_DEV_INFO_UPDATE:
case MCU_UNI_CMD_BSS_INFO_UPDATE:
case MCU_UNI_CMD_STA_REC_UPDATE:
@@ -205,9 +217,18 @@ mt7615_mcu_parse_response(struct mt7615_dev *dev, int cmd,
ret = le32_to_cpu(event->status);
break;
}
+ case MCU_CMD_REG_READ: {
+ struct mt7615_mcu_reg_event *event;
+
+ skb_pull(skb, sizeof(*rxd));
+ event = (struct mt7615_mcu_reg_event *)skb->data;
+ ret = (int)le32_to_cpu(event->val);
+ break;
+ }
default:
break;
}
+out:
dev_kfree_skb(skb);
return ret;
@@ -271,6 +292,38 @@ int mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
}
EXPORT_SYMBOL_GPL(mt7615_mcu_msg_send);
+u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg)
+{
+ struct {
+ __le32 wifi_stream;
+ __le32 address;
+ __le32 data;
+ } req = {
+ .wifi_stream = cpu_to_le32(wf),
+ .address = cpu_to_le32(reg),
+ };
+
+ return __mt76_mcu_send_msg(&dev->mt76,
+ MCU_EXT_CMD_RF_REG_ACCESS | MCU_QUERY_PREFIX,
+ &req, sizeof(req), true);
+}
+
+int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val)
+{
+ struct {
+ __le32 wifi_stream;
+ __le32 address;
+ __le32 data;
+ } req = {
+ .wifi_stream = cpu_to_le32(wf),
+ .address = cpu_to_le32(reg),
+ .data = cpu_to_le32(val),
+ };
+
+ return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_RF_REG_ACCESS, &req,
+ sizeof(req), false);
+}
+
static void
mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
@@ -927,6 +980,38 @@ mt7615_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
}
static void
+mt7615_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct sta_rec_uapsd *uapsd;
+ struct tlv *tlv;
+
+ if (vif->type != NL80211_IFTYPE_AP || !sta->wme)
+ return;
+
+ tlv = mt7615_mcu_add_tlv(skb, STA_REC_APPS, sizeof(*uapsd));
+ uapsd = (struct sta_rec_uapsd *)tlv;
+
+ if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) {
+ uapsd->dac_map |= BIT(3);
+ uapsd->tac_map |= BIT(3);
+ }
+ if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) {
+ uapsd->dac_map |= BIT(2);
+ uapsd->tac_map |= BIT(2);
+ }
+ if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) {
+ uapsd->dac_map |= BIT(1);
+ uapsd->tac_map |= BIT(1);
+ }
+ if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) {
+ uapsd->dac_map |= BIT(0);
+ uapsd->tac_map |= BIT(0);
+ }
+ uapsd->max_sp = sta->max_sp;
+}
+
+static void
mt7615_mcu_wtbl_ba_tlv(struct sk_buff *skb,
struct ieee80211_ampdu_params *params,
bool enable, bool tx, void *sta_wtbl,
@@ -1188,8 +1273,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_dev *dev, struct ieee80211_vif *vif,
return PTR_ERR(sskb);
mt7615_mcu_sta_basic_tlv(sskb, vif, sta, enable);
- if (enable && sta)
+ if (enable && sta) {
mt7615_mcu_sta_ht_tlv(sskb, sta);
+ mt7615_mcu_sta_uapsd(sskb, vif, sta);
+ }
wtbl_hdr = mt7615_mcu_alloc_wtbl_req(dev, msta, WTBL_RESET_AND_SET,
NULL, &wskb);
@@ -1206,8 +1293,12 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_dev *dev, struct ieee80211_vif *vif,
skb = enable ? wskb : sskb;
err = __mt76_mcu_skb_send_msg(&dev->mt76, skb, cmd, true);
- if (err < 0)
+ if (err < 0) {
+ skb = enable ? sskb : wskb;
+ dev_kfree_skb(skb);
+
return err;
+ }
cmd = enable ? MCU_EXT_CMD_STA_REC_UPDATE : MCU_EXT_CMD_WTBL_UPDATE;
skb = enable ? sskb : wskb;
@@ -1285,8 +1376,10 @@ mt7615_mcu_add_sta_cmd(struct mt7615_dev *dev, struct ieee80211_vif *vif,
return PTR_ERR(skb);
mt7615_mcu_sta_basic_tlv(skb, vif, sta, enable);
- if (enable && sta)
+ if (enable && sta) {
mt7615_mcu_sta_ht_tlv(skb, sta);
+ mt7615_mcu_sta_uapsd(skb, vif, sta);
+ }
sta_wtbl = mt7615_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));
@@ -1429,6 +1522,7 @@ mt7615_mcu_uni_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif,
u8 pad[3];
} __packed hdr;
struct mt7615_bss_basic_tlv basic;
+ struct mt7615_bss_qos_tlv qos;
} basic_req = {
.hdr = {
.bss_idx = mvif->idx,
@@ -1444,6 +1538,11 @@ mt7615_mcu_uni_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif,
.active = true, /* keep bss deactivated */
.phymode = 0x38,
},
+ .qos = {
+ .tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
+ .len = cpu_to_le16(sizeof(struct mt7615_bss_qos_tlv)),
+ .qos = vif->bss_conf.qos,
+ },
};
struct {
struct {
@@ -1808,44 +1907,66 @@ static void mt7622_trigger_hif_int(struct mt7615_dev *dev, bool en)
int mt7615_driver_own(struct mt7615_dev *dev)
{
+ struct mt76_phy *mphy = &dev->mt76.phy;
struct mt76_dev *mdev = &dev->mt76;
- u32 addr;
+ int i;
- addr = is_mt7663(mdev) ? MT_PCIE_DOORBELL_PUSH : MT_CFG_LPCR_HOST;
- mt76_wr(dev, addr, MT_CFG_LPCR_HOST_DRV_OWN);
+ if (!test_and_clear_bit(MT76_STATE_PM, &mphy->state))
+ goto out;
mt7622_trigger_hif_int(dev, true);
- addr = is_mt7663(mdev) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;
- if (!mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN, 0, 3000)) {
- dev_err(dev->mt76.dev, "Timeout for driver own\n");
- return -EIO;
+ for (i = 0; i < MT7615_DRV_OWN_RETRY_COUNT; i++) {
+ u32 addr;
+
+ addr = is_mt7663(mdev) ? MT_PCIE_DOORBELL_PUSH : MT_CFG_LPCR_HOST;
+ mt76_wr(dev, addr, MT_CFG_LPCR_HOST_DRV_OWN);
+
+ addr = is_mt7663(mdev) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;
+ if (mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN, 0, 50))
+ break;
}
mt7622_trigger_hif_int(dev, false);
+ if (i == MT7615_DRV_OWN_RETRY_COUNT) {
+ dev_err(mdev->dev, "driver own failed\n");
+ set_bit(MT76_STATE_PM, &mphy->state);
+ return -EIO;
+ }
+
+out:
+ dev->pm.last_activity = jiffies;
+
return 0;
}
EXPORT_SYMBOL_GPL(mt7615_driver_own);
int mt7615_firmware_own(struct mt7615_dev *dev)
{
+ struct mt76_phy *mphy = &dev->mt76.phy;
+ int err = 0;
u32 addr;
- addr = is_mt7663(&dev->mt76) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;
+ if (test_and_set_bit(MT76_STATE_PM, &mphy->state))
+ return 0;
+
mt7622_trigger_hif_int(dev, true);
+ addr = is_mt7663(&dev->mt76) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;
mt76_wr(dev, addr, MT_CFG_LPCR_HOST_FW_OWN);
- if (!is_mt7615(&dev->mt76) &&
+ if (is_mt7622(&dev->mt76) &&
!mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN,
- MT_CFG_LPCR_HOST_FW_OWN, 3000)) {
+ MT_CFG_LPCR_HOST_FW_OWN, 300)) {
dev_err(dev->mt76.dev, "Timeout for firmware own\n");
- return -EIO;
+ clear_bit(MT76_STATE_PM, &mphy->state);
+ err = -EIO;
}
+
mt7622_trigger_hif_int(dev, false);
- return 0;
+ return err;
}
EXPORT_SYMBOL_GPL(mt7615_firmware_own);
@@ -2725,6 +2846,14 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
.center_chan2 = ieee80211_frequency_to_channel(freq2),
};
+#ifdef CONFIG_NL80211_TESTMODE
+ if (dev->mt76.test.state == MT76_TM_STATE_TX_FRAMES &&
+ dev->mt76.test.tx_antenna_mask) {
+ req.tx_streams = hweight8(dev->mt76.test.tx_antenna_mask);
+ req.rx_streams_mask = dev->mt76.test.tx_antenna_mask;
+ }
+#endif
+
if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
else if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) &&
@@ -2736,7 +2865,10 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
req.band_idx = phy != &dev->phy;
req.bw = mt7615_mcu_chan_bw(chandef);
- mt7615_mcu_set_txpower_sku(phy, req.txpower_sku);
+ if (mt76_testmode_enabled(&dev->mt76))
+ memset(req.txpower_sku, 0x3f, 49);
+ else
+ mt7615_mcu_set_txpower_sku(phy, req.txpower_sku);
return __mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);
}
@@ -2754,6 +2886,27 @@ int mt7615_mcu_get_temperature(struct mt7615_dev *dev, int index)
sizeof(req), true);
}
+int mt7615_mcu_set_test_param(struct mt7615_dev *dev, u8 param, bool test_mode,
+ u32 val)
+{
+ struct {
+ u8 test_mode_en;
+ u8 param_idx;
+ u8 _rsv[2];
+
+ __le32 value;
+
+ u8 pad[8];
+ } req = {
+ .test_mode_en = test_mode,
+ .param_idx = param,
+ .value = cpu_to_le32(val),
+ };
+
+ return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req,
+ sizeof(req), false);
+}
+
int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable)
{
struct mt7615_dev *dev = phy->dev;
@@ -3332,43 +3485,8 @@ out:
return ret;
}
-#ifdef CONFIG_PM
-int mt7615_mcu_set_hif_suspend(struct mt7615_dev *dev, bool suspend)
-{
- struct {
- struct {
- u8 hif_type; /* 0x0: HIF_SDIO
- * 0x1: HIF_USB
- * 0x2: HIF_PCIE
- */
- u8 pad[3];
- } __packed hdr;
- struct hif_suspend_tlv {
- __le16 tag;
- __le16 len;
- u8 suspend;
- } __packed hif_suspend;
- } req = {
- .hif_suspend = {
- .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
- .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
- .suspend = suspend,
- },
- };
-
- if (mt76_is_mmio(&dev->mt76))
- req.hdr.hif_type = 2;
- else if (mt76_is_usb(&dev->mt76))
- req.hdr.hif_type = 1;
-
- return __mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_HIF_CTRL,
- &req, sizeof(req), true);
-}
-EXPORT_SYMBOL_GPL(mt7615_mcu_set_hif_suspend);
-
-static int
-mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
- bool enable)
+int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
+ bool enable)
{
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
struct {
@@ -3408,6 +3526,40 @@ mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
&req, sizeof(req), false);
}
+#ifdef CONFIG_PM
+int mt7615_mcu_set_hif_suspend(struct mt7615_dev *dev, bool suspend)
+{
+ struct {
+ struct {
+ u8 hif_type; /* 0x0: HIF_SDIO
+ * 0x1: HIF_USB
+ * 0x2: HIF_PCIE
+ */
+ u8 pad[3];
+ } __packed hdr;
+ struct hif_suspend_tlv {
+ __le16 tag;
+ __le16 len;
+ u8 suspend;
+ } __packed hif_suspend;
+ } req = {
+ .hif_suspend = {
+ .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
+ .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
+ .suspend = suspend,
+ },
+ };
+
+ if (mt76_is_mmio(&dev->mt76))
+ req.hdr.hif_type = 2;
+ else if (mt76_is_usb(&dev->mt76))
+ req.hdr.hif_type = 1;
+
+ return __mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_HIF_CTRL,
+ &req, sizeof(req), true);
+}
+EXPORT_SYMBOL_GPL(mt7615_mcu_set_hif_suspend);
+
static int
mt7615_mcu_set_wow_ctrl(struct mt7615_phy *phy, struct ieee80211_vif *vif,
bool suspend, struct cfg80211_wowlan *wowlan)
@@ -3542,6 +3694,32 @@ mt7615_mcu_set_gtk_rekey(struct mt7615_dev *dev,
&req, sizeof(req), true);
}
+static int
+mt7615_mcu_set_arp_filter(struct mt7615_dev *dev, struct ieee80211_vif *vif,
+ bool suspend)
+{
+ struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
+ struct {
+ struct {
+ u8 bss_idx;
+ u8 pad[3];
+ } __packed hdr;
+ struct mt7615_arpns_tlv arpns;
+ } req = {
+ .hdr = {
+ .bss_idx = mvif->idx,
+ },
+ .arpns = {
+ .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
+ .len = cpu_to_le16(sizeof(struct mt7615_arpns_tlv)),
+ .mode = suspend,
+ },
+ };
+
+ return __mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_OFFLOAD,
+ &req, sizeof(req), true);
+}
+
void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac,
struct ieee80211_vif *vif)
{
@@ -3554,6 +3732,7 @@ void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac,
mt7615_mcu_set_bss_pm(phy->dev, vif, suspend);
mt7615_mcu_set_gtk_rekey(phy->dev, vif, suspend);
+ mt7615_mcu_set_arp_filter(phy->dev, vif, suspend);
mt7615_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
@@ -3653,6 +3832,53 @@ int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,
sizeof(req), false);
}
+int mt7615_mcu_update_arp_filter(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info)
+{
+ struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
+ struct sk_buff *skb;
+ int i, len = min_t(int, info->arp_addr_cnt,
+ IEEE80211_BSS_ARP_ADDR_LIST_LEN);
+ struct {
+ struct {
+ u8 bss_idx;
+ u8 pad[3];
+ } __packed hdr;
+ struct mt7615_arpns_tlv arp;
+ } req_hdr = {
+ .hdr = {
+ .bss_idx = mvif->idx,
+ },
+ .arp = {
+ .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
+ .len = cpu_to_le16(sizeof(struct mt7615_arpns_tlv)),
+ .ips_num = len,
+ .mode = 2, /* update */
+ .option = 1,
+ },
+ };
+
+ if (!mt7615_firmware_offload(dev))
+ return 0;
+
+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
+ sizeof(req_hdr) + len * sizeof(__be32));
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put_data(skb, &req_hdr, sizeof(req_hdr));
+ for (i = 0; i < len; i++) {
+ u8 *addr = (u8 *)skb_put(skb, sizeof(__be32));
+
+ memcpy(addr, &info->arp_addr_list[i], sizeof(__be32));
+ }
+
+ return __mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_UNI_CMD_OFFLOAD, true);
+}
+
int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
@@ -3674,3 +3900,32 @@ int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
return __mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_P2P_OPPPS,
&req, sizeof(req), false);
}
+
+u32 mt7615_mcu_reg_rr(struct mt76_dev *dev, u32 offset)
+{
+ struct {
+ __le32 addr;
+ __le32 val;
+ } __packed req = {
+ .addr = cpu_to_le32(offset),
+ };
+
+ return __mt76_mcu_send_msg(dev, MCU_CMD_REG_READ,
+ &req, sizeof(req), true);
+}
+EXPORT_SYMBOL_GPL(mt7615_mcu_reg_rr);
+
+void mt7615_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val)
+{
+ struct {
+ __le32 addr;
+ __le32 val;
+ } __packed req = {
+ .addr = cpu_to_le32(offset),
+ .val = cpu_to_le32(val),
+ };
+
+ __mt76_mcu_send_msg(dev, MCU_CMD_REG_WRITE,
+ &req, sizeof(req), false);
+}
+EXPORT_SYMBOL_GPL(mt7615_mcu_reg_wr);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
index 2314d0b23af1..7b856e9eee1e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
@@ -81,6 +81,7 @@ enum {
MCU_EVENT_GENERIC = 0x01,
MCU_EVENT_ACCESS_REG = 0x02,
MCU_EVENT_MT_PATCH_SEM = 0x04,
+ MCU_EVENT_REG_ACCESS = 0x05,
MCU_EVENT_SCAN_DONE = 0x0d,
MCU_EVENT_ROC = 0x10,
MCU_EVENT_BSS_ABSENCE = 0x11,
@@ -238,8 +239,11 @@ enum {
#define MCU_FW_PREFIX BIT(31)
#define MCU_UNI_PREFIX BIT(30)
#define MCU_CE_PREFIX BIT(29)
+#define MCU_QUERY_PREFIX BIT(28)
#define MCU_CMD_MASK ~(MCU_FW_PREFIX | MCU_UNI_PREFIX | \
- MCU_CE_PREFIX)
+ MCU_CE_PREFIX | MCU_QUERY_PREFIX)
+
+#define MCU_QUERY_MASK BIT(16)
enum {
MCU_CMD_TARGET_ADDRESS_LEN_REQ = MCU_FW_PREFIX | 0x01,
@@ -254,6 +258,7 @@ enum {
};
enum {
+ MCU_EXT_CMD_RF_REG_ACCESS = 0x02,
MCU_EXT_CMD_PM_STATE_CTRL = 0x07,
MCU_EXT_CMD_CHANNEL_SWITCH = 0x08,
MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11,
@@ -266,6 +271,7 @@ enum {
MCU_EXT_CMD_GET_TEMP = 0x2c,
MCU_EXT_CMD_WTBL_UPDATE = 0x32,
MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
+ MCU_EXT_CMD_ATE_CTRL = 0x3d,
MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
MCU_EXT_CMD_DBDC_CTRL = 0x45,
MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
@@ -287,6 +293,11 @@ enum {
MCU_UNI_CMD_HIF_CTRL = MCU_UNI_PREFIX | 0x07,
};
+enum {
+ MCU_ATE_SET_FREQ_OFFSET = 0xa,
+ MCU_ATE_SET_TX_POWER_CONTROL = 0x15,
+};
+
struct mt7615_mcu_uni_event {
u8 cid;
u8 pad[3];
@@ -421,6 +432,11 @@ struct nt7615_sched_scan_done {
__le16 pad;
} __packed;
+struct mt7615_mcu_reg_event {
+ __le32 reg;
+ __le32 val;
+} __packed;
+
struct mt7615_mcu_bss_event {
u8 bss_idx;
u8 is_absent;
@@ -454,6 +470,13 @@ struct mt7615_bss_basic_tlv {
u8 pad[3];
} __packed;
+struct mt7615_bss_qos_tlv {
+ __le16 tag;
+ __le16 len;
+ u8 qos;
+ u8 pad[3];
+} __packed;
+
struct mt7615_wow_ctrl_tlv {
__le16 tag;
__le16 len;
@@ -545,6 +568,15 @@ struct mt7615_roc_tlv {
u8 rsv1[8];
} __packed;
+struct mt7615_arpns_tlv {
+ __le16 tag;
+ __le16 len;
+ u8 mode;
+ u8 ips_num;
+ u8 option;
+ u8 pad[1];
+} __packed;
+
/* offload mcu commands */
enum {
MCU_CMD_START_HW_SCAN = MCU_CE_PREFIX | 0x03,
@@ -557,6 +589,8 @@ enum {
MCU_CMD_SET_P2P_OPPPS = MCU_CE_PREFIX | 0x33,
MCU_CMD_SCHED_SCAN_ENABLE = MCU_CE_PREFIX | 0x61,
MCU_CMD_SCHED_SCAN_REQ = MCU_CE_PREFIX | 0x62,
+ MCU_CMD_REG_WRITE = MCU_CE_PREFIX | 0xc0,
+ MCU_CMD_REG_READ = MCU_CE_PREFIX | MCU_QUERY_MASK | 0xc0,
};
#define MCU_CMD_ACK BIT(0)
@@ -569,6 +603,8 @@ enum {
UNI_BSS_INFO_BASIC = 0,
UNI_BSS_INFO_RLM = 2,
UNI_BSS_INFO_BCN_CONTENT = 7,
+ UNI_BSS_INFO_QBSS = 15,
+ UNI_BSS_INFO_UAPSD = 19,
};
enum {
@@ -580,8 +616,8 @@ enum {
};
enum {
- UNI_OFFLOAD_OFFLOAD_ARPNS_IPV4,
- UNI_OFFLOAD_OFFLOAD_ARPNS_IPV6,
+ UNI_OFFLOAD_OFFLOAD_ARP,
+ UNI_OFFLOAD_OFFLOAD_ND,
UNI_OFFLOAD_OFFLOAD_GTK_REKEY,
UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
};
@@ -882,6 +918,7 @@ struct wtbl_raw {
sizeof(struct sta_rec_basic) + \
sizeof(struct sta_rec_ht) + \
sizeof(struct sta_rec_vht) + \
+ sizeof(struct sta_rec_uapsd) + \
sizeof(struct tlv) + \
MT7615_WTBL_UPDATE_MAX_SIZE)
@@ -971,6 +1008,17 @@ struct sta_rec_ba {
__le16 winsize;
} __packed;
+struct sta_rec_uapsd {
+ __le16 tag;
+ __le16 len;
+ u8 dac_map;
+ u8 tac_map;
+ u8 max_sp;
+ u8 rsv0;
+ __le16 listen_interval;
+ u8 rsv1[2];
+} __packed;
+
enum {
STA_REC_BASIC,
STA_REC_RA,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
index 2e99845b9c96..133f93a6ed1b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
@@ -17,7 +17,6 @@ const u32 mt7615e_reg_map[] = {
[MT_CSR_BASE] = 0x07000,
[MT_PLE_BASE] = 0x08000,
[MT_PSE_BASE] = 0x0c000,
- [MT_PHY_BASE] = 0x10000,
[MT_CFG_BASE] = 0x20200,
[MT_AGG_BASE] = 0x20a00,
[MT_TMAC_BASE] = 0x21000,
@@ -44,7 +43,7 @@ const u32 mt7663e_reg_map[] = {
[MT_CSR_BASE] = 0x07000,
[MT_PLE_BASE] = 0x08000,
[MT_PSE_BASE] = 0x0c000,
- [MT_PHY_BASE] = 0x10000,
+ [MT_PP_BASE] = 0x0e000,
[MT_CFG_BASE] = 0x20000,
[MT_AGG_BASE] = 0x22000,
[MT_TMAC_BASE] = 0x24000,
@@ -140,6 +139,38 @@ static void mt7615_irq_tasklet(unsigned long data)
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
}
+static u32 __mt7615_reg_addr(struct mt7615_dev *dev, u32 addr)
+{
+ if (addr < 0x100000)
+ return addr;
+
+ return mt7615_reg_map(dev, addr);
+}
+
+static u32 mt7615_rr(struct mt76_dev *mdev, u32 offset)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ u32 addr = __mt7615_reg_addr(dev, offset);
+
+ return dev->bus_ops->rr(mdev, addr);
+}
+
+static void mt7615_wr(struct mt76_dev *mdev, u32 offset, u32 val)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ u32 addr = __mt7615_reg_addr(dev, offset);
+
+ dev->bus_ops->wr(mdev, addr, val);
+}
+
+static u32 mt7615_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ u32 addr = __mt7615_reg_addr(dev, offset);
+
+ return dev->bus_ops->rmw(mdev, addr, mask, val);
+}
+
int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
int irq, const u32 *map)
{
@@ -159,6 +190,7 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
.sta_remove = mt7615_mac_sta_remove,
.update_survey = mt7615_update_channel,
};
+ struct mt76_bus_ops *bus_ops;
struct ieee80211_ops *ops;
struct mt7615_dev *dev;
struct mt76_dev *mdev;
@@ -182,6 +214,19 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
(mt76_rr(dev, MT_HW_REV) & 0xff);
dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
+ dev->bus_ops = dev->mt76.bus;
+ bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),
+ GFP_KERNEL);
+ if (!bus_ops) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ bus_ops->rr = mt7615_rr;
+ bus_ops->wr = mt7615_wr;
+ bus_ops->rmw = mt7615_rmw;
+ dev->mt76.bus = bus_ops;
+
ret = devm_request_irq(mdev->dev, irq, mt7615_irq_handler,
IRQF_SHARED, KBUILD_MODNAME, dev);
if (ret)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index 3e7d51bf42a4..571eadc033a3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -4,6 +4,7 @@
#ifndef __MT7615_H
#define __MT7615_H
+#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/ktime.h>
#include <linux/regmap.h>
@@ -18,6 +19,7 @@
#define MT7615_WTBL_STA (MT7615_WTBL_RESERVED - \
MT7615_MAX_INTERFACES)
+#define MT7615_PM_TIMEOUT (HZ / 12)
#define MT7615_WATCHDOG_TIME (HZ / 10)
#define MT7615_HW_SCAN_TIMEOUT (HZ / 10)
#define MT7615_RESET_TIMEOUT (30 * HZ)
@@ -31,6 +33,8 @@
#define MT7615_RX_RING_SIZE 1024
#define MT7615_RX_MCU_RING_SIZE 512
+#define MT7615_DRV_OWN_RETRY_COUNT 10
+
#define MT7615_FIRMWARE_CR4 "mediatek/mt7615_cr4.bin"
#define MT7615_FIRMWARE_N9 "mediatek/mt7615_n9.bin"
#define MT7615_ROM_PATCH "mediatek/mt7615_rom_patch.bin"
@@ -169,6 +173,8 @@ struct mt7615_phy {
struct mt76_phy *mt76;
struct mt7615_dev *dev;
+ struct ieee80211_vif *monitor_vif;
+
u32 rxfilter;
u32 omac_mask;
@@ -240,10 +246,10 @@ struct mt7615_dev {
struct mt76_phy mphy;
};
+ const struct mt76_bus_ops *bus_ops;
struct tasklet_struct irq_tasklet;
struct mt7615_phy phy;
- u32 vif_mask;
u32 omac_mask;
u16 chainmask;
@@ -280,6 +286,37 @@ struct mt7615_dev {
struct work_struct wtbl_work;
struct list_head wd_head;
+
+ u32 debugfs_rf_wf;
+ u32 debugfs_rf_reg;
+
+#ifdef CONFIG_NL80211_TESTMODE
+ struct {
+ u32 *reg_backup;
+
+ s16 last_freq_offset;
+ u8 last_rcpi[4];
+ s8 last_ib_rssi;
+ s8 last_wb_rssi;
+ } test;
+#endif
+
+ struct {
+ bool enable;
+
+ spinlock_t txq_lock;
+ struct {
+ struct mt7615_sta *msta;
+ struct sk_buff *skb;
+ } tx_q[IEEE80211_NUM_ACS];
+
+ struct work_struct wake_work;
+ struct completion wake_cmpl;
+
+ struct delayed_work ps_work;
+ unsigned long last_activity;
+ unsigned long idle_timeout;
+ } pm;
};
enum tx_pkt_queue_idx {
@@ -372,8 +409,10 @@ extern struct ieee80211_rate mt7615_rates[12];
extern const struct ieee80211_ops mt7615_ops;
extern const u32 mt7615e_reg_map[__MT_BASE_MAX];
extern const u32 mt7663e_reg_map[__MT_BASE_MAX];
+extern const u32 mt7663_usb_sdio_reg_map[__MT_BASE_MAX];
extern struct pci_driver mt7615_pci_driver;
extern struct platform_driver mt7622_wmac_driver;
+extern const struct mt76_testmode_ops mt7615_testmode_ops;
#ifdef CONFIG_MT7622_WMAC
int mt7622_wmac_init(struct mt7615_dev *dev);
@@ -408,6 +447,11 @@ bool mt7615_wait_for_mcu_init(struct mt7615_dev *dev);
void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
struct ieee80211_tx_rate *probe_rate,
struct ieee80211_tx_rate *rates);
+int mt7615_pm_set_enable(struct mt7615_dev *dev, bool enable);
+void mt7615_pm_wake_work(struct work_struct *work);
+int mt7615_pm_wake(struct mt7615_dev *dev);
+void mt7615_pm_power_save_sched(struct mt7615_dev *dev);
+void mt7615_pm_power_save_work(struct work_struct *work);
int mt7615_mcu_del_wtbl_all(struct mt7615_dev *dev);
int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd);
int mt7615_mcu_set_wmm(struct mt7615_dev *dev, u8 queue,
@@ -462,6 +506,20 @@ static inline u16 mt7615_wtbl_size(struct mt7615_dev *dev)
return MT7615_WTBL_SIZE;
}
+static inline void mt7615_mutex_acquire(struct mt7615_dev *dev)
+ __acquires(&dev->mt76.mutex)
+{
+ mutex_lock(&dev->mt76.mutex);
+ mt7615_pm_wake(dev);
+}
+
+static inline void mt7615_mutex_release(struct mt7615_dev *dev)
+ __releases(&dev->mt76.mutex)
+{
+ mt7615_pm_power_save_sched(dev);
+ mutex_unlock(&dev->mt76.mutex);
+}
+
static inline u8 mt7615_lmac_mapping(struct mt7615_dev *dev, u8 ac)
{
static const u8 lmac_queue_map[] = {
@@ -485,6 +543,7 @@ void mt7615_init_txpower(struct mt7615_dev *dev,
struct ieee80211_supported_band *sband);
void mt7615_phy_init(struct mt7615_dev *dev);
void mt7615_mac_init(struct mt7615_dev *dev);
+int mt7615_set_channel(struct mt7615_phy *phy);
int mt7615_mcu_restart(struct mt76_dev *dev);
void mt7615_update_channel(struct mt76_dev *mdev);
@@ -516,15 +575,19 @@ int mt7615_mac_wtbl_update_key(struct mt7615_dev *dev,
enum mt7615_cipher_type cipher,
enum set_key_cmd cmd);
void mt7615_mac_reset_work(struct work_struct *work);
+u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid);
int mt7615_mcu_wait_response(struct mt7615_dev *dev, int cmd, int seq);
int mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
int len, bool wait_resp);
+u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg);
+int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val);
int mt7615_mcu_set_dbdc(struct mt7615_dev *dev);
int mt7615_mcu_set_eeprom(struct mt7615_dev *dev);
int mt7615_mcu_set_mac_enable(struct mt7615_dev *dev, int band, bool enable);
int mt7615_mcu_set_rts_thresh(struct mt7615_phy *phy, u32 val);
int mt7615_mcu_get_temperature(struct mt7615_dev *dev, int index);
+int mt7615_mcu_set_tx_power(struct mt7615_phy *phy);
void mt7615_mcu_exit(struct mt7615_dev *dev);
void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,
int cmd, int *wait_seq);
@@ -563,6 +626,8 @@ int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev,
const struct mt7615_dfs_pulse *pulse);
int mt7615_mcu_set_radar_th(struct mt7615_dev *dev, int index,
const struct mt7615_dfs_pattern *pattern);
+int mt7615_mcu_set_test_param(struct mt7615_dev *dev, u8 param, bool test_mode,
+ u32 val);
int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable);
int mt7615_mcu_apply_rx_dcoc(struct mt7615_phy *phy);
int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy);
@@ -579,18 +644,40 @@ int mt7615_driver_own(struct mt7615_dev *dev);
int mt7615_init_debugfs(struct mt7615_dev *dev);
int mt7615_mcu_wait_response(struct mt7615_dev *dev, int cmd, int seq);
+int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
+ bool enable);
int mt7615_mcu_set_hif_suspend(struct mt7615_dev *dev, bool suspend);
void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac,
struct ieee80211_vif *vif);
int mt7615_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_gtk_rekey_data *key);
-
+int mt7615_mcu_update_arp_filter(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info);
int __mt7663_load_firmware(struct mt7615_dev *dev);
+u32 mt7615_mcu_reg_rr(struct mt76_dev *dev, u32 offset);
+void mt7615_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val);
/* usb */
-void mt7663u_wtbl_work(struct work_struct *work);
+int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ enum mt76_txq_id qid, struct mt76_wcid *wcid,
+ struct ieee80211_sta *sta,
+ struct mt76_tx_info *tx_info);
+bool mt7663_usb_sdio_tx_status_data(struct mt76_dev *mdev, u8 *update);
+void mt7663_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,
+ enum mt76_txq_id qid,
+ struct mt76_queue_entry *e);
+void mt7663_usb_sdio_wtbl_work(struct work_struct *work);
+int mt7663_usb_sdio_register_device(struct mt7615_dev *dev);
int mt7663u_mcu_init(struct mt7615_dev *dev);
-int mt7663u_register_device(struct mt7615_dev *dev);
+
+/* sdio */
+u32 mt7663s_read_pcr(struct mt7615_dev *dev);
+int mt7663s_mcu_init(struct mt7615_dev *dev);
+int mt7663s_driver_own(struct mt7615_dev *dev);
+int mt7663s_firmware_own(struct mt7615_dev *dev);
+int mt7663s_kthread_run(void *data);
+void mt7663s_sdio_irq(struct sdio_func *func);
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci.c
index ba12f199bce0..2328d78e06a1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci.c
@@ -75,6 +75,10 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)
bool hif_suspend;
int i, err;
+ err = mt7615_pm_wake(dev);
+ if (err < 0)
+ return err;
+
hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
mt7615_firmware_offload(dev);
if (hif_suspend) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
index 69cba8609edf..7224a0078211 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
@@ -70,6 +70,10 @@ mt7615_led_set_config(struct led_classdev *led_cdev,
mt76 = container_of(led_cdev, struct mt76_dev, led_cdev);
dev = container_of(mt76, struct mt7615_dev, mt76);
+
+ if (test_bit(MT76_STATE_PM, &mt76->phy.state))
+ return;
+
val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |
FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
FIELD_PREP(MT_LED_STATUS_ON, delay_on);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
index 7ec91c0856f5..2d67f9a148cd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
@@ -155,7 +155,6 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
spin_lock_bh(&dev->mt76.lock);
mt7615_mac_set_rates(phy, msta, &info->control.rates[0],
msta->rates);
- msta->rate_probe = true;
spin_unlock_bh(&dev->mt76.lock);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h
index aee433a9eff6..9137d9e6b51d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h
@@ -14,7 +14,6 @@ enum mt7615_reg_base {
MT_CSR_BASE,
MT_PLE_BASE,
MT_PSE_BASE,
- MT_PHY_BASE,
MT_CFG_BASE,
MT_AGG_BASE,
MT_TMAC_BASE,
@@ -29,6 +28,7 @@ enum mt7615_reg_base {
MT_PCIE_REMAP_BASE2,
MT_TOP_MISC_BASE,
MT_EFUSE_ADDR_BASE,
+ MT_PP_BASE,
__MT_BASE_MAX,
};
@@ -153,6 +153,8 @@ enum mt7615_reg_base {
#define MT_PLE(ofs) ((dev)->reg_map[MT_PLE_BASE] + (ofs))
+#define MT_PLE_PG_HIF0_GROUP MT_PLE(0x110)
+#define MT_HIF0_MIN_QUOTA GENMASK(11, 0)
#define MT_PLE_FL_Q0_CTRL MT_PLE(0x1b0)
#define MT_PLE_FL_Q1_CTRL MT_PLE(0x1b4)
#define MT_PLE_FL_Q2_CTRL MT_PLE(0x1b8)
@@ -162,6 +164,10 @@ enum mt7615_reg_base {
((n) << 2))
#define MT_PSE(ofs) ((dev)->reg_map[MT_PSE_BASE] + (ofs))
+#define MT_PSE_PG_HIF0_GROUP MT_PSE(0x110)
+#define MT_HIF0_MIN_QUOTA GENMASK(11, 0)
+#define MT_PSE_PG_HIF1_GROUP MT_PSE(0x118)
+#define MT_HIF1_MIN_QUOTA GENMASK(11, 0)
#define MT_PSE_QUEUE_EMPTY MT_PSE(0x0b4)
#define MT_HIF_0_EMPTY_MASK BIT(16)
#define MT_HIF_1_EMPTY_MASK BIT(17)
@@ -169,7 +175,12 @@ enum mt7615_reg_base {
#define MT_PSE_PG_INFO MT_PSE(0x194)
#define MT_PSE_SRC_CNT GENMASK(27, 16)
-#define MT_WF_PHY_BASE ((dev)->reg_map[MT_PHY_BASE])
+#define MT_PP(ofs) ((dev)->reg_map[MT_PP_BASE] + (ofs))
+#define MT_PP_TXDWCNT MT_PP(0x0)
+#define MT_PP_TXDWCNT_TX0_ADD_DW_CNT GENMASK(7, 0)
+#define MT_PP_TXDWCNT_TX1_ADD_DW_CNT GENMASK(15, 8)
+
+#define MT_WF_PHY_BASE 0x82070000
#define MT_WF_PHY(ofs) (MT_WF_PHY_BASE + (ofs))
#define MT_WF_PHY_WF2_RFCTRL0(n) MT_WF_PHY(0x1900 + (n) * 0x400)
@@ -213,6 +224,9 @@ enum mt7615_reg_base {
#define MT_WF_PHY_RXTD2_BASE MT_WF_PHY(0x2a00)
#define MT_WF_PHY_RXTD2(_n) (MT_WF_PHY_RXTD2_BASE + ((_n) << 2))
+#define MT_WF_PHY_RFINTF3_0(_n) MT_WF_PHY(0x1100 + (_n) * 0x400)
+#define MT_WF_PHY_RFINTF3_0_ANT GENMASK(7, 4)
+
#define MT_WF_CFG_BASE ((dev)->reg_map[MT_CFG_BASE])
#define MT_WF_CFG(ofs) (MT_WF_CFG_BASE + (ofs))
@@ -256,6 +270,13 @@ enum mt7615_reg_base {
#define MT_WF_ARB_BASE ((dev)->reg_map[MT_ARB_BASE])
#define MT_WF_ARB(ofs) (MT_WF_ARB_BASE + (ofs))
+#define MT_ARB_RQCR MT_WF_ARB(0x070)
+#define MT_ARB_RQCR_RX_START BIT(0)
+#define MT_ARB_RQCR_RXV_START BIT(4)
+#define MT_ARB_RQCR_RXV_R_EN BIT(7)
+#define MT_ARB_RQCR_RXV_T_EN BIT(8)
+#define MT_ARB_RQCR_BAND_SHIFT 16
+
#define MT_ARB_SCR MT_WF_ARB(0x080)
#define MT_ARB_SCR_TX0_DISABLE BIT(8)
#define MT_ARB_SCR_RX0_DISABLE BIT(9)
@@ -417,6 +438,7 @@ enum mt7615_reg_base {
#define MT_LPON_T0CR MT_LPON(0x010)
#define MT_LPON_T0CR_MODE GENMASK(1, 0)
+#define MT_LPON_T0CR_WRITE BIT(0)
#define MT_LPON_UTTR0 MT_LPON(0x018)
#define MT_LPON_UTTR1 MT_LPON(0x01c)
@@ -550,4 +572,11 @@ enum mt7615_reg_base {
#define MT_WL_RX_BUSY BIT(30)
#define MT_WL_TX_BUSY BIT(31)
+#define MT_MCU_PTA_BASE 0x81060000
+#define MT_MCU_PTA(_n) (MT_MCU_PTA_BASE + (_n))
+
+#define MT_ANT_SWITCH_CON(n) MT_MCU_PTA(0x0c8)
+#define MT_ANT_SWITCH_CON_MODE(_n) (GENMASK(4, 0) << (_n * 8))
+#define MT_ANT_SWITCH_CON_MODE1(_n) (GENMASK(3, 0) << (_n * 8))
+
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
new file mode 100644
index 000000000000..dabce51117b0
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
@@ -0,0 +1,478 @@
+// SPDX-License-Identifier: ISC
+/* Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Felix Fietkau <nbd@nbd.name>
+ * Lorenzo Bianconi <lorenzo@kernel.org>
+ * Sean Wang <sean.wang@mediatek.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "mt7615.h"
+#include "sdio.h"
+#include "mac.h"
+
+static const struct sdio_device_id mt7663s_table[] = {
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, 0x7603) },
+ { } /* Terminating entry */
+};
+
+static u32 mt7663s_read_whisr(struct mt76_dev *dev)
+{
+ return sdio_readl(dev->sdio.func, MCR_WHISR, NULL);
+}
+
+u32 mt7663s_read_pcr(struct mt7615_dev *dev)
+{
+ struct mt76_sdio *sdio = &dev->mt76.sdio;
+
+ return sdio_readl(sdio->func, MCR_WHLPCR, NULL);
+}
+
+static u32 mt7663s_read_mailbox(struct mt76_dev *dev, u32 offset)
+{
+ struct sdio_func *func = dev->sdio.func;
+ u32 val = ~0, status;
+ int err;
+
+ sdio_claim_host(func);
+
+ sdio_writel(func, offset, MCR_H2DSM0R, &err);
+ if (err < 0) {
+ dev_err(dev->dev, "failed setting address [err=%d]\n", err);
+ goto out;
+ }
+
+ sdio_writel(func, H2D_SW_INT_READ, MCR_WSICR, &err);
+ if (err < 0) {
+ dev_err(dev->dev, "failed setting read mode [err=%d]\n", err);
+ goto out;
+ }
+
+ err = readx_poll_timeout(mt7663s_read_whisr, dev, status,
+ status & H2D_SW_INT_READ, 0, 1000000);
+ if (err < 0) {
+ dev_err(dev->dev, "query whisr timeout\n");
+ goto out;
+ }
+
+ sdio_writel(func, H2D_SW_INT_READ, MCR_WHISR, &err);
+ if (err < 0) {
+ dev_err(dev->dev, "failed setting read mode [err=%d]\n", err);
+ goto out;
+ }
+
+ val = sdio_readl(func, MCR_H2DSM0R, &err);
+ if (err < 0) {
+ dev_err(dev->dev, "failed reading h2dsm0r [err=%d]\n", err);
+ goto out;
+ }
+
+ if (val != offset) {
+ dev_err(dev->dev, "register mismatch\n");
+ val = ~0;
+ goto out;
+ }
+
+ val = sdio_readl(func, MCR_D2HRM1R, &err);
+ if (err < 0)
+ dev_err(dev->dev, "failed reading d2hrm1r [err=%d]\n", err);
+
+out:
+ sdio_release_host(func);
+
+ return val;
+}
+
+static void mt7663s_write_mailbox(struct mt76_dev *dev, u32 offset, u32 val)
+{
+ struct sdio_func *func = dev->sdio.func;
+ u32 status;
+ int err;
+
+ sdio_claim_host(func);
+
+ sdio_writel(func, offset, MCR_H2DSM0R, &err);
+ if (err < 0) {
+ dev_err(dev->dev, "failed setting address [err=%d]\n", err);
+ goto out;
+ }
+
+ sdio_writel(func, val, MCR_H2DSM1R, &err);
+ if (err < 0) {
+ dev_err(dev->dev,
+ "failed setting write value [err=%d]\n", err);
+ goto out;
+ }
+
+ sdio_writel(func, H2D_SW_INT_WRITE, MCR_WSICR, &err);
+ if (err < 0) {
+ dev_err(dev->dev, "failed setting write mode [err=%d]\n", err);
+ goto out;
+ }
+
+ err = readx_poll_timeout(mt7663s_read_whisr, dev, status,
+ status & H2D_SW_INT_WRITE, 0, 1000000);
+ if (err < 0) {
+ dev_err(dev->dev, "query whisr timeout\n");
+ goto out;
+ }
+
+ sdio_writel(func, H2D_SW_INT_WRITE, MCR_WHISR, &err);
+ if (err < 0) {
+ dev_err(dev->dev, "failed setting write mode [err=%d]\n", err);
+ goto out;
+ }
+
+ val = sdio_readl(func, MCR_H2DSM0R, &err);
+ if (err < 0) {
+ dev_err(dev->dev, "failed reading h2dsm0r [err=%d]\n", err);
+ goto out;
+ }
+
+ if (val != offset)
+ dev_err(dev->dev, "register mismatch\n");
+
+out:
+ sdio_release_host(func);
+}
+
+static u32 mt7663s_rr(struct mt76_dev *dev, u32 offset)
+{
+ if (test_bit(MT76_STATE_MCU_RUNNING, &dev->phy.state))
+ return dev->mcu_ops->mcu_rr(dev, offset);
+ else
+ return mt7663s_read_mailbox(dev, offset);
+}
+
+static void mt7663s_wr(struct mt76_dev *dev, u32 offset, u32 val)
+{
+ if (test_bit(MT76_STATE_MCU_RUNNING, &dev->phy.state))
+ dev->mcu_ops->mcu_wr(dev, offset, val);
+ else
+ mt7663s_write_mailbox(dev, offset, val);
+}
+
+static u32 mt7663s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val)
+{
+ val |= mt7663s_rr(dev, offset) & ~mask;
+ mt7663s_wr(dev, offset, val);
+
+ return val;
+}
+
+static void mt7663s_write_copy(struct mt76_dev *dev, u32 offset,
+ const void *data, int len)
+{
+ const u32 *val = data;
+ int i;
+
+ for (i = 0; i < len / sizeof(u32); i++) {
+ mt7663s_wr(dev, offset, val[i]);
+ offset += sizeof(u32);
+ }
+}
+
+static void mt7663s_read_copy(struct mt76_dev *dev, u32 offset,
+ void *data, int len)
+{
+ u32 *val = data;
+ int i;
+
+ for (i = 0; i < len / sizeof(u32); i++) {
+ val[i] = mt7663s_rr(dev, offset);
+ offset += sizeof(u32);
+ }
+}
+
+static int mt7663s_wr_rp(struct mt76_dev *dev, u32 base,
+ const struct mt76_reg_pair *data,
+ int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ mt7663s_wr(dev, data->reg, data->value);
+ data++;
+ }
+
+ return 0;
+}
+
+static int mt7663s_rd_rp(struct mt76_dev *dev, u32 base,
+ struct mt76_reg_pair *data,
+ int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ data->value = mt7663s_rr(dev, data->reg);
+ data++;
+ }
+
+ return 0;
+}
+
+static void mt7663s_init_work(struct work_struct *work)
+{
+ struct mt7615_dev *dev;
+
+ dev = container_of(work, struct mt7615_dev, mcu_work);
+ if (mt7663s_mcu_init(dev))
+ return;
+
+ mt7615_mcu_set_eeprom(dev);
+ mt7615_mac_init(dev);
+ mt7615_phy_init(dev);
+ mt7615_mcu_del_wtbl_all(dev);
+ mt7615_check_offload_capability(dev);
+}
+
+static int mt7663s_hw_init(struct mt7615_dev *dev, struct sdio_func *func)
+{
+ u32 status, ctrl;
+ int ret;
+
+ sdio_claim_host(func);
+
+ ret = sdio_enable_func(func);
+ if (ret < 0)
+ goto release;
+
+ /* Get ownership from the device */
+ sdio_writel(func, WHLPCR_INT_EN_CLR | WHLPCR_FW_OWN_REQ_CLR,
+ MCR_WHLPCR, &ret);
+ if (ret < 0)
+ goto disable_func;
+
+ ret = readx_poll_timeout(mt7663s_read_pcr, dev, status,
+ status & WHLPCR_IS_DRIVER_OWN, 2000, 1000000);
+ if (ret < 0) {
+ dev_err(dev->mt76.dev, "Cannot get ownership from device");
+ goto disable_func;
+ }
+
+ ret = sdio_set_block_size(func, 512);
+ if (ret < 0)
+ goto disable_func;
+
+ /* Enable interrupt */
+ sdio_writel(func, WHLPCR_INT_EN_SET, MCR_WHLPCR, &ret);
+ if (ret < 0)
+ goto disable_func;
+
+ ctrl = WHIER_RX0_DONE_INT_EN | WHIER_TX_DONE_INT_EN;
+ sdio_writel(func, ctrl, MCR_WHIER, &ret);
+ if (ret < 0)
+ goto disable_func;
+
+ /* set WHISR as read clear and Rx aggregation number as 16 */
+ ctrl = FIELD_PREP(MAX_HIF_RX_LEN_NUM, 16);
+ sdio_writel(func, ctrl, MCR_WHCR, &ret);
+ if (ret < 0)
+ goto disable_func;
+
+ ret = sdio_claim_irq(func, mt7663s_sdio_irq);
+ if (ret < 0)
+ goto disable_func;
+
+ sdio_release_host(func);
+
+ return 0;
+
+disable_func:
+ sdio_disable_func(func);
+release:
+ sdio_release_host(func);
+
+ return ret;
+}
+
+static int mt7663s_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ struct mt76_sdio *sdio = &mdev->sdio;
+ u32 pse, ple;
+ int err;
+
+ err = mt7615_mac_sta_add(mdev, vif, sta);
+ if (err < 0)
+ return err;
+
+ /* init sched data quota */
+ pse = mt76_get_field(dev, MT_PSE_PG_HIF0_GROUP, MT_HIF0_MIN_QUOTA);
+ ple = mt76_get_field(dev, MT_PLE_PG_HIF0_GROUP, MT_HIF0_MIN_QUOTA);
+
+ mutex_lock(&sdio->sched.lock);
+ sdio->sched.pse_data_quota = pse;
+ sdio->sched.ple_data_quota = ple;
+ mutex_unlock(&sdio->sched.lock);
+
+ return 0;
+}
+
+static int mt7663s_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ static const struct mt76_driver_ops drv_ops = {
+ .txwi_size = MT_USB_TXD_SIZE,
+ .drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ,
+ .tx_prepare_skb = mt7663_usb_sdio_tx_prepare_skb,
+ .tx_complete_skb = mt7663_usb_sdio_tx_complete_skb,
+ .tx_status_data = mt7663_usb_sdio_tx_status_data,
+ .rx_skb = mt7615_queue_rx_skb,
+ .sta_ps = mt7615_sta_ps,
+ .sta_add = mt7663s_sta_add,
+ .sta_remove = mt7615_mac_sta_remove,
+ .update_survey = mt7615_update_channel,
+ };
+ static const struct mt76_bus_ops mt7663s_ops = {
+ .rr = mt7663s_rr,
+ .rmw = mt7663s_rmw,
+ .wr = mt7663s_wr,
+ .write_copy = mt7663s_write_copy,
+ .read_copy = mt7663s_read_copy,
+ .wr_rp = mt7663s_wr_rp,
+ .rd_rp = mt7663s_rd_rp,
+ .type = MT76_BUS_SDIO,
+ };
+ struct ieee80211_ops *ops;
+ struct mt7615_dev *dev;
+ struct mt76_dev *mdev;
+ int ret;
+
+ ops = devm_kmemdup(&func->dev, &mt7615_ops, sizeof(mt7615_ops),
+ GFP_KERNEL);
+ if (!ops)
+ return -ENOMEM;
+
+ mdev = mt76_alloc_device(&func->dev, sizeof(*dev), ops, &drv_ops);
+ if (!mdev)
+ return -ENOMEM;
+
+ dev = container_of(mdev, struct mt7615_dev, mt76);
+
+ INIT_WORK(&dev->mcu_work, mt7663s_init_work);
+ dev->reg_map = mt7663_usb_sdio_reg_map;
+ dev->ops = ops;
+ sdio_set_drvdata(func, dev);
+
+ mdev->sdio.tx_kthread = kthread_create(mt7663s_kthread_run, dev,
+ "mt7663s_tx");
+ if (IS_ERR(mdev->sdio.tx_kthread))
+ return PTR_ERR(mdev->sdio.tx_kthread);
+
+ ret = mt76s_init(mdev, func, &mt7663s_ops);
+ if (ret < 0)
+ goto err_free;
+
+ ret = mt7663s_hw_init(dev, func);
+ if (ret)
+ goto err_free;
+
+ mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
+ (mt76_rr(dev, MT_HW_REV) & 0xff);
+ dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
+
+ ret = mt76s_alloc_queues(&dev->mt76);
+ if (ret)
+ goto err_deinit;
+
+ ret = mt7663_usb_sdio_register_device(dev);
+ if (ret)
+ goto err_deinit;
+
+ return 0;
+
+err_deinit:
+ mt76s_deinit(&dev->mt76);
+err_free:
+ mt76_free_device(&dev->mt76);
+
+ return ret;
+}
+
+static void mt7663s_remove(struct sdio_func *func)
+{
+ struct mt7615_dev *dev = sdio_get_drvdata(func);
+
+ if (!test_and_clear_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
+ return;
+
+ ieee80211_unregister_hw(dev->mt76.hw);
+ mt76s_deinit(&dev->mt76);
+ mt76_free_device(&dev->mt76);
+}
+
+#ifdef CONFIG_PM
+static int mt7663s_suspend(struct device *dev)
+{
+ struct sdio_func *func = dev_to_sdio_func(dev);
+ struct mt7615_dev *mdev = sdio_get_drvdata(func);
+
+ if (!test_bit(MT76_STATE_SUSPEND, &mdev->mphy.state) &&
+ mt7615_firmware_offload(mdev)) {
+ int err;
+
+ err = mt7615_mcu_set_hif_suspend(mdev, true);
+ if (err < 0)
+ return err;
+ }
+
+ mt76s_stop_txrx(&mdev->mt76);
+
+ return mt7663s_firmware_own(mdev);
+}
+
+static int mt7663s_resume(struct device *dev)
+{
+ struct sdio_func *func = dev_to_sdio_func(dev);
+ struct mt7615_dev *mdev = sdio_get_drvdata(func);
+ int err;
+
+ err = mt7663s_driver_own(mdev);
+ if (err)
+ return err;
+
+ if (!test_bit(MT76_STATE_SUSPEND, &mdev->mphy.state) &&
+ mt7615_firmware_offload(mdev))
+ err = mt7615_mcu_set_hif_suspend(mdev, false);
+
+ return err;
+}
+
+static const struct dev_pm_ops mt7663s_pm_ops = {
+ .suspend = mt7663s_suspend,
+ .resume = mt7663s_resume,
+};
+#endif
+
+MODULE_DEVICE_TABLE(sdio, mt7663s_table);
+MODULE_FIRMWARE(MT7663_OFFLOAD_FIRMWARE_N9);
+MODULE_FIRMWARE(MT7663_OFFLOAD_ROM_PATCH);
+MODULE_FIRMWARE(MT7663_FIRMWARE_N9);
+MODULE_FIRMWARE(MT7663_ROM_PATCH);
+
+static struct sdio_driver mt7663s_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = mt7663s_probe,
+ .remove = mt7663s_remove,
+ .id_table = mt7663s_table,
+#ifdef CONFIG_PM
+ .drv = {
+ .pm = &mt7663s_pm_ops,
+ }
+#endif
+};
+module_sdio_driver(mt7663s_driver);
+
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.h b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.h
new file mode 100644
index 000000000000..05180971de84
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.h
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: ISC
+/* Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Sean Wang <sean.wang@mediatek.com>
+ */
+
+#ifndef __MT76S_H
+#define __MT76S_H
+
+#define MT_PSE_PAGE_SZ 128
+
+#define MCR_WCIR 0x0000
+#define MCR_WHLPCR 0x0004
+#define WHLPCR_FW_OWN_REQ_CLR BIT(9)
+#define WHLPCR_FW_OWN_REQ_SET BIT(8)
+#define WHLPCR_IS_DRIVER_OWN BIT(8)
+#define WHLPCR_INT_EN_CLR BIT(1)
+#define WHLPCR_INT_EN_SET BIT(0)
+
+#define MCR_WSDIOCSR 0x0008
+#define MCR_WHCR 0x000C
+#define W_INT_CLR_CTRL BIT(1)
+#define RECV_MAILBOX_RD_CLR_EN BIT(2)
+#define MAX_HIF_RX_LEN_NUM GENMASK(13, 8)
+#define RX_ENHANCE_MODE BIT(16)
+
+#define MCR_WHISR 0x0010
+#define MCR_WHIER 0x0014
+#define WHIER_D2H_SW_INT GENMASK(31, 8)
+#define WHIER_FW_OWN_BACK_INT_EN BIT(7)
+#define WHIER_ABNORMAL_INT_EN BIT(6)
+#define WHIER_RX1_DONE_INT_EN BIT(2)
+#define WHIER_RX0_DONE_INT_EN BIT(1)
+#define WHIER_TX_DONE_INT_EN BIT(0)
+#define WHIER_DEFAULT (WHIER_RX0_DONE_INT_EN | \
+ WHIER_RX1_DONE_INT_EN | \
+ WHIER_TX_DONE_INT_EN | \
+ WHIER_ABNORMAL_INT_EN | \
+ WHIER_D2H_SW_INT)
+
+#define MCR_WASR 0x0020
+#define MCR_WSICR 0x0024
+#define MCR_WTSR0 0x0028
+#define TQ0_CNT GENMASK(7, 0)
+#define TQ1_CNT GENMASK(15, 8)
+#define TQ2_CNT GENMASK(23, 16)
+#define TQ3_CNT GENMASK(31, 24)
+
+#define MCR_WTSR1 0x002c
+#define TQ4_CNT GENMASK(7, 0)
+#define TQ5_CNT GENMASK(15, 8)
+#define TQ6_CNT GENMASK(23, 16)
+#define TQ7_CNT GENMASK(31, 24)
+
+#define MCR_WTDR1 0x0034
+#define MCR_WRDR0 0x0050
+#define MCR_WRDR1 0x0054
+#define MCR_WRDR(p) (0x0050 + 4 * (p))
+#define MCR_H2DSM0R 0x0070
+#define H2D_SW_INT_READ BIT(16)
+#define H2D_SW_INT_WRITE BIT(17)
+
+#define MCR_H2DSM1R 0x0074
+#define MCR_D2HRM0R 0x0078
+#define MCR_D2HRM1R 0x007c
+#define MCR_D2HRM2R 0x0080
+#define MCR_WRPLR 0x0090
+#define RX0_PACKET_LENGTH GENMASK(15, 0)
+#define RX1_PACKET_LENGTH GENMASK(31, 16)
+
+#define MCR_WTMDR 0x00b0
+#define MCR_WTMCR 0x00b4
+#define MCR_WTMDPCR0 0x00b8
+#define MCR_WTMDPCR1 0x00bc
+#define MCR_WPLRCR 0x00d4
+#define MCR_WSR 0x00D8
+#define MCR_CLKIOCR 0x0100
+#define MCR_CMDIOCR 0x0104
+#define MCR_DAT0IOCR 0x0108
+#define MCR_DAT1IOCR 0x010C
+#define MCR_DAT2IOCR 0x0110
+#define MCR_DAT3IOCR 0x0114
+#define MCR_CLKDLYCR 0x0118
+#define MCR_CMDDLYCR 0x011C
+#define MCR_ODATDLYCR 0x0120
+#define MCR_IDATDLYCR1 0x0124
+#define MCR_IDATDLYCR2 0x0128
+#define MCR_ILCHCR 0x012C
+#define MCR_WTQCR0 0x0130
+#define MCR_WTQCR1 0x0134
+#define MCR_WTQCR2 0x0138
+#define MCR_WTQCR3 0x013C
+#define MCR_WTQCR4 0x0140
+#define MCR_WTQCR5 0x0144
+#define MCR_WTQCR6 0x0148
+#define MCR_WTQCR7 0x014C
+#define MCR_WTQCR(x) (0x130 + 4 * (x))
+#define TXQ_CNT_L GENMASK(15, 0)
+#define TXQ_CNT_H GENMASK(31, 16)
+
+#define MCR_SWPCDBGR 0x0154
+
+struct mt76s_intr {
+ u32 isr;
+ struct {
+ u32 wtqcr[8];
+ } tx;
+ struct {
+ u16 num[2];
+ u16 len[2][16];
+ } rx;
+ u32 rec_mb[2];
+} __packed;
+
+#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c
new file mode 100644
index 000000000000..28b86bec7fc2
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_mcu.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Felix Fietkau <nbd@nbd.name>
+ * Lorenzo Bianconi <lorenzo@kernel.org>
+ * Sean Wang <sean.wang@mediatek.com>
+ */
+#include <linux/kernel.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/module.h>
+#include <linux/iopoll.h>
+
+#include "mt7615.h"
+#include "mac.h"
+#include "mcu.h"
+#include "regs.h"
+#include "sdio.h"
+
+static int mt7663s_mcu_init_sched(struct mt7615_dev *dev)
+{
+ struct mt76_sdio *sdio = &dev->mt76.sdio;
+ u32 pse0, ple, pse1, txdwcnt;
+
+ pse0 = mt76_get_field(dev, MT_PSE_PG_HIF0_GROUP, MT_HIF0_MIN_QUOTA);
+ pse1 = mt76_get_field(dev, MT_PSE_PG_HIF1_GROUP, MT_HIF1_MIN_QUOTA);
+ ple = mt76_get_field(dev, MT_PLE_PG_HIF0_GROUP, MT_HIF0_MIN_QUOTA);
+ txdwcnt = mt76_get_field(dev, MT_PP_TXDWCNT,
+ MT_PP_TXDWCNT_TX1_ADD_DW_CNT);
+
+ mutex_lock(&sdio->sched.lock);
+
+ sdio->sched.pse_data_quota = pse0;
+ sdio->sched.ple_data_quota = ple;
+ sdio->sched.pse_mcu_quota = pse1;
+ sdio->sched.deficit = txdwcnt << 2;
+
+ mutex_unlock(&sdio->sched.lock);
+
+ return 0;
+}
+
+static int
+mt7663s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
+ int cmd, bool wait_resp)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ int ret, seq;
+
+ mutex_lock(&mdev->mcu.mutex);
+
+ mt7615_mcu_fill_msg(dev, skb, cmd, &seq);
+ ret = mt76_tx_queue_skb_raw(dev, MT_TXQ_MCU, skb, 0);
+ if (ret)
+ goto out;
+
+ mt76_queue_kick(dev, mdev->q_tx[MT_TXQ_MCU].q);
+ if (wait_resp)
+ ret = mt7615_mcu_wait_response(dev, cmd, seq);
+
+out:
+ mutex_unlock(&mdev->mcu.mutex);
+
+ return ret;
+}
+
+int mt7663s_driver_own(struct mt7615_dev *dev)
+{
+ struct sdio_func *func = dev->mt76.sdio.func;
+ struct mt76_phy *mphy = &dev->mt76.phy;
+ u32 status;
+ int ret;
+
+ if (!test_and_clear_bit(MT76_STATE_PM, &mphy->state))
+ goto out;
+
+ sdio_claim_host(func);
+
+ sdio_writel(func, WHLPCR_FW_OWN_REQ_CLR, MCR_WHLPCR, 0);
+
+ ret = readx_poll_timeout(mt7663s_read_pcr, dev, status,
+ status & WHLPCR_IS_DRIVER_OWN, 2000, 1000000);
+ if (ret < 0) {
+ dev_err(dev->mt76.dev, "Cannot get ownership from device");
+ set_bit(MT76_STATE_PM, &mphy->state);
+ sdio_release_host(func);
+
+ return ret;
+ }
+
+ sdio_release_host(func);
+
+out:
+ dev->pm.last_activity = jiffies;
+
+ return 0;
+}
+
+int mt7663s_firmware_own(struct mt7615_dev *dev)
+{
+ struct sdio_func *func = dev->mt76.sdio.func;
+ struct mt76_phy *mphy = &dev->mt76.phy;
+ u32 status;
+ int ret;
+
+ if (test_and_set_bit(MT76_STATE_PM, &mphy->state))
+ return 0;
+
+ sdio_claim_host(func);
+
+ sdio_writel(func, WHLPCR_FW_OWN_REQ_SET, MCR_WHLPCR, 0);
+
+ ret = readx_poll_timeout(mt7663s_read_pcr, dev, status,
+ !(status & WHLPCR_IS_DRIVER_OWN), 2000, 1000000);
+ if (ret < 0) {
+ dev_err(dev->mt76.dev, "Cannot set ownership to device");
+ clear_bit(MT76_STATE_PM, &mphy->state);
+ }
+
+ sdio_release_host(func);
+
+ return ret;
+}
+
+int mt7663s_mcu_init(struct mt7615_dev *dev)
+{
+ static const struct mt76_mcu_ops mt7663s_mcu_ops = {
+ .headroom = sizeof(struct mt7615_mcu_txd),
+ .tailroom = MT_USB_TAIL_SIZE,
+ .mcu_skb_send_msg = mt7663s_mcu_send_message,
+ .mcu_send_msg = mt7615_mcu_msg_send,
+ .mcu_restart = mt7615_mcu_restart,
+ .mcu_rr = mt7615_mcu_reg_rr,
+ .mcu_wr = mt7615_mcu_reg_wr,
+ };
+ int ret;
+
+ ret = mt7663s_driver_own(dev);
+ if (ret)
+ return ret;
+
+ dev->mt76.mcu_ops = &mt7663s_mcu_ops,
+
+ ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
+ if (ret) {
+ mt7615_mcu_restart(&dev->mt76);
+ if (!mt76_poll_msec(dev, MT_CONN_ON_MISC,
+ MT_TOP_MISC2_FW_N9_RDY, 0, 500))
+ return -EIO;
+ }
+
+ ret = __mt7663_load_firmware(dev);
+ if (ret)
+ return ret;
+
+ ret = mt7663s_mcu_init_sched(dev);
+ if (ret)
+ return ret;
+
+ set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
+
+ return 0;
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
new file mode 100644
index 000000000000..443a4ecdad3a
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: ISC
+/* Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Felix Fietkau <nbd@nbd.name>
+ * Lorenzo Bianconi <lorenzo@kernel.org>
+ * Sean Wang <sean.wang@mediatek.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "../trace.h"
+#include "mt7615.h"
+#include "sdio.h"
+#include "mac.h"
+
+static void mt7663s_refill_sched_quota(struct mt7615_dev *dev, u32 *data)
+{
+ struct mt76_sdio *sdio = &dev->mt76.sdio;
+
+ mutex_lock(&sdio->sched.lock);
+ sdio->sched.pse_data_quota += FIELD_GET(TXQ_CNT_L, data[0]) + /* BK */
+ FIELD_GET(TXQ_CNT_H, data[0]) + /* BE */
+ FIELD_GET(TXQ_CNT_L, data[1]) + /* VI */
+ FIELD_GET(TXQ_CNT_H, data[1]); /* VO */
+ sdio->sched.ple_data_quota += FIELD_GET(TXQ_CNT_H, data[2]) + /* BK */
+ FIELD_GET(TXQ_CNT_L, data[3]) + /* BE */
+ FIELD_GET(TXQ_CNT_H, data[3]) + /* VI */
+ FIELD_GET(TXQ_CNT_L, data[4]); /* VO */
+ sdio->sched.pse_mcu_quota += FIELD_GET(TXQ_CNT_L, data[2]);
+ mutex_unlock(&sdio->sched.lock);
+}
+
+static struct sk_buff *mt7663s_build_rx_skb(void *data, int data_len,
+ int buf_len)
+{
+ int len = min_t(int, data_len, MT_SKB_HEAD_LEN);
+ struct sk_buff *skb;
+
+ skb = alloc_skb(len, GFP_KERNEL);
+ if (!skb)
+ return NULL;
+
+ skb_put_data(skb, data, len);
+ if (data_len > len) {
+ struct page *page;
+
+ data += len;
+ page = virt_to_head_page(data);
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+ page, data - page_address(page),
+ data_len - len, buf_len);
+ get_page(page);
+ }
+
+ return skb;
+}
+
+static int mt7663s_rx_run_queue(struct mt7615_dev *dev, enum mt76_rxq_id qid,
+ struct mt76s_intr *intr)
+{
+ struct mt76_queue *q = &dev->mt76.q_rx[qid];
+ struct mt76_sdio *sdio = &dev->mt76.sdio;
+ int len = 0, err, i, order;
+ struct page *page;
+ u8 *buf;
+
+ for (i = 0; i < intr->rx.num[qid]; i++)
+ len += round_up(intr->rx.len[qid][i] + 4, 4);
+
+ if (!len)
+ return 0;
+
+ if (len > sdio->func->cur_blksize)
+ len = roundup(len, sdio->func->cur_blksize);
+
+ order = get_order(len);
+ page = __dev_alloc_pages(GFP_KERNEL, order);
+ if (!page)
+ return -ENOMEM;
+
+ buf = page_address(page);
+
+ err = sdio_readsb(sdio->func, buf, MCR_WRDR(qid), len);
+ if (err < 0) {
+ dev_err(dev->mt76.dev, "sdio read data failed:%d\n", err);
+ __free_pages(page, order);
+ return err;
+ }
+
+ for (i = 0; i < intr->rx.num[qid]; i++) {
+ int index = (q->tail + i) % q->ndesc;
+ struct mt76_queue_entry *e = &q->entry[index];
+
+ len = intr->rx.len[qid][i];
+ e->skb = mt7663s_build_rx_skb(buf, len, round_up(len + 4, 4));
+ if (!e->skb)
+ break;
+
+ buf += round_up(len + 4, 4);
+ if (q->queued + i + 1 == q->ndesc)
+ break;
+ }
+ __free_pages(page, order);
+
+ spin_lock_bh(&q->lock);
+ q->tail = (q->tail + i) % q->ndesc;
+ q->queued += i;
+ spin_unlock_bh(&q->lock);
+
+ return err;
+}
+
+static int mt7663s_tx_update_sched(struct mt7615_dev *dev,
+ struct mt76_queue_entry *e,
+ bool mcu)
+{
+ struct mt76_sdio *sdio = &dev->mt76.sdio;
+ struct mt76_phy *mphy = &dev->mt76.phy;
+ struct ieee80211_hdr *hdr;
+ int size, ret = -EBUSY;
+
+ size = DIV_ROUND_UP(e->buf_sz + sdio->sched.deficit, MT_PSE_PAGE_SZ);
+
+ if (mcu) {
+ if (!test_bit(MT76_STATE_MCU_RUNNING, &mphy->state))
+ return 0;
+
+ mutex_lock(&sdio->sched.lock);
+ if (sdio->sched.pse_mcu_quota > size) {
+ sdio->sched.pse_mcu_quota -= size;
+ ret = 0;
+ }
+ mutex_unlock(&sdio->sched.lock);
+
+ return ret;
+ }
+
+ hdr = (struct ieee80211_hdr *)(e->skb->data + MT_USB_TXD_SIZE);
+ if (ieee80211_is_ctl(hdr->frame_control))
+ return 0;
+
+ mutex_lock(&sdio->sched.lock);
+ if (sdio->sched.pse_data_quota > size &&
+ sdio->sched.ple_data_quota > 0) {
+ sdio->sched.pse_data_quota -= size;
+ sdio->sched.ple_data_quota--;
+ ret = 0;
+ }
+ mutex_unlock(&sdio->sched.lock);
+
+ return ret;
+}
+
+static int mt7663s_tx_run_queue(struct mt7615_dev *dev, struct mt76_queue *q)
+{
+ bool mcu = q == dev->mt76.q_tx[MT_TXQ_MCU].q;
+ struct mt76_sdio *sdio = &dev->mt76.sdio;
+ int nframes = 0;
+
+ while (q->first != q->tail) {
+ struct mt76_queue_entry *e = &q->entry[q->first];
+ int err, len = e->skb->len;
+
+ if (mt7663s_tx_update_sched(dev, e, mcu))
+ break;
+
+ if (len > sdio->func->cur_blksize)
+ len = roundup(len, sdio->func->cur_blksize);
+
+ /* TODO: skb_walk_frags and then write to SDIO port */
+ err = sdio_writesb(sdio->func, MCR_WTDR1, e->skb->data, len);
+ if (err) {
+ dev_err(dev->mt76.dev, "sdio write failed: %d\n", err);
+ return -EIO;
+ }
+
+ e->done = true;
+ q->first = (q->first + 1) % q->ndesc;
+ nframes++;
+ }
+
+ return nframes;
+}
+
+static int mt7663s_tx_run_queues(struct mt7615_dev *dev)
+{
+ int i, nframes = 0;
+
+ for (i = 0; i < MT_TXQ_MCU_WA; i++) {
+ int ret;
+
+ ret = mt7663s_tx_run_queue(dev, dev->mt76.q_tx[i].q);
+ if (ret < 0)
+ return ret;
+
+ nframes += ret;
+ }
+
+ return nframes;
+}
+
+int mt7663s_kthread_run(void *data)
+{
+ struct mt7615_dev *dev = data;
+ struct mt76_phy *mphy = &dev->mt76.phy;
+
+ while (!kthread_should_stop()) {
+ int ret;
+
+ cond_resched();
+
+ sdio_claim_host(dev->mt76.sdio.func);
+ ret = mt7663s_tx_run_queues(dev);
+ sdio_release_host(dev->mt76.sdio.func);
+
+ if (ret <= 0 || !test_bit(MT76_STATE_RUNNING, &mphy->state)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ } else {
+ wake_up_process(dev->mt76.sdio.kthread);
+ }
+ }
+
+ return 0;
+}
+
+void mt7663s_sdio_irq(struct sdio_func *func)
+{
+ struct mt7615_dev *dev = sdio_get_drvdata(func);
+ struct mt76_sdio *sdio = &dev->mt76.sdio;
+ struct mt76s_intr intr;
+
+ /* disable interrupt */
+ sdio_writel(func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, 0);
+
+ do {
+ sdio_readsb(func, &intr, MCR_WHISR, sizeof(struct mt76s_intr));
+ trace_dev_irq(&dev->mt76, intr.isr, 0);
+
+ if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.phy.state))
+ goto out;
+
+ if (intr.isr & WHIER_RX0_DONE_INT_EN) {
+ mt7663s_rx_run_queue(dev, 0, &intr);
+ wake_up_process(sdio->kthread);
+ }
+
+ if (intr.isr & WHIER_RX1_DONE_INT_EN) {
+ mt7663s_rx_run_queue(dev, 1, &intr);
+ wake_up_process(sdio->kthread);
+ }
+
+ if (intr.isr & WHIER_TX_DONE_INT_EN) {
+ mt7663s_refill_sched_quota(dev, intr.tx.wtqcr);
+ mt7663s_tx_run_queues(dev);
+ wake_up_process(sdio->kthread);
+ }
+ } while (intr.isr);
+out:
+ /* enable interrupt */
+ sdio_writel(func, WHLPCR_INT_EN_SET, MCR_WHLPCR, 0);
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7615/testmode.c
new file mode 100644
index 000000000000..1730751133aa
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/testmode.c
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: ISC
+/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
+
+#include "mt7615.h"
+#include "eeprom.h"
+#include "mcu.h"
+
+enum {
+ TM_CHANGED_TXPOWER_CTRL,
+ TM_CHANGED_TXPOWER,
+ TM_CHANGED_FREQ_OFFSET,
+
+ /* must be last */
+ NUM_TM_CHANGED
+};
+
+
+static const u8 tm_change_map[] = {
+ [TM_CHANGED_TXPOWER_CTRL] = MT76_TM_ATTR_TX_POWER_CONTROL,
+ [TM_CHANGED_TXPOWER] = MT76_TM_ATTR_TX_POWER,
+ [TM_CHANGED_FREQ_OFFSET] = MT76_TM_ATTR_FREQ_OFFSET,
+};
+
+static const u32 reg_backup_list[] = {
+ MT_WF_PHY_RFINTF3_0(0),
+ MT_WF_PHY_RFINTF3_0(1),
+ MT_WF_PHY_RFINTF3_0(2),
+ MT_WF_PHY_RFINTF3_0(3),
+ MT_ANT_SWITCH_CON(2),
+ MT_ANT_SWITCH_CON(3),
+ MT_ANT_SWITCH_CON(4),
+ MT_ANT_SWITCH_CON(6),
+ MT_ANT_SWITCH_CON(7),
+ MT_ANT_SWITCH_CON(8),
+};
+
+static const struct {
+ u16 wf;
+ u16 reg;
+} rf_backup_list[] = {
+ { 0, 0x48 },
+ { 1, 0x48 },
+ { 2, 0x48 },
+ { 3, 0x48 },
+};
+
+static int
+mt7615_tm_set_tx_power(struct mt7615_phy *phy)
+{
+ struct mt7615_dev *dev = phy->dev;
+ struct mt76_phy *mphy = phy->mt76;
+ int i, ret, n_chains = hweight8(mphy->antenna_mask);
+ struct cfg80211_chan_def *chandef = &mphy->chandef;
+ int freq = chandef->center_freq1, len, target_chains;
+ u8 *data, *eep = (u8 *)dev->mt76.eeprom.data;
+ enum nl80211_band band = chandef->chan->band;
+ struct sk_buff *skb;
+ struct {
+ u8 center_chan;
+ u8 dbdc_idx;
+ u8 band;
+ u8 rsv;
+ } __packed req_hdr = {
+ .center_chan = ieee80211_frequency_to_channel(freq),
+ .band = band,
+ .dbdc_idx = phy != &dev->phy,
+ };
+ u8 *tx_power = NULL;
+
+ if (dev->mt76.test.state != MT76_TM_STATE_OFF)
+ tx_power = dev->mt76.test.tx_power;
+
+ len = sizeof(req_hdr) + MT7615_EE_MAX - MT_EE_NIC_CONF_0;
+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(req_hdr) + len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put_data(skb, &req_hdr, sizeof(req_hdr));
+ data = skb_put_data(skb, eep + MT_EE_NIC_CONF_0, len);
+
+ target_chains = mt7615_ext_pa_enabled(dev, band) ? 1 : n_chains;
+ for (i = 0; i < target_chains; i++) {
+ int index;
+
+ ret = mt7615_eeprom_get_target_power_index(dev, chandef->chan, i);
+ if (ret < 0)
+ return -EINVAL;
+
+ index = ret - MT_EE_NIC_CONF_0;
+ if (tx_power && tx_power[i])
+ data[ret - MT_EE_NIC_CONF_0] = tx_power[i];
+ }
+
+ return __mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_EXT_CMD_SET_TX_POWER_CTRL, false);
+}
+
+static void
+mt7615_tm_reg_backup_restore(struct mt7615_dev *dev)
+{
+ u32 *b = dev->test.reg_backup;
+ int n_regs = ARRAY_SIZE(reg_backup_list);
+ int n_rf_regs = ARRAY_SIZE(rf_backup_list);
+ int i;
+
+ if (dev->mt76.test.state == MT76_TM_STATE_OFF) {
+ for (i = 0; i < n_regs; i++)
+ mt76_wr(dev, reg_backup_list[i], b[i]);
+
+ for (i = 0; i < n_rf_regs; i++)
+ mt7615_rf_wr(dev, rf_backup_list[i].wf,
+ rf_backup_list[i].reg, b[n_regs + i]);
+ return;
+ }
+
+ if (b)
+ return;
+
+ b = devm_kzalloc(dev->mt76.dev, 4 * (n_regs + n_rf_regs),
+ GFP_KERNEL);
+ if (!b)
+ return;
+
+ dev->test.reg_backup = b;
+ for (i = 0; i < n_regs; i++)
+ b[i] = mt76_rr(dev, reg_backup_list[i]);
+ for (i = 0; i < n_rf_regs; i++)
+ b[n_regs + i] = mt7615_rf_rr(dev, rf_backup_list[i].wf,
+ rf_backup_list[i].reg);
+}
+
+
+static void
+mt7615_tm_init_phy(struct mt7615_dev *dev, struct mt7615_phy *phy)
+{
+ unsigned int total_flags = ~0;
+
+ if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
+ return;
+
+ mutex_unlock(&dev->mt76.mutex);
+ mt7615_set_channel(phy);
+ mt7615_ops.configure_filter(phy->mt76->hw, 0, &total_flags, 0);
+ mutex_lock(&dev->mt76.mutex);
+
+ mt7615_tm_reg_backup_restore(dev);
+}
+
+static void
+mt7615_tm_init(struct mt7615_dev *dev)
+{
+ mt7615_tm_init_phy(dev, &dev->phy);
+
+ if (dev->mt76.phy2)
+ mt7615_tm_init_phy(dev, dev->mt76.phy2->priv);
+}
+
+static void
+mt7615_tm_set_rx_enable(struct mt7615_dev *dev, bool en)
+{
+ u32 rqcr_mask = (MT_ARB_RQCR_RX_START |
+ MT_ARB_RQCR_RXV_START |
+ MT_ARB_RQCR_RXV_R_EN |
+ MT_ARB_RQCR_RXV_T_EN) *
+ (BIT(0) | BIT(MT_ARB_RQCR_BAND_SHIFT));
+
+ if (en) {
+ mt76_clear(dev, MT_ARB_SCR,
+ MT_ARB_SCR_RX0_DISABLE | MT_ARB_SCR_RX1_DISABLE);
+ mt76_set(dev, MT_ARB_RQCR, rqcr_mask);
+ } else {
+ mt76_set(dev, MT_ARB_SCR,
+ MT_ARB_SCR_RX0_DISABLE | MT_ARB_SCR_RX1_DISABLE);
+ mt76_clear(dev, MT_ARB_RQCR, rqcr_mask);
+ }
+}
+
+static void
+mt7615_tm_set_tx_antenna(struct mt7615_dev *dev, bool en)
+{
+ struct mt76_testmode_data *td = &dev->mt76.test;
+ u8 mask = td->tx_antenna_mask;
+ int i;
+
+ if (!mask)
+ return;
+
+ if (!en)
+ mask = dev->phy.chainmask;
+
+ for (i = 0; i < 4; i++) {
+ mt76_rmw_field(dev, MT_WF_PHY_RFINTF3_0(i),
+ MT_WF_PHY_RFINTF3_0_ANT,
+ td->tx_antenna_mask & BIT(i) ? 0 : 0xa);
+
+ }
+
+ /* 2.4 GHz band */
+ mt76_rmw_field(dev, MT_ANT_SWITCH_CON(3), MT_ANT_SWITCH_CON_MODE(0),
+ (td->tx_antenna_mask & BIT(0)) ? 0x8 : 0x1b);
+ mt76_rmw_field(dev, MT_ANT_SWITCH_CON(4), MT_ANT_SWITCH_CON_MODE(2),
+ (td->tx_antenna_mask & BIT(1)) ? 0xe : 0x1b);
+ mt76_rmw_field(dev, MT_ANT_SWITCH_CON(6), MT_ANT_SWITCH_CON_MODE1(0),
+ (td->tx_antenna_mask & BIT(2)) ? 0x0 : 0xf);
+ mt76_rmw_field(dev, MT_ANT_SWITCH_CON(7), MT_ANT_SWITCH_CON_MODE1(2),
+ (td->tx_antenna_mask & BIT(3)) ? 0x6 : 0xf);
+
+ /* 5 GHz band */
+ mt76_rmw_field(dev, MT_ANT_SWITCH_CON(4), MT_ANT_SWITCH_CON_MODE(1),
+ (td->tx_antenna_mask & BIT(0)) ? 0xd : 0x1b);
+ mt76_rmw_field(dev, MT_ANT_SWITCH_CON(2), MT_ANT_SWITCH_CON_MODE(3),
+ (td->tx_antenna_mask & BIT(1)) ? 0x13 : 0x1b);
+ mt76_rmw_field(dev, MT_ANT_SWITCH_CON(7), MT_ANT_SWITCH_CON_MODE1(1),
+ (td->tx_antenna_mask & BIT(2)) ? 0x5 : 0xf);
+ mt76_rmw_field(dev, MT_ANT_SWITCH_CON(8), MT_ANT_SWITCH_CON_MODE1(3),
+ (td->tx_antenna_mask & BIT(3)) ? 0xb : 0xf);
+
+ for (i = 0; i < 4; i++) {
+ u32 val;
+
+ val = mt7615_rf_rr(dev, i, 0x48);
+ val &= ~(0x3ff << 20);
+ if (td->tx_antenna_mask & BIT(i))
+ val |= 3 << 20;
+ else
+ val |= (2 << 28) | (2 << 26) | (8 << 20);
+ mt7615_rf_wr(dev, i, 0x48, val);
+ }
+}
+
+static void
+mt7615_tm_set_tx_frames(struct mt7615_dev *dev, bool en)
+{
+ struct ieee80211_tx_info *info;
+ struct sk_buff *skb = dev->mt76.test.tx_skb;
+
+ mt7615_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH);
+ mt7615_tm_set_tx_antenna(dev, en);
+ mt7615_tm_set_rx_enable(dev, !en);
+ if (!en || !skb)
+ return;
+
+ info = IEEE80211_SKB_CB(skb);
+ info->control.vif = dev->phy.monitor_vif;
+}
+
+static void
+mt7615_tm_update_params(struct mt7615_dev *dev, u32 changed)
+{
+ struct mt76_testmode_data *td = &dev->mt76.test;
+ bool en = dev->mt76.test.state != MT76_TM_STATE_OFF;
+
+ if (changed & BIT(TM_CHANGED_TXPOWER_CTRL))
+ mt7615_mcu_set_test_param(dev, MCU_ATE_SET_TX_POWER_CONTROL,
+ en, en && td->tx_power_control);
+ if (changed & BIT(TM_CHANGED_FREQ_OFFSET))
+ mt7615_mcu_set_test_param(dev, MCU_ATE_SET_FREQ_OFFSET,
+ en, en ? td->freq_offset : 0);
+ if (changed & BIT(TM_CHANGED_TXPOWER))
+ mt7615_tm_set_tx_power(&dev->phy);
+}
+
+static int
+mt7615_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ struct mt76_testmode_data *td = &mdev->test;
+ enum mt76_testmode_state prev_state = td->state;
+
+ mdev->test.state = state;
+
+ if (prev_state == MT76_TM_STATE_TX_FRAMES)
+ mt7615_tm_set_tx_frames(dev, false);
+ else if (state == MT76_TM_STATE_TX_FRAMES)
+ mt7615_tm_set_tx_frames(dev, true);
+
+ if (state <= MT76_TM_STATE_IDLE)
+ mt7615_tm_init(dev);
+
+ if ((state == MT76_TM_STATE_IDLE &&
+ prev_state == MT76_TM_STATE_OFF) ||
+ (state == MT76_TM_STATE_OFF &&
+ prev_state == MT76_TM_STATE_IDLE)) {
+ u32 changed = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
+ u16 cur = tm_change_map[i];
+
+ if (td->param_set[cur / 32] & BIT(cur % 32))
+ changed |= BIT(i);
+ }
+
+ mt7615_tm_update_params(dev, changed);
+ }
+
+ return 0;
+}
+
+static int
+mt7615_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
+ enum mt76_testmode_state new_state)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ struct mt76_testmode_data *td = &dev->mt76.test;
+ u32 changed = 0;
+ int i;
+
+ BUILD_BUG_ON(NUM_TM_CHANGED >= 32);
+
+ if (new_state == MT76_TM_STATE_OFF ||
+ td->state == MT76_TM_STATE_OFF)
+ return 0;
+
+ if (td->tx_antenna_mask & ~dev->phy.chainmask)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
+ if (tb[tm_change_map[i]])
+ changed |= BIT(i);
+ }
+
+ mt7615_tm_update_params(dev, changed);
+
+ return 0;
+}
+
+static int
+mt7615_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ void *rx, *rssi;
+ int i;
+
+ rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX);
+ if (!rx)
+ return -ENOMEM;
+
+ if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, dev->test.last_freq_offset) ||
+ nla_put_s32(msg, MT76_TM_RX_ATTR_IB_RSSI, dev->test.last_ib_rssi) ||
+ nla_put_s32(msg, MT76_TM_RX_ATTR_WB_RSSI, dev->test.last_wb_rssi))
+ return -ENOMEM;
+
+ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RCPI);
+ if (!rssi)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(dev->test.last_rcpi); i++)
+ if (nla_put_u8(msg, i, dev->test.last_rcpi[i]))
+ return -ENOMEM;
+
+ nla_nest_end(msg, rssi);
+
+ nla_nest_end(msg, rx);
+
+ return 0;
+}
+
+const struct mt76_testmode_ops mt7615_testmode_ops = {
+ .set_state = mt7615_tm_set_state,
+ .set_params = mt7615_tm_set_params,
+ .dump_stats = mt7615_tm_dump_stats,
+};
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c
index 5be6704770ad..23a21338c46e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c
@@ -15,31 +15,6 @@
#include "mcu.h"
#include "regs.h"
-static const u32 mt7663u_reg_map[] = {
- [MT_TOP_CFG_BASE] = 0x80020000,
- [MT_HW_BASE] = 0x80000000,
- [MT_DMA_SHDL_BASE] = 0x5000a000,
- [MT_HIF_BASE] = 0x50000000,
- [MT_CSR_BASE] = 0x40000000,
- [MT_EFUSE_ADDR_BASE] = 0x78011000,
- [MT_TOP_MISC_BASE] = 0x81020000,
- [MT_PLE_BASE] = 0x82060000,
- [MT_PSE_BASE] = 0x82068000,
- [MT_PHY_BASE] = 0x82070000,
- [MT_WTBL_BASE_ADDR] = 0x820e0000,
- [MT_CFG_BASE] = 0x820f0000,
- [MT_AGG_BASE] = 0x820f2000,
- [MT_ARB_BASE] = 0x820f3000,
- [MT_TMAC_BASE] = 0x820f4000,
- [MT_RMAC_BASE] = 0x820f5000,
- [MT_DMA_BASE] = 0x820f7000,
- [MT_PF_BASE] = 0x820f8000,
- [MT_WTBL_BASE_ON] = 0x820f9000,
- [MT_WTBL_BASE_OFF] = 0x820f9800,
- [MT_LPON_BASE] = 0x820fb000,
- [MT_MIB_BASE] = 0x820fd000,
-};
-
static const struct usb_device_id mt7615_device_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7663, 0xff, 0xff, 0xff) },
{ },
@@ -64,205 +39,19 @@ static void mt7663u_cleanup(struct mt7615_dev *dev)
mt76u_queues_deinit(&dev->mt76);
}
-static void
-mt7663u_mac_write_txwi(struct mt7615_dev *dev, struct mt76_wcid *wcid,
- enum mt76_txq_id qid, struct ieee80211_sta *sta,
- struct sk_buff *skb)
-{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_key_conf *key = info->control.hw_key;
- __le32 *txwi;
- int pid;
-
- if (!wcid)
- wcid = &dev->mt76.global_wcid;
-
- pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
-
- txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE);
- memset(txwi, 0, MT_USB_TXD_SIZE);
- mt7615_mac_write_txwi(dev, txwi, skb, wcid, sta, pid, key, false);
- skb_push(skb, MT_USB_TXD_SIZE);
-}
-
-static int
-__mt7663u_mac_set_rates(struct mt7615_dev *dev,
- struct mt7615_wtbl_desc *wd)
-{
- struct mt7615_rate_desc *rate = &wd->rate;
- struct mt7615_sta *sta = wd->sta;
- u32 w5, w27, addr, val;
-
- lockdep_assert_held(&dev->mt76.mutex);
-
- if (!sta)
- return -EINVAL;
-
- if (!mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000))
- return -ETIMEDOUT;
-
- addr = mt7615_mac_wtbl_addr(dev, sta->wcid.idx);
-
- w27 = mt76_rr(dev, addr + 27 * 4);
- w27 &= ~MT_WTBL_W27_CC_BW_SEL;
- w27 |= FIELD_PREP(MT_WTBL_W27_CC_BW_SEL, rate->bw);
-
- w5 = mt76_rr(dev, addr + 5 * 4);
- w5 &= ~(MT_WTBL_W5_BW_CAP | MT_WTBL_W5_CHANGE_BW_RATE |
- MT_WTBL_W5_MPDU_OK_COUNT |
- MT_WTBL_W5_MPDU_FAIL_COUNT |
- MT_WTBL_W5_RATE_IDX);
- w5 |= FIELD_PREP(MT_WTBL_W5_BW_CAP, rate->bw) |
- FIELD_PREP(MT_WTBL_W5_CHANGE_BW_RATE,
- rate->bw_idx ? rate->bw_idx - 1 : 7);
-
- mt76_wr(dev, MT_WTBL_RIUCR0, w5);
-
- mt76_wr(dev, MT_WTBL_RIUCR1,
- FIELD_PREP(MT_WTBL_RIUCR1_RATE0, rate->probe_val) |
- FIELD_PREP(MT_WTBL_RIUCR1_RATE1, rate->val[0]) |
- FIELD_PREP(MT_WTBL_RIUCR1_RATE2_LO, rate->val[1]));
-
- mt76_wr(dev, MT_WTBL_RIUCR2,
- FIELD_PREP(MT_WTBL_RIUCR2_RATE2_HI, rate->val[1] >> 8) |
- FIELD_PREP(MT_WTBL_RIUCR2_RATE3, rate->val[1]) |
- FIELD_PREP(MT_WTBL_RIUCR2_RATE4, rate->val[2]) |
- FIELD_PREP(MT_WTBL_RIUCR2_RATE5_LO, rate->val[2]));
-
- mt76_wr(dev, MT_WTBL_RIUCR3,
- FIELD_PREP(MT_WTBL_RIUCR3_RATE5_HI, rate->val[2] >> 4) |
- FIELD_PREP(MT_WTBL_RIUCR3_RATE6, rate->val[3]) |
- FIELD_PREP(MT_WTBL_RIUCR3_RATE7, rate->val[3]));
-
- mt76_wr(dev, MT_WTBL_UPDATE,
- FIELD_PREP(MT_WTBL_UPDATE_WLAN_IDX, sta->wcid.idx) |
- MT_WTBL_UPDATE_RATE_UPDATE |
- MT_WTBL_UPDATE_TX_COUNT_CLEAR);
-
- mt76_wr(dev, addr + 27 * 4, w27);
-
- mt76_set(dev, MT_LPON_T0CR, MT_LPON_T0CR_MODE); /* TSF read */
- val = mt76_rr(dev, MT_LPON_UTTR0);
- sta->rate_set_tsf = (val & ~BIT(0)) | rate->rateset;
-
- if (!(sta->wcid.tx_info & MT_WCID_TX_INFO_SET))
- mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000);
-
- sta->rate_count = 2 * MT7615_RATE_RETRY * sta->n_rates;
- sta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
-
- return 0;
-}
-
-static int
-__mt7663u_mac_set_key(struct mt7615_dev *dev,
- struct mt7615_wtbl_desc *wd)
-{
- struct mt7615_key_desc *key = &wd->key;
- struct mt7615_sta *sta = wd->sta;
- enum mt7615_cipher_type cipher;
- struct mt76_wcid *wcid;
- int err;
-
- lockdep_assert_held(&dev->mt76.mutex);
-
- if (!sta)
- return -EINVAL;
-
- cipher = mt7615_mac_get_cipher(key->cipher);
- if (cipher == MT_CIPHER_NONE)
- return -EOPNOTSUPP;
-
- wcid = &wd->sta->wcid;
-
- mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, key->cmd);
- err = mt7615_mac_wtbl_update_key(dev, wcid, key->key, key->keylen,
- cipher, key->cmd);
- if (err < 0)
- return err;
-
- err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, key->keyidx,
- key->cmd);
- if (err < 0)
- return err;
-
- if (key->cmd == SET_KEY)
- wcid->cipher |= BIT(cipher);
- else
- wcid->cipher &= ~BIT(cipher);
-
- return 0;
-}
-
-void mt7663u_wtbl_work(struct work_struct *work)
+static void mt7663u_init_work(struct work_struct *work)
{
- struct mt7615_wtbl_desc *wd, *wd_next;
struct mt7615_dev *dev;
- dev = (struct mt7615_dev *)container_of(work, struct mt7615_dev,
- wtbl_work);
-
- list_for_each_entry_safe(wd, wd_next, &dev->wd_head, node) {
- spin_lock_bh(&dev->mt76.lock);
- list_del(&wd->node);
- spin_unlock_bh(&dev->mt76.lock);
-
- mutex_lock(&dev->mt76.mutex);
- switch (wd->type) {
- case MT7615_WTBL_RATE_DESC:
- __mt7663u_mac_set_rates(dev, wd);
- break;
- case MT7615_WTBL_KEY_DESC:
- __mt7663u_mac_set_key(dev, wd);
- break;
- }
- mutex_unlock(&dev->mt76.mutex);
-
- kfree(wd);
- }
-}
-
-static void
-mt7663u_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
- struct mt76_queue_entry *e)
-{
- skb_pull(e->skb, MT_USB_HDR_SIZE + MT_USB_TXD_SIZE);
- mt76_tx_complete_skb(mdev, e->skb);
-}
-
-static int
-mt7663u_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- enum mt76_txq_id qid, struct mt76_wcid *wcid,
- struct ieee80211_sta *sta,
- struct mt76_tx_info *tx_info)
-{
- struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
-
- if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
- struct mt7615_sta *msta;
-
- msta = container_of(wcid, struct mt7615_sta, wcid);
- spin_lock_bh(&dev->mt76.lock);
- mt7615_mac_set_rates(&dev->phy, msta, &info->control.rates[0],
- msta->rates);
- msta->rate_probe = true;
- spin_unlock_bh(&dev->mt76.lock);
- }
- mt7663u_mac_write_txwi(dev, wcid, qid, sta, tx_info->skb);
-
- return mt76u_skb_dma_info(tx_info->skb, tx_info->skb->len);
-}
-
-static bool mt7663u_tx_status_data(struct mt76_dev *mdev, u8 *update)
-{
- struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
-
- mutex_lock(&dev->mt76.mutex);
- mt7615_mac_sta_poll(dev);
- mutex_unlock(&dev->mt76.mutex);
+ dev = container_of(work, struct mt7615_dev, mcu_work);
+ if (mt7663u_mcu_init(dev))
+ return;
- return 0;
+ mt7615_mcu_set_eeprom(dev);
+ mt7615_mac_init(dev);
+ mt7615_phy_init(dev);
+ mt7615_mcu_del_wtbl_all(dev);
+ mt7615_check_offload_capability(dev);
}
static int mt7663u_probe(struct usb_interface *usb_intf,
@@ -271,9 +60,9 @@ static int mt7663u_probe(struct usb_interface *usb_intf,
static const struct mt76_driver_ops drv_ops = {
.txwi_size = MT_USB_TXD_SIZE,
.drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ,
- .tx_prepare_skb = mt7663u_tx_prepare_skb,
- .tx_complete_skb = mt7663u_tx_complete_skb,
- .tx_status_data = mt7663u_tx_status_data,
+ .tx_prepare_skb = mt7663_usb_sdio_tx_prepare_skb,
+ .tx_complete_skb = mt7663_usb_sdio_tx_complete_skb,
+ .tx_status_data = mt7663_usb_sdio_tx_status_data,
.rx_skb = mt7615_queue_rx_skb,
.sta_ps = mt7615_sta_ps,
.sta_add = mt7615_mac_sta_add,
@@ -303,7 +92,8 @@ static int mt7663u_probe(struct usb_interface *usb_intf,
usb_set_intfdata(usb_intf, dev);
- dev->reg_map = mt7663u_reg_map;
+ INIT_WORK(&dev->mcu_work, mt7663u_init_work);
+ dev->reg_map = mt7663_usb_sdio_reg_map;
dev->ops = ops;
ret = mt76u_init(mdev, usb_intf, true);
if (ret < 0)
@@ -342,7 +132,7 @@ alloc_queues:
if (ret)
goto error_free_q;
- ret = mt7663u_register_device(dev);
+ ret = mt7663_usb_sdio_register_device(dev);
if (ret)
goto error_free_q;
@@ -351,11 +141,10 @@ alloc_queues:
error_free_q:
mt76u_queues_deinit(&dev->mt76);
error:
- mt76u_deinit(&dev->mt76);
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
- ieee80211_free_hw(mdev->hw);
+ mt76_free_device(&dev->mt76);
return ret;
}
@@ -373,8 +162,7 @@ static void mt7663u_disconnect(struct usb_interface *usb_intf)
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
- mt76u_deinit(&dev->mt76);
- ieee80211_free_hw(dev->mt76.hw);
+ mt76_free_device(&dev->mt76);
}
#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_init.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_init.c
deleted file mode 100644
index 1fbc9601391d..000000000000
--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb_init.c
+++ /dev/null
@@ -1,145 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright (C) 2019 MediaTek Inc.
- *
- * Author: Felix Fietkau <nbd@nbd.name>
- * Lorenzo Bianconi <lorenzo@kernel.org>
- * Sean Wang <sean.wang@mediatek.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "mt7615.h"
-#include "mac.h"
-#include "regs.h"
-
-static int mt7663u_dma_sched_init(struct mt7615_dev *dev)
-{
- int i;
-
- mt76_rmw(dev, MT_DMA_SHDL(MT_DMASHDL_PKT_MAX_SIZE),
- MT_DMASHDL_PKT_MAX_SIZE_PLE | MT_DMASHDL_PKT_MAX_SIZE_PSE,
- FIELD_PREP(MT_DMASHDL_PKT_MAX_SIZE_PLE, 1) |
- FIELD_PREP(MT_DMASHDL_PKT_MAX_SIZE_PSE, 8));
-
- /* disable refill group 5 - group 15 and raise group 2
- * and 3 as high priority.
- */
- mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_REFILL), 0xffe00006);
- mt76_clear(dev, MT_DMA_SHDL(MT_DMASHDL_PAGE), BIT(16));
-
- for (i = 0; i < 5; i++)
- mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_GROUP_QUOTA(i)),
- FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MIN, 0x3) |
- FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MAX, 0x1ff));
-
- mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(0)), 0x42104210);
- mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(1)), 0x42104210);
-
- mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(2)), 0x4444);
-
- /* group pririority from high to low:
- * 15 (cmd groups) > 4 > 3 > 2 > 1 > 0.
- */
- mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_SCHED_SET0), 0x6501234f);
- mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_SCHED_SET1), 0xedcba987);
- mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_OPTIONAL), 0x7004801c);
-
- mt76_wr(dev, MT_UDMA_WLCFG_1,
- FIELD_PREP(MT_WL_TX_TMOUT_LMT, 80000) |
- FIELD_PREP(MT_WL_RX_AGG_PKT_LMT, 1));
-
- /* setup UDMA Rx Flush */
- mt76_clear(dev, MT_UDMA_WLCFG_0, MT_WL_RX_FLUSH);
- /* hif reset */
- mt76_set(dev, MT_HIF_RST, MT_HIF_LOGIC_RST_N);
-
- mt76_set(dev, MT_UDMA_WLCFG_0,
- MT_WL_RX_AGG_EN | MT_WL_RX_EN | MT_WL_TX_EN |
- MT_WL_RX_MPSZ_PAD0 | MT_TICK_1US_EN |
- MT_WL_TX_TMOUT_FUNC_EN);
- mt76_rmw(dev, MT_UDMA_WLCFG_0, MT_WL_RX_AGG_LMT | MT_WL_RX_AGG_TO,
- FIELD_PREP(MT_WL_RX_AGG_LMT, 32) |
- FIELD_PREP(MT_WL_RX_AGG_TO, 100));
-
- return 0;
-}
-
-static int mt7663u_init_hardware(struct mt7615_dev *dev)
-{
- int ret, idx;
-
- ret = mt7615_eeprom_init(dev, MT_EFUSE_BASE);
- if (ret < 0)
- return ret;
-
- ret = mt7663u_dma_sched_init(dev);
- if (ret)
- return ret;
-
- set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
-
- /* Beacon and mgmt frames should occupy wcid 0 */
- idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);
- if (idx)
- return -ENOSPC;
-
- dev->mt76.global_wcid.idx = idx;
- dev->mt76.global_wcid.hw_key_idx = -1;
- rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
-
- return 0;
-}
-
-static void mt7663u_init_work(struct work_struct *work)
-{
- struct mt7615_dev *dev;
-
- dev = container_of(work, struct mt7615_dev, mcu_work);
- if (mt7663u_mcu_init(dev))
- return;
-
- mt7615_mcu_set_eeprom(dev);
- mt7615_mac_init(dev);
- mt7615_phy_init(dev);
- mt7615_mcu_del_wtbl_all(dev);
- mt7615_check_offload_capability(dev);
-}
-
-int mt7663u_register_device(struct mt7615_dev *dev)
-{
- struct ieee80211_hw *hw = mt76_hw(dev);
- int err;
-
- INIT_WORK(&dev->wtbl_work, mt7663u_wtbl_work);
- INIT_WORK(&dev->mcu_work, mt7663u_init_work);
- INIT_LIST_HEAD(&dev->wd_head);
- mt7615_init_device(dev);
-
- err = mt7663u_init_hardware(dev);
- if (err)
- return err;
-
- hw->extra_tx_headroom += MT_USB_HDR_SIZE + MT_USB_TXD_SIZE;
- /* check hw sg support in order to enable AMSDU */
- hw->max_tx_fragments = dev->mt76.usb.sg_en ? MT_HW_TXP_MAX_BUF_NUM : 1;
-
- err = mt76_register_device(&dev->mt76, true, mt7615_rates,
- ARRAY_SIZE(mt7615_rates));
- if (err < 0)
- return err;
-
- if (!dev->mt76.usb.sg_en) {
- struct ieee80211_sta_vht_cap *vht_cap;
-
- /* decrease max A-MSDU size if SG is not supported */
- vht_cap = &dev->mphy.sband_5g.sband.vht_cap;
- vht_cap->cap &= ~IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
- }
-
- ieee80211_queue_work(hw, &dev->mcu_work);
- mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband);
- mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband);
-
- return mt7615_init_debugfs(dev);
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c
index cd709fd617db..0b33df3e3bfe 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c
@@ -28,13 +28,13 @@ mt7663u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
else
ep = MT_EP_OUT_AC_BE;
- ret = mt76u_skb_dma_info(skb, skb->len);
+ put_unaligned_le32(skb->len, skb_push(skb, sizeof(skb->len)));
+ ret = mt76_skb_adjust_pad(skb);
if (ret < 0)
goto out;
ret = mt76u_bulk_msg(&dev->mt76, skb->data, skb->len, NULL,
1000, ep);
- dev_kfree_skb(skb);
if (ret < 0)
goto out;
@@ -43,6 +43,7 @@ mt7663u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
out:
mutex_unlock(&mdev->mcu.mutex);
+ dev_kfree_skb(skb);
return ret;
}
@@ -60,6 +61,8 @@ int mt7663u_mcu_init(struct mt7615_dev *dev)
dev->mt76.mcu_ops = &mt7663u_mcu_ops,
+ /* usb does not support runtime-pm */
+ clear_bit(MT76_STATE_PM, &dev->mphy.state);
mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
if (test_and_clear_bit(MT76_STATE_POWER_OFF, &dev->mphy.state)) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
new file mode 100644
index 000000000000..6dffdaaa9ad5
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
@@ -0,0 +1,394 @@
+// SPDX-License-Identifier: ISC
+/* Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
+ * Sean Wang <sean.wang@mediatek.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "mt7615.h"
+#include "mac.h"
+#include "mcu.h"
+#include "regs.h"
+
+const u32 mt7663_usb_sdio_reg_map[] = {
+ [MT_TOP_CFG_BASE] = 0x80020000,
+ [MT_HW_BASE] = 0x80000000,
+ [MT_DMA_SHDL_BASE] = 0x5000a000,
+ [MT_HIF_BASE] = 0x50000000,
+ [MT_CSR_BASE] = 0x40000000,
+ [MT_EFUSE_ADDR_BASE] = 0x78011000,
+ [MT_TOP_MISC_BASE] = 0x81020000,
+ [MT_PLE_BASE] = 0x82060000,
+ [MT_PSE_BASE] = 0x82068000,
+ [MT_PP_BASE] = 0x8206c000,
+ [MT_WTBL_BASE_ADDR] = 0x820e0000,
+ [MT_CFG_BASE] = 0x820f0000,
+ [MT_AGG_BASE] = 0x820f2000,
+ [MT_ARB_BASE] = 0x820f3000,
+ [MT_TMAC_BASE] = 0x820f4000,
+ [MT_RMAC_BASE] = 0x820f5000,
+ [MT_DMA_BASE] = 0x820f7000,
+ [MT_PF_BASE] = 0x820f8000,
+ [MT_WTBL_BASE_ON] = 0x820f9000,
+ [MT_WTBL_BASE_OFF] = 0x820f9800,
+ [MT_LPON_BASE] = 0x820fb000,
+ [MT_MIB_BASE] = 0x820fd000,
+};
+EXPORT_SYMBOL_GPL(mt7663_usb_sdio_reg_map);
+
+static void
+mt7663_usb_sdio_write_txwi(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+ enum mt76_txq_id qid, struct ieee80211_sta *sta,
+ struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_key_conf *key = info->control.hw_key;
+ __le32 *txwi;
+ int pid;
+
+ if (!wcid)
+ wcid = &dev->mt76.global_wcid;
+
+ pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
+
+ txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE);
+ memset(txwi, 0, MT_USB_TXD_SIZE);
+ mt7615_mac_write_txwi(dev, txwi, skb, wcid, sta, pid, key, false);
+ skb_push(skb, MT_USB_TXD_SIZE);
+}
+
+static int
+mt7663_usb_sdio_set_rates(struct mt7615_dev *dev,
+ struct mt7615_wtbl_desc *wd)
+{
+ struct mt7615_rate_desc *rate = &wd->rate;
+ struct mt7615_sta *sta = wd->sta;
+ u32 w5, w27, addr, val;
+
+ lockdep_assert_held(&dev->mt76.mutex);
+
+ if (!sta)
+ return -EINVAL;
+
+ if (!mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000))
+ return -ETIMEDOUT;
+
+ addr = mt7615_mac_wtbl_addr(dev, sta->wcid.idx);
+
+ w27 = mt76_rr(dev, addr + 27 * 4);
+ w27 &= ~MT_WTBL_W27_CC_BW_SEL;
+ w27 |= FIELD_PREP(MT_WTBL_W27_CC_BW_SEL, rate->bw);
+
+ w5 = mt76_rr(dev, addr + 5 * 4);
+ w5 &= ~(MT_WTBL_W5_BW_CAP | MT_WTBL_W5_CHANGE_BW_RATE |
+ MT_WTBL_W5_MPDU_OK_COUNT |
+ MT_WTBL_W5_MPDU_FAIL_COUNT |
+ MT_WTBL_W5_RATE_IDX);
+ w5 |= FIELD_PREP(MT_WTBL_W5_BW_CAP, rate->bw) |
+ FIELD_PREP(MT_WTBL_W5_CHANGE_BW_RATE,
+ rate->bw_idx ? rate->bw_idx - 1 : 7);
+
+ mt76_wr(dev, MT_WTBL_RIUCR0, w5);
+
+ mt76_wr(dev, MT_WTBL_RIUCR1,
+ FIELD_PREP(MT_WTBL_RIUCR1_RATE0, rate->probe_val) |
+ FIELD_PREP(MT_WTBL_RIUCR1_RATE1, rate->val[0]) |
+ FIELD_PREP(MT_WTBL_RIUCR1_RATE2_LO, rate->val[1]));
+
+ mt76_wr(dev, MT_WTBL_RIUCR2,
+ FIELD_PREP(MT_WTBL_RIUCR2_RATE2_HI, rate->val[1] >> 8) |
+ FIELD_PREP(MT_WTBL_RIUCR2_RATE3, rate->val[1]) |
+ FIELD_PREP(MT_WTBL_RIUCR2_RATE4, rate->val[2]) |
+ FIELD_PREP(MT_WTBL_RIUCR2_RATE5_LO, rate->val[2]));
+
+ mt76_wr(dev, MT_WTBL_RIUCR3,
+ FIELD_PREP(MT_WTBL_RIUCR3_RATE5_HI, rate->val[2] >> 4) |
+ FIELD_PREP(MT_WTBL_RIUCR3_RATE6, rate->val[3]) |
+ FIELD_PREP(MT_WTBL_RIUCR3_RATE7, rate->val[3]));
+
+ mt76_wr(dev, MT_WTBL_UPDATE,
+ FIELD_PREP(MT_WTBL_UPDATE_WLAN_IDX, sta->wcid.idx) |
+ MT_WTBL_UPDATE_RATE_UPDATE |
+ MT_WTBL_UPDATE_TX_COUNT_CLEAR);
+
+ mt76_wr(dev, addr + 27 * 4, w27);
+
+ sta->rate_probe = sta->rateset[rate->rateset].probe_rate.idx != -1;
+
+ mt76_set(dev, MT_LPON_T0CR, MT_LPON_T0CR_MODE); /* TSF read */
+ val = mt76_rr(dev, MT_LPON_UTTR0);
+ sta->rate_set_tsf = (val & ~BIT(0)) | rate->rateset;
+
+ if (!(sta->wcid.tx_info & MT_WCID_TX_INFO_SET))
+ mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000);
+
+ sta->rate_count = 2 * MT7615_RATE_RETRY * sta->n_rates;
+ sta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
+
+ return 0;
+}
+
+static int
+mt7663_usb_sdio_set_key(struct mt7615_dev *dev,
+ struct mt7615_wtbl_desc *wd)
+{
+ struct mt7615_key_desc *key = &wd->key;
+ struct mt7615_sta *sta = wd->sta;
+ enum mt7615_cipher_type cipher;
+ struct mt76_wcid *wcid;
+ int err;
+
+ lockdep_assert_held(&dev->mt76.mutex);
+
+ if (!sta) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ cipher = mt7615_mac_get_cipher(key->cipher);
+ if (cipher == MT_CIPHER_NONE) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ wcid = &wd->sta->wcid;
+
+ mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, key->cmd);
+ err = mt7615_mac_wtbl_update_key(dev, wcid, key->key, key->keylen,
+ cipher, key->cmd);
+ if (err < 0)
+ goto out;
+
+ err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, key->keyidx,
+ key->cmd);
+ if (err < 0)
+ goto out;
+
+ if (key->cmd == SET_KEY)
+ wcid->cipher |= BIT(cipher);
+ else
+ wcid->cipher &= ~BIT(cipher);
+out:
+ kfree(key->key);
+
+ return err;
+}
+
+void mt7663_usb_sdio_wtbl_work(struct work_struct *work)
+{
+ struct mt7615_wtbl_desc *wd, *wd_next;
+ struct list_head wd_list;
+ struct mt7615_dev *dev;
+
+ dev = (struct mt7615_dev *)container_of(work, struct mt7615_dev,
+ wtbl_work);
+
+ INIT_LIST_HEAD(&wd_list);
+ spin_lock_bh(&dev->mt76.lock);
+ list_splice_init(&dev->wd_head, &wd_list);
+ spin_unlock_bh(&dev->mt76.lock);
+
+ list_for_each_entry_safe(wd, wd_next, &wd_list, node) {
+ list_del(&wd->node);
+
+ mt7615_mutex_acquire(dev);
+
+ switch (wd->type) {
+ case MT7615_WTBL_RATE_DESC:
+ mt7663_usb_sdio_set_rates(dev, wd);
+ break;
+ case MT7615_WTBL_KEY_DESC:
+ mt7663_usb_sdio_set_key(dev, wd);
+ break;
+ }
+
+ mt7615_mutex_release(dev);
+
+ kfree(wd);
+ }
+}
+EXPORT_SYMBOL_GPL(mt7663_usb_sdio_wtbl_work);
+
+bool mt7663_usb_sdio_tx_status_data(struct mt76_dev *mdev, u8 *update)
+{
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+
+ mt7615_mutex_acquire(dev);
+ mt7615_mac_sta_poll(dev);
+ mt7615_mutex_release(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_status_data);
+
+void mt7663_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,
+ enum mt76_txq_id qid,
+ struct mt76_queue_entry *e)
+{
+ unsigned int headroom = MT_USB_TXD_SIZE;
+
+ if (mt76_is_usb(mdev))
+ headroom += MT_USB_HDR_SIZE;
+ skb_pull(e->skb, headroom);
+
+ mt76_tx_complete_skb(mdev, e->skb);
+}
+EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_complete_skb);
+
+int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ enum mt76_txq_id qid, struct mt76_wcid *wcid,
+ struct ieee80211_sta *sta,
+ struct mt76_tx_info *tx_info)
+{
+ struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid);
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ struct sk_buff *skb = tx_info->skb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+ if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) &&
+ !msta->rate_probe) {
+ /* request to configure sampling rate */
+ spin_lock_bh(&dev->mt76.lock);
+ mt7615_mac_set_rates(&dev->phy, msta, &info->control.rates[0],
+ msta->rates);
+ spin_unlock_bh(&dev->mt76.lock);
+ }
+
+ mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, skb);
+ if (mt76_is_usb(mdev))
+ put_unaligned_le32(skb->len, skb_push(skb, sizeof(skb->len)));
+
+ return mt76_skb_adjust_pad(skb);
+}
+EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_prepare_skb);
+
+static int mt7663u_dma_sched_init(struct mt7615_dev *dev)
+{
+ int i;
+
+ mt76_rmw(dev, MT_DMA_SHDL(MT_DMASHDL_PKT_MAX_SIZE),
+ MT_DMASHDL_PKT_MAX_SIZE_PLE | MT_DMASHDL_PKT_MAX_SIZE_PSE,
+ FIELD_PREP(MT_DMASHDL_PKT_MAX_SIZE_PLE, 1) |
+ FIELD_PREP(MT_DMASHDL_PKT_MAX_SIZE_PSE, 8));
+
+ /* disable refill group 5 - group 15 and raise group 2
+ * and 3 as high priority.
+ */
+ mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_REFILL), 0xffe00006);
+ mt76_clear(dev, MT_DMA_SHDL(MT_DMASHDL_PAGE), BIT(16));
+
+ for (i = 0; i < 5; i++)
+ mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_GROUP_QUOTA(i)),
+ FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MIN, 0x3) |
+ FIELD_PREP(MT_DMASHDL_GROUP_QUOTA_MAX, 0x1ff));
+
+ mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(0)), 0x42104210);
+ mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(1)), 0x42104210);
+
+ mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_Q_MAP(2)), 0x4444);
+
+ /* group pririority from high to low:
+ * 15 (cmd groups) > 4 > 3 > 2 > 1 > 0.
+ */
+ mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_SCHED_SET0), 0x6501234f);
+ mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_SCHED_SET1), 0xedcba987);
+ mt76_wr(dev, MT_DMA_SHDL(MT_DMASHDL_OPTIONAL), 0x7004801c);
+
+ mt76_wr(dev, MT_UDMA_WLCFG_1,
+ FIELD_PREP(MT_WL_TX_TMOUT_LMT, 80000) |
+ FIELD_PREP(MT_WL_RX_AGG_PKT_LMT, 1));
+
+ /* setup UDMA Rx Flush */
+ mt76_clear(dev, MT_UDMA_WLCFG_0, MT_WL_RX_FLUSH);
+ /* hif reset */
+ mt76_set(dev, MT_HIF_RST, MT_HIF_LOGIC_RST_N);
+
+ mt76_set(dev, MT_UDMA_WLCFG_0,
+ MT_WL_RX_AGG_EN | MT_WL_RX_EN | MT_WL_TX_EN |
+ MT_WL_RX_MPSZ_PAD0 | MT_TICK_1US_EN |
+ MT_WL_TX_TMOUT_FUNC_EN);
+ mt76_rmw(dev, MT_UDMA_WLCFG_0, MT_WL_RX_AGG_LMT | MT_WL_RX_AGG_TO,
+ FIELD_PREP(MT_WL_RX_AGG_LMT, 32) |
+ FIELD_PREP(MT_WL_RX_AGG_TO, 100));
+
+ return 0;
+}
+
+static int mt7663_usb_sdio_init_hardware(struct mt7615_dev *dev)
+{
+ int ret, idx;
+
+ ret = mt7615_eeprom_init(dev, MT_EFUSE_BASE);
+ if (ret < 0)
+ return ret;
+
+ if (mt76_is_usb(&dev->mt76)) {
+ ret = mt7663u_dma_sched_init(dev);
+ if (ret)
+ return ret;
+ }
+
+ set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
+
+ /* Beacon and mgmt frames should occupy wcid 0 */
+ idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);
+ if (idx)
+ return -ENOSPC;
+
+ dev->mt76.global_wcid.idx = idx;
+ dev->mt76.global_wcid.hw_key_idx = -1;
+ rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
+
+ return 0;
+}
+
+int mt7663_usb_sdio_register_device(struct mt7615_dev *dev)
+{
+ struct ieee80211_hw *hw = mt76_hw(dev);
+ int err;
+
+ INIT_WORK(&dev->wtbl_work, mt7663_usb_sdio_wtbl_work);
+ INIT_LIST_HEAD(&dev->wd_head);
+ mt7615_init_device(dev);
+
+ err = mt7663_usb_sdio_init_hardware(dev);
+ if (err)
+ return err;
+
+ /* check hw sg support in order to enable AMSDU */
+ if (dev->mt76.usb.sg_en || mt76_is_sdio(&dev->mt76))
+ hw->max_tx_fragments = MT_HW_TXP_MAX_BUF_NUM;
+ else
+ hw->max_tx_fragments = 1;
+ hw->extra_tx_headroom += MT_USB_TXD_SIZE;
+ if (mt76_is_usb(&dev->mt76))
+ hw->extra_tx_headroom += MT_USB_HDR_SIZE;
+
+ err = mt76_register_device(&dev->mt76, true, mt7615_rates,
+ ARRAY_SIZE(mt7615_rates));
+ if (err < 0)
+ return err;
+
+ if (!dev->mt76.usb.sg_en) {
+ struct ieee80211_sta_vht_cap *vht_cap;
+
+ /* decrease max A-MSDU size if SG is not supported */
+ vht_cap = &dev->mphy.sband_5g.sband.vht_cap;
+ vht_cap->cap &= ~IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
+ }
+
+ ieee80211_queue_work(hw, &dev->mcu_work);
+ mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband);
+ mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband);
+
+ return mt7615_init_debugfs(dev);
+}
+EXPORT_SYMBOL_GPL(mt7663_usb_sdio_register_device);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 5535b9c0632f..ce6b286a8152 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -277,9 +277,8 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
err:
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
- mt76u_deinit(&dev->mt76);
+ mt76_free_device(&dev->mt76);
- ieee80211_free_hw(mdev->hw);
return ret;
}
@@ -297,8 +296,7 @@ static void mt76x0_disconnect(struct usb_interface *usb_intf)
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
- mt76u_deinit(&dev->mt76);
- ieee80211_free_hw(dev->mt76.hw);
+ mt76_free_device(&dev->mt76);
}
static int __maybe_unused mt76x0_suspend(struct usb_interface *usb_intf,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 4c9bbc7ce023..4660b9691ec3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -80,7 +80,6 @@ struct mt76x02_dev {
struct mutex phy_mutex;
- u16 vif_mask;
u16 chainmask;
u8 txdone_seq;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 5fda6e7b120c..bacb1f10a699 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -439,7 +439,7 @@ static void mt76x02_reset_state(struct mt76x02_dev *dev)
memset(msta, 0, sizeof(*msta));
}
- dev->vif_mask = 0;
+ dev->mphy.vif_mask = 0;
dev->mt76.beacon_mask = 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 0180b6200b17..37321e656776 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -56,8 +56,9 @@ int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags)
*/
info = FIELD_PREP(MT_TXD_INFO_LEN, round_up(skb->len, 4)) |
FIELD_PREP(MT_TXD_INFO_DPORT, port) | flags;
+ put_unaligned_le32(info, skb_push(skb, sizeof(info)));
- return mt76u_skb_dma_info(skb, info);
+ return mt76_skb_adjust_pad(skb);
}
int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
index a30bb536fc8a..e43d13d7c988 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
@@ -87,8 +87,10 @@ __mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb,
u32 info;
int ret;
- if (test_bit(MT76_REMOVED, &dev->phy.state))
- return 0;
+ if (test_bit(MT76_REMOVED, &dev->phy.state)) {
+ ret = 0;
+ goto out;
+ }
if (wait_resp) {
seq = ++dev->mcu.msg_seq & 0xf;
@@ -111,6 +113,7 @@ __mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb,
if (wait_resp)
ret = mt76x02u_mcu_wait_resp(dev, seq);
+out:
consume_skb(skb);
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 44822a849eb1..dbd4077ea283 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -305,7 +305,7 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
unsigned int idx = 0;
/* Allow to change address in HW if we create first interface. */
- if (!dev->vif_mask &&
+ if (!dev->mphy.vif_mask &&
(((vif->addr[0] ^ dev->mt76.macaddr[0]) & ~GENMASK(4, 1)) ||
memcmp(vif->addr + 1, dev->mt76.macaddr + 1, ETH_ALEN - 1)))
mt76x02_mac_setaddr(dev, vif->addr);
@@ -330,11 +330,11 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
idx += 8;
/* vif is already set or idx is 8 for AP/Mesh/... */
- if (dev->vif_mask & BIT(idx) ||
+ if (dev->mphy.vif_mask & BIT(idx) ||
(vif->type != NL80211_IFTYPE_STATION && idx > 7))
return -EBUSY;
- dev->vif_mask |= BIT(idx);
+ dev->mphy.vif_mask |= BIT(idx);
mt76x02_vif_init(dev, vif, idx);
return 0;
@@ -348,7 +348,7 @@ void mt76x02_remove_interface(struct ieee80211_hw *hw,
struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
mt76_txq_remove(&dev->mt76, vif->txq);
- dev->vif_mask &= ~BIT(mvif->idx);
+ dev->mphy.vif_mask &= ~BIT(mvif->idx);
}
EXPORT_SYMBOL_GPL(mt76x02_remove_interface);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
index eca95b7f64d2..d01f47c83eb1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
@@ -39,6 +39,7 @@ static inline bool mt76x2_channel_silent(struct mt76x02_dev *dev)
extern const struct ieee80211_ops mt76x2_ops;
int mt76x2_register_device(struct mt76x02_dev *dev);
+int mt76x2_resume_device(struct mt76x02_dev *dev);
void mt76x2_phy_power_on(struct mt76x02_dev *dev);
void mt76x2_stop_hardware(struct mt76x02_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
index 53ca0cedf026..6dfb0df8ec8a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
@@ -9,7 +9,7 @@
#include "mt76x2.h"
-static const struct pci_device_id mt76pci_device_table[] = {
+static const struct pci_device_id mt76x2e_device_table[] = {
{ PCI_DEVICE(0x14c3, 0x7662) },
{ PCI_DEVICE(0x14c3, 0x7612) },
{ PCI_DEVICE(0x14c3, 0x7602) },
@@ -17,7 +17,7 @@ static const struct pci_device_id mt76pci_device_table[] = {
};
static int
-mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+mt76x2e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct mt76_driver_ops drv_ops = {
.txwi_size = sizeof(struct mt76x02_txwi),
@@ -93,7 +93,7 @@ error:
}
static void
-mt76pci_remove(struct pci_dev *pdev)
+mt76x2e_remove(struct pci_dev *pdev)
{
struct mt76_dev *mdev = pci_get_drvdata(pdev);
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
@@ -103,16 +103,72 @@ mt76pci_remove(struct pci_dev *pdev)
mt76_free_device(mdev);
}
-MODULE_DEVICE_TABLE(pci, mt76pci_device_table);
+static int __maybe_unused
+mt76x2e_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct mt76_dev *mdev = pci_get_drvdata(pdev);
+ int i, err;
+
+ napi_disable(&mdev->tx_napi);
+ tasklet_kill(&mdev->pre_tbtt_tasklet);
+ tasklet_kill(&mdev->tx_tasklet);
+
+ mt76_for_each_q_rx(mdev, i)
+ napi_disable(&mdev->napi[i]);
+
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), true);
+ pci_save_state(pdev);
+ err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ if (err)
+ goto restore;
+
+ return 0;
+
+restore:
+ mt76_for_each_q_rx(mdev, i)
+ napi_enable(&mdev->napi[i]);
+ napi_enable(&mdev->tx_napi);
+
+ return err;
+}
+
+static int __maybe_unused
+mt76x2e_resume(struct pci_dev *pdev)
+{
+ struct mt76_dev *mdev = pci_get_drvdata(pdev);
+ struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
+ int i, err;
+
+ err = pci_set_power_state(pdev, PCI_D0);
+ if (err)
+ return err;
+
+ pci_restore_state(pdev);
+
+ mt76_for_each_q_rx(mdev, i) {
+ napi_enable(&mdev->napi[i]);
+ napi_schedule(&mdev->napi[i]);
+ }
+ napi_enable(&mdev->tx_napi);
+ napi_schedule(&mdev->tx_napi);
+
+ return mt76x2_resume_device(dev);
+}
+
+MODULE_DEVICE_TABLE(pci, mt76x2e_device_table);
MODULE_FIRMWARE(MT7662_FIRMWARE);
MODULE_FIRMWARE(MT7662_ROM_PATCH);
MODULE_LICENSE("Dual BSD/GPL");
static struct pci_driver mt76pci_driver = {
.name = KBUILD_MODNAME,
- .id_table = mt76pci_device_table,
- .probe = mt76pci_probe,
- .remove = mt76pci_remove,
+ .id_table = mt76x2e_device_table,
+ .probe = mt76x2e_probe,
+ .remove = mt76x2e_remove,
+#ifdef CONFIG_PM
+ .suspend = mt76x2e_suspend,
+ .resume = mt76x2e_resume,
+#endif /* CONFIG_PM */
};
module_pci_driver(mt76pci_driver);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index f27774f57438..101a0fe00ef3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -217,6 +217,23 @@ mt76x2_power_on(struct mt76x02_dev *dev)
mt76x2_power_on_rf(dev, 1);
}
+int mt76x2_resume_device(struct mt76x02_dev *dev)
+{
+ int err;
+
+ mt76x02_dma_disable(dev);
+ mt76x2_reset_wlan(dev, true);
+ mt76x2_power_on(dev);
+
+ err = mt76x2_mac_reset(dev, true);
+ if (err)
+ return err;
+
+ mt76x02_mac_start(dev);
+
+ return mt76x2_mcu_init(dev);
+}
+
static int mt76x2_init_hardware(struct mt76x02_dev *dev)
{
int ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
index 3a4e41724af1..4e003c7b62cf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
@@ -16,6 +16,7 @@ static const struct usb_device_id mt76x2u_device_table[] = {
{ USB_DEVICE(0x0e8d, 0x7612) }, /* Aukey USBAC1200 - Alfa AWUS036ACM */
{ USB_DEVICE(0x057c, 0x8503) }, /* Avm FRITZ!WLAN AC860 */
{ USB_DEVICE(0x7392, 0xb711) }, /* Edimax EW 7722 UAC */
+ { USB_DEVICE(0x0e8d, 0x7632) }, /* HC-M7662BU1 */
{ USB_DEVICE(0x2c4e, 0x0103) }, /* Mercury UD13 */
{ USB_DEVICE(0x0846, 0x9053) }, /* Netgear A6210 */
{ USB_DEVICE(0x045e, 0x02e6) }, /* XBox One Wireless Adapter */
@@ -74,8 +75,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
return 0;
err:
- ieee80211_free_hw(mt76_hw(dev));
- mt76u_deinit(&dev->mt76);
+ mt76_free_device(&dev->mt76);
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
@@ -91,9 +91,7 @@ static void mt76x2u_disconnect(struct usb_interface *intf)
set_bit(MT76_REMOVED, &dev->mphy.state);
ieee80211_unregister_hw(hw);
mt76x2u_cleanup(dev);
- mt76u_deinit(&dev->mt76);
-
- ieee80211_free_hw(hw);
+ mt76_free_device(&dev->mt76);
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index 5278bee812f1..38f473d587c9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -178,7 +178,14 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
seq_printf(s, "Tx Beamformee feedback triggered counts: %ld\n",
FIELD_GET(MT_ETBF_TX_FB_TRI, cnt));
- /* Tx SU counters */
+ /* Tx SU & MU counters */
+ cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy));
+ seq_printf(s, "Tx multi-user Beamforming counts: %ld\n",
+ FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt));
+ cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy));
+ seq_printf(s, "Tx multi-user MPDU counts: %d\n", cnt);
+ cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy));
+ seq_printf(s, "Tx multi-user successful MPDU counts: %d\n", cnt);
cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
seq_printf(s, "Tx single-user successful MPDU counts: %d\n", cnt);
@@ -384,6 +391,7 @@ int mt7915_init_debugfs(struct mt7915_dev *dev)
return 0;
}
+#ifdef CONFIG_MAC80211_DEBUGFS
/** per-station debugfs **/
/* usage: <tx mode> <ldpc> <stbc> <bw> <gi> <nss> <mcs> */
@@ -461,3 +469,4 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
debugfs_create_file("fixed_rate", 0600, dir, sta, &fops_fixed_rate);
debugfs_create_file("stats", 0400, dir, sta, &fops_sta_stats);
}
+#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
index 766185d1aa21..a8832c5e6004 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
@@ -79,26 +79,27 @@ void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
}
}
+static void
+mt7915_tx_cleanup(struct mt7915_dev *dev)
+{
+ mt76_queue_tx_cleanup(dev, MT_TXQ_MCU, false);
+ mt76_queue_tx_cleanup(dev, MT_TXQ_MCU_WA, false);
+ mt76_queue_tx_cleanup(dev, MT_TXQ_PSD, false);
+ mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false);
+}
+
static int mt7915_poll_tx(struct napi_struct *napi, int budget)
{
- static const u8 queue_map[] = {
- MT_TXQ_MCU,
- MT_TXQ_MCU_WA,
- MT_TXQ_BE
- };
struct mt7915_dev *dev;
- int i;
dev = container_of(napi, struct mt7915_dev, mt76.tx_napi);
- for (i = 0; i < ARRAY_SIZE(queue_map); i++)
- mt76_queue_tx_cleanup(dev, queue_map[i], false);
+ mt7915_tx_cleanup(dev);
if (napi_complete_done(napi, 0))
mt7915_irq_enable(dev, MT_INT_TX_DONE_ALL);
- for (i = 0; i < ARRAY_SIZE(queue_map); i++)
- mt76_queue_tx_cleanup(dev, queue_map[i], false);
+ mt7915_tx_cleanup(dev);
mt7915_mac_sta_poll(dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index aadf56e80bae..e90d0087e377 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -417,11 +417,6 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
he_cap_elem->mac_cap_info[0] =
IEEE80211_HE_MAC_CAP0_HTC_HE;
- he_cap_elem->mac_cap_info[1] =
- IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_0US |
- IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_1;
- he_cap_elem->mac_cap_info[2] =
- IEEE80211_HE_MAC_CAP2_BSR;
he_cap_elem->mac_cap_info[3] =
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED;
@@ -443,27 +438,27 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ;
- /* TODO: OFDMA */
-
switch (i) {
case NL80211_IFTYPE_AP:
he_cap_elem->mac_cap_info[0] |=
IEEE80211_HE_MAC_CAP0_TWT_RES;
+ he_cap_elem->mac_cap_info[2] |=
+ IEEE80211_HE_MAC_CAP2_BSR;
he_cap_elem->mac_cap_info[4] |=
IEEE80211_HE_MAC_CAP4_BQR;
+ he_cap_elem->mac_cap_info[5] |=
+ IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX;
he_cap_elem->phy_cap_info[3] |=
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;
he_cap_elem->phy_cap_info[6] |=
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
- he_cap_elem->phy_cap_info[9] |=
- IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
break;
case NL80211_IFTYPE_STATION:
he_cap_elem->mac_cap_info[0] |=
IEEE80211_HE_MAC_CAP0_TWT_REQ;
- he_cap_elem->mac_cap_info[3] |=
- IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED;
+ he_cap_elem->mac_cap_info[1] |=
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;
if (band == NL80211_BAND_2GHZ)
he_cap_elem->phy_cap_info[0] |=
@@ -473,18 +468,31 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G;
he_cap_elem->phy_cap_info[1] |=
- IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A;
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
+ IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US;
+ he_cap_elem->phy_cap_info[3] |=
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;
+ he_cap_elem->phy_cap_info[6] |=
+ IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
+ IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |
+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
+ he_cap_elem->phy_cap_info[7] |=
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
+ IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI;
he_cap_elem->phy_cap_info[8] |=
IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
- IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU;
+ IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU |
+ IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_484;
he_cap_elem->phy_cap_info[9] |=
- IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;
+ IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM |
+ IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
+ IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
+ IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;
break;
-#ifdef CONFIG_MAC80211_MESH
- case NL80211_IFTYPE_MESH_POINT:
- break;
-#endif
}
he_mcs->rx_mcs_80 = cpu_to_le16(mcs_map);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index a264e304a3df..6825afca1efb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -178,14 +178,14 @@ void mt7915_mac_sta_poll(struct mt7915_dev *dev)
static void
mt7915_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
- struct mt7915_rxv *rxv,
- struct ieee80211_radiotap_he *he)
+ struct ieee80211_radiotap_he *he,
+ __le32 *rxv)
{
u32 ru_h, ru_l;
u8 ru, offs = 0;
- ru_l = FIELD_GET(MT_PRXV_HE_RU_ALLOC_L, le32_to_cpu(rxv->v[0]));
- ru_h = FIELD_GET(MT_PRXV_HE_RU_ALLOC_H, le32_to_cpu(rxv->v[1]));
+ ru_l = FIELD_GET(MT_PRXV_HE_RU_ALLOC_L, le32_to_cpu(rxv[0]));
+ ru_h = FIELD_GET(MT_PRXV_HE_RU_ALLOC_H, le32_to_cpu(rxv[1]));
ru = (u8)(ru_l | ru_h << 4);
status->bw = RATE_INFO_BW_HE_RU;
@@ -228,7 +228,7 @@ mt7915_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
static void
mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
struct mt76_rx_status *status,
- struct mt7915_rxv *rxv)
+ __le32 *rxv, u32 phy)
{
/* TODO: struct ieee80211_radiotap_he_mu */
static const struct ieee80211_radiotap_he known = {
@@ -245,48 +245,45 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
HE_BITS(DATA2_TXOP_KNOWN),
};
struct ieee80211_radiotap_he *he = NULL;
- __le32 v2 = rxv->v[2];
- __le32 v11 = rxv->v[11];
- __le32 v14 = rxv->v[14];
- u32 ltf_size = le32_get_bits(v2, MT_CRXV_HE_LTF_SIZE) + 1;
+ u32 ltf_size = le32_get_bits(rxv[2], MT_CRXV_HE_LTF_SIZE) + 1;
he = skb_push(skb, sizeof(known));
memcpy(he, &known, sizeof(known));
- he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, v14) |
- HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, v2);
- he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, v2) |
+ he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[14]) |
+ HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[2]);
+ he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[2]) |
le16_encode_bits(ltf_size,
IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
- he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, v14) |
- HE_PREP(DATA6_DOPPLER, DOPPLER, v14);
+ he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) |
+ HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]);
- switch (rxv->phy) {
+ switch (phy) {
case MT_PHY_TYPE_HE_SU:
he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
HE_BITS(DATA1_UL_DL_KNOWN) |
HE_BITS(DATA1_BEAM_CHANGE_KNOWN) |
HE_BITS(DATA1_SPTL_REUSE_KNOWN);
- he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, v14) |
- HE_PREP(DATA3_UL_DL, UPLINK, v2);
- he->data4 |= HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, v11);
+ he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[14]) |
+ HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
+ he->data4 |= HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]);
break;
case MT_PHY_TYPE_HE_EXT_SU:
he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) |
HE_BITS(DATA1_UL_DL_KNOWN);
- he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, v2);
+ he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
break;
case MT_PHY_TYPE_HE_MU:
he->data1 |= HE_BITS(DATA1_FORMAT_MU) |
HE_BITS(DATA1_UL_DL_KNOWN) |
HE_BITS(DATA1_SPTL_REUSE_KNOWN);
- he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, v2);
- he->data4 |= HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, v11);
+ he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
+ he->data4 |= HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]);
- mt7915_mac_decode_he_radiotap_ru(status, rxv, he);
+ mt7915_mac_decode_he_radiotap_ru(status, he, rxv);
break;
case MT_PHY_TYPE_HE_TB:
he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) |
@@ -295,12 +292,12 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
HE_BITS(DATA1_SPTL_REUSE3_KNOWN) |
HE_BITS(DATA1_SPTL_REUSE4_KNOWN);
- he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, v11) |
- HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, v11) |
- HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, v11) |
- HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, v11);
+ he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[11]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[11]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[11]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[11]);
- mt7915_mac_decode_he_radiotap_ru(status, rxv, he);
+ mt7915_mac_decode_he_radiotap_ru(status, he, rxv);
break;
default:
break;
@@ -314,8 +311,9 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
struct mt7915_phy *phy = &dev->phy;
struct ieee80211_supported_band *sband;
struct ieee80211_hdr *hdr;
- struct mt7915_rxv rxv = {};
__le32 *rxd = (__le32 *)skb->data;
+ __le32 *rxv = NULL;
+ u32 mode = 0;
u32 rxd1 = le32_to_cpu(rxd[1]);
u32 rxd2 = le32_to_cpu(rxd[2]);
u32 rxd3 = le32_to_cpu(rxd[3]);
@@ -427,15 +425,14 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
if (rxd1 & MT_RXD1_NORMAL_GROUP_3) {
u32 v0, v1, v2;
- memcpy(rxv.v, rxd, sizeof(rxv.v));
-
+ rxv = rxd;
rxd += 2;
if ((u8 *)rxd - skb->data >= skb->len)
return -EINVAL;
- v0 = le32_to_cpu(rxv.v[0]);
- v1 = le32_to_cpu(rxv.v[1]);
- v2 = le32_to_cpu(rxv.v[2]);
+ v0 = le32_to_cpu(rxv[0]);
+ v1 = le32_to_cpu(rxv[1]);
+ v2 = le32_to_cpu(rxv[2]);
if (v0 & MT_PRXV_HT_AD_CODE)
status->enc_flags |= RX_ENC_FLAG_LDPC;
@@ -466,9 +463,9 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
return -EINVAL;
idx = i = FIELD_GET(MT_PRXV_TX_RATE, v0);
- rxv.phy = FIELD_GET(MT_CRXV_TX_MODE, v2);
+ mode = FIELD_GET(MT_CRXV_TX_MODE, v2);
- switch (rxv.phy) {
+ switch (mode) {
case MT_PHY_TYPE_CCK:
cck = true;
/* fall through */
@@ -503,8 +500,7 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
if (gi <= NL80211_RATE_INFO_HE_GI_3_2)
status->he_gi = gi;
- if (idx & MT_PRXV_TX_DCM)
- status->he_dcm = true;
+ status->he_dcm = !!(idx & MT_PRXV_TX_DCM);
break;
default:
return -EINVAL;
@@ -515,7 +511,7 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
case IEEE80211_STA_RX_BW_20:
break;
case IEEE80211_STA_RX_BW_40:
- if (rxv.phy & MT_PHY_TYPE_HE_EXT_SU &&
+ if (mode & MT_PHY_TYPE_HE_EXT_SU &&
(idx & MT_PRXV_TX_ER_SU_106T)) {
status->bw = RATE_INFO_BW_HE_RU;
status->he_ru =
@@ -535,7 +531,7 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
}
status->enc_flags |= RX_ENC_FLAG_STBC_MASK * stbc;
- if (rxv.phy < MT_PHY_TYPE_HE_SU && gi)
+ if (mode < MT_PHY_TYPE_HE_SU && gi)
status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
}
}
@@ -548,8 +544,8 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
mt76_insert_ccmp_hdr(skb, key_id);
}
- if (status->flag & RX_FLAG_RADIOTAP_HE)
- mt7915_mac_decode_he_radiotap(skb, status, &rxv);
+ if (rxv && status->flag & RX_FLAG_RADIOTAP_HE)
+ mt7915_mac_decode_he_radiotap(skb, status, rxv, mode);
hdr = mt76_skb_get_hdr(skb);
if (!status->wcid || !ieee80211_is_data_qos(hdr->frame_control))
@@ -591,16 +587,16 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;
- if (ieee80211_is_data(fc) || ieee80211_is_bufferable_mmpdu(fc)) {
- q_idx = wmm_idx * MT7915_MAX_WMM_SETS +
- skb_get_queue_mapping(skb);
- p_fmt = MT_TX_TYPE_CT;
- } else if (beacon) {
- q_idx = MT_LMAC_BCN0;
+ if (beacon) {
p_fmt = MT_TX_TYPE_FW;
- } else {
+ q_idx = MT_LMAC_BCN0;
+ } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
+ p_fmt = MT_TX_TYPE_CT;
q_idx = MT_LMAC_ALTX0;
+ } else {
p_fmt = MT_TX_TYPE_CT;
+ q_idx = wmm_idx * MT7915_MAX_WMM_SETS +
+ mt7915_lmac_mapping(dev, skb_get_queue_mapping(skb));
}
val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + MT_TXD_SIZE) |
@@ -616,6 +612,7 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
FIELD_PREP(MT_TXD1_TID,
skb->priority & IEEE80211_QOS_CTL_TID_MASK) |
FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx);
+
if (ext_phy && q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0)
val |= MT_TXD1_TGID;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
index b9bc8b25b031..c8bb5ea96c60 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
@@ -128,13 +128,6 @@ enum rx_pkt_type {
#define MT_CRXV_HE_BEAM_CHNG BIT(13)
#define MT_CRXV_HE_DOPPLER BIT(16)
-struct mt7915_rxv {
- u32 phy;
-
- /* P-RXV: bit 0~1, C-RXV: bit 2~19 */
- __le32 v[20];
-};
-
enum tx_header_format {
MT_HDR_FORMAT_802_3,
MT_HDR_FORMAT_CMD,
@@ -149,16 +142,6 @@ enum tx_pkt_type {
MT_TX_TYPE_FW,
};
-enum tx_pkt_queue_idx {
- MT_LMAC_AC00,
- MT_LMAC_AC01,
- MT_LMAC_AC02,
- MT_LMAC_AC03,
- MT_LMAC_ALTX0 = 0x10,
- MT_LMAC_BMC0 = 0x10,
- MT_LMAC_BCN0 = 0x12,
-};
-
enum tx_port_idx {
MT_TX_PORT_IDX_LMAC,
MT_TX_PORT_IDX_MCU
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 05b5650c56c8..f95a0b55c4a2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -125,7 +125,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
mutex_lock(&dev->mt76.mutex);
- mvif->idx = ffs(~phy->vif_mask) - 1;
+ mvif->idx = ffs(~phy->mt76->vif_mask) - 1;
if (mvif->idx >= MT7915_MAX_INTERFACES) {
ret = -ENOSPC;
goto out;
@@ -150,7 +150,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
if (ret)
goto out;
- phy->vif_mask |= BIT(mvif->idx);
+ phy->mt76->vif_mask |= BIT(mvif->idx);
phy->omac_mask |= BIT(mvif->omac_idx);
idx = MT7915_WTBL_RESERVED - mvif->idx;
@@ -194,7 +194,7 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
mt76_txq_remove(&dev->mt76, vif->txq);
mutex_lock(&dev->mt76.mutex);
- phy->vif_mask &= ~BIT(mvif->idx);
+ phy->mt76->vif_mask &= ~BIT(mvif->idx);
phy->omac_mask &= ~BIT(mvif->omac_idx);
mutex_unlock(&dev->mt76.mutex);
@@ -350,13 +350,12 @@ static int
mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
/* no need to update right away, we'll get BSS_CHANGED_QOS */
- mvif->wmm[queue].cw_min = params->cw_min;
- mvif->wmm[queue].cw_max = params->cw_max;
- mvif->wmm[queue].aifs = params->aifs;
- mvif->wmm[queue].txop = params->txop;
+ queue = mt7915_lmac_mapping(dev, queue);
+ mvif->queue_params[queue] = *params;
return 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index c8c12c740c1a..eaed5ef05401 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -312,8 +312,10 @@ mt7915_mcu_parse_response(struct mt7915_dev *dev, int cmd,
struct mt7915_mcu_rxd *rxd = (struct mt7915_mcu_rxd *)skb->data;
int ret = 0;
- if (seq != rxd->seq)
- return -EAGAIN;
+ if (seq != rxd->seq) {
+ ret = -EAGAIN;
+ goto out;
+ }
switch (cmd) {
case -MCU_CMD_PATCH_SEM_CONTROL:
@@ -330,6 +332,7 @@ mt7915_mcu_parse_response(struct mt7915_dev *dev, int cmd,
default:
break;
}
+out:
dev_kfree_skb(skb);
return ret;
@@ -505,15 +508,22 @@ static void
mt7915_mcu_tx_rate_report(struct mt7915_dev *dev, struct sk_buff *skb)
{
struct mt7915_mcu_ra_info *ra = (struct mt7915_mcu_ra_info *)skb->data;
- u16 wcidx = le16_to_cpu(ra->wlan_idx);
- struct mt76_wcid *wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
- struct mt7915_sta *msta = container_of(wcid, struct mt7915_sta, wcid);
- struct mt7915_sta_stats *stats = &msta->stats;
- struct mt76_phy *mphy = &dev->mphy;
struct rate_info rate = {}, prob_rate = {};
+ u16 probe = le16_to_cpu(ra->prob_up_rate);
u16 attempts = le16_to_cpu(ra->attempts);
u16 curr = le16_to_cpu(ra->curr_rate);
- u16 probe = le16_to_cpu(ra->prob_up_rate);
+ u16 wcidx = le16_to_cpu(ra->wlan_idx);
+ struct mt76_phy *mphy = &dev->mphy;
+ struct mt7915_sta_stats *stats;
+ struct mt7915_sta *msta;
+ struct mt76_wcid *wcid;
+
+ if (wcidx >= MT76_N_WCIDS)
+ return;
+
+ wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
+ msta = container_of(wcid, struct mt7915_sta, wcid);
+ stats = &msta->stats;
if (msta->wcid.ext_phy && dev->mt76.phy2)
mphy = dev->mt76.phy2;
@@ -1166,19 +1176,31 @@ mt7915_mcu_sta_ba(struct mt7915_dev *dev,
struct wtbl_req_hdr *wtbl_hdr;
struct tlv *sta_wtbl;
struct sk_buff *skb;
+ int ret;
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
MT7915_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
- mt7915_mcu_sta_ba_tlv(skb, params, enable, tx);
sta_wtbl = mt7915_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));
wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, sta_wtbl,
&skb);
mt7915_mcu_wtbl_ba_tlv(skb, params, enable, tx, sta_wtbl, wtbl_hdr);
+ ret = __mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_EXT_CMD_STA_REC_UPDATE, true);
+ if (ret)
+ return ret;
+
+ skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
+ MT7915_STA_UPDATE_MAX_SIZE);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ mt7915_mcu_sta_ba_tlv(skb, params, enable, tx);
+
return __mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD_STA_REC_UPDATE, true);
}
@@ -1466,16 +1488,39 @@ mt7915_mcu_sta_muru_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]);
}
+static int
+mt7915_mcu_add_mu(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+ struct sk_buff *skb;
+ int len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_muru);
+
+ if (!sta->vht_cap.vht_supported && !sta->he_cap.has_he)
+ return 0;
+
+ skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ /* starec muru */
+ mt7915_mcu_sta_muru_tlv(skb, sta);
+
+ return __mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_EXT_CMD_STA_REC_UPDATE, true);
+}
+
static void
mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
struct ieee80211_sta *sta)
{
struct tlv *tlv;
+ /* starec ht */
if (sta->ht_cap.ht_supported) {
struct sta_rec_ht *ht;
- /* starec ht */
tlv = mt7915_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
ht = (struct sta_rec_ht *)tlv;
ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);
@@ -1495,10 +1540,6 @@ mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
/* starec he */
if (sta->he_cap.has_he)
mt7915_mcu_sta_he_tlv(skb, sta);
-
- /* starec muru */
- if (sta->he_cap.has_he || sta->vht_cap.vht_supported)
- mt7915_mcu_sta_muru_tlv(skb, sta);
}
static void
@@ -2064,6 +2105,32 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
MCU_EXT_CMD_STA_REC_UPDATE, true);
}
+static int
+mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+#define MT_STA_BSS_GROUP 1
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+ struct {
+ __le32 action;
+ u8 wlan_idx_lo;
+ u8 status;
+ u8 wlan_idx_hi;
+ u8 rsv0[5];
+ __le32 val;
+ u8 rsv1[8];
+ } __packed req = {
+ .action = cpu_to_le32(MT_STA_BSS_GROUP),
+ .wlan_idx_lo = to_wcid_lo(msta->wcid.idx),
+ .wlan_idx_hi = to_wcid_hi(msta->wcid.idx),
+ .val = cpu_to_le32(mvif->idx),
+ };
+
+ return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_DRR_CTRL,
+ &req, sizeof(req), true);
+}
+
int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable)
{
@@ -2073,10 +2140,18 @@ int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
return 0;
/* must keep the order */
+ ret = mt7915_mcu_add_group(dev, vif, sta);
+ if (ret)
+ return ret;
+
ret = mt7915_mcu_add_txbf(dev, vif, sta, enable);
if (ret)
return ret;
+ ret = mt7915_mcu_add_mu(dev, vif, sta);
+ if (ret)
+ return ret;
+
if (enable)
return mt7915_mcu_add_rate_ctrl(dev, vif, sta);
@@ -2823,23 +2898,23 @@ int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif)
int ac;
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ struct ieee80211_tx_queue_params *q = &mvif->queue_params[ac];
struct edca *e = &req.edca[ac];
e->queue = ac + mvif->wmm_idx * MT7915_MAX_WMM_SETS;
- e->aifs = mvif->wmm[ac].aifs;
- e->txop = cpu_to_le16(mvif->wmm[ac].txop);
+ e->aifs = q->aifs;
+ e->txop = cpu_to_le16(q->txop);
- if (mvif->wmm[ac].cw_min)
- e->cw_min = fls(mvif->wmm[ac].cw_max);
+ if (q->cw_min)
+ e->cw_min = fls(q->cw_min);
else
e->cw_min = 5;
- if (mvif->wmm[ac].cw_max)
- e->cw_max = cpu_to_le16(fls(mvif->wmm[ac].cw_max));
+ if (q->cw_max)
+ e->cw_max = cpu_to_le16(fls(q->cw_max));
else
e->cw_max = cpu_to_le16(10);
}
-
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EDCA_UPDATE,
&req, sizeof(req), true);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index c241dd7c4c36..cb35e718409a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -201,6 +201,7 @@ enum {
MCU_EXT_CMD_EDCA_UPDATE = 0x27,
MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
+ MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
@@ -653,7 +654,7 @@ struct sta_rec_muru {
bool ofdma_ul_en;
bool mimo_dl_en;
bool mimo_ul_en;
- bool rsv[4];
+ u8 rsv[4];
} cfg;
struct {
@@ -664,7 +665,7 @@ struct sta_rec_muru {
bool lt16_sigb;
bool rx_su_comp_sigb;
bool rx_su_non_comp_sigb;
- bool rsv;
+ u8 rsv;
} ofdma_dl;
struct {
@@ -951,7 +952,6 @@ enum {
sizeof(struct sta_rec_ba) + \
sizeof(struct sta_rec_vht) + \
sizeof(struct tlv) + \
- sizeof(struct sta_rec_muru) + \
MT7915_WTBL_UPDATE_MAX_SIZE)
#define MT7915_WTBL_UPDATE_BA_SIZE (sizeof(struct wtbl_req_hdr) + \
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 85d74ecd0351..d8a13b4a2359 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -99,15 +99,10 @@ struct mt7915_vif {
u8 band_idx;
u8 wmm_idx;
- struct {
- u16 cw_min;
- u16 cw_max;
- u16 txop;
- u8 aifs;
- } wmm[IEEE80211_NUM_ACS];
-
struct mt7915_sta sta;
struct mt7915_dev *dev;
+
+ struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
};
struct mib_stats {
@@ -125,7 +120,6 @@ struct mt7915_phy {
struct ieee80211_sband_iftype_data iftype[2][NUM_NL80211_IFTYPES];
u32 rxfilter;
- u32 vif_mask;
u32 omac_mask;
u16 noise;
@@ -200,6 +194,16 @@ enum {
};
enum {
+ MT_LMAC_AC00,
+ MT_LMAC_AC01,
+ MT_LMAC_AC02,
+ MT_LMAC_AC03,
+ MT_LMAC_ALTX0 = 0x10,
+ MT_LMAC_BMC0,
+ MT_LMAC_BCN0,
+};
+
+enum {
MT_RX_SEL0,
MT_RX_SEL1,
};
@@ -254,6 +258,21 @@ mt7915_ext_phy(struct mt7915_dev *dev)
return phy->priv;
}
+static inline u8 mt7915_lmac_mapping(struct mt7915_dev *dev, u8 ac)
+{
+ static const u8 lmac_queue_map[] = {
+ [IEEE80211_AC_BK] = MT_LMAC_AC00,
+ [IEEE80211_AC_BE] = MT_LMAC_AC01,
+ [IEEE80211_AC_VI] = MT_LMAC_AC02,
+ [IEEE80211_AC_VO] = MT_LMAC_AC03,
+ };
+
+ if (WARN_ON_ONCE(ac >= ARRAY_SIZE(lmac_queue_map)))
+ return MT_LMAC_AC01; /* BE */
+
+ return lmac_queue_map[ac];
+}
+
static inline void
mt7915_set_aggr_state(struct mt7915_sta *msta, u8 tid,
enum mt7915_ampdu_state state)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
index 7937c6965f59..0ec4e184b889 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
@@ -103,7 +103,7 @@ static int mt7915_pci_probe(struct pci_dev *pdev,
static const struct mt76_driver_ops drv_ops = {
/* txwi_size = txd size + txp size */
.txwi_size = MT_TXD_SIZE + sizeof(struct mt7915_txp),
- .drv_flags = MT_DRV_TXWI_NO_FREE,
+ .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ,
.survey_flags = SURVEY_INFO_TIME_TX |
SURVEY_INFO_TIME_RX |
SURVEY_INFO_TIME_BSS_RX,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index c121715f8bff..e0989141d9da 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -117,11 +117,16 @@
#define MT_MIB_SDR16(_band) MT_WF_MIB(_band, 0x048)
#define MT_MIB_SDR16_BUSY_MASK GENMASK(23, 0)
+#define MT_MIB_SDR34(_band) MT_WF_MIB(_band, 0x090)
+#define MT_MIB_MU_BF_TX_CNT GENMASK(15, 0)
+
#define MT_MIB_SDR36(_band) MT_WF_MIB(_band, 0x098)
#define MT_MIB_SDR36_TXTIME_MASK GENMASK(23, 0)
#define MT_MIB_SDR37(_band) MT_WF_MIB(_band, 0x09c)
#define MT_MIB_SDR37_RXTIME_MASK GENMASK(23, 0)
+#define MT_MIB_DR8(_band) MT_WF_MIB(_band, 0x0c0)
+#define MT_MIB_DR9(_band) MT_WF_MIB(_band, 0x0c4)
#define MT_MIB_DR11(_band) MT_WF_MIB(_band, 0x0cc)
#define MT_MIB_MB_SDR0(_band, n) MT_WF_MIB(_band, 0x100 + ((n) << 4))
diff --git a/drivers/net/wireless/mediatek/mt76/pci.c b/drivers/net/wireless/mediatek/mt76/pci.c
index 04c5a692bc85..4c1c159fbb62 100644
--- a/drivers/net/wireless/mediatek/mt76/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/pci.c
@@ -3,6 +3,7 @@
* Copyright (C) 2019 Lorenzo Bianconi <lorenzo@kernel.org>
*/
+#include "mt76.h"
#include <linux/pci.h>
void mt76_pci_disable_aspm(struct pci_dev *pdev)
diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
new file mode 100644
index 000000000000..d2b38ed7f3b4
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/sdio.c
@@ -0,0 +1,368 @@
+// SPDX-License-Identifier: ISC
+/* Copyright (C) 2020 MediaTek Inc.
+ *
+ * This file is written based on mt76/usb.c.
+ *
+ * Author: Felix Fietkau <nbd@nbd.name>
+ * Lorenzo Bianconi <lorenzo@kernel.org>
+ * Sean Wang <sean.wang@mediatek.com>
+ */
+
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+
+#include "mt76.h"
+
+static int
+mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid)
+{
+ struct mt76_queue *q = &dev->q_rx[qid];
+
+ spin_lock_init(&q->lock);
+ q->entry = devm_kcalloc(dev->dev,
+ MT_NUM_RX_ENTRIES, sizeof(*q->entry),
+ GFP_KERNEL);
+ if (!q->entry)
+ return -ENOMEM;
+
+ q->ndesc = MT_NUM_RX_ENTRIES;
+ q->head = q->tail = 0;
+ q->queued = 0;
+
+ return 0;
+}
+
+static int mt76s_alloc_tx(struct mt76_dev *dev)
+{
+ struct mt76_queue *q;
+ int i;
+
+ for (i = 0; i < MT_TXQ_MCU_WA; i++) {
+ INIT_LIST_HEAD(&dev->q_tx[i].swq);
+
+ q = devm_kzalloc(dev->dev, sizeof(*q), GFP_KERNEL);
+ if (!q)
+ return -ENOMEM;
+
+ spin_lock_init(&q->lock);
+ q->hw_idx = i;
+ dev->q_tx[i].q = q;
+
+ q->entry = devm_kcalloc(dev->dev,
+ MT_NUM_TX_ENTRIES, sizeof(*q->entry),
+ GFP_KERNEL);
+ if (!q->entry)
+ return -ENOMEM;
+
+ q->ndesc = MT_NUM_TX_ENTRIES;
+ }
+
+ return 0;
+}
+
+void mt76s_stop_txrx(struct mt76_dev *dev)
+{
+ struct mt76_sdio *sdio = &dev->sdio;
+
+ cancel_work_sync(&sdio->stat_work);
+ clear_bit(MT76_READING_STATS, &dev->phy.state);
+
+ mt76_tx_status_check(dev, NULL, true);
+}
+EXPORT_SYMBOL_GPL(mt76s_stop_txrx);
+
+int mt76s_alloc_queues(struct mt76_dev *dev)
+{
+ int err;
+
+ err = mt76s_alloc_rx_queue(dev, MT_RXQ_MAIN);
+ if (err < 0)
+ return err;
+
+ return mt76s_alloc_tx(dev);
+}
+EXPORT_SYMBOL_GPL(mt76s_alloc_queues);
+
+static struct mt76_queue_entry *
+mt76s_get_next_rx_entry(struct mt76_queue *q)
+{
+ struct mt76_queue_entry *e = NULL;
+
+ spin_lock_bh(&q->lock);
+ if (q->queued > 0) {
+ e = &q->entry[q->head];
+ q->head = (q->head + 1) % q->ndesc;
+ q->queued--;
+ }
+ spin_unlock_bh(&q->lock);
+
+ return e;
+}
+
+static int
+mt76s_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
+{
+ int qid = q - &dev->q_rx[MT_RXQ_MAIN];
+ int nframes = 0;
+
+ while (true) {
+ struct mt76_queue_entry *e;
+
+ if (!test_bit(MT76_STATE_INITIALIZED, &dev->phy.state))
+ break;
+
+ e = mt76s_get_next_rx_entry(q);
+ if (!e || !e->skb)
+ break;
+
+ dev->drv->rx_skb(dev, MT_RXQ_MAIN, e->skb);
+ e->skb = NULL;
+ nframes++;
+ }
+ if (qid == MT_RXQ_MAIN)
+ mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
+
+ return nframes;
+}
+
+static int mt76s_process_tx_queue(struct mt76_dev *dev, enum mt76_txq_id qid)
+{
+ struct mt76_sw_queue *sq = &dev->q_tx[qid];
+ u32 n_dequeued = 0, n_sw_dequeued = 0;
+ struct mt76_queue_entry entry;
+ struct mt76_queue *q = sq->q;
+ bool wake;
+
+ while (q->queued > n_dequeued) {
+ if (!q->entry[q->head].done)
+ break;
+
+ if (q->entry[q->head].schedule) {
+ q->entry[q->head].schedule = false;
+ n_sw_dequeued++;
+ }
+
+ entry = q->entry[q->head];
+ q->entry[q->head].done = false;
+ q->head = (q->head + 1) % q->ndesc;
+ n_dequeued++;
+
+ if (qid == MT_TXQ_MCU)
+ dev_kfree_skb(entry.skb);
+ else
+ dev->drv->tx_complete_skb(dev, qid, &entry);
+ }
+
+ spin_lock_bh(&q->lock);
+
+ sq->swq_queued -= n_sw_dequeued;
+ q->queued -= n_dequeued;
+
+ wake = q->stopped && q->queued < q->ndesc - 8;
+ if (wake)
+ q->stopped = false;
+
+ if (!q->queued)
+ wake_up(&dev->tx_wait);
+
+ spin_unlock_bh(&q->lock);
+
+ if (qid == MT_TXQ_MCU)
+ goto out;
+
+ mt76_txq_schedule(&dev->phy, qid);
+
+ if (wake)
+ ieee80211_wake_queue(dev->hw, qid);
+
+ wake_up_process(dev->sdio.tx_kthread);
+out:
+ return n_dequeued;
+}
+
+static void mt76s_tx_status_data(struct work_struct *work)
+{
+ struct mt76_sdio *sdio;
+ struct mt76_dev *dev;
+ u8 update = 1;
+ u16 count = 0;
+
+ sdio = container_of(work, struct mt76_sdio, stat_work);
+ dev = container_of(sdio, struct mt76_dev, sdio);
+
+ while (true) {
+ if (test_bit(MT76_REMOVED, &dev->phy.state))
+ break;
+
+ if (!dev->drv->tx_status_data(dev, &update))
+ break;
+ count++;
+ }
+
+ if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state))
+ queue_work(dev->wq, &sdio->stat_work);
+ else
+ clear_bit(MT76_READING_STATS, &dev->phy.state);
+}
+
+static int
+mt76s_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
+ struct sk_buff *skb, struct mt76_wcid *wcid,
+ struct ieee80211_sta *sta)
+{
+ struct mt76_queue *q = dev->q_tx[qid].q;
+ struct mt76_tx_info tx_info = {
+ .skb = skb,
+ };
+ int err, len = skb->len;
+ u16 idx = q->tail;
+
+ if (q->queued == q->ndesc)
+ return -ENOSPC;
+
+ skb->prev = skb->next = NULL;
+ err = dev->drv->tx_prepare_skb(dev, NULL, qid, wcid, sta, &tx_info);
+ if (err < 0)
+ return err;
+
+ q->entry[q->tail].skb = tx_info.skb;
+ q->entry[q->tail].buf_sz = len;
+ q->tail = (q->tail + 1) % q->ndesc;
+ q->queued++;
+
+ return idx;
+}
+
+static int
+mt76s_tx_queue_skb_raw(struct mt76_dev *dev, enum mt76_txq_id qid,
+ struct sk_buff *skb, u32 tx_info)
+{
+ struct mt76_queue *q = dev->q_tx[qid].q;
+ int ret = -ENOSPC, len = skb->len;
+
+ spin_lock_bh(&q->lock);
+ if (q->queued == q->ndesc)
+ goto out;
+
+ ret = mt76_skb_adjust_pad(skb);
+ if (ret)
+ goto out;
+
+ q->entry[q->tail].buf_sz = len;
+ q->entry[q->tail].skb = skb;
+ q->tail = (q->tail + 1) % q->ndesc;
+ q->queued++;
+
+out:
+ spin_unlock_bh(&q->lock);
+
+ return ret;
+}
+
+static void mt76s_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
+{
+ struct mt76_sdio *sdio = &dev->sdio;
+
+ wake_up_process(sdio->tx_kthread);
+}
+
+static const struct mt76_queue_ops sdio_queue_ops = {
+ .tx_queue_skb = mt76s_tx_queue_skb,
+ .kick = mt76s_tx_kick,
+ .tx_queue_skb_raw = mt76s_tx_queue_skb_raw,
+};
+
+static int mt76s_kthread_run(void *data)
+{
+ struct mt76_dev *dev = data;
+ struct mt76_phy *mphy = &dev->phy;
+
+ while (!kthread_should_stop()) {
+ int i, nframes = 0;
+
+ cond_resched();
+
+ /* rx processing */
+ local_bh_disable();
+ rcu_read_lock();
+
+ mt76_for_each_q_rx(dev, i)
+ nframes += mt76s_process_rx_queue(dev, &dev->q_rx[i]);
+
+ rcu_read_unlock();
+ local_bh_enable();
+
+ /* tx processing */
+ for (i = 0; i < MT_TXQ_MCU_WA; i++)
+ nframes += mt76s_process_tx_queue(dev, i);
+
+ if (dev->drv->tx_status_data &&
+ !test_and_set_bit(MT76_READING_STATS, &mphy->state))
+ queue_work(dev->wq, &dev->sdio.stat_work);
+
+ if (!nframes || !test_bit(MT76_STATE_RUNNING, &mphy->state)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }
+ }
+
+ return 0;
+}
+
+void mt76s_deinit(struct mt76_dev *dev)
+{
+ struct mt76_sdio *sdio = &dev->sdio;
+ int i;
+
+ kthread_stop(sdio->kthread);
+ kthread_stop(sdio->tx_kthread);
+ mt76s_stop_txrx(dev);
+
+ sdio_claim_host(sdio->func);
+ sdio_release_irq(sdio->func);
+ sdio_release_host(sdio->func);
+
+ mt76_for_each_q_rx(dev, i) {
+ struct mt76_queue *q = &dev->q_rx[i];
+ int j;
+
+ for (j = 0; j < q->ndesc; j++) {
+ struct mt76_queue_entry *e = &q->entry[j];
+
+ if (!e->skb)
+ continue;
+
+ dev_kfree_skb(e->skb);
+ e->skb = NULL;
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(mt76s_deinit);
+
+int mt76s_init(struct mt76_dev *dev, struct sdio_func *func,
+ const struct mt76_bus_ops *bus_ops)
+{
+ struct mt76_sdio *sdio = &dev->sdio;
+
+ sdio->kthread = kthread_create(mt76s_kthread_run, dev, "mt76s");
+ if (IS_ERR(sdio->kthread))
+ return PTR_ERR(sdio->kthread);
+
+ INIT_WORK(&sdio->stat_work, mt76s_tx_status_data);
+
+ mutex_init(&sdio->sched.lock);
+ dev->queue_ops = &sdio_queue_ops;
+ dev->bus = bus_ops;
+ dev->sdio.func = func;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mt76s_init);
+
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/testmode.c b/drivers/net/wireless/mediatek/mt76/testmode.c
new file mode 100644
index 000000000000..75bb02cdfdae
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/testmode.c
@@ -0,0 +1,497 @@
+// SPDX-License-Identifier: ISC
+/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
+#include "mt76.h"
+
+static const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+ [MT76_TM_ATTR_RESET] = { .type = NLA_FLAG },
+ [MT76_TM_ATTR_STATE] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 },
+ [MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_RATE_NSS] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_RATE_IDX] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_RATE_SGI] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_RATE_LDPC] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_ANTENNA] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_POWER_CONTROL] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_POWER] = { .type = NLA_NESTED },
+ [MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
+};
+
+void mt76_testmode_tx_pending(struct mt76_dev *dev)
+{
+ struct mt76_testmode_data *td = &dev->test;
+ struct mt76_wcid *wcid = &dev->global_wcid;
+ struct sk_buff *skb = td->tx_skb;
+ struct mt76_queue *q;
+ int qid;
+
+ if (!skb || !td->tx_pending)
+ return;
+
+ qid = skb_get_queue_mapping(skb);
+ q = dev->q_tx[qid].q;
+
+ spin_lock_bh(&q->lock);
+
+ while (td->tx_pending > 0 && q->queued < q->ndesc / 2) {
+ int ret;
+
+ ret = dev->queue_ops->tx_queue_skb(dev, qid, skb_get(skb), wcid, NULL);
+ if (ret < 0)
+ break;
+
+ td->tx_pending--;
+ td->tx_queued++;
+ }
+
+ dev->queue_ops->kick(dev, q);
+
+ spin_unlock_bh(&q->lock);
+}
+
+
+static int
+mt76_testmode_tx_init(struct mt76_dev *dev)
+{
+ struct mt76_testmode_data *td = &dev->test;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_hdr *hdr;
+ struct sk_buff *skb;
+ u16 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
+ IEEE80211_FCTL_FROMDS;
+ struct ieee80211_tx_rate *rate;
+ u8 max_nss = hweight8(dev->phy.antenna_mask);
+
+ if (td->tx_antenna_mask)
+ max_nss = min_t(u8, max_nss, hweight8(td->tx_antenna_mask));
+
+ skb = alloc_skb(td->tx_msdu_len, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ dev_kfree_skb(td->tx_skb);
+ td->tx_skb = skb;
+ hdr = __skb_put_zero(skb, td->tx_msdu_len);
+ hdr->frame_control = cpu_to_le16(fc);
+ memcpy(hdr->addr1, dev->macaddr, sizeof(dev->macaddr));
+ memcpy(hdr->addr2, dev->macaddr, sizeof(dev->macaddr));
+ memcpy(hdr->addr3, dev->macaddr, sizeof(dev->macaddr));
+
+ info = IEEE80211_SKB_CB(skb);
+ info->flags = IEEE80211_TX_CTL_INJECTED |
+ IEEE80211_TX_CTL_NO_ACK |
+ IEEE80211_TX_CTL_NO_PS_BUFFER;
+ rate = &info->control.rates[0];
+ rate->count = 1;
+ rate->idx = td->tx_rate_idx;
+
+ switch (td->tx_rate_mode) {
+ case MT76_TM_TX_MODE_CCK:
+ if (dev->phy.chandef.chan->band != NL80211_BAND_2GHZ)
+ return -EINVAL;
+
+ if (rate->idx > 4)
+ return -EINVAL;
+ break;
+ case MT76_TM_TX_MODE_OFDM:
+ if (dev->phy.chandef.chan->band != NL80211_BAND_2GHZ)
+ break;
+
+ if (rate->idx > 8)
+ return -EINVAL;
+
+ rate->idx += 4;
+ break;
+ case MT76_TM_TX_MODE_HT:
+ if (rate->idx > 8 * max_nss &&
+ !(rate->idx == 32 &&
+ dev->phy.chandef.width >= NL80211_CHAN_WIDTH_40))
+ return -EINVAL;
+
+ rate->flags |= IEEE80211_TX_RC_MCS;
+ break;
+ case MT76_TM_TX_MODE_VHT:
+ if (rate->idx > 9)
+ return -EINVAL;
+
+ if (td->tx_rate_nss > max_nss)
+ return -EINVAL;
+
+ ieee80211_rate_set_vht(rate, td->tx_rate_idx, td->tx_rate_nss);
+ rate->flags |= IEEE80211_TX_RC_VHT_MCS;
+ break;
+ default:
+ break;
+ }
+
+ if (td->tx_rate_sgi)
+ rate->flags |= IEEE80211_TX_RC_SHORT_GI;
+
+ if (td->tx_rate_ldpc)
+ info->flags |= IEEE80211_TX_CTL_LDPC;
+
+ if (td->tx_rate_mode >= MT76_TM_TX_MODE_HT) {
+ switch (dev->phy.chandef.width) {
+ case NL80211_CHAN_WIDTH_40:
+ rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+ break;
+ case NL80211_CHAN_WIDTH_80:
+ rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
+ break;
+ case NL80211_CHAN_WIDTH_80P80:
+ case NL80211_CHAN_WIDTH_160:
+ rate->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH;
+ break;
+ default:
+ break;
+ }
+ }
+
+ skb_set_queue_mapping(skb, IEEE80211_AC_BE);
+
+ return 0;
+}
+
+static void
+mt76_testmode_tx_start(struct mt76_dev *dev)
+{
+ struct mt76_testmode_data *td = &dev->test;
+
+ td->tx_queued = 0;
+ td->tx_done = 0;
+ td->tx_pending = td->tx_count;
+ tasklet_schedule(&dev->tx_tasklet);
+}
+
+static void
+mt76_testmode_tx_stop(struct mt76_dev *dev)
+{
+ struct mt76_testmode_data *td = &dev->test;
+
+ tasklet_disable(&dev->tx_tasklet);
+
+ td->tx_pending = 0;
+
+ tasklet_enable(&dev->tx_tasklet);
+
+ wait_event_timeout(dev->tx_wait, td->tx_done == td->tx_queued, 10 * HZ);
+
+ dev_kfree_skb(td->tx_skb);
+ td->tx_skb = NULL;
+}
+
+static inline void
+mt76_testmode_param_set(struct mt76_testmode_data *td, u16 idx)
+{
+ td->param_set[idx / 32] |= BIT(idx % 32);
+}
+
+static inline bool
+mt76_testmode_param_present(struct mt76_testmode_data *td, u16 idx)
+{
+ return td->param_set[idx / 32] & BIT(idx % 32);
+}
+
+static void
+mt76_testmode_init_defaults(struct mt76_dev *dev)
+{
+ struct mt76_testmode_data *td = &dev->test;
+
+ if (td->tx_msdu_len > 0)
+ return;
+
+ td->tx_msdu_len = 1024;
+ td->tx_count = 1;
+ td->tx_rate_mode = MT76_TM_TX_MODE_OFDM;
+ td->tx_rate_nss = 1;
+}
+
+static int
+__mt76_testmode_set_state(struct mt76_dev *dev, enum mt76_testmode_state state)
+{
+ enum mt76_testmode_state prev_state = dev->test.state;
+ int err;
+
+ if (prev_state == MT76_TM_STATE_TX_FRAMES)
+ mt76_testmode_tx_stop(dev);
+
+ if (state == MT76_TM_STATE_TX_FRAMES) {
+ err = mt76_testmode_tx_init(dev);
+ if (err)
+ return err;
+ }
+
+ err = dev->test_ops->set_state(dev, state);
+ if (err) {
+ if (state == MT76_TM_STATE_TX_FRAMES)
+ mt76_testmode_tx_stop(dev);
+
+ return err;
+ }
+
+ if (state == MT76_TM_STATE_TX_FRAMES)
+ mt76_testmode_tx_start(dev);
+ else if (state == MT76_TM_STATE_RX_FRAMES) {
+ memset(&dev->test.rx_stats, 0, sizeof(dev->test.rx_stats));
+ }
+
+ dev->test.state = state;
+
+ return 0;
+}
+
+int mt76_testmode_set_state(struct mt76_dev *dev, enum mt76_testmode_state state)
+{
+ struct mt76_testmode_data *td = &dev->test;
+ struct ieee80211_hw *hw = dev->phy.hw;
+
+ if (state == td->state && state == MT76_TM_STATE_OFF)
+ return 0;
+
+ if (state > MT76_TM_STATE_OFF &&
+ (!test_bit(MT76_STATE_RUNNING, &dev->phy.state) ||
+ !(hw->conf.flags & IEEE80211_CONF_MONITOR)))
+ return -ENOTCONN;
+
+ if (state != MT76_TM_STATE_IDLE &&
+ td->state != MT76_TM_STATE_IDLE) {
+ int ret;
+
+ ret = __mt76_testmode_set_state(dev, MT76_TM_STATE_IDLE);
+ if (ret)
+ return ret;
+ }
+
+ return __mt76_testmode_set_state(dev, state);
+
+}
+EXPORT_SYMBOL(mt76_testmode_set_state);
+
+static int
+mt76_tm_get_u8(struct nlattr *attr, u8 *dest, u8 min, u8 max)
+{
+ u8 val;
+
+ if (!attr)
+ return 0;
+
+ val = nla_get_u8(attr);
+ if (val < min || val > max)
+ return -EINVAL;
+
+ *dest = val;
+ return 0;
+}
+
+int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ void *data, int len)
+{
+ struct mt76_phy *phy = hw->priv;
+ struct mt76_dev *dev = phy->dev;
+ struct mt76_testmode_data *td = &dev->test;
+ struct nlattr *tb[NUM_MT76_TM_ATTRS];
+ u32 state;
+ int err;
+ int i;
+
+ if (!dev->test_ops)
+ return -EOPNOTSUPP;
+
+ err = nla_parse_deprecated(tb, MT76_TM_ATTR_MAX, data, len,
+ mt76_tm_policy, NULL);
+ if (err)
+ return err;
+
+ err = -EINVAL;
+
+ mutex_lock(&dev->mutex);
+
+ if (tb[MT76_TM_ATTR_RESET]) {
+ mt76_testmode_set_state(dev, MT76_TM_STATE_OFF);
+ memset(td, 0, sizeof(*td));
+ }
+
+ mt76_testmode_init_defaults(dev);
+
+ if (tb[MT76_TM_ATTR_TX_COUNT])
+ td->tx_count = nla_get_u32(tb[MT76_TM_ATTR_TX_COUNT]);
+
+ if (tb[MT76_TM_ATTR_TX_LENGTH]) {
+ u32 val = nla_get_u32(tb[MT76_TM_ATTR_TX_LENGTH]);
+
+ if (val > IEEE80211_MAX_FRAME_LEN ||
+ val < sizeof(struct ieee80211_hdr))
+ goto out;
+
+ td->tx_msdu_len = val;
+ }
+
+ if (tb[MT76_TM_ATTR_TX_RATE_IDX])
+ td->tx_rate_idx = nla_get_u8(tb[MT76_TM_ATTR_TX_RATE_IDX]);
+
+ if (mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_MODE], &td->tx_rate_mode,
+ 0, MT76_TM_TX_MODE_MAX) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_NSS], &td->tx_rate_nss,
+ 1, hweight8(phy->antenna_mask)) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_SGI], &td->tx_rate_sgi, 0, 1) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_LDPC], &td->tx_rate_ldpc, 0, 1) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA], &td->tx_antenna_mask, 1,
+ phy->antenna_mask) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
+ &td->tx_power_control, 0, 1))
+ goto out;
+
+ if (tb[MT76_TM_ATTR_FREQ_OFFSET])
+ td->freq_offset = nla_get_u32(tb[MT76_TM_ATTR_FREQ_OFFSET]);
+
+ if (tb[MT76_TM_ATTR_STATE]) {
+ state = nla_get_u32(tb[MT76_TM_ATTR_STATE]);
+ if (state > MT76_TM_STATE_MAX)
+ goto out;
+ } else {
+ state = td->state;
+ }
+
+ if (tb[MT76_TM_ATTR_TX_POWER]) {
+ struct nlattr *cur;
+ int idx = 0;
+ int rem;
+
+ nla_for_each_nested(cur, tb[MT76_TM_ATTR_TX_POWER], rem) {
+ if (nla_len(cur) != 1 ||
+ idx >= ARRAY_SIZE(td->tx_power))
+ goto out;
+
+ td->tx_power[idx++] = nla_get_u8(cur);
+ }
+ }
+
+ if (dev->test_ops->set_params) {
+ err = dev->test_ops->set_params(dev, tb, state);
+ if (err)
+ goto out;
+ }
+
+ for (i = MT76_TM_ATTR_STATE; i < ARRAY_SIZE(tb); i++)
+ if (tb[i])
+ mt76_testmode_param_set(td, i);
+
+ err = 0;
+ if (tb[MT76_TM_ATTR_STATE])
+ err = mt76_testmode_set_state(dev, state);
+
+out:
+ mutex_unlock(&dev->mutex);
+
+ return err;
+}
+EXPORT_SYMBOL(mt76_testmode_cmd);
+
+static int
+mt76_testmode_dump_stats(struct mt76_dev *dev, struct sk_buff *msg)
+{
+ struct mt76_testmode_data *td = &dev->test;
+ u64 rx_packets = 0;
+ u64 rx_fcs_error = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(td->rx_stats.packets); i++) {
+ rx_packets += td->rx_stats.packets[i];
+ rx_fcs_error += td->rx_stats.fcs_error[i];
+ }
+
+ if (nla_put_u32(msg, MT76_TM_STATS_ATTR_TX_PENDING, td->tx_pending) ||
+ nla_put_u32(msg, MT76_TM_STATS_ATTR_TX_QUEUED, td->tx_queued) ||
+ nla_put_u32(msg, MT76_TM_STATS_ATTR_TX_DONE, td->tx_done) ||
+ nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_PACKETS, rx_packets,
+ MT76_TM_STATS_ATTR_PAD) ||
+ nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_FCS_ERROR, rx_fcs_error,
+ MT76_TM_STATS_ATTR_PAD))
+ return -EMSGSIZE;
+
+ if (dev->test_ops->dump_stats)
+ return dev->test_ops->dump_stats(dev, msg);
+
+ return 0;
+}
+
+int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+ struct netlink_callback *cb, void *data, int len)
+{
+ struct mt76_phy *phy = hw->priv;
+ struct mt76_dev *dev = phy->dev;
+ struct mt76_testmode_data *td = &dev->test;
+ struct nlattr *tb[NUM_MT76_TM_ATTRS] = {};
+ int err = 0;
+ void *a;
+ int i;
+
+ if (!dev->test_ops)
+ return -EOPNOTSUPP;
+
+ if (cb->args[2]++ > 0)
+ return -ENOENT;
+
+ if (data) {
+ err = nla_parse_deprecated(tb, MT76_TM_ATTR_MAX, data, len,
+ mt76_tm_policy, NULL);
+ if (err)
+ return err;
+ }
+
+ mutex_lock(&dev->mutex);
+
+ if (tb[MT76_TM_ATTR_STATS]) {
+ a = nla_nest_start(msg, MT76_TM_ATTR_STATS);
+ err = mt76_testmode_dump_stats(dev, msg);
+ nla_nest_end(msg, a);
+
+ goto out;
+ }
+
+ mt76_testmode_init_defaults(dev);
+
+ err = -EMSGSIZE;
+ if (nla_put_u32(msg, MT76_TM_ATTR_STATE, td->state))
+ goto out;
+
+ if (td->mtd_name &&
+ (nla_put_string(msg, MT76_TM_ATTR_MTD_PART, td->mtd_name) ||
+ nla_put_u32(msg, MT76_TM_ATTR_MTD_OFFSET, td->mtd_offset)))
+ goto out;
+
+ if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
+ nla_put_u32(msg, MT76_TM_ATTR_TX_LENGTH, td->tx_msdu_len) ||
+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_MODE, td->tx_rate_mode) ||
+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_NSS, td->tx_rate_nss) ||
+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_IDX, td->tx_rate_idx) ||
+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_SGI, td->tx_rate_sgi) ||
+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_LDPC, td->tx_rate_ldpc) ||
+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
+ nla_put_u8(msg, MT76_TM_ATTR_TX_ANTENNA, td->tx_antenna_mask)) ||
+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER_CONTROL) &&
+ nla_put_u8(msg, MT76_TM_ATTR_TX_POWER_CONTROL, td->tx_power_control)) ||
+ (mt76_testmode_param_present(td, MT76_TM_ATTR_FREQ_OFFSET) &&
+ nla_put_u8(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset)))
+ goto out;
+
+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER)) {
+ a = nla_nest_start(msg, MT76_TM_ATTR_TX_POWER);
+ if (!a)
+ goto out;
+
+ for (i = 0; i < ARRAY_SIZE(td->tx_power); i++)
+ if (nla_put_u8(msg, i, td->tx_power[i]))
+ goto out;
+
+ nla_nest_end(msg, a);
+ }
+
+ err = 0;
+
+out:
+ mutex_unlock(&dev->mutex);
+
+ return err;
+}
+EXPORT_SYMBOL(mt76_testmode_dump);
diff --git a/drivers/net/wireless/mediatek/mt76/testmode.h b/drivers/net/wireless/mediatek/mt76/testmode.h
new file mode 100644
index 000000000000..691fe5773244
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/testmode.h
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: ISC */
+/*
+ * Copyright (C) 2020 Felix Fietkau <nbd@nbd.name>
+ */
+#ifndef __MT76_TESTMODE_H
+#define __MT76_TESTMODE_H
+
+/**
+ * enum mt76_testmode_attr - testmode attributes inside NL80211_ATTR_TESTDATA
+ *
+ * @MT76_TM_ATTR_UNSPEC: (invalid attribute)
+ *
+ * @MT76_TM_ATTR_RESET: reset parameters to default (flag)
+ * @MT76_TM_ATTR_STATE: test state (u32), see &enum mt76_testmode_state
+ *
+ * @MT76_TM_ATTR_MTD_PART: mtd partition used for eeprom data (string)
+ * @MT76_TM_ATTR_MTD_OFFSET: offset of eeprom data within the partition (u32)
+ *
+ * @MT76_TM_ATTR_TX_COUNT: configured number of frames to send when setting
+ * state to MT76_TM_STATE_TX_FRAMES (u32)
+ * @MT76_TM_ATTR_TX_PENDING: pending frames during MT76_TM_STATE_TX_FRAMES (u32)
+ * @MT76_TM_ATTR_TX_LENGTH: packet tx msdu length (u32)
+ * @MT76_TM_ATTR_TX_RATE_MODE: packet tx mode (u8, see &enum mt76_testmode_tx_mode)
+ * @MT76_TM_ATTR_TX_RATE_NSS: packet tx number of spatial streams (u8)
+ * @MT76_TM_ATTR_TX_RATE_IDX: packet tx rate/MCS index (u8)
+ * @MT76_TM_ATTR_TX_RATE_SGI: packet tx use short guard interval (u8)
+ * @MT76_TM_ATTR_TX_RATE_LDPC: packet tx enable LDPC (u8)
+ *
+ * @MT76_TM_ATTR_TX_ANTENNA: tx antenna mask (u8)
+ * @MT76_TM_ATTR_TX_POWER_CONTROL: enable tx power control (u8)
+ * @MT76_TM_ATTR_TX_POWER: per-antenna tx power array (nested, u8 attrs)
+ *
+ * @MT76_TM_ATTR_FREQ_OFFSET: RF frequency offset (u32)
+ *
+ * @MT76_TM_ATTR_STATS: statistics (nested, see &enum mt76_testmode_stats_attr)
+ */
+enum mt76_testmode_attr {
+ MT76_TM_ATTR_UNSPEC,
+
+ MT76_TM_ATTR_RESET,
+ MT76_TM_ATTR_STATE,
+
+ MT76_TM_ATTR_MTD_PART,
+ MT76_TM_ATTR_MTD_OFFSET,
+
+ MT76_TM_ATTR_TX_COUNT,
+ MT76_TM_ATTR_TX_LENGTH,
+ MT76_TM_ATTR_TX_RATE_MODE,
+ MT76_TM_ATTR_TX_RATE_NSS,
+ MT76_TM_ATTR_TX_RATE_IDX,
+ MT76_TM_ATTR_TX_RATE_SGI,
+ MT76_TM_ATTR_TX_RATE_LDPC,
+
+ MT76_TM_ATTR_TX_ANTENNA,
+ MT76_TM_ATTR_TX_POWER_CONTROL,
+ MT76_TM_ATTR_TX_POWER,
+
+ MT76_TM_ATTR_FREQ_OFFSET,
+
+ MT76_TM_ATTR_STATS,
+
+ /* keep last */
+ NUM_MT76_TM_ATTRS,
+ MT76_TM_ATTR_MAX = NUM_MT76_TM_ATTRS - 1,
+};
+
+/**
+ * enum mt76_testmode_state - statistics attributes
+ *
+ * @MT76_TM_STATS_ATTR_TX_PENDING: pending tx frames (u32)
+ * @MT76_TM_STATS_ATTR_TX_QUEUED: queued tx frames (u32)
+ * @MT76_TM_STATS_ATTR_TX_QUEUED: completed tx frames (u32)
+ *
+ * @MT76_TM_STATS_ATTR_RX_PACKETS: number of rx packets (u64)
+ * @MT76_TM_STATS_ATTR_RX_FCS_ERROR: number of rx packets with FCS error (u64)
+ * @MT76_TM_STATS_ATTR_LAST_RX: information about the last received packet
+ * see &enum mt76_testmode_rx_attr
+ */
+enum mt76_testmode_stats_attr {
+ MT76_TM_STATS_ATTR_UNSPEC,
+ MT76_TM_STATS_ATTR_PAD,
+
+ MT76_TM_STATS_ATTR_TX_PENDING,
+ MT76_TM_STATS_ATTR_TX_QUEUED,
+ MT76_TM_STATS_ATTR_TX_DONE,
+
+ MT76_TM_STATS_ATTR_RX_PACKETS,
+ MT76_TM_STATS_ATTR_RX_FCS_ERROR,
+ MT76_TM_STATS_ATTR_LAST_RX,
+
+ /* keep last */
+ NUM_MT76_TM_STATS_ATTRS,
+ MT76_TM_STATS_ATTR_MAX = NUM_MT76_TM_STATS_ATTRS - 1,
+};
+
+
+/**
+ * enum mt76_testmode_rx_attr - packet rx information
+ *
+ * @MT76_TM_RX_ATTR_FREQ_OFFSET: frequency offset (s32)
+ * @MT76_TM_RX_ATTR_RCPI: received channel power indicator (array, u8)
+ * @MT76_TM_RX_ATTR_IB_RSSI: internal inband RSSI (s8)
+ * @MT76_TM_RX_ATTR_WB_RSSI: internal wideband RSSI (s8)
+ */
+enum mt76_testmode_rx_attr {
+ MT76_TM_RX_ATTR_UNSPEC,
+
+ MT76_TM_RX_ATTR_FREQ_OFFSET,
+ MT76_TM_RX_ATTR_RCPI,
+ MT76_TM_RX_ATTR_IB_RSSI,
+ MT76_TM_RX_ATTR_WB_RSSI,
+
+ /* keep last */
+ NUM_MT76_TM_RX_ATTRS,
+ MT76_TM_RX_ATTR_MAX = NUM_MT76_TM_RX_ATTRS - 1,
+};
+
+/**
+ * enum mt76_testmode_state - phy test state
+ *
+ * @MT76_TM_STATE_OFF: test mode disabled (normal operation)
+ * @MT76_TM_STATE_IDLE: test mode enabled, but idle
+ * @MT76_TM_STATE_TX_FRAMES: send a fixed number of test frames
+ * @MT76_TM_STATE_RX_FRAMES: receive packets and keep statistics
+ */
+enum mt76_testmode_state {
+ MT76_TM_STATE_OFF,
+ MT76_TM_STATE_IDLE,
+ MT76_TM_STATE_TX_FRAMES,
+ MT76_TM_STATE_RX_FRAMES,
+
+ /* keep last */
+ NUM_MT76_TM_STATES,
+ MT76_TM_STATE_MAX = NUM_MT76_TM_STATES - 1,
+};
+
+/**
+ * enum mt76_testmode_tx_mode - packet tx phy mode
+ *
+ * @MT76_TM_TX_MODE_CCK: legacy CCK mode
+ * @MT76_TM_TX_MODE_OFDM: legacy OFDM mode
+ * @MT76_TM_TX_MODE_HT: 802.11n MCS
+ * @MT76_TM_TX_MODE_VHT: 802.11ac MCS
+ */
+enum mt76_testmode_tx_mode {
+ MT76_TM_TX_MODE_CCK,
+ MT76_TM_TX_MODE_OFDM,
+ MT76_TM_TX_MODE_HT,
+ MT76_TM_TX_MODE_VHT,
+
+ /* keep last */
+ NUM_MT76_TM_TX_MODES,
+ MT76_TM_TX_MODE_MAX = NUM_MT76_TM_TX_MODES - 1,
+};
+
+#endif
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index f10c98aa883c..3afd89ecd6c9 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -236,6 +236,14 @@ void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb)
struct ieee80211_hw *hw;
struct sk_buff_head list;
+#ifdef CONFIG_NL80211_TESTMODE
+ if (skb == dev->test.tx_skb) {
+ dev->test.tx_done++;
+ if (dev->test.tx_queued == dev->test.tx_done)
+ wake_up(&dev->tx_wait);
+ }
+#endif
+
if (!skb->prev) {
hw = mt76_tx_status_get_hw(dev, skb);
ieee80211_free_txskb(hw, skb);
@@ -259,6 +267,11 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
int qid = skb_get_queue_mapping(skb);
bool ext_phy = phy != &dev->phy;
+ if (mt76_testmode_enabled(dev)) {
+ ieee80211_free_txskb(phy->hw, skb);
+ return;
+ }
+
if (WARN_ON(qid >= MT_TXQ_PSD)) {
qid = MT_TXQ_BE;
skb_set_queue_mapping(skb, qid);
@@ -579,6 +592,11 @@ void mt76_tx_tasklet(unsigned long data)
mt76_txq_schedule_all(&dev->phy);
if (dev->phy2)
mt76_txq_schedule_all(dev->phy2);
+
+#ifdef CONFIG_NL80211_TESTMODE
+ if (dev->test.tx_pending)
+ mt76_testmode_tx_pending(dev);
+#endif
}
void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,
@@ -659,3 +677,32 @@ u8 mt76_ac_to_hwq(u8 ac)
return wmm_queue_map[ac];
}
EXPORT_SYMBOL_GPL(mt76_ac_to_hwq);
+
+int mt76_skb_adjust_pad(struct sk_buff *skb)
+{
+ struct sk_buff *iter, *last = skb;
+ u32 pad;
+
+ /* Add zero pad of 4 - 7 bytes */
+ pad = round_up(skb->len, 4) + 4 - skb->len;
+
+ /* First packet of a A-MSDU burst keeps track of the whole burst
+ * length, need to update length of it and the last packet.
+ */
+ skb_walk_frags(skb, iter) {
+ last = iter;
+ if (!iter->next) {
+ skb->data_len += pad;
+ skb->len += pad;
+ break;
+ }
+ }
+
+ if (skb_pad(last, pad))
+ return -ENOMEM;
+
+ __skb_put(last, pad);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mt76_skb_adjust_pad);
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 87382b2f7443..dcab5993763a 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -672,17 +672,11 @@ mt76u_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
static void mt76u_rx_tasklet(unsigned long data)
{
struct mt76_dev *dev = (struct mt76_dev *)data;
- struct mt76_queue *q;
int i;
rcu_read_lock();
- for (i = 0; i < __MT_RXQ_MAX; i++) {
- q = &dev->q_rx[i];
- if (!q->ndesc)
- continue;
-
- mt76u_process_rx_queue(dev, q);
- }
+ mt76_for_each_q_rx(dev, i)
+ mt76u_process_rx_queue(dev, &dev->q_rx[i]);
rcu_read_unlock();
}
@@ -756,27 +750,19 @@ mt76u_free_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
static void mt76u_free_rx(struct mt76_dev *dev)
{
- struct mt76_queue *q;
int i;
- for (i = 0; i < __MT_RXQ_MAX; i++) {
- q = &dev->q_rx[i];
- if (!q->ndesc)
- continue;
-
- mt76u_free_rx_queue(dev, q);
- }
+ mt76_for_each_q_rx(dev, i)
+ mt76u_free_rx_queue(dev, &dev->q_rx[i]);
}
void mt76u_stop_rx(struct mt76_dev *dev)
{
- struct mt76_queue *q;
- int i, j;
+ int i;
- for (i = 0; i < __MT_RXQ_MAX; i++) {
- q = &dev->q_rx[i];
- if (!q->ndesc)
- continue;
+ mt76_for_each_q_rx(dev, i) {
+ struct mt76_queue *q = &dev->q_rx[i];
+ int j;
for (j = 0; j < q->ndesc; j++)
usb_poison_urb(q->entry[j].urb);
@@ -788,14 +774,11 @@ EXPORT_SYMBOL_GPL(mt76u_stop_rx);
int mt76u_resume_rx(struct mt76_dev *dev)
{
- struct mt76_queue *q;
- int i, j, err;
-
- for (i = 0; i < __MT_RXQ_MAX; i++) {
- q = &dev->q_rx[i];
+ int i;
- if (!q->ndesc)
- continue;
+ mt76_for_each_q_rx(dev, i) {
+ struct mt76_queue *q = &dev->q_rx[i];
+ int err, j;
for (j = 0; j < q->ndesc; j++)
usb_unpoison_urb(q->entry[j].urb);
@@ -859,7 +842,7 @@ static void mt76u_tx_tasklet(unsigned long data)
if (dev->drv->tx_status_data &&
!test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
- queue_work(dev->usb.wq, &dev->usb.stat_work);
+ queue_work(dev->wq, &dev->usb.stat_work);
if (wake)
ieee80211_wake_queue(dev->hw, i);
}
@@ -885,7 +868,7 @@ static void mt76u_tx_status_data(struct work_struct *work)
}
if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state))
- queue_work(usb->wq, &usb->stat_work);
+ queue_work(dev->wq, &usb->stat_work);
else
clear_bit(MT76_READING_STATS, &dev->phy.state);
}
@@ -921,35 +904,6 @@ mt76u_tx_setup_buffers(struct mt76_dev *dev, struct sk_buff *skb,
return urb->num_sgs;
}
-int mt76u_skb_dma_info(struct sk_buff *skb, u32 info)
-{
- struct sk_buff *iter, *last = skb;
- u32 pad;
-
- put_unaligned_le32(info, skb_push(skb, sizeof(info)));
- /* Add zero pad of 4 - 7 bytes */
- pad = round_up(skb->len, 4) + 4 - skb->len;
-
- /* First packet of a A-MSDU burst keeps track of the whole burst
- * length, need to update length of it and the last packet.
- */
- skb_walk_frags(skb, iter) {
- last = iter;
- if (!iter->next) {
- skb->data_len += pad;
- skb->len += pad;
- break;
- }
- }
-
- if (skb_pad(last, pad))
- return -ENOMEM;
- __skb_put(last, pad);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(mt76u_skb_dma_info);
-
static int
mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
struct sk_buff *skb, struct mt76_wcid *wcid,
@@ -1161,15 +1115,6 @@ static const struct mt76_queue_ops usb_queue_ops = {
.kick = mt76u_tx_kick,
};
-void mt76u_deinit(struct mt76_dev *dev)
-{
- if (dev->usb.wq) {
- destroy_workqueue(dev->usb.wq);
- dev->usb.wq = NULL;
- }
-}
-EXPORT_SYMBOL_GPL(mt76u_deinit);
-
int mt76u_init(struct mt76_dev *dev,
struct usb_interface *intf, bool ext)
{
@@ -1192,10 +1137,6 @@ int mt76u_init(struct mt76_dev *dev,
tasklet_init(&dev->tx_tasklet, mt76u_tx_tasklet, (unsigned long)dev);
INIT_WORK(&usb->stat_work, mt76u_tx_status_data);
- usb->wq = alloc_workqueue("mt76u", WQ_UNBOUND, 0);
- if (!usb->wq)
- return -ENOMEM;
-
usb->data_len = usb_maxpacket(udev, usb_sndctrlpipe(udev, 0), 1);
if (usb->data_len < 32)
usb->data_len = 32;
@@ -1219,7 +1160,8 @@ int mt76u_init(struct mt76_dev *dev,
return 0;
error:
- mt76u_deinit(dev);
+ destroy_workqueue(dev->wq);
+
return err;
}
EXPORT_SYMBOL_GPL(mt76u_init);
diff --git a/drivers/net/wireless/mediatek/mt76/util.c b/drivers/net/wireless/mediatek/mt76/util.c
index ecde87465bf6..f53bb4ae5001 100644
--- a/drivers/net/wireless/mediatek/mt76/util.c
+++ b/drivers/net/wireless/mediatek/mt76/util.c
@@ -13,7 +13,7 @@ bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
timeout /= 10;
do {
- cur = dev->bus->rr(dev, offset) & mask;
+ cur = __mt76_rr(dev, offset) & mask;
if (cur == val)
return true;
@@ -31,7 +31,7 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
timeout /= 10;
do {
- cur = dev->bus->rr(dev, offset) & mask;
+ cur = __mt76_rr(dev, offset) & mask;
if (cur == val)
return true;
diff --git a/drivers/net/wireless/mediatek/mt7601u/mcu.c b/drivers/net/wireless/mediatek/mt7601u/mcu.c
index af55ed82b96f..1b5cc271a9e1 100644
--- a/drivers/net/wireless/mediatek/mt7601u/mcu.c
+++ b/drivers/net/wireless/mediatek/mt7601u/mcu.c
@@ -116,8 +116,10 @@ mt7601u_mcu_msg_send(struct mt7601u_dev *dev, struct sk_buff *skb,
int sent, ret;
u8 seq = 0;
- if (test_bit(MT7601U_STATE_REMOVED, &dev->state))
+ if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) {
+ consume_skb(skb);
return 0;
+ }
mutex_lock(&dev->mcu.mutex);
diff --git a/drivers/net/wireless/microchip/Kconfig b/drivers/net/wireless/microchip/Kconfig
new file mode 100644
index 000000000000..a6b46fb6b1ec
--- /dev/null
+++ b/drivers/net/wireless/microchip/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+config WLAN_VENDOR_MICROCHIP
+ bool "Microchip devices"
+ default y
+ help
+ If you have a wireless card belonging to this class, say Y.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all the
+ questions about these cards. If you say Y, you will be asked for
+ your specific card in the following questions.
+
+if WLAN_VENDOR_MICROCHIP
+source "drivers/net/wireless/microchip/wilc1000/Kconfig"
+endif # WLAN_VENDOR_MICROCHIP
diff --git a/drivers/net/wireless/microchip/Makefile b/drivers/net/wireless/microchip/Makefile
new file mode 100644
index 000000000000..73b763c7393e
--- /dev/null
+++ b/drivers/net/wireless/microchip/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_WILC1000) += wilc1000/
diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/net/wireless/microchip/wilc1000/Kconfig
index 80c92e8bf8a5..80c92e8bf8a5 100644
--- a/drivers/staging/wilc1000/Kconfig
+++ b/drivers/net/wireless/microchip/wilc1000/Kconfig
diff --git a/drivers/staging/wilc1000/Makefile b/drivers/net/wireless/microchip/wilc1000/Makefile
index a3305a0a888a..c3c9e34c1eaa 100644
--- a/drivers/staging/wilc1000/Makefile
+++ b/drivers/net/wireless/microchip/wilc1000/Makefile
@@ -1,9 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_WILC1000) += wilc1000.o
-ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
- -DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\"
-
wilc1000-objs := cfg80211.o netdev.o mon.o \
hif.o wlan_cfg.o wlan.o
diff --git a/drivers/staging/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
index b6065a0d660f..c1ac1d84790f 100644
--- a/drivers/staging/wilc1000/cfg80211.c
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
@@ -46,9 +46,11 @@ static const struct ieee80211_txrx_stypes
}
};
+#ifdef CONFIG_PM
static const struct wiphy_wowlan_support wowlan_support = {
.flags = WIPHY_WOWLAN_ANY
};
+#endif
struct wilc_p2p_mgmt_data {
int size;
diff --git a/drivers/staging/wilc1000/cfg80211.h b/drivers/net/wireless/microchip/wilc1000/cfg80211.h
index 37b294cb3b37..37b294cb3b37 100644
--- a/drivers/staging/wilc1000/cfg80211.h
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.h
diff --git a/drivers/staging/wilc1000/fw.h b/drivers/net/wireless/microchip/wilc1000/fw.h
index a76e1dea4345..a76e1dea4345 100644
--- a/drivers/staging/wilc1000/fw.h
+++ b/drivers/net/wireless/microchip/wilc1000/fw.h
diff --git a/drivers/staging/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
index d025a3093015..d025a3093015 100644
--- a/drivers/staging/wilc1000/hif.c
+++ b/drivers/net/wireless/microchip/wilc1000/hif.c
diff --git a/drivers/staging/wilc1000/hif.h b/drivers/net/wireless/microchip/wilc1000/hif.h
index db9179171f05..db9179171f05 100644
--- a/drivers/staging/wilc1000/hif.h
+++ b/drivers/net/wireless/microchip/wilc1000/hif.h
diff --git a/drivers/staging/wilc1000/mon.c b/drivers/net/wireless/microchip/wilc1000/mon.c
index 60331417bd98..358ac8601333 100644
--- a/drivers/staging/wilc1000/mon.c
+++ b/drivers/net/wireless/microchip/wilc1000/mon.c
@@ -229,8 +229,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
return NULL;
wl->monitor_dev->type = ARPHRD_IEEE80211_RADIOTAP;
- strncpy(wl->monitor_dev->name, name, IFNAMSIZ);
- wl->monitor_dev->name[IFNAMSIZ - 1] = 0;
+ strlcpy(wl->monitor_dev->name, name, IFNAMSIZ);
wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops;
wl->monitor_dev->needs_free_netdev = true;
diff --git a/drivers/staging/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
index fda0ab97b02c..20615c7ec168 100644
--- a/drivers/staging/wilc1000/netdev.c
+++ b/drivers/net/wireless/microchip/wilc1000/netdev.c
@@ -15,6 +15,13 @@
#define WILC_MULTICAST_TABLE_SIZE 8
+/* latest API version supported */
+#define WILC1000_API_VER 1
+
+#define WILC1000_FW_PREFIX "atmel/wilc1000_wifi_firmware-"
+#define __WILC1000_FW(api) WILC1000_FW_PREFIX #api ".bin"
+#define WILC1000_FW(api) __WILC1000_FW(api)
+
static irqreturn_t isr_uh_routine(int irq, void *user_data)
{
struct net_device *dev = user_data;
@@ -176,23 +183,22 @@ static int wilc_wlan_get_firmware(struct net_device *dev)
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc = vif->wilc;
int chip_id;
- const struct firmware *wilc_firmware;
- char *firmware;
+ const struct firmware *wilc_fw;
+ int ret;
chip_id = wilc_get_chipid(wilc, false);
- if (chip_id < 0x1003a0)
- firmware = FIRMWARE_1002;
- else
- firmware = FIRMWARE_1003;
-
- netdev_info(dev, "loading firmware %s\n", firmware);
+ netdev_info(dev, "ChipID [%x] loading firmware [%s]\n", chip_id,
+ WILC1000_FW(WILC1000_API_VER));
- if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
- netdev_err(dev, "%s - firmware not available\n", firmware);
+ ret = request_firmware(&wilc_fw, WILC1000_FW(WILC1000_API_VER),
+ wilc->dev);
+ if (ret != 0) {
+ netdev_err(dev, "%s - firmware not available\n",
+ WILC1000_FW(WILC1000_API_VER));
return -EINVAL;
}
- wilc->firmware = wilc_firmware;
+ wilc->firmware = wilc_fw;
return 0;
}
@@ -678,14 +684,14 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
if (skb->dev != ndev) {
netdev_err(ndev, "Packet not destined to this device\n");
- return 0;
+ return NETDEV_TX_OK;
}
tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
if (!tx_data) {
dev_kfree_skb(skb);
netif_wake_queue(ndev);
- return 0;
+ return NETDEV_TX_OK;
}
tx_data->buff = skb->data;
@@ -710,7 +716,7 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
srcu_read_unlock(&wilc->srcu, srcu_idx);
}
- return 0;
+ return NETDEV_TX_OK;
}
static int wilc_mac_close(struct net_device *ndev)
@@ -929,3 +935,4 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
}
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(WILC1000_FW(WILC1000_API_VER));
diff --git a/drivers/staging/wilc1000/netdev.h b/drivers/net/wireless/microchip/wilc1000/netdev.h
index d0a006b68d08..d0a006b68d08 100644
--- a/drivers/staging/wilc1000/netdev.h
+++ b/drivers/net/wireless/microchip/wilc1000/netdev.h
diff --git a/drivers/staging/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c
index 36eb589263bf..3ece7b0b0392 100644
--- a/drivers/staging/wilc1000/sdio.c
+++ b/drivers/net/wireless/microchip/wilc1000/sdio.c
@@ -6,6 +6,7 @@
#include <linux/clk.h>
#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdio.h>
#include <linux/of_irq.h>
@@ -15,11 +16,8 @@
#define SDIO_MODALIAS "wilc1000_sdio"
-#define SDIO_VENDOR_ID_WILC 0x0296
-#define SDIO_DEVICE_ID_WILC 0x5347
-
static const struct sdio_device_id wilc_sdio_ids[] = {
- { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MICROCHIP_WILC, SDIO_DEVICE_ID_MICROCHIP_WILC1000) },
{ },
};
diff --git a/drivers/staging/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c
index 3f19e3f38a39..3f19e3f38a39 100644
--- a/drivers/staging/wilc1000/spi.c
+++ b/drivers/net/wireless/microchip/wilc1000/spi.c
diff --git a/drivers/staging/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c
index 6a82fb2f283e..6a82fb2f283e 100644
--- a/drivers/staging/wilc1000/wlan.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
diff --git a/drivers/staging/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h
index 7689569cd82f..7689569cd82f 100644
--- a/drivers/staging/wilc1000/wlan.h
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.h
diff --git a/drivers/staging/wilc1000/wlan_cfg.c b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c
index fe2a7ed8e5cd..fe2a7ed8e5cd 100644
--- a/drivers/staging/wilc1000/wlan_cfg.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c
diff --git a/drivers/staging/wilc1000/wlan_cfg.h b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h
index 614c5673f232..614c5673f232 100644
--- a/drivers/staging/wilc1000/wlan_cfg.h
+++ b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h
diff --git a/drivers/staging/wilc1000/wlan_if.h b/drivers/net/wireless/microchip/wilc1000/wlan_if.h
index f85fd575136d..f85fd575136d 100644
--- a/drivers/staging/wilc1000/wlan_if.h
+++ b/drivers/net/wireless/microchip/wilc1000/wlan_if.h
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c
index eea777f8acea..6aafff9d4231 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
@@ -446,8 +446,11 @@ static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
}
wiphy = qtnf_wiphy_allocate(bus, pdev);
- if (!wiphy)
+ if (!wiphy) {
+ if (pdev)
+ platform_device_unregister(pdev);
return ERR_PTR(-ENOMEM);
+ }
mac = wiphy_priv(wiphy);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
index 4d44509e2ce3..c1ac933349d1 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
@@ -1834,8 +1834,7 @@ static struct pci_driver rt2400pci_driver = {
.id_table = rt2400pci_device_table,
.probe = rt2400pci_probe,
.remove = rt2x00pci_remove,
- .suspend = rt2x00pci_suspend,
- .resume = rt2x00pci_resume,
+ .driver.pm = &rt2x00pci_pm_ops,
};
module_pci_driver(rt2400pci_driver);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
index 4620990a94cf..0859adebd860 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
@@ -2132,8 +2132,7 @@ static struct pci_driver rt2500pci_driver = {
.id_table = rt2500pci_device_table,
.probe = rt2500pci_probe,
.remove = rt2x00pci_remove,
- .suspend = rt2x00pci_suspend,
- .resume = rt2x00pci_resume,
+ .driver.pm = &rt2x00pci_pm_ops,
};
module_pci_driver(rt2500pci_driver);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
index 3868c07672bd..9a33baaa6184 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
@@ -455,8 +455,7 @@ static struct pci_driver rt2800pci_driver = {
.id_table = rt2800pci_device_table,
.probe = rt2800pci_probe,
.remove = rt2x00pci_remove,
- .suspend = rt2x00pci_suspend,
- .resume = rt2x00pci_resume,
+ .driver.pm = &rt2x00pci_pm_ops,
};
module_pci_driver(rt2800pci_driver);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
index ea8a34ecae14..ecc60d8cbb01 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -1487,9 +1487,8 @@ bool rt2x00mac_tx_frames_pending(struct ieee80211_hw *hw);
*/
int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev);
-#ifdef CONFIG_PM
-int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state);
+
+int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev);
int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev);
-#endif /* CONFIG_PM */
#endif /* RT2X00_H */
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
index 7f9e43a4f805..8c6d3099b19d 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1556,8 +1556,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
/*
* Device state handlers
*/
-#ifdef CONFIG_PM
-int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
+int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev)
{
rt2x00_dbg(rt2x00dev, "Going to sleep\n");
@@ -1614,7 +1613,6 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
return 0;
}
EXPORT_SYMBOL_GPL(rt2x00lib_resume);
-#endif /* CONFIG_PM */
/*
* rt2x00lib module information.
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c b/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
index 7f9baa94c7c8..cabeef0dde45 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
@@ -169,39 +169,24 @@ void rt2x00pci_remove(struct pci_dev *pci_dev)
}
EXPORT_SYMBOL_GPL(rt2x00pci_remove);
-#ifdef CONFIG_PM
-int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state)
+static int __maybe_unused rt2x00pci_suspend(struct device *dev)
{
- struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
+ struct ieee80211_hw *hw = dev_get_drvdata(dev);
struct rt2x00_dev *rt2x00dev = hw->priv;
- int retval;
-
- retval = rt2x00lib_suspend(rt2x00dev, state);
- if (retval)
- return retval;
- pci_save_state(pci_dev);
- pci_disable_device(pci_dev);
- return pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+ return rt2x00lib_suspend(rt2x00dev);
}
-EXPORT_SYMBOL_GPL(rt2x00pci_suspend);
-int rt2x00pci_resume(struct pci_dev *pci_dev)
+static int __maybe_unused rt2x00pci_resume(struct device *dev)
{
- struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
+ struct ieee80211_hw *hw = dev_get_drvdata(dev);
struct rt2x00_dev *rt2x00dev = hw->priv;
- if (pci_set_power_state(pci_dev, PCI_D0) ||
- pci_enable_device(pci_dev)) {
- rt2x00_err(rt2x00dev, "Failed to resume device\n");
- return -EIO;
- }
-
- pci_restore_state(pci_dev);
return rt2x00lib_resume(rt2x00dev);
}
-EXPORT_SYMBOL_GPL(rt2x00pci_resume);
-#endif /* CONFIG_PM */
+
+SIMPLE_DEV_PM_OPS(rt2x00pci_pm_ops, rt2x00pci_suspend, rt2x00pci_resume);
+EXPORT_SYMBOL_GPL(rt2x00pci_pm_ops);
/*
* rt2x00pci module information.
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00pci.h b/drivers/net/wireless/ralink/rt2x00/rt2x00pci.h
index fd955ccaa1e6..27f7b2bd26ea 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00pci.h
@@ -21,12 +21,7 @@
*/
int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops);
void rt2x00pci_remove(struct pci_dev *pci_dev);
-#ifdef CONFIG_PM
-int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state);
-int rt2x00pci_resume(struct pci_dev *pci_dev);
-#else
-#define rt2x00pci_suspend NULL
-#define rt2x00pci_resume NULL
-#endif /* CONFIG_PM */
+
+extern const struct dev_pm_ops rt2x00pci_pm_ops;
#endif /* RT2X00PCI_H */
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
index 596b8a432946..eface610178d 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
@@ -130,7 +130,7 @@ int rt2x00soc_suspend(struct platform_device *pdev, pm_message_t state)
struct ieee80211_hw *hw = platform_get_drvdata(pdev);
struct rt2x00_dev *rt2x00dev = hw->priv;
- return rt2x00lib_suspend(rt2x00dev, state);
+ return rt2x00lib_suspend(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00soc_suspend);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
index 92e9e023c349..e4473a551241 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
@@ -886,7 +886,7 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state)
struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
struct rt2x00_dev *rt2x00dev = hw->priv;
- return rt2x00lib_suspend(rt2x00dev, state);
+ return rt2x00lib_suspend(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00usb_suspend);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt61pci.c b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
index d83288bef2fc..eefce76fc99b 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
@@ -3009,8 +3009,7 @@ static struct pci_driver rt61pci_driver = {
.id_table = rt61pci_device_table,
.probe = rt61pci_probe,
.remove = rt2x00pci_remove,
- .suspend = rt2x00pci_suspend,
- .resume = rt2x00pci_resume,
+ .driver.pm = &rt2x00pci_pm_ops,
};
module_pci_driver(rt61pci_driver);
diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
index d5f65372356b..ba3286f732cc 100644
--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
@@ -1966,32 +1966,17 @@ static void rtl8180_remove(struct pci_dev *pdev)
ieee80211_free_hw(dev);
}
-#ifdef CONFIG_PM
-static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- pci_save_state(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return 0;
-}
-
-static int rtl8180_resume(struct pci_dev *pdev)
-{
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- return 0;
-}
+#define rtl8180_suspend NULL
+#define rtl8180_resume NULL
-#endif /* CONFIG_PM */
+static SIMPLE_DEV_PM_OPS(rtl8180_pm_ops, rtl8180_suspend, rtl8180_resume);
static struct pci_driver rtl8180_driver = {
.name = KBUILD_MODNAME,
.id_table = rtl8180_table,
.probe = rtl8180_probe,
.remove = rtl8180_remove,
-#ifdef CONFIG_PM
- .suspend = rtl8180_suspend,
- .resume = rtl8180_resume,
-#endif /* CONFIG_PM */
+ .driver.pm = &rtl8180_pm_ops,
};
module_pci_driver(rtl8180_driver);
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index a4940a3842de..2b140c1e8e8d 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -894,11 +894,9 @@ static void halbtc_display_wifi_status(struct btc_coexist *btcoexist,
(low_power ? ", 32k" : ""));
seq_printf(m,
- "\n %-35s = %02x %02x %02x %02x %02x %02x (0x%x/0x%x)",
+ "\n %-35s = %6ph (0x%x/0x%x)",
"Power mode cmd(lps/rpwm)",
- btcoexist->pwr_mode_val[0], btcoexist->pwr_mode_val[1],
- btcoexist->pwr_mode_val[2], btcoexist->pwr_mode_val[3],
- btcoexist->pwr_mode_val[4], btcoexist->pwr_mode_val[5],
+ btcoexist->pwr_mode_val,
btcoexist->bt_info.lps_val,
btcoexist->bt_info.rpwm_val);
}
@@ -1318,7 +1316,7 @@ bool exhalbtc_bind_bt_coex_withadapter(void *adapter)
{
struct rtl_priv *rtlpriv = adapter;
struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
- u8 ant_num = 2, chip_type, single_ant_path = 0;
+ u8 ant_num, chip_type, single_ant_path;
if (!btcoexist)
return false;
diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c
index bc0ac96ee615..90f92728e16a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/ps.c
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
@@ -769,13 +769,13 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data,
*(u8 *)(ie + index);
index += 1;
p2pinfo->noa_duration[i] =
- le32_to_cpu(*(__le32 *)ie + index);
+ le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
p2pinfo->noa_interval[i] =
- le32_to_cpu(*(__le32 *)ie + index);
+ le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
p2pinfo->noa_start_time[i] =
- le32_to_cpu(*(__le32 *)ie + index);
+ le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
}
@@ -864,13 +864,13 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,
*(u8 *)(ie + index);
index += 1;
p2pinfo->noa_duration[i] =
- le32_to_cpu(*(__le32 *)ie + index);
+ le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
p2pinfo->noa_interval[i] =
- le32_to_cpu(*(__le32 *)ie + index);
+ le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
p2pinfo->noa_start_time[i] =
- le32_to_cpu(*(__le32 *)ie + index);
+ le32_to_cpu(*(__le32 *)(ie + index));
index += 4;
}
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
index dceb04a9b3f5..1ffa188a65c9 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
@@ -870,11 +870,11 @@ static void dm_txpower_track_cb_therm(struct ieee80211_hw *hw)
/*0.1 the following TWO tables decide the
*final index of OFDM/CCK swing table
*/
- s8 delta_swing_table_idx[2][15] = {
+ static const s8 delta_swing_table_idx[2][15] = {
{0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
{0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
};
- u8 thermal_threshold[2][15] = {
+ static const u8 thermal_threshold[2][15] = {
{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
};
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
index aa2e9e88be53..a5d2d6ece8db 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
@@ -497,7 +497,7 @@ void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw,
dma_addr_t mapping;
u8 bw_40 = 0;
u8 short_gi = 0;
- __le32 *pdesc = (u32 *)pdesc8;
+ __le32 *pdesc = (__le32 *)pdesc8;
if (mac->opmode == NL80211_IFTYPE_STATION) {
bw_40 = mac->bw_40;
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c
index b13fd3c0c832..c9b3d9d09c48 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c
@@ -736,11 +736,11 @@ static void rtl8723be_dm_txpower_tracking_callback_thermalmeter(
u8 ofdm_min_index = 6;
u8 index_for_channel = 0;
- s8 delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = {
+ static const s8 delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = {
0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10,
10, 11, 11, 12, 12, 13, 14, 15};
- s8 delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = {
+ static const s8 delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = {
0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9,
9, 10, 10, 11, 12, 13, 14, 15};
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c
index f57e8794f0ec..97a30ccf0b27 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c
@@ -115,47 +115,47 @@ static const u32 edca_setting_ul[PEER_MAX] = {
0x5ea44f, /* 7 MARV */
};
-static u8 rtl8818e_delta_swing_table_idx_24gb_p[] = {
+static const u8 rtl8818e_delta_swing_table_idx_24gb_p[] = {
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4,
4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9};
-static u8 rtl8818e_delta_swing_table_idx_24gb_n[] = {
+static const u8 rtl8818e_delta_swing_table_idx_24gb_n[] = {
0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11};
-static u8 rtl8812ae_delta_swing_table_idx_24gb_n[] = {
+static const u8 rtl8812ae_delta_swing_table_idx_24gb_n[] = {
0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
-static u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = {
+static const u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = {
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
-static u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = {
+static const u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = {
0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
-static u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = {
+static const u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = {
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
-static u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = {
+static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = {
0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
-static u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = {
+static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = {
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
-static u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = {
+static const u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = {
0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
-static u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = {
+static const u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = {
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
-static u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = {
+static const u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = {
{0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7,
7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13},
{0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
@@ -164,7 +164,7 @@ static u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = {
12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18},
};
-static u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = {
+static const u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = {
{0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8,
8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
@@ -173,7 +173,7 @@ static u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = {
9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
};
-static u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
+static const u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13},
{0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9,
@@ -182,7 +182,7 @@ static u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18},
};
-static u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
+static const u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8,
8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
@@ -191,57 +191,23 @@ static u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
};
-static u8 rtl8821ae_delta_swing_table_idx_24gb_n[] = {
+static const u8 rtl8821ae_delta_swing_table_idx_24ga_n[] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
-static u8 rtl8821ae_delta_swing_table_idx_24gb_p[] = {
+static const u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = {
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
-static u8 rtl8821ae_delta_swing_table_idx_24ga_n[] = {
+static const u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
-static u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = {
+static const u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = {
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
-static u8 rtl8821ae_delta_swing_table_idx_24gcckb_n[] = {
- 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
- 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
-
-static u8 rtl8821ae_delta_swing_table_idx_24gcckb_p[] = {
- 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
- 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
-
-static u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = {
- 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
- 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
-
-static u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = {
- 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
- 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
-
-static u8 rtl8821ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = {
- {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
- 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
- {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
- 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
- {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
- 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
-};
-
-static u8 rtl8821ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = {
- {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
- 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
- {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
- 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
- {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
- 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
-};
-
-static u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
+static const u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
@@ -250,7 +216,7 @@ static u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
};
-static u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
+static const u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
@@ -962,8 +928,10 @@ static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw)
}
static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw,
- u8 **up_a, u8 **down_a,
- u8 **up_b, u8 **down_b)
+ const u8 **up_a,
+ const u8 **down_a,
+ const u8 **up_b,
+ const u8 **down_b)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &rtlpriv->phy;
@@ -999,10 +967,10 @@ static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw,
*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2];
*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2];
} else {
- *up_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p;
- *down_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n;
- *up_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p;
- *down_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n;
+ *up_a = rtl8818e_delta_swing_table_idx_24gb_p;
+ *down_a = rtl8818e_delta_swing_table_idx_24gb_n;
+ *up_b = rtl8818e_delta_swing_table_idx_24gb_p;
+ *down_b = rtl8818e_delta_swing_table_idx_24gb_n;
}
}
@@ -1492,17 +1460,17 @@ void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(
/* 1. The following TWO tables decide
* the final index of OFDM/CCK swing table.
*/
- u8 *delta_swing_table_idx_tup_a;
- u8 *delta_swing_table_idx_tdown_a;
- u8 *delta_swing_table_idx_tup_b;
- u8 *delta_swing_table_idx_tdown_b;
+ const u8 *delta_swing_table_idx_tup_a;
+ const u8 *delta_swing_table_idx_tdown_a;
+ const u8 *delta_swing_table_idx_tup_b;
+ const u8 *delta_swing_table_idx_tdown_b;
/*2. Initilization ( 7 steps in total )*/
rtl8812ae_get_delta_swing_table(hw,
- (u8 **)&delta_swing_table_idx_tup_a,
- (u8 **)&delta_swing_table_idx_tdown_a,
- (u8 **)&delta_swing_table_idx_tup_b,
- (u8 **)&delta_swing_table_idx_tdown_b);
+ &delta_swing_table_idx_tup_a,
+ &delta_swing_table_idx_tdown_a,
+ &delta_swing_table_idx_tup_b,
+ &delta_swing_table_idx_tdown_b);
rtldm->txpower_trackinginit = true;
@@ -1830,8 +1798,9 @@ void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(
"<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n");
}
-static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, u8 **up_a,
- u8 **down_a, u8 **up_b, u8 **down_b)
+static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw,
+ const u8 **up_a,
+ const u8 **down_a)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &rtlpriv->phy;
@@ -1843,34 +1812,22 @@ static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, u8 **up_a,
if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) {
*up_a = rtl8821ae_delta_swing_table_idx_24gccka_p;
*down_a = rtl8821ae_delta_swing_table_idx_24gccka_n;
- *up_b = rtl8821ae_delta_swing_table_idx_24gcckb_p;
- *down_b = rtl8821ae_delta_swing_table_idx_24gcckb_n;
} else {
*up_a = rtl8821ae_delta_swing_table_idx_24ga_p;
*down_a = rtl8821ae_delta_swing_table_idx_24ga_n;
- *up_b = rtl8821ae_delta_swing_table_idx_24gb_p;
- *down_b = rtl8821ae_delta_swing_table_idx_24gb_n;
}
} else if (36 <= channel && channel <= 64) {
*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0];
*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0];
- *up_b = rtl8821ae_delta_swing_table_idx_5gb_p[0];
- *down_b = rtl8821ae_delta_swing_table_idx_5gb_n[0];
} else if (100 <= channel && channel <= 140) {
*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1];
*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1];
- *up_b = rtl8821ae_delta_swing_table_idx_5gb_p[1];
- *down_b = rtl8821ae_delta_swing_table_idx_5gb_n[1];
} else if (149 <= channel && channel <= 173) {
*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2];
*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2];
- *up_b = rtl8821ae_delta_swing_table_idx_5gb_p[2];
- *down_b = rtl8821ae_delta_swing_table_idx_5gb_n[2];
} else {
- *up_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p;
- *down_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n;
- *up_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p;
- *down_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n;
+ *up_a = rtl8818e_delta_swing_table_idx_24gb_p;
+ *down_a = rtl8818e_delta_swing_table_idx_24gb_n;
}
return;
}
@@ -2075,16 +2032,13 @@ void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(
/* 1. The following TWO tables decide the final
* index of OFDM/CCK swing table.
*/
- u8 *delta_swing_table_idx_tup_a;
- u8 *delta_swing_table_idx_tdown_a;
- u8 *delta_swing_table_idx_tup_b;
- u8 *delta_swing_table_idx_tdown_b;
+ const u8 *delta_swing_table_idx_tup_a;
+ const u8 *delta_swing_table_idx_tdown_a;
/*2. Initilization ( 7 steps in total )*/
- rtl8821ae_get_delta_swing_table(hw, (u8 **)&delta_swing_table_idx_tup_a,
- (u8 **)&delta_swing_table_idx_tdown_a,
- (u8 **)&delta_swing_table_idx_tup_b,
- (u8 **)&delta_swing_table_idx_tdown_b);
+ rtl8821ae_get_delta_swing_table(hw,
+ &delta_swing_table_idx_tup_a,
+ &delta_swing_table_idx_tdown_a);
rtldm->txpower_trackinginit = true;
diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c
index c66c6dc00378..d05e709536ea 100644
--- a/drivers/net/wireless/realtek/rtlwifi/usb.c
+++ b/drivers/net/wireless/realtek/rtlwifi/usb.c
@@ -680,8 +680,10 @@ static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw)
tasklet_kill(&rtlusb->rx_work_tasklet);
cancel_work_sync(&rtlpriv->works.lps_change_work);
- flush_workqueue(rtlpriv->works.rtl_wq);
- destroy_workqueue(rtlpriv->works.rtl_wq);
+ if (rtlpriv->works.rtl_wq) {
+ destroy_workqueue(rtlpriv->works.rtl_wq);
+ rtlpriv->works.rtl_wq = NULL;
+ }
skb_queue_purge(&rtlusb->rx_queue);
@@ -718,8 +720,11 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
usb_anchor_urb(urb, &rtlusb->rx_submitted);
err = usb_submit_urb(urb, GFP_KERNEL);
- if (err)
+ if (err) {
+ usb_unanchor_urb(urb);
+ usb_free_urb(urb);
goto err_out;
+ }
usb_free_urb(urb);
}
return 0;
@@ -1082,6 +1087,7 @@ error_out2:
usb_put_dev(udev);
complete(&rtlpriv->firmware_loading_complete);
kfree(rtlpriv->usb_data);
+ ieee80211_free_hw(hw);
return -ENODEV;
}
EXPORT_SYMBOL(rtl_usb_probe);
diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index ca894c4f96ac..e3d7cb6c1290 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -25,6 +25,9 @@ config RTW88_8822C
config RTW88_8723D
tristate
+config RTW88_8821C
+ tristate
+
config RTW88_8822BE
tristate "Realtek 8822BE PCI wireless network adapter"
depends on PCI
@@ -58,6 +61,17 @@ config RTW88_8723DE
802.11n PCIe wireless network adapter
+config RTW88_8821CE
+ tristate "Realtek 8821CE PCI wireless network adapter"
+ depends on PCI
+ select RTW88_CORE
+ select RTW88_PCI
+ select RTW88_8821C
+ help
+ Select this option will enable support for 8821CE chipset
+
+ 802.11ac PCIe wireless network adapter
+
config RTW88_DEBUG
bool "Realtek rtw88 debug support"
depends on RTW88_CORE
diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile
index f31e78a6f146..c0e4b111c8b4 100644
--- a/drivers/net/wireless/realtek/rtw88/Makefile
+++ b/drivers/net/wireless/realtek/rtw88/Makefile
@@ -37,5 +37,11 @@ rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o
obj-$(CONFIG_RTW88_8723DE) += rtw88_8723de.o
rtw88_8723de-objs := rtw8723de.o
+obj-$(CONFIG_RTW88_8821C) += rtw88_8821c.o
+rtw88_8821c-objs := rtw8821c.o rtw8821c_table.o
+
+obj-$(CONFIG_RTW88_8821CE) += rtw88_8821ce.o
+rtw88_8821ce-objs := rtw8821ce.o
+
obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o
rtw88_pci-objs := pci.o
diff --git a/drivers/net/wireless/realtek/rtw88/bf.c b/drivers/net/wireless/realtek/rtw88/bf.c
index 8a070d5d9174..aff70e4ae028 100644
--- a/drivers/net/wireless/realtek/rtw88/bf.c
+++ b/drivers/net/wireless/realtek/rtw88/bf.c
@@ -183,7 +183,7 @@ void rtw_bf_del_sounding(struct rtw_dev *rtwdev)
void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif,
struct rtw_bfee *bfee)
{
- u8 nc_index = 1;
+ u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1;
u8 nr_index = bfee->sound_dim;
u8 grouping = 0, codebookinfo = 1, coefficientsize = 3;
u32 addr_bfer_info, addr_csi_rpt, csi_param;
@@ -231,7 +231,8 @@ void rtw_bf_enable_bfee_mu(struct rtw_dev *rtwdev, struct rtw_vif *vif,
{
struct rtw_bf_info *bf_info = &rtwdev->bf_info;
struct mu_bfer_init_para param;
- u8 nc_index = 1, nr_index = 1;
+ u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1;
+ u8 nr_index = 1;
u8 grouping = 0, codebookinfo = 1, coefficientsize = 0;
u32 csi_param;
diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
index cbf3d503df1c..aa08fd7d9fcd 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.c
+++ b/drivers/net/wireless/realtek/rtw88/coex.c
@@ -378,6 +378,7 @@ static void rtw_coex_update_wl_link_info(struct rtw_dev *rtwdev, u8 reason)
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_traffic_stats *stats = &rtwdev->stats;
bool is_5G = false;
+ bool wl_busy = false;
bool scan = false, link = false;
int i;
u8 rssi_state;
@@ -386,7 +387,16 @@ static void rtw_coex_update_wl_link_info(struct rtw_dev *rtwdev, u8 reason)
scan = test_bit(RTW_FLAG_SCANNING, rtwdev->flags);
coex_stat->wl_connected = !!rtwdev->sta_cnt;
- coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
+
+ wl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
+ if (wl_busy != coex_stat->wl_gl_busy) {
+ if (wl_busy)
+ coex_stat->wl_gl_busy = true;
+ else
+ ieee80211_queue_delayed_work(rtwdev->hw,
+ &coex->wl_remain_work,
+ 12 * HZ);
+ }
if (stats->tx_throughput > stats->rx_throughput)
coex_stat->wl_tput_dir = COEX_WL_TPUT_TX;
@@ -888,10 +898,12 @@ static void rtw_coex_tdma(struct rtw_dev *rtwdev, bool force, u32 tcase)
{
struct rtw_coex *coex = &rtwdev->coex;
struct rtw_coex_dm *coex_dm = &coex->dm;
+ struct rtw_coex_stat *coex_stat = &coex->stat;
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_efuse *efuse = &rtwdev->efuse;
u8 n, type;
bool turn_on;
+ bool wl_busy = false;
if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */
rtw_coex_tdma_timer_base(rtwdev, 3);
@@ -909,13 +921,18 @@ static void rtw_coex_tdma(struct rtw_dev *rtwdev, bool force, u32 tcase)
}
}
- if (turn_on) {
- /* enable TBTT interrupt */
+ /* enable TBTT interrupt */
+ if (turn_on)
rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
- rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, true);
- } else {
+
+ wl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
+
+ if ((coex_stat->bt_a2dp_exist &&
+ (coex_stat->bt_inq_remain || coex_stat->bt_multi_link)) ||
+ !wl_busy)
rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, false);
- }
+ else
+ rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, true);
if (efuse->share_ant) {
if (type < chip->tdma_sant_num)
@@ -1323,20 +1340,31 @@ static void rtw_coex_action_bt_inquiry(struct rtw_dev *rtwdev)
/* Shared-Ant */
if (wl_hi_pri) {
table_case = 15;
- if (coex_stat->bt_a2dp_exist &&
- !coex_stat->bt_pan_exist) {
- slot_type = TDMA_4SLOT;
- tdma_case = 11;
- } else if (coex_stat->wl_hi_pri_task1) {
+ if (coex_stat->bt_profile_num > 0)
+ tdma_case = 10;
+ else if (coex_stat->wl_hi_pri_task1)
tdma_case = 6;
- } else if (!coex_stat->bt_page) {
+ else if (!coex_stat->bt_page)
tdma_case = 8;
- } else {
+ else
tdma_case = 9;
+ } else if (coex_stat->wl_gl_busy) {
+ if (coex_stat->bt_profile_num == 0) {
+ table_case = 12;
+ tdma_case = 18;
+ } else if (coex_stat->bt_profile_num == 1 &&
+ !coex_stat->bt_a2dp_exist) {
+ slot_type = TDMA_4SLOT;
+ table_case = 12;
+ tdma_case = 20;
+ } else {
+ slot_type = TDMA_4SLOT;
+ table_case = 12;
+ tdma_case = 26;
}
} else if (coex_stat->wl_connected) {
- table_case = 10;
- tdma_case = 10;
+ table_case = 9;
+ tdma_case = 27;
} else {
table_case = 1;
tdma_case = 0;
@@ -1934,7 +1962,8 @@ static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason)
if (coex_stat->wl_under_ips)
return;
- if (coex->freeze && !coex_stat->bt_setup_link)
+ if (coex->freeze && coex_dm->reason == COEX_RSN_BTINFO &&
+ !coex_stat->bt_setup_link)
return;
coex_stat->cnt_wl[COEX_CNT_WL_COEXRUN]++;
@@ -2277,6 +2306,7 @@ void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length)
struct rtw_chip_info *chip = rtwdev->chip;
unsigned long bt_relink_time;
u8 i, rsp_source = 0, type;
+ bool inq_page = false;
rsp_source = buf[0] & 0xf;
if (rsp_source >= COEX_BTINFO_SRC_MAX)
@@ -2343,7 +2373,20 @@ void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length)
/* 0xff means BT is under WHCK test */
coex_stat->bt_whck_test = (coex_stat->bt_info_lb2 == 0xff);
- coex_stat->bt_inq_page = ((coex_stat->bt_info_lb2 & BIT(2)) == BIT(2));
+
+ inq_page = ((coex_stat->bt_info_lb2 & BIT(2)) == BIT(2));
+
+ if (inq_page != coex_stat->bt_inq_page) {
+ cancel_delayed_work_sync(&coex->bt_remain_work);
+ coex_stat->bt_inq_page = inq_page;
+
+ if (inq_page)
+ coex_stat->bt_inq_remain = true;
+ else
+ ieee80211_queue_delayed_work(rtwdev->hw,
+ &coex->bt_remain_work,
+ 4 * HZ);
+ }
coex_stat->bt_acl_busy = ((coex_stat->bt_info_lb2 & BIT(3)) == BIT(3));
coex_stat->cnt_bt[COEX_CNT_BT_RETRY] = coex_stat->bt_info_lb3 & 0xf;
if (coex_stat->cnt_bt[COEX_CNT_BT_RETRY] >= 1)
@@ -2518,6 +2561,30 @@ void rtw_coex_defreeze_work(struct work_struct *work)
mutex_unlock(&rtwdev->mutex);
}
+void rtw_coex_wl_remain_work(struct work_struct *work)
+{
+ struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
+ coex.wl_remain_work.work);
+ struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
+
+ mutex_lock(&rtwdev->mutex);
+ coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
+ rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
+ mutex_unlock(&rtwdev->mutex);
+}
+
+void rtw_coex_bt_remain_work(struct work_struct *work)
+{
+ struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
+ coex.bt_remain_work.work);
+ struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
+
+ mutex_lock(&rtwdev->mutex);
+ coex_stat->bt_inq_remain = coex_stat->bt_inq_page;
+ rtw_coex_run_coex(rtwdev, COEX_RSN_BTSTATUS);
+ mutex_unlock(&rtwdev->mutex);
+}
+
#ifdef CONFIG_RTW88_DEBUGFS
#define INFO_SIZE 80
diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h
index 4c3a01968f5e..44720fdfc053 100644
--- a/drivers/net/wireless/realtek/rtw88/coex.h
+++ b/drivers/net/wireless/realtek/rtw88/coex.h
@@ -95,6 +95,7 @@ enum coex_runreason {
COEX_RSN_BTINFO = 12,
COEX_RSN_LPS = 13,
COEX_RSN_WLSTATUS = 14,
+ COEX_RSN_BTSTATUS = 15,
COEX_RSN_MAX
};
@@ -362,6 +363,8 @@ void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set);
void rtw_coex_bt_relink_work(struct work_struct *work);
void rtw_coex_bt_reenable_work(struct work_struct *work);
void rtw_coex_defreeze_work(struct work_struct *work);
+void rtw_coex_wl_remain_work(struct work_struct *work);
+void rtw_coex_bt_remain_work(struct work_struct *work);
void rtw_coex_power_on_setting(struct rtw_dev *rtwdev);
void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only);
diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index 09f04feb8fe1..f769c982cc91 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -344,6 +344,31 @@ static ssize_t rtw_debugfs_set_write_reg(struct file *filp,
return count;
}
+static ssize_t rtw_debugfs_set_h2c(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *loff)
+{
+ struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
+ struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+ char tmp[32 + 1];
+ u8 param[8];
+ int num;
+
+ rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);
+
+ num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx",
+ &param[0], &param[1], &param[2], &param[3],
+ &param[4], &param[5], &param[6], &param[7]);
+ if (num != 8) {
+ rtw_info(rtwdev, "invalid H2C command format for debug\n");
+ return -EINVAL;
+ }
+
+ rtw_fw_h2c_cmd_dbg(rtwdev, param);
+
+ return count;
+}
+
static ssize_t rtw_debugfs_set_rf_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *loff)
@@ -808,6 +833,10 @@ static struct rtw_debugfs_priv rtw_debug_priv_write_reg = {
.cb_write = rtw_debugfs_set_write_reg,
};
+static struct rtw_debugfs_priv rtw_debug_priv_h2c = {
+ .cb_write = rtw_debugfs_set_h2c,
+};
+
static struct rtw_debugfs_priv rtw_debug_priv_rf_write = {
.cb_write = rtw_debugfs_set_rf_write,
};
@@ -877,6 +906,7 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
rtw_debugfs_add_r(phy_info);
rtw_debugfs_add_r(coex_info);
rtw_debugfs_add_rw(coex_enable);
+ rtw_debugfs_add_w(h2c);
rtw_debugfs_add_r(mac_0);
rtw_debugfs_add_r(mac_1);
rtw_debugfs_add_r(mac_2);
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 6478fd7a78f6..63b00bc19000 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -253,6 +253,11 @@ out:
spin_unlock(&rtwdev->h2c.lock);
}
+void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c)
+{
+ rtw_fw_send_h2c_command(rtwdev, h2c);
+}
+
static void rtw_fw_send_h2c_packet(struct rtw_dev *rtwdev, u8 *h2c_pkt)
{
int ret;
@@ -456,7 +461,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
SET_RA_INFO_INIT_RA_LVL(h2c_pkt, si->init_ra_lv);
SET_RA_INFO_SGI_EN(h2c_pkt, si->sgi_enable);
SET_RA_INFO_BW_MODE(h2c_pkt, si->bw_mode);
- SET_RA_INFO_LDPC(h2c_pkt, si->ldpc_en);
+ SET_RA_INFO_LDPC(h2c_pkt, !!si->ldpc_en);
SET_RA_INFO_NO_UPDATE(h2c_pkt, no_update);
SET_RA_INFO_VHT_EN(h2c_pkt, si->vht_enable);
SET_RA_INFO_DIS_PT(h2c_pkt, disable_pt);
@@ -915,14 +920,14 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw,
return skb_new;
}
-static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb)
+static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb,
+ enum rtw_rsvd_packet_type type)
{
- struct rtw_tx_pkt_info pkt_info;
+ struct rtw_tx_pkt_info pkt_info = {0};
struct rtw_chip_info *chip = rtwdev->chip;
u8 *pkt_desc;
- memset(&pkt_info, 0, sizeof(pkt_info));
- rtw_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb);
+ rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type);
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
rtw_tx_fill_tx_desc(&pkt_info, skb);
@@ -1261,7 +1266,7 @@ static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size)
* And iter->len will be added with size of tx_desc_sz.
*/
if (rsvd_pkt->add_txdesc)
- rtw_fill_rsvd_page_desc(rtwdev, iter);
+ rtw_fill_rsvd_page_desc(rtwdev, iter, rsvd_pkt->type);
rsvd_pkt->skb = iter;
rsvd_pkt->page = total_page;
diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h
index 470e1809645a..686dcd3bbda6 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.h
+++ b/drivers/net/wireless/realtek/rtw88/fw.h
@@ -563,4 +563,6 @@ void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable);
void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev,
struct cfg80211_ssid *ssid);
void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable);
+void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c);
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index c412bc54efde..6b199152abcf 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -231,6 +231,23 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
mutex_unlock(&rtwdev->mutex);
}
+static int rtw_ops_change_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum nl80211_iftype type, bool p2p)
+{
+ struct rtw_dev *rtwdev = hw->priv;
+
+ rtw_info(rtwdev, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n",
+ vif->addr, vif->type, type, vif->p2p, p2p);
+
+ rtw_ops_remove_interface(hw, vif);
+
+ vif->type = type;
+ vif->p2p = p2p;
+
+ return rtw_ops_add_interface(hw, vif);
+}
+
static void rtw_ops_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *new_flags,
@@ -373,6 +390,15 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BEACON)
rtw_fw_download_rsvd_page(rtwdev);
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ if (conf->enable_beacon)
+ rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL,
+ BIT_EN_BCNQ_DL);
+ else
+ rtw_write32_clr(rtwdev, REG_FWHW_TXQ_CTRL,
+ BIT_EN_BCNQ_DL);
+ }
+
if (changed & BSS_CHANGED_MU_GROUPS)
rtw_chip_set_gid_table(rtwdev, vif, conf);
@@ -827,6 +853,7 @@ const struct ieee80211_ops rtw_ops = {
.config = rtw_ops_config,
.add_interface = rtw_ops_add_interface,
.remove_interface = rtw_ops_remove_interface,
+ .change_interface = rtw_ops_change_interface,
.configure_filter = rtw_ops_configure_filter,
.bss_info_changed = rtw_ops_bss_info_changed,
.conf_tx = rtw_ops_conf_tx,
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 0eefafc51c62..54044abf30d7 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -722,8 +722,6 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
stbc_en = VHT_STBC_EN;
if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
ldpc_en = VHT_LDPC_EN;
- if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
- is_support_sgi = true;
} else if (sta->ht_cap.ht_supported) {
ra_mask |= (sta->ht_cap.mcs.rx_mask[1] << 20) |
(sta->ht_cap.mcs.rx_mask[0] << 12);
@@ -731,9 +729,6 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
stbc_en = HT_STBC_EN;
if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
ldpc_en = HT_LDPC_EN;
- if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20 ||
- sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
- is_support_sgi = true;
}
if (efuse->hw_cap.nss == 1)
@@ -775,12 +770,18 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
switch (sta->bandwidth) {
case IEEE80211_STA_RX_BW_80:
bw_mode = RTW_CHANNEL_WIDTH_80;
+ is_support_sgi = sta->vht_cap.vht_supported &&
+ (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80);
break;
case IEEE80211_STA_RX_BW_40:
bw_mode = RTW_CHANNEL_WIDTH_40;
+ is_support_sgi = sta->ht_cap.ht_supported &&
+ (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
break;
default:
bw_mode = RTW_CHANNEL_WIDTH_20;
+ is_support_sgi = sta->ht_cap.ht_supported &&
+ (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
break;
}
@@ -935,6 +936,8 @@ void rtw_core_stop(struct rtw_dev *rtwdev)
cancel_delayed_work_sync(&coex->bt_relink_work);
cancel_delayed_work_sync(&coex->bt_reenable_work);
cancel_delayed_work_sync(&coex->defreeze_work);
+ cancel_delayed_work_sync(&coex->wl_remain_work);
+ cancel_delayed_work_sync(&coex->bt_remain_work);
mutex_lock(&rtwdev->mutex);
@@ -989,12 +992,12 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev,
vht_cap->vht_supported = true;
vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
IEEE80211_VHT_CAP_SHORT_GI_80 |
- IEEE80211_VHT_CAP_TXSTBC |
IEEE80211_VHT_CAP_RXSTBC_1 |
IEEE80211_VHT_CAP_HTC_VHT |
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
0;
-
+ if (rtwdev->hal.rf_path_num > 1)
+ vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
vht_cap->cap |= (rtwdev->hal.bfee_sts_cap <<
@@ -1326,6 +1329,10 @@ static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev)
efuse->share_ant = true;
if (efuse->regd == 0xff)
efuse->regd = 0;
+ if (efuse->tx_bb_swing_setting_2g == 0xff)
+ efuse->tx_bb_swing_setting_2g = 0;
+ if (efuse->tx_bb_swing_setting_5g == 0xff)
+ efuse->tx_bb_swing_setting_5g = 0;
efuse->btcoex = (efuse->rf_board_option & 0xe0) == 0x20;
efuse->ext_pa_2g = efuse->pa_type_2g & BIT(4) ? 1 : 0;
@@ -1422,6 +1429,8 @@ int rtw_core_init(struct rtw_dev *rtwdev)
INIT_DELAYED_WORK(&coex->bt_relink_work, rtw_coex_bt_relink_work);
INIT_DELAYED_WORK(&coex->bt_reenable_work, rtw_coex_bt_reenable_work);
INIT_DELAYED_WORK(&coex->defreeze_work, rtw_coex_defreeze_work);
+ INIT_DELAYED_WORK(&coex->wl_remain_work, rtw_coex_wl_remain_work);
+ INIT_DELAYED_WORK(&coex->bt_remain_work, rtw_coex_bt_remain_work);
INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work);
INIT_WORK(&rtwdev->ba_work, rtw_txq_ba_work);
skb_queue_head_init(&rtwdev->c2h_queue);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 0841f5fa4bf2..276b5d381467 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -183,6 +183,7 @@ enum rtw_chip_type {
RTW_CHIP_TYPE_8822B,
RTW_CHIP_TYPE_8822C,
RTW_CHIP_TYPE_8723D,
+ RTW_CHIP_TYPE_8821C,
};
enum rtw_tx_queue_type {
@@ -591,6 +592,8 @@ struct rtw_tx_pkt_info {
bool dis_qselseq;
bool en_hwseq;
u8 hw_ssn_sel;
+ bool nav_use_hdr;
+ bool bt_null;
};
struct rtw_rx_pkt_stat {
@@ -1147,6 +1150,9 @@ struct rtw_chip_info {
const struct wiphy_wowlan_support *wowlan_stub;
const u8 max_sched_scan_ssids;
+ /* for 8821c set channel */
+ u32 ch_param[3];
+
/* coex paras */
u32 coex_para_ver;
u8 bt_desired_ver;
@@ -1263,6 +1269,7 @@ struct rtw_coex_stat {
bool bt_link_exist;
bool bt_whck_test;
bool bt_inq_page;
+ bool bt_inq_remain;
bool bt_inq;
bool bt_page;
bool bt_ble_voice;
@@ -1363,6 +1370,8 @@ struct rtw_coex {
struct delayed_work bt_relink_work;
struct delayed_work bt_reenable_work;
struct delayed_work defreeze_work;
+ struct delayed_work wl_remain_work;
+ struct delayed_work bt_remain_work;
};
#define DPK_RF_REG_NUM 7
@@ -1462,6 +1471,7 @@ struct rtw_dm_info {
u8 thermal_avg[RTW_RF_PATH_MAX];
u8 thermal_meter_k;
s8 delta_power_index[RTW_RF_PATH_MAX];
+ s8 delta_power_index_last[RTW_RF_PATH_MAX];
u8 default_ofdm_index;
bool pwr_trk_triggered;
bool pwr_trk_init_trigger;
@@ -1479,6 +1489,7 @@ struct rtw_dm_info {
/* [bandwidth 0:20M/1:40M][number of path] */
u8 cck_pd_lv[2][RTW_RF_PATH_MAX];
u32 cck_fa_avg;
+ u8 cck_pd_default;
/* save the last rx phy status for debug */
s8 rx_snr[RTW_RF_PATH_MAX];
@@ -1526,6 +1537,8 @@ struct rtw_efuse {
u8 apa_type;
bool ext_pa_2g;
bool ext_pa_5g;
+ u8 tx_bb_swing_setting_2g;
+ u8 tx_bb_swing_setting_5g;
bool btcoex;
/* bt share antenna with wifi */
diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
index 8228db9a5fc8..3413973bc475 100644
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -14,8 +14,11 @@
#include "debug.h"
static bool rtw_disable_msi;
+static bool rtw_pci_disable_aspm;
module_param_named(disable_msi, rtw_disable_msi, bool, 0644);
+module_param_named(disable_aspm, rtw_pci_disable_aspm, bool, 0644);
MODULE_PARM_DESC(disable_msi, "Set Y to disable MSI interrupt support");
+MODULE_PARM_DESC(disable_aspm, "Set Y to disable PCI ASPM support");
static u32 rtw_pci_tx_queue_idx_addr[] = {
[RTW_TX_QUEUE_BK] = RTK_PCI_TXBD_IDX_BKQ,
@@ -1200,6 +1203,9 @@ static void rtw_pci_clkreq_set(struct rtw_dev *rtwdev, bool enable)
u8 value;
int ret;
+ if (rtw_pci_disable_aspm)
+ return;
+
ret = rtw_dbi_read8(rtwdev, RTK_PCIE_LINK_CFG, &value);
if (ret) {
rtw_err(rtwdev, "failed to read CLKREQ_L1, ret=%d", ret);
@@ -1219,6 +1225,9 @@ static void rtw_pci_aspm_set(struct rtw_dev *rtwdev, bool enable)
u8 value;
int ret;
+ if (rtw_pci_disable_aspm)
+ return;
+
ret = rtw_dbi_read8(rtwdev, RTK_PCIE_LINK_CFG, &value);
if (ret) {
rtw_err(rtwdev, "failed to read ASPM, ret=%d", ret);
diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
index 5a3e9cc7c400..8f468d6b5f78 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -43,6 +43,8 @@
#define BITS_EF_ADDR (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR)
#define BITS_PLL 0xf0
+#define REG_AFE_XTAL_CTRL 0x24
+#define REG_AFE_PLL_CTRL 0x28
#define REG_AFE_CTRL3 0x2c
#define BIT_MASK_XTAL 0x00FFF000
#define BIT_XTAL_GMP_BIT4 BIT(28)
@@ -59,6 +61,7 @@
#define BIT_FSPI_EN BIT(19)
#define BIT_EN_SIC BIT(12)
#define BIT_BT_AOD_GPIO3 BIT(9)
+#define BIT_PO_BT_PTA_PINS BIT(9)
#define BIT_BT_PTA_EN BIT(5)
#define BIT_WLRFE_4_5_EN BIT(2)
@@ -476,6 +479,8 @@
#define REG_RFE_CTRL_E 0x0974
#define REG_2ND_CCA_CTRL 0x0976
+#define REG_CCK0_FAREPORT 0xa2c
+
#define REG_DIS_DPD 0x0a70
#define DIS_DPD_MASK GENMASK(9, 0)
#define DIS_DPD_RATE6M BIT(0)
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 4700195c8eef..3ddd170f1651 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -1956,13 +1956,13 @@ static const struct coex_table_para table_sant_8723d[] = {
{0xa5555555, 0xaaaa5aaa},
{0x6a5a5a5a, 0x5a5a5a5a},
{0x6a5a5a5a, 0x6a5a5a5a},
- {0x65555555, 0x5a5a5a5a},
+ {0x66555555, 0x5a5a5a5a},
{0x65555555, 0x6a5a5a5a}, /* case-10 */
{0x65555555, 0xfafafafa},
- {0x65555555, 0x6a5a5aaa},
+ {0x66555555, 0x5a5a5aaa},
{0x65555555, 0x5aaa5aaa},
{0x65555555, 0xaaaa5aaa},
- {0x65555555, 0xaaaaaaaa}, /* case-15 */
+ {0x66555555, 0xaaaaaaaa}, /* case-15 */
{0xffff55ff, 0xfafafafa},
{0xffff55ff, 0x6afa5afa},
{0xaaffffaa, 0xfafafafa},
@@ -2034,8 +2034,9 @@ static const struct coex_tdma_para tdma_sant_8723d[] = {
{ {0x51, 0x0c, 0x03, 0x10, 0x54} },
{ {0x55, 0x08, 0x03, 0x10, 0x54} },
{ {0x65, 0x10, 0x03, 0x11, 0x11} },
- { {0x51, 0x10, 0x03, 0x10, 0x51} },
- { {0x61, 0x15, 0x03, 0x11, 0x10} }
+ { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
+ { {0x51, 0x08, 0x03, 0x10, 0x50} },
+ { {0x61, 0x08, 0x03, 0x11, 0x11} }
};
/* Non-Shared-Antenna TDMA */
@@ -2714,7 +2715,7 @@ struct rtw_chip_info rtw8723d_hw_spec = {
.pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl,
.iqk_threshold = 8,
- .coex_para_ver = 0x1905302f,
+ .coex_para_ver = 0x2007022f,
.bt_desired_ver = 0x2f,
.scbd_support = true,
.new_scbd10_def = true,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
new file mode 100644
index 000000000000..d8863d8a5468
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -0,0 +1,1853 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#include "main.h"
+#include "coex.h"
+#include "fw.h"
+#include "tx.h"
+#include "rx.h"
+#include "phy.h"
+#include "rtw8821c.h"
+#include "rtw8821c_table.h"
+#include "mac.h"
+#include "reg.h"
+#include "debug.h"
+#include "bf.h"
+
+static void rtw8821ce_efuse_parsing(struct rtw_efuse *efuse,
+ struct rtw8821c_efuse *map)
+{
+ ether_addr_copy(efuse->addr, map->e.mac_addr);
+}
+
+static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
+{
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ struct rtw8821c_efuse *map;
+ int i;
+
+ map = (struct rtw8821c_efuse *)log_map;
+
+ efuse->rfe_option = map->rfe_option;
+ efuse->rf_board_option = map->rf_board_option;
+ efuse->crystal_cap = map->xtal_k;
+ efuse->pa_type_2g = map->pa_type;
+ efuse->pa_type_5g = map->pa_type;
+ efuse->lna_type_2g = map->lna_type_2g[0];
+ efuse->lna_type_5g = map->lna_type_5g[0];
+ efuse->channel_plan = map->channel_plan;
+ efuse->country_code[0] = map->country_code[0];
+ efuse->country_code[1] = map->country_code[1];
+ efuse->bt_setting = map->rf_bt_setting;
+ efuse->regd = map->rf_board_option & 0x7;
+ efuse->thermal_meter[0] = map->thermal_meter;
+ efuse->thermal_meter_k = map->thermal_meter;
+ efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g;
+ efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g;
+
+ for (i = 0; i < 4; i++)
+ efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
+
+ switch (rtw_hci_type(rtwdev)) {
+ case RTW_HCI_TYPE_PCIE:
+ rtw8821ce_efuse_parsing(efuse, map);
+ break;
+ default:
+ /* unsupported now */
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static const u32 rtw8821c_txscale_tbl[] = {
+ 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8,
+ 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180,
+ 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab,
+ 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe
+};
+
+static const u8 rtw8821c_get_swing_index(struct rtw_dev *rtwdev)
+{
+ u8 i = 0;
+ u32 swing, table_value;
+
+ swing = rtw_read32_mask(rtwdev, REG_TXSCALE_A, 0xffe00000);
+ for (i = 0; i < ARRAY_SIZE(rtw8821c_txscale_tbl); i++) {
+ table_value = rtw8821c_txscale_tbl[i];
+ if (swing == table_value)
+ break;
+ }
+
+ return i;
+}
+
+static void rtw8821c_pwrtrack_init(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 swing_idx = rtw8821c_get_swing_index(rtwdev);
+
+ if (swing_idx >= ARRAY_SIZE(rtw8821c_txscale_tbl))
+ dm_info->default_ofdm_index = 24;
+ else
+ dm_info->default_ofdm_index = swing_idx;
+
+ ewma_thermal_init(&dm_info->avg_thermal[RF_PATH_A]);
+ dm_info->delta_power_index[RF_PATH_A] = 0;
+ dm_info->delta_power_index_last[RF_PATH_A] = 0;
+ dm_info->pwr_trk_triggered = false;
+ dm_info->pwr_trk_init_trigger = true;
+ dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
+}
+
+static void rtw8821c_phy_bf_init(struct rtw_dev *rtwdev)
+{
+ rtw_bf_phy_init(rtwdev);
+ /* Grouping bitmap parameters */
+ rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF);
+}
+
+static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev)
+{
+ u8 crystal_cap, val;
+
+ /* power on BB/RF domain */
+ val = rtw_read8(rtwdev, REG_SYS_FUNC_EN);
+ val |= BIT_FEN_PCIEA;
+ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val);
+
+ /* toggle BB reset */
+ val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST;
+ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val);
+ val &= ~(BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST);
+ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val);
+ val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST;
+ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val);
+
+ rtw_write8(rtwdev, REG_RF_CTRL,
+ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
+ usleep_range(10, 11);
+ rtw_write8(rtwdev, REG_WLRF1 + 3,
+ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
+ usleep_range(10, 11);
+
+ /* pre init before header files config */
+ rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
+
+ rtw_phy_load_tables(rtwdev);
+
+ crystal_cap = rtwdev->efuse.crystal_cap & 0x3F;
+ rtw_write32_mask(rtwdev, REG_AFE_XTAL_CTRL, 0x7e000000, crystal_cap);
+ rtw_write32_mask(rtwdev, REG_AFE_PLL_CTRL, 0x7e, crystal_cap);
+ rtw_write32_mask(rtwdev, REG_CCK0_FAREPORT, BIT(18) | BIT(22), 0);
+
+ /* post init after header files config */
+ rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST);
+ rtwdev->chip->ch_param[0] = rtw_read32_mask(rtwdev, REG_TXSF2, MASKDWORD);
+ rtwdev->chip->ch_param[1] = rtw_read32_mask(rtwdev, REG_TXSF6, MASKDWORD);
+ rtwdev->chip->ch_param[2] = rtw_read32_mask(rtwdev, REG_TXFILTER, MASKDWORD);
+
+ rtw_phy_init(rtwdev);
+ rtwdev->dm_info.cck_pd_default = rtw_read8(rtwdev, REG_CSRATIO) & 0x1f;
+
+ rtw8821c_pwrtrack_init(rtwdev);
+
+ rtw8821c_phy_bf_init(rtwdev);
+}
+
+static int rtw8821c_mac_init(struct rtw_dev *rtwdev)
+{
+ u32 value32;
+ u16 pre_txcnt;
+
+ /* protocol configuration */
+ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME);
+ rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1);
+ pre_txcnt = WLAN_PRE_TXCNT_TIME_TH | BIT_EN_PRECNT;
+ rtw_write8(rtwdev, REG_PRECNT_CTRL, (u8)(pre_txcnt & 0xFF));
+ rtw_write8(rtwdev, REG_PRECNT_CTRL + 1, (u8)(pre_txcnt >> 8));
+ value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) |
+ (WLAN_MAX_AGG_PKT_LIMIT << 16) |
+ (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24);
+ rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32);
+ rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2,
+ WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8);
+ rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH);
+ rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH);
+ rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH);
+ rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH);
+ rtw_write8_set(rtwdev, REG_INIRTS_RATE_SEL, BIT(5));
+
+ /* EDCA configuration */
+ rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0);
+ rtw_write16(rtwdev, REG_TXPAUSE, 0);
+ rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME);
+ rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME);
+ rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG);
+ rtw_write16(rtwdev, REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT);
+ rtw_write16(rtwdev, REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT);
+ rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG);
+ rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG);
+
+ /* Set beacon cotnrol - enable TSF and other related functions */
+ rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
+
+ /* Set send beacon related registers */
+ rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME);
+ rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT);
+ rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME);
+ rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8);
+
+ /* WMAC configuration */
+ rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
+ rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
+ rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
+ rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512);
+ rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2);
+ rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1);
+ rtw_write8(rtwdev, REG_ACKTO_CCK, 0x40);
+ rtw_write8_set(rtwdev, REG_WMAC_TRXPTCL_CTL_H, BIT(1));
+ rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, BIT(6));
+ rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2);
+ rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1);
+
+ return 0;
+}
+
+static void rtw8821c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
+{
+ u8 ldo_pwr;
+
+ ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
+ ldo_pwr = enable ? ldo_pwr | BIT(7) : ldo_pwr & ~BIT(7);
+ rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
+}
+
+static void rtw8821c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
+{
+ u32 rf_reg18;
+
+ rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK);
+
+ rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK |
+ RF18_BW_MASK);
+
+ rf_reg18 |= (channel <= 14 ? RF18_BAND_2G : RF18_BAND_5G);
+ rf_reg18 |= (channel & RF18_CHANNEL_MASK);
+
+ if (channel >= 100 && channel <= 140)
+ rf_reg18 |= RF18_RFSI_GE;
+ else if (channel > 140)
+ rf_reg18 |= RF18_RFSI_GT;
+
+ switch (bw) {
+ case RTW_CHANNEL_WIDTH_5:
+ case RTW_CHANNEL_WIDTH_10:
+ case RTW_CHANNEL_WIDTH_20:
+ default:
+ rf_reg18 |= RF18_BW_20M;
+ break;
+ case RTW_CHANNEL_WIDTH_40:
+ rf_reg18 |= RF18_BW_40M;
+ break;
+ case RTW_CHANNEL_WIDTH_80:
+ rf_reg18 |= RF18_BW_80M;
+ break;
+ }
+
+ if (channel <= 14) {
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x1);
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x64, 0xf, 0xf);
+ } else {
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x0);
+ }
+
+ rtw_write_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK, rf_reg18);
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 0);
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 1);
+}
+
+static void rtw8821c_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw)
+{
+ if (bw == RTW_CHANNEL_WIDTH_40) {
+ /* RX DFIR for BW40 */
+ rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
+ rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2);
+ rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
+ rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0);
+ } else if (bw == RTW_CHANNEL_WIDTH_80) {
+ /* RX DFIR for BW80 */
+ rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
+ rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x1);
+ rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0);
+ rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x1);
+ } else {
+ /* RX DFIR for BW20, BW10 and BW5 */
+ rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2);
+ rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2);
+ rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x1);
+ rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0);
+ }
+}
+
+static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
+ u8 primary_ch_idx)
+{
+ u32 val32;
+
+ if (channel <= 14) {
+ rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1);
+ rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0);
+ rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0);
+ rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15);
+
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x0);
+ rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a);
+ if (channel == 14) {
+ rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c);
+ rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000);
+ rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667);
+ } else {
+ rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD,
+ rtwdev->chip->ch_param[0]);
+ rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD,
+ rtwdev->chip->ch_param[1] & MASKLWORD);
+ rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD,
+ rtwdev->chip->ch_param[2]);
+ }
+ } else if (channel > 35) {
+ rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1);
+ rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1);
+ rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0);
+ rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15);
+
+ if (channel >= 36 && channel <= 64)
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x1);
+ else if (channel >= 100 && channel <= 144)
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x2);
+ else if (channel >= 149)
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x3);
+
+ if (channel >= 36 && channel <= 48)
+ rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494);
+ else if (channel >= 52 && channel <= 64)
+ rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453);
+ else if (channel >= 100 && channel <= 116)
+ rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452);
+ else if (channel >= 118 && channel <= 177)
+ rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412);
+ }
+
+ switch (bw) {
+ case RTW_CHANNEL_WIDTH_20:
+ default:
+ val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
+ val32 &= 0xffcffc00;
+ val32 |= 0x10010000;
+ rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
+
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
+ break;
+ case RTW_CHANNEL_WIDTH_40:
+ if (primary_ch_idx == 1)
+ rtw_write32_set(rtwdev, REG_RXSB, BIT(4));
+ else
+ rtw_write32_clr(rtwdev, REG_RXSB, BIT(4));
+
+ val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
+ val32 &= 0xff3ff300;
+ val32 |= 0x20020000 | ((primary_ch_idx & 0xf) << 2) |
+ RTW_CHANNEL_WIDTH_40;
+ rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
+
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
+ break;
+ case RTW_CHANNEL_WIDTH_80:
+ val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
+ val32 &= 0xfcffcf00;
+ val32 |= 0x40040000 | ((primary_ch_idx & 0xf) << 2) |
+ RTW_CHANNEL_WIDTH_80;
+ rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
+
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1);
+ break;
+ case RTW_CHANNEL_WIDTH_5:
+ val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
+ val32 &= 0xefcefc00;
+ val32 |= 0x200240;
+ rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
+
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
+ rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
+ break;
+ case RTW_CHANNEL_WIDTH_10:
+ val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD);
+ val32 &= 0xefcefc00;
+ val32 |= 0x300380;
+ rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32);
+
+ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0);
+ rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1);
+ break;
+ }
+}
+
+static u32 rtw8821c_get_bb_swing(struct rtw_dev *rtwdev, u8 channel)
+{
+ struct rtw_efuse efuse = rtwdev->efuse;
+ u8 tx_bb_swing;
+ u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6};
+
+ tx_bb_swing = channel <= 14 ? efuse.tx_bb_swing_setting_2g :
+ efuse.tx_bb_swing_setting_5g;
+ if (tx_bb_swing > 9)
+ tx_bb_swing = 0;
+
+ return swing2setting[(tx_bb_swing / 3)];
+}
+
+static void rtw8821c_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 channel,
+ u8 bw, u8 primary_ch_idx)
+{
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21),
+ rtw8821c_get_bb_swing(rtwdev, channel));
+ rtw8821c_pwrtrack_init(rtwdev);
+}
+
+static void rtw8821c_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
+ u8 primary_chan_idx)
+{
+ rtw8821c_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
+ rtw8821c_set_channel_bb_swing(rtwdev, channel, bw, primary_chan_idx);
+ rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
+ rtw8821c_set_channel_rf(rtwdev, channel, bw);
+ rtw8821c_set_channel_rxdfir(rtwdev, bw);
+}
+
+static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ s8 min_rx_power = -120;
+ u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status);
+
+ pkt_stat->rx_power[RF_PATH_A] = pwdb - 100;
+ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
+ pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
+ pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
+ min_rx_power);
+}
+
+static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ u8 rxsc, bw;
+ s8 min_rx_power = -120;
+
+ if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0)
+ rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status);
+ else
+ rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status);
+
+ if (rxsc >= 1 && rxsc <= 8)
+ bw = RTW_CHANNEL_WIDTH_20;
+ else if (rxsc >= 9 && rxsc <= 12)
+ bw = RTW_CHANNEL_WIDTH_40;
+ else if (rxsc >= 13)
+ bw = RTW_CHANNEL_WIDTH_80;
+ else
+ bw = GET_PHY_STAT_P1_RF_MODE(phy_status);
+
+ pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110;
+ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
+ pkt_stat->bw = bw;
+ pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
+ min_rx_power);
+}
+
+static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ u8 page;
+
+ page = *phy_status & 0xf;
+
+ switch (page) {
+ case 0:
+ query_phy_status_page0(rtwdev, phy_status, pkt_stat);
+ break;
+ case 1:
+ query_phy_status_page1(rtwdev, phy_status, pkt_stat);
+ break;
+ default:
+ rtw_warn(rtwdev, "unused phy status page (%d)\n", page);
+ return;
+ }
+}
+
+static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
+ struct rtw_rx_pkt_stat *pkt_stat,
+ struct ieee80211_rx_status *rx_status)
+{
+ struct ieee80211_hdr *hdr;
+ u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
+ u8 *phy_status = NULL;
+
+ memset(pkt_stat, 0, sizeof(*pkt_stat));
+
+ pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
+ pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
+ pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
+ pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc);
+ pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
+ pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
+ pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
+ pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
+ pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
+ pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
+ pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
+ pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
+
+ /* drv_info_sz is in unit of 8-bytes */
+ pkt_stat->drv_info_sz *= 8;
+
+ /* c2h cmd pkt's rx/phy status is not interested */
+ if (pkt_stat->is_c2h)
+ return;
+
+ hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
+ pkt_stat->drv_info_sz);
+ if (pkt_stat->phy_status) {
+ phy_status = rx_desc + desc_sz + pkt_stat->shift;
+ query_phy_status(rtwdev, phy_status, pkt_stat);
+ }
+
+ rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
+}
+
+static void
+rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
+{
+ struct rtw_hal *hal = &rtwdev->hal;
+ static const u32 offset_txagc[2] = {0x1d00, 0x1d80};
+ static u32 phy_pwr_idx;
+ u8 rate, rate_idx, pwr_index, shift;
+ int j;
+
+ for (j = 0; j < rtw_rate_size[rs]; j++) {
+ rate = rtw_rate_section[rs][j];
+ pwr_index = hal->tx_pwr_tbl[path][rate];
+ shift = rate & 0x3;
+ phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
+ if (shift == 0x3 || rate == DESC_RATEVHT1SS_MCS9) {
+ rate_idx = rate & 0xfc;
+ rtw_write32(rtwdev, offset_txagc[path] + rate_idx,
+ phy_pwr_idx);
+ phy_pwr_idx = 0;
+ }
+ }
+}
+
+static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev)
+{
+ struct rtw_hal *hal = &rtwdev->hal;
+ int rs, path;
+
+ for (path = 0; path < hal->rf_path_num; path++) {
+ for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) {
+ if (rs == RTW_RATE_SECTION_HT_2S ||
+ rs == RTW_RATE_SECTION_VHT_2S)
+ continue;
+ rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs);
+ }
+ }
+}
+
+static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u32 cck_enable;
+ u32 cck_fa_cnt;
+ u32 ofdm_fa_cnt;
+ u32 crc32_cnt;
+ u32 cca32_cnt;
+
+ cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28);
+ cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK);
+ ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM);
+
+ dm_info->cck_fa_cnt = cck_fa_cnt;
+ dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
+ if (cck_enable)
+ dm_info->total_fa_cnt += cck_fa_cnt;
+ dm_info->total_fa_cnt = ofdm_fa_cnt;
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK);
+ dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
+ dm_info->cck_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM);
+ dm_info->ofdm_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
+ dm_info->ofdm_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT);
+ dm_info->ht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
+ dm_info->ht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT);
+ dm_info->vht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
+ dm_info->vht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt);
+
+ cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM);
+ dm_info->ofdm_cca_cnt = FIELD_GET(GENMASK(31, 16), cca32_cnt);
+ dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt;
+ if (cck_enable) {
+ cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK);
+ dm_info->cck_cca_cnt = FIELD_GET(GENMASK(15, 0), cca32_cnt);
+ dm_info->total_cca_cnt += dm_info->cck_cca_cnt;
+ }
+
+ rtw_write32_set(rtwdev, REG_FAS, BIT(17));
+ rtw_write32_clr(rtwdev, REG_FAS, BIT(17));
+ rtw_write32_clr(rtwdev, REG_RXDESC, BIT(15));
+ rtw_write32_set(rtwdev, REG_RXDESC, BIT(15));
+ rtw_write32_set(rtwdev, REG_CNTRST, BIT(0));
+ rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0));
+}
+
+static void rtw8821c_do_iqk(struct rtw_dev *rtwdev)
+{
+ static int do_iqk_cnt;
+ struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0};
+ u32 rf_reg, iqk_fail_mask;
+ int counter;
+ bool reload;
+
+ if (rtw_is_assoc(rtwdev))
+ para.segment_iqk = 1;
+
+ rtw_fw_do_iqk(rtwdev, &para);
+
+ for (counter = 0; counter < 300; counter++) {
+ rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK);
+ if (rf_reg == 0xabcde)
+ break;
+ msleep(20);
+ }
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
+
+ reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
+ iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0));
+ rtw_dbg(rtwdev, RTW_DBG_PHY,
+ "iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n",
+ counter, reload, ++do_iqk_cnt, iqk_fail_mask);
+}
+
+static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev)
+{
+ rtw8821c_do_iqk(rtwdev);
+}
+
+/* for coex */
+static void rtw8821c_coex_cfg_init(struct rtw_dev *rtwdev)
+{
+ /* enable TBTT nterrupt */
+ rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
+
+ /* BT report packet sample rate */
+ rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, SAMPLE_RATE_MASK,
+ SAMPLE_RATE);
+
+ /* enable BT counter statistics */
+ rtw_write8(rtwdev, REG_BT_STAT_CTRL, BT_CNT_ENABLE);
+
+ /* enable PTA (3-wire function form BT side) */
+ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
+ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);
+
+ /* enable PTA (tx/rx signal form WiFi side) */
+ rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
+ /* wl tx signal to PTA not case EDCCA */
+ rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN);
+ /* GNT_BT=1 while select both */
+ rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY);
+
+ /* beacon queue always hi-pri */
+ rtw_write8_mask(rtwdev, REG_BT_COEX_TABLE_H + 3, BIT_BCN_QUEUE,
+ BCN_PRI_EN);
+}
+
+static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type,
+ u8 pos_type)
+{
+ struct rtw_coex *coex = &rtwdev->coex;
+ struct rtw_coex_dm *coex_dm = &coex->dm;
+ struct rtw_coex_rfe *coex_rfe = &coex->rfe;
+ u32 switch_status = FIELD_PREP(CTRL_TYPE_MASK, ctrl_type) | pos_type;
+ bool polarity_inverse;
+ u8 regval = 0;
+
+ if (switch_status == coex_dm->cur_switch_status)
+ return;
+
+ coex_dm->cur_switch_status = switch_status;
+
+ if (coex_rfe->ant_switch_diversity &&
+ ctrl_type == COEX_SWITCH_CTRL_BY_BBSW)
+ ctrl_type = COEX_SWITCH_CTRL_BY_ANTDIV;
+
+ polarity_inverse = (coex_rfe->ant_switch_polarity == 1);
+
+ switch (ctrl_type) {
+ default:
+ case COEX_SWITCH_CTRL_BY_BBSW:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89,
+ DPDT_CTRL_PIN);
+
+ if (pos_type == COEX_SWITCH_TO_WLG_BT) {
+ if (coex_rfe->rfe_module_type != 0x4 &&
+ coex_rfe->rfe_module_type != 0x2)
+ regval = 0x3;
+ else
+ regval = (!polarity_inverse ? 0x2 : 0x1);
+ } else if (pos_type == COEX_SWITCH_TO_WLG) {
+ regval = (!polarity_inverse ? 0x2 : 0x1);
+ } else {
+ regval = (!polarity_inverse ? 0x1 : 0x2);
+ }
+
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15,
+ regval);
+ break;
+ case COEX_SWITCH_CTRL_BY_PTA:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89,
+ PTA_CTRL_PIN);
+
+ regval = (!polarity_inverse ? 0x2 : 0x1);
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15,
+ regval);
+ break;
+ case COEX_SWITCH_CTRL_BY_ANTDIV:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89,
+ ANTDIC_CTRL_PIN);
+ break;
+ case COEX_SWITCH_CTRL_BY_MAC:
+ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+
+ regval = (!polarity_inverse ? 0x0 : 0x1);
+ rtw_write8_mask(rtwdev, REG_PAD_CTRL1, BIT_SW_DPDT_SEL_DATA,
+ regval);
+ break;
+ case COEX_SWITCH_CTRL_BY_FW:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ break;
+ case COEX_SWITCH_CTRL_BY_BT:
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN);
+ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL);
+ break;
+ }
+
+ if (ctrl_type == COEX_SWITCH_CTRL_BY_BT) {
+ rtw_write32_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1);
+ rtw_write32_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2);
+ } else {
+ rtw_write32_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1);
+ rtw_write32_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2);
+ }
+}
+
+static void rtw8821c_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
+{}
+
+static void rtw8821c_coex_cfg_gnt_debug(struct rtw_dev *rtwdev)
+{
+ rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_BTGP_SPI_EN);
+ rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_BTGP_JTAG_EN);
+ rtw_write32_clr(rtwdev, REG_GPIO_MUXCFG, BIT_FSPI_EN);
+ rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_LED1DIS);
+ rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_SDIO_INT);
+ rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_DBG_GNT_WL_BT);
+}
+
+static void rtw8821c_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
+{
+ struct rtw_coex *coex = &rtwdev->coex;
+ struct rtw_coex_rfe *coex_rfe = &coex->rfe;
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+
+ coex_rfe->rfe_module_type = efuse->rfe_option;
+ coex_rfe->ant_switch_polarity = 0;
+ coex_rfe->ant_switch_exist = true;
+ coex_rfe->wlg_at_btg = false;
+
+ switch (coex_rfe->rfe_module_type) {
+ case 0:
+ case 8:
+ case 1:
+ case 9: /* 1-Ant, Main, WLG */
+ default: /* 2-Ant, DPDT, WLG */
+ break;
+ case 2:
+ case 10: /* 1-Ant, Main, BTG */
+ case 7:
+ case 15: /* 2-Ant, DPDT, BTG */
+ coex_rfe->wlg_at_btg = true;
+ break;
+ case 3:
+ case 11: /* 1-Ant, Aux, WLG */
+ coex_rfe->ant_switch_polarity = 1;
+ break;
+ case 4:
+ case 12: /* 1-Ant, Aux, BTG */
+ coex_rfe->wlg_at_btg = true;
+ coex_rfe->ant_switch_polarity = 1;
+ break;
+ case 5:
+ case 13: /* 2-Ant, no switch, WLG */
+ case 6:
+ case 14: /* 2-Ant, no antenna switch, WLG */
+ coex_rfe->ant_switch_exist = false;
+ break;
+ }
+}
+
+static void rtw8821c_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
+{
+ struct rtw_coex *coex = &rtwdev->coex;
+ struct rtw_coex_dm *coex_dm = &coex->dm;
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ bool share_ant = efuse->share_ant;
+
+ if (share_ant)
+ return;
+
+ if (wl_pwr == coex_dm->cur_wl_pwr_lvl)
+ return;
+
+ coex_dm->cur_wl_pwr_lvl = wl_pwr;
+}
+
+static void rtw8821c_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
+{}
+
+static void
+rtw8821c_txagc_swing_offset(struct rtw_dev *rtwdev, u8 pwr_idx_offset,
+ s8 pwr_idx_offset_lower,
+ s8 *txagc_idx, u8 *swing_idx)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ s8 delta_pwr_idx = dm_info->delta_power_index[RF_PATH_A];
+ u8 swing_upper_bound = dm_info->default_ofdm_index + 10;
+ u8 swing_lower_bound = 0;
+ u8 max_pwr_idx_offset = 0xf;
+ s8 agc_index = 0;
+ u8 swing_index = dm_info->default_ofdm_index;
+
+ pwr_idx_offset = min_t(u8, pwr_idx_offset, max_pwr_idx_offset);
+ pwr_idx_offset_lower = max_t(s8, pwr_idx_offset_lower, -15);
+
+ if (delta_pwr_idx >= 0) {
+ if (delta_pwr_idx <= pwr_idx_offset) {
+ agc_index = delta_pwr_idx;
+ swing_index = dm_info->default_ofdm_index;
+ } else if (delta_pwr_idx > pwr_idx_offset) {
+ agc_index = pwr_idx_offset;
+ swing_index = dm_info->default_ofdm_index +
+ delta_pwr_idx - pwr_idx_offset;
+ swing_index = min_t(u8, swing_index, swing_upper_bound);
+ }
+ } else if (delta_pwr_idx < 0) {
+ if (delta_pwr_idx >= pwr_idx_offset_lower) {
+ agc_index = delta_pwr_idx;
+ swing_index = dm_info->default_ofdm_index;
+ } else if (delta_pwr_idx < pwr_idx_offset_lower) {
+ if (dm_info->default_ofdm_index >
+ (pwr_idx_offset_lower - delta_pwr_idx))
+ swing_index = dm_info->default_ofdm_index +
+ delta_pwr_idx - pwr_idx_offset_lower;
+ else
+ swing_index = swing_lower_bound;
+
+ agc_index = pwr_idx_offset_lower;
+ }
+ }
+
+ if (swing_index >= ARRAY_SIZE(rtw8821c_txscale_tbl)) {
+ rtw_warn(rtwdev, "swing index overflow\n");
+ swing_index = ARRAY_SIZE(rtw8821c_txscale_tbl) - 1;
+ }
+
+ *txagc_idx = agc_index;
+ *swing_idx = swing_index;
+}
+
+static void rtw8821c_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 pwr_idx_offset,
+ s8 pwr_idx_offset_lower)
+{
+ s8 txagc_idx;
+ u8 swing_idx;
+
+ rtw8821c_txagc_swing_offset(rtwdev, pwr_idx_offset, pwr_idx_offset_lower,
+ &txagc_idx, &swing_idx);
+ rtw_write32_mask(rtwdev, REG_TXAGCIDX, GENMASK(6, 1), txagc_idx);
+ rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21),
+ rtw8821c_txscale_tbl[swing_idx]);
+}
+
+static void rtw8821c_pwrtrack_set(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 pwr_idx_offset, tx_pwr_idx;
+ s8 pwr_idx_offset_lower;
+ u8 channel = rtwdev->hal.current_channel;
+ u8 band_width = rtwdev->hal.current_band_width;
+ u8 regd = rtwdev->regd.txpwr_regd;
+ u8 tx_rate = dm_info->tx_rate;
+ u8 max_pwr_idx = rtwdev->chip->max_power_index;
+
+ tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, RF_PATH_A, tx_rate,
+ band_width, channel, regd);
+
+ tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx);
+
+ pwr_idx_offset = max_pwr_idx - tx_pwr_idx;
+ pwr_idx_offset_lower = 0 - tx_pwr_idx;
+
+ rtw8821c_pwrtrack_set_pwr(rtwdev, pwr_idx_offset, pwr_idx_offset_lower);
+}
+
+static void rtw8821c_phy_pwrtrack(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ struct rtw_swing_table swing_table;
+ u8 thermal_value, delta;
+
+ rtw_phy_config_swing_table(rtwdev, &swing_table);
+
+ if (rtwdev->efuse.thermal_meter[0] == 0xff)
+ return;
+
+ thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);
+
+ rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);
+
+ if (dm_info->pwr_trk_init_trigger)
+ dm_info->pwr_trk_init_trigger = false;
+ else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,
+ RF_PATH_A))
+ goto iqk;
+
+ delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);
+
+ delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1);
+
+ dm_info->delta_power_index[RF_PATH_A] =
+ rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, RF_PATH_A,
+ RF_PATH_A, delta);
+ if (dm_info->delta_power_index[RF_PATH_A] ==
+ dm_info->delta_power_index_last[RF_PATH_A])
+ goto iqk;
+ else
+ dm_info->delta_power_index_last[RF_PATH_A] =
+ dm_info->delta_power_index[RF_PATH_A];
+ rtw8821c_pwrtrack_set(rtwdev);
+
+iqk:
+ if (rtw_phy_pwrtrack_need_iqk(rtwdev))
+ rtw8821c_do_iqk(rtwdev);
+}
+
+static void rtw8821c_pwr_track(struct rtw_dev *rtwdev)
+{
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+ if (efuse->power_track_type != 0)
+ return;
+
+ if (!dm_info->pwr_trk_triggered) {
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
+ GENMASK(17, 16), 0x03);
+ dm_info->pwr_trk_triggered = true;
+ return;
+ }
+
+ rtw8821c_phy_pwrtrack(rtwdev);
+ dm_info->pwr_trk_triggered = false;
+}
+
+static void rtw8821c_bf_config_bfee_su(struct rtw_dev *rtwdev,
+ struct rtw_vif *vif,
+ struct rtw_bfee *bfee, bool enable)
+{
+ if (enable)
+ rtw_bf_enable_bfee_su(rtwdev, vif, bfee);
+ else
+ rtw_bf_remove_bfee_su(rtwdev, bfee);
+}
+
+static void rtw8821c_bf_config_bfee_mu(struct rtw_dev *rtwdev,
+ struct rtw_vif *vif,
+ struct rtw_bfee *bfee, bool enable)
+{
+ if (enable)
+ rtw_bf_enable_bfee_mu(rtwdev, vif, bfee);
+ else
+ rtw_bf_remove_bfee_mu(rtwdev, bfee);
+}
+
+static void rtw8821c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
+ struct rtw_bfee *bfee, bool enable)
+{
+ if (bfee->role == RTW_BFEE_SU)
+ rtw8821c_bf_config_bfee_su(rtwdev, vif, bfee, enable);
+ else if (bfee->role == RTW_BFEE_MU)
+ rtw8821c_bf_config_bfee_mu(rtwdev, vif, bfee, enable);
+ else
+ rtw_warn(rtwdev, "wrong bfee role\n");
+}
+
+static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 pd[CCK_PD_LV_MAX] = {3, 7, 13, 13, 13};
+
+ if (dm_info->min_rssi > 60) {
+ new_lvl = 4;
+ pd[4] = 0x1d;
+ goto set_cck_pd;
+ }
+
+ if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl)
+ return;
+
+ dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
+
+set_cck_pd:
+ dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl;
+ rtw_write32_mask(rtwdev, REG_PWRTH, 0x3f0000, pd[new_lvl]);
+ rtw_write32_mask(rtwdev, REG_PWRTH2, 0x1f0000,
+ dm_info->cck_pd_default + new_lvl * 2);
+}
+
+static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
+ {0x0086,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0086,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
+ {0x004A,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0},
+ {0x0300,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0},
+ {0x0301,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
+ {0x0020,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0001,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS},
+ {0x0000,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},
+ {0x0075,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0006,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
+ {0x0075,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0006,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(7), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0},
+ {0x10C3,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, BIT(0), 0},
+ {0x0020,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
+ {0x0074,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
+ {0x0022,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0062,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)),
+ (BIT(7) | BIT(6) | BIT(5))},
+ {0x0061,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 0},
+ {0x007C,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
+ {0x0093,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), 0},
+ {0x001F,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0},
+ {0x0049,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0006,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0002,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x10C3,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_POLLING, BIT(1), 0},
+ {0x0020,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3), 0},
+ {0x0000,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
+ {0x0007,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x20},
+ {0x0067,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
+ {0x004A,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0067,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(5), 0},
+ {0x0067,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(4), 0},
+ {0x004F,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(0), 0},
+ {0x0067,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0046,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
+ {0x0067,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(2), 0},
+ {0x0046,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},
+ {0x0062,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
+ {0x0081,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0},
+ {0x0005,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},
+ {0x0086,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
+ {0x0086,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_POLLING, BIT(1), 0},
+ {0x0090,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK,
+ RTW_PWR_ADDR_MAC,
+ RTW_PWR_CMD_WRITE, BIT(1), 0},
+ {0x0044,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_WRITE, 0xFF, 0},
+ {0x0040,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x90},
+ {0x0041,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x00},
+ {0x0042,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_SDIO_MSK,
+ RTW_PWR_ADDR_SDIO,
+ RTW_PWR_CMD_WRITE, 0xFF, 0x04},
+ {0xFFFF,
+ RTW_PWR_CUT_ALL_MSK,
+ RTW_PWR_INTF_ALL_MSK,
+ 0,
+ RTW_PWR_CMD_END, 0, 0},
+};
+
+static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = {
+ trans_carddis_to_cardemu_8821c,
+ trans_cardemu_to_act_8821c,
+ NULL
+};
+
+static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = {
+ trans_act_to_cardemu_8821c,
+ trans_cardemu_to_carddis_8821c,
+ NULL
+};
+
+static const struct rtw_intf_phy_para usb2_param_8821c[] = {
+ {0xFFFF, 0x00,
+ RTW_IP_SEL_PHY,
+ RTW_INTF_PHY_CUT_ALL,
+ RTW_INTF_PHY_PLATFORM_ALL},
+};
+
+static const struct rtw_intf_phy_para usb3_param_8821c[] = {
+ {0xFFFF, 0x0000,
+ RTW_IP_SEL_PHY,
+ RTW_INTF_PHY_CUT_ALL,
+ RTW_INTF_PHY_PLATFORM_ALL},
+};
+
+static const struct rtw_intf_phy_para pcie_gen1_param_8821c[] = {
+ {0x0009, 0x6380,
+ RTW_IP_SEL_PHY,
+ RTW_INTF_PHY_CUT_ALL,
+ RTW_INTF_PHY_PLATFORM_ALL},
+ {0xFFFF, 0x0000,
+ RTW_IP_SEL_PHY,
+ RTW_INTF_PHY_CUT_ALL,
+ RTW_INTF_PHY_PLATFORM_ALL},
+};
+
+static const struct rtw_intf_phy_para pcie_gen2_param_8821c[] = {
+ {0xFFFF, 0x0000,
+ RTW_IP_SEL_PHY,
+ RTW_INTF_PHY_CUT_ALL,
+ RTW_INTF_PHY_PLATFORM_ALL},
+};
+
+static const struct rtw_intf_phy_para_table phy_para_table_8821c = {
+ .usb2_para = usb2_param_8821c,
+ .usb3_para = usb3_param_8821c,
+ .gen1_para = pcie_gen1_param_8821c,
+ .gen2_para = pcie_gen2_param_8821c,
+ .n_usb2_para = ARRAY_SIZE(usb2_param_8821c),
+ .n_usb3_para = ARRAY_SIZE(usb2_param_8821c),
+ .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8821c),
+ .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c),
+};
+
+static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
+ [0] = RTW_DEF_RFE(8821c, 0, 0),
+};
+
+static struct rtw_hw_reg rtw8821c_dig[] = {
+ [0] = { .addr = 0xc50, .mask = 0x7f },
+};
+
+static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = {
+ .ctrl = LTECOEX_ACCESS_CTRL,
+ .wdata = LTECOEX_WRITE_DATA,
+ .rdata = LTECOEX_READ_DATA,
+};
+
+static struct rtw_page_table page_table_8821c[] = {
+ /* not sure what [0] stands for */
+ {16, 16, 16, 14, 1},
+ {16, 16, 16, 14, 1},
+ {16, 16, 0, 0, 1},
+ {16, 16, 16, 0, 1},
+ {16, 16, 16, 14, 1},
+};
+
+static struct rtw_rqpn rqpn_table_8821c[] = {
+ /* not sure what [0] stands for */
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH,
+ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
+ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
+ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
+ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
+};
+
+static struct rtw_prioq_addrs prioq_addrs_8821c = {
+ .prio[RTW_DMA_MAPPING_EXTRA] = {
+ .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
+ },
+ .prio[RTW_DMA_MAPPING_LOW] = {
+ .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2,
+ },
+ .prio[RTW_DMA_MAPPING_NORMAL] = {
+ .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2,
+ },
+ .prio[RTW_DMA_MAPPING_HIGH] = {
+ .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2,
+ },
+ .wsize = true,
+};
+
+static struct rtw_chip_ops rtw8821c_ops = {
+ .phy_set_param = rtw8821c_phy_set_param,
+ .read_efuse = rtw8821c_read_efuse,
+ .query_rx_desc = rtw8821c_query_rx_desc,
+ .set_channel = rtw8821c_set_channel,
+ .mac_init = rtw8821c_mac_init,
+ .read_rf = rtw_phy_read_rf,
+ .write_rf = rtw_phy_write_rf_reg_sipi,
+ .set_antenna = NULL,
+ .set_tx_power_index = rtw8821c_set_tx_power_index,
+ .cfg_ldo25 = rtw8821c_cfg_ldo25,
+ .false_alarm_statistics = rtw8821c_false_alarm_statistics,
+ .phy_calibration = rtw8821c_phy_calibration,
+ .cck_pd_set = rtw8821c_phy_cck_pd_set,
+ .pwr_track = rtw8821c_pwr_track,
+ .config_bfee = rtw8821c_bf_config_bfee,
+ .set_gid_table = rtw_bf_set_gid_table,
+ .cfg_csi_rate = rtw_bf_cfg_csi_rate,
+
+ .coex_set_init = rtw8821c_coex_cfg_init,
+ .coex_set_ant_switch = rtw8821c_coex_cfg_ant_switch,
+ .coex_set_gnt_fix = rtw8821c_coex_cfg_gnt_fix,
+ .coex_set_gnt_debug = rtw8821c_coex_cfg_gnt_debug,
+ .coex_set_rfe_type = rtw8821c_coex_cfg_rfe_type,
+ .coex_set_wl_tx_power = rtw8821c_coex_cfg_wl_tx_power,
+ .coex_set_wl_rx_gain = rtw8821c_coex_cfg_wl_rx_gain,
+};
+
+/* rssi in percentage % (dbm = % - 100) */
+static const u8 wl_rssi_step_8821c[] = {101, 45, 101, 40};
+static const u8 bt_rssi_step_8821c[] = {101, 101, 101, 101};
+
+/* Shared-Antenna Coex Table */
+static const struct coex_table_para table_sant_8821c[] = {
+ {0x55555555, 0x55555555}, /* case-0 */
+ {0x55555555, 0x55555555},
+ {0x66555555, 0x66555555},
+ {0xaaaaaaaa, 0xaaaaaaaa},
+ {0x5a5a5a5a, 0x5a5a5a5a},
+ {0xfafafafa, 0xfafafafa}, /* case-5 */
+ {0x6a5a5555, 0xaaaaaaaa},
+ {0x6a5a56aa, 0x6a5a56aa},
+ {0x6a5a5a5a, 0x6a5a5a5a},
+ {0x66555555, 0x5a5a5a5a},
+ {0x66555555, 0x6a5a5a5a}, /* case-10 */
+ {0x66555555, 0xaaaaaaaa},
+ {0x66555555, 0x6a5a5aaa},
+ {0x66555555, 0x6aaa6aaa},
+ {0x66555555, 0x6a5a5aaa},
+ {0x66555555, 0xaaaaaaaa}, /* case-15 */
+ {0xffff55ff, 0xfafafafa},
+ {0xffff55ff, 0x6afa5afa},
+ {0xaaffffaa, 0xfafafafa},
+ {0xaa5555aa, 0x5a5a5a5a},
+ {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
+ {0xaa5555aa, 0xaaaaaaaa},
+ {0xffffffff, 0x55555555},
+ {0xffffffff, 0x5a5a5a5a},
+ {0xffffffff, 0x5a5a5a5a},
+ {0xffffffff, 0x5a5a5aaa}, /* case-25 */
+ {0x55555555, 0x5a5a5a5a},
+ {0x55555555, 0xaaaaaaaa},
+ {0x66555555, 0x6a5a6a5a},
+ {0x66556655, 0x66556655},
+ {0x66556aaa, 0x6a5a6aaa}, /* case-30 */
+ {0xffffffff, 0x5aaa5aaa},
+ {0x56555555, 0x5a5a5aaa}
+};
+
+/* Non-Shared-Antenna Coex Table */
+static const struct coex_table_para table_nsant_8821c[] = {
+ {0xffffffff, 0xffffffff}, /* case-100 */
+ {0xffff55ff, 0xfafafafa},
+ {0x66555555, 0x66555555},
+ {0xaaaaaaaa, 0xaaaaaaaa},
+ {0x5a5a5a5a, 0x5a5a5a5a},
+ {0xffffffff, 0xffffffff}, /* case-105 */
+ {0x5afa5afa, 0x5afa5afa},
+ {0x55555555, 0xfafafafa},
+ {0x66555555, 0xfafafafa},
+ {0x66555555, 0x5a5a5a5a},
+ {0x66555555, 0x6a5a5a5a}, /* case-110 */
+ {0x66555555, 0xaaaaaaaa},
+ {0xffff55ff, 0xfafafafa},
+ {0xffff55ff, 0x5afa5afa},
+ {0xffff55ff, 0xaaaaaaaa},
+ {0xffff55ff, 0xffff55ff}, /* case-115 */
+ {0xaaffffaa, 0x5afa5afa},
+ {0xaaffffaa, 0xaaaaaaaa},
+ {0xffffffff, 0xfafafafa},
+ {0xffff55ff, 0xfafafafa},
+ {0xffffffff, 0xaaaaaaaa}, /* case-120 */
+ {0xffff55ff, 0x5afa5afa},
+ {0xffff55ff, 0x5afa5afa},
+ {0x55ff55ff, 0x55ff55ff}
+};
+
+/* Shared-Antenna TDMA */
+static const struct coex_tdma_para tdma_sant_8821c[] = {
+ { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
+ { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */
+ { {0x61, 0x3a, 0x03, 0x11, 0x11} },
+ { {0x61, 0x35, 0x03, 0x11, 0x11} },
+ { {0x61, 0x20, 0x03, 0x11, 0x11} },
+ { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */
+ { {0x61, 0x45, 0x03, 0x11, 0x10} },
+ { {0x61, 0x35, 0x03, 0x11, 0x10} },
+ { {0x61, 0x30, 0x03, 0x11, 0x10} },
+ { {0x61, 0x20, 0x03, 0x11, 0x10} },
+ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
+ { {0x61, 0x08, 0x03, 0x11, 0x15} },
+ { {0x61, 0x08, 0x03, 0x10, 0x14} },
+ { {0x51, 0x08, 0x03, 0x10, 0x54} },
+ { {0x51, 0x08, 0x03, 0x10, 0x55} },
+ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */
+ { {0x51, 0x45, 0x03, 0x10, 0x50} },
+ { {0x51, 0x3a, 0x03, 0x11, 0x50} },
+ { {0x51, 0x30, 0x03, 0x10, 0x50} },
+ { {0x51, 0x21, 0x03, 0x10, 0x50} },
+ { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */
+ { {0x51, 0x4a, 0x03, 0x10, 0x50} },
+ { {0x51, 0x08, 0x03, 0x30, 0x54} },
+ { {0x55, 0x08, 0x03, 0x10, 0x54} },
+ { {0x65, 0x10, 0x03, 0x11, 0x10} },
+ { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
+ { {0x51, 0x21, 0x03, 0x10, 0x50} },
+ { {0x61, 0x08, 0x03, 0x11, 0x11} }
+};
+
+/* Non-Shared-Antenna TDMA */
+static const struct coex_tdma_para tdma_nsant_8821c[] = {
+ { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */
+ { {0x61, 0x45, 0x03, 0x11, 0x11} },
+ { {0x61, 0x25, 0x03, 0x11, 0x11} },
+ { {0x61, 0x35, 0x03, 0x11, 0x11} },
+ { {0x61, 0x20, 0x03, 0x11, 0x11} },
+ { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
+ { {0x61, 0x45, 0x03, 0x11, 0x10} },
+ { {0x61, 0x30, 0x03, 0x11, 0x10} },
+ { {0x61, 0x30, 0x03, 0x11, 0x10} },
+ { {0x61, 0x20, 0x03, 0x11, 0x10} },
+ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
+ { {0x61, 0x10, 0x03, 0x11, 0x11} },
+ { {0x61, 0x08, 0x03, 0x10, 0x14} },
+ { {0x51, 0x08, 0x03, 0x10, 0x54} },
+ { {0x51, 0x08, 0x03, 0x10, 0x55} },
+ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
+ { {0x51, 0x45, 0x03, 0x10, 0x50} },
+ { {0x51, 0x3a, 0x03, 0x10, 0x50} },
+ { {0x51, 0x30, 0x03, 0x10, 0x50} },
+ { {0x51, 0x21, 0x03, 0x10, 0x50} },
+ { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */
+ { {0x51, 0x10, 0x03, 0x10, 0x50} }
+};
+
+static const struct coex_5g_afh_map afh_5g_8821c[] = { {0, 0, 0} };
+
+/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */
+static const struct coex_rf_para rf_para_tx_8821c[] = {
+ {0, 0, false, 7}, /* for normal */
+ {0, 20, false, 7}, /* for WL-CPT */
+ {8, 17, true, 4},
+ {7, 18, true, 4},
+ {6, 19, true, 4},
+ {5, 20, true, 4}
+};
+
+static const struct coex_rf_para rf_para_rx_8821c[] = {
+ {0, 0, false, 7}, /* for normal */
+ {0, 20, false, 7}, /* for WL-CPT */
+ {3, 24, true, 5},
+ {2, 26, true, 5},
+ {1, 27, true, 5},
+ {0, 28, true, 5}
+};
+
+static_assert(ARRAY_SIZE(rf_para_tx_8821c) == ARRAY_SIZE(rf_para_rx_8821c));
+
+static const u8 rtw8821c_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10,
+ 11, 11, 12, 12, 12, 12, 12},
+ {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11,
+ 11, 12, 12, 12, 12, 12, 12, 12},
+ {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11,
+ 11, 12, 12, 12, 12, 12, 12},
+};
+
+static const u8 rtw8821c_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12},
+ {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11,
+ 11, 12, 12, 12, 12, 12, 12, 12},
+};
+
+static const u8 rtw8821c_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10,
+ 11, 11, 12, 12, 12, 12, 12},
+ {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11,
+ 11, 12, 12, 12, 12, 12, 12, 12},
+ {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11,
+ 11, 12, 12, 12, 12, 12, 12},
+};
+
+static const u8 rtw8821c_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = {
+ {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12},
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12},
+ {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11,
+ 11, 12, 12, 12, 12, 12, 12, 12},
+};
+
+static const u8 rtw8821c_pwrtrk_2gb_n[] = {
+ 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4,
+ 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9
+};
+
+static const u8 rtw8821c_pwrtrk_2gb_p[] = {
+ 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5,
+ 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9
+};
+
+static const u8 rtw8821c_pwrtrk_2ga_n[] = {
+ 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4,
+ 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9
+};
+
+static const u8 rtw8821c_pwrtrk_2ga_p[] = {
+ 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5,
+ 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9
+};
+
+static const u8 rtw8821c_pwrtrk_2g_cck_b_n[] = {
+ 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9
+};
+
+static const u8 rtw8821c_pwrtrk_2g_cck_b_p[] = {
+ 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5,
+ 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9
+};
+
+static const u8 rtw8821c_pwrtrk_2g_cck_a_n[] = {
+ 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9
+};
+
+static const u8 rtw8821c_pwrtrk_2g_cck_a_p[] = {
+ 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5,
+ 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9
+};
+
+static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = {
+ .pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0],
+ .pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1],
+ .pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2],
+ .pwrtrk_5gb_p[0] = rtw8821c_pwrtrk_5gb_p[0],
+ .pwrtrk_5gb_p[1] = rtw8821c_pwrtrk_5gb_p[1],
+ .pwrtrk_5gb_p[2] = rtw8821c_pwrtrk_5gb_p[2],
+ .pwrtrk_5ga_n[0] = rtw8821c_pwrtrk_5ga_n[0],
+ .pwrtrk_5ga_n[1] = rtw8821c_pwrtrk_5ga_n[1],
+ .pwrtrk_5ga_n[2] = rtw8821c_pwrtrk_5ga_n[2],
+ .pwrtrk_5ga_p[0] = rtw8821c_pwrtrk_5ga_p[0],
+ .pwrtrk_5ga_p[1] = rtw8821c_pwrtrk_5ga_p[1],
+ .pwrtrk_5ga_p[2] = rtw8821c_pwrtrk_5ga_p[2],
+ .pwrtrk_2gb_n = rtw8821c_pwrtrk_2gb_n,
+ .pwrtrk_2gb_p = rtw8821c_pwrtrk_2gb_p,
+ .pwrtrk_2ga_n = rtw8821c_pwrtrk_2ga_n,
+ .pwrtrk_2ga_p = rtw8821c_pwrtrk_2ga_p,
+ .pwrtrk_2g_cckb_n = rtw8821c_pwrtrk_2g_cck_b_n,
+ .pwrtrk_2g_cckb_p = rtw8821c_pwrtrk_2g_cck_b_p,
+ .pwrtrk_2g_ccka_n = rtw8821c_pwrtrk_2g_cck_a_n,
+ .pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p,
+};
+
+static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = {
+ {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+ {0, 0, RTW_REG_DOMAIN_NL},
+ {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
+ {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+ {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
+ {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16},
+ {0, 0, RTW_REG_DOMAIN_NL},
+ {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32},
+ {0x64, BIT(0), RTW_REG_DOMAIN_MAC8},
+ {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
+ {0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
+ {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A},
+ {0, 0, RTW_REG_DOMAIN_NL},
+ {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
+ {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+ {0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
+ {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+ {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
+};
+
+struct rtw_chip_info rtw8821c_hw_spec = {
+ .ops = &rtw8821c_ops,
+ .id = RTW_CHIP_TYPE_8821C,
+ .fw_name = "rtw88/rtw8821c_fw.bin",
+ .wlan_cpu = RTW_WCPU_11AC,
+ .tx_pkt_desc_sz = 48,
+ .tx_buf_desc_sz = 16,
+ .rx_pkt_desc_sz = 24,
+ .rx_buf_desc_sz = 8,
+ .phy_efuse_size = 512,
+ .log_efuse_size = 512,
+ .ptct_efuse_size = 96,
+ .txff_size = 65536,
+ .rxff_size = 16384,
+ .txgi_factor = 1,
+ .is_pwr_by_rate_dec = true,
+ .max_power_index = 0x3f,
+ .csi_buf_pg_num = 0,
+ .band = RTW_BAND_2G | RTW_BAND_5G,
+ .page_size = 128,
+ .dig_min = 0x1c,
+ .ht_supported = true,
+ .vht_supported = true,
+ .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
+ .sys_func_en = 0xD8,
+ .pwr_on_seq = card_enable_flow_8821c,
+ .pwr_off_seq = card_disable_flow_8821c,
+ .page_table = page_table_8821c,
+ .rqpn_table = rqpn_table_8821c,
+ .prioq_addrs = &prioq_addrs_8821c,
+ .intf_table = &phy_para_table_8821c,
+ .dig = rtw8821c_dig,
+ .rf_base_addr = {0x2800, 0x2c00},
+ .rf_sipi_addr = {0xc90, 0xe90},
+ .ltecoex_addr = &rtw8821c_ltecoex_addr,
+ .mac_tbl = &rtw8821c_mac_tbl,
+ .agc_tbl = &rtw8821c_agc_tbl,
+ .bb_tbl = &rtw8821c_bb_tbl,
+ .rf_tbl = {&rtw8821c_rf_a_tbl},
+ .rfe_defs = rtw8821c_rfe_defs,
+ .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs),
+ .rx_ldpc = false,
+ .pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl,
+ .iqk_threshold = 8,
+ .bfer_su_max_num = 2,
+ .bfer_mu_max_num = 1,
+
+ .coex_para_ver = 0x19092746,
+ .bt_desired_ver = 0x46,
+ .scbd_support = true,
+ .new_scbd10_def = false,
+ .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
+ .bt_rssi_type = COEX_BTRSSI_RATIO,
+ .ant_isolation = 15,
+ .rssi_tolerance = 2,
+ .wl_rssi_step = wl_rssi_step_8821c,
+ .bt_rssi_step = bt_rssi_step_8821c,
+ .table_sant_num = ARRAY_SIZE(table_sant_8821c),
+ .table_sant = table_sant_8821c,
+ .table_nsant_num = ARRAY_SIZE(table_nsant_8821c),
+ .table_nsant = table_nsant_8821c,
+ .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821c),
+ .tdma_sant = tdma_sant_8821c,
+ .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821c),
+ .tdma_nsant = tdma_nsant_8821c,
+ .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821c),
+ .wl_rf_para_tx = rf_para_tx_8821c,
+ .wl_rf_para_rx = rf_para_rx_8821c,
+ .bt_afh_span_bw20 = 0x24,
+ .bt_afh_span_bw40 = 0x36,
+ .afh_5g_num = ARRAY_SIZE(afh_5g_8821c),
+ .afh_5g = afh_5g_8821c,
+
+ .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821c),
+ .coex_info_hw_regs = coex_info_hw_regs_8821c,
+};
+EXPORT_SYMBOL(rtw8821c_hw_spec);
+
+MODULE_FIRMWARE("rtw88/rtw8821c_fw.bin");
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821c driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h
new file mode 100644
index 000000000000..bd01e82b6bcd
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h
@@ -0,0 +1,259 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#ifndef __RTW8821C_H__
+#define __RTW8821C_H__
+
+#include <asm/byteorder.h>
+
+#define RCR_VHT_ACK BIT(26)
+
+struct rtw8821ce_efuse {
+ u8 mac_addr[ETH_ALEN]; /* 0xd0 */
+ u8 vender_id[2];
+ u8 device_id[2];
+ u8 sub_vender_id[2];
+ u8 sub_device_id[2];
+ u8 pmc[2];
+ u8 exp_device_cap[2];
+ u8 msi_cap;
+ u8 ltr_cap; /* 0xe3 */
+ u8 exp_link_control[2];
+ u8 link_cap[4];
+ u8 link_control[2];
+ u8 serial_number[8];
+ u8 res0:2; /* 0xf4 */
+ u8 ltr_en:1;
+ u8 res1:2;
+ u8 obff:2;
+ u8 res2:3;
+ u8 obff_cap:2;
+ u8 res3:4;
+ u8 res4[3];
+ u8 class_code[3];
+ u8 pci_pm_L1_2_supp:1;
+ u8 pci_pm_L1_1_supp:1;
+ u8 aspm_pm_L1_2_supp:1;
+ u8 aspm_pm_L1_1_supp:1;
+ u8 L1_pm_substates_supp:1;
+ u8 res5:3;
+ u8 port_common_mode_restore_time;
+ u8 port_t_power_on_scale:2;
+ u8 res6:1;
+ u8 port_t_power_on_value:5;
+ u8 res7;
+};
+
+struct rtw8821c_efuse {
+ __le16 rtl_id;
+ u8 res0[0x0e];
+
+ /* power index for four RF paths */
+ struct rtw_txpwr_idx txpwr_idx_table[4];
+
+ u8 channel_plan; /* 0xb8 */
+ u8 xtal_k;
+ u8 thermal_meter;
+ u8 iqk_lck;
+ u8 pa_type; /* 0xbc */
+ u8 lna_type_2g[2]; /* 0xbd */
+ u8 lna_type_5g[2];
+ u8 rf_board_option;
+ u8 rf_feature_option;
+ u8 rf_bt_setting;
+ u8 eeprom_version;
+ u8 eeprom_customer_id;
+ u8 tx_bb_swing_setting_2g;
+ u8 tx_bb_swing_setting_5g;
+ u8 tx_pwr_calibrate_rate;
+ u8 rf_antenna_option; /* 0xc9 */
+ u8 rfe_option;
+ u8 country_code[2];
+ u8 res[3];
+ union {
+ struct rtw8821ce_efuse e;
+ };
+};
+
+static inline void
+_rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
+{
+ /* 0xC00-0xCFF and 0xE00-0xEFF have the same layout */
+ rtw_write32_mask(rtwdev, addr, mask, data);
+ rtw_write32_mask(rtwdev, addr + 0x200, mask, data);
+}
+
+#define rtw_write32s_mask(rtwdev, addr, mask, data) \
+ do { \
+ BUILD_BUG_ON((addr) < 0xC00 || (addr) >= 0xD00); \
+ \
+ _rtw_write32s_mask(rtwdev, addr, mask, data); \
+ } while (0)
+
+#define BIT_FEN_PCIEA BIT(6)
+#define WLAN_SLOT_TIME 0x09
+#define WLAN_PIFS_TIME 0x19
+#define WLAN_SIFS_CCK_CONT_TX 0xA
+#define WLAN_SIFS_OFDM_CONT_TX 0xE
+#define WLAN_SIFS_CCK_TRX 0x10
+#define WLAN_SIFS_OFDM_TRX 0x10
+#define WLAN_VO_TXOP_LIMIT 0x186
+#define WLAN_VI_TXOP_LIMIT 0x3BC
+#define WLAN_RDG_NAV 0x05
+#define WLAN_TXOP_NAV 0x1B
+#define WLAN_CCK_RX_TSF 0x30
+#define WLAN_OFDM_RX_TSF 0x30
+#define WLAN_TBTT_PROHIBIT 0x04
+#define WLAN_TBTT_HOLD_TIME 0x064
+#define WLAN_DRV_EARLY_INT 0x04
+#define WLAN_BCN_DMA_TIME 0x02
+
+#define WLAN_RX_FILTER0 0x0FFFFFFF
+#define WLAN_RX_FILTER2 0xFFFF
+#define WLAN_RCR_CFG 0xE400220E
+#define WLAN_RXPKT_MAX_SZ 12288
+#define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9)
+
+#define WLAN_AMPDU_MAX_TIME 0x70
+#define WLAN_RTS_LEN_TH 0xFF
+#define WLAN_RTS_TX_TIME_TH 0x08
+#define WLAN_MAX_AGG_PKT_LIMIT 0x20
+#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x20
+#define FAST_EDCA_VO_TH 0x06
+#define FAST_EDCA_VI_TH 0x06
+#define FAST_EDCA_BE_TH 0x06
+#define FAST_EDCA_BK_TH 0x06
+#define WLAN_BAR_RETRY_LIMIT 0x01
+#define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08
+
+#define WLAN_TX_FUNC_CFG1 0x30
+#define WLAN_TX_FUNC_CFG2 0x30
+#define WLAN_MAC_OPT_NORM_FUNC1 0x98
+#define WLAN_MAC_OPT_LB_FUNC1 0x80
+#define WLAN_MAC_OPT_FUNC2 0x30810041
+
+#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \
+ (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \
+ (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \
+ (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX))
+
+#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\
+ (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP))
+
+#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16))
+#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8)
+#define WLAN_PRE_TXCNT_TIME_TH 0x1E4
+
+/* phy status page0 */
+#define GET_PHY_STAT_P0_PWDB(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8))
+
+/* phy status page1 */
+#define GET_PHY_STAT_P1_PWDB_A(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8))
+#define GET_PHY_STAT_P1_PWDB_B(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(23, 16))
+#define GET_PHY_STAT_P1_RF_MODE(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x03), GENMASK(29, 28))
+#define GET_PHY_STAT_P1_L_RXSC(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8))
+#define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12))
+#define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0))
+#define GET_PHY_STAT_P1_RXEVM_B(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(15, 8))
+#define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0))
+#define GET_PHY_STAT_P1_CFO_TAIL_B(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(15, 8))
+#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0))
+#define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8))
+
+#define REG_INIRTS_RATE_SEL 0x0480
+#define REG_HTSTFWT 0x800
+#define REG_RXPSEL 0x808
+#define BIT_RX_PSEL_RST (BIT(28) | BIT(29))
+#define REG_TXPSEL 0x80c
+#define REG_RXCCAMSK 0x814
+#define REG_CCASEL 0x82c
+#define REG_PDMFTH 0x830
+#define REG_CCA2ND 0x838
+#define REG_L1WT 0x83c
+#define REG_L1PKWT 0x840
+#define REG_MRC 0x850
+#define REG_CLKTRK 0x860
+#define REG_ADCCLK 0x8ac
+#define REG_ADC160 0x8c4
+#define REG_ADC40 0x8c8
+#define REG_CHFIR 0x8f0
+#define REG_CDDTXP 0x93c
+#define REG_TXPSEL1 0x940
+#define REG_ACBB0 0x948
+#define REG_ACBBRXFIR 0x94c
+#define REG_ACGG2TBL 0x958
+#define REG_FAS 0x9a4
+#define REG_RXSB 0xa00
+#define REG_ADCINI 0xa04
+#define REG_PWRTH 0xa08
+#define REG_TXSF2 0xa24
+#define REG_TXSF6 0xa28
+#define REG_FA_CCK 0xa5c
+#define REG_RXDESC 0xa2c
+#define REG_ENTXCCK 0xa80
+#define REG_PWRTH2 0xaa8
+#define REG_CSRATIO 0xaaa
+#define REG_TXFILTER 0xaac
+#define REG_CNTRST 0xb58
+#define REG_AGCTR_A 0xc08
+#define REG_TXSCALE_A 0xc1c
+#define REG_TXDFIR 0xc20
+#define REG_RXIGI_A 0xc50
+#define REG_TXAGCIDX 0xc94
+#define REG_TRSW 0xca0
+#define REG_RFESEL0 0xcb0
+#define REG_RFESEL8 0xcb4
+#define REG_RFECTL 0xcb8
+#define REG_RFEINV 0xcbc
+#define REG_AGCTR_B 0xe08
+#define REG_RXIGI_B 0xe50
+#define REG_CRC_CCK 0xf04
+#define REG_CRC_OFDM 0xf14
+#define REG_CRC_HT 0xf10
+#define REG_CRC_VHT 0xf0c
+#define REG_CCA_OFDM 0xf08
+#define REG_FA_OFDM 0xf48
+#define REG_CCA_CCK 0xfcc
+#define REG_ANTWT 0x1904
+#define REG_IQKFAILMSK 0x1bf0
+#define BIT_MASK_R_RFE_SEL_15 GENMASK(31, 28)
+#define BIT_SDIO_INT BIT(18)
+#define SAMPLE_RATE_MASK GENMASK(5, 0)
+#define SAMPLE_RATE 0x5
+#define BT_CNT_ENABLE 0x1
+#define BIT_BCN_QUEUE BIT(3)
+#define BCN_PRI_EN 0x1
+#define PTA_CTRL_PIN 0x66
+#define DPDT_CTRL_PIN 0x77
+#define ANTDIC_CTRL_PIN 0x88
+#define REG_CTRL_TYPE 0x67
+#define BIT_CTRL_TYPE1 BIT(5)
+#define BIT_CTRL_TYPE2 BIT(4)
+#define CTRL_TYPE_MASK GENMASK(15, 8)
+
+#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8))
+#define RF18_BAND_2G (0)
+#define RF18_BAND_5G (BIT(16) | BIT(8))
+#define RF18_CHANNEL_MASK (MASKBYTE0)
+#define RF18_RFSI_MASK (BIT(18) | BIT(17))
+#define RF18_RFSI_GE (BIT(17))
+#define RF18_RFSI_GT (BIT(18))
+#define RF18_BW_MASK (BIT(11) | BIT(10))
+#define RF18_BW_20M (BIT(11) | BIT(10))
+#define RF18_BW_40M (BIT(11))
+#define RF18_BW_80M (BIT(10))
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c
new file mode 100644
index 000000000000..970f903f7dc7
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.c
@@ -0,0 +1,6611 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#include "main.h"
+#include "phy.h"
+#include "rtw8821c_table.h"
+
+static const u32 rtw8821c_mac[] = {
+ 0x010, 0x00000043,
+ 0x025, 0x0000001D,
+ 0x026, 0x000000CE,
+ 0x04F, 0x00000001,
+ 0x029, 0x000000F9,
+ 0x420, 0x00000080,
+ 0x421, 0x0000000F,
+ 0x428, 0x0000000A,
+ 0x429, 0x00000010,
+ 0x430, 0x00000000,
+ 0x431, 0x00000000,
+ 0x432, 0x00000000,
+ 0x433, 0x00000001,
+ 0x434, 0x00000004,
+ 0x435, 0x00000005,
+ 0x436, 0x00000007,
+ 0x437, 0x00000008,
+ 0x43C, 0x00000004,
+ 0x43D, 0x00000005,
+ 0x43E, 0x00000007,
+ 0x43F, 0x00000008,
+ 0x440, 0x0000005D,
+ 0x441, 0x00000001,
+ 0x442, 0x00000000,
+ 0x444, 0x00000010,
+ 0x445, 0x000000F0,
+ 0x446, 0x00000001,
+ 0x447, 0x000000FE,
+ 0x448, 0x00000000,
+ 0x449, 0x00000000,
+ 0x44A, 0x00000000,
+ 0x44B, 0x00000040,
+ 0x44C, 0x00000010,
+ 0x44D, 0x000000F0,
+ 0x44E, 0x0000003F,
+ 0x44F, 0x00000000,
+ 0x450, 0x00000000,
+ 0x451, 0x00000000,
+ 0x452, 0x00000000,
+ 0x453, 0x00000040,
+ 0x455, 0x00000070,
+ 0x45E, 0x00000004,
+ 0x49C, 0x00000010,
+ 0x49D, 0x000000F0,
+ 0x49E, 0x00000000,
+ 0x49F, 0x00000006,
+ 0x4A0, 0x000000E0,
+ 0x4A1, 0x00000003,
+ 0x4A2, 0x00000000,
+ 0x4A3, 0x00000040,
+ 0x4A4, 0x00000015,
+ 0x4A5, 0x000000F0,
+ 0x4A6, 0x00000000,
+ 0x4A7, 0x00000006,
+ 0x4A8, 0x000000E0,
+ 0x4A9, 0x00000000,
+ 0x4AA, 0x00000000,
+ 0x4AB, 0x00000000,
+ 0x7DA, 0x00000008,
+ 0x1448, 0x00000006,
+ 0x144A, 0x00000006,
+ 0x144C, 0x00000006,
+ 0x144E, 0x00000006,
+ 0x4C8, 0x000000FF,
+ 0x4C9, 0x00000008,
+ 0x4CC, 0x000000FF,
+ 0x4CD, 0x000000FF,
+ 0x4CE, 0x00000001,
+ 0x4CF, 0x00000008,
+ 0x500, 0x00000026,
+ 0x501, 0x000000A2,
+ 0x502, 0x0000002F,
+ 0x503, 0x00000000,
+ 0x504, 0x00000028,
+ 0x505, 0x000000A3,
+ 0x506, 0x0000005E,
+ 0x507, 0x00000000,
+ 0x508, 0x0000002B,
+ 0x509, 0x000000A4,
+ 0x50A, 0x0000005E,
+ 0x50B, 0x00000000,
+ 0x50C, 0x0000004F,
+ 0x50D, 0x000000A4,
+ 0x50E, 0x00000000,
+ 0x50F, 0x00000000,
+ 0x512, 0x0000001C,
+ 0x514, 0x0000000A,
+ 0x516, 0x0000000A,
+ 0x521, 0x0000002F,
+ 0x525, 0x0000004F,
+ 0x551, 0x00000010,
+ 0x559, 0x00000002,
+ 0x55C, 0x00000050,
+ 0x55D, 0x000000FF,
+ 0x577, 0x0000000B,
+ 0x578, 0x00000014,
+ 0x579, 0x00000014,
+ 0x57A, 0x00000014,
+ 0x5BE, 0x00000064,
+ 0x605, 0x00000030,
+ 0x608, 0x0000000E,
+ 0x609, 0x00000022,
+ 0x60C, 0x00000018,
+ 0x6A0, 0x000000FF,
+ 0x6A1, 0x000000FF,
+ 0x6A2, 0x000000FF,
+ 0x6A3, 0x000000FF,
+ 0x6A4, 0x000000FF,
+ 0x6A5, 0x000000FF,
+ 0x6DE, 0x00000084,
+ 0x620, 0x000000FF,
+ 0x621, 0x000000FF,
+ 0x622, 0x000000FF,
+ 0x623, 0x000000FF,
+ 0x624, 0x000000FF,
+ 0x625, 0x000000FF,
+ 0x626, 0x000000FF,
+ 0x627, 0x000000FF,
+ 0x638, 0x00000050,
+ 0x63C, 0x0000000A,
+ 0x63D, 0x0000000A,
+ 0x63E, 0x0000000E,
+ 0x63F, 0x0000000E,
+ 0x640, 0x00000040,
+ 0x642, 0x00000040,
+ 0x643, 0x00000000,
+ 0x652, 0x000000C8,
+ 0x66E, 0x00000005,
+ 0x700, 0x00000021,
+ 0x701, 0x00000043,
+ 0x702, 0x00000065,
+ 0x703, 0x00000087,
+ 0x708, 0x00000021,
+ 0x709, 0x00000043,
+ 0x70A, 0x00000065,
+ 0x70B, 0x00000087,
+ 0x718, 0x00000040,
+ 0x7D4, 0x00000098,
+
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8821c_mac, rtw_phy_cfg_mac);
+
+static const u32 rtw8821c_agc[] = {
+ 0x80001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFB000003,
+ 0x81C, 0xFA020003,
+ 0x81C, 0xF9040003,
+ 0x81C, 0xF8060003,
+ 0x81C, 0xF7080003,
+ 0x81C, 0xF60A0003,
+ 0x81C, 0xF50C0003,
+ 0x81C, 0xF40E0003,
+ 0x81C, 0xF3100003,
+ 0x81C, 0xF2120003,
+ 0x81C, 0xF1140003,
+ 0x81C, 0xF0160003,
+ 0x81C, 0xEF180003,
+ 0x81C, 0xEE1A0003,
+ 0x81C, 0xED1C0003,
+ 0x81C, 0xEC1E0003,
+ 0x81C, 0xEB200003,
+ 0x81C, 0xEA220003,
+ 0x81C, 0xE9240003,
+ 0x81C, 0xE8260003,
+ 0x81C, 0xE7280003,
+ 0x81C, 0xE62A0003,
+ 0x81C, 0xE52C0003,
+ 0x81C, 0xE42E0003,
+ 0x81C, 0xE3300003,
+ 0x81C, 0xE2320003,
+ 0x81C, 0xE1340003,
+ 0x81C, 0xC4360003,
+ 0x81C, 0xC3380003,
+ 0x81C, 0xC23A0003,
+ 0x81C, 0xC13C0003,
+ 0x81C, 0x883E0003,
+ 0x81C, 0x87400003,
+ 0x81C, 0x86420003,
+ 0x81C, 0x85440003,
+ 0x81C, 0x84460003,
+ 0x81C, 0x83480003,
+ 0x81C, 0x824A0003,
+ 0x81C, 0x814C0003,
+ 0x81C, 0x804E0003,
+ 0x81C, 0x64500003,
+ 0x81C, 0x63520003,
+ 0x81C, 0x62540003,
+ 0x81C, 0x61560003,
+ 0x81C, 0x60580003,
+ 0x81C, 0x475A0003,
+ 0x81C, 0x465C0003,
+ 0x81C, 0x455E0003,
+ 0x81C, 0x44600003,
+ 0x81C, 0x43620003,
+ 0x81C, 0x42640003,
+ 0x81C, 0x41660003,
+ 0x81C, 0x40680003,
+ 0x81C, 0x236A0003,
+ 0x81C, 0x226C0003,
+ 0x81C, 0x056E0003,
+ 0x81C, 0x04700003,
+ 0x81C, 0x03720003,
+ 0x81C, 0x02740003,
+ 0x81C, 0x01760003,
+ 0x81C, 0x01780003,
+ 0x81C, 0x017A0003,
+ 0x81C, 0x017C0003,
+ 0x81C, 0x017E0003,
+ 0x90001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFB000003,
+ 0x81C, 0xFA020003,
+ 0x81C, 0xF9040003,
+ 0x81C, 0xF8060003,
+ 0x81C, 0xF7080003,
+ 0x81C, 0xF60A0003,
+ 0x81C, 0xF50C0003,
+ 0x81C, 0xF40E0003,
+ 0x81C, 0xF3100003,
+ 0x81C, 0xF2120003,
+ 0x81C, 0xF1140003,
+ 0x81C, 0xF0160003,
+ 0x81C, 0xEF180003,
+ 0x81C, 0xEE1A0003,
+ 0x81C, 0xED1C0003,
+ 0x81C, 0xEC1E0003,
+ 0x81C, 0xEB200003,
+ 0x81C, 0xEA220003,
+ 0x81C, 0xE9240003,
+ 0x81C, 0xE8260003,
+ 0x81C, 0xE7280003,
+ 0x81C, 0xE62A0003,
+ 0x81C, 0xE52C0003,
+ 0x81C, 0xE42E0003,
+ 0x81C, 0xE3300003,
+ 0x81C, 0xE2320003,
+ 0x81C, 0xE1340003,
+ 0x81C, 0xC4360003,
+ 0x81C, 0xC3380003,
+ 0x81C, 0xC23A0003,
+ 0x81C, 0xC13C0003,
+ 0x81C, 0x883E0003,
+ 0x81C, 0x87400003,
+ 0x81C, 0x86420003,
+ 0x81C, 0x85440003,
+ 0x81C, 0x84460003,
+ 0x81C, 0x83480003,
+ 0x81C, 0x824A0003,
+ 0x81C, 0x814C0003,
+ 0x81C, 0x804E0003,
+ 0x81C, 0x64500003,
+ 0x81C, 0x63520003,
+ 0x81C, 0x62540003,
+ 0x81C, 0x61560003,
+ 0x81C, 0x60580003,
+ 0x81C, 0x475A0003,
+ 0x81C, 0x465C0003,
+ 0x81C, 0x455E0003,
+ 0x81C, 0x44600003,
+ 0x81C, 0x43620003,
+ 0x81C, 0x42640003,
+ 0x81C, 0x41660003,
+ 0x81C, 0x40680003,
+ 0x81C, 0x236A0003,
+ 0x81C, 0x226C0003,
+ 0x81C, 0x056E0003,
+ 0x81C, 0x04700003,
+ 0x81C, 0x03720003,
+ 0x81C, 0x02740003,
+ 0x81C, 0x01760003,
+ 0x81C, 0x01780003,
+ 0x81C, 0x017A0003,
+ 0x81C, 0x017C0003,
+ 0x81C, 0x017E0003,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0xFB000003,
+ 0x81C, 0xFA020003,
+ 0x81C, 0xF9040003,
+ 0x81C, 0xF8060003,
+ 0x81C, 0xF7080003,
+ 0x81C, 0xF60A0003,
+ 0x81C, 0xF50C0003,
+ 0x81C, 0xF40E0003,
+ 0x81C, 0xF3100003,
+ 0x81C, 0xF2120003,
+ 0x81C, 0xF1140003,
+ 0x81C, 0xF0160003,
+ 0x81C, 0xEF180003,
+ 0x81C, 0xEE1A0003,
+ 0x81C, 0xED1C0003,
+ 0x81C, 0xEC1E0003,
+ 0x81C, 0xEB200003,
+ 0x81C, 0xEA220003,
+ 0x81C, 0xE9240003,
+ 0x81C, 0xE8260003,
+ 0x81C, 0xE7280003,
+ 0x81C, 0xE62A0003,
+ 0x81C, 0xCA2C0003,
+ 0x81C, 0xC92E0003,
+ 0x81C, 0xC8300003,
+ 0x81C, 0xC7320003,
+ 0x81C, 0xC6340003,
+ 0x81C, 0xC5360003,
+ 0x81C, 0xC4380003,
+ 0x81C, 0xC33A0003,
+ 0x81C, 0xC23C0003,
+ 0x81C, 0xC13E0003,
+ 0x81C, 0x88400003,
+ 0x81C, 0x87420003,
+ 0x81C, 0x86440003,
+ 0x81C, 0x85460003,
+ 0x81C, 0x84480003,
+ 0x81C, 0x834A0003,
+ 0x81C, 0x674C0003,
+ 0x81C, 0x664E0003,
+ 0x81C, 0x65500003,
+ 0x81C, 0x64520003,
+ 0x81C, 0x63540003,
+ 0x81C, 0x62560003,
+ 0x81C, 0x61580003,
+ 0x81C, 0x455A0003,
+ 0x81C, 0x445C0003,
+ 0x81C, 0x435E0003,
+ 0x81C, 0x42600003,
+ 0x81C, 0x41620003,
+ 0x81C, 0x25640003,
+ 0x81C, 0x24660003,
+ 0x81C, 0x23680003,
+ 0x81C, 0x226A0003,
+ 0x81C, 0x216C0003,
+ 0x81C, 0x016E0003,
+ 0x81C, 0x01700003,
+ 0x81C, 0x01720003,
+ 0x81C, 0x01740003,
+ 0x81C, 0x01760003,
+ 0x81C, 0x01780003,
+ 0x81C, 0x017A0003,
+ 0x81C, 0x017C0003,
+ 0x81C, 0x017E0003,
+ 0xB0000000, 0x00000000,
+ 0x80001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFD000103,
+ 0x81C, 0xFC020103,
+ 0x81C, 0xFB040103,
+ 0x81C, 0xFA060103,
+ 0x81C, 0xF9080103,
+ 0x81C, 0xF80A0103,
+ 0x81C, 0xF70C0103,
+ 0x81C, 0xF60E0103,
+ 0x81C, 0xF5100103,
+ 0x81C, 0xF4120103,
+ 0x81C, 0xF3140103,
+ 0x81C, 0xF2160103,
+ 0x81C, 0xF1180103,
+ 0x81C, 0xF01A0103,
+ 0x81C, 0xEF1C0103,
+ 0x81C, 0xEE1E0103,
+ 0x81C, 0xED200103,
+ 0x81C, 0xEC220103,
+ 0x81C, 0xEB240103,
+ 0x81C, 0xEA260103,
+ 0x81C, 0xE9280103,
+ 0x81C, 0xE82A0103,
+ 0x81C, 0xE72C0103,
+ 0x81C, 0xE62E0103,
+ 0x81C, 0xE5300103,
+ 0x81C, 0xE4320103,
+ 0x81C, 0xE3340103,
+ 0x81C, 0xE2360103,
+ 0x81C, 0xE1380103,
+ 0x81C, 0xE03A0103,
+ 0x81C, 0xC33C0103,
+ 0x81C, 0xC23E0103,
+ 0x81C, 0xC1400103,
+ 0x81C, 0xC0420103,
+ 0x81C, 0xA3440103,
+ 0x81C, 0xA2460103,
+ 0x81C, 0xA1480103,
+ 0x81C, 0xA04A0103,
+ 0x81C, 0x824C0103,
+ 0x81C, 0x814E0103,
+ 0x81C, 0x80500103,
+ 0x81C, 0x62520103,
+ 0x81C, 0x61540103,
+ 0x81C, 0x60560103,
+ 0x81C, 0x24580103,
+ 0x81C, 0x235A0103,
+ 0x81C, 0x225C0103,
+ 0x81C, 0x215E0103,
+ 0x81C, 0x20600103,
+ 0x81C, 0x03620103,
+ 0x81C, 0x02640103,
+ 0x81C, 0x01660103,
+ 0x81C, 0x01680103,
+ 0x81C, 0x016A0103,
+ 0x81C, 0x016C0103,
+ 0x81C, 0x016E0103,
+ 0x81C, 0x01700103,
+ 0x81C, 0x01720103,
+ 0x81C, 0x01740103,
+ 0x81C, 0x01760103,
+ 0x81C, 0x01780103,
+ 0x81C, 0x017A0103,
+ 0x81C, 0x017C0103,
+ 0x81C, 0x017E0103,
+ 0x90001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xF6000103,
+ 0x81C, 0xF5020103,
+ 0x81C, 0xF4040103,
+ 0x81C, 0xF3060103,
+ 0x81C, 0xF2080103,
+ 0x81C, 0xF10A0103,
+ 0x81C, 0xF00C0103,
+ 0x81C, 0xEF0E0103,
+ 0x81C, 0xEE100103,
+ 0x81C, 0xED120103,
+ 0x81C, 0xEC140103,
+ 0x81C, 0xCE160103,
+ 0x81C, 0xEA180103,
+ 0x81C, 0xE91A0103,
+ 0x81C, 0xE81C0103,
+ 0x81C, 0xE71E0103,
+ 0x81C, 0xE6200103,
+ 0x81C, 0xE5220103,
+ 0x81C, 0xE4240103,
+ 0x81C, 0xE3260103,
+ 0x81C, 0xE2280103,
+ 0x81C, 0xE12A0103,
+ 0x81C, 0xC32C0103,
+ 0x81C, 0xA62E0103,
+ 0x81C, 0xC1300103,
+ 0x81C, 0xA4320103,
+ 0x81C, 0xA3340103,
+ 0x81C, 0xA2360103,
+ 0x81C, 0xA1380103,
+ 0x81C, 0x833A0103,
+ 0x81C, 0x823C0103,
+ 0x81C, 0x813E0103,
+ 0x81C, 0x63400103,
+ 0x81C, 0x62420103,
+ 0x81C, 0x61440103,
+ 0x81C, 0x60460103,
+ 0x81C, 0x25480103,
+ 0x81C, 0x244A0103,
+ 0x81C, 0x234C0103,
+ 0x81C, 0x064E0103,
+ 0x81C, 0x21500103,
+ 0x81C, 0x04520103,
+ 0x81C, 0x03540103,
+ 0x81C, 0x02560103,
+ 0x81C, 0x01580103,
+ 0x81C, 0x005A0103,
+ 0x81C, 0x005C0103,
+ 0x81C, 0x005E0103,
+ 0x81C, 0x00600103,
+ 0x81C, 0x00620103,
+ 0x81C, 0x00640103,
+ 0x81C, 0x00660103,
+ 0x81C, 0x00680103,
+ 0x81C, 0x006A0103,
+ 0x81C, 0x006C0103,
+ 0x81C, 0x006E0103,
+ 0x81C, 0x00700103,
+ 0x81C, 0x00720103,
+ 0x81C, 0x00740103,
+ 0x81C, 0x00760103,
+ 0x81C, 0x00780103,
+ 0x81C, 0x007A0103,
+ 0x81C, 0x007C0103,
+ 0x81C, 0x007E0103,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0xFD000103,
+ 0x81C, 0xFC020103,
+ 0x81C, 0xFB040103,
+ 0x81C, 0xFA060103,
+ 0x81C, 0xF9080103,
+ 0x81C, 0xF80A0103,
+ 0x81C, 0xF70C0103,
+ 0x81C, 0xF60E0103,
+ 0x81C, 0xF5100103,
+ 0x81C, 0xF4120103,
+ 0x81C, 0xF3140103,
+ 0x81C, 0xF2160103,
+ 0x81C, 0xF1180103,
+ 0x81C, 0xF01A0103,
+ 0x81C, 0xEF1C0103,
+ 0x81C, 0xEE1E0103,
+ 0x81C, 0xED200103,
+ 0x81C, 0xEC220103,
+ 0x81C, 0xEB240103,
+ 0x81C, 0xEA260103,
+ 0x81C, 0xE9280103,
+ 0x81C, 0xE82A0103,
+ 0x81C, 0xE72C0103,
+ 0x81C, 0xE62E0103,
+ 0x81C, 0xE5300103,
+ 0x81C, 0xE4320103,
+ 0x81C, 0xE3340103,
+ 0x81C, 0xE2360103,
+ 0x81C, 0xE1380103,
+ 0x81C, 0xE03A0103,
+ 0x81C, 0xA83C0103,
+ 0x81C, 0xA73E0103,
+ 0x81C, 0xA6400103,
+ 0x81C, 0xA5420103,
+ 0x81C, 0xA4440103,
+ 0x81C, 0xA3460103,
+ 0x81C, 0xA2480103,
+ 0x81C, 0xA14A0103,
+ 0x81C, 0x834C0103,
+ 0x81C, 0x824E0103,
+ 0x81C, 0x81500103,
+ 0x81C, 0x63520103,
+ 0x81C, 0x62540103,
+ 0x81C, 0x61560103,
+ 0x81C, 0x25580103,
+ 0x81C, 0x245A0103,
+ 0x81C, 0x235C0103,
+ 0x81C, 0x225E0103,
+ 0x81C, 0x04600103,
+ 0x81C, 0x03620103,
+ 0x81C, 0x02640103,
+ 0x81C, 0x01660103,
+ 0x81C, 0x01680103,
+ 0x81C, 0x016A0103,
+ 0x81C, 0x016C0103,
+ 0x81C, 0x016E0103,
+ 0x81C, 0x01700103,
+ 0x81C, 0x01720103,
+ 0x81C, 0x01740103,
+ 0x81C, 0x01760103,
+ 0x81C, 0x01780103,
+ 0x81C, 0x017A0103,
+ 0x81C, 0x017C0103,
+ 0x81C, 0x017E0103,
+ 0xB0000000, 0x00000000,
+ 0x80001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFB000203,
+ 0x81C, 0xFA020203,
+ 0x81C, 0xF9040203,
+ 0x81C, 0xF8060203,
+ 0x81C, 0xF7080203,
+ 0x81C, 0xF60A0203,
+ 0x81C, 0xF50C0203,
+ 0x81C, 0xF40E0203,
+ 0x81C, 0xF3100203,
+ 0x81C, 0xF2120203,
+ 0x81C, 0xF1140203,
+ 0x81C, 0xF0160203,
+ 0x81C, 0xEF180203,
+ 0x81C, 0xEE1A0203,
+ 0x81C, 0xED1C0203,
+ 0x81C, 0xEC1E0203,
+ 0x81C, 0xEB200203,
+ 0x81C, 0xEA220203,
+ 0x81C, 0xE9240203,
+ 0x81C, 0xE8260203,
+ 0x81C, 0xE7280203,
+ 0x81C, 0xE62A0203,
+ 0x81C, 0xE52C0203,
+ 0x81C, 0xE42E0203,
+ 0x81C, 0xE3300203,
+ 0x81C, 0xE2320203,
+ 0x81C, 0xE1340203,
+ 0x81C, 0xC5360203,
+ 0x81C, 0xC4380203,
+ 0x81C, 0xC33A0203,
+ 0x81C, 0xC23C0203,
+ 0x81C, 0xC13E0203,
+ 0x81C, 0xA4400203,
+ 0x81C, 0xA3420203,
+ 0x81C, 0xA2440203,
+ 0x81C, 0xA1460203,
+ 0x81C, 0xA0480203,
+ 0x81C, 0x834A0203,
+ 0x81C, 0x824C0203,
+ 0x81C, 0x814E0203,
+ 0x81C, 0x63500203,
+ 0x81C, 0x62520203,
+ 0x81C, 0x61540203,
+ 0x81C, 0x60560203,
+ 0x81C, 0x23580203,
+ 0x81C, 0x225A0203,
+ 0x81C, 0x215C0203,
+ 0x81C, 0x205E0203,
+ 0x81C, 0x04600203,
+ 0x81C, 0x03620203,
+ 0x81C, 0x02640203,
+ 0x81C, 0x01660203,
+ 0x81C, 0x01680203,
+ 0x81C, 0x016A0203,
+ 0x81C, 0x016C0203,
+ 0x81C, 0x016E0203,
+ 0x81C, 0x01700203,
+ 0x81C, 0x01720203,
+ 0x81C, 0x01740203,
+ 0x81C, 0x01760203,
+ 0x81C, 0x01780203,
+ 0x81C, 0x017A0203,
+ 0x81C, 0x017C0203,
+ 0x81C, 0x017E0203,
+ 0x90001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xF6000203,
+ 0x81C, 0xF5020203,
+ 0x81C, 0xF4040203,
+ 0x81C, 0xF3060203,
+ 0x81C, 0xF2080203,
+ 0x81C, 0xF10A0203,
+ 0x81C, 0xF00C0203,
+ 0x81C, 0xEF0E0203,
+ 0x81C, 0xEE100203,
+ 0x81C, 0xED120203,
+ 0x81C, 0xEC140203,
+ 0x81C, 0xEB160203,
+ 0x81C, 0xEA180203,
+ 0x81C, 0xE91A0203,
+ 0x81C, 0xE81C0203,
+ 0x81C, 0xE71E0203,
+ 0x81C, 0xE6200203,
+ 0x81C, 0xE5220203,
+ 0x81C, 0xE4240203,
+ 0x81C, 0xE3260203,
+ 0x81C, 0xE2280203,
+ 0x81C, 0xE12A0203,
+ 0x81C, 0xE02C0203,
+ 0x81C, 0xC22E0203,
+ 0x81C, 0xC1300203,
+ 0x81C, 0xC0320203,
+ 0x81C, 0xA3340203,
+ 0x81C, 0xA2360203,
+ 0x81C, 0xA1380203,
+ 0x81C, 0xA03A0203,
+ 0x81C, 0x833C0203,
+ 0x81C, 0x823E0203,
+ 0x81C, 0x81400203,
+ 0x81C, 0x80420203,
+ 0x81C, 0x62440203,
+ 0x81C, 0x61460203,
+ 0x81C, 0x42480203,
+ 0x81C, 0x414A0203,
+ 0x81C, 0x234C0203,
+ 0x81C, 0x224E0203,
+ 0x81C, 0x21500203,
+ 0x81C, 0x20520203,
+ 0x81C, 0x03540203,
+ 0x81C, 0x02560203,
+ 0x81C, 0x01580203,
+ 0x81C, 0x005A0203,
+ 0x81C, 0x005C0203,
+ 0x81C, 0x005E0203,
+ 0x81C, 0x00600203,
+ 0x81C, 0x00620203,
+ 0x81C, 0x00640203,
+ 0x81C, 0x00660203,
+ 0x81C, 0x00680203,
+ 0x81C, 0x006A0203,
+ 0x81C, 0x006C0203,
+ 0x81C, 0x006E0203,
+ 0x81C, 0x00700203,
+ 0x81C, 0x00720203,
+ 0x81C, 0x00740203,
+ 0x81C, 0x00760203,
+ 0x81C, 0x00780203,
+ 0x81C, 0x007A0203,
+ 0x81C, 0x007C0203,
+ 0x81C, 0x007E0203,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0xFC000203,
+ 0x81C, 0xFB020203,
+ 0x81C, 0xFA040203,
+ 0x81C, 0xF9060203,
+ 0x81C, 0xF8080203,
+ 0x81C, 0xF70A0203,
+ 0x81C, 0xF60C0203,
+ 0x81C, 0xF50E0203,
+ 0x81C, 0xF4100203,
+ 0x81C, 0xF3120203,
+ 0x81C, 0xF2140203,
+ 0x81C, 0xF1160203,
+ 0x81C, 0xF0180203,
+ 0x81C, 0xEF1A0203,
+ 0x81C, 0xEE1C0203,
+ 0x81C, 0xED1E0203,
+ 0x81C, 0xEC200203,
+ 0x81C, 0xEB220203,
+ 0x81C, 0xEA240203,
+ 0x81C, 0xE9260203,
+ 0x81C, 0xE8280203,
+ 0x81C, 0xE72A0203,
+ 0x81C, 0xE62C0203,
+ 0x81C, 0xE52E0203,
+ 0x81C, 0xE4300203,
+ 0x81C, 0xE3320203,
+ 0x81C, 0xE2340203,
+ 0x81C, 0xE1360203,
+ 0x81C, 0xC5380203,
+ 0x81C, 0xC43A0203,
+ 0x81C, 0xC33C0203,
+ 0x81C, 0xC23E0203,
+ 0x81C, 0xA6400203,
+ 0x81C, 0xA5420203,
+ 0x81C, 0xA4440203,
+ 0x81C, 0xA3460203,
+ 0x81C, 0xA2480203,
+ 0x81C, 0x844A0203,
+ 0x81C, 0x834C0203,
+ 0x81C, 0x824E0203,
+ 0x81C, 0x64500203,
+ 0x81C, 0x63520203,
+ 0x81C, 0x62540203,
+ 0x81C, 0x61560203,
+ 0x81C, 0x60580203,
+ 0x81C, 0x235A0203,
+ 0x81C, 0x225C0203,
+ 0x81C, 0x215E0203,
+ 0x81C, 0x04600203,
+ 0x81C, 0x03620203,
+ 0x81C, 0x02640203,
+ 0x81C, 0x01660203,
+ 0x81C, 0x01680203,
+ 0x81C, 0x016A0203,
+ 0x81C, 0x016C0203,
+ 0x81C, 0x016E0203,
+ 0x81C, 0x01700203,
+ 0x81C, 0x01720203,
+ 0x81C, 0x01740203,
+ 0x81C, 0x01760203,
+ 0x81C, 0x01780203,
+ 0x81C, 0x017A0203,
+ 0x81C, 0x017C0203,
+ 0x81C, 0x017E0203,
+ 0xB0000000, 0x00000000,
+ 0x80001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFB000303,
+ 0x81C, 0xFA020303,
+ 0x81C, 0xF9040303,
+ 0x81C, 0xF8060303,
+ 0x81C, 0xF7080303,
+ 0x81C, 0xF60A0303,
+ 0x81C, 0xF50C0303,
+ 0x81C, 0xF40E0303,
+ 0x81C, 0xF3100303,
+ 0x81C, 0xF2120303,
+ 0x81C, 0xF1140303,
+ 0x81C, 0xF0160303,
+ 0x81C, 0xEF180303,
+ 0x81C, 0xEE1A0303,
+ 0x81C, 0xED1C0303,
+ 0x81C, 0xEC1E0303,
+ 0x81C, 0xEB200303,
+ 0x81C, 0xEA220303,
+ 0x81C, 0xE9240303,
+ 0x81C, 0xE8260303,
+ 0x81C, 0xE7280303,
+ 0x81C, 0xE62A0303,
+ 0x81C, 0xE52C0303,
+ 0x81C, 0xE42E0303,
+ 0x81C, 0xE3300303,
+ 0x81C, 0xE2320303,
+ 0x81C, 0xE1340303,
+ 0x81C, 0xC4360303,
+ 0x81C, 0xC3380303,
+ 0x81C, 0xC23A0303,
+ 0x81C, 0xC13C0303,
+ 0x81C, 0xA53E0303,
+ 0x81C, 0xA4400303,
+ 0x81C, 0xA3420303,
+ 0x81C, 0xA2440303,
+ 0x81C, 0xA1460303,
+ 0x81C, 0x83480303,
+ 0x81C, 0x824A0303,
+ 0x81C, 0x814C0303,
+ 0x81C, 0x644E0303,
+ 0x81C, 0x63500303,
+ 0x81C, 0x62520303,
+ 0x81C, 0x61540303,
+ 0x81C, 0x60560303,
+ 0x81C, 0x23580303,
+ 0x81C, 0x225A0303,
+ 0x81C, 0x215C0303,
+ 0x81C, 0x045E0303,
+ 0x81C, 0x03600303,
+ 0x81C, 0x02620303,
+ 0x81C, 0x01640303,
+ 0x81C, 0x01660303,
+ 0x81C, 0x01680303,
+ 0x81C, 0x016A0303,
+ 0x81C, 0x016C0303,
+ 0x81C, 0x016E0303,
+ 0x81C, 0x01700303,
+ 0x81C, 0x01720303,
+ 0x81C, 0x01740303,
+ 0x81C, 0x01760303,
+ 0x81C, 0x01780303,
+ 0x81C, 0x017A0303,
+ 0x81C, 0x017C0303,
+ 0x81C, 0x017E0303,
+ 0x90001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xF5000303,
+ 0x81C, 0xF4020303,
+ 0x81C, 0xF3040303,
+ 0x81C, 0xF2060303,
+ 0x81C, 0xF1080303,
+ 0x81C, 0xF00A0303,
+ 0x81C, 0xEF0C0303,
+ 0x81C, 0xEE0E0303,
+ 0x81C, 0xED100303,
+ 0x81C, 0xEC120303,
+ 0x81C, 0xEB140303,
+ 0x81C, 0xEA160303,
+ 0x81C, 0xE9180303,
+ 0x81C, 0xE81A0303,
+ 0x81C, 0xE71C0303,
+ 0x81C, 0xE61E0303,
+ 0x81C, 0xE5200303,
+ 0x81C, 0xE4220303,
+ 0x81C, 0xE3240303,
+ 0x81C, 0xE2260303,
+ 0x81C, 0xE1280303,
+ 0x81C, 0xE02A0303,
+ 0x81C, 0xA72C0303,
+ 0x81C, 0xA62E0303,
+ 0x81C, 0xA5300303,
+ 0x81C, 0xA4320303,
+ 0x81C, 0xA3340303,
+ 0x81C, 0xA2360303,
+ 0x81C, 0xA1380303,
+ 0x81C, 0xA03A0303,
+ 0x81C, 0x823C0303,
+ 0x81C, 0x643E0303,
+ 0x81C, 0x63400303,
+ 0x81C, 0x62420303,
+ 0x81C, 0x61440303,
+ 0x81C, 0x60460303,
+ 0x81C, 0x24480303,
+ 0x81C, 0x234A0303,
+ 0x81C, 0x224C0303,
+ 0x81C, 0x054E0303,
+ 0x81C, 0x04500303,
+ 0x81C, 0x03520303,
+ 0x81C, 0x02540303,
+ 0x81C, 0x01560303,
+ 0x81C, 0x00580303,
+ 0x81C, 0x005A0303,
+ 0x81C, 0x005C0303,
+ 0x81C, 0x005E0303,
+ 0x81C, 0x00600303,
+ 0x81C, 0x00620303,
+ 0x81C, 0x00640303,
+ 0x81C, 0x00660303,
+ 0x81C, 0x00680303,
+ 0x81C, 0x006A0303,
+ 0x81C, 0x006C0303,
+ 0x81C, 0x006E0303,
+ 0x81C, 0x00700303,
+ 0x81C, 0x00720303,
+ 0x81C, 0x00740303,
+ 0x81C, 0x00760303,
+ 0x81C, 0x00780303,
+ 0x81C, 0x007A0303,
+ 0x81C, 0x007C0303,
+ 0x81C, 0x007E0303,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0xFC000303,
+ 0x81C, 0xFB020303,
+ 0x81C, 0xFA040303,
+ 0x81C, 0xF9060303,
+ 0x81C, 0xF8080303,
+ 0x81C, 0xF70A0303,
+ 0x81C, 0xF60C0303,
+ 0x81C, 0xF50E0303,
+ 0x81C, 0xF4100303,
+ 0x81C, 0xF3120303,
+ 0x81C, 0xF2140303,
+ 0x81C, 0xF1160303,
+ 0x81C, 0xF0180303,
+ 0x81C, 0xEF1A0303,
+ 0x81C, 0xEE1C0303,
+ 0x81C, 0xED1E0303,
+ 0x81C, 0xEC200303,
+ 0x81C, 0xEB220303,
+ 0x81C, 0xEA240303,
+ 0x81C, 0xE9260303,
+ 0x81C, 0xE8280303,
+ 0x81C, 0xE72A0303,
+ 0x81C, 0xE62C0303,
+ 0x81C, 0xE52E0303,
+ 0x81C, 0xE4300303,
+ 0x81C, 0xE3320303,
+ 0x81C, 0xE2340303,
+ 0x81C, 0xE1360303,
+ 0x81C, 0xC4380303,
+ 0x81C, 0xC33A0303,
+ 0x81C, 0xC23C0303,
+ 0x81C, 0xC13E0303,
+ 0x81C, 0xA5400303,
+ 0x81C, 0xA4420303,
+ 0x81C, 0xA3440303,
+ 0x81C, 0xA2460303,
+ 0x81C, 0xA1480303,
+ 0x81C, 0x834A0303,
+ 0x81C, 0x824C0303,
+ 0x81C, 0x814E0303,
+ 0x81C, 0x64500303,
+ 0x81C, 0x63520303,
+ 0x81C, 0x62540303,
+ 0x81C, 0x61560303,
+ 0x81C, 0x24580303,
+ 0x81C, 0x235A0303,
+ 0x81C, 0x225C0303,
+ 0x81C, 0x215E0303,
+ 0x81C, 0x04600303,
+ 0x81C, 0x03620303,
+ 0x81C, 0x02640303,
+ 0x81C, 0x01660303,
+ 0x81C, 0x01680303,
+ 0x81C, 0x016A0303,
+ 0x81C, 0x016C0303,
+ 0x81C, 0x016E0303,
+ 0x81C, 0x01700303,
+ 0x81C, 0x01720303,
+ 0x81C, 0x01740303,
+ 0x81C, 0x01760303,
+ 0x81C, 0x01780303,
+ 0x81C, 0x017A0303,
+ 0x81C, 0x017C0303,
+ 0x81C, 0x017E0303,
+ 0xB0000000, 0x00000000,
+ 0x80001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFC000803,
+ 0x81C, 0xFB020803,
+ 0x81C, 0xFA040803,
+ 0x81C, 0xF9060803,
+ 0x81C, 0xF8080803,
+ 0x81C, 0xF70A0803,
+ 0x81C, 0xF60C0803,
+ 0x81C, 0xF50E0803,
+ 0x81C, 0xF4100803,
+ 0x81C, 0xF3120803,
+ 0x81C, 0xF2140803,
+ 0x81C, 0xF1160803,
+ 0x81C, 0xF0180803,
+ 0x81C, 0xEF1A0803,
+ 0x81C, 0xEE1C0803,
+ 0x81C, 0xED1E0803,
+ 0x81C, 0xB5200803,
+ 0x81C, 0xB4220803,
+ 0x81C, 0xB3240803,
+ 0x81C, 0xB2260803,
+ 0x81C, 0xB1280803,
+ 0x81C, 0xB02A0803,
+ 0x81C, 0xAF2C0803,
+ 0x81C, 0xAE2E0803,
+ 0x81C, 0xAD300803,
+ 0x81C, 0xAC320803,
+ 0x81C, 0xAB340803,
+ 0x81C, 0xAA360803,
+ 0x81C, 0xA9380803,
+ 0x81C, 0xA83A0803,
+ 0x81C, 0xA73C0803,
+ 0x81C, 0xA63E0803,
+ 0x81C, 0x88400803,
+ 0x81C, 0x87420803,
+ 0x81C, 0x86440803,
+ 0x81C, 0x85460803,
+ 0x81C, 0x84480803,
+ 0x81C, 0x834A0803,
+ 0x81C, 0x674C0803,
+ 0x81C, 0x664E0803,
+ 0x81C, 0x65500803,
+ 0x81C, 0x64520803,
+ 0x81C, 0x63540803,
+ 0x81C, 0x62560803,
+ 0x81C, 0x61580803,
+ 0x81C, 0x455A0803,
+ 0x81C, 0x445C0803,
+ 0x81C, 0x435E0803,
+ 0x81C, 0x42600803,
+ 0x81C, 0x41620803,
+ 0x81C, 0x25640803,
+ 0x81C, 0x24660803,
+ 0x81C, 0x23680803,
+ 0x81C, 0x226A0803,
+ 0x81C, 0x216C0803,
+ 0x81C, 0x016E0803,
+ 0x81C, 0x01700803,
+ 0x81C, 0x01720803,
+ 0x81C, 0x01740803,
+ 0x81C, 0x01760803,
+ 0x81C, 0x01780803,
+ 0x81C, 0x017A0803,
+ 0x81C, 0x017C0803,
+ 0x81C, 0x017E0803,
+ 0x90001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFC000803,
+ 0x81C, 0xFB020803,
+ 0x81C, 0xFA040803,
+ 0x81C, 0xF9060803,
+ 0x81C, 0xF8080803,
+ 0x81C, 0xF70A0803,
+ 0x81C, 0xF60C0803,
+ 0x81C, 0xF50E0803,
+ 0x81C, 0xF4100803,
+ 0x81C, 0xF3120803,
+ 0x81C, 0xF2140803,
+ 0x81C, 0xF1160803,
+ 0x81C, 0xF0180803,
+ 0x81C, 0xEF1A0803,
+ 0x81C, 0xEE1C0803,
+ 0x81C, 0xED1E0803,
+ 0x81C, 0xB5200803,
+ 0x81C, 0xB4220803,
+ 0x81C, 0xB3240803,
+ 0x81C, 0xB2260803,
+ 0x81C, 0xB1280803,
+ 0x81C, 0xB02A0803,
+ 0x81C, 0xAF2C0803,
+ 0x81C, 0xAE2E0803,
+ 0x81C, 0xAD300803,
+ 0x81C, 0xAC320803,
+ 0x81C, 0xAB340803,
+ 0x81C, 0xAA360803,
+ 0x81C, 0xA9380803,
+ 0x81C, 0xA83A0803,
+ 0x81C, 0xA73C0803,
+ 0x81C, 0xA63E0803,
+ 0x81C, 0x88400803,
+ 0x81C, 0x87420803,
+ 0x81C, 0x86440803,
+ 0x81C, 0x85460803,
+ 0x81C, 0x84480803,
+ 0x81C, 0x834A0803,
+ 0x81C, 0x674C0803,
+ 0x81C, 0x664E0803,
+ 0x81C, 0x65500803,
+ 0x81C, 0x64520803,
+ 0x81C, 0x63540803,
+ 0x81C, 0x62560803,
+ 0x81C, 0x61580803,
+ 0x81C, 0x455A0803,
+ 0x81C, 0x445C0803,
+ 0x81C, 0x435E0803,
+ 0x81C, 0x42600803,
+ 0x81C, 0x41620803,
+ 0x81C, 0x25640803,
+ 0x81C, 0x24660803,
+ 0x81C, 0x23680803,
+ 0x81C, 0x226A0803,
+ 0x81C, 0x216C0803,
+ 0x81C, 0x016E0803,
+ 0x81C, 0x01700803,
+ 0x81C, 0x01720803,
+ 0x81C, 0x01740803,
+ 0x81C, 0x01760803,
+ 0x81C, 0x01780803,
+ 0x81C, 0x017A0803,
+ 0x81C, 0x017C0803,
+ 0x81C, 0x017E0803,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0xFC000803,
+ 0x81C, 0xFB020803,
+ 0x81C, 0xFA040803,
+ 0x81C, 0xF9060803,
+ 0x81C, 0xF8080803,
+ 0x81C, 0xF70A0803,
+ 0x81C, 0xF60C0803,
+ 0x81C, 0xF50E0803,
+ 0x81C, 0xF4100803,
+ 0x81C, 0xF3120803,
+ 0x81C, 0xF2140803,
+ 0x81C, 0xF1160803,
+ 0x81C, 0xF0180803,
+ 0x81C, 0xEF1A0803,
+ 0x81C, 0xEE1C0803,
+ 0x81C, 0xED1E0803,
+ 0x81C, 0xB5200803,
+ 0x81C, 0xB4220803,
+ 0x81C, 0xB3240803,
+ 0x81C, 0xB2260803,
+ 0x81C, 0xB1280803,
+ 0x81C, 0xB02A0803,
+ 0x81C, 0xAF2C0803,
+ 0x81C, 0xAE2E0803,
+ 0x81C, 0xAD300803,
+ 0x81C, 0xAC320803,
+ 0x81C, 0xAB340803,
+ 0x81C, 0xAA360803,
+ 0x81C, 0xA9380803,
+ 0x81C, 0xA83A0803,
+ 0x81C, 0xA73C0803,
+ 0x81C, 0xA63E0803,
+ 0x81C, 0x88400803,
+ 0x81C, 0x87420803,
+ 0x81C, 0x86440803,
+ 0x81C, 0x85460803,
+ 0x81C, 0x84480803,
+ 0x81C, 0x834A0803,
+ 0x81C, 0x674C0803,
+ 0x81C, 0x664E0803,
+ 0x81C, 0x65500803,
+ 0x81C, 0x64520803,
+ 0x81C, 0x63540803,
+ 0x81C, 0x62560803,
+ 0x81C, 0x61580803,
+ 0x81C, 0x455A0803,
+ 0x81C, 0x445C0803,
+ 0x81C, 0x435E0803,
+ 0x81C, 0x42600803,
+ 0x81C, 0x41620803,
+ 0x81C, 0x25640803,
+ 0x81C, 0x24660803,
+ 0x81C, 0x23680803,
+ 0x81C, 0x226A0803,
+ 0x81C, 0x216C0803,
+ 0x81C, 0x016E0803,
+ 0x81C, 0x01700803,
+ 0x81C, 0x01720803,
+ 0x81C, 0x01740803,
+ 0x81C, 0x01760803,
+ 0x81C, 0x01780803,
+ 0x81C, 0x017A0803,
+ 0x81C, 0x017C0803,
+ 0x81C, 0x017E0803,
+ 0xB0000000, 0x00000000,
+ 0x80001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFF000913,
+ 0x81C, 0xFE020913,
+ 0x81C, 0xFD040913,
+ 0x81C, 0xFC060913,
+ 0x81C, 0xFB080913,
+ 0x81C, 0xFA0A0913,
+ 0x81C, 0xF90C0913,
+ 0x81C, 0xF80E0913,
+ 0x81C, 0xF7100913,
+ 0x81C, 0xF6120913,
+ 0x81C, 0xF5140913,
+ 0x81C, 0xF4160913,
+ 0x81C, 0xF3180913,
+ 0x81C, 0xF21A0913,
+ 0x81C, 0xF11C0913,
+ 0x81C, 0x941E0913,
+ 0x81C, 0x93200913,
+ 0x81C, 0x92220913,
+ 0x81C, 0x91240913,
+ 0x81C, 0x90260913,
+ 0x81C, 0x8F280913,
+ 0x81C, 0x8E2A0913,
+ 0x81C, 0x8D2C0913,
+ 0x81C, 0x8C2E0913,
+ 0x81C, 0x8B300913,
+ 0x81C, 0x8A320913,
+ 0x81C, 0x89340913,
+ 0x81C, 0x88360913,
+ 0x81C, 0x87380913,
+ 0x81C, 0x863A0913,
+ 0x81C, 0x853C0913,
+ 0x81C, 0x843E0913,
+ 0x81C, 0x83400913,
+ 0x81C, 0x82420913,
+ 0x81C, 0x81440913,
+ 0x81C, 0x07460913,
+ 0x81C, 0x06480913,
+ 0x81C, 0x054A0913,
+ 0x81C, 0x044C0913,
+ 0x81C, 0x034E0913,
+ 0x81C, 0x02500913,
+ 0x81C, 0x01520913,
+ 0x81C, 0x88540903,
+ 0x81C, 0x87560903,
+ 0x81C, 0x86580903,
+ 0x81C, 0x855A0903,
+ 0x81C, 0x845C0903,
+ 0x81C, 0x835E0903,
+ 0x81C, 0x82600903,
+ 0x81C, 0x81620903,
+ 0x81C, 0x07640903,
+ 0x81C, 0x06660903,
+ 0x81C, 0x05680903,
+ 0x81C, 0x046A0903,
+ 0x81C, 0x036C0903,
+ 0x81C, 0x026E0903,
+ 0x81C, 0x01700903,
+ 0x81C, 0x01720903,
+ 0x81C, 0x01740903,
+ 0x81C, 0x01760903,
+ 0x81C, 0x01780903,
+ 0x81C, 0x017A0903,
+ 0x81C, 0x017C0903,
+ 0x81C, 0x017E0903,
+ 0x90001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x81C, 0xFF000913,
+ 0x81C, 0xFE020913,
+ 0x81C, 0xFD040913,
+ 0x81C, 0xFC060913,
+ 0x81C, 0xFB080913,
+ 0x81C, 0xFA0A0913,
+ 0x81C, 0xF90C0913,
+ 0x81C, 0xF80E0913,
+ 0x81C, 0xF7100913,
+ 0x81C, 0xF6120913,
+ 0x81C, 0xF5140913,
+ 0x81C, 0xF4160913,
+ 0x81C, 0xF3180913,
+ 0x81C, 0xF21A0913,
+ 0x81C, 0xF11C0913,
+ 0x81C, 0x941E0913,
+ 0x81C, 0x93200913,
+ 0x81C, 0x92220913,
+ 0x81C, 0x91240913,
+ 0x81C, 0x90260913,
+ 0x81C, 0x8F280913,
+ 0x81C, 0x8E2A0913,
+ 0x81C, 0x8D2C0913,
+ 0x81C, 0x8C2E0913,
+ 0x81C, 0x8B300913,
+ 0x81C, 0x8A320913,
+ 0x81C, 0x89340913,
+ 0x81C, 0x88360913,
+ 0x81C, 0x87380913,
+ 0x81C, 0x863A0913,
+ 0x81C, 0x853C0913,
+ 0x81C, 0x843E0913,
+ 0x81C, 0x83400913,
+ 0x81C, 0x82420913,
+ 0x81C, 0x81440913,
+ 0x81C, 0x07460913,
+ 0x81C, 0x06480913,
+ 0x81C, 0x054A0913,
+ 0x81C, 0x044C0913,
+ 0x81C, 0x034E0913,
+ 0x81C, 0x02500913,
+ 0x81C, 0x01520913,
+ 0x81C, 0x88540903,
+ 0x81C, 0x87560903,
+ 0x81C, 0x86580903,
+ 0x81C, 0x855A0903,
+ 0x81C, 0x845C0903,
+ 0x81C, 0x835E0903,
+ 0x81C, 0x82600903,
+ 0x81C, 0x81620903,
+ 0x81C, 0x07640903,
+ 0x81C, 0x06660903,
+ 0x81C, 0x05680903,
+ 0x81C, 0x046A0903,
+ 0x81C, 0x036C0903,
+ 0x81C, 0x026E0903,
+ 0x81C, 0x01700903,
+ 0x81C, 0x01720903,
+ 0x81C, 0x01740903,
+ 0x81C, 0x01760903,
+ 0x81C, 0x01780903,
+ 0x81C, 0x017A0903,
+ 0x81C, 0x017C0903,
+ 0x81C, 0x017E0903,
+ 0xA0000000, 0x00000000,
+ 0x81C, 0xFF000913,
+ 0x81C, 0xFE020913,
+ 0x81C, 0xFD040913,
+ 0x81C, 0xFC060913,
+ 0x81C, 0xFB080913,
+ 0x81C, 0xFA0A0913,
+ 0x81C, 0xF90C0913,
+ 0x81C, 0xF80E0913,
+ 0x81C, 0xF7100913,
+ 0x81C, 0xF6120913,
+ 0x81C, 0xF5140913,
+ 0x81C, 0xF4160913,
+ 0x81C, 0xF3180913,
+ 0x81C, 0xF21A0913,
+ 0x81C, 0xF11C0913,
+ 0x81C, 0x941E0913,
+ 0x81C, 0x93200913,
+ 0x81C, 0x92220913,
+ 0x81C, 0x91240913,
+ 0x81C, 0x90260913,
+ 0x81C, 0x8F280913,
+ 0x81C, 0x8E2A0913,
+ 0x81C, 0x8D2C0913,
+ 0x81C, 0x8C2E0913,
+ 0x81C, 0x8B300913,
+ 0x81C, 0x8A320913,
+ 0x81C, 0x89340913,
+ 0x81C, 0x88360913,
+ 0x81C, 0x87380913,
+ 0x81C, 0x863A0913,
+ 0x81C, 0x853C0913,
+ 0x81C, 0x843E0913,
+ 0x81C, 0x83400913,
+ 0x81C, 0x82420913,
+ 0x81C, 0x81440913,
+ 0x81C, 0x07460913,
+ 0x81C, 0x06480913,
+ 0x81C, 0x054A0913,
+ 0x81C, 0x044C0913,
+ 0x81C, 0x034E0913,
+ 0x81C, 0x02500913,
+ 0x81C, 0x01520913,
+ 0x81C, 0x88540903,
+ 0x81C, 0x87560903,
+ 0x81C, 0x86580903,
+ 0x81C, 0x855A0903,
+ 0x81C, 0x845C0903,
+ 0x81C, 0x835E0903,
+ 0x81C, 0x82600903,
+ 0x81C, 0x81620903,
+ 0x81C, 0x07640903,
+ 0x81C, 0x06660903,
+ 0x81C, 0x05680903,
+ 0x81C, 0x046A0903,
+ 0x81C, 0x036C0903,
+ 0x81C, 0x026E0903,
+ 0x81C, 0x01700903,
+ 0x81C, 0x01720903,
+ 0x81C, 0x01740903,
+ 0x81C, 0x01760903,
+ 0x81C, 0x01780903,
+ 0x81C, 0x017A0903,
+ 0x81C, 0x017C0903,
+ 0x81C, 0x017E0903,
+ 0xB0000000, 0x00000000,
+ 0x80001004, 0x00000000, 0x40000000, 0x00000000,
+ 0xC50, 0x00000022,
+ 0xC50, 0x00000020,
+ 0x90001005, 0x00000000, 0x40000000, 0x00000000,
+ 0xC50, 0x00000022,
+ 0xC50, 0x00000022,
+ 0xA0000000, 0x00000000,
+ 0xC50, 0x00000022,
+ 0xC50, 0x00000020,
+ 0xB0000000, 0x00000000,
+
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8821c_agc, rtw_phy_cfg_agc);
+
+static const u32 rtw8821c_bb[] = {
+ 0x800, 0x9020D010,
+ 0x804, 0x80018180,
+ 0x808, 0x04028211,
+ 0x80C, 0x13D10011,
+ 0x810, 0x21104255,
+ 0x814, 0x020C3D10,
+ 0x818, 0x84A10385,
+ 0x81C, 0x1E1E081F,
+ 0x820, 0x0001AAAA,
+ 0x824, 0x00030FE0,
+ 0x828, 0x0000CCCC,
+ 0x82C, 0x75CB7010,
+ 0x830, 0x79A0EAAA,
+ 0x834, 0x072E698A,
+ 0x838, 0x87766461,
+ 0x83C, 0x9194B2B6,
+ 0x840, 0x171740E0,
+ 0x844, 0x4D3D7CDB,
+ 0x848, 0x4AD0408B,
+ 0x84C, 0x6AFBF7A5,
+ 0x850, 0x28A74706,
+ 0x854, 0x0001520C,
+ 0x858, 0x4060C000,
+ 0x85C, 0x74010160,
+ 0x860, 0x68A7C321,
+ 0x864, 0x79F27432,
+ 0x868, 0x8CA7A314,
+ 0x86C, 0x558C2878,
+ 0x870, 0x55555555,
+ 0x874, 0x27612C2E,
+ 0x878, 0xC0003152,
+ 0x87C, 0x5C8FC000,
+ 0x880, 0x00000000,
+ 0x884, 0x00000000,
+ 0x888, 0x00000000,
+ 0x88C, 0x00000000,
+ 0x890, 0x00000000,
+ 0x894, 0x00000000,
+ 0x898, 0x00000000,
+ 0x89C, 0x00000000,
+ 0x8A0, 0x00000013,
+ 0x8A4, 0x7F7F7F7F,
+ 0x8A8, 0x2202033E,
+ 0x8AC, 0xF00F000A,
+ 0x8B0, 0x00000600,
+ 0x8B4, 0x000FC080,
+ 0x8B8, 0xEC0057FF,
+ 0x8BC, 0x2CB520A3,
+ 0x8C0, 0xFFE04020,
+ 0x8C4, 0x47C00000,
+ 0x8C8, 0x00025165,
+ 0x8CC, 0x08188492,
+ 0x8D0, 0x0000B800,
+ 0x8D4, 0x860308A0,
+ 0x8D8, 0x290B5612,
+ 0x8DC, 0x00000000,
+ 0x8E0, 0x32D16777,
+ 0x8E4, 0x49092925,
+ 0x8E8, 0xFFFFC42C,
+ 0x8EC, 0x99999999,
+ 0x8F0, 0x00009999,
+ 0x8F4, 0x00D80FA1,
+ 0x8F8, 0x400000C0,
+ 0x8FC, 0x00000130,
+ 0x900, 0x00C00000,
+ 0x904, 0x0FFF0FFF,
+ 0x908, 0x00000000,
+ 0x90C, 0x13000000,
+ 0x910, 0x0000FC00,
+ 0x914, 0xC6380000,
+ 0x918, 0x1C1028C0,
+ 0x91C, 0x64B11A1C,
+ 0x920, 0xE0767233,
+ 0x924, 0x855A2500,
+ 0x928, 0x4AB0E4E4,
+ 0x92C, 0xFFFEB200,
+ 0x930, 0xFFFFFFFE,
+ 0x934, 0x001FFFFF,
+ 0x938, 0x00008480,
+ 0x93C, 0xE41C0642,
+ 0x940, 0x0E470430,
+ 0x944, 0x00000000,
+ 0x948, 0xAC000000,
+ 0x94C, 0x10000083,
+ 0x950, 0xB2010080,
+ 0x954, 0x86510080,
+ 0x958, 0x00000181,
+ 0x95C, 0x04248000,
+ 0x960, 0x00000000,
+ 0x964, 0x00000000,
+ 0x968, 0x00000000,
+ 0x96C, 0x00000000,
+ 0x970, 0x00001FFF,
+ 0x974, 0x04000FFF,
+ 0x978, 0x00000000,
+ 0x97C, 0x00000000,
+ 0x980, 0x00000000,
+ 0x984, 0x00000000,
+ 0x988, 0x00000000,
+ 0x98C, 0x23440000,
+ 0x990, 0x27100000,
+ 0x994, 0xFFFF0100,
+ 0x998, 0xFFFFFF5C,
+ 0x99C, 0xFFFFFFFF,
+ 0x9A0, 0x000000FF,
+ 0x9A4, 0x80000088,
+ 0x9A8, 0x0C2F0000,
+ 0x9AC, 0x01560000,
+ 0x9B0, 0x70000000,
+ 0x9B4, 0x00000000,
+ 0x9B8, 0x00000000,
+ 0x9BC, 0x00000000,
+ 0x9C0, 0x00000000,
+ 0x9C4, 0x00000000,
+ 0x9C8, 0x00000000,
+ 0x9CC, 0x00000000,
+ 0x9D0, 0x00000000,
+ 0x9D4, 0x00000000,
+ 0x9D8, 0x00000000,
+ 0x9DC, 0x00000000,
+ 0x9E0, 0x00000000,
+ 0x9E4, 0x02000402,
+ 0x9E8, 0x000022D4,
+ 0x9EC, 0x00000000,
+ 0x9F0, 0x00000000,
+ 0x9F4, 0x00000000,
+ 0x9F8, 0x00000000,
+ 0x9FC, 0xEFFFF7FF,
+ 0xA00, 0x00D040C8,
+ 0xA04, 0x80FF800C,
+ 0xA08, 0x9C838300,
+ 0xA0C, 0x297E000F,
+ 0xA10, 0x9500BB78,
+ 0xA14, 0x1114D028,
+ 0xA18, 0x00881117,
+ 0xA1C, 0x89140F00,
+ 0xA20, 0xE82C0000,
+ 0xA24, 0x64B80C1C,
+ 0xA28, 0x00008810,
+ 0xA2C, 0x00D20000,
+ 0xA70, 0x101FBF00,
+ 0xA74, 0x00000107,
+ 0xA78, 0x00008900,
+ 0xA7C, 0x225B0606,
+ 0xA80, 0x21807532,
+ 0xA84, 0x80120000,
+ 0xA88, 0x048C0000,
+ 0xA8C, 0x12345678,
+ 0xA90, 0xABCDEF00,
+ 0xA94, 0x001B1B89,
+ 0xA98, 0x00000000,
+ 0xA9C, 0x3F000000,
+ 0xAA0, 0x00000000,
+ 0xAA4, 0x00080000,
+ 0xAA8, 0xEACF0004,
+ 0xAAC, 0x01235667,
+ 0xAB0, 0x00000000,
+ 0xB00, 0xE1000440,
+ 0xB04, 0x00800000,
+ 0xB08, 0xFF02030B,
+ 0xB0C, 0x01EAA406,
+ 0xB10, 0x00030690,
+ 0xB14, 0x006000FA,
+ 0xB18, 0x00000002,
+ 0xB1C, 0x00000002,
+ 0xB20, 0x4B00001F,
+ 0xB24, 0x4E8E3E40,
+ 0xB28, 0x03020100,
+ 0xB2C, 0x07060504,
+ 0xB30, 0x0B0A0908,
+ 0xB34, 0x0F0E0D0C,
+ 0xB38, 0x13121110,
+ 0xB3C, 0x0000003A,
+ 0xB40, 0x00000000,
+ 0xB44, 0x80000000,
+ 0xB48, 0x3F0000FA,
+ 0xB4C, 0x88C80020,
+ 0xB50, 0x00000000,
+ 0xB54, 0x00004241,
+ 0xB58, 0xE0008208,
+ 0xB5C, 0x41EFFFF9,
+ 0xB60, 0x00000000,
+ 0xB64, 0x00200063,
+ 0xB68, 0x0000003A,
+ 0xB6C, 0x00000102,
+ 0xB70, 0x4E6D1870,
+ 0xB74, 0x03020100,
+ 0xB78, 0x07060504,
+ 0xB7C, 0x0B0A0908,
+ 0xB80, 0x0F0E0D0C,
+ 0xB84, 0x13121110,
+ 0xB88, 0x00000000,
+ 0xB8C, 0x00000000,
+ 0xC00, 0x00000007,
+ 0xC04, 0x03050020,
+ 0xC08, 0x60403231,
+ 0xC0C, 0x00012345,
+ 0xC10, 0x00000100,
+ 0xC14, 0x01000000,
+ 0xC18, 0x00000000,
+ 0xC1C, 0x40040053,
+ 0xC20, 0x400503A3,
+ 0xC24, 0x00000000,
+ 0xC28, 0x00000000,
+ 0xC2C, 0x00000000,
+ 0xC30, 0x00000000,
+ 0xC34, 0x00000000,
+ 0xC38, 0x00000000,
+ 0xC3C, 0x00000000,
+ 0xC40, 0x00000000,
+ 0xC44, 0x00000000,
+ 0xC48, 0x00000000,
+ 0xC4C, 0x00000000,
+ 0xC50, 0x00000020,
+ 0xC54, 0x00000000,
+ 0xC58, 0xD8020402,
+ 0xC5C, 0xDE000120,
+ 0xC68, 0x0000003F,
+ 0xC6C, 0x0000122A,
+ 0xC70, 0x00000000,
+ 0xC74, 0x00000000,
+ 0xC78, 0x00000000,
+ 0xC7C, 0x00000000,
+ 0xC80, 0x00000000,
+ 0xC84, 0x00000000,
+ 0xC88, 0x00000000,
+ 0xC8C, 0x07000000,
+ 0xC94, 0x01000100,
+ 0xC98, 0x201C8000,
+ 0xC9C, 0x00000000,
+ 0xCA0, 0x0000A555,
+ 0xCA4, 0x08040201,
+ 0xCA8, 0x80402010,
+ 0xCAC, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0xCB0, 0x77777717,
+ 0xCB4, 0x00000073,
+ 0xA0000000, 0x00000000,
+ 0xCB0, 0x77775747,
+ 0xCB4, 0x10000077,
+ 0xB0000000, 0x00000000,
+ 0xCB8, 0x00000000,
+ 0xCBC, 0x00000000,
+ 0xCC0, 0x00000000,
+ 0xCC4, 0x00000000,
+ 0xCC8, 0x00000000,
+ 0xCCC, 0x00000000,
+ 0xCD0, 0x00000000,
+ 0xCD4, 0x00000000,
+ 0xCD8, 0x00000000,
+ 0xCDC, 0x00000000,
+ 0xCE0, 0x00000000,
+ 0xCE4, 0x00000000,
+ 0xCE8, 0x00000000,
+ 0xCEC, 0x00000000,
+ 0xE00, 0x00000007,
+ 0xE04, 0x00000020,
+ 0xE08, 0x60403231,
+ 0xE0C, 0x00012345,
+ 0xE10, 0x00000100,
+ 0xE14, 0x01000000,
+ 0xE18, 0x00000000,
+ 0xE1C, 0x40040053,
+ 0xE20, 0x00020103,
+ 0xE24, 0x00000000,
+ 0xE28, 0x00000000,
+ 0xE2C, 0x00000000,
+ 0xE30, 0x00000000,
+ 0xE34, 0x00000000,
+ 0xE38, 0x00000000,
+ 0xE3C, 0x00000000,
+ 0xE40, 0x00000000,
+ 0xE44, 0x00000000,
+ 0xE48, 0x00000000,
+ 0xE4C, 0x00000000,
+ 0xE50, 0x00000020,
+ 0xE54, 0x00000000,
+ 0xE58, 0xD8020402,
+ 0xE5C, 0xDE000120,
+ 0xE68, 0x59799979,
+ 0xE6C, 0x0000122A,
+ 0xE70, 0x99795979,
+ 0xE74, 0x99795979,
+ 0xE78, 0x99799979,
+ 0xE7C, 0x99791979,
+ 0xE80, 0x19791979,
+ 0xE84, 0x19791979,
+ 0xE88, 0x00000000,
+ 0xE8C, 0x07000000,
+ 0xE94, 0x01000100,
+ 0xE98, 0x201C8000,
+ 0xE9C, 0x00000000,
+ 0xEA0, 0x0000A555,
+ 0xEA4, 0x08040201,
+ 0xEA8, 0x80402010,
+ 0xEAC, 0x00000000,
+ 0xEB0, 0x98543210,
+ 0xEB4, 0x000000BA,
+ 0xEB8, 0x00000000,
+ 0xEBC, 0x00000000,
+ 0xEC0, 0x00000000,
+ 0xEC4, 0x00000000,
+ 0xEC8, 0x00000000,
+ 0xECC, 0x00000000,
+ 0xED0, 0x00000000,
+ 0xED4, 0x00000000,
+ 0xED8, 0x00000000,
+ 0xEDC, 0x00000000,
+ 0xEE0, 0x00000000,
+ 0xEE4, 0x00000000,
+ 0xEE8, 0x00000000,
+ 0xEEC, 0x00000000,
+ 0x1900, 0x00000000,
+ 0x1904, 0x00238000,
+ 0x1908, 0x00000000,
+ 0x190C, 0x00000000,
+ 0x1910, 0x00001800,
+ 0x1914, 0x00000000,
+ 0x1918, 0x00000000,
+ 0x191C, 0x00000000,
+ 0x1920, 0x00000000,
+ 0x1924, 0x00000000,
+ 0x1928, 0x00000000,
+ 0x192C, 0x00000000,
+ 0x1930, 0x00000000,
+ 0x1934, 0x00000000,
+ 0x1938, 0x00000000,
+ 0x193C, 0x00000000,
+ 0x1940, 0x00000000,
+ 0x1944, 0x00000000,
+ 0x1948, 0x00000000,
+ 0x194C, 0x00000000,
+ 0x1950, 0x00000000,
+ 0x1954, 0x00000000,
+ 0x1958, 0x00000000,
+ 0x195C, 0x00000000,
+ 0x1960, 0x00000000,
+ 0x1964, 0x00000000,
+ 0x1968, 0x00000000,
+ 0x196C, 0x00000000,
+ 0x1970, 0x00000000,
+ 0x1974, 0x00000000,
+ 0x1978, 0x00000000,
+ 0x197C, 0x00000000,
+ 0x1980, 0x00000000,
+ 0x1984, 0x03000000,
+ 0x1988, 0x21401E88,
+ 0x198C, 0x00004000,
+ 0x1990, 0x00000000,
+ 0x1994, 0x00000000,
+ 0x1998, 0x00000053,
+ 0x199C, 0x00000000,
+ 0x19A0, 0x00000000,
+ 0x19A4, 0x00000000,
+ 0x19A8, 0x010A0000,
+ 0x19AC, 0x0E47E47F,
+ 0x19B0, 0x00008000,
+ 0x19B4, 0x0E47E47F,
+ 0x19B8, 0x00000000,
+ 0x19BC, 0x00000000,
+ 0x19C0, 0x00000000,
+ 0x19C4, 0x00000000,
+ 0x19C8, 0x00000000,
+ 0x19CC, 0x00000000,
+ 0x19D0, 0x00000000,
+ 0x19D4, 0x77777777,
+ 0x19D8, 0x00000777,
+ 0x19DC, 0x133E0F37,
+ 0x19E0, 0x00000000,
+ 0x19E4, 0x00000000,
+ 0x19E8, 0x00000000,
+ 0x19EC, 0x00000000,
+ 0x19F0, 0x00000000,
+ 0x19F4, 0x00000000,
+ 0x19F8, 0x01A00000,
+ 0x19FC, 0x00000000,
+ 0x1C00, 0x00000100,
+ 0x1C04, 0x01000000,
+ 0x1C08, 0x00000100,
+ 0x1C0C, 0x01000000,
+ 0x1C10, 0x00000100,
+ 0x1C14, 0x01000000,
+ 0x1C18, 0x00000100,
+ 0x1C1C, 0x01000000,
+ 0x1C20, 0x00000100,
+ 0x1C24, 0x01000000,
+ 0x1C28, 0x00000100,
+ 0x1C2C, 0x01000000,
+ 0x1C30, 0x00000100,
+ 0x1C34, 0x01000000,
+ 0x1C38, 0x00000000,
+ 0x1C3C, 0x00008000,
+ 0x1C40, 0x000C0100,
+ 0x1C44, 0x000000F3,
+ 0x1C48, 0x1A8249A8,
+ 0x1C4C, 0x1461C826,
+ 0x1C50, 0x0001469E,
+ 0x1C54, 0x58D158D1,
+ 0x1C58, 0x04490088,
+ 0x1C5C, 0x04004400,
+ 0x1C60, 0x00000000,
+ 0x1C64, 0x04004400,
+ 0x1C68, 0x0B7B7B75,
+ 0x1C6C, 0x01000000,
+ 0x1C70, 0x00A08145,
+ 0x1C74, 0x2080E0E0,
+ 0x1C78, 0x00000000,
+ 0x1C7C, 0x00000010,
+ 0x1C80, 0x00000100,
+ 0x1C84, 0x01000000,
+ 0x1C88, 0x00000100,
+ 0x1C8C, 0x01000000,
+ 0x1C90, 0x00000100,
+ 0x1C94, 0x01000000,
+ 0x1C98, 0x00000100,
+ 0x1C9C, 0x01000000,
+ 0x1CA0, 0x00000100,
+ 0x1CA4, 0x01000000,
+ 0x1CA8, 0x00000100,
+ 0x1CAC, 0x01000000,
+ 0x1CB0, 0x00000100,
+ 0x1CB4, 0x01000000,
+ 0x1CB8, 0x00000000,
+ 0x1CBC, 0x00000000,
+ 0x1CC0, 0x201B0100,
+ 0x1CC4, 0x00308000,
+ 0x1CC8, 0x5B74B6E9,
+ 0x1CCC, 0x01000000,
+ 0x1CD0, 0x00000400,
+ 0x1CD4, 0x01000000,
+ 0x1CD8, 0x01B8ADEB,
+ 0x1CDC, 0x01000000,
+ 0x1CE0, 0x00030003,
+ 0x1CE4, 0x4E4A0306,
+ 0x1CE8, 0x00000100,
+ 0x1CEC, 0x01000000,
+ 0x1CF0, 0x00000100,
+ 0x1CF4, 0x01000000,
+ 0x1CF8, 0x01B8ADEB,
+ 0x1CFC, 0x00000000,
+ 0xC60, 0x700B8040,
+ 0xC60, 0x700B8040,
+ 0xC60, 0x70146040,
+ 0xC60, 0x70246040,
+ 0xC60, 0x70346040,
+ 0xC60, 0x70446040,
+ 0xC60, 0x705B2040,
+ 0xC60, 0x70646040,
+ 0xC60, 0x707B8040,
+ 0xC60, 0x708B8040,
+ 0xC60, 0x709B8040,
+ 0xC60, 0x70AB8040,
+ 0xC60, 0x70BB6040,
+ 0xC60, 0x70C06040,
+ 0xC60, 0x70D06040,
+ 0xC60, 0x70EF6040,
+ 0xC60, 0x70F06040,
+ 0xE60, 0x700B8040,
+ 0xE60, 0x700B8040,
+ 0xE60, 0x70146040,
+ 0xE60, 0x70246040,
+ 0xE60, 0x70346040,
+ 0xE60, 0x70446040,
+ 0xE60, 0x705B2040,
+ 0xE60, 0x70646040,
+ 0xE60, 0x707B8040,
+ 0xE60, 0x708B8040,
+ 0xE60, 0x709B8040,
+ 0xE60, 0x70AB8040,
+ 0xE60, 0x70BB6040,
+ 0xE60, 0x70C06040,
+ 0xE60, 0x70D06040,
+ 0xE60, 0x70EF6040,
+ 0xE60, 0x70F06040,
+ 0xC64, 0x00800000,
+ 0xC64, 0x08800001,
+ 0xC64, 0x00800002,
+ 0xC64, 0x00800003,
+ 0xC64, 0x00800004,
+ 0xC64, 0x00800005,
+ 0xC64, 0x00800006,
+ 0xC64, 0x08800007,
+ 0xC64, 0x00004000,
+ 0xE64, 0x00800000,
+ 0xE64, 0x08800001,
+ 0xE64, 0x00800002,
+ 0xE64, 0x00800003,
+ 0xE64, 0x00800004,
+ 0xE64, 0x00800005,
+ 0xE64, 0x00800006,
+ 0xE64, 0x08800007,
+ 0xE64, 0x00004000,
+ 0x1B00, 0xF8000008,
+ 0x1B00, 0xF80A7008,
+ 0x1B00, 0xF8015008,
+ 0x1B00, 0xF8000008,
+ 0x1B04, 0xE24629D2,
+ 0x1B08, 0x00000080,
+ 0x1B0C, 0x00000000,
+ 0x1B10, 0x00011C00,
+ 0x1B14, 0x00000000,
+ 0x1B18, 0x00292903,
+ 0x1B1C, 0xA2193C32,
+ 0x1B20, 0x01840008,
+ 0x1B24, 0x01860008,
+ 0x1B28, 0x80060300,
+ 0x1B2C, 0x00000003,
+ 0x1B30, 0x20000000,
+ 0x1B34, 0x00000800,
+ 0x1B3C, 0x20000000,
+ 0x1BC0, 0x01000000,
+ 0x1BCC, 0x00000000,
+ 0x1B90, 0x0001E018,
+ 0x1B94, 0xF76D9F84,
+ 0x1BC8, 0x000C44AA,
+ 0x1BCC, 0x11978200,
+ 0x1B8C, 0x00002000,
+ 0x1B9C, 0x5B554F48,
+ 0x1BA0, 0x6F6B6661,
+ 0x1BA4, 0x817D7874,
+ 0x1BA8, 0x908C8884,
+ 0x1BAC, 0x9D9A9793,
+ 0x1BB0, 0xAAA7A4A1,
+ 0x1BB4, 0xB6B3B0AD,
+ 0x1B40, 0x02CE03E8,
+ 0x1B44, 0x01FD024C,
+ 0x1B48, 0x01A101C9,
+ 0x1B4C, 0x016A0183,
+ 0x1B50, 0x01430153,
+ 0x1B54, 0x01280134,
+ 0x1B58, 0x0112011C,
+ 0x1B5C, 0x01000107,
+ 0x1B60, 0x00F200F9,
+ 0x1B64, 0x00E500EB,
+ 0x1B68, 0x00DA00E0,
+ 0x1B6C, 0x00D200D6,
+ 0x1B70, 0x00C900CD,
+ 0x1B74, 0x00C200C5,
+ 0x1B78, 0x00BB00BE,
+ 0x1B7C, 0x00B500B8,
+ 0x1BDC, 0x40CAFFE1,
+ 0x1BDC, 0x4080A1E3,
+ 0x1BDC, 0x405165E5,
+ 0x1BDC, 0x403340E7,
+ 0x1BDC, 0x402028E9,
+ 0x1BDC, 0x401419EB,
+ 0x1BDC, 0x400D10ED,
+ 0x1BDC, 0x40080AEF,
+ 0x1BDC, 0x400506F1,
+ 0x1BDC, 0x400304F3,
+ 0x1BDC, 0x400203F5,
+ 0x1BDC, 0x400102F7,
+ 0x1BDC, 0x400101F9,
+ 0x1BDC, 0x400101FB,
+ 0x1BDC, 0x400101FD,
+ 0x1BDC, 0x400101FF,
+ 0x1BDC, 0x40CAFF81,
+ 0x1BDC, 0x4080A183,
+ 0x1BDC, 0x40516585,
+ 0x1BDC, 0x40334087,
+ 0x1BDC, 0x40202889,
+ 0x1BDC, 0x4014198B,
+ 0x1BDC, 0x400D108D,
+ 0x1BDC, 0x40080A8F,
+ 0x1BDC, 0x40050691,
+ 0x1BDC, 0x40030493,
+ 0x1BDC, 0x40020395,
+ 0x1BDC, 0x40010297,
+ 0x1BDC, 0x40010199,
+ 0x1BDC, 0x4001019B,
+ 0x1BDC, 0x4001019D,
+ 0x1BDC, 0x4001019F,
+ 0x1BDC, 0x00000000,
+ 0x1BDC, 0xD0000001,
+ 0x1BDC, 0xD0000003,
+ 0x1BDC, 0xD0000005,
+ 0x1BDC, 0xD0000007,
+ 0x1BDC, 0xD0000009,
+ 0x1BDC, 0xD000000B,
+ 0x1BDC, 0xD000000D,
+ 0x1BDC, 0xD000000F,
+ 0x1BDC, 0xD0000011,
+ 0x1BDC, 0xD0000013,
+ 0x1BDC, 0xD0000015,
+ 0x1BDC, 0xD0000017,
+ 0x1BDC, 0xD0000019,
+ 0x1BDC, 0xD000001B,
+ 0x1BDC, 0xD000001D,
+ 0x1BDC, 0xD000001F,
+ 0x1BDC, 0xD0000021,
+ 0x1BDC, 0xD0000023,
+ 0x1BDC, 0xD0000025,
+ 0x1BDC, 0xD0000027,
+ 0x1BDC, 0xD0000029,
+ 0x1BDC, 0xD000002B,
+ 0x1BDC, 0xD000002D,
+ 0x1BDC, 0xD000002F,
+ 0x1BDC, 0xD0000031,
+ 0x1BDC, 0xD0000033,
+ 0x1BDC, 0xD0000035,
+ 0x1BDC, 0xD0000037,
+ 0x1BDC, 0xD0000039,
+ 0x1BDC, 0xD000003B,
+ 0x1BDC, 0xD000003D,
+ 0x1BDC, 0xD000003F,
+ 0x1BDC, 0xD0000041,
+ 0x1BDC, 0xD0000043,
+ 0x1BDC, 0xD0000045,
+ 0x1BDC, 0xD0000047,
+ 0x1BDC, 0xD0000049,
+ 0x1BDC, 0xD000004B,
+ 0x1BDC, 0xD000004D,
+ 0x1BDC, 0xD000004F,
+ 0x1BDC, 0xD0000051,
+ 0x1BDC, 0xD0000053,
+ 0x1BDC, 0xD0000055,
+ 0x1BDC, 0xD0000057,
+ 0x1BDC, 0xD0000059,
+ 0x1BDC, 0xD000005B,
+ 0x1BDC, 0xD000005D,
+ 0x1BDC, 0xD000005F,
+ 0x1BDC, 0xD0000061,
+ 0x1BDC, 0xD0000063,
+ 0x1BDC, 0xD0000065,
+ 0x1BDC, 0xD0000067,
+ 0x1BDC, 0xD0000069,
+ 0x1BDC, 0xD000006B,
+ 0x1BDC, 0xD000006D,
+ 0x1BDC, 0xD000006F,
+ 0x1BDC, 0xD0000071,
+ 0x1BDC, 0xD0000073,
+ 0x1BDC, 0xD0000075,
+ 0x1BDC, 0xD0000077,
+ 0x1BDC, 0xD0000079,
+ 0x1BDC, 0xD000007B,
+ 0x1BDC, 0xD000007D,
+ 0x1BDC, 0xD000007F,
+ 0x1BDC, 0x90000081,
+ 0x1BDC, 0x90000083,
+ 0x1BDC, 0x90000085,
+ 0x1BDC, 0x90000087,
+ 0x1BDC, 0x90000089,
+ 0x1BDC, 0x9000008B,
+ 0x1BDC, 0x9000008D,
+ 0x1BDC, 0x9000008F,
+ 0x1BDC, 0x90000091,
+ 0x1BDC, 0x90000093,
+ 0x1BDC, 0x90000095,
+ 0x1BDC, 0x90000097,
+ 0x1BDC, 0x90000099,
+ 0x1BDC, 0x9000009B,
+ 0x1BDC, 0x9000009D,
+ 0x1BDC, 0x9000009F,
+ 0x1BDC, 0x900000A1,
+ 0x1BDC, 0x900000A3,
+ 0x1BDC, 0x900000A5,
+ 0x1BDC, 0x900000A7,
+ 0x1BDC, 0x900000A9,
+ 0x1BDC, 0x900000AB,
+ 0x1BDC, 0x900000AD,
+ 0x1BDC, 0x900000AF,
+ 0x1BDC, 0x900000B1,
+ 0x1BDC, 0x900000B3,
+ 0x1BDC, 0x900000B5,
+ 0x1BDC, 0x900000B7,
+ 0x1BDC, 0x900000B9,
+ 0x1BDC, 0x900000BB,
+ 0x1BDC, 0x900000BD,
+ 0x1BDC, 0x900000BF,
+ 0x1BDC, 0x900000C1,
+ 0x1BDC, 0x900000C3,
+ 0x1BDC, 0x900000C5,
+ 0x1BDC, 0x900000C7,
+ 0x1BDC, 0x900000C9,
+ 0x1BDC, 0x900000CB,
+ 0x1BDC, 0x900000CD,
+ 0x1BDC, 0x900000CF,
+ 0x1BDC, 0x900000D1,
+ 0x1BDC, 0x900000D3,
+ 0x1BDC, 0x900000D5,
+ 0x1BDC, 0x900000D7,
+ 0x1BDC, 0x900000D9,
+ 0x1BDC, 0x900000DB,
+ 0x1BDC, 0x900000DD,
+ 0x1BDC, 0x900000DF,
+ 0x1BDC, 0x900000E1,
+ 0x1BDC, 0x900000E3,
+ 0x1BDC, 0x900000E5,
+ 0x1BDC, 0x900000E7,
+ 0x1BDC, 0x900000E9,
+ 0x1BDC, 0x900000EB,
+ 0x1BDC, 0x900000ED,
+ 0x1BDC, 0x900000EF,
+ 0x1BDC, 0x900000F1,
+ 0x1BDC, 0x900000F3,
+ 0x1BDC, 0x900000F5,
+ 0x1BDC, 0x900000F7,
+ 0x1BDC, 0x900000F9,
+ 0x1BDC, 0x900000FB,
+ 0x1BDC, 0x900000FD,
+ 0x1BDC, 0x900000FF,
+ 0x1BDC, 0x00000000,
+ 0x1B00, 0xF8000000,
+ 0x1B80, 0x00000007,
+ 0x1B80, 0x090A0005,
+ 0x1B80, 0x090A0007,
+ 0x1B80, 0x0FFE0015,
+ 0x1B80, 0x0FFE0017,
+ 0x1B80, 0x00220025,
+ 0x1B80, 0x00220027,
+ 0x1B80, 0x00040035,
+ 0x1B80, 0x00040037,
+ 0x1B80, 0x05C00045,
+ 0x1B80, 0x05C00047,
+ 0x1B80, 0x00070055,
+ 0x1B80, 0x00070057,
+ 0x1B80, 0x64000065,
+ 0x1B80, 0x64000067,
+ 0x1B80, 0x00020075,
+ 0x1B80, 0x00020077,
+ 0x1B80, 0x00080085,
+ 0x1B80, 0x00080087,
+ 0x1B80, 0x80000095,
+ 0x1B80, 0x80000097,
+ 0x1B80, 0x090800A5,
+ 0x1B80, 0x090800A7,
+ 0x1B80, 0x0F0200B5,
+ 0x1B80, 0x0F0200B7,
+ 0x1B80, 0x002200C5,
+ 0x1B80, 0x002200C7,
+ 0x1B80, 0x000400D5,
+ 0x1B80, 0x000400D7,
+ 0x1B80, 0x05C000E5,
+ 0x1B80, 0x05C000E7,
+ 0x1B80, 0x000700F5,
+ 0x1B80, 0x000700F7,
+ 0x1B80, 0x64020105,
+ 0x1B80, 0x64020107,
+ 0x1B80, 0x00020115,
+ 0x1B80, 0x00020117,
+ 0x1B80, 0x00040125,
+ 0x1B80, 0x00040127,
+ 0x1B80, 0x4A000135,
+ 0x1B80, 0x4A000137,
+ 0x1B80, 0x4B040145,
+ 0x1B80, 0x4B040147,
+ 0x1B80, 0x85030155,
+ 0x1B80, 0x85030157,
+ 0x1B80, 0x40090165,
+ 0x1B80, 0x40090167,
+ 0x1B80, 0xE02A0175,
+ 0x1B80, 0xE02A0177,
+ 0x1B80, 0x4B050185,
+ 0x1B80, 0x4B050187,
+ 0x1B80, 0x86030195,
+ 0x1B80, 0x86030197,
+ 0x1B80, 0x400B01A5,
+ 0x1B80, 0x400B01A7,
+ 0x1B80, 0xE02A01B5,
+ 0x1B80, 0xE02A01B7,
+ 0x1B80, 0x4B0001C5,
+ 0x1B80, 0x4B0001C7,
+ 0x1B80, 0x000701D5,
+ 0x1B80, 0x000701D7,
+ 0x1B80, 0x4C0001E5,
+ 0x1B80, 0x4C0001E7,
+ 0x1B80, 0x000401F5,
+ 0x1B80, 0x000401F7,
+ 0x1B80, 0x4D040205,
+ 0x1B80, 0x4D040207,
+ 0x1B80, 0x2EE00215,
+ 0x1B80, 0x2EE00217,
+ 0x1B80, 0x00000225,
+ 0x1B80, 0x00000227,
+ 0x1B80, 0x2EF00235,
+ 0x1B80, 0x2EF00237,
+ 0x1B80, 0x00000245,
+ 0x1B80, 0x00000247,
+ 0x1B80, 0x20810255,
+ 0x1B80, 0x20810257,
+ 0x1B80, 0x23450265,
+ 0x1B80, 0x23450267,
+ 0x1B80, 0x4D000275,
+ 0x1B80, 0x4D000277,
+ 0x1B80, 0x00040285,
+ 0x1B80, 0x00040287,
+ 0x1B80, 0x30000295,
+ 0x1B80, 0x30000297,
+ 0x1B80, 0xE1D602A5,
+ 0x1B80, 0xE1D602A7,
+ 0x1B80, 0xF01102B5,
+ 0x1B80, 0xF01102B7,
+ 0x1B80, 0xF11102C5,
+ 0x1B80, 0xF11102C7,
+ 0x1B80, 0xF21102D5,
+ 0x1B80, 0xF21102D7,
+ 0x1B80, 0xF31102E5,
+ 0x1B80, 0xF31102E7,
+ 0x1B80, 0xF41102F5,
+ 0x1B80, 0xF41102F7,
+ 0x1B80, 0xF5110305,
+ 0x1B80, 0xF5110307,
+ 0x1B80, 0xF6110315,
+ 0x1B80, 0xF6110317,
+ 0x1B80, 0xF7110325,
+ 0x1B80, 0xF7110327,
+ 0x1B80, 0xF8110335,
+ 0x1B80, 0xF8110337,
+ 0x1B80, 0xF9110345,
+ 0x1B80, 0xF9110347,
+ 0x1B80, 0xFA110355,
+ 0x1B80, 0xFA110357,
+ 0x1B80, 0xFB110365,
+ 0x1B80, 0xFB110367,
+ 0x1B80, 0xFC110375,
+ 0x1B80, 0xFC110377,
+ 0x1B80, 0xFD110385,
+ 0x1B80, 0xFD110387,
+ 0x1B80, 0xFE110395,
+ 0x1B80, 0xFE110397,
+ 0x1B80, 0xFF1103A5,
+ 0x1B80, 0xFF1103A7,
+ 0x1B80, 0x000103B5,
+ 0x1B80, 0x000103B7,
+ 0x1B80, 0x305503C5,
+ 0x1B80, 0x305503C7,
+ 0x1B80, 0x306D03D5,
+ 0x1B80, 0x306D03D7,
+ 0x1B80, 0x30B803E5,
+ 0x1B80, 0x30B803E7,
+ 0x1B80, 0x30BB03F5,
+ 0x1B80, 0x30BB03F7,
+ 0x1B80, 0x306F0405,
+ 0x1B80, 0x306F0407,
+ 0x1B80, 0x307A0415,
+ 0x1B80, 0x307A0417,
+ 0x1B80, 0x30850425,
+ 0x1B80, 0x30850427,
+ 0x1B80, 0x30C50435,
+ 0x1B80, 0x30C50437,
+ 0x1B80, 0x30BF0445,
+ 0x1B80, 0x30BF0447,
+ 0x1B80, 0x30D30455,
+ 0x1B80, 0x30D30457,
+ 0x1B80, 0x30DE0465,
+ 0x1B80, 0x30DE0467,
+ 0x1B80, 0x30E90475,
+ 0x1B80, 0x30E90477,
+ 0x1B80, 0x304C0485,
+ 0x1B80, 0x304C0487,
+ 0x1B80, 0x31180495,
+ 0x1B80, 0x31180497,
+ 0x1B80, 0x312904A5,
+ 0x1B80, 0x312904A7,
+ 0x1B80, 0x313E04B5,
+ 0x1B80, 0x313E04B7,
+ 0x1B80, 0x4D0404C5,
+ 0x1B80, 0x4D0404C7,
+ 0x1B80, 0x2EE004D5,
+ 0x1B80, 0x2EE004D7,
+ 0x1B80, 0x000004E5,
+ 0x1B80, 0x000004E7,
+ 0x1B80, 0x2EF004F5,
+ 0x1B80, 0x2EF004F7,
+ 0x1B80, 0x00000505,
+ 0x1B80, 0x00000507,
+ 0x1B80, 0x20810515,
+ 0x1B80, 0x20810517,
+ 0x1B80, 0xA3B50525,
+ 0x1B80, 0xA3B50527,
+ 0x1B80, 0x4D000535,
+ 0x1B80, 0x4D000537,
+ 0x1B80, 0x30000545,
+ 0x1B80, 0x30000547,
+ 0x1B80, 0xE1690555,
+ 0x1B80, 0xE1690557,
+ 0x1B80, 0x4D040565,
+ 0x1B80, 0x4D040567,
+ 0x1B80, 0x20800575,
+ 0x1B80, 0x20800577,
+ 0x1B80, 0x00000585,
+ 0x1B80, 0x00000587,
+ 0x1B80, 0x4D000595,
+ 0x1B80, 0x4D000597,
+ 0x1B80, 0x550705A5,
+ 0x1B80, 0x550705A7,
+ 0x1B80, 0xE16105B5,
+ 0x1B80, 0xE16105B7,
+ 0x1B80, 0xE16105C5,
+ 0x1B80, 0xE16105C7,
+ 0x1B80, 0x4D0405D5,
+ 0x1B80, 0x4D0405D7,
+ 0x1B80, 0x208805E5,
+ 0x1B80, 0x208805E7,
+ 0x1B80, 0x020005F5,
+ 0x1B80, 0x020005F7,
+ 0x1B80, 0x4D000605,
+ 0x1B80, 0x4D000607,
+ 0x1B80, 0x550F0615,
+ 0x1B80, 0x550F0617,
+ 0x1B80, 0xE1610625,
+ 0x1B80, 0xE1610627,
+ 0x1B80, 0x4F020635,
+ 0x1B80, 0x4F020637,
+ 0x1B80, 0x4E000645,
+ 0x1B80, 0x4E000647,
+ 0x1B80, 0x53020655,
+ 0x1B80, 0x53020657,
+ 0x1B80, 0x52010665,
+ 0x1B80, 0x52010667,
+ 0x1B80, 0xE1650675,
+ 0x1B80, 0xE1650677,
+ 0x1B80, 0x4D080685,
+ 0x1B80, 0x4D080687,
+ 0x1B80, 0x57100695,
+ 0x1B80, 0x57100697,
+ 0x1B80, 0x570006A5,
+ 0x1B80, 0x570006A7,
+ 0x1B80, 0x4D0006B5,
+ 0x1B80, 0x4D0006B7,
+ 0x1B80, 0x000106C5,
+ 0x1B80, 0x000106C7,
+ 0x1B80, 0xE16906D5,
+ 0x1B80, 0xE16906D7,
+ 0x1B80, 0x000106E5,
+ 0x1B80, 0x000106E7,
+ 0x1B80, 0x308F06F5,
+ 0x1B80, 0x308F06F7,
+ 0x1B80, 0x00230705,
+ 0x1B80, 0x00230707,
+ 0x1B80, 0xE1C90715,
+ 0x1B80, 0xE1C90717,
+ 0x1B80, 0x00020725,
+ 0x1B80, 0x00020727,
+ 0x1B80, 0x54E90735,
+ 0x1B80, 0x54E90737,
+ 0x1B80, 0x0BA60745,
+ 0x1B80, 0x0BA60747,
+ 0x1B80, 0x00230755,
+ 0x1B80, 0x00230757,
+ 0x1B80, 0xE1C90765,
+ 0x1B80, 0xE1C90767,
+ 0x1B80, 0x00020775,
+ 0x1B80, 0x00020777,
+ 0x1B80, 0x4D300785,
+ 0x1B80, 0x4D300787,
+ 0x1B80, 0x30A80795,
+ 0x1B80, 0x30A80797,
+ 0x1B80, 0x308B07A5,
+ 0x1B80, 0x308B07A7,
+ 0x1B80, 0x002207B5,
+ 0x1B80, 0x002207B7,
+ 0x1B80, 0xE1C907C5,
+ 0x1B80, 0xE1C907C7,
+ 0x1B80, 0x000207D5,
+ 0x1B80, 0x000207D7,
+ 0x1B80, 0x54E807E5,
+ 0x1B80, 0x54E807E7,
+ 0x1B80, 0x0BA607F5,
+ 0x1B80, 0x0BA607F7,
+ 0x1B80, 0x00220805,
+ 0x1B80, 0x00220807,
+ 0x1B80, 0xE1C90815,
+ 0x1B80, 0xE1C90817,
+ 0x1B80, 0x00020825,
+ 0x1B80, 0x00020827,
+ 0x1B80, 0x4D300835,
+ 0x1B80, 0x4D300837,
+ 0x1B80, 0x30A80845,
+ 0x1B80, 0x30A80847,
+ 0x1B80, 0x63F10855,
+ 0x1B80, 0x63F10857,
+ 0x1B80, 0xE1690865,
+ 0x1B80, 0xE1690867,
+ 0x1B80, 0xE1C90875,
+ 0x1B80, 0xE1C90877,
+ 0x1B80, 0x63F40885,
+ 0x1B80, 0x63F40887,
+ 0x1B80, 0xE1690895,
+ 0x1B80, 0xE1690897,
+ 0x1B80, 0xE1C908A5,
+ 0x1B80, 0xE1C908A7,
+ 0x1B80, 0x0BA808B5,
+ 0x1B80, 0x0BA808B7,
+ 0x1B80, 0x63F808C5,
+ 0x1B80, 0x63F808C7,
+ 0x1B80, 0xE16908D5,
+ 0x1B80, 0xE16908D7,
+ 0x1B80, 0xE1C908E5,
+ 0x1B80, 0xE1C908E7,
+ 0x1B80, 0x0BA908F5,
+ 0x1B80, 0x0BA908F7,
+ 0x1B80, 0x63FC0905,
+ 0x1B80, 0x63FC0907,
+ 0x1B80, 0xE1690915,
+ 0x1B80, 0xE1690917,
+ 0x1B80, 0xE1C90925,
+ 0x1B80, 0xE1C90927,
+ 0x1B80, 0x63FF0935,
+ 0x1B80, 0x63FF0937,
+ 0x1B80, 0xE1690945,
+ 0x1B80, 0xE1690947,
+ 0x1B80, 0xE1C90955,
+ 0x1B80, 0xE1C90957,
+ 0x1B80, 0x63000965,
+ 0x1B80, 0x63000967,
+ 0x1B80, 0xE1690975,
+ 0x1B80, 0xE1690977,
+ 0x1B80, 0xE1C90985,
+ 0x1B80, 0xE1C90987,
+ 0x1B80, 0x63030995,
+ 0x1B80, 0x63030997,
+ 0x1B80, 0xE16909A5,
+ 0x1B80, 0xE16909A7,
+ 0x1B80, 0xE1C909B5,
+ 0x1B80, 0xE1C909B7,
+ 0x1B80, 0xF4D409C5,
+ 0x1B80, 0xF4D409C7,
+ 0x1B80, 0x630709D5,
+ 0x1B80, 0x630709D7,
+ 0x1B80, 0xE16909E5,
+ 0x1B80, 0xE16909E7,
+ 0x1B80, 0xE1C909F5,
+ 0x1B80, 0xE1C909F7,
+ 0x1B80, 0xF5DB0A05,
+ 0x1B80, 0xF5DB0A07,
+ 0x1B80, 0x630B0A15,
+ 0x1B80, 0x630B0A17,
+ 0x1B80, 0xE1690A25,
+ 0x1B80, 0xE1690A27,
+ 0x1B80, 0xE1C90A35,
+ 0x1B80, 0xE1C90A37,
+ 0x1B80, 0x630E0A45,
+ 0x1B80, 0x630E0A47,
+ 0x1B80, 0xE1690A55,
+ 0x1B80, 0xE1690A57,
+ 0x1B80, 0xE1C90A65,
+ 0x1B80, 0xE1C90A67,
+ 0x1B80, 0x4D300A75,
+ 0x1B80, 0x4D300A77,
+ 0x1B80, 0x55010A85,
+ 0x1B80, 0x55010A87,
+ 0x1B80, 0x57040A95,
+ 0x1B80, 0x57040A97,
+ 0x1B80, 0x57000AA5,
+ 0x1B80, 0x57000AA7,
+ 0x1B80, 0x96000AB5,
+ 0x1B80, 0x96000AB7,
+ 0x1B80, 0x57080AC5,
+ 0x1B80, 0x57080AC7,
+ 0x1B80, 0x57000AD5,
+ 0x1B80, 0x57000AD7,
+ 0x1B80, 0x95000AE5,
+ 0x1B80, 0x95000AE7,
+ 0x1B80, 0x4D000AF5,
+ 0x1B80, 0x4D000AF7,
+ 0x1B80, 0x6C070B05,
+ 0x1B80, 0x6C070B07,
+ 0x1B80, 0x7B200B15,
+ 0x1B80, 0x7B200B17,
+ 0x1B80, 0x7A000B25,
+ 0x1B80, 0x7A000B27,
+ 0x1B80, 0x79000B35,
+ 0x1B80, 0x79000B37,
+ 0x1B80, 0x7F200B45,
+ 0x1B80, 0x7F200B47,
+ 0x1B80, 0x7E000B55,
+ 0x1B80, 0x7E000B57,
+ 0x1B80, 0x7D000B65,
+ 0x1B80, 0x7D000B67,
+ 0x1B80, 0x00010B75,
+ 0x1B80, 0x00010B77,
+ 0x1B80, 0x62850B85,
+ 0x1B80, 0x62850B87,
+ 0x1B80, 0xE1690B95,
+ 0x1B80, 0xE1690B97,
+ 0x1B80, 0x00010BA5,
+ 0x1B80, 0x00010BA7,
+ 0x1B80, 0x5C320BB5,
+ 0x1B80, 0x5C320BB7,
+ 0x1B80, 0xE1C50BC5,
+ 0x1B80, 0xE1C50BC7,
+ 0x1B80, 0xE1950BD5,
+ 0x1B80, 0xE1950BD7,
+ 0x1B80, 0x00010BE5,
+ 0x1B80, 0x00010BE7,
+ 0x1B80, 0x5C320BF5,
+ 0x1B80, 0x5C320BF7,
+ 0x1B80, 0x63F40C05,
+ 0x1B80, 0x63F40C07,
+ 0x1B80, 0x62850C15,
+ 0x1B80, 0x62850C17,
+ 0x1B80, 0x0BB00C25,
+ 0x1B80, 0x0BB00C27,
+ 0x1B80, 0xE1690C35,
+ 0x1B80, 0xE1690C37,
+ 0x1B80, 0xE1C90C45,
+ 0x1B80, 0xE1C90C47,
+ 0x1B80, 0x5C320C55,
+ 0x1B80, 0x5C320C57,
+ 0x1B80, 0x63FC0C65,
+ 0x1B80, 0x63FC0C67,
+ 0x1B80, 0x62850C75,
+ 0x1B80, 0x62850C77,
+ 0x1B80, 0x0BB10C85,
+ 0x1B80, 0x0BB10C87,
+ 0x1B80, 0xE1690C95,
+ 0x1B80, 0xE1690C97,
+ 0x1B80, 0xE1C90CA5,
+ 0x1B80, 0xE1C90CA7,
+ 0x1B80, 0x63030CB5,
+ 0x1B80, 0x63030CB7,
+ 0x1B80, 0xE1690CC5,
+ 0x1B80, 0xE1690CC7,
+ 0x1B80, 0xE1C90CD5,
+ 0x1B80, 0xE1C90CD7,
+ 0x1B80, 0xF7040CE5,
+ 0x1B80, 0xF7040CE7,
+ 0x1B80, 0x630B0CF5,
+ 0x1B80, 0x630B0CF7,
+ 0x1B80, 0xE1690D05,
+ 0x1B80, 0xE1690D07,
+ 0x1B80, 0xE1C90D15,
+ 0x1B80, 0xE1C90D17,
+ 0x1B80, 0x00010D25,
+ 0x1B80, 0x00010D27,
+ 0x1B80, 0x30F70D35,
+ 0x1B80, 0x30F70D37,
+ 0x1B80, 0x00230D45,
+ 0x1B80, 0x00230D47,
+ 0x1B80, 0xE1CE0D55,
+ 0x1B80, 0xE1CE0D57,
+ 0x1B80, 0x00020D65,
+ 0x1B80, 0x00020D67,
+ 0x1B80, 0x54E90D75,
+ 0x1B80, 0x54E90D77,
+ 0x1B80, 0x0BA60D85,
+ 0x1B80, 0x0BA60D87,
+ 0x1B80, 0x00230D95,
+ 0x1B80, 0x00230D97,
+ 0x1B80, 0xE1CE0DA5,
+ 0x1B80, 0xE1CE0DA7,
+ 0x1B80, 0x00020DB5,
+ 0x1B80, 0x00020DB7,
+ 0x1B80, 0x4D100DC5,
+ 0x1B80, 0x4D100DC7,
+ 0x1B80, 0x30A80DD5,
+ 0x1B80, 0x30A80DD7,
+ 0x1B80, 0x30F10DE5,
+ 0x1B80, 0x30F10DE7,
+ 0x1B80, 0x00220DF5,
+ 0x1B80, 0x00220DF7,
+ 0x1B80, 0xE1CE0E05,
+ 0x1B80, 0xE1CE0E07,
+ 0x1B80, 0x00020E15,
+ 0x1B80, 0x00020E17,
+ 0x1B80, 0x54E80E25,
+ 0x1B80, 0x54E80E27,
+ 0x1B80, 0x0BA60E35,
+ 0x1B80, 0x0BA60E37,
+ 0x1B80, 0x00220E45,
+ 0x1B80, 0x00220E47,
+ 0x1B80, 0xE1CE0E55,
+ 0x1B80, 0xE1CE0E57,
+ 0x1B80, 0x00020E65,
+ 0x1B80, 0x00020E67,
+ 0x1B80, 0x4D100E75,
+ 0x1B80, 0x4D100E77,
+ 0x1B80, 0x30A80E85,
+ 0x1B80, 0x30A80E87,
+ 0x1B80, 0x5C320E95,
+ 0x1B80, 0x5C320E97,
+ 0x1B80, 0x54F00EA5,
+ 0x1B80, 0x54F00EA7,
+ 0x1B80, 0x67F10EB5,
+ 0x1B80, 0x67F10EB7,
+ 0x1B80, 0xE1950EC5,
+ 0x1B80, 0xE1950EC7,
+ 0x1B80, 0xE1CE0ED5,
+ 0x1B80, 0xE1CE0ED7,
+ 0x1B80, 0x67F40EE5,
+ 0x1B80, 0x67F40EE7,
+ 0x1B80, 0xE1950EF5,
+ 0x1B80, 0xE1950EF7,
+ 0x1B80, 0xE1CE0F05,
+ 0x1B80, 0xE1CE0F07,
+ 0x1B80, 0x5C320F15,
+ 0x1B80, 0x5C320F17,
+ 0x1B80, 0x54F10F25,
+ 0x1B80, 0x54F10F27,
+ 0x1B80, 0x0BA80F35,
+ 0x1B80, 0x0BA80F37,
+ 0x1B80, 0x67F80F45,
+ 0x1B80, 0x67F80F47,
+ 0x1B80, 0xE1950F55,
+ 0x1B80, 0xE1950F57,
+ 0x1B80, 0xE1CE0F65,
+ 0x1B80, 0xE1CE0F67,
+ 0x1B80, 0x5C320F75,
+ 0x1B80, 0x5C320F77,
+ 0x1B80, 0x54F10F85,
+ 0x1B80, 0x54F10F87,
+ 0x1B80, 0x0BA90F95,
+ 0x1B80, 0x0BA90F97,
+ 0x1B80, 0x67FC0FA5,
+ 0x1B80, 0x67FC0FA7,
+ 0x1B80, 0xE1950FB5,
+ 0x1B80, 0xE1950FB7,
+ 0x1B80, 0xE1CE0FC5,
+ 0x1B80, 0xE1CE0FC7,
+ 0x1B80, 0x67FF0FD5,
+ 0x1B80, 0x67FF0FD7,
+ 0x1B80, 0xE1950FE5,
+ 0x1B80, 0xE1950FE7,
+ 0x1B80, 0xE1CE0FF5,
+ 0x1B80, 0xE1CE0FF7,
+ 0x1B80, 0x5C321005,
+ 0x1B80, 0x5C321007,
+ 0x1B80, 0x54F21015,
+ 0x1B80, 0x54F21017,
+ 0x1B80, 0x67001025,
+ 0x1B80, 0x67001027,
+ 0x1B80, 0xE1951035,
+ 0x1B80, 0xE1951037,
+ 0x1B80, 0xE1CE1045,
+ 0x1B80, 0xE1CE1047,
+ 0x1B80, 0x67031055,
+ 0x1B80, 0x67031057,
+ 0x1B80, 0xE1951065,
+ 0x1B80, 0xE1951067,
+ 0x1B80, 0xE1CE1075,
+ 0x1B80, 0xE1CE1077,
+ 0x1B80, 0xF9CC1085,
+ 0x1B80, 0xF9CC1087,
+ 0x1B80, 0x67071095,
+ 0x1B80, 0x67071097,
+ 0x1B80, 0xE19510A5,
+ 0x1B80, 0xE19510A7,
+ 0x1B80, 0xE1CE10B5,
+ 0x1B80, 0xE1CE10B7,
+ 0x1B80, 0xFAD310C5,
+ 0x1B80, 0xFAD310C7,
+ 0x1B80, 0x5C3210D5,
+ 0x1B80, 0x5C3210D7,
+ 0x1B80, 0x54F310E5,
+ 0x1B80, 0x54F310E7,
+ 0x1B80, 0x670B10F5,
+ 0x1B80, 0x670B10F7,
+ 0x1B80, 0xE1951105,
+ 0x1B80, 0xE1951107,
+ 0x1B80, 0xE1CE1115,
+ 0x1B80, 0xE1CE1117,
+ 0x1B80, 0x670E1125,
+ 0x1B80, 0x670E1127,
+ 0x1B80, 0xE1951135,
+ 0x1B80, 0xE1951137,
+ 0x1B80, 0xE1CE1145,
+ 0x1B80, 0xE1CE1147,
+ 0x1B80, 0x4D101155,
+ 0x1B80, 0x4D101157,
+ 0x1B80, 0x30A81165,
+ 0x1B80, 0x30A81167,
+ 0x1B80, 0x00011175,
+ 0x1B80, 0x00011177,
+ 0x1B80, 0x6C001185,
+ 0x1B80, 0x6C001187,
+ 0x1B80, 0x00061195,
+ 0x1B80, 0x00061197,
+ 0x1B80, 0x530011A5,
+ 0x1B80, 0x530011A7,
+ 0x1B80, 0x57F711B5,
+ 0x1B80, 0x57F711B7,
+ 0x1B80, 0x582111C5,
+ 0x1B80, 0x582111C7,
+ 0x1B80, 0x592E11D5,
+ 0x1B80, 0x592E11D7,
+ 0x1B80, 0x5A3811E5,
+ 0x1B80, 0x5A3811E7,
+ 0x1B80, 0x5B4111F5,
+ 0x1B80, 0x5B4111F7,
+ 0x1B80, 0x00071205,
+ 0x1B80, 0x00071207,
+ 0x1B80, 0x5C001215,
+ 0x1B80, 0x5C001217,
+ 0x1B80, 0x4B001225,
+ 0x1B80, 0x4B001227,
+ 0x1B80, 0x4E8F1235,
+ 0x1B80, 0x4E8F1237,
+ 0x1B80, 0x4F151245,
+ 0x1B80, 0x4F151247,
+ 0x1B80, 0x00041255,
+ 0x1B80, 0x00041257,
+ 0x1B80, 0xE1B31265,
+ 0x1B80, 0xE1B31267,
+ 0x1B80, 0xAB001275,
+ 0x1B80, 0xAB001277,
+ 0x1B80, 0x00011285,
+ 0x1B80, 0x00011287,
+ 0x1B80, 0x6C001295,
+ 0x1B80, 0x6C001297,
+ 0x1B80, 0x000612A5,
+ 0x1B80, 0x000612A7,
+ 0x1B80, 0x530012B5,
+ 0x1B80, 0x530012B7,
+ 0x1B80, 0x57F712C5,
+ 0x1B80, 0x57F712C7,
+ 0x1B80, 0x582112D5,
+ 0x1B80, 0x582112D7,
+ 0x1B80, 0x592E12E5,
+ 0x1B80, 0x592E12E7,
+ 0x1B80, 0x5A3812F5,
+ 0x1B80, 0x5A3812F7,
+ 0x1B80, 0x5B411305,
+ 0x1B80, 0x5B411307,
+ 0x1B80, 0x00071315,
+ 0x1B80, 0x00071317,
+ 0x1B80, 0x5C001325,
+ 0x1B80, 0x5C001327,
+ 0x1B80, 0x4B401335,
+ 0x1B80, 0x4B401337,
+ 0x1B80, 0x4E971345,
+ 0x1B80, 0x4E971347,
+ 0x1B80, 0x4F111355,
+ 0x1B80, 0x4F111357,
+ 0x1B80, 0x00041365,
+ 0x1B80, 0x00041367,
+ 0x1B80, 0xE1B31375,
+ 0x1B80, 0xE1B31377,
+ 0x1B80, 0xAB001385,
+ 0x1B80, 0xAB001387,
+ 0x1B80, 0x8B001395,
+ 0x1B80, 0x8B001397,
+ 0x1B80, 0xAB0013A5,
+ 0x1B80, 0xAB0013A7,
+ 0x1B80, 0x8A1913B5,
+ 0x1B80, 0x8A1913B7,
+ 0x1B80, 0x301D13C5,
+ 0x1B80, 0x301D13C7,
+ 0x1B80, 0x000113D5,
+ 0x1B80, 0x000113D7,
+ 0x1B80, 0x6C0113E5,
+ 0x1B80, 0x6C0113E7,
+ 0x1B80, 0x000613F5,
+ 0x1B80, 0x000613F7,
+ 0x1B80, 0x53011405,
+ 0x1B80, 0x53011407,
+ 0x1B80, 0x57F71415,
+ 0x1B80, 0x57F71417,
+ 0x1B80, 0x58211425,
+ 0x1B80, 0x58211427,
+ 0x1B80, 0x592E1435,
+ 0x1B80, 0x592E1437,
+ 0x1B80, 0x5A381445,
+ 0x1B80, 0x5A381447,
+ 0x1B80, 0x5B411455,
+ 0x1B80, 0x5B411457,
+ 0x1B80, 0x00071465,
+ 0x1B80, 0x00071467,
+ 0x1B80, 0x5C001475,
+ 0x1B80, 0x5C001477,
+ 0x1B80, 0x4B001485,
+ 0x1B80, 0x4B001487,
+ 0x1B80, 0x4E871495,
+ 0x1B80, 0x4E871497,
+ 0x1B80, 0x4F1114A5,
+ 0x1B80, 0x4F1114A7,
+ 0x1B80, 0x000414B5,
+ 0x1B80, 0x000414B7,
+ 0x1B80, 0xE1B314C5,
+ 0x1B80, 0xE1B314C7,
+ 0x1B80, 0xAB0014D5,
+ 0x1B80, 0xAB0014D7,
+ 0x1B80, 0x000614E5,
+ 0x1B80, 0x000614E7,
+ 0x1B80, 0x577714F5,
+ 0x1B80, 0x577714F7,
+ 0x1B80, 0x00071505,
+ 0x1B80, 0x00071507,
+ 0x1B80, 0x4E861515,
+ 0x1B80, 0x4E861517,
+ 0x1B80, 0x00041525,
+ 0x1B80, 0x00041527,
+ 0x1B80, 0x00011535,
+ 0x1B80, 0x00011537,
+ 0x1B80, 0x00011545,
+ 0x1B80, 0x00011547,
+ 0x1B80, 0x7B241555,
+ 0x1B80, 0x7B241557,
+ 0x1B80, 0x7A401565,
+ 0x1B80, 0x7A401567,
+ 0x1B80, 0x79001575,
+ 0x1B80, 0x79001577,
+ 0x1B80, 0x55031585,
+ 0x1B80, 0x55031587,
+ 0x1B80, 0x31611595,
+ 0x1B80, 0x31611597,
+ 0x1B80, 0x7B1C15A5,
+ 0x1B80, 0x7B1C15A7,
+ 0x1B80, 0x7A4015B5,
+ 0x1B80, 0x7A4015B7,
+ 0x1B80, 0x550B15C5,
+ 0x1B80, 0x550B15C7,
+ 0x1B80, 0x316115D5,
+ 0x1B80, 0x316115D7,
+ 0x1B80, 0x7B2015E5,
+ 0x1B80, 0x7B2015E7,
+ 0x1B80, 0x7A0015F5,
+ 0x1B80, 0x7A0015F7,
+ 0x1B80, 0x55131605,
+ 0x1B80, 0x55131607,
+ 0x1B80, 0x74011615,
+ 0x1B80, 0x74011617,
+ 0x1B80, 0x74001625,
+ 0x1B80, 0x74001627,
+ 0x1B80, 0x8E001635,
+ 0x1B80, 0x8E001637,
+ 0x1B80, 0x00011645,
+ 0x1B80, 0x00011647,
+ 0x1B80, 0x57021655,
+ 0x1B80, 0x57021657,
+ 0x1B80, 0x57001665,
+ 0x1B80, 0x57001667,
+ 0x1B80, 0x97001675,
+ 0x1B80, 0x97001677,
+ 0x1B80, 0x00011685,
+ 0x1B80, 0x00011687,
+ 0x1B80, 0x4F781695,
+ 0x1B80, 0x4F781697,
+ 0x1B80, 0x538816A5,
+ 0x1B80, 0x538816A7,
+ 0x1B80, 0xE17516B5,
+ 0x1B80, 0xE17516B7,
+ 0x1B80, 0x548016C5,
+ 0x1B80, 0x548016C7,
+ 0x1B80, 0x540016D5,
+ 0x1B80, 0x540016D7,
+ 0x1B80, 0x548116E5,
+ 0x1B80, 0x548116E7,
+ 0x1B80, 0x540016F5,
+ 0x1B80, 0x540016F7,
+ 0x1B80, 0x54821705,
+ 0x1B80, 0x54821707,
+ 0x1B80, 0x54001715,
+ 0x1B80, 0x54001717,
+ 0x1B80, 0xE1801725,
+ 0x1B80, 0xE1801727,
+ 0x1B80, 0xBF1D1735,
+ 0x1B80, 0xBF1D1737,
+ 0x1B80, 0x301D1745,
+ 0x1B80, 0x301D1747,
+ 0x1B80, 0xE1551755,
+ 0x1B80, 0xE1551757,
+ 0x1B80, 0xE15A1765,
+ 0x1B80, 0xE15A1767,
+ 0x1B80, 0xE15E1775,
+ 0x1B80, 0xE15E1777,
+ 0x1B80, 0xE1651785,
+ 0x1B80, 0xE1651787,
+ 0x1B80, 0xE1C51795,
+ 0x1B80, 0xE1C51797,
+ 0x1B80, 0x551317A5,
+ 0x1B80, 0x551317A7,
+ 0x1B80, 0xE16117B5,
+ 0x1B80, 0xE16117B7,
+ 0x1B80, 0x551517C5,
+ 0x1B80, 0x551517C7,
+ 0x1B80, 0xE16517D5,
+ 0x1B80, 0xE16517D7,
+ 0x1B80, 0xE1C517E5,
+ 0x1B80, 0xE1C517E7,
+ 0x1B80, 0x000117F5,
+ 0x1B80, 0x000117F7,
+ 0x1B80, 0x54BF1805,
+ 0x1B80, 0x54BF1807,
+ 0x1B80, 0x54C01815,
+ 0x1B80, 0x54C01817,
+ 0x1B80, 0x54A31825,
+ 0x1B80, 0x54A31827,
+ 0x1B80, 0x54C11835,
+ 0x1B80, 0x54C11837,
+ 0x1B80, 0x54A41845,
+ 0x1B80, 0x54A41847,
+ 0x1B80, 0x4C181855,
+ 0x1B80, 0x4C181857,
+ 0x1B80, 0xBF071865,
+ 0x1B80, 0xBF071867,
+ 0x1B80, 0x54C21875,
+ 0x1B80, 0x54C21877,
+ 0x1B80, 0x54A41885,
+ 0x1B80, 0x54A41887,
+ 0x1B80, 0xBF041895,
+ 0x1B80, 0xBF041897,
+ 0x1B80, 0x54C118A5,
+ 0x1B80, 0x54C118A7,
+ 0x1B80, 0x54A318B5,
+ 0x1B80, 0x54A318B7,
+ 0x1B80, 0xBF0118C5,
+ 0x1B80, 0xBF0118C7,
+ 0x1B80, 0xE1D318D5,
+ 0x1B80, 0xE1D318D7,
+ 0x1B80, 0x54DF18E5,
+ 0x1B80, 0x54DF18E7,
+ 0x1B80, 0x000118F5,
+ 0x1B80, 0x000118F7,
+ 0x1B80, 0x54BF1905,
+ 0x1B80, 0x54BF1907,
+ 0x1B80, 0x54E51915,
+ 0x1B80, 0x54E51917,
+ 0x1B80, 0x050A1925,
+ 0x1B80, 0x050A1927,
+ 0x1B80, 0x54DF1935,
+ 0x1B80, 0x54DF1937,
+ 0x1B80, 0x00011945,
+ 0x1B80, 0x00011947,
+ 0x1B80, 0x7F201955,
+ 0x1B80, 0x7F201957,
+ 0x1B80, 0x7E001965,
+ 0x1B80, 0x7E001967,
+ 0x1B80, 0x7D001975,
+ 0x1B80, 0x7D001977,
+ 0x1B80, 0x55011985,
+ 0x1B80, 0x55011987,
+ 0x1B80, 0x5C311995,
+ 0x1B80, 0x5C311997,
+ 0x1B80, 0xE16119A5,
+ 0x1B80, 0xE16119A7,
+ 0x1B80, 0xE16519B5,
+ 0x1B80, 0xE16519B7,
+ 0x1B80, 0x548019C5,
+ 0x1B80, 0x548019C7,
+ 0x1B80, 0x540019D5,
+ 0x1B80, 0x540019D7,
+ 0x1B80, 0x548119E5,
+ 0x1B80, 0x548119E7,
+ 0x1B80, 0x540019F5,
+ 0x1B80, 0x540019F7,
+ 0x1B80, 0x54821A05,
+ 0x1B80, 0x54821A07,
+ 0x1B80, 0x54001A15,
+ 0x1B80, 0x54001A17,
+ 0x1B80, 0xE1801A25,
+ 0x1B80, 0xE1801A27,
+ 0x1B80, 0xBFED1A35,
+ 0x1B80, 0xBFED1A37,
+ 0x1B80, 0x301D1A45,
+ 0x1B80, 0x301D1A47,
+ 0x1B80, 0x00231A55,
+ 0x1B80, 0x00231A57,
+ 0x1B80, 0x7B201A65,
+ 0x1B80, 0x7B201A67,
+ 0x1B80, 0x7A001A75,
+ 0x1B80, 0x7A001A77,
+ 0x1B80, 0x79001A85,
+ 0x1B80, 0x79001A87,
+ 0x1B80, 0xE1C91A95,
+ 0x1B80, 0xE1C91A97,
+ 0x1B80, 0x00021AA5,
+ 0x1B80, 0x00021AA7,
+ 0x1B80, 0x00011AB5,
+ 0x1B80, 0x00011AB7,
+ 0x1B80, 0x00221AC5,
+ 0x1B80, 0x00221AC7,
+ 0x1B80, 0x7B201AD5,
+ 0x1B80, 0x7B201AD7,
+ 0x1B80, 0x7A001AE5,
+ 0x1B80, 0x7A001AE7,
+ 0x1B80, 0x79001AF5,
+ 0x1B80, 0x79001AF7,
+ 0x1B80, 0xE1C91B05,
+ 0x1B80, 0xE1C91B07,
+ 0x1B80, 0x00021B15,
+ 0x1B80, 0x00021B17,
+ 0x1B80, 0x00011B25,
+ 0x1B80, 0x00011B27,
+ 0x1B80, 0x74021B35,
+ 0x1B80, 0x74021B37,
+ 0x1B80, 0x003F1B45,
+ 0x1B80, 0x003F1B47,
+ 0x1B80, 0x74001B55,
+ 0x1B80, 0x74001B57,
+ 0x1B80, 0x00021B65,
+ 0x1B80, 0x00021B67,
+ 0x1B80, 0x00011B75,
+ 0x1B80, 0x00011B77,
+ 0x1B80, 0x4D041B85,
+ 0x1B80, 0x4D041B87,
+ 0x1B80, 0x2EF81B95,
+ 0x1B80, 0x2EF81B97,
+ 0x1B80, 0x00001BA5,
+ 0x1B80, 0x00001BA7,
+ 0x1B80, 0x23301BB5,
+ 0x1B80, 0x23301BB7,
+ 0x1B80, 0x00241BC5,
+ 0x1B80, 0x00241BC7,
+ 0x1B80, 0x23E01BD5,
+ 0x1B80, 0x23E01BD7,
+ 0x1B80, 0x003F1BE5,
+ 0x1B80, 0x003F1BE7,
+ 0x1B80, 0x23FC1BF5,
+ 0x1B80, 0x23FC1BF7,
+ 0x1B80, 0xBFCE1C05,
+ 0x1B80, 0xBFCE1C07,
+ 0x1B80, 0x2EF01C15,
+ 0x1B80, 0x2EF01C17,
+ 0x1B80, 0x00001C25,
+ 0x1B80, 0x00001C27,
+ 0x1B80, 0x4D001C35,
+ 0x1B80, 0x4D001C37,
+ 0x1B80, 0x00011C45,
+ 0x1B80, 0x00011C47,
+ 0x1B80, 0x549F1C55,
+ 0x1B80, 0x549F1C57,
+ 0x1B80, 0x54FF1C65,
+ 0x1B80, 0x54FF1C67,
+ 0x1B80, 0x54001C75,
+ 0x1B80, 0x54001C77,
+ 0x1B80, 0x00011C85,
+ 0x1B80, 0x00011C87,
+ 0x1B80, 0x5C311C95,
+ 0x1B80, 0x5C311C97,
+ 0x1B80, 0x07141CA5,
+ 0x1B80, 0x07141CA7,
+ 0x1B80, 0x54001CB5,
+ 0x1B80, 0x54001CB7,
+ 0x1B80, 0x5C321CC5,
+ 0x1B80, 0x5C321CC7,
+ 0x1B80, 0x00011CD5,
+ 0x1B80, 0x00011CD7,
+ 0x1B80, 0x5C321CE5,
+ 0x1B80, 0x5C321CE7,
+ 0x1B80, 0x07141CF5,
+ 0x1B80, 0x07141CF7,
+ 0x1B80, 0x54001D05,
+ 0x1B80, 0x54001D07,
+ 0x1B80, 0x5C311D15,
+ 0x1B80, 0x5C311D17,
+ 0x1B80, 0x00011D25,
+ 0x1B80, 0x00011D27,
+ 0x1B80, 0x4C981D35,
+ 0x1B80, 0x4C981D37,
+ 0x1B80, 0x4C181D45,
+ 0x1B80, 0x4C181D47,
+ 0x1B80, 0x00011D55,
+ 0x1B80, 0x00011D57,
+ 0x1B80, 0x5C321D65,
+ 0x1B80, 0x5C321D67,
+ 0x1B80, 0x62841D75,
+ 0x1B80, 0x62841D77,
+ 0x1B80, 0x66861D85,
+ 0x1B80, 0x66861D87,
+ 0x1B80, 0x6C031D95,
+ 0x1B80, 0x6C031D97,
+ 0x1B80, 0x7B201DA5,
+ 0x1B80, 0x7B201DA7,
+ 0x1B80, 0x7A001DB5,
+ 0x1B80, 0x7A001DB7,
+ 0x1B80, 0x79001DC5,
+ 0x1B80, 0x79001DC7,
+ 0x1B80, 0x7F201DD5,
+ 0x1B80, 0x7F201DD7,
+ 0x1B80, 0x7E001DE5,
+ 0x1B80, 0x7E001DE7,
+ 0x1B80, 0x7D001DF5,
+ 0x1B80, 0x7D001DF7,
+ 0x1B80, 0x09011E05,
+ 0x1B80, 0x09011E07,
+ 0x1B80, 0x0C011E15,
+ 0x1B80, 0x0C011E17,
+ 0x1B80, 0x0BA61E25,
+ 0x1B80, 0x0BA61E27,
+ 0x1B80, 0x00011E35,
+ 0x1B80, 0x00011E37,
+ 0x1B80, 0x00000006,
+ 0x1B80, 0x00000002,
+
+};
+
+RTW_DECL_TABLE_PHY_COND(rtw8821c_bb, rtw_phy_cfg_bb);
+
+static const struct rtw_phy_pg_cfg_pair rtw8821c_bb_pg_type0[] = {
+ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, },
+ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36363636, },
+ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, },
+ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363636, },
+ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, },
+ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363636, },
+ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, },
+ { 0, 0, 0, 0x00000c44, 0xffffffff, 0x22222224, },
+ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, },
+ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, },
+ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343434, },
+ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, },
+ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343434, },
+ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, },
+ { 1, 0, 0, 0x00000c44, 0xffffffff, 0x20202022, },
+};
+
+RTW_DECL_TABLE_BB_PG(rtw8821c_bb_pg_type0);
+
+static const u32 rtw8821c_rf_a[] = {
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x000, 0x00010000,
+ 0x018, 0x00010D24,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x000, 0x00010000,
+ 0x018, 0x00010D24,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x000, 0x00010000,
+ 0x018, 0x00010D24,
+ 0xA0000000, 0x00000000,
+ 0x000, 0x00010000,
+ 0x018, 0x00010D24,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000002,
+ 0x03E, 0x0000003F,
+ 0x03F, 0x000C0F4E,
+ 0x033, 0x00000001,
+ 0x03E, 0x00000034,
+ 0x03F, 0x0004080E,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000002,
+ 0x03E, 0x0000003F,
+ 0x03F, 0x000C0F4E,
+ 0x033, 0x00000001,
+ 0x03E, 0x00000034,
+ 0x03F, 0x0004080E,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000002,
+ 0x03E, 0x0000003F,
+ 0x03F, 0x000C0F4E,
+ 0x033, 0x00000001,
+ 0x03E, 0x00000034,
+ 0x03F, 0x0004080E,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000002,
+ 0x03E, 0x0000003F,
+ 0x03F, 0x000C0F4E,
+ 0x033, 0x00000001,
+ 0x03E, 0x00000034,
+ 0x03F, 0x0004080E,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00002000,
+ 0x033, 0x00000000,
+ 0x03F, 0x000005DF,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00002000,
+ 0x033, 0x00000000,
+ 0x03F, 0x000005DF,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00002000,
+ 0x033, 0x00000000,
+ 0x03F, 0x000005DF,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00002000,
+ 0x033, 0x00000000,
+ 0x03F, 0x000005DF,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00000400,
+ 0x033, 0x00000000,
+ 0x03F, 0x000005DF,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00000400,
+ 0x033, 0x00000000,
+ 0x03F, 0x000005DF,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00000400,
+ 0x033, 0x00000000,
+ 0x03F, 0x000005DF,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00000400,
+ 0x033, 0x00000000,
+ 0x03F, 0x000005DF,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B0, 0x000FF0F8,
+ 0x0B1, 0x0007DBE4,
+ 0x0B2, 0x000225D1,
+ 0x0B3, 0x000FC760,
+ 0x0B4, 0x00099DD0,
+ 0x0B5, 0x000400FC,
+ 0x0B6, 0x000187F0,
+ 0x0B7, 0x00030018,
+ 0x0B8, 0x00080800,
+ 0x0B9, 0x00000000,
+ 0x0BA, 0x00008000,
+ 0x0BB, 0x00000004,
+ 0x0BC, 0x00040000,
+ 0x0BD, 0x00000000,
+ 0x0BE, 0x00000000,
+ 0x0BF, 0x00000000,
+ 0x0C0, 0x00000000,
+ 0x0C1, 0x00000000,
+ 0x0C2, 0x00000000,
+ 0x0C3, 0x00000000,
+ 0x0C4, 0x00002402,
+ 0x0C5, 0x00000009,
+ 0x0C6, 0x00040299,
+ 0x0C7, 0x00055555,
+ 0x0C8, 0x0000C16C,
+ 0x0C9, 0x0001C140,
+ 0x0CA, 0x00000000,
+ 0x0CB, 0x00000000,
+ 0x0CC, 0x00000000,
+ 0x0CD, 0x00000000,
+ 0x0CE, 0x00090C00,
+ 0x0CF, 0x0006D200,
+ 0x0DF, 0x00000009,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B0, 0x000FF0F8,
+ 0x0B1, 0x0007DBE4,
+ 0x0B2, 0x000225D1,
+ 0x0B3, 0x000FC760,
+ 0x0B4, 0x00099DD0,
+ 0x0B5, 0x000400FC,
+ 0x0B6, 0x000187F0,
+ 0x0B7, 0x00030018,
+ 0x0B8, 0x00080800,
+ 0x0B9, 0x00000000,
+ 0x0BA, 0x00008000,
+ 0x0BB, 0x00000004,
+ 0x0BC, 0x00040000,
+ 0x0BD, 0x00000000,
+ 0x0BE, 0x00000000,
+ 0x0BF, 0x00000000,
+ 0x0C0, 0x00000000,
+ 0x0C1, 0x00000000,
+ 0x0C2, 0x00000000,
+ 0x0C3, 0x00000000,
+ 0x0C4, 0x00002402,
+ 0x0C5, 0x00000009,
+ 0x0C6, 0x00040299,
+ 0x0C7, 0x00055555,
+ 0x0C8, 0x0000C16C,
+ 0x0C9, 0x0001C140,
+ 0x0CA, 0x00000000,
+ 0x0CB, 0x00000000,
+ 0x0CC, 0x00000000,
+ 0x0CD, 0x00000000,
+ 0x0CE, 0x00090C00,
+ 0x0CF, 0x0006D200,
+ 0x0DF, 0x00000009,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B0, 0x000FF0F8,
+ 0x0B1, 0x0007DBE4,
+ 0x0B2, 0x000225D1,
+ 0x0B3, 0x000FC760,
+ 0x0B4, 0x00099DD0,
+ 0x0B5, 0x000400FC,
+ 0x0B6, 0x000187F0,
+ 0x0B7, 0x00030018,
+ 0x0B8, 0x00080800,
+ 0x0B9, 0x00000000,
+ 0x0BA, 0x00008000,
+ 0x0BB, 0x00000004,
+ 0x0BC, 0x00040000,
+ 0x0BD, 0x00000000,
+ 0x0BE, 0x00000000,
+ 0x0BF, 0x00000000,
+ 0x0C0, 0x00000000,
+ 0x0C1, 0x00000000,
+ 0x0C2, 0x00000000,
+ 0x0C3, 0x00000000,
+ 0x0C4, 0x00002402,
+ 0x0C5, 0x00000009,
+ 0x0C6, 0x00040299,
+ 0x0C7, 0x00055555,
+ 0x0C8, 0x0000C16C,
+ 0x0C9, 0x0001C140,
+ 0x0CA, 0x00000000,
+ 0x0CB, 0x00000000,
+ 0x0CC, 0x00000000,
+ 0x0CD, 0x00000000,
+ 0x0CE, 0x00090C00,
+ 0x0CF, 0x0006D200,
+ 0x0DF, 0x00000009,
+ 0xA0000000, 0x00000000,
+ 0x0B0, 0x000FF0F8,
+ 0x0B1, 0x0007DBE4,
+ 0x0B2, 0x000225D1,
+ 0x0B3, 0x000FC760,
+ 0x0B4, 0x00099DD0,
+ 0x0B5, 0x000400FC,
+ 0x0B6, 0x000187F0,
+ 0x0B7, 0x00030018,
+ 0x0B8, 0x00080800,
+ 0x0B9, 0x00000000,
+ 0x0BA, 0x00008000,
+ 0x0BB, 0x00000004,
+ 0x0BC, 0x00040000,
+ 0x0BD, 0x00000000,
+ 0x0BE, 0x00000000,
+ 0x0BF, 0x00000000,
+ 0x0C0, 0x00000000,
+ 0x0C1, 0x00000000,
+ 0x0C2, 0x00000000,
+ 0x0C3, 0x00000000,
+ 0x0C4, 0x00002402,
+ 0x0C5, 0x00000009,
+ 0x0C6, 0x00040299,
+ 0x0C7, 0x00055555,
+ 0x0C8, 0x0000C16C,
+ 0x0C9, 0x0001C140,
+ 0x0CA, 0x00000000,
+ 0x0CB, 0x00000000,
+ 0x0CC, 0x00000000,
+ 0x0CD, 0x00000000,
+ 0x0CE, 0x00090C00,
+ 0x0CF, 0x0006D200,
+ 0x0DF, 0x00000009,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00010000,
+ 0x033, 0x00000058,
+ 0x03F, 0x0000001C,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00010000,
+ 0x033, 0x00000058,
+ 0x03F, 0x0000001C,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00010000,
+ 0x033, 0x00000058,
+ 0x03F, 0x0000001C,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00010000,
+ 0x033, 0x00000058,
+ 0x03F, 0x0000001C,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00010524,
+ 0x081, 0x0000FCC1,
+ 0x089, 0x00000004,
+ 0x08A, 0x0008A186,
+ 0x08B, 0x0006FFFC,
+ 0x08C, 0x000312C7,
+ 0x08D, 0x00020888,
+ 0x08E, 0x00064140,
+ 0x08F, 0x000A8010,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00010524,
+ 0x081, 0x0000FCC1,
+ 0x089, 0x00000004,
+ 0x08A, 0x0008A186,
+ 0x08B, 0x0006FFFC,
+ 0x08C, 0x000312C7,
+ 0x08D, 0x00020888,
+ 0x08E, 0x00064140,
+ 0x08F, 0x000A8010,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00010524,
+ 0x081, 0x0000FCC1,
+ 0x089, 0x00000004,
+ 0x08A, 0x0008A186,
+ 0x08B, 0x0007060C,
+ 0x08C, 0x000312C7,
+ 0x08D, 0x00020888,
+ 0x08E, 0x00064140,
+ 0x08F, 0x000A8010,
+ 0xA0000000, 0x00000000,
+ 0x018, 0x00010524,
+ 0x081, 0x0000FCC1,
+ 0x089, 0x00000004,
+ 0x08A, 0x0008A186,
+ 0x08B, 0x0007060C,
+ 0x08C, 0x000312C7,
+ 0x08D, 0x00020888,
+ 0x08E, 0x00064140,
+ 0x08F, 0x000A8010,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0DD, 0x00000020,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0DD, 0x00000020,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0DD, 0x00000020,
+ 0xA0000000, 0x00000000,
+ 0x0DD, 0x00000020,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00020000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00020000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00020000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00020000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000007,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000006,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000005,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000004,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000003,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000002,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000001,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000000,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000007,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000006,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000005,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000004,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000003,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000002,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000001,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000000,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000007,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000006,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000005,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000004,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000003,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000002,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000001,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000000,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0xA0000000, 0x00000000,
+ 0x033, 0x00000007,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000006,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000005,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000004,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000003,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000002,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000001,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000000,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x0000000F,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000E,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000D,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000C,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000B,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000A,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000009,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000008,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x0000000F,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000E,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000D,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000C,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000B,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000A,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000009,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000008,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x0000000F,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000E,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000D,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000C,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000B,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000A,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000009,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000008,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0xA0000000, 0x00000000,
+ 0x033, 0x0000000F,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000E,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000D,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000C,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000B,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x0000000A,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000009,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000008,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000017,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000016,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000015,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000014,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000013,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000012,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000011,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000010,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000017,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000016,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000015,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000014,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000013,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000012,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000011,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000010,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000017,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000016,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000015,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000014,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000013,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000012,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000011,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000010,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x033, 0x00000017,
+ 0x03E, 0x00038000,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000016,
+ 0x03E, 0x00038080,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000015,
+ 0x03E, 0x000380C8,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000014,
+ 0x03E, 0x00038190,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000013,
+ 0x03E, 0x00038998,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000012,
+ 0x03E, 0x00039840,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000011,
+ 0x03E, 0x000398C4,
+ 0x03F, 0x000C3186,
+ 0x033, 0x00000010,
+ 0x03E, 0x00039930,
+ 0x03F, 0x000C3186,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00004000,
+ 0x033, 0x00000000,
+ 0x03F, 0x0000000F,
+ 0x033, 0x00000001,
+ 0x03F, 0x0000000A,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000005,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00004000,
+ 0x033, 0x00000000,
+ 0x03F, 0x0000000F,
+ 0x033, 0x00000001,
+ 0x03F, 0x0000000A,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000005,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00004000,
+ 0x033, 0x00000000,
+ 0x03F, 0x0000000F,
+ 0x033, 0x00000001,
+ 0x03F, 0x0000000A,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000005,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00004000,
+ 0x033, 0x00000000,
+ 0x03F, 0x0000000F,
+ 0x033, 0x00000001,
+ 0x03F, 0x0000000A,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000005,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00000401,
+ 0x084, 0x00001209,
+ 0x086, 0x000001A0,
+ 0x087, 0x000E8180,
+ 0x088, 0x00006020,
+ 0x0DF, 0x00008009,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00000401,
+ 0x084, 0x00001209,
+ 0x086, 0x000001A0,
+ 0x087, 0x000E8180,
+ 0x088, 0x00006020,
+ 0x0DF, 0x00008009,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00000401,
+ 0x084, 0x00001209,
+ 0x086, 0x000001A0,
+ 0x087, 0x000E8180,
+ 0x088, 0x00006020,
+ 0x0DF, 0x00008009,
+ 0xA0000000, 0x00000000,
+ 0x018, 0x00000401,
+ 0x084, 0x00001209,
+ 0x086, 0x000001A0,
+ 0x087, 0x000E8180,
+ 0x088, 0x00006020,
+ 0x0DF, 0x00008009,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00008000,
+ 0x033, 0x0000000F,
+ 0x03F, 0x0000003C,
+ 0x033, 0x0000000E,
+ 0x03F, 0x00000038,
+ 0x033, 0x0000000D,
+ 0x03F, 0x00000030,
+ 0x033, 0x0000000C,
+ 0x03F, 0x00000028,
+ 0x033, 0x0000000B,
+ 0x03F, 0x00000020,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00000018,
+ 0x033, 0x00000009,
+ 0x03F, 0x00000010,
+ 0x033, 0x00000008,
+ 0x03F, 0x00000008,
+ 0x033, 0x00000007,
+ 0x03F, 0x0000003C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00000038,
+ 0x033, 0x00000005,
+ 0x03F, 0x00000030,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000028,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000020,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000018,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000010,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000008,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00008000,
+ 0x033, 0x0000000F,
+ 0x03F, 0x0000003C,
+ 0x033, 0x0000000E,
+ 0x03F, 0x00000038,
+ 0x033, 0x0000000D,
+ 0x03F, 0x00000030,
+ 0x033, 0x0000000C,
+ 0x03F, 0x00000028,
+ 0x033, 0x0000000B,
+ 0x03F, 0x00000020,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00000018,
+ 0x033, 0x00000009,
+ 0x03F, 0x00000010,
+ 0x033, 0x00000008,
+ 0x03F, 0x00000008,
+ 0x033, 0x00000007,
+ 0x03F, 0x0000003C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00000038,
+ 0x033, 0x00000005,
+ 0x03F, 0x00000030,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000028,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000020,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000018,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000010,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000008,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00008000,
+ 0x033, 0x0000000F,
+ 0x03F, 0x0000003C,
+ 0x033, 0x0000000E,
+ 0x03F, 0x00000038,
+ 0x033, 0x0000000D,
+ 0x03F, 0x00000030,
+ 0x033, 0x0000000C,
+ 0x03F, 0x00000028,
+ 0x033, 0x0000000B,
+ 0x03F, 0x00000020,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00000018,
+ 0x033, 0x00000009,
+ 0x03F, 0x00000010,
+ 0x033, 0x00000008,
+ 0x03F, 0x00000008,
+ 0x033, 0x00000007,
+ 0x03F, 0x0000003C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00000038,
+ 0x033, 0x00000005,
+ 0x03F, 0x00000030,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000028,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000020,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000018,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000010,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000008,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00008000,
+ 0x033, 0x0000000F,
+ 0x03F, 0x0000003C,
+ 0x033, 0x0000000E,
+ 0x03F, 0x00000038,
+ 0x033, 0x0000000D,
+ 0x03F, 0x00000030,
+ 0x033, 0x0000000C,
+ 0x03F, 0x00000028,
+ 0x033, 0x0000000B,
+ 0x03F, 0x00000020,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00000018,
+ 0x033, 0x00000009,
+ 0x03F, 0x00000010,
+ 0x033, 0x00000008,
+ 0x03F, 0x00000008,
+ 0x033, 0x00000007,
+ 0x03F, 0x0000003C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00000038,
+ 0x033, 0x00000005,
+ 0x03F, 0x00000030,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000028,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000020,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000018,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000010,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000008,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00000002,
+ 0x033, 0x0000001E,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000001C,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000E,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000C,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00000002,
+ 0x033, 0x00000008,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000036,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000037,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000034,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000026,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000027,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000024,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000022,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000020,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000006,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000007,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000006,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00000002,
+ 0x033, 0x0000001E,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000001C,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000E,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000C,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00000002,
+ 0x033, 0x00000008,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000036,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000037,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000034,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000026,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000027,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000024,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000022,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000020,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000006,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000007,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000006,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00000002,
+ 0x033, 0x0000001E,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000001C,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000E,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000C,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00000002,
+ 0x033, 0x00000008,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000036,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000037,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000034,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000026,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000027,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000024,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000022,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000020,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000006,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000007,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000006,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00000002,
+ 0x033, 0x0000001E,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000001C,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000E,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000C,
+ 0x03F, 0x00000000,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00000002,
+ 0x033, 0x00000008,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000036,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000037,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000034,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000026,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000027,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000024,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000022,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000020,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000006,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000007,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000006,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000006,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0A0, 0x000F0005,
+ 0x0A1, 0x0006C000,
+ 0x0A2, 0x0000161B,
+ 0x0A3, 0x000B9CBD,
+ 0x0AF, 0x00070000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0A0, 0x000F0005,
+ 0x0A1, 0x0006C000,
+ 0x0A2, 0x0000161B,
+ 0x0A3, 0x000B9CBD,
+ 0x0AF, 0x00070000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0A0, 0x000F0005,
+ 0x0A1, 0x0006C000,
+ 0x0A2, 0x0000161B,
+ 0x0A3, 0x000B9CBD,
+ 0x0AF, 0x00070000,
+ 0xA0000000, 0x00000000,
+ 0x0A0, 0x000F0005,
+ 0x0A1, 0x0006C000,
+ 0x0A2, 0x0000161B,
+ 0x0A3, 0x000B9CBD,
+ 0x0AF, 0x00070000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0DE, 0x00000200,
+ 0x0EE, 0x00000100,
+ 0x033, 0x00000007,
+ 0x03F, 0x00000043,
+ 0x033, 0x00000006,
+ 0x03F, 0x0000007A,
+ 0x033, 0x00000005,
+ 0x03F, 0x00000041,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000079,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000043,
+ 0x033, 0x00000002,
+ 0x03F, 0x0000007A,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000041,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000079,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0DE, 0x00000200,
+ 0x0EE, 0x00000100,
+ 0x033, 0x00000007,
+ 0x03F, 0x00000043,
+ 0x033, 0x00000006,
+ 0x03F, 0x0000007A,
+ 0x033, 0x00000005,
+ 0x03F, 0x00000041,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000079,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000043,
+ 0x033, 0x00000002,
+ 0x03F, 0x0000007A,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000041,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000079,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0DE, 0x00000200,
+ 0x0EE, 0x00000100,
+ 0x033, 0x00000007,
+ 0x03F, 0x00000043,
+ 0x033, 0x00000006,
+ 0x03F, 0x0000007A,
+ 0x033, 0x00000005,
+ 0x03F, 0x00000041,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000079,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000043,
+ 0x033, 0x00000002,
+ 0x03F, 0x0000007A,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000041,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000079,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0DE, 0x00000200,
+ 0x0EE, 0x00000100,
+ 0x033, 0x00000007,
+ 0x03F, 0x00000043,
+ 0x033, 0x00000006,
+ 0x03F, 0x0000007A,
+ 0x033, 0x00000005,
+ 0x03F, 0x00000041,
+ 0x033, 0x00000004,
+ 0x03F, 0x00000079,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000043,
+ 0x033, 0x00000002,
+ 0x03F, 0x0000007A,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000041,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000079,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B8, 0x00080A00,
+ 0x0B0, 0x000FF0FA,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B8, 0x00080A00,
+ 0x0B0, 0x000FF0FA,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B8, 0x00080A00,
+ 0x0B0, 0x000FF0FA,
+ 0xA0000000, 0x00000000,
+ 0x0B8, 0x00080A00,
+ 0x0B0, 0x000FF0FA,
+ 0xB0000000, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0CA, 0x00080000,
+ 0x0C9, 0x0001C141,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0CA, 0x00080000,
+ 0x0C9, 0x0001C141,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0CA, 0x00080000,
+ 0x0C9, 0x0001C141,
+ 0xA0000000, 0x00000000,
+ 0x0CA, 0x00080000,
+ 0x0C9, 0x0001C141,
+ 0xB0000000, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B0, 0x000FF0F8,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B0, 0x000FF0F8,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0B0, 0x000FF0F8,
+ 0xA0000000, 0x00000000,
+ 0x0B0, 0x000FF0F8,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00018D24,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00018D24,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00018D24,
+ 0xA0000000, 0x00000000,
+ 0x018, 0x00018D24,
+ 0xB0000000, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00010D24,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00010D24,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x018, 0x00010D24,
+ 0xA0000000, 0x00000000,
+ 0x018, 0x00010D24,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x01B, 0x00003A40,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x01B, 0x00003A40,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x01B, 0x00003A40,
+ 0xA0000000, 0x00000000,
+ 0x01B, 0x00003A40,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0004D3A3,
+ 0x062, 0x0000D303,
+ 0x063, 0x00000002,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0004D3A3,
+ 0x062, 0x0000D303,
+ 0x063, 0x00000002,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x061, 0x0004D3A1,
+ 0x062, 0x0000D3A3,
+ 0x063, 0x00000002,
+ 0xA0000000, 0x00000000,
+ 0x061, 0x0004D3A1,
+ 0x062, 0x0000D3A3,
+ 0x063, 0x00000002,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000200,
+ 0x030, 0x00000000,
+ 0x03F, 0x00033303,
+ 0x030, 0x00001000,
+ 0x03F, 0x00033303,
+ 0x030, 0x00002000,
+ 0x03F, 0x00033303,
+ 0x030, 0x00003000,
+ 0x03F, 0x00033303,
+ 0x030, 0x00004000,
+ 0x03F, 0x00033303,
+ 0x030, 0x00005000,
+ 0x03F, 0x00033303,
+ 0x030, 0x00006000,
+ 0x03F, 0x00033303,
+ 0x030, 0x00007000,
+ 0x03F, 0x00033303,
+ 0x030, 0x00008000,
+ 0x03F, 0x00033303,
+ 0x030, 0x00009000,
+ 0x03F, 0x00033303,
+ 0x030, 0x0000A000,
+ 0x03F, 0x00033303,
+ 0x030, 0x0000B000,
+ 0x03F, 0x00033303,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000200,
+ 0x030, 0x00000000,
+ 0x03F, 0x000333A3,
+ 0x030, 0x00001000,
+ 0x03F, 0x000333A3,
+ 0x030, 0x00002000,
+ 0x03F, 0x000333A3,
+ 0x030, 0x00003000,
+ 0x03F, 0x000333A3,
+ 0x030, 0x00004000,
+ 0x03F, 0x000313A3,
+ 0x030, 0x00005000,
+ 0x03F, 0x000313A3,
+ 0x030, 0x00006000,
+ 0x03F, 0x000313A3,
+ 0x030, 0x00007000,
+ 0x03F, 0x000313A3,
+ 0x030, 0x00008000,
+ 0x03F, 0x000333A3,
+ 0x030, 0x00009000,
+ 0x03F, 0x000333A3,
+ 0x030, 0x0000A000,
+ 0x03F, 0x000333A3,
+ 0x030, 0x0000B000,
+ 0x03F, 0x000333A3,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000200,
+ 0x030, 0x00000000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00001000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00002000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00003000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00004000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00005000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00006000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00007000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00008000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00009000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x0000A000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x0000B000,
+ 0x03F, 0x000335A3,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00000200,
+ 0x030, 0x00000000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00001000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00002000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00003000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00004000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00005000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00006000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00007000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00008000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x00009000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x0000A000,
+ 0x03F, 0x000335A3,
+ 0x030, 0x0000B000,
+ 0x03F, 0x000335A3,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080,
+ 0x033, 0x00000000,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000001,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000002,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000003,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000004,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000005,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000006,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000007,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000008,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000009,
+ 0x03F, 0x00033303,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00033303,
+ 0x033, 0x0000000B,
+ 0x03F, 0x00033303,
+ 0x033, 0x0000000C,
+ 0x03F, 0x00033303,
+ 0x033, 0x0000000D,
+ 0x03F, 0x00033303,
+ 0x033, 0x0000000E,
+ 0x03F, 0x00033303,
+ 0x033, 0x0000000F,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000010,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000011,
+ 0x03F, 0x00033303,
+ 0x033, 0x00000012,
+ 0x03F, 0x00033303,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080,
+ 0x033, 0x00000000,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000001,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000002,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000003,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000004,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000005,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000006,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000007,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000008,
+ 0x03F, 0x000313A3,
+ 0x033, 0x00000009,
+ 0x03F, 0x000313A3,
+ 0x033, 0x0000000A,
+ 0x03F, 0x000313A3,
+ 0x033, 0x0000000B,
+ 0x03F, 0x000313A3,
+ 0x033, 0x0000000C,
+ 0x03F, 0x000313A3,
+ 0x033, 0x0000000D,
+ 0x03F, 0x000333A3,
+ 0x033, 0x0000000E,
+ 0x03F, 0x000333A3,
+ 0x033, 0x0000000F,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000010,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000011,
+ 0x03F, 0x000333A3,
+ 0x033, 0x00000012,
+ 0x03F, 0x000333A3,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000080,
+ 0x033, 0x00000000,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000001,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000002,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000003,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000004,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000005,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000006,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000007,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000008,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000009,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000A,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000B,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000C,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000D,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000E,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000F,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000010,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000011,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000012,
+ 0x03F, 0x000335A3,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00000080,
+ 0x033, 0x00000000,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000001,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000002,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000003,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000004,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000005,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000006,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000007,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000008,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000009,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000A,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000B,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000C,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000D,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000E,
+ 0x03F, 0x000335A3,
+ 0x033, 0x0000000F,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000010,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000011,
+ 0x03F, 0x000335A3,
+ 0x033, 0x00000012,
+ 0x03F, 0x000335A3,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000040,
+ 0x030, 0x00000644,
+ 0x030, 0x00001135,
+ 0x030, 0x00002133,
+ 0x030, 0x00004000,
+ 0x030, 0x00005000,
+ 0x030, 0x00006000,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000040,
+ 0x030, 0x00000644,
+ 0x030, 0x00001412,
+ 0x030, 0x00002202,
+ 0x030, 0x00004000,
+ 0x030, 0x00005000,
+ 0x030, 0x00006000,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000040,
+ 0x030, 0x00000640,
+ 0x030, 0x00001512,
+ 0x030, 0x00002202,
+ 0x030, 0x00004000,
+ 0x030, 0x00005000,
+ 0x030, 0x00006000,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00000040,
+ 0x030, 0x00000640,
+ 0x030, 0x00001512,
+ 0x030, 0x00002202,
+ 0x030, 0x00004000,
+ 0x030, 0x00005000,
+ 0x030, 0x00006000,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000800,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000800,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000800,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00000800,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020,
+ 0x03F, 0x00000001,
+ 0x033, 0x00000021,
+ 0x03F, 0x00000004,
+ 0x033, 0x00000022,
+ 0x03F, 0x00000007,
+ 0x033, 0x00000023,
+ 0x03F, 0x00000024,
+ 0x033, 0x00000024,
+ 0x03F, 0x00000027,
+ 0x033, 0x00000025,
+ 0x03F, 0x0000002A,
+ 0x033, 0x00000026,
+ 0x03F, 0x0000002D,
+ 0x033, 0x00000027,
+ 0x03F, 0x00000030,
+ 0x033, 0x00000028,
+ 0x03F, 0x00000033,
+ 0x033, 0x00000029,
+ 0x03F, 0x00000036,
+ 0x033, 0x0000002A,
+ 0x03F, 0x00000039,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020,
+ 0x03F, 0x00000E42,
+ 0x033, 0x00000021,
+ 0x03F, 0x00000E45,
+ 0x033, 0x00000022,
+ 0x03F, 0x00000E65,
+ 0x033, 0x00000023,
+ 0x03F, 0x00000E68,
+ 0x033, 0x00000024,
+ 0x03F, 0x00000EE4,
+ 0x033, 0x00000025,
+ 0x03F, 0x00000EE7,
+ 0x033, 0x00000026,
+ 0x03F, 0x00000EEA,
+ 0x033, 0x00000027,
+ 0x03F, 0x00000EED,
+ 0x033, 0x00000028,
+ 0x03F, 0x00000EF0,
+ 0x033, 0x00000029,
+ 0x03F, 0x00000EF3,
+ 0x033, 0x0000002A,
+ 0x03F, 0x00000EF6,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000020,
+ 0x03F, 0x00000E42,
+ 0x033, 0x00000021,
+ 0x03F, 0x00000E45,
+ 0x033, 0x00000022,
+ 0x03F, 0x00000E48,
+ 0x033, 0x00000023,
+ 0x03F, 0x00000E68,
+ 0x033, 0x00000024,
+ 0x03F, 0x00000E6B,
+ 0x033, 0x00000025,
+ 0x03F, 0x00000EAA,
+ 0x033, 0x00000026,
+ 0x03F, 0x00000EEA,
+ 0x033, 0x00000027,
+ 0x03F, 0x00000EED,
+ 0x033, 0x00000028,
+ 0x03F, 0x00000EF0,
+ 0x033, 0x00000029,
+ 0x03F, 0x00000EF3,
+ 0x033, 0x0000002A,
+ 0x03F, 0x00000EF6,
+ 0xA0000000, 0x00000000,
+ 0x033, 0x00000020,
+ 0x03F, 0x00000E42,
+ 0x033, 0x00000021,
+ 0x03F, 0x00000E45,
+ 0x033, 0x00000022,
+ 0x03F, 0x00000E65,
+ 0x033, 0x00000023,
+ 0x03F, 0x00000E68,
+ 0x033, 0x00000024,
+ 0x03F, 0x00000EE4,
+ 0x033, 0x00000025,
+ 0x03F, 0x00000EE7,
+ 0x033, 0x00000026,
+ 0x03F, 0x00000EEA,
+ 0x033, 0x00000027,
+ 0x03F, 0x00000EED,
+ 0x033, 0x00000028,
+ 0x03F, 0x00000EF0,
+ 0x033, 0x00000029,
+ 0x03F, 0x00000EF3,
+ 0x033, 0x0000002A,
+ 0x03F, 0x00000EF6,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060,
+ 0x03F, 0x00000001,
+ 0x033, 0x00000061,
+ 0x03F, 0x00000004,
+ 0x033, 0x00000062,
+ 0x03F, 0x00000007,
+ 0x033, 0x00000063,
+ 0x03F, 0x00000024,
+ 0x033, 0x00000064,
+ 0x03F, 0x00000027,
+ 0x033, 0x00000065,
+ 0x03F, 0x0000002A,
+ 0x033, 0x00000066,
+ 0x03F, 0x0000002D,
+ 0x033, 0x00000067,
+ 0x03F, 0x00000030,
+ 0x033, 0x00000068,
+ 0x03F, 0x00000033,
+ 0x033, 0x00000069,
+ 0x03F, 0x00000036,
+ 0x033, 0x0000006A,
+ 0x03F, 0x00000039,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060,
+ 0x03F, 0x00000E42,
+ 0x033, 0x00000061,
+ 0x03F, 0x00000E45,
+ 0x033, 0x00000062,
+ 0x03F, 0x00000E65,
+ 0x033, 0x00000063,
+ 0x03F, 0x00000E68,
+ 0x033, 0x00000064,
+ 0x03F, 0x00000EE5,
+ 0x033, 0x00000065,
+ 0x03F, 0x00000EE8,
+ 0x033, 0x00000066,
+ 0x03F, 0x00000EEB,
+ 0x033, 0x00000067,
+ 0x03F, 0x00000EEE,
+ 0x033, 0x00000068,
+ 0x03F, 0x00000EF1,
+ 0x033, 0x00000069,
+ 0x03F, 0x00000EF4,
+ 0x033, 0x0000006A,
+ 0x03F, 0x00000EF7,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x00000060,
+ 0x03F, 0x00000E09,
+ 0x033, 0x00000061,
+ 0x03F, 0x00000E43,
+ 0x033, 0x00000062,
+ 0x03F, 0x00000E46,
+ 0x033, 0x00000063,
+ 0x03F, 0x00000E49,
+ 0x033, 0x00000064,
+ 0x03F, 0x00000E88,
+ 0x033, 0x00000065,
+ 0x03F, 0x00000E8B,
+ 0x033, 0x00000066,
+ 0x03F, 0x00000ECB,
+ 0x033, 0x00000067,
+ 0x03F, 0x00000ECE,
+ 0x033, 0x00000068,
+ 0x03F, 0x00000EF0,
+ 0x033, 0x00000069,
+ 0x03F, 0x00000EF3,
+ 0x033, 0x0000006A,
+ 0x03F, 0x00000EF6,
+ 0xA0000000, 0x00000000,
+ 0x033, 0x00000060,
+ 0x03F, 0x00000E42,
+ 0x033, 0x00000061,
+ 0x03F, 0x00000E45,
+ 0x033, 0x00000062,
+ 0x03F, 0x00000E65,
+ 0x033, 0x00000063,
+ 0x03F, 0x00000E68,
+ 0x033, 0x00000064,
+ 0x03F, 0x00000EE5,
+ 0x033, 0x00000065,
+ 0x03F, 0x00000EE8,
+ 0x033, 0x00000066,
+ 0x03F, 0x00000EEB,
+ 0x033, 0x00000067,
+ 0x03F, 0x00000EEE,
+ 0x033, 0x00000068,
+ 0x03F, 0x00000EF1,
+ 0x033, 0x00000069,
+ 0x03F, 0x00000EF4,
+ 0x033, 0x0000006A,
+ 0x03F, 0x00000EF7,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0,
+ 0x03F, 0x00000001,
+ 0x033, 0x000000A1,
+ 0x03F, 0x00000004,
+ 0x033, 0x000000A2,
+ 0x03F, 0x00000007,
+ 0x033, 0x000000A3,
+ 0x03F, 0x00000025,
+ 0x033, 0x000000A4,
+ 0x03F, 0x00000028,
+ 0x033, 0x000000A5,
+ 0x03F, 0x0000002B,
+ 0x033, 0x000000A6,
+ 0x03F, 0x0000002E,
+ 0x033, 0x000000A7,
+ 0x03F, 0x00000031,
+ 0x033, 0x000000A8,
+ 0x03F, 0x00000034,
+ 0x033, 0x000000A9,
+ 0x03F, 0x00000037,
+ 0x033, 0x000000AA,
+ 0x03F, 0x0000003A,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0,
+ 0x03F, 0x00000E09,
+ 0x033, 0x000000A1,
+ 0x03F, 0x00000E43,
+ 0x033, 0x000000A2,
+ 0x03F, 0x00000E64,
+ 0x033, 0x000000A3,
+ 0x03F, 0x00000E67,
+ 0x033, 0x000000A4,
+ 0x03F, 0x00000EE4,
+ 0x033, 0x000000A5,
+ 0x03F, 0x00000EE7,
+ 0x033, 0x000000A6,
+ 0x03F, 0x00000EEA,
+ 0x033, 0x000000A7,
+ 0x03F, 0x00000EED,
+ 0x033, 0x000000A8,
+ 0x03F, 0x00000EF0,
+ 0x033, 0x000000A9,
+ 0x03F, 0x00000EF3,
+ 0x033, 0x000000AA,
+ 0x03F, 0x00000EF6,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x033, 0x000000A0,
+ 0x03F, 0x00000E08,
+ 0x033, 0x000000A1,
+ 0x03F, 0x00000E42,
+ 0x033, 0x000000A2,
+ 0x03F, 0x00000E45,
+ 0x033, 0x000000A3,
+ 0x03F, 0x00000E48,
+ 0x033, 0x000000A4,
+ 0x03F, 0x00000EA5,
+ 0x033, 0x000000A5,
+ 0x03F, 0x00000EA8,
+ 0x033, 0x000000A6,
+ 0x03F, 0x00000ECA,
+ 0x033, 0x000000A7,
+ 0x03F, 0x00000ECD,
+ 0x033, 0x000000A8,
+ 0x03F, 0x00000EEF,
+ 0x033, 0x000000A9,
+ 0x03F, 0x00000EF2,
+ 0x033, 0x000000AA,
+ 0x03F, 0x00000EF5,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x033, 0x000000A0,
+ 0x03F, 0x00000E09,
+ 0x033, 0x000000A1,
+ 0x03F, 0x00000E43,
+ 0x033, 0x000000A2,
+ 0x03F, 0x00000E64,
+ 0x033, 0x000000A3,
+ 0x03F, 0x00000E67,
+ 0x033, 0x000000A4,
+ 0x03F, 0x00000EE4,
+ 0x033, 0x000000A5,
+ 0x03F, 0x00000EE7,
+ 0x033, 0x000000A6,
+ 0x03F, 0x00000EEA,
+ 0x033, 0x000000A7,
+ 0x03F, 0x00000EED,
+ 0x033, 0x000000A8,
+ 0x03F, 0x00000EF0,
+ 0x033, 0x000000A9,
+ 0x03F, 0x00000EF3,
+ 0x033, 0x000000AA,
+ 0x03F, 0x00000EF6,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000400,
+ 0x033, 0x00000000,
+ 0x03F, 0x0006AC00,
+ 0x033, 0x00000001,
+ 0x03F, 0x00060C00,
+ 0x033, 0x00000002,
+ 0x03F, 0x0006AC00,
+ 0x033, 0x00000003,
+ 0x03F, 0x00086A00,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000400,
+ 0x033, 0x00000000,
+ 0x03F, 0x0006AC00,
+ 0x033, 0x00000001,
+ 0x03F, 0x00060C00,
+ 0x033, 0x00000002,
+ 0x03F, 0x0006AC00,
+ 0x033, 0x00000003,
+ 0x03F, 0x00086A00,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000400,
+ 0x033, 0x00000000,
+ 0x03F, 0x0006AC00,
+ 0x033, 0x00000001,
+ 0x03F, 0x00060C00,
+ 0x033, 0x00000002,
+ 0x03F, 0x0006AC00,
+ 0x033, 0x00000003,
+ 0x03F, 0x00086A00,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00000400,
+ 0x033, 0x00000000,
+ 0x03F, 0x0006AC00,
+ 0x033, 0x00000001,
+ 0x03F, 0x00060C00,
+ 0x033, 0x00000002,
+ 0x03F, 0x0006AC00,
+ 0x033, 0x00000003,
+ 0x03F, 0x00086A00,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000100,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000040,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000100,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000040,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000100,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000040,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00000100,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000040,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000040,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00040000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000001,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000002,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000003,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000004,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000005,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000006,
+ 0x03F, 0x00084A40,
+ 0x033, 0x00000007,
+ 0x03F, 0x00084A40,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00040000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000001,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000002,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000003,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000004,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000005,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000006,
+ 0x03F, 0x00084A40,
+ 0x033, 0x00000007,
+ 0x03F, 0x00084A40,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00040000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000001,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000002,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000003,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000004,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000005,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000006,
+ 0x03F, 0x00084A40,
+ 0x033, 0x00000007,
+ 0x03F, 0x00084A40,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00040000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000001,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000002,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000003,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000004,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000005,
+ 0x03F, 0x00086A40,
+ 0x033, 0x00000006,
+ 0x03F, 0x00084A40,
+ 0x033, 0x00000007,
+ 0x03F, 0x00084A40,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x051, 0x000801A8,
+ 0x052, 0x000972E3,
+ 0x053, 0x00008069,
+ 0x054, 0x00030032,
+ 0x055, 0x00082003,
+ 0x056, 0x00051CCB,
+ 0x057, 0x0000CFC2,
+ 0x058, 0x00000010,
+ 0x059, 0x00030000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x051, 0x000801A8,
+ 0x052, 0x000972E3,
+ 0x053, 0x00008069,
+ 0x054, 0x00030032,
+ 0x055, 0x00082003,
+ 0x056, 0x00051CCB,
+ 0x057, 0x0000CFC2,
+ 0x058, 0x00000010,
+ 0x059, 0x00030000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x051, 0x000801A8,
+ 0x052, 0x000972E3,
+ 0x053, 0x00008069,
+ 0x054, 0x00030032,
+ 0x055, 0x00082003,
+ 0x056, 0x00051CCB,
+ 0x057, 0x0000CFC2,
+ 0x058, 0x00000010,
+ 0x059, 0x00030000,
+ 0xA0000000, 0x00000000,
+ 0x051, 0x000801A8,
+ 0x052, 0x000972E3,
+ 0x053, 0x00008069,
+ 0x054, 0x00030032,
+ 0x055, 0x00082003,
+ 0x056, 0x00051CCB,
+ 0x057, 0x0000CFC2,
+ 0x058, 0x00000010,
+ 0x059, 0x00030000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000800,
+ 0x033, 0x00000000,
+ 0x03F, 0x00051429,
+ 0x033, 0x00000001,
+ 0x03F, 0x00051449,
+ 0x033, 0x00000002,
+ 0x03F, 0x0005144C,
+ 0x033, 0x00000003,
+ 0x03F, 0x00051C66,
+ 0x033, 0x00000004,
+ 0x03F, 0x00051C69,
+ 0x033, 0x00000005,
+ 0x03F, 0x00051C6C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00051CE8,
+ 0x033, 0x00000007,
+ 0x03F, 0x00051CEB,
+ 0x033, 0x00000008,
+ 0x03F, 0x00051CEE,
+ 0x033, 0x00000009,
+ 0x03F, 0x00051CF1,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00051CF4,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000800,
+ 0x033, 0x00000000,
+ 0x03F, 0x00051429,
+ 0x033, 0x00000001,
+ 0x03F, 0x00051449,
+ 0x033, 0x00000002,
+ 0x03F, 0x0005144C,
+ 0x033, 0x00000003,
+ 0x03F, 0x00051C66,
+ 0x033, 0x00000004,
+ 0x03F, 0x00051C69,
+ 0x033, 0x00000005,
+ 0x03F, 0x00051C6C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00051CE8,
+ 0x033, 0x00000007,
+ 0x03F, 0x00051CEB,
+ 0x033, 0x00000008,
+ 0x03F, 0x00051CEE,
+ 0x033, 0x00000009,
+ 0x03F, 0x00051CF1,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00051CF4,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000800,
+ 0x033, 0x00000000,
+ 0x03F, 0x00051427,
+ 0x033, 0x00000001,
+ 0x03F, 0x00051446,
+ 0x033, 0x00000002,
+ 0x03F, 0x00051449,
+ 0x033, 0x00000003,
+ 0x03F, 0x0005144C,
+ 0x033, 0x00000004,
+ 0x03F, 0x00051C67,
+ 0x033, 0x00000005,
+ 0x03F, 0x00051C6A,
+ 0x033, 0x00000006,
+ 0x03F, 0x00051C8B,
+ 0x033, 0x00000007,
+ 0x03F, 0x00051CE9,
+ 0x033, 0x00000008,
+ 0x03F, 0x00051CEC,
+ 0x033, 0x00000009,
+ 0x03F, 0x00051CEF,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00051CF2,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00000800,
+ 0x033, 0x00000000,
+ 0x03F, 0x00051427,
+ 0x033, 0x00000001,
+ 0x03F, 0x00051446,
+ 0x033, 0x00000002,
+ 0x03F, 0x00051449,
+ 0x033, 0x00000003,
+ 0x03F, 0x0005144C,
+ 0x033, 0x00000004,
+ 0x03F, 0x00051C67,
+ 0x033, 0x00000005,
+ 0x03F, 0x00051C6A,
+ 0x033, 0x00000006,
+ 0x03F, 0x00051C8B,
+ 0x033, 0x00000007,
+ 0x03F, 0x00051CE9,
+ 0x033, 0x00000008,
+ 0x03F, 0x00051CEC,
+ 0x033, 0x00000009,
+ 0x03F, 0x00051CEF,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00051CF2,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00004000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000001,
+ 0x03F, 0x00086E00,
+ 0x033, 0x00000002,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000003,
+ 0x03F, 0x00048400,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00004000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000001,
+ 0x03F, 0x00086E00,
+ 0x033, 0x00000002,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000003,
+ 0x03F, 0x00048400,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00004000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000001,
+ 0x03F, 0x00086E00,
+ 0x033, 0x00000002,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000003,
+ 0x03F, 0x00048400,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00004000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000001,
+ 0x03F, 0x00086E00,
+ 0x033, 0x00000002,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000003,
+ 0x03F, 0x00048400,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00002000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000000,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00002000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000000,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00002000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000000,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00002000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000001,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000002,
+ 0x03F, 0x00000000,
+ 0x033, 0x00000003,
+ 0x03F, 0x00000000,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00080000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000001,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000002,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000003,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000004,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000005,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000006,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000007,
+ 0x03F, 0x00048400,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00080000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000001,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000002,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000003,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000004,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000005,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000006,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000007,
+ 0x03F, 0x00048400,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00080000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000001,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000002,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000003,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000004,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000005,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000006,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000007,
+ 0x03F, 0x00048400,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00080000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000001,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000002,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000003,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000004,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000005,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000006,
+ 0x03F, 0x00048400,
+ 0x033, 0x00000007,
+ 0x03F, 0x00048400,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x070, 0x00008000,
+ 0x075, 0x000027DA,
+ 0x076, 0x00006997,
+ 0x077, 0x00070418,
+ 0x078, 0x000BB000,
+ 0x07D, 0x00007600,
+ 0x07F, 0x00000000,
+ 0x06A, 0x000F4C00,
+ 0x065, 0x00082030,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x070, 0x00008000,
+ 0x075, 0x000027DA,
+ 0x076, 0x00006997,
+ 0x077, 0x00070418,
+ 0x078, 0x000BB000,
+ 0x07D, 0x00007600,
+ 0x07F, 0x00000000,
+ 0x06A, 0x000F4C00,
+ 0x065, 0x00082030,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x070, 0x00008000,
+ 0x075, 0x000027DA,
+ 0x076, 0x00006997,
+ 0x077, 0x00070418,
+ 0x078, 0x000BB000,
+ 0x07D, 0x00007600,
+ 0x07F, 0x00000000,
+ 0x06A, 0x000F4C00,
+ 0x065, 0x00082030,
+ 0xA0000000, 0x00000000,
+ 0x070, 0x00008000,
+ 0x075, 0x000027DA,
+ 0x076, 0x00006997,
+ 0x077, 0x00070418,
+ 0x078, 0x000BB000,
+ 0x07D, 0x00007600,
+ 0x07F, 0x00000000,
+ 0x06A, 0x000F4C00,
+ 0x065, 0x00082030,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00008000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00051427,
+ 0x033, 0x00000001,
+ 0x03F, 0x00051446,
+ 0x033, 0x00000002,
+ 0x03F, 0x00051449,
+ 0x033, 0x00000003,
+ 0x03F, 0x0005144C,
+ 0x033, 0x00000004,
+ 0x03F, 0x00051C69,
+ 0x033, 0x00000005,
+ 0x03F, 0x00051C6C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00051C8D,
+ 0x033, 0x00000007,
+ 0x03F, 0x00051CEB,
+ 0x033, 0x00000008,
+ 0x03F, 0x00051CEE,
+ 0x033, 0x00000009,
+ 0x03F, 0x00051CF1,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00051CF4,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00008000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00051427,
+ 0x033, 0x00000001,
+ 0x03F, 0x00051446,
+ 0x033, 0x00000002,
+ 0x03F, 0x00051449,
+ 0x033, 0x00000003,
+ 0x03F, 0x0005144C,
+ 0x033, 0x00000004,
+ 0x03F, 0x00051C69,
+ 0x033, 0x00000005,
+ 0x03F, 0x00051C6C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00051C8D,
+ 0x033, 0x00000007,
+ 0x03F, 0x00051CEB,
+ 0x033, 0x00000008,
+ 0x03F, 0x00051CEE,
+ 0x033, 0x00000009,
+ 0x03F, 0x00051CF1,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00051CF4,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00008000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00051427,
+ 0x033, 0x00000001,
+ 0x03F, 0x00051446,
+ 0x033, 0x00000002,
+ 0x03F, 0x00051449,
+ 0x033, 0x00000003,
+ 0x03F, 0x0005144C,
+ 0x033, 0x00000004,
+ 0x03F, 0x00051C69,
+ 0x033, 0x00000005,
+ 0x03F, 0x00051C6C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00051C8D,
+ 0x033, 0x00000007,
+ 0x03F, 0x00051CEB,
+ 0x033, 0x00000008,
+ 0x03F, 0x00051CEE,
+ 0x033, 0x00000009,
+ 0x03F, 0x00051CF1,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00051CF4,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00008000,
+ 0x033, 0x00000000,
+ 0x03F, 0x00051427,
+ 0x033, 0x00000001,
+ 0x03F, 0x00051446,
+ 0x033, 0x00000002,
+ 0x03F, 0x00051449,
+ 0x033, 0x00000003,
+ 0x03F, 0x0005144C,
+ 0x033, 0x00000004,
+ 0x03F, 0x00051C69,
+ 0x033, 0x00000005,
+ 0x03F, 0x00051C6C,
+ 0x033, 0x00000006,
+ 0x03F, 0x00051C8D,
+ 0x033, 0x00000007,
+ 0x03F, 0x00051CEB,
+ 0x033, 0x00000008,
+ 0x03F, 0x00051CEE,
+ 0x033, 0x00000009,
+ 0x03F, 0x00051CF1,
+ 0x033, 0x0000000A,
+ 0x03F, 0x00051CF4,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000010,
+ 0x033, 0x00000000,
+ 0x008, 0x0009C060,
+ 0x033, 0x00000001,
+ 0x008, 0x0009C060,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000010,
+ 0x033, 0x00000000,
+ 0x008, 0x0009C060,
+ 0x033, 0x00000001,
+ 0x008, 0x0009C060,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00000010,
+ 0x033, 0x00000000,
+ 0x008, 0x0009C060,
+ 0x033, 0x00000001,
+ 0x008, 0x0009C060,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00000010,
+ 0x033, 0x00000000,
+ 0x008, 0x0009C060,
+ 0x033, 0x00000001,
+ 0x008, 0x0009C060,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000024,
+ 0x03E, 0x0000003F,
+ 0x03F, 0x00060FDE,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000024,
+ 0x03E, 0x0000003F,
+ 0x03F, 0x00060FDE,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000024,
+ 0x03E, 0x0000003F,
+ 0x03F, 0x00060FDE,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000024,
+ 0x03E, 0x0000003F,
+ 0x03F, 0x00060FDE,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000025,
+ 0x03E, 0x00000037,
+ 0x03F, 0x0007EFCE,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000025,
+ 0x03E, 0x00000037,
+ 0x03F, 0x0007EFCE,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000025,
+ 0x03E, 0x00000037,
+ 0x03F, 0x0007EFCE,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000025,
+ 0x03E, 0x00000037,
+ 0x03F, 0x0007EFCE,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000026,
+ 0x03E, 0x00000037,
+ 0x03F, 0x0005EFCE,
+ 0x0EF, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000026,
+ 0x03E, 0x00000037,
+ 0x03F, 0x0005EFCE,
+ 0x0EF, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000026,
+ 0x03E, 0x00000037,
+ 0x03F, 0x0005EFCE,
+ 0x0EF, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EF, 0x00080000,
+ 0x033, 0x00000026,
+ 0x03E, 0x00000037,
+ 0x03F, 0x0005EFCE,
+ 0x0EF, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000004,
+ 0x03F, 0x00001EC1,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000004,
+ 0x03F, 0x00001EC1,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000004,
+ 0x03F, 0x00001EC1,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000004,
+ 0x03F, 0x00001EC1,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000005,
+ 0x03F, 0x00001ECF,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000005,
+ 0x03F, 0x00001ECF,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000005,
+ 0x03F, 0x00001ECF,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000005,
+ 0x03F, 0x00001ECF,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x80001005, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000006,
+ 0x03F, 0x00001F9D,
+ 0x0EE, 0x00000000,
+ 0x90001004, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000006,
+ 0x03F, 0x00001F9D,
+ 0x0EE, 0x00000000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000006,
+ 0x03F, 0x00001F9D,
+ 0x0EE, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x0EE, 0x00001000,
+ 0x033, 0x00000006,
+ 0x03F, 0x00001F9D,
+ 0x0EE, 0x00000000,
+ 0xB0000000, 0x00000000,
+
+};
+
+RTW_DECL_TABLE_RF_RADIO(rtw8821c_rf_a, A);
+
+static const struct rtw_txpwr_lmt_cfg_pair rtw8821c_txpwr_lmt_type0[] = {
+ { 0, 0, 0, 0, 1, 30, },
+ { 2, 0, 0, 0, 1, 30, },
+ { 0, 0, 0, 0, 2, 32, },
+ { 2, 0, 0, 0, 2, 30, },
+ { 0, 0, 0, 0, 3, 32, },
+ { 2, 0, 0, 0, 3, 30, },
+ { 0, 0, 0, 0, 4, 32, },
+ { 2, 0, 0, 0, 4, 30, },
+ { 0, 0, 0, 0, 5, 32, },
+ { 2, 0, 0, 0, 5, 30, },
+ { 0, 0, 0, 0, 6, 32, },
+ { 2, 0, 0, 0, 6, 30, },
+ { 0, 0, 0, 0, 7, 32, },
+ { 2, 0, 0, 0, 7, 30, },
+ { 0, 0, 0, 0, 8, 32, },
+ { 2, 0, 0, 0, 8, 30, },
+ { 0, 0, 0, 0, 9, 32, },
+ { 2, 0, 0, 0, 9, 30, },
+ { 0, 0, 0, 0, 10, 32, },
+ { 2, 0, 0, 0, 10, 30, },
+ { 0, 0, 0, 0, 11, 32, },
+ { 2, 0, 0, 0, 11, 30, },
+ { 0, 0, 0, 0, 12, 24, },
+ { 2, 0, 0, 0, 12, 30, },
+ { 0, 0, 0, 0, 13, 16, },
+ { 2, 0, 0, 0, 13, 30, },
+ { 0, 0, 0, 0, 14, 63, },
+ { 2, 0, 0, 0, 14, 63, },
+ { 0, 0, 0, 1, 1, 30, },
+ { 2, 0, 0, 1, 1, 30, },
+ { 0, 0, 0, 1, 2, 32, },
+ { 2, 0, 0, 1, 2, 30, },
+ { 0, 0, 0, 1, 3, 34, },
+ { 2, 0, 0, 1, 3, 30, },
+ { 0, 0, 0, 1, 4, 34, },
+ { 2, 0, 0, 1, 4, 30, },
+ { 0, 0, 0, 1, 5, 34, },
+ { 2, 0, 0, 1, 5, 30, },
+ { 0, 0, 0, 1, 6, 34, },
+ { 2, 0, 0, 1, 6, 30, },
+ { 0, 0, 0, 1, 7, 34, },
+ { 2, 0, 0, 1, 7, 30, },
+ { 0, 0, 0, 1, 8, 34, },
+ { 2, 0, 0, 1, 8, 30, },
+ { 0, 0, 0, 1, 9, 34, },
+ { 2, 0, 0, 1, 9, 30, },
+ { 0, 0, 0, 1, 10, 32, },
+ { 2, 0, 0, 1, 10, 30, },
+ { 0, 0, 0, 1, 11, 30, },
+ { 2, 0, 0, 1, 11, 30, },
+ { 0, 0, 0, 1, 12, 28, },
+ { 2, 0, 0, 1, 12, 30, },
+ { 0, 0, 0, 1, 13, 16, },
+ { 2, 0, 0, 1, 13, 30, },
+ { 0, 0, 0, 1, 14, 63, },
+ { 2, 0, 0, 1, 14, 63, },
+ { 0, 0, 0, 2, 1, 26, },
+ { 2, 0, 0, 2, 1, 30, },
+ { 0, 0, 0, 2, 2, 30, },
+ { 2, 0, 0, 2, 2, 30, },
+ { 0, 0, 0, 2, 3, 32, },
+ { 2, 0, 0, 2, 3, 30, },
+ { 0, 0, 0, 2, 4, 34, },
+ { 2, 0, 0, 2, 4, 30, },
+ { 0, 0, 0, 2, 5, 34, },
+ { 2, 0, 0, 2, 5, 30, },
+ { 0, 0, 0, 2, 6, 34, },
+ { 2, 0, 0, 2, 6, 30, },
+ { 0, 0, 0, 2, 7, 34, },
+ { 2, 0, 0, 2, 7, 30, },
+ { 0, 0, 0, 2, 8, 34, },
+ { 2, 0, 0, 2, 8, 30, },
+ { 0, 0, 0, 2, 9, 32, },
+ { 2, 0, 0, 2, 9, 30, },
+ { 0, 0, 0, 2, 10, 30, },
+ { 2, 0, 0, 2, 10, 30, },
+ { 0, 0, 0, 2, 11, 28, },
+ { 2, 0, 0, 2, 11, 30, },
+ { 0, 0, 0, 2, 12, 26, },
+ { 2, 0, 0, 2, 12, 30, },
+ { 0, 0, 0, 2, 13, 12, },
+ { 2, 0, 0, 2, 13, 30, },
+ { 0, 0, 0, 2, 14, 63, },
+ { 2, 0, 0, 2, 14, 63, },
+ { 0, 0, 1, 2, 1, 63, },
+ { 2, 0, 1, 2, 1, 63, },
+ { 0, 0, 1, 2, 2, 63, },
+ { 2, 0, 1, 2, 2, 63, },
+ { 0, 0, 1, 2, 3, 26, },
+ { 2, 0, 1, 2, 3, 30, },
+ { 0, 0, 1, 2, 4, 26, },
+ { 2, 0, 1, 2, 4, 30, },
+ { 0, 0, 1, 2, 5, 30, },
+ { 2, 0, 1, 2, 5, 30, },
+ { 0, 0, 1, 2, 6, 30, },
+ { 2, 0, 1, 2, 6, 30, },
+ { 0, 0, 1, 2, 7, 30, },
+ { 2, 0, 1, 2, 7, 30, },
+ { 0, 0, 1, 2, 8, 26, },
+ { 2, 0, 1, 2, 8, 30, },
+ { 0, 0, 1, 2, 9, 26, },
+ { 2, 0, 1, 2, 9, 30, },
+ { 0, 0, 1, 2, 10, 28, },
+ { 2, 0, 1, 2, 10, 30, },
+ { 0, 0, 1, 2, 11, 20, },
+ { 2, 0, 1, 2, 11, 30, },
+ { 0, 0, 1, 2, 12, 63, },
+ { 2, 0, 1, 2, 12, 63, },
+ { 0, 0, 1, 2, 13, 63, },
+ { 2, 0, 1, 2, 13, 63, },
+ { 0, 0, 1, 2, 14, 63, },
+ { 2, 0, 1, 2, 14, 63, },
+ { 0, 1, 0, 1, 36, 31, },
+ { 2, 1, 0, 1, 36, 32, },
+ { 0, 1, 0, 1, 40, 33, },
+ { 2, 1, 0, 1, 40, 32, },
+ { 0, 1, 0, 1, 44, 33, },
+ { 2, 1, 0, 1, 44, 32, },
+ { 0, 1, 0, 1, 48, 31, },
+ { 2, 1, 0, 1, 48, 32, },
+ { 0, 1, 0, 1, 52, 33, },
+ { 2, 1, 0, 1, 52, 32, },
+ { 0, 1, 0, 1, 56, 33, },
+ { 2, 1, 0, 1, 56, 32, },
+ { 0, 1, 0, 1, 60, 33, },
+ { 2, 1, 0, 1, 60, 32, },
+ { 0, 1, 0, 1, 64, 30, },
+ { 2, 1, 0, 1, 64, 32, },
+ { 0, 1, 0, 1, 100, 30, },
+ { 2, 1, 0, 1, 100, 32, },
+ { 0, 1, 0, 1, 104, 33, },
+ { 2, 1, 0, 1, 104, 32, },
+ { 0, 1, 0, 1, 108, 33, },
+ { 2, 1, 0, 1, 108, 32, },
+ { 0, 1, 0, 1, 112, 33, },
+ { 2, 1, 0, 1, 112, 32, },
+ { 0, 1, 0, 1, 116, 33, },
+ { 2, 1, 0, 1, 116, 32, },
+ { 0, 1, 0, 1, 120, 33, },
+ { 2, 1, 0, 1, 120, 32, },
+ { 0, 1, 0, 1, 124, 33, },
+ { 2, 1, 0, 1, 124, 32, },
+ { 0, 1, 0, 1, 128, 33, },
+ { 2, 1, 0, 1, 128, 32, },
+ { 0, 1, 0, 1, 132, 33, },
+ { 2, 1, 0, 1, 132, 32, },
+ { 0, 1, 0, 1, 136, 33, },
+ { 2, 1, 0, 1, 136, 32, },
+ { 0, 1, 0, 1, 140, 31, },
+ { 2, 1, 0, 1, 140, 32, },
+ { 0, 1, 0, 1, 144, 30, },
+ { 2, 1, 0, 1, 144, 63, },
+ { 0, 1, 0, 1, 149, 33, },
+ { 2, 1, 0, 1, 149, 63, },
+ { 0, 1, 0, 1, 153, 33, },
+ { 2, 1, 0, 1, 153, 63, },
+ { 0, 1, 0, 1, 157, 33, },
+ { 2, 1, 0, 1, 157, 63, },
+ { 0, 1, 0, 1, 161, 33, },
+ { 2, 1, 0, 1, 161, 63, },
+ { 0, 1, 0, 1, 165, 33, },
+ { 2, 1, 0, 1, 165, 63, },
+ { 0, 1, 0, 2, 36, 30, },
+ { 2, 1, 0, 2, 36, 32, },
+ { 0, 1, 0, 2, 40, 33, },
+ { 2, 1, 0, 2, 40, 32, },
+ { 0, 1, 0, 2, 44, 33, },
+ { 2, 1, 0, 2, 44, 32, },
+ { 0, 1, 0, 2, 48, 33, },
+ { 2, 1, 0, 2, 48, 32, },
+ { 0, 1, 0, 2, 52, 33, },
+ { 2, 1, 0, 2, 52, 32, },
+ { 0, 1, 0, 2, 56, 33, },
+ { 2, 1, 0, 2, 56, 32, },
+ { 0, 1, 0, 2, 60, 33, },
+ { 2, 1, 0, 2, 60, 32, },
+ { 0, 1, 0, 2, 64, 30, },
+ { 2, 1, 0, 2, 64, 32, },
+ { 0, 1, 0, 2, 100, 30, },
+ { 2, 1, 0, 2, 100, 32, },
+ { 0, 1, 0, 2, 104, 33, },
+ { 2, 1, 0, 2, 104, 32, },
+ { 0, 1, 0, 2, 108, 33, },
+ { 2, 1, 0, 2, 108, 32, },
+ { 0, 1, 0, 2, 112, 33, },
+ { 2, 1, 0, 2, 112, 32, },
+ { 0, 1, 0, 2, 116, 33, },
+ { 2, 1, 0, 2, 116, 32, },
+ { 0, 1, 0, 2, 120, 33, },
+ { 2, 1, 0, 2, 120, 32, },
+ { 0, 1, 0, 2, 124, 33, },
+ { 2, 1, 0, 2, 124, 32, },
+ { 0, 1, 0, 2, 128, 33, },
+ { 2, 1, 0, 2, 128, 32, },
+ { 0, 1, 0, 2, 132, 33, },
+ { 2, 1, 0, 2, 132, 32, },
+ { 0, 1, 0, 2, 136, 33, },
+ { 2, 1, 0, 2, 136, 32, },
+ { 0, 1, 0, 2, 140, 29, },
+ { 2, 1, 0, 2, 140, 32, },
+ { 0, 1, 0, 2, 144, 27, },
+ { 2, 1, 0, 2, 144, 63, },
+ { 0, 1, 0, 2, 149, 33, },
+ { 2, 1, 0, 2, 149, 63, },
+ { 0, 1, 0, 2, 153, 33, },
+ { 2, 1, 0, 2, 153, 63, },
+ { 0, 1, 0, 2, 157, 33, },
+ { 2, 1, 0, 2, 157, 63, },
+ { 0, 1, 0, 2, 161, 33, },
+ { 2, 1, 0, 2, 161, 63, },
+ { 0, 1, 0, 2, 165, 33, },
+ { 2, 1, 0, 2, 165, 63, },
+ { 0, 1, 1, 2, 38, 22, },
+ { 2, 1, 1, 2, 38, 32, },
+ { 0, 1, 1, 2, 46, 32, },
+ { 2, 1, 1, 2, 46, 32, },
+ { 0, 1, 1, 2, 54, 32, },
+ { 2, 1, 1, 2, 54, 32, },
+ { 0, 1, 1, 2, 62, 23, },
+ { 2, 1, 1, 2, 62, 32, },
+ { 0, 1, 1, 2, 102, 21, },
+ { 2, 1, 1, 2, 102, 32, },
+ { 0, 1, 1, 2, 110, 32, },
+ { 2, 1, 1, 2, 110, 32, },
+ { 0, 1, 1, 2, 118, 32, },
+ { 2, 1, 1, 2, 118, 32, },
+ { 0, 1, 1, 2, 126, 32, },
+ { 2, 1, 1, 2, 126, 32, },
+ { 0, 1, 1, 2, 134, 32, },
+ { 2, 1, 1, 2, 134, 32, },
+ { 0, 1, 1, 2, 142, 29, },
+ { 2, 1, 1, 2, 142, 63, },
+ { 0, 1, 1, 2, 151, 32, },
+ { 2, 1, 1, 2, 151, 63, },
+ { 0, 1, 1, 2, 159, 32, },
+ { 2, 1, 1, 2, 159, 63, },
+ { 0, 1, 2, 4, 42, 19, },
+ { 2, 1, 2, 4, 42, 32, },
+ { 0, 1, 2, 4, 58, 22, },
+ { 2, 1, 2, 4, 58, 32, },
+ { 0, 1, 2, 4, 106, 18, },
+ { 2, 1, 2, 4, 106, 32, },
+ { 0, 1, 2, 4, 122, 32, },
+ { 2, 1, 2, 4, 122, 32, },
+ { 0, 1, 2, 4, 138, 28, },
+ { 2, 1, 2, 4, 138, 63, },
+ { 0, 1, 2, 4, 155, 32, },
+ { 2, 1, 2, 4, 155, 63, },
+ { 1, 0, 0, 0, 1, 34, },
+ { 3, 0, 0, 0, 1, 30, },
+ { 4, 0, 0, 0, 1, 34, },
+ { 5, 0, 0, 0, 1, 30, },
+ { 6, 0, 0, 0, 1, 30, },
+ { 7, 0, 0, 0, 1, 30, },
+ { 1, 0, 0, 0, 2, 34, },
+ { 3, 0, 0, 0, 2, 32, },
+ { 4, 0, 0, 0, 2, 34, },
+ { 5, 0, 0, 0, 2, 30, },
+ { 6, 0, 0, 0, 2, 32, },
+ { 7, 0, 0, 0, 2, 30, },
+ { 1, 0, 0, 0, 3, 34, },
+ { 3, 0, 0, 0, 3, 32, },
+ { 4, 0, 0, 0, 3, 34, },
+ { 5, 0, 0, 0, 3, 30, },
+ { 6, 0, 0, 0, 3, 32, },
+ { 7, 0, 0, 0, 3, 30, },
+ { 1, 0, 0, 0, 4, 34, },
+ { 3, 0, 0, 0, 4, 32, },
+ { 4, 0, 0, 0, 4, 34, },
+ { 5, 0, 0, 0, 4, 30, },
+ { 6, 0, 0, 0, 4, 32, },
+ { 7, 0, 0, 0, 4, 30, },
+ { 1, 0, 0, 0, 5, 34, },
+ { 3, 0, 0, 0, 5, 32, },
+ { 4, 0, 0, 0, 5, 34, },
+ { 5, 0, 0, 0, 5, 30, },
+ { 6, 0, 0, 0, 5, 32, },
+ { 7, 0, 0, 0, 5, 30, },
+ { 1, 0, 0, 0, 6, 34, },
+ { 3, 0, 0, 0, 6, 32, },
+ { 4, 0, 0, 0, 6, 34, },
+ { 5, 0, 0, 0, 6, 30, },
+ { 6, 0, 0, 0, 6, 32, },
+ { 7, 0, 0, 0, 6, 30, },
+ { 1, 0, 0, 0, 7, 34, },
+ { 3, 0, 0, 0, 7, 32, },
+ { 4, 0, 0, 0, 7, 34, },
+ { 5, 0, 0, 0, 7, 30, },
+ { 6, 0, 0, 0, 7, 32, },
+ { 7, 0, 0, 0, 7, 30, },
+ { 1, 0, 0, 0, 8, 34, },
+ { 3, 0, 0, 0, 8, 32, },
+ { 4, 0, 0, 0, 8, 34, },
+ { 5, 0, 0, 0, 8, 30, },
+ { 6, 0, 0, 0, 8, 32, },
+ { 7, 0, 0, 0, 8, 30, },
+ { 1, 0, 0, 0, 9, 34, },
+ { 3, 0, 0, 0, 9, 32, },
+ { 4, 0, 0, 0, 9, 34, },
+ { 5, 0, 0, 0, 9, 30, },
+ { 6, 0, 0, 0, 9, 32, },
+ { 7, 0, 0, 0, 9, 30, },
+ { 1, 0, 0, 0, 10, 34, },
+ { 3, 0, 0, 0, 10, 32, },
+ { 4, 0, 0, 0, 10, 34, },
+ { 5, 0, 0, 0, 10, 30, },
+ { 6, 0, 0, 0, 10, 32, },
+ { 7, 0, 0, 0, 10, 30, },
+ { 1, 0, 0, 0, 11, 34, },
+ { 3, 0, 0, 0, 11, 32, },
+ { 4, 0, 0, 0, 11, 34, },
+ { 5, 0, 0, 0, 11, 30, },
+ { 6, 0, 0, 0, 11, 32, },
+ { 7, 0, 0, 0, 11, 30, },
+ { 1, 0, 0, 0, 12, 34, },
+ { 3, 0, 0, 0, 12, 24, },
+ { 4, 0, 0, 0, 12, 34, },
+ { 5, 0, 0, 0, 12, 30, },
+ { 6, 0, 0, 0, 12, 24, },
+ { 7, 0, 0, 0, 12, 30, },
+ { 1, 0, 0, 0, 13, 34, },
+ { 3, 0, 0, 0, 13, 16, },
+ { 4, 0, 0, 0, 13, 34, },
+ { 5, 0, 0, 0, 13, 30, },
+ { 6, 0, 0, 0, 13, 16, },
+ { 7, 0, 0, 0, 13, 30, },
+ { 1, 0, 0, 0, 14, 34, },
+ { 3, 0, 0, 0, 14, 63, },
+ { 4, 0, 0, 0, 14, 63, },
+ { 5, 0, 0, 0, 14, 63, },
+ { 6, 0, 0, 0, 14, 63, },
+ { 7, 0, 0, 0, 14, 63, },
+ { 1, 0, 0, 1, 1, 34, },
+ { 3, 0, 0, 1, 1, 30, },
+ { 4, 0, 0, 1, 1, 32, },
+ { 5, 0, 0, 1, 1, 30, },
+ { 6, 0, 0, 1, 1, 30, },
+ { 7, 0, 0, 1, 1, 30, },
+ { 1, 0, 0, 1, 2, 34, },
+ { 3, 0, 0, 1, 2, 32, },
+ { 4, 0, 0, 1, 2, 34, },
+ { 5, 0, 0, 1, 2, 30, },
+ { 6, 0, 0, 1, 2, 32, },
+ { 7, 0, 0, 1, 2, 30, },
+ { 1, 0, 0, 1, 3, 34, },
+ { 3, 0, 0, 1, 3, 34, },
+ { 4, 0, 0, 1, 3, 34, },
+ { 5, 0, 0, 1, 3, 30, },
+ { 6, 0, 0, 1, 3, 34, },
+ { 7, 0, 0, 1, 3, 30, },
+ { 1, 0, 0, 1, 4, 34, },
+ { 3, 0, 0, 1, 4, 34, },
+ { 4, 0, 0, 1, 4, 34, },
+ { 5, 0, 0, 1, 4, 30, },
+ { 6, 0, 0, 1, 4, 34, },
+ { 7, 0, 0, 1, 4, 30, },
+ { 1, 0, 0, 1, 5, 34, },
+ { 3, 0, 0, 1, 5, 34, },
+ { 4, 0, 0, 1, 5, 34, },
+ { 5, 0, 0, 1, 5, 30, },
+ { 6, 0, 0, 1, 5, 34, },
+ { 7, 0, 0, 1, 5, 30, },
+ { 1, 0, 0, 1, 6, 34, },
+ { 3, 0, 0, 1, 6, 34, },
+ { 4, 0, 0, 1, 6, 34, },
+ { 5, 0, 0, 1, 6, 30, },
+ { 6, 0, 0, 1, 6, 34, },
+ { 7, 0, 0, 1, 6, 30, },
+ { 1, 0, 0, 1, 7, 34, },
+ { 3, 0, 0, 1, 7, 34, },
+ { 4, 0, 0, 1, 7, 34, },
+ { 5, 0, 0, 1, 7, 30, },
+ { 6, 0, 0, 1, 7, 34, },
+ { 7, 0, 0, 1, 7, 30, },
+ { 1, 0, 0, 1, 8, 34, },
+ { 3, 0, 0, 1, 8, 34, },
+ { 4, 0, 0, 1, 8, 34, },
+ { 5, 0, 0, 1, 8, 30, },
+ { 6, 0, 0, 1, 8, 34, },
+ { 7, 0, 0, 1, 8, 30, },
+ { 1, 0, 0, 1, 9, 34, },
+ { 3, 0, 0, 1, 9, 34, },
+ { 4, 0, 0, 1, 9, 34, },
+ { 5, 0, 0, 1, 9, 30, },
+ { 6, 0, 0, 1, 9, 34, },
+ { 7, 0, 0, 1, 9, 30, },
+ { 1, 0, 0, 1, 10, 34, },
+ { 3, 0, 0, 1, 10, 32, },
+ { 4, 0, 0, 1, 10, 34, },
+ { 5, 0, 0, 1, 10, 30, },
+ { 6, 0, 0, 1, 10, 32, },
+ { 7, 0, 0, 1, 10, 30, },
+ { 1, 0, 0, 1, 11, 34, },
+ { 3, 0, 0, 1, 11, 30, },
+ { 4, 0, 0, 1, 11, 34, },
+ { 5, 0, 0, 1, 11, 30, },
+ { 6, 0, 0, 1, 11, 30, },
+ { 7, 0, 0, 1, 11, 30, },
+ { 1, 0, 0, 1, 12, 34, },
+ { 3, 0, 0, 1, 12, 28, },
+ { 4, 0, 0, 1, 12, 34, },
+ { 5, 0, 0, 1, 12, 30, },
+ { 6, 0, 0, 1, 12, 28, },
+ { 7, 0, 0, 1, 12, 30, },
+ { 1, 0, 0, 1, 13, 34, },
+ { 3, 0, 0, 1, 13, 16, },
+ { 4, 0, 0, 1, 13, 32, },
+ { 5, 0, 0, 1, 13, 30, },
+ { 6, 0, 0, 1, 13, 16, },
+ { 7, 0, 0, 1, 13, 30, },
+ { 1, 0, 0, 1, 14, 63, },
+ { 3, 0, 0, 1, 14, 63, },
+ { 4, 0, 0, 1, 14, 63, },
+ { 5, 0, 0, 1, 14, 63, },
+ { 6, 0, 0, 1, 14, 63, },
+ { 7, 0, 0, 1, 14, 63, },
+ { 1, 0, 0, 2, 1, 34, },
+ { 3, 0, 0, 2, 1, 26, },
+ { 4, 0, 0, 2, 1, 32, },
+ { 5, 0, 0, 2, 1, 30, },
+ { 6, 0, 0, 2, 1, 26, },
+ { 7, 0, 0, 2, 1, 30, },
+ { 1, 0, 0, 2, 2, 34, },
+ { 3, 0, 0, 2, 2, 30, },
+ { 4, 0, 0, 2, 2, 34, },
+ { 5, 0, 0, 2, 2, 30, },
+ { 6, 0, 0, 2, 2, 30, },
+ { 7, 0, 0, 2, 2, 30, },
+ { 1, 0, 0, 2, 3, 34, },
+ { 3, 0, 0, 2, 3, 32, },
+ { 4, 0, 0, 2, 3, 34, },
+ { 5, 0, 0, 2, 3, 30, },
+ { 6, 0, 0, 2, 3, 32, },
+ { 7, 0, 0, 2, 3, 30, },
+ { 1, 0, 0, 2, 4, 34, },
+ { 3, 0, 0, 2, 4, 34, },
+ { 4, 0, 0, 2, 4, 34, },
+ { 5, 0, 0, 2, 4, 30, },
+ { 6, 0, 0, 2, 4, 34, },
+ { 7, 0, 0, 2, 4, 30, },
+ { 1, 0, 0, 2, 5, 34, },
+ { 3, 0, 0, 2, 5, 34, },
+ { 4, 0, 0, 2, 5, 34, },
+ { 5, 0, 0, 2, 5, 30, },
+ { 6, 0, 0, 2, 5, 34, },
+ { 7, 0, 0, 2, 5, 30, },
+ { 1, 0, 0, 2, 6, 34, },
+ { 3, 0, 0, 2, 6, 34, },
+ { 4, 0, 0, 2, 6, 34, },
+ { 5, 0, 0, 2, 6, 30, },
+ { 6, 0, 0, 2, 6, 34, },
+ { 7, 0, 0, 2, 6, 30, },
+ { 1, 0, 0, 2, 7, 34, },
+ { 3, 0, 0, 2, 7, 34, },
+ { 4, 0, 0, 2, 7, 34, },
+ { 5, 0, 0, 2, 7, 30, },
+ { 6, 0, 0, 2, 7, 34, },
+ { 7, 0, 0, 2, 7, 30, },
+ { 1, 0, 0, 2, 8, 34, },
+ { 3, 0, 0, 2, 8, 34, },
+ { 4, 0, 0, 2, 8, 34, },
+ { 5, 0, 0, 2, 8, 30, },
+ { 6, 0, 0, 2, 8, 34, },
+ { 7, 0, 0, 2, 8, 30, },
+ { 1, 0, 0, 2, 9, 34, },
+ { 3, 0, 0, 2, 9, 32, },
+ { 4, 0, 0, 2, 9, 34, },
+ { 5, 0, 0, 2, 9, 30, },
+ { 6, 0, 0, 2, 9, 32, },
+ { 7, 0, 0, 2, 9, 30, },
+ { 1, 0, 0, 2, 10, 34, },
+ { 3, 0, 0, 2, 10, 30, },
+ { 4, 0, 0, 2, 10, 34, },
+ { 5, 0, 0, 2, 10, 30, },
+ { 6, 0, 0, 2, 10, 30, },
+ { 7, 0, 0, 2, 10, 30, },
+ { 1, 0, 0, 2, 11, 34, },
+ { 3, 0, 0, 2, 11, 28, },
+ { 4, 0, 0, 2, 11, 34, },
+ { 5, 0, 0, 2, 11, 30, },
+ { 6, 0, 0, 2, 11, 28, },
+ { 7, 0, 0, 2, 11, 30, },
+ { 1, 0, 0, 2, 12, 34, },
+ { 3, 0, 0, 2, 12, 26, },
+ { 4, 0, 0, 2, 12, 34, },
+ { 5, 0, 0, 2, 12, 30, },
+ { 6, 0, 0, 2, 12, 26, },
+ { 7, 0, 0, 2, 12, 30, },
+ { 1, 0, 0, 2, 13, 34, },
+ { 3, 0, 0, 2, 13, 12, },
+ { 4, 0, 0, 2, 13, 32, },
+ { 5, 0, 0, 2, 13, 30, },
+ { 6, 0, 0, 2, 13, 12, },
+ { 7, 0, 0, 2, 13, 30, },
+ { 1, 0, 0, 2, 14, 63, },
+ { 3, 0, 0, 2, 14, 63, },
+ { 4, 0, 0, 2, 14, 63, },
+ { 5, 0, 0, 2, 14, 63, },
+ { 6, 0, 0, 2, 14, 63, },
+ { 7, 0, 0, 2, 14, 63, },
+ { 1, 0, 1, 2, 1, 63, },
+ { 3, 0, 1, 2, 1, 63, },
+ { 4, 0, 1, 2, 1, 63, },
+ { 5, 0, 1, 2, 1, 63, },
+ { 6, 0, 1, 2, 1, 63, },
+ { 7, 0, 1, 2, 1, 63, },
+ { 1, 0, 1, 2, 2, 63, },
+ { 3, 0, 1, 2, 2, 63, },
+ { 4, 0, 1, 2, 2, 63, },
+ { 5, 0, 1, 2, 2, 63, },
+ { 6, 0, 1, 2, 2, 63, },
+ { 7, 0, 1, 2, 2, 63, },
+ { 1, 0, 1, 2, 3, 30, },
+ { 3, 0, 1, 2, 3, 26, },
+ { 4, 0, 1, 2, 3, 30, },
+ { 5, 0, 1, 2, 3, 30, },
+ { 6, 0, 1, 2, 3, 26, },
+ { 7, 0, 1, 2, 3, 30, },
+ { 1, 0, 1, 2, 4, 30, },
+ { 3, 0, 1, 2, 4, 26, },
+ { 4, 0, 1, 2, 4, 30, },
+ { 5, 0, 1, 2, 4, 30, },
+ { 6, 0, 1, 2, 4, 26, },
+ { 7, 0, 1, 2, 4, 30, },
+ { 1, 0, 1, 2, 5, 30, },
+ { 3, 0, 1, 2, 5, 30, },
+ { 4, 0, 1, 2, 5, 30, },
+ { 5, 0, 1, 2, 5, 30, },
+ { 6, 0, 1, 2, 5, 30, },
+ { 7, 0, 1, 2, 5, 30, },
+ { 1, 0, 1, 2, 6, 30, },
+ { 3, 0, 1, 2, 6, 30, },
+ { 4, 0, 1, 2, 6, 30, },
+ { 5, 0, 1, 2, 6, 30, },
+ { 6, 0, 1, 2, 6, 30, },
+ { 7, 0, 1, 2, 6, 30, },
+ { 1, 0, 1, 2, 7, 30, },
+ { 3, 0, 1, 2, 7, 30, },
+ { 4, 0, 1, 2, 7, 30, },
+ { 5, 0, 1, 2, 7, 30, },
+ { 6, 0, 1, 2, 7, 30, },
+ { 7, 0, 1, 2, 7, 30, },
+ { 1, 0, 1, 2, 8, 30, },
+ { 3, 0, 1, 2, 8, 26, },
+ { 4, 0, 1, 2, 8, 30, },
+ { 5, 0, 1, 2, 8, 30, },
+ { 6, 0, 1, 2, 8, 26, },
+ { 7, 0, 1, 2, 8, 30, },
+ { 1, 0, 1, 2, 9, 30, },
+ { 3, 0, 1, 2, 9, 26, },
+ { 4, 0, 1, 2, 9, 30, },
+ { 5, 0, 1, 2, 9, 30, },
+ { 6, 0, 1, 2, 9, 26, },
+ { 7, 0, 1, 2, 9, 30, },
+ { 1, 0, 1, 2, 10, 30, },
+ { 3, 0, 1, 2, 10, 28, },
+ { 4, 0, 1, 2, 10, 30, },
+ { 5, 0, 1, 2, 10, 30, },
+ { 6, 0, 1, 2, 10, 28, },
+ { 7, 0, 1, 2, 10, 30, },
+ { 1, 0, 1, 2, 11, 30, },
+ { 3, 0, 1, 2, 11, 20, },
+ { 4, 0, 1, 2, 11, 30, },
+ { 5, 0, 1, 2, 11, 30, },
+ { 6, 0, 1, 2, 11, 20, },
+ { 7, 0, 1, 2, 11, 30, },
+ { 1, 0, 1, 2, 12, 63, },
+ { 3, 0, 1, 2, 12, 63, },
+ { 4, 0, 1, 2, 12, 63, },
+ { 5, 0, 1, 2, 12, 63, },
+ { 6, 0, 1, 2, 12, 63, },
+ { 7, 0, 1, 2, 12, 63, },
+ { 1, 0, 1, 2, 13, 63, },
+ { 3, 0, 1, 2, 13, 63, },
+ { 4, 0, 1, 2, 13, 63, },
+ { 5, 0, 1, 2, 13, 63, },
+ { 6, 0, 1, 2, 13, 63, },
+ { 7, 0, 1, 2, 13, 63, },
+ { 1, 0, 1, 2, 14, 63, },
+ { 3, 0, 1, 2, 14, 63, },
+ { 4, 0, 1, 2, 14, 63, },
+ { 5, 0, 1, 2, 14, 63, },
+ { 6, 0, 1, 2, 14, 63, },
+ { 7, 0, 1, 2, 14, 63, },
+ { 1, 1, 0, 1, 36, 33, },
+ { 3, 1, 0, 1, 36, 31, },
+ { 4, 1, 0, 1, 36, 29, },
+ { 5, 1, 0, 1, 36, 32, },
+ { 6, 1, 0, 1, 36, 29, },
+ { 7, 1, 0, 1, 36, 27, },
+ { 1, 1, 0, 1, 40, 33, },
+ { 3, 1, 0, 1, 40, 31, },
+ { 4, 1, 0, 1, 40, 28, },
+ { 5, 1, 0, 1, 40, 32, },
+ { 6, 1, 0, 1, 40, 29, },
+ { 7, 1, 0, 1, 40, 27, },
+ { 1, 1, 0, 1, 44, 33, },
+ { 3, 1, 0, 1, 44, 31, },
+ { 4, 1, 0, 1, 44, 28, },
+ { 5, 1, 0, 1, 44, 32, },
+ { 6, 1, 0, 1, 44, 30, },
+ { 7, 1, 0, 1, 44, 27, },
+ { 1, 1, 0, 1, 48, 33, },
+ { 3, 1, 0, 1, 48, 31, },
+ { 4, 1, 0, 1, 48, 27, },
+ { 5, 1, 0, 1, 48, 32, },
+ { 6, 1, 0, 1, 48, 30, },
+ { 7, 1, 0, 1, 48, 27, },
+ { 1, 1, 0, 1, 52, 33, },
+ { 3, 1, 0, 1, 52, 32, },
+ { 4, 1, 0, 1, 52, 16, },
+ { 5, 1, 0, 1, 52, 32, },
+ { 6, 1, 0, 1, 52, 30, },
+ { 7, 1, 0, 1, 52, 27, },
+ { 1, 1, 0, 1, 56, 33, },
+ { 3, 1, 0, 1, 56, 32, },
+ { 4, 1, 0, 1, 56, 33, },
+ { 5, 1, 0, 1, 56, 32, },
+ { 6, 1, 0, 1, 56, 30, },
+ { 7, 1, 0, 1, 56, 27, },
+ { 1, 1, 0, 1, 60, 33, },
+ { 3, 1, 0, 1, 60, 32, },
+ { 4, 1, 0, 1, 60, 33, },
+ { 5, 1, 0, 1, 60, 32, },
+ { 6, 1, 0, 1, 60, 30, },
+ { 7, 1, 0, 1, 60, 27, },
+ { 1, 1, 0, 1, 64, 33, },
+ { 3, 1, 0, 1, 64, 30, },
+ { 4, 1, 0, 1, 64, 33, },
+ { 5, 1, 0, 1, 64, 32, },
+ { 6, 1, 0, 1, 64, 29, },
+ { 7, 1, 0, 1, 64, 27, },
+ { 1, 1, 0, 1, 100, 33, },
+ { 3, 1, 0, 1, 100, 30, },
+ { 4, 1, 0, 1, 100, 33, },
+ { 5, 1, 0, 1, 100, 32, },
+ { 6, 1, 0, 1, 100, 30, },
+ { 7, 1, 0, 1, 100, 27, },
+ { 1, 1, 0, 1, 104, 33, },
+ { 3, 1, 0, 1, 104, 33, },
+ { 4, 1, 0, 1, 104, 33, },
+ { 5, 1, 0, 1, 104, 32, },
+ { 6, 1, 0, 1, 104, 30, },
+ { 7, 1, 0, 1, 104, 27, },
+ { 1, 1, 0, 1, 108, 33, },
+ { 3, 1, 0, 1, 108, 33, },
+ { 4, 1, 0, 1, 108, 33, },
+ { 5, 1, 0, 1, 108, 32, },
+ { 6, 1, 0, 1, 108, 30, },
+ { 7, 1, 0, 1, 108, 27, },
+ { 1, 1, 0, 1, 112, 33, },
+ { 3, 1, 0, 1, 112, 33, },
+ { 4, 1, 0, 1, 112, 33, },
+ { 5, 1, 0, 1, 112, 32, },
+ { 6, 1, 0, 1, 112, 30, },
+ { 7, 1, 0, 1, 112, 27, },
+ { 1, 1, 0, 1, 116, 33, },
+ { 3, 1, 0, 1, 116, 33, },
+ { 4, 1, 0, 1, 116, 33, },
+ { 5, 1, 0, 1, 116, 32, },
+ { 6, 1, 0, 1, 116, 30, },
+ { 7, 1, 0, 1, 116, 27, },
+ { 1, 1, 0, 1, 120, 33, },
+ { 3, 1, 0, 1, 120, 63, },
+ { 4, 1, 0, 1, 120, 33, },
+ { 5, 1, 0, 1, 120, 63, },
+ { 6, 1, 0, 1, 120, 30, },
+ { 7, 1, 0, 1, 120, 27, },
+ { 1, 1, 0, 1, 124, 33, },
+ { 3, 1, 0, 1, 124, 63, },
+ { 4, 1, 0, 1, 124, 33, },
+ { 5, 1, 0, 1, 124, 63, },
+ { 6, 1, 0, 1, 124, 30, },
+ { 7, 1, 0, 1, 124, 27, },
+ { 1, 1, 0, 1, 128, 33, },
+ { 3, 1, 0, 1, 128, 63, },
+ { 4, 1, 0, 1, 128, 63, },
+ { 5, 1, 0, 1, 128, 63, },
+ { 6, 1, 0, 1, 128, 30, },
+ { 7, 1, 0, 1, 128, 27, },
+ { 1, 1, 0, 1, 132, 33, },
+ { 3, 1, 0, 1, 132, 33, },
+ { 4, 1, 0, 1, 132, 63, },
+ { 5, 1, 0, 1, 132, 32, },
+ { 6, 1, 0, 1, 132, 30, },
+ { 7, 1, 0, 1, 132, 27, },
+ { 1, 1, 0, 1, 136, 33, },
+ { 3, 1, 0, 1, 136, 33, },
+ { 4, 1, 0, 1, 136, 63, },
+ { 5, 1, 0, 1, 136, 32, },
+ { 6, 1, 0, 1, 136, 30, },
+ { 7, 1, 0, 1, 136, 63, },
+ { 1, 1, 0, 1, 140, 33, },
+ { 3, 1, 0, 1, 140, 31, },
+ { 4, 1, 0, 1, 140, 63, },
+ { 5, 1, 0, 1, 140, 32, },
+ { 6, 1, 0, 1, 140, 30, },
+ { 7, 1, 0, 1, 140, 63, },
+ { 1, 1, 0, 1, 144, 63, },
+ { 3, 1, 0, 1, 144, 30, },
+ { 4, 1, 0, 1, 144, 63, },
+ { 5, 1, 0, 1, 144, 63, },
+ { 6, 1, 0, 1, 144, 30, },
+ { 7, 1, 0, 1, 144, 63, },
+ { 1, 1, 0, 1, 149, 63, },
+ { 3, 1, 0, 1, 149, 30, },
+ { 4, 1, 0, 1, 149, 33, },
+ { 5, 1, 0, 1, 149, 33, },
+ { 6, 1, 0, 1, 149, 30, },
+ { 7, 1, 0, 1, 149, 27, },
+ { 1, 1, 0, 1, 153, 63, },
+ { 3, 1, 0, 1, 153, 33, },
+ { 4, 1, 0, 1, 153, 33, },
+ { 5, 1, 0, 1, 153, 33, },
+ { 6, 1, 0, 1, 153, 30, },
+ { 7, 1, 0, 1, 153, 27, },
+ { 1, 1, 0, 1, 157, 63, },
+ { 3, 1, 0, 1, 157, 33, },
+ { 4, 1, 0, 1, 157, 33, },
+ { 5, 1, 0, 1, 157, 33, },
+ { 6, 1, 0, 1, 157, 30, },
+ { 7, 1, 0, 1, 157, 27, },
+ { 1, 1, 0, 1, 161, 63, },
+ { 3, 1, 0, 1, 161, 33, },
+ { 4, 1, 0, 1, 161, 31, },
+ { 5, 1, 0, 1, 161, 33, },
+ { 6, 1, 0, 1, 161, 30, },
+ { 7, 1, 0, 1, 161, 27, },
+ { 1, 1, 0, 1, 165, 63, },
+ { 3, 1, 0, 1, 165, 33, },
+ { 4, 1, 0, 1, 165, 63, },
+ { 5, 1, 0, 1, 165, 33, },
+ { 6, 1, 0, 1, 165, 30, },
+ { 7, 1, 0, 1, 165, 27, },
+ { 1, 1, 0, 2, 36, 33, },
+ { 3, 1, 0, 2, 36, 30, },
+ { 4, 1, 0, 2, 36, 27, },
+ { 5, 1, 0, 2, 36, 32, },
+ { 6, 1, 0, 2, 36, 30, },
+ { 7, 1, 0, 2, 36, 27, },
+ { 1, 1, 0, 2, 40, 33, },
+ { 3, 1, 0, 2, 40, 31, },
+ { 4, 1, 0, 2, 40, 29, },
+ { 5, 1, 0, 2, 40, 32, },
+ { 6, 1, 0, 2, 40, 30, },
+ { 7, 1, 0, 2, 40, 27, },
+ { 1, 1, 0, 2, 44, 33, },
+ { 3, 1, 0, 2, 44, 31, },
+ { 4, 1, 0, 2, 44, 29, },
+ { 5, 1, 0, 2, 44, 32, },
+ { 6, 1, 0, 2, 44, 30, },
+ { 7, 1, 0, 2, 44, 27, },
+ { 1, 1, 0, 2, 48, 33, },
+ { 3, 1, 0, 2, 48, 31, },
+ { 4, 1, 0, 2, 48, 26, },
+ { 5, 1, 0, 2, 48, 32, },
+ { 6, 1, 0, 2, 48, 30, },
+ { 7, 1, 0, 2, 48, 27, },
+ { 1, 1, 0, 2, 52, 33, },
+ { 3, 1, 0, 2, 52, 32, },
+ { 4, 1, 0, 2, 52, 7, },
+ { 5, 1, 0, 2, 52, 32, },
+ { 6, 1, 0, 2, 52, 30, },
+ { 7, 1, 0, 2, 52, 27, },
+ { 1, 1, 0, 2, 56, 33, },
+ { 3, 1, 0, 2, 56, 32, },
+ { 4, 1, 0, 2, 56, 33, },
+ { 5, 1, 0, 2, 56, 32, },
+ { 6, 1, 0, 2, 56, 30, },
+ { 7, 1, 0, 2, 56, 27, },
+ { 1, 1, 0, 2, 60, 33, },
+ { 3, 1, 0, 2, 60, 32, },
+ { 4, 1, 0, 2, 60, 33, },
+ { 5, 1, 0, 2, 60, 32, },
+ { 6, 1, 0, 2, 60, 30, },
+ { 7, 1, 0, 2, 60, 27, },
+ { 1, 1, 0, 2, 64, 33, },
+ { 3, 1, 0, 2, 64, 30, },
+ { 4, 1, 0, 2, 64, 33, },
+ { 5, 1, 0, 2, 64, 32, },
+ { 6, 1, 0, 2, 64, 30, },
+ { 7, 1, 0, 2, 64, 27, },
+ { 1, 1, 0, 2, 100, 33, },
+ { 3, 1, 0, 2, 100, 30, },
+ { 4, 1, 0, 2, 100, 33, },
+ { 5, 1, 0, 2, 100, 32, },
+ { 6, 1, 0, 2, 100, 30, },
+ { 7, 1, 0, 2, 100, 27, },
+ { 1, 1, 0, 2, 104, 33, },
+ { 3, 1, 0, 2, 104, 33, },
+ { 4, 1, 0, 2, 104, 33, },
+ { 5, 1, 0, 2, 104, 32, },
+ { 6, 1, 0, 2, 104, 30, },
+ { 7, 1, 0, 2, 104, 27, },
+ { 1, 1, 0, 2, 108, 33, },
+ { 3, 1, 0, 2, 108, 33, },
+ { 4, 1, 0, 2, 108, 33, },
+ { 5, 1, 0, 2, 108, 32, },
+ { 6, 1, 0, 2, 108, 30, },
+ { 7, 1, 0, 2, 108, 27, },
+ { 1, 1, 0, 2, 112, 33, },
+ { 3, 1, 0, 2, 112, 33, },
+ { 4, 1, 0, 2, 112, 33, },
+ { 5, 1, 0, 2, 112, 32, },
+ { 6, 1, 0, 2, 112, 30, },
+ { 7, 1, 0, 2, 112, 27, },
+ { 1, 1, 0, 2, 116, 33, },
+ { 3, 1, 0, 2, 116, 33, },
+ { 4, 1, 0, 2, 116, 33, },
+ { 5, 1, 0, 2, 116, 32, },
+ { 6, 1, 0, 2, 116, 30, },
+ { 7, 1, 0, 2, 116, 27, },
+ { 1, 1, 0, 2, 120, 33, },
+ { 3, 1, 0, 2, 120, 63, },
+ { 4, 1, 0, 2, 120, 33, },
+ { 5, 1, 0, 2, 120, 63, },
+ { 6, 1, 0, 2, 120, 30, },
+ { 7, 1, 0, 2, 120, 27, },
+ { 1, 1, 0, 2, 124, 33, },
+ { 3, 1, 0, 2, 124, 63, },
+ { 4, 1, 0, 2, 124, 33, },
+ { 5, 1, 0, 2, 124, 63, },
+ { 6, 1, 0, 2, 124, 30, },
+ { 7, 1, 0, 2, 124, 27, },
+ { 1, 1, 0, 2, 128, 33, },
+ { 3, 1, 0, 2, 128, 63, },
+ { 4, 1, 0, 2, 128, 63, },
+ { 5, 1, 0, 2, 128, 63, },
+ { 6, 1, 0, 2, 128, 30, },
+ { 7, 1, 0, 2, 128, 27, },
+ { 1, 1, 0, 2, 132, 33, },
+ { 3, 1, 0, 2, 132, 33, },
+ { 4, 1, 0, 2, 132, 63, },
+ { 5, 1, 0, 2, 132, 32, },
+ { 6, 1, 0, 2, 132, 30, },
+ { 7, 1, 0, 2, 132, 27, },
+ { 1, 1, 0, 2, 136, 33, },
+ { 3, 1, 0, 2, 136, 33, },
+ { 4, 1, 0, 2, 136, 63, },
+ { 5, 1, 0, 2, 136, 32, },
+ { 6, 1, 0, 2, 136, 30, },
+ { 7, 1, 0, 2, 136, 63, },
+ { 1, 1, 0, 2, 140, 33, },
+ { 3, 1, 0, 2, 140, 29, },
+ { 4, 1, 0, 2, 140, 63, },
+ { 5, 1, 0, 2, 140, 32, },
+ { 6, 1, 0, 2, 140, 30, },
+ { 7, 1, 0, 2, 140, 63, },
+ { 1, 1, 0, 2, 144, 63, },
+ { 3, 1, 0, 2, 144, 27, },
+ { 4, 1, 0, 2, 144, 63, },
+ { 5, 1, 0, 2, 144, 63, },
+ { 6, 1, 0, 2, 144, 30, },
+ { 7, 1, 0, 2, 144, 63, },
+ { 1, 1, 0, 2, 149, 63, },
+ { 3, 1, 0, 2, 149, 33, },
+ { 4, 1, 0, 2, 149, 33, },
+ { 5, 1, 0, 2, 149, 33, },
+ { 6, 1, 0, 2, 149, 30, },
+ { 7, 1, 0, 2, 149, 27, },
+ { 1, 1, 0, 2, 153, 63, },
+ { 3, 1, 0, 2, 153, 33, },
+ { 4, 1, 0, 2, 153, 33, },
+ { 5, 1, 0, 2, 153, 33, },
+ { 6, 1, 0, 2, 153, 30, },
+ { 7, 1, 0, 2, 153, 27, },
+ { 1, 1, 0, 2, 157, 63, },
+ { 3, 1, 0, 2, 157, 33, },
+ { 4, 1, 0, 2, 157, 33, },
+ { 5, 1, 0, 2, 157, 33, },
+ { 6, 1, 0, 2, 157, 30, },
+ { 7, 1, 0, 2, 157, 27, },
+ { 1, 1, 0, 2, 161, 63, },
+ { 3, 1, 0, 2, 161, 33, },
+ { 4, 1, 0, 2, 161, 31, },
+ { 5, 1, 0, 2, 161, 33, },
+ { 6, 1, 0, 2, 161, 30, },
+ { 7, 1, 0, 2, 161, 27, },
+ { 1, 1, 0, 2, 165, 63, },
+ { 3, 1, 0, 2, 165, 33, },
+ { 4, 1, 0, 2, 165, 63, },
+ { 5, 1, 0, 2, 165, 33, },
+ { 6, 1, 0, 2, 165, 30, },
+ { 7, 1, 0, 2, 165, 27, },
+ { 1, 1, 1, 2, 38, 32, },
+ { 3, 1, 1, 2, 38, 22, },
+ { 4, 1, 1, 2, 38, 26, },
+ { 5, 1, 1, 2, 38, 32, },
+ { 6, 1, 1, 2, 38, 22, },
+ { 7, 1, 1, 2, 38, 27, },
+ { 1, 1, 1, 2, 46, 32, },
+ { 3, 1, 1, 2, 46, 32, },
+ { 4, 1, 1, 2, 46, 28, },
+ { 5, 1, 1, 2, 46, 32, },
+ { 6, 1, 1, 2, 46, 30, },
+ { 7, 1, 1, 2, 46, 27, },
+ { 1, 1, 1, 2, 54, 32, },
+ { 3, 1, 1, 2, 54, 32, },
+ { 4, 1, 1, 2, 54, 22, },
+ { 5, 1, 1, 2, 54, 32, },
+ { 6, 1, 1, 2, 54, 30, },
+ { 7, 1, 1, 2, 54, 27, },
+ { 1, 1, 1, 2, 62, 32, },
+ { 3, 1, 1, 2, 62, 23, },
+ { 4, 1, 1, 2, 62, 31, },
+ { 5, 1, 1, 2, 62, 32, },
+ { 6, 1, 1, 2, 62, 23, },
+ { 7, 1, 1, 2, 62, 27, },
+ { 1, 1, 1, 2, 102, 32, },
+ { 3, 1, 1, 2, 102, 21, },
+ { 4, 1, 1, 2, 102, 31, },
+ { 5, 1, 1, 2, 102, 32, },
+ { 6, 1, 1, 2, 102, 30, },
+ { 7, 1, 1, 2, 102, 27, },
+ { 1, 1, 1, 2, 110, 32, },
+ { 3, 1, 1, 2, 110, 32, },
+ { 4, 1, 1, 2, 110, 32, },
+ { 5, 1, 1, 2, 110, 32, },
+ { 6, 1, 1, 2, 110, 30, },
+ { 7, 1, 1, 2, 110, 27, },
+ { 1, 1, 1, 2, 118, 32, },
+ { 3, 1, 1, 2, 118, 63, },
+ { 4, 1, 1, 2, 118, 32, },
+ { 5, 1, 1, 2, 118, 63, },
+ { 6, 1, 1, 2, 118, 30, },
+ { 7, 1, 1, 2, 118, 27, },
+ { 1, 1, 1, 2, 126, 32, },
+ { 3, 1, 1, 2, 126, 63, },
+ { 4, 1, 1, 2, 126, 63, },
+ { 5, 1, 1, 2, 126, 63, },
+ { 6, 1, 1, 2, 126, 30, },
+ { 7, 1, 1, 2, 126, 27, },
+ { 1, 1, 1, 2, 134, 32, },
+ { 3, 1, 1, 2, 134, 32, },
+ { 4, 1, 1, 2, 134, 63, },
+ { 5, 1, 1, 2, 134, 32, },
+ { 6, 1, 1, 2, 134, 30, },
+ { 7, 1, 1, 2, 134, 63, },
+ { 1, 1, 1, 2, 142, 63, },
+ { 3, 1, 1, 2, 142, 29, },
+ { 4, 1, 1, 2, 142, 63, },
+ { 5, 1, 1, 2, 142, 63, },
+ { 6, 1, 1, 2, 142, 30, },
+ { 7, 1, 1, 2, 142, 63, },
+ { 1, 1, 1, 2, 151, 63, },
+ { 3, 1, 1, 2, 151, 32, },
+ { 4, 1, 1, 2, 151, 27, },
+ { 5, 1, 1, 2, 151, 32, },
+ { 6, 1, 1, 2, 151, 30, },
+ { 7, 1, 1, 2, 151, 27, },
+ { 1, 1, 1, 2, 159, 63, },
+ { 3, 1, 1, 2, 159, 32, },
+ { 4, 1, 1, 2, 159, 26, },
+ { 5, 1, 1, 2, 159, 32, },
+ { 6, 1, 1, 2, 159, 30, },
+ { 7, 1, 1, 2, 159, 27, },
+ { 1, 1, 2, 4, 42, 28, },
+ { 3, 1, 2, 4, 42, 19, },
+ { 4, 1, 2, 4, 42, 25, },
+ { 5, 1, 2, 4, 42, 32, },
+ { 6, 1, 2, 4, 42, 19, },
+ { 7, 1, 2, 4, 42, 27, },
+ { 1, 1, 2, 4, 58, 28, },
+ { 3, 1, 2, 4, 58, 22, },
+ { 4, 1, 2, 4, 58, 28, },
+ { 5, 1, 2, 4, 58, 32, },
+ { 6, 1, 2, 4, 58, 22, },
+ { 7, 1, 2, 4, 58, 27, },
+ { 1, 1, 2, 4, 106, 32, },
+ { 3, 1, 2, 4, 106, 18, },
+ { 4, 1, 2, 4, 106, 30, },
+ { 5, 1, 2, 4, 106, 32, },
+ { 6, 1, 2, 4, 106, 30, },
+ { 7, 1, 2, 4, 106, 27, },
+ { 1, 1, 2, 4, 122, 32, },
+ { 3, 1, 2, 4, 122, 63, },
+ { 4, 1, 2, 4, 122, 26, },
+ { 5, 1, 2, 4, 122, 63, },
+ { 6, 1, 2, 4, 122, 30, },
+ { 7, 1, 2, 4, 122, 27, },
+ { 1, 1, 2, 4, 138, 63, },
+ { 3, 1, 2, 4, 138, 28, },
+ { 4, 1, 2, 4, 138, 63, },
+ { 5, 1, 2, 4, 138, 63, },
+ { 6, 1, 2, 4, 138, 30, },
+ { 7, 1, 2, 4, 138, 63, },
+ { 1, 1, 2, 4, 155, 63, },
+ { 3, 1, 2, 4, 155, 32, },
+ { 4, 1, 2, 4, 155, 27, },
+ { 5, 1, 2, 4, 155, 32, },
+ { 6, 1, 2, 4, 155, 30, },
+ { 7, 1, 2, 4, 155, 27, },
+};
+
+RTW_DECL_TABLE_TXPWR_LMT(rtw8821c_txpwr_lmt_type0);
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c_table.h b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.h
new file mode 100644
index 000000000000..5ea8b4fc7fba
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c_table.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#ifndef __RTW8821C_TABLE_H__
+#define __RTW8821C_TABLE_H__
+
+extern const struct rtw_table rtw8821c_mac_tbl;
+extern const struct rtw_table rtw8821c_agc_tbl;
+extern const struct rtw_table rtw8821c_bb_tbl;
+extern const struct rtw_table rtw8821c_bb_pg_type0_tbl;
+extern const struct rtw_table rtw8821c_rf_a_tbl;
+extern const struct rtw_table rtw8821c_txpwr_lmt_type0_tbl;
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821ce.c b/drivers/net/wireless/realtek/rtw88/rtw8821ce.c
new file mode 100644
index 000000000000..616fdcfd62c9
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821ce.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include "rtw8821ce.h"
+
+static const struct pci_device_id rtw_8821ce_id_table[] = {
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC821),
+ .driver_data = (kernel_ulong_t)&rtw8821c_hw_spec
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(pci, rtw_8821ce_id_table);
+
+static struct pci_driver rtw_8821ce_driver = {
+ .name = "rtw_8821ce",
+ .id_table = rtw_8821ce_id_table,
+ .probe = rtw_pci_probe,
+ .remove = rtw_pci_remove,
+ .driver.pm = &rtw_pm_ops,
+ .shutdown = rtw_pci_shutdown,
+};
+module_pci_driver(rtw_8821ce_driver);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821ce driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821ce.h b/drivers/net/wireless/realtek/rtw88/rtw8821ce.h
new file mode 100644
index 000000000000..8d3eb77a876b
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821ce.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2018-2019 Realtek Corporation
+ */
+
+#ifndef __RTW_8821CE_H_
+#define __RTW_8821CE_H_
+
+extern const struct dev_pm_ops rtw_pm_ops;
+extern struct rtw_chip_info rtw8821c_hw_spec;
+int rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
+void rtw_pci_remove(struct pci_dev *pdev);
+void rtw_pci_shutdown(struct pci_dev *pdev);
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index e49bdd76ab9a..351cd055a295 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -2147,7 +2147,7 @@ static const struct coex_table_para table_sant_8822b[] = {
{0x66555555, 0x5a5a5a5a},
{0x66555555, 0x6a5a5a5a}, /* case-10 */
{0x66555555, 0xfafafafa},
- {0x66555555, 0x6a5a5aaa},
+ {0x66555555, 0x5a5a5aaa},
{0x66555555, 0x5aaa5aaa},
{0x66555555, 0xaaaa5aaa},
{0x66555555, 0xaaaaaaaa}, /* case-15 */
@@ -2223,7 +2223,8 @@ static const struct coex_tdma_para tdma_sant_8822b[] = {
{ {0x55, 0x08, 0x03, 0x10, 0x54} },
{ {0x65, 0x10, 0x03, 0x11, 0x11} },
{ {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
- { {0x51, 0x08, 0x03, 0x10, 0x50} }
+ { {0x51, 0x08, 0x03, 0x10, 0x50} },
+ { {0x61, 0x08, 0x03, 0x11, 0x11} }
};
/* Non-Shared-Antenna TDMA */
@@ -2475,7 +2476,7 @@ struct rtw_chip_info rtw8822b_hw_spec = {
.bfer_mu_max_num = 1,
.rx_ldpc = true,
- .coex_para_ver = 0x19062706,
+ .coex_para_ver = 0x20070206,
.bt_desired_ver = 0x6,
.scbd_support = true,
.new_scbd10_def = false,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index c3d72ef611c6..426808413baa 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -3899,6 +3899,7 @@ static const struct rtw_rfe_def rtw8822c_rfe_defs[] = {
[1] = RTW_DEF_RFE(8822c, 0, 0),
[2] = RTW_DEF_RFE(8822c, 0, 0),
[5] = RTW_DEF_RFE(8822c, 0, 5),
+ [6] = RTW_DEF_RFE(8822c, 0, 0),
};
static const struct rtw_hw_reg rtw8822c_dig[] = {
@@ -3997,7 +3998,7 @@ static const struct coex_table_para table_sant_8822c[] = {
{0x66555555, 0x5a5a5a5a},
{0x66555555, 0x6a5a5a5a}, /* case-10 */
{0x66555555, 0xfafafafa},
- {0x66555555, 0x6a5a5aaa},
+ {0x66555555, 0x5a5a5aaa},
{0x66555555, 0x5aaa5aaa},
{0x66555555, 0xaaaa5aaa},
{0x66555555, 0xaaaaaaaa}, /* case-15 */
@@ -4073,7 +4074,8 @@ static const struct coex_tdma_para tdma_sant_8822c[] = {
{ {0x55, 0x08, 0x03, 0x10, 0x54} },
{ {0x65, 0x10, 0x03, 0x11, 0x11} },
{ {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */
- { {0x51, 0x08, 0x03, 0x10, 0x50} }
+ { {0x51, 0x08, 0x03, 0x10, 0x50} },
+ { {0x61, 0x08, 0x03, 0x11, 0x11} }
};
/* Non-Shared-Antenna TDMA */
@@ -4343,8 +4345,8 @@ struct rtw_chip_info rtw8822c_hw_spec = {
.wowlan_stub = &rtw_wowlan_stub_8822c,
.max_sched_scan_ssids = 4,
#endif
- .coex_para_ver = 0x19062706,
- .bt_desired_ver = 0x6,
+ .coex_para_ver = 0x20070217,
+ .bt_desired_ver = 0x17,
.scbd_support = true,
.new_scbd10_def = true,
.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822ce.c b/drivers/net/wireless/realtek/rtw88/rtw8822ce.c
index 7b6bd990651e..026ac49ce6e3 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822ce.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822ce.c
@@ -11,6 +11,10 @@ static const struct pci_device_id rtw_8822ce_id_table[] = {
PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC822),
.driver_data = (kernel_ulong_t)&rtw8822c_hw_spec
},
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC82F),
+ .driver_data = (kernel_ulong_t)&rtw8822c_hw_spec
+ },
{}
};
MODULE_DEVICE_TABLE(pci, rtw_8822ce_id_table);
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 79c42118825f..7fcc992b01a8 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -61,6 +61,8 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
SET_TX_DESC_DISQSELSEQ(txdesc, pkt_info->dis_qselseq);
SET_TX_DESC_EN_HWSEQ(txdesc, pkt_info->en_hwseq);
SET_TX_DESC_HW_SSN_SEL(txdesc, pkt_info->hw_ssn_sel);
+ SET_TX_DESC_NAVUSEHDR(txdesc, pkt_info->nav_use_hdr);
+ SET_TX_DESC_BT_NULL(txdesc, pkt_info->bt_null);
}
EXPORT_SYMBOL(rtw_tx_fill_tx_desc);
@@ -227,17 +229,58 @@ void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src)
spin_unlock_irqrestore(&tx_report->q_lock, flags);
}
-static void rtw_tx_mgmt_pkt_info_update(struct rtw_dev *rtwdev,
+static void rtw_tx_pkt_info_update_rate(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
- struct ieee80211_sta *sta,
struct sk_buff *skb)
{
+ if (rtwdev->hal.current_band_type == RTW_BAND_2G) {
+ pkt_info->rate_id = RTW_RATEID_B_20M;
+ pkt_info->rate = DESC_RATE1M;
+ } else {
+ pkt_info->rate_id = RTW_RATEID_G;
+ pkt_info->rate = DESC_RATE6M;
+ }
pkt_info->use_rate = true;
- pkt_info->rate_id = 6;
pkt_info->dis_rate_fallback = true;
+}
+
+static void rtw_tx_pkt_info_update_sec(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ u8 sec_type = 0;
+
+ if (info && info->control.hw_key) {
+ struct ieee80211_key_conf *key = info->control.hw_key;
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
+ sec_type = 0x01;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ sec_type = 0x03;
+ break;
+ default:
+ break;
+ }
+ }
+
+ pkt_info->sec_type = sec_type;
+}
+
+static void rtw_tx_mgmt_pkt_info_update(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb)
+{
+ rtw_tx_pkt_info_update_rate(rtwdev, pkt_info, skb);
pkt_info->dis_qselseq = true;
pkt_info->en_hwseq = true;
pkt_info->hw_ssn_sel = 0;
+ /* TODO: need to change hw port and hw ssn sel for multiple vifs */
}
static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev,
@@ -312,7 +355,6 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
struct rtw_sta_info *si;
struct ieee80211_vif *vif = NULL;
__le16 fc = hdr->frame_control;
- u8 sec_type = 0;
bool bmc;
if (sta) {
@@ -325,23 +367,6 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
else if (ieee80211_is_data(fc))
rtw_tx_data_pkt_info_update(rtwdev, pkt_info, sta, skb);
- if (info->control.hw_key) {
- struct ieee80211_key_conf *key = info->control.hw_key;
-
- switch (key->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- case WLAN_CIPHER_SUITE_TKIP:
- sec_type = 0x01;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- sec_type = 0x03;
- break;
- default:
- break;
- }
- }
-
bmc = is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1);
@@ -349,7 +374,7 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
rtw_tx_report_enable(rtwdev, pkt_info);
pkt_info->bmc = bmc;
- pkt_info->sec_type = sec_type;
+ rtw_tx_pkt_info_update_sec(rtwdev, pkt_info, skb);
pkt_info->tx_pkt_size = skb->len;
pkt_info->offset = chip->tx_pkt_desc_sz;
pkt_info->qsel = skb->priority;
@@ -359,24 +384,42 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
rtw_tx_stats(rtwdev, vif, skb);
}
-void rtw_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
- struct rtw_tx_pkt_info *pkt_info,
- struct sk_buff *skb)
+void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ struct sk_buff *skb,
+ enum rtw_rsvd_packet_type type)
{
struct rtw_chip_info *chip = rtwdev->chip;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
bool bmc;
+ /* A beacon or dummy reserved page packet indicates that it is the first
+ * reserved page, and the qsel of it will be set in each hci.
+ */
+ if (type != RSVD_BEACON && type != RSVD_DUMMY)
+ pkt_info->qsel = TX_DESC_QSEL_MGMT;
+
+ rtw_tx_pkt_info_update_rate(rtwdev, pkt_info, skb);
+
bmc = is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1);
- pkt_info->use_rate = true;
- pkt_info->rate_id = 6;
- pkt_info->dis_rate_fallback = true;
pkt_info->bmc = bmc;
pkt_info->tx_pkt_size = skb->len;
pkt_info->offset = chip->tx_pkt_desc_sz;
- pkt_info->qsel = TX_DESC_QSEL_MGMT;
pkt_info->ls = true;
+ if (type == RSVD_PS_POLL) {
+ pkt_info->nav_use_hdr = true;
+ } else {
+ pkt_info->dis_qselseq = true;
+ pkt_info->en_hwseq = true;
+ pkt_info->hw_ssn_sel = 0;
+ }
+ if (type == RSVD_QOS_NULL)
+ pkt_info->bt_null = true;
+
+ rtw_tx_pkt_info_update_sec(rtwdev, pkt_info, skb);
+
+ /* TODO: need to change hw port and hw ssn sel for multiple vifs */
}
struct sk_buff *
@@ -399,8 +442,7 @@ rtw_tx_write_data_rsvd_page_get(struct rtw_dev *rtwdev,
skb_reserve(skb, tx_pkt_desc_sz);
skb_put_data(skb, buf, size);
- pkt_info->tx_pkt_size = size;
- pkt_info->offset = tx_pkt_desc_sz;
+ rtw_tx_rsvd_page_pkt_info_update(rtwdev, pkt_info, skb, RSVD_BEACON);
return skb;
}
diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h
index 72dfd4059f03..cfe84eef5923 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -59,6 +59,10 @@
le32p_replace_bits((__le32 *)(txdesc) + 0x08, value, BIT(15))
#define SET_TX_DESC_HW_SSN_SEL(txdesc, value) \
le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(7, 6))
+#define SET_TX_DESC_NAVUSEHDR(txdesc, value) \
+ le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15))
+#define SET_TX_DESC_BT_NULL(txdesc, value) \
+ le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23))
enum rtw_tx_desc_queue_select {
TX_DESC_QSEL_TID0 = 0,
@@ -83,6 +87,8 @@ enum rtw_tx_desc_queue_select {
TX_DESC_QSEL_H2C = 19,
};
+enum rtw_rsvd_packet_type;
+
void rtw_tx(struct rtw_dev *rtwdev,
struct ieee80211_tx_control *control,
struct sk_buff *skb);
@@ -96,9 +102,10 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
-void rtw_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
- struct rtw_tx_pkt_info *pkt_info,
- struct sk_buff *skb);
+void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
+ struct rtw_tx_pkt_info *pkt_info,
+ struct sk_buff *skb,
+ enum rtw_rsvd_packet_type type);
struct sk_buff *
rtw_tx_write_data_rsvd_page_get(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c
index 850864dbafa1..e6d426edab56 100644
--- a/drivers/net/wireless/ti/wl1251/event.c
+++ b/drivers/net/wireless/ti/wl1251/event.c
@@ -70,7 +70,7 @@ static int wl1251_event_ps_report(struct wl1251 *wl,
break;
}
- return 0;
+ return ret;
}
static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index de6c8a7589ca..821ad1acd505 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -521,6 +521,7 @@ static int wlcore_irq_locked(struct wl1271 *wl)
int ret = 0;
u32 intr;
int loopcount = WL1271_IRQ_MAX_LOOPS;
+ bool run_tx_queue = true;
bool done = false;
unsigned int defer_count;
unsigned long flags;
@@ -586,19 +587,22 @@ static int wlcore_irq_locked(struct wl1271 *wl)
goto err_ret;
/* Check if any tx blocks were freed */
- spin_lock_irqsave(&wl->wl_lock, flags);
- if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
- wl1271_tx_total_queue_count(wl) > 0) {
- spin_unlock_irqrestore(&wl->wl_lock, flags);
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) {
+ if (spin_trylock_irqsave(&wl->wl_lock, flags)) {
+ if (!wl1271_tx_total_queue_count(wl))
+ run_tx_queue = false;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ }
+
/*
* In order to avoid starvation of the TX path,
* call the work function directly.
*/
- ret = wlcore_tx_work_locked(wl);
- if (ret < 0)
- goto err_ret;
- } else {
- spin_unlock_irqrestore(&wl->wl_lock, flags);
+ if (run_tx_queue) {
+ ret = wlcore_tx_work_locked(wl);
+ if (ret < 0)
+ goto err_ret;
+ }
}
/* check for tx results */
@@ -648,25 +652,28 @@ static irqreturn_t wlcore_irq(int irq, void *cookie)
int ret;
unsigned long flags;
struct wl1271 *wl = cookie;
+ bool queue_tx_work = true;
- /* complete the ELP completion */
- spin_lock_irqsave(&wl->wl_lock, flags);
set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
- if (wl->elp_compl) {
- complete(wl->elp_compl);
- wl->elp_compl = NULL;
+
+ /* complete the ELP completion */
+ if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags)) {
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ if (wl->elp_compl)
+ complete(wl->elp_compl);
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
}
if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
/* don't enqueue a work right now. mark it as pending */
set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
wl1271_debug(DEBUG_IRQ, "should not enqueue work");
+ spin_lock_irqsave(&wl->wl_lock, flags);
disable_irq_nosync(wl->irq);
pm_wakeup_event(wl->dev, 0);
spin_unlock_irqrestore(&wl->wl_lock, flags);
goto out_handled;
}
- spin_unlock_irqrestore(&wl->wl_lock, flags);
/* TX might be handled here, avoid redundant work */
set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
@@ -678,20 +685,22 @@ static irqreturn_t wlcore_irq(int irq, void *cookie)
if (ret)
wl12xx_queue_recovery_work(wl);
- spin_lock_irqsave(&wl->wl_lock, flags);
- /* In case TX was not handled here, queue TX work */
+ /* In case TX was not handled in wlcore_irq_locked(), queue TX work */
clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
- if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
- wl1271_tx_total_queue_count(wl) > 0)
- ieee80211_queue_work(wl->hw, &wl->tx_work);
- spin_unlock_irqrestore(&wl->wl_lock, flags);
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) {
+ if (spin_trylock_irqsave(&wl->wl_lock, flags)) {
+ if (!wl1271_tx_total_queue_count(wl))
+ queue_tx_work = false;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ }
+ if (queue_tx_work)
+ ieee80211_queue_work(wl->hw, &wl->tx_work);
+ }
mutex_unlock(&wl->mutex);
out_handled:
- spin_lock_irqsave(&wl->wl_lock, flags);
clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
- spin_unlock_irqrestore(&wl->wl_lock, flags);
return IRQ_HANDLED;
}
@@ -6732,7 +6741,6 @@ static int __maybe_unused wlcore_runtime_resume(struct device *dev)
unsigned long flags;
int ret;
unsigned long start_time = jiffies;
- bool pending = false;
bool recovery = false;
/* Nothing to do if no ELP mode requested */
@@ -6742,49 +6750,35 @@ static int __maybe_unused wlcore_runtime_resume(struct device *dev)
wl1271_debug(DEBUG_PSM, "waking up chip from elp");
spin_lock_irqsave(&wl->wl_lock, flags);
- if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
- pending = true;
- else
- wl->elp_compl = &compl;
+ wl->elp_compl = &compl;
spin_unlock_irqrestore(&wl->wl_lock, flags);
ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
if (ret < 0) {
recovery = true;
- goto err;
- }
-
- if (!pending) {
+ } else if (!test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) {
ret = wait_for_completion_timeout(&compl,
msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
if (ret == 0) {
wl1271_warning("ELP wakeup timeout!");
-
- /* Return no error for runtime PM for recovery */
- ret = 0;
recovery = true;
- goto err;
}
}
- clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
-
- wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
- jiffies_to_msecs(jiffies - start_time));
-
- return 0;
-
-err:
spin_lock_irqsave(&wl->wl_lock, flags);
wl->elp_compl = NULL;
spin_unlock_irqrestore(&wl->wl_lock, flags);
+ clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
if (recovery) {
set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
wl12xx_queue_recovery_work(wl);
+ } else {
+ wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
+ jiffies_to_msecs(jiffies - start_time));
}
- return ret;
+ return 0;
}
static const struct dev_pm_ops wlcore_pm_ops = {
diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c
index 8ff0374126e4..65b5985ad402 100644
--- a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c
@@ -600,9 +600,7 @@ void zd_usb_disable_int(struct zd_usb *usb)
dev_dbg_f(zd_usb_dev(usb), "urb %p killed\n", urb);
usb_free_urb(urb);
- if (buffer)
- usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER,
- buffer, buffer_dma);
+ usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER, buffer, buffer_dma);
}
static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 05847eb91a1b..ae477f7756af 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -281,6 +281,9 @@ struct xenvif {
u8 ipv6_csum:1;
u8 multicast_control:1;
+ /* headroom requested by xen-netfront */
+ u16 xdp_headroom;
+
/* Is this interface disabled? True when backend discovers
* frontend is rogue.
*/
@@ -395,6 +398,7 @@ static inline pending_ring_idx_t nr_pending_reqs(struct xenvif_queue *queue)
irqreturn_t xenvif_interrupt(int irq, void *dev_id);
extern bool separate_tx_rx_irq;
+extern bool provides_xdp_headroom;
extern unsigned int rx_drain_timeout_msecs;
extern unsigned int rx_stall_timeout_msecs;
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 0c8a02a1ead7..8af497285691 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -483,6 +483,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
vif->queues = NULL;
vif->num_queues = 0;
+ vif->xdp_headroom = 0;
+
spin_lock_init(&vif->lock);
INIT_LIST_HEAD(&vif->fe_mcast_addr);
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 315dfc6ea297..6dfca7265644 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -96,6 +96,13 @@ unsigned int xenvif_hash_cache_size = XENVIF_HASH_CACHE_SIZE_DEFAULT;
module_param_named(hash_cache_size, xenvif_hash_cache_size, uint, 0644);
MODULE_PARM_DESC(hash_cache_size, "Number of flows in the hash cache");
+/* The module parameter tells that we have to put data
+ * for xen-netfront with the XDP_PACKET_HEADROOM offset
+ * needed for XDP processing
+ */
+bool provides_xdp_headroom = true;
+module_param(provides_xdp_headroom, bool, 0644);
+
static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx,
u8 status);
diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c
index ef5887037b22..ac034f69a170 100644
--- a/drivers/net/xen-netback/rx.c
+++ b/drivers/net/xen-netback/rx.c
@@ -258,6 +258,19 @@ static void xenvif_rx_next_skb(struct xenvif_queue *queue,
pkt->extra_count++;
}
+ if (queue->vif->xdp_headroom) {
+ struct xen_netif_extra_info *extra;
+
+ extra = &pkt->extras[XEN_NETIF_EXTRA_TYPE_XDP - 1];
+
+ memset(extra, 0, sizeof(struct xen_netif_extra_info));
+ extra->u.xdp.headroom = queue->vif->xdp_headroom;
+ extra->type = XEN_NETIF_EXTRA_TYPE_XDP;
+ extra->flags = 0;
+
+ pkt->extra_count++;
+ }
+
if (skb->sw_hash) {
struct xen_netif_extra_info *extra;
@@ -356,7 +369,7 @@ static void xenvif_rx_data_slot(struct xenvif_queue *queue,
struct xen_netif_rx_request *req,
struct xen_netif_rx_response *rsp)
{
- unsigned int offset = 0;
+ unsigned int offset = queue->vif->xdp_headroom;
unsigned int flags;
do {
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 286054b60d47..7e62a6ee7622 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -393,6 +393,24 @@ static void set_backend_state(struct backend_info *be,
}
}
+static void read_xenbus_frontend_xdp(struct backend_info *be,
+ struct xenbus_device *dev)
+{
+ struct xenvif *vif = be->vif;
+ u16 headroom;
+ int err;
+
+ err = xenbus_scanf(XBT_NIL, dev->otherend,
+ "xdp-headroom", "%hu", &headroom);
+ if (err != 1) {
+ vif->xdp_headroom = 0;
+ return;
+ }
+ if (headroom > XEN_NETIF_MAX_XDP_HEADROOM)
+ headroom = XEN_NETIF_MAX_XDP_HEADROOM;
+ vif->xdp_headroom = headroom;
+}
+
/**
* Callback received when the frontend's state changes.
*/
@@ -417,6 +435,11 @@ static void frontend_changed(struct xenbus_device *dev,
set_backend_state(be, XenbusStateConnected);
break;
+ case XenbusStateReconfiguring:
+ read_xenbus_frontend_xdp(be, dev);
+ xenbus_switch_state(dev, XenbusStateReconfigured);
+ break;
+
case XenbusStateClosing:
set_backend_state(be, XenbusStateClosing);
break;
@@ -947,6 +970,8 @@ static int read_xenbus_vif_flags(struct backend_info *be)
vif->ipv6_csum = !!xenbus_read_unsigned(dev->otherend,
"feature-ipv6-csum-offload", 0);
+ read_xenbus_frontend_xdp(be, dev);
+
return 0;
}
@@ -1036,6 +1061,15 @@ static int netback_probe(struct xenbus_device *dev,
goto abort_transaction;
}
+ /* we can adjust a headroom for netfront XDP processing */
+ err = xenbus_printf(xbt, dev->nodename,
+ "feature-xdp-headroom", "%d",
+ provides_xdp_headroom);
+ if (err) {
+ message = "writing feature-xdp-headroom";
+ goto abort_transaction;
+ }
+
/* We don't support rx-flip path (except old guests who
* don't grok this feature flag).
*/
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 88280057e032..458be6882b98 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -44,6 +44,9 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <net/ip.h>
+#include <linux/bpf.h>
+#include <net/page_pool.h>
+#include <linux/bpf_trace.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
@@ -104,6 +107,8 @@ struct netfront_queue {
char name[QUEUE_NAME_SIZE]; /* DEVNAME-qN */
struct netfront_info *info;
+ struct bpf_prog __rcu *xdp_prog;
+
struct napi_struct napi;
/* Split event channels support, tx_* == rx_* when using
@@ -146,6 +151,9 @@ struct netfront_queue {
struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
grant_ref_t gref_rx_head;
grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
+
+ struct page_pool *page_pool;
+ struct xdp_rxq_info xdp_rxq;
};
struct netfront_info {
@@ -161,6 +169,10 @@ struct netfront_info {
struct netfront_stats __percpu *rx_stats;
struct netfront_stats __percpu *tx_stats;
+ /* XDP state */
+ bool netback_has_xdp_headroom;
+ bool netfront_xdp_enabled;
+
atomic_t rx_gso_checksum_fixup;
};
@@ -267,8 +279,8 @@ static struct sk_buff *xennet_alloc_one_rx_buffer(struct netfront_queue *queue)
if (unlikely(!skb))
return NULL;
- page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
- if (!page) {
+ page = page_pool_dev_alloc_pages(queue->page_pool);
+ if (unlikely(!page)) {
kfree_skb(skb);
return NULL;
}
@@ -562,6 +574,66 @@ static u16 xennet_select_queue(struct net_device *dev, struct sk_buff *skb,
return queue_idx;
}
+static int xennet_xdp_xmit_one(struct net_device *dev,
+ struct netfront_queue *queue,
+ struct xdp_frame *xdpf)
+{
+ struct netfront_info *np = netdev_priv(dev);
+ struct netfront_stats *tx_stats = this_cpu_ptr(np->tx_stats);
+ int notify;
+
+ xennet_make_first_txreq(queue, NULL,
+ virt_to_page(xdpf->data),
+ offset_in_page(xdpf->data),
+ xdpf->len);
+
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&queue->tx, notify);
+ if (notify)
+ notify_remote_via_irq(queue->tx_irq);
+
+ u64_stats_update_begin(&tx_stats->syncp);
+ tx_stats->bytes += xdpf->len;
+ tx_stats->packets++;
+ u64_stats_update_end(&tx_stats->syncp);
+
+ xennet_tx_buf_gc(queue);
+
+ return 0;
+}
+
+static int xennet_xdp_xmit(struct net_device *dev, int n,
+ struct xdp_frame **frames, u32 flags)
+{
+ unsigned int num_queues = dev->real_num_tx_queues;
+ struct netfront_info *np = netdev_priv(dev);
+ struct netfront_queue *queue = NULL;
+ unsigned long irq_flags;
+ int drops = 0;
+ int i, err;
+
+ if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
+ return -EINVAL;
+
+ queue = &np->queues[smp_processor_id() % num_queues];
+
+ spin_lock_irqsave(&queue->tx_lock, irq_flags);
+ for (i = 0; i < n; i++) {
+ struct xdp_frame *xdpf = frames[i];
+
+ if (!xdpf)
+ continue;
+ err = xennet_xdp_xmit_one(dev, queue, xdpf);
+ if (err) {
+ xdp_return_frame_rx_napi(xdpf);
+ drops++;
+ }
+ }
+ spin_unlock_irqrestore(&queue->tx_lock, irq_flags);
+
+ return n - drops;
+}
+
+
#define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1)
static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -684,6 +756,9 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev
/* First request has the packet length. */
first_tx->size = skb->len;
+ /* timestamp packet in software */
+ skb_tx_timestamp(skb);
+
RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&queue->tx, notify);
if (notify)
notify_remote_via_irq(queue->tx_irq);
@@ -780,23 +855,82 @@ static int xennet_get_extras(struct netfront_queue *queue,
return err;
}
+static u32 xennet_run_xdp(struct netfront_queue *queue, struct page *pdata,
+ struct xen_netif_rx_response *rx, struct bpf_prog *prog,
+ struct xdp_buff *xdp, bool *need_xdp_flush)
+{
+ struct xdp_frame *xdpf;
+ u32 len = rx->status;
+ u32 act;
+ int err;
+
+ xdp->data_hard_start = page_address(pdata);
+ xdp->data = xdp->data_hard_start + XDP_PACKET_HEADROOM;
+ xdp_set_data_meta_invalid(xdp);
+ xdp->data_end = xdp->data + len;
+ xdp->rxq = &queue->xdp_rxq;
+ xdp->frame_sz = XEN_PAGE_SIZE - XDP_PACKET_HEADROOM;
+
+ act = bpf_prog_run_xdp(prog, xdp);
+ switch (act) {
+ case XDP_TX:
+ get_page(pdata);
+ xdpf = xdp_convert_buff_to_frame(xdp);
+ err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0);
+ if (unlikely(err < 0))
+ trace_xdp_exception(queue->info->netdev, prog, act);
+ break;
+ case XDP_REDIRECT:
+ get_page(pdata);
+ err = xdp_do_redirect(queue->info->netdev, xdp, prog);
+ *need_xdp_flush = true;
+ if (unlikely(err))
+ trace_xdp_exception(queue->info->netdev, prog, act);
+ break;
+ case XDP_PASS:
+ case XDP_DROP:
+ break;
+
+ case XDP_ABORTED:
+ trace_xdp_exception(queue->info->netdev, prog, act);
+ break;
+
+ default:
+ bpf_warn_invalid_xdp_action(act);
+ }
+
+ return act;
+}
+
static int xennet_get_responses(struct netfront_queue *queue,
struct netfront_rx_info *rinfo, RING_IDX rp,
- struct sk_buff_head *list)
+ struct sk_buff_head *list,
+ bool *need_xdp_flush)
{
struct xen_netif_rx_response *rx = &rinfo->rx;
- struct xen_netif_extra_info *extras = rinfo->extras;
- struct device *dev = &queue->info->netdev->dev;
+ int max = XEN_NETIF_NR_SLOTS_MIN + (rx->status <= RX_COPY_THRESHOLD);
RING_IDX cons = queue->rx.rsp_cons;
struct sk_buff *skb = xennet_get_rx_skb(queue, cons);
+ struct xen_netif_extra_info *extras = rinfo->extras;
grant_ref_t ref = xennet_get_rx_ref(queue, cons);
- int max = XEN_NETIF_NR_SLOTS_MIN + (rx->status <= RX_COPY_THRESHOLD);
+ struct device *dev = &queue->info->netdev->dev;
+ struct bpf_prog *xdp_prog;
+ struct xdp_buff xdp;
+ unsigned long ret;
int slots = 1;
int err = 0;
- unsigned long ret;
+ u32 verdict;
if (rx->flags & XEN_NETRXF_extra_info) {
err = xennet_get_extras(queue, extras, rp);
+ if (!err) {
+ if (extras[XEN_NETIF_EXTRA_TYPE_XDP - 1].type) {
+ struct xen_netif_extra_info *xdp;
+
+ xdp = &extras[XEN_NETIF_EXTRA_TYPE_XDP - 1];
+ rx->offset = xdp->u.xdp.headroom;
+ }
+ }
cons = queue->rx.rsp_cons;
}
@@ -829,9 +963,24 @@ static int xennet_get_responses(struct netfront_queue *queue,
gnttab_release_grant_reference(&queue->gref_rx_head, ref);
- __skb_queue_tail(list, skb);
-
+ rcu_read_lock();
+ xdp_prog = rcu_dereference(queue->xdp_prog);
+ if (xdp_prog) {
+ if (!(rx->flags & XEN_NETRXF_more_data)) {
+ /* currently only a single page contains data */
+ verdict = xennet_run_xdp(queue,
+ skb_frag_page(&skb_shinfo(skb)->frags[0]),
+ rx, xdp_prog, &xdp, need_xdp_flush);
+ if (verdict != XDP_PASS)
+ err = -EINVAL;
+ } else {
+ /* drop the frame */
+ err = -EINVAL;
+ }
+ }
+ rcu_read_unlock();
next:
+ __skb_queue_tail(list, skb);
if (!(rx->flags & XEN_NETRXF_more_data))
break;
@@ -1000,6 +1149,7 @@ static int xennet_poll(struct napi_struct *napi, int budget)
struct sk_buff_head errq;
struct sk_buff_head tmpq;
int err;
+ bool need_xdp_flush = false;
spin_lock(&queue->rx_lock);
@@ -1016,7 +1166,8 @@ static int xennet_poll(struct napi_struct *napi, int budget)
memcpy(rx, RING_GET_RESPONSE(&queue->rx, i), sizeof(*rx));
memset(extras, 0, sizeof(rinfo.extras));
- err = xennet_get_responses(queue, &rinfo, rp, &tmpq);
+ err = xennet_get_responses(queue, &rinfo, rp, &tmpq,
+ &need_xdp_flush);
if (unlikely(err)) {
err:
@@ -1062,6 +1213,8 @@ err:
i = ++queue->rx.rsp_cons;
work_done++;
}
+ if (need_xdp_flush)
+ xdp_do_flush();
__skb_queue_purge(&errq);
@@ -1263,6 +1416,80 @@ static void xennet_poll_controller(struct net_device *dev)
}
#endif
+#define NETBACK_XDP_HEADROOM_DISABLE 0
+#define NETBACK_XDP_HEADROOM_ENABLE 1
+
+static int talk_to_netback_xdp(struct netfront_info *np, int xdp)
+{
+ int err;
+ unsigned short headroom;
+
+ headroom = xdp ? XDP_PACKET_HEADROOM : 0;
+ err = xenbus_printf(XBT_NIL, np->xbdev->nodename,
+ "xdp-headroom", "%hu",
+ headroom);
+ if (err)
+ pr_warn("Error writing xdp-headroom\n");
+
+ return err;
+}
+
+static int xennet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
+ struct netlink_ext_ack *extack)
+{
+ unsigned long max_mtu = XEN_PAGE_SIZE - XDP_PACKET_HEADROOM;
+ struct netfront_info *np = netdev_priv(dev);
+ struct bpf_prog *old_prog;
+ unsigned int i, err;
+
+ if (dev->mtu > max_mtu) {
+ netdev_warn(dev, "XDP requires MTU less than %lu\n", max_mtu);
+ return -EINVAL;
+ }
+
+ if (!np->netback_has_xdp_headroom)
+ return 0;
+
+ xenbus_switch_state(np->xbdev, XenbusStateReconfiguring);
+
+ err = talk_to_netback_xdp(np, prog ? NETBACK_XDP_HEADROOM_ENABLE :
+ NETBACK_XDP_HEADROOM_DISABLE);
+ if (err)
+ return err;
+
+ /* avoid the race with XDP headroom adjustment */
+ wait_event(module_wq,
+ xenbus_read_driver_state(np->xbdev->otherend) ==
+ XenbusStateReconfigured);
+ np->netfront_xdp_enabled = true;
+
+ old_prog = rtnl_dereference(np->queues[0].xdp_prog);
+
+ if (prog)
+ bpf_prog_add(prog, dev->real_num_tx_queues);
+
+ for (i = 0; i < dev->real_num_tx_queues; ++i)
+ rcu_assign_pointer(np->queues[i].xdp_prog, prog);
+
+ if (old_prog)
+ for (i = 0; i < dev->real_num_tx_queues; ++i)
+ bpf_prog_put(old_prog);
+
+ xenbus_switch_state(np->xbdev, XenbusStateConnected);
+
+ return 0;
+}
+
+static int xennet_xdp(struct net_device *dev, struct netdev_bpf *xdp)
+{
+ switch (xdp->command) {
+ case XDP_SETUP_PROG:
+ return xennet_xdp_set(dev, xdp->prog, xdp->extack);
+ default:
+ return -EINVAL;
+ }
+}
+
static const struct net_device_ops xennet_netdev_ops = {
.ndo_open = xennet_open,
.ndo_stop = xennet_close,
@@ -1274,6 +1501,8 @@ static const struct net_device_ops xennet_netdev_ops = {
.ndo_fix_features = xennet_fix_features,
.ndo_set_features = xennet_set_features,
.ndo_select_queue = xennet_select_queue,
+ .ndo_bpf = xennet_xdp,
+ .ndo_xdp_xmit = xennet_xdp_xmit,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = xennet_poll_controller,
#endif
@@ -1333,6 +1562,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
SET_NETDEV_DEV(netdev, &dev->dev);
np->netdev = netdev;
+ np->netfront_xdp_enabled = false;
netif_carrier_off(netdev);
@@ -1424,6 +1654,8 @@ static void xennet_disconnect_backend(struct netfront_info *info)
queue->rx_ring_ref = GRANT_INVALID_REF;
queue->tx.sring = NULL;
queue->rx.sring = NULL;
+
+ page_pool_destroy(queue->page_pool);
}
}
@@ -1759,6 +1991,51 @@ static void xennet_destroy_queues(struct netfront_info *info)
info->queues = NULL;
}
+
+
+static int xennet_create_page_pool(struct netfront_queue *queue)
+{
+ int err;
+ struct page_pool_params pp_params = {
+ .order = 0,
+ .flags = 0,
+ .pool_size = NET_RX_RING_SIZE,
+ .nid = NUMA_NO_NODE,
+ .dev = &queue->info->netdev->dev,
+ .offset = XDP_PACKET_HEADROOM,
+ .max_len = XEN_PAGE_SIZE - XDP_PACKET_HEADROOM,
+ };
+
+ queue->page_pool = page_pool_create(&pp_params);
+ if (IS_ERR(queue->page_pool)) {
+ err = PTR_ERR(queue->page_pool);
+ queue->page_pool = NULL;
+ return err;
+ }
+
+ err = xdp_rxq_info_reg(&queue->xdp_rxq, queue->info->netdev,
+ queue->id);
+ if (err) {
+ netdev_err(queue->info->netdev, "xdp_rxq_info_reg failed\n");
+ goto err_free_pp;
+ }
+
+ err = xdp_rxq_info_reg_mem_model(&queue->xdp_rxq,
+ MEM_TYPE_PAGE_POOL, queue->page_pool);
+ if (err) {
+ netdev_err(queue->info->netdev, "xdp_rxq_info_reg_mem_model failed\n");
+ goto err_unregister_rxq;
+ }
+ return 0;
+
+err_unregister_rxq:
+ xdp_rxq_info_unreg(&queue->xdp_rxq);
+err_free_pp:
+ page_pool_destroy(queue->page_pool);
+ queue->page_pool = NULL;
+ return err;
+}
+
static int xennet_create_queues(struct netfront_info *info,
unsigned int *num_queues)
{
@@ -1784,6 +2061,14 @@ static int xennet_create_queues(struct netfront_info *info,
break;
}
+ /* use page pool recycling instead of buddy allocator */
+ ret = xennet_create_page_pool(queue);
+ if (ret < 0) {
+ dev_err(&info->xbdev->dev, "can't allocate page pool\n");
+ *num_queues = i;
+ return ret;
+ }
+
netif_napi_add(queue->info->netdev, &queue->napi,
xennet_poll, 64);
if (netif_running(info->netdev))
@@ -1830,6 +2115,17 @@ static int talk_to_netback(struct xenbus_device *dev,
goto out_unlocked;
}
+ info->netback_has_xdp_headroom = xenbus_read_unsigned(info->xbdev->otherend,
+ "feature-xdp-headroom", 0);
+ if (info->netback_has_xdp_headroom) {
+ /* set the current xen-netfront xdp state */
+ err = talk_to_netback_xdp(info, info->netfront_xdp_enabled ?
+ NETBACK_XDP_HEADROOM_ENABLE :
+ NETBACK_XDP_HEADROOM_DISABLE);
+ if (err)
+ goto out_unlocked;
+ }
+
rtnl_lock();
if (info->queues)
xennet_destroy_queues(info);
@@ -1964,6 +2260,8 @@ static int xennet_connect(struct net_device *dev)
err = talk_to_netback(np->xbdev, np);
if (err)
return err;
+ if (np->netback_has_xdp_headroom)
+ pr_info("backend supports XDP headroom\n");
/* talk_to_netback() sets the correct number of queues */
num_queues = dev->real_num_tx_queues;
@@ -2100,6 +2398,7 @@ static const struct ethtool_ops xennet_ethtool_ops =
.get_sset_count = xennet_get_sset_count,
.get_ethtool_stats = xennet_get_ethtool_stats,
.get_strings = xennet_get_strings,
+ .get_ts_info = ethtool_op_get_ts_info,
};
#ifdef CONFIG_SYSFS
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index ef6f818ce5b3..cb32d7ef4938 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -268,6 +268,8 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
/* Get bus level PHY reset GPIO details */
mdio->reset_delay_us = DEFAULT_GPIO_RESET_DELAY;
of_property_read_u32(np, "reset-delay-us", &mdio->reset_delay_us);
+ mdio->reset_post_delay_us = 0;
+ of_property_read_u32(np, "reset-post-delay-us", &mdio->reset_post_delay_us);
/* Register the MDIO bus */
rc = mdiobus_register(mdio);
@@ -385,7 +387,7 @@ struct phy_device *of_phy_connect(struct net_device *dev,
if (!phy)
return NULL;
- phy->dev_flags = flags;
+ phy->dev_flags |= flags;
ret = phy_connect_direct(dev, phy, hndlr, iface);
diff --git a/drivers/ptp/idt8a340_reg.h b/drivers/ptp/idt8a340_reg.h
index 69eedda9f731..b297c4aba2ba 100644
--- a/drivers/ptp/idt8a340_reg.h
+++ b/drivers/ptp/idt8a340_reg.h
@@ -20,6 +20,10 @@
#define HW_DPLL_1 (0x8b00)
#define HW_DPLL_2 (0x8c00)
#define HW_DPLL_3 (0x8d00)
+#define HW_DPLL_4 (0x8e00)
+#define HW_DPLL_5 (0x8f00)
+#define HW_DPLL_6 (0x9000)
+#define HW_DPLL_7 (0x9100)
#define HW_DPLL_TOD_SW_TRIG_ADDR__0 (0x080)
#define HW_DPLL_TOD_CTRL_1 (0x089)
@@ -57,6 +61,43 @@
#define SYNCTRL1_Q1_DIV_SYNC_TRIG BIT(1)
#define SYNCTRL1_Q0_DIV_SYNC_TRIG BIT(0)
+#define HW_Q8_CTRL_SPARE (0xa7d4)
+#define HW_Q11_CTRL_SPARE (0xa7ec)
+
+/**
+ * Select FOD5 as sync_trigger for Q8 divider.
+ * Transition from logic zero to one
+ * sets trigger to sync Q8 divider.
+ *
+ * Unused when FOD4 is driving Q8 divider (normal operation).
+ */
+#define Q9_TO_Q8_SYNC_TRIG BIT(1)
+
+/**
+ * Enable FOD5 as driver for clock and sync for Q8 divider.
+ * Enable fanout buffer for FOD5.
+ *
+ * Unused when FOD4 is driving Q8 divider (normal operation).
+ */
+#define Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK (BIT(0) | BIT(2))
+
+/**
+ * Select FOD6 as sync_trigger for Q11 divider.
+ * Transition from logic zero to one
+ * sets trigger to sync Q11 divider.
+ *
+ * Unused when FOD7 is driving Q11 divider (normal operation).
+ */
+#define Q10_TO_Q11_SYNC_TRIG BIT(1)
+
+/**
+ * Enable FOD6 as driver for clock and sync for Q11 divider.
+ * Enable fanout buffer for FOD6.
+ *
+ * Unused when FOD7 is driving Q11 divider (normal operation).
+ */
+#define Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK (BIT(0) | BIT(2))
+
#define RESET_CTRL 0xc000
#define SM_RESET 0x0012
#define SM_RESET_CMD 0x5A
@@ -191,6 +232,7 @@
#define DPLL_CTRL_0 0xc600
#define DPLL_CTRL_DPLL_MANU_REF_CFG 0x0001
+#define DPLL_CTRL_COMBO_MASTER_CFG 0x003a
#define DPLL_CTRL_1 0xc63c
@@ -646,6 +688,9 @@
/* Bit definitions for the TOD_WRITE_CMD register */
#define TOD_WRITE_SELECTION_SHIFT (0)
#define TOD_WRITE_SELECTION_MASK (0xf)
+/* 4.8.7 */
+#define TOD_WRITE_TYPE_SHIFT (4)
+#define TOD_WRITE_TYPE_MASK (0x3)
/* Bit definitions for the TOD_READ_PRIMARY_SEL_CFG_0 register */
#define RD_PWM_DECODER_INDEX_SHIFT (4)
@@ -658,4 +703,7 @@
#define TOD_READ_TRIGGER_SHIFT (0)
#define TOD_READ_TRIGGER_MASK (0xf)
+/* Bit definitions for the DPLL_CTRL_COMBO_MASTER_CFG register */
+#define COMBO_MASTER_HOLD BIT(0)
+
#endif
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 375cd6e4aade..af3bc65c4595 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -191,12 +191,46 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
err = -EFAULT;
break;
}
- if (((req.perout.flags & ~PTP_PEROUT_VALID_FLAGS) ||
- req.perout.rsv[0] || req.perout.rsv[1] ||
- req.perout.rsv[2] || req.perout.rsv[3]) &&
- cmd == PTP_PEROUT_REQUEST2) {
- err = -EINVAL;
- break;
+ if (cmd == PTP_PEROUT_REQUEST2) {
+ struct ptp_perout_request *perout = &req.perout;
+
+ if (perout->flags & ~PTP_PEROUT_VALID_FLAGS) {
+ err = -EINVAL;
+ break;
+ }
+ /*
+ * The "on" field has undefined meaning if
+ * PTP_PEROUT_DUTY_CYCLE isn't set, we must still treat
+ * it as reserved, which must be set to zero.
+ */
+ if (!(perout->flags & PTP_PEROUT_DUTY_CYCLE) &&
+ (perout->rsv[0] || perout->rsv[1] ||
+ perout->rsv[2] || perout->rsv[3])) {
+ err = -EINVAL;
+ break;
+ }
+ if (perout->flags & PTP_PEROUT_DUTY_CYCLE) {
+ /* The duty cycle must be subunitary. */
+ if (perout->on.sec > perout->period.sec ||
+ (perout->on.sec == perout->period.sec &&
+ perout->on.nsec > perout->period.nsec)) {
+ err = -ERANGE;
+ break;
+ }
+ }
+ if (perout->flags & PTP_PEROUT_PHASE) {
+ /*
+ * The phase should be specified modulo the
+ * period, therefore anything equal or larger
+ * than 1 period is invalid.
+ */
+ if (perout->phase.sec > perout->period.sec ||
+ (perout->phase.sec == perout->period.sec &&
+ perout->phase.nsec >= perout->period.nsec)) {
+ err = -ERANGE;
+ break;
+ }
+ }
} else if (cmd == PTP_PEROUT_REQUEST) {
req.perout.flags &= PTP_PEROUT_V1_VALID_FLAGS;
req.perout.rsv[0] = 0;
diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c
index ceb6bc58f3b4..73aaae5574ed 100644
--- a/drivers/ptp/ptp_clockmatrix.c
+++ b/drivers/ptp/ptp_clockmatrix.c
@@ -13,6 +13,7 @@
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/timekeeping.h>
+#include <linux/string.h>
#include "ptp_private.h"
#include "ptp_clockmatrix.h"
@@ -23,6 +24,13 @@ MODULE_AUTHOR("IDT support-1588 <IDT-support-1588@lm.renesas.com>");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");
+/*
+ * The name of the firmware file to be loaded
+ * over-rides any automatic selection
+ */
+static char *firmware;
+module_param(firmware, charp, 0);
+
#define SETTIME_CORRECTION (0)
static long set_write_phase_ready(struct ptp_clock_info *ptp)
@@ -95,6 +103,45 @@ static int timespec_to_char_array(struct timespec64 const *ts,
return 0;
}
+static int idtcm_strverscmp(const char *ver1, const char *ver2)
+{
+ u8 num1;
+ u8 num2;
+ int result = 0;
+
+ /* loop through each level of the version string */
+ while (result == 0) {
+ /* extract leading version numbers */
+ if (kstrtou8(ver1, 10, &num1) < 0)
+ return -1;
+
+ if (kstrtou8(ver2, 10, &num2) < 0)
+ return -1;
+
+ /* if numbers differ, then set the result */
+ if (num1 < num2)
+ result = -1;
+ else if (num1 > num2)
+ result = 1;
+ else {
+ /* if numbers are the same, go to next level */
+ ver1 = strchr(ver1, '.');
+ ver2 = strchr(ver2, '.');
+ if (!ver1 && !ver2)
+ break;
+ else if (!ver1)
+ result = -1;
+ else if (!ver2)
+ result = 1;
+ else {
+ ver1++;
+ ver2++;
+ }
+ }
+ }
+ return result;
+}
+
static int idtcm_xfer(struct idtcm *idtcm,
u8 regaddr,
u8 *buf,
@@ -104,6 +151,7 @@ static int idtcm_xfer(struct idtcm *idtcm,
struct i2c_client *client = idtcm->client;
struct i2c_msg msg[2];
int cnt;
+ char *fmt = "i2c_transfer failed at %d in %s for %s, at addr: %04X!\n";
msg[0].addr = client->addr;
msg[0].flags = 0;
@@ -118,7 +166,12 @@ static int idtcm_xfer(struct idtcm *idtcm,
cnt = i2c_transfer(client->adapter, msg, 2);
if (cnt < 0) {
- dev_err(&client->dev, "i2c_transfer returned %d\n", cnt);
+ dev_err(&client->dev,
+ fmt,
+ __LINE__,
+ __func__,
+ write ? "write" : "read",
+ regaddr);
return cnt;
} else if (cnt != 2) {
dev_err(&client->dev,
@@ -144,10 +197,12 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
err = idtcm_xfer(idtcm, PAGE_ADDR, buf, sizeof(buf), 1);
- if (err)
+ if (err) {
+ idtcm->page_offset = 0xff;
dev_err(&idtcm->client->dev, "failed to set page offset\n");
- else
+ } else {
idtcm->page_offset = val;
+ }
return err;
}
@@ -198,6 +253,7 @@ static int _idtcm_gettime(struct idtcm_channel *channel,
{
struct idtcm *idtcm = channel->idtcm;
u8 buf[TOD_BYTE_COUNT];
+ u8 timeout = 10;
u8 trigger;
int err;
@@ -208,16 +264,29 @@ static int _idtcm_gettime(struct idtcm_channel *channel,
trigger &= ~(TOD_READ_TRIGGER_MASK << TOD_READ_TRIGGER_SHIFT);
trigger |= (1 << TOD_READ_TRIGGER_SHIFT);
- trigger |= TOD_READ_TRIGGER_MODE;
+ trigger &= ~TOD_READ_TRIGGER_MODE; /* single shot */
err = idtcm_write(idtcm, channel->tod_read_primary,
TOD_READ_PRIMARY_CMD, &trigger, sizeof(trigger));
-
if (err)
return err;
- if (idtcm->calculate_overhead_flag)
- idtcm->start_time = ktime_get_raw();
+ /* wait trigger to be 0 */
+ while (trigger & TOD_READ_TRIGGER_MASK) {
+
+ if (idtcm->calculate_overhead_flag)
+ idtcm->start_time = ktime_get_raw();
+
+ err = idtcm_read(idtcm, channel->tod_read_primary,
+ TOD_READ_PRIMARY_CMD, &trigger,
+ sizeof(trigger));
+
+ if (err)
+ return err;
+
+ if (--timeout == 0)
+ return -EIO;
+ }
err = idtcm_read(idtcm, channel->tod_read_primary,
TOD_READ_PRIMARY, buf, sizeof(buf));
@@ -240,6 +309,7 @@ static int _sync_pll_output(struct idtcm *idtcm,
u8 val;
u16 sync_ctrl0;
u16 sync_ctrl1;
+ u8 temp;
if ((qn == 0) && (qn_plus_1 == 0))
return 0;
@@ -305,6 +375,50 @@ static int _sync_pll_output(struct idtcm *idtcm,
if (err)
return err;
+ /* PLL5 can have OUT8 as second additional output. */
+ if ((pll == 5) && (qn_plus_1 != 0)) {
+ err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE,
+ &temp, sizeof(temp));
+ if (err)
+ return err;
+
+ temp &= ~(Q9_TO_Q8_SYNC_TRIG);
+
+ err = idtcm_write(idtcm, 0, HW_Q8_CTRL_SPARE,
+ &temp, sizeof(temp));
+ if (err)
+ return err;
+
+ temp |= Q9_TO_Q8_SYNC_TRIG;
+
+ err = idtcm_write(idtcm, 0, HW_Q8_CTRL_SPARE,
+ &temp, sizeof(temp));
+ if (err)
+ return err;
+ }
+
+ /* PLL6 can have OUT11 as second additional output. */
+ if ((pll == 6) && (qn_plus_1 != 0)) {
+ err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE,
+ &temp, sizeof(temp));
+ if (err)
+ return err;
+
+ temp &= ~(Q10_TO_Q11_SYNC_TRIG);
+
+ err = idtcm_write(idtcm, 0, HW_Q11_CTRL_SPARE,
+ &temp, sizeof(temp));
+ if (err)
+ return err;
+
+ temp |= Q10_TO_Q11_SYNC_TRIG;
+
+ err = idtcm_write(idtcm, 0, HW_Q11_CTRL_SPARE,
+ &temp, sizeof(temp));
+ if (err)
+ return err;
+ }
+
/* Place master sync out of reset */
val &= ~(SYNCTRL1_MASTER_SYNC_RST);
err = idtcm_write(idtcm, 0, sync_ctrl1, &val, sizeof(val));
@@ -312,6 +426,30 @@ static int _sync_pll_output(struct idtcm *idtcm,
return err;
}
+static int sync_source_dpll_tod_pps(u16 tod_addr, u8 *sync_src)
+{
+ int err = 0;
+
+ switch (tod_addr) {
+ case TOD_0:
+ *sync_src = SYNC_SOURCE_DPLL0_TOD_PPS;
+ break;
+ case TOD_1:
+ *sync_src = SYNC_SOURCE_DPLL1_TOD_PPS;
+ break;
+ case TOD_2:
+ *sync_src = SYNC_SOURCE_DPLL2_TOD_PPS;
+ break;
+ case TOD_3:
+ *sync_src = SYNC_SOURCE_DPLL3_TOD_PPS;
+ break;
+ default:
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
static int idtcm_sync_pps_output(struct idtcm_channel *channel)
{
struct idtcm *idtcm = channel->idtcm;
@@ -321,37 +459,68 @@ static int idtcm_sync_pps_output(struct idtcm_channel *channel)
u8 qn;
u8 qn_plus_1;
int err = 0;
+ u8 out8_mux = 0;
+ u8 out11_mux = 0;
+ u8 temp;
u16 output_mask = channel->output_mask;
- switch (channel->dpll_n) {
- case DPLL_0:
- sync_src = SYNC_SOURCE_DPLL0_TOD_PPS;
- break;
- case DPLL_1:
- sync_src = SYNC_SOURCE_DPLL1_TOD_PPS;
- break;
- case DPLL_2:
- sync_src = SYNC_SOURCE_DPLL2_TOD_PPS;
- break;
- case DPLL_3:
- sync_src = SYNC_SOURCE_DPLL3_TOD_PPS;
- break;
- default:
- return -EINVAL;
- }
+ err = sync_source_dpll_tod_pps(channel->tod_n, &sync_src);
+ if (err)
+ return err;
- for (pll = 0; pll < 8; pll++) {
+ err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE,
+ &temp, sizeof(temp));
+ if (err)
+ return err;
- qn = output_mask & 0x1;
- output_mask = output_mask >> 1;
+ if ((temp & Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK) ==
+ Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK)
+ out8_mux = 1;
+
+ err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE,
+ &temp, sizeof(temp));
+ if (err)
+ return err;
+
+ if ((temp & Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK) ==
+ Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK)
+ out11_mux = 1;
+
+ for (pll = 0; pll < 8; pll++) {
+ qn = 0;
+ qn_plus_1 = 0;
if (pll < 4) {
/* First 4 pll has 2 outputs */
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
qn_plus_1 = output_mask & 0x1;
output_mask = output_mask >> 1;
- } else {
- qn_plus_1 = 0;
+ } else if (pll == 4) {
+ if (out8_mux == 0) {
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ }
+ } else if (pll == 5) {
+ if (out8_mux) {
+ qn_plus_1 = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ }
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ } else if (pll == 6) {
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ if (out11_mux) {
+ qn_plus_1 = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ }
+ } else if (pll == 7) {
+ if (out11_mux == 0) {
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ }
}
if ((qn != 0) || (qn_plus_1 != 0))
@@ -365,7 +534,7 @@ static int idtcm_sync_pps_output(struct idtcm_channel *channel)
return err;
}
-static int _idtcm_set_dpll_tod(struct idtcm_channel *channel,
+static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
struct timespec64 const *ts,
enum hw_tod_write_trig_sel wr_trig)
{
@@ -439,17 +608,78 @@ static int _idtcm_set_dpll_tod(struct idtcm_channel *channel,
return err;
}
+static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel,
+ struct timespec64 const *ts,
+ enum scsr_tod_write_trig_sel wr_trig,
+ enum scsr_tod_write_type_sel wr_type)
+{
+ struct idtcm *idtcm = channel->idtcm;
+ unsigned char buf[TOD_BYTE_COUNT], cmd;
+ struct timespec64 local_ts = *ts;
+ int err, count = 0;
+
+ timespec64_add_ns(&local_ts, SETTIME_CORRECTION);
+
+ err = timespec_to_char_array(&local_ts, buf, sizeof(buf));
+
+ if (err)
+ return err;
+
+ err = idtcm_write(idtcm, channel->tod_write, TOD_WRITE,
+ buf, sizeof(buf));
+ if (err)
+ return err;
+
+ /* Trigger the write operation. */
+ err = idtcm_read(idtcm, channel->tod_write, TOD_WRITE_CMD,
+ &cmd, sizeof(cmd));
+ if (err)
+ return err;
+
+ cmd &= ~(TOD_WRITE_SELECTION_MASK << TOD_WRITE_SELECTION_SHIFT);
+ cmd &= ~(TOD_WRITE_TYPE_MASK << TOD_WRITE_TYPE_SHIFT);
+ cmd |= (wr_trig << TOD_WRITE_SELECTION_SHIFT);
+ cmd |= (wr_type << TOD_WRITE_TYPE_SHIFT);
+
+ err = idtcm_write(idtcm, channel->tod_write, TOD_WRITE_CMD,
+ &cmd, sizeof(cmd));
+ if (err)
+ return err;
+
+ /* Wait for the operation to complete. */
+ while (1) {
+ /* pps trigger takes up to 1 sec to complete */
+ if (wr_trig == SCSR_TOD_WR_TRIG_SEL_TODPPS)
+ msleep(50);
+
+ err = idtcm_read(idtcm, channel->tod_write, TOD_WRITE_CMD,
+ &cmd, sizeof(cmd));
+ if (err)
+ return err;
+
+ if (cmd == 0)
+ break;
+
+ if (++count > 20) {
+ dev_err(&idtcm->client->dev,
+ "Timed out waiting for the write counter\n");
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
static int _idtcm_settime(struct idtcm_channel *channel,
struct timespec64 const *ts,
enum hw_tod_write_trig_sel wr_trig)
{
struct idtcm *idtcm = channel->idtcm;
- s32 retval;
int err;
int i;
u8 trig_sel;
- err = _idtcm_set_dpll_tod(channel, ts, wr_trig);
+ err = _idtcm_set_dpll_hw_tod(channel, ts, wr_trig);
if (err)
return err;
@@ -469,12 +699,24 @@ static int _idtcm_settime(struct idtcm_channel *channel,
err = 1;
}
- if (err)
+ if (err) {
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
return err;
+ }
- retval = idtcm_sync_pps_output(channel);
+ return idtcm_sync_pps_output(channel);
+}
- return retval;
+static int _idtcm_settime_v487(struct idtcm_channel *channel,
+ struct timespec64 const *ts,
+ enum scsr_tod_write_type_sel wr_type)
+{
+ return _idtcm_set_dpll_scsr_tod(channel, ts,
+ SCSR_TOD_WR_TRIG_SEL_IMMEDIATE,
+ wr_type);
}
static int idtcm_set_phase_pull_in_offset(struct idtcm_channel *channel,
@@ -565,6 +807,50 @@ static int idtcm_do_phase_pull_in(struct idtcm_channel *channel,
return err;
}
+static int set_tod_write_overhead(struct idtcm_channel *channel)
+{
+ struct idtcm *idtcm = channel->idtcm;
+ s64 current_ns = 0;
+ s64 lowest_ns = 0;
+ int err;
+ u8 i;
+
+ ktime_t start;
+ ktime_t stop;
+
+ char buf[TOD_BYTE_COUNT] = {0};
+
+ /* Set page offset */
+ idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_OVR__0,
+ buf, sizeof(buf));
+
+ for (i = 0; i < TOD_WRITE_OVERHEAD_COUNT_MAX; i++) {
+
+ start = ktime_get_raw();
+
+ err = idtcm_write(idtcm, channel->hw_dpll_n,
+ HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
+
+ if (err)
+ return err;
+
+ stop = ktime_get_raw();
+
+ current_ns = ktime_to_ns(stop - start);
+
+ if (i == 0) {
+ lowest_ns = current_ns;
+ } else {
+ if (current_ns < lowest_ns)
+ lowest_ns = current_ns;
+ }
+ }
+
+ idtcm->tod_write_overhead_ns = lowest_ns;
+
+ return err;
+}
+
static int _idtcm_adjtime(struct idtcm_channel *channel, s64 delta)
{
int err;
@@ -577,6 +863,11 @@ static int _idtcm_adjtime(struct idtcm_channel *channel, s64 delta)
} else {
idtcm->calculate_overhead_flag = 1;
+ err = set_tod_write_overhead(channel);
+
+ if (err)
+ return err;
+
err = _idtcm_gettime(channel, &ts);
if (err)
@@ -656,93 +947,118 @@ static int idtcm_read_otp_scsr_config_select(struct idtcm *idtcm,
config_select, sizeof(u8));
}
-static int process_pll_mask(struct idtcm *idtcm, u32 addr, u8 val, u8 *mask)
-{
- int err = 0;
-
- if (addr == PLL_MASK_ADDR) {
- if ((val & 0xf0) || !(val & 0xf)) {
- dev_err(&idtcm->client->dev,
- "Invalid PLL mask 0x%hhx\n", val);
- err = -EINVAL;
- }
- *mask = val;
- }
-
- return err;
-}
-
static int set_pll_output_mask(struct idtcm *idtcm, u16 addr, u8 val)
{
int err = 0;
switch (addr) {
- case OUTPUT_MASK_PLL0_ADDR:
+ case TOD0_OUT_ALIGN_MASK_ADDR:
SET_U16_LSB(idtcm->channel[0].output_mask, val);
break;
- case OUTPUT_MASK_PLL0_ADDR + 1:
+ case TOD0_OUT_ALIGN_MASK_ADDR + 1:
SET_U16_MSB(idtcm->channel[0].output_mask, val);
break;
- case OUTPUT_MASK_PLL1_ADDR:
+ case TOD1_OUT_ALIGN_MASK_ADDR:
SET_U16_LSB(idtcm->channel[1].output_mask, val);
break;
- case OUTPUT_MASK_PLL1_ADDR + 1:
+ case TOD1_OUT_ALIGN_MASK_ADDR + 1:
SET_U16_MSB(idtcm->channel[1].output_mask, val);
break;
- case OUTPUT_MASK_PLL2_ADDR:
+ case TOD2_OUT_ALIGN_MASK_ADDR:
SET_U16_LSB(idtcm->channel[2].output_mask, val);
break;
- case OUTPUT_MASK_PLL2_ADDR + 1:
+ case TOD2_OUT_ALIGN_MASK_ADDR + 1:
SET_U16_MSB(idtcm->channel[2].output_mask, val);
break;
- case OUTPUT_MASK_PLL3_ADDR:
+ case TOD3_OUT_ALIGN_MASK_ADDR:
SET_U16_LSB(idtcm->channel[3].output_mask, val);
break;
- case OUTPUT_MASK_PLL3_ADDR + 1:
+ case TOD3_OUT_ALIGN_MASK_ADDR + 1:
SET_U16_MSB(idtcm->channel[3].output_mask, val);
break;
default:
- err = -EINVAL;
+ err = -EFAULT; /* Bad address */;
break;
}
return err;
}
+static int set_tod_ptp_pll(struct idtcm *idtcm, u8 index, u8 pll)
+{
+ if (index >= MAX_TOD) {
+ dev_err(&idtcm->client->dev, "ToD%d not supported\n", index);
+ return -EINVAL;
+ }
+
+ if (pll >= MAX_PLL) {
+ dev_err(&idtcm->client->dev, "Pll%d not supported\n", pll);
+ return -EINVAL;
+ }
+
+ idtcm->channel[index].pll = pll;
+
+ return 0;
+}
+
static int check_and_set_masks(struct idtcm *idtcm,
u16 regaddr,
u8 val)
{
int err = 0;
- if (set_pll_output_mask(idtcm, regaddr, val)) {
- /* Not an output mask, check for pll mask */
- err = process_pll_mask(idtcm, regaddr, val, &idtcm->pll_mask);
+ switch (regaddr) {
+ case TOD_MASK_ADDR:
+ if ((val & 0xf0) || !(val & 0x0f)) {
+ dev_err(&idtcm->client->dev,
+ "Invalid TOD mask 0x%hhx\n", val);
+ err = -EINVAL;
+ } else {
+ idtcm->tod_mask = val;
+ }
+ break;
+ case TOD0_PTP_PLL_ADDR:
+ err = set_tod_ptp_pll(idtcm, 0, val);
+ break;
+ case TOD1_PTP_PLL_ADDR:
+ err = set_tod_ptp_pll(idtcm, 1, val);
+ break;
+ case TOD2_PTP_PLL_ADDR:
+ err = set_tod_ptp_pll(idtcm, 2, val);
+ break;
+ case TOD3_PTP_PLL_ADDR:
+ err = set_tod_ptp_pll(idtcm, 3, val);
+ break;
+ default:
+ err = set_pll_output_mask(idtcm, regaddr, val);
+ break;
}
return err;
}
-static void display_pll_and_output_masks(struct idtcm *idtcm)
+static void display_pll_and_masks(struct idtcm *idtcm)
{
u8 i;
u8 mask;
- dev_dbg(&idtcm->client->dev, "pllmask = 0x%02x\n", idtcm->pll_mask);
+ dev_dbg(&idtcm->client->dev, "tod_mask = 0x%02x\n", idtcm->tod_mask);
- for (i = 0; i < MAX_PHC_PLL; i++) {
+ for (i = 0; i < MAX_TOD; i++) {
mask = 1 << i;
- if (mask & idtcm->pll_mask)
+ if (mask & idtcm->tod_mask)
dev_dbg(&idtcm->client->dev,
- "PLL%d output_mask = 0x%04x\n",
- i, idtcm->channel[i].output_mask);
+ "TOD%d pll = %d output_mask = 0x%04x\n",
+ i, idtcm->channel[i].pll,
+ idtcm->channel[i].output_mask);
}
}
static int idtcm_load_firmware(struct idtcm *idtcm,
struct device *dev)
{
+ char fname[128] = FW_FILENAME;
const struct firmware *fw;
struct idtcm_fwrc *rec;
u32 regaddr;
@@ -751,12 +1067,20 @@ static int idtcm_load_firmware(struct idtcm *idtcm,
u8 val;
u8 loaddr;
- dev_dbg(&idtcm->client->dev, "requesting firmware '%s'\n", FW_FILENAME);
+ if (firmware) /* module parameter */
+ snprintf(fname, sizeof(fname), "%s", firmware);
- err = request_firmware(&fw, FW_FILENAME, dev);
+ dev_dbg(&idtcm->client->dev, "requesting firmware '%s'\n", fname);
- if (err)
+ err = request_firmware(&fw, fname, dev);
+
+ if (err) {
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
return err;
+ }
dev_dbg(&idtcm->client->dev, "firmware size %zu bytes\n", fw->size);
@@ -783,7 +1107,9 @@ static int idtcm_load_firmware(struct idtcm *idtcm,
err = check_and_set_masks(idtcm, regaddr, val);
}
- if (err == 0) {
+ if (err != -EINVAL) {
+ err = 0;
+
/* Top (status registers) and bottom are read-only */
if ((regaddr < GPIO_USER_CONTROL)
|| (regaddr >= SCRATCH))
@@ -801,42 +1127,22 @@ static int idtcm_load_firmware(struct idtcm *idtcm,
goto out;
}
- display_pll_and_output_masks(idtcm);
+ display_pll_and_masks(idtcm);
out:
release_firmware(fw);
return err;
}
-static int idtcm_pps_enable(struct idtcm_channel *channel, bool enable)
+static int idtcm_output_enable(struct idtcm_channel *channel,
+ bool enable, unsigned int outn)
{
struct idtcm *idtcm = channel->idtcm;
- u32 module;
- u8 val;
int err;
+ u8 val;
- /*
- * This assumes that the 1-PPS is on the second of the two
- * output. But is this always true?
- */
- switch (channel->dpll_n) {
- case DPLL_0:
- module = OUTPUT_1;
- break;
- case DPLL_1:
- module = OUTPUT_3;
- break;
- case DPLL_2:
- module = OUTPUT_5;
- break;
- case DPLL_3:
- module = OUTPUT_7;
- break;
- default:
- return -EINVAL;
- }
-
- err = idtcm_read(idtcm, module, OUT_CTRL_1, &val, sizeof(val));
+ err = idtcm_read(idtcm, OUTPUT_MODULE_FROM_INDEX(outn),
+ OUT_CTRL_1, &val, sizeof(val));
if (err)
return err;
@@ -846,14 +1152,50 @@ static int idtcm_pps_enable(struct idtcm_channel *channel, bool enable)
else
val &= ~SQUELCH_DISABLE;
- err = idtcm_write(idtcm, module, OUT_CTRL_1, &val, sizeof(val));
+ return idtcm_write(idtcm, OUTPUT_MODULE_FROM_INDEX(outn),
+ OUT_CTRL_1, &val, sizeof(val));
+}
- if (err)
- return err;
+static int idtcm_output_mask_enable(struct idtcm_channel *channel,
+ bool enable)
+{
+ u16 mask;
+ int err;
+ u8 outn;
+
+ mask = channel->output_mask;
+ outn = 0;
+
+ while (mask) {
+
+ if (mask & 0x1) {
+
+ err = idtcm_output_enable(channel, enable, outn);
+
+ if (err)
+ return err;
+ }
+
+ mask >>= 0x1;
+ outn++;
+ }
return 0;
}
+static int idtcm_perout_enable(struct idtcm_channel *channel,
+ bool enable,
+ struct ptp_perout_request *perout)
+{
+ unsigned int flags = perout->flags;
+
+ if (flags == PEROUT_ENABLE_OUTPUT_MASK)
+ return idtcm_output_mask_enable(channel, enable);
+
+ /* Enable/disable individual output instead */
+ return idtcm_output_enable(channel, enable, perout->index);
+}
+
static int idtcm_set_pll_mode(struct idtcm_channel *channel,
enum pll_mode pll_mode)
{
@@ -940,10 +1282,8 @@ static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
return err;
}
-static int idtcm_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm)
{
- struct idtcm_channel *channel =
- container_of(ptp, struct idtcm_channel, caps);
struct idtcm *idtcm = channel->idtcm;
u8 i;
bool neg_adj = 0;
@@ -970,15 +1310,15 @@ static int idtcm_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
* FCW = -------------
* 111 * 2^4
*/
- if (ppb < 0) {
+ if (scaled_ppm < 0) {
neg_adj = 1;
- ppb = -ppb;
+ scaled_ppm = -scaled_ppm;
}
/* 2 ^ -53 = 1.1102230246251565404236316680908e-16 */
- fcw = ppb * 1000000000000ULL;
+ fcw = scaled_ppm * 244140625ULL;
- fcw = div_u64(fcw, 111022);
+ fcw = div_u64(fcw, 1776);
if (neg_adj)
fcw = -fcw;
@@ -988,12 +1328,9 @@ static int idtcm_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
fcw >>= 8;
}
- mutex_lock(&idtcm->reg_lock);
-
err = idtcm_write(idtcm, channel->dpll_freq, DPLL_WR_FREQ,
buf, sizeof(buf));
- mutex_unlock(&idtcm->reg_lock);
return err;
}
@@ -1008,6 +1345,12 @@ static int idtcm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
err = _idtcm_gettime(channel, ts);
+ if (err)
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+
mutex_unlock(&idtcm->reg_lock);
return err;
@@ -1025,6 +1368,35 @@ static int idtcm_settime(struct ptp_clock_info *ptp,
err = _idtcm_settime(channel, ts, HW_TOD_WR_TRIG_SEL_MSB);
+ if (err)
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+
+ mutex_unlock(&idtcm->reg_lock);
+
+ return err;
+}
+
+static int idtcm_settime_v487(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts)
+{
+ struct idtcm_channel *channel =
+ container_of(ptp, struct idtcm_channel, caps);
+ struct idtcm *idtcm = channel->idtcm;
+ int err;
+
+ mutex_lock(&idtcm->reg_lock);
+
+ err = _idtcm_settime_v487(channel, ts, SCSR_TOD_WR_TYPE_SEL_ABSOLUTE);
+
+ if (err)
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+
mutex_unlock(&idtcm->reg_lock);
return err;
@@ -1041,6 +1413,54 @@ static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
err = _idtcm_adjtime(channel, delta);
+ if (err)
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+
+ mutex_unlock(&idtcm->reg_lock);
+
+ return err;
+}
+
+static int idtcm_adjtime_v487(struct ptp_clock_info *ptp, s64 delta)
+{
+ struct idtcm_channel *channel =
+ container_of(ptp, struct idtcm_channel, caps);
+ struct idtcm *idtcm = channel->idtcm;
+ struct timespec64 ts;
+ enum scsr_tod_write_type_sel type;
+ int err;
+
+ if (abs(delta) < PHASE_PULL_IN_THRESHOLD_NS_V487) {
+ err = idtcm_do_phase_pull_in(channel, delta, 0);
+ if (err)
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+ return err;
+ }
+
+ if (delta >= 0) {
+ ts = ns_to_timespec64(delta);
+ type = SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS;
+ } else {
+ ts = ns_to_timespec64(-delta);
+ type = SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS;
+ }
+
+ mutex_lock(&idtcm->reg_lock);
+
+ err = _idtcm_settime_v487(channel, &ts, type);
+
+ if (err)
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+
mutex_unlock(&idtcm->reg_lock);
return err;
@@ -1059,6 +1479,36 @@ static int idtcm_adjphase(struct ptp_clock_info *ptp, s32 delta)
err = _idtcm_adjphase(channel, delta);
+ if (err)
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+
+ mutex_unlock(&idtcm->reg_lock);
+
+ return err;
+}
+
+static int idtcm_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+{
+ struct idtcm_channel *channel =
+ container_of(ptp, struct idtcm_channel, caps);
+
+ struct idtcm *idtcm = channel->idtcm;
+
+ int err;
+
+ mutex_lock(&idtcm->reg_lock);
+
+ err = _idtcm_adjfine(channel, scaled_ppm);
+
+ if (err)
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+
mutex_unlock(&idtcm->reg_lock);
return err;
@@ -1067,20 +1517,35 @@ static int idtcm_adjphase(struct ptp_clock_info *ptp, s32 delta)
static int idtcm_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on)
{
+ int err;
+
struct idtcm_channel *channel =
container_of(ptp, struct idtcm_channel, caps);
switch (rq->type) {
case PTP_CLK_REQ_PEROUT:
- if (!on)
- return idtcm_pps_enable(channel, false);
+ if (!on) {
+ err = idtcm_perout_enable(channel, false, &rq->perout);
+ if (err)
+ dev_err(&channel->idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+ return err;
+ }
/* Only accept a 1-PPS aligned to the second. */
if (rq->perout.start.nsec || rq->perout.period.sec != 1 ||
rq->perout.period.nsec)
return -ERANGE;
- return idtcm_pps_enable(channel, true);
+ err = idtcm_perout_enable(channel, true, &rq->perout);
+ if (err)
+ dev_err(&channel->idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+ return err;
default:
break;
}
@@ -1088,17 +1553,237 @@ static int idtcm_enable(struct ptp_clock_info *ptp,
return -EOPNOTSUPP;
}
-static int idtcm_enable_tod(struct idtcm_channel *channel)
+static int _enable_pll_tod_sync(struct idtcm *idtcm,
+ u8 pll,
+ u8 sync_src,
+ u8 qn,
+ u8 qn_plus_1)
+{
+ int err;
+ u8 val;
+ u16 dpll;
+ u16 out0 = 0, out1 = 0;
+
+ if ((qn == 0) && (qn_plus_1 == 0))
+ return 0;
+
+ switch (pll) {
+ case 0:
+ dpll = DPLL_0;
+ if (qn)
+ out0 = OUTPUT_0;
+ if (qn_plus_1)
+ out1 = OUTPUT_1;
+ break;
+ case 1:
+ dpll = DPLL_1;
+ if (qn)
+ out0 = OUTPUT_2;
+ if (qn_plus_1)
+ out1 = OUTPUT_3;
+ break;
+ case 2:
+ dpll = DPLL_2;
+ if (qn)
+ out0 = OUTPUT_4;
+ if (qn_plus_1)
+ out1 = OUTPUT_5;
+ break;
+ case 3:
+ dpll = DPLL_3;
+ if (qn)
+ out0 = OUTPUT_6;
+ if (qn_plus_1)
+ out1 = OUTPUT_7;
+ break;
+ case 4:
+ dpll = DPLL_4;
+ if (qn)
+ out0 = OUTPUT_8;
+ break;
+ case 5:
+ dpll = DPLL_5;
+ if (qn)
+ out0 = OUTPUT_9;
+ if (qn_plus_1)
+ out1 = OUTPUT_8;
+ break;
+ case 6:
+ dpll = DPLL_6;
+ if (qn)
+ out0 = OUTPUT_10;
+ if (qn_plus_1)
+ out1 = OUTPUT_11;
+ break;
+ case 7:
+ dpll = DPLL_7;
+ if (qn)
+ out0 = OUTPUT_11;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /*
+ * Enable OUTPUT OUT_SYNC.
+ */
+ if (out0) {
+ err = idtcm_read(idtcm, out0, OUT_CTRL_1, &val, sizeof(val));
+
+ if (err)
+ return err;
+
+ val &= ~OUT_SYNC_DISABLE;
+
+ err = idtcm_write(idtcm, out0, OUT_CTRL_1, &val, sizeof(val));
+
+ if (err)
+ return err;
+ }
+
+ if (out1) {
+ err = idtcm_read(idtcm, out1, OUT_CTRL_1, &val, sizeof(val));
+
+ if (err)
+ return err;
+
+ val &= ~OUT_SYNC_DISABLE;
+
+ err = idtcm_write(idtcm, out1, OUT_CTRL_1, &val, sizeof(val));
+
+ if (err)
+ return err;
+ }
+
+ /* enable dpll sync tod pps, must be set before dpll_mode */
+ err = idtcm_read(idtcm, dpll, DPLL_TOD_SYNC_CFG, &val, sizeof(val));
+ if (err)
+ return err;
+
+ val &= ~(TOD_SYNC_SOURCE_MASK << TOD_SYNC_SOURCE_SHIFT);
+ val |= (sync_src << TOD_SYNC_SOURCE_SHIFT);
+ val |= TOD_SYNC_EN;
+
+ return idtcm_write(idtcm, dpll, DPLL_TOD_SYNC_CFG, &val, sizeof(val));
+}
+
+static int idtcm_enable_tod_sync(struct idtcm_channel *channel)
{
struct idtcm *idtcm = channel->idtcm;
- struct timespec64 ts = {0, 0};
+
+ u8 pll;
+ u8 sync_src;
+ u8 qn;
+ u8 qn_plus_1;
u8 cfg;
- int err;
+ int err = 0;
+ u16 output_mask = channel->output_mask;
+ u8 out8_mux = 0;
+ u8 out11_mux = 0;
+ u8 temp;
+
+ /*
+ * set tod_out_sync_enable to 0.
+ */
+ err = idtcm_read(idtcm, channel->tod_n, TOD_CFG, &cfg, sizeof(cfg));
+ if (err)
+ return err;
+
+ cfg &= ~TOD_OUT_SYNC_ENABLE;
+
+ err = idtcm_write(idtcm, channel->tod_n, TOD_CFG, &cfg, sizeof(cfg));
+ if (err)
+ return err;
+
+ switch (channel->tod_n) {
+ case TOD_0:
+ sync_src = 0;
+ break;
+ case TOD_1:
+ sync_src = 1;
+ break;
+ case TOD_2:
+ sync_src = 2;
+ break;
+ case TOD_3:
+ sync_src = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
- err = idtcm_pps_enable(channel, false);
+ err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE,
+ &temp, sizeof(temp));
if (err)
return err;
+ if ((temp & Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK) ==
+ Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK)
+ out8_mux = 1;
+
+ err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE,
+ &temp, sizeof(temp));
+ if (err)
+ return err;
+
+ if ((temp & Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK) ==
+ Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK)
+ out11_mux = 1;
+
+ for (pll = 0; pll < 8; pll++) {
+ qn = 0;
+ qn_plus_1 = 0;
+
+ if (pll < 4) {
+ /* First 4 pll has 2 outputs */
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ qn_plus_1 = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ } else if (pll == 4) {
+ if (out8_mux == 0) {
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ }
+ } else if (pll == 5) {
+ if (out8_mux) {
+ qn_plus_1 = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ }
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ } else if (pll == 6) {
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ if (out11_mux) {
+ qn_plus_1 = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ }
+ } else if (pll == 7) {
+ if (out11_mux == 0) {
+ qn = output_mask & 0x1;
+ output_mask = output_mask >> 1;
+ }
+ }
+
+ if ((qn != 0) || (qn_plus_1 != 0))
+ err = _enable_pll_tod_sync(idtcm, pll, sync_src, qn,
+ qn_plus_1);
+
+ if (err)
+ return err;
+ }
+
+ return err;
+}
+
+static int idtcm_enable_tod(struct idtcm_channel *channel)
+{
+ struct idtcm *idtcm = channel->idtcm;
+ struct timespec64 ts = {0, 0};
+ u8 cfg;
+ int err;
+
/*
* Start the TOD clock ticking.
*/
@@ -1134,16 +1819,32 @@ static void idtcm_display_version_info(struct idtcm *idtcm)
idtcm_read_otp_scsr_config_select(idtcm, &config_select);
+ snprintf(idtcm->version, sizeof(idtcm->version), "%u.%u.%u",
+ major, minor, hotfix);
+
dev_info(&idtcm->client->dev, fmt, major, minor, hotfix,
product_id, hw_rev_id, config_select);
}
+static const struct ptp_clock_info idtcm_caps_v487 = {
+ .owner = THIS_MODULE,
+ .max_adj = 244000,
+ .n_per_out = 12,
+ .adjphase = &idtcm_adjphase,
+ .adjfine = &idtcm_adjfine,
+ .adjtime = &idtcm_adjtime_v487,
+ .gettime64 = &idtcm_gettime,
+ .settime64 = &idtcm_settime_v487,
+ .enable = &idtcm_enable,
+ .do_aux_work = &set_write_phase_ready,
+};
+
static const struct ptp_clock_info idtcm_caps = {
.owner = THIS_MODULE,
.max_adj = 244000,
- .n_per_out = 1,
+ .n_per_out = 12,
.adjphase = &idtcm_adjphase,
- .adjfreq = &idtcm_adjfreq,
+ .adjfine = &idtcm_adjfine,
.adjtime = &idtcm_adjtime,
.gettime64 = &idtcm_gettime,
.settime64 = &idtcm_settime,
@@ -1151,24 +1852,14 @@ static const struct ptp_clock_info idtcm_caps = {
.do_aux_work = &set_write_phase_ready,
};
-
-static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
+static int configure_channel_pll(struct idtcm_channel *channel)
{
- struct idtcm_channel *channel;
- int err;
-
- if (!(index < MAX_PHC_PLL))
- return -EINVAL;
-
- channel = &idtcm->channel[index];
+ int err = 0;
- switch (index) {
+ switch (channel->pll) {
case 0:
channel->dpll_freq = DPLL_FREQ_0;
channel->dpll_n = DPLL_0;
- channel->tod_read_primary = TOD_READ_PRIMARY_0;
- channel->tod_write = TOD_WRITE_0;
- channel->tod_n = TOD_0;
channel->hw_dpll_n = HW_DPLL_0;
channel->dpll_phase = DPLL_PHASE_0;
channel->dpll_ctrl_n = DPLL_CTRL_0;
@@ -1177,9 +1868,6 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
case 1:
channel->dpll_freq = DPLL_FREQ_1;
channel->dpll_n = DPLL_1;
- channel->tod_read_primary = TOD_READ_PRIMARY_1;
- channel->tod_write = TOD_WRITE_1;
- channel->tod_n = TOD_1;
channel->hw_dpll_n = HW_DPLL_1;
channel->dpll_phase = DPLL_PHASE_1;
channel->dpll_ctrl_n = DPLL_CTRL_1;
@@ -1188,9 +1876,6 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
case 2:
channel->dpll_freq = DPLL_FREQ_2;
channel->dpll_n = DPLL_2;
- channel->tod_read_primary = TOD_READ_PRIMARY_2;
- channel->tod_write = TOD_WRITE_2;
- channel->tod_n = TOD_2;
channel->hw_dpll_n = HW_DPLL_2;
channel->dpll_phase = DPLL_PHASE_2;
channel->dpll_ctrl_n = DPLL_CTRL_2;
@@ -1199,31 +1884,129 @@ static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
case 3:
channel->dpll_freq = DPLL_FREQ_3;
channel->dpll_n = DPLL_3;
- channel->tod_read_primary = TOD_READ_PRIMARY_3;
- channel->tod_write = TOD_WRITE_3;
- channel->tod_n = TOD_3;
channel->hw_dpll_n = HW_DPLL_3;
channel->dpll_phase = DPLL_PHASE_3;
channel->dpll_ctrl_n = DPLL_CTRL_3;
channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_3;
break;
+ case 4:
+ channel->dpll_freq = DPLL_FREQ_4;
+ channel->dpll_n = DPLL_4;
+ channel->hw_dpll_n = HW_DPLL_4;
+ channel->dpll_phase = DPLL_PHASE_4;
+ channel->dpll_ctrl_n = DPLL_CTRL_4;
+ channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_4;
+ break;
+ case 5:
+ channel->dpll_freq = DPLL_FREQ_5;
+ channel->dpll_n = DPLL_5;
+ channel->hw_dpll_n = HW_DPLL_5;
+ channel->dpll_phase = DPLL_PHASE_5;
+ channel->dpll_ctrl_n = DPLL_CTRL_5;
+ channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_5;
+ break;
+ case 6:
+ channel->dpll_freq = DPLL_FREQ_6;
+ channel->dpll_n = DPLL_6;
+ channel->hw_dpll_n = HW_DPLL_6;
+ channel->dpll_phase = DPLL_PHASE_6;
+ channel->dpll_ctrl_n = DPLL_CTRL_6;
+ channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_6;
+ break;
+ case 7:
+ channel->dpll_freq = DPLL_FREQ_7;
+ channel->dpll_n = DPLL_7;
+ channel->hw_dpll_n = HW_DPLL_7;
+ channel->dpll_phase = DPLL_PHASE_7;
+ channel->dpll_ctrl_n = DPLL_CTRL_7;
+ channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_7;
+ break;
+ default:
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
+{
+ struct idtcm_channel *channel;
+ int err;
+
+ if (!(index < MAX_TOD))
+ return -EINVAL;
+
+ channel = &idtcm->channel[index];
+
+ /* Set pll addresses */
+ err = configure_channel_pll(channel);
+ if (err)
+ return err;
+
+ /* Set tod addresses */
+ switch (index) {
+ case 0:
+ channel->tod_read_primary = TOD_READ_PRIMARY_0;
+ channel->tod_write = TOD_WRITE_0;
+ channel->tod_n = TOD_0;
+ break;
+ case 1:
+ channel->tod_read_primary = TOD_READ_PRIMARY_1;
+ channel->tod_write = TOD_WRITE_1;
+ channel->tod_n = TOD_1;
+ break;
+ case 2:
+ channel->tod_read_primary = TOD_READ_PRIMARY_2;
+ channel->tod_write = TOD_WRITE_2;
+ channel->tod_n = TOD_2;
+ break;
+ case 3:
+ channel->tod_read_primary = TOD_READ_PRIMARY_3;
+ channel->tod_write = TOD_WRITE_3;
+ channel->tod_n = TOD_3;
+ break;
default:
return -EINVAL;
}
channel->idtcm = idtcm;
- channel->caps = idtcm_caps;
+ if (idtcm_strverscmp(idtcm->version, "4.8.7") >= 0)
+ channel->caps = idtcm_caps_v487;
+ else
+ channel->caps = idtcm_caps;
+
snprintf(channel->caps.name, sizeof(channel->caps.name),
- "IDT CM PLL%u", index);
+ "IDT CM TOD%u", index);
+
+ if (idtcm_strverscmp(idtcm->version, "4.8.7") >= 0) {
+ err = idtcm_enable_tod_sync(channel);
+ if (err) {
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
+ return err;
+ }
+ }
err = idtcm_set_pll_mode(channel, PLL_MODE_WRITE_FREQUENCY);
- if (err)
+ if (err) {
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
return err;
+ }
err = idtcm_enable_tod(channel);
- if (err)
+ if (err) {
+ dev_err(&idtcm->client->dev,
+ "Failed at line %d in func %s!\n",
+ __LINE__,
+ __func__);
return err;
+ }
channel->ptp_clock = ptp_clock_register(&channel->caps, NULL);
@@ -1249,7 +2032,7 @@ static void ptp_clock_unregister_all(struct idtcm *idtcm)
u8 i;
struct idtcm_channel *channel;
- for (i = 0; i < MAX_PHC_PLL; i++) {
+ for (i = 0; i < MAX_TOD; i++) {
channel = &idtcm->channel[i];
@@ -1260,7 +2043,12 @@ static void ptp_clock_unregister_all(struct idtcm *idtcm)
static void set_default_masks(struct idtcm *idtcm)
{
- idtcm->pll_mask = DEFAULT_PLL_MASK;
+ idtcm->tod_mask = DEFAULT_TOD_MASK;
+
+ idtcm->channel[0].pll = DEFAULT_TOD0_PTP_PLL;
+ idtcm->channel[1].pll = DEFAULT_TOD1_PTP_PLL;
+ idtcm->channel[2].pll = DEFAULT_TOD2_PTP_PLL;
+ idtcm->channel[3].pll = DEFAULT_TOD3_PTP_PLL;
idtcm->channel[0].output_mask = DEFAULT_OUTPUT_MASK_PLL0;
idtcm->channel[1].output_mask = DEFAULT_OUTPUT_MASK_PLL1;
@@ -1268,51 +2056,13 @@ static void set_default_masks(struct idtcm *idtcm)
idtcm->channel[3].output_mask = DEFAULT_OUTPUT_MASK_PLL3;
}
-static int set_tod_write_overhead(struct idtcm *idtcm)
-{
- int err;
- u8 i;
-
- s64 total_ns = 0;
-
- ktime_t start;
- ktime_t stop;
-
- char buf[TOD_BYTE_COUNT];
-
- struct idtcm_channel *channel = &idtcm->channel[2];
-
- /* Set page offset */
- idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_OVR__0,
- buf, sizeof(buf));
-
- for (i = 0; i < TOD_WRITE_OVERHEAD_COUNT_MAX; i++) {
-
- start = ktime_get_raw();
-
- err = idtcm_write(idtcm, channel->hw_dpll_n,
- HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
-
- if (err)
- return err;
-
- stop = ktime_get_raw();
-
- total_ns += ktime_to_ns(stop - start);
- }
-
- idtcm->tod_write_overhead_ns = div_s64(total_ns,
- TOD_WRITE_OVERHEAD_COUNT_MAX);
-
- return err;
-}
-
static int idtcm_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct idtcm *idtcm;
int err;
u8 i;
+ char *fmt = "Failed at %d in line %s with channel output %d!\n";
/* Unused for now */
(void)id;
@@ -1333,25 +2083,24 @@ static int idtcm_probe(struct i2c_client *client,
idtcm_display_version_info(idtcm);
- err = set_tod_write_overhead(idtcm);
-
- if (err) {
- mutex_unlock(&idtcm->reg_lock);
- return err;
- }
-
err = idtcm_load_firmware(idtcm, &client->dev);
if (err)
dev_warn(&idtcm->client->dev,
"loading firmware failed with %d\n", err);
- if (idtcm->pll_mask) {
- for (i = 0; i < MAX_PHC_PLL; i++) {
- if (idtcm->pll_mask & (1 << i)) {
+ if (idtcm->tod_mask) {
+ for (i = 0; i < MAX_TOD; i++) {
+ if (idtcm->tod_mask & (1 << i)) {
err = idtcm_enable_channel(idtcm, i);
- if (err)
+ if (err) {
+ dev_err(&idtcm->client->dev,
+ fmt,
+ __LINE__,
+ __func__,
+ i);
break;
+ }
}
}
} else {
diff --git a/drivers/ptp/ptp_clockmatrix.h b/drivers/ptp/ptp_clockmatrix.h
index 3de0eb72889c..ffae56c5d97f 100644
--- a/drivers/ptp/ptp_clockmatrix.h
+++ b/drivers/ptp/ptp_clockmatrix.h
@@ -13,32 +13,48 @@
#include "idt8a340_reg.h"
#define FW_FILENAME "idtcm.bin"
-#define MAX_PHC_PLL 4
+#define MAX_TOD (4)
+#define MAX_PLL (8)
#define MAX_ABS_WRITE_PHASE_PICOSECONDS (107374182350LL)
-#define PLL_MASK_ADDR (0xFFA5)
-#define DEFAULT_PLL_MASK (0x04)
+#define TOD_MASK_ADDR (0xFFA5)
+#define DEFAULT_TOD_MASK (0x04)
#define SET_U16_LSB(orig, val8) (orig = (0xff00 & (orig)) | (val8))
#define SET_U16_MSB(orig, val8) (orig = (0x00ff & (orig)) | (val8 << 8))
-#define OUTPUT_MASK_PLL0_ADDR (0xFFB0)
-#define OUTPUT_MASK_PLL1_ADDR (0xFFB2)
-#define OUTPUT_MASK_PLL2_ADDR (0xFFB4)
-#define OUTPUT_MASK_PLL3_ADDR (0xFFB6)
+#define TOD0_PTP_PLL_ADDR (0xFFA8)
+#define TOD1_PTP_PLL_ADDR (0xFFA9)
+#define TOD2_PTP_PLL_ADDR (0xFFAA)
+#define TOD3_PTP_PLL_ADDR (0xFFAB)
+
+#define TOD0_OUT_ALIGN_MASK_ADDR (0xFFB0)
+#define TOD1_OUT_ALIGN_MASK_ADDR (0xFFB2)
+#define TOD2_OUT_ALIGN_MASK_ADDR (0xFFB4)
+#define TOD3_OUT_ALIGN_MASK_ADDR (0xFFB6)
#define DEFAULT_OUTPUT_MASK_PLL0 (0x003)
#define DEFAULT_OUTPUT_MASK_PLL1 (0x00c)
#define DEFAULT_OUTPUT_MASK_PLL2 (0x030)
#define DEFAULT_OUTPUT_MASK_PLL3 (0x0c0)
+#define DEFAULT_TOD0_PTP_PLL (0)
+#define DEFAULT_TOD1_PTP_PLL (1)
+#define DEFAULT_TOD2_PTP_PLL (2)
+#define DEFAULT_TOD3_PTP_PLL (3)
+
#define POST_SM_RESET_DELAY_MS (3000)
#define PHASE_PULL_IN_THRESHOLD_NS (150000)
-#define TOD_WRITE_OVERHEAD_COUNT_MAX (5)
+#define PHASE_PULL_IN_THRESHOLD_NS_V487 (15000)
+#define TOD_WRITE_OVERHEAD_COUNT_MAX (2)
#define TOD_BYTE_COUNT (11)
#define WR_PHASE_SETUP_MS (5000)
+#define OUTPUT_MODULE_FROM_INDEX(index) (OUTPUT_0 + (index) * 0x10)
+
+#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef)
+
/* Values of DPLL_N.DPLL_MODE.PLL_MODE */
enum pll_mode {
PLL_MODE_MIN = 0,
@@ -48,7 +64,8 @@ enum pll_mode {
PLL_MODE_GPIO_INC_DEC = 3,
PLL_MODE_SYNTHESIS = 4,
PLL_MODE_PHASE_MEASUREMENT = 5,
- PLL_MODE_MAX = PLL_MODE_PHASE_MEASUREMENT,
+ PLL_MODE_DISABLED = 6,
+ PLL_MODE_MAX = PLL_MODE_DISABLED,
};
enum hw_tod_write_trig_sel {
@@ -63,6 +80,26 @@ enum hw_tod_write_trig_sel {
WR_TRIG_SEL_MAX = HW_TOD_WR_TRIG_SEL_FOD_SYNC,
};
+/* 4.8.7 only */
+enum scsr_tod_write_trig_sel {
+ SCSR_TOD_WR_TRIG_SEL_DISABLE = 0,
+ SCSR_TOD_WR_TRIG_SEL_IMMEDIATE = 1,
+ SCSR_TOD_WR_TRIG_SEL_REFCLK = 2,
+ SCSR_TOD_WR_TRIG_SEL_PWMPPS = 3,
+ SCSR_TOD_WR_TRIG_SEL_TODPPS = 4,
+ SCSR_TOD_WR_TRIG_SEL_SYNCFOD = 5,
+ SCSR_TOD_WR_TRIG_SEL_GPIO = 6,
+ SCSR_TOD_WR_TRIG_SEL_MAX = SCSR_TOD_WR_TRIG_SEL_GPIO,
+};
+
+/* 4.8.7 only */
+enum scsr_tod_write_type_sel {
+ SCSR_TOD_WR_TYPE_SEL_ABSOLUTE = 0,
+ SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS = 1,
+ SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS = 2,
+ SCSR_TOD_WR_TYPE_SEL_MAX = SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS,
+};
+
struct idtcm;
struct idtcm_channel {
@@ -79,15 +116,17 @@ struct idtcm_channel {
u16 tod_n;
u16 hw_dpll_n;
enum pll_mode pll_mode;
+ u8 pll;
u16 output_mask;
int write_phase_ready;
};
struct idtcm {
- struct idtcm_channel channel[MAX_PHC_PLL];
+ struct idtcm_channel channel[MAX_TOD];
struct i2c_client *client;
u8 page_offset;
- u8 pll_mask;
+ u8 tod_mask;
+ char version[16];
/* Overhead calculation for adjtime */
u8 calculate_overhead_flag;
diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c
index dcd6e00c8046..ce10ecd41ba0 100644
--- a/drivers/ptp/ptp_pch.c
+++ b/drivers/ptp/ptp_pch.c
@@ -508,40 +508,8 @@ static const struct ptp_clock_info ptp_pch_caps = {
.enable = ptp_pch_enable,
};
-
-#ifdef CONFIG_PM
-static s32 pch_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- pci_disable_device(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
-
- if (pci_save_state(pdev) != 0) {
- dev_err(&pdev->dev, "could not save PCI config state\n");
- return -ENOMEM;
- }
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- return 0;
-}
-
-static s32 pch_resume(struct pci_dev *pdev)
-{
- s32 ret;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- ret = pci_enable_device(pdev);
- if (ret) {
- dev_err(&pdev->dev, "pci_enable_device failed\n");
- return ret;
- }
- pci_enable_wake(pdev, PCI_D3hot, 0);
- return 0;
-}
-#else
#define pch_suspend NULL
#define pch_resume NULL
-#endif
static void pch_remove(struct pci_dev *pdev)
{
@@ -684,13 +652,14 @@ static const struct pci_device_id pch_ieee1588_pcidev_id[] = {
{0}
};
+static SIMPLE_DEV_PM_OPS(pch_pm_ops, pch_suspend, pch_resume);
+
static struct pci_driver pch_driver = {
.name = KBUILD_MODNAME,
.id_table = pch_ieee1588_pcidev_id,
.probe = pch_probe,
.remove = pch_remove,
- .suspend = pch_suspend,
- .resume = pch_resume,
+ .driver.pm = &pch_pm_ops,
};
static void __exit ptp_pch_exit(void)
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
index c7fade836d83..5fbe9eae84d1 100644
--- a/drivers/s390/net/ism_drv.c
+++ b/drivers/s390/net/ism_drv.c
@@ -231,7 +231,7 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct smcd_dmb *dmb)
bit = find_next_zero_bit(ism->sba_bitmap, ISM_NR_DMBS,
ISM_DMB_BIT_OFFSET);
if (bit == ISM_NR_DMBS)
- return -ENOMEM;
+ return -ENOSPC;
dmb->sba_idx = bit;
}
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 51ea56b73a97..ecfd6d152e86 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -721,7 +721,6 @@ struct qeth_card_options {
struct qeth_vnicc_info vnicc; /* VNICC options */
enum qeth_discipline_id layer;
enum qeth_ipa_isolation_modes isolation;
- enum qeth_ipa_isolation_modes prev_isolation;
int sniffer;
enum qeth_cq cq;
char hsuid[9];
@@ -765,6 +764,7 @@ struct qeth_rx {
u8 buf_element;
int e_offset;
int qdio_err;
+ u8 bufs_refill;
};
struct carrier_info {
@@ -804,14 +804,13 @@ struct qeth_card {
struct workqueue_struct *event_wq;
struct workqueue_struct *cmd_wq;
wait_queue_head_t wait_q;
- DECLARE_HASHTABLE(mac_htable, 4);
DECLARE_HASHTABLE(ip_htable, 4);
DECLARE_HASHTABLE(local_addrs4, 4);
DECLARE_HASHTABLE(local_addrs6, 4);
spinlock_t local_addrs4_lock;
spinlock_t local_addrs6_lock;
struct mutex ip_lock;
- DECLARE_HASHTABLE(ip_mc_htable, 4);
+ DECLARE_HASHTABLE(rx_mode_addrs, 4);
struct work_struct rx_mode_work;
struct work_struct kernel_thread_starter;
spinlock_t thread_mask_lock;
@@ -835,7 +834,6 @@ struct qeth_card {
struct napi_struct napi;
struct qeth_rx rx;
struct delayed_work buffer_reclaim_work;
- int reclaim_index;
struct work_struct close_dev_work;
};
@@ -1071,6 +1069,9 @@ int qeth_query_switch_attributes(struct qeth_card *card,
struct qeth_switch_info *sw_info);
int qeth_query_card_info(struct qeth_card *card,
struct carrier_info *carrier_info);
+int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
+ enum qeth_ipa_isolation_modes mode);
+
unsigned int qeth_count_elements(struct sk_buff *skb, unsigned int data_offset);
int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
struct sk_buff *skb, struct qeth_hdr *hdr,
@@ -1078,7 +1079,6 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
int elements_needed);
int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...);
-int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback);
int qeth_configure_cq(struct qeth_card *, enum qeth_cq);
int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
void qeth_trace_features(struct qeth_card *);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 88e998de2d03..bba1b54b8aa3 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -204,12 +204,17 @@ EXPORT_SYMBOL_GPL(qeth_threads_running);
void qeth_clear_working_pool_list(struct qeth_card *card)
{
struct qeth_buffer_pool_entry *pool_entry, *tmp;
+ struct qeth_qdio_q *queue = card->qdio.in_q;
+ unsigned int i;
QETH_CARD_TEXT(card, 5, "clwrklst");
list_for_each_entry_safe(pool_entry, tmp,
&card->qdio.in_buf_pool.entry_list, list){
list_del(&pool_entry->list);
}
+
+ for (i = 0; i < ARRAY_SIZE(queue->bufs); i++)
+ queue->bufs[i].pool_entry = NULL;
}
EXPORT_SYMBOL_GPL(qeth_clear_working_pool_list);
@@ -969,7 +974,7 @@ void qeth_clear_ipacmd_list(struct qeth_card *card)
spin_lock_irqsave(&card->lock, flags);
list_for_each_entry(iob, &card->cmd_waiter_list, list)
- qeth_notify_cmd(iob, -EIO);
+ qeth_notify_cmd(iob, -ECANCELED);
spin_unlock_irqrestore(&card->lock, flags);
}
EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);
@@ -1647,6 +1652,7 @@ static void qeth_setup_card(struct qeth_card *card)
qeth_init_qdio_info(card);
INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work);
INIT_WORK(&card->close_dev_work, qeth_close_dev_handler);
+ hash_init(card->rx_mode_addrs);
hash_init(card->local_addrs4);
hash_init(card->local_addrs6);
spin_lock_init(&card->local_addrs4_lock);
@@ -2025,7 +2031,7 @@ static bool qeth_mpc_match_reply(struct qeth_cmd_buffer *iob,
}
static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card,
- void *data,
+ const void *data,
unsigned int data_length)
{
struct qeth_cmd_buffer *iob;
@@ -2436,6 +2442,17 @@ static int qeth_cm_setup(struct qeth_card *card)
return qeth_send_control_data(card, iob, qeth_cm_setup_cb, NULL);
}
+static bool qeth_is_supported_link_type(struct qeth_card *card, u8 link_type)
+{
+ if (link_type == QETH_LINK_TYPE_LANE_TR ||
+ link_type == QETH_LINK_TYPE_HSTR) {
+ dev_err(&card->gdev->dev, "Unsupported Token Ring device\n");
+ return false;
+ }
+
+ return true;
+}
+
static int qeth_update_max_mtu(struct qeth_card *card, unsigned int max_mtu)
{
struct net_device *dev = card->dev;
@@ -2495,8 +2512,8 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
{
__u16 mtu, framesize;
__u16 len;
- __u8 link_type;
struct qeth_cmd_buffer *iob;
+ u8 link_type = 0;
QETH_CARD_TEXT(card, 2, "ulpenacb");
@@ -2516,9 +2533,11 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
if (len >= QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE) {
memcpy(&link_type,
QETH_ULP_ENABLE_RESP_LINK_TYPE(iob->data), 1);
- card->info.link_type = link_type;
- } else
- card->info.link_type = 0;
+ if (!qeth_is_supported_link_type(card, link_type))
+ return -EPROTONOSUPPORT;
+ }
+
+ card->info.link_type = link_type;
QETH_CARD_TEXT_(card, 2, "link%d", card->info.link_type);
return 0;
}
@@ -2951,7 +2970,7 @@ static struct qeth_buffer_pool_entry *qeth_find_free_buffer_pool_entry(
static int qeth_init_input_buffer(struct qeth_card *card,
struct qeth_qdio_buffer *buf)
{
- struct qeth_buffer_pool_entry *pool_entry;
+ struct qeth_buffer_pool_entry *pool_entry = buf->pool_entry;
int i;
if ((card->options.cq == QETH_CQ_ENABLED) && (!buf->rx_skb)) {
@@ -2962,9 +2981,13 @@ static int qeth_init_input_buffer(struct qeth_card *card,
return -ENOMEM;
}
- pool_entry = qeth_find_free_buffer_pool_entry(card);
- if (!pool_entry)
- return -ENOBUFS;
+ if (!pool_entry) {
+ pool_entry = qeth_find_free_buffer_pool_entry(card);
+ if (!pool_entry)
+ return -ENOBUFS;
+
+ buf->pool_entry = pool_entry;
+ }
/*
* since the buffer is accessed only from the input_tasklet
@@ -2972,8 +2995,6 @@ static int qeth_init_input_buffer(struct qeth_card *card,
* the QETH_IN_BUF_REQUEUE_THRESHOLD we should never run out off
* buffers
*/
-
- buf->pool_entry = pool_entry;
for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
buf->buffer->element[i].length = PAGE_SIZE;
buf->buffer->element[i].addr =
@@ -3001,6 +3022,7 @@ static unsigned int qeth_tx_select_bulk_max(struct qeth_card *card,
static int qeth_init_qdio_queues(struct qeth_card *card)
{
+ unsigned int rx_bufs = card->qdio.in_buf_pool.buf_count;
unsigned int i;
int rc;
@@ -3012,16 +3034,14 @@ static int qeth_init_qdio_queues(struct qeth_card *card)
qeth_initialize_working_pool_list(card);
/*give only as many buffers to hardware as we have buffer pool entries*/
- for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; i++) {
+ for (i = 0; i < rx_bufs; i++) {
rc = qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]);
if (rc)
return rc;
}
- card->qdio.in_q->next_buf_to_init =
- card->qdio.in_buf_pool.buf_count - 1;
- rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0,
- card->qdio.in_buf_pool.buf_count - 1);
+ card->qdio.in_q->next_buf_to_init = QDIO_BUFNR(rx_bufs);
+ rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, rx_bufs);
if (rc) {
QETH_CARD_TEXT_(card, 2, "1err%d", rc);
return rc;
@@ -3100,7 +3120,6 @@ struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card,
enum qeth_prot_versions prot,
unsigned int data_length)
{
- enum qeth_link_types link_type = card->info.link_type;
struct qeth_cmd_buffer *iob;
struct qeth_ipacmd_hdr *hdr;
@@ -3116,7 +3135,7 @@ struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card,
hdr->command = cmd_code;
hdr->initiator = IPA_CMD_INITIATOR_HOST;
/* hdr->seqno is set by qeth_send_control_data() */
- hdr->adapter_type = (link_type == QETH_LINK_TYPE_HSTR) ? 2 : 1;
+ hdr->adapter_type = QETH_LINK_TYPE_FAST_ETH;
hdr->rel_adapter_no = (u8) card->dev->dev_port;
hdr->prim_version_no = IS_LAYER2(card) ? 2 : 1;
hdr->param_count = 1;
@@ -3199,18 +3218,22 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data)
{
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
+ struct qeth_query_cmds_supp *query_cmd;
QETH_CARD_TEXT(card, 3, "quyadpcb");
if (qeth_setadpparms_inspect_rc(cmd))
return -EIO;
- if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f) {
- card->info.link_type =
- cmd->data.setadapterparms.data.query_cmds_supp.lan_type;
+ query_cmd = &cmd->data.setadapterparms.data.query_cmds_supp;
+ if (query_cmd->lan_type & 0x7f) {
+ if (!qeth_is_supported_link_type(card, query_cmd->lan_type))
+ return -EPROTONOSUPPORT;
+
+ card->info.link_type = query_cmd->lan_type;
QETH_CARD_TEXT_(card, 2, "lnk %d", card->info.link_type);
}
- card->options.adp.supported =
- cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds;
+
+ card->options.adp.supported = query_cmd->supported_cmds;
return 0;
}
@@ -3468,20 +3491,15 @@ static int qeth_check_qdio_errors(struct qeth_card *card,
return 0;
}
-static void qeth_queue_input_buffer(struct qeth_card *card, int index)
+static unsigned int qeth_rx_refill_queue(struct qeth_card *card,
+ unsigned int count)
{
struct qeth_qdio_q *queue = card->qdio.in_q;
struct list_head *lh;
- int count;
int i;
int rc;
int newcount = 0;
- count = (index < queue->next_buf_to_init)?
- card->qdio.in_buf_pool.buf_count -
- (queue->next_buf_to_init - index) :
- card->qdio.in_buf_pool.buf_count -
- (queue->next_buf_to_init + QDIO_MAX_BUFFERS_PER_Q - index);
/* only requeue at a certain threshold to avoid SIGAs */
if (count >= QETH_IN_BUF_REQUEUE_THRESHOLD(card)) {
for (i = queue->next_buf_to_init;
@@ -3509,21 +3527,13 @@ static void qeth_queue_input_buffer(struct qeth_card *card, int index)
i++;
if (i == card->qdio.in_buf_pool.buf_count) {
QETH_CARD_TEXT(card, 2, "qsarbw");
- card->reclaim_index = index;
schedule_delayed_work(
&card->buffer_reclaim_work,
QETH_RECLAIM_WORK_TIME);
}
- return;
+ return 0;
}
- /*
- * according to old code it should be avoided to requeue all
- * 128 buffers in order to benefit from PCI avoidance.
- * this function keeps at least one buffer (the buffer at
- * 'index') un-requeued -> this buffer is the first buffer that
- * will be requeued the next time
- */
rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0,
queue->next_buf_to_init, count);
if (rc) {
@@ -3531,7 +3541,10 @@ static void qeth_queue_input_buffer(struct qeth_card *card, int index)
}
queue->next_buf_to_init = QDIO_BUFNR(queue->next_buf_to_init +
count);
+ return count;
}
+
+ return 0;
}
static void qeth_buffer_reclaim_work(struct work_struct *work)
@@ -3539,8 +3552,10 @@ static void qeth_buffer_reclaim_work(struct work_struct *work)
struct qeth_card *card = container_of(work, struct qeth_card,
buffer_reclaim_work.work);
- QETH_CARD_TEXT_(card, 2, "brw:%x", card->reclaim_index);
- qeth_queue_input_buffer(card, card->reclaim_index);
+ local_bh_disable();
+ napi_schedule(&card->napi);
+ /* kick-start the NAPI softirq: */
+ local_bh_enable();
}
static void qeth_handle_send_error(struct qeth_card *card,
@@ -4541,7 +4556,6 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
{
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
struct qeth_set_access_ctrl *access_ctrl_req;
- int fallback = *(int *)reply->param;
QETH_CARD_TEXT(card, 4, "setaccb");
@@ -4555,70 +4569,54 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
cmd->data.setadapterparms.hdr.return_code);
switch (qeth_setadpparms_inspect_rc(cmd)) {
case SET_ACCESS_CTRL_RC_SUCCESS:
- if (card->options.isolation == ISOLATION_MODE_NONE) {
+ if (access_ctrl_req->subcmd_code == ISOLATION_MODE_NONE)
dev_info(&card->gdev->dev,
"QDIO data connection isolation is deactivated\n");
- } else {
+ else
dev_info(&card->gdev->dev,
"QDIO data connection isolation is activated\n");
- }
- break;
+ return 0;
case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
QETH_DBF_MESSAGE(2, "QDIO data connection isolation on device %x already deactivated\n",
CARD_DEVID(card));
- if (fallback)
- card->options.isolation = card->options.prev_isolation;
- break;
+ return 0;
case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
QETH_DBF_MESSAGE(2, "QDIO data connection isolation on device %x already activated\n",
CARD_DEVID(card));
- if (fallback)
- card->options.isolation = card->options.prev_isolation;
- break;
+ return 0;
case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
dev_err(&card->gdev->dev, "Adapter does not "
"support QDIO data connection isolation\n");
- break;
+ return -EOPNOTSUPP;
case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
dev_err(&card->gdev->dev,
"Adapter is dedicated. "
"QDIO data connection isolation not supported\n");
- if (fallback)
- card->options.isolation = card->options.prev_isolation;
- break;
+ return -EOPNOTSUPP;
case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
dev_err(&card->gdev->dev,
"TSO does not permit QDIO data connection isolation\n");
- if (fallback)
- card->options.isolation = card->options.prev_isolation;
- break;
+ return -EPERM;
case SET_ACCESS_CTRL_RC_REFLREL_UNSUPPORTED:
dev_err(&card->gdev->dev, "The adjacent switch port does not "
"support reflective relay mode\n");
- if (fallback)
- card->options.isolation = card->options.prev_isolation;
- break;
+ return -EOPNOTSUPP;
case SET_ACCESS_CTRL_RC_REFLREL_FAILED:
dev_err(&card->gdev->dev, "The reflective relay mode cannot be "
"enabled at the adjacent switch port");
- if (fallback)
- card->options.isolation = card->options.prev_isolation;
- break;
+ return -EREMOTEIO;
case SET_ACCESS_CTRL_RC_REFLREL_DEACT_FAILED:
dev_warn(&card->gdev->dev, "Turning off reflective relay mode "
"at the adjacent switch failed\n");
- break;
+ /* benign error while disabling ISOLATION_MODE_FWD */
+ return 0;
default:
- /* this should never happen */
- if (fallback)
- card->options.isolation = card->options.prev_isolation;
- break;
+ return -EIO;
}
- return (cmd->hdr.return_code) ? -EIO : 0;
}
-static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
- enum qeth_ipa_isolation_modes isolation, int fallback)
+int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
+ enum qeth_ipa_isolation_modes mode)
{
int rc;
struct qeth_cmd_buffer *iob;
@@ -4627,42 +4625,28 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
QETH_CARD_TEXT(card, 4, "setacctl");
+ if (!qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
+ dev_err(&card->gdev->dev,
+ "Adapter does not support QDIO data connection isolation\n");
+ return -EOPNOTSUPP;
+ }
+
iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL,
SETADP_DATA_SIZEOF(set_access_ctrl));
if (!iob)
return -ENOMEM;
cmd = __ipa_cmd(iob);
access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
- access_ctrl_req->subcmd_code = isolation;
+ access_ctrl_req->subcmd_code = mode;
rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb,
- &fallback);
- QETH_CARD_TEXT_(card, 2, "rc=%d", rc);
- return rc;
-}
-
-int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback)
-{
- int rc = 0;
-
- QETH_CARD_TEXT(card, 4, "setactlo");
-
- if ((IS_OSD(card) || IS_OSX(card)) &&
- qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
- rc = qeth_setadpparms_set_access_ctrl(card,
- card->options.isolation, fallback);
- if (rc) {
- QETH_DBF_MESSAGE(3, "IPA(SET_ACCESS_CTRL(%d) on device %x: sent failed\n",
- rc, CARD_DEVID(card));
- rc = -EOPNOTSUPP;
- }
- } else if (card->options.isolation != ISOLATION_MODE_NONE) {
- card->options.isolation = ISOLATION_MODE_NONE;
-
- dev_err(&card->gdev->dev, "Adapter does not "
- "support QDIO data connection isolation\n");
- rc = -EOPNOTSUPP;
+ NULL);
+ if (rc) {
+ QETH_CARD_TEXT_(card, 2, "rc=%d", rc);
+ QETH_DBF_MESSAGE(3, "IPA(SET_ACCESS_CTRL(%d) on device %x: sent failed\n",
+ rc, CARD_DEVID(card));
}
+
return rc;
}
@@ -4850,26 +4834,24 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata)
}
static int qeth_setadpparms_query_oat_cb(struct qeth_card *card,
- struct qeth_reply *reply, unsigned long data)
+ struct qeth_reply *reply,
+ unsigned long data)
{
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;
- struct qeth_qoat_priv *priv;
- char *resdata;
+ struct qeth_qoat_priv *priv = reply->param;
int resdatalen;
QETH_CARD_TEXT(card, 3, "qoatcb");
if (qeth_setadpparms_inspect_rc(cmd))
return -EIO;
- priv = (struct qeth_qoat_priv *)reply->param;
resdatalen = cmd->data.setadapterparms.hdr.cmdlength;
- resdata = (char *)data + 28;
if (resdatalen > (priv->buffer_len - priv->response_len))
return -ENOSPC;
- memcpy((priv->buffer + priv->response_len), resdata,
- resdatalen);
+ memcpy(priv->buffer + priv->response_len,
+ &cmd->data.setadapterparms.hdr, resdatalen);
priv->response_len += resdatalen;
if (cmd->data.setadapterparms.hdr.seq_no <
@@ -4890,24 +4872,17 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
QETH_CARD_TEXT(card, 3, "qoatcmd");
- if (!qeth_adp_supported(card, IPA_SETADP_QUERY_OAT)) {
- rc = -EOPNOTSUPP;
- goto out;
- }
+ if (!qeth_adp_supported(card, IPA_SETADP_QUERY_OAT))
+ return -EOPNOTSUPP;
- if (copy_from_user(&oat_data, udata,
- sizeof(struct qeth_query_oat_data))) {
- rc = -EFAULT;
- goto out;
- }
+ if (copy_from_user(&oat_data, udata, sizeof(oat_data)))
+ return -EFAULT;
priv.buffer_len = oat_data.buffer_len;
priv.response_len = 0;
priv.buffer = vzalloc(oat_data.buffer_len);
- if (!priv.buffer) {
- rc = -ENOMEM;
- goto out;
- }
+ if (!priv.buffer)
+ return -ENOMEM;
iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT,
SETADP_DATA_SIZEOF(query_oat));
@@ -4919,30 +4894,19 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
oat_req = &cmd->data.setadapterparms.data.query_oat;
oat_req->subcmd_code = oat_data.command;
- rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_query_oat_cb,
- &priv);
+ rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_query_oat_cb, &priv);
if (!rc) {
- if (is_compat_task())
- tmp = compat_ptr(oat_data.ptr);
- else
- tmp = (void __user *)(unsigned long)oat_data.ptr;
-
- if (copy_to_user(tmp, priv.buffer,
- priv.response_len)) {
- rc = -EFAULT;
- goto out_free;
- }
-
+ tmp = is_compat_task() ? compat_ptr(oat_data.ptr) :
+ u64_to_user_ptr(oat_data.ptr);
oat_data.response_len = priv.response_len;
- if (copy_to_user(udata, &oat_data,
- sizeof(struct qeth_query_oat_data)))
+ if (copy_to_user(tmp, priv.buffer, priv.response_len) ||
+ copy_to_user(udata, &oat_data, sizeof(oat_data)))
rc = -EFAULT;
}
out_free:
vfree(priv.buffer);
-out:
return rc;
}
@@ -5331,9 +5295,12 @@ retriable:
(card->info.hwtrap && qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM)))
card->info.hwtrap = 0;
- rc = qeth_set_access_ctrl_online(card, 0);
- if (rc)
- goto out;
+ if (card->options.isolation != ISOLATION_MODE_NONE) {
+ rc = qeth_setadpparms_set_access_ctrl(card,
+ card->options.isolation);
+ if (rc)
+ goto out;
+ }
rc = qeth_init_qdio_queues(card);
if (rc) {
@@ -5767,6 +5734,7 @@ static unsigned int qeth_extract_skbs(struct qeth_card *card, int budget,
static unsigned int qeth_rx_poll(struct qeth_card *card, int budget)
{
+ struct qeth_rx *ctx = &card->rx;
unsigned int work_done = 0;
while (budget > 0) {
@@ -5802,8 +5770,11 @@ static unsigned int qeth_rx_poll(struct qeth_card *card, int budget)
if (done) {
QETH_CARD_STAT_INC(card, rx_bufs);
qeth_put_buffer_pool_entry(card, buffer->pool_entry);
- qeth_queue_input_buffer(card, card->rx.b_index);
+ buffer->pool_entry = NULL;
card->rx.b_count--;
+ ctx->bufs_refill++;
+ ctx->bufs_refill -= qeth_rx_refill_queue(card,
+ ctx->bufs_refill);
/* Step forward to next buffer: */
card->rx.b_index = QDIO_BUFNR(card->rx.b_index + 1);
@@ -5843,9 +5814,16 @@ int qeth_poll(struct napi_struct *napi, int budget)
if (card->options.cq == QETH_CQ_ENABLED)
qeth_cq_poll(card);
- /* Exhausted the RX budget. Keep IRQ disabled, we get called again. */
- if (budget && work_done >= budget)
- return work_done;
+ if (budget) {
+ struct qeth_rx *ctx = &card->rx;
+
+ /* Process any substantial refill backlog: */
+ ctx->bufs_refill -= qeth_rx_refill_queue(card, ctx->bufs_refill);
+
+ /* Exhausted the RX budget. Keep IRQ disabled, we get called again. */
+ if (work_done >= budget)
+ return work_done;
+ }
if (napi_complete_done(napi, work_done) &&
qdio_start_irq(CARD_DDEV(card)))
@@ -6841,7 +6819,7 @@ netdev_features_t qeth_features_check(struct sk_buff *skb,
/* Traffic with local next-hop is not eligible for some offloads: */
if (skb->ip_summed == CHECKSUM_PARTIAL &&
- card->options.isolation != ISOLATION_MODE_FWD) {
+ READ_ONCE(card->options.isolation) != ISOLATION_MODE_FWD) {
netdev_features_t restricted = 0;
if (skb_is_gso(skb) && !netif_needs_gso(skb, features))
@@ -7032,6 +7010,7 @@ int qeth_stop(struct net_device *dev)
}
napi_disable(&card->napi);
+ cancel_delayed_work_sync(&card->buffer_reclaim_work);
qdio_stop_irq(CARD_DDEV(card));
return 0;
diff --git a/drivers/s390/net/qeth_core_mpc.c b/drivers/s390/net/qeth_core_mpc.c
index e3f4866c158e..68c2588b9dcc 100644
--- a/drivers/s390/net/qeth_core_mpc.c
+++ b/drivers/s390/net/qeth_core_mpc.c
@@ -10,7 +10,7 @@
#include <asm/cio.h>
#include "qeth_core_mpc.h"
-unsigned char IDX_ACTIVATE_READ[] = {
+const unsigned char IDX_ACTIVATE_READ[] = {
0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x19, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc1,
@@ -18,7 +18,7 @@ unsigned char IDX_ACTIVATE_READ[] = {
0x00, 0x00
};
-unsigned char IDX_ACTIVATE_WRITE[] = {
+const unsigned char IDX_ACTIVATE_WRITE[] = {
0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc1,
@@ -26,7 +26,7 @@ unsigned char IDX_ACTIVATE_WRITE[] = {
0x00, 0x00
};
-unsigned char CM_ENABLE[] = {
+const unsigned char CM_ENABLE[] = {
0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x63,
0x10, 0x00, 0x00, 0x01,
@@ -45,7 +45,7 @@ unsigned char CM_ENABLE[] = {
0xff, 0xff, 0xff
};
-unsigned char CM_SETUP[] = {
+const unsigned char CM_SETUP[] = {
0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x64,
0x10, 0x00, 0x00, 0x01,
@@ -65,7 +65,7 @@ unsigned char CM_SETUP[] = {
0x04, 0x06, 0xc8, 0x00
};
-unsigned char ULP_ENABLE[] = {
+const unsigned char ULP_ENABLE[] = {
0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x6b,
0x10, 0x00, 0x00, 0x01,
@@ -85,7 +85,7 @@ unsigned char ULP_ENABLE[] = {
0xf1, 0x00, 0x00
};
-unsigned char ULP_SETUP[] = {
+const unsigned char ULP_SETUP[] = {
0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x6c,
0x10, 0x00, 0x00, 0x01,
@@ -107,7 +107,7 @@ unsigned char ULP_SETUP[] = {
0x00, 0x00, 0x00, 0x00
};
-unsigned char DM_ACT[] = {
+const unsigned char DM_ACT[] = {
0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x55,
0x10, 0x00, 0x00, 0x01,
@@ -123,7 +123,7 @@ unsigned char DM_ACT[] = {
0x05, 0x40, 0x01, 0x01, 0x00
};
-unsigned char IPA_PDU_HEADER[] = {
+const unsigned char IPA_PDU_HEADER[] = {
0x00, 0xe0, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77,
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 9d6f39d8f9ab..b459def0fb26 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -13,13 +13,13 @@
#include <uapi/linux/if_ether.h>
#include <uapi/linux/in6.h>
+extern const unsigned char IPA_PDU_HEADER[];
#define IPA_PDU_HEADER_SIZE 0x40
#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer + 0x0e)
#define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer + 0x26)
#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer + 0x29)
#define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer + 0x3a)
-extern unsigned char IPA_PDU_HEADER[];
#define QETH_IPA_CMD_DEST_ADDR(buffer) (buffer + 0x2c)
#define QETH_SEQ_NO_LENGTH 4
@@ -858,7 +858,7 @@ extern const char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
/* END OF IP Assist related definitions */
/*****************************************************************************/
-extern unsigned char CM_ENABLE[];
+extern const unsigned char CM_ENABLE[];
#define CM_ENABLE_SIZE 0x63
#define QETH_CM_ENABLE_ISSUER_RM_TOKEN(buffer) (buffer + 0x2c)
#define QETH_CM_ENABLE_FILTER_TOKEN(buffer) (buffer + 0x53)
@@ -868,7 +868,7 @@ extern unsigned char CM_ENABLE[];
(PDU_ENCAPSULATION(buffer) + 0x13)
-extern unsigned char CM_SETUP[];
+extern const unsigned char CM_SETUP[];
#define CM_SETUP_SIZE 0x64
#define QETH_CM_SETUP_DEST_ADDR(buffer) (buffer + 0x2c)
#define QETH_CM_SETUP_CONNECTION_TOKEN(buffer) (buffer + 0x51)
@@ -877,7 +877,7 @@ extern unsigned char CM_SETUP[];
#define QETH_CM_SETUP_RESP_DEST_ADDR(buffer) \
(PDU_ENCAPSULATION(buffer) + 0x1a)
-extern unsigned char ULP_ENABLE[];
+extern const unsigned char ULP_ENABLE[];
#define ULP_ENABLE_SIZE 0x6b
#define QETH_ULP_ENABLE_LINKNUM(buffer) (buffer + 0x61)
#define QETH_ULP_ENABLE_DEST_ADDR(buffer) (buffer + 0x2c)
@@ -898,7 +898,7 @@ extern unsigned char ULP_ENABLE[];
#define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer + 0x50)
#define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer + 0x19)
-extern unsigned char ULP_SETUP[];
+extern const unsigned char ULP_SETUP[];
#define ULP_SETUP_SIZE 0x6c
#define QETH_ULP_SETUP_DEST_ADDR(buffer) (buffer + 0x2c)
#define QETH_ULP_SETUP_CONNECTION_TOKEN(buffer) (buffer + 0x51)
@@ -910,7 +910,7 @@ extern unsigned char ULP_SETUP[];
(PDU_ENCAPSULATION(buffer) + 0x1a)
-extern unsigned char DM_ACT[];
+extern const unsigned char DM_ACT[];
#define DM_ACT_SIZE 0x55
#define QETH_DM_ACT_DEST_ADDR(buffer) (buffer + 0x2c)
#define QETH_DM_ACT_CONNECTION_TOKEN(buffer) (buffer + 0x51)
@@ -921,9 +921,8 @@ extern unsigned char DM_ACT[];
#define QETH_PDU_HEADER_SEQ_NO(buffer) (buffer + 0x1c)
#define QETH_PDU_HEADER_ACK_SEQ_NO(buffer) (buffer + 0x20)
-extern unsigned char IDX_ACTIVATE_READ[];
-extern unsigned char IDX_ACTIVATE_WRITE[];
-
+extern const unsigned char IDX_ACTIVATE_READ[];
+extern const unsigned char IDX_ACTIVATE_WRITE[];
#define IDX_ACTIVATE_SIZE 0x22
#define QETH_IDX_ACT_PNO(buffer) (buffer+0x0b)
#define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer + 0x0c)
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index c901c942fed7..8def82336f53 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -448,19 +448,17 @@ static ssize_t qeth_dev_isolation_store(struct device *dev,
rc = -EINVAL;
goto out;
}
- rc = count;
-
- /* defer IP assist if device is offline (until discipline->set_online)*/
- card->options.prev_isolation = card->options.isolation;
- card->options.isolation = isolation;
- if (qeth_card_hw_is_reachable(card)) {
- int ipa_rc = qeth_set_access_ctrl_online(card, 1);
- if (ipa_rc != 0)
- rc = ipa_rc;
- }
+
+ if (qeth_card_hw_is_reachable(card))
+ rc = qeth_setadpparms_set_access_ctrl(card, isolation);
+
+ if (!rc)
+ WRITE_ONCE(card->options.isolation, isolation);
+
out:
mutex_unlock(&card->conf_mutex);
- return rc;
+
+ return rc ? rc : count;
}
static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 2d3bca3c0141..8b342a88ff5c 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -156,7 +156,7 @@ static void qeth_l2_drain_rx_mode_cache(struct qeth_card *card)
struct hlist_node *tmp;
int i;
- hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
+ hash_for_each_safe(card->rx_mode_addrs, i, tmp, mac, hnode) {
hash_del(&mac->hnode);
kfree(mac);
}
@@ -285,7 +285,6 @@ static void qeth_l2_stop_card(struct qeth_card *card)
if (card->state == CARD_STATE_SOFTSETUP) {
qeth_clear_ipacmd_list(card);
qeth_drain_output_queues(card);
- cancel_delayed_work_sync(&card->buffer_reclaim_work);
card->state = CARD_STATE_DOWN;
}
@@ -438,7 +437,7 @@ static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha)
u32 mac_hash = get_unaligned((u32 *)(&ha->addr[2]));
struct qeth_mac *mac;
- hash_for_each_possible(card->mac_htable, mac, hnode, mac_hash) {
+ hash_for_each_possible(card->rx_mode_addrs, mac, hnode, mac_hash) {
if (ether_addr_equal_64bits(ha->addr, mac->mac_addr)) {
mac->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
return;
@@ -452,7 +451,7 @@ static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha)
ether_addr_copy(mac->mac_addr, ha->addr);
mac->disp_flag = QETH_DISP_ADDR_ADD;
- hash_add(card->mac_htable, &mac->hnode, mac_hash);
+ hash_add(card->rx_mode_addrs, &mac->hnode, mac_hash);
}
static void qeth_l2_rx_mode_work(struct work_struct *work)
@@ -475,7 +474,7 @@ static void qeth_l2_rx_mode_work(struct work_struct *work)
qeth_l2_add_mac(card, ha);
netif_addr_unlock_bh(dev);
- hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
+ hash_for_each_safe(card->rx_mode_addrs, i, tmp, mac, hnode) {
switch (mac->disp_flag) {
case QETH_DISP_ADDR_DELETE:
qeth_l2_remove_mac(card, mac->mac_addr);
@@ -601,7 +600,6 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
return rc;
}
- hash_init(card->mac_htable);
INIT_WORK(&card->rx_mode_work, qeth_l2_rx_mode_work);
return 0;
}
@@ -1142,6 +1140,10 @@ static void qeth_bridge_state_change(struct qeth_card *card,
int extrasize;
QETH_CARD_TEXT(card, 2, "brstchng");
+ if (qports->num_entries == 0) {
+ QETH_CARD_TEXT(card, 2, "BPempty");
+ return;
+ }
if (qports->entry_length != sizeof(struct qeth_sbp_port_entry)) {
QETH_CARD_TEXT_(card, 2, "BPsz%04x", qports->entry_length);
return;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 1e50aa0297a3..fe44b0249e34 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -58,7 +58,7 @@ static struct qeth_ipaddr *qeth_l3_find_addr_by_ip(struct qeth_card *card,
struct qeth_ipaddr *addr;
if (query->is_multicast) {
- hash_for_each_possible(card->ip_mc_htable, addr, hnode, key)
+ hash_for_each_possible(card->rx_mode_addrs, addr, hnode, key)
if (qeth_l3_addr_match_ip(addr, query))
return addr;
} else {
@@ -239,7 +239,7 @@ static void qeth_l3_drain_rx_mode_cache(struct qeth_card *card)
struct hlist_node *tmp;
int i;
- hash_for_each_safe(card->ip_mc_htable, i, tmp, addr, hnode) {
+ hash_for_each_safe(card->rx_mode_addrs, i, tmp, addr, hnode) {
hash_del(&addr->hnode);
kfree(addr);
}
@@ -1093,7 +1093,7 @@ static int qeth_l3_add_mcast_rtnl(struct net_device *dev, int vid, void *arg)
if (!ipm)
continue;
- hash_add(card->ip_mc_htable, &ipm->hnode,
+ hash_add(card->rx_mode_addrs, &ipm->hnode,
qeth_l3_ipaddr_hash(ipm));
}
@@ -1124,8 +1124,8 @@ walk_ipv6:
if (!ipm)
continue;
- hash_add(card->ip_mc_htable,
- &ipm->hnode, qeth_l3_ipaddr_hash(ipm));
+ hash_add(card->rx_mode_addrs, &ipm->hnode,
+ qeth_l3_ipaddr_hash(ipm));
}
read_unlock_bh(&in6_dev->lock);
@@ -1169,7 +1169,6 @@ static void qeth_l3_stop_card(struct qeth_card *card)
qeth_l3_clear_ip_htable(card, 1);
qeth_clear_ipacmd_list(card);
qeth_drain_output_queues(card);
- cancel_delayed_work_sync(&card->buffer_reclaim_work);
card->state = CARD_STATE_DOWN;
}
@@ -1219,7 +1218,7 @@ static void qeth_l3_rx_mode_work(struct work_struct *work)
vlan_for_each(card->dev, qeth_l3_add_mcast_rtnl, card);
rtnl_unlock();
- hash_for_each_safe(card->ip_mc_htable, i, tmp, addr, hnode) {
+ hash_for_each_safe(card->rx_mode_addrs, i, tmp, addr, hnode) {
switch (addr->disp_flag) {
case QETH_DISP_ADDR_DELETE:
rc = qeth_l3_deregister_addr_entry(card, addr);
@@ -1919,12 +1918,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
return rc;
if (IS_OSD(card) || IS_OSX(card)) {
- if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
- (card->info.link_type == QETH_LINK_TYPE_HSTR)) {
- pr_info("qeth_l3: ignoring TR device\n");
- return -ENODEV;
- }
-
card->dev->netdev_ops = &qeth_l3_osa_netdev_ops;
/*IPv6 address autoconfiguration stuff*/
@@ -2004,7 +1997,6 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
}
}
- hash_init(card->ip_mc_htable);
INIT_WORK(&card->rx_mode_work, qeth_l3_rx_mode_work);
return 0;
}
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index 36b1ca2dadbb..6e77e4908605 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -13,6 +13,7 @@
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/kthread.h>
+#include <linux/phylink.h>
#include <scsi/libfc.h>
#include <scsi/scsi_host.h>
#include <scsi/fc_frame.h>
@@ -440,6 +441,7 @@ static void qedf_link_recovery(struct work_struct *work)
static void qedf_update_link_speed(struct qedf_ctx *qedf,
struct qed_link_output *link)
{
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(sup_caps);
struct fc_lport *lport = qedf->lport;
lport->link_speed = FC_PORTSPEED_UNKNOWN;
@@ -474,40 +476,60 @@ static void qedf_update_link_speed(struct qedf_ctx *qedf,
* Set supported link speed by querying the supported
* capabilities of the link.
*/
- if ((link->supported_caps & QED_LM_10000baseT_Full_BIT) ||
- (link->supported_caps & QED_LM_10000baseKX4_Full_BIT) ||
- (link->supported_caps & QED_LM_10000baseR_FEC_BIT) ||
- (link->supported_caps & QED_LM_10000baseCR_Full_BIT) ||
- (link->supported_caps & QED_LM_10000baseSR_Full_BIT) ||
- (link->supported_caps & QED_LM_10000baseLR_Full_BIT) ||
- (link->supported_caps & QED_LM_10000baseLRM_Full_BIT) ||
- (link->supported_caps & QED_LM_10000baseKR_Full_BIT)) {
+
+ phylink_zero(sup_caps);
+ phylink_set(sup_caps, 10000baseT_Full);
+ phylink_set(sup_caps, 10000baseKX4_Full);
+ phylink_set(sup_caps, 10000baseR_FEC);
+ phylink_set(sup_caps, 10000baseCR_Full);
+ phylink_set(sup_caps, 10000baseSR_Full);
+ phylink_set(sup_caps, 10000baseLR_Full);
+ phylink_set(sup_caps, 10000baseLRM_Full);
+ phylink_set(sup_caps, 10000baseKR_Full);
+
+ if (linkmode_intersects(link->supported_caps, sup_caps))
lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
- }
- if ((link->supported_caps & QED_LM_25000baseKR_Full_BIT) ||
- (link->supported_caps & QED_LM_25000baseCR_Full_BIT) ||
- (link->supported_caps & QED_LM_25000baseSR_Full_BIT)) {
+
+ phylink_zero(sup_caps);
+ phylink_set(sup_caps, 25000baseKR_Full);
+ phylink_set(sup_caps, 25000baseCR_Full);
+ phylink_set(sup_caps, 25000baseSR_Full);
+
+ if (linkmode_intersects(link->supported_caps, sup_caps))
lport->link_supported_speeds |= FC_PORTSPEED_25GBIT;
- }
- if ((link->supported_caps & QED_LM_40000baseLR4_Full_BIT) ||
- (link->supported_caps & QED_LM_40000baseKR4_Full_BIT) ||
- (link->supported_caps & QED_LM_40000baseCR4_Full_BIT) ||
- (link->supported_caps & QED_LM_40000baseSR4_Full_BIT)) {
+
+ phylink_zero(sup_caps);
+ phylink_set(sup_caps, 40000baseLR4_Full);
+ phylink_set(sup_caps, 40000baseKR4_Full);
+ phylink_set(sup_caps, 40000baseCR4_Full);
+ phylink_set(sup_caps, 40000baseSR4_Full);
+
+ if (linkmode_intersects(link->supported_caps, sup_caps))
lport->link_supported_speeds |= FC_PORTSPEED_40GBIT;
- }
- if ((link->supported_caps & QED_LM_50000baseKR2_Full_BIT) ||
- (link->supported_caps & QED_LM_50000baseCR2_Full_BIT) ||
- (link->supported_caps & QED_LM_50000baseSR2_Full_BIT)) {
+
+ phylink_zero(sup_caps);
+ phylink_set(sup_caps, 50000baseKR2_Full);
+ phylink_set(sup_caps, 50000baseCR2_Full);
+ phylink_set(sup_caps, 50000baseSR2_Full);
+
+ if (linkmode_intersects(link->supported_caps, sup_caps))
lport->link_supported_speeds |= FC_PORTSPEED_50GBIT;
- }
- if ((link->supported_caps & QED_LM_100000baseKR4_Full_BIT) ||
- (link->supported_caps & QED_LM_100000baseSR4_Full_BIT) ||
- (link->supported_caps & QED_LM_100000baseCR4_Full_BIT) ||
- (link->supported_caps & QED_LM_100000baseLR4_ER4_Full_BIT)) {
+
+ phylink_zero(sup_caps);
+ phylink_set(sup_caps, 100000baseKR4_Full);
+ phylink_set(sup_caps, 100000baseSR4_Full);
+ phylink_set(sup_caps, 100000baseCR4_Full);
+ phylink_set(sup_caps, 100000baseLR4_ER4_Full);
+
+ if (linkmode_intersects(link->supported_caps, sup_caps))
lport->link_supported_speeds |= FC_PORTSPEED_100GBIT;
- }
- if (link->supported_caps & QED_LM_20000baseKR2_Full_BIT)
+
+ phylink_zero(sup_caps);
+ phylink_set(sup_caps, 20000baseKR2_Full);
+
+ if (linkmode_intersects(link->supported_caps, sup_caps))
lport->link_supported_speeds |= FC_PORTSPEED_20GBIT;
+
fc_host_supported_speeds(lport->host) = lport->link_supported_speeds;
}
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 6c647ba4ba0b..823dc99be46f 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -238,7 +238,7 @@ static void chipco_powercontrol_init(struct ssb_chipcommon *cc)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */
+/* https://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */
static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc)
{
struct ssb_bus *bus = cc->dev->bus;
@@ -255,7 +255,7 @@ static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */
+/* https://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */
static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)
{
struct ssb_bus *bus = cc->dev->bus;
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index 0f60e90ded26..888069e10659 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -513,7 +513,7 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc)
chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk);
}
-/* http://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */
+/* https://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */
void ssb_pmu_init(struct ssb_chipcommon *cc)
{
u32 pmucap;
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
index 42d620cee8a9..7cd553127861 100644
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -186,7 +186,7 @@ int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out)
return get_fallback_sprom(bus, out);
}
-/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
+/* https://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
bool ssb_is_sprom_available(struct ssb_bus *bus)
{
/* status register only exists on chipcomon rev >= 11 and we need check
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 4ec5528f89fa..b3fb4d41e231 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -84,8 +84,6 @@ source "drivers/staging/fbtft/Kconfig"
source "drivers/staging/fsl-dpaa2/Kconfig"
-source "drivers/staging/wilc1000/Kconfig"
-
source "drivers/staging/most/Kconfig"
source "drivers/staging/ks7010/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 4d34198151b3..3d8c7ea21a10 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -32,7 +32,6 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/
obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/
obj-$(CONFIG_FB_TFT) += fbtft/
obj-$(CONFIG_FSL_DPAA2) += fsl-dpaa2/
-obj-$(CONFIG_WILC1000) += wilc1000/
obj-$(CONFIG_MOST) += most/
obj-$(CONFIG_KS7010) += ks7010/
obj-$(CONFIG_GREYBUS) += greybus/
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index c798672d61b2..cfb673a52b25 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -163,7 +163,7 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
of_node_put(phy_node);
if (!phydev)
- return -ENODEV;
+ return -EPROBE_DEFER;
priv->last_link = 0;
phy_start(phydev);
diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h
index e3771d48c49b..7f6716e3fad4 100644
--- a/drivers/staging/octeon/ethernet-mdio.h
+++ b/drivers/staging/octeon/ethernet-mdio.h
@@ -22,7 +22,5 @@
extern const struct ethtool_ops cvm_oct_ethtool_ops;
-void octeon_mdiobus_force_mod_depencency(void);
-
int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
int cvm_oct_phy_setup_device(struct net_device *dev);
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index f42c3816ce49..204f0b1e2739 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -689,8 +689,6 @@ static int cvm_oct_probe(struct platform_device *pdev)
mtu_overhead += VLAN_HLEN;
#endif
- octeon_mdiobus_force_mod_depencency();
-
pip = pdev->dev.of_node;
if (!pip) {
pr_err("Error: No 'pip' in /aliases\n");
@@ -987,6 +985,7 @@ static struct platform_driver cvm_oct_driver = {
module_platform_driver(cvm_oct_driver);
+MODULE_SOFTDEP("pre: mdio-cavium");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver.");
diff --git a/drivers/staging/wilc1000/microchip,wilc1000.yaml b/drivers/staging/wilc1000/microchip,wilc1000.yaml
deleted file mode 100644
index 2c320eb2a8c4..000000000000
--- a/drivers/staging/wilc1000/microchip,wilc1000.yaml
+++ /dev/null
@@ -1,71 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/net/wireless/microchip,wilc1000.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Microchip WILC wireless devicetree bindings
-
-maintainers:
- - Adham Abozaeid <adham.abozaeid@microchip.com>
- - Ajay Singh <ajay.kathat@microchip.com>
-
-description:
- The wilc1000 chips can be connected via SPI or SDIO. This document
- describes the binding to connect wilc devices.
-
-properties:
- compatible:
- const: microchip,wilc1000
-
- spi-max-frequency: true
-
- interrupts:
- maxItems: 1
-
- clocks:
- description: phandle to the clock connected on rtc clock line.
- maxItems: 1
-
- clock-names:
- const: rtc
-
-required:
- - compatible
- - interrupts
-
-examples:
- - |
- spi {
- #address-cells = <1>;
- #size-cells = <0>;
- wifi@0 {
- compatible = "microchip,wilc1000";
- spi-max-frequency = <48000000>;
- reg = <0>;
- interrupt-parent = <&pioC>;
- interrupts = <27 0>;
- clocks = <&pck1>;
- clock-names = "rtc";
- };
- };
-
- - |
- mmc {
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>;
- non-removable;
- vmmc-supply = <&vcc_mmc1_reg>;
- vqmmc-supply = <&vcc_3v3_reg>;
- bus-width = <4>;
- wifi@0 {
- compatible = "microchip,wilc1000";
- reg = <0>;
- interrupt-parent = <&pioC>;
- interrupts = <27 0>;
- clocks = <&pck1>;
- clock-names = "rtc";
- };
- };