[patch] Bring link down when interface goes down

Eugene Grosbein egrosbein at rdtc.ru
Thu Dec 9 18:43:51 UTC 2010


On 06.12.2010 17:48, Eugene Grosbein wrote:
> On 04.12.2010 15:08, Jack Vogel wrote:
>> This isn't some simple 'go change this line or parameter',
>> there were some problematic issues that my Linux coworkers
>> faced, I have to go look into it before I even decide...
>>
>> so...patience friend.
> 
> For igb(4) the change seems pretty short. At least, it works
> for my 82576-based dual-port copper card.

[skip]

> 
> However, similar patch applied to em(4) does not work
> for my on-board 82574L-based cards: e1000_power_down_phy()
> thanslates to e1000_power_down_phy_copper_82571() that does nothing
> because mac->ops.check_mng_mode(hw) returns true value
> and, therefore, e1000_power_down_phy_copper(hw) is not even called.
> 
> Still trying to find a way...

I've written a patch for em(4) that works for my 82573L and 82574L-based
systems. By default, ifconfig down does not affect link (POLA issue).
After sysctl dev.em.0.down_disables_link=1 it does.
Still do not know how to disable "management mode" on my cards
so patch just ignores it when sysctl turned on. Dirty hack, I guess.

--- sys/dev/e1000/if_em.h.orig	2010-12-06 12:45:53.000000000 +0600
+++ sys/dev/e1000/if_em.h	2010-12-08 20:11:05.000000000 +0600
@@ -436,6 +436,9 @@
 	unsigned long	link_irq;
 
 	struct e1000_hw_stats stats;
+	
+	/* Bring link down when interface goes down */
+	int		down_disables_link;
 };
 
 /********************************************************************************
--- sys/dev/e1000/if_em.c.orig	2010-12-06 12:47:51.000000000 +0600
+++ sys/dev/e1000/if_em.c	2010-12-08 20:46:02.000000000 +0600
@@ -452,6 +452,13 @@
 	    OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
 	    em_sysctl_debug_info, "I", "Debug Information");
 
+	adapter->down_disables_link = 0;
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+	    OID_AUTO, "down_disables_link", CTLTYPE_INT|CTLFLAG_RW,
+	    &adapter->down_disables_link, adapter->down_disables_link,
+	    "Bring link down when interface goes down");
+
 	callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
 
 	/* Determine hardware and mac info */
@@ -1266,6 +1273,8 @@
 	}
 
 	/* Initialize the hardware */
+	if (!adapter->hw.phy.reset_disable)
+	        e1000_phy_hw_reset(&adapter->hw);
 	em_reset(adapter);
 	em_update_link_status(adapter);
 
@@ -2319,6 +2328,19 @@
 
 	e1000_led_off(&adapter->hw);
 	e1000_cleanup_led(&adapter->hw);
+
+	if(adapter->down_disables_link) {
+		/* Bring physical link down by powering the phy down */
+/*		e1000_power_down_phy(&adapter->hw); */
+		e1000_power_down_phy_copper(&adapter->hw);
+
+		/* Update system interface state */
+		adapter->hw.mac.get_link_status = 1;
+		em_update_link_status(adapter);
+
+		/* Reset the phy next time init gets called */
+		adapter->hw.phy.reset_disable = FALSE;
+	}
 }
 
 


More information about the freebsd-net mailing list