*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
*/
#define DRV_NAME "emac"
-#define DRV_VERSION "3.53"
+#define DRV_VERSION "3.54"
#define DRV_DESC "PPC 4xx OCP EMAC driver"
MODULE_DESCRIPTION(DRV_DESC);
#define PHY_POLL_LINK_ON HZ
#define PHY_POLL_LINK_OFF (HZ / 5)
+/* Graceful stop timeouts in us.
+ * We should allow up to 1 frame time (full-duplex, ignoring collisions)
+ */
+#define STOP_TIMEOUT_10 1230
+#define STOP_TIMEOUT_100 124
+#define STOP_TIMEOUT_1000 13
+#define STOP_TIMEOUT_1000_JUMBO 73
+
/* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */
static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {
"rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum",
"tx_errors"
};
-static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t emac_irq(int irq, void *dev_instance);
static void emac_clean_tx_ring(struct ocp_enet_private *dev);
static inline int emac_phy_supports_gige(int phy_mode)
static inline void emac_tx_enable(struct ocp_enet_private *dev)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
unsigned long flags;
u32 r;
static void emac_tx_disable(struct ocp_enet_private *dev)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
unsigned long flags;
u32 r;
r = in_be32(&p->mr0);
if (r & EMAC_MR0_TXE) {
- int n = 300;
+ int n = dev->stop_timeout;
out_be32(&p->mr0, r & ~EMAC_MR0_TXE);
- while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n)
+ while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) {
+ udelay(1);
--n;
+ }
if (unlikely(!n))
emac_report_timeout_error(dev, "TX disable timeout");
}
static void emac_rx_enable(struct ocp_enet_private *dev)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
unsigned long flags;
u32 r;
if (!(r & EMAC_MR0_RXE)) {
if (unlikely(!(r & EMAC_MR0_RXI))) {
/* Wait if previous async disable is still in progress */
- int n = 100;
- while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+ int n = dev->stop_timeout;
+ while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {
+ udelay(1);
--n;
+ }
if (unlikely(!n))
emac_report_timeout_error(dev,
"RX disable timeout");
static void emac_rx_disable(struct ocp_enet_private *dev)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
unsigned long flags;
u32 r;
r = in_be32(&p->mr0);
if (r & EMAC_MR0_RXE) {
- int n = 300;
+ int n = dev->stop_timeout;
out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
- while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+ while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {
+ udelay(1);
--n;
+ }
if (unlikely(!n))
emac_report_timeout_error(dev, "RX disable timeout");
}
static inline void emac_rx_disable_async(struct ocp_enet_private *dev)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
unsigned long flags;
u32 r;
static int emac_reset(struct ocp_enet_private *dev)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
unsigned long flags;
int n = 20;
static void emac_hash_mc(struct ocp_enet_private *dev)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
u16 gaht[4] = { 0 };
struct dev_mc_list *dmi;
/* BHs disabled */
static int emac_configure(struct ocp_enet_private *dev)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
struct net_device *ndev = dev->ndev;
int gige;
u32 r;
/* Mode register */
r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;
if (dev->phy.duplex == DUPLEX_FULL)
- r |= EMAC_MR1_FDE;
+ r |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001;
+ dev->stop_timeout = STOP_TIMEOUT_10;
switch (dev->phy.speed) {
case SPEED_1000:
if (emac_phy_gpcs(dev->phy.mode)) {
r |= EMAC_MR1_MF_1000;
r |= EMAC_MR1_RFS_16K;
gige = 1;
-
- if (dev->ndev->mtu > ETH_DATA_LEN)
+
+ if (dev->ndev->mtu > ETH_DATA_LEN) {
r |= EMAC_MR1_JPSM;
+ dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO;
+ } else
+ dev->stop_timeout = STOP_TIMEOUT_1000;
break;
case SPEED_100:
r |= EMAC_MR1_MF_100;
+ dev->stop_timeout = STOP_TIMEOUT_100;
/* Fall through */
default:
r |= EMAC_MR1_RFS_4K;
static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
u32 r;
int n;
static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg,
u16 val)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
int n;
DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg,
static void emac_set_multicast_list(struct net_device *ndev)
{
struct ocp_enet_private *dev = ndev->priv;
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
u32 rmr = emac_iff2rmr(ndev);
DBG("%d: multicast %08x" NL, dev->def->index, rmr);
}
static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot,
- int flags)
+ gfp_t flags)
{
struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
if (unlikely(!skb))
struct sk_buff *skb)
{
#if defined(CONFIG_IBM_EMAC_TAH)
- if (skb->ip_summed == CHECKSUM_HW) {
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
++dev->stats.tx_packets_csum;
return EMAC_TX_CTRL_TAH_CSUM;
}
static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len)
{
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
struct net_device *ndev = dev->ndev;
/* Send the packet out */
}
/* Hard IRQ */
-static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t emac_irq(int irq, void *dev_instance)
{
struct ocp_enet_private *dev = dev_instance;
- struct emac_regs *p = dev->emacp;
+ struct emac_regs __iomem *p = dev->emacp;
struct ibm_emac_error_stats *st = &dev->estats;
u32 isr = in_be32(&p->isr);
DBG("%d: remove" NL, dev->def->index);
- ocp_set_drvdata(ocpdev, 0);
+ ocp_set_drvdata(ocpdev, NULL);
unregister_netdev(dev->ndev);
tah_fini(dev->tah_dev);
rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
zmii_fini(dev->zmii_dev, dev->zmii_input);
- emac_dbg_register(dev->def->index, 0);
+ emac_dbg_register(dev->def->index, NULL);
mal_unregister_commac(dev->mal, &dev->commac);
- iounmap((void *)dev->emacp);
+ iounmap(dev->emacp);
kfree(dev->ndev);
}
info->regdump_len = emac_ethtool_get_regs_len(ndev);
}
-static struct ethtool_ops emac_ethtool_ops = {
+static const struct ethtool_ops emac_ethtool_ops = {
.get_settings = emac_ethtool_get_settings,
.set_settings = emac_ethtool_set_settings,
.get_drvinfo = emac_ethtool_get_drvinfo,
goto out4;
/* Map EMAC regs */
- dev->emacp =
- (struct emac_regs *)ioremap(dev->def->paddr,
- sizeof(struct emac_regs));
+ dev->emacp = ioremap(dev->def->paddr, sizeof(struct emac_regs));
if (!dev->emacp) {
printk(KERN_ERR "emac%d: could not ioremap device registers!\n",
dev->def->index);
dev->phy.duplex = DUPLEX_FULL;
dev->phy.autoneg = AUTONEG_DISABLE;
dev->phy.pause = dev->phy.asym_pause = 0;
+ dev->stop_timeout = STOP_TIMEOUT_100;
init_timer(&dev->link_timer);
dev->link_timer.function = emac_link_timer;
dev->link_timer.data = (unsigned long)dev;
return 0;
out6:
- iounmap((void *)dev->emacp);
+ iounmap(dev->emacp);
out5:
tah_fini(dev->tah_dev);
out4: