/*
* Atheros AR71xx built-in ethernet mac driver
*
- * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*
* Based on Atheros' AG7100 driver
ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
}
-#define AR71XX_MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \
- MAC_CFG1_SRX | MAC_CFG1_STX)
-#define AR71XX_FIFO_CFG5_INIT 0x0007ffef
-
-#define AR91XX_MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \
- MAC_CFG1_SRX | MAC_CFG1_STX | \
- MAC_CFG1_TFC | MAC_CFG1_RFC)
-#define AR91XX_FIFO_CFG5_INIT 0x0007efef
-
-#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
-
static void ag71xx_dma_reset(struct ag71xx *ag)
{
int i;
ag71xx_dump_dma_regs(ag);
}
+#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \
+ MAC_CFG1_SRX | MAC_CFG1_STX)
+
+#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
+
+#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
+ FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
+ FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
+ FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
+ FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
+ FIFO_CFG4_VT)
+
+#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
+ FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
+ FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
+ FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
+ FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
+ FIFO_CFG5_17 | FIFO_CFG5_SF)
+
static void ag71xx_hw_init(struct ag71xx *ag)
{
struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
mdelay(100);
/* setup MAC configuration registers */
- ag71xx_wr(ag, AG71XX_REG_MAC_CFG1,
- pdata->is_ar91xx ? AR91XX_MAC_CFG1_INIT : AR71XX_MAC_CFG1_INIT);
+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT);
ag71xx_sb(ag, AG71XX_REG_MAC_CFG2,
MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
- ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, 0x0000ffff);
- ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5,
- pdata->is_ar91xx ? AR91XX_FIFO_CFG5_INIT
- : AR71XX_FIFO_CFG5_INIT);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);
ag71xx_dma_reset(ag);
}
if (!ag71xx_desc_empty(desc))
goto err_drop;
+ ag71xx_add_ar8216_header(ag, skb);
+
if (skb->len <= 0) {
DBG("%s: packet len is too small\n", ag->dev->name);
goto err_drop;
skb_put(skb, pktlen);
skb->dev = dev;
- skb->protocol = eth_type_trans(skb, dev);
skb->ip_summed = CHECKSUM_NONE;
- netif_receive_skb(skb);
-
dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += pktlen;
+ if (ag71xx_remove_ar8216_header(ag, skb) != 0) {
+ dev->stats.rx_dropped++;
+ kfree_skb(skb);
+ } else {
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_receive_skb(skb);
+ }
+
ring->buf[i].skb = NULL;
done++;
spin_lock_irqsave(&ag->lock, flags);
ag71xx_int_enable(ag, AG71XX_INT_POLL);
spin_unlock_irqrestore(&ag->lock, flags);
- return 0;
+ return done;
}
more:
DBG("%s: stay in polling mode, done=%d, limit=%d\n",
dev->name, done, limit);
- return 1;
+ return done;
oom:
if (netif_msg_rx_err(ag))
ag = netdev_priv(dev);
ag->pdev = pdev;
ag->dev = dev;
- ag->mii_bus = &ag71xx_mdio_bus->mii_bus;
+ ag->mii_bus = ag71xx_mdio_bus->mii_bus;
ag->msg_enable = netif_msg_init(ag71xx_debug,
AG71XX_DEFAULT_MSG_ENABLE);
spin_lock_init(&ag->lock);
ag->oom_timer.data = (unsigned long) dev;
ag->oom_timer.function = ag71xx_oom_timer_handler;
- netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT);
+ memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN);
- if (is_valid_ether_addr(pdata->mac_addr))
- memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN);
- else {
- dev->dev_addr[0] = 0xde;
- dev->dev_addr[1] = 0xad;
- get_random_bytes(&dev->dev_addr[2], 3);
- dev->dev_addr[5] = pdev->id & 0xff;
- }
+ netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT);
err = register_netdev(dev);
if (err) {