File: /usr/src/linux/drivers/isdn/isdn_net.h
1 /* $Id: isdn_net.h,v 1.19.6.2 2001/08/14 14:04:21 kai Exp $
2
3 * header for Linux ISDN subsystem, network related functions (linklevel).
4 *
5 * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de)
6 * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg
7 * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25 /* Definitions for hupflags: */
26 #define ISDN_WAITCHARGE 1 /* did not get a charge info yet */
27 #define ISDN_HAVECHARGE 2 /* We know a charge info */
28 #define ISDN_CHARGEHUP 4 /* We want to use the charge mechanism */
29 #define ISDN_INHUP 8 /* Even if incoming, close after huptimeout */
30 #define ISDN_MANCHARGE 16 /* Charge Interval manually set */
31
32 /*
33 * Definitions for Cisco-HDLC header.
34 */
35
36 #define CISCO_ADDR_UNICAST 0x0f
37 #define CISCO_ADDR_BROADCAST 0x8f
38 #define CISCO_CTRL 0x00
39 #define CISCO_TYPE_CDP 0x2000
40 #define CISCO_TYPE_INET 0x0800
41 #define CISCO_TYPE_SLARP 0x8035
42 #define CISCO_SLARP_REPLY 0
43 #define CISCO_SLARP_REQUEST 1
44 #define CISCO_SLARP_KEEPALIVE 2
45
46 extern char *isdn_net_new(char *, struct net_device *);
47 extern char *isdn_net_newslave(char *);
48 extern int isdn_net_rm(char *);
49 extern int isdn_net_rmall(void);
50 extern int isdn_net_stat_callback(int, isdn_ctrl *);
51 extern int isdn_net_setcfg(isdn_net_ioctl_cfg *);
52 extern int isdn_net_getcfg(isdn_net_ioctl_cfg *);
53 extern int isdn_net_addphone(isdn_net_ioctl_phone *);
54 extern int isdn_net_getphones(isdn_net_ioctl_phone *, char *);
55 extern int isdn_net_getpeer(isdn_net_ioctl_phone *, isdn_net_ioctl_phone *);
56 extern int isdn_net_delphone(isdn_net_ioctl_phone *);
57 extern int isdn_net_find_icall(int, int, int, setup_parm *);
58 extern void isdn_net_hangup(struct net_device *);
59 extern void isdn_net_dial(void);
60 extern void isdn_net_autohup(void);
61 extern int isdn_net_force_hangup(char *);
62 extern int isdn_net_force_dial(char *);
63 extern isdn_net_dev *isdn_net_findif(char *);
64 extern int isdn_net_rcv_skb(int, struct sk_buff *);
65 extern int isdn_net_dial_req(isdn_net_local *);
66 extern void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb);
67 extern void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb);
68
69 #define ISDN_NET_MAX_QUEUE_LENGTH 2
70
71 /*
72 * is this particular channel busy?
73 */
74 static __inline__ int isdn_net_lp_busy(isdn_net_local *lp)
75 {
76 if (atomic_read(&lp->frame_cnt) < ISDN_NET_MAX_QUEUE_LENGTH)
77 return 0;
78 else
79 return 1;
80 }
81
82 /*
83 * For the given net device, this will get a non-busy channel out of the
84 * corresponding bundle. The returned channel is locked.
85 */
86 static __inline__ isdn_net_local * isdn_net_get_locked_lp(isdn_net_dev *nd)
87 {
88 unsigned long flags;
89 isdn_net_local *lp;
90
91 spin_lock_irqsave(&nd->queue_lock, flags);
92 lp = nd->queue; /* get lp on top of queue */
93 spin_lock_bh(&nd->queue->xmit_lock);
94 while (isdn_net_lp_busy(nd->queue)) {
95 spin_unlock_bh(&nd->queue->xmit_lock);
96 nd->queue = nd->queue->next;
97 if (nd->queue == lp) { /* not found -- should never happen */
98 lp = NULL;
99 goto errout;
100 }
101 spin_lock_bh(&nd->queue->xmit_lock);
102 }
103 lp = nd->queue;
104 nd->queue = nd->queue->next;
105 errout:
106 spin_unlock_irqrestore(&nd->queue_lock, flags);
107 return lp;
108 }
109
110 /*
111 * add a channel to a bundle
112 */
113 static __inline__ void isdn_net_add_to_bundle(isdn_net_dev *nd, isdn_net_local *nlp)
114 {
115 isdn_net_local *lp;
116 unsigned long flags;
117
118 spin_lock_irqsave(&nd->queue_lock, flags);
119
120 lp = nd->queue;
121 nlp->last = lp->last;
122 lp->last->next = nlp;
123 lp->last = nlp;
124 nlp->next = lp;
125 nd->queue = nlp;
126
127 spin_unlock_irqrestore(&nd->queue_lock, flags);
128 }
129 /*
130 * remove a channel from the bundle it belongs to
131 */
132 static __inline__ void isdn_net_rm_from_bundle(isdn_net_local *lp)
133 {
134 isdn_net_local *master_lp = lp;
135 unsigned long flags;
136
137 if (lp->master)
138 master_lp = (isdn_net_local *) lp->master->priv;
139
140 spin_lock_irqsave(&master_lp->netdev->queue_lock, flags);
141 lp->last->next = lp->next;
142 lp->next->last = lp->last;
143 if (master_lp->netdev->queue == lp)
144 master_lp->netdev->queue = lp->next;
145 lp->next = lp->last = lp; /* (re)set own pointers */
146 spin_unlock_irqrestore(&master_lp->netdev->queue_lock, flags);
147 }
148
149 static inline int
150 put_u8(unsigned char *p, __u8 x)
151 {
152 p[0] = x;
153 return 1;
154 }
155
156 static inline int
157 put_u16(unsigned char *p, __u16 x)
158 {
159 p[0] = x >> 8;
160 p[1] = x;
161 return 2;
162 }
163
164 static inline int
165 put_u32(unsigned char *p, __u32 x)
166 {
167 p[0] = x >> 24;
168 p[1] = x >> 16;
169 p[2] = x >> 8;
170 p[3] = x;
171 return 4;
172 }
173
174 static inline int
175 get_u8(unsigned char *p, __u8 *x)
176 {
177 *x = p[0];
178 return 1;
179 }
180
181 static inline int
182 get_u16(unsigned char *p, __u16 *x)
183 {
184 *x = (p[0] << 8) + p[1];
185 return 2;
186 }
187
188 static inline int
189 get_u32(unsigned char *p, __u32 *x)
190 {
191 *x = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
192 return 4;
193 }
194
195
196