summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorKrzysztof Halasa <khc@pm.waw.pl>2003-04-06 19:22:40 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-04-06 19:22:40 -0700
commit80d316b743aa85e2a3a0e449efc6feada77041a3 (patch)
tree684015eaac17b9979ff7854aede0708a1048e3f7 /include/linux
parent00c6dc1cafc25e1979543eb4c62f51821f06b556 (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.h66
-rw-r--r--include/linux/hdlc/ioctl.h17
-rw-r--r--include/linux/if.h10
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" */