Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] Modularize generic HDLC

This patch enables building of individual WAN protocol support
routines (parts of generic HDLC) as separate modules.
All protocol-private definitions are moved from hdlc.h file
to protocol drivers. User-space interface and interface
between generic HDLC and underlying low-level HDLC drivers
are unchanged.

Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by

Krzysztof Halasa and committed by
Jeff Garzik
eb2a2fd9 c226951b

+739 -504
+6 -6
drivers/net/wan/Kconfig
··· 154 154 If unsure, say N. 155 155 156 156 config HDLC_RAW 157 - bool "Raw HDLC support" 157 + tristate "Raw HDLC support" 158 158 depends on HDLC 159 159 help 160 160 Generic HDLC driver supporting raw HDLC over WAN connections. ··· 162 162 If unsure, say N. 163 163 164 164 config HDLC_RAW_ETH 165 - bool "Raw HDLC Ethernet device support" 165 + tristate "Raw HDLC Ethernet device support" 166 166 depends on HDLC 167 167 help 168 168 Generic HDLC driver supporting raw HDLC Ethernet device emulation ··· 173 173 If unsure, say N. 174 174 175 175 config HDLC_CISCO 176 - bool "Cisco HDLC support" 176 + tristate "Cisco HDLC support" 177 177 depends on HDLC 178 178 help 179 179 Generic HDLC driver supporting Cisco HDLC over WAN connections. ··· 181 181 If unsure, say N. 182 182 183 183 config HDLC_FR 184 - bool "Frame Relay support" 184 + tristate "Frame Relay support" 185 185 depends on HDLC 186 186 help 187 187 Generic HDLC driver supporting Frame Relay over WAN connections. ··· 189 189 If unsure, say N. 190 190 191 191 config HDLC_PPP 192 - bool "Synchronous Point-to-Point Protocol (PPP) support" 192 + tristate "Synchronous Point-to-Point Protocol (PPP) support" 193 193 depends on HDLC 194 194 help 195 195 Generic HDLC driver supporting PPP over WAN connections. ··· 197 197 If unsure, say N. 198 198 199 199 config HDLC_X25 200 - bool "X.25 protocol support" 200 + tristate "X.25 protocol support" 201 201 depends on HDLC && (LAPB=m && HDLC=m || LAPB=y) 202 202 help 203 203 Generic HDLC driver supporting X.25 over WAN connections.
+7 -12
drivers/net/wan/Makefile
··· 9 9 cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o 10 10 cyclomx-objs := $(cyclomx-y) 11 11 12 - hdlc-y := hdlc_generic.o 13 - hdlc-$(CONFIG_HDLC_RAW) += hdlc_raw.o 14 - hdlc-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o 15 - hdlc-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o 16 - hdlc-$(CONFIG_HDLC_FR) += hdlc_fr.o 17 - hdlc-$(CONFIG_HDLC_PPP) += hdlc_ppp.o 18 - hdlc-$(CONFIG_HDLC_X25) += hdlc_x25.o 19 - hdlc-objs := $(hdlc-y) 12 + obj-$(CONFIG_HDLC) += hdlc.o 13 + obj-$(CONFIG_HDLC_RAW) += hdlc_raw.o 14 + obj-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o 15 + obj-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o 16 + obj-$(CONFIG_HDLC_FR) += hdlc_fr.o 17 + obj-$(CONFIG_HDLC_PPP) += hdlc_ppp.o syncppp.o 18 + obj-$(CONFIG_HDLC_X25) += hdlc_x25.o 20 19 21 20 pc300-y := pc300_drv.o 22 21 pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o ··· 37 38 obj-$(CONFIG_LAPBETHER) += lapbether.o 38 39 obj-$(CONFIG_SBNI) += sbni.o 39 40 obj-$(CONFIG_PC300) += pc300.o 40 - obj-$(CONFIG_HDLC) += hdlc.o 41 - ifeq ($(CONFIG_HDLC_PPP),y) 42 - obj-$(CONFIG_HDLC) += syncppp.o 43 - endif 44 41 obj-$(CONFIG_N2) += n2.o 45 42 obj-$(CONFIG_C101) += c101.o 46 43 obj-$(CONFIG_WANXL) += wanxl.o
+133 -63
drivers/net/wan/hdlc_cisco.c
··· 2 2 * Generic HDLC support routines for Linux 3 3 * Cisco HDLC support 4 4 * 5 - * Copyright (C) 2000 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 + * Copyright (C) 2000 - 2006 Krzysztof Halasa <khc@pm.waw.pl> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify it 8 8 * under the terms of version 2 of the GNU General Public License ··· 34 34 #define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ 35 35 36 36 37 + struct hdlc_header { 38 + u8 address; 39 + u8 control; 40 + u16 protocol; 41 + }__attribute__ ((packed)); 42 + 43 + 44 + struct cisco_packet { 45 + u32 type; /* code */ 46 + u32 par1; 47 + u32 par2; 48 + u16 rel; /* reliability */ 49 + u32 time; 50 + }__attribute__ ((packed)); 51 + #define CISCO_PACKET_LEN 18 52 + #define CISCO_BIG_PACKET_LEN 20 53 + 54 + 55 + struct cisco_state { 56 + cisco_proto settings; 57 + 58 + struct timer_list timer; 59 + unsigned long last_poll; 60 + int up; 61 + int request_sent; 62 + u32 txseq; /* TX sequence number */ 63 + u32 rxseq; /* RX sequence number */ 64 + }; 65 + 66 + 67 + static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr); 68 + 69 + 70 + static inline struct cisco_state * state(hdlc_device *hdlc) 71 + { 72 + return(struct cisco_state *)(hdlc->state); 73 + } 74 + 75 + 37 76 static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev, 38 77 u16 type, void *daddr, void *saddr, 39 78 unsigned int len) 40 79 { 41 - hdlc_header *data; 80 + struct hdlc_header *data; 42 81 #ifdef DEBUG_HARD_HEADER 43 82 printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name); 44 83 #endif 45 84 46 - skb_push(skb, sizeof(hdlc_header)); 47 - data = (hdlc_header*)skb->data; 85 + skb_push(skb, sizeof(struct hdlc_header)); 86 + data = (struct hdlc_header*)skb->data; 48 87 if (type == CISCO_KEEPALIVE) 49 88 data->address = CISCO_MULTICAST; 50 89 else ··· 91 52 data->control = 0; 92 53 data->protocol = htons(type); 93 54 94 - return sizeof(hdlc_header); 55 + return sizeof(struct hdlc_header); 95 56 } 96 57 97 58 ··· 100 61 u32 par1, u32 par2) 101 62 { 102 63 struct sk_buff *skb; 103 - cisco_packet *data; 64 + struct cisco_packet *data; 104 65 105 - skb = dev_alloc_skb(sizeof(hdlc_header) + sizeof(cisco_packet)); 66 + skb = dev_alloc_skb(sizeof(struct hdlc_header) + 67 + sizeof(struct cisco_packet)); 106 68 if (!skb) { 107 69 printk(KERN_WARNING 108 70 "%s: Memory squeeze on cisco_keepalive_send()\n", ··· 112 72 } 113 73 skb_reserve(skb, 4); 114 74 cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); 115 - data = (cisco_packet*)(skb->data + 4); 75 + data = (struct cisco_packet*)(skb->data + 4); 116 76 117 77 data->type = htonl(type); 118 78 data->par1 = htonl(par1); ··· 121 81 /* we will need do_div here if 1000 % HZ != 0 */ 122 82 data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ)); 123 83 124 - skb_put(skb, sizeof(cisco_packet)); 84 + skb_put(skb, sizeof(struct cisco_packet)); 125 85 skb->priority = TC_PRIO_CONTROL; 126 86 skb->dev = dev; 127 87 skb->nh.raw = skb->data; ··· 133 93 134 94 static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev) 135 95 { 136 - hdlc_header *data = (hdlc_header*)skb->data; 96 + struct hdlc_header *data = (struct hdlc_header*)skb->data; 137 97 138 - if (skb->len < sizeof(hdlc_header)) 98 + if (skb->len < sizeof(struct hdlc_header)) 139 99 return __constant_htons(ETH_P_HDLC); 140 100 141 101 if (data->address != CISCO_MULTICAST && ··· 146 106 case __constant_htons(ETH_P_IP): 147 107 case __constant_htons(ETH_P_IPX): 148 108 case __constant_htons(ETH_P_IPV6): 149 - skb_pull(skb, sizeof(hdlc_header)); 109 + skb_pull(skb, sizeof(struct hdlc_header)); 150 110 return data->protocol; 151 111 default: 152 112 return __constant_htons(ETH_P_HDLC); ··· 158 118 { 159 119 struct net_device *dev = skb->dev; 160 120 hdlc_device *hdlc = dev_to_hdlc(dev); 161 - hdlc_header *data = (hdlc_header*)skb->data; 162 - cisco_packet *cisco_data; 121 + struct hdlc_header *data = (struct hdlc_header*)skb->data; 122 + struct cisco_packet *cisco_data; 163 123 struct in_device *in_dev; 164 124 u32 addr, mask; 165 125 166 - if (skb->len < sizeof(hdlc_header)) 126 + if (skb->len < sizeof(struct hdlc_header)) 167 127 goto rx_error; 168 128 169 129 if (data->address != CISCO_MULTICAST && ··· 177 137 return NET_RX_SUCCESS; 178 138 179 139 case CISCO_KEEPALIVE: 180 - if (skb->len != sizeof(hdlc_header) + CISCO_PACKET_LEN && 181 - skb->len != sizeof(hdlc_header) + CISCO_BIG_PACKET_LEN) { 182 - printk(KERN_INFO "%s: Invalid length of Cisco " 183 - "control packet (%d bytes)\n", 184 - dev->name, skb->len); 140 + if ((skb->len != sizeof(struct hdlc_header) + 141 + CISCO_PACKET_LEN) && 142 + (skb->len != sizeof(struct hdlc_header) + 143 + CISCO_BIG_PACKET_LEN)) { 144 + printk(KERN_INFO "%s: Invalid length of Cisco control" 145 + " packet (%d bytes)\n", dev->name, skb->len); 185 146 goto rx_error; 186 147 } 187 148 188 - cisco_data = (cisco_packet*)(skb->data + sizeof(hdlc_header)); 149 + cisco_data = (struct cisco_packet*)(skb->data + sizeof 150 + (struct hdlc_header)); 189 151 190 152 switch(ntohl (cisco_data->type)) { 191 153 case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ ··· 220 178 goto rx_error; 221 179 222 180 case CISCO_KEEPALIVE_REQ: 223 - hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); 224 - if (hdlc->state.cisco.request_sent && 225 - ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { 226 - hdlc->state.cisco.last_poll = jiffies; 227 - if (!hdlc->state.cisco.up) { 181 + state(hdlc)->rxseq = ntohl(cisco_data->par1); 182 + if (state(hdlc)->request_sent && 183 + ntohl(cisco_data->par2) == state(hdlc)->txseq) { 184 + state(hdlc)->last_poll = jiffies; 185 + if (!state(hdlc)->up) { 228 186 u32 sec, min, hrs, days; 229 187 sec = ntohl(cisco_data->time) / 1000; 230 188 min = sec / 60; sec -= min * 60; ··· 235 193 dev->name, days, hrs, 236 194 min, sec); 237 195 netif_dormant_off(dev); 238 - hdlc->state.cisco.up = 1; 196 + state(hdlc)->up = 1; 239 197 } 240 198 } 241 199 ··· 250 208 return NET_RX_DROP; 251 209 252 210 rx_error: 253 - hdlc->stats.rx_errors++; /* Mark error */ 211 + dev_to_desc(dev)->stats.rx_errors++; /* Mark error */ 254 212 dev_kfree_skb_any(skb); 255 213 return NET_RX_DROP; 256 214 } ··· 262 220 struct net_device *dev = (struct net_device *)arg; 263 221 hdlc_device *hdlc = dev_to_hdlc(dev); 264 222 265 - if (hdlc->state.cisco.up && 266 - time_after(jiffies, hdlc->state.cisco.last_poll + 267 - hdlc->state.cisco.settings.timeout * HZ)) { 268 - hdlc->state.cisco.up = 0; 223 + if (state(hdlc)->up && 224 + time_after(jiffies, state(hdlc)->last_poll + 225 + state(hdlc)->settings.timeout * HZ)) { 226 + state(hdlc)->up = 0; 269 227 printk(KERN_INFO "%s: Link down\n", dev->name); 270 228 netif_dormant_on(dev); 271 229 } 272 230 273 - cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, 274 - ++hdlc->state.cisco.txseq, 275 - hdlc->state.cisco.rxseq); 276 - hdlc->state.cisco.request_sent = 1; 277 - hdlc->state.cisco.timer.expires = jiffies + 278 - hdlc->state.cisco.settings.interval * HZ; 279 - hdlc->state.cisco.timer.function = cisco_timer; 280 - hdlc->state.cisco.timer.data = arg; 281 - add_timer(&hdlc->state.cisco.timer); 231 + cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, ++state(hdlc)->txseq, 232 + state(hdlc)->rxseq); 233 + state(hdlc)->request_sent = 1; 234 + state(hdlc)->timer.expires = jiffies + 235 + state(hdlc)->settings.interval * HZ; 236 + state(hdlc)->timer.function = cisco_timer; 237 + state(hdlc)->timer.data = arg; 238 + add_timer(&state(hdlc)->timer); 282 239 } 283 240 284 241 ··· 285 244 static void cisco_start(struct net_device *dev) 286 245 { 287 246 hdlc_device *hdlc = dev_to_hdlc(dev); 288 - hdlc->state.cisco.up = 0; 289 - hdlc->state.cisco.request_sent = 0; 290 - hdlc->state.cisco.txseq = hdlc->state.cisco.rxseq = 0; 247 + state(hdlc)->up = 0; 248 + state(hdlc)->request_sent = 0; 249 + state(hdlc)->txseq = state(hdlc)->rxseq = 0; 291 250 292 - init_timer(&hdlc->state.cisco.timer); 293 - hdlc->state.cisco.timer.expires = jiffies + HZ; /*First poll after 1s*/ 294 - hdlc->state.cisco.timer.function = cisco_timer; 295 - hdlc->state.cisco.timer.data = (unsigned long)dev; 296 - add_timer(&hdlc->state.cisco.timer); 251 + init_timer(&state(hdlc)->timer); 252 + state(hdlc)->timer.expires = jiffies + HZ; /*First poll after 1s*/ 253 + state(hdlc)->timer.function = cisco_timer; 254 + state(hdlc)->timer.data = (unsigned long)dev; 255 + add_timer(&state(hdlc)->timer); 297 256 } 298 257 299 258 ··· 301 260 static void cisco_stop(struct net_device *dev) 302 261 { 303 262 hdlc_device *hdlc = dev_to_hdlc(dev); 304 - del_timer_sync(&hdlc->state.cisco.timer); 263 + del_timer_sync(&state(hdlc)->timer); 305 264 netif_dormant_on(dev); 306 - hdlc->state.cisco.up = 0; 307 - hdlc->state.cisco.request_sent = 0; 265 + state(hdlc)->up = 0; 266 + state(hdlc)->request_sent = 0; 308 267 } 309 268 310 269 311 270 312 - int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) 271 + static struct hdlc_proto proto = { 272 + .start = cisco_start, 273 + .stop = cisco_stop, 274 + .type_trans = cisco_type_trans, 275 + .ioctl = cisco_ioctl, 276 + .module = THIS_MODULE, 277 + }; 278 + 279 + 280 + static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) 313 281 { 314 282 cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; 315 283 const size_t size = sizeof(cisco_proto); ··· 328 278 329 279 switch (ifr->ifr_settings.type) { 330 280 case IF_GET_PROTO: 281 + if (dev_to_hdlc(dev)->proto != &proto) 282 + return -EINVAL; 331 283 ifr->ifr_settings.type = IF_PROTO_CISCO; 332 284 if (ifr->ifr_settings.size < size) { 333 285 ifr->ifr_settings.size = size; /* data size wanted */ 334 286 return -ENOBUFS; 335 287 } 336 - if (copy_to_user(cisco_s, &hdlc->state.cisco.settings, size)) 288 + if (copy_to_user(cisco_s, &state(hdlc)->settings, size)) 337 289 return -EFAULT; 338 290 return 0; 339 291 ··· 354 302 return -EINVAL; 355 303 356 304 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); 357 - 358 305 if (result) 359 306 return result; 360 307 361 - hdlc_proto_detach(hdlc); 362 - memcpy(&hdlc->state.cisco.settings, &new_settings, size); 363 - memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 308 + result = attach_hdlc_protocol(dev, &proto, cisco_rx, 309 + sizeof(struct cisco_state)); 310 + if (result) 311 + return result; 364 312 365 - hdlc->proto.start = cisco_start; 366 - hdlc->proto.stop = cisco_stop; 367 - hdlc->proto.netif_rx = cisco_rx; 368 - hdlc->proto.type_trans = cisco_type_trans; 369 - hdlc->proto.id = IF_PROTO_CISCO; 313 + memcpy(&state(hdlc)->settings, &new_settings, size); 370 314 dev->hard_start_xmit = hdlc->xmit; 371 315 dev->hard_header = cisco_hard_header; 372 316 dev->hard_header_cache = NULL; ··· 375 327 376 328 return -EINVAL; 377 329 } 330 + 331 + 332 + static int __init mod_init(void) 333 + { 334 + register_hdlc_protocol(&proto); 335 + return 0; 336 + } 337 + 338 + 339 + 340 + static void __exit mod_exit(void) 341 + { 342 + unregister_hdlc_protocol(&proto); 343 + } 344 + 345 + 346 + module_init(mod_init); 347 + module_exit(mod_exit); 348 + 349 + MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 350 + MODULE_DESCRIPTION("Cisco HDLC protocol support for generic HDLC"); 351 + MODULE_LICENSE("GPL v2");
+235 -150
drivers/net/wan/hdlc_fr.c
··· 2 2 * Generic HDLC support routines for Linux 3 3 * Frame Relay support 4 4 * 5 - * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> 5 + * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify it 8 8 * under the terms of version 2 of the GNU General Public License ··· 52 52 #undef DEBUG_PKT 53 53 #undef DEBUG_ECN 54 54 #undef DEBUG_LINK 55 + #undef DEBUG_PROTO 56 + #undef DEBUG_PVC 55 57 56 58 #define FR_UI 0x03 57 59 #define FR_PAD 0x00 ··· 117 115 }__attribute__ ((packed)) fr_hdr; 118 116 119 117 118 + typedef struct pvc_device_struct { 119 + struct net_device *frad; 120 + struct net_device *main; 121 + struct net_device *ether; /* bridged Ethernet interface */ 122 + struct pvc_device_struct *next; /* Sorted in ascending DLCI order */ 123 + int dlci; 124 + int open_count; 125 + 126 + struct { 127 + unsigned int new: 1; 128 + unsigned int active: 1; 129 + unsigned int exist: 1; 130 + unsigned int deleted: 1; 131 + unsigned int fecn: 1; 132 + unsigned int becn: 1; 133 + unsigned int bandwidth; /* Cisco LMI reporting only */ 134 + }state; 135 + }pvc_device; 136 + 137 + 138 + struct frad_state { 139 + fr_proto settings; 140 + pvc_device *first_pvc; 141 + int dce_pvc_count; 142 + 143 + struct timer_list timer; 144 + unsigned long last_poll; 145 + int reliable; 146 + int dce_changed; 147 + int request; 148 + int fullrep_sent; 149 + u32 last_errors; /* last errors bit list */ 150 + u8 n391cnt; 151 + u8 txseq; /* TX sequence number */ 152 + u8 rxseq; /* RX sequence number */ 153 + }; 154 + 155 + 156 + static int fr_ioctl(struct net_device *dev, struct ifreq *ifr); 157 + 158 + 120 159 static inline u16 q922_to_dlci(u8 *hdr) 121 160 { 122 161 return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4); 123 162 } 124 - 125 163 126 164 127 165 static inline void dlci_to_q922(u8 *hdr, u16 dlci) ··· 171 129 } 172 130 173 131 132 + static inline struct frad_state * state(hdlc_device *hdlc) 133 + { 134 + return(struct frad_state *)(hdlc->state); 135 + } 136 + 137 + 138 + static __inline__ pvc_device* dev_to_pvc(struct net_device *dev) 139 + { 140 + return dev->priv; 141 + } 142 + 174 143 175 144 static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) 176 145 { 177 - pvc_device *pvc = hdlc->state.fr.first_pvc; 146 + pvc_device *pvc = state(hdlc)->first_pvc; 178 147 179 148 while (pvc) { 180 149 if (pvc->dlci == dlci) ··· 199 146 } 200 147 201 148 202 - static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci) 149 + static pvc_device* add_pvc(struct net_device *dev, u16 dlci) 203 150 { 204 151 hdlc_device *hdlc = dev_to_hdlc(dev); 205 - pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc; 152 + pvc_device *pvc, **pvc_p = &state(hdlc)->first_pvc; 206 153 207 154 while (*pvc_p) { 208 155 if ((*pvc_p)->dlci == dlci) ··· 213 160 } 214 161 215 162 pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC); 163 + #ifdef DEBUG_PVC 164 + printk(KERN_DEBUG "add_pvc: allocated pvc %p, frad %p\n", pvc, dev); 165 + #endif 216 166 if (!pvc) 217 167 return NULL; 218 168 219 169 memset(pvc, 0, sizeof(pvc_device)); 220 170 pvc->dlci = dlci; 221 - pvc->master = dev; 171 + pvc->frad = dev; 222 172 pvc->next = *pvc_p; /* Put it in the chain */ 223 173 *pvc_p = pvc; 224 174 return pvc; ··· 230 174 231 175 static inline int pvc_is_used(pvc_device *pvc) 232 176 { 233 - return pvc->main != NULL || pvc->ether != NULL; 177 + return pvc->main || pvc->ether; 234 178 } 235 179 236 180 ··· 256 200 257 201 static inline void delete_unused_pvcs(hdlc_device *hdlc) 258 202 { 259 - pvc_device **pvc_p = &hdlc->state.fr.first_pvc; 203 + pvc_device **pvc_p = &state(hdlc)->first_pvc; 260 204 261 205 while (*pvc_p) { 262 206 if (!pvc_is_used(*pvc_p)) { 263 207 pvc_device *pvc = *pvc_p; 208 + #ifdef DEBUG_PVC 209 + printk(KERN_DEBUG "freeing unused pvc: %p\n", pvc); 210 + #endif 264 211 *pvc_p = pvc->next; 265 212 kfree(pvc); 266 213 continue; ··· 354 295 { 355 296 pvc_device *pvc = dev_to_pvc(dev); 356 297 357 - if ((pvc->master->flags & IFF_UP) == 0) 358 - return -EIO; /* Master must be UP in order to activate PVC */ 298 + if ((pvc->frad->flags & IFF_UP) == 0) 299 + return -EIO; /* Frad must be UP in order to activate PVC */ 359 300 360 301 if (pvc->open_count++ == 0) { 361 - hdlc_device *hdlc = dev_to_hdlc(pvc->master); 362 - if (hdlc->state.fr.settings.lmi == LMI_NONE) 363 - pvc->state.active = netif_carrier_ok(pvc->master); 302 + hdlc_device *hdlc = dev_to_hdlc(pvc->frad); 303 + if (state(hdlc)->settings.lmi == LMI_NONE) 304 + pvc->state.active = netif_carrier_ok(pvc->frad); 364 305 365 306 pvc_carrier(pvc->state.active, pvc); 366 - hdlc->state.fr.dce_changed = 1; 307 + state(hdlc)->dce_changed = 1; 367 308 } 368 309 return 0; 369 310 } ··· 375 316 pvc_device *pvc = dev_to_pvc(dev); 376 317 377 318 if (--pvc->open_count == 0) { 378 - hdlc_device *hdlc = dev_to_hdlc(pvc->master); 379 - if (hdlc->state.fr.settings.lmi == LMI_NONE) 319 + hdlc_device *hdlc = dev_to_hdlc(pvc->frad); 320 + if (state(hdlc)->settings.lmi == LMI_NONE) 380 321 pvc->state.active = 0; 381 322 382 - if (hdlc->state.fr.settings.dce) { 383 - hdlc->state.fr.dce_changed = 1; 323 + if (state(hdlc)->settings.dce) { 324 + state(hdlc)->dce_changed = 1; 384 325 pvc->state.active = 0; 385 326 } 386 327 } ··· 407 348 } 408 349 409 350 info.dlci = pvc->dlci; 410 - memcpy(info.master, pvc->master->name, IFNAMSIZ); 351 + memcpy(info.master, pvc->frad->name, IFNAMSIZ); 411 352 if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, 412 353 &info, sizeof(info))) 413 354 return -EFAULT; ··· 420 361 421 362 static inline struct net_device_stats *pvc_get_stats(struct net_device *dev) 422 363 { 423 - return netdev_priv(dev); 364 + return &dev_to_desc(dev)->stats; 424 365 } 425 366 426 367 ··· 452 393 stats->tx_packets++; 453 394 if (pvc->state.fecn) /* TX Congestion counter */ 454 395 stats->tx_compressed++; 455 - skb->dev = pvc->master; 396 + skb->dev = pvc->frad; 456 397 dev_queue_xmit(skb); 457 398 return 0; 458 399 } ··· 478 419 static inline void fr_log_dlci_active(pvc_device *pvc) 479 420 { 480 421 printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n", 481 - pvc->master->name, 422 + pvc->frad->name, 482 423 pvc->dlci, 483 424 pvc->main ? pvc->main->name : "", 484 425 pvc->main && pvc->ether ? " " : "", ··· 497 438 } 498 439 499 440 500 - 501 441 static void fr_lmi_send(struct net_device *dev, int fullrep) 502 442 { 503 443 hdlc_device *hdlc = dev_to_hdlc(dev); 504 444 struct sk_buff *skb; 505 - pvc_device *pvc = hdlc->state.fr.first_pvc; 506 - int lmi = hdlc->state.fr.settings.lmi; 507 - int dce = hdlc->state.fr.settings.dce; 445 + pvc_device *pvc = state(hdlc)->first_pvc; 446 + int lmi = state(hdlc)->settings.lmi; 447 + int dce = state(hdlc)->settings.dce; 508 448 int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH; 509 449 int stat_len = (lmi == LMI_CISCO) ? 6 : 3; 510 450 u8 *data; 511 451 int i = 0; 512 452 513 453 if (dce && fullrep) { 514 - len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); 454 + len += state(hdlc)->dce_pvc_count * (2 + stat_len); 515 455 if (len > HDLC_MAX_MRU) { 516 456 printk(KERN_WARNING "%s: Too many PVCs while sending " 517 457 "LMI full report\n", dev->name); ··· 544 486 data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; 545 487 data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE; 546 488 data[i++] = LMI_INTEG_LEN; 547 - data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq); 548 - data[i++] = hdlc->state.fr.rxseq; 489 + data[i++] = state(hdlc)->txseq = 490 + fr_lmi_nextseq(state(hdlc)->txseq); 491 + data[i++] = state(hdlc)->rxseq; 549 492 550 493 if (dce && fullrep) { 551 494 while (pvc) { ··· 555 496 data[i++] = stat_len; 556 497 557 498 /* LMI start/restart */ 558 - if (hdlc->state.fr.reliable && !pvc->state.exist) { 499 + if (state(hdlc)->reliable && !pvc->state.exist) { 559 500 pvc->state.exist = pvc->state.new = 1; 560 501 fr_log_dlci_active(pvc); 561 502 } ··· 600 541 static void fr_set_link_state(int reliable, struct net_device *dev) 601 542 { 602 543 hdlc_device *hdlc = dev_to_hdlc(dev); 603 - pvc_device *pvc = hdlc->state.fr.first_pvc; 544 + pvc_device *pvc = state(hdlc)->first_pvc; 604 545 605 - hdlc->state.fr.reliable = reliable; 546 + state(hdlc)->reliable = reliable; 606 547 if (reliable) { 607 548 netif_dormant_off(dev); 608 - hdlc->state.fr.n391cnt = 0; /* Request full status */ 609 - hdlc->state.fr.dce_changed = 1; 549 + state(hdlc)->n391cnt = 0; /* Request full status */ 550 + state(hdlc)->dce_changed = 1; 610 551 611 - if (hdlc->state.fr.settings.lmi == LMI_NONE) { 552 + if (state(hdlc)->settings.lmi == LMI_NONE) { 612 553 while (pvc) { /* Activate all PVCs */ 613 554 pvc_carrier(1, pvc); 614 555 pvc->state.exist = pvc->state.active = 1; ··· 622 563 pvc_carrier(0, pvc); 623 564 pvc->state.exist = pvc->state.active = 0; 624 565 pvc->state.new = 0; 625 - if (!hdlc->state.fr.settings.dce) 566 + if (!state(hdlc)->settings.dce) 626 567 pvc->state.bandwidth = 0; 627 568 pvc = pvc->next; 628 569 } 629 570 } 630 571 } 631 - 632 572 633 573 634 574 static void fr_timer(unsigned long arg) ··· 637 579 int i, cnt = 0, reliable; 638 580 u32 list; 639 581 640 - if (hdlc->state.fr.settings.dce) { 641 - reliable = hdlc->state.fr.request && 642 - time_before(jiffies, hdlc->state.fr.last_poll + 643 - hdlc->state.fr.settings.t392 * HZ); 644 - hdlc->state.fr.request = 0; 582 + if (state(hdlc)->settings.dce) { 583 + reliable = state(hdlc)->request && 584 + time_before(jiffies, state(hdlc)->last_poll + 585 + state(hdlc)->settings.t392 * HZ); 586 + state(hdlc)->request = 0; 645 587 } else { 646 - hdlc->state.fr.last_errors <<= 1; /* Shift the list */ 647 - if (hdlc->state.fr.request) { 648 - if (hdlc->state.fr.reliable) 588 + state(hdlc)->last_errors <<= 1; /* Shift the list */ 589 + if (state(hdlc)->request) { 590 + if (state(hdlc)->reliable) 649 591 printk(KERN_INFO "%s: No LMI status reply " 650 592 "received\n", dev->name); 651 - hdlc->state.fr.last_errors |= 1; 593 + state(hdlc)->last_errors |= 1; 652 594 } 653 595 654 - list = hdlc->state.fr.last_errors; 655 - for (i = 0; i < hdlc->state.fr.settings.n393; i++, list >>= 1) 596 + list = state(hdlc)->last_errors; 597 + for (i = 0; i < state(hdlc)->settings.n393; i++, list >>= 1) 656 598 cnt += (list & 1); /* errors count */ 657 599 658 - reliable = (cnt < hdlc->state.fr.settings.n392); 600 + reliable = (cnt < state(hdlc)->settings.n392); 659 601 } 660 602 661 - if (hdlc->state.fr.reliable != reliable) { 603 + if (state(hdlc)->reliable != reliable) { 662 604 printk(KERN_INFO "%s: Link %sreliable\n", dev->name, 663 605 reliable ? "" : "un"); 664 606 fr_set_link_state(reliable, dev); 665 607 } 666 608 667 - if (hdlc->state.fr.settings.dce) 668 - hdlc->state.fr.timer.expires = jiffies + 669 - hdlc->state.fr.settings.t392 * HZ; 609 + if (state(hdlc)->settings.dce) 610 + state(hdlc)->timer.expires = jiffies + 611 + state(hdlc)->settings.t392 * HZ; 670 612 else { 671 - if (hdlc->state.fr.n391cnt) 672 - hdlc->state.fr.n391cnt--; 613 + if (state(hdlc)->n391cnt) 614 + state(hdlc)->n391cnt--; 673 615 674 - fr_lmi_send(dev, hdlc->state.fr.n391cnt == 0); 616 + fr_lmi_send(dev, state(hdlc)->n391cnt == 0); 675 617 676 - hdlc->state.fr.last_poll = jiffies; 677 - hdlc->state.fr.request = 1; 678 - hdlc->state.fr.timer.expires = jiffies + 679 - hdlc->state.fr.settings.t391 * HZ; 618 + state(hdlc)->last_poll = jiffies; 619 + state(hdlc)->request = 1; 620 + state(hdlc)->timer.expires = jiffies + 621 + state(hdlc)->settings.t391 * HZ; 680 622 } 681 623 682 - hdlc->state.fr.timer.function = fr_timer; 683 - hdlc->state.fr.timer.data = arg; 684 - add_timer(&hdlc->state.fr.timer); 624 + state(hdlc)->timer.function = fr_timer; 625 + state(hdlc)->timer.data = arg; 626 + add_timer(&state(hdlc)->timer); 685 627 } 686 - 687 628 688 629 689 630 static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) ··· 690 633 hdlc_device *hdlc = dev_to_hdlc(dev); 691 634 pvc_device *pvc; 692 635 u8 rxseq, txseq; 693 - int lmi = hdlc->state.fr.settings.lmi; 694 - int dce = hdlc->state.fr.settings.dce; 636 + int lmi = state(hdlc)->settings.lmi; 637 + int dce = state(hdlc)->settings.dce; 695 638 int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i; 696 639 697 640 if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH : ··· 702 645 703 646 if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI : 704 647 NLPID_CCITT_ANSI_LMI)) { 705 - printk(KERN_INFO "%s: Received non-LMI frame with LMI" 706 - " DLCI\n", dev->name); 648 + printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n", 649 + dev->name); 707 650 return 1; 708 651 } 709 652 ··· 763 706 } 764 707 i++; 765 708 766 - hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */ 709 + state(hdlc)->rxseq = skb->data[i++]; /* TX sequence from peer */ 767 710 rxseq = skb->data[i++]; /* Should confirm our sequence */ 768 711 769 - txseq = hdlc->state.fr.txseq; 712 + txseq = state(hdlc)->txseq; 770 713 771 714 if (dce) 772 - hdlc->state.fr.last_poll = jiffies; 715 + state(hdlc)->last_poll = jiffies; 773 716 774 717 error = 0; 775 - if (!hdlc->state.fr.reliable) 718 + if (!state(hdlc)->reliable) 776 719 error = 1; 777 720 778 - if (rxseq == 0 || rxseq != txseq) { 779 - hdlc->state.fr.n391cnt = 0; /* Ask for full report next time */ 721 + if (rxseq == 0 || rxseq != txseq) { /* Ask for full report next time */ 722 + state(hdlc)->n391cnt = 0; 780 723 error = 1; 781 724 } 782 725 783 726 if (dce) { 784 - if (hdlc->state.fr.fullrep_sent && !error) { 727 + if (state(hdlc)->fullrep_sent && !error) { 785 728 /* Stop sending full report - the last one has been confirmed by DTE */ 786 - hdlc->state.fr.fullrep_sent = 0; 787 - pvc = hdlc->state.fr.first_pvc; 729 + state(hdlc)->fullrep_sent = 0; 730 + pvc = state(hdlc)->first_pvc; 788 731 while (pvc) { 789 732 if (pvc->state.new) { 790 733 pvc->state.new = 0; 791 734 792 735 /* Tell DTE that new PVC is now active */ 793 - hdlc->state.fr.dce_changed = 1; 736 + state(hdlc)->dce_changed = 1; 794 737 } 795 738 pvc = pvc->next; 796 739 } 797 740 } 798 741 799 - if (hdlc->state.fr.dce_changed) { 742 + if (state(hdlc)->dce_changed) { 800 743 reptype = LMI_FULLREP; 801 - hdlc->state.fr.fullrep_sent = 1; 802 - hdlc->state.fr.dce_changed = 0; 744 + state(hdlc)->fullrep_sent = 1; 745 + state(hdlc)->dce_changed = 0; 803 746 } 804 747 805 - hdlc->state.fr.request = 1; /* got request */ 748 + state(hdlc)->request = 1; /* got request */ 806 749 fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); 807 750 return 0; 808 751 } 809 752 810 753 /* DTE */ 811 754 812 - hdlc->state.fr.request = 0; /* got response, no request pending */ 755 + state(hdlc)->request = 0; /* got response, no request pending */ 813 756 814 757 if (error) 815 758 return 0; ··· 817 760 if (reptype != LMI_FULLREP) 818 761 return 0; 819 762 820 - pvc = hdlc->state.fr.first_pvc; 763 + pvc = state(hdlc)->first_pvc; 821 764 822 765 while (pvc) { 823 766 pvc->state.deleted = 1; ··· 884 827 i += stat_len; 885 828 } 886 829 887 - pvc = hdlc->state.fr.first_pvc; 830 + pvc = state(hdlc)->first_pvc; 888 831 889 832 while (pvc) { 890 833 if (pvc->state.deleted && pvc->state.exist) { ··· 898 841 } 899 842 900 843 /* Next full report after N391 polls */ 901 - hdlc->state.fr.n391cnt = hdlc->state.fr.settings.n391; 844 + state(hdlc)->n391cnt = state(hdlc)->settings.n391; 902 845 903 846 return 0; 904 847 } 905 848 906 849 907 - 908 850 static int fr_rx(struct sk_buff *skb) 909 851 { 910 - struct net_device *ndev = skb->dev; 911 - hdlc_device *hdlc = dev_to_hdlc(ndev); 852 + struct net_device *frad = skb->dev; 853 + hdlc_device *hdlc = dev_to_hdlc(frad); 912 854 fr_hdr *fh = (fr_hdr*)skb->data; 913 855 u8 *data = skb->data; 914 856 u16 dlci; ··· 920 864 dlci = q922_to_dlci(skb->data); 921 865 922 866 if ((dlci == LMI_CCITT_ANSI_DLCI && 923 - (hdlc->state.fr.settings.lmi == LMI_ANSI || 924 - hdlc->state.fr.settings.lmi == LMI_CCITT)) || 867 + (state(hdlc)->settings.lmi == LMI_ANSI || 868 + state(hdlc)->settings.lmi == LMI_CCITT)) || 925 869 (dlci == LMI_CISCO_DLCI && 926 - hdlc->state.fr.settings.lmi == LMI_CISCO)) { 927 - if (fr_lmi_recv(ndev, skb)) 870 + state(hdlc)->settings.lmi == LMI_CISCO)) { 871 + if (fr_lmi_recv(frad, skb)) 928 872 goto rx_error; 929 873 dev_kfree_skb_any(skb); 930 874 return NET_RX_SUCCESS; ··· 934 878 if (!pvc) { 935 879 #ifdef DEBUG_PKT 936 880 printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", 937 - ndev->name, dlci); 881 + frad->name, dlci); 938 882 #endif 939 883 dev_kfree_skb_any(skb); 940 884 return NET_RX_DROP; ··· 942 886 943 887 if (pvc->state.fecn != fh->fecn) { 944 888 #ifdef DEBUG_ECN 945 - printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", ndev->name, 889 + printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", frad->name, 946 890 dlci, fh->fecn ? "N" : "FF"); 947 891 #endif 948 892 pvc->state.fecn ^= 1; ··· 950 894 951 895 if (pvc->state.becn != fh->becn) { 952 896 #ifdef DEBUG_ECN 953 - printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", ndev->name, 897 + printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", frad->name, 954 898 dlci, fh->becn ? "N" : "FF"); 955 899 #endif 956 900 pvc->state.becn ^= 1; ··· 958 902 959 903 960 904 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 961 - hdlc->stats.rx_dropped++; 905 + dev_to_desc(frad)->stats.rx_dropped++; 962 906 return NET_RX_DROP; 963 907 } 964 908 ··· 994 938 995 939 default: 996 940 printk(KERN_INFO "%s: Unsupported protocol, OUI=%x " 997 - "PID=%x\n", ndev->name, oui, pid); 941 + "PID=%x\n", frad->name, oui, pid); 998 942 dev_kfree_skb_any(skb); 999 943 return NET_RX_DROP; 1000 944 } 1001 945 } else { 1002 946 printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x " 1003 - "length = %i\n", ndev->name, data[3], skb->len); 947 + "length = %i\n", frad->name, data[3], skb->len); 1004 948 dev_kfree_skb_any(skb); 1005 949 return NET_RX_DROP; 1006 950 } ··· 1020 964 } 1021 965 1022 966 rx_error: 1023 - hdlc->stats.rx_errors++; /* Mark error */ 967 + dev_to_desc(frad)->stats.rx_errors++; /* Mark error */ 1024 968 dev_kfree_skb_any(skb); 1025 969 return NET_RX_DROP; 1026 970 } ··· 1033 977 #ifdef DEBUG_LINK 1034 978 printk(KERN_DEBUG "fr_start\n"); 1035 979 #endif 1036 - if (hdlc->state.fr.settings.lmi != LMI_NONE) { 1037 - hdlc->state.fr.reliable = 0; 1038 - hdlc->state.fr.dce_changed = 1; 1039 - hdlc->state.fr.request = 0; 1040 - hdlc->state.fr.fullrep_sent = 0; 1041 - hdlc->state.fr.last_errors = 0xFFFFFFFF; 1042 - hdlc->state.fr.n391cnt = 0; 1043 - hdlc->state.fr.txseq = hdlc->state.fr.rxseq = 0; 980 + if (state(hdlc)->settings.lmi != LMI_NONE) { 981 + state(hdlc)->reliable = 0; 982 + state(hdlc)->dce_changed = 1; 983 + state(hdlc)->request = 0; 984 + state(hdlc)->fullrep_sent = 0; 985 + state(hdlc)->last_errors = 0xFFFFFFFF; 986 + state(hdlc)->n391cnt = 0; 987 + state(hdlc)->txseq = state(hdlc)->rxseq = 0; 1044 988 1045 - init_timer(&hdlc->state.fr.timer); 989 + init_timer(&state(hdlc)->timer); 1046 990 /* First poll after 1 s */ 1047 - hdlc->state.fr.timer.expires = jiffies + HZ; 1048 - hdlc->state.fr.timer.function = fr_timer; 1049 - hdlc->state.fr.timer.data = (unsigned long)dev; 1050 - add_timer(&hdlc->state.fr.timer); 991 + state(hdlc)->timer.expires = jiffies + HZ; 992 + state(hdlc)->timer.function = fr_timer; 993 + state(hdlc)->timer.data = (unsigned long)dev; 994 + add_timer(&state(hdlc)->timer); 1051 995 } else 1052 996 fr_set_link_state(1, dev); 1053 997 } 1054 - 1055 998 1056 999 1057 1000 static void fr_stop(struct net_device *dev) ··· 1059 1004 #ifdef DEBUG_LINK 1060 1005 printk(KERN_DEBUG "fr_stop\n"); 1061 1006 #endif 1062 - if (hdlc->state.fr.settings.lmi != LMI_NONE) 1063 - del_timer_sync(&hdlc->state.fr.timer); 1007 + if (state(hdlc)->settings.lmi != LMI_NONE) 1008 + del_timer_sync(&state(hdlc)->timer); 1064 1009 fr_set_link_state(0, dev); 1065 1010 } 1066 - 1067 1011 1068 1012 1069 1013 static void fr_close(struct net_device *dev) 1070 1014 { 1071 1015 hdlc_device *hdlc = dev_to_hdlc(dev); 1072 - pvc_device *pvc = hdlc->state.fr.first_pvc; 1016 + pvc_device *pvc = state(hdlc)->first_pvc; 1073 1017 1074 1018 while (pvc) { /* Shutdown all PVCs for this FRAD */ 1075 1019 if (pvc->main) ··· 1079 1025 } 1080 1026 } 1081 1027 1082 - static void dlci_setup(struct net_device *dev) 1028 + 1029 + static void pvc_setup(struct net_device *dev) 1083 1030 { 1084 1031 dev->type = ARPHRD_DLCI; 1085 1032 dev->flags = IFF_POINTOPOINT; ··· 1088 1033 dev->addr_len = 2; 1089 1034 } 1090 1035 1091 - static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type) 1036 + static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) 1092 1037 { 1093 - hdlc_device *hdlc = dev_to_hdlc(master); 1038 + hdlc_device *hdlc = dev_to_hdlc(frad); 1094 1039 pvc_device *pvc = NULL; 1095 1040 struct net_device *dev; 1096 1041 int result, used; ··· 1099 1044 if (type == ARPHRD_ETHER) 1100 1045 prefix = "pvceth%d"; 1101 1046 1102 - if ((pvc = add_pvc(master, dlci)) == NULL) { 1047 + if ((pvc = add_pvc(frad, dlci)) == NULL) { 1103 1048 printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", 1104 - master->name); 1049 + frad->name); 1105 1050 return -ENOBUFS; 1106 1051 } 1107 1052 ··· 1115 1060 "pvceth%d", ether_setup); 1116 1061 else 1117 1062 dev = alloc_netdev(sizeof(struct net_device_stats), 1118 - "pvc%d", dlci_setup); 1063 + "pvc%d", pvc_setup); 1119 1064 1120 1065 if (!dev) { 1121 1066 printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", 1122 - master->name); 1067 + frad->name); 1123 1068 delete_unused_pvcs(hdlc); 1124 1069 return -ENOBUFS; 1125 1070 } ··· 1157 1102 dev->destructor = free_netdev; 1158 1103 *get_dev_p(pvc, type) = dev; 1159 1104 if (!used) { 1160 - hdlc->state.fr.dce_changed = 1; 1161 - hdlc->state.fr.dce_pvc_count++; 1105 + state(hdlc)->dce_changed = 1; 1106 + state(hdlc)->dce_pvc_count++; 1162 1107 } 1163 1108 return 0; 1164 1109 } ··· 1183 1128 *get_dev_p(pvc, type) = NULL; 1184 1129 1185 1130 if (!pvc_is_used(pvc)) { 1186 - hdlc->state.fr.dce_pvc_count--; 1187 - hdlc->state.fr.dce_changed = 1; 1131 + state(hdlc)->dce_pvc_count--; 1132 + state(hdlc)->dce_changed = 1; 1188 1133 } 1189 1134 delete_unused_pvcs(hdlc); 1190 1135 return 0; ··· 1192 1137 1193 1138 1194 1139 1195 - static void fr_destroy(hdlc_device *hdlc) 1140 + static void fr_destroy(struct net_device *frad) 1196 1141 { 1197 - pvc_device *pvc; 1198 - 1199 - pvc = hdlc->state.fr.first_pvc; 1200 - hdlc->state.fr.first_pvc = NULL; /* All PVCs destroyed */ 1201 - hdlc->state.fr.dce_pvc_count = 0; 1202 - hdlc->state.fr.dce_changed = 1; 1142 + hdlc_device *hdlc = dev_to_hdlc(frad); 1143 + pvc_device *pvc = state(hdlc)->first_pvc; 1144 + state(hdlc)->first_pvc = NULL; /* All PVCs destroyed */ 1145 + state(hdlc)->dce_pvc_count = 0; 1146 + state(hdlc)->dce_changed = 1; 1203 1147 1204 1148 while (pvc) { 1205 1149 pvc_device *next = pvc->next; ··· 1215 1161 } 1216 1162 1217 1163 1164 + static struct hdlc_proto proto = { 1165 + .close = fr_close, 1166 + .start = fr_start, 1167 + .stop = fr_stop, 1168 + .detach = fr_destroy, 1169 + .ioctl = fr_ioctl, 1170 + .module = THIS_MODULE, 1171 + }; 1218 1172 1219 - int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) 1173 + 1174 + static int fr_ioctl(struct net_device *dev, struct ifreq *ifr) 1220 1175 { 1221 1176 fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr; 1222 1177 const size_t size = sizeof(fr_proto); ··· 1236 1173 1237 1174 switch (ifr->ifr_settings.type) { 1238 1175 case IF_GET_PROTO: 1176 + if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */ 1177 + return -EINVAL; 1239 1178 ifr->ifr_settings.type = IF_PROTO_FR; 1240 1179 if (ifr->ifr_settings.size < size) { 1241 1180 ifr->ifr_settings.size = size; /* data size wanted */ 1242 1181 return -ENOBUFS; 1243 1182 } 1244 - if (copy_to_user(fr_s, &hdlc->state.fr.settings, size)) 1183 + if (copy_to_user(fr_s, &state(hdlc)->settings, size)) 1245 1184 return -EFAULT; 1246 1185 return 0; 1247 1186 ··· 1278 1213 if (result) 1279 1214 return result; 1280 1215 1281 - if (hdlc->proto.id != IF_PROTO_FR) { 1282 - hdlc_proto_detach(hdlc); 1283 - hdlc->state.fr.first_pvc = NULL; 1284 - hdlc->state.fr.dce_pvc_count = 0; 1216 + if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */ 1217 + result = attach_hdlc_protocol(dev, &proto, fr_rx, 1218 + sizeof(struct frad_state)); 1219 + if (result) 1220 + return result; 1221 + state(hdlc)->first_pvc = NULL; 1222 + state(hdlc)->dce_pvc_count = 0; 1285 1223 } 1286 - memcpy(&hdlc->state.fr.settings, &new_settings, size); 1287 - memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 1224 + memcpy(&state(hdlc)->settings, &new_settings, size); 1288 1225 1289 - hdlc->proto.close = fr_close; 1290 - hdlc->proto.start = fr_start; 1291 - hdlc->proto.stop = fr_stop; 1292 - hdlc->proto.detach = fr_destroy; 1293 - hdlc->proto.netif_rx = fr_rx; 1294 - hdlc->proto.id = IF_PROTO_FR; 1295 1226 dev->hard_start_xmit = hdlc->xmit; 1296 1227 dev->hard_header = NULL; 1297 1228 dev->type = ARPHRD_FRAD; ··· 1299 1238 case IF_PROTO_FR_DEL_PVC: 1300 1239 case IF_PROTO_FR_ADD_ETH_PVC: 1301 1240 case IF_PROTO_FR_DEL_ETH_PVC: 1241 + if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */ 1242 + return -EINVAL; 1243 + 1302 1244 if(!capable(CAP_NET_ADMIN)) 1303 1245 return -EPERM; 1304 1246 ··· 1327 1263 1328 1264 return -EINVAL; 1329 1265 } 1266 + 1267 + 1268 + static int __init mod_init(void) 1269 + { 1270 + register_hdlc_protocol(&proto); 1271 + return 0; 1272 + } 1273 + 1274 + 1275 + static void __exit mod_exit(void) 1276 + { 1277 + unregister_hdlc_protocol(&proto); 1278 + } 1279 + 1280 + 1281 + module_init(mod_init); 1282 + module_exit(mod_exit); 1283 + 1284 + MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 1285 + MODULE_DESCRIPTION("Frame-Relay protocol support for generic HDLC"); 1286 + MODULE_LICENSE("GPL v2");
+99 -70
drivers/net/wan/hdlc_generic.c drivers/net/wan/hdlc.c
··· 1 1 /* 2 2 * Generic HDLC support routines for Linux 3 3 * 4 - * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> 4 + * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify it 7 7 * under the terms of version 2 of the GNU General Public License ··· 17 17 * Use sethdlc utility to set line parameters, protocol and PVCs 18 18 * 19 19 * How does it work: 20 - * - proto.open(), close(), start(), stop() calls are serialized. 20 + * - proto->open(), close(), start(), stop() calls are serialized. 21 21 * The order is: open, [ start, stop ... ] close ... 22 - * - proto.start() and stop() are called with spin_lock_irq held. 22 + * - proto->start() and stop() are called with spin_lock_irq held. 23 23 */ 24 24 25 25 #include <linux/module.h> ··· 38 38 #include <linux/hdlc.h> 39 39 40 40 41 - static const char* version = "HDLC support module revision 1.19"; 41 + static const char* version = "HDLC support module revision 1.20"; 42 42 43 43 #undef DEBUG_LINK 44 + 45 + static struct hdlc_proto *first_proto = NULL; 44 46 45 47 46 48 static int hdlc_change_mtu(struct net_device *dev, int new_mtu) ··· 65 63 static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, 66 64 struct packet_type *p, struct net_device *orig_dev) 67 65 { 68 - hdlc_device *hdlc = dev_to_hdlc(dev); 69 - if (hdlc->proto.netif_rx) 70 - return hdlc->proto.netif_rx(skb); 66 + struct hdlc_device_desc *desc = dev_to_desc(dev); 67 + if (desc->netif_rx) 68 + return desc->netif_rx(skb); 71 69 72 - hdlc->stats.rx_dropped++; /* Shouldn't happen */ 70 + desc->stats.rx_dropped++; /* Shouldn't happen */ 73 71 dev_kfree_skb(skb); 74 72 return NET_RX_DROP; 75 73 } ··· 79 77 static inline void hdlc_proto_start(struct net_device *dev) 80 78 { 81 79 hdlc_device *hdlc = dev_to_hdlc(dev); 82 - if (hdlc->proto.start) 83 - return hdlc->proto.start(dev); 80 + if (hdlc->proto->start) 81 + return hdlc->proto->start(dev); 84 82 } 85 83 86 84 ··· 88 86 static inline void hdlc_proto_stop(struct net_device *dev) 89 87 { 90 88 hdlc_device *hdlc = dev_to_hdlc(dev); 91 - if (hdlc->proto.stop) 92 - return hdlc->proto.stop(dev); 89 + if (hdlc->proto->stop) 90 + return hdlc->proto->stop(dev); 93 91 } 94 92 95 93 ··· 146 144 { 147 145 hdlc_device *hdlc = dev_to_hdlc(dev); 148 146 #ifdef DEBUG_LINK 149 - printk(KERN_DEBUG "hdlc_open() carrier %i open %i\n", 147 + printk(KERN_DEBUG "%s: hdlc_open() carrier %i open %i\n", dev->name, 150 148 hdlc->carrier, hdlc->open); 151 149 #endif 152 150 153 - if (hdlc->proto.id == -1) 151 + if (hdlc->proto == NULL) 154 152 return -ENOSYS; /* no protocol attached */ 155 153 156 - if (hdlc->proto.open) { 157 - int result = hdlc->proto.open(dev); 154 + if (hdlc->proto->open) { 155 + int result = hdlc->proto->open(dev); 158 156 if (result) 159 157 return result; 160 158 } ··· 180 178 { 181 179 hdlc_device *hdlc = dev_to_hdlc(dev); 182 180 #ifdef DEBUG_LINK 183 - printk(KERN_DEBUG "hdlc_close() carrier %i open %i\n", 181 + printk(KERN_DEBUG "%s: hdlc_close() carrier %i open %i\n", dev->name, 184 182 hdlc->carrier, hdlc->open); 185 183 #endif 186 184 ··· 192 190 193 191 spin_unlock_irq(&hdlc->state_lock); 194 192 195 - if (hdlc->proto.close) 196 - hdlc->proto.close(dev); 193 + if (hdlc->proto->close) 194 + hdlc->proto->close(dev); 197 195 } 198 196 199 197 200 198 201 - #ifndef CONFIG_HDLC_RAW 202 - #define hdlc_raw_ioctl(dev, ifr) -ENOSYS 203 - #endif 204 - 205 - #ifndef CONFIG_HDLC_RAW_ETH 206 - #define hdlc_raw_eth_ioctl(dev, ifr) -ENOSYS 207 - #endif 208 - 209 - #ifndef CONFIG_HDLC_PPP 210 - #define hdlc_ppp_ioctl(dev, ifr) -ENOSYS 211 - #endif 212 - 213 - #ifndef CONFIG_HDLC_CISCO 214 - #define hdlc_cisco_ioctl(dev, ifr) -ENOSYS 215 - #endif 216 - 217 - #ifndef CONFIG_HDLC_FR 218 - #define hdlc_fr_ioctl(dev, ifr) -ENOSYS 219 - #endif 220 - 221 - #ifndef CONFIG_HDLC_X25 222 - #define hdlc_x25_ioctl(dev, ifr) -ENOSYS 223 - #endif 224 - 225 - 226 199 int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 227 200 { 228 - hdlc_device *hdlc = dev_to_hdlc(dev); 229 - unsigned int proto; 201 + struct hdlc_proto *proto = first_proto; 202 + int result; 230 203 231 204 if (cmd != SIOCWANDEV) 232 205 return -EINVAL; 233 206 234 - switch(ifr->ifr_settings.type) { 235 - case IF_PROTO_HDLC: 236 - case IF_PROTO_HDLC_ETH: 237 - case IF_PROTO_PPP: 238 - case IF_PROTO_CISCO: 239 - case IF_PROTO_FR: 240 - case IF_PROTO_X25: 241 - proto = ifr->ifr_settings.type; 242 - break; 243 - 244 - default: 245 - proto = hdlc->proto.id; 207 + if (dev_to_hdlc(dev)->proto) { 208 + result = dev_to_hdlc(dev)->proto->ioctl(dev, ifr); 209 + if (result != -EINVAL) 210 + return result; 246 211 } 247 212 248 - switch(proto) { 249 - case IF_PROTO_HDLC: return hdlc_raw_ioctl(dev, ifr); 250 - case IF_PROTO_HDLC_ETH: return hdlc_raw_eth_ioctl(dev, ifr); 251 - case IF_PROTO_PPP: return hdlc_ppp_ioctl(dev, ifr); 252 - case IF_PROTO_CISCO: return hdlc_cisco_ioctl(dev, ifr); 253 - case IF_PROTO_FR: return hdlc_fr_ioctl(dev, ifr); 254 - case IF_PROTO_X25: return hdlc_x25_ioctl(dev, ifr); 255 - default: return -EINVAL; 213 + /* Not handled by currently attached protocol (if any) */ 214 + 215 + while (proto) { 216 + if ((result = proto->ioctl(dev, ifr)) != -EINVAL) 217 + return result; 218 + proto = proto->next; 256 219 } 220 + return -EINVAL; 257 221 } 258 222 259 223 void hdlc_setup(struct net_device *dev) ··· 235 267 236 268 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 237 269 238 - hdlc->proto.id = -1; 239 - hdlc->proto.detach = NULL; 240 270 hdlc->carrier = 1; 241 271 hdlc->open = 0; 242 272 spin_lock_init(&hdlc->state_lock); ··· 243 277 struct net_device *alloc_hdlcdev(void *priv) 244 278 { 245 279 struct net_device *dev; 246 - dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d", hdlc_setup); 280 + dev = alloc_netdev(sizeof(struct hdlc_device_desc) + 281 + sizeof(hdlc_device), "hdlc%d", hdlc_setup); 247 282 if (dev) 248 283 dev_to_hdlc(dev)->priv = priv; 249 284 return dev; ··· 253 286 void unregister_hdlc_device(struct net_device *dev) 254 287 { 255 288 rtnl_lock(); 256 - hdlc_proto_detach(dev_to_hdlc(dev)); 257 289 unregister_netdevice(dev); 290 + detach_hdlc_protocol(dev); 258 291 rtnl_unlock(); 292 + } 293 + 294 + 295 + 296 + int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, 297 + int (*rx)(struct sk_buff *skb), size_t size) 298 + { 299 + detach_hdlc_protocol(dev); 300 + 301 + if (!try_module_get(proto->module)) 302 + return -ENOSYS; 303 + 304 + if (size) 305 + if ((dev_to_hdlc(dev)->state = kmalloc(size, 306 + GFP_KERNEL)) == NULL) { 307 + printk(KERN_WARNING "Memory squeeze on" 308 + " hdlc_proto_attach()\n"); 309 + module_put(proto->module); 310 + return -ENOBUFS; 311 + } 312 + dev_to_hdlc(dev)->proto = proto; 313 + dev_to_desc(dev)->netif_rx = rx; 314 + return 0; 315 + } 316 + 317 + 318 + void detach_hdlc_protocol(struct net_device *dev) 319 + { 320 + hdlc_device *hdlc = dev_to_hdlc(dev); 321 + 322 + if (hdlc->proto) { 323 + if (hdlc->proto->detach) 324 + hdlc->proto->detach(dev); 325 + module_put(hdlc->proto->module); 326 + hdlc->proto = NULL; 327 + } 328 + kfree(hdlc->state); 329 + hdlc->state = NULL; 330 + } 331 + 332 + 333 + void register_hdlc_protocol(struct hdlc_proto *proto) 334 + { 335 + proto->next = first_proto; 336 + first_proto = proto; 337 + } 338 + 339 + 340 + void unregister_hdlc_protocol(struct hdlc_proto *proto) 341 + { 342 + struct hdlc_proto **p = &first_proto; 343 + while (*p) { 344 + if (*p == proto) { 345 + *p = proto->next; 346 + return; 347 + } 348 + p = &((*p)->next); 349 + } 259 350 } 260 351 261 352 ··· 328 303 EXPORT_SYMBOL(hdlc_setup); 329 304 EXPORT_SYMBOL(alloc_hdlcdev); 330 305 EXPORT_SYMBOL(unregister_hdlc_device); 306 + EXPORT_SYMBOL(register_hdlc_protocol); 307 + EXPORT_SYMBOL(unregister_hdlc_protocol); 308 + EXPORT_SYMBOL(attach_hdlc_protocol); 309 + EXPORT_SYMBOL(detach_hdlc_protocol); 331 310 332 311 static struct packet_type hdlc_packet_type = { 333 312 .type = __constant_htons(ETH_P_HDLC),
+61 -16
drivers/net/wan/hdlc_ppp.c
··· 2 2 * Generic HDLC support routines for Linux 3 3 * Point-to-point protocol support 4 4 * 5 - * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 + * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify it 8 8 * under the terms of version 2 of the GNU General Public License ··· 22 22 #include <linux/lapb.h> 23 23 #include <linux/rtnetlink.h> 24 24 #include <linux/hdlc.h> 25 + #include <net/syncppp.h> 26 + 27 + struct ppp_state { 28 + struct ppp_device pppdev; 29 + struct ppp_device *syncppp_ptr; 30 + int (*old_change_mtu)(struct net_device *dev, int new_mtu); 31 + }; 32 + 33 + static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr); 34 + 35 + 36 + static inline struct ppp_state* state(hdlc_device *hdlc) 37 + { 38 + return(struct ppp_state *)(hdlc->state); 39 + } 25 40 26 41 27 42 static int ppp_open(struct net_device *dev) ··· 45 30 void *old_ioctl; 46 31 int result; 47 32 48 - dev->priv = &hdlc->state.ppp.syncppp_ptr; 49 - hdlc->state.ppp.syncppp_ptr = &hdlc->state.ppp.pppdev; 50 - hdlc->state.ppp.pppdev.dev = dev; 33 + dev->priv = &state(hdlc)->syncppp_ptr; 34 + state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev; 35 + state(hdlc)->pppdev.dev = dev; 51 36 52 37 old_ioctl = dev->do_ioctl; 53 - hdlc->state.ppp.old_change_mtu = dev->change_mtu; 54 - sppp_attach(&hdlc->state.ppp.pppdev); 38 + state(hdlc)->old_change_mtu = dev->change_mtu; 39 + sppp_attach(&state(hdlc)->pppdev); 55 40 /* sppp_attach nukes them. We don't need syncppp's ioctl */ 56 41 dev->do_ioctl = old_ioctl; 57 - hdlc->state.ppp.pppdev.sppp.pp_flags &= ~PP_CISCO; 42 + state(hdlc)->pppdev.sppp.pp_flags &= ~PP_CISCO; 58 43 dev->type = ARPHRD_PPP; 59 44 result = sppp_open(dev); 60 45 if (result) { ··· 74 59 sppp_close(dev); 75 60 sppp_detach(dev); 76 61 dev->rebuild_header = NULL; 77 - dev->change_mtu = hdlc->state.ppp.old_change_mtu; 62 + dev->change_mtu = state(hdlc)->old_change_mtu; 78 63 dev->mtu = HDLC_MAX_MTU; 79 64 dev->hard_header_len = 16; 80 65 } ··· 88 73 89 74 90 75 91 - int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) 76 + static struct hdlc_proto proto = { 77 + .open = ppp_open, 78 + .close = ppp_close, 79 + .type_trans = ppp_type_trans, 80 + .ioctl = ppp_ioctl, 81 + .module = THIS_MODULE, 82 + }; 83 + 84 + 85 + static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr) 92 86 { 93 87 hdlc_device *hdlc = dev_to_hdlc(dev); 94 88 int result; 95 89 96 90 switch (ifr->ifr_settings.type) { 97 91 case IF_GET_PROTO: 92 + if (dev_to_hdlc(dev)->proto != &proto) 93 + return -EINVAL; 98 94 ifr->ifr_settings.type = IF_PROTO_PPP; 99 95 return 0; /* return protocol only, no settable parameters */ 100 96 ··· 122 96 if (result) 123 97 return result; 124 98 125 - hdlc_proto_detach(hdlc); 126 - memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 127 - 128 - hdlc->proto.open = ppp_open; 129 - hdlc->proto.close = ppp_close; 130 - hdlc->proto.type_trans = ppp_type_trans; 131 - hdlc->proto.id = IF_PROTO_PPP; 99 + result = attach_hdlc_protocol(dev, &proto, NULL, 100 + sizeof(struct ppp_state)); 101 + if (result) 102 + return result; 132 103 dev->hard_start_xmit = hdlc->xmit; 133 104 dev->hard_header = NULL; 134 105 dev->type = ARPHRD_PPP; ··· 136 113 137 114 return -EINVAL; 138 115 } 116 + 117 + 118 + static int __init mod_init(void) 119 + { 120 + register_hdlc_protocol(&proto); 121 + return 0; 122 + } 123 + 124 + 125 + 126 + static void __exit mod_exit(void) 127 + { 128 + unregister_hdlc_protocol(&proto); 129 + } 130 + 131 + 132 + module_init(mod_init); 133 + module_exit(mod_exit); 134 + 135 + MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 136 + MODULE_DESCRIPTION("PPP protocol support for generic HDLC"); 137 + MODULE_LICENSE("GPL v2");
+41 -9
drivers/net/wan/hdlc_raw.c
··· 2 2 * Generic HDLC support routines for Linux 3 3 * HDLC support 4 4 * 5 - * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 + * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify it 8 8 * under the terms of version 2 of the GNU General Public License ··· 24 24 #include <linux/hdlc.h> 25 25 26 26 27 + static int raw_ioctl(struct net_device *dev, struct ifreq *ifr); 28 + 27 29 static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev) 28 30 { 29 31 return __constant_htons(ETH_P_IP); ··· 33 31 34 32 35 33 36 - int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) 34 + static struct hdlc_proto proto = { 35 + .type_trans = raw_type_trans, 36 + .ioctl = raw_ioctl, 37 + .module = THIS_MODULE, 38 + }; 39 + 40 + 41 + static int raw_ioctl(struct net_device *dev, struct ifreq *ifr) 37 42 { 38 43 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; 39 44 const size_t size = sizeof(raw_hdlc_proto); ··· 50 41 51 42 switch (ifr->ifr_settings.type) { 52 43 case IF_GET_PROTO: 44 + if (dev_to_hdlc(dev)->proto != &proto) 45 + return -EINVAL; 53 46 ifr->ifr_settings.type = IF_PROTO_HDLC; 54 47 if (ifr->ifr_settings.size < size) { 55 48 ifr->ifr_settings.size = size; /* data size wanted */ 56 49 return -ENOBUFS; 57 50 } 58 - if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) 51 + if (copy_to_user(raw_s, hdlc->state, size)) 59 52 return -EFAULT; 60 53 return 0; 61 54 ··· 82 71 if (result) 83 72 return result; 84 73 85 - hdlc_proto_detach(hdlc); 86 - memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); 87 - memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 88 - 89 - hdlc->proto.type_trans = raw_type_trans; 90 - hdlc->proto.id = IF_PROTO_HDLC; 74 + result = attach_hdlc_protocol(dev, &proto, NULL, 75 + sizeof(raw_hdlc_proto)); 76 + if (result) 77 + return result; 78 + memcpy(hdlc->state, &new_settings, size); 91 79 dev->hard_start_xmit = hdlc->xmit; 92 80 dev->hard_header = NULL; 93 81 dev->type = ARPHRD_RAWHDLC; ··· 98 88 99 89 return -EINVAL; 100 90 } 91 + 92 + 93 + static int __init mod_init(void) 94 + { 95 + register_hdlc_protocol(&proto); 96 + return 0; 97 + } 98 + 99 + 100 + 101 + static void __exit mod_exit(void) 102 + { 103 + unregister_hdlc_protocol(&proto); 104 + } 105 + 106 + 107 + module_init(mod_init); 108 + module_exit(mod_exit); 109 + 110 + MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 111 + MODULE_DESCRIPTION("Raw HDLC protocol support for generic HDLC"); 112 + MODULE_LICENSE("GPL v2");
+40 -9
drivers/net/wan/hdlc_raw_eth.c
··· 2 2 * Generic HDLC support routines for Linux 3 3 * HDLC Ethernet emulation support 4 4 * 5 - * Copyright (C) 2002-2003 Krzysztof Halasa <khc@pm.waw.pl> 5 + * Copyright (C) 2002-2006 Krzysztof Halasa <khc@pm.waw.pl> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify it 8 8 * under the terms of version 2 of the GNU General Public License ··· 25 25 #include <linux/etherdevice.h> 26 26 #include <linux/hdlc.h> 27 27 28 + static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr); 28 29 29 30 static int eth_tx(struct sk_buff *skb, struct net_device *dev) 30 31 { ··· 45 44 } 46 45 47 46 48 - int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) 47 + static struct hdlc_proto proto = { 48 + .type_trans = eth_type_trans, 49 + .ioctl = raw_eth_ioctl, 50 + .module = THIS_MODULE, 51 + }; 52 + 53 + 54 + static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) 49 55 { 50 56 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; 51 57 const size_t size = sizeof(raw_hdlc_proto); ··· 64 56 65 57 switch (ifr->ifr_settings.type) { 66 58 case IF_GET_PROTO: 59 + if (dev_to_hdlc(dev)->proto != &proto) 60 + return -EINVAL; 67 61 ifr->ifr_settings.type = IF_PROTO_HDLC_ETH; 68 62 if (ifr->ifr_settings.size < size) { 69 63 ifr->ifr_settings.size = size; /* data size wanted */ 70 64 return -ENOBUFS; 71 65 } 72 - if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) 66 + if (copy_to_user(raw_s, hdlc->state, size)) 73 67 return -EFAULT; 74 68 return 0; 75 69 ··· 96 86 if (result) 97 87 return result; 98 88 99 - hdlc_proto_detach(hdlc); 100 - memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); 101 - memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 102 - 103 - hdlc->proto.type_trans = eth_type_trans; 104 - hdlc->proto.id = IF_PROTO_HDLC_ETH; 89 + result = attach_hdlc_protocol(dev, &proto, NULL, 90 + sizeof(raw_hdlc_proto)); 91 + if (result) 92 + return result; 93 + memcpy(hdlc->state, &new_settings, size); 105 94 dev->hard_start_xmit = eth_tx; 106 95 old_ch_mtu = dev->change_mtu; 107 96 old_qlen = dev->tx_queue_len; ··· 115 106 116 107 return -EINVAL; 117 108 } 109 + 110 + 111 + static int __init mod_init(void) 112 + { 113 + register_hdlc_protocol(&proto); 114 + return 0; 115 + } 116 + 117 + 118 + 119 + static void __exit mod_exit(void) 120 + { 121 + unregister_hdlc_protocol(&proto); 122 + } 123 + 124 + 125 + module_init(mod_init); 126 + module_exit(mod_exit); 127 + 128 + MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 129 + MODULE_DESCRIPTION("Ethernet encapsulation support for generic HDLC"); 130 + MODULE_LICENSE("GPL v2");
+41 -13
drivers/net/wan/hdlc_x25.c
··· 2 2 * Generic HDLC support routines for Linux 3 3 * X.25 support 4 4 * 5 - * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 + * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify it 8 8 * under the terms of version 2 of the GNU General Public License ··· 24 24 #include <linux/hdlc.h> 25 25 26 26 #include <net/x25device.h> 27 + 28 + static int x25_ioctl(struct net_device *dev, struct ifreq *ifr); 27 29 28 30 /* These functions are callbacks called by LAPB layer */ 29 31 ··· 164 162 165 163 static int x25_rx(struct sk_buff *skb) 166 164 { 167 - hdlc_device *hdlc = dev_to_hdlc(skb->dev); 165 + struct hdlc_device_desc *desc = dev_to_desc(skb->dev); 168 166 169 167 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 170 - hdlc->stats.rx_dropped++; 168 + desc->stats.rx_dropped++; 171 169 return NET_RX_DROP; 172 170 } 173 171 174 172 if (lapb_data_received(skb->dev, skb) == LAPB_OK) 175 173 return NET_RX_SUCCESS; 176 174 177 - hdlc->stats.rx_errors++; 175 + desc->stats.rx_errors++; 178 176 dev_kfree_skb_any(skb); 179 177 return NET_RX_DROP; 180 178 } 181 179 182 180 181 + static struct hdlc_proto proto = { 182 + .open = x25_open, 183 + .close = x25_close, 184 + .ioctl = x25_ioctl, 185 + .module = THIS_MODULE, 186 + }; 183 187 184 - int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr) 188 + 189 + static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) 185 190 { 186 191 hdlc_device *hdlc = dev_to_hdlc(dev); 187 192 int result; 188 193 189 194 switch (ifr->ifr_settings.type) { 190 195 case IF_GET_PROTO: 196 + if (dev_to_hdlc(dev)->proto != &proto) 197 + return -EINVAL; 191 198 ifr->ifr_settings.type = IF_PROTO_X25; 192 199 return 0; /* return protocol only, no settable parameters */ 193 200 ··· 211 200 if (result) 212 201 return result; 213 202 214 - hdlc_proto_detach(hdlc); 215 - memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 216 - 217 - hdlc->proto.open = x25_open; 218 - hdlc->proto.close = x25_close; 219 - hdlc->proto.netif_rx = x25_rx; 220 - hdlc->proto.type_trans = NULL; 221 - hdlc->proto.id = IF_PROTO_X25; 203 + if ((result = attach_hdlc_protocol(dev, &proto, 204 + x25_rx, 0)) != 0) 205 + return result; 222 206 dev->hard_start_xmit = x25_xmit; 223 207 dev->hard_header = NULL; 224 208 dev->type = ARPHRD_X25; ··· 224 218 225 219 return -EINVAL; 226 220 } 221 + 222 + 223 + static int __init mod_init(void) 224 + { 225 + register_hdlc_protocol(&proto); 226 + return 0; 227 + } 228 + 229 + 230 + 231 + static void __exit mod_exit(void) 232 + { 233 + unregister_hdlc_protocol(&proto); 234 + } 235 + 236 + 237 + module_init(mod_init); 238 + module_exit(mod_exit); 239 + 240 + MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 241 + MODULE_DESCRIPTION("X.25 protocol support for generic HDLC"); 242 + MODULE_LICENSE("GPL v2");
+43 -156
include/linux/hdlc.h
··· 11 11 #ifndef __HDLC_H 12 12 #define __HDLC_H 13 13 14 - #define GENERIC_HDLC_VERSION 4 /* For synchronization with sethdlc utility */ 15 - 16 - #define CLOCK_DEFAULT 0 /* Default setting */ 17 - #define CLOCK_EXT 1 /* External TX and RX clock - DTE */ 18 - #define CLOCK_INT 2 /* Internal TX and RX clock - DCE */ 19 - #define CLOCK_TXINT 3 /* Internal TX and external RX clock */ 20 - #define CLOCK_TXFROMRX 4 /* TX clock derived from external RX clock */ 21 - 22 - 23 - #define ENCODING_DEFAULT 0 /* Default setting */ 24 - #define ENCODING_NRZ 1 25 - #define ENCODING_NRZI 2 26 - #define ENCODING_FM_MARK 3 27 - #define ENCODING_FM_SPACE 4 28 - #define ENCODING_MANCHESTER 5 29 - 30 - 31 - #define PARITY_DEFAULT 0 /* Default setting */ 32 - #define PARITY_NONE 1 /* No parity */ 33 - #define PARITY_CRC16_PR0 2 /* CRC16, initial value 0x0000 */ 34 - #define PARITY_CRC16_PR1 3 /* CRC16, initial value 0xFFFF */ 35 - #define PARITY_CRC16_PR0_CCITT 4 /* CRC16, initial 0x0000, ITU-T version */ 36 - #define PARITY_CRC16_PR1_CCITT 5 /* CRC16, initial 0xFFFF, ITU-T version */ 37 - #define PARITY_CRC32_PR0_CCITT 6 /* CRC32, initial value 0x00000000 */ 38 - #define PARITY_CRC32_PR1_CCITT 7 /* CRC32, initial value 0xFFFFFFFF */ 39 - 40 - #define LMI_DEFAULT 0 /* Default setting */ 41 - #define LMI_NONE 1 /* No LMI, all PVCs are static */ 42 - #define LMI_ANSI 2 /* ANSI Annex D */ 43 - #define LMI_CCITT 3 /* ITU-T Annex A */ 44 - #define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */ 45 14 46 15 #define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */ 16 + #if 0 47 17 #define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */ 18 + #else 19 + #define HDLC_MAX_MRU 1600 /* as required for FR network */ 20 + #endif 48 21 49 22 50 23 #ifdef __KERNEL__ 51 24 52 25 #include <linux/skbuff.h> 53 26 #include <linux/netdevice.h> 54 - #include <net/syncppp.h> 55 27 #include <linux/hdlc/ioctl.h> 56 28 57 29 58 - typedef struct { /* Used in Cisco and PPP mode */ 59 - u8 address; 60 - u8 control; 61 - u16 protocol; 62 - }__attribute__ ((packed)) hdlc_header; 63 - 64 - 65 - 66 - typedef struct { 67 - u32 type; /* code */ 68 - u32 par1; 69 - u32 par2; 70 - u16 rel; /* reliability */ 71 - u32 time; 72 - }__attribute__ ((packed)) cisco_packet; 73 - #define CISCO_PACKET_LEN 18 74 - #define CISCO_BIG_PACKET_LEN 20 75 - 76 - 77 - 78 - typedef struct pvc_device_struct { 79 - struct net_device *master; 80 - struct net_device *main; 81 - struct net_device *ether; /* bridged Ethernet interface */ 82 - struct pvc_device_struct *next; /* Sorted in ascending DLCI order */ 83 - int dlci; 84 - int open_count; 85 - 86 - struct { 87 - unsigned int new: 1; 88 - unsigned int active: 1; 89 - unsigned int exist: 1; 90 - unsigned int deleted: 1; 91 - unsigned int fecn: 1; 92 - unsigned int becn: 1; 93 - unsigned int bandwidth; /* Cisco LMI reporting only */ 94 - }state; 95 - }pvc_device; 96 - 97 - 98 - 99 - typedef struct hdlc_device_struct { 100 - /* To be initialized by hardware driver */ 30 + /* Used by all network devices here, pointed to by netdev_priv(dev) */ 31 + struct hdlc_device_desc { 32 + int (*netif_rx)(struct sk_buff *skb); 101 33 struct net_device_stats stats; 34 + }; 102 35 36 + /* This structure is a private property of HDLC protocols. 37 + Hardware drivers have no interest here */ 38 + 39 + struct hdlc_proto { 40 + int (*open)(struct net_device *dev); 41 + void (*close)(struct net_device *dev); 42 + void (*start)(struct net_device *dev); /* if open & DCD */ 43 + void (*stop)(struct net_device *dev); /* if open & !DCD */ 44 + void (*detach)(struct net_device *dev); 45 + int (*ioctl)(struct net_device *dev, struct ifreq *ifr); 46 + unsigned short (*type_trans)(struct sk_buff *skb, 47 + struct net_device *dev); 48 + struct module *module; 49 + struct hdlc_proto *next; /* next protocol in the list */ 50 + }; 51 + 52 + 53 + typedef struct hdlc_device { 103 54 /* used by HDLC layer to take control over HDLC device from hw driver*/ 104 55 int (*attach)(struct net_device *dev, 105 56 unsigned short encoding, unsigned short parity); ··· 58 107 /* hardware driver must handle this instead of dev->hard_start_xmit */ 59 108 int (*xmit)(struct sk_buff *skb, struct net_device *dev); 60 109 61 - 62 110 /* Things below are for HDLC layer internal use only */ 63 - struct { 64 - int (*open)(struct net_device *dev); 65 - void (*close)(struct net_device *dev); 66 - 67 - /* if open & DCD */ 68 - void (*start)(struct net_device *dev); 69 - /* if open & !DCD */ 70 - void (*stop)(struct net_device *dev); 71 - 72 - void (*detach)(struct hdlc_device_struct *hdlc); 73 - int (*netif_rx)(struct sk_buff *skb); 74 - unsigned short (*type_trans)(struct sk_buff *skb, 75 - struct net_device *dev); 76 - int id; /* IF_PROTO_HDLC/CISCO/FR/etc. */ 77 - }proto; 78 - 111 + const struct hdlc_proto *proto; 79 112 int carrier; 80 113 int open; 81 114 spinlock_t state_lock; 82 - 83 - union { 84 - struct { 85 - fr_proto settings; 86 - pvc_device *first_pvc; 87 - int dce_pvc_count; 88 - 89 - struct timer_list timer; 90 - unsigned long last_poll; 91 - int reliable; 92 - int dce_changed; 93 - int request; 94 - int fullrep_sent; 95 - u32 last_errors; /* last errors bit list */ 96 - u8 n391cnt; 97 - u8 txseq; /* TX sequence number */ 98 - u8 rxseq; /* RX sequence number */ 99 - }fr; 100 - 101 - struct { 102 - cisco_proto settings; 103 - 104 - struct timer_list timer; 105 - unsigned long last_poll; 106 - int up; 107 - int request_sent; 108 - u32 txseq; /* TX sequence number */ 109 - u32 rxseq; /* RX sequence number */ 110 - }cisco; 111 - 112 - struct { 113 - raw_hdlc_proto settings; 114 - }raw_hdlc; 115 - 116 - struct { 117 - struct ppp_device pppdev; 118 - struct ppp_device *syncppp_ptr; 119 - int (*old_change_mtu)(struct net_device *dev, 120 - int new_mtu); 121 - }ppp; 122 - }state; 115 + void *state; 123 116 void *priv; 124 117 }hdlc_device; 125 118 126 119 127 120 128 - int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr); 129 - int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr); 130 - int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr); 131 - int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr); 132 - int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr); 133 - int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr); 134 - 135 - 136 - /* Exported from hdlc.o */ 121 + /* Exported from hdlc module */ 137 122 138 123 /* Called by hardware driver when a user requests HDLC service */ 139 124 int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); ··· 78 191 #define register_hdlc_device(dev) register_netdev(dev) 79 192 void unregister_hdlc_device(struct net_device *dev); 80 193 194 + 195 + void register_hdlc_protocol(struct hdlc_proto *proto); 196 + void unregister_hdlc_protocol(struct hdlc_proto *proto); 197 + 81 198 struct net_device *alloc_hdlcdev(void *priv); 82 199 83 - static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev) 200 + 201 + static __inline__ struct hdlc_device_desc* dev_to_desc(struct net_device *dev) 84 202 { 85 203 return netdev_priv(dev); 86 204 } 87 205 88 - 89 - static __inline__ pvc_device* dev_to_pvc(struct net_device *dev) 206 + static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev) 90 207 { 91 - return (pvc_device*)dev->priv; 208 + return netdev_priv(dev) + sizeof(struct hdlc_device_desc); 92 209 } 93 210 94 211 ··· 116 225 /* Must be called by hardware driver when HDLC device is being closed */ 117 226 void hdlc_close(struct net_device *dev); 118 227 228 + int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, 229 + int (*rx)(struct sk_buff *skb), size_t size); 119 230 /* May be used by hardware driver to gain control over HDLC device */ 120 - static __inline__ void hdlc_proto_detach(hdlc_device *hdlc) 121 - { 122 - if (hdlc->proto.detach) 123 - hdlc->proto.detach(hdlc); 124 - hdlc->proto.detach = NULL; 125 - } 126 - 231 + void detach_hdlc_protocol(struct net_device *dev); 127 232 128 233 static __inline__ struct net_device_stats *hdlc_stats(struct net_device *dev) 129 234 { 130 - return &dev_to_hdlc(dev)->stats; 235 + return &dev_to_desc(dev)->stats; 131 236 } 132 237 133 238 ··· 135 248 skb->mac.raw = skb->data; 136 249 skb->dev = dev; 137 250 138 - if (hdlc->proto.type_trans) 139 - return hdlc->proto.type_trans(skb, dev); 251 + if (hdlc->proto->type_trans) 252 + return hdlc->proto->type_trans(skb, dev); 140 253 else 141 254 return htons(ETH_P_HDLC); 142 255 }
+33
include/linux/hdlc/ioctl.h
··· 1 1 #ifndef __HDLC_IOCTL_H__ 2 2 #define __HDLC_IOCTL_H__ 3 3 4 + 5 + #define GENERIC_HDLC_VERSION 4 /* For synchronization with sethdlc utility */ 6 + 7 + #define CLOCK_DEFAULT 0 /* Default setting */ 8 + #define CLOCK_EXT 1 /* External TX and RX clock - DTE */ 9 + #define CLOCK_INT 2 /* Internal TX and RX clock - DCE */ 10 + #define CLOCK_TXINT 3 /* Internal TX and external RX clock */ 11 + #define CLOCK_TXFROMRX 4 /* TX clock derived from external RX clock */ 12 + 13 + 14 + #define ENCODING_DEFAULT 0 /* Default setting */ 15 + #define ENCODING_NRZ 1 16 + #define ENCODING_NRZI 2 17 + #define ENCODING_FM_MARK 3 18 + #define ENCODING_FM_SPACE 4 19 + #define ENCODING_MANCHESTER 5 20 + 21 + 22 + #define PARITY_DEFAULT 0 /* Default setting */ 23 + #define PARITY_NONE 1 /* No parity */ 24 + #define PARITY_CRC16_PR0 2 /* CRC16, initial value 0x0000 */ 25 + #define PARITY_CRC16_PR1 3 /* CRC16, initial value 0xFFFF */ 26 + #define PARITY_CRC16_PR0_CCITT 4 /* CRC16, initial 0x0000, ITU-T version */ 27 + #define PARITY_CRC16_PR1_CCITT 5 /* CRC16, initial 0xFFFF, ITU-T version */ 28 + #define PARITY_CRC32_PR0_CCITT 6 /* CRC32, initial value 0x00000000 */ 29 + #define PARITY_CRC32_PR1_CCITT 7 /* CRC32, initial value 0xFFFFFFFF */ 30 + 31 + #define LMI_DEFAULT 0 /* Default setting */ 32 + #define LMI_NONE 1 /* No LMI, all PVCs are static */ 33 + #define LMI_ANSI 2 /* ANSI Annex D */ 34 + #define LMI_CCITT 3 /* ITU-T Annex A */ 35 + #define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */ 36 + 4 37 typedef struct { 5 38 unsigned int clock_rate; /* bits per second */ 6 39 unsigned int clock_type; /* internal, external, TX-internal etc. */