mirror of https://github.com/hak5/openwrt-owl.git
parent
242439e532
commit
43f15e09a9
|
@ -136,7 +136,8 @@
|
||||||
#define AR2313_BUFSIZE (AR2313_MTU + ETH_HLEN + CRC_LEN + RX_OFFSET)
|
#define AR2313_BUFSIZE (AR2313_MTU + ETH_HLEN + CRC_LEN + RX_OFFSET)
|
||||||
|
|
||||||
#ifdef MODULE
|
#ifdef MODULE
|
||||||
MODULE_AUTHOR("Sameer Dekate <sdekate@arubanetworks.com>, Imre Kaloz <kaloz@openwrt.org>, Felix Fietkau <nbd@openwrt.org>");
|
MODULE_AUTHOR
|
||||||
|
("Sameer Dekate <sdekate@arubanetworks.com>, Imre Kaloz <kaloz@openwrt.org>, Felix Fietkau <nbd@openwrt.org>");
|
||||||
MODULE_DESCRIPTION("AR2313 Ethernet driver");
|
MODULE_DESCRIPTION("AR2313 Ethernet driver");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -144,7 +145,8 @@ MODULE_DESCRIPTION("AR2313 Ethernet driver");
|
||||||
|
|
||||||
// prototypes
|
// prototypes
|
||||||
static short armiiread(struct net_device *dev, short phy, short reg);
|
static short armiiread(struct net_device *dev, short phy, short reg);
|
||||||
static void armiiwrite(struct net_device *dev, short phy, short reg, short data);
|
static void armiiwrite(struct net_device *dev, short phy, short reg,
|
||||||
|
short data);
|
||||||
#ifdef TX_TIMEOUT
|
#ifdef TX_TIMEOUT
|
||||||
static void ar2313_tx_timeout(struct net_device *dev);
|
static void ar2313_tx_timeout(struct net_device *dev);
|
||||||
#endif
|
#endif
|
||||||
|
@ -168,7 +170,8 @@ int __init ar2313_probe(struct platform_device *pdev)
|
||||||
dev = alloc_etherdev(sizeof(struct ar2313_private));
|
dev = alloc_etherdev(sizeof(struct ar2313_private));
|
||||||
|
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
printk(KERN_ERR "ar2313: Unable to allocate net_device structure!\n");
|
printk(KERN_ERR
|
||||||
|
"ar2313: Unable to allocate net_device structure!\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +215,8 @@ int __init ar2313_probe(struct platform_device *pdev)
|
||||||
tasklet_init(&sp->rx_tasklet, rx_tasklet_func, (unsigned long) dev);
|
tasklet_init(&sp->rx_tasklet, rx_tasklet_func, (unsigned long) dev);
|
||||||
tasklet_disable(&sp->rx_tasklet);
|
tasklet_disable(&sp->rx_tasklet);
|
||||||
|
|
||||||
sp->eth_regs = ioremap_nocache(virt_to_phys(ar_eth_base), sizeof(*sp->eth_regs));
|
sp->eth_regs =
|
||||||
|
ioremap_nocache(virt_to_phys(ar_eth_base), sizeof(*sp->eth_regs));
|
||||||
if (!sp->eth_regs) {
|
if (!sp->eth_regs) {
|
||||||
printk("Can't remap eth registers\n");
|
printk("Can't remap eth registers\n");
|
||||||
return (-ENXIO);
|
return (-ENXIO);
|
||||||
|
@ -226,14 +230,18 @@ int __init ar2313_probe(struct platform_device *pdev)
|
||||||
if (virt_to_phys(ar_eth_base) == virt_to_phys(sp->phy_regs))
|
if (virt_to_phys(ar_eth_base) == virt_to_phys(sp->phy_regs))
|
||||||
sp->phy_regs = sp->eth_regs;
|
sp->phy_regs = sp->eth_regs;
|
||||||
else {
|
else {
|
||||||
sp->phy_regs = ioremap_nocache(virt_to_phys(sp->cfg->phy_base), sizeof(*sp->phy_regs));
|
sp->phy_regs =
|
||||||
|
ioremap_nocache(virt_to_phys(sp->cfg->phy_base),
|
||||||
|
sizeof(*sp->phy_regs));
|
||||||
if (!sp->phy_regs) {
|
if (!sp->phy_regs) {
|
||||||
printk("Can't remap phy registers\n");
|
printk("Can't remap phy registers\n");
|
||||||
return (-ENXIO);
|
return (-ENXIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sp->dma_regs = ioremap_nocache(virt_to_phys(ar_eth_base + 0x1000), sizeof(*sp->dma_regs));
|
sp->dma_regs =
|
||||||
|
ioremap_nocache(virt_to_phys(ar_eth_base + 0x1000),
|
||||||
|
sizeof(*sp->dma_regs));
|
||||||
dev->base_addr = (unsigned int) sp->dma_regs;
|
dev->base_addr = (unsigned int) sp->dma_regs;
|
||||||
if (!sp->dma_regs) {
|
if (!sp->dma_regs) {
|
||||||
printk("Can't remap DMA registers\n");
|
printk("Can't remap DMA registers\n");
|
||||||
|
@ -267,8 +275,7 @@ int __init ar2313_probe(struct platform_device *pdev)
|
||||||
printk("%s: %s: %02x:%02x:%02x:%02x:%02x:%02x, irq %d\n",
|
printk("%s: %s: %02x:%02x:%02x:%02x:%02x:%02x, irq %d\n",
|
||||||
dev->name, sp->name,
|
dev->name, sp->name,
|
||||||
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
|
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
|
||||||
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5],
|
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], dev->irq);
|
||||||
dev->irq);
|
|
||||||
|
|
||||||
/* start link poll timer */
|
/* start link poll timer */
|
||||||
ar2313_setup_timer(dev);
|
ar2313_setup_timer(dev);
|
||||||
|
@ -283,7 +290,8 @@ static void ar2313_dump_regs(struct net_device *dev)
|
||||||
struct ar2313_private *sp = (struct ar2313_private *) dev->priv;
|
struct ar2313_private *sp = (struct ar2313_private *) dev->priv;
|
||||||
|
|
||||||
ptr = (unsigned int *) sp->eth_regs;
|
ptr = (unsigned int *) sp->eth_regs;
|
||||||
for(i=0; i< (sizeof(ETHERNET_STRUCT)/ sizeof(unsigned int)); i++, ptr++) {
|
for (i = 0; i < (sizeof(ETHERNET_STRUCT) / sizeof(unsigned int));
|
||||||
|
i++, ptr++) {
|
||||||
printk("ENET: %08x = %08x\n", (int) ptr, *ptr);
|
printk("ENET: %08x = %08x\n", (int) ptr, *ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,8 +314,7 @@ static void ar2313_dump_regs(struct net_device *dev)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TX_TIMEOUT
|
#ifdef TX_TIMEOUT
|
||||||
static void
|
static void ar2313_tx_timeout(struct net_device *dev)
|
||||||
ar2313_tx_timeout(struct net_device *dev)
|
|
||||||
{
|
{
|
||||||
struct ar2313_private *sp = (struct ar2313_private *) dev->priv;
|
struct ar2313_private *sp = (struct ar2313_private *) dev->priv;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -322,8 +329,7 @@ ar2313_tx_timeout(struct net_device *dev)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DEBUG_MC
|
#if DEBUG_MC
|
||||||
static void
|
static void printMcList(struct net_device *dev)
|
||||||
printMcList(struct net_device *dev)
|
|
||||||
{
|
{
|
||||||
struct dev_mc_list *list = dev->mc_list;
|
struct dev_mc_list *list = dev->mc_list;
|
||||||
int num = 0, i;
|
int num = 0, i;
|
||||||
|
@ -342,8 +348,7 @@ printMcList(struct net_device *dev)
|
||||||
* Set or clear the multicast filter for this adaptor.
|
* Set or clear the multicast filter for this adaptor.
|
||||||
* THIS IS ABSOLUTE CRAP, disabled
|
* THIS IS ABSOLUTE CRAP, disabled
|
||||||
*/
|
*/
|
||||||
static void
|
static void ar2313_multicast_list(struct net_device *dev)
|
||||||
ar2313_multicast_list(struct net_device *dev)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Always listen to broadcasts and
|
* Always listen to broadcasts and
|
||||||
|
@ -363,7 +368,8 @@ ar2313_multicast_list(struct net_device *dev)
|
||||||
if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) {
|
if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) {
|
||||||
#if DEBUG_MC
|
#if DEBUG_MC
|
||||||
printMcList(dev);
|
printMcList(dev);
|
||||||
printk("%s: all MULTICAST mc_count %d\n", __FUNCTION__, dev->mc_count);
|
printk("%s: all MULTICAST mc_count %d\n", __FUNCTION__,
|
||||||
|
dev->mc_count);
|
||||||
#endif
|
#endif
|
||||||
recognise |= MAC_CONTROL_PM; /* all multicast */
|
recognise |= MAC_CONTROL_PM; /* all multicast */
|
||||||
} else if (dev->mc_count > 0) {
|
} else if (dev->mc_count > 0) {
|
||||||
|
@ -374,7 +380,8 @@ ar2313_multicast_list(struct net_device *dev)
|
||||||
recognise |= MAC_CONTROL_PM; /* for the time being */
|
recognise |= MAC_CONTROL_PM; /* for the time being */
|
||||||
}
|
}
|
||||||
#if DEBUG_MC
|
#if DEBUG_MC
|
||||||
printk("%s: setting %08x to %08x\n", __FUNCTION__, (int)sp->eth_regs, recognise);
|
printk("%s: setting %08x to %08x\n", __FUNCTION__, (int) sp->eth_regs,
|
||||||
|
recognise);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sp->eth_regs->mac_control = recognise;
|
sp->eth_regs->mac_control = recognise;
|
||||||
|
@ -468,7 +475,8 @@ static int ar2313_allocate_descriptors(struct net_device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = (sizeof(ar2313_descr_t) * (AR2313_DESCR_ENTRIES * AR2313_QUEUES));
|
size =
|
||||||
|
(sizeof(ar2313_descr_t) * (AR2313_DESCR_ENTRIES * AR2313_QUEUES));
|
||||||
space = kmalloc(size, GFP_KERNEL);
|
space = kmalloc(size, GFP_KERNEL);
|
||||||
if (space == NULL)
|
if (space == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -493,7 +501,9 @@ static int ar2313_allocate_descriptors(struct net_device *dev)
|
||||||
td->status = 0;
|
td->status = 0;
|
||||||
td->devcs = DMA_TX1_CHAINED;
|
td->devcs = DMA_TX1_CHAINED;
|
||||||
td->addr = 0;
|
td->addr = 0;
|
||||||
td->descr = virt_to_phys(&sp->tx_ring[(j+1) & (AR2313_DESCR_ENTRIES-1)]);
|
td->descr =
|
||||||
|
virt_to_phys(&sp->
|
||||||
|
tx_ring[(j + 1) & (AR2313_DESCR_ENTRIES - 1)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -512,8 +522,10 @@ static void ar2313_init_cleanup(struct net_device *dev)
|
||||||
|
|
||||||
ar2313_free_descriptors(dev);
|
ar2313_free_descriptors(dev);
|
||||||
|
|
||||||
if (sp->eth_regs) iounmap((void*)sp->eth_regs);
|
if (sp->eth_regs)
|
||||||
if (sp->dma_regs) iounmap((void*)sp->dma_regs);
|
iounmap((void *) sp->eth_regs);
|
||||||
|
if (sp->dma_regs)
|
||||||
|
iounmap((void *) sp->dma_regs);
|
||||||
|
|
||||||
if (sp->rx_skb) {
|
if (sp->rx_skb) {
|
||||||
for (j = 0; j < AR2313_DESCR_ENTRIES; j++) {
|
for (j = 0; j < AR2313_DESCR_ENTRIES; j++) {
|
||||||
|
@ -582,7 +594,8 @@ static void ar2313_check_link(struct net_device *dev)
|
||||||
phyData = armiiread(dev, sp->phy, MII_BMSR);
|
phyData = armiiread(dev, sp->phy, MII_BMSR);
|
||||||
if (sp->phyData != phyData) {
|
if (sp->phyData != phyData) {
|
||||||
if (phyData & BMSR_LSTATUS) {
|
if (phyData & BMSR_LSTATUS) {
|
||||||
/* link is present, ready link partner ability to deterine duplexity */
|
/* link is present, ready link partner ability to deterine
|
||||||
|
duplexity */
|
||||||
int duplex = 0;
|
int duplex = 0;
|
||||||
u16 reg;
|
u16 reg;
|
||||||
|
|
||||||
|
@ -597,17 +610,19 @@ static void ar2313_check_link(struct net_device *dev)
|
||||||
duplex = (reg & BMCR_FULLDPLX) ? 1 : 0;
|
duplex = (reg & BMCR_FULLDPLX) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_INFO "%s: Configuring MAC for %s duplex\n", dev->name,
|
printk(KERN_INFO "%s: Configuring MAC for %s duplex\n",
|
||||||
(duplex)? "full":"half");
|
dev->name, (duplex) ? "full" : "half");
|
||||||
|
|
||||||
if (duplex) {
|
if (duplex) {
|
||||||
/* full duplex */
|
/* full duplex */
|
||||||
sp->eth_regs->mac_control = ((sp->eth_regs->mac_control | MAC_CONTROL_F) &
|
sp->eth_regs->mac_control =
|
||||||
~MAC_CONTROL_DRO);
|
((sp->eth_regs->
|
||||||
|
mac_control | MAC_CONTROL_F) & ~MAC_CONTROL_DRO);
|
||||||
} else {
|
} else {
|
||||||
/* half duplex */
|
/* half duplex */
|
||||||
sp->eth_regs->mac_control = ((sp->eth_regs->mac_control | MAC_CONTROL_DRO) &
|
sp->eth_regs->mac_control =
|
||||||
~MAC_CONTROL_F);
|
((sp->eth_regs->
|
||||||
|
mac_control | MAC_CONTROL_DRO) & ~MAC_CONTROL_F);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* no link */
|
/* no link */
|
||||||
|
@ -617,8 +632,7 @@ static void ar2313_check_link(struct net_device *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int ar2313_reset_reg(struct net_device *dev)
|
||||||
ar2313_reset_reg(struct net_device *dev)
|
|
||||||
{
|
{
|
||||||
struct ar2313_private *sp = (struct ar2313_private *) dev->priv;
|
struct ar2313_private *sp = (struct ar2313_private *) dev->priv;
|
||||||
unsigned int ethsal, ethsah;
|
unsigned int ethsal, ethsah;
|
||||||
|
@ -635,17 +649,18 @@ ar2313_reset_reg(struct net_device *dev)
|
||||||
|
|
||||||
sp->dma_regs->bus_mode = (DMA_BUS_MODE_SWR);
|
sp->dma_regs->bus_mode = (DMA_BUS_MODE_SWR);
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
sp->dma_regs->bus_mode = ((32 << DMA_BUS_MODE_PBL_SHIFT) | DMA_BUS_MODE_BLE);
|
sp->dma_regs->bus_mode =
|
||||||
|
((32 << DMA_BUS_MODE_PBL_SHIFT) | DMA_BUS_MODE_BLE);
|
||||||
|
|
||||||
/* enable interrupts */
|
/* enable interrupts */
|
||||||
sp->dma_regs->intr_ena = (DMA_STATUS_AIS |
|
sp->dma_regs->intr_ena = (DMA_STATUS_AIS |
|
||||||
DMA_STATUS_NIS |
|
DMA_STATUS_NIS |
|
||||||
DMA_STATUS_RI |
|
DMA_STATUS_RI |
|
||||||
DMA_STATUS_TI |
|
DMA_STATUS_TI | DMA_STATUS_FBE);
|
||||||
DMA_STATUS_FBE);
|
|
||||||
sp->dma_regs->xmt_base = virt_to_phys(sp->tx_ring);
|
sp->dma_regs->xmt_base = virt_to_phys(sp->tx_ring);
|
||||||
sp->dma_regs->rcv_base = virt_to_phys(sp->rx_ring);
|
sp->dma_regs->rcv_base = virt_to_phys(sp->rx_ring);
|
||||||
sp->dma_regs->control = (DMA_CONTROL_SR | DMA_CONTROL_ST | DMA_CONTROL_SF);
|
sp->dma_regs->control =
|
||||||
|
(DMA_CONTROL_SR | DMA_CONTROL_ST | DMA_CONTROL_SF);
|
||||||
|
|
||||||
sp->eth_regs->flow_control = (FLOW_CONTROL_FCE);
|
sp->eth_regs->flow_control = (FLOW_CONTROL_FCE);
|
||||||
sp->eth_regs->vlan_tag = (0x8100);
|
sp->eth_regs->vlan_tag = (0x8100);
|
||||||
|
@ -698,7 +713,9 @@ static int ar2313_init(struct net_device *dev)
|
||||||
* Get the memory for the skb rings.
|
* Get the memory for the skb rings.
|
||||||
*/
|
*/
|
||||||
if (sp->rx_skb == NULL) {
|
if (sp->rx_skb == NULL) {
|
||||||
sp->rx_skb = kmalloc(sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES, GFP_KERNEL);
|
sp->rx_skb =
|
||||||
|
kmalloc(sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES,
|
||||||
|
GFP_KERNEL);
|
||||||
if (!(sp->rx_skb)) {
|
if (!(sp->rx_skb)) {
|
||||||
printk("%s: %s: rx_skb kmalloc failed\n",
|
printk("%s: %s: rx_skb kmalloc failed\n",
|
||||||
dev->name, __FUNCTION__);
|
dev->name, __FUNCTION__);
|
||||||
|
@ -709,7 +726,9 @@ static int ar2313_init(struct net_device *dev)
|
||||||
memset(sp->rx_skb, 0, sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES);
|
memset(sp->rx_skb, 0, sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES);
|
||||||
|
|
||||||
if (sp->tx_skb == NULL) {
|
if (sp->tx_skb == NULL) {
|
||||||
sp->tx_skb = kmalloc(sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES, GFP_KERNEL);
|
sp->tx_skb =
|
||||||
|
kmalloc(sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES,
|
||||||
|
GFP_KERNEL);
|
||||||
if (!(sp->tx_skb)) {
|
if (!(sp->tx_skb)) {
|
||||||
printk("%s: %s: tx_skb kmalloc failed\n",
|
printk("%s: %s: tx_skb kmalloc failed\n",
|
||||||
dev->name, __FUNCTION__);
|
dev->name, __FUNCTION__);
|
||||||
|
@ -749,7 +768,10 @@ static int ar2313_init(struct net_device *dev)
|
||||||
/*
|
/*
|
||||||
* Get the IRQ
|
* Get the IRQ
|
||||||
*/
|
*/
|
||||||
ecode = request_irq(dev->irq, &ar2313_interrupt, IRQF_SHARED | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, dev->name, dev);
|
ecode =
|
||||||
|
request_irq(dev->irq, &ar2313_interrupt,
|
||||||
|
IRQF_SHARED | IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
|
||||||
|
dev->name, dev);
|
||||||
if (ecode) {
|
if (ecode) {
|
||||||
printk(KERN_WARNING "%s: %s: Requested IRQ %d is busy\n",
|
printk(KERN_WARNING "%s: %s: Requested IRQ %d is busy\n",
|
||||||
dev->name, __FUNCTION__, dev->irq);
|
dev->name, __FUNCTION__, dev->irq);
|
||||||
|
@ -791,11 +813,11 @@ static void ar2313_load_rx_ring(struct net_device *dev, int nr_bufs)
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// partha: create additional room for the second GRE fragment
|
// partha: create additional room for the second GRE fragment
|
||||||
skb = alloc_skb(AR2313_BUFSIZE + 128, GFP_ATOMIC);
|
skb = alloc_skb(AR2313_BUFSIZE + 128, GFP_ATOMIC);
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
printk("\n\n\n\n %s: No memory in system\n\n\n\n", __FUNCTION__);
|
printk("\n\n\n\n %s: No memory in system\n\n\n\n",
|
||||||
|
__FUNCTION__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// partha: create additional room in the front for tx pkt capture
|
// partha: create additional room in the front for tx pkt capture
|
||||||
|
@ -814,7 +836,9 @@ static void ar2313_load_rx_ring(struct net_device *dev, int nr_bufs)
|
||||||
rd->devcs = ((AR2313_BUFSIZE << DMA_RX1_BSIZE_SHIFT) |
|
rd->devcs = ((AR2313_BUFSIZE << DMA_RX1_BSIZE_SHIFT) |
|
||||||
DMA_RX1_CHAINED);
|
DMA_RX1_CHAINED);
|
||||||
rd->addr = virt_to_phys(skb->data);
|
rd->addr = virt_to_phys(skb->data);
|
||||||
rd->descr = virt_to_phys(&sp->rx_ring[(idx+1) & (AR2313_DESCR_ENTRIES-1)]);
|
rd->descr =
|
||||||
|
virt_to_phys(&sp->
|
||||||
|
rx_ring[(idx + 1) & (AR2313_DESCR_ENTRIES - 1)]);
|
||||||
rd->status = DMA_RX_OWN;
|
rd->status = DMA_RX_OWN;
|
||||||
|
|
||||||
idx = DSC_NEXT(idx);
|
idx = DSC_NEXT(idx);
|
||||||
|
@ -822,7 +846,8 @@ static void ar2313_load_rx_ring(struct net_device *dev, int nr_bufs)
|
||||||
|
|
||||||
if (!i) {
|
if (!i) {
|
||||||
#if DEBUG_ERR
|
#if DEBUG_ERR
|
||||||
printk(KERN_INFO "Out of memory when allocating standard receive buffers\n");
|
printk(KERN_INFO
|
||||||
|
"Out of memory when allocating standard receive buffers\n");
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
} else {
|
} else {
|
||||||
sp->rx_skbprd = idx;
|
sp->rx_skbprd = idx;
|
||||||
|
@ -845,7 +870,8 @@ static int ar2313_rx_int(struct net_device *dev)
|
||||||
|
|
||||||
idx = sp->cur_rx;
|
idx = sp->cur_rx;
|
||||||
|
|
||||||
/* process at most the entire ring and then wait for another interrupt */
|
/* process at most the entire ring and then wait for another interrupt
|
||||||
|
*/
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
rxdesc = &sp->rx_ring[idx];
|
rxdesc = &sp->rx_ring[idx];
|
||||||
|
@ -860,7 +886,6 @@ static int ar2313_rx_int(struct net_device *dev)
|
||||||
rval = 1;
|
rval = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG_RX
|
#if DEBUG_RX
|
||||||
printk("index %d\n", idx);
|
printk("index %d\n", idx);
|
||||||
printk("RX status %08x\n", rxdesc->status);
|
printk("RX status %08x\n", rxdesc->status);
|
||||||
|
@ -878,12 +903,16 @@ static int ar2313_rx_int(struct net_device *dev)
|
||||||
sp->stats.rx_dropped++;
|
sp->stats.rx_dropped++;
|
||||||
|
|
||||||
/* add statistics counters */
|
/* add statistics counters */
|
||||||
if (status & DMA_RX_ERR_CRC) sp->stats.rx_crc_errors++;
|
if (status & DMA_RX_ERR_CRC)
|
||||||
if (status & DMA_RX_ERR_COL) sp->stats.rx_over_errors++;
|
sp->stats.rx_crc_errors++;
|
||||||
|
if (status & DMA_RX_ERR_COL)
|
||||||
|
sp->stats.rx_over_errors++;
|
||||||
if (status & DMA_RX_ERR_LENGTH)
|
if (status & DMA_RX_ERR_LENGTH)
|
||||||
sp->stats.rx_length_errors++;
|
sp->stats.rx_length_errors++;
|
||||||
if (status & DMA_RX_ERR_RUNT) sp->stats.rx_over_errors++;
|
if (status & DMA_RX_ERR_RUNT)
|
||||||
if (status & DMA_RX_ERR_DESC) sp->stats.rx_over_errors++;
|
sp->stats.rx_over_errors++;
|
||||||
|
if (status & DMA_RX_ERR_DESC)
|
||||||
|
sp->stats.rx_over_errors++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* alloc new buffer. */
|
/* alloc new buffer. */
|
||||||
|
@ -892,7 +921,8 @@ static int ar2313_rx_int(struct net_device *dev)
|
||||||
|
|
||||||
skb = sp->rx_skb[idx];
|
skb = sp->rx_skb[idx];
|
||||||
/* set skb */
|
/* set skb */
|
||||||
skb_put(skb, ((status >> DMA_RX_LEN_SHIFT) & 0x3fff) - CRC_LEN);
|
skb_put(skb,
|
||||||
|
((status >> DMA_RX_LEN_SHIFT) & 0x3fff) - CRC_LEN);
|
||||||
|
|
||||||
sp->stats.rx_bytes += skb->len;
|
sp->stats.rx_bytes += skb->len;
|
||||||
skb->protocol = eth_type_trans(skb, dev);
|
skb->protocol = eth_type_trans(skb, dev);
|
||||||
|
@ -940,9 +970,10 @@ static void ar2313_tx_int(struct net_device *dev)
|
||||||
txdesc = &sp->tx_ring[idx];
|
txdesc = &sp->tx_ring[idx];
|
||||||
|
|
||||||
#if DEBUG_TX
|
#if DEBUG_TX
|
||||||
printk("%s: TXINT: csm=%d idx=%d prd=%d status=%x devcs=%x addr=%08x descr=%x\n",
|
printk
|
||||||
dev->name, sp->tx_csm, idx, sp->tx_prd,
|
("%s: TXINT: csm=%d idx=%d prd=%d status=%x devcs=%x addr=%08x descr=%x\n",
|
||||||
txdesc->status, txdesc->devcs, txdesc->addr, txdesc->descr);
|
dev->name, sp->tx_csm, idx, sp->tx_prd, txdesc->status,
|
||||||
|
txdesc->devcs, txdesc->addr, txdesc->descr);
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
if ((status = txdesc->status) & DMA_TX_OWN) {
|
if ((status = txdesc->status) & DMA_TX_OWN) {
|
||||||
|
@ -950,7 +981,9 @@ static void ar2313_tx_int(struct net_device *dev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* done with this descriptor */
|
/* done with this descriptor */
|
||||||
dma_unmap_single(NULL, txdesc->addr, txdesc->devcs & DMA_TX1_BSIZE_MASK, DMA_TO_DEVICE);
|
dma_unmap_single(NULL, txdesc->addr,
|
||||||
|
txdesc->devcs & DMA_TX1_BSIZE_MASK,
|
||||||
|
DMA_TO_DEVICE);
|
||||||
txdesc->status = 0;
|
txdesc->status = 0;
|
||||||
|
|
||||||
if (status & DMA_TX_ERROR) {
|
if (status & DMA_TX_ERROR) {
|
||||||
|
@ -960,13 +993,11 @@ static void ar2313_tx_int(struct net_device *dev)
|
||||||
sp->stats.tx_fifo_errors++;
|
sp->stats.tx_fifo_errors++;
|
||||||
if (status & DMA_TX_ERR_HB)
|
if (status & DMA_TX_ERR_HB)
|
||||||
sp->stats.tx_heartbeat_errors++;
|
sp->stats.tx_heartbeat_errors++;
|
||||||
if(status & (DMA_TX_ERR_LOSS |
|
if (status & (DMA_TX_ERR_LOSS | DMA_TX_ERR_LINK))
|
||||||
DMA_TX_ERR_LINK))
|
|
||||||
sp->stats.tx_carrier_errors++;
|
sp->stats.tx_carrier_errors++;
|
||||||
if (status & (DMA_TX_ERR_LATE |
|
if (status & (DMA_TX_ERR_LATE |
|
||||||
DMA_TX_ERR_COL |
|
DMA_TX_ERR_COL |
|
||||||
DMA_TX_ERR_JABBER |
|
DMA_TX_ERR_JABBER | DMA_TX_ERR_DEFER))
|
||||||
DMA_TX_ERR_DEFER))
|
|
||||||
sp->stats.tx_aborted_errors++;
|
sp->stats.tx_aborted_errors++;
|
||||||
} else {
|
} else {
|
||||||
/* transmit OK */
|
/* transmit OK */
|
||||||
|
@ -986,8 +1017,7 @@ static void ar2313_tx_int(struct net_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void rx_tasklet_func(unsigned long data)
|
||||||
rx_tasklet_func(unsigned long data)
|
|
||||||
{
|
{
|
||||||
struct net_device *dev = (struct net_device *) data;
|
struct net_device *dev = (struct net_device *) data;
|
||||||
struct ar2313_private *sp = dev->priv;
|
struct ar2313_private *sp = dev->priv;
|
||||||
|
@ -998,8 +1028,7 @@ rx_tasklet_func(unsigned long data)
|
||||||
|
|
||||||
if (ar2313_rx_int(dev)) {
|
if (ar2313_rx_int(dev)) {
|
||||||
tasklet_hi_schedule(&sp->rx_tasklet);
|
tasklet_hi_schedule(&sp->rx_tasklet);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
spin_lock_irqsave(&sp->lock, flags);
|
spin_lock_irqsave(&sp->lock, flags);
|
||||||
sp->dma_regs->intr_ena |= DMA_STATUS_RI;
|
sp->dma_regs->intr_ena |= DMA_STATUS_RI;
|
||||||
|
@ -1007,8 +1036,7 @@ rx_tasklet_func(unsigned long data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void rx_schedule(struct net_device *dev)
|
||||||
rx_schedule(struct net_device *dev)
|
|
||||||
{
|
{
|
||||||
struct ar2313_private *sp = dev->priv;
|
struct ar2313_private *sp = dev->priv;
|
||||||
|
|
||||||
|
@ -1189,7 +1217,8 @@ static int ar2313_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
|
static int netdev_get_ecmd(struct net_device *dev,
|
||||||
|
struct ethtool_cmd *ecmd)
|
||||||
{
|
{
|
||||||
struct ar2313_private *np = dev->priv;
|
struct ar2313_private *np = dev->priv;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
@ -1254,7 +1283,8 @@ static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
|
static int netdev_set_ecmd(struct net_device *dev,
|
||||||
|
struct ethtool_cmd *ecmd)
|
||||||
{
|
{
|
||||||
struct ar2313_private *np = dev->priv;
|
struct ar2313_private *np = dev->priv;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
@ -1267,7 +1297,8 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ecmd->transceiver != XCVR_INTERNAL)
|
if (ecmd->transceiver != XCVR_INTERNAL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
|
if (ecmd->autoneg != AUTONEG_DISABLE
|
||||||
|
&& ecmd->autoneg != AUTONEG_ENABLE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
/* ignore phy_address, maxtxpkt, maxrxpkt for now */
|
/* ignore phy_address, maxtxpkt, maxrxpkt for now */
|
||||||
|
|
||||||
|
@ -1340,7 +1371,8 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
|
||||||
/* get link status */
|
/* get link status */
|
||||||
case ETHTOOL_GLINK:{
|
case ETHTOOL_GLINK:{
|
||||||
struct ethtool_value edata = { ETHTOOL_GLINK };
|
struct ethtool_value edata = { ETHTOOL_GLINK };
|
||||||
edata.data = (armiiread(dev, np->phy, MII_BMSR)&BMSR_LSTATUS) ? 1:0;
|
edata.data =
|
||||||
|
(armiiread(dev, np->phy, MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
|
||||||
if (copy_to_user(useraddr, &edata, sizeof(edata)))
|
if (copy_to_user(useraddr, &edata, sizeof(edata)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1375,12 +1407,14 @@ static int ar2313_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SIOCSIFHWADDR:
|
case SIOCSIFHWADDR:
|
||||||
if (copy_from_user(dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))
|
if (copy_from_user
|
||||||
|
(dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SIOCGIFHWADDR:
|
case SIOCGIFHWADDR:
|
||||||
if (copy_to_user(ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))
|
if (copy_to_user
|
||||||
|
(ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1401,8 +1435,7 @@ static struct net_device_stats *ar2313_get_stats(struct net_device *dev)
|
||||||
#define MII_ADDR(phy, reg) \
|
#define MII_ADDR(phy, reg) \
|
||||||
((reg << MII_ADDR_REG_SHIFT) | (phy << MII_ADDR_PHY_SHIFT))
|
((reg << MII_ADDR_REG_SHIFT) | (phy << MII_ADDR_PHY_SHIFT))
|
||||||
|
|
||||||
static short
|
static short armiiread(struct net_device *dev, short phy, short reg)
|
||||||
armiiread(struct net_device *dev, short phy, short reg)
|
|
||||||
{
|
{
|
||||||
struct ar2313_private *sp = (struct ar2313_private *) dev->priv;
|
struct ar2313_private *sp = (struct ar2313_private *) dev->priv;
|
||||||
volatile ETHERNET_STRUCT *ethernet = sp->phy_regs;
|
volatile ETHERNET_STRUCT *ethernet = sp->phy_regs;
|
||||||
|
@ -1422,4 +1455,3 @@ armiiwrite(struct net_device *dev, short phy, short reg, short data)
|
||||||
ethernet->mii_data = data << MII_DATA_SHIFT;
|
ethernet->mii_data = data << MII_DATA_SHIFT;
|
||||||
ethernet->mii_addr = MII_ADDR(phy, reg) | MII_ADDR_WRITE;
|
ethernet->mii_addr = MII_ADDR(phy, reg) | MII_ADDR_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,8 +105,7 @@ typedef struct {
|
||||||
* Frequently accessed variables are put at the beginning of the
|
* Frequently accessed variables are put at the beginning of the
|
||||||
* struct to help the compiler generate better/shorter code.
|
* struct to help the compiler generate better/shorter code.
|
||||||
*/
|
*/
|
||||||
struct ar2313_private
|
struct ar2313_private {
|
||||||
{
|
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
int version;
|
int version;
|
||||||
u32 mb[2];
|
u32 mb[2];
|
||||||
|
@ -184,7 +183,8 @@ static irqreturn_t ar2313_interrupt(int irq, void *dev_id);
|
||||||
static int ar2313_open(struct net_device *dev);
|
static int ar2313_open(struct net_device *dev);
|
||||||
static int ar2313_start_xmit(struct sk_buff *skb, struct net_device *dev);
|
static int ar2313_start_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||||
static int ar2313_close(struct net_device *dev);
|
static int ar2313_close(struct net_device *dev);
|
||||||
static int ar2313_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
|
static int ar2313_ioctl(struct net_device *dev, struct ifreq *ifr,
|
||||||
|
int cmd);
|
||||||
static void ar2313_init_cleanup(struct net_device *dev);
|
static void ar2313_init_cleanup(struct net_device *dev);
|
||||||
static int ar2313_setup_timer(struct net_device *dev);
|
static int ar2313_setup_timer(struct net_device *dev);
|
||||||
static void ar2313_link_timer_fn(unsigned long data);
|
static void ar2313_link_timer_fn(unsigned long data);
|
||||||
|
|
|
@ -85,13 +85,16 @@
|
||||||
#define MAC_CONTROL_HO AR_BIT(15) /* Hash only filtering */
|
#define MAC_CONTROL_HO AR_BIT(15) /* Hash only filtering */
|
||||||
#define MAC_CONTROL_PB AR_BIT(16) /* Pass Bad frames */
|
#define MAC_CONTROL_PB AR_BIT(16) /* Pass Bad frames */
|
||||||
#define MAC_CONTROL_IF AR_BIT(17) /* Inverse filtering */
|
#define MAC_CONTROL_IF AR_BIT(17) /* Inverse filtering */
|
||||||
#define MAC_CONTROL_PR AR_BIT(18) /* promiscuous mode (valid frames only) */
|
#define MAC_CONTROL_PR AR_BIT(18) /* promiscuous mode (valid frames
|
||||||
|
only) */
|
||||||
#define MAC_CONTROL_PM AR_BIT(19) /* pass multicast */
|
#define MAC_CONTROL_PM AR_BIT(19) /* pass multicast */
|
||||||
#define MAC_CONTROL_F AR_BIT(20) /* full-duplex */
|
#define MAC_CONTROL_F AR_BIT(20) /* full-duplex */
|
||||||
#define MAC_CONTROL_DRO AR_BIT(23) /* Disable Receive Own */
|
#define MAC_CONTROL_DRO AR_BIT(23) /* Disable Receive Own */
|
||||||
#define MAC_CONTROL_HBD AR_BIT(28) /* heart-beat disabled (MUST BE SET) */
|
#define MAC_CONTROL_HBD AR_BIT(28) /* heart-beat disabled (MUST BE
|
||||||
|
SET) */
|
||||||
#define MAC_CONTROL_BLE AR_BIT(30) /* big endian mode */
|
#define MAC_CONTROL_BLE AR_BIT(30) /* big endian mode */
|
||||||
#define MAC_CONTROL_RA AR_BIT(31) /* receive all (valid and invalid frames) */
|
#define MAC_CONTROL_RA AR_BIT(31) /* receive all (valid and invalid
|
||||||
|
frames) */
|
||||||
|
|
||||||
#define MII_ADDR_BUSY AR_BIT(0)
|
#define MII_ADDR_BUSY AR_BIT(0)
|
||||||
#define MII_ADDR_WRITE AR_BIT(1)
|
#define MII_ADDR_WRITE AR_BIT(1)
|
||||||
|
@ -137,4 +140,3 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
#endif // __ARUBA_DMA_H__
|
#endif // __ARUBA_DMA_H__
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue