Lines Matching +full:modem +full:- +full:init
6 * Please use z8530drv-utils-3.0 with this version.
7 * ------------------
15 * SCC.C - Linux driver for Z8530 based HDLC cards for AX.25 *
28 The code is likely to fail, and so your kernel could --- even
40 For non-Amateur-Radio use please note that you might need a special
42 MODEM.
60 -------------------------------
62 1994-09-13 started to write the driver, rescued most of my own
71 1995-01-31 changed copyright notice to GPL without limitations.
77 1996-10-05 New semester, new driver...
85 * Invents brand new bugs... ;-)
90 1996-12-13 Fixed for Linux networking changes. (G4KLX)
91 1997-01-08 Fixed the remaining problems.
92 1997-04-02 Hopefully fixed the problems with the new *_timer()
94 1997-10-12 Made SCC_DELAY a CONFIG option, added CONFIG_SCC_TRXECHO
95 1998-01-29 Small fix to avoid lock-up on initialization
96 1998-09-29 Fixed the "grouping" bugs, tx_inhibit works again,
97 using dev->tx_queue_len now instead of MAXQUEUE now.
98 1998-10-21 Postponed the spinlock changes, would need a lot of
101 1998-11-04 Softdcd does not work correctly in DPLL mode, in fact it
106 2000-02-13 Fixed for new network driver interface changes, still
113 NB -- if you find errors, change something, please let me know
121 New versions of the driver will be announced on the linux-hams
122 mailing list on vger.kernel.org. To subscribe send an e-mail
126 subscribe linux-hams
131 Joerg Reuter ampr-net: dl1bke@db0pra.ampr.org
132 AX-25 : DL1BKE @ DB0ABH.#BAY.DEU.EU
137 /* ----------------------------------------------------------------------- */
149 /* ----------------------------------------------------------------------- */
168 #include <linux/init.h>
238 /* These provide interrupt save 2-step access to the Z8530 registers */
279 OutReg(scc->ctrl, reg, (scc->wreg[reg] = val)); in wr()
284 OutReg(scc->ctrl, reg, (scc->wreg[reg] |= val)); in or()
289 OutReg(scc->ctrl, reg, (scc->wreg[reg] &= ~val)); in cl()
300 spin_lock_irqsave(&scc->lock, flags); in scc_discard_buffers()
301 if (scc->tx_buff != NULL) in scc_discard_buffers()
303 dev_kfree_skb(scc->tx_buff); in scc_discard_buffers()
304 scc->tx_buff = NULL; in scc_discard_buffers()
307 while (!skb_queue_empty(&scc->tx_queue)) in scc_discard_buffers()
308 dev_kfree_skb(skb_dequeue(&scc->tx_queue)); in scc_discard_buffers()
310 spin_unlock_irqrestore(&scc->lock, flags); in scc_discard_buffers()
320 /* ----> subroutines for the interrupt handlers <---- */
327 if (scc->kiss.fulldup != KISS_DUPLEX_OPTIMA) in scc_notify()
338 scc->stat.nospace++; in scc_notify()
346 Inb(scc->data); in flush_rx_FIFO()
348 if(scc->rx_buff != NULL) /* did we receive something? */ in flush_rx_FIFO()
350 scc->stat.rxerrs++; /* then count it as an error */ in flush_rx_FIFO()
351 dev_kfree_skb_irq(scc->rx_buff); in flush_rx_FIFO()
352 scc->rx_buff = NULL; in flush_rx_FIFO()
358 if ((scc->modem.clocksrc != CLK_EXTERNAL)) in start_hunt()
359 OutReg(scc->ctrl,R14,SEARCH|scc->wreg[R14]); /* DPLL: enter search mode */ in start_hunt()
363 /* ----> four different interrupt handlers for Tx, Rx, changing of */
371 scc->stat.txints++; in scc_txint()
372 skb = scc->tx_buff; in scc_txint()
378 skb = skb_dequeue(&scc->tx_queue); in scc_txint()
379 scc->tx_buff = skb; in scc_txint()
380 netif_wake_queue(scc->dev); in scc_txint()
385 Outb(scc->ctrl, RES_Tx_P); in scc_txint()
389 if (skb->len == 0) /* Paranoia... */ in scc_txint()
392 scc->tx_buff = NULL; in scc_txint()
394 Outb(scc->ctrl, RES_Tx_P); in scc_txint()
398 scc->stat.tx_state = TXS_ACTIVE; in scc_txint()
400 OutReg(scc->ctrl, R0, RES_Tx_CRC); in scc_txint()
402 or(scc,R10,ABUNDER); /* re-install underrun protection */ in scc_txint()
403 Outb(scc->data,*skb->data); /* send byte */ in scc_txint()
406 if (!scc->enhanced) /* reset EOM latch */ in scc_txint()
407 Outb(scc->ctrl,RES_EOM_L); in scc_txint()
413 if (skb->len == 0) in scc_txint()
415 Outb(scc->ctrl, RES_Tx_P); /* reset pending int */ in scc_txint()
418 scc->tx_buff = NULL; in scc_txint()
419 scc->stat.tx_state = TXS_NEWFRAME; /* next frame... */ in scc_txint()
425 Outb(scc->data,*skb->data); in scc_txint()
435 scc->stat.exints++; in scc_exint()
437 status = InReg(scc->ctrl,R0); in scc_exint()
438 changes = status ^ scc->status; in scc_exint()
448 if ((changes & SYNC_HUNT) && scc->kiss.softdcd) in scc_exint()
452 scc->dcd = 0; in scc_exint()
454 if ((scc->modem.clocksrc != CLK_EXTERNAL)) in scc_exint()
455 OutReg(scc->ctrl,R14,SEARCH|scc->wreg[R14]); /* DPLL: enter search mode */ in scc_exint()
457 scc->dcd = 1; in scc_exint()
460 scc_notify(scc, scc->dcd? HWEV_DCD_OFF:HWEV_DCD_ON); in scc_exint()
466 if((changes & DCD) && !scc->kiss.softdcd) /* DCD input changed state */ in scc_exint()
471 scc->dcd = 1; in scc_exint()
475 scc->dcd = 0; in scc_exint()
478 scc_notify(scc, scc->dcd? HWEV_DCD_ON:HWEV_DCD_OFF); in scc_exint()
490 if (scc->kiss.txdelay == 0) /* zero TXDELAY = wait for CTS */ in scc_exint()
495 if (scc->stat.tx_state == TXS_ACTIVE && (status & TxEOM)) in scc_exint()
497 scc->stat.tx_under++; /* oops, an underrun! count 'em */ in scc_exint()
498 Outb(scc->ctrl, RES_EXT_INT); /* reset ext/status interrupts */ in scc_exint()
500 if (scc->tx_buff != NULL) in scc_exint()
502 dev_kfree_skb_irq(scc->tx_buff); in scc_exint()
503 scc->tx_buff = NULL; in scc_exint()
510 scc->status = status; in scc_exint()
511 Outb(scc->ctrl,RES_EXT_INT); in scc_exint()
520 scc->stat.rxints++; in scc_rxint()
522 if((scc->wreg[5] & RTS) && scc->kiss.fulldup == KISS_DUPLEX_HALF) in scc_rxint()
524 Inb(scc->data); /* discard char */ in scc_rxint()
529 skb = scc->rx_buff; in scc_rxint()
533 skb = dev_alloc_skb(scc->stat.bufsize); in scc_rxint()
536 scc->dev_stat.rx_dropped++; in scc_rxint()
537 scc->stat.nospace++; in scc_rxint()
538 Inb(scc->data); in scc_rxint()
543 scc->rx_buff = skb; in scc_rxint()
547 if (skb->len >= scc->stat.bufsize) in scc_rxint()
553 scc->rx_buff = NULL; in scc_rxint()
554 Inb(scc->data); in scc_rxint()
559 skb_put_u8(skb, Inb(scc->data)); in scc_rxint()
569 scc->stat.spints++; in scc_spint()
571 status = InReg(scc->ctrl,R1); /* read receiver status */ in scc_spint()
573 Inb(scc->data); /* throw away Rx byte */ in scc_spint()
574 skb = scc->rx_buff; in scc_spint()
578 scc->stat.rx_over++; /* count them */ in scc_spint()
583 scc->rx_buff = skb = NULL; in scc_spint()
590 if (!(status & CRC_ERR) && (status & 0xe) == RES8 && skb->len > 0) in scc_spint()
593 skb_trim(skb, skb->len-1); in scc_spint()
595 scc->rx_buff = NULL; in scc_spint()
596 scc->stat.rxframes++; in scc_spint()
599 scc->rx_buff = NULL; in scc_spint()
600 scc->stat.rxerrs++; in scc_spint()
604 Outb(scc->ctrl,ERR_RES); in scc_spint()
608 /* ----> interrupt service routine for the Z8530 <---- */
612 spin_lock(&scc->lock); in scc_isr_dispatch()
620 spin_unlock(&scc->lock); in scc_isr_dispatch()
649 if (!scc->dev) break; in scc_isr()
653 OutReg(scc->ctrl,R0,RES_H_IUS); /* Reset Highest IUS */ in scc_isr()
667 while (ctrl->chan_A) in scc_isr()
669 if (ctrl->irq != chip_irq) in scc_isr()
676 for (k = 0; InReg(ctrl->chan_A,R3) && k < SCC_IRQTIMEOUT; k++) in scc_isr()
678 vector=InReg(ctrl->chan_B,R2); /* Read the vector */ in scc_isr()
682 if (!scc->dev) break; in scc_isr()
702 OutReg(scc->ctrl,R0,RES_H_IUS); in scc_isr()
713 /* * Init Channel */
717 /* ----> set SCC channel speed <---- */
730 spin_lock_irqsave(&scc->lock, flags); in set_speed()
732 if (scc->modem.speed > 0) /* paranoia... */ in set_speed()
733 set_brg(scc, (unsigned) (scc->clock / (scc->modem.speed * 64)) - 2); in set_speed()
735 spin_unlock_irqrestore(&scc->lock, flags); in set_speed()
739 /* ----> initialize a SCC channel <---- */
744 OutReg(scc->ctrl, R14, SSBR|scc->wreg[R14]); /* DPLL source = BRG */ in init_brg()
745 OutReg(scc->ctrl, R14, SNRZI|scc->wreg[R14]); /* DPLL NRZI mode */ in init_brg()
749 * Initialization according to the Z8530 manual (SGS-Thomson's version):
786 * X = user defined, S = same as previous init
795 del_timer(&scc->tx_t); in init_channel()
796 del_timer(&scc->tx_wdog); in init_channel()
798 disable_irq(scc->irq); in init_channel()
807 …wr(scc,R10,(scc->modem.nrz? NRZ : NRZI)|CRCPS|ABUNDER); /* abort on underrun, preset CRC generator… in init_channel()
819 CLK_EXTERNAL: external clocking (G3RUH or DF9IC modem) in init_channel()
837 switch(scc->modem.clocksrc) in init_channel()
845 wr(scc, R11, ((scc->brand & BAYCOM)? TRxCDP : TRxCBR) | RCDPLL|TCRTxCP|TRxCOI); in init_channel()
850 wr(scc, R11, (scc->brand & BAYCOM)? RCTRxCP|TCRTxCP : RCRTxCP|TCTRxCP); in init_channel()
851 OutReg(scc->ctrl, R14, DISDPLL); in init_channel()
858 if(scc->enhanced) in init_channel()
864 if(scc->kiss.softdcd || (InReg(scc->ctrl,R0) & DCD)) in init_channel()
872 wr(scc,R15, BRKIE|TxUIE|(scc->kiss.softdcd? SYNCIE:DCDIE)); in init_channel()
874 Outb(scc->ctrl,RES_EXT_INT); /* reset ext/status interrupts */ in init_channel()
875 Outb(scc->ctrl,RES_EXT_INT); /* must be done twice */ in init_channel()
879 scc->status = InReg(scc->ctrl,R0); /* read initial status */ in init_channel()
885 enable_irq(scc->irq); in init_channel()
896 /* ----> scc_key_trx sets the time constant for the baudrate
897 generator and keys the transmitter <---- */
903 if (scc->brand & PRIMUS) in scc_key_trx()
904 Outb(scc->ctrl + 4, scc->option | (tx? 0x80 : 0)); in scc_key_trx()
906 if (scc->modem.speed < 300) in scc_key_trx()
907 scc->modem.speed = 1200; in scc_key_trx()
909 time_const = (unsigned) (scc->clock / (scc->modem.speed * (tx? 2:64))) - 2; in scc_key_trx()
911 disable_irq(scc->irq); in scc_key_trx()
919 if (scc->modem.clocksrc == CLK_DPLL) in scc_key_trx()
929 /* DPLL -> Rx clk, BRG -> Tx CLK, TRxC mode output, TRxC = BRG */ in scc_key_trx()
933 if (scc->kiss.tx_inhibit) in scc_key_trx()
936 scc->wreg[R5] |= RTS; in scc_key_trx()
945 /* DPLL -> Rx clk, DPLL -> Tx CLK, TRxC mode output, TRxC = DPLL */ in scc_key_trx()
949 if (scc->kiss.softdcd) in scc_key_trx()
952 or(scc,R15, scc->kiss.softdcd? SYNCIE:DCDIE); in scc_key_trx()
960 if (scc->kiss.fulldup == KISS_DUPLEX_HALF) in scc_key_trx()
967 if (scc->kiss.tx_inhibit) in scc_key_trx()
970 scc->wreg[R5] |= RTS; in scc_key_trx()
977 if ((scc->kiss.fulldup == KISS_DUPLEX_HALF) && in scc_key_trx()
979 scc->kiss.softdcd) in scc_key_trx()
984 or(scc, R15, scc->kiss.softdcd? SYNCIE:DCDIE); in scc_key_trx()
990 enable_irq(scc->irq); in scc_key_trx()
994 /* ----> SCC timer interrupt handler and friends. <---- */
1000 del_timer(&scc->tx_t); in __scc_start_tx_timer()
1004 handler(&scc->tx_t); in __scc_start_tx_timer()
1008 scc->tx_t.function = handler; in __scc_start_tx_timer()
1009 scc->tx_t.expires = jiffies + (when*HZ)/100; in __scc_start_tx_timer()
1010 add_timer(&scc->tx_t); in __scc_start_tx_timer()
1020 spin_lock_irqsave(&scc->lock, flags); in scc_start_tx_timer()
1022 spin_unlock_irqrestore(&scc->lock, flags); in scc_start_tx_timer()
1029 spin_lock_irqsave(&scc->lock, flags); in scc_start_defer()
1030 del_timer(&scc->tx_wdog); in scc_start_defer()
1032 if (scc->kiss.maxdefer != 0 && scc->kiss.maxdefer != TIMER_OFF) in scc_start_defer()
1034 scc->tx_wdog.function = t_busy; in scc_start_defer()
1035 scc->tx_wdog.expires = jiffies + HZ*scc->kiss.maxdefer; in scc_start_defer()
1036 add_timer(&scc->tx_wdog); in scc_start_defer()
1038 spin_unlock_irqrestore(&scc->lock, flags); in scc_start_defer()
1045 spin_lock_irqsave(&scc->lock, flags); in scc_start_maxkeyup()
1046 del_timer(&scc->tx_wdog); in scc_start_maxkeyup()
1048 if (scc->kiss.maxkeyup != 0 && scc->kiss.maxkeyup != TIMER_OFF) in scc_start_maxkeyup()
1050 scc->tx_wdog.function = t_maxkeyup; in scc_start_maxkeyup()
1051 scc->tx_wdog.expires = jiffies + HZ*scc->kiss.maxkeyup; in scc_start_maxkeyup()
1052 add_timer(&scc->tx_wdog); in scc_start_maxkeyup()
1054 spin_unlock_irqrestore(&scc->lock, flags); in scc_start_maxkeyup()
1068 switch (scc->kiss.fulldup) in scc_tx_done()
1071 scc->stat.tx_state = TXS_IDLE2; in scc_tx_done()
1072 if (scc->kiss.idletime != TIMER_OFF) in scc_tx_done()
1074 scc->kiss.idletime*100); in scc_tx_done()
1080 scc->stat.tx_state = TXS_BUSY; in scc_tx_done()
1081 scc_start_tx_timer(scc, t_tail, scc->kiss.tailtime); in scc_tx_done()
1084 netif_wake_queue(scc->dev); in scc_tx_done()
1096 grp1 = scc->kiss.group; in is_grouped()
1101 grp2 = scc2->kiss.group; in is_grouped()
1103 if (scc2 == scc || !(scc2->dev && grp2)) in is_grouped()
1108 if ( (grp1 & TXGROUP) && (scc2->wreg[R5] & RTS) ) in is_grouped()
1111 if ( (grp1 & RXGROUP) && scc2->dcd ) in is_grouped()
1120 * fulldup == 0: DCD is active or Rand > P-persistence: start t_busy timer
1130 if (scc->stat.tx_state == TXS_WAIT) /* maxkeyup or idle timeout */ in t_dwait()
1132 if (skb_queue_empty(&scc->tx_queue)) { /* nothing to send */ in t_dwait()
1133 scc->stat.tx_state = TXS_IDLE; in t_dwait()
1134 netif_wake_queue(scc->dev); /* t_maxkeyup locked it. */ in t_dwait()
1138 scc->stat.tx_state = TXS_BUSY; in t_dwait()
1141 if (scc->kiss.fulldup == KISS_DUPLEX_HALF) in t_dwait()
1145 if (scc->dcd || (scc->kiss.persist) < Rand || (scc->kiss.group && is_grouped(scc)) ) in t_dwait()
1148 scc_start_tx_timer(scc, t_dwait, scc->kiss.slottime); in t_dwait()
1153 if ( !(scc->wreg[R5] & RTS) ) in t_dwait()
1156 scc_start_tx_timer(scc, t_txdelay, scc->kiss.txdelay); in t_dwait()
1174 if (scc->tx_buff == NULL) in t_txdelay()
1176 disable_irq(scc->irq); in t_txdelay()
1178 enable_irq(scc->irq); in t_txdelay()
1194 spin_lock_irqsave(&scc->lock, flags); in t_tail()
1195 del_timer(&scc->tx_wdog); in t_tail()
1197 spin_unlock_irqrestore(&scc->lock, flags); in t_tail()
1199 if (scc->stat.tx_state == TXS_TIMEOUT) /* we had a timeout? */ in t_tail()
1201 scc->stat.tx_state = TXS_WAIT; in t_tail()
1202 scc_start_tx_timer(scc, t_dwait, scc->kiss.mintime*100); in t_tail()
1206 scc->stat.tx_state = TXS_IDLE; in t_tail()
1207 netif_wake_queue(scc->dev); in t_tail()
1220 del_timer(&scc->tx_t); in t_busy()
1221 netif_stop_queue(scc->dev); /* don't pile on the wabbit! */ in t_busy()
1224 scc->stat.txerrs++; in t_busy()
1225 scc->stat.tx_state = TXS_IDLE; in t_busy()
1227 netif_wake_queue(scc->dev); in t_busy()
1240 spin_lock_irqsave(&scc->lock, flags); in t_maxkeyup()
1246 netif_stop_queue(scc->dev); in t_maxkeyup()
1249 del_timer(&scc->tx_t); in t_maxkeyup()
1253 OutReg(scc->ctrl, R0, RES_Tx_P); in t_maxkeyup()
1255 spin_unlock_irqrestore(&scc->lock, flags); in t_maxkeyup()
1257 scc->stat.txerrs++; in t_maxkeyup()
1258 scc->stat.tx_state = TXS_TIMEOUT; in t_maxkeyup()
1259 scc_start_tx_timer(scc, t_tail, scc->kiss.tailtime); in t_maxkeyup()
1273 del_timer(&scc->tx_wdog); in t_idle()
1276 if(scc->kiss.mintime) in t_idle()
1277 scc_start_tx_timer(scc, t_dwait, scc->kiss.mintime*100); in t_idle()
1278 scc->stat.tx_state = TXS_WAIT; in t_idle()
1285 spin_lock_irqsave(&scc->lock, flags); in scc_init_timer()
1286 scc->stat.tx_state = TXS_IDLE; in scc_init_timer()
1287 spin_unlock_irqrestore(&scc->lock, flags); in scc_init_timer()
1306 case PARAM_TXDELAY: scc->kiss.txdelay=arg; break; in scc_set_param()
1307 case PARAM_PERSIST: scc->kiss.persist=arg; break; in scc_set_param()
1308 case PARAM_SLOTTIME: scc->kiss.slottime=arg; break; in scc_set_param()
1309 case PARAM_TXTAIL: scc->kiss.tailtime=arg; break; in scc_set_param()
1310 case PARAM_FULLDUP: scc->kiss.fulldup=arg; break; in scc_set_param()
1312 case PARAM_GROUP: scc->kiss.group=arg; break; in scc_set_param()
1313 case PARAM_IDLE: scc->kiss.idletime=arg; break; in scc_set_param()
1314 case PARAM_MIN: scc->kiss.mintime=arg; break; in scc_set_param()
1315 case PARAM_MAXKEY: scc->kiss.maxkeyup=arg; break; in scc_set_param()
1316 case PARAM_WAIT: scc->kiss.waittime=arg; break; in scc_set_param()
1317 case PARAM_MAXDEFER: scc->kiss.maxdefer=arg; break; in scc_set_param()
1318 case PARAM_TX: scc->kiss.tx_inhibit=arg; break; in scc_set_param()
1321 scc->kiss.softdcd=arg; in scc_set_param()
1335 scc->modem.speed=arg*100; in scc_set_param()
1337 scc->modem.speed=arg; in scc_set_param()
1339 if (scc->stat.tx_state == 0) /* only switch baudrate on rx... ;-) */ in scc_set_param()
1344 if ( !(scc->wreg[R5] & RTS) ) in scc_set_param()
1348 scc_start_tx_timer(scc, t_txdelay, scc->kiss.txdelay); in scc_set_param()
1353 scc->stat.tx_state = TXS_BUSY; in scc_set_param()
1354 scc_start_tx_timer(scc, t_tail, scc->kiss.tailtime); in scc_set_param()
1360 scc_notify(scc, scc->dcd? HWEV_DCD_ON:HWEV_DCD_OFF); in scc_set_param()
1363 default: return -EINVAL; in scc_set_param()
1375 case PARAM_TXDELAY: return CAST(scc->kiss.txdelay); in scc_get_param()
1376 case PARAM_PERSIST: return CAST(scc->kiss.persist); in scc_get_param()
1377 case PARAM_SLOTTIME: return CAST(scc->kiss.slottime); in scc_get_param()
1378 case PARAM_TXTAIL: return CAST(scc->kiss.tailtime); in scc_get_param()
1379 case PARAM_FULLDUP: return CAST(scc->kiss.fulldup); in scc_get_param()
1380 case PARAM_SOFTDCD: return CAST(scc->kiss.softdcd); in scc_get_param()
1381 case PARAM_DTR: return CAST((scc->wreg[R5] & DTR)? 1:0); in scc_get_param()
1382 case PARAM_RTS: return CAST((scc->wreg[R5] & RTS)? 1:0); in scc_get_param()
1383 case PARAM_SPEED: return CAST(scc->modem.speed); in scc_get_param()
1384 case PARAM_GROUP: return CAST(scc->kiss.group); in scc_get_param()
1385 case PARAM_IDLE: return CAST(scc->kiss.idletime); in scc_get_param()
1386 case PARAM_MIN: return CAST(scc->kiss.mintime); in scc_get_param()
1387 case PARAM_MAXKEY: return CAST(scc->kiss.maxkeyup); in scc_get_param()
1388 case PARAM_WAIT: return CAST(scc->kiss.waittime); in scc_get_param()
1389 case PARAM_MAXDEFER: return CAST(scc->kiss.maxdefer); in scc_get_param()
1390 case PARAM_TX: return CAST(scc->kiss.tx_inhibit); in scc_get_param()
1407 spin_lock_irqsave(&scc->lock, flags); in scc_stop_calibrate()
1408 del_timer(&scc->tx_wdog); in scc_stop_calibrate()
1412 Outb(scc->ctrl,RES_EXT_INT); /* reset ext/status interrupts */ in scc_stop_calibrate()
1413 Outb(scc->ctrl,RES_EXT_INT); in scc_stop_calibrate()
1415 netif_wake_queue(scc->dev); in scc_stop_calibrate()
1416 spin_unlock_irqrestore(&scc->lock, flags); in scc_stop_calibrate()
1425 spin_lock_irqsave(&scc->lock, flags); in scc_start_calibrate()
1426 netif_stop_queue(scc->dev); in scc_start_calibrate()
1429 del_timer(&scc->tx_wdog); in scc_start_calibrate()
1431 scc->tx_wdog.function = scc_stop_calibrate; in scc_start_calibrate()
1432 scc->tx_wdog.expires = jiffies + HZ*duration; in scc_start_calibrate()
1433 add_timer(&scc->tx_wdog); in scc_start_calibrate()
1444 Outb(scc->ctrl,RES_EXT_INT); /* reset ext/status interrupts */ in scc_start_calibrate()
1445 Outb(scc->ctrl,RES_EXT_INT); in scc_start_calibrate()
1448 spin_unlock_irqrestore(&scc->lock, flags); in scc_start_calibrate()
1452 /* * Init channel structures, special HW, etc... * */
1467 printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2); in z8530_init()
1479 /* reset and pre-init all chips in the system */ in z8530_init()
1483 if (!scc->ctrl) continue; in z8530_init()
1487 if(scc->brand & EAGLE) /* this is an EAGLE card */ in z8530_init()
1488 Outb(scc->special,0x08); /* enable interrupt on the board */ in z8530_init()
1490 if(scc->brand & (PC100 | PRIMUS)) /* this is a PC100/PRIMUS card */ in z8530_init()
1491 Outb(scc->special,scc->option); /* set the MODEM mode (0x22) */ in z8530_init()
1494 /* Reset and pre-init Z8530 */ in z8530_init()
1496 spin_lock_irqsave(&scc->lock, flags); in z8530_init()
1498 Outb(scc->ctrl, 0); in z8530_init()
1499 OutReg(scc->ctrl,R9,FHWRES); /* force hardware reset */ in z8530_init()
1503 spin_unlock_irqrestore(&scc->lock, flags); in z8530_init()
1521 return -ENOMEM; in scc_net_alloc()
1523 dev->ml_priv = scc; in scc_net_alloc()
1524 scc->dev = dev; in scc_net_alloc()
1525 spin_lock_init(&scc->lock); in scc_net_alloc()
1526 timer_setup(&scc->tx_t, NULL, 0); in scc_net_alloc()
1527 timer_setup(&scc->tx_wdog, NULL, 0); in scc_net_alloc()
1534 scc->dev = NULL; in scc_net_alloc()
1556 /* ----> Initialize device <----- */
1560 dev->tx_queue_len = 16; /* should be enough... */ in scc_net_setup()
1562 dev->netdev_ops = &scc_netdev_ops; in scc_net_setup()
1563 dev->header_ops = &ax25_header_ops; in scc_net_setup()
1565 memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN); in scc_net_setup()
1566 memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN); in scc_net_setup()
1568 dev->flags = 0; in scc_net_setup()
1570 dev->type = ARPHRD_AX25; in scc_net_setup()
1571 dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; in scc_net_setup()
1572 dev->mtu = AX25_DEF_PACLEN; in scc_net_setup()
1573 dev->addr_len = AX25_ADDR_LEN; in scc_net_setup()
1577 /* ----> open network device <---- */
1581 struct scc_channel *scc = (struct scc_channel *) dev->ml_priv; in scc_net_open()
1583 if (!scc->init) in scc_net_open()
1584 return -EINVAL; in scc_net_open()
1586 scc->tx_buff = NULL; in scc_net_open()
1587 skb_queue_head_init(&scc->tx_queue); in scc_net_open()
1595 /* ----> close network device <---- */
1599 struct scc_channel *scc = (struct scc_channel *) dev->ml_priv; in scc_net_close()
1604 spin_lock_irqsave(&scc->lock, flags); in scc_net_close()
1605 Outb(scc->ctrl,0); /* Make sure pointer is written */ in scc_net_close()
1608 spin_unlock_irqrestore(&scc->lock, flags); in scc_net_close()
1610 del_timer_sync(&scc->tx_t); in scc_net_close()
1611 del_timer_sync(&scc->tx_wdog); in scc_net_close()
1618 /* ----> receive frame, called from scc_rxint() <---- */
1622 if (skb->len == 0) { in scc_net_rx()
1627 scc->dev_stat.rx_packets++; in scc_net_rx()
1628 scc->dev_stat.rx_bytes += skb->len; in scc_net_rx()
1630 skb->protocol = ax25_type_trans(skb, scc->dev); in scc_net_rx()
1635 /* ----> transmit frame <---- */
1639 struct scc_channel *scc = (struct scc_channel *) dev->ml_priv; in scc_net_tx()
1643 if (skb->protocol == htons(ETH_P_IP)) in scc_net_tx()
1646 if (skb->len > scc->stat.bufsize || skb->len < 2) { in scc_net_tx()
1647 scc->dev_stat.tx_dropped++; /* bogus frame */ in scc_net_tx()
1652 scc->dev_stat.tx_packets++; in scc_net_tx()
1653 scc->dev_stat.tx_bytes += skb->len; in scc_net_tx()
1654 scc->stat.txframes++; in scc_net_tx()
1656 kisscmd = *skb->data & 0x1f; in scc_net_tx()
1660 scc_set_param(scc, kisscmd, *skb->data); in scc_net_tx()
1665 spin_lock_irqsave(&scc->lock, flags); in scc_net_tx()
1667 if (skb_queue_len(&scc->tx_queue) > scc->dev->tx_queue_len) { in scc_net_tx()
1669 skb_del = skb_dequeue(&scc->tx_queue); in scc_net_tx()
1672 skb_queue_tail(&scc->tx_queue, skb); in scc_net_tx()
1682 if(scc->stat.tx_state == TXS_IDLE || scc->stat.tx_state == TXS_IDLE2) { in scc_net_tx()
1683 scc->stat.tx_state = TXS_BUSY; in scc_net_tx()
1684 if (scc->kiss.fulldup == KISS_DUPLEX_HALF) in scc_net_tx()
1685 __scc_start_tx_timer(scc, t_dwait, scc->kiss.waittime); in scc_net_tx()
1689 spin_unlock_irqrestore(&scc->lock, flags); in scc_net_tx()
1693 /* ----> ioctl functions <---- */
1696 * SIOCSCCCFG - configure driver arg: (struct scc_hw_config *) arg
1697 * SIOCSCCINI - initialize driver arg: ---
1698 * SIOCSCCCHANINI - initialize channel arg: (struct scc_modem *) arg
1699 * SIOCSCCSMEM - set memory arg: (struct scc_mem_config *) arg
1700 * SIOCSCCGKISS - get level 1 parameter arg: (struct scc_kiss_cmd *) arg
1701 * SIOCSCCSKISS - set level 1 parameter arg: (struct scc_kiss_cmd *) arg
1702 * SIOCSCCGSTAT - get driver status arg: (struct scc_stat *) arg
1703 * SIOCSCCCAL - send calib. pattern arg: (struct scc_calibrate *) arg
1712 struct scc_channel *scc = (struct scc_channel *) dev->ml_priv; in scc_net_ioctl()
1715 void __user *arg = ifr->ifr_data; in scc_net_ioctl()
1724 if (!capable(CAP_SYS_RAWIO)) return -EPERM; in scc_net_ioctl()
1725 if (!arg) return -EFAULT; in scc_net_ioctl()
1728 return -EINVAL; in scc_net_ioctl()
1731 return -EFAULT; in scc_net_ioctl()
1736 return -EINVAL; in scc_net_ioctl()
1760 if(request_region(hwcfg.ctrl_a, 1, "scc-probe")) in scc_net_ioctl()
1810 printk(KERN_INFO "%s: data port = 0x%3.3lx control port = 0x%3.3lx -- %s\n", in scc_net_ioctl()
1824 return -EINVAL; in scc_net_ioctl()
1836 return -EPERM; in scc_net_ioctl()
1839 return -EINVAL; in scc_net_ioctl()
1845 return -EINVAL; /* confuse the user */ in scc_net_ioctl()
1848 if (!scc->init) in scc_net_ioctl()
1852 if (!capable(CAP_NET_ADMIN)) return -EPERM; in scc_net_ioctl()
1853 if (!arg) return -EINVAL; in scc_net_ioctl()
1855 scc->stat.bufsize = SCC_BUFSIZE; in scc_net_ioctl()
1857 if (copy_from_user(&scc->modem, arg, sizeof(struct scc_modem))) in scc_net_ioctl()
1858 return -EINVAL; in scc_net_ioctl()
1862 if (scc->modem.speed < 4800) in scc_net_ioctl()
1864 scc->kiss.txdelay = 36; /* 360 ms */ in scc_net_ioctl()
1865 scc->kiss.persist = 42; /* 25% persistence */ /* was 25 */ in scc_net_ioctl()
1866 scc->kiss.slottime = 16; /* 160 ms */ in scc_net_ioctl()
1867 scc->kiss.tailtime = 4; /* minimal reasonable value */ in scc_net_ioctl()
1868 scc->kiss.fulldup = 0; /* CSMA */ in scc_net_ioctl()
1869 scc->kiss.waittime = 50; /* 500 ms */ in scc_net_ioctl()
1870 scc->kiss.maxkeyup = 10; /* 10 s */ in scc_net_ioctl()
1871 scc->kiss.mintime = 3; /* 3 s */ in scc_net_ioctl()
1872 scc->kiss.idletime = 30; /* 30 s */ in scc_net_ioctl()
1873 scc->kiss.maxdefer = 120; /* 2 min */ in scc_net_ioctl()
1874 scc->kiss.softdcd = 0; /* hardware dcd */ in scc_net_ioctl()
1876 scc->kiss.txdelay = 10; /* 100 ms */ in scc_net_ioctl()
1877 scc->kiss.persist = 64; /* 25% persistence */ /* was 25 */ in scc_net_ioctl()
1878 scc->kiss.slottime = 8; /* 160 ms */ in scc_net_ioctl()
1879 scc->kiss.tailtime = 1; /* minimal reasonable value */ in scc_net_ioctl()
1880 scc->kiss.fulldup = 0; /* CSMA */ in scc_net_ioctl()
1881 scc->kiss.waittime = 50; /* 500 ms */ in scc_net_ioctl()
1882 scc->kiss.maxkeyup = 7; /* 7 s */ in scc_net_ioctl()
1883 scc->kiss.mintime = 3; /* 3 s */ in scc_net_ioctl()
1884 scc->kiss.idletime = 30; /* 30 s */ in scc_net_ioctl()
1885 scc->kiss.maxdefer = 120; /* 2 min */ in scc_net_ioctl()
1886 scc->kiss.softdcd = 0; /* hardware dcd */ in scc_net_ioctl()
1889 scc->tx_buff = NULL; in scc_net_ioctl()
1890 skb_queue_head_init(&scc->tx_queue); in scc_net_ioctl()
1891 scc->init = 1; in scc_net_ioctl()
1896 return -EINVAL; in scc_net_ioctl()
1902 return -ENOIOCTLCMD; in scc_net_ioctl()
1905 if (!capable(CAP_SYS_RAWIO)) return -EPERM; in scc_net_ioctl()
1907 return -EINVAL; in scc_net_ioctl()
1908 scc->stat.bufsize = memcfg.bufsize; in scc_net_ioctl()
1912 if (!arg || copy_to_user(arg, &scc->stat, sizeof(scc->stat))) in scc_net_ioctl()
1913 return -EINVAL; in scc_net_ioctl()
1918 return -EINVAL; in scc_net_ioctl()
1921 return -EINVAL; in scc_net_ioctl()
1925 if (!capable(CAP_NET_ADMIN)) return -EPERM; in scc_net_ioctl()
1927 return -EINVAL; in scc_net_ioctl()
1931 if (!capable(CAP_SYS_RAWIO)) return -EPERM; in scc_net_ioctl()
1933 return -EINVAL; in scc_net_ioctl()
1939 return -ENOIOCTLCMD; in scc_net_ioctl()
1943 return -EINVAL; in scc_net_ioctl()
1946 /* ----> set interface callsign <---- */
1951 memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); in scc_net_set_mac_address()
1955 /* ----> get statistics <---- */
1959 struct scc_channel *scc = (struct scc_channel *) dev->ml_priv; in scc_net_get_stats()
1961 scc->dev_stat.rx_errors = scc->stat.rxerrs + scc->stat.rx_over; in scc_net_get_stats()
1962 scc->dev_stat.tx_errors = scc->stat.txerrs + scc->stat.tx_under; in scc_net_get_stats()
1963 scc->dev_stat.rx_fifo_errors = scc->stat.rx_over; in scc_net_get_stats()
1964 scc->dev_stat.tx_fifo_errors = scc->stat.tx_under; in scc_net_get_stats()
1966 return &scc->dev_stat; in scc_net_get_stats()
1980 if (!SCC_Info[k].init) in scc_net_seq_idx()
1982 if (pos-- == 0) in scc_net_seq_idx()
1990 return *pos ? scc_net_seq_idx(*pos - 1) : SEQ_START_TOKEN; in scc_net_seq_start()
2000 for (k = (v == SEQ_START_TOKEN) ? 0 : (scc - SCC_Info)+1; in scc_net_seq_next()
2002 if (SCC_Info[k].init) in scc_net_seq_next()
2015 seq_puts(seq, "z8530drv-"VERSION"\n"); in scc_net_seq_show()
2022 const struct scc_stat *stat = &scc->stat; in scc_net_seq_show()
2023 const struct scc_kiss *kiss = &scc->kiss; in scc_net_seq_show()
2036 scc->dev->name, in scc_net_seq_show()
2037 scc->data, scc->ctrl, scc->irq, scc->clock, scc->brand, in scc_net_seq_show()
2038 scc->enhanced, Vector_Latch, scc->special, in scc_net_seq_show()
2039 scc->option); in scc_net_seq_show()
2041 scc->modem.speed, scc->modem.nrz, in scc_net_seq_show()
2042 scc->modem.clocksrc, kiss->softdcd, in scc_net_seq_show()
2043 stat->bufsize); in scc_net_seq_show()
2045 stat->rxints, stat->txints, stat->exints, stat->spints); in scc_net_seq_show()
2047 stat->rxframes, stat->rxerrs, stat->rx_over, in scc_net_seq_show()
2048 stat->txframes, stat->txerrs, stat->tx_under, in scc_net_seq_show()
2049 stat->nospace, stat->tx_state); in scc_net_seq_show()
2051 #define K(x) kiss->x in scc_net_seq_show()
2063 seq_printf(seq, "%2.2x ", scc->wreg[reg]); in scc_net_seq_show()
2066 seq_printf(seq, "\tR %2.2x %2.2x XX ", InReg(scc->ctrl,R0), InReg(scc->ctrl,R1)); in scc_net_seq_show()
2068 seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg)); in scc_net_seq_show()
2071 seq_printf(seq, "%2.2x ", InReg(scc->ctrl, reg)); in scc_net_seq_show()
2091 /* * Init SCC driver * */
2106 return -EIO; in scc_init_driver()
2149 if (scc->ctrl) in scc_cleanup_driver()
2151 release_region(scc->ctrl, 1); in scc_cleanup_driver()
2152 release_region(scc->data, 1); in scc_cleanup_driver()
2154 if (scc->dev) in scc_cleanup_driver()
2156 unregister_netdev(scc->dev); in scc_cleanup_driver()
2157 free_netdev(scc->dev); in scc_cleanup_driver()