Skip to content

Commit

Permalink
mlxsw: Convert resources into array
Browse files Browse the repository at this point in the history
Since the number of resources is going to get much bigger, ease up the
addition by simly defining IDs. Convert the existing structure members
to a set array, one for validity, one for values. Introduce a set of
getters and setters for easy access.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jiri Pirko authored and David S. Miller committed Oct 23, 2016
1 parent f38a231 commit c1a3831
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 190 deletions.
32 changes: 21 additions & 11 deletions drivers/net/ethernet/mellanox/mlxsw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "trap.h"
#include "emad.h"
#include "reg.h"
#include "resources.h"

static LIST_HEAD(mlxsw_core_driver_list);
static DEFINE_SPINLOCK(mlxsw_core_driver_list_lock);
Expand Down Expand Up @@ -111,7 +112,7 @@ struct mlxsw_core {
struct {
u8 *mapping; /* lag_id+port_index to local_port mapping */
} lag;
struct mlxsw_resources resources;
struct mlxsw_res res;
struct mlxsw_hwmon *hwmon;
unsigned long driver_priv[0];
/* driver_priv has to be always the last item */
Expand Down Expand Up @@ -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,
&mlxsw_core->resources);
&mlxsw_core->res);
if (err)
goto err_bus_init;

if (mlxsw_core->resources.max_lag_valid &&
mlxsw_core->resources.max_ports_in_lag_valid) {
alloc_size = sizeof(u8) * mlxsw_core->resources.max_lag *
mlxsw_core->resources.max_ports_in_lag;
if (MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG) &&
MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG_MEMBERS)) {
alloc_size = sizeof(u8) *
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);
if (!mlxsw_core->lag.mapping) {
err = -ENOMEM;
Expand Down Expand Up @@ -1615,7 +1617,7 @@ EXPORT_SYMBOL(mlxsw_core_skb_receive);
static int mlxsw_core_lag_mapping_index(struct mlxsw_core *mlxsw_core,
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;
}

Expand Down Expand Up @@ -1644,7 +1646,7 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
{
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,
lag_id, i);

Expand All @@ -1654,11 +1656,19 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
}
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,
struct mlxsw_core_port *mlxsw_core_port, u8 local_port,
Expand Down
44 changes: 11 additions & 33 deletions drivers/net/ethernet/mellanox/mlxsw/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@

#include "trap.h"
#include "reg.h"

#include "cmd.h"
#include "resources.h"

#define MLXSW_MODULE_ALIAS_PREFIX "mlxsw-driver-"
#define MODULE_MLXSW_DRIVER_ALIAS(kind) \
Expand Down Expand Up @@ -266,45 +266,23 @@ struct mlxsw_driver {
const struct mlxsw_config_profile *profile;
};

struct mlxsw_resources {
u32 max_span_valid:1,
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;
bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
enum mlxsw_res_id res_id);

/* Internal resources.
* Determined by the SW, not queried from the HW.
*/
u32 kvd_single_size;
u32 kvd_double_size;
u32 kvd_linear_size;
};
#define MLXSW_CORE_RES_VALID(res, short_res_id) \
mlxsw_core_res_valid(res, MLXSW_RES_ID_##short_res_id)

u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
enum mlxsw_res_id res_id);

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 {
const char *kind;
int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
const struct mlxsw_config_profile *profile,
struct mlxsw_resources *resources);
struct mlxsw_res *res);
void (*fini)(void *bus_priv);
bool (*skb_transmit_busy)(void *bus_priv,
const struct mlxsw_tx_info *tx_info);
Expand Down
127 changes: 32 additions & 95 deletions drivers/net/ethernet/mellanox/mlxsw/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include "core.h"
#include "cmd.h"
#include "port.h"
#include "resources.h"

static const char mlxsw_pci_driver_name[] = "mlxsw_pci";

Expand Down Expand Up @@ -1155,73 +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);
}

#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

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,
struct mlxsw_resources *resources,
struct mlxsw_res *res,
u8 query_enabled)
{
int index, i;
Expand All @@ -1248,7 +1184,7 @@ static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox,
if (id == MLXSW_CMD_QUERY_RESOURCES_TABLE_END_ID)
return 0;

mlxsw_pci_resources_query_parse(id, data, resources);
mlxsw_res_parse(res, id, data);
}
}

Expand All @@ -1258,13 +1194,14 @@ static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox,
return -EIO;
}

static int mlxsw_pci_profile_get_kvd_sizes(const struct mlxsw_config_profile *profile,
struct mlxsw_resources *resources)
static int
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 ||
!resources->kvd_double_min_size_valid ||
if (!MLXSW_RES_VALID(res, KVD_SINGLE_MIN_SIZE) ||
!MLXSW_RES_VALID(res, KVD_DOUBLE_MIN_SIZE) ||
!profile->used_kvd_split_data)
return -EIO;

Expand All @@ -1276,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
* granularity from the profile.
*/
doubles_size = (resources->kvd_size - linear_size);
doubles_size *= profile->kvd_hash_double_parts;
doubles_size /= (profile->kvd_hash_double_parts +
profile->kvd_hash_single_parts);
doubles_size /= profile->kvd_hash_granularity;
doubles_size *= profile->kvd_hash_granularity;
singles_size = resources->kvd_size - doubles_size -
linear_size;
double_size = MLXSW_RES_GET(res, KVD_SIZE) - linear_size;
double_size *= profile->kvd_hash_double_parts;
double_size /= profile->kvd_hash_double_parts +
profile->kvd_hash_single_parts;
double_size /= profile->kvd_hash_granularity;
double_size *= profile->kvd_hash_granularity;
single_size = MLXSW_RES_GET(res, KVD_SIZE) - double_size -
linear_size;

/* Check results are legal. */
if (singles_size < resources->kvd_single_min_size ||
doubles_size < resources->kvd_double_min_size ||
resources->kvd_size < linear_size)
if (single_size < MLXSW_RES_GET(res, KVD_SINGLE_MIN_SIZE) ||
double_size < MLXSW_RES_GET(res, KVD_DOUBLE_MIN_SIZE) ||
MLXSW_RES_GET(res, KVD_SIZE) < linear_size)
return -EIO;

resources->kvd_single_size = singles_size;
resources->kvd_double_size = doubles_size;
resources->kvd_linear_size = linear_size;
MLXSW_RES_SET(res, KVD_SINGLE_SIZE, single_size);
MLXSW_RES_SET(res, KVD_DOUBLE_SIZE, double_size);
MLXSW_RES_SET(res, KVD_LINEAR_SIZE, linear_size);

return 0;
}

static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox,
const struct mlxsw_config_profile *profile,
struct mlxsw_resources *resources)
struct mlxsw_res *res)
{
int i;
int err;
Expand Down Expand Up @@ -1389,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(
mbox, profile->adaptive_routing_group_cap);
}
if (resources->kvd_size_valid) {
err = mlxsw_pci_profile_get_kvd_sizes(profile, resources);
if (MLXSW_RES_VALID(res, KVD_SIZE)) {
err = mlxsw_pci_profile_get_kvd_sizes(profile, res);
if (err)
return err;

mlxsw_cmd_mbox_config_profile_set_kvd_linear_size_set(mbox, 1);
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,
1);
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(
mbox, 1);
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++)
Expand Down Expand Up @@ -1542,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,
const struct mlxsw_config_profile *profile,
struct mlxsw_resources *resources)
struct mlxsw_res *res)
{
struct mlxsw_pci *mlxsw_pci = bus_priv;
struct pci_dev *pdev = mlxsw_pci->pdev;
Expand Down Expand Up @@ -1601,12 +1538,12 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
if (err)
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);
if (err)
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)
goto err_config_profile;

Expand Down
Loading

0 comments on commit c1a3831

Please sign in to comment.