[PATCH 18/30] rapidio/rionet: add mport removal handling
Add handling of a local mport device removal. RIONET driver registers itself as class interface that supports only removal notification, 'add_device' callback is not provided because RIONET network device can be initialized only after enumeration is completed and the existing method (using remote peer addition) satisfies this condition. Signed-off-by: Alexandre Bounine <alexandre.boun...@idt.com> Cc: Matt Porter <mpor...@kernel.crashing.org> Cc: Aurelien Jacquiot <a-jacqu...@ti.com> Cc: Andre van Herk <andre.van.h...@prodrive-technologies.com> Cc: linux-ker...@vger.kernel.org Cc: netdev@vger.kernel.org --- drivers/net/rionet.c | 70 +++-- 1 files changed, 44 insertions(+), 26 deletions(-) diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index c15d958..9cfe6ae 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -676,6 +676,34 @@ static int rionet_shutdown(struct notifier_block *nb, unsigned long code, return NOTIFY_DONE; } +static void rionet_remove_mport(struct device *dev, + struct class_interface *class_intf) +{ + struct rio_mport *mport = to_rio_mport(dev); + struct net_device *ndev; + int id = mport->id; + + pr_debug("%s %s\n", __func__, mport->name); + + WARN(nets[id].nact, "%s called when connected to %d peers\n", +__func__, nets[id].nact); + WARN(!nets[id].ndev, "%s called for mport without NDEV\n", +__func__); + + if (nets[id].ndev) { + ndev = nets[id].ndev; + netif_stop_queue(ndev); + unregister_netdev(ndev); + + free_pages((unsigned long)nets[id].active, + get_order(sizeof(void *) * + RIO_MAX_ROUTE_ENTRIES(mport->sys_size))); + nets[id].active = NULL; + free_netdev(ndev); + nets[id].ndev = NULL; + } +} + #ifdef MODULE static struct rio_device_id rionet_id_table[] = { {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}, @@ -696,6 +724,13 @@ static struct notifier_block rionet_notifier = { .notifier_call = rionet_shutdown, }; +/* the rio_mport_interface is used to handle local mport devices */ +static struct class_interface rio_mport_interface __refdata = { + .class = _mport_class, + .add_dev = NULL, + .remove_dev = rionet_remove_mport, +}; + static int __init rionet_init(void) { int ret; @@ -706,39 +741,22 @@ static int __init rionet_init(void) DRV_NAME, ret); return ret; } + + ret = class_interface_register(_mport_interface); + if (ret) { + pr_err("%s: class_interface_register error: %d\n", + DRV_NAME, ret); + return ret; + } + return subsys_interface_register(_interface); } static void __exit rionet_exit(void) { - struct rionet_private *rnet; - struct net_device *ndev; - struct rionet_peer *peer, *tmp; - int i; - - for (i = 0; i < RIONET_MAX_NETS; i++) { - if (nets[i].ndev != NULL) { - ndev = nets[i].ndev; - rnet = netdev_priv(ndev); - unregister_netdev(ndev); - - list_for_each_entry_safe(peer, -tmp, [i].peers, node) { - list_del(>node); - kfree(peer); - } - - free_pages((unsigned long)nets[i].active, -get_order(sizeof(void *) * -RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size))); - nets[i].active = NULL; - - free_netdev(ndev); - } - } - unregister_reboot_notifier(_notifier); subsys_interface_unregister(_interface); + class_interface_unregister(_mport_interface); } late_initcall(rionet_init); -- 1.7.8.4
[PATCH 02/30] rapidio/rionet: add capability to change MTU
From: Aurelien Jacquiot <a-jacqu...@ti.com> Replace default Ethernet-specific routine by the custom one to allow setting of larger MTU supported by RapidIO messaging (max RIO packet size is 4096 bytes). Signed-off-by: Aurelien Jacquiot <a-jacqu...@ti.com> Signed-off-by: Alexandre Bounine <alexandre.boun...@idt.com> Cc: Matt Porter <mpor...@kernel.crashing.org> Cc: Andre van Herk <andre.van.h...@prodrive-technologies.com> Cc: linux-ker...@vger.kernel.org Cc: netdev@vger.kernel.org --- drivers/net/rionet.c | 17 +++-- 1 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index e7034c5..d3d6e35 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -48,6 +48,8 @@ MODULE_LICENSE("GPL"); #define RIONET_TX_RING_SIZECONFIG_RIONET_TX_SIZE #define RIONET_RX_RING_SIZECONFIG_RIONET_RX_SIZE #define RIONET_MAX_NETS8 +#define RIONET_MSG_SIZE RIO_MAX_MSG_SIZE +#define RIONET_MAX_MTU (RIONET_MSG_SIZE - ETH_HLEN) struct rionet_private { struct rio_mport *mport; @@ -443,6 +445,17 @@ static void rionet_set_msglevel(struct net_device *ndev, u32 value) rnet->msg_enable = value; } +static int rionet_change_mtu(struct net_device *ndev, int new_mtu) +{ + if ((new_mtu < 68) || (new_mtu > RIONET_MAX_MTU)) { + printk(KERN_ERR "%s: Invalid MTU size %d\n", + ndev->name, new_mtu); + return -EINVAL; + } + ndev->mtu = new_mtu; + return 0; +} + static const struct ethtool_ops rionet_ethtool_ops = { .get_drvinfo = rionet_get_drvinfo, .get_msglevel = rionet_get_msglevel, @@ -454,7 +467,7 @@ static const struct net_device_ops rionet_netdev_ops = { .ndo_open = rionet_open, .ndo_stop = rionet_close, .ndo_start_xmit = rionet_start_xmit, - .ndo_change_mtu = eth_change_mtu, + .ndo_change_mtu = rionet_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address= eth_mac_addr, }; @@ -489,7 +502,7 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) ndev->dev_addr[5] = device_id & 0xff; ndev->netdev_ops = _netdev_ops; - ndev->mtu = RIO_MAX_MSG_SIZE - 14; + ndev->mtu = RIONET_MAX_MTU; ndev->features = NETIF_F_LLTX; SET_NETDEV_DEV(ndev, >dev); ndev->ethtool_ops = _ethtool_ops; -- 1.7.8.4
[PATCH 01/30] rapidio/rionet: fix deadlock on SMP
From: Aurelien Jacquiot <a-jacqu...@ti.com> Fix deadlocking during concurrent receive and transmit operations on SMP platforms caused by the use of incorrect lock: on transmit 'tx_lock' spinlock should be used instead of 'lock' which is used for receive operation. This fix is applicable to kernel versions starting from v2.15. Signed-off-by: Aurelien Jacquiot <a-jacqu...@ti.com> Signed-off-by: Alexandre Bounine <alexandre.boun...@idt.com> Cc: Matt Porter <mpor...@kernel.crashing.org> Cc: Andre van Herk <andre.van.h...@prodrive-technologies.com> Cc: linux-ker...@vger.kernel.org Cc: netdev@vger.kernel.org --- drivers/net/rionet.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 01f08a7..e7034c5 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -280,7 +280,7 @@ static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbo struct net_device *ndev = dev_id; struct rionet_private *rnet = netdev_priv(ndev); - spin_lock(>lock); + spin_lock(>tx_lock); if (netif_msg_intr(rnet)) printk(KERN_INFO @@ -299,7 +299,7 @@ static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbo if (rnet->tx_cnt < RIONET_TX_RING_SIZE) netif_wake_queue(ndev); - spin_unlock(>lock); + spin_unlock(>tx_lock); } static int rionet_open(struct net_device *ndev) -- 1.7.8.4
[PATCH 11/30] rapidio/rionet: add shutdown event handling
Add shutdown notification handler which terminates active connections with remote RapidIO nodes. This prevents remote nodes from sending packets to the powered off node and eliminates hardware error events on remote nodes. Signed-off-by: Alexandre Bounine <alexandre.boun...@idt.com> Cc: Matt Porter <mpor...@kernel.crashing.org> Cc: Aurelien Jacquiot <a-jacqu...@ti.com> Cc: Andre van Herk <andre.van.h...@prodrive-technologies.com> Cc: linux-ker...@vger.kernel.org Cc: netdev@vger.kernel.org --- drivers/net/rionet.c | 38 ++ 1 files changed, 38 insertions(+), 0 deletions(-) diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index d3d6e35..f994fa1 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -24,6 +24,7 @@ #include #include #include +#include #define DRV_NAME"rionet" #define DRV_VERSION "0.3" @@ -599,6 +600,30 @@ out: return rc; } +static int rionet_shutdown(struct notifier_block *nb, unsigned long code, + void *unused) +{ + struct rionet_peer *peer, *tmp; + int i; + + pr_debug("%s: %s\n", DRV_NAME, __func__); + + for (i = 0; i < RIONET_MAX_NETS; i++) { + if (!nets[i].ndev) + continue; + + list_for_each_entry_safe(peer, tmp, [i].peers, node) { + if (nets[i].active[peer->rdev->destid]) { + rio_send_doorbell(peer->rdev, + RIONET_DOORBELL_LEAVE); + nets[i].active[peer->rdev->destid] = NULL; + } + } + } + + return NOTIFY_DONE; +} + #ifdef MODULE static struct rio_device_id rionet_id_table[] = { {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}, @@ -615,8 +640,20 @@ static struct subsys_interface rionet_interface = { .remove_dev = rionet_remove_dev, }; +static struct notifier_block rionet_notifier = { + .notifier_call = rionet_shutdown, +}; + static int __init rionet_init(void) { + int ret; + + ret = register_reboot_notifier(_notifier); + if (ret) { + pr_err("%s: failed to register reboot notifier (err=%d)\n", + DRV_NAME, ret); + return ret; + } return subsys_interface_register(_interface); } @@ -648,6 +685,7 @@ static void __exit rionet_exit(void) } } + unregister_reboot_notifier(_notifier); subsys_interface_unregister(_interface); } -- 1.7.8.4
[PATCH 17/30] rapidio/rionet: add locking into add/remove device
Add spinlock protection when handling list of connected peers and ability to handle new peer device addition after the RIONET device was open. Before his update RIONET was sending JOIN requests only when it have been opened, peer devices added later have been missing from this process. Signed-off-by: Alexandre Bounine <alexandre.boun...@idt.com> Cc: Matt Porter <mpor...@kernel.crashing.org> Cc: Aurelien Jacquiot <a-jacqu...@ti.com> Cc: Andre van Herk <andre.van.h...@prodrive-technologies.com> Cc: linux-ker...@vger.kernel.org Cc: netdev@vger.kernel.org --- drivers/net/rionet.c | 152 + 1 files changed, 102 insertions(+), 50 deletions(-) diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index f994fa1..c15d958 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -63,6 +63,7 @@ struct rionet_private { spinlock_t lock; spinlock_t tx_lock; u32 msg_enable; + bool open; }; struct rionet_peer { @@ -74,6 +75,7 @@ struct rionet_peer { struct rionet_net { struct net_device *ndev; struct list_head peers; + spinlock_t lock;/* net info access lock */ struct rio_dev **active; int nact; /* number of active peers */ }; @@ -235,26 +237,32 @@ static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u struct net_device *ndev = dev_id; struct rionet_private *rnet = netdev_priv(ndev); struct rionet_peer *peer; + unsigned char netid = rnet->mport->id; if (netif_msg_intr(rnet)) printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x", DRV_NAME, sid, tid, info); if (info == RIONET_DOORBELL_JOIN) { - if (!nets[rnet->mport->id].active[sid]) { - list_for_each_entry(peer, - [rnet->mport->id].peers, node) { + if (!nets[netid].active[sid]) { + spin_lock([netid].lock); + list_for_each_entry(peer, [netid].peers, node) { if (peer->rdev->destid == sid) { - nets[rnet->mport->id].active[sid] = - peer->rdev; - nets[rnet->mport->id].nact++; + nets[netid].active[sid] = peer->rdev; + nets[netid].nact++; } } + spin_unlock([netid].lock); + rio_mport_send_doorbell(mport, sid, RIONET_DOORBELL_JOIN); } } else if (info == RIONET_DOORBELL_LEAVE) { - nets[rnet->mport->id].active[sid] = NULL; - nets[rnet->mport->id].nact--; + spin_lock([netid].lock); + if (nets[netid].active[sid]) { + nets[netid].active[sid] = NULL; + nets[netid].nact--; + } + spin_unlock([netid].lock); } else { if (netif_msg_intr(rnet)) printk(KERN_WARNING "%s: unhandled doorbell\n", @@ -308,8 +316,10 @@ static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbo static int rionet_open(struct net_device *ndev) { int i, rc = 0; - struct rionet_peer *peer, *tmp; + struct rionet_peer *peer; struct rionet_private *rnet = netdev_priv(ndev); + unsigned char netid = rnet->mport->id; + unsigned long flags; if (netif_msg_ifup(rnet)) printk(KERN_INFO "%s: open\n", DRV_NAME); @@ -348,20 +358,13 @@ static int rionet_open(struct net_device *ndev) netif_carrier_on(ndev); netif_start_queue(ndev); - list_for_each_entry_safe(peer, tmp, -[rnet->mport->id].peers, node) { - if (!(peer->res = rio_request_outb_dbell(peer->rdev, -RIONET_DOORBELL_JOIN, - RIONET_DOORBELL_LEAVE))) - { - printk(KERN_ERR "%s: error requesting doorbells\n", - DRV_NAME); - continue; - } - + spin_lock_irqsave([netid].lock, flags); + list_for_each_entry(peer, [netid].peers, node) { /* Send a join message */ rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); } + spin_unlock_irqrestore([netid].lock, flags); + rnet->open = true; out: return rc; @@ -370,7 +373
[PATCH 5/5 v2] Tsi108_eth: Add ethtool support
Add ethtool support to tsi108_eth network driver. Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-02-06 17:10:53.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 18:09:43.0 -0500 @@ -36,6 +36,7 @@ #include linux/net.h #include linux/netdevice.h #include linux/etherdevice.h +#include linux/ethtool.h #include linux/skbuff.h #include linux/slab.h #include linux/spinlock.h @@ -1519,12 +1520,46 @@ static void tsi108_init_mac(struct net_d TSI_WRITE(TSI108_EC_INTMASK, ~0); } +static int tsi108_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct tsi108_prv_data *data = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(data-txlock, flags); + rc = mii_ethtool_gset(data-mii_if, cmd); + spin_unlock_irqrestore(data-txlock, flags); + + return rc; +} + +static int tsi108_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct tsi108_prv_data *data = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(data-txlock, flags); + rc = mii_ethtool_sset(data-mii_if, cmd); + spin_unlock_irqrestore(data-txlock, flags); + + return rc; +} + static int tsi108_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct tsi108_prv_data *data = netdev_priv(dev); + if (!netif_running(dev)) + return -EINVAL; return generic_mii_ioctl(data-mii_if, if_mii(rq), cmd, NULL); } +static const struct ethtool_ops tsi108_ethtool_ops = { + .get_link = ethtool_op_get_link, + .get_settings = tsi108_get_settings, + .set_settings = tsi108_set_settings, +}; + static int tsi108_init_one(struct platform_device *pdev) { @@ -1589,6 +1624,7 @@ tsi108_init_one(struct platform_device * dev-get_stats = tsi108_get_stats; netif_napi_add(dev, data-napi, tsi108_poll, 64); dev-do_ioctl = tsi108_do_ioctl; + dev-ethtool_ops = tsi108_ethtool_ops; /* Apparently, the Linux networking code won't use scatter-gather * if the hardware doesn't do checksums. However, it's faster --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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 1/5 v2] Tsi108_eth: add missing linking to driver data
Bug fix for tsi108_eth network driver. This patch adds missing linking to driver data. Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-01-24 17:58:37.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 14:30:04.0 -0500 @@ -1629,6 +1629,7 @@ tsi108_init_one(struct platform_device * goto register_fail; } + platform_set_drvdata(pdev, dev); printk(KERN_INFO %s: Tsi108 Gigabit Ethernet, MAC: %s\n, dev-name, print_mac(mac, dev-dev_addr)); #ifdef DEBUG --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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 4/5 v2] Tsi108_eth: fix link recovery after disconnect
Bug fix for tsi108_eth network driver. This patch fixes a problem with link recovery after connection was lost. Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-02-06 16:16:00.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 16:57:41.0 -0500 @@ -338,22 +338,21 @@ static void tsi108_check_phy(struct net_ TSI_WRITE(TSI108_MAC_CFG2, mac_cfg2_reg); TSI_WRITE(TSI108_EC_PORTCTRL, portctrl_reg); + } - if (data-link_up == 0) { - /* The manual says it can take 3-4 usecs for the speed change -* to take effect. -*/ - udelay(5); - - spin_lock(data-txlock); - if (is_valid_ether_addr(dev-dev_addr) data-txfree) - netif_wake_queue(dev); + if (data-link_up == 0) { + /* The manual says it can take 3-4 usecs for the speed change +* to take effect. +*/ + udelay(5); - data-link_up = 1; - spin_unlock(data-txlock); - } - } + spin_lock(data-txlock); + if (is_valid_ether_addr(dev-dev_addr) data-txfree) + netif_wake_queue(dev); + data-link_up = 1; + spin_unlock(data-txlock); + } } else { if (data-link_up == 1) { netif_stop_queue(dev); @@ -1267,12 +1266,11 @@ static void tsi108_init_phy(struct net_d * PHY_STAT register before the link up status bit is set. */ - data-link_up = 1; + data-link_up = 0; while (!((phyval = tsi108_read_mii(data, MII_BMSR)) BMSR_LSTATUS)) { if (i++ (MII_READ_DELAY / 10)) { - data-link_up = 0; break; } spin_unlock_irqrestore(phy_lock, flags); --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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 3/5 v2] Tsi108_eth: remove not needed code
Code clean-up for tsi108_eth network driver. This patch removes not needed dummy read and the corresponding comment. The PHY logic requires two reads from the status register to get current link status. This is done correctly inside mii_check_media(). Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-02-06 15:47:35.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 15:54:14.0 -0500 @@ -297,18 +297,11 @@ static void tsi108_check_phy(struct net_ u32 speed; unsigned long flags; - /* Do a dummy read, as for some reason the first read -* after a link becomes up returns link down, even if -* it's been a while since the link came up. -*/ - spin_lock_irqsave(phy_lock, flags); if (!data-phy_ok) goto out; - tsi108_read_mii(data, MII_BMSR); - duplex = mii_check_media(data-mii_if, netif_msg_link(data), data-init_media); data-init_media = 0; --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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/5 v2] Tsi108_eth: fix detection of 1000Mb mode
Bug fix for tsi108_eth network driver. This patch fixes a problem with detection of 1000Mb speed. Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-02-06 15:09:19.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 15:34:12.0 -0500 @@ -1287,6 +1287,7 @@ static void tsi108_init_phy(struct net_d spin_lock_irqsave(phy_lock, flags); } + data-mii_if.supports_gmii = mii_check_gmii_support(data-mii_if); printk(KERN_DEBUG PHY_STAT reg contains %08x\n, phyval); data-phy_ok = 1; data-init_media = 1; @@ -1584,7 +1585,6 @@ tsi108_init_one(struct platform_device * data-mii_if.phy_id = einfo-phy; data-mii_if.phy_id_mask = 0x1f; data-mii_if.reg_num_mask = 0x1f; - data-mii_if.supports_gmii = mii_check_gmii_support(data-mii_if); data-phy = einfo-phy; data-phy_type = einfo-phy_type; --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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 0/5] Tsi108_eth: set of driver fix-ups
This is set of small fixes for Tsi108 Ethernet driver. Based on kernel version 2.6.24 --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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 3/5] Tsi108_eth: remove not needed code
Code clean-up for tsi108_eth network driver. This patch removes not needed dummy read and the corresponding comment. The PHY logic requires two reads from the status register to get current link status. This is done correctly inside mii_check_media(). Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-02-06 15:47:35.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 15:54:14.0 -0500 @@ -297,18 +297,11 @@ static void tsi108_check_phy(struct net_ u32 speed; unsigned long flags; - /* Do a dummy read, as for some reason the first read -* after a link becomes up returns link down, even if -* it's been a while since the link came up. -*/ - spin_lock_irqsave(phy_lock, flags); if (!data-phy_ok) goto out; - tsi108_read_mii(data, MII_BMSR); - duplex = mii_check_media(data-mii_if, netif_msg_link(data), data-init_media); data-init_media = 0; --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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 4/5] Tsi108_eth: fix link recovery after disconnect
Bug fix for tsi108_eth network driver. This patch fixes a problem with link recovery after connection was lost. Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-02-06 16:16:00.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 16:57:41.0 -0500 @@ -338,22 +338,21 @@ static void tsi108_check_phy(struct net_ TSI_WRITE(TSI108_MAC_CFG2, mac_cfg2_reg); TSI_WRITE(TSI108_EC_PORTCTRL, portctrl_reg); + } - if (data-link_up == 0) { - /* The manual says it can take 3-4 usecs for the speed change -* to take effect. -*/ - udelay(5); - - spin_lock(data-txlock); - if (is_valid_ether_addr(dev-dev_addr) data-txfree) - netif_wake_queue(dev); + if (data-link_up == 0) { + /* The manual says it can take 3-4 usecs for the speed change +* to take effect. +*/ + udelay(5); - data-link_up = 1; - spin_unlock(data-txlock); - } - } + spin_lock(data-txlock); + if (is_valid_ether_addr(dev-dev_addr) data-txfree) + netif_wake_queue(dev); + data-link_up = 1; + spin_unlock(data-txlock); + } } else { if (data-link_up == 1) { netif_stop_queue(dev); @@ -1267,12 +1266,11 @@ static void tsi108_init_phy(struct net_d * PHY_STAT register before the link up status bit is set. */ - data-link_up = 1; + data-link_up = 0; while (!((phyval = tsi108_read_mii(data, MII_BMSR)) BMSR_LSTATUS)) { if (i++ (MII_READ_DELAY / 10)) { - data-link_up = 0; break; } spin_unlock_irqrestore(phy_lock, flags); --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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 5/5] Tsi108_eth: Add ethtool support
Add ethtool support to tsi108_eth network driver. Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-02-06 17:10:53.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 18:09:43.0 -0500 @@ -36,6 +36,7 @@ #include linux/net.h #include linux/netdevice.h #include linux/etherdevice.h +#include linux/ethtool.h #include linux/skbuff.h #include linux/slab.h #include linux/spinlock.h @@ -1519,12 +1520,46 @@ static void tsi108_init_mac(struct net_d TSI_WRITE(TSI108_EC_INTMASK, ~0); } +static int tsi108_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct tsi108_prv_data *data = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(data-txlock, flags); + rc = mii_ethtool_gset(data-mii_if, cmd); + spin_unlock_irqrestore(data-txlock, flags); + + return rc; +} + +static int tsi108_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct tsi108_prv_data *data = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(data-txlock, flags); + rc = mii_ethtool_sset(data-mii_if, cmd); + spin_unlock_irqrestore(data-txlock, flags); + + return rc; +} + static int tsi108_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct tsi108_prv_data *data = netdev_priv(dev); + if (!netif_running(dev)) + return -EINVAL; return generic_mii_ioctl(data-mii_if, if_mii(rq), cmd, NULL); } +static const struct ethtool_ops tsi108_ethtool_ops = { + .get_link = ethtool_op_get_link, + .get_settings = tsi108_get_settings, + .set_settings = tsi108_set_settings, +}; + static int tsi108_init_one(struct platform_device *pdev) { @@ -1589,6 +1624,7 @@ tsi108_init_one(struct platform_device * dev-get_stats = tsi108_get_stats; netif_napi_add(dev, data-napi, tsi108_poll, 64); dev-do_ioctl = tsi108_do_ioctl; + dev-ethtool_ops = tsi108_ethtool_ops; /* Apparently, the Linux networking code won't use scatter-gather * if the hardware doesn't do checksums. However, it's faster --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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 1/5] Tsi108_eth: add missing linking to driver data
Bug fix for tsi108_eth network driver. This patch adds missing linking to driver data. Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-01-24 17:58:37.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 14:30:04.0 -0500 @@ -1629,6 +1629,7 @@ tsi108_init_one(struct platform_device * goto register_fail; } + platform_set_drvdata(pdev, dev); printk(KERN_INFO %s: Tsi108 Gigabit Ethernet, MAC: %s\n, dev-name, print_mac(mac, dev-dev_addr)); #ifdef DEBUG --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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/5] Tsi108_eth: fix detection of 1000Mb mode
Bug fix for tsi108_eth network driver. This patch fixes a problem with detection of 1000Mb speed. Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -pNur linux-2.6.24/drivers/net/tsi108_eth.c linux-2.6.24-fix/drivers/net/tsi108_eth.c --- linux-2.6.24/drivers/net/tsi108_eth.c 2008-02-06 15:09:19.0 -0500 +++ linux-2.6.24-fix/drivers/net/tsi108_eth.c 2008-02-06 15:34:12.0 -0500 @@ -1287,6 +1287,7 @@ static void tsi108_init_phy(struct net_d spin_lock_irqsave(phy_lock, flags); } + data-mii_if.supports_gmii = mii_check_gmii_support(data-mii_if); printk(KERN_DEBUG PHY_STAT reg contains %08x\n, phyval); data-phy_ok = 1; data-init_media = 1; @@ -1584,7 +1585,6 @@ tsi108_init_one(struct platform_device * data-mii_if.phy_id = einfo-phy; data-mii_if.phy_id_mask = 0x1f; data-mii_if.reg_num_mask = 0x1f; - data-mii_if.supports_gmii = mii_check_gmii_support(data-mii_if); data-phy = einfo-phy; data-phy_type = einfo-phy_type; --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message from your systems. Thank you. -- 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] Fix Tsi108 ethernet driver performance
From: Alexandre Bounine [EMAIL PROTECTED] This patch improves performance of the Tsi108 Ethernet driver by changing interrupt handling for frame receive path. It reduces number of interrupts generated for received frames and therefore lowers CPU utilization by the device driver. Signed-off-by: Alexandre Bounine [EMAIL PROTECTED] --- diff -Nurp linux-2.6.22-hpc2/drivers/net/tsi108_eth.c linux-2.6.22-tun/drivers/net/tsi108_eth.c --- linux-2.6.22-hpc2/drivers/net/tsi108_eth.c 2007-07-08 19:32:17.0 -0400 +++ linux-2.6.22-tun/drivers/net/tsi108_eth.c 2007-07-12 16:55:50.0 -0400 @@ -58,6 +58,7 @@ #define MII_READ_DELAY 1 /* max link wait time in msec */ #define TSI108_RXRING_LEN 256 +#define TSI108_RX_INT_FREQ32 /* NOTE: The driver currently does not support receiving packets * larger than the buffer size, so don't decrease this (unless you @@ -69,8 +70,10 @@ #define TSI108_TX_INT_FREQ64 -/* Check the phy status every half a second. */ -#define CHECK_PHY_INTERVAL (HZ/2) +/* Timer interval to check the RX queue status */ +#define CHECK_RX_INTERVAL (HZ/50) +/* Timer interval to check the PHY status */ +#define CHECK_PHY_INTERVAL (CHECK_RX_INTERVAL * 10) static int tsi108_init_one(struct platform_device *pdev); static int tsi108_ether_remove(struct platform_device *pdev); @@ -104,6 +107,7 @@ struct tsi108_prv_data { unsigned int txfree; unsigned int phy_ok;/* The PHY is currently powered on. */ + unsigned int phy_chk_count; /* PHY status (duplex is 1 for half, 2 for full, * so that the default 0 indicates that neither has @@ -823,7 +827,10 @@ static int tsi108_refill_rx(struct net_d */ data-rxring[rx].blen = TSI108_RX_SKB_SIZE; - data-rxring[rx].misc = TSI108_RX_OWN | TSI108_RX_INT; + if (rx % TSI108_RX_INT_FREQ) + data-rxring[rx].misc = TSI108_RX_OWN; + else + data-rxring[rx].misc = TSI108_RX_OWN | TSI108_RX_INT; data-rxhead = (data-rxhead + 1) % TSI108_RXRING_LEN; data-rxfree++; @@ -973,24 +980,22 @@ static void tsi108_rx_int(struct net_dev } } -/* If the RX ring has run out of memory, try periodically - * to allocate some more, as otherwise poll would never - * get called (apart from the initial end-of-queue condition). - * - * This is called once per second (by default) from the thread. +/* tsi108_check_rxring() is used to periodically check if the RX ring has + * pending frames that have not been reported by RX interrupt (due to interrupt + * moderation). It is called with CHECK_RX_INTERVAL timer interval. */ static void tsi108_check_rxring(struct net_device *dev) { struct tsi108_prv_data *data = netdev_priv(dev); + unsigned int rx = data-rxtail; - /* A poll is scheduled, as opposed to caling tsi108_refill_rx -* directly, so as to keep the receive path single-threaded -* (and thus not needing a lock). -*/ - - if (netif_running(dev) data-rxfree TSI108_RXRING_LEN / 4) + /* Schedule a poll (if required) */ + if (netif_running(dev) + 0 == (data-rxring[rx].misc TSI108_RX_OWN)) { + data-rxpending = 1; tsi108_rx_int(dev); + } } static void tsi108_tx_int(struct net_device *dev) @@ -1295,6 +1300,7 @@ static void tsi108_init_phy(struct net_d printk(KERN_DEBUG PHY_STAT reg contains %08x\n, phyval); data-phy_ok = 1; + data-phy_chk_count = 0; data-init_media = 1; spin_unlock_irqrestore(phy_lock, flags); } @@ -1664,9 +1670,12 @@ static void tsi108_timed_checker(unsigne struct net_device *dev = (struct net_device *)dev_ptr; struct tsi108_prv_data *data = netdev_priv(dev); - tsi108_check_phy(dev); + /* We assume that RX queue is checked more often than PHY status */ + if (data-phy_chk_count++ == 0) + tsi108_check_phy(dev); tsi108_check_rxring(dev); - mod_timer(data-timer, jiffies + CHECK_PHY_INTERVAL); + data-phy_chk_count %= (CHECK_PHY_INTERVAL/CHECK_RX_INTERVAL); + mod_timer(data-timer, jiffies + CHECK_RX_INTERVAL); } static int tsi108_ether_init(void) --- Important Notice: This message is intended for the use of the individual to whom it is addressed and may contain information which is privileged, confidential and/or exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or is not the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone or return e-mail and delete the original message