diff options
| author | Krzysztof Halasa <khc@pm.waw.pl> | 2003-04-06 19:22:40 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-04-06 19:22:40 -0700 |
| commit | 80d316b743aa85e2a3a0e449efc6feada77041a3 (patch) | |
| tree | 684015eaac17b9979ff7854aede0708a1048e3f7 /include/linux | |
| parent | 00c6dc1cafc25e1979543eb4c62f51821f06b556 (diff) | |
[PATCH] generic HDLC update
This version fixes:
- missing rtnl_lock()/rtnl_unload() bug on unregister_hdlc_device
- N2, C101: interrupt handler now works under high IRQ load from other
devices (with previous versions, the IRQ processing for the card could
sometimes stop after reaching "work limit")
This is production-tested on devices I have access to (N2, C101, PC300,
PCI200SYN).
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/hdlc.h | 66 | ||||
| -rw-r--r-- | include/linux/hdlc/ioctl.h | 17 | ||||
| -rw-r--r-- | include/linux/if.h | 10 |
3 files changed, 44 insertions, 49 deletions
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h index aeceb6f1a7be..6b89e9c85f9b 100644 --- a/include/linux/hdlc.h +++ b/include/linux/hdlc.h @@ -1,12 +1,11 @@ /* * Generic HDLC support routines for Linux * - * Copyright (C) 1999-2002 Krzysztof Halasa <khc@pm.waw.pl> + * Copyright (C) 1999-2003 Krzysztof Halasa <khc@pm.waw.pl> * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. */ #ifndef __HDLC_H @@ -52,7 +51,7 @@ #include <linux/hdlc/ioctl.h> #define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */ -#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10) /* max 10 bytes for FR */ +#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */ #define MAXLEN_LMISTAT 20 /* max size of status enquiry frame */ @@ -145,17 +144,20 @@ typedef struct { typedef struct pvc_device_struct { - struct net_device netdev; /* PVC net device - must be first */ - struct net_device_stats stats; struct hdlc_device_struct *master; - struct pvc_device_struct *next; + struct net_device *main; + struct net_device *ether; /* bridged Ethernet interface */ + struct pvc_device_struct *next; /* Sorted in ascending DLCI order */ + int dlci; + int open_count; struct { - int active; - int new; - int deleted; - int fecn; - int becn; + unsigned int new: 1; + unsigned int active: 1; + unsigned int exist: 1; + unsigned int deleted: 1; + unsigned int fecn: 1; + unsigned int becn: 1; }state; }pvc_device; @@ -180,18 +182,20 @@ typedef struct hdlc_device_struct { void (*stop)(struct hdlc_device_struct *hdlc); void (*proto_detach)(struct hdlc_device_struct *hdlc); void (*netif_rx)(struct sk_buff *skb); + unsigned short (*type_trans)(struct sk_buff *skb, + struct net_device *dev); int proto; /* IF_PROTO_HDLC/CISCO/FR/etc. */ union { struct { fr_proto settings; pvc_device *first_pvc; - int pvc_count; + int dce_pvc_count; struct timer_list timer; int last_poll; int reliable; - int changed; + int dce_changed; int request; int fullrep_sent; u32 last_errors; /* last errors bit list */ @@ -226,6 +230,7 @@ typedef struct hdlc_device_struct { int hdlc_raw_ioctl(hdlc_device *hdlc, struct ifreq *ifr); +int hdlc_raw_eth_ioctl(hdlc_device *hdlc, struct ifreq *ifr); int hdlc_cisco_ioctl(hdlc_device *hdlc, struct ifreq *ifr); int hdlc_ppp_ioctl(hdlc_device *hdlc, struct ifreq *ifr); int hdlc_fr_ioctl(hdlc_device *hdlc, struct ifreq *ifr); @@ -254,15 +259,9 @@ static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev) } -static __inline__ struct net_device* pvc_to_dev(pvc_device *pvc) -{ - return &pvc->netdev; -} - - static __inline__ pvc_device* dev_to_pvc(struct net_device *dev) { - return (pvc_device*)dev; + return (pvc_device*)dev->priv; } @@ -272,19 +271,6 @@ static __inline__ const char *hdlc_to_name(hdlc_device *hdlc) } -static __inline__ const char *pvc_to_name(pvc_device *pvc) -{ - return pvc_to_dev(pvc)->name; -} - - -static __inline__ u16 netdev_dlci(struct net_device *dev) -{ - return ntohs(*(u16*)dev->dev_addr); -} - - - static __inline__ u16 q922_to_dlci(u8 *hdr) { return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4); @@ -345,5 +331,15 @@ static __inline__ void hdlc_proto_detach(hdlc_device *hdlc) } +static __inline__ unsigned short hdlc_type_trans(struct sk_buff *skb, + struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(skb->dev); + if (hdlc->type_trans) + return hdlc->type_trans(skb, dev); + else + return __constant_htons(ETH_P_HDLC); +} + #endif /* __KERNEL */ #endif /* __HDLC_H */ diff --git a/include/linux/hdlc/ioctl.h b/include/linux/hdlc/ioctl.h index c35e1a35d847..78430ba3ea69 100644 --- a/include/linux/hdlc/ioctl.h +++ b/include/linux/hdlc/ioctl.h @@ -34,22 +34,15 @@ typedef struct { } fr_proto_pvc; /* for creating/deleting FR PVCs */ typedef struct { + unsigned int dlci; + char master[IFNAMSIZ]; /* Name of master FRAD device */ +}fr_proto_pvc_info; /* for returning PVC information only */ + +typedef struct { unsigned int interval; unsigned int timeout; } cisco_proto; /* PPP doesn't need any info now - supply length = 0 to ioctl */ -union hdlc_settings { - raw_hdlc_proto raw_hdlc; - cisco_proto cisco; - fr_proto fr; - fr_proto_pvc fr_pvc; -}; - -union line_settings { - sync_serial_settings sync; - te1_settings te1; -}; - #endif /* __HDLC_IOCTL_H__ */ diff --git a/include/linux/if.h b/include/linux/if.h index 898cfdf1bb14..c4c72e790700 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -21,6 +21,8 @@ #include <linux/types.h> /* for "__kernel_caddr_t" et al */ #include <linux/socket.h> /* for "struct sockaddr" et al */ + +#define IFNAMSIZ 16 #include <linux/hdlc/ioctl.h> /* Standard interface flags (netdevice->flags). */ @@ -69,7 +71,11 @@ #define IF_PROTO_FR_ADD_PVC 0x2004 /* Create FR PVC */ #define IF_PROTO_FR_DEL_PVC 0x2005 /* Delete FR PVC */ #define IF_PROTO_X25 0x2006 /* X.25 */ - +#define IF_PROTO_HDLC_ETH 0x2007 /* raw HDLC, Ethernet emulation */ +#define IF_PROTO_FR_ADD_ETH_PVC 0x2008 /* Create FR Ethernet-bridged PVC */ +#define IF_PROTO_FR_DEL_ETH_PVC 0x2009 /* Delete FR Ethernet-bridged PVC */ +#define IF_PROTO_FR_PVC 0x200A /* for reading PVC status */ +#define IF_PROTO_FR_ETH_PVC 0x200B /* @@ -103,6 +109,7 @@ struct if_settings cisco_proto *cisco; fr_proto *fr; fr_proto_pvc *fr_pvc; + fr_proto_pvc_info *fr_pvc_info; /* interface settings */ sync_serial_settings *sync; @@ -120,7 +127,6 @@ struct if_settings struct ifreq { #define IFHWADDRLEN 6 -#define IFNAMSIZ 16 union { char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ |
