1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2018 Netronome Systems, Inc. */
4 #include <linux/kernel.h>
5 #include <net/devlink.h>
7 #include "nfpcore/nfp_cpp.h"
8 #include "nfpcore/nfp_nffw.h"
13 static u32
nfp_shared_buf_pool_unit(struct nfp_pf
*pf
, unsigned int sb
)
15 __le32 sb_id
= cpu_to_le32(sb
);
18 for (i
= 0; i
< pf
->num_shared_bufs
; i
++)
19 if (pf
->shared_bufs
[i
].id
== sb_id
)
20 return le32_to_cpu(pf
->shared_bufs
[i
].pool_size_unit
);
26 int nfp_shared_buf_pool_get(struct nfp_pf
*pf
, unsigned int sb
, u16 pool_index
,
27 struct devlink_sb_pool_info
*pool_info
)
29 struct nfp_shared_buf_pool_info_get get_data
;
30 struct nfp_shared_buf_pool_id id
= {
31 .shared_buf
= cpu_to_le32(sb
),
32 .pool
= cpu_to_le32(pool_index
),
34 unsigned int unit_size
;
37 unit_size
= nfp_shared_buf_pool_unit(pf
, sb
);
41 n
= nfp_mbox_cmd(pf
, NFP_MBOX_POOL_GET
, &id
, sizeof(id
),
42 &get_data
, sizeof(get_data
));
45 if (n
< sizeof(get_data
))
48 pool_info
->pool_type
= le32_to_cpu(get_data
.pool_type
);
49 pool_info
->threshold_type
= le32_to_cpu(get_data
.threshold_type
);
50 pool_info
->size
= le32_to_cpu(get_data
.size
) * unit_size
;
51 pool_info
->cell_size
= unit_size
;
56 int nfp_shared_buf_pool_set(struct nfp_pf
*pf
, unsigned int sb
,
57 u16 pool_index
, u32 size
,
58 enum devlink_sb_threshold_type threshold_type
)
60 struct nfp_shared_buf_pool_info_set set_data
= {
62 .shared_buf
= cpu_to_le32(sb
),
63 .pool
= cpu_to_le32(pool_index
),
65 .threshold_type
= cpu_to_le32(threshold_type
),
67 unsigned int unit_size
;
69 unit_size
= nfp_shared_buf_pool_unit(pf
, sb
);
70 if (!unit_size
|| size
% unit_size
)
72 set_data
.size
= cpu_to_le32(size
/ unit_size
);
74 return nfp_mbox_cmd(pf
, NFP_MBOX_POOL_SET
, &set_data
, sizeof(set_data
),
78 int nfp_shared_buf_register(struct nfp_pf
*pf
)
80 struct devlink
*devlink
= priv_to_devlink(pf
);
81 unsigned int i
, num_entries
, entry_sz
;
82 struct nfp_cpp_area
*sb_desc_area
;
89 n
= nfp_pf_rtsym_read_optional(pf
, NFP_SHARED_BUF_COUNT_SYM_NAME
, 0);
94 sb_desc
= nfp_pf_map_rtsym(pf
, "sb_tbl", NFP_SHARED_BUF_TABLE_SYM_NAME
,
95 num_entries
* sizeof(pf
->shared_bufs
[0]),
98 return PTR_ERR(sb_desc
);
100 entry_sz
= nfp_cpp_area_size(sb_desc_area
) / num_entries
;
102 pf
->shared_bufs
= kmalloc_array(num_entries
, sizeof(pf
->shared_bufs
[0]),
104 if (!pf
->shared_bufs
) {
106 goto err_release_area
;
109 for (i
= 0; i
< num_entries
; i
++) {
110 struct nfp_shared_buf
*sb
= &pf
->shared_bufs
[i
];
112 /* Entries may be larger in future FW */
113 memcpy_fromio(sb
, sb_desc
+ i
* entry_sz
, sizeof(*sb
));
115 err
= devlink_sb_register(devlink
,
117 le32_to_cpu(sb
->size
),
118 le16_to_cpu(sb
->ingress_pools_count
),
119 le16_to_cpu(sb
->egress_pools_count
),
120 le16_to_cpu(sb
->ingress_tc_count
),
121 le16_to_cpu(sb
->egress_tc_count
));
125 pf
->num_shared_bufs
= num_entries
;
127 nfp_cpp_area_release_free(sb_desc_area
);
133 devlink_sb_unregister(devlink
,
134 le32_to_cpu(pf
->shared_bufs
[i
].id
));
135 kfree(pf
->shared_bufs
);
137 nfp_cpp_area_release_free(sb_desc_area
);
141 void nfp_shared_buf_unregister(struct nfp_pf
*pf
)
143 struct devlink
*devlink
= priv_to_devlink(pf
);
146 for (i
= 0; i
< pf
->num_shared_bufs
; i
++)
147 devlink_sb_unregister(devlink
,
148 le32_to_cpu(pf
->shared_bufs
[i
].id
));
149 kfree(pf
->shared_bufs
);