public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Daniel Golle <daniel@makrotopia.org>
To: Vladimir Oltean <olteanv@gmail.com>
Cc: Jakub Kicinski <kuba@kernel.org>, Andrew Lunn <andrew@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Paolo Abeni <pabeni@redhat.com>, Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	Simon Horman <horms@kernel.org>,
	netdev@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, Frank Wunderlich <frankwu@gmx.de>,
	Chad Monroe <chad@monroe.io>,
	Cezary Wilmanski <cezary.wilmanski@adtran.com>,
	Liang Xu <lxu@maxlinear.com>, John Crispin <john@phrozen.org>
Subject: Re: [PATCH net-next v13 4/4] net: dsa: add basic initial driver for MxL862xx switches
Date: Fri, 6 Feb 2026 16:43:19 +0000	[thread overview]
Message-ID: <aYYaJ4Yp_MAQ0eqw@makrotopia.org> (raw)
In-Reply-To: <20260206133418.vxui223u4d6jdpql@skbuf>

On Fri, Feb 06, 2026 at 03:34:18PM +0200, Vladimir Oltean wrote:
> On Fri, Feb 06, 2026 at 03:14:26AM +0000, Daniel Golle wrote:
> > Hi Jakub,
> > 
> > thank you for looking into this driver another time.
> > 
> > On Thu, Feb 05, 2026 at 06:21:17PM -0800, Jakub Kicinski wrote:
> > > On Wed, 4 Feb 2026 13:33:19 +0000 Daniel Golle wrote:
> > > > +/* The switch firmware expects all structs to be byte-aligned */
> > > > +#pragma pack(push, 1)
> > > 
> > > "Byte-aligned" means..? Generally aligned means that it starts
> > > at an address which is multiple of X. All addresses are multiple of 1
> > 
> > In case fo the firmware running on this switch it means that data types
> > used in structures used as input and output parameters for firmware
> > functions should be aligned to 8 bits, without any additional padding in
> > between.
> > 
> > struct foo {
> > 	u8	var1;
> > 	__le16	var2;
> > 	__le32	var3;
> > } __packed;
> > 
> > It's size is 7 bytes and it looks like this:
> > 
> > .||||||||.||||||||.||||||||.||||||||.||||||||.||||||||.||||||||.
> > |  var1  |       var2      |                var3               |
> > .        .   LSB  .   MSB  .  LSB                         MSB  .
> > 
> > 
> > This is what the firmware on the other end expects, from all data sent
> > to it and what the Linux host has to expect from all data received from
> > it.
> > 
> > > We used you push back against blanket __packed because it's forcing
> > > all *host* accesses to also assume that the structures are unaligned.
> > 
> > Understand that in general, and of course know that using packed structs
> > without a hardware requirement of doing so needlessly wastes CPU cycles
> > on each access to struct members.
> > 
> > However, in this case this is a header file which exclusively defines
> > structs which are only used to communicate with the firmware running on
> > the switch. Using them for anything else, such as storing or processing
> > data the driver deals with internally is, very inconvenient because all
> > types are also defined as little-endian, so not only unaligned access,
> > but also endian conversion burdens every access (in the sense that it
> > burdens the programmer on little-endian machines, but the CPU as well on
> > big-endian machines).
> > 
> > tl;dr: This whole file is only API definition. And this is how the
> > firmware API is defined, and that's the only way to deal with that
> > switch.
> > 
> > (I would have preferred if they just exposed the internal 16-bit
> > registers of the switch via MDIO, and have asked MxL for that several
> > times, without success)
> > 
> > > The best practice is to pack only specific structs which need it
> > > and add compile_assert()s to make sure that the compiler doesn't add
> > > any padding.
> > 
> > Imho checking whether each of these structs is naturally packed (ie.
> > 8-bit aligned without padding between 8-bit aligned members) is prone to
> > human errors which only become visible when testing on the real
> > hardware, and hence complicates maintainance.
> > 
> > Other drivers which operate on similar APIs (many GPU drivers, for
> > example) also use #pragma pack(push, 1) in header files defining
> > external API. Also there all external API definitions are kept in a
> > separate file, away from any of the datastructures used by the driver
> > internally at runtime.
> > 
> > Anyway, if you really really want me to set individual __packed for each
> > struct which isn't naturally packed in this whole file, please tell me
> > clearly that this is what you would like, and I will of course do it
> > despite disagreeing with the reasoning.
> 
> When I created the pack_fields() API it was exactly for situations like
> this. It helps you keep naturally aligned structures in native CPU
> endianness while adapting to whatever quirks the peripheral you're
> talking to has.

I've spent an hour studying the pack_fields() API and it's (well
written) documentation. The only example of it's use in the current
kernel I could find is the Intel E800 (ICE) driver. And there it does
make sense as it is handling conversion between CPU and hardware formats
in the hotpath for DMA descriptors, a total of 3 different structs, each
with their individual accessor functions.

Using this approach for this switch driver would require writing a lot
of boilerplate code, accessor functions for each and every struct,
and a struct definition once unpacked for the host platform and then
again using the PACKED_FIELD(...) notation for the hardware format.
Surely, most of that could be auto-generated using the existing
vendor drivers API definition. Yet (at least to me) it feels like
over-engineering and also it would require rewriting most of the driver
which has been discussed for almost 2 months now.

Also note that the driver doesn't need the naturally aligned version of
all these structs in native CPU endian -- they are not used for further
processing anything, you can see that because they aren't ever used as a
function parameters, but only ever as exchange formats when
communicating with the firmware.

Maybe I'm missing something obvious here and there is a more simple way
to use this API, some generic macros using compiler introspection to
magically handle everything without needing to write packed and unpacked
struct definitions and individual pack/unpack boiler-plate functions for
each struct. If so, please provide me with an example or explain how you
imagine the pack_fields() API to be used in the context of this driver
and it's total of at more than 30 different structs which will be used
for all the different firmware function I will need to use in order to
implement phylink_pcs as well as the various offloading and VLAN-related
functionality the driver should have in the end (ie. the structs you
currently see in the mxl862xx-api.h file are just a fraction of what I
hope to add there by follow-up series)


  reply	other threads:[~2026-02-06 16:43 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-04 13:32 [PATCH net-next v13 0/4] net: dsa: initial support for MaxLinear MxL862xx switches Daniel Golle
2026-02-04 13:32 ` [PATCH net-next v13 1/4] dt-bindings: net: dsa: add MaxLinear MxL862xx Daniel Golle
2026-02-04 13:33 ` [PATCH net-next v13 2/4] net: dsa: add tag format for MxL862xx switches Daniel Golle
2026-02-06  2:21   ` [net-next,v13,2/4] " Jakub Kicinski
2026-02-06  3:30     ` Daniel Golle
2026-02-07  2:46       ` Jakub Kicinski
2026-02-04 13:33 ` [PATCH net-next v13 3/4] net: mdio: add unlocked mdiodev C45 bus accessors Daniel Golle
2026-02-04 13:33 ` [PATCH net-next v13 4/4] net: dsa: add basic initial driver for MxL862xx switches Daniel Golle
2026-02-06  2:21   ` Jakub Kicinski
2026-02-06  3:14     ` Daniel Golle
2026-02-06 13:34       ` Vladimir Oltean
2026-02-06 16:43         ` Daniel Golle [this message]
2026-02-07 22:14           ` Vladimir Oltean
2026-02-07  2:52       ` Jakub Kicinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aYYaJ4Yp_MAQ0eqw@makrotopia.org \
    --to=daniel@makrotopia.org \
    --cc=andrew@lunn.ch \
    --cc=cezary.wilmanski@adtran.com \
    --cc=chad@monroe.io \
    --cc=conor+dt@kernel.org \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=frankwu@gmx.de \
    --cc=hkallweit1@gmail.com \
    --cc=horms@kernel.org \
    --cc=john@phrozen.org \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=lxu@maxlinear.com \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=robh@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox