Wolfgang On 3/8/19 8:41 AM, Wolfgang Grandegger wrote: > Hello Dan, > > thinking more about it... > > Am 08.03.19 um 14:29 schrieb Wolfgang Grandegger: >> Hello Dan, >> >> Am 08.03.19 um 13:44 schrieb Dan Murphy: >>> Wolfgang >>> >>> On 3/8/19 4:10 AM, Wolfgang Grandegger wrote: >>>> Hallo Dan, >>>> >>>> Am 05.03.19 um 16:52 schrieb Dan Murphy: >>>>> Create a m_can platform framework that peripherial >>>>> devices can register to and use common code and register sets. >>>>> The peripherial devices may provide read/write and configuration >>>>> support of the IP. >>>>> >>>>> Signed-off-by: Dan Murphy <dmur...@ti.com> >>>>> --- >>>>> >>>>> >>>>> v7 - Fixed remaining new checkpatch issues, removed CSR setting, fixed tx >>>>> hard >>>>> start function to return tx_busy, and renamed device callbacks - >>>>> https://lore.kernel.org/patchwork/patch/1047220/ >>>>> >>>>> v6 - Squashed platform patch to this patch for bissectablity, fixed >>>>> coding style >>>>> issues, updated Kconfig help, placed mcan reg offsets back into c file, >>>>> renamed >>>>> priv->skb to priv->tx_skb and cleared perp interrupts at ISR start - >>>>> Patch 1 comments - https://lore.kernel.org/patchwork/patch/1042446/ >>>>> Patch 2 comments - https://lore.kernel.org/patchwork/patch/1042442/ >>>>> >>>>> drivers/net/can/m_can/Kconfig | 13 +- >>>>> drivers/net/can/m_can/Makefile | 1 + >>>>> drivers/net/can/m_can/m_can.c | 700 +++++++++++++------------ >>>>> drivers/net/can/m_can/m_can.h | 110 ++++ >>>>> drivers/net/can/m_can/m_can_platform.c | 202 +++++++ >>>>> 5 files changed, 682 insertions(+), 344 deletions(-) >>>>> create mode 100644 drivers/net/can/m_can/m_can.h >>>>> create mode 100644 drivers/net/can/m_can/m_can_platform.c >>>>> >>>>> diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig >>>>> index 04f20dd39007..f7119fd72df4 100644 >>>>> --- a/drivers/net/can/m_can/Kconfig >>>>> +++ b/drivers/net/can/m_can/Kconfig >>>>> @@ -1,5 +1,14 @@ >>>>> config CAN_M_CAN >>>>> + tristate "Bosch M_CAN support" >>>>> + ---help--- >>>>> + Say Y here if you want support for Bosch M_CAN controller framework. >>>>> + This is common support for devices that embed the Bosch M_CAN IP. >>>>> + >>>>> +config CAN_M_CAN_PLATFORM >>>>> + tristate "Bosch M_CAN support for io-mapped devices" >>>>> depends on HAS_IOMEM >>>>> - tristate "Bosch M_CAN devices" >>>>> + depends on CAN_M_CAN >>>>> ---help--- >>>>> - Say Y here if you want to support for Bosch M_CAN controller. >>>>> + Say Y here if you want support for IO Mapped Bosch M_CAN controller. >>>>> + This support is for devices that have the Bosch M_CAN controller >>>>> + IP embedded into the device and the IP is IO Mapped to the processor. >>>>> diff --git a/drivers/net/can/m_can/Makefile >>>>> b/drivers/net/can/m_can/Makefile >>>>> index 8bbd7f24f5be..057bbcdb3c74 100644 >>>>> --- a/drivers/net/can/m_can/Makefile >>>>> +++ b/drivers/net/can/m_can/Makefile >>>>> @@ -3,3 +3,4 @@ >>>>> # >>>>> >>>>> obj-$(CONFIG_CAN_M_CAN) += m_can.o >>>>> +obj-$(CONFIG_CAN_M_CAN_PLATFORM) += m_can_platform.o >>>>> diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c >>>>> index 9b449400376b..a60278d94126 100644 >>>>> --- a/drivers/net/can/m_can/m_can.c >>>>> +++ b/drivers/net/can/m_can/m_can.c >>>> >>>> ... snip... >>>> >>>>> +static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, >>>>> + struct net_device *dev) >>>>> +{ >>>>> + struct m_can_priv *priv = netdev_priv(dev); >>>>> + >>>>> + if (can_dropped_invalid_skb(dev, skb)) >>>>> + return NETDEV_TX_OK; >>>>> + >>>>> + if (priv->is_peripherial) { >>>>> + if (priv->tx_skb) { >>>>> + netdev_err(dev, "hard_xmit called while tx busy\n"); >>>>> + return NETDEV_TX_BUSY; >>>>> + } >>>> >>>> The problem with that approach is, that the upper layer will try to >>>> resubmit the current "skb" but not the previous "tx_skb". And the >>>> previous "tx_skb" has not been freed yet. I would just drop and free the >>>> skb and return NETDEV_TX_OK in m_can_tx_handler() for peripheral devices >>>> (like can_dropped_invalid_skb() does). >>>> >>> >>> OK. >>> >>> So would this also be a bug in the hi3110 and mcp251x drivers (line 521) as >>> well because besides checking tx_length >>> this is how these drivers are written. >> >> This is different. When entering the "start_xmit" routine, the previous >> TX is still in progress. It will (hopefully) complete soon. Therefore >> returning NETDEV_TX_BUSY is OK. The "start_xmit" routine will be >> recalled soon with the same "skb". That scenario should/could also not >> happen. > > In principle, this also applies to the m_can peripheral devices. If > tx_skb is not NULL, the TX is still in progress and returning > NETDEV_TX_BUSY is just fine. > >> >> In contrast, in "m_can_tx_handler()", the skb could not be handled >> because the FIFO is full. The "start_xmit" routine for peripheral >> devices for that skb already returned NETDEV_TX_OK. Therefore the only >> meaningful action is to drop the skb. Also this error should not happen >> and if, something is going really wrong. Therefore I think, a >> WARN_ONCE() would be even more appropriate. But that should be a >> separate patch. > > But that's a different issue/error. The tx_skb cannot be processed in > "m_can_tx_handler()". Either we drop it or we re-queue it (retry later). >
OK I am a bit confused on this. Are you saying this is not an issue? Or are you saying I need to check for tx_len like the other code? Again if this code is an issue here I believe this is an issue in the hi3110 and mcp251x Dan >>> >>> In addition in the peripheral context the work queue does not report up to >>> the upper layer the status. >>> Again the hi3110 and mcp251x drivers are written this way. >>> >>> The only issue I see here is that the dropped and invalid check needs to >>> come after the tx_skb check. >> >> See above. > > Wolfgang. > -- ------------------ Dan Murphy