Commit 74f54248 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 4c8aded7 d1b610e5
......@@ -71,6 +71,7 @@
#include <linux/udp.h>
#include <linux/cache.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
/* VLAN tagging feature enable/disable */
......
......@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
......@@ -27,8 +28,8 @@
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.94"
#define DRV_MODULE_RELDATE "May 4, 2004"
#define DRV_MODULE_VERSION "0.95"
#define DRV_MODULE_RELDATE "Aug 3, 2004"
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
......@@ -57,6 +58,7 @@
#define B44_DEF_TX_RING_PENDING (B44_TX_RING_SIZE - 1)
#define B44_TX_RING_BYTES (sizeof(struct dma_desc) * \
B44_TX_RING_SIZE)
#define B44_DMA_MASK 0x3fffffff
#define TX_RING_GAP(BP) \
(B44_TX_RING_SIZE - (BP)->tx_pending)
......@@ -67,6 +69,7 @@
#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1))
#define RX_PKT_BUF_SZ (1536 + bp->rx_offset + 64)
#define TX_PKT_BUF_SZ (B44_MAX_MTU + ETH_HLEN + 8)
/* minimum number of free TX descriptors required to wake up TX process */
#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4)
......@@ -74,13 +77,13 @@
static char version[] __devinitdata =
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
MODULE_AUTHOR("Florian Schirmer, Pekka Pietikainen, David S. Miller");
MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
MODULE_LICENSE("GPL");
MODULE_PARM(b44_debug, "i");
MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
static int b44_debug = -1; /* -1 == use B44_DEF_MSG_ENABLE as value */
module_param(b44_debug, int, 0);
MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
static struct pci_device_id b44_pci_tbl[] = {
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
......@@ -97,6 +100,10 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
static void b44_halt(struct b44 *);
static void b44_init_rings(struct b44 *);
static void b44_init_hw(struct b44 *);
static int b44_poll(struct net_device *dev, int *budget);
#ifdef CONFIG_NET_POLL_CONTROLLER
static void b44_poll_controller(struct net_device *dev);
#endif
static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
{
......@@ -141,41 +148,8 @@ static int b44_wait_bit(struct b44 *bp, unsigned long reg,
* interrupts disabled.
*/
#define SBID_SDRAM 0
#define SBID_PCI_MEM 1
#define SBID_PCI_CFG 2
#define SBID_PCI_DMA 3
#define SBID_SDRAM_SWAPPED 4
#define SBID_ENUM 5
#define SBID_REG_SDRAM 6
#define SBID_REG_ILINE20 7
#define SBID_REG_EMAC 8
#define SBID_REG_CODEC 9
#define SBID_REG_USB 10
#define SBID_REG_PCI 11
#define SBID_REG_MIPS 12
#define SBID_REG_EXTIF 13
#define SBID_EXTIF 14
#define SBID_EJTAG 15
#define SBID_MAX 16
static u32 ssb_get_addr(struct b44 *bp, u32 id, u32 instance)
{
switch (id) {
case SBID_PCI_DMA:
return 0x40000000;
case SBID_ENUM:
return 0x18000000;
case SBID_REG_EMAC:
return 0x18000000;
case SBID_REG_CODEC:
return 0x18001000;
case SBID_REG_PCI:
return 0x18002000;
default:
return 0;
};
}
#define SB_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */
#define BCM4400_PCI_CORE_ADDR 0x18002000 /* Address of PCI core on BCM4400 cards */
static u32 ssb_get_core_rev(struct b44 *bp)
{
......@@ -187,8 +161,7 @@ static u32 ssb_pci_setup(struct b44 *bp, u32 cores)
u32 bar_orig, pci_rev, val;
pci_read_config_dword(bp->pdev, SSB_BAR0_WIN, &bar_orig);
pci_write_config_dword(bp->pdev, SSB_BAR0_WIN,
ssb_get_addr(bp, SBID_REG_PCI, 0));
pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, BCM4400_PCI_CORE_ADDR);
pci_rev = ssb_get_core_rev(bp);
val = br32(bp, B44_SBINTVEC);
......@@ -649,10 +622,30 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (skb == NULL)
return -ENOMEM;
skb->dev = bp->dev;
mapping = pci_map_single(bp->pdev, skb->data,
RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
/* Hardware bug work-around, the chip is unable to do PCI DMA
to/from anything above 1GB :-( */
if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) {
/* Sigh... */
pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb);
skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA);
if (skb == NULL)
return -ENOMEM;
mapping = pci_map_single(bp->pdev, skb->data,
RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) {
pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb);
return -ENOMEM;
}
}
skb->dev = bp->dev;
skb_reserve(skb, bp->rx_offset);
rh = (struct rx_header *)
......@@ -930,6 +923,12 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
entry = bp->tx_prod;
mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
if(mapping+len > B44_DMA_MASK) {
/* Chip can't handle DMA to/from >1GB, use bounce buffer */
pci_unmap_single(bp->pdev, mapping, len,PCI_DMA_TODEVICE);
memcpy(bp->tx_bufs+entry*TX_PKT_BUF_SZ,skb->data,skb->len);
mapping = pci_map_single(bp->pdev, bp->tx_bufs+entry*TX_PKT_BUF_SZ, len, PCI_DMA_TODEVICE);
}
bp->tx_buffers[entry].skb = skb;
pci_unmap_addr_set(&bp->tx_buffers[entry], mapping, mapping);
......@@ -1077,6 +1076,11 @@ static void b44_free_consistent(struct b44 *bp)
bp->tx_ring, bp->tx_ring_dma);
bp->tx_ring = NULL;
}
if (bp->tx_bufs) {
pci_free_consistent(bp->pdev, B44_TX_RING_SIZE * TX_PKT_BUF_SZ,
bp->tx_bufs, bp->tx_bufs_dma);
bp->tx_bufs = NULL;
}
}
/*
......@@ -1099,6 +1103,12 @@ static int b44_alloc_consistent(struct b44 *bp)
goto out_err;
memset(bp->tx_buffers, 0, size);
size = B44_TX_RING_SIZE * TX_PKT_BUF_SZ;
bp->tx_bufs = pci_alloc_consistent(bp->pdev, size, &bp->tx_bufs_dma);
if (!bp->tx_bufs)
goto out_err;
memset(bp->tx_bufs, 0, size);
size = DMA_TABLE_BYTES;
bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
if (!bp->rx_ring)
......@@ -1297,6 +1307,19 @@ static int b44_open(struct net_device *dev)
}
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling receive - used by netconsole and other diagnostic tools
* to allow network i/o with interrupts disabled.
*/
static void b44_poll_controller(struct net_device *dev)
{
disable_irq(dev->irq);
b44_interrupt(dev->irq, dev, NULL);
enable_irq(dev->irq);
}
#endif
static int b44_close(struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
......@@ -1358,7 +1381,10 @@ static struct net_device_stats *b44_get_stats(struct net_device *dev)
hwstat->rx_symbol_errs);
nstat->tx_aborted_errors = hwstat->tx_underruns;
#if 0
/* Carrier lost counter seems to be broken for some devices */
nstat->tx_carrier_errors = hwstat->tx_carrier_lost;
#endif
return nstat;
}
......@@ -1684,7 +1710,6 @@ static int __devinit b44_get_invariants(struct b44 *bp)
bp->dev->dev_addr[5] = eeprom[82];
bp->phy_addr = eeprom[90] & 0x1f;
bp->mdc_port = (eeprom[90] >> 14) & 0x1;
/* With this, plus the rx_header prepended to the data by the
* hardware, we'll land the ethernet header on a 2-byte boundary.
......@@ -1694,7 +1719,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
bp->imask = IMASK_DEF;
bp->core_unit = ssb_core_unit(bp);
bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0);
bp->dma_offset = SB_PCI_DMA;
/* XXX - really required?
bp->flags |= B44_FLAG_BUGGY_TXPTR;
......@@ -1738,12 +1763,19 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
pci_set_master(pdev);
err = pci_set_dma_mask(pdev, (u64) 0xffffffff);
err = pci_set_dma_mask(pdev, (u64) B44_DMA_MASK);
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
goto err_out_free_res;
}
err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
goto err_out_free_res;
}
b44reg_base = pci_resource_start(pdev, 0);
b44reg_len = pci_resource_len(pdev, 0);
......@@ -1793,6 +1825,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
dev->poll = b44_poll;
dev->weight = 64;
dev->watchdog_timeo = B44_TX_TIMEOUT;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = b44_poll_controller;
#endif
dev->change_mtu = b44_change_mtu;
dev->irq = pdev->irq;
SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
......@@ -1870,7 +1905,7 @@ static void __devexit b44_remove_one(struct pci_dev *pdev)
static int b44_suspend(struct pci_dev *pdev, u32 state)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct b44 *bp = dev->priv;
struct b44 *bp = netdev_priv(dev);
if (!netif_running(dev))
return 0;
......@@ -1891,7 +1926,7 @@ static int b44_suspend(struct pci_dev *pdev, u32 state)
static int b44_resume(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct b44 *bp = dev->priv;
struct b44 *bp = netdev_priv(dev);
pci_restore_state(pdev);
......
......@@ -223,21 +223,8 @@
#define B44_RX_SYM 0x05D0UL /* MIB RX Symbol Errors */
#define B44_RX_PAUSE 0x05D4UL /* MIB RX Pause Packets */
#define B44_RX_NPAUSE 0x05D8UL /* MIB RX Non-Pause Packets */
#define B44_SBIPSFLAG 0x0F08UL /* SB Initiator Port OCP Slave Flag */
#define SBIPSFLAG_IMASK1 0x0000003f /* Which sbflags --> mips interrupt 1 */
#define SBIPSFLAG_ISHIFT1 0
#define SBIPSFLAG_IMASK2 0x00003f00 /* Which sbflags --> mips interrupt 2 */
#define SBIPSFLAG_ISHIFT2 8
#define SBIPSFLAG_IMASK3 0x003f0000 /* Which sbflags --> mips interrupt 3 */
#define SBIPSFLAG_ISHIFT3 16
#define SBIPSFLAG_IMASK4 0x3f000000 /* Which sbflags --> mips interrupt 4 */
#define SBIPSFLAG_ISHIFT4 24
#define B44_SBTPSFLAG 0x0F18UL /* SB Target Port OCP Slave Flag */
#define SBTPS_NUM0_MASK 0x0000003f
#define SBTPS_F0EN0 0x00000040
#define B44_SBADMATCH3 0x0F60UL /* SB Address Match 3 */
#define B44_SBADMATCH2 0x0F68UL /* SB Address Match 2 */
#define B44_SBADMATCH1 0x0F70UL /* SB Address Match 1 */
/* Silicon backplane register definitions */
#define B44_SBIMSTATE 0x0F90UL /* SB Initiator Agent State */
#define SBIMSTATE_PC 0x0000000f /* Pipe Count */
#define SBIMSTATE_AP_MASK 0x00000030 /* Arbitration Priority */
......@@ -269,86 +256,6 @@
#define SBTMSHIGH_GCR 0x20000000 /* Gated Clock Request */
#define SBTMSHIGH_BISTF 0x40000000 /* BIST Failed */
#define SBTMSHIGH_BISTD 0x80000000 /* BIST Done */
#define B44_SBBWA0 0x0FA0UL /* SB Bandwidth Allocation Table 0 */
#define SBBWA0_TAB0_MASK 0x0000ffff /* Lookup Table 0 */
#define SBBWA0_TAB0_SHIFT 0
#define SBBWA0_TAB1_MASK 0xffff0000 /* Lookup Table 0 */
#define SBBWA0_TAB1_SHIFT 16
#define B44_SBIMCFGLOW 0x0FA8UL /* SB Initiator Configuration Low */
#define SBIMCFGLOW_STO_MASK 0x00000003 /* Service Timeout */
#define SBIMCFGLOW_RTO_MASK 0x00000030 /* Request Timeout */
#define SBIMCFGLOW_RTO_SHIFT 4
#define SBIMCFGLOW_CID_MASK 0x00ff0000 /* Connection ID */
#define SBIMCFGLOW_CID_SHIFT 16
#define B44_SBIMCFGHIGH 0x0FACUL /* SB Initiator Configuration High */
#define SBIMCFGHIGH_IEM_MASK 0x0000000c /* Inband Error Mode */
#define SBIMCFGHIGH_TEM_MASK 0x00000030 /* Timeout Error Mode */
#define SBIMCFGHIGH_TEM_SHIFT 4
#define SBIMCFGHIGH_BEM_MASK 0x000000c0 /* Bus Error Mode */
#define SBIMCFGHIGH_BEM_SHIFT 6
#define B44_SBADMATCH0 0x0FB0UL /* SB Address Match 0 */
#define SBADMATCH0_TYPE_MASK 0x00000003 /* Address Type */
#define SBADMATCH0_AD64 0x00000004 /* Reserved */
#define SBADMATCH0_AI0_MASK 0x000000f8 /* Type0 Size */
#define SBADMATCH0_AI0_SHIFT 3
#define SBADMATCH0_AI1_MASK 0x000001f8 /* Type1 Size */
#define SBADMATCH0_AI1_SHIFT 3
#define SBADMATCH0_AI2_MASK 0x000001f8 /* Type2 Size */
#define SBADMATCH0_AI2_SHIFT 3
#define SBADMATCH0_ADEN 0x00000400 /* Enable */
#define SBADMATCH0_ADNEG 0x00000800 /* Negative Decode */
#define SBADMATCH0_BS0_MASK 0xffffff00 /* Type0 Base Address */
#define SBADMATCH0_BS0_SHIFT 8
#define SBADMATCH0_BS1_MASK 0xfffff000 /* Type1 Base Address */
#define SBADMATCH0_BS1_SHIFT 12
#define SBADMATCH0_BS2_MASK 0xffff0000 /* Type2 Base Address */
#define SBADMATCH0_BS2_SHIFT 16
#define B44_SBTMCFGLOW 0x0FB8UL /* SB Target Configuration Low */
#define SBTMCFGLOW_CD_MASK 0x000000ff /* Clock Divide Mask */
#define SBTMCFGLOW_CO_MASK 0x0000f800 /* Clock Offset Mask */
#define SBTMCFGLOW_CO_SHIFT 11
#define SBTMCFGLOW_IF_MASK 0x00fc0000 /* Interrupt Flags Mask */
#define SBTMCFGLOW_IF_SHIFT 18
#define SBTMCFGLOW_IM_MASK 0x03000000 /* Interrupt Mode Mask */
#define SBTMCFGLOW_IM_SHIFT 24
#define B44_SBTMCFGHIGH 0x0FBCUL /* SB Target Configuration High */
#define SBTMCFGHIGH_BM_MASK 0x00000003 /* Busy Mode */
#define SBTMCFGHIGH_RM_MASK 0x0000000C /* Retry Mode */
#define SBTMCFGHIGH_RM_SHIFT 2
#define SBTMCFGHIGH_SM_MASK 0x00000030 /* Stop Mode */
#define SBTMCFGHIGH_SM_SHIFT 4
#define SBTMCFGHIGH_EM_MASK 0x00000300 /* Error Mode */
#define SBTMCFGHIGH_EM_SHIFT 8
#define SBTMCFGHIGH_IM_MASK 0x00000c00 /* Interrupt Mode */
#define SBTMCFGHIGH_IM_SHIFT 10
#define B44_SBBCFG 0x0FC0UL /* SB Broadcast Configuration */
#define SBBCFG_LAT_MASK 0x00000003 /* SB Latency */
#define SBBCFG_MAX0_MASK 0x000f0000 /* MAX Counter 0 */
#define SBBCFG_MAX0_SHIFT 16
#define SBBCFG_MAX1_MASK 0x00f00000 /* MAX Counter 1 */
#define SBBCFG_MAX1_SHIFT 20
#define B44_SBBSTATE 0x0FC8UL /* SB Broadcast State */
#define SBBSTATE_SRD 0x00000001 /* ST Reg Disable */
#define SBBSTATE_HRD 0x00000002 /* Hold Reg Disable */
#define B44_SBACTCNFG 0x0FD8UL /* SB Activate Configuration */
#define B44_SBFLAGST 0x0FE8UL /* SB Current SBFLAGS */
#define B44_SBIDLOW 0x0FF8UL /* SB Identification Low */
#define SBIDLOW_CS_MASK 0x00000003 /* Config Space Mask */
#define SBIDLOW_AR_MASK 0x00000038 /* Num Address Ranges Supported */
#define SBIDLOW_AR_SHIFT 3
#define SBIDLOW_SYNCH 0x00000040 /* Sync */
#define SBIDLOW_INIT 0x00000080 /* Initiator */
#define SBIDLOW_MINLAT_MASK 0x00000f00 /* Minimum Backplane Latency */
#define SBIDLOW_MINLAT_SHIFT 8
#define SBIDLOW_MAXLAT_MASK 0x0000f000 /* Maximum Backplane Latency */
#define SBIDLOW_MAXLAT_SHIFT 12
#define SBIDLOW_FIRST 0x00010000 /* This Initiator is First */
#define SBIDLOW_CW_MASK 0x000c0000 /* Cycle Counter Width */
#define SBIDLOW_CW_SHIFT 18
#define SBIDLOW_TP_MASK 0x00f00000 /* Target Ports */
#define SBIDLOW_TP_SHIFT 20
#define SBIDLOW_IP_MASK 0x0f000000 /* Initiator Ports */
#define SBIDLOW_IP_SHIFT 24
#define B44_SBIDHIGH 0x0FFCUL /* SB Identification High */
#define SBIDHIGH_RC_MASK 0x0000000f /* Revision Code */
#define SBIDHIGH_CC_MASK 0x0000fff0 /* Core Code */
......@@ -356,23 +263,13 @@
#define SBIDHIGH_VC_MASK 0xffff0000 /* Vendor Code */
#define SBIDHIGH_VC_SHIFT 16
#define CORE_CODE_ILINE20 0x801
#define CORE_CODE_SDRAM 0x803
#define CORE_CODE_PCI 0x804
#define CORE_CODE_MIPS 0x805
#define CORE_CODE_ENET 0x806
#define CORE_CODE_CODEC 0x807
#define CORE_CODE_USB 0x808
#define CORE_CODE_ILINE100 0x80a
#define CORE_CODE_EXTIF 0x811
/* SSB PCI config space registers. */
#define SSB_BAR0_WIN 0x80
#define SSB_BAR1_WIN 0x84
#define SSB_SPROM_CONTROL 0x88
#define SSB_BAR1_CONTROL 0x8c
/* SSB core and hsot control registers. */
/* SSB core and host control registers. */
#define SSB_CONTROL 0x0000UL
#define SSB_ARBCONTROL 0x0010UL
#define SSB_ISTAT 0x0020UL
......@@ -500,6 +397,7 @@ struct b44 {
struct ring_info *rx_buffers;
struct ring_info *tx_buffers;
unsigned char *tx_bufs;
u32 dma_offset;
u32 flags;
......@@ -531,12 +429,11 @@ struct b44 {
struct pci_dev *pdev;
struct net_device *dev;
dma_addr_t rx_ring_dma, tx_ring_dma;
dma_addr_t rx_ring_dma, tx_ring_dma,tx_bufs_dma;
u32 rx_pending;
u32 tx_pending;
u8 phy_addr;
u8 mdc_port;
u8 core_unit;
struct mii_if_info mii_if;
......
......@@ -1222,10 +1222,10 @@ static int InitRestartDepca(struct net_device *dev)
/* clear IDON by writing a "1", enable interrupts and start lance */
outw(IDON | INEA | STRT, DEPCA_DATA);
if (depca_debug > 2) {
printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, virt_to_phys(lp->sh_mem), inw(DEPCA_DATA));
printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, lp->mem_start, inw(DEPCA_DATA));
}
} else {
printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, virt_to_phys(lp->sh_mem), inw(DEPCA_DATA));
printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, lp->mem_start, inw(DEPCA_DATA));
status = -1;
}
......@@ -1901,7 +1901,7 @@ static void depca_dbg_open(struct net_device *dev)
}
}
printk("...0x%8.8x\n", readl(&lp->tx_ring[i].base));
printk("Initialisation block at 0x%8.8lx(Phys)\n", virt_to_phys(lp->sh_mem));
printk("Initialisation block at 0x%8.8lx(Phys)\n", lp->mem_start);
printk(" mode: 0x%4.4x\n", p->mode);
printk(" physical address: ");
for (i = 0; i < ETH_ALEN - 1; i++) {
......@@ -1915,7 +1915,7 @@ static void depca_dbg_open(struct net_device *dev)
printk("%2.2x\n", p->mcast_table[i]);
printk(" rx_ring at: 0x%8.8x\n", p->rx_ring);
printk(" tx_ring at: 0x%8.8x\n", p->tx_ring);
printk("buffers (Phys): 0x%8.8lx\n", virt_to_phys(lp->sh_mem) + lp->buffs_offset);
printk("buffers (Phys): 0x%8.8lx\n", lp->mem_start + lp->buffs_offset);
printk("Ring size:\nRX: %d Log2(rxRingMask): 0x%8.8x\n", (int) lp->rxRingMask + 1, lp->rx_rlen);
printk("TX: %d Log2(txRingMask): 0x%8.8x\n", (int) lp->txRingMask + 1, lp->tx_rlen);
outw(CSR2, DEPCA_ADDR);
......
......@@ -76,6 +76,9 @@
* for registers, link status and other minor fixes.
* 0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe
* 0.29: 31 Aug 2004: Add backup timer for link change notification.
* 0.30: 25 Sep 2004: rx checksum support for nf 250 Gb. Add rx reset
* into nv_close, otherwise reenabling for wol can
* cause DMA to kfree'd memory.
*
* Known bugs:
* We suspect that on some hardware no TX done interrupts are generated.
......@@ -87,7 +90,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
#define FORCEDETH_VERSION "0.29"
#define FORCEDETH_VERSION "0.30"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
......@@ -217,6 +220,7 @@ enum {
#define NVREG_TXRXCTL_BIT2 0x0004
#define NVREG_TXRXCTL_IDLE 0x0008
#define NVREG_TXRXCTL_RESET 0x0010
#define NVREG_TXRXCTL_RXCHECK 0x0400
NvRegMIIStatus = 0x180,
#define NVREG_MIISTAT_ERROR 0x0001
#define NVREG_MIISTAT_LINKCHANGE 0x0008
......@@ -313,6 +317,10 @@ struct ring_desc {
#define NV_RX_ERROR (1<<30)
#define NV_RX_AVAIL (1<<31)
#define NV_RX2_CHECKSUMMASK (0x1C000000)
#define NV_RX2_CHECKSUMOK1 (0x10000000)
#define NV_RX2_CHECKSUMOK2 (0x14000000)
#define NV_RX2_CHECKSUMOK3 (0x18000000)
#define NV_RX2_DESCRIPTORVALID (1<<29)
#define NV_RX2_SUBSTRACT1 (1<<25)
#define NV_RX2_ERROR1 (1<<18)
......@@ -371,8 +379,15 @@ struct ring_desc {
#define POLL_WAIT (1+HZ/100)
#define LINK_TIMEOUT (3*HZ)
/*
* desc_ver values:
* This field has two purposes:
* - Newer nics uses a different ring layout. The layout is selected by
* comparing np->desc_ver with DESC_VER_xy.
* - It contains bits that are forced on when writing to NvRegTxRxControl.
*/
#define DESC_VER_1 0x0
#define DESC_VER_2 0x02100
#define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK)
/* PHY defines */
#define PHY_OUI_MARVELL 0x5043
......@@ -1142,6 +1157,15 @@ static void nv_rx_process(struct net_device *dev)
goto next_pkt;
}
}
Flags &= NV_RX2_CHECKSUMMASK;
if (Flags == NV_RX2_CHECKSUMOK1 ||
Flags == NV_RX2_CHECKSUMOK2 ||
Flags == NV_RX2_CHECKSUMOK3) {
dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name);
np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY;
} else {
dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name);
}
}
/* got a valid packet - forward it to the network core */
skb = np->rx_skbuff[i];
......@@ -1634,9 +1658,10 @@ static int nv_close(struct net_device *dev)
spin_lock_irq(&np->lock);
nv_stop_tx(dev);
nv_stop_rx(dev);
base = get_hwbase(dev);
nv_txrx_reset(dev);
/* disable interrupts on the nic or we will lock up */
base = get_hwbase(dev);
writel(0, base + NvRegIrqMask);
pci_push(base);
dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name);
......
This diff is collapsed.
This diff is collapsed.
......@@ -173,6 +173,11 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
#define set_irq_type(irq, type) do {} while(0)
#define RPC_LSA_DEFAULT RPC_LED_TX_RX
#define RPC_LSB_DEFAULT RPC_LED_100_10
#else
#define SMC_CAN_USE_8BIT 1
......@@ -202,8 +207,9 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
* different and probably not worth it for that reason, and not as critical
* as RX which can overrun memory and lose packets.
*/
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <asm/dma.h>
#include <asm/arch/pxa-regs.h>
#ifdef SMC_insl
#undef SMC_insl
......@@ -223,19 +229,21 @@ smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
/* 64 bit alignment is required for memory to memory DMA */
if ((long)buf & 4) {
*((u32 *)buf)++ = SMC_inl(ioaddr, reg);
*((u32 *)buf) = SMC_inl(ioaddr, reg);
buf += 4;
len--;
}
len *= 4;
dmabuf = dma_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE);
dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
DCSR(dma) = DCSR_NODESC;
DTADR(dma) = dmabuf;
DSADR(dma) = physaddr + reg;
DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
DCMD_WIDTH4 | (DCMD_LENGTH & len));
DCSR(dma) = DCSR_NODESC | DCSR_RUN;
while (!(DCSR(dma) & DCSR_STOPSTATE));
while (!(DCSR(dma) & DCSR_STOPSTATE))
cpu_relax();
DCSR(dma) = 0;
dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE);
}
......@@ -259,7 +267,8 @@ smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
/* 64 bit alignment is required for memory to memory DMA */
while ((long)buf & 6) {
*((u16 *)buf)++ = SMC_inw(ioaddr, reg);
*((u16 *)buf) = SMC_inw(ioaddr, reg);
buf += 2;
len--;
}
......@@ -271,9 +280,10 @@ smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
DCMD_WIDTH2 | (DCMD_LENGTH & len));
DCSR(dma) = DCSR_NODESC | DCSR_RUN;
while (!(DCSR(dma) & DCSR_STOPSTATE));
while (!(DCSR(dma) & DCSR_STOPSTATE))
cpu_relax();
DCSR(dma) = 0;
dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE);
dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
}
#endif
......@@ -762,16 +772,9 @@ static const char * chip_ids[ 16 ] = {
SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG ); \
} while (0)
#define SMC_CLEAR_MCAST() \
do { \
SMC_outw( 0, ioaddr, MCAST_REG1 ); \
SMC_outw( 0, ioaddr, MCAST_REG2 ); \
SMC_outw( 0, ioaddr, MCAST_REG3 ); \
SMC_outw( 0, ioaddr, MCAST_REG4 ); \
} while (0)
#define SMC_SET_MCAST(x) \
do { \
unsigned char *mt = (x); \
const unsigned char *mt = (x); \
SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 ); \
SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 ); \
SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 ); \
......
......@@ -1606,7 +1606,7 @@ static void streamer_arb_cmd(struct net_device *dev)
i += 2;
}
memcpy_fromio(skb_put(mac_frame, buffer_len),
memcpy(skb_put(mac_frame, buffer_len),
frame_data, buffer_len);
} while (next_ptr && (buff_off = next_ptr));
......
......@@ -92,6 +92,7 @@
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
/* Board/System/Debug information/definition ---------------- */
......
......@@ -1957,6 +1957,7 @@ static int rhine_suspend(struct pci_dev *pdev, u32 state)
rhine_shutdown(&pdev->dev);
spin_unlock_irqrestore(&rp->lock, flags);
free_irq(dev->irq, dev);
return 0;
}
......@@ -1970,6 +1971,9 @@ static int rhine_resume(struct pci_dev *pdev)
if (!netif_running(dev))
return 0;
if (request_irq(dev->irq, rhine_interrupt, SA_SHIRQ, dev->name, dev))
printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name);
ret = pci_set_power_state(pdev, 0);
if (debug > 1)
printk(KERN_INFO "%s: Entering power state D0 %s (%d).\n",
......
......@@ -133,8 +133,8 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
readl(device_base + ISL38XX_CTRL_STAT_REG));
udelay(ISL38XX_WRITEIO_DELAY);
if (reg = readl(device_base + ISL38XX_INT_IDENT_REG),
reg == 0xabadface) {
reg = readl(device_base + ISL38XX_INT_IDENT_REG);
if (reg == 0xabadface) {
#if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday(&current_time);
DEBUG(SHOW_TRACING,
......@@ -192,10 +192,8 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
void
isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
{
u32 reg;
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_interface_reset \n");
DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_interface_reset\n");
#endif
/* load the address of the control block in the device */
......@@ -203,8 +201,7 @@ isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
udelay(ISL38XX_WRITEIO_DELAY);
/* set the reset bit in the Device Interrupt Register */
isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_RESET,
ISL38XX_DEV_INT_REG);
isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_RESET, ISL38XX_DEV_INT_REG);
udelay(ISL38XX_WRITEIO_DELAY);
/* enable the interrupt for detecting initialization */
......@@ -212,9 +209,7 @@ isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
/* Note: Do not enable other interrupts here. We want the
* device to have come up first 100% before allowing any other
* interrupts. */
reg = ISL38XX_INT_IDENT_INIT;
isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG);
isl38xx_w32_flush(device_base, ISL38XX_INT_IDENT_INIT, ISL38XX_INT_EN_REG);
udelay(ISL38XX_WRITEIO_DELAY); /* allow complete full reset */
}
......
......@@ -95,6 +95,10 @@ isl38xx_w32_flush(void __iomem *base, u32 val, unsigned long offset)
#define ISL38XX_INT_SOURCES 0x001E
/* Control/Status register bits */
/* Looks like there are other meaningful bits
0x20004400 seen in normal operation,
0x200044db at 'timeout waiting for mgmt response'
*/
#define ISL38XX_CTRL_STAT_SLEEPMODE 0x00000200
#define ISL38XX_CTRL_STAT_CLKRUN 0x00800000
#define ISL38XX_CTRL_STAT_RESET 0x10000000
......
This diff is collapsed.
......@@ -48,6 +48,8 @@ size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
int prism54_set_mac_address(struct net_device *, void *);
int prism54_ioctl(struct net_device *, struct ifreq *, int);
int prism54_set_wpa(struct net_device *, struct iw_request_info *,
__u32 *, char *);
extern const struct iw_handler_def prism54_handler_def;
......
......@@ -91,6 +91,14 @@ struct obj_frequencies {
u16 mhz[0];
} __attribute__ ((packed));
struct obj_attachment {
char type;
char reserved;
short id;
short size;
char data[0];
} __attribute__((packed));
/*
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
......@@ -472,6 +480,7 @@ enum oid_num_t {
#define OID_TYPE_MLMEEX 0x09
#define OID_TYPE_ADDR 0x0A
#define OID_TYPE_RAW 0x0B
#define OID_TYPE_ATTACH 0x0C
/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
* Not yet implemented (not used in driver anyway).
......
......@@ -105,7 +105,7 @@ isl_upload_firmware(islpci_private *priv)
"%s: firmware '%s' size is not multiple of 32bit, aborting!\n",
"prism54", priv->firmware);
release_firmware(fw_entry);
return EILSEQ; /* Illegal byte sequence */;
return -EILSEQ; /* Illegal byte sequence */;
}
while (fw_len > 0) {
......@@ -142,6 +142,10 @@ isl_upload_firmware(islpci_private *priv)
BUG_ON(fw_len != 0);
/* Firmware version is at offset 40 (also for "newmac") */
printk(KERN_DEBUG "%s: firmware version: %.8s\n",
priv->ndev->name, fw_entry->data + 40);
release_firmware(fw_entry);
}
......@@ -375,8 +379,6 @@ islpci_open(struct net_device *ndev)
u32 rc;
islpci_private *priv = netdev_priv(ndev);
printk(KERN_DEBUG "%s: islpci_open()\n", ndev->name);
/* reset data structures, upload firmware and reset device */
rc = islpci_reset(priv,1);
if (rc) {
......@@ -462,8 +464,7 @@ islpci_upload_fw(islpci_private *priv)
return rc;
}
printk(KERN_DEBUG
"%s: firmware uploaded done, now triggering reset...\n",
printk(KERN_DEBUG "%s: firmware upload complete\n",
priv->ndev->name);
islpci_set_state(priv, PRV_STATE_POSTBOOT);
......@@ -489,6 +490,7 @@ islpci_reset_if(islpci_private *priv)
/* The software reset acknowledge needs about 220 msec here.
* Be conservative and wait for up to one second. */
set_current_state(TASK_UNINTERRUPTIBLE);
remaining = schedule_timeout(HZ);
if(remaining > 0) {
......@@ -499,15 +501,16 @@ islpci_reset_if(islpci_private *priv)
/* If we're here it's because our IRQ hasn't yet gone through.
* Retry a bit more...
*/
printk(KERN_ERR "%s: device soft reset timed out\n",
priv->ndev->name);
printk(KERN_ERR "%s: no 'reset complete' IRQ seen - retrying\n",
priv->ndev->name);
}
finish_wait(&priv->reset_done, &wait);
if(result)
if (result) {
printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
return result;
}
islpci_set_state(priv, PRV_STATE_INIT);
......@@ -519,11 +522,17 @@ islpci_reset_if(islpci_private *priv)
isl38xx_enable_common_interrupts(priv->device_base);
down_write(&priv->mib_sem);
mgt_commit(priv);
result = mgt_commit(priv);
if (result) {
printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
up_write(&priv->mib_sem);
return result;
}
up_write(&priv->mib_sem);
islpci_set_state(priv, PRV_STATE_READY);
printk(KERN_DEBUG "%s: interface reset complete\n", priv->ndev->name);
return 0;
}
......@@ -584,18 +593,18 @@ islpci_reset(islpci_private *priv, int reload_firmware)
/* now that the data structures are cleaned up, upload
* firmware and reset interface */
rc = islpci_upload_fw(priv);
if (rc)
if (rc) {
printk(KERN_ERR "%s: islpci_reset: failure\n",
priv->ndev->name);
return rc;
}
}
/* finally reset interface */
rc = islpci_reset_if(priv);
if (!rc) /* If successful */
return rc;
printk(KERN_DEBUG "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n");
if (rc)
printk(KERN_ERR "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n");
return rc;
}
struct net_device_stats *
......@@ -604,7 +613,7 @@ islpci_statistics(struct net_device *ndev)
islpci_private *priv = netdev_priv(ndev);
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics \n");
DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics\n");
#endif
return &priv->statistics;
......@@ -830,6 +839,12 @@ islpci_setup(struct pci_dev *pdev)
priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
priv->monitor_type : ARPHRD_ETHER;
#if WIRELESS_EXT > 16
/* Add pointers to enable iwspy support. */
priv->wireless_data.spy_data = &priv->spy_data;
ndev->wireless_data = &priv->wireless_data;
#endif /* WIRELESS_EXT > 16 */
/* save the start and end address of the PCI memory area */
ndev->mem_start = (unsigned long) priv->device_base;
ndev->mem_end = ndev->mem_start + ISL38XX_PCI_MEM_SIZE;
......
......@@ -100,6 +100,10 @@ typedef struct {
struct iw_spy_data spy_data; /* iwspy support */
#if WIRELESS_EXT > 16
struct iw_public_data wireless_data;
#endif /* WIRELESS_EXT > 16 */
int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
struct islpci_acl acl;
......
......@@ -508,11 +508,12 @@ islpci_eth_tx_timeout(struct net_device *ndev)
/* increment the transmit error counter */
statistics->tx_errors++;
printk(KERN_WARNING "%s: tx_timeout", ndev->name);
if (!priv->reset_task_pending) {
priv->reset_task_pending = 1;
printk(", scheduling a reset");
netif_stop_queue(ndev);
schedule_work(&priv->reset_task);
}
return;
printk("\n");
}
......@@ -107,9 +107,6 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
islpci_private *priv;
int rvalue;
/* TRACE(DRV_NAME); */
/* Enable the pci device */
if (pci_enable_device(pdev)) {
printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
......
......@@ -473,6 +473,7 @@ islpci_mgt_transaction(struct net_device *ndev,
int timeleft;
struct islpci_mgmtframe *frame;
set_current_state(TASK_UNINTERRUPTIBLE);
timeleft = schedule_timeout(wait_cycle_jiffies);
frame = xchg(&priv->mgmt_received, NULL);
if (frame) {
......
......@@ -31,8 +31,6 @@
#define K_DEBUG(f, m, args...) do { if(f & m) printk(KERN_DEBUG args); } while(0)
#define DEBUG(f, args...) K_DEBUG(f, pc_debug, args)
#define TRACE(devname) K_DEBUG(SHOW_TRACING, VERBOSE, "%s: -> " __FUNCTION__ "()\n", devname)
extern int pc_debug;
#define init_wds 0 /* help compiler optimize away dead code */
......
......@@ -201,7 +201,8 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
OID_UNKNOWN(DOT11_OID_ATTACHMENT, 0x19000003),
[DOT11_OID_ATTACHMENT] = {0x19000003, 0,
sizeof(struct obj_attachment), OID_TYPE_ATTACH},
OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
OID_TYPE_BUFFER),
......@@ -329,6 +330,12 @@ mgt_le_to_cpu(int type, void *data)
mlme->size = le16_to_cpu(mlme->size);
break;
}
case OID_TYPE_ATTACH:{
struct obj_attachment *attach = data;
attach->id = le16_to_cpu(attach->id);
attach->size = le16_to_cpu(attach->size);;
break;
}
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
......@@ -392,6 +399,12 @@ mgt_cpu_to_le(int type, void *data)
mlme->size = cpu_to_le16(mlme->size);
break;
}
case OID_TYPE_ATTACH:{
struct obj_attachment *attach = data;
attach->id = cpu_to_le16(attach->id);
attach->size = cpu_to_le16(attach->size);;
break;
}
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
......@@ -465,6 +478,42 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
return ret;
}
/* None of these are cached */
int
mgt_set_varlen(islpci_private *priv, enum oid_num_t n, void *data, int extra_len)
{
int ret = 0;
struct islpci_mgmtframe *response;
int response_op = PIMFOR_OP_ERROR;
int dlen;
u32 oid;
BUG_ON(OID_NUM_LAST <= n);
dlen = isl_oid[n].size;
oid = isl_oid[n].oid;
mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, data);
if (islpci_get_state(priv) >= PRV_STATE_READY) {
ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid,
data, dlen + extra_len, &response);
if (!ret) {
response_op = response->header->operation;
islpci_mgt_release(response);
}
if (ret || response_op == PIMFOR_OP_ERROR)
ret = -EIO;
} else
ret = -EIO;
/* re-set given data to what it was */
if (data)
mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data);
return ret;
}
int
mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,
union oid_res_t *res)
......@@ -555,15 +604,18 @@ mgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n)
u32 oid = t->oid;
BUG_ON(data == NULL);
while (j <= t->range) {
response = NULL;
ret |= islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
int r = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
oid, data, t->size,
&response);
if (response) {
ret |= (response->header->operation ==
PIMFOR_OP_ERROR);
r |= (response->header->operation == PIMFOR_OP_ERROR);
islpci_mgt_release(response);
}
if (r)
printk(KERN_ERR "%s: mgt_commit_list: failure. "
"oid=%08x err=%d\n",
priv->ndev->name, oid, r);
ret |= r;
j++;
oid++;
data += t->size;
......@@ -624,7 +676,7 @@ static enum oid_num_t commit_part2[] = {
static int
mgt_update_addr(islpci_private *priv)
{
struct islpci_mgmtframe *res = NULL;
struct islpci_mgmtframe *res;
int ret;
ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
......@@ -638,26 +690,26 @@ mgt_update_addr(islpci_private *priv)
if (res)
islpci_mgt_release(res);
if (ret)
printk(KERN_ERR "%s: mgt_update_addr: failure\n", priv->ndev->name);
return ret;
}
void
#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0]))
int
mgt_commit(islpci_private *priv)
{
int rvalue;
u32 u;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return;
return 0;
rvalue = mgt_commit_list(priv, commit_part1,
sizeof (commit_part1) /
sizeof (commit_part1[0]));
rvalue = mgt_commit_list(priv, commit_part1, VEC_SIZE(commit_part1));
if (priv->iw_mode != IW_MODE_MONITOR)
rvalue |= mgt_commit_list(priv, commit_part2,
sizeof (commit_part2) /
sizeof (commit_part2[0]));
rvalue |= mgt_commit_list(priv, commit_part2, VEC_SIZE(commit_part2));
u = OID_INL_MODE;
rvalue |= mgt_commit_list(priv, &u, 1);
......@@ -666,9 +718,43 @@ mgt_commit(islpci_private *priv)
if (rvalue) {
/* some request have failed. The device might be in an
incoherent state. We should reset it ! */
printk(KERN_DEBUG "%s: mgt_commit has failed. Restart the "
"device \n", priv->ndev->name);
printk(KERN_DEBUG "%s: mgt_commit: failure\n", priv->ndev->name);
}
return rvalue;
}
/* The following OIDs need to be "unlatched":
*
* MEDIUMLIMIT,BEACONPERIOD,DTIMPERIOD,ATIMWINDOW,LISTENINTERVAL
* FREQUENCY,EXTENDEDRATES.
*
* The way to do this is to set ESSID. Note though that they may get
* unlatch before though by setting another OID. */
void
mgt_unlatch_all(islpci_private *priv)
{
u32 u;
int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return;
u = DOT11_OID_SSID;
rvalue = mgt_commit_list(priv, &u, 1);
/* Necessary if in MANUAL RUN mode? */
#if 0
u = OID_INL_MODE;
rvalue |= mgt_commit_list(priv, &u, 1);
u = DOT11_OID_MLMEAUTOLEVEL;
rvalue |= mgt_commit_list(priv, &u, 1);
u = OID_INL_MODE;
rvalue |= mgt_commit_list(priv, &u, 1);
#endif
if (rvalue)
printk(KERN_DEBUG "%s: Unlatching OIDs failed\n", priv->ndev->name);
}
/* This will tell you if you are allowed to answer a mlme(ex) request .*/
......@@ -771,6 +857,14 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
mlme->state, mlme->code, mlme->size);
}
break;
case OID_TYPE_ATTACH:{
struct obj_attachment *attach = r->ptr;
return snprintf(str, PRIV_STR_SIZE,
"id=%d\nsize=%d\n",
attach->id,
attach->size);
}
break;
case OID_TYPE_SSID:{
struct obj_ssid *ssid = r->ptr;
return snprintf(str, PRIV_STR_SIZE,
......
......@@ -36,6 +36,8 @@ int channel_of_freq(int);
void mgt_le_to_cpu(int, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
int mgt_get_request(islpci_private *, enum oid_num_t, int, void *,
union oid_res_t *);
......@@ -46,7 +48,8 @@ void mgt_set(islpci_private *, enum oid_num_t, void *);
void mgt_get(islpci_private *, enum oid_num_t, void *);
void mgt_commit(islpci_private *);
int mgt_commit(islpci_private *);
void mgt_unlatch_all(islpci_private *);
int mgt_mlme_answer(islpci_private *);
......
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