diff --git a/ael2005_conf.c b/ael2005_conf.c index cd47a90..4317e39 100644 --- a/ael2005_conf.c +++ b/ael2005_conf.c @@ -1,3 +1,48 @@ +/******************************************************************************* +* +* NetFPGA-10G http://www.netfpga.org +* +* File: +* ael2005_conf.c +* +* Project: +* +* +* Author: +* Hwanju Kim +* Marco Forconesi +* +* Description: +* Write magic registers for PHYs (AEL2005) configuration. +* +* TODO: +* +* +* This code is initially developed for the Network-as-a-Service (NaaS) project. +* (under development in https://github.com/NetFPGA-NewNIC/linux-driver) +* +* +* Copyright notice: +* Copyright (C) 2014 University of Cambridge +* +* Licence: +* This file is part of the NetFPGA 10G development base package. +* +* This file is free code: you can redistribute it and/or modify it under +* the terms of the GNU Lesser General Public License version 2.1 as +* published by the Free Software Foundation. +* +* This package 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with the NetFPGA source package. If not, see +* http://www.gnu.org/licenses/. +* +*/ + #include #include #include @@ -8,6 +53,11 @@ #include "nf10.h" #include "ael2005_conf.h" +static bool CF_PHY_NF0 = true; +static bool CF_PHY_NF1 = true; +static bool CF_PHY_NF2 = true; +static bool CF_PHY_NF3 = true; + irqreturn_t mdio_access_interrupt_handler(int irq, void *dev_id) { struct pci_dev *pdev = dev_id; @@ -27,22 +77,48 @@ int configure_ael2005_phy_chips(struct nf10_adapter *adapter) u8 DEVAD; u16 ADDR, WRITE_DATA; int size, i; - int timeout = 0; + int timeout; + bool config_phy; - pr_info("PHY: AEL2005 Initialization Start...\n"); + pr_info("PHY: AEL2005 configuration starts\n"); - /* We only need interface 3 in this project - * don't forget that the nearest port to PCIe is hardwired to 0x2 */ - for(PRTAD = 3; PRTAD < 4; PRTAD++) { + /* configure PHYs one at a time: + * Port Address (PRTAD) identifies each of the Ethernet + * interfaces on the board. The closest to the PCIe + * fingers has a PRTAD hard-wired to 0x02 and corresponds to + * nf0 in SW */ + for(PRTAD = 0; PRTAD < 4; PRTAD++) { DEVAD = MDIO_MMD_PMAPMD; + timeout = 0; + + /* map nfx to PRTAD */ + switch (PRTAD) { + case 0x02: + config_phy = CF_PHY_NF0; + break; + case 0x01: + config_phy = CF_PHY_NF1; + break; + case 0x00: + config_phy = CF_PHY_NF2; + break; + case 0x03: + config_phy = CF_PHY_NF3; + break; + default: + return -1; + } + + if (!config_phy) + continue; - /* Step 1: write reset registers */ + /* step 1: write reset registers */ size = sizeof(reset) / sizeof(u16); for(i = 0; i < size; i += 2) { /* MDIO clause 45 Set Address Transaction */ atomic_set(&adapter->mdio_access_rdy, 0); - /* Send Memory Write Request TLP */ + /* send Memory Write Request TLP */ OP_CODE = 0x0; ADDR = reset[i]; *(((u32 *)adapter->bar0) + 4) = @@ -54,8 +130,7 @@ int configure_ael2005_phy_chips(struct nf10_adapter *adapter) msleep(2); timeout++; - /* if it takes too long, - * hw is not working properly */ + /* no response from HW */ if (timeout > 20) return ret; } while (!atomic_read(&adapter->mdio_access_rdy)); @@ -63,7 +138,7 @@ int configure_ael2005_phy_chips(struct nf10_adapter *adapter) /* MDIO clause 45 Write Transaction */ atomic_set(&adapter->mdio_access_rdy, 0); - /* Send Memory Write Request TLP */ + /* send Memory Write Request TLP */ OP_CODE = 0x1; WRITE_DATA = reset[i+1]; *(((u32 *)adapter->bar0) + 4) = @@ -76,14 +151,14 @@ int configure_ael2005_phy_chips(struct nf10_adapter *adapter) } while (!atomic_read(&adapter->mdio_access_rdy)); } - /* Step 2: write sr_edc or twinax_edc registers. + /* step 2: write sr_edc or twinax_edc registers. * (depending on the sfp+ modules) */ size = sizeof(sr_edc) / sizeof(u16); for (i = 0; i < size; i += 2) { /* MDIO clause 45 Set Address Transaction */ atomic_set(&adapter->mdio_access_rdy, 0); - /* Send Memory Write Request TLP */ + /* send Memory Write Request TLP */ OP_CODE = 0x0; ADDR = sr_edc[i]; *(((u32 *)adapter->bar0) + 4) = @@ -98,7 +173,7 @@ int configure_ael2005_phy_chips(struct nf10_adapter *adapter) /* MDIO clause 45 Write Transaction */ atomic_set(&adapter->mdio_access_rdy, 0); - /* Send Memory Write Request TLP */ + /* send Memory Write Request TLP */ OP_CODE = 0x1; WRITE_DATA = sr_edc[i+1]; *(((u32 *)adapter->bar0) + 4) = @@ -111,13 +186,13 @@ int configure_ael2005_phy_chips(struct nf10_adapter *adapter) } while (!atomic_read(&adapter->mdio_access_rdy)); } - /* Step 1: write regs1 registers */ + /* step 1: write regs1 registers */ size = sizeof(regs1) / sizeof(u16); for(i = 0; i < size; i += 2) { /* MDIO clause 45 Set Address Transaction */ atomic_set(&adapter->mdio_access_rdy, 0); - /* Send Memory Write Request TLP */ + /* send Memory Write Request TLP */ OP_CODE = 0x0; ADDR = regs1[i]; *(((u32 *)adapter->bar0) + 4) = @@ -132,7 +207,7 @@ int configure_ael2005_phy_chips(struct nf10_adapter *adapter) /* MDIO clause 45 Write Transaction */ atomic_set(&adapter->mdio_access_rdy, 0); - /* Send Memory Write Request TLP */ + /* send Memory Write Request TLP */ OP_CODE = 0x1; WRITE_DATA = regs1[i+1]; *(((u32 *)adapter->bar0) + 4) = @@ -145,7 +220,7 @@ int configure_ael2005_phy_chips(struct nf10_adapter *adapter) } while (!atomic_read(&adapter->mdio_access_rdy)); } } - pr_info("PHY: AEL2005 Initialization Finished...\n"); + pr_info("PHY: AEL2005 configuration finishes\n"); return 0; } diff --git a/ael2005_conf.h b/ael2005_conf.h index ad919b8..83948ed 100644 --- a/ael2005_conf.h +++ b/ael2005_conf.h @@ -1,3 +1,4 @@ +/* Magic registers */ #ifndef _AEL2005_SIMPLE_CONF_H #define _AEL2005_SIMPLE_CONF_H