From 0cb7e3b26bb31178a6ed30e00975c18da22bf9d4 Mon Sep 17 00:00:00 2001 From: Noe Rubinstein Date: Fri, 13 Apr 2012 10:53:33 +0200 Subject: e1000: add driver for the Intel GCU. This is used for MDIO on Intel EP80579. --- src/Makefile | 1 + src/drivers/net/e1000/gcu/gcu.h | 82 ++++++++++ src/drivers/net/e1000/gcu/gcu_if.c | 307 +++++++++++++++++++++++++++++++++++ src/drivers/net/e1000/gcu/gcu_if.h | 54 ++++++ src/drivers/net/e1000/gcu/gcu_main.c | 283 ++++++++++++++++++++++++++++++++ src/drivers/net/e1000/gcu/gcu_reg.h | 68 ++++++++ src/include/ipxe/errfile.h | 2 + 7 files changed, 797 insertions(+) create mode 100644 src/drivers/net/e1000/gcu/gcu.h create mode 100644 src/drivers/net/e1000/gcu/gcu_if.c create mode 100644 src/drivers/net/e1000/gcu/gcu_if.h create mode 100644 src/drivers/net/e1000/gcu/gcu_main.c create mode 100644 src/drivers/net/e1000/gcu/gcu_reg.h diff --git a/src/Makefile b/src/Makefile index c30dc5c9..efd9f5ce 100644 --- a/src/Makefile +++ b/src/Makefile @@ -63,6 +63,7 @@ SRCDIRS += image SRCDIRS += drivers/bus SRCDIRS += drivers/net SRCDIRS += drivers/net/e1000 +SRCDIRS += drivers/net/e1000/gcu SRCDIRS += drivers/net/e1000e SRCDIRS += drivers/net/igb SRCDIRS += drivers/net/igbvf diff --git a/src/drivers/net/e1000/gcu/gcu.h b/src/drivers/net/e1000/gcu/gcu.h new file mode 100644 index 00000000..a23671cb --- /dev/null +++ b/src/drivers/net/e1000/gcu/gcu.h @@ -0,0 +1,82 @@ +/***************************************************************************** + +GPL LICENSE SUMMARY + + Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution + in the file called LICENSE.GPL. + + Contact Information: + Intel Corporation + + version: Embedded.Release.Patch.L.1.0.7-5 + + Contact Information: + + Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226 + +*****************************************************************************/ + +/* Linux GCU Driver main header file */ + +#ifndef _GCU_H_ +#define _GCU_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../../wlan_compat.h" + +#define BAR_0 0 + +#define PFX "gcu: " +#define GCU_DBG(args...) DBG(args) +#define GCU_ERR(args...) printf(PFX args) + +#define pci_dev pci_device +#define iowrite32 writel +#define ioread32 readl + +struct gcu_adapter { + struct pci_dev *pdev; + uint32_t mem_start; + uint32_t mem_end; + uint32_t base_addr; + uint8_t *hw_addr; + uint32_t pci_state[16]; + uint16_t device_id; + uint16_t vendor_id; + uint16_t subsystem_id; + uint16_t subsystem_vendor_id; + uint16_t pci_cmd_word; + uint8_t revision_id; +}; + +/* + * Exported interface functions need access to the modules + * gcu_adapter struct + */ +const struct gcu_adapter *gcu_get_adapter(void); +void gcu_release_adapter(const struct gcu_adapter **adapter); + +#endif /* _GCU_H_ */ diff --git a/src/drivers/net/e1000/gcu/gcu_if.c b/src/drivers/net/e1000/gcu/gcu_if.c new file mode 100644 index 00000000..175b764a --- /dev/null +++ b/src/drivers/net/e1000/gcu/gcu_if.c @@ -0,0 +1,307 @@ +/***************************************************************************** + +GPL LICENSE SUMMARY + + Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution + in the file called LICENSE.GPL. + + Contact Information: + Intel Corporation + + version: Embedded.Release.Patch.L.1.0.7-5 + + Contact Information: + + Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226 + +*****************************************************************************/ + +/************************************************************************** + * @ingroup GCU_INTERFACE + * + * @file gcu_if.c + * + * @description + * This module contains shared functions for accessing and configuring + * the GCU. + * + **************************************************************************/ + +#include "gcu.h" +#include "gcu_reg.h" +#include "gcu_if.h" + +#if DBG_LOG +/* forward declaration for write verify used in gcu_write_eth_phy */ +static int32_t gcu_write_verify(uint32_t phy_num, + uint32_t reg_addr, + uint16_t written_data, + const struct gcu_adapter *adapter); +#endif + +/** + * gcu_write_eth_phy + * @phy_num: phy we want to write to, either 0, 1, or 2 + * @reg_addr: address in PHY's register space to write to + * @phy_data: data to be written + * + * interface function for other modules to access the GCU + **/ +int32_t +gcu_write_eth_phy(uint32_t phy_num, uint32_t reg_addr, uint16_t phy_data) +{ + const struct gcu_adapter *adapter; + uint32_t data = 0; + uint32_t timeoutCounter = 0; + const uint32_t timeoutCounterMax = GCU_MAX_ATTEMPTS; + uint32_t pending; + + GCU_DBG("%s\n", __func__); + + if (phy_num > MDIO_COMMAND_PHY_ADDR_MAX) { + GCU_ERR("phy_num = %d, which is greater than " + "MDIO_COMMAND_PHY_ADDR_MAX\n", phy_num); + + return -1; + } + + if (reg_addr > MDIO_COMMAND_PHY_REG_MAX) { + GCU_ERR("reg_addr = %d, which is greater than " + "MDIO_COMMAND_PHY_REG_MAX\n", phy_num); + + return -1; + } + + /* format the data to be written to the MDIO_COMMAND_REG */ + data = phy_data; + data |= (reg_addr << MDIO_COMMAND_PHY_REG_OFFSET); + data |= (phy_num << MDIO_COMMAND_PHY_ADDR_OFFSET); + data |= MDIO_COMMAND_OPER_MASK | MDIO_COMMAND_GO_MASK; + + adapter = gcu_get_adapter(); + if (!adapter) { + GCU_ERR("gcu_adapter not available, cannot access MMIO\n"); + return -1; + } + + /* + * We write to MDIO_COMMAND_REG initially, then read that + * same register until its MDIO_GO bit is cleared. When cleared, + * the transaction is complete + */ + iowrite32(data, adapter->hw_addr + MDIO_COMMAND_REG); + do { + timeoutCounter++; + udelay(0x32); /* 50 microsecond delay */ + data = ioread32(adapter->hw_addr + MDIO_COMMAND_REG); + pending = + (data & MDIO_COMMAND_GO_MASK) >> MDIO_COMMAND_GO_OFFSET; + } while (pending && timeoutCounter < timeoutCounterMax); + + if (timeoutCounter == timeoutCounterMax && pending) { + GCU_ERR("Reached maximum number of retries" + " accessing MDIO_COMMAND_REG\n"); + + gcu_release_adapter(&adapter); + + return -1; + } + + /* validate the write during debug */ +#if DBG_LOG + if (!gcu_write_verify(phy_num, reg_addr, phy_data, adapter)) + DBG("Write verification failed for PHY=%d and addr=%d\n", + phy_num, reg_addr); +#endif + + gcu_release_adapter(&adapter); + + return 0; +} +EXPORT_SYMBOL(gcu_write_eth_phy); + +/** + * gcu_read_eth_phy + * @phy_num: phy we want to write to, either 0, 1, or 2 + * @reg_addr: address in PHY's register space to write to + * @phy_data: data to be written + * + * interface function for other modules to access the GCU + **/ +int32_t +gcu_read_eth_phy(uint32_t phy_num, uint32_t reg_addr, uint16_t *phy_data) +{ + const struct gcu_adapter *adapter; + uint32_t data = 0; + uint32_t timeoutCounter = 0; + const uint32_t timeoutCounterMax = GCU_MAX_ATTEMPTS; + uint32_t pending = 0; + + GCU_DBG("%s\n", __func__); + + if (phy_num > MDIO_COMMAND_PHY_ADDR_MAX) { + GCU_ERR("phy_num = %d, which is greater than " + "MDIO_COMMAND_PHY_ADDR_MAX\n", phy_num); + + return -1; + } + + if (reg_addr > MDIO_COMMAND_PHY_REG_MAX) { + GCU_ERR("reg_addr = %d, which is greater than " + "MDIO_COMMAND_PHY_REG_MAX\n", phy_num); + + return -1; + } + + /* format the data to be written to MDIO_COMMAND_REG */ + data |= (reg_addr << MDIO_COMMAND_PHY_REG_OFFSET); + data |= (phy_num << MDIO_COMMAND_PHY_ADDR_OFFSET); + data |= MDIO_COMMAND_GO_MASK; + + adapter = gcu_get_adapter(); + if (!adapter) { + GCU_ERR("gcu_adapter not available, cannot access MMIO\n"); + return -1; + } + + /* + * We write to MDIO_COMMAND_REG initially, then read that + * same register until its MDIO_GO bit is cleared. When cleared, + * the transaction is complete + */ + iowrite32(data, adapter->hw_addr + MDIO_COMMAND_REG); + do { + timeoutCounter++; + udelay(0x32); /* 50 microsecond delay */ + data = ioread32(adapter->hw_addr + MDIO_COMMAND_REG); + pending = + (data & MDIO_COMMAND_GO_MASK) >> MDIO_COMMAND_GO_OFFSET; + } while (pending && timeoutCounter < timeoutCounterMax); + + if (timeoutCounter == timeoutCounterMax && pending) { + GCU_ERR("Reached maximum number of retries" + " accessing MDIO_COMMAND_REG\n"); + + gcu_release_adapter(&adapter); + + return -1; + } + + /* we retrieve the data from the MDIO_STATUS_REGISTER */ + data = ioread32(adapter->hw_addr + MDIO_STATUS_REG); + if ((data & MDIO_STATUS_STATUS_MASK) != 0) { + GCU_ERR("Unable to retrieve data from MDIO_STATUS_REG\n"); + + gcu_release_adapter(&adapter); + + return -1; + } + + *phy_data = (uint16_t) (data & MDIO_STATUS_READ_DATA_MASK); + + gcu_release_adapter(&adapter); + + return 0; +} +EXPORT_SYMBOL(gcu_read_eth_phy); + +#if DBG_LOG +/** + * gcu_write_verify + * @phy_num: phy we want to write to, either 0, 1, or 2 + * @reg_addr: address in PHY's register space to write to + * @phy_data: data to be checked + * @adapter: pointer to global adapter struct + * + * This f(n) assumes that the spinlock acquired for adapter is + * still in force. + **/ +int32_t +gcu_write_verify(uint32_t phy_num, uint32_t reg_addr, uint16_t written_data, + const struct gcu_adapter *adapter) +{ + u32 data = 0; + u32 timeoutCounter = 0; + const uint32_t timeoutCounterMax = GCU_MAX_ATTEMPTS; + u32 pending = 0; + u16 read_data; + int success; + + GCU_DBG("%s\n", __func__); + + if (!adapter) { + GCU_ERR("Invalid adapter pointer\n"); + return 0; + } + + if (phy_num > MDIO_COMMAND_PHY_ADDR_MAX) { + GCU_ERR("phy_num = %d, which is greater than " + "MDIO_COMMAND_PHY_ADDR_MAX\n", phy_num); + + return 0; + } + + if (reg_addr > MDIO_COMMAND_PHY_REG_MAX) { + GCU_ERR("reg_addr = %d, which is greater than " + "MDIO_COMMAND_PHY_REG_MAX\n", phy_num); + + return 0; + } + + /* format the data to be written to MDIO_COMMAND_REG */ + data |= (reg_addr << MDIO_COMMAND_PHY_REG_OFFSET); + data |= (phy_num << MDIO_COMMAND_PHY_ADDR_OFFSET); + data |= MDIO_COMMAND_GO_MASK; + + /* + * We write to MDIO_COMMAND_REG initially, then read that + * same register until its MDIO_GO bit is cleared. When cleared, + * the transaction is complete + */ + iowrite32(data, adapter->hw_addr + MDIO_COMMAND_REG); + do { + timeoutCounter++; + udelay(0x32); /* 50 microsecond delay */ + data = ioread32(adapter->hw_addr + MDIO_COMMAND_REG); + pending = + (data & MDIO_COMMAND_GO_MASK) >> MDIO_COMMAND_GO_OFFSET; + } while (pending && timeoutCounter < timeoutCounterMax); + + if (timeoutCounter == timeoutCounterMax && pending) { + GCU_ERR("Reached maximum number of retries" + " accessing MDIO_COMMAND_REG\n"); + + return 0; + } + + /* we retrieve the data from the MDIO_STATUS_REGISTER */ + data = ioread32(adapter->hw_addr + MDIO_STATUS_REG); + if ((data & MDIO_STATUS_STATUS_MASK) != 0) { + GCU_ERR("Unable to retrieve data from MDIO_STATUS_REG\n"); + + return 0; + } + + read_data = data & MDIO_STATUS_READ_DATA_MASK; + success = written_data == read_data; + if (!success) + DBG("WARNING: PHY%d reg %x: wrote 0x%04x, read 0x%04x\n", + phy_num, reg_addr, written_data, read_data); + + return success; +} +#endif diff --git a/src/drivers/net/e1000/gcu/gcu_if.h b/src/drivers/net/e1000/gcu/gcu_if.h new file mode 100644 index 00000000..2d5991e8 --- /dev/null +++ b/src/drivers/net/e1000/gcu/gcu_if.h @@ -0,0 +1,54 @@ +/***************************************************************************** + +GPL LICENSE SUMMARY + + Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution + in the file called LICENSE.GPL. + + Contact Information: + Intel Corporation + + version: Embedded.Release.Patch.L.1.0.7-5 + + Contact Information: + + Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226 + +*****************************************************************************/ + +/* + * gcu_if.h + * Shared functions for accessing and configuring the GCU + */ + +#ifndef GCU_IF_H +#define GCU_IF_H + +#include + +#define GCU_DEVID 0x503E +#define GCU_MAX_ATTEMPTS 64 + +int32_t gcu_write_eth_phy(uint32_t phy_num, uint32_t reg_addr, + uint16_t phy_data); + +int32_t gcu_read_eth_phy(uint32_t phy_num, uint32_t reg_addr, + uint16_t *phy_data); + +int gcu_e1000_suspend(struct pci_device *pdev, uint32_t state); +void gcu_e1000_resume(struct pci_device *pdev); +#endif /* ifndef GCU_IF_H */ diff --git a/src/drivers/net/e1000/gcu/gcu_main.c b/src/drivers/net/e1000/gcu/gcu_main.c new file mode 100644 index 00000000..63b2dbc4 --- /dev/null +++ b/src/drivers/net/e1000/gcu/gcu_main.c @@ -0,0 +1,283 @@ +/****************************************************************************** + +GPL LICENSE SUMMARY + + Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution + in the file called LICENSE.GPL. + + Contact Information: + Intel Corporation + + version: Embedded.Release.Patch.L.1.0.7-5 + + Contact Information: + + Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226 + +******************************************************************************/ +/************************************************************************** + * @ingroup GCU_GENERAL + * + * @file gcu_main.c + * + * @description + * This module contains the upper-edge routines of the driver + * interface that handle initialization, resets, and shutdowns + * of the GCU. + * + **************************************************************************/ + +#include "gcu.h" + +char gcu_driver_name[] = "GCU"; +char gcu_driver_string[] = "Global Configuration Unit Driver"; +#define DRV_VERSION "1.0.0" +char gcu_driver_version[] = DRV_VERSION; +char gcu_copyright[] = "Copyright (c) 1999-2007 Intel Corporation."; + +/* gcu_pci_tbl - PCI Device ID Table + * + * Last entry must be all 0s + * + * Macro expands to... + * {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)} + */ +static struct pci_device_id gcu_pci_tbl[] = { + PCI_ID(0x8086, 0x503E, "gcu", "Global Configuration Unit", 0), +}; + +MODULE_DEVICE_TABLE(pci, gcu_pci_tbl); + +enum gcu_err_type { err_ioremap, err_alloc_gcu_adapter }; + +static int gcu_probe(struct pci_dev *pdev); +static void gcu_probe_err(enum gcu_err_type err, struct gcu_adapter *adapter); +static void gcu_remove(struct pci_dev *pdev); +static struct gcu_adapter *alloc_gcu_adapter(void); +static void free_gcu_adapter(struct gcu_adapter *adapter); + +struct pci_driver gcu_driver __pci_driver = { + .ids = gcu_pci_tbl, + .id_count = ARRAY_SIZE(gcu_pci_tbl), + .probe = gcu_probe, + .remove = gcu_remove, + .load_order = 1, +}; + +static struct gcu_adapter *global_adapter = 0; + +/** + * gcu_probe - Device Initialization Routine + * @pdev: PCI device information struct + * @ent: entry in gcu_pci_tbl + * + * Returns 0 on success, negative on failure + * + * gcu_probe initializes an adapter identified by a pci_dev structure. + * The OS initialization, configuring of the adapter private structure, + * and a hardware reset occur. + **/ +static int +gcu_probe(struct pci_dev *pdev) +{ + struct gcu_adapter *adapter = 0; + uint32_t mmio_start, mmio_len; + + GCU_DBG("%s\n", __func__); + + /** If we already have an adapter then we must already have been probed. */ + if (global_adapter != 0) + return 0; + + adjust_pci_device(pdev); + + /* + * acquire the adapter spinlock. Once the module is loaded, it is + * possible for someone to access the adapter struct via the interface + * functions exported in gcu_if.c + */ + spin_lock(&global_adapter_spinlock); + + adapter = alloc_gcu_adapter(); + if (!adapter) { + gcu_probe_err(err_alloc_gcu_adapter, adapter); + spin_unlock(&global_adapter_spinlock); + return -ENOMEM; + } + + pci_set_drvdata(pdev, adapter); + + adapter->pdev = pdev; + + mmio_start = pci_bar_start(pdev, PCI_BASE_ADDRESS_0); + mmio_len = pci_bar_size(pdev, PCI_BASE_ADDRESS_0); + + adapter->hw_addr = ioremap(mmio_start, mmio_len); + if (!adapter->hw_addr) { + GCU_DBG("Unable to map mmio\n"); + gcu_probe_err(err_ioremap, adapter); + spin_unlock(&global_adapter_spinlock); + return -EIO; + } + + adapter->mem_start = mmio_start; + adapter->mem_end = mmio_start + mmio_len; + + adapter->vendor_id = pdev->vendor; + adapter->device_id = pdev->device; + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, + &adapter->subsystem_vendor_id); + pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &adapter->subsystem_id); + pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->revision_id); + + pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->revision_id); + + pci_read_config_word(pdev, PCI_COMMAND, &adapter->pci_cmd_word); + + global_adapter = adapter; + spin_unlock(&global_adapter_spinlock); + + DBG("Intel(R) GCU Initialized\n"); + + return 0; +} + +/** + * gcu_probe_err - gcu_probe error handler + * @err: gcu_err_type + * + * encapsulated error handling for gcu_probe + **/ +static void +gcu_probe_err(enum gcu_err_type err, struct gcu_adapter *adapter) +{ + switch (err) { + case err_ioremap: + iounmap(adapter->hw_addr); + case err_alloc_gcu_adapter: + default: + free_gcu_adapter(adapter); + break; + } +} + +/** + * gcu_remove - Device Removal Routine + * @pdev: PCI device information struct + * + * gcu_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. The could be caused by a + * Hot-Plug event, or because the driver is going to be removed from + * memory. + **/ +static void gcu_remove(struct pci_dev *pdev) +{ + struct gcu_adapter *adapter = pci_get_drvdata(pdev); + + GCU_DBG("%s\n", __func__); + + iounmap(adapter->hw_addr); + free_gcu_adapter(adapter); + pci_set_drvdata(pdev, NULL); +} + +/** + * alloc_gcu_adapter + * + * alloc_gcu_adapter is a wrapper for the kmalloc call for the + * device specific data block plus inits the global_adapter variable. + * + * Note that this function assumes that the spinlock for the global + * gcu_adapter struct as been acquired. + **/ +static struct gcu_adapter *alloc_gcu_adapter() +{ + struct gcu_adapter *adapter; + + GCU_DBG("%s\n", __func__); + + adapter = malloc(sizeof(*adapter)); + + global_adapter = adapter; + + if (!adapter) { + GCU_DBG("Unable to allocate space for global gcu_adapter"); + return 0; + } + + memset(adapter, 0, sizeof(*adapter)); + + return adapter; +} + +/** + * free_gcu_adapter + * @adapter: gcu_adapter struct to be free'd + * + * free_gcu_adapter is a wrapper for the kfree call for the + * device specific data block plus clears the global_adapter variable + * + * Note that this function assumes that the spinlock for the global + * gcu_adapter struct as been acquired. + **/ +static void free_gcu_adapter(struct gcu_adapter *adapter) +{ + GCU_DBG("%s\n", __func__); + + global_adapter = 0; + + free(adapter); +} + +/** + * gcu_get_adapter + * + * gcu_get_adapter is used by the functions exported in gcu_if.c to get + * access to the memory addresses needed to access the MMIO registers + * of the GCU + **/ +const struct gcu_adapter *gcu_get_adapter(void) +{ + GCU_DBG("%s\n", __func__); + + if (global_adapter == NULL) { + GCU_DBG("global gcu_adapter is not available\n"); + return NULL; + } + + return global_adapter; +} + +/** + * gcu_release_adapter + * + * gcu_release_adapter is used by the functions exported in gcu_if.c to get + * release the adapter spinlock and the handle to the adapter + **/ +void gcu_release_adapter(const struct gcu_adapter **adapter) +{ + GCU_DBG("%s\n", __func__); + + if (adapter == NULL) + GCU_ERR("global gcu_adapter handle is invalid\n"); + else + *adapter = 0; + + return; +} + +/* gcu_main.c */ diff --git a/src/drivers/net/e1000/gcu/gcu_reg.h b/src/drivers/net/e1000/gcu/gcu_reg.h new file mode 100644 index 00000000..cf77303c --- /dev/null +++ b/src/drivers/net/e1000/gcu/gcu_reg.h @@ -0,0 +1,68 @@ +/****************************************************************************** + +GPL LICENSE SUMMARY + + Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution + in the file called LICENSE.GPL. + + Contact Information: + Intel Corporation + + version: Embedded.Release.Patch.L.1.0.7-5 + + Contact Information: + + Intel Corporation, 5000 W Chandler Blvd, Chandler, AZ 85226 + +******************************************************************************/ + +/* + * gcu_reg.h + * Macros and constants related to the registers available on the GCU + */ + +#ifndef GCU_REG_H +#define GCU_REG_H + +/* Register Offsets within memory map register space */ +#define MDIO_STATUS_REG 0x00000010UL +#define MDIO_COMMAND_REG 0x00000014UL + +/* MDIO_STATUS_REG fields */ +#define MDIO_STATUS_STATUS_MASK 0x80000000UL /* bit 31 = 1 on error */ +#define MDIO_STATUS_READ_DATA_MASK 0x0000FFFFUL + +/* MDIO_COMMAND_REG fields */ +#define MDIO_COMMAND_GO_MASK 0x80000000UL /* bit 31 = 1 during read + * or write, 0 on + * completion */ +#define MDIO_COMMAND_OPER_MASK 0x04000000UL /* bit = 1 is a write */ +#define MDIO_COMMAND_PHY_ADDR_MASK 0x03E00000UL +#define MDIO_COMMAND_PHY_REG_MASK 0x001F0000UL +#define MDIO_COMMAND_WRITE_DATA_MASK 0x0000FFFFUL + +#define MDIO_COMMAND_GO_OFFSET 31 +#define MDIO_COMMAND_OPER_OFFSET 26 +#define MDIO_COMMAND_PHY_ADDR_OFFSET 21 +#define MDIO_COMMAND_PHY_REG_OFFSET 16 +#define MDIO_COMMAND_WRITE_DATA_OFFSET 0 + +#define MDIO_COMMAND_PHY_ADDR_MAX 2 /* total phys supported by GCU */ +#define MDIO_COMMAND_PHY_REG_MAX 31 /* total registers available on the + * M88 Phy used on truxton */ + +#endif /* ifndef GCU_REG_H */ diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index 7c86fdbb..6a334ff0 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -140,6 +140,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ERRFILE_ath9k ( ERRFILE_DRIVER | 0x005f0000 ) #define ERRFILE_ath ( ERRFILE_DRIVER | 0x00600000 ) #define ERRFILE_vmxnet3 ( ERRFILE_DRIVER | 0x00610000 ) +#define ERRFILE_gcu_main ( ERRFILE_DRIVER | 0x00620000 ) +#define ERRFILE_gcu_if ( ERRFILE_DRIVER | 0x00630000 ) #define ERRFILE_scsi ( ERRFILE_DRIVER | 0x00700000 ) #define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 ) -- cgit v1.2.3