summaryrefslogtreecommitdiff
path: root/drivers/net/mvf_switch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mvf_switch.c')
-rw-r--r--drivers/net/mvf_switch.c319
1 files changed, 184 insertions, 135 deletions
diff --git a/drivers/net/mvf_switch.c b/drivers/net/mvf_switch.c
index b2a943756aa5..3c5ece8f78f7 100644
--- a/drivers/net/mvf_switch.c
+++ b/drivers/net/mvf_switch.c
@@ -39,6 +39,7 @@
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/signal.h>
+#include <linux/clk.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
@@ -49,6 +50,8 @@
#include <asm/mvf_switch.h>
#include "mvf_switch.h"
+#define LOOKUP_ELEMENTS 2048
+
#define SWITCH_MAX_PORTS 1
#define CONFIG_FEC_SHARED_PHY
#define FEC_PHY
@@ -58,6 +61,8 @@
#define CONFIG_ENHANCED_BD
#endif
+#define TOMOICHI_DMA_MOVE
+
/* Interrupt events/masks.
*/
#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
@@ -71,6 +76,16 @@
#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
+#define FEC_MMFR_ST (1 << 30)
+#define FEC_MMFR_OP_READ (2 << 28)
+#define FEC_MMFR_OP_WRITE (1 << 28)
+#define FEC_MMFR_PA(v) ((v & 0x1f) << 23)
+#define FEC_MMFR_RA(v) ((v & 0x1f) << 18)
+#define FEC_MMFR_TA (2 << 16)
+#define FEC_MMFR_DATA(v) (v & 0xffff)
+#define FEC_MII_TIMEOUT 30 /* ms */
+
+
static int switch_enet_open(struct net_device *dev);
static int switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t switch_enet_interrupt(int irq, void *dev_id);
@@ -87,8 +102,7 @@ static void switch_set_mac_address(struct net_device *dev);
/* Make MII read/write commands for the FEC.
*/
#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
-#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \
- (VAL & 0xffff))
+#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff))
/* Transmitter timeout.
*/
@@ -102,6 +116,30 @@ struct port_status ports_link_status;
/* the user space pid, used to send the link change to user space */
long user_pid = 1;
+// for debug
+void dump_regs(void __iomem *fec)
+{
+ printk("FEC_ECNTRL REG = %x\n", readl(fec + FEC_ECNTRL));
+ printk("FEC_MII_SPEED REG = %x\n", readl(fec + FEC_MII_SPEED));
+ printk("FEC_R_CNTRL REG = %x\n", readl(fec + FEC_R_CNTRL));
+ printk("FEC_X_CNTRL REG = %x\n", readl(fec + FEC_X_CNTRL));
+}
+
+static void adjust_phy_speed( struct switch_enet_private *fep, int phy_index)
+{
+ u32 val;
+
+ val = readl(fep->fec[phy_index] + FEC_R_CNTRL);
+ if (fep->phydev[phy_index] && fep->phydev[phy_index]->speed == SPEED_100){
+ printk("Phy %d is 100M\n", phy_index);
+ val &= ~(1 << 9);
+ }else{
+ printk("Phy %d is 10M\n", phy_index);
+ val |= (1 << 9);
+ }
+ writel(val, fep->fec[phy_index] + FEC_R_CNTRL);
+}
+
/* ----------------------------------------------------------------*/
/*
* Calculate Galois Field Arithmetic CRC for Polynom x^8+x^2+x+1.
@@ -156,7 +194,6 @@ void read_atable(struct switch_enet_private *fep,
int index,
unsigned long *read_lo, unsigned long *read_hi)
{
-// unsigned long atable_base = 0xFC0E0000;
unsigned long atable_base = (long)fep->hwentry;
*read_lo = *((volatile unsigned long *)(atable_base + (index<<3)));
@@ -167,7 +204,6 @@ void write_atable(struct switch_enet_private *fep,
int index,
unsigned long write_lo, unsigned long write_hi)
{
-// unsigned long atable_base = 0xFC0E0000;
unsigned long atable_base = (long)fep->hwentry;
*((volatile unsigned long *)(atable_base + (index<<3))) = write_lo;
@@ -241,7 +277,7 @@ eswPortInfo *esw_portinfofifo_read(
void esw_clear_atable(struct switch_enet_private *fep)
{
int index;
- for (index = 0; index < 2048; index++)
+ for (index = 0; index < LOOKUP_ELEMENTS; index++)
write_atable(fep, index, 0, 0);
}
@@ -249,7 +285,7 @@ void esw_dump_atable(struct switch_enet_private *fep)
{
int index;
unsigned long read_lo, read_hi;
- for (index = 0; index < 2048; index++) {
+ for (index = 0; index < LOOKUP_ELEMENTS; index++) {
read_atable(fep, index, &read_lo, &read_hi);
}
@@ -1077,11 +1113,11 @@ void esw_mac_lookup_table_range(struct switch_enet_private *fep)
int index;
unsigned long read_lo, read_hi;
/* Pointer to switch address look up memory*/
- for (index = 0; index < 2048; index++)
+ for (index = 0; index < LOOKUP_ELEMENTS; index++)
write_atable(fep, index, index, (~index));
/* Pointer to switch address look up memory*/
- for (index = 0; index < 2048; index++) {
+ for (index = 0; index < LOOKUP_ELEMENTS; index++) {
read_atable(fep, index, &read_lo, &read_hi);
if (read_lo != index) {
printk(KERN_ERR "%s:Mismatch at low %d\n",
@@ -2321,6 +2357,7 @@ int esw_get_mac_address_lookup_table(struct switch_enet_private *fep,
static void l2switch_aging_timer(unsigned long data)
{
struct switch_enet_private *fep;
+printk("aging occured\n");
fep = (struct switch_enet_private *)data;
@@ -3203,6 +3240,9 @@ switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
cbd_t *bdp;
unsigned short status;
unsigned long flags;
+#ifdef TOMOICHI_DMA_MOVE
+ void *bufaddr;
+#endif
fep = netdev_priv(dev);
fecp = (switch_t *)fep->hwp;
@@ -3219,7 +3259,11 @@ switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Set buffer length and buffer pointer.
*/
+#ifdef TOMOICHI_DMA_MOVE
+ bufaddr = skb->data;
+#else
bdp->cbd_bufaddr = __pa(skb->data);
+#endif
bdp->cbd_datlen = skb->len;
/*
@@ -3233,7 +3277,11 @@ switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
memcpy(fep->tx_bounce[index1],
(void *)skb->data, bdp->cbd_datlen);
+#ifdef TOMOICHI_DMA_MOVE
+ bufaddr = fep->tx_bounce[index1];
+#else
bdp->cbd_bufaddr = __pa(fep->tx_bounce[index1]);
+#endif
}
/* Save skb pointer. */
@@ -3246,8 +3294,13 @@ switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
* data.
*/
// flush_dcache_range((unsigned long)skb->data,
+#ifdef TOMOICHI_DMA_MOVE
+ bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr,
+ SWITCH_ENET_TX_FRSIZE, DMA_TO_DEVICE);
+#else
flush_kernel_vmap_range(skb->data,
(unsigned long)skb->data + skb->len);
+#endif
/* Send it on its way. Tell FEC it's ready, interrupt when done,
* it's the last BD of the frame, and to put the CRC on the end.
@@ -3304,12 +3357,14 @@ switch_enet_interrupt(int irq, void *dev_id)
irqreturn_t ret = IRQ_NONE;
fecp = (switch_t *)dev->base_addr;
-
/* Get the interrupt events that caused us to be here.
*/
do {
int_events = fecp->switch_ievent;
fecp->switch_ievent = int_events;
+
+// if (int_events)printk("Interrupt %s:%d occured ev:%x, reg address %x\n", __func__, __LINE__,int_events, &fecp->switch_ievent);
+
/* Handle receive event in its own function. */
/* Transmit OK, or non-fatal error. Update the buffer
@@ -3361,7 +3416,12 @@ switch_enet_tx(struct net_device *dev)
while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
if (bdp == fep->cur_tx && fep->tx_full == 0)
break;
-
+#ifdef TOMOICHI_DMA_MOVE
+ if (bdp->cbd_bufaddr)
+ dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
+ SWITCH_ENET_TX_FRSIZE, DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = 0;
+#endif
skb = fep->tx_skbuff[fep->skb_dirty];
/* Check for errors. */
if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
@@ -3483,6 +3543,7 @@ switch_enet_rx(struct net_device *dev)
dev->stats.rx_bytes += pkt_len;
data = (__u8 *)__va(bdp->cbd_bufaddr);
+
/* This does 16 byte alignment, exactly what we need.
* The packet length includes FCS, but we don't want to
* include that when passing upstream as it messes up
@@ -3498,6 +3559,7 @@ switch_enet_rx(struct net_device *dev)
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
}
+
rx_processing_done:
/* Clear the status flags for this buffer */
@@ -3524,70 +3586,45 @@ rx_processing_done:
spin_unlock_irq(&fep->hw_lock);
}
-static int fec_mdio_transfer(struct mii_bus *bus, int phy_id,
- int reg, int regval)
+static int mvf_fec_mdio_read(struct mii_bus *bus,
+ int phy_id, int reg)
{
- struct net_device *dev = bus->priv;
- unsigned long flags;
+ unsigned long time_left;
struct switch_enet_private *fep;
- int tries = 100;
- int retval = 0;
- fep = netdev_priv(dev);
- spin_lock_irqsave(&fep->mii_lock, flags);
-
- regval |= phy_id << 23;
-#if 0
- MCF_FEC_MMFR0 = regval;
-#else
- writel(regval, fep->fec[0] + FEC_MII_DATA);
-#endif
-
- /* wait for it to finish, this takes about 23 us on lite5200b */
-#if 0
- while (!(MCF_FEC_EIR0 & FEC_ENET_MII) && --tries)
-#else
- while (!(readl(fep->fec[0]+FEC_IEVENT) & FEC_ENET_MII) && --tries)
-#endif
- udelay(5);
-
- if (!tries) {
- printk(KERN_ERR "%s timeout\n", __func__);
- return -ETIMEDOUT;
- }
-
-#if 0
- MCF_FEC_EIR0 = FEC_ENET_MII;
-#else
- writel(FEC_ENET_MII, fep->fec[0]+FEC_IEVENT);
-#endif
-
-#if 0
- retval = MCF_FEC_MMFR0;
-#else
- retval = readl(fep->fec[0] + FEC_MII_DATA);
-#endif
+ struct net_device *dev = bus->priv;
- spin_unlock_irqrestore(&fep->mii_lock, flags);
+ fep = netdev_priv(dev);
- return retval;
-}
+ /* start a read op */
+ writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
+ FEC_MMFR_PA(phy_id) | FEC_MMFR_RA(reg) |
+ FEC_MMFR_TA, fep->fec[0] + FEC_MII_DATA);
+ mdelay(FEC_MII_TIMEOUT);
-static int mvf_fec_mdio_read(struct mii_bus *bus,
- int phy_id, int reg)
-{
- int ret;
- ret = fec_mdio_transfer(bus, phy_id, reg,
- mk_mii_read(reg));
- return ret;
+ /* return value */
+ return FEC_MMFR_DATA(readl(fep->fec[0] + FEC_MII_DATA));
}
static int mvf_fec_mdio_write(struct mii_bus *bus,
int phy_id, int reg, u16 data)
{
- return fec_mdio_transfer(bus, phy_id, reg,
- mk_mii_write(reg, data));
+ unsigned long time_left;
+ struct switch_enet_private *fep;
+ struct net_device *dev = bus->priv;
+
+ fep = netdev_priv(dev);
+
+ /* start a write op */
+ writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE |
+ FEC_MMFR_PA(phy_id) | FEC_MMFR_RA(reg) |
+ FEC_MMFR_TA | FEC_MMFR_DATA(data),
+ fep->fec[0] + FEC_MII_DATA);
+
+ mdelay(FEC_MII_TIMEOUT);
+
+ return 0;
}
static void switch_adjust_link1(struct net_device *dev)
@@ -3605,6 +3642,7 @@ static void switch_adjust_link1(struct net_device *dev)
if (phydev1->speed != priv->phy1_speed) {
new_state = 1;
priv->phy1_speed = phydev1->speed;
+ adjust_phy_speed(priv,0);
}
if (priv->phy1_old_link == PHY_DOWN) {
@@ -3626,6 +3664,10 @@ static void switch_adjust_link1(struct net_device *dev)
/*Send the new status to user space*/
if (user_pid != 1)
sys_tkill(user_pid, SIGUSR1);
+
+#if 1
+ phy_print_status(phydev1);
+#endif
}
}
@@ -3644,6 +3686,7 @@ static void switch_adjust_link2(struct net_device *dev)
if (phydev2->speed != priv->phy2_speed) {
new_state = 1;
priv->phy2_speed = phydev2->speed;
+ adjust_phy_speed(priv,1);
}
if (priv->phy2_old_link == PHY_DOWN) {
@@ -3665,13 +3708,17 @@ static void switch_adjust_link2(struct net_device *dev)
/*Send the new status to user space*/
if (user_pid != 1)
sys_tkill(user_pid, SIGUSR1);
+
+#if 1
+ phy_print_status(phydev2);
+#endif
}
}
static int mvf_switch_init_phy(struct net_device *dev)
{
struct switch_enet_private *priv = netdev_priv(dev);
- struct phy_device *phydev[SWITCH_EPORT_NUMBER] = {NULL, NULL};
+ struct phy_device *phydev[PHY_MAX_ADDR] = {NULL, NULL};
int i, startnode = 0;
/* search for connect PHY device */
@@ -3722,34 +3769,24 @@ static int mvf_switch_init_phy(struct net_device *dev)
priv->phy2_speed = 0;
priv->phy2_duplex = -1;
-#ifndef CONFIG_ARCH_MVF
- phydev[0] = phy_connect(dev, phydev[0]->dev.bus_id,
-#else
phydev[0] = phy_connect(dev, dev_name(&phydev[0]->dev),
-#endif
&switch_adjust_link1, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev[0])) {
printk(KERN_ERR " %s phy_connect failed\n", __func__);
return PTR_ERR(phydev[0]);
}
-
-#ifndef CONFIG_ARCH_MVF
- phydev[1] = phy_connect(dev, phydev[1]->dev.bus_id,
-#else
- phydev[0] = phy_connect(dev, dev_name(&phydev[0]->dev),
-#endif
+ phydev[1] = phy_connect(dev, dev_name(&phydev[1]->dev),
&switch_adjust_link2, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev[1])) {
printk(KERN_ERR " %s phy_connect failed\n", __func__);
return PTR_ERR(phydev[1]);
}
-
+ printk("Phy devs %s, %s\n", dev_name(&phydev[0]->dev),dev_name(&phydev[1]->dev));
for (i = 0; i < SWITCH_EPORT_NUMBER; i++) {
printk(KERN_INFO "attached phy %i to driver %s\n",
phydev[i]->addr, phydev[i]->drv->name);
priv->phydev[i] = phydev[i];
}
-
return 0;
}
/* -----------------------------------------------------------------------*/
@@ -3760,6 +3797,7 @@ switch_enet_open(struct net_device *dev)
volatile switch_t *fecp;
int i;
+
fecp = (volatile switch_t *)fep->hwp;
/* I should reset the ring buffers here, but I don't yet know
* a simple way to do that.
@@ -3783,7 +3821,6 @@ switch_enet_open(struct net_device *dev)
/* no phy, go full duplex, it's most likely a hub chip */
switch_restart(dev, 1);
-
/* if the fec is the fist open, we need to do nothing*/
/* if the fec is not the fist open, we need to restart the FEC*/
if (fep->sequence_done == 0)
@@ -3800,6 +3837,8 @@ switch_enet_open(struct net_device *dev)
netif_start_queue(dev);
fep->opened = 1;
+
+
return 0;
}
@@ -3809,6 +3848,7 @@ switch_enet_close(struct net_device *dev)
struct switch_enet_private *fep = netdev_priv(dev);
int i;
+
/* Don't know what to do yet.*/
fep->opened = 0;
netif_stop_queue(dev);
@@ -3820,6 +3860,8 @@ switch_enet_close(struct net_device *dev)
phy_write(fep->phydev[i], MII_BMCR, BMCR_PDOWN);
}
#endif
+
+
return 0;
}
@@ -3897,78 +3939,57 @@ switch_set_mac_address(struct net_device *dev)
static void
switch_hw_init( struct switch_enet_private *fep)
{
-#if 0
- /* GPIO config - RMII mode for both MACs */
- MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC &
- MCF_GPIO_PAR_FEC_FEC_MASK) |
- MCF_GPIO_PAR_FEC_FEC_RMII0FUL_1FUL;
-#endif
-
+ int i;
-#if 0
- /* Initialize MAC 0/1 */
- /* RCR */
- MCF_FEC_RCR0 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE |
- MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD);
- MCF_FEC_RCR1 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE |
- MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD);
- /* TCR */
- MCF_FEC_TCR0 = MCF_FEC_TCR_FDEN;
- MCF_FEC_TCR1 = MCF_FEC_TCR_FDEN;
-#else
+// /* Initialize MAC 0/1 */
+// /* RCR */
+// MCF_FEC_RCR0 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE |
+// MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD);
+// MCF_FEC_RCR1 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE |
+// MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD);
+// /* TCR */
+// MCF_FEC_TCR0 = MCF_FEC_TCR_FDEN;
+// MCF_FEC_TCR1 = MCF_FEC_TCR_FDEN;
writel((MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD), fep->fec[0] + FEC_R_CNTRL);
writel((MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE | MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD), fep->fec[1] + FEC_R_CNTRL);
writel(MCF_FEC_TCR_FDEN, fep->fec[0] + FEC_X_CNTRL);
writel(MCF_FEC_TCR_FDEN, fep->fec[1] + FEC_X_CNTRL);
-#endif
-
-
-#if 0
/* ECR */
-#ifdef CONFIG_ENHANCED_BD
- MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588;
- MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588;
-#else
- MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN;
- MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN;
-#endif
-
-#else
-
+// #ifdef CONFIG_ENHANCED_BD
+// MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588;
+// MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588;
+//#else
+// MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN;
+// MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN;
+//#endif
#ifdef CONFIG_ENHANCED_BD
- writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588, fep->fec[0] + FEC_ECNTRL);
- writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588, fep->fec[1] + FEC_ECNTRL);
+ writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588 |MCF_FEC_ECR_SWAP, fep->fec[0] + FEC_ECNTRL);
+ writel(MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588 |MCF_FEC_ECR_SWAP, fep->fec[1] + FEC_ECNTRL);
#else
- writel(MCF_FEC_ECR_ETHER_EN , fep->fec[0] + FEC_ECNTRL);
- writel(MCF_FEC_ECR_ETHER_EN , fep->fec[1] + FEC_ECNTRL);
+ writel(MCF_FEC_ECR_ETHER_EN |MCF_FEC_ECR_SWAP, fep->fec[0] + FEC_ECNTRL);
+ writel(MCF_FEC_ECR_ETHER_EN |MCF_FEC_ECR_SWAP, fep->fec[1] + FEC_ECNTRL);
#endif
-#endif
-#if 0
- MCF_FEC_MSCR0 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
- MCF_FEC_MSCR1 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
+// MCF_FEC_MSCR0 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
+// MCF_FEC_MSCR1 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
- MCF_FEC_EIMR0 = FEC_ENET_TXF | FEC_ENET_RXF;
- MCF_FEC_EIMR1 = FEC_ENET_TXF | FEC_ENET_RXF;
+// MCF_FEC_EIMR0 = FEC_ENET_TXF | FEC_ENET_RXF;
+// MCF_FEC_EIMR1 = FEC_ENET_TXF | FEC_ENET_RXF;
/*MCF_PPMHR0*/
- MCF_PPMCR0 = 0;
-#else
+// MCF_PPMCR0 = 0;
writel( MVF_MII_SWITCH_SPEED, fep->fec[0] + FEC_MII_SPEED);
writel( MVF_MII_SWITCH_SPEED, fep->fec[1] + FEC_MII_SPEED);
writel( FEC_ENET_TXF | FEC_ENET_RXF, fep->fec[0] + FEC_IMASK);
writel( FEC_ENET_TXF | FEC_ENET_RXF, fep->fec[1] + FEC_IMASK);
-// MCF_PPMCR0 = 0;
-// writel( , fep->fec[0] + );
- #pragma message "need fix!!!!!"
-#endif
-
-
+ for (i = 0; i < SWITCH_EPORT_NUMBER; i++) {
+ adjust_phy_speed(fep, i);
+ }
}
#ifdef CONFIG_ARCH_MVF
@@ -4006,7 +4027,11 @@ int __init switch_enet_init(struct net_device *dev,
/* Allocate memory for buffer descriptors.
*/
+//#ifdef TOMOICHI_DMA_MOVE
+// mem_addr = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, GFP_KERNEL);
+//#else
mem_addr = __get_free_page(GFP_DMA);
+//#endif
if (mem_addr == 0) {
printk(KERN_ERR "Switch: allocate descriptor memory failed?\n");
return -ENOMEM;
@@ -4026,7 +4051,7 @@ int __init switch_enet_init(struct net_device *dev,
fep->index = slot;
fep->hwp = fecp;
#ifdef CONFIG_ARCH_MVF
- fep->hwentry = (eswAddrTable_t *)ioremap(plat->switch_hw[1], SZ_4K);
+ fep->hwentry = (eswAddrTable_t *)ioremap(plat->switch_hw[1], SZ_16K);
#else
fep->hwentry = (eswAddrTable_t *)plat->switch_hw[1];
#endif
@@ -4108,6 +4133,7 @@ int __init switch_enet_init(struct net_device *dev,
for (j = 0; j < SWITCH_ENET_RX_FRPPG; j++) {
bdp->cbd_sc = BD_ENET_RX_EMPTY;
bdp->cbd_bufaddr = __pa(mem_addr);
+
#ifdef CONFIG_ENHANCED_BD
bdp->bdu = 0x00000000;
bdp->ebd_status = RX_BD_INT;
@@ -4185,6 +4211,7 @@ int __init switch_enet_init(struct net_device *dev,
fecp->switch_imask = MCF_ESW_IMR_RXB | MCF_ESW_IMR_TXB |
MCF_ESW_IMR_RXF | MCF_ESW_IMR_TXF;
esw_clear_atable(fep);
+
/* Queue up command to detect the PHY and initialize the
* remainder of the interface.
*/
@@ -4214,14 +4241,10 @@ switch_restart(struct net_device *dev, int duplex)
fep = netdev_priv(dev);
fecp = fep->hwp;
plat = fep->pdev->dev.platform_data;
+
/* Whack a reset. We should wait for this.*/
-#if 0
- MCF_FEC_ECR0 = 1;
- MCF_FEC_ECR1 = 1;
-#else
writel(1, fep->fec[0] + FEC_ECNTRL);
writel(1, fep->fec[1] + FEC_ECNTRL);
-#endif
udelay(10);
@@ -4343,6 +4366,11 @@ switch_stop(struct net_device *dev)
udelay(10);
}
+static int mvf_fec_mdio_reset(struct mii_bus *bus)
+{
+ return 0;
+}
+
static int fec_mdio_register(struct net_device *dev,
int slot)
{
@@ -4366,8 +4394,9 @@ static int fec_mdio_register(struct net_device *dev,
"support more than 2 mii bus\n");
}
- fep->mdio_bus->read = &mvf_fec_mdio_read;
- fep->mdio_bus->write = &mvf_fec_mdio_write;
+ fep->mdio_bus->read = mvf_fec_mdio_read;
+ fep->mdio_bus->write = mvf_fec_mdio_write;
+ fep->mdio_bus->reset = mvf_fec_mdio_reset;
fep->mdio_bus->priv = dev;
err = mdiobus_register(fep->mdio_bus);
if (err) {
@@ -4387,7 +4416,6 @@ static int __init eth_switch_probe(struct platform_device *pdev)
struct net_device *dev;
int i, err;
struct switch_enet_private *fep;
-
struct switch_platform_private *chip;
struct task_struct *task;
@@ -4401,6 +4429,23 @@ static int __init eth_switch_probe(struct platform_device *pdev)
(unsigned int)chip);
return err;
}
+ chip->fec0 = clk_get(&pdev->dev, "fec_clk");
+ chip->fec1 = clk_get(&pdev->dev, "fec1_clk");
+ chip->l2sw = clk_get(&pdev->dev, "eth_l2_sw_clk");
+
+ if ( IS_ERR( chip->fec0 )) {
+ dev_err(&pdev->dev, "Could not get FEC0 clock \n");
+ return PTR_ERR( chip->fec0);
+ }
+ if ( IS_ERR( chip->fec1 )) {
+ dev_err(&pdev->dev, "Could not get FEC1 clock \n");
+ return PTR_ERR( chip->fec1);
+ }
+ if ( IS_ERR( chip->l2sw )) {
+ dev_err(&pdev->dev, "Could not get L2 Switch clock \n");
+ return PTR_ERR( chip->l2sw);
+ }
+
chip->pdev = pdev;
chip->num_slots = SWITCH_MAX_PORTS;
@@ -4449,6 +4494,7 @@ static int __init eth_switch_probe(struct platform_device *pdev)
return -ENOMEM;
}
#endif
+
/* setup timer for Learning Aging function */
init_timer(&fep->timer_aging);
fep->timer_aging.function = l2switch_aging_timer;
@@ -4499,6 +4545,9 @@ static int eth_switch_remove(struct platform_device *pdev)
del_timer_sync(&fep->timer_aging);
}
+ clk_disable( chip->fec0);
+ clk_disable( chip->fec1);
+ clk_disable( chip->l2sw);
platform_set_drvdata(pdev, NULL);
kfree(chip);