Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 181e4246 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-cleanups'



Jiri Pirko says:

====================
mlxsw: Driver update, cleanups

This patchset contains various cleanups and improvements in mlxsw driver.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 96aec911 5cd16d8c
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -464,6 +464,8 @@ MLXSW_ITEM32(cmd_mbox, query_aq_cap, max_sg_rq, 0x10, 0, 8);
 * passed in this command must be pinned.
 */

#define MLXSW_CMD_MAP_FA_VPM_ENTRIES_MAX 32

static inline int mlxsw_cmd_map_fa(struct mlxsw_core *mlxsw_core,
				   char *in_mbox, u32 vpm_entries_count)
{
@@ -568,7 +570,7 @@ MLXSW_ITEM32(cmd_mbox, config_profile, set_max_vlan_groups, 0x0C, 6, 1);
 */
MLXSW_ITEM32(cmd_mbox, config_profile, set_max_regions, 0x0C, 7, 1);

/* cmd_mbox_config_profile_set_fid_based
/* cmd_mbox_config_profile_set_flood_mode
 * Capability bit. Setting a bit to 1 configures the profile
 * according to the mailbox contents.
 */
@@ -649,12 +651,8 @@ MLXSW_ITEM32(cmd_mbox, config_profile, max_vlan_groups, 0x28, 0, 12);
MLXSW_ITEM32(cmd_mbox, config_profile, max_regions, 0x2C, 0, 16);

/* cmd_mbox_config_profile_max_flood_tables
 * Maximum number of Flooding Tables. Flooding Tables are associated to
 * the different packet types for the different switch partitions.
 * Note that the table size depends on the fid_based mode.
 * In SwitchX silicon, tables are split equally between the switch
 * partitions. e.g. for 2 swids and 8 tables, the first 4 are associated
 * with swid-1 and the last 4 are associated with swid-2.
 * Maximum number of single-entry flooding tables. Different flooding tables
 * can be associated with different packet types.
 */
MLXSW_ITEM32(cmd_mbox, config_profile, max_flood_tables, 0x30, 16, 4);

@@ -665,12 +663,14 @@ MLXSW_ITEM32(cmd_mbox, config_profile, max_flood_tables, 0x30, 16, 4);
 */
MLXSW_ITEM32(cmd_mbox, config_profile, max_vid_flood_tables, 0x30, 8, 4);

/* cmd_mbox_config_profile_fid_based
 * FID Based Flood Mode
 * 00 Do not use FID to offset the index into the Port Group Table/Multicast ID
 * 01 Use FID to offset the index to the Port Group Table (pgi)
 * 10 Use FID to offset the index to the Port Group Table (pgi) and
 * the Multicast ID
/* cmd_mbox_config_profile_flood_mode
 * Flooding mode to use.
 * 0-2 - Backward compatible modes for SwitchX devices.
 * 3 - Mixed mode, where:
 * max_flood_tables indicates the number of single-entry tables.
 * max_vid_flood_tables indicates the number of per-VID tables.
 * max_fid_offset_flood_tables indicates the number of FID-offset tables.
 * max_fid_flood_tables indicates the number of per-FID tables.
 */
MLXSW_ITEM32(cmd_mbox, config_profile, flood_mode, 0x30, 0, 2);

+1 −2
Original line number Diff line number Diff line
@@ -506,7 +506,6 @@ static int mlxsw_emad_traps_set(struct mlxsw_core *mlxsw_core)
		return err;

	mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU,
			    MLXSW_REG_HTGT_TRAP_GROUP_EMAD,
			    MLXSW_TRAP_ID_ETHEMAD);
	return mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl);
}
@@ -551,8 +550,8 @@ static void mlxsw_emad_fini(struct mlxsw_core *mlxsw_core)
{
	char hpkt_pl[MLXSW_REG_HPKT_LEN];

	mlxsw_core->emad.use_emad = false;
	mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD,
			    MLXSW_REG_HTGT_TRAP_GROUP_EMAD,
			    MLXSW_TRAP_ID_ETHEMAD);
	mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl);

+29 −20
Original line number Diff line number Diff line
@@ -171,8 +171,8 @@ struct mlxsw_pci {
	struct msix_entry msix_entry;
	struct mlxsw_core *core;
	struct {
		u16 num_pages;
		struct mlxsw_pci_mem_item *items;
		unsigned int count;
	} fw_area;
	struct {
		struct mlxsw_pci_mem_item out_mbox;
@@ -431,8 +431,7 @@ static int mlxsw_pci_wqe_frag_map(struct mlxsw_pci *mlxsw_pci, char *wqe,

	mapaddr = pci_map_single(pdev, frag_data, frag_len, direction);
	if (unlikely(pci_dma_mapping_error(pdev, mapaddr))) {
		if (net_ratelimit())
			dev_err(&pdev->dev, "failed to dma map tx frag\n");
		dev_err_ratelimited(&pdev->dev, "failed to dma map tx frag\n");
		return -EIO;
	}
	mlxsw_pci_wqe_address_set(wqe, index, mapaddr);
@@ -497,6 +496,7 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
			      struct mlxsw_pci_queue *q)
{
	struct mlxsw_pci_queue_elem_info *elem_info;
	u8 sdq_count = mlxsw_pci_sdq_count(mlxsw_pci);
	int i;
	int err;

@@ -504,9 +504,9 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
	q->consumer_counter = 0;

	/* Set CQ of same number of this RDQ with base
	 * above MLXSW_PCI_SDQS_MAX as the lower ones are assigned to SDQs.
	 * above SDQ count as the lower ones are assigned to SDQs.
	 */
	mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, q->num + MLXSW_PCI_SDQS_COUNT);
	mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, sdq_count + q->num);
	mlxsw_cmd_mbox_sw2hw_dq_log2_dq_sz_set(mbox, 3); /* 8 pages */
	for (i = 0; i < MLXSW_PCI_AQ_PAGES; i++) {
		dma_addr_t mapaddr = __mlxsw_pci_queue_page_get(q, i);
@@ -699,8 +699,8 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
put_new_skb:
	memset(wqe, 0, q->elem_size);
	err = mlxsw_pci_rdq_skb_alloc(mlxsw_pci, elem_info);
	if (err && net_ratelimit())
		dev_dbg(&pdev->dev, "Failed to alloc skb for RDQ\n");
	if (err)
		dev_dbg_ratelimited(&pdev->dev, "Failed to alloc skb for RDQ\n");
	/* Everything is set up, ring doorbell to pass elem to HW */
	q->producer_counter++;
	mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q);
@@ -830,7 +830,8 @@ static void mlxsw_pci_eq_tasklet(unsigned long data)
{
	struct mlxsw_pci_queue *q = (struct mlxsw_pci_queue *) data;
	struct mlxsw_pci *mlxsw_pci = q->pci;
	unsigned long active_cqns[BITS_TO_LONGS(MLXSW_PCI_CQS_COUNT)];
	u8 cq_count = mlxsw_pci_cq_count(mlxsw_pci);
	unsigned long active_cqns[BITS_TO_LONGS(MLXSW_PCI_CQS_MAX)];
	char *eqe;
	u8 cqn;
	bool cq_handle = false;
@@ -866,7 +867,7 @@ static void mlxsw_pci_eq_tasklet(unsigned long data)

	if (!cq_handle)
		return;
	for_each_set_bit(cqn, active_cqns, MLXSW_PCI_CQS_COUNT) {
	for_each_set_bit(cqn, active_cqns, cq_count) {
		q = mlxsw_pci_cq_get(mlxsw_pci, cqn);
		mlxsw_pci_queue_tasklet_schedule(q);
	}
@@ -1067,10 +1068,8 @@ static int mlxsw_pci_aqs_init(struct mlxsw_pci *mlxsw_pci, char *mbox)
	num_eqs = mlxsw_cmd_mbox_query_aq_cap_max_num_eqs_get(mbox);
	eq_log2sz = mlxsw_cmd_mbox_query_aq_cap_log_max_eq_sz_get(mbox);

	if ((num_sdqs != MLXSW_PCI_SDQS_COUNT) ||
	    (num_rdqs != MLXSW_PCI_RDQS_COUNT) ||
	    (num_cqs != MLXSW_PCI_CQS_COUNT) ||
	    (num_eqs != MLXSW_PCI_EQS_COUNT)) {
	if (num_sdqs + num_rdqs > num_cqs ||
	    num_cqs > MLXSW_PCI_CQS_MAX || num_eqs != MLXSW_PCI_EQS_COUNT) {
		dev_err(&pdev->dev, "Unsupported number of queues\n");
		return -EINVAL;
	}
@@ -1272,6 +1271,7 @@ static int mlxsw_pci_fw_area_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
				  u16 num_pages)
{
	struct mlxsw_pci_mem_item *mem_item;
	int nent = 0;
	int i;
	int err;

@@ -1279,7 +1279,7 @@ static int mlxsw_pci_fw_area_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
					   GFP_KERNEL);
	if (!mlxsw_pci->fw_area.items)
		return -ENOMEM;
	mlxsw_pci->fw_area.num_pages = num_pages;
	mlxsw_pci->fw_area.count = num_pages;

	mlxsw_cmd_mbox_zero(mbox);
	for (i = 0; i < num_pages; i++) {
@@ -1293,13 +1293,22 @@ static int mlxsw_pci_fw_area_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
			err = -ENOMEM;
			goto err_alloc;
		}
		mlxsw_cmd_mbox_map_fa_pa_set(mbox, i, mem_item->mapaddr);
		mlxsw_cmd_mbox_map_fa_log2size_set(mbox, i, 0); /* 1 page */
		mlxsw_cmd_mbox_map_fa_pa_set(mbox, nent, mem_item->mapaddr);
		mlxsw_cmd_mbox_map_fa_log2size_set(mbox, nent, 0); /* 1 page */
		if (++nent == MLXSW_CMD_MAP_FA_VPM_ENTRIES_MAX) {
			err = mlxsw_cmd_map_fa(mlxsw_pci->core, mbox, nent);
			if (err)
				goto err_cmd_map_fa;
			nent = 0;
			mlxsw_cmd_mbox_zero(mbox);
		}
	}

	err = mlxsw_cmd_map_fa(mlxsw_pci->core, mbox, num_pages);
	if (nent) {
		err = mlxsw_cmd_map_fa(mlxsw_pci->core, mbox, nent);
		if (err)
			goto err_cmd_map_fa;
	}

	return 0;

@@ -1322,7 +1331,7 @@ static void mlxsw_pci_fw_area_fini(struct mlxsw_pci *mlxsw_pci)

	mlxsw_cmd_unmap_fa(mlxsw_pci->core);

	for (i = 0; i < mlxsw_pci->fw_area.num_pages; i++) {
	for (i = 0; i < mlxsw_pci->fw_area.count; i++) {
		mem_item = &mlxsw_pci->fw_area.items[i];

		pci_free_consistent(mlxsw_pci->pdev, mem_item->size,
+1 −3
Original line number Diff line number Diff line
@@ -71,9 +71,7 @@
#define MLXSW_PCI_DOORBELL(offset, type_offset, num)	\
	((offset) + (type_offset) + (num) * 4)

#define MLXSW_PCI_RDQS_COUNT	24
#define MLXSW_PCI_SDQS_COUNT	24
#define MLXSW_PCI_CQS_COUNT	(MLXSW_PCI_RDQS_COUNT + MLXSW_PCI_SDQS_COUNT)
#define MLXSW_PCI_CQS_MAX	96
#define MLXSW_PCI_EQS_COUNT	2
#define MLXSW_PCI_EQ_ASYNC_NUM	0
#define MLXSW_PCI_EQ_COMP_NUM	1
+48 −73
Original line number Diff line number Diff line
@@ -99,57 +99,6 @@ static const struct mlxsw_reg_info mlxsw_reg_spad = {
 */
MLXSW_ITEM_BUF(reg, spad, base_mac, 0x02, 6);

/* SMID - Switch Multicast ID
 * --------------------------
 * In multi-chip configuration, each device should maintain mapping between
 * Multicast ID (MID) into a list of local ports. This mapping is used in all
 * the devices other than the ingress device, and is implemented as part of the
 * FDB. The MID record maps from a MID, which is a unique identi- fier of the
 * multicast group within the stacking domain, into a list of local ports into
 * which the packet is replicated.
 */
#define MLXSW_REG_SMID_ID 0x2007
#define MLXSW_REG_SMID_LEN 0x420

static const struct mlxsw_reg_info mlxsw_reg_smid = {
	.id = MLXSW_REG_SMID_ID,
	.len = MLXSW_REG_SMID_LEN,
};

/* reg_smid_swid
 * Switch partition ID.
 * Access: Index
 */
MLXSW_ITEM32(reg, smid, swid, 0x00, 24, 8);

/* reg_smid_mid
 * Multicast identifier - global identifier that represents the multicast group
 * across all devices
 * Access: Index
 */
MLXSW_ITEM32(reg, smid, mid, 0x00, 0, 16);

/* reg_smid_port
 * Local port memebership (1 bit per port).
 * Access: RW
 */
MLXSW_ITEM_BIT_ARRAY(reg, smid, port, 0x20, 0x20, 1);

/* reg_smid_port_mask
 * Local port mask (1 bit per port).
 * Access: W
 */
MLXSW_ITEM_BIT_ARRAY(reg, smid, port_mask, 0x220, 0x20, 1);

static inline void mlxsw_reg_smid_pack(char *payload, u16 mid)
{
	MLXSW_REG_ZERO(smid, payload);
	mlxsw_reg_smid_swid_set(payload, 0);
	mlxsw_reg_smid_mid_set(payload, mid);
	mlxsw_reg_smid_port_set(payload, MLXSW_PORT_CPU_PORT, 1);
	mlxsw_reg_smid_port_mask_set(payload, MLXSW_PORT_CPU_PORT, 1);
}

/* SSPR - Switch System Port Record Register
 * -----------------------------------------
 * Configures the system port to local port mapping.
@@ -212,7 +161,7 @@ static inline void mlxsw_reg_sspr_pack(char *payload, u8 local_port)
 * -------------------------------------------
 * Configures the spanning tree state of a physical port.
 */
#define MLXSW_REG_SPMS_ID 0x200d
#define MLXSW_REG_SPMS_ID 0x200D
#define MLXSW_REG_SPMS_LEN 0x404

static const struct mlxsw_reg_info mlxsw_reg_spms = {
@@ -243,11 +192,15 @@ enum mlxsw_reg_spms_state {
 */
MLXSW_ITEM_BIT_ARRAY(reg, spms, state, 0x04, 0x400, 2);

static inline void mlxsw_reg_spms_pack(char *payload, u8 local_port, u16 vid,
				       enum mlxsw_reg_spms_state state)
static inline void mlxsw_reg_spms_pack(char *payload, u8 local_port)
{
	MLXSW_REG_ZERO(spms, payload);
	mlxsw_reg_spms_local_port_set(payload, local_port);
}

static inline void mlxsw_reg_spms_vid_pack(char *payload, u16 vid,
					   enum mlxsw_reg_spms_state state)
{
	mlxsw_reg_spms_state_set(payload, vid, state);
}

@@ -265,13 +218,15 @@ static const struct mlxsw_reg_info mlxsw_reg_sfgc = {
};

enum mlxsw_reg_sfgc_type {
	MLXSW_REG_SFGC_TYPE_BROADCAST = 0,
	MLXSW_REG_SFGC_TYPE_UNKNOWN_UNICAST = 1,
	MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV4 = 2,
	MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV6 = 3,
	MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_NON_IP = 5,
	MLXSW_REG_SFGC_TYPE_IPV4_LINK_LOCAL = 6,
	MLXSW_REG_SFGC_TYPE_IPV6_ALL_HOST = 7,
	MLXSW_REG_SFGC_TYPE_BROADCAST,
	MLXSW_REG_SFGC_TYPE_UNKNOWN_UNICAST,
	MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV4,
	MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV6,
	MLXSW_REG_SFGC_TYPE_RESERVED,
	MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_NON_IP,
	MLXSW_REG_SFGC_TYPE_IPV4_LINK_LOCAL,
	MLXSW_REG_SFGC_TYPE_IPV6_ALL_HOST,
	MLXSW_REG_SFGC_TYPE_MAX,
};

/* reg_sfgc_type
@@ -1013,7 +968,7 @@ static inline void mlxsw_reg_ppcnt_pack(char *payload, u8 local_port)
 * Controls the association of a port with a switch partition and enables
 * configuring ports as stacking ports.
 */
#define MLXSW_REG_PSPA_ID 0x500d
#define MLXSW_REG_PSPA_ID 0x500D
#define MLXSW_REG_PSPA_LEN 0x8

static const struct mlxsw_reg_info mlxsw_reg_pspa = {
@@ -1074,8 +1029,11 @@ MLXSW_ITEM32(reg, htgt, swid, 0x00, 24, 8);
 */
MLXSW_ITEM32(reg, htgt, type, 0x00, 8, 4);

#define MLXSW_REG_HTGT_TRAP_GROUP_EMAD	0x0
#define MLXSW_REG_HTGT_TRAP_GROUP_RX	0x1
enum mlxsw_reg_htgt_trap_group {
	MLXSW_REG_HTGT_TRAP_GROUP_EMAD,
	MLXSW_REG_HTGT_TRAP_GROUP_RX,
	MLXSW_REG_HTGT_TRAP_GROUP_CTRL,
};

/* reg_htgt_trap_group
 * Trap group number. User defined number specifying which trap groups
@@ -1142,6 +1100,7 @@ MLXSW_ITEM32(reg, htgt, local_path_cpu_tclass, 0x10, 16, 6);

#define MLXSW_REG_HTGT_LOCAL_PATH_RDQ_EMAD	0x15
#define MLXSW_REG_HTGT_LOCAL_PATH_RDQ_RX	0x14
#define MLXSW_REG_HTGT_LOCAL_PATH_RDQ_CTRL	0x13

/* reg_htgt_local_path_rdq
 * Receive descriptor queue (RDQ) to use for the trap group.
@@ -1149,21 +1108,29 @@ MLXSW_ITEM32(reg, htgt, local_path_cpu_tclass, 0x10, 16, 6);
 */
MLXSW_ITEM32(reg, htgt, local_path_rdq, 0x10, 0, 6);

static inline void mlxsw_reg_htgt_pack(char *payload, u8 trap_group)
static inline void mlxsw_reg_htgt_pack(char *payload,
				       enum mlxsw_reg_htgt_trap_group group)
{
	u8 swid, rdq;

	MLXSW_REG_ZERO(htgt, payload);
	if (MLXSW_REG_HTGT_TRAP_GROUP_EMAD == trap_group) {
	switch (group) {
	case MLXSW_REG_HTGT_TRAP_GROUP_EMAD:
		swid = MLXSW_PORT_SWID_ALL_SWIDS;
		rdq = MLXSW_REG_HTGT_LOCAL_PATH_RDQ_EMAD;
	} else {
		break;
	case MLXSW_REG_HTGT_TRAP_GROUP_RX:
		swid = 0;
		rdq = MLXSW_REG_HTGT_LOCAL_PATH_RDQ_RX;
		break;
	case MLXSW_REG_HTGT_TRAP_GROUP_CTRL:
		swid = 0;
		rdq = MLXSW_REG_HTGT_LOCAL_PATH_RDQ_CTRL;
		break;
	}
	mlxsw_reg_htgt_swid_set(payload, swid);
	mlxsw_reg_htgt_type_set(payload, MLXSW_REG_HTGT_PATH_TYPE_LOCAL);
	mlxsw_reg_htgt_trap_group_set(payload, trap_group);
	mlxsw_reg_htgt_trap_group_set(payload, group);
	mlxsw_reg_htgt_pide_set(payload, MLXSW_REG_HTGT_POLICER_DISABLE);
	mlxsw_reg_htgt_pid_set(payload, 0);
	mlxsw_reg_htgt_mirror_action_set(payload, MLXSW_REG_HTGT_TRAP_TO_CPU);
@@ -1254,12 +1221,22 @@ enum {
 */
MLXSW_ITEM32(reg, hpkt, ctrl, 0x04, 16, 2);

static inline void mlxsw_reg_hpkt_pack(char *payload, u8 action,
				       u8 trap_group, u16 trap_id)
static inline void mlxsw_reg_hpkt_pack(char *payload, u8 action, u16 trap_id)
{
	enum mlxsw_reg_htgt_trap_group trap_group;

	MLXSW_REG_ZERO(hpkt, payload);
	mlxsw_reg_hpkt_ack_set(payload, MLXSW_REG_HPKT_ACK_NOT_REQUIRED);
	mlxsw_reg_hpkt_action_set(payload, action);
	switch (trap_id) {
	case MLXSW_TRAP_ID_ETHEMAD:
	case MLXSW_TRAP_ID_PUDE:
		trap_group = MLXSW_REG_HTGT_TRAP_GROUP_EMAD;
		break;
	default:
		trap_group = MLXSW_REG_HTGT_TRAP_GROUP_RX;
		break;
	}
	mlxsw_reg_hpkt_trap_group_set(payload, trap_group);
	mlxsw_reg_hpkt_trap_id_set(payload, trap_id);
	mlxsw_reg_hpkt_ctrl_set(payload, MLXSW_REG_HPKT_CTRL_PACKET_DEFAULT);
@@ -1272,8 +1249,6 @@ static inline const char *mlxsw_reg_id_str(u16 reg_id)
		return "SGCR";
	case MLXSW_REG_SPAD_ID:
		return "SPAD";
	case MLXSW_REG_SMID_ID:
		return "SMID";
	case MLXSW_REG_SSPR_ID:
		return "SSPR";
	case MLXSW_REG_SPMS_ID:
Loading