mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 22:51:37 +00:00
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 ...
This commit is contained in:
commit
2ed0e21b30
1136 changed files with 106390 additions and 47777 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved.
|
||||
* Copyright (C) 2006-2009 Freescale Semicondutor, Inc. All rights reserved.
|
||||
*
|
||||
* Author: Shlomi Gridish <gridish@freescale.com>
|
||||
* Li Yang <leoli@freescale.com>
|
||||
|
@ -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>
|
||||
|
@ -64,6 +65,8 @@
|
|||
|
||||
static DEFINE_SPINLOCK(ugeth_lock);
|
||||
|
||||
static void uec_configure_serdes(struct net_device *dev);
|
||||
|
||||
static struct {
|
||||
u32 msg_enable;
|
||||
} debug = { -1 };
|
||||
|
@ -1409,6 +1412,9 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
|
|||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
|
||||
upsmr |= UCC_GETH_UPSMR_TBIM;
|
||||
}
|
||||
if ((ugeth->phy_interface == PHY_INTERFACE_MODE_SGMII))
|
||||
upsmr |= UCC_GETH_UPSMR_SGMM;
|
||||
|
||||
out_be32(&uf_regs->upsmr, upsmr);
|
||||
|
||||
/* Disable autonegotiation in tbi mode, because by default it
|
||||
|
@ -1543,14 +1549,19 @@ 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;
|
||||
}
|
||||
|
||||
if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
|
||||
uec_configure_serdes(dev);
|
||||
|
||||
phydev->supported &= (ADVERTISED_10baseT_Half |
|
||||
ADVERTISED_10baseT_Full |
|
||||
ADVERTISED_100baseT_Half |
|
||||
|
@ -1566,7 +1577,41 @@ static int init_phy(struct net_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize TBI PHY interface for communicating with the
|
||||
* SERDES lynx PHY on the chip. We communicate with this PHY
|
||||
* through the MDIO bus on each controller, treating it as a
|
||||
* "normal" PHY at the address found in the UTBIPA register. We assume
|
||||
* that the UTBIPA register is valid. Either the MDIO bus code will set
|
||||
* it to a value that doesn't conflict with other PHYs on the bus, or the
|
||||
* value doesn't matter, as there are no other PHYs on the bus.
|
||||
*/
|
||||
static void uec_configure_serdes(struct net_device *dev)
|
||||
{
|
||||
struct ucc_geth_private *ugeth = netdev_priv(dev);
|
||||
|
||||
if (!ugeth->tbiphy) {
|
||||
printk(KERN_WARNING "SGMII mode requires that the device "
|
||||
"tree specify a tbi-handle\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 (phy_read(ugeth->tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS)
|
||||
return;
|
||||
|
||||
/* Single clk mode, mii mode off(for serdes communication) */
|
||||
phy_write(ugeth->tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS);
|
||||
|
||||
phy_write(ugeth->tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);
|
||||
|
||||
phy_write(ugeth->tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS);
|
||||
|
||||
}
|
||||
|
||||
static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
|
||||
{
|
||||
|
@ -3225,7 +3270,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] =
|
||||
|
@ -3259,9 +3304,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;
|
||||
|
@ -3275,8 +3326,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__);
|
||||
|
||||
|
@ -3290,27 +3339,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)
|
||||
|
@ -3339,6 +3375,37 @@ static void ucc_netpoll(struct net_device *dev)
|
|||
}
|
||||
#endif /* CONFIG_NET_POLL_CONTROLLER */
|
||||
|
||||
static int ucc_geth_set_mac_addr(struct net_device *dev, void *p)
|
||||
{
|
||||
struct ucc_geth_private *ugeth = netdev_priv(dev);
|
||||
struct sockaddr *addr = p;
|
||||
|
||||
if (!is_valid_ether_addr(addr->sa_data))
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
|
||||
|
||||
/*
|
||||
* If device is not running, we will set mac addr register
|
||||
* when opening the device.
|
||||
*/
|
||||
if (!netif_running(dev))
|
||||
return 0;
|
||||
|
||||
spin_lock_irq(&ugeth->lock);
|
||||
init_mac_station_addr_regs(dev->dev_addr[0],
|
||||
dev->dev_addr[1],
|
||||
dev->dev_addr[2],
|
||||
dev->dev_addr[3],
|
||||
dev->dev_addr[4],
|
||||
dev->dev_addr[5],
|
||||
&ugeth->ug_regs->macstnaddr1,
|
||||
&ugeth->ug_regs->macstnaddr2);
|
||||
spin_unlock_irq(&ugeth->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when something needs to use the ethernet device */
|
||||
/* Returns 0 for success. */
|
||||
static int ucc_geth_open(struct net_device *dev)
|
||||
|
@ -3506,6 +3573,8 @@ static phy_interface_t to_phy_interface(const char *phy_connection_type)
|
|||
return PHY_INTERFACE_MODE_RGMII_RXID;
|
||||
if (strcasecmp(phy_connection_type, "rtbi") == 0)
|
||||
return PHY_INTERFACE_MODE_RTBI;
|
||||
if (strcasecmp(phy_connection_type, "sgmii") == 0)
|
||||
return PHY_INTERFACE_MODE_SGMII;
|
||||
|
||||
return PHY_INTERFACE_MODE_MII;
|
||||
}
|
||||
|
@ -3515,7 +3584,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = {
|
|||
.ndo_stop = ucc_geth_close,
|
||||
.ndo_start_xmit = ucc_geth_start_xmit,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
.ndo_set_mac_address = ucc_geth_set_mac_addr,
|
||||
.ndo_change_mtu = eth_change_mtu,
|
||||
.ndo_set_multicast_list = ucc_geth_set_multi,
|
||||
.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
|
|||
{
|
||||
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;
|
||||
|
@ -3552,6 +3619,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
|
|||
PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII,
|
||||
PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII,
|
||||
PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
|
||||
PHY_INTERFACE_MODE_SGMII,
|
||||
};
|
||||
|
||||
ugeth_vdbg("%s: IN", __func__);
|
||||
|
@ -3635,40 +3703,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);
|
||||
|
@ -3694,6 +3735,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
|
|||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
case PHY_INTERFACE_MODE_TBI:
|
||||
case PHY_INTERFACE_MODE_RTBI:
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
max_speed = SPEED_1000;
|
||||
break;
|
||||
default:
|
||||
|
@ -3751,7 +3793,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);
|
||||
|
@ -3776,6 +3818,37 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
|
|||
ugeth->ndev = dev;
|
||||
ugeth->node = np;
|
||||
|
||||
/* Find the TBI PHY. If it's not there, we don't support SGMII */
|
||||
ph = of_get_property(np, "tbi-handle", NULL);
|
||||
if (ph) {
|
||||
struct device_node *tbi = of_find_node_by_phandle(*ph);
|
||||
struct of_device *ofdev;
|
||||
struct mii_bus *bus;
|
||||
const unsigned int *id;
|
||||
|
||||
if (!tbi)
|
||||
return 0;
|
||||
|
||||
mdio = of_get_parent(tbi);
|
||||
if (!mdio)
|
||||
return 0;
|
||||
|
||||
ofdev = of_find_device_by_node(mdio);
|
||||
|
||||
of_node_put(mdio);
|
||||
|
||||
id = of_get_property(tbi, "reg", NULL);
|
||||
if (!id)
|
||||
return 0;
|
||||
of_node_put(tbi);
|
||||
|
||||
bus = dev_get_drvdata(&ofdev->dev);
|
||||
if (!bus)
|
||||
return 0;
|
||||
|
||||
ugeth->tbiphy = bus->phy_map[*id];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue