brintos

brintos / linux-shallow public Read only

0
0
Text · 31.0 KiB · c3f8020 Raw
1180 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/* sb1000.c: A General Instruments SB1000 driver for linux. */3/*4	Written 1998 by Franco Venturi.5 6	Copyright 1998 by Franco Venturi.7	Copyright 1994,1995 by Donald Becker.8	Copyright 1993 United States Government as represented by the9	Director, National Security Agency.10 11	This driver is for the General Instruments SB1000 (internal SURFboard)12 13	The author may be reached as fventuri@mediaone.net14 15 16	Changes:17 18	981115 Steven Hirsch <shirsch@adelphia.net>19 20	Linus changed the timer interface.  Should work on all recent21	development kernels.22 23	980608 Steven Hirsch <shirsch@adelphia.net>24 25	Small changes to make it work with 2.1.x kernels. Hopefully,26	nothing major will change before official release of Linux 2.2.27 28	Merged with 2.2 - Alan Cox29*/30 31static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n";32 33#include <linux/module.h>34#include <linux/kernel.h>35#include <linux/sched.h>36#include <linux/string.h>37#include <linux/interrupt.h>38#include <linux/errno.h>39#include <linux/if_cablemodem.h> /* for SIOGCM/SIOSCM stuff */40#include <linux/in.h>41#include <linux/ioport.h>42#include <linux/netdevice.h>43#include <linux/if_arp.h>44#include <linux/skbuff.h>45#include <linux/delay.h>	/* for udelay() */46#include <linux/etherdevice.h>47#include <linux/pnp.h>48#include <linux/init.h>49#include <linux/bitops.h>50#include <linux/gfp.h>51 52#include <asm/io.h>53#include <asm/processor.h>54#include <linux/uaccess.h>55 56#ifdef SB1000_DEBUG57static int sb1000_debug = SB1000_DEBUG;58#else59static const int sb1000_debug = 1;60#endif61 62static const int SB1000_IO_EXTENT = 8;63/* SB1000 Maximum Receive Unit */64static const int SB1000_MRU = 1500; /* octects */65 66#define NPIDS 467struct sb1000_private {68	struct sk_buff *rx_skb[NPIDS];69	short rx_dlen[NPIDS];70	unsigned int rx_frames;71	short rx_error_count;72	short rx_error_dpc_count;73	unsigned char rx_session_id[NPIDS];74	unsigned char rx_frame_id[NPIDS];75	unsigned char rx_pkt_type[NPIDS];76};77 78/* prototypes for Linux interface */79extern int sb1000_probe(struct net_device *dev);80static int sb1000_open(struct net_device *dev);81static int sb1000_siocdevprivate(struct net_device *dev, struct ifreq *ifr,82				 void __user *data, int cmd);83static netdev_tx_t sb1000_start_xmit(struct sk_buff *skb,84				     struct net_device *dev);85static irqreturn_t sb1000_interrupt(int irq, void *dev_id);86static int sb1000_close(struct net_device *dev);87 88 89/* SB1000 hardware routines to be used during open/configuration phases */90static int card_wait_for_busy_clear(const int ioaddr[],91	const char* name);92static int card_wait_for_ready(const int ioaddr[], const char* name,93	unsigned char in[]);94static int card_send_command(const int ioaddr[], const char* name,95	const unsigned char out[], unsigned char in[]);96 97/* SB1000 hardware routines to be used during frame rx interrupt */98static int sb1000_wait_for_ready(const int ioaddr[], const char* name);99static int sb1000_wait_for_ready_clear(const int ioaddr[],100	const char* name);101static void sb1000_send_command(const int ioaddr[], const char* name,102	const unsigned char out[]);103static void sb1000_read_status(const int ioaddr[], unsigned char in[]);104static void sb1000_issue_read_command(const int ioaddr[],105	const char* name);106 107/* SB1000 commands for open/configuration */108static int sb1000_reset(const int ioaddr[], const char* name);109static int sb1000_check_CRC(const int ioaddr[], const char* name);110static inline int sb1000_start_get_set_command(const int ioaddr[],111	const char* name);112static int sb1000_end_get_set_command(const int ioaddr[],113	const char* name);114static int sb1000_activate(const int ioaddr[], const char* name);115static int sb1000_get_firmware_version(const int ioaddr[],116	const char* name, unsigned char version[], int do_end);117static int sb1000_get_frequency(const int ioaddr[], const char* name,118	int* frequency);119static int sb1000_set_frequency(const int ioaddr[], const char* name,120	int frequency);121static int sb1000_get_PIDs(const int ioaddr[], const char* name,122	short PID[]);123static int sb1000_set_PIDs(const int ioaddr[], const char* name,124	const short PID[]);125 126/* SB1000 commands for frame rx interrupt */127static int sb1000_rx(struct net_device *dev);128static void sb1000_error_dpc(struct net_device *dev);129 130static const struct pnp_device_id sb1000_pnp_ids[] = {131	{ "GIC1000", 0 },132	{ "", 0 }133};134MODULE_DEVICE_TABLE(pnp, sb1000_pnp_ids);135 136static const struct net_device_ops sb1000_netdev_ops = {137	.ndo_open		= sb1000_open,138	.ndo_start_xmit		= sb1000_start_xmit,139	.ndo_siocdevprivate	= sb1000_siocdevprivate,140	.ndo_stop		= sb1000_close,141	.ndo_set_mac_address 	= eth_mac_addr,142	.ndo_validate_addr	= eth_validate_addr,143};144 145static int146sb1000_probe_one(struct pnp_dev *pdev, const struct pnp_device_id *id)147{148	struct net_device *dev;149	unsigned short ioaddr[2], irq;150	unsigned int serial_number;151	int error = -ENODEV;152	u8 addr[ETH_ALEN];153 154	if (pnp_device_attach(pdev) < 0)155		return -ENODEV;156	if (pnp_activate_dev(pdev) < 0)157		goto out_detach;158 159	if (!pnp_port_valid(pdev, 0) || !pnp_port_valid(pdev, 1))160		goto out_disable;161	if (!pnp_irq_valid(pdev, 0))162		goto out_disable;163 164	serial_number = pdev->card->serial;165 166	ioaddr[0] = pnp_port_start(pdev, 0);167	ioaddr[1] = pnp_port_start(pdev, 0);168 169	irq = pnp_irq(pdev, 0);170 171	if (!request_region(ioaddr[0], 16, "sb1000"))172		goto out_disable;173	if (!request_region(ioaddr[1], 16, "sb1000"))174		goto out_release_region0;175 176	dev = alloc_etherdev(sizeof(struct sb1000_private));177	if (!dev) {178		error = -ENOMEM;179		goto out_release_regions;180	}181 182 183	dev->base_addr = ioaddr[0];184	/* mem_start holds the second I/O address */185	dev->mem_start = ioaddr[1];186	dev->irq = irq;187 188	if (sb1000_debug > 0)189		printk(KERN_NOTICE "%s: sb1000 at (%#3.3lx,%#3.3lx), "190			"S/N %#8.8x, IRQ %d.\n", dev->name, dev->base_addr,191			dev->mem_start, serial_number, dev->irq);192 193	/*194	 * The SB1000 is an rx-only cable modem device.  The uplink is a modem195	 * and we do not want to arp on it.196	 */197	dev->flags = IFF_POINTOPOINT|IFF_NOARP;198 199	SET_NETDEV_DEV(dev, &pdev->dev);200 201	if (sb1000_debug > 0)202		printk(KERN_NOTICE "%s", version);203 204	dev->netdev_ops	= &sb1000_netdev_ops;205 206	/* hardware address is 0:0:serial_number */207	addr[0] = 0;208	addr[1] = 0;209	addr[2]	= serial_number >> 24 & 0xff;210	addr[3]	= serial_number >> 16 & 0xff;211	addr[4]	= serial_number >>  8 & 0xff;212	addr[5]	= serial_number >>  0 & 0xff;213	eth_hw_addr_set(dev, addr);214 215	pnp_set_drvdata(pdev, dev);216 217	error = register_netdev(dev);218	if (error)219		goto out_free_netdev;220	return 0;221 222 out_free_netdev:223	free_netdev(dev);224 out_release_regions:225	release_region(ioaddr[1], 16);226 out_release_region0:227	release_region(ioaddr[0], 16);228 out_disable:229	pnp_disable_dev(pdev);230 out_detach:231	pnp_device_detach(pdev);232	return error;233}234 235static void236sb1000_remove_one(struct pnp_dev *pdev)237{238	struct net_device *dev = pnp_get_drvdata(pdev);239 240	unregister_netdev(dev);241	release_region(dev->base_addr, 16);242	release_region(dev->mem_start, 16);243	free_netdev(dev);244}245 246static struct pnp_driver sb1000_driver = {247	.name		= "sb1000",248	.id_table	= sb1000_pnp_ids,249	.probe		= sb1000_probe_one,250	.remove		= sb1000_remove_one,251};252 253 254/*255 * SB1000 hardware routines to be used during open/configuration phases256 */257 258static const int TimeOutJiffies = (875 * HZ) / 100;259 260/* Card Wait For Busy Clear (cannot be used during an interrupt) */261static int262card_wait_for_busy_clear(const int ioaddr[], const char* name)263{264	unsigned char a;265	unsigned long timeout;266 267	a = inb(ioaddr[0] + 7);268	timeout = jiffies + TimeOutJiffies;269	while (a & 0x80 || a & 0x40) {270		/* a little sleep */271		yield();272 273		a = inb(ioaddr[0] + 7);274		if (time_after_eq(jiffies, timeout)) {275			printk(KERN_WARNING "%s: card_wait_for_busy_clear timeout\n",276				name);277			return -ETIME;278		}279	}280 281	return 0;282}283 284/* Card Wait For Ready (cannot be used during an interrupt) */285static int286card_wait_for_ready(const int ioaddr[], const char* name, unsigned char in[])287{288	unsigned char a;289	unsigned long timeout;290 291	a = inb(ioaddr[1] + 6);292	timeout = jiffies + TimeOutJiffies;293	while (a & 0x80 || !(a & 0x40)) {294		/* a little sleep */295		yield();296 297		a = inb(ioaddr[1] + 6);298		if (time_after_eq(jiffies, timeout)) {299			printk(KERN_WARNING "%s: card_wait_for_ready timeout\n",300				name);301			return -ETIME;302		}303	}304 305	in[1] = inb(ioaddr[0] + 1);306	in[2] = inb(ioaddr[0] + 2);307	in[3] = inb(ioaddr[0] + 3);308	in[4] = inb(ioaddr[0] + 4);309	in[0] = inb(ioaddr[0] + 5);310	in[6] = inb(ioaddr[0] + 6);311	in[5] = inb(ioaddr[1] + 6);312	return 0;313}314 315/* Card Send Command (cannot be used during an interrupt) */316static int317card_send_command(const int ioaddr[], const char* name,318	const unsigned char out[], unsigned char in[])319{320	int status;321 322	if ((status = card_wait_for_busy_clear(ioaddr, name)))323		return status;324	outb(0xa0, ioaddr[0] + 6);325	outb(out[2], ioaddr[0] + 1);326	outb(out[3], ioaddr[0] + 2);327	outb(out[4], ioaddr[0] + 3);328	outb(out[5], ioaddr[0] + 4);329	outb(out[1], ioaddr[0] + 5);330	outb(0xa0, ioaddr[0] + 6);331	outb(out[0], ioaddr[0] + 7);332	if (out[0] != 0x20 && out[0] != 0x30) {333		if ((status = card_wait_for_ready(ioaddr, name, in)))334			return status;335		inb(ioaddr[0] + 7);336		if (sb1000_debug > 3)337			printk(KERN_DEBUG "%s: card_send_command "338				"out: %02x%02x%02x%02x%02x%02x  "339				"in: %02x%02x%02x%02x%02x%02x%02x\n", name,340				out[0], out[1], out[2], out[3], out[4], out[5],341				in[0], in[1], in[2], in[3], in[4], in[5], in[6]);342	} else {343		if (sb1000_debug > 3)344			printk(KERN_DEBUG "%s: card_send_command "345				"out: %02x%02x%02x%02x%02x%02x\n", name,346				out[0], out[1], out[2], out[3], out[4], out[5]);347	}348 349	if (out[1] != 0x1b) {350		if (out[0] >= 0x80 && in[0] != (out[1] | 0x80))351			return -EIO;352	}353	return 0;354}355 356 357/*358 * SB1000 hardware routines to be used during frame rx interrupt359 */360static const int Sb1000TimeOutJiffies = 7 * HZ;361 362/* Card Wait For Ready (to be used during frame rx) */363static int364sb1000_wait_for_ready(const int ioaddr[], const char* name)365{366	unsigned long timeout;367 368	timeout = jiffies + Sb1000TimeOutJiffies;369	while (inb(ioaddr[1] + 6) & 0x80) {370		if (time_after_eq(jiffies, timeout)) {371			printk(KERN_WARNING "%s: sb1000_wait_for_ready timeout\n",372				name);373			return -ETIME;374		}375	}376	timeout = jiffies + Sb1000TimeOutJiffies;377	while (!(inb(ioaddr[1] + 6) & 0x40)) {378		if (time_after_eq(jiffies, timeout)) {379			printk(KERN_WARNING "%s: sb1000_wait_for_ready timeout\n",380				name);381			return -ETIME;382		}383	}384	inb(ioaddr[0] + 7);385	return 0;386}387 388/* Card Wait For Ready Clear (to be used during frame rx) */389static int390sb1000_wait_for_ready_clear(const int ioaddr[], const char* name)391{392	unsigned long timeout;393 394	timeout = jiffies + Sb1000TimeOutJiffies;395	while (inb(ioaddr[1] + 6) & 0x80) {396		if (time_after_eq(jiffies, timeout)) {397			printk(KERN_WARNING "%s: sb1000_wait_for_ready_clear timeout\n",398				name);399			return -ETIME;400		}401	}402	timeout = jiffies + Sb1000TimeOutJiffies;403	while (inb(ioaddr[1] + 6) & 0x40) {404		if (time_after_eq(jiffies, timeout)) {405			printk(KERN_WARNING "%s: sb1000_wait_for_ready_clear timeout\n",406				name);407			return -ETIME;408		}409	}410	return 0;411}412 413/* Card Send Command (to be used during frame rx) */414static void415sb1000_send_command(const int ioaddr[], const char* name,416	const unsigned char out[])417{418	outb(out[2], ioaddr[0] + 1);419	outb(out[3], ioaddr[0] + 2);420	outb(out[4], ioaddr[0] + 3);421	outb(out[5], ioaddr[0] + 4);422	outb(out[1], ioaddr[0] + 5);423	outb(out[0], ioaddr[0] + 7);424	if (sb1000_debug > 3)425		printk(KERN_DEBUG "%s: sb1000_send_command out: %02x%02x%02x%02x"426			"%02x%02x\n", name, out[0], out[1], out[2], out[3], out[4], out[5]);427}428 429/* Card Read Status (to be used during frame rx) */430static void431sb1000_read_status(const int ioaddr[], unsigned char in[])432{433	in[1] = inb(ioaddr[0] + 1);434	in[2] = inb(ioaddr[0] + 2);435	in[3] = inb(ioaddr[0] + 3);436	in[4] = inb(ioaddr[0] + 4);437	in[0] = inb(ioaddr[0] + 5);438}439 440/* Issue Read Command (to be used during frame rx) */441static void442sb1000_issue_read_command(const int ioaddr[], const char* name)443{444	static const unsigned char Command0[6] = {0x20, 0x00, 0x00, 0x01, 0x00, 0x00};445 446	sb1000_wait_for_ready_clear(ioaddr, name);447	outb(0xa0, ioaddr[0] + 6);448	sb1000_send_command(ioaddr, name, Command0);449}450 451 452/*453 * SB1000 commands for open/configuration454 */455/* reset SB1000 card */456static int457sb1000_reset(const int ioaddr[], const char* name)458{459	static const unsigned char Command0[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00};460 461	unsigned char st[7];462	int port, status;463 464	port = ioaddr[1] + 6;465	outb(0x4, port);466	inb(port);467	udelay(1000);468	outb(0x0, port);469	inb(port);470	ssleep(1);471	outb(0x4, port);472	inb(port);473	udelay(1000);474	outb(0x0, port);475	inb(port);476	udelay(0);477 478	if ((status = card_send_command(ioaddr, name, Command0, st)))479		return status;480	if (st[3] != 0xf0)481		return -EIO;482	return 0;483}484 485/* check SB1000 firmware CRC */486static int487sb1000_check_CRC(const int ioaddr[], const char* name)488{489	static const unsigned char Command0[6] = {0x80, 0x1f, 0x00, 0x00, 0x00, 0x00};490 491	unsigned char st[7];492	int status;493 494	/* check CRC */495	if ((status = card_send_command(ioaddr, name, Command0, st)))496		return status;497	if (st[1] != st[3] || st[2] != st[4])498		return -EIO;499	return 0;500}501 502static inline int503sb1000_start_get_set_command(const int ioaddr[], const char* name)504{505	static const unsigned char Command0[6] = {0x80, 0x1b, 0x00, 0x00, 0x00, 0x00};506 507	unsigned char st[7];508 509	return card_send_command(ioaddr, name, Command0, st);510}511 512static int513sb1000_end_get_set_command(const int ioaddr[], const char* name)514{515	static const unsigned char Command0[6] = {0x80, 0x1b, 0x02, 0x00, 0x00, 0x00};516	static const unsigned char Command1[6] = {0x20, 0x00, 0x00, 0x00, 0x00, 0x00};517 518	unsigned char st[7];519	int status;520 521	if ((status = card_send_command(ioaddr, name, Command0, st)))522		return status;523	return card_send_command(ioaddr, name, Command1, st);524}525 526static int527sb1000_activate(const int ioaddr[], const char* name)528{529	static const unsigned char Command0[6] = {0x80, 0x11, 0x00, 0x00, 0x00, 0x00};530	static const unsigned char Command1[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00};531 532	unsigned char st[7];533	int status;534 535	ssleep(1);536	status = card_send_command(ioaddr, name, Command0, st);537	if (status)538		return status;539	status = card_send_command(ioaddr, name, Command1, st);540	if (status)541		return status;542	if (st[3] != 0xf1) {543		status = sb1000_start_get_set_command(ioaddr, name);544		if (status)545			return status;546		return -EIO;547	}548	udelay(1000);549	return sb1000_start_get_set_command(ioaddr, name);550}551 552/* get SB1000 firmware version */553static int554sb1000_get_firmware_version(const int ioaddr[], const char* name,555	unsigned char version[], int do_end)556{557	static const unsigned char Command0[6] = {0x80, 0x23, 0x00, 0x00, 0x00, 0x00};558 559	unsigned char st[7];560	int status;561 562	if ((status = sb1000_start_get_set_command(ioaddr, name)))563		return status;564	if ((status = card_send_command(ioaddr, name, Command0, st)))565		return status;566	if (st[0] != 0xa3)567		return -EIO;568	version[0] = st[1];569	version[1] = st[2];570	if (do_end)571		return sb1000_end_get_set_command(ioaddr, name);572	else573		return 0;574}575 576/* get SB1000 frequency */577static int578sb1000_get_frequency(const int ioaddr[], const char* name, int* frequency)579{580	static const unsigned char Command0[6] = {0x80, 0x44, 0x00, 0x00, 0x00, 0x00};581 582	unsigned char st[7];583	int status;584 585	udelay(1000);586	if ((status = sb1000_start_get_set_command(ioaddr, name)))587		return status;588	if ((status = card_send_command(ioaddr, name, Command0, st)))589		return status;590	*frequency = ((st[1] << 8 | st[2]) << 8 | st[3]) << 8 | st[4];591	return sb1000_end_get_set_command(ioaddr, name);592}593 594/* set SB1000 frequency */595static int596sb1000_set_frequency(const int ioaddr[], const char* name, int frequency)597{598	unsigned char st[7];599	int status;600	unsigned char Command0[6] = {0x80, 0x29, 0x00, 0x00, 0x00, 0x00};601 602	const int FrequencyLowerLimit = 57000;603	const int FrequencyUpperLimit = 804000;604 605	if (frequency < FrequencyLowerLimit || frequency > FrequencyUpperLimit) {606		printk(KERN_ERR "%s: frequency chosen (%d kHz) is not in the range "607			"[%d,%d] kHz\n", name, frequency, FrequencyLowerLimit,608			FrequencyUpperLimit);609		return -EINVAL;610	}611	udelay(1000);612	if ((status = sb1000_start_get_set_command(ioaddr, name)))613		return status;614	Command0[5] = frequency & 0xff;615	frequency >>= 8;616	Command0[4] = frequency & 0xff;617	frequency >>= 8;618	Command0[3] = frequency & 0xff;619	frequency >>= 8;620	Command0[2] = frequency & 0xff;621	return card_send_command(ioaddr, name, Command0, st);622}623 624/* get SB1000 PIDs */625static int626sb1000_get_PIDs(const int ioaddr[], const char* name, short PID[])627{628	static const unsigned char Command0[6] = {0x80, 0x40, 0x00, 0x00, 0x00, 0x00};629	static const unsigned char Command1[6] = {0x80, 0x41, 0x00, 0x00, 0x00, 0x00};630	static const unsigned char Command2[6] = {0x80, 0x42, 0x00, 0x00, 0x00, 0x00};631	static const unsigned char Command3[6] = {0x80, 0x43, 0x00, 0x00, 0x00, 0x00};632 633	unsigned char st[7];634	int status;635 636	udelay(1000);637	if ((status = sb1000_start_get_set_command(ioaddr, name)))638		return status;639 640	if ((status = card_send_command(ioaddr, name, Command0, st)))641		return status;642	PID[0] = st[1] << 8 | st[2];643 644	if ((status = card_send_command(ioaddr, name, Command1, st)))645		return status;646	PID[1] = st[1] << 8 | st[2];647 648	if ((status = card_send_command(ioaddr, name, Command2, st)))649		return status;650	PID[2] = st[1] << 8 | st[2];651 652	if ((status = card_send_command(ioaddr, name, Command3, st)))653		return status;654	PID[3] = st[1] << 8 | st[2];655 656	return sb1000_end_get_set_command(ioaddr, name);657}658 659/* set SB1000 PIDs */660static int661sb1000_set_PIDs(const int ioaddr[], const char* name, const short PID[])662{663	static const unsigned char Command4[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00};664 665	unsigned char st[7];666	short p;667	int status;668	unsigned char Command0[6] = {0x80, 0x31, 0x00, 0x00, 0x00, 0x00};669	unsigned char Command1[6] = {0x80, 0x32, 0x00, 0x00, 0x00, 0x00};670	unsigned char Command2[6] = {0x80, 0x33, 0x00, 0x00, 0x00, 0x00};671	unsigned char Command3[6] = {0x80, 0x34, 0x00, 0x00, 0x00, 0x00};672 673	udelay(1000);674	if ((status = sb1000_start_get_set_command(ioaddr, name)))675		return status;676 677	p = PID[0];678	Command0[3] = p & 0xff;679	p >>= 8;680	Command0[2] = p & 0xff;681	if ((status = card_send_command(ioaddr, name, Command0, st)))682		return status;683 684	p = PID[1];685	Command1[3] = p & 0xff;686	p >>= 8;687	Command1[2] = p & 0xff;688	if ((status = card_send_command(ioaddr, name, Command1, st)))689		return status;690 691	p = PID[2];692	Command2[3] = p & 0xff;693	p >>= 8;694	Command2[2] = p & 0xff;695	if ((status = card_send_command(ioaddr, name, Command2, st)))696		return status;697 698	p = PID[3];699	Command3[3] = p & 0xff;700	p >>= 8;701	Command3[2] = p & 0xff;702	if ((status = card_send_command(ioaddr, name, Command3, st)))703		return status;704 705	if ((status = card_send_command(ioaddr, name, Command4, st)))706		return status;707	return sb1000_end_get_set_command(ioaddr, name);708}709 710 711static void712sb1000_print_status_buffer(const char* name, unsigned char st[],713	unsigned char buffer[], int size)714{715	int i, j, k;716 717	printk(KERN_DEBUG "%s: status: %02x %02x\n", name, st[0], st[1]);718	if (buffer[24] == 0x08 && buffer[25] == 0x00 && buffer[26] == 0x45) {719		printk(KERN_DEBUG "%s: length: %d protocol: %d from: %d.%d.%d.%d:%d "720			"to %d.%d.%d.%d:%d\n", name, buffer[28] << 8 | buffer[29],721			buffer[35], buffer[38], buffer[39], buffer[40], buffer[41],722            buffer[46] << 8 | buffer[47],723			buffer[42], buffer[43], buffer[44], buffer[45],724            buffer[48] << 8 | buffer[49]);725	} else {726		for (i = 0, k = 0; i < (size + 7) / 8; i++) {727			printk(KERN_DEBUG "%s: %s", name, i ? "       " : "buffer:");728			for (j = 0; j < 8 && k < size; j++, k++)729				printk(" %02x", buffer[k]);730			printk("\n");731		}732	}733}734 735/*736 * SB1000 commands for frame rx interrupt737 */738/* receive a single frame and assemble datagram739 * (this is the heart of the interrupt routine)740 */741static int742sb1000_rx(struct net_device *dev)743{744 745#define FRAMESIZE 184746	unsigned char st[2], buffer[FRAMESIZE], session_id, frame_id;747	short dlen;748	int ioaddr, ns;749	unsigned int skbsize;750	struct sk_buff *skb;751	struct sb1000_private *lp = netdev_priv(dev);752	struct net_device_stats *stats = &dev->stats;753 754	/* SB1000 frame constants */755	const int FrameSize = FRAMESIZE;756	const int NewDatagramHeaderSkip = 8;757	const int NewDatagramHeaderSize = NewDatagramHeaderSkip + 18;758	const int NewDatagramDataSize = FrameSize - NewDatagramHeaderSize;759	const int ContDatagramHeaderSkip = 7;760	const int ContDatagramHeaderSize = ContDatagramHeaderSkip + 1;761	const int ContDatagramDataSize = FrameSize - ContDatagramHeaderSize;762	const int TrailerSize = 4;763 764	ioaddr = dev->base_addr;765 766	insw(ioaddr, (unsigned short*) st, 1);767#ifdef XXXDEBUG768printk("cm0: received: %02x %02x\n", st[0], st[1]);769#endif /* XXXDEBUG */770	lp->rx_frames++;771 772	/* decide if it is a good or bad frame */773	for (ns = 0; ns < NPIDS; ns++) {774		session_id = lp->rx_session_id[ns];775		frame_id = lp->rx_frame_id[ns];776		if (st[0] == session_id) {777			if (st[1] == frame_id || (!frame_id && (st[1] & 0xf0) == 0x30)) {778				goto good_frame;779			} else if ((st[1] & 0xf0) == 0x30 && (st[0] & 0x40)) {780				goto skipped_frame;781			} else {782				goto bad_frame;783			}784		} else if (st[0] == (session_id | 0x40)) {785			if ((st[1] & 0xf0) == 0x30) {786				goto skipped_frame;787			} else {788				goto bad_frame;789			}790		}791	}792	goto bad_frame;793 794skipped_frame:795	stats->rx_frame_errors++;796	skb = lp->rx_skb[ns];797	if (sb1000_debug > 1)798		printk(KERN_WARNING "%s: missing frame(s): got %02x %02x "799			"expecting %02x %02x\n", dev->name, st[0], st[1],800			skb ? session_id : session_id | 0x40, frame_id);801	if (skb) {802		dev_kfree_skb(skb);803		skb = NULL;804	}805 806good_frame:807	lp->rx_frame_id[ns] = 0x30 | ((st[1] + 1) & 0x0f);808	/* new datagram */809	if (st[0] & 0x40) {810		/* get data length */811		insw(ioaddr, buffer, NewDatagramHeaderSize / 2);812#ifdef XXXDEBUG813printk("cm0: IP identification: %02x%02x  fragment offset: %02x%02x\n", buffer[30], buffer[31], buffer[32], buffer[33]);814#endif /* XXXDEBUG */815		if (buffer[0] != NewDatagramHeaderSkip) {816			if (sb1000_debug > 1)817				printk(KERN_WARNING "%s: new datagram header skip error: "818					"got %02x expecting %02x\n", dev->name, buffer[0],819					NewDatagramHeaderSkip);820			stats->rx_length_errors++;821			insw(ioaddr, buffer, NewDatagramDataSize / 2);822			goto bad_frame_next;823		}824		dlen = ((buffer[NewDatagramHeaderSkip + 3] & 0x0f) << 8 |825			buffer[NewDatagramHeaderSkip + 4]) - 17;826		if (dlen > SB1000_MRU) {827			if (sb1000_debug > 1)828				printk(KERN_WARNING "%s: datagram length (%d) greater "829					"than MRU (%d)\n", dev->name, dlen, SB1000_MRU);830			stats->rx_length_errors++;831			insw(ioaddr, buffer, NewDatagramDataSize / 2);832			goto bad_frame_next;833		}834		lp->rx_dlen[ns] = dlen;835		/* compute size to allocate for datagram */836		skbsize = dlen + FrameSize;837		if ((skb = alloc_skb(skbsize, GFP_ATOMIC)) == NULL) {838			if (sb1000_debug > 1)839				printk(KERN_WARNING "%s: can't allocate %d bytes long "840					"skbuff\n", dev->name, skbsize);841			stats->rx_dropped++;842			insw(ioaddr, buffer, NewDatagramDataSize / 2);843			goto dropped_frame;844		}845		skb->dev = dev;846		skb_reset_mac_header(skb);847		skb->protocol = (unsigned short) buffer[NewDatagramHeaderSkip + 16];848		insw(ioaddr, skb_put(skb, NewDatagramDataSize),849			NewDatagramDataSize / 2);850		lp->rx_skb[ns] = skb;851	} else {852		/* continuation of previous datagram */853		insw(ioaddr, buffer, ContDatagramHeaderSize / 2);854		if (buffer[0] != ContDatagramHeaderSkip) {855			if (sb1000_debug > 1)856				printk(KERN_WARNING "%s: cont datagram header skip error: "857					"got %02x expecting %02x\n", dev->name, buffer[0],858					ContDatagramHeaderSkip);859			stats->rx_length_errors++;860			insw(ioaddr, buffer, ContDatagramDataSize / 2);861			goto bad_frame_next;862		}863		skb = lp->rx_skb[ns];864		insw(ioaddr, skb_put(skb, ContDatagramDataSize),865			ContDatagramDataSize / 2);866		dlen = lp->rx_dlen[ns];867	}868	if (skb->len < dlen + TrailerSize) {869		lp->rx_session_id[ns] &= ~0x40;870		return 0;871	}872 873	/* datagram completed: send to upper level */874	skb_trim(skb, dlen);875	__netif_rx(skb);876	stats->rx_bytes+=dlen;877	stats->rx_packets++;878	lp->rx_skb[ns] = NULL;879	lp->rx_session_id[ns] |= 0x40;880	return 0;881 882bad_frame:883	insw(ioaddr, buffer, FrameSize / 2);884	if (sb1000_debug > 1)885		printk(KERN_WARNING "%s: frame error: got %02x %02x\n",886			dev->name, st[0], st[1]);887	stats->rx_frame_errors++;888bad_frame_next:889	if (sb1000_debug > 2)890		sb1000_print_status_buffer(dev->name, st, buffer, FrameSize);891dropped_frame:892	stats->rx_errors++;893	if (ns < NPIDS) {894		if ((skb = lp->rx_skb[ns])) {895			dev_kfree_skb(skb);896			lp->rx_skb[ns] = NULL;897		}898		lp->rx_session_id[ns] |= 0x40;899	}900	return -1;901}902 903static void904sb1000_error_dpc(struct net_device *dev)905{906	static const unsigned char Command0[6] = {0x80, 0x26, 0x00, 0x00, 0x00, 0x00};907 908	char *name;909	unsigned char st[5];910	int ioaddr[2];911	struct sb1000_private *lp = netdev_priv(dev);912	const int ErrorDpcCounterInitialize = 200;913 914	ioaddr[0] = dev->base_addr;915	/* mem_start holds the second I/O address */916	ioaddr[1] = dev->mem_start;917	name = dev->name;918 919	sb1000_wait_for_ready_clear(ioaddr, name);920	sb1000_send_command(ioaddr, name, Command0);921	sb1000_wait_for_ready(ioaddr, name);922	sb1000_read_status(ioaddr, st);923	if (st[1] & 0x10)924		lp->rx_error_dpc_count = ErrorDpcCounterInitialize;925}926 927 928/*929 * Linux interface functions930 */931static int932sb1000_open(struct net_device *dev)933{934	char *name;935	int ioaddr[2], status;936	struct sb1000_private *lp = netdev_priv(dev);937	const unsigned short FirmwareVersion[] = {0x01, 0x01};938 939	ioaddr[0] = dev->base_addr;940	/* mem_start holds the second I/O address */941	ioaddr[1] = dev->mem_start;942	name = dev->name;943 944	/* initialize sb1000 */945	if ((status = sb1000_reset(ioaddr, name)))946		return status;947	ssleep(1);948	if ((status = sb1000_check_CRC(ioaddr, name)))949		return status;950 951	/* initialize private data before board can catch interrupts */952	lp->rx_skb[0] = NULL;953	lp->rx_skb[1] = NULL;954	lp->rx_skb[2] = NULL;955	lp->rx_skb[3] = NULL;956	lp->rx_dlen[0] = 0;957	lp->rx_dlen[1] = 0;958	lp->rx_dlen[2] = 0;959	lp->rx_dlen[3] = 0;960	lp->rx_frames = 0;961	lp->rx_error_count = 0;962	lp->rx_error_dpc_count = 0;963	lp->rx_session_id[0] = 0x50;964	lp->rx_session_id[1] = 0x48;965	lp->rx_session_id[2] = 0x44;966	lp->rx_session_id[3] = 0x42;967	lp->rx_frame_id[0] = 0;968	lp->rx_frame_id[1] = 0;969	lp->rx_frame_id[2] = 0;970	lp->rx_frame_id[3] = 0;971	if (request_irq(dev->irq, sb1000_interrupt, 0, "sb1000", dev)) {972		return -EAGAIN;973	}974 975	if (sb1000_debug > 2)976		printk(KERN_DEBUG "%s: Opening, IRQ %d\n", name, dev->irq);977 978	/* Activate board and check firmware version */979	udelay(1000);980	if ((status = sb1000_activate(ioaddr, name)))981		return status;982	udelay(0);983	if ((status = sb1000_get_firmware_version(ioaddr, name, version, 0)))984		return status;985	if (version[0] != FirmwareVersion[0] || version[1] != FirmwareVersion[1])986		printk(KERN_WARNING "%s: found firmware version %x.%02x "987			"(should be %x.%02x)\n", name, version[0], version[1],988			FirmwareVersion[0], FirmwareVersion[1]);989 990 991	netif_start_queue(dev);992	return 0;					/* Always succeed */993}994 995static int sb1000_siocdevprivate(struct net_device *dev, struct ifreq *ifr,996				 void __user *data, int cmd)997{998	char* name;999	unsigned char version[2];1000	short PID[4];1001	int ioaddr[2], status, frequency;1002	unsigned int stats[5];1003	struct sb1000_private *lp = netdev_priv(dev);1004 1005	if (!(dev && dev->flags & IFF_UP))1006		return -ENODEV;1007 1008	ioaddr[0] = dev->base_addr;1009	/* mem_start holds the second I/O address */1010	ioaddr[1] = dev->mem_start;1011	name = dev->name;1012 1013	switch (cmd) {1014	case SIOCGCMSTATS:		/* get statistics */1015		stats[0] = dev->stats.rx_bytes;1016		stats[1] = lp->rx_frames;1017		stats[2] = dev->stats.rx_packets;1018		stats[3] = dev->stats.rx_errors;1019		stats[4] = dev->stats.rx_dropped;1020		if (copy_to_user(data, stats, sizeof(stats)))1021			return -EFAULT;1022		status = 0;1023		break;1024 1025	case SIOCGCMFIRMWARE:		/* get firmware version */1026		if ((status = sb1000_get_firmware_version(ioaddr, name, version, 1)))1027			return status;1028		if (copy_to_user(data, version, sizeof(version)))1029			return -EFAULT;1030		break;1031 1032	case SIOCGCMFREQUENCY:		/* get frequency */1033		if ((status = sb1000_get_frequency(ioaddr, name, &frequency)))1034			return status;1035		if (put_user(frequency, (int __user *)data))1036			return -EFAULT;1037		break;1038 1039	case SIOCSCMFREQUENCY:		/* set frequency */1040		if (!capable(CAP_NET_ADMIN))1041			return -EPERM;1042		if (get_user(frequency, (int __user *)data))1043			return -EFAULT;1044		if ((status = sb1000_set_frequency(ioaddr, name, frequency)))1045			return status;1046		break;1047 1048	case SIOCGCMPIDS:			/* get PIDs */1049		if ((status = sb1000_get_PIDs(ioaddr, name, PID)))1050			return status;1051		if (copy_to_user(data, PID, sizeof(PID)))1052			return -EFAULT;1053		break;1054 1055	case SIOCSCMPIDS:			/* set PIDs */1056		if (!capable(CAP_NET_ADMIN))1057			return -EPERM;1058		if (copy_from_user(PID, data, sizeof(PID)))1059			return -EFAULT;1060		if ((status = sb1000_set_PIDs(ioaddr, name, PID)))1061			return status;1062		/* set session_id, frame_id and pkt_type too */1063		lp->rx_session_id[0] = 0x50 | (PID[0] & 0x0f);1064		lp->rx_session_id[1] = 0x48;1065		lp->rx_session_id[2] = 0x44;1066		lp->rx_session_id[3] = 0x42;1067		lp->rx_frame_id[0] = 0;1068		lp->rx_frame_id[1] = 0;1069		lp->rx_frame_id[2] = 0;1070		lp->rx_frame_id[3] = 0;1071		break;1072 1073	default:1074		status = -EINVAL;1075		break;1076	}1077	return status;1078}1079 1080/* transmit function: do nothing since SB1000 can't send anything out */1081static netdev_tx_t1082sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev)1083{1084	printk(KERN_WARNING "%s: trying to transmit!!!\n", dev->name);1085	/* sb1000 can't xmit datagrams */1086	dev_kfree_skb(skb);1087	return NETDEV_TX_OK;1088}1089 1090/* SB1000 interrupt handler. */1091static irqreturn_t sb1000_interrupt(int irq, void *dev_id)1092{1093	static const unsigned char Command0[6] = {0x80, 0x2c, 0x00, 0x00, 0x00, 0x00};1094	static const unsigned char Command1[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00};1095 1096	char *name;1097	unsigned char st;1098	int ioaddr[2];1099	struct net_device *dev = dev_id;1100	struct sb1000_private *lp = netdev_priv(dev);1101 1102	const int MaxRxErrorCount = 6;1103 1104	ioaddr[0] = dev->base_addr;1105	/* mem_start holds the second I/O address */1106	ioaddr[1] = dev->mem_start;1107	name = dev->name;1108 1109	/* is it a good interrupt? */1110	st = inb(ioaddr[1] + 6);1111	if (!(st & 0x08 && st & 0x20)) {1112		return IRQ_NONE;1113	}1114 1115	if (sb1000_debug > 3)1116		printk(KERN_DEBUG "%s: entering interrupt\n", dev->name);1117 1118	st = inb(ioaddr[0] + 7);1119	if (sb1000_rx(dev))1120		lp->rx_error_count++;1121#ifdef SB1000_DELAY1122	udelay(SB1000_DELAY);1123#endif /* SB1000_DELAY */1124	sb1000_issue_read_command(ioaddr, name);1125	if (st & 0x01) {1126		sb1000_error_dpc(dev);1127		sb1000_issue_read_command(ioaddr, name);1128	}1129	if (lp->rx_error_dpc_count && !(--lp->rx_error_dpc_count)) {1130		sb1000_wait_for_ready_clear(ioaddr, name);1131		sb1000_send_command(ioaddr, name, Command0);1132		sb1000_wait_for_ready(ioaddr, name);1133		sb1000_issue_read_command(ioaddr, name);1134	}1135	if (lp->rx_error_count >= MaxRxErrorCount) {1136		sb1000_wait_for_ready_clear(ioaddr, name);1137		sb1000_send_command(ioaddr, name, Command1);1138		sb1000_wait_for_ready(ioaddr, name);1139		sb1000_issue_read_command(ioaddr, name);1140		lp->rx_error_count = 0;1141	}1142 1143	return IRQ_HANDLED;1144}1145 1146static int sb1000_close(struct net_device *dev)1147{1148	int i;1149	int ioaddr[2];1150	struct sb1000_private *lp = netdev_priv(dev);1151 1152	if (sb1000_debug > 2)1153		printk(KERN_DEBUG "%s: Shutting down sb1000.\n", dev->name);1154 1155	netif_stop_queue(dev);1156 1157	ioaddr[0] = dev->base_addr;1158	/* mem_start holds the second I/O address */1159	ioaddr[1] = dev->mem_start;1160 1161	free_irq(dev->irq, dev);1162	/* If we don't do this, we can't re-insmod it later. */1163	release_region(ioaddr[1], SB1000_IO_EXTENT);1164	release_region(ioaddr[0], SB1000_IO_EXTENT);1165 1166	/* free rx_skb's if needed */1167	for (i=0; i<4; i++) {1168		if (lp->rx_skb[i]) {1169			dev_kfree_skb(lp->rx_skb[i]);1170		}1171	}1172	return 0;1173}1174 1175MODULE_AUTHOR("Franco Venturi <fventuri@mediaone.net>");1176MODULE_DESCRIPTION("General Instruments SB1000 driver");1177MODULE_LICENSE("GPL");1178 1179module_pnp_driver(sb1000_driver);1180