0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <linux/capability.h>
0033 #include <linux/compat.h>
0034 #include <linux/module.h>
0035 #include <linux/types.h>
0036 #include <linux/net.h>
0037 #include <linux/in.h>
0038 #include <linux/if.h>
0039 #include <linux/errno.h>
0040 #include <linux/init.h>
0041 #include <linux/bitops.h>
0042
0043 #include <linux/netdevice.h>
0044 #include <linux/if_arp.h>
0045 #include <linux/skbuff.h>
0046 #include <linux/hdlcdrv.h>
0047 #include <linux/random.h>
0048 #include <net/ax25.h>
0049 #include <linux/uaccess.h>
0050
0051 #include <linux/crc-ccitt.h>
0052
0053
0054
0055 #define KISS_VERBOSE
0056
0057
0058
0059 #define PARAM_TXDELAY 1
0060 #define PARAM_PERSIST 2
0061 #define PARAM_SLOTTIME 3
0062 #define PARAM_TXTAIL 4
0063 #define PARAM_FULLDUP 5
0064 #define PARAM_HARDWARE 6
0065 #define PARAM_RETURN 255
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 static inline void append_crc_ccitt(unsigned char *buffer, int len)
0077 {
0078 unsigned int crc = crc_ccitt(0xffff, buffer, len) ^ 0xffff;
0079 buffer += len;
0080 *buffer++ = crc;
0081 *buffer++ = crc >> 8;
0082 }
0083
0084
0085
0086 static inline int check_crc_ccitt(const unsigned char *buf, int cnt)
0087 {
0088 return (crc_ccitt(0xffff, buf, cnt) & 0xffff) == 0xf0b8;
0089 }
0090
0091
0092
0093 #if 0
0094 static int calc_crc_ccitt(const unsigned char *buf, int cnt)
0095 {
0096 unsigned int crc = 0xffff;
0097
0098 for (; cnt > 0; cnt--)
0099 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
0100 crc ^= 0xffff;
0101 return crc & 0xffff;
0102 }
0103 #endif
0104
0105
0106
0107 #define tenms_to_2flags(s,tenms) ((tenms * s->par.bitrate) / 100 / 16)
0108
0109
0110
0111
0112
0113
0114 static int hdlc_rx_add_bytes(struct hdlcdrv_state *s, unsigned int bits,
0115 int num)
0116 {
0117 int added = 0;
0118
0119 while (s->hdlcrx.rx_state && num >= 8) {
0120 if (s->hdlcrx.len >= sizeof(s->hdlcrx.buffer)) {
0121 s->hdlcrx.rx_state = 0;
0122 return 0;
0123 }
0124 *s->hdlcrx.bp++ = bits >> (32-num);
0125 s->hdlcrx.len++;
0126 num -= 8;
0127 added += 8;
0128 }
0129 return added;
0130 }
0131
0132 static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
0133 {
0134 struct sk_buff *skb;
0135 int pkt_len;
0136 unsigned char *cp;
0137
0138 if (s->hdlcrx.len < 4)
0139 return;
0140 if (!check_crc_ccitt(s->hdlcrx.buffer, s->hdlcrx.len))
0141 return;
0142 pkt_len = s->hdlcrx.len - 2 + 1;
0143 if (!(skb = dev_alloc_skb(pkt_len))) {
0144 printk("%s: memory squeeze, dropping packet\n", dev->name);
0145 dev->stats.rx_dropped++;
0146 return;
0147 }
0148 cp = skb_put(skb, pkt_len);
0149 *cp++ = 0;
0150 memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
0151 skb->protocol = ax25_type_trans(skb, dev);
0152 netif_rx(skb);
0153 dev->stats.rx_packets++;
0154 }
0155
0156 void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s)
0157 {
0158 int i;
0159 unsigned int mask1, mask2, mask3, mask4, mask5, mask6, word;
0160
0161 if (!s || s->magic != HDLCDRV_MAGIC)
0162 return;
0163 if (test_and_set_bit(0, &s->hdlcrx.in_hdlc_rx))
0164 return;
0165
0166 while (!hdlcdrv_hbuf_empty(&s->hdlcrx.hbuf)) {
0167 word = hdlcdrv_hbuf_get(&s->hdlcrx.hbuf);
0168
0169 #ifdef HDLCDRV_DEBUG
0170 hdlcdrv_add_bitbuffer_word(&s->bitbuf_hdlc, word);
0171 #endif
0172 s->hdlcrx.bitstream >>= 16;
0173 s->hdlcrx.bitstream |= word << 16;
0174 s->hdlcrx.bitbuf >>= 16;
0175 s->hdlcrx.bitbuf |= word << 16;
0176 s->hdlcrx.numbits += 16;
0177 for(i = 15, mask1 = 0x1fc00, mask2 = 0x1fe00, mask3 = 0x0fc00,
0178 mask4 = 0x1f800, mask5 = 0xf800, mask6 = 0xffff;
0179 i >= 0;
0180 i--, mask1 <<= 1, mask2 <<= 1, mask3 <<= 1, mask4 <<= 1,
0181 mask5 <<= 1, mask6 = (mask6 << 1) | 1) {
0182 if ((s->hdlcrx.bitstream & mask1) == mask1)
0183 s->hdlcrx.rx_state = 0;
0184 else if ((s->hdlcrx.bitstream & mask2) == mask3) {
0185
0186 if (s->hdlcrx.rx_state) {
0187 hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf
0188 << (8+i),
0189 s->hdlcrx.numbits
0190 -8-i);
0191 hdlc_rx_flag(dev, s);
0192 }
0193 s->hdlcrx.len = 0;
0194 s->hdlcrx.bp = s->hdlcrx.buffer;
0195 s->hdlcrx.rx_state = 1;
0196 s->hdlcrx.numbits = i;
0197 } else if ((s->hdlcrx.bitstream & mask4) == mask5) {
0198
0199 s->hdlcrx.numbits--;
0200 s->hdlcrx.bitbuf = (s->hdlcrx.bitbuf & (~mask6)) |
0201 ((s->hdlcrx.bitbuf & mask6) << 1);
0202 }
0203 }
0204 s->hdlcrx.numbits -= hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf,
0205 s->hdlcrx.numbits);
0206 }
0207 clear_bit(0, &s->hdlcrx.in_hdlc_rx);
0208 }
0209
0210
0211
0212 static inline void do_kiss_params(struct hdlcdrv_state *s,
0213 unsigned char *data, unsigned long len)
0214 {
0215
0216 #ifdef KISS_VERBOSE
0217 #define PKP(a,b) printk(KERN_INFO "hdlcdrv.c: channel params: " a "\n", b)
0218 #else
0219 #define PKP(a,b)
0220 #endif
0221
0222 if (len < 2)
0223 return;
0224 switch(data[0]) {
0225 case PARAM_TXDELAY:
0226 s->ch_params.tx_delay = data[1];
0227 PKP("TX delay = %ums", 10 * s->ch_params.tx_delay);
0228 break;
0229 case PARAM_PERSIST:
0230 s->ch_params.ppersist = data[1];
0231 PKP("p persistence = %u", s->ch_params.ppersist);
0232 break;
0233 case PARAM_SLOTTIME:
0234 s->ch_params.slottime = data[1];
0235 PKP("slot time = %ums", s->ch_params.slottime);
0236 break;
0237 case PARAM_TXTAIL:
0238 s->ch_params.tx_tail = data[1];
0239 PKP("TX tail = %ums", s->ch_params.tx_tail);
0240 break;
0241 case PARAM_FULLDUP:
0242 s->ch_params.fulldup = !!data[1];
0243 PKP("%s duplex", s->ch_params.fulldup ? "full" : "half");
0244 break;
0245 default:
0246 break;
0247 }
0248 #undef PKP
0249 }
0250
0251
0252
0253 void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s)
0254 {
0255 unsigned int mask1, mask2, mask3;
0256 int i;
0257 struct sk_buff *skb;
0258 int pkt_len;
0259
0260 if (!s || s->magic != HDLCDRV_MAGIC)
0261 return;
0262 if (test_and_set_bit(0, &s->hdlctx.in_hdlc_tx))
0263 return;
0264 for (;;) {
0265 if (s->hdlctx.numbits >= 16) {
0266 if (hdlcdrv_hbuf_full(&s->hdlctx.hbuf)) {
0267 clear_bit(0, &s->hdlctx.in_hdlc_tx);
0268 return;
0269 }
0270 hdlcdrv_hbuf_put(&s->hdlctx.hbuf, s->hdlctx.bitbuf);
0271 s->hdlctx.bitbuf >>= 16;
0272 s->hdlctx.numbits -= 16;
0273 }
0274 switch (s->hdlctx.tx_state) {
0275 default:
0276 clear_bit(0, &s->hdlctx.in_hdlc_tx);
0277 return;
0278 case 0:
0279 case 1:
0280 if (s->hdlctx.numflags) {
0281 s->hdlctx.numflags--;
0282 s->hdlctx.bitbuf |=
0283 0x7e7e << s->hdlctx.numbits;
0284 s->hdlctx.numbits += 16;
0285 break;
0286 }
0287 if (s->hdlctx.tx_state == 1) {
0288 clear_bit(0, &s->hdlctx.in_hdlc_tx);
0289 return;
0290 }
0291 if (!(skb = s->skb)) {
0292 int flgs = tenms_to_2flags(s, s->ch_params.tx_tail);
0293 if (flgs < 2)
0294 flgs = 2;
0295 s->hdlctx.tx_state = 1;
0296 s->hdlctx.numflags = flgs;
0297 break;
0298 }
0299 s->skb = NULL;
0300 netif_wake_queue(dev);
0301 pkt_len = skb->len-1;
0302 if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
0303 s->hdlctx.tx_state = 0;
0304 s->hdlctx.numflags = 1;
0305 dev_kfree_skb_irq(skb);
0306 break;
0307 }
0308 skb_copy_from_linear_data_offset(skb, 1,
0309 s->hdlctx.buffer,
0310 pkt_len);
0311 dev_kfree_skb_irq(skb);
0312 s->hdlctx.bp = s->hdlctx.buffer;
0313 append_crc_ccitt(s->hdlctx.buffer, pkt_len);
0314 s->hdlctx.len = pkt_len+2;
0315 s->hdlctx.tx_state = 2;
0316 s->hdlctx.bitstream = 0;
0317 dev->stats.tx_packets++;
0318 break;
0319 case 2:
0320 if (!s->hdlctx.len) {
0321 s->hdlctx.tx_state = 0;
0322 s->hdlctx.numflags = 1;
0323 break;
0324 }
0325 s->hdlctx.len--;
0326 s->hdlctx.bitbuf |= *s->hdlctx.bp <<
0327 s->hdlctx.numbits;
0328 s->hdlctx.bitstream >>= 8;
0329 s->hdlctx.bitstream |= (*s->hdlctx.bp++) << 16;
0330 mask1 = 0x1f000;
0331 mask2 = 0x10000;
0332 mask3 = 0xffffffff >> (31-s->hdlctx.numbits);
0333 s->hdlctx.numbits += 8;
0334 for(i = 0; i < 8; i++, mask1 <<= 1, mask2 <<= 1,
0335 mask3 = (mask3 << 1) | 1) {
0336 if ((s->hdlctx.bitstream & mask1) != mask1)
0337 continue;
0338 s->hdlctx.bitstream &= ~mask2;
0339 s->hdlctx.bitbuf =
0340 (s->hdlctx.bitbuf & mask3) |
0341 ((s->hdlctx.bitbuf &
0342 (~mask3)) << 1);
0343 s->hdlctx.numbits++;
0344 mask3 = (mask3 << 1) | 1;
0345 }
0346 break;
0347 }
0348 }
0349 }
0350
0351
0352
0353 static void start_tx(struct net_device *dev, struct hdlcdrv_state *s)
0354 {
0355 s->hdlctx.tx_state = 0;
0356 s->hdlctx.numflags = tenms_to_2flags(s, s->ch_params.tx_delay);
0357 s->hdlctx.bitbuf = s->hdlctx.bitstream = s->hdlctx.numbits = 0;
0358 hdlcdrv_transmitter(dev, s);
0359 s->hdlctx.ptt = 1;
0360 s->ptt_keyed++;
0361 }
0362
0363
0364
0365 void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
0366 {
0367 if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || !s->skb)
0368 return;
0369 if (s->ch_params.fulldup) {
0370 start_tx(dev, s);
0371 return;
0372 }
0373 if (s->hdlcrx.dcd) {
0374 s->hdlctx.slotcnt = s->ch_params.slottime;
0375 return;
0376 }
0377 if ((--s->hdlctx.slotcnt) > 0)
0378 return;
0379 s->hdlctx.slotcnt = s->ch_params.slottime;
0380 if ((prandom_u32() % 256) > s->ch_params.ppersist)
0381 return;
0382 start_tx(dev, s);
0383 }
0384
0385
0386
0387
0388
0389
0390 static netdev_tx_t hdlcdrv_send_packet(struct sk_buff *skb,
0391 struct net_device *dev)
0392 {
0393 struct hdlcdrv_state *sm = netdev_priv(dev);
0394
0395 if (skb->protocol == htons(ETH_P_IP))
0396 return ax25_ip_xmit(skb);
0397
0398 if (skb->data[0] != 0) {
0399 do_kiss_params(sm, skb->data, skb->len);
0400 dev_kfree_skb(skb);
0401 return NETDEV_TX_OK;
0402 }
0403 if (sm->skb) {
0404 dev_kfree_skb(skb);
0405 return NETDEV_TX_OK;
0406 }
0407 netif_stop_queue(dev);
0408 sm->skb = skb;
0409 return NETDEV_TX_OK;
0410 }
0411
0412
0413
0414 static int hdlcdrv_set_mac_address(struct net_device *dev, void *addr)
0415 {
0416 struct sockaddr *sa = (struct sockaddr *)addr;
0417
0418
0419 dev_addr_set(dev, sa->sa_data);
0420 return 0;
0421 }
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433 static int hdlcdrv_open(struct net_device *dev)
0434 {
0435 struct hdlcdrv_state *s = netdev_priv(dev);
0436 int i;
0437
0438 if (!s->ops || !s->ops->open)
0439 return -ENODEV;
0440
0441
0442
0443
0444 s->opened = 1;
0445 s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
0446 s->hdlcrx.in_hdlc_rx = 0;
0447 s->hdlcrx.rx_state = 0;
0448
0449 s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
0450 s->hdlctx.in_hdlc_tx = 0;
0451 s->hdlctx.tx_state = 1;
0452 s->hdlctx.numflags = 0;
0453 s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
0454 s->hdlctx.ptt = 0;
0455 s->hdlctx.slotcnt = s->ch_params.slottime;
0456 s->hdlctx.calibrate = 0;
0457
0458 i = s->ops->open(dev);
0459 if (i)
0460 return i;
0461 netif_start_queue(dev);
0462 return 0;
0463 }
0464
0465
0466
0467
0468
0469
0470 static int hdlcdrv_close(struct net_device *dev)
0471 {
0472 struct hdlcdrv_state *s = netdev_priv(dev);
0473 int i = 0;
0474
0475 netif_stop_queue(dev);
0476
0477 if (s->ops && s->ops->close)
0478 i = s->ops->close(dev);
0479 dev_kfree_skb(s->skb);
0480 s->skb = NULL;
0481 s->opened = 0;
0482 return i;
0483 }
0484
0485
0486
0487 static int hdlcdrv_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
0488 void __user *data, int cmd)
0489 {
0490 struct hdlcdrv_state *s = netdev_priv(dev);
0491 struct hdlcdrv_ioctl bi;
0492
0493 if (cmd != SIOCDEVPRIVATE)
0494 return -ENOIOCTLCMD;
0495
0496 if (in_compat_syscall())
0497 return -ENOIOCTLCMD;
0498
0499 if (copy_from_user(&bi, data, sizeof(bi)))
0500 return -EFAULT;
0501
0502 switch (bi.cmd) {
0503 default:
0504 if (s->ops && s->ops->ioctl)
0505 return s->ops->ioctl(dev, data, &bi, cmd);
0506 return -ENOIOCTLCMD;
0507
0508 case HDLCDRVCTL_GETCHANNELPAR:
0509 bi.data.cp.tx_delay = s->ch_params.tx_delay;
0510 bi.data.cp.tx_tail = s->ch_params.tx_tail;
0511 bi.data.cp.slottime = s->ch_params.slottime;
0512 bi.data.cp.ppersist = s->ch_params.ppersist;
0513 bi.data.cp.fulldup = s->ch_params.fulldup;
0514 break;
0515
0516 case HDLCDRVCTL_SETCHANNELPAR:
0517 if (!capable(CAP_NET_ADMIN))
0518 return -EACCES;
0519 s->ch_params.tx_delay = bi.data.cp.tx_delay;
0520 s->ch_params.tx_tail = bi.data.cp.tx_tail;
0521 s->ch_params.slottime = bi.data.cp.slottime;
0522 s->ch_params.ppersist = bi.data.cp.ppersist;
0523 s->ch_params.fulldup = bi.data.cp.fulldup;
0524 s->hdlctx.slotcnt = 1;
0525 return 0;
0526
0527 case HDLCDRVCTL_GETMODEMPAR:
0528 bi.data.mp.iobase = dev->base_addr;
0529 bi.data.mp.irq = dev->irq;
0530 bi.data.mp.dma = dev->dma;
0531 bi.data.mp.dma2 = s->ptt_out.dma2;
0532 bi.data.mp.seriobase = s->ptt_out.seriobase;
0533 bi.data.mp.pariobase = s->ptt_out.pariobase;
0534 bi.data.mp.midiiobase = s->ptt_out.midiiobase;
0535 break;
0536
0537 case HDLCDRVCTL_SETMODEMPAR:
0538 if ((!capable(CAP_SYS_RAWIO)) || netif_running(dev))
0539 return -EACCES;
0540 dev->base_addr = bi.data.mp.iobase;
0541 dev->irq = bi.data.mp.irq;
0542 dev->dma = bi.data.mp.dma;
0543 s->ptt_out.dma2 = bi.data.mp.dma2;
0544 s->ptt_out.seriobase = bi.data.mp.seriobase;
0545 s->ptt_out.pariobase = bi.data.mp.pariobase;
0546 s->ptt_out.midiiobase = bi.data.mp.midiiobase;
0547 return 0;
0548
0549 case HDLCDRVCTL_GETSTAT:
0550 bi.data.cs.ptt = hdlcdrv_ptt(s);
0551 bi.data.cs.dcd = s->hdlcrx.dcd;
0552 bi.data.cs.ptt_keyed = s->ptt_keyed;
0553 bi.data.cs.tx_packets = dev->stats.tx_packets;
0554 bi.data.cs.tx_errors = dev->stats.tx_errors;
0555 bi.data.cs.rx_packets = dev->stats.rx_packets;
0556 bi.data.cs.rx_errors = dev->stats.rx_errors;
0557 break;
0558
0559 case HDLCDRVCTL_OLDGETSTAT:
0560 bi.data.ocs.ptt = hdlcdrv_ptt(s);
0561 bi.data.ocs.dcd = s->hdlcrx.dcd;
0562 bi.data.ocs.ptt_keyed = s->ptt_keyed;
0563 break;
0564
0565 case HDLCDRVCTL_CALIBRATE:
0566 if(!capable(CAP_SYS_RAWIO))
0567 return -EPERM;
0568 if (s->par.bitrate <= 0)
0569 return -EINVAL;
0570 if (bi.data.calibrate > INT_MAX / s->par.bitrate)
0571 return -EINVAL;
0572 s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
0573 return 0;
0574
0575 case HDLCDRVCTL_GETSAMPLES:
0576 #ifndef HDLCDRV_DEBUG
0577 return -EPERM;
0578 #else
0579 if (s->bitbuf_channel.rd == s->bitbuf_channel.wr)
0580 return -EAGAIN;
0581 bi.data.bits =
0582 s->bitbuf_channel.buffer[s->bitbuf_channel.rd];
0583 s->bitbuf_channel.rd = (s->bitbuf_channel.rd+1) %
0584 sizeof(s->bitbuf_channel.buffer);
0585 break;
0586 #endif
0587
0588 case HDLCDRVCTL_GETBITS:
0589 #ifndef HDLCDRV_DEBUG
0590 return -EPERM;
0591 #else
0592 if (s->bitbuf_hdlc.rd == s->bitbuf_hdlc.wr)
0593 return -EAGAIN;
0594 bi.data.bits =
0595 s->bitbuf_hdlc.buffer[s->bitbuf_hdlc.rd];
0596 s->bitbuf_hdlc.rd = (s->bitbuf_hdlc.rd+1) %
0597 sizeof(s->bitbuf_hdlc.buffer);
0598 break;
0599 #endif
0600
0601 case HDLCDRVCTL_DRIVERNAME:
0602 if (s->ops && s->ops->drvname) {
0603 strlcpy(bi.data.drivername, s->ops->drvname,
0604 sizeof(bi.data.drivername));
0605 break;
0606 }
0607 bi.data.drivername[0] = '\0';
0608 break;
0609
0610 }
0611 if (copy_to_user(data, &bi, sizeof(bi)))
0612 return -EFAULT;
0613 return 0;
0614
0615 }
0616
0617
0618
0619 static const struct net_device_ops hdlcdrv_netdev = {
0620 .ndo_open = hdlcdrv_open,
0621 .ndo_stop = hdlcdrv_close,
0622 .ndo_start_xmit = hdlcdrv_send_packet,
0623 .ndo_siocdevprivate = hdlcdrv_siocdevprivate,
0624 .ndo_set_mac_address = hdlcdrv_set_mac_address,
0625 };
0626
0627
0628
0629
0630 static void hdlcdrv_setup(struct net_device *dev)
0631 {
0632 static const struct hdlcdrv_channel_params dflt_ch_params = {
0633 20, 2, 10, 40, 0
0634 };
0635 struct hdlcdrv_state *s = netdev_priv(dev);
0636
0637
0638
0639
0640 s->ch_params = dflt_ch_params;
0641 s->ptt_keyed = 0;
0642
0643 spin_lock_init(&s->hdlcrx.hbuf.lock);
0644 s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
0645 s->hdlcrx.in_hdlc_rx = 0;
0646 s->hdlcrx.rx_state = 0;
0647
0648 spin_lock_init(&s->hdlctx.hbuf.lock);
0649 s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
0650 s->hdlctx.in_hdlc_tx = 0;
0651 s->hdlctx.tx_state = 1;
0652 s->hdlctx.numflags = 0;
0653 s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
0654 s->hdlctx.ptt = 0;
0655 s->hdlctx.slotcnt = s->ch_params.slottime;
0656 s->hdlctx.calibrate = 0;
0657
0658 #ifdef HDLCDRV_DEBUG
0659 s->bitbuf_channel.rd = s->bitbuf_channel.wr = 0;
0660 s->bitbuf_channel.shreg = 0x80;
0661
0662 s->bitbuf_hdlc.rd = s->bitbuf_hdlc.wr = 0;
0663 s->bitbuf_hdlc.shreg = 0x80;
0664 #endif
0665
0666
0667
0668
0669 s->skb = NULL;
0670
0671 dev->netdev_ops = &hdlcdrv_netdev;
0672 dev->header_ops = &ax25_header_ops;
0673
0674 dev->type = ARPHRD_AX25;
0675 dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
0676 dev->mtu = AX25_DEF_PACLEN;
0677 dev->addr_len = AX25_ADDR_LEN;
0678 memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
0679 dev_addr_set(dev, (u8 *)&ax25_defaddr);
0680 dev->tx_queue_len = 16;
0681 }
0682
0683
0684 struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
0685 unsigned int privsize, const char *ifname,
0686 unsigned int baseaddr, unsigned int irq,
0687 unsigned int dma)
0688 {
0689 struct net_device *dev;
0690 struct hdlcdrv_state *s;
0691 int err;
0692
0693 if (privsize < sizeof(struct hdlcdrv_state))
0694 privsize = sizeof(struct hdlcdrv_state);
0695
0696 dev = alloc_netdev(privsize, ifname, NET_NAME_UNKNOWN, hdlcdrv_setup);
0697 if (!dev)
0698 return ERR_PTR(-ENOMEM);
0699
0700
0701
0702
0703 s = netdev_priv(dev);
0704 s->magic = HDLCDRV_MAGIC;
0705 s->ops = ops;
0706 dev->base_addr = baseaddr;
0707 dev->irq = irq;
0708 dev->dma = dma;
0709
0710 err = register_netdev(dev);
0711 if (err < 0) {
0712 printk(KERN_WARNING "hdlcdrv: cannot register net "
0713 "device %s\n", dev->name);
0714 free_netdev(dev);
0715 dev = ERR_PTR(err);
0716 }
0717 return dev;
0718 }
0719
0720
0721
0722 void hdlcdrv_unregister(struct net_device *dev)
0723 {
0724 struct hdlcdrv_state *s = netdev_priv(dev);
0725
0726 BUG_ON(s->magic != HDLCDRV_MAGIC);
0727
0728 if (s->opened && s->ops->close)
0729 s->ops->close(dev);
0730 unregister_netdev(dev);
0731
0732 free_netdev(dev);
0733 }
0734
0735
0736
0737 EXPORT_SYMBOL(hdlcdrv_receiver);
0738 EXPORT_SYMBOL(hdlcdrv_transmitter);
0739 EXPORT_SYMBOL(hdlcdrv_arbitrate);
0740 EXPORT_SYMBOL(hdlcdrv_register);
0741 EXPORT_SYMBOL(hdlcdrv_unregister);
0742
0743
0744
0745 static int __init hdlcdrv_init_driver(void)
0746 {
0747 printk(KERN_INFO "hdlcdrv: (C) 1996-2000 Thomas Sailer HB9JNX/AE4WA\n");
0748 printk(KERN_INFO "hdlcdrv: version 0.8\n");
0749 return 0;
0750 }
0751
0752
0753
0754 static void __exit hdlcdrv_cleanup_driver(void)
0755 {
0756 printk(KERN_INFO "hdlcdrv: cleanup\n");
0757 }
0758
0759
0760
0761 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
0762 MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder");
0763 MODULE_LICENSE("GPL");
0764 module_init(hdlcdrv_init_driver);
0765 module_exit(hdlcdrv_cleanup_driver);
0766
0767