aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ucc_geth.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-15 12:40:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-15 12:40:05 -0400
commit2ed0e21b30b53d3a94e204196e523e6c8f732b56 (patch)
treede2635426477d86338a9469ce09ba0626052288f /drivers/net/ucc_geth.c
parent0fa213310cd8fa7a51071cdcf130e26fa56e9549 (diff)
parent9cbc1cb8cd46ce1f7645b9de249b2ce8460129bb (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1244 commits) pkt_sched: Rename PSCHED_US2NS and PSCHED_NS2US ipv4: Fix fib_trie rebalancing Bluetooth: Fix issue with uninitialized nsh.type in DTL-1 driver Bluetooth: Fix Kconfig issue with RFKILL integration PIM-SM: namespace changes ipv4: update ARPD help text net: use a deferred timer in rt_check_expire ieee802154: fix kconfig bool/tristate muckup bonding: initialization rework bonding: use is_zero_ether_addr bonding: network device names are case sensative bonding: elminate bad refcount code bonding: fix style issues bonding: fix destructor bonding: remove bonding read/write semaphore bonding: initialize before registration bonding: bond_create always called with default parameters x_tables: Convert printk to pr_err netfilter: conntrack: optional reliable conntrack event delivery list_nulls: add hlist_nulls_add_head and hlist_nulls_del ...
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r--drivers/net/ucc_geth.c187
1 files changed, 130 insertions, 57 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 9dd16c9b1a10..e2f2e91cfdd2 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved. 2 * Copyright (C) 2006-2009 Freescale Semicondutor, Inc. All rights reserved.
3 * 3 *
4 * Author: Shlomi Gridish <gridish@freescale.com> 4 * Author: Shlomi Gridish <gridish@freescale.com>
5 * Li Yang <leoli@freescale.com> 5 * Li Yang <leoli@freescale.com>
@@ -27,6 +27,7 @@
27#include <linux/mii.h> 27#include <linux/mii.h>
28#include <linux/phy.h> 28#include <linux/phy.h>
29#include <linux/workqueue.h> 29#include <linux/workqueue.h>
30#include <linux/of_mdio.h>
30#include <linux/of_platform.h> 31#include <linux/of_platform.h>
31 32
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
@@ -64,6 +65,8 @@
64 65
65static DEFINE_SPINLOCK(ugeth_lock); 66static DEFINE_SPINLOCK(ugeth_lock);
66 67
68static void uec_configure_serdes(struct net_device *dev);
69
67static struct { 70static struct {
68 u32 msg_enable; 71 u32 msg_enable;
69} debug = { -1 }; 72} debug = { -1 };
@@ -1409,6 +1412,9 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1409 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { 1412 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1410 upsmr |= UCC_GETH_UPSMR_TBIM; 1413 upsmr |= UCC_GETH_UPSMR_TBIM;
1411 } 1414 }
1415 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_SGMII))
1416 upsmr |= UCC_GETH_UPSMR_SGMM;
1417
1412 out_be32(&uf_regs->upsmr, upsmr); 1418 out_be32(&uf_regs->upsmr, upsmr);
1413 1419
1414 /* Disable autonegotiation in tbi mode, because by default it 1420 /* Disable autonegotiation in tbi mode, because by default it
@@ -1543,14 +1549,19 @@ static int init_phy(struct net_device *dev)
1543 priv->oldspeed = 0; 1549 priv->oldspeed = 0;
1544 priv->oldduplex = -1; 1550 priv->oldduplex = -1;
1545 1551
1546 phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0, 1552 if (!ug_info->phy_node)
1547 priv->phy_interface); 1553 return 0;
1548 1554
1549 if (IS_ERR(phydev)) { 1555 phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0,
1556 priv->phy_interface);
1557 if (!phydev) {
1550 printk("%s: Could not attach to PHY\n", dev->name); 1558 printk("%s: Could not attach to PHY\n", dev->name);
1551 return PTR_ERR(phydev); 1559 return -ENODEV;
1552 } 1560 }
1553 1561
1562 if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
1563 uec_configure_serdes(dev);
1564
1554 phydev->supported &= (ADVERTISED_10baseT_Half | 1565 phydev->supported &= (ADVERTISED_10baseT_Half |
1555 ADVERTISED_10baseT_Full | 1566 ADVERTISED_10baseT_Full |
1556 ADVERTISED_100baseT_Half | 1567 ADVERTISED_100baseT_Half |
@@ -1566,7 +1577,41 @@ static int init_phy(struct net_device *dev)
1566 return 0; 1577 return 0;
1567} 1578}
1568 1579
1580/* Initialize TBI PHY interface for communicating with the
1581 * SERDES lynx PHY on the chip. We communicate with this PHY
1582 * through the MDIO bus on each controller, treating it as a
1583 * "normal" PHY at the address found in the UTBIPA register. We assume
1584 * that the UTBIPA register is valid. Either the MDIO bus code will set
1585 * it to a value that doesn't conflict with other PHYs on the bus, or the
1586 * value doesn't matter, as there are no other PHYs on the bus.
1587 */
1588static void uec_configure_serdes(struct net_device *dev)
1589{
1590 struct ucc_geth_private *ugeth = netdev_priv(dev);
1591
1592 if (!ugeth->tbiphy) {
1593 printk(KERN_WARNING "SGMII mode requires that the device "
1594 "tree specify a tbi-handle\n");
1595 return;
1596 }
1597
1598 /*
1599 * If the link is already up, we must already be ok, and don't need to
1600 * configure and reset the TBI<->SerDes link. Maybe U-Boot configured
1601 * everything for us? Resetting it takes the link down and requires
1602 * several seconds for it to come back.
1603 */
1604 if (phy_read(ugeth->tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS)
1605 return;
1569 1606
1607 /* Single clk mode, mii mode off(for serdes communication) */
1608 phy_write(ugeth->tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS);
1609
1610 phy_write(ugeth->tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);
1611
1612 phy_write(ugeth->tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS);
1613
1614}
1570 1615
1571static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) 1616static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
1572{ 1617{
@@ -3225,7 +3270,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
3225 dev->stats.tx_packets++; 3270 dev->stats.tx_packets++;
3226 3271
3227 /* Free the sk buffer associated with this TxBD */ 3272 /* Free the sk buffer associated with this TxBD */
3228 dev_kfree_skb_irq(ugeth-> 3273 dev_kfree_skb(ugeth->
3229 tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]); 3274 tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]);
3230 ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL; 3275 ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
3231 ugeth->skb_dirtytx[txQ] = 3276 ugeth->skb_dirtytx[txQ] =
@@ -3259,9 +3304,15 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
3259 for (i = 0; i < ug_info->numQueuesRx; i++) 3304 for (i = 0; i < ug_info->numQueuesRx; i++)
3260 howmany += ucc_geth_rx(ugeth, i, budget - howmany); 3305 howmany += ucc_geth_rx(ugeth, i, budget - howmany);
3261 3306
3307 /* Tx event processing */
3308 spin_lock(&ugeth->lock);
3309 for (i = 0; i < ug_info->numQueuesTx; i++)
3310 ucc_geth_tx(ugeth->ndev, i);
3311 spin_unlock(&ugeth->lock);
3312
3262 if (howmany < budget) { 3313 if (howmany < budget) {
3263 napi_complete(napi); 3314 napi_complete(napi);
3264 setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS); 3315 setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS);
3265 } 3316 }
3266 3317
3267 return howmany; 3318 return howmany;
@@ -3275,8 +3326,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
3275 struct ucc_geth_info *ug_info; 3326 struct ucc_geth_info *ug_info;
3276 register u32 ucce; 3327 register u32 ucce;
3277 register u32 uccm; 3328 register u32 uccm;
3278 register u32 tx_mask;
3279 u8 i;
3280 3329
3281 ugeth_vdbg("%s: IN", __func__); 3330 ugeth_vdbg("%s: IN", __func__);
3282 3331
@@ -3290,27 +3339,14 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
3290 out_be32(uccf->p_ucce, ucce); 3339 out_be32(uccf->p_ucce, ucce);
3291 3340
3292 /* check for receive events that require processing */ 3341 /* check for receive events that require processing */
3293 if (ucce & UCCE_RX_EVENTS) { 3342 if (ucce & (UCCE_RX_EVENTS | UCCE_TX_EVENTS)) {
3294 if (napi_schedule_prep(&ugeth->napi)) { 3343 if (napi_schedule_prep(&ugeth->napi)) {
3295 uccm &= ~UCCE_RX_EVENTS; 3344 uccm &= ~(UCCE_RX_EVENTS | UCCE_TX_EVENTS);
3296 out_be32(uccf->p_uccm, uccm); 3345 out_be32(uccf->p_uccm, uccm);
3297 __napi_schedule(&ugeth->napi); 3346 __napi_schedule(&ugeth->napi);
3298 } 3347 }
3299 } 3348 }
3300 3349
3301 /* Tx event processing */
3302 if (ucce & UCCE_TX_EVENTS) {
3303 spin_lock(&ugeth->lock);
3304 tx_mask = UCC_GETH_UCCE_TXB0;
3305 for (i = 0; i < ug_info->numQueuesTx; i++) {
3306 if (ucce & tx_mask)
3307 ucc_geth_tx(dev, i);
3308 ucce &= ~tx_mask;
3309 tx_mask <<= 1;
3310 }
3311 spin_unlock(&ugeth->lock);
3312 }
3313
3314 /* Errors and other events */ 3350 /* Errors and other events */
3315 if (ucce & UCCE_OTHER) { 3351 if (ucce & UCCE_OTHER) {
3316 if (ucce & UCC_GETH_UCCE_BSY) 3352 if (ucce & UCC_GETH_UCCE_BSY)
@@ -3339,6 +3375,37 @@ static void ucc_netpoll(struct net_device *dev)
3339} 3375}
3340#endif /* CONFIG_NET_POLL_CONTROLLER */ 3376#endif /* CONFIG_NET_POLL_CONTROLLER */
3341 3377
3378static int ucc_geth_set_mac_addr(struct net_device *dev, void *p)
3379{
3380 struct ucc_geth_private *ugeth = netdev_priv(dev);
3381 struct sockaddr *addr = p;
3382
3383 if (!is_valid_ether_addr(addr->sa_data))
3384 return -EADDRNOTAVAIL;
3385
3386 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
3387
3388 /*
3389 * If device is not running, we will set mac addr register
3390 * when opening the device.
3391 */
3392 if (!netif_running(dev))
3393 return 0;
3394
3395 spin_lock_irq(&ugeth->lock);
3396 init_mac_station_addr_regs(dev->dev_addr[0],
3397 dev->dev_addr[1],
3398 dev->dev_addr[2],
3399 dev->dev_addr[3],
3400 dev->dev_addr[4],
3401 dev->dev_addr[5],
3402 &ugeth->ug_regs->macstnaddr1,
3403 &ugeth->ug_regs->macstnaddr2);
3404 spin_unlock_irq(&ugeth->lock);
3405
3406 return 0;
3407}
3408
3342/* Called when something needs to use the ethernet device */ 3409/* Called when something needs to use the ethernet device */
3343/* Returns 0 for success. */ 3410/* Returns 0 for success. */
3344static int ucc_geth_open(struct net_device *dev) 3411static int ucc_geth_open(struct net_device *dev)
@@ -3506,6 +3573,8 @@ static phy_interface_t to_phy_interface(const char *phy_connection_type)
3506 return PHY_INTERFACE_MODE_RGMII_RXID; 3573 return PHY_INTERFACE_MODE_RGMII_RXID;
3507 if (strcasecmp(phy_connection_type, "rtbi") == 0) 3574 if (strcasecmp(phy_connection_type, "rtbi") == 0)
3508 return PHY_INTERFACE_MODE_RTBI; 3575 return PHY_INTERFACE_MODE_RTBI;
3576 if (strcasecmp(phy_connection_type, "sgmii") == 0)
3577 return PHY_INTERFACE_MODE_SGMII;
3509 3578
3510 return PHY_INTERFACE_MODE_MII; 3579 return PHY_INTERFACE_MODE_MII;
3511} 3580}
@@ -3515,7 +3584,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = {
3515 .ndo_stop = ucc_geth_close, 3584 .ndo_stop = ucc_geth_close,
3516 .ndo_start_xmit = ucc_geth_start_xmit, 3585 .ndo_start_xmit = ucc_geth_start_xmit,
3517 .ndo_validate_addr = eth_validate_addr, 3586 .ndo_validate_addr = eth_validate_addr,
3518 .ndo_set_mac_address = eth_mac_addr, 3587 .ndo_set_mac_address = ucc_geth_set_mac_addr,
3519 .ndo_change_mtu = eth_change_mtu, 3588 .ndo_change_mtu = eth_change_mtu,
3520 .ndo_set_multicast_list = ucc_geth_set_multi, 3589 .ndo_set_multicast_list = ucc_geth_set_multi,
3521 .ndo_tx_timeout = ucc_geth_timeout, 3590 .ndo_tx_timeout = ucc_geth_timeout,
@@ -3528,14 +3597,12 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3528{ 3597{
3529 struct device *device = &ofdev->dev; 3598 struct device *device = &ofdev->dev;
3530 struct device_node *np = ofdev->node; 3599 struct device_node *np = ofdev->node;
3531 struct device_node *mdio;
3532 struct net_device *dev = NULL; 3600 struct net_device *dev = NULL;
3533 struct ucc_geth_private *ugeth = NULL; 3601 struct ucc_geth_private *ugeth = NULL;
3534 struct ucc_geth_info *ug_info; 3602 struct ucc_geth_info *ug_info;
3535 struct resource res; 3603 struct resource res;
3536 struct device_node *phy; 3604 struct device_node *phy;
3537 int err, ucc_num, max_speed = 0; 3605 int err, ucc_num, max_speed = 0;
3538 const phandle *ph;
3539 const u32 *fixed_link; 3606 const u32 *fixed_link;
3540 const unsigned int *prop; 3607 const unsigned int *prop;
3541 const char *sprop; 3608 const char *sprop;
@@ -3552,6 +3619,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3552 PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII, 3619 PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII,
3553 PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII, 3620 PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII,
3554 PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI, 3621 PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
3622 PHY_INTERFACE_MODE_SGMII,
3555 }; 3623 };
3556 3624
3557 ugeth_vdbg("%s: IN", __func__); 3625 ugeth_vdbg("%s: IN", __func__);
@@ -3635,40 +3703,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3635 ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); 3703 ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
3636 fixed_link = of_get_property(np, "fixed-link", NULL); 3704 fixed_link = of_get_property(np, "fixed-link", NULL);
3637 if (fixed_link) { 3705 if (fixed_link) {
3638 snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
3639 PHY_ID_FMT, "0", fixed_link[0]);
3640 phy = NULL; 3706 phy = NULL;
3641 } else { 3707 } else {
3642 char bus_name[MII_BUS_ID_SIZE]; 3708 phy = of_parse_phandle(np, "phy-handle", 0);
3643
3644 ph = of_get_property(np, "phy-handle", NULL);
3645 phy = of_find_node_by_phandle(*ph);
3646
3647 if (phy == NULL) 3709 if (phy == NULL)
3648 return -ENODEV; 3710 return -ENODEV;
3649
3650 /* set the PHY address */
3651 prop = of_get_property(phy, "reg", NULL);
3652 if (prop == NULL)
3653 return -1;
3654
3655 /* Set the bus id */
3656 mdio = of_get_parent(phy);
3657
3658 if (mdio == NULL)
3659 return -ENODEV;
3660
3661 err = of_address_to_resource(mdio, 0, &res);
3662
3663 if (err) {
3664 of_node_put(mdio);
3665 return err;
3666 }
3667 fsl_pq_mdio_bus_name(bus_name, mdio);
3668 of_node_put(mdio);
3669 snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
3670 "%s:%02x", bus_name, *prop);
3671 } 3711 }
3712 ug_info->phy_node = phy;
3672 3713
3673 /* get the phy interface type, or default to MII */ 3714 /* get the phy interface type, or default to MII */
3674 prop = of_get_property(np, "phy-connection-type", NULL); 3715 prop = of_get_property(np, "phy-connection-type", NULL);
@@ -3694,6 +3735,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3694 case PHY_INTERFACE_MODE_RGMII_TXID: 3735 case PHY_INTERFACE_MODE_RGMII_TXID:
3695 case PHY_INTERFACE_MODE_TBI: 3736 case PHY_INTERFACE_MODE_TBI:
3696 case PHY_INTERFACE_MODE_RTBI: 3737 case PHY_INTERFACE_MODE_RTBI:
3738 case PHY_INTERFACE_MODE_SGMII:
3697 max_speed = SPEED_1000; 3739 max_speed = SPEED_1000;
3698 break; 3740 break;
3699 default: 3741 default:
@@ -3751,7 +3793,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3751 dev->netdev_ops = &ucc_geth_netdev_ops; 3793 dev->netdev_ops = &ucc_geth_netdev_ops;
3752 dev->watchdog_timeo = TX_TIMEOUT; 3794 dev->watchdog_timeo = TX_TIMEOUT;
3753 INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); 3795 INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work);
3754 netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT); 3796 netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64);
3755 dev->mtu = 1500; 3797 dev->mtu = 1500;
3756 3798
3757 ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); 3799 ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
@@ -3776,6 +3818,37 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3776 ugeth->ndev = dev; 3818 ugeth->ndev = dev;
3777 ugeth->node = np; 3819 ugeth->node = np;
3778 3820
3821 /* Find the TBI PHY. If it's not there, we don't support SGMII */
3822 ph = of_get_property(np, "tbi-handle", NULL);
3823 if (ph) {
3824 struct device_node *tbi = of_find_node_by_phandle(*ph);
3825 struct of_device *ofdev;
3826 struct mii_bus *bus;
3827 const unsigned int *id;
3828
3829 if (!tbi)
3830 return 0;
3831
3832 mdio = of_get_parent(tbi);
3833 if (!mdio)
3834 return 0;
3835
3836 ofdev = of_find_device_by_node(mdio);
3837
3838 of_node_put(mdio);
3839
3840 id = of_get_property(tbi, "reg", NULL);
3841 if (!id)
3842 return 0;
3843 of_node_put(tbi);
3844
3845 bus = dev_get_drvdata(&ofdev->dev);
3846 if (!bus)
3847 return 0;
3848
3849 ugeth->tbiphy = bus->phy_map[*id];
3850 }
3851
3779 return 0; 3852 return 0;
3780} 3853}
3781 3854