Re: [PATCH net] macmace: Set platform device coherent_dma_mask

2018-05-11 Thread Michael Schmitz
Hi Finn,

Am 11.05.2018 um 22:06 schrieb Finn Thain:
>> You would have to be careful not to overwrite a pdev->dev.dma_mask and 
>> pdev->dev.dma_coherent_mask that might have been set in a platform 
>> device passed via platform_device_register here. Coldfire is the only 
>> m68k platform currently using that, but there might be others in future.
>>
> 
> That Coldfire patch could be reverted if this is a better solution.

True, but there might be other uses for deviating from a platform
default (I'm thinking of Atari SCSI and floppy drivers here). But we
could chose the correct mask to set in arch_setup_pdev_archdata()
instead, as it's a platform property not a driver property in that case.

>> ... But I don't think there are smaller DMA masks used by m68k drivers 
>> that use the platform device mechanism at present. I've only looked at 
>> arch/m68k though.
> 
> So we're back at the same problem that Geert's suggestion also raised: how 
> to identify potentially affected platform devices and drivers?
> 
> Maybe we can take a leaf out of Christoph's book, and leave a noisy 
> WARNING splat in the log.
> 
> void arch_setup_pdev_archdata(struct platform_device *pdev)
> {
> WARN_ON_ONCE(pdev->dev.coherent_dma_mask != DMA_MASK_NONE ||
>  pdev->dev.dma_mask != NULL);

I'd suggest using WARN_ON() so we catch all uses on a particular platform.

I initially thought it necessary to warn on unset mask here, but I see
that would throw up a lot of redundant false positives.

Cheers,

Michael


Re: [PATCH net] macmace: Set platform device coherent_dma_mask

2018-05-11 Thread Michael Schmitz
Hi Finn,

Am 11.05.2018 um 17:28 schrieb Finn Thain:
> On Fri, 11 May 2018, Michael Schmitz wrote:
> 
>>
>> I'm afraid using platform_device_register() (which you already use for 
>> the SCC devices) is the only option handling this on a per-device basis 
>> without touching platform core code, while at the same time keeping the 
>> DMA mask setup out of device drivers
> 
> I don't think that will fly. If you call platform_device_register() and 
> follow that with a dma mask assignment, you could race with the bus 
> matching and driver probe, and we are back to the same WARNING message.

I wasn't proposing to follow platform_device_register() with the mask
assignment, but rather to use the same strategy from the Coldfire FEC
patch (f61e64310b75): set pdev.dev.coherent_dma_mask and
pdev.dev.dma_mask _before_ calling platform_device_register().

> If you want to use platform_device_register(), you'd have to implement 
> arch_setup_pdev_archdata() and use that to set up the dma mask.

If you want to avoid the overhead of defining the macmace platform
device and using platform_device_register() ... seeing as you would not
be defining just the DMA mask and nothing else, that's probably the
least effort for the MACE and SONIC drivers.

>> (I can see Geert's point there - device driver code might be shared 
>> across implementations of the device on platforms with different DMA 
>> mask requirements,, something the driver can't be expected to know 
>> about).
> 
> As I said, these drivers might be expected to be portable between Macs and 
> early PowerMacs, but the same dma mask would apply AFAIK.
> 
> If a platform driver isn't expected to be portable, I think either method 
> is reasonable: arch_setup_pdev_archdata() or the method in the patch.
> 
> Anyway, there is this in arch/powerpc/kernel/setup-common.c:
> 
> void arch_setup_pdev_archdata(struct platform_device *pdev)
> {
> pdev->archdata.dma_mask = DMA_BIT_MASK(32);
> pdev->dev.dma_mask = >archdata.dma_mask;
>   ...

You would have to be careful not to overwrite a pdev->dev.dma_mask and
pdev->dev.dma_coherent_mask that might have been set in a platform
device passed via platform_device_register here. Coldfire is the only
m68k platform currently using that, but there might be others in future.

> I'm inclined to propose something similar for m68k. That should fix the 
> problem, since arch_setup_pdev_archdata() is already in the call chain:
> 
>   platform_device_register_simple()
>   platform_device_register_resndata()
>   platform_device_register_full()
>   platform_device_alloc()
>   arch_setup_pdev_archdata()
> 
> Thoughts? Will this have nasty side effects for m68k platforms that use 
> smaller dma masks?

These can still set a smaller mask in pdev->dev directly and use
platform_device_register() instead. But I don't think there are smaller
DMA masks used by m68k drivers that use the platform device mechanism at
present. I've only looked at arch/m68k though.

Cheers,

Michael


Re: [PATCH net] macmace: Set platform device coherent_dma_mask

2018-05-10 Thread Michael Schmitz
Hi Finn,

Am 11.05.2018 um 15:28 schrieb Finn Thain:
> On Fri, 11 May 2018, Michael Schmitz wrote:
> 
>>>> Which begs the question: why can' you set up all Nubus bus devices' 
>>>> DMA masks in nubus_device_register(), or nubus_add_board()?
>>>
>>> I am expecting to see the same WARNING from the nubus sonic driver but 
>>> it hasn't happened yet, so I don't have a patch for it yet. In 
>>> anycase, the nubus fix would be a lot like the zorro bus fix, so I 
>>> don't see a problem.
>>
>> That's odd. But what I meant to say is that by setting up 
>> dma_coherent_mask in nubus_add_board(), and pointing dma_mask to that, 
>> ypu won't need any patches to Nubus device drivers.
> 
> Right. I think I've already acknowledged that. But it's off-topic, because 
> the patches under review are for platform drivers. Those patches fix an 
> actual bug that I've observed. Whereas, the nubus driver dma mask issue 
> that you raised is purely theoretical at this stage.

I had lost track of the fact that macsonic can be probed as either Nubus
or platform device. Sorry for the noise.

I'm afraid using platform_device_register() (which you already use for
the SCC devices) is the only option handling this on a per-device basis
without touching platform core code, while at the same time keeping the
DMA mask setup out of device drivers (I can see Geert's point there -
device driver code might be shared across implementations of the device
on platforms with different DMA mask requirements,, something the driver
can't be expected to know about).

Cheers,

Michael


Re: [PATCH net] macmace: Set platform device coherent_dma_mask

2018-05-10 Thread Michael Schmitz
Hi Finn,

On Fri, May 11, 2018 at 11:55 AM, Finn Thain  wrote:

>> > What's worse, if you do pass a dma_mask in struct
>> > platform_device_info, you end up with this problem in
>> > platform_device_register_full():
>> >
>> > if (pdevinfo->dma_mask) {
>> > /*
>> >  * This memory isn't freed when the device is put,
>> >  * I don't have a nice idea for that though.  Conceptually
>> >  * dma_mask in struct device should not be a pointer.
>> >  * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
>> >  */
>> > pdev->dev.dma_mask =
>> > kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
>>
>> Maybe platform_device_register_full() should rather check whether
>> dev.coherent_dma_mask is set, and make dev.dma_mask point to that? This
>> is how we solved the warning issue for the Zorro bus devices...
>> (8614f1b58bd0e920a5859464a500b93152c5f8b1)
>>
>
> The claim in the comment above that a pointer is the wrong solution
> suggests that your proposal won't get far. Also, your proposal doesn't

I read the comment to be mostly concerned about not freeing memory,
and attempted to address that. I won't pretend it's the right thing to
do if the pointer will go away anyway, and I certainly won't submit a
patch. Sorry for muddling the issue.

> address the other issues I raised: a new
> platform_device_register_simple_dma() API would only have two callers, and
> the dma mask setup for device-tree probed platform devices is apparently a
> work-in-progress (which I don't want to churn up).

Yes, and that's why I would prefer your old patch handling this in the
device driver (which Geert didn't like), or in the alternative to set
the mask up when registering a device with its bus where appropriate.

I concede this won't help with pure platform devices but as we can't
test all these, we should leave the fix for platfoem devices up to
Christoph.

>
>> > > With people setting the mask to kill the WARNING splat, this may
>> > > become more common.
>> >
>> > Since the commit which introduced the WARNING, only commits f61e64310b75
>> > ("m68k: set dma and coherent masks for platform FEC ethernets") and
>> > 7bcfab202ca7 ("powerpc/macio: set a proper dma_coherent_mask") seem to be
>> > aimed at squelching that WARNING.
>> >
>> > (Am I missing any others?)
>>
>> Zorro devices :-)
>
> Right, I should add commit 55496d3fe2ac ("zorro: Set up z->dev.dma_mask
> for the DMA API") to that list.
>
>> Which begs the question: why can' you set up all Nubus bus devices' DMA
>> masks in nubus_device_register(), or nubus_add_board()?
>
> I am expecting to see the same WARNING from the nubus sonic driver but it
> hasn't happened yet, so I don't have a patch for it yet. In anycase, the
> nubus fix would be a lot like the zorro bus fix, so I don't see a problem.

That's odd. But what I meant to say is that by setting up
dma_coherent_mask in nubus_add_board(), and pointing dma_mask to that,
ypu won't need any patches to Nubus device drivers.

I must be missing something else...

Cheers,

  Michael


>
> --


Re: [PATCH net] macmace: Set platform device coherent_dma_mask

2018-05-10 Thread Michael Schmitz
Hi Finn,

On Thu, May 10, 2018 at 1:25 PM, Finn Thain  wrote:
> On Thu, 3 May 2018, Geert Uytterhoeven wrote:
>
>>
>> Perhaps you can add a new helper
>> (platform_device_register_simple_dma()?) that takes the DMA mask, too?
[...]
> To actually hoist the dma mask setup out of existing platform drivers
> would have implications for every device that matches with those drivers.
>
> That's a bit risky since I can't test those devices -- that's assuming I
> could identify them all; sometimes platform device matching is not well
> defined at build time (see loongson_sysconf.ecname).
>
> So far, it looks like macmace and macsonic would be the only callers of
> this new API call.
>
> What's worse, if you do pass a dma_mask in struct platform_device_info,
> you end up with this problem in platform_device_register_full():
>
> if (pdevinfo->dma_mask) {
> /*
>  * This memory isn't freed when the device is put,
>  * I don't have a nice idea for that though.  Conceptually
>  * dma_mask in struct device should not be a pointer.
>  * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
>  */
> pdev->dev.dma_mask =
> kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);

Maybe platform_device_register_full() should rather check whether
dev.coherent_dma_mask is set, and make dev.dma_mask point to that?
This is how we solved the warning issue for the Zorro bus devices...
(8614f1b58bd0e920a5859464a500b93152c5f8b1)

Not sure what the ramifications of that change would be in the general
case (i.e. platforms where coherent and non-coherent DMA operations
must use different masks). I'd hope all those platforms explicitly set
up their DMA masks anyway.

Your other comment regarding the default used by dma_get_mask() is spot on.

> Most of the platform drivers that call dma_coerce_mask_and_coherent() are
> using pdev->of_match_table, not platform_device_register_simple(). Many of
> them have a comment like this:
>
> /*
>  * Right now device-tree probed devices don't get dma_mask set.
>  * Since shared usb code relies on it, set it here for now.
>  * Once we have dma capability bindings this can go away.
>  */
>
>> With people setting the mask to kill the WARNING splat, this may become
>> more common.
>
> Since the commit which introduced the WARNING, only commits f61e64310b75
> ("m68k: set dma and coherent masks for platform FEC ethernets") and
> 7bcfab202ca7 ("powerpc/macio: set a proper dma_coherent_mask") seem to be
> aimed at squelching that WARNING.
>
> (Am I missing any others?)

Zorro devices :-) Which begs the question: why can' you set up all
Nubus bus devices' DMA masks in nubus_device_register(), or
nubus_add_board()?

> So far, this is not looking like a common problem, and I'm having trouble
> finding some way to improve on my original patches.

Putting this in the core platform device code might have too many
unintended side effects. Platform specific bus drivers or device
drivers might be a safer place to put this. Makes it harder for
Christoph to find all instances of such workarounds though.

Cheers,

  Michael


Re: [PATCH net] macmace: Set platform device coherent_dma_mask

2018-05-04 Thread Michael Schmitz
Hi Geert,

Am 04.05.2018 um 19:24 schrieb Geert Uytterhoeven:
> Hi Michael,
> 
>>> Yes, that would be useful.  The other assumption could be that
>>> platform devices always allow an all-0xff dma mask.
>>
>> That's not always true (Atari NCR5380 SCSI and floppy would use a 24
>> bit DMA mask). We use bounce buffers allocated from a dedicated lowmem
>> pool there currently, and for all I know don't use the DMA API yet.
>>
>> I bet that is a rare exception though. Setting the default DMA mask
>> for platform devices to all-0xff and letting the few odd drivers force
>> a different setting seems the best way forward.
> 
> I'd say that's usually a property of the platform, not of the device?

Right - I was thinking 'm68k' as platform, not a particular machine like
Mac or Falcon (the 24 bit mask only applies to that particular model
anyway).

> So IMHO it belongs in the platform code, not in the device driver code.

OK - let's have a default mask of 64 bit, and allow machine specific
platform_init() to override using a new helper function.

Cheers,

Michael

> Gr{oetje,eeting}s,
> 
> Geert
> 


Re: [PATCH net] macmace: Set platform device coherent_dma_mask

2018-05-03 Thread Michael Schmitz
Hi Christoph,

On Thu, May 3, 2018 at 8:51 PM, Christoph Hellwig  wrote:
> On Thu, May 03, 2018 at 10:46:56AM +0200, Geert Uytterhoeven wrote:
>> Perhaps you can add a new helper (platform_device_register_simple_dma()?)
>> that takes the DMA mask, too?
>> With people setting the mask to kill the WARNING splat, this may become
>> more common.
>>
>> struct platform_device_info already has a dma_mask field, but
>> platform_device_register_resndata() explicitly sets it to zero.
>
> Yes, that would be useful.  The other assumption could be that
> platform devices always allow an all-0xff dma mask.

That's not always true (Atari NCR5380 SCSI and floppy would use a 24
bit DMA mask). We use bounce buffers allocated from a dedicated lowmem
pool there currently, and for all I know don't use the DMA API yet.

I bet that is a rare exception though. Setting the default DMA mask
for platform devices to all-0xff and letting the few odd drivers force
a different setting seems the best way forward.

Cheers,

  Michael



> --
> To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 00/10] New network driver for Amiga X-Surf 100 (m68k)

2018-04-19 Thread Michael Schmitz
Thanks Dave!

And many thanks to all the reviewers and testers!

Cheers,

  Michael


On Fri, Apr 20, 2018 at 8:11 AM, David Miller <da...@davemloft.net> wrote:
> From: Michael Schmitz <schmitz...@gmail.com>
> Date: Thu, 19 Apr 2018 14:05:17 +1200
>
>> This patch series adds support for the Individual Computers X-Surf 100
>> network card for m68k Amiga, a network adapter based on the AX88796 chip set.
>
> Series applied, thank you.


Re: [PATCH v4 00/10] New network driver for Amiga X-Surf 100 (m68k)

2018-04-18 Thread Michael Schmitz
Hi,

messed up the subject there, sorry - this was meant to be

[PATCH v4 0/9] net-next: New network driver for Amiga X-Surf 100 (m68k)

Cheers,

Michael


Am 19.04.2018 um 14:05 schrieb Michael Schmitz:
> [This is a resend of my v3 series which was based on the wrong version and
> tree. Only substantial change is to Asix AX99796B PHY driver.]
> 
> This patch series adds support for the Individual Computers X-Surf 100
> network card for m68k Amiga, a network adapter based on the AX88796 chip set.
> 
> The driver was originally written for kernel version 3.19 by Michael Karcher
> (see CC:), and adapted to 4.16+ for submission to netdev by me. Questions
> regarding motivation for some of the changes are probably best directed at
> Michael Karcher.
> 
> The driver has been tested by Adrian <glaub...@physik.fu-berlin.de> who will
> send his Tested-by tag separately.
> 
> A few changes to the ax88796 driver were required:
> - to read the MAC address, some setup of the ax99796 chip must be done,
> - attach to the MII bus only on device open to allow module unloading,
> - allow to supersede ax_block_input/ax_block_output by card-specific
>   optimized code,
> - use an optional interrupt status callback to allow easier sharing of the
>   card interrupt,
> - set IRQF_SHARED if platform IRQ resource is marked shareable
> 
> The Asix Electronix PHY used on the X-Surf 100 is buggy, and causes the
> software reset to hang if the previous command sent to the PHY was also
> a soft reset. This bug requires addition of a PHY driver for Asix PHYs
> to provide a fixed .soft_reset function, included in this series.
> 
> Some additional cleanup:
> - do not attempt to free IRQ in ax_remove (complements 82533ad9a1c),
> - clear platform drvdata on probe fail and module remove.
> 
> Changes since v1:
> 
> Raised in review by Andrew Lunn:
> - move MII code around to avoid need for forward declaration,
> - combine patches 2 and 7 to add cleanup in error path
> 
> Changes since v2:
> 
> - corrected authorship attribution to Michael Karcher
> 
> Suggested by Geert Uytterhoeven:
> - use ei_local->reset_8390() instead of duplicating ax_reset_8390(),
> - use %pR to format struct resource pointers,
> - assign pdev and xs100 pointers in declaration,
> - don't split error messages,
> - change Kconfig logic to only require XSURF100 set on Amiga
> 
> Suggested by Andrew Lunn:
> - add COMPILE_TEST to ax88796 Kconfig options,
> - use new Asix PHY driver for X-Surf 100
> 
> Suggested by Andrew Lunn/Finn Thain:
> - declare struct sk_buff in ax88796.h,
> - correct whitespace error in ax88796.h
> 
> Changes since v3:
> 
> - various checkpatch cleanup
> 
> Andrew Lunn:
> - don't duplicate genphy_soft_reset in Asix PHY driver, just call 
>   genphy_soft_reset after writing zero to control register
> 
> This series' patches, in order:
> 
> 1/9 net-next: phy: new Asix Electronics PHY driver
> 2/9 net-next: ax88796: Fix MAC address reading
> 3/9 net-next: ax88796: Attach MII bus only when open
> 4/9 net-next: ax88796: Do not free IRQ in ax_remove() (already freed in 
> ax_close()).
> 5/9 net-next: ax88796: Add block_input/output hooks to ax_plat_data
> 6/9 net-next: ax88796: add interrupt status callback to platform data
> 7/9 net-next: ax88796: set IRQF_SHARED flag when IRQ resource is marked as 
> shareable
> 8/9 net-next: ax88796: release platform device drvdata on probe error and 
> module remove
> 9/9 net-next: New ax88796 platform driver for Amiga X-Surf 100 Zorro board 
> (m68k)
> 
>  drivers/net/ethernet/8390/Kconfig|   17 ++-
>  drivers/net/ethernet/8390/Makefile   |1 +
>  drivers/net/ethernet/8390/ax88796.c  |  228 
>  drivers/net/ethernet/8390/xsurf100.c |  382 
> ++
>  drivers/net/phy/Kconfig  |6 +
>  drivers/net/phy/Makefile |1 +
>  drivers/net/phy/asix.c   |   63 ++
>  include/net/ax88796.h|   14 ++
>  8 files changed, 617 insertions(+), 95 deletions(-)
> 
> Cheers,
> 
>   Michael
> 


[PATCH v4 8/9] net-next: ax88796: release platform device drvdata on probe error and module remove

2018-04-18 Thread Michael Schmitz
The net device struct pointer is stored as platform device drvdata on
module probe - clear the drvdata entry on probe fail there, as well as
when unloading the module.

Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 229279f..2a0ddec 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -826,6 +826,7 @@ static int ax_remove(struct platform_device *pdev)
release_mem_region(mem->start, resource_size(mem));
}
 
+   platform_set_drvdata(pdev, NULL);
free_netdev(dev);
 
return 0;
@@ -959,6 +960,7 @@ static int ax_probe(struct platform_device *pdev)
release_mem_region(mem->start, mem_size);
 
  exit_mem:
+   platform_set_drvdata(pdev, NULL);
free_netdev(dev);
 
return ret;
-- 
1.7.0.4



[PATCH v4 2/9] net-next: ax88796: Fix MAC address reading

2018-04-18 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

To read the MAC address from the (virtual) SAprom, the remote DMA
unit needs to be set up like for every other process access to card-local
memory.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index da61cf3..ae39375 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -669,10 +669,16 @@ static int ax_init_dev(struct net_device *dev)
if (ax->plat->flags & AXFLG_HAS_EEPROM) {
unsigned char SA_prom[32];
 
+   ei_outb(6, ioaddr + EN0_RCNTLO);
+   ei_outb(0, ioaddr + EN0_RCNTHI);
+   ei_outb(0, ioaddr + EN0_RSARLO);
+   ei_outb(0, ioaddr + EN0_RSARHI);
+   ei_outb(E8390_RREAD + E8390_START, ioaddr + NE_CMD);
for (i = 0; i < sizeof(SA_prom); i += 2) {
SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
SA_prom[i + 1] = ei_inb(ioaddr + NE_DATAPORT);
}
+   ei_outb(ENISR_RDC, ioaddr + EN0_ISR);   /* Ack intr. */
 
if (ax->plat->wordlength == 2)
for (i = 0; i < 16; i++)
-- 
1.7.0.4



[PATCH v4 6/9] net-next: ax88796: add interrupt status callback to platform data

2018-04-18 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

To be able to tell the ax88796 driver whether it is sensible to enter
the 8390 interrupt handler, an "is this interrupt caused by the 88796"
callback has been added to the ax_plat_data structure (with NULL being
compatible to the previous behaviour).

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |   23 +--
 include/net/ax88796.h   |5 +
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 939a572..d283ed0 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -163,6 +163,21 @@ static void ax_reset_8390(struct net_device *dev)
ei_outb(ENISR_RESET, addr + EN0_ISR);   /* Ack intr. */
 }
 
+/* Wrapper for __ei_interrupt for platforms that have a platform-specific
+ * way to find out whether the interrupt request might be caused by
+ * the ax88796 chip.
+ */
+static irqreturn_t ax_ei_interrupt_filtered(int irq, void *dev_id)
+{
+   struct net_device *dev = dev_id;
+   struct ax_device *ax = to_ax_dev(dev);
+   struct platform_device *pdev = to_platform_device(dev->dev.parent);
+
+   if (!ax->plat->check_irq(pdev))
+   return IRQ_NONE;
+
+   return ax_ei_interrupt(irq, dev_id);
+}
 
 static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page)
@@ -482,8 +497,12 @@ static int ax_open(struct net_device *dev)
if (ret)
goto failed_mii;
 
-   ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
- dev->name, dev);
+   if (ax->plat->check_irq)
+   ret = request_irq(dev->irq, ax_ei_interrupt_filtered,
+ ax->irqflags, dev->name, dev);
+   else
+   ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
+ dev->name, dev);
if (ret)
goto failed_request_irq;
 
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
index 363b0ca..84b3785 100644
--- a/include/net/ax88796.h
+++ b/include/net/ax88796.h
@@ -14,6 +14,7 @@
 
 struct sk_buff;
 struct net_device;
+struct platform_device;
 
 #define AXFLG_HAS_EEPROM   (1<<0)
 #define AXFLG_MAC_FROMDEV  (1<<1)  /* device already has MAC */
@@ -35,6 +36,10 @@ struct ax_plat_data {
const unsigned char *buf, int star_page);
void (*block_input)(struct net_device *dev, int count,
struct sk_buff *skb, int ring_offset);
+   /* returns nonzero if a pending interrupt request might by caused by
+* the ax88786. Handles all interrupts if set to NULL
+*/
+   int (*check_irq)(struct platform_device *pdev);
 };
 
 #endif /* __NET_AX88796_PLAT_H */
-- 
1.7.0.4



[PATCH v4 7/9] net-next: ax88796: set IRQF_SHARED flag when IRQ resource is marked as shareable

2018-04-18 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

On the Amiga X-Surf100, the network card interrupt is shared with many
other interrupt sources, so requires the IRQF_SHARED flag to register.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index d283ed0..229279f 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -872,6 +872,9 @@ static int ax_probe(struct platform_device *pdev)
dev->irq = irq->start;
ax->irqflags = irq->flags & IRQF_TRIGGER_MASK;
 
+   if (irq->flags &  IORESOURCE_IRQ_SHAREABLE)
+   ax->irqflags |= IRQF_SHARED;
+
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(>dev, "no MEM specified\n");
-- 
1.7.0.4



[PATCH v4 1/9] net-next: phy: new Asix Electronics PHY driver

2018-04-18 Thread Michael Schmitz
The Asix Electronics PHY found on the X-Surf 100 Amiga Zorro network
card by Individual Computers is buggy, and needs the reset bit toggled
as workaround to make a PHY soft reset succeed.

Add workaround driver just for this special case.

Suggested in xsurf100 patch series review by Andrew Lunn <and...@lunn.ch>

Signed-off-by: Michael Schmitz <schmitz...@gmail.com>

---

Changes in v4:

Andrew Lunn:
- don't duplicate genphy_soft_reset, just call after writing zero
  to control register
---
 drivers/net/phy/Kconfig  |6 
 drivers/net/phy/Makefile |1 +
 drivers/net/phy/asix.c   |   63 ++
 3 files changed, 70 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/phy/asix.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index bdfbabb..edb8b9a 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -218,6 +218,12 @@ config AQUANTIA_PHY
---help---
  Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
 
+config ASIX_PHY
+   tristate "Asix PHYs"
+   help
+ Currently supports the Asix Electronics PHY found in the X-Surf 100
+ AX88796B package.
+
 config AT803X_PHY
tristate "AT803X PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 01acbcb..701ca0b 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -45,6 +45,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m)
 
 obj-$(CONFIG_AMD_PHY)  += amd.o
 obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
+obj-$(CONFIG_ASIX_PHY) += asix.o
 obj-$(CONFIG_AT803X_PHY)   += at803x.o
 obj-$(CONFIG_BCM63XX_PHY)  += bcm63xx.o
 obj-$(CONFIG_BCM7XXX_PHY)  += bcm7xxx.o
diff --git a/drivers/net/phy/asix.c b/drivers/net/phy/asix.c
new file mode 100644
index 000..8ebe7f5
--- /dev/null
+++ b/drivers/net/phy/asix.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Driver for Asix PHYs
+ *
+ * Author: Michael Schmitz <schmitz...@gmail.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PHY_ID_ASIX_AX88796B   0x003b1841
+
+MODULE_DESCRIPTION("Asix PHY driver");
+MODULE_AUTHOR("Michael Schmitz <schmitz...@gmail.com>");
+MODULE_LICENSE("GPL");
+
+/**
+ * asix_soft_reset - software reset the PHY via BMCR_RESET bit
+ * @phydev: target phy_device struct
+ *
+ * Description: Perform a software PHY reset using the standard
+ * BMCR_RESET bit and poll for the reset bit to be cleared.
+ * Toggle BMCR_RESET bit off to accommodate broken AX8796B PHY implementation
+ * such as used on the Individual Computers' X-Surf 100 Zorro card.
+ *
+ * Returns: 0 on success, < 0 on failure
+ */
+static int asix_soft_reset(struct phy_device *phydev)
+{
+   int ret;
+
+   /* Asix PHY won't reset unless reset bit toggles */
+   ret = phy_write(phydev, MII_BMCR, 0);
+   if (ret < 0)
+   return ret;
+
+   return genphy_soft_reset(phydev);
+}
+
+static struct phy_driver asix_driver[] = { {
+   .phy_id = PHY_ID_ASIX_AX88796B,
+   .name   = "Asix Electronics AX88796B",
+   .phy_id_mask= 0xfff0,
+   .features   = PHY_BASIC_FEATURES,
+   .soft_reset = asix_soft_reset,
+} };
+
+module_phy_driver(asix_driver);
+
+static struct mdio_device_id __maybe_unused asix_tbl[] = {
+   { PHY_ID_ASIX_AX88796B, 0xfff0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(mdio, asix_tbl);
-- 
1.7.0.4



[PATCH v4 00/10] New network driver for Amiga X-Surf 100 (m68k)

2018-04-18 Thread Michael Schmitz
[This is a resend of my v3 series which was based on the wrong version and
tree. Only substantial change is to Asix AX99796B PHY driver.]

This patch series adds support for the Individual Computers X-Surf 100
network card for m68k Amiga, a network adapter based on the AX88796 chip set.

The driver was originally written for kernel version 3.19 by Michael Karcher
(see CC:), and adapted to 4.16+ for submission to netdev by me. Questions
regarding motivation for some of the changes are probably best directed at
Michael Karcher.

The driver has been tested by Adrian  who will
send his Tested-by tag separately.

A few changes to the ax88796 driver were required:
- to read the MAC address, some setup of the ax99796 chip must be done,
- attach to the MII bus only on device open to allow module unloading,
- allow to supersede ax_block_input/ax_block_output by card-specific
  optimized code,
- use an optional interrupt status callback to allow easier sharing of the
  card interrupt,
- set IRQF_SHARED if platform IRQ resource is marked shareable

The Asix Electronix PHY used on the X-Surf 100 is buggy, and causes the
software reset to hang if the previous command sent to the PHY was also
a soft reset. This bug requires addition of a PHY driver for Asix PHYs
to provide a fixed .soft_reset function, included in this series.

Some additional cleanup:
- do not attempt to free IRQ in ax_remove (complements 82533ad9a1c),
- clear platform drvdata on probe fail and module remove.

Changes since v1:

Raised in review by Andrew Lunn:
- move MII code around to avoid need for forward declaration,
- combine patches 2 and 7 to add cleanup in error path

Changes since v2:

- corrected authorship attribution to Michael Karcher

Suggested by Geert Uytterhoeven:
- use ei_local->reset_8390() instead of duplicating ax_reset_8390(),
- use %pR to format struct resource pointers,
- assign pdev and xs100 pointers in declaration,
- don't split error messages,
- change Kconfig logic to only require XSURF100 set on Amiga

Suggested by Andrew Lunn:
- add COMPILE_TEST to ax88796 Kconfig options,
- use new Asix PHY driver for X-Surf 100

Suggested by Andrew Lunn/Finn Thain:
- declare struct sk_buff in ax88796.h,
- correct whitespace error in ax88796.h

Changes since v3:

- various checkpatch cleanup

Andrew Lunn:
- don't duplicate genphy_soft_reset in Asix PHY driver, just call 
  genphy_soft_reset after writing zero to control register

This series' patches, in order:

1/9 net-next: phy: new Asix Electronics PHY driver
2/9 net-next: ax88796: Fix MAC address reading
3/9 net-next: ax88796: Attach MII bus only when open
4/9 net-next: ax88796: Do not free IRQ in ax_remove() (already freed in 
ax_close()).
5/9 net-next: ax88796: Add block_input/output hooks to ax_plat_data
6/9 net-next: ax88796: add interrupt status callback to platform data
7/9 net-next: ax88796: set IRQF_SHARED flag when IRQ resource is marked as 
shareable
8/9 net-next: ax88796: release platform device drvdata on probe error and 
module remove
9/9 net-next: New ax88796 platform driver for Amiga X-Surf 100 Zorro board 
(m68k)

 drivers/net/ethernet/8390/Kconfig|   17 ++-
 drivers/net/ethernet/8390/Makefile   |1 +
 drivers/net/ethernet/8390/ax88796.c  |  228 
 drivers/net/ethernet/8390/xsurf100.c |  382 ++
 drivers/net/phy/Kconfig  |6 +
 drivers/net/phy/Makefile |1 +
 drivers/net/phy/asix.c   |   63 ++
 include/net/ax88796.h|   14 ++
 8 files changed, 617 insertions(+), 95 deletions(-)

Cheers,

Michael


[PATCH v4 9/9] net-next: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

2018-04-18 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

Add platform device driver to populate the ax88796 platform data from
information provided by the XSurf100 zorro device driver. The ax88796
module will be loaded through this module's probe function.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>

---

Changes in v3:

Suggested by Geert Uytterhoeven:
- use ei_local->reset_8390() instead of duplicating ax_reset_8390()
- use %pR to format struct resource pointers
- assign pdev and xs100 pointers in declaration
- don't split error messages
- change Kconfig logic to only require XSURF100 set on Amiga

Suggested by Andrew Lunn:
- add COMPILE_TEST to ax88796 Kconfig options
- use new Asix PHY driver for X-Surf 100
---
 drivers/net/ethernet/8390/Kconfig|   17 ++-
 drivers/net/ethernet/8390/Makefile   |1 +
 drivers/net/ethernet/8390/xsurf100.c |  382 ++
 3 files changed, 398 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/8390/xsurf100.c

diff --git a/drivers/net/ethernet/8390/Kconfig 
b/drivers/net/ethernet/8390/Kconfig
index 9fee7c8..f2f0264 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -29,8 +29,8 @@ config PCMCIA_AXNET
  called axnet_cs.  If unsure, say N.
 
 config AX88796
-   tristate "ASIX AX88796 NE2000 clone support"
-   depends on (ARM || MIPS || SUPERH)
+   tristate "ASIX AX88796 NE2000 clone support" if !ZORRO
+   depends on (ARM || MIPS || SUPERH || ZORRO || COMPILE_TEST)
select CRC32
select PHYLIB
select MDIO_BITBANG
@@ -45,6 +45,19 @@ config AX88796_93CX6
---help---
  Select this if your platform comes with an external 93CX6 eeprom.
 
+config XSURF100
+   tristate "Amiga XSurf 100 AX88796/NE2000 clone support"
+   depends on ZORRO
+   select AX88796
+   select ASIX_PHY
+   help
+ This driver is for the Individual Computers X-Surf 100 Ethernet
+ card (based on the Asix AX88796 chip). If you have such a card,
+ say Y. Otherwise, say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called xsurf100.
+
 config HYDRA
tristate "Hydra support"
depends on ZORRO
diff --git a/drivers/net/ethernet/8390/Makefile 
b/drivers/net/ethernet/8390/Makefile
index 1d650e6..85c83c5 100644
--- a/drivers/net/ethernet/8390/Makefile
+++ b/drivers/net/ethernet/8390/Makefile
@@ -16,4 +16,5 @@ obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o
 obj-$(CONFIG_STNIC) += stnic.o 8390.o
 obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
 obj-$(CONFIG_WD80x3) += wd.o 8390.o
+obj-$(CONFIG_XSURF100) += xsurf100.o
 obj-$(CONFIG_ZORRO8390) += zorro8390.o
diff --git a/drivers/net/ethernet/8390/xsurf100.c 
b/drivers/net/ethernet/8390/xsurf100.c
new file mode 100644
index 000..e2c9638
--- /dev/null
+++ b/drivers/net/ethernet/8390/xsurf100.c
@@ -0,0 +1,382 @@
+// SPDX-License-Identifier: GPL-2.0
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \
+   ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0)
+
+#define XS100_IRQSTATUS_BASE 0x40
+#define XS100_8390_BASE 0x800
+
+/* Longword-access area. Translated to 2 16-bit access cycles by the
+ * X-Surf 100 FPGA
+ */
+#define XS100_8390_DATA32_BASE 0x8000
+#define XS100_8390_DATA32_SIZE 0x2000
+/* Sub-Areas for fast data register access; addresses relative to area begin */
+#define XS100_8390_DATA_READ32_BASE 0x0880
+#define XS100_8390_DATA_WRITE32_BASE 0x0C80
+#define XS100_8390_DATA_AREA_SIZE 0x80
+
+#define __NS8390_init ax_NS8390_init
+
+/* force unsigned long back to 'void __iomem *' */
+#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
+
+#define ei_inb(_a) z_readb(ax_convert_addr(_a))
+#define ei_outb(_v, _a) z_writeb(_v, ax_convert_addr(_a))
+
+#define ei_inw(_a) z_readw(ax_convert_addr(_a))
+#define ei_outw(_v, _a) z_writew(_v, ax_convert_addr(_a))
+
+#define ei_inb_p(_a) ei_inb(_a)
+#define ei_outb_p(_v, _a) ei_outb(_v, _a)
+
+/* define EI_SHIFT() to take into account our register offsets */
+#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
+
+/* Ensure we have our RCR base value */
+#define AX88796_PLATFORM
+
+static unsigned char version[] =
+   "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
+
+#include "lib8390.c"
+
+/* from ne.c */
+#define NE_CMD EI_SHIFT(0x00)
+#define NE_RESET   EI_SHIFT(0x1f)
+#define NE_DATAPORTEI_SHIFT(0x10)
+
+struct xsurf100_ax_plat_data {
+   struct ax_plat_data ax;
+   void __iomem *base_regs;
+   void __iomem *data_area;
+};
+
+static int is_xsurf100_network_irq(struct platform_device *pdev)
+{
+   struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(>dev);
+
+   return (readw(xs10

[PATCH v4 3/9] net-next: ax88796: Attach MII bus only when open

2018-04-18 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

Call ax_mii_init in ax_open(), and unregister/remove mdiobus resources
in ax_close().

This is needed to be able to unload the module, as the module is busy
while the MII bus is attached.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
Reviewed-by: Andrew Lunn <and...@lunn.ch>
---
 drivers/net/ethernet/8390/ax88796.c |  183 ++-
 1 files changed, 95 insertions(+), 88 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index ae39375..ab020e6 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -387,6 +387,90 @@ static void ax_phy_switch(struct net_device *dev, int on)
ei_outb(reg_gpoc, ei_local->mem + EI_SHIFT(0x17));
 }
 
+static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+   if (level)
+   ax->reg_memr |= AX_MEMR_MDC;
+   else
+   ax->reg_memr &= ~AX_MEMR_MDC;
+
+   ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+   if (output)
+   ax->reg_memr &= ~AX_MEMR_MDIR;
+   else
+   ax->reg_memr |= AX_MEMR_MDIR;
+
+   ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static void ax_bb_set_data(struct mdiobb_ctrl *ctrl, int value)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+   if (value)
+   ax->reg_memr |= AX_MEMR_MDO;
+   else
+   ax->reg_memr &= ~AX_MEMR_MDO;
+
+   ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static int ax_bb_get_data(struct mdiobb_ctrl *ctrl)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+   int reg_memr = ei_inb(ax->addr_memr);
+
+   return reg_memr & AX_MEMR_MDI ? 1 : 0;
+}
+
+static const struct mdiobb_ops bb_ops = {
+   .owner = THIS_MODULE,
+   .set_mdc = ax_bb_mdc,
+   .set_mdio_dir = ax_bb_dir,
+   .set_mdio_data = ax_bb_set_data,
+   .get_mdio_data = ax_bb_get_data,
+};
+
+static int ax_mii_init(struct net_device *dev)
+{
+   struct platform_device *pdev = to_platform_device(dev->dev.parent);
+   struct ei_device *ei_local = netdev_priv(dev);
+   struct ax_device *ax = to_ax_dev(dev);
+   int err;
+
+   ax->bb_ctrl.ops = _ops;
+   ax->addr_memr = ei_local->mem + AX_MEMR;
+   ax->mii_bus = alloc_mdio_bitbang(>bb_ctrl);
+   if (!ax->mii_bus) {
+   err = -ENOMEM;
+   goto out;
+   }
+
+   ax->mii_bus->name = "ax88796_mii_bus";
+   ax->mii_bus->parent = dev->dev.parent;
+   snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+pdev->name, pdev->id);
+
+   err = mdiobus_register(ax->mii_bus);
+   if (err)
+   goto out_free_mdio_bitbang;
+
+   return 0;
+
+ out_free_mdio_bitbang:
+   free_mdio_bitbang(ax->mii_bus);
+ out:
+   return err;
+}
+
 static int ax_open(struct net_device *dev)
 {
struct ax_device *ax = to_ax_dev(dev);
@@ -394,6 +478,10 @@ static int ax_open(struct net_device *dev)
 
netdev_dbg(dev, "open\n");
 
+   ret = ax_mii_init(dev);
+   if (ret)
+   goto failed_mii;
+
ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
  dev->name, dev);
if (ret)
@@ -421,6 +509,10 @@ static int ax_open(struct net_device *dev)
ax_phy_switch(dev, 0);
free_irq(dev->irq, dev);
  failed_request_irq:
+   /* unregister mdiobus */
+   mdiobus_unregister(ax->mii_bus);
+   free_mdio_bitbang(ax->mii_bus);
+ failed_mii:
return ret;
 }
 
@@ -440,6 +532,9 @@ static int ax_close(struct net_device *dev)
phy_disconnect(dev->phydev);
 
free_irq(dev->irq, dev);
+
+   mdiobus_unregister(ax->mii_bus);
+   free_mdio_bitbang(ax->mii_bus);
return 0;
 }
 
@@ -539,92 +634,8 @@ static void ax_eeprom_register_write(struct eeprom_93cx6 
*eeprom)
 #endif
 };
 
-static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level)
-{
-   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
-
-   if (level)
-   ax->reg_memr |= AX_MEMR_MDC;
-   else
-   ax->reg_memr &= ~AX_MEMR_MDC;
-
-   ei_outb(ax->reg_memr, ax->addr_memr);
-}
-
-static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output)
-{
-   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
-
-   if (output)
- 

[PATCH v4 5/9] net-next: ax88796: Add block_input/output hooks to ax_plat_data

2018-04-18 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

Add platform specific hooks for block transfer reads/writes of packet
buffer data, superseding the default provided ax_block_input/output.
Currently used for m68k Amiga XSurf100.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>

---

Changes in v3:

Suggested by Andrew Lunn/Finn Thain:
- declare struct sk_buff in ax88796.h
- correct whitespace error in ax88796.h
---
 drivers/net/ethernet/8390/ax88796.c |   10 --
 include/net/ax88796.h   |9 +
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index d3f30f1..939a572 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -758,8 +758,14 @@ static int ax_init_dev(struct net_device *dev)
 #endif
 
ei_local->reset_8390 = _reset_8390;
-   ei_local->block_input = _block_input;
-   ei_local->block_output = _block_output;
+   if (ax->plat->block_input)
+   ei_local->block_input = ax->plat->block_input;
+   else
+   ei_local->block_input = _block_input;
+   if (ax->plat->block_output)
+   ei_local->block_output = ax->plat->block_output;
+   else
+   ei_local->block_output = _block_output;
ei_local->get_8390_hdr = _get_8390_hdr;
ei_local->priv = 0;
 
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
index b9a3bec..363b0ca 100644
--- a/include/net/ax88796.h
+++ b/include/net/ax88796.h
@@ -12,6 +12,9 @@
 #ifndef __NET_AX88796_PLAT_H
 #define __NET_AX88796_PLAT_H
 
+struct sk_buff;
+struct net_device;
+
 #define AXFLG_HAS_EEPROM   (1<<0)
 #define AXFLG_MAC_FROMDEV  (1<<1)  /* device already has MAC */
 #define AXFLG_HAS_93CX6(1<<2)  /* use eeprom_93cx6 
driver */
@@ -26,6 +29,12 @@ struct ax_plat_data {
u32 *reg_offsets;   /* register offsets */
u8  *mac_addr;  /* MAC addr (only used when
   AXFLG_MAC_FROMPLATFORM is used */
+
+   /* uses default ax88796 buffer if set to NULL */
+   void (*block_output)(struct net_device *dev, int count,
+   const unsigned char *buf, int star_page);
+   void (*block_input)(struct net_device *dev, int count,
+   struct sk_buff *skb, int ring_offset);
 };
 
 #endif /* __NET_AX88796_PLAT_H */
-- 
1.7.0.4



[PATCH v4 4/9] net-next: ax88796: Do not free IRQ in ax_remove() (already freed in ax_close()).

2018-04-18 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

This complements the fix in 82533ad9a1c ("net: ethernet: ax88796:
don't call free_irq without request_irq first") that removed the
free_irq call in the error path of probe, to also not call free_irq
when remove is called to revert the effects of probe.

Fixes: 82533ad9a1c (net: ethernet: ax88796: don't call free_irq without 
request_irq first)
Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
Reviewed-by: Geert Uytterhoeven <ge...@linux-m68k.org>
---
 drivers/net/ethernet/8390/ax88796.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index ab020e6..d3f30f1 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -790,7 +790,6 @@ static int ax_remove(struct platform_device *pdev)
struct resource *mem;
 
unregister_netdev(dev);
-   free_irq(dev->irq, dev);
 
iounmap(ei_local->mem);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
1.7.0.4



Re: [PATCH v3 1/9] net: phy: new Asix Electronics PHY driver

2018-04-18 Thread Michael Schmitz
Hi Andrew,

I agree, that's much better. I had something like that in mind before
I got distracted...

/me looking for brown paper bag now.

Cheers,

  Michael


On Thu, Apr 19, 2018 at 12:13 AM, Andrew Lunn  wrote:
>> +
>> +/**
>> + * asix_soft_reset - software reset the PHY via BMCR_RESET bit
>> + * @phydev: target phy_device struct
>> + *
>> + * Description: Perform a software PHY reset using the standard
>> + * BMCR_RESET bit and poll for the reset bit to be cleared.
>> + * Toggle BMCR_RESET bit off to accomodate broken PHY implementations
>> + * such as used on the Individual Computers' X-Surf 100 Zorro card.
>> + *
>> + * Returns: 0 on success, < 0 on failure
>> + */
>> +static int asix_soft_reset(struct phy_device *phydev)
>> +{
>> + int ret;
>> +
>> + /* Asix PHY won't reset unless reset bit toggles */
>> + ret = phy_write(phydev, MII_BMCR, 0);
>> + if (ret < 0)
>> + return ret;
>> +
>> + phy_write(phydev, MII_BMCR, BMCR_RESET);
>> +
>> + return phy_poll_reset(phydev);
>> +}
>
> Why not simply:
>
> static int asix_soft_reset(struct phy_device *phydev)
> {
> int ret;
>
> /* Asix PHY won't reset unless reset bit toggles */
> ret = phy_write(phydev, MII_BMCR, 0);
> if (ret < 0)
> return ret;
>
> return genphy_soft_reset(phydev);
> }
>
> Andrew
> --
> To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 00/10] New network driver for Amiga X-Surf 100 (m68k)

2018-04-18 Thread Michael Schmitz
Hi Andrew,

sorry, my mistake. I didn't realize how fast DaveM's tree diverges
from Linus' (and Geert's) once the merge window opens.

Cheers,

  Michael


On Thu, Apr 19, 2018 at 12:19 AM, Andrew Lunn <and...@lunn.ch> wrote:
> On Wed, Apr 18, 2018 at 05:10:45PM +1200, Michael Schmitz wrote:
>> All,
>>
>> just noticed belatedly that the Makefile hunk of patch 9 does no
>> longer apply cleanly in 4.17-rc1, sorry. My series was based on 4.16.
>> I'll resend that one, OK?
>
> Hi Michael
>
> You should be based on DaveM net-next tree:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
>
> Please also have "net-next" in the patch subject. See
> Documentation/networking/netdev-FAQ.txt
>
> Andrew


Re: [PATCH v3 00/10] New network driver for Amiga X-Surf 100 (m68k)

2018-04-18 Thread Michael Schmitz
Hi Finn,

thanks for the feedback!

On Wed, Apr 18, 2018 at 5:45 PM, Finn Thain  wrote:
>> > 1/9 net: phy: new Asix Electronics PHY driver
>> > 2/9 net: ax88796: Fix MAC address reading
>> > 3/9 net: ax88796: Attach MII bus only when open
>> > 4/9 net: ax88796: Do not free IRQ in ax_remove() (already freed in 
>> > ax_close()).
>> > 5/9 net: ax88796: Add block_input/output hooks to ax_plat_data
>
> I found that git am rejects this one, though 'patch' applies it with fuzz.

Can't remember seeing anything there when rebasing the series, odd.

>
>> > 6/9 net: ax88796: add interrupt status callback to platform data
>> > 7/9 net: ax88796: set IRQF_SHARED flag when IRQ resource is marked as 
>> > shareable
>> > 8/9 net: ax88796: release platform device drvdata on probe error and 
>> > module remove
>> > 9/9 net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board 
>> > (m68k)
>
> git am rejected this one and also complained about trailing whitespace.
>
> I'd rebase on v4.17-rc1 and also run checkpatch over the results.

Done that now, thanks. Andrew recommended basing my patches on
net-next so I'll do that before resubmitting.

Cheers,

  Michael

> --
>
>> >
>> >  drivers/net/ethernet/8390/Kconfig|   17 ++-
>> >  drivers/net/ethernet/8390/Makefile   |1 +
>> >  drivers/net/ethernet/8390/ax88796.c  |  228 
>> >  drivers/net/ethernet/8390/xsurf100.c |  381 
>> > ++
>> >  drivers/net/phy/Kconfig  |6 +
>> >  drivers/net/phy/Makefile |1 +
>> >  drivers/net/phy/asix.c   |   65 ++
>> >  drivers/net/phy/phy_device.c |3 +-
>> >  include/linux/phy.h  |1 +
>> >  include/net/ax88796.h|   14 ++
>> >  10 files changed, 621 insertions(+), 96 deletions(-)
>> >
>> > Cheers,
>> >
>> >   Michael


Re: [PATCH v3 00/10] New network driver for Amiga X-Surf 100 (m68k)

2018-04-17 Thread Michael Schmitz
All,

just noticed belatedly that the Makefile hunk of patch 9 does no
longer apply cleanly in 4.17-rc1, sorry. My series was based on 4.16.
I'll resend that one, OK?

Cheers,

  Michael


On Wed, Apr 18, 2018 at 4:26 PM, Michael Schmitz <schmitz...@gmail.com> wrote:
> This patch series adds support for the Individual Computers X-Surf 100
> network card for m68k Amiga, a network adapter based on the AX88796 chip set.
>
> The driver was originally written for kernel version 3.19 by Michael Karcher
> (see CC:), and adapted to 4.16 for submission to netdev by me. Questions
> regarding motivation for some of the changes are probably best directed at
> Michael Karcher.
>
> The driver has been tested by Adrian <glaub...@physik.fu-berlin.de> who will
> send his Tested-by tag separately.
>
> A few changes to the ax88796 driver were required:
> - to read the MAC address, some setup of the ax99796 chip must be done,
> - attach to the MII bus only on device open to allow module unloading,
> - allow to supersede ax_block_input/ax_block_output by card-specific
>   optimized code,
> - use an optional interrupt status callback to allow easier sharing of the
>   card interrupt,
> - set IRQF_SHARED if platform IRQ resource is marked shareable,
>
> The Asix Electronix PHY used on the X-Surf 100 is buggy, and causes the
> software reset to hang if the previous command sent to the PHY was also
> a soft reset. This bug requires addition of a PHY driver for Asix PHYs
> to provide a fixed .soft_reset function, included in this series.
>
> Some additional cleanup:
> - do not attempt to free IRQ in ax_remove (complements 82533ad9a1c),
> - clear platform drvdata on probe fail and module remove.
>
> Changes since v1:
>
> Raised in review by Andrew Lunn:
> - move MII code around to avoid need for forward declaration
> - combine patches 2 and 7 to add cleanup in error path
>
> Changes since v2:
>
> - corrected authorship attribution to Michael Karcher
>
> Suggested by Geert Uytterhoeven:
> - use ei_local->reset_8390() instead of duplicating ax_reset_8390()
> - use %pR to format struct resource pointers
> - assign pdev and xs100 pointers in declaration
> - don't split error messages
> - change Kconfig logic to only require XSURF100 set on Amiga
>
> Suggested by Andrew Lunn:
> - add COMPILE_TEST to ax88796 Kconfig options
> - use new Asix PHY driver for X-Surf 100
>
> Suggested by Andrew Lunn/Finn Thain:
> - declare struct sk_buff in ax88796.h
> - correct whitespace error in ax88796.h
>
> This series' patches, in order:
>
> 1/9 net: phy: new Asix Electronics PHY driver
> 2/9 net: ax88796: Fix MAC address reading
> 3/9 net: ax88796: Attach MII bus only when open
> 4/9 net: ax88796: Do not free IRQ in ax_remove() (already freed in 
> ax_close()).
> 5/9 net: ax88796: Add block_input/output hooks to ax_plat_data
> 6/9 net: ax88796: add interrupt status callback to platform data
> 7/9 net: ax88796: set IRQF_SHARED flag when IRQ resource is marked as 
> shareable
> 8/9 net: ax88796: release platform device drvdata on probe error and module 
> remove
> 9/9 net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)
>
>  drivers/net/ethernet/8390/Kconfig|   17 ++-
>  drivers/net/ethernet/8390/Makefile   |1 +
>  drivers/net/ethernet/8390/ax88796.c  |  228 
>  drivers/net/ethernet/8390/xsurf100.c |  381 
> ++
>  drivers/net/phy/Kconfig  |6 +
>  drivers/net/phy/Makefile |1 +
>  drivers/net/phy/asix.c   |   65 ++
>  drivers/net/phy/phy_device.c |3 +-
>  include/linux/phy.h  |1 +
>  include/net/ax88796.h|   14 ++
>  10 files changed, 621 insertions(+), 96 deletions(-)
>
> Cheers,
>
>   Michael


Re: [PATCH 10/10] net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

2018-04-17 Thread Michael Schmitz
Hi Geert,

On Wed, Apr 18, 2018 at 1:53 AM, Geert Uytterhoeven
 wrote:
>> --- /dev/null
>> +++ b/drivers/net/ethernet/8390/xsurf100.c
>> @@ -0,0 +1,411 @@
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \
>> +   ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0)
>
> Another long define to get rid of? ;-)

I decided to leave it that way - it doesn't stick out quite as badly
as the one in the ESP driver. Give me a yell if you insist.

Cheers,

  Michael


[PATCH v3 1/9] net: phy: new Asix Electronics PHY driver

2018-04-17 Thread Michael Schmitz
The Asix Electronics PHY found on the X-Surf 100 Amiga Zorro network
card by Individual Computers is buggy, and needs the reset bit toggled
as workaround to make a PHY soft reset succed.

Add workaround driver just for this special case. Export phy_poll_reset()
from core phy_device driver to avoid code duplication.

Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/phy/Kconfig  |6 
 drivers/net/phy/Makefile |1 +
 drivers/net/phy/asix.c   |   65 ++
 drivers/net/phy/phy_device.c |3 +-
 include/linux/phy.h  |1 +
 5 files changed, 75 insertions(+), 1 deletions(-)
 create mode 100644 drivers/net/phy/asix.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index bdfbabb..f5b484c 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -218,6 +218,12 @@ config AQUANTIA_PHY
---help---
  Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
 
+config ASIX_PHY
+   tristate "Asix PHYs"
+   ---help---
+ Currently supports the Asix Electronics PHY found in the X-Surf 100
+ AX88796 package.
+
 config AT803X_PHY
tristate "AT803X PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 01acbcb..701ca0b 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -45,6 +45,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m)
 
 obj-$(CONFIG_AMD_PHY)  += amd.o
 obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
+obj-$(CONFIG_ASIX_PHY) += asix.o
 obj-$(CONFIG_AT803X_PHY)   += at803x.o
 obj-$(CONFIG_BCM63XX_PHY)  += bcm63xx.o
 obj-$(CONFIG_BCM7XXX_PHY)  += bcm7xxx.o
diff --git a/drivers/net/phy/asix.c b/drivers/net/phy/asix.c
new file mode 100644
index 000..15e8a0e
--- /dev/null
+++ b/drivers/net/phy/asix.c
@@ -0,0 +1,65 @@
+/*
+ * Driver for Asix PHYs
+ *
+ * Author: Michael Schmitz <schmitz...@gmail.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PHY_ID_ASIX0x003b1841
+
+MODULE_DESCRIPTION("Asix PHY driver");
+MODULE_AUTHOR("Michael Schmitz <schmitz...@gmail.com>");
+MODULE_LICENSE("GPL");
+
+/**
+ * asix_soft_reset - software reset the PHY via BMCR_RESET bit
+ * @phydev: target phy_device struct
+ *
+ * Description: Perform a software PHY reset using the standard
+ * BMCR_RESET bit and poll for the reset bit to be cleared.
+ * Toggle BMCR_RESET bit off to accomodate broken PHY implementations
+ * such as used on the Individual Computers' X-Surf 100 Zorro card.
+ *
+ * Returns: 0 on success, < 0 on failure
+ */
+static int asix_soft_reset(struct phy_device *phydev)
+{
+   int ret;
+
+   /* Asix PHY won't reset unless reset bit toggles */
+   ret = phy_write(phydev, MII_BMCR, 0);
+   if (ret < 0)
+   return ret;
+
+   phy_write(phydev, MII_BMCR, BMCR_RESET);
+
+   return phy_poll_reset(phydev);
+}
+
+static struct phy_driver asix_driver[] = { {
+   .phy_id = PHY_ID_ASIX,
+   .name   = "Asix Electronics",
+   .phy_id_mask= 0xfff0,
+   .features   = PHY_BASIC_FEATURES,
+   .soft_reset = asix_soft_reset,
+} };
+
+module_phy_driver(asix_driver);
+
+static struct mdio_device_id __maybe_unused asix_tbl[] = {
+   { PHY_ID_ASIX, 0xfff0 },
+   { }
+};
+
+MODULE_DEVICE_TABLE(mdio, asix_tbl);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 777912b..fb8c13b 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -833,7 +833,7 @@ void phy_disconnect(struct phy_device *phydev)
  *   standard phy_init_hw() which will zero all the other bits in the BMCR
  *   and reapply all driver-specific and board-specific fixups.
  */
-static int phy_poll_reset(struct phy_device *phydev)
+int phy_poll_reset(struct phy_device *phydev)
 {
/* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
unsigned int retries = 12;
@@ -854,6 +854,7 @@ static int phy_poll_reset(struct phy_device *phydev)
msleep(1);
return 0;
 }
+EXPORT_SYMBOL(phy_poll_reset);
 
 int phy_init_hw(struct phy_device *phydev)
 {
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 7c4c237..fa0c4fd 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -980,6 +980,7 @@ void phy_attached_print(struct phy_device *phydev, const 
char *fmt, ...)
 int genphy_resume(struct phy_device *phydev);
 int genphy_loopback(struct phy_device *phydev, bool enable);
 int genphy_soft_reset(struct phy_device *phydev);
+int phy_p

[PATCH v3 00/10] New network driver for Amiga X-Surf 100 (m68k)

2018-04-17 Thread Michael Schmitz
This patch series adds support for the Individual Computers X-Surf 100
network card for m68k Amiga, a network adapter based on the AX88796 chip set.

The driver was originally written for kernel version 3.19 by Michael Karcher
(see CC:), and adapted to 4.16 for submission to netdev by me. Questions
regarding motivation for some of the changes are probably best directed at
Michael Karcher.

The driver has been tested by Adrian  who will
send his Tested-by tag separately.

A few changes to the ax88796 driver were required:
- to read the MAC address, some setup of the ax99796 chip must be done,
- attach to the MII bus only on device open to allow module unloading,
- allow to supersede ax_block_input/ax_block_output by card-specific
  optimized code,
- use an optional interrupt status callback to allow easier sharing of the
  card interrupt,
- set IRQF_SHARED if platform IRQ resource is marked shareable,

The Asix Electronix PHY used on the X-Surf 100 is buggy, and causes the
software reset to hang if the previous command sent to the PHY was also
a soft reset. This bug requires addition of a PHY driver for Asix PHYs
to provide a fixed .soft_reset function, included in this series.

Some additional cleanup:
- do not attempt to free IRQ in ax_remove (complements 82533ad9a1c),
- clear platform drvdata on probe fail and module remove.

Changes since v1:

Raised in review by Andrew Lunn:
- move MII code around to avoid need for forward declaration
- combine patches 2 and 7 to add cleanup in error path

Changes since v2:

- corrected authorship attribution to Michael Karcher

Suggested by Geert Uytterhoeven:
- use ei_local->reset_8390() instead of duplicating ax_reset_8390()
- use %pR to format struct resource pointers
- assign pdev and xs100 pointers in declaration
- don't split error messages
- change Kconfig logic to only require XSURF100 set on Amiga

Suggested by Andrew Lunn:
- add COMPILE_TEST to ax88796 Kconfig options
- use new Asix PHY driver for X-Surf 100

Suggested by Andrew Lunn/Finn Thain:
- declare struct sk_buff in ax88796.h
- correct whitespace error in ax88796.h

This series' patches, in order:

1/9 net: phy: new Asix Electronics PHY driver
2/9 net: ax88796: Fix MAC address reading
3/9 net: ax88796: Attach MII bus only when open
4/9 net: ax88796: Do not free IRQ in ax_remove() (already freed in ax_close()).
5/9 net: ax88796: Add block_input/output hooks to ax_plat_data
6/9 net: ax88796: add interrupt status callback to platform data
7/9 net: ax88796: set IRQF_SHARED flag when IRQ resource is marked as shareable
8/9 net: ax88796: release platform device drvdata on probe error and module 
remove
9/9 net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

 drivers/net/ethernet/8390/Kconfig|   17 ++-
 drivers/net/ethernet/8390/Makefile   |1 +
 drivers/net/ethernet/8390/ax88796.c  |  228 
 drivers/net/ethernet/8390/xsurf100.c |  381 ++
 drivers/net/phy/Kconfig  |6 +
 drivers/net/phy/Makefile |1 +
 drivers/net/phy/asix.c   |   65 ++
 drivers/net/phy/phy_device.c |3 +-
 include/linux/phy.h  |1 +
 include/net/ax88796.h|   14 ++
 10 files changed, 621 insertions(+), 96 deletions(-)

Cheers,

  Michael


[PATCH v3 9/9] net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

2018-04-17 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

Add platform device driver to populate the ax88796 platform data from
information provided by the XSurf100 zorro device driver. The ax88796
module will be loaded through this module's probe function.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>

---

Changes in v3:
Suggested by Geert Uytterhoeven:
- use ei_local->reset_8390() instead of duplicating ax_reset_8390()
- use %pR to format struct resource pointers
- assign pdev and xs100 pointers in declaration
- don't split error messages
- change Kconfig logic to only require XSURF100 set on Amiga

Suggested by Andrew Lunn:
- add COMPILE_TEST to ax88796 Kconfig options
- use new Asix PHY driver for X-Surf 100
---
 drivers/net/ethernet/8390/Kconfig|   17 ++-
 drivers/net/ethernet/8390/Makefile   |1 +
 drivers/net/ethernet/8390/xsurf100.c |  381 ++
 3 files changed, 397 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/8390/xsurf100.c

diff --git a/drivers/net/ethernet/8390/Kconfig 
b/drivers/net/ethernet/8390/Kconfig
index fdc6734..607dc00 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -29,8 +29,8 @@ config PCMCIA_AXNET
  called axnet_cs.  If unsure, say N.
 
 config AX88796
-   tristate "ASIX AX88796 NE2000 clone support"
-   depends on (ARM || MIPS || SUPERH)
+   tristate "ASIX AX88796 NE2000 clone support" if !ZORRO
+   depends on (ARM || MIPS || SUPERH || ZORRO || COMPILE_TEST)
select CRC32
select PHYLIB
select MDIO_BITBANG
@@ -45,6 +45,19 @@ config AX88796_93CX6
---help---
  Select this if your platform comes with an external 93CX6 eeprom.
 
+config XSURF100
+   tristate "Amiga XSurf 100 AX88796/NE2000 clone support"
+   depends on ZORRO
+   select AX88796
+   select ASIX_PHY
+   ---help---
+ This driver is for the Individual Computers X-Surf 100 Ethernet
+ card (based on the Asix AX88796 chip). If you have such a card,
+ say Y. Otherwise, say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called xsurf100.
+
 config HYDRA
tristate "Hydra support"
depends on ZORRO
diff --git a/drivers/net/ethernet/8390/Makefile 
b/drivers/net/ethernet/8390/Makefile
index f975c2f..3715f8d 100644
--- a/drivers/net/ethernet/8390/Makefile
+++ b/drivers/net/ethernet/8390/Makefile
@@ -16,4 +16,5 @@ obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o
 obj-$(CONFIG_STNIC) += stnic.o 8390.o
 obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
 obj-$(CONFIG_WD80x3) += wd.o 8390.o
+obj-$(CONFIG_XSURF100) += xsurf100.o
 obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o
diff --git a/drivers/net/ethernet/8390/xsurf100.c 
b/drivers/net/ethernet/8390/xsurf100.c
new file mode 100644
index 000..7ab5ca0
--- /dev/null
+++ b/drivers/net/ethernet/8390/xsurf100.c
@@ -0,0 +1,381 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \
+   ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0)
+
+#define XS100_IRQSTATUS_BASE 0x40
+#define XS100_8390_BASE 0x800
+
+/* Longword-access area. Translated to 2 16-bit access cycles by the
+ * X-Surf 100 FPGA
+ */
+#define XS100_8390_DATA32_BASE 0x8000
+#define XS100_8390_DATA32_SIZE 0x2000
+/* Sub-Areas for fast data register access; addresses relative to area begin */
+#define XS100_8390_DATA_READ32_BASE 0x0880
+#define XS100_8390_DATA_WRITE32_BASE 0x0C80
+#define XS100_8390_DATA_AREA_SIZE 0x80
+
+#define __NS8390_init ax_NS8390_init
+
+/* force unsigned long back to 'void __iomem *' */
+#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
+
+#define ei_inb(_a) z_readb(ax_convert_addr(_a))
+#define ei_outb(_v, _a) z_writeb(_v, ax_convert_addr(_a))
+
+#define ei_inw(_a) z_readw(ax_convert_addr(_a))
+#define ei_outw(_v, _a) z_writew(_v, ax_convert_addr(_a))
+
+#define ei_inb_p(_a) ei_inb(_a)
+#define ei_outb_p(_v, _a) ei_outb(_v, _a)
+
+/* define EI_SHIFT() to take into account our register offsets */
+#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
+
+/* Ensure we have our RCR base value */
+#define AX88796_PLATFORM
+
+static unsigned char version[] =
+   "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
+
+#include "lib8390.c"
+
+/* from ne.c */
+#define NE_CMD EI_SHIFT(0x00)
+#define NE_RESET   EI_SHIFT(0x1f)
+#define NE_DATAPORTEI_SHIFT(0x10)
+
+struct xsurf100_ax_plat_data {
+   struct ax_plat_data ax;
+   void __iomem *base_regs;
+   void __iomem *data_area;
+};
+
+static int is_xsurf100_network_irq(struct platform_device *pdev)
+{
+   struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(>dev);
+
+   return (readw(xs100->base_regs + XS100_IRQ

[PATCH v3 4/9] net: ax88796: Do not free IRQ in ax_remove() (already freed in ax_close()).

2018-04-17 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

This complements the fix in 82533ad9a1c ("net: ethernet: ax88796:
don't call free_irq without request_irq first") that removed the
free_irq call in the error path of probe, to also not call free_irq
when remove is called to revert the effects of probe.

Fixes: 82533ad9a1c (net: ethernet: ax88796: don't call free_irq without 
request_irq first)
Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
Reviewed-by: Geert Uytterhoeven <ge...@linux-m68k.org>
---
 drivers/net/ethernet/8390/ax88796.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 83e59ae..ecf104c 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -793,7 +793,6 @@ static int ax_remove(struct platform_device *pdev)
struct resource *mem;
 
unregister_netdev(dev);
-   free_irq(dev->irq, dev);
 
iounmap(ei_local->mem);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
1.7.0.4



[PATCH v3 5/9] net: ax88796: Add block_input/output hooks to ax_plat_data

2018-04-17 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

Add platform specific hooks for block transfer reads/writes of packet
buffer data, superseding the default provided ax_block_input/output.
Currently used for m68k Amiga XSurf100.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>

---

Changes in v3:

Suggested by Andrew Lunn/Finn Thain:
- declare struct sk_buff in ax88796.h
- correct whitespace error
---
 drivers/net/ethernet/8390/ax88796.c |   10 --
 include/net/ax88796.h   |9 +
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index ecf104c..29cde38 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -760,8 +760,14 @@ static int ax_init_dev(struct net_device *dev)
 #endif
 
ei_local->reset_8390 = _reset_8390;
-   ei_local->block_input = _block_input;
-   ei_local->block_output = _block_output;
+   if (ax->plat->block_input)
+   ei_local->block_input = ax->plat->block_input;
+   else
+   ei_local->block_input = _block_input;
+   if (ax->plat->block_output)
+   ei_local->block_output = ax->plat->block_output;
+   else
+   ei_local->block_output = _block_output;
ei_local->get_8390_hdr = _get_8390_hdr;
ei_local->priv = 0;
ei_local->msg_enable = ax_msg_enable;
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
index b9a3bec..363b0ca 100644
--- a/include/net/ax88796.h
+++ b/include/net/ax88796.h
@@ -12,6 +12,9 @@
 #ifndef __NET_AX88796_PLAT_H
 #define __NET_AX88796_PLAT_H
 
+struct sk_buff;
+struct net_device;
+
 #define AXFLG_HAS_EEPROM   (1<<0)
 #define AXFLG_MAC_FROMDEV  (1<<1)  /* device already has MAC */
 #define AXFLG_HAS_93CX6(1<<2)  /* use eeprom_93cx6 
driver */
@@ -26,6 +29,12 @@ struct ax_plat_data {
u32 *reg_offsets;   /* register offsets */
u8  *mac_addr;  /* MAC addr (only used when
   AXFLG_MAC_FROMPLATFORM is used */
+
+   /* uses default ax88796 buffer if set to NULL */
+   void (*block_output)(struct net_device *dev, int count,
+   const unsigned char *buf, int star_page);
+   void (*block_input)(struct net_device *dev, int count,
+   struct sk_buff *skb, int ring_offset);
 };
 
 #endif /* __NET_AX88796_PLAT_H */
-- 
1.7.0.4



[PATCH v3 6/9] net: ax88796: add interrupt status callback to platform data

2018-04-17 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

To be able to tell the ax88796 driver whether it is sensible to enter
the 8390 interrupt handler, an "is this interrupt caused by the 88796"
callback has been added to the ax_plat_data structure (with NULL being
compatible to the previous behaviour).

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |   23 +--
 include/net/ax88796.h   |5 +
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 29cde38..c799441 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -165,6 +165,21 @@ static void ax_reset_8390(struct net_device *dev)
ei_outb(ENISR_RESET, addr + EN0_ISR);   /* Ack intr. */
 }
 
+/* Wrapper for __ei_interrupt for platforms that have a platform-specific
+ * way to find out whether the interrupt request might be caused by
+ * the ax88796 chip.
+ */
+static irqreturn_t ax_ei_interrupt_filtered(int irq, void *dev_id)
+{
+   struct net_device *dev = dev_id;
+   struct ax_device *ax = to_ax_dev(dev);
+   struct platform_device *pdev = to_platform_device(dev->dev.parent);
+
+   if (!ax->plat->check_irq(pdev))
+   return IRQ_NONE;
+
+   return ax_ei_interrupt(irq, dev_id);
+}
 
 static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page)
@@ -484,8 +499,12 @@ static int ax_open(struct net_device *dev)
if (ret)
goto failed_mii;
 
-   ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
- dev->name, dev);
+   if (ax->plat->check_irq)
+   ret = request_irq(dev->irq, ax_ei_interrupt_filtered,
+ ax->irqflags, dev->name, dev);
+   else
+   ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
+ dev->name, dev);
if (ret)
goto failed_request_irq;
 
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
index 363b0ca..84b3785 100644
--- a/include/net/ax88796.h
+++ b/include/net/ax88796.h
@@ -14,6 +14,7 @@
 
 struct sk_buff;
 struct net_device;
+struct platform_device;
 
 #define AXFLG_HAS_EEPROM   (1<<0)
 #define AXFLG_MAC_FROMDEV  (1<<1)  /* device already has MAC */
@@ -35,6 +36,10 @@ struct ax_plat_data {
const unsigned char *buf, int star_page);
void (*block_input)(struct net_device *dev, int count,
struct sk_buff *skb, int ring_offset);
+   /* returns nonzero if a pending interrupt request might by caused by
+* the ax88786. Handles all interrupts if set to NULL
+*/
+   int (*check_irq)(struct platform_device *pdev);
 };
 
 #endif /* __NET_AX88796_PLAT_H */
-- 
1.7.0.4



[PATCH v3 3/9] net: ax88796: Attach MII bus only when open

2018-04-17 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

Call ax_mii_init in ax_open(), and unregister/remove mdiobus resources
in ax_close().

This is needed to be able to unload the module, as the module is busy
while the MII bus is attached.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
Reviewed-by: Andrew Lunn <and...@lunn.ch>
---
 drivers/net/ethernet/8390/ax88796.c |  183 ++-
 1 files changed, 95 insertions(+), 88 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 2a256aa..83e59ae 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -389,6 +389,90 @@ static void ax_phy_switch(struct net_device *dev, int on)
ei_outb(reg_gpoc, ei_local->mem + EI_SHIFT(0x17));
 }
 
+static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+   if (level)
+   ax->reg_memr |= AX_MEMR_MDC;
+   else
+   ax->reg_memr &= ~AX_MEMR_MDC;
+
+   ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+   if (output)
+   ax->reg_memr &= ~AX_MEMR_MDIR;
+   else
+   ax->reg_memr |= AX_MEMR_MDIR;
+
+   ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static void ax_bb_set_data(struct mdiobb_ctrl *ctrl, int value)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+   if (value)
+   ax->reg_memr |= AX_MEMR_MDO;
+   else
+   ax->reg_memr &= ~AX_MEMR_MDO;
+
+   ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static int ax_bb_get_data(struct mdiobb_ctrl *ctrl)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+   int reg_memr = ei_inb(ax->addr_memr);
+
+   return reg_memr & AX_MEMR_MDI ? 1 : 0;
+}
+
+static const struct mdiobb_ops bb_ops = {
+   .owner = THIS_MODULE,
+   .set_mdc = ax_bb_mdc,
+   .set_mdio_dir = ax_bb_dir,
+   .set_mdio_data = ax_bb_set_data,
+   .get_mdio_data = ax_bb_get_data,
+};
+
+static int ax_mii_init(struct net_device *dev)
+{
+   struct platform_device *pdev = to_platform_device(dev->dev.parent);
+   struct ei_device *ei_local = netdev_priv(dev);
+   struct ax_device *ax = to_ax_dev(dev);
+   int err;
+
+   ax->bb_ctrl.ops = _ops;
+   ax->addr_memr = ei_local->mem + AX_MEMR;
+   ax->mii_bus = alloc_mdio_bitbang(>bb_ctrl);
+   if (!ax->mii_bus) {
+   err = -ENOMEM;
+   goto out;
+   }
+
+   ax->mii_bus->name = "ax88796_mii_bus";
+   ax->mii_bus->parent = dev->dev.parent;
+   snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+   pdev->name, pdev->id);
+
+   err = mdiobus_register(ax->mii_bus);
+   if (err)
+   goto out_free_mdio_bitbang;
+
+   return 0;
+
+ out_free_mdio_bitbang:
+   free_mdio_bitbang(ax->mii_bus);
+ out:
+   return err;
+}
+
 static int ax_open(struct net_device *dev)
 {
struct ax_device *ax = to_ax_dev(dev);
@@ -396,6 +480,10 @@ static int ax_open(struct net_device *dev)
 
netdev_dbg(dev, "open\n");
 
+   ret = ax_mii_init(dev);
+   if (ret)
+   goto failed_mii;
+
ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
  dev->name, dev);
if (ret)
@@ -423,6 +511,10 @@ static int ax_open(struct net_device *dev)
ax_phy_switch(dev, 0);
free_irq(dev->irq, dev);
  failed_request_irq:
+   /* unregister mdiobus */
+   mdiobus_unregister(ax->mii_bus);
+   free_mdio_bitbang(ax->mii_bus);
+ failed_mii:
return ret;
 }
 
@@ -442,6 +534,9 @@ static int ax_close(struct net_device *dev)
phy_disconnect(dev->phydev);
 
free_irq(dev->irq, dev);
+
+   mdiobus_unregister(ax->mii_bus);
+   free_mdio_bitbang(ax->mii_bus);
return 0;
 }
 
@@ -541,92 +636,8 @@ static void ax_eeprom_register_write(struct eeprom_93cx6 
*eeprom)
 #endif
 };
 
-static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level)
-{
-   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
-
-   if (level)
-   ax->reg_memr |= AX_MEMR_MDC;
-   else
-   ax->reg_memr &= ~AX_MEMR_MDC;
-
-   ei_outb(ax->reg_memr, ax->addr_memr);
-}
-
-static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output)
-{
-   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
-
-   if (output)
- 

[PATCH v3 8/9] net: ax88796: release platform device drvdata on probe error and module remove

2018-04-17 Thread Michael Schmitz
The net device struct pointer is stored as platform device drvdata on
module probe - clear the drvdata entry on probe fail there, as well as
when unloading the module.

Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index a72dfbc..eb72282 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -829,6 +829,7 @@ static int ax_remove(struct platform_device *pdev)
release_mem_region(mem->start, resource_size(mem));
}
 
+   platform_set_drvdata(pdev, NULL);
free_netdev(dev);
 
return 0;
@@ -962,6 +963,7 @@ static int ax_probe(struct platform_device *pdev)
release_mem_region(mem->start, mem_size);
 
  exit_mem:
+   platform_set_drvdata(pdev, NULL);
free_netdev(dev);
 
return ret;
-- 
1.7.0.4



[PATCH v3 7/9] net: ax88796: set IRQF_SHARED flag when IRQ resource is marked as shareable

2018-04-17 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

On the Amiga X-Surf100, the network card interrupt is shared with many
other interrupt sources, so requires the IRQF_SHARED flag to register.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index c799441..a72dfbc 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -875,6 +875,9 @@ static int ax_probe(struct platform_device *pdev)
dev->irq = irq->start;
ax->irqflags = irq->flags & IRQF_TRIGGER_MASK;
 
+   if (irq->flags &  IORESOURCE_IRQ_SHAREABLE)
+   ax->irqflags |= IRQF_SHARED;
+
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(>dev, "no MEM specified\n");
-- 
1.7.0.4



[PATCH v3 2/9] net: ax88796: Fix MAC address reading

2018-04-17 Thread Michael Schmitz
From: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>

To read the MAC address from the (virtual) SAprom, the remote DMA
unit needs to be set up like for every other process access to card-local
memory.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 2455547..2a256aa 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -671,10 +671,16 @@ static int ax_init_dev(struct net_device *dev)
if (ax->plat->flags & AXFLG_HAS_EEPROM) {
unsigned char SA_prom[32];
 
+   ei_outb(6, ioaddr + EN0_RCNTLO);
+   ei_outb(0, ioaddr + EN0_RCNTHI);
+   ei_outb(0, ioaddr + EN0_RSARLO);
+   ei_outb(0, ioaddr + EN0_RSARHI);
+   ei_outb(E8390_RREAD + E8390_START, ioaddr + NE_CMD);
for (i = 0; i < sizeof(SA_prom); i += 2) {
SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
SA_prom[i + 1] = ei_inb(ioaddr + NE_DATAPORT);
}
+   ei_outb(ENISR_RDC, ioaddr + EN0_ISR);   /* Ack intr. */
 
if (ax->plat->wordlength == 2)
for (i = 0; i < 16; i++)
-- 
1.7.0.4



Re: [PATCH 04/10] net: ax88796: Add block_input/output hooks to ax_plat_data

2018-04-17 Thread Michael Schmitz
Hi Finn,

On Wed, Apr 18, 2018 at 1:23 PM, Finn Thain <fth...@telegraphics.com.au> wrote:
> On Wed, 18 Apr 2018, Michael Schmitz wrote:
>
>> I think this is a false positive - we're encouraged to provide the
>> full parameter list for functions, so the sreuct sk_buff* can't be
>> avoided.
>>
>
> I don't think it's a false positive. I think ax88796.h would need to
> #include .
>
> You may be able to get away with a forward declaration, as in,
> struct skbuff;
> but I'm not sure about that. I would have to build mach-anubis.c to check.

I've added a forward declaration for now - worked for struct
net_device as well (would have been missing from the mach-anubis.c
build as well because of the missing netdevice header).

> But why do you need to pass an skbuff pointer here? xs100_block_input()
> only accesses skb->data.

I'm forced to use the same interface as ax_block_input()
(xs100_block_input is a plug-in replacement for that). But both could
be changed. Let's leave that for later please.

> BTW, this patch has an unrelated whitespace change.

Fixed, thanks.

Cheers,

  Michael

>
> --
>
>> Cheers,
>>
>>   Michael
>>
>>
>> On Wed, Apr 18, 2018 at 6:46 AM, kbuild test robot <l...@intel.com> wrote:
>> > Hi Michael,
>> >
>> > I love your patch! Perhaps something to improve:
>> >
>> > [auto build test WARNING on v4.16]
>> > [cannot apply to net-next/master net/master v4.17-rc1 next-20180417]
>> > [if your patch is applied to the wrong git tree, please drop us a note to 
>> > help improve the system]
>> >
>> > url:
>> > https://github.com/0day-ci/linux/commits/Michael-Schmitz/New-network-driver-for-Amiga-X-Surf-100-m68k/20180417-141150
>> > config: arm-samsung (attached as .config)
>> > compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
>> > reproduce:
>> > wget 
>> > https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross 
>> > -O ~/bin/make.cross
>> > chmod +x ~/bin/make.cross
>> > # save the attached .config to linux build tree
>> > make.cross ARCH=arm
>> >
>> > All warnings (new ones prefixed by >>):
>> >
>> >In file included from arch/arm/mach-s3c24xx/mach-anubis.c:42:0:
>> >>> include/net/ax88796.h:35:11: warning: 'struct sk_buff' declared inside 
>> >>> parameter list will not be visible outside of this definition or 
>> >>> declaration
>> >struct sk_buff *skb, int ring_offset);
>> >   ^~~
>> >
>> > vim +35 include/net/ax88796.h
>> >
>> > 20
>> > 21  struct ax_plat_data {
>> > 22  unsigned int flags;
>> > 23  unsigned charwordlength;/* 1 or 2 */
>> > 24  unsigned chardcr_val;   /* default value for DCR */
>> > 25  unsigned charrcr_val;   /* default value for RCR */
>> > 26  unsigned chargpoc_val;  /* default value for GPOC 
>> > */
>> > 27  u32 *reg_offsets;   /* register offsets */
>> > 28  u8  *mac_addr;  /* MAC addr (only used when
>> > 29 AXFLG_MAC_FROMPLATFORM 
>> > is used */
>> > 30
>> > 31  /* uses default ax88796 buffer if set to NULL */
>> > 32  void (*block_output)(struct net_device *dev, int count,
>> > 33  const unsigned char *buf, int star_page);
>> > 34  void (*block_input)(struct net_device *dev, int count,
>> >   > 35  struct sk_buff *skb, int ring_offset);
>> > 36  };
>> > 37
>> >
>> > ---
>> > 0-DAY kernel test infrastructureOpen Source Technology 
>> > Center
>> > https://lists.01.org/pipermail/kbuild-all   Intel 
>> > Corporation
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/10] net: ax88796: Add block_input/output hooks to ax_plat_data

2018-04-17 Thread Michael Schmitz
Hi Andrew,

ax88796 includes it via linux/netdevice.h. mac-anubis.c doesn't.

Michael Karcher's patches have added forward derclarations for struct
netdevice and struct platform_data already - I'll add struct sk_buff
as suggested by Finn.

Cheers,

  Michael


On Wed, Apr 18, 2018 at 1:19 PM, Andrew Lunn <and...@lunn.ch> wrote:
> On Wed, Apr 18, 2018 at 12:53:21PM +1200, Michael Schmitz wrote:
>> I think this is a false positive - we're encouraged to provide the
>> full parameter list for functions, so the sreuct sk_buff* can't be
>> avoided.
>
> Hi Michael
>
> How is  being included?
>
> You probably want to build using the .config file and see.
>
> Andrew


Re: [PATCH 04/10] net: ax88796: Add block_input/output hooks to ax_plat_data

2018-04-17 Thread Michael Schmitz
I think this is a false positive - we're encouraged to provide the
full parameter list for functions, so the sreuct sk_buff* can't be
avoided.

Cheers,

  Michael


On Wed, Apr 18, 2018 at 6:46 AM, kbuild test robot <l...@intel.com> wrote:
> Hi Michael,
>
> I love your patch! Perhaps something to improve:
>
> [auto build test WARNING on v4.16]
> [cannot apply to net-next/master net/master v4.17-rc1 next-20180417]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Michael-Schmitz/New-network-driver-for-Amiga-X-Surf-100-m68k/20180417-141150
> config: arm-samsung (attached as .config)
> compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
> reproduce:
> wget 
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=arm
>
> All warnings (new ones prefixed by >>):
>
>In file included from arch/arm/mach-s3c24xx/mach-anubis.c:42:0:
>>> include/net/ax88796.h:35:11: warning: 'struct sk_buff' declared inside 
>>> parameter list will not be visible outside of this definition or declaration
>struct sk_buff *skb, int ring_offset);
>   ^~~
>
> vim +35 include/net/ax88796.h
>
> 20
> 21  struct ax_plat_data {
> 22  unsigned int flags;
> 23  unsigned charwordlength;/* 1 or 2 */
> 24  unsigned chardcr_val;   /* default value for DCR */
> 25  unsigned charrcr_val;   /* default value for RCR */
> 26  unsigned chargpoc_val;  /* default value for GPOC */
> 27  u32 *reg_offsets;   /* register offsets */
> 28  u8  *mac_addr;  /* MAC addr (only used when
> 29 AXFLG_MAC_FROMPLATFORM is 
> used */
> 30
> 31  /* uses default ax88796 buffer if set to NULL */
> 32  void (*block_output)(struct net_device *dev, int count,
> 33  const unsigned char *buf, int star_page);
> 34  void (*block_input)(struct net_device *dev, int count,
>   > 35  struct sk_buff *skb, int ring_offset);
> 36  };
> 37
>
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation


Re: [PATCH v2 8/8] net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

2018-04-17 Thread Michael Schmitz
Hi Andrew,

On Wed, Apr 18, 2018 at 1:26 AM, Andrew Lunn <and...@lunn.ch> wrote:
> On Tue, Apr 17, 2018 at 02:08:15PM +1200, Michael Schmitz wrote:
>> Add platform device driver to populate the ax88796 platform data from
>> information provided by the XSurf100 zorro device driver.
>> This driver will have to be loaded before loading the ax88796 module,
>> or compiled as built-in.
>>
>> Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
>> Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
>> ---
>>  drivers/net/ethernet/8390/Kconfig|   14 +-
>>  drivers/net/ethernet/8390/Makefile   |1 +
>>  drivers/net/ethernet/8390/xsurf100.c |  411 
>> ++
>>  3 files changed, 425 insertions(+), 1 deletions(-)
>>  create mode 100644 drivers/net/ethernet/8390/xsurf100.c
>>
>> diff --git a/drivers/net/ethernet/8390/Kconfig 
>> b/drivers/net/ethernet/8390/Kconfig
>> index fdc6734..0cadd45 100644
>> --- a/drivers/net/ethernet/8390/Kconfig
>> +++ b/drivers/net/ethernet/8390/Kconfig
>> @@ -30,7 +30,7 @@ config PCMCIA_AXNET
>>
>>  config AX88796
>>   tristate "ASIX AX88796 NE2000 clone support"
>> - depends on (ARM || MIPS || SUPERH)
>> + depends on (ARM || MIPS || SUPERH || AMIGA)
>
> Hi Michael
>
> Will it compile on other platforms? If so, it is a good idea to add
> COMPILE_TEST as well.

I suppose it will - nothing in there that wouldn't be portable. Well,
let's find out, shall we?

Cheers,

  Michael

>
>  Andrew


Re: [PATCH 10/10] net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

2018-04-17 Thread Michael Schmitz
Hi Geert,

thanks for your suggestions!

On Wed, Apr 18, 2018 at 1:53 AM, Geert Uytterhoeven
<ge...@linux-m68k.org> wrote:
> Hi Michael,
>
> Thanks for your patch!
>
> On Tue, Apr 17, 2018 at 12:04 AM, Michael Schmitz <schmitz...@gmail.com> 
> wrote:
>> Add platform device driver to populate the ax88796 platform data from
>> information provided by the XSurf100 zorro device driver.
>> This driver will have to be loaded before loading the ax88796 module,
>> or compiled as built-in.
>
> Is that really true? The platform device should be probed when both the
> device and driver have been registered, but order shouldn't matter.

Loading the xsurf100 module will pull in the ax88796 module, so order
does not matter. I'll drop that.

>
>> Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
>
> Missing "From: Michael Karcher ..."?

Fixed the authorship now - probably got mangled when squashing in my
local edits.

>
>> Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
>
>> --- a/drivers/net/ethernet/8390/Kconfig
>> +++ b/drivers/net/ethernet/8390/Kconfig
>> @@ -30,7 +30,7 @@ config PCMCIA_AXNET
>>
>>  config AX88796
>> tristate "ASIX AX88796 NE2000 clone support"
>> -   depends on (ARM || MIPS || SUPERH)
>> +   depends on (ARM || MIPS || SUPERH || AMIGA)
>
> s/AMIGA/ZORRO/, for consistency with the below.

Will do.

>
>> select CRC32
>> select PHYLIB
>> select MDIO_BITBANG
>> @@ -45,6 +45,18 @@ config AX88796_93CX6
>> ---help---
>>   Select this if your platform comes with an external 93CX6 eeprom.
>>
>> +config XSURF100
>> +   tristate "Amiga XSurf 100 AX88796/NE2000 clone support"
>> +   depends on ZORRO
>> +   depends on AX88796
>
> It's a bit unfortunate the user has to enable _two_ config options to enable
> this driver.
>
> I see two solutions for that:
>
> 1) Hide the XSURF100 symbol, so it gets enabled automatically if AX88796 is
>enabled on a Zorro bus system:
>
> config XSURF100
> tristate
> depends on ZORRO
> default AX88796
>
> 2) Hide the AX88796 symbol, and let it be selected by XSURF100:
>
> config AX88796
> tristate "ASIX AX88796 NE2000 clone support" if !ZORRO
> depends on ARM || MIPS || SUPERH || ZORRO
> ...
>
> config XSURF100
> tristate "Amiga XSurf 100 AX88796/NE2000 clone support"
> depends on ZORRO
> select AX88796

I'll use the latter -

>> --- /dev/null
>> +++ b/drivers/net/ethernet/8390/xsurf100.c
>> @@ -0,0 +1,411 @@
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \
>> +   ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0)
>
> Another long define to get rid of? ;-)
>
>> +/* Hard reset the card. This used to pause for the same period that a
>> + * 8390 reset command required, but that shouldn't be necessary.
>> + */
>> +static void ax_reset_8390(struct net_device *dev)
>> +{
>> +   struct ei_device *ei_local = netdev_priv(dev);
>> +   unsigned long reset_start_time = jiffies;
>> +   void __iomem *addr = (void __iomem *)dev->base_addr;
>> +
>> +   netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", 
>> jiffies);
>> +
>> +   ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
>> +
>> +   ei_local->txing = 0;
>> +   ei_local->dmaing = 0;
>> +
>> +   /* This check _should_not_ be necessary, omit eventually. */
>> +   while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
>> +   if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
>> +   netdev_warn(dev, "%s: did not complete.\n", 
>> __func__);
>> +   break;
>> +   }
>
> cpu_relax()?
>
> How long does this usually take? If > 1 ms, you can use e.g. msleep(1)
> instead of cpu_relax().

No idea how long this will take - the reset function is lifted
straight out of ax88796.c with no modifications whatsoever.

Come to think of it - it's exported as ei_local->reset_8390 there, so
there is no good reason for even duplicating the code that I can see.
I'lll drop it.

>
>> +   }
>> +
>> +   ei_outb(ENISR_RESET, addr + EN0_ISR);   /* Ack intr. */
>> +}
>
>> +

Re: [PATCH v2 3/8] net: ax88796: Do not free IRQ in ax_remove() (already freed in ax_close()).

2018-04-17 Thread Michael Schmitz
Hi Andrew,

thanks, that's what I was looking for. The next version will have all
but one patch correctly attributed to Michael Karcher.

Cheers,

  Michael


On Wed, Apr 18, 2018 at 9:13 AM, Andrew Lunn <and...@lunn.ch> wrote:
> On Wed, Apr 18, 2018 at 08:32:25AM +1200, Michael Schmitz wrote:
>> Hi Adrian,
>>
>> On Tue, Apr 17, 2018 at 11:40 PM, John Paul Adrian Glaubitz
>> <glaub...@physik.fu-berlin.de> wrote:
>> > On 04/17/2018 04:08 AM, Michael Schmitz wrote:
>> >>
>> >> From: John Paul Adrian Glaubitz <glaub...@physik.fu-berlin.de>
>> >
>> > This should be:
>> >
>> > From: Michael Karcher <deb...@mkarcher.dialup.fu-berlin.de>
>>
>> I haven't found a way to change that in my tree yet, sorry. Unless
>> someone has a simple way to fix patch authorship after a merge, I may
>> have to reimport from scratch.
>
> git commit --am --author=
>
> Andrew


Re: [PATCH v2 3/8] net: ax88796: Do not free IRQ in ax_remove() (already freed in ax_close()).

2018-04-17 Thread Michael Schmitz
Thanks Geert, I'll fix that.

I see my v2 series shows up as new series on patchwork - do I need to
do something different when tagging the next version, Dave?

Cheers,

  Michael


On Wed, Apr 18, 2018 at 1:51 AM, David Miller  wrote:
> From: Geert Uytterhoeven 
> Date: Tue, 17 Apr 2018 10:20:25 +0200
>
>> BTW, I have a git alias for that:
>>
>> $ git help fixes
>> `git fixes' is aliased to `show --format='Fixes: %h ("%s")' -s'
>> $ git fixes 82533ad9a1c
>> Fixes: 82533ad9a1c ("net: ethernet: ax88796: don't call free_irq
>> without request_irq first")
>
> Thanks for sharing :)


Re: [PATCH v2 3/8] net: ax88796: Do not free IRQ in ax_remove() (already freed in ax_close()).

2018-04-17 Thread Michael Schmitz
Hi Adrian,

On Tue, Apr 17, 2018 at 11:40 PM, John Paul Adrian Glaubitz
<glaub...@physik.fu-berlin.de> wrote:
> On 04/17/2018 04:08 AM, Michael Schmitz wrote:
>>
>> From: John Paul Adrian Glaubitz <glaub...@physik.fu-berlin.de>
>
> This should be:
>
> From: Michael Karcher <deb...@mkarcher.dialup.fu-berlin.de>

I haven't found a way to change that in my tree yet, sorry. Unless
someone has a simple way to fix patch authorship after a merge, I may
have to reimport from scratch.

Cheers,

  Michael


Re: [PATCH 08/10] net: ax88796: Make reset more robust on AX88796B

2018-04-17 Thread Michael Schmitz
Thanks Florian,

I'll keep the Asix PHY driver separate from ax88796 for now. Mainly to
simplify testing. Let's see whether it can be used by any other MAC -
can still fold it into ax88796 later.

Cheers,

  Michael


On Wed, Apr 18, 2018 at 6:08 AM, Florian Fainelli  wrote:
> On 04/17/2018 06:01 AM, Andrew Lunn wrote:
>> On Tue, Apr 17, 2018 at 07:18:10AM +0200, Michael Karcher wrote:
>>> [Andrew, sorry for the dup. I did hit reply-to-auhor instead of
>>> reply-to-all first.]
>>>
>>> Andrew Lunn schrieb:
>> This should really be fixed in the PHY driver, not the MAC.
>
> OK - do you want this separate, or as part of this series? Might have
> a few side effects on more commonly used hardware, perhaps?

 Hi Michael

 What PHY driver is used?
>>> The ax88796b comes with its own integrated (buggy) PHY needing this
>>> workaround. This PHY has its own ID which is not known by Linux, so it is
>>> using the genphy driver as fallback.
>>>
 In the driver you can implement a .soft_reset
 function which first does the dummy write, and then uses
 genphy_soft_reset() to do the actual reset.
>>> We could do that - but I dont't see the point in creating a PHY driver
>>> that is only ever used by this MAC driver, just to add a single line to
>>> the genphy driver. If the same PHY might be used with a different MAC,
>>> you definitely would have a point there, though.
>>
>>
>> Hi Michael
>>
>> We try to keep the core code clean, and put all workarounds for buggy
>> hardware in drivers specific to them. It just helps keep the core code
>> maintainable.
>>
>> I would prefer a driver specific to this PHY with the workaround. But
>> lets see what Florian says.
>
> If you are already using the generic PHY driver, coming up with a custom
> one that only overrides the soft_reset and/or config_init callback is
> really not that much work, and as Andrew says, it helps make things
> clearer and properly isolated. As far as where to place that driver, you
> can either create a new file under drivers/net/phy/* or you can even
> register a phy_driver instance from within ax88796 if that makes it any
> clearer.
>
> FWIW, there are plenty of examples where there is a PHY driver used by a
> single MAC, and that is perfectly fine, because the abstraction is still
> preserved.
> --
> Florian


[PATCH v2 4/8] net: ax88796: Add block_input/output hooks to ax_plat_data

2018-04-16 Thread Michael Schmitz
Add platform specific hooks for block transfer reads/writes of packet
buffer data, superseding the default provided ax_block_input/output.
Currently used for m68k Amiga XSurf100.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |   10 --
 include/net/ax88796.h   |9 -
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index ecf104c..29cde38 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -760,8 +760,14 @@ static int ax_init_dev(struct net_device *dev)
 #endif
 
ei_local->reset_8390 = _reset_8390;
-   ei_local->block_input = _block_input;
-   ei_local->block_output = _block_output;
+   if (ax->plat->block_input)
+   ei_local->block_input = ax->plat->block_input;
+   else
+   ei_local->block_input = _block_input;
+   if (ax->plat->block_output)
+   ei_local->block_output = ax->plat->block_output;
+   else
+   ei_local->block_output = _block_output;
ei_local->get_8390_hdr = _get_8390_hdr;
ei_local->priv = 0;
ei_local->msg_enable = ax_msg_enable;
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
index b9a3bec..26cc459 100644
--- a/include/net/ax88796.h
+++ b/include/net/ax88796.h
@@ -8,10 +8,11 @@
  * published by the Free Software Foundation.
  *
 */
-
 #ifndef __NET_AX88796_PLAT_H
 #define __NET_AX88796_PLAT_H
 
+struct net_device;
+
 #define AXFLG_HAS_EEPROM   (1<<0)
 #define AXFLG_MAC_FROMDEV  (1<<1)  /* device already has MAC */
 #define AXFLG_HAS_93CX6(1<<2)  /* use eeprom_93cx6 
driver */
@@ -26,6 +27,12 @@ struct ax_plat_data {
u32 *reg_offsets;   /* register offsets */
u8  *mac_addr;  /* MAC addr (only used when
   AXFLG_MAC_FROMPLATFORM is used */
+
+   /* uses default ax88796 buffer if set to NULL */
+   void (*block_output)(struct net_device *dev, int count,
+   const unsigned char *buf, int star_page);
+   void (*block_input)(struct net_device *dev, int count,
+   struct sk_buff *skb, int ring_offset);
 };
 
 #endif /* __NET_AX88796_PLAT_H */
-- 
1.7.0.4



[PATCH v2 0/8] New network driver for Amiga X-Surf 100 (m68k)

2018-04-16 Thread Michael Schmitz
This patch series adds support for the Individual Computers X-Surf 100
network card for m68k Amiga, a network adapter based on the AX88796 chip set.

The driver was originally written for kernel version 3.19 by Michael Karcher
(see CC:), and adapted to 4.16 for submission to netdev by me. Questions 
regarding motivation for some of the changes are probably best directed at
Michael Karcher.

The driver has been tested by Adrian  who will
send his Tested-by tag separately.

A few changes to the ax88796 driver were required:
- to read the MAC address, some setup of the ax99796 chip must be done,
- attach to the MII bus only on device open to allow module unloading,
- allow to supersede ax_block_input/ax_block_output by card-specific
  optimized code,
- use an optional interrupt status callback to allow easier sharing of the
  card interrupt,
- set IRQF_SHARED if platform IRQ resource is marked shareable,

Some additional cleanup:
- do not attempt to free IRQ in ax_remove (complements 82533ad9a1c),
- clear platform drvdata on probe fail and module remove.

Changes since v1:

Raised in review by Andrew Lunn:
- move MII code around to avoid need for forward declaration
- combine patches 2 and 7 to add cleanup in error path

The patch series, in order:

1/8 net: ax88796: Fix MAC address reading
2/8 net: ax88796: Attach MII bus only when open
3/8 net: ax88796: Do not free IRQ in ax_remove() (already freed in ax_close()).
4/8 net: ax88796: Add block_input/output hooks to ax_plat_data
5/8 net: ax88796: add interrupt status callback to platform data
6/8 net: ax88796: set IRQF_SHARED flag when IRQ resource is marked as shareable
7/8 net: ax88796: release platform device drvdata on probe error and module 
remove
8/8 net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

 drivers/net/ethernet/8390/Kconfig|   14 +-
 drivers/net/ethernet/8390/Makefile   |1 +
 drivers/net/ethernet/8390/ax88796.c  |  228 +++
 drivers/net/ethernet/8390/xsurf100.c |  411 ++
 include/net/ax88796.h|   14 +-
 5 files changed, 573 insertions(+), 95 deletions(-)

Cheers,

  Michael


[PATCH v2 2/8] net: ax88796: Attach MII bus only when open

2018-04-16 Thread Michael Schmitz
From: Michael Karcher <deb...@mkarcher.dialup.fu-berlin.de>

Call ax_mii_init in ax_open(), and unregister/remove mdiobus resources
in ax_close().

This is needed to be able to unload the module, as the module is busy
while the MII bus is attached.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |  183 ++-
 1 files changed, 95 insertions(+), 88 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 2a256aa..83e59ae 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -389,6 +389,90 @@ static void ax_phy_switch(struct net_device *dev, int on)
ei_outb(reg_gpoc, ei_local->mem + EI_SHIFT(0x17));
 }
 
+static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+   if (level)
+   ax->reg_memr |= AX_MEMR_MDC;
+   else
+   ax->reg_memr &= ~AX_MEMR_MDC;
+
+   ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+   if (output)
+   ax->reg_memr &= ~AX_MEMR_MDIR;
+   else
+   ax->reg_memr |= AX_MEMR_MDIR;
+
+   ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static void ax_bb_set_data(struct mdiobb_ctrl *ctrl, int value)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+   if (value)
+   ax->reg_memr |= AX_MEMR_MDO;
+   else
+   ax->reg_memr &= ~AX_MEMR_MDO;
+
+   ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static int ax_bb_get_data(struct mdiobb_ctrl *ctrl)
+{
+   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+   int reg_memr = ei_inb(ax->addr_memr);
+
+   return reg_memr & AX_MEMR_MDI ? 1 : 0;
+}
+
+static const struct mdiobb_ops bb_ops = {
+   .owner = THIS_MODULE,
+   .set_mdc = ax_bb_mdc,
+   .set_mdio_dir = ax_bb_dir,
+   .set_mdio_data = ax_bb_set_data,
+   .get_mdio_data = ax_bb_get_data,
+};
+
+static int ax_mii_init(struct net_device *dev)
+{
+   struct platform_device *pdev = to_platform_device(dev->dev.parent);
+   struct ei_device *ei_local = netdev_priv(dev);
+   struct ax_device *ax = to_ax_dev(dev);
+   int err;
+
+   ax->bb_ctrl.ops = _ops;
+   ax->addr_memr = ei_local->mem + AX_MEMR;
+   ax->mii_bus = alloc_mdio_bitbang(>bb_ctrl);
+   if (!ax->mii_bus) {
+   err = -ENOMEM;
+   goto out;
+   }
+
+   ax->mii_bus->name = "ax88796_mii_bus";
+   ax->mii_bus->parent = dev->dev.parent;
+   snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+   pdev->name, pdev->id);
+
+   err = mdiobus_register(ax->mii_bus);
+   if (err)
+   goto out_free_mdio_bitbang;
+
+   return 0;
+
+ out_free_mdio_bitbang:
+   free_mdio_bitbang(ax->mii_bus);
+ out:
+   return err;
+}
+
 static int ax_open(struct net_device *dev)
 {
struct ax_device *ax = to_ax_dev(dev);
@@ -396,6 +480,10 @@ static int ax_open(struct net_device *dev)
 
netdev_dbg(dev, "open\n");
 
+   ret = ax_mii_init(dev);
+   if (ret)
+   goto failed_mii;
+
ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
  dev->name, dev);
if (ret)
@@ -423,6 +511,10 @@ static int ax_open(struct net_device *dev)
ax_phy_switch(dev, 0);
free_irq(dev->irq, dev);
  failed_request_irq:
+   /* unregister mdiobus */
+   mdiobus_unregister(ax->mii_bus);
+   free_mdio_bitbang(ax->mii_bus);
+ failed_mii:
return ret;
 }
 
@@ -442,6 +534,9 @@ static int ax_close(struct net_device *dev)
phy_disconnect(dev->phydev);
 
free_irq(dev->irq, dev);
+
+   mdiobus_unregister(ax->mii_bus);
+   free_mdio_bitbang(ax->mii_bus);
return 0;
 }
 
@@ -541,92 +636,8 @@ static void ax_eeprom_register_write(struct eeprom_93cx6 
*eeprom)
 #endif
 };
 
-static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level)
-{
-   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
-
-   if (level)
-   ax->reg_memr |= AX_MEMR_MDC;
-   else
-   ax->reg_memr &= ~AX_MEMR_MDC;
-
-   ei_outb(ax->reg_memr, ax->addr_memr);
-}
-
-static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output)
-{
-   struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
-
-   if (output)
-   ax->reg_memr &= ~AX_MEMR_MDIR;
-   else
- 

[PATCH v2 7/8] net: ax88796: release platform device drvdata on probe error and module remove

2018-04-16 Thread Michael Schmitz
The net device struct pointer is stored as platform device drvdata on
module probe - clear the drvdata entry on probe fail there, as well as
when unloading the module.

Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index a72dfbc..eb72282 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -829,6 +829,7 @@ static int ax_remove(struct platform_device *pdev)
release_mem_region(mem->start, resource_size(mem));
}
 
+   platform_set_drvdata(pdev, NULL);
free_netdev(dev);
 
return 0;
@@ -962,6 +963,7 @@ static int ax_probe(struct platform_device *pdev)
release_mem_region(mem->start, mem_size);
 
  exit_mem:
+   platform_set_drvdata(pdev, NULL);
free_netdev(dev);
 
return ret;
-- 
1.7.0.4



[PATCH v2 3/8] net: ax88796: Do not free IRQ in ax_remove() (already freed in ax_close()).

2018-04-16 Thread Michael Schmitz
From: John Paul Adrian Glaubitz 

This complements the fix in 82533ad9a1c that removed the free_irq
call in the error path of probe, to also not call free_irq when
remove is called to revert the effects of probe.

Signed-off-by: Michael Karcher 
---
 drivers/net/ethernet/8390/ax88796.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 83e59ae..ecf104c 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -793,7 +793,6 @@ static int ax_remove(struct platform_device *pdev)
struct resource *mem;
 
unregister_netdev(dev);
-   free_irq(dev->irq, dev);
 
iounmap(ei_local->mem);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
1.7.0.4



[PATCH v2 6/8] net: ax88796: set IRQF_SHARED flag when IRQ resource is marked as shareable

2018-04-16 Thread Michael Schmitz
From: John Paul Adrian Glaubitz <glaub...@physik.fu-berlin.de>

On the Amiga X-Surf100, the network card interrupt is shared with many
other interrupt sources, so requires the IRQF_SHARED flag to register.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index c799441..a72dfbc 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -875,6 +875,9 @@ static int ax_probe(struct platform_device *pdev)
dev->irq = irq->start;
ax->irqflags = irq->flags & IRQF_TRIGGER_MASK;
 
+   if (irq->flags &  IORESOURCE_IRQ_SHAREABLE)
+   ax->irqflags |= IRQF_SHARED;
+
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(>dev, "no MEM specified\n");
-- 
1.7.0.4



[PATCH v2 8/8] net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

2018-04-16 Thread Michael Schmitz
Add platform device driver to populate the ax88796 platform data from
information provided by the XSurf100 zorro device driver.
This driver will have to be loaded before loading the ax88796 module,
or compiled as built-in.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/Kconfig|   14 +-
 drivers/net/ethernet/8390/Makefile   |1 +
 drivers/net/ethernet/8390/xsurf100.c |  411 ++
 3 files changed, 425 insertions(+), 1 deletions(-)
 create mode 100644 drivers/net/ethernet/8390/xsurf100.c

diff --git a/drivers/net/ethernet/8390/Kconfig 
b/drivers/net/ethernet/8390/Kconfig
index fdc6734..0cadd45 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -30,7 +30,7 @@ config PCMCIA_AXNET
 
 config AX88796
tristate "ASIX AX88796 NE2000 clone support"
-   depends on (ARM || MIPS || SUPERH)
+   depends on (ARM || MIPS || SUPERH || AMIGA)
select CRC32
select PHYLIB
select MDIO_BITBANG
@@ -45,6 +45,18 @@ config AX88796_93CX6
---help---
  Select this if your platform comes with an external 93CX6 eeprom.
 
+config XSURF100
+   tristate "Amiga XSurf 100 AX88796/NE2000 clone support"
+   depends on ZORRO
+   depends on AX88796
+   ---help---
+ This driver is for the Individual Computers X-Surf 100 Ethernet
+ card (based on the Asix AX88796 chip). If you have such a card,
+ say Y. Otherwise, say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called xsurf100.
+
 config HYDRA
tristate "Hydra support"
depends on ZORRO
diff --git a/drivers/net/ethernet/8390/Makefile 
b/drivers/net/ethernet/8390/Makefile
index f975c2f..3715f8d 100644
--- a/drivers/net/ethernet/8390/Makefile
+++ b/drivers/net/ethernet/8390/Makefile
@@ -16,4 +16,5 @@ obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o
 obj-$(CONFIG_STNIC) += stnic.o 8390.o
 obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
 obj-$(CONFIG_WD80x3) += wd.o 8390.o
+obj-$(CONFIG_XSURF100) += xsurf100.o
 obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o
diff --git a/drivers/net/ethernet/8390/xsurf100.c 
b/drivers/net/ethernet/8390/xsurf100.c
new file mode 100644
index 000..3caece0
--- /dev/null
+++ b/drivers/net/ethernet/8390/xsurf100.c
@@ -0,0 +1,411 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \
+   ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0)
+
+#define XS100_IRQSTATUS_BASE 0x40
+#define XS100_8390_BASE 0x800
+
+/* Longword-access area. Translated to 2 16-bit access cycles by the
+ * X-Surf 100 FPGA
+ */
+#define XS100_8390_DATA32_BASE 0x8000
+#define XS100_8390_DATA32_SIZE 0x2000
+/* Sub-Areas for fast data register access; addresses relative to area begin */
+#define XS100_8390_DATA_READ32_BASE 0x0880
+#define XS100_8390_DATA_WRITE32_BASE 0x0C80
+#define XS100_8390_DATA_AREA_SIZE 0x80
+
+#define __NS8390_init ax_NS8390_init
+
+/* force unsigned long back to 'void __iomem *' */
+#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
+
+#define ei_inb(_a) z_readb(ax_convert_addr(_a))
+#define ei_outb(_v, _a) z_writeb(_v, ax_convert_addr(_a))
+
+#define ei_inw(_a) z_readw(ax_convert_addr(_a))
+#define ei_outw(_v, _a) z_writew(_v, ax_convert_addr(_a))
+
+#define ei_inb_p(_a) ei_inb(_a)
+#define ei_outb_p(_v, _a) ei_outb(_v, _a)
+
+/* define EI_SHIFT() to take into account our register offsets */
+#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
+
+/* Ensure we have our RCR base value */
+#define AX88796_PLATFORM
+
+static unsigned char version[] =
+   "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
+
+#include "lib8390.c"
+
+/* from ne.c */
+#define NE_CMD EI_SHIFT(0x00)
+#define NE_RESET   EI_SHIFT(0x1f)
+#define NE_DATAPORTEI_SHIFT(0x10)
+
+/* Hard reset the card. This used to pause for the same period that a
+ * 8390 reset command required, but that shouldn't be necessary.
+ */
+static void ax_reset_8390(struct net_device *dev)
+{
+   struct ei_device *ei_local = netdev_priv(dev);
+   unsigned long reset_start_time = jiffies;
+   void __iomem *addr = (void __iomem *)dev->base_addr;
+
+   netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
+
+   ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
+
+   ei_local->txing = 0;
+   ei_local->dmaing = 0;
+
+   /* This check _should_not_ be necessary, omit eventually. */
+   while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
+   if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
+   netdev_warn(dev, "%s: did not complete.\n", __func__);
+   break;
+   }
+   }
+

[PATCH v2 5/8] net: ax88796: add interrupt status callback to platform data

2018-04-16 Thread Michael Schmitz
To be able to tell the ax88796 driver whether it is sensible to enter
the 8390 interrupt handler, an "is this interrupt caused by the 88796"
callback has been added to the ax_plat_data structure (with NULL being
compatible to the previous behaviour).

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |   23 +--
 include/net/ax88796.h   |5 +
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 29cde38..c799441 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -165,6 +165,21 @@ static void ax_reset_8390(struct net_device *dev)
ei_outb(ENISR_RESET, addr + EN0_ISR);   /* Ack intr. */
 }
 
+/* Wrapper for __ei_interrupt for platforms that have a platform-specific
+ * way to find out whether the interrupt request might be caused by
+ * the ax88796 chip.
+ */
+static irqreturn_t ax_ei_interrupt_filtered(int irq, void *dev_id)
+{
+   struct net_device *dev = dev_id;
+   struct ax_device *ax = to_ax_dev(dev);
+   struct platform_device *pdev = to_platform_device(dev->dev.parent);
+
+   if (!ax->plat->check_irq(pdev))
+   return IRQ_NONE;
+
+   return ax_ei_interrupt(irq, dev_id);
+}
 
 static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page)
@@ -484,8 +499,12 @@ static int ax_open(struct net_device *dev)
if (ret)
goto failed_mii;
 
-   ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
- dev->name, dev);
+   if (ax->plat->check_irq)
+   ret = request_irq(dev->irq, ax_ei_interrupt_filtered,
+ ax->irqflags, dev->name, dev);
+   else
+   ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
+ dev->name, dev);
if (ret)
goto failed_request_irq;
 
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
index 26cc459..26412cd 100644
--- a/include/net/ax88796.h
+++ b/include/net/ax88796.h
@@ -12,6 +12,7 @@
 #define __NET_AX88796_PLAT_H
 
 struct net_device;
+struct platform_device;
 
 #define AXFLG_HAS_EEPROM   (1<<0)
 #define AXFLG_MAC_FROMDEV  (1<<1)  /* device already has MAC */
@@ -33,6 +34,10 @@ struct ax_plat_data {
const unsigned char *buf, int star_page);
void (*block_input)(struct net_device *dev, int count,
struct sk_buff *skb, int ring_offset);
+   /* returns nonzero if a pending interrupt request might by caused by
+* the ax88786. Handles all interrupts if set to NULL
+*/
+   int (*check_irq)(struct platform_device *pdev);
 };
 
 #endif /* __NET_AX88796_PLAT_H */
-- 
1.7.0.4



[PATCH v2 1/8] net: ax88796: Fix MAC address reading

2018-04-16 Thread Michael Schmitz
From: Michael Karcher <deb...@mkarcher.dialup.fu-berlin.de>

To read the MAC address from the (virtual) SAprom, the remote DMA
unit needs to be set up like for every other process access to card-local
memory.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 2455547..2a256aa 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -671,10 +671,16 @@ static int ax_init_dev(struct net_device *dev)
if (ax->plat->flags & AXFLG_HAS_EEPROM) {
unsigned char SA_prom[32];
 
+   ei_outb(6, ioaddr + EN0_RCNTLO);
+   ei_outb(0, ioaddr + EN0_RCNTHI);
+   ei_outb(0, ioaddr + EN0_RSARLO);
+   ei_outb(0, ioaddr + EN0_RSARHI);
+   ei_outb(E8390_RREAD + E8390_START, ioaddr + NE_CMD);
for (i = 0; i < sizeof(SA_prom); i += 2) {
SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
SA_prom[i + 1] = ei_inb(ioaddr + NE_DATAPORT);
}
+   ei_outb(ENISR_RDC, ioaddr + EN0_ISR);   /* Ack intr. */
 
if (ax->plat->wordlength == 2)
for (i = 0; i < 16; i++)
-- 
1.7.0.4



Re: [PATCH 08/10] net: ax88796: Make reset more robust on AX88796B

2018-04-16 Thread Michael Schmitz
Hi Andrew,

On Tue, Apr 17, 2018 at 11:12 AM, Andrew Lunn <and...@lunn.ch> wrote:
> On Tue, Apr 17, 2018 at 10:04:43AM +1200, Michael Schmitz wrote:
>> From: John Paul Adrian Glaubitz <glaub...@physik.fu-berlin.de>
>>
>> The AX88796B as installed on the X-Surf-100 does not recognize a MII reset
>> request if the previous write to the MII control register also was a reset
>> request. So a dummy write to the control register makes the soft reset in
>> the PHY initialization code work.
>>
>> Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
>> ---
>>  drivers/net/ethernet/8390/ax88796.c |4 
>>  1 files changed, 4 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/8390/ax88796.c 
>> b/drivers/net/ethernet/8390/ax88796.c
>> index 6af9aca..a2f9a09 100644
>> --- a/drivers/net/ethernet/8390/ax88796.c
>> +++ b/drivers/net/ethernet/8390/ax88796.c
>> @@ -374,6 +374,10 @@ static int ax_mii_probe(struct net_device *dev)
>>   return -ENODEV;
>>   }
>>
>> + /* write a non-reset pattern to the control register to
>> +  * re-arm the reset request detection logic (needed on AX88796B)
>> +  */
>> + phy_write(phy_dev, MII_BMCR, 0);
>
> This should really be fixed in the PHY driver, not the MAC.

OK - do you want this separate, or as part of this series? Might have
a few side effects on more commonly used hardware, perhaps?

Cheers,

  Michael

>
>  Andrew


Re: [PATCH 02/10] net: ax88796: Attach MII bus only when open

2018-04-16 Thread Michael Schmitz
Hi Andrew,

thank you for reviewing this series!

On Tue, Apr 17, 2018 at 10:59 AM, Andrew Lunn <and...@lunn.ch> wrote:
> On Tue, Apr 17, 2018 at 10:04:37AM +1200, Michael Schmitz wrote:
>> From: Michael Karcher <deb...@mkarcher.dialup.fu-berlin.de>
>>
>> Call ax_mii_init in ax_open(), and unregister/remove mdiobus resources
>> in ax_close().
>>
>> This is needed to be able to unload the module, as the module is busy
>> while the MII bus is attached.
>>
>> Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
>> Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
>> ---
>>  drivers/net/ethernet/8390/ax88796.c |   13 +
>>  1 files changed, 9 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/8390/ax88796.c 
>> b/drivers/net/ethernet/8390/ax88796.c
>> index 2a256aa..f7b8911 100644
>> --- a/drivers/net/ethernet/8390/ax88796.c
>> +++ b/drivers/net/ethernet/8390/ax88796.c
>> @@ -79,6 +79,8 @@
>>
>>  static u32 ax_msg_enable;
>>
>> +static int ax_mii_init(struct net_device *dev);
>
> Hi Michael
>
> We try to avoid forward declarations. Please can you move
> ax_mii_init() so this is not needed.

Done that - had to move the entire bitbang stuff along with
ax_mii_init() though.

>> +
>>  /* device private data */
>>
>>  struct ax_device {
>> @@ -396,6 +398,10 @@ static int ax_open(struct net_device *dev)
>>
>>   netdev_dbg(dev, "open\n");
>>
>> + ret = ax_mii_init(dev);
>> + if (ret)
>> + goto failed_request_irq;
>> +
>>   ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
>> dev->name, dev);
>>   if (ret)
>
> You are missing some cleanup on error at the end of ax_open().
> It was also missing before.

Yep, that's addressed in patch 7 of this series. I'll fold that into
this one for clarity.

Cheers,

  Michael


>
>Andrew


[PATCH 07/10] net: ax88796: unregister mdiobus on ax_mii_init() fail

2018-04-16 Thread Michael Schmitz
From: Michael Schmitz <schm...@debian.org>

Unregister and free up mdiobus resources if ax_mii_init() failed.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index b09cdc6..6af9aca 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -415,7 +415,7 @@ static int ax_open(struct net_device *dev)
 
ret = ax_mii_init(dev);
if (ret)
-   goto failed_request_irq;
+   goto failed_mii;
 
if (ax->plat->check_irq)
ret = request_irq(dev->irq, ax_ei_interrupt_filtered,
@@ -448,6 +448,10 @@ static int ax_open(struct net_device *dev)
ax_phy_switch(dev, 0);
free_irq(dev->irq, dev);
  failed_request_irq:
+   /* unregister mdiobus */
+   mdiobus_unregister(ax->mii_bus);
+   free_mdio_bitbang(ax->mii_bus);
+ failed_mii:
return ret;
 }
 
-- 
1.7.0.4



[PATCH 04/10] net: ax88796: Add block_input/output hooks to ax_plat_data

2018-04-16 Thread Michael Schmitz
Add platform specific hooks for block transfer reads/writes of packet
buffer data, superseding the default provided ax_block_input/output.
Currently used for m68k Amiga XSurf100.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |   10 --
 include/net/ax88796.h   |9 -
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index a4f23ba..9159235 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -758,8 +758,14 @@ static int ax_init_dev(struct net_device *dev)
 #endif
 
ei_local->reset_8390 = _reset_8390;
-   ei_local->block_input = _block_input;
-   ei_local->block_output = _block_output;
+   if (ax->plat->block_input)
+   ei_local->block_input = ax->plat->block_input;
+   else
+   ei_local->block_input = _block_input;
+   if (ax->plat->block_output)
+   ei_local->block_output = ax->plat->block_output;
+   else
+   ei_local->block_output = _block_output;
ei_local->get_8390_hdr = _get_8390_hdr;
ei_local->priv = 0;
ei_local->msg_enable = ax_msg_enable;
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
index b9a3bec..26cc459 100644
--- a/include/net/ax88796.h
+++ b/include/net/ax88796.h
@@ -8,10 +8,11 @@
  * published by the Free Software Foundation.
  *
 */
-
 #ifndef __NET_AX88796_PLAT_H
 #define __NET_AX88796_PLAT_H
 
+struct net_device;
+
 #define AXFLG_HAS_EEPROM   (1<<0)
 #define AXFLG_MAC_FROMDEV  (1<<1)  /* device already has MAC */
 #define AXFLG_HAS_93CX6(1<<2)  /* use eeprom_93cx6 
driver */
@@ -26,6 +27,12 @@ struct ax_plat_data {
u32 *reg_offsets;   /* register offsets */
u8  *mac_addr;  /* MAC addr (only used when
   AXFLG_MAC_FROMPLATFORM is used */
+
+   /* uses default ax88796 buffer if set to NULL */
+   void (*block_output)(struct net_device *dev, int count,
+   const unsigned char *buf, int star_page);
+   void (*block_input)(struct net_device *dev, int count,
+   struct sk_buff *skb, int ring_offset);
 };
 
 #endif /* __NET_AX88796_PLAT_H */
-- 
1.7.0.4



[PATCH 05/10] net: ax88796: add interrupt status callback to platform data

2018-04-16 Thread Michael Schmitz
To be able to tell the ax88796 driver whether it is sensible to enter
the 8390 interrupt handler, an "is this interrupt caused by the 88796"
callback has been added to the ax_plat_data structure (with NULL being
compatible to the previous behaviour).

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |   23 +--
 include/net/ax88796.h   |5 +
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 9159235..b6d5bec 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -167,6 +167,21 @@ static void ax_reset_8390(struct net_device *dev)
ei_outb(ENISR_RESET, addr + EN0_ISR);   /* Ack intr. */
 }
 
+/* Wrapper for __ei_interrupt for platforms that have a platform-specific
+ * way to find out whether the interrupt request might be caused by
+ * the ax88796 chip.
+ */
+static irqreturn_t ax_ei_interrupt_filtered(int irq, void *dev_id)
+{
+   struct net_device *dev = dev_id;
+   struct ax_device *ax = to_ax_dev(dev);
+   struct platform_device *pdev = to_platform_device(dev->dev.parent);
+
+   if (!ax->plat->check_irq(pdev))
+   return IRQ_NONE;
+
+   return ax_ei_interrupt(irq, dev_id);
+}
 
 static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page)
@@ -402,8 +417,12 @@ static int ax_open(struct net_device *dev)
if (ret)
goto failed_request_irq;
 
-   ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
- dev->name, dev);
+   if (ax->plat->check_irq)
+   ret = request_irq(dev->irq, ax_ei_interrupt_filtered,
+ ax->irqflags, dev->name, dev);
+   else
+   ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
+ dev->name, dev);
if (ret)
goto failed_request_irq;
 
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
index 26cc459..26412cd 100644
--- a/include/net/ax88796.h
+++ b/include/net/ax88796.h
@@ -12,6 +12,7 @@
 #define __NET_AX88796_PLAT_H
 
 struct net_device;
+struct platform_device;
 
 #define AXFLG_HAS_EEPROM   (1<<0)
 #define AXFLG_MAC_FROMDEV  (1<<1)  /* device already has MAC */
@@ -33,6 +34,10 @@ struct ax_plat_data {
const unsigned char *buf, int star_page);
void (*block_input)(struct net_device *dev, int count,
struct sk_buff *skb, int ring_offset);
+   /* returns nonzero if a pending interrupt request might by caused by
+* the ax88786. Handles all interrupts if set to NULL
+*/
+   int (*check_irq)(struct platform_device *pdev);
 };
 
 #endif /* __NET_AX88796_PLAT_H */
-- 
1.7.0.4



[PATCH 02/10] net: ax88796: Attach MII bus only when open

2018-04-16 Thread Michael Schmitz
From: Michael Karcher <deb...@mkarcher.dialup.fu-berlin.de>

Call ax_mii_init in ax_open(), and unregister/remove mdiobus resources
in ax_close().

This is needed to be able to unload the module, as the module is busy
while the MII bus is attached.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |   13 +
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 2a256aa..f7b8911 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -79,6 +79,8 @@
 
 static u32 ax_msg_enable;
 
+static int ax_mii_init(struct net_device *dev);
+
 /* device private data */
 
 struct ax_device {
@@ -396,6 +398,10 @@ static int ax_open(struct net_device *dev)
 
netdev_dbg(dev, "open\n");
 
+   ret = ax_mii_init(dev);
+   if (ret)
+   goto failed_request_irq;
+
ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
  dev->name, dev);
if (ret)
@@ -442,6 +448,9 @@ static int ax_close(struct net_device *dev)
phy_disconnect(dev->phydev);
 
free_irq(dev->irq, dev);
+
+   mdiobus_unregister(ax->mii_bus);
+   free_mdio_bitbang(ax->mii_bus);
return 0;
 }
 
@@ -758,10 +767,6 @@ static int ax_init_dev(struct net_device *dev)
dev->netdev_ops = _netdev_ops;
dev->ethtool_ops = _ethtool_ops;
 
-   ret = ax_mii_init(dev);
-   if (ret)
-   goto err_out;
-
ax_NS8390_init(dev, 0);
 
ret = register_netdev(dev);
-- 
1.7.0.4



[PATCH 08/10] net: ax88796: Make reset more robust on AX88796B

2018-04-16 Thread Michael Schmitz
From: John Paul Adrian Glaubitz 

The AX88796B as installed on the X-Surf-100 does not recognize a MII reset
request if the previous write to the MII control register also was a reset
request. So a dummy write to the control register makes the soft reset in
the PHY initialization code work.

Signed-off-by: Michael Karcher 
---
 drivers/net/ethernet/8390/ax88796.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 6af9aca..a2f9a09 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -374,6 +374,10 @@ static int ax_mii_probe(struct net_device *dev)
return -ENODEV;
}
 
+   /* write a non-reset pattern to the control register to
+* re-arm the reset request detection logic (needed on AX88796B)
+*/
+   phy_write(phy_dev, MII_BMCR, 0);
ret = phy_connect_direct(dev, phy_dev, ax_handle_link_change,
 PHY_INTERFACE_MODE_MII);
if (ret) {
-- 
1.7.0.4



[PATCH 06/10] net: ax88796: set IRQF_SHARED flag when IRQ resource is marked as shareable

2018-04-16 Thread Michael Schmitz
From: John Paul Adrian Glaubitz <glaub...@physik.fu-berlin.de>

On the Amiga X-Surf100, the network card interrupt is shared with many
other interrupt sources, so requires the IRQF_SHARED flag to register.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index b6d5bec..b09cdc6 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -873,6 +873,9 @@ static int ax_probe(struct platform_device *pdev)
dev->irq = irq->start;
ax->irqflags = irq->flags & IRQF_TRIGGER_MASK;
 
+   if (irq->flags &  IORESOURCE_IRQ_SHAREABLE)
+   ax->irqflags |= IRQF_SHARED;
+
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(>dev, "no MEM specified\n");
-- 
1.7.0.4



[PATCH 09/10] net: ax88796: release platform device drvdata on probe error and module remove

2018-04-16 Thread Michael Schmitz
The net device struct pointer is stored as platform device drvdata on
module probe - clear the drvdata entry on probe fail there, as well as
when unloading the module.

Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index a2f9a09..8db6592 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -835,6 +835,7 @@ static int ax_remove(struct platform_device *pdev)
release_mem_region(mem->start, resource_size(mem));
}
 
+   platform_set_drvdata(pdev, NULL);
free_netdev(dev);
 
return 0;
@@ -968,6 +969,7 @@ static int ax_probe(struct platform_device *pdev)
release_mem_region(mem->start, mem_size);
 
  exit_mem:
+   platform_set_drvdata(pdev, NULL);
free_netdev(dev);
 
return ret;
-- 
1.7.0.4



[PATCH 01/10] net: ax88796: Fix MAC address reading

2018-04-16 Thread Michael Schmitz
From: Michael Karcher <deb...@mkarcher.dialup.fu-berlin.de>

To read the MAC address from the (virtual) SAprom, the remote DMA
unit needs to be set up like for every other process access to card-local
memory.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/ax88796.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index 2455547..2a256aa 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -671,10 +671,16 @@ static int ax_init_dev(struct net_device *dev)
if (ax->plat->flags & AXFLG_HAS_EEPROM) {
unsigned char SA_prom[32];
 
+   ei_outb(6, ioaddr + EN0_RCNTLO);
+   ei_outb(0, ioaddr + EN0_RCNTHI);
+   ei_outb(0, ioaddr + EN0_RSARLO);
+   ei_outb(0, ioaddr + EN0_RSARHI);
+   ei_outb(E8390_RREAD + E8390_START, ioaddr + NE_CMD);
for (i = 0; i < sizeof(SA_prom); i += 2) {
SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
SA_prom[i + 1] = ei_inb(ioaddr + NE_DATAPORT);
}
+   ei_outb(ENISR_RDC, ioaddr + EN0_ISR);   /* Ack intr. */
 
if (ax->plat->wordlength == 2)
for (i = 0; i < 16; i++)
-- 
1.7.0.4



[PATCH 00/10] New network driver for Amiga X-Surf 100 (m68k)

2018-04-16 Thread Michael Schmitz
This patch series adds support for the Individual Computers X-Surf 100
network card for m68k Amiga, a network adapter based on the AX88796 chip set.

The driver was originally written for kernel version 3.19 by Michael Karcher
(see CC:), and adapted to 4.16 for submission to netdev by me. Questions  
regarding motivation for some of the changes are probably best directed at
Michael Karcher.

The driver has been tested by Adrian <glaub...@physik.fu-berlin.de> who will
send his Tested-by tag separately.

A few changes to the ax88796 driver were required:
- to read the MAC address, some setup of the ax99796 chip must be done,
- attach to the MII bus only on device open to allow module unloading,
- allow to supersede ax_block_input/ax_block_output by card-specific
  optimized code,
- use an optional interrupt status callback to allow easier sharing of the
  card interrupt,
- set IRQF_SHARED if platform IRQ resource is marked shareable,
- add a dummy control register write to MII reset code so back-to-back
  reset requests work.

Some additional cleanup:
- do not attempt to free IRQ in ax_remove (complements 82533ad9a1c),
- unregister and free mdiobus resources in ax_mii_init error path,
- clear platform drvdata on probe fail and module remove.

The patch series, in order:

01/10 net: ax88796: Fix MAC address reading
02/10 net: ax88796: Attach MII bus only when open
03/10 net: ax88796: Do not free IRQ in ax_remove() (already freed in 
ax_close()).
04/10 net: ax88796: Add block_input/output hooks to ax_plat_data
05/10 net: ax88796: add interrupt status callback to platform data
06/10 net: ax88796: set IRQF_SHARED flag when IRQ resource is marked as 
shareable
07/10 net: ax88796: unregister mdiobus on ax_mii_init() fail
08/10 net: ax88796: Make reset more robust on AX88796B
09/10 net: ax88796: release platform device drvdata on probe error and module 
remove
10/10 net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

 drivers/net/ethernet/8390/Kconfig|   14 +-
 drivers/net/ethernet/8390/Makefile   |1 +
 drivers/net/ethernet/8390/ax88796.c  |   66 +-
 drivers/net/ethernet/8390/xsurf100.c |  411 ++
 include/net/ax88796.h|   14 +-
 5 files changed, 495 insertions(+), 11 deletions(-)

Cheers,

    Michael Schmitz


[PATCH 03/10] net: ax88796: Do not free IRQ in ax_remove() (already freed in ax_close()).

2018-04-16 Thread Michael Schmitz
From: John Paul Adrian Glaubitz 

This complements the fix in 82533ad9a1c that removed the free_irq
call in the error path of probe, to also not call free_irq when
remove is called to revert the effects of probe.

Signed-off-by: Michael Karcher 
---
 drivers/net/ethernet/8390/ax88796.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/8390/ax88796.c 
b/drivers/net/ethernet/8390/ax88796.c
index f7b8911..a4f23ba 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -791,7 +791,6 @@ static int ax_remove(struct platform_device *pdev)
struct resource *mem;
 
unregister_netdev(dev);
-   free_irq(dev->irq, dev);
 
iounmap(ei_local->mem);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
1.7.0.4



[PATCH 10/10] net: New ax88796 platform driver for Amiga X-Surf 100 Zorro board (m68k)

2018-04-16 Thread Michael Schmitz
Add platform device driver to populate the ax88796 platform data from
information provided by the XSurf100 zorro device driver.
This driver will have to be loaded before loading the ax88796 module,
or compiled as built-in.

Signed-off-by: Michael Karcher <ker...@mkarcher.dialup.fu-berlin.de>
Signed-off-by: Michael Schmitz <schmitz...@gmail.com>
---
 drivers/net/ethernet/8390/Kconfig|   14 +-
 drivers/net/ethernet/8390/Makefile   |1 +
 drivers/net/ethernet/8390/xsurf100.c |  411 ++
 3 files changed, 425 insertions(+), 1 deletions(-)
 create mode 100644 drivers/net/ethernet/8390/xsurf100.c

diff --git a/drivers/net/ethernet/8390/Kconfig 
b/drivers/net/ethernet/8390/Kconfig
index fdc6734..0cadd45 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -30,7 +30,7 @@ config PCMCIA_AXNET
 
 config AX88796
tristate "ASIX AX88796 NE2000 clone support"
-   depends on (ARM || MIPS || SUPERH)
+   depends on (ARM || MIPS || SUPERH || AMIGA)
select CRC32
select PHYLIB
select MDIO_BITBANG
@@ -45,6 +45,18 @@ config AX88796_93CX6
---help---
  Select this if your platform comes with an external 93CX6 eeprom.
 
+config XSURF100
+   tristate "Amiga XSurf 100 AX88796/NE2000 clone support"
+   depends on ZORRO
+   depends on AX88796
+   ---help---
+ This driver is for the Individual Computers X-Surf 100 Ethernet
+ card (based on the Asix AX88796 chip). If you have such a card,
+ say Y. Otherwise, say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called xsurf100.
+
 config HYDRA
tristate "Hydra support"
depends on ZORRO
diff --git a/drivers/net/ethernet/8390/Makefile 
b/drivers/net/ethernet/8390/Makefile
index f975c2f..3715f8d 100644
--- a/drivers/net/ethernet/8390/Makefile
+++ b/drivers/net/ethernet/8390/Makefile
@@ -16,4 +16,5 @@ obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o
 obj-$(CONFIG_STNIC) += stnic.o 8390.o
 obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
 obj-$(CONFIG_WD80x3) += wd.o 8390.o
+obj-$(CONFIG_XSURF100) += xsurf100.o
 obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o
diff --git a/drivers/net/ethernet/8390/xsurf100.c 
b/drivers/net/ethernet/8390/xsurf100.c
new file mode 100644
index 000..3caece0
--- /dev/null
+++ b/drivers/net/ethernet/8390/xsurf100.c
@@ -0,0 +1,411 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \
+   ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0)
+
+#define XS100_IRQSTATUS_BASE 0x40
+#define XS100_8390_BASE 0x800
+
+/* Longword-access area. Translated to 2 16-bit access cycles by the
+ * X-Surf 100 FPGA
+ */
+#define XS100_8390_DATA32_BASE 0x8000
+#define XS100_8390_DATA32_SIZE 0x2000
+/* Sub-Areas for fast data register access; addresses relative to area begin */
+#define XS100_8390_DATA_READ32_BASE 0x0880
+#define XS100_8390_DATA_WRITE32_BASE 0x0C80
+#define XS100_8390_DATA_AREA_SIZE 0x80
+
+#define __NS8390_init ax_NS8390_init
+
+/* force unsigned long back to 'void __iomem *' */
+#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
+
+#define ei_inb(_a) z_readb(ax_convert_addr(_a))
+#define ei_outb(_v, _a) z_writeb(_v, ax_convert_addr(_a))
+
+#define ei_inw(_a) z_readw(ax_convert_addr(_a))
+#define ei_outw(_v, _a) z_writew(_v, ax_convert_addr(_a))
+
+#define ei_inb_p(_a) ei_inb(_a)
+#define ei_outb_p(_v, _a) ei_outb(_v, _a)
+
+/* define EI_SHIFT() to take into account our register offsets */
+#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
+
+/* Ensure we have our RCR base value */
+#define AX88796_PLATFORM
+
+static unsigned char version[] =
+   "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
+
+#include "lib8390.c"
+
+/* from ne.c */
+#define NE_CMD EI_SHIFT(0x00)
+#define NE_RESET   EI_SHIFT(0x1f)
+#define NE_DATAPORTEI_SHIFT(0x10)
+
+/* Hard reset the card. This used to pause for the same period that a
+ * 8390 reset command required, but that shouldn't be necessary.
+ */
+static void ax_reset_8390(struct net_device *dev)
+{
+   struct ei_device *ei_local = netdev_priv(dev);
+   unsigned long reset_start_time = jiffies;
+   void __iomem *addr = (void __iomem *)dev->base_addr;
+
+   netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
+
+   ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
+
+   ei_local->txing = 0;
+   ei_local->dmaing = 0;
+
+   /* This check _should_not_ be necessary, omit eventually. */
+   while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
+   if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
+   netdev_warn(dev, "%s: did not complete.\n", __func__);
+   break;
+   }
+   }
+