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 | /* $Id: isdn_net.h,v 1.19.6.4 2001/09/28 08:05:29 kai Exp $ * * header for Linux ISDN subsystem, network related functions (linklevel). * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */ /* Definitions for hupflags: */ #define ISDN_WAITCHARGE 1 /* did not get a charge info yet */ #define ISDN_HAVECHARGE 2 /* We know a charge info */ #define ISDN_CHARGEHUP 4 /* We want to use the charge mechanism */ #define ISDN_INHUP 8 /* Even if incoming, close after huptimeout */ #define ISDN_MANCHARGE 16 /* Charge Interval manually set */ /* * Definitions for Cisco-HDLC header. */ #define CISCO_ADDR_UNICAST 0x0f #define CISCO_ADDR_BROADCAST 0x8f #define CISCO_CTRL 0x00 #define CISCO_TYPE_CDP 0x2000 #define CISCO_TYPE_INET 0x0800 #define CISCO_TYPE_SLARP 0x8035 #define CISCO_SLARP_REQUEST 0 #define CISCO_SLARP_REPLY 1 #define CISCO_SLARP_KEEPALIVE 2 extern char *isdn_net_new(char *, struct net_device *); extern char *isdn_net_newslave(char *); extern int isdn_net_rm(char *); extern int isdn_net_rmall(void); extern int isdn_net_stat_callback(int, isdn_ctrl *); extern int isdn_net_setcfg(isdn_net_ioctl_cfg *); extern int isdn_net_getcfg(isdn_net_ioctl_cfg *); extern int isdn_net_addphone(isdn_net_ioctl_phone *); extern int isdn_net_getphones(isdn_net_ioctl_phone *, char *); extern int isdn_net_getpeer(isdn_net_ioctl_phone *, isdn_net_ioctl_phone *); extern int isdn_net_delphone(isdn_net_ioctl_phone *); extern int isdn_net_find_icall(int, int, int, setup_parm *); extern void isdn_net_hangup(struct net_device *); extern void isdn_net_dial(void); extern void isdn_net_autohup(void); extern int isdn_net_force_hangup(char *); extern int isdn_net_force_dial(char *); extern isdn_net_dev *isdn_net_findif(char *); extern int isdn_net_rcv_skb(int, struct sk_buff *); extern int isdn_net_dial_req(isdn_net_local *); extern void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb); extern void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb); #define ISDN_NET_MAX_QUEUE_LENGTH 2 /* * is this particular channel busy? */ static __inline__ int isdn_net_lp_busy(isdn_net_local *lp) { if (atomic_read(&lp->frame_cnt) < ISDN_NET_MAX_QUEUE_LENGTH) return 0; else return 1; } /* * For the given net device, this will get a non-busy channel out of the * corresponding bundle. The returned channel is locked. */ static __inline__ isdn_net_local * isdn_net_get_locked_lp(isdn_net_dev *nd) { unsigned long flags; isdn_net_local *lp; spin_lock_irqsave(&nd->queue_lock, flags); lp = nd->queue; /* get lp on top of queue */ spin_lock_bh(&nd->queue->xmit_lock); while (isdn_net_lp_busy(nd->queue)) { spin_unlock_bh(&nd->queue->xmit_lock); nd->queue = nd->queue->next; if (nd->queue == lp) { /* not found -- should never happen */ lp = NULL; goto errout; } spin_lock_bh(&nd->queue->xmit_lock); } lp = nd->queue; nd->queue = nd->queue->next; errout: spin_unlock_irqrestore(&nd->queue_lock, flags); return lp; } /* * add a channel to a bundle */ static __inline__ void isdn_net_add_to_bundle(isdn_net_dev *nd, isdn_net_local *nlp) { isdn_net_local *lp; unsigned long flags; spin_lock_irqsave(&nd->queue_lock, flags); lp = nd->queue; nlp->last = lp->last; lp->last->next = nlp; lp->last = nlp; nlp->next = lp; nd->queue = nlp; spin_unlock_irqrestore(&nd->queue_lock, flags); } /* * remove a channel from the bundle it belongs to */ static __inline__ void isdn_net_rm_from_bundle(isdn_net_local *lp) { isdn_net_local *master_lp = lp; unsigned long flags; if (lp->master) master_lp = (isdn_net_local *) lp->master->priv; spin_lock_irqsave(&master_lp->netdev->queue_lock, flags); lp->last->next = lp->next; lp->next->last = lp->last; if (master_lp->netdev->queue == lp) master_lp->netdev->queue = lp->next; lp->next = lp->last = lp; /* (re)set own pointers */ spin_unlock_irqrestore(&master_lp->netdev->queue_lock, flags); } static inline int put_u8(unsigned char *p, u8 x) { *p = x; return 1; } static inline int put_u16(unsigned char *p, u16 x) { *((u16 *)p) = htons(x); return 2; } static inline int put_u32(unsigned char *p, u32 x) { *((u32 *)p) = htonl(x); return 4; } static inline int get_u8(unsigned char *p, u8 *x) { *x = *p; return 1; } static inline int get_u16(unsigned char *p, u16 *x) { *x = ntohs(*((u16 *)p)); return 2; } static inline int get_u32(unsigned char *p, u32 *x) { *x = ntohl(*((u32 *)p)); return 4; } |