From patchwork Wed Nov 17 23:16:55 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Brandeburg X-Patchwork-Id: 71631 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id A0575B7179 for ; Thu, 18 Nov 2010 10:17:01 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750731Ab0KQXQ5 (ORCPT ); Wed, 17 Nov 2010 18:16:57 -0500 Received: from mga11.intel.com ([192.55.52.93]:39616 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750698Ab0KQXQ4 (ORCPT ); Wed, 17 Nov 2010 18:16:56 -0500 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 17 Nov 2010 15:16:56 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.59,213,1288594800"; d="scan'208";a="627841820" Received: from jbrandeb-ich9b.jf.intel.com ([134.134.3.214]) by fmsmga002.fm.intel.com with ESMTP; 17 Nov 2010 15:16:56 -0800 Received: from jbrandeb-ich9b.jf.intel.com (localhost.localdomain [127.0.0.1]) by jbrandeb-ich9b.jf.intel.com (8.14.4/8.14.4) with ESMTP id oAHNGtYt030702; Wed, 17 Nov 2010 15:16:55 -0800 From: Jesse Brandeburg Subject: [RFC PATCH] ethtool: allow setting MDI-X state To: netdev@vger.kernel.org, bhutchings@solarflare.com Date: Wed, 17 Nov 2010 15:16:55 -0800 Message-ID: <20101117231655.30673.37157.stgit@jbrandeb-ich9b.jf.intel.com> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org ethtool recently added support for reading MDI-X state, this patch finishes the implementation, adding the complementary write command. Add support to ethtool for controlling the MDI-X (crossover) state of a network port. Most adapters correctly negotiate MDI-X, but some ill-behaved switches have trouble and end up picking the wrong MDI setting, which results in complete loss of link. Usually this error condition can be observed with multiple ethtool -r ethX required before link is achieved. usage is ethtool -s eth0 mdix [auto|on|off] Signed-off-by: Jesse Brandeburg --- ethtool.8 | 8 ++++++++ ethtool.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 0 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/ethtool.8 b/ethtool.8 index 1760924..c96e35d 100644 --- a/ethtool.8 +++ b/ethtool.8 @@ -196,6 +196,7 @@ ethtool \- Display or change ethernet card settings .BI speed \ N .B2 duplex half full .B4 port tp aui bnc mii fibre +.B3 mdix auto on off .B2 autoneg on off .RB [ advertise .IR N ] @@ -452,6 +453,13 @@ Sets full or half duplex mode. .A4 port tp aui bnc mii fibre Selects device port. .TP +.A3 mdix auto on off +Selects MDI-X mode for port. May be used to override the automatic detection +feature of most adapters. Auto means automatic detection of MDI status, on +forces MDI-X (crossover) mode, while off means MDI (straight through) mode. +Depending on implementation an ethtool -r ethX command may be necessary to +cause the change to take effect. +.TP .A2 autoneg on off Specifies whether autonegotiation should be enabled. Autonegotiation is enabled by deafult, but in some network devices may have trouble diff --git a/ethtool.c b/ethtool.c index 239912b..fcc7998 100644 --- a/ethtool.c +++ b/ethtool.c @@ -157,6 +157,7 @@ static struct option { " [ speed %d ]\n" " [ duplex half|full ]\n" " [ port tp|aui|bnc|mii|fibre ]\n" + " [ mdix auto|on|off ]\n" " [ autoneg on|off ]\n" " [ advertise %x ]\n" " [ phyad %d ]\n" @@ -353,6 +354,7 @@ static s32 coal_tx_frames_high_wanted = -1; static int speed_wanted = -1; static int duplex_wanted = -1; static int port_wanted = -1; +static int mdix_wanted = -1; static int autoneg_wanted = -1; static int phyad_wanted = -1; static int xcvr_wanted = -1; @@ -1048,6 +1050,20 @@ static void parse_cmdline(int argc, char **argp) else show_usage(1); break; + } else if (!strcmp(argp[i], "mdix")) { + gset_changed = 1; + i += 1; + if (i >= argc) + show_usage(1); + if (!strcmp(argp[i], "auto")) + mdix_wanted = ETH_TP_MDI_INVALID; + else if (!strcmp(argp[i], "on")) + mdix_wanted = ETH_TP_MDI_X; + else if (!strcmp(argp[i], "off")) + mdix_wanted = ETH_TP_MDI; + else + show_usage(1); + break; } else if (!strcmp(argp[i], "autoneg")) { i += 1; if (i >= argc) @@ -1124,6 +1140,20 @@ static void parse_cmdline(int argc, char **argp) i = argc; } break; + } else if (!strcmp(argp[i], "mdix")) { + gset_changed = 1; + i += 1; + if (i >= argc) + show_usage(1); + if (!strcmp(argp[i], "auto")) + mdix_wanted = ETH_TP_MDI_INVALID; + else if (!strcmp(argp[i], "on")) + mdix_wanted = ETH_TP_MDI_X; + else if (!strcmp(argp[i], "off")) + mdix_wanted = ETH_TP_MDI; + else + show_usage(1); + break; } show_usage(1); } @@ -2525,6 +2555,8 @@ static int do_sset(int fd, struct ifreq *ifr) ecmd.duplex = duplex_wanted; if (port_wanted != -1) ecmd.port = port_wanted; + if (mdix_wanted != -1) + ecmd.eth_tp_mdix = mdix_wanted; if (autoneg_wanted != -1) ecmd.autoneg = autoneg_wanted; if (phyad_wanted != -1) @@ -2566,6 +2598,8 @@ static int do_sset(int fd, struct ifreq *ifr) fprintf(stderr, " not setting phy_address\n"); if (xcvr_wanted != -1) fprintf(stderr, " not setting transceiver\n"); + if (mdix_wanted != -1) + fprintf(stderr, " not setting mdix\n"); } }