#include <linux/dma-mapping.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
+#include <linux/bitops.h>
#include <asm/processor.h>
-#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/irq.h>
#define RGMII_PRIV(ocpdev) ((struct ibm_ocp_rgmii*)ocp_get_drvdata(ocpdev))
-static unsigned int rgmii_enable[] =
- { RGMII_RTBI, RGMII_RGMII, RGMII_TBI, RGMII_GMII };
+static unsigned int rgmii_enable[] = {
+ RGMII_RTBI,
+ RGMII_RGMII,
+ RGMII_TBI,
+ RGMII_GMII
+};
-static unsigned int rgmii_speed_mask[] = { 0,
- 0,
+static unsigned int rgmii_speed_mask[] = {
RGMII_MII2_SPDMASK,
RGMII_MII3_SPDMASK
};
-static unsigned int rgmii_speed100[] = { 0,
- 0,
+static unsigned int rgmii_speed100[] = {
RGMII_MII2_100MB,
RGMII_MII3_100MB
};
-static unsigned int rgmii_speed1000[] = { 0,
- 0,
+static unsigned int rgmii_speed1000[] = {
RGMII_MII2_1000MB,
RGMII_MII3_1000MB
};
~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)},
{ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)}
};
-static unsigned int mdi_enable[] =
- { ZMII_MDI0, ZMII_MDI1, ZMII_MDI2, ZMII_MDI3 };
+
+static unsigned int mdi_enable[] = {
+ ZMII_MDI0,
+ ZMII_MDI1,
+ ZMII_MDI2,
+ ZMII_MDI3
+};
static unsigned int zmii_speed = 0x0;
-static unsigned int zmii_speed100[] = { ZMII_MII0_100MB, ZMII_MII1_100MB };
+static unsigned int zmii_speed100[] = {
+ ZMII_MII0_100MB,
+ ZMII_MII1_100MB,
+ ZMII_MII2_100MB,
+ ZMII_MII3_100MB
+};
/* Since multiple EMACs share MDIO lines in various ways, we need
* to avoid re-using the same PHY ID in cases where the arch didn't
int emac_phy_read(struct net_device *dev, int mii_id, int reg)
{
+ int count;
uint32_t stacr;
struct ocp_enet_private *fep = dev->priv;
emac_t *emacp = fep->emacp;
emacp = fep->emacp;
}
- udelay(MDIO_DELAY);
+ count = 0;
+ while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
+ && (count++ < MDIO_DELAY))
+ udelay(1);
+ MDIO_DEBUG((" (count was %d)\n", count));
- if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) {
+ if ((stacr & EMAC_STACR_OC) == 0) {
printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name);
return -1;
}
out_be32(&emacp->em0stacr, stacr);
- udelay(MDIO_DELAY);
- stacr = in_be32(&emacp->em0stacr);
+ count = 0;
+ while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
+ && (count++ < MDIO_DELAY))
+ udelay(1);
+ MDIO_DEBUG((" (count was %d)\n", count));
if ((stacr & EMAC_STACR_OC) == 0) {
printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name);
void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data)
{
+ int count;
uint32_t stacr;
struct ocp_enet_private *fep = dev->priv;
emac_t *emacp = fep->emacp;
emacp = fep->emacp;
}
- udelay(MDIO_DELAY);
+ count = 0;
+ while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
+ && (count++ < MDIO_DELAY))
+ udelay(1);
+ MDIO_DEBUG((" (count was %d)\n", count));
- if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) {
+ if ((stacr & EMAC_STACR_OC) == 0) {
printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
return;
}
out_be32(&emacp->em0stacr, stacr);
- udelay(MDIO_DELAY);
+ count = 0;
+ while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
+ && (count++ < MDIO_DELAY))
+ udelay(1);
+ MDIO_DEBUG((" (count was %d)\n", count));
- if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0)
+ if ((stacr & EMAC_STACR_OC) == 0)
printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
/* Check for a write error */
static int emac_rx_clean(struct net_device *dev)
{
- int i, b, bnum, buf[6];
+ int i, b, bnum = 0, buf[6];
int error, frame_length;
struct ocp_enet_private *fep = dev->priv;
unsigned short ctrl;
PKT_DEBUG(("emac_start_xmit() stopping queue\n"));
netif_stop_queue(dev);
spin_unlock_irqrestore(&fep->lock, flags);
- restore_flags(flags);
return -EBUSY;
}
static int emac_adjust_to_link(struct ocp_enet_private *fep)
{
emac_t *emacp = fep->emacp;
- struct ibm_ocp_rgmii *rgmii;
unsigned long mode_reg;
int full_duplex, speed;
speed = fep->phy_mii.speed;
}
- if (fep->rgmii_dev)
- rgmii = RGMII_PRIV(fep->rgmii_dev);
/* set speed (default is 10Mb) */
switch (speed) {
case SPEED_1000:
mode_reg |= EMAC_M1_JUMBO_ENABLE | EMAC_M1_RFS_16K;
- if ((rgmii->mode[fep->rgmii_input] == RTBI)
- || (rgmii->mode[fep->rgmii_input] == TBI))
- mode_reg |= EMAC_M1_MF_1000GPCS;
- else
- mode_reg |= EMAC_M1_MF_1000MBPS;
- if (fep->rgmii_dev)
+ if (fep->rgmii_dev) {
+ struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(fep->rgmii_dev);
+
+ if ((rgmii->mode[fep->rgmii_input] == RTBI)
+ || (rgmii->mode[fep->rgmii_input] == TBI))
+ mode_reg |= EMAC_M1_MF_1000GPCS;
+ else
+ mode_reg |= EMAC_M1_MF_1000MBPS;
+
emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input,
1000);
+ }
break;
case SPEED_100:
mode_reg |= EMAC_M1_MF_100MBPS | EMAC_M1_RFS_4K;
/* Format the receive descriptor ring. */
ep->rx_slot = 0;
/* Default is MTU=1500 + Ethernet overhead */
- ep->rx_buffer_size = ENET_DEF_BUF_SIZE;
+ ep->rx_buffer_size = dev->mtu + ENET_HEADER_SIZE + ENET_FCS_SIZE;
emac_rx_fill(dev, 0);
if (ep->rx_slot != 0) {
printk(KERN_ERR
/* set frame gap */
out_be32(&emacp->em0ipgvr, CONFIG_IBM_EMAC_FGAP);
+
+ /* set VLAN Tag Protocol Identifier */
+ out_be32(&emacp->em0vtpid, 0x8100);
/* Init ring buffers */
emac_init_rings(fep->ndev);
.rxde = &emac_rxde_dev,
};
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static int emac_netpoll(struct net_device *ndev)
+{
+ emac_rxeob_dev((void *)ndev, 0);
+ emac_txeob_dev((void *)ndev, 0);
+ return 0;
+}
+#endif
+
static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
{
int deferred_init = 0;
SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
if (emacdata->tah_idx >= 0)
ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ ndev->poll_controller = emac_netpoll;
+#endif
SET_MODULE_OWNER(ndev);
static int __init emac_init(void)
{
- int rc;
-
printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n");
printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n");
skb_res);
skb_res = 2;
}
- rc = ocp_register_driver(&emac_driver);
- if (rc < 0) {
- ocp_unregister_driver(&emac_driver);
- return -ENODEV;
- }
- return 0;
+ return ocp_register_driver(&emac_driver);
}
static void __exit emac_exit(void)