Commit be1f6b36 authored by Pekka Pietikäinen's avatar Pekka Pietikäinen Committed by Jeff Garzik

[netdrvr b44] tons of fixes. should work now.

parent cd8e2b44
/* b44.c: Broadcom 4400 device driver.
*
* Copyright (C) 2002 David S. Miller (davem@redhat.com)
* Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
*/
#include <linux/kernel.h>
......@@ -14,6 +15,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#include <asm/io.h>
......@@ -23,8 +25,8 @@
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.6"
#define DRV_MODULE_RELDATE "Nov 11, 2002"
#define DRV_MODULE_VERSION "0.9"
#define DRV_MODULE_RELDATE "Jul 14, 2003"
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
......@@ -78,6 +80,15 @@ MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
static int b44_debug = -1; /* -1 == use B44_DEF_MSG_ENABLE as value */
#ifndef PCI_DEVICE_ID_BCM4401
#define PCI_DEVICE_ID_BCM4401 0x4401
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#define IRQ_RETVAL(x)
#define irqreturn_t void
#endif
static struct pci_device_id b44_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
......@@ -259,7 +270,7 @@ static int ssb_is_core_up(struct b44 *bp)
== SBTMSLOW_CLOCK);
}
static void __b44_cam_write(struct b44 *bp, char *data, int index)
static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
{
u32 val;
......@@ -521,7 +532,7 @@ static void b44_check_phy(struct b44 *bp)
/* Link now up */
netif_carrier_on(bp->dev);
b44_link_report(bp);
} else if (netif_carrier_ok(bp->dev)) {
} else if (netif_carrier_ok(bp->dev) && !(bmsr & BMSR_LSTATUS)) {
/* Link now down */
netif_carrier_off(bp->dev);
b44_link_report(bp);
......@@ -650,8 +661,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
src_map = &bp->rx_buffers[src_idx];
dest_map->skb = src_map->skb;
rh = (struct rx_header *)
(src_map->skb->data - bp->rx_offset);
rh = (struct rx_header *) src_map->skb->data;
rh->len = 0;
rh->flags = 0;
pci_unmap_addr_set(dest_map, mapping,
......@@ -660,9 +670,12 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
ctrl = src_desc->ctrl;
if (dest_idx == (B44_RX_RING_SIZE - 1))
ctrl |= cpu_to_le32(DESC_CTRL_EOT);
else
ctrl &= cpu_to_le32(~DESC_CTRL_EOT);
dest_desc->ctrl = ctrl;
dest_desc->addr = src_desc->addr;
src_map->skb = NULL;
}
static int b44_rx(struct b44 *bp, int budget)
......@@ -685,7 +698,7 @@ static int b44_rx(struct b44 *bp, int budget)
pci_dma_sync_single(bp->pdev, map,
RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
rh = (struct rx_header *) (skb->data - bp->rx_offset);
rh = (struct rx_header *) skb->data;
len = cpu_to_le16(rh->len);
if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) ||
(rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) {
......@@ -718,7 +731,9 @@ static int b44_rx(struct b44 *bp, int budget)
goto drop_it;
pci_unmap_single(bp->pdev, map,
skb_size, PCI_DMA_FROMDEVICE);
skb_put(skb, len);
/* Leave out rx_header */
skb_put(skb, len+bp->rx_offset);
skb_pull(skb,bp->rx_offset);
} else {
struct sk_buff *copy_skb;
......@@ -730,8 +745,8 @@ static int b44_rx(struct b44 *bp, int budget)
copy_skb->dev = bp->dev;
skb_reserve(copy_skb, 2);
skb_put(copy_skb, len);
/* DMA sync done above */
memcpy(copy_skb->data, skb->data, len);
/* DMA sync done above, copy just the actual packet */
memcpy(copy_skb->data, skb->data+bp->rx_offset, len);
skb = copy_skb;
}
......@@ -748,6 +763,7 @@ static int b44_rx(struct b44 *bp, int budget)
}
bp->rx_cons = cons;
bw32(B44_DMARX_PTR, cons * sizeof(struct dma_desc));
return received;
}
......@@ -764,6 +780,7 @@ static int b44_poll(struct net_device *netdev, int *budget)
b44_tx(bp);
/* spin_unlock(&bp->tx_lock); */
}
spin_unlock_irq(&bp->lock);
done = 1;
if (bp->istat & ISTAT_RX) {
......@@ -783,10 +800,12 @@ static int b44_poll(struct net_device *netdev, int *budget)
}
if (bp->istat & ISTAT_ERRORS) {
spin_lock_irq(&bp->lock);
b44_halt(bp);
b44_init_rings(bp);
b44_init_hw(bp);
netif_wake_queue(bp->dev);
spin_unlock_irq(&bp->lock);
done = 1;
}
......@@ -794,7 +813,6 @@ static int b44_poll(struct net_device *netdev, int *budget)
netif_rx_complete(netdev);
b44_enable_ints(bp);
}
spin_unlock_irq(&bp->lock);
return (done ? 0 : 1);
}
......@@ -885,7 +903,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
ctrl |= DESC_CTRL_EOT;
bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl);
bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping);
bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
entry = NEXT_TX(entry);
......@@ -1173,8 +1191,8 @@ static int b44_init_hw(struct b44 *bp)
__b44_set_rx_mode(bp->dev);
/* MTU + eth header + possible VLAN tag + struct rx_header */
bw32(B44_RXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + 24);
bw32(B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + 24);
bw32(B44_RXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
bw32(B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
bw32(B44_TX_WMARK, 56); /* XXX magic */
bw32(B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
......@@ -1184,6 +1202,7 @@ static int b44_init_hw(struct b44 *bp)
bw32(B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
bw32(B44_DMARX_PTR, bp->rx_pending);
bp->rx_prod = bp->rx_pending;
bw32(B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
......@@ -1345,6 +1364,8 @@ static void __b44_set_rx_mode(struct net_device *dev)
__b44_load_mcast(bp, dev);
bw32(B44_RXCONFIG, val);
val = br32(B44_CAM_CTRL);
bw32(B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
}
}
......@@ -1678,8 +1699,9 @@ static int __devinit b44_get_invariants(struct b44 *bp)
bp->core_unit = ssb_core_unit(bp);
bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0);
bp->flags |= B44_FLAG_BUGGY_TXPTR;
/* XXX - really required?
bp->flags |= B44_FLAG_BUGGY_TXPTR;
*/
out:
return err;
}
......
......@@ -142,7 +142,7 @@
#define MDIO_OP_READ 2
#define MDIO_DATA_SB_MASK 0xc0000000 /* Start Bits */
#define MDIO_DATA_SB_SHIFT 30
#define MDIO_DATA_SB_START 0x10000000 /* Start Of Frame */
#define MDIO_DATA_SB_START 0x40000000 /* Start Of Frame */
#define B44_EMAC_IMASK 0x0418UL /* EMAC Interrupt Mask */
#define B44_EMAC_ISTAT 0x041CUL /* EMAC Interrupt Status */
#define EMAC_INT_MII 0x00000001 /* MII MDIO Interrupt */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment