From be1f6b36f5871417f3e1fb26c63b3b2709aa0af7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pekka=20Pietik=C3=A4inen?= Date: Sat, 19 Jul 2003 04:36:13 -0400 Subject: [PATCH] [netdrvr b44] tons of fixes. should work now. --- drivers/net/b44.c | 54 +++++++++++++++++++++++++++++++++-------------- drivers/net/b44.h | 2 +- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 3b7d0f98f418f..81ec0344e5c17 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -1,6 +1,7 @@ /* b44.c: Broadcom 4400 device driver. * * Copyright (C) 2002 David S. Miller (davem@redhat.com) + * Fixed by Pekka Pietikainen (pp@ee.oulu.fi) */ #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include @@ -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; } diff --git a/drivers/net/b44.h b/drivers/net/b44.h index c06416d3d7a61..1686505558cdd 100644 --- a/drivers/net/b44.h +++ b/drivers/net/b44.h @@ -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 */ -- 2.53.0