Merge branch 'upstream' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

This commit is contained in:
Linus Torvalds 2005-10-28 09:05:25 -07:00
commit e5dfa9282f
145 changed files with 8164 additions and 4652 deletions

View File

@ -777,7 +777,7 @@ doing so is the same as described in the "Configuring Multiple Bonds
Manually" section, below.
NOTE: It has been observed that some Red Hat supplied kernels
are apparently unable to rename modules at load time (the "-obonding1"
are apparently unable to rename modules at load time (the "-o bond1"
part). Attempts to pass that option to modprobe will produce an
"Operation not permitted" error. This has been reported on some
Fedora Core kernels, and has been seen on RHEL 4 as well. On kernels
@ -883,7 +883,8 @@ the above does not work, and the second bonding instance never sees
its options. In that case, the second options line can be substituted
as follows:
install bonding1 /sbin/modprobe bonding -obond1 mode=balance-alb miimon=50
install bond1 /sbin/modprobe --ignore-install bonding -o bond1 \
mode=balance-alb miimon=50
This may be repeated any number of times, specifying a new and
unique name in place of bond1 for each subsequent instance.

View File

@ -1027,8 +1027,7 @@ static void cp_reset_hw (struct cp_private *cp)
if (!(cpr8(Cmd) & CmdReset))
return;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(10);
schedule_timeout_uninterruptible(10);
}
printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
@ -1575,6 +1574,7 @@ static struct ethtool_ops cp_ethtool_ops = {
.set_wol = cp_set_wol,
.get_strings = cp_get_strings,
.get_ethtool_stats = cp_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr,
};
static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
@ -1773,6 +1773,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < 3; i++)
((u16 *) (dev->dev_addr))[i] =
le16_to_cpu (read_eeprom (regs, i + 7, addr_len));
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->open = cp_open;
dev->stop = cp_close;

View File

@ -552,7 +552,8 @@ const static struct {
{ "RTL-8100B/8139D",
HW_REVID(1, 1, 1, 0, 1, 0, 1),
HasLWake,
HasHltClk /* XXX undocumented? */
| HasLWake,
},
{ "RTL-8101",
@ -970,6 +971,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
for (i = 0; i < 3; i++)
((u16 *) (dev->dev_addr))[i] =
le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* The Rtl8139-specific entries in the device structure. */
dev->open = rtl8139_open;
@ -2465,6 +2467,7 @@ static struct ethtool_ops rtl8139_ethtool_ops = {
.get_strings = rtl8139_get_strings,
.get_stats_count = rtl8139_get_stats_count,
.get_ethtool_stats = rtl8139_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)

View File

@ -475,6 +475,14 @@ config SGI_IOC3_ETH_HW_TX_CSUM
the moment only acceleration of IPv4 is supported. This option
enables offloading for checksums on transmit. If unsure, say Y.
config MIPS_SIM_NET
tristate "MIPS simulator Network device (EXPERIMENTAL)"
depends on NETDEVICES && MIPS_SIM && EXPERIMENTAL
help
The MIPSNET device is a simple Ethernet network device which is
emulated by the MIPS Simulator.
If you are not using a MIPSsim or are unsure, say N.
config SGI_O2MACE_ETH
tristate "SGI O2 MACE Fast Ethernet support"
depends on NET_ETHERNET && SGI_IP32=y
@ -2083,6 +2091,7 @@ config SPIDER_NET
config GIANFAR
tristate "Gianfar Ethernet"
depends on 85xx || 83xx
select PHYLIB
help
This driver supports the Gigabit TSEC on the MPC85xx
family of chips, and the FEC on the 8540
@ -2243,6 +2252,20 @@ config ISERIES_VETH
tristate "iSeries Virtual Ethernet driver support"
depends on PPC_ISERIES
config RIONET
tristate "RapidIO Ethernet over messaging driver support"
depends on NETDEVICES && RAPIDIO
config RIONET_TX_SIZE
int "Number of outbound queue entries"
depends on RIONET
default "128"
config RIONET_RX_SIZE
int "Number of inbound queue entries"
depends on RIONET
default "128"
config FDDI
bool "FDDI driver support"
depends on (PCI || EISA)

View File

@ -13,7 +13,7 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o
gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_phy.o
gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
#
# link order important here
@ -64,6 +64,7 @@ obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
obj-$(CONFIG_RIONET) += rionet.o
#
# end link order section
@ -166,6 +167,7 @@ obj-$(CONFIG_EQUALIZER) += eql.o
obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o
obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
obj-$(CONFIG_DECLANCE) += declance.o
obj-$(CONFIG_ATARILANCE) += atarilance.o

View File

@ -151,13 +151,6 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
SUPPORTED_Autoneg
static char *phy_link[] =
{ "unknown",
"10Base2", "10BaseT",
"AUI",
"100BaseT", "100BaseTX", "100BaseFX"
};
int bcm_5201_init(struct net_device *dev, int phy_addr)
{
s16 data;
@ -785,6 +778,7 @@ static struct mii_chip_info {
{"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0},
{"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0},
{"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1},
{"NS DP83847 PHY", 0x2000, 0x5c30, &bcm_5201_ops ,0},
{"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0},
{"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0},
{"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0},
@ -1045,7 +1039,7 @@ static int mii_probe (struct net_device * dev)
#endif
if (aup->mii->chip_info == NULL) {
printk(KERN_ERR "%s: Au1x No MII transceivers found!\n",
printk(KERN_ERR "%s: Au1x No known MII transceivers found!\n",
dev->name);
return -1;
}
@ -1546,6 +1540,9 @@ au1000_probe(u32 ioaddr, int irq, int port_num)
printk(KERN_ERR "%s: out of memory\n", dev->name);
goto err_out;
}
aup->mii->next = NULL;
aup->mii->chip_info = NULL;
aup->mii->status = 0;
aup->mii->mii_control_reg = 0;
aup->mii->mii_data_reg = 0;

View File

@ -106,6 +106,29 @@ static int b44_poll(struct net_device *dev, int *budget);
static void b44_poll_controller(struct net_device *dev);
#endif
static int dma_desc_align_mask;
static int dma_desc_sync_size;
static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
dma_addr_t dma_base,
unsigned long offset,
enum dma_data_direction dir)
{
dma_sync_single_range_for_device(&pdev->dev, dma_base,
offset & dma_desc_align_mask,
dma_desc_sync_size, dir);
}
static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
dma_addr_t dma_base,
unsigned long offset,
enum dma_data_direction dir)
{
dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
offset & dma_desc_align_mask,
dma_desc_sync_size, dir);
}
static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
{
return readl(bp->regs + reg);
@ -668,6 +691,11 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dp->ctrl = cpu_to_le32(ctrl);
dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
dest_idx * sizeof(dp),
DMA_BIDIRECTIONAL);
return RX_PKT_BUF_SZ;
}
@ -692,6 +720,11 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
pci_unmap_addr_set(dest_map, mapping,
pci_unmap_addr(src_map, mapping));
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
src_idx * sizeof(src_desc),
DMA_BIDIRECTIONAL);
ctrl = src_desc->ctrl;
if (dest_idx == (B44_RX_RING_SIZE - 1))
ctrl |= cpu_to_le32(DESC_CTRL_EOT);
@ -700,8 +733,14 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dest_desc->ctrl = ctrl;
dest_desc->addr = src_desc->addr;
src_map->skb = NULL;
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
dest_idx * sizeof(dest_desc),
DMA_BIDIRECTIONAL);
pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
@ -959,6 +998,11 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl);
bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
if (bp->flags & B44_FLAG_TX_RING_HACK)
b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
entry * sizeof(bp->tx_ring[0]),
DMA_TO_DEVICE);
entry = NEXT_TX(entry);
bp->tx_prod = entry;
@ -1064,6 +1108,16 @@ static void b44_init_rings(struct b44 *bp)
memset(bp->rx_ring, 0, B44_RX_RING_BYTES);
memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
if (bp->flags & B44_FLAG_RX_RING_HACK)
dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
DMA_TABLE_BYTES,
PCI_DMA_BIDIRECTIONAL);
if (bp->flags & B44_FLAG_TX_RING_HACK)
dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
DMA_TABLE_BYTES,
PCI_DMA_TODEVICE);
for (i = 0; i < bp->rx_pending; i++) {
if (b44_alloc_rx_skb(bp, -1, i) < 0)
break;
@ -1085,14 +1139,28 @@ static void b44_free_consistent(struct b44 *bp)
bp->tx_buffers = NULL;
}
if (bp->rx_ring) {
pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
bp->rx_ring, bp->rx_ring_dma);
if (bp->flags & B44_FLAG_RX_RING_HACK) {
dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);
kfree(bp->rx_ring);
} else
pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
bp->rx_ring, bp->rx_ring_dma);
bp->rx_ring = NULL;
bp->flags &= ~B44_FLAG_RX_RING_HACK;
}
if (bp->tx_ring) {
pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
bp->tx_ring, bp->tx_ring_dma);
if (bp->flags & B44_FLAG_TX_RING_HACK) {
dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);
kfree(bp->tx_ring);
} else
pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
bp->tx_ring, bp->tx_ring_dma);
bp->tx_ring = NULL;
bp->flags &= ~B44_FLAG_TX_RING_HACK;
}
}
@ -1118,12 +1186,56 @@ static int b44_alloc_consistent(struct b44 *bp)
size = DMA_TABLE_BYTES;
bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
if (!bp->rx_ring)
goto out_err;
if (!bp->rx_ring) {
/* Allocation may have failed due to pci_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive
than necessary... */
struct dma_desc *rx_ring;
dma_addr_t rx_ring_dma;
if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
goto out_err;
memset(rx_ring, 0, size);
rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);
if (rx_ring_dma + size > B44_DMA_MASK) {
kfree(rx_ring);
goto out_err;
}
bp->rx_ring = rx_ring;
bp->rx_ring_dma = rx_ring_dma;
bp->flags |= B44_FLAG_RX_RING_HACK;
}
bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
if (!bp->tx_ring)
goto out_err;
if (!bp->tx_ring) {
/* Allocation may have failed due to pci_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive
than necessary... */
struct dma_desc *tx_ring;
dma_addr_t tx_ring_dma;
if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
goto out_err;
memset(tx_ring, 0, size);
tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);
if (tx_ring_dma + size > B44_DMA_MASK) {
kfree(tx_ring);
goto out_err;
}
bp->tx_ring = tx_ring;
bp->tx_ring_dma = tx_ring_dma;
bp->flags |= B44_FLAG_TX_RING_HACK;
}
return 0;
@ -1676,6 +1788,7 @@ static struct ethtool_ops b44_ethtool_ops = {
.set_pauseparam = b44_set_pauseparam,
.get_msglevel = b44_get_msglevel,
.set_msglevel = b44_set_msglevel,
.get_perm_addr = ethtool_op_get_perm_addr,
};
static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@ -1718,6 +1831,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
bp->dev->dev_addr[3] = eeprom[80];
bp->dev->dev_addr[4] = eeprom[83];
bp->dev->dev_addr[5] = eeprom[82];
memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
bp->phy_addr = eeprom[90] & 0x1f;
@ -1971,6 +2085,12 @@ static struct pci_driver b44_driver = {
static int __init b44_init(void)
{
unsigned int dma_desc_align_size = dma_get_cache_alignment();
/* Setup paramaters for syncing RX/TX DMA descriptors */
dma_desc_align_mask = ~(dma_desc_align_size - 1);
dma_desc_sync_size = max(dma_desc_align_size, sizeof(struct dma_desc));
return pci_module_init(&b44_driver);
}

View File

@ -400,6 +400,8 @@ struct b44 {
#define B44_FLAG_ADV_100HALF 0x04000000
#define B44_FLAG_ADV_100FULL 0x08000000
#define B44_FLAG_INTERNAL_PHY 0x10000000
#define B44_FLAG_RX_RING_HACK 0x20000000
#define B44_FLAG_TX_RING_HACK 0x40000000
u32 rx_offset;

View File

@ -4241,6 +4241,43 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
return 0;
}
static void bond_activebackup_xmit_copy(struct sk_buff *skb,
struct bonding *bond,
struct slave *slave)
{
struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
struct ethhdr *eth_data;
u8 *hwaddr;
int res;
if (!skb2) {
printk(KERN_ERR DRV_NAME ": Error: "
"bond_activebackup_xmit_copy(): skb_copy() failed\n");
return;
}
skb2->mac.raw = (unsigned char *)skb2->data;
eth_data = eth_hdr(skb2);
/* Pick an appropriate source MAC address
* -- use slave's perm MAC addr, unless used by bond
* -- otherwise, borrow active slave's perm MAC addr
* since that will not be used
*/
hwaddr = slave->perm_hwaddr;
if (!memcmp(eth_data->h_source, hwaddr, ETH_ALEN))
hwaddr = bond->curr_active_slave->perm_hwaddr;
/* Set source MAC address appropriately */
memcpy(eth_data->h_source, hwaddr, ETH_ALEN);
res = bond_dev_queue_xmit(bond, skb2, slave->dev);
if (res)
dev_kfree_skb(skb2);
return;
}
/*
* in active-backup mode, we know that bond->curr_active_slave is always valid if
* the bond has a usable interface.
@ -4257,10 +4294,26 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
goto out;
}
if (bond->curr_active_slave) { /* one usable interface */
res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
if (!bond->curr_active_slave)
goto out;
/* Xmit IGMP frames on all slaves to ensure rapid fail-over
for multicast traffic on snooping switches */
if (skb->protocol == __constant_htons(ETH_P_IP) &&
skb->nh.iph->protocol == IPPROTO_IGMP) {
struct slave *slave, *active_slave;
int i;
active_slave = bond->curr_active_slave;
bond_for_each_slave_from_to(bond, slave, i, active_slave->next,
active_slave->prev)
if (IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP))
bond_activebackup_xmit_copy(skb, bond, slave);
}
res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
out:
if (res) {
/* no suitable interface, frame not sent */

View File

@ -5,7 +5,7 @@
*
* adopted from sunlance.c by Richard van den Berg
*
* Copyright (C) 2002, 2003 Maciej W. Rozycki
* Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
*
* additional sources:
* - PMAD-AA TURBOchannel Ethernet Module Functional Specification,
@ -57,13 +57,15 @@
#include <linux/string.h>
#include <asm/addrspace.h>
#include <asm/system.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/kn01.h>
#include <asm/dec/machtype.h>
#include <asm/dec/system.h>
#include <asm/dec/tc.h>
#include <asm/system.h>
static char version[] __devinitdata =
"declance.c: v0.009 by Linux MIPS DECstation task force\n";
@ -79,10 +81,6 @@ MODULE_LICENSE("GPL");
#define PMAD_LANCE 2
#define PMAX_LANCE 3
#ifndef CONFIG_TC
unsigned long system_base;
unsigned long dmaptr;
#endif
#define LE_CSR0 0
#define LE_CSR1 1
@ -237,7 +235,7 @@ struct lance_init_block {
/*
* This works *only* for the ring descriptors
*/
#define LANCE_ADDR(x) (PHYSADDR(x) >> 1)
#define LANCE_ADDR(x) (CPHYSADDR(x) >> 1)
struct lance_private {
struct net_device *next;
@ -697,12 +695,13 @@ static void lance_tx(struct net_device *dev)
spin_unlock(&lp->lock);
}
static void lance_dma_merr_int(const int irq, void *dev_id,
struct pt_regs *regs)
static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id,
struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_id;
printk("%s: DMA error\n", dev->name);
return IRQ_HANDLED;
}
static irqreturn_t
@ -1026,10 +1025,6 @@ static int __init dec_lance_init(const int type, const int slot)
unsigned long esar_base;
unsigned char *esar;
#ifndef CONFIG_TC
system_base = KN01_LANCE_BASE;
#endif
if (dec_lance_debug && version_printed++ == 0)
printk(version);
@ -1062,16 +1057,16 @@ static int __init dec_lance_init(const int type, const int slot)
switch (type) {
#ifdef CONFIG_TC
case ASIC_LANCE:
dev->base_addr = system_base + IOASIC_LANCE;
dev->base_addr = CKSEG1ADDR(dec_kn_slot_base + IOASIC_LANCE);
/* buffer space for the on-board LANCE shared memory */
/*
* FIXME: ugly hack!
*/
dev->mem_start = KSEG1ADDR(0x00020000);
dev->mem_start = CKSEG1ADDR(0x00020000);
dev->mem_end = dev->mem_start + 0x00020000;
dev->irq = dec_interrupt[DEC_IRQ_LANCE];
esar_base = system_base + IOASIC_ESAR;
esar_base = CKSEG1ADDR(dec_kn_slot_base + IOASIC_ESAR);
/* Workaround crash with booting KN04 2.1k from Disk */
memset((void *)dev->mem_start, 0,
@ -1101,14 +1096,14 @@ static int __init dec_lance_init(const int type, const int slot)
/* Setup I/O ASIC LANCE DMA. */
lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR];
ioasic_write(IO_REG_LANCE_DMA_P,
PHYSADDR(dev->mem_start) << 3);
CPHYSADDR(dev->mem_start) << 3);
break;
case PMAD_LANCE:
claim_tc_card(slot);
dev->mem_start = get_tc_base_addr(slot);
dev->mem_start = CKSEG1ADDR(get_tc_base_addr(slot));
dev->base_addr = dev->mem_start + 0x100000;
dev->irq = get_tc_irq_nr(slot);
esar_base = dev->mem_start + 0x1c0002;
@ -1137,9 +1132,9 @@ static int __init dec_lance_init(const int type, const int slot)
case PMAX_LANCE:
dev->irq = dec_interrupt[DEC_IRQ_LANCE];
dev->base_addr = KN01_LANCE_BASE;
dev->mem_start = KN01_LANCE_BASE + 0x01000000;
esar_base = KN01_RTC_BASE + 1;
dev->base_addr = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE);
dev->mem_start = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE_MEM);
esar_base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_ESAR + 1);
lp->dma_irq = -1;
/*

View File

@ -2201,6 +2201,7 @@ static struct ethtool_ops e100_ethtool_ops = {
.phys_id = e100_phys_id,
.get_stats_count = e100_get_stats_count,
.get_ethtool_stats = e100_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr,
};
static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
@ -2351,7 +2352,8 @@ static int __devinit e100_probe(struct pci_dev *pdev,
e100_phy_init(nic);
memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
if(!is_valid_ether_addr(netdev->dev_addr)) {
memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN);
if(!is_valid_ether_addr(netdev->perm_addr)) {
DPRINTK(PROBE, ERR, "Invalid MAC address from "
"EEPROM, aborting.\n");
err = -EAGAIN;

View File

@ -72,6 +72,10 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#ifdef CONFIG_E1000_MQ
#include <linux/cpu.h>
#include <linux/smp.h>
#endif
#define BAR_0 0
#define BAR_1 1
@ -165,10 +169,33 @@ struct e1000_buffer {
uint16_t next_to_watch;
};
struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; };
struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; };
struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; };
struct e1000_ps_page_dma { uint64_t ps_page_dma[PS_PAGE_BUFFERS]; };
struct e1000_desc_ring {
struct e1000_tx_ring {
/* pointer to the descriptor ring memory */
void *desc;
/* physical address of the descriptor ring */
dma_addr_t dma;
/* length of descriptor ring in bytes */
unsigned int size;
/* number of descriptors in the ring */
unsigned int count;
/* next descriptor to associate a buffer with */
unsigned int next_to_use;
/* next descriptor to check for DD status bit */
unsigned int next_to_clean;
/* array of buffer information structs */
struct e1000_buffer *buffer_info;
struct e1000_buffer previous_buffer_info;
spinlock_t tx_lock;
uint16_t tdh;
uint16_t tdt;
uint64_t pkt;
};
struct e1000_rx_ring {
/* pointer to the descriptor ring memory */
void *desc;
/* physical address of the descriptor ring */
@ -186,6 +213,10 @@ struct e1000_desc_ring {
/* arrays of page information for packet split */
struct e1000_ps_page *ps_page;
struct e1000_ps_page_dma *ps_page_dma;
uint16_t rdh;
uint16_t rdt;
uint64_t pkt;
};
#define E1000_DESC_UNUSED(R) \
@ -227,9 +258,10 @@ struct e1000_adapter {
unsigned long led_status;
/* TX */
struct e1000_desc_ring tx_ring;
struct e1000_buffer previous_buffer_info;
spinlock_t tx_lock;
struct e1000_tx_ring *tx_ring; /* One per active queue */
#ifdef CONFIG_E1000_MQ
struct e1000_tx_ring **cpu_tx_ring; /* per-cpu */
#endif
uint32_t txd_cmd;
uint32_t tx_int_delay;
uint32_t tx_abs_int_delay;
@ -246,19 +278,33 @@ struct e1000_adapter {
/* RX */
#ifdef CONFIG_E1000_NAPI
boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done,
int work_to_do);
boolean_t (*clean_rx) (struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring,
int *work_done, int work_to_do);
#else
boolean_t (*clean_rx) (struct e1000_adapter *adapter);
boolean_t (*clean_rx) (struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring);
#endif
void (*alloc_rx_buf) (struct e1000_adapter *adapter);
struct e1000_desc_ring rx_ring;
void (*alloc_rx_buf) (struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring);
struct e1000_rx_ring *rx_ring; /* One per active queue */
#ifdef CONFIG_E1000_NAPI
struct net_device *polling_netdev; /* One per active queue */
#endif
#ifdef CONFIG_E1000_MQ
struct net_device **cpu_netdev; /* per-cpu */
struct call_async_data_struct rx_sched_call_data;
int cpu_for_queue[4];
#endif
int num_queues;
uint64_t hw_csum_err;
uint64_t hw_csum_good;
uint64_t rx_hdr_split;
uint32_t rx_int_delay;
uint32_t rx_abs_int_delay;
boolean_t rx_csum;
boolean_t rx_ps;
unsigned int rx_ps_pages;
uint32_t gorcl;
uint64_t gorcl_old;
uint16_t rx_ps_bsize0;
@ -278,8 +324,8 @@ struct e1000_adapter {
struct e1000_phy_stats phy_stats;
uint32_t test_icr;
struct e1000_desc_ring test_tx_ring;
struct e1000_desc_ring test_rx_ring;
struct e1000_tx_ring test_tx_ring;
struct e1000_rx_ring test_rx_ring;
int msg_enable;

View File

@ -39,10 +39,10 @@ extern int e1000_up(struct e1000_adapter *adapter);
extern void e1000_down(struct e1000_adapter *adapter);
extern void e1000_reset(struct e1000_adapter *adapter);
extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_update_stats(struct e1000_adapter *adapter);
struct e1000_stats {
@ -91,7 +91,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
{ "rx_long_byte_count", E1000_STAT(stats.gorcl) },
{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }
{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
{ "rx_header_split", E1000_STAT(rx_hdr_split) },
};
#define E1000_STATS_LEN \
sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
@ -546,8 +547,10 @@ e1000_set_eeprom(struct net_device *netdev,
ret_val = e1000_write_eeprom(hw, first_word,
last_word - first_word + 1, eeprom_buff);
/* Update the checksum over the first part of the EEPROM if needed */
if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
/* Update the checksum over the first part of the EEPROM if needed
* and flush shadow RAM for 82573 conrollers */
if((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) ||
(hw->mac_type == e1000_82573)))
e1000_update_eeprom_checksum(hw);
kfree(eeprom_buff);
@ -576,8 +579,8 @@ e1000_get_ringparam(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
struct e1000_desc_ring *txdr = &adapter->tx_ring;
struct e1000_desc_ring *rxdr = &adapter->rx_ring;
struct e1000_tx_ring *txdr = adapter->tx_ring;
struct e1000_rx_ring *rxdr = adapter->rx_ring;
ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
E1000_MAX_82544_RXD;
@ -597,20 +600,40 @@ e1000_set_ringparam(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type;
struct e1000_desc_ring *txdr = &adapter->tx_ring;
struct e1000_desc_ring *rxdr = &adapter->rx_ring;
struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new;
int err;
struct e1000_tx_ring *txdr, *tx_old, *tx_new;
struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
int i, err, tx_ring_size, rx_ring_size;
tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
if (netif_running(adapter->netdev))
e1000_down(adapter);
tx_old = adapter->tx_ring;
rx_old = adapter->rx_ring;
adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
if (!adapter->tx_ring) {
err = -ENOMEM;
goto err_setup_rx;
}
memset(adapter->tx_ring, 0, tx_ring_size);
adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
if (!adapter->rx_ring) {
kfree(adapter->tx_ring);
err = -ENOMEM;
goto err_setup_rx;
}
memset(adapter->rx_ring, 0, rx_ring_size);
txdr = adapter->tx_ring;
rxdr = adapter->rx_ring;
if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
if(netif_running(adapter->netdev))
e1000_down(adapter);
rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
E1000_MAX_RXD : E1000_MAX_82544_RXD));
@ -621,11 +644,16 @@ e1000_set_ringparam(struct net_device *netdev,
E1000_MAX_TXD : E1000_MAX_82544_TXD));
E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
for (i = 0; i < adapter->num_queues; i++) {
txdr[i].count = txdr->count;
rxdr[i].count = rxdr->count;
}
if(netif_running(adapter->netdev)) {
/* Try to get new resources before deleting old */
if((err = e1000_setup_rx_resources(adapter)))
if ((err = e1000_setup_all_rx_resources(adapter)))
goto err_setup_rx;
if((err = e1000_setup_tx_resources(adapter)))
if ((err = e1000_setup_all_tx_resources(adapter)))
goto err_setup_tx;
/* save the new, restore the old in order to free it,
@ -635,8 +663,10 @@ e1000_set_ringparam(struct net_device *netdev,
tx_new = adapter->tx_ring;
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
e1000_free_rx_resources(adapter);
e1000_free_tx_resources(adapter);
e1000_free_all_rx_resources(adapter);
e1000_free_all_tx_resources(adapter);
kfree(tx_old);
kfree(rx_old);
adapter->rx_ring = rx_new;
adapter->tx_ring = tx_new;
if((err = e1000_up(adapter)))
@ -645,7 +675,7 @@ e1000_set_ringparam(struct net_device *netdev,
return 0;
err_setup_tx:
e1000_free_rx_resources(adapter);
e1000_free_all_rx_resources(adapter);
err_setup_rx:
adapter->rx_ring = rx_old;
adapter->tx_ring = tx_old;
@ -696,6 +726,11 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
* Some bits that get toggled are ignored.
*/
switch (adapter->hw.mac_type) {
/* there are several bits on newer hardware that are r/w */
case e1000_82571:
case e1000_82572:
toggle = 0x7FFFF3FF;
break;
case e1000_82573:
toggle = 0x7FFFF033;
break;
@ -898,8 +933,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
static void
e1000_free_desc_rings(struct e1000_adapter *adapter)
{
struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
int i;
@ -941,8 +976,8 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
static int
e1000_setup_desc_rings(struct e1000_adapter *adapter)
{
struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
uint32_t rctl;
int size, i, ret_val;
@ -1245,6 +1280,8 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter)
case e1000_82541_rev_2:
case e1000_82547:
case e1000_82547_rev_2:
case e1000_82571:
case e1000_82572:
case e1000_82573:
return e1000_integrated_phy_loopback(adapter);
break;
@ -1340,8 +1377,8 @@ e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
static int
e1000_run_loopback_test(struct e1000_adapter *adapter)
{
struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
int i, j, k, l, lc, good_cnt, ret_val=0;
unsigned long time;
@ -1509,6 +1546,7 @@ e1000_diag_test(struct net_device *netdev,
data[2] = 0;
data[3] = 0;
}
msleep_interruptible(4 * 1000);
}
static void
@ -1625,7 +1663,7 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
if(adapter->hw.mac_type < e1000_82573) {
if(adapter->hw.mac_type < e1000_82571) {
if(!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function = e1000_led_blink_callback;
@ -1739,6 +1777,7 @@ struct ethtool_ops e1000_ethtool_ops = {
.phys_id = e1000_phys_id,
.get_stats_count = e1000_get_stats_count,
.get_ethtool_stats = e1000_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr,
};
void e1000_set_ethtool_ops(struct net_device *netdev)

View File

@ -83,14 +83,14 @@ uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
static const
uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
{ 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43,
22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58,
32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74,
43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90,
57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108,
73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124,
91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128,
108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
104, 109, 114, 118, 121, 124};
/******************************************************************************
@ -286,7 +286,6 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82546GB_FIBER:
case E1000_DEV_ID_82546GB_SERDES:
case E1000_DEV_ID_82546GB_PCIE:
case E1000_DEV_ID_82546GB_QUAD_COPPER:
hw->mac_type = e1000_82546_rev_3;
break;
case E1000_DEV_ID_82541EI:
@ -305,8 +304,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82547GI:
hw->mac_type = e1000_82547_rev_2;
break;
case E1000_DEV_ID_82571EB_COPPER:
case E1000_DEV_ID_82571EB_FIBER:
case E1000_DEV_ID_82571EB_SERDES:
hw->mac_type = e1000_82571;
break;
case E1000_DEV_ID_82572EI_COPPER:
case E1000_DEV_ID_82572EI_FIBER:
case E1000_DEV_ID_82572EI_SERDES:
hw->mac_type = e1000_82572;
break;
case E1000_DEV_ID_82573E:
case E1000_DEV_ID_82573E_IAMT:
case E1000_DEV_ID_82573L:
hw->mac_type = e1000_82573;
break;
default:
@ -315,6 +325,8 @@ e1000_set_mac_type(struct e1000_hw *hw)
}
switch(hw->mac_type) {
case e1000_82571:
case e1000_82572:
case e1000_82573:
hw->eeprom_semaphore_present = TRUE;
/* fall through */
@ -351,6 +363,8 @@ e1000_set_media_type(struct e1000_hw *hw)
switch (hw->device_id) {
case E1000_DEV_ID_82545GM_SERDES:
case E1000_DEV_ID_82546GB_SERDES:
case E1000_DEV_ID_82571EB_SERDES:
case E1000_DEV_ID_82572EI_SERDES:
hw->media_type = e1000_media_type_internal_serdes;
break;
default:
@ -523,6 +537,8 @@ e1000_reset_hw(struct e1000_hw *hw)
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
/* fall through */
case e1000_82571:
case e1000_82572:
ret_val = e1000_get_auto_rd_done(hw);
if(ret_val)
/* We don't want to continue accessing MAC registers. */
@ -683,6 +699,9 @@ e1000_init_hw(struct e1000_hw *hw)
switch (hw->mac_type) {
default:
break;
case e1000_82571:
case e1000_82572:
ctrl |= (1 << 22);
case e1000_82573:
ctrl |= E1000_TXDCTL_COUNT_DESC;
break;
@ -694,6 +713,26 @@ e1000_init_hw(struct e1000_hw *hw)
e1000_enable_tx_pkt_filtering(hw);
}
switch (hw->mac_type) {
default:
break;
case e1000_82571:
case e1000_82572:
ctrl = E1000_READ_REG(hw, TXDCTL1);
ctrl &= ~E1000_TXDCTL_WTHRESH;
ctrl |= E1000_TXDCTL_COUNT_DESC | E1000_TXDCTL_FULL_TX_DESC_WB;
ctrl |= (1 << 22);
E1000_WRITE_REG(hw, TXDCTL1, ctrl);
break;
}
if (hw->mac_type == e1000_82573) {
uint32_t gcr = E1000_READ_REG(hw, GCR);
gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
E1000_WRITE_REG(hw, GCR, gcr);
}
/* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
@ -878,6 +917,14 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
DEBUGFUNC("e1000_setup_fiber_serdes_link");
/* On 82571 and 82572 Fiber connections, SerDes loopback mode persists
* until explicitly turned off or a power cycle is performed. A read to
* the register does not indicate its status. Therefore, we ensure
* loopback mode is disabled during initialization.
*/
if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
/* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
* set when the optics detect a signal. On older adapters, it will be
* cleared when there is a signal. This applies to fiber media only.
@ -2943,6 +2990,8 @@ e1000_phy_reset(struct e1000_hw *hw)
switch (hw->mac_type) {
case e1000_82541_rev_2:
case e1000_82571:
case e1000_82572:
ret_val = e1000_phy_hw_reset(hw);
if(ret_val)
return ret_val;
@ -2981,6 +3030,16 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
DEBUGFUNC("e1000_detect_gig_phy");
/* The 82571 firmware may still be configuring the PHY. In this
* case, we cannot access the PHY until the configuration is done. So
* we explicitly set the PHY values. */
if(hw->mac_type == e1000_82571 ||
hw->mac_type == e1000_82572) {
hw->phy_id = IGP01E1000_I_PHY_ID;
hw->phy_type = e1000_phy_igp_2;
return E1000_SUCCESS;
}
/* Read the PHY ID Registers to identify which PHY is onboard. */
ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
if(ret_val)
@ -3334,6 +3393,21 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->use_eerd = FALSE;
eeprom->use_eewr = FALSE;
break;
case e1000_82571:
case e1000_82572:
eeprom->type = e1000_eeprom_spi;
eeprom->opcode_bits = 8;
eeprom->delay_usec = 1;
if (eecd & E1000_EECD_ADDR_BITS) {
eeprom->page_size = 32;
eeprom->address_bits = 16;
} else {
eeprom->page_size = 8;
eeprom->address_bits = 8;
}
eeprom->use_eerd = FALSE;
eeprom->use_eewr = FALSE;
break;
case e1000_82573:
eeprom->type = e1000_eeprom_spi;
eeprom->opcode_bits = 8;
@ -3543,25 +3617,26 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
eecd = E1000_READ_REG(hw, EECD);
if (hw->mac_type != e1000_82573) {
/* Request EEPROM Access */
if(hw->mac_type > e1000_82544) {
eecd |= E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
eecd = E1000_READ_REG(hw, EECD);
while((!(eecd & E1000_EECD_GNT)) &&
(i < E1000_EEPROM_GRANT_ATTEMPTS)) {
i++;
udelay(5);
eecd = E1000_READ_REG(hw, EECD);
}
if(!(eecd & E1000_EECD_GNT)) {
eecd &= ~E1000_EECD_REQ;
/* Request EEPROM Access */
if(hw->mac_type > e1000_82544) {
eecd |= E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
DEBUGOUT("Could not acquire EEPROM grant\n");
return -E1000_ERR_EEPROM;
eecd = E1000_READ_REG(hw, EECD);
while((!(eecd & E1000_EECD_GNT)) &&
(i < E1000_EEPROM_GRANT_ATTEMPTS)) {
i++;
udelay(5);
eecd = E1000_READ_REG(hw, EECD);
}
if(!(eecd & E1000_EECD_GNT)) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, EECD, eecd);
DEBUGOUT("Could not acquire EEPROM grant\n");
e1000_put_hw_eeprom_semaphore(hw);
return -E1000_ERR_EEPROM;
}
}
}
}
/* Setup EEPROM for Read/Write */
@ -4064,7 +4139,7 @@ e1000_write_eeprom(struct e1000_hw *hw,
return -E1000_ERR_EEPROM;
}
/* 82573 reads only through eerd */
/* 82573 writes only through eewr */
if(eeprom->use_eewr == TRUE)
return e1000_write_eeprom_eewr(hw, offset, words, data);
@ -4353,9 +4428,16 @@ e1000_read_mac_addr(struct e1000_hw * hw)
hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
}
if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
switch (hw->mac_type) {
default:
break;
case e1000_82546:
case e1000_82546_rev_3:
case e1000_82571:
if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
hw->perm_mac_addr[5] ^= 0x01;
break;
}
for(i = 0; i < NODE_ADDRESS_SIZE; i++)
hw->mac_addr[i] = hw->perm_mac_addr[i];
@ -4385,6 +4467,12 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
e1000_rar_set(hw, hw->mac_addr, 0);
rar_num = E1000_RAR_ENTRIES;
/* Reserve a spot for the Locally Administered Address to work around
* an 82571 issue in which a reset on one port will reload the MAC on
* the other port. */
if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
rar_num -= 1;
/* Zero out the other 15 receive addresses. */
DEBUGOUT("Clearing RAR[1-15]\n");
for(i = 1; i < rar_num; i++) {
@ -4427,6 +4515,12 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
/* Clear RAR[1-15] */
DEBUGOUT(" Clearing RAR[1-15]\n");
num_rar_entry = E1000_RAR_ENTRIES;
/* Reserve a spot for the Locally Administered Address to work around
* an 82571 issue in which a reset on one port will reload the MAC on
* the other port. */
if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
num_rar_entry -= 1;
for(i = rar_used_count; i < num_rar_entry; i++) {
E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
@ -4984,7 +5078,6 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw)
temp = E1000_READ_REG(hw, ICTXQEC);
temp = E1000_READ_REG(hw, ICTXQMTC);
temp = E1000_READ_REG(hw, ICRXDMTC);
}
/******************************************************************************
@ -5151,6 +5244,8 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw->bus_speed = e1000_bus_speed_unknown;
hw->bus_width = e1000_bus_width_unknown;
break;
case e1000_82571:
case e1000_82572:
case e1000_82573:
hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500;
@ -5250,6 +5345,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
int32_t ret_val;
uint16_t agc_value = 0;
uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
uint16_t max_agc = 0;
uint16_t i, phy_data;
uint16_t cable_length;
@ -5338,6 +5434,40 @@ e1000_get_cable_length(struct e1000_hw *hw,
IGP01E1000_AGC_RANGE) : 0;
*max_length = e1000_igp_cable_length_table[agc_value] +
IGP01E1000_AGC_RANGE;
} else if (hw->phy_type == e1000_phy_igp_2) {
uint16_t agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
{IGP02E1000_PHY_AGC_A,
IGP02E1000_PHY_AGC_B,
IGP02E1000_PHY_AGC_C,
IGP02E1000_PHY_AGC_D};
/* Read the AGC registers for all channels */
for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
if (ret_val)
return ret_val;
/* Getting bits 15:9, which represent the combination of course and
* fine gain values. The result is a number that can be put into
* the lookup table to obtain the approximate cable length. */
cur_agc = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
IGP02E1000_AGC_LENGTH_MASK;
/* Remove min & max AGC values from calculation. */
if (e1000_igp_2_cable_length_table[min_agc] > e1000_igp_2_cable_length_table[cur_agc])
min_agc = cur_agc;
if (e1000_igp_2_cable_length_table[max_agc] < e1000_igp_2_cable_length_table[cur_agc])
max_agc = cur_agc;
agc_value += e1000_igp_2_cable_length_table[cur_agc];
}
agc_value -= (e1000_igp_2_cable_length_table[min_agc] + e1000_igp_2_cable_length_table[max_agc]);
agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
/* Calculate cable length with the error range of +/- 10 meters. */
*min_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
(agc_value - IGP02E1000_AGC_RANGE) : 0;
*max_length = agc_value + IGP02E1000_AGC_RANGE;
}
return E1000_SUCCESS;
@ -6465,6 +6595,8 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
default:
msec_delay(5);
break;
case e1000_82571:
case e1000_82572:
case e1000_82573:
while(timeout) {
if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break;
@ -6494,10 +6626,31 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
int32_t
e1000_get_phy_cfg_done(struct e1000_hw *hw)
{
int32_t timeout = PHY_CFG_TIMEOUT;
uint32_t cfg_mask = E1000_EEPROM_CFG_DONE;
DEBUGFUNC("e1000_get_phy_cfg_done");
/* Simply wait for 10ms */
msec_delay(10);
switch (hw->mac_type) {
default:
msec_delay(10);
break;
case e1000_82571:
case e1000_82572:
while (timeout) {
if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask)
break;
else
msec_delay(1);
timeout--;
}
if (!timeout) {
DEBUGOUT("MNG configuration cycle has not completed.\n");
return -E1000_ERR_RESET;
}
break;
}
return E1000_SUCCESS;
}
@ -6569,8 +6722,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
return;
swsm = E1000_READ_REG(hw, SWSM);
/* Release both semaphores. */
swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
swsm &= ~(E1000_SWSM_SWESMBI);
E1000_WRITE_REG(hw, SWSM, swsm);
}
@ -6606,6 +6758,8 @@ e1000_arc_subsystem_valid(struct e1000_hw *hw)
* if this is the case. We read FWSM to determine the manageability mode.
*/
switch (hw->mac_type) {
case e1000_82571:
case e1000_82572:
case e1000_82573:
fwsm = E1000_READ_REG(hw, FWSM);
if((fwsm & E1000_FWSM_MODE_MASK) != 0)

View File

@ -57,6 +57,8 @@ typedef enum {
e1000_82541_rev_2,
e1000_82547,
e1000_82547_rev_2,
e1000_82571,
e1000_82572,
e1000_82573,
e1000_num_macs
} e1000_mac_type;
@ -478,10 +480,16 @@ uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
#define E1000_DEV_ID_82546GB_SERDES 0x107B
#define E1000_DEV_ID_82546GB_PCIE 0x108A
#define E1000_DEV_ID_82547EI 0x1019
#define E1000_DEV_ID_82571EB_COPPER 0x105E
#define E1000_DEV_ID_82571EB_FIBER 0x105F
#define E1000_DEV_ID_82571EB_SERDES 0x1060
#define E1000_DEV_ID_82572EI_COPPER 0x107D
#define E1000_DEV_ID_82572EI_FIBER 0x107E
#define E1000_DEV_ID_82572EI_SERDES 0x107F
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82573L 0x109A
#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
#define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6
@ -833,6 +841,8 @@ struct e1000_ffvt_entry {
#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
#define E1000_DISABLE_SERDES_LOOPBACK 0x0400
/* Register Set. (82543, 82544)
*
* Registers are defined to be 32 bits and should be accessed as 32 bit values.
@ -853,6 +863,7 @@ struct e1000_ffvt_entry {
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_FLA 0x0001C /* Flash Access - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
@ -864,6 +875,12 @@ struct e1000_ffvt_entry {
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_RCTL 0x00100 /* RX Control - RW */
#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
@ -895,6 +912,12 @@ struct e1000_ffvt_entry {
#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */
#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */
#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */
#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */
#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */
#define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */
#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
@ -980,15 +1003,15 @@ struct e1000_ffvt_entry {
#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
#define E1000_IAC 0x4100 /* Interrupt Assertion Count */
#define E1000_ICRXPTC 0x4104 /* Interrupt Cause Rx Packet Timer Expire Count */
#define E1000_ICRXATC 0x4108 /* Interrupt Cause Rx Absolute Timer Expire Count */
#define E1000_ICTXPTC 0x410C /* Interrupt Cause Tx Packet Timer Expire Count */
#define E1000_ICTXATC 0x4110 /* Interrupt Cause Tx Absolute Timer Expire Count */
#define E1000_ICTXQEC 0x4118 /* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQMTC 0x411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
#define E1000_ICRXDMTC 0x4120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXOC 0x4124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */
#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */
#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */
#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
@ -1018,6 +1041,14 @@ struct e1000_ffvt_entry {
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Inteface Control */
/* RSS registers */
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
/* Register Set (82542)
*
* Some of the 82542 registers are located at different offsets than they are
@ -1032,6 +1063,7 @@ struct e1000_ffvt_entry {
#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
#define E1000_82542_FLA E1000_FLA
#define E1000_82542_MDIC E1000_MDIC
#define E1000_82542_SCTL E1000_SCTL
#define E1000_82542_FCAL E1000_FCAL
#define E1000_82542_FCAH E1000_FCAH
#define E1000_82542_FCT E1000_FCT
@ -1049,6 +1081,18 @@ struct e1000_ffvt_entry {
#define E1000_82542_RDLEN 0x00118
#define E1000_82542_RDH 0x00120
#define E1000_82542_RDT 0x00128
#define E1000_82542_RDTR0 E1000_82542_RDTR
#define E1000_82542_RDBAL0 E1000_82542_RDBAL
#define E1000_82542_RDBAH0 E1000_82542_RDBAH
#define E1000_82542_RDLEN0 E1000_82542_RDLEN
#define E1000_82542_RDH0 E1000_82542_RDH
#define E1000_82542_RDT0 E1000_82542_RDT
#define E1000_82542_RDTR1 0x00130
#define E1000_82542_RDBAL1 0x00138
#define E1000_82542_RDBAH1 0x0013C
#define E1000_82542_RDLEN1 0x00140
#define E1000_82542_RDH1 0x00148
#define E1000_82542_RDT1 0x00150
#define E1000_82542_FCRTH 0x00160
#define E1000_82542_FCRTL 0x00168
#define E1000_82542_FCTTV E1000_FCTTV
@ -1197,6 +1241,13 @@ struct e1000_ffvt_entry {
#define E1000_82542_ICRXOC E1000_ICRXOC
#define E1000_82542_HICR E1000_HICR
#define E1000_82542_CPUVEC E1000_CPUVEC
#define E1000_82542_MRQC E1000_MRQC
#define E1000_82542_RETA E1000_RETA
#define E1000_82542_RSSRK E1000_RSSRK
#define E1000_82542_RSSIM E1000_RSSIM
#define E1000_82542_RSSIR E1000_RSSIR
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
uint64_t crcerrs;
@ -1336,6 +1387,7 @@ struct e1000_hw {
boolean_t serdes_link_down;
boolean_t tbi_compatibility_en;
boolean_t tbi_compatibility_on;
boolean_t laa_is_present;
boolean_t phy_reset_disable;
boolean_t fc_send_xon;
boolean_t fc_strict_ieee;
@ -1374,6 +1426,7 @@ struct e1000_hw {
#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */
#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
@ -1491,6 +1544,8 @@ struct e1000_hw {
#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
#define E1000_CTRL_EXT_CANC 0x04000000 /* Interrupt delay cancellation */
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
@ -1524,6 +1579,7 @@ struct e1000_hw {
#define E1000_LEDCTL_LED2_BLINK 0x00800000
#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
#define E1000_LEDCTL_LED3_MODE_SHIFT 24
#define E1000_LEDCTL_LED3_BLINK_RATE 0x20000000
#define E1000_LEDCTL_LED3_IVRT 0x40000000
#define E1000_LEDCTL_LED3_BLINK 0x80000000
@ -1784,6 +1840,16 @@ struct e1000_hw {
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* Multiple Receive Queue Control */
#define E1000_MRQC_ENABLE_MASK 0x00000003
#define E1000_MRQC_ENABLE_RSS_2Q 0x00000001
#define E1000_MRQC_ENABLE_RSS_INT 0x00000004
#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00040000
#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000
#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
/* Definitions for power management and wakeup registers */
/* Wake Up Control */
@ -1928,6 +1994,7 @@ struct e1000_host_command_info {
#define E1000_MDALIGN 4096
#define E1000_GCR_BEM32 0x00400000
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
/* Function Active and Power State to MNG */
#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003
#define E1000_FACTPS_LAN0_VALID 0x00000004
@ -1980,6 +2047,7 @@ struct e1000_host_command_info {
/* EEPROM Word Offsets */
#define EEPROM_COMPAT 0x0003
#define EEPROM_ID_LED_SETTINGS 0x0004
#define EEPROM_VERSION 0x0005
#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
#define EEPROM_PHY_CLASS_WORD 0x0007
#define EEPROM_INIT_CONTROL1_REG 0x000A
@ -1990,6 +2058,8 @@ struct e1000_host_command_info {
#define EEPROM_FLASH_VERSION 0x0032
#define EEPROM_CHECKSUM_REG 0x003F
#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
/* Word definitions for ID LED Settings */
#define ID_LED_RESERVED_0000 0x0000
#define ID_LED_RESERVED_FFFF 0xFFFF
@ -2108,6 +2178,8 @@ struct e1000_host_command_info {
#define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018
#define E1000_PBA_30K 0x001E
#define E1000_PBA_32K 0x0020
#define E1000_PBA_38K 0x0026
#define E1000_PBA_40K 0x0028
#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
@ -2592,11 +2664,11 @@ struct e1000_host_command_info {
/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128
#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 113
/* The precision error of the cable length is +/- 10 meters */
#define IGP01E1000_AGC_RANGE 10
#define IGP02E1000_AGC_RANGE 10
#define IGP02E1000_AGC_RANGE 15
/* IGP01E1000 PCS Initialization register */
/* bits 3:6 in the PCS registers stores the channels polarity */

File diff suppressed because it is too large Load Diff

View File

@ -306,7 +306,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.def = E1000_DEFAULT_TXD,
.arg = { .r = { .min = E1000_MIN_TXD }}
};
struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
struct e1000_tx_ring *tx_ring = adapter->tx_ring;
int i;
e1000_mac_type mac_type = adapter->hw.mac_type;
opt.arg.r.max = mac_type < e1000_82544 ?
E1000_MAX_TXD : E1000_MAX_82544_TXD;
@ -319,6 +320,8 @@ e1000_check_options(struct e1000_adapter *adapter)
} else {
tx_ring->count = opt.def;
}
for (i = 0; i < adapter->num_queues; i++)
tx_ring[i].count = tx_ring->count;
}
{ /* Receive Descriptor Count */
struct e1000_option opt = {
@ -329,7 +332,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.def = E1000_DEFAULT_RXD,
.arg = { .r = { .min = E1000_MIN_RXD }}
};
struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
struct e1000_rx_ring *rx_ring = adapter->rx_ring;
int i;
e1000_mac_type mac_type = adapter->hw.mac_type;
opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
E1000_MAX_82544_RXD;
@ -342,6 +346,8 @@ e1000_check_options(struct e1000_adapter *adapter)
} else {
rx_ring->count = opt.def;
}
for (i = 0; i < adapter->num_queues; i++)
rx_ring[i].count = rx_ring->count;
}
{ /* Checksum Offload Enable/Disable */
struct e1000_option opt = {

View File

@ -1334,7 +1334,7 @@ static void epic_rx_err(struct net_device *dev, struct epic_private *ep)
static int epic_poll(struct net_device *dev, int *budget)
{
struct epic_private *ep = dev->priv;
int work_done, orig_budget;
int work_done = 0, orig_budget;
long ioaddr = dev->base_addr;
orig_budget = (*budget > dev->quota) ? dev->quota : *budget;
@ -1343,7 +1343,7 @@ static int epic_poll(struct net_device *dev, int *budget)
epic_tx(dev, ep);
work_done = epic_rx(dev, *budget);
work_done += epic_rx(dev, *budget);
epic_rx_err(dev, ep);

View File

@ -95,6 +95,8 @@
* of nv_remove
* 0.42: 06 Aug 2005: Fix lack of link speed initialization
* in the second (and later) nv_open call
* 0.43: 10 Aug 2005: Add support for tx checksum.
* 0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
*
* Known bugs:
* We suspect that on some hardware no TX done interrupts are generated.
@ -106,7 +108,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.41"
#define FORCEDETH_VERSION "0.44"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@ -145,6 +147,7 @@
#define DEV_NEED_LINKTIMER 0x0002 /* poll link settings. Relies on the timer irq */
#define DEV_HAS_LARGEDESC 0x0004 /* device supports jumbo frames and needs packet format 2 */
#define DEV_HAS_HIGH_DMA 0x0008 /* device supports 64bit dma */
#define DEV_HAS_CHECKSUM 0x0010 /* device supports tx and rx checksum offloads */
enum {
NvRegIrqStatus = 0x000,
@ -241,6 +244,9 @@ enum {
#define NVREG_TXRXCTL_IDLE 0x0008
#define NVREG_TXRXCTL_RESET 0x0010
#define NVREG_TXRXCTL_RXCHECK 0x0400
#define NVREG_TXRXCTL_DESC_1 0
#define NVREG_TXRXCTL_DESC_2 0x02100
#define NVREG_TXRXCTL_DESC_3 0x02200
NvRegMIIStatus = 0x180,
#define NVREG_MIISTAT_ERROR 0x0001
#define NVREG_MIISTAT_LINKCHANGE 0x0008
@ -335,6 +341,10 @@ typedef union _ring_type {
/* error and valid are the same for both */
#define NV_TX2_ERROR (1<<30)
#define NV_TX2_VALID (1<<31)
#define NV_TX2_TSO (1<<28)
#define NV_TX2_TSO_SHIFT 14
#define NV_TX2_CHECKSUM_L3 (1<<27)
#define NV_TX2_CHECKSUM_L4 (1<<26)
#define NV_RX_DESCRIPTORVALID (1<<16)
#define NV_RX_MISSEDFRAME (1<<17)
@ -417,14 +427,14 @@ typedef union _ring_type {
/*
* 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.
* The nic supports three different descriptor types:
* - DESC_VER_1: Original
* - DESC_VER_2: support for jumbo frames.
* - DESC_VER_3: 64-bit format.
*/
#define DESC_VER_1 0x0
#define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK)
#define DESC_VER_3 (0x02200|NVREG_TXRXCTL_RXCHECK)
#define DESC_VER_1 1
#define DESC_VER_2 2
#define DESC_VER_3 3
/* PHY defines */
#define PHY_OUI_MARVELL 0x5043
@ -491,6 +501,7 @@ struct fe_priv {
u32 orig_mac[2];
u32 irqmask;
u32 desc_ver;
u32 txrxctl_bits;
void __iomem *base;
@ -534,7 +545,7 @@ static inline struct fe_priv *get_nvpriv(struct net_device *dev)
static inline u8 __iomem *get_hwbase(struct net_device *dev)
{
return get_nvpriv(dev)->base;
return ((struct fe_priv *)netdev_priv(dev))->base;
}
static inline void pci_push(u8 __iomem *base)
@ -623,7 +634,7 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value)
static int phy_reset(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u32 miicontrol;
unsigned int tries = 0;
@ -726,7 +737,7 @@ static int phy_init(struct net_device *dev)
static void nv_start_rx(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
dprintk(KERN_DEBUG "%s: nv_start_rx\n", dev->name);
@ -782,14 +793,14 @@ static void nv_stop_tx(struct net_device *dev)
static void nv_txrx_reset(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name);
writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl);
writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
udelay(NV_TXRX_RESET_DELAY);
writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl);
writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
}
@ -801,7 +812,7 @@ static void nv_txrx_reset(struct net_device *dev)
*/
static struct net_device_stats *nv_get_stats(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
/* It seems that the nic always generates interrupts and doesn't
* accumulate errors internally. Thus the current values in np->stats
@ -817,7 +828,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
*/
static int nv_alloc_rx(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
unsigned int refill_rx = np->refill_rx;
int nr;
@ -861,7 +872,7 @@ static int nv_alloc_rx(struct net_device *dev)
static void nv_do_rx_refill(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
disable_irq(dev->irq);
if (nv_alloc_rx(dev)) {
@ -875,7 +886,7 @@ static void nv_do_rx_refill(unsigned long data)
static void nv_init_rx(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
int i;
np->cur_rx = RX_RING;
@ -889,15 +900,17 @@ static void nv_init_rx(struct net_device *dev)
static void nv_init_tx(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
int i;
np->next_tx = np->nic_tx = 0;
for (i = 0; i < TX_RING; i++)
for (i = 0; i < TX_RING; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
np->tx_ring.orig[i].FlagLen = 0;
else
np->tx_ring.ex[i].FlagLen = 0;
np->tx_skbuff[i] = NULL;
}
}
static int nv_init_ring(struct net_device *dev)
@ -907,21 +920,44 @@ static int nv_init_ring(struct net_device *dev)
return nv_alloc_rx(dev);
}
static void nv_release_txskb(struct net_device *dev, unsigned int skbnr)
{
struct fe_priv *np = netdev_priv(dev);
struct sk_buff *skb = np->tx_skbuff[skbnr];
unsigned int j, entry, fragments;
dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d, skb %p\n",
dev->name, skbnr, np->tx_skbuff[skbnr]);
entry = skbnr;
if ((fragments = skb_shinfo(skb)->nr_frags) != 0) {
for (j = fragments; j >= 1; j--) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[j-1];
pci_unmap_page(np->pci_dev, np->tx_dma[entry],
frag->size,
PCI_DMA_TODEVICE);
entry = (entry - 1) % TX_RING;
}
}
pci_unmap_single(np->pci_dev, np->tx_dma[entry],
skb->len - skb->data_len,
PCI_DMA_TODEVICE);
dev_kfree_skb_irq(skb);
np->tx_skbuff[skbnr] = NULL;
}
static void nv_drain_tx(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
int i;
struct fe_priv *np = netdev_priv(dev);
unsigned int i;
for (i = 0; i < TX_RING; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
np->tx_ring.orig[i].FlagLen = 0;
else
np->tx_ring.ex[i].FlagLen = 0;
if (np->tx_skbuff[i]) {
pci_unmap_single(np->pci_dev, np->tx_dma[i],
np->tx_skbuff[i]->len,
PCI_DMA_TODEVICE);
dev_kfree_skb(np->tx_skbuff[i]);
np->tx_skbuff[i] = NULL;
nv_release_txskb(dev, i);
np->stats.tx_dropped++;
}
}
@ -929,7 +965,7 @@ static void nv_drain_tx(struct net_device *dev)
static void nv_drain_rx(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
int i;
for (i = 0; i < RX_RING; i++) {
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
@ -959,28 +995,69 @@ static void drain_ring(struct net_device *dev)
*/
static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
int nr = np->next_tx % TX_RING;
np->tx_skbuff[nr] = skb;
np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len,
PCI_DMA_TODEVICE);
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
else {
np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
}
struct fe_priv *np = netdev_priv(dev);
u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET);
unsigned int fragments = skb_shinfo(skb)->nr_frags;
unsigned int nr = (np->next_tx + fragments) % TX_RING;
unsigned int i;
spin_lock_irq(&np->lock);
wmb();
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
if ((np->next_tx - np->nic_tx + fragments) > TX_LIMIT_STOP) {
spin_unlock_irq(&np->lock);
netif_stop_queue(dev);
return NETDEV_TX_BUSY;
}
np->tx_skbuff[nr] = skb;
if (fragments) {
dprintk(KERN_DEBUG "%s: nv_start_xmit: buffer contains %d fragments\n", dev->name, fragments);
/* setup descriptors in reverse order */
for (i = fragments; i >= 1; i--) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset, frag->size,
PCI_DMA_TODEVICE);
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
} else {
np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
}
nr = (nr - 1) % TX_RING;
if (np->desc_ver == DESC_VER_1)
tx_flags_extra &= ~NV_TX_LASTPACKET;
else
tx_flags_extra &= ~NV_TX2_LASTPACKET;
}
}
#ifdef NETIF_F_TSO
if (skb_shinfo(skb)->tso_size)
tx_flags_extra |= NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
else
np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n",
dev->name, np->next_tx);
#endif
tx_flags_extra |= (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len-skb->data_len,
PCI_DMA_TODEVICE);
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
} else {
np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
}
dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission. tx_flags_extra: %x\n",
dev->name, np->next_tx, tx_flags_extra);
{
int j;
for (j=0; j<64; j++) {
@ -991,15 +1068,13 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
dprintk("\n");
}
np->next_tx++;
np->next_tx += 1 + fragments;
dev->trans_start = jiffies;
if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP)
netif_stop_queue(dev);
spin_unlock_irq(&np->lock);
writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
pci_push(get_hwbase(dev));
return 0;
return NETDEV_TX_OK;
}
/*
@ -1009,9 +1084,10 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
static void nv_tx_done(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u32 Flags;
int i;
unsigned int i;
struct sk_buff *skb;
while (np->nic_tx != np->next_tx) {
i = np->nic_tx % TX_RING;
@ -1026,35 +1102,38 @@ static void nv_tx_done(struct net_device *dev)
if (Flags & NV_TX_VALID)
break;
if (np->desc_ver == DESC_VER_1) {
if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
NV_TX_UNDERFLOW|NV_TX_ERROR)) {
if (Flags & NV_TX_UNDERFLOW)
np->stats.tx_fifo_errors++;
if (Flags & NV_TX_CARRIERLOST)
np->stats.tx_carrier_errors++;
np->stats.tx_errors++;
} else {
np->stats.tx_packets++;
np->stats.tx_bytes += np->tx_skbuff[i]->len;
if (Flags & NV_TX_LASTPACKET) {
skb = np->tx_skbuff[i];
if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
NV_TX_UNDERFLOW|NV_TX_ERROR)) {
if (Flags & NV_TX_UNDERFLOW)
np->stats.tx_fifo_errors++;
if (Flags & NV_TX_CARRIERLOST)
np->stats.tx_carrier_errors++;
np->stats.tx_errors++;
} else {
np->stats.tx_packets++;
np->stats.tx_bytes += skb->len;
}
nv_release_txskb(dev, i);
}
} else {
if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
if (Flags & NV_TX2_UNDERFLOW)
np->stats.tx_fifo_errors++;
if (Flags & NV_TX2_CARRIERLOST)
np->stats.tx_carrier_errors++;
np->stats.tx_errors++;
} else {
np->stats.tx_packets++;
np->stats.tx_bytes += np->tx_skbuff[i]->len;
if (Flags & NV_TX2_LASTPACKET) {
skb = np->tx_skbuff[i];
if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
if (Flags & NV_TX2_UNDERFLOW)
np->stats.tx_fifo_errors++;
if (Flags & NV_TX2_CARRIERLOST)
np->stats.tx_carrier_errors++;
np->stats.tx_errors++;
} else {
np->stats.tx_packets++;
np->stats.tx_bytes += skb->len;
}
nv_release_txskb(dev, i);
}
}
pci_unmap_single(np->pci_dev, np->tx_dma[i],
np->tx_skbuff[i]->len,
PCI_DMA_TODEVICE);
dev_kfree_skb_irq(np->tx_skbuff[i]);
np->tx_skbuff[i] = NULL;
np->nic_tx++;
}
if (np->next_tx - np->nic_tx < TX_LIMIT_START)
@ -1067,7 +1146,7 @@ static void nv_tx_done(struct net_device *dev)
*/
static void nv_tx_timeout(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name,
@ -1200,7 +1279,7 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen)
static void nv_rx_process(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u32 Flags;
for (;;) {
@ -1355,7 +1434,7 @@ static void set_bufsize(struct net_device *dev)
*/
static int nv_change_mtu(struct net_device *dev, int new_mtu)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
int old_mtu;
if (new_mtu < 64 || new_mtu > np->pkt_limit)
@ -1408,7 +1487,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
pci_push(base);
writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
pci_push(base);
/* restart rx engine */
@ -1440,7 +1519,7 @@ static void nv_copy_mac_to_hw(struct net_device *dev)
*/
static int nv_set_mac_address(struct net_device *dev, void *addr)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
struct sockaddr *macaddr = (struct sockaddr*)addr;
if(!is_valid_ether_addr(macaddr->sa_data))
@ -1475,7 +1554,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
*/
static void nv_set_multicast(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 addr[2];
u32 mask[2];
@ -1535,7 +1614,7 @@ static void nv_set_multicast(struct net_device *dev)
static int nv_update_linkspeed(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
int adv, lpa;
int newls = np->linkspeed;
@ -1705,7 +1784,7 @@ static void nv_link_irq(struct net_device *dev)
static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) data;
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 events;
int i;
@ -1777,7 +1856,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
static void nv_do_nic_poll(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
disable_irq(dev->irq);
@ -1801,7 +1880,7 @@ static void nv_poll_controller(struct net_device *dev)
static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
strcpy(info->driver, "forcedeth");
strcpy(info->version, FORCEDETH_VERSION);
strcpy(info->bus_info, pci_name(np->pci_dev));
@ -1809,7 +1888,7 @@ static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
wolinfo->supported = WAKE_MAGIC;
spin_lock_irq(&np->lock);
@ -1820,7 +1899,7 @@ static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
spin_lock_irq(&np->lock);
@ -2021,7 +2100,7 @@ static int nv_get_regs_len(struct net_device *dev)
static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 *rbuf = buf;
int i;
@ -2035,7 +2114,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void
static int nv_nway_reset(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
int ret;
spin_lock_irq(&np->lock);
@ -2065,11 +2144,12 @@ static struct ethtool_ops ops = {
.get_regs_len = nv_get_regs_len,
.get_regs = nv_get_regs,
.nway_reset = nv_nway_reset,
.get_perm_addr = ethtool_op_get_perm_addr,
};
static int nv_open(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
int ret, oom, i;
@ -2114,9 +2194,9 @@ static int nv_open(struct net_device *dev)
/* 5) continue setup */
writel(np->linkspeed, base + NvRegLinkSpeed);
writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
writel(np->desc_ver, base + NvRegTxRxControl);
writel(np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl);
writel(NVREG_TXRXCTL_BIT1|np->txrxctl_bits, base + NvRegTxRxControl);
reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
@ -2205,7 +2285,7 @@ static int nv_open(struct net_device *dev)
static int nv_close(struct net_device *dev)
{
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base;
spin_lock_irq(&np->lock);
@ -2261,7 +2341,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (!dev)
goto out;
np = get_nvpriv(dev);
np = netdev_priv(dev);
np->pci_dev = pci_dev;
spin_lock_init(&np->lock);
SET_MODULE_OWNER(dev);
@ -2313,19 +2393,32 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (pci_set_dma_mask(pci_dev, 0x0000007fffffffffULL)) {
printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
pci_name(pci_dev));
} else {
dev->features |= NETIF_F_HIGHDMA;
}
np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
} else if (id->driver_data & DEV_HAS_LARGEDESC) {
/* packet format 2: supports jumbo frames */
np->desc_ver = DESC_VER_2;
np->txrxctl_bits = NVREG_TXRXCTL_DESC_2;
} else {
/* original packet format */
np->desc_ver = DESC_VER_1;
np->txrxctl_bits = NVREG_TXRXCTL_DESC_1;
}
np->pkt_limit = NV_PKTLIMIT_1;
if (id->driver_data & DEV_HAS_LARGEDESC)
np->pkt_limit = NV_PKTLIMIT_2;
if (id->driver_data & DEV_HAS_CHECKSUM) {
np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
#ifdef NETIF_F_TSO
dev->features |= NETIF_F_TSO;
#endif
}
err = -ENOMEM;
np->base = ioremap(addr, NV_PCI_REGSZ);
if (!np->base)
@ -2377,8 +2470,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff;
dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff;
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
if (!is_valid_ether_addr(dev->dev_addr)) {
if (!is_valid_ether_addr(dev->perm_addr)) {
/*
* Bad mac address. At least one bios sets the mac address
* to 01:23:45:67:89:ab
@ -2403,9 +2497,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->wolenabled = 0;
if (np->desc_ver == DESC_VER_1) {
np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID;
np->tx_flags = NV_TX_VALID;
} else {
np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID;
np->tx_flags = NV_TX2_VALID;
}
np->irqmask = NVREG_IRQMASK_WANTED;
if (id->driver_data & DEV_NEED_TIMERIRQ)
@ -2494,7 +2588,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
static void __devexit nv_remove(struct pci_dev *pci_dev)
{
struct net_device *dev = pci_get_drvdata(pci_dev);
struct fe_priv *np = get_nvpriv(dev);
struct fe_priv *np = netdev_priv(dev);
unregister_netdev(dev);
@ -2525,35 +2619,35 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* nForce3 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP51 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
@ -2565,11 +2659,11 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
},
{0,},
};

View File

@ -29,12 +29,7 @@
* define the configuration needed by the board are defined in a
* board structure in arch/ppc/platforms (though I do not
* discount the possibility that other architectures could one
* day be supported. One assumption the driver currently makes
* is that the PHY is configured in such a way to advertise all
* capabilities. This is a sensible default, and on certain
* PHYs, changing this default encounters substantial errata
* issues. Future versions may remove this requirement, but for
* now, it is best for the firmware to ensure this is the case.
* day be supported.
*
* The Gianfar Ethernet Controller uses a ring of buffer
* descriptors. The beginning is indicated by a register
@ -47,7 +42,7 @@
* corresponding bit in the IMASK register is also set (if
* interrupt coalescing is active, then the interrupt may not
* happen immediately, but will wait until either a set number
* of frames or amount of time have passed.). In NAPI, the
* of frames or amount of time have passed). In NAPI, the
* interrupt handler will signal there is work to be done, and
* exit. Without NAPI, the packet(s) will be handled
* immediately. Both methods will start at the last known empty
@ -75,6 +70,7 @@
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
@ -97,9 +93,11 @@
#include <linux/version.h>
#include <linux/dma-mapping.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include "gianfar.h"
#include "gianfar_phy.h"
#include "gianfar_mii.h"
#define TX_TIMEOUT (1*HZ)
#define SKB_ALLOC_TIMEOUT 1000000
@ -113,9 +111,8 @@
#endif
const char gfar_driver_name[] = "Gianfar Ethernet";
const char gfar_driver_version[] = "1.1";
const char gfar_driver_version[] = "1.2";
int startup_gfar(struct net_device *dev);
static int gfar_enet_open(struct net_device *dev);
static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void gfar_timeout(struct net_device *dev);
@ -126,17 +123,13 @@ static int gfar_set_mac_address(struct net_device *dev);
static int gfar_change_mtu(struct net_device *dev, int new_mtu);
static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static void gfar_phy_change(void *data);
static void gfar_phy_timer(unsigned long data);
static void adjust_link(struct net_device *dev);
static void init_registers(struct net_device *dev);
static int init_phy(struct net_device *dev);
static int gfar_probe(struct device *device);
static int gfar_remove(struct device *device);
void free_skb_resources(struct gfar_private *priv);
static void free_skb_resources(struct gfar_private *priv);
static void gfar_set_multi(struct net_device *dev);
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
#ifdef CONFIG_GFAR_NAPI
@ -144,7 +137,6 @@ static int gfar_poll(struct net_device *dev, int *budget);
#endif
int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
static void gfar_phy_startup_timer(unsigned long data);
static void gfar_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
@ -162,6 +154,9 @@ int gfar_uses_fcb(struct gfar_private *priv)
else
return 0;
}
/* Set up the ethernet device structure, private data,
* and anything else we need before we start */
static int gfar_probe(struct device *device)
{
u32 tempval;
@ -175,7 +170,7 @@ static int gfar_probe(struct device *device)
einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
if (einfo == NULL) {
if (NULL == einfo) {
printk(KERN_ERR "gfar %d: Missing additional data!\n",
pdev->id);
@ -185,7 +180,7 @@ static int gfar_probe(struct device *device)
/* Create an ethernet device instance */
dev = alloc_etherdev(sizeof (*priv));
if (dev == NULL)
if (NULL == dev)
return -ENOMEM;
priv = netdev_priv(dev);
@ -207,20 +202,11 @@ static int gfar_probe(struct device *device)
priv->regs = (struct gfar *)
ioremap(r->start, sizeof (struct gfar));
if (priv->regs == NULL) {
if (NULL == priv->regs) {
err = -ENOMEM;
goto regs_fail;
}
/* Set the PHY base address */
priv->phyregs = (struct gfar *)
ioremap(einfo->phy_reg_addr, sizeof (struct gfar));
if (priv->phyregs == NULL) {
err = -ENOMEM;
goto phy_regs_fail;
}
spin_lock_init(&priv->lock);
dev_set_drvdata(device, dev);
@ -386,12 +372,10 @@ static int gfar_probe(struct device *device)
return 0;
register_fail:
iounmap((void *) priv->phyregs);
phy_regs_fail:
iounmap((void *) priv->regs);
regs_fail:
free_netdev(dev);
return -ENOMEM;
return err;
}
static int gfar_remove(struct device *device)
@ -402,108 +386,41 @@ static int gfar_remove(struct device *device)
dev_set_drvdata(device, NULL);
iounmap((void *) priv->regs);
iounmap((void *) priv->phyregs);
free_netdev(dev);
return 0;
}
/* Configure the PHY for dev.
* returns 0 if success. -1 if failure
/* Initializes driver's PHY state, and attaches to the PHY.
* Returns 0 on success.
*/
static int init_phy(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
struct phy_info *curphy;
unsigned int timeout = PHY_INIT_TIMEOUT;
struct gfar *phyregs = priv->phyregs;
struct gfar_mii_info *mii_info;
int err;
uint gigabit_support =
priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
SUPPORTED_1000baseT_Full : 0;
struct phy_device *phydev;
priv->oldlink = 0;
priv->oldspeed = 0;
priv->oldduplex = -1;
mii_info = kmalloc(sizeof(struct gfar_mii_info),
GFP_KERNEL);
phydev = phy_connect(dev, priv->einfo->bus_id, &adjust_link, 0);
if(NULL == mii_info) {
if (netif_msg_ifup(priv))
printk(KERN_ERR "%s: Could not allocate mii_info\n",
dev->name);
return -ENOMEM;
if (IS_ERR(phydev)) {
printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
return PTR_ERR(phydev);
}
mii_info->speed = SPEED_1000;
mii_info->duplex = DUPLEX_FULL;
mii_info->pause = 0;
mii_info->link = 1;
/* Remove any features not supported by the controller */
phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
phydev->advertising = phydev->supported;
mii_info->advertising = (ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half |
ADVERTISED_100baseT_Full |
ADVERTISED_1000baseT_Full);
mii_info->autoneg = 1;
spin_lock_init(&mii_info->mdio_lock);
mii_info->mii_id = priv->einfo->phyid;
mii_info->dev = dev;
mii_info->mdio_read = &read_phy_reg;
mii_info->mdio_write = &write_phy_reg;
priv->mii_info = mii_info;
/* Reset the management interface */
gfar_write(&phyregs->miimcfg, MIIMCFG_RESET);
/* Setup the MII Mgmt clock speed */
gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE);
/* Wait until the bus is free */
while ((gfar_read(&phyregs->miimind) & MIIMIND_BUSY) &&
timeout--)
cpu_relax();
if(timeout <= 0) {
printk(KERN_ERR "%s: The MII Bus is stuck!\n",
dev->name);
err = -1;
goto bus_fail;
}
/* get info for this PHY */
curphy = get_phy_info(priv->mii_info);
if (curphy == NULL) {
if (netif_msg_ifup(priv))
printk(KERN_ERR "%s: No PHY found\n", dev->name);
err = -1;
goto no_phy;
}
mii_info->phyinfo = curphy;
/* Run the commands which initialize the PHY */
if(curphy->init) {
err = curphy->init(priv->mii_info);
if (err)
goto phy_init_fail;
}
priv->phydev = phydev;
return 0;
phy_init_fail:
no_phy:
bus_fail:
kfree(mii_info);
return err;
}
static void init_registers(struct net_device *dev)
@ -603,24 +520,13 @@ void stop_gfar(struct net_device *dev)
struct gfar *regs = priv->regs;
unsigned long flags;
phy_stop(priv->phydev);
/* Lock it down */
spin_lock_irqsave(&priv->lock, flags);
/* Tell the kernel the link is down */
priv->mii_info->link = 0;
adjust_link(dev);
gfar_halt(dev);
if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
/* Clear any pending interrupts */
mii_clear_phy_interrupt(priv->mii_info);
/* Disable PHY Interrupts */
mii_configure_phy_interrupt(priv->mii_info,
MII_INTERRUPT_DISABLED);
}
spin_unlock_irqrestore(&priv->lock, flags);
/* Free the IRQs */
@ -629,13 +535,7 @@ void stop_gfar(struct net_device *dev)
free_irq(priv->interruptTransmit, dev);
free_irq(priv->interruptReceive, dev);
} else {
free_irq(priv->interruptTransmit, dev);
}
if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
free_irq(priv->einfo->interruptPHY, dev);
} else {
del_timer_sync(&priv->phy_info_timer);
free_irq(priv->interruptTransmit, dev);
}
free_skb_resources(priv);
@ -649,7 +549,7 @@ void stop_gfar(struct net_device *dev)
/* If there are any tx skbs or rx skbs still around, free them.
* Then free tx_skbuff and rx_skbuff */
void free_skb_resources(struct gfar_private *priv)
static void free_skb_resources(struct gfar_private *priv)
{
struct rxbd8 *rxbdp;
struct txbd8 *txbdp;
@ -770,7 +670,7 @@ int startup_gfar(struct net_device *dev)
(struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
priv->tx_ring_size, GFP_KERNEL);
if (priv->tx_skbuff == NULL) {
if (NULL == priv->tx_skbuff) {
if (netif_msg_ifup(priv))
printk(KERN_ERR "%s: Could not allocate tx_skbuff\n",
dev->name);
@ -785,7 +685,7 @@ int startup_gfar(struct net_device *dev)
(struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
priv->rx_ring_size, GFP_KERNEL);
if (priv->rx_skbuff == NULL) {
if (NULL == priv->rx_skbuff) {
if (netif_msg_ifup(priv))
printk(KERN_ERR "%s: Could not allocate rx_skbuff\n",
dev->name);
@ -879,13 +779,7 @@ int startup_gfar(struct net_device *dev)
}
}
/* Set up the PHY change work queue */
INIT_WORK(&priv->tq, gfar_phy_change, dev);
init_timer(&priv->phy_info_timer);
priv->phy_info_timer.function = &gfar_phy_startup_timer;
priv->phy_info_timer.data = (unsigned long) priv->mii_info;
mod_timer(&priv->phy_info_timer, jiffies + HZ);
phy_start(priv->phydev);
/* Configure the coalescing support */
if (priv->txcoalescing)
@ -933,11 +827,6 @@ int startup_gfar(struct net_device *dev)
priv->tx_bd_base,
gfar_read(&regs->tbase0));
if (priv->mii_info->phyinfo->close)
priv->mii_info->phyinfo->close(priv->mii_info);
kfree(priv->mii_info);
return err;
}
@ -1035,7 +924,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp->status &= TXBD_WRAP;
/* Set up checksumming */
if ((dev->features & NETIF_F_IP_CSUM)
if ((dev->features & NETIF_F_IP_CSUM)
&& (CHECKSUM_HW == skb->ip_summed)) {
fcb = gfar_add_fcb(skb, txbdp);
gfar_tx_checksum(skb, fcb);
@ -1103,11 +992,9 @@ static int gfar_close(struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev);
stop_gfar(dev);
/* Shutdown the PHY */
if (priv->mii_info->phyinfo->close)
priv->mii_info->phyinfo->close(priv->mii_info);
kfree(priv->mii_info);
/* Disconnect from the PHY */
phy_disconnect(priv->phydev);
priv->phydev = NULL;
netif_stop_queue(dev);
@ -1343,7 +1230,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
while ((!skb) && timeout--)
skb = dev_alloc_skb(priv->rx_buffer_size + RXBUF_ALIGNMENT);
if (skb == NULL)
if (NULL == skb)
return NULL;
/* We need the data buffer to be aligned properly. We will reserve
@ -1490,7 +1377,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
struct gfar_private *priv = netdev_priv(dev);
struct rxfcb *fcb = NULL;
if (skb == NULL) {
if (NULL == skb) {
if (netif_msg_rx_err(priv))
printk(KERN_WARNING "%s: Missing skb!!.\n", dev->name);
priv->stats.rx_dropped++;
@ -1718,131 +1605,9 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_id;
struct gfar_private *priv = netdev_priv(dev);
/* Clear the interrupt */
mii_clear_phy_interrupt(priv->mii_info);
/* Disable PHY interrupts */
mii_configure_phy_interrupt(priv->mii_info,
MII_INTERRUPT_DISABLED);
/* Schedule the phy change */
schedule_work(&priv->tq);
return IRQ_HANDLED;
}
/* Scheduled by the phy_interrupt/timer to handle PHY changes */
static void gfar_phy_change(void *data)
{
struct net_device *dev = (struct net_device *) data;
struct gfar_private *priv = netdev_priv(dev);
int result = 0;
/* Delay to give the PHY a chance to change the
* register state */
msleep(1);
/* Update the link, speed, duplex */
result = priv->mii_info->phyinfo->read_status(priv->mii_info);
/* Adjust the known status as long as the link
* isn't still coming up */
if((0 == result) || (priv->mii_info->link == 0))
adjust_link(dev);
/* Reenable interrupts, if needed */
if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR)
mii_configure_phy_interrupt(priv->mii_info,
MII_INTERRUPT_ENABLED);
}
/* Called every so often on systems that don't interrupt
* the core for PHY changes */
static void gfar_phy_timer(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
struct gfar_private *priv = netdev_priv(dev);
schedule_work(&priv->tq);
mod_timer(&priv->phy_info_timer, jiffies +
GFAR_PHY_CHANGE_TIME * HZ);
}
/* Keep trying aneg for some time
* If, after GFAR_AN_TIMEOUT seconds, it has not
* finished, we switch to forced.
* Either way, once the process has completed, we either
* request the interrupt, or switch the timer over to
* using gfar_phy_timer to check status */
static void gfar_phy_startup_timer(unsigned long data)
{
int result;
static int secondary = GFAR_AN_TIMEOUT;
struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
struct gfar_private *priv = netdev_priv(mii_info->dev);
/* Configure the Auto-negotiation */
result = mii_info->phyinfo->config_aneg(mii_info);
/* If autonegotiation failed to start, and
* we haven't timed out, reset the timer, and return */
if (result && secondary--) {
mod_timer(&priv->phy_info_timer, jiffies + HZ);
return;
} else if (result) {
/* Couldn't start autonegotiation.
* Try switching to forced */
mii_info->autoneg = 0;
result = mii_info->phyinfo->config_aneg(mii_info);
/* Forcing failed! Give up */
if(result) {
if (netif_msg_link(priv))
printk(KERN_ERR "%s: Forcing failed!\n",
mii_info->dev->name);
return;
}
}
/* Kill the timer so it can be restarted */
del_timer_sync(&priv->phy_info_timer);
/* Grab the PHY interrupt, if necessary/possible */
if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
if (request_irq(priv->einfo->interruptPHY,
phy_interrupt,
SA_SHIRQ,
"phy_interrupt",
mii_info->dev) < 0) {
if (netif_msg_intr(priv))
printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n",
mii_info->dev->name,
priv->einfo->interruptPHY);
} else {
mii_configure_phy_interrupt(priv->mii_info,
MII_INTERRUPT_ENABLED);
return;
}
}
/* Start the timer again, this time in order to
* handle a change in status */
init_timer(&priv->phy_info_timer);
priv->phy_info_timer.function = &gfar_phy_timer;
priv->phy_info_timer.data = (unsigned long) mii_info->dev;
mod_timer(&priv->phy_info_timer, jiffies +
GFAR_PHY_CHANGE_TIME * HZ);
}
/* Called every time the controller might need to be made
* aware of new link state. The PHY code conveys this
* information through variables in the priv structure, and this
* information through variables in the phydev structure, and this
* function converts those variables into the appropriate
* register values, and can bring down the device if needed.
*/
@ -1850,84 +1615,68 @@ static void adjust_link(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
struct gfar *regs = priv->regs;
u32 tempval;
struct gfar_mii_info *mii_info = priv->mii_info;
unsigned long flags;
struct phy_device *phydev = priv->phydev;
int new_state = 0;
spin_lock_irqsave(&priv->lock, flags);
if (phydev->link) {
u32 tempval = gfar_read(&regs->maccfg2);
if (mii_info->link) {
/* Now we make sure that we can be in full duplex mode.
* If not, we operate in half-duplex mode. */
if (mii_info->duplex != priv->oldduplex) {
if (!(mii_info->duplex)) {
tempval = gfar_read(&regs->maccfg2);
if (phydev->duplex != priv->oldduplex) {
new_state = 1;
if (!(phydev->duplex))
tempval &= ~(MACCFG2_FULL_DUPLEX);
gfar_write(&regs->maccfg2, tempval);
if (netif_msg_link(priv))
printk(KERN_INFO "%s: Half Duplex\n",
dev->name);
} else {
tempval = gfar_read(&regs->maccfg2);
else
tempval |= MACCFG2_FULL_DUPLEX;
gfar_write(&regs->maccfg2, tempval);
if (netif_msg_link(priv))
printk(KERN_INFO "%s: Full Duplex\n",
dev->name);
}
priv->oldduplex = mii_info->duplex;
priv->oldduplex = phydev->duplex;
}
if (mii_info->speed != priv->oldspeed) {
switch (mii_info->speed) {
if (phydev->speed != priv->oldspeed) {
new_state = 1;
switch (phydev->speed) {
case 1000:
tempval = gfar_read(&regs->maccfg2);
tempval =
((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
gfar_write(&regs->maccfg2, tempval);
break;
case 100:
case 10:
tempval = gfar_read(&regs->maccfg2);
tempval =
((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
gfar_write(&regs->maccfg2, tempval);
break;
default:
if (netif_msg_link(priv))
printk(KERN_WARNING
"%s: Ack! Speed (%d) is not 10/100/1000!\n",
dev->name, mii_info->speed);
"%s: Ack! Speed (%d) is not 10/100/1000!\n",
dev->name, phydev->speed);
break;
}
if (netif_msg_link(priv))
printk(KERN_INFO "%s: Speed %dBT\n", dev->name,
mii_info->speed);
priv->oldspeed = mii_info->speed;
priv->oldspeed = phydev->speed;
}
gfar_write(&regs->maccfg2, tempval);
if (!priv->oldlink) {
if (netif_msg_link(priv))
printk(KERN_INFO "%s: Link is up\n", dev->name);
new_state = 1;
priv->oldlink = 1;
netif_carrier_on(dev);
netif_schedule(dev);
}
} else {
if (priv->oldlink) {
if (netif_msg_link(priv))
printk(KERN_INFO "%s: Link is down\n",
dev->name);
priv->oldlink = 0;
priv->oldspeed = 0;
priv->oldduplex = -1;
netif_carrier_off(dev);
}
} else if (priv->oldlink) {
new_state = 1;
priv->oldlink = 0;
priv->oldspeed = 0;
priv->oldduplex = -1;
}
}
if (new_state && netif_msg_link(priv))
phy_print_status(phydev);
spin_unlock_irqrestore(&priv->lock, flags);
}
/* Update the hash table based on the current list of multicast
* addresses we subscribe to. Also, change the promiscuity of
@ -2122,12 +1871,23 @@ static struct device_driver gfar_driver = {
static int __init gfar_init(void)
{
return driver_register(&gfar_driver);
int err = gfar_mdio_init();
if (err)
return err;
err = driver_register(&gfar_driver);
if (err)
gfar_mdio_exit();
return err;
}
static void __exit gfar_exit(void)
{
driver_unregister(&gfar_driver);
gfar_mdio_exit();
}
module_init(gfar_init);

View File

@ -17,7 +17,6 @@
*
* Still left to do:
* -Add support for module parameters
* -Add support for ethtool -s
* -Add patch for ethtool phys id
*/
#ifndef __GIANFAR_H
@ -37,7 +36,8 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/fsl_devices.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <asm/io.h>
#include <asm/irq.h>
@ -48,7 +48,8 @@
#include <linux/workqueue.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include "gianfar_phy.h"
#include <linux/fsl_devices.h>
#include "gianfar_mii.h"
/* The maximum number of packets to be handled in one call of gfar_poll */
#define GFAR_DEV_WEIGHT 64
@ -73,7 +74,7 @@
#define PHY_INIT_TIMEOUT 100000
#define GFAR_PHY_CHANGE_TIME 2
#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.1, "
#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.2, "
#define DRV_NAME "gfar-enet"
extern const char gfar_driver_name[];
extern const char gfar_driver_version[];
@ -578,12 +579,7 @@ struct gfar {
u32 hafdup; /* 0x.50c - Half Duplex Register */
u32 maxfrm; /* 0x.510 - Maximum Frame Length Register */
u8 res18[12];
u32 miimcfg; /* 0x.520 - MII Management Configuration Register */
u32 miimcom; /* 0x.524 - MII Management Command Register */
u32 miimadd; /* 0x.528 - MII Management Address Register */
u32 miimcon; /* 0x.52c - MII Management Control Register */
u32 miimstat; /* 0x.530 - MII Management Status Register */
u32 miimind; /* 0x.534 - MII Management Indicator Register */
u8 gfar_mii_regs[24]; /* See gianfar_phy.h */
u8 res19[4];
u32 ifstat; /* 0x.53c - Interface Status Register */
u32 macstnaddr1; /* 0x.540 - Station Address Part 1 Register */
@ -688,9 +684,6 @@ struct gfar_private {
struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */
u32 *hash_regs[16];
int hash_width;
struct gfar *phyregs;
struct work_struct tq;
struct timer_list phy_info_timer;
struct net_device_stats stats; /* linux network statistics */
struct gfar_extra_stats extra_stats;
spinlock_t lock;
@ -710,7 +703,8 @@ struct gfar_private {
unsigned int interruptError;
struct gianfar_platform_data *einfo;
struct gfar_mii_info *mii_info;
struct phy_device *phydev;
struct mii_bus *mii_bus;
int oldspeed;
int oldduplex;
int oldlink;
@ -732,4 +726,12 @@ extern inline void gfar_write(volatile unsigned *addr, u32 val)
extern struct ethtool_ops *gfar_op_array[];
extern irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
extern int startup_gfar(struct net_device *dev);
extern void stop_gfar(struct net_device *dev);
extern void gfar_halt(struct net_device *dev);
extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
int enable, u32 regnum, u32 read);
void gfar_setup_stashing(struct net_device *dev);
#endif /* __GIANFAR_H */

View File

@ -39,17 +39,18 @@
#include <asm/types.h>
#include <asm/uaccess.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include "gianfar.h"
#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
extern int startup_gfar(struct net_device *dev);
extern void stop_gfar(struct net_device *dev);
extern void gfar_halt(struct net_device *dev);
extern void gfar_start(struct net_device *dev);
extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
#define GFAR_MAX_COAL_USECS 0xffff
#define GFAR_MAX_COAL_FRAMES 0xff
static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
u64 * buf);
static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
@ -182,38 +183,32 @@ static void gfar_gdrvinfo(struct net_device *dev, struct
drvinfo->eedump_len = 0;
}
static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct gfar_private *priv = netdev_priv(dev);
struct phy_device *phydev = priv->phydev;
if (NULL == phydev)
return -ENODEV;
return phy_ethtool_sset(phydev, cmd);
}
/* Return the current settings in the ethtool_cmd structure */
static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct gfar_private *priv = netdev_priv(dev);
uint gigabit_support =
priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
SUPPORTED_1000baseT_Full : 0;
uint gigabit_advert =
priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
ADVERTISED_1000baseT_Full: 0;
struct phy_device *phydev = priv->phydev;
cmd->supported = (SUPPORTED_10baseT_Half
| SUPPORTED_100baseT_Half
| SUPPORTED_100baseT_Full
| gigabit_support | SUPPORTED_Autoneg);
/* For now, we always advertise everything */
cmd->advertising = (ADVERTISED_10baseT_Half
| ADVERTISED_100baseT_Half
| ADVERTISED_100baseT_Full
| gigabit_advert | ADVERTISED_Autoneg);
cmd->speed = priv->mii_info->speed;
cmd->duplex = priv->mii_info->duplex;
cmd->port = PORT_MII;
cmd->phy_address = priv->mii_info->mii_id;
cmd->transceiver = XCVR_EXTERNAL;
cmd->autoneg = AUTONEG_ENABLE;
if (NULL == phydev)
return -ENODEV;
cmd->maxtxpkt = priv->txcount;
cmd->maxrxpkt = priv->rxcount;
return 0;
return phy_ethtool_gset(phydev, cmd);
}
/* Return the length of the register structure */
@ -241,14 +236,14 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use
unsigned int count;
/* The timer is different, depending on the interface speed */
switch (priv->mii_info->speed) {
case 1000:
switch (priv->phydev->speed) {
case SPEED_1000:
count = GFAR_GBIT_TIME;
break;
case 100:
case SPEED_100:
count = GFAR_100_TIME;
break;
case 10:
case SPEED_10:
default:
count = GFAR_10_TIME;
break;
@ -265,14 +260,14 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic
unsigned int count;
/* The timer is different, depending on the interface speed */
switch (priv->mii_info->speed) {
case 1000:
switch (priv->phydev->speed) {
case SPEED_1000:
count = GFAR_GBIT_TIME;
break;
case 100:
case SPEED_100:
count = GFAR_100_TIME;
break;
case 10:
case SPEED_10:
default:
count = GFAR_10_TIME;
break;
@ -292,6 +287,9 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
return -EOPNOTSUPP;
if (NULL == priv->phydev)
return -ENODEV;
cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
cvals->rx_max_coalesced_frames = priv->rxcount;
@ -348,6 +346,22 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
else
priv->rxcoalescing = 1;
if (NULL == priv->phydev)
return -ENODEV;
/* Check the bounds of the values */
if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
pr_info("Coalescing is limited to %d microseconds\n",
GFAR_MAX_COAL_USECS);
return -EINVAL;
}
if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
pr_info("Coalescing is limited to %d frames\n",
GFAR_MAX_COAL_FRAMES);
return -EINVAL;
}
priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
priv->rxcount = cvals->rx_max_coalesced_frames;
@ -358,6 +372,19 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
else
priv->txcoalescing = 1;
/* Check the bounds of the values */
if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
pr_info("Coalescing is limited to %d microseconds\n",
GFAR_MAX_COAL_USECS);
return -EINVAL;
}
if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
pr_info("Coalescing is limited to %d frames\n",
GFAR_MAX_COAL_FRAMES);
return -EINVAL;
}
priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
priv->txcount = cvals->tx_max_coalesced_frames;
@ -536,6 +563,7 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
struct ethtool_ops gfar_ethtool_ops = {
.get_settings = gfar_gsettings,
.set_settings = gfar_ssettings,
.get_drvinfo = gfar_gdrvinfo,
.get_regs_len = gfar_reglen,
.get_regs = gfar_get_regs,

219
drivers/net/gianfar_mii.c Normal file
View File

@ -0,0 +1,219 @@
/*
* drivers/net/gianfar_mii.c
*
* Gianfar Ethernet Driver -- MIIM bus implementation
* Provides Bus interface for MIIM regs
*
* Author: Andy Fleming
* Maintainer: Kumar Gala (kumar.gala@freescale.com)
*
* Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/version.h>
#include <asm/ocp.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include "gianfar.h"
#include "gianfar_mii.h"
/* Write value to the PHY at mii_id at register regnum,
* on the bus, waiting until the write is done before returning.
* All PHY configuration is done through the TSEC1 MIIM regs */
int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
{
struct gfar_mii *regs = bus->priv;
/* Set the PHY address and the register address we want to write */
gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
/* Write out the value we want */
gfar_write(&regs->miimcon, value);
/* Wait for the transaction to finish */
while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
cpu_relax();
return 0;
}
/* Read the bus for PHY at addr mii_id, register regnum, and
* return the value. Clears miimcom first. All PHY
* configuration has to be done through the TSEC1 MIIM regs */
int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
struct gfar_mii *regs = bus->priv;
u16 value;
/* Set the PHY address and the register address we want to read */
gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
/* Clear miimcom, and then initiate a read */
gfar_write(&regs->miimcom, 0);
gfar_write(&regs->miimcom, MII_READ_COMMAND);
/* Wait for the transaction to finish */
while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
cpu_relax();
/* Grab the value of the register from miimstat */
value = gfar_read(&regs->miimstat);
return value;
}
/* Reset the MIIM registers, and wait for the bus to free */
int gfar_mdio_reset(struct mii_bus *bus)
{
struct gfar_mii *regs = bus->priv;
unsigned int timeout = PHY_INIT_TIMEOUT;
spin_lock_bh(&bus->mdio_lock);
/* Reset the management interface */
gfar_write(&regs->miimcfg, MIIMCFG_RESET);
/* Setup the MII Mgmt clock speed */
gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);
/* Wait until the bus is free */
while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
timeout--)
cpu_relax();
spin_unlock_bh(&bus->mdio_lock);
if(timeout <= 0) {
printk(KERN_ERR "%s: The MII Bus is stuck!\n",
bus->name);
return -EBUSY;
}
return 0;
}
int gfar_mdio_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct gianfar_mdio_data *pdata;
struct gfar_mii *regs;
struct mii_bus *new_bus;
int err = 0;
if (NULL == dev)
return -EINVAL;
new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
if (NULL == new_bus)
return -ENOMEM;
new_bus->name = "Gianfar MII Bus",
new_bus->read = &gfar_mdio_read,
new_bus->write = &gfar_mdio_write,
new_bus->reset = &gfar_mdio_reset,
new_bus->id = pdev->id;
pdata = (struct gianfar_mdio_data *)pdev->dev.platform_data;
if (NULL == pdata) {
printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
return -ENODEV;
}
/* Set the PHY base address */
regs = (struct gfar_mii *) ioremap(pdata->paddr,
sizeof (struct gfar_mii));
if (NULL == regs) {
err = -ENOMEM;
goto reg_map_fail;
}
new_bus->priv = regs;
new_bus->irq = pdata->irq;
new_bus->dev = dev;
dev_set_drvdata(dev, new_bus);
err = mdiobus_register(new_bus);
if (0 != err) {
printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
new_bus->name);
goto bus_register_fail;
}
return 0;
bus_register_fail:
iounmap((void *) regs);
reg_map_fail:
kfree(new_bus);
return err;
}
int gfar_mdio_remove(struct device *dev)
{
struct mii_bus *bus = dev_get_drvdata(dev);
mdiobus_unregister(bus);
dev_set_drvdata(dev, NULL);
iounmap((void *) (&bus->priv));
bus->priv = NULL;
kfree(bus);
return 0;
}
static struct device_driver gianfar_mdio_driver = {
.name = "fsl-gianfar_mdio",
.bus = &platform_bus_type,
.probe = gfar_mdio_probe,
.remove = gfar_mdio_remove,
};
int __init gfar_mdio_init(void)
{
return driver_register(&gianfar_mdio_driver);
}
void __exit gfar_mdio_exit(void)
{
driver_unregister(&gianfar_mdio_driver);
}

45
drivers/net/gianfar_mii.h Normal file
View File

@ -0,0 +1,45 @@
/*
* drivers/net/gianfar_mii.h
*
* Gianfar Ethernet Driver -- MII Management Bus Implementation
* Driver for the MDIO bus controller in the Gianfar register space
*
* Author: Andy Fleming
* Maintainer: Kumar Gala (kumar.gala@freescale.com)
*
* Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#ifndef __GIANFAR_MII_H
#define __GIANFAR_MII_H
#define MIIMIND_BUSY 0x00000001
#define MIIMIND_NOTVALID 0x00000004
#define MII_READ_COMMAND 0x00000001
#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
| SUPPORTED_100baseT_Half \
| SUPPORTED_100baseT_Full \
| SUPPORTED_Autoneg \
| SUPPORTED_MII)
struct gfar_mii {
u32 miimcfg; /* 0x.520 - MII Management Config Register */
u32 miimcom; /* 0x.524 - MII Management Command Register */
u32 miimadd; /* 0x.528 - MII Management Address Register */
u32 miimcon; /* 0x.52c - MII Management Control Register */
u32 miimstat; /* 0x.530 - MII Management Status Register */
u32 miimind; /* 0x.534 - MII Management Indicator Register */
};
int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
int __init gfar_mdio_init(void);
void __exit gfar_mdio_exit(void);
#endif /* GIANFAR_PHY_H */

View File

@ -1,661 +0,0 @@
/*
* drivers/net/gianfar_phy.c
*
* Gianfar Ethernet Driver -- PHY handling
* Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
* Based on 8260_io/fcc_enet.c
*
* Author: Andy Fleming
* Maintainer: Kumar Gala (kumar.gala@freescale.com)
*
* Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include "gianfar.h"
#include "gianfar_phy.h"
static void config_genmii_advert(struct gfar_mii_info *mii_info);
static void genmii_setup_forced(struct gfar_mii_info *mii_info);
static void genmii_restart_aneg(struct gfar_mii_info *mii_info);
static int gbit_config_aneg(struct gfar_mii_info *mii_info);
static int genmii_config_aneg(struct gfar_mii_info *mii_info);
static int genmii_update_link(struct gfar_mii_info *mii_info);
static int genmii_read_status(struct gfar_mii_info *mii_info);
u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum);
void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val);
/* Write value to the PHY for this device to the register at regnum, */
/* waiting until the write is done before it returns. All PHY */
/* configuration has to be done through the TSEC1 MIIM regs */
void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
{
struct gfar_private *priv = netdev_priv(dev);
struct gfar *regbase = priv->phyregs;
/* Set the PHY address and the register address we want to write */
gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
/* Write out the value we want */
gfar_write(&regbase->miimcon, value);
/* Wait for the transaction to finish */
while (gfar_read(&regbase->miimind) & MIIMIND_BUSY)
cpu_relax();
}
/* Reads from register regnum in the PHY for device dev, */
/* returning the value. Clears miimcom first. All PHY */
/* configuration has to be done through the TSEC1 MIIM regs */
int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
{
struct gfar_private *priv = netdev_priv(dev);
struct gfar *regbase = priv->phyregs;
u16 value;
/* Set the PHY address and the register address we want to read */
gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
/* Clear miimcom, and then initiate a read */
gfar_write(&regbase->miimcom, 0);
gfar_write(&regbase->miimcom, MII_READ_COMMAND);
/* Wait for the transaction to finish */
while (gfar_read(&regbase->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
cpu_relax();
/* Grab the value of the register from miimstat */
value = gfar_read(&regbase->miimstat);
return value;
}
void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info)
{
if(mii_info->phyinfo->ack_interrupt)
mii_info->phyinfo->ack_interrupt(mii_info);
}
void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts)
{
mii_info->interrupts = interrupts;
if(mii_info->phyinfo->config_intr)
mii_info->phyinfo->config_intr(mii_info);
}
/* Writes MII_ADVERTISE with the appropriate values, after
* sanitizing advertise to make sure only supported features
* are advertised
*/
static void config_genmii_advert(struct gfar_mii_info *mii_info)
{
u32 advertise;
u16 adv;
/* Only allow advertising what this PHY supports */
mii_info->advertising &= mii_info->phyinfo->features;
advertise = mii_info->advertising;
/* Setup standard advertisement */
adv = phy_read(mii_info, MII_ADVERTISE);
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
if (advertise & ADVERTISED_10baseT_Half)
adv |= ADVERTISE_10HALF;
if (advertise & ADVERTISED_10baseT_Full)
adv |= ADVERTISE_10FULL;
if (advertise & ADVERTISED_100baseT_Half)
adv |= ADVERTISE_100HALF;
if (advertise & ADVERTISED_100baseT_Full)
adv |= ADVERTISE_100FULL;
phy_write(mii_info, MII_ADVERTISE, adv);
}
static void genmii_setup_forced(struct gfar_mii_info *mii_info)
{
u16 ctrl;
u32 features = mii_info->phyinfo->features;
ctrl = phy_read(mii_info, MII_BMCR);
ctrl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPEED1000|BMCR_ANENABLE);
ctrl |= BMCR_RESET;
switch(mii_info->speed) {
case SPEED_1000:
if(features & (SUPPORTED_1000baseT_Half
| SUPPORTED_1000baseT_Full)) {
ctrl |= BMCR_SPEED1000;
break;
}
mii_info->speed = SPEED_100;
case SPEED_100:
if (features & (SUPPORTED_100baseT_Half
| SUPPORTED_100baseT_Full)) {
ctrl |= BMCR_SPEED100;
break;
}
mii_info->speed = SPEED_10;
case SPEED_10:
if (features & (SUPPORTED_10baseT_Half
| SUPPORTED_10baseT_Full))
break;
default: /* Unsupported speed! */
printk(KERN_ERR "%s: Bad speed!\n",
mii_info->dev->name);
break;
}
phy_write(mii_info, MII_BMCR, ctrl);
}
/* Enable and Restart Autonegotiation */
static void genmii_restart_aneg(struct gfar_mii_info *mii_info)
{
u16 ctl;
ctl = phy_read(mii_info, MII_BMCR);
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
phy_write(mii_info, MII_BMCR, ctl);
}
static int gbit_config_aneg(struct gfar_mii_info *mii_info)
{
u16 adv;
u32 advertise;
if(mii_info->autoneg) {
/* Configure the ADVERTISE register */
config_genmii_advert(mii_info);
advertise = mii_info->advertising;
adv = phy_read(mii_info, MII_1000BASETCONTROL);
adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
MII_1000BASETCONTROL_HALFDUPLEXCAP);
if (advertise & SUPPORTED_1000baseT_Half)
adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
if (advertise & SUPPORTED_1000baseT_Full)
adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
phy_write(mii_info, MII_1000BASETCONTROL, adv);
/* Start/Restart aneg */
genmii_restart_aneg(mii_info);
} else
genmii_setup_forced(mii_info);
return 0;
}
static int marvell_config_aneg(struct gfar_mii_info *mii_info)
{
/* The Marvell PHY has an errata which requires
* that certain registers get written in order
* to restart autonegotiation */
phy_write(mii_info, MII_BMCR, BMCR_RESET);
phy_write(mii_info, 0x1d, 0x1f);
phy_write(mii_info, 0x1e, 0x200c);
phy_write(mii_info, 0x1d, 0x5);
phy_write(mii_info, 0x1e, 0);
phy_write(mii_info, 0x1e, 0x100);
gbit_config_aneg(mii_info);
return 0;
}
static int genmii_config_aneg(struct gfar_mii_info *mii_info)
{
if (mii_info->autoneg) {
config_genmii_advert(mii_info);
genmii_restart_aneg(mii_info);
} else
genmii_setup_forced(mii_info);
return 0;
}
static int genmii_update_link(struct gfar_mii_info *mii_info)
{
u16 status;
/* Do a fake read */
phy_read(mii_info, MII_BMSR);
/* Read link and autonegotiation status */
status = phy_read(mii_info, MII_BMSR);
if ((status & BMSR_LSTATUS) == 0)
mii_info->link = 0;
else
mii_info->link = 1;
/* If we are autonegotiating, and not done,
* return an error */
if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE))
return -EAGAIN;
return 0;
}
static int genmii_read_status(struct gfar_mii_info *mii_info)
{
u16 status;
int err;
/* Update the link, but return if there
* was an error */
err = genmii_update_link(mii_info);
if (err)
return err;
if (mii_info->autoneg) {
status = phy_read(mii_info, MII_LPA);
if (status & (LPA_10FULL | LPA_100FULL))
mii_info->duplex = DUPLEX_FULL;
else
mii_info->duplex = DUPLEX_HALF;
if (status & (LPA_100FULL | LPA_100HALF))
mii_info->speed = SPEED_100;
else
mii_info->speed = SPEED_10;
mii_info->pause = 0;
}
/* On non-aneg, we assume what we put in BMCR is the speed,
* though magic-aneg shouldn't prevent this case from occurring
*/
return 0;
}
static int marvell_read_status(struct gfar_mii_info *mii_info)
{
u16 status;
int err;
/* Update the link, but return if there
* was an error */
err = genmii_update_link(mii_info);
if (err)
return err;
/* If the link is up, read the speed and duplex */
/* If we aren't autonegotiating, assume speeds
* are as set */
if (mii_info->autoneg && mii_info->link) {
int speed;
status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
#if 0
/* If speed and duplex aren't resolved,
* return an error. Isn't this handled
* by checking aneg?
*/
if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0)
return -EAGAIN;
#endif
/* Get the duplexity */
if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
mii_info->duplex = DUPLEX_FULL;
else
mii_info->duplex = DUPLEX_HALF;
/* Get the speed */
speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK;
switch(speed) {
case MII_M1011_PHY_SPEC_STATUS_1000:
mii_info->speed = SPEED_1000;
break;
case MII_M1011_PHY_SPEC_STATUS_100:
mii_info->speed = SPEED_100;
break;
default:
mii_info->speed = SPEED_10;
break;
}
mii_info->pause = 0;
}
return 0;
}
static int cis820x_read_status(struct gfar_mii_info *mii_info)
{
u16 status;
int err;
/* Update the link, but return if there
* was an error */
err = genmii_update_link(mii_info);
if (err)
return err;
/* If the link is up, read the speed and duplex */
/* If we aren't autonegotiating, assume speeds
* are as set */
if (mii_info->autoneg && mii_info->link) {
int speed;
status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT);
if (status & MII_CIS8201_AUXCONSTAT_DUPLEX)
mii_info->duplex = DUPLEX_FULL;
else
mii_info->duplex = DUPLEX_HALF;
speed = status & MII_CIS8201_AUXCONSTAT_SPEED;
switch (speed) {
case MII_CIS8201_AUXCONSTAT_GBIT:
mii_info->speed = SPEED_1000;
break;
case MII_CIS8201_AUXCONSTAT_100:
mii_info->speed = SPEED_100;
break;
default:
mii_info->speed = SPEED_10;
break;
}
}
return 0;
}
static int marvell_ack_interrupt(struct gfar_mii_info *mii_info)
{
/* Clear the interrupts by reading the reg */
phy_read(mii_info, MII_M1011_IEVENT);
return 0;
}
static int marvell_config_intr(struct gfar_mii_info *mii_info)
{
if(mii_info->interrupts == MII_INTERRUPT_ENABLED)
phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
else
phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
return 0;
}
static int cis820x_init(struct gfar_mii_info *mii_info)
{
phy_write(mii_info, MII_CIS8201_AUX_CONSTAT,
MII_CIS8201_AUXCONSTAT_INIT);
phy_write(mii_info, MII_CIS8201_EXT_CON1,
MII_CIS8201_EXTCON1_INIT);
return 0;
}
static int cis820x_ack_interrupt(struct gfar_mii_info *mii_info)
{
phy_read(mii_info, MII_CIS8201_ISTAT);
return 0;
}
static int cis820x_config_intr(struct gfar_mii_info *mii_info)
{
if(mii_info->interrupts == MII_INTERRUPT_ENABLED)
phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK);
else
phy_write(mii_info, MII_CIS8201_IMASK, 0);
return 0;
}
#define DM9161_DELAY 10
static int dm9161_read_status(struct gfar_mii_info *mii_info)
{
u16 status;
int err;
/* Update the link, but return if there
* was an error */
err = genmii_update_link(mii_info);
if (err)
return err;
/* If the link is up, read the speed and duplex */
/* If we aren't autonegotiating, assume speeds
* are as set */
if (mii_info->autoneg && mii_info->link) {
status = phy_read(mii_info, MII_DM9161_SCSR);
if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H))
mii_info->speed = SPEED_100;
else
mii_info->speed = SPEED_10;
if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F))
mii_info->duplex = DUPLEX_FULL;
else
mii_info->duplex = DUPLEX_HALF;
}
return 0;
}
static int dm9161_config_aneg(struct gfar_mii_info *mii_info)
{
struct dm9161_private *priv = mii_info->priv;
if(0 == priv->resetdone)
return -EAGAIN;
return 0;
}
static void dm9161_timer(unsigned long data)
{
struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
struct dm9161_private *priv = mii_info->priv;
u16 status = phy_read(mii_info, MII_BMSR);
if (status & BMSR_ANEGCOMPLETE) {
priv->resetdone = 1;
} else
mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
}
static int dm9161_init(struct gfar_mii_info *mii_info)
{
struct dm9161_private *priv;
/* Allocate the private data structure */
priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL);
if (NULL == priv)
return -ENOMEM;
mii_info->priv = priv;
/* Reset is not done yet */
priv->resetdone = 0;
/* Isolate the PHY */
phy_write(mii_info, MII_BMCR, BMCR_ISOLATE);
/* Do not bypass the scrambler/descrambler */
phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
/* Clear 10BTCSR to default */
phy_write(mii_info, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT);
/* Reconnect the PHY, and enable Autonegotiation */
phy_write(mii_info, MII_BMCR, BMCR_ANENABLE);
/* Start a timer for DM9161_DELAY seconds to wait
* for the PHY to be ready */
init_timer(&priv->timer);
priv->timer.function = &dm9161_timer;
priv->timer.data = (unsigned long) mii_info;
mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
return 0;
}
static void dm9161_close(struct gfar_mii_info *mii_info)
{
struct dm9161_private *priv = mii_info->priv;
del_timer_sync(&priv->timer);
kfree(priv);
}
#if 0
static int dm9161_ack_interrupt(struct gfar_mii_info *mii_info)
{
phy_read(mii_info, MII_DM9161_INTR);
return 0;
}
#endif
/* Cicada 820x */
static struct phy_info phy_info_cis820x = {
0x000fc440,
"Cicada Cis8204",
0x000fffc0,
.features = MII_GBIT_FEATURES,
.init = &cis820x_init,
.config_aneg = &gbit_config_aneg,
.read_status = &cis820x_read_status,
.ack_interrupt = &cis820x_ack_interrupt,
.config_intr = &cis820x_config_intr,
};
static struct phy_info phy_info_dm9161 = {
.phy_id = 0x0181b880,
.name = "Davicom DM9161E",
.phy_id_mask = 0x0ffffff0,
.init = dm9161_init,
.config_aneg = dm9161_config_aneg,
.read_status = dm9161_read_status,
.close = dm9161_close,
};
static struct phy_info phy_info_marvell = {
.phy_id = 0x01410c00,
.phy_id_mask = 0xffffff00,
.name = "Marvell 88E1101/88E1111",
.features = MII_GBIT_FEATURES,
.config_aneg = &marvell_config_aneg,
.read_status = &marvell_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
};
static struct phy_info phy_info_genmii= {
.phy_id = 0x00000000,
.phy_id_mask = 0x00000000,
.name = "Generic MII",
.features = MII_BASIC_FEATURES,
.config_aneg = genmii_config_aneg,
.read_status = genmii_read_status,
};
static struct phy_info *phy_info[] = {
&phy_info_cis820x,
&phy_info_marvell,
&phy_info_dm9161,
&phy_info_genmii,
NULL
};
u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum)
{
u16 retval;
unsigned long flags;
spin_lock_irqsave(&mii_info->mdio_lock, flags);
retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum);
spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
return retval;
}
void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val)
{
unsigned long flags;
spin_lock_irqsave(&mii_info->mdio_lock, flags);
mii_info->mdio_write(mii_info->dev,
mii_info->mii_id,
regnum, val);
spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
}
/* Use the PHY ID registers to determine what type of PHY is attached
* to device dev. return a struct phy_info structure describing that PHY
*/
struct phy_info * get_phy_info(struct gfar_mii_info *mii_info)
{
u16 phy_reg;
u32 phy_ID;
int i;
struct phy_info *theInfo = NULL;
struct net_device *dev = mii_info->dev;
/* Grab the bits from PHYIR1, and put them in the upper half */
phy_reg = phy_read(mii_info, MII_PHYSID1);
phy_ID = (phy_reg & 0xffff) << 16;
/* Grab the bits from PHYIR2, and put them in the lower half */
phy_reg = phy_read(mii_info, MII_PHYSID2);
phy_ID |= (phy_reg & 0xffff);
/* loop through all the known PHY types, and find one that */
/* matches the ID we read from the PHY. */
for (i = 0; phy_info[i]; i++)
if (phy_info[i]->phy_id ==
(phy_ID & phy_info[i]->phy_id_mask)) {
theInfo = phy_info[i];
break;
}
/* This shouldn't happen, as we have generic PHY support */
if (theInfo == NULL) {
printk("%s: PHY id %x is not supported!\n", dev->name, phy_ID);
return NULL;
} else {
printk("%s: PHY is %s (%x)\n", dev->name, theInfo->name,
phy_ID);
}
return theInfo;
}

View File

@ -1,213 +0,0 @@
/*
* drivers/net/gianfar_phy.h
*
* Gianfar Ethernet Driver -- PHY handling
* Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
* Based on 8260_io/fcc_enet.c
*
* Author: Andy Fleming
* Maintainer: Kumar Gala (kumar.gala@freescale.com)
*
* Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#ifndef __GIANFAR_PHY_H
#define __GIANFAR_PHY_H
#define MII_end ((u32)-2)
#define MII_read ((u32)-1)
#define MIIMIND_BUSY 0x00000001
#define MIIMIND_NOTVALID 0x00000004
#define GFAR_AN_TIMEOUT 2000
/* 1000BT control (Marvell & BCM54xx at least) */
#define MII_1000BASETCONTROL 0x09
#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200
#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100
/* Cicada Extended Control Register 1 */
#define MII_CIS8201_EXT_CON1 0x17
#define MII_CIS8201_EXTCON1_INIT 0x0000
/* Cicada Interrupt Mask Register */
#define MII_CIS8201_IMASK 0x19
#define MII_CIS8201_IMASK_IEN 0x8000
#define MII_CIS8201_IMASK_SPEED 0x4000
#define MII_CIS8201_IMASK_LINK 0x2000
#define MII_CIS8201_IMASK_DUPLEX 0x1000
#define MII_CIS8201_IMASK_MASK 0xf000
/* Cicada Interrupt Status Register */
#define MII_CIS8201_ISTAT 0x1a
#define MII_CIS8201_ISTAT_STATUS 0x8000
#define MII_CIS8201_ISTAT_SPEED 0x4000
#define MII_CIS8201_ISTAT_LINK 0x2000
#define MII_CIS8201_ISTAT_DUPLEX 0x1000
/* Cicada Auxiliary Control/Status Register */
#define MII_CIS8201_AUX_CONSTAT 0x1c
#define MII_CIS8201_AUXCONSTAT_INIT 0x0004
#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020
#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018
#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010
#define MII_CIS8201_AUXCONSTAT_100 0x0008
/* 88E1011 PHY Status Register */
#define MII_M1011_PHY_SPEC_STATUS 0x11
#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000
#define MII_M1011_PHY_SPEC_STATUS_100 0x4000
#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000
#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000
#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800
#define MII_M1011_PHY_SPEC_STATUS_LINK 0x0400
#define MII_M1011_IEVENT 0x13
#define MII_M1011_IEVENT_CLEAR 0x0000
#define MII_M1011_IMASK 0x12
#define MII_M1011_IMASK_INIT 0x6400
#define MII_M1011_IMASK_CLEAR 0x0000
#define MII_DM9161_SCR 0x10
#define MII_DM9161_SCR_INIT 0x0610
/* DM9161 Specified Configuration and Status Register */
#define MII_DM9161_SCSR 0x11
#define MII_DM9161_SCSR_100F 0x8000
#define MII_DM9161_SCSR_100H 0x4000
#define MII_DM9161_SCSR_10F 0x2000
#define MII_DM9161_SCSR_10H 0x1000
/* DM9161 Interrupt Register */
#define MII_DM9161_INTR 0x15
#define MII_DM9161_INTR_PEND 0x8000
#define MII_DM9161_INTR_DPLX_MASK 0x0800
#define MII_DM9161_INTR_SPD_MASK 0x0400
#define MII_DM9161_INTR_LINK_MASK 0x0200
#define MII_DM9161_INTR_MASK 0x0100
#define MII_DM9161_INTR_DPLX_CHANGE 0x0010
#define MII_DM9161_INTR_SPD_CHANGE 0x0008
#define MII_DM9161_INTR_LINK_CHANGE 0x0004
#define MII_DM9161_INTR_INIT 0x0000
#define MII_DM9161_INTR_STOP \
(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
| MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
/* DM9161 10BT Configuration/Status */
#define MII_DM9161_10BTCSR 0x12
#define MII_DM9161_10BTCSR_INIT 0x7800
#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | \
SUPPORTED_10baseT_Full | \
SUPPORTED_100baseT_Half | \
SUPPORTED_100baseT_Full | \
SUPPORTED_Autoneg | \
SUPPORTED_TP | \
SUPPORTED_MII)
#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \
SUPPORTED_1000baseT_Half | \
SUPPORTED_1000baseT_Full)
#define MII_READ_COMMAND 0x00000001
#define MII_INTERRUPT_DISABLED 0x0
#define MII_INTERRUPT_ENABLED 0x1
/* Taken from mii_if_info and sungem_phy.h */
struct gfar_mii_info {
/* Information about the PHY type */
/* And management functions */
struct phy_info *phyinfo;
/* forced speed & duplex (no autoneg)
* partner speed & duplex & pause (autoneg)
*/
int speed;
int duplex;
int pause;
/* The most recently read link state */
int link;
/* Enabled Interrupts */
u32 interrupts;
u32 advertising;
int autoneg;
int mii_id;
/* private data pointer */
/* For use by PHYs to maintain extra state */
void *priv;
/* Provided by host chip */
struct net_device *dev;
/* A lock to ensure that only one thing can read/write
* the MDIO bus at a time */
spinlock_t mdio_lock;
/* Provided by ethernet driver */
int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
};
/* struct phy_info: a structure which defines attributes for a PHY
*
* id will contain a number which represents the PHY. During
* startup, the driver will poll the PHY to find out what its
* UID--as defined by registers 2 and 3--is. The 32-bit result
* gotten from the PHY will be ANDed with phy_id_mask to
* discard any bits which may change based on revision numbers
* unimportant to functionality
*
* There are 6 commands which take a gfar_mii_info structure.
* Each PHY must declare config_aneg, and read_status.
*/
struct phy_info {
u32 phy_id;
char *name;
unsigned int phy_id_mask;
u32 features;
/* Called to initialize the PHY */
int (*init)(struct gfar_mii_info *mii_info);
/* Called to suspend the PHY for power */
int (*suspend)(struct gfar_mii_info *mii_info);
/* Reconfigures autonegotiation (or disables it) */
int (*config_aneg)(struct gfar_mii_info *mii_info);
/* Determines the negotiated speed and duplex */
int (*read_status)(struct gfar_mii_info *mii_info);
/* Clears any pending interrupts */
int (*ack_interrupt)(struct gfar_mii_info *mii_info);
/* Enables or disables interrupts */
int (*config_intr)(struct gfar_mii_info *mii_info);
/* Clears up any memory if needed */
void (*close)(struct gfar_mii_info *mii_info);
};
struct phy_info *get_phy_info(struct gfar_mii_info *mii_info);
int read_phy_reg(struct net_device *dev, int mii_id, int regnum);
void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value);
void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info);
void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts);
struct dm9161_private {
struct timer_list timer;
int resetdone;
};
#endif /* GIANFAR_PHY_H */

View File

@ -1,6 +1,7 @@
config MKISS
tristate "Serial port KISS driver"
depends on AX25
select CRC16
---help---
KISS is a protocol used for the exchange of data between a computer
and a Terminal Node Controller (a small embedded system commonly

View File

@ -144,7 +144,7 @@ static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev)
{
struct bpqdev *bpq;
list_for_each_entry(bpq, &bpq_devices, bpq_list) {
list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list) {
if (bpq->ethdev == dev)
return bpq->axdev;
}
@ -399,7 +399,7 @@ static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
if (*pos == 0)
return SEQ_START_TOKEN;
list_for_each_entry(bpqdev, &bpq_devices, bpq_list) {
list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
if (i == *pos)
return bpqdev;
}
@ -418,7 +418,7 @@ static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
p = ((struct bpqdev *)v)->bpq_list.next;
return (p == &bpq_devices) ? NULL
: list_entry(p, struct bpqdev, bpq_list);
: rcu_dereference(list_entry(p, struct bpqdev, bpq_list));
}
static void bpq_seq_stop(struct seq_file *seq, void *v)
@ -561,8 +561,6 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
if (!dev_is_ethdev(dev))
return NOTIFY_DONE;
rcu_read_lock();
switch (event) {
case NETDEV_UP: /* new ethernet device -> new BPQ interface */
if (bpq_get_ax25_dev(dev) == NULL)
@ -581,7 +579,6 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
default:
break;
}
rcu_read_unlock();
return NOTIFY_DONE;
}

View File

@ -14,13 +14,14 @@
*
* Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
* Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
* Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas@x-berg.in-berlin.de>
*/
#include <linux/config.h>
#include <linux/module.h>
#include <asm/system.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
#include <linux/crc16.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
@ -39,11 +40,6 @@
#include <net/ax25.h>
#ifdef CONFIG_INET
#include <linux/ip.h>
#include <linux/tcp.h>
#endif
#define AX_MTU 236
/* SLIP/KISS protocol characters. */
@ -80,9 +76,13 @@ struct mkiss {
int mode;
int crcmode; /* MW: for FlexNet, SMACK etc. */
#define CRC_MODE_NONE 0
#define CRC_MODE_FLEX 1
#define CRC_MODE_SMACK 2
int crcauto; /* CRC auto mode */
#define CRC_MODE_NONE 0
#define CRC_MODE_FLEX 1
#define CRC_MODE_SMACK 2
#define CRC_MODE_FLEX_TEST 3
#define CRC_MODE_SMACK_TEST 4
atomic_t refcnt;
struct semaphore dead_sem;
@ -151,6 +151,21 @@ static int check_crc_flex(unsigned char *cp, int size)
return 0;
}
static int check_crc_16(unsigned char *cp, int size)
{
unsigned short crc = 0x0000;
if (size < 3)
return -1;
crc = crc16(0, cp, size);
if (crc != 0x0000)
return -1;
return 0;
}
/*
* Standard encapsulation
*/
@ -237,19 +252,42 @@ static void ax_bump(struct mkiss *ax)
spin_lock_bh(&ax->buflock);
if (ax->rbuff[0] > 0x0f) {
if (ax->rbuff[0] & 0x20) {
ax->crcmode = CRC_MODE_FLEX;
if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
ax->stats.rx_errors++;
if (ax->rbuff[0] & 0x80) {
if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
ax->stats.rx_errors++;
spin_unlock_bh(&ax->buflock);
return;
}
if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
printk(KERN_INFO
"mkiss: %s: Switchting to crc-smack\n",
ax->dev->name);
ax->crcmode = CRC_MODE_SMACK;
}
ax->rcount -= 2;
/* dl9sau bugfix: the trailling two bytes flexnet crc
* will not be passed to the kernel. thus we have
* to correct the kissparm signature, because it
* indicates a crc but there's none
*ax->rbuff &= ~0x80;
} else if (ax->rbuff[0] & 0x20) {
if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
ax->stats.rx_errors++;
spin_unlock_bh(&ax->buflock);
return;
}
if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
printk(KERN_INFO
"mkiss: %s: Switchting to crc-flexnet\n",
ax->dev->name);
ax->crcmode = CRC_MODE_FLEX;
}
ax->rcount -= 2;
/*
* dl9sau bugfix: the trailling two bytes flexnet crc
* will not be passed to the kernel. thus we have to
* correct the kissparm signature, because it indicates
* a crc but there's none
*/
*ax->rbuff &= ~0x20;
*ax->rbuff &= ~0x20;
}
}
spin_unlock_bh(&ax->buflock);
@ -417,20 +455,69 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
p = icp;
spin_lock_bh(&ax->buflock);
switch (ax->crcmode) {
unsigned short crc;
if ((*p & 0x0f) != 0) {
/* Configuration Command (kissparms(1).
* Protocol spec says: never append CRC.
* This fixes a very old bug in the linux
* kiss driver. -- dl9sau */
switch (*p & 0xff) {
case 0x85:
/* command from userspace especially for us,
* not for delivery to the tnc */
if (len > 1) {
int cmd = (p[1] & 0xff);
switch(cmd) {
case 3:
ax->crcmode = CRC_MODE_SMACK;
break;
case 2:
ax->crcmode = CRC_MODE_FLEX;
break;
case 1:
ax->crcmode = CRC_MODE_NONE;
break;
case 0:
default:
ax->crcmode = CRC_MODE_SMACK_TEST;
cmd = 0;
}
ax->crcauto = (cmd ? 0 : 1);
printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd);
}
spin_unlock_bh(&ax->buflock);
netif_start_queue(dev);
case CRC_MODE_FLEX:
*p |= 0x20;
crc = calc_crc_flex(p, len);
count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
break;
return;
default:
count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
}
} else {
unsigned short crc;
switch (ax->crcmode) {
case CRC_MODE_SMACK_TEST:
ax->crcmode = CRC_MODE_FLEX_TEST;
printk(KERN_INFO "mkiss: %s: Trying crc-smack\n", ax->dev->name);
// fall through
case CRC_MODE_SMACK:
*p |= 0x80;
crc = swab16(crc16(0, p, len));
count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
break;
case CRC_MODE_FLEX_TEST:
ax->crcmode = CRC_MODE_NONE;
printk(KERN_INFO "mkiss: %s: Trying crc-flexnet\n", ax->dev->name);
// fall through
case CRC_MODE_FLEX:
*p |= 0x20;
crc = calc_crc_flex(p, len);
count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
break;
default:
count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
}
}
default:
count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
break;
}
set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
ax->stats.tx_packets++;
@ -439,8 +526,6 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
ax->dev->trans_start = jiffies;
ax->xleft = count - actual;
ax->xhead = ax->xbuff + actual;
spin_unlock_bh(&ax->buflock);
}
/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
@ -622,7 +707,7 @@ static void ax_setup(struct net_device *dev)
* best way to fix this is to use a rwlock in the tty struct, but for now we
* use a single global rwlock for all ttys in ppp line discipline.
*/
static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
static DEFINE_RWLOCK(disc_data_lock);
static struct mkiss *mkiss_get(struct tty_struct *tty)
{
@ -643,6 +728,8 @@ static void mkiss_put(struct mkiss *ax)
up(&ax->dead_sem);
}
static int crc_force = 0; /* Can be overridden with insmod */
static int mkiss_open(struct tty_struct *tty)
{
struct net_device *dev;
@ -682,6 +769,33 @@ static int mkiss_open(struct tty_struct *tty)
if (register_netdev(dev))
goto out_free_buffers;
/* after register_netdev() - because else printk smashes the kernel */
switch (crc_force) {
case 3:
ax->crcmode = CRC_MODE_SMACK;
printk(KERN_INFO "mkiss: %s: crc mode smack forced.\n",
ax->dev->name);
break;
case 2:
ax->crcmode = CRC_MODE_FLEX;
printk(KERN_INFO "mkiss: %s: crc mode flexnet forced.\n",
ax->dev->name);
break;
case 1:
ax->crcmode = CRC_MODE_NONE;
printk(KERN_INFO "mkiss: %s: crc mode disabled.\n",
ax->dev->name);
break;
case 0:
/* fall through */
default:
crc_force = 0;
printk(KERN_INFO "mkiss: %s: crc mode is auto.\n",
ax->dev->name);
ax->crcmode = CRC_MODE_SMACK_TEST;
}
ax->crcauto = (crc_force ? 0 : 1);
netif_start_queue(dev);
/* Done. We have linked the TTY line to a channel. */
@ -765,7 +879,6 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
case SIOCSIFHWADDR: {
char addr[AX25_ADDR_LEN];
printk(KERN_INFO "In SIOCSIFHWADDR");
if (copy_from_user(&addr,
(void __user *) arg, AX25_ADDR_LEN)) {
@ -864,6 +977,7 @@ static void mkiss_write_wakeup(struct tty_struct *tty)
}
static struct tty_ldisc ax_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "mkiss",
.open = mkiss_open,
@ -904,6 +1018,8 @@ static void __exit mkiss_exit_driver(void)
MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>");
MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
MODULE_PARM(crc_force, "i");
MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]");
MODULE_LICENSE("GPL");
MODULE_ALIAS_LDISC(N_AX25);

View File

@ -1,62 +0,0 @@
/****************************************************************************
* Defines for the Multi-KISS driver.
****************************************************************************/
#define AX25_MAXDEV 16 /* MAX number of AX25 channels;
This can be overridden with
insmod -oax25_maxdev=nnn */
#define AX_MTU 236
/* SLIP/KISS protocol characters. */
#define END 0300 /* indicates end of frame */
#define ESC 0333 /* indicates byte stuffing */
#define ESC_END 0334 /* ESC ESC_END means END 'data' */
#define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
struct ax_disp {
int magic;
/* Various fields. */
struct tty_struct *tty; /* ptr to TTY structure */
struct net_device *dev; /* easy for intr handling */
/* These are pointers to the malloc()ed frame buffers. */
unsigned char *rbuff; /* receiver buffer */
int rcount; /* received chars counter */
unsigned char *xbuff; /* transmitter buffer */
unsigned char *xhead; /* pointer to next byte to XMIT */
int xleft; /* bytes left in XMIT queue */
/* SLIP interface statistics. */
unsigned long rx_packets; /* inbound frames counter */
unsigned long tx_packets; /* outbound frames counter */
unsigned long rx_bytes; /* inbound bytes counter */
unsigned long tx_bytes; /* outbound bytes counter */
unsigned long rx_errors; /* Parity, etc. errors */
unsigned long tx_errors; /* Planned stuff */
unsigned long rx_dropped; /* No memory for skb */
unsigned long tx_dropped; /* When MTU change */
unsigned long rx_over_errors; /* Frame bigger then SLIP buf. */
/* Detailed SLIP statistics. */
int mtu; /* Our mtu (to spot changes!) */
int buffsize; /* Max buffers sizes */
unsigned long flags; /* Flag values/ mode etc */
/* long req'd: used by set_bit --RR */
#define AXF_INUSE 0 /* Channel in use */
#define AXF_ESCAPE 1 /* ESC received */
#define AXF_ERROR 2 /* Parity, etc. error */
#define AXF_KEEPTEST 3 /* Keepalive test flag */
#define AXF_OUTWAIT 4 /* is outpacket was flag */
int mode;
int crcmode; /* MW: for FlexNet, SMACK etc. */
#define CRC_MODE_NONE 0
#define CRC_MODE_FLEX 1
#define CRC_MODE_SMACK 2
spinlock_t buflock; /* lock for rbuf and xbuf */
};
#define AX25_MAGIC 0x5316

View File

@ -2517,10 +2517,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
break;
if (!in_interrupt()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
if (!in_interrupt())
schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
if (time_after_eq(jiffies, time)) /* no signal->no logout */
@ -2536,10 +2534,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
break;
if (!in_interrupt()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
if (!in_interrupt())
schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
#ifdef HP100_DEBUG
@ -2577,10 +2573,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if (!(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST))
break;
if (!in_interrupt()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
if (!in_interrupt())
schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
hp100_orb(HP100_AUTO_MODE, MAC_CFG_3); /* Autosel back on */
@ -2591,10 +2585,8 @@ static int hp100_down_vg_link(struct net_device *dev)
do {
if ((hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) == 0)
break;
if (!in_interrupt()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
if (!in_interrupt())
schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
if (time_before_eq(time, jiffies)) {
@ -2606,10 +2598,8 @@ static int hp100_down_vg_link(struct net_device *dev)
time = jiffies + (2 * HZ); /* This seems to take a while.... */
do {
if (!in_interrupt()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
if (!in_interrupt())
schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
return 0;
@ -2659,10 +2649,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
do {
if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
break;
if (!in_interrupt()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
if (!in_interrupt())
schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
/* Start an addressed training and optionally request promiscuous port */
@ -2697,10 +2685,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
do {
if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
break;
if (!in_interrupt()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
if (!in_interrupt())
schedule_timeout_interruptible(1);
} while (time_before(jiffies, time));
if (time_after_eq(jiffies, time)) {
@ -2723,10 +2709,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
#endif
break;
}
if (!in_interrupt()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
if (!in_interrupt())
schedule_timeout_interruptible(1);
} while (time_after(time, jiffies));
}

View File

@ -678,10 +678,9 @@ static void turnaround_delay(const struct stir_cb *stir, long us)
return;
ticks = us / (1000000 / HZ);
if (ticks > 0) {
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(1 + ticks);
} else
if (ticks > 0)
schedule_timeout_interruptible(1 + ticks);
else
udelay(us);
}

View File

@ -645,11 +645,10 @@ ixgb_phys_id(struct net_device *netdev, uint32_t data)
mod_timer(&adapter->blink_timer, jiffies);
set_current_state(TASK_INTERRUPTIBLE);
if(data)
schedule_timeout(data * HZ);
if (data)
schedule_timeout_interruptible(data * HZ);
else
schedule_timeout(MAX_SCHEDULE_TIMEOUT);
schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
del_timer_sync(&adapter->blink_timer);
ixgb_led_off(&adapter->hw);
@ -723,6 +722,7 @@ struct ethtool_ops ixgb_ethtool_ops = {
.phys_id = ixgb_phys_id,
.get_stats_count = ixgb_get_stats_count,
.get_ethtool_stats = ixgb_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr,
};
void ixgb_set_ethtool_ops(struct net_device *netdev)

View File

@ -460,8 +460,9 @@ ixgb_probe(struct pci_dev *pdev,
}
ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
if(!is_valid_ether_addr(netdev->dev_addr)) {
if(!is_valid_ether_addr(netdev->perm_addr)) {
err = -EIO;
goto err_eeprom;
}

View File

@ -298,7 +298,7 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
return 0;
unmap:
if (ei_status.reg0)
iounmap((void *)dev->mem_start);
iounmap(ei_status.mem);
cleanup:
free_irq(dev->irq, dev);
return ret;

View File

@ -207,6 +207,20 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
return 0;
}
int mii_check_gmii_support(struct mii_if_info *mii)
{
int reg;
reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
if (reg & BMSR_ESTATEN) {
reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS);
if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
return 1;
}
return 0;
}
int mii_link_ok (struct mii_if_info *mii)
{
/* first, a dummy read, needed to latch some MII phys */
@ -394,5 +408,6 @@ EXPORT_SYMBOL(mii_ethtool_gset);
EXPORT_SYMBOL(mii_ethtool_sset);
EXPORT_SYMBOL(mii_check_link);
EXPORT_SYMBOL(mii_check_media);
EXPORT_SYMBOL(mii_check_gmii_support);
EXPORT_SYMBOL(generic_mii_ioctl);

371
drivers/net/mipsnet.c Normal file
View File

@ -0,0 +1,371 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#define DEBUG
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/sched.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <asm/io.h>
#include <asm/mips-boards/simint.h>
#include "mipsnet.h" /* actual device IO mapping */
#define MIPSNET_VERSION "2005-06-20"
#define mipsnet_reg_address(dev, field) (dev->base_addr + field_offset(field))
struct mipsnet_priv {
struct net_device_stats stats;
};
static struct platform_device *mips_plat_dev;
static char mipsnet_string[] = "mipsnet";
/*
* Copy data from the MIPSNET rx data port
*/
static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
int len)
{
uint32_t available_len = inl(mipsnet_reg_address(dev, rxDataCount));
if (available_len < len)
return -EFAULT;
for (; len > 0; len--, kdata++) {
*kdata = inb(mipsnet_reg_address(dev, rxDataBuffer));
}
return inl(mipsnet_reg_address(dev, rxDataCount));
}
static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
struct sk_buff *skb)
{
int count_to_go = skb->len;
char *buf_ptr = skb->data;
struct mipsnet_priv *mp = netdev_priv(dev);
pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
dev->name, __FUNCTION__, skb->len);
outl(skb->len, mipsnet_reg_address(dev, txDataCount));
pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
dev->name, __FUNCTION__, skb->len);
for (; count_to_go; buf_ptr++, count_to_go--) {
outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
}
mp->stats.tx_packets++;
mp->stats.tx_bytes += skb->len;
return skb->len;
}
static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
{
pr_debug("%s:%s(): transmitting %d bytes\n",
dev->name, __FUNCTION__, skb->len);
/* Only one packet at a time. Once TXDONE interrupt is serviced, the
* queue will be restarted.
*/
netif_stop_queue(dev);
mipsnet_put_todevice(dev, skb);
return 0;
}
static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
{
struct sk_buff *skb;
size_t len = count;
struct mipsnet_priv *mp = netdev_priv(dev);
if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
mp->stats.rx_dropped++;
return -ENOMEM;
}
skb_reserve(skb, 2);
if (ioiocpy_frommipsnet(dev, skb_put(skb, len), len))
return -EFAULT;
skb->dev = dev;
skb->protocol = eth_type_trans(skb, dev);
skb->ip_summed = CHECKSUM_UNNECESSARY;
pr_debug("%s:%s(): pushing RXed data to kernel\n",
dev->name, __FUNCTION__);
netif_rx(skb);
mp->stats.rx_packets++;
mp->stats.rx_bytes += len;
return count;
}
static irqreturn_t
mipsnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
irqreturn_t retval = IRQ_NONE;
uint64_t interruptFlags;
if (irq == dev->irq) {
pr_debug("%s:%s(): irq %d for device\n",
dev->name, __FUNCTION__, irq);
retval = IRQ_HANDLED;
interruptFlags =
inl(mipsnet_reg_address(dev, interruptControl));
pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
__FUNCTION__, interruptFlags);
if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
pr_debug("%s:%s(): got TXDone\n",
dev->name, __FUNCTION__);
outl(MIPSNET_INTCTL_TXDONE,
mipsnet_reg_address(dev, interruptControl));
// only one packet at a time, we are done.
netif_wake_queue(dev);
} else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
pr_debug("%s:%s(): got RX data\n",
dev->name, __FUNCTION__);
mipsnet_get_fromdev(dev,
inl(mipsnet_reg_address(dev, rxDataCount)));
pr_debug("%s:%s(): clearing RX int\n",
dev->name, __FUNCTION__);
outl(MIPSNET_INTCTL_RXDONE,
mipsnet_reg_address(dev, interruptControl));
} else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
pr_debug("%s:%s(): got test interrupt\n",
dev->name, __FUNCTION__);
// TESTBIT is cleared on read.
// And takes effect after a write with 0
outl(0, mipsnet_reg_address(dev, interruptControl));
} else {
pr_debug("%s:%s(): no valid fags 0x%016llx\n",
dev->name, __FUNCTION__, interruptFlags);
// Maybe shared IRQ, just ignore, no clearing.
retval = IRQ_NONE;
}
} else {
printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
dev->name, __FUNCTION__, irq);
retval = IRQ_NONE;
}
return retval;
} //mipsnet_interrupt()
static int mipsnet_open(struct net_device *dev)
{
int err;
pr_debug("%s: mipsnet_open\n", dev->name);
err = request_irq(dev->irq, &mipsnet_interrupt,
SA_SHIRQ, dev->name, (void *) dev);
if (err) {
pr_debug("%s: %s(): can't get irq %d\n",
dev->name, __FUNCTION__, dev->irq);
release_region(dev->base_addr, MIPSNET_IO_EXTENT);
return err;
}
pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
dev->name, __FUNCTION__, dev->base_addr, dev->irq);
netif_start_queue(dev);
// test interrupt handler
outl(MIPSNET_INTCTL_TESTBIT,
mipsnet_reg_address(dev, interruptControl));
return 0;
}
static int mipsnet_close(struct net_device *dev)
{
pr_debug("%s: %s()\n", dev->name, __FUNCTION__);
netif_stop_queue(dev);
return 0;
}
static struct net_device_stats *mipsnet_get_stats(struct net_device *dev)
{
struct mipsnet_priv *mp = netdev_priv(dev);
return &mp->stats;
}
static void mipsnet_set_mclist(struct net_device *dev)
{
// we don't do anything
return;
}
static int __init mipsnet_probe(struct device *dev)
{
struct net_device *netdev;
int err;
netdev = alloc_etherdev(sizeof(struct mipsnet_priv));
if (!netdev) {
err = -ENOMEM;
goto out;
}
dev_set_drvdata(dev, netdev);
netdev->open = mipsnet_open;
netdev->stop = mipsnet_close;
netdev->hard_start_xmit = mipsnet_xmit;
netdev->get_stats = mipsnet_get_stats;
netdev->set_multicast_list = mipsnet_set_mclist;
/*
* TODO: probe for these or load them from PARAM
*/
netdev->base_addr = 0x4200;
netdev->irq = MIPSCPU_INT_BASE + MIPSCPU_INT_MB0 +
inl(mipsnet_reg_address(netdev, interruptInfo));
// Get the io region now, get irq on open()
if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
"for dev is not availble.\n", netdev->name,
__FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
err = -EBUSY;
goto out_free_netdev;
}
/*
* Lacking any better mechanism to allocate a MAC address we use a
* random one ...
*/
random_ether_addr(netdev->dev_addr);
err = register_netdev(netdev);
if (err) {
printk(KERN_ERR "MIPSNet: failed to register netdev.\n");
goto out_free_region;
}
return 0;
out_free_region:
release_region(netdev->base_addr, MIPSNET_IO_EXTENT);
out_free_netdev:
free_netdev(netdev);
out:
return err;
}
static int __devexit mipsnet_device_remove(struct device *device)
{
struct net_device *dev = dev_get_drvdata(device);
unregister_netdev(dev);
release_region(dev->base_addr, MIPSNET_IO_EXTENT);
free_netdev(dev);
dev_set_drvdata(device, NULL);
return 0;
}
static struct device_driver mipsnet_driver = {
.name = mipsnet_string,
.bus = &platform_bus_type,
.probe = mipsnet_probe,
.remove = __devexit_p(mipsnet_device_remove),
};
static void mipsnet_platform_release(struct device *device)
{
struct platform_device *pldev;
/* free device */
pldev = to_platform_device(device);
kfree(pldev);
}
static int __init mipsnet_init_module(void)
{
struct platform_device *pldev;
int err;
printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
"(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
if (driver_register(&mipsnet_driver)) {
printk(KERN_ERR "Driver registration failed\n");
err = -ENODEV;
goto out;
}
if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
err = -ENOMEM;
goto out_unregister_driver;
}
memset (pldev, 0, sizeof (*pldev));
pldev->name = mipsnet_string;
pldev->id = 0;
pldev->dev.release = mipsnet_platform_release;
if (platform_device_register(pldev)) {
err = -ENODEV;
goto out_free_pldev;
}
if (!pldev->dev.driver) {
/*
* The driver was not bound to this device, there was
* no hardware at this address. Unregister it, as the
* release fuction will take care of freeing the
* allocated structure
*/
platform_device_unregister (pldev);
}
mips_plat_dev = pldev;
return 0;
out_free_pldev:
kfree(pldev);
out_unregister_driver:
driver_unregister(&mipsnet_driver);
out:
return err;
}
static void __exit mipsnet_exit_module(void)
{
pr_debug("MIPSNet Ethernet driver exiting\n");
driver_unregister(&mipsnet_driver);
}
module_init(mipsnet_init_module);
module_exit(mipsnet_exit_module);

127
drivers/net/mipsnet.h Normal file
View File

@ -0,0 +1,127 @@
//
// <COPYRIGHT CLASS="1B" YEAR="2005">
// Unpublished work (c) MIPS Technologies, Inc. All rights reserved.
// Unpublished rights reserved under the copyright laws of the U.S.A. and
// other countries.
//
// PROPRIETARY / SECRET CONFIDENTIAL INFORMATION OF MIPS TECHNOLOGIES, INC.
// FOR INTERNAL USE ONLY.
//
// Under no circumstances (contract or otherwise) may this information be
// disclosed to, or copied, modified or used by anyone other than employees
// or contractors of MIPS Technologies having a need to know.
// </COPYRIGHT>
//
//++
// File: MIPS_Net.h
//
// Description:
// The definition of the emulated MIPSNET device's interface.
//
// Notes: This include file needs to work from a Linux device drivers.
//
//--
//
#ifndef __MIPSNET_H
#define __MIPSNET_H
/*
* Id of this Net device, as seen by the core.
*/
#define MIPS_NET_DEV_ID ((uint64_t) \
((uint64_t)'M'<< 0)| \
((uint64_t)'I'<< 8)| \
((uint64_t)'P'<<16)| \
((uint64_t)'S'<<24)| \
((uint64_t)'N'<<32)| \
((uint64_t)'E'<<40)| \
((uint64_t)'T'<<48)| \
((uint64_t)'0'<<56))
/*
* Net status/control block as seen by sw in the core.
* (Why not use bit fields? can't be bothered with cross-platform struct
* packing.)
*/
typedef struct _net_control_block {
/// dev info for probing
/// reads as MIPSNET%d where %d is some form of version
uint64_t devId; /*0x00 */
/*
* read only busy flag.
* Set and cleared by the Net Device to indicate that an rx or a tx
* is in progress.
*/
uint32_t busy; /*0x08 */
/*
* Set by the Net Device.
* The device will set it once data has been received.
* The value is the number of bytes that should be read from
* rxDataBuffer. The value will decrease till 0 until all the data
* from rxDataBuffer has been read.
*/
uint32_t rxDataCount; /*0x0c */
#define MIPSNET_MAX_RXTX_DATACOUNT (1<<16)
/*
* Settable from the MIPS core, cleared by the Net Device.
* The core should set the number of bytes it wants to send,
* then it should write those bytes of data to txDataBuffer.
* The device will clear txDataCount has been processed (not necessarily sent).
*/
uint32_t txDataCount; /*0x10 */
/*
* Interrupt control
*
* Used to clear the interrupted generated by this dev.
* Write a 1 to clear the interrupt. (except bit31).
*
* Bit0 is set if it was a tx-done interrupt.
* Bit1 is set when new rx-data is available.
* Until this bit is cleared there will be no other RXs.
*
* Bit31 is used for testing, it clears after a read.
* Writing 1 to this bit will cause an interrupt to be generated.
* To clear the test interrupt, write 0 to this register.
*/
uint32_t interruptControl; /*0x14 */
#define MIPSNET_INTCTL_TXDONE ((uint32_t)(1<< 0))
#define MIPSNET_INTCTL_RXDONE ((uint32_t)(1<< 1))
#define MIPSNET_INTCTL_TESTBIT ((uint32_t)(1<<31))
#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE|MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TESTBIT)
/*
* Readonly core-specific interrupt info for the device to signal the core.
* The meaning of the contents of this field might change.
*/
/*###\todo: the whole memIntf interrupt scheme is messy: the device should have
* no control what so ever of what VPE/register set is being used.
* The MemIntf should only expose interrupt lines, and something in the
* config should be responsible for the line<->core/vpe bindings.
*/
uint32_t interruptInfo; /*0x18 */
/*
* This is where the received data is read out.
* There is more data to read until rxDataReady is 0.
* Only 1 byte at this regs offset is used.
*/
uint32_t rxDataBuffer; /*0x1c */
/*
* This is where the data to transmit is written.
* Data should be written for the amount specified in the txDataCount register.
* Only 1 byte at this regs offset is used.
*/
uint32_t txDataBuffer; /*0x20 */
} MIPS_T_NetControl;
#define MIPSNET_IO_EXTENT 0x40 /* being generous */
#define field_offset(field) ((int)&((MIPS_T_NetControl*)(0))->field)
#endif /* __MIPSNET_H */

View File

@ -54,6 +54,10 @@ static const char version2[] =
#include <asm/system.h>
#include <asm/io.h>
#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
#include <asm/tx4938/rbtx4938.h>
#endif
#include "8390.h"
#define DRV_NAME "ne"
@ -111,6 +115,9 @@ bad_clone_list[] __initdata = {
{"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
{"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
{"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
{"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
#endif
{"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
{NULL,}
};
@ -226,6 +233,10 @@ struct net_device * __init ne_probe(int unit)
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
#ifdef CONFIG_TOSHIBA_RBTX4938
dev->base_addr = 0x07f20280;
dev->irq = RBTX4938_RTL_8019_IRQ;
#endif
err = do_ne_probe(dev);
if (err)
goto out;
@ -506,6 +517,10 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
ei_status.name = name;
ei_status.tx_start_page = start_page;
ei_status.stop_page = stop_page;
#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
wordlength = 1;
#endif
#ifdef CONFIG_PLAT_OAKS32R
ei_status.word16 = 0;
#else

View File

@ -372,6 +372,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":");
dev->dev_addr[i] = SA_prom[i];
}
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
return 0;
@ -637,6 +638,7 @@ static struct ethtool_ops ne2k_pci_ethtool_ops = {
.get_drvinfo = ne2k_pci_get_drvinfo,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.get_perm_addr = ethtool_op_get_perm_addr,
};
static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)

View File

@ -1632,8 +1632,7 @@ static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enab
timed_out = 1;
break;
}
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout_uninterruptible(1);
}
if (status & fail)

View File

@ -22,8 +22,8 @@
*************************************************************************/
#define DRV_NAME "pcnet32"
#define DRV_VERSION "1.30j"
#define DRV_RELDATE "29.04.2005"
#define DRV_VERSION "1.31a"
#define DRV_RELDATE "12.Sep.2005"
#define PFX DRV_NAME ": "
static const char *version =
@ -257,6 +257,9 @@ static int homepna[MAX_UNITS];
* v1.30h 24 Jun 2004 Don Fry correctly select auto, speed, duplex in bcr32.
* v1.30i 28 Jun 2004 Don Fry change to use module_param.
* v1.30j 29 Apr 2005 Don Fry fix skb/map leak with loopback test.
* v1.31 02 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> added set_ringparam().
* v1.31a 12 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> set min ring size to 4
* to allow loopback test to work unchanged.
*/
@ -266,17 +269,17 @@ static int homepna[MAX_UNITS];
* That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
*/
#ifndef PCNET32_LOG_TX_BUFFERS
#define PCNET32_LOG_TX_BUFFERS 4
#define PCNET32_LOG_RX_BUFFERS 5
#define PCNET32_LOG_TX_BUFFERS 4
#define PCNET32_LOG_RX_BUFFERS 5
#define PCNET32_LOG_MAX_TX_BUFFERS 9 /* 2^9 == 512 */
#define PCNET32_LOG_MAX_RX_BUFFERS 9
#endif
#define TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS))
#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
#define TX_RING_LEN_BITS ((PCNET32_LOG_TX_BUFFERS) << 12)
#define TX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_TX_BUFFERS))
#define RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS))
#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
#define RX_RING_LEN_BITS ((PCNET32_LOG_RX_BUFFERS) << 4)
#define RX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_RX_BUFFERS))
#define PKT_BUF_SZ 1544
@ -334,14 +337,14 @@ struct pcnet32_access {
};
/*
* The first three fields of pcnet32_private are read by the ethernet device
* so we allocate the structure should be allocated by pci_alloc_consistent().
* The first field of pcnet32_private is read by the ethernet device
* so the structure should be allocated using pci_alloc_consistent().
*/
struct pcnet32_private {
/* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
struct pcnet32_rx_head rx_ring[RX_RING_SIZE];
struct pcnet32_tx_head tx_ring[TX_RING_SIZE];
struct pcnet32_init_block init_block;
/* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
struct pcnet32_rx_head *rx_ring;
struct pcnet32_tx_head *tx_ring;
dma_addr_t dma_addr; /* DMA address of beginning of this
object, returned by
pci_alloc_consistent */
@ -349,13 +352,21 @@ struct pcnet32_private {
structure */
const char *name;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct sk_buff *tx_skbuff[TX_RING_SIZE];
struct sk_buff *rx_skbuff[RX_RING_SIZE];
dma_addr_t tx_dma_addr[TX_RING_SIZE];
dma_addr_t rx_dma_addr[RX_RING_SIZE];
struct sk_buff **tx_skbuff;
struct sk_buff **rx_skbuff;
dma_addr_t *tx_dma_addr;
dma_addr_t *rx_dma_addr;
struct pcnet32_access a;
spinlock_t lock; /* Guard lock */
unsigned int cur_rx, cur_tx; /* The next free ring entry */
unsigned int rx_ring_size; /* current rx ring size */
unsigned int tx_ring_size; /* current tx ring size */
unsigned int rx_mod_mask; /* rx ring modular mask */
unsigned int tx_mod_mask; /* tx ring modular mask */
unsigned short rx_len_bits;
unsigned short tx_len_bits;
dma_addr_t rx_ring_dma_addr;
dma_addr_t tx_ring_dma_addr;
unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
struct net_device_stats stats;
char tx_full;
@ -397,6 +408,9 @@ static int pcnet32_get_regs_len(struct net_device *dev);
static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *ptr);
static void pcnet32_purge_tx_ring(struct net_device *dev);
static int pcnet32_alloc_ring(struct net_device *dev);
static void pcnet32_free_ring(struct net_device *dev);
enum pci_flags_bit {
PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
@ -613,10 +627,62 @@ static void pcnet32_get_ringparam(struct net_device *dev, struct ethtool_ringpar
{
struct pcnet32_private *lp = dev->priv;
ering->tx_max_pending = TX_RING_SIZE - 1;
ering->tx_pending = lp->cur_tx - lp->dirty_tx;
ering->rx_max_pending = RX_RING_SIZE - 1;
ering->rx_pending = lp->cur_rx & RX_RING_MOD_MASK;
ering->tx_max_pending = TX_MAX_RING_SIZE - 1;
ering->tx_pending = lp->tx_ring_size - 1;
ering->rx_max_pending = RX_MAX_RING_SIZE - 1;
ering->rx_pending = lp->rx_ring_size - 1;
}
static int pcnet32_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
{
struct pcnet32_private *lp = dev->priv;
unsigned long flags;
int i;
if (ering->rx_mini_pending || ering->rx_jumbo_pending)
return -EINVAL;
if (netif_running(dev))
pcnet32_close(dev);
spin_lock_irqsave(&lp->lock, flags);
pcnet32_free_ring(dev);
lp->tx_ring_size = min(ering->tx_pending, (unsigned int) TX_MAX_RING_SIZE);
lp->rx_ring_size = min(ering->rx_pending, (unsigned int) RX_MAX_RING_SIZE);
/* set the minimum ring size to 4, to allow the loopback test to work
* unchanged.
*/
for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
if (lp->tx_ring_size <= (1 << i))
break;
}
lp->tx_ring_size = (1 << i);
lp->tx_mod_mask = lp->tx_ring_size - 1;
lp->tx_len_bits = (i << 12);
for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
if (lp->rx_ring_size <= (1 << i))
break;
}
lp->rx_ring_size = (1 << i);
lp->rx_mod_mask = lp->rx_ring_size - 1;
lp->rx_len_bits = (i << 4);
if (pcnet32_alloc_ring(dev)) {
pcnet32_free_ring(dev);
return -ENOMEM;
}
spin_unlock_irqrestore(&lp->lock, flags);
if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_INFO PFX "Ring Param Settings: RX: %d, TX: %d\n", lp->rx_ring_size, lp->tx_ring_size);
if (netif_running(dev))
pcnet32_open(dev);
return 0;
}
static void pcnet32_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@ -948,6 +1014,7 @@ static struct ethtool_ops pcnet32_ethtool_ops = {
.nway_reset = pcnet32_nway_reset,
.get_link = pcnet32_get_link,
.get_ringparam = pcnet32_get_ringparam,
.set_ringparam = pcnet32_set_ringparam,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.get_tso = ethtool_op_get_tso,
@ -957,6 +1024,7 @@ static struct ethtool_ops pcnet32_ethtool_ops = {
.phys_id = pcnet32_phys_id,
.get_regs_len = pcnet32_get_regs_len,
.get_regs = pcnet32_get_regs,
.get_perm_addr = ethtool_op_get_perm_addr,
};
/* only probes for non-PCI devices, the rest are handled by
@ -1185,9 +1253,10 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
memcpy(dev->dev_addr, promaddr, 6);
}
}
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
if (!is_valid_ether_addr(dev->dev_addr))
if (!is_valid_ether_addr(dev->perm_addr))
memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
if (pcnet32_debug & NETIF_MSG_PROBE) {
@ -1239,6 +1308,12 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
dev->priv = lp;
lp->name = chipname;
lp->shared_irq = shared;
lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */
lp->rx_ring_size = RX_RING_SIZE; /* default rx ring size */
lp->tx_mod_mask = lp->tx_ring_size - 1;
lp->rx_mod_mask = lp->rx_ring_size - 1;
lp->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 12);
lp->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4);
lp->mii_if.full_duplex = fdx;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
@ -1265,21 +1340,23 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
}
lp->a = *a;
if (pcnet32_alloc_ring(dev)) {
ret = -ENOMEM;
goto err_free_ring;
}
/* detect special T1/E1 WAN card by checking for MAC address */
if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0
&& dev->dev_addr[2] == 0x75)
lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */
lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
for (i = 0; i < 6; i++)
lp->init_block.phys_addr[i] = dev->dev_addr[i];
lp->init_block.filter[0] = 0x00000000;
lp->init_block.filter[1] = 0x00000000;
lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
offsetof(struct pcnet32_private, rx_ring));
lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
offsetof(struct pcnet32_private, tx_ring));
lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
/* switch pcnet32 to 32bit mode */
a->write_bcr(ioaddr, 20, 2);
@ -1310,7 +1387,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
if (pcnet32_debug & NETIF_MSG_PROBE)
printk(", failed to detect IRQ line.\n");
ret = -ENODEV;
goto err_free_consistent;
goto err_free_ring;
}
if (pcnet32_debug & NETIF_MSG_PROBE)
printk(", probed IRQ %d.\n", dev->irq);
@ -1341,7 +1418,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
/* Fill in the generic fields of the device structure. */
if (register_netdev(dev))
goto err_free_consistent;
goto err_free_ring;
if (pdev) {
pci_set_drvdata(pdev, dev);
@ -1359,6 +1436,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
return 0;
err_free_ring:
pcnet32_free_ring(dev);
err_free_consistent:
pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
err_free_netdev:
@ -1369,6 +1448,86 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
}
static int pcnet32_alloc_ring(struct net_device *dev)
{
struct pcnet32_private *lp = dev->priv;
if ((lp->tx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
&lp->tx_ring_dma_addr)) == NULL) {
if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
return -ENOMEM;
}
if ((lp->rx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
&lp->rx_ring_dma_addr)) == NULL) {
if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
return -ENOMEM;
}
if (!(lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size, GFP_ATOMIC))) {
if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Memory allocation failed.\n");
return -ENOMEM;
}
memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size);
if (!(lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size, GFP_ATOMIC))) {
if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Memory allocation failed.\n");
return -ENOMEM;
}
memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size);
if (!(lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size, GFP_ATOMIC))) {
if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Memory allocation failed.\n");
return -ENOMEM;
}
memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size);
if (!(lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size, GFP_ATOMIC))) {
if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Memory allocation failed.\n");
return -ENOMEM;
}
memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size);
return 0;
}
static void pcnet32_free_ring(struct net_device *dev)
{
struct pcnet32_private *lp = dev->priv;
kfree(lp->tx_skbuff);
lp->tx_skbuff = NULL;
kfree(lp->rx_skbuff);
lp->rx_skbuff = NULL;
kfree(lp->tx_dma_addr);
lp->tx_dma_addr = NULL;
kfree(lp->rx_dma_addr);
lp->rx_dma_addr = NULL;
if (lp->tx_ring) {
pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
lp->tx_ring, lp->tx_ring_dma_addr);
lp->tx_ring = NULL;
}
if (lp->rx_ring) {
pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
lp->rx_ring, lp->rx_ring_dma_addr);
lp->rx_ring = NULL;
}
}
static int
pcnet32_open(struct net_device *dev)
{
@ -1400,8 +1559,8 @@ pcnet32_open(struct net_device *dev)
if (netif_msg_ifup(lp))
printk(KERN_DEBUG "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
dev->name, dev->irq,
(u32) (lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)),
(u32) (lp->dma_addr + offsetof(struct pcnet32_private, rx_ring)),
(u32) (lp->tx_ring_dma_addr),
(u32) (lp->rx_ring_dma_addr),
(u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block)));
/* set/reset autoselect bit */
@ -1521,7 +1680,7 @@ pcnet32_open(struct net_device *dev)
err_free_ring:
/* free any allocated skbuffs */
for (i = 0; i < RX_RING_SIZE; i++) {
for (i = 0; i < lp->rx_ring_size; i++) {
lp->rx_ring[i].status = 0;
if (lp->rx_skbuff[i]) {
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2,
@ -1531,6 +1690,9 @@ pcnet32_open(struct net_device *dev)
lp->rx_skbuff[i] = NULL;
lp->rx_dma_addr[i] = 0;
}
pcnet32_free_ring(dev);
/*
* Switch back to 16bit mode to avoid problems with dumb
* DOS packet driver after a warm reboot
@ -1562,7 +1724,7 @@ pcnet32_purge_tx_ring(struct net_device *dev)
struct pcnet32_private *lp = dev->priv;
int i;
for (i = 0; i < TX_RING_SIZE; i++) {
for (i = 0; i < lp->tx_ring_size; i++) {
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->tx_skbuff[i]) {
@ -1587,7 +1749,7 @@ pcnet32_init_ring(struct net_device *dev)
lp->cur_rx = lp->cur_tx = 0;
lp->dirty_rx = lp->dirty_tx = 0;
for (i = 0; i < RX_RING_SIZE; i++) {
for (i = 0; i < lp->rx_ring_size; i++) {
struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
if (rx_skbuff == NULL) {
if (!(rx_skbuff = lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) {
@ -1611,20 +1773,18 @@ pcnet32_init_ring(struct net_device *dev)
}
/* The Tx buffer address is filled in as needed, but we do need to clear
* the upper ownership bit. */
for (i = 0; i < TX_RING_SIZE; i++) {
for (i = 0; i < lp->tx_ring_size; i++) {
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
lp->tx_ring[i].base = 0;
lp->tx_dma_addr[i] = 0;
}
lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
for (i = 0; i < 6; i++)
lp->init_block.phys_addr[i] = dev->dev_addr[i];
lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
offsetof(struct pcnet32_private, rx_ring));
lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
offsetof(struct pcnet32_private, tx_ring));
lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
wmb(); /* Make sure all changes are visible */
return 0;
}
@ -1682,13 +1842,13 @@ pcnet32_tx_timeout (struct net_device *dev)
printk(KERN_DEBUG " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
lp->cur_rx);
for (i = 0 ; i < RX_RING_SIZE; i++)
for (i = 0 ; i < lp->rx_ring_size; i++)
printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
le32_to_cpu(lp->rx_ring[i].base),
(-le16_to_cpu(lp->rx_ring[i].buf_length)) & 0xffff,
le32_to_cpu(lp->rx_ring[i].msg_length),
le16_to_cpu(lp->rx_ring[i].status));
for (i = 0 ; i < TX_RING_SIZE; i++)
for (i = 0 ; i < lp->tx_ring_size; i++)
printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
le32_to_cpu(lp->tx_ring[i].base),
(-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff,
@ -1729,7 +1889,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Fill in a Tx ring entry */
/* Mask to ring buffer boundary. */
entry = lp->cur_tx & TX_RING_MOD_MASK;
entry = lp->cur_tx & lp->tx_mod_mask;
/* Caution: the write order is important here, set the status
* with the "ownership" bits last. */
@ -1753,7 +1913,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base != 0) {
if (lp->tx_ring[(entry+1) & lp->tx_mod_mask].base != 0) {
lp->tx_full = 1;
netif_stop_queue(dev);
}
@ -1806,7 +1966,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
int delta;
while (dirty_tx != lp->cur_tx) {
int entry = dirty_tx & TX_RING_MOD_MASK;
int entry = dirty_tx & lp->tx_mod_mask;
int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
if (status < 0)
@ -1864,18 +2024,18 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
dirty_tx++;
}
delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE);
if (delta > TX_RING_SIZE) {
delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
if (delta > lp->tx_ring_size) {
if (netif_msg_drv(lp))
printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
dirty_tx += TX_RING_SIZE;
delta -= TX_RING_SIZE;
dirty_tx += lp->tx_ring_size;
delta -= lp->tx_ring_size;
}
if (lp->tx_full &&
netif_queue_stopped(dev) &&
delta < TX_RING_SIZE - 2) {
delta < lp->tx_ring_size - 2) {
/* The ring is no longer full, clear tbusy. */
lp->tx_full = 0;
netif_wake_queue (dev);
@ -1932,8 +2092,8 @@ static int
pcnet32_rx(struct net_device *dev)
{
struct pcnet32_private *lp = dev->priv;
int entry = lp->cur_rx & RX_RING_MOD_MASK;
int boguscnt = RX_RING_SIZE / 2;
int entry = lp->cur_rx & lp->rx_mod_mask;
int boguscnt = lp->rx_ring_size / 2;
/* If we own the next entry, it's a new packet. Send it up. */
while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
@ -1998,12 +2158,12 @@ pcnet32_rx(struct net_device *dev)
if (netif_msg_drv(lp))
printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n",
dev->name);
for (i = 0; i < RX_RING_SIZE; i++)
for (i = 0; i < lp->rx_ring_size; i++)
if ((short)le16_to_cpu(lp->rx_ring[(entry+i)
& RX_RING_MOD_MASK].status) < 0)
& lp->rx_mod_mask].status) < 0)
break;
if (i > RX_RING_SIZE -2) {
if (i > lp->rx_ring_size -2) {
lp->stats.rx_dropped++;
lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
wmb(); /* Make sure adapter sees owner change */
@ -2041,7 +2201,7 @@ pcnet32_rx(struct net_device *dev)
lp->rx_ring[entry].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
wmb(); /* Make sure owner changes after all others are visible */
lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
entry = (++lp->cur_rx) & lp->rx_mod_mask;
if (--boguscnt <= 0) break; /* don't stay in loop forever */
}
@ -2084,7 +2244,7 @@ pcnet32_close(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
/* free all allocated skbuffs */
for (i = 0; i < RX_RING_SIZE; i++) {
for (i = 0; i < lp->rx_ring_size; i++) {
lp->rx_ring[i].status = 0;
wmb(); /* Make sure adapter sees owner change */
if (lp->rx_skbuff[i]) {
@ -2096,7 +2256,7 @@ pcnet32_close(struct net_device *dev)
lp->rx_dma_addr[i] = 0;
}
for (i = 0; i < TX_RING_SIZE; i++) {
for (i = 0; i < lp->tx_ring_size; i++) {
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->tx_skbuff[i]) {
@ -2265,6 +2425,7 @@ static void __devexit pcnet32_remove_one(struct pci_dev *pdev)
struct pcnet32_private *lp = dev->priv;
unregister_netdev(dev);
pcnet32_free_ring(dev);
release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
free_netdev(dev);
@ -2340,6 +2501,7 @@ static void __exit pcnet32_cleanup_module(void)
struct pcnet32_private *lp = pcnet32_dev->priv;
next_dev = lp->next;
unregister_netdev(pcnet32_dev);
pcnet32_free_ring(pcnet32_dev);
release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
free_netdev(pcnet32_dev);

View File

@ -12,14 +12,6 @@ config PHYLIB
devices. This option provides infrastructure for
managing PHY devices.
config PHYCONTROL
bool " Support for automatically handling PHY state changes"
depends on PHYLIB
help
Adds code to perform all the work for keeping PHY link
state (speed/duplex/etc) up-to-date. Also handles
interrupts.
comment "MII PHY device drivers"
depends on PHYLIB

View File

@ -242,10 +242,6 @@ EXPORT_SYMBOL(phy_sanitize_settings);
* choose the next best ones from the ones selected, so we don't
* care if ethtool tries to give us bad values
*
* A note about the PHYCONTROL Layer. If you turn off
* CONFIG_PHYCONTROL, you will need to read the PHY status
* registers after this function completes, and update your
* controller manually.
*/
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
{
@ -380,7 +376,6 @@ int phy_start_aneg(struct phy_device *phydev)
err = phydev->drv->config_aneg(phydev);
#ifdef CONFIG_PHYCONTROL
if (err < 0)
goto out_unlock;
@ -395,14 +390,12 @@ int phy_start_aneg(struct phy_device *phydev)
}
out_unlock:
#endif
spin_unlock(&phydev->lock);
return err;
}
EXPORT_SYMBOL(phy_start_aneg);
#ifdef CONFIG_PHYCONTROL
static void phy_change(void *data);
static void phy_timer(unsigned long data);
@ -868,4 +861,3 @@ static void phy_timer(unsigned long data)
mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
}
#endif /* CONFIG_PHYCONTROL */

View File

@ -101,7 +101,6 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
return dev;
}
#ifdef CONFIG_PHYCONTROL
/* phy_prepare_link:
*
* description: Tells the PHY infrastructure to handle the
@ -160,8 +159,6 @@ void phy_disconnect(struct phy_device *phydev)
}
EXPORT_SYMBOL(phy_disconnect);
#endif /* CONFIG_PHYCONTROL */
/* phy_attach:
*
* description: Called by drivers to attach to a particular PHY

View File

@ -1027,6 +1027,7 @@ static struct ethtool_ops rtl8169_ethtool_ops = {
.get_strings = rtl8169_get_strings,
.get_stats_count = rtl8169_get_stats_count,
.get_ethtool_stats = rtl8169_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr,
};
static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
@ -1511,6 +1512,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Get MAC address. FIXME: read EEPROM */
for (i = 0; i < MAC_ADDR_LEN; i++)
dev->dev_addr[i] = RTL_R8(MAC0 + i);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->open = rtl8169_open;
dev->hard_start_xmit = rtl8169_start_xmit;

574
drivers/net/rionet.c Normal file
View File

@ -0,0 +1,574 @@
/*
* rionet - Ethernet driver over RapidIO messaging services
*
* Copyright 2005 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
#include <linux/rio_ids.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/crc32.h>
#include <linux/ethtool.h>
#define DRV_NAME "rionet"
#define DRV_VERSION "0.2"
#define DRV_AUTHOR "Matt Porter <mporter@kernel.crashing.org>"
#define DRV_DESC "Ethernet over RapidIO"
MODULE_AUTHOR(DRV_AUTHOR);
MODULE_DESCRIPTION(DRV_DESC);
MODULE_LICENSE("GPL");
#define RIONET_DEFAULT_MSGLEVEL \
(NETIF_MSG_DRV | \
NETIF_MSG_LINK | \
NETIF_MSG_RX_ERR | \
NETIF_MSG_TX_ERR)
#define RIONET_DOORBELL_JOIN 0x1000
#define RIONET_DOORBELL_LEAVE 0x1001
#define RIONET_MAILBOX 0
#define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE
#define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE
static LIST_HEAD(rionet_peers);
struct rionet_private {
struct rio_mport *mport;
struct sk_buff *rx_skb[RIONET_RX_RING_SIZE];
struct sk_buff *tx_skb[RIONET_TX_RING_SIZE];
struct net_device_stats stats;
int rx_slot;
int tx_slot;
int tx_cnt;
int ack_slot;
spinlock_t lock;
spinlock_t tx_lock;
u32 msg_enable;
};
struct rionet_peer {
struct list_head node;
struct rio_dev *rdev;
struct resource *res;
};
static int rionet_check = 0;
static int rionet_capable = 1;
/*
* This is a fast lookup table for for translating TX
* Ethernet packets into a destination RIO device. It
* could be made into a hash table to save memory depending
* on system trade-offs.
*/
static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES];
#define is_rionet_capable(pef, src_ops, dst_ops) \
((pef & RIO_PEF_INB_MBOX) && \
(pef & RIO_PEF_INB_DOORBELL) && \
(src_ops & RIO_SRC_OPS_DOORBELL) && \
(dst_ops & RIO_DST_OPS_DOORBELL))
#define dev_rionet_capable(dev) \
is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops)
#define RIONET_MAC_MATCH(x) (*(u32 *)x == 0x00010001)
#define RIONET_GET_DESTID(x) (*(u16 *)(x + 4))
static struct net_device_stats *rionet_stats(struct net_device *ndev)
{
struct rionet_private *rnet = ndev->priv;
return &rnet->stats;
}
static int rionet_rx_clean(struct net_device *ndev)
{
int i;
int error = 0;
struct rionet_private *rnet = ndev->priv;
void *data;
i = rnet->rx_slot;
do {
if (!rnet->rx_skb[i])
continue;
if (!(data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX)))
break;
rnet->rx_skb[i]->data = data;
skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE);
rnet->rx_skb[i]->dev = ndev;
rnet->rx_skb[i]->protocol =
eth_type_trans(rnet->rx_skb[i], ndev);
error = netif_rx(rnet->rx_skb[i]);
if (error == NET_RX_DROP) {
rnet->stats.rx_dropped++;
} else if (error == NET_RX_BAD) {
if (netif_msg_rx_err(rnet))
printk(KERN_WARNING "%s: bad rx packet\n",
DRV_NAME);
rnet->stats.rx_errors++;
} else {
rnet->stats.rx_packets++;
rnet->stats.rx_bytes += RIO_MAX_MSG_SIZE;
}
} while ((i = (i + 1) % RIONET_RX_RING_SIZE) != rnet->rx_slot);
return i;
}
static void rionet_rx_fill(struct net_device *ndev, int end)
{
int i;
struct rionet_private *rnet = ndev->priv;
i = rnet->rx_slot;
do {
rnet->rx_skb[i] = dev_alloc_skb(RIO_MAX_MSG_SIZE);
if (!rnet->rx_skb[i])
break;
rio_add_inb_buffer(rnet->mport, RIONET_MAILBOX,
rnet->rx_skb[i]->data);
} while ((i = (i + 1) % RIONET_RX_RING_SIZE) != end);
rnet->rx_slot = i;
}
static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
struct rio_dev *rdev)
{
struct rionet_private *rnet = ndev->priv;
rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len);
rnet->tx_skb[rnet->tx_slot] = skb;
rnet->stats.tx_packets++;
rnet->stats.tx_bytes += skb->len;
if (++rnet->tx_cnt == RIONET_TX_RING_SIZE)
netif_stop_queue(ndev);
++rnet->tx_slot;
rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
if (netif_msg_tx_queued(rnet))
printk(KERN_INFO "%s: queued skb %8.8x len %8.8x\n", DRV_NAME,
(u32) skb, skb->len);
return 0;
}
static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
int i;
struct rionet_private *rnet = ndev->priv;
struct ethhdr *eth = (struct ethhdr *)skb->data;
u16 destid;
unsigned long flags;
local_irq_save(flags);
if (!spin_trylock(&rnet->tx_lock)) {
local_irq_restore(flags);
return NETDEV_TX_LOCKED;
}
if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
netif_stop_queue(ndev);
spin_unlock_irqrestore(&rnet->tx_lock, flags);
printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
ndev->name);
return NETDEV_TX_BUSY;
}
if (eth->h_dest[0] & 0x01) {
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++)
if (rionet_active[i])
rionet_queue_tx_msg(skb, ndev,
rionet_active[i]);
} else if (RIONET_MAC_MATCH(eth->h_dest)) {
destid = RIONET_GET_DESTID(eth->h_dest);
if (rionet_active[destid])
rionet_queue_tx_msg(skb, ndev, rionet_active[destid]);
}
spin_unlock_irqrestore(&rnet->tx_lock, flags);
return 0;
}
static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid,
u16 info)
{
struct net_device *ndev = dev_id;
struct rionet_private *rnet = ndev->priv;
struct rionet_peer *peer;
if (netif_msg_intr(rnet))
printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
DRV_NAME, sid, tid, info);
if (info == RIONET_DOORBELL_JOIN) {
if (!rionet_active[sid]) {
list_for_each_entry(peer, &rionet_peers, node) {
if (peer->rdev->destid == sid)
rionet_active[sid] = peer->rdev;
}
rio_mport_send_doorbell(mport, sid,
RIONET_DOORBELL_JOIN);
}
} else if (info == RIONET_DOORBELL_LEAVE) {
rionet_active[sid] = NULL;
} else {
if (netif_msg_intr(rnet))
printk(KERN_WARNING "%s: unhandled doorbell\n",
DRV_NAME);
}
}
static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
{
int n;
struct net_device *ndev = dev_id;
struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
if (netif_msg_intr(rnet))
printk(KERN_INFO "%s: inbound message event, mbox %d slot %d\n",
DRV_NAME, mbox, slot);
spin_lock(&rnet->lock);
if ((n = rionet_rx_clean(ndev)) != rnet->rx_slot)
rionet_rx_fill(ndev, n);
spin_unlock(&rnet->lock);
}
static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
{
struct net_device *ndev = dev_id;
struct rionet_private *rnet = ndev->priv;
spin_lock(&rnet->lock);
if (netif_msg_intr(rnet))
printk(KERN_INFO
"%s: outbound message event, mbox %d slot %d\n",
DRV_NAME, mbox, slot);
while (rnet->tx_cnt && (rnet->ack_slot != slot)) {
/* dma unmap single */
dev_kfree_skb_irq(rnet->tx_skb[rnet->ack_slot]);
rnet->tx_skb[rnet->ack_slot] = NULL;
++rnet->ack_slot;
rnet->ack_slot &= (RIONET_TX_RING_SIZE - 1);
rnet->tx_cnt--;
}
if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
netif_wake_queue(ndev);
spin_unlock(&rnet->lock);
}
static int rionet_open(struct net_device *ndev)
{
int i, rc = 0;
struct rionet_peer *peer, *tmp;
u32 pwdcsr;
struct rionet_private *rnet = ndev->priv;
if (netif_msg_ifup(rnet))
printk(KERN_INFO "%s: open\n", DRV_NAME);
if ((rc = rio_request_inb_dbell(rnet->mport,
(void *)ndev,
RIONET_DOORBELL_JOIN,
RIONET_DOORBELL_LEAVE,
rionet_dbell_event)) < 0)
goto out;
if ((rc = rio_request_inb_mbox(rnet->mport,
(void *)ndev,
RIONET_MAILBOX,
RIONET_RX_RING_SIZE,
rionet_inb_msg_event)) < 0)
goto out;
if ((rc = rio_request_outb_mbox(rnet->mport,
(void *)ndev,
RIONET_MAILBOX,
RIONET_TX_RING_SIZE,
rionet_outb_msg_event)) < 0)
goto out;
/* Initialize inbound message ring */
for (i = 0; i < RIONET_RX_RING_SIZE; i++)
rnet->rx_skb[i] = NULL;
rnet->rx_slot = 0;
rionet_rx_fill(ndev, 0);
rnet->tx_slot = 0;
rnet->tx_cnt = 0;
rnet->ack_slot = 0;
netif_carrier_on(ndev);
netif_start_queue(ndev);
list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
if (!(peer->res = rio_request_outb_dbell(peer->rdev,
RIONET_DOORBELL_JOIN,
RIONET_DOORBELL_LEAVE)))
{
printk(KERN_ERR "%s: error requesting doorbells\n",
DRV_NAME);
continue;
}
/*
* If device has initialized inbound doorbells,
* send a join message
*/
rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr);
if (pwdcsr & RIO_DOORBELL_AVAIL)
rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
}
out:
return rc;
}
static int rionet_close(struct net_device *ndev)
{
struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
struct rionet_peer *peer, *tmp;
int i;
if (netif_msg_ifup(rnet))
printk(KERN_INFO "%s: close\n", DRV_NAME);
netif_stop_queue(ndev);
netif_carrier_off(ndev);
for (i = 0; i < RIONET_RX_RING_SIZE; i++)
if (rnet->rx_skb[i])
kfree_skb(rnet->rx_skb[i]);
list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
if (rionet_active[peer->rdev->destid]) {
rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE);
rionet_active[peer->rdev->destid] = NULL;
}
rio_release_outb_dbell(peer->rdev, peer->res);
}
rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN,
RIONET_DOORBELL_LEAVE);
rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX);
rio_release_outb_mbox(rnet->mport, RIONET_MAILBOX);
return 0;
}
static void rionet_remove(struct rio_dev *rdev)
{
struct net_device *ndev = NULL;
struct rionet_peer *peer, *tmp;
unregister_netdev(ndev);
kfree(ndev);
list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
list_del(&peer->node);
kfree(peer);
}
}
static void rionet_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
{
struct rionet_private *rnet = ndev->priv;
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->fw_version, "n/a");
strcpy(info->bus_info, rnet->mport->name);
}
static u32 rionet_get_msglevel(struct net_device *ndev)
{
struct rionet_private *rnet = ndev->priv;
return rnet->msg_enable;
}
static void rionet_set_msglevel(struct net_device *ndev, u32 value)
{
struct rionet_private *rnet = ndev->priv;
rnet->msg_enable = value;
}
static struct ethtool_ops rionet_ethtool_ops = {
.get_drvinfo = rionet_get_drvinfo,
.get_msglevel = rionet_get_msglevel,
.set_msglevel = rionet_set_msglevel,
.get_link = ethtool_op_get_link,
};
static int rionet_setup_netdev(struct rio_mport *mport)
{
int rc = 0;
struct net_device *ndev = NULL;
struct rionet_private *rnet;
u16 device_id;
/* Allocate our net_device structure */
ndev = alloc_etherdev(sizeof(struct rionet_private));
if (ndev == NULL) {
printk(KERN_INFO "%s: could not allocate ethernet device.\n",
DRV_NAME);
rc = -ENOMEM;
goto out;
}
/* Set up private area */
rnet = (struct rionet_private *)ndev->priv;
rnet->mport = mport;
/* Set the default MAC address */
device_id = rio_local_get_device_id(mport);
ndev->dev_addr[0] = 0x00;
ndev->dev_addr[1] = 0x01;
ndev->dev_addr[2] = 0x00;
ndev->dev_addr[3] = 0x01;
ndev->dev_addr[4] = device_id >> 8;
ndev->dev_addr[5] = device_id & 0xff;
/* Fill in the driver function table */
ndev->open = &rionet_open;
ndev->hard_start_xmit = &rionet_start_xmit;
ndev->stop = &rionet_close;
ndev->get_stats = &rionet_stats;
ndev->mtu = RIO_MAX_MSG_SIZE - 14;
ndev->features = NETIF_F_LLTX;
SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
SET_MODULE_OWNER(ndev);
spin_lock_init(&rnet->lock);
spin_lock_init(&rnet->tx_lock);
rnet->msg_enable = RIONET_DEFAULT_MSGLEVEL;
rc = register_netdev(ndev);
if (rc != 0)
goto out;
printk("%s: %s %s Version %s, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
ndev->name,
DRV_NAME,
DRV_DESC,
DRV_VERSION,
ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
out:
return rc;
}
/*
* XXX Make multi-net safe
*/
static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
{
int rc = -ENODEV;
u32 lpef, lsrc_ops, ldst_ops;
struct rionet_peer *peer;
/* If local device is not rionet capable, give up quickly */
if (!rionet_capable)
goto out;
/*
* First time through, make sure local device is rionet
* capable, setup netdev, and set flags so this is skipped
* on later probes
*/
if (!rionet_check) {
rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef);
rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
&lsrc_ops);
rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
&ldst_ops);
if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) {
printk(KERN_ERR
"%s: local device is not network capable\n",
DRV_NAME);
rionet_check = 1;
rionet_capable = 0;
goto out;
}
rc = rionet_setup_netdev(rdev->net->hport);
rionet_check = 1;
}
/*
* If the remote device has mailbox/doorbell capabilities,
* add it to the peer list.
*/
if (dev_rionet_capable(rdev)) {
if (!(peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL))) {
rc = -ENOMEM;
goto out;
}
peer->rdev = rdev;
list_add_tail(&peer->node, &rionet_peers);
}
out:
return rc;
}
static struct rio_device_id rionet_id_table[] = {
{RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}
};
static struct rio_driver rionet_driver = {
.name = "rionet",
.id_table = rionet_id_table,
.probe = rionet_probe,
.remove = rionet_remove,
};
static int __init rionet_init(void)
{
return rio_register_driver(&rionet_driver);
}
static void __exit rionet_exit(void)
{
rio_unregister_driver(&rionet_driver);
}
module_init(rionet_init);
module_exit(rionet_exit);

View File

@ -814,6 +814,17 @@ typedef struct _XENA_dev_config {
u64 rxgxs_ber_0; /* CHANGED */
u64 rxgxs_ber_1; /* CHANGED */
u64 spi_control;
#define SPI_CONTROL_KEY(key) vBIT(key,0,4)
#define SPI_CONTROL_BYTECNT(cnt) vBIT(cnt,29,3)
#define SPI_CONTROL_CMD(cmd) vBIT(cmd,32,8)
#define SPI_CONTROL_ADDR(addr) vBIT(addr,40,24)
#define SPI_CONTROL_SEL1 BIT(4)
#define SPI_CONTROL_REQ BIT(7)
#define SPI_CONTROL_NACK BIT(5)
#define SPI_CONTROL_DONE BIT(6)
u64 spi_data;
#define SPI_DATA_WRITE(data,len) vBIT(data,0,len)
} XENA_dev_config_t;
#define XENA_REG_SPACE sizeof(XENA_dev_config_t)

File diff suppressed because it is too large Load Diff

View File

@ -652,6 +652,30 @@ typedef struct {
#define SMALL_BLK_CNT 30
#define LARGE_BLK_CNT 100
/*
* Structure to keep track of the MSI-X vectors and the corresponding
* argument registered against each vector
*/
#define MAX_REQUESTED_MSI_X 17
struct s2io_msix_entry
{
u16 vector;
u16 entry;
void *arg;
u8 type;
#define MSIX_FIFO_TYPE 1
#define MSIX_RING_TYPE 2
u8 in_use;
#define MSIX_REGISTERED_SUCCESS 0xAA
};
struct msix_info_st {
u64 addr;
u64 data;
};
/* Structure representing one instance of the NIC */
struct s2io_nic {
#ifdef CONFIG_S2IO_NAPI
@ -719,13 +743,8 @@ struct s2io_nic {
* a schedule task that will set the correct Link state once the
* NIC's PHY has stabilized after a state change.
*/
#ifdef INIT_TQUEUE
struct tq_struct rst_timer_task;
struct tq_struct set_link_task;
#else
struct work_struct rst_timer_task;
struct work_struct set_link_task;
#endif
/* Flag that can be used to turn on or turn off the Rx checksum
* offload feature.
@ -748,10 +767,23 @@ struct s2io_nic {
atomic_t card_state;
volatile unsigned long link_state;
struct vlan_group *vlgrp;
#define MSIX_FLG 0xA5
struct msix_entry *entries;
struct s2io_msix_entry *s2io_entries;
char desc1[35];
char desc2[35];
struct msix_info_st msix_info[0x3f];
#define XFRAME_I_DEVICE 1
#define XFRAME_II_DEVICE 2
u8 device_type;
#define INTA 0
#define MSI 1
#define MSI_X 2
u8 intr_type;
spinlock_t rx_lock;
atomic_t isr_cnt;
};
@ -886,6 +918,13 @@ static int s2io_poll(struct net_device *dev, int *budget);
static void s2io_init_pci(nic_t * sp);
int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
static void s2io_alarm_handle(unsigned long data);
static int s2io_enable_msi(nic_t *nic);
static irqreturn_t s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t
s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t
s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs);
int s2io_enable_msi_x(nic_t *nic);
static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs);
static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag);
static struct ethtool_ops netdev_ethtool_ops;
@ -894,4 +933,5 @@ int s2io_set_swapper(nic_t * sp);
static void s2io_card_down(nic_t *nic);
static int s2io_card_up(nic_t *nic);
int get_xena_rev_id(struct pci_dev *pdev);
void restore_xmsi_data(nic_t *nic);
#endif /* _S2IO_H */

File diff suppressed because it is too large Load Diff

View File

@ -32,8 +32,6 @@
#include "sgiseeq.h"
static char *version = "sgiseeq.c: David S. Miller (dm@engr.sgi.com)\n";
static char *sgiseeqstr = "SGI Seeq8003";
/*
@ -113,9 +111,9 @@ static struct net_device *root_sgiseeq_dev;
static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
{
hregs->rx_reset = HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ;
hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
udelay(20);
hregs->rx_reset = 0;
hregs->reset = 0;
}
static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs,
@ -252,7 +250,6 @@ void sgiseeq_dump_rings(void)
#define TSTAT_INIT_SEEQ (SEEQ_TCMD_IPT|SEEQ_TCMD_I16|SEEQ_TCMD_IC|SEEQ_TCMD_IUF)
#define TSTAT_INIT_EDLC ((TSTAT_INIT_SEEQ) | SEEQ_TCMD_RB2)
#define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ)
static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
struct sgiseeq_regs *sregs)
@ -274,8 +271,6 @@ static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
sregs->tstat = TSTAT_INIT_SEEQ;
}
hregs->rx_dconfig |= RDMACFG_INIT;
hregs->rx_ndptr = CPHYSADDR(sp->rx_desc);
hregs->tx_ndptr = CPHYSADDR(sp->tx_desc);
@ -446,7 +441,7 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs
spin_lock(&sp->tx_lock);
/* Ack the IRQ and set software state. */
hregs->rx_reset = HPC3_ERXRST_CLRIRQ;
hregs->reset = HPC3_ERST_CLRIRQ;
/* Always check for received packets. */
sgiseeq_rx(dev, sp, hregs, sregs);
@ -493,11 +488,13 @@ static int sgiseeq_close(struct net_device *dev)
{
struct sgiseeq_private *sp = netdev_priv(dev);
struct sgiseeq_regs *sregs = sp->sregs;
unsigned int irq = dev->irq;
netif_stop_queue(dev);
/* Shutdown the Seeq. */
reset_hpc3_and_seeq(sp->hregs, sregs);
free_irq(irq, dev);
return 0;
}
@ -644,7 +641,7 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs)
#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf))
static int sgiseeq_init(struct hpc3_regs* regs, int irq)
static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq)
{
struct sgiseeq_init_block *sr;
struct sgiseeq_private *sp;
@ -680,8 +677,8 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
gpriv = sp;
gdev = dev;
#endif
sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0];
sp->hregs = &hpc3c0->ethregs;
sp->sregs = (struct sgiseeq_regs *) &hpcregs->eth_ext[0];
sp->hregs = &hpcregs->ethregs;
sp->name = sgiseeqstr;
sp->mode = SEEQ_RCMD_RBCAST;
@ -698,6 +695,11 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS);
setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS);
/* Setup PIO and DMA transfer timing */
sp->hregs->pconfig = 0x161;
sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP |
HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026;
/* Reset the chip. */
hpc3_eth_reset(sp->hregs);
@ -724,7 +726,7 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
goto err_out_free_page;
}
printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name);
printk(KERN_INFO "%s: %s ", dev->name, sgiseeqstr);
for (i = 0; i < 6; i++)
printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
@ -734,7 +736,7 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
return 0;
err_out_free_page:
free_page((unsigned long) sp);
free_page((unsigned long) sp->srings);
err_out_free_dev:
kfree(dev);
@ -744,8 +746,6 @@ static int sgiseeq_init(struct hpc3_regs* regs, int irq)
static int __init sgiseeq_probe(void)
{
printk(version);
/* On board adapter on 1st HPC is always present */
return sgiseeq_init(hpc3c0, SGI_ENET_IRQ);
}
@ -754,15 +754,12 @@ static void __exit sgiseeq_exit(void)
{
struct net_device *next, *dev;
struct sgiseeq_private *sp;
int irq;
for (dev = root_sgiseeq_dev; dev; dev = next) {
sp = (struct sgiseeq_private *) netdev_priv(dev);
next = sp->next_module;
irq = dev->irq;
unregister_netdev(dev);
free_irq(irq, dev);
free_page((unsigned long) sp);
free_page((unsigned long) sp->srings);
free_netdev(dev);
}
}
@ -770,4 +767,6 @@ static void __exit sgiseeq_exit(void)
module_init(sgiseeq_probe);
module_exit(sgiseeq_exit);
MODULE_DESCRIPTION("SGI Seeq 8003 driver");
MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>");
MODULE_LICENSE("GPL");

View File

@ -730,6 +730,7 @@ static struct ethtool_ops skge_ethtool_ops = {
.phys_id = skge_phys_id,
.get_stats_count = skge_get_stats_count,
.get_ethtool_stats = skge_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr,
};
/*
@ -3096,6 +3097,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
/* read the mac address */
memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* device is off until link detection */
netif_carrier_off(dev);

View File

@ -518,6 +518,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
#else
int bar = 1;
#endif
int phy, phy_idx = 0;
/* when built into the kernel, we only print version if device is found */
@ -549,6 +550,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
for (i = 0; i < 3; i++)
((u16 *)dev->dev_addr)[i] =
le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->base_addr = (unsigned long)ioaddr;
dev->irq = irq;
@ -605,32 +607,30 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
printk("%2.2x:", dev->dev_addr[i]);
printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
if (1) {
int phy, phy_idx = 0;
np->phys[0] = 1; /* Default setting */
np->mii_preamble_required++;
for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
int mii_status = mdio_read(dev, phy, MII_BMSR);
if (mii_status != 0xffff && mii_status != 0x0000) {
np->phys[phy_idx++] = phy;
np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
if ((mii_status & 0x0040) == 0)
np->mii_preamble_required++;
printk(KERN_INFO "%s: MII PHY found at address %d, status "
"0x%4.4x advertising %4.4x.\n",
dev->name, phy, mii_status, np->mii_if.advertising);
}
np->phys[0] = 1; /* Default setting */
np->mii_preamble_required++;
for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) {
int mii_status = mdio_read(dev, phy, MII_BMSR);
int phyx = phy & 0x1f;
if (mii_status != 0xffff && mii_status != 0x0000) {
np->phys[phy_idx++] = phyx;
np->mii_if.advertising = mdio_read(dev, phyx, MII_ADVERTISE);
if ((mii_status & 0x0040) == 0)
np->mii_preamble_required++;
printk(KERN_INFO "%s: MII PHY found at address %d, status "
"0x%4.4x advertising %4.4x.\n",
dev->name, phyx, mii_status, np->mii_if.advertising);
}
np->mii_preamble_required--;
if (phy_idx == 0) {
printk(KERN_INFO "%s: No MII transceiver found, aborting. ASIC status %x\n",
dev->name, ioread32(ioaddr + ASICCtrl));
goto err_out_unregister;
}
np->mii_if.phy_id = np->phys[0];
}
np->mii_preamble_required--;
if (phy_idx == 0) {
printk(KERN_INFO "%s: No MII transceiver found, aborting. ASIC status %x\n",
dev->name, ioread32(ioaddr + ASICCtrl));
goto err_out_unregister;
}
np->mii_if.phy_id = np->phys[0];
/* Parse override configuration */
np->an_enable = 1;
@ -692,7 +692,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
/* Reset the chip to erase previous misconfiguration. */
if (netif_msg_hw(np))
printk("ASIC Control is %x.\n", ioread32(ioaddr + ASICCtrl));
iowrite16(0x007f, ioaddr + ASICCtrl + 2);
iowrite16(0x00ff, ioaddr + ASICCtrl + 2);
if (netif_msg_hw(np))
printk("ASIC Control is now %x.\n", ioread32(ioaddr + ASICCtrl));
@ -1619,6 +1619,7 @@ static struct ethtool_ops ethtool_ops = {
.get_link = get_link,
.get_msglevel = get_msglevel,
.set_msglevel = set_msglevel,
.get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)

View File

@ -318,7 +318,7 @@ static void ibmtr_cleanup_card(struct net_device *dev)
if (dev->base_addr) {
outb(0,dev->base_addr+ADAPTRESET);
schedule_timeout(TR_RST_TIME); /* wait 50ms */
schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
outb(0,dev->base_addr+ADAPTRESETREL);
}
@ -854,8 +854,7 @@ static int tok_init_card(struct net_device *dev)
writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
outb(0, PIOaddr + ADAPTRESET);
current->state=TASK_UNINTERRUPTIBLE;
schedule_timeout(TR_RST_TIME); /* wait 50ms */
schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
outb(0, PIOaddr + ADAPTRESETREL);
#ifdef ENABLE_PAGING
@ -903,8 +902,8 @@ static int tok_open(struct net_device *dev)
DPRINTK("Adapter is up and running\n");
return 0;
}
current->state=TASK_INTERRUPTIBLE;
i=schedule_timeout(TR_RETRY_INTERVAL); /* wait 30 seconds */
i=schedule_timeout_interruptible(TR_RETRY_INTERVAL);
/* wait 30 seconds */
if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */
}
outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/

View File

@ -1101,7 +1101,7 @@ static int olympic_close(struct net_device *dev)
while(olympic_priv->srb_queued) {
t = schedule_timeout(60*HZ);
t = schedule_timeout_interruptible(60*HZ);
if(signal_pending(current)) {
printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);

View File

@ -1243,8 +1243,7 @@ void tms380tr_wait(unsigned long time)
tmp = jiffies + time/(1000000/HZ);
do {
current->state = TASK_INTERRUPTIBLE;
tmp = schedule_timeout(tmp);
tmp = schedule_timeout_interruptible(tmp);
} while(time_after(tmp, jiffies));
#else
udelay(time);

View File

@ -1787,10 +1787,15 @@ static void __init de21041_get_srom_info (struct de_private *de)
/* DEC now has a specification but early board makers
just put the address in the first EEPROM locations. */
/* This does memcmp(eedata, eedata+16, 8) */
#ifndef CONFIG_MIPS_COBALT
for (i = 0; i < 8; i ++)
if (ee_data[i] != ee_data[16+i])
sa_offset = 20;
#endif
/* store MAC address */
for (i = 0; i < 6; i ++)
de->dev->dev_addr[i] = ee_data[i + sa_offset];

View File

@ -419,10 +419,9 @@ typhoon_reset(void __iomem *ioaddr, int wait_type)
TYPHOON_STATUS_WAITING_FOR_HOST)
goto out;
if(wait_type == WaitSleep) {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} else
if(wait_type == WaitSleep)
schedule_timeout_uninterruptible(1);
else
udelay(TYPHOON_UDELAY);
}

View File

@ -490,6 +490,8 @@ struct rhine_private {
u8 tx_thresh, rx_thresh;
struct mii_if_info mii_if;
struct work_struct tx_timeout_task;
struct work_struct check_media_task;
void __iomem *base;
};
@ -497,6 +499,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int rhine_open(struct net_device *dev);
static void rhine_tx_timeout(struct net_device *dev);
static void rhine_tx_timeout_task(struct net_device *dev);
static void rhine_check_media_task(struct net_device *dev);
static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static void rhine_tx(struct net_device *dev);
@ -814,8 +818,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
for (i = 0; i < 6; i++)
dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
if (!is_valid_ether_addr(dev->dev_addr)) {
if (!is_valid_ether_addr(dev->perm_addr)) {
rc = -EIO;
printk(KERN_ERR "Invalid MAC address\n");
goto err_out_unmap;
@ -850,6 +855,12 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
if (rp->quirks & rqRhineI)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
INIT_WORK(&rp->tx_timeout_task,
(void (*)(void *))rhine_tx_timeout_task, dev);
INIT_WORK(&rp->check_media_task,
(void (*)(void *))rhine_check_media_task, dev);
/* dev->name not defined before register_netdev()! */
rc = register_netdev(dev);
if (rc)
@ -1076,6 +1087,11 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media)
ioaddr + ChipCmd1);
}
static void rhine_check_media_task(struct net_device *dev)
{
rhine_check_media(dev, 0);
}
static void init_registers(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
@ -1129,8 +1145,8 @@ static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks)
if (quirks & rqRhineI) {
iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR
/* Can be called from ISR. Evil. */
mdelay(1);
/* Do not call from ISR! */
msleep(1);
/* 0x80 must be set immediately before turning it off */
iowrite8(0x80, ioaddr + MIICmd);
@ -1218,6 +1234,16 @@ static int rhine_open(struct net_device *dev)
}
static void rhine_tx_timeout(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
/*
* Move bulk of work outside of interrupt context
*/
schedule_work(&rp->tx_timeout_task);
}
static void rhine_tx_timeout_task(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
@ -1625,7 +1651,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
spin_lock(&rp->lock);
if (intr_status & IntrLinkChange)
rhine_check_media(dev, 0);
schedule_work(&rp->check_media_task);
if (intr_status & IntrStatsMax) {
rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
@ -1829,6 +1855,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
.set_wol = rhine_set_wol,
.get_sg = ethtool_op_get_sg,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@ -1872,6 +1899,9 @@ static int rhine_close(struct net_device *dev)
spin_unlock_irq(&rp->lock);
free_irq(rp->pdev->irq, dev);
flush_scheduled_work();
free_rbufs(dev);
free_tbufs(dev);
free_ring(dev);

View File

@ -1617,8 +1617,7 @@ static int get_wait_data(struct cosa_data *cosa)
return r;
}
/* sleep if not ready to read */
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout_interruptible(1);
}
printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n",
cosa_getstatus(cosa));
@ -1644,8 +1643,7 @@ static int put_wait_data(struct cosa_data *cosa, int data)
}
#if 0
/* sleep if not ready to read */
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(1);
schedule_timeout_interruptible(1);
#endif
}
printk(KERN_INFO "cosa%d: timeout in put_wait_data (status 0x%x)\n",

View File

@ -109,7 +109,7 @@ static long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 };
* < 0 error.
* Context: process */
int __init cycx_drv_init(void)
static int __init cycx_drv_init(void)
{
printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE,
copyright);
@ -119,7 +119,7 @@ int __init cycx_drv_init(void)
/* Module 'remove' entry point.
* o release all remaining system resources */
void cycx_drv_cleanup(void)
static void cycx_drv_cleanup(void)
{
}
@ -184,8 +184,7 @@ int cycx_down(struct cycx_hw *hw)
}
/* Enable interrupt generation. */
EXPORT_SYMBOL(cycx_inten);
void cycx_inten(struct cycx_hw *hw)
static void cycx_inten(struct cycx_hw *hw)
{
writeb(0, hw->dpmbase);
}

View File

@ -103,7 +103,7 @@ static struct cycx_device *cycx_card_array; /* adapter data space */
* < 0 error.
* Context: process
*/
int __init cycx_init(void)
static int __init cycx_init(void)
{
int cnt, err = -ENOMEM;

View File

@ -78,6 +78,7 @@
#define CYCLOMX_X25_DEBUG 1
#include <linux/ctype.h> /* isdigit() */
#include <linux/errno.h> /* return codes */
#include <linux/if_arp.h> /* ARPHRD_HWX25 */
#include <linux/kernel.h> /* printk(), and other useful stuff */
@ -418,7 +419,7 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
/* Set channel timeouts (default if not specified) */
chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
} else if (is_digit(conf->addr[0])) { /* PVC */
} else if (isdigit(conf->addr[0])) { /* PVC */
s16 lcn = dec_to_uint(conf->addr, 0);
if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
@ -1531,7 +1532,7 @@ static unsigned dec_to_uint(u8 *str, int len)
if (!len)
len = strlen(str);
for (; len && is_digit(*str); ++str, --len)
for (; len && isdigit(*str); ++str, --len)
val = (val * 10) + (*str - (unsigned) '0');
return val;

View File

@ -446,8 +446,8 @@ static inline unsigned int dscc4_tx_quiescent(struct dscc4_dev_priv *dpriv,
return readl(dpriv->base_addr + CH0FTDA + dpriv->dev_id*4) == dpriv->ltda;
}
int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
const char *msg)
static int state_check(u32 state, struct dscc4_dev_priv *dpriv,
struct net_device *dev, const char *msg)
{
int ret = 0;
@ -466,8 +466,9 @@ int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
return ret;
}
void dscc4_tx_print(struct net_device *dev, struct dscc4_dev_priv *dpriv,
char *msg)
static void dscc4_tx_print(struct net_device *dev,
struct dscc4_dev_priv *dpriv,
char *msg)
{
printk(KERN_DEBUG "%s: tx_current=%02d tx_dirty=%02d (%s)\n",
dev->name, dpriv->tx_current, dpriv->tx_dirty, msg);
@ -507,7 +508,8 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv)
}
}
inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, struct net_device *dev)
static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
struct net_device *dev)
{
unsigned int dirty = dpriv->rx_dirty%RX_RING_SIZE;
struct RxFD *rx_fd = dpriv->rx_fd + dirty;
@ -542,8 +544,7 @@ static int dscc4_wait_ack_cec(struct dscc4_dev_priv *dpriv,
msg, i);
goto done;
}
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(10);
schedule_timeout_uninterruptible(10);
rmb();
} while (++i > 0);
printk(KERN_ERR "%s: %s timeout\n", dev->name, msg);
@ -588,8 +589,7 @@ static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv)
(dpriv->iqtx[cur] & Xpr))
break;
smp_rmb();
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(10);
schedule_timeout_uninterruptible(10);
} while (++i > 0);
return (i >= 0 ) ? i : -EAGAIN;
@ -1035,8 +1035,7 @@ static void dscc4_pci_reset(struct pci_dev *pdev, void __iomem *ioaddr)
/* Flush posted writes */
readl(ioaddr + GSTAR);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(10);
schedule_timeout_uninterruptible(10);
for (i = 0; i < 16; i++)
pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]);
@ -1894,7 +1893,7 @@ static void dscc4_rx_irq(struct dscc4_pci_priv *priv,
* It failed and locked solid. Thus the introduction of a dummy skb.
* Problem is acknowledged in errata sheet DS5. Joy :o/
*/
struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
{
struct sk_buff *skb;

View File

@ -74,11 +74,11 @@ MODULE_LICENSE("GPL");
/*
* Modules parameters and associated varaibles
*/
int fst_txq_low = FST_LOW_WATER_MARK;
int fst_txq_high = FST_HIGH_WATER_MARK;
int fst_max_reads = 7;
int fst_excluded_cards = 0;
int fst_excluded_list[FST_MAX_CARDS];
static int fst_txq_low = FST_LOW_WATER_MARK;
static int fst_txq_high = FST_HIGH_WATER_MARK;
static int fst_max_reads = 7;
static int fst_excluded_cards = 0;
static int fst_excluded_list[FST_MAX_CARDS];
module_param(fst_txq_low, int, 0);
module_param(fst_txq_high, int, 0);
@ -572,13 +572,13 @@ static void do_bottom_half_rx(struct fst_card_info *card);
static void fst_process_tx_work_q(unsigned long work_q);
static void fst_process_int_work_q(unsigned long work_q);
DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
static DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
static DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
struct fst_card_info *fst_card_array[FST_MAX_CARDS];
spinlock_t fst_work_q_lock;
u64 fst_work_txq;
u64 fst_work_intq;
static struct fst_card_info *fst_card_array[FST_MAX_CARDS];
static spinlock_t fst_work_q_lock;
static u64 fst_work_txq;
static u64 fst_work_intq;
static void
fst_q_work_item(u64 * queue, int card_index)
@ -980,8 +980,7 @@ fst_issue_cmd(struct fst_port_info *port, unsigned short cmd)
/* Wait for any previous command to complete */
while (mbval > NAK) {
spin_unlock_irqrestore(&card->card_lock, flags);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
schedule_timeout_uninterruptible(1);
spin_lock_irqsave(&card->card_lock, flags);
if (++safety > 2000) {
@ -1498,7 +1497,7 @@ do_bottom_half_rx(struct fst_card_info *card)
* The interrupt service routine
* Dev_id is our fst_card_info pointer
*/
irqreturn_t
static irqreturn_t
fst_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct fst_card_info *card;

View File

@ -330,7 +330,7 @@ static int pvc_close(struct net_device *dev)
int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
pvc_device *pvc = dev_to_pvc(dev);
fr_proto_pvc_info info;

View File

@ -8,10 +8,10 @@
/*
* Prints out len, max to 80 octets using printk, 20 per line
*/
void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
{
#ifdef DEBUG
#ifdef LMC_PACKET_LOG
void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
{
int iNewLine = 1;
char str[80], *pstr;
@ -43,26 +43,24 @@ void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
}
sprintf(pstr, "\n");
printk(str);
#endif
#endif
}
#endif
#endif
#ifdef DEBUG
u_int32_t lmcEventLogIndex = 0;
u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
#endif
void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3)
{
#ifdef DEBUG
lmcEventLogBuf[lmcEventLogIndex++] = EventNum;
lmcEventLogBuf[lmcEventLogIndex++] = arg2;
lmcEventLogBuf[lmcEventLogIndex++] = arg3;
lmcEventLogBuf[lmcEventLogIndex++] = jiffies;
lmcEventLogIndex &= (LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS) - 1;
#endif
}
#endif /* DEBUG */
void lmc_trace(struct net_device *dev, char *msg){
#ifdef LMC_TRACE

View File

@ -47,14 +47,6 @@
* of the GNU General Public License version 2, incorporated herein by reference.
*/
/*
* For lack of a better place, put the SSI cable stuff here.
*/
char *lmc_t1_cables[] = {
"V.10/RS423", "EIA530A", "reserved", "X.21", "V.35",
"EIA449/EIA530/V.36", "V.28/EIA232", "none", NULL
};
/*
* protocol independent method.
*/

View File

@ -472,24 +472,8 @@ enum pc300_loopback_cmds {
#ifdef __KERNEL__
/* Function Prototypes */
int dma_buf_write(pc300_t *, int, ucchar *, int);
int dma_buf_read(pc300_t *, int, struct sk_buff *);
void tx_dma_start(pc300_t *, int);
void rx_dma_start(pc300_t *, int);
void tx_dma_stop(pc300_t *, int);
void rx_dma_stop(pc300_t *, int);
int cpc_queue_xmit(struct sk_buff *, struct net_device *);
void cpc_net_rx(struct net_device *);
void cpc_sca_status(pc300_t *, int);
int cpc_change_mtu(struct net_device *, int);
int cpc_ioctl(struct net_device *, struct ifreq *, int);
int ch_config(pc300dev_t *);
int rx_config(pc300dev_t *);
int tx_config(pc300dev_t *);
void cpc_opench(pc300dev_t *);
void cpc_closech(pc300dev_t *);
int cpc_open(struct net_device *dev);
int cpc_close(struct net_device *dev);
int cpc_set_media(hdlc_device *, int);
#endif /* __KERNEL__ */

View File

@ -291,6 +291,7 @@ static uclong detect_ram(pc300_t *);
static void plx_init(pc300_t *);
static void cpc_trace(struct net_device *, struct sk_buff *, char);
static int cpc_attach(struct net_device *, unsigned short, unsigned short);
static int cpc_close(struct net_device *dev);
#ifdef CONFIG_PC300_MLPPP
void cpc_tty_init(pc300dev_t * dev);
@ -437,7 +438,7 @@ static void rx_dma_buf_check(pc300_t * card, int ch)
printk("\n");
}
int dma_get_rx_frame_size(pc300_t * card, int ch)
static int dma_get_rx_frame_size(pc300_t * card, int ch)
{
volatile pcsca_bd_t __iomem *ptdescr;
ucshort first_bd = card->chan[ch].rx_first_bd;
@ -462,7 +463,7 @@ int dma_get_rx_frame_size(pc300_t * card, int ch)
* dma_buf_write: writes a frame to the Tx DMA buffers
* NOTE: this function writes one frame at a time.
*/
int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
static int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
{
int i, nchar;
volatile pcsca_bd_t __iomem *ptdescr;
@ -503,7 +504,7 @@ int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
* dma_buf_read: reads a frame from the Rx DMA buffers
* NOTE: this function reads one frame at a time.
*/
int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
{
int nchar;
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@ -560,7 +561,7 @@ int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
return (rcvd);
}
void tx_dma_stop(pc300_t * card, int ch)
static void tx_dma_stop(pc300_t * card, int ch)
{
void __iomem *scabase = card->hw.scabase;
ucchar drr_ena_bit = 1 << (5 + 2 * ch);
@ -571,7 +572,7 @@ void tx_dma_stop(pc300_t * card, int ch)
cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
}
void rx_dma_stop(pc300_t * card, int ch)
static void rx_dma_stop(pc300_t * card, int ch)
{
void __iomem *scabase = card->hw.scabase;
ucchar drr_ena_bit = 1 << (4 + 2 * ch);
@ -582,7 +583,7 @@ void rx_dma_stop(pc300_t * card, int ch)
cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
}
void rx_dma_start(pc300_t * card, int ch)
static void rx_dma_start(pc300_t * card, int ch)
{
void __iomem *scabase = card->hw.scabase;
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@ -607,7 +608,7 @@ void rx_dma_start(pc300_t * card, int ch)
/*************************/
/*** FALC Routines ***/
/*************************/
void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
static void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
{
void __iomem *falcbase = card->hw.falcbase;
unsigned long i = 0;
@ -622,7 +623,7 @@ void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
cpc_writeb(falcbase + F_REG(CMDR, ch), cmd);
}
void falc_intr_enable(pc300_t * card, int ch)
static void falc_intr_enable(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -672,7 +673,7 @@ void falc_intr_enable(pc300_t * card, int ch)
}
}
void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
{
void __iomem *falcbase = card->hw.falcbase;
ucchar tshf = card->chan[ch].falc.offset;
@ -688,7 +689,7 @@ void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
(0x80 >> (timeslot & 0x07)));
}
void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
static void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
{
void __iomem *falcbase = card->hw.falcbase;
ucchar tshf = card->chan[ch].falc.offset;
@ -704,7 +705,7 @@ void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
~(0x80 >> (timeslot & 0x07)));
}
void falc_close_all_timeslots(pc300_t * card, int ch)
static void falc_close_all_timeslots(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -726,7 +727,7 @@ void falc_close_all_timeslots(pc300_t * card, int ch)
}
}
void falc_open_all_timeslots(pc300_t * card, int ch)
static void falc_open_all_timeslots(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -758,7 +759,7 @@ void falc_open_all_timeslots(pc300_t * card, int ch)
}
}
void falc_init_timeslot(pc300_t * card, int ch)
static void falc_init_timeslot(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -776,7 +777,7 @@ void falc_init_timeslot(pc300_t * card, int ch)
}
}
void falc_enable_comm(pc300_t * card, int ch)
static void falc_enable_comm(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@ -792,7 +793,7 @@ void falc_enable_comm(pc300_t * card, int ch)
~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
}
void falc_disable_comm(pc300_t * card, int ch)
static void falc_disable_comm(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@ -806,7 +807,7 @@ void falc_disable_comm(pc300_t * card, int ch)
((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
}
void falc_init_t1(pc300_t * card, int ch)
static void falc_init_t1(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -975,7 +976,7 @@ void falc_init_t1(pc300_t * card, int ch)
falc_close_all_timeslots(card, ch);
}
void falc_init_e1(pc300_t * card, int ch)
static void falc_init_e1(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1155,7 +1156,7 @@ void falc_init_e1(pc300_t * card, int ch)
falc_close_all_timeslots(card, ch);
}
void falc_init_hdlc(pc300_t * card, int ch)
static void falc_init_hdlc(pc300_t * card, int ch)
{
void __iomem *falcbase = card->hw.falcbase;
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@ -1181,7 +1182,7 @@ void falc_init_hdlc(pc300_t * card, int ch)
falc_intr_enable(card, ch);
}
void te_config(pc300_t * card, int ch)
static void te_config(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1241,7 +1242,7 @@ void te_config(pc300_t * card, int ch)
CPC_UNLOCK(card, flags);
}
void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
static void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1397,7 +1398,7 @@ void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
}
}
void falc_update_stats(pc300_t * card, int ch)
static void falc_update_stats(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1450,7 +1451,7 @@ void falc_update_stats(pc300_t * card, int ch)
* the synchronizer and then sent to the system interface.
*----------------------------------------------------------------------------
*/
void falc_remote_loop(pc300_t * card, int ch, int loop_on)
static void falc_remote_loop(pc300_t * card, int ch, int loop_on)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1495,7 +1496,7 @@ void falc_remote_loop(pc300_t * card, int ch, int loop_on)
* coding must be identical.
*----------------------------------------------------------------------------
*/
void falc_local_loop(pc300_t * card, int ch, int loop_on)
static void falc_local_loop(pc300_t * card, int ch, int loop_on)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@ -1522,7 +1523,7 @@ void falc_local_loop(pc300_t * card, int ch, int loop_on)
* looped. They are originated by the FALC-LH transmitter.
*----------------------------------------------------------------------------
*/
void falc_payload_loop(pc300_t * card, int ch, int loop_on)
static void falc_payload_loop(pc300_t * card, int ch, int loop_on)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1576,7 +1577,7 @@ void falc_payload_loop(pc300_t * card, int ch, int loop_on)
* Description: Turns XLU bit off in the proper register
*----------------------------------------------------------------------------
*/
void turn_off_xlu(pc300_t * card, int ch)
static void turn_off_xlu(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1597,7 +1598,7 @@ void turn_off_xlu(pc300_t * card, int ch)
* Description: Turns XLD bit off in the proper register
*----------------------------------------------------------------------------
*/
void turn_off_xld(pc300_t * card, int ch)
static void turn_off_xld(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1619,7 +1620,7 @@ void turn_off_xld(pc300_t * card, int ch)
* to generate a LOOP activation code over a T1/E1 line.
*----------------------------------------------------------------------------
*/
void falc_generate_loop_up_code(pc300_t * card, int ch)
static void falc_generate_loop_up_code(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1652,7 +1653,7 @@ void falc_generate_loop_up_code(pc300_t * card, int ch)
* to generate a LOOP deactivation code over a T1/E1 line.
*----------------------------------------------------------------------------
*/
void falc_generate_loop_down_code(pc300_t * card, int ch)
static void falc_generate_loop_down_code(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1682,7 +1683,7 @@ void falc_generate_loop_down_code(pc300_t * card, int ch)
* it on the reception side.
*----------------------------------------------------------------------------
*/
void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -1729,7 +1730,7 @@ void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
* Description: This routine returns the bit error counter value
*----------------------------------------------------------------------------
*/
ucshort falc_pattern_test_error(pc300_t * card, int ch)
static ucshort falc_pattern_test_error(pc300_t * card, int ch)
{
pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@ -1769,7 +1770,7 @@ cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx)
netif_rx(skb);
}
void cpc_tx_timeout(struct net_device *dev)
static void cpc_tx_timeout(struct net_device *dev)
{
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
@ -1797,7 +1798,7 @@ void cpc_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
{
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
@ -1880,7 +1881,7 @@ int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
void cpc_net_rx(struct net_device *dev)
static void cpc_net_rx(struct net_device *dev)
{
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
@ -2403,7 +2404,7 @@ static irqreturn_t cpc_intr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
void cpc_sca_status(pc300_t * card, int ch)
static void cpc_sca_status(pc300_t * card, int ch)
{
ucchar ilar;
void __iomem *scabase = card->hw.scabase;
@ -2495,7 +2496,7 @@ void cpc_sca_status(pc300_t * card, int ch)
}
}
void cpc_falc_status(pc300_t * card, int ch)
static void cpc_falc_status(pc300_t * card, int ch)
{
pc300ch_t *chan = &card->chan[ch];
falc_t *pfalc = (falc_t *) & chan->falc;
@ -2523,7 +2524,7 @@ void cpc_falc_status(pc300_t * card, int ch)
CPC_UNLOCK(card, flags);
}
int cpc_change_mtu(struct net_device *dev, int new_mtu)
static int cpc_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU))
return -EINVAL;
@ -2531,7 +2532,7 @@ int cpc_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
pc300dev_t *d = (pc300dev_t *) dev->priv;
@ -2856,7 +2857,7 @@ static int clock_rate_calc(uclong rate, uclong clock, int *br_io)
}
}
int ch_config(pc300dev_t * d)
static int ch_config(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@ -3004,7 +3005,7 @@ int ch_config(pc300dev_t * d)
return 0;
}
int rx_config(pc300dev_t * d)
static int rx_config(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@ -3035,7 +3036,7 @@ int rx_config(pc300dev_t * d)
return 0;
}
int tx_config(pc300dev_t * d)
static int tx_config(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@ -3098,7 +3099,7 @@ static int cpc_attach(struct net_device *dev, unsigned short encoding,
return 0;
}
void cpc_opench(pc300dev_t * d)
static void cpc_opench(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@ -3116,7 +3117,7 @@ void cpc_opench(pc300dev_t * d)
cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
}
void cpc_closech(pc300dev_t * d)
static void cpc_closech(pc300dev_t * d)
{
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
@ -3173,7 +3174,7 @@ int cpc_open(struct net_device *dev)
return 0;
}
int cpc_close(struct net_device *dev)
static int cpc_close(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
pc300dev_t *d = (pc300dev_t *) dev->priv;

View File

@ -112,10 +112,10 @@ typedef struct _st_cpc_tty_area {
static struct tty_driver serial_drv;
/* local variables */
st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS];
static st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS];
int cpc_tty_cnt=0; /* number of intrfaces configured with MLPPP */
int cpc_tty_unreg_flag = 0;
static int cpc_tty_cnt = 0; /* number of intrfaces configured with MLPPP */
static int cpc_tty_unreg_flag = 0;
/* TTY functions prototype */
static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
@ -132,9 +132,9 @@ static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);
int pc300_tiocmset(struct tty_struct *, struct file *,
unsigned int, unsigned int);
int pc300_tiocmget(struct tty_struct *, struct file *);
static int pc300_tiocmset(struct tty_struct *, struct file *,
unsigned int, unsigned int);
static int pc300_tiocmget(struct tty_struct *, struct file *);
/* functions called by PC300 driver */
void cpc_tty_init(pc300dev_t *dev);
@ -538,8 +538,8 @@ static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
return(0);
}
int pc300_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
st_cpc_tty_area *cpc_tty;
@ -565,7 +565,7 @@ int pc300_tiocmset(struct tty_struct *tty, struct file *file,
return 0;
}
int pc300_tiocmget(struct tty_struct *tty, struct file *file)
static int pc300_tiocmget(struct tty_struct *tty, struct file *file)
{
unsigned int result;
unsigned char status;

View File

@ -182,7 +182,7 @@ static char sdla_byte(struct net_device *dev, int addr)
return(byte);
}
void sdla_stop(struct net_device *dev)
static void sdla_stop(struct net_device *dev)
{
struct frad_local *flp;
@ -209,7 +209,7 @@ void sdla_stop(struct net_device *dev)
}
}
void sdla_start(struct net_device *dev)
static void sdla_start(struct net_device *dev)
{
struct frad_local *flp;
@ -247,7 +247,7 @@ void sdla_start(struct net_device *dev)
*
***************************************************/
int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
{
unsigned long start, done, now;
char resp, *temp;
@ -505,7 +505,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
static int sdla_reconfig(struct net_device *dev);
int sdla_activate(struct net_device *slave, struct net_device *master)
static int sdla_activate(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@ -527,7 +527,7 @@ int sdla_activate(struct net_device *slave, struct net_device *master)
return(0);
}
int sdla_deactivate(struct net_device *slave, struct net_device *master)
static int sdla_deactivate(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@ -549,7 +549,7 @@ int sdla_deactivate(struct net_device *slave, struct net_device *master)
return(0);
}
int sdla_assoc(struct net_device *slave, struct net_device *master)
static int sdla_assoc(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@ -585,7 +585,7 @@ int sdla_assoc(struct net_device *slave, struct net_device *master)
return(0);
}
int sdla_deassoc(struct net_device *slave, struct net_device *master)
static int sdla_deassoc(struct net_device *slave, struct net_device *master)
{
struct frad_local *flp;
int i;
@ -613,7 +613,7 @@ int sdla_deassoc(struct net_device *slave, struct net_device *master)
return(0);
}
int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
{
struct frad_local *flp;
struct dlci_local *dlp;
@ -1324,7 +1324,7 @@ NOTE: This is rather a useless action right now, as the
return(0);
}
int sdla_change_mtu(struct net_device *dev, int new_mtu)
static int sdla_change_mtu(struct net_device *dev, int new_mtu)
{
struct frad_local *flp;
@ -1337,7 +1337,7 @@ int sdla_change_mtu(struct net_device *dev, int new_mtu)
return(-EOPNOTSUPP);
}
int sdla_set_config(struct net_device *dev, struct ifmap *map)
static int sdla_set_config(struct net_device *dev, struct ifmap *map)
{
struct frad_local *flp;
int i;

View File

@ -822,7 +822,7 @@ static int new_if(struct wan_device* wandev, struct net_device* dev,
chan->card = card;
/* verify media address */
if (is_digit(conf->addr[0])) {
if (isdigit(conf->addr[0])) {
dlci = dec_to_uint(conf->addr, 0);
@ -3456,7 +3456,7 @@ static unsigned int dec_to_uint (unsigned char* str, int len)
if (!len)
len = strlen(str);
for (val = 0; len && is_digit(*str); ++str, --len)
for (val = 0; len && isdigit(*str); ++str, --len)
val = (val * 10) + (*str - (unsigned)'0');
return val;

View File

@ -957,7 +957,7 @@ static int new_if(struct wan_device* wandev, struct net_device* dev,
chan->hold_timeout = (conf->hold_timeout) ?
conf->hold_timeout : 10;
}else if (is_digit(conf->addr[0])){ /* PVC */
}else if (isdigit(conf->addr[0])){ /* PVC */
int lcn = dec_to_uint(conf->addr, 0);
if ((lcn >= card->u.x.lo_pvc) && (lcn <= card->u.x.hi_pvc)){
@ -3875,7 +3875,7 @@ static unsigned int dec_to_uint (unsigned char* str, int len)
if (!len)
len = strlen(str);
for (val = 0; len && is_digit(*str); ++str, --len)
for (val = 0; len && isdigit(*str); ++str, --len)
val = (val * 10) + (*str - (unsigned)'0');
return val;
@ -3896,9 +3896,9 @@ static unsigned int hex_to_uint (unsigned char* str, int len)
for (val = 0; len; ++str, --len)
{
ch = *str;
if (is_digit(ch))
if (isdigit(ch))
val = (val << 4) + (ch - (unsigned)'0');
else if (is_hex_digit(ch))
else if (isxdigit(ch))
val = (val << 4) + ((ch & 0xDF) - (unsigned)'A' + 10);
else break;
}

View File

@ -642,9 +642,7 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
* Enable interrupt generation.
*/
EXPORT_SYMBOL(sdla_inten);
int sdla_inten (sdlahw_t* hw)
static int sdla_inten (sdlahw_t* hw)
{
unsigned port = hw->port;
int tmp, i;
@ -698,8 +696,7 @@ int sdla_inten (sdlahw_t* hw)
* Disable interrupt generation.
*/
EXPORT_SYMBOL(sdla_intde);
#if 0
int sdla_intde (sdlahw_t* hw)
{
unsigned port = hw->port;
@ -748,14 +745,13 @@ int sdla_intde (sdlahw_t* hw)
}
return 0;
}
#endif /* 0 */
/*============================================================================
* Acknowledge SDLA hardware interrupt.
*/
EXPORT_SYMBOL(sdla_intack);
int sdla_intack (sdlahw_t* hw)
static int sdla_intack (sdlahw_t* hw)
{
unsigned port = hw->port;
int tmp;
@ -827,8 +823,7 @@ void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
* Generate an interrupt to adapter's CPU.
*/
EXPORT_SYMBOL(sdla_intr);
#if 0
int sdla_intr (sdlahw_t* hw)
{
unsigned port = hw->port;
@ -863,6 +858,7 @@ int sdla_intr (sdlahw_t* hw)
}
return 0;
}
#endif /* 0 */
/*============================================================================
* Execute Adapter Command.

View File

@ -221,7 +221,7 @@ static void sppp_clear_timeout(struct sppp *p)
* here.
*/
void sppp_input (struct net_device *dev, struct sk_buff *skb)
static void sppp_input (struct net_device *dev, struct sk_buff *skb)
{
struct ppp_header *h;
struct sppp *sp = (struct sppp *)sppp_of(dev);
@ -355,8 +355,6 @@ void sppp_input (struct net_device *dev, struct sk_buff *skb)
return;
}
EXPORT_SYMBOL(sppp_input);
/*
* Handle transmit packets.
*/
@ -990,7 +988,7 @@ EXPORT_SYMBOL(sppp_reopen);
* the mtu is out of range.
*/
int sppp_change_mtu(struct net_device *dev, int new_mtu)
static int sppp_change_mtu(struct net_device *dev, int new_mtu)
{
if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP))
return -EINVAL;
@ -998,8 +996,6 @@ int sppp_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
EXPORT_SYMBOL(sppp_change_mtu);
/**
* sppp_do_ioctl - Ioctl handler for ppp/hdlc
* @dev: Device subject to ioctl
@ -1456,7 +1452,7 @@ static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_t
return 0;
}
struct packet_type sppp_packet_type = {
static struct packet_type sppp_packet_type = {
.type = __constant_htons(ETH_P_WAN_PPP),
.func = sppp_rcv,
};

View File

@ -1046,7 +1046,6 @@ static WifiCtlHdr wifictlhdr8023 = {
}
};
#ifdef WIRELESS_EXT
// Frequency list (map channels to frequencies)
static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484 };
@ -1067,7 +1066,6 @@ typedef struct wep_key_t {
/* List of Wireless Handlers (new API) */
static const struct iw_handler_def airo_handler_def;
#endif /* WIRELESS_EXT */
static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
@ -1110,10 +1108,8 @@ static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
static int airo_thread(void *data);
static void timer_func( struct net_device *dev );
static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
#ifdef WIRELESS_EXT
static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
static void airo_read_wireless_stats (struct airo_info *local);
#endif /* WIRELESS_EXT */
#ifdef CISCO_EXT
static int readrids(struct net_device *dev, aironet_ioctl *comp);
static int writerids(struct net_device *dev, aironet_ioctl *comp);
@ -1187,12 +1183,10 @@ struct airo_info {
int fid;
} xmit, xmit11;
struct net_device *wifidev;
#ifdef WIRELESS_EXT
struct iw_statistics wstats; // wireless stats
unsigned long scan_timestamp; /* Time started to scan */
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
#endif /* WIRELESS_EXT */
#ifdef MICSUPPORT
/* MIC stuff */
struct crypto_tfm *tfm;
@ -2527,7 +2521,8 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
unsigned long mem_start, mem_len, aux_start, aux_len;
int rc = -1;
int i;
unsigned char *busaddroff,*vpackoff;
dma_addr_t busaddroff;
unsigned char *vpackoff;
unsigned char __iomem *pciaddroff;
mem_start = pci_resource_start(pci, 1);
@ -2570,7 +2565,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
/*
* Setup descriptor RX, TX, CONFIG
*/
busaddroff = (unsigned char *)ai->shared_dma;
busaddroff = ai->shared_dma;
pciaddroff = ai->pciaux + AUX_OFFSET;
vpackoff = ai->shared;
@ -2579,7 +2574,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
ai->rxfids[i].pending = 0;
ai->rxfids[i].card_ram_off = pciaddroff;
ai->rxfids[i].virtual_host_addr = vpackoff;
ai->rxfids[i].rx_desc.host_addr = (dma_addr_t) busaddroff;
ai->rxfids[i].rx_desc.host_addr = busaddroff;
ai->rxfids[i].rx_desc.valid = 1;
ai->rxfids[i].rx_desc.len = PKTSIZE;
ai->rxfids[i].rx_desc.rdy = 0;
@ -2594,7 +2589,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
ai->txfids[i].card_ram_off = pciaddroff;
ai->txfids[i].virtual_host_addr = vpackoff;
ai->txfids[i].tx_desc.valid = 1;
ai->txfids[i].tx_desc.host_addr = (dma_addr_t) busaddroff;
ai->txfids[i].tx_desc.host_addr = busaddroff;
memcpy(ai->txfids[i].virtual_host_addr,
&wifictlhdr8023, sizeof(wifictlhdr8023));
@ -2607,8 +2602,8 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
/* Rid descriptor setup */
ai->config_desc.card_ram_off = pciaddroff;
ai->config_desc.virtual_host_addr = vpackoff;
ai->config_desc.rid_desc.host_addr = (dma_addr_t) busaddroff;
ai->ridbus = (dma_addr_t)busaddroff;
ai->config_desc.rid_desc.host_addr = busaddroff;
ai->ridbus = busaddroff;
ai->config_desc.rid_desc.rid = 0;
ai->config_desc.rid_desc.len = RIDSIZE;
ai->config_desc.rid_desc.valid = 1;
@ -2647,9 +2642,7 @@ static void wifi_setup(struct net_device *dev)
dev->get_stats = &airo_get_stats;
dev->set_mac_address = &airo_set_mac_address;
dev->do_ioctl = &airo_ioctl;
#ifdef WIRELESS_EXT
dev->wireless_handlers = &airo_handler_def;
#endif /* WIRELESS_EXT */
dev->change_mtu = &airo_change_mtu;
dev->open = &airo_open;
dev->stop = &airo_close;
@ -2675,9 +2668,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
dev->priv = ethdev->priv;
dev->irq = ethdev->irq;
dev->base_addr = ethdev->base_addr;
#ifdef WIRELESS_EXT
dev->wireless_data = ethdev->wireless_data;
#endif /* WIRELESS_EXT */
memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
err = register_netdev(dev);
if (err<0) {
@ -2755,11 +2746,9 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
dev->set_multicast_list = &airo_set_multicast_list;
dev->set_mac_address = &airo_set_mac_address;
dev->do_ioctl = &airo_ioctl;
#ifdef WIRELESS_EXT
dev->wireless_handlers = &airo_handler_def;
ai->wireless_data.spy_data = &ai->spy_data;
dev->wireless_data = &ai->wireless_data;
#endif /* WIRELESS_EXT */
dev->change_mtu = &airo_change_mtu;
dev->open = &airo_open;
dev->stop = &airo_close;
@ -5515,12 +5504,13 @@ static int airo_pci_resume(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct airo_info *ai = dev->priv;
Resp rsp;
pci_power_t prev_state = pdev->current_state;
pci_set_power_state(pdev, 0);
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, ai->power), 0);
pci_enable_wake(pdev, PCI_D0, 0);
if (ai->power.event > 1) {
if (prev_state != PCI_D1) {
reset_card(dev, 0);
mpi_init_descriptors(ai);
setup_card(ai, dev->dev_addr, 0);
@ -5598,7 +5588,6 @@ static void __exit airo_cleanup_module( void )
remove_proc_entry("aironet", proc_root_driver);
}
#ifdef WIRELESS_EXT
/*
* Initial Wireless Extension code for Aironet driver by :
* Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
@ -7107,8 +7096,6 @@ static const struct iw_handler_def airo_handler_def =
.get_wireless_stats = airo_get_wireless_stats,
};
#endif /* WIRELESS_EXT */
/*
* This defines the configuration part of the Wireless Extensions
* Note : irq and spinlock protection will occur in the subroutines
@ -7187,7 +7174,6 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return rc;
}
#ifdef WIRELESS_EXT
/*
* Get the Wireless stats out of the driver
* Note : irq and spinlock protection will occur in the subroutines
@ -7260,7 +7246,6 @@ static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
return &local->wstats;
}
#endif /* WIRELESS_EXT */
#ifdef CISCO_EXT
/*

View File

@ -15,28 +15,11 @@
#define PFX DRIVER_NAME ": "
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/current.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <linux/delay.h>
#include <asm/pmac_feature.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include "orinoco.h"

View File

@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_private *priv);
static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
static void atmel_command_irq(struct atmel_private *priv);
static int atmel_validate_channel(struct atmel_private *priv, int channel);
static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 frame_len, u8 rssi);
static void atmel_management_timer(u_long a);
static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u8 *body, int body_len);
static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
@ -827,7 +827,7 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
static int start_tx (struct sk_buff *skb, struct net_device *dev)
{
struct atmel_private *priv = netdev_priv(dev);
struct ieee80211_hdr header;
struct ieee80211_hdr_4addr header;
unsigned long flags;
u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
}
static void atmel_transmit_management_frame(struct atmel_private *priv,
struct ieee80211_hdr *header,
struct ieee80211_hdr_4addr *header,
u8 *body, int body_len)
{
u16 buff;
@ -917,7 +917,7 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
}
static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 msdu_size, u16 rx_packet_loc, u32 crc)
{
/* fast path: unfragmented packet copy directly into skbuf */
@ -990,7 +990,7 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
return (crc ^ 0xffffffff) == netcrc;
}
static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
{
u8 mac4[6];
@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *heade
static void rx_done_irq(struct atmel_private *priv)
{
int i;
struct ieee80211_hdr header;
struct ieee80211_hdr_4addr header;
for (i = 0;
atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
@ -2650,7 +2650,7 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
{
struct ieee80211_hdr header;
struct ieee80211_hdr_4addr header;
struct auth_body auth;
header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
@ -2688,7 +2688,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
{
u8 *ssid_el_p;
int bodysize;
struct ieee80211_hdr header;
struct ieee80211_hdr_4addr header;
struct ass_req_format {
u16 capability;
u16 listen_interval;
@ -2738,7 +2738,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
}
static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr *header)
static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr_4addr *header)
{
if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
@ -2788,7 +2788,7 @@ static int retrieve_bss(struct atmel_private *priv)
}
static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr *header,
static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 capability, u16 beacon_period, u8 channel, u8 rssi,
u8 ssid_len, u8 *ssid, int is_beacon)
{
@ -3072,7 +3072,7 @@ static void atmel_smooth_qual(struct atmel_private *priv)
}
/* deals with incoming managment frames. */
static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
u16 frame_len, u8 rssi)
{
u16 subtype;

View File

@ -39,17 +39,10 @@
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/threads.h>
#include <linux/smp.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/net.h>
#include <asm/errno.h>
#include <linux/init.h>
#include <linux/delay.h>
#include "hermes.h"

View File

@ -30,9 +30,8 @@
* access to the hermes_t structure, and to the hardware
*/
#include <linux/delay.h>
#include <linux/if_ether.h>
#include <asm/byteorder.h>
#include <asm/io.h>
/*
* Limits and constants
@ -192,13 +191,13 @@
#define HERMES_RXSTAT_WMP (0x6000) /* Wavelan-II Management Protocol frame */
struct hermes_tx_descriptor {
u16 status;
u16 reserved1;
u16 reserved2;
u32 sw_support;
__le16 status;
__le16 reserved1;
__le16 reserved2;
__le32 sw_support;
u8 retry_count;
u8 tx_rate;
u16 tx_control;
__le16 tx_control;
} __attribute__ ((packed));
#define HERMES_TXSTAT_RETRYERR (0x0001)
@ -222,60 +221,60 @@ struct hermes_tx_descriptor {
#define HERMES_INQ_SEC_STAT_AGERE (0xF202)
struct hermes_tallies_frame {
u16 TxUnicastFrames;
u16 TxMulticastFrames;
u16 TxFragments;
u16 TxUnicastOctets;
u16 TxMulticastOctets;
u16 TxDeferredTransmissions;
u16 TxSingleRetryFrames;
u16 TxMultipleRetryFrames;
u16 TxRetryLimitExceeded;
u16 TxDiscards;
u16 RxUnicastFrames;
u16 RxMulticastFrames;
u16 RxFragments;
u16 RxUnicastOctets;
u16 RxMulticastOctets;
u16 RxFCSErrors;
u16 RxDiscards_NoBuffer;
u16 TxDiscardsWrongSA;
u16 RxWEPUndecryptable;
u16 RxMsgInMsgFragments;
u16 RxMsgInBadMsgFragments;
__le16 TxUnicastFrames;
__le16 TxMulticastFrames;
__le16 TxFragments;
__le16 TxUnicastOctets;
__le16 TxMulticastOctets;
__le16 TxDeferredTransmissions;
__le16 TxSingleRetryFrames;
__le16 TxMultipleRetryFrames;
__le16 TxRetryLimitExceeded;
__le16 TxDiscards;
__le16 RxUnicastFrames;
__le16 RxMulticastFrames;
__le16 RxFragments;
__le16 RxUnicastOctets;
__le16 RxMulticastOctets;
__le16 RxFCSErrors;
__le16 RxDiscards_NoBuffer;
__le16 TxDiscardsWrongSA;
__le16 RxWEPUndecryptable;
__le16 RxMsgInMsgFragments;
__le16 RxMsgInBadMsgFragments;
/* Those last are probably not available in very old firmwares */
u16 RxDiscards_WEPICVError;
u16 RxDiscards_WEPExcluded;
__le16 RxDiscards_WEPICVError;
__le16 RxDiscards_WEPExcluded;
} __attribute__ ((packed));
/* Grabbed from wlan-ng - Thanks Mark... - Jean II
* This is the result of a scan inquiry command */
/* Structure describing info about an Access Point */
struct prism2_scan_apinfo {
u16 channel; /* Channel where the AP sits */
u16 noise; /* Noise level */
u16 level; /* Signal level */
__le16 channel; /* Channel where the AP sits */
__le16 noise; /* Noise level */
__le16 level; /* Signal level */
u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
u16 beacon_interv; /* Beacon interval */
u16 capabilities; /* Capabilities */
u16 essid_len; /* ESSID length */
__le16 beacon_interv; /* Beacon interval */
__le16 capabilities; /* Capabilities */
__le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
u8 rates[10]; /* Bit rate supported */
u16 proberesp_rate; /* Data rate of the response frame */
u16 atim; /* ATIM window time, Kus (hostscan only) */
__le16 proberesp_rate; /* Data rate of the response frame */
__le16 atim; /* ATIM window time, Kus (hostscan only) */
} __attribute__ ((packed));
/* Same stuff for the Lucent/Agere card.
* Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
struct agere_scan_apinfo {
u16 channel; /* Channel where the AP sits */
u16 noise; /* Noise level */
u16 level; /* Signal level */
__le16 channel; /* Channel where the AP sits */
__le16 noise; /* Noise level */
__le16 level; /* Signal level */
u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
u16 beacon_interv; /* Beacon interval */
u16 capabilities; /* Capabilities */
__le16 beacon_interv; /* Beacon interval */
__le16 capabilities; /* Capabilities */
/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
u16 essid_len; /* ESSID length */
__le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
} __attribute__ ((packed));
@ -283,16 +282,16 @@ struct agere_scan_apinfo {
struct symbol_scan_apinfo {
u8 channel; /* Channel where the AP sits */
u8 unknown1; /* 8 in 2.9x and 3.9x f/w, 0 otherwise */
u16 noise; /* Noise level */
u16 level; /* Signal level */
__le16 noise; /* Noise level */
__le16 level; /* Signal level */
u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
u16 beacon_interv; /* Beacon interval */
u16 capabilities; /* Capabilities */
__le16 beacon_interv; /* Beacon interval */
__le16 capabilities; /* Capabilities */
/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
u16 essid_len; /* ESSID length */
__le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
u16 rates[5]; /* Bit rate supported */
u16 basic_rates; /* Basic rates bitmask */
__le16 rates[5]; /* Bit rate supported */
__le16 basic_rates; /* Basic rates bitmask */
u8 unknown2[6]; /* Always FF:FF:FF:FF:00:00 */
u8 unknown3[8]; /* Always 0, appeared in f/w 3.91-68 */
} __attribute__ ((packed));
@ -312,7 +311,7 @@ union hermes_scan_info {
#define HERMES_LINKSTATUS_ASSOC_FAILED (0x0006)
struct hermes_linkstatus {
u16 linkstatus; /* Link status */
__le16 linkstatus; /* Link status */
} __attribute__ ((packed));
struct hermes_response {
@ -321,8 +320,8 @@ struct hermes_response {
/* "ID" structure - used for ESSID and station nickname */
struct hermes_idstring {
u16 len;
u16 val[16];
__le16 len;
__le16 val[16];
} __attribute__ ((packed));
struct hermes_multicast {
@ -447,7 +446,7 @@ static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count
static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
{
u16 rec;
__le16 rec;
int err;
err = HERMES_READ_RECORD(hw, bap, rid, &rec);
@ -457,7 +456,7 @@ static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
{
u16 rec = cpu_to_le16(word);
__le16 rec = cpu_to_le16(word);
return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
}

View File

@ -716,9 +716,6 @@ static int prism2_close(struct net_device *dev)
hostap_deauth_all_stas(dev, local->ap, 1);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
if (local->func->dev_close && local->func->dev_close(local))
return 0;
if (dev == local->dev) {
local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL);
}
@ -766,9 +763,6 @@ static int prism2_open(struct net_device *dev)
local->hw_downloading)
return -ENODEV;
if (local->func->dev_open && local->func->dev_open(local))
return 1;
if (!try_module_get(local->hw_module))
return -ENODEV;
local->num_dev_open++;

View File

@ -6,10 +6,10 @@
void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
u16 fc;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
"jiffies=%ld\n",
@ -51,7 +51,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
int hdrlen, phdrlen, head_need, tail_need;
u16 fc;
int prism_header, ret;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@ -70,7 +70,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
phdrlen = 0;
}
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
@ -215,7 +215,7 @@ prism2_frag_cache_find(local_info_t *local, unsigned int seq,
/* Called only as a tasklet (software IRQ) */
static struct sk_buff *
prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
{
struct sk_buff *skb = NULL;
u16 sc;
@ -229,7 +229,7 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
if (frag == 0) {
/* Reserve enough space to fit maximum frame length */
skb = dev_alloc_skb(local->dev->mtu +
sizeof(struct ieee80211_hdr) +
sizeof(struct ieee80211_hdr_4addr) +
8 /* LLC */ +
2 /* alignment */ +
8 /* WEP */ + ETH_ALEN /* WDS */);
@ -267,7 +267,7 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
/* Called only as a tasklet (software IRQ) */
static int prism2_frag_cache_invalidate(local_info_t *local,
struct ieee80211_hdr *hdr)
struct ieee80211_hdr_4addr *hdr)
{
u16 sc;
unsigned int seq;
@ -441,7 +441,7 @@ hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
u16 stype)
{
if (local->iw_mode == IW_MODE_MASTER) {
hostap_update_sta_ps(local, (struct ieee80211_hdr *)
hostap_update_sta_ps(local, (struct ieee80211_hdr_4addr *)
skb->data);
}
@ -520,7 +520,7 @@ static inline struct net_device *prism2_rx_get_wds(local_info_t *local,
static inline int
hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr,
hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
u16 fc, struct net_device **wds)
{
/* FIX: is this really supposed to accept WDS frames only in Master
@ -579,13 +579,13 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
{
struct net_device *dev = local->dev;
u16 fc, ethertype;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
u8 *pos;
if (skb->len < 24)
return 0;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
/* check that the frame is unicast frame to us */
@ -619,13 +619,13 @@ static inline int
hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt)
{
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
return 0;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
if (local->tkip_countermeasures &&
@ -658,13 +658,13 @@ static inline int
hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
int keyidx, struct ieee80211_crypt_data *crypt)
{
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
return 0;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
atomic_inc(&crypt->refcnt);
@ -689,7 +689,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
size_t hdrlen;
u16 fc, type, stype, sc;
struct net_device *wds = NULL;
@ -716,7 +716,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
dev = local->ddev;
iface = netdev_priv(dev);
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
stats = hostap_get_stats(dev);
if (skb->len < 10)
@ -737,7 +737,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
struct iw_quality wstats;
wstats.level = rx_stats->signal;
wstats.noise = rx_stats->noise;
wstats.updated = 6; /* No qual value */
wstats.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED
| IW_QUAL_QUAL_INVALID | IW_QUAL_DBM;
/* Update spy records */
wireless_spy_update(dev, hdr->addr2, &wstats);
}
@ -889,7 +890,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
(keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
goto rx_dropped;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
/* skb: hdr + (possibly fragmented) plaintext payload */
@ -941,7 +942,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
/* this was the last fragment and the frame will be
* delivered, so remove skb from fragment cache */
skb = frag_skb;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
prism2_frag_cache_invalidate(local, hdr);
}
@ -952,7 +953,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
goto rx_dropped;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
if (local->ieee_802_1x &&
hostap_is_eapol_frame(local, skb)) {

View File

@ -1,9 +1,9 @@
void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
u16 fc;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
name, skb->len, jiffies);
@ -41,7 +41,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
int need_headroom, need_tailroom = 0;
struct ieee80211_hdr hdr;
struct ieee80211_hdr_4addr hdr;
u16 fc, ethertype = 0;
enum {
WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
@ -244,7 +244,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
struct hostap_skb_tx_data *meta;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
u16 fc;
iface = netdev_priv(dev);
@ -266,7 +266,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
meta->iface = iface;
if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
@ -289,7 +289,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
u16 fc;
int hdr_len, res;
@ -303,7 +303,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
if (local->tkip_countermeasures &&
crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
"TX packet to " MACSTR "\n",
@ -317,15 +317,15 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
if (skb == NULL)
return NULL;
if ((skb_headroom(skb) < crypt->ops->extra_prefix_len ||
skb_tailroom(skb) < crypt->ops->extra_postfix_len) &&
pskb_expand_head(skb, crypt->ops->extra_prefix_len,
crypt->ops->extra_postfix_len, GFP_ATOMIC)) {
if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
kfree_skb(skb);
return NULL;
}
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
hdr_len = hostap_80211_get_hdrlen(fc);
@ -360,7 +360,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
ap_tx_ret tx_ret;
struct hostap_skb_tx_data *meta;
int no_encrypt = 0;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@ -403,7 +403,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_ret = hostap_handle_sta_tx(local, &tx);
skb = tx.skb;
meta = (struct hostap_skb_tx_data *) skb->cb;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
switch (tx_ret) {
case AP_TX_CONTINUE:

View File

@ -591,14 +591,14 @@ static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
u16 fc;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
if (!ap->local->hostapd || !ap->local->apdev) {
dev_kfree_skb(skb);
return;
}
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
/* Pass the TX callback frame to the hostapd; use 802.11 header version
@ -623,7 +623,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
u16 fc, *pos, auth_alg, auth_transaction, status;
struct sta_info *sta = NULL;
char *txt = NULL;
@ -633,7 +633,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
return;
}
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
@ -692,7 +692,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
u16 fc, *pos, status;
struct sta_info *sta = NULL;
char *txt = NULL;
@ -702,7 +702,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
return;
}
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
(WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
@ -757,12 +757,12 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
struct sta_info *sta;
if (skb->len < 24)
goto fail;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (ok) {
spin_lock(&ap->sta_table_lock);
sta = ap_get_sta(ap, hdr->addr1);
@ -918,7 +918,7 @@ static void prism2_send_mgmt(struct net_device *dev,
{
struct hostap_interface *iface;
local_info_t *local;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
u16 fc;
struct sk_buff *skb;
struct hostap_skb_tx_data *meta;
@ -944,7 +944,7 @@ static void prism2_send_mgmt(struct net_device *dev,
fc = type_subtype;
hdrlen = hostap_80211_get_hdrlen(fc);
hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
if (body)
memcpy(skb_put(skb, body_len), body, body_len);
@ -1256,14 +1256,14 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
}
skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
ap->crypt->extra_prefix_len +
ap->crypt->extra_postfix_len);
ap->crypt->extra_mpdu_prefix_len +
ap->crypt->extra_mpdu_postfix_len);
if (skb == NULL) {
kfree(tmpbuf);
return NULL;
}
skb_reserve(skb, ap->crypt->extra_prefix_len);
skb_reserve(skb, ap->crypt->extra_mpdu_prefix_len);
memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
WLAN_AUTH_CHALLENGE_LEN);
if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
@ -1272,7 +1272,7 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
return NULL;
}
memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
memcpy(tmpbuf, skb->data + ap->crypt->extra_mpdu_prefix_len,
WLAN_AUTH_CHALLENGE_LEN);
dev_kfree_skb(skb);
@ -1285,7 +1285,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
size_t hdrlen;
struct ap_data *ap = local->ap;
char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
@ -1498,7 +1498,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, int reassoc)
{
struct net_device *dev = local->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char body[12], *p, *lpos;
int len, left;
u16 *pos;
@ -1705,7 +1705,7 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
int len;
u16 reason_code, *pos;
@ -1746,7 +1746,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len;
u16 reason_code, *pos;
@ -1784,7 +1784,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_data_nullfunc(local_info_t *local,
struct ieee80211_hdr *hdr)
struct ieee80211_hdr_4addr *hdr)
{
struct net_device *dev = local->dev;
@ -1801,7 +1801,7 @@ static void ap_handle_data_nullfunc(local_info_t *local,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_dropped_data(local_info_t *local,
struct ieee80211_hdr *hdr)
struct ieee80211_hdr_4addr *hdr)
{
struct net_device *dev = local->dev;
struct sta_info *sta;
@ -1860,7 +1860,7 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
/* Called only as a scheduled task for pending AP frames. */
static void handle_pspoll(local_info_t *local,
struct ieee80211_hdr *hdr,
struct ieee80211_hdr_4addr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
@ -1979,7 +1979,7 @@ static void handle_wds_oper_queue(void *data)
static void handle_beacon(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len, left;
u16 *pos, beacon_int, capability;
@ -2137,11 +2137,11 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
struct net_device *dev = local->dev;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
u16 fc, type, stype;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
/* FIX: should give skb->len to handler functions and check that the
* buffer is long enough */
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
type = WLAN_FC_GET_TYPE(fc);
stype = WLAN_FC_GET_STYPE(fc);
@ -2258,7 +2258,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
struct hostap_interface *iface;
local_info_t *local;
u16 fc;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@ -2268,7 +2268,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
local->stats.rx_packets++;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
@ -2289,7 +2289,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
{
struct sk_buff *skb;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
struct hostap_80211_rx_status rx_stats;
if (skb_queue_empty(&sta->tx_buf))
@ -2302,7 +2302,7 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
return;
}
hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
/* Generate a fake pspoll frame to start packet delivery */
hdr->frame_ctl = __constant_cpu_to_le16(
@ -2349,7 +2349,7 @@ static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
qual[count].updated = sta->last_rx_updated;
sta->last_rx_updated = 0;
sta->last_rx_updated = IW_QUAL_DBM;
count++;
if (count >= buf_size)
@ -2467,7 +2467,7 @@ static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
sta->last_rx_updated = 0;
sta->last_rx_updated = IW_QUAL_DBM;
/* To be continued, we should make good use of IWEVCUSTOM */
}
@ -2685,7 +2685,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
struct sta_info *sta = NULL;
struct sk_buff *skb = tx->skb;
int set_tim, ret;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
struct hostap_skb_tx_data *meta;
meta = (struct hostap_skb_tx_data *) skb->cb;
@ -2694,7 +2694,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
meta->iface->type == HOSTAP_INTERFACE_STA)
goto out;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
if (hdr->addr1[0] & 0x01) {
/* broadcast/multicast frame - no AP related processing */
@ -2821,10 +2821,10 @@ void hostap_handle_sta_release(void *ptr)
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
{
struct sta_info *sta;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
struct hostap_skb_tx_data *meta;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
meta = (struct hostap_skb_tx_data *) skb->cb;
spin_lock(&local->ap->sta_table_lock);
@ -2892,7 +2892,7 @@ static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
/* Called only as a tasklet (software IRQ). Called for each RX frame to update
* STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
{
struct sta_info *sta;
u16 fc;
@ -2925,12 +2925,12 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
int ret;
struct sta_info *sta;
u16 fc, type, stype;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_4addr *hdr;
if (local->ap == NULL)
return AP_RX_CONTINUE;
hdr = (struct ieee80211_hdr *) skb->data;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
type = WLAN_FC_GET_TYPE(fc);
@ -3058,7 +3058,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
/* Called only as a tasklet (software IRQ) */
int hostap_handle_sta_crypto(local_info_t *local,
struct ieee80211_hdr *hdr,
struct ieee80211_hdr_4addr *hdr,
struct ieee80211_crypt_data **crypt,
void **sta_ptr)
{
@ -3160,7 +3160,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
/* Called only as a tasklet (software IRQ) */
int hostap_update_rx_stats(struct ap_data *ap,
struct ieee80211_hdr *hdr,
struct ieee80211_hdr_4addr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct sta_info *sta;
@ -3174,7 +3174,7 @@ int hostap_update_rx_stats(struct ap_data *ap,
sta->last_rx_silence = rx_stats->noise;
sta->last_rx_signal = rx_stats->signal;
sta->last_rx_rate = rx_stats->rate;
sta->last_rx_updated = 7;
sta->last_rx_updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
if (rx_stats->rate == 10)
sta->rx_count[0]++;
else if (rx_stats->rate == 20)

View File

@ -233,7 +233,7 @@ struct hostap_tx_data {
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
void hostap_handle_sta_release(void *ptr);
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr);
typedef enum {
AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
} ap_rx_ret;
@ -241,13 +241,13 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats,
int wds);
int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
struct ieee80211_crypt_data **crypt,
void **sta_ptr);
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr_4addr *hdr,
struct hostap_80211_rx_status *rx_stats);
void hostap_update_rates(local_info_t *local);
void hostap_add_wds_links(local_info_t *local);

View File

@ -492,42 +492,10 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
}
static int prism2_pccard_dev_open(local_info_t *local)
{
struct hostap_cs_priv *hw_priv = local->hw_priv;
hw_priv->link->open++;
return 0;
}
static int prism2_pccard_dev_close(local_info_t *local)
{
struct hostap_cs_priv *hw_priv;
if (local == NULL || local->hw_priv == NULL)
return 1;
hw_priv = local->hw_priv;
if (hw_priv->link == NULL)
return 1;
if (!hw_priv->link->open) {
printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
"link not open?!\n", local->dev->name);
return 1;
}
hw_priv->link->open--;
return 0;
}
static struct prism2_helper_functions prism2_pccard_funcs =
{
.card_present = prism2_pccard_card_present,
.cor_sreset = prism2_pccard_cor_sreset,
.dev_open = prism2_pccard_dev_open,
.dev_close = prism2_pccard_dev_close,
.genesis_reset = prism2_pccard_genesis_reset,
.hw_type = HOSTAP_HW_PCCARD,
};
@ -597,13 +565,14 @@ static void prism2_detach(dev_link_t *link)
*linkp = link->next;
/* release net devices */
if (link->priv) {
struct hostap_cs_priv *hw_priv;
struct net_device *dev;
struct hostap_interface *iface;
dev = link->priv;
iface = netdev_priv(dev);
kfree(iface->local->hw_priv);
iface->local->hw_priv = NULL;
hw_priv = iface->local->hw_priv;
prism2_free_local_data(dev);
kfree(hw_priv);
}
kfree(link);
}
@ -883,6 +852,13 @@ static int prism2_event(event_t event, int priority,
{
dev_link_t *link = args->client_data;
struct net_device *dev = (struct net_device *) link->priv;
int dev_open = 0;
if (link->state & DEV_CONFIG) {
struct hostap_interface *iface = netdev_priv(dev);
if (iface && iface->local)
dev_open = iface->local->num_dev_open > 0;
}
switch (event) {
case CS_EVENT_CARD_INSERTION:
@ -911,7 +887,7 @@ static int prism2_event(event_t event, int priority,
case CS_EVENT_RESET_PHYSICAL:
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
if (link->state & DEV_CONFIG) {
if (link->open) {
if (dev_open) {
netif_stop_queue(dev);
netif_device_detach(dev);
}
@ -931,8 +907,8 @@ static int prism2_event(event_t event, int priority,
pcmcia_request_configuration(link->handle,
&link->conf);
prism2_hw_shutdown(dev, 1);
prism2_hw_config(dev, link->open ? 0 : 1);
if (link->open) {
prism2_hw_config(dev, dev_open ? 0 : 1);
if (dev_open) {
netif_device_attach(dev);
netif_start_queue(dev);
}

View File

@ -3322,6 +3322,18 @@ static void prism2_free_local_data(struct net_device *dev)
iface = netdev_priv(dev);
local = iface->local;
/* Unregister all netdevs before freeing local data. */
list_for_each_safe(ptr, n, &local->hostap_interfaces) {
iface = list_entry(ptr, struct hostap_interface, list);
if (iface->type == HOSTAP_INTERFACE_MASTER) {
/* special handling for this interface below */
continue;
}
hostap_remove_interface(iface->dev, 0, 1);
}
unregister_netdev(local->dev);
flush_scheduled_work();
if (timer_pending(&local->crypt_deinit_timer))
@ -3382,15 +3394,6 @@ static void prism2_free_local_data(struct net_device *dev)
prism2_download_free_data(local->dl_sec);
#endif /* PRISM2_DOWNLOAD_SUPPORT */
list_for_each_safe(ptr, n, &local->hostap_interfaces) {
iface = list_entry(ptr, struct hostap_interface, list);
if (iface->type == HOSTAP_INTERFACE_MASTER) {
/* special handling for this interface below */
continue;
}
hostap_remove_interface(iface->dev, 0, 1);
}
prism2_clear_set_tim_queue(local);
list_for_each_safe(ptr, n, &local->bss_list) {
@ -3403,7 +3406,6 @@ static void prism2_free_local_data(struct net_device *dev)
kfree(local->last_scan_results);
kfree(local->generic_elem);
unregister_netdev(local->dev);
free_netdev(local->dev);
}

View File

@ -50,7 +50,8 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
#endif /* in_atomic */
if (update && prism2_update_comms_qual(dev) == 0)
wstats->qual.updated = 7;
wstats->qual.updated = IW_QUAL_ALL_UPDATED |
IW_QUAL_DBM;
wstats->qual.qual = local->comms_qual;
wstats->qual.level = local->avg_signal;
@ -59,7 +60,7 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
wstats->qual.qual = 0;
wstats->qual.level = 0;
wstats->qual.noise = 0;
wstats->qual.updated = 0;
wstats->qual.updated = IW_QUAL_ALL_INVALID;
}
return wstats;
@ -1827,13 +1828,6 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
/* FIX:
* I do not know how this is possible, but iwe_stream_add_event
* seems to re-order memcpy execution so that len is set only
* after copying.. Pre-setting len here "fixes" this, but real
* problems should be solved (after which these iwe.len
* settings could be removed from this function). */
iwe.len = IW_EV_ADDR_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_ADDR_LEN);
@ -1843,7 +1837,6 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = ssid_len;
iwe.u.data.flags = 1;
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
memset(&iwe, 0, sizeof(iwe));
@ -1859,7 +1852,6 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
iwe.len = IW_EV_UINT_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_UINT_LEN);
}
@ -1877,7 +1869,6 @@ static char * __prism2_translate_scan(local_info_t *local,
if (chan > 0) {
iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
iwe.u.freq.e = 1;
iwe.len = IW_EV_FREQ_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_FREQ_LEN);
}
@ -1894,7 +1885,10 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.qual.noise =
HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
}
iwe.len = IW_EV_QUAL_LEN;
iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
| IW_QUAL_NOISE_UPDATED
| IW_QUAL_QUAL_INVALID
| IW_QUAL_DBM;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
IW_EV_QUAL_LEN);
}
@ -1906,7 +1900,6 @@ static char * __prism2_translate_scan(local_info_t *local,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
/* TODO: add SuppRates into BSS table */
@ -1930,7 +1923,7 @@ static char * __prism2_translate_scan(local_info_t *local,
}
/* TODO: add BeaconInt,resp_rate,atim into BSS table */
buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_ATOMIC);
if (buf && scan) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;

View File

@ -59,11 +59,13 @@ static struct pci_device_id prism2_pci_id_table[] __devinitdata = {
static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
{
struct hostap_interface *iface;
struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
iface = netdev_priv(dev);
local = iface->local;
hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
@ -74,12 +76,14 @@ static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
{
struct hostap_interface *iface;
struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
u8 v;
iface = netdev_priv(dev);
local = iface->local;
hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
v = readb(hw_priv->mem_start + a);
@ -91,11 +95,13 @@ static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
{
struct hostap_interface *iface;
struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
iface = netdev_priv(dev);
local = iface->local;
hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
@ -106,12 +112,14 @@ static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
{
struct hostap_interface *iface;
struct hostap_pci_priv *hw_priv;
local_info_t *local;
unsigned long flags;
u16 v;
iface = netdev_priv(dev);
local = iface->local;
hw_priv = local->hw_priv;
spin_lock_irqsave(&local->lock, flags);
v = readw(hw_priv->mem_start + a);
@ -277,8 +285,6 @@ static struct prism2_helper_functions prism2_pci_funcs =
{
.card_present = NULL,
.cor_sreset = prism2_pci_cor_sreset,
.dev_open = NULL,
.dev_close = NULL,
.genesis_reset = prism2_pci_genesis_reset,
.hw_type = HOSTAP_HW_PCI,
};
@ -352,8 +358,6 @@ static int prism2_pci_probe(struct pci_dev *pdev,
return hostap_hw_ready(dev);
fail:
kfree(hw_priv);
if (irq_registered && dev)
free_irq(dev->irq, dev);
@ -364,10 +368,8 @@ static int prism2_pci_probe(struct pci_dev *pdev,
err_out_disable:
pci_disable_device(pdev);
kfree(hw_priv);
if (local)
local->hw_priv = NULL;
prism2_free_local_data(dev);
kfree(hw_priv);
return -ENODEV;
}
@ -392,9 +394,8 @@ static void prism2_pci_remove(struct pci_dev *pdev)
free_irq(dev->irq, dev);
mem_start = hw_priv->mem_start;
kfree(hw_priv);
iface->local->hw_priv = NULL;
prism2_free_local_data(dev);
kfree(hw_priv);
iounmap(mem_start);
@ -441,7 +442,7 @@ static int prism2_pci_resume(struct pci_dev *pdev)
MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
static struct pci_driver prism2_pci_drv_id = {
.name = "prism2_pci",
.name = "hostap_pci",
.id_table = prism2_pci_id_table,
.probe = prism2_pci_probe,
.remove = prism2_pci_remove,

View File

@ -328,8 +328,6 @@ static struct prism2_helper_functions prism2_plx_funcs =
{
.card_present = NULL,
.cor_sreset = prism2_plx_cor_sreset,
.dev_open = NULL,
.dev_close = NULL,
.genesis_reset = prism2_plx_genesis_reset,
.hw_type = HOSTAP_HW_PLX,
};
@ -570,10 +568,8 @@ static int prism2_plx_probe(struct pci_dev *pdev,
return hostap_hw_ready(dev);
fail:
kfree(hw_priv);
if (local)
local->hw_priv = NULL;
prism2_free_local_data(dev);
kfree(hw_priv);
if (irq_registered && dev)
free_irq(dev->irq, dev);
@ -606,9 +602,8 @@ static void prism2_plx_remove(struct pci_dev *pdev)
if (dev->irq)
free_irq(dev->irq, dev);
kfree(iface->local->hw_priv);
iface->local->hw_priv = NULL;
prism2_free_local_data(dev);
kfree(hw_priv);
pci_disable_device(pdev);
}
@ -616,7 +611,7 @@ static void prism2_plx_remove(struct pci_dev *pdev)
MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
static struct pci_driver prism2_plx_drv_id = {
.name = "prism2_plx",
.name = "hostap_plx",
.id_table = prism2_plx_id_table,
.probe = prism2_plx_probe,
.remove = prism2_plx_remove,

View File

@ -552,8 +552,6 @@ struct prism2_helper_functions {
* (hostap_{cs,plx,pci}.c */
int (*card_present)(local_info_t *local);
void (*cor_sreset)(local_info_t *local);
int (*dev_open)(local_info_t *local);
int (*dev_close)(local_info_t *local);
void (*genesis_reset)(local_info_t *local, int hcr);
/* the following functions are from hostap_hw.c, but they may have some

View File

@ -800,8 +800,7 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
* doesn't seem to have as many firmware restart cycles...
*
* As a test, we're sticking in a 1/100s delay here */
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ / 100);
schedule_timeout_uninterruptible(msecs_to_jiffies(10));
return 0;
@ -1256,8 +1255,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n");
i = 5000;
do {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(40 * HZ / 1000);
schedule_timeout_uninterruptible(msecs_to_jiffies(40));
/* Todo... wait for sync command ... */
read_register(priv->net_dev, IPW_REG_INTA, &inta);
@ -1411,8 +1409,7 @@ static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
(val2 & IPW2100_COMMAND_PHY_OFF))
return 0;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HW_PHY_OFF_LOOP_DELAY);
schedule_timeout_uninterruptible(HW_PHY_OFF_LOOP_DELAY);
}
return -EIO;
@ -1466,7 +1463,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
{
#define HW_POWER_DOWN_DELAY (HZ / 10)
#define HW_POWER_DOWN_DELAY (msecs_to_jiffies(100))
struct host_command cmd = {
.host_command = HOST_PRE_POWER_DOWN,
@ -1520,10 +1517,8 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
printk(KERN_WARNING DRV_NAME ": "
"%s: Power down command failed: Error %d\n",
priv->net_dev->name, err);
else {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HW_POWER_DOWN_DELAY);
}
else
schedule_timeout_uninterruptible(HW_POWER_DOWN_DELAY);
}
priv->status &= ~STATUS_ENABLED;
@ -2953,7 +2948,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
int next = txq->next;
int i = 0;
struct ipw2100_data_header *ipw_hdr;
struct ieee80211_hdr *hdr;
struct ieee80211_hdr_3addr *hdr;
while (!list_empty(&priv->tx_pend_list)) {
/* if there isn't enough space in TBD queue, then
@ -2989,7 +2984,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
packet->index = txq->next;
ipw_hdr = packet->info.d_struct.data;
hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb->
hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
fragments[0]->data;
if (priv->ieee->iw_mode == IW_MODE_INFRA) {
@ -3274,7 +3269,8 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
return IRQ_NONE;
}
static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
int pri)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
struct list_head *element;

View File

@ -808,7 +808,7 @@ struct ipw2100_priv {
struct ipw2100_rx {
union {
unsigned char payload[IPW_RX_NIC_BUFFER_LENGTH];
struct ieee80211_hdr header;
struct ieee80211_hdr_4addr header;
u32 status;
struct ipw2100_notification notification;
struct ipw2100_cmd_header command;

View File

@ -4904,7 +4904,7 @@ static void ipw_rx(struct ipw_priv *priv)
{
struct ipw_rx_mem_buffer *rxb;
struct ipw_rx_packet *pkt;
struct ieee80211_hdr *header;
struct ieee80211_hdr_4addr *header;
u32 r, w, i;
u8 network_packet;
@ -4967,8 +4967,9 @@ static void ipw_rx(struct ipw_priv *priv)
#endif
header =
(struct ieee80211_hdr *)(rxb->skb->data +
IPW_RX_FRAME_SIZE);
(struct ieee80211_hdr_4addr *)(rxb->skb->
data +
IPW_RX_FRAME_SIZE);
/* TODO: Check Ad-Hoc dest/source and make sure
* that we are actually parsing these packets
* correctly -- we should probably use the
@ -5317,8 +5318,6 @@ static int ipw_wx_set_freq(struct net_device *dev,
IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
return ipw_set_channel(priv, (u8) fwrq->m);
return 0;
}
static int ipw_wx_get_freq(struct net_device *dev,
@ -6010,12 +6009,12 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
}
if (priv->adapter == IPW_2915ABG) {
priv->ieee->abg_ture = 1;
priv->ieee->abg_true = 1;
if (mode & IEEE_A) {
band |= IEEE80211_52GHZ_BAND;
modulation |= IEEE80211_OFDM_MODULATION;
} else
priv->ieee->abg_ture = 0;
priv->ieee->abg_true = 0;
} else {
if (mode & IEEE_A) {
IPW_WARNING("Attempt to set 2200BG into "
@ -6023,20 +6022,20 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
return -EINVAL;
}
priv->ieee->abg_ture = 0;
priv->ieee->abg_true = 0;
}
if (mode & IEEE_B) {
band |= IEEE80211_24GHZ_BAND;
modulation |= IEEE80211_CCK_MODULATION;
} else
priv->ieee->abg_ture = 0;
priv->ieee->abg_true = 0;
if (mode & IEEE_G) {
band |= IEEE80211_24GHZ_BAND;
modulation |= IEEE80211_OFDM_MODULATION;
} else
priv->ieee->abg_ture = 0;
priv->ieee->abg_true = 0;
priv->ieee->mode = mode;
priv->ieee->freq_band = band;
@ -6325,7 +6324,7 @@ we need to heavily modify the ieee80211_skb_to_txb.
static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)
struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
txb->fragments[0]->data;
int i = 0;
struct tfd_frame *tfd;
@ -6448,7 +6447,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
}
static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
struct net_device *dev)
struct net_device *dev, int pri)
{
struct ipw_priv *priv = ieee80211_priv(dev);
unsigned long flags;
@ -7108,7 +7107,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
printk(KERN_INFO DRV_NAME
": Detected Intel PRO/Wireless 2915ABG Network "
"Connection\n");
priv->ieee->abg_ture = 1;
priv->ieee->abg_true = 1;
band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
modulation = IEEE80211_OFDM_MODULATION |
IEEE80211_CCK_MODULATION;
@ -7124,7 +7123,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
": Detected Intel PRO/Wireless 2200BG Network "
"Connection\n");
priv->ieee->abg_ture = 0;
priv->ieee->abg_true = 0;
band = IEEE80211_24GHZ_BAND;
modulation = IEEE80211_OFDM_MODULATION |
IEEE80211_CCK_MODULATION;

View File

@ -1654,12 +1654,12 @@ static const long ipw_frequencies[] = {
#define IPW_MAX_CONFIG_RETRIES 10
static inline u32 frame_hdr_len(struct ieee80211_hdr *hdr)
static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
{
u32 retval;
u16 fc;
retval = sizeof(struct ieee80211_hdr);
retval = sizeof(struct ieee80211_hdr_3addr);
fc = le16_to_cpu(hdr->frame_ctl);
/*

View File

@ -57,9 +57,7 @@
#include <linux/bitops.h>
#ifdef CONFIG_NET_RADIO
#include <linux/wireless.h>
#if WIRELESS_EXT > 12
#include <net/iw_handler.h>
#endif /* WIRELESS_EXT > 12 */
#endif
#include <pcmcia/cs_types.h>
@ -225,10 +223,7 @@ static void update_stats(struct net_device *dev);
static struct net_device_stats *netwave_get_stats(struct net_device *dev);
/* Wireless extensions */
#ifdef WIRELESS_EXT
static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
#endif
static int netwave_ioctl(struct net_device *, struct ifreq *, int);
static void set_multicast_list(struct net_device *dev);
@ -260,26 +255,7 @@ static dev_link_t *dev_list;
because they generally can't be allocated dynamically.
*/
#if WIRELESS_EXT <= 12
/* Wireless extensions backward compatibility */
/* Part of iw_handler prototype we need */
struct iw_request_info
{
__u16 cmd; /* Wireless Extension command */
__u16 flags; /* More to come ;-) */
};
/* Wireless Extension Backward compatibility - Jean II
* If the new wireless device private ioctl range is not defined,
* default to standard device private ioctl range */
#ifndef SIOCIWFIRSTPRIV
#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
#endif /* SIOCIWFIRSTPRIV */
#else /* WIRELESS_EXT <= 12 */
static const struct iw_handler_def netwave_handler_def;
#endif /* WIRELESS_EXT <= 12 */
#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */
@ -319,9 +295,7 @@ typedef struct netwave_private {
struct timer_list watchdog; /* To avoid blocking state */
struct site_survey nss;
struct net_device_stats stats;
#ifdef WIRELESS_EXT
struct iw_statistics iw_stats; /* Wireless stats */
#endif
} netwave_private;
#ifdef NETWAVE_STATS
@ -353,7 +327,6 @@ static inline void wait_WOC(unsigned int iobase)
while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ;
}
#ifdef WIRELESS_EXT
static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
kio_addr_t iobase) {
u_short resultBuffer;
@ -376,9 +349,7 @@ static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
sizeof(struct site_survey));
}
}
#endif
#ifdef WIRELESS_EXT
/*
* Function netwave_get_wireless_stats (dev)
*
@ -411,7 +382,6 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
return &priv->iw_stats;
}
#endif
/*
* Function netwave_attach (void)
@ -471,13 +441,7 @@ static dev_link_t *netwave_attach(void)
dev->get_stats = &netwave_get_stats;
dev->set_multicast_list = &set_multicast_list;
/* wireless extensions */
#if WIRELESS_EXT <= 16
dev->get_wireless_stats = &netwave_get_wireless_stats;
#endif /* WIRELESS_EXT <= 16 */
#if WIRELESS_EXT > 12
dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
#endif /* WIRELESS_EXT > 12 */
dev->do_ioctl = &netwave_ioctl;
dev->tx_timeout = &netwave_watchdog;
dev->watchdog_timeo = TX_TIMEOUT;
@ -576,13 +540,8 @@ static int netwave_set_nwid(struct net_device *dev,
/* Disable interrupts & save flags */
spin_lock_irqsave(&priv->spinlock, flags);
#if WIRELESS_EXT > 8
if(!wrqu->nwid.disabled) {
domain = wrqu->nwid.value;
#else /* WIRELESS_EXT > 8 */
if(wrqu->nwid.on) {
domain = wrqu->nwid.nwid;
#endif /* WIRELESS_EXT > 8 */
printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
(domain >> 8) & 0x01, domain & 0xff);
wait_WOC(iobase);
@ -606,15 +565,9 @@ static int netwave_get_nwid(struct net_device *dev,
union iwreq_data *wrqu,
char *extra)
{
#if WIRELESS_EXT > 8
wrqu->nwid.value = domain;
wrqu->nwid.disabled = 0;
wrqu->nwid.fixed = 1;
#else /* WIRELESS_EXT > 8 */
wrqu->nwid.nwid = domain;
wrqu->nwid.on = 1;
#endif /* WIRELESS_EXT > 8 */
return 0;
}
@ -657,17 +610,11 @@ static int netwave_get_scramble(struct net_device *dev,
{
key[1] = scramble_key & 0xff;
key[0] = (scramble_key>>8) & 0xff;
#if WIRELESS_EXT > 8
wrqu->encoding.flags = IW_ENCODE_ENABLED;
wrqu->encoding.length = 2;
#else /* WIRELESS_EXT > 8 */
wrqu->encoding.method = 1;
#endif /* WIRELESS_EXT > 8 */
return 0;
}
#if WIRELESS_EXT > 8
/*
* Wireless Handler : get mode
*/
@ -683,7 +630,6 @@ static int netwave_get_mode(struct net_device *dev,
return 0;
}
#endif /* WIRELESS_EXT > 8 */
/*
* Wireless Handler : get range info
@ -702,11 +648,9 @@ static int netwave_get_range(struct net_device *dev,
/* Set all the info we don't care or don't know about to zero */
memset(range, 0, sizeof(struct iw_range));
#if WIRELESS_EXT > 10
/* Set the Wireless Extension versions */
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 9; /* Nothing for us in v10 and v11 */
#endif /* WIRELESS_EXT > 10 */
/* Set information in the range struct */
range->throughput = 450 * 1000; /* don't argue on this ! */
@ -720,16 +664,12 @@ static int netwave_get_range(struct net_device *dev,
range->max_qual.level = 255;
range->max_qual.noise = 0;
#if WIRELESS_EXT > 7
range->num_bitrates = 1;
range->bitrate[0] = 1000000; /* 1 Mb/s */
#endif /* WIRELESS_EXT > 7 */
#if WIRELESS_EXT > 8
range->encoding_size[0] = 2; /* 16 bits scrambling */
range->num_encoding_sizes = 1;
range->max_encoding_tokens = 1; /* Only one key possible */
#endif /* WIRELESS_EXT > 8 */
return ret;
}
@ -775,8 +715,6 @@ static const struct iw_priv_args netwave_private_args[] = {
"getsitesurvey" },
};
#if WIRELESS_EXT > 12
static const iw_handler netwave_handler[] =
{
NULL, /* SIOCSIWNAME */
@ -839,131 +777,8 @@ static const struct iw_handler_def netwave_handler_def =
.standard = (iw_handler *) netwave_handler,
.private = (iw_handler *) netwave_private_handler,
.private_args = (struct iw_priv_args *) netwave_private_args,
#if WIRELESS_EXT > 16
.get_wireless_stats = netwave_get_wireless_stats,
#endif /* WIRELESS_EXT > 16 */
};
#endif /* WIRELESS_EXT > 12 */
/*
* Function netwave_ioctl (dev, rq, cmd)
*
* Perform ioctl : config & info stuff
* This is the stuff that are treated the wireless extensions (iwconfig)
*
*/
static int netwave_ioctl(struct net_device *dev, /* ioctl device */
struct ifreq *rq, /* Data passed */
int cmd) /* Ioctl number */
{
int ret = 0;
#ifdef WIRELESS_EXT
#if WIRELESS_EXT <= 12
struct iwreq *wrq = (struct iwreq *) rq;
#endif
#endif
DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
/* Look what is the request */
switch(cmd) {
/* --------------- WIRELESS EXTENSIONS --------------- */
#ifdef WIRELESS_EXT
#if WIRELESS_EXT <= 12
case SIOCGIWNAME:
netwave_get_name(dev, NULL, &(wrq->u), NULL);
break;
case SIOCSIWNWID:
ret = netwave_set_nwid(dev, NULL, &(wrq->u), NULL);
break;
case SIOCGIWNWID:
ret = netwave_get_nwid(dev, NULL, &(wrq->u), NULL);
break;
#if WIRELESS_EXT > 8 /* Note : The API did change... */
case SIOCGIWENCODE:
/* Get scramble key */
if(wrq->u.encoding.pointer != (caddr_t) 0)
{
char key[2];
ret = netwave_get_scramble(dev, NULL, &(wrq->u), key);
if(copy_to_user(wrq->u.encoding.pointer, key, 2))
ret = -EFAULT;
}
break;
case SIOCSIWENCODE:
/* Set scramble key */
if(wrq->u.encoding.pointer != (caddr_t) 0)
{
char key[2];
if(copy_from_user(key, wrq->u.encoding.pointer, 2))
{
ret = -EFAULT;
break;
}
ret = netwave_set_scramble(dev, NULL, &(wrq->u), key);
}
break;
case SIOCGIWMODE:
/* Mode of operation */
ret = netwave_get_mode(dev, NULL, &(wrq->u), NULL);
break;
#else /* WIRELESS_EXT > 8 */
case SIOCGIWENCODE:
/* Get scramble key */
ret = netwave_get_scramble(dev, NULL, &(wrq->u),
(char *) &wrq->u.encoding.code);
break;
case SIOCSIWENCODE:
/* Set scramble key */
ret = netwave_set_scramble(dev, NULL, &(wrq->u),
(char *) &wrq->u.encoding.code);
break;
#endif /* WIRELESS_EXT > 8 */
case SIOCGIWRANGE:
/* Basic checking... */
if(wrq->u.data.pointer != (caddr_t) 0) {
struct iw_range range;
ret = netwave_get_range(dev, NULL, &(wrq->u), (char *) &range);
if (copy_to_user(wrq->u.data.pointer, &range,
sizeof(struct iw_range)))
ret = -EFAULT;
}
break;
case SIOCGIWPRIV:
/* Basic checking... */
if(wrq->u.data.pointer != (caddr_t) 0) {
/* Set the number of ioctl available */
wrq->u.data.length = sizeof(netwave_private_args) / sizeof(netwave_private_args[0]);
/* Copy structure to the user buffer */
if(copy_to_user(wrq->u.data.pointer,
(u_char *) netwave_private_args,
sizeof(netwave_private_args)))
ret = -EFAULT;
}
break;
case SIOCGIPSNAP:
if(wrq->u.data.pointer != (caddr_t) 0) {
char buffer[sizeof( struct site_survey)];
ret = netwave_get_snap(dev, NULL, &(wrq->u), buffer);
/* Copy structure to the user buffer */
if(copy_to_user(wrq->u.data.pointer,
buffer,
sizeof( struct site_survey)))
{
printk(KERN_DEBUG "Bad buffer!\n");
break;
}
}
break;
#endif /* WIRELESS_EXT <= 12 */
#endif /* WIRELESS_EXT */
default:
ret = -EOPNOTSUPP;
}
return ret;
}
/*
* Function netwave_pcmcia_config (link)

View File

@ -77,30 +77,16 @@
#define DRIVER_NAME "orinoco"
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <net/ieee80211.h>
#include <net/ieee80211.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
#include "hermes.h"
#include "hermes_rid.h"
#include "orinoco.h"
@ -137,7 +123,7 @@ MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
/* We do this this way to avoid ifdefs in the actual code */
#ifdef WIRELESS_SPY
#define SPY_NUMBER(priv) (priv->spy_number)
#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
#else
#define SPY_NUMBER(priv) 0
#endif /* WIRELESS_SPY */
@ -216,31 +202,32 @@ static struct {
/********************************************************************/
/* Used in Event handling.
* We avoid nested structres as they break on ARM -- Moustafa */
* We avoid nested structures as they break on ARM -- Moustafa */
struct hermes_tx_descriptor_802_11 {
/* hermes_tx_descriptor */
u16 status;
u16 reserved1;
u16 reserved2;
u32 sw_support;
__le16 status;
__le16 reserved1;
__le16 reserved2;
__le32 sw_support;
u8 retry_count;
u8 tx_rate;
u16 tx_control;
__le16 tx_control;
/* ieee802_11_hdr */
u16 frame_ctl;
u16 duration_id;
/* ieee80211_hdr */
__le16 frame_ctl;
__le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
u16 seq_ctl;
__le16 seq_ctl;
u8 addr4[ETH_ALEN];
u16 data_len;
__le16 data_len;
/* ethhdr */
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
u8 h_dest[ETH_ALEN]; /* destination eth addr */
u8 h_source[ETH_ALEN]; /* source ether addr */
__be16 h_proto; /* packet type ID field */
/* p8022_hdr */
u8 dsap;
@ -248,31 +235,31 @@ struct hermes_tx_descriptor_802_11 {
u8 ctrl;
u8 oui[3];
u16 ethertype;
__be16 ethertype;
} __attribute__ ((packed));
/* Rx frame header except compatibility 802.3 header */
struct hermes_rx_descriptor {
/* Control */
u16 status;
u32 time;
__le16 status;
__le32 time;
u8 silence;
u8 signal;
u8 rate;
u8 rxflow;
u32 reserved;
__le32 reserved;
/* 802.11 header */
u16 frame_ctl;
u16 duration_id;
__le16 frame_ctl;
__le16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
u16 seq_ctl;
__le16 seq_ctl;
u8 addr4[ETH_ALEN];
/* Data length */
u16 data_len;
__le16 data_len;
} __attribute__ ((packed));
/********************************************************************/
@ -396,14 +383,14 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
/* If a spy address is defined, we report stats of the
* first spy address - Jean II */
if (SPY_NUMBER(priv)) {
wstats->qual.qual = priv->spy_stat[0].qual;
wstats->qual.level = priv->spy_stat[0].level;
wstats->qual.noise = priv->spy_stat[0].noise;
wstats->qual.updated = priv->spy_stat[0].updated;
wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
wstats->qual.level = priv->spy_data.spy_stat[0].level;
wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
}
} else {
struct {
u16 qual, signal, noise;
__le16 qual, signal, noise;
} __attribute__ ((packed)) cq;
err = HERMES_READ_RECORD(hw, USER_BAP,
@ -505,11 +492,9 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
/* Check packet length, pad short packets, round up odd length */
len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
if (skb->len < len) {
skb = skb_padto(skb, len);
if (skb == NULL)
goto fail;
}
skb = skb_padto(skb, len);
if (skb == NULL)
goto fail;
len -= ETH_HLEN;
eh = (struct ethhdr *)skb->data;
@ -634,16 +619,17 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
struct orinoco_private *priv = netdev_priv(dev);
struct net_device_stats *stats = &priv->stats;
u16 fid = hermes_read_regn(hw, TXCOMPLFID);
u16 status;
struct hermes_tx_descriptor_802_11 hdr;
int err = 0;
if (fid == DUMMY_FID)
return; /* Nothing's really happened */
/* Read the frame header */
/* Read part of the frame header - we need status and addr1 */
err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
sizeof(struct hermes_tx_descriptor) +
sizeof(struct ieee80211_hdr),
offsetof(struct hermes_tx_descriptor_802_11,
addr2),
fid, 0);
hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
@ -663,8 +649,8 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
* exceeded, because that's the only status that really mean
* that this particular node went away.
* Other errors means that *we* screwed up. - Jean II */
hdr.status = le16_to_cpu(hdr.status);
if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
status = le16_to_cpu(hdr.status);
if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
union iwreq_data wrqu;
/* Copy 802.11 dest address.
@ -723,18 +709,13 @@ static inline int is_ethersnap(void *_hdr)
static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
int level, int noise)
{
struct orinoco_private *priv = netdev_priv(dev);
int i;
/* Gather wireless spy statistics: for each packet, compare the
* source address with out list, and if match, get the stats... */
for (i = 0; i < priv->spy_number; i++)
if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
priv->spy_stat[i].level = level - 0x95;
priv->spy_stat[i].noise = noise - 0x95;
priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
priv->spy_stat[i].updated = 7;
}
struct iw_quality wstats;
wstats.level = level - 0x95;
wstats.noise = noise - 0x95;
wstats.qual = (level > noise) ? (level - noise) : 0;
wstats.updated = 7;
/* Update spy records */
wireless_spy_update(dev, mac, &wstats);
}
static void orinoco_stat_gather(struct net_device *dev,
@ -1055,7 +1036,7 @@ static void orinoco_join_ap(struct net_device *dev)
unsigned long flags;
struct join_req {
u8 bssid[ETH_ALEN];
u16 channel;
__le16 channel;
} __attribute__ ((packed)) req;
const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
struct prism2_scan_apinfo *atom = NULL;
@ -1070,7 +1051,7 @@ static void orinoco_join_ap(struct net_device *dev)
return;
if (orinoco_lock(priv, &flags) != 0)
goto out;
goto fail_lock;
/* Sanity checks in case user changed something in the meantime */
if (! priv->bssid_fixed)
@ -1115,8 +1096,10 @@ static void orinoco_join_ap(struct net_device *dev)
printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
out:
kfree(buf);
orinoco_unlock(priv, &flags);
fail_lock:
kfree(buf);
}
/* Send new BSSID to userspace */
@ -1134,12 +1117,14 @@ static void orinoco_send_wevents(struct net_device *dev)
err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
if (err != 0)
return;
goto out;
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
/* Send event to user space */
wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
out:
orinoco_unlock(priv, &flags);
}
@ -1148,8 +1133,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
struct orinoco_private *priv = netdev_priv(dev);
u16 infofid;
struct {
u16 len;
u16 type;
__le16 len;
__le16 type;
} __attribute__ ((packed)) info;
int len, type;
int err;
@ -2464,6 +2449,10 @@ struct net_device *alloc_orinocodev(int sizeof_card,
dev->get_stats = orinoco_get_stats;
dev->ethtool_ops = &orinoco_ethtool_ops;
dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
#ifdef WIRELESS_SPY
priv->wireless_data.spy_data = &priv->spy_data;
dev->wireless_data = &priv->wireless_data;
#endif
dev->change_mtu = orinoco_change_mtu;
dev->set_multicast_list = orinoco_set_multicast_list;
/* we use the default eth_mac_addr for setting the MAC addr */
@ -2835,7 +2824,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
}
}
if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
/* Quality stats meaningless in ad-hoc mode */
} else {
range->max_qual.qual = 0x8b - 0x2f;
@ -2882,6 +2871,14 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
range->min_r_time = 0;
range->max_r_time = 65535 * 1000; /* ??? */
/* Event capability (kernel) */
IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
/* Event capability (driver) */
IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
TRACE_EXIT(dev->name);
return 0;
@ -3841,92 +3838,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
return err;
}
/* Spy is used for link quality/strength measurements in Ad-Hoc mode
* Jean II */
static int orinoco_ioctl_setspy(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *srq,
char *extra)
{
struct orinoco_private *priv = netdev_priv(dev);
struct sockaddr *address = (struct sockaddr *) extra;
int number = srq->length;
int i;
unsigned long flags;
/* Make sure nobody mess with the structure while we do */
if (orinoco_lock(priv, &flags) != 0)
return -EBUSY;
/* orinoco_lock() doesn't disable interrupts, so make sure the
* interrupt rx path don't get confused while we copy */
priv->spy_number = 0;
if (number > 0) {
/* Extract the addresses */
for (i = 0; i < number; i++)
memcpy(priv->spy_address[i], address[i].sa_data,
ETH_ALEN);
/* Reset stats */
memset(priv->spy_stat, 0,
sizeof(struct iw_quality) * IW_MAX_SPY);
/* Set number of addresses */
priv->spy_number = number;
}
/* Now, let the others play */
orinoco_unlock(priv, &flags);
/* Do NOT call commit handler */
return 0;
}
static int orinoco_ioctl_getspy(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *srq,
char *extra)
{
struct orinoco_private *priv = netdev_priv(dev);
struct sockaddr *address = (struct sockaddr *) extra;
int number;
int i;
unsigned long flags;
if (orinoco_lock(priv, &flags) != 0)
return -EBUSY;
number = priv->spy_number;
/* Create address struct */
for (i = 0; i < number; i++) {
memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
address[i].sa_family = AF_UNIX;
}
if (number > 0) {
/* Create address struct */
for (i = 0; i < number; i++) {
memcpy(address[i].sa_data, priv->spy_address[i],
ETH_ALEN);
address[i].sa_family = AF_UNIX;
}
/* Copy stats */
/* In theory, we should disable irqs while copying the stats
* because the rx path might update it in the middle...
* Bah, who care ? - Jean II */
memcpy(extra + (sizeof(struct sockaddr) * number),
priv->spy_stat, sizeof(struct iw_quality) * number);
}
/* Reset updated flags. */
for (i = 0; i < number; i++)
priv->spy_stat[i].updated = 0;
orinoco_unlock(priv, &flags);
srq->length = number;
return 0;
}
/* Trigger a scan (look for other cells in the vicinity */
static int orinoco_ioctl_setscan(struct net_device *dev,
struct iw_request_info *info,
@ -3999,7 +3910,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
HERMES_HOSTSCAN_SYMBOL_BCAST);
break;
case FIRMWARE_TYPE_INTERSIL: {
u16 req[3];
__le16 req[3];
req[0] = cpu_to_le16(0x3fff); /* All channels */
req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
@ -4073,7 +3984,7 @@ static inline int orinoco_translate_scan(struct net_device *dev,
case FIRMWARE_TYPE_INTERSIL:
offset = 4;
if (priv->has_hostscan) {
atom_len = le16_to_cpup((u16 *)scan);
atom_len = le16_to_cpup((__le16 *)scan);
/* Sanity check for atom_len */
if (atom_len < sizeof(struct prism2_scan_apinfo)) {
printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
@ -4357,8 +4268,10 @@ static const iw_handler orinoco_handler[] = {
[SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
[SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
[SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
[SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy,
[SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy,
[SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
[SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
[SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
[SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
[SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
[SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
[SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,

View File

@ -7,12 +7,11 @@
#ifndef _ORINOCO_H
#define _ORINOCO_H
#define DRIVER_VERSION "0.15rc2"
#define DRIVER_VERSION "0.15rc3"
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <linux/version.h>
#include "hermes.h"
@ -28,7 +27,7 @@
#define ORINOCO_MAX_KEYS 4
struct orinoco_key {
u16 len; /* always stored as little-endian */
__le16 len; /* always stored as little-endian */
char data[ORINOCO_MAX_KEY_SIZE];
} __attribute__ ((packed));
@ -36,14 +35,14 @@ struct header_struct {
/* 802.3 */
u8 dest[ETH_ALEN];
u8 src[ETH_ALEN];
u16 len;
__be16 len;
/* 802.2 */
u8 dsap;
u8 ssap;
u8 ctrl;
/* SNAP */
u8 oui[3];
u16 ethertype;
unsigned short ethertype;
} __attribute__ ((packed));
typedef enum {
@ -112,9 +111,8 @@ struct orinoco_private {
u16 pm_on, pm_mcast, pm_period, pm_timeout;
u16 preamble;
#ifdef WIRELESS_SPY
int spy_number;
u_char spy_address[IW_MAX_SPY][ETH_ALEN];
struct iw_quality spy_stat[IW_MAX_SPY];
struct iw_spy_data spy_data; /* iwspy support */
struct iw_public_data wireless_data;
#endif
/* Configuration dependent variables */

Some files were not shown because too many files have changed in this diff Show More