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