brintos

brintos / linux-shallow public Read only

0
0
Text · 34.1 KiB · 9e366f2 Raw
1318 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*****************************************************************************/3 4/*5 *	baycom_epp.c  -- baycom epp radio modem driver.6 *7 *	Copyright (C) 1998-20008 *          Thomas Sailer (sailer@ife.ee.ethz.ch)9 *10 *  Please note that the GPL allows you to use the driver, NOT the radio.11 *  In order to use the radio, you need a license from the communications12 *  authority of your country.13 *14 *  History:15 *   0.1  xx.xx.1998  Initial version by Matthias Welwarsky (dg2fef)16 *   0.2  21.04.1998  Massive rework by Thomas Sailer17 *                    Integrated FPGA EPP modem configuration routines18 *   0.3  11.05.1998  Took FPGA config out and moved it into a separate program19 *   0.4  26.07.1999  Adapted to new lowlevel parport driver interface20 *   0.5  03.08.1999  adapt to Linus' new __setup/__initcall21 *                    removed some pre-2.2 kernel compatibility cruft22 *   0.6  10.08.1999  Check if parport can do SPP and is safe to access during interrupt contexts23 *   0.7  12.02.2000  adapted to softnet driver interface24 */25 26/*****************************************************************************/27 28#include <linux/crc-ccitt.h>29#include <linux/module.h>30#include <linux/kernel.h>31#include <linux/init.h>32#include <linux/sched.h>33#include <linux/string.h>34#include <linux/workqueue.h>35#include <linux/fs.h>36#include <linux/parport.h>37#include <linux/if_arp.h>38#include <linux/hdlcdrv.h>39#include <linux/baycom.h>40#include <linux/jiffies.h>41#include <linux/random.h>42#include <net/ax25.h> 43#include <linux/uaccess.h>44 45/* --------------------------------------------------------------------- */46 47#define BAYCOM_DEBUG48#define BAYCOM_MAGIC 1973051049 50/* --------------------------------------------------------------------- */51 52static const char paranoia_str[] = KERN_ERR 53	"baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n";54 55static const char bc_drvname[] = "baycom_epp";56static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n"57"baycom_epp: version 0.7\n";58 59/* --------------------------------------------------------------------- */60 61#define NR_PORTS 462 63static struct net_device *baycom_device[NR_PORTS];64 65/* --------------------------------------------------------------------- */66 67/* EPP status register */68#define EPP_DCDBIT      0x8069#define EPP_PTTBIT      0x0870#define EPP_NREF        0x0171#define EPP_NRAEF       0x0272#define EPP_NRHF        0x0473#define EPP_NTHF        0x2074#define EPP_NTAEF       0x1075#define EPP_NTEF        EPP_PTTBIT76 77/* EPP control register */78#define EPP_TX_FIFO_ENABLE 0x1079#define EPP_RX_FIFO_ENABLE 0x0880#define EPP_MODEM_ENABLE   0x2081#define EPP_LEDS           0xC082#define EPP_IRQ_ENABLE     0x1083 84/* LPT registers */85#define LPTREG_ECONTROL       0x40286#define LPTREG_CONFIGB        0x40187#define LPTREG_CONFIGA        0x40088#define LPTREG_EPPDATA        0x00489#define LPTREG_EPPADDR        0x00390#define LPTREG_CONTROL        0x00291#define LPTREG_STATUS         0x00192#define LPTREG_DATA           0x00093 94/* LPT control register */95#define LPTCTRL_PROGRAM       0x04   /* 0 to reprogram */96#define LPTCTRL_WRITE         0x0197#define LPTCTRL_ADDRSTB       0x0898#define LPTCTRL_DATASTB       0x0299#define LPTCTRL_INTEN         0x10100 101/* LPT status register */102#define LPTSTAT_SHIFT_NINTR   6103#define LPTSTAT_WAIT          0x80104#define LPTSTAT_NINTR         (1<<LPTSTAT_SHIFT_NINTR)105#define LPTSTAT_PE            0x20106#define LPTSTAT_DONE          0x10107#define LPTSTAT_NERROR        0x08108#define LPTSTAT_EPPTIMEOUT    0x01109 110/* LPT data register */111#define LPTDATA_SHIFT_TDI     0112#define LPTDATA_SHIFT_TMS     2113#define LPTDATA_TDI           (1<<LPTDATA_SHIFT_TDI)114#define LPTDATA_TCK           0x02115#define LPTDATA_TMS           (1<<LPTDATA_SHIFT_TMS)116#define LPTDATA_INITBIAS      0x80117 118 119/* EPP modem config/status bits */120#define EPP_DCDBIT            0x80121#define EPP_PTTBIT            0x08122#define EPP_RXEBIT            0x01123#define EPP_RXAEBIT           0x02124#define EPP_RXHFULL           0x04125 126#define EPP_NTHF              0x20127#define EPP_NTAEF             0x10128#define EPP_NTEF              EPP_PTTBIT129 130#define EPP_TX_FIFO_ENABLE    0x10131#define EPP_RX_FIFO_ENABLE    0x08132#define EPP_MODEM_ENABLE      0x20133#define EPP_LEDS              0xC0134#define EPP_IRQ_ENABLE        0x10135 136/* Xilinx 4k JTAG instructions */137#define XC4K_IRLENGTH   3138#define XC4K_EXTEST     0139#define XC4K_PRELOAD    1140#define XC4K_CONFIGURE  5141#define XC4K_BYPASS     7142 143#define EPP_CONVENTIONAL  0144#define EPP_FPGA          1145#define EPP_FPGAEXTSTATUS 2146 147#define TXBUFFER_SIZE     ((HDLCDRV_MAXFLEN*6/5)+8)148 149/* ---------------------------------------------------------------------- */150/*151 * Information that need to be kept for each board.152 */153 154struct baycom_state {155	int magic;156 157        struct pardevice *pdev;158	struct net_device *dev;159	unsigned int work_running;160	struct delayed_work run_work;161	unsigned int modem;162	unsigned int bitrate;163	unsigned char stat;164 165	struct {166		unsigned int intclk;167		unsigned int fclk;168		unsigned int bps;169		unsigned int extmodem;170		unsigned int loopback;171	} cfg;172 173        struct hdlcdrv_channel_params ch_params;174 175        struct {176		unsigned int bitbuf, bitstream, numbits, state;177		unsigned char *bufptr;178		int bufcnt;179		unsigned char buf[TXBUFFER_SIZE];180        } hdlcrx;181 182        struct {183		int calibrate;184                int slotcnt;185		int flags;186		enum { tx_idle = 0, tx_keyup, tx_data, tx_tail } state;187		unsigned char *bufptr;188		int bufcnt;189		unsigned char buf[TXBUFFER_SIZE];190        } hdlctx;191 192	unsigned int ptt_keyed;193	struct sk_buff *skb;  /* next transmit packet  */194 195#ifdef BAYCOM_DEBUG196	struct debug_vals {197		unsigned long last_jiffies;198		unsigned cur_intcnt;199		unsigned last_intcnt;200		int cur_pllcorr;201		int last_pllcorr;202		unsigned int mod_cycles;203		unsigned int demod_cycles;204	} debug_vals;205#endif /* BAYCOM_DEBUG */206};207 208/* --------------------------------------------------------------------- */209 210#define KISS_VERBOSE211 212/* --------------------------------------------------------------------- */213 214#define PARAM_TXDELAY   1215#define PARAM_PERSIST   2216#define PARAM_SLOTTIME  3217#define PARAM_TXTAIL    4218#define PARAM_FULLDUP   5219#define PARAM_HARDWARE  6220#define PARAM_RETURN    255221 222/* --------------------------------------------------------------------- */223/*224 * the CRC routines are stolen from WAMPES225 * by Dieter Deyke226 */227 228 229/*---------------------------------------------------------------------------*/230 231#if 0232static inline void append_crc_ccitt(unsigned char *buffer, int len)233{234	unsigned int crc = 0xffff;235 236	for (;len>0;len--)237		crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff];238	crc ^= 0xffff;239	*buffer++ = crc;240	*buffer++ = crc >> 8;241}242#endif243 244/*---------------------------------------------------------------------------*/245 246static inline int check_crc_ccitt(const unsigned char *buf, int cnt)247{248	return (crc_ccitt(0xffff, buf, cnt) & 0xffff) == 0xf0b8;249}250 251/*---------------------------------------------------------------------------*/252 253static inline int calc_crc_ccitt(const unsigned char *buf, int cnt)254{255	return (crc_ccitt(0xffff, buf, cnt) ^ 0xffff) & 0xffff;256}257 258/* ---------------------------------------------------------------------- */259 260#define tenms_to_flags(bc,tenms) ((tenms * bc->bitrate) / 800)261 262/* --------------------------------------------------------------------- */263 264static inline void baycom_int_freq(struct baycom_state *bc)265{266#ifdef BAYCOM_DEBUG267	unsigned long cur_jiffies = jiffies;268	/*269	 * measure the interrupt frequency270	 */271	bc->debug_vals.cur_intcnt++;272	if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) {273		bc->debug_vals.last_jiffies = cur_jiffies;274		bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;275		bc->debug_vals.cur_intcnt = 0;276		bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;277		bc->debug_vals.cur_pllcorr = 0;278	}279#endif /* BAYCOM_DEBUG */280}281 282/* ---------------------------------------------------------------------- */283/*284 *    eppconfig_path should be setable  via /proc/sys.285 */286 287static char const eppconfig_path[] = "/usr/sbin/eppfpga";288 289static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL };290 291/* eppconfig: called during ifconfig up to configure the modem */292static int eppconfig(struct baycom_state *bc)293{294	char modearg[256];295	char portarg[16];296        char *argv[] = {297		(char *)eppconfig_path,298		"-s",299		"-p", portarg,300		"-m", modearg,301		NULL };302 303	/* set up arguments */304	sprintf(modearg, "%sclk,%smodem,fclk=%d,bps=%d,divider=%d%s,extstat",305		bc->cfg.intclk ? "int" : "ext",306		bc->cfg.extmodem ? "ext" : "int", bc->cfg.fclk, bc->cfg.bps,307		(bc->cfg.fclk + 8 * bc->cfg.bps) / (16 * bc->cfg.bps),308		bc->cfg.loopback ? ",loopback" : "");309	sprintf(portarg, "%ld", bc->pdev->port->base);310	printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg);311 312	return call_usermodehelper(eppconfig_path, argv, envp, UMH_WAIT_PROC);313}314 315/* ---------------------------------------------------------------------- */316 317static inline void do_kiss_params(struct baycom_state *bc,318				  unsigned char *data, unsigned long len)319{320 321#ifdef KISS_VERBOSE322#define PKP(a,b) printk(KERN_INFO "baycomm_epp: channel params: " a "\n", b)323#else /* KISS_VERBOSE */	      324#define PKP(a,b) 325#endif /* KISS_VERBOSE */	      326 327	if (len < 2)328		return;329	switch(data[0]) {330	case PARAM_TXDELAY:331		bc->ch_params.tx_delay = data[1];332		PKP("TX delay = %ums", 10 * bc->ch_params.tx_delay);333		break;334	case PARAM_PERSIST:   335		bc->ch_params.ppersist = data[1];336		PKP("p persistence = %u", bc->ch_params.ppersist);337		break;338	case PARAM_SLOTTIME:  339		bc->ch_params.slottime = data[1];340		PKP("slot time = %ums", bc->ch_params.slottime);341		break;342	case PARAM_TXTAIL:    343		bc->ch_params.tx_tail = data[1];344		PKP("TX tail = %ums", bc->ch_params.tx_tail);345		break;346	case PARAM_FULLDUP:   347		bc->ch_params.fulldup = !!data[1];348		PKP("%s duplex", bc->ch_params.fulldup ? "full" : "half");349		break;350	default:351		break;352	}353#undef PKP354}355 356/* --------------------------------------------------------------------- */357 358static void encode_hdlc(struct baycom_state *bc)359{360	struct sk_buff *skb;361	unsigned char *wp, *bp;362	int pkt_len;363        unsigned bitstream, notbitstream, bitbuf, numbit, crc;364	unsigned char crcarr[2];365	int j;366	367	if (bc->hdlctx.bufcnt > 0)368		return;369	skb = bc->skb;370	if (!skb)371		return;372	bc->skb = NULL;373	pkt_len = skb->len-1; /* strip KISS byte */374	wp = bc->hdlctx.buf;375	bp = skb->data+1;376	crc = calc_crc_ccitt(bp, pkt_len);377	crcarr[0] = crc;378	crcarr[1] = crc >> 8;379	*wp++ = 0x7e;380	bitstream = bitbuf = numbit = 0;381	while (pkt_len > -2) {382		bitstream >>= 8;383		bitstream |= ((unsigned int)*bp) << 8;384		bitbuf |= ((unsigned int)*bp) << numbit;385		notbitstream = ~bitstream;386		bp++;387		pkt_len--;388		if (!pkt_len)389			bp = crcarr;390		for (j = 0; j < 8; j++)391			if (unlikely(!(notbitstream & (0x1f0 << j)))) {392				bitstream &= ~(0x100 << j);393				bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) |394					((bitbuf & ~(((2 << j) << numbit) - 1)) << 1);395				numbit++;396				notbitstream = ~bitstream;397			}398		numbit += 8;399		while (numbit >= 8) {400			*wp++ = bitbuf;401			bitbuf >>= 8;402			numbit -= 8;403		}404	}405	bitbuf |= 0x7e7e << numbit;406	numbit += 16;407	while (numbit >= 8) {408		*wp++ = bitbuf;409		bitbuf >>= 8;410		numbit -= 8;411	}412	bc->hdlctx.bufptr = bc->hdlctx.buf;413	bc->hdlctx.bufcnt = wp - bc->hdlctx.buf;414	dev_kfree_skb(skb);415	bc->dev->stats.tx_packets++;416}417 418/* ---------------------------------------------------------------------- */419 420static int transmit(struct baycom_state *bc, int cnt, unsigned char stat)421{422	struct parport *pp = bc->pdev->port;423	unsigned char tmp[128];424	int i, j;425 426	if (bc->hdlctx.state == tx_tail && !(stat & EPP_PTTBIT))427		bc->hdlctx.state = tx_idle;428	if (bc->hdlctx.state == tx_idle && bc->hdlctx.calibrate <= 0) {429		if (bc->hdlctx.bufcnt <= 0)430			encode_hdlc(bc);431		if (bc->hdlctx.bufcnt <= 0)432			return 0;433		if (!bc->ch_params.fulldup) {434			if (!(stat & EPP_DCDBIT)) {435				bc->hdlctx.slotcnt = bc->ch_params.slottime;436				return 0;437			}438			if ((--bc->hdlctx.slotcnt) > 0)439				return 0;440			bc->hdlctx.slotcnt = bc->ch_params.slottime;441			if (get_random_u8() > bc->ch_params.ppersist)442				return 0;443		}444	}445	if (bc->hdlctx.state == tx_idle && bc->hdlctx.bufcnt > 0) {446		bc->hdlctx.state = tx_keyup;447		bc->hdlctx.flags = tenms_to_flags(bc, bc->ch_params.tx_delay);448		bc->ptt_keyed++;449	}450	while (cnt > 0) {451		switch (bc->hdlctx.state) {452		case tx_keyup:453			i = min_t(int, cnt, bc->hdlctx.flags);454			cnt -= i;455			bc->hdlctx.flags -= i;456			if (bc->hdlctx.flags <= 0)457				bc->hdlctx.state = tx_data;458			memset(tmp, 0x7e, sizeof(tmp));459			while (i > 0) {460				j = (i > sizeof(tmp)) ? sizeof(tmp) : i;461				if (j != pp->ops->epp_write_data(pp, tmp, j, 0))462					return -1;463				i -= j;464			}465			break;466 467		case tx_data:468			if (bc->hdlctx.bufcnt <= 0) {469				encode_hdlc(bc);470				if (bc->hdlctx.bufcnt <= 0) {471					bc->hdlctx.state = tx_tail;472					bc->hdlctx.flags = tenms_to_flags(bc, bc->ch_params.tx_tail);473					break;474				}475			}476			i = min_t(int, cnt, bc->hdlctx.bufcnt);477			bc->hdlctx.bufcnt -= i;478			cnt -= i;479			if (i != pp->ops->epp_write_data(pp, bc->hdlctx.bufptr, i, 0))480					return -1;481			bc->hdlctx.bufptr += i;482			break;483			484		case tx_tail:485			encode_hdlc(bc);486			if (bc->hdlctx.bufcnt > 0) {487				bc->hdlctx.state = tx_data;488				break;489			}490			i = min_t(int, cnt, bc->hdlctx.flags);491			if (i) {492				cnt -= i;493				bc->hdlctx.flags -= i;494				memset(tmp, 0x7e, sizeof(tmp));495				while (i > 0) {496					j = (i > sizeof(tmp)) ? sizeof(tmp) : i;497					if (j != pp->ops->epp_write_data(pp, tmp, j, 0))498						return -1;499					i -= j;500				}501				break;502			}503			fallthrough;504 505		default:506			if (bc->hdlctx.calibrate <= 0)507				return 0;508			i = min_t(int, cnt, bc->hdlctx.calibrate);509			cnt -= i;510			bc->hdlctx.calibrate -= i;511			memset(tmp, 0, sizeof(tmp));512			while (i > 0) {513				j = (i > sizeof(tmp)) ? sizeof(tmp) : i;514				if (j != pp->ops->epp_write_data(pp, tmp, j, 0))515					return -1;516				i -= j;517			}518			break;519		}520	}521	return 0;522}523 524/* ---------------------------------------------------------------------- */525 526static void do_rxpacket(struct net_device *dev)527{528	struct baycom_state *bc = netdev_priv(dev);529	struct sk_buff *skb;530	unsigned char *cp;531	unsigned pktlen;532 533	if (bc->hdlcrx.bufcnt < 4) 534		return;535	if (!check_crc_ccitt(bc->hdlcrx.buf, bc->hdlcrx.bufcnt)) 536		return;537	pktlen = bc->hdlcrx.bufcnt-2+1; /* KISS kludge */538	if (!(skb = dev_alloc_skb(pktlen))) {539		printk("%s: memory squeeze, dropping packet\n", dev->name);540		dev->stats.rx_dropped++;541		return;542	}543	cp = skb_put(skb, pktlen);544	*cp++ = 0; /* KISS kludge */545	memcpy(cp, bc->hdlcrx.buf, pktlen - 1);546	skb->protocol = ax25_type_trans(skb, dev);547	netif_rx(skb);548	dev->stats.rx_packets++;549}550 551static int receive(struct net_device *dev, int cnt)552{553	struct baycom_state *bc = netdev_priv(dev);554	struct parport *pp = bc->pdev->port;555        unsigned int bitbuf, notbitstream, bitstream, numbits, state;556	unsigned char tmp[128];557        unsigned char *cp;558	int cnt2, ret = 0;559	int j;560        561        numbits = bc->hdlcrx.numbits;562	state = bc->hdlcrx.state;563	bitstream = bc->hdlcrx.bitstream;564	bitbuf = bc->hdlcrx.bitbuf;565	while (cnt > 0) {566		cnt2 = (cnt > sizeof(tmp)) ? sizeof(tmp) : cnt;567		cnt -= cnt2;568		if (cnt2 != pp->ops->epp_read_data(pp, tmp, cnt2, 0)) {569			ret = -1;570			break;571		}572		cp = tmp;573		for (; cnt2 > 0; cnt2--, cp++) {574			bitstream >>= 8;575			bitstream |= (*cp) << 8;576			bitbuf >>= 8;577			bitbuf |= (*cp) << 8;578			numbits += 8;579			notbitstream = ~bitstream;580			for (j = 0; j < 8; j++) {581 582				/* flag or abort */583			        if (unlikely(!(notbitstream & (0x0fc << j)))) {584 585					/* abort received */586					if (!(notbitstream & (0x1fc << j)))587						state = 0;588 589					/* flag received */590					else if ((bitstream & (0x1fe << j)) == (0x0fc << j)) {591						if (state)592							do_rxpacket(dev);593						bc->hdlcrx.bufcnt = 0;594						bc->hdlcrx.bufptr = bc->hdlcrx.buf;595						state = 1;596						numbits = 7-j;597					}598				}599 600				/* stuffed bit */601				else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) {602					numbits--;603					bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1);604					}605				}606			while (state && numbits >= 8) {607				if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) {608					state = 0;609				} else {610					*(bc->hdlcrx.bufptr)++ = bitbuf >> (16-numbits);611					bc->hdlcrx.bufcnt++;612					numbits -= 8;613				}614			}615		}616	}617        bc->hdlcrx.numbits = numbits;618	bc->hdlcrx.state = state;619	bc->hdlcrx.bitstream = bitstream;620	bc->hdlcrx.bitbuf = bitbuf;621	return ret;622}623 624/* --------------------------------------------------------------------- */625 626#define GETTICK(x)						\627({								\628	x = (unsigned int)get_cycles();				\629})630 631static void epp_bh(struct work_struct *work)632{633	struct net_device *dev;634	struct baycom_state *bc;635	struct parport *pp;636	unsigned char stat;637	unsigned char tmp[2];638	unsigned int time1 = 0, time2 = 0, time3 = 0;639	int cnt, cnt2;640 641	bc = container_of(work, struct baycom_state, run_work.work);642	dev = bc->dev;643	if (!bc->work_running)644		return;645	baycom_int_freq(bc);646	pp = bc->pdev->port;647	/* update status */648	if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)649		goto epptimeout;650	bc->stat = stat;651	bc->debug_vals.last_pllcorr = stat;652	GETTICK(time1);653	if (bc->modem == EPP_FPGAEXTSTATUS) {654		/* get input count */655		tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|1;656		if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1)657			goto epptimeout;658		if (pp->ops->epp_read_addr(pp, tmp, 2, 0) != 2)659			goto epptimeout;660		cnt = tmp[0] | (tmp[1] << 8);661		cnt &= 0x7fff;662		/* get output count */663		tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|2;664		if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1)665			goto epptimeout;666		if (pp->ops->epp_read_addr(pp, tmp, 2, 0) != 2)667			goto epptimeout;668		cnt2 = tmp[0] | (tmp[1] << 8);669		cnt2 = 16384 - (cnt2 & 0x7fff);670		/* return to normal */671		tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE;672		if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1)673			goto epptimeout;674		if (transmit(bc, cnt2, stat))675			goto epptimeout;676		GETTICK(time2);677		if (receive(dev, cnt))678			goto epptimeout;679		if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)680			goto epptimeout;681		bc->stat = stat;682	} else {683		/* try to tx */684		switch (stat & (EPP_NTAEF|EPP_NTHF)) {685		case EPP_NTHF:686			cnt = 2048 - 256;687			break;688		689		case EPP_NTAEF:690			cnt = 2048 - 1793;691			break;692		693		case 0:694			cnt = 0;695			break;696		697		default:698			cnt = 2048 - 1025;699			break;700		}701		if (transmit(bc, cnt, stat))702			goto epptimeout;703		GETTICK(time2);704		/* do receiver */705		while ((stat & (EPP_NRAEF|EPP_NRHF)) != EPP_NRHF) {706			switch (stat & (EPP_NRAEF|EPP_NRHF)) {707			case EPP_NRAEF:708				cnt = 1025;709				break;710 711			case 0:712				cnt = 1793;713				break;714 715			default:716				cnt = 256;717				break;718			}719			if (receive(dev, cnt))720				goto epptimeout;721			if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)722				goto epptimeout;723		}724		cnt = 0;725		if (bc->bitrate < 50000)726			cnt = 256;727		else if (bc->bitrate < 100000)728			cnt = 128;729		while (cnt > 0 && stat & EPP_NREF) {730			if (receive(dev, 1))731				goto epptimeout;732			cnt--;733			if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)734				goto epptimeout;735		}736	}737	GETTICK(time3);738#ifdef BAYCOM_DEBUG739	bc->debug_vals.mod_cycles = time2 - time1;740	bc->debug_vals.demod_cycles = time3 - time2;741#endif /* BAYCOM_DEBUG */742	schedule_delayed_work(&bc->run_work, 1);743	if (!bc->skb)744		netif_wake_queue(dev);745	return;746 epptimeout:747	printk(KERN_ERR "%s: EPP timeout!\n", bc_drvname);748}749 750/* ---------------------------------------------------------------------- */751/*752 * ===================== network driver interface =========================753 */754 755static netdev_tx_t baycom_send_packet(struct sk_buff *skb, struct net_device *dev)756{757	struct baycom_state *bc = netdev_priv(dev);758 759	if (skb->protocol == htons(ETH_P_IP))760		return ax25_ip_xmit(skb);761 762	if (skb->data[0] != 0) {763		do_kiss_params(bc, skb->data, skb->len);764		dev_kfree_skb(skb);765		return NETDEV_TX_OK;766	}767	if (bc->skb) {768		dev_kfree_skb(skb);769		return NETDEV_TX_OK;770	}771	/* strip KISS byte */772	if (skb->len >= HDLCDRV_MAXFLEN+1 || skb->len < 3) {773		dev_kfree_skb(skb);774		return NETDEV_TX_OK;775	}776	netif_stop_queue(dev);777	bc->skb = skb;778	return NETDEV_TX_OK;779}780 781/* --------------------------------------------------------------------- */782 783static int baycom_set_mac_address(struct net_device *dev, void *addr)784{785	struct sockaddr *sa = (struct sockaddr *)addr;786 787	/* addr is an AX.25 shifted ASCII mac address */788	dev_addr_set(dev, sa->sa_data);789	return 0;                                         790}791 792/* --------------------------------------------------------------------- */793 794static void epp_wakeup(void *handle)795{796        struct net_device *dev = (struct net_device *)handle;797        struct baycom_state *bc = netdev_priv(dev);798 799        printk(KERN_DEBUG "baycom_epp: %s: why am I being woken up?\n", dev->name);800        if (!parport_claim(bc->pdev))801                printk(KERN_DEBUG "baycom_epp: %s: I'm broken.\n", dev->name);802}803 804/* --------------------------------------------------------------------- */805 806/*807 * Open/initialize the board. This is called (in the current kernel)808 * sometime after booting when the 'ifconfig' program is run.809 *810 * This routine should set everything up anew at each open, even811 * registers that "should" only need to be set once at boot, so that812 * there is non-reboot way to recover if something goes wrong.813 */814 815static int epp_open(struct net_device *dev)816{817	struct baycom_state *bc = netdev_priv(dev);818        struct parport *pp = parport_find_base(dev->base_addr);819	unsigned int i, j;820	unsigned char tmp[128];821	unsigned char stat;822	unsigned long tstart;823	struct pardev_cb par_cb;824	825        if (!pp) {826                printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr);827                return -ENXIO;828        }829#if 0830        if (pp->irq < 0) {831                printk(KERN_ERR "%s: parport at 0x%lx has no irq\n", bc_drvname, pp->base);832		parport_put_port(pp);833                return -ENXIO;834        }835#endif836	if ((~pp->modes) & (PARPORT_MODE_TRISTATE | PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) {837                printk(KERN_ERR "%s: parport at 0x%lx cannot be used\n",838		       bc_drvname, pp->base);839		parport_put_port(pp);840                return -EIO;841	}842	memset(&bc->modem, 0, sizeof(bc->modem));843	memset(&par_cb, 0, sizeof(par_cb));844	par_cb.wakeup = epp_wakeup;845	par_cb.private = (void *)dev;846	par_cb.flags = PARPORT_DEV_EXCL;847	for (i = 0; i < NR_PORTS; i++)848		if (baycom_device[i] == dev)849			break;850 851	if (i == NR_PORTS) {852		pr_err("%s: no device found\n", bc_drvname);853		parport_put_port(pp);854		return -ENODEV;855	}856 857	bc->pdev = parport_register_dev_model(pp, dev->name, &par_cb, i);858	parport_put_port(pp);859        if (!bc->pdev) {860                printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base);861                return -ENXIO;862        }863        if (parport_claim(bc->pdev)) {864                printk(KERN_ERR "%s: parport at 0x%lx busy\n", bc_drvname, pp->base);865                parport_unregister_device(bc->pdev);866                return -EBUSY;867        }868        dev->irq = /*pp->irq*/ 0;869	INIT_DELAYED_WORK(&bc->run_work, epp_bh);870	bc->work_running = 1;871	bc->modem = EPP_CONVENTIONAL;872	if (eppconfig(bc))873		printk(KERN_INFO "%s: no FPGA detected, assuming conventional EPP modem\n", bc_drvname);874	else875		bc->modem = /*EPP_FPGA*/ EPP_FPGAEXTSTATUS;876	parport_write_control(pp, LPTCTRL_PROGRAM); /* prepare EPP mode; we aren't using interrupts */877	/* reset the modem */878	tmp[0] = 0;879	tmp[1] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE;880	if (pp->ops->epp_write_addr(pp, tmp, 2, 0) != 2)881		goto epptimeout;882	/* autoprobe baud rate */883	tstart = jiffies;884	i = 0;885	while (time_before(jiffies, tstart + HZ/3)) {886		if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)887			goto epptimeout;888		if ((stat & (EPP_NRAEF|EPP_NRHF)) == EPP_NRHF) {889			schedule();890			continue;891		}892		if (pp->ops->epp_read_data(pp, tmp, 128, 0) != 128)893			goto epptimeout;894		if (pp->ops->epp_read_data(pp, tmp, 128, 0) != 128)895			goto epptimeout;896		i += 256;897	}898	for (j = 0; j < 256; j++) {899		if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1)900			goto epptimeout;901		if (!(stat & EPP_NREF))902			break;903		if (pp->ops->epp_read_data(pp, tmp, 1, 0) != 1)904			goto epptimeout;905		i++;906	}907	tstart = jiffies - tstart;908	bc->bitrate = i * (8 * HZ) / tstart;909	j = 1;910	i = bc->bitrate >> 3;911	while (j < 7 && i > 150) {912		j++;913		i >>= 1;914	}915	printk(KERN_INFO "%s: autoprobed bitrate: %d  int divider: %d  int rate: %d\n", 916	       bc_drvname, bc->bitrate, j, bc->bitrate >> (j+2));917	tmp[0] = EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE/*|j*/;918	if (pp->ops->epp_write_addr(pp, tmp, 1, 0) != 1)919		goto epptimeout;920	/*921	 * initialise hdlc variables922	 */923	bc->hdlcrx.state = 0;924	bc->hdlcrx.numbits = 0;925	bc->hdlctx.state = tx_idle;926	bc->hdlctx.bufcnt = 0;927	bc->hdlctx.slotcnt = bc->ch_params.slottime;928	bc->hdlctx.calibrate = 0;929	/* start the bottom half stuff */930	schedule_delayed_work(&bc->run_work, 1);931	netif_start_queue(dev);932	return 0;933 934 epptimeout:935	printk(KERN_ERR "%s: epp timeout during bitrate probe\n", bc_drvname);936	parport_write_control(pp, 0); /* reset the adapter */937        parport_release(bc->pdev);938        parport_unregister_device(bc->pdev);939	return -EIO;940}941 942/* --------------------------------------------------------------------- */943 944static int epp_close(struct net_device *dev)945{946	struct baycom_state *bc = netdev_priv(dev);947	struct parport *pp = bc->pdev->port;948	unsigned char tmp[1];949 950	bc->work_running = 0;951	cancel_delayed_work_sync(&bc->run_work);952	bc->stat = EPP_DCDBIT;953	tmp[0] = 0;954	pp->ops->epp_write_addr(pp, tmp, 1, 0);955	parport_write_control(pp, 0); /* reset the adapter */956        parport_release(bc->pdev);957        parport_unregister_device(bc->pdev);958	dev_kfree_skb(bc->skb);959	bc->skb = NULL;960	printk(KERN_INFO "%s: close epp at iobase 0x%lx irq %u\n",961	       bc_drvname, dev->base_addr, dev->irq);962	return 0;963}964 965/* --------------------------------------------------------------------- */966 967static int baycom_setmode(struct baycom_state *bc, const char *modestr)968{969	const char *cp;970 971	if (strstr(modestr,"intclk"))972		bc->cfg.intclk = 1;973	if (strstr(modestr,"extclk"))974		bc->cfg.intclk = 0;975	if (strstr(modestr,"intmodem"))976		bc->cfg.extmodem = 0;977	if (strstr(modestr,"extmodem"))978		bc->cfg.extmodem = 1;979	if (strstr(modestr,"loopback"))980		bc->cfg.loopback = 1;981	if (strstr(modestr, "noloopback"))982		bc->cfg.loopback = 0;983	if ((cp = strstr(modestr,"fclk="))) {984		bc->cfg.fclk = simple_strtoul(cp+5, NULL, 0);985		if (bc->cfg.fclk < 1000000)986			bc->cfg.fclk = 1000000;987		if (bc->cfg.fclk > 25000000)988			bc->cfg.fclk = 25000000;989	}990	if ((cp = strstr(modestr,"bps="))) {991		bc->cfg.bps = simple_strtoul(cp+4, NULL, 0);992		if (bc->cfg.bps < 1000)993			bc->cfg.bps = 1000;994		if (bc->cfg.bps > 1500000)995			bc->cfg.bps = 1500000;996	}997	return 0;998}999 1000/* --------------------------------------------------------------------- */1001 1002static int baycom_siocdevprivate(struct net_device *dev, struct ifreq *ifr,1003				 void __user *data, int cmd)1004{1005	struct baycom_state *bc = netdev_priv(dev);1006	struct hdlcdrv_ioctl hi;1007 1008	if (cmd != SIOCDEVPRIVATE)1009		return -ENOIOCTLCMD;1010 1011	if (copy_from_user(&hi, data, sizeof(hi)))1012		return -EFAULT;1013	switch (hi.cmd) {1014	default:1015		return -ENOIOCTLCMD;1016 1017	case HDLCDRVCTL_GETCHANNELPAR:1018		hi.data.cp.tx_delay = bc->ch_params.tx_delay;1019		hi.data.cp.tx_tail = bc->ch_params.tx_tail;1020		hi.data.cp.slottime = bc->ch_params.slottime;1021		hi.data.cp.ppersist = bc->ch_params.ppersist;1022		hi.data.cp.fulldup = bc->ch_params.fulldup;1023		break;1024 1025	case HDLCDRVCTL_SETCHANNELPAR:1026		if (!capable(CAP_NET_ADMIN))1027			return -EACCES;1028		bc->ch_params.tx_delay = hi.data.cp.tx_delay;1029		bc->ch_params.tx_tail = hi.data.cp.tx_tail;1030		bc->ch_params.slottime = hi.data.cp.slottime;1031		bc->ch_params.ppersist = hi.data.cp.ppersist;1032		bc->ch_params.fulldup = hi.data.cp.fulldup;1033		bc->hdlctx.slotcnt = 1;1034		return 0;1035		1036	case HDLCDRVCTL_GETMODEMPAR:1037		hi.data.mp.iobase = dev->base_addr;1038		hi.data.mp.irq = dev->irq;1039		hi.data.mp.dma = dev->dma;1040		hi.data.mp.dma2 = 0;1041		hi.data.mp.seriobase = 0;1042		hi.data.mp.pariobase = 0;1043		hi.data.mp.midiiobase = 0;1044		break;1045 1046	case HDLCDRVCTL_SETMODEMPAR:1047		if ((!capable(CAP_SYS_RAWIO)) || netif_running(dev))1048			return -EACCES;1049		dev->base_addr = hi.data.mp.iobase;1050		dev->irq = /*hi.data.mp.irq*/0;1051		dev->dma = /*hi.data.mp.dma*/0;1052		return 0;	1053		1054	case HDLCDRVCTL_GETSTAT:1055		hi.data.cs.ptt = !!(bc->stat & EPP_PTTBIT);1056		hi.data.cs.dcd = !(bc->stat & EPP_DCDBIT);1057		hi.data.cs.ptt_keyed = bc->ptt_keyed;1058		hi.data.cs.tx_packets = dev->stats.tx_packets;1059		hi.data.cs.tx_errors = dev->stats.tx_errors;1060		hi.data.cs.rx_packets = dev->stats.rx_packets;1061		hi.data.cs.rx_errors = dev->stats.rx_errors;1062		break;		1063 1064	case HDLCDRVCTL_OLDGETSTAT:1065		hi.data.ocs.ptt = !!(bc->stat & EPP_PTTBIT);1066		hi.data.ocs.dcd = !(bc->stat & EPP_DCDBIT);1067		hi.data.ocs.ptt_keyed = bc->ptt_keyed;1068		break;		1069 1070	case HDLCDRVCTL_CALIBRATE:1071		if (!capable(CAP_SYS_RAWIO))1072			return -EACCES;1073		bc->hdlctx.calibrate = hi.data.calibrate * bc->bitrate / 8;1074		return 0;1075 1076	case HDLCDRVCTL_DRIVERNAME:1077		strscpy_pad(hi.data.drivername, "baycom_epp", sizeof(hi.data.drivername));1078		break;1079		1080	case HDLCDRVCTL_GETMODE:1081		sprintf(hi.data.modename, "%sclk,%smodem,fclk=%d,bps=%d%s", 1082			bc->cfg.intclk ? "int" : "ext",1083			bc->cfg.extmodem ? "ext" : "int", bc->cfg.fclk, bc->cfg.bps,1084			bc->cfg.loopback ? ",loopback" : "");1085		break;1086 1087	case HDLCDRVCTL_SETMODE:1088		if (!capable(CAP_NET_ADMIN) || netif_running(dev))1089			return -EACCES;1090		hi.data.modename[sizeof(hi.data.modename)-1] = '\0';1091		return baycom_setmode(bc, hi.data.modename);1092 1093	case HDLCDRVCTL_MODELIST:1094		strscpy_pad(hi.data.modename, "intclk,extclk,intmodem,extmodem,divider=x",1095			sizeof(hi.data.modename));1096		break;1097 1098	case HDLCDRVCTL_MODEMPARMASK:1099		return HDLCDRV_PARMASK_IOBASE;1100 1101	}1102	if (copy_to_user(data, &hi, sizeof(hi)))1103		return -EFAULT;1104	return 0;1105}1106 1107/* --------------------------------------------------------------------- */1108 1109static const struct net_device_ops baycom_netdev_ops = {1110	.ndo_open	     = epp_open,1111	.ndo_stop	     = epp_close,1112	.ndo_siocdevprivate  = baycom_siocdevprivate,1113	.ndo_start_xmit      = baycom_send_packet,1114	.ndo_set_mac_address = baycom_set_mac_address,1115};1116 1117/*1118 * Check for a network adaptor of this type, and return '0' if one exists.1119 * If dev->base_addr == 0, probe all likely locations.1120 * If dev->base_addr == 1, always return failure.1121 * If dev->base_addr == 2, allocate space for the device and return success1122 * (detachable devices only).1123 */1124static void baycom_probe(struct net_device *dev)1125{1126	const struct hdlcdrv_channel_params dflt_ch_params = { 1127		20, 2, 10, 40, 0 1128	};1129	struct baycom_state *bc;1130 1131	/*1132	 * not a real probe! only initialize data structures1133	 */1134	bc = netdev_priv(dev);1135	/*1136	 * initialize the baycom_state struct1137	 */1138	bc->ch_params = dflt_ch_params;1139	bc->ptt_keyed = 0;1140 1141	/*1142	 * initialize the device struct1143	 */1144 1145	/* Fill in the fields of the device structure */1146	bc->skb = NULL;1147	1148	dev->netdev_ops = &baycom_netdev_ops;1149	dev->header_ops = &ax25_header_ops;1150	1151	dev->type = ARPHRD_AX25;           /* AF_AX25 device */1152	dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;1153	dev->mtu = AX25_DEF_PACLEN;        /* eth_mtu is the default */1154	dev->addr_len = AX25_ADDR_LEN;     /* sizeof an ax.25 address */1155	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);1156	dev_addr_set(dev, (u8 *)&null_ax25_address);1157	dev->tx_queue_len = 16;1158 1159	/* New style flags */1160	dev->flags = 0;1161}1162 1163/* --------------------------------------------------------------------- */1164 1165/*1166 * command line settable parameters1167 */1168static char *mode[NR_PORTS] = { "", };1169static int iobase[NR_PORTS] = { 0x378, };1170 1171module_param_array(mode, charp, NULL, 0);1172MODULE_PARM_DESC(mode, "baycom operating mode");1173module_param_hw_array(iobase, int, ioport, NULL, 0);1174MODULE_PARM_DESC(iobase, "baycom io base address");1175 1176MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");1177MODULE_DESCRIPTION("Baycom epp amateur radio modem driver");1178MODULE_LICENSE("GPL");1179 1180/* --------------------------------------------------------------------- */1181 1182static int baycom_epp_par_probe(struct pardevice *par_dev)1183{1184	struct device_driver *drv = par_dev->dev.driver;1185	int len = strlen(drv->name);1186 1187	if (strncmp(par_dev->name, drv->name, len))1188		return -ENODEV;1189 1190	return 0;1191}1192 1193static struct parport_driver baycom_epp_par_driver = {1194	.name = "bce",1195	.probe = baycom_epp_par_probe,1196};1197 1198static void __init baycom_epp_dev_setup(struct net_device *dev)1199{1200	struct baycom_state *bc = netdev_priv(dev);1201 1202	/*1203	 * initialize part of the baycom_state struct1204	 */1205	bc->dev = dev;1206	bc->magic = BAYCOM_MAGIC;1207	bc->cfg.fclk = 19666600;1208	bc->cfg.bps = 9600;1209	/*1210	 * initialize part of the device struct1211	 */1212	baycom_probe(dev);1213}1214 1215static int __init init_baycomepp(void)1216{1217	int i, found = 0, ret;1218	char set_hw = 1;1219 1220	printk(bc_drvinfo);1221 1222	ret = parport_register_driver(&baycom_epp_par_driver);1223	if (ret)1224		return ret;1225 1226	/*1227	 * register net devices1228	 */1229	for (i = 0; i < NR_PORTS; i++) {1230		struct net_device *dev;1231		1232		dev = alloc_netdev(sizeof(struct baycom_state), "bce%d",1233				   NET_NAME_UNKNOWN, baycom_epp_dev_setup);1234 1235		if (!dev) {1236			printk(KERN_WARNING "bce%d : out of memory\n", i);1237			return found ? 0 : -ENOMEM;1238		}1239			1240		sprintf(dev->name, "bce%d", i);1241		dev->base_addr = iobase[i];1242 1243		if (!mode[i])1244			set_hw = 0;1245		if (!set_hw)1246			iobase[i] = 0;1247 1248		if (register_netdev(dev)) {1249			printk(KERN_WARNING "%s: cannot register net device %s\n", bc_drvname, dev->name);1250			free_netdev(dev);1251			break;1252		}1253		if (set_hw && baycom_setmode(netdev_priv(dev), mode[i]))1254			set_hw = 0;1255		baycom_device[i] = dev;1256		found++;1257	}1258 1259	if (found == 0) {1260		parport_unregister_driver(&baycom_epp_par_driver);1261		return -ENXIO;1262	}1263 1264	return 0;1265}1266 1267static void __exit cleanup_baycomepp(void)1268{1269	int i;1270 1271	for(i = 0; i < NR_PORTS; i++) {1272		struct net_device *dev = baycom_device[i];1273 1274		if (dev) {1275			struct baycom_state *bc = netdev_priv(dev);1276			if (bc->magic == BAYCOM_MAGIC) {1277				unregister_netdev(dev);1278				free_netdev(dev);1279			} else1280				printk(paranoia_str, "cleanup_module");1281		}1282	}1283	parport_unregister_driver(&baycom_epp_par_driver);1284}1285 1286module_init(init_baycomepp);1287module_exit(cleanup_baycomepp);1288 1289/* --------------------------------------------------------------------- */1290 1291#ifndef MODULE1292 1293/*1294 * format: baycom_epp=io,mode1295 * mode: fpga config options1296 */1297 1298static int __init baycom_epp_setup(char *str)1299{1300        static unsigned __initdata nr_dev = 0;1301	int ints[2];1302 1303        if (nr_dev >= NR_PORTS)1304                return 0;1305	str = get_options(str, 2, ints);1306	if (ints[0] < 1)1307		return 0;1308	mode[nr_dev] = str;1309	iobase[nr_dev] = ints[1];1310	nr_dev++;1311	return 1;1312}1313 1314__setup("baycom_epp=", baycom_epp_setup);1315 1316#endif /* MODULE */1317/* --------------------------------------------------------------------- */1318