* [RFC PATCH 04/13] ipv6: Add new offload registration infrastructure.
From: Vlad Yasevich @ 2012-11-14 1:24 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, davem
In-Reply-To: <1352856254-29667-1-git-send-email-vyasevic@redhat.com>
Create a new data structure for IPv6 protocols that holds GRO/GSO
callbacks and a new array to track the protocols that register GRO/GSO.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
include/net/protocol.h | 4 ++++
net/ipv6/exthdrs.c | 8 ++++++++
net/ipv6/protocol.c | 21 +++++++++++++++++++++
net/ipv6/tcp_ipv6.c | 7 +++++++
net/ipv6/udp.c | 5 +++++
5 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/include/net/protocol.h b/include/net/protocol.h
index d8ecb17..637e1bb 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -84,6 +84,7 @@ struct net_offload {
struct sk_buff **(*gro_receive)(struct sk_buff **head,
struct sk_buff *skb);
int (*gro_complete)(struct sk_buff *skb);
+ unsigned int flags; /* Flags used by IPv6 for now */
};
/* This is used to register socket interfaces for IP protocols. */
@@ -109,6 +110,7 @@ extern const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS];
#if IS_ENABLED(CONFIG_IPV6)
extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS];
+extern const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS];
#endif
extern int inet_add_protocol(const struct net_protocol *prot, unsigned char num);
@@ -121,6 +123,8 @@ extern void inet_unregister_protosw(struct inet_protosw *p);
#if IS_ENABLED(CONFIG_IPV6)
extern int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num);
extern int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num);
+extern int inet6_add_offload(const struct net_offload *prot, unsigned char num);
+extern int inet6_del_offload(const struct net_offload *prot, unsigned char num);
extern int inet6_register_protosw(struct inet_protosw *p);
extern void inet6_unregister_protosw(struct inet_protosw *p);
#endif
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index fa3d9c3..8c01574 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -531,11 +531,19 @@ static const struct inet6_protocol rthdr_protocol = {
.flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
};
+static const struct net_offload rthdr_offload = {
+ .flags = INET6_PROTO_GSO_EXTHDR,
+};
+
static const struct inet6_protocol destopt_protocol = {
.handler = ipv6_destopt_rcv,
.flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
};
+static const struct net_offload dstopt_offload = {
+ .flags = INET6_PROTO_GSO_EXTHDR,
+};
+
static const struct inet6_protocol nodata_protocol = {
.handler = dst_discard,
.flags = INET6_PROTO_NOPOLICY,
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index 053082d..f7c53a7 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -26,6 +26,7 @@
#include <net/protocol.h>
const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly;
+const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly;
int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
{
@@ -34,6 +35,13 @@ int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol
}
EXPORT_SYMBOL(inet6_add_protocol);
+int inet6_add_offload(const struct net_offload *prot, unsigned char protocol)
+{
+ return !cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
+ NULL, prot) ? 0 : -1;
+}
+EXPORT_SYMBOL(inet6_add_offload);
+
/*
* Remove a protocol from the hash tables.
*/
@@ -50,3 +58,16 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol
return ret;
}
EXPORT_SYMBOL(inet6_del_protocol);
+
+int inet6_del_offload(const struct net_offload *prot, unsigned char protocol)
+{
+ int ret;
+
+ ret = (cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
+ prot, NULL) == prot) ? 0 : -1;
+
+ synchronize_net();
+
+ return ret;
+}
+EXPORT_SYMBOL(inet6_del_offload);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 26175bf..8ce2c30 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2070,6 +2070,13 @@ static const struct inet6_protocol tcpv6_protocol = {
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};
+static const struct net_offload tcpv6_offload = {
+ .gso_send_check = tcp_v6_gso_send_check,
+ .gso_segment = tcp_tso_segment,
+ .gro_receive = tcp6_gro_receive,
+ .gro_complete = tcp6_gro_complete,
+};
+
static struct inet_protosw tcpv6_protosw = {
.type = SOCK_STREAM,
.protocol = IPPROTO_TCP,
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index fc99972..3ad44e1 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1443,6 +1443,11 @@ static const struct inet6_protocol udpv6_protocol = {
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};
+static const struct net_offload udpv6_offload = {
+ .gso_send_check = udp6_ufo_send_check,
+ .gso_segment = udp6_ufo_fragment,
+};
+
/* ------------------------------------------------------------------------ */
#ifdef CONFIG_PROC_FS
--
1.7.7.6
^ permalink raw reply related
* [RFC PATCH 03/13] net: Add net protocol offload registration infrustructure
From: Vlad Yasevich @ 2012-11-14 1:24 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, davem
In-Reply-To: <1352856254-29667-1-git-send-email-vyasevic@redhat.com>
Create a new data structure for IPv4 protocols that holds GRO/GSO
callbacks and a new array to track the protocols that register GRO/GSO.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
include/net/protocol.h | 12 ++++++++++++
net/ipv4/af_inet.c | 12 ++++++++++++
net/ipv4/protocol.c | 22 +++++++++++++++++++++-
3 files changed, 45 insertions(+), 1 deletions(-)
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 929528c..d8ecb17 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -77,6 +77,15 @@ struct inet6_protocol {
#define INET6_PROTO_GSO_EXTHDR 0x4
#endif
+struct net_offload {
+ int (*gso_send_check)(struct sk_buff *skb);
+ struct sk_buff *(*gso_segment)(struct sk_buff *skb,
+ netdev_features_t features);
+ struct sk_buff **(*gro_receive)(struct sk_buff **head,
+ struct sk_buff *skb);
+ int (*gro_complete)(struct sk_buff *skb);
+};
+
/* This is used to register socket interfaces for IP protocols. */
struct inet_protosw {
struct list_head list;
@@ -96,6 +105,7 @@ struct inet_protosw {
#define INET_PROTOSW_ICSK 0x04 /* Is this an inet_connection_sock? */
extern const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS];
+extern const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS];
#if IS_ENABLED(CONFIG_IPV6)
extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS];
@@ -103,6 +113,8 @@ extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS];
extern int inet_add_protocol(const struct net_protocol *prot, unsigned char num);
extern int inet_del_protocol(const struct net_protocol *prot, unsigned char num);
+extern int inet_add_offload(const struct net_offload *prot, unsigned char num);
+extern int inet_del_offload(const struct net_offload *prot, unsigned char num);
extern void inet_register_protosw(struct inet_protosw *p);
extern void inet_unregister_protosw(struct inet_protosw *p);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 4c99c5f..3918d86 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1566,6 +1566,13 @@ static const struct net_protocol tcp_protocol = {
.netns_ok = 1,
};
+static const struct net_offload tcp_offload = {
+ .gso_send_check = tcp_v4_gso_send_check,
+ .gso_segment = tcp_tso_segment,
+ .gro_receive = tcp4_gro_receive,
+ .gro_complete = tcp4_gro_complete,
+};
+
static const struct net_protocol udp_protocol = {
.handler = udp_rcv,
.err_handler = udp_err,
@@ -1575,6 +1582,11 @@ static const struct net_protocol udp_protocol = {
.netns_ok = 1,
};
+static const struct net_offload udp_offload = {
+ .gso_send_check = udp4_ufo_send_check,
+ .gso_segment = udp4_ufo_fragment,
+};
+
static const struct net_protocol icmp_protocol = {
.handler = icmp_rcv,
.err_handler = ping_err,
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index 8918eff..1278db8 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -29,6 +29,7 @@
#include <net/protocol.h>
const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly;
+const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly;
/*
* Add a protocol handler to the hash tables
@@ -41,6 +42,13 @@ int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
}
EXPORT_SYMBOL(inet_add_protocol);
+int inet_add_offload(const struct net_offload *prot, unsigned char protocol)
+{
+ return !cmpxchg((const struct net_offload **)&inet_offloads[protocol],
+ NULL, prot) ? 0 : -1;
+}
+EXPORT_SYMBOL(inet_add_offload);
+
/*
* Remove a protocol from the hash tables.
*/
@@ -56,4 +64,16 @@ int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
return ret;
}
-EXPORT_SYMBOL(inet_del_protocol);
+
+int inet_del_offload(const struct net_offload *prot, unsigned char protocol)
+{
+ int ret;
+
+ ret = (cmpxchg((const struct net_offload **)&inet_offloads[protocol],
+ prot, NULL) == prot) ? 0 : -1;
+
+ synchronize_net();
+
+ return ret;
+}
+EXPORT_SYMBOL(inet_del_offload);
--
1.7.7.6
^ permalink raw reply related
* [RFC PATCH 02/13] core: Switch to using the new packet offload infrustructure
From: Vlad Yasevich @ 2012-11-14 1:24 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, davem
In-Reply-To: <1352856254-29667-1-git-send-email-vyasevic@redhat.com>
Convert to using the new GSO/GRO registration mechanism and new
packet offload structure.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
include/linux/netdevice.h | 6 ------
net/core/dev.c | 13 ++++++-------
net/ipv4/af_inet.c | 5 +++++
net/ipv6/af_inet6.c | 6 ++++++
4 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d15af51..d683508 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1499,12 +1499,6 @@ struct packet_type {
struct net_device *,
struct packet_type *,
struct net_device *);
- struct sk_buff *(*gso_segment)(struct sk_buff *skb,
- netdev_features_t features);
- int (*gso_send_check)(struct sk_buff *skb);
- struct sk_buff **(*gro_receive)(struct sk_buff **head,
- struct sk_buff *skb);
- int (*gro_complete)(struct sk_buff *skb);
bool (*id_match)(struct packet_type *ptype,
struct sock *sk);
void *af_packet_priv;
diff --git a/net/core/dev.c b/net/core/dev.c
index 10967e5..64d4302 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2072,7 +2072,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb,
netdev_features_t features)
{
struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
- struct packet_type *ptype;
+ struct packet_offload *ptype;
__be16 type = skb->protocol;
int vlan_depth = ETH_HLEN;
int err;
@@ -2101,8 +2101,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb,
}
rcu_read_lock();
- list_for_each_entry_rcu(ptype,
- &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
+ list_for_each_entry_rcu(ptype, &offload_base, list) {
if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
err = ptype->gso_send_check(skb);
@@ -3522,9 +3521,9 @@ static void flush_backlog(void *arg)
static int napi_gro_complete(struct sk_buff *skb)
{
- struct packet_type *ptype;
+ struct packet_offload *ptype;
__be16 type = skb->protocol;
- struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK];
+ struct list_head *head = &offload_base;
int err = -ENOENT;
if (NAPI_GRO_CB(skb)->count == 1) {
@@ -3584,9 +3583,9 @@ EXPORT_SYMBOL(napi_gro_flush);
enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
struct sk_buff **pp = NULL;
- struct packet_type *ptype;
+ struct packet_offload *ptype;
__be16 type = skb->protocol;
- struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK];
+ struct list_head *head = &offload_base;
int same_flow;
int mac_len;
enum gro_result ret;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 766c596..4c99c5f 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1662,6 +1662,10 @@ static int ipv4_proc_init(void);
static struct packet_type ip_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_IP),
.func = ip_rcv,
+};
+
+static struct packet_offload ip_packet_offload __read_mostly = {
+ .type = cpu_to_be16(ETH_P_IP),
.gso_send_check = inet_gso_send_check,
.gso_segment = inet_gso_segment,
.gro_receive = inet_gro_receive,
@@ -1781,6 +1785,7 @@ static int __init inet_init(void)
ipfrag_init();
+ dev_add_offload(&ip_packet_offload);
dev_add_pack(&ip_packet_type);
rc = 0;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index a974247..6e24517 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -938,6 +938,10 @@ out_unlock:
static struct packet_type ipv6_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_IPV6),
.func = ipv6_rcv,
+};
+
+static struct packet_offload ipv6_packet_offload __read_mostly = {
+ .type = cpu_to_be16(ETH_P_IPV6),
.gso_send_check = ipv6_gso_send_check,
.gso_segment = ipv6_gso_segment,
.gro_receive = ipv6_gro_receive,
@@ -946,6 +950,7 @@ static struct packet_type ipv6_packet_type __read_mostly = {
static int __init ipv6_packet_init(void)
{
+ dev_add_offload(&ipv6_packet_offload);
dev_add_pack(&ipv6_packet_type);
return 0;
}
@@ -953,6 +958,7 @@ static int __init ipv6_packet_init(void)
static void ipv6_packet_cleanup(void)
{
dev_remove_pack(&ipv6_packet_type);
+ dev_remove_offload(&ipv6_packet_offload);
}
static int __net_init ipv6_init_mibs(struct net *net)
--
1.7.7.6
^ permalink raw reply related
* [RFC PATCH 01/13] net: Add generic packet offload infrastructure.
From: Vlad Yasevich @ 2012-11-14 1:24 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, davem
In-Reply-To: <1352856254-29667-1-git-send-email-vyasevic@redhat.com>
Create a new data structure to contain the GRO/GSO callbacks and add
a new registration mechanism.
Singed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
include/linux/netdevice.h | 15 ++++++++
net/core/dev.c | 80 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 95 insertions(+), 0 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f8eda02..d15af51 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1511,6 +1511,18 @@ struct packet_type {
struct list_head list;
};
+struct packet_offload {
+ __be16 type; /* This is really htons(ether_type). */
+ struct net_device *dev; /* NULL is wildcarded here */
+ struct sk_buff *(*gso_segment)(struct sk_buff *skb,
+ netdev_features_t features);
+ int (*gso_send_check)(struct sk_buff *skb);
+ struct sk_buff **(*gro_receive)(struct sk_buff **head,
+ struct sk_buff *skb);
+ int (*gro_complete)(struct sk_buff *skb);
+ struct list_head list;
+};
+
#include <linux/notifier.h>
/* netdevice notifier chain. Please remember to update the rtnetlink
@@ -1605,6 +1617,9 @@ extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short
extern void dev_add_pack(struct packet_type *pt);
extern void dev_remove_pack(struct packet_type *pt);
extern void __dev_remove_pack(struct packet_type *pt);
+extern void dev_add_offload(struct packet_offload *po);
+extern void dev_remove_offload(struct packet_offload *po);
+extern void __dev_remove_offload(struct packet_offload *po);
extern struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short flags,
unsigned short mask);
diff --git a/net/core/dev.c b/net/core/dev.c
index 09cb3f6..10967e5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -176,8 +176,10 @@
#define PTYPE_HASH_MASK (PTYPE_HASH_SIZE - 1)
static DEFINE_SPINLOCK(ptype_lock);
+static DEFINE_SPINLOCK(offload_lock);
static struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
static struct list_head ptype_all __read_mostly; /* Taps */
+static struct list_head offload_base __read_mostly;
/*
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
@@ -470,6 +472,82 @@ void dev_remove_pack(struct packet_type *pt)
}
EXPORT_SYMBOL(dev_remove_pack);
+
+/**
+ * dev_add_offload - register offload handlers
+ * @po: protocol offload declaration
+ *
+ * Add protocol offload handlers to the networking stack. The passed
+ * &proto_offload is linked into kernel lists and may not be freed until
+ * it has been removed from the kernel lists.
+ *
+ * This call does not sleep therefore it can not
+ * guarantee all CPU's that are in middle of receiving packets
+ * will see the new offload handlers (until the next received packet).
+ */
+void dev_add_offload(struct packet_offload *po)
+{
+ struct list_head *head = &offload_base;
+
+ spin_lock(&offload_lock);
+ list_add_rcu(&po->list, head);
+ spin_unlock(&offload_lock);
+}
+EXPORT_SYMBOL(dev_add_offload);
+
+/**
+ * __dev_remove_offload - remove offload handler
+ * @po: packet offload declaration
+ *
+ * Remove a protocol offload handler that was previously added to the
+ * kernel offload handlers by dev_add_offload(). The passed &offload_type
+ * is removed from the kernel lists and can be freed or reused once this
+ * function returns.
+ *
+ * The packet type might still be in use by receivers
+ * and must not be freed until after all the CPU's have gone
+ * through a quiescent state.
+ */
+void __dev_remove_offload(struct packet_offload *po)
+{
+ struct list_head *head = &offload_base;
+ struct packet_offload *po1;
+
+ spin_lock(&ptype_lock);
+
+ list_for_each_entry(po1, head, list) {
+ if (po == po1) {
+ list_del_rcu(&po->list);
+ goto out;
+ }
+ }
+
+ pr_warn("dev_remove_offload: %p not found\n", po);
+out:
+ spin_unlock(&ptype_lock);
+}
+EXPORT_SYMBOL(__dev_remove_offload);
+
+/**
+ * dev_remove_offload - remove packet offload handler
+ * @po: packet offload declaration
+ *
+ * Remove a packet offload handler that was previously added to the kernel
+ * offload handlers by dev_add_offload(). The passed &offload_type is
+ * removed from the kernel lists and can be freed or reused once this
+ * function returns.
+ *
+ * This call sleeps to guarantee that no CPU is looking at the packet
+ * type after return.
+ */
+void dev_remove_offload(struct packet_offload *po)
+{
+ __dev_remove_offload(po);
+
+ synchronize_net();
+}
+EXPORT_SYMBOL(dev_remove_offload);
+
/******************************************************************************
Device Boot-time Settings Routines
@@ -6662,6 +6740,8 @@ static int __init net_dev_init(void)
for (i = 0; i < PTYPE_HASH_SIZE; i++)
INIT_LIST_HEAD(&ptype_base[i]);
+ INIT_LIST_HEAD(&offload_base);
+
if (register_pernet_subsys(&netdev_net_ops))
goto out;
--
1.7.7.6
^ permalink raw reply related
* [RFC PATCH 00/13] Always build GSO/GRO functionality into the kernel
From: Vlad Yasevich @ 2012-11-14 1:24 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, davem
This patch series is a revision suggested by Eric to solve the problem where
a host without IPv6 support drops GSO frames from the guest.
The problem is that GSO/GRO support is per protocol, and when said protocol
is not loaded or is disabled, packets attempting to go through GSO/GRO code paths
are dropped. This causes retransmissions and a two orders of magnitude drop in
performance.
Prior attempt to solve the problem simply enabled enough GSO/GRO functionality
for IPv6 protocol when IPv6 was diabled. This did not solve the problem when
the protocol was not build in or was blacklisted.
To solve the problem, it was suggested that we separate GSO/GRO callback
registration from packet processing registrations. That way
GSO/GRO callbacks can be built into the kernel and always be there.
This patch series attempts to do just that.
* Patches 1 and 2 split the GSO/GRO handlers from packet_type and convert
to the new structure.
* Patches 3, 4 and 5 do the same thing for net_protocol structure.
* The rest of the patches try to incrementally move the IPv6 GSO/GRO
code out of the module and into the static kernel build. Some IPv6
helper functions also had to move as well.
I am currently testing the patches, but if folks could look this over
and send me any comments, I'd appreciate it.
Thanks
-vlad
Vlad Yasevich (13):
net: Add generic packet offload infrastructure.
net: Switch to using the new packet offload infrustructure
net: Add net protocol offload registration infrustructure
ipv6: Add new offload registration infrastructure.
ipv4: Switch to using the new offload infrastructure.
ipv6: Switch to using new offload infrastructure.
ipv6: Separate ipv6 offload support
ipv6: Separate tcp offload functionality
ipv6: Separate out UDP offload functionality
ipv6: Move exthdr offload support into separate file
ipv6: Update ipv6 static library with newly needed functions
ipv4: Pull GSO registration out of inet_init()
ipv6: Pull IPv6 GSO registration out of the module
include/linux/netdevice.h | 15 ++-
include/net/ip6_checksum.h | 33 +++++
include/net/protocol.h | 35 +++---
net/core/dev.c | 93 ++++++++++++++-
net/ipv4/af_inet.c | 53 ++++++---
net/ipv4/protocol.c | 22 ++++-
net/ipv6/Makefile | 7 +-
net/ipv6/af_inet6.c | 240 -------------------------------------
net/ipv6/exthdrs.c | 8 +-
net/ipv6/exthdrs_offload.c | 41 +++++++
net/ipv6/ip6_offload.c | 280 ++++++++++++++++++++++++++++++++++++++++++++
net/ipv6/ip6_offload.h | 18 +++
net/ipv6/ip6_output.c | 65 ----------
net/ipv6/output_core.c | 76 ++++++++++++
net/ipv6/protocol.c | 21 ++++
net/ipv6/tcp_ipv6.c | 107 +-----------------
net/ipv6/tcpv6_offload.c | 93 +++++++++++++++
net/ipv6/udp.c | 94 ---------------
net/ipv6/udp_offload.c | 117 ++++++++++++++++++
19 files changed, 867 insertions(+), 551 deletions(-)
create mode 100644 net/ipv6/exthdrs_offload.c
create mode 100644 net/ipv6/ip6_offload.c
create mode 100644 net/ipv6/ip6_offload.h
create mode 100644 net/ipv6/output_core.c
create mode 100644 net/ipv6/tcpv6_offload.c
create mode 100644 net/ipv6/udp_offload.c
--
1.7.7.6
^ permalink raw reply
* Re: [PATCH net-next] 8021q: validate SAN MAC address
From: David Miller @ 2012-11-14 1:24 UTC (permalink / raw)
To: mchan; +Cc: netdev
In-Reply-To: <1352850029.6276.52.camel@LTIRV-MCHAN1.corp.ad.broadcom.com>
From: "Michael Chan" <mchan@broadcom.com>
Date: Tue, 13 Nov 2012 15:40:29 -0800
> I suppose we can just put the SAN MAC into the real netdev->dev_addr so
> that the VLAN will automatically get it. But this doesn't seem very
> nice as we would be pretending to have a normal MAC address (for
> networking) in this SAN device. The networking MAC address is in a
> different PCI function.
I certainly would prefer if you took that approach. At least in that
way the addressing of the netdev objects would appear more consistent.
Thanks.
^ permalink raw reply
* Re: [PATCH v2 net-next 0/3 ] tunneling: Add support for hardware-offloaded encapsulation
From: Joseph Gasparakis @ 2012-11-14 0:42 UTC (permalink / raw)
To: Joseph Gasparakis
Cc: davem, shemminger, chrisw, netdev, linux-kernel, dmitry,
saeed.bishara
In-Reply-To: <1352709418-28996-1-git-send-email-joseph.gasparakis@intel.com>
On Mon, 12 Nov 2012, Joseph Gasparakis wrote:
> The series contains updates to add in the NIC Rx and Tx checksumming support
> for encapsulated packets.
>
> The sk_buff needs to somehow have information of the inner packet, and adding
> three fields for the inner mac, network and transport headers was the prefered
> approach.
>
> Not adding these fields would mean that the drivers would need to parse the
> sk_buff data in hot-path, having a negative impact in the performance.
>
> Adding in sk_buff a pointer to the skbuff of the inner packet made sense, but
> would be a complicated change as assumptions needed to be made with regards to
> helper functions such as skb_clone() skb_copy(). Also code for the existing
> encapsulation protocols (such as VXLAN and IP GRE) had to be reworked, so the
> decision was to have the simple approach of adding these three fields.
>
> v2 Makes sure that checksumming for IP GRE does not take place if the offload flag is set in the skb's netdev features
>
Thank you all. I am working now on implementing a demo using ixgbe and
will re-submit soon this series of patches taking into consideration any
open comments.
^ permalink raw reply
* [PATCH net-next] vmxnet3: fix indentation
From: Stephen Hemminger @ 2012-11-13 23:53 UTC (permalink / raw)
To: David Miller, Shreyas Bhatewara; +Cc: netdev
Minor indentation out of alignment.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/vmxnet3/vmxnet3_drv.c 2012-11-12 07:58:45.531037908 -0800
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c 2012-11-13 15:50:53.076593627 -0800
@@ -1094,10 +1094,10 @@ vmxnet3_xmit_frame(struct sk_buff *skb,
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- BUG_ON(skb->queue_mapping > adapter->num_tx_queues);
- return vmxnet3_tq_xmit(skb,
- &adapter->tx_queue[skb->queue_mapping],
- adapter, netdev);
+ BUG_ON(skb->queue_mapping > adapter->num_tx_queues);
+ return vmxnet3_tq_xmit(skb,
+ &adapter->tx_queue[skb->queue_mapping],
+ adapter, netdev);
}
@@ -1243,8 +1243,8 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx
skb_reserve(new_skb, NET_IP_ALIGN);
rbi->skb = new_skb;
rbi->dma_addr = pci_map_single(adapter->pdev,
- rbi->skb->data, rbi->len,
- PCI_DMA_FROMDEVICE);
+ rbi->skb->data, rbi->len,
+ PCI_DMA_FROMDEVICE);
rxd->addr = cpu_to_le64(rbi->dma_addr);
rxd->len = rbi->len;
@@ -1331,14 +1331,14 @@ rcd_done:
/* if needed, update the register */
if (unlikely(rq->shared->updateRxProd)) {
VMXNET3_WRITE_BAR0_REG(adapter,
- rxprod_reg[ring_idx] + rq->qid * 8,
- ring->next2fill);
+ rxprod_reg[ring_idx] + rq->qid * 8,
+ ring->next2fill);
rq->uncommitted[ring_idx] = 0;
}
vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring);
vmxnet3_getRxComp(rcd,
- &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, &rxComp);
+ &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, &rxComp);
}
return num_rxd;
@@ -2949,11 +2949,11 @@ vmxnet3_probe_device(struct pci_dev *pde
spin_lock_init(&adapter->cmd_lock);
adapter->shared = pci_alloc_consistent(adapter->pdev,
- sizeof(struct Vmxnet3_DriverShared),
- &adapter->shared_pa);
+ sizeof(struct Vmxnet3_DriverShared),
+ &adapter->shared_pa);
if (!adapter->shared) {
printk(KERN_ERR "Failed to allocate memory for %s\n",
- pci_name(pdev));
+ pci_name(pdev));
err = -ENOMEM;
goto err_alloc_shared;
}
@@ -2964,16 +2964,16 @@ vmxnet3_probe_device(struct pci_dev *pde
size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues;
size += sizeof(struct Vmxnet3_RxQueueDesc) * adapter->num_rx_queues;
adapter->tqd_start = pci_alloc_consistent(adapter->pdev, size,
- &adapter->queue_desc_pa);
+ &adapter->queue_desc_pa);
if (!adapter->tqd_start) {
printk(KERN_ERR "Failed to allocate memory for %s\n",
- pci_name(pdev));
+ pci_name(pdev));
err = -ENOMEM;
goto err_alloc_queue_desc;
}
adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start +
- adapter->num_tx_queues);
+ adapter->num_tx_queues);
adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL);
if (adapter->pm_conf == NULL) {
@@ -3019,7 +3019,7 @@ vmxnet3_probe_device(struct pci_dev *pde
adapter->dev_number = atomic_read(&devices_found);
- adapter->share_intr = irq_share_mode;
+ adapter->share_intr = irq_share_mode;
if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE &&
adapter->num_tx_queues != adapter->num_rx_queues)
adapter->share_intr = VMXNET3_INTR_DONTSHARE;
@@ -3065,7 +3065,7 @@ vmxnet3_probe_device(struct pci_dev *pde
if (err) {
printk(KERN_ERR "Failed to register adapter %s\n",
- pci_name(pdev));
+ pci_name(pdev));
goto err_register;
}
^ permalink raw reply
* Re: [PATCH net-next] 8021q: validate SAN MAC address
From: Michael Chan @ 2012-11-13 23:40 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20121113.181600.667479923208656972.davem@davemloft.net>
On Tue, 2012-11-13 at 18:16 -0500, David Miller wrote:
> From: "Michael Chan" <mchan@broadcom.com>
> Date: Tue, 13 Nov 2012 14:29:48 -0800
>
> > We need to have VLAN tags inserted to packets using that interface.
> > The VID is dynamically discovered by application. How do suggest we
> > do that if we don't use 8021q?
>
> Ok. So what's the reason that the VLAN device isn't given a
> valid MAC address, for example why not use the SAN one?
>
The VLAN netdev automatically gets the MAC address from the real
netdev->dev_addr. In this case, the real netdev does not have a valid
dev_addr because the PCI function is a SAN device. The SAN MAC is in a
different hw address list in netdev->dev_addrs.
I suppose we can just put the SAN MAC into the real netdev->dev_addr so
that the VLAN will automatically get it. But this doesn't seem very
nice as we would be pretending to have a normal MAC address (for
networking) in this SAN device. The networking MAC address is in a
different PCI function.
^ permalink raw reply
* Re: [PATCH v6 2/7] net: mvneta: driver for Marvell Armada 370/XP network unit
From: Francois Romieu @ 2012-11-13 23:12 UTC (permalink / raw)
To: Thomas Petazzoni
Cc: David S. Miller, Lennert Buytenhek, netdev, linux-arm-kernel,
Jason Cooper, Andrew Lunn, Gregory Clement, Lior Amsalem,
Dmitri Epshtein
In-Reply-To: <1352818843-4457-3-git-send-email-thomas.petazzoni@free-electrons.com>
Thomas Petazzoni <thomas.petazzoni@free-electrons.com> :
[...]
> +static int mvneta_mac_addr_set(struct mvneta_port *pp, unsigned char *addr,
> + int queue)
> +{
> + unsigned int mac_h;
> + unsigned int mac_l;
> +
> + if (queue >= 1) {
> + netdev_err(pp->dev, "RX queue #%d is out of range\n", queue);
> + return -EINVAL;
> + }
(whence q <= 0)
> +
> + if (queue != -1) {
> + mac_l = (addr[4] << 8) | (addr[5]);
> + mac_h = (addr[0] << 24) | (addr[1] << 16) |
> + (addr[2] << 8) | (addr[3] << 0);
> +
> + mvreg_write(pp, MVNETA_MAC_ADDR_LOW, mac_l);
> + mvreg_write(pp, MVNETA_MAC_ADDR_HIGH, mac_h);
> + }
What is it trying to achieve with the "queue" argument ?
[...]
> +/* Refill processing */
> +static int mvneta_rx_refill(struct mvneta_port *pp,
> + struct mvneta_rx_desc *rx_desc)
> +
> +{
> + dma_addr_t phys_addr;
> + struct sk_buff *skb;
> +
> + skb = netdev_alloc_skb(pp->dev, pp->pkt_size);
> + if (!skb)
> + return -ENOMEM;
Could netdev_alloc_skb_ip_align be an option ?
[...]
> +static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
> + struct mvneta_rx_queue *rxq)
> +{
> + struct net_device *dev = pp->dev;
> + int rx_done, rx_filled;
> +
> + /* Get number of received packets */
> + rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
> +
> + if (rx_todo > rx_done)
> + rx_todo = rx_done;
> +
> + rx_done = 0;
> + rx_filled = 0;
> +
> + /* Fairness NAPI loop */
> + while (rx_done < rx_todo) {
> + struct mvneta_rx_desc *rx_desc = mvneta_rxq_next_desc_get(rxq);
> + struct sk_buff *skb;
> + u32 rx_status;
> + int rx_bytes, err;
> +
> + prefetch(rx_desc);
> + rx_done++;
> + rx_filled++;
> + rx_status = rx_desc->status;
> + skb = (struct sk_buff *)rx_desc->buf_cookie;
> +
> + if (!mvneta_rxq_desc_is_first_last(rx_desc) ||
> + (rx_status & MVNETA_RXD_ERR_SUMMARY)) {
> + dev->stats.rx_errors++;
> + mvneta_rx_error(pp, rx_desc);
> + mvneta_rx_desc_fill(rx_desc, rx_desc->buf_phys_addr,
> + (u32)skb);
> + continue;
> + }
> +
> + dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
> + rx_desc->data_size, DMA_FROM_DEVICE);
> +
> + rx_bytes = rx_desc->data_size -
> + (MVNETA_ETH_CRC_SIZE + MVNETA_MH_SIZE);
> + u64_stats_update_begin(&pp->rx_stats.syncp);
> + pp->rx_stats.packets++;
> + pp->rx_stats.bytes += rx_bytes;
> + u64_stats_update_end(&pp->rx_stats.syncp);
> +
> + /* Linux processing */
> + skb_reserve(skb, MVNETA_MH_SIZE);
> + skb_put(skb, rx_bytes);
(I suggested to use skb_reserve / skb_put instead of hand-crafted code but
I may have ignored the elephant in the living room)
I understand the skb_put, ok. What is the purpose of the skb_reserve ?
Are MVNETA_ETH_CRC_SIZE (4) and MVNETA_MH_SIZE (2) really different from
ETH_FCS_LEN and NET_IP_ALIGN ?
[...]
> +static irqreturn_t mvneta_isr(int irq, void *dev_id)
> +{
> + struct mvneta_port *pp = (struct mvneta_port *)dev_id;
> +
> + /* Mask all interrupts */
> + mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
> +
> + /* Verify that the device not already on the polling list */
> + if (napi_schedule_prep(&pp->napi))
> + __napi_schedule(&pp->napi);
Hand-crafted napi_schedule.
[...]
> +static int mvneta_open(struct net_device *dev)
> +{
> + struct mvneta_port *pp = netdev_priv(dev);
> + int ret;
> +
> + ret = mvneta_mac_addr_set(pp, dev->dev_addr, rxq_def);
> + if (ret < 0) {
> + netdev_err(dev, "mvneta_mac_addr_set failed\n");
> + goto mac_addr_set_failure;
> + }
AFAIU mvneta_mac_addr_set can only fail when (module parameter) rxq_def is
not set correctly. It imho calls for a check in probe/remove and a removal
of the failure case in mvneta_mac_addr_set.
> +
> + pp->pkt_size = MVNETA_RX_PKT_SIZE(pp->dev->mtu);
> +
> + ret = mvneta_setup_rxqs(pp);
> + if (ret)
> + goto rxqs_setup_failure;
> +
> + ret = mvneta_setup_txqs(pp);
> + if (ret)
> + goto txqs_setup_failure;
> +
> + /* Connect to port interrupt line */
> + ret = request_irq(pp->dev->irq, mvneta_isr, IRQF_DISABLED,
> + MVNETA_DRIVER_NAME, pp);
include/linux/interrupt.h
[...]
* IRQF_DISABLED - keep irqs disabled when calling the action handler.
* DEPRECATED. This flag is a NOOP and scheduled to be removed
[...]
> +static int __devinit mvneta_probe(struct platform_device *pdev)
> +{
> + const struct mbus_dram_target_info *dram_target_info;
> + struct device_node *dn = pdev->dev.of_node;
> + struct device_node *phy_node;
> + u32 phy_addr, clk_rate_hz;
> + struct mvneta_port *pp;
> + struct net_device *dev;
> + const char *mac_addr;
> + int phy_mode;
> + int err;
> +
> + dev = alloc_etherdev_mq(sizeof(struct mvneta_port), 8);
> + if (!dev)
> + return -ENOMEM;
> +
> + dev->irq = irq_of_parse_and_map(dn, 0);
> + if (dev->irq == 0) {
> + err = -EINVAL;
> + goto err_irq;
> + }
> +
> + phy_node = of_parse_phandle(dn, "phy", 0);
> + if (!phy_node) {
> + dev_err(&pdev->dev, "no associated PHY\n");
> + err = -ENODEV;
> + goto err_node;
> + }
> +
> + phy_mode = of_get_phy_mode(dn);
> + if (phy_mode < 0) {
> + dev_err(&pdev->dev, "incorrect phy-mode\n");
> + err = -EINVAL;
> + goto err_node;
> + }
> +
> + if (of_property_read_u32(dn, "clock-frequency", &clk_rate_hz) != 0) {
> + dev_err(&pdev->dev, "could not read clock-frequency\n");
> + err = -EINVAL;
> + goto err_node;
> + }
> +
> + mac_addr = of_get_mac_address(dn);
> +
> + if (!mac_addr || !is_valid_ether_addr(mac_addr))
> + eth_hw_addr_random(dev);
> + else
> + memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
> +
> + dev->tx_queue_len = MVNETA_MAX_TXD;
> + dev->watchdog_timeo = 5 * HZ;
> + dev->netdev_ops = &mvneta_netdev_ops;
> +
> + SET_ETHTOOL_OPS(dev, &mvneta_eth_tool_ops);
> +
> + pp = netdev_priv(dev);
> +
> + pp->tx_done_timer.function = mvneta_tx_done_timer_callback;
> + init_timer(&pp->tx_done_timer);
> + clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
> +
> + pp->weight = MVNETA_RX_POLL_WEIGHT;
> + pp->clk_rate_hz = clk_rate_hz;
> + pp->phy_node = phy_node;
> + pp->phy_interface = phy_mode;
> +
> + pp->base = of_iomap(dn, 0);
> + if (pp->base == NULL) {
> + err = -ENOMEM;
> + goto err_node;
> + }
> +
> + pp->tx_done_timer.data = (unsigned long)dev;
> +
> + pp->tx_ring_size = MVNETA_MAX_TXD;
> + pp->rx_ring_size = MVNETA_MAX_RXD;
> +
> + pp->dev = dev;
> + SET_NETDEV_DEV(dev, &pdev->dev);
> +
> + if (mvneta_init(pp, phy_addr)) {
> + dev_err(&pdev->dev, "can't init eth hal\n");
> + err = -ENODEV;
> + goto err_base;
> + }
The error code from mvneta_init() should be used.
> + mvneta_port_power_up(pp, phy_mode);
> +
> + dram_target_info = mv_mbus_dram_info();
> + if (dram_target_info)
> + mvneta_conf_mbus_windows(pp, dram_target_info);
> +
> + netif_napi_add(dev, &pp->napi, mvneta_poll, pp->weight);
> +
> + if (register_netdev(dev)) {
> + dev_err(&pdev->dev, "failed to register\n");
> + err = ENOMEM;
> + goto err_base;
> + }
- The error code from register_netdev() should be used.
- Leak: allocations in mvneta_init() are not balanced.
- Nit: the "err_where_did_it_trigger_first" style of label shows its
downside when compared to the "err_what_should_be_done" when
it gets used several times.
> +
> + dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
> + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM;
> + dev->priv_flags |= IFF_UNICAST_FLT;
> +
> + dev_info(&pdev->dev, "%s, mac: %pM\n", dev->name,
> + dev->dev_addr);
> +
> + platform_set_drvdata(pdev, pp->dev);
> +
> + return 0;
> +err_base:
> + iounmap(pp->base);
> +err_node:
> + irq_dispose_mapping(dev->irq);
> +err_irq:
> + free_netdev(dev);
> + return err;
> +}
> +
> +/* Device removal routine */
> +static int __devexit mvneta_remove(struct platform_device *pdev)
> +{
> + struct net_device *dev = platform_get_drvdata(pdev);
> + struct mvneta_port *pp = netdev_priv(dev);
> +
> + iounmap(pp->base);
> +
> + unregister_netdev(dev);
> + irq_dispose_mapping(dev->irq);
> + free_netdev(dev);
> + mvneta_deinit(pp);
One may expect the same ordering as the mvneta_probe unroll sequence.
--
Ueimor
^ permalink raw reply
* Re: [PATCH V3] wanrouter: Remove it and the drivers that depend on it
From: David Miller @ 2012-11-13 23:22 UTC (permalink / raw)
To: joe; +Cc: netdev
In-Reply-To: <1352846164.17444.16.camel@joe-AO722>
From: Joe Perches <joe@perches.com>
Date: Tue, 13 Nov 2012 14:36:04 -0800
> Remove wanrouter as it's obsolete and has not been updated
> by sangoma since 2.4.3 or so and it's not used anymore.
>
> Remove obsolete cyclomx drivers.
> Update files that include now deleted wanrouter bits.
>
> Signed-off-by: Joe Perches <joe@perches.com>
This breaks the build.
drivers/isdn/i4l/isdn_x25iface.c:33:18: error: field ‘state’ has incomplete type
drivers/isdn/i4l/isdn_x25iface.c: In function ‘isdn_x25iface_proto_new’:
drivers/isdn/i4l/isdn_x25iface.c:89:16: error: ‘WAN_UNCONFIGURED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c:89:16: note: each undeclared identifier is reported only once for each function it appears in
drivers/isdn/i4l/isdn_x25iface.c: In function ‘isdn_x25iface_proto_close’:
drivers/isdn/i4l/isdn_x25iface.c:124:16: error: ‘WAN_UNCONFIGURED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c: In function ‘isdn_x25iface_proto_restart’:
drivers/isdn/i4l/isdn_x25iface.c:183:15: error: ‘WAN_DISCONNECTED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c: In function ‘isdn_x25iface_receive’:
drivers/isdn/i4l/isdn_x25iface.c:194:17: error: ‘WAN_CONNECTED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c: In function ‘isdn_x25iface_connect_ind’:
drivers/isdn/i4l/isdn_x25iface.c:216:6: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:216:18: error: ‘WAN_UNCONFIGURED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c:222:2: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:222:13: error: ‘WAN_CONNECTED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c: In function ‘isdn_x25iface_disconn_ind’:
drivers/isdn/i4l/isdn_x25iface.c:246:6: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:246:18: error: ‘WAN_UNCONFIGURED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c:252:2: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:252:13: error: ‘WAN_DISCONNECTED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c: In function ‘isdn_x25iface_xmit’:
drivers/isdn/i4l/isdn_x25iface.c:278:7: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:278:17: error: ‘WAN_CONNECTED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c:286:22: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:289:7: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:289:17: error: ‘WAN_DISCONNECTED’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c:290:4: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:290:13: error: ‘WAN_CONNECTING’ undeclared (first use in this function)
drivers/isdn/i4l/isdn_x25iface.c:298:23: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:302:11: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:314:4: error: dereferencing pointer to incomplete type
drivers/isdn/i4l/isdn_x25iface.c:318:23: error: dereferencing pointer to incomplete type
make[3]: *** [drivers/isdn/i4l/isdn_x25iface.o] Error 1
make[2]: *** [drivers/isdn/i4l] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [drivers/isdn] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [drivers] Error 2
make: *** Waiting for unfinished jobs....
^ permalink raw reply
* Re: [PATCH net-next 2/2] ARM: net: bpf_jit_32: add VLAN instructions for BPF JIT
From: David Miller @ 2012-11-13 23:21 UTC (permalink / raw)
To: mgherzan; +Cc: dxchgb, arnd, netdev, linux-arm-kernel
In-Reply-To: <50A2D114.8080306@gmail.com>
From: Mircea Gherzan <mgherzan@gmail.com>
Date: Wed, 14 Nov 2012 00:00:36 +0100
> Am 08.11.2012 02:31, schrieb Daniel Borkmann:
>> This patch is a follow-up for patch "net: filter: add vlan tag access"
>> to support the new VLAN_TAG/VLAN_TAG_PRESENT accessors in BPF JIT.
>>
>> Signed-off-by: Daniel Borkmann <daniel.borkmann@tik.ee.ethz.ch>
...
> Acked-by: Mircea Gherzan <mgherzan@gmail.com>
Applied, thanks again.
^ permalink raw reply
* Re: [PATCH net-next 1/2] ARM: net: bpf_jit_32: add XOR instruction for BPF JIT
From: David Miller @ 2012-11-13 23:21 UTC (permalink / raw)
To: mgherzan; +Cc: dxchgb, arnd, netdev, linux-arm-kernel
In-Reply-To: <50A2D0F4.3090202@gmail.com>
From: Mircea Gherzan <mgherzan@gmail.com>
Date: Wed, 14 Nov 2012 00:00:04 +0100
> Am 08.11.2012 02:28, schrieb Daniel Borkmann:
>> This patch is a follow-up for patch "filter: add XOR instruction for use
>> with X/K" that implements BPF ARM JIT parts for the BPF XOR operation.
>>
>> Signed-off-by: Daniel Borkmann <daniel.borkmann@tik.ee.ethz.ch>
...
> Acked-by: Mircea Gherzan <mgherzan@gmail.com>
Applied, thanks for reviewing.
^ permalink raw reply
* Re: [PATCH] vxlan: Update hard_header_len based on lowerdev when instantiating VXLAN
From: David Miller @ 2012-11-13 23:20 UTC (permalink / raw)
To: shemminger; +Cc: alexander.h.duyck, netdev
In-Reply-To: <20121113151200.16afce74@nehalam.linuxnetplumber.net>
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Tue, 13 Nov 2012 15:12:00 -0800
> On Tue, 13 Nov 2012 15:10:59 -0800
> Alexander Duyck <alexander.h.duyck@intel.com> wrote:
>
>> In the event of a VXLAN device being linked to a device that has a
>> hard_header_len greater than that of standard ethernet we could end up with
>> the hard_header_len not being large enough for outgoing frames. In order to
>> prevent this we should update the length when a lowerdev is provided.
>>
>> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
...
> Acked-by: Stephen Hemminger <shemminger@vyatta.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next] 8021q: validate SAN MAC address
From: David Miller @ 2012-11-13 23:16 UTC (permalink / raw)
To: mchan; +Cc: netdev
In-Reply-To: <1352845788.6276.28.camel@LTIRV-MCHAN1.corp.ad.broadcom.com>
From: "Michael Chan" <mchan@broadcom.com>
Date: Tue, 13 Nov 2012 14:29:48 -0800
> We need to have VLAN tags inserted to packets using that interface.
> The VID is dynamically discovered by application. How do suggest we
> do that if we don't use 8021q?
Ok. So what's the reason that the VLAN device isn't given a
valid MAC address, for example why not use the SAN one?
^ permalink raw reply
* Re: [PATCH] vxlan: Update hard_header_len based on lowerdev when instantiating VXLAN
From: Stephen Hemminger @ 2012-11-13 23:12 UTC (permalink / raw)
To: Alexander Duyck; +Cc: netdev, davem
In-Reply-To: <20121113230955.16102.62399.stgit@ahduyck-cp1.jf.intel.com>
On Tue, 13 Nov 2012 15:10:59 -0800
Alexander Duyck <alexander.h.duyck@intel.com> wrote:
> In the event of a VXLAN device being linked to a device that has a
> hard_header_len greater than that of standard ethernet we could end up with
> the hard_header_len not being large enough for outgoing frames. In order to
> prevent this we should update the length when a lowerdev is provided.
>
> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
> ---
>
> drivers/net/vxlan.c | 4 ++++
> 1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index 44bcc20..6b666eb 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -1110,6 +1110,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
>
> if (!tb[IFLA_MTU])
> dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
> +
> + /* update header length based on lower device */
> + dev->hard_header_len = lowerdev->hard_header_len +
> + VXLAN_HEADROOM;
> }
>
> if (data[IFLA_VXLAN_TOS])
>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
^ permalink raw reply
* [PATCH] vxlan: Update hard_header_len based on lowerdev when instantiating VXLAN
From: Alexander Duyck @ 2012-11-13 23:10 UTC (permalink / raw)
To: netdev; +Cc: shemminger, davem
In-Reply-To: <20121113133353.227ec987@nehalam.linuxnetplumber.net>
In the event of a VXLAN device being linked to a device that has a
hard_header_len greater than that of standard ethernet we could end up with
the hard_header_len not being large enough for outgoing frames. In order to
prevent this we should update the length when a lowerdev is provided.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
drivers/net/vxlan.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 44bcc20..6b666eb 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1110,6 +1110,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
if (!tb[IFLA_MTU])
dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
+
+ /* update header length based on lower device */
+ dev->hard_header_len = lowerdev->hard_header_len +
+ VXLAN_HEADROOM;
}
if (data[IFLA_VXLAN_TOS])
^ permalink raw reply related
* Re: [PATCH net-next 2/2] ARM: net: bpf_jit_32: add VLAN instructions for BPF JIT
From: Mircea Gherzan @ 2012-11-13 23:00 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: davem, Arnd Bergmann, netdev, linux-arm-kernel
In-Reply-To: <20121108013101.GB23143@thinkbox>
Am 08.11.2012 02:31, schrieb Daniel Borkmann:
> This patch is a follow-up for patch "net: filter: add vlan tag access"
> to support the new VLAN_TAG/VLAN_TAG_PRESENT accessors in BPF JIT.
>
> Signed-off-by: Daniel Borkmann <daniel.borkmann@tik.ee.ethz.ch>
> Cc: Mircea Gherzan <mgherzan@gmail.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> ---
> arch/arm/net/bpf_jit_32.c | 14 ++++++++++++++
> 1 files changed, 14 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
> index 8be702d..9af9a69 100644
> --- a/arch/arm/net/bpf_jit_32.c
> +++ b/arch/arm/net/bpf_jit_32.c
> @@ -16,6 +16,7 @@
> #include <linux/netdevice.h>
> #include <linux/string.h>
> #include <linux/slab.h>
> +#include <linux/if_vlan.h>
> #include <asm/cacheflush.h>
> #include <asm/hwcap.h>
>
> @@ -168,6 +169,8 @@ static inline bool is_load_to_a(u16 inst)
> case BPF_S_ANC_MARK:
> case BPF_S_ANC_PROTOCOL:
> case BPF_S_ANC_RXHASH:
> + case BPF_S_ANC_VLAN_TAG:
> + case BPF_S_ANC_VLAN_TAG_PRESENT:
> case BPF_S_ANC_QUEUE:
> return true;
> default:
> @@ -815,6 +818,17 @@ b_epilogue:
> off = offsetof(struct sk_buff, rxhash);
> emit(ARM_LDR_I(r_A, r_skb, off), ctx);
> break;
> + case BPF_S_ANC_VLAN_TAG:
> + case BPF_S_ANC_VLAN_TAG_PRESENT:
> + ctx->seen |= SEEN_SKB;
> + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
> + off = offsetof(struct sk_buff, vlan_tci);
> + emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
> + if (inst->code == BPF_S_ANC_VLAN_TAG)
> + OP_IMM3(ARM_AND, r_A, r_A, VLAN_VID_MASK, ctx);
> + else
> + OP_IMM3(ARM_AND, r_A, r_A, VLAN_TAG_PRESENT, ctx);
> + break;
> case BPF_S_ANC_QUEUE:
> ctx->seen |= SEEN_SKB;
> BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
Acked-by: Mircea Gherzan <mgherzan@gmail.com>
^ permalink raw reply
* Re: [PATCH net-next 1/2] ARM: net: bpf_jit_32: add XOR instruction for BPF JIT
From: Mircea Gherzan @ 2012-11-13 23:00 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: davem, Arnd Bergmann, netdev, linux-arm-kernel
In-Reply-To: <20121108012828.GA23143@thinkbox>
Am 08.11.2012 02:28, schrieb Daniel Borkmann:
> This patch is a follow-up for patch "filter: add XOR instruction for use
> with X/K" that implements BPF ARM JIT parts for the BPF XOR operation.
>
> Signed-off-by: Daniel Borkmann <daniel.borkmann@tik.ee.ethz.ch>
> Cc: Mircea Gherzan <mgherzan@gmail.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> ---
> arch/arm/net/bpf_jit_32.c | 15 ++++++++++-----
> arch/arm/net/bpf_jit_32.h | 2 ++
> 2 files changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
> index c641fb6..8be702d 100644
> --- a/arch/arm/net/bpf_jit_32.c
> +++ b/arch/arm/net/bpf_jit_32.c
> @@ -646,6 +646,16 @@ load_ind:
> update_on_xread(ctx);
> emit(ARM_ORR_R(r_A, r_A, r_X), ctx);
> break;
> + case BPF_S_ALU_XOR_K:
> + /* A ^= K; */
> + OP_IMM3(ARM_EOR, r_A, r_A, k, ctx);
> + break;
> + case BPF_S_ANC_ALU_XOR_X:
> + case BPF_S_ALU_XOR_X:
> + /* A ^= X */
> + update_on_xread(ctx);
> + emit(ARM_EOR_R(r_A, r_A, r_X), ctx);
> + break;
> case BPF_S_ALU_AND_K:
> /* A &= K */
> OP_IMM3(ARM_AND, r_A, r_A, k, ctx);
> @@ -762,11 +772,6 @@ b_epilogue:
> update_on_xread(ctx);
> emit(ARM_MOV_R(r_A, r_X), ctx);
> break;
> - case BPF_S_ANC_ALU_XOR_X:
> - /* A ^= X */
> - update_on_xread(ctx);
> - emit(ARM_EOR_R(r_A, r_A, r_X), ctx);
> - break;
> case BPF_S_ANC_PROTOCOL:
> /* A = ntohs(skb->protocol) */
> ctx->seen |= SEEN_SKB;
> diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h
> index 7fa2f7d..afb8462 100644
> --- a/arch/arm/net/bpf_jit_32.h
> +++ b/arch/arm/net/bpf_jit_32.h
> @@ -69,6 +69,7 @@
> #define ARM_INST_CMP_I 0x03500000
>
> #define ARM_INST_EOR_R 0x00200000
> +#define ARM_INST_EOR_I 0x02200000
>
> #define ARM_INST_LDRB_I 0x05d00000
> #define ARM_INST_LDRB_R 0x07d00000
> @@ -135,6 +136,7 @@
> #define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm)
>
> #define ARM_EOR_R(rd, rn, rm) _AL3_R(ARM_INST_EOR, rd, rn, rm)
> +#define ARM_EOR_I(rd, rn, imm) _AL3_I(ARM_INST_EOR, rd, rn, imm)
>
> #define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \
> | (off))
Acked-by: Mircea Gherzan <mgherzan@gmail.com>
^ permalink raw reply
* Re: [REGRESSION] r8169: jumbo fixes caused jumbo regressions!
From: Francois Romieu @ 2012-11-13 22:35 UTC (permalink / raw)
To: Kirill Smelkov
Cc: Realtek linux nic maintainers, Hayes Wang, David S. Miller,
Greg Kroah-Hartman, netdev
In-Reply-To: <20121113170655.GA20291@tugrik.mns.mnsspb.ru>
Kirill Smelkov <kirr@mns.spb.ru> :
[...]
> My test is to stream raw video from 8 PAL cameras to net - 4 for 720x576@25 and
> 4 for 360x288@25 which for YUYV format occupies ~ 860 Mbps of bandwidth. The
> program to transmit/receive video is here: http://repo.or.cz/w/rawv.git
$ git clone http://repo.or.cz/w/rawv.git
Cloning into 'rawv'...
fatal: http://repo.or.cz/w/rawv.git/info/refs not valid: is this a git repository?
[...]
> (by the way, on atom system, without tx csum offload, half of cpu time
> is spent only to calculate checksums...)
:o(
> Now I wonder, where that 6K limit came from and why they say it is now
> not possible to use jumbos together with tx csum offload ?
Here is an excerpt from a mail where Hayes explained the rules of
engagement back in may 2011 (John Lumby and Chris Friesen were Cced then):
! The Max tx sizes for 8168 series are as following:
!
! 8168B is 4K bytes.
! 8168C and 8168CP are 6K bytes.
! 8168D and later are 9K bytes.
!
! Note that these sizes all include head size. That is, the mtu must less than
! these values.
! You have to enable Jumbo frame feature when the tx size is large, otherwise the
! packet would not be sent. Because the hw doesn't provide the threshold, the
! checking for MTU > 1500 is just for convenience for sw.
!
! The TSO couldn't work with some feature which need to disable hw checksum, such
! as Jumbo frame. The hw checksum have to be disabled in certain situations, so
! the TSO feature should be checked in these situations, too.
> Is my testing enough to justify raising the limits and allowing tx offload ?
I don't oppose knobs to go off-limits but I'll need some rather good reason
before changing the manufacturer's suggested defaults.
--
Ueimor
^ permalink raw reply
* Re: [PATCH net-next] add DOVE extensions for VXLAN
From: Stephen Hemminger @ 2012-11-13 22:41 UTC (permalink / raw)
To: David Stevens; +Cc: David Miller, netdev
In-Reply-To: <OFD9622F46.08427B4F-ON85257AB5.00792B0C-85257AB5.007B6F17@us.ibm.com>
On Tue, 13 Nov 2012 17:28:17 -0500
David Stevens <dlstevens@us.ibm.com> wrote:
> Stephen Hemminger <shemminger@vyatta.com> wrote on 11/13/2012 04:28:42 PM:
>
> >
> > There are some issues with this.
> > 1. DOVE flag is mixing multiple functions (arp and route) together,
> > users may want one without the other.
>
> I can separate these.
>
> > 2. There is an implicit assumption that IP stack has valid IP address
> > in the tenant network (vxlan). This is rarely the case. For security
> > and other reasons, in my opinion the best practice is not to have
> > the bridge as part of the tenant network.
>
> No, actually for testing I didn't set an IP address on the tunnel
> endpoint at all. The neighbor table entries must be in the domain, but
> they are only used within the domain when the tunnel endpoint is on a
> bridge and the host has no IP address on that interface.
>
> > 3. Misses might be common and this could easily be used to DoS the host
> > from a malicious guest.
>
> Yes. The management piece can add forwarding table entries with
> "0.0.0.0" as the dst IP address to disable MAC misses, and neighbor
> table entries to disable IP misses, but it is our intention to have all
> reachable destinations with both forwarding table and neighbor table
> entries and no learning or multicast address (ie, no forwarding of
> anything
> that isn't in the forwarding table). And yes, we want a notification
> for every miss packet.
> Someone who doesn't want all of them shouldn't use this feature.
> If we're dropping the "dove" flag in favor of individual flags for each
> feature, then I could make this into "l2miss" and "l3miss" flags and
> they should default off, of course.
>
> +-DLS
Maybe a OVS style "here is the homeless packet" message is needed.
That would allow for controller in user space to populate table
on as needed basis.
^ permalink raw reply
* Re: [tcpdump-workers] vlan tagged packets and libpcap breakage
From: Ani Sinha @ 2012-11-13 22:42 UTC (permalink / raw)
Cc: Guy Harris, netdev, tcpdump-workers, Michael Richardson,
Francesco Ruggeri
In-Reply-To: <CAOxq_8N7mSY9rLTeSdUohV5ufU+QF7DtrjwZ3xnAbuP9mRm3jQ@mail.gmail.com>
Folks,
I'm wondering if there has been any progress on this. Are there any
thoughts on what Bill wrote in his email?
Thanks
On Tue, Nov 13, 2012 at 2:41 PM, Ani Sinha <ani@aristanetworks.com> wrote:
> Folks,
>
> I'm wondering if there has been any progress on this. Are there any thoughts
> on what Bill wrote in his email?
>
> Thanks
> ani
>
>
>
> On Fri, Nov 2, 2012 at 9:13 AM, Bill Fenner <fenner@gmail.com> wrote:
>>
>> On Wed, Oct 31, 2012 at 6:20 PM, Guy Harris <guy@alum.mit.edu> wrote:
>> >
>> > On Oct 31, 2012, at 2:50 PM, Ani Sinha <ani@aristanetworks.com> wrote:
>> >
>> >> pcap files that already have the tags reinsrted should work with
>> >> current filter code. However for live traffic, one has to get the tags
>> >> from CMSG() and then reinsert it back to the packet for the current
>> >> filter to work.
>> >
>> > *Somebody* has to do that, at least to packets that pass the filter,
>> > before they're handed to a libpcap-based application, for programs that
>> > expect to see packets as they arrived from/were transmitted to the wire to
>> > work.
>> >
>> > I.e., the tags *should* be reinserted by libpcap, and, as I understand
>> > it, that's what the
>> >
>> > #if defined(HAVE_PACKET_AUXDATA) &&
>> > defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI)
>> > ...
>> > #endif
>> >
>> > blocks of code in pcap-linux.c in libpcap are doing.
>> >
>> > Now, if filtering is being done in the *kernel*, and the tags aren't
>> > being reinserted by the kernel, then filter code stuffed into the kernel
>> > would need to differ from filter code run in userland. There's already
>> > precedent for that on Linux, with the "cooked mode" headers; those are
>> > synthesized by libpcap from the metadata returned for PF_PACKET sockets, and
>> > the code that attempts to hand the kernel a filter goes through the filter
>> > code, which was generated under the assumption that the packet begins with a
>> > "cooked mode" header, and modifies (a copy of) the code to, instead, use the
>> > special Linux-BPF-interpreter offsets to access the metadata.
>> >
>> > The right thing to do here would be to, if possible, do the same, so
>> > that the kernel doesn't have to reinsert VLAN tags for packets that aren't
>> > going to be handed to userland.
>>
>> In this case, it would be incredibly complicated to do this just
>> postprocessing a set of bpf instructions. The problem is that when
>> running the filter in the kernel, the IP header, etc. are not offset,
>> so "off_macpl" and "off_linktype" would be zero, not 4, while
>> generating the rest of the expression. We would also have to insert
>> code when comparing the ethertype to 0x8100 to instead load the
>> vlan-tagged metadata, so all jumps crossing that point would have to
>> be adjusted, and if the "if-false" instruction was also testing the
>> ethertype, then the ethertype would have to be reloaded (again
>> inserting another instruction).
>>
>> Basically, take a look at the output of "tcpdump -d tcp port 22 or
>> (vlan and tcp port 22)". Are the IPv4 tcp ports at x+14/x+16, or at
>> x+18/x+20? If we're filtering in the kernel, they're at x+14/x+16
>> whether the packet is vlan tagged or not. If we're filtering on the
>> actual packet contents (from a savefile, for example), they're at
>> x+18/x+20 if the packet is vlan tagged.
>>
>> Also, an expression such as 'tcp port 22' would have to have some
>> instructions added at the beginning, for "vlan-tagged == false", or it
>> would match both tagged and untagged packets.
>>
>> This would be much more straightforward to deal with in the code
>> generation phase, except until now the code generation phase hasn't
>> known whether the filter is headed for the kernel or not.
>>
>> Bill
>
>
^ permalink raw reply
* Re: vlan tagged packets and libpcap breakage
From: Ani Sinha @ 2012-11-13 22:41 UTC (permalink / raw)
To: Bill Fenner
Cc: netdev, Michael Richardson, tcpdump-workers, Francesco Ruggeri
In-Reply-To: <CAF4SogYMyANyZ4-RYoVHf3TewPVQgR49m5HLDdwVMJ7sn8_XxQ@mail.gmail.com>
Folks,
I'm wondering if there has been any progress on this. Are there any
thoughts on what Bill wrote in his email?
Thanks
ani
On Fri, Nov 2, 2012 at 9:13 AM, Bill Fenner <fenner@gmail.com> wrote:
> On Wed, Oct 31, 2012 at 6:20 PM, Guy Harris <guy@alum.mit.edu> wrote:
> >
> > On Oct 31, 2012, at 2:50 PM, Ani Sinha <ani@aristanetworks.com> wrote:
> >
> >> pcap files that already have the tags reinsrted should work with
> >> current filter code. However for live traffic, one has to get the tags
> >> from CMSG() and then reinsert it back to the packet for the current
> >> filter to work.
> >
> > *Somebody* has to do that, at least to packets that pass the filter,
> before they're handed to a libpcap-based application, for programs that
> expect to see packets as they arrived from/were transmitted to the wire to
> work.
> >
> > I.e., the tags *should* be reinserted by libpcap, and, as I understand
> it, that's what the
> >
> > #if defined(HAVE_PACKET_AUXDATA) &&
> defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI)
> > ...
> > #endif
> >
> > blocks of code in pcap-linux.c in libpcap are doing.
> >
> > Now, if filtering is being done in the *kernel*, and the tags aren't
> being reinserted by the kernel, then filter code stuffed into the kernel
> would need to differ from filter code run in userland. There's already
> precedent for that on Linux, with the "cooked mode" headers; those are
> synthesized by libpcap from the metadata returned for PF_PACKET sockets,
> and the code that attempts to hand the kernel a filter goes through the
> filter code, which was generated under the assumption that the packet
> begins with a "cooked mode" header, and modifies (a copy of) the code to,
> instead, use the special Linux-BPF-interpreter offsets to access the
> metadata.
> >
> > The right thing to do here would be to, if possible, do the same, so
> that the kernel doesn't have to reinsert VLAN tags for packets that aren't
> going to be handed to userland.
>
> In this case, it would be incredibly complicated to do this just
> postprocessing a set of bpf instructions. The problem is that when
> running the filter in the kernel, the IP header, etc. are not offset,
> so "off_macpl" and "off_linktype" would be zero, not 4, while
> generating the rest of the expression. We would also have to insert
> code when comparing the ethertype to 0x8100 to instead load the
> vlan-tagged metadata, so all jumps crossing that point would have to
> be adjusted, and if the "if-false" instruction was also testing the
> ethertype, then the ethertype would have to be reloaded (again
> inserting another instruction).
>
> Basically, take a look at the output of "tcpdump -d tcp port 22 or
> (vlan and tcp port 22)". Are the IPv4 tcp ports at x+14/x+16, or at
> x+18/x+20? If we're filtering in the kernel, they're at x+14/x+16
> whether the packet is vlan tagged or not. If we're filtering on the
> actual packet contents (from a savefile, for example), they're at
> x+18/x+20 if the packet is vlan tagged.
>
> Also, an expression such as 'tcp port 22' would have to have some
> instructions added at the beginning, for "vlan-tagged == false", or it
> would match both tagged and untagged packets.
>
> This would be much more straightforward to deal with in the code
> generation phase, except until now the code generation phase hasn't
> known whether the filter is headed for the kernel or not.
>
> Bill
>
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers@lists.tcpdump.org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers
^ permalink raw reply
* Re: [RFC net-next] tun: implement BQL
From: Stephen Hemminger @ 2012-11-13 22:39 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20121113.171939.1673751173342429141.davem@davemloft.net>
On Tue, 13 Nov 2012 17:19:39 -0500 (EST)
David Miller <davem@davemloft.net> wrote:
> From: Stephen Hemminger <shemminger@vyatta.com>
> Date: Mon, 12 Nov 2012 13:22:41 -0800
>
> > Add multiqueue BQL to tap device. Tested with VPN, doesn't have a big impact,
> > most likely because there is little queueing occuring at TAP device except
> > under case of forwarding.
> >
> > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
> I think unless we can show it making an impact in a normal
> usage scenerio, we should leave it alone for now.
Agreed, that is why I submitted as RFC.
^ permalink raw reply
* [PATCH V3] wanrouter: Remove it and the drivers that depend on it
From: Joe Perches @ 2012-11-13 22:36 UTC (permalink / raw)
To: netdev
Remove wanrouter as it's obsolete and has not been updated
by sangoma since 2.4.3 or so and it's not used anymore.
Remove obsolete cyclomx drivers.
Update files that include now deleted wanrouter bits.
Signed-off-by: Joe Perches <joe@perches.com>
---
Resending in a different form because
git format-patch -M -D creates a patch
that can not be applied cleanly via git am.
Documentation/ioctl/ioctl-number.txt | 1 -
Documentation/magic-number.txt | 1 -
Documentation/zh_CN/magic-number.txt | 1 -
drivers/isdn/i4l/isdn_x25iface.c | 1 -
drivers/isdn/i4l/isdn_x25iface.h | 1 -
drivers/net/wan/Kconfig | 54 --
drivers/net/wan/Makefile | 5 -
drivers/net/wan/cycx_drv.c | 569 ------------
drivers/net/wan/cycx_main.c | 346 --------
drivers/net/wan/cycx_x25.c | 1602 ----------------------------------
include/linux/cyclomx.h | 77 --
include/linux/cycx_drv.h | 64 --
include/linux/wanrouter.h | 129 ---
include/uapi/linux/Kbuild | 1 -
include/uapi/linux/wanrouter.h | 452 ----------
net/Kconfig | 1 -
net/Makefile | 1 -
net/socket.c | 1 -
net/wanrouter/Kconfig | 27 -
net/wanrouter/Makefile | 7 -
net/wanrouter/patchlevel | 1 -
net/wanrouter/wanmain.c | 782 -----------------
net/wanrouter/wanproc.c | 380 --------
23 files changed, 0 insertions(+), 4504 deletions(-)
delete mode 100644 drivers/net/wan/cycx_drv.c
delete mode 100644 drivers/net/wan/cycx_main.c
delete mode 100644 drivers/net/wan/cycx_x25.c
delete mode 100644 include/linux/cyclomx.h
delete mode 100644 include/linux/cycx_drv.h
delete mode 100644 include/linux/wanrouter.h
delete mode 100644 include/uapi/linux/wanrouter.h
delete mode 100644 net/wanrouter/Kconfig
delete mode 100644 net/wanrouter/Makefile
delete mode 100644 net/wanrouter/patchlevel
delete mode 100644 net/wanrouter/wanmain.c
delete mode 100644 net/wanrouter/wanproc.c
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 2152b0e..028a034 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -179,7 +179,6 @@ Code Seq#(hex) Include File Comments
'V' C0 media/davinci/vpfe_capture.h conflict!
'V' C0 media/si4713.h conflict!
'W' 00-1F linux/watchdog.h conflict!
-'W' 00-1F linux/wanrouter.h conflict!
'W' 00-3F sound/asound.h conflict!
'X' all fs/xfs/xfs_fs.h conflict!
and fs/xfs/linux-2.6/xfs_ioctl32.h
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index 82761a3..0c39e72 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -122,7 +122,6 @@ SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
I810_CARD_MAGIC 0x5072696E i810_card sound/oss/i810_audio.c
TRIDENT_CARD_MAGIC 0x5072696E trident_card sound/oss/trident.c
-ROUTER_MAGIC 0x524d4157 wan_device include/linux/wanrouter.h
SCC_MAGIC 0x52696368 gs_port drivers/char/scc.h
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
diff --git a/Documentation/zh_CN/magic-number.txt b/Documentation/zh_CN/magic-number.txt
index 4263022..51b7e15 100644
--- a/Documentation/zh_CN/magic-number.txt
+++ b/Documentation/zh_CN/magic-number.txt
@@ -122,7 +122,6 @@ SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
I810_CARD_MAGIC 0x5072696E i810_card sound/oss/i810_audio.c
TRIDENT_CARD_MAGIC 0x5072696E trident_card sound/oss/trident.c
-ROUTER_MAGIC 0x524d4157 wan_device include/linux/wanrouter.h
SCC_MAGIC 0x52696368 gs_port drivers/char/scc.h
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c
index e2d4e58..d00c86d 100644
--- a/drivers/isdn/i4l/isdn_x25iface.c
+++ b/drivers/isdn/i4l/isdn_x25iface.c
@@ -21,7 +21,6 @@
#include <linux/netdevice.h>
#include <linux/concap.h>
#include <linux/slab.h>
-#include <linux/wanrouter.h>
#include <net/x25device.h>
#include "isdn_x25iface.h"
diff --git a/drivers/isdn/i4l/isdn_x25iface.h b/drivers/isdn/i4l/isdn_x25iface.h
index 0b26e3b..ca08e08 100644
--- a/drivers/isdn/i4l/isdn_x25iface.h
+++ b/drivers/isdn/i4l/isdn_x25iface.h
@@ -19,7 +19,6 @@
#endif
#include <linux/skbuff.h>
-#include <linux/wanrouter.h>
#include <linux/isdn.h>
#include <linux/concap.h>
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index d58431e..0c077b0 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -356,60 +356,6 @@ config SDLA
To compile this driver as a module, choose M here: the
module will be called sdla.
-# Wan router core.
-config WAN_ROUTER_DRIVERS
- tristate "WAN router drivers"
- depends on WAN_ROUTER
- ---help---
- Connect LAN to WAN via Linux box.
-
- Select driver your card and remember to say Y to "Wan Router."
- You will need the wan-tools package which is available from
- <ftp://ftp.sangoma.com/>.
-
- Note that the answer to this question won't directly affect the
- kernel except for how subordinate drivers may be built:
- saying N will just cause the configurator to skip all
- the questions about WAN router drivers.
-
- If unsure, say N.
-
-config CYCLADES_SYNC
- tristate "Cyclom 2X(tm) cards (EXPERIMENTAL)"
- depends on WAN_ROUTER_DRIVERS && (PCI || ISA)
- ---help---
- Cyclom 2X from Cyclades Corporation <http://www.avocent.com/> is an
- intelligent multiprotocol WAN adapter with data transfer rates up to
- 512 Kbps. These cards support the X.25 and SNA related protocols.
-
- While no documentation is available at this time please grab the
- wanconfig tarball in
- <http://www.conectiva.com.br/~acme/cycsyn-devel/> (with minor changes
- to make it compile with the current wanrouter include files; efforts
- are being made to use the original package available at
- <ftp://ftp.sangoma.com/>).
-
- Feel free to contact me or the cycsyn-devel mailing list at
- <acme@conectiva.com.br> and <cycsyn-devel@bazar.conectiva.com.br> for
- additional details, I hope to have documentation available as soon as
- possible. (Cyclades Brazil is writing the Documentation).
-
- The next questions will ask you about the protocols you want the
- driver to support (for now only X.25 is supported).
-
- If you have one or more of these cards, say Y to this option.
-
- To compile this driver as a module, choose M here: the
- module will be called cyclomx.
-
-config CYCLOMX_X25
- bool "Cyclom 2X X.25 support (EXPERIMENTAL)"
- depends on CYCLADES_SYNC
- help
- Connect a Cyclom 2X card to an X.25 network.
-
- Enabling X.25 support will enlarge your kernel by about 11 kB.
-
# X.25 network drivers
config LAPBETHER
tristate "LAPB over Ethernet driver (EXPERIMENTAL)"
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index df70248..c135ef4 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -5,10 +5,6 @@
# Rewritten to use lists instead of if-statements.
#
-cyclomx-y := cycx_main.o
-cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o
-cyclomx-objs := $(cyclomx-y)
-
obj-$(CONFIG_HDLC) += hdlc.o
obj-$(CONFIG_HDLC_RAW) += hdlc_raw.o
obj-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o
@@ -28,7 +24,6 @@ obj-$(CONFIG_LANMEDIA) += lmc/
obj-$(CONFIG_DLCI) += dlci.o
obj-$(CONFIG_SDLA) += sdla.o
-obj-$(CONFIG_CYCLADES_SYNC) += cycx_drv.o cyclomx.o
obj-$(CONFIG_LAPBETHER) += lapbether.o
obj-$(CONFIG_SBNI) += sbni.o
obj-$(CONFIG_N2) += n2.o
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
deleted file mode 100644
index 2a3ecae..0000000
--- a/drivers/net/wan/cycx_drv.c
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
-* cycx_drv.c Cyclom 2X Support Module.
-*
-* This module is a library of common hardware specific
-* functions used by the Cyclades Cyclom 2X sync card.
-*
-* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-*
-* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
-*
-* Based on sdladrv.c by Gene Kozin <genek@compuserve.com>
-*
-* 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.
-* ============================================================================
-* 1999/11/11 acme set_current_state(TASK_INTERRUPTIBLE), code
-* cleanup
-* 1999/11/08 acme init_cyc2x deleted, doing nothing
-* 1999/11/06 acme back to read[bw], write[bw] and memcpy_to and
-* fromio to use dpmbase ioremaped
-* 1999/10/26 acme use isa_read[bw], isa_write[bw] & isa_memcpy_to
-* & fromio
-* 1999/10/23 acme cleanup to only supports cyclom2x: all the other
-* boards are no longer manufactured by cyclades,
-* if someone wants to support them... be my guest!
-* 1999/05/28 acme cycx_intack & cycx_intde gone for good
-* 1999/05/18 acme lots of unlogged work, submitting to Linus...
-* 1999/01/03 acme more judicious use of data types
-* 1999/01/03 acme judicious use of data types :>
-* cycx_inten trying to reset pending interrupts
-* from cyclom 2x - I think this isn't the way to
-* go, but for now...
-* 1999/01/02 acme cycx_intack ok, I think there's nothing to do
-* to ack an int in cycx_drv.c, only handle it in
-* cyx_isr (or in the other protocols: cyp_isr,
-* cyf_isr, when they get implemented.
-* Dec 31, 1998 acme cycx_data_boot & cycx_code_boot fixed, crossing
-* fingers to see x25_configure in cycx_x25.c
-* work... :)
-* Dec 26, 1998 acme load implementation fixed, seems to work! :)
-* cycx_2x_dpmbase_options with all the possible
-* DPM addresses (20).
-* cycx_intr implemented (test this!)
-* general code cleanup
-* Dec 8, 1998 Ivan Passos Cyclom-2X firmware load implementation.
-* Aug 8, 1998 acme Initial version.
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h> /* __init */
-#include <linux/module.h>
-#include <linux/kernel.h> /* printk(), and other useful stuff */
-#include <linux/stddef.h> /* offsetof(), etc. */
-#include <linux/errno.h> /* return codes */
-#include <linux/cycx_drv.h> /* API definitions */
-#include <linux/cycx_cfm.h> /* CYCX firmware module definitions */
-#include <linux/delay.h> /* udelay, msleep_interruptible */
-#include <asm/io.h> /* read[wl], write[wl], ioremap, iounmap */
-
-#define MOD_VERSION 0
-#define MOD_RELEASE 6
-
-MODULE_AUTHOR("Arnaldo Carvalho de Melo");
-MODULE_DESCRIPTION("Cyclom 2x Sync Card Driver");
-MODULE_LICENSE("GPL");
-
-/* Hardware-specific functions */
-static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len);
-static void cycx_bootcfg(struct cycx_hw *hw);
-
-static int reset_cyc2x(void __iomem *addr);
-static int detect_cyc2x(void __iomem *addr);
-
-/* Miscellaneous functions */
-static int get_option_index(const long *optlist, long optval);
-static u16 checksum(u8 *buf, u32 len);
-
-#define wait_cyc(addr) cycx_exec(addr + CMD_OFFSET)
-
-/* Global Data */
-
-/* private data */
-static const char fullname[] = "Cyclom 2X Support Module";
-static const char copyright[] =
- "(c) 1998-2003 Arnaldo Carvalho de Melo <acme@conectiva.com.br>";
-
-/* Hardware configuration options.
- * These are arrays of configuration options used by verification routines.
- * The first element of each array is its size (i.e. number of options).
- */
-static const long cyc2x_dpmbase_options[] = {
- 20,
- 0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, 0xB8000,
- 0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000, 0xD0000, 0xD4000,
- 0xD8000, 0xDC000, 0xE0000, 0xE4000, 0xE8000, 0xEC000
-};
-
-static const long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 };
-
-/* Kernel Loadable Module Entry Points */
-/* Module 'insert' entry point.
- * o print announcement
- * o initialize static data
- *
- * Return: 0 Ok
- * < 0 error.
- * Context: process */
-
-static int __init cycx_drv_init(void)
-{
- pr_info("%s v%u.%u %s\n",
- fullname, MOD_VERSION, MOD_RELEASE, copyright);
-
- return 0;
-}
-
-/* Module 'remove' entry point.
- * o release all remaining system resources */
-static void cycx_drv_cleanup(void)
-{
-}
-
-/* Kernel APIs */
-/* Set up adapter.
- * o detect adapter type
- * o verify hardware configuration options
- * o check for hardware conflicts
- * o set up adapter shared memory
- * o test adapter memory
- * o load firmware
- * Return: 0 ok.
- * < 0 error */
-EXPORT_SYMBOL(cycx_setup);
-int cycx_setup(struct cycx_hw *hw, void *cfm, u32 len, unsigned long dpmbase)
-{
- int err;
-
- /* Verify IRQ configuration options */
- if (!get_option_index(cycx_2x_irq_options, hw->irq)) {
- pr_err("IRQ %d is invalid!\n", hw->irq);
- return -EINVAL;
- }
-
- /* Setup adapter dual-port memory window and test memory */
- if (!dpmbase) {
- pr_err("you must specify the dpm address!\n");
- return -EINVAL;
- } else if (!get_option_index(cyc2x_dpmbase_options, dpmbase)) {
- pr_err("memory address 0x%lX is invalid!\n", dpmbase);
- return -EINVAL;
- }
-
- hw->dpmbase = ioremap(dpmbase, CYCX_WINDOWSIZE);
- hw->dpmsize = CYCX_WINDOWSIZE;
-
- if (!detect_cyc2x(hw->dpmbase)) {
- pr_err("adapter Cyclom 2X not found at address 0x%lX!\n",
- dpmbase);
- return -EINVAL;
- }
-
- pr_info("found Cyclom 2X card at address 0x%lX\n", dpmbase);
-
- /* Load firmware. If loader fails then shut down adapter */
- err = load_cyc2x(hw, cfm, len);
-
- if (err)
- cycx_down(hw); /* shutdown adapter */
-
- return err;
-}
-
-EXPORT_SYMBOL(cycx_down);
-int cycx_down(struct cycx_hw *hw)
-{
- iounmap(hw->dpmbase);
- return 0;
-}
-
-/* Enable interrupt generation. */
-static void cycx_inten(struct cycx_hw *hw)
-{
- writeb(0, hw->dpmbase);
-}
-
-/* Generate an interrupt to adapter's CPU. */
-EXPORT_SYMBOL(cycx_intr);
-void cycx_intr(struct cycx_hw *hw)
-{
- writew(0, hw->dpmbase + GEN_CYCX_INTR);
-}
-
-/* Execute Adapter Command.
- * o Set exec flag.
- * o Busy-wait until flag is reset. */
-EXPORT_SYMBOL(cycx_exec);
-int cycx_exec(void __iomem *addr)
-{
- u16 i = 0;
- /* wait till addr content is zeroed */
-
- while (readw(addr)) {
- udelay(1000);
-
- if (++i > 50)
- return -1;
- }
-
- return 0;
-}
-
-/* Read absolute adapter memory.
- * Transfer data from adapter's memory to data buffer. */
-EXPORT_SYMBOL(cycx_peek);
-int cycx_peek(struct cycx_hw *hw, u32 addr, void *buf, u32 len)
-{
- if (len == 1)
- *(u8*)buf = readb(hw->dpmbase + addr);
- else
- memcpy_fromio(buf, hw->dpmbase + addr, len);
-
- return 0;
-}
-
-/* Write Absolute Adapter Memory.
- * Transfer data from data buffer to adapter's memory. */
-EXPORT_SYMBOL(cycx_poke);
-int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len)
-{
- if (len == 1)
- writeb(*(u8*)buf, hw->dpmbase + addr);
- else
- memcpy_toio(hw->dpmbase + addr, buf, len);
-
- return 0;
-}
-
-/* Hardware-Specific Functions */
-
-/* Load Aux Routines */
-/* Reset board hardware.
- return 1 if memory exists at addr and 0 if not. */
-static int memory_exists(void __iomem *addr)
-{
- int tries = 0;
-
- for (; tries < 3 ; tries++) {
- writew(TEST_PATTERN, addr + 0x10);
-
- if (readw(addr + 0x10) == TEST_PATTERN)
- if (readw(addr + 0x10) == TEST_PATTERN)
- return 1;
-
- msleep_interruptible(1 * 1000);
- }
-
- return 0;
-}
-
-/* Load reset code. */
-static void reset_load(void __iomem *addr, u8 *buffer, u32 cnt)
-{
- void __iomem *pt_code = addr + RESET_OFFSET;
- u16 i; /*, j; */
-
- for (i = 0 ; i < cnt ; i++) {
-/* for (j = 0 ; j < 50 ; j++); Delay - FIXME busy waiting... */
- writeb(*buffer++, pt_code++);
- }
-}
-
-/* Load buffer using boot interface.
- * o copy data from buffer to Cyclom-X memory
- * o wait for reset code to copy it to right portion of memory */
-static int buffer_load(void __iomem *addr, u8 *buffer, u32 cnt)
-{
- memcpy_toio(addr + DATA_OFFSET, buffer, cnt);
- writew(GEN_BOOT_DAT, addr + CMD_OFFSET);
-
- return wait_cyc(addr);
-}
-
-/* Set up entry point and kick start Cyclom-X CPU. */
-static void cycx_start(void __iomem *addr)
-{
- /* put in 0x30 offset the jump instruction to the code entry point */
- writeb(0xea, addr + 0x30);
- writeb(0x00, addr + 0x31);
- writeb(0xc4, addr + 0x32);
- writeb(0x00, addr + 0x33);
- writeb(0x00, addr + 0x34);
-
- /* cmd to start executing code */
- writew(GEN_START, addr + CMD_OFFSET);
-}
-
-/* Load and boot reset code. */
-static void cycx_reset_boot(void __iomem *addr, u8 *code, u32 len)
-{
- void __iomem *pt_start = addr + START_OFFSET;
-
- writeb(0xea, pt_start++); /* jmp to f000:3f00 */
- writeb(0x00, pt_start++);
- writeb(0xfc, pt_start++);
- writeb(0x00, pt_start++);
- writeb(0xf0, pt_start);
- reset_load(addr, code, len);
-
- /* 80186 was in hold, go */
- writeb(0, addr + START_CPU);
- msleep_interruptible(1 * 1000);
-}
-
-/* Load data.bin file through boot (reset) interface. */
-static int cycx_data_boot(void __iomem *addr, u8 *code, u32 len)
-{
- void __iomem *pt_boot_cmd = addr + CMD_OFFSET;
- u32 i;
-
- /* boot buffer length */
- writew(CFM_LOAD_BUFSZ, pt_boot_cmd + sizeof(u16));
- writew(GEN_DEFPAR, pt_boot_cmd);
-
- if (wait_cyc(addr) < 0)
- return -1;
-
- writew(0, pt_boot_cmd + sizeof(u16));
- writew(0x4000, pt_boot_cmd + 2 * sizeof(u16));
- writew(GEN_SET_SEG, pt_boot_cmd);
-
- if (wait_cyc(addr) < 0)
- return -1;
-
- for (i = 0 ; i < len ; i += CFM_LOAD_BUFSZ)
- if (buffer_load(addr, code + i,
- min_t(u32, CFM_LOAD_BUFSZ, (len - i))) < 0) {
- pr_err("Error !!\n");
- return -1;
- }
-
- return 0;
-}
-
-
-/* Load code.bin file through boot (reset) interface. */
-static int cycx_code_boot(void __iomem *addr, u8 *code, u32 len)
-{
- void __iomem *pt_boot_cmd = addr + CMD_OFFSET;
- u32 i;
-
- /* boot buffer length */
- writew(CFM_LOAD_BUFSZ, pt_boot_cmd + sizeof(u16));
- writew(GEN_DEFPAR, pt_boot_cmd);
-
- if (wait_cyc(addr) < 0)
- return -1;
-
- writew(0x0000, pt_boot_cmd + sizeof(u16));
- writew(0xc400, pt_boot_cmd + 2 * sizeof(u16));
- writew(GEN_SET_SEG, pt_boot_cmd);
-
- if (wait_cyc(addr) < 0)
- return -1;
-
- for (i = 0 ; i < len ; i += CFM_LOAD_BUFSZ)
- if (buffer_load(addr, code + i,
- min_t(u32, CFM_LOAD_BUFSZ, (len - i)))) {
- pr_err("Error !!\n");
- return -1;
- }
-
- return 0;
-}
-
-/* Load adapter from the memory image of the CYCX firmware module.
- * o verify firmware integrity and compatibility
- * o start adapter up */
-static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
-{
- int i, j;
- struct cycx_fw_header *img_hdr;
- u8 *reset_image,
- *data_image,
- *code_image;
- void __iomem *pt_cycld = hw->dpmbase + 0x400;
- u16 cksum;
-
- /* Announce */
- pr_info("firmware signature=\"%s\"\n", cfm->signature);
-
- /* Verify firmware signature */
- if (strcmp(cfm->signature, CFM_SIGNATURE)) {
- pr_err("load_cyc2x: not Cyclom-2X firmware!\n");
- return -EINVAL;
- }
-
- pr_info("firmware version=%u\n", cfm->version);
-
- /* Verify firmware module format version */
- if (cfm->version != CFM_VERSION) {
- pr_err("%s: firmware format %u rejected! Expecting %u.\n",
- __func__, cfm->version, CFM_VERSION);
- return -EINVAL;
- }
-
- /* Verify firmware module length and checksum */
- cksum = checksum((u8*)&cfm->info, sizeof(struct cycx_fw_info) +
- cfm->info.codesize);
-/*
- FIXME cfm->info.codesize is off by 2
- if (((len - sizeof(struct cycx_firmware) - 1) != cfm->info.codesize) ||
-*/
- if (cksum != cfm->checksum) {
- pr_err("%s: firmware corrupted!\n", __func__);
- pr_err(" cdsize = 0x%x (expected 0x%lx)\n",
- len - (int)sizeof(struct cycx_firmware) - 1,
- cfm->info.codesize);
- pr_err(" chksum = 0x%x (expected 0x%x)\n",
- cksum, cfm->checksum);
- return -EINVAL;
- }
-
- /* If everything is ok, set reset, data and code pointers */
- img_hdr = (struct cycx_fw_header *)&cfm->image;
-#ifdef FIRMWARE_DEBUG
- pr_info("%s: image sizes\n", __func__);
- pr_info(" reset=%lu\n", img_hdr->reset_size);
- pr_info(" data=%lu\n", img_hdr->data_size);
- pr_info(" code=%lu\n", img_hdr->code_size);
-#endif
- reset_image = ((u8 *)img_hdr) + sizeof(struct cycx_fw_header);
- data_image = reset_image + img_hdr->reset_size;
- code_image = data_image + img_hdr->data_size;
-
- /*---- Start load ----*/
- /* Announce */
- pr_info("loading firmware %s (ID=%u)...\n",
- cfm->descr[0] ? cfm->descr : "unknown firmware",
- cfm->info.codeid);
-
- for (i = 0 ; i < 5 ; i++) {
- /* Reset Cyclom hardware */
- if (!reset_cyc2x(hw->dpmbase)) {
- pr_err("dpm problem or board not found\n");
- return -EINVAL;
- }
-
- /* Load reset.bin */
- cycx_reset_boot(hw->dpmbase, reset_image, img_hdr->reset_size);
- /* reset is waiting for boot */
- writew(GEN_POWER_ON, pt_cycld);
- msleep_interruptible(1 * 1000);
-
- for (j = 0 ; j < 3 ; j++)
- if (!readw(pt_cycld))
- goto reset_loaded;
- else
- msleep_interruptible(1 * 1000);
- }
-
- pr_err("reset not started\n");
- return -EINVAL;
-
-reset_loaded:
- /* Load data.bin */
- if (cycx_data_boot(hw->dpmbase, data_image, img_hdr->data_size)) {
- pr_err("cannot load data file\n");
- return -EINVAL;
- }
-
- /* Load code.bin */
- if (cycx_code_boot(hw->dpmbase, code_image, img_hdr->code_size)) {
- pr_err("cannot load code file\n");
- return -EINVAL;
- }
-
- /* Prepare boot-time configuration data */
- cycx_bootcfg(hw);
-
- /* kick-off CPU */
- cycx_start(hw->dpmbase);
-
- /* Arthur Ganzert's tip: wait a while after the firmware loading...
- seg abr 26 17:17:12 EST 1999 - acme */
- msleep_interruptible(7 * 1000);
- pr_info("firmware loaded!\n");
-
- /* enable interrupts */
- cycx_inten(hw);
-
- return 0;
-}
-
-/* Prepare boot-time firmware configuration data.
- * o initialize configuration data area
- From async.doc - V_3.4.0 - 07/18/1994
- - As of now, only static buffers are available to the user.
- So, the bit VD_RXDIRC must be set in 'valid'. That means that user
- wants to use the static transmission and reception buffers. */
-static void cycx_bootcfg(struct cycx_hw *hw)
-{
- /* use fixed buffers */
- writeb(FIXED_BUFFERS, hw->dpmbase + CONF_OFFSET);
-}
-
-/* Detect Cyclom 2x adapter.
- * Following tests are used to detect Cyclom 2x adapter:
- * to be completed based on the tests done below
- * Return 1 if detected o.k. or 0 if failed.
- * Note: This test is destructive! Adapter will be left in shutdown
- * state after the test. */
-static int detect_cyc2x(void __iomem *addr)
-{
- reset_cyc2x(addr);
-
- return memory_exists(addr);
-}
-
-/* Miscellaneous */
-/* Get option's index into the options list.
- * Return option's index (1 .. N) or zero if option is invalid. */
-static int get_option_index(const long *optlist, long optval)
-{
- int i = 1;
-
- for (; i <= optlist[0]; ++i)
- if (optlist[i] == optval)
- return i;
-
- return 0;
-}
-
-/* Reset adapter's CPU. */
-static int reset_cyc2x(void __iomem *addr)
-{
- writeb(0, addr + RST_ENABLE);
- msleep_interruptible(2 * 1000);
- writeb(0, addr + RST_DISABLE);
- msleep_interruptible(2 * 1000);
-
- return memory_exists(addr);
-}
-
-/* Calculate 16-bit CRC using CCITT polynomial. */
-static u16 checksum(u8 *buf, u32 len)
-{
- u16 crc = 0;
- u16 mask, flag;
-
- for (; len; --len, ++buf)
- for (mask = 0x80; mask; mask >>= 1) {
- flag = (crc & 0x8000);
- crc <<= 1;
- crc |= ((*buf & mask) ? 1 : 0);
-
- if (flag)
- crc ^= 0x1021;
- }
-
- return crc;
-}
-
-module_init(cycx_drv_init);
-module_exit(cycx_drv_cleanup);
-
-/* End */
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
deleted file mode 100644
index 81fbbad..0000000
--- a/drivers/net/wan/cycx_main.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
-* cycx_main.c Cyclades Cyclom 2X WAN Link Driver. Main module.
-*
-* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-*
-* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
-*
-* Based on sdlamain.c by Gene Kozin <genek@compuserve.com> &
-* Jaspreet Singh <jaspreet@sangoma.com>
-*
-* 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.
-* ============================================================================
-* Please look at the bitkeeper changelog (or any other scm tool that ends up
-* importing bitkeeper changelog or that replaces bitkeeper in the future as
-* main tool for linux development).
-*
-* 2001/05/09 acme Fix MODULE_DESC for debug, .bss nitpicks,
-* some cleanups
-* 2000/07/13 acme remove useless #ifdef MODULE and crap
-* #if KERNEL_VERSION > blah
-* 2000/07/06 acme __exit at cyclomx_cleanup
-* 2000/04/02 acme dprintk and cycx_debug
-* module_init/module_exit
-* 2000/01/21 acme rename cyclomx_open to cyclomx_mod_inc_use_count
-* and cyclomx_close to cyclomx_mod_dec_use_count
-* 2000/01/08 acme cleanup
-* 1999/11/06 acme cycx_down back to life (it needs to be
-* called to iounmap the dpmbase)
-* 1999/08/09 acme removed references to enable_tx_int
-* use spinlocks instead of cli/sti in
-* cyclomx_set_state
-* 1999/05/19 acme works directly linked into the kernel
-* init_waitqueue_head for 2.3.* kernel
-* 1999/05/18 acme major cleanup (polling not needed), etc
-* 1998/08/28 acme minor cleanup (ioctls for firmware deleted)
-* queue_task activated
-* 1998/08/08 acme Initial version.
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/stddef.h> /* offsetof(), etc. */
-#include <linux/errno.h> /* return codes */
-#include <linux/string.h> /* inline memset(), etc. */
-#include <linux/slab.h> /* kmalloc(), kfree() */
-#include <linux/kernel.h> /* printk(), and other useful stuff */
-#include <linux/module.h> /* support for loadable modules */
-#include <linux/ioport.h> /* request_region(), release_region() */
-#include <linux/wanrouter.h> /* WAN router definitions */
-#include <linux/cyclomx.h> /* cyclomx common user API definitions */
-#include <linux/init.h> /* __init (when not using as a module) */
-#include <linux/interrupt.h>
-
-unsigned int cycx_debug;
-
-MODULE_AUTHOR("Arnaldo Carvalho de Melo");
-MODULE_DESCRIPTION("Cyclom 2X Sync Card Driver.");
-MODULE_LICENSE("GPL");
-module_param(cycx_debug, int, 0);
-MODULE_PARM_DESC(cycx_debug, "cyclomx debug level");
-
-/* Defines & Macros */
-
-#define CYCX_DRV_VERSION 0 /* version number */
-#define CYCX_DRV_RELEASE 11 /* release (minor version) number */
-#define CYCX_MAX_CARDS 1 /* max number of adapters */
-
-#define CONFIG_CYCX_CARDS 1
-
-/* Function Prototypes */
-
-/* WAN link driver entry points */
-static int cycx_wan_setup(struct wan_device *wandev, wandev_conf_t *conf);
-static int cycx_wan_shutdown(struct wan_device *wandev);
-
-/* Miscellaneous functions */
-static irqreturn_t cycx_isr(int irq, void *dev_id);
-
-/* Global Data
- * Note: All data must be explicitly initialized!!!
- */
-
-/* private data */
-static const char cycx_drvname[] = "cyclomx";
-static const char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver";
-static const char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
- "<acme@conectiva.com.br>";
-static int cycx_ncards = CONFIG_CYCX_CARDS;
-static struct cycx_device *cycx_card_array; /* adapter data space */
-
-/* Kernel Loadable Module Entry Points */
-
-/*
- * Module 'insert' entry point.
- * o print announcement
- * o allocate adapter data space
- * o initialize static data
- * o register all cards with WAN router
- * o calibrate Cyclom 2X shared memory access delay.
- *
- * Return: 0 Ok
- * < 0 error.
- * Context: process
- */
-static int __init cycx_init(void)
-{
- int cnt, err = -ENOMEM;
-
- pr_info("%s v%u.%u %s\n",
- cycx_fullname, CYCX_DRV_VERSION, CYCX_DRV_RELEASE,
- cycx_copyright);
-
- /* Verify number of cards and allocate adapter data space */
- cycx_ncards = min_t(int, cycx_ncards, CYCX_MAX_CARDS);
- cycx_ncards = max_t(int, cycx_ncards, 1);
- cycx_card_array = kcalloc(cycx_ncards, sizeof(struct cycx_device), GFP_KERNEL);
- if (!cycx_card_array)
- goto out;
-
-
- /* Register adapters with WAN router */
- for (cnt = 0; cnt < cycx_ncards; ++cnt) {
- struct cycx_device *card = &cycx_card_array[cnt];
- struct wan_device *wandev = &card->wandev;
-
- sprintf(card->devname, "%s%d", cycx_drvname, cnt + 1);
- wandev->magic = ROUTER_MAGIC;
- wandev->name = card->devname;
- wandev->private = card;
- wandev->setup = cycx_wan_setup;
- wandev->shutdown = cycx_wan_shutdown;
- err = register_wan_device(wandev);
-
- if (err) {
- pr_err("%s registration failed with error %d!\n",
- card->devname, err);
- break;
- }
- }
-
- err = -ENODEV;
- if (!cnt) {
- kfree(cycx_card_array);
- goto out;
- }
- err = 0;
- cycx_ncards = cnt; /* adjust actual number of cards */
-out: return err;
-}
-
-/*
- * Module 'remove' entry point.
- * o unregister all adapters from the WAN router
- * o release all remaining system resources
- */
-static void __exit cycx_exit(void)
-{
- int i = 0;
-
- for (; i < cycx_ncards; ++i) {
- struct cycx_device *card = &cycx_card_array[i];
- unregister_wan_device(card->devname);
- }
-
- kfree(cycx_card_array);
-}
-
-/* WAN Device Driver Entry Points */
-/*
- * Setup/configure WAN link driver.
- * o check adapter state
- * o make sure firmware is present in configuration
- * o allocate interrupt vector
- * o setup Cyclom 2X hardware
- * o call appropriate routine to perform protocol-specific initialization
- *
- * This function is called when router handles ROUTER_SETUP IOCTL. The
- * configuration structure is in kernel memory (including extended data, if
- * any).
- */
-static int cycx_wan_setup(struct wan_device *wandev, wandev_conf_t *conf)
-{
- int rc = -EFAULT;
- struct cycx_device *card;
- int irq;
-
- /* Sanity checks */
-
- if (!wandev || !wandev->private || !conf)
- goto out;
-
- card = wandev->private;
- rc = -EBUSY;
- if (wandev->state != WAN_UNCONFIGURED)
- goto out;
-
- rc = -EINVAL;
- if (!conf->data_size || !conf->data) {
- pr_err("%s: firmware not found in configuration data!\n",
- wandev->name);
- goto out;
- }
-
- if (conf->irq <= 0) {
- pr_err("%s: can't configure without IRQ!\n", wandev->name);
- goto out;
- }
-
- /* Allocate IRQ */
- irq = conf->irq == 2 ? 9 : conf->irq; /* IRQ2 -> IRQ9 */
-
- if (request_irq(irq, cycx_isr, 0, wandev->name, card)) {
- pr_err("%s: can't reserve IRQ %d!\n", wandev->name, irq);
- goto out;
- }
-
- /* Configure hardware, load firmware, etc. */
- memset(&card->hw, 0, sizeof(card->hw));
- card->hw.irq = irq;
- card->hw.dpmsize = CYCX_WINDOWSIZE;
- card->hw.fwid = CFID_X25_2X;
- spin_lock_init(&card->lock);
- init_waitqueue_head(&card->wait_stats);
-
- rc = cycx_setup(&card->hw, conf->data, conf->data_size, conf->maddr);
- if (rc)
- goto out_irq;
-
- /* Initialize WAN device data space */
- wandev->irq = irq;
- wandev->dma = wandev->ioport = 0;
- wandev->maddr = (unsigned long)card->hw.dpmbase;
- wandev->msize = card->hw.dpmsize;
- wandev->hw_opt[2] = 0;
- wandev->hw_opt[3] = card->hw.fwid;
-
- /* Protocol-specific initialization */
- switch (card->hw.fwid) {
-#ifdef CONFIG_CYCLOMX_X25
- case CFID_X25_2X:
- rc = cycx_x25_wan_init(card, conf);
- break;
-#endif
- default:
- pr_err("%s: this firmware is not supported!\n", wandev->name);
- rc = -EINVAL;
- }
-
- if (rc) {
- cycx_down(&card->hw);
- goto out_irq;
- }
-
- rc = 0;
-out:
- return rc;
-out_irq:
- free_irq(irq, card);
- goto out;
-}
-
-/*
- * Shut down WAN link driver.
- * o shut down adapter hardware
- * o release system resources.
- *
- * This function is called by the router when device is being unregistered or
- * when it handles ROUTER_DOWN IOCTL.
- */
-static int cycx_wan_shutdown(struct wan_device *wandev)
-{
- int ret = -EFAULT;
- struct cycx_device *card;
-
- /* sanity checks */
- if (!wandev || !wandev->private)
- goto out;
-
- ret = 0;
- if (wandev->state == WAN_UNCONFIGURED)
- goto out;
-
- card = wandev->private;
- wandev->state = WAN_UNCONFIGURED;
- cycx_down(&card->hw);
- pr_info("%s: irq %d being freed!\n", wandev->name, wandev->irq);
- free_irq(wandev->irq, card);
-out: return ret;
-}
-
-/* Miscellaneous */
-/*
- * Cyclom 2X Interrupt Service Routine.
- * o acknowledge Cyclom 2X hardware interrupt.
- * o call protocol-specific interrupt service routine, if any.
- */
-static irqreturn_t cycx_isr(int irq, void *dev_id)
-{
- struct cycx_device *card = dev_id;
-
- if (card->wandev.state == WAN_UNCONFIGURED)
- goto out;
-
- if (card->in_isr) {
- pr_warn("%s: interrupt re-entrancy on IRQ %d!\n",
- card->devname, card->wandev.irq);
- goto out;
- }
-
- if (card->isr)
- card->isr(card);
- return IRQ_HANDLED;
-out:
- return IRQ_NONE;
-}
-
-/* Set WAN device state. */
-void cycx_set_state(struct cycx_device *card, int state)
-{
- unsigned long flags;
- char *string_state = NULL;
-
- spin_lock_irqsave(&card->lock, flags);
-
- if (card->wandev.state != state) {
- switch (state) {
- case WAN_CONNECTED:
- string_state = "connected!";
- break;
- case WAN_DISCONNECTED:
- string_state = "disconnected!";
- break;
- }
- pr_info("%s: link %s\n", card->devname, string_state);
- card->wandev.state = state;
- }
-
- card->state_tick = jiffies;
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-module_init(cycx_init);
-module_exit(cycx_exit);
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
deleted file mode 100644
index 06f3f63..0000000
--- a/drivers/net/wan/cycx_x25.c
+++ /dev/null
@@ -1,1602 +0,0 @@
-/*
-* cycx_x25.c Cyclom 2X WAN Link Driver. X.25 module.
-*
-* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-*
-* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
-*
-* Based on sdla_x25.c by Gene Kozin <genek@compuserve.com>
-*
-* 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.
-* ============================================================================
-* 2001/01/12 acme use dev_kfree_skb_irq on interrupt context
-* 2000/04/02 acme dprintk, cycx_debug
-* fixed the bug introduced in get_dev_by_lcn and
-* get_dev_by_dte_addr by the anonymous hacker
-* that converted this driver to softnet
-* 2000/01/08 acme cleanup
-* 1999/10/27 acme use ARPHRD_HWX25 so that the X.25 stack know
-* that we have a X.25 stack implemented in
-* firmware onboard
-* 1999/10/18 acme support for X.25 sockets in if_send,
-* beware: socket(AF_X25...) IS WORK IN PROGRESS,
-* TCP/IP over X.25 via wanrouter not affected,
-* working.
-* 1999/10/09 acme chan_disc renamed to chan_disconnect,
-* began adding support for X.25 sockets:
-* conf->protocol in new_if
-* 1999/10/05 acme fixed return E... to return -E...
-* 1999/08/10 acme serialized access to the card thru a spinlock
-* in x25_exec
-* 1999/08/09 acme removed per channel spinlocks
-* removed references to enable_tx_int
-* 1999/05/28 acme fixed nibble_to_byte, ackvc now properly treated
-* if_send simplified
-* 1999/05/25 acme fixed t1, t2, t21 & t23 configuration
-* use spinlocks instead of cli/sti in some points
-* 1999/05/24 acme finished the x25_get_stat function
-* 1999/05/23 acme dev->type = ARPHRD_X25 (tcpdump only works,
-* AFAIT, with ARPHRD_ETHER). This seems to be
-* needed to use socket(AF_X25)...
-* Now the config file must specify a peer media
-* address for svc channels over a crossover cable.
-* Removed hold_timeout from x25_channel_t,
-* not used.
-* A little enhancement in the DEBUG processing
-* 1999/05/22 acme go to DISCONNECTED in disconnect_confirm_intr,
-* instead of chan_disc.
-* 1999/05/16 marcelo fixed timer initialization in SVCs
-* 1999/01/05 acme x25_configure now get (most of) all
-* parameters...
-* 1999/01/05 acme pktlen now (correctly) uses log2 (value
-* configured)
-* 1999/01/03 acme judicious use of data types (u8, u16, u32, etc)
-* 1999/01/03 acme cyx_isr: reset dpmbase to acknowledge
-* indication (interrupt from cyclom 2x)
-* 1999/01/02 acme cyx_isr: first hackings...
-* 1999/01/0203 acme when initializing an array don't give less
-* elements than declared...
-* example: char send_cmd[6] = "?\xFF\x10";
-* you'll gonna lose a couple hours, 'cause your
-* brain won't admit that there's an error in the
-* above declaration... the side effect is that
-* memset is put into the unresolved symbols
-* instead of using the inline memset functions...
-* 1999/01/02 acme began chan_connect, chan_send, x25_send
-* 1998/12/31 acme x25_configure
-* this code can be compiled as non module
-* 1998/12/27 acme code cleanup
-* IPX code wiped out! let's decrease code
-* complexity for now, remember: I'm learning! :)
-* bps_to_speed_code OK
-* 1998/12/26 acme Minimal debug code cleanup
-* 1998/08/08 acme Initial version.
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define CYCLOMX_X25_DEBUG 1
-
-#include <linux/ctype.h> /* isdigit() */
-#include <linux/errno.h> /* return codes */
-#include <linux/if_arp.h> /* ARPHRD_HWX25 */
-#include <linux/kernel.h> /* printk(), and other useful stuff */
-#include <linux/module.h>
-#include <linux/string.h> /* inline memset(), etc. */
-#include <linux/sched.h>
-#include <linux/slab.h> /* kmalloc(), kfree() */
-#include <linux/stddef.h> /* offsetof(), etc. */
-#include <linux/wanrouter.h> /* WAN router definitions */
-
-#include <asm/byteorder.h> /* htons(), etc. */
-
-#include <linux/cyclomx.h> /* Cyclom 2X common user API definitions */
-#include <linux/cycx_x25.h> /* X.25 firmware API definitions */
-
-#include <net/x25device.h>
-
-/* Defines & Macros */
-#define CYCX_X25_MAX_CMD_RETRY 5
-#define CYCX_X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */
-
-/* Data Structures */
-/* This is an extension of the 'struct net_device' we create for each network
- interface to keep the rest of X.25 channel-specific data. */
-struct cycx_x25_channel {
- /* This member must be first. */
- struct net_device *slave; /* WAN slave */
-
- char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
- char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
- char *local_addr; /* local media address, ASCIIZ -
- svc thru crossover cable */
- s16 lcn; /* logical channel number/conn.req.key*/
- u8 link;
- struct timer_list timer; /* timer used for svc channel disc. */
- u16 protocol; /* ethertype, 0 - multiplexed */
- u8 svc; /* 0 - permanent, 1 - switched */
- u8 state; /* channel state */
- u8 drop_sequence; /* mark sequence for dropping */
- u32 idle_tmout; /* sec, before disconnecting */
- struct sk_buff *rx_skb; /* receive socket buffer */
- struct cycx_device *card; /* -> owner */
- struct net_device_stats ifstats;/* interface statistics */
-};
-
-/* Function Prototypes */
-/* WAN link driver entry points. These are called by the WAN router module. */
-static int cycx_wan_update(struct wan_device *wandev),
- cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
- wanif_conf_t *conf),
- cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
-
-/* Network device interface */
-static int cycx_netdevice_init(struct net_device *dev);
-static int cycx_netdevice_open(struct net_device *dev);
-static int cycx_netdevice_stop(struct net_device *dev);
-static int cycx_netdevice_hard_header(struct sk_buff *skb,
- struct net_device *dev, u16 type,
- const void *daddr, const void *saddr,
- unsigned len);
-static int cycx_netdevice_rebuild_header(struct sk_buff *skb);
-static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
- struct net_device *dev);
-
-static struct net_device_stats *
- cycx_netdevice_get_stats(struct net_device *dev);
-
-/* Interrupt handlers */
-static void cycx_x25_irq_handler(struct cycx_device *card),
- cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
- cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
- cycx_x25_irq_log(struct cycx_device *card,
- struct cycx_x25_cmd *cmd),
- cycx_x25_irq_stat(struct cycx_device *card,
- struct cycx_x25_cmd *cmd),
- cycx_x25_irq_connect_confirm(struct cycx_device *card,
- struct cycx_x25_cmd *cmd),
- cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
- struct cycx_x25_cmd *cmd),
- cycx_x25_irq_connect(struct cycx_device *card,
- struct cycx_x25_cmd *cmd),
- cycx_x25_irq_disconnect(struct cycx_device *card,
- struct cycx_x25_cmd *cmd),
- cycx_x25_irq_spurious(struct cycx_device *card,
- struct cycx_x25_cmd *cmd);
-
-/* X.25 firmware interface functions */
-static int cycx_x25_configure(struct cycx_device *card,
- struct cycx_x25_config *conf),
- cycx_x25_get_stats(struct cycx_device *card),
- cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
- int len, void *buf),
- cycx_x25_connect_response(struct cycx_device *card,
- struct cycx_x25_channel *chan),
- cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
- u8 lcn);
-
-/* channel functions */
-static int cycx_x25_chan_connect(struct net_device *dev),
- cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb);
-
-static void cycx_x25_chan_disconnect(struct net_device *dev),
- cycx_x25_chan_send_event(struct net_device *dev, u8 event);
-
-/* Miscellaneous functions */
-static void cycx_x25_set_chan_state(struct net_device *dev, u8 state),
- cycx_x25_chan_timer(unsigned long d);
-
-static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble),
- reset_timer(struct net_device *dev);
-
-static u8 bps_to_speed_code(u32 bps);
-static u8 cycx_log2(u32 n);
-
-static unsigned dec_to_uint(u8 *str, int len);
-
-static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
- s16 lcn);
-static struct net_device *
- cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
-
-static void cycx_x25_chan_setup(struct net_device *dev);
-
-#ifdef CYCLOMX_X25_DEBUG
-static void hex_dump(char *msg, unsigned char *p, int len);
-static void cycx_x25_dump_config(struct cycx_x25_config *conf);
-static void cycx_x25_dump_stats(struct cycx_x25_stats *stats);
-static void cycx_x25_dump_devs(struct wan_device *wandev);
-#else
-#define hex_dump(msg, p, len)
-#define cycx_x25_dump_config(conf)
-#define cycx_x25_dump_stats(stats)
-#define cycx_x25_dump_devs(wandev)
-#endif
-/* Public Functions */
-
-/* X.25 Protocol Initialization routine.
- *
- * This routine is called by the main Cyclom 2X module during setup. At this
- * point adapter is completely initialized and X.25 firmware is running.
- * o configure adapter
- * o initialize protocol-specific fields of the adapter data space.
- *
- * Return: 0 o.k.
- * < 0 failure. */
-int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf)
-{
- struct cycx_x25_config cfg;
-
- /* Verify configuration ID */
- if (conf->config_id != WANCONFIG_X25) {
- pr_info("%s: invalid configuration ID %u!\n",
- card->devname, conf->config_id);
- return -EINVAL;
- }
-
- /* Initialize protocol-specific fields */
- card->mbox = card->hw.dpmbase + X25_MBOX_OFFS;
- card->u.x.connection_keys = 0;
- spin_lock_init(&card->u.x.lock);
-
- /* Configure adapter. Here we set reasonable defaults, then parse
- * device configuration structure and set configuration options.
- * Most configuration options are verified and corrected (if
- * necessary) since we can't rely on the adapter to do so and don't
- * want it to fail either. */
- memset(&cfg, 0, sizeof(cfg));
- cfg.link = 0;
- cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
- cfg.speed = bps_to_speed_code(conf->bps);
- cfg.n3win = 7;
- cfg.n2win = 2;
- cfg.n2 = 5;
- cfg.nvc = 1;
- cfg.npvc = 1;
- cfg.flags = 0x02; /* default = V35 */
- cfg.t1 = 10; /* line carrier timeout */
- cfg.t2 = 29; /* tx timeout */
- cfg.t21 = 180; /* CALL timeout */
- cfg.t23 = 180; /* CLEAR timeout */
-
- /* adjust MTU */
- if (!conf->mtu || conf->mtu >= 512)
- card->wandev.mtu = 512;
- else if (conf->mtu >= 256)
- card->wandev.mtu = 256;
- else if (conf->mtu >= 128)
- card->wandev.mtu = 128;
- else
- card->wandev.mtu = 64;
-
- cfg.pktlen = cycx_log2(card->wandev.mtu);
-
- if (conf->station == WANOPT_DTE) {
- cfg.locaddr = 3; /* DTE */
- cfg.remaddr = 1; /* DCE */
- } else {
- cfg.locaddr = 1; /* DCE */
- cfg.remaddr = 3; /* DTE */
- }
-
- if (conf->interface == WANOPT_RS232)
- cfg.flags = 0; /* FIXME just reset the 2nd bit */
-
- if (conf->u.x25.hi_pvc) {
- card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, 4095);
- card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
- }
-
- if (conf->u.x25.hi_svc) {
- card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, 4095);
- card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
- }
-
- if (card->u.x.lo_pvc == 255)
- cfg.npvc = 0;
- else
- cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
-
- cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
-
- if (conf->u.x25.hdlc_window)
- cfg.n2win = min_t(unsigned int, conf->u.x25.hdlc_window, 7);
-
- if (conf->u.x25.pkt_window)
- cfg.n3win = min_t(unsigned int, conf->u.x25.pkt_window, 7);
-
- if (conf->u.x25.t1)
- cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
-
- if (conf->u.x25.t2)
- cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 30);
-
- if (conf->u.x25.t11_t21)
- cfg.t21 = min_t(unsigned int, conf->u.x25.t11_t21, 30);
-
- if (conf->u.x25.t13_t23)
- cfg.t23 = min_t(unsigned int, conf->u.x25.t13_t23, 30);
-
- if (conf->u.x25.n2)
- cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
-
- /* initialize adapter */
- if (cycx_x25_configure(card, &cfg))
- return -EIO;
-
- /* Initialize protocol-specific fields of adapter data space */
- card->wandev.bps = conf->bps;
- card->wandev.interface = conf->interface;
- card->wandev.clocking = conf->clocking;
- card->wandev.station = conf->station;
- card->isr = cycx_x25_irq_handler;
- card->exec = NULL;
- card->wandev.update = cycx_wan_update;
- card->wandev.new_if = cycx_wan_new_if;
- card->wandev.del_if = cycx_wan_del_if;
- card->wandev.state = WAN_DISCONNECTED;
-
- return 0;
-}
-
-/* WAN Device Driver Entry Points */
-/* Update device status & statistics. */
-static int cycx_wan_update(struct wan_device *wandev)
-{
- /* sanity checks */
- if (!wandev || !wandev->private)
- return -EFAULT;
-
- if (wandev->state == WAN_UNCONFIGURED)
- return -ENODEV;
-
- cycx_x25_get_stats(wandev->private);
-
- return 0;
-}
-
-/* Create new logical channel.
- * This routine is called by the router when ROUTER_IFNEW IOCTL is being
- * handled.
- * o parse media- and hardware-specific configuration
- * o make sure that a new channel can be created
- * o allocate resources, if necessary
- * o prepare network device structure for registration.
- *
- * Return: 0 o.k.
- * < 0 failure (channel will not be created) */
-static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
- wanif_conf_t *conf)
-{
- struct cycx_device *card = wandev->private;
- struct cycx_x25_channel *chan;
- int err = 0;
-
- if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
- pr_info("%s: invalid interface name!\n", card->devname);
- return -EINVAL;
- }
-
- dev = alloc_netdev(sizeof(struct cycx_x25_channel), conf->name,
- cycx_x25_chan_setup);
- if (!dev)
- return -ENOMEM;
-
- chan = netdev_priv(dev);
- strcpy(chan->name, conf->name);
- chan->card = card;
- chan->link = conf->port;
- chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
- chan->rx_skb = NULL;
- /* only used in svc connected thru crossover cable */
- chan->local_addr = NULL;
-
- if (conf->addr[0] == '@') { /* SVC */
- int len = strlen(conf->local_addr);
-
- if (len) {
- if (len > WAN_ADDRESS_SZ) {
- pr_err("%s: %s local addr too long!\n",
- wandev->name, chan->name);
- err = -EINVAL;
- goto error;
- } else {
- chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
-
- if (!chan->local_addr) {
- err = -ENOMEM;
- goto error;
- }
- }
-
- strncpy(chan->local_addr, conf->local_addr,
- WAN_ADDRESS_SZ);
- }
-
- chan->svc = 1;
- strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
- init_timer(&chan->timer);
- chan->timer.function = cycx_x25_chan_timer;
- chan->timer.data = (unsigned long)dev;
-
- /* Set channel timeouts (default if not specified) */
- chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
- } else if (isdigit(conf->addr[0])) { /* PVC */
- s16 lcn = dec_to_uint(conf->addr, 0);
-
- if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
- chan->lcn = lcn;
- else {
- pr_err("%s: PVC %u is out of range on interface %s!\n",
- wandev->name, lcn, chan->name);
- err = -EINVAL;
- goto error;
- }
- } else {
- pr_err("%s: invalid media address on interface %s!\n",
- wandev->name, chan->name);
- err = -EINVAL;
- goto error;
- }
-
- return 0;
-
-error:
- free_netdev(dev);
- return err;
-}
-
-/* Delete logical channel. */
-static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
-
- if (chan->svc) {
- kfree(chan->local_addr);
- if (chan->state == WAN_CONNECTED)
- del_timer(&chan->timer);
- }
-
- return 0;
-}
-
-
-/* Network Device Interface */
-
-static const struct header_ops cycx_header_ops = {
- .create = cycx_netdevice_hard_header,
- .rebuild = cycx_netdevice_rebuild_header,
-};
-
-static const struct net_device_ops cycx_netdev_ops = {
- .ndo_init = cycx_netdevice_init,
- .ndo_open = cycx_netdevice_open,
- .ndo_stop = cycx_netdevice_stop,
- .ndo_start_xmit = cycx_netdevice_hard_start_xmit,
- .ndo_get_stats = cycx_netdevice_get_stats,
-};
-
-static void cycx_x25_chan_setup(struct net_device *dev)
-{
- /* Initialize device driver entry points */
- dev->netdev_ops = &cycx_netdev_ops;
- dev->header_ops = &cycx_header_ops;
-
- /* Initialize media-specific parameters */
- dev->mtu = CYCX_X25_CHAN_MTU;
- dev->type = ARPHRD_HWX25; /* ARP h/w type */
- dev->hard_header_len = 0; /* media header length */
- dev->addr_len = 0; /* hardware address length */
-}
-
-/* Initialize Linux network interface.
- *
- * This routine is called only once for each interface, during Linux network
- * interface registration. Returning anything but zero will fail interface
- * registration. */
-static int cycx_netdevice_init(struct net_device *dev)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
- struct cycx_device *card = chan->card;
- struct wan_device *wandev = &card->wandev;
-
- if (!chan->svc)
- *(__be16*)dev->dev_addr = htons(chan->lcn);
-
- /* Initialize hardware parameters (just for reference) */
- dev->irq = wandev->irq;
- dev->dma = wandev->dma;
- dev->base_addr = wandev->ioport;
- dev->mem_start = (unsigned long)wandev->maddr;
- dev->mem_end = (unsigned long)(wandev->maddr +
- wandev->msize - 1);
- dev->flags |= IFF_NOARP;
-
- /* Set transmit buffer queue length */
- dev->tx_queue_len = 10;
-
- /* Initialize socket buffers */
- cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
-
- return 0;
-}
-
-/* Open network interface.
- * o prevent module from unloading by incrementing use count
- * o if link is disconnected then initiate connection
- *
- * Return 0 if O.k. or errno. */
-static int cycx_netdevice_open(struct net_device *dev)
-{
- if (netif_running(dev))
- return -EBUSY; /* only one open is allowed */
-
- netif_start_queue(dev);
- return 0;
-}
-
-/* Close network interface.
- * o reset flags.
- * o if there's no more open channels then disconnect physical link. */
-static int cycx_netdevice_stop(struct net_device *dev)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
-
- netif_stop_queue(dev);
-
- if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
- cycx_x25_chan_disconnect(dev);
-
- return 0;
-}
-
-/* Build media header.
- * o encapsulate packet according to encapsulation type.
- *
- * The trick here is to put packet type (Ethertype) into 'protocol' field of
- * the socket buffer, so that we don't forget it. If encapsulation fails,
- * set skb->protocol to 0 and discard packet later.
- *
- * Return: media header length. */
-static int cycx_netdevice_hard_header(struct sk_buff *skb,
- struct net_device *dev, u16 type,
- const void *daddr, const void *saddr,
- unsigned len)
-{
- skb->protocol = htons(type);
-
- return dev->hard_header_len;
-}
-
-/* * Re-build media header.
- * Return: 1 physical address resolved.
- * 0 physical address not resolved */
-static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
-{
- return 1;
-}
-
-/* Send a packet on a network interface.
- * o set busy flag (marks start of the transmission).
- * o check link state. If link is not up, then drop the packet.
- * o check channel status. If it's down then initiate a call.
- * o pass a packet to corresponding WAN device.
- * o free socket buffer
- *
- * Return: 0 complete (socket buffer must be freed)
- * non-0 packet may be re-transmitted (tbusy must be set)
- *
- * Notes:
- * 1. This routine is called either by the protocol stack or by the "net
- * bottom half" (with interrupts enabled).
- * 2. Setting tbusy flag will inhibit further transmit requests from the
- * protocol stack and can be used for flow control with protocol layer. */
-static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
- struct cycx_device *card = chan->card;
-
- if (!chan->svc)
- chan->protocol = ntohs(skb->protocol);
-
- if (card->wandev.state != WAN_CONNECTED)
- ++chan->ifstats.tx_dropped;
- else if (chan->svc && chan->protocol &&
- chan->protocol != ntohs(skb->protocol)) {
- pr_info("%s: unsupported Ethertype 0x%04X on interface %s!\n",
- card->devname, ntohs(skb->protocol), dev->name);
- ++chan->ifstats.tx_errors;
- } else if (chan->protocol == ETH_P_IP) {
- switch (chan->state) {
- case WAN_DISCONNECTED:
- if (cycx_x25_chan_connect(dev)) {
- netif_stop_queue(dev);
- return NETDEV_TX_BUSY;
- }
- /* fall thru */
- case WAN_CONNECTED:
- reset_timer(dev);
- dev->trans_start = jiffies;
- netif_stop_queue(dev);
-
- if (cycx_x25_chan_send(dev, skb))
- return NETDEV_TX_BUSY;
-
- break;
- default:
- ++chan->ifstats.tx_dropped;
- ++card->wandev.stats.tx_dropped;
- }
- } else { /* chan->protocol == ETH_P_X25 */
- switch (skb->data[0]) {
- case X25_IFACE_DATA:
- break;
- case X25_IFACE_CONNECT:
- cycx_x25_chan_connect(dev);
- goto free_packet;
- case X25_IFACE_DISCONNECT:
- cycx_x25_chan_disconnect(dev);
- goto free_packet;
- default:
- pr_info("%s: unknown %d x25-iface request on %s!\n",
- card->devname, skb->data[0], dev->name);
- ++chan->ifstats.tx_errors;
- goto free_packet;
- }
-
- skb_pull(skb, 1); /* Remove control byte */
- reset_timer(dev);
- dev->trans_start = jiffies;
- netif_stop_queue(dev);
-
- if (cycx_x25_chan_send(dev, skb)) {
- /* prepare for future retransmissions */
- skb_push(skb, 1);
- return NETDEV_TX_BUSY;
- }
- }
-
-free_packet:
- dev_kfree_skb(skb);
-
- return NETDEV_TX_OK;
-}
-
-/* Get Ethernet-style interface statistics.
- * Return a pointer to struct net_device_stats */
-static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
-
- return chan ? &chan->ifstats : NULL;
-}
-
-/* Interrupt Handlers */
-/* X.25 Interrupt Service Routine. */
-static void cycx_x25_irq_handler(struct cycx_device *card)
-{
- struct cycx_x25_cmd cmd;
- u16 z = 0;
-
- card->in_isr = 1;
- card->buff_int_mode_unbusy = 0;
- cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
-
- switch (cmd.command) {
- case X25_DATA_INDICATION:
- cycx_x25_irq_rx(card, &cmd);
- break;
- case X25_ACK_FROM_VC:
- cycx_x25_irq_tx(card, &cmd);
- break;
- case X25_LOG:
- cycx_x25_irq_log(card, &cmd);
- break;
- case X25_STATISTIC:
- cycx_x25_irq_stat(card, &cmd);
- break;
- case X25_CONNECT_CONFIRM:
- cycx_x25_irq_connect_confirm(card, &cmd);
- break;
- case X25_CONNECT_INDICATION:
- cycx_x25_irq_connect(card, &cmd);
- break;
- case X25_DISCONNECT_INDICATION:
- cycx_x25_irq_disconnect(card, &cmd);
- break;
- case X25_DISCONNECT_CONFIRM:
- cycx_x25_irq_disconnect_confirm(card, &cmd);
- break;
- case X25_LINE_ON:
- cycx_set_state(card, WAN_CONNECTED);
- break;
- case X25_LINE_OFF:
- cycx_set_state(card, WAN_DISCONNECTED);
- break;
- default:
- cycx_x25_irq_spurious(card, &cmd);
- break;
- }
-
- cycx_poke(&card->hw, 0, &z, sizeof(z));
- cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
- card->in_isr = 0;
-}
-
-/* Transmit interrupt handler.
- * o Release socket buffer
- * o Clear 'tbusy' flag */
-static void cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
-{
- struct net_device *dev;
- struct wan_device *wandev = &card->wandev;
- u8 lcn;
-
- cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
-
- /* unbusy device and then dev_tint(); */
- dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
- if (dev) {
- card->buff_int_mode_unbusy = 1;
- netif_wake_queue(dev);
- } else
- pr_err("%s:ackvc for inexistent lcn %d\n", card->devname, lcn);
-}
-
-/* Receive interrupt handler.
- * This routine handles fragmented IP packets using M-bit according to the
- * RFC1356.
- * o map logical channel number to network interface.
- * o allocate socket buffer or append received packet to the existing one.
- * o if M-bit is reset (i.e. it's the last packet in a sequence) then
- * decapsulate packet and pass socket buffer to the protocol stack.
- *
- * Notes:
- * 1. When allocating a socket buffer, if M-bit is set then more data is
- * coming and we have to allocate buffer for the maximum IP packet size
- * expected on this channel.
- * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
- * socket buffers available) the whole packet sequence must be discarded. */
-static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
-{
- struct wan_device *wandev = &card->wandev;
- struct net_device *dev;
- struct cycx_x25_channel *chan;
- struct sk_buff *skb;
- u8 bitm, lcn;
- int pktlen = cmd->len - 5;
-
- cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
- cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
- bitm &= 0x10;
-
- dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
- if (!dev) {
- /* Invalid channel, discard packet */
- pr_info("%s: receiving on orphaned LCN %d!\n",
- card->devname, lcn);
- return;
- }
-
- chan = netdev_priv(dev);
- reset_timer(dev);
-
- if (chan->drop_sequence) {
- if (!bitm)
- chan->drop_sequence = 0;
- else
- return;
- }
-
- if ((skb = chan->rx_skb) == NULL) {
- /* Allocate new socket buffer */
- int bufsize = bitm ? dev->mtu : pktlen;
-
- if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) +
- bufsize +
- dev->hard_header_len)) == NULL) {
- pr_info("%s: no socket buffers available!\n",
- card->devname);
- chan->drop_sequence = 1;
- ++chan->ifstats.rx_dropped;
- return;
- }
-
- if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */
- /* 0 = data packet (dev_alloc_skb zeroed skb->data) */
- skb_put(skb, 1);
-
- skb->dev = dev;
- skb->protocol = htons(chan->protocol);
- chan->rx_skb = skb;
- }
-
- if (skb_tailroom(skb) < pktlen) {
- /* No room for the packet. Call off the whole thing! */
- dev_kfree_skb_irq(skb);
- chan->rx_skb = NULL;
-
- if (bitm)
- chan->drop_sequence = 1;
-
- pr_info("%s: unexpectedly long packet sequence on interface %s!\n",
- card->devname, dev->name);
- ++chan->ifstats.rx_length_errors;
- return;
- }
-
- /* Append packet to the socket buffer */
- cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
-
- if (bitm)
- return; /* more data is coming */
-
- chan->rx_skb = NULL; /* dequeue packet */
-
- ++chan->ifstats.rx_packets;
- chan->ifstats.rx_bytes += pktlen;
-
- skb_reset_mac_header(skb);
- netif_rx(skb);
-}
-
-/* Connect interrupt handler. */
-static void cycx_x25_irq_connect(struct cycx_device *card,
- struct cycx_x25_cmd *cmd)
-{
- struct wan_device *wandev = &card->wandev;
- struct net_device *dev = NULL;
- struct cycx_x25_channel *chan;
- u8 d[32],
- loc[24],
- rem[24];
- u8 lcn, sizeloc, sizerem;
-
- cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
- cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
- cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
-
- sizerem = sizeloc >> 4;
- sizeloc &= 0x0F;
-
- loc[0] = rem[0] = '\0';
-
- if (sizeloc)
- nibble_to_byte(d, loc, sizeloc, 0);
-
- if (sizerem)
- nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
-
- dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
- __func__, lcn, loc, rem);
-
- dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
- if (!dev) {
- /* Invalid channel, discard packet */
- pr_info("%s: connect not expected: remote %s!\n",
- card->devname, rem);
- return;
- }
-
- chan = netdev_priv(dev);
- chan->lcn = lcn;
- cycx_x25_connect_response(card, chan);
- cycx_x25_set_chan_state(dev, WAN_CONNECTED);
-}
-
-/* Connect confirm interrupt handler. */
-static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
- struct cycx_x25_cmd *cmd)
-{
- struct wan_device *wandev = &card->wandev;
- struct net_device *dev;
- struct cycx_x25_channel *chan;
- u8 lcn, key;
-
- cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
- cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
- dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
- card->devname, __func__, lcn, key);
-
- dev = cycx_x25_get_dev_by_lcn(wandev, -key);
- if (!dev) {
- /* Invalid channel, discard packet */
- clear_bit(--key, (void*)&card->u.x.connection_keys);
- pr_info("%s: connect confirm not expected: lcn %d, key=%d!\n",
- card->devname, lcn, key);
- return;
- }
-
- clear_bit(--key, (void*)&card->u.x.connection_keys);
- chan = netdev_priv(dev);
- chan->lcn = lcn;
- cycx_x25_set_chan_state(dev, WAN_CONNECTED);
-}
-
-/* Disconnect confirm interrupt handler. */
-static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
- struct cycx_x25_cmd *cmd)
-{
- struct wan_device *wandev = &card->wandev;
- struct net_device *dev;
- u8 lcn;
-
- cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
- dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
- card->devname, __func__, lcn);
- dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
- if (!dev) {
- /* Invalid channel, discard packet */
- pr_info("%s:disconnect confirm not expected!:lcn %d\n",
- card->devname, lcn);
- return;
- }
-
- cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
-}
-
-/* disconnect interrupt handler. */
-static void cycx_x25_irq_disconnect(struct cycx_device *card,
- struct cycx_x25_cmd *cmd)
-{
- struct wan_device *wandev = &card->wandev;
- struct net_device *dev;
- u8 lcn;
-
- cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
- dprintk(1, KERN_INFO "%s:lcn=%d\n", __func__, lcn);
-
- dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
- if (dev) {
- struct cycx_x25_channel *chan = netdev_priv(dev);
-
- cycx_x25_disconnect_response(card, chan->link, lcn);
- cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
- } else
- cycx_x25_disconnect_response(card, 0, lcn);
-}
-
-/* LOG interrupt handler. */
-static void cycx_x25_irq_log(struct cycx_device *card, struct cycx_x25_cmd *cmd)
-{
-#if CYCLOMX_X25_DEBUG
- char bf[20];
- u16 size, toread, link, msg_code;
- u8 code, routine;
-
- cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
- cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
- cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
- /* at most 20 bytes are available... thanks to Daniela :) */
- toread = size < 20 ? size : 20;
- cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
- cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
- cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
-
- pr_info("cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n");
- pr_info("cmd->buf=0x%X\n", cmd->buf);
- pr_info("Log message code=0x%X\n", msg_code);
- pr_info("Link=%d\n", link);
- pr_info("log code=0x%X\n", code);
- pr_info("log routine=0x%X\n", routine);
- pr_info("Message size=%d\n", size);
- hex_dump("Message", bf, toread);
-#endif
-}
-
-/* STATISTIC interrupt handler. */
-static void cycx_x25_irq_stat(struct cycx_device *card,
- struct cycx_x25_cmd *cmd)
-{
- cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
- sizeof(card->u.x.stats));
- hex_dump("cycx_x25_irq_stat", (unsigned char*)&card->u.x.stats,
- sizeof(card->u.x.stats));
- cycx_x25_dump_stats(&card->u.x.stats);
- wake_up_interruptible(&card->wait_stats);
-}
-
-/* Spurious interrupt handler.
- * o print a warning
- * If number of spurious interrupts exceeded some limit, then ??? */
-static void cycx_x25_irq_spurious(struct cycx_device *card,
- struct cycx_x25_cmd *cmd)
-{
- pr_info("%s: spurious interrupt (0x%X)!\n",
- card->devname, cmd->command);
-}
-#ifdef CYCLOMX_X25_DEBUG
-static void hex_dump(char *msg, unsigned char *p, int len)
-{
- print_hex_dump(KERN_INFO, msg, DUMP_PREFIX_OFFSET, 16, 1,
- p, len, true);
-}
-#endif
-
-/* Cyclom 2X Firmware-Specific Functions */
-/* Exec X.25 command. */
-static int x25_exec(struct cycx_device *card, int command, int link,
- void *d1, int len1, void *d2, int len2)
-{
- struct cycx_x25_cmd c;
- unsigned long flags;
- u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
- u8 retry = CYCX_X25_MAX_CMD_RETRY;
- int err = 0;
-
- c.command = command;
- c.link = link;
- c.len = len1 + len2;
-
- spin_lock_irqsave(&card->u.x.lock, flags);
-
- /* write command */
- cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
-
- /* write X.25 data */
- if (d1) {
- cycx_poke(&card->hw, addr, d1, len1);
-
- if (d2) {
- if (len2 > 254) {
- u32 addr1 = 0xA00 + 0x400 * link;
-
- cycx_poke(&card->hw, addr + len1, d2, 249);
- cycx_poke(&card->hw, addr1, ((u8*)d2) + 249,
- len2 - 249);
- } else
- cycx_poke(&card->hw, addr + len1, d2, len2);
- }
- }
-
- /* generate interruption, executing command */
- cycx_intr(&card->hw);
-
- /* wait till card->mbox == 0 */
- do {
- err = cycx_exec(card->mbox);
- } while (retry-- && err);
-
- spin_unlock_irqrestore(&card->u.x.lock, flags);
-
- return err;
-}
-
-/* Configure adapter. */
-static int cycx_x25_configure(struct cycx_device *card,
- struct cycx_x25_config *conf)
-{
- struct {
- u16 nlinks;
- struct cycx_x25_config conf[2];
- } x25_cmd_conf;
-
- memset(&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
- x25_cmd_conf.nlinks = 2;
- x25_cmd_conf.conf[0] = *conf;
- /* FIXME: we need to find a way in the wanrouter framework
- to configure the second link, for now lets use it
- with the same config from the first link, fixing
- the interface type to RS232, the speed in 38400 and
- the clock to external */
- x25_cmd_conf.conf[1] = *conf;
- x25_cmd_conf.conf[1].link = 1;
- x25_cmd_conf.conf[1].speed = 5; /* 38400 */
- x25_cmd_conf.conf[1].clock = 8;
- x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
-
- cycx_x25_dump_config(&x25_cmd_conf.conf[0]);
- cycx_x25_dump_config(&x25_cmd_conf.conf[1]);
-
- return x25_exec(card, X25_CONFIG, 0,
- &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
-}
-
-/* Get protocol statistics. */
-static int cycx_x25_get_stats(struct cycx_device *card)
-{
- /* the firmware expects 20 in the size field!!!
- thanks to Daniela */
- int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
-
- if (err)
- return err;
-
- interruptible_sleep_on(&card->wait_stats);
-
- if (signal_pending(current))
- return -EINTR;
-
- card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
- card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
- card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
- card->wandev.stats.rx_length_errors = 0; /* not available from fw */
- card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
- card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
- card->wandev.stats.rx_dropped = 0; /* not available from fw */
- card->wandev.stats.rx_errors = 0; /* not available from fw */
- card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
- card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
- card->wandev.stats.tx_dropped = 0; /* not available from fw */
- card->wandev.stats.collisions = 0; /* not available from fw */
- card->wandev.stats.tx_errors = 0; /* not available from fw */
-
- cycx_x25_dump_devs(&card->wandev);
-
- return 0;
-}
-
-/* return the number of nibbles */
-static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
-{
- int i = 0;
-
- if (*nibble && *s) {
- d[i] |= *s++ - '0';
- *nibble = 0;
- ++i;
- }
-
- while (*s) {
- d[i] = (*s - '0') << 4;
- if (*(s + 1))
- d[i] |= *(s + 1) - '0';
- else {
- *nibble = 1;
- break;
- }
- ++i;
- s += 2;
- }
-
- return i;
-}
-
-static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
-{
- if (nibble) {
- *d++ = '0' + (*s++ & 0x0F);
- --len;
- }
-
- while (len) {
- *d++ = '0' + (*s >> 4);
-
- if (--len) {
- *d++ = '0' + (*s & 0x0F);
- --len;
- } else break;
-
- ++s;
- }
-
- *d = '\0';
-}
-
-/* Place X.25 call. */
-static int x25_place_call(struct cycx_device *card,
- struct cycx_x25_channel *chan)
-{
- int err = 0,
- len;
- char d[64],
- nibble = 0,
- mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
- remotelen = strlen(chan->addr);
- u8 key;
-
- if (card->u.x.connection_keys == ~0U) {
- pr_info("%s: too many simultaneous connection requests!\n",
- card->devname);
- return -EAGAIN;
- }
-
- key = ffz(card->u.x.connection_keys);
- set_bit(key, (void*)&card->u.x.connection_keys);
- ++key;
- dprintk(1, KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
- memset(d, 0, sizeof(d));
- d[1] = key; /* user key */
- d[2] = 0x10;
- d[4] = 0x0B;
-
- len = byte_to_nibble(chan->addr, d + 6, &nibble);
-
- if (chan->local_addr)
- len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
-
- if (nibble)
- ++len;
-
- d[5] = mylen << 4 | remotelen;
- d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanks to Daniela :) */
-
- if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
- &d, 7 + len + 1, NULL, 0)) != 0)
- clear_bit(--key, (void*)&card->u.x.connection_keys);
- else
- chan->lcn = -key;
-
- return err;
-}
-
-/* Place X.25 CONNECT RESPONSE. */
-static int cycx_x25_connect_response(struct cycx_device *card,
- struct cycx_x25_channel *chan)
-{
- u8 d[8];
-
- memset(d, 0, sizeof(d));
- d[0] = d[3] = chan->lcn;
- d[2] = 0x10;
- d[4] = 0x0F;
- d[7] = 0xCC; /* TCP/IP over X.25, thanks Daniela */
-
- return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
-}
-
-/* Place X.25 DISCONNECT RESPONSE. */
-static int cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
- u8 lcn)
-{
- char d[5];
-
- memset(d, 0, sizeof(d));
- d[0] = d[3] = lcn;
- d[2] = 0x10;
- d[4] = 0x17;
-
- return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
-}
-
-/* Clear X.25 call. */
-static int x25_clear_call(struct cycx_device *card, u8 link, u8 lcn, u8 cause,
- u8 diagn)
-{
- u8 d[7];
-
- memset(d, 0, sizeof(d));
- d[0] = d[3] = lcn;
- d[2] = 0x10;
- d[4] = 0x13;
- d[5] = cause;
- d[6] = diagn;
-
- return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
-}
-
-/* Send X.25 data packet. */
-static int cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
- int len, void *buf)
-{
- u8 d[] = "?\xFF\x10??";
-
- d[0] = d[3] = lcn;
- d[4] = bitm;
-
- return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
-}
-
-/* Miscellaneous */
-/* Find network device by its channel number. */
-static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
- s16 lcn)
-{
- struct net_device *dev = wandev->dev;
- struct cycx_x25_channel *chan;
-
- while (dev) {
- chan = netdev_priv(dev);
-
- if (chan->lcn == lcn)
- break;
- dev = chan->slave;
- }
- return dev;
-}
-
-/* Find network device by its remote dte address. */
-static struct net_device *
- cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte)
-{
- struct net_device *dev = wandev->dev;
- struct cycx_x25_channel *chan;
-
- while (dev) {
- chan = netdev_priv(dev);
-
- if (!strcmp(chan->addr, dte))
- break;
- dev = chan->slave;
- }
- return dev;
-}
-
-/* Initiate connection on the logical channel.
- * o for PVC we just get channel configuration
- * o for SVCs place an X.25 call
- *
- * Return: 0 connected
- * >0 connection in progress
- * <0 failure */
-static int cycx_x25_chan_connect(struct net_device *dev)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
- struct cycx_device *card = chan->card;
-
- if (chan->svc) {
- if (!chan->addr[0])
- return -EINVAL; /* no destination address */
-
- dprintk(1, KERN_INFO "%s: placing X.25 call to %s...\n",
- card->devname, chan->addr);
-
- if (x25_place_call(card, chan))
- return -EIO;
-
- cycx_x25_set_chan_state(dev, WAN_CONNECTING);
- return 1;
- } else
- cycx_x25_set_chan_state(dev, WAN_CONNECTED);
-
- return 0;
-}
-
-/* Disconnect logical channel.
- * o if SVC then clear X.25 call */
-static void cycx_x25_chan_disconnect(struct net_device *dev)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
-
- if (chan->svc) {
- x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
- cycx_x25_set_chan_state(dev, WAN_DISCONNECTING);
- } else
- cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
-}
-
-/* Called by kernel timer */
-static void cycx_x25_chan_timer(unsigned long d)
-{
- struct net_device *dev = (struct net_device *)d;
- struct cycx_x25_channel *chan = netdev_priv(dev);
-
- if (chan->state == WAN_CONNECTED)
- cycx_x25_chan_disconnect(dev);
- else
- pr_err("%s: %s for svc (%s) not connected!\n",
- chan->card->devname, __func__, dev->name);
-}
-
-/* Set logical channel state. */
-static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
- struct cycx_device *card = chan->card;
- unsigned long flags;
- char *string_state = NULL;
-
- spin_lock_irqsave(&card->lock, flags);
-
- if (chan->state != state) {
- if (chan->svc && chan->state == WAN_CONNECTED)
- del_timer(&chan->timer);
-
- switch (state) {
- case WAN_CONNECTED:
- string_state = "connected!";
- *(__be16*)dev->dev_addr = htons(chan->lcn);
- netif_wake_queue(dev);
- reset_timer(dev);
-
- if (chan->protocol == ETH_P_X25)
- cycx_x25_chan_send_event(dev,
- X25_IFACE_CONNECT);
-
- break;
- case WAN_CONNECTING:
- string_state = "connecting...";
- break;
- case WAN_DISCONNECTING:
- string_state = "disconnecting...";
- break;
- case WAN_DISCONNECTED:
- string_state = "disconnected!";
-
- if (chan->svc) {
- *(unsigned short*)dev->dev_addr = 0;
- chan->lcn = 0;
- }
-
- if (chan->protocol == ETH_P_X25)
- cycx_x25_chan_send_event(dev,
- X25_IFACE_DISCONNECT);
-
- netif_wake_queue(dev);
- break;
- }
-
- pr_info("%s: interface %s %s\n",
- card->devname, dev->name, string_state);
- chan->state = state;
- }
-
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/* Send packet on a logical channel.
- * When this function is called, tx_skb field of the channel data space
- * points to the transmit socket buffer. When transmission is complete,
- * release socket buffer and reset 'tbusy' flag.
- *
- * Return: 0 - transmission complete
- * 1 - busy
- *
- * Notes:
- * 1. If packet length is greater than MTU for this channel, we'll fragment
- * the packet into 'complete sequence' using M-bit.
- * 2. When transmission is complete, an event notification should be issued
- * to the router. */
-static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
- struct cycx_device *card = chan->card;
- int bitm = 0; /* final packet */
- unsigned len = skb->len;
-
- if (skb->len > card->wandev.mtu) {
- len = card->wandev.mtu;
- bitm = 0x10; /* set M-bit (more data) */
- }
-
- if (cycx_x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
- return 1;
-
- if (bitm) {
- skb_pull(skb, len);
- return 1;
- }
-
- ++chan->ifstats.tx_packets;
- chan->ifstats.tx_bytes += len;
-
- return 0;
-}
-
-/* Send event (connection, disconnection, etc) to X.25 socket layer */
-
-static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
-{
- struct sk_buff *skb;
- unsigned char *ptr;
-
- if ((skb = dev_alloc_skb(1)) == NULL) {
- pr_err("%s: out of memory\n", __func__);
- return;
- }
-
- ptr = skb_put(skb, 1);
- *ptr = event;
-
- skb->protocol = x25_type_trans(skb, dev);
- netif_rx(skb);
-}
-
-/* Convert line speed in bps to a number used by cyclom 2x code. */
-static u8 bps_to_speed_code(u32 bps)
-{
- u8 number = 0; /* defaults to the lowest (1200) speed ;> */
-
- if (bps >= 512000) number = 8;
- else if (bps >= 256000) number = 7;
- else if (bps >= 64000) number = 6;
- else if (bps >= 38400) number = 5;
- else if (bps >= 19200) number = 4;
- else if (bps >= 9600) number = 3;
- else if (bps >= 4800) number = 2;
- else if (bps >= 2400) number = 1;
-
- return number;
-}
-
-/* log base 2 */
-static u8 cycx_log2(u32 n)
-{
- u8 log = 0;
-
- if (!n)
- return 0;
-
- while (n > 1) {
- n >>= 1;
- ++log;
- }
-
- return log;
-}
-
-/* Convert decimal string to unsigned integer.
- * If len != 0 then only 'len' characters of the string are converted. */
-static unsigned dec_to_uint(u8 *str, int len)
-{
- unsigned val = 0;
-
- if (!len)
- len = strlen(str);
-
- for (; len && isdigit(*str); ++str, --len)
- val = (val * 10) + (*str - (unsigned) '0');
-
- return val;
-}
-
-static void reset_timer(struct net_device *dev)
-{
- struct cycx_x25_channel *chan = netdev_priv(dev);
-
- if (chan->svc)
- mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
-}
-#ifdef CYCLOMX_X25_DEBUG
-static void cycx_x25_dump_config(struct cycx_x25_config *conf)
-{
- pr_info("X.25 configuration\n");
- pr_info("-----------------\n");
- pr_info("link number=%d\n", conf->link);
- pr_info("line speed=%d\n", conf->speed);
- pr_info("clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
- pr_info("# level 2 retransm.=%d\n", conf->n2);
- pr_info("level 2 window=%d\n", conf->n2win);
- pr_info("level 3 window=%d\n", conf->n3win);
- pr_info("# logical channels=%d\n", conf->nvc);
- pr_info("level 3 pkt len=%d\n", conf->pktlen);
- pr_info("my address=%d\n", conf->locaddr);
- pr_info("remote address=%d\n", conf->remaddr);
- pr_info("t1=%d seconds\n", conf->t1);
- pr_info("t2=%d seconds\n", conf->t2);
- pr_info("t21=%d seconds\n", conf->t21);
- pr_info("# PVCs=%d\n", conf->npvc);
- pr_info("t23=%d seconds\n", conf->t23);
- pr_info("flags=0x%x\n", conf->flags);
-}
-
-static void cycx_x25_dump_stats(struct cycx_x25_stats *stats)
-{
- pr_info("X.25 statistics\n");
- pr_info("--------------\n");
- pr_info("rx_crc_errors=%d\n", stats->rx_crc_errors);
- pr_info("rx_over_errors=%d\n", stats->rx_over_errors);
- pr_info("n2_tx_frames=%d\n", stats->n2_tx_frames);
- pr_info("n2_rx_frames=%d\n", stats->n2_rx_frames);
- pr_info("tx_timeouts=%d\n", stats->tx_timeouts);
- pr_info("rx_timeouts=%d\n", stats->rx_timeouts);
- pr_info("n3_tx_packets=%d\n", stats->n3_tx_packets);
- pr_info("n3_rx_packets=%d\n", stats->n3_rx_packets);
- pr_info("tx_aborts=%d\n", stats->tx_aborts);
- pr_info("rx_aborts=%d\n", stats->rx_aborts);
-}
-
-static void cycx_x25_dump_devs(struct wan_device *wandev)
-{
- struct net_device *dev = wandev->dev;
-
- pr_info("X.25 dev states\n");
- pr_info("name: addr: txoff: protocol:\n");
- pr_info("---------------------------------------\n");
-
- while(dev) {
- struct cycx_x25_channel *chan = netdev_priv(dev);
-
- pr_info("%-5.5s %-15.15s %d ETH_P_%s\n",
- chan->name, chan->addr, netif_queue_stopped(dev),
- chan->protocol == ETH_P_IP ? "IP" : "X25");
- dev = chan->slave;
- }
-}
-
-#endif /* CYCLOMX_X25_DEBUG */
-/* End */
diff --git a/include/linux/cyclomx.h b/include/linux/cyclomx.h
deleted file mode 100644
index b88f7f4..0000000
--- a/include/linux/cyclomx.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef _CYCLOMX_H
-#define _CYCLOMX_H
-/*
-* cyclomx.h Cyclom 2X WAN Link Driver.
-* User-level API definitions.
-*
-* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-*
-* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
-*
-* Based on wanpipe.h by Gene Kozin <genek@compuserve.com>
-*
-* 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.
-* ============================================================================
-* 2000/07/13 acme remove crap #if KERNEL_VERSION > blah
-* 2000/01/21 acme rename cyclomx_open to cyclomx_mod_inc_use_count
-* and cyclomx_close to cyclomx_mod_dec_use_count
-* 1999/05/19 acme wait_queue_head_t wait_stats(support for 2.3.*)
-* 1999/01/03 acme judicious use of data types
-* 1998/12/27 acme cleanup: PACKED not needed
-* 1998/08/08 acme Version 0.0.1
-*/
-
-#include <linux/wanrouter.h>
-#include <linux/spinlock.h>
-
-#ifdef __KERNEL__
-/* Kernel Interface */
-
-#include <linux/cycx_drv.h> /* Cyclom 2X support module API definitions */
-#include <linux/cycx_cfm.h> /* Cyclom 2X firmware module definitions */
-#ifdef CONFIG_CYCLOMX_X25
-#include <linux/cycx_x25.h>
-#endif
-
-/* Adapter Data Space.
- * This structure is needed because we handle multiple cards, otherwise
- * static data would do it.
- */
-struct cycx_device {
- char devname[WAN_DRVNAME_SZ + 1];/* card name */
- struct cycx_hw hw; /* hardware configuration */
- struct wan_device wandev; /* WAN device data space */
- u32 state_tick; /* link state timestamp */
- spinlock_t lock;
- char in_isr; /* interrupt-in-service flag */
- char buff_int_mode_unbusy; /* flag for carrying out dev_tint */
- wait_queue_head_t wait_stats; /* to wait for the STATS indication */
- void __iomem *mbox; /* -> mailbox */
- void (*isr)(struct cycx_device* card); /* interrupt service routine */
- int (*exec)(struct cycx_device* card, void* u_cmd, void* u_data);
- union {
-#ifdef CONFIG_CYCLOMX_X25
- struct { /* X.25 specific data */
- u32 lo_pvc;
- u32 hi_pvc;
- u32 lo_svc;
- u32 hi_svc;
- struct cycx_x25_stats stats;
- spinlock_t lock;
- u32 connection_keys;
- } x;
-#endif
- } u;
-};
-
-/* Public Functions */
-void cycx_set_state(struct cycx_device *card, int state);
-
-#ifdef CONFIG_CYCLOMX_X25
-int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf);
-#endif
-#endif /* __KERNEL__ */
-#endif /* _CYCLOMX_H */
diff --git a/include/linux/cycx_drv.h b/include/linux/cycx_drv.h
deleted file mode 100644
index 12fe6b0..0000000
--- a/include/linux/cycx_drv.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-* cycx_drv.h CYCX Support Module. Kernel API Definitions.
-*
-* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-*
-* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
-*
-* Based on sdladrv.h by Gene Kozin <genek@compuserve.com>
-*
-* 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.
-* ============================================================================
-* 1999/10/23 acme cycxhw_t cleanup
-* 1999/01/03 acme more judicious use of data types...
-* uclong, ucchar, etc deleted, the u8, u16, u32
-* types are the portable way to go.
-* 1999/01/03 acme judicious use of data types... u16, u32, etc
-* 1998/12/26 acme FIXED_BUFFERS, CONF_OFFSET,
-* removal of cy_read{bwl}
-* 1998/08/08 acme Initial version.
-*/
-#ifndef _CYCX_DRV_H
-#define _CYCX_DRV_H
-
-#define CYCX_WINDOWSIZE 0x4000 /* default dual-port memory window size */
-#define GEN_CYCX_INTR 0x02
-#define RST_ENABLE 0x04
-#define START_CPU 0x06
-#define RST_DISABLE 0x08
-#define FIXED_BUFFERS 0x08
-#define TEST_PATTERN 0xaa55
-#define CMD_OFFSET 0x20
-#define CONF_OFFSET 0x0380
-#define RESET_OFFSET 0x3c00 /* For reset file load */
-#define DATA_OFFSET 0x0100 /* For code and data files load */
-#define START_OFFSET 0x3ff0 /* 80186 starts here */
-
-/**
- * struct cycx_hw - Adapter hardware configuration
- * @fwid - firmware ID
- * @irq - interrupt request level
- * @dpmbase - dual-port memory base
- * @dpmsize - dual-port memory size
- * @reserved - reserved for future use
- */
-struct cycx_hw {
- u32 fwid;
- int irq;
- void __iomem *dpmbase;
- u32 dpmsize;
- u32 reserved[5];
-};
-
-/* Function Prototypes */
-extern int cycx_setup(struct cycx_hw *hw, void *sfm, u32 len, unsigned long base);
-extern int cycx_down(struct cycx_hw *hw);
-extern int cycx_peek(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
-extern int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
-extern int cycx_exec(void __iomem *addr);
-
-extern void cycx_intr(struct cycx_hw *hw);
-#endif /* _CYCX_DRV_H */
diff --git a/include/linux/wanrouter.h b/include/linux/wanrouter.h
deleted file mode 100644
index cec4b41..0000000
--- a/include/linux/wanrouter.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*****************************************************************************
-* wanrouter.h Definitions for the WAN Multiprotocol Router Module.
-* This module provides API and common services for WAN Link
-* Drivers and is completely hardware-independent.
-*
-* Author: Nenad Corbic <ncorbic@sangoma.com>
-* Gideon Hack
-* Additions: Arnaldo Melo
-*
-* Copyright: (c) 1995-2000 Sangoma Technologies Inc.
-*
-* 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.
-* ============================================================================
-* Jul 21, 2000 Nenad Corbic Added WAN_FT1_READY State
-* Feb 24, 2000 Nenad Corbic Added support for socket based x25api
-* Jan 28, 2000 Nenad Corbic Added support for the ASYNC protocol.
-* Oct 04, 1999 Nenad Corbic Updated for 2.1.0 release
-* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
-* May 23, 1999 Arnaldo Melo Added local_addr to wanif_conf_t
-* WAN_DISCONNECTING state added
-* Jul 20, 1998 David Fong Added Inverse ARP options to 'wanif_conf_t'
-* Jun 12, 1998 David Fong Added Cisco HDLC support.
-* Dec 16, 1997 Jaspreet Singh Moved 'enable_IPX' and 'network_number' to
-* 'wanif_conf_t'
-* Dec 05, 1997 Jaspreet Singh Added 'pap', 'chap' to 'wanif_conf_t'
-* Added 'authenticator' to 'wan_ppp_conf_t'
-* Nov 06, 1997 Jaspreet Singh Changed Router Driver version to 1.1 from 1.0
-* Oct 20, 1997 Jaspreet Singh Added 'cir','bc','be' and 'mc' to 'wanif_conf_t'
-* Added 'enable_IPX' and 'network_number' to
-* 'wan_device_t'. Also added defines for
-* UDP PACKET TYPE, Interrupt test, critical values
-* for RACE conditions.
-* Oct 05, 1997 Jaspreet Singh Added 'dlci_num' and 'dlci[100]' to
-* 'wan_fr_conf_t' to configure a list of dlci(s)
-* for a NODE
-* Jul 07, 1997 Jaspreet Singh Added 'ttl' to 'wandev_conf_t' & 'wan_device_t'
-* May 29, 1997 Jaspreet Singh Added 'tx_int_enabled' to 'wan_device_t'
-* May 21, 1997 Jaspreet Singh Added 'udp_port' to 'wan_device_t'
-* Apr 25, 1997 Farhan Thawar Added 'udp_port' to 'wandev_conf_t'
-* Jan 16, 1997 Gene Kozin router_devlist made public
-* Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h).
-*****************************************************************************/
-#ifndef _ROUTER_H
-#define _ROUTER_H
-
-#include <uapi/linux/wanrouter.h>
-
-/****** Kernel Interface ****************************************************/
-
-#include <linux/fs.h> /* support for device drivers */
-#include <linux/proc_fs.h> /* proc filesystem pragmatics */
-#include <linux/netdevice.h> /* support for network drivers */
-#include <linux/spinlock.h> /* Support for SMP Locking */
-
-/*----------------------------------------------------------------------------
- * WAN device data space.
- */
-struct wan_device {
- unsigned magic; /* magic number */
- char* name; /* -> WAN device name (ASCIIZ) */
- void* private; /* -> driver private data */
- unsigned config_id; /* Configuration ID */
- /****** hardware configuration ******/
- unsigned ioport; /* adapter I/O port base #1 */
- char S514_cpu_no[1]; /* PCI CPU Number */
- unsigned char S514_slot_no; /* PCI Slot Number */
- unsigned long maddr; /* dual-port memory address */
- unsigned msize; /* dual-port memory size */
- int irq; /* interrupt request level */
- int dma; /* DMA request level */
- unsigned bps; /* data transfer rate */
- unsigned mtu; /* max physical transmit unit size */
- unsigned udp_port; /* UDP port for management */
- unsigned char ttl; /* Time To Live for UDP security */
- unsigned enable_tx_int; /* Transmit Interrupt enabled or not */
- char interface; /* RS-232/V.35, etc. */
- char clocking; /* external/internal */
- char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */
- char station; /* DTE/DCE, primary/secondary, etc. */
- char connection; /* permanent/switched/on-demand */
- char signalling; /* Signalling RS232 or V35 */
- char read_mode; /* read mode: Polling or interrupt */
- char new_if_cnt; /* Number of interfaces per wanpipe */
- char del_if_cnt; /* Number of times del_if() gets called */
- unsigned char piggyback; /* Piggibacking a port */
- unsigned hw_opt[4]; /* other hardware options */
- /****** status and statistics *******/
- char state; /* device state */
- char api_status; /* device api status */
- struct net_device_stats stats; /* interface statistics */
- unsigned reserved[16]; /* reserved for future use */
- unsigned long critical; /* critical section flag */
- spinlock_t lock; /* Support for SMP Locking */
-
- /****** device management methods ***/
- int (*setup) (struct wan_device *wandev, wandev_conf_t *conf);
- int (*shutdown) (struct wan_device *wandev);
- int (*update) (struct wan_device *wandev);
- int (*ioctl) (struct wan_device *wandev, unsigned cmd,
- unsigned long arg);
- int (*new_if)(struct wan_device *wandev, struct net_device *dev,
- wanif_conf_t *conf);
- int (*del_if)(struct wan_device *wandev, struct net_device *dev);
- /****** maintained by the router ****/
- struct wan_device* next; /* -> next device */
- struct net_device* dev; /* list of network interfaces */
- unsigned ndev; /* number of interfaces */
- struct proc_dir_entry *dent; /* proc filesystem entry */
-};
-
-/* Public functions available for device drivers */
-extern int register_wan_device(struct wan_device *wandev);
-extern int unregister_wan_device(char *name);
-
-/* Proc interface functions. These must not be called by the drivers! */
-extern int wanrouter_proc_init(void);
-extern void wanrouter_proc_cleanup(void);
-extern int wanrouter_proc_add(struct wan_device *wandev);
-extern int wanrouter_proc_delete(struct wan_device *wandev);
-extern long wanrouter_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-
-/* Public Data */
-/* list of registered devices */
-extern struct wan_device *wanrouter_router_devlist;
-
-#endif /* _ROUTER_H */
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index e194387..c54b7e7 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -408,7 +408,6 @@ header-y += virtio_ring.h
header-y += virtio_rng.h
header-y += vt.h
header-y += wait.h
-header-y += wanrouter.h
header-y += watchdog.h
header-y += wimax.h
header-y += wireless.h
diff --git a/include/uapi/linux/wanrouter.h b/include/uapi/linux/wanrouter.h
deleted file mode 100644
index 7617df2..0000000
--- a/include/uapi/linux/wanrouter.h
+++ /dev/null
@@ -1,452 +0,0 @@
-/*****************************************************************************
-* wanrouter.h Definitions for the WAN Multiprotocol Router Module.
-* This module provides API and common services for WAN Link
-* Drivers and is completely hardware-independent.
-*
-* Author: Nenad Corbic <ncorbic@sangoma.com>
-* Gideon Hack
-* Additions: Arnaldo Melo
-*
-* Copyright: (c) 1995-2000 Sangoma Technologies Inc.
-*
-* 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.
-* ============================================================================
-* Jul 21, 2000 Nenad Corbic Added WAN_FT1_READY State
-* Feb 24, 2000 Nenad Corbic Added support for socket based x25api
-* Jan 28, 2000 Nenad Corbic Added support for the ASYNC protocol.
-* Oct 04, 1999 Nenad Corbic Updated for 2.1.0 release
-* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
-* May 23, 1999 Arnaldo Melo Added local_addr to wanif_conf_t
-* WAN_DISCONNECTING state added
-* Jul 20, 1998 David Fong Added Inverse ARP options to 'wanif_conf_t'
-* Jun 12, 1998 David Fong Added Cisco HDLC support.
-* Dec 16, 1997 Jaspreet Singh Moved 'enable_IPX' and 'network_number' to
-* 'wanif_conf_t'
-* Dec 05, 1997 Jaspreet Singh Added 'pap', 'chap' to 'wanif_conf_t'
-* Added 'authenticator' to 'wan_ppp_conf_t'
-* Nov 06, 1997 Jaspreet Singh Changed Router Driver version to 1.1 from 1.0
-* Oct 20, 1997 Jaspreet Singh Added 'cir','bc','be' and 'mc' to 'wanif_conf_t'
-* Added 'enable_IPX' and 'network_number' to
-* 'wan_device_t'. Also added defines for
-* UDP PACKET TYPE, Interrupt test, critical values
-* for RACE conditions.
-* Oct 05, 1997 Jaspreet Singh Added 'dlci_num' and 'dlci[100]' to
-* 'wan_fr_conf_t' to configure a list of dlci(s)
-* for a NODE
-* Jul 07, 1997 Jaspreet Singh Added 'ttl' to 'wandev_conf_t' & 'wan_device_t'
-* May 29, 1997 Jaspreet Singh Added 'tx_int_enabled' to 'wan_device_t'
-* May 21, 1997 Jaspreet Singh Added 'udp_port' to 'wan_device_t'
-* Apr 25, 1997 Farhan Thawar Added 'udp_port' to 'wandev_conf_t'
-* Jan 16, 1997 Gene Kozin router_devlist made public
-* Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h).
-*****************************************************************************/
-
-#ifndef _UAPI_ROUTER_H
-#define _UAPI_ROUTER_H
-
-#define ROUTER_NAME "wanrouter" /* in case we ever change it */
-#define ROUTER_VERSION 1 /* version number */
-#define ROUTER_RELEASE 1 /* release (minor version) number */
-#define ROUTER_IOCTL 'W' /* for IOCTL calls */
-#define ROUTER_MAGIC 0x524D4157L /* signature: 'WANR' reversed */
-
-/* IOCTL codes for /proc/router/<device> entries (up to 255) */
-enum router_ioctls
-{
- ROUTER_SETUP = ROUTER_IOCTL<<8, /* configure device */
- ROUTER_DOWN, /* shut down device */
- ROUTER_STAT, /* get device status */
- ROUTER_IFNEW, /* add interface */
- ROUTER_IFDEL, /* delete interface */
- ROUTER_IFSTAT, /* get interface status */
- ROUTER_USER = (ROUTER_IOCTL<<8)+16, /* driver-specific calls */
- ROUTER_USER_MAX = (ROUTER_IOCTL<<8)+31
-};
-
-/* identifiers for displaying proc file data for dual port adapters */
-#define PROC_DATA_PORT_0 0x8000 /* the data is for port 0 */
-#define PROC_DATA_PORT_1 0x8001 /* the data is for port 1 */
-
-/* NLPID for packet encapsulation (ISO/IEC TR 9577) */
-#define NLPID_IP 0xCC /* Internet Protocol Datagram */
-#define NLPID_SNAP 0x80 /* IEEE Subnetwork Access Protocol */
-#define NLPID_CLNP 0x81 /* ISO/IEC 8473 */
-#define NLPID_ESIS 0x82 /* ISO/IEC 9542 */
-#define NLPID_ISIS 0x83 /* ISO/IEC ISIS */
-#define NLPID_Q933 0x08 /* CCITT Q.933 */
-
-/* Miscellaneous */
-#define WAN_IFNAME_SZ 15 /* max length of the interface name */
-#define WAN_DRVNAME_SZ 15 /* max length of the link driver name */
-#define WAN_ADDRESS_SZ 31 /* max length of the WAN media address */
-#define USED_BY_FIELD 8 /* max length of the used by field */
-
-/* Defines for UDP PACKET TYPE */
-#define UDP_PTPIPE_TYPE 0x01
-#define UDP_FPIPE_TYPE 0x02
-#define UDP_CPIPE_TYPE 0x03
-#define UDP_DRVSTATS_TYPE 0x04
-#define UDP_INVALID_TYPE 0x05
-
-/* Command return code */
-#define CMD_OK 0 /* normal firmware return code */
-#define CMD_TIMEOUT 0xFF /* firmware command timed out */
-
-/* UDP Packet Management */
-#define UDP_PKT_FRM_STACK 0x00
-#define UDP_PKT_FRM_NETWORK 0x01
-
-/* Maximum interrupt test counter */
-#define MAX_INTR_TEST_COUNTER 100
-
-/* Critical Values for RACE conditions*/
-#define CRITICAL_IN_ISR 0xA1
-#define CRITICAL_INTR_HANDLED 0xB1
-
-/****** Data Types **********************************************************/
-
-/*----------------------------------------------------------------------------
- * X.25-specific link-level configuration.
- */
-typedef struct wan_x25_conf
-{
- unsigned lo_pvc; /* lowest permanent circuit number */
- unsigned hi_pvc; /* highest permanent circuit number */
- unsigned lo_svc; /* lowest switched circuit number */
- unsigned hi_svc; /* highest switched circuit number */
- unsigned hdlc_window; /* HDLC window size (1..7) */
- unsigned pkt_window; /* X.25 packet window size (1..7) */
- unsigned t1; /* HDLC timer T1, sec (1..30) */
- unsigned t2; /* HDLC timer T2, sec (0..29) */
- unsigned t4; /* HDLC supervisory frame timer = T4 * T1 */
- unsigned n2; /* HDLC retransmission limit (1..30) */
- unsigned t10_t20; /* X.25 RESTART timeout, sec (1..255) */
- unsigned t11_t21; /* X.25 CALL timeout, sec (1..255) */
- unsigned t12_t22; /* X.25 RESET timeout, sec (1..255) */
- unsigned t13_t23; /* X.25 CLEAR timeout, sec (1..255) */
- unsigned t16_t26; /* X.25 INTERRUPT timeout, sec (1..255) */
- unsigned t28; /* X.25 REGISTRATION timeout, sec (1..255) */
- unsigned r10_r20; /* RESTART retransmission limit (0..250) */
- unsigned r12_r22; /* RESET retransmission limit (0..250) */
- unsigned r13_r23; /* CLEAR retransmission limit (0..250) */
- unsigned ccitt_compat; /* compatibility mode: 1988/1984/1980 */
- unsigned x25_conf_opt; /* User defined x25 config optoins */
- unsigned char LAPB_hdlc_only; /* Run in HDLC only mode */
- unsigned char logging; /* Control connection logging */
- unsigned char oob_on_modem; /* Whether to send modem status to the user app */
-} wan_x25_conf_t;
-
-/*----------------------------------------------------------------------------
- * Frame relay specific link-level configuration.
- */
-typedef struct wan_fr_conf
-{
- unsigned signalling; /* local in-channel signalling type */
- unsigned t391; /* link integrity verification timer */
- unsigned t392; /* polling verification timer */
- unsigned n391; /* full status polling cycle counter */
- unsigned n392; /* error threshold counter */
- unsigned n393; /* monitored events counter */
- unsigned dlci_num; /* number of DLCs (access node) */
- unsigned dlci[100]; /* List of all DLCIs */
-} wan_fr_conf_t;
-
-/*----------------------------------------------------------------------------
- * PPP-specific link-level configuration.
- */
-typedef struct wan_ppp_conf
-{
- unsigned restart_tmr; /* restart timer */
- unsigned auth_rsrt_tmr; /* authentication timer */
- unsigned auth_wait_tmr; /* authentication timer */
- unsigned mdm_fail_tmr; /* modem failure timer */
- unsigned dtr_drop_tmr; /* DTR drop timer */
- unsigned connect_tmout; /* connection timeout */
- unsigned conf_retry; /* max. retry */
- unsigned term_retry; /* max. retry */
- unsigned fail_retry; /* max. retry */
- unsigned auth_retry; /* max. retry */
- unsigned auth_options; /* authentication opt. */
- unsigned ip_options; /* IP options */
- char authenticator; /* AUTHENTICATOR or not */
- char ip_mode; /* Static/Host/Peer */
-} wan_ppp_conf_t;
-
-/*----------------------------------------------------------------------------
- * CHDLC-specific link-level configuration.
- */
-typedef struct wan_chdlc_conf
-{
- unsigned char ignore_dcd; /* Protocol options: */
- unsigned char ignore_cts; /* Ignore these to determine */
- unsigned char ignore_keepalive; /* link status (Yes or No) */
- unsigned char hdlc_streaming; /* hdlc_streaming mode (Y/N) */
- unsigned char receive_only; /* no transmit buffering (Y/N) */
- unsigned keepalive_tx_tmr; /* transmit keepalive timer */
- unsigned keepalive_rx_tmr; /* receive keepalive timer */
- unsigned keepalive_err_margin; /* keepalive_error_tolerance */
- unsigned slarp_timer; /* SLARP request timer */
-} wan_chdlc_conf_t;
-
-
-/*----------------------------------------------------------------------------
- * WAN device configuration. Passed to ROUTER_SETUP IOCTL.
- */
-typedef struct wandev_conf
-{
- unsigned magic; /* magic number (for verification) */
- unsigned config_id; /* configuration structure identifier */
- /****** hardware configuration ******/
- unsigned ioport; /* adapter I/O port base */
- unsigned long maddr; /* dual-port memory address */
- unsigned msize; /* dual-port memory size */
- int irq; /* interrupt request level */
- int dma; /* DMA request level */
- char S514_CPU_no[1]; /* S514 PCI adapter CPU number ('A' or 'B') */
- unsigned PCI_slot_no; /* S514 PCI adapter slot number */
- char auto_pci_cfg; /* S515 PCI automatic slot detection */
- char comm_port; /* Communication Port (PRI=0, SEC=1) */
- unsigned bps; /* data transfer rate */
- unsigned mtu; /* maximum transmit unit size */
- unsigned udp_port; /* UDP port for management */
- unsigned char ttl; /* Time To Live for UDP security */
- unsigned char ft1; /* FT1 Configurator Option */
- char interface; /* RS-232/V.35, etc. */
- char clocking; /* external/internal */
- char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */
- char station; /* DTE/DCE, primary/secondary, etc. */
- char connection; /* permanent/switched/on-demand */
- char read_mode; /* read mode: Polling or interrupt */
- char receive_only; /* disable tx buffers */
- char tty; /* Create a fake tty device */
- unsigned tty_major; /* Major number for wanpipe tty device */
- unsigned tty_minor; /* Minor number for wanpipe tty device */
- unsigned tty_mode; /* TTY operation mode SYNC or ASYNC */
- char backup; /* Backup Mode */
- unsigned hw_opt[4]; /* other hardware options */
- unsigned reserved[4];
- /****** arbitrary data ***************/
- unsigned data_size; /* data buffer size */
- void* data; /* data buffer, e.g. firmware */
- union /****** protocol-specific ************/
- {
- wan_x25_conf_t x25; /* X.25 configuration */
- wan_ppp_conf_t ppp; /* PPP configuration */
- wan_fr_conf_t fr; /* frame relay configuration */
- wan_chdlc_conf_t chdlc; /* Cisco HDLC configuration */
- } u;
-} wandev_conf_t;
-
-/* 'config_id' definitions */
-#define WANCONFIG_X25 101 /* X.25 link */
-#define WANCONFIG_FR 102 /* frame relay link */
-#define WANCONFIG_PPP 103 /* synchronous PPP link */
-#define WANCONFIG_CHDLC 104 /* Cisco HDLC Link */
-#define WANCONFIG_BSC 105 /* BiSync Streaming */
-#define WANCONFIG_HDLC 106 /* HDLC Support */
-#define WANCONFIG_MPPP 107 /* Multi Port PPP over RAW CHDLC */
-
-/*
- * Configuration options defines.
- */
-/* general options */
-#define WANOPT_OFF 0
-#define WANOPT_ON 1
-#define WANOPT_NO 0
-#define WANOPT_YES 1
-
-/* intercace options */
-#define WANOPT_RS232 0
-#define WANOPT_V35 1
-
-/* data encoding options */
-#define WANOPT_NRZ 0
-#define WANOPT_NRZI 1
-#define WANOPT_FM0 2
-#define WANOPT_FM1 3
-
-/* link type options */
-#define WANOPT_POINTTOPOINT 0 /* RTS always active */
-#define WANOPT_MULTIDROP 1 /* RTS is active when transmitting */
-
-/* clocking options */
-#define WANOPT_EXTERNAL 0
-#define WANOPT_INTERNAL 1
-
-/* station options */
-#define WANOPT_DTE 0
-#define WANOPT_DCE 1
-#define WANOPT_CPE 0
-#define WANOPT_NODE 1
-#define WANOPT_SECONDARY 0
-#define WANOPT_PRIMARY 1
-
-/* connection options */
-#define WANOPT_PERMANENT 0 /* DTR always active */
-#define WANOPT_SWITCHED 1 /* use DTR to setup link (dial-up) */
-#define WANOPT_ONDEMAND 2 /* activate DTR only before sending */
-
-/* frame relay in-channel signalling */
-#define WANOPT_FR_ANSI 1 /* ANSI T1.617 Annex D */
-#define WANOPT_FR_Q933 2 /* ITU Q.933A */
-#define WANOPT_FR_LMI 3 /* LMI */
-
-/* PPP IP Mode Options */
-#define WANOPT_PPP_STATIC 0
-#define WANOPT_PPP_HOST 1
-#define WANOPT_PPP_PEER 2
-
-/* ASY Mode Options */
-#define WANOPT_ONE 1
-#define WANOPT_TWO 2
-#define WANOPT_ONE_AND_HALF 3
-
-#define WANOPT_NONE 0
-#define WANOPT_ODD 1
-#define WANOPT_EVEN 2
-
-/* CHDLC Protocol Options */
-/* DF Commented out for now.
-
-#define WANOPT_CHDLC_NO_DCD IGNORE_DCD_FOR_LINK_STAT
-#define WANOPT_CHDLC_NO_CTS IGNORE_CTS_FOR_LINK_STAT
-#define WANOPT_CHDLC_NO_KEEPALIVE IGNORE_KPALV_FOR_LINK_STAT
-*/
-
-/* Port options */
-#define WANOPT_PRI 0
-#define WANOPT_SEC 1
-/* read mode */
-#define WANOPT_INTR 0
-#define WANOPT_POLL 1
-
-
-#define WANOPT_TTY_SYNC 0
-#define WANOPT_TTY_ASYNC 1
-/*----------------------------------------------------------------------------
- * WAN Link Status Info (for ROUTER_STAT IOCTL).
- */
-typedef struct wandev_stat
-{
- unsigned state; /* link state */
- unsigned ndev; /* number of configured interfaces */
-
- /* link/interface configuration */
- unsigned connection; /* permanent/switched/on-demand */
- unsigned media_type; /* Frame relay/PPP/X.25/SDLC, etc. */
- unsigned mtu; /* max. transmit unit for this device */
-
- /* physical level statistics */
- unsigned modem_status; /* modem status */
- unsigned rx_frames; /* received frames count */
- unsigned rx_overruns; /* receiver overrun error count */
- unsigned rx_crc_err; /* receive CRC error count */
- unsigned rx_aborts; /* received aborted frames count */
- unsigned rx_bad_length; /* unexpetedly long/short frames count */
- unsigned rx_dropped; /* frames discarded at device level */
- unsigned tx_frames; /* transmitted frames count */
- unsigned tx_underruns; /* aborted transmissions (underruns) count */
- unsigned tx_timeouts; /* transmission timeouts */
- unsigned tx_rejects; /* other transmit errors */
-
- /* media level statistics */
- unsigned rx_bad_format; /* frames with invalid format */
- unsigned rx_bad_addr; /* frames with invalid media address */
- unsigned tx_retries; /* frames re-transmitted */
- unsigned reserved[16]; /* reserved for future use */
-} wandev_stat_t;
-
-/* 'state' defines */
-enum wan_states
-{
- WAN_UNCONFIGURED, /* link/channel is not configured */
- WAN_DISCONNECTED, /* link/channel is disconnected */
- WAN_CONNECTING, /* connection is in progress */
- WAN_CONNECTED, /* link/channel is operational */
- WAN_LIMIT, /* for verification only */
- WAN_DUALPORT, /* for Dual Port cards */
- WAN_DISCONNECTING,
- WAN_FT1_READY /* FT1 Configurator Ready */
-};
-
-enum {
- WAN_LOCAL_IP,
- WAN_POINTOPOINT_IP,
- WAN_NETMASK_IP,
- WAN_BROADCAST_IP
-};
-
-/* 'modem_status' masks */
-#define WAN_MODEM_CTS 0x0001 /* CTS line active */
-#define WAN_MODEM_DCD 0x0002 /* DCD line active */
-#define WAN_MODEM_DTR 0x0010 /* DTR line active */
-#define WAN_MODEM_RTS 0x0020 /* RTS line active */
-
-/*----------------------------------------------------------------------------
- * WAN interface (logical channel) configuration (for ROUTER_IFNEW IOCTL).
- */
-typedef struct wanif_conf
-{
- unsigned magic; /* magic number */
- unsigned config_id; /* configuration identifier */
- char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
- char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
- char usedby[USED_BY_FIELD]; /* used by API or WANPIPE */
- unsigned idle_timeout; /* sec, before disconnecting */
- unsigned hold_timeout; /* sec, before re-connecting */
- unsigned cir; /* Committed Information Rate fwd,bwd*/
- unsigned bc; /* Committed Burst Size fwd, bwd */
- unsigned be; /* Excess Burst Size fwd, bwd */
- unsigned char enable_IPX; /* Enable or Disable IPX */
- unsigned char inarp; /* Send Inverse ARP requests Y/N */
- unsigned inarp_interval; /* sec, between InARP requests */
- unsigned long network_number; /* Network Number for IPX */
- char mc; /* Multicast on or off */
- char local_addr[WAN_ADDRESS_SZ+1];/* local media address, ASCIIZ */
- unsigned char port; /* board port */
- unsigned char protocol; /* prococol used in this channel (TCPOX25 or X25) */
- char pap; /* PAP enabled or disabled */
- char chap; /* CHAP enabled or disabled */
- unsigned char userid[511]; /* List of User Id */
- unsigned char passwd[511]; /* List of passwords */
- unsigned char sysname[31]; /* Name of the system */
- unsigned char ignore_dcd; /* Protocol options: */
- unsigned char ignore_cts; /* Ignore these to determine */
- unsigned char ignore_keepalive; /* link status (Yes or No) */
- unsigned char hdlc_streaming; /* Hdlc streaming mode (Y/N) */
- unsigned keepalive_tx_tmr; /* transmit keepalive timer */
- unsigned keepalive_rx_tmr; /* receive keepalive timer */
- unsigned keepalive_err_margin; /* keepalive_error_tolerance */
- unsigned slarp_timer; /* SLARP request timer */
- unsigned char ttl; /* Time To Live for UDP security */
- char interface; /* RS-232/V.35, etc. */
- char clocking; /* external/internal */
- unsigned bps; /* data transfer rate */
- unsigned mtu; /* maximum transmit unit size */
- unsigned char if_down; /* brind down interface when disconnected */
- unsigned char gateway; /* Is this interface a gateway */
- unsigned char true_if_encoding; /* Set the dev->type to true board protocol */
-
- unsigned char asy_data_trans; /* async API options */
- unsigned char rts_hs_for_receive; /* async Protocol options */
- unsigned char xon_xoff_hs_for_receive;
- unsigned char xon_xoff_hs_for_transmit;
- unsigned char dcd_hs_for_transmit;
- unsigned char cts_hs_for_transmit;
- unsigned char async_mode;
- unsigned tx_bits_per_char;
- unsigned rx_bits_per_char;
- unsigned stop_bits;
- unsigned char parity;
- unsigned break_timer;
- unsigned inter_char_timer;
- unsigned rx_complete_length;
- unsigned xon_char;
- unsigned xoff_char;
- unsigned char receive_only; /* no transmit buffering (Y/N) */
-} wanif_conf_t;
-
-#endif /* _UAPI_ROUTER_H */
diff --git a/net/Kconfig b/net/Kconfig
index 30b48f5..4cf4bb5 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -209,7 +209,6 @@ source "net/ipx/Kconfig"
source "drivers/net/appletalk/Kconfig"
source "net/x25/Kconfig"
source "net/lapb/Kconfig"
-source "net/wanrouter/Kconfig"
source "net/phonet/Kconfig"
source "net/ieee802154/Kconfig"
source "net/mac802154/Kconfig"
diff --git a/net/Makefile b/net/Makefile
index 4f4ee08..c5aa8b3 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -26,7 +26,6 @@ obj-$(CONFIG_BRIDGE) += bridge/
obj-$(CONFIG_NET_DSA) += dsa/
obj-$(CONFIG_IPX) += ipx/
obj-$(CONFIG_ATALK) += appletalk/
-obj-$(CONFIG_WAN_ROUTER) += wanrouter/
obj-$(CONFIG_X25) += x25/
obj-$(CONFIG_LAPB) += lapb/
obj-$(CONFIG_NETROM) += netrom/
diff --git a/net/socket.c b/net/socket.c
index 2ca51c7..5c4d82c 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -69,7 +69,6 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
-#include <linux/wanrouter.h>
#include <linux/if_bridge.h>
#include <linux/if_frad.h>
#include <linux/if_vlan.h>
diff --git a/net/wanrouter/Kconfig b/net/wanrouter/Kconfig
deleted file mode 100644
index a157a2e..0000000
--- a/net/wanrouter/Kconfig
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Configuration for WAN router
-#
-
-config WAN_ROUTER
- tristate "WAN router (DEPRECATED)"
- depends on EXPERIMENTAL
- ---help---
- Wide Area Networks (WANs), such as X.25, frame relay and leased
- lines, are used to interconnect Local Area Networks (LANs) over vast
- distances with data transfer rates significantly higher than those
- achievable with commonly used asynchronous modem connections.
- Usually, a quite expensive external device called a `WAN router' is
- needed to connect to a WAN.
-
- As an alternative, WAN routing can be built into the Linux kernel.
- With relatively inexpensive WAN interface cards available on the
- market, a perfectly usable router can be built for less than half
- the price of an external router. If you have one of those cards and
- wish to use your Linux box as a WAN router, say Y here and also to
- the WAN driver for your card, below. You will then need the
- wan-tools package which is available from <ftp://ftp.sangoma.com/>.
-
- To compile WAN routing support as a module, choose M here: the
- module will be called wanrouter.
-
- If unsure, say N.
diff --git a/net/wanrouter/Makefile b/net/wanrouter/Makefile
deleted file mode 100644
index 4da14bc..0000000
--- a/net/wanrouter/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for the Linux WAN router layer.
-#
-
-obj-$(CONFIG_WAN_ROUTER) += wanrouter.o
-
-wanrouter-y := wanproc.o wanmain.o
diff --git a/net/wanrouter/patchlevel b/net/wanrouter/patchlevel
deleted file mode 100644
index c043eea..0000000
--- a/net/wanrouter/patchlevel
+++ /dev/null
@@ -1 +0,0 @@
-2.2.1
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
deleted file mode 100644
index 2ab7850..0000000
--- a/net/wanrouter/wanmain.c
+++ /dev/null
@@ -1,782 +0,0 @@
-/*****************************************************************************
-* wanmain.c WAN Multiprotocol Router Module. Main code.
-*
-* This module is completely hardware-independent and provides
-* the following common services for the WAN Link Drivers:
-* o WAN device management (registering, unregistering)
-* o Network interface management
-* o Physical connection management (dial-up, incoming calls)
-* o Logical connection management (switched virtual circuits)
-* o Protocol encapsulation/decapsulation
-*
-* Author: Gideon Hack
-*
-* Copyright: (c) 1995-1999 Sangoma Technologies Inc.
-*
-* 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.
-* ============================================================================
-* Nov 24, 2000 Nenad Corbic Updated for 2.4.X kernels
-* Nov 07, 2000 Nenad Corbic Fixed the Mulit-Port PPP for kernels 2.2.16 and
-* greater.
-* Aug 2, 2000 Nenad Corbic Block the Multi-Port PPP from running on
-* kernels 2.2.16 or greater. The SyncPPP
-* has changed.
-* Jul 13, 2000 Nenad Corbic Added SyncPPP support
-* Added extra debugging in device_setup().
-* Oct 01, 1999 Gideon Hack Update for s514 PCI card
-* Dec 27, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
-* Jan 16, 1997 Gene Kozin router_devlist made public
-* Jan 31, 1997 Alan Cox Hacked it about a bit for 2.1
-* Jun 27, 1997 Alan Cox realigned with vendor code
-* Oct 15, 1997 Farhan Thawar changed wan_encapsulate to add a pad byte of 0
-* Apr 20, 1998 Alan Cox Fixed 2.1 symbols
-* May 17, 1998 K. Baranowski Fixed SNAP encapsulation in wan_encapsulate
-* Dec 15, 1998 Arnaldo Melo support for firmwares of up to 128000 bytes
-* check wandev->setup return value
-* Dec 22, 1998 Arnaldo Melo vmalloc/vfree used in device_setup to allocate
-* kernel memory and copy configuration data to
-* kernel space (for big firmwares)
-* Jun 02, 1999 Gideon Hack Updates for Linux 2.0.X and 2.2.X kernels.
-*****************************************************************************/
-
-#include <linux/stddef.h> /* offsetof(), etc. */
-#include <linux/capability.h>
-#include <linux/errno.h> /* return codes */
-#include <linux/kernel.h>
-#include <linux/module.h> /* support for loadable modules */
-#include <linux/slab.h> /* kmalloc(), kfree() */
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/string.h> /* inline mem*, str* functions */
-
-#include <asm/byteorder.h> /* htons(), etc. */
-#include <linux/wanrouter.h> /* WAN router API definitions */
-
-#include <linux/vmalloc.h> /* vmalloc, vfree */
-#include <asm/uaccess.h> /* copy_to/from_user */
-#include <linux/init.h> /* __initfunc et al. */
-
-#define DEV_TO_SLAVE(dev) (*((struct net_device **)netdev_priv(dev)))
-
-/*
- * Function Prototypes
- */
-
-/*
- * WAN device IOCTL handlers
- */
-
-static DEFINE_MUTEX(wanrouter_mutex);
-static int wanrouter_device_setup(struct wan_device *wandev,
- wandev_conf_t __user *u_conf);
-static int wanrouter_device_stat(struct wan_device *wandev,
- wandev_stat_t __user *u_stat);
-static int wanrouter_device_shutdown(struct wan_device *wandev);
-static int wanrouter_device_new_if(struct wan_device *wandev,
- wanif_conf_t __user *u_conf);
-static int wanrouter_device_del_if(struct wan_device *wandev,
- char __user *u_name);
-
-/*
- * Miscellaneous
- */
-
-static struct wan_device *wanrouter_find_device(char *name);
-static int wanrouter_delete_interface(struct wan_device *wandev, char *name);
-static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
- __acquires(lock);
-static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
- __releases(lock);
-
-
-
-/*
- * Global Data
- */
-
-static char wanrouter_fullname[] = "Sangoma WANPIPE Router";
-static char wanrouter_copyright[] = "(c) 1995-2000 Sangoma Technologies Inc.";
-static char wanrouter_modname[] = ROUTER_NAME; /* short module name */
-struct wan_device* wanrouter_router_devlist; /* list of registered devices */
-
-/*
- * Organize Unique Identifiers for encapsulation/decapsulation
- */
-
-#if 0
-static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };
-static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 };
-#endif
-
-static int __init wanrouter_init(void)
-{
- int err;
-
- printk(KERN_INFO "%s v%u.%u %s\n",
- wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,
- wanrouter_copyright);
-
- err = wanrouter_proc_init();
- if (err)
- printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",
- wanrouter_modname);
-
- return err;
-}
-
-static void __exit wanrouter_cleanup (void)
-{
- wanrouter_proc_cleanup();
-}
-
-/*
- * This is just plain dumb. We should move the bugger to drivers/net/wan,
- * slap it first in directory and make it module_init(). The only reason
- * for subsys_initcall() here is that net goes after drivers (why, BTW?)
- */
-subsys_initcall(wanrouter_init);
-module_exit(wanrouter_cleanup);
-
-/*
- * Kernel APIs
- */
-
-/*
- * Register WAN device.
- * o verify device credentials
- * o create an entry for the device in the /proc/net/router directory
- * o initialize internally maintained fields of the wan_device structure
- * o link device data space to a singly-linked list
- * o if it's the first device, then start kernel 'thread'
- * o increment module use count
- *
- * Return:
- * 0 Ok
- * < 0 error.
- *
- * Context: process
- */
-
-
-int register_wan_device(struct wan_device *wandev)
-{
- int err, namelen;
-
- if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC) ||
- (wandev->name == NULL))
- return -EINVAL;
-
- namelen = strlen(wandev->name);
- if (!namelen || (namelen > WAN_DRVNAME_SZ))
- return -EINVAL;
-
- if (wanrouter_find_device(wandev->name))
- return -EEXIST;
-
-#ifdef WANDEBUG
- printk(KERN_INFO "%s: registering WAN device %s\n",
- wanrouter_modname, wandev->name);
-#endif
-
- /*
- * Register /proc directory entry
- */
- err = wanrouter_proc_add(wandev);
- if (err) {
- printk(KERN_INFO
- "%s: can't create /proc/net/router/%s entry!\n",
- wanrouter_modname, wandev->name);
- return err;
- }
-
- /*
- * Initialize fields of the wan_device structure maintained by the
- * router and update local data.
- */
-
- wandev->ndev = 0;
- wandev->dev = NULL;
- wandev->next = wanrouter_router_devlist;
- wanrouter_router_devlist = wandev;
- return 0;
-}
-
-/*
- * Unregister WAN device.
- * o shut down device
- * o unlink device data space from the linked list
- * o delete device entry in the /proc/net/router directory
- * o decrement module use count
- *
- * Return: 0 Ok
- * <0 error.
- * Context: process
- */
-
-
-int unregister_wan_device(char *name)
-{
- struct wan_device *wandev, *prev;
-
- if (name == NULL)
- return -EINVAL;
-
- for (wandev = wanrouter_router_devlist, prev = NULL;
- wandev && strcmp(wandev->name, name);
- prev = wandev, wandev = wandev->next)
- ;
- if (wandev == NULL)
- return -ENODEV;
-
-#ifdef WANDEBUG
- printk(KERN_INFO "%s: unregistering WAN device %s\n",
- wanrouter_modname, name);
-#endif
-
- if (wandev->state != WAN_UNCONFIGURED)
- wanrouter_device_shutdown(wandev);
-
- if (prev)
- prev->next = wandev->next;
- else
- wanrouter_router_devlist = wandev->next;
-
- wanrouter_proc_delete(wandev);
- return 0;
-}
-
-#if 0
-
-/*
- * Encapsulate packet.
- *
- * Return: encapsulation header size
- * < 0 - unsupported Ethertype
- *
- * Notes:
- * 1. This function may be called on interrupt context.
- */
-
-
-int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev,
- unsigned short type)
-{
- int hdr_len = 0;
-
- switch (type) {
- case ETH_P_IP: /* IP datagram encapsulation */
- hdr_len += 1;
- skb_push(skb, 1);
- skb->data[0] = NLPID_IP;
- break;
-
- case ETH_P_IPX: /* SNAP encapsulation */
- case ETH_P_ARP:
- hdr_len += 7;
- skb_push(skb, 7);
- skb->data[0] = 0;
- skb->data[1] = NLPID_SNAP;
- skb_copy_to_linear_data_offset(skb, 2, wanrouter_oui_ether,
- sizeof(wanrouter_oui_ether));
- *((unsigned short*)&skb->data[5]) = htons(type);
- break;
-
- default: /* Unknown packet type */
- printk(KERN_INFO
- "%s: unsupported Ethertype 0x%04X on interface %s!\n",
- wanrouter_modname, type, dev->name);
- hdr_len = -EINVAL;
- }
- return hdr_len;
-}
-
-
-/*
- * Decapsulate packet.
- *
- * Return: Ethertype (in network order)
- * 0 unknown encapsulation
- *
- * Notes:
- * 1. This function may be called on interrupt context.
- */
-
-
-__be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
-{
- int cnt = skb->data[0] ? 0 : 1; /* there may be a pad present */
- __be16 ethertype;
-
- switch (skb->data[cnt]) {
- case NLPID_IP: /* IP datagramm */
- ethertype = htons(ETH_P_IP);
- cnt += 1;
- break;
-
- case NLPID_SNAP: /* SNAP encapsulation */
- if (memcmp(&skb->data[cnt + 1], wanrouter_oui_ether,
- sizeof(wanrouter_oui_ether))){
- printk(KERN_INFO
- "%s: unsupported SNAP OUI %02X-%02X-%02X "
- "on interface %s!\n", wanrouter_modname,
- skb->data[cnt+1], skb->data[cnt+2],
- skb->data[cnt+3], dev->name);
- return 0;
- }
- ethertype = *((__be16*)&skb->data[cnt+4]);
- cnt += 6;
- break;
-
- /* add other protocols, e.g. CLNP, ESIS, ISIS, if needed */
-
- default:
- printk(KERN_INFO
- "%s: unsupported NLPID 0x%02X on interface %s!\n",
- wanrouter_modname, skb->data[cnt], dev->name);
- return 0;
- }
- skb->protocol = ethertype;
- skb->pkt_type = PACKET_HOST; /* Physically point to point */
- skb_pull(skb, cnt);
- skb_reset_mac_header(skb);
- return ethertype;
-}
-
-#endif /* 0 */
-
-/*
- * WAN device IOCTL.
- * o find WAN device associated with this node
- * o execute requested action or pass command to the device driver
- */
-
-long wanrouter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct inode *inode = file->f_path.dentry->d_inode;
- int err = 0;
- struct proc_dir_entry *dent;
- struct wan_device *wandev;
- void __user *data = (void __user *)arg;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if ((cmd >> 8) != ROUTER_IOCTL)
- return -EINVAL;
-
- dent = PDE(inode);
- if ((dent == NULL) || (dent->data == NULL))
- return -EINVAL;
-
- wandev = dent->data;
- if (wandev->magic != ROUTER_MAGIC)
- return -EINVAL;
-
- mutex_lock(&wanrouter_mutex);
- switch (cmd) {
- case ROUTER_SETUP:
- err = wanrouter_device_setup(wandev, data);
- break;
-
- case ROUTER_DOWN:
- err = wanrouter_device_shutdown(wandev);
- break;
-
- case ROUTER_STAT:
- err = wanrouter_device_stat(wandev, data);
- break;
-
- case ROUTER_IFNEW:
- err = wanrouter_device_new_if(wandev, data);
- break;
-
- case ROUTER_IFDEL:
- err = wanrouter_device_del_if(wandev, data);
- break;
-
- case ROUTER_IFSTAT:
- break;
-
- default:
- if ((cmd >= ROUTER_USER) &&
- (cmd <= ROUTER_USER_MAX) &&
- wandev->ioctl)
- err = wandev->ioctl(wandev, cmd, arg);
- else err = -EINVAL;
- }
- mutex_unlock(&wanrouter_mutex);
- return err;
-}
-
-/*
- * WAN Driver IOCTL Handlers
- */
-
-/*
- * Setup WAN link device.
- * o verify user address space
- * o allocate kernel memory and copy configuration data to kernel space
- * o if configuration data includes extension, copy it to kernel space too
- * o call driver's setup() entry point
- */
-
-static int wanrouter_device_setup(struct wan_device *wandev,
- wandev_conf_t __user *u_conf)
-{
- void *data = NULL;
- wandev_conf_t *conf;
- int err = -EINVAL;
-
- if (wandev->setup == NULL) { /* Nothing to do ? */
- printk(KERN_INFO "%s: ERROR, No setup script: wandev->setup()\n",
- wandev->name);
- return 0;
- }
-
- conf = kmalloc(sizeof(wandev_conf_t), GFP_KERNEL);
- if (conf == NULL){
- printk(KERN_INFO "%s: ERROR, Failed to allocate kernel memory !\n",
- wandev->name);
- return -ENOBUFS;
- }
-
- if (copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) {
- printk(KERN_INFO "%s: Failed to copy user config data to kernel space!\n",
- wandev->name);
- kfree(conf);
- return -EFAULT;
- }
-
- if (conf->magic != ROUTER_MAGIC) {
- kfree(conf);
- printk(KERN_INFO "%s: ERROR, Invalid MAGIC Number\n",
- wandev->name);
- return -EINVAL;
- }
-
- if (conf->data_size && conf->data) {
- if (conf->data_size > 128000) {
- printk(KERN_INFO
- "%s: ERROR, Invalid firmware data size %i !\n",
- wandev->name, conf->data_size);
- kfree(conf);
- return -EINVAL;
- }
-
- data = vmalloc(conf->data_size);
- if (!data) {
- printk(KERN_INFO
- "%s: ERROR, Failed allocate kernel memory !\n",
- wandev->name);
- kfree(conf);
- return -ENOBUFS;
- }
- if (!copy_from_user(data, conf->data, conf->data_size)) {
- conf->data = data;
- err = wandev->setup(wandev, conf);
- } else {
- printk(KERN_INFO
- "%s: ERROR, Failed to copy from user data !\n",
- wandev->name);
- err = -EFAULT;
- }
- vfree(data);
- } else {
- printk(KERN_INFO
- "%s: ERROR, No firmware found ! Firmware size = %i !\n",
- wandev->name, conf->data_size);
- }
-
- kfree(conf);
- return err;
-}
-
-/*
- * Shutdown WAN device.
- * o delete all not opened logical channels for this device
- * o call driver's shutdown() entry point
- */
-
-static int wanrouter_device_shutdown(struct wan_device *wandev)
-{
- struct net_device *dev;
- int err=0;
-
- if (wandev->state == WAN_UNCONFIGURED)
- return 0;
-
- printk(KERN_INFO "\n%s: Shutting Down!\n",wandev->name);
-
- for (dev = wandev->dev; dev;) {
- err = wanrouter_delete_interface(wandev, dev->name);
- if (err)
- return err;
- /* The above function deallocates the current dev
- * structure. Therefore, we cannot use netdev_priv(dev)
- * as the next element: wandev->dev points to the
- * next element */
- dev = wandev->dev;
- }
-
- if (wandev->ndev)
- return -EBUSY; /* there are opened interfaces */
-
- if (wandev->shutdown)
- err=wandev->shutdown(wandev);
-
- return err;
-}
-
-/*
- * Get WAN device status & statistics.
- */
-
-static int wanrouter_device_stat(struct wan_device *wandev,
- wandev_stat_t __user *u_stat)
-{
- wandev_stat_t stat;
-
- memset(&stat, 0, sizeof(stat));
-
- /* Ask device driver to update device statistics */
- if ((wandev->state != WAN_UNCONFIGURED) && wandev->update)
- wandev->update(wandev);
-
- /* Fill out structure */
- stat.ndev = wandev->ndev;
- stat.state = wandev->state;
-
- if (copy_to_user(u_stat, &stat, sizeof(stat)))
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * Create new WAN interface.
- * o verify user address space
- * o copy configuration data to kernel address space
- * o allocate network interface data space
- * o call driver's new_if() entry point
- * o make sure there is no interface name conflict
- * o register network interface
- */
-
-static int wanrouter_device_new_if(struct wan_device *wandev,
- wanif_conf_t __user *u_conf)
-{
- wanif_conf_t *cnf;
- struct net_device *dev = NULL;
- int err;
-
- if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))
- return -ENODEV;
-
- cnf = kmalloc(sizeof(wanif_conf_t), GFP_KERNEL);
- if (!cnf)
- return -ENOBUFS;
-
- err = -EFAULT;
- if (copy_from_user(cnf, u_conf, sizeof(wanif_conf_t)))
- goto out;
-
- err = -EINVAL;
- if (cnf->magic != ROUTER_MAGIC)
- goto out;
-
- if (cnf->config_id == WANCONFIG_MPPP) {
- printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!\n",
- wandev->name);
- err = -EPROTONOSUPPORT;
- goto out;
- } else {
- err = wandev->new_if(wandev, dev, cnf);
- }
-
- if (!err) {
- /* Register network interface. This will invoke init()
- * function supplied by the driver. If device registered
- * successfully, add it to the interface list.
- */
-
-#ifdef WANDEBUG
- printk(KERN_INFO "%s: registering interface %s...\n",
- wanrouter_modname, dev->name);
-#endif
-
- err = register_netdev(dev);
- if (!err) {
- struct net_device *slave = NULL;
- unsigned long smp_flags=0;
-
- lock_adapter_irq(&wandev->lock, &smp_flags);
-
- if (wandev->dev == NULL) {
- wandev->dev = dev;
- } else {
- for (slave=wandev->dev;
- DEV_TO_SLAVE(slave);
- slave = DEV_TO_SLAVE(slave))
- DEV_TO_SLAVE(slave) = dev;
- }
- ++wandev->ndev;
-
- unlock_adapter_irq(&wandev->lock, &smp_flags);
- err = 0; /* done !!! */
- goto out;
- }
- if (wandev->del_if)
- wandev->del_if(wandev, dev);
- free_netdev(dev);
- }
-
-out:
- kfree(cnf);
- return err;
-}
-
-
-/*
- * Delete WAN logical channel.
- * o verify user address space
- * o copy configuration data to kernel address space
- */
-
-static int wanrouter_device_del_if(struct wan_device *wandev, char __user *u_name)
-{
- char name[WAN_IFNAME_SZ + 1];
- int err = 0;
-
- if (wandev->state == WAN_UNCONFIGURED)
- return -ENODEV;
-
- memset(name, 0, sizeof(name));
-
- if (copy_from_user(name, u_name, WAN_IFNAME_SZ))
- return -EFAULT;
-
- err = wanrouter_delete_interface(wandev, name);
- if (err)
- return err;
-
- /* If last interface being deleted, shutdown card
- * This helps with administration at leaf nodes
- * (You can tell if the person at the other end of the phone
- * has an interface configured) and avoids DoS vulnerabilities
- * in binary driver files - this fixes a problem with the current
- * Sangoma driver going into strange states when all the network
- * interfaces are deleted and the link irrecoverably disconnected.
- */
-
- if (!wandev->ndev && wandev->shutdown)
- err = wandev->shutdown(wandev);
-
- return err;
-}
-
-/*
- * Miscellaneous Functions
- */
-
-/*
- * Find WAN device by name.
- * Return pointer to the WAN device data space or NULL if device not found.
- */
-
-static struct wan_device *wanrouter_find_device(char *name)
-{
- struct wan_device *wandev;
-
- for (wandev = wanrouter_router_devlist;
- wandev && strcmp(wandev->name, name);
- wandev = wandev->next);
- return wandev;
-}
-
-/*
- * Delete WAN logical channel identified by its name.
- * o find logical channel by its name
- * o call driver's del_if() entry point
- * o unregister network interface
- * o unlink channel data space from linked list of channels
- * o release channel data space
- *
- * Return: 0 success
- * -ENODEV channel not found.
- * -EBUSY interface is open
- *
- * Note: If (force != 0), then device will be destroyed even if interface
- * associated with it is open. It's caller's responsibility to make
- * sure that opened interfaces are not removed!
- */
-
-static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
-{
- struct net_device *dev = NULL, *prev = NULL;
- unsigned long smp_flags=0;
-
- lock_adapter_irq(&wandev->lock, &smp_flags);
- dev = wandev->dev;
- prev = NULL;
- while (dev && strcmp(name, dev->name)) {
- struct net_device **slave = netdev_priv(dev);
- prev = dev;
- dev = *slave;
- }
- unlock_adapter_irq(&wandev->lock, &smp_flags);
-
- if (dev == NULL)
- return -ENODEV; /* interface not found */
-
- if (netif_running(dev))
- return -EBUSY; /* interface in use */
-
- if (wandev->del_if)
- wandev->del_if(wandev, dev);
-
- lock_adapter_irq(&wandev->lock, &smp_flags);
- if (prev) {
- struct net_device **prev_slave = netdev_priv(prev);
- struct net_device **slave = netdev_priv(dev);
-
- *prev_slave = *slave;
- } else {
- struct net_device **slave = netdev_priv(dev);
- wandev->dev = *slave;
- }
- --wandev->ndev;
- unlock_adapter_irq(&wandev->lock, &smp_flags);
-
- printk(KERN_INFO "%s: unregistering '%s'\n", wandev->name, dev->name);
-
- unregister_netdev(dev);
-
- free_netdev(dev);
-
- return 0;
-}
-
-static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
- __acquires(lock)
-{
- spin_lock_irqsave(lock, *smp_flags);
-}
-
-
-static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
- __releases(lock)
-{
- spin_unlock_irqrestore(lock, *smp_flags);
-}
-
-EXPORT_SYMBOL(register_wan_device);
-EXPORT_SYMBOL(unregister_wan_device);
-
-MODULE_LICENSE("GPL");
-
-/*
- * End
- */
diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
deleted file mode 100644
index c43612e..0000000
--- a/net/wanrouter/wanproc.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*****************************************************************************
-* wanproc.c WAN Router Module. /proc filesystem interface.
-*
-* This module is completely hardware-independent and provides
-* access to the router using Linux /proc filesystem.
-*
-* Author: Gideon Hack
-*
-* Copyright: (c) 1995-1999 Sangoma Technologies Inc.
-*
-* 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.
-* ============================================================================
-* Jun 02, 1999 Gideon Hack Updates for Linux 2.2.X kernels.
-* Jun 29, 1997 Alan Cox Merged with 1.0.3 vendor code
-* Jan 29, 1997 Gene Kozin v1.0.1. Implemented /proc read routines
-* Jan 30, 1997 Alan Cox Hacked around for 2.1
-* Dec 13, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
-*****************************************************************************/
-
-#include <linux/init.h> /* __initfunc et al. */
-#include <linux/stddef.h> /* offsetof(), etc. */
-#include <linux/errno.h> /* return codes */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/wanrouter.h> /* WAN router API definitions */
-#include <linux/seq_file.h>
-#include <linux/mutex.h>
-
-#include <net/net_namespace.h>
-#include <asm/io.h>
-
-#define PROC_STATS_FORMAT "%30s: %12lu\n"
-
-/****** Defines and Macros **************************************************/
-
-#define PROT_DECODE(prot) ((prot == WANCONFIG_FR) ? " FR" :\
- (prot == WANCONFIG_X25) ? " X25" : \
- (prot == WANCONFIG_PPP) ? " PPP" : \
- (prot == WANCONFIG_CHDLC) ? " CHDLC": \
- (prot == WANCONFIG_MPPP) ? " MPPP" : \
- " Unknown" )
-
-/****** Function Prototypes *************************************************/
-
-#ifdef CONFIG_PROC_FS
-
-/* Miscellaneous */
-
-/*
- * Structures for interfacing with the /proc filesystem.
- * Router creates its own directory /proc/net/router with the following
- * entries:
- * config device configuration
- * status global device statistics
- * <device> entry for each WAN device
- */
-
-/*
- * Generic /proc/net/router/<file> file and inode operations
- */
-
-/*
- * /proc/net/router
- */
-
-static DEFINE_MUTEX(config_mutex);
-static struct proc_dir_entry *proc_router;
-
-/* Strings */
-
-/*
- * Interface functions
- */
-
-/****** Proc filesystem entry points ****************************************/
-
-/*
- * Iterator
- */
-static void *r_start(struct seq_file *m, loff_t *pos)
-{
- struct wan_device *wandev;
- loff_t l = *pos;
-
- mutex_lock(&config_mutex);
- if (!l--)
- return SEQ_START_TOKEN;
- for (wandev = wanrouter_router_devlist; l-- && wandev;
- wandev = wandev->next)
- ;
- return wandev;
-}
-
-static void *r_next(struct seq_file *m, void *v, loff_t *pos)
-{
- struct wan_device *wandev = v;
- (*pos)++;
- return (v == SEQ_START_TOKEN) ? wanrouter_router_devlist : wandev->next;
-}
-
-static void r_stop(struct seq_file *m, void *v)
-{
- mutex_unlock(&config_mutex);
-}
-
-static int config_show(struct seq_file *m, void *v)
-{
- struct wan_device *p = v;
- if (v == SEQ_START_TOKEN) {
- seq_puts(m, "Device name | port |IRQ|DMA| mem.addr |"
- "mem.size|option1|option2|option3|option4\n");
- return 0;
- }
- if (!p->state)
- return 0;
- seq_printf(m, "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
- p->name, p->ioport, p->irq, p->dma, p->maddr, p->msize,
- p->hw_opt[0], p->hw_opt[1], p->hw_opt[2], p->hw_opt[3]);
- return 0;
-}
-
-static int status_show(struct seq_file *m, void *v)
-{
- struct wan_device *p = v;
- if (v == SEQ_START_TOKEN) {
- seq_puts(m, "Device name |protocol|station|interface|"
- "clocking|baud rate| MTU |ndev|link state\n");
- return 0;
- }
- if (!p->state)
- return 0;
- seq_printf(m, "%-15s|%-8s| %-7s| %-9s|%-8s|%9u|%5u|%3u |",
- p->name,
- PROT_DECODE(p->config_id),
- p->config_id == WANCONFIG_FR ?
- (p->station ? "Node" : "CPE") :
- (p->config_id == WANCONFIG_X25 ?
- (p->station ? "DCE" : "DTE") :
- ("N/A")),
- p->interface ? "V.35" : "RS-232",
- p->clocking ? "internal" : "external",
- p->bps,
- p->mtu,
- p->ndev);
-
- switch (p->state) {
- case WAN_UNCONFIGURED:
- seq_printf(m, "%-12s\n", "unconfigured");
- break;
- case WAN_DISCONNECTED:
- seq_printf(m, "%-12s\n", "disconnected");
- break;
- case WAN_CONNECTING:
- seq_printf(m, "%-12s\n", "connecting");
- break;
- case WAN_CONNECTED:
- seq_printf(m, "%-12s\n", "connected");
- break;
- default:
- seq_printf(m, "%-12s\n", "invalid");
- break;
- }
- return 0;
-}
-
-static const struct seq_operations config_op = {
- .start = r_start,
- .next = r_next,
- .stop = r_stop,
- .show = config_show,
-};
-
-static const struct seq_operations status_op = {
- .start = r_start,
- .next = r_next,
- .stop = r_stop,
- .show = status_show,
-};
-
-static int config_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &config_op);
-}
-
-static int status_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &status_op);
-}
-
-static const struct file_operations config_fops = {
- .owner = THIS_MODULE,
- .open = config_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static const struct file_operations status_fops = {
- .owner = THIS_MODULE,
- .open = status_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static int wandev_show(struct seq_file *m, void *v)
-{
- struct wan_device *wandev = m->private;
-
- if (wandev->magic != ROUTER_MAGIC)
- return 0;
-
- if (!wandev->state) {
- seq_puts(m, "device is not configured!\n");
- return 0;
- }
-
- /* Update device statistics */
- if (wandev->update) {
- int err = wandev->update(wandev);
- if (err == -EAGAIN) {
- seq_puts(m, "Device is busy!\n");
- return 0;
- }
- if (err) {
- seq_puts(m, "Device is not configured!\n");
- return 0;
- }
- }
-
- seq_printf(m, PROC_STATS_FORMAT,
- "total packets received", wandev->stats.rx_packets);
- seq_printf(m, PROC_STATS_FORMAT,
- "total packets transmitted", wandev->stats.tx_packets);
- seq_printf(m, PROC_STATS_FORMAT,
- "total bytes received", wandev->stats.rx_bytes);
- seq_printf(m, PROC_STATS_FORMAT,
- "total bytes transmitted", wandev->stats.tx_bytes);
- seq_printf(m, PROC_STATS_FORMAT,
- "bad packets received", wandev->stats.rx_errors);
- seq_printf(m, PROC_STATS_FORMAT,
- "packet transmit problems", wandev->stats.tx_errors);
- seq_printf(m, PROC_STATS_FORMAT,
- "received frames dropped", wandev->stats.rx_dropped);
- seq_printf(m, PROC_STATS_FORMAT,
- "transmit frames dropped", wandev->stats.tx_dropped);
- seq_printf(m, PROC_STATS_FORMAT,
- "multicast packets received", wandev->stats.multicast);
- seq_printf(m, PROC_STATS_FORMAT,
- "transmit collisions", wandev->stats.collisions);
- seq_printf(m, PROC_STATS_FORMAT,
- "receive length errors", wandev->stats.rx_length_errors);
- seq_printf(m, PROC_STATS_FORMAT,
- "receiver overrun errors", wandev->stats.rx_over_errors);
- seq_printf(m, PROC_STATS_FORMAT,
- "CRC errors", wandev->stats.rx_crc_errors);
- seq_printf(m, PROC_STATS_FORMAT,
- "frame format errors (aborts)", wandev->stats.rx_frame_errors);
- seq_printf(m, PROC_STATS_FORMAT,
- "receiver fifo overrun", wandev->stats.rx_fifo_errors);
- seq_printf(m, PROC_STATS_FORMAT,
- "receiver missed packet", wandev->stats.rx_missed_errors);
- seq_printf(m, PROC_STATS_FORMAT,
- "aborted frames transmitted", wandev->stats.tx_aborted_errors);
- return 0;
-}
-
-static int wandev_open(struct inode *inode, struct file *file)
-{
- return single_open(file, wandev_show, PDE(inode)->data);
-}
-
-static const struct file_operations wandev_fops = {
- .owner = THIS_MODULE,
- .open = wandev_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .unlocked_ioctl = wanrouter_ioctl,
-};
-
-/*
- * Initialize router proc interface.
- */
-
-int __init wanrouter_proc_init(void)
-{
- struct proc_dir_entry *p;
- proc_router = proc_mkdir(ROUTER_NAME, init_net.proc_net);
- if (!proc_router)
- goto fail;
-
- p = proc_create("config", S_IRUGO, proc_router, &config_fops);
- if (!p)
- goto fail_config;
- p = proc_create("status", S_IRUGO, proc_router, &status_fops);
- if (!p)
- goto fail_stat;
- return 0;
-fail_stat:
- remove_proc_entry("config", proc_router);
-fail_config:
- remove_proc_entry(ROUTER_NAME, init_net.proc_net);
-fail:
- return -ENOMEM;
-}
-
-/*
- * Clean up router proc interface.
- */
-
-void wanrouter_proc_cleanup(void)
-{
- remove_proc_entry("config", proc_router);
- remove_proc_entry("status", proc_router);
- remove_proc_entry(ROUTER_NAME, init_net.proc_net);
-}
-
-/*
- * Add directory entry for WAN device.
- */
-
-int wanrouter_proc_add(struct wan_device* wandev)
-{
- if (wandev->magic != ROUTER_MAGIC)
- return -EINVAL;
-
- wandev->dent = proc_create(wandev->name, S_IRUGO,
- proc_router, &wandev_fops);
- if (!wandev->dent)
- return -ENOMEM;
- wandev->dent->data = wandev;
- return 0;
-}
-
-/*
- * Delete directory entry for WAN device.
- */
-int wanrouter_proc_delete(struct wan_device* wandev)
-{
- if (wandev->magic != ROUTER_MAGIC)
- return -EINVAL;
- remove_proc_entry(wandev->name, proc_router);
- return 0;
-}
-
-#else
-
-/*
- * No /proc - output stubs
- */
-
-int __init wanrouter_proc_init(void)
-{
- return 0;
-}
-
-void wanrouter_proc_cleanup(void)
-{
-}
-
-int wanrouter_proc_add(struct wan_device *wandev)
-{
- return 0;
-}
-
-int wanrouter_proc_delete(struct wan_device *wandev)
-{
- return 0;
-}
-
-#endif
-
-/*
- * End
- */
-
--
1.7.8.112.g3fd21
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox