Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | /* * hdlcdrv.h -- HDLC packet radio network driver. * The Linux soundcard driver for 1200 baud and 9600 baud packet radio * (C) 1996-1998 by Thomas Sailer, HB9JNX/AE4WA */ #ifndef _HDLCDRV_H #define _HDLCDRV_H /* -------------------------------------------------------------------- */ /* * structs for the IOCTL commands */ struct hdlcdrv_params { int iobase; int irq; int dma; int dma2; int seriobase; int pariobase; int midiiobase; }; struct hdlcdrv_channel_params { int tx_delay; /* the transmitter keyup delay in 10ms units */ int tx_tail; /* the transmitter keyoff delay in 10ms units */ int slottime; /* the slottime in 10ms; usually 10 = 100ms */ int ppersist; /* the p-persistence 0..255 */ int fulldup; /* some driver do not support full duplex, setting */ /* this just makes them send even if DCD is on */ }; struct hdlcdrv_old_channel_state { int ptt; int dcd; int ptt_keyed; }; struct hdlcdrv_channel_state { int ptt; int dcd; int ptt_keyed; unsigned long tx_packets; unsigned long tx_errors; unsigned long rx_packets; unsigned long rx_errors; }; struct hdlcdrv_ioctl { int cmd; union { struct hdlcdrv_params mp; struct hdlcdrv_channel_params cp; struct hdlcdrv_channel_state cs; struct hdlcdrv_old_channel_state ocs; unsigned int calibrate; unsigned char bits; char modename[128]; char drivername[32]; } data; }; /* -------------------------------------------------------------------- */ /* * ioctl values */ #define HDLCDRVCTL_GETMODEMPAR 0 #define HDLCDRVCTL_SETMODEMPAR 1 #define HDLCDRVCTL_MODEMPARMASK 2 /* not handled by hdlcdrv */ #define HDLCDRVCTL_GETCHANNELPAR 10 #define HDLCDRVCTL_SETCHANNELPAR 11 #define HDLCDRVCTL_OLDGETSTAT 20 #define HDLCDRVCTL_CALIBRATE 21 #define HDLCDRVCTL_GETSTAT 22 /* * these are mainly for debugging purposes */ #define HDLCDRVCTL_GETSAMPLES 30 #define HDLCDRVCTL_GETBITS 31 /* * not handled by hdlcdrv, but by its depending drivers */ #define HDLCDRVCTL_GETMODE 40 #define HDLCDRVCTL_SETMODE 41 #define HDLCDRVCTL_MODELIST 42 #define HDLCDRVCTL_DRIVERNAME 43 /* * mask of needed modem parameters, returned by HDLCDRVCTL_MODEMPARMASK */ #define HDLCDRV_PARMASK_IOBASE (1<<0) #define HDLCDRV_PARMASK_IRQ (1<<1) #define HDLCDRV_PARMASK_DMA (1<<2) #define HDLCDRV_PARMASK_DMA2 (1<<3) #define HDLCDRV_PARMASK_SERIOBASE (1<<4) #define HDLCDRV_PARMASK_PARIOBASE (1<<5) #define HDLCDRV_PARMASK_MIDIIOBASE (1<<6) /* -------------------------------------------------------------------- */ #ifdef __KERNEL__ #include <linux/netdevice.h> #include <linux/if.h> #include <linux/spinlock.h> #define HDLCDRV_MAGIC 0x5ac6e778 #define HDLCDRV_HDLCBUFFER 32 /* should be a power of 2 for speed reasons */ #define HDLCDRV_BITBUFFER 256 /* should be a power of 2 for speed reasons */ #undef HDLCDRV_LOOPBACK /* define for HDLC debugging purposes */ #define HDLCDRV_DEBUG /* maximum packet length, excluding CRC */ #define HDLCDRV_MAXFLEN 400 struct hdlcdrv_hdlcbuffer { spinlock_t lock; unsigned rd, wr; unsigned short buf[HDLCDRV_HDLCBUFFER]; }; #ifdef HDLCDRV_DEBUG struct hdlcdrv_bitbuffer { unsigned int rd; unsigned int wr; unsigned int shreg; unsigned char buffer[HDLCDRV_BITBUFFER]; }; static inline void hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer *buf, unsigned int bit) { unsigned char new; new = buf->shreg & 1; buf->shreg >>= 1; buf->shreg |= (!!bit) << 7; if (new) { buf->buffer[buf->wr] = buf->shreg; buf->wr = (buf->wr+1) % sizeof(buf->buffer); buf->shreg = 0x80; } } static inline void hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer *buf, unsigned int bits) { buf->buffer[buf->wr] = bits & 0xff; buf->wr = (buf->wr+1) % sizeof(buf->buffer); buf->buffer[buf->wr] = (bits >> 8) & 0xff; buf->wr = (buf->wr+1) % sizeof(buf->buffer); } #endif /* HDLCDRV_DEBUG */ /* -------------------------------------------------------------------- */ /* * Information that need to be kept for each driver. */ struct hdlcdrv_ops { /* * first some informations needed by the hdlcdrv routines */ const char *drvname; const char *drvinfo; /* * the routines called by the hdlcdrv routines */ int (*open)(struct net_device *); int (*close)(struct net_device *); int (*ioctl)(struct net_device *, struct ifreq *, struct hdlcdrv_ioctl *, int); }; struct hdlcdrv_state { int magic; const struct hdlcdrv_ops *ops; struct { int bitrate; } par; struct hdlcdrv_pttoutput { int dma2; int seriobase; int pariobase; int midiiobase; unsigned int flags; } ptt_out; struct hdlcdrv_channel_params ch_params; struct hdlcdrv_hdlcrx { struct hdlcdrv_hdlcbuffer hbuf; long in_hdlc_rx; /* 0 = sync hunt, != 0 receiving */ int rx_state; unsigned int bitstream; unsigned int bitbuf; int numbits; unsigned char dcd; int len; unsigned char *bp; unsigned char buffer[HDLCDRV_MAXFLEN+2]; } hdlcrx; struct hdlcdrv_hdlctx { struct hdlcdrv_hdlcbuffer hbuf; int in_hdlc_tx; /* * 0 = send flags * 1 = send txtail (flags) * 2 = send packet */ int tx_state; int numflags; unsigned int bitstream; unsigned char ptt; int calibrate; int slotcnt; unsigned int bitbuf; int numbits; int len; unsigned char *bp; unsigned char buffer[HDLCDRV_MAXFLEN+2]; } hdlctx; #ifdef HDLCDRV_DEBUG struct hdlcdrv_bitbuffer bitbuf_channel; struct hdlcdrv_bitbuffer bitbuf_hdlc; #endif /* HDLCDRV_DEBUG */ struct net_device_stats stats; int ptt_keyed; /* queued skb for transmission */ struct sk_buff *skb; }; /* -------------------------------------------------------------------- */ static inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb) { unsigned long flags; int ret; spin_lock_irqsave(&hb->lock, flags); ret = !((HDLCDRV_HDLCBUFFER - 1 + hb->rd - hb->wr) % HDLCDRV_HDLCBUFFER); spin_unlock_irqrestore(&hb->lock, flags); return ret; } /* -------------------------------------------------------------------- */ static inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb) { unsigned long flags; int ret; spin_lock_irqsave(&hb->lock, flags); ret = (hb->rd == hb->wr); spin_unlock_irqrestore(&hb->lock, flags); return ret; } /* -------------------------------------------------------------------- */ static inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb) { unsigned long flags; unsigned short val; unsigned newr; spin_lock_irqsave(&hb->lock, flags); if (hb->rd == hb->wr) val = 0; else { newr = (hb->rd+1) % HDLCDRV_HDLCBUFFER; val = hb->buf[hb->rd]; hb->rd = newr; } spin_unlock_irqrestore(&hb->lock, flags); return val; } /* -------------------------------------------------------------------- */ static inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb, unsigned short val) { unsigned newp; unsigned long flags; spin_lock_irqsave(&hb->lock, flags); newp = (hb->wr+1) % HDLCDRV_HDLCBUFFER; if (newp != hb->rd) { hb->buf[hb->wr] = val & 0xffff; hb->wr = newp; } spin_unlock_irqrestore(&hb->lock, flags); } /* -------------------------------------------------------------------- */ static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits) { hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits); } static inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s) { unsigned int ret; if (hdlcdrv_hbuf_empty(&s->hdlctx.hbuf)) { if (s->hdlctx.calibrate > 0) s->hdlctx.calibrate--; else s->hdlctx.ptt = 0; ret = 0; } else ret = hdlcdrv_hbuf_get(&s->hdlctx.hbuf); #ifdef HDLCDRV_LOOPBACK hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, ret); #endif /* HDLCDRV_LOOPBACK */ return ret; } static inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit) { #ifdef HDLCDRV_DEBUG hdlcdrv_add_bitbuffer(&s->bitbuf_channel, bit); #endif /* HDLCDRV_DEBUG */ } static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd) { s->hdlcrx.dcd = !!dcd; } static inline int hdlcdrv_ptt(struct hdlcdrv_state *s) { return s->hdlctx.ptt || (s->hdlctx.calibrate > 0); } /* -------------------------------------------------------------------- */ void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *); void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *); void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *); int hdlcdrv_register_hdlcdrv(struct net_device *dev, const struct hdlcdrv_ops *ops, unsigned int privsize, char *ifname, unsigned int baseaddr, unsigned int irq, unsigned int dma); int hdlcdrv_unregister_hdlcdrv(struct net_device *dev); /* -------------------------------------------------------------------- */ #endif /* __KERNEL__ */ /* -------------------------------------------------------------------- */ #endif /* _HDLCDRV_H */ /* -------------------------------------------------------------------- */ |