Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: dvb-bt8xx and net device



Hi,

can you please try again and report if this oops is fixed?
The oops that appears when trying to bring the network device up can be fixed by manually setting the mac address in the dvb_net code. Until now I couln't find any other solution. The latest CVS version still shows this error.
I didn't have much time before so I couldn't try many things out. With my "hacked" version I get the network device working but only to a certain point. If the promisc mode isn't enabled, the system runs normally for many hours without crashing. But when I enable promisc mode and check the data packets with tcpdump/iptraf I get a serious kernel oops that makes the system hang completely. The keyboard/mouse doesn't react on anything.
As I don't have a possibility to setup a serial console at the moment, I had to get infos using another way. I logged into the system using ssh and saved dmesg output after testing the net device. I added also some dprintk in most important dvb_net functions.

dvbtune -f 10773250 -s 22000 -p H -n 251
ifconfig -a dvb0_0
ifconfig dvb0_0 10.0.1.1

>>>>
DVB: registering new adapter (Pinnacle PCTV DVB-S).
DVB: registering frontend 0:0 (Conexant CX24110 with CX24108 tuner, aka HM1221/HM1811)...
dvb_net_init: registring net-device.
bttv0: IRQ lockup, cleared int mask
dvb_net_ioctl: cmd=-1073451212, arg=-1073742548.
dvb_net_do_ioctl: cmd=NET_ADD_IF
get_if: i = 0
get_if: set state to 1 of if[0]
dvb_net_add_if: opening network @ pid 251
dvb_net_init_dev: init net device.
dvb_net_get_stats
dvb_net_add_if: network registered dvb0_0 @ pid 251
dvb_net_get_stats
dvb_net_open: priv->in_use = 1
dvb_net_feed_start
dvb_net_feed_start: rx_mode 0
dvb_net_feed_start: alloc secfeed
dvb_net_feed_start: set secfilter
dvb_net_filter_set
dvb0_0: filter mac=30 8d 00 03 30 00
dvb0_0: filter mask=ff ff ff ff ff ff
dvb_net_feed_start: start filtering
dvb_net_set_multicast_list
dvb_net_get_stats
dvb_net_set_multicast_list
dvb_net_set_multicast_list
dvb_net_get_stats
tq_set_mutlicast_list
dvb_net_feed_stop
dvb_net_feed_stop
dvb_net_feed_stop: stop secfeed
dvb_net_feed_stop: release secfilter
dvb0_0: set_mc_list, 1 entries
dvb_set_mc_filter
dvb_net_feed_start
dvb_net_feed_start: rx_mode 1
dvb_net_feed_start: alloc secfeed
dvb_net_feed_start: set secfilter
dvb_net_filter_set
dvb0_0: filter mac=30 8d 00 03 30 00
dvb0_0: filter mask=ff ff ff ff ff ff
dvb_net_feed_start: set multi_secfilter[0]
dvb_net_filter_set
dvb0_0: filter mac=01 00 5e 00 00 01
dvb0_0: filter mask=ff ff ff ff ff ff
dvb_net_feed_start: start filtering
<<<<

After first tcpdump -ni dvb0_0
>>>>
......
dvb_net_callback
dvb_net_sec
dvb_net_eth_type_trans
dvb_net_sec: packet processed - netif_rx() follows
dvb_net_callback
dvb_net_sec
dvb_net_eth_type_trans
dvb_net_sec: packet processed - netif_rx() follows
dvb_net_set_multicast_list
dvb_net_set_multicast_list
device dvb0_0 left promiscuous mode
dvb_net_get_stats
tq_set_mutlicast_list
dvb_net_feed_stop
dvb_net_feed_stop
dvb_net_feed_stop: stop secfeed
dvb_net_feed_stop: release secfilter
dvb0_0: set_mc_list, 1 entries
dvb_set_mc_filter
dvb_net_feed_start
dvb_net_feed_start: rx_mode 1
dvb_net_feed_start: alloc secfeed
dvb_net_feed_start: set secfilter
dvb_net_filter_set
dvb0_0: filter mac=30 8d 00 03 30 00
dvb0_0: filter mask=ff ff ff ff ff ff
dvb_net_feed_start: set multi_secfilter[0]
dvb_net_filter_set
dvb0_0: filter mac=01 00 5e 00 00 01
dvb0_0: filter mask=ff ff ff ff ff ff
dvb_net_feed_start: start filtering
<<<<<<

After some time I get that kernel oops (while running tcpdump). I get a trace too but unfortunately I didn't see a solution to save it. The last functions following my dprintk's are:
dvb_net_eth_type_trans
dvb_net_sec: packet processed netif_rx() follows

Here's the panic message:
<0> Kernel panic: Aiee, killing interrupt handler..

Perhaps you know a way to save the kernel trace output without setting up a serial console. Anyway it seems to be a problem with irq handler. I will also try to follow the approach you wrote about in your last mail.

Thanks again,
-André.

--
http://www.steinsoft.net
cout << "Happy Coding!" << endl;
--- dvb_net.c.old	2003-06-24 18:39:01.000000000 +0200
+++ dvb_net.c	2003-06-27 01:23:30.000000000 +0200
@@ -75,6 +75,8 @@
 	struct ethhdr *eth;
 	unsigned char *rawp;
 
+	dprintk("dvb_net_eth_type_trans\n");
+
 	skb->mac.raw = skb->data;
 	skb_pull(skb, dev->hard_header_len);
 	eth = skb->mac.ethernet;
@@ -112,6 +114,8 @@
 	u8 *eth;
 	struct sk_buff *skb;
 
+	dprintk("dvb_net_sec\n");
+
 	/* note: pkt_len includes a 32bit checksum */
 	if (pkt_len < 16) {
 		printk("%s: IP/MPE packet length = %d too small.\n",
@@ -168,6 +172,8 @@
 
 	skb->protocol = dvb_net_eth_type_trans(skb, dev);
 
+	dprintk("dvb_net_sec: packet processed - netif_rx() follows\n");
+
 	((struct dvb_net_priv *) dev->priv)->stats.rx_packets++;
 	((struct dvb_net_priv *) dev->priv)->stats.rx_bytes += skb->len;
 	netif_rx(skb);
@@ -180,6 +186,8 @@
 {
 	struct net_device *dev=(struct net_device *) filter->priv;
 
+
+	dprintk("dvb_net_callback\n");
 	/**
 	 * we rely on the DVB API definition where exactly one complete
 	 * section is delivered in buffer1
@@ -207,6 +215,8 @@
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 	int ret;
 
+	dprintk("dvb_net_filter_set\n");
+
 	*secfilter=0;
 
 	ret = priv->secfeed->allocate_filter(priv->secfeed, secfilter);
@@ -254,6 +264,8 @@
 	struct dmx_demux *demux = priv->demux;
 	unsigned char *mac = (unsigned char *) dev->dev_addr;
 
+	dprintk("dvb_net_feed_start\n");
+
 	dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
 	if (priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
 		printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
@@ -315,6 +327,8 @@
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 	int i;
 
+	dprintk("dvb_net_feed_stop\n");
+
 	dprintk("%s\n", __FUNCTION__);
 	if (priv->secfeed) {
 		if (priv->secfeed->is_filtering) {
@@ -349,6 +363,8 @@
 {
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 
+	dprintk("dvb_set_mc_filter\n");
+
 	if (priv->multi_num == DVB_NET_MULTICAST_MAX)
 		return -ENOMEM;
 
@@ -364,6 +380,8 @@
 	struct net_device *dev = data;
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 
+	dprintk("tq_set_mutlicast_list\n");
+
 	dvb_net_feed_stop(dev);
 
 	priv->rx_mode = RX_MODE_UNI;
@@ -398,12 +416,15 @@
 static void dvb_net_set_multicast_list (struct net_device *dev)
 {
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+
+	dprintk("dvb_net_set_multicast_list\n");
 	schedule_work(&priv->wq);
 }
 
 
 static int dvb_net_set_config (struct net_device *dev, struct ifmap *map)
 {
+	dprintk("dvb_net_set_config\n");
 	if (netif_running(dev))
 		return -EBUSY;
 	return 0;
@@ -414,6 +435,8 @@
 {
 	struct sockaddr *addr=p;
 
+	dprintk("dvb_net_sec_mac: dev->addr_len=%d\n", dev->addr_len);
+
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
 	if (netif_running(dev)) {
@@ -430,6 +453,7 @@
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 
 	priv->in_use++;
+	dprintk("dvb_net_open: priv->in_use = %d\n", priv->in_use);
 	dvb_net_feed_start(dev);
 	return 0;
 }
@@ -439,7 +463,9 @@
 {
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 
+
 	priv->in_use--;
+	dprintk("dvb_net_stop: priv->in_use = %d\n", priv->in_use);
 	dvb_net_feed_stop(dev);
 	return 0;
 }
@@ -447,12 +473,14 @@
 
 static struct net_device_stats* dvb_net_get_stats (struct net_device *dev)
 {
+	dprintk("dvb_net_get_stats\n");
 	return &((struct dvb_net_priv*) dev->priv)->stats;
 }
 
 
 static int dvb_net_init_dev (struct net_device *dev)
 {
+	dprintk("dvb_net_init_dev: init net device.\n");
 	ether_setup(dev);
 
 	dev->open		= dvb_net_open;
@@ -480,9 +508,13 @@
 		if (!dvbnet->state[i])
 			break;
 
+	dprintk("get_if: i = %d\n", i);
+
 	if (i == DVB_NET_DEVICES_MAX)
 		return -1;
 
+	dprintk("get_if: set state to 1 of if[%d]\n", i);
+
 	dvbnet->state[i] = 1;
 	return i;
 }
@@ -495,13 +527,18 @@
 	struct dvb_net_priv *priv;
 	int result;
 	int if_num;
+	unsigned char mac[] = { 0x30, 0x8D, 0x00, 0x03, 0x30, 0x00};
 
 	if ((if_num = get_if(dvbnet)) < 0)
 		return -EINVAL;
 
+	dprintk("dvb_net_add_if: opening network @ pid %d\n", pid);
+
 	net = &dvbnet->device[if_num];
 	demux = dvbnet->demux;
 
+	memset(net, 0, sizeof(struct net_device));
+
 	net->base_addr = 0;
 	net->irq       = 0;
 	net->dma       = 0;
@@ -510,7 +547,8 @@
 	net->name[3]   = dvbnet->dvbdev->adapter->num + '0';
 	net->name[5]   = if_num + '0';
 	net->addr_len  = 6;
-	memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
+/*	memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);*/
+	memcpy(net->dev_addr, mac, 6);
 	net->next      = NULL;
 	net->init      = dvb_net_init_dev;
 
@@ -531,6 +569,8 @@
 		return result;
 	}
 
+	dprintk("dvb_net_add_if: network registered %s @ pid %d\n", net->name, pid);
+
 	return if_num;
 }
 
@@ -561,11 +601,14 @@
 	if (((file->f_flags&O_ACCMODE) == O_RDONLY))
 		return -EPERM;
 
+
 	switch (cmd) {
 	case NET_ADD_IF:
 	{
 		struct dvb_net_if *dvbnetif = (struct dvb_net_if *)parg;
 		int result;
+		
+		dprintk("dvb_net_do_ioctl: cmd=NET_ADD_IF\n");
 
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
@@ -581,6 +624,8 @@
 		struct dvb_net_priv *priv_data;
 		struct dvb_net_if *dvbnetif = (struct dvb_net_if *)parg;
 
+		dprintk("dvb_net_do_ioctl: cmd=NET_GET_IF\n");
+		
 		if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
 		    !dvbnet->state[dvbnetif->if_num])
 			return -EFAULT;
@@ -591,6 +636,7 @@
 		break;
 	}
 	case NET_REMOVE_IF:
+		dprintk("dvb_net_do_ioctl: cmd=NET_REMOVE_IF\n");
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		return dvb_net_remove_if(dvbnet, (int) parg);
@@ -605,6 +651,8 @@
 static int dvb_net_ioctl(struct inode *inode, struct file *file,
 		         unsigned int cmd, unsigned long arg)
 {
+	dprintk("dvb_net_ioctl: cmd=%d, arg=%d.\n", cmd, arg);
+
 	return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl);
 }
 
@@ -652,6 +700,8 @@
 	for (i=0; i<DVB_NET_DEVICES_MAX; i++)
 		dvbnet->state[i] = 0;
 
+	dprintk("dvb_net_init: registring net-device.\n");
+
 	dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net,
 			     dvbnet, DVB_DEVICE_NET);
 

Home | Main Index | Thread Index