Merge branch 'mlxsw-Various-static-checkers-fixes'
Ido Schimmel says: ==================== mlxsw: Various static checkers fixes Jakub told me he gets some warnings with W=1, so I decided to check with sparse, smatch and coccinelle as well. This patch set fixes all the issues found. None are actual bugs / regressions and therefore not targeted at net. Patches #1-#2 add missing kernel-doc comments. Patch #3 removes dead code. Patch #4 reworks the ACL code to avoid defining a static variable in a header file. Patch #5 removes unnecessary conversion to bool that coccinelle warns about. Patch #6 avoids false-positive uninitialized symbol errors emitted by smatch. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
a1c7a536e0
@ -9,6 +9,41 @@
|
||||
#include "item.h"
|
||||
#include "core_acl_flex_keys.h"
|
||||
|
||||
/* For the purpose of the driver, define an internal storage scratchpad
|
||||
* that will be used to store key/mask values. For each defined element type
|
||||
* define an internal storage geometry.
|
||||
*
|
||||
* When adding new elements, MLXSW_AFK_ELEMENT_STORAGE_SIZE must be increased
|
||||
* accordingly.
|
||||
*/
|
||||
static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 16),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_32_47, 0x04, 2),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_0_31, 0x06, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_32_47, 0x0A, 2),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_0_31, 0x0C, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_8_10, 0x18, 17, 3),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_0_7, 0x18, 20, 8),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_0_31, 0x2C, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_96_127, 0x30, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_64_95, 0x34, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4),
|
||||
};
|
||||
|
||||
struct mlxsw_afk {
|
||||
struct list_head key_info_list;
|
||||
unsigned int max_blocks;
|
||||
@ -26,13 +61,15 @@ static bool mlxsw_afk_blocks_check(struct mlxsw_afk *mlxsw_afk)
|
||||
const struct mlxsw_afk_block *block = &mlxsw_afk->blocks[i];
|
||||
|
||||
for (j = 0; j < block->instances_count; j++) {
|
||||
const struct mlxsw_afk_element_info *elinfo;
|
||||
struct mlxsw_afk_element_inst *elinst;
|
||||
|
||||
elinst = &block->instances[j];
|
||||
if (elinst->type != elinst->info->type ||
|
||||
elinfo = &mlxsw_afk_element_infos[elinst->element];
|
||||
if (elinst->type != elinfo->type ||
|
||||
(!elinst->avoid_size_check &&
|
||||
elinst->item.size.bits !=
|
||||
elinst->info->item.size.bits))
|
||||
elinfo->item.size.bits))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -116,7 +153,7 @@ static void mlxsw_afk_picker_count_hits(struct mlxsw_afk *mlxsw_afk,
|
||||
struct mlxsw_afk_element_inst *elinst;
|
||||
|
||||
elinst = &block->instances[j];
|
||||
if (elinst->info->element == element) {
|
||||
if (elinst->element == element) {
|
||||
__set_bit(element, picker->hits[i].element);
|
||||
picker->hits[i].total++;
|
||||
}
|
||||
@ -301,7 +338,7 @@ mlxsw_afk_block_elinst_get(const struct mlxsw_afk_block *block,
|
||||
struct mlxsw_afk_element_inst *elinst;
|
||||
|
||||
elinst = &block->instances[i];
|
||||
if (elinst->info->element == element)
|
||||
if (elinst->element == element)
|
||||
return elinst;
|
||||
}
|
||||
return NULL;
|
||||
@ -409,9 +446,12 @@ static void
|
||||
mlxsw_sp_afk_encode_one(const struct mlxsw_afk_element_inst *elinst,
|
||||
char *output, char *storage, int u32_diff)
|
||||
{
|
||||
const struct mlxsw_item *storage_item = &elinst->info->item;
|
||||
const struct mlxsw_item *output_item = &elinst->item;
|
||||
const struct mlxsw_afk_element_info *elinfo;
|
||||
const struct mlxsw_item *storage_item;
|
||||
|
||||
elinfo = &mlxsw_afk_element_infos[elinst->element];
|
||||
storage_item = &elinfo->item;
|
||||
if (elinst->type == MLXSW_AFK_ELEMENT_TYPE_U32)
|
||||
mlxsw_sp_afk_encode_u32(storage_item, output_item,
|
||||
storage, output, u32_diff);
|
||||
|
@ -69,42 +69,10 @@ struct mlxsw_afk_element_info {
|
||||
MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF, \
|
||||
_element, _offset, 0, _size)
|
||||
|
||||
/* For the purpose of the driver, define an internal storage scratchpad
|
||||
* that will be used to store key/mask values. For each defined element type
|
||||
* define an internal storage geometry.
|
||||
*/
|
||||
static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 16),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_32_47, 0x04, 2),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_0_31, 0x06, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_32_47, 0x0A, 2),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_0_31, 0x0C, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_8_10, 0x18, 17, 3),
|
||||
MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_0_7, 0x18, 20, 8),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_0_31, 0x2C, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_96_127, 0x30, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_64_95, 0x34, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4),
|
||||
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4),
|
||||
};
|
||||
|
||||
#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
|
||||
|
||||
struct mlxsw_afk_element_inst { /* element instance in actual block */
|
||||
const struct mlxsw_afk_element_info *info;
|
||||
enum mlxsw_afk_element element;
|
||||
enum mlxsw_afk_element_type type;
|
||||
struct mlxsw_item item; /* element geometry in block */
|
||||
int u32_key_diff; /* in case value needs to be adjusted before write
|
||||
@ -116,7 +84,7 @@ struct mlxsw_afk_element_inst { /* element instance in actual block */
|
||||
#define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, \
|
||||
_shift, _size, _u32_key_diff, _avoid_size_check) \
|
||||
{ \
|
||||
.info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \
|
||||
.element = MLXSW_AFK_ELEMENT_##_element, \
|
||||
.type = _type, \
|
||||
.item = { \
|
||||
.offset = _offset, \
|
||||
|
@ -53,6 +53,7 @@
|
||||
|
||||
/**
|
||||
* struct mlxsw_i2c - device private data:
|
||||
* @cmd: command attributes;
|
||||
* @cmd.mb_size_in: input mailbox size;
|
||||
* @cmd.mb_off_in: input mailbox offset in register space;
|
||||
* @cmd.mb_size_out: output mailbox size;
|
||||
|
@ -438,16 +438,6 @@ static int mlxsw_sp_fid_vni_op(struct mlxsw_sp *mlxsw_sp, u16 fid_index,
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_fid_vid_map(struct mlxsw_sp *mlxsw_sp, u16 fid_index,
|
||||
u16 vid, bool valid)
|
||||
{
|
||||
enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_VID_TO_FID;
|
||||
char svfa_pl[MLXSW_REG_SVFA_LEN];
|
||||
|
||||
mlxsw_reg_svfa_pack(svfa_pl, 0, mt, valid, fid_index, vid);
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
|
||||
}
|
||||
|
||||
static int __mlxsw_sp_fid_port_vid_map(struct mlxsw_sp *mlxsw_sp, u16 fid_index,
|
||||
u8 local_port, u16 vid, bool valid)
|
||||
{
|
||||
@ -458,140 +448,6 @@ static int __mlxsw_sp_fid_port_vid_map(struct mlxsw_sp *mlxsw_sp, u16 fid_index,
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_fid_8021q_configure(struct mlxsw_sp_fid *fid)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
|
||||
struct mlxsw_sp_fid_8021q *fid_8021q;
|
||||
int err;
|
||||
|
||||
err = mlxsw_sp_fid_op(mlxsw_sp, fid->fid_index, fid->fid_index, true);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fid_8021q = mlxsw_sp_fid_8021q_fid(fid);
|
||||
err = mlxsw_sp_fid_vid_map(mlxsw_sp, fid->fid_index, fid_8021q->vid,
|
||||
true);
|
||||
if (err)
|
||||
goto err_fid_map;
|
||||
|
||||
return 0;
|
||||
|
||||
err_fid_map:
|
||||
mlxsw_sp_fid_op(mlxsw_sp, fid->fid_index, 0, false);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_fid_8021q_deconfigure(struct mlxsw_sp_fid *fid)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
|
||||
struct mlxsw_sp_fid_8021q *fid_8021q;
|
||||
|
||||
fid_8021q = mlxsw_sp_fid_8021q_fid(fid);
|
||||
mlxsw_sp_fid_vid_map(mlxsw_sp, fid->fid_index, fid_8021q->vid, false);
|
||||
mlxsw_sp_fid_op(mlxsw_sp, fid->fid_index, 0, false);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_fid_8021q_index_alloc(struct mlxsw_sp_fid *fid,
|
||||
const void *arg, u16 *p_fid_index)
|
||||
{
|
||||
struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
|
||||
u16 vid = *(u16 *) arg;
|
||||
|
||||
/* Use 1:1 mapping for simplicity although not a must */
|
||||
if (vid < fid_family->start_index || vid > fid_family->end_index)
|
||||
return -EINVAL;
|
||||
*p_fid_index = vid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
mlxsw_sp_fid_8021q_compare(const struct mlxsw_sp_fid *fid, const void *arg)
|
||||
{
|
||||
u16 vid = *(u16 *) arg;
|
||||
|
||||
return mlxsw_sp_fid_8021q_fid(fid)->vid == vid;
|
||||
}
|
||||
|
||||
static u16 mlxsw_sp_fid_8021q_flood_index(const struct mlxsw_sp_fid *fid)
|
||||
{
|
||||
return fid->fid_index;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_fid_8021q_port_vid_map(struct mlxsw_sp_fid *fid,
|
||||
struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
u16 vid)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
u8 local_port = mlxsw_sp_port->local_port;
|
||||
|
||||
/* In case there are no {Port, VID} => FID mappings on the port,
|
||||
* we can use the global VID => FID mapping we created when the
|
||||
* FID was configured.
|
||||
*/
|
||||
if (mlxsw_sp->fid_core->port_fid_mappings[local_port] == 0)
|
||||
return 0;
|
||||
return __mlxsw_sp_fid_port_vid_map(mlxsw_sp, fid->fid_index, local_port,
|
||||
vid, true);
|
||||
}
|
||||
|
||||
static void
|
||||
mlxsw_sp_fid_8021q_port_vid_unmap(struct mlxsw_sp_fid *fid,
|
||||
struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
u8 local_port = mlxsw_sp_port->local_port;
|
||||
|
||||
if (mlxsw_sp->fid_core->port_fid_mappings[local_port] == 0)
|
||||
return;
|
||||
__mlxsw_sp_fid_port_vid_map(mlxsw_sp, fid->fid_index, local_port, vid,
|
||||
false);
|
||||
}
|
||||
|
||||
static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021q_ops = {
|
||||
.setup = mlxsw_sp_fid_8021q_setup,
|
||||
.configure = mlxsw_sp_fid_8021q_configure,
|
||||
.deconfigure = mlxsw_sp_fid_8021q_deconfigure,
|
||||
.index_alloc = mlxsw_sp_fid_8021q_index_alloc,
|
||||
.compare = mlxsw_sp_fid_8021q_compare,
|
||||
.flood_index = mlxsw_sp_fid_8021q_flood_index,
|
||||
.port_vid_map = mlxsw_sp_fid_8021q_port_vid_map,
|
||||
.port_vid_unmap = mlxsw_sp_fid_8021q_port_vid_unmap,
|
||||
};
|
||||
|
||||
static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021q_flood_tables[] = {
|
||||
{
|
||||
.packet_type = MLXSW_SP_FLOOD_TYPE_UC,
|
||||
.bridge_type = MLXSW_REG_SFGC_BRIDGE_TYPE_1Q_FID,
|
||||
.table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET,
|
||||
.table_index = 0,
|
||||
},
|
||||
{
|
||||
.packet_type = MLXSW_SP_FLOOD_TYPE_MC,
|
||||
.bridge_type = MLXSW_REG_SFGC_BRIDGE_TYPE_1Q_FID,
|
||||
.table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET,
|
||||
.table_index = 1,
|
||||
},
|
||||
{
|
||||
.packet_type = MLXSW_SP_FLOOD_TYPE_BC,
|
||||
.bridge_type = MLXSW_REG_SFGC_BRIDGE_TYPE_1Q_FID,
|
||||
.table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET,
|
||||
.table_index = 2,
|
||||
},
|
||||
};
|
||||
|
||||
/* Range and flood configuration must match mlxsw_config_profile */
|
||||
static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021q_family = {
|
||||
.type = MLXSW_SP_FID_TYPE_8021Q,
|
||||
.fid_size = sizeof(struct mlxsw_sp_fid_8021q),
|
||||
.start_index = 1,
|
||||
.end_index = VLAN_VID_MASK,
|
||||
.flood_tables = mlxsw_sp_fid_8021q_flood_tables,
|
||||
.nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021q_flood_tables),
|
||||
.rif_type = MLXSW_SP_RIF_TYPE_VLAN,
|
||||
.ops = &mlxsw_sp_fid_8021q_ops,
|
||||
};
|
||||
|
||||
static struct mlxsw_sp_fid_8021d *
|
||||
mlxsw_sp_fid_8021d_fid(const struct mlxsw_sp_fid *fid)
|
||||
{
|
||||
@ -846,6 +702,14 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021d_family = {
|
||||
.lag_vid_valid = 1,
|
||||
};
|
||||
|
||||
static bool
|
||||
mlxsw_sp_fid_8021q_compare(const struct mlxsw_sp_fid *fid, const void *arg)
|
||||
{
|
||||
u16 vid = *(u16 *) arg;
|
||||
|
||||
return mlxsw_sp_fid_8021q_fid(fid)->vid == vid;
|
||||
}
|
||||
|
||||
static void
|
||||
mlxsw_sp_fid_8021q_fdb_clear_offload(const struct mlxsw_sp_fid *fid,
|
||||
const struct net_device *nve_dev)
|
||||
|
@ -1212,7 +1212,7 @@ mlxsw_sp_ipip_entry_find_decap(struct mlxsw_sp *mlxsw_sp,
|
||||
saddr_len = 4;
|
||||
saddr_prefix_len = 32;
|
||||
break;
|
||||
case MLXSW_SP_L3_PROTO_IPV6:
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
@ -1380,9 +1380,9 @@ static bool mlxsw_sp_netdevice_ipip_can_offload(struct mlxsw_sp *mlxsw_sp,
|
||||
static int mlxsw_sp_netdevice_ipip_ol_reg_event(struct mlxsw_sp *mlxsw_sp,
|
||||
struct net_device *ol_dev)
|
||||
{
|
||||
enum mlxsw_sp_ipip_type ipipt = MLXSW_SP_IPIP_TYPE_MAX;
|
||||
struct mlxsw_sp_ipip_entry *ipip_entry;
|
||||
enum mlxsw_sp_l3proto ul_proto;
|
||||
enum mlxsw_sp_ipip_type ipipt;
|
||||
union mlxsw_sp_l3addr saddr;
|
||||
u32 ul_tb_id;
|
||||
|
||||
@ -1535,13 +1535,17 @@ static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_rif *rif);
|
||||
|
||||
/**
|
||||
* Update the offload related to an IPIP entry. This always updates decap, and
|
||||
* in addition to that it also:
|
||||
* @recreate_loopback: recreates the associated loopback RIF
|
||||
* @keep_encap: updates next hops that use the tunnel netdevice. This is only
|
||||
* __mlxsw_sp_ipip_entry_update_tunnel - Update offload related to IPIP entry.
|
||||
* @mlxsw_sp: mlxsw_sp.
|
||||
* @ipip_entry: IPIP entry.
|
||||
* @recreate_loopback: Recreates the associated loopback RIF.
|
||||
* @keep_encap: Updates next hops that use the tunnel netdevice. This is only
|
||||
* relevant when recreate_loopback is true.
|
||||
* @update_nexthops: updates next hops, keeping the current loopback RIF. This
|
||||
* @update_nexthops: Updates next hops, keeping the current loopback RIF. This
|
||||
* is only relevant when recreate_loopback is false.
|
||||
* @extack: extack.
|
||||
*
|
||||
* Return: Non-zero value on failure.
|
||||
*/
|
||||
int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_ipip_entry *ipip_entry,
|
||||
@ -3227,7 +3231,6 @@ mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
|
||||
u32 adj_index = nh_grp->adj_index; /* base */
|
||||
struct mlxsw_sp_nexthop *nh;
|
||||
int i;
|
||||
int err;
|
||||
|
||||
for (i = 0; i < nh_grp->count; i++) {
|
||||
nh = &nh_grp->nexthops[i];
|
||||
@ -3238,6 +3241,8 @@ mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
|
||||
}
|
||||
|
||||
if (nh->update || reallocate) {
|
||||
int err = 0;
|
||||
|
||||
switch (nh->type) {
|
||||
case MLXSW_SP_NEXTHOP_TYPE_ETH:
|
||||
err = mlxsw_sp_nexthop_update
|
||||
@ -7471,113 +7476,6 @@ u8 mlxsw_sp_router_port(const struct mlxsw_sp *mlxsw_sp)
|
||||
return mlxsw_core_max_ports(mlxsw_sp->core) + 1;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_rif_vlan_configure(struct mlxsw_sp_rif *rif)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
|
||||
u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid);
|
||||
int err;
|
||||
|
||||
err = mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_VLAN_IF, vid, true);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
|
||||
mlxsw_sp_router_port(mlxsw_sp), true);
|
||||
if (err)
|
||||
goto err_fid_mc_flood_set;
|
||||
|
||||
err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
|
||||
mlxsw_sp_router_port(mlxsw_sp), true);
|
||||
if (err)
|
||||
goto err_fid_bc_flood_set;
|
||||
|
||||
err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
|
||||
mlxsw_sp_fid_index(rif->fid), true);
|
||||
if (err)
|
||||
goto err_rif_fdb_op;
|
||||
|
||||
mlxsw_sp_fid_rif_set(rif->fid, rif);
|
||||
return 0;
|
||||
|
||||
err_rif_fdb_op:
|
||||
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
|
||||
mlxsw_sp_router_port(mlxsw_sp), false);
|
||||
err_fid_bc_flood_set:
|
||||
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
|
||||
mlxsw_sp_router_port(mlxsw_sp), false);
|
||||
err_fid_mc_flood_set:
|
||||
mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_VLAN_IF, vid, false);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_rif_vlan_deconfigure(struct mlxsw_sp_rif *rif)
|
||||
{
|
||||
u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid);
|
||||
struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
|
||||
struct mlxsw_sp_fid *fid = rif->fid;
|
||||
|
||||
mlxsw_sp_fid_rif_set(fid, NULL);
|
||||
mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
|
||||
mlxsw_sp_fid_index(fid), false);
|
||||
mlxsw_sp_rif_macvlan_flush(rif);
|
||||
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
|
||||
mlxsw_sp_router_port(mlxsw_sp), false);
|
||||
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
|
||||
mlxsw_sp_router_port(mlxsw_sp), false);
|
||||
mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_VLAN_IF, vid, false);
|
||||
}
|
||||
|
||||
static struct mlxsw_sp_fid *
|
||||
mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct net_device *br_dev = rif->dev;
|
||||
u16 vid;
|
||||
int err;
|
||||
|
||||
if (is_vlan_dev(rif->dev)) {
|
||||
vid = vlan_dev_vlan_id(rif->dev);
|
||||
br_dev = vlan_dev_real_dev(rif->dev);
|
||||
if (WARN_ON(!netif_is_bridge_master(br_dev)))
|
||||
return ERR_PTR(-EINVAL);
|
||||
} else {
|
||||
err = br_vlan_get_pvid(rif->dev, &vid);
|
||||
if (err < 0 || !vid) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Couldn't determine bridge PVID");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
return mlxsw_sp_fid_8021q_get(rif->mlxsw_sp, vid);
|
||||
}
|
||||
|
||||
static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
|
||||
{
|
||||
u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid);
|
||||
struct switchdev_notifier_fdb_info info;
|
||||
struct net_device *br_dev;
|
||||
struct net_device *dev;
|
||||
|
||||
br_dev = is_vlan_dev(rif->dev) ? vlan_dev_real_dev(rif->dev) : rif->dev;
|
||||
dev = br_fdb_find_port(br_dev, mac, vid);
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
info.addr = mac;
|
||||
info.vid = vid;
|
||||
call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_vlan_ops = {
|
||||
.type = MLXSW_SP_RIF_TYPE_VLAN,
|
||||
.rif_size = sizeof(struct mlxsw_sp_rif),
|
||||
.configure = mlxsw_sp_rif_vlan_configure,
|
||||
.deconfigure = mlxsw_sp_rif_vlan_deconfigure,
|
||||
.fid_get = mlxsw_sp_rif_vlan_fid_get,
|
||||
.fdb_del = mlxsw_sp_rif_vlan_fdb_del,
|
||||
};
|
||||
|
||||
static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
|
||||
@ -7666,6 +7564,48 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_fid_ops = {
|
||||
.fdb_del = mlxsw_sp_rif_fid_fdb_del,
|
||||
};
|
||||
|
||||
static struct mlxsw_sp_fid *
|
||||
mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct net_device *br_dev = rif->dev;
|
||||
u16 vid;
|
||||
int err;
|
||||
|
||||
if (is_vlan_dev(rif->dev)) {
|
||||
vid = vlan_dev_vlan_id(rif->dev);
|
||||
br_dev = vlan_dev_real_dev(rif->dev);
|
||||
if (WARN_ON(!netif_is_bridge_master(br_dev)))
|
||||
return ERR_PTR(-EINVAL);
|
||||
} else {
|
||||
err = br_vlan_get_pvid(rif->dev, &vid);
|
||||
if (err < 0 || !vid) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Couldn't determine bridge PVID");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
return mlxsw_sp_fid_8021q_get(rif->mlxsw_sp, vid);
|
||||
}
|
||||
|
||||
static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
|
||||
{
|
||||
u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid);
|
||||
struct switchdev_notifier_fdb_info info;
|
||||
struct net_device *br_dev;
|
||||
struct net_device *dev;
|
||||
|
||||
br_dev = is_vlan_dev(rif->dev) ? vlan_dev_real_dev(rif->dev) : rif->dev;
|
||||
dev = br_fdb_find_port(br_dev, mac, vid);
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
info.addr = mac;
|
||||
info.vid = vid;
|
||||
call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_vlan_emu_ops = {
|
||||
.type = MLXSW_SP_RIF_TYPE_VLAN,
|
||||
.rif_size = sizeof(struct mlxsw_sp_rif),
|
||||
|
@ -180,7 +180,7 @@ static int mlxsw_sx_port_oper_status_get(struct mlxsw_sx_port *mlxsw_sx_port,
|
||||
if (err)
|
||||
return err;
|
||||
oper_status = mlxsw_reg_paos_oper_status_get(paos_pl);
|
||||
*p_is_up = oper_status == MLXSW_PORT_ADMIN_STATUS_UP ? true : false;
|
||||
*p_is_up = oper_status == MLXSW_PORT_ADMIN_STATUS_UP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user