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