Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

baycom_epp.c

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 
00003 /*
00004  *      baycom_epp.c  -- baycom epp radio modem driver.
00005  *
00006  *      Copyright (C) 1998
00007  *          Thomas Sailer (sailer@ife.ee.ethz.ch)
00008  *
00009  *      This program is free software; you can redistribute it and/or modify
00010  *      it under the terms of the GNU General Public License as published by
00011  *      the Free Software Foundation; either version 2 of the License, or
00012  *      (at your option) any later version.
00013  *
00014  *      This program is distributed in the hope that it will be useful,
00015  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *      GNU General Public License for more details.
00018  *
00019  *      You should have received a copy of the GNU General Public License
00020  *      along with this program; if not, write to the Free Software
00021  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022  *
00023  *  Please note that the GPL allows you to use the driver, NOT the radio.
00024  *  In order to use the radio, you need a license from the communications
00025  *  authority of your country.
00026  *
00027  *
00028  *  History:
00029  *   0.1  xx.xx.98  Initial version by Matthias Welwarsky (dg2fef)
00030  *   0.2  21.04.98  Massive rework by Thomas Sailer
00031  *                  Integrated FPGA EPP modem configuration routines
00032  *   0.3  11.05.98  Took FPGA config out and moved it into a separate program
00033  *
00034  */
00035 
00036 /*****************************************************************************/
00037 
00038 #include <linux/config.h>
00039 #include <linux/module.h>
00040 #include <linux/kernel.h>
00041 #include <linux/types.h>
00042 #include <linux/ptrace.h>
00043 #include <linux/socket.h>
00044 #include <linux/sched.h>
00045 #include <linux/interrupt.h>
00046 #include <linux/ioport.h>
00047 #include <linux/in.h>
00048 #include <linux/string.h>
00049 #include <linux/parport.h>
00050 #include <linux/bitops.h>
00051 #include <asm/system.h>
00052 #include <asm/io.h>
00053 #include <asm/processor.h>
00054 #include <asm/uaccess.h>
00055 #include <linux/delay.h>
00056 #include <linux/errno.h>
00057 #include <linux/netdevice.h>
00058 #include <linux/if_arp.h>
00059 //#include <net/ax25dev.h>
00060 #include <linux/kmod.h>
00061 #include <linux/init.h>
00062 #include <linux/hdlcdrv.h>
00063 #include <linux/baycom.h>
00064 #include <linux/soundmodem.h>
00065 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
00066 /* prototypes for ax25_encapsulate and ax25_rebuild_header */
00067 #include <net/ax25.h> 
00068 #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
00069 
00070 #define __KERNEL_SYSCALLS__
00071 #include <linux/unistd.h>
00072 
00073 /* --------------------------------------------------------------------- */
00074 
00075 #define BAYCOM_DEBUG
00076 #define BAYCOM_MAGIC 19730510
00077 
00078 /* --------------------------------------------------------------------- */
00079 
00080 static const char paranoia_str[] = KERN_ERR 
00081 "baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n";
00082 
00083 #define baycom_paranoia_check(dev,routine,retval)                                              \
00084 ({                                                                                             \
00085         if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
00086                 printk(paranoia_str, routine);                                                 \
00087                 return retval;                                                                 \
00088         }                                                                                      \
00089 })
00090 
00091 #define baycom_paranoia_check_void(dev,routine)                                                \
00092 ({                                                                                             \
00093         if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
00094                 printk(paranoia_str, routine);                                                 \
00095                 return;                                                                        \
00096         }                                                                                      \
00097 })
00098 
00099 /* --------------------------------------------------------------------- */
00100 
00101 static const char bc_drvname[] = "baycom_epp";
00102 static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998 Thomas Sailer, HB9JNX/AE4WA\n"
00103 KERN_INFO "baycom_epp: version 0.3 compiled " __TIME__ " " __DATE__ "\n";
00104 
00105 /* --------------------------------------------------------------------- */
00106 
00107 #define NR_PORTS 4
00108 
00109 static struct device baycom_device[NR_PORTS];
00110 
00111 static struct {
00112         const char *mode;
00113         int iobase;
00114 } baycom_ports[NR_PORTS] = { { NULL, 0 }, };
00115 
00116 /* --------------------------------------------------------------------- */
00117 
00118 /* EPP status register */
00119 #define EPP_DCDBIT      0x80
00120 #define EPP_PTTBIT      0x08
00121 #define EPP_NREF        0x01
00122 #define EPP_NRAEF       0x02
00123 #define EPP_NRHF        0x04
00124 #define EPP_NTHF        0x20
00125 #define EPP_NTAEF       0x10
00126 #define EPP_NTEF        EPP_PTTBIT
00127 
00128 /* EPP control register */
00129 #define EPP_TX_FIFO_ENABLE 0x10
00130 #define EPP_RX_FIFO_ENABLE 0x08
00131 #define EPP_MODEM_ENABLE   0x20
00132 #define EPP_LEDS           0xC0
00133 #define EPP_IRQ_ENABLE     0x10
00134 
00135 /* LPT registers */
00136 #define LPTREG_ECONTROL       0x402
00137 #define LPTREG_CONFIGB        0x401
00138 #define LPTREG_CONFIGA        0x400
00139 #define LPTREG_EPPDATA        0x004
00140 #define LPTREG_EPPADDR        0x003
00141 #define LPTREG_CONTROL        0x002
00142 #define LPTREG_STATUS         0x001
00143 #define LPTREG_DATA           0x000
00144 
00145 /* LPT control register */
00146 #define LPTCTRL_PROGRAM       0x04   /* 0 to reprogram */
00147 #define LPTCTRL_WRITE         0x01
00148 #define LPTCTRL_ADDRSTB       0x08
00149 #define LPTCTRL_DATASTB       0x02
00150 #define LPTCTRL_INTEN         0x10
00151 
00152 /* LPT status register */
00153 #define LPTSTAT_SHIFT_NINTR   6
00154 #define LPTSTAT_WAIT          0x80
00155 #define LPTSTAT_NINTR         (1<<LPTSTAT_SHIFT_NINTR)
00156 #define LPTSTAT_PE            0x20
00157 #define LPTSTAT_DONE          0x10
00158 #define LPTSTAT_NERROR        0x08
00159 #define LPTSTAT_EPPTIMEOUT    0x01
00160 
00161 /* LPT data register */
00162 #define LPTDATA_SHIFT_TDI     0
00163 #define LPTDATA_SHIFT_TMS     2
00164 #define LPTDATA_TDI           (1<<LPTDATA_SHIFT_TDI)
00165 #define LPTDATA_TCK           0x02
00166 #define LPTDATA_TMS           (1<<LPTDATA_SHIFT_TMS)
00167 #define LPTDATA_INITBIAS      0x80
00168 
00169 
00170 /* EPP modem config/status bits */
00171 #define EPP_DCDBIT            0x80
00172 #define EPP_PTTBIT            0x08
00173 #define EPP_RXEBIT            0x01
00174 #define EPP_RXAEBIT           0x02
00175 #define EPP_RXHFULL           0x04
00176 
00177 #define EPP_NTHF              0x20
00178 #define EPP_NTAEF             0x10
00179 #define EPP_NTEF              EPP_PTTBIT
00180 
00181 #define EPP_TX_FIFO_ENABLE    0x10
00182 #define EPP_RX_FIFO_ENABLE    0x08
00183 #define EPP_MODEM_ENABLE      0x20
00184 #define EPP_LEDS              0xC0
00185 #define EPP_IRQ_ENABLE        0x10
00186 
00187 /* Xilinx 4k JTAG instructions */
00188 #define XC4K_IRLENGTH   3
00189 #define XC4K_EXTEST     0
00190 #define XC4K_PRELOAD    1
00191 #define XC4K_CONFIGURE  5
00192 #define XC4K_BYPASS     7
00193 
00194 #define EPP_CONVENTIONAL  0
00195 #define EPP_FPGA          1
00196 #define EPP_FPGAEXTSTATUS 2
00197 
00198 #define TXBUFFER_SIZE     ((HDLCDRV_MAXFLEN*6/5)+8)
00199 
00200 /* ---------------------------------------------------------------------- */
00201 /*
00202  * Information that need to be kept for each board.
00203  */
00204 
00205 struct baycom_state {
00206         int magic;
00207 
00208         struct pardevice *pdev;
00209         unsigned int bh_running;
00210         struct tq_struct run_bh;
00211         unsigned int modem;
00212         unsigned int bitrate;
00213         unsigned char stat;
00214 
00215         char ifname[HDLCDRV_IFNAMELEN];
00216 
00217         struct {
00218                 unsigned int intclk;
00219                 unsigned int divider;
00220                 unsigned int extmodem;
00221                 unsigned int loopback;
00222         } cfg;
00223 
00224         struct hdlcdrv_channel_params ch_params;
00225 
00226         struct {
00227                 unsigned int bitbuf, bitstream, numbits, state;
00228                 unsigned char *bufptr;
00229                 int bufcnt;
00230                 unsigned char buf[TXBUFFER_SIZE];
00231         } hdlcrx;
00232 
00233         struct {
00234                 int calibrate;
00235                 int slotcnt;
00236                 int flags;
00237                 enum { tx_idle = 0, tx_keyup, tx_data, tx_tail } state;
00238                 unsigned char *bufptr;
00239                 int bufcnt;
00240                 unsigned char buf[TXBUFFER_SIZE];
00241         } hdlctx;
00242 
00243         struct net_device_stats stats;
00244         unsigned int ptt_keyed;
00245         struct sk_buff_head send_queue;  /* Packets awaiting transmission */
00246 
00247 
00248 #ifdef BAYCOM_DEBUG
00249         struct debug_vals {
00250                 unsigned long last_jiffies;
00251                 unsigned cur_intcnt;
00252                 unsigned last_intcnt;
00253                 int cur_pllcorr;
00254                 int last_pllcorr;
00255                 unsigned int mod_cycles;
00256                 unsigned int demod_cycles;
00257         } debug_vals;
00258 #endif /* BAYCOM_DEBUG */
00259 };
00260 
00261 /* --------------------------------------------------------------------- */
00262 
00263 #define min(a, b) (((a) < (b)) ? (a) : (b))
00264 #define max(a, b) (((a) > (b)) ? (a) : (b))
00265 
00266 /* --------------------------------------------------------------------- */
00267 
00268 #define KISS_VERBOSE
00269 
00270 /* --------------------------------------------------------------------- */
00271 
00272 #define PARAM_TXDELAY   1
00273 #define PARAM_PERSIST   2
00274 #define PARAM_SLOTTIME  3
00275 #define PARAM_TXTAIL    4
00276 #define PARAM_FULLDUP   5
00277 #define PARAM_HARDWARE  6
00278 #define PARAM_RETURN    255
00279 
00280 /* --------------------------------------------------------------------- */
00281 /*
00282  * the CRC routines are stolen from WAMPES
00283  * by Dieter Deyke
00284  */
00285 
00286 static const unsigned short crc_ccitt_table[] = {
00287         0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
00288         0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
00289         0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
00290         0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
00291         0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
00292         0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
00293         0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
00294         0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
00295         0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
00296         0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
00297         0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
00298         0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
00299         0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
00300         0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
00301         0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
00302         0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
00303         0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
00304         0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
00305         0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
00306         0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
00307         0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
00308         0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
00309         0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
00310         0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
00311         0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
00312         0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
00313         0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
00314         0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
00315         0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
00316         0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
00317         0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
00318         0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
00319 };
00320 
00321 /*---------------------------------------------------------------------------*/
00322 
00323 #if 0
00324 extern inline void append_crc_ccitt(unsigned char *buffer, int len)
00325 {
00326         unsigned int crc = 0xffff;
00327 
00328         for (;len>0;len--)
00329                 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff];
00330         crc ^= 0xffff;
00331         *buffer++ = crc;
00332         *buffer++ = crc >> 8;
00333 }
00334 #endif
00335 
00336 /*---------------------------------------------------------------------------*/
00337 
00338 extern inline int check_crc_ccitt(const unsigned char *buf, int cnt)
00339 {
00340         unsigned int crc = 0xffff;
00341 
00342         for (; cnt > 0; cnt--)
00343                 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
00344         return (crc & 0xffff) == 0xf0b8;
00345 }
00346 
00347 /*---------------------------------------------------------------------------*/
00348 
00349 extern inline int calc_crc_ccitt(const unsigned char *buf, int cnt)
00350 {
00351         unsigned int crc = 0xffff;
00352 
00353         for (; cnt > 0; cnt--)
00354                 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
00355         crc ^= 0xffff;
00356         return (crc & 0xffff);
00357 }
00358 
00359 /* ---------------------------------------------------------------------- */
00360 
00361 #define tenms_to_flags(bc,tenms) ((tenms * bc->bitrate) / 800)
00362 
00363 /* --------------------------------------------------------------------- */
00364 
00365 static void inline baycom_int_freq(struct baycom_state *bc)
00366 {
00367 #ifdef BAYCOM_DEBUG
00368         unsigned long cur_jiffies = jiffies;
00369         /*
00370          * measure the interrupt frequency
00371          */
00372         bc->debug_vals.cur_intcnt++;
00373         if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) {
00374                 bc->debug_vals.last_jiffies = cur_jiffies;
00375                 bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
00376                 bc->debug_vals.cur_intcnt = 0;
00377                 bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
00378                 bc->debug_vals.cur_pllcorr = 0;
00379         }
00380 #endif /* BAYCOM_DEBUG */
00381 }
00382 
00383 /* ---------------------------------------------------------------------- */
00384 /*
00385  *    eppconfig_path should be setable  via /proc/sys.
00386  */
00387 
00388 char eppconfig_path[256] = "/sbin/eppfpga";
00389 
00390 static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL };
00391 
00392 static int errno;
00393 
00394 static int exec_eppfpga(void *b)
00395 {
00396         struct baycom_state *bc = (struct baycom_state *)b;
00397         char modearg[256];
00398         char portarg[16];
00399         char *argv[] = { eppconfig_path, "-s", "-p", portarg, "-m", modearg, NULL};
00400         int i;
00401 
00402         /* set up arguments */
00403         sprintf(modearg, "%sclk,%smodem,divider=%d%s,extstat",
00404                 bc->cfg.intclk ? "int" : "ext",
00405                 bc->cfg.extmodem ? "ext" : "int", bc->cfg.divider,
00406                 bc->cfg.loopback ? ",loopback" : "");
00407         sprintf(portarg, "%ld", bc->pdev->port->base);
00408         printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg);
00409 
00410         i = exec_usermodehelper(eppconfig_path, argv, envp);
00411         if (i < 0) {
00412                 printk(KERN_ERR "%s: failed to exec %s -s -p %s -m %s, errno = %d\n",
00413                        bc_drvname, eppconfig_path, portarg, modearg, errno);
00414                 return -errno;
00415         }
00416         return 0;
00417 }
00418 
00419 
00420 /* eppconfig: called during ifconfig up to configure the modem */
00421 
00422 static int eppconfig(struct baycom_state *bc)
00423 {
00424         int i, pid, r;
00425         mm_segment_t fs;
00426 
00427         pid = kernel_thread(exec_eppfpga, bc, CLONE_FS);
00428         if (pid < 0) {
00429                 printk(KERN_ERR "%s: fork failed, errno %d\n", bc_drvname, -pid);
00430                 return pid;
00431         }
00432         fs = get_fs();
00433         set_fs(KERNEL_DS);      /* Allow i to be in kernel space. */
00434         r = waitpid(pid, &i, __WCLONE);
00435         set_fs(fs);
00436         if (r != pid) {
00437                 printk(KERN_ERR "%s: waitpid(%d) failed, returning %d\n",
00438                        bc_drvname, pid, r);
00439                 return -1;
00440         }
00441         printk(KERN_DEBUG "%s: eppfpga returned %d\n", bc_drvname, i);
00442         return i;
00443 }
00444 
00445 /* ---------------------------------------------------------------------- */
00446 
00447 static void epp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
00448 {
00449 }
00450 
00451 /* ---------------------------------------------------------------------- */
00452 
00453 static void inline do_kiss_params(struct baycom_state *bc,
00454                                   unsigned char *data, unsigned long len)
00455 {
00456 
00457 #ifdef KISS_VERBOSE
00458 #define PKP(a,b) printk(KERN_INFO "%s: channel params: " a "\n", bc->ifname, b)
00459 #else /* KISS_VERBOSE */              
00460 #define PKP(a,b) 
00461 #endif /* KISS_VERBOSE */             
00462 
00463         if (len < 2)
00464                 return;
00465         switch(data[0]) {
00466         case PARAM_TXDELAY:
00467                 bc->ch_params.tx_delay = data[1];
00468                 PKP("TX delay = %ums", 10 * bc->ch_params.tx_delay);
00469                 break;
00470         case PARAM_PERSIST:   
00471                 bc->ch_params.ppersist = data[1];
00472                 PKP("p persistence = %u", bc->ch_params.ppersist);
00473                 break;
00474         case PARAM_SLOTTIME:  
00475                 bc->ch_params.slottime = data[1];
00476                 PKP("slot time = %ums", bc->ch_params.slottime);
00477                 break;
00478         case PARAM_TXTAIL:    
00479                 bc->ch_params.tx_tail = data[1];
00480                 PKP("TX tail = %ums", bc->ch_params.tx_tail);
00481                 break;
00482         case PARAM_FULLDUP:   
00483                 bc->ch_params.fulldup = !!data[1];
00484                 PKP("%s duplex", bc->ch_params.fulldup ? "full" : "half");
00485                 break;
00486         default:
00487                 break;
00488         }
00489 #undef PKP
00490 }
00491 
00492 /* --------------------------------------------------------------------- */
00493 /*
00494  * high performance HDLC encoder
00495  * yes, it's ugly, but generates pretty good code
00496  */
00497 
00498 #define ENCODEITERA(j)                         \
00499 ({                                             \
00500         if (!(notbitstream & (0x1f0 << j)))    \
00501                 goto stuff##j;                 \
00502   encodeend##j:                                \
00503 })
00504 
00505 #define ENCODEITERB(j)                                          \
00506 ({                                                              \
00507   stuff##j:                                                     \
00508         bitstream &= ~(0x100 << j);                             \
00509         bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) |        \
00510                 ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1);  \
00511         numbit++;                                               \
00512         notbitstream = ~bitstream;                              \
00513         goto encodeend##j;                                      \
00514 })
00515 
00516 
00517 static void encode_hdlc(struct baycom_state *bc)
00518 {
00519         struct sk_buff *skb;
00520         unsigned char *wp, *bp;
00521         int pkt_len;
00522         unsigned bitstream, notbitstream, bitbuf, numbit, crc;
00523         unsigned char crcarr[2];
00524         
00525         if (bc->hdlctx.bufcnt > 0)
00526                 return;
00527         while ((skb = skb_dequeue(&bc->send_queue))) {
00528                 if (skb->data[0] != 0) {
00529                         do_kiss_params(bc, skb->data, skb->len);
00530                         dev_kfree_skb(skb);
00531                         continue;
00532                 }
00533                 pkt_len = skb->len-1; /* strip KISS byte */
00534                 if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
00535                         dev_kfree_skb(skb);
00536                         continue;
00537                 }
00538                 wp = bc->hdlctx.buf;
00539                 bp = skb->data+1;
00540                 crc = calc_crc_ccitt(bp, pkt_len);
00541                 crcarr[0] = crc;
00542                 crcarr[1] = crc >> 8;
00543                 *wp++ = 0x7e;
00544                 bitstream = bitbuf = numbit = 0;
00545                 while (pkt_len > -2) {
00546                         bitstream >>= 8;
00547                         bitstream |= ((unsigned int)*bp) << 8;
00548                         bitbuf |= ((unsigned int)*bp) << numbit;
00549                         notbitstream = ~bitstream;
00550                         bp++;
00551                         pkt_len--;
00552                         if (!pkt_len)
00553                                 bp = crcarr;
00554                         ENCODEITERA(0);
00555                         ENCODEITERA(1);
00556                         ENCODEITERA(2);
00557                         ENCODEITERA(3);
00558                         ENCODEITERA(4);
00559                         ENCODEITERA(5);
00560                         ENCODEITERA(6);
00561                         ENCODEITERA(7);
00562                         goto enditer;
00563                         ENCODEITERB(0);
00564                         ENCODEITERB(1);
00565                         ENCODEITERB(2);
00566                         ENCODEITERB(3);
00567                         ENCODEITERB(4);
00568                         ENCODEITERB(5);
00569                         ENCODEITERB(6);
00570                         ENCODEITERB(7);
00571                   enditer:
00572                         numbit += 8;
00573                         while (numbit >= 8) {
00574                                 *wp++ = bitbuf;
00575                                 bitbuf >>= 8;
00576                                 numbit -= 8;
00577                         }
00578                 }
00579                 bitbuf |= 0x7e7e << numbit;
00580                 numbit += 16;
00581                 while (numbit >= 8) {
00582                         *wp++ = bitbuf;
00583                         bitbuf >>= 8;
00584                         numbit -= 8;
00585                 }
00586                 bc->hdlctx.bufptr = bc->hdlctx.buf;
00587                 bc->hdlctx.bufcnt = wp - bc->hdlctx.buf;
00588                 dev_kfree_skb(skb);
00589                 bc->stats.tx_packets++;
00590                 return;
00591         }
00592 }
00593 
00594 /* ---------------------------------------------------------------------- */
00595 
00596 static unsigned short random_seed;
00597 
00598 static inline unsigned short random_num(void)
00599 {
00600         random_seed = 28629 * random_seed + 157;
00601         return random_seed;
00602 }
00603 
00604 /* ---------------------------------------------------------------------- */
00605 
00606 static void transmit(struct baycom_state *bc, int cnt, unsigned char stat)
00607 {
00608         struct parport *pp = bc->pdev->port;
00609         int i;
00610 
00611         if (bc->hdlctx.state == tx_tail && !(stat & EPP_PTTBIT))
00612                 bc->hdlctx.state = tx_idle;
00613         if (bc->hdlctx.state == tx_idle && bc->hdlctx.calibrate <= 0) {
00614                 if (bc->hdlctx.bufcnt <= 0)
00615                         encode_hdlc(bc);
00616                 if (bc->hdlctx.bufcnt <= 0)
00617                         return;
00618                 if (!bc->ch_params.fulldup) {
00619                         if (!(stat & EPP_DCDBIT)) {
00620                                 bc->hdlctx.slotcnt = bc->ch_params.slottime;
00621                                 return;
00622                         }
00623                         if ((--bc->hdlctx.slotcnt) > 0)
00624                                 return;
00625                         bc->hdlctx.slotcnt = bc->ch_params.slottime;
00626                         if ((random_num() % 256) > bc->ch_params.ppersist)
00627                                 return;
00628                 }
00629         }
00630         if (bc->hdlctx.state == tx_idle && bc->hdlctx.bufcnt > 0) {
00631                 bc->hdlctx.state = tx_keyup;
00632                 bc->hdlctx.flags = tenms_to_flags(bc, bc->ch_params.tx_delay);
00633                 bc->ptt_keyed++;
00634         }
00635         while (cnt > 0) {
00636                 switch (bc->hdlctx.state) {
00637                 case tx_keyup:
00638                         i = min(cnt, bc->hdlctx.flags);
00639                         cnt -= i;
00640                         bc->hdlctx.flags -= i;
00641                         if (bc->hdlctx.flags <= 0)
00642                                 bc->hdlctx.state = tx_data;
00643                         for (; i > 0; i--)
00644                                 parport_epp_write_data(pp, 0x7e);
00645                         break;
00646 
00647                 case tx_data:
00648                         if (bc->hdlctx.bufcnt <= 0) {
00649                                 encode_hdlc(bc);
00650                                 if (bc->hdlctx.bufcnt <= 0) {
00651                                         bc->hdlctx.state = tx_tail;
00652                                         bc->hdlctx.flags = tenms_to_flags(bc, bc->ch_params.tx_tail);
00653                                         break;
00654                                 }
00655                         }
00656                         i = min(cnt, bc->hdlctx.bufcnt);
00657                         bc->hdlctx.bufcnt -= i;
00658                         cnt -= i;
00659                         for (; i > 0; i--)
00660                                 parport_epp_write_data(pp, *(bc->hdlctx.bufptr)++);
00661                         break;
00662                         
00663                 case tx_tail:
00664                         encode_hdlc(bc);
00665                         if (bc->hdlctx.bufcnt > 0) {
00666                                 bc->hdlctx.state = tx_data;
00667                                 break;
00668                         }
00669                         i = min(cnt, bc->hdlctx.flags);
00670                         if (i) {
00671                                 cnt -= i;
00672                                 bc->hdlctx.flags -= i;
00673                                 for (; i > 0; i--)
00674                                         parport_epp_write_data(pp, 0x7e);
00675                                 break;
00676                         }
00677 
00678                 default:  /* fall through */
00679                         if (bc->hdlctx.calibrate <= 0)
00680                                 return;
00681                         i = min(cnt, bc->hdlctx.calibrate);
00682                         cnt -= i;
00683                         bc->hdlctx.calibrate -= i;
00684                         for (; i > 0; i--)
00685                                 parport_epp_write_data(pp, 0);
00686                         break;
00687                 }
00688         }
00689 }
00690 
00691 /* ---------------------------------------------------------------------- */
00692 
00693 static void do_rxpacket(struct device *dev)
00694 {
00695         struct baycom_state *bc = (struct baycom_state *)dev->priv;
00696         struct sk_buff *skb;
00697         unsigned char *cp;
00698         unsigned pktlen;
00699 
00700         if (bc->hdlcrx.bufcnt < 4) 
00701                 return;
00702         if (!check_crc_ccitt(bc->hdlcrx.buf, bc->hdlcrx.bufcnt)) 
00703                 return;
00704         pktlen = bc->hdlcrx.bufcnt-2+1; /* KISS kludge */
00705         if (!(skb = dev_alloc_skb(pktlen))) {
00706                 printk("%s: memory squeeze, dropping packet\n", bc->ifname);
00707                 bc->stats.rx_dropped++;
00708                 return;
00709         }
00710         skb->dev = dev;
00711         cp = skb_put(skb, pktlen);
00712         *cp++ = 0; /* KISS kludge */
00713         memcpy(cp, bc->hdlcrx.buf, pktlen - 1);
00714         skb->protocol = htons(ETH_P_AX25);
00715         skb->mac.raw = skb->data;
00716         netif_rx(skb);
00717         bc->stats.rx_packets++;
00718 }
00719 
00720 #define DECODEITERA(j)                                                        \
00721 ({                                                                            \
00722         if (!(notbitstream & (0x0fc << j)))              /* flag or abort */  \
00723                 goto flgabrt##j;                                              \
00724         if ((bitstream & (0x1f8 << j)) == (0xf8 << j))   /* stuffed bit */    \
00725                 goto stuff##j;                                                \
00726   enditer##j:                                                                 \
00727 })
00728 
00729 #define DECODEITERB(j)                                                                 \
00730 ({                                                                                     \
00731   flgabrt##j:                                                                          \
00732         if (!(notbitstream & (0x1fc << j))) {              /* abort received */        \
00733                 state = 0;                                                             \
00734                 goto enditer##j;                                                       \
00735         }                                                                              \
00736         if ((bitstream & (0x1fe << j)) != (0x0fc << j))   /* flag received */          \
00737                 goto enditer##j;                                                       \
00738         if (state)                                                                     \
00739                 do_rxpacket(dev);                                                      \
00740         bc->hdlcrx.bufcnt = 0;                                                         \
00741         bc->hdlcrx.bufptr = bc->hdlcrx.buf;                                            \
00742         state = 1;                                                                     \
00743         numbits = 7-j;                                                                 \
00744         goto enditer##j;                                                               \
00745   stuff##j:                                                                            \
00746         numbits--;                                                                     \
00747         bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1);        \
00748         goto enditer##j;                                                               \
00749 })
00750         
00751 static void receive(struct device *dev, int cnt)
00752 {
00753         struct baycom_state *bc = (struct baycom_state *)dev->priv;
00754         struct parport *pp = bc->pdev->port;
00755         unsigned int bitbuf, notbitstream, bitstream, numbits, state;
00756         unsigned char ch;
00757         
00758         numbits = bc->hdlcrx.numbits;
00759         state = bc->hdlcrx.state;
00760         bitstream = bc->hdlcrx.bitstream;
00761         bitbuf = bc->hdlcrx.bitbuf;
00762         for (; cnt > 0; cnt--) {
00763                 ch = parport_epp_read_data(pp);
00764                 bitstream >>= 8;
00765                 bitstream |= ch << 8;
00766                 bitbuf >>= 8;
00767                 bitbuf |= ch << 8;
00768                 numbits += 8;
00769                 notbitstream = ~bitstream;
00770                 DECODEITERA(0);
00771                 DECODEITERA(1);
00772                 DECODEITERA(2);
00773                 DECODEITERA(3);
00774                 DECODEITERA(4);
00775                 DECODEITERA(5);
00776                 DECODEITERA(6);
00777                 DECODEITERA(7);
00778                 goto enddec;
00779                 DECODEITERB(0);
00780                 DECODEITERB(1);
00781                 DECODEITERB(2);
00782                 DECODEITERB(3);
00783                 DECODEITERB(4);
00784                 DECODEITERB(5);
00785                 DECODEITERB(6);
00786                 DECODEITERB(7);
00787           enddec:
00788                 while (state && numbits >= 8) {
00789                         if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) {
00790                                 state = 0;
00791                         } else {
00792                                 *(bc->hdlcrx.bufptr)++ = bitbuf >> (16-numbits);
00793                                 bc->hdlcrx.bufcnt++;
00794                                 numbits -= 8;
00795                         }
00796                 }
00797         }
00798         bc->hdlcrx.numbits = numbits;
00799         bc->hdlcrx.state = state;
00800         bc->hdlcrx.bitstream = bitstream;
00801         bc->hdlcrx.bitbuf = bitbuf;
00802 }
00803 
00804 /* --------------------------------------------------------------------- */
00805 
00806 #ifdef __i386__
00807 #define GETTICK(x)                                                \
00808 ({                                                                \
00809         if (current_cpu_data.x86_capability & X86_FEATURE_TSC)    \
00810                 __asm__ __volatile__("rdtsc" : "=a" (x) : : "dx");\
00811 })
00812 #else /* __i386__ */
00813 #define GETTICK(x)
00814 #endif /* __i386__ */
00815 
00816 static void epp_bh(struct device *dev)
00817 {
00818         struct baycom_state *bc;
00819         struct parport *pp;
00820         unsigned char stat;
00821         unsigned int time1 = 0, time2 = 0, time3 = 0;
00822         int cnt, cnt2;
00823         
00824         baycom_paranoia_check_void(dev, "epp_bh");
00825         bc = (struct baycom_state *)dev->priv;
00826         if (!bc->bh_running)
00827                 return;
00828         baycom_int_freq(bc);
00829         pp = bc->pdev->port;
00830         /* update status */
00831         bc->stat = stat = parport_epp_read_addr(pp);
00832         bc->debug_vals.last_pllcorr = stat;
00833         GETTICK(time1);
00834         if (bc->modem == EPP_FPGAEXTSTATUS) {
00835                 /* get input count */
00836                 parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|1);
00837                 cnt = parport_epp_read_addr(pp);
00838                 cnt |= parport_epp_read_addr(pp) << 8;
00839                 cnt &= 0x7fff;
00840                 /* get output count */
00841                 parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE|2);
00842                 cnt2 = parport_epp_read_addr(pp);
00843                 cnt2 |= parport_epp_read_addr(pp) << 8;
00844                 cnt2 = 16384 - (cnt2 & 0x7fff);
00845                 /* return to normal */
00846                 parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE);
00847                 transmit(bc, cnt2, stat);
00848                 GETTICK(time2);
00849                 receive(dev, cnt);
00850                 bc->stat = stat = parport_epp_read_addr(pp);
00851         } else {
00852                 /* try to tx */
00853                 switch (stat & (EPP_NTAEF|EPP_NTHF)) {
00854                 case EPP_NTHF:
00855                         cnt = 2048 - 256;
00856                         break;
00857                 
00858                 case EPP_NTAEF:
00859                         cnt = 2048 - 1793;
00860                         break;
00861                 
00862                 case 0:
00863                         cnt = 0;
00864                         break;
00865                 
00866                 default:
00867                         cnt = 2048 - 1025;
00868                         break;
00869                 }
00870                 transmit(bc, cnt, stat);
00871                 GETTICK(time2);
00872                 /* do receiver */
00873                 while ((stat & (EPP_NRAEF|EPP_NRHF)) != EPP_NRHF) {
00874                         switch (stat & (EPP_NRAEF|EPP_NRHF)) {
00875                         case EPP_NRAEF:
00876                                 cnt = 1025;
00877                                 break;
00878 
00879                         case 0:
00880                                 cnt = 1793;
00881                                 break;
00882 
00883                         default:
00884                                 cnt = 256;
00885                                 break;
00886                         }
00887                         receive(dev, cnt);
00888                         stat = parport_epp_read_addr(pp);
00889                         if (parport_epp_check_timeout(pp))
00890                                 goto epptimeout;
00891                 }
00892                 cnt = 0;
00893                 if (bc->bitrate < 50000)
00894                         cnt = 256;
00895                 else if (bc->bitrate < 100000)
00896                         cnt = 128;
00897                 while (cnt > 0 && stat & EPP_NREF) {
00898                         receive(dev, 1);
00899                         cnt--;
00900                         stat = parport_epp_read_addr(pp);
00901                 }
00902         }
00903         GETTICK(time3);
00904 #ifdef BAYCOM_DEBUG
00905         bc->debug_vals.mod_cycles = time2 - time1;
00906         bc->debug_vals.demod_cycles = time3 - time2;
00907 #endif /* BAYCOM_DEBUG */
00908         if (parport_epp_check_timeout(pp)) 
00909                 goto epptimeout;
00910         queue_task(&bc->run_bh, &tq_timer);
00911         return;
00912  epptimeout:
00913         printk(KERN_ERR "%s: EPP timeout!\n", bc_drvname);
00914 }
00915 
00916 /* ---------------------------------------------------------------------- */
00917 /*
00918  * ===================== network driver interface =========================
00919  */
00920 
00921 static int baycom_send_packet(struct sk_buff *skb, struct device *dev)
00922 {
00923         struct baycom_state *bc;
00924 
00925         baycom_paranoia_check(dev, "baycom_send_packet", 0);
00926         bc = (struct baycom_state *)dev->priv;
00927         skb_queue_tail(&bc->send_queue, skb);
00928         dev->trans_start = jiffies;     
00929         return 0;
00930 }
00931 
00932 /* --------------------------------------------------------------------- */
00933 
00934 static int baycom_set_mac_address(struct device *dev, void *addr)
00935 {
00936         struct sockaddr *sa = (struct sockaddr *)addr;
00937 
00938         /* addr is an AX.25 shifted ASCII mac address */
00939         memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); 
00940         return 0;                                         
00941 }
00942 
00943 /* --------------------------------------------------------------------- */
00944 
00945 static struct net_device_stats *baycom_get_stats(struct device *dev)
00946 {
00947         struct baycom_state *bc;
00948 
00949         baycom_paranoia_check(dev, "baycom_get_stats", NULL);
00950         bc = (struct baycom_state *)dev->priv;
00951         /* 
00952          * Get the current statistics.  This may be called with the
00953          * card open or closed. 
00954          */
00955         return &bc->stats;
00956 }
00957 
00958 /* --------------------------------------------------------------------- */
00959 
00960 static void epp_wakeup(void *handle)
00961 {
00962         struct device *dev = (struct device *)handle;
00963         struct baycom_state *bc;
00964 
00965         baycom_paranoia_check_void(dev, "epp_wakeup");
00966         bc = (struct baycom_state *)dev->priv;
00967         printk(KERN_DEBUG "baycom_epp: %s: why am I being woken up?\n", dev->name);
00968         if (!parport_claim(bc->pdev))
00969                 printk(KERN_DEBUG "baycom_epp: %s: I'm broken.\n", dev->name);
00970 }
00971 
00972 /* --------------------------------------------------------------------- */
00973 
00974 /*
00975  * Open/initialize the board. This is called (in the current kernel)
00976  * sometime after booting when the 'ifconfig' program is run.
00977  *
00978  * This routine should set everything up anew at each open, even
00979  * registers that "should" only need to be set once at boot, so that
00980  * there is non-reboot way to recover if something goes wrong.
00981  */
00982 
00983 static int epp_open(struct device *dev)
00984 {
00985         struct baycom_state *bc;
00986         struct parport *pp;
00987         const struct tq_struct run_bh = {
00988                 0, 0, (void *)(void *)epp_bh, dev
00989         };
00990         unsigned int i, j;
00991         unsigned char stat;
00992         unsigned long tstart;
00993         
00994         baycom_paranoia_check(dev, "epp_open", -ENXIO);
00995         bc = (struct baycom_state *)dev->priv;
00996         if (dev->start)
00997                 return 0;
00998         pp = parport_enumerate();
00999         while (pp && pp->base != dev->base_addr) 
01000                 pp = pp->next;
01001         if (!pp) {
01002                 printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr);
01003                 return -ENXIO;
01004         }
01005 #if 0
01006         if (pp->irq < 0) {
01007                 printk(KERN_ERR "%s: parport at 0x%lx has no irq\n", bc_drvname, pp->base);
01008                 return -ENXIO;
01009         }
01010 #endif
01011         memset(&bc->modem, 0, sizeof(bc->modem));
01012         if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup, 
01013                                                  epp_interrupt, PARPORT_DEV_EXCL, dev))) {
01014                 printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base);
01015                 return -ENXIO;
01016         }
01017         if (parport_claim(bc->pdev)) {
01018                 printk(KERN_ERR "%s: parport at 0x%lx busy\n", bc_drvname, pp->base);
01019                 parport_unregister_device(bc->pdev);
01020                 return -EBUSY;
01021         }
01022         if (!(pp->modes & (PARPORT_MODE_PCECPEPP|PARPORT_MODE_PCEPP))) {
01023                 printk(KERN_ERR "%s: parport at 0x%lx does not support any EPP mode\n",
01024                        bc_drvname, pp->base);
01025                 parport_release(bc->pdev);
01026                 parport_unregister_device(bc->pdev);
01027                 return -EIO;            
01028         }
01029         dev->irq = /*pp->irq*/ 0;
01030         bc->run_bh = run_bh;
01031         bc->bh_running = 1;
01032         if (pp->modes & PARPORT_MODE_PCECPEPP) {
01033                 printk(KERN_INFO "%s: trying to enable EPP mode\n", bc_drvname);
01034                 parport_frob_econtrol(pp, 0xe0, 0x80);
01035         }
01036         /* bc->pdev->port->ops->change_mode(bc->pdev->port, PARPORT_MODE_PCEPP);  not yet implemented */
01037         bc->modem = EPP_CONVENTIONAL;
01038         if (eppconfig(bc))
01039                 printk(KERN_INFO "%s: no FPGA detected, assuming conventional EPP modem\n", bc_drvname);
01040         else
01041                 bc->modem = /*EPP_FPGA*/ EPP_FPGAEXTSTATUS;
01042         parport_write_control(pp, LPTCTRL_PROGRAM); /* prepare EPP mode; we aren't using interrupts */
01043         /* reset the modem */
01044         parport_epp_write_addr(pp, 0);
01045         parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE);
01046         /* autoprobe baud rate */
01047         tstart = jiffies;
01048         i = 0;
01049         while ((signed)(jiffies-tstart-HZ/3) < 0) {
01050                 stat = parport_epp_read_addr(pp);
01051                 if ((stat & (EPP_NRAEF|EPP_NRHF)) == EPP_NRHF) {
01052                         schedule();
01053                         continue;
01054                 }
01055                 for (j = 0; j < 256; j++)
01056                         parport_epp_read_data(pp);
01057                 i += 256;
01058         }
01059         for (j = 0; j < 256; j++) {
01060                 stat = parport_epp_read_addr(pp);
01061                 if (!(stat & EPP_NREF))
01062                         break;
01063                 parport_epp_read_data(pp);
01064                 i++;
01065         }
01066         tstart = jiffies - tstart;
01067         bc->bitrate = i * (8 * HZ) / tstart;
01068         j = 1;
01069         i = bc->bitrate >> 3;
01070         while (j < 7 && i > 150) {
01071                 j++;
01072                 i >>= 1;
01073         }
01074         printk(KERN_INFO "%s: autoprobed bitrate: %d  int divider: %d  int rate: %d\n", 
01075                bc_drvname, bc->bitrate, j, bc->bitrate >> (j+2));
01076         parport_epp_write_addr(pp, EPP_TX_FIFO_ENABLE|EPP_RX_FIFO_ENABLE|EPP_MODEM_ENABLE/*|j*/);
01077         /*
01078          * initialise hdlc variables
01079          */
01080         bc->hdlcrx.state = 0;
01081         bc->hdlcrx.numbits = 0;
01082         bc->hdlctx.state = tx_idle;
01083         bc->hdlctx.bufcnt = 0;
01084         bc->hdlctx.slotcnt = bc->ch_params.slottime;
01085         bc->hdlctx.calibrate = 0;
01086         dev->start = 1;
01087         dev->tbusy = 0;
01088         dev->interrupt = 0;
01089         /* start the bottom half stuff */
01090         queue_task(&bc->run_bh, &tq_timer);
01091         MOD_INC_USE_COUNT;
01092         return 0;
01093 
01094 #if 0
01095   errreturn:
01096         parport_release(bc->pdev);
01097         parport_unregister_device(bc->pdev);
01098         return -EIO;
01099 #endif
01100 }
01101 
01102 /* --------------------------------------------------------------------- */
01103 
01104 static int epp_close(struct device *dev)
01105 {
01106         struct baycom_state *bc;
01107         struct parport *pp;
01108         struct sk_buff *skb;
01109 
01110         baycom_paranoia_check(dev, "epp_close", -EINVAL);
01111         if (!dev->start)
01112                 return 0;
01113         bc = (struct baycom_state *)dev->priv;
01114         pp = bc->pdev->port;
01115         bc->bh_running = 0;
01116         dev->start = 0;
01117         dev->tbusy = 1;
01118         run_task_queue(&tq_timer);  /* dequeue bottom half */
01119         bc->stat = EPP_DCDBIT;
01120         parport_epp_write_addr(pp, 0);
01121         parport_write_control(pp, 0); /* reset the adapter */
01122         parport_release(bc->pdev);
01123         parport_unregister_device(bc->pdev);
01124         /* Free any buffers left in the hardware transmit queue */
01125         while ((skb = skb_dequeue(&bc->send_queue)))
01126                         dev_kfree_skb(skb);
01127         printk(KERN_INFO "%s: close epp at iobase 0x%lx irq %u\n",
01128                bc_drvname, dev->base_addr, dev->irq);
01129         MOD_DEC_USE_COUNT;
01130         return 0;
01131 }
01132 
01133 /* --------------------------------------------------------------------- */
01134 
01135 static int baycom_setmode(struct baycom_state *bc, const char *modestr)
01136 {
01137         const char *cp;
01138 
01139         if (strstr(modestr,"intclk"))
01140                 bc->cfg.intclk = 1;
01141         if (strstr(modestr,"extclk"))
01142                 bc->cfg.intclk = 0;
01143         if (strstr(modestr,"intmodem"))
01144                 bc->cfg.extmodem = 0;
01145         if (strstr(modestr,"extmodem"))
01146                 bc->cfg.extmodem = 1;
01147         if (strstr(modestr,"noloopback"))
01148                 bc->cfg.loopback = 0;
01149         if (strstr(modestr,"loopback"))
01150                 bc->cfg.loopback = 1;
01151         if ((cp = strstr(modestr,"divider="))) {
01152                 bc->cfg.divider = simple_strtoul(cp+8, NULL, 0);
01153                 if (bc->cfg.divider < 1)
01154                         bc->cfg.divider = 1;
01155                 if (bc->cfg.divider > 1023)
01156                         bc->cfg.divider = 1023;
01157         }
01158         return 0;
01159 }
01160 
01161 /* --------------------------------------------------------------------- */
01162 
01163 static int baycom_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
01164 {
01165         struct baycom_state *bc;
01166         struct baycom_ioctl bi;
01167         struct hdlcdrv_ioctl hi;
01168         struct sm_ioctl si;
01169 
01170         baycom_paranoia_check(dev, "baycom_ioctl", -EINVAL);
01171         bc = (struct baycom_state *)dev->priv;
01172         if (cmd != SIOCDEVPRIVATE)
01173                 return -ENOIOCTLCMD;
01174         if (get_user(cmd, (int *)ifr->ifr_data))
01175                 return -EFAULT;
01176 #ifdef BAYCOM_DEBUG
01177         if (cmd == BAYCOMCTL_GETDEBUG) {
01178                 bi.data.dbg.debug1 = bc->ptt_keyed;
01179                 bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
01180                 bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
01181                 bc->debug_vals.last_intcnt = 0;
01182                 if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
01183                         return -EFAULT;
01184