Re: MII-less network card support



Dan Williams wrote:
That would be great. I'm not quite sure how to fit this in, perhaps we need to add this into the "wired" device activation process and wait for 10s or so for a frame before continuing or failing. Thoughts?

This seemed like an interesting little project (especially after a few frustrations with my day work), and so I've actually just implemented it :-) Easier than I thought, patch against current CVS attached. What it's doing at the moment is if we fail all of the standard MII checks, then it waits 3 seconds for an ethernet frame, and reports 'link ok' if we get one. There's some setsockopt() work with SO_BINDTODEVICE that *should* only get frames sent to the relevant interface, but can someone double-check please.

This makes my card now work with NM, but there's a separate problem. Everything comes up fine, and then after a few moments:

NetworkManager: Activation (eth0) IP configuration/DHCP successful!
NetworkManager: Activation (eth0) ended.
NetworkManager: Activation (eth0) successful, device activated.
NetworkManager: SWITCH: old device no longer good, but no better device was available

Given this wired card is the only one in this machine, this is somewhat annoying. Now, I *think* this might be linked into the fact that my crappy network card is breaking HAL somewhat, as it's entry in hal-device-manager has the net.80203 capability, and a net.interface_up as '1', but no net.80203.link entry, in direct contravention of the HAL 0.42 spec. I'll have a look at that at some point...

Tom
--
palfrey tevp net - http://tevp.net
Illegitimus non carborundum
Index: NetworkManagerDevice.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/NetworkManagerDevice.c,v
retrieving revision 1.85
diff -u -r1.85 NetworkManagerDevice.c
--- NetworkManagerDevice.c	24 Jan 2005 21:53:39 -0000	1.85
+++ NetworkManagerDevice.c	26 Jan 2005 15:57:54 -0000
@@ -3610,6 +3610,50 @@
 	return data[3];
 }
 
+#define FRAME_WAIT_TIME 3
+
+static gboolean ethernet_get_link (NMDevice *dev)
+{
+	int s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+	if (s == -1)
+	{
+		syslog(LOG_ERR, "Can't open raw socket: %s",strerror(errno));
+		return FALSE;
+	}
+	
+	struct ifreq interface;
+	strncpy(interface.ifr_ifrn.ifrn_name, dev->iface, IFNAMSIZ);
+	if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (char *) &interface, sizeof(interface)) < 0)
+	{
+		syslog(LOG_ERR, "setting SO_BINDTODEVICE: %s",strerror(errno));
+		return FALSE;
+	}
+
+	struct timeval t;
+	int retval;
+	fd_set read_set;
+	FD_ZERO(&read_set);
+	FD_SET(s, &read_set);
+	t.tv_sec = FRAME_WAIT_TIME;
+	t.tv_usec = 0;
+	retval = select (s+1, &read_set, 0, 0, &t);
+	if (retval == -1)
+	{
+		syslog(LOG_ERR, "Error on select for raw socket: %s",strerror(errno));
+		return FALSE; 
+	}
+	if (retval!=0)
+	{
+		syslog(LOG_INFO,"Received an ethernet frame!\n");
+		return TRUE;
+	}
+	else
+	{
+		syslog(LOG_INFO,"No ethernet frames within %d seconds!\n",FRAME_WAIT_TIME);
+		return FALSE;
+	}
+}
+
 static gboolean mii_get_link (NMDevice *dev)
 {
 	int			sockfd;
@@ -3634,7 +3678,11 @@
 	{
 		syslog (LOG_ERR, "SIOCGMIIPHY on %s failed: %s", ifr.ifr_name, strerror (errno));
 		close (sockfd);
-		return (FALSE);
+		if (ethernet_get_link (dev))
+			link_active = TRUE;
+		else
+			link_active = FALSE;
+		return (link_active);
 	}
 
 	/* Refer to http://www.scyld.com/diag/mii-status.html for


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