1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
3 * Copyright (C) 2018 Netronome Systems, Inc.
5 * This software is dual licensed under the GNU General License Version 2,
6 * June 1991 as shown in the file COPYING in the top-level directory of this
7 * source tree or the BSD 2-Clause License provided below. You have the
8 * option to license this software under the complete terms of either license.
10 * The BSD 2-Clause License:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * 1. Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #include <linux/kernel.h>
36 #include <net/devlink.h>
38 #include "nfpcore/nfp_cpp.h"
39 #include "nfpcore/nfp_nffw.h"
44 static u32
nfp_shared_buf_pool_unit(struct nfp_pf
*pf
, unsigned int sb
)
46 __le32 sb_id
= cpu_to_le32(sb
);
49 for (i
= 0; i
< pf
->num_shared_bufs
; i
++)
50 if (pf
->shared_bufs
[i
].id
== sb_id
)
51 return le32_to_cpu(pf
->shared_bufs
[i
].pool_size_unit
);
57 int nfp_shared_buf_pool_get(struct nfp_pf
*pf
, unsigned int sb
, u16 pool_index
,
58 struct devlink_sb_pool_info
*pool_info
)
60 struct nfp_shared_buf_pool_info_get get_data
;
61 struct nfp_shared_buf_pool_id id
= {
62 .shared_buf
= cpu_to_le32(sb
),
63 .pool
= cpu_to_le32(pool_index
),
65 unsigned int unit_size
;
68 unit_size
= nfp_shared_buf_pool_unit(pf
, sb
);
72 n
= nfp_mbox_cmd(pf
, NFP_MBOX_POOL_GET
, &id
, sizeof(id
),
73 &get_data
, sizeof(get_data
));
76 if (n
< sizeof(get_data
))
79 pool_info
->pool_type
= le32_to_cpu(get_data
.pool_type
);
80 pool_info
->threshold_type
= le32_to_cpu(get_data
.threshold_type
);
81 pool_info
->size
= le32_to_cpu(get_data
.size
) * unit_size
;
86 int nfp_shared_buf_pool_set(struct nfp_pf
*pf
, unsigned int sb
,
87 u16 pool_index
, u32 size
,
88 enum devlink_sb_threshold_type threshold_type
)
90 struct nfp_shared_buf_pool_info_set set_data
= {
92 .shared_buf
= cpu_to_le32(sb
),
93 .pool
= cpu_to_le32(pool_index
),
95 .threshold_type
= cpu_to_le32(threshold_type
),
97 unsigned int unit_size
;
99 unit_size
= nfp_shared_buf_pool_unit(pf
, sb
);
100 if (!unit_size
|| size
% unit_size
)
102 set_data
.size
= cpu_to_le32(size
/ unit_size
);
104 return nfp_mbox_cmd(pf
, NFP_MBOX_POOL_SET
, &set_data
, sizeof(set_data
),
108 int nfp_shared_buf_register(struct nfp_pf
*pf
)
110 struct devlink
*devlink
= priv_to_devlink(pf
);
111 unsigned int i
, num_entries
, entry_sz
;
112 struct nfp_cpp_area
*sb_desc_area
;
119 n
= nfp_pf_rtsym_read_optional(pf
, NFP_SHARED_BUF_COUNT_SYM_NAME
, 0);
124 sb_desc
= nfp_pf_map_rtsym(pf
, "sb_tbl", NFP_SHARED_BUF_TABLE_SYM_NAME
,
125 num_entries
* sizeof(pf
->shared_bufs
[0]),
128 return PTR_ERR(sb_desc
);
130 entry_sz
= nfp_cpp_area_size(sb_desc_area
) / num_entries
;
132 pf
->shared_bufs
= kmalloc_array(num_entries
, sizeof(pf
->shared_bufs
[0]),
134 if (!pf
->shared_bufs
) {
136 goto err_release_area
;
139 for (i
= 0; i
< num_entries
; i
++) {
140 struct nfp_shared_buf
*sb
= &pf
->shared_bufs
[i
];
142 /* Entries may be larger in future FW */
143 memcpy_fromio(sb
, sb_desc
+ i
* entry_sz
, sizeof(*sb
));
145 err
= devlink_sb_register(devlink
,
147 le32_to_cpu(sb
->size
),
148 le16_to_cpu(sb
->ingress_pools_count
),
149 le16_to_cpu(sb
->egress_pools_count
),
150 le16_to_cpu(sb
->ingress_tc_count
),
151 le16_to_cpu(sb
->egress_tc_count
));
155 pf
->num_shared_bufs
= num_entries
;
157 nfp_cpp_area_release_free(sb_desc_area
);
163 devlink_sb_unregister(devlink
,
164 le32_to_cpu(pf
->shared_bufs
[i
].id
));
165 kfree(pf
->shared_bufs
);
167 nfp_cpp_area_release_free(sb_desc_area
);
171 void nfp_shared_buf_unregister(struct nfp_pf
*pf
)
173 struct devlink
*devlink
= priv_to_devlink(pf
);
176 for (i
= 0; i
< pf
->num_shared_bufs
; i
++)
177 devlink_sb_unregister(devlink
,
178 le32_to_cpu(pf
->shared_bufs
[i
].id
));
179 kfree(pf
->shared_bufs
);