summaryrefslogtreecommitdiffstats
path: root/drivers/net/wan
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-21 22:34:01 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-21 22:34:01 +0000
commit9e30c3705aed9fbec4c3304570e4d6e707856bcb (patch)
treeb19e6acb5a67af31a4e7742e05c2166dc3f1444c /drivers/net/wan
parent72919904796333a20c6a5d5c380091b42e407aa9 (diff)
Merge with Linux 2.3.22.
Diffstat (limited to 'drivers/net/wan')
-rw-r--r--drivers/net/wan/cosa.c74
-rw-r--r--drivers/net/wan/cycx_x25.c50
-rw-r--r--drivers/net/wan/sbni.c20
3 files changed, 92 insertions, 52 deletions
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 863cd4b59..a48c5d31c 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -1,4 +1,4 @@
-/* $Id: cosa.c,v 1.26 1999/07/09 15:02:37 kas Exp $ */
+/* $Id: cosa.c,v 1.28 1999/10/11 21:06:58 kas Exp $ */
/*
* Copyright (C) 1995-1997 Jan "Yenya" Kasprzak <kas@fi.muni.cz>
@@ -137,8 +137,7 @@ struct channel_data {
struct semaphore rsem, wsem;
char *rxdata;
int rxsize;
- wait_queue_head_t txwaitq;
- wait_queue_head_t rxwaitq;
+ wait_queue_head_t txwaitq, rxwaitq;
int tx_status, rx_status;
/* SPPP/HDLC device parts */
@@ -147,6 +146,11 @@ struct channel_data {
struct net_device_stats stats;
};
+/* cosa->firmware_status bits */
+#define COSA_FW_RESET (1<<0) /* Is the ROM monitor active? */
+#define COSA_FW_DOWNLOAD (1<<1) /* Is the microcode downloaded? */
+#define COSA_FW_START (1<<2) /* Is the microcode running? */
+
struct cosa_data {
int num; /* Card number */
char name[COSA_MAX_NAME]; /* Card name - e.g "cosa0" */
@@ -606,6 +610,11 @@ static int cosa_sppp_open(struct net_device *d)
struct channel_data *chan = d->priv;
int err, flags;
+ if (!(chan->cosa->firmware_status & COSA_FW_START)) {
+ printk(KERN_NOTICE "%s: start the firmware first (status %d)\n",
+ chan->cosa->name, chan->cosa->firmware_status);
+ return -EPERM;
+ }
spin_lock_irqsave(&chan->cosa->lock, flags);
if (chan->usage != 0) {
printk(KERN_WARNING "%s: sppp_open called with usage count %d\n",
@@ -781,6 +790,11 @@ static ssize_t cosa_read(struct file *file,
struct cosa_data *cosa = chan->cosa;
char *kbuf;
+ if (!(cosa->firmware_status & COSA_FW_START)) {
+ printk(KERN_NOTICE "%s: start the firmware first (status %d)\n",
+ cosa->name, cosa->firmware_status);
+ return -EPERM;
+ }
if (down_interruptible(&chan->rsem))
return -ERESTARTSYS;
@@ -845,12 +859,17 @@ static int chrdev_rx_done(struct channel_data *chan)
static ssize_t cosa_write(struct file *file,
const char *buf, size_t count, loff_t *ppos)
{
- struct channel_data *chan = (struct channel_data *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
+ struct channel_data *chan = (struct channel_data *)file->private_data;
struct cosa_data *cosa = chan->cosa;
unsigned int flags;
char *kbuf;
+ if (!(cosa->firmware_status & COSA_FW_START)) {
+ printk(KERN_NOTICE "%s: start the firmware first (status %d)\n",
+ cosa->name, cosa->firmware_status);
+ return -EPERM;
+ }
if (down_interruptible(&chan->wsem))
return -ERESTARTSYS;
@@ -992,12 +1011,14 @@ static inline int cosa_reset(struct cosa_data *cosa)
if (cosa->usage > 1)
printk(KERN_INFO "cosa%d: WARNING: reset requested with cosa->usage > 1 (%d). Odd things may happen.\n",
cosa->num, cosa->usage);
+ cosa->firmware_status &= ~(COSA_FW_RESET|COSA_FW_START);
if (cosa_reset_and_read_id(cosa, idstring) < 0) {
printk(KERN_NOTICE "cosa%d: reset failed\n", cosa->num);
return -EIO;
}
printk(KERN_INFO "cosa%d: resetting device: %s\n", cosa->num,
idstring);
+ cosa->firmware_status |= COSA_FW_RESET;
return 0;
}
@@ -1009,15 +1030,14 @@ static inline int cosa_download(struct cosa_data *cosa, struct cosa_download *d)
char *code;
if (cosa->usage > 1)
- printk(KERN_INFO "cosa%d: WARNING: download of microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n",
- cosa->num, cosa->usage);
-#if 0
- if (cosa->status != CARD_STATUS_RESETED && cosa->status != CARD_STATUS_DOWNLOADED) {
- printk(KERN_NOTICE "cosa%d: reset the card first (status %d).\n",
- cosa->num, cosa->status);
+ printk(KERN_INFO "%s: WARNING: download of microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n",
+ cosa->name, cosa->usage);
+ if (!(cosa->firmware_status & COSA_FW_RESET)) {
+ printk(KERN_NOTICE "%s: reset the card first (status %d).\n",
+ cosa->name, cosa->firmware_status);
return -EPERM;
}
-#endif
+
get_user_ret(addr, &(d->addr), -EFAULT);
get_user_ret(len, &(d->len), -EFAULT);
get_user_ret(code, &(d->code), -EFAULT);
@@ -1027,6 +1047,9 @@ static inline int cosa_download(struct cosa_data *cosa, struct cosa_download *d)
if (d->len < 0 || d->len > COSA_MAX_FIRMWARE_SIZE)
return -EINVAL;
+ /* If something fails, force the user to reset the card */
+ cosa->firmware_status &= ~(COSA_FW_RESET|COSA_FW_DOWNLOAD);
+
if ((i=download(cosa, d->code, len, addr)) < 0) {
printk(KERN_NOTICE "cosa%d: microcode download failed: %d\n",
cosa->num, i);
@@ -1034,6 +1057,7 @@ static inline int cosa_download(struct cosa_data *cosa, struct cosa_download *d)
}
printk(KERN_INFO "cosa%d: downloading microcode - 0x%04x bytes at 0x%04x\n",
cosa->num, len, addr);
+ cosa->firmware_status |= COSA_FW_RESET|COSA_FW_DOWNLOAD;
return 0;
}
@@ -1048,18 +1072,19 @@ static inline int cosa_readmem(struct cosa_data *cosa, struct cosa_download *d)
printk(KERN_INFO "cosa%d: WARNING: readmem requested with "
"cosa->usage > 1 (%d). Odd things may happen.\n",
cosa->num, cosa->usage);
-#if 0
- if (cosa->status != CARD_STATUS_RESETED &&
- cosa->status != CARD_STATUS_DOWNLOADED) {
- printk(KERN_NOTICE "cosa%d: reset the card first (status %d).\n",
- cosa->num, cosa->status);
+ if (!(cosa->firmware_status & COSA_FW_RESET)) {
+ printk(KERN_NOTICE "%s: reset the card first (status %d).\n",
+ cosa->name, cosa->firmware_status);
return -EPERM;
}
-#endif
+
get_user_ret(addr, &(d->addr), -EFAULT);
get_user_ret(len, &(d->len), -EFAULT);
get_user_ret(code, &(d->code), -EFAULT);
+ /* If something fails, force the user to reset the card */
+ cosa->firmware_status &= ~COSA_FW_RESET;
+
if ((i=readmem(cosa, d->code, len, addr)) < 0) {
printk(KERN_NOTICE "cosa%d: reading memory failed: %d\n",
cosa->num, i);
@@ -1067,6 +1092,7 @@ static inline int cosa_readmem(struct cosa_data *cosa, struct cosa_download *d)
}
printk(KERN_INFO "cosa%d: reading card memory - 0x%04x bytes at 0x%04x\n",
cosa->num, len, addr);
+ cosa->firmware_status |= COSA_FW_RESET;
return 0;
}
@@ -1078,13 +1104,14 @@ static inline int cosa_start(struct cosa_data *cosa, int address)
if (cosa->usage > 1)
printk(KERN_INFO "cosa%d: WARNING: start microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n",
cosa->num, cosa->usage);
-#if 0
- if (cosa->status != CARD_STATUS_DOWNLOADED) {
- printk(KERN_NOTICE "cosa%d: download the microcode first (status %d).\n",
- cosa->num, cosa->status);
+
+ if ((cosa->firmware_status & (COSA_FW_RESET|COSA_FW_DOWNLOAD))
+ != (COSA_FW_RESET|COSA_FW_DOWNLOAD)) {
+ printk(KERN_NOTICE "%s: download the microcode and/or reset the card first (status %d).\n",
+ cosa->name, cosa->firmware_status);
return -EPERM;
}
-#endif
+ cosa->firmware_status &= ~COSA_FW_RESET;
if ((i=startmicrocode(cosa, address)) < 0) {
printk(KERN_NOTICE "cosa%d: start microcode at 0x%04x failed: %d\n",
cosa->num, address, i);
@@ -1093,6 +1120,7 @@ static inline int cosa_start(struct cosa_data *cosa, int address)
printk(KERN_INFO "cosa%d: starting microcode at 0x%04x\n",
cosa->num, address);
cosa->startaddr = address;
+ cosa->firmware_status |= COSA_FW_START;
return 0;
}
@@ -1689,9 +1717,11 @@ static inline void tx_interrupt(struct cosa_data *cosa, int status)
/* in second pass, accept first ready-to-TX channel */
if (i > cosa->nchannels) {
/* Can be safely ignored */
+#ifdef DEBUG_IRQS
printk(KERN_DEBUG "%s: Forcing TX "
"to not-ready channel %d\n",
cosa->name, cosa->txchan);
+#endif
break;
}
}
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 7e79943c0..40f76b2a5 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -11,6 +11,10 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
+* 1999/10/09 acme chan_disc renamed to chan_disconnect,
+* began adding support for X.25 sockets:
+* conf->protocol in new_if
+* 1999/10/05 acme fixed return E... to return -E...
* 1999/08/10 acme serialized access to the card thru a spinlock
* in x25_exec
* 1999/08/09 acme removed per channel spinlocks
@@ -132,16 +136,19 @@ static int x25_configure (cycx_t *card, TX25Config *conf),
x25_connect_response (cycx_t *card, x25_channel_t *chan),
x25_disconnect_response (cycx_t *card, u8 link, u8 lcn);
-/* Miscellaneous functions */
-static int chan_connect (struct net_device *dev),
- chan_send (struct net_device *dev, struct sk_buff *skb);
+/* channel functions */
+int chan_connect (struct net_device *dev),
+ chan_send (struct net_device *dev, struct sk_buff *skb);
+
+static void chan_disconnect (struct net_device *dev);
+/* Miscellaneous functions */
static void set_chan_state (struct net_device *dev, u8 state),
- nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble),
- reset_timer (struct net_device *dev),
- chan_disc (struct net_device *dev),
chan_timer (unsigned long d);
+static void nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble),
+ reset_timer (struct net_device *dev);
+
static u8 bps_to_speed_code (u32 bps);
static u8 log2 (u32 n);
@@ -334,7 +341,7 @@ static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *c
strcpy(chan->name, conf->name);
chan->card = card;
chan->link = conf->port;
- chan->protocol = ETH_P_IP;
+ chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
chan->rx_skb = NULL;
/* only used in svc connected thru crossover cable */
chan->local_addr = NULL;
@@ -353,7 +360,7 @@ static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *c
if (!chan->local_addr) {
kfree(chan);
- return ENOMEM;
+ return -ENOMEM;
}
}
@@ -505,7 +512,7 @@ static int if_close (struct net_device *dev)
dev->start = 0;
if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
- chan_disc(dev);
+ chan_disconnect(dev);
cyclomx_close(card);
return 0;
@@ -763,7 +770,7 @@ static void rx_intr (cycx_t *card, TX25Cmd *cmd)
dev->last_rx = jiffies; /* timestamp */
chan->rx_skb = NULL; /* dequeue packet */
- skb->protocol = htons(ETH_P_IP);
+ skb->protocol = htons(chan->protocol);
skb->dev = dev;
skb->mac.raw = skb->data;
netif_rx(skb);
@@ -799,6 +806,7 @@ static void connect_intr (cycx_t *card, TX25Cmd *cmd)
dprintk(KERN_INFO "connect_intr:lcn=%d, local=%s, remote=%s\n",
lcn, loc, rem);
+
if ((dev = get_dev_by_dte_addr(wandev, rem)) == NULL) {
/* Invalid channel, discard packet */
printk(KERN_INFO "%s: connect not expected: remote %s!\n",
@@ -824,6 +832,7 @@ static void connect_confirm_intr (cycx_t *card, TX25Cmd *cmd)
cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
dprintk(KERN_INFO "%s: connect_confirm_intr:lcn=%d, key=%d\n",
card->devname, lcn, key);
+
if ((dev = get_dev_by_lcn(wandev, -key)) == NULL) {
/* Invalid channel, discard packet */
clear_bit(--key, (void*)&card->u.x.connection_keys);
@@ -1139,10 +1148,8 @@ static int x25_place_call (cycx_t *card, x25_channel_t *chan)
if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
&d, 7 + len + 1, NULL, 0)) != 0)
clear_bit(--key, (void*)&card->u.x.connection_keys);
- else {
+ else
chan->lcn = -key;
- chan->protocol = ETH_P_IP;
- }
return err;
}
@@ -1229,7 +1236,7 @@ static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte)
* Return: 0 connected
* >0 connection in progress
* <0 failure */
-static int chan_connect (struct net_device *dev)
+int chan_connect (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
@@ -1251,7 +1258,7 @@ static int chan_connect (struct net_device *dev)
/* Disconnect logical channel.
* o if SVC then clear X.25 call */
-static void chan_disc (struct net_device *dev)
+static void chan_disconnect (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
@@ -1270,7 +1277,7 @@ static void chan_timer (unsigned long d)
switch (chan->state) {
case WAN_CONNECTED:
- chan_disc(dev);
+ chan_disconnect(dev);
break;
default:
printk (KERN_ERR "%s: chan_timer for svc (%s) not "
@@ -1345,7 +1352,7 @@ static void set_chan_state (struct net_device *dev, u8 state)
* the packet into 'complete sequence' using M-bit.
* 2. When transmission is complete, an event notification should be issued
* to the router. */
-static int chan_send (struct net_device *dev, struct sk_buff *skb)
+int chan_send (struct net_device *dev, struct sk_buff *skb)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
@@ -1473,14 +1480,15 @@ static void x25_dump_devs(wan_device_t *wandev)
struct net_device *dev = wandev->dev;
printk (KERN_INFO "x25 dev states\n");
- printk (KERN_INFO "name: addr: tbusy:\n");
- printk (KERN_INFO "----------------------------\n");
+ printk (KERN_INFO "name: addr: tbusy: protocol:\n");
+ printk (KERN_INFO "---------------------------------------\n");
for (; dev; dev = dev->slave) {
x25_channel_t *chan = dev->priv;
- printk (KERN_INFO "%-5.5s %-15.15s %ld\n",
- chan->name, chan->addr, dev->tbusy);
+ printk (KERN_INFO "%-5.5s %-15.15s %ld ETH_P_%s\n",
+ chan->name, chan->addr, dev->tbusy,
+ chan->protocol == ETH_P_IP ? "IP" : "X25");
}
}
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 9d5fba082..4cf0c05a1 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -1280,10 +1280,12 @@ static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EPERM;
if(copy_from_user( tmpstr, ifr->ifr_data, 6))
return -EFAULT;
- slave=dev_get(tmpstr);
+ slave = dev_get_by_name(tmpstr);
if(!(slave && slave->flags & IFF_UP && dev->flags & IFF_UP))
{
printk("%s: Both devices should be UP to enslave!\n",dev->name);
+ if (slave)
+ dev_put(slave);
return -EINVAL;
}
@@ -1304,8 +1306,9 @@ static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
else
{
printk("%s: one of devices is already slave!\n",dev->name);
- return -EBUSY;
+ error = -EBUSY;
}
+ dev_put(slave);
}
else
{
@@ -1359,7 +1362,7 @@ static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
unsigned long calc_crc(char *mem, int len, unsigned initial)
{
-
+ unsigned crc, dummy_len;
__asm__ (
"xorl %%eax,%%eax\n\t"
"1:\n\t"
@@ -1367,13 +1370,12 @@ unsigned long calc_crc(char *mem, int len, unsigned initial)
"xorb %%dl,%%al\n\t"
"shrl $8,%%edx\n\t"
"xorl (%%edi,%%eax,4),%%edx\n\t"
- "loop 1b\n\t"
- "movl %%edx,%%eax"
- :
- : "S" (mem), "D" (&crc32tab[0]), "c" (len), "d" (initial)
- : "eax", "edx", "ecx"
+ "loop 1b"
+ : "=d" (crc), "=c" (dummy_len)
+ : "S" (mem), "D" (&crc32tab[0]), "1" (len), "0" (initial)
+ : "eax"
);
- /* return crc; */
+ return crc;
}
#else