static int mlxsw_sp_sb_mms_init(struct mlxsw_sp *mlxsw_sp) { char sbmm_pl[MLXSW_REG_SBMM_LEN]; int i; int err; for (i = 0; i < mlxsw_sp->sb_vals->mms_count; i++) { const struct mlxsw_sp_sb_pool_des *des; const struct mlxsw_sp_sb_mm *mc; u32 min_buff; mc = &mlxsw_sp->sb_vals->mms[i]; des = &mlxsw_sp->sb_vals->pool_dess[mc->pool_index]; /* All pools used by sb_mm's are initialized using dynamic * thresholds, therefore 'max_buff' isn't specified in cells. */ min_buff = mlxsw_sp_bytes_cells(mlxsw_sp, mc->min_buff); mlxsw_reg_sbmm_pack(sbmm_pl, i, min_buff, mc->max_buff, des->pool); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbmm), sbmm_pl); if (err) return err; } return 0; }
static void __mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) { char rgcr_pl[MLXSW_REG_RGCR_LEN]; mlxsw_reg_rgcr_pack(rgcr_pl, false); mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl); }
static int mlxsw_sp_sb_cm_write(struct mlxsw_sp *mlxsw_sp, u8 local_port, u8 pg_buff, u32 min_buff, u32 max_buff, bool infi_max, u16 pool_index) { const struct mlxsw_sp_sb_pool_des *des = &mlxsw_sp->sb_vals->pool_dess[pool_index]; char sbcm_pl[MLXSW_REG_SBCM_LEN]; struct mlxsw_sp_sb_cm *cm; int err; mlxsw_reg_sbcm_pack(sbcm_pl, local_port, pg_buff, des->dir, min_buff, max_buff, infi_max, des->pool); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbcm), sbcm_pl); if (err) return err; if (mlxsw_sp_sb_cm_exists(pg_buff, des->dir)) { if (infi_max) max_buff = mlxsw_sp_bytes_cells(mlxsw_sp, mlxsw_sp->sb->sb_size); cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, pg_buff, des->dir); cm->min_buff = min_buff; cm->max_buff = max_buff; cm->pool_index = pool_index; } return 0; }
static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) { char rgcr_pl[MLXSW_REG_RGCR_LEN]; mlxsw_reg_rgcr_pack(rgcr_pl, true); mlxsw_reg_rgcr_max_router_interfaces_set(rgcr_pl, MLXSW_SP_RIF_MAX); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl); }
static int mlxsw_sx_port_swid_set(struct mlxsw_sx_port *mlxsw_sx_port, u8 swid) { struct mlxsw_sx *mlxsw_sx = mlxsw_sx_port->mlxsw_sx; char pspa_pl[MLXSW_REG_PSPA_LEN]; mlxsw_reg_pspa_pack(pspa_pl, swid, mlxsw_sx_port->local_port); return mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(pspa), pspa_pl); }
static int mlxsw_sx_port_system_port_mapping_set(struct mlxsw_sx_port *mlxsw_sx_port) { struct mlxsw_sx *mlxsw_sx = mlxsw_sx_port->mlxsw_sx; char sspr_pl[MLXSW_REG_SSPR_LEN]; mlxsw_reg_sspr_pack(sspr_pl, mlxsw_sx_port->local_port); return mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(sspr), sspr_pl); }
static int mlxsw_sib_port_speed_set(struct mlxsw_sib_port *mlxsw_sib_port, u16 speed, u16 width) { struct mlxsw_sib *mlxsw_sib = mlxsw_sib_port->mlxsw_sib; char ptys_pl[MLXSW_REG_PTYS_LEN]; mlxsw_reg_ptys_ib_pack(ptys_pl, mlxsw_sib_port->local_port, speed, width); return mlxsw_reg_write(mlxsw_sib->core, MLXSW_REG(ptys), ptys_pl); }
static int mlxsw_sp_port_pb_prio_init(struct mlxsw_sp_port *mlxsw_sp_port) { char pptb_pl[MLXSW_REG_PPTB_LEN]; int i; mlxsw_reg_pptb_pack(pptb_pl, mlxsw_sp_port->local_port); for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) mlxsw_reg_pptb_prio_to_buff_pack(pptb_pl, i, 0); return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pptb), pptb_pl); }
static int mlxsw_sib_port_set(struct mlxsw_sib_port *mlxsw_sib_port, u8 port) { struct mlxsw_sib *mlxsw_sib = mlxsw_sib_port->mlxsw_sib; char plib_pl[MLXSW_REG_PLIB_LEN] = {0}; int err; mlxsw_reg_plib_local_port_set(plib_pl, mlxsw_sib_port->local_port); mlxsw_reg_plib_ib_port_set(plib_pl, port); err = mlxsw_reg_write(mlxsw_sib->core, MLXSW_REG(plib), plib_pl); return err; }
static int mlxsw_sx_port_admin_status_set(struct mlxsw_sx_port *mlxsw_sx_port, bool is_up) { struct mlxsw_sx *mlxsw_sx = mlxsw_sx_port->mlxsw_sx; char paos_pl[MLXSW_REG_PAOS_LEN]; mlxsw_reg_paos_pack(paos_pl, mlxsw_sx_port->local_port, is_up ? MLXSW_PORT_ADMIN_STATUS_UP : MLXSW_PORT_ADMIN_STATUS_DOWN); return mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(paos), paos_pl); }
static int mlxsw_sp2_mr_tcam_bind_group(struct mlxsw_sp *mlxsw_sp, enum mlxsw_reg_pemrbt_protocol protocol, struct mlxsw_sp_acl_ruleset *ruleset) { char pemrbt_pl[MLXSW_REG_PEMRBT_LEN]; u16 group_id; group_id = mlxsw_sp_acl_ruleset_group_id(ruleset); mlxsw_reg_pemrbt_pack(pemrbt_pl, protocol, group_id); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pemrbt), pemrbt_pl); }
static void mlxsw_sp_acl_ctcam_region_move(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_tcam_region *region, u16 src_offset, u16 dst_offset, u16 size) { char prcr_pl[MLXSW_REG_PRCR_LEN]; mlxsw_reg_prcr_pack(prcr_pl, MLXSW_REG_PRCR_OP_MOVE, region->tcam_region_info, src_offset, region->tcam_region_info, dst_offset, size); mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(prcr), prcr_pl); }
static int mlxsw_sp_acl_ctcam_region_resize(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_tcam_region *region, u16 new_size) { char ptar_pl[MLXSW_REG_PTAR_LEN]; mlxsw_reg_ptar_pack(ptar_pl, MLXSW_REG_PTAR_OP_RESIZE, region->key_type, new_size, region->id, region->tcam_region_info); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptar), ptar_pl); }
static int mlxsw_sib_basic_trap_groups_set(struct mlxsw_core *mlxsw_core) { char htgt_pl[MLXSW_REG_HTGT_LEN]; mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_EMAD, MLXSW_REG_HTGT_INVALID_POLICER, MLXSW_REG_HTGT_DEFAULT_PRIORITY, MLXSW_REG_HTGT_DEFAULT_TC); mlxsw_reg_htgt_swid_set(htgt_pl, MLXSW_PORT_SWID_ALL_SWIDS); mlxsw_reg_htgt_local_path_rdq_set(htgt_pl, MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SIB_EMAD); return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl); }
static void mlxsw_sp_acl_ctcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ctcam_region *cregion, struct mlxsw_sp_acl_ctcam_entry *centry) { char ptce2_pl[MLXSW_REG_PTCE2_LEN]; mlxsw_reg_ptce2_pack(ptce2_pl, false, MLXSW_REG_PTCE2_OP_WRITE_WRITE, cregion->region->tcam_region_info, centry->parman_item.index, 0); mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl); cregion->ops->entry_remove(cregion, centry); }
static int mlxsw_sp2_kvdl_rec_del(struct mlxsw_sp *mlxsw_sp, u8 res_type, u16 size, u32 kvdl_index) { char *iedr_pl; int err; iedr_pl = kmalloc(MLXSW_REG_IEDR_LEN, GFP_KERNEL); if (!iedr_pl) return -ENOMEM; mlxsw_reg_iedr_pack(iedr_pl); mlxsw_reg_iedr_rec_pack(iedr_pl, 0, res_type, size, kvdl_index); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(iedr), iedr_pl); kfree(iedr_pl); return err; }
static int mlxsw_sp_port_pb_init(struct mlxsw_sp_port *mlxsw_sp_port) { char pbmc_pl[MLXSW_REG_PBMC_LEN]; int i; mlxsw_reg_pbmc_pack(pbmc_pl, mlxsw_sp_port->local_port, 0xffff, 0xffff / 2); for (i = 0; i < MLXSW_SP_PBS_LEN; i++) { if (i == MLXSW_SP_PB_UNUSED) continue; mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, i, mlxsw_sp_pbs[i]); } mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, MLXSW_REG_PBMC_PORT_SHARED_BUF_IDX, 0); return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl); }
static int mlxsw_sp_sb_mms_init(struct mlxsw_sp *mlxsw_sp) { char sbmm_pl[MLXSW_REG_SBMM_LEN]; int i; int err; for (i = 0; i < MLXSW_SP_SB_MMS_LEN; i++) { const struct mlxsw_sp_sb_mm *mc; mc = &mlxsw_sp_sb_mms[i]; mlxsw_reg_sbmm_pack(sbmm_pl, i, mc->min_buff, mc->max_buff, mc->pool); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbmm), sbmm_pl); if (err) return err; } return 0; }
static int mlxsw_sp_sb_pr_write(struct mlxsw_sp *mlxsw_sp, u8 pool, enum mlxsw_reg_sbxx_dir dir, enum mlxsw_reg_sbpr_mode mode, u32 size) { char sbpr_pl[MLXSW_REG_SBPR_LEN]; struct mlxsw_sp_sb_pr *pr; int err; mlxsw_reg_sbpr_pack(sbpr_pl, pool, dir, mode, size); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbpr), sbpr_pl); if (err) return err; pr = mlxsw_sp_sb_pr_get(mlxsw_sp, pool, dir); pr->mode = mode; pr->size = size; return 0; }
static int mlxsw_sp_sb_pm_write(struct mlxsw_sp *mlxsw_sp, u8 local_port, u8 pool, enum mlxsw_reg_sbxx_dir dir, u32 min_buff, u32 max_buff) { char sbpm_pl[MLXSW_REG_SBPM_LEN]; struct mlxsw_sp_sb_pm *pm; int err; mlxsw_reg_sbpm_pack(sbpm_pl, local_port, pool, dir, false, min_buff, max_buff); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbpm), sbpm_pl); if (err) return err; pm = mlxsw_sp_sb_pm_get(mlxsw_sp, local_port, pool, dir); pm->min_buff = min_buff; pm->max_buff = max_buff; return 0; }
static int mlxsw_sp_acl_ctcam_region_entry_action_replace(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ctcam_region *cregion, struct mlxsw_sp_acl_ctcam_entry *centry, struct mlxsw_afa_block *afa_block, unsigned int priority) { char ptce2_pl[MLXSW_REG_PTCE2_LEN]; char *act_set; mlxsw_reg_ptce2_pack(ptce2_pl, true, MLXSW_REG_PTCE2_OP_WRITE_UPDATE, cregion->region->tcam_region_info, centry->parman_item.index, priority); act_set = mlxsw_afa_block_first_set(afa_block); mlxsw_reg_ptce2_flex_action_set_memcpy_to(ptce2_pl, act_set); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl); }
static int mlxsw_sp_sb_pm_write(struct mlxsw_sp *mlxsw_sp, u8 local_port, u16 pool_index, u32 min_buff, u32 max_buff) { const struct mlxsw_sp_sb_pool_des *des = &mlxsw_sp->sb_vals->pool_dess[pool_index]; char sbpm_pl[MLXSW_REG_SBPM_LEN]; struct mlxsw_sp_sb_pm *pm; int err; mlxsw_reg_sbpm_pack(sbpm_pl, local_port, des->pool, des->dir, false, min_buff, max_buff); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbpm), sbpm_pl); if (err) return err; pm = mlxsw_sp_sb_pm_get(mlxsw_sp, local_port, pool_index); pm->min_buff = min_buff; pm->max_buff = max_buff; return 0; }
static int mlxsw_sib_port_mtu_set(struct mlxsw_sib_port *mlxsw_sib_port, u16 mtu) { struct mlxsw_sib *mlxsw_sib = mlxsw_sib_port->mlxsw_sib; char pmtu_pl[MLXSW_REG_PMTU_LEN]; int max_mtu; int err; mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sib_port->local_port, 0); err = mlxsw_reg_query(mlxsw_sib->core, MLXSW_REG(pmtu), pmtu_pl); if (err) return err; max_mtu = mlxsw_reg_pmtu_max_mtu_get(pmtu_pl); if (mtu > max_mtu) return -EINVAL; mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sib_port->local_port, mtu); return mlxsw_reg_write(mlxsw_sib->core, MLXSW_REG(pmtu), pmtu_pl); }
static int mlxsw_sp_sb_cm_write(struct mlxsw_sp *mlxsw_sp, u8 local_port, u8 pg_buff, enum mlxsw_reg_sbxx_dir dir, u32 min_buff, u32 max_buff, u8 pool) { char sbcm_pl[MLXSW_REG_SBCM_LEN]; int err; mlxsw_reg_sbcm_pack(sbcm_pl, local_port, pg_buff, dir, min_buff, max_buff, pool); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbcm), sbcm_pl); if (err) return err; if (pg_buff < MLXSW_SP_SB_TC_COUNT) { struct mlxsw_sp_sb_cm *cm; cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, pg_buff, dir); cm->min_buff = min_buff; cm->max_buff = max_buff; cm->pool = pool; } return 0; }
static int mlxsw_sp_acl_ctcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ctcam_region *cregion, struct mlxsw_sp_acl_ctcam_entry *centry, struct mlxsw_sp_acl_rule_info *rulei, bool fillup_priority) { struct mlxsw_sp_acl_tcam_region *region = cregion->region; struct mlxsw_afk *afk = mlxsw_sp_acl_afk(mlxsw_sp->acl); char ptce2_pl[MLXSW_REG_PTCE2_LEN]; char *act_set; u32 priority; char *mask; char *key; int err; err = mlxsw_sp_acl_tcam_priority_get(mlxsw_sp, rulei, &priority, fillup_priority); if (err) return err; mlxsw_reg_ptce2_pack(ptce2_pl, true, MLXSW_REG_PTCE2_OP_WRITE_WRITE, region->tcam_region_info, centry->parman_item.index, priority); key = mlxsw_reg_ptce2_flex_key_blocks_data(ptce2_pl); mask = mlxsw_reg_ptce2_mask_data(ptce2_pl); mlxsw_afk_encode(afk, region->key_info, &rulei->values, key, mask); err = cregion->ops->entry_insert(cregion, centry, mask); if (err) return err; /* Only the first action set belongs here, the rest is in KVD */ act_set = mlxsw_afa_block_first_set(rulei->act_block); mlxsw_reg_ptce2_flex_action_set_memcpy_to(ptce2_pl, act_set); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl); }
static int mlxsw_sp_port_pb_init(struct mlxsw_sp_port *mlxsw_sp_port) { const u32 pbs[] = { [0] = MLXSW_SP_PB_HEADROOM * mlxsw_sp_port->mapping.width, [9] = 2 * MLXSW_PORT_MAX_MTU, }; struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; char pbmc_pl[MLXSW_REG_PBMC_LEN]; int i; mlxsw_reg_pbmc_pack(pbmc_pl, mlxsw_sp_port->local_port, 0xffff, 0xffff / 2); for (i = 0; i < ARRAY_SIZE(pbs); i++) { u16 size = mlxsw_sp_bytes_cells(mlxsw_sp, pbs[i]); if (i == MLXSW_SP_PB_UNUSED) continue; mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, i, size); } mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, MLXSW_REG_PBMC_PORT_SHARED_BUF_IDX, 0); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl); }
static int mlxsw_sp_sb_pr_write(struct mlxsw_sp *mlxsw_sp, u16 pool_index, enum mlxsw_reg_sbpr_mode mode, u32 size, bool infi_size) { const struct mlxsw_sp_sb_pool_des *des = &mlxsw_sp->sb_vals->pool_dess[pool_index]; char sbpr_pl[MLXSW_REG_SBPR_LEN]; struct mlxsw_sp_sb_pr *pr; int err; mlxsw_reg_sbpr_pack(sbpr_pl, des->pool, des->dir, mode, size, infi_size); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbpr), sbpr_pl); if (err) return err; if (infi_size) size = mlxsw_sp_bytes_cells(mlxsw_sp, mlxsw_sp->sb->sb_size); pr = mlxsw_sp_sb_pr_get(mlxsw_sp, pool_index); pr->mode = mode; pr->size = size; return 0; }