Commit 57d316ba authored by Nogah Frankel's avatar Nogah Frankel Committed by David S. Miller

mlxsw: pci: Add resources query implementation.

Add resources query implementation. If exists, query the HW for its
builtin resources instead of having them as consts in the code.
Signed-off-by: default avatarNogah Frankel <nogahf@mellanox.com>
Reviewed-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bfe9b9d2
...@@ -105,6 +105,7 @@ enum mlxsw_cmd_opcode { ...@@ -105,6 +105,7 @@ enum mlxsw_cmd_opcode {
MLXSW_CMD_OPCODE_SW2HW_EQ = 0x013, MLXSW_CMD_OPCODE_SW2HW_EQ = 0x013,
MLXSW_CMD_OPCODE_HW2SW_EQ = 0x014, MLXSW_CMD_OPCODE_HW2SW_EQ = 0x014,
MLXSW_CMD_OPCODE_QUERY_EQ = 0x015, MLXSW_CMD_OPCODE_QUERY_EQ = 0x015,
MLXSW_CMD_OPCODE_QUERY_RESOURCES = 0x101,
}; };
static inline const char *mlxsw_cmd_opcode_str(u16 opcode) static inline const char *mlxsw_cmd_opcode_str(u16 opcode)
...@@ -144,6 +145,8 @@ static inline const char *mlxsw_cmd_opcode_str(u16 opcode) ...@@ -144,6 +145,8 @@ static inline const char *mlxsw_cmd_opcode_str(u16 opcode)
return "HW2SW_EQ"; return "HW2SW_EQ";
case MLXSW_CMD_OPCODE_QUERY_EQ: case MLXSW_CMD_OPCODE_QUERY_EQ:
return "QUERY_EQ"; return "QUERY_EQ";
case MLXSW_CMD_OPCODE_QUERY_RESOURCES:
return "QUERY_RESOURCES";
default: default:
return "*UNKNOWN*"; return "*UNKNOWN*";
} }
...@@ -500,6 +503,35 @@ static inline int mlxsw_cmd_unmap_fa(struct mlxsw_core *mlxsw_core) ...@@ -500,6 +503,35 @@ static inline int mlxsw_cmd_unmap_fa(struct mlxsw_core *mlxsw_core)
return mlxsw_cmd_exec_none(mlxsw_core, MLXSW_CMD_OPCODE_UNMAP_FA, 0, 0); return mlxsw_cmd_exec_none(mlxsw_core, MLXSW_CMD_OPCODE_UNMAP_FA, 0, 0);
} }
/* QUERY_RESOURCES - Query chip resources
* --------------------------------------
* OpMod == 0 (N/A) , INMmod is index
* ----------------------------------
* The QUERY_RESOURCES command retrieves information related to chip resources
* by resource ID. Every command returns 32 entries. INmod is being use as base.
* for example, index 1 will return entries 32-63. When the tables end and there
* are no more sources in the table, will return resource id 0xFFF to indicate
* it.
*/
static inline int mlxsw_cmd_query_resources(struct mlxsw_core *mlxsw_core,
char *out_mbox, int index)
{
return mlxsw_cmd_exec_out(mlxsw_core, MLXSW_CMD_OPCODE_QUERY_RESOURCES,
0, index, false, out_mbox,
MLXSW_CMD_MBOX_SIZE);
}
/* cmd_mbox_query_resource_id
* The resource id. 0xFFFF indicates table's end.
*/
MLXSW_ITEM32_INDEXED(cmd_mbox, query_resource, id, 0x00, 16, 16, 0x8, 0, false);
/* cmd_mbox_query_resource_data
* The resource
*/
MLXSW_ITEM64_INDEXED(cmd_mbox, query_resource, data,
0x00, 0, 40, 0x8, 0, false);
/* CONFIG_PROFILE (Set) - Configure Switch Profile /* CONFIG_PROFILE (Set) - Configure Switch Profile
* ------------------------------ * ------------------------------
* OpMod == 1 (Set), INMmod == 0 (N/A) * OpMod == 1 (Set), INMmod == 0 (N/A)
......
...@@ -111,6 +111,7 @@ struct mlxsw_core { ...@@ -111,6 +111,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_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 */
...@@ -1110,7 +1111,8 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, ...@@ -1110,7 +1111,8 @@ 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);
if (err) if (err)
goto err_bus_init; goto err_bus_init;
...@@ -1652,6 +1654,12 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core, ...@@ -1652,6 +1654,12 @@ 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)
{
return &mlxsw_core->resources;
}
EXPORT_SYMBOL(mlxsw_core_resources_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,
struct net_device *dev, bool split, u32 split_group) struct net_device *dev, bool split, u32 split_group)
......
...@@ -215,6 +215,7 @@ struct mlxsw_config_profile { ...@@ -215,6 +215,7 @@ struct mlxsw_config_profile {
u32 kvd_linear_size; u32 kvd_linear_size;
u32 kvd_hash_single_size; u32 kvd_hash_single_size;
u32 kvd_hash_double_size; u32 kvd_hash_double_size;
u8 resource_query_enable;
struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT]; struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
}; };
...@@ -266,10 +267,16 @@ struct mlxsw_driver { ...@@ -266,10 +267,16 @@ struct mlxsw_driver {
const struct mlxsw_config_profile *profile; const struct mlxsw_config_profile *profile;
}; };
struct mlxsw_resources {
};
struct mlxsw_resources *mlxsw_core_resources_get(struct mlxsw_core *mlxsw_core);
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);
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);
......
...@@ -1154,6 +1154,56 @@ mlxsw_pci_config_profile_swid_config(struct mlxsw_pci *mlxsw_pci, ...@@ -1154,6 +1154,56 @@ 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_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) {
default:
break;
}
}
static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox,
struct mlxsw_resources *resources,
u8 query_enabled)
{
int index, i;
u64 data;
u16 id;
int err;
/* Not all the versions support resources query */
if (!query_enabled)
return 0;
mlxsw_cmd_mbox_zero(mbox);
for (index = 0; index < MLXSW_RESOURCES_QUERY_MAX_QUERIES; index++) {
err = mlxsw_cmd_query_resources(mlxsw_pci->core, mbox, index);
if (err)
return err;
for (i = 0; i < MLXSW_RESOURCES_PER_QUERY; i++) {
id = mlxsw_cmd_mbox_query_resource_id_get(mbox, i);
data = mlxsw_cmd_mbox_query_resource_data_get(mbox, i);
if (id == MLXSW_RESOURCES_TABLE_END_ID)
return 0;
mlxsw_pci_resources_query_parse(id, data, resources);
}
}
/* If after MLXSW_RESOURCES_QUERY_MAX_QUERIES we still didn't get
* MLXSW_RESOURCES_TABLE_END_ID, something went bad in the FW.
*/
return -EIO;
}
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)
{ {
...@@ -1404,7 +1454,8 @@ static void mlxsw_pci_mbox_free(struct mlxsw_pci *mlxsw_pci, ...@@ -1404,7 +1454,8 @@ 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_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;
...@@ -1463,6 +1514,11 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core, ...@@ -1463,6 +1514,11 @@ 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,
profile->resource_query_enable);
if (err)
goto err_query_resources;
err = mlxsw_pci_config_profile(mlxsw_pci, mbox, profile); err = mlxsw_pci_config_profile(mlxsw_pci, mbox, profile);
if (err) if (err)
goto err_config_profile; goto err_config_profile;
...@@ -1485,6 +1541,7 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core, ...@@ -1485,6 +1541,7 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
mlxsw_pci_aqs_fini(mlxsw_pci); mlxsw_pci_aqs_fini(mlxsw_pci);
err_aqs_init: err_aqs_init:
err_config_profile: err_config_profile:
err_query_resources:
err_boardinfo: err_boardinfo:
mlxsw_pci_fw_area_fini(mlxsw_pci); mlxsw_pci_fw_area_fini(mlxsw_pci);
err_fw_area_init: err_fw_area_init:
......
...@@ -2488,6 +2488,7 @@ static struct mlxsw_config_profile mlxsw_sp_config_profile = { ...@@ -2488,6 +2488,7 @@ static struct mlxsw_config_profile mlxsw_sp_config_profile = {
.type = MLXSW_PORT_SWID_TYPE_ETH, .type = MLXSW_PORT_SWID_TYPE_ETH,
} }
}, },
.resource_query_enable = 1,
}; };
static struct mlxsw_driver mlxsw_sp_driver = { static struct mlxsw_driver mlxsw_sp_driver = {
......
...@@ -1541,6 +1541,7 @@ static struct mlxsw_config_profile mlxsw_sx_config_profile = { ...@@ -1541,6 +1541,7 @@ static struct mlxsw_config_profile mlxsw_sx_config_profile = {
.type = MLXSW_PORT_SWID_TYPE_ETH, .type = MLXSW_PORT_SWID_TYPE_ETH,
} }
}, },
.resource_query_enable = 0,
}; };
static struct mlxsw_driver mlxsw_sx_driver = { static struct mlxsw_driver mlxsw_sx_driver = {
......
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