scc.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:47k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Generic driver for Z8530 boards, modified from the PE1CHL
  2.  * driver for use with NOS. This version also supports the NRS
  3.  * mode when used as an asynch port. Device setup is similar to
  4.  * that of the PE1CHL version, with the addition of user specification
  5.  * of buffer size (bufsize). See the file "scc.txt" for general
  6.  * information on the use of this driver and setup procedures.
  7.  *
  8.  * General differences between this driver and the original version:
  9.  *
  10.  * 1) Slip encoding and decoding is not done in the driver, but
  11.  *    using the routines in slip.c, and these routines are supported
  12.  *    in a manner similar to the asynch routines for the 8250. The
  13.  *    input is handled via fifo buffer, while output is direct. The
  14.  *    routines scc_send and get_scc are called via pointers in the
  15.  *    Slip and Nrs structs for the parcticular channel.
  16.  *
  17.  * 2) The timer routine, scctim, is not installed directly in the
  18.  *    timer interrupt chain, but is called through the systick routine
  19.  *    in pc.c.
  20.  *
  21.  * 3) Facilities of nos are used whenever possible in place of direct
  22.  *    structure or variable manipulation. Mbuf management is handled
  23.  *    this way, along with interface initialization.
  24.  *
  25.  * 4) Nrs mode support is added in a manner similar to that of the
  26.  *    Slip support. I have not had an opportunity to test this, but
  27.  *    it is essentially identical to the way the 8250 version works.
  28.  *
  29.  * 5) Callsign specification on radio modes (kiss,nrs,ax25) is an
  30.  *    option. If not supplied, the value of Mycall will be used.
  31.  *
  32.  * 6) Bufsize specification is now a parameter on setup of each channel.
  33.  *    This is the size of the fifo on asynch input, and the size of
  34.  *    mbuf buffers for sdlc mode. Since the fifo buffer can fill up,
  35.  *    this value should be reasonably large for asynch mode. Mbufs
  36.  *    are chained when they fill up, so having a small bufsize with
  37.  *    sdlc modes (ax25) does not result in loss of characters.
  38.  *
  39.  * 7) Because slip and nrs decoding is handled outside the driver,
  40.  *    sccstat cannot be used to report sent and receive packet counts
  41.  *    in asynch mode, and these fields are blanked on display in asynch
  42.  *    modes.
  43.  *
  44.  *
  45.  * I am interested in setting up some default initializations for
  46.  * the popular Z8530 boards, to minimize user problems in constructing
  47.  * the proper attach init entries. These would allow for shortened
  48.  * entries to use the defaults, such as "attach scc 1 init drsi" to
  49.  * attach a DRSI board in standard configuration at its default address.
  50.  * Since I do not have complete technical information on all such boards,
  51.  * I would very much appreciate any information that users can provide
  52.  * me regarding particular boards.
  53.  *
  54.  * 1/25/90
  55.  *
  56.  * Modifications:
  57.  *
  58.  * 2/17/90:
  59.  *
  60.  * 1) Added mods from PE1CHL which reflect relevent changes to the
  61.  *    scc driver in his version of net between 10/89 and 1/90. Changes
  62.  *    incorporated include additional delays in sccvec.asm, addition
  63.  *    of external clock mode, and initialization for the 8536 as a
  64.  *    clock divider on the DRSI board. "INLINE" is a slight delay
  65.  *    for register access incorporated for use with the inline i/o
  66.  *    code in MSC. This may not be useful or necessary with TURBO.
  67.  *    Changes making "TPS" a variable were not added, since the
  68.  *    scc timer does not install itself on the hardware interrupt
  69.  *    in this version.
  70.  * 
  71.  *
  72.  * Ken Mitchum, KY3B       km@cs.pitt.edu  km@dsl.pitt.edu
  73.  *                             or mail to the tcpip group
  74.  *
  75.  * 5 Aug 91:
  76.  * Support added for Sealevel Systems Inc's ACB-IV 8530 card (HWSEALEVEL)
  77.  * <hdwe> == HWSEALEVEL (0x10) sets the control/status port at chipbase + 4
  78.  * to the value in <param>. (Where the control bits for both side's DTR
  79.  * lines are; the 8530-internal DTR/REQB is used for DMA...)
  80.  *
  81.  * Added a side-effect to ATTACH SCC's <speed> == 'ext'. Previously, all 
  82.  * async modes set a 16X clock; now when external clock is selected, the 
  83.  * baud rate divider in R4 is set to 1X.
  84.  *
  85.  * Tom Jennings, Cygnus Support (tomj@cygnus.com) 
  86.  *
  87.  *
  88.  * 9 Aug 91:
  89.  * Allow 'v' to specify Van Jacobson TCP header compression (SLIP only).
  90.  * Because the 8th arg is optional [<call>], this checks for 'v' in the
  91.  * 9th arg if that exists, otherwise the 8th arg is used. Not pretty
  92.  * but servicable.
  93.  *
  94.  * Tom Jennings, Cygnus Support (tomj@cygnus.com) 
  95.  */
  96. /* Added ANSI-style prototypes, reformatted source, minor delinting.
  97.  * Integrated into standard 900201 NOS by KA9Q.
  98.  */
  99. /*
  100.  * Generic driver for Z8530 SCC chip in SLIP, KISS or AX.25 mode.
  101.  *
  102.  * Written by R.E. Janssen (PE1CHL) using material from earlier
  103.  * EAGLE and PC100 drivers in this package.
  104.  *
  105.  * The driver has initially been written for my own Atari SCC interface
  106.  * board, but it could eventually replace the other SCC drivers.
  107.  *
  108.  * Unfortunately, there is little consistency between the different interface
  109.  * boards, as to the use of a clock source, the solution for the fullduplex
  110.  * clocking problem, and most important of all: the generation of the INTACK
  111.  * signal. Most designs do not even support the generation of an INTACK and
  112.  * the read of the interrupt vector provided by the chip.
  113.  * This results in lots of configuration parameters, and a fuzzy
  114.  * polltable to be able to support multiple chips connected at one interrupt
  115.  * line...
  116.  *
  117.  */
  118. #include <stdlib.h>
  119. #include <stdio.h>
  120. #include <ctype.h>
  121. #include <time.h>
  122. #include <dos.h>
  123. #include "global.h"
  124. #include "mbuf.h"
  125. #include "config.h"
  126. #include "netuser.h"
  127. #include "proc.h"
  128. #include "iface.h"
  129. #include "pktdrvr.h"
  130. #include "slip.h"
  131. #include "nrs.h"
  132. #include "n8250.h"
  133. #include "scc.h"
  134. #include "z8530.h"
  135. #include "z8536.h"
  136. #include "ax25.h"
  137. #include "trace.h"
  138. #include "nospc.h"
  139. #include "kiss.h"
  140. #include "devparam.h"
  141. /* interrupt handlers */
  142. extern INTERRUPT sccvec();
  143. extern INTERRUPT sccnovec();
  144. /* variables used by the SCC interrupt handler in sccvec.asm */
  145. static INTERRUPT (*Orgivec)(); /* original interrupt vector */
  146. struct sccinfo Sccinfo = {0}; /* global info about SCCs */
  147. struct sccchan *Sccchan[2 * MAXSCC] = {0}; /* information per channel */
  148. ioaddr Sccvecloc = {0}; /* location to access for SCC vector */
  149. unsigned char Sccmaxvec = {0}; /* maximum legal vector from SCC */
  150. ioaddr Sccpolltab[MAXSCC+1][2] = {0}; /* polling table when no vectoring */
  151. #if defined(INLINE)
  152. static unsigned scc_delay(unsigned v);
  153. static unsigned scc_delay (v) /* delay for about 5 PCLK cycles */
  154.    unsigned v; /* pass-through used for input */
  155. {
  156.    register int i,j; /* it takes time to save them */
  157.    return v; /* return the passed parameter */
  158. }
  159. #endif
  160. unsigned char Random = 0; /* random number for p-persist */
  161. static int scc_call(struct iface *ifp,char *call);
  162. static int scc_init(int nchips,ioaddr iobase,int space,int aoff,
  163.  int boff,int doff,ioaddr intack,int ivec,long clk,int pclk,int hwtype,
  164.  int hwparam);
  165. static int scc_raw(struct iface *ifp,struct mbuf **bpp);
  166. static int scc_stop(struct iface *ifp);
  167. static int get_scc(int dev);
  168. static int scc_send(int dev,struct mbuf **bpp);
  169. static int scc_async(struct sccchan *scc);
  170. static void scc_sdlc(struct sccchan *scc);
  171. static void scc_tossb(struct sccchan *scc);
  172. static void scc_txon(struct sccchan *scc);
  173. static void scc_txoff(struct sccchan *scc);
  174. static int32 scc_aioctl(struct iface *ifp,int cmd,int set,int32 val);
  175. static int32 scc_sioctl(struct iface *ifp,int cmd,int set,int32 val);
  176. static void scc_sstart(struct sccchan *scc);
  177. static unsigned int scc_speed(struct sccchan *scc,
  178.   unsigned int clkmode,long speed);
  179. static void scc_asytx(struct sccchan *scc);
  180. static void scc_asyex(struct sccchan *scc);
  181. static void scc_asyrx(struct sccchan *scc);
  182. static void scc_asysp(struct sccchan *scc);
  183. static void scc_sdlctx(struct sccchan *scc);
  184. static void scc_sdlcex(struct sccchan *scc);
  185. static void scc_sdlcrx(struct sccchan *scc);
  186. static void scc_sdlcsp(struct sccchan *scc);
  187. /* Attach an SCC channel to the system, or initialize SCC driver.
  188.  * operation depends on argv[2]:
  189.  * when "init", the SCC driver is initialized, and global information about
  190.  * the hardware is set up.
  191.  * argv[0]: hardware type, must be "scc"
  192.  * argv[1]: number of SCC chips we will support
  193.  * argv[2]: mode, must be: "init" in this case
  194.  * argv[3]: base address of SCC chip #0 (hex)
  195.  * argv[4]: spacing between SCC chip base addresses
  196.  * argv[5]: offset from chip base address to channel A control register
  197.  * argv[6]: offset from chip base address to channel B control register
  198.  * argv[7]: offset from each channel's control register to data register
  199.  * argv[8]: address of INTACK/Read Vector port. 0 to read from RR3A/RR2B
  200.  * argv[9]: CPU interrupt vector number for all connected SCCs
  201.  * argv[10]: clock frequency (PCLK/RTxC) of all SCCs in cycles per second
  202.  *  prefix with "p" for PCLK, "r" for RTxC clock (for baudrate gen)
  203.  * argv[11]: optional hardware type (for special features)
  204.  * argv[12]: optional extra parameter for special hardware
  205.  *
  206.  * otherwise, a single channel is attached using the specified parameters:
  207.  * argv[0]: hardware type, must be "scc"
  208.  * argv[1]: SCC channel number to attach, 0/1 for first chip A/B, 2/3 for 2nd...
  209.  * argv[2]: mode, can be:
  210.  * "slip", "kiss", "ax25"
  211.  * argv[3]: interface label, e.g., "sl0"
  212.  * argv[4]: maximum transmission unit, bytes
  213.  * argv[5]: interface speed, e.g, "1200". prefix with "d" when an external
  214.  * divider is available to generate the TX clock. When the clock
  215.  * source is PCLK, this can be a /32 divider between TRxC and RTxC.
  216.  * When the clock is at RTxC, the TX rate must be supplied at TRxC.
  217.  * This is needed only for AX.25 fullduplex.
  218.  *     When this arg is given as "ext", the transmit and receive clock
  219.  *     are external, and the BRG and DPLL are not used.
  220.  * argv[6]: buffer size
  221.  * argv[7]: callsign used on the radio channels (optional) or 'v' to 
  222.  *          specify Van Jacobson TCP header compression. See argv[8] below.
  223.  * argv[8]: 'v' here specifies Van Jacobson TCP header compression iff
  224.  *          there is a 9th arg (ie. [7] is a callsign.)
  225.  */
  226. int
  227. scc_attach(argc,argv)
  228. int argc;
  229. char *argv[];
  230. {
  231. register struct iface *ifp;
  232. struct sccchan *scc;
  233. unsigned int chan,brgrate;
  234. int pclk = 0,hwtype = 0,hwparam = 0;
  235. int xdev;
  236. char *cp;
  237. /* first handle the special "init" mode, to initialize global stuff */
  238. if(!strcmp(argv[2],"init")){
  239. if(argc < 11) /* need at least argv[1]..argv[10] */
  240. return -1;
  241. if(isupper(argv[10][0]))
  242. argv[10][0] = tolower(argv[10][0]);
  243. if(argv[10][0] == 'p'){ /* wants to use PCLK as clock? */
  244. pclk = 1;
  245. argv[10]++;
  246. } else {
  247. if(argv[10][0] == 'r') /* wants to use RTxC? */
  248. argv[10]++; /* that's the default */
  249. }
  250. if(argc > 11) /* optional hardware type */
  251. hwtype = htoi(argv[11]); /* it is given in hex */
  252. if(argc > 12) /* optional hardware param */
  253. hwparam = htoi(argv[12]); /* also in hex */
  254. return scc_init(atoi(argv[1]),(ioaddr) htol(argv[3]),atoi(argv[4]),
  255. atoi(argv[5]),atoi(argv[6]),atoi(argv[7]),
  256. (ioaddr) htol(argv[8]),atoi(argv[9]),
  257. atol(argv[10]),pclk,hwtype,hwparam);
  258. }
  259. /* not "init", so it must be a valid mode to attach a channel */
  260. if(strcmp(argv[2],"ax25") && strcmp(argv[2],"kiss") &&
  261.  strcmp(argv[2],"slip")){
  262. printf("Mode %s unknown for SCCn",argv[2]);
  263. return -1;
  264. }
  265. if(strcmp(argv[2],"slip") == 0 || strcmp(argv[2],"kiss") == 0){
  266. for(xdev = 0;xdev < SLIP_MAX;xdev++)
  267. if(Slip[xdev].iface == NULL)
  268. break;
  269. if(xdev >= SLIP_MAX){
  270. printf("Too many slip devicesn");
  271. return -1;
  272. }
  273. }
  274. if(strcmp(argv[2],"nrs") == 0){
  275. for(xdev = 0;xdev < NRS_MAX;xdev++)
  276. if(Nrs[xdev].iface == NULL)
  277. break;
  278. if(xdev >= NRS_MAX){
  279. printf("Too many nrs devicesn");
  280. return -1;
  281. }
  282. }
  283. if(!Sccinfo.init){
  284. printf("First init SCC drivern");
  285. return -1;
  286. }
  287. if((chan = atoi(argv[1])) > Sccinfo.maxchan){
  288. printf("SCC channel %d out of rangen",chan);
  289. return -1;
  290. }
  291. if(Sccchan[chan] != NULL){
  292. printf("SCC channel %d already attachedn",chan);
  293. return -1;
  294. }
  295. /* create interface structure and fill in details */
  296. ifp = (struct iface *) callocw(1,sizeof(struct iface));
  297. ifp->name = mallocw(strlen(argv[3]) + 1);
  298. strcpy(ifp->name,argv[3]);
  299. ifp->mtu = atoi(argv[4]);
  300. ifp->dev = chan;
  301. ifp->stop = scc_stop;
  302. scc = (struct sccchan *) callocw(1,sizeof(struct sccchan));
  303. scc->ctrl = Sccinfo.iobase + (chan / 2) * Sccinfo.space + Sccinfo.off[chan % 2];
  304. scc->data = scc->ctrl + Sccinfo.doff;
  305. scc->iface = ifp;
  306. if(isupper(argv[5][0]))
  307. argv[5][0] = tolower(argv[5][0]);
  308.     switch (argv[5][0]) {
  309.     case 'd': /* fulldup divider installed? */
  310. scc->fulldup = 1; /* set appropriate flag */
  311. argv[5]++; /* skip the 'd' */
  312. break;
  313.     case 'e': /* external clocking? */
  314. scc->extclock = 1; /* set the flag */
  315. break;
  316.     }
  317. scc->bufsiz = atoi(argv[6]);
  318. ifp->addr = Ip_addr; 
  319. Sccchan[chan] = scc; /* put addr in table for interrupts */
  320. switch(argv[2][0]){  /* mode already checked above */
  321. #ifdef AX25
  322. case 'a': /* AX.25 */
  323. scc_sdlc(scc); /* init SCC in SDLC mode */
  324. if (!scc->extclock) {
  325. brgrate = scc_speed(scc,32,atol(argv[5]));/* init SCC speed */
  326. scc->speed = Sccinfo.clk / (64L * (brgrate + 2));/* calc real speed */
  327. }
  328. brgrate = scc_speed(scc,32,atol(argv[5]));/* init SCC speed */
  329. scc->speed = Sccinfo.clk / (64L * (brgrate + 2));/* calc real speed */
  330. setencap(ifp,"AX25UI");
  331. scc_call(ifp,argc > 7 ? argv[7] : (char *) 0); /* set the callsign */
  332. ifp->ioctl = scc_sioctl;
  333. ifp->raw = scc_raw;
  334. /* default KISS Params */
  335. scc->a.txdelay = 36*TPS/100; /* 360 ms */
  336. scc->a.persist = 25; /* 10% persistence */
  337. scc->a.slottime = 16*TPS/100; /* 160 ms */
  338. #if TPS > 67
  339. scc->a.tailtime = 3*TPS/100; /* 30 ms */
  340. #else
  341. scc->a.tailtime = 2; /* minimal reasonable value */
  342. #endif
  343. scc->a.fulldup = 0; /* CSMA */
  344. scc->a.waittime = 50*TPS/100; /* 500 ms */
  345. scc->a.maxkeyup = 7; /* 7 s */
  346. scc->a.mintime = 3; /* 3 s */
  347. scc->a.idletime = 120; /* 120 s */
  348. break;
  349. case 'k': /* kiss */
  350. scc_async(scc); /* init SCC in async mode */
  351. brgrate = scc_speed(scc,16,atol(argv[5]));
  352. scc->speed = Sccinfo.clk / (32L * (brgrate + 2));
  353. setencap(ifp,"AX25UI");
  354. scc_call(ifp,argc > 7 ? argv[7] : (char *) 0); /* set the callsign */
  355. ifp->ioctl = kiss_ioctl;
  356. ifp->raw = kiss_raw;
  357. for(xdev = 0;xdev < SLIP_MAX;xdev++){
  358. if(Slip[xdev].iface == NULL)
  359. break;
  360. }
  361. ifp->xdev = xdev;
  362. Slip[xdev].iface = ifp;
  363. Slip[xdev].type = CL_KISS;
  364. Slip[xdev].send = scc_send;
  365. Slip[xdev].get = get_scc;
  366. cp = if_name(ifp," rx");
  367. ifp->rxproc = newproc(cp,256,slip_rx,xdev,NULL,NULL,0);
  368. free(cp);
  369. break;
  370. #endif
  371. #ifdef SLIP
  372. case 's': /* slip */
  373. scc_async(scc); /* init SCC in async mode */
  374. brgrate = scc_speed(scc,16,atol(argv[5]));
  375. scc->speed = Sccinfo.clk / (32L * (brgrate + 2));
  376. setencap(ifp,"SLIP");
  377. ifp->ioctl = scc_aioctl;
  378. ifp->raw = slip_raw;
  379. for(xdev = 0;xdev < SLIP_MAX;xdev++){
  380. if(Slip[xdev].iface == NULL)
  381. break;
  382. }
  383. ifp->xdev = xdev;
  384. Slip[xdev].iface = ifp;
  385. Slip[xdev].type = CL_SERIAL_LINE;
  386. Slip[xdev].send = scc_send;
  387. Slip[xdev].get = get_scc;
  388. cp = if_name(ifp," rx");
  389. #ifdef VJCOMPRESS
  390. if((argc > 8) && (strchr(argv[8],'v') != NULL)) {
  391. Slip[xdev].escaped |= SLIP_VJCOMPR;
  392. Slip[xdev].slcomp = slhc_init(16,16);
  393. } else if((argc > 7) && (strchr(argv[7],'v') != NULL)) {
  394. Slip[xdev].escaped |= SLIP_VJCOMPR;
  395. Slip[xdev].slcomp = slhc_init(16,16);
  396. }
  397. #else
  398. Slip[xdev].slcomp = NULL;
  399. #endif /* VJCOMPRESS */
  400. ifp->rxproc = newproc(cp,256,slip_rx,xdev,NULL,NULL,0);
  401. free(cp);
  402. break;
  403. #endif
  404. #ifdef NRS
  405. case 'n': /* nrs */
  406. scc_async(scc); /* init SCC in async mode */
  407. brgrate = scc_speed(scc,16,atol(argv[5]));
  408. scc->speed = Sccinfo.clk / (32L * (brgrate + 2));
  409. setencap(ifp,"AX25UI");
  410. scc_call(ifp,argc > 7 ? argv[7] : (char *) 0); /* set the callsign */
  411. ifp->ioctl = scc_aioctl;
  412. ifp->raw = nrs_raw;
  413. for(xdev = 0;xdev < NRS_MAX;xdev++)
  414. if(Nrs[xdev].iface == NULL)
  415. break;
  416. ifp->xdev = xdev;
  417. Nrs[xdev].iface = ifp;
  418. Nrs[xdev].send = scc_send;
  419. Nrs[xdev].get = get_scc;
  420. cp = if_name(ifp," rx");
  421. ifp->rxproc = newproc(cp,256,nrs_recv,xdev,NULL,NULL,0);
  422. free(cp);
  423. break;
  424. #endif
  425. }
  426. ifp->next = Ifaces; /* link interface in list */
  427. Ifaces = ifp;
  428. cp = if_name(ifp," tx");
  429. ifp->txproc = newproc(cp,512,if_tx,0,ifp,NULL,0);
  430. free(cp);
  431. return 0;
  432. }
  433. /* SCC driver initialisation. called on "attach scc <num> init ..." */
  434. static int
  435. scc_init(nchips,iobase,space,aoff,boff,doff,intack,ivec,clk,pclk,hwtype,hwparam)
  436. int nchips; /* number of chips */
  437. ioaddr iobase; /* base of first chip */
  438. int space,aoff,boff,doff;
  439. ioaddr intack; /* INTACK ioport or 0 for no INTACK */
  440. int ivec; /* interrupt vector number */
  441. long clk; /* clock frequency */
  442. int pclk; /* PCLK or RTxC for clock */
  443. int hwtype; /* selection of special hardware types */
  444. int hwparam; /* extra parameter for special hardware */
  445. {
  446. int chip,chan;
  447. ioaddr chipbase;
  448. register ioaddr ctrl;
  449.     int d;
  450.     int dum = 1;
  451. int i_state;
  452. #define z 0
  453. if(Sccinfo.init){
  454. printf("SCC driver already initialized - nothing donen");
  455. return 1;
  456. }
  457. Sccinfo.init = 1;
  458. Sccinfo.nchips = nchips;
  459. Sccinfo.maxchan = (2 * nchips) - 1;
  460. Sccinfo.iobase = iobase;
  461. Sccinfo.space = space;
  462. Sccinfo.off[0] = aoff;
  463. Sccinfo.off[1] = boff;
  464. Sccinfo.doff = doff;
  465. Sccinfo.ivec = ivec;
  466. Sccinfo.clk = clk;
  467. Sccinfo.pclk = pclk;
  468. Sccinfo.hwtype = hwtype;
  469. Sccinfo.hwparam = hwparam;
  470. /* reset and pre-init all chips in the system */
  471. for(chip = 0; chip < nchips; chip++){
  472. chipbase = iobase + chip * space;
  473. ctrl = chipbase + Sccinfo.off[0];
  474. i_state = dirps(); /* because of 2-step accesses */
  475. VOID(RDREG(ctrl)); /* make sure pointer is written */
  476. WRSCC(ctrl,R9,FHWRES); /* force hardware reset */
  477. for (d = 0; d < 1000; d++) /* wait a while to be sure */
  478. dum *= 10;
  479. for(chan = 0; chan < 2; chan++){
  480. ctrl = chipbase + Sccinfo.off[chan];
  481. /* initialize a single channel to no-op */
  482. VOID(RDREG(ctrl)); /* make sure pointer is written */
  483. WRSCC(ctrl,R4,z); /* no mode selected yet */
  484. WRSCC(ctrl,R1,z); /* no W/REQ operation */
  485. WRSCC(ctrl,R2,16 * chip); /* chip# in upper 4 bits of vector */
  486. WRSCC(ctrl,R3,z); /* disable rx */
  487. WRSCC(ctrl,R5,z); /* disable tx */
  488. WRSCC(ctrl,R9,VIS); /* vector includes status, MIE off */
  489. Sccpolltab[chip][chan] = ctrl; /* store ctrl addr for polling */
  490. }
  491. if (hwtype & HWSEALEVEL) /* if a SEALEVEL card, */
  492. WRREG(chipbase + 4,hwparam); /* set control/status (DTR) */
  493. if(hwtype & HWEAGLE) /* this is an EAGLE card */
  494. WRREG(chipbase + 4,0x08); /* enable interrupt on the board */
  495. if(hwtype & HWPC100) /* this is a PC100 card */
  496. WRREG(chipbase,hwparam); /* set the MODEM mode (22H normally) */
  497. if(hwtype & HWPRIMUS) /* this is a PRIMUS-PC */
  498. WRREG(chipbase + 4,hwparam); /* set the MODEM mode (02H normally) */
  499. if (hwtype & HWDRSI) { /* this is a DRSI PC*Packet card */
  500. ioaddr z8536 = chipbase + 7; /* point to 8536 master ctrl reg */
  501. /* Initialize 8536 to perform its divide-by-32 function */
  502. /* This part copied from N6TTO DRSI-driver */
  503. /* Start by forcing chip into known state */
  504. VOID(RDREG(z8536)); /* make sure pointer is written */
  505. WRSCC(z8536,CIO_MICR,0x01); /* force hardware reset */
  506. for (d = 0; d < 1000; d++) /* wait a while to be sure */
  507. dum *= 10;
  508. WRSCC(z8536,CIO_MICR,0x00); /* Clear reset and start */
  509. /* Wait for chip to come ready */
  510. while (RDSCC(z8536,CIO_MICR) != 0x02)
  511. dum *= 10;
  512. WRSCC(z8536,CIO_MICR,0x26); /* NV|CT_VIS|RJA */
  513. WRSCC(z8536,CIO_MCCR,0xf4); /* PBE|CT1E|CT2E|CT3E|PAE */
  514. WRSCC(z8536,CIO_CTMS1,0xe2);/* Continuous, EOE, ECE, Pulse output */
  515. WRSCC(z8536,CIO_CTMS2,0xe2);/* Continuous, EOE, ECE, Pulse output */
  516.     WRSCC(z8536,CIO_CT1MSB,0x00); /* Load time constant CTC #1 */
  517. WRSCC(z8536,CIO_CT1LSB,0x10);
  518. WRSCC(z8536,CIO_CT2MSB,0x00); /* Load time constant CTC #2 */
  519. WRSCC(z8536,CIO_CT2LSB,0x10);
  520. WRSCC(z8536,CIO_IVR,0x06);
  521. /* Set port direction bits in port A and B      */
  522. /* Data is input on bits d1 and d5, output on d0 and d4. */
  523. /* The direction is set by 1 for input and 0 for output  */
  524. WRSCC(z8536,CIO_PDCA,0x22);
  525. WRSCC(z8536,CIO_PDCB,0x22);
  526. WRSCC(z8536,CIO_CSR1,CIO_GCB|CIO_TCB); /* Start CTC #1 running */
  527. WRSCC(z8536,CIO_CSR2,CIO_GCB|CIO_TCB); /* Start CTC #2 running */
  528. }
  529. restore(i_state);
  530. }
  531. Sccpolltab[chip][0] = 0; /* terminate the polling table */
  532. Sccvecloc = intack; /* location of INTACK/vector read */
  533. Sccmaxvec = 16 * nchips; /* upper limit on valid vector */
  534. /* save original interrupt vector */
  535. Orgivec = getirq(ivec);
  536. if(intack){ /* INTACK method selected? */
  537. /* set interrupt vector to INTACK-generating routine  */
  538. setirq(ivec,sccvec);
  539. } else {
  540. /* set interrupt vector to polling routine */
  541. setirq(ivec,sccnovec);
  542. }
  543. /* enable the interrupt  */
  544. maskon(ivec);
  545. return 0;
  546. }
  547. /* initialize an SCC channel in asynchronous mode */
  548. static int
  549. scc_async(scc)
  550. register struct sccchan *scc;
  551. {
  552. register struct fifo *fp = &(scc->fifo);
  553. int i_state;
  554. if((fp->buf = malloc(scc->bufsiz)) == NULL){
  555. printf("scc%d: No space for rx buffern",scc->iface->dev);
  556. return -1;
  557. }
  558. fp->bufsize = scc->bufsiz;
  559. fp->wp = fp->rp = fp->buf;
  560. fp->cnt = 0;
  561. scc->int_transmit = scc_asytx; /* set interrupt handlers */
  562. scc->int_extstat = scc_asyex;
  563. scc->int_receive = scc_asyrx;
  564. scc->int_special = scc_asysp;
  565. i_state = dirps();
  566. if (scc->extclock) {
  567. wr(scc,R4,X1CLK|SB1); /* *1 clock, 1 stopbit, no parity */
  568. wr(scc,R11,RCRTxCP|TCTRxCP); /* RXclk RTxC, TXclk TRxC. */
  569. wr(scc,R14,z); /* No BRG options */
  570. wr(scc,R4,X16CLK|SB1); /* *16 clock, 1 stopbit, no parity */
  571. wr(scc,R11,RCBR|TCBR); /* clocks are BR generator */
  572. wr(scc,R14,Sccinfo.pclk? BRSRC:z); /* brg source = PCLK/RTxC */
  573. }
  574. wr(scc,R1,z); /* no W/REQ operation */
  575. wr(scc,R3,Rx8); /* RX 8 bits/char, disabled */
  576. wr(scc,R5,Tx8|DTR|RTS); /* TX 8 bits/char, disabled, DTR RTS */
  577. wr(scc,R9,VIS); /* vector includes status */
  578. wr(scc,R10,NRZ|z); /* select NRZ */
  579. wr(scc,R15,BRKIE); /* enable BREAK ext/status int */
  580. or(scc,R3,RxENABLE); /* enable receiver */
  581. or(scc,R5,TxENAB); /* enable transmitter */
  582. WRREG(scc->ctrl,RES_EXT_INT); /* reset ext/status interrupts */
  583. WRREG(scc->ctrl,RES_EXT_INT); /* must be done twice */
  584. scc->status = RDREG(scc->ctrl); /* read initial status */
  585. or(scc,R1,INT_ALL_Rx|TxINT_ENAB|EXT_INT_ENAB); /* enable interrupts */
  586. or(scc,R9,MIE); /* master interrupt enable */
  587. restore(i_state);
  588. return 0;
  589. }
  590. /* initialize an SCC channel in SDLC mode */
  591. static void
  592. scc_sdlc(scc)
  593. register struct sccchan *scc;
  594. {
  595. int i_state;
  596. scc->int_transmit = scc_sdlctx; /* set interrupt handlers */
  597. scc->int_extstat = scc_sdlcex;
  598. scc->int_receive = scc_sdlcrx;
  599. scc->int_special = scc_sdlcsp;
  600. i_state = dirps();
  601. wr(scc,R4,X1CLK|SDLC); /* *1 clock, SDLC mode */
  602. wr(scc,R1,z); /* no W/REQ operation */
  603. wr(scc,R3,Rx8|RxCRC_ENAB); /* RX 8 bits/char, CRC, disabled */
  604. wr(scc,R5,Tx8|DTR|TxCRC_ENAB); /* TX 8 bits/char, disabled, DTR */
  605. wr(scc,R6,z); /* SDLC address zero (not used) */
  606. wr(scc,R7,FLAG); /* SDLC flag value */
  607. wr(scc,R9,VIS); /* vector includes status */
  608. wr(scc,R10,CRCPS|NRZI|ABUNDER); /* CRC preset 1, select NRZI, ABORT on underrun */
  609. if (scc->extclock){ /* when using external clocks */
  610. /* RXclk RTxC, TXclk TRxC. */
  611. wr(scc,R11,RCRTxCP|TCTRxCP);
  612. wr(scc,R14,z); /* No BRG options */
  613. WRSCC(scc->ctrl,R14,DISDPLL|scc->wreg[R14]); /* No DPLL operation */
  614. } else {
  615. if(scc->fulldup){ /* when external clock divider */
  616. if(Sccinfo.pclk){ /* when using PCLK as clock source */
  617. /* RXclk DPLL, TXclk RTxC, out=BRG.  external /32 TRxC->RTxC */
  618. wr(scc,R11,RCDPLL|TCRTxCP|TRxCOI|TRxCBR);
  619. } else {
  620. /* RXclk DPLL, TXclk TRxC. external TX clock to TRxC */
  621. wr(scc,R11,RCDPLL|TCTRxCP);
  622. }
  623. } else { /* only half-duplex operation */
  624. /* RXclk DPLL, TXclk BRG. BRG reprogrammed at every TX/RX switch */
  625. #ifdef notdef /* KA9Q - for PSK modem */
  626. wr(scc,R11,RCDPLL|TCBR);
  627. #else
  628. /* DPLL -> Rx clk, DPLL -> Tx CLK, TxCLK -> TRxC pin */
  629. wr(scc,R11,RCDPLL|TCDPLL|TRxCOI|TRxCDP);
  630. #endif
  631. }
  632. wr(scc,R14,Sccinfo.pclk? BRSRC:z); /* BRG source = PCLK/RTxC */
  633. WRSCC(scc->ctrl,R14,SSBR|scc->wreg[R14]); /* DPLL source = BRG */
  634. WRSCC(scc->ctrl,R14,SNRZI|scc->wreg[R14]); /* DPLL NRZI mode */
  635. }
  636. wr(scc,R15,BRKIE|CTSIE|DCDIE); /* enable ABORT, CTS & DCD interrupts */
  637. if(RDREG(scc->ctrl) & DCD){ /* DCD is now ON */
  638. if (!scc->extclock)
  639. WRSCC(scc->ctrl,R14,SEARCH|scc->wreg[R14]); /* DPLL: enter search mode */
  640. or(scc,R3,ENT_HM|RxENABLE); /* enable the receiver, hunt mode */
  641. }
  642. WRREG(scc->ctrl,RES_EXT_INT); /* reset ext/status interrupts */
  643. WRREG(scc->ctrl,RES_EXT_INT); /* must be done twice */
  644. scc->status = RDREG(scc->ctrl); /* read initial status */
  645. or(scc,R1,INT_ALL_Rx|TxINT_ENAB|EXT_INT_ENAB); /* enable interrupts */
  646. or(scc,R9,MIE); /* master interrupt enable */
  647. restore(i_state);
  648. }
  649. /* set SCC channel speed
  650.  * clkmode specifies the division rate (1,16,32) inside the SCC
  651.  * returns the selected brgrate for "real speed" calculation
  652.  */
  653. static unsigned int
  654. scc_speed(scc,clkmode,speed)
  655. register struct sccchan *scc;
  656. unsigned int clkmode;
  657. long speed; /* the desired baudrate */
  658. {
  659. unsigned int brgrate;
  660. long spdclkm;
  661. int i_state;
  662. /* calculate baudrate generator value */
  663.     if ((spdclkm = speed * clkmode) == 0)
  664. return 65000U; /* avoid divide-by-zero */
  665. brgrate = (unsigned) ((Sccinfo.clk + spdclkm) / (spdclkm * 2)) - 2;
  666. i_state = dirps(); /* 2-step register accesses... */
  667. cl(scc,R14,BRENABL); /* disable baudrate generator */
  668. wr(scc,R12,brgrate); /* brg rate LOW */
  669. wr(scc,R13,brgrate >> 8); /* brg rate HIGH */
  670. or(scc,R14,BRENABL); /* enable baudrate generator */
  671. restore(i_state);
  672. return brgrate;
  673. }
  674. /* de-activate SCC channel */
  675. static int
  676. scc_stop(ifp)
  677. struct iface *ifp;
  678. {
  679. struct sccchan *scc = Sccchan[ifp->dev];
  680. int i_state;
  681. i_state = dirps();
  682. VOID(RDREG(scc->ctrl)); /* make sure pointer is written */
  683. wr(scc,R9,(ifp->dev % 2)? CHRB : CHRA); /* reset the channel */
  684. switch(ifp->iftype->type){
  685. case CL_SERIAL_LINE:
  686. case CL_KISS:
  687. free(scc->fifo.buf);
  688. default:
  689. break;
  690. }
  691. free(scc);
  692. Sccchan[ifp->dev] = NULL;
  693. restore(i_state);
  694. return 0;
  695. }
  696. /* de-activate SCC driver on program exit */
  697. void
  698. sccstop()
  699. {
  700. if(Sccinfo.init){ /* was it initialized? */
  701. maskoff(Sccinfo.ivec); /* disable the interrupt */
  702. setirq(Sccinfo.ivec,Orgivec); /* restore original interrupt vector */
  703. }
  704. }
  705. /* perform ioctl on SCC (async) channel
  706.  * this is used for SLIP mode only, and will read/set the line speed
  707.  */
  708. static int32
  709. scc_aioctl(ifp,cmd,set,val)
  710. struct iface *ifp;
  711. int cmd;
  712. int set;
  713. int32 val;
  714. {
  715. struct sccchan *scc;
  716. unsigned int brgrate;
  717. scc = Sccchan[ifp->dev];
  718. switch(cmd){
  719. case PARAM_SPEED:
  720. if(set){
  721. brgrate = scc_speed(scc,16,val);
  722. scc->speed = Sccinfo.clk / (32L * (brgrate + 2));
  723. }
  724. return scc->speed;
  725. }
  726. return 0;
  727. }
  728. /* perform ioctl on SCC (sdlc) channel
  729.  * this is used for AX.25 mode only, and will set the "kiss" parameters
  730.  */
  731. static int32
  732. scc_sioctl(ifp,cmd,set,val)
  733. struct iface *ifp;
  734. int cmd;
  735. int set;
  736. int32 val;
  737. {
  738. struct sccchan *scc;
  739. unsigned int brgrate;
  740. int i_state;
  741. scc = Sccchan[ifp->dev];
  742. switch(cmd){
  743. case PARAM_SPEED:
  744. if(set){
  745. if(val == 0)
  746. scc->extclock = 1;
  747. else {
  748.     brgrate = scc_speed(scc,32,val);/* init SCC speed */
  749.     scc->speed = Sccinfo.clk / (64L * (brgrate + 2));/* calc real speed */
  750. }
  751. }
  752. return scc->speed;
  753. case PARAM_TXDELAY:
  754. if(set)
  755. scc->a.txdelay = val;
  756. return scc->a.txdelay;
  757. case PARAM_PERSIST:
  758. if(set)
  759. scc->a.persist = val;
  760. return scc->a.persist;
  761. case PARAM_SLOTTIME:
  762. if(set)
  763. scc->a.slottime = val;
  764. return scc->a.slottime;
  765. case PARAM_TXTAIL:
  766. if(set)
  767. scc->a.tailtime = val;
  768. return scc->a.tailtime;
  769. case PARAM_FULLDUP:
  770. if(set)
  771. scc->a.fulldup = val;
  772. return scc->a.fulldup;
  773. case PARAM_WAIT:
  774. if(set)
  775. scc->a.waittime = val;
  776. return scc->a.waittime;
  777. case PARAM_MAXKEY:
  778. if(set)
  779. scc->a.maxkeyup = val;
  780. return scc->a.maxkeyup;
  781. case PARAM_MIN:
  782. if(set)
  783. scc->a.mintime = val;
  784. return scc->a.mintime;
  785. case PARAM_IDLE:
  786. if(set)
  787. scc->a.idletime = val;
  788. return scc->a.idletime;
  789. case PARAM_DTR:
  790. if(set){
  791. if(val)
  792. scc->wreg[R5] |= DTR;
  793. else
  794. scc->wreg[R5] &= ~DTR;
  795. i_state = dirps();
  796. if(scc->a.tstate == IDLE && scc->timercount == 0)
  797. scc->timercount = 1; /* force an update */
  798. restore(i_state);
  799. }
  800. return (scc->wreg[R5] & DTR) ? 1 : 0;
  801. case PARAM_GROUP:
  802. if(set)
  803. scc->group = val;
  804. return scc->group;
  805. }
  806. return -1;
  807. }
  808. /* start SCC transmitter when it is idle (SLIP/KISS mode only) */
  809. static void
  810. scc_sstart(scc)
  811. register struct sccchan *scc;
  812. {
  813. if(scc->tbp != NULL || /* busy */
  814.  scc->sndq == NULL) /* no work */
  815. return;
  816. scc->tbp = dequeue(&scc->sndq);
  817. WRREG(scc->data,FR_END);
  818. }
  819. /* show SCC status */
  820. int
  821. dosccstat()
  822. {
  823. register struct sccchan *scc;
  824. int i;
  825. if(!Sccinfo.init){
  826. printf("SCC driver not initializedn");
  827. return 0;
  828. }
  829. printf("Ch Iface    Sent   Rcvd   Error Space Overr   Rxints   Txints   Exints   Spintsn");
  830. for(i = 0; i <= Sccinfo.maxchan; i++){
  831. if((scc = Sccchan[i]) == NULL)
  832. continue;
  833. if(scc->int_receive == scc_asyrx)
  834. printf("%2d %-6s  ** asynch ** %7lu %5u %5u %8lu %8lu %8lu %8lun",i,scc->iface->name,
  835.     scc->rxerrs,scc->nospace,scc->rovers,
  836.     scc->rxints,scc->txints,scc->exints,scc->spints);
  837. else
  838. printf("%2d %-6s %6lu %6lu %7lu %5u %5u %8lu %8lu %8lu %8lun",i,scc->iface->name,
  839.     scc->enqueued,scc->rxframes,scc->rxerrs,scc->nospace,scc->rovers,
  840.     scc->rxints,scc->txints,scc->exints,scc->spints);
  841. }
  842. return 0;
  843. }
  844. /* send raw frame to SCC. used for AX.25 */
  845. static int
  846. scc_raw(
  847. struct iface *ifp,
  848. struct mbuf **bpp
  849. ){
  850. struct sccchan *scc;
  851. int i_state;
  852. dump(ifp,IF_TRACE_OUT,*bpp);
  853. ifp->rawsndcnt++;
  854. ifp->lastsent = secclock();
  855. scc = Sccchan[ifp->dev];
  856. if (scc->tx_inhibit){ /* transmitter inhibit */
  857. free_p(bpp);
  858. return -1;
  859.     }
  860. enqueue(&scc->sndq,bpp); /* enqueue packet */
  861. scc->enqueued++;
  862. i_state = dirps();
  863. if(scc->a.tstate == IDLE){ /* when transmitter is idle */
  864. scc->a.tstate = DEFER; /* start the key-up sequence */
  865. scc->a.maxdefer = TPS * scc->a.idletime /
  866. scc->a.slottime;
  867. scc->timercount = scc->a.waittime;
  868. }
  869. restore(i_state);
  870. return 0;
  871. }
  872. static int
  873. scc_send(
  874. int dev,
  875. struct mbuf **bpp
  876. ){
  877. struct sccchan *scc;
  878. scc = Sccchan[dev];
  879. enqueue(&scc->sndq,bpp);
  880. if(scc->tbp == NULL)
  881. scc_sstart(scc);
  882. return(0);
  883. }
  884. /* initialize interface for AX.25 use */
  885. static int
  886. scc_call(ifp,call)
  887. register struct iface *ifp;
  888. char *call;
  889. {
  890. uint8 out[AXALEN];
  891. ifp->hwaddr = mallocw(AXALEN);
  892. if(setcall(out,call) == 0)
  893. memcpy(ifp->hwaddr,out,AXALEN);
  894. else
  895. memcpy(ifp->hwaddr,Mycall,AXALEN);
  896. return 0;
  897. }
  898. /* Interrupt handlers for asynchronous modes (kiss, slip) */
  899. /* Transmitter interrupt handler */
  900. /* This routine sends data from mbufs in SLIP format */
  901. static void
  902. scc_asytx(scc)
  903. register struct sccchan *scc;
  904. {
  905. register struct mbuf *bp;
  906. scc->txints++;
  907. if(scc->txchar != 0){ /* a character pending for transmit? */
  908. WRREG(scc->data,scc->txchar); /* send it now */
  909. scc->txchar = 0; /* next time, ignore it */
  910. return;
  911. }
  912. if(scc->tbp == NULL){ /* nothing to send? */
  913. if((scc->tbp = scc->sndq) != NULL){ /* dequeue next frame */
  914. scc->sndq = scc->sndq->anext;
  915. WRREG(scc->data,FR_END); /* send FR_END to flush line garbage */
  916. } else {
  917. WRREG(scc->ctrl,RES_Tx_P); /* else only reset pending int */
  918. }
  919. return;
  920. }
  921. while ((bp = scc->tbp)->cnt == 0){ /* nothing left in this mbuf? */
  922. bp = bp->next; /* save link to next */
  923. free_mbuf(&scc->tbp);
  924. if((scc->tbp = bp) == NULL){ /* see if more mbufs follow */
  925. WRREG(scc->data,FR_END); /* frame complete, send FR_END */
  926. return;
  927. }
  928. }
  929. /* now bp = scc->tbp (either from while or from if stmt above) */
  930. WRREG(scc->data,*(bp->data)); /* just send the character */
  931. bp->cnt--; /* decrease mbuf byte count */
  932. bp->data++; /* and increment the data pointer */
  933. }
  934. /* External/Status interrupt handler */
  935. static void
  936. scc_asyex(scc)
  937. register struct sccchan *scc;
  938. {
  939. register unsigned char status,changes;
  940. scc->exints++;
  941. status = RDREG(scc->ctrl);
  942. changes = status ^ scc->status;
  943. if(changes & BRK_ABRT){ /* BREAK? */
  944. if((status & BRK_ABRT) == 0) /* BREAK now over? */
  945. VOID(RDREG(scc->data)); /* read the NUL character */
  946. }
  947. scc->status = status;
  948. WRREG(scc->ctrl,RES_EXT_INT);
  949. }
  950. /* Receiver interrupt handler under NOS.
  951.  * Since the higher serial protocol routines are all written to work
  952.  * well with the routines in 8250.c, it makes sense to handle
  953.  * asynch i/o with the 8530 in a similar manner. Therefore, these
  954.  * routines are as close to their counterparts in 8250.c as possible.
  955.  */
  956.  
  957. static void
  958. scc_asyrx(scc)
  959. register struct sccchan *scc;
  960. {
  961. register struct fifo *fp;
  962. char c;
  963. scc->rxints++;
  964. fp = &(scc->fifo);
  965. do {
  966. c = RDREG(scc->data);
  967. if(fp->cnt != fp->bufsize){
  968. *fp->wp++ = c;
  969. if(fp->wp >= &fp->buf[fp->bufsize])
  970. fp->wp = fp->buf;
  971. fp->cnt++;
  972. } else
  973. scc->nospace++;
  974. } while(RDREG(scc->ctrl) & Rx_CH_AV);
  975. ksignal(fp,1); /* eventually move this to timer routine */
  976. }
  977. /* Blocking read from asynch input.
  978.  * Essentially the same as get_asy() in 8250.c
  979.  * See comments in asyrxint().
  980.  */
  981. static int
  982. get_scc(dev)
  983. int dev;
  984. {
  985. register struct fifo *fp;
  986. uint8 c;
  987. int tmp;
  988. int i_state;
  989. fp = &(Sccchan[dev]->fifo);
  990. for(;;){
  991. i_state = dirps();
  992. tmp = fp->cnt;
  993. if(tmp != 0){
  994. fp->cnt--;
  995. restore(i_state);
  996. break;
  997. }
  998. restore(i_state);
  999. kwait(fp);
  1000. }
  1001. c = *fp->rp++;
  1002. if(fp->rp >= &fp->buf[fp->bufsize])
  1003. fp->rp = fp->buf;
  1004. return c;
  1005. }
  1006. int
  1007. scc_frameup(dev)
  1008. int dev;
  1009. {
  1010. Sccchan[dev]->rxframes++;
  1011. return 0;
  1012. }
  1013. /* Receive Special Condition interrupt handler */
  1014. static void
  1015. scc_asysp(scc)
  1016. register struct sccchan *scc;
  1017. {
  1018. register unsigned char status;
  1019. scc->spints++;
  1020. status = rd(scc,R1); /* read receiver status */
  1021. VOID(RDREG(scc->data)); /* flush offending character */
  1022. if(status & (CRC_ERR | Rx_OVR)) /* did a framing error or overrun occur ? */
  1023. scc->rovers++; /* report as overrun */
  1024. WRREG(scc->ctrl,ERR_RES);
  1025. }
  1026. /* Interrupt handlers for sdlc mode (AX.25) */
  1027. /* Transmitter interrupt handler */
  1028. static void
  1029. scc_sdlctx(scc)
  1030. register struct sccchan *scc;
  1031. {
  1032. register struct mbuf *bp;
  1033. scc->txints++;
  1034. switch(scc->a.tstate){ /* look at transmitter state */
  1035. case ACTIVE: /* busy sending data bytes */
  1036. while ((bp = scc->tbp)->cnt == 0){ /* nothing left in this mbuf? */
  1037. bp = bp->next; /* save link to next */
  1038. free_mbuf(&scc->tbp); /*KM*/
  1039. if((scc->tbp = bp) == NULL){/* see if more mbufs follow */
  1040. if(RDREG(scc->ctrl) & TxEOM){ /* check tx underrun status */
  1041. scc->rovers++; /* oops, an underrun! count them */
  1042. WRREG(scc->ctrl,SEND_ABORT);/* send an abort to be sure */
  1043. scc->a.tstate = TAIL; /* key down tx after TAILTIME */
  1044. scc->timercount = scc->a.tailtime;
  1045. return;
  1046. }
  1047. cl(scc,R10,ABUNDER); /* frame complete, allow CRC transmit */
  1048. scc->a.tstate = FLUSH;
  1049. WRREG(scc->ctrl,RES_Tx_P); /* reset pending int */
  1050. return;
  1051. }
  1052. }
  1053. /* now bp = scc->tbp (either from while or from if stmt above) */
  1054. WRREG(scc->data,*(bp->data++)); /* send the character */
  1055. bp->cnt--; /* decrease mbuf byte count */
  1056. return;
  1057. case FLUSH: /* CRC just went out, more to send? */
  1058. or(scc,R10,ABUNDER); /* re-install underrun protection */
  1059. /* verify that we are not exeeding max tx time (if defined) */
  1060. if((scc->timercount != 0 || scc->a.maxkeyup == 0) &&
  1061.  (scc->tbp = scc->sndq) != NULL){ /* dequeue a frame */
  1062. scc->sndq = scc->sndq->anext;
  1063. WRREG(scc->ctrl,RES_Tx_CRC); /* reset the TX CRC generator */
  1064. scc->a.tstate = ACTIVE;
  1065. scc_sdlctx(scc); /* write 1st byte */
  1066. WRREG(scc->ctrl,RES_EOM_L); /* reset the EOM latch */
  1067. return;
  1068. }
  1069. scc->a.tstate = TAIL; /* no more, key down tx after TAILTIME */
  1070. scc->timercount = scc->a.tailtime;
  1071. WRREG(scc->ctrl,RES_Tx_P);
  1072. return;
  1073. default: /* another state */
  1074. WRREG(scc->ctrl,RES_Tx_P); /* then don't send anything */
  1075. return;
  1076. }
  1077. }
  1078. /* External/Status interrupt handler */
  1079. static void
  1080. scc_sdlcex(scc)
  1081. register struct sccchan *scc;
  1082. {
  1083. register unsigned char status,changes;
  1084. scc->exints++;
  1085. status = RDREG(scc->ctrl);
  1086. changes = status ^ scc->status;
  1087. if(changes & BRK_ABRT){ /* Received an ABORT */
  1088. if(status & BRK_ABRT){ /* is this the beginning? */
  1089. if(scc->rbp != NULL){/* did we receive something? */
  1090. /* check if a significant amount of data came in */
  1091. /* this is because the drop of DCD tends to generate an ABORT */
  1092. if(scc->rbp->next != NULL || scc->rbp->cnt > 0)
  1093. scc->rxerrs++; /* then count it as an error */
  1094. scc_tossb(scc); /* throw away buffer */
  1095. }
  1096. VOID(RDREG(scc->data)); /* flush the FIFO */
  1097. VOID(RDREG(scc->data));
  1098. VOID(RDREG(scc->data));
  1099. }
  1100. }
  1101. if(changes & CTS){ /* CTS input changed state */
  1102. if(status & CTS){ /* CTS is now ON */
  1103. if(scc->a.tstate == KEYWT &&
  1104. scc->a.txdelay == 0) /* zero TXDELAY = wait for CTS */
  1105. scc->timercount = 1; /* it will start within 10 ms */
  1106. }
  1107. }
  1108. if(changes & DCD){ /* DCD input changed state */
  1109. if(status & DCD){ /* DCD is now ON */
  1110. if (!scc->extclock)
  1111. WRSCC(scc->ctrl,R14,SEARCH|scc->wreg[R14]); /* DPLL: enter search mode */
  1112. or(scc,R3,ENT_HM|RxENABLE); /* enable the receiver, hunt mode */
  1113. } else { /* DCD is now OFF */
  1114. cl(scc,R3,ENT_HM|RxENABLE); /* disable the receiver */
  1115. VOID(RDREG(scc->data)); /* flush the FIFO */
  1116. VOID(RDREG(scc->data));
  1117. VOID(RDREG(scc->data));
  1118. if(scc->rbp != NULL){/* did we receive something? */
  1119. /* check if a significant amount of data came in */
  1120. /* this is because some characters precede the drop of DCD */
  1121. if(scc->rbp->next != NULL || scc->rbp->cnt > 0)
  1122. scc->rxerrs++; /* then count it as an error */
  1123. scc_tossb(scc); /* throw away buffer */
  1124. }
  1125. }
  1126. }
  1127. scc->status = status;
  1128. WRREG(scc->ctrl,RES_EXT_INT);
  1129. }
  1130. /* Receiver interrupt handler */
  1131. static void
  1132. scc_sdlcrx(scc)
  1133. register struct sccchan *scc;
  1134. {
  1135. register struct mbuf *bp;
  1136. scc->rxints++;
  1137. if((bp = scc->rbp1) == NULL){ /* no buffer available now */
  1138. if(scc->rbp == NULL){
  1139. if((bp = alloc_mbuf(scc->bufsiz+sizeof(struct iface *))) != NULL){
  1140. scc->rbp = scc->rbp1 = bp;
  1141. bp->cnt = 0;
  1142. }
  1143. } else if((bp = alloc_mbuf(scc->bufsiz)) != NULL){
  1144. scc->rbp1 = bp;
  1145. for(bp = scc->rbp; bp->next != NULL; bp = bp->next)
  1146. ;
  1147. bp->next = scc->rbp1;
  1148. bp = scc->rbp1;
  1149. }
  1150. if(bp == NULL){
  1151. VOID(RDREG(scc->data)); /* so we have to discard the char */
  1152. or(scc,R3,ENT_HM); /* enter hunt mode for next flag */
  1153. scc_tossb(scc); /* put buffers back on pool */
  1154. scc->nospace++; /* count these events */
  1155. return;
  1156. }
  1157. }
  1158. /* now, we have a buffer (at bp). read character and store it */
  1159. bp->data[bp->cnt++] = RDREG(scc->data);
  1160. if(bp->cnt == bp->size) /* buffer full? */
  1161. scc->rbp1 = NULL; /* acquire a new one next time */
  1162. }
  1163. /* Receive Special Condition interrupt handler */
  1164. static void
  1165. scc_sdlcsp(scc)
  1166. register struct sccchan *scc;
  1167. {
  1168. register unsigned char status;
  1169. register struct mbuf *bp;
  1170. scc->spints++;
  1171. status = rd(scc,R1); /* read receiver status */
  1172. VOID(RDREG(scc->data)); /* flush offending character */
  1173. if(status & Rx_OVR){ /* receiver overrun */
  1174. scc->rovers++; /* count them */
  1175. or(scc,R3,ENT_HM); /* enter hunt mode for next flag */
  1176. scc_tossb(scc); /* rewind the buffer and toss */
  1177. }
  1178. if(status & END_FR && /* end of frame */
  1179. scc->rbp != NULL){ /* at least received something */
  1180. if((status & CRC_ERR) == 0 && /* no CRC error is indicated */
  1181. (status & 0xe) == RES8 && /* 8 bits in last byte */
  1182. scc->rbp->cnt > 0){
  1183. /* we seem to have a good frame. but the last byte received */
  1184. /* from rx interrupt is in fact a CRC byte, so discard it */
  1185. if(scc->rbp1 != NULL){
  1186. scc->rbp1->cnt--; /* current mbuf was not full */
  1187. } else {
  1188. for(bp = scc->rbp; bp->next != NULL; bp = bp->next);
  1189. /* find last mbuf */
  1190. bp->cnt--; /* last byte is first CRC byte */
  1191. }
  1192. net_route(scc->iface,&scc->rbp);
  1193. scc->rbp = scc->rbp1 = NULL;
  1194. scc->rxframes++;
  1195. } else { /* a bad frame */
  1196. scc_tossb(scc); /* throw away frame */
  1197. scc->rxerrs++;
  1198. }
  1199. }
  1200. WRREG(scc->ctrl,ERR_RES);
  1201. }
  1202. /* Throw away receive mbuf(s) when an error occurred */
  1203. static void
  1204. scc_tossb (scc)
  1205. register struct sccchan *scc;
  1206. {
  1207. register struct mbuf *bp;
  1208. if((bp = scc->rbp) != NULL){
  1209. free_p(&bp->next);
  1210. free_p(&bp->dup); /* Should be NULL */
  1211. bp->next = NULL;
  1212. scc->rbp1 = bp; /* Don't throw this one away */
  1213. bp->cnt = 0; /* Simply rewind it */
  1214. }
  1215. }
  1216. /* Switch the SCC to "transmit" mode */
  1217. /* Only to be called from an interrupt handler, while in AX.25 mode */
  1218. static void
  1219. scc_txon(scc)
  1220. register struct sccchan *scc;
  1221. {
  1222.     if (!scc->fulldup && !scc->extclock){ /* no fulldup divider? */
  1223. cl(scc,R3,RxENABLE); /* then switch off receiver */
  1224. cl(scc,R5,TxENAB); /* transmitter off during switch */
  1225. scc_speed(scc,1,scc->speed); /* reprogram baudrate generator */
  1226. }
  1227. or(scc,R5,RTS|TxENAB); /* set the RTS line and enable TX */
  1228. if(Sccinfo.hwtype & HWPRIMUS) /* PRIMUS has another PTT bit... */
  1229. WRREG(scc->ctrl + 4,Sccinfo.hwparam | 0x80); /* set that bit! */
  1230. }
  1231. /* Switch the SCC to "receive" mode (or: switch off transmitter)
  1232.  * Only to be called from an interrupt handler, while in AX.25 mode
  1233.  */
  1234. static void
  1235. scc_txoff(scc)
  1236. register struct sccchan *scc;
  1237. {
  1238. cl(scc,R5,RTS); /* turn off RTS line */
  1239. if(Sccinfo.hwtype & HWPRIMUS) /* PRIMUS has another PTT bit... */
  1240. WRREG(scc->ctrl + 4,Sccinfo.hwparam); /* clear that bit! */
  1241.     if (!scc->fulldup && !scc->extclock){ /* no fulldup divider? */
  1242. cl(scc,R5,TxENAB); /* then disable the transmitter */
  1243. scc_speed(scc,32,scc->speed); /* back to receiver baudrate */
  1244. }
  1245. }
  1246. /* SCC timer interrupt handler. Will be called every 1/TPS s by the 
  1247.  * routine systick in pc.c
  1248.  */
  1249. void scctimer()
  1250. {
  1251. register struct sccchan *scc;
  1252. register struct sccchan **sccp;
  1253. int i_state;
  1254. i_state = dirps();
  1255. for(sccp = Sccchan + Sccinfo.maxchan; sccp >= Sccchan; sccp--){
  1256. if((scc = *sccp) != NULL &&
  1257.   scc->timercount != 0 &&
  1258.   --(scc->timercount) == 0){
  1259. /* handle an SCC timer event for this SCC channel
  1260.  * this can only happen when the channel is AX.25 type
  1261.  * (the SLIP/KISS driver does not use timers)
  1262.  */
  1263. switch(scc->a.tstate){
  1264. case IDLE: /* it was idle, this is FULLDUP2 timeout */
  1265. scc_txoff(scc); /* switch-off the transmitter */
  1266. break;
  1267. case DEFER: /* trying to get the channel */
  1268. /* operation is as follows:
  1269.  * CSMA: when channel clear AND persistence randomgenerator
  1270.  *  wins, AND group restrictions allow it:
  1271.  * keyup the transmitter
  1272.  *  if not, delay one SLOTTIME and try again
  1273.  * FULL: always keyup the transmitter
  1274.  */
  1275. if(scc->a.fulldup == 0){
  1276. Random = 21 * Random + 53;
  1277. if(scc->status & DCD || scc->a.persist < Random){
  1278. /* defer transmission again. check for limit */
  1279. defer_it: if(--(scc->a.maxdefer) == 0){
  1280. /* deferred too long. choice is to:
  1281.  * - throw away pending frames, or
  1282.  * - smash-on the transmitter and send them.
  1283.  * the first would be the choice in a clean
  1284.  * environment, but in the amateur radio world
  1285.  * a distant faulty station could tie us up
  1286.  * forever, so the second may be better...
  1287. */
  1288. #ifdef THROW_AWAY_AFTER_DEFER_TIMEOUT
  1289. struct mbuf *bp,*bp1;
  1290. while ((bp = scc->sndq) != NULL){
  1291. scc->sndq = scc->sndq->anext;
  1292. free_p(&bp);
  1293. }
  1294. #else
  1295. goto keyup; /* just keyup the transmitter... */
  1296. #endif
  1297. }
  1298. scc->timercount = scc->a.slottime;
  1299. break;
  1300. }
  1301. if(scc->group != NOGROUP){
  1302. int i;
  1303. struct sccchan *scc2;
  1304. for(i = 0; i <= Sccinfo.maxchan; i++)
  1305. if((scc2 = Sccchan[i]) != NULL &&
  1306.  scc2 != scc &&
  1307.  scc2->group & scc->group &&
  1308.  ((scc->group & TXGROUP && scc2->wreg[R5] & RTS) ||
  1309.  (scc->group & RXGROUP && scc2->status & DCD))){
  1310. goto defer_it;
  1311. }
  1312. }
  1313. }
  1314. case KEYUP: /* keyup transmitter (note fallthrough) */
  1315. keyup: if((scc->wreg[R5] & RTS) == 0){ /* when not yet keyed */
  1316. scc->a.tstate = KEYWT;
  1317. scc->timercount = scc->a.txdelay; /* 0 if CTSwait */
  1318. scc_txon(scc);
  1319. break;
  1320. }
  1321. /* when already keyed, directly fall through */
  1322. case KEYWT: /* waited for CTS or TXDELAY */
  1323. /* when a frame is available (it should be...):
  1324.  * - dequeue it from the send queue
  1325.  * - reset the transmitter CRC generator
  1326.  * - set a timeout on transmission length, if defined
  1327.  * - send the first byte of the frame
  1328.  * - reset the EOM latch
  1329.  * when no frame available, proceed to TAIL handling
  1330.  */
  1331. if((scc->tbp = scc->sndq) != NULL){
  1332. scc->sndq = scc->sndq->anext;
  1333. WRREG(scc->ctrl,RES_Tx_CRC);
  1334. scc->a.tstate = ACTIVE;
  1335. scc->timercount = TPS * scc->a.maxkeyup;
  1336. scc_sdlctx(scc);
  1337. WRREG(scc->ctrl,RES_EOM_L);
  1338. break;
  1339. }
  1340. /* when no frame queued, fall through to TAIL case */
  1341. case TAIL: /* at end of frame */
  1342. /* when fulldup is 0 or 1, switch off the transmitter.
  1343.  * when frames are still queued (because of transmit time limit),
  1344.  * restart the procedure to get the channel after MINTIME.
  1345.  * when fulldup is 2, the transmitter remains keyed and we
  1346.  * continue sending. IDLETIME is an idle timeout in this case.
  1347.  */
  1348. if(scc->a.fulldup < 2){
  1349. scc->a.tstate = IDLE;
  1350. scc_txoff(scc);
  1351. if(scc->sndq != NULL){
  1352. scc->a.tstate = DEFER;
  1353. scc->a.maxdefer = TPS * scc->a.idletime /
  1354.  scc->a.slottime;
  1355. scc->timercount = TPS * scc->a.mintime;
  1356. }
  1357. break;
  1358. }
  1359. if(scc->sndq != NULL){ /* still frames on the queue? */
  1360. scc->a.tstate = KEYWT; /* continue sending */
  1361. scc->timercount = TPS * scc->a.mintime; /* after mintime */
  1362. } else {
  1363. scc->a.tstate = IDLE;
  1364. scc->timercount = TPS * scc->a.idletime;
  1365. }
  1366. break;
  1367. case ACTIVE: /* max keyup time expired */
  1368. case FLUSH: /* same while in flush mode */
  1369. break; /* no action required yet */
  1370. default: /* unexpected state */
  1371. scc->a.tstate = IDLE; /* that should not happen, but... */
  1372. scc_txoff(scc); /* at least stop the transmitter */
  1373. break;
  1374. }
  1375. }
  1376. }
  1377. restore(i_state);
  1378. }