diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-16 04:42:13 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-16 04:42:13 +0300 |
commit | 9ff9b0d392ea08090cd1780fb196f36dbb586529 (patch) | |
tree | 276a3a5c4525b84dee64eda30b423fc31bf94850 /drivers/net/ethernet/hisilicon/hns3 | |
parent | 840e5bb326bbcb16ce82dd2416d2769de4839aea (diff) | |
parent | 105faa8742437c28815b2a3eb8314ebc5fd9288c (diff) | |
download | linux-9ff9b0d392ea08090cd1780fb196f36dbb586529.tar.xz |
Merge tag 'net-next-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Jakub Kicinski:
- Add redirect_neigh() BPF packet redirect helper, allowing to limit
stack traversal in common container configs and improving TCP
back-pressure.
Daniel reports ~10Gbps => ~15Gbps single stream TCP performance gain.
- Expand netlink policy support and improve policy export to user
space. (Ge)netlink core performs request validation according to
declared policies. Expand the expressiveness of those policies
(min/max length and bitmasks). Allow dumping policies for particular
commands. This is used for feature discovery by user space (instead
of kernel version parsing or trial and error).
- Support IGMPv3/MLDv2 multicast listener discovery protocols in
bridge.
- Allow more than 255 IPv4 multicast interfaces.
- Add support for Type of Service (ToS) reflection in SYN/SYN-ACK
packets of TCPv6.
- In Multi-patch TCP (MPTCP) support concurrent transmission of data on
multiple subflows in a load balancing scenario. Enhance advertising
addresses via the RM_ADDR/ADD_ADDR options.
- Support SMC-Dv2 version of SMC, which enables multi-subnet
deployments.
- Allow more calls to same peer in RxRPC.
- Support two new Controller Area Network (CAN) protocols - CAN-FD and
ISO 15765-2:2016.
- Add xfrm/IPsec compat layer, solving the 32bit user space on 64bit
kernel problem.
- Add TC actions for implementing MPLS L2 VPNs.
- Improve nexthop code - e.g. handle various corner cases when nexthop
objects are removed from groups better, skip unnecessary
notifications and make it easier to offload nexthops into HW by
converting to a blocking notifier.
- Support adding and consuming TCP header options by BPF programs,
opening the doors for easy experimental and deployment-specific TCP
option use.
- Reorganize TCP congestion control (CC) initialization to simplify
life of TCP CC implemented in BPF.
- Add support for shipping BPF programs with the kernel and loading
them early on boot via the User Mode Driver mechanism, hence reusing
all the user space infra we have.
- Support sleepable BPF programs, initially targeting LSM and tracing.
- Add bpf_d_path() helper for returning full path for given 'struct
path'.
- Make bpf_tail_call compatible with bpf-to-bpf calls.
- Allow BPF programs to call map_update_elem on sockmaps.
- Add BPF Type Format (BTF) support for type and enum discovery, as
well as support for using BTF within the kernel itself (current use
is for pretty printing structures).
- Support listing and getting information about bpf_links via the bpf
syscall.
- Enhance kernel interfaces around NIC firmware update. Allow
specifying overwrite mask to control if settings etc. are reset
during update; report expected max time operation may take to users;
support firmware activation without machine reboot incl. limits of
how much impact reset may have (e.g. dropping link or not).
- Extend ethtool configuration interface to report IEEE-standard
counters, to limit the need for per-vendor logic in user space.
- Adopt or extend devlink use for debug, monitoring, fw update in many
drivers (dsa loop, ice, ionic, sja1105, qed, mlxsw, mv88e6xxx,
dpaa2-eth).
- In mlxsw expose critical and emergency SFP module temperature alarms.
Refactor port buffer handling to make the defaults more suitable and
support setting these values explicitly via the DCBNL interface.
- Add XDP support for Intel's igb driver.
- Support offloading TC flower classification and filtering rules to
mscc_ocelot switches.
- Add PTP support for Marvell Octeontx2 and PP2.2 hardware, as well as
fixed interval period pulse generator and one-step timestamping in
dpaa-eth.
- Add support for various auth offloads in WiFi APs, e.g. SAE (WPA3)
offload.
- Add Lynx PHY/PCS MDIO module, and convert various drivers which have
this HW to use it. Convert mvpp2 to split PCS.
- Support Marvell Prestera 98DX3255 24-port switch ASICs, as well as
7-port Mediatek MT7531 IP.
- Add initial support for QCA6390 and IPQ6018 in ath11k WiFi driver,
and wcn3680 support in wcn36xx.
- Improve performance for packets which don't require much offloads on
recent Mellanox NICs by 20% by making multiple packets share a
descriptor entry.
- Move chelsio inline crypto drivers (for TLS and IPsec) from the
crypto subtree to drivers/net. Move MDIO drivers out of the phy
directory.
- Clean up a lot of W=1 warnings, reportedly the actively developed
subsections of networking drivers should now build W=1 warning free.
- Make sure drivers don't use in_interrupt() to dynamically adapt their
code. Convert tasklets to use new tasklet_setup API (sadly this
conversion is not yet complete).
* tag 'net-next-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2583 commits)
Revert "bpfilter: Fix build error with CONFIG_BPFILTER_UMH"
net, sockmap: Don't call bpf_prog_put() on NULL pointer
bpf, selftest: Fix flaky tcp_hdr_options test when adding addr to lo
bpf, sockmap: Add locking annotations to iterator
netfilter: nftables: allow re-computing sctp CRC-32C in 'payload' statements
net: fix pos incrementment in ipv6_route_seq_next
net/smc: fix invalid return code in smcd_new_buf_create()
net/smc: fix valid DMBE buffer sizes
net/smc: fix use-after-free of delayed events
bpfilter: Fix build error with CONFIG_BPFILTER_UMH
cxgb4/ch_ipsec: Replace the module name to ch_ipsec from chcr
net: sched: Fix suspicious RCU usage while accessing tcf_tunnel_info
bpf: Fix register equivalence tracking.
rxrpc: Fix loss of final ack on shutdown
rxrpc: Fix bundle counting for exclusive connections
netfilter: restore NF_INET_NUMHOOKS
ibmveth: Identify ingress large send packets.
ibmveth: Switch order of ibmveth_helper calls.
cxgb4: handle 4-tuple PEDIT to NAT mode translation
selftests: Add VRF route leaking tests
...
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3')
20 files changed, 975 insertions, 383 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 088550db2de7..912c51e327d6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -34,6 +34,13 @@ #define HNAE3_MIN_VECTOR_NUM 2 /* first one for misc, another for IO */ +/* Device version */ +#define HNAE3_DEVICE_VERSION_V1 0x00020 +#define HNAE3_DEVICE_VERSION_V2 0x00021 +#define HNAE3_DEVICE_VERSION_V3 0x00030 + +#define HNAE3_PCI_REVISION_BIT_SIZE 8 + /* Device IDs */ #define HNAE3_DEV_ID_GE 0xA220 #define HNAE3_DEV_ID_25GE 0xA221 @@ -42,8 +49,9 @@ #define HNAE3_DEV_ID_50GE_RDMA 0xA224 #define HNAE3_DEV_ID_50GE_RDMA_MACSEC 0xA225 #define HNAE3_DEV_ID_100G_RDMA_MACSEC 0xA226 -#define HNAE3_DEV_ID_100G_VF 0xA22E -#define HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF 0xA22F +#define HNAE3_DEV_ID_200G_RDMA 0xA228 +#define HNAE3_DEV_ID_VF 0xA22E +#define HNAE3_DEV_ID_RDMA_DCB_PFC_VF 0xA22F #define HNAE3_CLASS_NAME_SIZE 16 @@ -53,8 +61,6 @@ #define HNAE3_KNIC_CLIENT_INITED_B 0x3 #define HNAE3_UNIC_CLIENT_INITED_B 0x4 #define HNAE3_ROCE_CLIENT_INITED_B 0x5 -#define HNAE3_DEV_SUPPORT_FD_B 0x6 -#define HNAE3_DEV_SUPPORT_GRO_B 0x7 #define HNAE3_DEV_SUPPORT_ROCE_DCB_BITS (BIT(HNAE3_DEV_SUPPORT_DCB_B) |\ BIT(HNAE3_DEV_SUPPORT_ROCE_B)) @@ -65,11 +71,67 @@ #define hnae3_dev_dcb_supported(hdev) \ hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_DCB_B) +enum HNAE3_DEV_CAP_BITS { + HNAE3_DEV_SUPPORT_FD_B, + HNAE3_DEV_SUPPORT_GRO_B, + HNAE3_DEV_SUPPORT_FEC_B, + HNAE3_DEV_SUPPORT_UDP_GSO_B, + HNAE3_DEV_SUPPORT_QB_B, + HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B, + HNAE3_DEV_SUPPORT_PTP_B, + HNAE3_DEV_SUPPORT_INT_QL_B, + HNAE3_DEV_SUPPORT_SIMPLE_BD_B, + HNAE3_DEV_SUPPORT_TX_PUSH_B, + HNAE3_DEV_SUPPORT_PHY_IMP_B, + HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B, + HNAE3_DEV_SUPPORT_HW_PAD_B, + HNAE3_DEV_SUPPORT_STASH_B, +}; + #define hnae3_dev_fd_supported(hdev) \ - hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_FD_B) + test_bit(HNAE3_DEV_SUPPORT_FD_B, (hdev)->ae_dev->caps) #define hnae3_dev_gro_supported(hdev) \ - hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_GRO_B) + test_bit(HNAE3_DEV_SUPPORT_GRO_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_fec_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_FEC_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_udp_gso_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_qb_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_QB_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_fd_forward_tc_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_ptp_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_PTP_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_int_ql_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_simple_bd_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_SIMPLE_BD_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_tx_push_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_TX_PUSH_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_phy_imp_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_tqp_txrx_indep_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_hw_pad_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_HW_PAD_B, (hdev)->ae_dev->caps) + +#define hnae3_dev_stash_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_STASH_B, (hdev)->ae_dev->caps) + +#define hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev) \ + test_bit(HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B, (ae_dev)->caps) #define ring_ptr_move_fw(ring, p) \ ((ring)->p = ((ring)->p + 1) % (ring)->desc_num) @@ -152,6 +214,7 @@ enum hnae3_hw_error_type { HNAE3_PPU_POISON_ERROR, HNAE3_CMDQ_ECC_ERROR, HNAE3_IMP_RD_POISON_ERROR, + HNAE3_ROCEE_AXI_RESP_ERROR, }; enum hnae3_reset_type { @@ -207,6 +270,17 @@ struct hnae3_ring_chain_node { #define HNAE3_IS_TX_RING(node) \ (((node)->flag & (1 << HNAE3_RING_TYPE_B)) == HNAE3_RING_TYPE_TX) +/* device specification info from firmware */ +struct hnae3_dev_specs { + u32 mac_entry_num; /* number of mac-vlan table entry */ + u32 mng_entry_num; /* number of manager table entry */ + u32 max_tm_rate; + u16 rss_ind_tbl_size; + u16 rss_key_size; + u16 int_ql_max; /* max value of interrupt coalesce based on INT_QL */ + u8 max_non_tso_bd_num; /* max BD number of one non-TSO packet */ +}; + struct hnae3_client_ops { int (*init_instance)(struct hnae3_handle *handle); void (*uninit_instance)(struct hnae3_handle *handle, bool reset); @@ -227,12 +301,16 @@ struct hnae3_client { struct list_head node; }; +#define HNAE3_DEV_CAPS_MAX_NUM 96 struct hnae3_ae_dev { struct pci_dev *pdev; const struct hnae3_ae_ops *ops; struct list_head node; u32 flag; unsigned long hw_err_reset_req; + struct hnae3_dev_specs dev_specs; + u32 dev_version; + unsigned long caps[BITS_TO_LONGS(HNAE3_DEV_CAPS_MAX_NUM)]; void *priv; }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index fe7fb565da19..dc9a85745e62 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -15,11 +15,12 @@ static struct dentry *hns3_dbgfs_root; static int hns3_dbg_queue_info(struct hnae3_handle *h, const char *cmd_buf) { + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); struct hns3_nic_priv *priv = h->priv; struct hns3_enet_ring *ring; u32 base_add_l, base_add_h; u32 queue_num, queue_max; - u32 value, i = 0; + u32 value, i; int cnt; if (!priv->ring) { @@ -118,8 +119,25 @@ static int hns3_dbg_queue_info(struct hnae3_handle *h, value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_PKTNUM_RECORD_REG); - dev_info(&h->pdev->dev, "TX(%u) RING PKTNUM: %u\n\n", i, - value); + dev_info(&h->pdev->dev, "TX(%u) RING PKTNUM: %u\n", i, value); + + value = readl_relaxed(ring->tqp->io_base + HNS3_RING_EN_REG); + dev_info(&h->pdev->dev, "TX/RX(%u) RING EN: %s\n", i, + value ? "enable" : "disable"); + + if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) { + value = readl_relaxed(ring->tqp->io_base + + HNS3_RING_TX_EN_REG); + dev_info(&h->pdev->dev, "TX(%u) RING EN: %s\n", i, + value ? "enable" : "disable"); + + value = readl_relaxed(ring->tqp->io_base + + HNS3_RING_RX_EN_REG); + dev_info(&h->pdev->dev, "RX(%u) RING EN: %s\n", i, + value ? "enable" : "disable"); + } + + dev_info(&h->pdev->dev, "\n"); } return 0; @@ -244,6 +262,8 @@ static void hns3_dbg_help(struct hnae3_handle *h) dev_info(&h->pdev->dev, "queue info <number>\n"); dev_info(&h->pdev->dev, "queue map\n"); dev_info(&h->pdev->dev, "bd info <q_num> <bd index>\n"); + dev_info(&h->pdev->dev, "dev capability\n"); + dev_info(&h->pdev->dev, "dev spec\n"); if (!hns3_is_phys_func(h->pdev)) return; @@ -264,6 +284,7 @@ static void hns3_dbg_help(struct hnae3_handle *h) dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n"); dev_info(&h->pdev->dev, "dump uc mac list <func id>\n"); dev_info(&h->pdev->dev, "dump mc mac list <func id>\n"); + dev_info(&h->pdev->dev, "dump intr\n"); memset(printf_buf, 0, HNS3_DBG_BUF_LEN); strncat(printf_buf, "dump reg [[bios common] [ssu <port_id>]", @@ -284,6 +305,52 @@ static void hns3_dbg_help(struct hnae3_handle *h) dev_info(&h->pdev->dev, "%s", printf_buf); } +static void hns3_dbg_dev_caps(struct hnae3_handle *h) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); + unsigned long *caps; + + caps = ae_dev->caps; + + dev_info(&h->pdev->dev, "support FD: %s\n", + test_bit(HNAE3_DEV_SUPPORT_FD_B, caps) ? "yes" : "no"); + dev_info(&h->pdev->dev, "support GRO: %s\n", + test_bit(HNAE3_DEV_SUPPORT_GRO_B, caps) ? "yes" : "no"); + dev_info(&h->pdev->dev, "support FEC: %s\n", + test_bit(HNAE3_DEV_SUPPORT_FEC_B, caps) ? "yes" : "no"); + dev_info(&h->pdev->dev, "support UDP GSO: %s\n", + test_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, caps) ? "yes" : "no"); + dev_info(&h->pdev->dev, "support PTP: %s\n", + test_bit(HNAE3_DEV_SUPPORT_PTP_B, caps) ? "yes" : "no"); + dev_info(&h->pdev->dev, "support INT QL: %s\n", + test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, caps) ? "yes" : "no"); +} + +static void hns3_dbg_dev_specs(struct hnae3_handle *h) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); + struct hnae3_dev_specs *dev_specs = &ae_dev->dev_specs; + struct hnae3_knic_private_info *kinfo = &h->kinfo; + struct hns3_nic_priv *priv = h->priv; + + dev_info(priv->dev, "MAC entry num: %u\n", dev_specs->mac_entry_num); + dev_info(priv->dev, "MNG entry num: %u\n", dev_specs->mng_entry_num); + dev_info(priv->dev, "MAX non tso bd num: %u\n", + dev_specs->max_non_tso_bd_num); + dev_info(priv->dev, "RSS ind tbl size: %u\n", + dev_specs->rss_ind_tbl_size); + dev_info(priv->dev, "RSS key size: %u\n", dev_specs->rss_key_size); + dev_info(priv->dev, "RSS size: %u\n", kinfo->rss_size); + dev_info(priv->dev, "Allocated RSS size: %u\n", kinfo->req_rss_size); + dev_info(priv->dev, "Task queue pairs numbers: %u\n", kinfo->num_tqps); + + dev_info(priv->dev, "RX buffer length: %u\n", kinfo->rx_buf_len); + dev_info(priv->dev, "Desc num per TX queue: %u\n", kinfo->num_tx_desc); + dev_info(priv->dev, "Desc num per RX queue: %u\n", kinfo->num_rx_desc); + dev_info(priv->dev, "Total number of enabled TCs: %u\n", kinfo->num_tc); + dev_info(priv->dev, "MAX INT QL: %u\n", dev_specs->int_ql_max); +} + static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) { @@ -359,6 +426,10 @@ static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer, ret = hns3_dbg_queue_map(handle); else if (strncmp(cmd_buf, "bd info", 7) == 0) ret = hns3_dbg_bd_info(handle, cmd_buf); + else if (strncmp(cmd_buf, "dev capability", 14) == 0) + hns3_dbg_dev_caps(handle); + else if (strncmp(cmd_buf, "dev spec", 8) == 0) + hns3_dbg_dev_specs(handle); else if (handle->ae_algo->ops->dbg_run_cmd) ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf); else diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index a4f1d515e5e0..a362516a3185 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -81,8 +81,10 @@ static const struct pci_device_id hns3_pci_tbl[] = { HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, - {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_VF), 0}, - {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF), + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_200G_RDMA), + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_VF), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_RDMA_DCB_PFC_VF), HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, /* required last entry */ {0, } @@ -623,27 +625,15 @@ void hns3_request_update_promisc_mode(struct hnae3_handle *handle) ops->request_update_promisc_mode(handle); } -int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags) -{ - struct hns3_nic_priv *priv = netdev_priv(netdev); - struct hnae3_handle *h = priv->ae_handle; - - if (h->ae_algo->ops->set_promisc_mode) { - return h->ae_algo->ops->set_promisc_mode(h, - promisc_flags & HNAE3_UPE, - promisc_flags & HNAE3_MPE); - } - - return 0; -} - void hns3_enable_vlan_filter(struct net_device *netdev, bool enable) { struct hns3_nic_priv *priv = netdev_priv(netdev); struct hnae3_handle *h = priv->ae_handle; + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); bool last_state; - if (h->pdev->revision >= 0x21 && h->ae_algo->ops->enable_vlan_filter) { + if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2 && + h->ae_algo->ops->enable_vlan_filter) { last_state = h->netdev_flags & HNAE3_VLAN_FLTR ? true : false; if (enable != last_state) { netdev_info(netdev, @@ -706,12 +696,19 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen, /* normal or tunnel packet */ l4_offset = l4.hdr - skb->data; - hdr_len = (l4.tcp->doff << 2) + l4_offset; /* remove payload length from inner pseudo checksum when tso */ l4_paylen = skb->len - l4_offset; - csum_replace_by_diff(&l4.tcp->check, - (__force __wsum)htonl(l4_paylen)); + + if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) { + hdr_len = sizeof(*l4.udp) + l4_offset; + csum_replace_by_diff(&l4.udp->check, + (__force __wsum)htonl(l4_paylen)); + } else { + hdr_len = (l4.tcp->doff << 2) + l4_offset; + csum_replace_by_diff(&l4.tcp->check, + (__force __wsum)htonl(l4_paylen)); + } /* find the txbd field values */ *paylen = skb->len - hdr_len; @@ -1194,21 +1191,23 @@ static unsigned int hns3_skb_bd_num(struct sk_buff *skb, unsigned int *bd_size, return bd_num; } -static unsigned int hns3_tx_bd_num(struct sk_buff *skb, unsigned int *bd_size) +static unsigned int hns3_tx_bd_num(struct sk_buff *skb, unsigned int *bd_size, + u8 max_non_tso_bd_num) { struct sk_buff *frag_skb; unsigned int bd_num = 0; /* If the total len is within the max bd limit */ if (likely(skb->len <= HNS3_MAX_BD_SIZE && !skb_has_frag_list(skb) && - skb_shinfo(skb)->nr_frags < HNS3_MAX_NON_TSO_BD_NUM)) + skb_shinfo(skb)->nr_frags < max_non_tso_bd_num)) return skb_shinfo(skb)->nr_frags + 1U; /* The below case will always be linearized, return * HNS3_MAX_BD_NUM_TSO + 1U to make sure it is linearized. */ if (unlikely(skb->len > HNS3_MAX_TSO_SIZE || - (!skb_is_gso(skb) && skb->len > HNS3_MAX_NON_TSO_SIZE))) + (!skb_is_gso(skb) && skb->len > + HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num)))) return HNS3_MAX_TSO_BD_NUM + 1U; bd_num = hns3_skb_bd_num(skb, bd_size, bd_num); @@ -1233,31 +1232,34 @@ static unsigned int hns3_gso_hdr_len(struct sk_buff *skb) return skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb); } -/* HW need every continuous 8 buffer data to be larger than MSS, - * we simplify it by ensuring skb_headlen + the first continuous - * 7 frags to to be larger than gso header len + mss, and the remaining - * continuous 7 frags to be larger than MSS except the last 7 frags. +/* HW need every continuous max_non_tso_bd_num buffer data to be larger + * than MSS, we simplify it by ensuring skb_headlen + the first continuous + * max_non_tso_bd_num - 1 frags to be larger than gso header len + mss, + * and the remaining continuous max_non_tso_bd_num - 1 frags to be larger + * than MSS except the last max_non_tso_bd_num - 1 frags. */ static bool hns3_skb_need_linearized(struct sk_buff *skb, unsigned int *bd_size, - unsigned int bd_num) + unsigned int bd_num, u8 max_non_tso_bd_num) { unsigned int tot_len = 0; int i; - for (i = 0; i < HNS3_MAX_NON_TSO_BD_NUM - 1U; i++) + for (i = 0; i < max_non_tso_bd_num - 1U; i++) tot_len += bd_size[i]; - /* ensure the first 8 frags is greater than mss + header */ - if (tot_len + bd_size[HNS3_MAX_NON_TSO_BD_NUM - 1U] < + /* ensure the first max_non_tso_bd_num frags is greater than + * mss + header + */ + if (tot_len + bd_size[max_non_tso_bd_num - 1U] < skb_shinfo(skb)->gso_size + hns3_gso_hdr_len(skb)) return true; - /* ensure every continuous 7 buffer is greater than mss - * except the last one. + /* ensure every continuous max_non_tso_bd_num - 1 buffer is greater + * than mss except the last one. */ - for (i = 0; i < bd_num - HNS3_MAX_NON_TSO_BD_NUM; i++) { + for (i = 0; i < bd_num - max_non_tso_bd_num; i++) { tot_len -= bd_size[i]; - tot_len += bd_size[i + HNS3_MAX_NON_TSO_BD_NUM - 1U]; + tot_len += bd_size[i + max_non_tso_bd_num - 1U]; if (tot_len < skb_shinfo(skb)->gso_size) return true; @@ -1268,7 +1270,7 @@ static bool hns3_skb_need_linearized(struct sk_buff *skb, unsigned int *bd_size, void hns3_shinfo_pack(struct skb_shared_info *shinfo, __u32 *size) { - int i = 0; + int i; for (i = 0; i < MAX_SKB_FRAGS; i++) size[i] = skb_frag_size(&shinfo->frags[i]); @@ -1279,14 +1281,16 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring, struct sk_buff *skb) { struct hns3_nic_priv *priv = netdev_priv(netdev); + u8 max_non_tso_bd_num = priv->max_non_tso_bd_num; unsigned int bd_size[HNS3_MAX_TSO_BD_NUM + 1U]; unsigned int bd_num; - bd_num = hns3_tx_bd_num(skb, bd_size); - if (unlikely(bd_num > HNS3_MAX_NON_TSO_BD_NUM)) { + bd_num = hns3_tx_bd_num(skb, bd_size, max_non_tso_bd_num); + if (unlikely(bd_num > max_non_tso_bd_num)) { if (bd_num <= HNS3_MAX_TSO_BD_NUM && skb_is_gso(skb) && - !hns3_skb_need_linearized(skb, bd_size, bd_num)) { - trace_hns3_over_8bd(skb); + !hns3_skb_need_linearized(skb, bd_size, bd_num, + max_non_tso_bd_num)) { + trace_hns3_over_max_bd(skb); goto out; } @@ -1296,8 +1300,8 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring, bd_num = hns3_tx_bd_count(skb->len); if ((skb_is_gso(skb) && bd_num > HNS3_MAX_TSO_BD_NUM) || (!skb_is_gso(skb) && - bd_num > HNS3_MAX_NON_TSO_BD_NUM)) { - trace_hns3_over_8bd(skb); + bd_num > max_non_tso_bd_num)) { + trace_hns3_over_max_bd(skb); return -ENOMEM; } @@ -1397,6 +1401,27 @@ static int hns3_fill_skb_to_desc(struct hns3_enet_ring *ring, return bd_num; } +static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num, + bool doorbell) +{ + ring->pending_buf += num; + + if (!doorbell) { + u64_stats_update_begin(&ring->syncp); + ring->stats.tx_more++; + u64_stats_update_end(&ring->syncp); + return; + } + + if (!ring->pending_buf) + return; + + writel(ring->pending_buf, + ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG); + ring->pending_buf = 0; + WRITE_ONCE(ring->last_to_use, ring->next_to_use); +} + netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) { struct hns3_nic_priv *priv = netdev_priv(netdev); @@ -1405,11 +1430,14 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) int pre_ntu, next_to_use_head; struct sk_buff *frag_skb; int bd_num = 0; + bool doorbell; int ret; /* Hardware can only handle short frames above 32 bytes */ - if (skb_put_padto(skb, HNS3_MIN_TX_LEN)) + if (skb_put_padto(skb, HNS3_MIN_TX_LEN)) { + hns3_tx_doorbell(ring, 0, !netdev_xmit_more()); return NETDEV_TX_OK; + } /* Prefetch the data used later */ prefetch(skb->data); @@ -1420,6 +1448,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) u64_stats_update_begin(&ring->syncp); ring->stats.tx_busy++; u64_stats_update_end(&ring->syncp); + hns3_tx_doorbell(ring, 0, true); return NETDEV_TX_BUSY; } else if (ret == -ENOMEM) { u64_stats_update_begin(&ring->syncp); @@ -1460,11 +1489,9 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) /* Complete translate all packets */ dev_queue = netdev_get_tx_queue(netdev, ring->queue_index); - netdev_tx_sent_queue(dev_queue, skb->len); - - wmb(); /* Commit all data before submit */ - - hnae3_queue_xmit(ring->tqp, bd_num); + doorbell = __netdev_tx_sent_queue(dev_queue, skb->len, + netdev_xmit_more()); + hns3_tx_doorbell(ring, bd_num, doorbell); return NETDEV_TX_OK; @@ -1473,6 +1500,7 @@ fill_err: out_err_tx_ok: dev_kfree_skb_any(skb); + hns3_tx_doorbell(ring, 0, !netdev_xmit_more()); return NETDEV_TX_OK; } @@ -1853,13 +1881,13 @@ static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev) tx_ring->next_to_clean, napi->state); netdev_info(ndev, - "tx_pkts: %llu, tx_bytes: %llu, io_err_cnt: %llu, sw_err_cnt: %llu\n", + "tx_pkts: %llu, tx_bytes: %llu, sw_err_cnt: %llu, tx_pending: %d\n", tx_ring->stats.tx_pkts, tx_ring->stats.tx_bytes, - tx_ring->stats.io_err_cnt, tx_ring->stats.sw_err_cnt); + tx_ring->stats.sw_err_cnt, tx_ring->pending_buf); netdev_info(ndev, - "seg_pkt_cnt: %llu, tx_err_cnt: %llu, restart_queue: %llu, tx_busy: %llu\n", - tx_ring->stats.seg_pkt_cnt, tx_ring->stats.tx_err_cnt, + "seg_pkt_cnt: %llu, tx_more: %llu, restart_queue: %llu, tx_busy: %llu\n", + tx_ring->stats.seg_pkt_cnt, tx_ring->stats.tx_more, tx_ring->stats.restart_queue, tx_ring->stats.tx_busy); /* When mac received many pause frames continuous, it's unable to send @@ -2034,9 +2062,10 @@ bool hns3_is_phys_func(struct pci_dev *pdev) case HNAE3_DEV_ID_50GE_RDMA: case HNAE3_DEV_ID_50GE_RDMA_MACSEC: case HNAE3_DEV_ID_100G_RDMA_MACSEC: + case HNAE3_DEV_ID_200G_RDMA: return true; - case HNAE3_DEV_ID_100G_VF: - case HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF: + case HNAE3_DEV_ID_VF: + case HNAE3_DEV_ID_RDMA_DCB_PFC_VF: return false; default: dev_warn(&pdev->dev, "un-recognized pci device-id %u", @@ -2061,15 +2090,6 @@ static void hns3_disable_sriov(struct pci_dev *pdev) pci_disable_sriov(pdev); } -static void hns3_get_dev_capability(struct pci_dev *pdev, - struct hnae3_ae_dev *ae_dev) -{ - if (pdev->revision >= 0x21) { - hnae3_set_bit(ae_dev->flag, HNAE3_DEV_SUPPORT_FD_B, 1); - hnae3_set_bit(ae_dev->flag, HNAE3_DEV_SUPPORT_GRO_B, 1); - } -} - /* hns3_probe - Device initialization routine * @pdev: PCI device information struct * @ent: entry in hns3_pci_tbl @@ -2091,7 +2111,6 @@ static int hns3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ae_dev->pdev = pdev; ae_dev->flag = ent->driver_data; - hns3_get_dev_capability(pdev, ae_dev); pci_set_drvdata(pdev, ae_dev); ret = hnae3_register_ae_dev(ae_dev); @@ -2252,6 +2271,7 @@ static void hns3_set_default_feature(struct net_device *netdev) { struct hnae3_handle *h = hns3_get_handle(netdev); struct pci_dev *pdev = h->pdev; + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); netdev->priv_flags |= IFF_UNICAST_FLT; @@ -2289,7 +2309,7 @@ static void hns3_set_default_feature(struct net_device *netdev) NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST; - if (pdev->revision >= 0x21) { + if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { netdev->hw_features |= NETIF_F_GRO_HW; netdev->features |= NETIF_F_GRO_HW; @@ -2298,6 +2318,13 @@ static void hns3_set_default_feature(struct net_device *netdev) netdev->features |= NETIF_F_NTUPLE; } } + + if (test_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, ae_dev->caps)) { + netdev->hw_features |= NETIF_F_GSO_UDP_L4; + netdev->features |= NETIF_F_GSO_UDP_L4; + netdev->vlan_features |= NETIF_F_GSO_UDP_L4; + netdev->hw_enc_features |= NETIF_F_GSO_UDP_L4; + } } static int hns3_alloc_buffer(struct hns3_enet_ring *ring, @@ -2316,17 +2343,19 @@ static int hns3_alloc_buffer(struct hns3_enet_ring *ring, cb->buf = page_address(p); cb->length = hns3_page_size(ring); cb->type = DESC_TYPE_PAGE; + page_ref_add(p, USHRT_MAX - 1); + cb->pagecnt_bias = USHRT_MAX; return 0; } static void hns3_free_buffer(struct hns3_enet_ring *ring, - struct hns3_desc_cb *cb) + struct hns3_desc_cb *cb, int budget) { if (cb->type == DESC_TYPE_SKB) - dev_kfree_skb_any((struct sk_buff *)cb->priv); - else if (!HNAE3_IS_TX_RING(ring)) - put_page((struct page *)cb->priv); + napi_consume_skb(cb->priv, budget); + else if (!HNAE3_IS_TX_RING(ring) && cb->pagecnt_bias) + __page_frag_cache_drain(cb->priv, cb->pagecnt_bias); memset(cb, 0, sizeof(*cb)); } @@ -2358,7 +2387,8 @@ static void hns3_buffer_detach(struct hns3_enet_ring *ring, int i) ring->desc[i].addr = 0; } -static void hns3_free_buffer_detach(struct hns3_enet_ring *ring, int i) +static void hns3_free_buffer_detach(struct hns3_enet_ring *ring, int i, + int budget) { struct hns3_desc_cb *cb = &ring->desc_cb[i]; @@ -2366,7 +2396,7 @@ static void hns3_free_buffer_detach(struct hns3_enet_ring *ring, int i) return; hns3_buffer_detach(ring, i); - hns3_free_buffer(ring, cb); + hns3_free_buffer(ring, cb, budget); } static void hns3_free_buffers(struct hns3_enet_ring *ring) @@ -2374,7 +2404,7 @@ static void hns3_free_buffers(struct hns3_enet_ring *ring) int i; for (i = 0; i < ring->desc_num; i++) - hns3_free_buffer_detach(ring, i); + hns3_free_buffer_detach(ring, i, 0); } /* free desc along with its attached buffer */ @@ -2419,7 +2449,7 @@ static int hns3_alloc_and_map_buffer(struct hns3_enet_ring *ring, return 0; out_with_buf: - hns3_free_buffer(ring, cb); + hns3_free_buffer(ring, cb, 0); out: return ret; } @@ -2451,7 +2481,7 @@ static int hns3_alloc_ring_buffers(struct hns3_enet_ring *ring) out_buffer_fail: for (j = i - 1; j >= 0; j--) - hns3_free_buffer_detach(ring, j); + hns3_free_buffer_detach(ring, j, 0); return ret; } @@ -2478,71 +2508,62 @@ static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i) DMA_FROM_DEVICE); } -static void hns3_nic_reclaim_desc(struct hns3_enet_ring *ring, int head, - int *bytes, int *pkts) +static bool hns3_nic_reclaim_desc(struct hns3_enet_ring *ring, + int *bytes, int *pkts, int budget) { + /* pair with ring->last_to_use update in hns3_tx_doorbell(), + * smp_store_release() is not used in hns3_tx_doorbell() because + * the doorbell operation already have the needed barrier operation. + */ + int ltu = smp_load_acquire(&ring->last_to_use); int ntc = ring->next_to_clean; struct hns3_desc_cb *desc_cb; + bool reclaimed = false; + struct hns3_desc *desc; + + while (ltu != ntc) { + desc = &ring->desc[ntc]; + + if (le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri) & + BIT(HNS3_TXD_VLD_B)) + break; - while (head != ntc) { desc_cb = &ring->desc_cb[ntc]; (*pkts) += (desc_cb->type == DESC_TYPE_SKB); (*bytes) += desc_cb->length; /* desc_cb will be cleaned, after hnae3_free_buffer_detach */ - hns3_free_buffer_detach(ring, ntc); + hns3_free_buffer_detach(ring, ntc, budget); if (++ntc == ring->desc_num) ntc = 0; /* Issue prefetch for next Tx descriptor */ prefetch(&ring->desc_cb[ntc]); + reclaimed = true; } + if (unlikely(!reclaimed)) + return false; + /* This smp_store_release() pairs with smp_load_acquire() in * ring_space called by hns3_nic_net_xmit. */ smp_store_release(&ring->next_to_clean, ntc); + return true; } -static int is_valid_clean_head(struct hns3_enet_ring *ring, int h) -{ - int u = ring->next_to_use; - int c = ring->next_to_clean; - - if (unlikely(h > ring->desc_num)) - return 0; - - return u > c ? (h > c && h <= u) : (h > c || h <= u); -} - -void hns3_clean_tx_ring(struct hns3_enet_ring *ring) +void hns3_clean_tx_ring(struct hns3_enet_ring *ring, int budget) { struct net_device *netdev = ring_to_netdev(ring); struct hns3_nic_priv *priv = netdev_priv(netdev); struct netdev_queue *dev_queue; int bytes, pkts; - int head; - - head = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_HEAD_REG); - - if (is_ring_empty(ring) || head == ring->next_to_clean) - return; /* no data to poll */ - - rmb(); /* Make sure head is ready before touch any data */ - - if (unlikely(!is_valid_clean_head(ring, head))) { - hns3_rl_err(netdev, "wrong head (%d, %d-%d)\n", head, - ring->next_to_use, ring->next_to_clean); - - u64_stats_update_begin(&ring->syncp); - ring->stats.io_err_cnt++; - u64_stats_update_end(&ring->syncp); - return; - } bytes = 0; pkts = 0; - hns3_nic_reclaim_desc(ring, head, &bytes, &pkts); + + if (unlikely(!hns3_nic_reclaim_desc(ring, &bytes, &pkts, budget))) + return; ring->tqp_vector->tx_group.total_bytes += bytes; ring->tqp_vector->tx_group.total_packets += pkts; @@ -2614,8 +2635,7 @@ static void hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring, ring_ptr_move_fw(ring, next_to_use); } - wmb(); /* Make all data has been write before submit */ - writel_relaxed(i, ring->tqp->io_base + HNS3_RING_RX_RING_HEAD_REG); + writel(i, ring->tqp->io_base + HNS3_RING_RX_RING_HEAD_REG); } static bool hns3_page_is_reusable(struct page *page) @@ -2624,6 +2644,11 @@ static bool hns3_page_is_reusable(struct page *page) !page_is_pfmemalloc(page); } +static bool hns3_can_reuse_page(struct hns3_desc_cb *cb) +{ + return (page_count(cb->priv) - cb->pagecnt_bias) == 1; +} + static void hns3_nic_reuse_page(struct sk_buff *skb, int i, struct hns3_enet_ring *ring, int pull_len, struct hns3_desc_cb *desc_cb) @@ -2632,6 +2657,7 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i, int size = le16_to_cpu(desc->rx.size); u32 truesize = hns3_buf_size(ring); + desc_cb->pagecnt_bias--; skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len, size - pull_len, truesize); @@ -2639,20 +2665,27 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i, * when page_offset rollback to zero, flag default unreuse */ if (unlikely(!hns3_page_is_reusable(desc_cb->priv)) || - (!desc_cb->page_offset && page_count(desc_cb->priv) > 1)) + (!desc_cb->page_offset && !hns3_can_reuse_page(desc_cb))) { + __page_frag_cache_drain(desc_cb->priv, desc_cb->pagecnt_bias); return; + } /* Move offset up to the next cache line */ desc_cb->page_offset += truesize; if (desc_cb->page_offset + truesize <= hns3_page_size(ring)) { desc_cb->reuse_flag = 1; - /* Bump ref count on page before it is given */ - get_page(desc_cb->priv); - } else if (page_count(desc_cb->priv) == 1) { + } else if (hns3_can_reuse_page(desc_cb)) { desc_cb->reuse_flag = 1; desc_cb->page_offset = 0; - get_page(desc_cb->priv); + } else if (desc_cb->pagecnt_bias) { + __page_frag_cache_drain(desc_cb->priv, desc_cb->pagecnt_bias); + return; + } + + if (unlikely(!desc_cb->pagecnt_bias)) { + page_ref_add(desc_cb->priv, USHRT_MAX); + desc_cb->pagecnt_bias = USHRT_MAX; } } @@ -2782,8 +2815,9 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring, { struct hnae3_handle *handle = ring->tqp->handle; struct pci_dev *pdev = ring->tqp->handle->pdev; + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); - if (pdev->revision == 0x20) { + if (unlikely(ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)) { *vlan_tag = le16_to_cpu(desc->rx.ot_vlan_tag); if (!(*vlan_tag & VLAN_VID_MASK)) *vlan_tag = le16_to_cpu(desc->rx.vlan_tag); @@ -2828,6 +2862,16 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring, } } +static void hns3_rx_ring_move_fw(struct hns3_enet_ring *ring) +{ + ring->desc[ring->next_to_clean].rx.bd_base_info &= + cpu_to_le32(~BIT(HNS3_RXD_VLD_B)); + ring->next_to_clean += 1; + + if (unlikely(ring->next_to_clean == ring->desc_num)) + ring->next_to_clean = 0; +} + static int hns3_alloc_skb(struct hns3_enet_ring *ring, unsigned int length, unsigned char *va) { @@ -2860,9 +2904,10 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, unsigned int length, if (likely(hns3_page_is_reusable(desc_cb->priv))) desc_cb->reuse_flag = 1; else /* This page cannot be reused so discard it */ - put_page(desc_cb->priv); + __page_frag_cache_drain(desc_cb->priv, + desc_cb->pagecnt_bias); - ring_ptr_move_fw(ring, next_to_clean); + hns3_rx_ring_move_fw(ring); return 0; } u64_stats_update_begin(&ring->syncp); @@ -2873,7 +2918,7 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, unsigned int length, __skb_put(skb, ring->pull_len); hns3_nic_reuse_page(skb, ring->frag_num++, ring, ring->pull_len, desc_cb); - ring_ptr_move_fw(ring, next_to_clean); + hns3_rx_ring_move_fw(ring); return 0; } @@ -2928,7 +2973,7 @@ static int hns3_add_frag(struct hns3_enet_ring *ring) 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); + hns3_rx_ring_move_fw(ring); ring->pending_buf++; } while (!(bd_base_info & BIT(HNS3_RXD_FE_B))); @@ -3070,35 +3115,32 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring) prefetch(desc); - length = le16_to_cpu(desc->rx.size); - bd_base_info = le32_to_cpu(desc->rx.bd_base_info); + if (!skb) { + bd_base_info = le32_to_cpu(desc->rx.bd_base_info); - /* Check valid BD */ - if (unlikely(!(bd_base_info & BIT(HNS3_RXD_VLD_B)))) - return -ENXIO; + /* Check valid BD */ + if (unlikely(!(bd_base_info & BIT(HNS3_RXD_VLD_B)))) + return -ENXIO; + + dma_rmb(); + length = le16_to_cpu(desc->rx.size); - 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 - * line size is 64B so need to prefetch twice to make it 128B. But in - * actual we can have greater size of caches with 128B Level 1 cache - * lines. In such a case, single fetch would suffice to cache in the - * relevant part of the header. - */ - prefetch(ring->va); -#if L1_CACHE_BYTES < 128 - prefetch(ring->va + L1_CACHE_BYTES); -#endif + /* Prefetch first cache line of first page. + * Idea is to cache few bytes of the header of the packet. + * Our L1 Cache line size is 64B so need to prefetch twice to make + * it 128B. But in actual we can have greater size of caches with + * 128B Level 1 cache lines. In such a case, single fetch would + * suffice to cache in the relevant part of the header. + */ + net_prefetch(ring->va); - if (!skb) { ret = hns3_alloc_skb(ring, length, ring->va); skb = ring->skb; @@ -3138,19 +3180,11 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget, #define RCB_NOF_ALLOC_RX_BUFF_ONCE 16 int unused_count = hns3_desc_unused(ring); int recv_pkts = 0; - int recv_bds = 0; - int err, num; + int err; - num = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_FBDNUM_REG); - num -= unused_count; unused_count -= ring->pending_buf; - if (num <= 0) - goto out; - - rmb(); /* Make sure num taken effect before the other data is touched */ - - while (recv_pkts < budget && recv_bds < num) { + while (recv_pkts < budget) { /* Reuse or realloc buffers */ if (unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) { hns3_nic_alloc_rx_buffers(ring, unused_count); @@ -3168,7 +3202,6 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget, recv_pkts++; } - recv_bds += ring->pending_buf; unused_count += ring->pending_buf; ring->skb = NULL; ring->pending_buf = 0; @@ -3337,7 +3370,7 @@ static int hns3_nic_common_poll(struct napi_struct *napi, int budget) * budget and be more aggressive about cleaning up the Tx descriptors. */ hns3_for_each_ring(ring, tqp_vector->tx_group) - hns3_clean_tx_ring(ring); + hns3_clean_tx_ring(ring, budget); /* make sure rx ring budget not smaller than 1 */ if (tqp_vector->num_tqps > 1) @@ -3496,7 +3529,7 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv) struct hnae3_ring_chain_node vector_ring_chain; struct hnae3_handle *h = priv->ae_handle; struct hns3_enet_tqp_vector *tqp_vector; - int ret = 0; + int ret; int i; hns3_nic_set_cpumask(priv); @@ -3673,12 +3706,10 @@ static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, ring = &priv->ring[q->tqp_index]; desc_num = priv->ae_handle->kinfo.num_tx_desc; ring->queue_index = q->tqp_index; - ring->io_base = (u8 __iomem *)q->io_base + HNS3_TX_REG_OFFSET; } else { ring = &priv->ring[q->tqp_index + queue_num]; desc_num = priv->ae_handle->kinfo.num_rx_desc; ring->queue_index = q->tqp_index; - ring->io_base = q->io_base; } hnae3_set_bit(ring->flag, HNAE3_RING_TYPE_B, ring_type); @@ -3692,6 +3723,7 @@ static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, ring->desc_num = desc_num; ring->next_to_use = 0; ring->next_to_clean = 0; + ring->last_to_use = 0; } static void hns3_queue_to_ring(struct hnae3_queue *tqp, @@ -3771,6 +3803,7 @@ void hns3_fini_ring(struct hns3_enet_ring *ring) ring->desc_cb = NULL; ring->next_to_clean = 0; ring->next_to_use = 0; + ring->last_to_use = 0; ring->pending_buf = 0; if (ring->skb) { dev_kfree_skb_any(ring->skb); @@ -3979,6 +4012,7 @@ static void hns3_info_show(struct hns3_nic_priv *priv) static int hns3_client_init(struct hnae3_handle *handle) { struct pci_dev *pdev = handle->pdev; + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); u16 alloc_tqps, max_rss_size; struct hns3_nic_priv *priv; struct net_device *netdev; @@ -3995,6 +4029,7 @@ static int hns3_client_init(struct hnae3_handle *handle) priv->netdev = netdev; priv->ae_handle = handle; priv->tx_timeout_count = 0; + priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num; set_bit(HNS3_NIC_STATE_DOWN, &priv->state); handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL); @@ -4181,9 +4216,11 @@ static void hns3_clear_tx_ring(struct hns3_enet_ring *ring) { while (ring->next_to_clean != ring->next_to_use) { ring->desc[ring->next_to_clean].tx.bdtp_fe_sc_vld_ra_ri = 0; - hns3_free_buffer_detach(ring, ring->next_to_clean); + hns3_free_buffer_detach(ring, ring->next_to_clean, 0); ring_ptr_move_fw(ring, next_to_clean); } + + ring->pending_buf = 0; } static int hns3_clear_rx_ring(struct hns3_enet_ring *ring) @@ -4286,6 +4323,7 @@ int hns3_nic_reset_all_ring(struct hnae3_handle *h) hns3_clear_tx_ring(&priv->ring[i]); priv->ring[i].next_to_clean = 0; priv->ring[i].next_to_use = 0; + priv->ring[i].last_to_use = 0; rx_ring = &priv->ring[i + h->kinfo.num_tqps]; hns3_init_ring_hw(rx_ring); @@ -4582,6 +4620,8 @@ static const struct hns3_hw_error_info hns3_hw_err[] = { .msg = "IMP CMDQ error" }, { .type = HNAE3_IMP_RD_POISON_ERROR, .msg = "IMP RD poison" }, + { .type = HNAE3_ROCEE_AXI_RESP_ERROR, + .msg = "ROCEE AXI RESP error" }, }; static void hns3_process_hw_error(struct hnae3_handle *handle, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index 9922c5fd7f94..1c81dea0da1e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -42,12 +42,9 @@ enum hns3_nic_state { #define HNS3_RING_TX_RING_PKTNUM_RECORD_REG 0x0006C #define HNS3_RING_TX_RING_EBD_OFFSET_REG 0x00070 #define HNS3_RING_TX_RING_BD_ERR_REG 0x00074 -#define HNS3_RING_PREFETCH_EN_REG 0x0007C -#define HNS3_RING_CFG_VF_NUM_REG 0x00080 -#define HNS3_RING_ASID_REG 0x0008C #define HNS3_RING_EN_REG 0x00090 - -#define HNS3_TX_REG_OFFSET 0x40 +#define HNS3_RING_RX_EN_REG 0x00098 +#define HNS3_RING_TX_EN_REG 0x000D4 #define HNS3_RX_HEAD_SIZE 256 @@ -172,13 +169,12 @@ enum hns3_nic_state { #define HNS3_VECTOR_INITED 1 #define HNS3_MAX_BD_SIZE 65535 -#define HNS3_MAX_NON_TSO_BD_NUM 8U #define HNS3_MAX_TSO_BD_NUM 63U #define HNS3_MAX_TSO_SIZE \ (HNS3_MAX_BD_SIZE * HNS3_MAX_TSO_BD_NUM) -#define HNS3_MAX_NON_TSO_SIZE \ - (HNS3_MAX_BD_SIZE * HNS3_MAX_NON_TSO_BD_NUM) +#define HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num) \ + (HNS3_MAX_BD_SIZE * (max_non_tso_bd_num)) #define HNS3_VECTOR_GL0_OFFSET 0x100 #define HNS3_VECTOR_GL1_OFFSET 0x200 @@ -292,6 +288,7 @@ struct hns3_desc_cb { /* desc type, used by the ring user to mark the type of the priv data */ u16 type; + u16 pagecnt_bias; }; enum hns3_pkt_l3type { @@ -348,14 +345,13 @@ enum hns3_pkt_ol4type { }; struct ring_stats { - u64 io_err_cnt; u64 sw_err_cnt; u64 seg_pkt_cnt; union { struct { u64 tx_pkts; u64 tx_bytes; - u64 tx_err_cnt; + u64 tx_more; u64 restart_queue; u64 tx_busy; u64 tx_copy; @@ -380,7 +376,6 @@ struct ring_stats { }; struct hns3_enet_ring { - u8 __iomem *io_base; /* base io address for the ring */ struct hns3_desc *desc; /* dma map address space */ struct hns3_desc_cb *desc_cb; struct hns3_enet_ring *next; @@ -402,8 +397,10 @@ struct hns3_enet_ring { * next_to_use */ int next_to_clean; - - u32 pull_len; /* head length for current packet */ + union { + int last_to_use; /* last idx used by xmit */ + u32 pull_len; /* memcpy len for current rx packet */ + }; u32 frag_num; void *va; /* first buffer address for current packet */ @@ -479,6 +476,7 @@ struct hns3_nic_priv { struct hns3_enet_ring *ring; struct hns3_enet_tqp_vector *tqp_vector; u16 vector_num; + u8 max_non_tso_bd_num; u64 tx_timeout_count; @@ -518,11 +516,6 @@ static inline int ring_space(struct hns3_enet_ring *ring) (begin - end)) - 1; } -static inline int is_ring_empty(struct hns3_enet_ring *ring) -{ - return ring->next_to_use == ring->next_to_clean; -} - static inline u32 hns3_read_reg(void __iomem *base, u32 reg) { return readl(base + reg); @@ -548,9 +541,6 @@ static inline bool hns3_nic_resetting(struct net_device *netdev) #define hns3_write_dev(a, reg, value) \ hns3_write_reg((a)->io_base, (reg), (value)) -#define hnae3_queue_xmit(tqp, buf_num) writel_relaxed(buf_num, \ - (tqp)->io_base + HNS3_RING_TX_RING_TAIL_REG) - #define ring_to_dev(ring) ((ring)->dev) #define ring_to_netdev(ring) ((ring)->tqp_vector->napi.dev) @@ -588,7 +578,7 @@ void hns3_ethtool_set_ops(struct net_device *netdev); int hns3_set_channels(struct net_device *netdev, struct ethtool_channels *ch); -void hns3_clean_tx_ring(struct hns3_enet_ring *ring); +void hns3_clean_tx_ring(struct hns3_enet_ring *ring, int budget); int hns3_init_all_ring(struct hns3_nic_priv *priv); int hns3_uninit_all_ring(struct hns3_nic_priv *priv); int hns3_nic_reset_all_ring(struct hnae3_handle *h); @@ -607,7 +597,6 @@ void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector, u32 rl_value); void hns3_enable_vlan_filter(struct net_device *netdev, bool enable); -int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags); void hns3_request_update_promisc_mode(struct hnae3_handle *handle); #ifdef CONFIG_HNS3_DCB diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index 2622e04e8eed..6b07b2771172 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -27,12 +27,11 @@ struct hns3_sfp_type { static const struct hns3_stats hns3_txq_stats[] = { /* Tx per-queue statistics */ - HNS3_TQP_STAT("io_err_cnt", io_err_cnt), HNS3_TQP_STAT("dropped", sw_err_cnt), HNS3_TQP_STAT("seg_pkt_cnt", seg_pkt_cnt), HNS3_TQP_STAT("packets", tx_pkts), HNS3_TQP_STAT("bytes", tx_bytes), - HNS3_TQP_STAT("errors", tx_err_cnt), + HNS3_TQP_STAT("more", tx_more), HNS3_TQP_STAT("wake", restart_queue), HNS3_TQP_STAT("busy", tx_busy), HNS3_TQP_STAT("copy", tx_copy), @@ -46,7 +45,6 @@ static const struct hns3_stats hns3_txq_stats[] = { static const struct hns3_stats hns3_rxq_stats[] = { /* Rx per-queue statistics */ - HNS3_TQP_STAT("io_err_cnt", io_err_cnt), HNS3_TQP_STAT("dropped", sw_err_cnt), HNS3_TQP_STAT("seg_pkt_cnt", seg_pkt_cnt), HNS3_TQP_STAT("packets", rx_pkts), @@ -79,6 +77,7 @@ static const struct hns3_stats hns3_rxq_stats[] = { static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) { struct hnae3_handle *h = hns3_get_handle(ndev); + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); bool vlan_filter_enable; int ret; @@ -98,7 +97,7 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) break; } - if (ret || h->pdev->revision >= 0x21) + if (ret || ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) return ret; if (en) { @@ -149,6 +148,7 @@ static void hns3_lp_setup_skb(struct sk_buff *skb) struct net_device *ndev = skb->dev; struct hnae3_handle *handle; + struct hnae3_ae_dev *ae_dev; unsigned char *packet; struct ethhdr *ethh; unsigned int i; @@ -165,7 +165,8 @@ static void hns3_lp_setup_skb(struct sk_buff *skb) * the purpose of mac or serdes selftest. */ handle = hns3_get_handle(ndev); - if (handle->pdev->revision == 0x20) + ae_dev = pci_get_drvdata(handle->pdev); + if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) ethh->h_dest[5] += HNS3_NIC_LB_DST_MAC_ADDR; eth_zero_addr(ethh->h_source); ethh->h_proto = htons(ETH_P_ARP); @@ -232,7 +233,7 @@ static void hns3_lb_clear_tx_ring(struct hns3_nic_priv *priv, u32 start_ringid, for (i = start_ringid; i <= end_ringid; i++) { struct hns3_enet_ring *ring = &priv->ring[i]; - hns3_clean_tx_ring(ring); + hns3_clean_tx_ring(ring, 0); } } @@ -310,9 +311,6 @@ static void hns3_self_test(struct net_device *ndev, struct hnae3_handle *h = priv->ae_handle; int st_param[HNS3_SELF_TEST_TYPE_NUM][2]; bool if_running = netif_running(ndev); -#if IS_ENABLED(CONFIG_VLAN_8021Q) - bool dis_vlan_filter; -#endif int test_index = 0; u32 i; @@ -349,9 +347,7 @@ static void hns3_self_test(struct net_device *ndev, #if IS_ENABLED(CONFIG_VLAN_8021Q) /* Disable the vlan filter for selftest does not support it */ - dis_vlan_filter = (ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) && - h->ae_algo->ops->enable_vlan_filter; - if (dis_vlan_filter) + if (h->ae_algo->ops->enable_vlan_filter) h->ae_algo->ops->enable_vlan_filter(h, false); #endif @@ -388,7 +384,7 @@ static void hns3_self_test(struct net_device *ndev, h->ae_algo->ops->halt_autoneg(h, false); #if IS_ENABLED(CONFIG_VLAN_8021Q) - if (dis_vlan_filter) + if (h->ae_algo->ops->enable_vlan_filter) h->ae_algo->ops->enable_vlan_filter(h, true); #endif @@ -763,6 +759,7 @@ static int hns3_set_link_ksettings(struct net_device *netdev, const struct ethtool_link_ksettings *cmd) { struct hnae3_handle *handle = hns3_get_handle(netdev); + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev); const struct hnae3_ae_ops *ops = handle->ae_algo->ops; int ret; @@ -784,7 +781,7 @@ static int hns3_set_link_ksettings(struct net_device *netdev, return phy_ethtool_ksettings_set(netdev->phydev, cmd); } - if (handle->pdev->revision == 0x20) + if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return -EOPNOTSUPP; ret = hns3_check_ksettings_param(netdev, cmd); @@ -848,11 +845,12 @@ static int hns3_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key, const u8 hfunc) { struct hnae3_handle *h = hns3_get_handle(netdev); + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); if (!h->ae_algo->ops->set_rss) return -EOPNOTSUPP; - if ((h->pdev->revision == 0x20 && + if ((ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2 && hfunc != ETH_RSS_HASH_TOP) || (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR)) { netdev_err(netdev, "hash func not supported\n"); @@ -1073,9 +1071,6 @@ static int hns3_nway_reset(struct net_device *netdev) if (phy) return genphy_restart_aneg(phy); - if (handle->pdev->revision == 0x20) - return -EOPNOTSUPP; - return ops->restart_autoneg(handle); } @@ -1363,11 +1358,12 @@ static int hns3_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fec) { struct hnae3_handle *handle = hns3_get_handle(netdev); + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev); const struct hnae3_ae_ops *ops = handle->ae_algo->ops; u8 fec_ability; u8 fec_mode; - if (handle->pdev->revision == 0x20) + if (!test_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps)) return -EOPNOTSUPP; if (!ops->get_fec) @@ -1385,10 +1381,11 @@ static int hns3_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fec) { struct hnae3_handle *handle = hns3_get_handle(netdev); + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev); const struct hnae3_ae_ops *ops = handle->ae_algo->ops; u32 fec_mode; - if (handle->pdev->revision == 0x20) + if (!test_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps)) return -EOPNOTSUPP; if (!ops->set_fec) @@ -1406,11 +1403,13 @@ static int hns3_get_module_info(struct net_device *netdev, #define HNS3_SFF_8636_V1_3 0x03 struct hnae3_handle *handle = hns3_get_handle(netdev); + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev); const struct hnae3_ae_ops *ops = handle->ae_algo->ops; struct hns3_sfp_type sfp_type; int ret; - if (handle->pdev->revision == 0x20 || !ops->get_module_eeprom) + if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2 || + !ops->get_module_eeprom) return -EOPNOTSUPP; memset(&sfp_type, 0, sizeof(sfp_type)); @@ -1454,9 +1453,11 @@ static int hns3_get_module_eeprom(struct net_device *netdev, struct ethtool_eeprom *ee, u8 *data) { struct hnae3_handle *handle = hns3_get_handle(netdev); + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev); const struct hnae3_ae_ops *ops = handle->ae_algo->ops; - if (handle->pdev->revision == 0x20 || !ops->get_module_eeprom) + if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2 || + !ops->get_module_eeprom) return -EOPNOTSUPP; if (!ee->len) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h b/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h index 7bddcca148a5..5153e5d41bbd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h @@ -53,7 +53,7 @@ DECLARE_EVENT_CLASS(hns3_skb_template, ) ); -DEFINE_EVENT(hns3_skb_template, hns3_over_8bd, +DEFINE_EVENT(hns3_skb_template, hns3_over_max_bd, TP_PROTO(struct sk_buff *skb), TP_ARGS(skb)); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c index 1d6c328bd9fb..e6321dda0f3f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c @@ -261,7 +261,7 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num) bool complete = false; u32 timeout = 0; int handle = 0; - int retval = 0; + int retval; int ntc; spin_lock_bh(&hw->cmq.csq.lock); @@ -330,9 +330,37 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num) return retval; } -static enum hclge_cmd_status hclge_cmd_query_firmware_version( - struct hclge_hw *hw, u32 *version) +static void hclge_set_default_capability(struct hclge_dev *hdev) { + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + + set_bit(HNAE3_DEV_SUPPORT_FD_B, ae_dev->caps); + set_bit(HNAE3_DEV_SUPPORT_GRO_B, ae_dev->caps); + set_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps); +} + +static void hclge_parse_capability(struct hclge_dev *hdev, + struct hclge_query_version_cmd *cmd) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + u32 caps; + + caps = __le32_to_cpu(cmd->caps[0]); + + if (hnae3_get_bit(caps, HCLGE_CAP_UDP_GSO_B)) + set_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, ae_dev->caps); + if (hnae3_get_bit(caps, HCLGE_CAP_PTP_B)) + set_bit(HNAE3_DEV_SUPPORT_PTP_B, ae_dev->caps); + if (hnae3_get_bit(caps, HCLGE_CAP_INT_QL_B)) + set_bit(HNAE3_DEV_SUPPORT_INT_QL_B, ae_dev->caps); + if (hnae3_get_bit(caps, HCLGE_CAP_TQP_TXRX_INDEP_B)) + set_bit(HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B, ae_dev->caps); +} + +static enum hclge_cmd_status +hclge_cmd_query_version_and_capability(struct hclge_dev *hdev) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); struct hclge_query_version_cmd *resp; struct hclge_desc desc; int ret; @@ -340,9 +368,20 @@ static enum hclge_cmd_status hclge_cmd_query_firmware_version( hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_FW_VER, 1); resp = (struct hclge_query_version_cmd *)desc.data; - ret = hclge_cmd_send(hw, &desc, 1); - if (!ret) - *version = le32_to_cpu(resp->firmware); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + return ret; + + hdev->fw_version = le32_to_cpu(resp->firmware); + + ae_dev->dev_version = le32_to_cpu(resp->hardware) << + HNAE3_PCI_REVISION_BIT_SIZE; + ae_dev->dev_version |= hdev->pdev->revision; + + if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) + hclge_set_default_capability(hdev); + + hclge_parse_capability(hdev, resp); return ret; } @@ -402,7 +441,6 @@ static int hclge_firmware_compat_config(struct hclge_dev *hdev) int hclge_cmd_init(struct hclge_dev *hdev) { - u32 version; int ret; spin_lock_bh(&hdev->hw.cmq.csq.lock); @@ -431,22 +469,23 @@ int hclge_cmd_init(struct hclge_dev *hdev) goto err_cmd_init; } - ret = hclge_cmd_query_firmware_version(&hdev->hw, &version); + /* get version and device capabilities */ + ret = hclge_cmd_query_version_and_capability(hdev); if (ret) { dev_err(&hdev->pdev->dev, - "firmware version query failed %d\n", ret); + "failed to query version and capabilities, ret = %d\n", + ret); goto err_cmd_init; } - hdev->fw_version = version; dev_info(&hdev->pdev->dev, "The firmware version is %lu.%lu.%lu.%lu\n", - hnae3_get_field(version, HNAE3_FW_VERSION_BYTE3_MASK, + hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK, HNAE3_FW_VERSION_BYTE3_SHIFT), - hnae3_get_field(version, HNAE3_FW_VERSION_BYTE2_MASK, + hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK, HNAE3_FW_VERSION_BYTE2_SHIFT), - hnae3_get_field(version, HNAE3_FW_VERSION_BYTE1_MASK, + hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK, HNAE3_FW_VERSION_BYTE1_SHIFT), - hnae3_get_field(version, HNAE3_FW_VERSION_BYTE0_MASK, + hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK, HNAE3_FW_VERSION_BYTE0_SHIFT)); /* ask the firmware to enable some features, driver can work without diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index 463f29151ef0..096e26a2e16b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -115,7 +115,8 @@ enum hclge_opcode_type { HCLGE_OPC_DFX_RCB_REG = 0x004D, HCLGE_OPC_DFX_TQP_REG = 0x004E, HCLGE_OPC_DFX_SSU_REG_2 = 0x004F, - HCLGE_OPC_DFX_QUERY_CHIP_CAP = 0x0050, + + HCLGE_OPC_QUERY_DEV_SPECS = 0x0050, /* MAC command */ HCLGE_OPC_CONFIG_MAC_MODE = 0x0301, @@ -362,9 +363,26 @@ struct hclge_rx_priv_buff_cmd { u8 rsv[6]; }; +enum HCLGE_CAP_BITS { + HCLGE_CAP_UDP_GSO_B, + HCLGE_CAP_QB_B, + HCLGE_CAP_FD_FORWARD_TC_B, + HCLGE_CAP_PTP_B, + HCLGE_CAP_INT_QL_B, + HCLGE_CAP_SIMPLE_BD_B, + HCLGE_CAP_TX_PUSH_B, + HCLGE_CAP_PHY_IMP_B, + HCLGE_CAP_TQP_TXRX_INDEP_B, + HCLGE_CAP_HW_PAD_B, + HCLGE_CAP_STASH_B, +}; + +#define HCLGE_QUERY_CAP_LENGTH 3 struct hclge_query_version_cmd { __le32 firmware; - __le32 firmware_rsv[5]; + __le32 hardware; + __le32 rsv; + __le32 caps[HCLGE_QUERY_CAP_LENGTH]; /* capabilities of device */ }; #define HCLGE_RX_PRIV_EN_B 15 @@ -491,6 +509,8 @@ struct hclge_pf_res_cmd { #define HCLGE_CFG_RSS_SIZE_M GENMASK(31, 24) #define HCLGE_CFG_SPEED_ABILITY_S 0 #define HCLGE_CFG_SPEED_ABILITY_M GENMASK(7, 0) +#define HCLGE_CFG_SPEED_ABILITY_EXT_S 10 +#define HCLGE_CFG_SPEED_ABILITY_EXT_M GENMASK(15, 10) #define HCLGE_CFG_UMV_TBL_SPACE_S 16 #define HCLGE_CFG_UMV_TBL_SPACE_M GENMASK(31, 16) @@ -1069,6 +1089,20 @@ struct hclge_sfp_info_bd0_cmd { u8 data[HCLGE_SFP_INFO_BD0_LEN]; }; +#define HCLGE_QUERY_DEV_SPECS_BD_NUM 4 + +struct hclge_dev_specs_0_cmd { + __le32 rsv0; + __le32 mac_entry_num; + __le32 mng_entry_num; + __le16 rss_ind_tbl_size; + __le16 rss_key_size; + __le16 int_ql_max; + u8 max_non_tso_bd_num; + u8 rsv1; + __le32 max_tm_rate; +}; + int hclge_cmd_init(struct hclge_dev *hdev); static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value) { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c index d6c3952aba04..3606240025a8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c @@ -2,7 +2,9 @@ // Copyright (c) 2016-2017 Hisilicon Limited. #include "hclge_main.h" +#include "hclge_dcb.h" #include "hclge_tm.h" +#include "hclge_dcb.h" #include "hnae3.h" #define BW_PERCENT 100 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index 26f6f068b01d..16df050e72cf 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -8,7 +8,7 @@ #include "hclge_tm.h" #include "hnae3.h" -static struct hclge_dbg_reg_type_info hclge_dbg_reg_info[] = { +static const struct hclge_dbg_reg_type_info hclge_dbg_reg_info[] = { { .reg_type = "bios common", .dfx_msg = &hclge_dbg_bios_common_reg[0], .reg_msg = { .msg_num = ARRAY_SIZE(hclge_dbg_bios_common_reg), @@ -115,14 +115,14 @@ static int hclge_dbg_cmd_send(struct hclge_dev *hdev, } static void hclge_dbg_dump_reg_common(struct hclge_dev *hdev, - struct hclge_dbg_reg_type_info *reg_info, + const struct hclge_dbg_reg_type_info *reg_info, const char *cmd_buf) { #define IDX_OFFSET 1 const char *s = &cmd_buf[strlen(reg_info->reg_type) + IDX_OFFSET]; - struct hclge_dbg_dfx_message *dfx_message = reg_info->dfx_msg; - struct hclge_dbg_reg_common_msg *reg_msg = ®_info->reg_msg; + const struct hclge_dbg_dfx_message *dfx_message = reg_info->dfx_msg; + const struct hclge_dbg_reg_common_msg *reg_msg = ®_info->reg_msg; struct hclge_desc *desc_src; struct hclge_desc *desc; int entries_per_desc; @@ -399,7 +399,7 @@ err_dcb_cmd_send: static void hclge_dbg_dump_reg_cmd(struct hclge_dev *hdev, const char *cmd_buf) { - struct hclge_dbg_reg_type_info *reg_info; + const struct hclge_dbg_reg_type_info *reg_info; bool has_dump = false; int i; @@ -428,17 +428,13 @@ static void hclge_dbg_dump_reg_cmd(struct hclge_dev *hdev, const char *cmd_buf) } } -static void hclge_title_idx_print(struct hclge_dev *hdev, bool flag, int index, - char *title_buf, char *true_buf, - char *false_buf) +static void hclge_print_tc_info(struct hclge_dev *hdev, bool flag, int index) { if (flag) - dev_info(&hdev->pdev->dev, "%s(%d): %s weight: %u\n", - title_buf, index, true_buf, - hdev->tm_info.pg_info[0].tc_dwrr[index]); + dev_info(&hdev->pdev->dev, "tc(%d): no sp mode weight: %u\n", + index, hdev->tm_info.pg_info[0].tc_dwrr[index]); else - dev_info(&hdev->pdev->dev, "%s(%d): %s\n", title_buf, index, - false_buf); + dev_info(&hdev->pdev->dev, "tc(%d): sp mode\n", index); } static void hclge_dbg_dump_tc(struct hclge_dev *hdev) @@ -469,8 +465,7 @@ static void hclge_dbg_dump_tc(struct hclge_dev *hdev) ets_weight->weight_offset); for (i = 0; i < HNAE3_MAX_TC; i++) - hclge_title_idx_print(hdev, ets_weight->tc_weight[i], i, - "tc", "no sp mode", "sp mode"); + hclge_print_tc_info(hdev, ets_weight->tc_weight[i], i); } static void hclge_dbg_dump_tm_pg(struct hclge_dev *hdev) @@ -1170,6 +1165,14 @@ static void hclge_dbg_dump_serv_info(struct hclge_dev *hdev) hdev->serv_processed_cnt); } +static void hclge_dbg_dump_interrupt(struct hclge_dev *hdev) +{ + dev_info(&hdev->pdev->dev, "num_nic_msi: %u\n", hdev->num_nic_msi); + dev_info(&hdev->pdev->dev, "num_roce_msi: %u\n", hdev->num_roce_msi); + dev_info(&hdev->pdev->dev, "num_msi_used: %u\n", hdev->num_msi_used); + dev_info(&hdev->pdev->dev, "num_msi_left: %u\n", hdev->num_msi_left); +} + static void hclge_dbg_get_m7_stats_info(struct hclge_dev *hdev) { struct hclge_desc *desc_src, *desc_tmp; @@ -1494,6 +1497,7 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) #define DUMP_REG "dump reg" #define DUMP_TM_MAP "dump tm map" #define DUMP_LOOPBACK "dump loopback" +#define DUMP_INTERRUPT "dump intr" struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; @@ -1541,6 +1545,9 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) hclge_dbg_dump_mac_list(hdev, &cmd_buf[sizeof("dump mc mac list")], false); + } else if (strncmp(cmd_buf, DUMP_INTERRUPT, + strlen(DUMP_INTERRUPT)) == 0) { + hclge_dbg_dump_interrupt(hdev); } else { dev_info(&hdev->pdev->dev, "unknown command\n"); return -EINVAL; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h index 38b79321c4c4..a9066e6ff697 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h @@ -81,13 +81,13 @@ struct hclge_dbg_dfx_message { #define HCLGE_DBG_MAC_REG_TYPE_LEN 32 struct hclge_dbg_reg_type_info { const char *reg_type; - struct hclge_dbg_dfx_message *dfx_msg; + const struct hclge_dbg_dfx_message *dfx_msg; struct hclge_dbg_reg_common_msg reg_msg; }; #pragma pack() -static struct hclge_dbg_dfx_message hclge_dbg_bios_common_reg[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_bios_common_reg[] = { {false, "Reserved"}, {true, "BP_CPU_STATE"}, {true, "DFX_MSIX_INFO_NIC_0"}, @@ -103,7 +103,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_bios_common_reg[] = { {false, "Reserved"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_ssu_reg_0[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_ssu_reg_0[] = { {false, "Reserved"}, {true, "SSU_ETS_PORT_STATUS"}, {true, "SSU_ETS_TCG_STATUS"}, @@ -175,7 +175,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_ssu_reg_0[] = { {false, "Reserved"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_ssu_reg_1[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_ssu_reg_1[] = { {true, "prt_id"}, {true, "PACKET_TC_CURR_BUFFER_CNT_0"}, {true, "PACKET_TC_CURR_BUFFER_CNT_1"}, @@ -282,7 +282,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_ssu_reg_1[] = { {false, "Reserved"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_ssu_reg_2[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_ssu_reg_2[] = { {true, "OQ_INDEX"}, {true, "QUEUE_CNT"}, {false, "Reserved"}, @@ -291,7 +291,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_ssu_reg_2[] = { {false, "Reserved"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_igu_egu_reg[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_igu_egu_reg[] = { {true, "prt_id"}, {true, "IGU_RX_ERR_PKT"}, {true, "IGU_RX_NO_SOF_PKT"}, @@ -356,7 +356,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_igu_egu_reg[] = { {false, "Reserved"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_rpu_reg_0[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_rpu_reg_0[] = { {true, "tc_queue_num"}, {true, "FSM_DFX_ST0"}, {true, "FSM_DFX_ST1"}, @@ -365,7 +365,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_rpu_reg_0[] = { {true, "BUF_WAIT_TIMEOUT_QID"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_rpu_reg_1[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_rpu_reg_1[] = { {false, "Reserved"}, {true, "FIFO_DFX_ST0"}, {true, "FIFO_DFX_ST1"}, @@ -381,7 +381,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_rpu_reg_1[] = { {false, "Reserved"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_ncsi_reg[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_ncsi_reg[] = { {false, "Reserved"}, {true, "NCSI_EGU_TX_FIFO_STS"}, {true, "NCSI_PAUSE_STATUS"}, @@ -453,7 +453,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_ncsi_reg[] = { {true, "NCSI_MAC_RX_PAUSE_FRAMES"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_rtc_reg[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_rtc_reg[] = { {false, "Reserved"}, {true, "LGE_IGU_AFIFO_DFX_0"}, {true, "LGE_IGU_AFIFO_DFX_1"}, @@ -483,7 +483,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_rtc_reg[] = { {false, "Reserved"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_ppp_reg[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_ppp_reg[] = { {false, "Reserved"}, {true, "DROP_FROM_PRT_PKT_CNT"}, {true, "DROP_FROM_HOST_PKT_CNT"}, @@ -639,7 +639,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_ppp_reg[] = { {false, "Reserved"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_rcb_reg[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_rcb_reg[] = { {false, "Reserved"}, {true, "FSM_DFX_ST0"}, {true, "FSM_DFX_ST1"}, @@ -711,7 +711,7 @@ static struct hclge_dbg_dfx_message hclge_dbg_rcb_reg[] = { {false, "Reserved"}, }; -static struct hclge_dbg_dfx_message hclge_dbg_tqp_reg[] = { +static const struct hclge_dbg_dfx_message hclge_dbg_tqp_reg[] = { {true, "q_num"}, {true, "RCB_CFG_RX_RING_TAIL"}, {true, "RCB_CFG_RX_RING_HEAD"}, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c index 50d5ef71756b..9ee55ee0487d 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c @@ -729,7 +729,7 @@ static int hclge_config_ncsi_hw_err_int(struct hclge_dev *hdev, bool en) struct hclge_desc desc; int ret; - if (hdev->pdev->revision < 0x21) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return 0; /* configure NCSI error interrupts */ @@ -808,7 +808,7 @@ static int hclge_config_ppp_error_interrupt(struct hclge_dev *hdev, u32 cmd, cpu_to_le32(HCLGE_PPP_MPF_ECC_ERR_INT0_EN_MASK); desc[1].data[1] = cpu_to_le32(HCLGE_PPP_MPF_ECC_ERR_INT1_EN_MASK); - if (hdev->pdev->revision >= 0x21) + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) desc[1].data[2] = cpu_to_le32(HCLGE_PPP_PF_ERR_INT_EN_MASK); } else if (cmd == HCLGE_PPP_CMD1_INT_CMD) { @@ -1041,7 +1041,7 @@ static int hclge_config_ssu_hw_err_int(struct hclge_dev *hdev, bool en) hclge_cmd_setup_basic_desc(&desc[1], HCLGE_SSU_COMMON_INT_CMD, false); if (en) { - if (hdev->pdev->revision >= 0x21) + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) desc[0].data[0] = cpu_to_le32(HCLGE_SSU_COMMON_INT_EN); else @@ -1507,6 +1507,8 @@ hclge_log_and_clear_rocee_ras_error(struct hclge_dev *hdev) reset_type = HNAE3_FUNC_RESET; + hclge_report_hw_error(hdev, HNAE3_ROCEE_AXI_RESP_ERROR); + ret = hclge_log_rocee_axi_error(hdev); if (ret) return HNAE3_GLOBAL_RESET; @@ -1548,7 +1550,8 @@ int hclge_config_rocee_ras_interrupt(struct hclge_dev *hdev, bool en) struct hclge_desc desc; int ret; - if (hdev->pdev->revision < 0x21 || !hnae3_dev_roce_supported(hdev)) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2 || + !hnae3_dev_roce_supported(hdev)) return 0; hclge_cmd_setup_basic_desc(&desc, HCLGE_CONFIG_ROCEE_RAS_INT_EN, false); @@ -1574,8 +1577,7 @@ static void hclge_handle_rocee_ras_error(struct hnae3_ae_dev *ae_dev) struct hclge_dev *hdev = ae_dev->priv; enum hnae3_reset_type reset_type; - if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || - hdev->pdev->revision < 0x21) + if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) return; reset_type = hclge_log_and_clear_rocee_ras_error(hdev); @@ -1661,7 +1663,7 @@ pci_ers_result_t hclge_handle_hw_ras_error(struct hnae3_ae_dev *ae_dev) } /* Handling Non-fatal Rocee RAS errors */ - if (hdev->pdev->revision >= 0x21 && + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2 && status & HCLGE_RAS_REG_ROCEE_ERR_MASK) { dev_err(dev, "ROCEE Non-Fatal RAS error identified\n"); hclge_handle_rocee_ras_error(ae_dev); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index d553ed7ee64c..1f026408ad38 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -84,6 +84,7 @@ static const struct pci_device_id ae_algo_pci_tbl[] = { {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), 0}, {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), 0}, {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_200G_RDMA), 0}, /* required last entry */ {0, } }; @@ -622,7 +623,7 @@ static u8 *hclge_tqps_get_strings(struct hnae3_handle *handle, u8 *data) { struct hnae3_knic_private_info *kinfo = &handle->kinfo; u8 *buff = data; - int i = 0; + int i; for (i = 0; i < kinfo->num_tqps; i++) { struct hclge_tqp *tqp = container_of(handle->kinfo.tqp[i], @@ -739,7 +740,7 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset) if (stringset == ETH_SS_TEST) { /* clear loopback bit flags at first */ handle->flags = (handle->flags & (~HCLGE_LOOPBACK_TEST_FLAGS)); - if (hdev->pdev->revision >= 0x21 || + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2 || hdev->hw.mac.speed == HCLGE_MAC_SPEED_10M || hdev->hw.mac.speed == HCLGE_MAC_SPEED_100M || hdev->hw.mac.speed == HCLGE_MAC_SPEED_1G) { @@ -965,6 +966,9 @@ static int hclge_parse_speed(int speed_cmd, int *speed) case 5: *speed = HCLGE_MAC_SPEED_100G; break; + case 8: + *speed = HCLGE_MAC_SPEED_200G; + break; default: return -EINVAL; } @@ -1004,6 +1008,9 @@ static int hclge_check_port_speed(struct hnae3_handle *handle, u32 speed) case HCLGE_MAC_SPEED_100G: speed_bit = HCLGE_SUPPORT_100G_BIT; break; + case HCLGE_MAC_SPEED_200G: + speed_bit = HCLGE_SUPPORT_200G_BIT; + break; default: return -EINVAL; } @@ -1014,7 +1021,7 @@ static int hclge_check_port_speed(struct hnae3_handle *handle, u32 speed) return -EINVAL; } -static void hclge_convert_setting_sr(struct hclge_mac *mac, u8 speed_ability) +static void hclge_convert_setting_sr(struct hclge_mac *mac, u16 speed_ability) { if (speed_ability & HCLGE_SUPPORT_10G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, @@ -1031,9 +1038,12 @@ static void hclge_convert_setting_sr(struct hclge_mac *mac, u8 speed_ability) if (speed_ability & HCLGE_SUPPORT_100G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, mac->supported); + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + linkmode_set_bit(ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, + mac->supported); } -static void hclge_convert_setting_lr(struct hclge_mac *mac, u8 speed_ability) +static void hclge_convert_setting_lr(struct hclge_mac *mac, u16 speed_ability) { if (speed_ability & HCLGE_SUPPORT_10G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, @@ -1050,9 +1060,13 @@ static void hclge_convert_setting_lr(struct hclge_mac *mac, u8 speed_ability) if (speed_ability & HCLGE_SUPPORT_100G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, mac->supported); + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + linkmode_set_bit( + ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, + mac->supported); } -static void hclge_convert_setting_cr(struct hclge_mac *mac, u8 speed_ability) +static void hclge_convert_setting_cr(struct hclge_mac *mac, u16 speed_ability) { if (speed_ability & HCLGE_SUPPORT_10G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, @@ -1069,9 +1083,12 @@ static void hclge_convert_setting_cr(struct hclge_mac *mac, u8 speed_ability) if (speed_ability & HCLGE_SUPPORT_100G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, mac->supported); + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + linkmode_set_bit(ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, + mac->supported); } -static void hclge_convert_setting_kr(struct hclge_mac *mac, u8 speed_ability) +static void hclge_convert_setting_kr(struct hclge_mac *mac, u16 speed_ability) { if (speed_ability & HCLGE_SUPPORT_1G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, @@ -1091,6 +1108,9 @@ static void hclge_convert_setting_kr(struct hclge_mac *mac, u8 speed_ability) if (speed_ability & HCLGE_SUPPORT_100G_BIT) linkmode_set_bit(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, mac->supported); + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + linkmode_set_bit(ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, + mac->supported); } static void hclge_convert_setting_fec(struct hclge_mac *mac) @@ -1115,6 +1135,7 @@ static void hclge_convert_setting_fec(struct hclge_mac *mac) BIT(HNAE3_FEC_AUTO); break; case HCLGE_MAC_SPEED_100G: + case HCLGE_MAC_SPEED_200G: linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, mac->supported); mac->fec_ability = BIT(HNAE3_FEC_RS) | BIT(HNAE3_FEC_AUTO); break; @@ -1125,7 +1146,7 @@ static void hclge_convert_setting_fec(struct hclge_mac *mac) } static void hclge_parse_fiber_link_mode(struct hclge_dev *hdev, - u8 speed_ability) + u16 speed_ability) { struct hclge_mac *mac = &hdev->hw.mac; @@ -1136,7 +1157,7 @@ static void hclge_parse_fiber_link_mode(struct hclge_dev *hdev, hclge_convert_setting_sr(mac, speed_ability); hclge_convert_setting_lr(mac, speed_ability); hclge_convert_setting_cr(mac, speed_ability); - if (hdev->pdev->revision >= 0x21) + if (hnae3_dev_fec_supported(hdev)) hclge_convert_setting_fec(mac); linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, mac->supported); @@ -1145,12 +1166,12 @@ static void hclge_parse_fiber_link_mode(struct hclge_dev *hdev, } static void hclge_parse_backplane_link_mode(struct hclge_dev *hdev, - u8 speed_ability) + u16 speed_ability) { struct hclge_mac *mac = &hdev->hw.mac; hclge_convert_setting_kr(mac, speed_ability); - if (hdev->pdev->revision >= 0x21) + if (hnae3_dev_fec_supported(hdev)) hclge_convert_setting_fec(mac); linkmode_set_bit(ETHTOOL_LINK_MODE_Backplane_BIT, mac->supported); linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, mac->supported); @@ -1158,7 +1179,7 @@ static void hclge_parse_backplane_link_mode(struct hclge_dev *hdev, } static void hclge_parse_copper_link_mode(struct hclge_dev *hdev, - u8 speed_ability) + u16 speed_ability) { unsigned long *supported = hdev->hw.mac.supported; @@ -1188,7 +1209,7 @@ static void hclge_parse_copper_link_mode(struct hclge_dev *hdev, linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, supported); } -static void hclge_parse_link_mode(struct hclge_dev *hdev, u8 speed_ability) +static void hclge_parse_link_mode(struct hclge_dev *hdev, u16 speed_ability) { u8 media_type = hdev->hw.mac.media_type; @@ -1200,8 +1221,11 @@ static void hclge_parse_link_mode(struct hclge_dev *hdev, u8 speed_ability) hclge_parse_backplane_link_mode(hdev, speed_ability); } -static u32 hclge_get_max_speed(u8 speed_ability) +static u32 hclge_get_max_speed(u16 speed_ability) { + if (speed_ability & HCLGE_SUPPORT_200G_BIT) + return HCLGE_MAC_SPEED_200G; + if (speed_ability & HCLGE_SUPPORT_100G_BIT) return HCLGE_MAC_SPEED_100G; @@ -1231,8 +1255,11 @@ static u32 hclge_get_max_speed(u8 speed_ability) static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) { +#define SPEED_ABILITY_EXT_SHIFT 8 + struct hclge_cfg_param_cmd *req; u64 mac_addr_tmp_high; + u16 speed_ability_ext; u64 mac_addr_tmp; unsigned int i; @@ -1281,6 +1308,11 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) cfg->speed_ability = hnae3_get_field(__le32_to_cpu(req->param[1]), HCLGE_CFG_SPEED_ABILITY_M, HCLGE_CFG_SPEED_ABILITY_S); + speed_ability_ext = hnae3_get_field(__le32_to_cpu(req->param[1]), + HCLGE_CFG_SPEED_ABILITY_EXT_M, + HCLGE_CFG_SPEED_ABILITY_EXT_S); + cfg->speed_ability |= speed_ability_ext << SPEED_ABILITY_EXT_SHIFT; + cfg->umv_space = hnae3_get_field(__le32_to_cpu(req->param[1]), HCLGE_CFG_UMV_TBL_SPACE_M, HCLGE_CFG_UMV_TBL_SPACE_S); @@ -1324,6 +1356,78 @@ static int hclge_get_cfg(struct hclge_dev *hdev, struct hclge_cfg *hcfg) return 0; } +static void hclge_set_default_dev_specs(struct hclge_dev *hdev) +{ +#define HCLGE_MAX_NON_TSO_BD_NUM 8U + + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + + ae_dev->dev_specs.max_non_tso_bd_num = HCLGE_MAX_NON_TSO_BD_NUM; + ae_dev->dev_specs.rss_ind_tbl_size = HCLGE_RSS_IND_TBL_SIZE; + ae_dev->dev_specs.rss_key_size = HCLGE_RSS_KEY_SIZE; + ae_dev->dev_specs.max_tm_rate = HCLGE_ETHER_MAX_RATE; +} + +static void hclge_parse_dev_specs(struct hclge_dev *hdev, + struct hclge_desc *desc) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + struct hclge_dev_specs_0_cmd *req0; + + req0 = (struct hclge_dev_specs_0_cmd *)desc[0].data; + + ae_dev->dev_specs.max_non_tso_bd_num = req0->max_non_tso_bd_num; + ae_dev->dev_specs.rss_ind_tbl_size = + le16_to_cpu(req0->rss_ind_tbl_size); + ae_dev->dev_specs.rss_key_size = le16_to_cpu(req0->rss_key_size); + ae_dev->dev_specs.max_tm_rate = le32_to_cpu(req0->max_tm_rate); +} + +static void hclge_check_dev_specs(struct hclge_dev *hdev) +{ + struct hnae3_dev_specs *dev_specs = &hdev->ae_dev->dev_specs; + + if (!dev_specs->max_non_tso_bd_num) + dev_specs->max_non_tso_bd_num = HCLGE_MAX_NON_TSO_BD_NUM; + if (!dev_specs->rss_ind_tbl_size) + dev_specs->rss_ind_tbl_size = HCLGE_RSS_IND_TBL_SIZE; + if (!dev_specs->rss_key_size) + dev_specs->rss_key_size = HCLGE_RSS_KEY_SIZE; + if (!dev_specs->max_tm_rate) + dev_specs->max_tm_rate = HCLGE_ETHER_MAX_RATE; +} + +static int hclge_query_dev_specs(struct hclge_dev *hdev) +{ + struct hclge_desc desc[HCLGE_QUERY_DEV_SPECS_BD_NUM]; + int ret; + int i; + + /* set default specifications as devices lower than version V3 do not + * support querying specifications from firmware. + */ + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) { + hclge_set_default_dev_specs(hdev); + return 0; + } + + for (i = 0; i < HCLGE_QUERY_DEV_SPECS_BD_NUM - 1; i++) { + hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_QUERY_DEV_SPECS, + true); + desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); + } + hclge_cmd_setup_basic_desc(&desc[i], HCLGE_OPC_QUERY_DEV_SPECS, true); + + ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_QUERY_DEV_SPECS_BD_NUM); + if (ret) + return ret; + + hclge_parse_dev_specs(hdev, desc); + hclge_check_dev_specs(hdev); + + return 0; +} + static int hclge_get_cap(struct hclge_dev *hdev) { int ret; @@ -2422,6 +2526,10 @@ static int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed, hnae3_set_field(req->speed_dup, HCLGE_CFG_SPEED_M, HCLGE_CFG_SPEED_S, 5); break; + case HCLGE_MAC_SPEED_200G: + hnae3_set_field(req->speed_dup, HCLGE_CFG_SPEED_M, + HCLGE_CFG_SPEED_S, 8); + break; default: dev_err(&hdev->pdev->dev, "invalid speed (%d)\n", speed); return -EINVAL; @@ -2856,7 +2964,7 @@ static int hclge_update_port_info(struct hclge_dev *hdev) if (!hdev->support_sfp_query) return 0; - if (hdev->pdev->revision >= 0x21) + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) ret = hclge_get_sfp_info(hdev, mac); else ret = hclge_get_sfp_speed(hdev, &speed); @@ -2868,7 +2976,7 @@ static int hclge_update_port_info(struct hclge_dev *hdev) return ret; } - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { if (mac->speed_type == QUERY_ACTIVE_SPEED) { hclge_update_port_capability(mac); return 0; @@ -3211,7 +3319,7 @@ static int hclge_notify_roce_client(struct hclge_dev *hdev, enum hnae3_reset_notify_type type) { struct hnae3_client *client = hdev->roce_client; - int ret = 0; + int ret; u16 i; if (!test_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state) || !client) @@ -3533,7 +3641,7 @@ static void hclge_clear_reset_cause(struct hclge_dev *hdev) /* For revision 0x20, the reset interrupt source * can only be cleared after hardware reset done */ - if (hdev->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, clearval); @@ -3944,6 +4052,9 @@ static void hclge_periodic_service_task(struct hclge_dev *hdev) { unsigned long delta = round_jiffies_relative(HZ); + if (test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) + return; + /* Always handle the link updating to make sure link state is * updated when it is triggered by mbx. */ @@ -4537,7 +4648,7 @@ static void hclge_rss_init_cfg(struct hclge_dev *hdev) int i, rss_algo = HCLGE_RSS_HASH_ALGO_TOEPLITZ; struct hclge_vport *vport = hdev->vport; - if (hdev->pdev->revision >= 0x21) + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) rss_algo = HCLGE_RSS_HASH_ALGO_SIMPLE; for (i = 0; i < hdev->num_vmdq_vport + 1; i++) { @@ -4737,13 +4848,14 @@ static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc, bool en_mc_pmc) { struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; bool en_bc_pmc = true; - /* For revision 0x20, if broadcast promisc enabled, vlan filter is - * always bypassed. So broadcast promisc should be disabled until - * user enable promisc mode + /* For device whose version below V2, if broadcast promisc enabled, + * vlan filter is always bypassed. So broadcast promisc should be + * disabled until user enable promisc mode */ - if (handle->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) en_bc_pmc = handle->netdev_flags & HNAE3_BPE ? true : false; return hclge_set_vport_promisc_mode(vport, en_uc_pmc, en_mc_pmc, @@ -6758,7 +6870,7 @@ static int hclge_set_loopback(struct hnae3_handle *handle, * the same, the packets are looped back in the SSU. If SSU loopback * is disabled, packets can reach MAC even if SMAC is the same as DMAC. */ - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { u8 switch_param = en ? 0 : BIT(HCLGE_SWITCH_ALW_LPBK_B); ret = hclge_config_switch_param(hdev, PF_VPORT_ID, switch_param, @@ -8260,7 +8372,7 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable) struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, HCLGE_FILTER_FE_EGRESS, enable, 0); hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, @@ -8620,7 +8732,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) int ret; int i; - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { /* for revision 0x21, vf vlan filter is per function */ for (i = 0; i < hdev->num_alloc_vport; i++) { vport = &hdev->vport[i]; @@ -8975,7 +9087,7 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid, u16 state; int ret; - if (hdev->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return -EOPNOTSUPP; vport = hclge_get_vf_vport(hdev, vfid); @@ -9950,6 +10062,13 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) if (ret) goto err_cmd_uninit; + ret = hclge_query_dev_specs(hdev); + if (ret) { + dev_err(&pdev->dev, "failed to query dev specifications, ret = %d.\n", + ret); + goto err_cmd_uninit; + } + ret = hclge_configure(hdev); if (ret) { dev_err(&pdev->dev, "Configure dev error, ret = %d.\n", ret); @@ -10147,7 +10266,7 @@ static int hclge_set_vf_spoofchk(struct hnae3_handle *handle, int vf, u32 new_spoofchk = enable ? 1 : 0; int ret; - if (hdev->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return -EOPNOTSUPP; vport = hclge_get_vf_vport(hdev, vf); @@ -10180,7 +10299,7 @@ static int hclge_reset_vport_spoofchk(struct hclge_dev *hdev) int ret; int i; - if (hdev->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return 0; /* resume the vf spoof check state after reset */ @@ -10200,6 +10319,7 @@ static int hclge_set_vf_trust(struct hnae3_handle *handle, int vf, bool enable) { struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; + struct hnae3_ae_dev *ae_dev = hdev->ae_dev; u32 new_trusted = enable ? 1 : 0; bool en_bc_pmc; int ret; @@ -10213,7 +10333,7 @@ static int hclge_set_vf_trust(struct hnae3_handle *handle, int vf, bool enable) /* Disable promisc mode for VF if it is not trusted any more. */ if (!enable && vport->vf_info.promisc_enable) { - en_bc_pmc = hdev->pdev->revision != 0x20; + en_bc_pmc = ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2; ret = hclge_set_vport_promisc_mode(vport, false, false, en_bc_pmc); if (ret) @@ -11090,7 +11210,7 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev) { struct hclge_vport *vport = &hdev->vport[0]; struct hnae3_handle *handle = &vport->nic; - u8 tmp_flags = 0; + u8 tmp_flags; int ret; if (vport->last_promisc_flags != vport->overflow_promisc_flags) { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 9bbdd4557c27..64e6afdb61b8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -199,6 +199,7 @@ enum HLCGE_PORT_TYPE { #define HCLGE_SUPPORT_40G_BIT BIT(5) #define HCLGE_SUPPORT_100M_BIT BIT(6) #define HCLGE_SUPPORT_10M_BIT BIT(7) +#define HCLGE_SUPPORT_200G_BIT BIT(8) #define HCLGE_SUPPORT_GE \ (HCLGE_SUPPORT_1G_BIT | HCLGE_SUPPORT_100M_BIT | HCLGE_SUPPORT_10M_BIT) @@ -238,7 +239,8 @@ enum HCLGE_MAC_SPEED { HCLGE_MAC_SPEED_25G = 25000, /* 25000 Mbps = 25 Gbps */ HCLGE_MAC_SPEED_40G = 40000, /* 40000 Mbps = 40 Gbps */ HCLGE_MAC_SPEED_50G = 50000, /* 50000 Mbps = 50 Gbps */ - HCLGE_MAC_SPEED_100G = 100000 /* 100000 Mbps = 100 Gbps */ + HCLGE_MAC_SPEED_100G = 100000, /* 100000 Mbps = 100 Gbps */ + HCLGE_MAC_SPEED_200G = 200000 /* 200000 Mbps = 200 Gbps */ }; enum HCLGE_MAC_DUPLEX { @@ -266,7 +268,7 @@ struct hclge_mac { u32 fec_mode; /* active fec mode */ u32 user_fec_mode; u32 fec_ability; - int link; /* store the link status of mac & phy (if phy exit) */ + int link; /* store the link status of mac & phy (if phy exists) */ struct phy_device *phydev; struct mii_bus *mdio_bus; phy_interface_t phy_if; @@ -349,7 +351,7 @@ struct hclge_cfg { u8 mac_addr[ETH_ALEN]; u8 default_speed; u32 numa_node_map; - u8 speed_ability; + u16 speed_ability; u16 umv_space; }; @@ -749,7 +751,6 @@ struct hclge_dev { u16 num_tx_desc; /* desc num of per tx queue */ u16 num_rx_desc; /* desc num of per rx queue */ u8 hw_tc_map; - u8 tc_num_last_time; enum hclge_fc_mode fc_mode_last_time; u8 support_sfp_query; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index 28db13253a5e..15f69fa86323 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -23,14 +23,11 @@ enum hclge_shaper_level { #define HCLGE_SHAPER_BS_U_DEF 5 #define HCLGE_SHAPER_BS_S_DEF 20 -#define HCLGE_ETHER_MAX_RATE 100000 - /* hclge_shaper_para_calc: calculate ir parameter for the shaper * @ir: Rate to be config, its unit is Mbps * @shaper_level: the shaper level. eg: port, pg, priority, queueset - * @ir_b: IR_B parameter of IR shaper - * @ir_u: IR_U parameter of IR shaper - * @ir_s: IR_S parameter of IR shaper + * @ir_para: parameters of IR shaper + * @max_tm_rate: max tm rate is available to config * * the formula: * @@ -41,7 +38,8 @@ enum hclge_shaper_level { * @return: 0: calculate sucessful, negative: fail */ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, - u8 *ir_b, u8 *ir_u, u8 *ir_s) + struct hclge_shaper_ir_para *ir_para, + u32 max_tm_rate) { #define DIVISOR_CLK (1000 * 8) #define DIVISOR_IR_B_126 (126 * DIVISOR_CLK) @@ -59,7 +57,7 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, /* Calc tick */ if (shaper_level >= HCLGE_SHAPER_LVL_CNT || - ir > HCLGE_ETHER_MAX_RATE) + ir > max_tm_rate) return -EINVAL; tick = tick_array[shaper_level]; @@ -74,9 +72,9 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, ir_calc = (DIVISOR_IR_B_126 + (tick >> 1) - 1) / tick; if (ir_calc == ir) { - *ir_b = 126; - *ir_u = 0; - *ir_s = 0; + ir_para->ir_b = 126; + ir_para->ir_u = 0; + ir_para->ir_s = 0; return 0; } else if (ir_calc > ir) { @@ -86,8 +84,8 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, ir_calc = DIVISOR_IR_B_126 / (tick * (1 << ir_s_calc)); } - *ir_b = (ir * tick * (1 << ir_s_calc) + (DIVISOR_CLK >> 1)) / - DIVISOR_CLK; + ir_para->ir_b = (ir * tick * (1 << ir_s_calc) + + (DIVISOR_CLK >> 1)) / DIVISOR_CLK; } else { /* Increasing the numerator to select ir_u value */ u32 numerator; @@ -99,15 +97,16 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, } if (ir_calc == ir) { - *ir_b = 126; + ir_para->ir_b = 126; } else { u32 denominator = DIVISOR_CLK * (1 << --ir_u_calc); - *ir_b = (ir * tick + (denominator >> 1)) / denominator; + ir_para->ir_b = (ir * tick + (denominator >> 1)) / + denominator; } } - *ir_u = ir_u_calc; - *ir_s = ir_s_calc; + ir_para->ir_u = ir_u_calc; + ir_para->ir_s = ir_s_calc; return 0; } @@ -400,21 +399,22 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev, static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev) { struct hclge_port_shapping_cmd *shap_cfg_cmd; + struct hclge_shaper_ir_para ir_para; struct hclge_desc desc; - u8 ir_u, ir_b, ir_s; u32 shapping_para; int ret; - ret = hclge_shaper_para_calc(hdev->hw.mac.speed, - HCLGE_SHAPER_LVL_PORT, - &ir_b, &ir_u, &ir_s); + ret = hclge_shaper_para_calc(hdev->hw.mac.speed, HCLGE_SHAPER_LVL_PORT, + &ir_para, + hdev->ae_dev->dev_specs.max_tm_rate); if (ret) return ret; hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, false); shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data; - shapping_para = hclge_tm_get_shapping_para(ir_b, ir_u, ir_s, + shapping_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u, + ir_para.ir_s, HCLGE_SHAPER_BS_U_DEF, HCLGE_SHAPER_BS_S_DEF); @@ -515,21 +515,23 @@ int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate) { struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; struct hclge_qs_shapping_cmd *shap_cfg_cmd; + struct hclge_shaper_ir_para ir_para; struct hclge_dev *hdev = vport->back; struct hclge_desc desc; - u8 ir_b, ir_u, ir_s; u32 shaper_para; int ret, i; if (!max_tx_rate) - max_tx_rate = HCLGE_ETHER_MAX_RATE; + max_tx_rate = hdev->ae_dev->dev_specs.max_tm_rate; ret = hclge_shaper_para_calc(max_tx_rate, HCLGE_SHAPER_LVL_QSET, - &ir_b, &ir_u, &ir_s); + &ir_para, + hdev->ae_dev->dev_specs.max_tm_rate); if (ret) return ret; - shaper_para = hclge_tm_get_shapping_para(ir_b, ir_u, ir_s, + shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u, + ir_para.ir_s, HCLGE_SHAPER_BS_U_DEF, HCLGE_SHAPER_BS_S_DEF); @@ -668,7 +670,8 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev) hdev->tm_info.pg_info[i].pg_id = i; hdev->tm_info.pg_info[i].pg_sch_mode = HCLGE_SCH_MODE_DWRR; - hdev->tm_info.pg_info[i].bw_limit = HCLGE_ETHER_MAX_RATE; + hdev->tm_info.pg_info[i].bw_limit = + hdev->ae_dev->dev_specs.max_tm_rate; if (i != 0) continue; @@ -729,7 +732,8 @@ static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev) static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) { - u8 ir_u, ir_b, ir_s; + u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; + struct hclge_shaper_ir_para ir_para; u32 shaper_para; int ret; u32 i; @@ -741,10 +745,9 @@ static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) /* Pg to pri */ for (i = 0; i < hdev->tm_info.num_pg; i++) { /* Calc shaper para */ - ret = hclge_shaper_para_calc( - hdev->tm_info.pg_info[i].bw_limit, - HCLGE_SHAPER_LVL_PG, - &ir_b, &ir_u, &ir_s); + ret = hclge_shaper_para_calc(hdev->tm_info.pg_info[i].bw_limit, + HCLGE_SHAPER_LVL_PG, + &ir_para, max_tm_rate); if (ret) return ret; @@ -757,7 +760,9 @@ static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) if (ret) return ret; - shaper_para = hclge_tm_get_shapping_para(ir_b, ir_u, ir_s, + shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, + ir_para.ir_u, + ir_para.ir_s, HCLGE_SHAPER_BS_U_DEF, HCLGE_SHAPER_BS_S_DEF); ret = hclge_tm_pg_shapping_cfg(hdev, @@ -861,16 +866,16 @@ static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev) static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev) { - u8 ir_u, ir_b, ir_s; + u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; + struct hclge_shaper_ir_para ir_para; u32 shaper_para; int ret; u32 i; for (i = 0; i < hdev->tm_info.num_tc; i++) { - ret = hclge_shaper_para_calc( - hdev->tm_info.tc_info[i].bw_limit, - HCLGE_SHAPER_LVL_PRI, - &ir_b, &ir_u, &ir_s); + ret = hclge_shaper_para_calc(hdev->tm_info.tc_info[i].bw_limit, + HCLGE_SHAPER_LVL_PRI, + &ir_para, max_tm_rate); if (ret) return ret; @@ -882,7 +887,9 @@ static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev) if (ret) return ret; - shaper_para = hclge_tm_get_shapping_para(ir_b, ir_u, ir_s, + shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, + ir_para.ir_u, + ir_para.ir_s, HCLGE_SHAPER_BS_U_DEF, HCLGE_SHAPER_BS_S_DEF); ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i, @@ -897,12 +904,13 @@ static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev) static int hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport *vport) { struct hclge_dev *hdev = vport->back; - u8 ir_u, ir_b, ir_s; + struct hclge_shaper_ir_para ir_para; u32 shaper_para; int ret; ret = hclge_shaper_para_calc(vport->bw_limit, HCLGE_SHAPER_LVL_VF, - &ir_b, &ir_u, &ir_s); + &ir_para, + hdev->ae_dev->dev_specs.max_tm_rate); if (ret) return ret; @@ -914,7 +922,8 @@ static int hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport *vport) if (ret) return ret; - shaper_para = hclge_tm_get_shapping_para(ir_b, ir_u, ir_s, + shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u, + ir_para.ir_s, HCLGE_SHAPER_BS_U_DEF, HCLGE_SHAPER_BS_S_DEF); ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, @@ -929,15 +938,15 @@ static int hclge_tm_pri_vnet_base_shaper_qs_cfg(struct hclge_vport *vport) { struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; struct hclge_dev *hdev = vport->back; - u8 ir_u, ir_b, ir_s; + u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; + struct hclge_shaper_ir_para ir_para; u32 i; int ret; for (i = 0; i < kinfo->num_tc; i++) { - ret = hclge_shaper_para_calc( - hdev->tm_info.tc_info[i].bw_limit, - HCLGE_SHAPER_LVL_QSET, - &ir_b, &ir_u, &ir_s); + ret = hclge_shaper_para_calc(hdev->tm_info.tc_info[i].bw_limit, + HCLGE_SHAPER_LVL_QSET, + &ir_para, max_tm_rate); if (ret) return ret; } @@ -1355,7 +1364,7 @@ static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) static int hclge_tm_bp_setup(struct hclge_dev *hdev) { - int ret = 0; + int ret; int i; for (i = 0; i < hdev->tm_info.num_tc; i++) { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h index 45bcb67f90fd..bb2a2d8e9259 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h @@ -19,6 +19,8 @@ #define HCLGE_TM_TX_SCHD_DWRR_MSK BIT(0) #define HCLGE_TM_TX_SCHD_SP_MSK (0xFE) +#define HCLGE_ETHER_MAX_RATE 100000 + struct hclge_pg_to_pri_link_cmd { u8 pg_id; u8 rsvd1[3]; @@ -139,6 +141,12 @@ struct hclge_port_shapping_cmd { __le32 port_shapping_para; }; +struct hclge_shaper_ir_para { + u8 ir_b; /* IR_B parameter of IR shaper */ + u8 ir_u; /* IR_U parameter of IR shaper */ + u8 ir_s; /* IR_S parameter of IR shaper */ +}; + #define hclge_tm_set_field(dest, string, val) \ hnae3_set_field((dest), \ (HCLGE_TM_SHAP_##string##_MSK), \ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c index fec65239a3c8..66866c1cfb12 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c @@ -313,9 +313,34 @@ int hclgevf_cmd_send(struct hclgevf_hw *hw, struct hclgevf_desc *desc, int num) return status; } -static int hclgevf_cmd_query_firmware_version(struct hclgevf_hw *hw, - u32 *version) +static void hclgevf_set_default_capability(struct hclgevf_dev *hdev) { + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + + set_bit(HNAE3_DEV_SUPPORT_FD_B, ae_dev->caps); + set_bit(HNAE3_DEV_SUPPORT_GRO_B, ae_dev->caps); + set_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps); +} + +static void hclgevf_parse_capability(struct hclgevf_dev *hdev, + struct hclgevf_query_version_cmd *cmd) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + u32 caps; + + caps = __le32_to_cpu(cmd->caps[0]); + + if (hnae3_get_bit(caps, HCLGEVF_CAP_UDP_GSO_B)) + set_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, ae_dev->caps); + if (hnae3_get_bit(caps, HCLGEVF_CAP_INT_QL_B)) + set_bit(HNAE3_DEV_SUPPORT_INT_QL_B, ae_dev->caps); + if (hnae3_get_bit(caps, HCLGEVF_CAP_TQP_TXRX_INDEP_B)) + set_bit(HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B, ae_dev->caps); +} + +static int hclgevf_cmd_query_version_and_capability(struct hclgevf_dev *hdev) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); struct hclgevf_query_version_cmd *resp; struct hclgevf_desc desc; int status; @@ -323,9 +348,20 @@ static int hclgevf_cmd_query_firmware_version(struct hclgevf_hw *hw, resp = (struct hclgevf_query_version_cmd *)desc.data; hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_QUERY_FW_VER, 1); - status = hclgevf_cmd_send(hw, &desc, 1); - if (!status) - *version = le32_to_cpu(resp->firmware); + status = hclgevf_cmd_send(&hdev->hw, &desc, 1); + if (status) + return status; + + hdev->fw_version = le32_to_cpu(resp->firmware); + + ae_dev->dev_version = le32_to_cpu(resp->hardware) << + HNAE3_PCI_REVISION_BIT_SIZE; + ae_dev->dev_version |= hdev->pdev->revision; + + if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) + hclgevf_set_default_capability(hdev); + + hclgevf_parse_capability(hdev, resp); return status; } @@ -364,7 +400,6 @@ err_csq: int hclgevf_cmd_init(struct hclgevf_dev *hdev) { - u32 version; int ret; spin_lock_bh(&hdev->hw.cmq.csq.lock); @@ -395,23 +430,22 @@ int hclgevf_cmd_init(struct hclgevf_dev *hdev) goto err_cmd_init; } - /* get firmware version */ - ret = hclgevf_cmd_query_firmware_version(&hdev->hw, &version); + /* get version and device capabilities */ + ret = hclgevf_cmd_query_version_and_capability(hdev); if (ret) { dev_err(&hdev->pdev->dev, - "failed(%d) to query firmware version\n", ret); + "failed to query version and capabilities, ret = %d\n", ret); goto err_cmd_init; } - hdev->fw_version = version; dev_info(&hdev->pdev->dev, "The firmware version is %lu.%lu.%lu.%lu\n", - hnae3_get_field(version, HNAE3_FW_VERSION_BYTE3_MASK, + hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK, HNAE3_FW_VERSION_BYTE3_SHIFT), - hnae3_get_field(version, HNAE3_FW_VERSION_BYTE2_MASK, + hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE2_MASK, HNAE3_FW_VERSION_BYTE2_SHIFT), - hnae3_get_field(version, HNAE3_FW_VERSION_BYTE1_MASK, + hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE1_MASK, HNAE3_FW_VERSION_BYTE1_SHIFT), - hnae3_get_field(version, HNAE3_FW_VERSION_BYTE0_MASK, + hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK, HNAE3_FW_VERSION_BYTE0_SHIFT)); return 0; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h index 40d6e602ab51..9460c128c095 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h @@ -91,6 +91,8 @@ enum hclgevf_opcode_type { /* Generic command */ HCLGEVF_OPC_QUERY_FW_VER = 0x0001, HCLGEVF_OPC_QUERY_VF_RSRC = 0x0024, + HCLGEVF_OPC_QUERY_DEV_SPECS = 0x0050, + /* TQP command */ HCLGEVF_OPC_QUERY_TX_STATUS = 0x0B03, HCLGEVF_OPC_QUERY_RX_STATUS = 0x0B13, @@ -141,9 +143,26 @@ struct hclgevf_ctrl_vector_chain { u8 resv; }; +enum HCLGEVF_CAP_BITS { + HCLGEVF_CAP_UDP_GSO_B, + HCLGEVF_CAP_QB_B, + HCLGEVF_CAP_FD_FORWARD_TC_B, + HCLGEVF_CAP_PTP_B, + HCLGEVF_CAP_INT_QL_B, + HCLGEVF_CAP_SIMPLE_BD_B, + HCLGEVF_CAP_TX_PUSH_B, + HCLGEVF_CAP_PHY_IMP_B, + HCLGEVF_CAP_TQP_TXRX_INDEP_B, + HCLGEVF_CAP_HW_PAD_B, + HCLGEVF_CAP_STASH_B, +}; + +#define HCLGEVF_QUERY_CAP_LENGTH 3 struct hclgevf_query_version_cmd { __le32 firmware; - __le32 firmware_rsv[5]; + __le32 hardware; + __le32 rsv; + __le32 caps[HCLGEVF_QUERY_CAP_LENGTH]; /* capabilities of device */ }; #define HCLGEVF_MSIX_OFT_ROCEE_S 0 @@ -253,6 +272,19 @@ struct hclgevf_cfg_tx_queue_pointer_cmd { #define HCLGEVF_NIC_CMQ_DESC_NUM_S 3 #define HCLGEVF_NIC_CMDQ_INT_SRC_REG 0x27100 +#define HCLGEVF_QUERY_DEV_SPECS_BD_NUM 4 + +struct hclgevf_dev_specs_0_cmd { + __le32 rsv0; + __le32 mac_entry_num; + __le32 mng_entry_num; + __le16 rss_ind_tbl_size; + __le16 rss_key_size; + __le16 int_ql_max; + u8 max_non_tso_bd_num; + u8 rsv1[5]; +}; + static inline void hclgevf_write_reg(void __iomem *base, u32 reg, u32 value) { writel(value, base + reg); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index e972138a14ad..50c84c5e65d2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -19,8 +19,9 @@ static struct hnae3_ae_algo ae_algovf; static struct workqueue_struct *hclgevf_wq; static const struct pci_device_id ae_algovf_pci_tbl[] = { - {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_VF), 0}, - {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_VF), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_RDMA_DCB_PFC_VF), + HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, /* required last entry */ {0, } }; @@ -171,7 +172,7 @@ static u8 *hclgevf_tqps_get_strings(struct hnae3_handle *handle, u8 *data) { struct hnae3_knic_private_info *kinfo = &handle->kinfo; u8 *buff = data; - int i = 0; + int i; for (i = 0; i < kinfo->num_tqps; i++) { struct hclgevf_tqp *tqp = container_of(kinfo->tqp[i], @@ -745,7 +746,7 @@ static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key, struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; int i, ret; - if (handle->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { /* Get hash algorithm */ if (hfunc) { switch (rss_cfg->hash_algo) { @@ -791,7 +792,7 @@ static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir, struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; int ret, i; - if (handle->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { /* Set the RSS Hash Key if specififed by the user */ if (key) { switch (hfunc) { @@ -863,7 +864,7 @@ static int hclgevf_set_rss_tuple(struct hnae3_handle *handle, u8 tuple_sets; int ret; - if (handle->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return -EOPNOTSUPP; if (nfc->data & @@ -941,7 +942,7 @@ static int hclgevf_get_rss_tuple(struct hnae3_handle *handle, struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; u8 tuple_sets; - if (handle->pdev->revision == 0x20) + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) return -EOPNOTSUPP; nfc->data = 0; @@ -1154,10 +1155,9 @@ static int hclgevf_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc, bool en_mc_pmc) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); - struct pci_dev *pdev = hdev->pdev; bool en_bc_pmc; - en_bc_pmc = pdev->revision != 0x20; + en_bc_pmc = hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2; return hclgevf_cmd_set_promisc_mode(hdev, en_uc_pmc, en_mc_pmc, en_bc_pmc); @@ -1702,6 +1702,26 @@ static int hclgevf_notify_client(struct hclgevf_dev *hdev, return ret; } +static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev, + enum hnae3_reset_notify_type type) +{ + struct hnae3_client *client = hdev->roce_client; + struct hnae3_handle *handle = &hdev->roce; + int ret; + + if (!test_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state) || !client) + return 0; + + if (!client->ops->reset_notify) + return -EOPNOTSUPP; + + ret = client->ops->reset_notify(handle, type); + if (ret) + dev_err(&hdev->pdev->dev, "notify roce client failed %d(%d)", + type, ret); + return ret; +} + static int hclgevf_reset_wait(struct hclgevf_dev *hdev) { #define HCLGEVF_RESET_WAIT_US 20000 @@ -1788,10 +1808,10 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev) { #define HCLGEVF_RESET_SYNC_TIME 100 - struct hclge_vf_to_pf_msg send_msg; - int ret = 0; - if (hdev->reset_type == HNAE3_VF_FUNC_RESET) { + struct hclge_vf_to_pf_msg send_msg; + int ret; + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_RESET, 0); ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); if (ret) { @@ -1806,10 +1826,10 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev) /* inform hardware that preparatory work is done */ msleep(HCLGEVF_RESET_SYNC_TIME); hclgevf_reset_handshake(hdev, true); - dev_info(&hdev->pdev->dev, "prepare reset(%d) wait done, ret:%d\n", - hdev->reset_type, ret); + dev_info(&hdev->pdev->dev, "prepare reset(%d) wait done\n", + hdev->reset_type); - return ret; + return 0; } static void hclgevf_dump_rst_info(struct hclgevf_dev *hdev) @@ -1865,6 +1885,11 @@ static int hclgevf_reset_prepare(struct hclgevf_dev *hdev) hdev->rst_stats.rst_cnt++; + /* perform reset of the stack & ae device for a client */ + ret = hclgevf_notify_roce_client(hdev, HNAE3_DOWN_CLIENT); + if (ret) + return ret; + rtnl_lock(); /* bring down the nic to stop any ongoing TX/RX */ ret = hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT); @@ -1880,6 +1905,9 @@ static int hclgevf_reset_rebuild(struct hclgevf_dev *hdev) int ret; hdev->rst_stats.hw_rst_done_cnt++; + ret = hclgevf_notify_roce_client(hdev, HNAE3_UNINIT_CLIENT); + if (ret) + return ret; rtnl_lock(); /* now, re-initialize the nic client and ae device */ @@ -1890,6 +1918,18 @@ static int hclgevf_reset_rebuild(struct hclgevf_dev *hdev) return ret; } + ret = hclgevf_notify_roce_client(hdev, HNAE3_INIT_CLIENT); + /* ignore RoCE notify error if it fails HCLGEVF_RESET_MAX_FAIL_CNT - 1 + * times + */ + if (ret && + hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT - 1) + return ret; + + ret = hclgevf_notify_roce_client(hdev, HNAE3_UP_CLIENT); + if (ret) + return ret; + hdev->last_reset_time = jiffies; hdev->rst_stats.rst_done_cnt++; hdev->rst_stats.rst_fail_cnt = 0; @@ -2186,6 +2226,9 @@ static void hclgevf_periodic_service_task(struct hclgevf_dev *hdev) unsigned long delta = round_jiffies_relative(HZ); struct hnae3_handle *handle = &hdev->nic; + if (test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) + return; + if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) { delta = jiffies - hdev->last_serv_processed; @@ -2284,7 +2327,7 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, * register, so we should just write 0 to the bit we are * handling, and keep other bits as cmdq_stat_reg. */ - if (hdev->pdev->revision >= 0x21) + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) *clearval = ~(1U << HCLGEVF_VECTOR0_RX_CMDQ_INT_B); else *clearval = cmdq_stat_reg & @@ -2427,7 +2470,7 @@ static void hclgevf_rss_init_cfg(struct hclgevf_dev *hdev) rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_TOEPLITZ; rss_cfg->rss_size = hdev->nic.kinfo.rss_size; tuple_sets = &rss_cfg->rss_tuple_sets; - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_SIMPLE; memcpy(rss_cfg->rss_hash_key, hclgevf_hash_key, HCLGEVF_RSS_KEY_SIZE); @@ -2452,7 +2495,7 @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; int ret; - if (hdev->pdev->revision >= 0x21) { + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo, rss_cfg->rss_hash_key); if (ret) @@ -2551,13 +2594,7 @@ static int hclgevf_set_alive(struct hnae3_handle *handle, bool alive) static int hclgevf_client_start(struct hnae3_handle *handle) { - int ret; - - ret = hclgevf_set_alive(handle, true); - if (ret) - return ret; - - return 0; + return hclgevf_set_alive(handle, true); } static void hclgevf_client_stop(struct hnae3_handle *handle) @@ -2760,6 +2797,7 @@ static int hclgevf_init_roce_client_instance(struct hnae3_ae_dev *ae_dev, if (ret) return ret; + set_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state); hnae3_set_client_init_flag(client, ae_dev, 1); return 0; @@ -2820,6 +2858,7 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client, /* un-init roce, if it exists */ if (hdev->roce_client) { + clear_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state); hdev->roce_client->ops->uninit_instance(&hdev->roce, 0); hdev->roce_client = NULL; hdev->roce.client = NULL; @@ -2942,6 +2981,76 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev) return 0; } +static void hclgevf_set_default_dev_specs(struct hclgevf_dev *hdev) +{ +#define HCLGEVF_MAX_NON_TSO_BD_NUM 8U + + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + + ae_dev->dev_specs.max_non_tso_bd_num = + HCLGEVF_MAX_NON_TSO_BD_NUM; + ae_dev->dev_specs.rss_ind_tbl_size = HCLGEVF_RSS_IND_TBL_SIZE; + ae_dev->dev_specs.rss_key_size = HCLGEVF_RSS_KEY_SIZE; +} + +static void hclgevf_parse_dev_specs(struct hclgevf_dev *hdev, + struct hclgevf_desc *desc) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + struct hclgevf_dev_specs_0_cmd *req0; + + req0 = (struct hclgevf_dev_specs_0_cmd *)desc[0].data; + + ae_dev->dev_specs.max_non_tso_bd_num = req0->max_non_tso_bd_num; + ae_dev->dev_specs.rss_ind_tbl_size = + le16_to_cpu(req0->rss_ind_tbl_size); + ae_dev->dev_specs.rss_key_size = le16_to_cpu(req0->rss_key_size); +} + +static void hclgevf_check_dev_specs(struct hclgevf_dev *hdev) +{ + struct hnae3_dev_specs *dev_specs = &hdev->ae_dev->dev_specs; + + if (!dev_specs->max_non_tso_bd_num) + dev_specs->max_non_tso_bd_num = HCLGEVF_MAX_NON_TSO_BD_NUM; + if (!dev_specs->rss_ind_tbl_size) + dev_specs->rss_ind_tbl_size = HCLGEVF_RSS_IND_TBL_SIZE; + if (!dev_specs->rss_key_size) + dev_specs->rss_key_size = HCLGEVF_RSS_KEY_SIZE; +} + +static int hclgevf_query_dev_specs(struct hclgevf_dev *hdev) +{ + struct hclgevf_desc desc[HCLGEVF_QUERY_DEV_SPECS_BD_NUM]; + int ret; + int i; + + /* set default specifications as devices lower than version V3 do not + * support querying specifications from firmware. + */ + if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) { + hclgevf_set_default_dev_specs(hdev); + return 0; + } + + for (i = 0; i < HCLGEVF_QUERY_DEV_SPECS_BD_NUM - 1; i++) { + hclgevf_cmd_setup_basic_desc(&desc[i], + HCLGEVF_OPC_QUERY_DEV_SPECS, true); + desc[i].flag |= cpu_to_le16(HCLGEVF_CMD_FLAG_NEXT); + } + hclgevf_cmd_setup_basic_desc(&desc[i], HCLGEVF_OPC_QUERY_DEV_SPECS, + true); + + ret = hclgevf_cmd_send(&hdev->hw, desc, HCLGEVF_QUERY_DEV_SPECS_BD_NUM); + if (ret) + return ret; + + hclgevf_parse_dev_specs(hdev, desc); + hclgevf_check_dev_specs(hdev); + + return 0; +} + static int hclgevf_pci_reset(struct hclgevf_dev *hdev) { struct pci_dev *pdev = hdev->pdev; @@ -3050,6 +3159,13 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) if (ret) goto err_cmd_init; + ret = hclgevf_query_dev_specs(hdev); + if (ret) { + dev_err(&pdev->dev, + "failed to query dev specifications, ret = %d\n", ret); + goto err_cmd_init; + } + ret = hclgevf_init_msi(hdev); if (ret) { dev_err(&pdev->dev, "failed(%d) to init MSI/MSI-X\n", ret); @@ -3345,6 +3461,13 @@ static bool hclgevf_get_hw_reset_stat(struct hnae3_handle *handle) return !!hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); } +static bool hclgevf_get_cmdq_stat(struct hnae3_handle *handle) +{ + struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + + return test_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); +} + static bool hclgevf_ae_dev_resetting(struct hnae3_handle *handle) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); @@ -3530,6 +3653,7 @@ static const struct hnae3_ae_ops hclgevf_ops = { .get_link_mode = hclgevf_get_link_mode, .set_promisc_mode = hclgevf_set_promisc_mode, .request_update_promisc_mode = hclgevf_request_update_promisc_mode, + .get_cmdq_stat = hclgevf_get_cmdq_stat, }; static struct hnae3_ae_algo ae_algovf = { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index c1fac8920ae3..c5bcc3894fd5 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -139,6 +139,7 @@ enum hclgevf_states { HCLGEVF_STATE_IRQ_INITED, HCLGEVF_STATE_REMOVING, HCLGEVF_STATE_NIC_REGISTERED, + HCLGEVF_STATE_ROCE_REGISTERED, /* task states */ HCLGEVF_STATE_RST_SERVICE_SCHED, HCLGEVF_STATE_RST_HANDLING, |