Skip to content

Commit

Permalink
Merge branch 'mlxsw-More-Spectrum-2-preparations'
Browse files Browse the repository at this point in the history
aIdo Schimmel says:

====================
mlxsw: More Spectrum-2 preparations

This is the second and last set of preparations towards initial
Spectrum-2 support in mlxsw. It mainly re-arranges parts of the code
that need to work with both ASICs, but somewhat differ.

The first three patches allow different ASICs to register different set
of operations for KVD linear (KVDL) management. In Spectrum-2 there is
no linear memory and instead entries that reside there in Spectrum
(e.g., nexthops) are hashed and inserted to the hash-based KVD memory.

The fourth patch does a similar restructuring in the low-level multicast
router code. This is necessary because multicast routing is implemented
using regular circuit TCAM (C-TCAM) in Spectrum, whereas Spectrum-2 uses
an algorithmic TCAM (A-TCAM).

Next six patches prepare the ACL code for the introduction of A-TCAM in
follow-up patch sets.

Last two patches allow different ASICs to require different firmware
versions and add two resources that need to be queried from firmware by
Spectrum-2 specific code.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 9, 2018
2 parents eec4edc + a8b9f23 commit 1497d2f
Show file tree
Hide file tree
Showing 21 changed files with 1,924 additions and 1,099 deletions.
15 changes: 10 additions & 5 deletions drivers/net/ethernet/mellanox/mlxsw/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ mlxsw_switchx2-objs := switchx2.o
obj-$(CONFIG_MLXSW_SPECTRUM) += mlxsw_spectrum.o
mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
spectrum_switchdev.o spectrum_router.o \
spectrum_kvdl.o spectrum_acl_tcam.o \
spectrum_acl.o spectrum_flower.o \
spectrum_cnt.o spectrum_fid.o \
spectrum_ipip.o spectrum_acl_flex_actions.o \
spectrum_mr.o spectrum_mr_tcam.o \
spectrum1_kvdl.o spectrum_kvdl.o \
spectrum_acl_tcam.o spectrum_acl_ctcam.o \
spectrum1_acl_tcam.o \
spectrum_acl.o \
spectrum_flower.o spectrum_cnt.o \
spectrum_fid.o spectrum_ipip.o \
spectrum_acl_flex_actions.o \
spectrum_acl_flex_keys.o \
spectrum1_mr_tcam.o \
spectrum_mr_tcam.o spectrum_mr.o \
spectrum_qdisc.o spectrum_span.o
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o
Expand Down
58 changes: 11 additions & 47 deletions drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
struct mlxsw_afk {
struct list_head key_info_list;
unsigned int max_blocks;
const struct mlxsw_afk_ops *ops;
const struct mlxsw_afk_block *blocks;
unsigned int blocks_count;
};
Expand All @@ -69,8 +70,7 @@ static bool mlxsw_afk_blocks_check(struct mlxsw_afk *mlxsw_afk)
}

struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
const struct mlxsw_afk_block *blocks,
unsigned int blocks_count)
const struct mlxsw_afk_ops *ops)
{
struct mlxsw_afk *mlxsw_afk;

Expand All @@ -79,8 +79,9 @@ struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
return NULL;
INIT_LIST_HEAD(&mlxsw_afk->key_info_list);
mlxsw_afk->max_blocks = max_blocks;
mlxsw_afk->blocks = blocks;
mlxsw_afk->blocks_count = blocks_count;
mlxsw_afk->ops = ops;
mlxsw_afk->blocks = ops->blocks;
mlxsw_afk->blocks_count = ops->blocks_count;
WARN_ON(!mlxsw_afk_blocks_check(mlxsw_afk));
return mlxsw_afk;
}
Expand Down Expand Up @@ -415,45 +416,8 @@ void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
}
EXPORT_SYMBOL(mlxsw_afk_values_add_buf);

static void mlxsw_afk_encode_u32(const struct mlxsw_item *storage_item,
const struct mlxsw_item *output_item,
char *storage, char *output_indexed)
{
u32 value;

value = __mlxsw_item_get32(storage, storage_item, 0);
__mlxsw_item_set32(output_indexed, output_item, 0, value);
}

static void mlxsw_afk_encode_buf(const struct mlxsw_item *storage_item,
const struct mlxsw_item *output_item,
char *storage, char *output_indexed)
{
char *storage_data = __mlxsw_item_data(storage, storage_item, 0);
char *output_data = __mlxsw_item_data(output_indexed, output_item, 0);
size_t len = output_item->size.bytes;

memcpy(output_data, storage_data, len);
}

#define MLXSW_AFK_KEY_BLOCK_SIZE 16

static void mlxsw_afk_encode_one(const struct mlxsw_afk_element_inst *elinst,
int block_index, char *storage, char *output)
{
char *output_indexed = output + block_index * MLXSW_AFK_KEY_BLOCK_SIZE;
const struct mlxsw_item *storage_item = &elinst->info->item;
const struct mlxsw_item *output_item = &elinst->item;

if (elinst->type == MLXSW_AFK_ELEMENT_TYPE_U32)
mlxsw_afk_encode_u32(storage_item, output_item,
storage, output_indexed);
else if (elinst->type == MLXSW_AFK_ELEMENT_TYPE_BUF)
mlxsw_afk_encode_buf(storage_item, output_item,
storage, output_indexed);
}

void mlxsw_afk_encode(struct mlxsw_afk_key_info *key_info,
void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
struct mlxsw_afk_key_info *key_info,
struct mlxsw_afk_element_values *values,
char *key, char *mask)
{
Expand All @@ -466,10 +430,10 @@ void mlxsw_afk_encode(struct mlxsw_afk_key_info *key_info,
&block_index);
if (!elinst)
continue;
mlxsw_afk_encode_one(elinst, block_index,
values->storage.key, key);
mlxsw_afk_encode_one(elinst, block_index,
values->storage.mask, mask);
mlxsw_afk->ops->encode_one(elinst, block_index,
values->storage.key, key);
mlxsw_afk->ops->encode_one(elinst, block_index,
values->storage.mask, mask);
}
}
EXPORT_SYMBOL(mlxsw_afk_encode);
13 changes: 10 additions & 3 deletions drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,15 @@ mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,

struct mlxsw_afk;

struct mlxsw_afk_ops {
const struct mlxsw_afk_block *blocks;
unsigned int blocks_count;
void (*encode_one)(const struct mlxsw_afk_element_inst *elinst,
int block_index, char *storage, char *output);
};

struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
const struct mlxsw_afk_block *blocks,
unsigned int blocks_count);
const struct mlxsw_afk_ops *ops);
void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);

struct mlxsw_afk_key_info;
Expand Down Expand Up @@ -251,7 +257,8 @@ void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
enum mlxsw_afk_element element,
const char *key_value, const char *mask_value,
unsigned int len);
void mlxsw_afk_encode(struct mlxsw_afk_key_info *key_info,
void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
struct mlxsw_afk_key_info *key_info,
struct mlxsw_afk_element_values *values,
char *key, char *mask);

Expand Down
12 changes: 11 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -2402,6 +2402,15 @@ MLXSW_ITEM32(reg, ptce2, op, 0x00, 20, 3);
*/
MLXSW_ITEM32(reg, ptce2, offset, 0x00, 0, 16);

/* reg_ptce2_priority
* Priority of the rule, higher values win. The range is 1..cap_kvd_size-1.
* Note: priority does not have to be unique per rule.
* Within a region, higher priority should have lower offset (no limitation
* between regions in a multi-region).
* Access: RW
*/
MLXSW_ITEM32(reg, ptce2, priority, 0x04, 0, 24);

/* reg_ptce2_tcam_region_info
* Opaque object that represents the TCAM region.
* Access: Index
Expand Down Expand Up @@ -2437,12 +2446,13 @@ MLXSW_ITEM_BUF(reg, ptce2, flex_action_set, 0xE0,
static inline void mlxsw_reg_ptce2_pack(char *payload, bool valid,
enum mlxsw_reg_ptce2_op op,
const char *tcam_region_info,
u16 offset)
u16 offset, u32 priority)
{
MLXSW_REG_ZERO(ptce2, payload);
mlxsw_reg_ptce2_v_set(payload, valid);
mlxsw_reg_ptce2_op_set(payload, op);
mlxsw_reg_ptce2_offset_set(payload, offset);
mlxsw_reg_ptce2_priority_set(payload, priority);
mlxsw_reg_ptce2_tcam_region_info_memcpy_to(payload, tcam_region_info);
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ 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_KVD_LINEAR_RANGE,
MLXSW_RES_ID_MAX_KVD_ACTION_SETS,
MLXSW_RES_ID_MAX_TRAP_GROUPS,
MLXSW_RES_ID_CQE_V0,
MLXSW_RES_ID_CQE_V1,
Expand Down Expand Up @@ -83,6 +85,8 @@ 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_KVD_LINEAR_RANGE] = 0x1005,
[MLXSW_RES_ID_MAX_KVD_ACTION_SETS] = 0x1007,
[MLXSW_RES_ID_MAX_TRAP_GROUPS] = 0x2201,
[MLXSW_RES_ID_CQE_V0] = 0x2210,
[MLXSW_RES_ID_CQE_V1] = 0x2211,
Expand Down
53 changes: 36 additions & 17 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,22 @@
#include "spectrum_span.h"
#include "../mlxfw/mlxfw.h"

#define MLXSW_FWREV_MAJOR 13
#define MLXSW_FWREV_MINOR 1620
#define MLXSW_FWREV_SUBMINOR 192
#define MLXSW_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)
#define MLXSW_SP_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)

#define MLXSW_SP_FW_FILENAME \
"mellanox/mlxsw_spectrum-" __stringify(MLXSW_FWREV_MAJOR) \
"." __stringify(MLXSW_FWREV_MINOR) \
"." __stringify(MLXSW_FWREV_SUBMINOR) ".mfa2"
#define MLXSW_SP1_FWREV_MAJOR 13
#define MLXSW_SP1_FWREV_MINOR 1620
#define MLXSW_SP1_FWREV_SUBMINOR 192

static const struct mlxsw_fw_rev mlxsw_sp1_fw_rev = {
.major = MLXSW_SP1_FWREV_MAJOR,
.minor = MLXSW_SP1_FWREV_MINOR,
.subminor = MLXSW_SP1_FWREV_SUBMINOR,
};

#define MLXSW_SP1_FW_FILENAME \
"mellanox/mlxsw_spectrum-" __stringify(MLXSW_SP1_FWREV_MAJOR) \
"." __stringify(MLXSW_SP1_FWREV_MINOR) \
"." __stringify(MLXSW_SP1_FWREV_SUBMINOR) ".mfa2"

static const char mlxsw_sp_driver_name[] = "mlxsw_spectrum";
static const char mlxsw_sp_driver_version[] = "1.0";
Expand Down Expand Up @@ -338,29 +345,35 @@ static int mlxsw_sp_firmware_flash(struct mlxsw_sp *mlxsw_sp,
static int mlxsw_sp_fw_rev_validate(struct mlxsw_sp *mlxsw_sp)
{
const struct mlxsw_fw_rev *rev = &mlxsw_sp->bus_info->fw_rev;
const struct mlxsw_fw_rev *req_rev = mlxsw_sp->req_rev;
const char *fw_filename = mlxsw_sp->fw_filename;
const struct firmware *firmware;
int err;

/* Don't check if driver does not require it */
if (!req_rev || !fw_filename)
return 0;

/* Validate driver & FW are compatible */
if (rev->major != MLXSW_FWREV_MAJOR) {
if (rev->major != req_rev->major) {
WARN(1, "Mismatch in major FW version [%d:%d] is never expected; Please contact support\n",
rev->major, MLXSW_FWREV_MAJOR);
rev->major, req_rev->major);
return -EINVAL;
}
if (MLXSW_FWREV_MINOR_TO_BRANCH(rev->minor) ==
MLXSW_FWREV_MINOR_TO_BRANCH(MLXSW_FWREV_MINOR))
if (MLXSW_SP_FWREV_MINOR_TO_BRANCH(rev->minor) ==
MLXSW_SP_FWREV_MINOR_TO_BRANCH(req_rev->minor))
return 0;

dev_info(mlxsw_sp->bus_info->dev, "The firmware version %d.%d.%d is incompatible with the driver\n",
rev->major, rev->minor, rev->subminor);
dev_info(mlxsw_sp->bus_info->dev, "Flashing firmware using file %s\n",
MLXSW_SP_FW_FILENAME);
fw_filename);

err = request_firmware_direct(&firmware, MLXSW_SP_FW_FILENAME,
err = request_firmware_direct(&firmware, fw_filename,
mlxsw_sp->bus_info->dev);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Could not request firmware file %s\n",
MLXSW_SP_FW_FILENAME);
fw_filename);
return err;
}

Expand Down Expand Up @@ -3621,7 +3634,13 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
int err;

mlxsw_sp->req_rev = &mlxsw_sp1_fw_rev;
mlxsw_sp->fw_filename = MLXSW_SP1_FW_FILENAME;
mlxsw_sp->kvdl_ops = &mlxsw_sp1_kvdl_ops;
mlxsw_sp->afa_ops = &mlxsw_sp1_act_afa_ops;
mlxsw_sp->afk_ops = &mlxsw_sp1_afk_ops;
mlxsw_sp->mr_tcam_ops = &mlxsw_sp1_mr_tcam_ops;
mlxsw_sp->acl_tcam_ops = &mlxsw_sp1_acl_tcam_ops;

mlxsw_sp->core = mlxsw_core;
mlxsw_sp->bus_info = mlxsw_bus_info;
Expand Down Expand Up @@ -3880,7 +3899,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
if (err)
return err;

err = mlxsw_sp_kvdl_resources_register(mlxsw_core);
err = mlxsw_sp1_kvdl_resources_register(mlxsw_core);
if (err)
return err;

Expand Down Expand Up @@ -4741,4 +4760,4 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
MODULE_DESCRIPTION("Mellanox Spectrum driver");
MODULE_DEVICE_TABLE(pci, mlxsw_sp_pci_id_table);
MODULE_FIRMWARE(MLXSW_SP_FW_FILENAME);
MODULE_FIRMWARE(MLXSW_SP1_FW_FILENAME);
Loading

0 comments on commit 1497d2f

Please sign in to comment.