From 330ce9d3462e825c44368f58c32d2e2fcf819128 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 13 Feb 2023 10:22:26 -0600 Subject: [PATCH] net: ipa: define more fields for GSI registers Beyond the CH_C_QOS register, two other registers whose offset is related to channel number have fields within them. Define the fields within the CH_C_CNTXT_0 GSI register, using an enumerated type to identify the register's fields, and define an array of field masks to use for that register's reg structure. For the CH_C_CNTXT_1 GSI register, ch_c_cntxt_1_length_encode() previously hid the difference in bit width in the channel ring length field. Instead, define a new field CH_R_LENGTH and encode the ring size with reg_encode(). Signed-off-by: Alex Elder Signed-off-by: Jakub Kicinski --- drivers/net/ipa/gsi.c | 31 ++++++++++--------------------- drivers/net/ipa/gsi_reg.h | 24 +++++++++++++++--------- drivers/net/ipa/reg/gsi_reg-v3.1.c | 23 +++++++++++++++++++++-- drivers/net/ipa/reg/gsi_reg-v3.5.1.c | 23 +++++++++++++++++++++-- drivers/net/ipa/reg/gsi_reg-v4.0.c | 23 +++++++++++++++++++++-- drivers/net/ipa/reg/gsi_reg-v4.5.c | 23 +++++++++++++++++++++-- drivers/net/ipa/reg/gsi_reg-v4.9.c | 23 +++++++++++++++++++++-- 7 files changed, 130 insertions(+), 40 deletions(-) diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c index cbf4b2d..ff00c83 100644 --- a/drivers/net/ipa/gsi.c +++ b/drivers/net/ipa/gsi.c @@ -164,9 +164,6 @@ static void gsi_validate_build(void) */ BUILD_BUG_ON(!is_power_of_2(GSI_RING_ELEMENT_SIZE)); - /* The channel element size must fit in this field */ - BUILD_BUG_ON(GSI_RING_ELEMENT_SIZE > field_max(ELEMENT_SIZE_FMASK)); - /* The event ring element size must fit in this field */ BUILD_BUG_ON(GSI_RING_ELEMENT_SIZE > field_max(EV_ELEMENT_SIZE_FMASK)); } @@ -185,26 +182,18 @@ static bool gsi_channel_initialized(struct gsi_channel *channel) /* Encode the channel protocol for the CH_C_CNTXT_0 register */ static u32 ch_c_cntxt_0_type_encode(enum ipa_version version, + const struct reg *reg, enum gsi_channel_type type) { u32 val; - val = u32_encode_bits(type, CHTYPE_PROTOCOL_FMASK); + val = reg_encode(reg, CHTYPE_PROTOCOL, type); if (version < IPA_VERSION_4_5) return val; - type >>= hweight32(CHTYPE_PROTOCOL_FMASK); - - return val | u32_encode_bits(type, CHTYPE_PROTOCOL_MSB_FMASK); -} - -/* Encode a channel ring buffer length for the CH_C_CNTXT_1 register */ -static u32 ch_c_cntxt_1_length_encode(enum ipa_version version, u32 length) -{ - if (version < IPA_VERSION_4_9) - return u32_encode_bits(length, GENMASK(15, 0)); + type >>= hweight32(reg_fmask(reg, CHTYPE_PROTOCOL)); - return u32_encode_bits(length, GENMASK(19, 0)); + return val | reg_encode(reg, CHTYPE_PROTOCOL_MSB, type); } /* Encode the length of the event channel ring buffer for the @@ -544,7 +533,7 @@ static enum gsi_channel_state gsi_channel_state(struct gsi_channel *channel) reg = gsi_reg(gsi, CH_C_CNTXT_0); val = ioread32(virt + reg_n_offset(reg, channel_id)); - return u32_get_bits(val, CHSTATE_FMASK); + return reg_decode(reg, CHSTATE, val); } /* Issue a channel command and wait for it to complete */ @@ -862,15 +851,15 @@ static void gsi_channel_program(struct gsi_channel *channel, bool doorbell) reg = gsi_reg(gsi, CH_C_CNTXT_0); /* We program all channels as GPI type/protocol */ - val = ch_c_cntxt_0_type_encode(gsi->version, GSI_CHANNEL_TYPE_GPI); + val = ch_c_cntxt_0_type_encode(gsi->version, reg, GSI_CHANNEL_TYPE_GPI); if (channel->toward_ipa) - val |= CHTYPE_DIR_FMASK; - val |= u32_encode_bits(channel->evt_ring_id, ERINDEX_FMASK); - val |= u32_encode_bits(GSI_RING_ELEMENT_SIZE, ELEMENT_SIZE_FMASK); + val |= reg_bit(reg, CHTYPE_DIR); + val |= reg_encode(reg, ERINDEX, channel->evt_ring_id); + val |= reg_encode(reg, ELEMENT_SIZE, GSI_RING_ELEMENT_SIZE); iowrite32(val, gsi->virt + reg_n_offset(reg, channel_id)); reg = gsi_reg(gsi, CH_C_CNTXT_1); - val = ch_c_cntxt_1_length_encode(gsi->version, size); + val = reg_encode(reg, CH_R_LENGTH, size); iowrite32(val, gsi->virt + reg_n_offset(reg, channel_id)); /* The context 2 and 3 registers store the low-order and diff --git a/drivers/net/ipa/gsi_reg.h b/drivers/net/ipa/gsi_reg.h index f625afd..3f1a49a 100644 --- a/drivers/net/ipa/gsi_reg.h +++ b/drivers/net/ipa/gsi_reg.h @@ -96,15 +96,16 @@ enum gsi_reg_id { }; /* CH_C_CNTXT_0 register */ -#define CHTYPE_PROTOCOL_FMASK GENMASK(2, 0) -#define CHTYPE_DIR_FMASK GENMASK(3, 3) -#define EE_FMASK GENMASK(7, 4) -#define CHID_FMASK GENMASK(12, 8) -/* The next field is present for IPA v4.5 and above */ -#define CHTYPE_PROTOCOL_MSB_FMASK GENMASK(13, 13) -#define ERINDEX_FMASK GENMASK(18, 14) -#define CHSTATE_FMASK GENMASK(23, 20) -#define ELEMENT_SIZE_FMASK GENMASK(31, 24) +enum gsi_reg_ch_c_cntxt_0_field_id { + CHTYPE_PROTOCOL, + CHTYPE_DIR, + CH_EE, + CHID, + CHTYPE_PROTOCOL_MSB, /* IPA v4.9+ */ + ERINDEX, + CHSTATE, + ELEMENT_SIZE, +}; /** enum gsi_channel_type - CHTYPE_PROTOCOL field values in CH_C_CNTXT_0 */ enum gsi_channel_type { @@ -120,6 +121,11 @@ enum gsi_channel_type { GSI_CHANNEL_TYPE_11AD = 0x9, }; +/* CH_C_CNTXT_1 register */ +enum gsi_reg_ch_c_cntxt_1_field_id { + CH_R_LENGTH, +}; + /* CH_C_QOS register */ enum gsi_reg_ch_c_qos_field_id { WRR_WEIGHT, diff --git a/drivers/net/ipa/reg/gsi_reg-v3.1.c b/drivers/net/ipa/reg/gsi_reg-v3.1.c index 56cf487..4aa7a1c 100644 --- a/drivers/net/ipa/reg/gsi_reg-v3.1.c +++ b/drivers/net/ipa/reg/gsi_reg-v3.1.c @@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk, /* All other register offsets are relative to gsi->virt */ -REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); +static const u32 reg_ch_c_cntxt_0_fmask[] = { + [CHTYPE_PROTOCOL] = GENMASK(2, 0), + [CHTYPE_DIR] = BIT(3), + [CH_EE] = GENMASK(7, 4), + [CHID] = GENMASK(12, 8), + /* Bit 13 reserved */ + [ERINDEX] = GENMASK(18, 14), + /* Bit 19 reserved */ + [CHSTATE] = GENMASK(23, 20), + [ELEMENT_SIZE] = GENMASK(31, 24), +}; + +REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0, + 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); + +static const u32 reg_ch_c_cntxt_1_fmask[] = { + [CH_R_LENGTH] = GENMASK(15, 0), + /* Bits 16-31 reserved */ +}; -REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); +REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1, + 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80); diff --git a/drivers/net/ipa/reg/gsi_reg-v3.5.1.c b/drivers/net/ipa/reg/gsi_reg-v3.5.1.c index 866bae3..045061a 100644 --- a/drivers/net/ipa/reg/gsi_reg-v3.5.1.c +++ b/drivers/net/ipa/reg/gsi_reg-v3.5.1.c @@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk, /* All other register offsets are relative to gsi->virt */ -REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); +static const u32 reg_ch_c_cntxt_0_fmask[] = { + [CHTYPE_PROTOCOL] = GENMASK(2, 0), + [CHTYPE_DIR] = BIT(3), + [CH_EE] = GENMASK(7, 4), + [CHID] = GENMASK(12, 8), + /* Bit 13 reserved */ + [ERINDEX] = GENMASK(18, 14), + /* Bit 19 reserved */ + [CHSTATE] = GENMASK(23, 20), + [ELEMENT_SIZE] = GENMASK(31, 24), +}; + +REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0, + 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); + +static const u32 reg_ch_c_cntxt_1_fmask[] = { + [CH_R_LENGTH] = GENMASK(15, 0), + /* Bits 16-31 reserved */ +}; -REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); +REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1, + 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80); diff --git a/drivers/net/ipa/reg/gsi_reg-v4.0.c b/drivers/net/ipa/reg/gsi_reg-v4.0.c index 060876e..3374d4e9 100644 --- a/drivers/net/ipa/reg/gsi_reg-v4.0.c +++ b/drivers/net/ipa/reg/gsi_reg-v4.0.c @@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk, /* All other register offsets are relative to gsi->virt */ -REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); +static const u32 reg_ch_c_cntxt_0_fmask[] = { + [CHTYPE_PROTOCOL] = GENMASK(2, 0), + [CHTYPE_DIR] = BIT(3), + [CH_EE] = GENMASK(7, 4), + [CHID] = GENMASK(12, 8), + /* Bit 13 reserved */ + [ERINDEX] = GENMASK(18, 14), + /* Bit 19 reserved */ + [CHSTATE] = GENMASK(23, 20), + [ELEMENT_SIZE] = GENMASK(31, 24), +}; + +REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0, + 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); + +static const u32 reg_ch_c_cntxt_1_fmask[] = { + [CH_R_LENGTH] = GENMASK(15, 0), + /* Bits 16-31 reserved */ +}; -REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); +REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1, + 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80); diff --git a/drivers/net/ipa/reg/gsi_reg-v4.5.c b/drivers/net/ipa/reg/gsi_reg-v4.5.c index 98121fd..0502f3e 100644 --- a/drivers/net/ipa/reg/gsi_reg-v4.5.c +++ b/drivers/net/ipa/reg/gsi_reg-v4.5.c @@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk, /* All other register offsets are relative to gsi->virt */ -REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); +static const u32 reg_ch_c_cntxt_0_fmask[] = { + [CHTYPE_PROTOCOL] = GENMASK(2, 0), + [CHTYPE_DIR] = BIT(3), + [CH_EE] = GENMASK(7, 4), + [CHID] = GENMASK(12, 8), + [CHTYPE_PROTOCOL_MSB] = BIT(13), + [ERINDEX] = GENMASK(18, 14), + /* Bit 19 reserved */ + [CHSTATE] = GENMASK(23, 20), + [ELEMENT_SIZE] = GENMASK(31, 24), +}; + +REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0, + 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); + +static const u32 reg_ch_c_cntxt_1_fmask[] = { + [CH_R_LENGTH] = GENMASK(15, 0), + /* Bits 16-31 reserved */ +}; -REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); +REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1, + 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80); diff --git a/drivers/net/ipa/reg/gsi_reg-v4.9.c b/drivers/net/ipa/reg/gsi_reg-v4.9.c index 72ff788..2c61633 100644 --- a/drivers/net/ipa/reg/gsi_reg-v4.9.c +++ b/drivers/net/ipa/reg/gsi_reg-v4.9.c @@ -18,9 +18,28 @@ REG(INTER_EE_SRC_EV_CH_IRQ_MSK, inter_ee_src_ev_ch_irq_msk, /* All other register offsets are relative to gsi->virt */ -REG_STRIDE(CH_C_CNTXT_0, ch_c_cntxt_0, 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); +static const u32 reg_ch_c_cntxt_0_fmask[] = { + [CHTYPE_PROTOCOL] = GENMASK(2, 0), + [CHTYPE_DIR] = BIT(3), + [CH_EE] = GENMASK(7, 4), + [CHID] = GENMASK(12, 8), + [CHTYPE_PROTOCOL_MSB] = BIT(13), + [ERINDEX] = GENMASK(18, 14), + /* Bit 19 reserved */ + [CHSTATE] = GENMASK(23, 20), + [ELEMENT_SIZE] = GENMASK(31, 24), +}; + +REG_STRIDE_FIELDS(CH_C_CNTXT_0, ch_c_cntxt_0, + 0x0001c000 + 0x4000 * GSI_EE_AP, 0x80); + +static const u32 reg_ch_c_cntxt_1_fmask[] = { + [CH_R_LENGTH] = GENMASK(19, 0), + /* Bits 20-31 reserved */ +}; -REG_STRIDE(CH_C_CNTXT_1, ch_c_cntxt_1, 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); +REG_STRIDE_FIELDS(CH_C_CNTXT_1, ch_c_cntxt_1, + 0x0001c004 + 0x4000 * GSI_EE_AP, 0x80); REG_STRIDE(CH_C_CNTXT_2, ch_c_cntxt_2, 0x0001c008 + 0x4000 * GSI_EE_AP, 0x80); -- 2.7.4