e1000e: fix flow control denial of service possibility

this patch avoids a denial of service from an evildoer sending a
continuous stream of flow control at our adapter that is plugged
into a non-flow control enabled switch.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
Jesse Brandeburg 2008-02-21 15:11:02 -08:00 committed by Jeff Garzik
parent 4a5694e664
commit de92d84ec2

View File

@ -1104,34 +1104,13 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
mac->fc = e1000_fc_rx_pause; mac->fc = e1000_fc_rx_pause;
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n"); hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
} } else {
/* Per the IEEE spec, at this point flow control should be /*
* disabled. However, we want to consider that we could * Per the IEEE spec, at this point flow control
* be connected to a legacy switch that doesn't advertise * should be disabled.
* desired flow control, but can be forced on the link
* partner. So if we advertised no flow control, that is
* what we will resolve to. If we advertised some kind of
* receive capability (Rx Pause Only or Full Flow Control)
* and the link partner advertised none, we will configure
* ourselves to enable Rx Flow Control only. We can do
* this safely for two reasons: If the link partner really
* didn't want flow control enabled, and we enable Rx, no
* harm done since we won't be receiving any PAUSE frames
* anyway. If the intent on the link partner was to have
* flow control enabled, then by us enabling RX only, we
* can at least receive pause frames and process them.
* This is a good idea because in most cases, since we are
* predominantly a server NIC, more times than not we will
* be asked to delay transmission of packets than asking
* our link partner to pause transmission of frames.
*/ */
else if ((mac->original_fc == e1000_fc_none) ||
(mac->original_fc == e1000_fc_tx_pause)) {
mac->fc = e1000_fc_none; mac->fc = e1000_fc_none;
hw_dbg(hw, "Flow Control = NONE.\r\n"); hw_dbg(hw, "Flow Control = NONE.\r\n");
} else {
mac->fc = e1000_fc_rx_pause;
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
} }
/* Now we need to do one last check... If we auto- /* Now we need to do one last check... If we auto-