X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fhamradio%2Fbaycom_epp.c;h=153b6dc80af4c38bebcca28a4cf8afc6a4209124;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=b3f64f722cc7ad284ebb3f22f7ac396b70a8b8a8;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index b3f64f722..153b6dc80 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -40,7 +40,7 @@ /*****************************************************************************/ -#include +#include #include #include #include @@ -48,17 +48,12 @@ #include #include #include -#include -#include #include -#include #include #include -#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) -/* prototypes for ax25_encapsulate and ax25_rebuild_header */ +#include #include -#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */ -#include +#include /* --------------------------------------------------------------------- */ @@ -68,25 +63,7 @@ /* --------------------------------------------------------------------- */ static const char paranoia_str[] = KERN_ERR -"baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n"; - -#define baycom_paranoia_check(dev,routine,retval) \ -({ \ - if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \ - printk(paranoia_str, routine); \ - return retval; \ - } \ -}) - -#define baycom_paranoia_check_void(dev,routine) \ -({ \ - if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \ - printk(paranoia_str, routine); \ - return; \ - } \ -}) - -/* --------------------------------------------------------------------- */ + "baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n"; static const char bc_drvname[] = "baycom_epp"; static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n" @@ -191,8 +168,9 @@ struct baycom_state { int magic; struct pardevice *pdev; + struct net_device *dev; unsigned int work_running; - struct work_struct run_work; + struct delayed_work run_work; unsigned int modem; unsigned int bitrate; unsigned char stat; @@ -305,7 +283,7 @@ static inline void baycom_int_freq(struct baycom_state *bc) * measure the interrupt frequency */ bc->debug_vals.cur_intcnt++; - if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) { + if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) { bc->debug_vals.last_jiffies = cur_jiffies; bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; bc->debug_vals.cur_intcnt = 0; @@ -346,7 +324,7 @@ static int eppconfig(struct baycom_state *bc) /* ---------------------------------------------------------------------- */ -static void epp_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void epp_interrupt(int irq, void *dev_id) { } @@ -392,29 +370,6 @@ static inline void do_kiss_params(struct baycom_state *bc, } /* --------------------------------------------------------------------- */ -/* - * high performance HDLC encoder - * yes, it's ugly, but generates pretty good code - */ - -#define ENCODEITERA(j) \ -({ \ - if (!(notbitstream & (0x1f0 << j))) \ - goto stuff##j; \ - encodeend##j: ; \ -}) - -#define ENCODEITERB(j) \ -({ \ - stuff##j: \ - bitstream &= ~(0x100 << j); \ - bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | \ - ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); \ - numbit++; \ - notbitstream = ~bitstream; \ - goto encodeend##j; \ -}) - static void encode_hdlc(struct baycom_state *bc) { @@ -423,6 +378,7 @@ static void encode_hdlc(struct baycom_state *bc) int pkt_len; unsigned bitstream, notbitstream, bitbuf, numbit, crc; unsigned char crcarr[2]; + int j; if (bc->hdlctx.bufcnt > 0) return; @@ -447,24 +403,14 @@ static void encode_hdlc(struct baycom_state *bc) pkt_len--; if (!pkt_len) bp = crcarr; - ENCODEITERA(0); - ENCODEITERA(1); - ENCODEITERA(2); - ENCODEITERA(3); - ENCODEITERA(4); - ENCODEITERA(5); - ENCODEITERA(6); - ENCODEITERA(7); - goto enditer; - ENCODEITERB(0); - ENCODEITERB(1); - ENCODEITERB(2); - ENCODEITERB(3); - ENCODEITERB(4); - ENCODEITERB(5); - ENCODEITERB(6); - ENCODEITERB(7); - enditer: + for (j = 0; j < 8; j++) + if (unlikely(!(notbitstream & (0x1f0 << j)))) { + bitstream &= ~(0x100 << j); + bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | + ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); + numbit++; + notbitstream = ~bitstream; + } numbit += 8; while (numbit >= 8) { *wp++ = bitbuf; @@ -619,48 +565,15 @@ static void do_rxpacket(struct net_device *dev) bc->stats.rx_dropped++; return; } - skb->dev = dev; cp = skb_put(skb, pktlen); *cp++ = 0; /* KISS kludge */ memcpy(cp, bc->hdlcrx.buf, pktlen - 1); - skb->protocol = htons(ETH_P_AX25); - skb->mac.raw = skb->data; + skb->protocol = ax25_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; bc->stats.rx_packets++; } -#define DECODEITERA(j) \ -({ \ - if (!(notbitstream & (0x0fc << j))) /* flag or abort */ \ - goto flgabrt##j; \ - if ((bitstream & (0x1f8 << j)) == (0xf8 << j)) /* stuffed bit */ \ - goto stuff##j; \ - enditer##j: ; \ -}) - -#define DECODEITERB(j) \ -({ \ - flgabrt##j: \ - if (!(notbitstream & (0x1fc << j))) { /* abort received */ \ - state = 0; \ - goto enditer##j; \ - } \ - if ((bitstream & (0x1fe << j)) != (0x0fc << j)) /* flag received */ \ - goto enditer##j; \ - if (state) \ - do_rxpacket(dev); \ - bc->hdlcrx.bufcnt = 0; \ - bc->hdlcrx.bufptr = bc->hdlcrx.buf; \ - state = 1; \ - numbits = 7-j; \ - goto enditer##j; \ - stuff##j: \ - numbits--; \ - bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); \ - goto enditer##j; \ -}) - static int receive(struct net_device *dev, int cnt) { struct baycom_state *bc = netdev_priv(dev); @@ -669,6 +582,7 @@ static int receive(struct net_device *dev, int cnt) unsigned char tmp[128]; unsigned char *cp; int cnt2, ret = 0; + int j; numbits = bc->hdlcrx.numbits; state = bc->hdlcrx.state; @@ -689,24 +603,32 @@ static int receive(struct net_device *dev, int cnt) bitbuf |= (*cp) << 8; numbits += 8; notbitstream = ~bitstream; - DECODEITERA(0); - DECODEITERA(1); - DECODEITERA(2); - DECODEITERA(3); - DECODEITERA(4); - DECODEITERA(5); - DECODEITERA(6); - DECODEITERA(7); - goto enddec; - DECODEITERB(0); - DECODEITERB(1); - DECODEITERB(2); - DECODEITERB(3); - DECODEITERB(4); - DECODEITERB(5); - DECODEITERB(6); - DECODEITERB(7); - enddec: + for (j = 0; j < 8; j++) { + + /* flag or abort */ + if (unlikely(!(notbitstream & (0x0fc << j)))) { + + /* abort received */ + if (!(notbitstream & (0x1fc << j))) + state = 0; + + /* not flag received */ + else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) { + if (state) + do_rxpacket(dev); + bc->hdlcrx.bufcnt = 0; + bc->hdlcrx.bufptr = bc->hdlcrx.buf; + state = 1; + numbits = 7-j; + } + } + + /* stuffed bit */ + else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) { + numbits--; + bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); + } + } while (state && numbits >= 8) { if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) { state = 0; @@ -738,17 +660,18 @@ static int receive(struct net_device *dev, int cnt) #define GETTICK(x) #endif /* __i386__ */ -static void epp_bh(struct net_device *dev) +static void epp_bh(struct work_struct *work) { + struct net_device *dev; struct baycom_state *bc; struct parport *pp; unsigned char stat; unsigned char tmp[2]; unsigned int time1 = 0, time2 = 0, time3 = 0; int cnt, cnt2; - - baycom_paranoia_check_void(dev, "epp_bh"); - bc = netdev_priv(dev); + + bc = container_of(work, struct baycom_state, run_work.work); + dev = bc->dev; if (!bc->work_running) return; baycom_int_freq(bc); @@ -863,10 +786,8 @@ static void epp_bh(struct net_device *dev) static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct baycom_state *bc; + struct baycom_state *bc = netdev_priv(dev); - baycom_paranoia_check(dev, "baycom_send_packet", 0); - bc = netdev_priv(dev); if (skb->data[0] != 0) { do_kiss_params(bc, skb->data, skb->len); dev_kfree_skb(skb); @@ -899,10 +820,8 @@ static int baycom_set_mac_address(struct net_device *dev, void *addr) static struct net_device_stats *baycom_get_stats(struct net_device *dev) { - struct baycom_state *bc; + struct baycom_state *bc = netdev_priv(dev); - baycom_paranoia_check(dev, "baycom_get_stats", NULL); - bc = netdev_priv(dev); /* * Get the current statistics. This may be called with the * card open or closed. @@ -915,10 +834,8 @@ static struct net_device_stats *baycom_get_stats(struct net_device *dev) static void epp_wakeup(void *handle) { struct net_device *dev = (struct net_device *)handle; - struct baycom_state *bc; + struct baycom_state *bc = netdev_priv(dev); - baycom_paranoia_check_void(dev, "epp_wakeup"); - bc = netdev_priv(dev); printk(KERN_DEBUG "baycom_epp: %s: why am I being woken up?\n", dev->name); if (!parport_claim(bc->pdev)) printk(KERN_DEBUG "baycom_epp: %s: I'm broken.\n", dev->name); @@ -937,16 +854,13 @@ static void epp_wakeup(void *handle) static int epp_open(struct net_device *dev) { - struct baycom_state *bc; - struct parport *pp; + struct baycom_state *bc = netdev_priv(dev); + struct parport *pp = parport_find_base(dev->base_addr); unsigned int i, j; unsigned char tmp[128]; unsigned char stat; unsigned long tstart; - baycom_paranoia_check(dev, "epp_open", -ENXIO); - bc = netdev_priv(dev); - pp = parport_find_base(dev->base_addr); if (!pp) { printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr); return -ENXIO; @@ -978,7 +892,7 @@ static int epp_open(struct net_device *dev) return -EBUSY; } dev->irq = /*pp->irq*/ 0; - INIT_WORK(&bc->run_work, (void *)(void *)epp_bh, dev); + INIT_DELAYED_WORK(&bc->run_work, epp_bh); bc->work_running = 1; bc->modem = EPP_CONVENTIONAL; if (eppconfig(bc)) @@ -994,7 +908,7 @@ static int epp_open(struct net_device *dev) /* autoprobe baud rate */ tstart = jiffies; i = 0; - while ((signed)(jiffies-tstart-HZ/3) < 0) { + while (time_before(jiffies, tstart + HZ/3)) { if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1) goto epptimeout; if ((stat & (EPP_NRAEF|EPP_NRHF)) == EPP_NRHF) { @@ -1055,13 +969,10 @@ static int epp_open(struct net_device *dev) static int epp_close(struct net_device *dev) { - struct baycom_state *bc; - struct parport *pp; + struct baycom_state *bc = netdev_priv(dev); + struct parport *pp = bc->pdev->port; unsigned char tmp[1]; - baycom_paranoia_check(dev, "epp_close", -EINVAL); - bc = netdev_priv(dev); - pp = bc->pdev->port; bc->work_running = 0; flush_scheduled_work(); bc->stat = EPP_DCDBIT; @@ -1117,11 +1028,9 @@ static int baycom_setmode(struct baycom_state *bc, const char *modestr) static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct baycom_state *bc; + struct baycom_state *bc = netdev_priv(dev); struct hdlcdrv_ioctl hi; - baycom_paranoia_check(dev, "baycom_ioctl", -EINVAL); - bc = netdev_priv(dev); if (cmd != SIOCDEVPRIVATE) return -ENOIOCTLCMD; @@ -1232,12 +1141,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) */ static void baycom_probe(struct net_device *dev) { - static char ax25_bcast[AX25_ADDR_LEN] = { - 'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1 - }; - static char ax25_nocall[AX25_ADDR_LEN] = { - 'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1 - }; const struct hdlcdrv_channel_params dflt_ch_params = { 20, 2, 10, 40, 0 }; @@ -1265,21 +1168,16 @@ static void baycom_probe(struct net_device *dev) /* Fill in the fields of the device structure */ bc->skb = NULL; -#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) - dev->hard_header = ax25_encapsulate; + dev->hard_header = ax25_hard_header; dev->rebuild_header = ax25_rebuild_header; -#else /* CONFIG_AX25 || CONFIG_AX25_MODULE */ - dev->hard_header = NULL; - dev->rebuild_header = NULL; -#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */ dev->set_mac_address = baycom_set_mac_address; dev->type = ARPHRD_AX25; /* AF_AX25 device */ dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN; dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */ dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */ - memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); - memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN); + memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN); + memcpy(dev->dev_addr, &null_ax25_address, AX25_ADDR_LEN); dev->tx_queue_len = 16; /* New style flags */ @@ -1294,9 +1192,9 @@ static void baycom_probe(struct net_device *dev) static const char *mode[NR_PORTS] = { "", }; static int iobase[NR_PORTS] = { 0x378, }; -MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s"); +module_param_array(mode, charp, NULL, 0); MODULE_PARM_DESC(mode, "baycom operating mode"); -MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i"); +module_param_array(iobase, int, NULL, 0); MODULE_PARM_DESC(iobase, "baycom io base address"); MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); @@ -1312,6 +1210,7 @@ static void __init baycom_epp_dev_setup(struct net_device *dev) /* * initialize part of the baycom_state struct */ + bc->dev = dev; bc->magic = BAYCOM_MAGIC; bc->cfg.fclk = 19666600; bc->cfg.bps = 9600; @@ -1354,7 +1253,7 @@ static int __init init_baycomepp(void) free_netdev(dev); break; } - if (set_hw && baycom_setmode(dev->priv, mode[i])) + if (set_hw && baycom_setmode(netdev_priv(dev), mode[i])) set_hw = 0; baycom_device[i] = dev; found++;