summaryrefslogtreecommitdiff
path: root/libdde_linux26/lib
diff options
context:
space:
mode:
Diffstat (limited to 'libdde_linux26/lib')
-rw-r--r--libdde_linux26/lib/src/Makefile1
-rw-r--r--libdde_linux26/lib/src/arch/l4/mach_glue.c85
-rw-r--r--libdde_linux26/lib/src/net/core/skbuff.c11
3 files changed, 97 insertions, 0 deletions
diff --git a/libdde_linux26/lib/src/Makefile b/libdde_linux26/lib/src/Makefile
index b6670ed5..d06a8d6b 100644
--- a/libdde_linux26/lib/src/Makefile
+++ b/libdde_linux26/lib/src/Makefile
@@ -150,6 +150,7 @@ SRC_C_libdde_linux26.o.a += \
##################################################################
SRC_C_libdde_linux26_net.a += \
arch/l4/net.c \
+ arch/l4/mach_glue.c \
drivers/net/mii.c \
net/core/dev.c \
net/core/dev_mcast.c \
diff --git a/libdde_linux26/lib/src/arch/l4/mach_glue.c b/libdde_linux26/lib/src/arch/l4/mach_glue.c
new file mode 100644
index 00000000..9130c550
--- /dev/null
+++ b/libdde_linux26/lib/src/arch/l4/mach_glue.c
@@ -0,0 +1,85 @@
+#include <linux/netdevice.h>
+#include <linux/if.h>
+
+#define D_INVALID_SIZE 2507
+#define D_NO_MEMORY 2508
+
+/* List of sk_buffs waiting to be freed. */
+static struct sk_buff_head skb_done_list;
+
+struct net_device *search_netdev (char *name)
+{
+ struct net_device *dev;
+ struct net *net;
+
+ read_lock(&dev_base_lock);
+ for_each_net(net) {
+ for_each_netdev(net, dev) {
+ if (!strcmp (name, dev->name)
+ && dev->base_addr && dev->base_addr != 0xffe0)
+ goto end;
+ }
+ }
+end:
+ read_unlock(&dev_base_lock);
+ return dev;
+}
+
+int linux_pkg_xmit (char *pkg_data, int len, void *del_data,
+ int (*del_func) (struct sk_buff *, void *),
+ struct net_device *dev)
+{
+ struct sk_buff *skb;
+
+ if (len == 0 || len > dev->mtu + dev->hard_header_len)
+ return D_INVALID_SIZE;
+
+ /* Allocate a sk_buff. */
+ skb = dev_alloc_skb (len);
+ if (!skb)
+ return D_NO_MEMORY;
+
+ skb->del_data = del_data;
+ skb->pre_del_func = del_func;
+
+ /* Copy user data. This is only required if it spans multiple pages. */
+ skb->len = len;
+ skb->tail = skb->data + len;
+ skb->end = skb->tail;
+
+ memcpy (skb->data, pkg_data, len);
+
+ skb->dev = dev;
+
+ return dev->netdev_ops->ndo_start_xmit(skb, dev);
+}
+
+char *netdev_addr(struct net_device *dev)
+{
+ return dev->dev_addr;
+}
+
+int netdev_flags(struct net_device *dev)
+{
+ return dev->flags;
+}
+
+void *skb_reply(struct sk_buff *skb)
+{
+ return skb->del_data;
+}
+
+void skb_done_head_init()
+{
+ skb_queue_head_init (&skb_done_list);
+}
+
+struct sk_buff *skb_done_dequeue()
+{
+ return skb_dequeue (&skb_done_list);
+}
+
+void skb_done_queue(struct sk_buff *skb)
+{
+ skb_queue_tail (&skb_done_list, skb);
+}
diff --git a/libdde_linux26/lib/src/net/core/skbuff.c b/libdde_linux26/lib/src/net/core/skbuff.c
index 59b275b0..853b535b 100644
--- a/libdde_linux26/lib/src/net/core/skbuff.c
+++ b/libdde_linux26/lib/src/net/core/skbuff.c
@@ -421,6 +421,11 @@ static void skb_release_all(struct sk_buff *skb)
void __kfree_skb(struct sk_buff *skb)
{
+#ifdef DDE_LINUX
+ if (skb->del_data && skb->pre_del_func
+ && skb->pre_del_func(skb, skb->del_data))
+ return;
+#endif
skb_release_all(skb);
kfree_skbmem(skb);
}
@@ -436,6 +441,12 @@ void kfree_skb(struct sk_buff *skb)
{
if (unlikely(!skb))
return;
+#ifdef DDE_LINUX
+ if (atomic_read(&skb->users) == 0) {
+ __kfree_skb(skb);
+ return;
+ }
+#endif
if (likely(atomic_read(&skb->users) == 1))
smp_rmb();
else if (likely(!atomic_dec_and_test(&skb->users)))