From: Alex Elder <hidden> Date: 2021-03-17 22:30:46
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.
-Alex
Alex Elder (4):
net: ipa: fix assumptions about DMA address size
net: ipa: introduce dma_addr_high32()
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, 41 insertions(+), 19 deletions(-)
--
2.27.0
From: Alex Elder <hidden> Date: 2021-03-17 22:30:47
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-17 22:30:48
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-17 22:30:48
Create a new helper function to encapsulate extracting the
high-order 32 bits of a DMA address. It returns 0 for builds
in which a DMA address is not 64 bits.
This avoids doing a 32-position shift on a DMA address if it
happens not to be 64 bits wide.
Signed-off-by: Alex Elder <redacted>
---
drivers/net/ipa/gsi.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
From: Alex Elder <hidden> Date: 2021-03-17 22:30:48
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);
Create a new helper function to encapsulate extracting the
high-order 32 bits of a DMA address. It returns 0 for builds
in which a DMA address is not 64 bits.
This avoids doing a 32-position shift on a DMA address if it
happens not to be 64 bits wide.
Signed-off-by: Alex Elder <redacted>
---
drivers/net/ipa/gsi.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
Where is that defined? I'd be glad to use it. -Alex
include/linux/kernel.h, and it is upper_32_bits() and lower_32_bits()
sorry about the missing space.
That's nice. I'll still use a separate commit (and will
credit you with the suggestion) but it will be much smaller.
Thanks. I'll post v2 shortly.
-Alex