> Subject: Re: [RFC PATCH net-next 5/9] net: phylink: Add phylink_create_raw > > > > On 5/22/2019 7:25 PM, Florian Fainelli wrote: > > > > > > On 5/22/2019 6:20 PM, Ioana Ciornei wrote: > >> This adds a new entry point to PHYLINK that does not require a > >> net_device structure. > >> > >> The main intended use are DSA ports that do not have net devices > >> registered for them (mainly because doing so would be redundant - see > >> Documentation/networking/dsa/dsa.rst for details). So far DSA has > >> been using PHYLIB fixed PHYs for these ports, driven manually with > >> genphy instead of starting a full PHY state machine, but this does > >> not scale well when there are actual PHYs that need a driver on those > >> ports, or when a fixed-link is requested in DT that has a speed > >> unsupported by the fixed PHY C22 emulation (such as SGMII-2500). > >> > >> The proposed solution comes in the form of a notifier chain owned by > >> the PHYLINK instance, and the passing of phylink_notifier_info > >> structures back to the driver through a blocking notifier call. > >> > >> The event API exposed by the new notifier mechanism is a 1:1 mapping > >> to the existing PHYLINK mac_ops, plus the PHYLINK fixed-link callback. > >> > >> Both the standard phylink_create() function, as well as its raw > >> variant, call the same underlying function which initializes either > >> the netdev field or the notifier block of the PHYLINK instance. > >> > >> All PHYLINK driver callbacks have been extended to call the notifier > >> chain in case the instance is a raw one. > >> > >> Signed-off-by: Ioana Ciornei <ioana.cior...@nxp.com> > >> Signed-off-by: Vladimir Oltean <olte...@gmail.com> > >> --- > > > > [snip] > > > >> + struct phylink_notifier_info info = { > >> + .link_an_mode = pl->link_an_mode, > >> + /* Discard const pointer */ > >> + .state = (struct phylink_link_state *)state, > >> + }; > >> + > >> netdev_dbg(pl->netdev, > >> "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u > an=%u\n", > >> __func__, phylink_an_mode_str(pl->link_an_mode), > >> @@ -299,7 +317,12 @@ static void phylink_mac_config(struct phylink *pl, > >> __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising, > >> state->pause, state->link, state->an_enabled); > > > > Don't you need to guard that netdev_dbg() with an if (pl->ops) to > > avoid de-referencing a NULL net_device? > >
The netdev_* print will not dereference a NULL net_device since it has explicit checks agains this. Instead it will just print (net/core/dev.c, __netdev_printk): printk("%s(NULL net_device): %pV", level, vaf); > > Another possibility could be to change the signature of the > > phylink_mac_ops to take an opaque pointer and in the case where we > > called phylink_create() and passed down a net_device pointer, we > > somehow remember that for doing any operation that requires a > > net_device (printing, setting carrier). We lose strict typing in doing > > that, but we'd have fewer places to patch for a blocking notifier call. > > > > Or even make those functions part of phylink_mac_ops such that the caller > could pass an .carrier_ok callback which is netif_carrier_ok() for a > net_device, > else it's NULL, same with printing functions if desired... > -- > Florian Let me see if I understood this correctly. I presume that any API that we add should not break any current PHYLINK users. You suggest to change the prototype of the phylink_mac_ops from void (*validate)(struct net_device *ndev, unsigned long *supported, struct phylink_link_state *state); to something that takes a void pointer: void (*validate)(void *dev, unsigned long *supported, struct phylink_link_state *state); This would imply that the any function in PHYLINK would have to somehow differentiate if the dev provided is indeed a net_device or another structure in order to make the decision if netif_carrier_off should be called or not (this is so we do not break any drivers using PHYLINK). I cannot see how this judgement can be made. -- Ioana