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

This commit is contained in:
Linus Torvalds 2005-11-11 09:26:39 -08:00
commit 388f7ef720
19 changed files with 848 additions and 679 deletions

View File

@ -812,7 +812,7 @@ config SMC91X
tristate "SMC 91C9x/91C1xxx support"
select CRC32
select MII
depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH)
depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00)
help
This is a driver for SMC's 91x series of Ethernet chipsets,
including the SMC91C94 and the SMC91C111. Say Y if you want it

View File

@ -80,7 +80,7 @@
* into nv_close, otherwise reenabling for wol can
* cause DMA to kfree'd memory.
* 0.31: 14 Nov 2004: ethtool support for getting/setting link
* capabilities.
* capabilities.
* 0.32: 16 Apr 2005: RX_ERROR4 handling added.
* 0.33: 16 May 2005: Support for MCP51 added.
* 0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics.
@ -89,14 +89,17 @@
* 0.37: 10 Jul 2005: Additional ethtool support, cleanup of pci id list
* 0.38: 16 Jul 2005: tx irq rewrite: Use global flags instead of
* per-packet flags.
* 0.39: 18 Jul 2005: Add 64bit descriptor support.
* 0.40: 19 Jul 2005: Add support for mac address change.
* 0.41: 30 Jul 2005: Write back original MAC in nv_close instead
* 0.39: 18 Jul 2005: Add 64bit descriptor support.
* 0.40: 19 Jul 2005: Add support for mac address change.
* 0.41: 30 Jul 2005: Write back original MAC in nv_close instead
* of nv_remove
* 0.42: 06 Aug 2005: Fix lack of link speed initialization
* 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.
* 0.43: 10 Aug 2005: Add support for tx checksum.
* 0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
* 0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check
* 0.46: 20 Oct 2005: Add irq optimization modes.
* 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan.
*
* Known bugs:
* We suspect that on some hardware no TX done interrupts are generated.
@ -108,7 +111,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.44"
#define FORCEDETH_VERSION "0.47"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@ -163,7 +166,8 @@ enum {
#define NVREG_IRQ_LINK 0x0040
#define NVREG_IRQ_TX_ERROR 0x0080
#define NVREG_IRQ_TX1 0x0100
#define NVREG_IRQMASK_WANTED 0x00df
#define NVREG_IRQMASK_THROUGHPUT 0x00df
#define NVREG_IRQMASK_CPU 0x0040
#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \
NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX_ERROR| \
@ -177,7 +181,8 @@ enum {
* NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
*/
NvRegPollingInterval = 0x00c,
#define NVREG_POLL_DEFAULT 970
#define NVREG_POLL_DEFAULT_THROUGHPUT 970
#define NVREG_POLL_DEFAULT_CPU 13
NvRegMisc1 = 0x080,
#define NVREG_MISC1_HD 0x02
#define NVREG_MISC1_FORCE 0x3b0f3c
@ -538,6 +543,25 @@ struct fe_priv {
*/
static int max_interrupt_work = 5;
/*
* Optimization can be either throuput mode or cpu mode
*
* Throughput Mode: Every tx and rx packet will generate an interrupt.
* CPU Mode: Interrupts are controlled by a timer.
*/
#define NV_OPTIMIZATION_MODE_THROUGHPUT 0
#define NV_OPTIMIZATION_MODE_CPU 1
static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;
/*
* Poll interval for timer irq
*
* This interval determines how frequent an interrupt is generated.
* The is value is determined by [(time_in_micro_secs * 100) / (2^10)]
* Min = 0, and Max = 65535
*/
static int poll_interval = -1;
static inline struct fe_priv *get_nvpriv(struct net_device *dev)
{
return netdev_priv(dev);
@ -1328,67 +1352,71 @@ static void nv_rx_process(struct net_device *dev)
if (!(Flags & NV_RX_DESCRIPTORVALID))
goto next_pkt;
if (Flags & NV_RX_MISSEDFRAME) {
np->stats.rx_missed_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX_CRCERR) {
np->stats.rx_crc_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX_OVERFLOW) {
np->stats.rx_over_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX_ERROR4) {
len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
if (len < 0) {
if (Flags & NV_RX_ERROR) {
if (Flags & NV_RX_MISSEDFRAME) {
np->stats.rx_missed_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
}
/* framing errors are soft errors. */
if (Flags & NV_RX_FRAMINGERR) {
if (Flags & NV_RX_SUBSTRACT1) {
len--;
if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX_CRCERR) {
np->stats.rx_crc_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX_OVERFLOW) {
np->stats.rx_over_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX_ERROR4) {
len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
if (len < 0) {
np->stats.rx_errors++;
goto next_pkt;
}
}
/* framing errors are soft errors. */
if (Flags & NV_RX_FRAMINGERR) {
if (Flags & NV_RX_SUBSTRACT1) {
len--;
}
}
}
} else {
if (!(Flags & NV_RX2_DESCRIPTORVALID))
goto next_pkt;
if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX2_CRCERR) {
np->stats.rx_crc_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX2_OVERFLOW) {
np->stats.rx_over_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX2_ERROR4) {
len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
if (len < 0) {
if (Flags & NV_RX2_ERROR) {
if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {
np->stats.rx_errors++;
goto next_pkt;
}
}
/* framing errors are soft errors */
if (Flags & NV_RX2_FRAMINGERR) {
if (Flags & NV_RX2_SUBSTRACT1) {
len--;
if (Flags & NV_RX2_CRCERR) {
np->stats.rx_crc_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX2_OVERFLOW) {
np->stats.rx_over_errors++;
np->stats.rx_errors++;
goto next_pkt;
}
if (Flags & NV_RX2_ERROR4) {
len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
if (len < 0) {
np->stats.rx_errors++;
goto next_pkt;
}
}
/* framing errors are soft errors */
if (Flags & NV_RX2_FRAMINGERR) {
if (Flags & NV_RX2_SUBSTRACT1) {
len--;
}
}
}
Flags &= NV_RX2_CHECKSUMMASK;
@ -1612,6 +1640,17 @@ static void nv_set_multicast(struct net_device *dev)
spin_unlock_irq(&np->lock);
}
/**
* nv_update_linkspeed: Setup the MAC according to the link partner
* @dev: Network device to be configured
*
* The function queries the PHY and checks if there is a link partner.
* If yes, then it sets up the MAC accordingly. Otherwise, the MAC is
* set to 10 MBit HD.
*
* The function returns 0 if there is no link partner and 1 if there is
* a good link partner.
*/
static int nv_update_linkspeed(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
@ -1751,13 +1790,11 @@ static int nv_update_linkspeed(struct net_device *dev)
static void nv_linkchange(struct net_device *dev)
{
if (nv_update_linkspeed(dev)) {
if (netif_carrier_ok(dev)) {
nv_stop_rx(dev);
} else {
if (!netif_carrier_ok(dev)) {
netif_carrier_on(dev);
printk(KERN_INFO "%s: link up.\n", dev->name);
nv_start_rx(dev);
}
nv_start_rx(dev);
} else {
if (netif_carrier_ok(dev)) {
netif_carrier_off(dev);
@ -1799,22 +1836,18 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
if (!(events & np->irqmask))
break;
if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_ERROR|NVREG_IRQ_TX_ERR)) {
spin_lock(&np->lock);
nv_tx_done(dev);
spin_unlock(&np->lock);
nv_rx_process(dev);
if (nv_alloc_rx(dev)) {
spin_lock(&np->lock);
nv_tx_done(dev);
if (!np->in_shutdown)
mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
spin_unlock(&np->lock);
}
if (events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) {
nv_rx_process(dev);
if (nv_alloc_rx(dev)) {
spin_lock(&np->lock);
if (!np->in_shutdown)
mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
spin_unlock(&np->lock);
}
}
if (events & NVREG_IRQ_LINK) {
spin_lock(&np->lock);
nv_link_irq(dev);
@ -2216,7 +2249,14 @@ static int nv_open(struct net_device *dev)
writel(NVREG_RNDSEED_FORCE | (i&NVREG_RNDSEED_MASK), base + NvRegRandomSeed);
writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1);
writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);
writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval);
if (poll_interval == -1) {
if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT)
writel(NVREG_POLL_DEFAULT_THROUGHPUT, base + NvRegPollingInterval);
else
writel(NVREG_POLL_DEFAULT_CPU, base + NvRegPollingInterval);
}
else
writel(poll_interval & 0xFFFF, base + NvRegPollingInterval);
writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING,
base + NvRegAdapterControl);
@ -2501,7 +2541,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
} else {
np->tx_flags = NV_TX2_VALID;
}
np->irqmask = NVREG_IRQMASK_WANTED;
if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT)
np->irqmask = NVREG_IRQMASK_THROUGHPUT;
else
np->irqmask = NVREG_IRQMASK_CPU;
if (id->driver_data & DEV_NEED_TIMERIRQ)
np->irqmask |= NVREG_IRQ_TIMER;
if (id->driver_data & DEV_NEED_LINKTIMER) {
@ -2514,16 +2558,17 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
}
/* find a suitable phy */
for (i = 1; i < 32; i++) {
for (i = 1; i <= 32; i++) {
int id1, id2;
int phyaddr = i & 0x1F;
spin_lock_irq(&np->lock);
id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ);
id1 = mii_rw(dev, phyaddr, MII_PHYSID1, MII_READ);
spin_unlock_irq(&np->lock);
if (id1 < 0 || id1 == 0xffff)
continue;
spin_lock_irq(&np->lock);
id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ);
id2 = mii_rw(dev, phyaddr, MII_PHYSID2, MII_READ);
spin_unlock_irq(&np->lock);
if (id2 < 0 || id2 == 0xffff)
continue;
@ -2531,23 +2576,19 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT;
id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT;
dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n",
pci_name(pci_dev), id1, id2, i);
np->phyaddr = i;
pci_name(pci_dev), id1, id2, phyaddr);
np->phyaddr = phyaddr;
np->phy_oui = id1 | id2;
break;
}
if (i == 32) {
/* PHY in isolate mode? No phy attached and user wants to
* test loopback? Very odd, but can be correct.
*/
if (i == 33) {
printk(KERN_INFO "%s: open: Could not find a valid PHY.\n",
pci_name(pci_dev));
}
if (i != 32) {
/* reset it */
phy_init(dev);
pci_name(pci_dev));
goto out_freering;
}
/* reset it */
phy_init(dev);
/* set default link speed settings */
np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
@ -2689,6 +2730,10 @@ static void __exit exit_nic(void)
module_param(max_interrupt_work, int, 0);
MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
module_param(optimization_mode, int, 0);
MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer.");
module_param(poll_interval, int, 0);
MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535.");
MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");

View File

@ -133,7 +133,7 @@ int gfar_mdio_probe(struct device *dev)
if (NULL == dev)
return -EINVAL;
new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
if (NULL == new_bus)
return -ENOMEM;

View File

@ -72,8 +72,6 @@ static void dump_tx_desc(int dbg_lvl, struct net_device *dev, int i);
static void dump_rx_desc(int dbg_lvl, struct net_device *dev, int i);
static void dump_skb(int dbg_lvl, struct net_device *dev,
struct sk_buff *skb);
static void dump_hw_addr(int dbg_lvl, struct net_device *dev,
const char* pfx, unsigned char* addr_str);
static void update_stats(struct gt96100_private *gp);
static void abort(struct net_device *dev, u32 abort_bits);
static void hard_stop(struct net_device *dev);
@ -334,13 +332,13 @@ dump_MII(int dbg_lvl, struct net_device *dev)
static void
dump_hw_addr(int dbg_lvl, struct net_device *dev, const char* pfx,
unsigned char* addr_str)
const char* func, unsigned char* addr_str)
{
int i;
char buf[100], octet[5];
if (dbg_lvl <= GT96100_DEBUG) {
strcpy(buf, pfx);
sprintf(buf, pfx, func);
for (i = 0; i < 6; i++) {
sprintf(octet, "%2.2x%s",
addr_str[i], i<5 ? ":" : "\n");
@ -708,7 +706,7 @@ static int __init gt96100_probe1(struct pci_dev *pci, int port_num)
info("%s found at 0x%x, irq %d\n",
chip_name(gp->chip_rev), gtif->iobase, gtif->irq);
dump_hw_addr(0, dev, "HW Address ", dev->dev_addr);
dump_hw_addr(0, dev, "%s: HW Address ", __FUNCTION__, dev->dev_addr);
info("%s chip revision=%d\n", chip_name(gp->chip_rev), gp->chip_rev);
info("%s ethernet port %d\n", chip_name(gp->chip_rev), gp->port_num);
info("external PHY ID1=0x%04x, ID2=0x%04x\n", phy_id1, phy_id2);
@ -1488,7 +1486,7 @@ gt96100_set_rx_mode(struct net_device *dev)
gt96100_add_hash_entry(dev, dev->dev_addr);
for (mcptr = dev->mc_list; mcptr; mcptr = mcptr->next) {
dump_hw_addr(2, dev, __FUNCTION__ ": addr=",
dump_hw_addr(2, dev, "%s: addr=", __FUNCTION__,
mcptr->dmi_addr);
gt96100_add_hash_entry(dev, mcptr->dmi_addr);
}

View File

@ -58,7 +58,7 @@
#include "ibmveth.h"
#define DEBUG 1
#undef DEBUG
#define ibmveth_printk(fmt, args...) \
printk(KERN_INFO "%s: " fmt, __FILE__, ## args)

File diff suppressed because it is too large Load Diff

View File

@ -289,6 +289,38 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
#define RPC_LSA_DEFAULT RPC_LED_TX_RX
#define RPC_LSB_DEFAULT RPC_LED_100_10
#elif defined(CONFIG_SOC_AU1X00)
#include <au1xxx.h>
/* We can only do 16-bit reads and writes in the static memory space. */
#define SMC_CAN_USE_8BIT 0
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
#define SMC_IO_SHIFT 0
#define SMC_NOWAIT 1
#define SMC_inw(a, r) au_readw((unsigned long)((a) + (r)))
#define SMC_insw(a, r, p, l) \
do { \
unsigned long _a = (unsigned long)((a) + (r)); \
int _l = (l); \
u16 *_p = (u16 *)(p); \
while (_l-- > 0) \
*_p++ = au_readw(_a); \
} while(0)
#define SMC_outw(v, a, r) au_writew(v, (unsigned long)((a) + (r)))
#define SMC_outsw(a, r, p, l) \
do { \
unsigned long _a = (unsigned long)((a) + (r)); \
int _l = (l); \
const u16 *_p = (const u16 *)(p); \
while (_l-- > 0) \
au_writew(*_p++ , _a); \
} while(0)
#define set_irq_type(irq, type) do {} while (0)
#else
#define SMC_CAN_USE_8BIT 1

View File

@ -330,7 +330,7 @@ config PCI_HERMES
config ATMEL
tristate "Atmel at76c50x chipset 802.11b support"
depends on NET_RADIO && EXPERIMENTAL
depends on NET_RADIO
select FW_LOADER
select CRC32
---help---

View File

@ -72,7 +72,7 @@
#include "atmel.h"
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 96
#define DRIVER_MINOR 98
MODULE_AUTHOR("Simon Kelley");
MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
@ -1504,7 +1504,7 @@ static int atmel_read_proc(char *page, char **start, off_t off,
return len;
}
struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWType fw_type,
struct net_device *init_atmel_card( unsigned short irq, unsigned long port, const AtmelFWType fw_type,
struct device *sys_dev, int (*card_present)(void *), void *card)
{
struct net_device *dev;
@ -1605,8 +1605,8 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT
goto err_out_free;
}
if (priv->bus_type == BUS_TYPE_PCI &&
!request_region( dev->base_addr, 64, dev->name )) {
if (!request_region(dev->base_addr, 32,
priv->bus_type == BUS_TYPE_PCCARD ? "atmel_cs" : "atmel_pci")) {
goto err_out_irq;
}
@ -1622,15 +1622,16 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT
create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
printk(KERN_INFO "%s: Atmel at76c50x wireless. Version %d.%d simon@thekelleys.org.uk\n",
dev->name, DRIVER_MAJOR, DRIVER_MINOR);
printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
dev->name, DRIVER_MAJOR, DRIVER_MINOR,
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
SET_MODULE_OWNER(dev);
return dev;
err_out_res:
if (priv->bus_type == BUS_TYPE_PCI)
release_region( dev->base_addr, 64 );
release_region( dev->base_addr, 32);
err_out_irq:
free_irq(dev->irq, dev);
err_out_free:
@ -1640,7 +1641,7 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT
EXPORT_SYMBOL(init_atmel_card);
void stop_atmel_card(struct net_device *dev, int freeres)
void stop_atmel_card(struct net_device *dev)
{
struct atmel_private *priv = netdev_priv(dev);
@ -1654,10 +1655,7 @@ void stop_atmel_card(struct net_device *dev, int freeres)
remove_proc_entry("driver/atmel", NULL);
free_irq(dev->irq, dev);
kfree(priv->firmware);
if (freeres) {
/* PCMCIA frees this stuff, so only for PCI */
release_region(dev->base_addr, 64);
}
release_region(dev->base_addr, 32);
free_netdev(dev);
}
@ -1810,9 +1808,9 @@ static int atmel_set_encode(struct net_device *dev,
}
if(dwrq->flags & IW_ENCODE_RESTRICTED)
priv->exclude_unencrypted = 1;
if(dwrq->flags & IW_ENCODE_OPEN)
if(dwrq->flags & IW_ENCODE_OPEN)
priv->exclude_unencrypted = 0;
return -EINPROGRESS; /* Call commit handler */
}
@ -1827,11 +1825,12 @@ static int atmel_get_encode(struct net_device *dev,
if (!priv->wep_is_on)
dwrq->flags = IW_ENCODE_DISABLED;
else if (priv->exclude_unencrypted)
dwrq->flags = IW_ENCODE_RESTRICTED;
else
dwrq->flags = IW_ENCODE_OPEN;
else {
if (priv->exclude_unencrypted)
dwrq->flags = IW_ENCODE_RESTRICTED;
else
dwrq->flags = IW_ENCODE_OPEN;
}
/* Which key do we want ? -1 -> tx index */
if (index < 0 || index >= 4)
index = priv->default_key;
@ -2645,8 +2644,8 @@ 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)
static void send_authentication_request(struct atmel_private *priv, u16 system, u8 *challenge, int challenge_len)
{
struct ieee80211_hdr_4addr header;
struct auth_body auth;
@ -2658,14 +2657,11 @@ static void send_authentication_request(struct atmel_private *priv, u8 *challeng
memcpy(header.addr2, priv->dev->dev_addr, 6);
memcpy(header.addr3, priv->CurrentBSSID, 6);
if (priv->wep_is_on) {
auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY);
if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
/* no WEP for authentication frames with TrSeqNo 1 */
if (priv->CurrentAuthentTransactionSeqNum != 1)
header.frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
} else {
auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM);
}
header.frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
auth.alg = cpu_to_le16(system);
auth.status = 0;
auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
@ -2834,6 +2830,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
struct auth_body *auth = (struct auth_body *)priv->rx_buf;
u16 status = le16_to_cpu(auth->status);
u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
u16 system = le16_to_cpu(auth->alg);
if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) {
/* no WEP */
@ -2855,7 +2852,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
if (trans_seq_no == 0x0002 &&
auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
send_authentication_request(priv, auth->chall_text, auth->chall_text_len);
send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
return;
}
@ -2872,14 +2869,20 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
}
}
if (status == C80211_MGMT_SC_AuthAlgNotSupported && priv->connect_to_any_BSS) {
int bss_index;
priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
if ((bss_index = retrieve_bss(priv)) != -1) {
atmel_join_bss(priv, bss_index);
return;
if (status == C80211_MGMT_SC_AuthAlgNotSupported) {
/* Do opensystem first, then try sharedkey */
if (system == C80211_MGMT_AAN_OPENSYSTEM) {
priv->CurrentAuthentTransactionSeqNum = 0x001;
send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
} else if (priv->connect_to_any_BSS) {
int bss_index;
priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
if ((bss_index = retrieve_bss(priv)) != -1) {
atmel_join_bss(priv, bss_index);
return;
}
}
}
@ -3205,7 +3208,7 @@ static void atmel_management_timer(u_long a)
priv->AuthenticationRequestRetryCnt++;
priv->CurrentAuthentTransactionSeqNum = 0x0001;
mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
send_authentication_request(priv, NULL, 0);
send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
}
break;
@ -3312,7 +3315,7 @@ static void atmel_command_irq(struct atmel_private *priv)
mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
priv->CurrentAuthentTransactionSeqNum = 0x0001;
send_authentication_request(priv, NULL, 0);
send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
}
return;
}
@ -3482,11 +3485,6 @@ static int probe_atmel_card(struct net_device *dev)
printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
memcpy(dev->dev_addr, default_mac, 6);
}
printk(KERN_INFO "%s: MAC address %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
dev->name,
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
}
return rc;

View File

@ -35,9 +35,9 @@ typedef enum {
ATMEL_FW_TYPE_506
} AtmelFWType;
struct net_device *init_atmel_card(unsigned short, int, const AtmelFWType, struct device *,
struct net_device *init_atmel_card(unsigned short, unsigned long, const AtmelFWType, struct device *,
int (*present_func)(void *), void * );
void stop_atmel_card( struct net_device *, int );
void stop_atmel_card( struct net_device *);
int atmel_open( struct net_device * );
#endif

View File

@ -63,6 +63,7 @@
be present but disabled -- but it can then be enabled for specific
modules at load time with a 'pc_debug=#' option to insmod.
*/
#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0);
@ -285,41 +286,6 @@ static int card_present(void *arg)
return 0;
}
/* list of cards we know about and their firmware requirements.
Go either by Manfid or version strings.
Cards not in this list will need a firmware parameter to the module
in all probability. Note that the SMC 2632 V2 and V3 have the same
manfids, so we ignore those and use the version1 strings. */
static struct {
int manf, card;
char *ver1;
AtmelFWType firmware;
char *name;
} card_table[] = {
{ 0, 0, "WLAN/802.11b PC CARD", ATMEL_FW_TYPE_502D, "Actiontec 802CAT1" },
{ 0, 0, "ATMEL/AT76C502AR", ATMEL_FW_TYPE_502, "NoName-RFMD" },
{ 0, 0, "ATMEL/AT76C502AR_D", ATMEL_FW_TYPE_502D, "NoName-revD" },
{ 0, 0, "ATMEL/AT76C502AR_E", ATMEL_FW_TYPE_502E, "NoName-revE" },
{ 0, 0, "ATMEL/AT76C504", ATMEL_FW_TYPE_504, "NoName-504" },
{ 0, 0, "ATMEL/AT76C504A", ATMEL_FW_TYPE_504A_2958, "NoName-504a-2958" },
{ 0, 0, "ATMEL/AT76C504_R", ATMEL_FW_TYPE_504_2958, "NoName-504-2958" },
{ MANFID_3COM, 0x0620, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRWE62092B" },
{ MANFID_3COM, 0x0696, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRSHPW196" },
{ 0, 0, "SMC/2632W-V2", ATMEL_FW_TYPE_502, "SMC 2632W-V2" },
{ 0, 0, "SMC/2632W", ATMEL_FW_TYPE_502D, "SMC 2632W-V3" },
{ 0xd601, 0x0007, NULL, ATMEL_FW_TYPE_502, "Sitecom WLAN-011" },
{ 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" },
{ 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" },
{ 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" },
{ 0, 0, "IEEE 802.11b/Wireless LAN Card S", ATMEL_FW_TYPE_504_2958, "Siemens Gigaset PC Card II" },
{ 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" },
{ 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" },
{ 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" },
{ 0, 0, "11WAVE/11WP611AL-E", ATMEL_FW_TYPE_502E, "11WAVE WaveBuddy" },
{ 0, 0, "LG/LW2100N", ATMEL_FW_TYPE_502E, "LG LW2100N 11Mbps WLAN PCMCIA Card" },
};
static void atmel_config(dev_link_t *link)
{
client_handle_t handle;
@ -328,10 +294,11 @@ static void atmel_config(dev_link_t *link)
local_info_t *dev;
int last_fn, last_ret;
u_char buf[64];
int card_index = -1, done = 0;
struct pcmcia_device_id *did;
handle = link->handle;
dev = link->priv;
did = handle_to_dev(handle).driver_data;
DEBUG(0, "atmel_config(0x%p)\n", link);
@ -340,59 +307,6 @@ static void atmel_config(dev_link_t *link)
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_MANFID;
if (pcmcia_get_first_tuple(handle, &tuple) == 0) {
int i;
cistpl_manfid_t *manfid;
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
manfid = &(parse.manfid);
for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
if (!card_table[i].ver1 &&
manfid->manf == card_table[i].manf &&
manfid->card == card_table[i].card) {
card_index = i;
done = 1;
}
}
}
tuple.DesiredTuple = CISTPL_VERS_1;
if (!done && (pcmcia_get_first_tuple(handle, &tuple) == 0)) {
int i, j, k;
cistpl_vers_1_t *ver1;
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
ver1 = &(parse.version_1);
for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
for (j = 0; j < ver1->ns; j++) {
char *p = card_table[i].ver1;
char *q = &ver1->str[ver1->ofs[j]];
if (!p)
goto mismatch;
for (k = 0; k < j; k++) {
while ((*p != '\0') && (*p != '/')) p++;
if (*p == '\0') {
if (*q != '\0')
goto mismatch;
} else {
p++;
}
}
while((*q != '\0') && (*p != '\0') &&
(*p != '/') && (*p == *q)) p++, q++;
if (((*p != '\0') && *p != '/') || *q != '\0')
goto mismatch;
}
card_index = i;
break; /* done */
mismatch:
j = 0; /* dummy stmt to shut up compiler */
}
}
/*
This reads the card's CONFIG tuple to find its configuration
registers.
@ -509,12 +423,13 @@ static void atmel_config(dev_link_t *link)
((local_info_t*)link->priv)->eth_dev =
init_atmel_card(link->irq.AssignedIRQ,
link->io.BasePort1,
card_index == -1 ? ATMEL_FW_TYPE_NONE : card_table[card_index].firmware,
did ? did->driver_info : ATMEL_FW_TYPE_NONE,
&handle_to_dev(handle),
card_present,
link);
if (!((local_info_t*)link->priv)->eth_dev)
goto cs_failed;
goto cs_failed;
/*
At this point, the dev_node_t structure(s) need to be
@ -523,26 +438,7 @@ static void atmel_config(dev_link_t *link)
strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
dev->node.major = dev->node.minor = 0;
link->dev = &dev->node;
/* Finally, report what we've done */
printk(KERN_INFO "%s: %s%sindex 0x%02x: Vcc %d.%d",
dev->node.dev_name,
card_index == -1 ? "" : card_table[card_index].name,
card_index == -1 ? "" : " ",
link->conf.ConfigIndex,
link->conf.Vcc/10, link->conf.Vcc%10);
if (link->conf.Vpp1)
printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq.AssignedIRQ);
if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1);
if (link->io.NumPorts2)
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
link->io.BasePort2+link->io.NumPorts2-1);
printk("\n");
link->state &= ~DEV_CONFIG_PENDING;
return;
@ -569,7 +465,7 @@ static void atmel_release(dev_link_t *link)
link->dev = NULL;
if (dev)
stop_atmel_card(dev, 0);
stop_atmel_card(dev);
((local_info_t*)link->priv)->eth_dev = NULL;
/* Don't bother checking to see if these succeed or not */
@ -637,25 +533,47 @@ static int atmel_event(event_t event, int priority,
} /* atmel_event */
/*====================================================================*/
/* We use the driver_info field to store the correct firmware type for a card. */
#define PCMCIA_DEVICE_MANF_CARD_INFO(manf, card, info) { \
.match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
PCMCIA_DEV_ID_MATCH_CARD_ID, \
.manf_id = (manf), \
.card_id = (card), \
.driver_info = (kernel_ulong_t)(info), }
#define PCMCIA_DEVICE_PROD_ID12_INFO(v1, v2, vh1, vh2, info) { \
.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
PCMCIA_DEV_ID_MATCH_PROD_ID2, \
.prod_id = { (v1), (v2), NULL, NULL }, \
.prod_id_hash = { (vh1), (vh2), 0, 0 }, \
.driver_info = (kernel_ulong_t)(info), }
static struct pcmcia_device_id atmel_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0620),
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0696),
PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x3302),
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0007),
PCMCIA_DEVICE_PROD_ID12("11WAVE", "11WP611AL-E", 0x9eb2da1f, 0xc9a0d3f9),
PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C502AR", 0xabda4164, 0x41b37e1f),
PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C504", 0xabda4164, 0x5040670a),
PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C504A", 0xabda4164, 0xe15ed87f),
PCMCIA_DEVICE_PROD_ID12("BT", "Voyager 1020 Laptop Adapter", 0xae49b86a, 0x1e957cd5),
PCMCIA_DEVICE_PROD_ID12("CNet", "CNWLC 11Mbps Wireless PC Card V-5", 0xbc477dde, 0x502fae6b),
PCMCIA_DEVICE_PROD_ID12("IEEE 802.11b", "Wireless LAN PC Card", 0x5b878724, 0x122f1df6),
PCMCIA_DEVICE_PROD_ID12("OEM", "11Mbps Wireless LAN PC Card V-3", 0xfea54c90, 0x1c5b0f68),
PCMCIA_DEVICE_PROD_ID12("SMC", "2632W", 0xc4f8b18b, 0x30f38774),
PCMCIA_DEVICE_PROD_ID12("SMC", "2632W-V2", 0xc4f8b18b, 0x172d1377),
PCMCIA_DEVICE_PROD_ID12("Wireless", "PC", 0xa407ecdd, 0x556e4d7e),
PCMCIA_DEVICE_PROD_ID12("WLAN", "802.11b PC CARD", 0x575c516c, 0xb1f6dbc4),
PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0620, ATMEL_FW_TYPE_502_3COM),
PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0696, ATMEL_FW_TYPE_502_3COM),
PCMCIA_DEVICE_MANF_CARD_INFO(0x01bf, 0x3302, ATMEL_FW_TYPE_502E),
PCMCIA_DEVICE_MANF_CARD_INFO(0xd601, 0x0007, ATMEL_FW_TYPE_502),
PCMCIA_DEVICE_PROD_ID12_INFO("11WAVE", "11WP611AL-E", 0x9eb2da1f, 0xc9a0d3f9, ATMEL_FW_TYPE_502E),
PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR", 0xabda4164, 0x41b37e1f, ATMEL_FW_TYPE_502),
PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_D", 0xabda4164, 0x3675d704, ATMEL_FW_TYPE_502D),
PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_E", 0xabda4164, 0x4172e792, ATMEL_FW_TYPE_502E),
PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504_R", 0xabda4164, 0x917f3d72, ATMEL_FW_TYPE_504_2958),
PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504", 0xabda4164, 0x5040670a, ATMEL_FW_TYPE_504),
PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504A", 0xabda4164, 0xe15ed87f, ATMEL_FW_TYPE_504A_2958),
PCMCIA_DEVICE_PROD_ID12_INFO("BT", "Voyager 1020 Laptop Adapter", 0xae49b86a, 0x1e957cd5, ATMEL_FW_TYPE_502),
PCMCIA_DEVICE_PROD_ID12_INFO("CNet", "CNWLC 11Mbps Wireless PC Card V-5", 0xbc477dde, 0x502fae6b, ATMEL_FW_TYPE_502E),
PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN PC Card", 0x5b878724, 0x122f1df6, ATMEL_FW_TYPE_502),
PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN Card S", 0x5b878724, 0x5fba533a, ATMEL_FW_TYPE_504_2958),
PCMCIA_DEVICE_PROD_ID12_INFO("OEM", "11Mbps Wireless LAN PC Card V-3", 0xfea54c90, 0x1c5b0f68, ATMEL_FW_TYPE_502),
PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W", 0xc4f8b18b, 0x30f38774, ATMEL_FW_TYPE_502D),
PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W-V2", 0xc4f8b18b, 0x172d1377, ATMEL_FW_TYPE_502),
PCMCIA_DEVICE_PROD_ID12_INFO("Wireless", "PC_CARD", 0xa407ecdd, 0x119f6314, ATMEL_FW_TYPE_502D),
PCMCIA_DEVICE_PROD_ID12_INFO("WLAN", "802.11b PC CARD", 0x575c516c, 0xb1f6dbc4, ATMEL_FW_TYPE_502D),
PCMCIA_DEVICE_PROD_ID12_INFO("LG", "LW2100N", 0xb474d43a, 0x6b1fec94, ATMEL_FW_TYPE_502E),
PCMCIA_DEVICE_NULL
};
MODULE_DEVICE_TABLE(pcmcia, atmel_ids);
static struct pcmcia_driver atmel_driver = {

View File

@ -72,7 +72,7 @@ static int __devinit atmel_pci_probe(struct pci_dev *pdev,
static void __devexit atmel_pci_remove(struct pci_dev *pdev)
{
stop_atmel_card(pci_get_drvdata(pdev), 1);
stop_atmel_card(pci_get_drvdata(pdev));
}
static int __init atmel_init_module(void)

View File

@ -8,7 +8,7 @@
* Author(s): Original Code written by
* DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
* Rewritten by
* Frank Pavlic (pavlic@de.ibm.com) and
* Frank Pavlic (fpavlic@de.ibm.com) and
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*
* $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $
@ -2342,6 +2342,6 @@ __exit lcs_cleanup_module(void)
module_init(lcs_init_module);
module_exit(lcs_cleanup_module);
MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");
MODULE_LICENSE("GPL");

View File

@ -8,6 +8,7 @@
#include <linux/trdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/ctype.h>
#include <net/ipv6.h>
#include <linux/in6.h>
@ -24,7 +25,7 @@
#include "qeth_mpc.h"
#define VERSION_QETH_H "$Revision: 1.142 $"
#define VERSION_QETH_H "$Revision: 1.152 $"
#ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6"
@ -718,8 +719,6 @@ struct qeth_reply {
atomic_t refcnt;
};
#define QETH_BROADCAST_WITH_ECHO 1
#define QETH_BROADCAST_WITHOUT_ECHO 2
struct qeth_card_blkt {
int time_total;
@ -727,8 +726,10 @@ struct qeth_card_blkt {
int inter_packet_jumbo;
};
#define QETH_BROADCAST_WITH_ECHO 0x01
#define QETH_BROADCAST_WITHOUT_ECHO 0x02
#define QETH_LAYER2_MAC_READ 0x01
#define QETH_LAYER2_MAC_REGISTERED 0x02
struct qeth_card_info {
unsigned short unit_addr2;
unsigned short cula;
@ -736,7 +737,7 @@ struct qeth_card_info {
__u16 func_level;
char mcl_level[QETH_MCL_LENGTH + 1];
int guestlan;
int layer2_mac_registered;
int mac_bits;
int portname_required;
int portno;
char portname[9];
@ -749,6 +750,7 @@ struct qeth_card_info {
int unique_id;
struct qeth_card_blkt blkt;
__u32 csum_mask;
enum qeth_ipa_promisc_modes promisc_mode;
};
struct qeth_card_options {
@ -775,6 +777,7 @@ struct qeth_card_options {
enum qeth_threads {
QETH_SET_IP_THREAD = 1,
QETH_RECOVER_THREAD = 2,
QETH_SET_PROMISC_MODE_THREAD = 4,
};
struct qeth_osn_info {
@ -1074,6 +1077,26 @@ qeth_get_qdio_q_format(struct qeth_card *card)
}
}
static inline int
qeth_isdigit(char * buf)
{
while (*buf) {
if (!isdigit(*buf++))
return 0;
}
return 1;
}
static inline int
qeth_isxdigit(char * buf)
{
while (*buf) {
if (!isxdigit(*buf++))
return 0;
}
return 1;
}
static inline void
qeth_ipaddr4_to_string(const __u8 *addr, char *buf)
{
@ -1090,18 +1113,27 @@ qeth_string_to_ipaddr4(const char *buf, __u8 *addr)
int i;
start = buf;
for (i = 0; i < 3; i++) {
if (!(end = strchr(start, '.')))
for (i = 0; i < 4; i++) {
if (i == 3) {
end = strchr(start,0xa);
if (end)
len = end - start;
else
len = strlen(start);
}
else {
end = strchr(start, '.');
len = end - start;
}
if ((len <= 0) || (len > 3))
return -EINVAL;
len = end - start;
memset(abuf, 0, 4);
strncpy(abuf, start, len);
if (!qeth_isdigit(abuf))
return -EINVAL;
addr[i] = simple_strtoul(abuf, &tmp, 10);
start = end + 1;
}
memset(abuf, 0, 4);
strcpy(abuf, start);
addr[3] = simple_strtoul(abuf, &tmp, 10);
return 0;
}
@ -1128,18 +1160,27 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr)
tmp_addr = (u16 *)addr;
start = buf;
for (i = 0; i < 7; i++) {
if (!(end = strchr(start, ':')))
for (i = 0; i < 8; i++) {
if (i == 7) {
end = strchr(start,0xa);
if (end)
len = end - start;
else
len = strlen(start);
}
else {
end = strchr(start, ':');
len = end - start;
}
if ((len <= 0) || (len > 4))
return -EINVAL;
len = end - start;
memset(abuf, 0, 5);
strncpy(abuf, start, len);
if (!qeth_isxdigit(abuf))
return -EINVAL;
tmp_addr[i] = simple_strtoul(abuf, &tmp, 16);
start = end + 1;
}
memset(abuf, 0, 5);
strcpy(abuf, start);
tmp_addr[7] = simple_strtoul(abuf, &tmp, 16);
return 0;
}

View File

@ -1,6 +1,6 @@
/*
*
* linux/drivers/s390/net/qeth_main.c ($Revision: 1.224 $)
* linux/drivers/s390/net/qeth_main.c ($Revision: 1.242 $)
*
* Linux on zSeries OSA Express and HiperSockets support
*
@ -9,10 +9,10 @@
* Author(s): Original Code written by
* Utz Bacher (utz.bacher@de.ibm.com)
* Rewritten by
* Frank Pavlic (pavlic@de.ibm.com) and
* Frank Pavlic (fpavlic@de.ibm.com) and
* Thomas Spatzier <tspat@de.ibm.com>
*
* $Revision: 1.224 $ $Date: 2005/05/04 20:19:18 $
* $Revision: 1.242 $ $Date: 2005/05/04 20:19:18 $
*
* 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
@ -72,7 +72,7 @@
#include "qeth_eddp.h"
#include "qeth_tso.h"
#define VERSION_QETH_C "$Revision: 1.224 $"
#define VERSION_QETH_C "$Revision: 1.242 $"
static const char *version = "qeth S/390 OSA-Express driver";
/**
@ -159,6 +159,9 @@ qeth_get_addr_buffer(enum qeth_prot_versions);
static void
qeth_set_multicast_list(struct net_device *);
static void
qeth_setadp_promisc_mode(struct qeth_card *);
static void
qeth_notify_processes(void)
{
@ -602,11 +605,20 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
int found = 0;
list_for_each_entry(addr, &card->ip_list, entry) {
if (card->options.layer2) {
if ((addr->type == todo->type) &&
(memcmp(&addr->mac, &todo->mac,
OSA_ADDR_LEN) == 0)) {
found = 1;
break;
}
continue;
}
if ((addr->proto == QETH_PROT_IPV4) &&
(todo->proto == QETH_PROT_IPV4) &&
(addr->type == todo->type) &&
(addr->u.a4.addr == todo->u.a4.addr) &&
(addr->u.a4.mask == todo->u.a4.mask) ){
(addr->u.a4.mask == todo->u.a4.mask)) {
found = 1;
break;
}
@ -615,12 +627,12 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
(addr->type == todo->type) &&
(addr->u.a6.pfxlen == todo->u.a6.pfxlen) &&
(memcmp(&addr->u.a6.addr, &todo->u.a6.addr,
sizeof(struct in6_addr)) == 0)) {
sizeof(struct in6_addr)) == 0)) {
found = 1;
break;
}
}
if (found){
if (found) {
addr->users += todo->users;
if (addr->users <= 0){
*__addr = addr;
@ -632,7 +644,7 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
return 0;
}
}
if (todo->users > 0){
if (todo->users > 0) {
/* for VIPA and RXIP limit refcount to 1 */
if (todo->type != QETH_IP_TYPE_NORMAL)
todo->users = 1;
@ -682,12 +694,22 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
(tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
return 0;
if (card->options.layer2) {
if ((tmp->type == addr->type) &&
(tmp->is_multicast == addr->is_multicast) &&
(memcmp(&tmp->mac, &addr->mac,
OSA_ADDR_LEN) == 0)) {
found = 1;
break;
}
continue;
}
if ((tmp->proto == QETH_PROT_IPV4) &&
(addr->proto == QETH_PROT_IPV4) &&
(tmp->type == addr->type) &&
(tmp->is_multicast == addr->is_multicast) &&
(tmp->u.a4.addr == addr->u.a4.addr) &&
(tmp->u.a4.mask == addr->u.a4.mask) ){
(tmp->u.a4.mask == addr->u.a4.mask)) {
found = 1;
break;
}
@ -697,7 +719,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
(tmp->is_multicast == addr->is_multicast) &&
(tmp->u.a6.pfxlen == addr->u.a6.pfxlen) &&
(memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
sizeof(struct in6_addr)) == 0) ){
sizeof(struct in6_addr)) == 0)) {
found = 1;
break;
}
@ -707,7 +729,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
tmp->users += addr->users;
else
tmp->users += add? 1:-1;
if (tmp->users == 0){
if (tmp->users == 0) {
list_del(&tmp->entry);
kfree(tmp);
}
@ -738,12 +760,15 @@ qeth_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
unsigned long flags;
int rc = 0;
QETH_DBF_TEXT(trace,4,"delip");
if (addr->proto == QETH_PROT_IPV4)
QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4);
QETH_DBF_TEXT(trace, 4, "delip");
if (card->options.layer2)
QETH_DBF_HEX(trace, 4, &addr->mac, 6);
else if (addr->proto == QETH_PROT_IPV4)
QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
else {
QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8);
QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8);
QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
}
spin_lock_irqsave(&card->ip_lock, flags);
rc = __qeth_insert_ip_todo(card, addr, 0);
@ -757,12 +782,14 @@ qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
unsigned long flags;
int rc = 0;
QETH_DBF_TEXT(trace,4,"addip");
if (addr->proto == QETH_PROT_IPV4)
QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4);
QETH_DBF_TEXT(trace, 4, "addip");
if (card->options.layer2)
QETH_DBF_HEX(trace, 4, &addr->mac, 6);
else if (addr->proto == QETH_PROT_IPV4)
QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
else {
QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8);
QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8);
QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
}
spin_lock_irqsave(&card->ip_lock, flags);
rc = __qeth_insert_ip_todo(card, addr, 1);
@ -775,7 +802,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
{
struct qeth_ipaddr *addr, *tmp;
int rc;
again:
list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
if (addr->is_multicast) {
spin_unlock_irqrestore(&card->ip_lock, *flags);
@ -784,6 +811,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
if (!rc) {
list_del(&addr->entry);
kfree(addr);
goto again;
}
}
}
@ -851,6 +879,7 @@ qeth_set_ip_addr_list(struct qeth_card *card)
static void qeth_delete_mc_addresses(struct qeth_card *);
static void qeth_add_multicast_ipv4(struct qeth_card *);
static void qeth_layer2_add_multicast(struct qeth_card *);
#ifdef CONFIG_QETH_IPV6
static void qeth_add_multicast_ipv6(struct qeth_card *);
#endif
@ -939,6 +968,24 @@ qeth_register_ip_addresses(void *ptr)
return 0;
}
/*
* Drive the SET_PROMISC_MODE thread
*/
static int
qeth_set_promisc_mode(void *ptr)
{
struct qeth_card *card = (struct qeth_card *) ptr;
daemonize("qeth_setprm");
QETH_DBF_TEXT(trace,4,"setprm1");
if (!qeth_do_run_thread(card, QETH_SET_PROMISC_MODE_THREAD))
return 0;
QETH_DBF_TEXT(trace,4,"setprm2");
qeth_setadp_promisc_mode(card);
qeth_clear_thread_running_bit(card, QETH_SET_PROMISC_MODE_THREAD);
return 0;
}
static int
qeth_recover(void *ptr)
{
@ -1005,6 +1052,8 @@ qeth_start_kernel_thread(struct qeth_card *card)
if (qeth_do_start_thread(card, QETH_SET_IP_THREAD))
kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD);
if (qeth_do_start_thread(card, QETH_SET_PROMISC_MODE_THREAD))
kernel_thread(qeth_set_promisc_mode, (void *)card, SIGCHLD);
if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
kernel_thread(qeth_recover, (void *) card, SIGCHLD);
}
@ -3749,7 +3798,7 @@ qeth_open(struct net_device *dev)
if ( (card->info.type != QETH_CARD_TYPE_OSN) &&
(card->options.layer2) &&
(!card->info.layer2_mac_registered)) {
(!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) {
QETH_DBF_TEXT(trace,4,"nomacadr");
return -EPERM;
}
@ -4311,6 +4360,8 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
out:
if (flush_count)
qeth_flush_buffers(queue, 0, start_index, flush_count);
else if (!atomic_read(&queue->set_pci_flags_count))
atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
/*
* queue->state will go from LOCKED -> UNLOCKED or from
* LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us
@ -4975,6 +5026,10 @@ qeth_default_setassparms_cb(struct qeth_card *, struct qeth_reply *,
unsigned long);
static int
qeth_default_setadapterparms_cb(struct qeth_card *card,
struct qeth_reply *reply,
unsigned long data);
static int
qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *,
__u16, long,
int (*reply_cb)
@ -5301,8 +5356,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid)
struct qeth_ipaddr *addr;
QETH_DBF_TEXT(trace, 4, "frvaddr4");
if (!card->vlangrp)
return;
rcu_read_lock();
in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]);
if (!in_dev)
@ -5330,8 +5384,7 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
struct qeth_ipaddr *addr;
QETH_DBF_TEXT(trace, 4, "frvaddr6");
if (!card->vlangrp)
return;
in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]);
if (!in6_dev)
return;
@ -5351,10 +5404,38 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
}
static void
qeth_free_vlan_addresses(struct qeth_card *card, unsigned short vid)
{
if (card->options.layer2 || !card->vlangrp)
return;
qeth_free_vlan_addresses4(card, vid);
qeth_free_vlan_addresses6(card, vid);
}
static int
qeth_layer2_send_setdelvlan_cb(struct qeth_card *card,
struct qeth_reply *reply,
unsigned long data)
{
struct qeth_ipa_cmd *cmd;
QETH_DBF_TEXT(trace, 2, "L2sdvcb");
cmd = (struct qeth_ipa_cmd *) data;
if (cmd->hdr.return_code) {
PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
"Continuing\n",cmd->data.setdelvlan.vlan_id,
QETH_CARD_IFNAME(card), cmd->hdr.return_code);
QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command);
QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
}
return 0;
}
static int
qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
enum qeth_ipa_cmds ipacmd)
{
int rc;
struct qeth_ipa_cmd *cmd;
struct qeth_cmd_buffer *iob;
@ -5362,15 +5443,8 @@ qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
cmd->data.setdelvlan.vlan_id = i;
rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
if (rc) {
PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
"Continuing\n",i, QETH_CARD_IFNAME(card), rc);
QETH_DBF_TEXT_(trace, 2, "L2VL%4x", ipacmd);
QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
QETH_DBF_TEXT_(trace, 2, "err%d", rc);
}
return qeth_send_ipa_cmd(card, iob,
qeth_layer2_send_setdelvlan_cb, NULL);
}
static void
@ -5420,8 +5494,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
qeth_free_vlan_skbs(card, vid);
spin_lock_irqsave(&card->vlanlock, flags);
/* unregister IP addresses of vlan device */
qeth_free_vlan_addresses4(card, vid);
qeth_free_vlan_addresses6(card, vid);
qeth_free_vlan_addresses(card, vid);
if (card->vlangrp)
card->vlangrp->vlan_devices[vid] = NULL;
spin_unlock_irqrestore(&card->vlanlock, flags);
@ -5430,6 +5503,59 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
qeth_set_multicast_list(card->dev);
}
#endif
/**
* Examine hardware response to SET_PROMISC_MODE
*/
static int
qeth_setadp_promisc_mode_cb(struct qeth_card *card,
struct qeth_reply *reply,
unsigned long data)
{
struct qeth_ipa_cmd *cmd;
struct qeth_ipacmd_setadpparms *setparms;
QETH_DBF_TEXT(trace,4,"prmadpcb");
cmd = (struct qeth_ipa_cmd *) data;
setparms = &(cmd->data.setadapterparms);
qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
if (cmd->hdr.return_code) {
QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);
setparms->data.mode = SET_PROMISC_MODE_OFF;
}
card->info.promisc_mode = setparms->data.mode;
return 0;
}
/*
* Set promiscuous mode (on or off) (SET_PROMISC_MODE command)
*/
static void
qeth_setadp_promisc_mode(struct qeth_card *card)
{
enum qeth_ipa_promisc_modes mode;
struct net_device *dev = card->dev;
struct qeth_cmd_buffer *iob;
struct qeth_ipa_cmd *cmd;
QETH_DBF_TEXT(trace, 4, "setprom");
if (((dev->flags & IFF_PROMISC) &&
(card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
(!(dev->flags & IFF_PROMISC) &&
(card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
return;
mode = SET_PROMISC_MODE_OFF;
if (dev->flags & IFF_PROMISC)
mode = SET_PROMISC_MODE_ON;
QETH_DBF_TEXT_(trace, 4, "mode:%x", mode);
iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
sizeof(struct qeth_ipacmd_setadpparms));
cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
cmd->data.setadapterparms.data.mode = mode;
qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
}
/**
* set multicast address on card
@ -5444,12 +5570,22 @@ qeth_set_multicast_list(struct net_device *dev)
QETH_DBF_TEXT(trace,3,"setmulti");
qeth_delete_mc_addresses(card);
if (card->options.layer2) {
qeth_layer2_add_multicast(card);
goto out;
}
qeth_add_multicast_ipv4(card);
#ifdef CONFIG_QETH_IPV6
qeth_add_multicast_ipv6(card);
#endif
out:
if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
schedule_work(&card->kernel_thread_starter);
if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
return;
if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0)
schedule_work(&card->kernel_thread_starter);
}
static int
@ -5657,6 +5793,24 @@ qeth_add_multicast_ipv4(struct qeth_card *card)
in_dev_put(in4_dev);
}
static void
qeth_layer2_add_multicast(struct qeth_card *card)
{
struct qeth_ipaddr *ipm;
struct dev_mc_list *dm;
QETH_DBF_TEXT(trace,4,"L2addmc");
for (dm = card->dev->mc_list; dm; dm = dm->next) {
ipm = qeth_get_addr_buffer(QETH_PROT_IPV4);
if (!ipm)
continue;
memcpy(ipm->mac,dm->dmi_addr,MAX_ADDR_LEN);
ipm->is_multicast = 1;
if (!qeth_add_ip(card, ipm))
kfree(ipm);
}
}
#ifdef CONFIG_QETH_IPV6
static inline void
qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
@ -5825,10 +5979,10 @@ qeth_layer2_send_setmac_cb(struct qeth_card *card,
PRINT_WARN("Error in registering MAC address on " \
"device %s: x%x\n", CARD_BUS_ID(card),
cmd->hdr.return_code);
card->info.layer2_mac_registered = 0;
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
cmd->hdr.return_code = -EIO;
} else {
card->info.layer2_mac_registered = 1;
card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac,
OSA_ADDR_LEN);
PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
@ -5866,7 +6020,7 @@ qeth_layer2_send_delmac_cb(struct qeth_card *card,
cmd->hdr.return_code = -EIO;
return 0;
}
card->info.layer2_mac_registered = 0;
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
return 0;
}
@ -5874,7 +6028,7 @@ static int
qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac)
{
QETH_DBF_TEXT(trace, 2, "L2Delmac");
if (!card->info.layer2_mac_registered)
if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
return 0;
return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC,
qeth_layer2_send_delmac_cb);
@ -5896,7 +6050,7 @@ qeth_layer2_set_mac_address(struct net_device *dev, void *p)
card = (struct qeth_card *) dev->priv;
if (!card->options.layer2) {
PRINT_WARN("Setting MAC address on %s is not supported"
PRINT_WARN("Setting MAC address on %s is not supported "
"in Layer 3 mode.\n", dev->name);
QETH_DBF_TEXT(trace, 3, "setmcLY3");
return -EOPNOTSUPP;
@ -6441,6 +6595,8 @@ qeth_default_setadapterparms_cb(struct qeth_card *card,
return 0;
}
static int
qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply,
unsigned long data)
@ -6481,8 +6637,13 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
QETH_DBF_TEXT(trace,4,"chgmaccb");
cmd = (struct qeth_ipa_cmd *) data;
memcpy(card->dev->dev_addr,
&cmd->data.setadapterparms.data.change_addr.addr,OSA_ADDR_LEN);
if (!card->options.layer2 || card->info.guestlan ||
!(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
memcpy(card->dev->dev_addr,
&cmd->data.setadapterparms.data.change_addr.addr,
OSA_ADDR_LEN);
card->info.mac_bits |= QETH_LAYER2_MAC_READ;
}
qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
return 0;
}
@ -6602,6 +6763,12 @@ qeth_layer2_initialize(struct qeth_card *card)
QETH_DBF_TEXT(setup, 2, "doL2init");
QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card));
rc = qeth_query_setadapterparms(card);
if (rc) {
PRINT_WARN("could not query adapter parameters on device %s: "
"x%x\n", CARD_BUS_ID(card), rc);
}
rc = qeth_setadpparms_change_macaddr(card);
if (rc) {
PRINT_WARN("couldn't get MAC address on "
@ -8548,7 +8715,7 @@ EXPORT_SYMBOL(qeth_osn_deregister);
EXPORT_SYMBOL(qeth_osn_assist);
module_init(qeth_init);
module_exit(qeth_exit);
MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");
MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \
"Copyright 2000,2003 IBM Corporation\n");

View File

@ -4,7 +4,7 @@
* Linux on zSeries OSA Express and HiperSockets support
*
* Copyright 2000,2003 IBM Corporation
* Author(s): Frank Pavlic <pavlic@de.ibm.com>
* Author(s): Frank Pavlic <fpavlic@de.ibm.com>
* Thomas Spatzier <tspat@de.ibm.com>
*
*/

View File

@ -6,7 +6,7 @@
* Copyright 2000,2003 IBM Corporation
* Author(s): Utz Bacher <utz.bacher@de.ibm.com>
* Thomas Spatzier <tspat@de.ibm.com>
* Frank Pavlic <pavlic@de.ibm.com>
* Frank Pavlic <fpavlic@de.ibm.com>
*
*/
#ifndef __QETH_MPC_H__
@ -14,7 +14,7 @@
#include <asm/qeth.h>
#define VERSION_QETH_MPC_H "$Revision: 1.43 $"
#define VERSION_QETH_MPC_H "$Revision: 1.44 $"
extern const char *VERSION_QETH_MPC_C;
@ -217,7 +217,7 @@ enum qeth_ipa_setadp_cmd {
IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
IPA_SETADP_READ_SNMP_PARMS = 0x0400,
IPA_SETADP_WRITE_SNMP_PARMS = 0x0800,
IPA_SETADP_SET_PROMISC_MODE = 0x0800,
IPA_SETADP_QUERY_CARD_INFO = 0x1000,
};
enum qeth_ipa_mac_ops {
@ -232,9 +232,12 @@ enum qeth_ipa_addr_ops {
CHANGE_ADDR_ADD_ADDR = 1,
CHANGE_ADDR_DEL_ADDR = 2,
CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
};
enum qeth_ipa_promisc_modes {
SET_PROMISC_MODE_OFF = 0,
SET_PROMISC_MODE_ON = 1,
};
/* (SET)DELIP(M) IPA stuff ***************************************************/
struct qeth_ipacmd_setdelip4 {
__u8 ip_addr[4];

View File

@ -1,6 +1,6 @@
/*
*
* linux/drivers/s390/net/qeth_sys.c ($Revision: 1.55 $)
* linux/drivers/s390/net/qeth_sys.c ($Revision: 1.58 $)
*
* Linux on zSeries OSA Express and HiperSockets support
* This file contains code related to sysfs.
@ -8,7 +8,7 @@
* Copyright 2000,2003 IBM Corporation
*
* Author(s): Thomas Spatzier <tspat@de.ibm.com>
* Frank Pavlic <pavlic@de.ibm.com>
* Frank Pavlic <fpavlic@de.ibm.com>
*
*/
#include <linux/list.h>
@ -20,7 +20,7 @@
#include "qeth_mpc.h"
#include "qeth_fs.h"
const char *VERSION_QETH_SYS_C = "$Revision: 1.55 $";
const char *VERSION_QETH_SYS_C = "$Revision: 1.58 $";
/*****************************************************************************/
/* */
@ -1117,7 +1117,7 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
start = buf;
/* get address string */
end = strchr(start, '/');
if (!end){
if (!end || (end-start >= 49)){
PRINT_WARN("Invalid format for ipato_addx/delx. "
"Use <ip addr>/<mask bits>\n");
return -EINVAL;

View File

@ -5,7 +5,7 @@
*
* Copyright 2004 IBM Corporation
*
* Author(s): Frank Pavlic <pavlic@de.ibm.com>
* Author(s): Frank Pavlic <fpavlic@de.ibm.com>
*
* $Revision: 1.7 $ $Date: 2005/05/04 20:19:18 $
*