| 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; | 
| Al Viro | 64b3361 | 2007-10-14 19:35:20 +0100 | [diff] [blame] | 203 | 		unsigned long in_hdlc_rx; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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; | 
| Hannes Eder | 886a63e | 2009-02-14 11:36:20 +0000 | [diff] [blame] | 218 | 		unsigned long in_hdlc_tx; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 244 | 	int ptt_keyed; | 
 | 245 |  | 
 | 246 | 	/* queued skb for transmission */ | 
 | 247 | 	struct sk_buff *skb; | 
 | 248 | }; | 
 | 249 |  | 
 | 250 |  | 
 | 251 | /* -------------------------------------------------------------------- */ | 
 | 252 |  | 
 | 253 | static inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb)  | 
 | 254 | { | 
 | 255 | 	unsigned long flags; | 
 | 256 | 	int ret; | 
 | 257 | 	 | 
 | 258 | 	spin_lock_irqsave(&hb->lock, flags); | 
 | 259 | 	ret = !((HDLCDRV_HDLCBUFFER - 1 + hb->rd - hb->wr) % HDLCDRV_HDLCBUFFER); | 
 | 260 | 	spin_unlock_irqrestore(&hb->lock, flags); | 
 | 261 | 	return ret; | 
 | 262 | } | 
 | 263 |  | 
 | 264 | /* -------------------------------------------------------------------- */ | 
 | 265 |  | 
 | 266 | static inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb) | 
 | 267 | { | 
 | 268 | 	unsigned long flags; | 
 | 269 | 	int ret; | 
 | 270 | 	 | 
 | 271 | 	spin_lock_irqsave(&hb->lock, flags); | 
 | 272 | 	ret = (hb->rd == hb->wr); | 
 | 273 | 	spin_unlock_irqrestore(&hb->lock, flags); | 
 | 274 | 	return ret; | 
 | 275 | } | 
 | 276 |  | 
 | 277 | /* -------------------------------------------------------------------- */ | 
 | 278 |  | 
 | 279 | static inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb) | 
 | 280 | { | 
 | 281 | 	unsigned long flags; | 
 | 282 | 	unsigned short val; | 
 | 283 | 	unsigned newr; | 
 | 284 |  | 
 | 285 | 	spin_lock_irqsave(&hb->lock, flags); | 
 | 286 | 	if (hb->rd == hb->wr) | 
 | 287 | 		val = 0; | 
 | 288 | 	else { | 
 | 289 | 		newr = (hb->rd+1) % HDLCDRV_HDLCBUFFER; | 
 | 290 | 		val = hb->buf[hb->rd]; | 
 | 291 | 		hb->rd = newr; | 
 | 292 | 	} | 
 | 293 | 	spin_unlock_irqrestore(&hb->lock, flags); | 
 | 294 | 	return val; | 
 | 295 | } | 
 | 296 |  | 
 | 297 | /* -------------------------------------------------------------------- */ | 
 | 298 |  | 
 | 299 | static inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb,  | 
 | 300 | 				    unsigned short val) | 
 | 301 | { | 
 | 302 | 	unsigned newp; | 
 | 303 | 	unsigned long flags; | 
 | 304 | 	 | 
 | 305 | 	spin_lock_irqsave(&hb->lock, flags); | 
 | 306 | 	newp = (hb->wr+1) % HDLCDRV_HDLCBUFFER; | 
 | 307 | 	if (newp != hb->rd) {  | 
 | 308 | 		hb->buf[hb->wr] = val & 0xffff; | 
 | 309 | 		hb->wr = newp; | 
 | 310 | 	} | 
 | 311 | 	spin_unlock_irqrestore(&hb->lock, flags); | 
 | 312 | } | 
 | 313 |  | 
 | 314 | /* -------------------------------------------------------------------- */ | 
 | 315 |  | 
 | 316 | static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits) | 
 | 317 | { | 
 | 318 | 	hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits); | 
 | 319 | } | 
 | 320 |  | 
 | 321 | static inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s) | 
 | 322 | { | 
 | 323 | 	unsigned int ret; | 
 | 324 |  | 
 | 325 | 	if (hdlcdrv_hbuf_empty(&s->hdlctx.hbuf)) { | 
 | 326 | 		if (s->hdlctx.calibrate > 0) | 
 | 327 | 			s->hdlctx.calibrate--; | 
 | 328 | 		else | 
 | 329 | 			s->hdlctx.ptt = 0; | 
 | 330 | 		ret = 0; | 
 | 331 | 	} else  | 
 | 332 | 		ret = hdlcdrv_hbuf_get(&s->hdlctx.hbuf); | 
 | 333 | #ifdef HDLCDRV_LOOPBACK | 
 | 334 | 	hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, ret); | 
 | 335 | #endif /* HDLCDRV_LOOPBACK */ | 
 | 336 | 	return ret; | 
 | 337 | } | 
 | 338 |  | 
 | 339 | static inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit) | 
 | 340 | { | 
 | 341 | #ifdef HDLCDRV_DEBUG | 
 | 342 | 	hdlcdrv_add_bitbuffer(&s->bitbuf_channel, bit); | 
 | 343 | #endif /* HDLCDRV_DEBUG */ | 
 | 344 | } | 
 | 345 |  | 
 | 346 | static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd) | 
 | 347 | { | 
 | 348 | 	s->hdlcrx.dcd = !!dcd; | 
 | 349 | } | 
 | 350 |  | 
 | 351 | static inline int hdlcdrv_ptt(struct hdlcdrv_state *s) | 
 | 352 | { | 
 | 353 | 	return s->hdlctx.ptt || (s->hdlctx.calibrate > 0); | 
 | 354 | } | 
 | 355 |  | 
 | 356 | /* -------------------------------------------------------------------- */ | 
 | 357 |  | 
 | 358 | void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *); | 
 | 359 | void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *); | 
 | 360 | void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *); | 
 | 361 | struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops, | 
 | 362 | 				    unsigned int privsize, const char *ifname, | 
 | 363 | 				    unsigned int baseaddr, unsigned int irq,  | 
 | 364 | 				    unsigned int dma); | 
 | 365 | void hdlcdrv_unregister(struct net_device *dev); | 
 | 366 |  | 
 | 367 | /* -------------------------------------------------------------------- */ | 
 | 368 |  | 
 | 369 |  | 
 | 370 |  | 
 | 371 | #endif /* __KERNEL__ */ | 
 | 372 |  | 
 | 373 | /* -------------------------------------------------------------------- */ | 
 | 374 |  | 
 | 375 | #endif /* _HDLCDRV_H */ | 
 | 376 |  | 
 | 377 | /* -------------------------------------------------------------------- */ |