Commit 194dcdba authored by David S. Miller's avatar David S. Miller

Merge branch 'davem-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

parents 19b8cba2 bdb59f94
...@@ -223,6 +223,8 @@ static int gfar_mdio_of_init_one(struct device_node *np) ...@@ -223,6 +223,8 @@ static int gfar_mdio_of_init_one(struct device_node *np)
if (ret) if (ret)
return ret; return ret;
/* The gianfar device will try to use the same ID created below to find
* this bus, to coordinate register access (since they share). */
mdio_dev = platform_device_register_simple("fsl-gianfar_mdio", mdio_dev = platform_device_register_simple("fsl-gianfar_mdio",
res.start&0xfffff, &res, 1); res.start&0xfffff, &res, 1);
if (IS_ERR(mdio_dev)) if (IS_ERR(mdio_dev))
...@@ -394,6 +396,30 @@ static int __init gfar_of_init(void) ...@@ -394,6 +396,30 @@ static int __init gfar_of_init(void)
of_node_put(mdio); of_node_put(mdio);
} }
/* Get MDIO bus controlled by this eTSEC, if any. Normally only
* eTSEC 1 will control an MDIO bus, not necessarily the same
* bus that its PHY is on ('mdio' above), so we can't just use
* that. What we do is look for a gianfar mdio device that has
* overlapping registers with this device. That's really the
* whole point, to find the device sharing our registers to
* coordinate access with it.
*/
for_each_compatible_node(mdio, NULL, "fsl,gianfar-mdio") {
if (of_address_to_resource(mdio, 0, &res))
continue;
if (res.start >= r[0].start && res.end <= r[0].end) {
/* Get the ID the mdio bus platform device was
* registered with. gfar_data.bus_id is
* different because it's for finding a PHY,
* while this is for finding a MII bus.
*/
gfar_data.mdio_bus = res.start&0xfffff;
of_node_put(mdio);
break;
}
}
ret = ret =
platform_device_add_data(gfar_dev, &gfar_data, platform_device_add_data(gfar_dev, &gfar_data,
sizeof(struct sizeof(struct
......
...@@ -644,10 +644,6 @@ This function frees the transmiter and receiver descriptor rings. ...@@ -644,10 +644,6 @@ This function frees the transmiter and receiver descriptor rings.
*/ */
static void amd8111e_free_ring(struct amd8111e_priv* lp) static void amd8111e_free_ring(struct amd8111e_priv* lp)
{ {
/* Free transmit and receive skbs */
amd8111e_free_skbs(lp->amd8111e_net_dev);
/* Free transmit and receive descriptor rings */ /* Free transmit and receive descriptor rings */
if(lp->rx_ring){ if(lp->rx_ring){
pci_free_consistent(lp->pci_dev, pci_free_consistent(lp->pci_dev,
...@@ -1233,7 +1229,9 @@ static int amd8111e_close(struct net_device * dev) ...@@ -1233,7 +1229,9 @@ static int amd8111e_close(struct net_device * dev)
amd8111e_disable_interrupt(lp); amd8111e_disable_interrupt(lp);
amd8111e_stop_chip(lp); amd8111e_stop_chip(lp);
amd8111e_free_ring(lp);
/* Free transmit and receive skbs */
amd8111e_free_skbs(lp->amd8111e_net_dev);
netif_carrier_off(lp->amd8111e_net_dev); netif_carrier_off(lp->amd8111e_net_dev);
...@@ -1243,6 +1241,7 @@ static int amd8111e_close(struct net_device * dev) ...@@ -1243,6 +1241,7 @@ static int amd8111e_close(struct net_device * dev)
spin_unlock_irq(&lp->lock); spin_unlock_irq(&lp->lock);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
amd8111e_free_ring(lp);
/* Update the statistics before closing */ /* Update the statistics before closing */
amd8111e_get_stats(dev); amd8111e_get_stats(dev);
......
...@@ -1080,7 +1080,8 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add ...@@ -1080,7 +1080,8 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
init_timer(&lp->check_timer); init_timer(&lp->check_timer);
lp->check_timer.data = (unsigned long)dev; lp->check_timer.data = (unsigned long)dev;
lp->check_timer.function = at91ether_check_link; lp->check_timer.function = at91ether_check_link;
} } else if (lp->board_data.phy_irq_pin >= 32)
gpio_request(lp->board_data.phy_irq_pin, "ethernet_phy");
/* Display ethernet banner */ /* Display ethernet banner */
printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%s)\n", printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%s)\n",
...@@ -1167,6 +1168,9 @@ static int __devexit at91ether_remove(struct platform_device *pdev) ...@@ -1167,6 +1168,9 @@ static int __devexit at91ether_remove(struct platform_device *pdev)
struct net_device *dev = platform_get_drvdata(pdev); struct net_device *dev = platform_get_drvdata(pdev);
struct at91_private *lp = netdev_priv(dev); struct at91_private *lp = netdev_priv(dev);
if (lp->board_data.phy_irq_pin >= 32)
gpio_free(lp->board_data.phy_irq_pin);
unregister_netdev(dev); unregister_netdev(dev);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
......
...@@ -2310,7 +2310,8 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count, ...@@ -2310,7 +2310,8 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
if (tpd != ptpd) if (tpd != ptpd)
memcpy(tpd, ptpd, sizeof(struct tx_packet_desc)); memcpy(tpd, ptpd, sizeof(struct tx_packet_desc));
tpd->buffer_addr = cpu_to_le64(buffer_info->dma); tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
tpd->word2 = (cpu_to_le16(buffer_info->length) & tpd->word2 &= ~(TPD_BUFLEN_MASK << TPD_BUFLEN_SHIFT);
tpd->word2 |= (cpu_to_le16(buffer_info->length) &
TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT; TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT;
/* /*
...@@ -2409,8 +2410,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -2409,8 +2410,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
((vlan_tag >> 9) & 0x8); ((vlan_tag >> 9) & 0x8);
ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT; ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
ptpd->word3 |= (vlan_tag & TPD_VL_TAGGED_MASK) << ptpd->word2 |= (vlan_tag & TPD_VLANTAG_MASK) <<
TPD_VL_TAGGED_SHIFT; TPD_VLANTAG_SHIFT;
} }
tso = atl1_tso(adapter, skb, ptpd); tso = atl1_tso(adapter, skb, ptpd);
......
...@@ -504,7 +504,7 @@ struct rx_free_desc { ...@@ -504,7 +504,7 @@ struct rx_free_desc {
#define TPD_PKTNT_MASK 0x0001 #define TPD_PKTNT_MASK 0x0001
#define TPD_PKTINT_SHIFT 15 #define TPD_PKTINT_SHIFT 15
#define TPD_VLANTAG_MASK 0xFFFF #define TPD_VLANTAG_MASK 0xFFFF
#define TPD_VLAN_SHIFT 16 #define TPD_VLANTAG_SHIFT 16
/* tpd word 3 bits 0:13 */ /* tpd word 3 bits 0:13 */
#define TPD_EOP_MASK 0x0001 #define TPD_EOP_MASK 0x0001
......
...@@ -169,12 +169,15 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_ ...@@ -169,12 +169,15 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_
/* clear slave from tx_hashtbl */ /* clear slave from tx_hashtbl */
tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl; tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;
/* skip this if we've already freed the tx hash table */
if (tx_hash_table) {
index = SLAVE_TLB_INFO(slave).head; index = SLAVE_TLB_INFO(slave).head;
while (index != TLB_NULL_INDEX) { while (index != TLB_NULL_INDEX) {
u32 next_index = tx_hash_table[index].next; u32 next_index = tx_hash_table[index].next;
tlb_init_table_entry(&tx_hash_table[index], save_load); tlb_init_table_entry(&tx_hash_table[index], save_load);
index = next_index; index = next_index;
} }
}
tlb_init_slave(slave); tlb_init_slave(slave);
......
...@@ -1979,6 +1979,20 @@ void bond_destroy(struct bonding *bond) ...@@ -1979,6 +1979,20 @@ void bond_destroy(struct bonding *bond)
unregister_netdevice(bond->dev); unregister_netdevice(bond->dev);
} }
static void bond_destructor(struct net_device *bond_dev)
{
struct bonding *bond = bond_dev->priv;
if (bond->wq)
destroy_workqueue(bond->wq);
netif_addr_lock_bh(bond_dev);
bond_mc_list_destroy(bond);
netif_addr_unlock_bh(bond_dev);
free_netdev(bond_dev);
}
/* /*
* First release a slave and than destroy the bond if no more slaves iare left. * First release a slave and than destroy the bond if no more slaves iare left.
* Must be under rtnl_lock when this function is called. * Must be under rtnl_lock when this function is called.
...@@ -2376,6 +2390,9 @@ static void bond_miimon_commit(struct bonding *bond) ...@@ -2376,6 +2390,9 @@ static void bond_miimon_commit(struct bonding *bond)
continue; continue;
case BOND_LINK_DOWN: case BOND_LINK_DOWN:
if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
slave->link = BOND_LINK_DOWN; slave->link = BOND_LINK_DOWN;
if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || if (bond->params.mode == BOND_MODE_ACTIVEBACKUP ||
...@@ -4550,7 +4567,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) ...@@ -4550,7 +4567,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
bond_set_mode_ops(bond, bond->params.mode); bond_set_mode_ops(bond, bond->params.mode);
bond_dev->destructor = free_netdev; bond_dev->destructor = bond_destructor;
/* Initialize the device options */ /* Initialize the device options */
bond_dev->tx_queue_len = 0; bond_dev->tx_queue_len = 0;
...@@ -4589,20 +4606,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) ...@@ -4589,20 +4606,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
return 0; return 0;
} }
/* De-initialize device specific data.
* Caller must hold rtnl_lock.
*/
static void bond_deinit(struct net_device *bond_dev)
{
struct bonding *bond = bond_dev->priv;
list_del(&bond->bond_list);
#ifdef CONFIG_PROC_FS
bond_remove_proc_entry(bond);
#endif
}
static void bond_work_cancel_all(struct bonding *bond) static void bond_work_cancel_all(struct bonding *bond)
{ {
write_lock_bh(&bond->lock); write_lock_bh(&bond->lock);
...@@ -4624,6 +4627,22 @@ static void bond_work_cancel_all(struct bonding *bond) ...@@ -4624,6 +4627,22 @@ static void bond_work_cancel_all(struct bonding *bond)
cancel_delayed_work(&bond->ad_work); cancel_delayed_work(&bond->ad_work);
} }
/* De-initialize device specific data.
* Caller must hold rtnl_lock.
*/
static void bond_deinit(struct net_device *bond_dev)
{
struct bonding *bond = bond_dev->priv;
list_del(&bond->bond_list);
bond_work_cancel_all(bond);
#ifdef CONFIG_PROC_FS
bond_remove_proc_entry(bond);
#endif
}
/* Unregister and free all bond devices. /* Unregister and free all bond devices.
* Caller must hold rtnl_lock. * Caller must hold rtnl_lock.
*/ */
...@@ -4635,9 +4654,6 @@ static void bond_free_all(void) ...@@ -4635,9 +4654,6 @@ static void bond_free_all(void)
struct net_device *bond_dev = bond->dev; struct net_device *bond_dev = bond->dev;
bond_work_cancel_all(bond); bond_work_cancel_all(bond);
netif_addr_lock_bh(bond_dev);
bond_mc_list_destroy(bond);
netif_addr_unlock_bh(bond_dev);
/* Release the bonded slaves */ /* Release the bonded slaves */
bond_release_all(bond_dev); bond_release_all(bond_dev);
bond_destroy(bond); bond_destroy(bond);
......
...@@ -586,6 +586,18 @@ static void gfar_configure_serdes(struct net_device *dev) ...@@ -586,6 +586,18 @@ static void gfar_configure_serdes(struct net_device *dev)
struct gfar_mii __iomem *regs = struct gfar_mii __iomem *regs =
(void __iomem *)&priv->regs->gfar_mii_regs; (void __iomem *)&priv->regs->gfar_mii_regs;
int tbipa = gfar_read(&priv->regs->tbipa); int tbipa = gfar_read(&priv->regs->tbipa);
struct mii_bus *bus = gfar_get_miibus(priv);
if (bus)
mutex_lock(&bus->mdio_lock);
/* If the link is already up, we must already be ok, and don't need to
* configure and reset the TBI<->SerDes link. Maybe U-Boot configured
* everything for us? Resetting it takes the link down and requires
* several seconds for it to come back.
*/
if (gfar_local_mdio_read(regs, tbipa, MII_BMSR) & BMSR_LSTATUS)
goto done;
/* Single clk mode, mii mode off(for serdes communication) */ /* Single clk mode, mii mode off(for serdes communication) */
gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT);
...@@ -596,6 +608,10 @@ static void gfar_configure_serdes(struct net_device *dev) ...@@ -596,6 +608,10 @@ static void gfar_configure_serdes(struct net_device *dev)
gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE |
BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000);
done:
if (bus)
mutex_unlock(&bus->mdio_lock);
} }
static void init_registers(struct net_device *dev) static void init_registers(struct net_device *dev)
......
...@@ -269,6 +269,27 @@ static struct device_driver gianfar_mdio_driver = { ...@@ -269,6 +269,27 @@ static struct device_driver gianfar_mdio_driver = {
.remove = gfar_mdio_remove, .remove = gfar_mdio_remove,
}; };
static int match_mdio_bus(struct device *dev, void *data)
{
const struct gfar_private *priv = data;
const struct platform_device *pdev = to_platform_device(dev);
return !strcmp(pdev->name, gianfar_mdio_driver.name) &&
pdev->id == priv->einfo->mdio_bus;
}
/* Given a gfar_priv structure, find the mii_bus controlled by this device (not
* necessarily the same as the bus the gfar's PHY is on), if one exists.
* Normally only the first gianfar controls a mii_bus. */
struct mii_bus *gfar_get_miibus(const struct gfar_private *priv)
{
/*const*/ struct device *d;
d = bus_find_device(gianfar_mdio_driver.bus, NULL, (void *)priv,
match_mdio_bus);
return d ? dev_get_drvdata(d) : NULL;
}
int __init gfar_mdio_init(void) int __init gfar_mdio_init(void)
{ {
return driver_register(&gianfar_mdio_driver); return driver_register(&gianfar_mdio_driver);
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#ifndef __GIANFAR_MII_H #ifndef __GIANFAR_MII_H
#define __GIANFAR_MII_H #define __GIANFAR_MII_H
struct gfar_private; /* forward ref */
#define MIIMIND_BUSY 0x00000001 #define MIIMIND_BUSY 0x00000001
#define MIIMIND_NOTVALID 0x00000004 #define MIIMIND_NOTVALID 0x00000004
...@@ -44,6 +46,7 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); ...@@ -44,6 +46,7 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
int regnum, u16 value); int regnum, u16 value);
int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
struct mii_bus *gfar_get_miibus(const struct gfar_private *priv);
int __init gfar_mdio_init(void); int __init gfar_mdio_init(void);
void gfar_mdio_exit(void); void gfar_mdio_exit(void);
#endif /* GIANFAR_PHY_H */ #endif /* GIANFAR_PHY_H */
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
#include "myri10ge_mcp.h" #include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h" #include "myri10ge_mcp_gen_header.h"
#define MYRI10GE_VERSION_STR "1.4.3-1.371" #define MYRI10GE_VERSION_STR "1.4.3-1.375"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com"); MODULE_AUTHOR("Maintainer: help@myri.com");
...@@ -1393,6 +1393,7 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index) ...@@ -1393,6 +1393,7 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index)
if (tx->req == tx->done) { if (tx->req == tx->done) {
tx->queue_active = 0; tx->queue_active = 0;
put_be32(htonl(1), tx->send_stop); put_be32(htonl(1), tx->send_stop);
mmiowb();
} }
__netif_tx_unlock(dev_queue); __netif_tx_unlock(dev_queue);
} }
...@@ -2864,6 +2865,7 @@ again: ...@@ -2864,6 +2865,7 @@ again:
if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) { if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) {
tx->queue_active = 1; tx->queue_active = 1;
put_be32(htonl(1), tx->send_go); put_be32(htonl(1), tx->send_go);
mmiowb();
} }
tx->pkt_start++; tx->pkt_start++;
if ((avail - count) < MXGEFW_MAX_SEND_DESC) { if ((avail - count) < MXGEFW_MAX_SEND_DESC) {
......
...@@ -2060,7 +2060,6 @@ static int smc_request_attrib(struct platform_device *pdev, ...@@ -2060,7 +2060,6 @@ static int smc_request_attrib(struct platform_device *pdev,
struct net_device *ndev) struct net_device *ndev)
{ {
struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
struct smc_local *lp = netdev_priv(ndev);
if (!res) if (!res)
return 0; return 0;
...@@ -2075,7 +2074,6 @@ static void smc_release_attrib(struct platform_device *pdev, ...@@ -2075,7 +2074,6 @@ static void smc_release_attrib(struct platform_device *pdev,
struct net_device *ndev) struct net_device *ndev)
{ {
struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
struct smc_local *lp = netdev_priv(ndev);
if (res) if (res)
release_mem_region(res->start, ATTRIB_SIZE); release_mem_region(res->start, ATTRIB_SIZE);
......
...@@ -49,7 +49,8 @@ struct gianfar_platform_data { ...@@ -49,7 +49,8 @@ struct gianfar_platform_data {
u32 device_flags; u32 device_flags;
/* board specific information */ /* board specific information */
u32 board_flags; u32 board_flags;
char bus_id[MII_BUS_ID_SIZE]; int mdio_bus; /* Bus controlled by us */
char bus_id[MII_BUS_ID_SIZE]; /* Bus PHY is on */
u32 phy_id; u32 phy_id;
u8 mac_addr[6]; u8 mac_addr[6];
phy_interface_t interface; phy_interface_t interface;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment