From 5b8a867a26e7a655c66fec745d935f470c3b000b Mon Sep 17 00:00:00 2001 From: tianx Date: Thu, 23 May 2024 18:15:17 +0800 Subject: [PATCH] drivers: support Yunsilicon's MS and MV series NICs yunsilicon inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I9NGGU CVE: NA ------------------------------------------ Update XSC driver to support yunsilicon's MS and MV series NICs Reviewed-by: Weihonggang Reviewed-by: Wanrenyong Reviewed-by: Jacky Signed-off-by: Tianxin --- drivers/infiniband/hw/xsc/cq.c | 51 +- drivers/infiniband/hw/xsc/ib_peer_mem.h | 2 - drivers/infiniband/hw/xsc/ib_umem_ex.c | 6 + drivers/infiniband/hw/xsc/ib_umem_ex.h | 4 + drivers/infiniband/hw/xsc/main.c | 94 ++- drivers/infiniband/hw/xsc/mem.c | 19 +- drivers/infiniband/hw/xsc/mr.c | 10 + drivers/infiniband/hw/xsc/peer_mem.c | 207 ------ drivers/infiniband/hw/xsc/private_dev.c | 54 +- drivers/infiniband/hw/xsc/qp.c | 53 +- drivers/infiniband/hw/xsc/rtt.c | 4 +- drivers/infiniband/hw/xsc/xsc_ib.h | 1 + drivers/infiniband/hw/xsc/xsc_ib_compat.h | 3 + drivers/infiniband/hw/xsc/xsc_rdma_ctrl.c | 9 +- .../net/ethernet/yunsilicon/xsc/common/port.h | 4 +- .../net/ethernet/yunsilicon/xsc/common/qp.h | 13 +- .../net/ethernet/yunsilicon/xsc/common/qpts.h | 3 +- .../ethernet/yunsilicon/xsc/common/version.h | 6 +- .../ethernet/yunsilicon/xsc/common/vport.h | 1 + .../yunsilicon/xsc/common/xsc_auto_hw.h | 62 +- .../ethernet/yunsilicon/xsc/common/xsc_cmd.h | 195 ++++-- .../ethernet/yunsilicon/xsc/common/xsc_core.h | 645 ++---------------- .../ethernet/yunsilicon/xsc/common/xsc_hsi.h | 33 +- .../yunsilicon/xsc/common/xsc_ioctl.h | 20 +- .../ethernet/yunsilicon/xsc/common/xsc_lag.h | 28 +- .../xsc/{pci/fw/xsc_tbm.h => common/xsc_pp.h} | 40 +- .../net/ethernet/yunsilicon/xsc/net/main.c | 308 +++++---- .../ethernet/yunsilicon/xsc/net/xsc_dcbnl.c | 3 +- .../net/ethernet/yunsilicon/xsc/net/xsc_eth.h | 5 +- .../yunsilicon/xsc/net/xsc_eth_ctrl.c | 5 +- .../yunsilicon/xsc/net/xsc_eth_ethtool.c | 277 +++++++- .../ethernet/yunsilicon/xsc/net/xsc_eth_rx.c | 34 +- .../yunsilicon/xsc/net/xsc_eth_stats.c | 74 +- .../yunsilicon/xsc/net/xsc_eth_sysfs.c | 55 +- .../ethernet/yunsilicon/xsc/net/xsc_eth_tx.c | 4 +- .../yunsilicon/xsc/net/xsc_eth_txrx.h | 10 +- .../ethernet/yunsilicon/xsc/net/xsc_queue.h | 8 +- .../net/ethernet/yunsilicon/xsc/pci/cmd2.c | 27 +- .../net/ethernet/yunsilicon/xsc/pci/debugfs.c | 161 +---- .../net/ethernet/yunsilicon/xsc/pci/devlink.c | 9 +- .../net/ethernet/yunsilicon/xsc/pci/devlink.h | 2 +- .../net/ethernet/yunsilicon/xsc/pci/eswitch.c | 19 +- .../net/ethernet/yunsilicon/xsc/pci/eswitch.h | 27 +- drivers/net/ethernet/yunsilicon/xsc/pci/fw.c | 103 ++- .../net/ethernet/yunsilicon/xsc/pci/main.c | 201 ++---- .../net/ethernet/yunsilicon/xsc/pci/pci_irq.c | 56 +- .../net/ethernet/yunsilicon/xsc/pci/port.c | 46 ++ drivers/net/ethernet/yunsilicon/xsc/pci/qp.c | 101 +-- .../net/ethernet/yunsilicon/xsc/pci/res_obj.c | 11 +- .../net/ethernet/yunsilicon/xsc/pci/sriov.c | 25 +- .../ethernet/yunsilicon/xsc/pci/sriov_sysfs.c | 3 +- .../net/ethernet/yunsilicon/xsc/pci/vport.c | 2 +- .../net/ethernet/yunsilicon/xsc/pci/xsc_lag.c | 99 ++- .../yunsilicon/xsc/pci/xsc_pci_ctrl.c | 98 ++- .../yunsilicon/xsc/pci/xsc_pci_ctrl.h | 1 + .../yunsilicon/xsc/pci/xsc_port_ctrl.c | 20 +- 56 files changed, 1449 insertions(+), 1912 deletions(-) rename drivers/net/ethernet/yunsilicon/xsc/{pci/fw/xsc_tbm.h => common/xsc_pp.h} (67%) diff --git a/drivers/infiniband/hw/xsc/cq.c b/drivers/infiniband/hw/xsc/cq.c index 2c3e1e9e742b..65b91c784736 100644 --- a/drivers/infiniband/hw/xsc/cq.c +++ b/drivers/infiniband/hw/xsc/cq.c @@ -120,12 +120,12 @@ static void *get_cqe(struct xsc_ib_cq *cq, int n) static void *get_sw_cqe(struct xsc_ib_cq *cq, int n) { - struct xsc_cqe64 *cqe64; + struct xsc_cqe *cqe; - cqe64 = (struct xsc_cqe64 *)get_cqe(cq, n & cq->ibcq.cqe); + cqe = (struct xsc_cqe *)get_cqe(cq, n & (cq->ibcq.cqe - 1)); - return ((cqe64->owner & XSC_CQE_OWNER_MASK) ^ - !!(n & (cq->ibcq.cqe + 1))) ? NULL : cqe64; + return ((cqe->owner & XSC_CQE_OWNER_MASK) ^ + !!(n & cq->ibcq.cqe)) ? NULL : cqe; } static inline void handle_good_req(struct ib_wc *wc, @@ -198,6 +198,7 @@ static void xsc_handle_rdma_mad_resp_recv(struct xsc_ib_cq *cq, void *recv; struct xsc_wqe_data_seg *data_seg; struct iphdr *ip4h = NULL; + struct ipv6hdr *ip6h; struct udphdr *udph; struct ib_unpacked_eth *eth; struct ib_unpacked_vlan *vlan; @@ -208,6 +209,8 @@ static void xsc_handle_rdma_mad_resp_recv(struct xsc_ib_cq *cq, unsigned int pading_sz = 0; struct xsc_ib_wq *wq; int idx; + u16 eth_type; + void *l3_start; wq = &(*cur_qp)->rq; idx = wq->tail & (wq->wqe_cnt - 1); @@ -221,23 +224,36 @@ static void xsc_handle_rdma_mad_resp_recv(struct xsc_ib_cq *cq, grh = (struct ib_grh *)recv; if (eth->type == htons(ETH_P_8021Q)) { vlan = (struct ib_unpacked_vlan *)(eth + 1); - ip4h = (struct iphdr *)(vlan + 1); + eth_type = ntohs(vlan->type); + l3_start = vlan + 1; wc->vlan_id = ntohs(vlan->tag) & 0x0fff; wc->sl = (ntohs(vlan->tag) >> 13) & 0x7; wc->wc_flags |= IB_WC_WITH_VLAN; } else { - ip4h = (struct iphdr *)(eth + 1); + eth_type = ntohs(eth->type); + l3_start = eth + 1; + } + + if (eth_type == ETH_P_IP) { + ip4h = (struct iphdr *)l3_start; + udph = (struct udphdr *)(ip4h + 1); + } else { + ip6h = (struct ipv6hdr *)l3_start; + udph = (struct udphdr *)(ip6h + 1); } - udph = (struct udphdr *)(ip4h + 1); bth = (struct rxe_bth *)(udph + 1); deth = (struct rxe_deth *)(bth + 1); mad = (struct ib_mad *)(deth + 1); - memcpy(grh + 1, mad, sizeof(*mad)); - pading_sz = sizeof(*grh) - sizeof(*ip4h); - memmove((u8 *)(grh + 1) - sizeof(*ip4h), ip4h, sizeof(*ip4h)); - memset(grh, 0, pading_sz); + if (eth_type == ETH_P_IP) { + pading_sz = sizeof(*grh) - sizeof(*ip4h); + memmove((u8 *)(grh + 1) - sizeof(*ip4h), ip4h, sizeof(*ip4h)); + memset(grh, 0, pading_sz); + } else { + memmove(grh, ip6h, sizeof(*ip6h)); + } + memmove(grh + 1, mad, sizeof(*mad)); wc->wc_flags |= IB_WC_GRH; @@ -543,7 +559,7 @@ xsc_ib_create_cq_def() int err; unsigned int eqn; - entries = roundup_pow_of_two(entries + 1); + entries = roundup_pow_of_two(entries); xsc_ib_dbg(dev, "entries:%d, vector:%d, max_cqes:%d\n", entries, vector, dev->xdev->caps.max_cqes); @@ -551,7 +567,7 @@ xsc_ib_create_cq_def() if (entries > dev->xdev->caps.max_cqes) entries = dev->xdev->caps.max_cqes; cq = to_xcq(ibcq); - cq->ibcq.cqe = entries - 1; + cq->ibcq.cqe = entries; mutex_init(&cq->resize_mutex); spin_lock_init(&cq->lock); cq->resize_buf = NULL; @@ -628,7 +644,7 @@ xsc_ib_destroy_cq_def() return 0; } -static int is_equal_rsn(struct xsc_cqe64 *cqe, u32 rsn) +static int is_equal_rsn(struct xsc_cqe *cqe, u32 rsn) { u32 qpn = le32_to_cpu(cqe->qp_id); return rsn == qpn; @@ -636,7 +652,7 @@ static int is_equal_rsn(struct xsc_cqe64 *cqe, u32 rsn) void __xsc_ib_cq_clean(struct xsc_ib_cq *cq, u32 rsn) { - struct xsc_cqe64 *cqe, *dest; + struct xsc_cqe *cqe, *dest; u32 prod_index; int nfreed = 0; u8 owner_bit; @@ -658,11 +674,12 @@ void __xsc_ib_cq_clean(struct xsc_ib_cq *cq, u32 rsn) * that match our QP by copying older entries on top of them. */ while ((int)(--prod_index) - (int)cq->xcq.cons_index >= 0) { - cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); + cqe = (struct xsc_cqe *)get_cqe(cq, prod_index & (cq->ibcq.cqe - 1)); if (is_equal_rsn(cqe, rsn)) { ++nfreed; } else if (nfreed) { - dest = get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe); + dest = (struct xsc_cqe *)get_cqe(cq, (prod_index + nfreed) & + (cq->ibcq.cqe - 1)); owner_bit = dest->owner & XSC_CQE_OWNER_MASK; memcpy(dest, cqe, cq->xcq.cqe_sz); dest->owner = owner_bit | diff --git a/drivers/infiniband/hw/xsc/ib_peer_mem.h b/drivers/infiniband/hw/xsc/ib_peer_mem.h index ad7997fcece3..b955ac53bfde 100644 --- a/drivers/infiniband/hw/xsc/ib_peer_mem.h +++ b/drivers/infiniband/hw/xsc/ib_peer_mem.h @@ -33,8 +33,6 @@ struct ib_peer_memory_client { struct mutex lock; struct list_head core_ticket_list; u64 last_ticket; - struct kobject *kobj; - struct attribute_group peer_mem_attr_group; struct ib_peer_memory_statistics stats; }; diff --git a/drivers/infiniband/hw/xsc/ib_umem_ex.c b/drivers/infiniband/hw/xsc/ib_umem_ex.c index 71c823bdc0f6..58ded090b523 100644 --- a/drivers/infiniband/hw/xsc/ib_umem_ex.c +++ b/drivers/infiniband/hw/xsc/ib_umem_ex.c @@ -6,7 +6,9 @@ #include +#ifndef MLX_PEER_SUPPORT #include "ib_peer_mem.h" +#endif #include #include "ib_umem_ex.h" @@ -88,12 +90,16 @@ struct ib_umem_ex *ib_umem_ex(struct ib_umem *umem) if (!umem) return ERR_PTR(-EINVAL); +#ifndef MLX_PEER_SUPPORT ret_umem = kzalloc(sizeof(*ret_umem), GFP_KERNEL); if (!ret_umem) return ERR_PTR(-ENOMEM); ret_umem->umem = *umem; kfree(umem); +#else + ret_umem = (struct ib_umem_ex *)umem; +#endif return ret_umem; } diff --git a/drivers/infiniband/hw/xsc/ib_umem_ex.h b/drivers/infiniband/hw/xsc/ib_umem_ex.h index b73eecf3cd90..cedf13f02108 100644 --- a/drivers/infiniband/hw/xsc/ib_umem_ex.h +++ b/drivers/infiniband/hw/xsc/ib_umem_ex.h @@ -15,14 +15,17 @@ struct invalidation_ctx; // ib umem ex ib_umem add peer memory support struct ib_umem_ex { struct ib_umem umem; +#ifndef MLX_PEER_SUPPORT struct ib_peer_memory_client *ib_peer_mem; struct invalidation_ctx *invalidation_ctx; void *peer_mem_client_context; +#endif }; // expand ib_umem to ib_umem_ex by reallocate struct ib_umem_ex *ib_umem_ex(struct ib_umem *umem); +#ifndef MLX_PEER_SUPPORT typedef void (*umem_invalidate_func_t)(void *invalidation_cookie, struct ib_umem_ex *umem_ex, unsigned long addr, size_t size); @@ -36,6 +39,7 @@ struct invalidation_ctx { int peer_invalidated; struct completion comp; }; +#endif struct ib_umem_ex *ib_client_umem_get(struct ib_ucontext *context, unsigned long addr, size_t size, int access, diff --git a/drivers/infiniband/hw/xsc/main.c b/drivers/infiniband/hw/xsc/main.c index 09d6b5e25baf..a32115f485dc 100644 --- a/drivers/infiniband/hw/xsc/main.c +++ b/drivers/infiniband/hw/xsc/main.c @@ -12,10 +12,13 @@ #include #include #include +#include +#include #include "common/xsc_core.h" #include "common/xsc_hsi.h" #include "common/xsc_cmd.h" #include "common/driver.h" +#include "common/xsc_lag.h" #include #include @@ -98,6 +101,7 @@ static int xsc_ib_query_device(struct ib_device *ibdev, IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_RC_RNR_NAK_GEN; props->kernel_cap_flags = IBK_BLOCK_MULTICAST_LOOPBACK; + props->kernel_cap_flags |= IBK_LOCAL_DMA_LKEY; flags = dev->xdev->caps.flags; if (flags & XSC_DEV_CAP_FLAG_BAD_PKEY_CNTR) props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR; @@ -105,7 +109,6 @@ static int xsc_ib_query_device(struct ib_device *ibdev, props->device_cap_flags |= IB_DEVICE_BAD_QKEY_CNTR; if (flags & XSC_DEV_CAP_FLAG_APM) props->device_cap_flags |= IB_DEVICE_AUTO_PATH_MIG; - props->kernel_cap_flags |= IBK_LOCAL_DMA_LKEY; if (flags & XSC_DEV_CAP_FLAG_XRC) props->device_cap_flags |= IB_DEVICE_XRC; props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS; @@ -113,7 +116,7 @@ static int xsc_ib_query_device(struct ib_device *ibdev, props->page_size_cap = dev->xdev->caps.min_page_sz; props->max_mr_size = (1 << dev->xdev->caps.log_max_mtt) * PAGE_SIZE; props->max_qp = 1 << dev->xdev->caps.log_max_qp; - props->max_qp_wr = dev->xdev->caps.max_wqes; + props->max_qp_wr = (32 * 1024); /* hack for GPFS */ max_rq_sg = dev->xdev->caps.max_rq_desc_sz / sizeof(struct xsc_wqe_data_seg); max_sq_sg = (dev->xdev->caps.max_sq_desc_sz - sizeof(struct xsc_wqe_ctrl_seg_2)) / sizeof(struct xsc_wqe_data_seg_2); @@ -207,6 +210,57 @@ static int xsc_ib_query_device(struct ib_device *ibdev, return 0; } +void xsc_calc_link_info(struct xsc_core_device *xdev, + struct ib_port_attr *props) +{ + switch (xsc_get_link_speed(xdev)) { + case MODULE_SPEED_10G: + props->active_speed = XSC_RDMA_LINK_SPEED_10GB; + props->active_width = 1; + break; + case MODULE_SPEED_25G: + props->active_speed = XSC_RDMA_LINK_SPEED_25GB; + props->active_width = 1; + break; + case MODULE_SPEED_40G_R4: + props->active_speed = XSC_RDMA_LINK_SPEED_10GB; + props->active_width = 2; + break; + case MODULE_SPEED_50G_R: + props->active_speed = XSC_RDMA_LINK_SPEED_50GB; + props->active_width = 1; + break; + case MODULE_SPEED_50G_R2: + props->active_speed = XSC_RDMA_LINK_SPEED_50GB; + props->active_width = 1; + break; + case MODULE_SPEED_100G_R2: + props->active_speed = XSC_RDMA_LINK_SPEED_25GB; + props->active_width = 2; + break; + case MODULE_SPEED_100G_R4: + props->active_speed = XSC_RDMA_LINK_SPEED_25GB; + props->active_width = 2; + break; + case MODULE_SPEED_200G_R4: + props->active_speed = XSC_RDMA_LINK_SPEED_50GB; + props->active_width = 2; + break; + case MODULE_SPEED_200G_R8: + props->active_speed = XSC_RDMA_LINK_SPEED_25GB; + props->active_width = 4; + break; + case MODULE_SPEED_400G_R8: + props->active_speed = XSC_RDMA_LINK_SPEED_50GB; + props->active_width = 4; + break; + default: + props->active_speed = XSC_RDMA_LINK_SPEED_25GB; + props->active_width = 1; + break; + } +} + static enum rdma_link_layer xsc_ib_port_link_layer(struct ib_device *ibdev, u32 port) { return IB_LINK_LAYER_ETHERNET; @@ -246,11 +300,7 @@ int xsc_ib_query_port(struct ib_device *ibdev, u32 port, props->active_width = 1; props->active_speed = XSC_RDMA_LINK_SPEED_25GB; } else { - if (xsc_get_link_speed(xdev) == XSC_CMD_RESP_LINKSPEED_MODE_100G) - props->active_width = 2; - else - props->active_width = 1; - props->active_speed = XSC_RDMA_LINK_SPEED_25GB; + xsc_calc_link_info(xdev, props); } props->phys_state = netif_carrier_ok(ndev) ? XSC_RDMA_PHY_STATE_LINK_UP : @@ -455,6 +505,7 @@ xsc_ib_alloc_ucontext_def() xsc_ib_dealloc_ucontext_def() { + return; } static int xsc_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma) @@ -559,14 +610,27 @@ static void _xsc_get_netdev(struct xsc_ib_dev *dev) static struct net_device *xsc_get_netdev(struct ib_device *ibdev, u32 port_num) { - struct xsc_ib_dev *dev = to_mdev(ibdev); - struct net_device *netdev = dev->netdev; + struct xsc_ib_dev *xsc_ib_dev = to_mdev(ibdev); + struct net_device *dev = xsc_ib_dev->netdev; rcu_read_lock(); - if (netdev) - dev_hold(netdev); + if (dev) { + if (xsc_ib_dev->xdev->priv.lag && __xsc_lag_is_active(xsc_ib_dev->xdev->priv.lag)) { + struct net_device *upper = NULL; + + upper = netdev_master_upper_dev_get_rcu(dev); + if (upper) { + struct net_device *active; + + active = bond_option_active_slave_get_rcu(netdev_priv(upper)); + if (active) + dev = active; + } + } + dev_hold(dev); + } rcu_read_unlock(); - return netdev; + return dev; } void xsc_get_guid(const u8 *dev_addr, u8 *guid) @@ -741,7 +805,6 @@ static int populate_specs_root(struct xsc_ib_dev *dev) const struct uverbs_object_tree_def **trees = (const struct uverbs_object_tree_def **)dev->driver_trees; size_t num_trees = 0; - trees[num_trees++] = xsc_ib_get_devx_tree(); WARN_ON(num_trees >= ARRAY_SIZE(dev->driver_trees)); @@ -809,7 +872,6 @@ static void xsc_ib_dev_setting(struct xsc_ib_dev *dev) dev->ib_dev.ops.dereg_mr = xsc_ib_dereg_mr; dev->ib_dev.ops.alloc_mr = xsc_ib_alloc_mr; dev->ib_dev.ops.map_mr_sg = xsc_ib_map_mr_sg; - dev->ib_dev.ops.get_port_immutable = xsc_port_immutable; dev->ib_dev.ops INIT_RDMA_OBJ_SIZE(ib_ah, xsc_ib_ah, ibah); @@ -826,7 +888,6 @@ static int init_one(struct xsc_core_device *xdev, int err; pr_info_once("%s", xsc_version); - dev = (struct xsc_ib_dev *)ib_alloc_device(xsc_ib_dev, ib_dev); if (!dev) return -ENOMEM; @@ -899,6 +960,7 @@ static int init_one(struct xsc_core_device *xdev, if (ib_register_device(&dev->ib_dev, dev->ib_dev.name, dev->xdev->device)) goto err_rsrc; + rdma_roce_rescan_device(&dev->ib_dev); dev->ib_active = true; *m_ibdev = dev; @@ -949,7 +1011,6 @@ static void *xsc_add(struct xsc_core_device *xpdev) return NULL; } - xpdev->rdma_ready = 1; return m_ibdev; } @@ -957,7 +1018,6 @@ static void xsc_remove(struct xsc_core_device *xpdev, void *context) { pr_err("remove rdma driver\n"); remove_one(xpdev, context); - xpdev->rdma_ready = 0; } static struct xsc_interface xsc_interface = { diff --git a/drivers/infiniband/hw/xsc/mem.c b/drivers/infiniband/hw/xsc/mem.c index 617bc7b3844b..cd069a704d4c 100644 --- a/drivers/infiniband/hw/xsc/mem.c +++ b/drivers/infiniband/hw/xsc/mem.c @@ -75,7 +75,12 @@ int xsc_find_best_pgsz(struct ib_umem *umem, int pa_index; u64 chunk_pa; int chunk_npages; +#if defined(HAVE_IB_MEM_PAGE_SHIFT) + // In some ubuntu kernels, umem page shift maybe 0 for host memory + unsigned long page_shift = umem->page_shift != 0 ? umem->page_shift : PAGE_SHIFT; +#else unsigned long page_shift = PAGE_SHIFT; +#endif pgsz_bitmap &= GENMASK(BITS_PER_LONG - 1, 0); @@ -90,7 +95,7 @@ int xsc_find_best_pgsz(struct ib_umem *umem, list_add_tail(&chunk->list, &chunk_list); chunk_cnt = 1; - for_each_sg(umem->sgt_append.sgt.sgl, sg, umem->sgt_append.sgt.nents, i) { + for_each_sgtable_dma_sg(&umem->sgt_append.sgt, sg, i) { pa = sg_dma_address(sg); if (i == 0) { chunk->va = va; @@ -102,7 +107,7 @@ int xsc_find_best_pgsz(struct ib_umem *umem, if (pa == chunk->pa + chunk->length) { chunk->length += sg_dma_len(sg); - va += chunk->length; + va += sg_dma_len(sg); } else { chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); if (!chunk) { @@ -135,7 +140,7 @@ int xsc_find_best_pgsz(struct ib_umem *umem, if (chunk_cnt == 1) { list_for_each_entry(chunk, &chunk_list, list) { - mask = GENMASK(*shift - 1, min_t(int, page_shift, *shift - 1)); + mask = GENMASK(*shift - 1, min_t(int, page_shift, *shift)); *npages += DIV_ROUND_UP(chunk->length + (virt & mask), pgsz); *pas = vmalloc(*npages * sizeof(u64)); if (!*pas) { @@ -165,7 +170,7 @@ int xsc_find_best_pgsz(struct ib_umem *umem, for (i = 0; i < chunk_npages; i++) { if (pa_index == 0) { mask = GENMASK(*shift - 1, - min_t(int, page_shift, *shift - 1)); + min_t(int, page_shift, *shift)); chunk_pa -= (virt & mask); } (*pas)[pa_index] = chunk_pa + i * pgsz; @@ -202,6 +207,7 @@ void __xsc_ib_cont_pages(struct ib_umem *umem, u64 addr, int i = 0; struct scatterlist *sg; int entry; + // TODO: need peer mem support unsigned long page_shift = PAGE_SHIFT; addr = addr >> page_shift; @@ -209,7 +215,7 @@ void __xsc_ib_cont_pages(struct ib_umem *umem, u64 addr, m = find_first_bit(&tmp, BITS_PER_LONG); if (max_page_shift) m = min_t(unsigned long, max_page_shift - page_shift, m); - for_each_sg(umem->sgt_append.sgt.sgl, sg, umem->sgt_append.sgt.nents, entry) { + for_each_sgtable_dma_sg(&umem->sgt_append.sgt, sg, entry) { len = sg_dma_len(sg) >> page_shift; pfn = sg_dma_address(sg) >> page_shift; if (base + p != pfn) { @@ -251,6 +257,7 @@ void xsc_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift, int *ncont, int *order) { + // no limit for page_shift __xsc_ib_cont_pages(umem, addr, 0, count, shift, ncont, order); } @@ -269,7 +276,7 @@ void __xsc_ib_populate_pas(struct xsc_ib_dev *dev, struct ib_umem *umem, struct scatterlist *sg; int entry; - for_each_sg(umem->sgt_append.sgt.sgl, sg, umem->sgt_append.sgt.nents, entry) { + for_each_sgtable_dma_sg(&umem->sgt_append.sgt, sg, entry) { len = sg_dma_len(sg) >> umem_page_shift; if (need_to_devide) len = sg_dma_len(sg) >> PAGE_SHIFT_4K; diff --git a/drivers/infiniband/hw/xsc/mr.c b/drivers/infiniband/hw/xsc/mr.c index 0dfec80461c5..dac492579e25 100644 --- a/drivers/infiniband/hw/xsc/mr.c +++ b/drivers/infiniband/hw/xsc/mr.c @@ -14,9 +14,11 @@ #include "ib_umem_ex.h" #include "xsc_ib.h" +#ifndef MLX_PEER_SUPPORT static void xsc_invalidate_umem(void *invalidation_cookie, struct ib_umem_ex *umem, unsigned long addr, size_t size); +#endif enum { DEF_CACHE_SIZE = 10, @@ -167,6 +169,7 @@ struct ib_mr *xsc_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, umem = ib_umem_get(&dev->ib_dev, start, length, access_flags); if (IS_ERR(umem)) { // check client peer memory +#ifndef MLX_PEER_SUPPORT u8 peer_exists = 0; umem_ex = ib_client_umem_get(pd->uobject->context, @@ -188,6 +191,11 @@ struct ib_mr *xsc_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, if (err) goto error; using_peer_mem = 1; +#else + xsc_ib_warn(dev, "umem get failed\n"); + return (void *)umem; +#endif + } else { umem_ex = ib_umem_ex(umem); if (IS_ERR(umem_ex)) { @@ -295,6 +303,7 @@ xsc_ib_dereg_mr_def() return 0; } +#ifndef MLX_PEER_SUPPORT static void xsc_invalidate_umem(void *invalidation_cookie, struct ib_umem_ex *umem, unsigned long addr, @@ -321,6 +330,7 @@ static void xsc_invalidate_umem(void *invalidation_cookie, xsc_core_dereg_mr(dev->xdev, &mr->mmr); complete(&mr->invalidation_comp); } +#endif xsc_ib_alloc_mr_def() { diff --git a/drivers/infiniband/hw/xsc/peer_mem.c b/drivers/infiniband/hw/xsc/peer_mem.c index 596a0ca7ca40..29c1c4a1c76a 100644 --- a/drivers/infiniband/hw/xsc/peer_mem.c +++ b/drivers/infiniband/hw/xsc/peer_mem.c @@ -10,207 +10,8 @@ static DEFINE_MUTEX(peer_memory_mutex); static LIST_HEAD(peer_memory_list); -static struct kobject *peers_kobj; static void complete_peer(struct kref *kref); -static struct ib_peer_memory_client *get_peer_by_kobj(void *kobj); -static ssize_t version_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct ib_peer_memory_client *ib_peer_client = get_peer_by_kobj(kobj); - - if (ib_peer_client) { - sprintf(buf, "%s\n", ib_peer_client->peer_mem->version); - kref_put(&ib_peer_client->ref, complete_peer); - return strlen(buf); - } - /* not found - nothing is return */ - return 0; -} - -static ssize_t num_alloc_mrs_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct ib_peer_memory_client *ib_peer_client = get_peer_by_kobj(kobj); - - if (ib_peer_client) { - sprintf(buf, "%llu\n", (u64)atomic64_read(&ib_peer_client->stats.num_alloc_mrs)); - kref_put(&ib_peer_client->ref, complete_peer); - return strlen(buf); - } - /* not found - nothing is return */ - return 0; -} - -static ssize_t num_dealloc_mrs_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct ib_peer_memory_client *ib_peer_client = get_peer_by_kobj(kobj); - - if (ib_peer_client) { - sprintf(buf, "%llu\n", (u64)atomic64_read(&ib_peer_client->stats.num_dealloc_mrs)); - kref_put(&ib_peer_client->ref, complete_peer); - return strlen(buf); - } - /* not found - nothing is return */ - return 0; -} - -static ssize_t num_reg_pages_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct ib_peer_memory_client *ib_peer_client = get_peer_by_kobj(kobj); - - if (ib_peer_client) { - sprintf(buf, "%llu\n", (u64)atomic64_read(&ib_peer_client->stats.num_reg_pages)); - kref_put(&ib_peer_client->ref, complete_peer); - return strlen(buf); - } - /* not found - nothing is return */ - return 0; -} - -static ssize_t num_dereg_pages_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct ib_peer_memory_client *ib_peer_client = get_peer_by_kobj(kobj); - - if (ib_peer_client) { - sprintf(buf, "%llu\n", (u64)atomic64_read(&ib_peer_client->stats.num_dereg_pages)); - kref_put(&ib_peer_client->ref, complete_peer); - return strlen(buf); - } - /* not found - nothing is return */ - return 0; -} - -static ssize_t num_reg_bytes_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct ib_peer_memory_client *ib_peer_client = get_peer_by_kobj(kobj); - - if (ib_peer_client) { - sprintf(buf, "%llu\n", (u64)atomic64_read(&ib_peer_client->stats.num_reg_bytes)); - kref_put(&ib_peer_client->ref, complete_peer); - return strlen(buf); - } - /* not found - nothing is return */ - return 0; -} - -static ssize_t num_dereg_bytes_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct ib_peer_memory_client *ib_peer_client = get_peer_by_kobj(kobj); - - if (ib_peer_client) { - sprintf(buf, "%llu\n", (u64)atomic64_read(&ib_peer_client->stats.num_dereg_bytes)); - kref_put(&ib_peer_client->ref, complete_peer); - return strlen(buf); - } - /* not found - nothing is return */ - return 0; -} - -static ssize_t num_free_callbacks_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct ib_peer_memory_client *ib_peer_client = get_peer_by_kobj(kobj); - - if (ib_peer_client) { - sprintf(buf, "%lu\n", ib_peer_client->stats.num_free_callbacks); - kref_put(&ib_peer_client->ref, complete_peer); - return strlen(buf); - } - /* not found - nothing is return */ - return 0; -} - -static struct kobj_attribute version_attr = __ATTR_RO(version); -static struct kobj_attribute num_alloc_mrs = __ATTR_RO(num_alloc_mrs); -static struct kobj_attribute num_dealloc_mrs = __ATTR_RO(num_dealloc_mrs); -static struct kobj_attribute num_reg_pages = __ATTR_RO(num_reg_pages); -static struct kobj_attribute num_dereg_pages = __ATTR_RO(num_dereg_pages); -static struct kobj_attribute num_reg_bytes = __ATTR_RO(num_reg_bytes); -static struct kobj_attribute num_dereg_bytes = __ATTR_RO(num_dereg_bytes); -static struct kobj_attribute num_free_callbacks = __ATTR_RO(num_free_callbacks); - -static struct attribute *peer_mem_attrs[] = { - &version_attr.attr, - &num_alloc_mrs.attr, - &num_dealloc_mrs.attr, - &num_reg_pages.attr, - &num_dereg_pages.attr, - &num_reg_bytes.attr, - &num_dereg_bytes.attr, - &num_free_callbacks.attr, - NULL, -}; - -static void destroy_peer_sysfs(struct ib_peer_memory_client *ib_peer_client) -{ - kobject_put(ib_peer_client->kobj); - if (list_empty(&peer_memory_list)) - kobject_put(peers_kobj); -} - -static int create_peer_sysfs(struct ib_peer_memory_client *ib_peer_client) -{ - int ret; - - if (list_empty(&peer_memory_list)) { - /* creating under /sys/kernel/mm */ - peers_kobj = kobject_create_and_add("memory_peers", mm_kobj); - if (!peers_kobj) - return -ENOMEM; - } - - ib_peer_client->peer_mem_attr_group.attrs = peer_mem_attrs; - /* Dir alreday was created explicitly to get its kernel object for further usage */ - ib_peer_client->peer_mem_attr_group.name = NULL; - ib_peer_client->kobj = kobject_create_and_add(ib_peer_client->peer_mem->name, - peers_kobj); - - if (!ib_peer_client->kobj) { - ret = -EINVAL; - goto free; - } - - /* Create the files associated with this kobject */ - ret = sysfs_create_group(ib_peer_client->kobj, - &ib_peer_client->peer_mem_attr_group); - if (ret) - goto peer_free; - - return 0; - -peer_free: - kobject_put(ib_peer_client->kobj); - -free: - if (list_empty(&peer_memory_list)) - kobject_put(peers_kobj); - - return ret; -} - -static struct ib_peer_memory_client *get_peer_by_kobj(void *kobj) -{ - struct ib_peer_memory_client *ib_peer_client; - - mutex_lock(&peer_memory_mutex); - list_for_each_entry(ib_peer_client, &peer_memory_list, core_peer_list) { - if (ib_peer_client->kobj == kobj) { - kref_get(&ib_peer_client->ref); - goto found; - } - } - - ib_peer_client = NULL; -found: - mutex_unlock(&peer_memory_mutex); - return ib_peer_client; -} /* Caller should be holding the peer client lock, ib_peer_client->lock */ static struct core_ticket *ib_peer_search_context(struct ib_peer_memory_client *ib_peer_client, @@ -436,14 +237,7 @@ void *ib_register_peer_memory_client(const struct peer_memory_client *peer_clien ib_peer_client->last_ticket = 1; mutex_lock(&peer_memory_mutex); - if (create_peer_sysfs(ib_peer_client)) { - kfree(ib_peer_client); - ib_peer_client = NULL; - goto end; - } list_add_tail(&ib_peer_client->core_peer_list, &peer_memory_list); -end: - mutex_unlock(&peer_memory_mutex); return ib_peer_client; } @@ -455,7 +249,6 @@ void ib_unregister_peer_memory_client(void *reg_handle) mutex_lock(&peer_memory_mutex); list_del(&ib_peer_client->core_peer_list); - destroy_peer_sysfs(ib_peer_client); mutex_unlock(&peer_memory_mutex); kref_put(&ib_peer_client->ref, complete_peer); diff --git a/drivers/infiniband/hw/xsc/private_dev.c b/drivers/infiniband/hw/xsc/private_dev.c index a263ed941fed..aa4ec4fd53e5 100644 --- a/drivers/infiniband/hw/xsc/private_dev.c +++ b/drivers/infiniband/hw/xsc/private_dev.c @@ -286,6 +286,7 @@ static int xsc_priv_modify_qp(struct xsc_core_device *xdev, void *in, void *out) mailin = kvzalloc(insize, GFP_KERNEL); if (!mailin) return -ENOMEM; + if (resp->opcode == XSC_CMD_OP_RTR2RTS_QP) { for (i = 0; i < resp->num; i++) { mailin->hdr.opcode = cpu_to_be16(XSC_CMD_OP_RTR2RTS_QP); @@ -305,8 +306,6 @@ static int xsc_priv_dev_ioctl_get_phy(struct xsc_core_device *xdev, int ret = 0; struct xsc_ioctl_data_tl *tl = (struct xsc_ioctl_data_tl *)out; struct xsc_ioctl_get_phy_info_res *resp; - struct xsc_ioctl_get_vf_info_res *vf_res; - struct xsc_vf_info vf_info; struct xsc_lag *ldev = xsc_lag_dev_get(xdev); u16 lag_id = U16_MAX; @@ -317,11 +316,11 @@ static int xsc_priv_dev_ioctl_get_phy(struct xsc_core_device *xdev, case XSC_IOCTL_OP_GET_LOCAL: resp = (struct xsc_ioctl_get_phy_info_res *)(tl + 1); - resp->phy_port = xdev->pcie_port; + resp->pcie_no = xdev->pcie_no; resp->func_id = xdev->glb_func_id; - resp->logic_in_port = xdev->logic_port; + resp->pcie_host = xdev->caps.pcie_host; resp->mac_phy_port = xdev->mac_port; - resp->mac_logic_in_port = xdev->mac_logic_port; + resp->funcid_to_logic_port_off = xdev->caps.funcid_to_logic_port; resp->lag_id = lag_id; resp->raw_qp_id_base = xdev->caps.raweth_qp_id_base; resp->raw_rss_qp_id_base = xdev->caps.raweth_rss_qp_id_base; @@ -337,29 +336,20 @@ static int xsc_priv_dev_ioctl_get_phy(struct xsc_core_device *xdev, resp->pct_compress_vld = (xdev->feature_flag & FEATURE_PCT_EXP_MASK) ? 1 : 0; - xsc_core_dbg(xdev, "%d,%d,%d,%d,%d,%d\n", resp->phy_port, - resp->func_id, resp->logic_in_port, - resp->mac_phy_port, resp->mac_logic_in_port, - resp->lag_id); - resp->funcid[0] = xdev->caps.funcid[0]; - resp->funcid[1] = xdev->caps.funcid[1]; - resp->funcid[2] = xdev->caps.funcid[2]; - resp->funcid[3] = xdev->caps.funcid[3]; - resp->funcid[4] = xdev->caps.funcid[4]; - resp->funcid[5] = xdev->caps.funcid[5]; - resp->funcid[6] = xdev->caps.funcid[6]; - resp->funcid[7] = xdev->caps.funcid[7]; + xsc_core_dbg(xdev, "%d,%d,%d,%d,%d,%d\n", + resp->pcie_no, resp->func_id, resp->pcie_host, + resp->mac_phy_port, resp->lag_id, + resp->funcid_to_logic_port_off); + resp->pf0_vf_funcid_base = xdev->caps.pf0_vf_funcid_base; + resp->pf0_vf_funcid_top = xdev->caps.pf0_vf_funcid_top; + resp->pf1_vf_funcid_base = xdev->caps.pf1_vf_funcid_base; + resp->pf1_vf_funcid_top = xdev->caps.pf1_vf_funcid_top; + resp->pcie0_pf_funcid_base = xdev->caps.pcie0_pf_funcid_base; + resp->pcie0_pf_funcid_top = xdev->caps.pcie0_pf_funcid_top; + resp->pcie1_pf_funcid_base = xdev->caps.pcie1_pf_funcid_base; + resp->pcie1_pf_funcid_top = xdev->caps.pcie1_pf_funcid_top; resp->hca_core_clock = xdev->caps.hca_core_clock; - break; - - case XSC_IOCTL_OP_GET_VF_INFO: - vf_res = (struct xsc_ioctl_get_vf_info_res *)(tl + 1); - memcpy(&vf_info, vf_res, sizeof(struct xsc_vf_info)); - - xsc_pci_get_vf_info(xdev, &vf_info); - - vf_res->func_id = vf_info.func_id; - vf_res->logic_port = vf_info.logic_port; + resp->mac_bit = xdev->caps.mac_bit; break; default: @@ -375,7 +365,7 @@ static int xsc_priv_dev_ioctl_get_global_pcp(struct xsc_core_device *xdev, void int ret = 0; struct xsc_ioctl_global_pcp *resp = (struct xsc_ioctl_global_pcp *)out; - if (!check_is_pf(&xdev->caps, xdev->glb_func_id)) { + if (!xsc_core_is_pf(xdev)) { ret = -EOPNOTSUPP; return ret; } @@ -389,7 +379,7 @@ static int xsc_priv_dev_ioctl_get_global_dscp(struct xsc_core_device *xdev, void int ret = 0; struct xsc_ioctl_global_dscp *resp = (struct xsc_ioctl_global_dscp *)out; - if (!check_is_pf(&xdev->caps, xdev->glb_func_id)) { + if (!xsc_core_is_pf(xdev)) { ret = -EOPNOTSUPP; return ret; } @@ -403,7 +393,7 @@ static int xsc_priv_dev_ioctl_set_global_pcp(struct xsc_core_device *xdev, void int ret = 0; struct xsc_ioctl_global_pcp *req = (struct xsc_ioctl_global_pcp *)out; - if (!check_is_pf(&xdev->caps, xdev->glb_func_id)) { + if (!xsc_core_is_pf(xdev)) { ret = -EOPNOTSUPP; return ret; } @@ -417,7 +407,7 @@ static int xsc_priv_dev_ioctl_set_global_dscp(struct xsc_core_device *xdev, void int ret = 0; struct xsc_ioctl_global_dscp *req = (struct xsc_ioctl_global_dscp *)out; - if (!check_is_pf(&xdev->caps, xdev->glb_func_id)) { + if (!xsc_core_is_pf(xdev)) { ret = -EOPNOTSUPP; return ret; } @@ -660,7 +650,7 @@ static int xsc_ioctl_modify_raw_qp(struct xsc_priv_device *priv_dev, goto err; in->hdr.opcode = __cpu_to_be16(hdr->attr.opcode); - in->pcie_no = g_xsc_pcie_no; + in->pcie_no = xdev->pcie_no; err = xsc_cmd_exec(xdev, in, sizeof(struct xsc_modify_raw_qp_mbox_in), out, sizeof(struct xsc_modify_raw_qp_mbox_out)); diff --git a/drivers/infiniband/hw/xsc/qp.c b/drivers/infiniband/hw/xsc/qp.c index b3dbad288ae9..c497610e9b1d 100644 --- a/drivers/infiniband/hw/xsc/qp.c +++ b/drivers/infiniband/hw/xsc/qp.c @@ -298,6 +298,7 @@ static int create_user_qp(struct xsc_ib_dev *dev, struct ib_pd *pd, xsc_ib_cont_pages(qp->umem, ucmd.buf_addr, &npages, &page_shift, &ncont, NULL); if (ncont != npages) { + // TODO: peer memory support failed page_shift = PAGE_SHIFT; ncont = npages; } @@ -342,6 +343,7 @@ static void destroy_qp_user(struct ib_pd *pd, struct xsc_ib_qp *qp) context = to_xucontext(pd->uobject->context); ib_umem_release(qp->umem); + } #define MAX_QP1_SQ_HDR_SIZE_V2 512 @@ -411,9 +413,9 @@ static int create_kernel_qp(struct xsc_ib_dev *dev, qp->sq.mad_queue_depth = MAD_QUEUE_DEPTH; qp->sq.hdr_size = MAX_QP1_SQ_HDR_SIZE_V2 * MAD_QUEUE_DEPTH; qp->sq.hdr_buf = dma_alloc_coherent(dev->ib_dev.dma_device, - qp->sq.hdr_size, - &qp->sq.hdr_dma, - GFP_KERNEL); + qp->sq.hdr_size, + &qp->sq.hdr_dma, + GFP_KERNEL); if (!qp->sq.hdr_buf) { err = -ENOMEM; xsc_ib_err(dev, "Failed to create sq_hdr_buf"); @@ -439,7 +441,7 @@ static void destroy_qp_kernel(struct xsc_ib_dev *dev, struct xsc_ib_qp *qp) { if (qp->sq.hdr_buf) dma_free_coherent(dev->ib_dev.dma_device, qp->sq.hdr_size, - qp->sq.hdr_buf, qp->sq.hdr_dma); + qp->sq.hdr_buf, qp->sq.hdr_dma); kfree(qp->sq.wqe_head); kfree(qp->sq.w_list); kfree(qp->sq.wrid); @@ -574,7 +576,6 @@ static int create_qp_common(struct xsc_ib_dev *dev, struct ib_pd *pd, if (in->req.qp_type == XSC_QUEUE_TYPE_INVALID) goto err_create; in->req.glb_funcid = cpu_to_be16(dev->xdev->glb_func_id); - in->req.logic_port = cpu_to_be16(dev->xdev->logic_port); qp->xqp.qp_type_internal = in->req.qp_type; @@ -765,7 +766,6 @@ int xsc_ib_create_qp(struct ib_qp *ibqp, struct xsc_ib_qp *qp; struct ib_pd *pd = ibqp->pd; int err; - qp = to_xqp(ibqp); if (pd) { dev = to_mdev(pd->device); @@ -1004,7 +1004,7 @@ static int __xsc_ib_modify_qp(struct ib_qp *ibqp, LAG_PORT_NUM_OFFSET) % lag_port_num; else - context->lag_sel = qp->xqp.qpn % XSC_MAX_PORTS; + context->lag_sel = (ldev->lag_cnt++) % XSC_MAX_PORTS; } } @@ -1132,23 +1132,6 @@ static int xsc_wq_overflow(struct xsc_ib_wq *wq, int nreq, struct xsc_ib_cq *cq) return cur + nreq >= wq->max_post; } -#ifdef XSC_DEBUG -static void dump_wqe(struct xsc_ib_qp *qp, int idx) -{ - struct xsc_send_wqe_ctrl_seg *seg; - struct xsc_ib_dev *dev = to_mdev(qp->ibqp.device); - u32 *p = NULL; - int i; - - seg = xsc_get_send_wqe(qp, idx); - xsc_ib_dbg(dev, "current wqe:%p index:%d\n", seg, idx); - for (i = 0; i < 4; i++) { - p = (u32 *)get_seg_wqe(seg, i); - xsc_ib_dbg(dev, "%08x %08x %08x %08x\n", p[0], p[1], p[2], p[3]); - } -} -#endif - static inline void xsc_post_send_db(struct xsc_ib_qp *qp, struct xsc_core_device *xdev, int nreq) @@ -1275,6 +1258,7 @@ u32 xsc_icrc_hdr(struct xsc_ib_dev *dev, void *pkt, u32 size, u32 *icrc) /* Routine for sending QP1 packets for RoCE V1 an V2 */ + // TO BE DONE: sq hdr buf should be create dynamically for mult entry int build_qp1_send_v2(struct xsc_ib_dev *dev, struct xsc_ib_qp *qp, const struct ib_send_wr *wr, @@ -1350,11 +1334,25 @@ int build_qp1_send_v2(struct xsc_ib_dev *dev, qp->qp1_hdr.vlan.tag = cpu_to_be16(vlan_id | cm_pcp); } +#define ECN_CAPABLE_TRANSPORT 0x2 + if (is_grh || ip_version == 6) { + memcpy(qp->qp1_hdr.grh.source_gid.raw, sgid_attr->gid.raw, + sizeof(sgid_attr->gid)); + memcpy(qp->qp1_hdr.grh.destination_gid.raw, ah->av.rgid, + sizeof(ah->av.rgid)); + qp->qp1_hdr.grh.hop_limit = ah->av.hop_limit; + + if (dev->cm_dscp != DSCP_PCP_UNSET) + qp->qp1_hdr.grh.traffic_class = (dev->cm_dscp << 2) | ECN_CAPABLE_TRANSPORT; + else + qp->qp1_hdr.grh.traffic_class = ECN_CAPABLE_TRANSPORT; + } + if (ip_version == 4) { if (dev->cm_dscp != DSCP_PCP_UNSET) - qp->qp1_hdr.ip4.tos = dev->cm_dscp << 2; + qp->qp1_hdr.ip4.tos = (dev->cm_dscp << 2) | ECN_CAPABLE_TRANSPORT; else - qp->qp1_hdr.ip4.tos = 0; + qp->qp1_hdr.ip4.tos = ECN_CAPABLE_TRANSPORT; qp->qp1_hdr.ip4.id = 0; qp->qp1_hdr.ip4.frag_off = htons(IP_DF); qp->qp1_hdr.ip4.ttl = ah->av.hop_limit; @@ -1646,9 +1644,6 @@ int xsc_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, qp->sq.wrid[idx] = wr->wr_id; qp->sq.wqe_head[idx] = qp->sq.head + nreq; qp->sq.cur_post += 1; -#ifdef XSC_DEBUG - dump_wqe(qp, idx); -#endif } out: xsc_ib_dbg(dev, "nreq:%d\n", nreq); diff --git a/drivers/infiniband/hw/xsc/rtt.c b/drivers/infiniband/hw/xsc/rtt.c index 9d24ff7dab31..727963b84b01 100644 --- a/drivers/infiniband/hw/xsc/rtt.c +++ b/drivers/infiniband/hw/xsc/rtt.c @@ -272,8 +272,8 @@ static ssize_t stats_show(struct xsc_rtt_interface *g, struct xsc_rtt_attributes __be64_to_cpu(out.stats.rtt_rcv_rsp_cnt)); count += sprintf(&buf[count], "rtt_rcv_unk_cnt %llu\n", __be64_to_cpu(out.stats.rtt_rcv_unk_cnt)); - count += sprintf(&buf[count], "rtt_grp_invalid_cnt %llu\n", - __be64_to_cpu(out.stats.rtt_grp_invalid_cnt)); + count += sprintf(&buf[count], "rtt_grp_invaild_cnt %llu\n", + __be64_to_cpu(out.stats.rtt_grp_invaild_cnt)); return count; } diff --git a/drivers/infiniband/hw/xsc/xsc_ib.h b/drivers/infiniband/hw/xsc/xsc_ib.h index 6ff80cfce156..aa6a6bcced76 100644 --- a/drivers/infiniband/hw/xsc/xsc_ib.h +++ b/drivers/infiniband/hw/xsc/xsc_ib.h @@ -389,6 +389,7 @@ int xsc_ib_query_port(struct ib_device *ibdev, u32 port, int xsc_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr, struct ib_udata *udata); + void __xsc_ib_cq_clean(struct xsc_ib_cq *cq, u32 qpn); void xsc_ib_cq_clean(struct xsc_ib_cq *cq, u32 qpn); diff --git a/drivers/infiniband/hw/xsc/xsc_ib_compat.h b/drivers/infiniband/hw/xsc/xsc_ib_compat.h index 04c71442f416..937577ebe59b 100644 --- a/drivers/infiniband/hw/xsc/xsc_ib_compat.h +++ b/drivers/infiniband/hw/xsc/xsc_ib_compat.h @@ -30,6 +30,7 @@ int xsc_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata); int xsc_ib_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata); void xsc_ib_dealloc_ucontext(struct ib_ucontext *ibcontext); int xsc_ib_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata); + int xsc_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata); int xsc_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata); struct ib_mr *xsc_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, u32 max_num_sg); @@ -45,7 +46,9 @@ struct ib_mr *xsc_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, u32 max struct ib_ucontext *uctx, struct ib_udata *udata) #define xsc_ib_dealloc_ucontext_def() void xsc_ib_dealloc_ucontext(struct ib_ucontext *ibcontext) #define xsc_ib_alloc_pd_def() int xsc_ib_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) + #define xsc_ib_dealloc_pd_def() int xsc_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) + #define RET_VALUE(x) (x) #endif diff --git a/drivers/infiniband/hw/xsc/xsc_rdma_ctrl.c b/drivers/infiniband/hw/xsc/xsc_rdma_ctrl.c index e32aaacba583..777be012579e 100644 --- a/drivers/infiniband/hw/xsc/xsc_rdma_ctrl.c +++ b/drivers/infiniband/hw/xsc/xsc_rdma_ctrl.c @@ -303,7 +303,7 @@ static int xsc_priv_dev_ioctl_get_cma_pcp(struct xsc_core_device *xdev, void *in struct xsc_ib_dev *ib_dev = xdev->xsc_ib_dev; struct xsc_ioctl_cma_pcp *resp = (struct xsc_ioctl_cma_pcp *)out; - if (!check_is_pf(&xdev->caps, xdev->glb_func_id)) + if (!xsc_core_is_pf(xdev)) return -EOPNOTSUPP; resp->pcp = ib_dev->cm_pcp; @@ -315,7 +315,7 @@ static int xsc_priv_dev_ioctl_get_cma_dscp(struct xsc_core_device *xdev, void *i struct xsc_ib_dev *ib_dev = xdev->xsc_ib_dev; struct xsc_ioctl_cma_dscp *resp = (struct xsc_ioctl_cma_dscp *)out; - if (!check_is_pf(&xdev->caps, xdev->glb_func_id)) + if (!xsc_core_is_pf(xdev)) return -EOPNOTSUPP; resp->dscp = ib_dev->cm_dscp; @@ -327,7 +327,7 @@ static int xsc_priv_dev_ioctl_set_cma_pcp(struct xsc_core_device *xdev, void *in struct xsc_ib_dev *ib_dev = xdev->xsc_ib_dev; struct xsc_ioctl_cma_pcp *req = (struct xsc_ioctl_cma_pcp *)out; - if (!check_is_pf(&xdev->caps, xdev->glb_func_id)) + if (!xsc_core_is_pf(xdev)) return -EOPNOTSUPP; if (req->pcp < 0 || (req->pcp > QOS_PCP_MAX && req->pcp != DSCP_PCP_UNSET)) @@ -342,7 +342,7 @@ static int xsc_priv_dev_ioctl_set_cma_dscp(struct xsc_core_device *xdev, void *i struct xsc_ib_dev *ib_dev = xdev->xsc_ib_dev; struct xsc_ioctl_cma_dscp *req = (struct xsc_ioctl_cma_dscp *)out; - if (!check_is_pf(&xdev->caps, xdev->glb_func_id)) + if (!xsc_core_is_pf(xdev)) return -EOPNOTSUPP; if (req->dscp < 0 || (req->dscp > QOS_DSCP_MAX && req->dscp != DSCP_PCP_UNSET)) @@ -642,6 +642,7 @@ static int _rdma_ctrl_reg_cb(struct xsc_bdf_file *file, unsigned int cmd, break; case XSC_IOCTL_DRV_GET: case XSC_IOCTL_DRV_SET: + // TODO refactor to split driver get and set err = _rdma_ctrl_ioctl_getinfo(xdev, user_hdr); break; default: diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/port.h b/drivers/net/ethernet/yunsilicon/xsc/common/port.h index 5edb854e0fcd..a44af6c88c06 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/port.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/port.h @@ -11,7 +11,9 @@ enum xsc_module_id { XSC_MODULE_ID_QSFP = 0xC, XSC_MODULE_ID_QSFP_PLUS = 0xD, XSC_MODULE_ID_QSFP28 = 0x11, - XSC_MODULE_ID_DSFP = 0x1B, + XSC_MODULE_ID_QSFP_DD = 0x18, + XSC_MODULE_ID_DSFP = 0x1B, + XSC_MODULE_ID_QSFP_PLUS_CMIS = 0x1E, }; #define XSC_EEPROM_MAX_BYTES 32 diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/qp.h b/drivers/net/ethernet/yunsilicon/xsc/common/qp.h index d6c073dc2443..4b5f2bc6760f 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/qp.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/qp.h @@ -116,7 +116,13 @@ struct xsc_core_qp { struct xsc_qp_trace *trace_info; u16 qp_type_internal; u16 grp_id; +}; + +struct xsc_qp_rsc { + struct list_head node; + u32 qpn; struct completion delayed_release; + struct xsc_core_device *xdev; }; struct xsc_qp_path { @@ -182,6 +188,11 @@ void xsc_remove_qptrace(struct xsc_core_device *xdev, struct xsc_core_qp *qp); void xsc_init_delayed_release(void); void xsc_stop_delayed_release(void); -void xsc_add_to_delayed_release_list(struct xsc_core_device *xdev, struct xsc_core_qp *qp); + +int xsc_modify_qp(struct xsc_core_device *xdev, + struct xsc_modify_qp_mbox_in *in, + struct xsc_modify_qp_mbox_out *out, + u32 qpn, u16 status); + #endif /* XSC_QP_H */ diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/qpts.h b/drivers/net/ethernet/yunsilicon/xsc/common/qpts.h index 99d6a478d3ec..57eb829f811b 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/qpts.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/qpts.h @@ -53,8 +53,7 @@ struct __packed qpt_update_data { struct __packed xsc_qpt_update_msg { u16 main_ver; u16 sub_ver; - /* 0:UPDATE_TYPE_SPORT; 1:UPDATE_TYPE_AFFINITY */ - u32 type; + u32 type; //0:UPDATE_TYPE_SPORT; 1:UPDATE_TYPE_AFFINITY struct qpt_update_data data; }; diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/version.h b/drivers/net/ethernet/yunsilicon/xsc/common/version.h index 39c7d2592754..30a778e9d779 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/version.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/version.h @@ -4,7 +4,7 @@ */ #define BRANCH_VERSION 1 -#define MAJOR_VERSION 1 +#define MAJOR_VERSION 2 #define MINOR_VERSION 0 -#define HOTFIX_NUM 0 -#define BUILD_VERSION 375 +#define BUILD_VERSION 93 +#define HOTFIX_NUM 83 diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/vport.h b/drivers/net/ethernet/yunsilicon/xsc/common/vport.h index e50733f6655a..6f7655154e85 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/vport.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/vport.h @@ -113,5 +113,6 @@ int xsc_modify_hca_vport_context(struct xsc_core_device *dev, u8 other_vport, u8 port_num, int vf, struct xsc_hca_vport_context *req); + u16 xsc_eswitch_get_total_vports(const struct xsc_core_device *dev); #endif /* XSC_VPORT_H */ diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_auto_hw.h b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_auto_hw.h index 108e0f5a7c7b..4864cb747cde 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_auto_hw.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_auto_hw.h @@ -1,16 +1,17 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2021 - 2023, Shanghai Yunsilicon Technology Co., Ltd. +/* + * Copyright (C) 2021 - 2023, Shanghai Yunsilicon Technology Co., Ltd. * All rights reserved. */ /* generated time: - * Mon Jan 22 11:36:34 CST 2024 + * Thu Feb 29 15:33:50 CST 2024 */ #ifndef XSC_HW_H #define XSC_HW_H //hif_irq_csr_defines.h -#define HIF_IRQ_TBL2IRQ_TBL_RD_DONE_INT_MSIX_REG_ADDR 0xa1100050 +#define HIF_IRQ_TBL2IRQ_TBL_RD_DONE_INT_MSIX_REG_ADDR 0xa1100070 //hif_cpm_csr_defines.h #define HIF_CPM_LOCK_GET_REG_ADDR 0xa0000104 @@ -30,22 +31,22 @@ //mmc_csr_defines.h #define MMC_MPT_TBL_MEM_DEPTH 32768 -#define MMC_MTT_TBL_MEM_DEPTH 65536 +#define MMC_MTT_TBL_MEM_DEPTH 262144 #define MMC_MPT_TBL_MEM_WIDTH 256 #define MMC_MTT_TBL_MEM_WIDTH 64 #define MMC_MPT_TBL_MEM_ADDR 0xa4100000 #define MMC_MTT_TBL_MEM_ADDR 0xa4200000 //clsf_dma_csr_defines.h -#define CLSF_DMA_DMA_UL_BUSY_REG_ADDR 0xa6010038 -#define CLSF_DMA_DMA_DL_DONE_REG_ADDR 0xa6010090 -#define CLSF_DMA_DMA_DL_SUCCESS_REG_ADDR 0xa6010080 -#define CLSF_DMA_ERR_CODE_CLR_REG_ADDR 0xa6010094 +#define CLSF_DMA_DMA_UL_BUSY_REG_ADDR 0xa6010048 +#define CLSF_DMA_DMA_DL_DONE_REG_ADDR 0xa60100d0 +#define CLSF_DMA_DMA_DL_SUCCESS_REG_ADDR 0xa60100c0 +#define CLSF_DMA_ERR_CODE_CLR_REG_ADDR 0xa60100d4 #define CLSF_DMA_DMA_RD_TABLE_ID_REG_DMA_RD_TBL_ID_MASK 0x7f -#define CLSF_DMA_DMA_RD_TABLE_ID_REG_ADDR 0xa6010010 +#define CLSF_DMA_DMA_RD_TABLE_ID_REG_ADDR 0xa6010020 #define CLSF_DMA_DMA_RD_ADDR_REG_DMA_RD_BURST_NUM_SHIFT 16 -#define CLSF_DMA_DMA_RD_ADDR_REG_ADDR 0xa6010014 -#define CLSF_DMA_INDRW_RD_START_REG_ADDR 0xa6010018 +#define CLSF_DMA_DMA_RD_ADDR_REG_ADDR 0xa6010024 +#define CLSF_DMA_INDRW_RD_START_REG_ADDR 0xa6010028 //hif_tbl_csr_defines.h #define HIF_TBL_TBL_DL_BUSY_REG_ADDR 0xa1060030 @@ -67,29 +68,30 @@ #define HIF_TBL_MSG_RDY_REG_ADDR 0xa1060044 //hif_cmdqm_csr_defines.h -#define HIF_CMDQM_HOST_REQ_PID_MEM_ADDR 0xa1023000 -#define HIF_CMDQM_HOST_REQ_CID_MEM_ADDR 0xa1024000 -#define HIF_CMDQM_HOST_RSP_PID_MEM_ADDR 0xa1027000 -#define HIF_CMDQM_HOST_RSP_CID_MEM_ADDR 0xa1028000 -#define HIF_CMDQM_HOST_REQ_BUF_BASE_H_ADDR_MEM_ADDR 0xa1021000 -#define HIF_CMDQM_HOST_REQ_BUF_BASE_L_ADDR_MEM_ADDR 0xa1022000 -#define HIF_CMDQM_HOST_RSP_BUF_BASE_H_ADDR_MEM_ADDR 0xa1025000 -#define HIF_CMDQM_HOST_RSP_BUF_BASE_L_ADDR_MEM_ADDR 0xa1026000 -#define HIF_CMDQM_VECTOR_ID_MEM_ADDR 0xa102a000 +#define HIF_CMDQM_HOST_REQ_PID_MEM_ADDR 0xa1026000 +#define HIF_CMDQM_HOST_REQ_CID_MEM_ADDR 0xa1028000 +#define HIF_CMDQM_HOST_RSP_PID_MEM_ADDR 0xa102e000 +#define HIF_CMDQM_HOST_RSP_CID_MEM_ADDR 0xa1030000 +#define HIF_CMDQM_HOST_REQ_BUF_BASE_H_ADDR_MEM_ADDR 0xa1022000 +#define HIF_CMDQM_HOST_REQ_BUF_BASE_L_ADDR_MEM_ADDR 0xa1024000 +#define HIF_CMDQM_HOST_RSP_BUF_BASE_H_ADDR_MEM_ADDR 0xa102a000 +#define HIF_CMDQM_HOST_RSP_BUF_BASE_L_ADDR_MEM_ADDR 0xa102c000 +#define HIF_CMDQM_VECTOR_ID_MEM_ADDR 0xa1034000 #define HIF_CMDQM_Q_ELEMENT_SZ_REG_ADDR 0xa1020020 #define HIF_CMDQM_HOST_Q_DEPTH_REG_ADDR 0xa1020028 -#define HIF_CMDQM_HOST_VF_ERR_STS_MEM_ADDR 0xa1029000 +#define HIF_CMDQM_HOST_VF_ERR_STS_MEM_ADDR 0xa1032000 +//PSV use //hif_irq_csr_defines.h #define HIF_IRQ_CONTROL_TBL_MEM_ADDR 0xa1102000 -#define HIF_IRQ_INT_DB_REG_ADDR 0xa1100094 -#define HIF_IRQ_CFG_VECTOR_TABLE_BUSY_REG_ADDR 0xa11000f4 -#define HIF_IRQ_CFG_VECTOR_TABLE_ADDR_REG_ADDR 0xa11000d0 -#define HIF_IRQ_CFG_VECTOR_TABLE_CMD_REG_ADDR 0xa11000cc -#define HIF_IRQ_CFG_VECTOR_TABLE_MSG_LADDR_REG_ADDR 0xa11000d4 -#define HIF_IRQ_CFG_VECTOR_TABLE_MSG_UADDR_REG_ADDR 0xa11000d8 -#define HIF_IRQ_CFG_VECTOR_TABLE_MSG_DATA_REG_ADDR 0xa11000dc -#define HIF_IRQ_CFG_VECTOR_TABLE_CTRL_REG_ADDR 0xa11000e0 -#define HIF_IRQ_CFG_VECTOR_TABLE_START_REG_ADDR 0xa11000c8 +#define HIF_IRQ_INT_DB_REG_ADDR 0xa11000b4 +#define HIF_IRQ_CFG_VECTOR_TABLE_BUSY_REG_ADDR 0xa1100114 +#define HIF_IRQ_CFG_VECTOR_TABLE_ADDR_REG_ADDR 0xa11000f0 +#define HIF_IRQ_CFG_VECTOR_TABLE_CMD_REG_ADDR 0xa11000ec +#define HIF_IRQ_CFG_VECTOR_TABLE_MSG_LADDR_REG_ADDR 0xa11000f4 +#define HIF_IRQ_CFG_VECTOR_TABLE_MSG_UADDR_REG_ADDR 0xa11000f8 +#define HIF_IRQ_CFG_VECTOR_TABLE_MSG_DATA_REG_ADDR 0xa11000fc +#define HIF_IRQ_CFG_VECTOR_TABLE_CTRL_REG_ADDR 0xa1100100 +#define HIF_IRQ_CFG_VECTOR_TABLE_START_REG_ADDR 0xa11000e8 #endif /* XSC_HW_H */ diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_cmd.h b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_cmd.h index d5bea38ac13b..647bc5d044d8 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_cmd.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_cmd.h @@ -6,7 +6,7 @@ #ifndef XSC_CMD_H #define XSC_CMD_H -#define CMDQ_VERSION 0x19 +#define CMDQ_VERSION 0x21 #define QOS_PRIO_MAX 7 #define QOS_DSCP_MAX 63 @@ -19,13 +19,10 @@ #define MAX_PKT_LEN 9800 #define XSC_RTT_CFG_QPN_MAX 32 -#define XSC_PCIE_LAT_INIT_INTERVAL_MIN 200 #define XSC_PCIE_LAT_CFG_INTERVAL_MAX 8 #define XSC_PCIE_LAT_CFG_HISTOGRAM_MAX 9 #define XSC_PCIE_LAT_EN_DISABLE 0 #define XSC_PCIE_LAT_EN_ENABLE 1 -#define XSC_PCIE_LAT_INTERVAL_MIN 100 -#define XSC_PCIE_LAT_INTERVAL_MAX 30000 #define XSC_PCIE_LAT_PERIOD_MIN 1 #define XSC_PCIE_LAT_PERIOD_MAX 20 #define DPU_PORT_WGHT_CFG_MAX 1 @@ -154,6 +151,10 @@ enum { XSC_CMD_OP_QUERY_PHYPORT_STATE = 0x830, XSC_CMD_OP_QUERY_EVENT_TYPE = 0x831, XSC_CMD_OP_QUERY_LINK_INFO = 0x832, + XSC_CMD_OP_QUERY_PFC_PRIO_STATS = 0x833, + XSC_CMD_OP_MODIFY_LINK_INFO = 0x834, + XSC_CMD_OP_QUERY_FEC_PARAM = 0x835, + XSC_CMD_OP_MODIFY_FEC_PARAM = 0x836, XSC_CMD_OP_LAG_CREATE = 0x840, XSC_CMD_OP_LAG_MODIFY = 0x841, @@ -228,7 +229,7 @@ enum { XSC_CMD_OP_SET_LED_STATUS = 0X1228, - XSC_CMD_OP_AP_FEAT = 0x1400, + XSC_CMD_OP_AP_FEAT = 0x1400, XSC_CMD_OP_PCIE_LAT_FEAT = 0x1401, XSC_CMD_OP_USER_EMU_CMD = 0x8000, @@ -241,8 +242,7 @@ enum { }; enum xsc_eth_qp_num_sel { - XSC_ETH_QP_NUM_1K_SEL = 0, - XSC_ETH_QP_NUM_8K_SEL, + XSC_ETH_QP_NUM_8K_SEL = 0, XSC_ETH_QP_NUM_8K_8TC_SEL, XSC_ETH_QP_NUM_SEL_MAX, }; @@ -255,12 +255,33 @@ enum xsc_eth_vf_num_sel { XSC_ETH_VF_NUM_SEL_128, XSC_ETH_VF_NUM_SEL_256, XSC_ETH_VF_NUM_SEL_512, + XSC_ETH_VF_NUM_SEL_1024, XSC_ETH_VF_NUM_SEL_MAX }; enum { - XSC_CMD_RESP_LINKSPEED_MODE_25G = 25000, - XSC_CMD_RESP_LINKSPEED_MODE_100G = 100000 + LINKSPEED_MODE_UNKNOWN = -1, + LINKSPEED_MODE_10G = 10000, + LINKSPEED_MODE_25G = 25000, + LINKSPEED_MODE_40G = 40000, + LINKSPEED_MODE_50G = 50000, + LINKSPEED_MODE_100G = 100000, + LINKSPEED_MODE_200G = 200000, + LINKSPEED_MODE_400G = 400000, +}; + +enum { + MODULE_SPEED_UNKNOWN, + MODULE_SPEED_10G, + MODULE_SPEED_25G, + MODULE_SPEED_40G_R4, + MODULE_SPEED_50G_R, + MODULE_SPEED_50G_R2, + MODULE_SPEED_100G_R2, + MODULE_SPEED_100G_R4, + MODULE_SPEED_200G_R4, + MODULE_SPEED_200G_R8, + MODULE_SPEED_400G_R8, }; enum xsc_dma_direct { @@ -274,7 +295,7 @@ enum xsc_dma_direct { /* hw feature bitmap, 32bit */ enum xsc_hw_feature_flag { XSC_HW_RDMA_SUPPORT = 0x1, - XSC_HW_SECOND_FEATURE = 0x2, + XSC_HW_PFC_PRIO_STATISTIC_SUPPORT = 0x2, XSC_HW_THIRD_FEATURE = 0x4, XSC_HW_LAST_FEATURE = 0x80000000, @@ -351,7 +372,7 @@ struct xsc_create_qp_request { __be16 cqn_recv; __be16 glb_funcid; /*rsvd,rename logic_port used to transfer logical_port to fw*/ - __be16 logic_port; + u8 rsvd[2]; __be64 pas[]; }; @@ -507,7 +528,7 @@ struct xsc_eq_context { u8 log_eq_sz; __be16 glb_func_id; u8 is_async_eq; - u8 rsvd; + u8 rsvd[1]; }; struct xsc_create_eq_mbox_in { @@ -734,6 +755,15 @@ struct xsc_cmd_dummy_mbox_out { u8 rsvd[8]; }; +struct xsc_fw_version { + u8 fw_version_major; + u8 fw_version_minor; + __be16 fw_version_patch; + __be32 fw_version_tweak; + u8 fw_version_extra_flag; + u8 rsvd[7]; +}; + struct xsc_hca_cap { u8 rsvd1[12]; u8 send_seg_num; @@ -806,13 +836,23 @@ struct xsc_hca_cap { __be32 uar_page_sz; u8 rsvd27[8]; __be32 hw_feature_flag;/*enum xsc_hw_feature_flag*/ - __be16 funcid[8]; + __be16 pf0_vf_funcid_base; + __be16 pf0_vf_funcid_top; + __be16 pf1_vf_funcid_base; + __be16 pf1_vf_funcid_top; + __be16 pcie0_pf_funcid_base; + __be16 pcie0_pf_funcid_top; + __be16 pcie1_pf_funcid_base; + __be16 pcie1_pf_funcid_top; u8 log_msx_atomic_size_qp; - u8 rsvd28[2]; + u8 pcie_host; + u8 rsvd28; u8 log_msx_atomic_size_dc; u8 board_sn[XSC_BOARD_SN_LEN]; u8 max_tc; - u8 rsvd29[10]; + u8 mac_bit; + __be16 funcid_to_logic_port; + u8 rsvd29[7]; u8 nif_port_num; __be32 hca_core_clock; __be32 max_rwq_indirection_tables;/*rss_caps*/ @@ -831,6 +871,7 @@ struct xsc_hca_cap { __be64 event_db; __be32 qp_rate_limit_min; __be32 qp_rate_limit_max; + struct xsc_fw_version fw_ver; }; struct xsc_cmd_query_hca_cap_mbox_in { @@ -847,10 +888,6 @@ struct xsc_cmd_query_hca_cap_mbox_out { struct xsc_cmd_enable_hca_mbox_in { struct xsc_inbox_hdr hdr; - u8 pf; - u8 pcie; - u8 pf_id; - u8 rsvd0; __be16 vf_num; __be16 max_msix_vec; __be16 cpu_num; @@ -860,16 +897,11 @@ struct xsc_cmd_enable_hca_mbox_in { struct xsc_cmd_enable_hca_mbox_out { struct xsc_outbox_hdr hdr; - u8 status; - u8 rsvd0[3]; + u8 rsvd0[4]; }; struct xsc_cmd_disable_hca_mbox_in { struct xsc_inbox_hdr hdr; - u8 pf; - u8 pcie; - u8 pf_id; - u8 rsvd0; __be16 vf_num; u8 pp_bypass; u8 esw_mode; @@ -877,24 +909,19 @@ struct xsc_cmd_disable_hca_mbox_in { struct xsc_cmd_disable_hca_mbox_out { struct xsc_outbox_hdr hdr; - u8 status; - u8 rsvd0[3]; + u8 rsvd0[4]; }; struct xsc_cmd_modify_hca_mbox_in { struct xsc_inbox_hdr hdr; - u8 pf; - u8 pcie; - u8 pf_id; u8 pp_bypass; u8 esw_mode; - u8 rsvd0[3]; + u8 rsvd0[6]; }; struct xsc_cmd_modify_hca_mbox_out { struct xsc_outbox_hdr hdr; - u8 status; - u8 rsvd0[3]; + u8 rsvd0[4]; }; struct xsc_query_special_ctxs_mbox_in { @@ -1003,11 +1030,11 @@ struct xsc_modify_nic_vport_field_select { struct xsc_modify_nic_vport_context_in { struct xsc_inbox_hdr hdr; - __be32 other_vport:1; - __be32 vport_number:16; - __be32 rsvd:15; - __be16 caps; - __be16 caps_mask; + __be32 other_vport:1; + __be32 vport_number:16; + __be32 rsvd:15; + __be16 caps; + __be16 caps_mask; struct xsc_modify_nic_vport_field_select field_select; struct xsc_nic_vport_context nic_vport_ctx; @@ -1173,24 +1200,10 @@ struct xsc_modify_raw_qp_mbox_out { #define ETH_ALEN 6 -struct xsc_logic_port_info { - u8 pf; - u8 pcie; - u8 mac_port; /* mac physic port */ - u8 pcie_port; /* pcie physic port */ - u8 pf_id; - __be16 vf_id; - __be16 glb_func_id; /* function id */ - __be16 logic_port; /* logic port for pp */ - __be16 pf_logic_port; /* pf logic port */ - __be16 mac_logic_port; /* mac logic port */ - __be16 gsi_qpn; /* logic qpn for gsi*/ -}; - struct xsc_lag_port_info { - struct xsc_logic_port_info info_mac; u8 netdev_addr[ETH_ALEN]; u8 gw_dmac[ETH_ALEN]; + __be16 glb_func_id; }; struct xsc_create_lag_request { @@ -1306,6 +1319,23 @@ struct xsc_prio_stats_mbox_out { struct xsc_prio_stats prio_stats[QOS_PRIO_MAX + 1]; }; +struct xsc_pfc_prio_stats { + u64 tx_pause; + u64 tx_pause_duration; + u64 rx_pause; + u64 rx_pause_duration; +}; + +struct xsc_pfc_prio_stats_mbox_in { + struct xsc_inbox_hdr hdr; + u8 pport; +}; + +struct xsc_pfc_prio_stats_mbox_out { + struct xsc_outbox_hdr hdr; + struct xsc_pfc_prio_stats prio_stats[QOS_PRIO_MAX + 1]; +}; + struct xsc_hw_stats { /*by mac port*/ u64 rdma_tx_pkts; @@ -1403,7 +1433,7 @@ struct xsc_event_linkstatus_resp { u8 linkstatus; /*0:down, 1:up*/ }; -struct xsc_event_linkinfo_resp { +struct xsc_event_linkinfo { u8 linkstatus; /*0:down, 1:up*/ u8 port; u8 duplex; @@ -1443,7 +1473,17 @@ struct xsc_event_query_linkinfo_mbox_in { struct xsc_event_query_linkinfo_mbox_out { struct xsc_outbox_hdr hdr; - struct xsc_event_linkinfo_resp ctx; + struct xsc_event_linkinfo ctx; +}; + +struct xsc_event_modify_linkinfo_mbox_in { + struct xsc_inbox_hdr hdr; + struct xsc_event_linkinfo ctx; +}; + +struct xsc_event_modify_linkinfo_mbox_out { + struct xsc_outbox_hdr hdr; + u32 status; }; struct xsc_event_set_led_status_mbox_in { @@ -1456,6 +1496,28 @@ struct xsc_event_set_led_status_mbox_out { u32 status; }; +struct xsc_event_modify_fecparam_mbox_in { + struct xsc_inbox_hdr hdr; + u32 fec; +}; + +struct xsc_event_modify_fecparam_mbox_out { + struct xsc_outbox_hdr hdr; + u32 status; +}; + +struct xsc_event_query_fecparam_mbox_in { + struct xsc_inbox_hdr hdr; + u8 rsvd[2]; +}; + +struct xsc_event_query_fecparam_mbox_out { + struct xsc_outbox_hdr hdr; + u32 active_fec; + u32 fec_cfg; + u32 status; +}; + #define PFC_ON_PG_PRFL_IDX 0 #define PFC_OFF_PG_PRFL_IDX 1 #define PFC_ON_QMU_VALUE 0 @@ -1749,10 +1811,11 @@ struct hwc_set_t { u8 retry_cnt_th; u8 adapt_to_other; u8 alloc_qp_id_mode; - u16 max_vf_nums; + u16 max_vf_num; u8 eth_pkt_offset; u8 rdma_pkt_offset; u8 tso_eth_pkt_offset; + u8 tx_dedi_pref; }; struct hwc_get_t { @@ -1771,8 +1834,8 @@ struct hwc_get_t { u8 next_retry_cnt_th; u8 cur_adapt_to_other; u8 next_adapt_to_other; - u16 cur_max_vf_nums; - u16 next_max_vf_nums; + u16 cur_max_vf_num; + u16 next_max_vf_num; u8 cur_eth_pkt_offset; u8 next_eth_pkt_offset; u8 cur_rdma_pkt_offset; @@ -1781,6 +1844,8 @@ struct hwc_get_t { u8 next_tso_eth_pkt_offset; u8 cur_alloc_qp_id_mode; u8 next_alloc_qp_id_mode; + u8 cur_tx_dedi_pref; + u8 next_tx_dedi_pref; }; struct xsc_set_mtu_mbox_out { @@ -1813,10 +1878,10 @@ enum { XSC_TBM_CAP_HASH_PPH = 0, XSC_TBM_CAP_RSS, XSC_TBM_CAP_PP_BYPASS, + XSC_TBM_CAP_PCT_DROP_CONFIG, }; struct xsc_nic_attr { - struct xsc_logic_port_info info; __be16 caps; __be16 caps_mask; u8 mac_addr[6]; @@ -1838,12 +1903,10 @@ struct xsc_cmd_enable_nic_hca_mbox_in { struct xsc_cmd_enable_nic_hca_mbox_out { struct xsc_outbox_hdr hdr; - u8 status; - u8 rsvd0; + u8 rsvd0[2]; }; struct xsc_nic_dis_attr { - struct xsc_logic_port_info info; __be16 caps; }; @@ -1854,8 +1917,7 @@ struct xsc_cmd_disable_nic_hca_mbox_in { struct xsc_cmd_disable_nic_hca_mbox_out { struct xsc_outbox_hdr hdr; - u8 status; - u8 rsvd0[3]; + u8 rsvd0[4]; }; enum { @@ -1884,8 +1946,7 @@ struct xsc_cmd_modify_nic_hca_mbox_in { struct xsc_cmd_modify_nic_hca_mbox_out { struct xsc_outbox_hdr hdr; - u8 status; - u8 rsvd0[3]; + u8 rsvd0[4]; }; struct xsc_function_reset_mbox_in { @@ -2004,7 +2065,7 @@ struct rtt_stats { u64 rtt_rcv_req_cnt; u64 rtt_rcv_rsp_cnt; u64 rtt_rcv_unk_cnt; - u64 rtt_grp_invalid_cnt; + u64 rtt_grp_invaild_cnt; }; struct xsc_rtt_stats_mbox_out { diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h index 4501fe160668..ec9a56806d6b 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h @@ -61,7 +61,7 @@ extern unsigned int xsc_log_level; #define XSC_MV_SOC_PF_DEV_ID 0x1153 #define REG_ADDR(dev, offset) \ - (xsc_core_is_pf(dev) ? ((dev->bar2) + ((offset) - 0xA0000000)) : ((dev->bar2) + (offset))) + (xsc_core_is_pf(dev) ? ((dev->bar) + ((offset) - 0xA0000000)) : ((dev->bar) + (offset))) #define REG_WIDTH_TO_STRIDE(width) ((width) / 8) #define QPM_PAM_TBL_NUM 4 @@ -76,6 +76,14 @@ enum { XSC_LOG_LEVEL_ERR = 3, }; +enum { + XSC_CHIP_MC, + XSC_CHIP_MF, + XSC_CHIP_MS, + XSC_CHIP_MV, + XSC_CHIP_UNKNOWN, +}; + #ifndef dev_fmt #define dev_fmt(fmt) fmt #endif @@ -144,7 +152,12 @@ do { \ #define XSC_PCIE_NO_SOC 0x1 #define XSC_PCIE_NO_UNSET 0xFF -extern u8 g_xsc_pcie_no; +enum xsc_driver_mode { + HOST_MODE, + SOC_MODE, +}; + +u8 xsc_get_driver_work_mode(void); enum xsc_dev_event { XSC_DEV_EVENT_SYS_ERROR, @@ -331,14 +344,6 @@ struct xsc_vgroup { struct list_head list; }; -struct xsc_vf_info { - u16 vf_id; /* start from 1, 0 is reserved for pf */ - u16 phy_port; /* pcie0=0, pcie1=1 */ - u16 pf_id; /* pf0=0, pf1=1 */ - u32 func_id; - u32 logic_port; -}; - struct xsc_vport_info { u8 mac[ETH_ALEN]; u16 vlan; @@ -541,9 +546,18 @@ struct xsc_caps { u32 qp_rate_limit_min; u32 qp_rate_limit_max; u32 hw_feature_flag; - u16 funcid[8]; - u16 funcid_valid; + u16 pf0_vf_funcid_base; + u16 pf0_vf_funcid_top; + u16 pf1_vf_funcid_base; + u16 pf1_vf_funcid_top; + u16 pcie0_pf_funcid_base; + u16 pcie0_pf_funcid_top; + u16 pcie1_pf_funcid_base; + u16 pcie1_pf_funcid_top; u8 nif_port_num; + u8 pcie_host; + u8 mac_bit; + u16 funcid_to_logic_port; }; struct cache_ent { @@ -580,7 +594,7 @@ struct xsc_cmd_msg { #define RSP_FIRST_SIZE 14 struct xsc_rsp_first { - __be32 data[RSP_FIRST_SIZE]; /* can be larger, xsc_rsp_layout */ + __be32 data[RSP_FIRST_SIZE]; //can be larger, xsc_rsp_layout }; struct xsc_rsp_msg { @@ -593,13 +607,13 @@ struct xsc_rsp_msg { typedef void (*xsc_cmd_cbk_t)(int status, void *context); -/* hw will use this for some records(e.g. vf_id) */ +//hw will use this for some records(e.g. vf_id) struct cmdq_rsv { u16 vf_id; u8 rsv[2]; }; -/* related with hw, won't change */ +//related with hw, won't change #define CMDQ_ENTRY_SIZE 64 struct xsc_cmd_layout { @@ -681,6 +695,11 @@ struct xsc_cmd_reg { u32 interrupt_stat_addr; }; +enum xsc_cmd_status { + XSC_CMD_STATUS_NORMAL, + XSC_CMD_STATUS_TIMEDOUT, +}; + struct xsc_cmd { struct xsc_cmd_reg reg; void *cmd_buf; @@ -715,6 +734,7 @@ struct xsc_cmd { struct xsc_cmd_stats stats[XSC_CMD_OP_MAX]; unsigned int irqn; u8 ownerbit_learned; + u8 cmd_status; }; struct xsc_lock { @@ -741,33 +761,21 @@ struct xsc_core_device { struct pci_dev *pdev; struct device *device; struct xsc_priv priv; - struct xsc_port_ctrl port_ctrl; struct xsc_dev_resource *dev_res; void *xsc_ib_dev; void *netdev; void *eth_priv; void *ovs_priv; - void __iomem *bar2; + void __iomem *bar; int bar_num; - u16 bus_num; - u16 dev_num; - u16 func_id; - u16 device_id; - - u8 pf; - u8 mac_port; /* mac physic port */ - u8 pcie_port; /* pcie physic port */ + u8 mac_port; /* mac port */ + u8 pcie_no; /* pcie number */ u8 pf_id; u16 vf_id; u16 glb_func_id; /* function id */ - u16 logic_port; /* logic port for pp */ - u16 pf_logic_port; /* pf logic port */ - u16 mac_logic_port; /* mac logic port */ - u16 gsi_qpn; /* logic qpn for gsi*/ - - u16 bomt_idx; + u16 gsi_qpn; /* logic qpn for gsi*/ u16 msix_vec_base; struct mutex pci_status_mutex; /* protect pci_status */ @@ -781,7 +789,6 @@ struct xsc_core_device { atomic_t num_qps; struct xsc_cmd cmd; struct xsc_lock reg_access_lock; - u8 rdma_ready; void *counters_priv; struct xsc_priv_device priv_device; @@ -798,8 +805,15 @@ struct xsc_core_device { u32 hotfix_num; u32 feature_flag; u16 cmdq_ver; + u8 fw_version_major; + u8 fw_version_minor; + u16 fw_version_patch; + u32 fw_version_tweak; + u8 fw_version_extra_flag; cpumask_var_t xps_cpumask; + struct xsc_port_ctrl port_ctrl; + void *rtt_priv; void *ap_priv; void *pcie_lat; @@ -870,7 +884,6 @@ int xsc_create_mkey(struct xsc_core_device *xdev, void *in, void *out); int xsc_destroy_mkey(struct xsc_core_device *xdev, void *in, void *out); int xsc_reg_mr(struct xsc_core_device *dev, void *in, void *out); int xsc_dereg_mr(struct xsc_core_device *dev, void *in, void *out); -int xsc_board_reset(struct xsc_core_device *dev, int pcie_no); int xsc_eth_reset(struct xsc_core_device *dev); int xsc_tbm_init(struct xsc_core_device *dev); int xsc_qos_init(struct xsc_core_device *xdev); @@ -927,8 +940,6 @@ int xsc_create_vf_group_sysfs(struct xsc_core_device *dev, u32 group_id, struct kobject *group_kobj); void xsc_destroy_vf_group_sysfs(struct xsc_core_device *dev, struct kobject *group_kobj); -void xsc_pci_get_vf_info(struct xsc_core_device *dev, - struct xsc_vf_info *info); u32 xsc_eth_pcie_read32_by_mac_port(struct xsc_core_device *xdev, u32 mac_port, u32 eth_ip_inter_addr); void xsc_eth_pcie_write32_by_mac_port(struct xsc_core_device *xdev, u32 mac_port, @@ -936,6 +947,7 @@ void xsc_eth_pcie_write32_by_mac_port(struct xsc_core_device *xdev, u32 mac_port struct cpumask *xsc_comp_irq_get_affinity_mask(struct xsc_core_device *dev, int vector); void mask_cpu_by_node(int node, struct cpumask *dstp); int xsc_get_link_speed(struct xsc_core_device *dev); +int xsc_chip_type(struct xsc_core_device *dev); #define XSC_ESWITCH_MANAGER(dev) ((dev)->caps.eswitch_manager) @@ -1170,566 +1182,47 @@ static inline unsigned long bdf_to_key(unsigned int domain, unsigned int bus, un return ((unsigned long)domain << 32) | ((bus & 0xff) << 16) | (devfn & 0xff); } -enum xsc_port_type_encode { - XSC_PHY_PORT_MAC_0 = 0x0, - XSC_PHY_PORT_MAC_1 = 0x1, - XSC_PHY_PORT_MAC_2 = 0x2, - XSC_PHY_PORT_MAC_3 = 0x3, - XSC_PHY_PORT_MAC_4 = 0x4, - XSC_PHY_PORT_MAC_5 = 0x5, - XSC_PHY_PORT_MAC_6 = 0x6, - XSC_PHY_PORT_MAC_7 = 0x7, - XSC_PHY_PORT_PCIE_0 = 0x8, - XSC_PHY_PORT_PCIE_1 = 0x9, - - XSC_LAG_PORT_START = 15, - XSC_LAG_PORT_END = 62, - - XSC_PORT_FUNC_ID_START = 63, - XSC_PORT_FUNC_ID_END = 1214, -}; - -#define XSC_PHY_PORT_MAC_NUM 8 - -#define XSC_PHY_PORT_MAC_N(mac_id) \ - (XSC_PHY_PORT_MAC_0 + (mac_id)) -#define XSC_PHY_PORT_PCIE_N(pcie_id) \ - (XSC_PHY_PORT_PCIE_0 + (pcie_id)) -#define XSC_PHY_PORT_TO_PCIE0_PF_ID(pcie_port) \ - ((pcie_port) - XSC_PHY_PORT_PCIE_0) -#define XSC_PHY_PORT_TO_PCIE1_PF_ID(pcie_port) \ - ((pcie_port) - XSC_PHY_PORT_PCIE_1 - 1) - -#define U16_DIV2(a) ((u16)((u16)(a) >> 1)) - -#define U16_TOTAL(start, end) ((u16)(1 + (end) - (start))) - -#define U16_HALF(start, end) (U16_DIV2(U16_TOTAL(start, end))) - -/* use single unsigned integer overflow reduces instructions and branches - * notice: 'min' and 'max' cannot be a function or statement, to avoid possible side-effect - */ -#define U16_JUDGE_RANGE(min, max, x) \ - (((min) < (max)) && ((u16)((x) - (min)) <= (u16)((max) - (min)))) - -/* notice: 'min' and 'max' cannot be a function or statement, to avoid possible side-effect */ -#define U16_JUDGE_RANGE_BOTTOM_HALF(min, max, x) \ - (((min) < (max)) && \ - ((u16)((x) - (min)) <= U16_DIV2((u16)((max) - (min))))) - -/* notice: 'min' and 'max' cannot be a function or statement, to avoid possible side-effect */ -#define U16_JUDGE_RANGE_TOP_HALF(min, max, x) \ - (((min) < (max)) && \ - ((u16)((x) - U16_HALF((min), (max))) <= U16_DIV2((u16)((max) - (min))))) - -/* notice: 'b' cannot be a function or statement, to avoid possible side-effect */ -#define U16_THREE_EQUAL(a, b, c) \ - (((a) == (b)) && ((b) == (c))) - -static inline bool check_caps_funcid_valid(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return false; - - return true; -} - -/* Comment... - * accordence to xsc_core.h funcid[n] order must be: - * 0: pcie0_vf_begin - * 1: pcie0_vf_end - * 2: pcie0_pf_begin - * 3: pcie0_pf_end - * 4: pcie1_vf_begin - * 5: pcie1_vf_end - * 6: pcie1_pf_begin - * 7: pcie1_pf_end - */ -static inline u16 get_pcie0_vf_begin(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return caps->funcid[0]; -} - -static inline u16 get_pcie0_vf_end(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return caps->funcid[1]; -} - -static inline u16 get_pcie0_pf_begin(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return caps->funcid[2]; -} - -static inline u16 get_pcie0_pf_end(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return caps->funcid[3]; -} - -static inline u16 get_pcie1_vf_begin(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return caps->funcid[4]; -} - -static inline u16 get_pcie1_vf_end(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return caps->funcid[5]; -} - -static inline u16 get_pcie1_pf_begin(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return caps->funcid[6]; -} - -static inline u16 get_pcie1_pf_end(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return caps->funcid[7]; -} - -static inline u16 get_xsc_funcid_end(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return (caps->funcid[7] + 1); -} - -static inline u16 get_pcie0_vf_num(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return U16_TOTAL(caps->funcid[0], caps->funcid[1]); -} - -static inline u16 get_pcie0_pf_num(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return U16_TOTAL(caps->funcid[2], caps->funcid[3]); -} - -static inline u16 get_pcie1_vf_num(struct xsc_caps *caps) -{ - return 0;//pcie1 has no vf -} - -static inline u16 get_pcie1_pf_num(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - return U16_TOTAL(caps->funcid[6], caps->funcid[7]); -} - -static inline u16 get_pcie0_pf0_vf_num(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - if (U16_TOTAL(caps->funcid[2], caps->funcid[3]) == 1) - return U16_TOTAL(caps->funcid[0], caps->funcid[1]); - else - return U16_HALF(caps->funcid[0], caps->funcid[1]); -} - -static inline u16 get_pcie0_pf1_vf_num(struct xsc_caps *caps) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - if (U16_TOTAL(caps->funcid[2], caps->funcid[3]) == 1) - return 0; - else - return U16_HALF(caps->funcid[0], caps->funcid[1]); -} - -static inline u16 get_pcie1_pf0_vf_num(struct xsc_caps *caps) -{ - return 0; -} - -static inline u16 get_pcie1_pf1_vf_num(struct xsc_caps *caps) -{ - return 0; -} - -static inline u16 -vf_index_to_pcie0_funcid(struct xsc_caps *caps, u16 vf_index, u16 belong_pf) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - - return (belong_pf == 0) - ? (vf_index + caps->funcid[0]) - : (vf_index + U16_HALF(caps->funcid[0], caps->funcid[1])); -} - -static inline u16 -vf_index_to_pcie1_funcid(struct xsc_caps *caps, u16 vf_index, u16 belong_pf) -{ - return 0; -} - -static inline u16 -pf_index_to_pcie0_funcid(struct xsc_caps *caps, u16 pf_index) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - - return pf_index + caps->funcid[2]; -} - -static inline u16 -pf_index_to_pcie1_funcid(struct xsc_caps *caps, u16 pf_index) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - - return pf_index + caps->funcid[6]; -} - -static inline u16 -vf_index_to_pcie0_xscport(struct xsc_caps *caps, u16 vf_index, u16 belong_pf) -{ - return (belong_pf == 0) - ? (XSC_PORT_FUNC_ID_START + vf_index + caps->funcid[0]) - : (XSC_PORT_FUNC_ID_START + vf_index - + U16_HALF(caps->funcid[0], caps->funcid[1])); -} - -static inline u16 -vf_index_to_pcie1_xscport(struct xsc_caps *caps, u16 vf_index, u16 belong_pf) -{ - return 0; -} - -static inline u16 -pf_index_to_pcie0_xscport(struct xsc_caps *caps, u16 pf_index) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - //notice: not check pf_index out of range - return XSC_PORT_FUNC_ID_START + pf_index + caps->funcid[2]; -} - -static inline u16 -pf_index_to_pcie1_xscport(struct xsc_caps *caps, u16 pf_index) -{ - if (!caps || caps->funcid_valid == 0) - return 0; - //notice: not check pf_index out of range - return XSC_PORT_FUNC_ID_START + pf_index + caps->funcid[6]; -} - -static inline bool -check_is_vf(struct xsc_caps *caps, u16 func_id) -{ - if (!caps || caps->funcid_valid == 0) - return false; - - if (U16_JUDGE_RANGE(caps->funcid[0], caps->funcid[1], func_id)) - return true; - - if (U16_THREE_EQUAL(caps->funcid[0], caps->funcid[1], func_id)) - return true; - //pcie1 has no vf - - return false; -} - -static inline bool -check_is_pf(struct xsc_caps *caps, u16 func_id) -{ - if (!caps || caps->funcid_valid == 0) - return false; - - if (U16_JUDGE_RANGE(caps->funcid[2], caps->funcid[3], func_id)) - return true; - if (U16_JUDGE_RANGE(caps->funcid[6], caps->funcid[7], func_id)) - return true; - - if (U16_THREE_EQUAL(caps->funcid[2], caps->funcid[3], func_id)) - return true; - if (U16_THREE_EQUAL(caps->funcid[6], caps->funcid[7], func_id)) - return true; - - return false; -} - -static inline bool -check_is_pcie0_pf(struct xsc_caps *caps, u16 func_id) -{ - if (!caps || caps->funcid_valid == 0) - return false; - - if (U16_JUDGE_RANGE(caps->funcid[2], caps->funcid[3], func_id)) - return true; - - if (U16_THREE_EQUAL(caps->funcid[2], caps->funcid[3], func_id)) - return true; - - return false; -} - -static inline bool -check_is_pcie1_pf(struct xsc_caps *caps, u16 func_id) -{ - if (!caps || caps->funcid_valid == 0) - return false; - - if (U16_JUDGE_RANGE(caps->funcid[6], caps->funcid[7], func_id)) - return true; - - if (U16_THREE_EQUAL(caps->funcid[6], caps->funcid[7], func_id)) - return true; - - return false; -} - -static inline bool -check_is_pcie0_vf(struct xsc_caps *caps, u16 func_id) -{ - if (!caps || caps->funcid_valid == 0) - return false; - - if (U16_JUDGE_RANGE(caps->funcid[0], caps->funcid[1], func_id)) - return true; - - if (U16_THREE_EQUAL(caps->funcid[0], caps->funcid[1], func_id)) - return true; - - return false; -} - -static inline bool -check_is_pcie1_vf(struct xsc_caps *caps, u16 func_id) -{ - return false; -} - -static inline bool -check_is_pcie0_pf0_vf(struct xsc_caps *caps, u16 func_id) -{ - if (!caps || caps->funcid_valid == 0) - return false; - - if (U16_JUDGE_RANGE_BOTTOM_HALF(caps->funcid[0], caps->funcid[1], func_id)) - return true; - - if (U16_TOTAL(caps->funcid[2], caps->funcid[3]) == 1) { - if (U16_JUDGE_RANGE(caps->funcid[0], caps->funcid[1], func_id)) - return true; - } - - return false; -} - -static inline bool -check_is_pcie0_pf1_vf(struct xsc_caps *caps, u16 func_id) -{ - if (!caps || caps->funcid_valid == 0) - return false; - - if (U16_TOTAL(caps->funcid[2], caps->funcid[3]) == 2) { - if (U16_JUDGE_RANGE_TOP_HALF(caps->funcid[0], caps->funcid[1], func_id)) - return true; - } - - return false; -} - -static inline bool -pf_funcid_to_pf_index(struct xsc_caps *caps, u16 func_id, u8 *pf_id) -{ - if (!caps || caps->funcid_valid == 0 || !pf_id) - return false; - - *pf_id = 0xff; - if (U16_THREE_EQUAL(caps->funcid[2], caps->funcid[3], func_id)) { - *pf_id = 0; - return true; - } - if (U16_THREE_EQUAL(caps->funcid[6], caps->funcid[7], func_id)) { - *pf_id = 0; - return true; - } - - if (U16_JUDGE_RANGE(caps->funcid[2], caps->funcid[3], func_id)) - *pf_id = func_id - caps->funcid[2]; - else if (U16_JUDGE_RANGE(caps->funcid[6], caps->funcid[7], func_id)) - *pf_id = func_id - caps->funcid[6]; - else - return false; - - return true; -} - -static inline bool -vf_funcid_to_vf_index(struct xsc_caps *caps, u16 func_id, u16 *vf_id) +static inline void +funcid_to_pf_vf_index(struct xsc_caps *caps, u16 func_id, u8 *pf_no, u8 *pf_id, u16 *vf_id) { - if (!caps || caps->funcid_valid == 0 || !vf_id) - return false; - - *vf_id = 0xffff; - if (U16_TOTAL(caps->funcid[2], caps->funcid[3]) == 1) { - if (U16_JUDGE_RANGE(caps->funcid[0], caps->funcid[1], func_id)) { - *vf_id = func_id - caps->funcid[0]; - return true; - } - } - if (U16_JUDGE_RANGE_BOTTOM_HALF(caps->funcid[0], caps->funcid[1], func_id)) - *vf_id = func_id - caps->funcid[0]; - else if (U16_JUDGE_RANGE_TOP_HALF(caps->funcid[0], caps->funcid[1], func_id)) - *vf_id = func_id - U16_HALF(caps->funcid[0], caps->funcid[1]); - else - return false; - - return true; -} - -static inline bool -funcid_to_pf_index(struct xsc_caps *caps, u16 func_id, u8 *pf_id) -{ - if (!caps || caps->funcid_valid == 0 || !pf_id) - return false; - - *pf_id = 0xff; - if (U16_THREE_EQUAL(caps->funcid[2], caps->funcid[3], func_id)) { - *pf_id = 0; - return true; - } - if (U16_THREE_EQUAL(caps->funcid[6], caps->funcid[7], func_id)) { - *pf_id = 0; - return true; - } - - if (U16_TOTAL(caps->funcid[2], caps->funcid[3]) == 1) { - if (U16_JUDGE_RANGE(caps->funcid[0], caps->funcid[1], func_id)) { - *pf_id = 0; - return true; - } - } - if (U16_JUDGE_RANGE(caps->funcid[2], caps->funcid[3], func_id)) - *pf_id = func_id - caps->funcid[2]; - else if (U16_JUDGE_RANGE(caps->funcid[6], caps->funcid[7], func_id)) - *pf_id = func_id - caps->funcid[6]; - else if (U16_JUDGE_RANGE_BOTTOM_HALF(caps->funcid[0], caps->funcid[1], func_id)) + if (func_id >= caps->pf0_vf_funcid_base && func_id <= caps->pf0_vf_funcid_top) { *pf_id = 0; - else if (U16_JUDGE_RANGE_TOP_HALF(caps->funcid[0], caps->funcid[1], func_id)) + *pf_no = caps->pcie_host; + *vf_id = func_id - caps->pf0_vf_funcid_base; + } else if (func_id >= caps->pf1_vf_funcid_base && func_id <= caps->pf1_vf_funcid_top) { *pf_id = 1; - else - return false; - - return true; -} - -static inline bool -funcid_to_pcie_no(struct xsc_caps *caps, u16 func_id, u8 *pcie_no) -{ - if (!caps || caps->funcid_valid == 0 || !pcie_no) - return false; - - *pcie_no = 0xff; - if (U16_THREE_EQUAL(caps->funcid[2], caps->funcid[3], func_id)) { - *pcie_no = 0; - return true; - } - if (U16_THREE_EQUAL(caps->funcid[6], caps->funcid[7], func_id)) { - *pcie_no = 1; - return true; + *pf_no = caps->pcie_host; + *vf_id = func_id - caps->pf1_vf_funcid_base; + } else if (func_id >= caps->pcie0_pf_funcid_base && func_id <= caps->pcie0_pf_funcid_top) { + *pf_id = func_id - caps->pcie0_pf_funcid_base; + *pf_no = 0; + *vf_id = -1; + } else { + *pf_id = func_id - caps->pcie1_pf_funcid_base; + *pf_no = 1; + *vf_id = -1; } - if (U16_JUDGE_RANGE(caps->funcid[0], caps->funcid[1], func_id)) - *pcie_no = 0; - else if (U16_JUDGE_RANGE(caps->funcid[2], caps->funcid[3], func_id)) - *pcie_no = 0; - else if (U16_JUDGE_RANGE(caps->funcid[6], caps->funcid[7], func_id)) - *pcie_no = 1; - else - return false; - - return true; } static inline bool -funcid_to_pf_vf_index(struct xsc_caps *caps, u16 func_id, - u8 *is_pf, u8 *pf_id, u8 *pcie_no, u16 *vf_id) +is_support_rdma(struct xsc_core_device *dev) { - if (!caps || caps->funcid_valid == 0 || - !is_pf || !pf_id || !pcie_no || !vf_id) + if (!dev) return false; - *is_pf = 0xff; - *pf_id = 0xff; - *pcie_no = 0xff; - *vf_id = 0xffff; - if (U16_THREE_EQUAL(caps->funcid[2], caps->funcid[3], func_id)) { - *is_pf = 1; - *pf_id = 0; - *pcie_no = 0; - *vf_id = 0xffff; + if (dev->caps.hw_feature_flag & XSC_HW_RDMA_SUPPORT) return true; - } - if (U16_THREE_EQUAL(caps->funcid[6], caps->funcid[7], func_id)) { - *is_pf = 1; - *pf_id = 1; - *pcie_no = 1; - *vf_id = 0xffff; - return true; - } - if (U16_TOTAL(caps->funcid[2], caps->funcid[3]) == 1) { - if (U16_JUDGE_RANGE(caps->funcid[0], caps->funcid[1], func_id)) { - *is_pf = 0; - *pf_id = 0; - *pcie_no = 0; - *vf_id = func_id - caps->funcid[0]; - return true; - } - } - if (U16_JUDGE_RANGE(caps->funcid[2], caps->funcid[3], func_id)) { - *is_pf = 1; - *pf_id = func_id - caps->funcid[2]; - *pcie_no = 0; - *vf_id = 0xffff; - } else if (U16_JUDGE_RANGE(caps->funcid[6], caps->funcid[7], func_id)) { - *is_pf = 1; - *pf_id = func_id - caps->funcid[6]; - *pcie_no = 1; - *vf_id = 0xffff; - } else if (U16_JUDGE_RANGE_BOTTOM_HALF(caps->funcid[0], caps->funcid[1], func_id)) { - *is_pf = 0; - *pf_id = 0; - *vf_id = func_id - caps->funcid[0]; - *pcie_no = 0; - } else if (U16_JUDGE_RANGE_TOP_HALF(caps->funcid[0], caps->funcid[1], func_id)) { - *is_pf = 0; - *pf_id = 1; - *vf_id = func_id - U16_HALF(caps->funcid[0], caps->funcid[1]); - *pcie_no = 0; - } else { - return false; - } - return true; + return false; } static inline bool -is_support_rdma(struct xsc_core_device *dev) +is_support_pfc_prio_statistic(struct xsc_core_device *dev) { if (!dev) return false; - if (dev->caps.hw_feature_flag | XSC_HW_RDMA_SUPPORT) + if (dev->caps.hw_feature_flag & XSC_HW_PFC_PRIO_STATISTIC_SUPPORT) return true; return false; diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_hsi.h b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_hsi.h index e2569f953951..366271bf0ada 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_hsi.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_hsi.h @@ -87,6 +87,7 @@ enum { XSC_MSG_OPCODE_INIT_PATH_RSP = 14, }; +/* TODO: sw cqe opcode*/ enum { XSC_OPCODE_RDMA_REQ_SEND = 0, XSC_OPCODE_RDMA_REQ_SEND_IMMDT = 1, @@ -222,31 +223,6 @@ struct xsc_cqe { u8 owner:1; }; -struct xsc_cqe64 { - union { - u8 msg_opcode; - struct { - u8 error_code:7; - u8 is_error:1; - }; - }; - __le32 qp_id:15; - u8 rsv1:1; - u8 se:1; - u8 has_pph:1; - u8 type:1; - u8 with_immdt:1; - u8 csum_err:4; - __le32 imm_data; - __le32 msg_len; - __le32 vni; //rx hash - __le64 ts:48; - __le16 wqe_id; - __le16 rsv[3]; - __le16 rsv2:15; - u8 owner:1; -}; - /* CQ doorbell */ union xsc_cq_doorbell { struct{ @@ -376,7 +352,6 @@ union xsc_db_data { #define XSC_BROADCASTID_MAX 2 #define XSC_TBM_BOMT_DESTINFO_SHIFT (XSC_BROADCASTID_MAX / 2) -#define XSC_TBM_BOMT_BROADCASTID_MASK (XSC_BROADCASTID_MAX - 1) enum { XSC_EQ_VEC_ASYNC = 0, @@ -399,10 +374,4 @@ struct rxe_deth { __be32 sqp; }; -struct xsc_broadcast_attr { - u16 broadcast_id; - u16 bc_membernum; - u16 vf_num; -}; - #endif /* XSC_HSI_H */ diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_ioctl.h b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_ioctl.h index cb3af00b7e70..339dbdf2e4f6 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_ioctl.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_ioctl.h @@ -191,15 +191,22 @@ struct xsc_ioctl_get_phy_info_res { u32 domain; u32 bus; u32 devfn; - u32 phy_port; //local pf pcie funcid xdev->pcie_port - u32 func_id; //local pf port funcid xdev->glb_func_id ? - u32 logic_in_port; //local pf port logical_in_port xdev->logic_port - u32 mac_phy_port; // xdev->mac_port - u32 mac_logic_in_port;// xdev->logic_port + u32 pcie_no; //pcie number + u32 func_id; //pf glb func id + u32 pcie_host; //host pcie number + u32 mac_phy_port; //mac port + u32 funcid_to_logic_port_off; u16 lag_id; u16 raw_qp_id_base; u16 raw_rss_qp_id_base; - u16 funcid[8]; + u16 pf0_vf_funcid_base; + u16 pf0_vf_funcid_top; + u16 pf1_vf_funcid_base; + u16 pf1_vf_funcid_top; + u16 pcie0_pf_funcid_base; + u16 pcie0_pf_funcid_top; + u16 pcie1_pf_funcid_base; + u16 pcie1_pf_funcid_top; u16 lag_port_start; u16 raw_tpe_qp_num; int send_seg_num; @@ -209,6 +216,7 @@ struct xsc_ioctl_get_phy_info_res { u8 pct_compress_vld; u32 chip_version; u32 hca_core_clock; + u8 mac_bit; }; struct xsc_ioctl_get_vf_info_res { diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_lag.h b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_lag.h index d16051c5908d..7ac72dcb0f35 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_lag.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_lag.h @@ -8,6 +8,9 @@ #include +#define XSC_LAG_PORT_START 15 +#define XSC_LAG_NUM_MAX 0x30 + struct lag_func { struct xsc_core_device *xdev; struct net_device *netdev; @@ -22,7 +25,6 @@ struct lag_tracker { struct net_device *ndev[XSC_MAX_PORTS]; unsigned int is_hw_bonded:1; unsigned int is_kernel_bonded:1; - unsigned int is_kernel_bonded_change:1; unsigned int lag_disable:1; u8 gw_dmac0[6]; u8 gw_dmac1[6]; @@ -31,21 +33,22 @@ struct lag_tracker { /* used in tracking fib events */ struct lag_mp { struct notifier_block fib_nb; - struct fib_info *mfi; + struct fib_info *mfi; struct workqueue_struct *wq; }; struct xsc_lag { - u8 flags; - struct kref ref; - u8 v2p_map[XSC_MAX_PORTS]; - struct lag_func pf[XSC_MAX_PORTS]; - struct lag_tracker tracker; + u8 flags; + struct kref ref; + u8 v2p_map[XSC_MAX_PORTS]; + struct lag_func pf[XSC_MAX_PORTS]; + struct lag_tracker tracker; struct workqueue_struct *wq; - struct delayed_work bond_work; + struct delayed_work bond_work; struct notifier_block nb; - struct lag_mp lag_mp; - u16 lag_id; + struct lag_mp lag_mp; + u16 lag_id; + u16 lag_cnt; }; struct xsc_fib_event_work { @@ -66,7 +69,6 @@ enum { enum { XSC_BOND_FLAG_KERNEL = 1 << 3, - XSC_BOND_FLAG_LAG = 1 << 4, }; enum xsc_lag_hash { @@ -78,8 +80,8 @@ enum xsc_lag_hash { #define MAC_SHIFT 1 #define MAC_0_1_LOGIC 0 -#define MAC_0_LOGIC (XSC_PHY_PORT_MAC_0 + MAC_SHIFT) -#define MAC_1_LOGIC (XSC_PHY_PORT_MAC_1 + MAC_SHIFT) +#define MAC_0_LOGIC (0 + MAC_SHIFT) +#define MAC_1_LOGIC (1 + MAC_SHIFT) #define MAC_INVALID 0xff #define XSC_LAG_MODE_FLAGS (XSC_LAG_FLAG_ROCE | XSC_LAG_FLAG_SRIOV |\ diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/fw/xsc_tbm.h b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_pp.h similarity index 67% rename from drivers/net/ethernet/yunsilicon/xsc/pci/fw/xsc_tbm.h rename to drivers/net/ethernet/yunsilicon/xsc/common/xsc_pp.h index 818cb056c823..ae456e098d87 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/fw/xsc_tbm.h +++ b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_pp.h @@ -3,31 +3,8 @@ * All rights reserved. */ -#ifndef XSC_TBM_H -#define XSC_TBM_H - -#include "common/xsc_core.h" - -#define XSC_LAG_NUM_MAX 0x30 - -enum { - XSC_VLAN_MODE_NONE = 0, - XSC_VLAN_MODE_TRUNK, - XSC_VLAN_MODE_ACCESS, - XSC_VLAN_MODE_TUNNEL, - XSC_VLAN_MODE_NATIVE_TAGGED, - XSC_VLAN_MODE_NATIVE_UNTAGGED, -}; - -struct xsc_vlan_config { - u32 mode; - u32 pvid; - u32 proto; - u32 prio; - u32 vid_allow_base; - u32 vid_allow_num; - u32 smac_filter_en; -}; +#ifndef XSC_PP_H +#define XSC_PP_H enum { XSC_HASH_FIELD_SEL_SRC_IP = 1 << 0, @@ -58,9 +35,14 @@ enum { XSC_HASH_FIELD_SEL_DPORT_V6 |\ XSC_HASH_FIELD_SEL_PROTO) -int xsc_tbm_vlan_config(struct xsc_core_device *dev, - struct xsc_logic_port_info *info, - struct xsc_vlan_config *config); +enum { + XSC_HASH_TMPL_IDX_IP_PORTS_IP6_PORTS = 0, + XSC_HASH_TMPL_IDX_IP_IP6, + XSC_HASH_TMPL_IDX_IP_PORTS_IP6, + XSC_HASH_TMPL_IDX_IP_IP6_PORTS, + XSC_HASH_TMPL_IDX_MAX, +}; + -#endif /* XSC_TBM_H */ +#endif /* XSC_PP_H */ diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/main.c b/drivers/net/ethernet/yunsilicon/xsc/net/main.c index c4900be9abdc..f8bea4d7485d 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/main.c +++ b/drivers/net/ethernet/yunsilicon/xsc/net/main.c @@ -23,7 +23,7 @@ #include "common/xsc_cmd.h" #include "common/qp.h" #include "common/xsc_lag.h" -#include "../pci/fw/xsc_tbm.h" +#include "common/xsc_pp.h" #include "xsc_eth.h" #include "xsc_eth_txrx.h" @@ -36,6 +36,7 @@ #include "common/xsc_fs.h" #include "common/vport.h" +#include "common/qp.h" MODULE_LICENSE("GPL"); @@ -419,8 +420,7 @@ int xsc_eth_destroy_qp_rq(struct xsc_core_device *xdev, struct xsc_rq *prq) struct xsc_destroy_qp_mbox_out out; int err; - err = xsc_eth_modify_qp_status(xdev, prq->rqn, - XSC_CMD_OP_2RST_QP); + err = xsc_eth_modify_qp_status(xdev, prq->rqn, XSC_CMD_OP_2RST_QP); if (err) { xsc_core_warn(xdev, "failed to set rq%d status=rst, err=%d\n", prq->rqn, err); return err; @@ -460,8 +460,10 @@ static void xsc_free_qp_rq(struct xsc_rq *rq) kvfree(rq->wqe.frags); kvfree(rq->wqe.di); +#ifdef HAVE_PAGE_POOL_HEADER if (rq->page_pool) page_pool_destroy(rq->page_pool); +#endif xsc_eth_wq_destroy(&rq->wq_ctrl); } @@ -587,7 +589,7 @@ static int xsc_eth_alloc_cq(struct xsc_channel *c, struct xsc_cq *pcq, core_cq->vector = c->chl_idx; for (i = 0; i < xsc_cqwq_get_size(&pcq->wq); i++) { - struct xsc_cqe64 *cqe = xsc_cqwq_get_wqe(&pcq->wq, i); + struct xsc_cqe *cqe = xsc_cqwq_get_wqe(&pcq->wq, i); cqe->owner = 1; } @@ -626,8 +628,8 @@ static int xsc_eth_set_cq(struct xsc_channel *c, ret = xsc_eth_create_cq(c->adapter->xdev, &pcq->xcq, in, inlen); kfree(in); - xsc_core_info(c->adapter->xdev, "%s: create cqn%d, func_id=%d, ret=%d\n", - __func__, pcq->xcq.cqn, c->adapter->xdev->glb_func_id, ret); + xsc_core_info(c->adapter->xdev, "create cqn%d, func_id=%d, ret=%d\n", + pcq->xcq.cqn, c->adapter->xdev->glb_func_id, ret); return ret; } #else @@ -668,8 +670,8 @@ static int xsc_eth_set_cq(struct xsc_channel *c, err: kvfree(in); - xsc_core_info(c->adapter->xdev, "%s: create ch%d cqn%d, eqn=%d, func_id=%d, ret=%d\n", - __func__, c->chl_idx, pcq->xcq.cqn, eqn, xdev->glb_func_id, ret); + xsc_core_info(c->adapter->xdev, "create ch%d cqn%d, eqn=%d, func_id=%d, ret=%d\n", + c->chl_idx, pcq->xcq.cqn, eqn, xdev->glb_func_id, ret); return ret; } #endif @@ -721,30 +723,10 @@ static int xsc_eth_close_cq(struct xsc_channel *c, struct xsc_cq *pcq) static int xsc_eth_modify_qp_status(struct xsc_core_device *xdev, u32 qpn, u16 status) { - int ret = 0; - int insize; - struct xsc_modify_qp_mbox_in *in; + struct xsc_modify_qp_mbox_in in; struct xsc_modify_qp_mbox_out out; - insize = sizeof(struct xsc_modify_qp_mbox_in); - - in = kvzalloc(insize, GFP_KERNEL); - if (!in) - return -ENOMEM; - - /*eth: only set status according to cmd,ignore other fields*/ - in->hdr.opcode = cpu_to_be16(status); - in->qpn = cpu_to_be32(qpn); - - ret = xsc_cmd_exec(xdev, in, insize, &out, sizeof(out)); - if (ret || out.hdr.status) { - xsc_core_err(xdev, "failed to modify qp%d status=%d, err=%d out.status %u\n", - qpn, status, ret, out.hdr.status); - ret = -ENOEXEC; - } - - kvfree(in); - return ret; + return xsc_modify_qp(xdev, &in, &out, qpn, status); } int xsc_eth_set_hw_mtu(struct xsc_core_device *dev, u16 mtu, u16 rx_buf_sz) @@ -862,8 +844,10 @@ static int xsc_eth_alloc_rq(struct xsc_channel *c, { struct xsc_adapter *adapter = c->adapter; u8 q_log_size = prq_param->rq_attr.q_log_size; +#ifdef HAVE_PAGE_POOL_HEADER struct page_pool_params pagepool_params = { 0 }; u32 pool_size = 1 << q_log_size; +#endif u8 ele_log_size = prq_param->rq_attr.ele_log_size; struct xsc_stats *stats = c->adapter->stats; struct xsc_channel_stats *channel_stats = @@ -906,6 +890,7 @@ static int xsc_eth_alloc_rq(struct xsc_channel *c, goto err_create_pool; #endif +#ifdef HAVE_PAGE_POOL_HEADER /* Create a page_pool and register it with rxq */ pool_size = wq_sz << prq->wqe.info.log_num_frags; pagepool_params.order = XSC_RX_FRAG_SZ_ORDER; @@ -928,6 +913,7 @@ static int xsc_eth_alloc_rq(struct xsc_channel *c, pool_size, c->cpu, pagepool_params.nid, cache_init_sz, adapter->nic_param.mtu, prq_param->wq.buf_numa_node); +#endif for (i = 0; i < wq_sz; i++) { struct xsc_eth_rx_wqe_cyc *wqe = @@ -1068,8 +1054,7 @@ static int xsc_eth_open_rss_qp_rqs(struct xsc_adapter *adapter, return err; adapter->channels.rqn_base = rqn_base; - xsc_core_info(adapter->xdev, "%s: rqn_base=%d, ch_num=%d\n", - __func__, rqn_base, num_chl); + xsc_core_info(adapter->xdev, "rqn_base=%d, rq_num=%d\n", rqn_base, num_chl); return 0; err_create_rss_rqs: @@ -1133,13 +1118,13 @@ static int xsc_eth_open_qp_rq(struct xsc_channel *c, ret = create_resource_common(xdev, &prq->cqp); if (ret) { - xsc_core_err(xdev, "%s:failed to init rqn%d, err=%d\n", - __func__, prq->rqn, ret); + xsc_core_err(xdev, "failed to init rqn%d, err=%d\n", + prq->rqn, ret); goto err_destroy_rq; } - xsc_core_info(c->adapter->xdev, "%s: rqn=%d ch_num=%d\n", - __func__, prq->rqn, c->chl_idx); + xsc_core_info(c->adapter->xdev, "rqn=%d ch_num=%d\n", + prq->rqn, c->chl_idx); kvfree(in); @@ -1190,7 +1175,6 @@ static int xsc_eth_open_qp_sq(struct xsc_channel *c, int hw_npages; int inlen; int ret; - u8 pf_id; psq->stats = &channel_stats->sq[sq_idx]; psq_param->wq.db_numa_node = cpu_to_node(c->cpu); @@ -1255,13 +1239,8 @@ static int xsc_eth_open_qp_sq(struct xsc_channel *c, goto err_sq_common_destroy; } - if (funcid_to_pf_index(&xdev->caps, xdev->glb_func_id, &pf_id)) { - modify_in->req.qp_out_port = pf_id; - } else { - ret = -EINVAL; - goto err_sq_modify_in_destroy; - } - modify_in->pcie_no = g_xsc_pcie_no; + modify_in->req.qp_out_port = xdev->pf_id; + modify_in->pcie_no = xdev->pcie_no; modify_in->req.qpn = cpu_to_be16((u16)(psq->sqn)); modify_in->req.func_id = cpu_to_be16(xdev->glb_func_id); modify_in->req.dma_direct = DMA_DIR_TO_MAC; @@ -1273,8 +1252,8 @@ static int xsc_eth_open_qp_sq(struct xsc_channel *c, kvfree(modify_in); kvfree(in); - xsc_core_info(c->adapter->xdev, "%s ok, ch%d_sq%d=%d, db_numa=%d, buf_numa=%d\n", - __func__, c->chl_idx, sq_idx, psq->sqn, + xsc_core_info(c->adapter->xdev, "open sq ok, ch%d_sq%d_qpn=%d, db_numa=%d, buf_numa=%d\n", + c->chl_idx, sq_idx, psq->sqn, psq_param->wq.db_numa_node, psq_param->wq.buf_numa_node); return 0; @@ -1383,9 +1362,9 @@ int xsc_eth_open_channel(struct xsc_adapter *adapter, } } - netif_napi_add_weight(netdev, &c->napi, xsc_eth_napi_poll, XSC_CQ_POLL_BUDGET); + netif_napi_add(netdev, &c->napi, xsc_eth_napi_poll); - xsc_core_dbg(adapter->xdev, "%s ch%d ok\n", __func__, idx); + xsc_core_dbg(adapter->xdev, "open channel%d ok\n", idx); return 0; err_open_sq: @@ -1577,7 +1556,7 @@ int xsc_eth_open_channels(struct xsc_adapter *adapter) goto err_modify_qps; kvfree(chl_param); - xsc_core_info(adapter->xdev, "%s ok, ch_num=%d\n", __func__, chls->num_chl); + xsc_core_info(adapter->xdev, "open %d channels ok\n", chls->num_chl); return 0; err_modify_qps: @@ -1747,9 +1726,10 @@ static void xsc_eth_close_channels(struct xsc_adapter *adapter) int i; struct xsc_channel *c = NULL; - xsc_core_dbg(adapter->xdev, "start to close channel\n"); for (i = 0; i < adapter->channels.num_chl; i++) { c = &adapter->channels.c[i]; + xsc_core_dbg(adapter->xdev, "start to close channel%d\n", c->chl_idx); + xsc_eth_close_channel(c, true); } @@ -1757,6 +1737,13 @@ static void xsc_eth_close_channels(struct xsc_adapter *adapter) adapter->channels.num_chl = 0; } +static void xsc_eth_sw_deinit(struct xsc_adapter *adapter) +{ + xsc_eth_deactivate_priv_channels(adapter); + + return xsc_eth_close_channels(adapter); +} + static void xsc_eth_set_port_status(struct xsc_core_device *xdev, enum xsc_port_status status) { @@ -1804,7 +1791,7 @@ bool xsc_eth_get_link_status(struct xsc_adapter *adapter) } int xsc_eth_get_link_info(struct xsc_adapter *adapter, - struct xsc_event_linkinfo_resp *plinkinfo) + struct xsc_event_linkinfo *plinkinfo) { struct xsc_event_query_linkinfo_mbox_in in; struct xsc_event_query_linkinfo_mbox_out out; @@ -1832,14 +1819,34 @@ int xsc_eth_get_link_info(struct xsc_adapter *adapter, return 0; } +int xsc_eth_set_link_info(struct xsc_adapter *adapter, + struct xsc_event_linkinfo *plinkinfo) +{ + struct xsc_event_modify_linkinfo_mbox_in in; + struct xsc_event_modify_linkinfo_mbox_out out; + int err = 0; + + in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_MODIFY_LINK_INFO); + memcpy(&in.ctx, plinkinfo, sizeof(*plinkinfo)); + + err = xsc_cmd_exec(adapter->xdev, &in, sizeof(in), &out, sizeof(out)); + if (err || out.hdr.status) { + xsc_core_err(adapter->xdev, "failed to set link info, err=%d, status=%d\n", + err, out.hdr.status); + return -ENOEXEC; + } + + return err; +} + int xsc_get_link_speed(struct xsc_core_device *dev) { struct xsc_adapter *adapter = netdev_priv(dev->netdev); - struct xsc_event_linkinfo_resp linkinfo; + struct xsc_event_linkinfo linkinfo; if (xsc_eth_get_link_info(adapter, &linkinfo)) { xsc_core_err(adapter->xdev, "fail to get linkspeed, return 25G\n"); - return XSC_CMD_RESP_LINKSPEED_MODE_25G; + return MODULE_SPEED_25G; } return linkinfo.linkspeed; @@ -1923,17 +1930,6 @@ int xsc_eth_enable_nic_hca(struct xsc_adapter *adapter) int err; in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_ENABLE_NIC_HCA); - in.nic.info.pf = xdev->pf; - in.nic.info.pcie = g_xsc_pcie_no; - in.nic.info.mac_port = xdev->mac_port; - in.nic.info.pcie_port = xdev->pcie_port; - in.nic.info.pf_id = xdev->pf_id; - in.nic.info.vf_id = cpu_to_be16(xdev->vf_id); - in.nic.info.glb_func_id = cpu_to_be16(xdev->glb_func_id); - in.nic.info.logic_port = cpu_to_be16(xdev->logic_port); - in.nic.info.pf_logic_port = cpu_to_be16(xdev->pf_logic_port); - in.nic.info.mac_logic_port = cpu_to_be16(xdev->mac_logic_port); - in.nic.info.gsi_qpn = cpu_to_be16(xdev->gsi_qpn); #ifdef XSC_RSS_SUPPORT in.rss.rss_en = 1; @@ -1954,10 +1950,14 @@ int xsc_eth_enable_nic_hca(struct xsc_adapter *adapter) caps |= BIT(XSC_TBM_CAP_HASH_PPH); caps_mask |= BIT(XSC_TBM_CAP_HASH_PPH); - if (xsc_get_pp_bypass_res(adapter->xdev)) + if (xsc_get_pp_bypass_res(adapter->xdev, false)) caps |= BIT(XSC_TBM_CAP_PP_BYPASS); caps_mask |= BIT(XSC_TBM_CAP_PP_BYPASS); + if (xsc_get_pct_drop_config(xdev) && !(netdev->flags & IFF_SLAVE)) + caps |= BIT(XSC_TBM_CAP_PCT_DROP_CONFIG); + caps_mask |= BIT(XSC_TBM_CAP_PCT_DROP_CONFIG); + memcpy(in.nic.mac_addr, netdev->dev_addr, ETH_ALEN); in.nic.caps = cpu_to_be16(caps); @@ -1969,7 +1969,7 @@ int xsc_eth_enable_nic_hca(struct xsc_adapter *adapter) return -ENOEXEC; } - xsc_core_info(xdev, "rss_qp_base=%d\n", in.rss.rqn_base); + xsc_core_info(xdev, "caps=0x%x, caps_mask=0x%x\n", caps, caps_mask); return 0; } @@ -1977,26 +1977,20 @@ int xsc_eth_enable_nic_hca(struct xsc_adapter *adapter) int xsc_eth_disable_nic_hca(struct xsc_adapter *adapter) { struct xsc_core_device *xdev = adapter->xdev; + struct net_device *netdev = adapter->netdev; struct xsc_cmd_disable_nic_hca_mbox_in in = {}; struct xsc_cmd_disable_nic_hca_mbox_out out = {}; int err; u16 caps = 0; in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_DISABLE_NIC_HCA); - in.nic.info.pf = xdev->pf; - in.nic.info.pcie = g_xsc_pcie_no; - in.nic.info.mac_port = xdev->mac_port; - in.nic.info.pcie_port = xdev->pcie_port; - in.nic.info.pf_id = xdev->pf_id; - in.nic.info.vf_id = cpu_to_be16(xdev->vf_id); - in.nic.info.glb_func_id = cpu_to_be16(xdev->glb_func_id); - in.nic.info.logic_port = cpu_to_be16(xdev->logic_port); - in.nic.info.pf_logic_port = cpu_to_be16(xdev->pf_logic_port); - in.nic.info.mac_logic_port = cpu_to_be16(xdev->mac_logic_port); - - if (xsc_get_pp_bypass_res(adapter->xdev)) + + if (xsc_get_pp_bypass_res(adapter->xdev, false)) caps |= BIT(XSC_TBM_CAP_PP_BYPASS); + if (xsc_get_pct_drop_config(xdev) && !(netdev->priv_flags & IFF_BONDING)) + caps |= BIT(XSC_TBM_CAP_PCT_DROP_CONFIG); + in.nic.caps = cpu_to_be16(caps); err = xsc_cmd_exec(xdev, &in, sizeof(in), &out, sizeof(out)); if (err || out.hdr.status) { @@ -2068,16 +2062,6 @@ int xsc_eth_modify_nic_hca(struct xsc_adapter *adapter, u32 flags) int err = 0; in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_MODIFY_NIC_HCA); - in.nic.info.pf = xdev->pf; - in.nic.info.pcie = g_xsc_pcie_no; - in.nic.info.mac_port = xdev->mac_port; - in.nic.info.pcie_port = xdev->pcie_port; - in.nic.info.pf_id = xdev->pf_id; - in.nic.info.vf_id = cpu_to_be16(xdev->vf_id); - in.nic.info.glb_func_id = cpu_to_be16(xdev->glb_func_id); - in.nic.info.logic_port = cpu_to_be16(xdev->logic_port); - in.nic.info.pf_logic_port = cpu_to_be16(xdev->pf_logic_port); - in.nic.info.mac_logic_port = cpu_to_be16(xdev->mac_logic_port); xsc_eth_rss_params_change(adapter, flags, &in); @@ -2127,17 +2111,17 @@ int xsc_eth_open(struct net_device *netdev) ret = xsc_eth_reset(adapter->xdev); if (ret) - goto ret; + goto sw_deinit; ret = xsc_eth_enable_nic_hca(adapter); if (ret) - goto ret; + goto sw_deinit; #ifdef NEED_CREATE_RX_THREAD ret = xsc_eth_rx_thread_create(adapter); if (ret) { xsc_core_warn(adapter->xdev, "xsc_eth_rx_thread_create failed, err=%d\n", ret); - goto ret; + goto sw_deinit; } #endif @@ -2166,10 +2150,15 @@ int xsc_eth_open(struct net_device *netdev) xsc_set_default_xps_cpumasks(adapter, &adapter->nic_param); #endif + goto ret; + +sw_deinit: + xsc_eth_sw_deinit(adapter); + ret: mutex_unlock(&adapter->state_lock); - xsc_core_info(adapter->xdev, "%s: return %s, ret=%d\n", __func__, - ret ? "fail" : "ok", ret); + xsc_core_info(adapter->xdev, "open %s %s, ret=%d\n", + netdev->name, ret ? "failed" : "ok", ret); if (ret) return XSCALE_RET_ERROR; else @@ -2200,9 +2189,8 @@ int xsc_eth_close(struct net_device *netdev) xsc_eth_set_port_status(adapter->xdev, XSC_PORT_DOWN); netif_carrier_off(adapter->netdev); - xsc_eth_deactivate_priv_channels(adapter); - xsc_eth_close_channels(adapter); + xsc_eth_sw_deinit(adapter); ret = xsc_eth_disable_nic_hca(adapter); if (ret) @@ -2210,8 +2198,8 @@ int xsc_eth_close(struct net_device *netdev) ret: mutex_unlock(&adapter->state_lock); - xsc_core_info(adapter->xdev, "%s: return %s, ret=%d\n", __func__, - ret ? "fail" : "ok", ret); + xsc_core_info(adapter->xdev, "close device %s %s, ret=%d\n", + adapter->netdev->name, ret ? "failed" : "ok", ret); return ret; } @@ -2222,7 +2210,7 @@ static int xsc_eth_set_mac(struct net_device *netdev, void *addr) struct sockaddr *saddr = addr; struct xsc_core_device *xdev = adapter->xdev; int ret; - u16 vport = xdev->pf ? 0 : (xdev->vf_id + 1); + u16 vport = xsc_core_is_pf(xdev) ? 0 : (xdev->vf_id + 1); if (!is_valid_ether_addr(saddr->sa_data)) return -EADDRNOTAVAIL; @@ -2431,11 +2419,19 @@ static int xsc_eth_change_mtu(struct net_device *netdev, int new_mtu) int ret = 0; int max_buf_len = 0; +#ifdef HAVE_NETDEV_OPS_EXTEND + if (new_mtu > netdev->extended->max_mtu || new_mtu < netdev->extended->min_mtu) { + netdev_err(netdev, "%s: Bad MTU (%d), valid range is: [%d..%d]\n", + __func__, new_mtu, netdev->extended->min_mtu, netdev->extended->max_mtu); + return -EINVAL; + } +#else if (new_mtu > netdev->max_mtu || new_mtu < netdev->min_mtu) { netdev_err(netdev, "%s: Bad MTU (%d), valid range is: [%d..%d]\n", __func__, new_mtu, netdev->min_mtu, netdev->max_mtu); return -EINVAL; } +#endif if (!xsc_rx_is_linear_skb(new_mtu)) { max_buf_len = adapter->xdev->caps.recv_ds_num * PAGE_SIZE; @@ -2464,8 +2460,8 @@ static int xsc_eth_change_mtu(struct net_device *netdev, int new_mtu) out: mutex_unlock(&adapter->state_lock); - xsc_core_info(adapter->xdev, "%s: mtu: %d->%d, expected_mtu=%d, err=%d\n", - __func__, old_mtu, netdev->mtu, new_mtu, ret); + xsc_core_info(adapter->xdev, "mtu change from %d to %d, new_mtu=%d, err=%d\n", + old_mtu, netdev->mtu, new_mtu, ret); return ret; } @@ -2483,12 +2479,12 @@ int xsc_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) struct xsc_core_device *xdev = adapter->xdev; int ret; - if (g_xsc_pcie_no != XSC_PCIE_NO_HOST || vf >= sriov->num_vfs) + if (vf >= sriov->num_vfs) return -EINVAL; ret = xsc_eswitch_set_vport_mac(xdev->priv.eswitch, vf + 1, mac); if (ret) - xsc_core_err(xdev, "%s: xsc set mac addr failed\n", __func__); + xsc_core_err(xdev, "xsc set mac addr failed\n"); return ret; } @@ -2518,11 +2514,6 @@ int set_feature_rxcsum(struct net_device *netdev, bool enable) int err; in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_MODIFY_NIC_HCA); - in.nic.info.pcie = g_xsc_pcie_no; - in.nic.info.pf = xsc_core_is_pf(xdev) ? 1 : 0; - in.nic.info.pf_id = xdev->pf_id; - in.nic.info.vf_id = cpu_to_be16(xdev->vf_id); - in.nic.info.logic_port = cpu_to_be16(xdev->logic_port); in.nic.caps_mask = cpu_to_be16(BIT(XSC_TBM_CAP_HASH_PPH)); in.nic.caps = cpu_to_be16(enable << XSC_TBM_CAP_HASH_PPH); @@ -2578,6 +2569,52 @@ int xsc_eth_set_features(struct net_device *netdev, netdev_features_t features) return 0; } +#ifdef HAVE_NETDEVICE_OPS_SELECT_QUEUE_FALLBACK +#ifdef HAVE_NETDEV_OPS_EXTEND +u16 xsc_select_queue(struct net_device *dev, struct sk_buff *skb, + void *accel_priv, + select_queue_fallback_t fallback) +#else +u16 xsc_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev, + select_queue_fallback_t fallback) +#endif +{ +#ifdef HAVE_NETDEV_OPS_EXTEND + int txq_ix = fallback(dev, skb); +#else + int txq_ix = fallback(dev, skb, NULL); +#endif + u16 num_channels; + int up = 0; + struct xsc_adapter *adapter = netdev_priv(dev); + + if (!adapter) { + pr_err("%s adapter is null\n", __func__); + return txq_ix; + } + + if (!netdev_get_num_tc(dev)) + return txq_ix; + + if (skb_vlan_tag_present(skb)) { + up = skb->vlan_tci >> VLAN_PRIO_SHIFT; + if (adapter->nic_param.num_tc > 1) + up = up % (adapter->nic_param.num_tc - 1) + 1; + else + up = 0; + } + + /* channel_ix can be larger than num_channels since + * dev->num_real_tx_queues = num_channels * num_tc + */ + num_channels = adapter->channels.num_chl; + if (txq_ix >= num_channels) + txq_ix = adapter->txq2sq[txq_ix]->ch_ix; + + return adapter->channel_tc2realtxq[txq_ix][up]; +} +#else u16 xsc_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev) { @@ -2611,6 +2648,7 @@ u16 xsc_select_queue(struct net_device *dev, struct sk_buff *skb, return adapter->channel_tc2realtxq[txq_ix][up]; } +#endif static int xsc_get_phys_port_name(struct net_device *dev, char *buf, size_t len) @@ -2650,36 +2688,72 @@ static const struct net_device_ops xsc_netdev_ops = { .ndo_set_rx_mode = NULL, .ndo_validate_addr = NULL, .ndo_set_mac_address = xsc_eth_set_mac, +#ifdef HAVE_NETDEV_OPS_EXTEND + .extended.ndo_change_mtu = xsc_eth_change_mtu, +#else .ndo_change_mtu = xsc_eth_change_mtu, +#endif .ndo_tx_timeout = NULL, +#ifdef HAVE_NETDEV_OPS_EXTEND + .extended.ndo_set_tx_maxrate = NULL, +#else .ndo_set_tx_maxrate = NULL, +#endif .ndo_vlan_rx_add_vid = xsc_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = xsc_vlan_rx_kill_vid, .ndo_do_ioctl = NULL, .ndo_set_vf_mac = xsc_set_vf_mac, +#ifdef HAVE_NETDEV_OPS_EXTEND + .extended.ndo_set_vf_vlan = NULL, +#else .ndo_set_vf_vlan = NULL, +#endif .ndo_set_vf_rate = NULL, .ndo_set_vf_spoofchk = NULL, .ndo_set_vf_rss_query_en = NULL, +#ifdef HAVE_NETDEV_OPS_EXTEND + .extended.ndo_set_vf_trust = NULL, +#else .ndo_set_vf_trust = NULL, +#endif #ifdef NETLINK_MIN_DUMP_ALLOC_U32 .ndo_get_vf_config = xsc_get_vf_config, #endif .ndo_get_stats64 = xsc_get_stats, +#ifdef HAVE_NETDEV_OPS_EXTEND + .extended.ndo_setup_tc_rh = NULL, +#else .ndo_setup_tc = NULL, +#endif .ndo_set_features = xsc_eth_set_features, .ndo_fix_features = NULL, .ndo_fdb_add = NULL, .ndo_bridge_setlink = NULL, .ndo_bridge_getlink = NULL, +#ifdef HAVE_NETDEV_OPS_EXTEND + .extended.ndo_dfwd_add_station = NULL, + .extended.ndo_dfwd_del_station = NULL, + .extended.ndo_bpf = NULL, + .extended.ndo_xdp_xmit = NULL, + .extended.ndo_get_phys_port_name = xsc_get_phys_port_name, +#else .ndo_dfwd_add_station = NULL, .ndo_dfwd_del_station = NULL, .ndo_bpf = NULL, .ndo_xdp_xmit = NULL, .ndo_get_phys_port_name = xsc_get_phys_port_name, +#endif - .ndo_tunnel_ctl = NULL, +#ifdef HAVE_NETDEVICE_OPS_UDP_TUNNEL +#ifdef HAVE_NETDEV_OPS_EXTEND + .extended.ndo_udp_tunnel_add = NULL, + .extended.ndo_udp_tunnel_del = NULL, +#else + .ndo_udp_tunnel_add = NULL, + .ndo_udp_tunnel_del = NULL, +#endif +#endif .ndo_features_check = NULL, .ndo_select_queue = xsc_select_queue, }; @@ -2804,8 +2878,8 @@ void xsc_eth_build_nic_params(struct xsc_adapter *adapter, u32 ch_num, u32 tc_nu adapter->nic_param.sq_max_size = BIT(xdev->caps.log_max_qp_depth); xsc_build_rss_params(&adapter->rss_params, adapter->nic_param.num_channels); - xsc_core_info(xdev, "%s: mtu=%d, num_ch=%d(max=%d), num_tc=%d\n", - __func__, adapter->nic_param.mtu, + xsc_core_info(xdev, "mtu=%d, num_ch=%d(max=%d), num_tc=%d\n", + adapter->nic_param.mtu, adapter->nic_param.num_channels, adapter->nic_param.max_num_ch, adapter->nic_param.num_tc); @@ -2825,8 +2899,13 @@ void xsc_eth_build_nic_netdev(struct xsc_adapter *adapter) #endif eth_set_ethtool_ops(netdev); +#ifdef HAVE_NETDEV_OPS_EXTEND + netdev->extended->min_mtu = SW_MIN_MTU; + netdev->extended->max_mtu = SW_MAX_MTU; +#else netdev->min_mtu = SW_MIN_MTU; netdev->max_mtu = SW_MAX_MTU; +#endif /*mtu - macheaderlen - ipheaderlen should be aligned in 8B*/ netdev->mtu = SW_DEFAULT_MTU; @@ -2835,7 +2914,6 @@ void xsc_eth_build_nic_netdev(struct xsc_adapter *adapter) netdev->vlan_features |= NETIF_F_GRO; netdev->vlan_features |= NETIF_F_TSO;//NETIF_F_TSO_ECN netdev->vlan_features |= NETIF_F_TSO6; - //todo: enable rx csum netdev->vlan_features |= NETIF_F_RXCSUM; netdev->vlan_features |= NETIF_F_RXHASH; netdev->vlan_features |= NETIF_F_GSO_PARTIAL; @@ -2987,7 +3065,7 @@ static int xsc_attach_netdev(struct xsc_adapter *adapter) if (err) return err; - xsc_core_info(adapter->xdev, "%s:ok\n", __func__); + xsc_core_info(adapter->xdev, "%s ok\n", __func__); return 0; } @@ -3017,7 +3095,7 @@ static int xsc_eth_attach(struct xsc_core_device *xdev, struct xsc_adapter *adap if (err) return err; - xsc_core_info(adapter->xdev, "%s:ok\n", __func__); + xsc_core_info(adapter->xdev, "%s ok\n", __func__); return 0; } @@ -3117,10 +3195,12 @@ static void xsc_eth_remove(struct xsc_core_device *xdev, void *context) adapter = xdev->eth_priv; if (!adapter) { - xsc_core_warn(xdev, "%s: adapter is null\n", __func__); + xsc_core_warn(xdev, "failed! adapter is null\n"); return; } + xsc_core_info(adapter->xdev, "remove netdev %s entry\n", adapter->netdev->name); + xsc_eth_sysfs_remove(adapter->netdev, xdev); unregister_netdev(adapter->netdev); diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_dcbnl.c b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_dcbnl.c index d9629885321a..d61fdedf8ca6 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_dcbnl.c +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_dcbnl.c @@ -563,7 +563,6 @@ static int xsc_dcbnl_ieee_getmaxrate(struct net_device *netdev, break; } } - return 0; } @@ -920,7 +919,7 @@ static int xsc_dcbnl_getbuffer(struct net_device *dev, struct xsc_adapter *priv = netdev_priv(dev); struct xsc_core_device *xdev = priv->xdev; struct xsc_port_buffer port_buffer = {0}; - u8 buffer[XSC_MAX_PRIORITY] = {0}; + u8 buffer[XSC_MAX_PRIORITY]; int i; #ifndef XSC_DCBX_STUB int err = 0; diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth.h b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth.h index a840705abd28..9b12572f89f6 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth.h +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth.h @@ -197,7 +197,10 @@ int xsc_eth_num_channels_changed(struct xsc_adapter *priv); int xsc_eth_modify_nic_hca(struct xsc_adapter *adapter, u32 change); bool xsc_eth_get_link_status(struct xsc_adapter *adapter); int xsc_eth_get_link_info(struct xsc_adapter *adapter, - struct xsc_event_linkinfo_resp *plinkinfo); + struct xsc_event_linkinfo *plinkinfo); +int xsc_eth_set_link_info(struct xsc_adapter *adapter, + struct xsc_event_linkinfo *plinkinfo); + int xsc_eth_set_led_status(int id, struct xsc_adapter *adapter); /* Use this function to get max num channels after netdev was created */ diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_ctrl.c b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_ctrl.c index 6bff3a891bd2..6e867b7df5c4 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_ctrl.c +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_ctrl.c @@ -126,7 +126,7 @@ static int _eth_ctrl_ioctl_hwconfig(struct xsc_core_device *xdev, err = xsc_cmd_exec(xdev, in, sizeof(*in) + expect_req_size, out, sizeof(*out) + expect_resp_size); - hdr->attr.error = __be32_to_cpu(out->hdr.status); + hdr->attr.error = out->hdr.status; if (decode) decode((void *)out->data); @@ -229,7 +229,8 @@ static long _eth_ctrl_ioctl_cmdq(struct xsc_core_device *xdev, 0, sizeof(struct xsc_dpu_prio_weight_get), NULL, NULL); case XSC_CMD_OP_IOCTL_SET_HWC: return _eth_ctrl_ioctl_hwconfig(xdev, user_hdr, &hdr, - sizeof(struct hwc_set_t), 0, NULL, NULL); + sizeof(struct hwc_set_t), sizeof(struct hwc_set_t), + NULL, NULL); case XSC_CMD_OP_IOCTL_GET_HWC: return _eth_ctrl_ioctl_hwconfig(xdev, user_hdr, &hdr, sizeof(struct hwc_get_t), sizeof(struct hwc_get_t), diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_ethtool.c b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_ethtool.c index d09f0cc2aced..76eccd947bab 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_ethtool.c +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_ethtool.c @@ -10,8 +10,8 @@ #include "xsc_eth_ethtool.h" #include "xsc_eth.h" #include "common/xsc_cmd.h" +#include "common/xsc_pp.h" #include "common/port.h" -#include "../pci/fw/xsc_tbm.h" typedef int (*xsc_pflag_handler)(struct net_device *dev, bool enable); @@ -78,7 +78,7 @@ static int xsc_test_link_state(struct xsc_adapter *adapter) static int xsc_test_link_speed(struct xsc_adapter *adapter) { - struct xsc_event_linkinfo_resp linkinfo; + struct xsc_event_linkinfo linkinfo; if (xsc_eth_get_link_info(adapter, &linkinfo)) return 1; @@ -182,8 +182,8 @@ static int xsc_get_module_info(struct net_device *netdev, int size_read = 0; u8 data[4] = {0}; - size_read = xsc_query_module_eeprom(xdev, 0, 2, data); - if (size_read < 2) + size_read = xsc_query_module_eeprom(xdev, 0, 3, data); + if (size_read < 3) return -EIO; /* data[0] = identifier byte */ @@ -207,6 +207,19 @@ static int xsc_get_module_info(struct net_device *netdev, modinfo->type = ETH_MODULE_SFF_8472; modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; break; + case XSC_MODULE_ID_QSFP_DD: + case XSC_MODULE_ID_QSFP_PLUS_CMIS: + modinfo->type = ETH_MODULE_SFF_8636; + /* Verify if module EEPROM is a flat memory. In case of flat + * memory only page 00h (0-255 bytes) can be read. Otherwise + * upper pages 01h and 02h can also be read. Upper pages 10h + * and 11h are currently not supported by the driver. + */ + if (data[2] & 0x80) + modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; + else + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + break; default: netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n", __func__, data[0]); @@ -251,6 +264,49 @@ static int xsc_get_module_eeprom(struct net_device *netdev, return 0; } +static int xsc_get_module_eeprom_by_page(struct net_device *netdev, + const struct ethtool_module_eeprom *page_data, + struct netlink_ext_ack *extack) +{ + struct xsc_adapter *priv = netdev_priv(netdev); + struct xsc_core_device *xdev = priv->xdev; + struct xsc_module_eeprom_query_params query; + u8 *data = page_data->data; + int size_read; + int i = 0; + + if (!page_data->length) + return -EINVAL; + + memset(data, 0, page_data->length); + + query.offset = page_data->offset; + query.i2c_address = page_data->i2c_address; + query.bank = page_data->bank; + query.page = page_data->page; + while (i < page_data->length) { + query.size = page_data->length - i; + size_read = xsc_query_module_eeprom_by_page(xdev, &query, data + i); + + // Done reading, return how many bytes was read + if (!size_read) + return i; + + if (size_read == -EINVAL) + return -EINVAL; + if (size_read < 0) { + netdev_err(priv->netdev, "%s: xsc_query_module_eeprom_by_page failed:0x%x\n", + __func__, size_read); + return i; + } + + i += size_read; + query.offset += size_read; + } + + return i; +} + u32 xsc_get_priv_flags(struct net_device *dev) { struct xsc_adapter *priv = netdev_priv(dev); @@ -258,6 +314,33 @@ u32 xsc_get_priv_flags(struct net_device *dev) return priv->nic_param.pflags; } +static void xsc_set_drv_fw_version(struct ethtool_drvinfo *info, struct xsc_core_device *xdev) +{ + u8 fw_ver_major = xdev->fw_version_major; + u8 fw_ver_minor = xdev->fw_version_minor; + u16 fw_ver_patch = xdev->fw_version_patch; + u32 fw_ver_tweak = xdev->fw_version_tweak; + u8 fw_ver_extra_flag = xdev->fw_version_extra_flag; + + if (fw_ver_tweak == 0) { + if (fw_ver_extra_flag == 0) { + snprintf(info->fw_version, sizeof(info->fw_version), "v%u.%u.%u", + fw_ver_major, fw_ver_minor, fw_ver_patch); + } else { + snprintf(info->fw_version, sizeof(info->fw_version), "v%u.%u.%u-dirty", + fw_ver_major, fw_ver_minor, fw_ver_patch); + } + } else { + if (fw_ver_extra_flag == 0) { + snprintf(info->fw_version, sizeof(info->fw_version), "v%u.%u.%u+%u", + fw_ver_major, fw_ver_minor, fw_ver_patch, fw_ver_tweak); + } else { + snprintf(info->fw_version, sizeof(info->fw_version), "v%u.%u.%u+%u-dirty", + fw_ver_major, fw_ver_minor, fw_ver_patch, fw_ver_tweak); + } + } +} + static void xsc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct xsc_adapter *adapter = netdev_priv(dev); @@ -273,34 +356,39 @@ static void xsc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info snprintf(info->version, sizeof(info->version), "%d.%d.%d.%d.H%d", BRANCH_VERSION, MAJOR_VERSION, MINOR_VERSION, BUILD_VERSION, HOTFIX_NUM); - if (adapter->xdev->hotfix_num >= 0x27) - snprintf(info->fw_version, - sizeof(info->fw_version), - "%x.%x.%x.%s%s%s%s%s%s%s%s", - adapter->xdev->chip_ver_h, - adapter->xdev->hotfix_num, - adapter->xdev->chip_ver_l, - fpga_type_name[ff->fpga_type], - hps_ddr_name[ff->hps_ddr], - onchip_ft_name[ff->onchip_ft], - rdma_icrc_name[ff->rdma_icrc], - ma_xbar_name[ff->ma_xbar], - anlt_fec_name[ff->anlt_fec], - pp_tbl_dma_name[ff->pp_tbl_dma], - pct_exp_name[ff->pct_exp]); - else - snprintf(info->fw_version, - sizeof(info->fw_version), - "%x.%x.%x.%s%s%s%s%s%s", - adapter->xdev->chip_ver_h, - adapter->xdev->hotfix_num, - adapter->xdev->chip_ver_l, - fpga_type_name[ff->fpga_type], - hps_ddr_name[ff->hps_ddr], - onchip_ft_name[ff->onchip_ft], - rdma_icrc_name[ff->rdma_icrc], - ma_xbar_name[ff->ma_xbar], - anlt_fec_name[ff->anlt_fec]); + if (xsc_chip_type(adapter->xdev) == XSC_CHIP_MS || + xsc_chip_type(adapter->xdev) == XSC_CHIP_MV) { + xsc_set_drv_fw_version(info, adapter->xdev); + } else { + if (adapter->xdev->hotfix_num >= 0x27) + snprintf(info->fw_version, + sizeof(info->fw_version), + "%x.%x.%x.%s%s%s%s%s%s%s%s", + adapter->xdev->chip_ver_h, + adapter->xdev->hotfix_num, + adapter->xdev->chip_ver_l, + fpga_type_name[ff->fpga_type], + hps_ddr_name[ff->hps_ddr], + onchip_ft_name[ff->onchip_ft], + rdma_icrc_name[ff->rdma_icrc], + ma_xbar_name[ff->ma_xbar], + anlt_fec_name[ff->anlt_fec], + pp_tbl_dma_name[ff->pp_tbl_dma], + pct_exp_name[ff->pct_exp]); + else + snprintf(info->fw_version, + sizeof(info->fw_version), + "%x.%x.%x.%s%s%s%s%s%s", + adapter->xdev->chip_ver_h, + adapter->xdev->hotfix_num, + adapter->xdev->chip_ver_l, + fpga_type_name[ff->fpga_type], + hps_ddr_name[ff->hps_ddr], + onchip_ft_name[ff->onchip_ft], + rdma_icrc_name[ff->rdma_icrc], + ma_xbar_name[ff->ma_xbar], + anlt_fec_name[ff->anlt_fec]); + } strscpy(info->bus_info, pci_name(adapter->pdev), sizeof(info->bus_info)); } @@ -724,8 +812,8 @@ static int xsc_set_rss_hash_opt(struct xsc_adapter *priv, priv->rss_params.rx_hash_fields[tt] = rx_hash_field; } - xsc_core_info(priv->xdev, "%s: flow_type=%d, change=0x%x, hash_tmpl=0x%x\n", - __func__, nfc->flow_type, change, rx_hash_field); + xsc_core_info(priv->xdev, "flow_type=%d, change=0x%x, hash_tmpl=0x%x\n", + nfc->flow_type, change, rx_hash_field); if (change) ret = xsc_eth_modify_nic_hca(priv, change); @@ -841,7 +929,7 @@ static int xsc_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd) { struct xsc_adapter *adapter = netdev_priv(netdev); - struct xsc_event_linkinfo_resp linkinfo; + struct xsc_event_linkinfo linkinfo; if (xsc_eth_get_link_info(adapter, &linkinfo)) return -EINVAL; @@ -849,7 +937,38 @@ static int xsc_get_link_ksettings(struct net_device *netdev, cmd->base.port = linkinfo.port; cmd->base.duplex = linkinfo.duplex; cmd->base.autoneg = linkinfo.autoneg; - cmd->base.speed = linkinfo.linkspeed; + switch (linkinfo.linkspeed) { + case MODULE_SPEED_UNKNOWN: + cmd->base.speed = LINKSPEED_MODE_UNKNOWN; + break; + case MODULE_SPEED_10G: + cmd->base.speed = LINKSPEED_MODE_10G; + break; + case MODULE_SPEED_25G: + cmd->base.speed = LINKSPEED_MODE_25G; + break; + case MODULE_SPEED_40G_R4: + cmd->base.speed = LINKSPEED_MODE_40G; + break; + case MODULE_SPEED_50G_R: + case MODULE_SPEED_50G_R2: + cmd->base.speed = LINKSPEED_MODE_50G; + break; + case MODULE_SPEED_100G_R2: + case MODULE_SPEED_100G_R4: + cmd->base.speed = LINKSPEED_MODE_100G; + break; + case MODULE_SPEED_200G_R4: + case MODULE_SPEED_200G_R8: + cmd->base.speed = LINKSPEED_MODE_200G; + break; + case MODULE_SPEED_400G_R8: + cmd->base.speed = LINKSPEED_MODE_400G; + break; + default: + cmd->base.speed = LINKSPEED_MODE_25G; + break; + } ethtool_link_ksettings_zero_link_mode(cmd, supported); ethtool_link_ksettings_zero_link_mode(cmd, advertising); @@ -867,6 +986,42 @@ static int xsc_get_link_ksettings(struct net_device *netdev, return 0; } +static int xsc_set_link_ksettings(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd) +{ + struct xsc_adapter *adapter = netdev_priv(netdev); + struct xsc_event_linkinfo linkinfo; + int err = 0, i; + + if (!adapter) { + pr_err("%s fail to find adapter\n", __func__); + return -EINVAL; + } + + memset(&linkinfo, 0, sizeof(struct xsc_event_linkinfo)); + + linkinfo.port = cmd->base.port; + linkinfo.duplex = cmd->base.duplex; + linkinfo.autoneg = cmd->base.autoneg; + linkinfo.linkspeed = cpu_to_be32(cmd->base.speed); + + bitmap_copy((unsigned long *)linkinfo.supported_speed, + cmd->link_modes.supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + bitmap_copy((unsigned long *)linkinfo.advertising_speed, + cmd->link_modes.advertising, __ETHTOOL_LINK_MODE_MASK_NBITS); + + for (i = 0; i < ARRAY_SIZE(linkinfo.supported_speed); i++) { + linkinfo.supported_speed[i] = be64_to_cpu(linkinfo.supported_speed[i]); + linkinfo.advertising_speed[i] = be64_to_cpu(linkinfo.advertising_speed[i]); + } + + err = xsc_eth_set_link_info(adapter, &linkinfo); + if (err) + xsc_core_err(adapter->xdev, "fail to set link info err %d\n", err); + + return err; +} + static int xsc_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) { struct xsc_adapter *adapter = netdev_priv(dev); @@ -887,6 +1042,51 @@ static int xsc_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state st return ret; } +static int xsc_set_fecparam(struct net_device *netdev, + struct ethtool_fecparam *fec) +{ + struct xsc_adapter *adapter = netdev_priv(netdev); + struct xsc_event_modify_fecparam_mbox_in in; + struct xsc_event_modify_fecparam_mbox_out out; + u32 new_fec = fec->fec; + int err = 0; + + in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_MODIFY_FEC_PARAM); + in.fec = cpu_to_be32(new_fec); + + err = xsc_cmd_exec(adapter->xdev, &in, sizeof(in), &out, sizeof(out)); + if (err || out.hdr.status) { + xsc_core_err(adapter->xdev, "failed to set fec param, err=%d, status=%d\n", + err, out.hdr.status); + return -ENOEXEC; + } + + return err; +} + +static int xsc_get_fecparam(struct net_device *netdev, + struct ethtool_fecparam *fec) +{ + struct xsc_adapter *adapter = netdev_priv(netdev); + struct xsc_event_query_fecparam_mbox_in in; + struct xsc_event_query_fecparam_mbox_out out; + int err = 0; + + in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_QUERY_FEC_PARAM); + + err = xsc_cmd_exec(adapter->xdev, &in, sizeof(in), &out, sizeof(out)); + if (err || out.hdr.status) { + xsc_core_err(adapter->xdev, "failed to get fec param, err=%d, status=%d\n", + err, out.hdr.status); + return -ENOEXEC; + } + + fec->active_fec = be32_to_cpu(out.active_fec); + fec->fec = be32_to_cpu(out.fec_cfg); + + return err; +} + static const struct ethtool_ops xsc_ethtool_ops = { .get_drvinfo = xsc_get_drvinfo, .get_link = ethtool_op_get_link, @@ -899,7 +1099,7 @@ static const struct ethtool_ops xsc_ethtool_ops = { .get_channels = xsc_get_channels, .get_ts_info = NULL, .get_link_ksettings = xsc_get_link_ksettings, - .set_link_ksettings = NULL, + .set_link_ksettings = xsc_set_link_ksettings, .get_rxfh_key_size = xsc_get_rxfh_key_size, .get_rxfh_indir_size = xsc_get_rxfh_indir_size, .get_rxfh = xsc_get_rxfh, @@ -908,12 +1108,15 @@ static const struct ethtool_ops xsc_ethtool_ops = { .set_rxnfc = xsc_set_rxnfc, .get_module_info = xsc_get_module_info, .get_module_eeprom = xsc_get_module_eeprom, + .get_module_eeprom_by_page = xsc_get_module_eeprom_by_page, .get_priv_flags = xsc_get_priv_flags, .set_priv_flags = xsc_set_priv_flags, .get_msglevel = xsc_get_msglevel, .set_msglevel = xsc_set_msglevel, .self_test = xsc_self_test, .set_phys_id = xsc_set_phys_id, + .get_fecparam = xsc_get_fecparam, + .set_fecparam = xsc_set_fecparam, }; void eth_set_ethtool_ops(struct net_device *dev) diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_rx.c b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_rx.c index f09ae16e7333..3623801c0e68 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_rx.c +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_rx.c @@ -9,7 +9,8 @@ #include "xsc_eth_common.h" #include "xsc_eth_stats.h" #include -#include "../pci/fw/xsc_tbm.h" +#include "common/xsc_pp.h" + #define PAGE_REF_ELEV (U16_MAX) /* Upper bound on number of packets that share a single page */ @@ -37,7 +38,7 @@ static inline void xsc_rq_notify_hw(struct xsc_rq *rq) } static inline void xsc_skb_set_hash(struct xsc_adapter *adapter, - struct xsc_cqe64 *cqe, + struct xsc_cqe *cqe, struct sk_buff *skb) { struct xsc_rss_params *rss = &adapter->rss_params; @@ -173,7 +174,7 @@ static inline bool handle_udp_frag_csum(struct sk_buff *skb, struct epp_pph *pph return false; } -static inline void xsc_handle_csum(struct xsc_cqe64 *cqe, struct xsc_rq *rq, +static inline void xsc_handle_csum(struct xsc_cqe *cqe, struct xsc_rq *rq, struct sk_buff *skb, struct xsc_wqe_frag_info *wi) { struct xsc_rq_stats *stats = rq->stats; @@ -227,7 +228,7 @@ static inline void xsc_handle_csum(struct xsc_cqe64 *cqe, struct xsc_rq *rq, return; } -static inline void xsc_build_rx_skb(struct xsc_cqe64 *cqe, +static inline void xsc_build_rx_skb(struct xsc_cqe *cqe, u32 cqe_bcnt, struct xsc_rq *rq, struct sk_buff *skb, @@ -247,7 +248,7 @@ static inline void xsc_build_rx_skb(struct xsc_cqe64 *cqe, } static inline void xsc_complete_rx_cqe(struct xsc_rq *rq, - struct xsc_cqe64 *cqe, + struct xsc_cqe *cqe, u32 cqe_bcnt, struct sk_buff *skb, struct xsc_wqe_frag_info *wi) @@ -498,9 +499,18 @@ void xsc_page_release_dynamic(struct xsc_rq *rq, #endif xsc_page_dma_unmap(rq, dma_info); +#ifdef HAVE_PAGE_POOL_HEADER page_pool_recycle_direct(rq->page_pool, dma_info->page); +#else + __free_page(dma_info->page); +#endif } else { xsc_page_dma_unmap(rq, dma_info); +#ifdef HAVE_PAGE_POOL_HEADER +#ifdef HAVE_PAGE_POOL_RELEASE_PAGE + page_pool_release_page(rq->page_pool, dma_info->page); +#endif +#endif xsc_put_page(dma_info); } } @@ -527,7 +537,7 @@ static inline void xsc_free_rx_wqe(struct xsc_rq *rq, } void xsc_eth_handle_rx_cqe(struct xsc_cqwq *cqwq, - struct xsc_rq *rq, struct xsc_cqe64 *cqe) + struct xsc_rq *rq, struct xsc_cqe *cqe) { struct xsc_wq_cyc *wq = &rq->wqe.wq; struct xsc_channel *c = rq->cq.channel; @@ -575,7 +585,7 @@ void xsc_eth_handle_rx_cqe(struct xsc_cqwq *cqwq, } static void xsc_dump_error_rqcqe(struct xsc_rq *rq, - struct xsc_cqe64 *cqe) + struct xsc_cqe *cqe) { struct xsc_channel *c = rq->cq.channel; struct net_device *netdev = c->adapter->netdev; @@ -594,7 +604,7 @@ int xsc_poll_rx_cq(struct xsc_cq *cq, int budget) { struct xsc_rq *rq = container_of(cq, struct xsc_rq, cq); struct xsc_cqwq *cqwq = &cq->wq; - struct xsc_cqe64 *cqe; + struct xsc_cqe *cqe; int work_done = 0; struct xsc_ch_stats *ch_stats = cq->channel->stats; @@ -655,14 +665,22 @@ static inline int xsc_page_alloc_mapped(struct xsc_rq *rq, rq->stats->cache_alloc++; #endif +#ifdef HAVE_PAGE_POOL_HEADER dma_info->page = page_pool_dev_alloc_pages(rq->page_pool); +#else + dma_info->page = alloc_page(GFP_ATOMIC); +#endif if (unlikely(!dma_info->page)) return -ENOMEM; dma_info->addr = dma_map_page(dev, dma_info->page, 0, XSC_RX_FRAG_SZ, rq->buff.map_dir); if (unlikely(dma_mapping_error(dev, dma_info->addr))) { +#ifdef HAVE_PAGE_POOL_HEADER page_pool_recycle_direct(rq->page_pool, dma_info->page); +#else + __free_page(dma_info->page); +#endif dma_info->page = NULL; return -ENOMEM; } diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_stats.c b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_stats.c index 972540be09d6..7df1e25728df 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_stats.c +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_stats.c @@ -332,6 +332,49 @@ static const struct counter_desc hw_prio_stats_desc[] = { XSC_DECLARE_HW_PRIO_STAT(struct xsc_prio_stats, rx_bytes, 7), XSC_DECLARE_HW_PRIO_STAT(struct xsc_prio_stats, tx_pkts, 7), XSC_DECLARE_HW_PRIO_STAT(struct xsc_prio_stats, rx_pkts, 7), + +}; + +static const struct counter_desc hw_pfc_prio_stats_desc[] = { + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause, 0), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause_duration, 0), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause, 0), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause_duration, 0), + + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause, 1), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause_duration, 1), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause, 1), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause_duration, 1), + + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause, 2), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause_duration, 2), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause, 2), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause_duration, 2), + + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause, 3), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause_duration, 3), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause, 3), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause_duration, 3), + + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause, 4), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause_duration, 4), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause, 4), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause_duration, 4), + + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause, 5), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause_duration, 5), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause, 5), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause_duration, 5), + + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause, 6), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause_duration, 6), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause, 6), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause_duration, 6), + + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause, 7), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, tx_pause_duration, 7), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause, 7), + XSC_DECLARE_HW_PRIO_STAT(struct xsc_pfc_prio_stats, rx_pause_duration, 7), }; static const struct counter_desc hw_stats_desc[] = { @@ -356,7 +399,9 @@ static const struct counter_desc hw_stats_desc[] = { static int xsc_hw_get_num_stats(struct xsc_adapter *adapter) { - return ARRAY_SIZE(hw_prio_stats_desc) + ARRAY_SIZE(hw_stats_desc); + return ARRAY_SIZE(hw_prio_stats_desc) + ARRAY_SIZE(hw_stats_desc) + + (is_support_pfc_prio_statistic(adapter->xdev) ? + ARRAY_SIZE(hw_pfc_prio_stats_desc) : 0); } static int xsc_hw_fill_strings(struct xsc_adapter *adapter, u8 *data, int idx) @@ -371,6 +416,12 @@ static int xsc_hw_fill_strings(struct xsc_adapter *adapter, u8 *data, int idx) hw_prio_stats_desc[i].format, sizeof(hw_prio_stats_desc[i].format)); + if (is_support_pfc_prio_statistic(xdev)) + for (i = 0; i < ARRAY_SIZE(hw_pfc_prio_stats_desc); i++) + strscpy(data + (idx++) * ETH_GSTRING_LEN, + hw_pfc_prio_stats_desc[i].format, + sizeof(hw_pfc_prio_stats_desc[i].format)); + for (i = 0; i < ARRAY_SIZE(hw_stats_desc); i++) strscpy(data + (idx++) * ETH_GSTRING_LEN, hw_stats_desc[i].format, @@ -383,6 +434,8 @@ static int xsc_hw_fill_stats(struct xsc_adapter *adapter, u64 *data, int idx) { struct xsc_prio_stats_mbox_in in; struct xsc_prio_stats_mbox_out out; + struct xsc_pfc_prio_stats_mbox_in pfc_prio_in; + struct xsc_pfc_prio_stats_mbox_out pfc_prio_out; struct xsc_hw_stats_mbox_in hw_in; struct xsc_hw_stats_mbox_out hw_out; struct xsc_core_device *xdev; @@ -407,6 +460,25 @@ static int xsc_hw_fill_stats(struct xsc_adapter *adapter, u64 *data, int idx) } } + if (is_support_pfc_prio_statistic(xdev)) { + memset(&pfc_prio_in, 0, sizeof(pfc_prio_in)); + memset(&pfc_prio_out, 0, sizeof(pfc_prio_out)); + pfc_prio_in.hdr.opcode = __cpu_to_be16(XSC_CMD_OP_QUERY_PFC_PRIO_STATS); + pfc_prio_in.pport = xdev->mac_port; + + ret = xsc_cmd_exec(adapter->xdev, (void *)&pfc_prio_in, + sizeof(struct xsc_pfc_prio_stats_mbox_in), + (void *)&pfc_prio_out, + sizeof(struct xsc_pfc_prio_stats_mbox_out)); + if (ret == 0 && pfc_prio_out.hdr.status == 0) { + for (i = 0; i < ARRAY_SIZE(hw_pfc_prio_stats_desc); i++) { + val = XSC_READ_CTR64_CPU(&pfc_prio_out.prio_stats, + hw_pfc_prio_stats_desc, i); + data[idx++] = __be64_to_cpu(val); + } + } + } + memset(&hw_in, 0, sizeof(hw_in)); memset(&hw_out, 0, sizeof(hw_out)); hw_in.hdr.opcode = __cpu_to_be16(XSC_CMD_OP_QUERY_HW_STATS); diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_sysfs.c b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_sysfs.c index b0e714f42482..6cec78198895 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_sysfs.c +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_sysfs.c @@ -177,42 +177,7 @@ static ssize_t pcie_lat_interval_show(struct device *device, return count; } -#define PCIE_LAT_CFG_INTERVAL_FORMAT "%u,%u,%u,%u,%u,%u,%u,%u" -static ssize_t pcie_lat_interval_store(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct xsc_adapter *adapter = netdev_priv(to_net_dev(device)); - int err, i; - struct xsc_pcie_lat_feat_mbox_in in; - struct xsc_pcie_lat_feat_mbox_out out; - u32 *ptr = in.pcie_lat.pcie_lat_interval; - - memset(&in, 0, sizeof(in)); - memset(&out, 0, sizeof(out)); - - err = sscanf(buf, PCIE_LAT_CFG_INTERVAL_FORMAT, &ptr[0], &ptr[1], &ptr[2], &ptr[3], &ptr[4], - &ptr[5], &ptr[6], &ptr[7]); - if (err != XSC_PCIE_LAT_CFG_INTERVAL_MAX) - return -EINVAL; - - in.hdr.opcode = __cpu_to_be16(XSC_CMD_OP_PCIE_LAT_FEAT); - in.xsc_pcie_lat_feature_opcode = __cpu_to_be16(XSC_PCIE_LAT_FEAT_SET_INTERVAL); - for (i = 0 ; i < XSC_PCIE_LAT_CFG_INTERVAL_MAX; i++) - in.pcie_lat.pcie_lat_interval[i] = __cpu_to_be32(ptr[i]); - - err = xsc_cmd_exec(adapter->xdev, (void *)&in, sizeof(struct xsc_pcie_lat_feat_mbox_in), - (void *)&out, sizeof(struct xsc_pcie_lat_feat_mbox_out)); - if (err || out.hdr.status) { - xsc_core_err(adapter->xdev, "Failed to set pcie_lat interval, err(%u), status(%u)\n", - err, out.hdr.status); - return -EINVAL; - } - - return count; -} - -static DEVICE_ATTR_RW(pcie_lat_interval); +static DEVICE_ATTR_RO(pcie_lat_interval); static ssize_t pcie_lat_period_show(struct device *device, struct device_attribute *attr, @@ -286,14 +251,7 @@ static ssize_t pcie_lat_histogram_show(struct device *device, return count; } -static ssize_t pcie_lat_histogram_store(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return -EOPNOTSUPP; -} - -static DEVICE_ATTR_RW(pcie_lat_histogram); +static DEVICE_ATTR_RO(pcie_lat_histogram); static ssize_t pcie_lat_peak_show(struct device *device, struct device_attribute *attr, @@ -321,14 +279,7 @@ static ssize_t pcie_lat_peak_show(struct device *device, return sprintf(buf, "%u\n", __be32_to_cpu(out.pcie_lat.pcie_lat_peak)); } -static ssize_t pcie_lat_peak_store(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return -EOPNOTSUPP; -} - -static DEVICE_ATTR_RW(pcie_lat_peak); +static DEVICE_ATTR_RO(pcie_lat_peak); static struct attribute *pcie_lat_attrs[] = { &dev_attr_pcie_lat_enable.attr, diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_tx.c b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_tx.c index 63bcf1e6b674..c19701b2a696 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_tx.c +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_tx.c @@ -255,7 +255,7 @@ void xsc_txwqe_complete(struct xsc_sq *sq, struct sk_buff *skb, } static void xsc_dump_error_sqcqe(struct xsc_sq *sq, - struct xsc_cqe64 *cqe) + struct xsc_cqe *cqe) { u32 ci = xsc_cqwq_get_ci(&sq->cq.wq); struct net_device *netdev = sq->channel->netdev; @@ -315,7 +315,7 @@ bool xsc_poll_tx_cq(struct xsc_cq *cq, int napi_budget) struct device *dev; struct xsc_sq_stats *stats; struct xsc_sq *sq; - struct xsc_cqe64 *cqe; + struct xsc_cqe *cqe; u32 dma_fifo_cc; u32 nbytes = 0; u16 npkts = 0; diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_txrx.h b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_txrx.h index 1c0960b741cd..5bc9212ad26e 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_txrx.h +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_txrx.h @@ -24,18 +24,18 @@ static inline u32 xsc_cqwq_get_size(struct xsc_cqwq *wq) return wq->fbc.sz_m1 + 1; } -static inline struct xsc_cqe64 *xsc_cqwq_get_wqe(struct xsc_cqwq *wq, u32 ix) +static inline struct xsc_cqe *xsc_cqwq_get_wqe(struct xsc_cqwq *wq, u32 ix) { - struct xsc_cqe64 *cqe = xsc_frag_buf_get_wqe(&wq->fbc, ix); + struct xsc_cqe *cqe = xsc_frag_buf_get_wqe(&wq->fbc, ix); ETH_DEBUG_LOG("cqe = %p\n", cqe); return cqe; } -static inline struct xsc_cqe64 *xsc_cqwq_get_cqe(struct xsc_cqwq *wq) +static inline struct xsc_cqe *xsc_cqwq_get_cqe(struct xsc_cqwq *wq) { - struct xsc_cqe64 *cqe; + struct xsc_cqe *cqe; u8 cqe_ownership_bit; u8 sw_ownership_val; u32 ci = xsc_cqwq_get_ci(wq); @@ -61,7 +61,7 @@ int xsc_eth_napi_poll(struct napi_struct *napi, int budget); bool xsc_poll_tx_cq(struct xsc_cq *cq, int napi_budget); int xsc_poll_rx_cq(struct xsc_cq *cq, int budget); void xsc_eth_handle_rx_cqe(struct xsc_cqwq *cqwq, - struct xsc_rq *rq, struct xsc_cqe64 *cqe); + struct xsc_rq *rq, struct xsc_cqe *cqe); struct sk_buff *xsc_skb_from_cqe_linear(struct xsc_rq *rq, struct xsc_wqe_frag_info *wi, u32 cqe_bcnt, u8 has_pph); struct sk_buff *xsc_skb_from_cqe_nonlinear(struct xsc_rq *rq, diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_queue.h b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_queue.h index de8743894c32..d25a0e804732 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/net/xsc_queue.h +++ b/drivers/net/ethernet/yunsilicon/xsc/net/xsc_queue.h @@ -111,9 +111,9 @@ struct xsc_page_cache { }; struct xsc_rq; -struct xsc_cqe64; +struct xsc_cqe; typedef void (*xsc_fp_handle_rx_cqe)(struct xsc_cqwq *cqwq, struct xsc_rq *rq, - struct xsc_cqe64 *cqe64); + struct xsc_cqe *cqe); typedef bool (*xsc_fp_post_rx_wqes)(struct xsc_rq *rq); typedef void (*xsc_fp_dealloc_wqe)(struct xsc_rq *rq, u16 ix); typedef struct sk_buff * (*xsc_fp_skb_from_cqe)(struct xsc_rq *rq, @@ -242,13 +242,13 @@ struct xsc_wqe_ctrl_seg { u32 rsv : 30; }; -static inline u8 get_cqe_opcode(struct xsc_cqe64 *cqe) +static inline u8 get_cqe_opcode(struct xsc_cqe *cqe) { return cqe->msg_opcode; } static inline void xsc_dump_err_cqe(struct xsc_core_device *dev, - struct xsc_cqe64 *cqe) + struct xsc_cqe *cqe) { print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, cqe, sizeof(*cqe), false); diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/cmd2.c b/drivers/net/ethernet/yunsilicon/xsc/pci/cmd2.c index 6007319c7904..d1251e6674c0 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/cmd2.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/cmd2.c @@ -3,6 +3,9 @@ * All rights reserved. */ +#ifdef HAVE_GENERIC_KMAP_TYPE +#include +#endif #include #include #include @@ -397,6 +400,15 @@ const char *xsc_command_str(int command) case XSC_CMD_OP_QUERY_LINK_INFO: return "QUERY_LINK_INFO"; + case XSC_CMD_OP_MODIFY_LINK_INFO: + return "MODIFY_LINK_INFO"; + + case XSC_CMD_OP_MODIFY_FEC_PARAM: + return "MODIFY_FEC_PARAM"; + + case XSC_CMD_OP_QUERY_FEC_PARAM: + return "QUERY_FEC_PARAM"; + case XSC_CMD_OP_LAG_CREATE: return "LAG_CREATE"; @@ -595,6 +607,9 @@ const char *xsc_command_str(int command) case XSC_CMD_OP_USER_EMU_CMD: return "USER_EMU_CMD"; + case XSC_CMD_OP_QUERY_PFC_PRIO_STATS: + return "QUERY_PFC_PRIO_STATS"; + default: return "unknown command opcode"; } } @@ -724,6 +739,7 @@ static int wait_func(struct xsc_core_device *xdev, struct xsc_cmd_work_ent *ent) { unsigned long timeout = msecs_to_jiffies(XSC_CMD_TIMEOUT_MSEC); int err; + struct xsc_cmd *cmd = &xdev->cmd; if (!wait_for_completion_timeout(&ent->done, timeout)) err = -ETIMEDOUT; @@ -731,6 +747,7 @@ static int wait_func(struct xsc_core_device *xdev, struct xsc_cmd_work_ent *ent) err = ent->ret; if (err == -ETIMEDOUT) { + cmd->cmd_status = XSC_CMD_STATUS_TIMEDOUT; xsc_core_warn(xdev, "wait for %s(0x%x) response timeout!\n", xsc_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); @@ -1231,7 +1248,6 @@ static int create_debugfs_files(struct xsc_core_device *xdev) goto err_dbg; debugfs_create_u8("status", 0600, dbg->dbg_root, &dbg->status); - dbg->dbg_run = debugfs_create_file("run", 0200, dbg->dbg_root, xdev, &fops); if (!dbg->dbg_run) goto err_dbg; @@ -1538,6 +1554,10 @@ int _xsc_cmd_exec(struct xsc_core_device *xdev, void *in, int in_size, void *out struct xsc_rsp_msg *outb; int err; u8 status = 0; + struct xsc_cmd *cmd = &xdev->cmd; + + if (cmd->cmd_status == XSC_CMD_STATUS_TIMEDOUT) + return -ETIMEDOUT; inb = alloc_msg(xdev, in_size); if (IS_ERR(inb)) { @@ -1685,12 +1705,14 @@ static int cmd_cq_polling(void *data) continue; } + //get cqe rsp = get_cq_inst(cmd, cmd->cq_cid); if (!cmd->ownerbit_learned) { cmd->ownerbit_learned = 1; cmd->owner_bit = rsp->owner_bit; } if (cmd->owner_bit != rsp->owner_bit) { + //hw update cq doorbell but buf may not ready xsc_core_err(xdev, "hw update cq doorbell but buf not ready %u %u\n", cmd->cq_cid, cq_pid); continue; @@ -1944,6 +1966,7 @@ int xsc_cmd_init(struct xsc_core_device *xdev) (unsigned long long)(cmd->dma), (unsigned long long)(cmd->cq_dma)); cmd->mode = CMD_MODE_POLLING; + cmd->cmd_status = XSC_CMD_STATUS_NORMAL; err = create_msg_cache(xdev); if (err) { @@ -1979,7 +2002,7 @@ int xsc_cmd_init(struct xsc_core_device *xdev) goto err_req_restore; } - /* clear abnormal state to avoid the impact of previous error */ + // clear abnormal state to avoid the impact of previous error err_stat = readl(REG_ADDR(xdev, xdev->cmd.reg.interrupt_stat_addr)); if (err_stat) { xsc_core_warn(xdev, "err_stat 0x%x when initializing, clear it\n", err_stat); diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/debugfs.c b/drivers/net/ethernet/yunsilicon/xsc/pci/debugfs.c index 33409ebaf11c..a9fdbf40edb7 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/debugfs.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/debugfs.c @@ -10,7 +10,6 @@ #include "common/driver.h" #include "common/qp.h" #include "common/cq.h" -#include "fw/xsc_tbm.h" enum { QP_PID, @@ -188,137 +187,6 @@ static const struct file_operations xsc_debugfs_reg_fops = { .write = xsc_debugfs_reg_write, }; -static ssize_t xsc_debugfs_vlan_read(struct file *filp, char __user *buffer, - size_t count, loff_t *ppos) -{ - char *buf; - int len; - char xsc_debugfs_vlan_buf[256] = ""; - - /* don't allow partial reads */ - if (*ppos != 0) - return 0; - - buf = kasprintf(GFP_KERNEL, "%s: %s\n", - "vlan debugfs", xsc_debugfs_vlan_buf); - if (!buf) - return -ENOMEM; - - if (count < strlen(buf)) { - kfree(buf); - return -ENOSPC; - } - - len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); - - kfree(buf); - return len; -} - -static ssize_t xsc_debugfs_vlan_write(struct file *filp, - const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct xsc_core_device *xdev = filp->private_data; - struct xsc_vlan_config config; - char proto[16]; - int off = 0; - int len, cnt; - char xsc_debugfs_vlan_buf[256] = ""; - - /* don't allow partial writes */ - if (*ppos != 0) - return 0; - - if (count >= sizeof(xsc_debugfs_vlan_buf)) - return -ENOSPC; - - len = simple_write_to_buffer(xsc_debugfs_vlan_buf, - sizeof(xsc_debugfs_vlan_buf) - 1, - ppos, buffer, count); - if (len < 0) - return len; - - xsc_debugfs_vlan_buf[len] = '\0'; - memset(&config, 0, sizeof(config)); - /* - * trunk 100 0 4096 802.1q 0 0 - * tunnel 100 0 4096 802.1ad 1 0 - */ - if (strncmp(xsc_debugfs_vlan_buf, "trunk", 5) == 0) { - off = 5; - config.mode = XSC_VLAN_MODE_TRUNK; - } else if (strncmp(xsc_debugfs_vlan_buf, "tunnel", 6) == 0) { - off = 6; - config.mode = XSC_VLAN_MODE_TUNNEL; - } else if (strncmp(xsc_debugfs_vlan_buf, "access", 6) == 0) { - off = 6; - config.mode = XSC_VLAN_MODE_ACCESS; - } else if (strncmp(xsc_debugfs_vlan_buf, "tagged", 6) == 0) { - off = 6; - config.mode = XSC_VLAN_MODE_NATIVE_TAGGED; - } else if (strncmp(xsc_debugfs_vlan_buf, "untagged", 8) == 0) { - off = 8; - config.mode = XSC_VLAN_MODE_NATIVE_UNTAGGED; - } else if (strncmp(xsc_debugfs_vlan_buf, "none", 4) == 0) { - off = 4; - config.mode = 0; - } else { - xsc_core_err(xdev, "invalid vlan mode: %s\n", xsc_debugfs_vlan_buf); - return 0; - } - - cnt = sscanf(&xsc_debugfs_vlan_buf[off], "%u %u %u %s %u %u", - &config.pvid, &config.vid_allow_base, - &config.vid_allow_num, proto, - &config.prio, &config.smac_filter_en); - if (cnt < 3) { - xsc_core_err(xdev, "error arguments: \n"); - return 0; - } - - if (strncmp(proto, "802.1q", 6) == 0) - config.proto = ETH_P_8021Q; - else if (strncmp(proto, "802.1ad", 7) == 0) - config.proto = ETH_P_8021AD; - else - config.proto = ETH_P_8021Q; - - if (config.prio > 7) { - xsc_core_err(xdev, "invalid vlan prio: %s\n", xsc_debugfs_vlan_buf); - return 0; - } - - xsc_core_info(xdev, "%s: vlan_mode=%d vid=%d vlan_allow=%d/%d proto=0x%x prio=%d smac_en=%d", - __func__, config.mode, config.pvid, config.vid_allow_base, - config.vid_allow_num, config.proto, config.prio, - config.smac_filter_en); - - return count; -} - -static const struct file_operations xsc_debugfs_vlan_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = xsc_debugfs_vlan_read, - .write = xsc_debugfs_vlan_write, -}; - -int xsc_vlan_debugfs_init(struct xsc_core_device *dev) -{ - struct dentry *pfile; - - if (dev->dev_res->dbg_root) { - pfile = debugfs_create_file("vlan", 0644, - dev->dev_res->dbg_root, dev, - &xsc_debugfs_vlan_fops); - if (!pfile) - xsc_core_err(dev, "failed to create vlan debugfs\n"); - } - - return 0; -} - int xsc_debugfs_init(struct xsc_core_device *dev) { const char *name = pci_name(dev->pdev); @@ -339,8 +207,6 @@ int xsc_debugfs_init(struct xsc_core_device *dev) return -ENOMEM; } - xsc_vlan_debugfs_init(dev); - return 0; } @@ -608,6 +474,15 @@ static u64 eq_read_field(struct xsc_core_device *dev, struct xsc_eq *eq, goto out; } + switch (index) { + case EQ_NUM_EQES: + break; + case EQ_INTR: + break; + case EQ_LOG_PG_SZ: + break; + } + out: kfree(out); return param; @@ -633,6 +508,15 @@ static u64 cq_read_field(struct xsc_core_device *dev, struct xsc_core_cq *cq, goto out; } + switch (index) { + case CQ_PID: + break; + case CQ_NUM_CQES: + break; + case CQ_LOG_PG_SZ: + break; + } + out: kfree(out); return param; @@ -794,9 +678,9 @@ static int set_udp_sport(u32 qpn, u32 sport, struct xsc_core_device *xdev, struc msg.data.timestamp = (u64)(u32)ts.tv_sec * MSEC_PER_SEC + ts.tv_nsec / NSEC_PER_MSEC; msg.data.qpn = qpn; - msg.data.bus = xdev->bus_num; - msg.data.dev = xdev->dev_num; - msg.data.fun = xdev->func_id; + msg.data.bus = xdev->pdev->bus->number; + msg.data.dev = PCI_SLOT(xdev->pdev->devfn); + msg.data.fun = PCI_FUNC(xdev->pdev->devfn); msg.data.update.sport.port_old = t->s_port; msg.data.update.sport.port_new = __cpu_to_be16(sport); t->s_port = msg.data.update.sport.port_new; @@ -872,9 +756,6 @@ static ssize_t trace_write(struct file *filp, const char __user *buf, size_t cou } tmp_buf[len] = '\0'; - - // - // sport 10000 if (strncmp(tmp_buf, "sport", 5) == 0) { ret = kstrtouint(&tmp_buf[6], 0, &sport); if (ret != 0) { diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/devlink.c b/drivers/net/ethernet/yunsilicon/xsc/pci/devlink.c index 9477fecaf2cf..7ea5e1c78230 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/devlink.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/devlink.c @@ -5,15 +5,11 @@ #include "common/xsc_core.h" #include "devlink.h" -#ifdef CONFIG_XSC_ESWITCH #include "eswitch.h" -#endif static const struct devlink_ops xsc_devlink_ops = { -#ifdef CONFIG_XSC_ESWITCH .eswitch_mode_set = xsc_devlink_eswitch_mode_set, .eswitch_mode_get = xsc_devlink_eswitch_mode_get, -#endif }; struct devlink *xsc_devlink_alloc(struct device *dev) @@ -26,9 +22,12 @@ void xsc_devlink_free(struct devlink *devlink) devlink_free(devlink); } -void xsc_devlink_register(struct devlink *devlink) +int xsc_devlink_register(struct devlink *devlink, struct device *dev) { + int err = 0; + devlink_register(devlink); + return err; } void xsc_devlink_unregister(struct devlink *devlink) diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/devlink.h b/drivers/net/ethernet/yunsilicon/xsc/pci/devlink.h index c2bb020506cd..c08d04bfa989 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/devlink.h +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/devlink.h @@ -10,7 +10,7 @@ struct devlink *xsc_devlink_alloc(struct device *dev); void xsc_devlink_free(struct devlink *devlink); -void xsc_devlink_register(struct devlink *devlink); +int xsc_devlink_register(struct devlink *devlink, struct device *dev); void xsc_devlink_unregister(struct devlink *devlink); #endif /* XSC_DEVLINK_H */ diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/eswitch.c b/drivers/net/ethernet/yunsilicon/xsc/pci/eswitch.c index fd0758557f8d..01096d0a622f 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/eswitch.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/eswitch.c @@ -7,7 +7,6 @@ #include #include #include "common/vport.h" -#include "fw/xsc_tbm.h" #include "eswitch.h" #include "common/xsc_lag.h" @@ -101,7 +100,8 @@ int xsc_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, struct netli if (cur_xsc_mode == xsc_mode) goto done; - if ((cur_xsc_mode != XSC_ESWITCH_LEGACY && xsc_mode == XSC_ESWITCH_OFFLOADS) || + if (xsc_host_is_dpu_mode(dev) || + (cur_xsc_mode != XSC_ESWITCH_LEGACY && xsc_mode == XSC_ESWITCH_OFFLOADS) || (cur_xsc_mode == XSC_ESWITCH_OFFLOADS && xsc_mode == XSC_ESWITCH_LEGACY)) { xsc_core_err(dev, "%s failed: do not set mode %d to mode %d\n", __func__, cur_xsc_mode, xsc_mode); @@ -132,7 +132,10 @@ int xsc_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode) return err; mutex_lock(&esw->mode_lock); - err = esw_mode_to_devlink(esw->mode, mode); + if (xsc_host_is_dpu_mode(dev)) + err = -EOPNOTSUPP; + else + err = esw_mode_to_devlink(esw->mode, mode); mutex_unlock(&esw->mode_lock); return err; @@ -191,10 +194,13 @@ void xsc_eswitch_disable_vport(struct xsc_eswitch *esw, /* Mark this vport as disabled to discard new events */ vport->enabled = false; + /* Disable events from this vport */ +// arm_vport_context_events_cmd(esw->dev, vport->vport, 0); /* We don't assume VFs will cleanup after themselves. * Calling vport change handler while vport is disabled will cleanup * the vport resources. */ +// esw_vport_change_handle_locked(vport); vport->enabled_events = 0; esw->enabled_vports--; done: @@ -223,6 +229,7 @@ int esw_legacy_enable(struct xsc_eswitch *esw) { struct xsc_vport *vport; unsigned long i; + //int ret; xsc_esw_for_each_vf_vport(esw, i, vport, esw->num_vfs) { vport->info.link_state = XSC_VPORT_ADMIN_STATE_AUTO; @@ -239,10 +246,12 @@ int xsc_eswitch_enable_locked(struct xsc_eswitch *esw, int mode, int num_vfs) esw->num_vfs = num_vfs; - if (esw->mode == XSC_ESWITCH_NONE) + if (esw->mode == XSC_ESWITCH_NONE) { err = esw_legacy_enable(esw); - else + } else { + //err = esw_offloads_enable(esw); err = -EOPNOTSUPP; + } if (err) goto ret; diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/eswitch.h b/drivers/net/ethernet/yunsilicon/xsc/pci/eswitch.h index a0326058b4b7..6852ee3d74e6 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/eswitch.h +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/eswitch.h @@ -138,10 +138,31 @@ static inline u8 xsc_get_eswitch_mode(struct xsc_core_device *dev) return ESW_ALLOWED(esw) ? esw->mode : XSC_ESWITCH_NONE; } -static inline bool xsc_get_pp_bypass_res(struct xsc_core_device *dev) +static inline bool xsc_host_is_dpu_mode(struct xsc_core_device *dev) { - return (xsc_get_eswitch_mode(dev) == XSC_ESWITCH_OFFLOADS) || - (dev->device_id == XSC_MF_HOST_PF_DEV_ID); + return (dev->pdev->device == XSC_MF_HOST_PF_DEV_ID || + dev->pdev->device == XSC_MV_HOST_PF_DEV_ID); +} + +static inline bool xsc_is_host_mode(struct xsc_core_device *dev) +{ + return (dev->pdev->device == XSC_MF_HOST_PF_DEV_ID || + dev->pdev->device == XSC_MF_HOST_VF_DEV_ID || + dev->pdev->device == XSC_MV_HOST_PF_DEV_ID || + dev->pdev->device == XSC_MV_HOST_VF_DEV_ID); +} + +static inline bool xsc_get_pp_bypass_res(struct xsc_core_device *dev, bool esw_set) +{ + return esw_set || xsc_is_host_mode(dev); +} + +static inline bool xsc_get_pct_drop_config(struct xsc_core_device *dev) +{ + return (dev->pdev->device == XSC_MC_PF_DEV_ID) || + (dev->pdev->device == XSC_MF_SOC_PF_DEV_ID) || + (dev->pdev->device == XSC_MS_PF_DEV_ID) || + (dev->pdev->device == XSC_MV_SOC_PF_DEV_ID); } #endif /* ESWITCH_H */ diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/fw.c b/drivers/net/ethernet/yunsilicon/xsc/pci/fw.c index e6aa4578f792..58523b5a7975 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/fw.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/fw.c @@ -32,25 +32,15 @@ int xsc_cmd_query_psv_funcid(struct xsc_core_device *dev, goto out_out; } - /* accordence to xsc_core.h funcid[n] order must be: - * 0: pcie0_vf_begin - * 1: pcie0_vf_end - * 2: pcie0_pf_begin - * 3: pcie0_pf_end - * 4: pcie1_vf_begin - * 5: pcie1_vf_end - * 6: pcie1_pf_begin - * 7: pcie1_pf_end - */ - caps->funcid[0] = be16_to_cpu(out->hca_cap.funcid[0]);//pcie0_vf_begin - caps->funcid[1] = be16_to_cpu(out->hca_cap.funcid[1]);//pcie0_vf_end - caps->funcid[2] = be16_to_cpu(out->hca_cap.funcid[2]);//pcie0_pf_begin - caps->funcid[3] = be16_to_cpu(out->hca_cap.funcid[3]);//pcie0_pf_end - caps->funcid[4] = be16_to_cpu(out->hca_cap.funcid[4]);//pcie1_vf_begin - caps->funcid[5] = be16_to_cpu(out->hca_cap.funcid[5]);//pcie1_vf_end - caps->funcid[6] = be16_to_cpu(out->hca_cap.funcid[6]);//pcie1_pf_begin - caps->funcid[7] = be16_to_cpu(out->hca_cap.funcid[7]);//pcie1_pf_end - caps->funcid_valid = 1; + caps->pf0_vf_funcid_base = be16_to_cpu(out->hca_cap.pf0_vf_funcid_base); + caps->pf0_vf_funcid_top = be16_to_cpu(out->hca_cap.pf0_vf_funcid_top); + caps->pf1_vf_funcid_base = be16_to_cpu(out->hca_cap.pf1_vf_funcid_base); + caps->pf1_vf_funcid_top = be16_to_cpu(out->hca_cap.pf1_vf_funcid_top); + caps->pcie0_pf_funcid_base = be16_to_cpu(out->hca_cap.pcie0_pf_funcid_base); + caps->pcie0_pf_funcid_top = be16_to_cpu(out->hca_cap.pcie0_pf_funcid_top); + caps->pcie1_pf_funcid_base = be16_to_cpu(out->hca_cap.pcie1_pf_funcid_base); + caps->pcie1_pf_funcid_top = be16_to_cpu(out->hca_cap.pcie1_pf_funcid_top); + caps->pcie_host = out->hca_cap.pcie_host; out_out: kfree(out); @@ -64,6 +54,8 @@ int xsc_cmd_query_hca_cap(struct xsc_core_device *dev, { struct xsc_cmd_query_hca_cap_mbox_out *out; struct xsc_cmd_query_hca_cap_mbox_in in; + //struct xsc_query_special_ctxs_mbox_out ctx_out; + //struct xsc_query_special_ctxs_mbox_in ctx_in; int err; u16 t16; @@ -74,9 +66,8 @@ int xsc_cmd_query_hca_cap(struct xsc_core_device *dev, memset(&in, 0, sizeof(in)); in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_QUERY_HCA_CAP); in.hdr.opmod = cpu_to_be16(0x1); -#ifdef XSC_MSIX_BAR_EMUL in.cpu_num = cpu_to_be16(num_online_cpus()); -#endif + err = xsc_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out)); if (err) goto out_out; @@ -87,34 +78,24 @@ int xsc_cmd_query_hca_cap(struct xsc_core_device *dev, } dev->glb_func_id = be32_to_cpu(out->hca_cap.glb_func_id); - - /* accordence to xsc_core.h funcid[n] order must be: - * 0: pcie0_vf_begin - * 1: pcie0_vf_end - * 2: pcie0_pf_begin - * 3: pcie0_pf_end - * 4: pcie1_vf_begin - * 5: pcie1_vf_end - * 6: pcie1_pf_begin - * 7: pcie1_pf_end - */ - caps->funcid[0] = be16_to_cpu(out->hca_cap.funcid[0]);//pcie0_vf_begin - caps->funcid[1] = be16_to_cpu(out->hca_cap.funcid[1]);//pcie0_vf_end - caps->funcid[2] = be16_to_cpu(out->hca_cap.funcid[2]);//pcie0_pf_begin - caps->funcid[3] = be16_to_cpu(out->hca_cap.funcid[3]);//pcie0_pf_end - caps->funcid[4] = be16_to_cpu(out->hca_cap.funcid[4]);//pcie1_vf_begin - caps->funcid[5] = be16_to_cpu(out->hca_cap.funcid[5]);//pcie1_vf_end - caps->funcid[6] = be16_to_cpu(out->hca_cap.funcid[6]);//pcie1_pf_begin - caps->funcid[7] = be16_to_cpu(out->hca_cap.funcid[7]);//pcie1_pf_end - caps->funcid_valid = 1; + caps->pf0_vf_funcid_base = be16_to_cpu(out->hca_cap.pf0_vf_funcid_base); + caps->pf0_vf_funcid_top = be16_to_cpu(out->hca_cap.pf0_vf_funcid_top); + caps->pf1_vf_funcid_base = be16_to_cpu(out->hca_cap.pf1_vf_funcid_base); + caps->pf1_vf_funcid_top = be16_to_cpu(out->hca_cap.pf1_vf_funcid_top); + caps->pcie0_pf_funcid_base = be16_to_cpu(out->hca_cap.pcie0_pf_funcid_base); + caps->pcie0_pf_funcid_top = be16_to_cpu(out->hca_cap.pcie0_pf_funcid_top); + caps->pcie1_pf_funcid_base = be16_to_cpu(out->hca_cap.pcie1_pf_funcid_base); + caps->pcie1_pf_funcid_top = be16_to_cpu(out->hca_cap.pcie1_pf_funcid_top); + caps->funcid_to_logic_port = be16_to_cpu(out->hca_cap.funcid_to_logic_port); if (xsc_core_is_pf(dev)) { - xsc_core_dbg(dev, "pcie0_vf_range=(%4u, %4u), pcie0_pf_begin=(%4u, %4u)\n", - caps->funcid[0], caps->funcid[1], - caps->funcid[2], caps->funcid[3]); - xsc_core_dbg(dev, "pcie1_vf_range=(%4u, %4u), pcie1_pf_begin=(%4u, %4u)\n", - caps->funcid[4], caps->funcid[5], - caps->funcid[6], caps->funcid[7]); + xsc_core_dbg(dev, "pf0_vf_range(%4u, %4u), pf1_vf_range(%4u, %4u)\n", + caps->pf0_vf_funcid_base, caps->pf0_vf_funcid_top, + caps->pf1_vf_funcid_base, caps->pf1_vf_funcid_top); + xsc_core_dbg(dev, "pcie0_pf_range=(%4u, %4u), pcie1_pf_range=(%4u, %4u)\n", + caps->pcie0_pf_funcid_base, caps->pcie0_pf_funcid_top, + caps->pcie1_pf_funcid_base, caps->pcie1_pf_funcid_top); } + caps->pcie_host = out->hca_cap.pcie_host; caps->nif_port_num = out->hca_cap.nif_port_num; caps->hw_feature_flag = be32_to_cpu(out->hca_cap.hw_feature_flag); @@ -133,8 +114,8 @@ int xsc_cmd_query_hca_cap(struct xsc_core_device *dev, caps->log_max_cq = out->hca_cap.log_max_cq & 0x1f; caps->log_max_eq = out->hca_cap.log_max_eq & 0xf; caps->log_max_msix = out->hca_cap.log_max_msix & 0xf; - caps->max_num_eqs = out->hca_cap.max_num_eqs & 0xff; caps->mac_port = out->hca_cap.mac_port & 0xff; + dev->mac_port = caps->mac_port; if (caps->num_ports > XSC_MAX_FW_PORTS) { xsc_core_err(dev, "device has %d ports while the driver supports max %d ports\n", caps->num_ports, XSC_MAX_FW_PORTS); @@ -148,10 +129,8 @@ int xsc_cmd_query_hca_cap(struct xsc_core_device *dev, caps->embedded_cpu = 0; caps->ecpf_vport_exists = 0; -#ifdef CONFIG_XSC_ESWITCH caps->eswitch_manager = 1; caps->vport_group_manager = 1; -#endif caps->log_max_current_uc_list = 0; caps->log_max_current_mc_list = 0; caps->log_max_vlan_list = 8; @@ -182,10 +161,9 @@ int xsc_cmd_query_hca_cap(struct xsc_core_device *dev, #else caps->msix_enable = 0; #endif -#ifdef XSC_MSIX_BAR_EMUL + caps->msix_base = be16_to_cpu(out->hca_cap.msix_base); caps->msix_num = be16_to_cpu(out->hca_cap.msix_num); -#endif t16 = be16_to_cpu(out->hca_cap.bf_log_bf_reg_size); if (t16 & 0x8000) { @@ -203,6 +181,7 @@ int xsc_cmd_query_hca_cap(struct xsc_core_device *dev, caps->dscp = 1; caps->max_tc = out->hca_cap.max_tc; caps->log_max_qp_depth = out->hca_cap.log_max_qp_depth & 0xff; + caps->mac_bit = out->hca_cap.mac_bit; dev->chip_ver_h = be32_to_cpu(out->hca_cap.chip_ver_h); dev->chip_ver_m = be32_to_cpu(out->hca_cap.chip_ver_m); @@ -220,6 +199,11 @@ int xsc_cmd_query_hca_cap(struct xsc_core_device *dev, dev->regs.event_db = be64_to_cpu(out->hca_cap.event_db); } + dev->fw_version_major = out->hca_cap.fw_ver.fw_version_major; + dev->fw_version_minor = out->hca_cap.fw_ver.fw_version_minor; + dev->fw_version_patch = be16_to_cpu(out->hca_cap.fw_ver.fw_version_patch); + dev->fw_version_tweak = be32_to_cpu(out->hca_cap.fw_ver.fw_version_tweak); + dev->fw_version_extra_flag = out->hca_cap.fw_ver.fw_version_extra_flag; out_out: kfree(out); @@ -235,14 +219,11 @@ int xsc_cmd_enable_hca(struct xsc_core_device *dev, u16 vf_num, u16 max_msix) memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_ENABLE_HCA); - in.pf = dev->pf; - in.pcie = g_xsc_pcie_no; - in.pf_id = dev->pf_id; in.vf_num = cpu_to_be16(vf_num); in.max_msix_vec = cpu_to_be16(max_msix); in.cpu_num = cpu_to_be16(num_online_cpus()); - in.pp_bypass = xsc_get_pp_bypass_res(dev); + in.pp_bypass = xsc_get_pp_bypass_res(dev, false); in.esw_mode = xsc_get_eswitch_mode(dev); err = xsc_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); @@ -265,11 +246,8 @@ int xsc_cmd_disable_hca(struct xsc_core_device *dev, u16 vf_num) memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_DISABLE_HCA); - in.pf = dev->pf; - in.pcie = g_xsc_pcie_no; - in.pf_id = dev->pf_id; in.vf_num = cpu_to_be16(vf_num); - in.pp_bypass = xsc_get_pp_bypass_res(dev); + in.pp_bypass = xsc_get_pp_bypass_res(dev, false); in.esw_mode = xsc_get_eswitch_mode(dev); err = xsc_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); @@ -291,10 +269,7 @@ int xsc_cmd_modify_hca(struct xsc_core_device *dev) memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_MODIFY_HCA); - in.pf = dev->pf; - in.pcie = g_xsc_pcie_no; - in.pf_id = dev->pf_id; - in.pp_bypass = xsc_get_pp_bypass_res(dev); + in.pp_bypass = xsc_get_pp_bypass_res(dev, true); in.esw_mode = xsc_get_eswitch_mode(dev); err = xsc_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/main.c b/drivers/net/ethernet/yunsilicon/xsc/pci/main.c index eb5c91af282a..b9428eba6a3a 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/main.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/main.c @@ -9,12 +9,9 @@ #include "common/qp.h" #include "common/xsc_lag.h" #include "common/xsc_port_ctrl.h" -#ifdef CONFIG_XSC_ESWITCH #include "devlink.h" #include "eswitch.h" -#endif #include "fw/xsc_counters.h" -#include "fw/xsc_tbm.h" #include "xsc_pci_ctrl.h" #ifdef RUN_WITH_PSV @@ -37,8 +34,6 @@ module_param_named(probe_vf, probe_vf, bool, 0644); MODULE_PARM_DESC(probe_vf, "probe VFs or not, 0 = not probe, 1 = probe. Default = 1"); static bool xsc_hw_reset; -u8 g_xsc_pcie_no = XSC_PCIE_NO_UNSET; -EXPORT_SYMBOL(g_xsc_pcie_no); #define DRIVER_NAME "xsc_pci" #define DRIVER_VERSION "0.1.0" @@ -99,20 +94,20 @@ static u32 xsc_get_glb_func_id(struct xsc_core_device *dev) struct xsc_core_device *pf_xdev; if (xsc_core_is_pf(dev)) { - if (g_xsc_pcie_no == XSC_PCIE_NO_HOST) - return pf_index_to_pcie0_funcid(&dev->caps, phyport_num++); + if (dev->pcie_no == XSC_PCIE_NO_HOST) + return dev->caps.pcie0_pf_funcid_base + phyport_num++; else - return pf_index_to_pcie1_funcid(&dev->caps, phyport_num++); + return dev->caps.pcie1_pf_funcid_base + phyport_num++; } else { pf_xdev = pci_get_drvdata(pdev->physfn); vf_bdf = (pdev->bus->number << 8) | pdev->devfn; - if (g_xsc_pcie_no == XSC_PCIE_NO_HOST && + if (dev->pcie_no == XSC_PCIE_NO_HOST && vf_bdf >= pf_xdev->priv.sriov.vf_bdf_base) { vf_id = vf_bdf - pf_xdev->priv.sriov.vf_bdf_base; if (pf_xdev->pf_id == 0) - return vf_index_to_pcie0_funcid(&dev->caps, vf_id, 0); + return dev->caps.pf0_vf_base + vf_id; else - return vf_index_to_pcie0_funcid(&dev->caps, vf_id, 1); + return dev->caps.pf1_vf_base + vf_id; } } return 0; @@ -133,32 +128,6 @@ int xsc_cmd_exec(struct xsc_core_device *dev, void *in, int in_size, void *out, } EXPORT_SYMBOL(xsc_cmd_exec); -u8 xsc_devid_to_pcie_no(int dev_id) -{ - u8 pcie_no; - - switch (dev_id) { - case XSC_MC_PF_DEV_ID: - case XSC_MC_VF_DEV_ID: - case XSC_MF_HOST_PF_DEV_ID: - case XSC_MF_HOST_VF_DEV_ID: - case XSC_MS_PF_DEV_ID: - case XSC_MS_VF_DEV_ID: - case XSC_MV_HOST_PF_DEV_ID: - case XSC_MV_HOST_VF_DEV_ID: - pcie_no = 0; - break; - case XSC_MF_SOC_PF_DEV_ID: - case XSC_MV_SOC_PF_DEV_ID: - pcie_no = 1; - break; - default: - pcie_no = 0; - break; - } - return pcie_no; -} - static int set_dma_caps(struct pci_dev *pdev) { int err = 0; @@ -175,88 +144,6 @@ static int set_dma_caps(struct pci_dev *pdev) return err; } -static void xsc_pci_get_bdf(struct xsc_core_device *dev) -{ - struct pci_dev *pci_dev = dev->pdev; - - dev->bus_num = pci_dev->bus->number; - dev->dev_num = PCI_SLOT(pci_dev->devfn); - dev->func_id = PCI_FUNC(pci_dev->devfn); - dev->device_id = pci_dev->device; - - xsc_core_info(dev, "%s: bdf=%04x.%04x.%04x, device_id=0x%04x\n", - __func__, dev->bus_num, dev->dev_num, dev->func_id, dev->device_id); -} - -static int xsc_pci_calc_pf_port(struct xsc_core_device *dev) -{ - u8 pcie_no; - - if (!funcid_to_pf_vf_index(&dev->caps, dev->glb_func_id, - &dev->pf, &dev->pf_id, &pcie_no, &dev->vf_id)) - return -EINVAL; - - if (pcie_no == 0) { - dev->pcie_port = XSC_PHY_PORT_PCIE_N(0); - dev->logic_port = pf_index_to_pcie0_xscport(&dev->caps, dev->pf_id); - } else { - dev->pcie_port = XSC_PHY_PORT_PCIE_N(1); - dev->logic_port = pf_index_to_pcie1_xscport(&dev->caps, dev->pf_id); - } - dev->pf_logic_port = dev->logic_port; - dev->mac_port = dev->caps.mac_port; - dev->mac_logic_port = dev->mac_port; - - xsc_core_dbg(dev, - "glb_func=%d, pcie_port=%d, pf_logic_port=%d, mac_port=%d, board_id=%d\n", - dev->glb_func_id, dev->pcie_port, dev->logic_port, - dev->mac_port, dev->board_id); - - return 0; -} - -void xsc_pci_get_vf_info(struct xsc_core_device *dev, struct xsc_vf_info *info) -{ - if (!dev || !info || !check_caps_funcid_valid(&dev->caps)) - xsc_core_err(dev, "%s input err\n", __func__); - - if (info->phy_port == 0) { - info->logic_port = vf_index_to_pcie0_xscport(&dev->caps, info->vf_id, info->pf_id); - info->func_id = vf_index_to_pcie0_funcid(&dev->caps, info->vf_id, info->pf_id); - } else { - info->logic_port = vf_index_to_pcie1_xscport(&dev->caps, info->vf_id, info->pf_id); - info->func_id = vf_index_to_pcie1_funcid(&dev->caps, info->vf_id, info->pf_id); - } -} -EXPORT_SYMBOL(xsc_pci_get_vf_info); - -static int xsc_pci_calc_vf_port(struct xsc_core_device *dev) -{ - u8 pcie_no; - - if (!funcid_to_pf_vf_index(&dev->caps, dev->glb_func_id, - &dev->pf, &dev->pf_id, &pcie_no, &dev->vf_id)) - return -EINVAL; - if (unlikely(pcie_no == 1)) - return -EINVAL; - - dev->logic_port = vf_index_to_pcie0_xscport(&dev->caps, dev->vf_id, dev->pf_id); - - dev->pcie_port = XSC_PHY_PORT_PCIE_N(0); - dev->pf_logic_port = pf_index_to_pcie0_xscport(&dev->caps, dev->pf_id); - dev->mac_port = dev->caps.mac_port; - dev->mac_logic_port = dev->mac_port; - - xsc_core_dbg(dev, - "vf%d_logic_port=%d, glb_func_id=%d, pf%d_logic_port=%d\n", - dev->vf_id, dev->logic_port, dev->glb_func_id, dev->pf_id, - dev->pf_logic_port); - xsc_core_dbg(dev, "mac_logic_port=%d, board_id=%d\n", - dev->mac_logic_port, dev->board_id); - - return 0; -} - static int xsc_pci_enable_device(struct xsc_core_device *dev) { struct pci_dev *pdev = dev->pdev; @@ -369,8 +256,6 @@ int xsc_dev_init(struct xsc_core_device *dev) goto err_debugfs_init; } - xsc_init_reg_addr(dev); - return 0; err_debugfs_init: @@ -381,6 +266,7 @@ int xsc_dev_init(struct xsc_core_device *dev) void xsc_dev_cleanup(struct xsc_core_device *dev) { +// iounmap(dev->iseg); xsc_debugfs_fini(dev); xsc_dev_res_cleanup(dev); } @@ -428,9 +314,6 @@ static int xsc_pci_init(struct xsc_core_device *dev, const struct pci_device_id if (!bar_base) { xsc_core_err(dev, "failed to ioremap %s bar%d\n", name, bar_num); goto err_clr_master; - } else { - xsc_core_info(dev, "ioremap bar%d base address=0x%llx\n", bar_num, - (unsigned long long)bar_base); } err = pci_save_state(pdev); @@ -440,8 +323,7 @@ static int xsc_pci_init(struct xsc_core_device *dev, const struct pci_device_id } dev->bar_num = bar_num; - dev->bar2 = bar_base; - xsc_pci_get_bdf(dev); + dev->bar = bar_base; xsc_init_reg_addr(dev); @@ -461,16 +343,13 @@ static int xsc_pci_init(struct xsc_core_device *dev, const struct pci_device_id static void xsc_pci_fini(struct xsc_core_device *dev) { struct pci_dev *pdev = dev->pdev; - void __iomem *bar_base = NULL; #ifdef RUN_WITH_PSV xsc_stop_fw(dev); #endif - bar_base = dev->bar2; - - if (bar_base) - pci_iounmap(pdev, bar_base); + if (dev->bar) + pci_iounmap(pdev, dev->bar); pci_clear_master(pdev); pci_release_region(pdev, dev->bar_num); xsc_pci_disable_device(dev); @@ -534,13 +413,14 @@ int xsc_reset_function_resource(struct xsc_core_device *dev) static int xsc_fpga_not_supported(struct xsc_core_device *dev) { #define FPGA_VERSION_H 0x100 +#define ASIC_VERSION_H 0x20230423 u32 ver_h; if (!xsc_core_is_pf(dev)) return 0; ver_h = REG_RD32(dev, HIF_CPM_CHIP_VERSION_H_REG_ADDR); - if (ver_h != FPGA_VERSION_H) { + if (ver_h != FPGA_VERSION_H && ver_h != ASIC_VERSION_H) { xsc_core_err(dev, "fpga version 0x%x not supported\n", ver_h); return 1; } @@ -548,6 +428,29 @@ static int xsc_fpga_not_supported(struct xsc_core_device *dev) return 0; } +int xsc_chip_type(struct xsc_core_device *dev) +{ + switch (dev->pdev->device) { + case XSC_MC_PF_DEV_ID: + case XSC_MC_VF_DEV_ID: + return XSC_CHIP_MC; + case XSC_MF_HOST_PF_DEV_ID: + case XSC_MF_HOST_VF_DEV_ID: + case XSC_MF_SOC_PF_DEV_ID: + return XSC_CHIP_MF; + case XSC_MS_PF_DEV_ID: + case XSC_MS_VF_DEV_ID: + return XSC_CHIP_MS; + case XSC_MV_HOST_PF_DEV_ID: + case XSC_MV_HOST_VF_DEV_ID: + case XSC_MV_SOC_PF_DEV_ID: + return XSC_CHIP_MV; + default: + return XSC_CHIP_UNKNOWN; + } +} +EXPORT_SYMBOL(xsc_chip_type); + static int xsc_init_once(struct xsc_core_device *dev) { int err; @@ -592,23 +495,16 @@ static int xsc_init_once(struct xsc_core_device *dev) xsc_core_err(dev, "Failed to get board id, err=%d\n", err); goto err_cmdq_ver_chk; } + + funcid_to_pf_vf_index(&dev->caps, dev->glb_func_id, &dev->pcie_no, + &dev->pf_id, &dev->vf_id); if (xsc_core_is_pf(dev)) { - err = xsc_pci_calc_pf_port(dev); - if (err) { - xsc_core_err(dev, "Failed to xsc_pci_calc_pf_port\n"); - goto err_cmdq_ver_chk; - } err = xsc_create_res(dev); if (err) { xsc_core_err(dev, "Failed to create resource, err=%d\n", err); goto err_cmdq_ver_chk; } } else { - err = xsc_pci_calc_vf_port(dev); - if (err) { - xsc_core_err(dev, "Failed to xsc_pci_calc_vf_port\n"); - goto err_cmdq_ver_chk; - } if (!dev->pdev->physfn) { err = xsc_create_res(dev); if (err) { @@ -628,21 +524,17 @@ static int xsc_init_once(struct xsc_core_device *dev) xsc_core_err(dev, "Failed to init sriov %d\n", err); goto err_sriov_init; } -#ifdef CONFIG_XSC_ESWITCH err = xsc_eswitch_init(dev); if (err) { xsc_core_err(dev, "Failed to init eswitch %d\n", err); goto err_eswitch_init; } -#endif #endif return 0; #ifdef CONFIG_XSC_SRIOV -#ifdef CONFIG_XSC_ESWITCH err_eswitch_init: xsc_sriov_cleanup(dev); -#endif err_sriov_init: xsc_eq_cleanup(dev); xsc_cleanup_qp_table(dev); @@ -745,12 +637,15 @@ int xsc_load_one(struct xsc_core_device *dev, bool boot) goto err_load; } - if (boot) + if (boot) { #ifdef CONFIG_XSC_ESWITCH - xsc_devlink_register(priv_to_devlink(dev)); + err = xsc_devlink_register(priv_to_devlink(dev), dev->device); + if (err) + goto err_devlink_reg; #endif + } - if (dev->pf && dev->pf_id < 2) + if (xsc_core_is_pf(dev) && dev->pf_id < 2) xsc_lag_add_xdev(dev); if (xsc_device_registered(dev)) { @@ -781,6 +676,7 @@ int xsc_load_one(struct xsc_core_device *dev, bool boot) #ifdef CONFIG_XSC_ESWITCH if (boot) xsc_devlink_unregister(priv_to_devlink(dev)); +err_devlink_reg: #endif xsc_unload(dev); @@ -833,7 +729,6 @@ static int xsc_pci_probe(struct pci_dev *pci_dev, int err; #ifdef CONFIG_XSC_ESWITCH struct devlink *devlink; - devlink = xsc_devlink_alloc(&pci_dev->dev); if (!devlink) { dev_err(&pci_dev->dev, "devlink alloc failed\n"); @@ -849,13 +744,11 @@ static int xsc_pci_probe(struct pci_dev *pci_dev, xdev->pdev = pci_dev; xdev->device = &pci_dev->dev; - if (g_xsc_pcie_no == XSC_PCIE_NO_UNSET) - g_xsc_pcie_no = xsc_devid_to_pcie_no(pci_dev->device); priv = &xdev->priv; xdev->coredev_type = (IS_VIRT_FUNCTION(id)) ? XSC_COREDEV_VF : XSC_COREDEV_PF; - xsc_core_info(xdev, "%s: dev_type=%d is_vf=%d\n", - __func__, xdev->coredev_type, pci_dev->is_virtfn); + xsc_core_info(xdev, "dev_type=%d is_vf=%d\n", + xdev->coredev_type, pci_dev->is_virtfn); #ifdef CONFIG_XSC_SRIOV priv->sriov.probe_vf = probe_vf; diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/pci_irq.c b/drivers/net/ethernet/yunsilicon/xsc/pci/pci_irq.c index ed3a459a8498..206e76f69d3c 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/pci_irq.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/pci_irq.c @@ -515,7 +515,6 @@ xsc_comp_irq_get_affinity_mask(struct xsc_core_device *dev, int vector) } EXPORT_SYMBOL(xsc_comp_irq_get_affinity_mask); -#ifdef XSC_MSIX_BAR_EMUL static int xsc_alloc_irq_vectors(struct xsc_core_device *dev) { struct xsc_dev_resource *dev_res = dev->dev_res; @@ -547,57 +546,12 @@ static int xsc_alloc_irq_vectors(struct xsc_core_device *dev) table->eq_vec_comp_base = nvec_base; table->num_comp_vectors = nvec - nvec_base; +#ifdef XSC_MSIX_BAR_EMUL dev->msix_vec_base = dev->caps.msix_base; +#endif xsc_core_info(dev, - "alloc msix_vec_num=%d, vec_base_num=%d, max_msix_num=%d, msix_vec_base=%d\n", - nvec, nvec_base, dev->caps.msix_num, dev->msix_vec_base); - - return 0; - -err_free_irq_info: - pci_free_irq_vectors(dev->pdev); - kfree(dev_res->irq_info); - return err; -} - -#else - -static int xsc_alloc_irq_vectors(struct xsc_core_device *dev) -{ - struct xsc_dev_resource *dev_res = dev->dev_res; - struct xsc_eq_table *table = &dev_res->eq_table; - int num_eqs = (dev->caps.max_num_eqs ? - dev->caps.max_num_eqs : 1 << dev->caps.log_max_eq); - int nvec, nvec_base; - int err; - - if (xsc_core_is_pf(dev)) - nvec_base = XSC_EQ_VEC_COMP_BASE; - else - /*VF device not need dma read done vector.*/ - nvec_base = (XSC_EQ_VEC_COMP_BASE - 1); - nvec = XSC_MAX_PORTS * num_online_cpus() + nvec_base; - - nvec = min_t(int, nvec, (num_eqs + nvec_base)); - if (nvec <= nvec_base) { - xsc_core_warn(dev, "failed to alloc irq vector(%d)\n", nvec); - return -ENOMEM; - } - - dev_res->irq_info = kcalloc(nvec, sizeof(*dev_res->irq_info), GFP_KERNEL); - if (!dev_res->irq_info) - return -ENOMEM; - - nvec = pci_alloc_irq_vectors(dev->pdev, nvec_base + 1, nvec, PCI_IRQ_MSIX); - if (nvec < 0) { - err = nvec; - goto err_free_irq_info; - } - - table->eq_vec_comp_base = nvec_base; - table->num_comp_vectors = nvec - nvec_base; - xsc_core_info(dev, "alloc irq vector=%d, vec_base=%d, max_eq_nums=%d, log_max_eq=%d\n", - nvec, nvec_base, dev->caps.max_num_eqs, dev->caps.log_max_eq); + "alloc msix_vec_num=%d, comp_num=%d, max_msix_num=%d, msix_vec_base=%d\n", + nvec, table->num_comp_vectors, dev->caps.msix_num, dev->msix_vec_base); return 0; @@ -607,8 +561,6 @@ static int xsc_alloc_irq_vectors(struct xsc_core_device *dev) return err; } -#endif - static void xsc_free_irq_vectors(struct xsc_core_device *dev) { struct xsc_dev_resource *dev_res = dev->dev_res; diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/port.c b/drivers/net/ethernet/yunsilicon/xsc/pci/port.c index 5689d5c23663..448264d58853 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/port.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/port.c @@ -211,6 +211,8 @@ int xsc_query_module_eeprom(struct xsc_core_device *dev, case XSC_MODULE_ID_QSFP: case XSC_MODULE_ID_QSFP_PLUS: case XSC_MODULE_ID_QSFP28: + case XSC_MODULE_ID_QSFP_DD: + case XSC_MODULE_ID_QSFP_PLUS_CMIS: xsc_qsfp_eeprom_params_set(&query.i2c_address, &query.page, &offset); break; default: @@ -228,3 +230,47 @@ int xsc_query_module_eeprom(struct xsc_core_device *dev, return xsc_query_mcia(dev, &query, data); } EXPORT_SYMBOL_GPL(xsc_query_module_eeprom); + +int xsc_query_module_eeprom_by_page(struct xsc_core_device *dev, + struct xsc_module_eeprom_query_params *params, + u8 *data) +{ + u8 module_id; + int err; + + err = xsc_query_module_num(dev, ¶ms->module_number); + if (err) + return err; + + err = xsc_query_module_id(dev, params->module_number, &module_id); + if (err) + return err; + + switch (module_id) { + case XSC_MODULE_ID_SFP: + if (params->page > 0) + return -EINVAL; + break; + case XSC_MODULE_ID_QSFP: + case XSC_MODULE_ID_QSFP28: + case XSC_MODULE_ID_QSFP_PLUS: + if (params->page > 3) + return -EINVAL; + break; + case XSC_MODULE_ID_DSFP: + break; + default: + xsc_core_err(dev, "Module ID not recognized: 0x%x\n", module_id); + return -EINVAL; + } + + if (params->i2c_address != XSC_I2C_ADDR_HIGH && + params->i2c_address != XSC_I2C_ADDR_LOW) { + xsc_core_err(dev, "I2C address not recognized: 0x%x\n", params->i2c_address); + return -EINVAL; + } + + return xsc_query_mcia(dev, params, data); +} +EXPORT_SYMBOL_GPL(xsc_query_module_eeprom_by_page); + diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/qp.c b/drivers/net/ethernet/yunsilicon/xsc/pci/qp.c index 42788be7ae90..0c7be963c0cd 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/qp.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/qp.c @@ -22,12 +22,6 @@ enum { GROUP_MODE_PER_DEST_IP, }; -struct xsc_qp_rsc { - struct list_head node; - struct xsc_core_qp *qp; - struct xsc_core_device *xdev; -}; - struct { struct list_head head; spinlock_t lock; /* protect delayed_release_list */ @@ -53,12 +47,11 @@ static bool xsc_qp_flush_finished(struct xsc_core_device *xdev, u32 qpn) in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_QUERY_QP_FLUSH_STATUS); in.qpn = cpu_to_be32(qpn); err = xsc_cmd_exec(xdev, &in, sizeof(in), &out, sizeof(out)); - if (err || out.hdr.status != 0) { - xsc_core_dbg(xdev, "qp[%d] flush incomplete.\n", qpn); - return false; - } + if ((!err && !out.hdr.status) || err == -ETIMEDOUT) + return true; - return true; + xsc_core_dbg(xdev, "qp[%d] flush incomplete.\n", qpn); + return false; } static int xsc_qp_flush_check(void *arg) @@ -84,13 +77,12 @@ static int xsc_qp_flush_check(void *arg) list_del(&entry->node); spin_unlock(&delayed_release_list.lock); - if (!xsc_qp_flush_finished(entry->xdev, entry->qp->qpn)) { + if (!xsc_qp_flush_finished(entry->xdev, entry->qpn)) { spin_lock(&delayed_release_list.lock); list_add_tail(&entry->node, &delayed_release_list.head); spin_unlock(&delayed_release_list.lock); } else { - complete(&entry->qp->delayed_release); - kfree(entry); + complete(&entry->delayed_release); } } @@ -116,20 +108,24 @@ void xsc_stop_delayed_release(void) kthread_stop(delayed_release_list.poll_task); } -void xsc_add_to_delayed_release_list(struct xsc_core_device *xdev, struct xsc_core_qp *qp) +static void xsc_wait_qp_flush_complete(struct xsc_core_device *xdev, u32 qpn) { - struct xsc_qp_rsc *qp_rsc; + struct xsc_qp_rsc qp_rsc; + int err = 0; - qp_rsc = kzalloc(sizeof(*qp_rsc), GFP_KERNEL); - if (!qp_rsc) - return; - qp_rsc->qp = qp; - qp_rsc->xdev = xdev; + init_completion(&qp_rsc.delayed_release); + qp_rsc.qpn = qpn; + qp_rsc.xdev = xdev; spin_lock(&delayed_release_list.lock); - list_add_tail(&qp_rsc->node, &delayed_release_list.head); + list_add_tail(&qp_rsc.node, &delayed_release_list.head); spin_unlock(&delayed_release_list.lock); delayed_release_list.wait_flag = WAKEUP; wake_up(&delayed_release_list.wq); + + while ((err = wait_for_completion_interruptible(&qp_rsc.delayed_release)) + == -ERESTARTSYS) + xsc_core_dbg(xdev, "qp %d wait for completion is interrupted, err = %d\n", + qpn, err); } int create_resource_common(struct xsc_core_device *xdev, @@ -205,6 +201,7 @@ int xsc_core_create_qp(struct xsc_core_device *xdev, int exec = 1; ktime_get_boottime_ts64(&ts); + memset(&dout, 0, sizeof(dout)); in->hdr.opcode = cpu_to_be16(XSC_CMD_OP_CREATE_QP); @@ -305,6 +302,33 @@ int xsc_core_destroy_qp(struct xsc_core_device *xdev, } EXPORT_SYMBOL_GPL(xsc_core_destroy_qp); +int xsc_modify_qp(struct xsc_core_device *xdev, + struct xsc_modify_qp_mbox_in *in, + struct xsc_modify_qp_mbox_out *out, + u32 qpn, u16 status) +{ + int ret = 0; + + in->hdr.opcode = cpu_to_be16(status); + in->qpn = cpu_to_be32(qpn); + in->no_need_wait = 1; + + ret = xsc_cmd_exec(xdev, in, sizeof(*in), out, sizeof(*out)); + if ((status == XSC_CMD_OP_2RST_QP || status == XSC_CMD_OP_2ERR_QP) && + out->hdr.status) { + xsc_wait_qp_flush_complete(xdev, qpn); + out->hdr.status = 0; + } + if (ret || out->hdr.status != 0) { + xsc_core_err(xdev, "failed to modify qp %u status=%u, err=%d out.status %u\n", + qpn, status, ret, out->hdr.status); + ret = -ENOEXEC; + } + + return ret; +} +EXPORT_SYMBOL_GPL(xsc_modify_qp); + int xsc_core_qp_modify(struct xsc_core_device *xdev, enum xsc_qp_state cur_state, enum xsc_qp_state new_state, struct xsc_modify_qp_mbox_in *in, int sqd_event, @@ -353,7 +377,6 @@ int xsc_core_qp_modify(struct xsc_core_device *xdev, enum xsc_qp_state cur_state struct xsc_modify_qp_mbox_out out; int err = 0; u16 op; - u8 pf_id; if (cur_state >= XSC_QP_NUM_STATE || new_state >= XSC_QP_NUM_STATE || !optab[cur_state][new_state]) @@ -361,44 +384,26 @@ int xsc_core_qp_modify(struct xsc_core_device *xdev, enum xsc_qp_state cur_state memset(&out, 0, sizeof(out)); op = optab[cur_state][new_state]; - in->hdr.opcode = cpu_to_be16(op); - in->qpn = cpu_to_be32(qp->qpn); - in->no_need_wait = 1; if (new_state == XSC_QP_STATE_RTR) { if (qp->qp_type_internal == XSC_QUEUE_TYPE_RDMA_RC && ((in->ctx.ip_type == 0 && in->ctx.dip[0] == in->ctx.sip[0]) || (in->ctx.ip_type != 0 && - memcmp(in->ctx.dip, in->ctx.sip, sizeof(in->ctx.sip)) == 0))) { - in->ctx.qp_out_port = xdev->caps.nif_port_num + g_xsc_pcie_no; - } else if (in->ctx.lag_sel_en == 0) { - if (funcid_to_pf_index(&xdev->caps, xdev->glb_func_id, &pf_id)) - in->ctx.qp_out_port = pf_id; - else - return -EINVAL; - } else { + memcmp(in->ctx.dip, in->ctx.sip, sizeof(in->ctx.sip)) == 0))) + in->ctx.qp_out_port = xdev->caps.nif_port_num + xdev->pcie_no; + else if (in->ctx.lag_sel_en == 0) + in->ctx.qp_out_port = xdev->pf_id; + else in->ctx.qp_out_port = in->ctx.lag_sel; - } - in->ctx.pcie_no = g_xsc_pcie_no; + in->ctx.pcie_no = xdev->pcie_no; in->ctx.func_id = cpu_to_be16(xdev->glb_func_id); } - err = xsc_cmd_exec(xdev, in, sizeof(*in), &out, sizeof(out)); + err = xsc_modify_qp(xdev, in, &out, qp->qpn, op); if (err) return err; - if ((op == XSC_CMD_OP_2RST_QP || op == XSC_CMD_OP_2ERR_QP) && out.hdr.status) { - xsc_core_dbg(xdev, "qp %d flush incomplete in fw.\n", qp->qpn); - init_completion(&qp->delayed_release); - xsc_add_to_delayed_release_list(xdev, qp); - out.hdr.status = 0; - while ((err = wait_for_completion_interruptible(&qp->delayed_release)) - == -ERESTARTSYS) - xsc_core_dbg(xdev, "qp %d wait for completion is interrupted, err = %d\n", - qp->qpn, err); - } - if (new_state == XSC_QP_STATE_RTR) { qp->trace_info->main_ver = YS_QPTRACE_VER_MAJOR; qp->trace_info->sub_ver = YS_QPTRACE_VER_MINOR; diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/res_obj.c b/drivers/net/ethernet/yunsilicon/xsc/pci/res_obj.c index 495371b2193c..cc3dbe57b574 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/res_obj.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/res_obj.c @@ -7,6 +7,8 @@ #include "common/xsc_ioctl.h" #include "common/xsc_hsi.h" #include "common/xsc_cmd.h" +#include "common/qp.h" +#include "common/driver.h" static int xsc_alloc_obj(struct xsc_res_obj *obj, struct xsc_bdf_file *file, void (*release_func)(void *), unsigned long key, @@ -264,12 +266,9 @@ static void xsc_send_cmd_2rst_qp(struct xsc_core_device *xdev, unsigned int qpn) struct xsc_modify_qp_mbox_out out; int ret; - in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_2RST_QP); - in.qpn = cpu_to_be32(qpn); - in.no_need_wait = 0; - ret = xsc_cmd_exec(xdev, &in, sizeof(in), &out, sizeof(out)); - if (ret || out.hdr.status != 0) - xsc_core_err(xdev, "failed to modify qp %d to rst\n", qpn); + ret = xsc_modify_qp(xdev, &in, &out, qpn, XSC_CMD_OP_2RST_QP); + if (ret) + xsc_core_err(xdev, "failed to reset qp %u\n", qpn); } static void xsc_send_cmd_destroy_qp(struct xsc_core_device *xdev, unsigned int qpn) diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/sriov.c b/drivers/net/ethernet/yunsilicon/xsc/pci/sriov.c index 4029f69e84db..8875cc18f895 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/sriov.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/sriov.c @@ -10,7 +10,6 @@ #ifdef CONFIG_XSC_ESWITCH #include "eswitch.h" #endif -#include "fw/xsc_tbm.h" #include "xsc_pci_ctrl.h" static int xsc_device_enable_sriov(struct xsc_core_device *dev, int num_vfs) @@ -109,17 +108,17 @@ static int xsc_sriov_enable(struct pci_dev *pdev, int num_vfs) return -EBUSY; } - xsc_core_info(dev, "%s: num_vfs=%d\n", __func__, num_vfs); + xsc_core_info(dev, "enable %d VFs\n", num_vfs); err = xsc_device_enable_sriov(dev, num_vfs); if (err) { - xsc_core_warn(dev, "xsc_device_enable_sriov failed : %d\n", err); + xsc_core_warn(dev, "xsc_device_enable_sriov failed, err=%d\n", err); return err; } err = pci_enable_sriov(pdev, num_vfs); if (err) { - xsc_core_warn(dev, "pci_enable_sriov failed : %d\n", err); + xsc_core_warn(dev, "pci_enable_sriov failed, err=%d\n", err); xsc_device_disable_sriov(dev, num_vfs, true); } @@ -131,7 +130,7 @@ static void xsc_sriov_disable(struct pci_dev *pdev) struct xsc_core_device *dev = pci_get_drvdata(pdev); int num_vfs = pci_num_vf(dev->pdev); - xsc_core_info(dev, "%s: num_vfs=%d\n", __func__, num_vfs); + xsc_core_info(dev, "disable %d VFs\n", num_vfs); pci_disable_sriov(pdev); xsc_device_disable_sriov(dev, num_vfs, true); @@ -143,9 +142,6 @@ int xsc_core_sriov_configure(struct pci_dev *pdev, int num_vfs) struct xsc_core_sriov *sriov = &dev->priv.sriov; int err = 0; - xsc_core_info(dev, "%s: requested num_vfs %d\n", - __func__, num_vfs); - if (num_vfs) err = xsc_sriov_enable(pdev, num_vfs); else @@ -191,6 +187,9 @@ void xsc_sriov_detach(struct xsc_core_device *dev) static u16 xsc_get_max_vfs(struct xsc_core_device *dev) { + /* In RH6.8 and lower pci_sriov_get_totalvfs might return -EINVAL + * return in that case 1 + */ return (pci_sriov_get_totalvfs(dev->pdev) < 0) ? 0 : pci_sriov_get_totalvfs(dev->pdev); } @@ -259,13 +258,13 @@ int xsc_sriov_init(struct xsc_core_device *dev) if (!sriov->vfs_ctx) return -ENOMEM; - xsc_core_info(dev, "%s: total_vfs=%d, cur_vfs=%d, vf_bdf_base=0x%02x\n", - __func__, total_vfs, sriov->num_vfs, sriov->vf_bdf_base); - xsc_core_info(dev, "%s: vf_offset=%d, stride=%d, vf_device_id=0x%x\n", - __func__, iov->offset, iov->stride, iov->vf_device); + xsc_core_info(dev, "total_vfs=%d, cur_vfs=%d, vf_bdf_base=0x%02x\n", + total_vfs, sriov->num_vfs, sriov->vf_bdf_base); + xsc_core_info(dev, "vf_offset=%d, stride=%d, vf_device_id=0x%x\n", + iov->offset, iov->stride, iov->vf_device); err = xsc_sriov_sysfs_init(dev); if (err) { - xsc_core_warn(dev, "failed to init SRIOV sysfs (%d)\n", err); + xsc_core_warn(dev, "failed to init SRIOV sysfs, err=%d\n", err); kfree(sriov->vfs_ctx); return err; } diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/sriov_sysfs.c b/drivers/net/ethernet/yunsilicon/xsc/pci/sriov_sysfs.c index 8507b85583c7..2d9b14251475 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/sriov_sysfs.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/sriov_sysfs.c @@ -234,7 +234,8 @@ static ssize_t policy_show(struct xsc_sriov_vf *g, struct vf_attributes *oa, goto free; } p = policy_str(rep->vport_state_policy); - strscpy(buf, p, strlen(p)); + if (p) + strscpy(buf, p, strlen(p)); free: kfree(rep); diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/vport.c b/drivers/net/ethernet/yunsilicon/xsc/pci/vport.c index 0edda05262d4..7eb53f2a9bdc 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/vport.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/vport.c @@ -189,7 +189,7 @@ static int __xsc_modify_nic_vport_mac_address(struct xsc_core_device *dev, in.vport_number = cpu_to_be16(vport); } - if (xsc_get_pp_bypass_res(dev)) + if (xsc_get_pp_bypass_res(dev, false)) caps |= BIT(XSC_TBM_CAP_PP_BYPASS); caps_mask |= BIT(XSC_TBM_CAP_PP_BYPASS); in.caps = cpu_to_be16(caps); diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c b/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c index 71687f1ca2c9..b73e580fc627 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c @@ -16,7 +16,6 @@ #include #include #include -#include "fw/xsc_tbm.h" #ifdef fib_nh_dev #define HAVE_FIB_NH_DEV @@ -107,12 +106,8 @@ int xsc_cmd_create_lag(struct xsc_lag *ldev, u8 flags) memcpy(info_mac1->netdev_addr, netdev1->dev_addr, ETH_ALEN); memcpy(info_mac0->gw_dmac, tracker->gw_dmac0, ETH_ALEN); memcpy(info_mac1->gw_dmac, tracker->gw_dmac1, ETH_ALEN); - info_mac0->info_mac.mac_logic_port = cpu_to_be16(xdev0->mac_logic_port); - info_mac0->info_mac.logic_port = cpu_to_be16(xdev0->logic_port); - info_mac0->info_mac.glb_func_id = cpu_to_be16(xdev0->glb_func_id); - info_mac1->info_mac.mac_logic_port = cpu_to_be16(xdev1->mac_logic_port); - info_mac1->info_mac.logic_port = cpu_to_be16(xdev1->logic_port); - info_mac1->info_mac.glb_func_id = cpu_to_be16(xdev1->glb_func_id); + info_mac0->glb_func_id = cpu_to_be16(xdev0->glb_func_id); + info_mac1->glb_func_id = cpu_to_be16(xdev1->glb_func_id); ret = xsc_cmd_exec(xdev0, &in, sizeof(in), &out, sizeof(out)); if (ret || out.hdr.status) { @@ -136,11 +131,9 @@ int xsc_cmd_modify_lag(struct xsc_lag *ldev) bool sriov_lag = ldev->flags & XSC_LAG_FLAG_SRIOV; u8 remap_port1 = ldev->v2p_map[0]; u8 remap_port2 = ldev->v2p_map[1]; - - int ret = -1; - struct xsc_modify_lag_mbox_in in = {}; struct xsc_modify_lag_mbox_out out = {}; + int ret = -1; in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_LAG_MODIFY); @@ -169,17 +162,16 @@ int xsc_cmd_destroy_lag(struct xsc_lag *ldev, u8 bond_flags) struct xsc_core_device *xdev0 = ldev->pf[0].xdev; u8 flags = ldev->flags; int ret = -1; - bool kernel_bond = bond_flags & XSC_BOND_FLAG_KERNEL; struct xsc_destroy_lag_mbox_in in = {}; struct xsc_destroy_lag_mbox_out out = {}; - if (!(flags & XSC_LAG_MODE_FLAGS) && !kernel_bond) + if (!(flags & XSC_LAG_MODE_FLAGS) && !(flags & XSC_BOND_FLAG_KERNEL)) return -EINVAL; in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_LAG_DESTROY); - if (!kernel_bond) { + if (bond_flags & XSC_LAG_MODE_FLAGS) { in.req.lag_id = ldev->lag_id; xsc_core_info(xdev0, "destroy lag: lag_id = %d\n", ldev->lag_id); } else { @@ -194,8 +186,7 @@ int xsc_cmd_destroy_lag(struct xsc_lag *ldev, u8 bond_flags) return -ENOEXEC; } - if (!kernel_bond) - ldev->lag_id = 0xff; + ldev->lag_id = U16_MAX; return ret; } @@ -222,7 +213,7 @@ static int xsc_lag_set_qos(struct xsc_core_device *xdev, u16 lag_id, u8 member_b req->lag_id = cpu_to_be16(lag_id); req->member_bitmap = member_bitmap; req->lag_del = lag_del; - req->pcie_no = g_xsc_pcie_no; + req->pcie_no = xdev->pcie_no; in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_LAG_SET_QOS); ret = xsc_cmd_exec(xdev, &in, sizeof(in), &out, sizeof(out)); @@ -241,7 +232,13 @@ static bool xsc_lag_check_prereq(struct xsc_lag *ldev) return true; #ifdef CONFIG_XSC_ESWITCH - return (xdev0->priv.eswitch->mode == XSC_ESWITCH_OFFLOADS) && + if ((xdev0->priv.eswitch->mode == XSC_ESWITCH_OFFLOADS && + xdev1->priv.eswitch->mode != XSC_ESWITCH_OFFLOADS) || + (xdev0->priv.eswitch->mode != XSC_ESWITCH_OFFLOADS && + xdev1->priv.eswitch->mode == XSC_ESWITCH_OFFLOADS)) + xsc_core_info(xdev0, "lag is permitted by both pf is in switchdev mode\n"); + + return (xdev0->priv.eswitch->mode == XSC_ESWITCH_OFFLOADS) && (xdev1->priv.eswitch->mode == XSC_ESWITCH_OFFLOADS); #else #ifdef XSC_VF_ECMP_TEST @@ -339,17 +336,17 @@ void xsc_modify_lag(struct xsc_lag *ldev) xsc_core_err(xdev0, "failed to set QoS for LAG %u\n", ldev->lag_id); } -static void xsc_deactivate_lag(struct xsc_lag *ldev) +static void xsc_deactivate_lag(struct xsc_lag *ldev, u8 flags) { struct xsc_core_device *xdev0 = ldev->pf[0].xdev; if (xsc_lag_set_qos(xdev0, ldev->lag_id, 0, true)) xsc_core_err(xdev0, "failed to set QoS for LAG %u\n", ldev->lag_id); - if (xsc_cmd_destroy_lag(ldev, XSC_BOND_FLAG_LAG)) + if (xsc_cmd_destroy_lag(ldev, flags)) xsc_core_err(xdev0, "Failed to deactivate LAG; driver restart required, Make sure all VFs are unbound prior to LAG activation or deactivation\n"); - ldev->flags &= ~XSC_LAG_MODE_FLAGS; + ldev->flags &= ~flags; } static void xsc_lag_remove_ib_devices(struct xsc_lag *ldev) @@ -375,9 +372,8 @@ static void xsc_do_bond(struct xsc_lag *ldev) struct xsc_core_device *xdev0 = ldev->pf[0].xdev; struct xsc_core_device *xdev1 = ldev->pf[1].xdev; struct lag_tracker tracker; - bool do_lag; + bool do_lag, do_bond; bool roce_lag; - int ret = 0; if (!xdev0 || !xdev1) return; @@ -386,22 +382,7 @@ static void xsc_do_bond(struct xsc_lag *ldev) tracker = ldev->tracker; mutex_unlock(&lag_mutex); - if (tracker.is_kernel_bonded_change) { - if (tracker.is_kernel_bonded && !__xsc_bond_is_active(ldev)) { - ret = xsc_cmd_create_lag(ldev, XSC_BOND_FLAG_KERNEL); - ldev->flags |= XSC_BOND_FLAG_KERNEL; - - xsc_core_info(xdev0, "Create kernel bond, ret = %d\n", ret); - } else if (!tracker.is_kernel_bonded && __xsc_bond_is_active(ldev)) { - ret = xsc_cmd_destroy_lag(ldev, XSC_BOND_FLAG_KERNEL); - ldev->flags &= ~XSC_BOND_FLAG_KERNEL; - - xsc_core_info(xdev0, "Destroy kernel bond, ret = %d\n", ret); - } - tracker.is_kernel_bonded_change = false; - - return; - } + do_bond = tracker.is_kernel_bonded; do_lag = tracker.is_hw_bonded && !tracker.lag_disable && @@ -420,17 +401,19 @@ static void xsc_do_bond(struct xsc_lag *ldev) return; } - xsc_core_info(xdev0, "do_lag = %d, is_hw_bonded = %d, lag_disable = %d, lag_check = %d\n", - do_lag, tracker.is_hw_bonded, tracker.lag_disable, + xsc_core_info(xdev0, "do_bond = %d, do_lag = %d, is_hw_bonded = %d, lag_disable = %d, lag_check = %d\n", + do_bond, do_lag, tracker.is_hw_bonded, tracker.lag_disable, xsc_lag_check_prereq(ldev)); - if (do_lag && !__xsc_lag_is_active(ldev)) { - if (roce_lag) { + if ((do_bond && !__xsc_bond_is_active(ldev)) || + (do_lag && !__xsc_lag_is_active(ldev))) { + if (do_lag && roce_lag) { xsc_lag_remove_ib_devices(ldev); - xsc_activate_lag(ldev, (XSC_LAG_FLAG_ROCE)); + xsc_activate_lag(ldev, XSC_LAG_FLAG_ROCE); xsc_add_dev_by_protocol(xdev0, XSC_INTERFACE_PROTOCOL_IB); } else { - xsc_activate_lag(ldev, XSC_LAG_FLAG_SRIOV); + xsc_activate_lag(ldev, (do_lag ? + XSC_LAG_FLAG_SRIOV : XSC_BOND_FLAG_KERNEL)); } } else if (do_lag && __xsc_lag_is_active(ldev)) { xsc_modify_lag(ldev); @@ -438,10 +421,12 @@ static void xsc_do_bond(struct xsc_lag *ldev) if (roce_lag) xsc_remove_dev_by_protocol(xdev0, XSC_INTERFACE_PROTOCOL_IB); - xsc_deactivate_lag(ldev); + xsc_deactivate_lag(ldev, XSC_LAG_MODE_FLAGS); if (roce_lag) xsc_lag_add_ib_devices(ldev); + } else if (!do_bond && __xsc_bond_is_active(ldev)) { + xsc_deactivate_lag(ldev, XSC_BOND_FLAG_KERNEL); } } @@ -585,7 +570,6 @@ static bool xsc_lag_eval_bonding_conds(struct xsc_lag *ldev, if (tracker->is_kernel_bonded != is_kernel_bonded) { tracker->is_kernel_bonded = is_kernel_bonded; - tracker->is_kernel_bonded_change = true; return true; } @@ -798,13 +782,11 @@ static void xsc_lag_fib_route_event(struct xsc_lag *ldev, /* stop track */ if (mp->mfi == fi) mp->mfi = NULL; - xsc_deactivate_lag(ldev); + xsc_deactivate_lag(ldev, XSC_LAG_MODE_FLAGS); return; } -#ifdef XSC_LAG_DEBUG xsc_core_info(ldev->pf[0].xdev, "nhs=%d\n", nhs); -#endif if (nhs == 1 && event != FIB_EVENT_ENTRY_DEL) { if (__xsc_lag_is_active(ldev)) { @@ -1006,9 +988,7 @@ int xsc_lag_fib_event(struct notifier_block *nb, if (!xsc_lag_multipath_check_prereq(ldev)) return NOTIFY_DONE; -#ifdef XSC_LAG_DEBUG - xsc_core_info(ldev->pf[0].xdev, "lag fib event=%ld\n", event); -#endif + xsc_core_dbg(ldev->pf[0].xdev, "lag fib event=%ld\n", event); switch (event) { case FIB_EVENT_ENTRY_REPLACE: @@ -1110,11 +1090,15 @@ int __xsc_lag_add_xdev(struct xsc_core_device *xdev) } xsc_lag_dev_add_xdev(ldev, xdev); - ldev->lag_id = 0xff; + ldev->lag_id = U16_MAX; if (!ldev->nb.notifier_call) { ldev->nb.notifier_call = xsc_lag_netdev_event; +#ifdef HAVE_NETDEVICE_NOTIFIER_RH + err = register_netdevice_notifier_rh(&ldev->nb); +#else err = register_netdevice_notifier(&ldev->nb); +#endif if (err) { ldev->nb.notifier_call = NULL; xsc_core_err(xdev, "Failed to register LAG netdev notifier\n"); @@ -1253,7 +1237,11 @@ void xsc_lag_dev_free(struct kref *ref) struct xsc_lag *ldev = container_of(ref, struct xsc_lag, ref); if (ldev->nb.notifier_call) +#ifdef HAVE_NETDEVICE_NOTIFIER_RH + unregister_netdevice_notifier_rh(&ldev->nb); +#else unregister_netdevice_notifier(&ldev->nb); +#endif xsc_lag_mp_cleanup(ldev); cancel_delayed_work_sync(&ldev->bond_work); @@ -1275,7 +1263,10 @@ void xsc_lag_remove(struct xsc_core_device *xdev) return; if (__xsc_lag_is_active(ldev)) - xsc_deactivate_lag(ldev); + xsc_deactivate_lag(ldev, XSC_LAG_MODE_FLAGS); + + if (__xsc_bond_is_active(ldev)) + xsc_deactivate_lag(ldev, XSC_BOND_FLAG_KERNEL); xsc_lag_dev_remove_pf(ldev, xdev); xsc_lag_dev_put(ldev); diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_pci_ctrl.c b/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_pci_ctrl.c index 56aeb63d17b1..edd102e882df 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_pci_ctrl.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_pci_ctrl.c @@ -88,8 +88,6 @@ static int xsc_pci_ctrl_get_phy(struct xsc_core_device *xdev, int ret = 0; struct xsc_ioctl_data_tl *tl = (struct xsc_ioctl_data_tl *)out; struct xsc_ioctl_get_phy_info_res *resp; - struct xsc_ioctl_get_vf_info_res *vf_res; - struct xsc_vf_info vf_info; struct xsc_lag *ldev = xsc_lag_dev_get(xdev); u16 lag_id = U16_MAX; struct xsc_core_device *rl_xdev; @@ -101,11 +99,11 @@ static int xsc_pci_ctrl_get_phy(struct xsc_core_device *xdev, case XSC_IOCTL_OP_GET_LOCAL: resp = (struct xsc_ioctl_get_phy_info_res *)(tl + 1); - resp->phy_port = xdev->pcie_port; + resp->pcie_no = xdev->pcie_no; resp->func_id = xdev->glb_func_id; - resp->logic_in_port = xdev->logic_port; + resp->pcie_host = xdev->caps.pcie_host; resp->mac_phy_port = xdev->mac_port; - resp->mac_logic_in_port = xdev->mac_logic_port; + resp->funcid_to_logic_port_off = xdev->caps.funcid_to_logic_port; resp->lag_id = lag_id; resp->raw_qp_id_base = xdev->caps.raweth_qp_id_base; resp->raw_rss_qp_id_base = xdev->caps.raweth_rss_qp_id_base; @@ -121,28 +119,20 @@ static int xsc_pci_ctrl_get_phy(struct xsc_core_device *xdev, resp->pct_compress_vld = (xdev->feature_flag & FEATURE_PCT_EXP_MASK) ? 1 : 0; - xsc_core_dbg(xdev, "BY_LOCAL:%d,%d,%d,%d,%d,%d\n", resp->phy_port, - resp->func_id, resp->logic_in_port, - resp->mac_phy_port, resp->mac_logic_in_port, - resp->lag_id); - resp->funcid[0] = xdev->caps.funcid[0]; - resp->funcid[1] = xdev->caps.funcid[1]; - resp->funcid[2] = xdev->caps.funcid[2]; - resp->funcid[3] = xdev->caps.funcid[3]; - resp->funcid[4] = xdev->caps.funcid[4]; - resp->funcid[5] = xdev->caps.funcid[5]; - resp->funcid[6] = xdev->caps.funcid[6]; - resp->funcid[7] = xdev->caps.funcid[7]; - break; - - case XSC_IOCTL_OP_GET_VF_INFO: - vf_res = (struct xsc_ioctl_get_vf_info_res *)(tl + 1); - memcpy(&vf_info, vf_res, sizeof(struct xsc_vf_info)); - - xsc_pci_get_vf_info(xdev, &vf_info); - - vf_res->func_id = vf_info.func_id; - vf_res->logic_port = vf_info.logic_port; + xsc_core_dbg(xdev, "%d,%d,%d,%d,%d,%d\n", + resp->pcie_no, resp->func_id, resp->pcie_host, + resp->mac_phy_port, resp->lag_id, + resp->funcid_to_logic_port_off); + resp->pf0_vf_funcid_base = xdev->caps.pf0_vf_funcid_base; + resp->pf0_vf_funcid_top = xdev->caps.pf0_vf_funcid_top; + resp->pf1_vf_funcid_base = xdev->caps.pf1_vf_funcid_base; + resp->pf1_vf_funcid_top = xdev->caps.pf1_vf_funcid_top; + resp->pcie0_pf_funcid_base = xdev->caps.pcie0_pf_funcid_base; + resp->pcie0_pf_funcid_top = xdev->caps.pcie0_pf_funcid_top; + resp->pcie1_pf_funcid_base = xdev->caps.pcie1_pf_funcid_base; + resp->pcie1_pf_funcid_top = xdev->caps.pcie1_pf_funcid_top; + resp->hca_core_clock = xdev->caps.hca_core_clock; + resp->mac_bit = xdev->caps.mac_bit; break; case XSC_IOCTL_OP_GET_INFO_BY_BDF: @@ -155,11 +145,11 @@ static int xsc_pci_ctrl_get_phy(struct xsc_core_device *xdev, if (!rl_xdev) return -1; - resp->phy_port = rl_xdev->pcie_port; + resp->pcie_no = rl_xdev->pcie_no; resp->func_id = rl_xdev->glb_func_id; - resp->logic_in_port = rl_xdev->logic_port; + resp->pcie_host = rl_xdev->caps.pcie_host; resp->mac_phy_port = rl_xdev->mac_port; - resp->mac_logic_in_port = rl_xdev->mac_logic_port; + resp->funcid_to_logic_port_off = rl_xdev->caps.funcid_to_logic_port; resp->lag_id = lag_id; resp->raw_qp_id_base = rl_xdev->caps.raweth_qp_id_base; resp->raw_rss_qp_id_base = xdev->caps.raweth_rss_qp_id_base; @@ -175,18 +165,18 @@ static int xsc_pci_ctrl_get_phy(struct xsc_core_device *xdev, resp->pct_compress_vld = (rl_xdev->feature_flag & FEATURE_PCT_EXP_MASK) ? 1 : 0; - xsc_core_dbg(xdev, "BY_BDF:%d,%d,%d,%d,%d,%d\n", resp->phy_port, - resp->func_id, resp->logic_in_port, - resp->mac_phy_port, resp->mac_logic_in_port, - resp->lag_id); - resp->funcid[0] = xdev->caps.funcid[0]; - resp->funcid[1] = xdev->caps.funcid[1]; - resp->funcid[2] = xdev->caps.funcid[2]; - resp->funcid[3] = xdev->caps.funcid[3]; - resp->funcid[4] = xdev->caps.funcid[4]; - resp->funcid[5] = xdev->caps.funcid[5]; - resp->funcid[6] = xdev->caps.funcid[6]; - resp->funcid[7] = xdev->caps.funcid[7]; + xsc_core_dbg(xdev, "%d,%d,%d,%d,%d,%d\n", + resp->pcie_no, resp->func_id, resp->pcie_host, + resp->mac_phy_port, resp->lag_id, + resp->funcid_to_logic_port_off); + resp->pf0_vf_funcid_base = rl_xdev->caps.pf0_vf_funcid_base; + resp->pf0_vf_funcid_top = rl_xdev->caps.pf0_vf_funcid_top; + resp->pf1_vf_funcid_base = rl_xdev->caps.pf1_vf_funcid_base; + resp->pf1_vf_funcid_top = rl_xdev->caps.pf1_vf_funcid_top; + resp->pcie0_pf_funcid_base = rl_xdev->caps.pcie0_pf_funcid_base; + resp->pcie0_pf_funcid_top = rl_xdev->caps.pcie0_pf_funcid_top; + resp->pcie1_pf_funcid_base = rl_xdev->caps.pcie1_pf_funcid_base; + resp->pcie1_pf_funcid_top = rl_xdev->caps.pcie1_pf_funcid_top; break; default: @@ -260,7 +250,6 @@ static struct kprobe kp = { unsigned long (*kallsyms_lookup_name_func)(const char *name) = NULL; -//调用kprobe找到kallsyms_lookup_name的地址位置 int find_kallsyms_lookup_name(void) { int ret = -1; @@ -293,9 +282,6 @@ u16 xsc_get_irq_matrix_global_available(struct xsc_core_device *dev) xsc_core_dbg(dev, "vector_matrix addr=0x%lx\n", addr); if (addr == 0) { xsc_core_err(dev, "not support, arch maybe not X86?\n"); - /* 返回0xffff,做到在不知道cpu vector剩余多少可用的情况 - * 下不影响fw用该值判断能否分配中断 - */ return 0xffff; } m = (struct db_irq_matrix *)(*(long *)addr); @@ -646,7 +632,7 @@ static int xsc_ioctl_modify_raw_qp(struct xsc_core_device *xdev, goto err; in->hdr.opcode = __cpu_to_be16(hdr->attr.opcode); - in->pcie_no = g_xsc_pcie_no; + in->pcie_no = xdev->pcie_no; err = xsc_cmd_exec(xdev, in, sizeof(struct xsc_modify_raw_qp_mbox_in), out, sizeof(struct xsc_modify_raw_qp_mbox_out)); @@ -756,25 +742,32 @@ static long xsc_pci_ctrl_cmdq_raw(struct xsc_bdf_file *file, u8 key; err = copy_from_user(&hdr, user_hdr, sizeof(hdr)); - if (err) + if (err) { + xsc_core_err(dev, "fail to copy_from_user user hdr\n"); return -EFAULT; + } /* check valid */ - if (hdr.check_filed != XSC_IOCTL_CHECK_FILED) + if (hdr.check_filed != XSC_IOCTL_CHECK_FILED) { + xsc_core_err(dev, "invalid check filed %u\n", hdr.check_filed); return -EINVAL; + } in = kvzalloc(hdr.attr.length, GFP_KERNEL); if (!in) return -ENOMEM; + out = kvzalloc(hdr.attr.length, GFP_KERNEL); if (!out) { kfree(in); + xsc_core_err(dev, "fail to alloc hdr length for mbox out\n"); return -ENOMEM; } err = copy_from_user(in, user_hdr->attr.data, hdr.attr.length); if (err) { err = -EFAULT; + xsc_core_err(dev, "fail to copy_from_user user hdr attr\n"); goto err_exit; } @@ -819,11 +812,10 @@ static long xsc_pci_ctrl_cmdq_raw(struct xsc_bdf_file *file, break; } xsc_pci_ctrl_cmdq_handle_res_obj(file, in, hdr.attr.length, out, hdr.attr.opcode); -/* if (copy_to_user((void *)user_hdr, &hdr, sizeof(hdr))) - * err = -EFAULT; - */ - if (copy_to_user((void *)user_hdr->attr.data, out, hdr.attr.length)) + if (copy_to_user((void *)user_hdr->attr.data, out, hdr.attr.length)) { + xsc_core_err(dev, "fail to copy_to_user user hdr attr\n"); err = -EFAULT; + } err_exit: kfree(in); kfree(out); diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_pci_ctrl.h b/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_pci_ctrl.h index 8dda84170236..c57caed380b7 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_pci_ctrl.h +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_pci_ctrl.h @@ -10,6 +10,7 @@ #include #include +//for x86 #ifndef NR_VECTORS #define NR_VECTORS 256 #endif diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_port_ctrl.c b/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_port_ctrl.c index c98f34dd23fc..82d6041f620d 100644 --- a/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_port_ctrl.c +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/xsc_port_ctrl.c @@ -13,7 +13,7 @@ #include "common/driver.h" #include "common/xsc_port_ctrl.h" #include "common/res_obj.h" -#include "fw/xsc_tbm.h" + #define XSC_PORT_CTRL_MAX 256 #define XSC_PORT_CTRL_NAME_PRE "yunsilicon" @@ -208,8 +208,11 @@ static inline struct xsc_bdf_file *get_bdf_file(struct xsc_port_ctrl_file *file, } rl_xdev = xsc_pci_get_xdev_by_bus_and_slot(hdr->domain, hdr->bus, hdr->devfn); - if (!rl_xdev) + if (!rl_xdev) { + xsc_core_err(bdf_file->xdev, "fail to get xdev:domain=%x, bus=%x, devfn=%x\n", + hdr->domain, hdr->bus, hdr->devfn); return NULL; + } bdf_file = kzalloc(sizeof(*bdf_file), GFP_KERNEL); if (!bdf_file) @@ -241,12 +244,16 @@ static long _port_ctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long file = filp->private_data; user_hdr = (struct xsc_ioctl_hdr __user *)arg; err = copy_from_user(&hdr, user_hdr, sizeof(hdr)); - if (err) + if (err) { + pr_err("%s: fail to copy from user hdr\n", __func__); return err; + } bdf_file = get_bdf_file(file, &hdr); - if (!bdf_file) + if (!bdf_file) { + pr_err("%s: fail to find bdf file\n", __func__); return -EFAULT; + } list_for_each_entry(p, &g_port_ctrl_cbs, node) { if (p->cb) { @@ -363,8 +370,9 @@ static int _port_ctrl_dev_add(struct xsc_core_device *dev) ctrl->device = device_create(g_port_ctrl_class, NULL, ctrl->devid, NULL, "%s!%s_%02x:%02x.%x", XSC_PORT_CTRL_NAME_PRE, - XSC_PORT_CTRL_NAME, dev->bus_num, - dev->dev_num, dev->func_id); + XSC_PORT_CTRL_NAME, dev->pdev->bus->number, + PCI_SLOT(dev->pdev->devfn), + PCI_FUNC(dev->pdev->devfn)); if (IS_ERR(ctrl->device)) { xsc_core_err(dev, "failed to create port control device\n"); cdev_del(&ctrl->cdev); -- Gitee