Small changes to make it work with 2.1.x kernels. Hopefully,
nothing major will change before official release of Linux 2.2.
-
+
Merged with 2.2 - Alan Cox
*/
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#ifdef SB1000_DEBUG
static int sb1000_debug = SB1000_DEBUG;
#else
-static int sb1000_debug = 1;
+static const int sb1000_debug = 1;
#endif
static const int SB1000_IO_EXTENT = 8;
unsigned char rx_session_id[NPIDS];
unsigned char rx_frame_id[NPIDS];
unsigned char rx_pkt_type[NPIDS];
- struct net_device_stats stats;
};
/* prototypes for Linux interface */
extern int sb1000_probe(struct net_device *dev);
static int sb1000_open(struct net_device *dev);
static int sb1000_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd);
-static int sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static struct net_device_stats *sb1000_stats(struct net_device *dev);
+static netdev_tx_t sb1000_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
+static irqreturn_t sb1000_interrupt(int irq, void *dev_id);
static int sb1000_close(struct net_device *dev);
/* SB1000 hardware routines to be used during open/configuration phases */
-static inline void nicedelay(unsigned long usecs);
-static inline int card_wait_for_busy_clear(const int ioaddr[],
+static int card_wait_for_busy_clear(const int ioaddr[],
const char* name);
-static inline int card_wait_for_ready(const int ioaddr[], const char* name,
+static int card_wait_for_ready(const int ioaddr[], const char* name,
unsigned char in[]);
-static inline int card_send_command(const int ioaddr[], const char* name,
+static int card_send_command(const int ioaddr[], const char* name,
const unsigned char out[], unsigned char in[]);
/* SB1000 hardware routines to be used during frame rx interrupt */
-static inline int sb1000_wait_for_ready(const int ioaddr[], const char* name);
-static inline int sb1000_wait_for_ready_clear(const int ioaddr[],
+static int sb1000_wait_for_ready(const int ioaddr[], const char* name);
+static int sb1000_wait_for_ready_clear(const int ioaddr[],
const char* name);
-static inline void sb1000_send_command(const int ioaddr[], const char* name,
+static void sb1000_send_command(const int ioaddr[], const char* name,
const unsigned char out[]);
-static inline void sb1000_read_status(const int ioaddr[], unsigned char in[]);
-static inline void sb1000_issue_read_command(const int ioaddr[],
+static void sb1000_read_status(const int ioaddr[], unsigned char in[]);
+static void sb1000_issue_read_command(const int ioaddr[],
const char* name);
/* SB1000 commands for open/configuration */
-static inline int sb1000_reset(const int ioaddr[], const char* name);
-static inline int sb1000_check_CRC(const int ioaddr[], const char* name);
+static int sb1000_reset(const int ioaddr[], const char* name);
+static int sb1000_check_CRC(const int ioaddr[], const char* name);
static inline int sb1000_start_get_set_command(const int ioaddr[],
const char* name);
-static inline int sb1000_end_get_set_command(const int ioaddr[],
+static int sb1000_end_get_set_command(const int ioaddr[],
const char* name);
-static inline int sb1000_activate(const int ioaddr[], const char* name);
+static int sb1000_activate(const int ioaddr[], const char* name);
static int sb1000_get_firmware_version(const int ioaddr[],
const char* name, unsigned char version[], int do_end);
static int sb1000_get_frequency(const int ioaddr[], const char* name,
const short PID[]);
/* SB1000 commands for frame rx interrupt */
-static inline int sb1000_rx(struct net_device *dev);
-static inline void sb1000_error_dpc(struct net_device *dev);
+static int sb1000_rx(struct net_device *dev);
+static void sb1000_error_dpc(struct net_device *dev);
static const struct pnp_device_id sb1000_pnp_ids[] = {
{ "GIC1000", 0 },
};
MODULE_DEVICE_TABLE(pnp, sb1000_pnp_ids);
+static const struct net_device_ops sb1000_netdev_ops = {
+ .ndo_open = sb1000_open,
+ .ndo_start_xmit = sb1000_start_xmit,
+ .ndo_do_ioctl = sb1000_dev_ioctl,
+ .ndo_stop = sb1000_close,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int
sb1000_probe_one(struct pnp_dev *pdev, const struct pnp_device_id *id)
{
unsigned short ioaddr[2], irq;
unsigned int serial_number;
int error = -ENODEV;
-
+
if (pnp_device_attach(pdev) < 0)
return -ENODEV;
if (pnp_activate_dev(pdev) < 0)
goto out_disable;
if (!pnp_irq_valid(pdev, 0))
goto out_disable;
-
+
serial_number = pdev->card->serial;
-
+
ioaddr[0] = pnp_port_start(pdev, 0);
ioaddr[1] = pnp_port_start(pdev, 0);
-
+
irq = pnp_irq(pdev, 0);
if (!request_region(ioaddr[0], 16, "sb1000"))
goto out_release_regions;
}
-
+
dev->base_addr = ioaddr[0];
/* mem_start holds the second I/O address */
dev->mem_start = ioaddr[1];
*/
dev->flags = IFF_POINTOPOINT|IFF_NOARP;
- SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
if (sb1000_debug > 0)
printk(KERN_NOTICE "%s", version);
- /* The SB1000-specific entries in the device structure. */
- dev->open = sb1000_open;
- dev->do_ioctl = sb1000_dev_ioctl;
- dev->hard_start_xmit = sb1000_start_xmit;
- dev->stop = sb1000_close;
- dev->get_stats = sb1000_stats;
+ dev->netdev_ops = &sb1000_netdev_ops;
/* hardware address is 0:0:serial_number */
dev->dev_addr[2] = serial_number >> 24 & 0xff;
.remove = sb1000_remove_one,
};
-\f
+
/*
* SB1000 hardware routines to be used during open/configuration phases
*/
static const int TimeOutJiffies = (875 * HZ) / 100;
-static inline void nicedelay(unsigned long usecs)
-{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ);
- return;
-}
-
/* Card Wait For Busy Clear (cannot be used during an interrupt) */
-static inline int
+static int
card_wait_for_busy_clear(const int ioaddr[], const char* name)
{
unsigned char a;
}
/* Card Wait For Ready (cannot be used during an interrupt) */
-static inline int
+static int
card_wait_for_ready(const int ioaddr[], const char* name, unsigned char in[])
{
unsigned char a;
}
/* Card Send Command (cannot be used during an interrupt) */
-static inline int
+static int
card_send_command(const int ioaddr[], const char* name,
const unsigned char out[], unsigned char in[])
{
return 0;
}
-\f
+
/*
* SB1000 hardware routines to be used during frame rx interrupt
*/
static const int Sb1000TimeOutJiffies = 7 * HZ;
/* Card Wait For Ready (to be used during frame rx) */
-static inline int
+static int
sb1000_wait_for_ready(const int ioaddr[], const char* name)
{
unsigned long timeout;
}
/* Card Wait For Ready Clear (to be used during frame rx) */
-static inline int
+static int
sb1000_wait_for_ready_clear(const int ioaddr[], const char* name)
{
unsigned long timeout;
}
/* Card Send Command (to be used during frame rx) */
-static inline void
+static void
sb1000_send_command(const int ioaddr[], const char* name,
const unsigned char out[])
{
}
/* Card Read Status (to be used during frame rx) */
-static inline void
+static void
sb1000_read_status(const int ioaddr[], unsigned char in[])
{
in[1] = inb(ioaddr[0] + 1);
}
/* Issue Read Command (to be used during frame rx) */
-static inline void
+static void
sb1000_issue_read_command(const int ioaddr[], const char* name)
{
- const unsigned char Command0[6] = {0x20, 0x00, 0x00, 0x01, 0x00, 0x00};
+ static const unsigned char Command0[6] = {0x20, 0x00, 0x00, 0x01, 0x00, 0x00};
sb1000_wait_for_ready_clear(ioaddr, name);
outb(0xa0, ioaddr[0] + 6);
return;
}
-\f
+
/*
* SB1000 commands for open/configuration
*/
/* reset SB1000 card */
-static inline int
+static int
sb1000_reset(const int ioaddr[], const char* name)
{
+ static const unsigned char Command0[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00};
+
unsigned char st[7];
int port, status;
- const unsigned char Command0[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00};
port = ioaddr[1] + 6;
outb(0x4, port);
udelay(1000);
outb(0x0, port);
inb(port);
- nicedelay(60000);
+ ssleep(1);
outb(0x4, port);
inb(port);
udelay(1000);
}
/* check SB1000 firmware CRC */
-static inline int
+static int
sb1000_check_CRC(const int ioaddr[], const char* name)
{
+ static const unsigned char Command0[6] = {0x80, 0x1f, 0x00, 0x00, 0x00, 0x00};
+
unsigned char st[7];
int crc, status;
- const unsigned char Command0[6] = {0x80, 0x1f, 0x00, 0x00, 0x00, 0x00};
/* check CRC */
if ((status = card_send_command(ioaddr, name, Command0, st)))
static inline int
sb1000_start_get_set_command(const int ioaddr[], const char* name)
{
+ static const unsigned char Command0[6] = {0x80, 0x1b, 0x00, 0x00, 0x00, 0x00};
+
unsigned char st[7];
- const unsigned char Command0[6] = {0x80, 0x1b, 0x00, 0x00, 0x00, 0x00};
return card_send_command(ioaddr, name, Command0, st);
}
-static inline int
+static int
sb1000_end_get_set_command(const int ioaddr[], const char* name)
{
+ static const unsigned char Command0[6] = {0x80, 0x1b, 0x02, 0x00, 0x00, 0x00};
+ static const unsigned char Command1[6] = {0x20, 0x00, 0x00, 0x00, 0x00, 0x00};
+
unsigned char st[7];
int status;
- const unsigned char Command0[6] = {0x80, 0x1b, 0x02, 0x00, 0x00, 0x00};
- const unsigned char Command1[6] = {0x20, 0x00, 0x00, 0x00, 0x00, 0x00};
if ((status = card_send_command(ioaddr, name, Command0, st)))
return status;
return card_send_command(ioaddr, name, Command1, st);
}
-static inline int
+static int
sb1000_activate(const int ioaddr[], const char* name)
{
+ static const unsigned char Command0[6] = {0x80, 0x11, 0x00, 0x00, 0x00, 0x00};
+ static const unsigned char Command1[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00};
+
unsigned char st[7];
int status;
- const unsigned char Command0[6] = {0x80, 0x11, 0x00, 0x00, 0x00, 0x00};
- const unsigned char Command1[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00};
- nicedelay(50000);
+ ssleep(1);
if ((status = card_send_command(ioaddr, name, Command0, st)))
return status;
if ((status = card_send_command(ioaddr, name, Command1, st)))
sb1000_get_firmware_version(const int ioaddr[], const char* name,
unsigned char version[], int do_end)
{
+ static const unsigned char Command0[6] = {0x80, 0x23, 0x00, 0x00, 0x00, 0x00};
+
unsigned char st[7];
int status;
- const unsigned char Command0[6] = {0x80, 0x23, 0x00, 0x00, 0x00, 0x00};
if ((status = sb1000_start_get_set_command(ioaddr, name)))
return status;
static int
sb1000_get_frequency(const int ioaddr[], const char* name, int* frequency)
{
+ static const unsigned char Command0[6] = {0x80, 0x44, 0x00, 0x00, 0x00, 0x00};
+
unsigned char st[7];
int status;
- const unsigned char Command0[6] = {0x80, 0x44, 0x00, 0x00, 0x00, 0x00};
udelay(1000);
if ((status = sb1000_start_get_set_command(ioaddr, name)))
static int
sb1000_get_PIDs(const int ioaddr[], const char* name, short PID[])
{
+ static const unsigned char Command0[6] = {0x80, 0x40, 0x00, 0x00, 0x00, 0x00};
+ static const unsigned char Command1[6] = {0x80, 0x41, 0x00, 0x00, 0x00, 0x00};
+ static const unsigned char Command2[6] = {0x80, 0x42, 0x00, 0x00, 0x00, 0x00};
+ static const unsigned char Command3[6] = {0x80, 0x43, 0x00, 0x00, 0x00, 0x00};
+
unsigned char st[7];
int status;
- const unsigned char Command0[6] = {0x80, 0x40, 0x00, 0x00, 0x00, 0x00};
- const unsigned char Command1[6] = {0x80, 0x41, 0x00, 0x00, 0x00, 0x00};
- const unsigned char Command2[6] = {0x80, 0x42, 0x00, 0x00, 0x00, 0x00};
- const unsigned char Command3[6] = {0x80, 0x43, 0x00, 0x00, 0x00, 0x00};
udelay(1000);
if ((status = sb1000_start_get_set_command(ioaddr, name)))
static int
sb1000_set_PIDs(const int ioaddr[], const char* name, const short PID[])
{
+ static const unsigned char Command4[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00};
+
unsigned char st[7];
short p;
int status;
unsigned char Command1[6] = {0x80, 0x32, 0x00, 0x00, 0x00, 0x00};
unsigned char Command2[6] = {0x80, 0x33, 0x00, 0x00, 0x00, 0x00};
unsigned char Command3[6] = {0x80, 0x34, 0x00, 0x00, 0x00, 0x00};
- const unsigned char Command4[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00};
udelay(1000);
if ((status = sb1000_start_get_set_command(ioaddr, name)))
return sb1000_end_get_set_command(ioaddr, name);
}
-\f
-static inline void
+
+static void
sb1000_print_status_buffer(const char* name, unsigned char st[],
unsigned char buffer[], int size)
{
/* receive a single frame and assemble datagram
* (this is the heart of the interrupt routine)
*/
-static inline int
+static int
sb1000_rx(struct net_device *dev)
{
unsigned int skbsize;
struct sk_buff *skb;
struct sb1000_private *lp = netdev_priv(dev);
- struct net_device_stats *stats = &lp->stats;
+ struct net_device_stats *stats = &dev->stats;
/* SB1000 frame constants */
const int FrameSize = FRAMESIZE;
goto dropped_frame;
}
skb->dev = dev;
- skb->mac.raw = skb->data;
+ skb_reset_mac_header(skb);
skb->protocol = (unsigned short) buffer[NewDatagramHeaderSkip + 16];
insw(ioaddr, skb_put(skb, NewDatagramDataSize),
NewDatagramDataSize / 2);
/* datagram completed: send to upper level */
skb_trim(skb, dlen);
netif_rx(skb);
- dev->last_rx = jiffies;
stats->rx_bytes+=dlen;
stats->rx_packets++;
lp->rx_skb[ns] = NULL;
return -1;
}
-static inline void
+static void
sb1000_error_dpc(struct net_device *dev)
{
+ static const unsigned char Command0[6] = {0x80, 0x26, 0x00, 0x00, 0x00, 0x00};
+
char *name;
unsigned char st[5];
int ioaddr[2];
struct sb1000_private *lp = netdev_priv(dev);
- const unsigned char Command0[6] = {0x80, 0x26, 0x00, 0x00, 0x00, 0x00};
const int ErrorDpcCounterInitialize = 200;
ioaddr[0] = dev->base_addr;
return;
}
-\f
+
/*
* Linux interface functions
*/
/* initialize sb1000 */
if ((status = sb1000_reset(ioaddr, name)))
return status;
- nicedelay(200000);
+ ssleep(1);
if ((status = sb1000_check_CRC(ioaddr, name)))
return status;
lp->rx_frame_id[1] = 0;
lp->rx_frame_id[2] = 0;
lp->rx_frame_id[3] = 0;
- if (request_irq(dev->irq, &sb1000_interrupt, 0, "sb1000", dev)) {
+ if (request_irq(dev->irq, sb1000_interrupt, 0, "sb1000", dev)) {
return -EAGAIN;
}
switch (cmd) {
case SIOCGCMSTATS: /* get statistics */
- stats[0] = lp->stats.rx_bytes;
+ stats[0] = dev->stats.rx_bytes;
stats[1] = lp->rx_frames;
- stats[2] = lp->stats.rx_packets;
- stats[3] = lp->stats.rx_errors;
- stats[4] = lp->stats.rx_dropped;
+ stats[2] = dev->stats.rx_packets;
+ stats[3] = dev->stats.rx_errors;
+ stats[4] = dev->stats.rx_dropped;
if(copy_to_user(ifr->ifr_data, stats, sizeof(stats)))
return -EFAULT;
status = 0;
}
/* transmit function: do nothing since SB1000 can't send anything out */
-static int
+static netdev_tx_t
sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
printk(KERN_WARNING "%s: trying to transmit!!!\n", dev->name);
/* sb1000 can't xmit datagrams */
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
}
/* SB1000 interrupt handler. */
-static irqreturn_t sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sb1000_interrupt(int irq, void *dev_id)
{
+ static const unsigned char Command0[6] = {0x80, 0x2c, 0x00, 0x00, 0x00, 0x00};
+ static const unsigned char Command1[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00};
+
char *name;
unsigned char st;
int ioaddr[2];
- struct net_device *dev = (struct net_device *) dev_id;
+ struct net_device *dev = dev_id;
struct sb1000_private *lp = netdev_priv(dev);
- const unsigned char Command0[6] = {0x80, 0x2c, 0x00, 0x00, 0x00, 0x00};
- const unsigned char Command1[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00};
const int MaxRxErrorCount = 6;
- if (dev == NULL) {
- printk(KERN_ERR "sb1000_interrupt(): irq %d for unknown device.\n",
- irq);
- return IRQ_NONE;
- }
-
ioaddr[0] = dev->base_addr;
/* mem_start holds the second I/O address */
ioaddr[1] = dev->mem_start;
return IRQ_HANDLED;
}
-static struct net_device_stats *sb1000_stats(struct net_device *dev)
-{
- struct sb1000_private *lp = netdev_priv(dev);
- return &lp->stats;
-}
-
static int sb1000_close(struct net_device *dev)
{
int i;
printk(KERN_DEBUG "%s: Shutting down sb1000.\n", dev->name);
netif_stop_queue(dev);
-
+
ioaddr[0] = dev->base_addr;
/* mem_start holds the second I/O address */
ioaddr[1] = dev->mem_start;