From: Alex Elder <hidden> Date: 2021-03-18 19:00:33
There is currently a configuration dependency that restricts IPA to
be supported only on 64-bit machines. There are only a few things
that really require that, and those are fixed in this series. The
last patch in the series removes the CONFIG_64BIT build dependency
for IPA.
Version 2 of this series uses upper_32_bits() rather than creating
a new function to extract bits out of a DMA address. Version 3 of
uses lower_32_bits() as well.
-Alex
Alex Elder (4):
net: ipa: fix assumptions about DMA address size
net: ipa: use upper_32_bits()
net: ipa: fix table alignment requirement
net: ipa: relax 64-bit build requirement
drivers/net/ipa/Kconfig | 2 +-
drivers/net/ipa/gsi.c | 14 ++++++--------
drivers/net/ipa/ipa_main.c | 10 ++++++++--
drivers/net/ipa/ipa_table.c | 34 ++++++++++++++++++++--------------
4 files changed, 35 insertions(+), 25 deletions(-)
--
2.27.0
From: Alex Elder <hidden> Date: 2021-03-18 19:00:34
Some build time checks in ipa_table_validate_build() assume that a
DMA address is 64 bits wide. That is more restrictive than it has
to be. A route or filter table is 64 bits wide no matter what the
size of a DMA address is on the AP. The code actually uses a
pointer to __le64 to access table entries, and a fixed constant
IPA_TABLE_ENTRY_SIZE to describe the size of those entries.
Loosen up two checks so they still verify some requirements, but
such that they do not assume the size of a DMA address is 64 bits.
Signed-off-by: Alex Elder <redacted>
---
drivers/net/ipa/ipa_table.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
@@ -126,13 +126,15 @@ static void ipa_table_validate_build(void)*/BUILD_BUG_ON(ARCH_DMA_MINALIGN%IPA_TABLE_ALIGN);-/* Filter and route tables contain DMA addresses that refer to-*filterorrouterules.Weuseafixedconstanttorepresent-*thesizeofeithertypeoftableentry.Codeinipa_table_init()-*usesapointerto__le64toinitializetableentriews.+/* Filter and route tables contain DMA addresses that refer+*tofilterorrouterules.Butthesizeofatableentry+*is64bitsregardlessofwhatthesizeofanAPDMAaddress+*is.Afixedconstantdefinesthesizeofanentry,and+*codeinipa_table_init()usesapointerto__le64to+*initializetables.*/-BUILD_BUG_ON(IPA_TABLE_ENTRY_SIZE!=sizeof(dma_addr_t));-BUILD_BUG_ON(sizeof(dma_addr_t)!=sizeof(__le64));+BUILD_BUG_ON(sizeof(dma_addr_t)>IPA_TABLE_ENTRY_SIZE);+BUILD_BUG_ON(sizeof(__le64)!=IPA_TABLE_ENTRY_SIZE);/* A "zero rule" is used to represent no filtering or no routing.*Itisa64-bitblockofzeroedmemory.Codeinipa_table_init()
From: Alex Elder <hidden> Date: 2021-03-18 19:00:34
We currently have a build-time check to ensure that the minimum DMA
allocation alignment satisfies the constraint that IPA filter and
route tables must point to rules that are 128-byte aligned.
But what's really important is that the actual allocated DMA memory
has that alignment, even if the minimum is smaller than that.
Remove the BUILD_BUG_ON() call checking against minimim DMA alignment
and instead verify at rutime that the allocated memory is properly
aligned.
Signed-off-by: Alex Elder <redacted>
---
drivers/net/ipa/ipa_table.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
@@ -118,14 +118,6 @@/* Check things that can be validated at build time. */staticvoidipa_table_validate_build(void){-/* IPA hardware accesses memory 128 bytes at a time. Addresses-*referredtobyentriesinfilterandroutetablesmustbe-*alignedon128-bytebyteboundaries.Theonlyruleaddress-*everuseisthe"zero rule",andit'salignedatthebase-*ofacoherentDMAallocation.-*/-BUILD_BUG_ON(ARCH_DMA_MINALIGN%IPA_TABLE_ALIGN);-/* Filter and route tables contain DMA addresses that refer*tofilterorrouterules.Butthesizeofatableentry*is64bitsregardlessofwhatthesizeofanAPDMAaddress
@@ -665,6 +657,18 @@ int ipa_table_init(struct ipa *ipa)if(!virt)return-ENOMEM;+/* We put the "zero rule" at the base of our table area. The IPA+*hardwarerequiresrulestobealignedona128-byteboundary.+*Makesuretheallocationsatisfiesthisconstraint.+*/+if(addr%IPA_TABLE_ALIGN){+dev_err(dev,"table address %pad not %u-byte aligned\n",+&addr,IPA_TABLE_ALIGN);+dma_free_coherent(dev,size,virt,addr);++return-ERANGE;+}+ipa->table_virt=virt;ipa->table_addr=addr;
From: Alex Elder <hidden> Date: 2021-03-18 19:00:34
We currently assume the IPA driver is built only for a 64 bit kernel.
When this constraint was put in place it eliminated some do_div()
calls, replacing them with the "/" and "%" operators. We now only
use these operations on u32 and size_t objects. In a 32-bit kernel
build, size_t will be 32 bits wide, so there remains no reason to
use do_div() for divide and modulo.
A few recent commits also fix some code that assumes that DMA
addresses are 64 bits wide.
With that, we can get rid of the 64-bit build requirement.
Signed-off-by: Alex Elder <redacted>
---
drivers/net/ipa/Kconfig | 2 +-
drivers/net/ipa/ipa_main.c | 10 ++++++++--
2 files changed, 9 insertions(+), 3 deletions(-)
@@ -735,8 +735,14 @@ MODULE_DEVICE_TABLE(of, ipa_match);staticvoidipa_validate_build(void){#ifdef IPA_VALIDATE-/* We assume we're working on 64-bit hardware */-BUILD_BUG_ON(!IS_ENABLED(CONFIG_64BIT));+/* At one time we assumed a 64-bit build, allowing some do_div()+*callstobereplacedbysimpledivisionormodulooperations.+*Wecurrentlyonlyperformdivideandmodulooperationsonu32,+*u16,orsize_tobjects,andofthoseonlysize_thasanychance+*ofbeinga64-bitvalue.(Itshouldbeguaranteed32bitswide+*ona32-bitbuild,butthereisnoharminverifyingthat.)+*/+BUILD_BUG_ON(!IS_ENABLED(CONFIG_64BIT)&&sizeof(size_t)!=4);/* Code assumes the EE ID for the AP is 0 (zeroed structure field) */BUILD_BUG_ON(GSI_EE_AP!=0);
From: Alex Elder <hidden> Date: 2021-03-18 19:00:34
Use upper_32_bits() to extract the high-order 32 bits of a DMA
address. This avoids doing a 32-position shift on a DMA address
if it happens not to be 64 bits wide. Use lower_32_bits() to
extract the low-order 32 bits (because that's what it's for).
Suggested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Alex Elder <redacted>
---
v3: - Use upper_32_bits() where appropriate, and lower_32_bits() too.
v2: - Switched to use the upper_32_bits(), as suggested by Florian.
drivers/net/ipa/gsi.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
@@ -351,7 +351,7 @@ void *gsi_ring_virt(struct gsi_ring *ring, u32 index)/* Return the 32-bit DMA address associated with a ring index */staticu32gsi_ring_addr(structgsi_ring*ring,u32index){-return(ring->addr&GENMASK(31,0))+index*GSI_RING_ELEMENT_SIZE;+returnlower_32_bits(ring->addr)+index*GSI_RING_ELEMENT_SIZE;}/* Return the ring index of a 32-bit ring offset */
@@ -708,10 +708,9 @@ static void gsi_evt_ring_program(struct gsi *gsi, u32 evt_ring_id)*high-order32bitsoftheaddressoftheeventring,*respectively.*/-val=evt_ring->ring.addr&GENMASK(31,0);+val=lower_32_bits(evt_ring->ring.addr);iowrite32(val,gsi->virt+GSI_EV_CH_E_CNTXT_2_OFFSET(evt_ring_id));--val=evt_ring->ring.addr>>32;+val=upper_32_bits(evt_ring->ring.addr);iowrite32(val,gsi->virt+GSI_EV_CH_E_CNTXT_3_OFFSET(evt_ring_id));/* Enable interrupt moderation by setting the moderation delay */
@@ -1365,7 +1363,7 @@ static struct gsi_trans *gsi_event_trans(struct gsi_channel *channel,u32tre_index;/* Event xfer_ptr records the TRE it's associated with */-tre_offset=le64_to_cpu(event->xfer_ptr)&GENMASK(31,0);+tre_offset=lower_32_bits(le64_to_cpu(event->xfer_ptr));tre_index=gsi_ring_index(&channel->tre_ring,tre_offset);returngsi_channel_trans_mapped(channel,tre_index);
Use upper_32_bits() to extract the high-order 32 bits of a DMA
address. This avoids doing a 32-position shift on a DMA address
if it happens not to be 64 bits wide. Use lower_32_bits() to
extract the low-order 32 bits (because that's what it's for).
Suggested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Alex Elder <redacted>
Hello:
This series was applied to netdev/net-next.git (refs/heads/master):
On Thu, 18 Mar 2021 13:59:26 -0500 you wrote:
There is currently a configuration dependency that restricts IPA to
be supported only on 64-bit machines. There are only a few things
that really require that, and those are fixed in this series. The
last patch in the series removes the CONFIG_64BIT build dependency
for IPA.
Version 2 of this series uses upper_32_bits() rather than creating
a new function to extract bits out of a DMA address. Version 3 of
uses lower_32_bits() as well.
[...]