1/* 2 * Generic HDLC support routines for Linux 3 * 4 * Copyright (C) 1999, 2000 Krzysztof Halasa <khc@pm.waw.pl> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12#ifndef __HDLC_H 13#define __HDLC_H 14 15/* Ioctls - to be changed */ 16#define HDLCGSLOTMAP (0x89F4) /* E1/T1 slot bitmap */ 17#define HDLCGCLOCK (0x89F5) /* clock sources */ 18#define HDLCGCLOCKRATE (0x89F6) /* clock rate */ 19#define HDLCGMODE (0x89F7) /* internal to hdlc.c - protocol used */ 20#define HDLCGLINE (0x89F8) /* physical interface */ 21#define HDLCSSLOTMAP (0x89F9) 22#define HDLCSCLOCK (0x89FA) 23#define HDLCSCLOCKRATE (0x89FB) 24#define HDLCSMODE (0x89FC) /* internal to hdlc.c - select protocol */ 25#define HDLCPVC (0x89FD) /* internal to hdlc.c - create/delete PVC */ 26#define HDLCSLINE (0x89FE) 27#define HDLCRUN (0x89FF) /* Download firmware and run board */ 28 29/* Modes */ 30#define MODE_NONE 0x00000000 /* Not initialized */ 31#define MODE_DCE 0x00000080 /* DCE */ 32#define MODE_HDLC 0x00000100 /* Raw HDLC frames */ 33#define MODE_CISCO 0x00000200 34#define MODE_PPP 0x00000400 35#define MODE_FR 0x00000800 /* Any LMI */ 36#define MODE_FR_ANSI 0x00000801 37#define MODE_FR_CCITT 0x00000802 38#define MODE_X25 0x00001000 39#define MODE_MASK 0x0000FF00 40#define MODE_SOFT 0x80000000 /* Driver modes, using hardware HDLC */ 41 42/* Lines */ 43#define LINE_DEFAULT 0x00000000 44#define LINE_V35 0x00000001 45#define LINE_RS232 0x00000002 46#define LINE_X21 0x00000003 47#define LINE_T1 0x00000004 48#define LINE_E1 0x00000005 49#define LINE_MASK 0x000000FF 50#define LINE_LOOPBACK 0x80000000 /* On-card loopback */ 51 52#define CLOCK_EXT 0 /* External TX and RX clock - DTE */ 53#define CLOCK_INT 1 /* Internal TX and RX clock - DCE */ 54#define CLOCK_TXINT 2 /* Internal TX and external RX clock */ 55#define CLOCK_TXFROMRX 3 /* TX clock derived from external RX clock */ 56 57 58#define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */ 59#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10) /* max 10 bytes for FR */ 60 61#ifdef __KERNEL__ 62 63#include <linux/skbuff.h> 64#include <linux/netdevice.h> 65#include <net/syncppp.h> 66 67#define MAXLEN_LMISTAT 20 /* max size of status enquiry frame */ 68 69#define LINK_STATE_RELIABLE 0x01 70#define LINK_STATE_REQUEST 0x02 /* full stat sent (DCE) / req pending (DTE) */ 71#define LINK_STATE_CHANGED 0x04 /* change in PVCs state, send full report */ 72#define LINK_STATE_FULLREP_SENT 0x08 /* full report sent */ 73 74#define PVC_STATE_NEW 0x01 75#define PVC_STATE_ACTIVE 0x02 76#define PVC_STATE_FECN 0x08 /* FECN condition */ 77#define PVC_STATE_BECN 0x10 /* BECN condition */ 78 79 80#define FR_UI 0x03 81#define FR_PAD 0x00 82 83#define NLPID_IP 0xCC 84#define NLPID_IPV6 0x8E 85#define NLPID_SNAP 0x80 86#define NLPID_PAD 0x00 87#define NLPID_Q933 0x08 88 89 90#define LMI_DLCI 0 /* LMI DLCI */ 91#define LMI_PROTO 0x08 92#define LMI_CALLREF 0x00 /* Call Reference */ 93#define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI lockshift */ 94#define LMI_REPTYPE 1 /* report type */ 95#define LMI_CCITT_REPTYPE 0x51 96#define LMI_ALIVE 3 /* keep alive */ 97#define LMI_CCITT_ALIVE 0x53 98#define LMI_PVCSTAT 7 /* pvc status */ 99#define LMI_CCITT_PVCSTAT 0x57 100#define LMI_FULLREP 0 /* full report */ 101#define LMI_INTEGRITY 1 /* link integrity report */ 102#define LMI_SINGLE 2 /* single pvc report */ 103#define LMI_STATUS_ENQUIRY 0x75 104#define LMI_STATUS 0x7D /* reply */ 105 106#define LMI_REPT_LEN 1 /* report type element length */ 107#define LMI_INTEG_LEN 2 /* link integrity element length */ 108 109#define LMI_LENGTH 13 /* standard LMI frame length */ 110#define LMI_ANSI_LENGTH 14 111 112 113 114typedef struct { 115 unsigned ea1 : 1; 116 unsigned cr : 1; 117 unsigned dlcih: 6; 118 119 unsigned ea2 : 1; 120 unsigned de : 1; 121 unsigned becn : 1; 122 unsigned fecn : 1; 123 unsigned dlcil: 4; 124}__attribute__ ((packed)) fr_hdr; 125 126 127 128typedef struct { /* Used in Cisco and PPP mode */ 129 u8 address; 130 u8 control; 131 u16 protocol; 132}__attribute__ ((packed)) hdlc_header; 133 134 135 136typedef struct { 137 u32 type; /* code */ 138 u32 par1; 139 u32 par2; 140 u16 rel; /* reliability */ 141 u32 time; 142}__attribute__ ((packed)) cisco_packet; 143#define CISCO_PACKET_LEN 18 144#define CISCO_BIG_PACKET_LEN 20 145 146 147 148typedef struct pvc_device_struct { 149 struct net_device netdev; /* PVC net device - must be first */ 150 struct net_device_stats stats; 151 struct hdlc_device_struct *master; 152 struct pvc_device_struct *next; 153 154 u8 state; 155 u8 newstate; 156}pvc_device; 157 158 159 160typedef struct { 161 u32 last_errors; /* last errors bit list */ 162 int last_poll; /* ! */ 163 u8 T391; /* ! link integrity verification polling timer */ 164 u8 T392; /* ! polling verification timer */ 165 u8 N391; /* full status polling counter */ 166 u8 N392; /* error threshold */ 167 u8 N393; /* monitored events count */ 168 u8 N391cnt; 169 170 u8 state; /* ! */ 171 u32 txseq; /* ! TX sequence number - Cisco uses 4 bytes */ 172 u32 rxseq; /* ! RX sequence number */ 173}fr_lmi; /* ! means used in Cisco HDLC as well */ 174 175 176typedef struct hdlc_device_struct { 177 /* to be initialized by hardware driver: */ 178 struct net_device netdev; /* master net device - must be first */ 179 struct net_device_stats stats; 180 181 struct ppp_device pppdev; 182 struct ppp_device *syncppp_ptr; 183 184 /* set_mode may be NULL if HDLC-only board */ 185 int (*set_mode)(struct hdlc_device_struct *hdlc, int mode); 186 int (*open)(struct hdlc_device_struct *hdlc); 187 void (*close)(struct hdlc_device_struct *hdlc); 188 int (*xmit)(struct hdlc_device_struct *hdlc, struct sk_buff *skb); 189 int (*ioctl)(struct hdlc_device_struct *hdlc, struct ifreq *ifr, 190 int cmd); 191 192 /* Only in "hardware" FR modes etc. - may be NULL */ 193 int (*create_pvc)(pvc_device *pvc); 194 void (*destroy_pvc)(pvc_device *pvc); 195 int (*open_pvc)(pvc_device *pvc); 196 void (*close_pvc)(pvc_device *pvc); 197 198 /* for hdlc.c internal use only */ 199 pvc_device *first_pvc; 200 u16 pvc_count; 201 int mode; 202 203 struct timer_list timer; 204 fr_lmi lmi; 205}hdlc_device; 206 207 208int register_hdlc_device(hdlc_device *hdlc); 209void unregister_hdlc_device(hdlc_device *hdlc); 210void hdlc_netif_rx(hdlc_device *hdlc, struct sk_buff *skb); 211 212 213static __inline__ struct net_device* hdlc_to_dev(hdlc_device *hdlc) 214{ 215 return &hdlc->netdev; 216} 217 218 219static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev) 220{ 221 return (hdlc_device*)dev; 222} 223 224 225static __inline__ struct net_device* pvc_to_dev(pvc_device *pvc) 226{ 227 return &pvc->netdev; 228} 229 230 231static __inline__ pvc_device* dev_to_pvc(struct net_device *dev) 232{ 233 return (pvc_device*)dev; 234} 235 236 237static __inline__ const char *hdlc_to_name(hdlc_device *hdlc) 238{ 239 return hdlc_to_dev(hdlc)->name; 240} 241 242 243static __inline__ const char *pvc_to_name(pvc_device *pvc) 244{ 245 return pvc_to_dev(pvc)->name; 246} 247 248 249static __inline__ u16 status_to_dlci(hdlc_device *hdlc, u8 *status, u8 *state) 250{ 251 *state &= ~(PVC_STATE_ACTIVE | PVC_STATE_NEW); 252 if (status[2] & 0x08) 253 *state |= PVC_STATE_NEW; 254 else if (status[2] & 0x02) 255 *state |= PVC_STATE_ACTIVE; 256 257 return ((status[0] & 0x3F)<<4) | ((status[1] & 0x78)>>3); 258} 259 260 261static __inline__ void dlci_to_status(hdlc_device *hdlc, u16 dlci, u8 *status, 262 u8 state) 263{ 264 status[0] = (dlci>>4) & 0x3F; 265 status[1] = ((dlci<<3) & 0x78) | 0x80; 266 status[2] = 0x80; 267 268 if (state & PVC_STATE_NEW) 269 status[2] |= 0x08; 270 else if (state & PVC_STATE_ACTIVE) 271 status[2] |= 0x02; 272} 273 274 275 276static __inline__ u16 netdev_dlci(struct net_device *dev) 277{ 278 return ntohs(*(u16*)dev->dev_addr); 279} 280 281 282 283static __inline__ u16 q922_to_dlci(u8 *hdr) 284{ 285 return ((hdr[0] & 0xFC)<<2) | ((hdr[1] & 0xF0)>>4); 286} 287 288 289 290static __inline__ void dlci_to_q922(u8 *hdr, u16 dlci) 291{ 292 hdr[0] = (dlci>>2) & 0xFC; 293 hdr[1] = ((dlci<<4) & 0xF0) | 0x01; 294} 295 296 297 298static __inline__ int mode_is(hdlc_device *hdlc, int mask) 299{ 300 return (hdlc->mode & mask) == mask; 301} 302 303 304 305static __inline__ pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) 306{ 307 pvc_device *pvc=hdlc->first_pvc; 308 309 while (pvc) { 310 if (netdev_dlci(&pvc->netdev) == dlci) 311 return pvc; 312 pvc=pvc->next; 313 } 314 315 return NULL; 316} 317 318 319 320static __inline__ void debug_frame(const struct sk_buff *skb) 321{ 322 int i; 323 324 for (i=0; i<skb->len; i++) { 325 if (i == 100) { 326 printk("...\n"); 327 return; 328 } 329 printk(" %02X", skb->data[i]); 330 } 331 printk("\n"); 332} 333 334 335#endif /* __KERNEL */ 336#endif /* __HDLC_H */ 337