diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/ucc_geth.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r-- | drivers/net/ucc_geth.c | 105 |
1 files changed, 57 insertions, 48 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 4469f2451a6f..1b0aef37e495 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/qe.h> | 37 | #include <asm/qe.h> |
38 | #include <asm/ucc.h> | 38 | #include <asm/ucc.h> |
39 | #include <asm/ucc_fast.h> | 39 | #include <asm/ucc_fast.h> |
40 | #include <asm/machdep.h> | ||
40 | 41 | ||
41 | #include "ucc_geth.h" | 42 | #include "ucc_geth.h" |
42 | #include "fsl_pq_mdio.h" | 43 | #include "fsl_pq_mdio.h" |
@@ -429,7 +430,7 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, | |||
429 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | 430 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); |
430 | 431 | ||
431 | /* Ethernet frames are defined in Little Endian mode, | 432 | /* Ethernet frames are defined in Little Endian mode, |
432 | therefor to insert */ | 433 | therefore to insert */ |
433 | /* the address to the hash (Big Endian mode), we reverse the bytes.*/ | 434 | /* the address to the hash (Big Endian mode), we reverse the bytes.*/ |
434 | 435 | ||
435 | set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr); | 436 | set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr); |
@@ -1306,8 +1307,8 @@ static int init_max_rx_buff_len(u16 max_rx_buf_len, | |||
1306 | u16 __iomem *mrblr_register) | 1307 | u16 __iomem *mrblr_register) |
1307 | { | 1308 | { |
1308 | /* max_rx_buf_len value must be a multiple of 128 */ | 1309 | /* max_rx_buf_len value must be a multiple of 128 */ |
1309 | if ((max_rx_buf_len == 0) | 1310 | if ((max_rx_buf_len == 0) || |
1310 | || (max_rx_buf_len % UCC_GETH_MRBLR_ALIGNMENT)) | 1311 | (max_rx_buf_len % UCC_GETH_MRBLR_ALIGNMENT)) |
1311 | return -EINVAL; | 1312 | return -EINVAL; |
1312 | 1313 | ||
1313 | out_be16(mrblr_register, max_rx_buf_len); | 1314 | out_be16(mrblr_register, max_rx_buf_len); |
@@ -1334,7 +1335,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) | |||
1334 | struct ucc_geth __iomem *ug_regs; | 1335 | struct ucc_geth __iomem *ug_regs; |
1335 | struct ucc_fast __iomem *uf_regs; | 1336 | struct ucc_fast __iomem *uf_regs; |
1336 | int ret_val; | 1337 | int ret_val; |
1337 | u32 upsmr, maccfg2, tbiBaseAddress; | 1338 | u32 upsmr, maccfg2; |
1338 | u16 value; | 1339 | u16 value; |
1339 | 1340 | ||
1340 | ugeth_vdbg("%s: IN", __func__); | 1341 | ugeth_vdbg("%s: IN", __func__); |
@@ -1389,14 +1390,20 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) | |||
1389 | /* Note that this depends on proper setting in utbipar register. */ | 1390 | /* Note that this depends on proper setting in utbipar register. */ |
1390 | if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) || | 1391 | if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) || |
1391 | (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { | 1392 | (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { |
1392 | tbiBaseAddress = in_be32(&ug_regs->utbipar); | 1393 | struct ucc_geth_info *ug_info = ugeth->ug_info; |
1393 | tbiBaseAddress &= UTBIPAR_PHY_ADDRESS_MASK; | 1394 | struct phy_device *tbiphy; |
1394 | tbiBaseAddress >>= UTBIPAR_PHY_ADDRESS_SHIFT; | 1395 | |
1395 | value = ugeth->phydev->bus->read(ugeth->phydev->bus, | 1396 | if (!ug_info->tbi_node) |
1396 | (u8) tbiBaseAddress, ENET_TBI_MII_CR); | 1397 | ugeth_warn("TBI mode requires that the device " |
1398 | "tree specify a tbi-handle\n"); | ||
1399 | |||
1400 | tbiphy = of_phy_find_device(ug_info->tbi_node); | ||
1401 | if (!tbiphy) | ||
1402 | ugeth_warn("Could not get TBI device\n"); | ||
1403 | |||
1404 | value = phy_read(tbiphy, ENET_TBI_MII_CR); | ||
1397 | value &= ~0x1000; /* Turn off autonegotiation */ | 1405 | value &= ~0x1000; /* Turn off autonegotiation */ |
1398 | ugeth->phydev->bus->write(ugeth->phydev->bus, | 1406 | phy_write(tbiphy, ENET_TBI_MII_CR, value); |
1399 | (u8) tbiBaseAddress, ENET_TBI_MII_CR, value); | ||
1400 | } | 1407 | } |
1401 | 1408 | ||
1402 | init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2); | 1409 | init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2); |
@@ -1563,7 +1570,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) | |||
1563 | 1570 | ||
1564 | static void ugeth_quiesce(struct ucc_geth_private *ugeth) | 1571 | static void ugeth_quiesce(struct ucc_geth_private *ugeth) |
1565 | { | 1572 | { |
1566 | /* Wait for and prevent any further xmits. */ | 1573 | /* Prevent any further xmits, plus detach the device. */ |
1574 | netif_device_detach(ugeth->ndev); | ||
1575 | |||
1576 | /* Wait for any current xmits to finish. */ | ||
1567 | netif_tx_disable(ugeth->ndev); | 1577 | netif_tx_disable(ugeth->ndev); |
1568 | 1578 | ||
1569 | /* Disable the interrupt to avoid NAPI rescheduling. */ | 1579 | /* Disable the interrupt to avoid NAPI rescheduling. */ |
@@ -1577,7 +1587,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) | |||
1577 | { | 1587 | { |
1578 | napi_enable(&ugeth->napi); | 1588 | napi_enable(&ugeth->napi); |
1579 | enable_irq(ugeth->ug_info->uf_info.irq); | 1589 | enable_irq(ugeth->ug_info->uf_info.irq); |
1580 | netif_tx_wake_all_queues(ugeth->ndev); | 1590 | netif_device_attach(ugeth->ndev); |
1581 | } | 1591 | } |
1582 | 1592 | ||
1583 | /* Called every time the controller might need to be made | 1593 | /* Called every time the controller might need to be made |
@@ -1648,25 +1658,28 @@ static void adjust_link(struct net_device *dev) | |||
1648 | ugeth->oldspeed = phydev->speed; | 1658 | ugeth->oldspeed = phydev->speed; |
1649 | } | 1659 | } |
1650 | 1660 | ||
1651 | /* | ||
1652 | * To change the MAC configuration we need to disable the | ||
1653 | * controller. To do so, we have to either grab ugeth->lock, | ||
1654 | * which is a bad idea since 'graceful stop' commands might | ||
1655 | * take quite a while, or we can quiesce driver's activity. | ||
1656 | */ | ||
1657 | ugeth_quiesce(ugeth); | ||
1658 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | ||
1659 | |||
1660 | out_be32(&ug_regs->maccfg2, tempval); | ||
1661 | out_be32(&uf_regs->upsmr, upsmr); | ||
1662 | |||
1663 | ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | ||
1664 | ugeth_activate(ugeth); | ||
1665 | |||
1666 | if (!ugeth->oldlink) { | 1661 | if (!ugeth->oldlink) { |
1667 | new_state = 1; | 1662 | new_state = 1; |
1668 | ugeth->oldlink = 1; | 1663 | ugeth->oldlink = 1; |
1669 | } | 1664 | } |
1665 | |||
1666 | if (new_state) { | ||
1667 | /* | ||
1668 | * To change the MAC configuration we need to disable | ||
1669 | * the controller. To do so, we have to either grab | ||
1670 | * ugeth->lock, which is a bad idea since 'graceful | ||
1671 | * stop' commands might take quite a while, or we can | ||
1672 | * quiesce driver's activity. | ||
1673 | */ | ||
1674 | ugeth_quiesce(ugeth); | ||
1675 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | ||
1676 | |||
1677 | out_be32(&ug_regs->maccfg2, tempval); | ||
1678 | out_be32(&uf_regs->upsmr, upsmr); | ||
1679 | |||
1680 | ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | ||
1681 | ugeth_activate(ugeth); | ||
1682 | } | ||
1670 | } else if (ugeth->oldlink) { | 1683 | } else if (ugeth->oldlink) { |
1671 | new_state = 1; | 1684 | new_state = 1; |
1672 | ugeth->oldlink = 0; | 1685 | ugeth->oldlink = 0; |
@@ -1989,7 +2002,6 @@ static void ucc_geth_set_multi(struct net_device *dev) | |||
1989 | struct dev_mc_list *dmi; | 2002 | struct dev_mc_list *dmi; |
1990 | struct ucc_fast __iomem *uf_regs; | 2003 | struct ucc_fast __iomem *uf_regs; |
1991 | struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; | 2004 | struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; |
1992 | int i; | ||
1993 | 2005 | ||
1994 | ugeth = netdev_priv(dev); | 2006 | ugeth = netdev_priv(dev); |
1995 | 2007 | ||
@@ -2016,10 +2028,7 @@ static void ucc_geth_set_multi(struct net_device *dev) | |||
2016 | out_be32(&p_82xx_addr_filt->gaddr_h, 0x0); | 2028 | out_be32(&p_82xx_addr_filt->gaddr_h, 0x0); |
2017 | out_be32(&p_82xx_addr_filt->gaddr_l, 0x0); | 2029 | out_be32(&p_82xx_addr_filt->gaddr_l, 0x0); |
2018 | 2030 | ||
2019 | dmi = dev->mc_list; | 2031 | netdev_for_each_mc_addr(dmi, dev) { |
2020 | |||
2021 | for (i = 0; i < dev->mc_count; i++, dmi = dmi->next) { | ||
2022 | |||
2023 | /* Only support group multicast for now. | 2032 | /* Only support group multicast for now. |
2024 | */ | 2033 | */ |
2025 | if (!(dmi->dmi_addr[0] & 1)) | 2034 | if (!(dmi->dmi_addr[0] & 1)) |
@@ -2159,8 +2168,8 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) | |||
2159 | } | 2168 | } |
2160 | 2169 | ||
2161 | if ((ug_info->numStationAddresses != | 2170 | if ((ug_info->numStationAddresses != |
2162 | UCC_GETH_NUM_OF_STATION_ADDRESSES_1) | 2171 | UCC_GETH_NUM_OF_STATION_ADDRESSES_1) && |
2163 | && ug_info->rxExtendedFiltering) { | 2172 | ug_info->rxExtendedFiltering) { |
2164 | if (netif_msg_probe(ugeth)) | 2173 | if (netif_msg_probe(ugeth)) |
2165 | ugeth_err("%s: Number of station addresses greater than 1 " | 2174 | ugeth_err("%s: Number of station addresses greater than 1 " |
2166 | "not allowed in extended parsing mode.", | 2175 | "not allowed in extended parsing mode.", |
@@ -2284,9 +2293,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2284 | UCC_GETH_NUM_OF_STATION_ADDRESSES_1); | 2293 | UCC_GETH_NUM_OF_STATION_ADDRESSES_1); |
2285 | 2294 | ||
2286 | ugeth->rx_extended_features = ugeth->rx_non_dynamic_extended_features || | 2295 | ugeth->rx_extended_features = ugeth->rx_non_dynamic_extended_features || |
2287 | (ug_info->vlanOperationTagged != UCC_GETH_VLAN_OPERATION_TAGGED_NOP) | 2296 | (ug_info->vlanOperationTagged != UCC_GETH_VLAN_OPERATION_TAGGED_NOP) || |
2288 | || (ug_info->vlanOperationNonTagged != | 2297 | (ug_info->vlanOperationNonTagged != |
2289 | UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP); | 2298 | UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP); |
2290 | 2299 | ||
2291 | init_default_reg_vals(&uf_regs->upsmr, | 2300 | init_default_reg_vals(&uf_regs->upsmr, |
2292 | &ug_regs->maccfg1, &ug_regs->maccfg2); | 2301 | &ug_regs->maccfg1, &ug_regs->maccfg2); |
@@ -2987,11 +2996,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2987 | ugeth->p_init_enet_param_shadow->rgftgfrxglobal |= | 2996 | ugeth->p_init_enet_param_shadow->rgftgfrxglobal |= |
2988 | ugeth->rx_glbl_pram_offset | ug_info->riscRx; | 2997 | ugeth->rx_glbl_pram_offset | ug_info->riscRx; |
2989 | if ((ug_info->largestexternallookupkeysize != | 2998 | if ((ug_info->largestexternallookupkeysize != |
2990 | QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE) | 2999 | QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE) && |
2991 | && (ug_info->largestexternallookupkeysize != | 3000 | (ug_info->largestexternallookupkeysize != |
2992 | QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES) | 3001 | QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES) && |
2993 | && (ug_info->largestexternallookupkeysize != | 3002 | (ug_info->largestexternallookupkeysize != |
2994 | QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) { | 3003 | QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) { |
2995 | if (netif_msg_ifup(ugeth)) | 3004 | if (netif_msg_ifup(ugeth)) |
2996 | ugeth_err("%s: Invalid largest External Lookup Key Size.", | 3005 | ugeth_err("%s: Invalid largest External Lookup Key Size.", |
2997 | __func__); | 3006 | __func__); |
@@ -3273,13 +3282,12 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3273 | /* Handle the transmitted buffer and release */ | 3282 | /* Handle the transmitted buffer and release */ |
3274 | /* the BD to be used with the current frame */ | 3283 | /* the BD to be used with the current frame */ |
3275 | 3284 | ||
3276 | if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) | 3285 | skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; |
3286 | if (!skb) | ||
3277 | break; | 3287 | break; |
3278 | 3288 | ||
3279 | dev->stats.tx_packets++; | 3289 | dev->stats.tx_packets++; |
3280 | 3290 | ||
3281 | skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; | ||
3282 | |||
3283 | if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && | 3291 | if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && |
3284 | skb_recycle_check(skb, | 3292 | skb_recycle_check(skb, |
3285 | ugeth->ug_info->uf_info.max_rx_buf_length + | 3293 | ugeth->ug_info->uf_info.max_rx_buf_length + |
@@ -3601,6 +3609,7 @@ static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state) | |||
3601 | if (!netif_running(ndev)) | 3609 | if (!netif_running(ndev)) |
3602 | return 0; | 3610 | return 0; |
3603 | 3611 | ||
3612 | netif_device_detach(ndev); | ||
3604 | napi_disable(&ugeth->napi); | 3613 | napi_disable(&ugeth->napi); |
3605 | 3614 | ||
3606 | /* | 3615 | /* |
@@ -3659,7 +3668,7 @@ static int ucc_geth_resume(struct of_device *ofdev) | |||
3659 | phy_start(ugeth->phydev); | 3668 | phy_start(ugeth->phydev); |
3660 | 3669 | ||
3661 | napi_enable(&ugeth->napi); | 3670 | napi_enable(&ugeth->napi); |
3662 | netif_start_queue(ndev); | 3671 | netif_device_attach(ndev); |
3663 | 3672 | ||
3664 | return 0; | 3673 | return 0; |
3665 | } | 3674 | } |
@@ -3798,7 +3807,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3798 | prop = of_get_property(np, "tx-clock", NULL); | 3807 | prop = of_get_property(np, "tx-clock", NULL); |
3799 | if (!prop) { | 3808 | if (!prop) { |
3800 | printk(KERN_ERR | 3809 | printk(KERN_ERR |
3801 | "ucc_geth: mising tx-clock-name property\n"); | 3810 | "ucc_geth: missing tx-clock-name property\n"); |
3802 | return -EINVAL; | 3811 | return -EINVAL; |
3803 | } | 3812 | } |
3804 | if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) { | 3813 | if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) { |