summaryrefslogtreecommitdiff
path: root/cleopatre
diff options
context:
space:
mode:
authorsave2010-03-02 10:23:58 +0000
committersave2010-03-02 10:23:58 +0000
commit455dcfabb4ab6597cac5b6c73ed1758bafc3413e (patch)
tree58eceeb94f01da33b84aa6fd167dd06ab8c75a58 /cleopatre
parentfebe4e8d827c1ccf7ba84399bb97964e04f45756 (diff)
cleo/linux/eth: Use phy address on each mdio access+Check IP175 id, closes #1310
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@6801 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cleopatre')
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c162
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c13
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h8
3 files changed, 105 insertions, 78 deletions
diff --git a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c
index ef39ec59ba..0ea653c1bc 100644
--- a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c
+++ b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504.c
@@ -74,7 +74,13 @@
#define TX_RING_SIZE 64
/** Size of the DMA ring for rx */
#define RX_RING_SIZE 64
-/** Supported Phy reference */
+
+/** Bit fields for MII_PHY identifier */
+#define PHYSID_GET_ID(id1, id2) (id1 << 16 | id2)
+#define PHYSID_GET_OUI(id) ((id >> 10) & 0x00FFFFFF)
+#define PHYSID_GET_MODEL(id) ((id >> 4) & 0x0000003F)
+#define PHYSID_GET_REV(id) ((id >> 0) & 0x0000000F)
+/** Supported PHY reference */
#define OUI_ICPLUS 0x90C3
#define ICPLUS_MODEL_IP175 0x18
#define ICPLUS_MODEL_IP1001 0x19
@@ -258,7 +264,7 @@ static int mdio_read(struct net_device *dev, int phy, int reg)
Synopsys *synop = &priv->synop;
if(synop)
- return SynopsysMiiRead(synop, reg);
+ return SynopsysMiiRead(synop, (uint32_t)phy, reg);
else
return 0;
}// mdio_read
@@ -276,7 +282,7 @@ static void mdio_write(struct net_device *dev, int phy, int reg, int value)
Synopsys *synop = &priv->synop;
if(synop)
- SynopsysMiiWrite(synop, reg, value);
+ SynopsysMiiWrite(synop, (uint32_t)phy, reg, value);
}// mdio_write
@@ -462,13 +468,13 @@ static void synop3504_on_link_up(struct net_device *dev)
int fdx=0;
//Find ETH speed and duplex for DMA config
- status = mdio_read(dev, 0, MII_BMSR);
- estatus = mdio_read(dev, 0, MII_ESTATUS);
+ status = mdio_read(dev, priv->phy_addr, MII_BMSR);
+ estatus = mdio_read(dev, priv->phy_addr, MII_ESTATUS);
if((status & BMSR_ESTATEN) &&
((estatus & ESTATUS_1000_TFULL) || (estatus & ESTATUS_1000_THALF)))
{ //PHY can manage GIGA bits
- negotiated = mdio_read(dev, 0, MII_STAT1000);
+ negotiated = mdio_read(dev, priv->phy_addr, MII_STAT1000);
if(negotiated & LPA_1000FULL)
{
@@ -486,7 +492,7 @@ static void synop3504_on_link_up(struct net_device *dev)
if(speed == 0)
{ //No GIGA Bits detected
- negotiated = mdio_read(dev, 0, MII_LPA);
+ negotiated = mdio_read(dev, priv->phy_addr, MII_LPA);
if(negotiated & LPA_100FULL)
{
@@ -560,51 +566,59 @@ static void synop3504_enable_autonegotiation(struct net_device *dev)
{
volatile uint32_t data;
volatile uint32_t estatus;
+ struct net_priv *priv = NULL;
+
+ //Check pointer
+ if(dev == NULL)
+ return;
+ priv = (struct net_priv *)dev->priv;
+ if(priv == NULL)
+ return;
#ifdef CONFIG_MACH_ARIZONA
//Force hardware to be 10M FULL just for first tests
//Disable Auto-Negotiation
- data = mdio_read(dev, 0, MII_BMCR);
+ data = mdio_read(dev, priv->phy_addr, MII_BMCR);
data &= ~BMCR_ANENABLE;
- mdio_write(dev, 0, MII_BMCR, data);
+ mdio_write(dev, priv->phy_addr, MII_BMCR, data);
//Force 10M Full Duplex
- data = mdio_read(dev, 0, MII_BMCR);
+ data = mdio_read(dev, priv->phy_addr, MII_BMCR);
data &= ~BMCR_SPEED100;
data |= BMCR_FULLDPLX;
- mdio_write(dev, 0, MII_BMCR, data);
+ mdio_write(dev, priv->phy_addr, MII_BMCR, data);
#else
//Ensure that PHY is Auto-Negotiation capable
- if (mdio_read(dev, 0, MII_BMSR) & BMSR_ANEGCAPABLE)
+ if (mdio_read(dev, priv->phy_addr, MII_BMSR) & BMSR_ANEGCAPABLE)
{
//Disable Auto-Negotiation
- data = mdio_read(dev, 0, MII_BMCR);
+ data = mdio_read(dev, priv->phy_addr, MII_BMCR);
data &= ~BMCR_ANENABLE;
- mdio_write(dev, 0, MII_BMCR, data);
+ mdio_write(dev, priv->phy_addr, MII_BMCR, data);
//Set Auto-Negotiation advertisement register - all techs
- data = mdio_read(dev, 0, MII_ADVERTISE);
+ data = mdio_read(dev, priv->phy_addr, MII_ADVERTISE);
data |= ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | ADVERTISE_100FULL;
- mdio_write(dev, 0, MII_ADVERTISE, data);
+ mdio_write(dev, priv->phy_addr, MII_ADVERTISE, data);
//Check Giga bits capabilities
- if((mdio_read(dev, 0, MII_BMSR)) & BMSR_ESTATEN)
+ if((mdio_read(dev, priv->phy_addr, MII_BMSR)) & BMSR_ESTATEN)
{
- estatus = mdio_read(dev, 0, MII_ESTATUS);
- data = mdio_read(dev, 0, MII_CTRL1000);
+ estatus = mdio_read(dev, priv->phy_addr, MII_ESTATUS);
+ data = mdio_read(dev, priv->phy_addr, MII_CTRL1000);
if(estatus & ESTATUS_1000_TFULL)
data |= ADVERTISE_1000FULL;
if(estatus & ESTATUS_1000_THALF)
data |= ADVERTISE_1000HALF;
- mdio_write(dev, 0, MII_STAT1000, data);
+ mdio_write(dev, priv->phy_addr, MII_STAT1000, data);
}
//Kick Auto-Negotiation
- data = mdio_read(dev, 0, MII_BMCR);
+ data = mdio_read(dev, priv->phy_addr, MII_BMCR);
data |= BMCR_ANENABLE;
- mdio_write(dev, 0, MII_BMCR, data);
+ mdio_write(dev, priv->phy_addr, MII_BMCR, data);
}
#endif
}// synop3504_enable_autonegotiation
@@ -643,7 +657,7 @@ static int synop3504_autonegotiate(struct net_device *dev, int wait)
netif_start_queue(dev);
#else
//Start the Auto-Negotiation
- if(mdio_read(dev, 0, MII_BMSR) & BMSR_ANEGCAPABLE)
+ if(mdio_read(dev, priv->phy_addr, MII_BMSR) & BMSR_ANEGCAPABLE)
{
TRACE("starting AutoNegotiation for %s\n", dev->name);
//Kick Auto Negotiation
@@ -657,7 +671,7 @@ static int synop3504_autonegotiate(struct net_device *dev, int wait)
do
{
mdly(AUTONEG_STEP);
- data = mdio_read(dev, 0, MII_BMSR);
+ data = mdio_read(dev, priv->phy_addr, MII_BMSR);
} while(!(data & BMSR_ANEGCOMPLETE) && timeout--);
if(timeout <= 0)
@@ -701,7 +715,7 @@ static void synop3504_timer(unsigned long data)
return;
}
- if(!(mdio_read(dev, 0, MII_BMSR) & BMSR_LSTATUS))
+ if(!(mdio_read(dev, priv->phy_addr, MII_BMSR) & BMSR_LSTATUS))
{
if(netif_carrier_ok(dev))
{
@@ -986,7 +1000,7 @@ static int synop3504_tx(struct sk_buff *skb, struct net_device *dev)
n = tx->head_ptr;
//Check if the link is down
- status_mdio = mdio_read(dev, 0, MII_BMSR);
+ status_mdio = mdio_read(dev, priv->phy_addr, MII_BMSR);
if((status_mdio & BMSR_LSTATUS) == 0)
{
printk(KERN_WARNING DRV_NAME "%s: TX error : Link still down\n", dev->name);
@@ -1359,6 +1373,59 @@ static irqreturn_t synop3504_interrupt(int irq, void * dev_id)
}// synop3504_interrupt
/**
+ * Find PHY reference.
+ * \param dev device structure.
+ */
+static void synop3504_find_phy_ref(struct net_device *dev)
+{
+ struct net_priv *priv = NULL;
+
+ //Check pointers
+ if(dev == NULL)
+ return;
+ priv = (struct net_priv *)dev->priv;
+ if(priv == NULL)
+ return;
+
+ //Find PHY identifier
+ priv->phy_id = PHYSID_GET_ID(mdio_read(dev, priv->phy_addr, MII_PHYSID1), mdio_read(dev, priv->phy_addr, MII_PHYSID2));
+
+ //PHY identifier not found, but it can be a switch IP175 so let's check at
+ //phy_addr 0
+ if(0 == priv->phy_id)
+ {
+ priv->phy_id = PHYSID_GET_ID(mdio_read(dev, 0, MII_PHYSID1), mdio_read(dev, 0, MII_PHYSID2));
+
+ if((OUI_ICPLUS != PHYSID_GET_OUI(priv->phy_id)) || (ICPLUS_MODEL_IP175 != PHYSID_GET_MODEL(priv->phy_id)))
+ {
+ priv->phy_id = 0;
+ printk(DRV_NAME ": PHY ID not found for %s\n", dev->name);
+ return;
+ }
+ }
+
+ priv->phy_oui = PHYSID_GET_OUI(priv->phy_id);
+ priv->phy_model = PHYSID_GET_MODEL(priv->phy_id);
+ priv->phy_rev = PHYSID_GET_REV(priv->phy_id);
+
+ if((OUI_ICPLUS == priv->phy_oui) && (ICPLUS_MODEL_IP175 == priv->phy_model))
+ {
+ if(0x175D == mdio_read (dev, 20, 0))
+ {
+ printk(DRV_NAME ": PHY for %s is IC+ IP175D rev %u\n", dev->name, priv->phy_rev);
+ }
+ else
+ {
+ printk(DRV_NAME ": PHY for %s is IC+ IP175C rev %u\n", dev->name, priv->phy_rev);
+ }
+ }
+ else if(priv->phy_oui == OUI_ICPLUS && priv->phy_model == ICPLUS_MODEL_IP1001)
+ printk(DRV_NAME ": PHY for %s is IC+ IP1001 rev %u\n", dev->name, priv->phy_rev);
+ else
+ printk(DRV_NAME ": PHY ID for %s id is 0x%8.8x\n", dev->name, priv->phy_id);
+}
+
+/**
* Initialize the device.
* \param dev device structure.
* \return error code.
@@ -1384,42 +1451,11 @@ static int synop3504_open(struct net_device *dev)
SynopsysReset(synop);
//Reset PHY
- mdio_write(dev, 0, MII_BMCR, BMCR_RESET);
- while(mdio_read(dev, 0, MII_BMCR) & BMCR_RESET);
+ mdio_write(dev, priv->phy_addr, MII_BMCR, BMCR_RESET);
+ while(mdio_read(dev, priv->phy_addr, MII_BMCR) & BMCR_RESET);
//Check PHY ID
- priv->phy_id = mdio_read(dev, 0, MII_PHYSID1) << 16 | mdio_read(dev, 0, MII_PHYSID2);
- priv->phy_oui = (priv->phy_id >> 10) & 0x00ffffff;
- priv->phy_model = (priv->phy_id >> 4) & 0x0000003f;
- priv->phy_rev = (priv->phy_id >> 0) & 0x0000000f;
- if((priv->phy_oui == OUI_ICPLUS)
- && (priv->phy_model == ICPLUS_MODEL_IP175))
- {
- /* try to check if it is an IP175C or an IP175D */
-
- /* this cannot work due to MDIO functions which are only using
- nvram phy address !!!! */
-
- /*unsigned int phy_id3;
- phy_id3 = mdio_read (dev, 20, 0);
- printk ("phy_id3 = %08x\n", phy_id3);
- if(0x175D == phy_id3)
- {
- printk(DRV_NAME ": PHY for %s is IC+ IP175D rev %u\n", dev->name, priv->phy_rev);
- }
- else
- {
- printk(DRV_NAME ": PHY for %s is IC+ IP175C rev %u\n", dev->name, priv->phy_rev);
- }*/
-
- /* so guess that it is a IP175D :-( */
- printk(DRV_NAME ": PHY for %s is IC+ IP175D rev %u\n", dev->name, priv->phy_rev);
-
- }
- else if(priv->phy_oui == OUI_ICPLUS && priv->phy_model == ICPLUS_MODEL_IP1001)
- printk(DRV_NAME ": PHY for %s is IC+ IP1001 rev %u\n", dev->name, priv->phy_rev);
- else
- printk(DRV_NAME ": PHY ID for %s id is 0x%8.8x\n", dev->name, priv->phy_id);
+ synop3504_find_phy_ref(dev);
//Initialise DMA descriptors
synop3504_txdesc_init(dev);
@@ -1528,11 +1564,11 @@ static int synop3504_init(struct net_device *dev)
//Attach hardware layer addresses
if(priv->support_gmii)
- SynopsysAttach(&priv->synop, priv->gmac_addr, priv->dma_addr, priv->phy_addr, IS_GMII);
+ SynopsysAttach(&priv->synop, priv->gmac_addr, priv->dma_addr, IS_GMII);
else if(priv->support_rmii)
- SynopsysAttach(&priv->synop, priv->gmac_addr, priv->dma_addr, priv->phy_addr, IS_RMII);
+ SynopsysAttach(&priv->synop, priv->gmac_addr, priv->dma_addr, IS_RMII);
else
- SynopsysAttach(&priv->synop, priv->gmac_addr, priv->dma_addr, priv->phy_addr, IS_MII);
+ SynopsysAttach(&priv->synop, priv->gmac_addr, priv->dma_addr, IS_MII);
//Initialise device functions
ether_setup(dev);
diff --git a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c
index 1d52afcaa5..84261a05a2 100644
--- a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c
+++ b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.c
@@ -101,13 +101,10 @@ static inline void SynopsysClearDmaReg(Synopsys *synop, uint32_t reg, uint32_t d
__raw_writel(value, synop->dmabase+reg);
}
-uint16_t SynopsysMiiRead(Synopsys *synop, uint8_t reg)
+uint16_t SynopsysMiiRead(Synopsys *synop, uint32_t phyaddr, uint8_t reg)
{
uint32_t addr;
uint16_t data;
- uint32_t phyaddr;
-
- phyaddr = synop->phyaddr;
//Enable the phy clock and set the busy bit.
addr = ((phyaddr << GmiiDevShift) & GmiiDevMask) | ((reg << GmiiRegShift) & GmiiRegMask) | GmiiRead;
@@ -126,12 +123,9 @@ uint16_t SynopsysMiiRead(Synopsys *synop, uint8_t reg)
return data;
}
-void SynopsysMiiWrite(Synopsys *synop, uint8_t reg, uint16_t data)
+void SynopsysMiiWrite(Synopsys *synop, uint32_t phyaddr, uint8_t reg, uint16_t data)
{
uint32_t addr;
- uint32_t phyaddr;
-
- phyaddr = synop->phyaddr;
SynopsysWriteMacReg(synop, GmacGmiiData, data);
@@ -164,11 +158,10 @@ void SynopsysReset(Synopsys *synop)
TRACE("DMA Reset (%08x)\n", data);
}// SynopsysReset
-void SynopsysAttach(Synopsys *synop, uint32_t macbase, uint32_t dmabase, uint32_t phyaddr, mii_type mode)
+void SynopsysAttach(Synopsys *synop, uint32_t macbase, uint32_t dmabase, mii_type mode)
{
synop->macbase = macbase;
synop->dmabase = dmabase;
- synop->phyaddr = phyaddr;
synop->mode = mode;
TRACE("Base Addresses fixed\n");
}// SynopsysAttach
diff --git a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h
index 0323feb3da..0558a9bb40 100644
--- a/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h
+++ b/cleopatre/linux-2.6.25.10-spc300/drivers/net/arm/synop3504_hw.h
@@ -163,22 +163,20 @@ typedef struct synopsys
{
uint32_t macbase; //Base address of MAC registers
uint32_t dmabase; //Base address of DMA registers
- uint32_t phyaddr; //PHY device address on MII interface
mii_type mode; //Support MII PHY communication mode
} Synopsys;
-uint16_t SynopsysMiiRead(Synopsys *synop, uint8_t reg);
-void SynopsysMiiWrite(Synopsys *synop, uint8_t reg, uint16_t data);
+uint16_t SynopsysMiiRead(Synopsys *synop, uint32_t phyaddr, uint8_t reg);
+void SynopsysMiiWrite(Synopsys *synop, uint32_t phyaddr, uint8_t reg, uint16_t data);
/**
* Initialisation of the Synopsys device.
* \param synop Synopsys device structure.
* \param macbase base address of MAC registers.
* \param dmabase base address of DMA registers.
- * \param phyaddr MII phy device address.
* \param mode phy communication mode.
*/
-void SynopsysAttach(Synopsys *synop, uint32_t macbase, uint32_t dmabase, uint32_t phyaddr, mii_type mode);
+void SynopsysAttach(Synopsys *synop, uint32_t macbase, uint32_t dmabase, mii_type mode);
void SynopsysInit(Synopsys *synop, uint32_t txaddr, uint32_t rxaddr);