Re: [PATCH] macb: Fix speed setting
On Thu, 21 Feb 2008 22:50:54 +0900 (JST) Atsushi Nemoto [EMAIL PROTECTED] wrote: Fix NCFGR.SPD setting on 10Mbps. This bug was introduced by conversion to generic PHY layer in kernel 2.6.23. Signed-off-by: Atsushi Nemoto [EMAIL PROTECTED] --- diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 81bf005..1d210ed 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -148,7 +148,7 @@ static void macb_handle_link_change(struct net_device *dev) if (phydev-duplex) reg |= MACB_BIT(FD); - if (phydev-speed) + if (phydev-speed == SPEED_100) I have to admit that even after looking through include/linux/phy.h and include/linux/mii.h, I don't have the faintest idea what values we can expect to find in the speed field of phydev. The comment above struct phy_device says that it is used like in mii_if_info, but struct mii_if_info doesn't have a speed field... I'm willing to take your word for it, but some documentation would be really nice... Haavard -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] macb: Fix speed setting
On Fri, 22 Feb 2008 00:07:31 +0900 (JST) Atsushi Nemoto [EMAIL PROTECTED] wrote: I'm willing to take your word for it, but some documentation would be really nice... Well, simple grepping drivers/net/phy enlighten us ;) Yeah, the patch certainly looks correct as far as I can tell. Anyway, this patch fixes problem with 10Mbps on AT91SAM9260 board. Thanks. I'll pass it on. Haavard -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: BUG: 2.6.25-rc1: iptables postrouting setup causes oops
On Wed, 13 Feb 2008 00:48:29 -0800 Andrew Morton [EMAIL PROTECTED] wrote: On Tue, 12 Feb 2008 22:46:01 +1100 Ben Nizette [EMAIL PROTECTED] wrote: On an AVR32, root over NFS, config attached, running (from a startup script): iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE Results in (dmesg extract including a bit of context for good measure): -8 VFS: Mounted root (nfs filesystem). Freeing init memory: 72K (9000 - 90012000) eth0: no IPv6 routers present warning: `dnsmasq' uses 32-bit capabilities (legacy support in use) Hmm. What does that mean? What size do capabilities normally have? ip_tables: (C) 2000-2006 Netfilter Core Team nf_conntrack version 0.5.0 (1024 buckets, 4096 max) Unable to handle kernel paging request at virtual address d76a7138 ptbr = 91d3b000 pgd = e5f3 pte = 00014370 Hmm. It actually found something in the pte? Looks like a swap entry...but that doesn't make sense at that virtual address. Userspace is below 0x8000. Oops: Kernel access of bad area, sig: 11 [#1] FRAME_POINTER chip: 0x01f:0x1e82 rev 2 Modules linked in: nf_conntrack_ipv4(+) nf_conntrack ip_tables PC is at kmem_cache_alloc+0x2c/0x54 LR is at nf_conntrack_l4proto_register+0x34/0x9c [nf_conntrack] I take it that the above means that the crash is in kmem_cache_alloc()? That's correct. If so, the bug could be almost anywhere - in slab, or in some random piece of code which scribbles on slab's data structures. Yes, it looks like memory corruption, especially since the page table appears to be corrupted as well. But I'll have a look and see if the code that dumps the pte is doing something bogus... Perfectly repeatable. If my theory is correct, changing pretty much anything in the kernel config might just make it go away. But still, it would be most valuable if you could try running a bisection search, as described in http://www.kernel.org/doc/local/git-quick.html, thanks. Yes, that would be very valuable. Haavard -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: BUG: 2.6.25-rc1: iptables postrouting setup causes oops
On Wed, 13 Feb 2008 10:10:24 +0100 Haavard Skinnemoen [EMAIL PROTECTED] wrote: ip_tables: (C) 2000-2006 Netfilter Core Team nf_conntrack version 0.5.0 (1024 buckets, 4096 max) Unable to handle kernel paging request at virtual address d76a7138 ptbr = 91d3b000 pgd = e5f3 pte = 00014370 Hmm. It actually found something in the pte? Looks like a swap entry...but that doesn't make sense at that virtual address. Userspace is below 0x8000. (...) If so, the bug could be almost anywhere - in slab, or in some random piece of code which scribbles on slab's data structures. Yes, it looks like memory corruption, especially since the page table appears to be corrupted as well. But I'll have a look and see if the code that dumps the pte is doing something bogus... Yes, that code is indeed buggy. The below patch should fix it, although the page tables probably won't contain anything interesting, and it could still be a memory corruption issue. And it definitely won't fix the real issue. I have a couple of patches that will eliminate the need for this fixup (and probably improve performance as well), but they are probably 2.6.26 material. Haavard diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index 6560cb1..ce4e429 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -189,6 +189,8 @@ no_context: page = sysreg_read(PTBR); printk(KERN_ALERT ptbr = %08lx, page); + if (address = TASK_SIZE) + page = (unsigned long)swapper_pg_dir; if (page) { page = ((unsigned long *)page)[address 22]; printk( pgd = %08lx, page); -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: BUG: 2.6.25-rc1: iptables postrouting setup causes oops
On Wed, 13 Feb 2008 08:42:15 -0800 Andrew G. Morgan [EMAIL PROTECTED] wrote: However, it is a warning and, for any existing app that doesn't care about newly added capabilities, the warning is benign. Ok, I see. Thanks for explaining. Haavard -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] macb: Fix section mismatch and shrink runtime footprint
macb devices are only found integrated on SoCs, so they can't be hotplugged. Thus, the probe() and exit() functions can be __init and __exit, respectively. By using platform_driver_probe() instead of platform_driver_register(), there won't be any references to the discarded probe() function after the driver has loaded. This also fixes a section mismatch due to macb_probe(), defined as __devinit, calling macb_get_hwaddr, defined as __init. Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- drivers/net/macb.c |9 - 1 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index e10528e..81bf005 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -1084,7 +1084,7 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return phy_mii_ioctl(phydev, if_mii(rq), cmd); } -static int __devinit macb_probe(struct platform_device *pdev) +static int __init macb_probe(struct platform_device *pdev) { struct eth_platform_data *pdata; struct resource *regs; @@ -1248,7 +1248,7 @@ err_out: return err; } -static int __devexit macb_remove(struct platform_device *pdev) +static int __exit macb_remove(struct platform_device *pdev) { struct net_device *dev; struct macb *bp; @@ -1276,8 +1276,7 @@ static int __devexit macb_remove(struct platform_device *pdev) } static struct platform_driver macb_driver = { - .probe = macb_probe, - .remove = __devexit_p(macb_remove), + .remove = __exit_p(macb_remove), .driver = { .name = macb, }, @@ -1285,7 +1284,7 @@ static struct platform_driver macb_driver = { static int __init macb_init(void) { - return platform_driver_register(macb_driver); + return platform_driver_probe(macb_driver, macb_probe); } static void __exit macb_exit(void) -- 1.5.3.8 -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] PHYLIB: Locking fixes for PHY I/O potentially sleeping
On Tue, 29 Jan 2008 10:05:09 -0600 Nate Case [EMAIL PROTECTED] wrote: +/* PHY timer which schedules the state machine work */ +static void phy_timer(unsigned long data) +{ + struct phy_device *phydev = (struct phy_device *)data; + + /* + * PHY I/O operations can potentially sleep so we ensure that + * it's done from a process context + */ + schedule_work(phydev-state_queue); +} If you use schedule_delayed_work() instead, you can get rid of the timer. Haavard -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] MACB: clear transmit buffers properly on transmit underrun
From: Gregory CLEMENT [EMAIL PROTECTED] Initially transmit buffer pointers were only reset. But buffer descriptors were possibly still set as ready, and buffer in upper layer was not freed. This caused driver hang under big load. Now reset clean properly the buffer descriptor and freed upper layer. Signed-off-by: Gregory CLEMENT [EMAIL PROTECTED] Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- drivers/net/macb.c | 25 - 1 files changed, 24 insertions(+), 1 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 047ea7b..e10528e 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -307,8 +307,31 @@ static void macb_tx(struct macb *bp) (unsigned long)status); if (status MACB_BIT(UND)) { + int i; printk(KERN_ERR %s: TX underrun, resetting buffers\n, - bp-dev-name); + bp-dev-name); + + head = bp-tx_head; + + /*Mark all the buffer as used to avoid sending a lost buffer*/ + for (i = 0; i TX_RING_SIZE; i++) + bp-tx_ring[i].ctrl = MACB_BIT(TX_USED); + + /* free transmit buffer in upper layer*/ + for (tail = bp-tx_tail; tail != head; tail = NEXT_TX(tail)) { + struct ring_info *rp = bp-tx_skb[tail]; + struct sk_buff *skb = rp-skb; + + BUG_ON(skb == NULL); + + rmb(); + + dma_unmap_single(bp-pdev-dev, rp-mapping, skb-len, +DMA_TO_DEVICE); + rp-skb = NULL; + dev_kfree_skb_irq(skb); + } + bp-tx_head = bp-tx_tail = 0; } -- 1.5.3.4 -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] MACB: clear transmit buffers properly on TX Underrun
On Sun, 16 Dec 2007 12:37:25 +0100 Gregory CLEMENT [EMAIL PROTECTED] wrote: Haavard Skinnemoen a écrit : But the patch is a bit mangled, so I don't think it will apply. Please have a look in Documentation/email-clients.txt for information on how to set up Thunderbird to avoid this. I read it and apply it. Hope it will be OK as I didn't see any problem in m first mail... Looks good, thanks. I also think this should be done as part of the previous loop, before they are freed. Having free buffers in the ring sounds dangerous, even if it's only for a short time. OK, I moved this loop before the previous loop, as I wanted to be sure that all buffers are marked. I did it, but I think we don't really need to do it, as when underrun happen, controller stop transmitting, so it won't transmit a free buffer. Yes, you're probably right. But it looks better now, I think. + bp-tx_head = bp-tx_tail = 0; Now, I wonder if it would be better to just scan the ring descriptors, find the one that failed and just move the DMA pointer to the next entry. The hardware resets the DMA pointer when an underrun happens, so I think your code will work, but we're losing more packets than strictly necessary. In any case, it's better than the existing code. As hardware reset the DMA pointer, we have to rewrite all the buffer descriptor. For example if descriptor n°78 failed, and there is descriptor 79 and 80 which are pending. When underrun happen on 78 the hardware reset DMA pointer which will point on descriptor 0. So we have to copy descriptor 79 on 0 and 80 on 1. The other option is to change Transmit Buffer Queue Pointer Register (TBQP), to make it point on descriptor 79, but on the next descriptor having wrapped bit set, the DMA pointer will wrapped on descriptor 79 and not on 0. So I don't think it is a good solution. The second option sounds feasible to me. We know how large the ring is, so taking care of the wrapping isn't very expensive. Perhaps we need a check in macb_start_xmit() as well to avoid starting a transmission when the ring has just been reset. I joined the patch change along your recommendation, if there is no more error, you can maybe submit it for 2.6.24 release, and other improvement can be done later. Ok, if it works for you, I'll send it upstream; your patch certainly improves things. I think there's still an unresolved race with macb_start_xmit()...but closing it involves more complex modifications to the main tx patch, so it's probably safest to leave it for 2.6.25. From: Gregory CLEMENT [EMAIL PROTECTED] Date: Sun, 16 Dec 2007 11:45:03 +0100 Subject: [PATCH] MACB: clear transmit buffers properly on transmit underrun Initially transmit buffer pointers were only reset. But buffer descriptors were possibly still set as ready, and buffer in upper layer was not freed. This caused driver hang under big load. Now reset clean properly the buffer descriptor and freed upper layer. Signed-off-by: Gregory CLEMENT [EMAIL PROTECTED] --- drivers/net/macb.c | 27 ++- 1 files changed, 26 insertions(+), 1 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 047ea7b..e898713 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -307,9 +307,34 @@ static void macb_tx(struct macb *bp) (unsigned long)status); if (status MACB_BIT(UND)) { + int i; printk(KERN_ERR %s: TX underrun, resetting buffers\n, -bp-dev-name); +bp-dev-name); I'll just kill these extra spaces... bp-tx_head = bp-tx_tail = 0; + ...and this extra line. Haavard -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] MACB: clear transmit buffers properly on TX Underrun
On Thu, 13 Dec 2007 08:51:57 +0100 Gregory CLEMENT [EMAIL PROTECTED] wrote: Hi, I generated this patch for linux 2.6.24-rc5 and test it on AT91SAM9263 with iperf. From: Gregory CLEMENT [EMAIL PROTECTED] Date: Wed, 12 Dec 2007 18:10:14 +0100 Subject: [PATCH] MACB: clear transmit buffers properly on TX Underrun Initially transmit buffer pointers were only reset. But buffer descriptors were possibly still set as ready, and buffer in upper layer was not freed. This caused driver hang under big load. Now reset clean properly the buffer descriptor and freed upper layer. Nice. I think we want this for 2.6.24. But the patch is a bit mangled, so I don't think it will apply. Please have a look in Documentation/email-clients.txt for information on how to set up Thunderbird to avoid this. Signed-off-by: Gregory CLEMENT [EMAIL PROTECTED] --- drivers/net/macb.c | 26 +- 1 files changed, 25 insertions(+), 1 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 047ea7b..2ee1dab 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -307,9 +307,33 @@ static void macb_tx(struct macb *bp) (unsigned long)status); if (status MACB_BIT(UND)) { +int i; printk(KERN_ERR %s: TX underrun, resetting buffers\n, - bp-dev-name); + bp-dev-name); + +head = bp-tx_head; + +/* free transmit buffer in upper layer*/ +for (tail = bp-tx_tail; tail != head; tail = NEXT_TX(tail)) { +struct ring_info *rp = bp-tx_skb[tail]; +struct sk_buff *skb = rp-skb; + +BUG_ON(skb == NULL); + +rmb(); + +dma_unmap_single(bp-pdev-dev, rp-mapping, skb-len, + DMA_TO_DEVICE); +rp-skb = NULL; +dev_kfree_skb_irq(skb); +} + +/*Mark all the buffer as used to avoid sending a lost buffer*/ +for (i = 0; i RX_RING_SIZE; i++) +bp-tx_ring[i].ctrl = MACB_BIT(TX_USED); That should be TX_RING_SIZE, shouldn't it? I also think this should be done as part of the previous loop, before they are freed. Having free buffers in the ring sounds dangerous, even if it's only for a short time. + bp-tx_head = bp-tx_tail = 0; Now, I wonder if it would be better to just scan the ring descriptors, find the one that failed and just move the DMA pointer to the next entry. The hardware resets the DMA pointer when an underrun happens, so I think your code will work, but we're losing more packets than strictly necessary. In any case, it's better than the existing code. Perhaps we need a check in macb_start_xmit() as well to avoid starting a transmission when the ring has just been reset. Haavard -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2.6.23-rc8-mm2] Fix a compile problem in macb.c
From: Hans-Jürgen Koch [EMAIL PROTECTED] Compiling macb.c fails because the type of parameter 2 of macb_poll() was changed from int* to int. Furthermore, a local variable was removed but was still used inside the function. This patch fixes it. Signed-off-by: Hans J. Koch [EMAIL PROTECTED] Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- drivers/net/macb.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index c28a0a4..047ea7b 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -492,7 +492,7 @@ static int macb_poll(struct napi_struct *napi, int budget) } dev_dbg(bp-pdev-dev, poll: status = %08lx, budget = %d\n, - (unsigned long)status, *budget); + (unsigned long)status, budget); if (!(status MACB_BIT(REC))) { dev_warn(bp-pdev-dev, @@ -503,7 +503,7 @@ static int macb_poll(struct napi_struct *napi, int budget) } work_done = macb_rx(bp, budget); - if (work_done orig_budget) + if (work_done budget) netif_rx_complete(dev, napi); /* -- 1.5.3.1 - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] macb: Add multicast capability
From: Patrice Vilchez [EMAIL PROTECTED] Add multicast capability to Atmel ethernet macb driver. Signed-off-by: Patrice Vilchez [EMAIL PROTECTED] Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- drivers/net/macb.c | 120 1 files changed, 120 insertions(+), 0 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 83c35fd..a4bb026 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -796,6 +796,125 @@ static void macb_init_hw(struct macb *bp) } +/* + * The hash address register is 64 bits long and takes up two + * locations in the memory map. The least significant bits are stored + * in EMAC_HSL and the most significant bits in EMAC_HSH. + * + * The unicast hash enable and the multicast hash enable bits in the + * network configuration register enable the reception of hash matched + * frames. The destination address is reduced to a 6 bit index into + * the 64 bit hash register using the following hash function. The + * hash function is an exclusive or of every sixth bit of the + * destination address. + * + * hi[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47] + * hi[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46] + * hi[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45] + * hi[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44] + * hi[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43] + * hi[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42] + * + * da[0] represents the least significant bit of the first byte + * received, that is, the multicast/unicast indicator, and da[47] + * represents the most significant bit of the last byte received. If + * the hash index, hi[n], points to a bit that is set in the hash + * register then the frame will be matched according to whether the + * frame is multicast or unicast. A multicast match will be signalled + * if the multicast hash enable bit is set, da[0] is 1 and the hash + * index points to a bit set in the hash register. A unicast match + * will be signalled if the unicast hash enable bit is set, da[0] is 0 + * and the hash index points to a bit set in the hash register. To + * receive all multicast frames, the hash register should be set with + * all ones and the multicast hash enable bit should be set in the + * network configuration register. + */ + +static inline int hash_bit_value(int bitnr, __u8 *addr) +{ + if (addr[bitnr / 8] (1 (bitnr % 8))) + return 1; + return 0; +} + +/* + * Return the hash index value for the specified address. + */ +static int hash_get_index(__u8 *addr) +{ + int i, j, bitval; + int hash_index = 0; + + for (j = 0; j 6; j++) { + for (i = 0, bitval = 0; i 8; i++) + bitval ^= hash_bit_value(i*6 + j, addr); + + hash_index |= (bitval j); + } + + return hash_index; +} + +/* + * Add multicast addresses to the internal multicast-hash table. + */ +static void macb_sethashtable(struct net_device *dev) +{ + struct dev_mc_list *curr; + unsigned long mc_filter[2]; + unsigned int i, bitnr; + struct macb *bp = netdev_priv(dev); + + mc_filter[0] = mc_filter[1] = 0; + + curr = dev-mc_list; + for (i = 0; i dev-mc_count; i++, curr = curr-next) { + if (!curr) break; /* unexpected end of list */ + + bitnr = hash_get_index(curr-dmi_addr); + mc_filter[bitnr 5] |= 1 (bitnr 31); + } + + macb_writel(bp, HRB, mc_filter[0]); + macb_writel(bp, HRT, mc_filter[1]); +} + +/* + * Enable/Disable promiscuous and multicast modes. + */ +static void macb_set_rx_mode(struct net_device *dev) +{ + unsigned long cfg; + struct macb *bp = netdev_priv(dev); + + cfg = macb_readl(bp, NCFGR); + + if (dev-flags IFF_PROMISC) + /* Enable promiscuous mode */ + cfg |= MACB_BIT(CAF); + else if (dev-flags (~IFF_PROMISC)) +/* Disable promiscuous mode */ + cfg = ~MACB_BIT(CAF); + + if (dev-flags IFF_ALLMULTI) { + /* Enable all multicast mode */ + macb_writel(bp, HRB, -1); + macb_writel(bp, HRT, -1); + cfg |= MACB_BIT(NCFGR_MTI); + } else if (dev-mc_count 0) { + /* Enable specific multicasts */ + macb_sethashtable(dev); + cfg |= MACB_BIT(NCFGR_MTI); + } else if (dev-flags (~IFF_ALLMULTI)) { + /* Disable all multicast mode */ + macb_writel(bp, HRB, 0); + macb_writel(bp, HRT, 0); + cfg = ~MACB_BIT(NCFGR_MTI); + } + + macb_writel(bp, NCFGR, cfg); +} + static int macb_open(struct net_device *dev) { struct macb *bp = netdev_priv(dev); @@ -1025,6 +1144,7
[PATCH] macb: Use generic PHY layer
From: frederic RODO [EMAIL PROTECTED] Convert the macb driver to use the generic PHY layer in drivers/net/phy. Signed-off-by: Frederic RODO [EMAIL PROTECTED] Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- drivers/net/Kconfig |2 +- drivers/net/macb.c| 451 +++-- drivers/net/macb.h| 10 +- include/asm-arm/arch-at91/board.h |1 + include/asm-avr32/arch-at32ap/board.h |1 + 5 files changed, 208 insertions(+), 257 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b941c74..4b9b7fe 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -187,7 +187,7 @@ config MII config MACB tristate Atmel MACB support depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 - select MII + select PHYLIB help The Atmel MACB ethernet interface is found on many AT32 and AT91 parts. Say Y to include support for the MACB chip. diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 0e04f7a..83c35fd 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -17,13 +17,12 @@ #include linux/init.h #include linux/netdevice.h #include linux/etherdevice.h -#include linux/mii.h -#include linux/mutex.h #include linux/dma-mapping.h -#include linux/ethtool.h #include linux/platform_device.h +#include linux/phy.h #include asm/arch/board.h +#include asm/arch/cpu.h #include macb.h @@ -85,172 +84,202 @@ static void __init macb_get_hwaddr(struct macb *bp) memcpy(bp-dev-dev_addr, addr, sizeof(addr)); } -static void macb_enable_mdio(struct macb *bp) +static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) { - unsigned long flags; - u32 reg; - - spin_lock_irqsave(bp-lock, flags); - reg = macb_readl(bp, NCR); - reg |= MACB_BIT(MPE); - macb_writel(bp, NCR, reg); - macb_writel(bp, IER, MACB_BIT(MFD)); - spin_unlock_irqrestore(bp-lock, flags); -} - -static void macb_disable_mdio(struct macb *bp) -{ - unsigned long flags; - u32 reg; - - spin_lock_irqsave(bp-lock, flags); - reg = macb_readl(bp, NCR); - reg = ~MACB_BIT(MPE); - macb_writel(bp, NCR, reg); - macb_writel(bp, IDR, MACB_BIT(MFD)); - spin_unlock_irqrestore(bp-lock, flags); -} - -static int macb_mdio_read(struct net_device *dev, int phy_id, int location) -{ - struct macb *bp = netdev_priv(dev); + struct macb *bp = bus-priv; int value; - mutex_lock(bp-mdio_mutex); - - macb_enable_mdio(bp); macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) | MACB_BF(RW, MACB_MAN_READ) - | MACB_BF(PHYA, phy_id) - | MACB_BF(REGA, location) + | MACB_BF(PHYA, mii_id) + | MACB_BF(REGA, regnum) | MACB_BF(CODE, MACB_MAN_CODE))); - wait_for_completion(bp-mdio_complete); + /* wait for end of transfer */ + while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR))) + cpu_relax(); value = MACB_BFEXT(DATA, macb_readl(bp, MAN)); - macb_disable_mdio(bp); - mutex_unlock(bp-mdio_mutex); return value; } -static void macb_mdio_write(struct net_device *dev, int phy_id, - int location, int val) +static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, + u16 value) { - struct macb *bp = netdev_priv(dev); - - dev_dbg(bp-pdev-dev, mdio_write %02x:%02x - %04x\n, - phy_id, location, val); - - mutex_lock(bp-mdio_mutex); - macb_enable_mdio(bp); + struct macb *bp = bus-priv; macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) | MACB_BF(RW, MACB_MAN_WRITE) - | MACB_BF(PHYA, phy_id) - | MACB_BF(REGA, location) + | MACB_BF(PHYA, mii_id) + | MACB_BF(REGA, regnum) | MACB_BF(CODE, MACB_MAN_CODE) - | MACB_BF(DATA, val))); + | MACB_BF(DATA, value))); - wait_for_completion(bp-mdio_complete); + /* wait for end of transfer */ + while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR))) + cpu_relax(); + + return 0; +} - macb_disable_mdio(bp); - mutex_unlock(bp-mdio_mutex); +static int macb_mdio_reset(struct mii_bus *bus) +{ + return 0; } -static int macb_phy_probe(struct macb *bp) +static void macb_handle_link_change(struct net_device *dev) { - int phy_address; - u16 phyid1, phyid2; + struct macb *bp = netdev_priv(dev); + struct phy_device *phydev = bp-phy_dev; + unsigned long flags; - for (phy_address = 0
[PATCH] macb: Remove inappropriate spinlocks around mii calls
Remove spin_lock_irqsave() around mii_ethtool_gset, mii_ethtool_sset and generic_mii_ioctl. These are unnecessary and harmful because the mii calls may call back into the mdio functions, which may sleep. Pointed out by David Brownell. Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- drivers/net/macb.c | 24 +++- 1 files changed, 3 insertions(+), 21 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index a41418b..2e9571b 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -881,27 +881,15 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev) static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct macb *bp = netdev_priv(dev); - int ret; - unsigned long flags; - - spin_lock_irqsave(bp-lock, flags); - ret = mii_ethtool_gset(bp-mii, cmd); - spin_unlock_irqrestore(bp-lock, flags); - return ret; + return mii_ethtool_gset(bp-mii, cmd); } static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct macb *bp = netdev_priv(dev); - int ret; - unsigned long flags; - - spin_lock_irqsave(bp-lock, flags); - ret = mii_ethtool_sset(bp-mii, cmd); - spin_unlock_irqrestore(bp-lock, flags); - return ret; + return mii_ethtool_sset(bp-mii, cmd); } static void macb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -930,17 +918,11 @@ static struct ethtool_ops macb_ethtool_ops = { static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct macb *bp = netdev_priv(dev); - int ret; - unsigned long flags; if (!netif_running(dev)) return -EINVAL; - spin_lock_irqsave(bp-lock, flags); - ret = generic_mii_ioctl(bp-mii, if_mii(rq), cmd, NULL); - spin_unlock_irqrestore(bp-lock, flags); - - return ret; + return generic_mii_ioctl(bp-mii, if_mii(rq), cmd, NULL); } static ssize_t macb_mii_show(const struct device *_dev, char *buf, -- 1.4.4.4 - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] AT91: MACB support
From: Andrew Victor [EMAIL PROTECTED] The Atmel MACB Ethernet peripheral is also integrated in the AT91SAM9260 and AT91SAM9263 processors. The differences from the AVR32 version are: * Single peripheral clock. * MII/RMII selection bit is inverted. * Clock enable bit. Original patch from Patrice Vilchez. Signed-off-by: Andrew Victor [EMAIL PROTECTED] Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- drivers/net/Kconfig |2 +- drivers/net/macb.c | 25 +++-- drivers/net/macb.h |8 +++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 8aa8dd0..3318f30 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -190,7 +190,7 @@ config MII config MACB tristate Atmel MACB support - depends on NET_ETHERNET AVR32 + depends on NET_ETHERNET (AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263) select MII help The Atmel MACB ethernet interface is found on many AT32 and AT91 diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 25b559b..5eb7a35 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -1046,6 +1046,14 @@ static int __devinit macb_probe(struct platform_device *pdev) spin_lock_init(bp-lock); +#if defined(CONFIG_ARCH_AT91) + bp-pclk = clk_get(pdev-dev, macb_clk); + if (IS_ERR(bp-pclk)) { + dev_err(pdev-dev, failed to get macb_clk\n); + goto err_out_free_dev; + } + clk_enable(bp-pclk); +#else bp-pclk = clk_get(pdev-dev, pclk); if (IS_ERR(bp-pclk)) { dev_err(pdev-dev, failed to get pclk\n); @@ -1059,6 +1067,7 @@ static int __devinit macb_probe(struct platform_device *pdev) clk_enable(bp-pclk); clk_enable(bp-hclk); +#endif bp-regs = ioremap(regs-start, regs-end - regs-start + 1); if (!bp-regs) { @@ -1119,9 +1128,17 @@ static int __devinit macb_probe(struct platform_device *pdev) pdata = pdev-dev.platform_data; if (pdata pdata-is_rmii) +#if defined(CONFIG_ARCH_AT91) + macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) ); +#else macb_writel(bp, USRIO, 0); +#endif else +#if defined(CONFIG_ARCH_AT91) + macb_writel(bp, USRIO, MACB_BIT(CLKEN)); +#else macb_writel(bp, USRIO, MACB_BIT(MII)); +#endif bp-tx_pending = DEF_TX_RING_PENDING; @@ -1148,9 +1165,11 @@ err_out_free_irq: err_out_iounmap: iounmap(bp-regs); err_out_disable_clocks: +#ifndef CONFIG_ARCH_AT91 clk_disable(bp-hclk); - clk_disable(bp-pclk); clk_put(bp-hclk); +#endif + clk_disable(bp-pclk); err_out_put_pclk: clk_put(bp-pclk); err_out_free_dev: @@ -1173,9 +1192,11 @@ static int __devexit macb_remove(struct platform_device *pdev) unregister_netdev(dev); free_irq(dev-irq, dev); iounmap(bp-regs); +#ifndef CONFIG_ARCH_AT91 clk_disable(bp-hclk); - clk_disable(bp-pclk); clk_put(bp-hclk); +#endif + clk_disable(bp-pclk); clk_put(bp-pclk); free_netdev(dev); platform_set_drvdata(pdev, NULL); diff --git a/drivers/net/macb.h b/drivers/net/macb.h index 27bf0ae..b3bb218 100644 --- a/drivers/net/macb.h +++ b/drivers/net/macb.h @@ -200,7 +200,7 @@ #define MACB_SOF_OFFSET30 #define MACB_SOF_SIZE 2 -/* Bitfields in USRIO */ +/* Bitfields in USRIO (AVR32) */ #define MACB_MII_OFFSET0 #define MACB_MII_SIZE 1 #define MACB_EAM_OFFSET1 @@ -210,6 +210,12 @@ #define MACB_TX_PAUSE_ZERO_OFFSET 3 #define MACB_TX_PAUSE_ZERO_SIZE1 +/* Bitfields in USRIO (AT91) */ +#define MACB_RMII_OFFSET 0 +#define MACB_RMII_SIZE 1 +#define MACB_CLKEN_OFFSET 1 +#define MACB_CLKEN_SIZE1 + /* Bitfields in WOL */ #define MACB_IP_OFFSET 0 #define MACB_IP_SIZE 16 -- 1.4.4.3 - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] MACB: Use struct delayed_work instead of struct work_struct
The macb driver calls schedule_delayed_work() and friends, so we need to use a struct delayed_work along with it. The conversion was explained by David Howells on lkml Dec 5 2006: http://lkml.org/lkml/2006/12/5/269 Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- drivers/net/macb.c |6 +++--- drivers/net/macb.h |2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index bd0ce98..3496d19 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -267,9 +267,9 @@ static void macb_update_stats(struct mac *p += readl(reg); } -static void macb_periodic_task(void *arg) +static void macb_periodic_task(struct work_struct *work) { - struct macb *bp = arg; + struct macb *bp = container_of(work, struct macb, periodic_task.work); macb_update_stats(bp); macb_check_media(bp, 1, 0); @@ -1088,7 +1088,7 @@ static int __devinit macb_probe(struct p dev-base_addr = regs-start; - INIT_WORK(bp-periodic_task, macb_periodic_task, bp); + INIT_DELAYED_WORK(bp-periodic_task, macb_periodic_task); mutex_init(bp-mdio_mutex); init_completion(bp-mdio_complete); diff --git a/drivers/net/macb.h b/drivers/net/macb.h index 8c253db..e3fcb2e 100644 --- a/drivers/net/macb.h +++ b/drivers/net/macb.h @@ -377,7 +377,7 @@ struct macb { unsigned intrx_pending, tx_pending; - struct work_struct periodic_task; + struct delayed_work periodic_task; struct mutexmdio_mutex; struct completion mdio_complete; -- 1.4.3.3 - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] MACB: Use __raw register access
Since macb is a chip-internal device, use __raw_readl and __raw_writel instead of readl/writel. This will perform native-endian accesses, which is the right thing to do on both AVR32 and ARM devices. Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- drivers/net/macb.c |2 +- drivers/net/macb.h |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 3496d19..25b559b 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -264,7 +264,7 @@ static void macb_update_stats(struct mac WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4); for(; p end; p++, reg++) - *p += readl(reg); + *p += __raw_readl(reg); } static void macb_periodic_task(struct work_struct *work) diff --git a/drivers/net/macb.h b/drivers/net/macb.h index e3fcb2e..27bf0ae 100644 --- a/drivers/net/macb.h +++ b/drivers/net/macb.h @@ -250,9 +250,9 @@ /* Register access macros */ #define macb_readl(port,reg) \ - readl((port)-regs + MACB_##reg) + __raw_readl((port)-regs + MACB_##reg) #define macb_writel(port,reg,value)\ - writel((value), (port)-regs + MACB_##reg) + __raw_writel((value), (port)-regs + MACB_##reg) struct dma_desc { u32 addr; -- 1.4.3.3 - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH take 2] Atmel MACB ethernet driver
Driver for the Atmel MACB on-chip ethernet module. Tested on AVR32/AT32AP7000/ATSTK1000. I've heard rumours that it works with AT91SAM9260 as well, and it may be possible to share some code with the at91_ether driver for AT91RM9200. Hardware documentation can be found in the AT32AP7000 data sheet, which can be downloaded from http://www.atmel.com/dyn/products/datasheets.asp?family_id=682 Changes since previous version: * Probe for PHY ID instead of depending on it being provided through platform_data. * Grab initial ethernet address from the MACB registers instead of depending on platform_data. * Set MII/RMII mode correctly. These changes are mostly about making the driver more compatible with the at91 infrastructure. Signed-off-by: Haavard Skinnemoen [EMAIL PROTECTED] --- MAINTAINERS |7 + drivers/net/Kconfig | 11 + drivers/net/Makefile |2 + drivers/net/macb.c | 1210 ++ drivers/net/macb.h | 387 5 files changed, 1617 insertions(+), 0 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index d708702..b8c28b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -426,6 +426,13 @@ L: [EMAIL PROTECTED] W: http://linux-atm.sourceforge.net S: Maintained +ATMEL MACB ETHERNET DRIVER +P: Atmel AVR32 Support Team +M: [EMAIL PROTECTED] +P: Haavard Skinnemoen +M: [EMAIL PROTECTED] +S: Supported + ATMEL WIRELESS DRIVER P: Simon Kelley M: [EMAIL PROTECTED] diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9cb3ca5..4e033b1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -188,6 +188,17 @@ config MII or internal device. It is safe to say Y or M here even if your ethernet card lack MII. +config MACB + tristate Atmel MACB support + depends on NET_ETHERNET AVR32 + select MII + help + The Atmel MACB ethernet interface is found on many AT32 and AT91 + parts. Say Y to include support for the MACB chip. + + To compile this driver as a module, choose M here: the module + will be called macb. + source drivers/net/arm/Kconfig config MACE diff --git a/drivers/net/Makefile b/drivers/net/Makefile index f270bc4..8e67697 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -197,6 +197,8 @@ obj-$(CONFIG_SMC911X) += smc911x.o obj-$(CONFIG_DM9000) += dm9000.o obj-$(CONFIG_FEC_8XX) += fec_8xx/ +obj-$(CONFIG_MACB) += macb.o + obj-$(CONFIG_ARM) += arm/ obj-$(CONFIG_DEV_APPLETALK) += appletalk/ obj-$(CONFIG_TR) += tokenring/ diff --git a/drivers/net/macb.c b/drivers/net/macb.c new file mode 100644 index 000..bd0ce98 --- /dev/null +++ b/drivers/net/macb.c @@ -0,0 +1,1210 @@ +/* + * Atmel MACB Ethernet Controller driver + * + * Copyright (C) 2004-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/clk.h +#include linux/module.h +#include linux/moduleparam.h +#include linux/kernel.h +#include linux/types.h +#include linux/slab.h +#include linux/init.h +#include linux/netdevice.h +#include linux/etherdevice.h +#include linux/mii.h +#include linux/mutex.h +#include linux/dma-mapping.h +#include linux/ethtool.h +#include linux/platform_device.h + +#include asm/arch/board.h + +#include macb.h + +#define to_net_dev(class) container_of(class, struct net_device, class_dev) + +#define RX_BUFFER_SIZE 128 +#define RX_RING_SIZE 512 +#define RX_RING_BYTES (sizeof(struct dma_desc) * RX_RING_SIZE) + +/* Make the IP header word-aligned (the ethernet header is 14 bytes) */ +#define RX_OFFSET 2 + +#define TX_RING_SIZE 128 +#define DEF_TX_RING_PENDING(TX_RING_SIZE - 1) +#define TX_RING_BYTES (sizeof(struct dma_desc) * TX_RING_SIZE) + +#define TX_RING_GAP(bp)\ + (TX_RING_SIZE - (bp)-tx_pending) +#define TX_BUFFS_AVAIL(bp) \ + (((bp)-tx_tail = (bp)-tx_head) ? \ +(bp)-tx_tail + (bp)-tx_pending - (bp)-tx_head : \ +(bp)-tx_tail - (bp)-tx_head - TX_RING_GAP(bp)) +#define NEXT_TX(n) (((n) + 1) (TX_RING_SIZE - 1)) + +#define NEXT_RX(n) (((n) + 1) (RX_RING_SIZE - 1)) + +/* minimum number of free TX descriptors before waking up TX process */ +#define MACB_TX_WAKEUP_THRESH (TX_RING_SIZE / 4) + +#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \ +| MACB_BIT(ISR_ROVR)) + +static void __macb_set_hwaddr(struct macb *bp) +{ + u32 bottom; + u16 top; + + bottom = cpu_to_le32(*((u32 *)bp-dev-dev_addr)); + macb_writel(bp, SA1B, bottom); + top = cpu_to_le16(*((u16 *)(bp-dev-dev_addr + 4))); + macb_writel(bp, SA1T