From patchwork Sat Jan 14 06:44:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darren Hart X-Patchwork-Id: 136063 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 8674BB6F74 for ; Sat, 14 Jan 2012 17:46:31 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751654Ab2ANGpg (ORCPT ); Sat, 14 Jan 2012 01:45:36 -0500 Received: from mga02.intel.com ([134.134.136.20]:28097 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751424Ab2ANGpe (ORCPT ); Sat, 14 Jan 2012 01:45:34 -0500 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 13 Jan 2012 22:45:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.67,351,1309762800"; d="scan'208";a="98381938" Received: from unknown (HELO localhost) ([10.255.13.179]) by orsmga002.jf.intel.com with ESMTP; 13 Jan 2012 22:45:33 -0800 From: Darren Hart To: Linux Kernel Mailing List Cc: Darren Hart , Arjan van de Ven , Alan Cox , Tomoya MORINAGA , Jeff Kirsher (commit_signer:1/3=33% ,commit_signer:1/8=12%), "David S. Miller" , Paul Gortmaker , Jon Mason , netdev@vger.kernel.org Subject: [PATCH] pch_gbe: Use a randomly generated MAC instead of failing probe Date: Fri, 13 Jan 2012 22:44:55 -0800 Message-Id: <132d2a41a089905de3147b4656e350608aa7fd6f.1326523495.git.dvhart@linux.intel.com> X-Mailer: git-send-email 1.7.6.5 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If the MAC is invalid or not implemented, use a randomly generated one rather than failing the probe. Store the generated addr in a new sw_mac array in the pch_gbe_mac_info structure. Take care to allow for assigning the MAC via ifconfig by reusing sw_addr to store an assigned mac if probe populated it with a random one (otherwise the assignment would rely on the ROM and the reset would fail to write a valid MAC to the rx filter). Tested on two platforms, one with a valid MAC, the other without a MAC. The real MAC is used if present, a randomly generated one otherwise. Both are capable of changing the MAC with ifconfig. They successfully get an IP over DHCP and pass a simple ping and login over ssh test. This does not make any attempt to address a missing or invalid MAC for the pch_phub driver. Signed-off-by: Darren Hart CC: Arjan van de Ven CC: Alan Cox CC: Tomoya MORINAGA CC: Jeff Kirsher (commit_signer:1/3=33%,commit_signer:1/8=12%) CC: "David S. Miller" CC: Paul Gortmaker CC: Jon Mason CC: netdev@vger.kernel.org --- drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h | 3 ++ .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 25 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h index a09a071..3a451a9 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h @@ -356,6 +356,8 @@ struct pch_gbe_functions { /** * struct pch_gbe_mac_info - MAC information * @addr[6]: Store the MAC address + * @sw_addr[6]: Store a random or specified MAC address if the + * ROM is invalid or missing. * @fc: Mode of flow control * @fc_autoneg: Auto negotiation enable for flow control setting * @tx_fc_enable: Enable flag of Transmit flow control @@ -367,6 +369,7 @@ struct pch_gbe_functions { */ struct pch_gbe_mac_info { u8 addr[6]; + u8 sw_addr[6]; u8 fc; u8 fc_autoneg; u8 tx_fc_enable; diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 964e9c0..6453a71 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -116,6 +116,16 @@ s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw) { u32 adr1a, adr1b; + /* + * If we generated a random mac address during probe, then the one in + * the ROM is either invalid or missing, use the generated one instead. + */ + if (is_valid_ether_addr(hw->mac.sw_addr)) { + memcpy(hw->mac.addr, hw->mac.sw_addr, 6); + pr_debug("hw->mac.addr : %pM (using random generated addr)\n", hw->mac.addr); + return 0; + } + adr1a = ioread32(&hw->reg->mac_adr[0].high); adr1b = ioread32(&hw->reg->mac_adr[0].low); @@ -2036,6 +2046,8 @@ static int pch_gbe_set_mac(struct net_device *netdev, void *addr) ret_val = -EADDRNOTAVAIL; } else { memcpy(netdev->dev_addr, skaddr->sa_data, netdev->addr_len); + if (is_valid_ether_addr(adapter->hw.mac.sw_addr)) + memcpy(adapter->hw.mac.sw_addr, skaddr->sa_data, netdev->addr_len); memcpy(adapter->hw.mac.addr, skaddr->sa_data, netdev->addr_len); pch_gbe_mac_mar_set(&adapter->hw, adapter->hw.mac.addr, 0); ret_val = 0; @@ -2444,6 +2456,19 @@ static int pch_gbe_probe(struct pci_dev *pdev, pch_gbe_set_ethtool_ops(netdev); pch_gbe_mac_load_mac_addr(&adapter->hw); + + /* + * Try to read the MAC address. If it is invalid (or just missing), + * generate a random one to use from here on out. + */ + pch_gbe_mac_read_mac_addr(&adapter->hw); + if (!is_valid_ether_addr(adapter->hw.mac.addr)) { + dev_err(&pdev->dev, "Invalid MAC address, " + "using a random generated one.\n"); + random_ether_addr(adapter->hw.mac.sw_addr); + memcpy(adapter->hw.mac.addr, adapter->hw.mac.sw_addr, netdev->addr_len); + } + pch_gbe_mac_reset_hw(&adapter->hw); /* setup the private structure */