[l4ankh] Problems with fixed l4ankh
Timur <[email protected]>
| Newsgroups | gmane.comp.micro-kernel.l4.devel |
|---|---|
| Message-ID | <2015976.KVR3p8udXT@timmy-laptop> |
Hi! I had fixed the l4ankh driver and after that it started to work properly. Now only thread is used to receive packets. In lines 158-162 we clear the rcv buffer: that is necessary to be done as after opening a session we start to receive packets that should not be served; otherwise the response time will be quite slow. This is not the best solution, but I do not have time to make it better. Now I face the following problem: the driver in ankh (I use 8139cp) stops receiving packets after some time (for me it is usually 3-4 minutes). This situation occurs when the interrupt handler was called and the device register IntrStatus already equals "zero". An interrupt doesn't work after that. -- Galiullin Timur _______________________________________________ l4-hackers mailing list [email protected] http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers
patch_l4ankh
(text/x-patch, 4 KB)
--- l4re-snapshot-2011081207/src/l4linux/drivers/net/l4ankh.c 2011-08-12 09:20:35.000000000 +0400
+++ new/l4re-snapshot-2011081207/src/l4linux/drivers/net/l4ankh.c 2012-05-22 15:27:23.150321060 +0400
@@ -21,6 +21,9 @@
#include <l4/ankh/client-c.h>
#include <l4/ankh/session.h>
#include <l4/log/log.h>
+#include <l4/shmc/ringbuf.h>
+#include <l4/shmc/shmc.h>
+#include <l4/shmc/types.h>
MODULE_AUTHOR("Matthias Lange <[email protected]>, Adam Lackorzynski <[email protected]>");
MODULE_DESCRIPTION("L4ankh stub driver");
@@ -45,6 +48,9 @@
L4_EXTERNAL_FUNC(l4ankh_prepare_send);
L4_EXTERNAL_FUNC(l4ankh_recv_blocking);
L4_EXTERNAL_FUNC(l4ankh_prepare_recv);
+L4_EXTERNAL_FUNC(l4ankh_get_recvbuf);
+L4_EXTERNAL_FUNC(l4ankh_get_sendbuf);
+L4_EXTERNAL_FUNC(l4shmc_rb_receiver_read_next_size);
struct l4x_net_priv {
struct net_device_stats net_stats;
@@ -87,12 +93,8 @@
printk("L4net: %s\n", __func__);
}
-/*
- * Interrupt.
- */
-static irqreturn_t l4x_net_interrupt(int irq, void *dev_id)
+static void l4x_net_recv(struct net_device *netdev)
{
- struct net_device *netdev = dev_id;
struct l4x_net_priv *priv = netdev_priv(netdev);
struct sk_buff *skb;
@@ -114,7 +116,6 @@
priv->net_stats.rx_dropped++;
}
- return IRQ_HANDLED;
}
static unsigned int l4x_net_irq_startup(struct irq_data *data)
@@ -150,10 +151,15 @@
l4x_prepare_irq_thread(ctx, 0);
- res = l4ankh_prepare_recv(L4RE_THIS_TASK_CAP);
+ res = l4ankh_prepare_recv(l4lx_thread_get_cap(priv->irq_thread));
if (res)
printk("l4ankh_prepare_recv failed with %d\n", res);
+ l4shmc_ringbuf_head_t* rb_head = L4SHMC_RINGBUF_HEAD(l4ankh_get_recvbuf());
+ rb_head->next_read=0;
+ rb_head->next_write=0;
+ rb_head->bytes_filled = 0;
+ rb_head->sender_waits = 0;
while (1) {
size = 16384;
l4ankh_recv_blocking(_recv_buf, &size);
@@ -161,7 +167,7 @@
priv->pkt_size = size;
- l4x_do_IRQ(netdev->irq, ctx);
+ l4x_net_recv(netdev);
}
}
@@ -186,14 +192,6 @@
goto err_out_close;
}
- if ((err = request_irq(netdev->irq, l4x_net_interrupt,
- IRQF_SAMPLE_RANDOM | IRQF_SHARED,
- netdev->name, netdev))) {
- printk("[L4Ankh] %s: request_irq(%d, ...) failed: %d\n",
- netdev->name, netdev->irq, err);
- goto err_out_kfree;
- }
-
priv->irq_thread = l4lx_thread_create(l4x_ankh_irq_thread,
0, NULL, &netdev, sizeof(netdev),
CONFIG_L4_PRIO_L4ANKH,
@@ -223,7 +221,6 @@
static int l4x_net_close(struct net_device *netdev)
{
struct l4x_net_priv *priv = netdev_priv(netdev);
- free_irq(netdev->irq, netdev);
netif_stop_queue(netdev);
netif_carrier_off(netdev);
kfree(priv->pkt_buffer);
@@ -251,12 +248,32 @@
return 0;
}
+#if 0
+static int l4x_net_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct AnkhSessionDescriptor *session;
+ session = l4ankh_get_info();
+ struct sockaddr *mac_addr = addr;
+
+ if (!is_valid_ether_addr(mac_addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
+ memcpy((void *)session->mac, mac_addr->sa_data, sizeof(session->mac));
+ printk("MAC changed!\n");
+}
+#endif
+
+
static const struct net_device_ops l4xnet_netdev_ops = {
.ndo_open = l4x_net_open,
.ndo_stop = l4x_net_close,
.ndo_start_xmit = l4x_net_xmit_frame,
.ndo_get_stats = l4x_net_get_stats,
.ndo_tx_timeout = l4x_net_tx_timeout,
+#if 0
+ .ndo_set_mac_address = l4x_net_set_mac_address,
+#endif
};
/* Initialize one virtual interface. */
@@ -298,16 +315,6 @@
dev->netdev_ops = &l4xnet_netdev_ops;
priv = netdev_priv(dev);
- priv->rx_sig = L4_INVALID_CAP;
-
- if (l4_is_invalid_cap(priv->rx_sig = l4x_cap_alloc()))
- return -1;
-
- if ((dev->irq = l4x_register_irq(priv->rx_sig)) < 0) {
- printk(KERN_INFO "[L4Ankh] Failed to get signal irq\n");
- goto err_out_free_dev;
- }
-
if ((err = register_netdev(dev))) {
printk("[L4Ankh] Cannot register net device, aborting.\n");
goto err_out_free_dev;