Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
0002 /* Copyright (C) 2018 Netronome Systems, Inc. */
0003 
0004 #include <linux/kernel.h>
0005 #include <net/devlink.h>
0006 
0007 #include "nfpcore/nfp_cpp.h"
0008 #include "nfpcore/nfp_nffw.h"
0009 #include "nfp_abi.h"
0010 #include "nfp_app.h"
0011 #include "nfp_main.h"
0012 
0013 static u32 nfp_shared_buf_pool_unit(struct nfp_pf *pf, unsigned int sb)
0014 {
0015     __le32 sb_id = cpu_to_le32(sb);
0016     unsigned int i;
0017 
0018     for (i = 0; i < pf->num_shared_bufs; i++)
0019         if (pf->shared_bufs[i].id == sb_id)
0020             return le32_to_cpu(pf->shared_bufs[i].pool_size_unit);
0021 
0022     WARN_ON_ONCE(1);
0023     return 0;
0024 }
0025 
0026 int nfp_shared_buf_pool_get(struct nfp_pf *pf, unsigned int sb, u16 pool_index,
0027                 struct devlink_sb_pool_info *pool_info)
0028 {
0029     struct nfp_shared_buf_pool_info_get get_data;
0030     struct nfp_shared_buf_pool_id id = {
0031         .shared_buf = cpu_to_le32(sb),
0032         .pool       = cpu_to_le32(pool_index),
0033     };
0034     unsigned int unit_size;
0035     int n;
0036 
0037     unit_size = nfp_shared_buf_pool_unit(pf, sb);
0038     if (!unit_size)
0039         return -EINVAL;
0040 
0041     n = nfp_mbox_cmd(pf, NFP_MBOX_POOL_GET, &id, sizeof(id),
0042              &get_data, sizeof(get_data));
0043     if (n < 0)
0044         return n;
0045     if (n < sizeof(get_data))
0046         return -EIO;
0047 
0048     pool_info->pool_type = le32_to_cpu(get_data.pool_type);
0049     pool_info->threshold_type = le32_to_cpu(get_data.threshold_type);
0050     pool_info->size = le32_to_cpu(get_data.size) * unit_size;
0051     pool_info->cell_size = unit_size;
0052 
0053     return 0;
0054 }
0055 
0056 int nfp_shared_buf_pool_set(struct nfp_pf *pf, unsigned int sb,
0057                 u16 pool_index, u32 size,
0058                 enum devlink_sb_threshold_type threshold_type)
0059 {
0060     struct nfp_shared_buf_pool_info_set set_data = {
0061         .id = {
0062             .shared_buf = cpu_to_le32(sb),
0063             .pool       = cpu_to_le32(pool_index),
0064         },
0065         .threshold_type = cpu_to_le32(threshold_type),
0066     };
0067     unsigned int unit_size;
0068 
0069     unit_size = nfp_shared_buf_pool_unit(pf, sb);
0070     if (!unit_size || size % unit_size)
0071         return -EINVAL;
0072     set_data.size = cpu_to_le32(size / unit_size);
0073 
0074     return nfp_mbox_cmd(pf, NFP_MBOX_POOL_SET, &set_data, sizeof(set_data),
0075                 NULL, 0);
0076 }
0077 
0078 int nfp_shared_buf_register(struct nfp_pf *pf)
0079 {
0080     struct devlink *devlink = priv_to_devlink(pf);
0081     unsigned int i, num_entries, entry_sz;
0082     struct nfp_cpp_area *sb_desc_area;
0083     u8 __iomem *sb_desc;
0084     int n, err;
0085 
0086     if (!pf->mbox)
0087         return 0;
0088 
0089     n = nfp_pf_rtsym_read_optional(pf, NFP_SHARED_BUF_COUNT_SYM_NAME, 0);
0090     if (n <= 0)
0091         return n;
0092     num_entries = n;
0093 
0094     sb_desc = nfp_pf_map_rtsym(pf, "sb_tbl", NFP_SHARED_BUF_TABLE_SYM_NAME,
0095                    num_entries * sizeof(pf->shared_bufs[0]),
0096                    &sb_desc_area);
0097     if (IS_ERR(sb_desc))
0098         return PTR_ERR(sb_desc);
0099 
0100     entry_sz = nfp_cpp_area_size(sb_desc_area) / num_entries;
0101 
0102     pf->shared_bufs = kmalloc_array(num_entries, sizeof(pf->shared_bufs[0]),
0103                     GFP_KERNEL);
0104     if (!pf->shared_bufs) {
0105         err = -ENOMEM;
0106         goto err_release_area;
0107     }
0108 
0109     for (i = 0; i < num_entries; i++) {
0110         struct nfp_shared_buf *sb = &pf->shared_bufs[i];
0111 
0112         /* Entries may be larger in future FW */
0113         memcpy_fromio(sb, sb_desc + i * entry_sz, sizeof(*sb));
0114 
0115         err = devlink_sb_register(devlink,
0116                       le32_to_cpu(sb->id),
0117                       le32_to_cpu(sb->size),
0118                       le16_to_cpu(sb->ingress_pools_count),
0119                       le16_to_cpu(sb->egress_pools_count),
0120                       le16_to_cpu(sb->ingress_tc_count),
0121                       le16_to_cpu(sb->egress_tc_count));
0122         if (err)
0123             goto err_unreg_prev;
0124     }
0125     pf->num_shared_bufs = num_entries;
0126 
0127     nfp_cpp_area_release_free(sb_desc_area);
0128 
0129     return 0;
0130 
0131 err_unreg_prev:
0132     while (i--)
0133         devlink_sb_unregister(devlink,
0134                       le32_to_cpu(pf->shared_bufs[i].id));
0135     kfree(pf->shared_bufs);
0136 err_release_area:
0137     nfp_cpp_area_release_free(sb_desc_area);
0138     return err;
0139 }
0140 
0141 void nfp_shared_buf_unregister(struct nfp_pf *pf)
0142 {
0143     struct devlink *devlink = priv_to_devlink(pf);
0144     unsigned int i;
0145 
0146     for (i = 0; i < pf->num_shared_bufs; i++)
0147         devlink_sb_unregister(devlink,
0148                       le32_to_cpu(pf->shared_bufs[i].id));
0149     kfree(pf->shared_bufs);
0150 }