diff options
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r-- | drivers/net/ucc_geth.c | 75 |
1 files changed, 20 insertions, 55 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 44f8392da117..f18017dc0255 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -27,6 +27,7 @@ #include <linux/mii.h> #include <linux/phy.h> #include <linux/workqueue.h> +#include <linux/of_mdio.h> #include <linux/of_platform.h> #include <asm/uaccess.h> @@ -1543,12 +1544,14 @@ static int init_phy(struct net_device *dev) priv->oldspeed = 0; priv->oldduplex = -1; - phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0, - priv->phy_interface); + if (!ug_info->phy_node) + return 0; - if (IS_ERR(phydev)) { + phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0, + priv->phy_interface); + if (!phydev) { printk("%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(phydev); + return -ENODEV; } phydev->supported &= (ADVERTISED_10baseT_Half | @@ -3217,7 +3220,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) dev->stats.tx_packets++; /* Free the sk buffer associated with this TxBD */ - dev_kfree_skb_irq(ugeth-> + dev_kfree_skb(ugeth-> tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]); ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL; ugeth->skb_dirtytx[txQ] = @@ -3251,9 +3254,15 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget) for (i = 0; i < ug_info->numQueuesRx; i++) howmany += ucc_geth_rx(ugeth, i, budget - howmany); + /* Tx event processing */ + spin_lock(&ugeth->lock); + for (i = 0; i < ug_info->numQueuesTx; i++) + ucc_geth_tx(ugeth->ndev, i); + spin_unlock(&ugeth->lock); + if (howmany < budget) { napi_complete(napi); - setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS); + setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS); } return howmany; @@ -3267,8 +3276,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) struct ucc_geth_info *ug_info; register u32 ucce; register u32 uccm; - register u32 tx_mask; - u8 i; ugeth_vdbg("%s: IN", __func__); @@ -3282,27 +3289,14 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) out_be32(uccf->p_ucce, ucce); /* check for receive events that require processing */ - if (ucce & UCCE_RX_EVENTS) { + if (ucce & (UCCE_RX_EVENTS | UCCE_TX_EVENTS)) { if (napi_schedule_prep(&ugeth->napi)) { - uccm &= ~UCCE_RX_EVENTS; + uccm &= ~(UCCE_RX_EVENTS | UCCE_TX_EVENTS); out_be32(uccf->p_uccm, uccm); __napi_schedule(&ugeth->napi); } } - /* Tx event processing */ - if (ucce & UCCE_TX_EVENTS) { - spin_lock(&ugeth->lock); - tx_mask = UCC_GETH_UCCE_TXB0; - for (i = 0; i < ug_info->numQueuesTx; i++) { - if (ucce & tx_mask) - ucc_geth_tx(dev, i); - ucce &= ~tx_mask; - tx_mask <<= 1; - } - spin_unlock(&ugeth->lock); - } - /* Errors and other events */ if (ucce & UCCE_OTHER) { if (ucce & UCC_GETH_UCCE_BSY) @@ -3520,14 +3514,12 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma { struct device *device = &ofdev->dev; struct device_node *np = ofdev->node; - struct device_node *mdio; struct net_device *dev = NULL; struct ucc_geth_private *ugeth = NULL; struct ucc_geth_info *ug_info; struct resource res; struct device_node *phy; int err, ucc_num, max_speed = 0; - const phandle *ph; const u32 *fixed_link; const unsigned int *prop; const char *sprop; @@ -3627,40 +3619,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); fixed_link = of_get_property(np, "fixed-link", NULL); if (fixed_link) { - snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id), - PHY_ID_FMT, "0", fixed_link[0]); phy = NULL; } else { - char bus_name[MII_BUS_ID_SIZE]; - - ph = of_get_property(np, "phy-handle", NULL); - phy = of_find_node_by_phandle(*ph); - + phy = of_parse_phandle(np, "phy-handle", 0); if (phy == NULL) return -ENODEV; - - /* set the PHY address */ - prop = of_get_property(phy, "reg", NULL); - if (prop == NULL) - return -1; - - /* Set the bus id */ - mdio = of_get_parent(phy); - - if (mdio == NULL) - return -ENODEV; - - err = of_address_to_resource(mdio, 0, &res); - - if (err) { - of_node_put(mdio); - return err; - } - fsl_pq_mdio_bus_name(bus_name, mdio); - of_node_put(mdio); - snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id), - "%s:%02x", bus_name, *prop); } + ug_info->phy_node = phy; /* get the phy interface type, or default to MII */ prop = of_get_property(np, "phy-connection-type", NULL); @@ -3735,7 +3700,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma dev->netdev_ops = &ucc_geth_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); - netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT); + netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64); dev->mtu = 1500; ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); |