Commit 1bac9381 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-cosmetics-plus-res-mgmt-rewrite'

Jiri Pirko says:

====================
mlxsw: Driver update

Mostly cosmetics and small resource values management rewrite.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 67dc1596 c1a38311
...@@ -513,6 +513,11 @@ static inline int mlxsw_cmd_unmap_fa(struct mlxsw_core *mlxsw_core) ...@@ -513,6 +513,11 @@ static inline int mlxsw_cmd_unmap_fa(struct mlxsw_core *mlxsw_core)
* are no more sources in the table, will return resource id 0xFFF to indicate * are no more sources in the table, will return resource id 0xFFF to indicate
* it. * it.
*/ */
#define MLXSW_CMD_QUERY_RESOURCES_TABLE_END_ID 0xffff
#define MLXSW_CMD_QUERY_RESOURCES_MAX_QUERIES 100
#define MLXSW_CMD_QUERY_RESOURCES_PER_QUERY 32
static inline int mlxsw_cmd_query_resources(struct mlxsw_core *mlxsw_core, static inline int mlxsw_cmd_query_resources(struct mlxsw_core *mlxsw_core,
char *out_mbox, int index) char *out_mbox, int index)
{ {
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#include "trap.h" #include "trap.h"
#include "emad.h" #include "emad.h"
#include "reg.h" #include "reg.h"
#include "resources.h"
static LIST_HEAD(mlxsw_core_driver_list); static LIST_HEAD(mlxsw_core_driver_list);
static DEFINE_SPINLOCK(mlxsw_core_driver_list_lock); static DEFINE_SPINLOCK(mlxsw_core_driver_list_lock);
...@@ -111,7 +112,7 @@ struct mlxsw_core { ...@@ -111,7 +112,7 @@ struct mlxsw_core {
struct { struct {
u8 *mapping; /* lag_id+port_index to local_port mapping */ u8 *mapping; /* lag_id+port_index to local_port mapping */
} lag; } lag;
struct mlxsw_resources resources; struct mlxsw_res res;
struct mlxsw_hwmon *hwmon; struct mlxsw_hwmon *hwmon;
unsigned long driver_priv[0]; unsigned long driver_priv[0];
/* driver_priv has to be always the last item */ /* driver_priv has to be always the last item */
...@@ -1101,14 +1102,15 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, ...@@ -1101,14 +1102,15 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
} }
err = mlxsw_bus->init(bus_priv, mlxsw_core, mlxsw_driver->profile, err = mlxsw_bus->init(bus_priv, mlxsw_core, mlxsw_driver->profile,
&mlxsw_core->resources); &mlxsw_core->res);
if (err) if (err)
goto err_bus_init; goto err_bus_init;
if (mlxsw_core->resources.max_lag_valid && if (MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG) &&
mlxsw_core->resources.max_ports_in_lag_valid) { MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG_MEMBERS)) {
alloc_size = sizeof(u8) * mlxsw_core->resources.max_lag * alloc_size = sizeof(u8) *
mlxsw_core->resources.max_ports_in_lag; MLXSW_CORE_RES_GET(mlxsw_core, MAX_LAG) *
MLXSW_CORE_RES_GET(mlxsw_core, MAX_LAG_MEMBERS);
mlxsw_core->lag.mapping = kzalloc(alloc_size, GFP_KERNEL); mlxsw_core->lag.mapping = kzalloc(alloc_size, GFP_KERNEL);
if (!mlxsw_core->lag.mapping) { if (!mlxsw_core->lag.mapping) {
err = -ENOMEM; err = -ENOMEM;
...@@ -1615,7 +1617,7 @@ EXPORT_SYMBOL(mlxsw_core_skb_receive); ...@@ -1615,7 +1617,7 @@ EXPORT_SYMBOL(mlxsw_core_skb_receive);
static int mlxsw_core_lag_mapping_index(struct mlxsw_core *mlxsw_core, static int mlxsw_core_lag_mapping_index(struct mlxsw_core *mlxsw_core,
u16 lag_id, u8 port_index) u16 lag_id, u8 port_index)
{ {
return mlxsw_core->resources.max_ports_in_lag * lag_id + return MLXSW_CORE_RES_GET(mlxsw_core, MAX_LAG_MEMBERS) * lag_id +
port_index; port_index;
} }
...@@ -1644,7 +1646,7 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core, ...@@ -1644,7 +1646,7 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
{ {
int i; int i;
for (i = 0; i < mlxsw_core->resources.max_ports_in_lag; i++) { for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_core, MAX_LAG_MEMBERS); i++) {
int index = mlxsw_core_lag_mapping_index(mlxsw_core, int index = mlxsw_core_lag_mapping_index(mlxsw_core,
lag_id, i); lag_id, i);
...@@ -1654,11 +1656,19 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core, ...@@ -1654,11 +1656,19 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
} }
EXPORT_SYMBOL(mlxsw_core_lag_mapping_clear); EXPORT_SYMBOL(mlxsw_core_lag_mapping_clear);
struct mlxsw_resources *mlxsw_core_resources_get(struct mlxsw_core *mlxsw_core) bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
enum mlxsw_res_id res_id)
{ {
return &mlxsw_core->resources; return mlxsw_res_valid(&mlxsw_core->res, res_id);
} }
EXPORT_SYMBOL(mlxsw_core_resources_get); EXPORT_SYMBOL(mlxsw_core_res_valid);
u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
enum mlxsw_res_id res_id)
{
return mlxsw_res_get(&mlxsw_core->res, res_id);
}
EXPORT_SYMBOL(mlxsw_core_res_get);
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core,
struct mlxsw_core_port *mlxsw_core_port, u8 local_port, struct mlxsw_core_port *mlxsw_core_port, u8 local_port,
......
...@@ -48,8 +48,8 @@ ...@@ -48,8 +48,8 @@
#include "trap.h" #include "trap.h"
#include "reg.h" #include "reg.h"
#include "cmd.h" #include "cmd.h"
#include "resources.h"
#define MLXSW_MODULE_ALIAS_PREFIX "mlxsw-driver-" #define MLXSW_MODULE_ALIAS_PREFIX "mlxsw-driver-"
#define MODULE_MLXSW_DRIVER_ALIAS(kind) \ #define MODULE_MLXSW_DRIVER_ALIAS(kind) \
...@@ -266,45 +266,23 @@ struct mlxsw_driver { ...@@ -266,45 +266,23 @@ struct mlxsw_driver {
const struct mlxsw_config_profile *profile; const struct mlxsw_config_profile *profile;
}; };
struct mlxsw_resources { bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
u32 max_span_valid:1, enum mlxsw_res_id res_id);
max_lag_valid:1,
max_ports_in_lag_valid:1,
kvd_size_valid:1,
kvd_single_min_size_valid:1,
kvd_double_min_size_valid:1,
max_virtual_routers_valid:1,
max_system_ports_valid:1,
max_vlan_groups_valid:1,
max_regions_valid:1,
max_rif_valid:1;
u8 max_span;
u8 max_lag;
u8 max_ports_in_lag;
u32 kvd_size;
u32 kvd_single_min_size;
u32 kvd_double_min_size;
u16 max_virtual_routers;
u16 max_system_ports;
u16 max_vlan_groups;
u16 max_regions;
u16 max_rif;
/* Internal resources. #define MLXSW_CORE_RES_VALID(res, short_res_id) \
* Determined by the SW, not queried from the HW. mlxsw_core_res_valid(res, MLXSW_RES_ID_##short_res_id)
*/
u32 kvd_single_size; u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
u32 kvd_double_size; enum mlxsw_res_id res_id);
u32 kvd_linear_size;
};
struct mlxsw_resources *mlxsw_core_resources_get(struct mlxsw_core *mlxsw_core); #define MLXSW_CORE_RES_GET(res, short_res_id) \
mlxsw_core_res_get(res, MLXSW_RES_ID_##short_res_id)
struct mlxsw_bus { struct mlxsw_bus {
const char *kind; const char *kind;
int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core, int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
const struct mlxsw_config_profile *profile, const struct mlxsw_config_profile *profile,
struct mlxsw_resources *resources); struct mlxsw_res *res);
void (*fini)(void *bus_priv); void (*fini)(void *bus_priv);
bool (*skb_transmit_busy)(void *bus_priv, bool (*skb_transmit_busy)(void *bus_priv,
const struct mlxsw_tx_info *tx_info); const struct mlxsw_tx_info *tx_info);
......
...@@ -55,7 +55,7 @@ struct mlxsw_item { ...@@ -55,7 +55,7 @@ struct mlxsw_item {
}; };
static inline unsigned int static inline unsigned int
__mlxsw_item_offset(struct mlxsw_item *item, unsigned short index, __mlxsw_item_offset(const struct mlxsw_item *item, unsigned short index,
size_t typesize) size_t typesize)
{ {
BUG_ON(index && !item->step); BUG_ON(index && !item->step);
...@@ -72,7 +72,8 @@ __mlxsw_item_offset(struct mlxsw_item *item, unsigned short index, ...@@ -72,7 +72,8 @@ __mlxsw_item_offset(struct mlxsw_item *item, unsigned short index,
typesize); typesize);
} }
static inline u16 __mlxsw_item_get16(char *buf, struct mlxsw_item *item, static inline u16 __mlxsw_item_get16(const char *buf,
const struct mlxsw_item *item,
unsigned short index) unsigned short index)
{ {
unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u16)); unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u16));
...@@ -87,7 +88,7 @@ static inline u16 __mlxsw_item_get16(char *buf, struct mlxsw_item *item, ...@@ -87,7 +88,7 @@ static inline u16 __mlxsw_item_get16(char *buf, struct mlxsw_item *item,
return tmp; return tmp;
} }
static inline void __mlxsw_item_set16(char *buf, struct mlxsw_item *item, static inline void __mlxsw_item_set16(char *buf, const struct mlxsw_item *item,
unsigned short index, u16 val) unsigned short index, u16 val)
{ {
unsigned int offset = __mlxsw_item_offset(item, index, unsigned int offset = __mlxsw_item_offset(item, index,
...@@ -105,7 +106,8 @@ static inline void __mlxsw_item_set16(char *buf, struct mlxsw_item *item, ...@@ -105,7 +106,8 @@ static inline void __mlxsw_item_set16(char *buf, struct mlxsw_item *item,
b[offset] = cpu_to_be16(tmp); b[offset] = cpu_to_be16(tmp);
} }
static inline u32 __mlxsw_item_get32(char *buf, struct mlxsw_item *item, static inline u32 __mlxsw_item_get32(const char *buf,
const struct mlxsw_item *item,
unsigned short index) unsigned short index)
{ {
unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u32)); unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u32));
...@@ -120,7 +122,7 @@ static inline u32 __mlxsw_item_get32(char *buf, struct mlxsw_item *item, ...@@ -120,7 +122,7 @@ static inline u32 __mlxsw_item_get32(char *buf, struct mlxsw_item *item,
return tmp; return tmp;
} }
static inline void __mlxsw_item_set32(char *buf, struct mlxsw_item *item, static inline void __mlxsw_item_set32(char *buf, const struct mlxsw_item *item,
unsigned short index, u32 val) unsigned short index, u32 val)
{ {
unsigned int offset = __mlxsw_item_offset(item, index, unsigned int offset = __mlxsw_item_offset(item, index,
...@@ -138,7 +140,8 @@ static inline void __mlxsw_item_set32(char *buf, struct mlxsw_item *item, ...@@ -138,7 +140,8 @@ static inline void __mlxsw_item_set32(char *buf, struct mlxsw_item *item,
b[offset] = cpu_to_be32(tmp); b[offset] = cpu_to_be32(tmp);
} }
static inline u64 __mlxsw_item_get64(char *buf, struct mlxsw_item *item, static inline u64 __mlxsw_item_get64(const char *buf,
const struct mlxsw_item *item,
unsigned short index) unsigned short index)
{ {
unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64)); unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64));
...@@ -153,7 +156,7 @@ static inline u64 __mlxsw_item_get64(char *buf, struct mlxsw_item *item, ...@@ -153,7 +156,7 @@ static inline u64 __mlxsw_item_get64(char *buf, struct mlxsw_item *item,
return tmp; return tmp;
} }
static inline void __mlxsw_item_set64(char *buf, struct mlxsw_item *item, static inline void __mlxsw_item_set64(char *buf, const struct mlxsw_item *item,
unsigned short index, u64 val) unsigned short index, u64 val)
{ {
unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64)); unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64));
...@@ -170,8 +173,8 @@ static inline void __mlxsw_item_set64(char *buf, struct mlxsw_item *item, ...@@ -170,8 +173,8 @@ static inline void __mlxsw_item_set64(char *buf, struct mlxsw_item *item,
b[offset] = cpu_to_be64(tmp); b[offset] = cpu_to_be64(tmp);
} }
static inline void __mlxsw_item_memcpy_from(char *buf, char *dst, static inline void __mlxsw_item_memcpy_from(const char *buf, char *dst,
struct mlxsw_item *item, const struct mlxsw_item *item,
unsigned short index) unsigned short index)
{ {
unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char)); unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char));
...@@ -180,7 +183,7 @@ static inline void __mlxsw_item_memcpy_from(char *buf, char *dst, ...@@ -180,7 +183,7 @@ static inline void __mlxsw_item_memcpy_from(char *buf, char *dst,
} }
static inline void __mlxsw_item_memcpy_to(char *buf, const char *src, static inline void __mlxsw_item_memcpy_to(char *buf, const char *src,
struct mlxsw_item *item, const struct mlxsw_item *item,
unsigned short index) unsigned short index)
{ {
unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char)); unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char));
...@@ -189,7 +192,8 @@ static inline void __mlxsw_item_memcpy_to(char *buf, const char *src, ...@@ -189,7 +192,8 @@ static inline void __mlxsw_item_memcpy_to(char *buf, const char *src,
} }
static inline u16 static inline u16
__mlxsw_item_bit_array_offset(struct mlxsw_item *item, u16 index, u8 *shift) __mlxsw_item_bit_array_offset(const struct mlxsw_item *item,
u16 index, u8 *shift)
{ {
u16 max_index, be_index; u16 max_index, be_index;
u16 offset; /* byte offset inside the array */ u16 offset; /* byte offset inside the array */
...@@ -212,7 +216,8 @@ __mlxsw_item_bit_array_offset(struct mlxsw_item *item, u16 index, u8 *shift) ...@@ -212,7 +216,8 @@ __mlxsw_item_bit_array_offset(struct mlxsw_item *item, u16 index, u8 *shift)
return item->offset + offset; return item->offset + offset;
} }
static inline u8 __mlxsw_item_bit_array_get(char *buf, struct mlxsw_item *item, static inline u8 __mlxsw_item_bit_array_get(const char *buf,
const struct mlxsw_item *item,
u16 index) u16 index)
{ {
u8 shift, tmp; u8 shift, tmp;
...@@ -224,7 +229,8 @@ static inline u8 __mlxsw_item_bit_array_get(char *buf, struct mlxsw_item *item, ...@@ -224,7 +229,8 @@ static inline u8 __mlxsw_item_bit_array_get(char *buf, struct mlxsw_item *item,
return tmp; return tmp;
} }
static inline void __mlxsw_item_bit_array_set(char *buf, struct mlxsw_item *item, static inline void __mlxsw_item_bit_array_set(char *buf,
const struct mlxsw_item *item,
u16 index, u8 val) u16 index, u8 val)
{ {
u8 shift, tmp; u8 shift, tmp;
...@@ -254,7 +260,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ ...@@ -254,7 +260,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \
.size = {.bits = _sizebits,}, \ .size = {.bits = _sizebits,}, \
.name = #_type "_" #_cname "_" #_iname, \ .name = #_type "_" #_cname "_" #_iname, \
}; \ }; \
static inline u16 mlxsw_##_type##_##_cname##_##_iname##_get(char *buf) \ static inline u16 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \
{ \ { \
return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \
} \ } \
...@@ -275,7 +281,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ ...@@ -275,7 +281,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \
.name = #_type "_" #_cname "_" #_iname, \ .name = #_type "_" #_cname "_" #_iname, \
}; \ }; \
static inline u16 \ static inline u16 \
mlxsw_##_type##_##_cname##_##_iname##_get(char *buf, unsigned short index) \ mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\
{ \ { \
return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), \ return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), \
index); \ index); \
...@@ -295,7 +301,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ ...@@ -295,7 +301,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \
.size = {.bits = _sizebits,}, \ .size = {.bits = _sizebits,}, \
.name = #_type "_" #_cname "_" #_iname, \ .name = #_type "_" #_cname "_" #_iname, \
}; \ }; \
static inline u32 mlxsw_##_type##_##_cname##_##_iname##_get(char *buf) \ static inline u32 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \
{ \ { \
return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \
} \ } \
...@@ -316,7 +322,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ ...@@ -316,7 +322,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \
.name = #_type "_" #_cname "_" #_iname, \ .name = #_type "_" #_cname "_" #_iname, \
}; \ }; \
static inline u32 \ static inline u32 \
mlxsw_##_type##_##_cname##_##_iname##_get(char *buf, unsigned short index) \ mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\
{ \ { \
return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), \ return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), \
index); \ index); \
...@@ -336,7 +342,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ ...@@ -336,7 +342,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \
.size = {.bits = _sizebits,}, \ .size = {.bits = _sizebits,}, \
.name = #_type "_" #_cname "_" #_iname, \ .name = #_type "_" #_cname "_" #_iname, \
}; \ }; \
static inline u64 mlxsw_##_type##_##_cname##_##_iname##_get(char *buf) \ static inline u64 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \
{ \ { \
return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \
} \ } \
...@@ -357,7 +363,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ ...@@ -357,7 +363,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \
.name = #_type "_" #_cname "_" #_iname, \ .name = #_type "_" #_cname "_" #_iname, \
}; \ }; \
static inline u64 \ static inline u64 \
mlxsw_##_type##_##_cname##_##_iname##_get(char *buf, unsigned short index) \ mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\
{ \ { \
return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), \ return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), \
index); \ index); \
...@@ -377,7 +383,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ ...@@ -377,7 +383,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \
.name = #_type "_" #_cname "_" #_iname, \ .name = #_type "_" #_cname "_" #_iname, \
}; \ }; \
static inline void \ static inline void \
mlxsw_##_type##_##_cname##_##_iname##_memcpy_from(char *buf, char *dst) \ mlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf, char *dst) \
{ \ { \
__mlxsw_item_memcpy_from(buf, dst, \ __mlxsw_item_memcpy_from(buf, dst, \
&__ITEM_NAME(_type, _cname, _iname), 0); \ &__ITEM_NAME(_type, _cname, _iname), 0); \
...@@ -399,7 +405,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ ...@@ -399,7 +405,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \
.name = #_type "_" #_cname "_" #_iname, \ .name = #_type "_" #_cname "_" #_iname, \
}; \ }; \
static inline void \ static inline void \
mlxsw_##_type##_##_cname##_##_iname##_memcpy_from(char *buf, \ mlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf, \
unsigned short index, \ unsigned short index, \
char *dst) \ char *dst) \
{ \ { \
...@@ -424,7 +430,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ ...@@ -424,7 +430,7 @@ static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \
.name = #_type "_" #_cname "_" #_iname, \ .name = #_type "_" #_cname "_" #_iname, \
}; \ }; \
static inline u8 \ static inline u8 \
mlxsw_##_type##_##_cname##_##_iname##_get(char *buf, u16 index) \ mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, u16 index) \
{ \ { \
return __mlxsw_item_bit_array_get(buf, \ return __mlxsw_item_bit_array_get(buf, \
&__ITEM_NAME(_type, _cname, _iname), \ &__ITEM_NAME(_type, _cname, _iname), \
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "core.h" #include "core.h"
#include "cmd.h" #include "cmd.h"
#include "port.h" #include "port.h"
#include "resources.h"
static const char mlxsw_pci_driver_name[] = "mlxsw_pci"; static const char mlxsw_pci_driver_name[] = "mlxsw_pci";
...@@ -238,8 +239,9 @@ static bool mlxsw_pci_elem_hw_owned(struct mlxsw_pci_queue *q, bool owner_bit) ...@@ -238,8 +239,9 @@ static bool mlxsw_pci_elem_hw_owned(struct mlxsw_pci_queue *q, bool owner_bit)
return owner_bit != !!(q->consumer_counter & q->count); return owner_bit != !!(q->consumer_counter & q->count);
} }
static char *mlxsw_pci_queue_sw_elem_get(struct mlxsw_pci_queue *q, static char *
u32 (*get_elem_owner_func)(char *)) mlxsw_pci_queue_sw_elem_get(struct mlxsw_pci_queue *q,
u32 (*get_elem_owner_func)(const char *))
{ {
struct mlxsw_pci_queue_elem_info *elem_info; struct mlxsw_pci_queue_elem_info *elem_info;
char *elem; char *elem;
...@@ -1154,76 +1156,8 @@ mlxsw_pci_config_profile_swid_config(struct mlxsw_pci *mlxsw_pci, ...@@ -1154,76 +1156,8 @@ mlxsw_pci_config_profile_swid_config(struct mlxsw_pci *mlxsw_pci,
mlxsw_cmd_mbox_config_profile_swid_config_mask_set(mbox, index, mask); mlxsw_cmd_mbox_config_profile_swid_config_mask_set(mbox, index, mask);
} }
#define MLXSW_RESOURCES_TABLE_END_ID 0xffff
#define MLXSW_MAX_SPAN_ID 0x2420
#define MLXSW_MAX_LAG_ID 0x2520
#define MLXSW_MAX_PORTS_IN_LAG_ID 0x2521
#define MLXSW_KVD_SIZE_ID 0x1001
#define MLXSW_KVD_SINGLE_MIN_SIZE_ID 0x1002
#define MLXSW_KVD_DOUBLE_MIN_SIZE_ID 0x1003
#define MLXSW_MAX_VIRTUAL_ROUTERS_ID 0x2C01
#define MLXSW_MAX_SYSTEM_PORT_ID 0x2502
#define MLXSW_MAX_VLAN_GROUPS_ID 0x2906
#define MLXSW_MAX_REGIONS_ID 0x2901
#define MLXSW_MAX_RIF_ID 0x2C02
#define MLXSW_RESOURCES_QUERY_MAX_QUERIES 100
#define MLXSW_RESOURCES_PER_QUERY 32
static void mlxsw_pci_resources_query_parse(int id, u64 val,
struct mlxsw_resources *resources)
{
switch (id) {
case MLXSW_MAX_SPAN_ID:
resources->max_span = val;
resources->max_span_valid = 1;
break;
case MLXSW_MAX_LAG_ID:
resources->max_lag = val;
resources->max_lag_valid = 1;
break;
case MLXSW_MAX_PORTS_IN_LAG_ID:
resources->max_ports_in_lag = val;
resources->max_ports_in_lag_valid = 1;
break;
case MLXSW_KVD_SIZE_ID:
resources->kvd_size = val;
resources->kvd_size_valid = 1;
break;
case MLXSW_KVD_SINGLE_MIN_SIZE_ID:
resources->kvd_single_min_size = val;
resources->kvd_single_min_size_valid = 1;
break;
case MLXSW_KVD_DOUBLE_MIN_SIZE_ID:
resources->kvd_double_min_size = val;
resources->kvd_double_min_size_valid = 1;
break;
case MLXSW_MAX_VIRTUAL_ROUTERS_ID:
resources->max_virtual_routers = val;
resources->max_virtual_routers_valid = 1;
break;
case MLXSW_MAX_SYSTEM_PORT_ID:
resources->max_system_ports = val;
resources->max_system_ports_valid = 1;
break;
case MLXSW_MAX_VLAN_GROUPS_ID:
resources->max_vlan_groups = val;
resources->max_vlan_groups_valid = 1;
break;
case MLXSW_MAX_REGIONS_ID:
resources->max_regions = val;
resources->max_regions_valid = 1;
break;
case MLXSW_MAX_RIF_ID:
resources->max_rif = val;
resources->max_rif_valid = 1;
break;
default:
break;
}
}
static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox, static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox,
struct mlxsw_resources *resources, struct mlxsw_res *res,
u8 query_enabled) u8 query_enabled)
{ {
int index, i; int index, i;
...@@ -1237,19 +1171,20 @@ static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -1237,19 +1171,20 @@ static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox,
mlxsw_cmd_mbox_zero(mbox); mlxsw_cmd_mbox_zero(mbox);
for (index = 0; index < MLXSW_RESOURCES_QUERY_MAX_QUERIES; index++) { for (index = 0; index < MLXSW_CMD_QUERY_RESOURCES_MAX_QUERIES;
index++) {
err = mlxsw_cmd_query_resources(mlxsw_pci->core, mbox, index); err = mlxsw_cmd_query_resources(mlxsw_pci->core, mbox, index);
if (err) if (err)
return err; return err;
for (i = 0; i < MLXSW_RESOURCES_PER_QUERY; i++) { for (i = 0; i < MLXSW_CMD_QUERY_RESOURCES_PER_QUERY; i++) {
id = mlxsw_cmd_mbox_query_resource_id_get(mbox, i); id = mlxsw_cmd_mbox_query_resource_id_get(mbox, i);
data = mlxsw_cmd_mbox_query_resource_data_get(mbox, i); data = mlxsw_cmd_mbox_query_resource_data_get(mbox, i);
if (id == MLXSW_RESOURCES_TABLE_END_ID) if (id == MLXSW_CMD_QUERY_RESOURCES_TABLE_END_ID)
return 0; return 0;
mlxsw_pci_resources_query_parse(id, data, resources); mlxsw_res_parse(res, id, data);
} }
} }
...@@ -1259,13 +1194,14 @@ static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -1259,13 +1194,14 @@ static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox,
return -EIO; return -EIO;
} }
static int mlxsw_pci_profile_get_kvd_sizes(const struct mlxsw_config_profile *profile, static int
struct mlxsw_resources *resources) mlxsw_pci_profile_get_kvd_sizes(const struct mlxsw_config_profile *profile,
struct mlxsw_res *res)
{ {
u32 singles_size, doubles_size, linear_size; u32 single_size, double_size, linear_size;
if (!resources->kvd_single_min_size_valid || if (!MLXSW_RES_VALID(res, KVD_SINGLE_MIN_SIZE) ||
!resources->kvd_double_min_size_valid || !MLXSW_RES_VALID(res, KVD_DOUBLE_MIN_SIZE) ||
!profile->used_kvd_split_data) !profile->used_kvd_split_data)
return -EIO; return -EIO;
...@@ -1277,31 +1213,31 @@ static int mlxsw_pci_profile_get_kvd_sizes(const struct mlxsw_config_profile *pr ...@@ -1277,31 +1213,31 @@ static int mlxsw_pci_profile_get_kvd_sizes(const struct mlxsw_config_profile *pr
* Both sizes must be a multiplications of the * Both sizes must be a multiplications of the
* granularity from the profile. * granularity from the profile.
*/ */
doubles_size = (resources->kvd_size - linear_size); double_size = MLXSW_RES_GET(res, KVD_SIZE) - linear_size;
doubles_size *= profile->kvd_hash_double_parts; double_size *= profile->kvd_hash_double_parts;
doubles_size /= (profile->kvd_hash_double_parts + double_size /= profile->kvd_hash_double_parts +
profile->kvd_hash_single_parts); profile->kvd_hash_single_parts;
doubles_size /= profile->kvd_hash_granularity; double_size /= profile->kvd_hash_granularity;
doubles_size *= profile->kvd_hash_granularity; double_size *= profile->kvd_hash_granularity;
singles_size = resources->kvd_size - doubles_size - single_size = MLXSW_RES_GET(res, KVD_SIZE) - double_size -
linear_size; linear_size;
/* Check results are legal. */ /* Check results are legal. */
if (singles_size < resources->kvd_single_min_size || if (single_size < MLXSW_RES_GET(res, KVD_SINGLE_MIN_SIZE) ||
doubles_size < resources->kvd_double_min_size || double_size < MLXSW_RES_GET(res, KVD_DOUBLE_MIN_SIZE) ||
resources->kvd_size < linear_size) MLXSW_RES_GET(res, KVD_SIZE) < linear_size)
return -EIO; return -EIO;
resources->kvd_single_size = singles_size; MLXSW_RES_SET(res, KVD_SINGLE_SIZE, single_size);
resources->kvd_double_size = doubles_size; MLXSW_RES_SET(res, KVD_DOUBLE_SIZE, double_size);
resources->kvd_linear_size = linear_size; MLXSW_RES_SET(res, KVD_LINEAR_SIZE, linear_size);
return 0; return 0;
} }
static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox, static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox,
const struct mlxsw_config_profile *profile, const struct mlxsw_config_profile *profile,
struct mlxsw_resources *resources) struct mlxsw_res *res)
{ {
int i; int i;
int err; int err;
...@@ -1390,22 +1326,22 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox, ...@@ -1390,22 +1326,22 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox,
mlxsw_cmd_mbox_config_profile_adaptive_routing_group_cap_set( mlxsw_cmd_mbox_config_profile_adaptive_routing_group_cap_set(
mbox, profile->adaptive_routing_group_cap); mbox, profile->adaptive_routing_group_cap);
} }
if (resources->kvd_size_valid) { if (MLXSW_RES_VALID(res, KVD_SIZE)) {
err = mlxsw_pci_profile_get_kvd_sizes(profile, resources); err = mlxsw_pci_profile_get_kvd_sizes(profile, res);
if (err) if (err)
return err; return err;
mlxsw_cmd_mbox_config_profile_set_kvd_linear_size_set(mbox, 1); mlxsw_cmd_mbox_config_profile_set_kvd_linear_size_set(mbox, 1);
mlxsw_cmd_mbox_config_profile_kvd_linear_size_set(mbox, mlxsw_cmd_mbox_config_profile_kvd_linear_size_set(mbox,
resources->kvd_linear_size); MLXSW_RES_GET(res, KVD_LINEAR_SIZE));
mlxsw_cmd_mbox_config_profile_set_kvd_hash_single_size_set(mbox, mlxsw_cmd_mbox_config_profile_set_kvd_hash_single_size_set(mbox,
1); 1);
mlxsw_cmd_mbox_config_profile_kvd_hash_single_size_set(mbox, mlxsw_cmd_mbox_config_profile_kvd_hash_single_size_set(mbox,
resources->kvd_single_size); MLXSW_RES_GET(res, KVD_SINGLE_SIZE));
mlxsw_cmd_mbox_config_profile_set_kvd_hash_double_size_set( mlxsw_cmd_mbox_config_profile_set_kvd_hash_double_size_set(
mbox, 1); mbox, 1);
mlxsw_cmd_mbox_config_profile_kvd_hash_double_size_set(mbox, mlxsw_cmd_mbox_config_profile_kvd_hash_double_size_set(mbox,
resources->kvd_double_size); MLXSW_RES_GET(res, KVD_DOUBLE_SIZE));
} }
for (i = 0; i < MLXSW_CONFIG_PROFILE_SWID_COUNT; i++) for (i = 0; i < MLXSW_CONFIG_PROFILE_SWID_COUNT; i++)
...@@ -1543,7 +1479,7 @@ static void mlxsw_pci_mbox_free(struct mlxsw_pci *mlxsw_pci, ...@@ -1543,7 +1479,7 @@ static void mlxsw_pci_mbox_free(struct mlxsw_pci *mlxsw_pci,
static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core, static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
const struct mlxsw_config_profile *profile, const struct mlxsw_config_profile *profile,
struct mlxsw_resources *resources) struct mlxsw_res *res)
{ {
struct mlxsw_pci *mlxsw_pci = bus_priv; struct mlxsw_pci *mlxsw_pci = bus_priv;
struct pci_dev *pdev = mlxsw_pci->pdev; struct pci_dev *pdev = mlxsw_pci->pdev;
...@@ -1602,12 +1538,12 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core, ...@@ -1602,12 +1538,12 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
if (err) if (err)
goto err_boardinfo; goto err_boardinfo;
err = mlxsw_pci_resources_query(mlxsw_pci, mbox, resources, err = mlxsw_pci_resources_query(mlxsw_pci, mbox, res,
profile->resource_query_enable); profile->resource_query_enable);
if (err) if (err)
goto err_query_resources; goto err_query_resources;
err = mlxsw_pci_config_profile(mlxsw_pci, mbox, profile, resources); err = mlxsw_pci_config_profile(mlxsw_pci, mbox, profile, res);
if (err) if (err)
goto err_config_profile; goto err_config_profile;
......
This diff is collapsed.
/*
* drivers/net/ethernet/mellanox/mlxsw/resources.h
* Copyright (c) 2016 Mellanox Technologies. All rights reserved.
* Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MLXSW_RESOURCES_H
#define _MLXSW_RESOURCES_H
#include <linux/kernel.h>
#include <linux/types.h>
enum mlxsw_res_id {
MLXSW_RES_ID_KVD_SIZE,
MLXSW_RES_ID_KVD_SINGLE_MIN_SIZE,
MLXSW_RES_ID_KVD_DOUBLE_MIN_SIZE,
MLXSW_RES_ID_MAX_SPAN,
MLXSW_RES_ID_MAX_SYSTEM_PORT,
MLXSW_RES_ID_MAX_LAG,
MLXSW_RES_ID_MAX_LAG_MEMBERS,
MLXSW_RES_ID_MAX_VRS,
MLXSW_RES_ID_MAX_RIFS,
/* Internal resources.
* Determined by the SW, not queried from the HW.
*/
MLXSW_RES_ID_KVD_SINGLE_SIZE,
MLXSW_RES_ID_KVD_DOUBLE_SIZE,
MLXSW_RES_ID_KVD_LINEAR_SIZE,
__MLXSW_RES_ID_MAX,
};
static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_KVD_SIZE] = 0x1001,
[MLXSW_RES_ID_KVD_SINGLE_MIN_SIZE] = 0x1002,
[MLXSW_RES_ID_KVD_DOUBLE_MIN_SIZE] = 0x1003,
[MLXSW_RES_ID_MAX_SPAN] = 0x2420,
[MLXSW_RES_ID_MAX_SYSTEM_PORT] = 0x2502,
[MLXSW_RES_ID_MAX_LAG] = 0x2520,
[MLXSW_RES_ID_MAX_LAG_MEMBERS] = 0x2521,
[MLXSW_RES_ID_MAX_VRS] = 0x2C01,
[MLXSW_RES_ID_MAX_RIFS] = 0x2C02,
};
struct mlxsw_res {
bool valid[__MLXSW_RES_ID_MAX];
u64 values[__MLXSW_RES_ID_MAX];
};
static inline bool mlxsw_res_valid(struct mlxsw_res *res,
enum mlxsw_res_id res_id)
{
return res->valid[res_id];
}
#define MLXSW_RES_VALID(res, short_res_id) \
mlxsw_res_valid(res, MLXSW_RES_ID_##short_res_id)
static inline u64 mlxsw_res_get(struct mlxsw_res *res,
enum mlxsw_res_id res_id)
{
if (WARN_ON(!res->valid[res_id]))
return 0;
return res->values[res_id];
}
#define MLXSW_RES_GET(res, short_res_id) \
mlxsw_res_get(res, MLXSW_RES_ID_##short_res_id)
static inline void mlxsw_res_set(struct mlxsw_res *res,
enum mlxsw_res_id res_id, u64 value)
{
res->valid[res_id] = true;
res->values[res_id] = value;
}
#define MLXSW_RES_SET(res, short_res_id, value) \
mlxsw_res_set(res, MLXSW_RES_ID_##short_res_id, value)
static inline void mlxsw_res_parse(struct mlxsw_res *res, u16 id, u64 value)
{
int i;
for (i = 0; i < ARRAY_SIZE(mlxsw_res_ids); i++) {
if (mlxsw_res_ids[i] == id) {
mlxsw_res_set(res, i, value);
return;
}
}
}
#endif
...@@ -168,14 +168,13 @@ static int mlxsw_sp_base_mac_get(struct mlxsw_sp *mlxsw_sp) ...@@ -168,14 +168,13 @@ static int mlxsw_sp_base_mac_get(struct mlxsw_sp *mlxsw_sp)
static int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp) static int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_resources *resources;
int i; int i;
resources = mlxsw_core_resources_get(mlxsw_sp->core); if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_SPAN))
if (!resources->max_span_valid)
return -EIO; return -EIO;
mlxsw_sp->span.entries_count = resources->max_span; mlxsw_sp->span.entries_count = MLXSW_CORE_RES_GET(mlxsw_sp->core,
MAX_SPAN);
mlxsw_sp->span.entries = kcalloc(mlxsw_sp->span.entries_count, mlxsw_sp->span.entries = kcalloc(mlxsw_sp->span.entries_count,
sizeof(struct mlxsw_sp_span_entry), sizeof(struct mlxsw_sp_span_entry),
GFP_KERNEL); GFP_KERNEL);
...@@ -1413,7 +1412,7 @@ static int mlxsw_sp_port_set_pauseparam(struct net_device *dev, ...@@ -1413,7 +1412,7 @@ static int mlxsw_sp_port_set_pauseparam(struct net_device *dev,
struct mlxsw_sp_port_hw_stats { struct mlxsw_sp_port_hw_stats {
char str[ETH_GSTRING_LEN]; char str[ETH_GSTRING_LEN];
u64 (*getter)(char *payload); u64 (*getter)(const char *payload);
}; };
static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = { static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = {
...@@ -1534,7 +1533,7 @@ static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = { ...@@ -1534,7 +1533,7 @@ static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = {
#define MLXSW_SP_PORT_HW_PRIO_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_prio_stats) #define MLXSW_SP_PORT_HW_PRIO_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_prio_stats)
static u64 mlxsw_reg_ppcnt_tc_transmit_queue_bytes_get(char *ppcnt_pl) static u64 mlxsw_reg_ppcnt_tc_transmit_queue_bytes_get(const char *ppcnt_pl)
{ {
u64 transmit_queue = mlxsw_reg_ppcnt_tc_transmit_queue_get(ppcnt_pl); u64 transmit_queue = mlxsw_reg_ppcnt_tc_transmit_queue_get(ppcnt_pl);
...@@ -2892,7 +2891,6 @@ static int mlxsw_sp_flood_init(struct mlxsw_sp *mlxsw_sp) ...@@ -2892,7 +2891,6 @@ static int mlxsw_sp_flood_init(struct mlxsw_sp *mlxsw_sp)
static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp) static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_resources *resources;
char slcr_pl[MLXSW_REG_SLCR_LEN]; char slcr_pl[MLXSW_REG_SLCR_LEN];
int err; int err;
...@@ -2909,11 +2907,11 @@ static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp) ...@@ -2909,11 +2907,11 @@ static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
if (err) if (err)
return err; return err;
resources = mlxsw_core_resources_get(mlxsw_sp->core); if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG) ||
if (!(resources->max_lag_valid && resources->max_ports_in_lag_valid)) !MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG_MEMBERS))
return -EIO; return -EIO;
mlxsw_sp->lags = kcalloc(resources->max_lag, mlxsw_sp->lags = kcalloc(MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LAG),
sizeof(struct mlxsw_sp_upper), sizeof(struct mlxsw_sp_upper),
GFP_KERNEL); GFP_KERNEL);
if (!mlxsw_sp->lags) if (!mlxsw_sp->lags)
...@@ -3183,11 +3181,9 @@ static bool mlxsw_sp_rif_should_config(struct mlxsw_sp_rif *r, ...@@ -3183,11 +3181,9 @@ static bool mlxsw_sp_rif_should_config(struct mlxsw_sp_rif *r,
static int mlxsw_sp_avail_rif_get(struct mlxsw_sp *mlxsw_sp) static int mlxsw_sp_avail_rif_get(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_resources *resources;
int i; int i;
resources = mlxsw_core_resources_get(mlxsw_sp->core); for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++)
for (i = 0; i < resources->max_rif; i++)
if (!mlxsw_sp->rifs[i]) if (!mlxsw_sp->rifs[i])
return i; return i;
...@@ -3710,14 +3706,15 @@ static bool mlxsw_sp_port_fdb_should_flush(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -3710,14 +3706,15 @@ static bool mlxsw_sp_port_fdb_should_flush(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
u8 local_port = mlxsw_sp_port->local_port; u8 local_port = mlxsw_sp_port->local_port;
u16 lag_id = mlxsw_sp_port->lag_id; u16 lag_id = mlxsw_sp_port->lag_id;
struct mlxsw_resources *resources; u64 max_lag_members;
int i, count = 0; int i, count = 0;
if (!mlxsw_sp_port->lagged) if (!mlxsw_sp_port->lagged)
return true; return true;
resources = mlxsw_core_resources_get(mlxsw_sp->core); max_lag_members = MLXSW_CORE_RES_GET(mlxsw_sp->core,
for (i = 0; i < resources->max_ports_in_lag; i++) { MAX_LAG_MEMBERS);
for (i = 0; i < max_lag_members; i++) {
struct mlxsw_sp_port *lag_port; struct mlxsw_sp_port *lag_port;
lag_port = mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i); lag_port = mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i);
...@@ -3923,13 +3920,13 @@ static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp, ...@@ -3923,13 +3920,13 @@ static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
struct net_device *lag_dev, struct net_device *lag_dev,
u16 *p_lag_id) u16 *p_lag_id)
{ {
struct mlxsw_resources *resources;
struct mlxsw_sp_upper *lag; struct mlxsw_sp_upper *lag;
int free_lag_id = -1; int free_lag_id = -1;
u64 max_lag;
int i; int i;
resources = mlxsw_core_resources_get(mlxsw_sp->core); max_lag = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LAG);
for (i = 0; i < resources->max_lag; i++) { for (i = 0; i < max_lag; i++) {
lag = mlxsw_sp_lag_get(mlxsw_sp, i); lag = mlxsw_sp_lag_get(mlxsw_sp, i);
if (lag->ref_count) { if (lag->ref_count) {
if (lag->dev == lag_dev) { if (lag->dev == lag_dev) {
...@@ -3963,11 +3960,12 @@ mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp, ...@@ -3963,11 +3960,12 @@ mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
static int mlxsw_sp_port_lag_index_get(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_port_lag_index_get(struct mlxsw_sp *mlxsw_sp,
u16 lag_id, u8 *p_port_index) u16 lag_id, u8 *p_port_index)
{ {
struct mlxsw_resources *resources; u64 max_lag_members;
int i; int i;
resources = mlxsw_core_resources_get(mlxsw_sp->core); max_lag_members = MLXSW_CORE_RES_GET(mlxsw_sp->core,
for (i = 0; i < resources->max_ports_in_lag; i++) { MAX_LAG_MEMBERS);
for (i = 0; i < max_lag_members; i++) {
if (!mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i)) { if (!mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i)) {
*p_port_index = i; *p_port_index = i;
return 0; return 0;
......
...@@ -479,12 +479,9 @@ static inline struct mlxsw_sp_rif * ...@@ -479,12 +479,9 @@ static inline struct mlxsw_sp_rif *
mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp, mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp,
const struct net_device *dev) const struct net_device *dev)
{ {
struct mlxsw_resources *resources;
int i; int i;
resources = mlxsw_core_resources_get(mlxsw_sp->core); for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++)
for (i = 0; i < resources->max_rif; i++)
if (mlxsw_sp->rifs[i] && mlxsw_sp->rifs[i]->dev == dev) if (mlxsw_sp->rifs[i] && mlxsw_sp->rifs[i]->dev == dev)
return mlxsw_sp->rifs[i]; return mlxsw_sp->rifs[i];
......
...@@ -379,12 +379,10 @@ static void mlxsw_sp_lpm_init(struct mlxsw_sp *mlxsw_sp) ...@@ -379,12 +379,10 @@ static void mlxsw_sp_lpm_init(struct mlxsw_sp *mlxsw_sp)
static struct mlxsw_sp_vr *mlxsw_sp_vr_find_unused(struct mlxsw_sp *mlxsw_sp) static struct mlxsw_sp_vr *mlxsw_sp_vr_find_unused(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_resources *resources;
struct mlxsw_sp_vr *vr; struct mlxsw_sp_vr *vr;
int i; int i;
resources = mlxsw_core_resources_get(mlxsw_sp->core); for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
for (i = 0; i < resources->max_virtual_routers; i++) {
vr = &mlxsw_sp->router.vrs[i]; vr = &mlxsw_sp->router.vrs[i];
if (!vr->used) if (!vr->used)
return vr; return vr;
...@@ -426,14 +424,12 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_find(struct mlxsw_sp *mlxsw_sp, ...@@ -426,14 +424,12 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_find(struct mlxsw_sp *mlxsw_sp,
u32 tb_id, u32 tb_id,
enum mlxsw_sp_l3proto proto) enum mlxsw_sp_l3proto proto)
{ {
struct mlxsw_resources *resources;
struct mlxsw_sp_vr *vr; struct mlxsw_sp_vr *vr;
int i; int i;
tb_id = mlxsw_sp_fix_tb_id(tb_id); tb_id = mlxsw_sp_fix_tb_id(tb_id);
resources = mlxsw_core_resources_get(mlxsw_sp->core); for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
for (i = 0; i < resources->max_virtual_routers; i++) {
vr = &mlxsw_sp->router.vrs[i]; vr = &mlxsw_sp->router.vrs[i];
if (vr->used && vr->proto == proto && vr->tb_id == tb_id) if (vr->used && vr->proto == proto && vr->tb_id == tb_id)
return vr; return vr;
...@@ -569,21 +565,20 @@ static void mlxsw_sp_vr_put(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr) ...@@ -569,21 +565,20 @@ static void mlxsw_sp_vr_put(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr)
static int mlxsw_sp_vrs_init(struct mlxsw_sp *mlxsw_sp) static int mlxsw_sp_vrs_init(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_resources *resources;
struct mlxsw_sp_vr *vr; struct mlxsw_sp_vr *vr;
u64 max_vrs;
int i; int i;
resources = mlxsw_core_resources_get(mlxsw_sp->core); if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_VRS))
if (!resources->max_virtual_routers_valid)
return -EIO; return -EIO;
mlxsw_sp->router.vrs = kcalloc(resources->max_virtual_routers, max_vrs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS);
sizeof(struct mlxsw_sp_vr), mlxsw_sp->router.vrs = kcalloc(max_vrs, sizeof(struct mlxsw_sp_vr),
GFP_KERNEL); GFP_KERNEL);
if (!mlxsw_sp->router.vrs) if (!mlxsw_sp->router.vrs)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < resources->max_virtual_routers; i++) { for (i = 0; i < max_vrs; i++) {
vr = &mlxsw_sp->router.vrs[i]; vr = &mlxsw_sp->router.vrs[i];
vr->id = i; vr->id = i;
} }
...@@ -1875,15 +1870,13 @@ static int mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp) ...@@ -1875,15 +1870,13 @@ static int mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp)
static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp) static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_resources *resources;
struct mlxsw_sp_fib_entry *fib_entry; struct mlxsw_sp_fib_entry *fib_entry;
struct mlxsw_sp_fib_entry *tmp; struct mlxsw_sp_fib_entry *tmp;
struct mlxsw_sp_vr *vr; struct mlxsw_sp_vr *vr;
int i; int i;
int err; int err;
resources = mlxsw_core_resources_get(mlxsw_sp->core); for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
for (i = 0; i < resources->max_virtual_routers; i++) {
vr = &mlxsw_sp->router.vrs[i]; vr = &mlxsw_sp->router.vrs[i];
if (!vr->used) if (!vr->used)
continue; continue;
...@@ -1908,21 +1901,21 @@ static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp) ...@@ -1908,21 +1901,21 @@ static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp)
static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_resources *resources;
char rgcr_pl[MLXSW_REG_RGCR_LEN]; char rgcr_pl[MLXSW_REG_RGCR_LEN];
u64 max_rifs;
int err; int err;
resources = mlxsw_core_resources_get(mlxsw_sp->core); if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_RIFS))
if (!resources->max_rif_valid)
return -EIO; return -EIO;
mlxsw_sp->rifs = kcalloc(resources->max_rif, max_rifs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
sizeof(struct mlxsw_sp_rif *), GFP_KERNEL); mlxsw_sp->rifs = kcalloc(max_rifs, sizeof(struct mlxsw_sp_rif *),
GFP_KERNEL);
if (!mlxsw_sp->rifs) if (!mlxsw_sp->rifs)
return -ENOMEM; return -ENOMEM;
mlxsw_reg_rgcr_pack(rgcr_pl, true); mlxsw_reg_rgcr_pack(rgcr_pl, true);
mlxsw_reg_rgcr_max_router_interfaces_set(rgcr_pl, resources->max_rif); mlxsw_reg_rgcr_max_router_interfaces_set(rgcr_pl, max_rifs);
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl);
if (err) if (err)
goto err_rgcr_fail; goto err_rgcr_fail;
...@@ -1936,15 +1929,13 @@ static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) ...@@ -1936,15 +1929,13 @@ static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
static void __mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) static void __mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_resources *resources;
char rgcr_pl[MLXSW_REG_RGCR_LEN]; char rgcr_pl[MLXSW_REG_RGCR_LEN];
int i; int i;
mlxsw_reg_rgcr_pack(rgcr_pl, false); mlxsw_reg_rgcr_pack(rgcr_pl, false);
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl); mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl);
resources = mlxsw_core_resources_get(mlxsw_sp->core); for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++)
for (i = 0; i < resources->max_rif; i++)
WARN_ON_ONCE(mlxsw_sp->rifs[i]); WARN_ON_ONCE(mlxsw_sp->rifs[i]);
kfree(mlxsw_sp->rifs); kfree(mlxsw_sp->rifs);
......
...@@ -1196,11 +1196,12 @@ static struct mlxsw_sp_port *mlxsw_sp_lag_rep_port(struct mlxsw_sp *mlxsw_sp, ...@@ -1196,11 +1196,12 @@ static struct mlxsw_sp_port *mlxsw_sp_lag_rep_port(struct mlxsw_sp *mlxsw_sp,
u16 lag_id) u16 lag_id)
{ {
struct mlxsw_sp_port *mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port;
struct mlxsw_resources *resources; u64 max_lag_members;
int i; int i;
resources = mlxsw_core_resources_get(mlxsw_sp->core); max_lag_members = MLXSW_CORE_RES_GET(mlxsw_sp->core,
for (i = 0; i < resources->max_ports_in_lag; i++) { MAX_LAG_MEMBERS);
for (i = 0; i < max_lag_members; i++) {
mlxsw_sp_port = mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i); mlxsw_sp_port = mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i);
if (mlxsw_sp_port) if (mlxsw_sp_port)
return mlxsw_sp_port; return mlxsw_sp_port;
......
...@@ -410,7 +410,7 @@ static void mlxsw_sx_port_get_drvinfo(struct net_device *dev, ...@@ -410,7 +410,7 @@ static void mlxsw_sx_port_get_drvinfo(struct net_device *dev,
struct mlxsw_sx_port_hw_stats { struct mlxsw_sx_port_hw_stats {
char str[ETH_GSTRING_LEN]; char str[ETH_GSTRING_LEN];
u64 (*getter)(char *payload); u64 (*getter)(const char *payload);
}; };
static const struct mlxsw_sx_port_hw_stats mlxsw_sx_port_hw_stats[] = { static const struct mlxsw_sx_port_hw_stats mlxsw_sx_port_hw_stats[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment