The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com --- Drivers/Net/MarvellYukonDxe/DriverBinding.c | 6 +- Drivers/Net/MarvellYukonDxe/Snp.c | 46 +-- Drivers/Net/MarvellYukonDxe/e1000phy.c | 330 +++++++++++---- Drivers/Net/MarvellYukonDxe/e1000phyreg.h | 23 ++ Drivers/Net/MarvellYukonDxe/if_msk.c | 615 +++++++++++++++++++++------- Drivers/Net/MarvellYukonDxe/if_msk.h | 18 +- Drivers/Net/MarvellYukonDxe/if_mskreg.h | 17 + Drivers/Net/MarvellYukonDxe/miivar.h | 15 +- 8 files changed, 786 insertions(+), 284 deletions(-)
diff --git a/Drivers/Net/MarvellYukonDxe/DriverBinding.c b/Drivers/Net/MarvellYukonDxe/DriverBinding.c index 95068fa..fc684c0 100644 --- a/Drivers/Net/MarvellYukonDxe/DriverBinding.c +++ b/Drivers/Net/MarvellYukonDxe/DriverBinding.c @@ -192,14 +192,14 @@ MarvellYukonDriverStart ( // // Initialize Yukon card so we can get the MAC address // - Status = mskc_attach (YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress); + Status = mskc_attach (Controller, YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { gBS->FreePool (YukonDriver); return Status; }
- mskc_detach(); + mskc_detach (Controller);
// // Assign fields for device path @@ -487,6 +487,8 @@ InitializeMarvellYukonDriver (
if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: InitializeMarvellYukonDriver(): Driver binding failed\n")); + } else { + mskc_init_driver_list (); }
return Status; diff --git a/Drivers/Net/MarvellYukonDxe/Snp.c b/Drivers/Net/MarvellYukonDxe/Snp.c index 3d84f84..96cec5f 100644 --- a/Drivers/Net/MarvellYukonDxe/Snp.c +++ b/Drivers/Net/MarvellYukonDxe/Snp.c @@ -121,21 +121,21 @@ SnpGetStatus ( ) { EFI_STATUS Status; - YUKON_DRIVER *Snp; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This); - if (Snp == NULL) { + YukonDriver = YUKON_DEV_FROM_THIS_SNP (This); + if (YukonDriver == NULL) { return EFI_INVALID_PARAMETER; }
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) { + switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -148,7 +148,7 @@ SnpGetStatus ( goto ON_EXIT; }
- mskc_getstatus (InterruptStatus, TxBuf); + mskc_getstatus (YukonDriver->Controller, InterruptStatus, TxBuf); Status = EFI_SUCCESS;
ON_EXIT: @@ -199,7 +199,7 @@ SnpInitialize ( ) { EFI_STATUS Status; - YUKON_DRIVER *YukonDriver; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpInitialize()\n")); @@ -230,7 +230,7 @@ SnpInitialize ( gBS->SetMem (YukonDriver->SnpMode.MCastFilter, sizeof YukonDriver->SnpMode.MCastFilter, 0); gBS->CopyMem (&YukonDriver->SnpMode.CurrentAddress, &YukonDriver->SnpMode.PermanentAddress, sizeof (EFI_MAC_ADDRESS));
- Status = mskc_init (); + Status = mskc_init (YukonDriver->Controller);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL; @@ -509,18 +509,18 @@ SnpReceive ( ) { EFI_STATUS Status; - YUKON_DRIVER *Snp; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This); + YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) { + switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -538,7 +538,7 @@ SnpReceive ( goto ON_EXIT; }
- Status = mskc_receive (BufferSize, Buffer); + Status = mskc_receive (YukonDriver->Controller, BufferSize, Buffer); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_READY) { goto ON_EXIT_NO_DEBUG; @@ -678,7 +678,7 @@ SnpReceiveFilters ( ) { EFI_STATUS Status; - YUKON_DRIVER *YukonDriver; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; UINT32 newReceiveFilter;
@@ -743,7 +743,7 @@ SnpReceiveFilters ( }
YukonDriver->SnpMode.ReceiveFilterSetting = newReceiveFilter; - mskc_rxfilter (YukonDriver->SnpMode.ReceiveFilterSetting, MCastFilterCnt, MCastFilter); + mskc_rxfilter (YukonDriver->Controller, YukonDriver->SnpMode.ReceiveFilterSetting, MCastFilterCnt, MCastFilter);
Status = EFI_SUCCESS; goto ON_EXIT; @@ -788,7 +788,7 @@ SnpReset ( ) { EFI_STATUS Status; - YUKON_DRIVER *YukonDriver; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpReset()\n")); @@ -858,7 +858,7 @@ SnpShutdown ( ) { EFI_STATUS Status; - YUKON_DRIVER *YukonDriver; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpShutdown()\n")); @@ -890,7 +890,7 @@ SnpShutdown ( goto ON_ERROR_RESTORE_TPL; }
- mskc_shutdown (); + mskc_shutdown (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStarted; Status = EFI_SUCCESS;
@@ -938,7 +938,7 @@ SnpStart ( IN EFI_SIMPLE_NETWORK_PROTOCOL *This ) { - YUKON_DRIVER *YukonDriver; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -966,7 +966,7 @@ SnpStart ( goto ON_ERROR_RESTORE_TPL; }
- Status = mskc_attach (YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress); + Status = mskc_attach (YukonDriver->Controller, YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL; @@ -1025,7 +1025,7 @@ SnpStationAddress ( IN EFI_MAC_ADDRESS *New OPTIONAL ) { - YUKON_DRIVER *YukonDriver; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -1122,7 +1122,7 @@ SnpStatistics ( ) { EFI_STATUS Status; - YUKON_DRIVER *YukonDriver; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStatistics()\n")); @@ -1242,7 +1242,7 @@ SnpStop ( ) { EFI_STATUS Status; - YUKON_DRIVER *YukonDriver; + YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStop()\n")); @@ -1269,7 +1269,7 @@ SnpStop ( goto ON_ERROR_RESTORE_TPL; }
- mskc_detach (); + mskc_detach (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStopped; gBS->SetMem (&YukonDriver->SnpMode.CurrentAddress, sizeof (EFI_MAC_ADDRESS), 0); Status = EFI_SUCCESS; @@ -1407,7 +1407,7 @@ SnpTransmit ( gBS->CopyMem (&Frame->EtherType, &ProtocolNet, sizeof (UINT16)); }
- Status = mskc_transmit (BufferSize, Buffer); + Status = mskc_transmit (YukonDriver->Controller, BufferSize, Buffer);
ON_EXIT: gBS->RestoreTPL (OldTpl); diff --git a/Drivers/Net/MarvellYukonDxe/e1000phy.c b/Drivers/Net/MarvellYukonDxe/e1000phy.c index dee4cdf..ca84138 100644 --- a/Drivers/Net/MarvellYukonDxe/e1000phy.c +++ b/Drivers/Net/MarvellYukonDxe/e1000phy.c @@ -57,6 +57,7 @@ #include <Library/MemoryAllocationLib.h> #include <Library/DebugLib.h> #include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseLib.h>
#include "if_media.h"
@@ -64,27 +65,30 @@
#include "e1000phyreg.h"
+static LIST_ENTRY e1000phy_drv_data_head; + +static void e1000phy_attach (const struct mii_attach_args *ma, EFI_HANDLE, struct e1000phy_softc *); static EFI_STATUS e1000phy_probe (const struct mii_attach_args *ma); -static void e1000phy_attach (const struct mii_attach_args *ma); static const struct mii_phydesc * mii_phy_match (const struct mii_attach_args *ma, const struct mii_phydesc *mpd); static const struct mii_phydesc * mii_phy_match_gen (const struct mii_attach_args *ma, const struct mii_phydesc *mpd, UINTN endlen); static EFI_STATUS mii_phy_dev_probe (const struct mii_attach_args *ma, const struct mii_phydesc *mpd);
-struct e1000phy_softc { - struct mii_softc mii_sc; - INTN mii_model; - const struct msk_mii_data *mmd; -}; +static EFI_STATUS e1000phy_get_ctrl_data_phy (EFI_HANDLE, INT32, struct e1000phy_softc **); +static EFI_STATUS e1000phy_add_ctrl_data (EFI_HANDLE, INT32, struct e1000phy_softc *); +static EFI_STATUS e1000phy_del_ctrl_data (EFI_HANDLE, INT32); +static EFI_STATUS e1000phy_find_drv_node (EFI_HANDLE, INT32, E1000PHY_LINKED_DRV_BUF**);
-struct e1000phy_softc *mPhySoftc; +void msk_miibus_statchg (INTN, EFI_HANDLE); +INTN msk_phy_readreg (INTN, INTN, EFI_HANDLE); +INTN msk_phy_writereg (INTN, INTN, INTN, EFI_HANDLE);
-static void mii_phy_update (INTN); -static void e1000phy_service (INTN); -static void e1000phy_status (struct mii_softc *); -static void e1000phy_reset (struct mii_softc *); -static void e1000phy_mii_phy_auto (void); +static void mii_phy_update (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_service (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_status (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_reset (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_mii_phy_auto (EFI_HANDLE, struct e1000phy_softc *);
static const struct mii_phydesc e1000phys[] = { MII_PHY_DESC (MARVELL, E1000), @@ -113,12 +117,15 @@ static const struct mii_phydesc e1000phys[] = { EFI_STATUS e1000_probe_and_attach ( struct mii_data *mii, - const struct msk_mii_data *mmd - ) + const struct msk_mii_data *mmd, + EFI_HANDLE mController, + INT32 mPort + ) { struct mii_attach_args ma; INTN bmsr; EFI_STATUS Status; + struct e1000phy_softc *mPhySoftc;
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct e1000phy_softc), @@ -129,13 +136,12 @@ e1000_probe_and_attach ( gBS->SetMem (mPhySoftc, sizeof (struct e1000phy_softc), 0); mPhySoftc->mmd = mmd;
- /* * Check to see if there is a PHY at this address. Note, * many braindead PHYs report 0/0 in their ID registers, * so we test for media in the BMSR. */ - bmsr = PHY_READ (mPhySoftc, E1000_SR); + bmsr = PHY_READ (mPhySoftc, E1000_SR, mController); if (bmsr == 0 || bmsr == 0xffff || (bmsr & (E1000_SR_EXTENDED_STATUS|E1000_SR_MEDIAMASK)) == 0) { /* Assume no PHY at this address. */ gBS->FreePool (mPhySoftc); @@ -145,8 +151,8 @@ e1000_probe_and_attach ( /* * Extract the IDs. */ - ma.mii_id1 = PHY_READ (mPhySoftc, E1000_ID1); - ma.mii_id2 = PHY_READ (mPhySoftc, E1000_ID2); + ma.mii_id1 = PHY_READ (mPhySoftc, E1000_ID1, mController); + ma.mii_id2 = PHY_READ (mPhySoftc, E1000_ID2, mController);
ma.mii_data = mii;
@@ -156,11 +162,36 @@ e1000_probe_and_attach ( return Status; }
- e1000phy_attach (&ma); + e1000phy_attach (&ma, mController, mPhySoftc); + + Status = e1000phy_add_ctrl_data (mController, mPort, mPhySoftc); + if (EFI_ERROR (Status)) { + gBS->FreePool (mPhySoftc); + return Status; + } + return EFI_SUCCESS; }
EFI_STATUS +e1000phy_dettach ( + EFI_HANDLE mController, + INT32 mPort + ) +{ + EFI_STATUS Status; + struct e1000phy_softc *mPhySoftc; + + Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc); + if (!EFI_ERROR (Status)) { + e1000phy_del_ctrl_data(mController, mPort); + gBS->FreePool(mPhySoftc); + } + + return Status; +} + +EFI_STATUS e1000phy_probe ( const struct mii_attach_args *ma ) @@ -170,7 +201,9 @@ e1000phy_probe (
static void e1000phy_attach ( - const struct mii_attach_args *ma + const struct mii_attach_args *ma, + EFI_HANDLE mController, + struct e1000phy_softc *mPhySoftc ) { struct mii_softc *sc; @@ -188,7 +221,7 @@ e1000phy_attach ( switch (mPhySoftc->mii_model) { case MII_MODEL_MARVELL_E1011: case MII_MODEL_MARVELL_E1112: - if (PHY_READ (mPhySoftc, E1000_ESSR) & E1000_ESSR_FIBER_LINK) { + if (PHY_READ (mPhySoftc, E1000_ESSR, mController) & E1000_ESSR_FIBER_LINK) { sc->mii_flags |= MIIF_HAVEFIBER; } break; @@ -204,46 +237,48 @@ e1000phy_attach ( * that information should be used to select default * type of PHY. */ - PHY_WRITE (mPhySoftc, E1000_EADR, 0); + PHY_WRITE (mPhySoftc, E1000_EADR, 0, mController); break; }
- e1000phy_reset (sc); + e1000phy_reset (sc, mController, mPhySoftc);
- sc->mii_capabilities = PHY_READ (mPhySoftc, E1000_SR) & 0xFFFFFFFF; + sc->mii_capabilities = PHY_READ (mPhySoftc, E1000_SR, mController) & 0xFFFFFFFF; if (sc->mii_capabilities & E1000_SR_EXTENDED_STATUS) { - sc->mii_extcapabilities = PHY_READ (mPhySoftc, E1000_ESR); + sc->mii_extcapabilities = PHY_READ (mPhySoftc, E1000_ESR, mController); } }
static void e1000phy_reset ( - struct mii_softc *sc + struct mii_softc *sc, + EFI_HANDLE mController, + struct e1000phy_softc *mPhySoftc ) { UINT16 reg; UINT16 page;
- reg = PHY_READ (mPhySoftc, E1000_SCR); + reg = PHY_READ (mPhySoftc, E1000_SCR, mController); if ((sc->mii_flags & MIIF_HAVEFIBER) != 0) { reg &= ~E1000_SCR_AUTO_X_MODE; - PHY_WRITE (mPhySoftc, E1000_SCR, reg); + PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); if (mPhySoftc->mii_model == MII_MODEL_MARVELL_E1112) { // Select 1000BASE-X only mode. - page = PHY_READ (mPhySoftc, E1000_EADR); - PHY_WRITE (mPhySoftc, E1000_EADR, 2); - reg = PHY_READ (mPhySoftc, E1000_SCR); + page = PHY_READ (mPhySoftc, E1000_EADR, mController); + PHY_WRITE (mPhySoftc, E1000_EADR, 2, mController); + reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg &= ~E1000_SCR_MODE_MASK; reg |= E1000_SCR_MODE_1000BX; - PHY_WRITE (mPhySoftc, E1000_SCR, reg); + PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); if (mPhySoftc->mmd != NULL && mPhySoftc->mmd->pmd == 'P') { // Set SIGDET polarity low for SFP module - PHY_WRITE (mPhySoftc, E1000_EADR, 1); - reg = PHY_READ (mPhySoftc, E1000_SCR); + PHY_WRITE (mPhySoftc, E1000_EADR, 1, mController); + reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg |= E1000_SCR_FIB_SIGDET_POLARITY; - PHY_WRITE (mPhySoftc, E1000_SCR, reg); + PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); } - PHY_WRITE (mPhySoftc, E1000_EADR, page); + PHY_WRITE (mPhySoftc, E1000_EADR, page, mController); } } else { switch (mPhySoftc->mii_model) { @@ -270,7 +305,7 @@ e1000phy_reset ( E1000_SCR_SCRAMBLER_DISABLE); reg |= E1000_SCR_LPNP; // XXX Enable class A driver for Yukon FE+ A0 - PHY_WRITE (mPhySoftc, 0x1C, PHY_READ (mPhySoftc, 0x1C) | 0x0001); + PHY_WRITE (mPhySoftc, 0x1C, PHY_READ (mPhySoftc, 0x1C, mController) | 0x0001, mController); break; default: reg &= ~E1000_SCR_AUTO_X_MODE; @@ -281,15 +316,15 @@ e1000phy_reset ( /* Auto correction for reversed cable polarity. */ reg &= ~E1000_SCR_POLARITY_REVERSAL; } - PHY_WRITE (mPhySoftc, E1000_SCR, reg); + PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController);
if (mPhySoftc->mii_model == MII_MODEL_MARVELL_E1116 || mPhySoftc->mii_model == MII_MODEL_MARVELL_E1149) { - PHY_WRITE (mPhySoftc, E1000_EADR, 2); - reg = PHY_READ (mPhySoftc, E1000_SCR); + PHY_WRITE (mPhySoftc, E1000_EADR, 2, mController); + reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg |= E1000_SCR_RGMII_POWER_UP; - PHY_WRITE (mPhySoftc, E1000_SCR, reg); - PHY_WRITE (mPhySoftc, E1000_EADR, 0); + PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); + PHY_WRITE (mPhySoftc, E1000_EADR, 0, mController); } }
@@ -299,42 +334,45 @@ e1000phy_reset ( case MII_MODEL_MARVELL_E1118: break; case MII_MODEL_MARVELL_E1116: - page = PHY_READ (mPhySoftc, E1000_EADR); + page = PHY_READ (mPhySoftc, E1000_EADR, mController); /* Select page 3, LED control register. */ - PHY_WRITE (mPhySoftc, E1000_EADR, 3); + PHY_WRITE (mPhySoftc, E1000_EADR, 3, mController); PHY_WRITE (mPhySoftc, E1000_SCR, E1000_SCR_LED_LOS (1) | /* Link/Act */ E1000_SCR_LED_INIT (8) | /* 10Mbps */ E1000_SCR_LED_STAT1 (7) | /* 100Mbps */ - E1000_SCR_LED_STAT0 (7)); /* 1000Mbps */ + E1000_SCR_LED_STAT0 (7), /* 1000Mbps */ + mController); /* Set blink rate. */ - PHY_WRITE (mPhySoftc, E1000_IER, E1000_PULSE_DUR (E1000_PULSE_170MS) | E1000_BLINK_RATE (E1000_BLINK_84MS)); - PHY_WRITE (mPhySoftc, E1000_EADR, page); + PHY_WRITE (mPhySoftc, E1000_IER, E1000_PULSE_DUR (E1000_PULSE_170MS) | E1000_BLINK_RATE (E1000_BLINK_84MS), mController); + PHY_WRITE (mPhySoftc, E1000_EADR, page, mController); break; case MII_MODEL_MARVELL_E3016: /* LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED. */ - PHY_WRITE (mPhySoftc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04); + PHY_WRITE (mPhySoftc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04, mController); /* Integrated register calibration workaround. */ - PHY_WRITE (mPhySoftc, 0x1D, 17); - PHY_WRITE (mPhySoftc, 0x1E, 0x3F60); + PHY_WRITE (mPhySoftc, 0x1D, 17, mController); + PHY_WRITE (mPhySoftc, 0x1E, 0x3F60, mController); break; default: /* Force TX_CLK to 25MHz clock. */ - reg = PHY_READ (mPhySoftc, E1000_ESCR); + reg = PHY_READ (mPhySoftc, E1000_ESCR, mController); reg |= E1000_ESCR_TX_CLK_25; - PHY_WRITE (mPhySoftc, E1000_ESCR, reg); + PHY_WRITE (mPhySoftc, E1000_ESCR, reg, mController); break; }
/* Reset the PHY so all changes take effect. */ - reg = PHY_READ (mPhySoftc, E1000_CR); + reg = PHY_READ (mPhySoftc, E1000_CR, mController); reg |= E1000_CR_RESET; - PHY_WRITE (mPhySoftc, E1000_CR, reg); + PHY_WRITE (mPhySoftc, E1000_CR, reg, mController); }
static void mii_phy_update ( - INTN cmd + INTN cmd, + EFI_HANDLE mController, + struct e1000phy_softc *mPhySoftc ) { struct mii_softc *sc = &mPhySoftc->mii_sc; @@ -344,7 +382,7 @@ mii_phy_update ( sc->mii_media_status != mii->mii_media_status || cmd == MII_MEDIACHG) { - msk_miibus_statchg (mPhySoftc->mmd->port); + msk_miibus_statchg (mPhySoftc->mmd->port, mController); sc->mii_media_active = mii->mii_media_active; sc->mii_media_status = mii->mii_media_status; } @@ -352,27 +390,43 @@ mii_phy_update (
void e1000phy_tick ( - VOID + EFI_HANDLE mController, + INT32 mPort ) { - e1000phy_service (MII_TICK); + EFI_STATUS Status; + struct e1000phy_softc *mPhySoftc; + + Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc); + if (!EFI_ERROR (Status)) { + e1000phy_service (MII_TICK, mController, mPhySoftc); + } }
void e1000phy_mediachg ( - VOID + EFI_HANDLE mController, + INT32 mPort ) { - struct mii_data *mii = mPhySoftc->mii_sc.mii_pdata; - mii->mii_media_status = 0; - mii->mii_media_active = IFM_NONE; - e1000phy_service (MII_MEDIACHG); + EFI_STATUS Status; + struct e1000phy_softc *mPhySoftc; + + Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc); + if (!EFI_ERROR (Status)) { + struct mii_data *mii = mPhySoftc->mii_sc.mii_pdata; + mii->mii_media_status = 0; + mii->mii_media_active = IFM_NONE; + e1000phy_service (MII_MEDIACHG, mController, mPhySoftc); + } }
static void e1000phy_service ( - INTN cmd - ) + INTN cmd, + EFI_HANDLE mController, + struct e1000phy_softc *mPhySoftc + ) { struct mii_softc *sc = &mPhySoftc->mii_sc; INTN reg; @@ -385,7 +439,7 @@ e1000phy_service ( // // Always try to auto-negotiate // - e1000phy_mii_phy_auto (); + e1000phy_mii_phy_auto (mController, mPhySoftc); break;
case MII_TICK: @@ -393,7 +447,7 @@ e1000phy_service ( * check for link. * Read the status register twice; Link Status is latch-low. */ - reg = PHY_READ (mPhySoftc, E1000_SR) | PHY_READ (mPhySoftc, E1000_SR); + reg = PHY_READ (mPhySoftc, E1000_SR, mController) | PHY_READ (mPhySoftc, E1000_SR, mController); if (reg & E1000_SR_LINK_STATUS) { sc->mii_ticks = 0; break; @@ -411,21 +465,23 @@ e1000phy_service ( // Restart the auto-negotiation // sc->mii_ticks = 0; - e1000phy_reset (sc); - e1000phy_mii_phy_auto (); + e1000phy_reset (sc, mController, mPhySoftc); + e1000phy_mii_phy_auto (mController, mPhySoftc); break; }
/* Update the media status. */ - e1000phy_status (sc); + e1000phy_status (sc, mController, mPhySoftc);
/* Callback if something changed. */ - mii_phy_update (cmd); + mii_phy_update (cmd, mController, mPhySoftc); }
static void e1000phy_status ( - struct mii_softc *sc + struct mii_softc *sc, + EFI_HANDLE mController, + struct e1000phy_softc *mPhySoftc ) { struct mii_data *mii = sc->mii_pdata; @@ -439,9 +495,9 @@ e1000phy_status ( mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER;
- bmsr = PHY_READ (mPhySoftc, E1000_SR) | PHY_READ (mPhySoftc, E1000_SR); - bmcr = PHY_READ (mPhySoftc, E1000_CR); - ssr = PHY_READ (mPhySoftc, E1000_SSR); + bmsr = PHY_READ (mPhySoftc, E1000_SR, mController) | PHY_READ (mPhySoftc, E1000_SR, mController); + bmcr = PHY_READ (mPhySoftc, E1000_CR, mController); + ssr = PHY_READ (mPhySoftc, E1000_SSR, mController);
if (bmsr & E1000_SR_LINK_STATUS) { DEBUG ((EFI_D_NET, "Marvell Yukon: e1000phy_status, link up\n")); @@ -489,8 +545,8 @@ e1000phy_status ( }
if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { - ar = PHY_READ (mPhySoftc, E1000_AR); - lpar = PHY_READ (mPhySoftc, E1000_LPAR); + ar = PHY_READ (mPhySoftc, E1000_AR, mController); + lpar = PHY_READ (mPhySoftc, E1000_LPAR, mController); /* FLAG0==rx-flow-control FLAG1==tx-flow-control */ if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) { mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1; @@ -506,8 +562,8 @@ e1000phy_status ( /* FLAG2 : local PHY resolved to MASTER */ if ((IFM_SUBTYPE (mii->mii_media_active) == IFM_1000_T) || (IFM_SUBTYPE (mii->mii_media_active) == IFM_1000_SX)) { - PHY_READ (mPhySoftc, E1000_1GSR); - gsr = PHY_READ (mPhySoftc, E1000_1GSR); + PHY_READ (mPhySoftc, E1000_1GSR, mController); + gsr = PHY_READ (mPhySoftc, E1000_1GSR, mController); if ((gsr & E1000_1GSR_MS_CONFIG_RES) != 0) { mii->mii_media_active |= IFM_FLAG2; } @@ -516,7 +572,8 @@ e1000phy_status (
static void e1000phy_mii_phy_auto ( - VOID + EFI_HANDLE mController, + struct e1000phy_softc *mPhySoftc ) { struct mii_softc *sc; @@ -525,20 +582,20 @@ e1000phy_mii_phy_auto ( DEBUG ((EFI_D_NET, "Marvell Yukon: e1000phy_mii_phy_auto negotiation started\n")); sc = &mPhySoftc->mii_sc; if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { - reg = PHY_READ (mPhySoftc, E1000_AR); + reg = PHY_READ (mPhySoftc, E1000_AR, mController); reg |= E1000_AR_10T | E1000_AR_10T_FD | E1000_AR_100TX | E1000_AR_100TX_FD | E1000_AR_PAUSE | E1000_AR_ASM_DIR; - PHY_WRITE (mPhySoftc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD); + PHY_WRITE (mPhySoftc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD, mController); } else { - PHY_WRITE (mPhySoftc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE); + PHY_WRITE (mPhySoftc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE, mController); }
if ((sc->mii_extcapabilities & (E1000_ESR_1000T_FD | E1000_ESR_1000T)) != 0) { - PHY_WRITE (mPhySoftc, E1000_1GCR, E1000_1GCR_1000T_FD | E1000_1GCR_1000T); + PHY_WRITE (mPhySoftc, E1000_1GCR, E1000_1GCR_1000T_FD | E1000_1GCR_1000T, mController); }
- PHY_WRITE (mPhySoftc, E1000_CR, E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG); + PHY_WRITE (mPhySoftc, E1000_CR, E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG, mController); }
// @@ -589,3 +646,106 @@ mii_phy_dev_probe ( DEBUG ((EFI_D_NET, "Marvell Yukon: PHY not found (OUI=0x%x, MODEL=0x%x)\n", MII_OUI (ma->mii_id1, ma->mii_id2), MII_MODEL (ma->mii_id2))); return EFI_NOT_FOUND; } + +void +e1000phy_init_driver_list (void) +{ + InitializeListHead (&e1000phy_drv_data_head); +} + +static +EFI_STATUS +e1000phy_get_ctrl_data_phy ( + EFI_HANDLE mController, + INT32 mPort, + struct e1000phy_softc **mPhySoftc + ) +{ + E1000PHY_LINKED_DRV_BUF *mDrvNode; + EFI_STATUS Status; + + Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode); + if (!EFI_ERROR(Status)) { + *mPhySoftc = mDrvNode->mPhySoftc; + } + + return Status; +} + +static +EFI_STATUS +e1000phy_add_ctrl_data ( + EFI_HANDLE mController, + INT32 mPort, + struct e1000phy_softc *mPhySoftc + ) +{ + E1000PHY_LINKED_DRV_BUF *mDrvNode; + EFI_STATUS Status; + + Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode); + if (EFI_ERROR(Status)) { + Status = gBS->AllocatePool (EfiBootServicesData, + sizeof (E1000PHY_LINKED_DRV_BUF), + (VOID**) &mDrvNode); + if (!EFI_ERROR (Status)) { + mDrvNode->Signature = E1000PHY_DRV_SIGNATURE; + mDrvNode->mController = mController; + mDrvNode->mPort = mPort; + mDrvNode->mPhySoftc = mPhySoftc; + InsertTailList (&e1000phy_drv_data_head, &mDrvNode->Link); + } + } else { + Status = EFI_ALREADY_STARTED; + } + + return Status; +} + +static +EFI_STATUS +e1000phy_del_ctrl_data ( + EFI_HANDLE mController, + INT32 mPort + ) +{ + E1000PHY_LINKED_DRV_BUF *mDrvNode; + EFI_STATUS Status; + + Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode); + if (!EFI_ERROR(Status)) { + RemoveEntryList (&mDrvNode->Link); + gBS->FreePool (mDrvNode); + } + + return Status; +} + +static +EFI_STATUS +e1000phy_find_drv_node ( + EFI_HANDLE mController, + INT32 mPort, + E1000PHY_LINKED_DRV_BUF **mDrvNode + ) +{ + E1000PHY_LINKED_DRV_BUF *mDrvBuffNode; + EFI_STATUS Status; + LIST_ENTRY *Node; + + Status = EFI_NOT_FOUND; + + Node = GetFirstNode (&e1000phy_drv_data_head); + while (!IsNull (&e1000phy_drv_data_head, Node)) { + mDrvBuffNode = E1000PHY_DRV_INFO_FROM_THIS (Node); + if (mDrvBuffNode->mController == mController && + mDrvBuffNode->mPort == mPort) { + *mDrvNode = mDrvBuffNode; + Status = EFI_SUCCESS; + break; + } + Node = GetNextNode (&e1000phy_drv_data_head, Node); + } + + return Status; +} diff --git a/Drivers/Net/MarvellYukonDxe/e1000phyreg.h b/Drivers/Net/MarvellYukonDxe/e1000phyreg.h index a87b1f1..d0bfd25 100644 --- a/Drivers/Net/MarvellYukonDxe/e1000phyreg.h +++ b/Drivers/Net/MarvellYukonDxe/e1000phyreg.h @@ -396,3 +396,26 @@ #define E1000_ESSR_GMII_FIBER 0x0007 #define E1000_ESSR_TBI_COPPER 0x000d #define E1000_ESSR_TBI_FIBER 0x0005 + +struct e1000phy_softc { + struct mii_softc mii_sc; + INTN mii_model; + const struct msk_mii_data *mmd; +}; + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + INT32 mPort; + EFI_HANDLE mController; + struct e1000phy_softc *mPhySoftc; +} E1000PHY_LINKED_DRV_BUF; + +#define E1000PHY_DRV_SIGNATURE SIGNATURE_32 ('e', 'p', 'h', 'y') + +#define E1000PHY_DRV_INFO_FROM_THIS(a) \ + CR (a, \ + E1000PHY_LINKED_DRV_BUF, \ + Link, \ + E1000PHY_DRV_SIGNATURE \ + ); diff --git a/Drivers/Net/MarvellYukonDxe/if_msk.c b/Drivers/Net/MarvellYukonDxe/if_msk.c index d23f893..3f41d45 100644 --- a/Drivers/Net/MarvellYukonDxe/if_msk.c +++ b/Drivers/Net/MarvellYukonDxe/if_msk.c @@ -121,11 +121,7 @@ #include "if_mskreg.h" #include "if_msk.h"
-// -// Global Variables -// -static EFI_PCI_IO_PROTOCOL *mPciIo; -static struct msk_softc *mSoftc; +static LIST_ENTRY msk_drv_data_head;
#define MSK_CSUM_FEATURES (CSUM_TCP | CSUM_UDP)
@@ -189,49 +185,67 @@ static const CHAR8 *model_name[] = { // // Forward declarations // -static VOID mskc_setup_rambuffer (VOID); -static VOID mskc_reset (VOID); +static VOID mskc_setup_rambuffer (struct msk_softc *); +static VOID mskc_reset (EFI_PCI_IO_PROTOCOL *, struct msk_softc *);
-static EFI_STATUS msk_attach (INT32); -static VOID msk_detach (INT32); +static EFI_STATUS msk_attach (INT32, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_detach (INT32, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *);
static VOID mskc_tick (IN EFI_EVENT, IN VOID*); -static VOID msk_intr (VOID); -static VOID msk_intr_phy (struct msk_if_softc *); -static VOID msk_intr_gmac (struct msk_if_softc *); -static __inline VOID msk_rxput (struct msk_if_softc *); -static INTN msk_handle_events (VOID); -static VOID msk_handle_hwerr (struct msk_if_softc *, UINT32); -static VOID msk_intr_hwerr (VOID); -static VOID msk_rxeof (struct msk_if_softc *, UINT32, UINT32, INTN); -static VOID msk_txeof (struct msk_if_softc *, INTN); -static EFI_STATUS msk_encap (struct msk_if_softc *, MSK_SYSTEM_BUF *); -static VOID msk_start (INT32); -static VOID msk_set_prefetch (INTN, EFI_PHYSICAL_ADDRESS, UINT32); -static VOID msk_set_rambuffer (struct msk_if_softc *); -static VOID msk_set_tx_stfwd (struct msk_if_softc *); -static EFI_STATUS msk_init (struct msk_if_softc *); -static VOID msk_stop (struct msk_if_softc *); +static VOID msk_intr (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_intr_phy (struct msk_if_softc *, EFI_HANDLE); +static VOID msk_intr_gmac (struct msk_if_softc *, struct msk_softc *); +static __inline VOID msk_rxput (struct msk_if_softc *, struct msk_softc *); +static INTN msk_handle_events (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_handle_hwerr (struct msk_if_softc *, UINT32, struct msk_softc *); +static VOID msk_intr_hwerr (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_rxeof (struct msk_if_softc *, UINT32, UINT32, INTN, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_txeof (struct msk_if_softc *, INTN, EFI_PCI_IO_PROTOCOL *); +static EFI_STATUS msk_encap (struct msk_if_softc *, MSK_SYSTEM_BUF *, EFI_PCI_IO_PROTOCOL *); +static VOID msk_start (INT32, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_set_prefetch (INTN, EFI_PHYSICAL_ADDRESS, UINT32, struct msk_softc *); +static VOID msk_set_rambuffer (struct msk_if_softc *, struct msk_softc *); +static VOID msk_set_tx_stfwd (struct msk_if_softc *, struct msk_softc *); +static EFI_STATUS msk_init (struct msk_if_softc *, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_stop (struct msk_if_softc *, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); static VOID msk_phy_power (struct msk_softc *, INTN); -static EFI_STATUS msk_status_dma_alloc (VOID); -static VOID msk_status_dma_free (VOID); -static EFI_STATUS msk_txrx_dma_alloc (struct msk_if_softc *); -static VOID msk_txrx_dma_free (struct msk_if_softc *); -static EFI_STATUS msk_init_rx_ring (struct msk_if_softc *); +INTN msk_phy_readreg (INTN, INTN, EFI_HANDLE); +INTN msk_phy_writereg (INTN, INTN, INTN, EFI_HANDLE); +static EFI_STATUS msk_status_dma_alloc (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_status_dma_free (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static EFI_STATUS msk_txrx_dma_alloc (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *); +static VOID msk_txrx_dma_free (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *); +static EFI_STATUS msk_init_rx_ring (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); static VOID msk_init_tx_ring (struct msk_if_softc *); static __inline VOID msk_discard_rxbuf (struct msk_if_softc *, INTN); -static EFI_STATUS msk_newbuf (struct msk_if_softc *, INTN); +static EFI_STATUS msk_newbuf (struct msk_if_softc *, INTN, EFI_PCI_IO_PROTOCOL *);
static VOID msk_rxfilter ( struct msk_if_softc *sc_if, UINT32 FilterFlags, UINTN MCastFilterCnt, - EFI_MAC_ADDRESS *MCastFilter + EFI_MAC_ADDRESS *MCastFilter, + EFI_HANDLE mController ); -static VOID msk_setvlan (struct msk_if_softc *); - -static VOID msk_stats_clear (struct msk_if_softc *); -static VOID msk_stats_update (struct msk_if_softc *); +static VOID msk_setvlan (struct msk_if_softc *, struct msk_softc *); + +static VOID msk_stats_clear (struct msk_if_softc *, struct msk_softc *); +static VOID msk_stats_update (struct msk_if_softc *, struct msk_softc *); +static VOID clear_pci_errors (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); + +EFI_STATUS e1000_probe_and_attach (struct mii_data *, const struct msk_mii_data *, EFI_HANDLE, INT32); +void e1000phy_tick (EFI_HANDLE, INT32); +void e1000phy_mediachg (EFI_HANDLE, INT32); +void e1000phy_init_driver_list (void); +EFI_STATUS e1000phy_dettach (EFI_HANDLE, INT32); + +static EFI_STATUS msk_get_ctrl_data (EFI_HANDLE, EFI_PCI_IO_PROTOCOL **, + struct msk_softc **); +static EFI_STATUS msk_get_ctrl_data_msks (EFI_HANDLE, struct msk_softc **); +static EFI_STATUS msk_add_ctrl_data (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, + struct msk_softc *); +static EFI_STATUS msk_del_ctrl_data (EFI_HANDLE); +static EFI_STATUS msk_find_drv_node (EFI_HANDLE, MSK_LINKED_DRV_BUF **);
// // Functions @@ -239,12 +253,20 @@ static VOID msk_stats_update (struct msk_if_softc *);
INTN msk_phy_readreg ( - INTN port, - INTN reg + INTN port, + INTN reg, + EFI_HANDLE mController ) { - INTN i; - INTN val; + INTN i; + INTN val; + EFI_STATUS Status; + struct msk_softc *mSoftc; + + Status = msk_get_ctrl_data_msks (mController, &mSoftc); + if (EFI_ERROR (Status)) { + return 0; + }
GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
@@ -267,12 +289,20 @@ msk_phy_readreg (
INTN msk_phy_writereg ( - INTN port, - INTN reg, - INTN val + INTN port, + INTN reg, + INTN val, + EFI_HANDLE mController ) { INTN i; + EFI_STATUS Status; + struct msk_softc *mSoftc; + + Status = msk_get_ctrl_data_msks (mController, &mSoftc); + if (EFI_ERROR (Status)) { + return 0; + }
GMAC_WRITE_2 (mSoftc, port, GM_SMI_DATA, val); GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg)); @@ -291,13 +321,23 @@ msk_phy_writereg (
VOID msk_miibus_statchg ( - INTN port + INTN port, + EFI_HANDLE mController ) { - struct msk_if_softc *sc_if = mSoftc->msk_if[port]; - struct mii_data *mii = &sc_if->mii_d; + struct msk_if_softc *sc_if; + struct mii_data *mii; UINT32 gmac; + EFI_STATUS Status; + struct msk_softc *mSoftc; + + Status = msk_get_ctrl_data_msks (mController, &mSoftc); + if (EFI_ERROR (Status)) { + return; + }
+ sc_if = mSoftc->msk_if[port]; + mii = &sc_if->mii_d; sc_if->msk_flags &= ~MSK_FLAG_LINK;
if ((mii->mii_media_status & (IFM_AVALID | IFM_ACTIVE)) == (IFM_AVALID | IFM_ACTIVE)) { @@ -370,14 +410,14 @@ msk_miibus_statchg ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, GMAC_CTRL), gmac);
// Enable PHY interrupt for FIFO underrun/overflow - msk_phy_writereg (port, PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR); + msk_phy_writereg (port, PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR, mController); } else { // // Link state changed to down. // Disable PHY interrupts. // DEBUG ((EFI_D_NET, "Marvell Yukon: msk_miibus_statchg, link down\n")); - msk_phy_writereg (port, PHY_MARV_INT_MASK, 0); + msk_phy_writereg (port, PHY_MARV_INT_MASK, 0, mController); // Disable Rx/Tx MAC gmac = GMAC_READ_2 (mSoftc, port, GM_GP_CTRL); if ((GM_GPCR_RX_ENA | GM_GPCR_TX_ENA) != 0) { @@ -418,12 +458,21 @@ ether_crc32_be (
VOID mskc_rxfilter ( + EFI_HANDLE mController, UINT32 FilterFlags, UINTN MCastFilterCnt, EFI_MAC_ADDRESS *MCastFilter ) { - msk_rxfilter (mSoftc->msk_if[MSK_PORT_A], FilterFlags, MCastFilterCnt, MCastFilter); + EFI_STATUS Status; + struct msk_softc *mSoftc; + + Status = msk_get_ctrl_data_msks (mController, &mSoftc); + if (EFI_ERROR (Status)) { + return; + } + + msk_rxfilter (mSoftc->msk_if[MSK_PORT_A], FilterFlags, MCastFilterCnt, MCastFilter, mController); }
static VOID @@ -431,13 +480,21 @@ msk_rxfilter ( struct msk_if_softc *sc_if, UINT32 FilterFlags, UINTN MCastFilterCnt, - EFI_MAC_ADDRESS *MCastFilter + EFI_MAC_ADDRESS *MCastFilter, + EFI_HANDLE mController ) { - UINT32 mchash[2]; - UINT32 crc; - UINT16 mode; - INTN port = sc_if->msk_md.port; + UINT32 mchash[2]; + UINT32 crc; + UINT16 mode; + INTN port = sc_if->msk_md.port; + EFI_STATUS Status; + struct msk_softc *mSoftc; + + Status = msk_get_ctrl_data_msks (mController, &mSoftc); + if (EFI_ERROR (Status)) { + return; + }
gBS->SetMem (mchash, sizeof (mchash), 0); mode = GMAC_READ_2 (mSoftc, port, GM_RX_CTRL); @@ -472,7 +529,8 @@ msk_rxfilter ( static VOID msk_setvlan ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + struct msk_softc *mSoftc ) { // @@ -485,7 +543,9 @@ msk_setvlan ( static EFI_STATUS msk_init_rx_ring ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { struct msk_ring_data *rd; @@ -511,7 +571,7 @@ msk_init_rx_ring ( prod = 0;
for (i = 0; i < nbuf; i++) { - Status = msk_newbuf (sc_if, prod); + Status = msk_newbuf (sc_if, prod, mPciIo); if (EFI_ERROR (Status)) { return Status; } @@ -580,7 +640,8 @@ static EFI_STATUS msk_newbuf ( IN struct msk_if_softc *sc_if, - IN INTN idx + IN INTN idx, + EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_rx_desc *rx_le; @@ -663,7 +724,7 @@ mskc_probe ( static VOID mskc_setup_rambuffer ( - VOID + struct msk_softc *mSoftc ) { INTN next; @@ -811,7 +872,8 @@ msk_phy_power ( static VOID clear_pci_errors ( - VOID + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { EFI_STATUS Status; @@ -847,7 +909,8 @@ clear_pci_errors ( static VOID mskc_reset ( - VOID + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { EFI_STATUS Status; @@ -877,7 +940,7 @@ mskc_reset ( CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_SET); CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_CLR);
- clear_pci_errors (); + clear_pci_errors (mPciIo, mSoftc); switch (mSoftc->msk_bustype) { case MSK_PEX_BUS: // Clear all PEX errors @@ -1055,7 +1118,10 @@ mskc_reset ( static EFI_STATUS msk_attach ( - INT32 Port + INT32 Port, + EFI_HANDLE mController, + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if; @@ -1077,7 +1143,7 @@ msk_attach ( sc_if->msk_rxq = Q_R2; }
- Status = msk_txrx_dma_alloc (sc_if); + Status = msk_txrx_dma_alloc (sc_if, mPciIo); if (EFI_ERROR (Status)) { return Status; } @@ -1099,10 +1165,10 @@ msk_attach ( sc_if->MacAddress.Addr[0], sc_if->MacAddress.Addr[1], sc_if->MacAddress.Addr[2], sc_if->MacAddress.Addr[3], sc_if->MacAddress.Addr[4], sc_if->MacAddress.Addr[5]));
- Status = e1000_probe_and_attach (&sc_if->mii_d, &sc_if->msk_md); + Status = e1000_probe_and_attach (&sc_if->mii_d, &sc_if->msk_md, mController, Port); if (EFI_ERROR (Status)) { mSoftc->msk_if[Port] = NULL; - msk_detach (Port); + msk_detach (Port, mController, mPciIo, mSoftc); }
return (Status); @@ -1114,7 +1180,8 @@ msk_attach ( */ EFI_STATUS mskc_attach ( - IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_HANDLE mController, + IN EFI_PCI_IO_PROTOCOL *mPciIo, OUT EFI_MAC_ADDRESS *Mac ) { @@ -1123,8 +1190,8 @@ mskc_attach ( UINT8 *PciBarResources; EFI_STATUS Status; struct msk_if_softc *ScIf; + struct msk_softc *mSoftc;
- mPciIo = PciIo; Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct msk_softc), (VOID**) &mSoftc); @@ -1295,7 +1362,7 @@ mskc_attach ( break; }
- Status = msk_status_dma_alloc (); + Status = msk_status_dma_alloc (mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; } @@ -1305,9 +1372,9 @@ mskc_attach ( mSoftc->msk_intrhwemask = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT | Y2_IS_PCI_EXP | Y2_IS_PCI_NEXP;
// Reset the adapter - mskc_reset (); + mskc_reset (mPciIo, mSoftc);
- mskc_setup_rambuffer (); + mskc_setup_rambuffer (mSoftc);
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct msk_if_softc), @@ -1315,9 +1382,16 @@ mskc_attach ( if (EFI_ERROR (Status)) { goto fail; } + + //Add controller to the list + Status = msk_add_ctrl_data (mController, mPciIo, mSoftc); + if (EFI_ERROR (Status)) { + goto fail; + } + gBS->SetMem (ScIf, sizeof (struct msk_if_softc), 0); mSoftc->msk_if[MSK_PORT_A] = ScIf; - Status = msk_attach (MSK_PORT_A); + Status = msk_attach (MSK_PORT_A, mController, mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; } @@ -1342,7 +1416,7 @@ mskc_attach ( } gBS->SetMem (ScIf, sizeof (struct msk_if_softc), 0); mSoftc->msk_if[MSK_PORT_B] = ScIf; - Status = msk_attach (MSK_PORT_B); + Status = msk_attach (MSK_PORT_B, mController, mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; } @@ -1360,7 +1434,7 @@ mskc_attach ( EVT_NOTIFY_SIGNAL | EVT_TIMER, TPL_CALLBACK, mskc_tick, - mSoftc, + (VOID *)mController, &mSoftc->Timer ); if (EFI_ERROR (Status)) { @@ -1373,7 +1447,7 @@ mskc_attach (
fail: if (EFI_ERROR (Status)) { - mskc_detach (); + mskc_detach (mController); }
return (Status); @@ -1382,7 +1456,7 @@ RESTORE_PCI_ATTRIBS: // // Restore original PCI attributes // - mPciIo->Attributes ( +mPciIo->Attributes ( mPciIo, EfiPciIoAttributeOperationSet, mSoftc->OriginalPciAttributes, @@ -1402,34 +1476,47 @@ RESTORE_PCI_ATTRIBS: static VOID msk_detach ( - INT32 Port + INT32 Port, + EFI_HANDLE mController, + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if;
sc_if = mSoftc->msk_if[Port];
- msk_stop (sc_if); + msk_stop (sc_if, mController, mPciIo, mSoftc);
- msk_txrx_dma_free (sc_if); + msk_txrx_dma_free (sc_if, mPciIo); + + e1000phy_dettach (mController, Port); }
VOID mskc_detach ( - VOID + EFI_HANDLE mController ) { - EFI_TPL OldTpl; + EFI_TPL OldTpl; + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *mPciIo; + struct msk_softc *mSoftc;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+ Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); + if (EFI_ERROR (Status)) { + return; + } + if (mSoftc->msk_if[MSK_PORT_A] != NULL) { - msk_detach (MSK_PORT_A); + msk_detach (MSK_PORT_A, mController, mPciIo, mSoftc); gBS->FreePool (mSoftc->msk_if[MSK_PORT_A]); mSoftc->msk_if[MSK_PORT_A] = NULL; } if (mSoftc->msk_if[MSK_PORT_B] != NULL) { - msk_detach (MSK_PORT_B); + msk_detach (MSK_PORT_B, mController, mPciIo, mSoftc); gBS->FreePool (mSoftc->msk_if[MSK_PORT_B]); mSoftc->msk_if[MSK_PORT_B] = NULL; } @@ -1446,7 +1533,7 @@ mskc_detach ( // Put hardware reset. CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_SET);
- msk_status_dma_free (); + msk_status_dma_free (mPciIo, mSoftc);
if (mSoftc->Timer != NULL) { gBS->SetTimer (mSoftc->Timer, TimerCancel, 0); @@ -1463,9 +1550,8 @@ mskc_detach ( mSoftc->OriginalPciAttributes, NULL ); + msk_del_ctrl_data (mController); gBS->FreePool (mSoftc); - mSoftc = NULL; - mPciIo = NULL;
gBS->RestoreTPL (OldTpl); } @@ -1474,7 +1560,8 @@ mskc_detach ( static EFI_STATUS msk_status_dma_alloc ( - VOID + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { EFI_STATUS Status; @@ -1504,7 +1591,8 @@ msk_status_dma_alloc ( static VOID msk_status_dma_free ( - VOID + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { if (mSoftc->msk_stat_map) { @@ -1520,7 +1608,8 @@ msk_status_dma_free ( static EFI_STATUS msk_txrx_dma_alloc ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd; @@ -1585,7 +1674,8 @@ fail: static VOID msk_txrx_dma_free ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd; @@ -1640,7 +1730,8 @@ static EFI_STATUS msk_encap ( struct msk_if_softc *sc_if, - MSK_SYSTEM_BUF *m_head + MSK_SYSTEM_BUF *m_head, + EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd; @@ -1713,12 +1804,20 @@ msk_encap (
EFI_STATUS mskc_transmit ( - UINTN BufferSize, - VOID *Buffer + EFI_HANDLE mController, + UINTN BufferSize, + VOID *Buffer ) { MSK_LINKED_SYSTEM_BUF *LinkedSystemBuf; EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *mPciIo; + struct msk_softc *mSoftc; + + Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); + if (EFI_ERROR (Status)) { + return Status; + }
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (MSK_LINKED_SYSTEM_BUF), @@ -1734,23 +1833,33 @@ mskc_transmit ( LinkedSystemBuf->SystemBuf.Buf = Buffer; LinkedSystemBuf->SystemBuf.Length = BufferSize; InsertTailList (&mSoftc->TransmitQueueHead, &LinkedSystemBuf->Link); - msk_start (MSK_PORT_A); + //Force to use the first MAC + //TODO: enable multi MAC support + msk_start (MSK_PORT_A, mPciIo, mSoftc); return EFI_SUCCESS; }
void mskc_getstatus ( + IN EFI_HANDLE mController, OUT UINT32 *InterruptStatus, OPTIONAL OUT VOID **TxBuf OPTIONAL ) { - //struct msk_chain_data* cdata; MSK_LINKED_SYSTEM_BUF *m_head; + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *mPciIo; + struct msk_softc *mSoftc; + + Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); + if (EFI_ERROR (Status)) { + return; + }
// Interrupt status is not read from the device when InterruptStatus is NULL if (InterruptStatus != NULL) { // Check the interrupt lines - msk_intr (); + msk_intr (mController, mPciIo, mSoftc); }
// The transmit buffer status is not read when TxBuf is NULL @@ -1771,7 +1880,9 @@ mskc_getstatus ( static VOID msk_start ( - INT32 Port + INT32 Port, + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { EFI_STATUS Status; @@ -1793,7 +1904,7 @@ msk_start ( // don't have room, set the OACTIVE flag and wait // for the NIC to drain the ring. // - Status = msk_encap (sc_if, &m_head->SystemBuf); + Status = msk_encap (sc_if, &m_head->SystemBuf, mPciIo); if (EFI_ERROR (Status)) { break; } @@ -1811,17 +1922,25 @@ msk_start (
VOID mskc_shutdown ( - VOID + EFI_HANDLE mController ) { - INTN i; - EFI_TPL OldTpl; + INTN i; + EFI_TPL OldTpl; + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *mPciIo; + struct msk_softc *mSoftc;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+ Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); + if (EFI_ERROR (Status)) { + return; + } + for (i = 0; i < mSoftc->msk_num_port; i++) { if (mSoftc->msk_if[i] != NULL) { - msk_stop (mSoftc->msk_if[i]); + msk_stop (mSoftc->msk_if[i], mController, mPciIo, mSoftc); } } gBS->SetTimer (mSoftc->Timer, TimerCancel, 0); @@ -1834,13 +1953,22 @@ mskc_shutdown (
EFI_STATUS mskc_receive ( + IN EFI_HANDLE mController, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { MSK_LINKED_SYSTEM_BUF *mBuf; + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *mPciIo; + struct msk_softc *mSoftc; + + Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); + if (EFI_ERROR (Status)) { + return Status; + }
- msk_intr (); // check the interrupt lines + msk_intr (mController, mPciIo, mSoftc); // check the interrupt lines
if (IsListEmpty (&mSoftc->ReceiveQueueHead)) { *BufferSize = 0; @@ -1859,6 +1987,7 @@ mskc_receive ( gBS->CopyMem (Buffer, mBuf->SystemBuf.Buf, *BufferSize); gBS->FreePool(mBuf->SystemBuf.Buf); gBS->FreePool (mBuf); + return EFI_SUCCESS; }
@@ -1867,7 +1996,9 @@ msk_rxeof ( struct msk_if_softc *sc_if, UINT32 status, UINT32 control, - INTN len + INTN len, + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { EFI_STATUS Status; @@ -1909,7 +2040,7 @@ msk_rxeof ( m.DmaMapping = rxd->rx_m.DmaMapping; m.Length = rxd->rx_m.Length;
- Status = msk_newbuf (sc_if, cons); + Status = msk_newbuf (sc_if, cons, mPciIo); if (EFI_ERROR (Status)) { // This is a dropped packet, but we aren't counting drops // Reuse old buffer @@ -1951,7 +2082,8 @@ static VOID msk_txeof ( struct msk_if_softc *sc_if, - INTN idx + INTN idx, + EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd; @@ -1997,11 +2129,23 @@ mskc_tick ( ) { EFI_TPL OldTpl; + EFI_PCI_IO_PROTOCOL *mPciIo; + struct msk_softc *mSoftc; + EFI_STATUS Status; + EFI_HANDLE mController;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- e1000phy_tick (); - msk_handle_events (); + mController = (EFI_HANDLE)Context; + Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); + if (!EFI_ERROR (Status)) { + //TODO: enable multi MAC support + if (mSoftc->msk_if[MSK_PORT_A] != NULL) { + e1000phy_tick (mController, MSK_PORT_A); + } + + msk_handle_events (mPciIo, mSoftc); + }
gBS->RestoreTPL (OldTpl); } @@ -2009,13 +2153,14 @@ mskc_tick ( static VOID msk_intr_phy ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + EFI_HANDLE mController ) { UINT16 status;
- msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT); - status = msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT); + msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT, mController); + status = msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT, mController);
// Handle FIFO Underrun/Overflow ? if ((status & PHY_M_IS_FIFO_ERROR)) { @@ -2026,7 +2171,8 @@ msk_intr_phy ( static VOID msk_intr_gmac ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + struct msk_softc *mSoftc ) { UINT8 status; @@ -2059,7 +2205,8 @@ static VOID msk_handle_hwerr ( struct msk_if_softc *sc_if, - UINT32 status + UINT32 status, + struct msk_softc *mSoftc ) { if ((status & Y2_IS_PAR_RD1) != 0) { @@ -2092,7 +2239,8 @@ msk_handle_hwerr ( static VOID msk_intr_hwerr ( - VOID + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { UINT32 status; @@ -2123,7 +2271,7 @@ msk_intr_hwerr ( DEBUG ((EFI_D_NET, "Marvell Yukon: unexpected IRQ Master error\n")); } // Reset all bits in the PCI status register - clear_pci_errors (); + clear_pci_errors (mPciIo, mSoftc); }
// Check for PCI Express Uncorrectable Error. @@ -2164,10 +2312,10 @@ msk_intr_hwerr ( }
if ((status & Y2_HWE_L1_MASK) != 0 && mSoftc->msk_if[MSK_PORT_A] != NULL) { - msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_A], status); + msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_A], status, mSoftc); } if ((status & Y2_HWE_L2_MASK) != 0 && mSoftc->msk_if[MSK_PORT_B] != NULL) { - msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_B], status >> 8); + msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_B], status >> 8, mSoftc); } }
@@ -2175,7 +2323,8 @@ static __inline VOID msk_rxput ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + struct msk_softc *mSoftc ) { CSR_WRITE_2 (mSoftc, Y2_PREF_Q_ADDR (sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG), sc_if->msk_cdata.msk_rx_prod); @@ -2184,7 +2333,8 @@ msk_rxput ( static INTN msk_handle_events ( - VOID + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if; @@ -2223,7 +2373,7 @@ msk_handle_events (
switch (control & STLE_OP_MASK) { case OP_RXSTAT: - msk_rxeof (sc_if, status, control, len); + msk_rxeof (sc_if, status, control, len, mPciIo, mSoftc); rxprog++; // // Because there is no way to sync single Rx LE @@ -2233,20 +2383,20 @@ msk_handle_events ( rxput[port]++; // Update prefetch unit if we've passed water mark if (rxput[port] >= sc_if->msk_cdata.msk_rx_putwm) { - msk_rxput (sc_if); + msk_rxput (sc_if, mSoftc); rxput[port] = 0; } break; case OP_TXINDEXLE: if (mSoftc->msk_if[MSK_PORT_A] != NULL) { - msk_txeof (mSoftc->msk_if[MSK_PORT_A], status & STLE_TXA1_MSKL); + msk_txeof (mSoftc->msk_if[MSK_PORT_A], status & STLE_TXA1_MSKL, mPciIo); } if (mSoftc->msk_if[MSK_PORT_B] != NULL) { msk_txeof (mSoftc->msk_if[MSK_PORT_B], ((status & STLE_TXA2_MSKL) >> STLE_TXA2_SHIFTL) | ((len & STLE_TXA2_MSKH) << - STLE_TXA2_SHIFTH)); + STLE_TXA2_SHIFTH), mPciIo); } break; default: @@ -2262,10 +2412,10 @@ msk_handle_events ( mSoftc->msk_stat_cons = cons;
if (rxput[MSK_PORT_A] > 0) { - msk_rxput (mSoftc->msk_if[MSK_PORT_A]); + msk_rxput (mSoftc->msk_if[MSK_PORT_A], mSoftc); } if (rxput[MSK_PORT_B] > 0) { - msk_rxput (mSoftc->msk_if[MSK_PORT_B]); + msk_rxput (mSoftc->msk_if[MSK_PORT_B], mSoftc); }
return (mSoftc->msk_stat_cons != CSR_READ_2 (mSoftc, STAT_PUT_IDX)); @@ -2274,7 +2424,9 @@ msk_handle_events ( STATIC VOID msk_intr ( - VOID + EFI_HANDLE mController, + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if0; @@ -2297,16 +2449,16 @@ msk_intr ( sc_if1 = mSoftc->msk_if[MSK_PORT_B];
if ((Status & Y2_IS_IRQ_PHY1) != 0 && sc_if0 != NULL) { - msk_intr_phy (sc_if0); + msk_intr_phy (sc_if0, mController); } if ((Status & Y2_IS_IRQ_PHY2) != 0 && sc_if1 != NULL) { - msk_intr_phy (sc_if1); + msk_intr_phy (sc_if1, mController); } if ((Status & Y2_IS_IRQ_MAC1) != 0 && sc_if0 != NULL) { - msk_intr_gmac (sc_if0); + msk_intr_gmac (sc_if0, mSoftc); } if ((Status & Y2_IS_IRQ_MAC2) != 0 && sc_if1 != NULL) { - msk_intr_gmac (sc_if1); + msk_intr_gmac (sc_if1, mSoftc); } if ((Status & (Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2)) != 0) { DEBUG ((EFI_D_NET, "Marvell Yukon: Rx descriptor error\n")); @@ -2321,10 +2473,10 @@ msk_intr ( CSR_READ_4 (mSoftc, B0_IMSK); } if ((Status & Y2_IS_HW_ERR) != 0) { - msk_intr_hwerr (); + msk_intr_hwerr (mPciIo, mSoftc); }
- domore = msk_handle_events (); + domore = msk_handle_events (mPciIo, mSoftc); if ((Status & Y2_IS_STAT_BMU) != 0 && domore == 0) { CSR_WRITE_4 (mSoftc, STAT_CTRL, SC_STAT_CLR_IRQ); } @@ -2336,7 +2488,8 @@ msk_intr ( static VOID msk_set_tx_stfwd ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + struct msk_softc *mSoftc ) { // Disable jumbo frames for Tx @@ -2345,27 +2498,48 @@ msk_set_tx_stfwd (
EFI_STATUS mskc_init ( - VOID + EFI_HANDLE mController ) { - EFI_STATUS Status; + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *mPciIo; + struct msk_softc *mSoftc;
- // Just init port A - Status = msk_init (mSoftc->msk_if[MSK_PORT_A]); + Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); if (EFI_ERROR (Status)) { return Status; } + + if (mSoftc->msk_if[MSK_PORT_A] != NULL) { + Status = msk_init (mSoftc->msk_if[MSK_PORT_A], mController, mPciIo, mSoftc); + if (EFI_ERROR (Status)) { + return Status; + } + } + + if (mSoftc->msk_if[MSK_PORT_B] != NULL) { + Status = msk_init (mSoftc->msk_if[MSK_PORT_B], mController, mPciIo, mSoftc); + if (EFI_ERROR (Status)) { + return Status; + } + } + Status = gBS->SetTimer (mSoftc->Timer, TimerPeriodic, TICKS_PER_SECOND); if (EFI_ERROR (Status)) { - mskc_shutdown (); + mskc_shutdown (mController); } + return Status; }
static EFI_STATUS msk_init ( - IN struct msk_if_softc *sc_if + IN struct msk_if_softc *sc_if, + IN EFI_HANDLE mController, + IN EFI_PCI_IO_PROTOCOL *mPciIo, + IN struct msk_softc *mSoftc + ) { UINT8 *eaddr; @@ -2375,7 +2549,7 @@ msk_init ( INTN port = sc_if->msk_md.port;
// Cancel pending I/O and free all Rx/Tx buffers. - msk_stop (sc_if); + msk_stop (sc_if, mController, mPciIo, mSoftc);
sc_if->msk_framesize = MAX_SUPPORTED_PACKET_SIZE;
@@ -2397,7 +2571,7 @@ msk_init ( CSR_READ_1 (mSoftc, MR_ADDR (port, GMAC_IRQ_SRC));
// Clear MIB stats - msk_stats_clear (sc_if); + msk_stats_clear (sc_if, mSoftc);
// Disable FCS GMAC_WRITE_2 (mSoftc, port, GM_RX_CTRL, GM_RXCR_CRC_DIS); @@ -2465,14 +2639,14 @@ msk_init ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, TX_GMF_CTRL_T), GMF_OPER_ON);
// Configure hardware VLAN tag insertion/stripping - msk_setvlan (sc_if); + msk_setvlan (sc_if, mSoftc);
if ((sc_if->msk_flags & MSK_FLAG_RAMBUF) == 0) { // Set Rx Pause threshould. CSR_WRITE_2 (mSoftc, MR_ADDR (port, RX_GMF_LP_THR), MSK_ECU_LLPP); CSR_WRITE_2 (mSoftc, MR_ADDR (port, RX_GMF_UP_THR), MSK_ECU_ULPP); // Configure store-and-forward for Tx. - msk_set_tx_stfwd (sc_if); + msk_set_tx_stfwd (sc_if, mSoftc); }
if (mSoftc->msk_hw_id == CHIP_ID_YUKON_FE_P && mSoftc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) { @@ -2491,7 +2665,7 @@ msk_init ( CSR_WRITE_1 (mSoftc, MR_ADDR (port, TXA_CTRL), TXA_ENA_ARB);
// Setup RAM buffer - msk_set_rambuffer (sc_if); + msk_set_rambuffer (sc_if, mSoftc);
// Disable Tx sync Queue CSR_WRITE_1 (mSoftc, RB_ADDR (sc_if->msk_txsq, RB_CTRL), RB_RST_SET); @@ -2533,16 +2707,16 @@ msk_init ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, RX_GMF_TR_THR), 0x17a); CSR_WRITE_4 (mSoftc, MR_ADDR (port, RX_GMF_CTRL_T), RX_TRUNC_ON);
- msk_set_prefetch (sc_if->msk_txq, sc_if->msk_rdata.msk_tx_ring_paddr, MSK_TX_RING_CNT - 1); + msk_set_prefetch (sc_if->msk_txq, sc_if->msk_rdata.msk_tx_ring_paddr, MSK_TX_RING_CNT - 1, mSoftc); msk_init_tx_ring (sc_if);
// Disable Rx checksum offload and RSS hash CSR_WRITE_4 (mSoftc, Q_ADDR (sc_if->msk_rxq, Q_CSR), BMU_DIS_RX_CHKSUM | BMU_DIS_RX_RSS_HASH); - msk_set_prefetch (sc_if->msk_rxq, sc_if->msk_rdata.msk_rx_ring_paddr, MSK_RX_RING_CNT - 1); - Status = msk_init_rx_ring (sc_if); + msk_set_prefetch (sc_if->msk_rxq, sc_if->msk_rdata.msk_rx_ring_paddr, MSK_RX_RING_CNT - 1, mSoftc); + Status = msk_init_rx_ring (sc_if, mPciIo, mSoftc); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: Initialization failed: no memory for Rx buffers\n")); - msk_stop (sc_if); + msk_stop (sc_if, mController, mPciIo, mSoftc); return Status; }
@@ -2574,7 +2748,7 @@ msk_init ( CSR_READ_4 (mSoftc, B0_IMSK);
sc_if->msk_flags &= ~MSK_FLAG_LINK; - e1000phy_mediachg (); + e1000phy_mediachg (mController, port);
return Status; } @@ -2582,7 +2756,8 @@ msk_init ( STATIC VOID msk_set_rambuffer ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + struct msk_softc *mSoftc ) { INTN ltpp, utpp; @@ -2626,9 +2801,10 @@ msk_set_rambuffer ( STATIC VOID msk_set_prefetch ( - INTN qaddr, + INTN qaddr, EFI_PHYSICAL_ADDRESS addr, - UINT32 count + UINT32 count, + struct msk_softc *mSoftc ) { // Reset the prefetch unit @@ -2649,7 +2825,10 @@ msk_set_prefetch ( static VOID msk_stop ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + EFI_HANDLE mController, + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc ) { struct msk_txdesc *txd; @@ -2678,7 +2857,7 @@ msk_stop ( // Read again to ensure writing. GMAC_READ_2 (mSoftc, port, GM_GP_CTRL); // Update stats and clear counters - msk_stats_update (sc_if); + msk_stats_update (sc_if, mSoftc);
// Stop Tx BMU CSR_WRITE_4 (mSoftc, Q_ADDR (sc_if->msk_txq, Q_CSR), BMU_STOP); @@ -2700,7 +2879,7 @@ msk_stop ( // Disable all GMAC interrupt. CSR_WRITE_1 (mSoftc, MR_ADDR (port, GMAC_IRQ_MSK), 0); // Disable PHY interrupt. */ - msk_phy_writereg (port, PHY_MARV_INT_MASK, 0); + msk_phy_writereg (port, PHY_MARV_INT_MASK, 0, mController);
// Disable the RAM Interface Arbiter. CSR_WRITE_1 (mSoftc, MR_ADDR (port, TXA_CTRL), TXA_DIS_ARB); @@ -2788,7 +2967,8 @@ msk_stop ( static VOID msk_stats_clear ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + struct msk_softc *mSoftc ) { UINT16 gmac; @@ -2812,7 +2992,8 @@ msk_stats_clear ( static VOID msk_stats_update ( - struct msk_if_softc *sc_if + struct msk_if_softc *sc_if, + struct msk_softc *mSoftc ) { struct msk_hw_stats *stats; @@ -2877,5 +3058,125 @@ msk_stats_update ( GMAC_WRITE_2 (mSoftc, port, GM_PHY_ADDR, gmac); }
+void +mskc_init_driver_list (VOID) +{ + InitializeListHead (&msk_drv_data_head); + e1000phy_init_driver_list (); +} + +static +EFI_STATUS +msk_get_ctrl_data ( + EFI_HANDLE mController, + EFI_PCI_IO_PROTOCOL **mPciIo, + struct msk_softc **mSoftc + ) +{ + MSK_LINKED_DRV_BUF *mDrvNode; + EFI_STATUS Status; + + Status = msk_find_drv_node (mController, &mDrvNode); + if (!EFI_ERROR(Status)) { + *mSoftc = mDrvNode->mSoftc; + *mPciIo = mDrvNode->mPciIo; + } + + return Status; +} + +static +EFI_STATUS +msk_get_ctrl_data_msks ( + EFI_HANDLE mController, + struct msk_softc **mSoftc + ) +{ + MSK_LINKED_DRV_BUF *mDrvNode; + EFI_STATUS Status; + + Status = msk_find_drv_node (mController, &mDrvNode); + if (!EFI_ERROR(Status)) { + *mSoftc = mDrvNode->mSoftc; + } + + return Status; +} + +static +EFI_STATUS +msk_add_ctrl_data ( + EFI_HANDLE mController, + EFI_PCI_IO_PROTOCOL *mPciIo, + struct msk_softc *mSoftc + ) +{ + MSK_LINKED_DRV_BUF *mDrvNode; + EFI_STATUS Status; + + Status = msk_find_drv_node (mController, &mDrvNode); + if (EFI_ERROR(Status)) { + Status = gBS->AllocatePool (EfiBootServicesData, + sizeof (MSK_LINKED_DRV_BUF), + (VOID**) &mDrvNode); + if (!EFI_ERROR (Status)) { + mDrvNode->Signature = MSK_DRV_SIGNATURE; + mDrvNode->mController = mController; + mDrvNode->mPciIo = mPciIo; + mDrvNode->mSoftc = mSoftc; + InsertTailList (&msk_drv_data_head, &mDrvNode->Link); + } + } else { + Status = EFI_ALREADY_STARTED; + } + + return Status; +} + +static +EFI_STATUS +msk_del_ctrl_data ( + EFI_HANDLE mController + ) +{ + MSK_LINKED_DRV_BUF *mDrvNode; + EFI_STATUS Status; + + Status = msk_find_drv_node (mController, &mDrvNode); + if (!EFI_ERROR(Status)) { + RemoveEntryList (&mDrvNode->Link); + gBS->FreePool (mDrvNode); + } + + return Status; +} + +static +EFI_STATUS +msk_find_drv_node ( + EFI_HANDLE mController, + MSK_LINKED_DRV_BUF **mDrvNode + ) +{ + MSK_LINKED_DRV_BUF *mDrvBuffNode; + EFI_STATUS Status; + LIST_ENTRY *Node; + + Status = EFI_NOT_FOUND; + + Node = GetFirstNode (&msk_drv_data_head); + while (!IsNull (&msk_drv_data_head, Node)) { + mDrvBuffNode = MSK_DRV_INFO_FROM_THIS (Node); + if (mDrvBuffNode->mController == mController) { + *mDrvNode = mDrvBuffNode; + Status = EFI_SUCCESS; + break; + } + Node = GetNextNode (&msk_drv_data_head, Node); + } + + return Status; +} + #undef MSK_READ_MIB32 #undef MSK_READ_MIB64 diff --git a/Drivers/Net/MarvellYukonDxe/if_msk.h b/Drivers/Net/MarvellYukonDxe/if_msk.h index 110c562..07990fe 100644 --- a/Drivers/Net/MarvellYukonDxe/if_msk.h +++ b/Drivers/Net/MarvellYukonDxe/if_msk.h @@ -14,19 +14,21 @@ **/
#include <Uefi.h> +#include <Protocol/PciIo.h>
#define MAX_SUPPORTED_PACKET_SIZE (1566) /* No jumbo frame size support */
EFI_STATUS mskc_probe (EFI_PCI_IO_PROTOCOL *PciIo);
-EFI_STATUS mskc_attach (EFI_PCI_IO_PROTOCOL *PciIo, EFI_MAC_ADDRESS *Mac); -void mskc_detach (void); +EFI_STATUS mskc_attach (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *PciIo, EFI_MAC_ADDRESS *Mac); +void mskc_detach (EFI_HANDLE);
-EFI_STATUS mskc_init (void); -void mskc_shutdown (void); +EFI_STATUS mskc_init (EFI_HANDLE); +void mskc_shutdown (EFI_HANDLE);
void mskc_rxfilter ( + IN EFI_HANDLE mController, IN UINT32 FilterFlags, IN UINTN MCastFilterCnt, IN EFI_MAC_ADDRESS *MCastFilter @@ -34,18 +36,26 @@ mskc_rxfilter (
EFI_STATUS mskc_transmit ( + IN EFI_HANDLE mController, IN UINTN BufferSize, IN VOID *Buffer );
EFI_STATUS mskc_receive ( + IN EFI_HANDLE mController, IN OUT UINTN *BufferSize, OUT VOID *Buffer );
void mskc_getstatus ( + IN EFI_HANDLE mController, OUT UINT32 *InterruptStatus, OPTIONAL OUT VOID **TxBuf OPTIONAL ); + +void +mskc_init_driver_list ( + VOID + ); diff --git a/Drivers/Net/MarvellYukonDxe/if_mskreg.h b/Drivers/Net/MarvellYukonDxe/if_mskreg.h index 7718536..9f11e8e 100644 --- a/Drivers/Net/MarvellYukonDxe/if_mskreg.h +++ b/Drivers/Net/MarvellYukonDxe/if_mskreg.h @@ -2466,6 +2466,23 @@ struct msk_softc { EFI_EVENT Timer; };
+typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + EFI_HANDLE mController; + EFI_PCI_IO_PROTOCOL *mPciIo; + struct msk_softc *mSoftc; +} MSK_LINKED_DRV_BUF; + +#define MSK_DRV_SIGNATURE SIGNATURE_32 ('m', 's', 'k', 'c') + +#define MSK_DRV_INFO_FROM_THIS(a) \ + CR (a, \ + MSK_LINKED_DRV_BUF, \ + Link, \ + MSK_DRV_SIGNATURE \ + ); + #define MSK_USECS(sc, us) ((sc)->msk_clock * (us))
/* Softc for each logical interface. */ diff --git a/Drivers/Net/MarvellYukonDxe/miivar.h b/Drivers/Net/MarvellYukonDxe/miivar.h index 1903ef6..73fba3f 100644 --- a/Drivers/Net/MarvellYukonDxe/miivar.h +++ b/Drivers/Net/MarvellYukonDxe/miivar.h @@ -55,13 +55,6 @@ #define _DEV_MII_MIIVAR_H_
/* - * Callbacks from MII layer into network interface device driver. - */ -INTN msk_phy_readreg (INTN, INTN); -INTN msk_phy_writereg (INTN, INTN, INTN); -void msk_miibus_statchg (INTN); - -/* * A network interface driver has one of these structures in its softc. * It is the interface from the network interface driver to the MII * layer. @@ -181,9 +174,9 @@ struct mii_phydesc { #define MII_PHY_DESC(a, b) { MII_OUI_ ## a, MII_MODEL_ ## a ## _ ## b, MII_STR_ ## a ## _ ## b } #define MII_PHY_END { 0, 0, NULL }
-#define PHY_READ(p, r) msk_phy_readreg ((p)->mmd->port, (r)) +#define PHY_READ(p, r, c) msk_phy_readreg ((p)->mmd->port, (r), (c))
-#define PHY_WRITE(p, r, v) msk_phy_writereg ((p)->mmd->port, (r), (v)) +#define PHY_WRITE(p, r, v, c) msk_phy_writereg ((p)->mmd->port, (r), (v), (c))
struct msk_mii_data { INTN port; @@ -191,8 +184,4 @@ struct msk_mii_data { INTN mii_flags; };
-EFI_STATUS e1000_probe_and_attach (struct mii_data *mii, const struct msk_mii_data *mmd); -void e1000phy_tick (void); -void e1000phy_mediachg (void); - #endif /* _DEV_MII_MIIVAR_H_ */
Hi Daniil,
Thanks for looking into this.
On 17 October 2016 at 22:45, Daniil Egranov daniil.egranov@arm.com wrote:
The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
Drivers/Net/MarvellYukonDxe/DriverBinding.c | 6 +- Drivers/Net/MarvellYukonDxe/Snp.c | 46 +-- Drivers/Net/MarvellYukonDxe/e1000phy.c | 330 +++++++++++---- Drivers/Net/MarvellYukonDxe/e1000phyreg.h | 23 ++ Drivers/Net/MarvellYukonDxe/if_msk.c | 615 +++++++++++++++++++++------- Drivers/Net/MarvellYukonDxe/if_msk.h | 18 +- Drivers/Net/MarvellYukonDxe/if_mskreg.h | 17 + Drivers/Net/MarvellYukonDxe/miivar.h | 15 +- 8 files changed, 786 insertions(+), 284 deletions(-)
diff --git a/Drivers/Net/MarvellYukonDxe/DriverBinding.c b/Drivers/Net/MarvellYukonDxe/DriverBinding.c index 95068fa..fc684c0 100644 --- a/Drivers/Net/MarvellYukonDxe/DriverBinding.c +++ b/Drivers/Net/MarvellYukonDxe/DriverBinding.c @@ -192,14 +192,14 @@ MarvellYukonDriverStart ( // // Initialize Yukon card so we can get the MAC address //
- Status = mskc_attach (YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
Status = mskc_attach (Controller, YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { gBS->FreePool (YukonDriver); return Status; }
- mskc_detach();
mskc_detach (Controller);
// // Assign fields for device path
@@ -487,6 +487,8 @@ InitializeMarvellYukonDriver (
if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: InitializeMarvellYukonDriver(): Driver binding failed\n"));
} else {
mskc_init_driver_list (); }
return Status;
Could we have something like this instead, please?
""" if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: InitializeMarvellYukonDriver(): Driver binding failed\n")); return Status; } mskc_init_driver_list (); return EFI_SUCCESS; """
diff --git a/Drivers/Net/MarvellYukonDxe/Snp.c b/Drivers/Net/MarvellYukonDxe/Snp.c index 3d84f84..96cec5f 100644 --- a/Drivers/Net/MarvellYukonDxe/Snp.c +++ b/Drivers/Net/MarvellYukonDxe/Snp.c @@ -121,21 +121,21 @@ SnpGetStatus ( ) { EFI_STATUS Status;
- YUKON_DRIVER *Snp;
- YUKON_DRIVER *YukonDriver;
Could you split off this rename? (and all the associated white space only changes involving 'YUKON_DRIVER')
EFI_TPL OldTpl;
if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This);
- if (Snp == NULL) {
YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
if (YukonDriver == NULL) { return EFI_INVALID_PARAMETER; }
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) {
- switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -148,7 +148,7 @@ SnpGetStatus ( goto ON_EXIT; }
- mskc_getstatus (InterruptStatus, TxBuf);
- mskc_getstatus (YukonDriver->Controller, InterruptStatus, TxBuf); Status = EFI_SUCCESS;
ON_EXIT: @@ -199,7 +199,7 @@ SnpInitialize ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver;
... like this one ...
EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpInitialize()\n")); @@ -230,7 +230,7 @@ SnpInitialize ( gBS->SetMem (YukonDriver->SnpMode.MCastFilter, sizeof YukonDriver->SnpMode.MCastFilter, 0); gBS->CopyMem (&YukonDriver->SnpMode.CurrentAddress, &YukonDriver->SnpMode.PermanentAddress, sizeof (EFI_MAC_ADDRESS));
- Status = mskc_init ();
Status = mskc_init (YukonDriver->Controller);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL;
@@ -509,18 +509,18 @@ SnpReceive ( ) { EFI_STATUS Status;
- YUKON_DRIVER *Snp;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This);
YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) {
- switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -538,7 +538,7 @@ SnpReceive ( goto ON_EXIT; }
- Status = mskc_receive (BufferSize, Buffer);
- Status = mskc_receive (YukonDriver->Controller, BufferSize, Buffer); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_READY) { goto ON_EXIT_NO_DEBUG;
@@ -678,7 +678,7 @@ SnpReceiveFilters ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; UINT32 newReceiveFilter;
@@ -743,7 +743,7 @@ SnpReceiveFilters ( }
YukonDriver->SnpMode.ReceiveFilterSetting = newReceiveFilter;
- mskc_rxfilter (YukonDriver->SnpMode.ReceiveFilterSetting, MCastFilterCnt, MCastFilter);
mskc_rxfilter (YukonDriver->Controller, YukonDriver->SnpMode.ReceiveFilterSetting, MCastFilterCnt, MCastFilter);
Status = EFI_SUCCESS; goto ON_EXIT;
@@ -788,7 +788,7 @@ SnpReset ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpReset()\n"));
@@ -858,7 +858,7 @@ SnpShutdown ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpShutdown()\n"));
@@ -890,7 +890,7 @@ SnpShutdown ( goto ON_ERROR_RESTORE_TPL; }
- mskc_shutdown ();
- mskc_shutdown (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStarted; Status = EFI_SUCCESS;
@@ -938,7 +938,7 @@ SnpStart ( IN EFI_SIMPLE_NETWORK_PROTOCOL *This ) {
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -966,7 +966,7 @@ SnpStart ( goto ON_ERROR_RESTORE_TPL; }
- Status = mskc_attach (YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
Status = mskc_attach (YukonDriver->Controller, YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL;
@@ -1025,7 +1025,7 @@ SnpStationAddress ( IN EFI_MAC_ADDRESS *New OPTIONAL ) {
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -1122,7 +1122,7 @@ SnpStatistics ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStatistics()\n"));
@@ -1242,7 +1242,7 @@ SnpStop ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStop()\n"));
@@ -1269,7 +1269,7 @@ SnpStop ( goto ON_ERROR_RESTORE_TPL; }
- mskc_detach ();
- mskc_detach (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStopped; gBS->SetMem (&YukonDriver->SnpMode.CurrentAddress, sizeof (EFI_MAC_ADDRESS), 0); Status = EFI_SUCCESS;
@@ -1407,7 +1407,7 @@ SnpTransmit ( gBS->CopyMem (&Frame->EtherType, &ProtocolNet, sizeof (UINT16)); }
- Status = mskc_transmit (BufferSize, Buffer);
- Status = mskc_transmit (YukonDriver->Controller, BufferSize, Buffer);
ON_EXIT: gBS->RestoreTPL (OldTpl); diff --git a/Drivers/Net/MarvellYukonDxe/e1000phy.c b/Drivers/Net/MarvellYukonDxe/e1000phy.c index dee4cdf..ca84138 100644 --- a/Drivers/Net/MarvellYukonDxe/e1000phy.c +++ b/Drivers/Net/MarvellYukonDxe/e1000phy.c @@ -57,6 +57,7 @@ #include <Library/MemoryAllocationLib.h> #include <Library/DebugLib.h> #include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseLib.h>
#include "if_media.h"
@@ -64,27 +65,30 @@
#include "e1000phyreg.h"
+static LIST_ENTRY e1000phy_drv_data_head;
+static void e1000phy_attach (const struct mii_attach_args *ma, EFI_HANDLE, struct e1000phy_softc *); static EFI_STATUS e1000phy_probe (const struct mii_attach_args *ma); -static void e1000phy_attach (const struct mii_attach_args *ma); static const struct mii_phydesc * mii_phy_match (const struct mii_attach_args *ma, const struct mii_phydesc *mpd); static const struct mii_phydesc * mii_phy_match_gen (const struct mii_attach_args *ma, const struct mii_phydesc *mpd, UINTN endlen); static EFI_STATUS mii_phy_dev_probe (const struct mii_attach_args *ma, const struct mii_phydesc *mpd);
-struct e1000phy_softc {
- struct mii_softc mii_sc;
- INTN mii_model;
- const struct msk_mii_data *mmd;
-}; +static EFI_STATUS e1000phy_get_ctrl_data_phy (EFI_HANDLE, INT32, struct e1000phy_softc **); +static EFI_STATUS e1000phy_add_ctrl_data (EFI_HANDLE, INT32, struct e1000phy_softc *); +static EFI_STATUS e1000phy_del_ctrl_data (EFI_HANDLE, INT32); +static EFI_STATUS e1000phy_find_drv_node (EFI_HANDLE, INT32, E1000PHY_LINKED_DRV_BUF**);
-struct e1000phy_softc *mPhySoftc; +void msk_miibus_statchg (INTN, EFI_HANDLE); +INTN msk_phy_readreg (INTN, INTN, EFI_HANDLE); +INTN msk_phy_writereg (INTN, INTN, INTN, EFI_HANDLE);
-static void mii_phy_update (INTN); -static void e1000phy_service (INTN); -static void e1000phy_status (struct mii_softc *); -static void e1000phy_reset (struct mii_softc *); -static void e1000phy_mii_phy_auto (void); +static void mii_phy_update (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_service (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_status (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_reset (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_mii_phy_auto (EFI_HANDLE, struct e1000phy_softc *);
static const struct mii_phydesc e1000phys[] = { MII_PHY_DESC (MARVELL, E1000), @@ -113,12 +117,15 @@ static const struct mii_phydesc e1000phys[] = { EFI_STATUS e1000_probe_and_attach ( struct mii_data *mii,
- const struct msk_mii_data *mmd
- )
- const struct msk_mii_data *mmd,
- EFI_HANDLE mController,
- INT32 mPort
Please don't use the m prefix for struct fields or function arguments. It is intended for variables with module scope
- )
{ struct mii_attach_args ma; INTN bmsr; EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
Please don't use the m prefix for automatic [stack] variables either.
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct e1000phy_softc), @@ -129,13 +136,12 @@ e1000_probe_and_attach ( gBS->SetMem (mPhySoftc, sizeof (struct e1000phy_softc), 0); mPhySoftc->mmd = mmd;
- /*
*/
- Check to see if there is a PHY at this address. Note,
- many braindead PHYs report 0/0 in their ID registers,
- so we test for media in the BMSR.
- bmsr = PHY_READ (mPhySoftc, E1000_SR);
- bmsr = PHY_READ (mPhySoftc, E1000_SR, mController); if (bmsr == 0 || bmsr == 0xffff || (bmsr & (E1000_SR_EXTENDED_STATUS|E1000_SR_MEDIAMASK)) == 0) { /* Assume no PHY at this address. */ gBS->FreePool (mPhySoftc);
@@ -145,8 +151,8 @@ e1000_probe_and_attach ( /* * Extract the IDs. */
- ma.mii_id1 = PHY_READ (mPhySoftc, E1000_ID1);
- ma.mii_id2 = PHY_READ (mPhySoftc, E1000_ID2);
ma.mii_id1 = PHY_READ (mPhySoftc, E1000_ID1, mController);
ma.mii_id2 = PHY_READ (mPhySoftc, E1000_ID2, mController);
ma.mii_data = mii;
@@ -156,11 +162,36 @@ e1000_probe_and_attach ( return Status; }
- e1000phy_attach (&ma);
- e1000phy_attach (&ma, mController, mPhySoftc);
- Status = e1000phy_add_ctrl_data (mController, mPort, mPhySoftc);
- if (EFI_ERROR (Status)) {
- gBS->FreePool (mPhySoftc);
- return Status;
- }
- return EFI_SUCCESS;
}
EFI_STATUS +e1000phy_dettach (
'detach' has only one 't'
- EFI_HANDLE mController,
- INT32 mPort
- )
+{
- EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
- Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc);
- if (!EFI_ERROR (Status)) {
- e1000phy_del_ctrl_data(mController, mPort);
- gBS->FreePool(mPhySoftc);
- }
- return Status;
+}
+EFI_STATUS e1000phy_probe ( const struct mii_attach_args *ma ) @@ -170,7 +201,9 @@ e1000phy_probe (
static void e1000phy_attach (
- const struct mii_attach_args *ma
- const struct mii_attach_args *ma,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc )
{ struct mii_softc *sc; @@ -188,7 +221,7 @@ e1000phy_attach ( switch (mPhySoftc->mii_model) { case MII_MODEL_MARVELL_E1011: case MII_MODEL_MARVELL_E1112:
if (PHY_READ (mPhySoftc, E1000_ESSR) & E1000_ESSR_FIBER_LINK) {
if (PHY_READ (mPhySoftc, E1000_ESSR, mController) & E1000_ESSR_FIBER_LINK) { sc->mii_flags |= MIIF_HAVEFIBER; } break;
@@ -204,46 +237,48 @@ e1000phy_attach ( * that information should be used to select default * type of PHY. */
PHY_WRITE (mPhySoftc, E1000_EADR, 0);
}PHY_WRITE (mPhySoftc, E1000_EADR, 0, mController); break;
- e1000phy_reset (sc);
- e1000phy_reset (sc, mController, mPhySoftc);
- sc->mii_capabilities = PHY_READ (mPhySoftc, E1000_SR) & 0xFFFFFFFF;
- sc->mii_capabilities = PHY_READ (mPhySoftc, E1000_SR, mController) & 0xFFFFFFFF; if (sc->mii_capabilities & E1000_SR_EXTENDED_STATUS) {
- sc->mii_extcapabilities = PHY_READ (mPhySoftc, E1000_ESR);
- sc->mii_extcapabilities = PHY_READ (mPhySoftc, E1000_ESR, mController); }
}
static void e1000phy_reset (
- struct mii_softc *sc
- struct mii_softc *sc,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc )
{ UINT16 reg; UINT16 page;
- reg = PHY_READ (mPhySoftc, E1000_SCR);
- reg = PHY_READ (mPhySoftc, E1000_SCR, mController); if ((sc->mii_flags & MIIF_HAVEFIBER) != 0) { reg &= ~E1000_SCR_AUTO_X_MODE;
- PHY_WRITE (mPhySoftc, E1000_SCR, reg);
- PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); if (mPhySoftc->mii_model == MII_MODEL_MARVELL_E1112) { // Select 1000BASE-X only mode.
page = PHY_READ (mPhySoftc, E1000_EADR);
PHY_WRITE (mPhySoftc, E1000_EADR, 2);
reg = PHY_READ (mPhySoftc, E1000_SCR);
page = PHY_READ (mPhySoftc, E1000_EADR, mController);
PHY_WRITE (mPhySoftc, E1000_EADR, 2, mController);
reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg &= ~E1000_SCR_MODE_MASK; reg |= E1000_SCR_MODE_1000BX;
PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); if (mPhySoftc->mmd != NULL && mPhySoftc->mmd->pmd == 'P') { // Set SIGDET polarity low for SFP module
PHY_WRITE (mPhySoftc, E1000_EADR, 1);
reg = PHY_READ (mPhySoftc, E1000_SCR);
PHY_WRITE (mPhySoftc, E1000_EADR, 1, mController);
reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg |= E1000_SCR_FIB_SIGDET_POLARITY;
PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); }
PHY_WRITE (mPhySoftc, E1000_EADR, page);
} } else { switch (mPhySoftc->mii_model) {PHY_WRITE (mPhySoftc, E1000_EADR, page, mController);
@@ -270,7 +305,7 @@ e1000phy_reset ( E1000_SCR_SCRAMBLER_DISABLE); reg |= E1000_SCR_LPNP; // XXX Enable class A driver for Yukon FE+ A0
PHY_WRITE (mPhySoftc, 0x1C, PHY_READ (mPhySoftc, 0x1C) | 0x0001);
PHY_WRITE (mPhySoftc, 0x1C, PHY_READ (mPhySoftc, 0x1C, mController) | 0x0001, mController); break; default: reg &= ~E1000_SCR_AUTO_X_MODE;
@@ -281,15 +316,15 @@ e1000phy_reset ( /* Auto correction for reversed cable polarity. */ reg &= ~E1000_SCR_POLARITY_REVERSAL; }
- PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController);
if (mPhySoftc->mii_model == MII_MODEL_MARVELL_E1116 || mPhySoftc->mii_model == MII_MODEL_MARVELL_E1149) {
PHY_WRITE (mPhySoftc, E1000_EADR, 2);
reg = PHY_READ (mPhySoftc, E1000_SCR);
PHY_WRITE (mPhySoftc, E1000_EADR, 2, mController);
reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg |= E1000_SCR_RGMII_POWER_UP;
PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_EADR, 0);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController);
} }PHY_WRITE (mPhySoftc, E1000_EADR, 0, mController);
@@ -299,42 +334,45 @@ e1000phy_reset ( case MII_MODEL_MARVELL_E1118: break; case MII_MODEL_MARVELL_E1116:
page = PHY_READ (mPhySoftc, E1000_EADR);
page = PHY_READ (mPhySoftc, E1000_EADR, mController); /* Select page 3, LED control register. */
PHY_WRITE (mPhySoftc, E1000_EADR, 3);
PHY_WRITE (mPhySoftc, E1000_EADR, 3, mController); PHY_WRITE (mPhySoftc, E1000_SCR, E1000_SCR_LED_LOS (1) | /* Link/Act */ E1000_SCR_LED_INIT (8) | /* 10Mbps */ E1000_SCR_LED_STAT1 (7) | /* 100Mbps */
E1000_SCR_LED_STAT0 (7)); /* 1000Mbps */
E1000_SCR_LED_STAT0 (7), /* 1000Mbps */
mController); /* Set blink rate. */
PHY_WRITE (mPhySoftc, E1000_IER, E1000_PULSE_DUR (E1000_PULSE_170MS) | E1000_BLINK_RATE (E1000_BLINK_84MS));
PHY_WRITE (mPhySoftc, E1000_EADR, page);
PHY_WRITE (mPhySoftc, E1000_IER, E1000_PULSE_DUR (E1000_PULSE_170MS) | E1000_BLINK_RATE (E1000_BLINK_84MS), mController);
case MII_MODEL_MARVELL_E3016: /* LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED. */PHY_WRITE (mPhySoftc, E1000_EADR, page, mController); break;
PHY_WRITE (mPhySoftc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04);
PHY_WRITE (mPhySoftc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04, mController); /* Integrated register calibration workaround. */
PHY_WRITE (mPhySoftc, 0x1D, 17);
PHY_WRITE (mPhySoftc, 0x1E, 0x3F60);
PHY_WRITE (mPhySoftc, 0x1D, 17, mController);
default: /* Force TX_CLK to 25MHz clock. */PHY_WRITE (mPhySoftc, 0x1E, 0x3F60, mController); break;
reg = PHY_READ (mPhySoftc, E1000_ESCR);
reg = PHY_READ (mPhySoftc, E1000_ESCR, mController); reg |= E1000_ESCR_TX_CLK_25;
PHY_WRITE (mPhySoftc, E1000_ESCR, reg);
PHY_WRITE (mPhySoftc, E1000_ESCR, reg, mController); break;
}
/* Reset the PHY so all changes take effect. */
- reg = PHY_READ (mPhySoftc, E1000_CR);
- reg = PHY_READ (mPhySoftc, E1000_CR, mController); reg |= E1000_CR_RESET;
- PHY_WRITE (mPhySoftc, E1000_CR, reg);
- PHY_WRITE (mPhySoftc, E1000_CR, reg, mController);
}
static void mii_phy_update (
- INTN cmd
- INTN cmd,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc )
{ struct mii_softc *sc = &mPhySoftc->mii_sc; @@ -344,7 +382,7 @@ mii_phy_update ( sc->mii_media_status != mii->mii_media_status || cmd == MII_MEDIACHG) {
- msk_miibus_statchg (mPhySoftc->mmd->port);
- msk_miibus_statchg (mPhySoftc->mmd->port, mController); sc->mii_media_active = mii->mii_media_active; sc->mii_media_status = mii->mii_media_status; }
@@ -352,27 +390,43 @@ mii_phy_update (
void e1000phy_tick (
- VOID
- EFI_HANDLE mController,
- INT32 mPort )
{
- e1000phy_service (MII_TICK);
- EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
- Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc);
- if (!EFI_ERROR (Status)) {
- e1000phy_service (MII_TICK, mController, mPhySoftc);
- }
}
void e1000phy_mediachg (
- VOID
- EFI_HANDLE mController,
- INT32 mPort )
{
- struct mii_data *mii = mPhySoftc->mii_sc.mii_pdata;
- mii->mii_media_status = 0;
- mii->mii_media_active = IFM_NONE;
- e1000phy_service (MII_MEDIACHG);
- EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
- Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc);
- if (!EFI_ERROR (Status)) {
- struct mii_data *mii = mPhySoftc->mii_sc.mii_pdata;
- mii->mii_media_status = 0;
- mii->mii_media_active = IFM_NONE;
- e1000phy_service (MII_MEDIACHG, mController, mPhySoftc);
- }
}
static void e1000phy_service (
- INTN cmd
- )
- INTN cmd,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc
- )
{ struct mii_softc *sc = &mPhySoftc->mii_sc; INTN reg; @@ -385,7 +439,7 @@ e1000phy_service ( // // Always try to auto-negotiate //
e1000phy_mii_phy_auto ();
e1000phy_mii_phy_auto (mController, mPhySoftc); break;
case MII_TICK:
@@ -393,7 +447,7 @@ e1000phy_service ( * check for link. * Read the status register twice; Link Status is latch-low. */
reg = PHY_READ (mPhySoftc, E1000_SR) | PHY_READ (mPhySoftc, E1000_SR);
reg = PHY_READ (mPhySoftc, E1000_SR, mController) | PHY_READ (mPhySoftc, E1000_SR, mController); if (reg & E1000_SR_LINK_STATUS) { sc->mii_ticks = 0; break;
@@ -411,21 +465,23 @@ e1000phy_service ( // Restart the auto-negotiation // sc->mii_ticks = 0;
e1000phy_reset (sc);
e1000phy_mii_phy_auto ();
e1000phy_reset (sc, mController, mPhySoftc);
e1000phy_mii_phy_auto (mController, mPhySoftc); break;
}
/* Update the media status. */
- e1000phy_status (sc);
e1000phy_status (sc, mController, mPhySoftc);
/* Callback if something changed. */
- mii_phy_update (cmd);
- mii_phy_update (cmd, mController, mPhySoftc);
}
static void e1000phy_status (
- struct mii_softc *sc
- struct mii_softc *sc,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc )
{ struct mii_data *mii = sc->mii_pdata; @@ -439,9 +495,9 @@ e1000phy_status ( mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER;
- bmsr = PHY_READ (mPhySoftc, E1000_SR) | PHY_READ (mPhySoftc, E1000_SR);
- bmcr = PHY_READ (mPhySoftc, E1000_CR);
- ssr = PHY_READ (mPhySoftc, E1000_SSR);
bmsr = PHY_READ (mPhySoftc, E1000_SR, mController) | PHY_READ (mPhySoftc, E1000_SR, mController);
bmcr = PHY_READ (mPhySoftc, E1000_CR, mController);
ssr = PHY_READ (mPhySoftc, E1000_SSR, mController);
if (bmsr & E1000_SR_LINK_STATUS) { DEBUG ((EFI_D_NET, "Marvell Yukon: e1000phy_status, link up\n"));
@@ -489,8 +545,8 @@ e1000phy_status ( }
if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
- ar = PHY_READ (mPhySoftc, E1000_AR);
- lpar = PHY_READ (mPhySoftc, E1000_LPAR);
- ar = PHY_READ (mPhySoftc, E1000_AR, mController);
- lpar = PHY_READ (mPhySoftc, E1000_LPAR, mController); /* FLAG0==rx-flow-control FLAG1==tx-flow-control */ if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) { mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1;
@@ -506,8 +562,8 @@ e1000phy_status ( /* FLAG2 : local PHY resolved to MASTER */ if ((IFM_SUBTYPE (mii->mii_media_active) == IFM_1000_T) || (IFM_SUBTYPE (mii->mii_media_active) == IFM_1000_SX)) {
- PHY_READ (mPhySoftc, E1000_1GSR);
- gsr = PHY_READ (mPhySoftc, E1000_1GSR);
- PHY_READ (mPhySoftc, E1000_1GSR, mController);
- gsr = PHY_READ (mPhySoftc, E1000_1GSR, mController); if ((gsr & E1000_1GSR_MS_CONFIG_RES) != 0) { mii->mii_media_active |= IFM_FLAG2; }
@@ -516,7 +572,8 @@ e1000phy_status (
static void e1000phy_mii_phy_auto (
- VOID
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc )
{ struct mii_softc *sc; @@ -525,20 +582,20 @@ e1000phy_mii_phy_auto ( DEBUG ((EFI_D_NET, "Marvell Yukon: e1000phy_mii_phy_auto negotiation started\n")); sc = &mPhySoftc->mii_sc; if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
- reg = PHY_READ (mPhySoftc, E1000_AR);
- reg = PHY_READ (mPhySoftc, E1000_AR, mController); reg |= E1000_AR_10T | E1000_AR_10T_FD | E1000_AR_100TX | E1000_AR_100TX_FD | E1000_AR_PAUSE | E1000_AR_ASM_DIR;
- PHY_WRITE (mPhySoftc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD);
- PHY_WRITE (mPhySoftc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD, mController); } else {
- PHY_WRITE (mPhySoftc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE);
PHY_WRITE (mPhySoftc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE, mController); }
if ((sc->mii_extcapabilities & (E1000_ESR_1000T_FD | E1000_ESR_1000T)) != 0) {
- PHY_WRITE (mPhySoftc, E1000_1GCR, E1000_1GCR_1000T_FD | E1000_1GCR_1000T);
- PHY_WRITE (mPhySoftc, E1000_1GCR, E1000_1GCR_1000T_FD | E1000_1GCR_1000T, mController); }
- PHY_WRITE (mPhySoftc, E1000_CR, E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG);
- PHY_WRITE (mPhySoftc, E1000_CR, E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG, mController);
}
// @@ -589,3 +646,106 @@ mii_phy_dev_probe ( DEBUG ((EFI_D_NET, "Marvell Yukon: PHY not found (OUI=0x%x, MODEL=0x%x)\n", MII_OUI (ma->mii_id1, ma->mii_id2), MII_MODEL (ma->mii_id2))); return EFI_NOT_FOUND; }
+void +e1000phy_init_driver_list (void) +{
- InitializeListHead (&e1000phy_drv_data_head);
+}
+static +EFI_STATUS +e1000phy_get_ctrl_data_phy (
- EFI_HANDLE mController,
- INT32 mPort,
- struct e1000phy_softc **mPhySoftc
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- *mPhySoftc = mDrvNode->mPhySoftc;
- }
- return Status;
+}
+static +EFI_STATUS +e1000phy_add_ctrl_data (
- EFI_HANDLE mController,
- INT32 mPort,
- struct e1000phy_softc *mPhySoftc
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode);
- if (EFI_ERROR(Status)) {
- Status = gBS->AllocatePool (EfiBootServicesData,
sizeof (E1000PHY_LINKED_DRV_BUF),
(VOID**) &mDrvNode);
- if (!EFI_ERROR (Status)) {
mDrvNode->Signature = E1000PHY_DRV_SIGNATURE;
mDrvNode->mController = mController;
mDrvNode->mPort = mPort;
mDrvNode->mPhySoftc = mPhySoftc;
InsertTailList (&e1000phy_drv_data_head, &mDrvNode->Link);
- }
- } else {
- Status = EFI_ALREADY_STARTED;
- }
- return Status;
+}
+static +EFI_STATUS +e1000phy_del_ctrl_data (
- EFI_HANDLE mController,
- INT32 mPort
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- RemoveEntryList (&mDrvNode->Link);
- gBS->FreePool (mDrvNode);
- }
- return Status;
+}
+static +EFI_STATUS +e1000phy_find_drv_node (
- EFI_HANDLE mController,
- INT32 mPort,
- E1000PHY_LINKED_DRV_BUF **mDrvNode
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvBuffNode;
- EFI_STATUS Status;
- LIST_ENTRY *Node;
- Status = EFI_NOT_FOUND;
- Node = GetFirstNode (&e1000phy_drv_data_head);
- while (!IsNull (&e1000phy_drv_data_head, Node)) {
- mDrvBuffNode = E1000PHY_DRV_INFO_FROM_THIS (Node);
- if (mDrvBuffNode->mController == mController &&
mDrvBuffNode->mPort == mPort) {
*mDrvNode = mDrvBuffNode;
Status = EFI_SUCCESS;
break;
- }
- Node = GetNextNode (&e1000phy_drv_data_head, Node);
- }
- return Status;
+} diff --git a/Drivers/Net/MarvellYukonDxe/e1000phyreg.h b/Drivers/Net/MarvellYukonDxe/e1000phyreg.h index a87b1f1..d0bfd25 100644 --- a/Drivers/Net/MarvellYukonDxe/e1000phyreg.h +++ b/Drivers/Net/MarvellYukonDxe/e1000phyreg.h @@ -396,3 +396,26 @@ #define E1000_ESSR_GMII_FIBER 0x0007 #define E1000_ESSR_TBI_COPPER 0x000d #define E1000_ESSR_TBI_FIBER 0x0005
+struct e1000phy_softc {
- struct mii_softc mii_sc;
- INTN mii_model;
- const struct msk_mii_data *mmd;
+};
+typedef struct {
- UINT32 Signature;
- LIST_ENTRY Link;
- INT32 mPort;
- EFI_HANDLE mController;
- struct e1000phy_softc *mPhySoftc;
+} E1000PHY_LINKED_DRV_BUF;
+#define E1000PHY_DRV_SIGNATURE SIGNATURE_32 ('e', 'p', 'h', 'y')
+#define E1000PHY_DRV_INFO_FROM_THIS(a) \
- CR (a, \
E1000PHY_LINKED_DRV_BUF, \
Link, \
E1000PHY_DRV_SIGNATURE \
);
diff --git a/Drivers/Net/MarvellYukonDxe/if_msk.c b/Drivers/Net/MarvellYukonDxe/if_msk.c index d23f893..3f41d45 100644 --- a/Drivers/Net/MarvellYukonDxe/if_msk.c +++ b/Drivers/Net/MarvellYukonDxe/if_msk.c @@ -121,11 +121,7 @@ #include "if_mskreg.h" #include "if_msk.h"
-// -// Global Variables -// -static EFI_PCI_IO_PROTOCOL *mPciIo; -static struct msk_softc *mSoftc; +static LIST_ENTRY msk_drv_data_head;
#define MSK_CSUM_FEATURES (CSUM_TCP | CSUM_UDP)
@@ -189,49 +185,67 @@ static const CHAR8 *model_name[] = { // // Forward declarations // -static VOID mskc_setup_rambuffer (VOID); -static VOID mskc_reset (VOID); +static VOID mskc_setup_rambuffer (struct msk_softc *); +static VOID mskc_reset (EFI_PCI_IO_PROTOCOL *, struct msk_softc *);
-static EFI_STATUS msk_attach (INT32); -static VOID msk_detach (INT32); +static EFI_STATUS msk_attach (INT32, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_detach (INT32, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *);
static VOID mskc_tick (IN EFI_EVENT, IN VOID*); -static VOID msk_intr (VOID); -static VOID msk_intr_phy (struct msk_if_softc *); -static VOID msk_intr_gmac (struct msk_if_softc *); -static __inline VOID msk_rxput (struct msk_if_softc *); -static INTN msk_handle_events (VOID); -static VOID msk_handle_hwerr (struct msk_if_softc *, UINT32); -static VOID msk_intr_hwerr (VOID); -static VOID msk_rxeof (struct msk_if_softc *, UINT32, UINT32, INTN); -static VOID msk_txeof (struct msk_if_softc *, INTN); -static EFI_STATUS msk_encap (struct msk_if_softc *, MSK_SYSTEM_BUF *); -static VOID msk_start (INT32); -static VOID msk_set_prefetch (INTN, EFI_PHYSICAL_ADDRESS, UINT32); -static VOID msk_set_rambuffer (struct msk_if_softc *); -static VOID msk_set_tx_stfwd (struct msk_if_softc *); -static EFI_STATUS msk_init (struct msk_if_softc *); -static VOID msk_stop (struct msk_if_softc *); +static VOID msk_intr (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_intr_phy (struct msk_if_softc *, EFI_HANDLE); +static VOID msk_intr_gmac (struct msk_if_softc *, struct msk_softc *); +static __inline VOID msk_rxput (struct msk_if_softc *, struct msk_softc *); +static INTN msk_handle_events (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_handle_hwerr (struct msk_if_softc *, UINT32, struct msk_softc *); +static VOID msk_intr_hwerr (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_rxeof (struct msk_if_softc *, UINT32, UINT32, INTN, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_txeof (struct msk_if_softc *, INTN, EFI_PCI_IO_PROTOCOL *); +static EFI_STATUS msk_encap (struct msk_if_softc *, MSK_SYSTEM_BUF *, EFI_PCI_IO_PROTOCOL *); +static VOID msk_start (INT32, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_set_prefetch (INTN, EFI_PHYSICAL_ADDRESS, UINT32, struct msk_softc *); +static VOID msk_set_rambuffer (struct msk_if_softc *, struct msk_softc *); +static VOID msk_set_tx_stfwd (struct msk_if_softc *, struct msk_softc *); +static EFI_STATUS msk_init (struct msk_if_softc *, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_stop (struct msk_if_softc *, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); static VOID msk_phy_power (struct msk_softc *, INTN); -static EFI_STATUS msk_status_dma_alloc (VOID); -static VOID msk_status_dma_free (VOID); -static EFI_STATUS msk_txrx_dma_alloc (struct msk_if_softc *); -static VOID msk_txrx_dma_free (struct msk_if_softc *); -static EFI_STATUS msk_init_rx_ring (struct msk_if_softc *); +INTN msk_phy_readreg (INTN, INTN, EFI_HANDLE); +INTN msk_phy_writereg (INTN, INTN, INTN, EFI_HANDLE); +static EFI_STATUS msk_status_dma_alloc (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_status_dma_free (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static EFI_STATUS msk_txrx_dma_alloc (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *); +static VOID msk_txrx_dma_free (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *); +static EFI_STATUS msk_init_rx_ring (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); static VOID msk_init_tx_ring (struct msk_if_softc *); static __inline VOID msk_discard_rxbuf (struct msk_if_softc *, INTN); -static EFI_STATUS msk_newbuf (struct msk_if_softc *, INTN); +static EFI_STATUS msk_newbuf (struct msk_if_softc *, INTN, EFI_PCI_IO_PROTOCOL *);
static VOID msk_rxfilter ( struct msk_if_softc *sc_if, UINT32 FilterFlags, UINTN MCastFilterCnt,
- EFI_MAC_ADDRESS *MCastFilter
- EFI_MAC_ADDRESS *MCastFilter,
- EFI_HANDLE mController );
-static VOID msk_setvlan (struct msk_if_softc *);
-static VOID msk_stats_clear (struct msk_if_softc *); -static VOID msk_stats_update (struct msk_if_softc *); +static VOID msk_setvlan (struct msk_if_softc *, struct msk_softc *);
+static VOID msk_stats_clear (struct msk_if_softc *, struct msk_softc *); +static VOID msk_stats_update (struct msk_if_softc *, struct msk_softc *); +static VOID clear_pci_errors (EFI_PCI_IO_PROTOCOL *, struct msk_softc *);
+EFI_STATUS e1000_probe_and_attach (struct mii_data *, const struct msk_mii_data *, EFI_HANDLE, INT32); +void e1000phy_tick (EFI_HANDLE, INT32); +void e1000phy_mediachg (EFI_HANDLE, INT32); +void e1000phy_init_driver_list (void); +EFI_STATUS e1000phy_dettach (EFI_HANDLE, INT32);
+static EFI_STATUS msk_get_ctrl_data (EFI_HANDLE, EFI_PCI_IO_PROTOCOL **,
struct msk_softc **);
+static EFI_STATUS msk_get_ctrl_data_msks (EFI_HANDLE, struct msk_softc **); +static EFI_STATUS msk_add_ctrl_data (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *,
struct msk_softc *);
+static EFI_STATUS msk_del_ctrl_data (EFI_HANDLE); +static EFI_STATUS msk_find_drv_node (EFI_HANDLE, MSK_LINKED_DRV_BUF **);
// // Functions @@ -239,12 +253,20 @@ static VOID msk_stats_update (struct msk_if_softc *);
INTN msk_phy_readreg (
- INTN port,
- INTN reg
- INTN port,
- INTN reg,
- EFI_HANDLE mController )
{
- INTN i;
- INTN val;
INTN i;
INTN val;
EFI_STATUS Status;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc);
if (EFI_ERROR (Status)) {
return 0;
}
GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
@@ -267,12 +289,20 @@ msk_phy_readreg (
INTN msk_phy_writereg (
- INTN port,
- INTN reg,
- INTN val
- INTN port,
- INTN reg,
- INTN val,
- EFI_HANDLE mController )
{ INTN i;
EFI_STATUS Status;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc);
if (EFI_ERROR (Status)) {
return 0;
}
GMAC_WRITE_2 (mSoftc, port, GM_SMI_DATA, val); GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
@@ -291,13 +321,23 @@ msk_phy_writereg (
VOID msk_miibus_statchg (
- INTN port
- INTN port,
- EFI_HANDLE mController )
{
- struct msk_if_softc *sc_if = mSoftc->msk_if[port];
- struct mii_data *mii = &sc_if->mii_d;
struct msk_if_softc *sc_if;
struct mii_data *mii; UINT32 gmac;
EFI_STATUS Status;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
sc_if = mSoftc->msk_if[port];
mii = &sc_if->mii_d; sc_if->msk_flags &= ~MSK_FLAG_LINK;
if ((mii->mii_media_status & (IFM_AVALID | IFM_ACTIVE)) == (IFM_AVALID | IFM_ACTIVE)) {
@@ -370,14 +410,14 @@ msk_miibus_statchg ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, GMAC_CTRL), gmac);
// Enable PHY interrupt for FIFO underrun/overflow
- msk_phy_writereg (port, PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR);
- msk_phy_writereg (port, PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR, mController); } else { // // Link state changed to down. // Disable PHY interrupts. // DEBUG ((EFI_D_NET, "Marvell Yukon: msk_miibus_statchg, link down\n"));
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0);
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0, mController); // Disable Rx/Tx MAC gmac = GMAC_READ_2 (mSoftc, port, GM_GP_CTRL); if ((GM_GPCR_RX_ENA | GM_GPCR_TX_ENA) != 0) {
@@ -418,12 +458,21 @@ ether_crc32_be (
VOID mskc_rxfilter (
- EFI_HANDLE mController, UINT32 FilterFlags, UINTN MCastFilterCnt, EFI_MAC_ADDRESS *MCastFilter )
{
- msk_rxfilter (mSoftc->msk_if[MSK_PORT_A], FilterFlags, MCastFilterCnt, MCastFilter);
- EFI_STATUS Status;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data_msks (mController, &mSoftc);
- if (EFI_ERROR (Status)) {
- return;
- }
- msk_rxfilter (mSoftc->msk_if[MSK_PORT_A], FilterFlags, MCastFilterCnt, MCastFilter, mController);
}
static VOID @@ -431,13 +480,21 @@ msk_rxfilter ( struct msk_if_softc *sc_if, UINT32 FilterFlags, UINTN MCastFilterCnt,
- EFI_MAC_ADDRESS *MCastFilter
- EFI_MAC_ADDRESS *MCastFilter,
- EFI_HANDLE mController )
{
- UINT32 mchash[2];
- UINT32 crc;
- UINT16 mode;
- INTN port = sc_if->msk_md.port;
UINT32 mchash[2];
UINT32 crc;
UINT16 mode;
INTN port = sc_if->msk_md.port;
EFI_STATUS Status;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
gBS->SetMem (mchash, sizeof (mchash), 0); mode = GMAC_READ_2 (mSoftc, port, GM_RX_CTRL);
@@ -472,7 +529,8 @@ msk_rxfilter ( static VOID msk_setvlan (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc )
{ // @@ -485,7 +543,9 @@ msk_setvlan ( static EFI_STATUS msk_init_rx_ring (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ struct msk_ring_data *rd; @@ -511,7 +571,7 @@ msk_init_rx_ring ( prod = 0;
for (i = 0; i < nbuf; i++) {
Status = msk_newbuf (sc_if, prod);
Status = msk_newbuf (sc_if, prod, mPciIo); if (EFI_ERROR (Status)) { return Status; }
@@ -580,7 +640,8 @@ static EFI_STATUS msk_newbuf ( IN struct msk_if_softc *sc_if,
- IN INTN idx
- IN INTN idx,
- EFI_PCI_IO_PROTOCOL *mPciIo )
{ struct msk_rx_desc *rx_le; @@ -663,7 +724,7 @@ mskc_probe ( static VOID mskc_setup_rambuffer (
- VOID
- struct msk_softc *mSoftc )
{ INTN next; @@ -811,7 +872,8 @@ msk_phy_power ( static VOID clear_pci_errors (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ EFI_STATUS Status; @@ -847,7 +909,8 @@ clear_pci_errors ( static VOID mskc_reset (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ EFI_STATUS Status; @@ -877,7 +940,7 @@ mskc_reset ( CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_SET); CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_CLR);
- clear_pci_errors ();
- clear_pci_errors (mPciIo, mSoftc); switch (mSoftc->msk_bustype) { case MSK_PEX_BUS: // Clear all PEX errors
@@ -1055,7 +1118,10 @@ mskc_reset ( static EFI_STATUS msk_attach (
- INT32 Port
- INT32 Port,
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ struct msk_if_softc *sc_if; @@ -1077,7 +1143,7 @@ msk_attach ( sc_if->msk_rxq = Q_R2; }
- Status = msk_txrx_dma_alloc (sc_if);
- Status = msk_txrx_dma_alloc (sc_if, mPciIo); if (EFI_ERROR (Status)) { return Status; }
@@ -1099,10 +1165,10 @@ msk_attach ( sc_if->MacAddress.Addr[0], sc_if->MacAddress.Addr[1], sc_if->MacAddress.Addr[2], sc_if->MacAddress.Addr[3], sc_if->MacAddress.Addr[4], sc_if->MacAddress.Addr[5]));
- Status = e1000_probe_and_attach (&sc_if->mii_d, &sc_if->msk_md);
- Status = e1000_probe_and_attach (&sc_if->mii_d, &sc_if->msk_md, mController, Port); if (EFI_ERROR (Status)) { mSoftc->msk_if[Port] = NULL;
- msk_detach (Port);
msk_detach (Port, mController, mPciIo, mSoftc); }
return (Status);
@@ -1114,7 +1180,8 @@ msk_attach ( */ EFI_STATUS mskc_attach (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN EFI_HANDLE mController,
- IN EFI_PCI_IO_PROTOCOL *mPciIo, OUT EFI_MAC_ADDRESS *Mac )
{ @@ -1123,8 +1190,8 @@ mskc_attach ( UINT8 *PciBarResources; EFI_STATUS Status; struct msk_if_softc *ScIf;
- struct msk_softc *mSoftc;
- mPciIo = PciIo; Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct msk_softc), (VOID**) &mSoftc);
@@ -1295,7 +1362,7 @@ mskc_attach ( break; }
- Status = msk_status_dma_alloc ();
- Status = msk_status_dma_alloc (mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; }
@@ -1305,9 +1372,9 @@ mskc_attach ( mSoftc->msk_intrhwemask = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT | Y2_IS_PCI_EXP | Y2_IS_PCI_NEXP;
// Reset the adapter
- mskc_reset ();
- mskc_reset (mPciIo, mSoftc);
- mskc_setup_rambuffer ();
mskc_setup_rambuffer (mSoftc);
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct msk_if_softc),
@@ -1315,9 +1382,16 @@ mskc_attach ( if (EFI_ERROR (Status)) { goto fail; }
- //Add controller to the list
- Status = msk_add_ctrl_data (mController, mPciIo, mSoftc);
- if (EFI_ERROR (Status)) {
- goto fail;
- }
- gBS->SetMem (ScIf, sizeof (struct msk_if_softc), 0); mSoftc->msk_if[MSK_PORT_A] = ScIf;
- Status = msk_attach (MSK_PORT_A);
- Status = msk_attach (MSK_PORT_A, mController, mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; }
@@ -1342,7 +1416,7 @@ mskc_attach ( } gBS->SetMem (ScIf, sizeof (struct msk_if_softc), 0); mSoftc->msk_if[MSK_PORT_B] = ScIf;
- Status = msk_attach (MSK_PORT_B);
- Status = msk_attach (MSK_PORT_B, mController, mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; }
@@ -1360,7 +1434,7 @@ mskc_attach ( EVT_NOTIFY_SIGNAL | EVT_TIMER, TPL_CALLBACK, mskc_tick,
mSoftc,
if (EFI_ERROR (Status)) {(VOID *)mController, &mSoftc->Timer );
@@ -1373,7 +1447,7 @@ mskc_attach (
fail: if (EFI_ERROR (Status)) {
- mskc_detach ();
mskc_detach (mController); }
return (Status);
@@ -1382,7 +1456,7 @@ RESTORE_PCI_ATTRIBS: // // Restore original PCI attributes //
- mPciIo->Attributes (
+mPciIo->Attributes ( mPciIo, EfiPciIoAttributeOperationSet, mSoftc->OriginalPciAttributes, @@ -1402,34 +1476,47 @@ RESTORE_PCI_ATTRIBS: static VOID msk_detach (
- INT32 Port
- INT32 Port,
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ struct msk_if_softc *sc_if;
sc_if = mSoftc->msk_if[Port];
- msk_stop (sc_if);
- msk_stop (sc_if, mController, mPciIo, mSoftc);
- msk_txrx_dma_free (sc_if);
- msk_txrx_dma_free (sc_if, mPciIo);
- e1000phy_dettach (mController, Port);
}
VOID mskc_detach (
- VOID
- EFI_HANDLE mController )
{
- EFI_TPL OldTpl;
EFI_TPL OldTpl;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
- msk_detach (MSK_PORT_A);
- msk_detach (MSK_PORT_A, mController, mPciIo, mSoftc); gBS->FreePool (mSoftc->msk_if[MSK_PORT_A]); mSoftc->msk_if[MSK_PORT_A] = NULL; } if (mSoftc->msk_if[MSK_PORT_B] != NULL) {
- msk_detach (MSK_PORT_B);
- msk_detach (MSK_PORT_B, mController, mPciIo, mSoftc); gBS->FreePool (mSoftc->msk_if[MSK_PORT_B]); mSoftc->msk_if[MSK_PORT_B] = NULL; }
@@ -1446,7 +1533,7 @@ mskc_detach ( // Put hardware reset. CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_SET);
- msk_status_dma_free ();
msk_status_dma_free (mPciIo, mSoftc);
if (mSoftc->Timer != NULL) { gBS->SetTimer (mSoftc->Timer, TimerCancel, 0);
@@ -1463,9 +1550,8 @@ mskc_detach ( mSoftc->OriginalPciAttributes, NULL );
- msk_del_ctrl_data (mController); gBS->FreePool (mSoftc);
mSoftc = NULL;
mPciIo = NULL;
gBS->RestoreTPL (OldTpl);
} @@ -1474,7 +1560,8 @@ mskc_detach ( static EFI_STATUS msk_status_dma_alloc (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ EFI_STATUS Status; @@ -1504,7 +1591,8 @@ msk_status_dma_alloc ( static VOID msk_status_dma_free (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ if (mSoftc->msk_stat_map) { @@ -1520,7 +1608,8 @@ msk_status_dma_free ( static EFI_STATUS msk_txrx_dma_alloc (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_PCI_IO_PROTOCOL *mPciIo )
{ struct msk_txdesc *txd; @@ -1585,7 +1674,8 @@ fail: static VOID msk_txrx_dma_free (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_PCI_IO_PROTOCOL *mPciIo )
{ struct msk_txdesc *txd; @@ -1640,7 +1730,8 @@ static EFI_STATUS msk_encap ( struct msk_if_softc *sc_if,
- MSK_SYSTEM_BUF *m_head
- MSK_SYSTEM_BUF *m_head,
- EFI_PCI_IO_PROTOCOL *mPciIo )
{ struct msk_txdesc *txd; @@ -1713,12 +1804,20 @@ msk_encap (
EFI_STATUS mskc_transmit (
- UINTN BufferSize,
- VOID *Buffer
- EFI_HANDLE mController,
- UINTN BufferSize,
- VOID *Buffer )
{ MSK_LINKED_SYSTEM_BUF *LinkedSystemBuf; EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (MSK_LINKED_SYSTEM_BUF),
@@ -1734,23 +1833,33 @@ mskc_transmit ( LinkedSystemBuf->SystemBuf.Buf = Buffer; LinkedSystemBuf->SystemBuf.Length = BufferSize; InsertTailList (&mSoftc->TransmitQueueHead, &LinkedSystemBuf->Link);
- msk_start (MSK_PORT_A);
- //Force to use the first MAC
- //TODO: enable multi MAC support
- msk_start (MSK_PORT_A, mPciIo, mSoftc); return EFI_SUCCESS;
}
void mskc_getstatus (
- IN EFI_HANDLE mController, OUT UINT32 *InterruptStatus, OPTIONAL OUT VOID **TxBuf OPTIONAL )
{
- //struct msk_chain_data* cdata; MSK_LINKED_SYSTEM_BUF *m_head;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
// Interrupt status is not read from the device when InterruptStatus is NULL if (InterruptStatus != NULL) { // Check the interrupt lines
- msk_intr ();
msk_intr (mController, mPciIo, mSoftc); }
// The transmit buffer status is not read when TxBuf is NULL
@@ -1771,7 +1880,9 @@ mskc_getstatus ( static VOID msk_start (
- INT32 Port
- INT32 Port,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ EFI_STATUS Status; @@ -1793,7 +1904,7 @@ msk_start ( // don't have room, set the OACTIVE flag and wait // for the NIC to drain the ring. //
- Status = msk_encap (sc_if, &m_head->SystemBuf);
- Status = msk_encap (sc_if, &m_head->SystemBuf, mPciIo); if (EFI_ERROR (Status)) { break; }
@@ -1811,17 +1922,25 @@ msk_start (
VOID mskc_shutdown (
- VOID
- EFI_HANDLE mController )
{
- INTN i;
- EFI_TPL OldTpl;
INTN i;
EFI_TPL OldTpl;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
for (i = 0; i < mSoftc->msk_num_port; i++) { if (mSoftc->msk_if[i] != NULL) {
msk_stop (mSoftc->msk_if[i]);
} } gBS->SetTimer (mSoftc->Timer, TimerCancel, 0);msk_stop (mSoftc->msk_if[i], mController, mPciIo, mSoftc);
@@ -1834,13 +1953,22 @@ mskc_shutdown (
EFI_STATUS mskc_receive (
- IN EFI_HANDLE mController, IN OUT UINTN *BufferSize, OUT VOID *Buffer )
{ MSK_LINKED_SYSTEM_BUF *mBuf;
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- msk_intr (); // check the interrupt lines
msk_intr (mController, mPciIo, mSoftc); // check the interrupt lines
if (IsListEmpty (&mSoftc->ReceiveQueueHead)) { *BufferSize = 0;
@@ -1859,6 +1987,7 @@ mskc_receive ( gBS->CopyMem (Buffer, mBuf->SystemBuf.Buf, *BufferSize); gBS->FreePool(mBuf->SystemBuf.Buf); gBS->FreePool (mBuf);
- return EFI_SUCCESS;
}
@@ -1867,7 +1996,9 @@ msk_rxeof ( struct msk_if_softc *sc_if, UINT32 status, UINT32 control,
- INTN len
- INTN len,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ EFI_STATUS Status; @@ -1909,7 +2040,7 @@ msk_rxeof ( m.DmaMapping = rxd->rx_m.DmaMapping; m.Length = rxd->rx_m.Length;
- Status = msk_newbuf (sc_if, cons);
- Status = msk_newbuf (sc_if, cons, mPciIo); if (EFI_ERROR (Status)) { // This is a dropped packet, but we aren't counting drops // Reuse old buffer
@@ -1951,7 +2082,8 @@ static VOID msk_txeof ( struct msk_if_softc *sc_if,
- INTN idx
- INTN idx,
- EFI_PCI_IO_PROTOCOL *mPciIo )
{ struct msk_txdesc *txd; @@ -1997,11 +2129,23 @@ mskc_tick ( ) { EFI_TPL OldTpl;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
EFI_STATUS Status;
EFI_HANDLE mController;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- e1000phy_tick ();
- msk_handle_events ();
mController = (EFI_HANDLE)Context;
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (!EFI_ERROR (Status)) {
//TODO: enable multi MAC support
if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
e1000phy_tick (mController, MSK_PORT_A);
}
msk_handle_events (mPciIo, mSoftc);
}
gBS->RestoreTPL (OldTpl);
} @@ -2009,13 +2153,14 @@ mskc_tick ( static VOID msk_intr_phy (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_HANDLE mController )
{ UINT16 status;
- msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT);
- status = msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT);
msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT, mController);
status = msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT, mController);
// Handle FIFO Underrun/Overflow ? if ((status & PHY_M_IS_FIFO_ERROR)) {
@@ -2026,7 +2171,8 @@ msk_intr_phy ( static VOID msk_intr_gmac (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc )
{ UINT8 status; @@ -2059,7 +2205,8 @@ static VOID msk_handle_hwerr ( struct msk_if_softc *sc_if,
- UINT32 status
- UINT32 status,
- struct msk_softc *mSoftc )
{ if ((status & Y2_IS_PAR_RD1) != 0) { @@ -2092,7 +2239,8 @@ msk_handle_hwerr ( static VOID msk_intr_hwerr (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ UINT32 status; @@ -2123,7 +2271,7 @@ msk_intr_hwerr ( DEBUG ((EFI_D_NET, "Marvell Yukon: unexpected IRQ Master error\n")); } // Reset all bits in the PCI status register
- clear_pci_errors ();
clear_pci_errors (mPciIo, mSoftc); }
// Check for PCI Express Uncorrectable Error.
@@ -2164,10 +2312,10 @@ msk_intr_hwerr ( }
if ((status & Y2_HWE_L1_MASK) != 0 && mSoftc->msk_if[MSK_PORT_A] != NULL) {
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_A], status);
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_A], status, mSoftc); } if ((status & Y2_HWE_L2_MASK) != 0 && mSoftc->msk_if[MSK_PORT_B] != NULL) {
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_B], status >> 8);
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_B], status >> 8, mSoftc); }
}
@@ -2175,7 +2323,8 @@ static __inline VOID msk_rxput (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc )
{ CSR_WRITE_2 (mSoftc, Y2_PREF_Q_ADDR (sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG), sc_if->msk_cdata.msk_rx_prod); @@ -2184,7 +2333,8 @@ msk_rxput ( static INTN msk_handle_events (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ struct msk_if_softc *sc_if; @@ -2223,7 +2373,7 @@ msk_handle_events (
switch (control & STLE_OP_MASK) { case OP_RXSTAT:
msk_rxeof (sc_if, status, control, len);
msk_rxeof (sc_if, status, control, len, mPciIo, mSoftc); rxprog++; // // Because there is no way to sync single Rx LE
@@ -2233,20 +2383,20 @@ msk_handle_events ( rxput[port]++; // Update prefetch unit if we've passed water mark if (rxput[port] >= sc_if->msk_cdata.msk_rx_putwm) {
msk_rxput (sc_if);
msk_rxput (sc_if, mSoftc); rxput[port] = 0; } break; case OP_TXINDEXLE: if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
msk_txeof (mSoftc->msk_if[MSK_PORT_A], status & STLE_TXA1_MSKL);
msk_txeof (mSoftc->msk_if[MSK_PORT_A], status & STLE_TXA1_MSKL, mPciIo); } if (mSoftc->msk_if[MSK_PORT_B] != NULL) { msk_txeof (mSoftc->msk_if[MSK_PORT_B], ((status & STLE_TXA2_MSKL) >> STLE_TXA2_SHIFTL) | ((len & STLE_TXA2_MSKH) <<
STLE_TXA2_SHIFTH));
STLE_TXA2_SHIFTH), mPciIo); } break; default:
@@ -2262,10 +2412,10 @@ msk_handle_events ( mSoftc->msk_stat_cons = cons;
if (rxput[MSK_PORT_A] > 0) {
- msk_rxput (mSoftc->msk_if[MSK_PORT_A]);
- msk_rxput (mSoftc->msk_if[MSK_PORT_A], mSoftc); } if (rxput[MSK_PORT_B] > 0) {
- msk_rxput (mSoftc->msk_if[MSK_PORT_B]);
msk_rxput (mSoftc->msk_if[MSK_PORT_B], mSoftc); }
return (mSoftc->msk_stat_cons != CSR_READ_2 (mSoftc, STAT_PUT_IDX));
@@ -2274,7 +2424,9 @@ msk_handle_events ( STATIC VOID msk_intr (
- VOID
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ struct msk_if_softc *sc_if0; @@ -2297,16 +2449,16 @@ msk_intr ( sc_if1 = mSoftc->msk_if[MSK_PORT_B];
if ((Status & Y2_IS_IRQ_PHY1) != 0 && sc_if0 != NULL) {
- msk_intr_phy (sc_if0);
- msk_intr_phy (sc_if0, mController); } if ((Status & Y2_IS_IRQ_PHY2) != 0 && sc_if1 != NULL) {
- msk_intr_phy (sc_if1);
- msk_intr_phy (sc_if1, mController); } if ((Status & Y2_IS_IRQ_MAC1) != 0 && sc_if0 != NULL) {
- msk_intr_gmac (sc_if0);
- msk_intr_gmac (sc_if0, mSoftc); } if ((Status & Y2_IS_IRQ_MAC2) != 0 && sc_if1 != NULL) {
- msk_intr_gmac (sc_if1);
- msk_intr_gmac (sc_if1, mSoftc); } if ((Status & (Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2)) != 0) { DEBUG ((EFI_D_NET, "Marvell Yukon: Rx descriptor error\n"));
@@ -2321,10 +2473,10 @@ msk_intr ( CSR_READ_4 (mSoftc, B0_IMSK); } if ((Status & Y2_IS_HW_ERR) != 0) {
- msk_intr_hwerr ();
- msk_intr_hwerr (mPciIo, mSoftc); }
- domore = msk_handle_events ();
- domore = msk_handle_events (mPciIo, mSoftc); if ((Status & Y2_IS_STAT_BMU) != 0 && domore == 0) { CSR_WRITE_4 (mSoftc, STAT_CTRL, SC_STAT_CLR_IRQ); }
@@ -2336,7 +2488,8 @@ msk_intr ( static VOID msk_set_tx_stfwd (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc )
{ // Disable jumbo frames for Tx @@ -2345,27 +2498,48 @@ msk_set_tx_stfwd (
EFI_STATUS mskc_init (
- VOID
- EFI_HANDLE mController )
{
- EFI_STATUS Status;
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
- // Just init port A
- Status = msk_init (mSoftc->msk_if[MSK_PORT_A]);
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); if (EFI_ERROR (Status)) { return Status; }
- if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
- Status = msk_init (mSoftc->msk_if[MSK_PORT_A], mController, mPciIo, mSoftc);
- if (EFI_ERROR (Status)) {
return Status;
- }
- }
- if (mSoftc->msk_if[MSK_PORT_B] != NULL) {
- Status = msk_init (mSoftc->msk_if[MSK_PORT_B], mController, mPciIo, mSoftc);
- if (EFI_ERROR (Status)) {
return Status;
- }
- }
- Status = gBS->SetTimer (mSoftc->Timer, TimerPeriodic, TICKS_PER_SECOND); if (EFI_ERROR (Status)) {
- mskc_shutdown ();
- mskc_shutdown (mController); }
- return Status;
}
static EFI_STATUS msk_init (
- IN struct msk_if_softc *sc_if
- IN struct msk_if_softc *sc_if,
- IN EFI_HANDLE mController,
- IN EFI_PCI_IO_PROTOCOL *mPciIo,
- IN struct msk_softc *mSoftc
- )
{ UINT8 *eaddr; @@ -2375,7 +2549,7 @@ msk_init ( INTN port = sc_if->msk_md.port;
// Cancel pending I/O and free all Rx/Tx buffers.
- msk_stop (sc_if);
msk_stop (sc_if, mController, mPciIo, mSoftc);
sc_if->msk_framesize = MAX_SUPPORTED_PACKET_SIZE;
@@ -2397,7 +2571,7 @@ msk_init ( CSR_READ_1 (mSoftc, MR_ADDR (port, GMAC_IRQ_SRC));
// Clear MIB stats
- msk_stats_clear (sc_if);
msk_stats_clear (sc_if, mSoftc);
// Disable FCS GMAC_WRITE_2 (mSoftc, port, GM_RX_CTRL, GM_RXCR_CRC_DIS);
@@ -2465,14 +2639,14 @@ msk_init ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, TX_GMF_CTRL_T), GMF_OPER_ON);
// Configure hardware VLAN tag insertion/stripping
- msk_setvlan (sc_if);
msk_setvlan (sc_if, mSoftc);
if ((sc_if->msk_flags & MSK_FLAG_RAMBUF) == 0) { // Set Rx Pause threshould. CSR_WRITE_2 (mSoftc, MR_ADDR (port, RX_GMF_LP_THR), MSK_ECU_LLPP); CSR_WRITE_2 (mSoftc, MR_ADDR (port, RX_GMF_UP_THR), MSK_ECU_ULPP); // Configure store-and-forward for Tx.
- msk_set_tx_stfwd (sc_if);
msk_set_tx_stfwd (sc_if, mSoftc); }
if (mSoftc->msk_hw_id == CHIP_ID_YUKON_FE_P && mSoftc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
@@ -2491,7 +2665,7 @@ msk_init ( CSR_WRITE_1 (mSoftc, MR_ADDR (port, TXA_CTRL), TXA_ENA_ARB);
// Setup RAM buffer
- msk_set_rambuffer (sc_if);
msk_set_rambuffer (sc_if, mSoftc);
// Disable Tx sync Queue CSR_WRITE_1 (mSoftc, RB_ADDR (sc_if->msk_txsq, RB_CTRL), RB_RST_SET);
@@ -2533,16 +2707,16 @@ msk_init ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, RX_GMF_TR_THR), 0x17a); CSR_WRITE_4 (mSoftc, MR_ADDR (port, RX_GMF_CTRL_T), RX_TRUNC_ON);
- msk_set_prefetch (sc_if->msk_txq, sc_if->msk_rdata.msk_tx_ring_paddr, MSK_TX_RING_CNT - 1);
msk_set_prefetch (sc_if->msk_txq, sc_if->msk_rdata.msk_tx_ring_paddr, MSK_TX_RING_CNT - 1, mSoftc); msk_init_tx_ring (sc_if);
// Disable Rx checksum offload and RSS hash CSR_WRITE_4 (mSoftc, Q_ADDR (sc_if->msk_rxq, Q_CSR), BMU_DIS_RX_CHKSUM | BMU_DIS_RX_RSS_HASH);
- msk_set_prefetch (sc_if->msk_rxq, sc_if->msk_rdata.msk_rx_ring_paddr, MSK_RX_RING_CNT - 1);
- Status = msk_init_rx_ring (sc_if);
- msk_set_prefetch (sc_if->msk_rxq, sc_if->msk_rdata.msk_rx_ring_paddr, MSK_RX_RING_CNT - 1, mSoftc);
- Status = msk_init_rx_ring (sc_if, mPciIo, mSoftc); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: Initialization failed: no memory for Rx buffers\n"));
- msk_stop (sc_if);
- msk_stop (sc_if, mController, mPciIo, mSoftc); return Status; }
@@ -2574,7 +2748,7 @@ msk_init ( CSR_READ_4 (mSoftc, B0_IMSK);
sc_if->msk_flags &= ~MSK_FLAG_LINK;
- e1000phy_mediachg ();
e1000phy_mediachg (mController, port);
return Status;
} @@ -2582,7 +2756,8 @@ msk_init ( STATIC VOID msk_set_rambuffer (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc )
{ INTN ltpp, utpp; @@ -2626,9 +2801,10 @@ msk_set_rambuffer ( STATIC VOID msk_set_prefetch (
- INTN qaddr,
- INTN qaddr, EFI_PHYSICAL_ADDRESS addr,
- UINT32 count
- UINT32 count,
- struct msk_softc *mSoftc )
{ // Reset the prefetch unit @@ -2649,7 +2825,10 @@ msk_set_prefetch ( static VOID msk_stop (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc )
{ struct msk_txdesc *txd; @@ -2678,7 +2857,7 @@ msk_stop ( // Read again to ensure writing. GMAC_READ_2 (mSoftc, port, GM_GP_CTRL); // Update stats and clear counters
- msk_stats_update (sc_if);
msk_stats_update (sc_if, mSoftc);
// Stop Tx BMU CSR_WRITE_4 (mSoftc, Q_ADDR (sc_if->msk_txq, Q_CSR), BMU_STOP);
@@ -2700,7 +2879,7 @@ msk_stop ( // Disable all GMAC interrupt. CSR_WRITE_1 (mSoftc, MR_ADDR (port, GMAC_IRQ_MSK), 0); // Disable PHY interrupt. */
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0);
msk_phy_writereg (port, PHY_MARV_INT_MASK, 0, mController);
// Disable the RAM Interface Arbiter. CSR_WRITE_1 (mSoftc, MR_ADDR (port, TXA_CTRL), TXA_DIS_ARB);
@@ -2788,7 +2967,8 @@ msk_stop ( static VOID msk_stats_clear (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc )
{ UINT16 gmac; @@ -2812,7 +2992,8 @@ msk_stats_clear ( static VOID msk_stats_update (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc )
{ struct msk_hw_stats *stats; @@ -2877,5 +3058,125 @@ msk_stats_update ( GMAC_WRITE_2 (mSoftc, port, GM_PHY_ADDR, gmac); }
+void +mskc_init_driver_list (VOID) +{
- InitializeListHead (&msk_drv_data_head);
- e1000phy_init_driver_list ();
+}
+static +EFI_STATUS +msk_get_ctrl_data (
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL **mPciIo,
- struct msk_softc **mSoftc
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- *mSoftc = mDrvNode->mSoftc;
- *mPciIo = mDrvNode->mPciIo;
- }
- return Status;
+}
+static +EFI_STATUS +msk_get_ctrl_data_msks (
- EFI_HANDLE mController,
- struct msk_softc **mSoftc
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- *mSoftc = mDrvNode->mSoftc;
- }
- return Status;
+}
+static +EFI_STATUS +msk_add_ctrl_data (
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (EFI_ERROR(Status)) {
- Status = gBS->AllocatePool (EfiBootServicesData,
sizeof (MSK_LINKED_DRV_BUF),
(VOID**) &mDrvNode);
- if (!EFI_ERROR (Status)) {
mDrvNode->Signature = MSK_DRV_SIGNATURE;
mDrvNode->mController = mController;
mDrvNode->mPciIo = mPciIo;
mDrvNode->mSoftc = mSoftc;
InsertTailList (&msk_drv_data_head, &mDrvNode->Link);
- }
- } else {
- Status = EFI_ALREADY_STARTED;
- }
- return Status;
+}
+static +EFI_STATUS +msk_del_ctrl_data (
- EFI_HANDLE mController
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- RemoveEntryList (&mDrvNode->Link);
- gBS->FreePool (mDrvNode);
- }
- return Status;
+}
+static +EFI_STATUS +msk_find_drv_node (
- EFI_HANDLE mController,
- MSK_LINKED_DRV_BUF **mDrvNode
- )
+{
- MSK_LINKED_DRV_BUF *mDrvBuffNode;
- EFI_STATUS Status;
- LIST_ENTRY *Node;
- Status = EFI_NOT_FOUND;
- Node = GetFirstNode (&msk_drv_data_head);
- while (!IsNull (&msk_drv_data_head, Node)) {
- mDrvBuffNode = MSK_DRV_INFO_FROM_THIS (Node);
- if (mDrvBuffNode->mController == mController) {
*mDrvNode = mDrvBuffNode;
Status = EFI_SUCCESS;
break;
- }
- Node = GetNextNode (&msk_drv_data_head, Node);
- }
- return Status;
+}
#undef MSK_READ_MIB32 #undef MSK_READ_MIB64 diff --git a/Drivers/Net/MarvellYukonDxe/if_msk.h b/Drivers/Net/MarvellYukonDxe/if_msk.h index 110c562..07990fe 100644 --- a/Drivers/Net/MarvellYukonDxe/if_msk.h +++ b/Drivers/Net/MarvellYukonDxe/if_msk.h @@ -14,19 +14,21 @@ **/
#include <Uefi.h> +#include <Protocol/PciIo.h>
#define MAX_SUPPORTED_PACKET_SIZE (1566) /* No jumbo frame size support */
EFI_STATUS mskc_probe (EFI_PCI_IO_PROTOCOL *PciIo);
-EFI_STATUS mskc_attach (EFI_PCI_IO_PROTOCOL *PciIo, EFI_MAC_ADDRESS *Mac); -void mskc_detach (void); +EFI_STATUS mskc_attach (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *PciIo, EFI_MAC_ADDRESS *Mac); +void mskc_detach (EFI_HANDLE);
-EFI_STATUS mskc_init (void); -void mskc_shutdown (void); +EFI_STATUS mskc_init (EFI_HANDLE); +void mskc_shutdown (EFI_HANDLE);
void mskc_rxfilter (
- IN EFI_HANDLE mController, IN UINT32 FilterFlags, IN UINTN MCastFilterCnt, IN EFI_MAC_ADDRESS *MCastFilter
@@ -34,18 +36,26 @@ mskc_rxfilter (
EFI_STATUS mskc_transmit (
- IN EFI_HANDLE mController, IN UINTN BufferSize, IN VOID *Buffer );
EFI_STATUS mskc_receive (
- IN EFI_HANDLE mController, IN OUT UINTN *BufferSize, OUT VOID *Buffer );
void mskc_getstatus (
- IN EFI_HANDLE mController, OUT UINT32 *InterruptStatus, OPTIONAL OUT VOID **TxBuf OPTIONAL );
+void +mskc_init_driver_list (
- VOID
- );
diff --git a/Drivers/Net/MarvellYukonDxe/if_mskreg.h b/Drivers/Net/MarvellYukonDxe/if_mskreg.h index 7718536..9f11e8e 100644 --- a/Drivers/Net/MarvellYukonDxe/if_mskreg.h +++ b/Drivers/Net/MarvellYukonDxe/if_mskreg.h @@ -2466,6 +2466,23 @@ struct msk_softc { EFI_EVENT Timer; };
+typedef struct {
- UINT32 Signature;
- LIST_ENTRY Link;
- EFI_HANDLE mController;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
+} MSK_LINKED_DRV_BUF;
+#define MSK_DRV_SIGNATURE SIGNATURE_32 ('m', 's', 'k', 'c')
+#define MSK_DRV_INFO_FROM_THIS(a) \
- CR (a, \
MSK_LINKED_DRV_BUF, \
Link, \
MSK_DRV_SIGNATURE \
);
#define MSK_USECS(sc, us) ((sc)->msk_clock * (us))
/* Softc for each logical interface. */ diff --git a/Drivers/Net/MarvellYukonDxe/miivar.h b/Drivers/Net/MarvellYukonDxe/miivar.h index 1903ef6..73fba3f 100644 --- a/Drivers/Net/MarvellYukonDxe/miivar.h +++ b/Drivers/Net/MarvellYukonDxe/miivar.h @@ -55,13 +55,6 @@ #define _DEV_MII_MIIVAR_H_
/*
- Callbacks from MII layer into network interface device driver.
- */
-INTN msk_phy_readreg (INTN, INTN); -INTN msk_phy_writereg (INTN, INTN, INTN); -void msk_miibus_statchg (INTN);
-/*
- A network interface driver has one of these structures in its softc.
- It is the interface from the network interface driver to the MII
- layer.
@@ -181,9 +174,9 @@ struct mii_phydesc { #define MII_PHY_DESC(a, b) { MII_OUI_ ## a, MII_MODEL_ ## a ## _ ## b, MII_STR_ ## a ## _ ## b } #define MII_PHY_END { 0, 0, NULL }
-#define PHY_READ(p, r) msk_phy_readreg ((p)->mmd->port, (r)) +#define PHY_READ(p, r, c) msk_phy_readreg ((p)->mmd->port, (r), (c))
-#define PHY_WRITE(p, r, v) msk_phy_writereg ((p)->mmd->port, (r), (v)) +#define PHY_WRITE(p, r, v, c) msk_phy_writereg ((p)->mmd->port, (r), (v), (c))
struct msk_mii_data { INTN port; @@ -191,8 +184,4 @@ struct msk_mii_data { INTN mii_flags; };
-EFI_STATUS e1000_probe_and_attach (struct mii_data *mii, const struct msk_mii_data *mmd); -void e1000phy_tick (void); -void e1000phy_mediachg (void);
#endif /* _DEV_MII_MIIVAR_H_ */
2.7.4
Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi
Hi Ard,
Thanks for the review. Please see my comments related to "m" prefix.
Thanks,
Daniil
On 10/18/2016 05:12 AM, Ard Biesheuvel wrote:
Hi Daniil,
Thanks for looking into this.
On 17 October 2016 at 22:45, Daniil Egranov daniil.egranov@arm.com wrote:
The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
Drivers/Net/MarvellYukonDxe/DriverBinding.c | 6 +- Drivers/Net/MarvellYukonDxe/Snp.c | 46 +-- Drivers/Net/MarvellYukonDxe/e1000phy.c | 330 +++++++++++---- Drivers/Net/MarvellYukonDxe/e1000phyreg.h | 23 ++ Drivers/Net/MarvellYukonDxe/if_msk.c | 615 +++++++++++++++++++++------- Drivers/Net/MarvellYukonDxe/if_msk.h | 18 +- Drivers/Net/MarvellYukonDxe/if_mskreg.h | 17 + Drivers/Net/MarvellYukonDxe/miivar.h | 15 +- 8 files changed, 786 insertions(+), 284 deletions(-)
diff --git a/Drivers/Net/MarvellYukonDxe/DriverBinding.c b/Drivers/Net/MarvellYukonDxe/DriverBinding.c index 95068fa..fc684c0 100644 --- a/Drivers/Net/MarvellYukonDxe/DriverBinding.c +++ b/Drivers/Net/MarvellYukonDxe/DriverBinding.c @@ -192,14 +192,14 @@ MarvellYukonDriverStart ( // // Initialize Yukon card so we can get the MAC address //
- Status = mskc_attach (YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
Status = mskc_attach (Controller, YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { gBS->FreePool (YukonDriver); return Status; }
- mskc_detach();
mskc_detach (Controller);
// // Assign fields for device path
@@ -487,6 +487,8 @@ InitializeMarvellYukonDriver (
if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: InitializeMarvellYukonDriver(): Driver binding failed\n"));
} else {
mskc_init_driver_list (); }
return Status;
Could we have something like this instead, please?
""" if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: InitializeMarvellYukonDriver(): Driver binding failed\n")); return Status; } mskc_init_driver_list (); return EFI_SUCCESS; """
diff --git a/Drivers/Net/MarvellYukonDxe/Snp.c b/Drivers/Net/MarvellYukonDxe/Snp.c index 3d84f84..96cec5f 100644 --- a/Drivers/Net/MarvellYukonDxe/Snp.c +++ b/Drivers/Net/MarvellYukonDxe/Snp.c @@ -121,21 +121,21 @@ SnpGetStatus ( ) { EFI_STATUS Status;
- YUKON_DRIVER *Snp;
- YUKON_DRIVER *YukonDriver;
Could you split off this rename? (and all the associated white space only changes involving 'YUKON_DRIVER')
EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This);
- if (Snp == NULL) {
YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
if (YukonDriver == NULL) { return EFI_INVALID_PARAMETER; }
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) {
- switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -148,7 +148,7 @@ SnpGetStatus ( goto ON_EXIT; }
- mskc_getstatus (InterruptStatus, TxBuf);
mskc_getstatus (YukonDriver->Controller, InterruptStatus, TxBuf); Status = EFI_SUCCESS;
ON_EXIT:
@@ -199,7 +199,7 @@ SnpInitialize ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver;
... like this one ...
EFI_TPL OldTpl; DEBUG ((EFI_D_NET, "Marvell Yukon: SnpInitialize()\n"));
@@ -230,7 +230,7 @@ SnpInitialize ( gBS->SetMem (YukonDriver->SnpMode.MCastFilter, sizeof YukonDriver->SnpMode.MCastFilter, 0); gBS->CopyMem (&YukonDriver->SnpMode.CurrentAddress, &YukonDriver->SnpMode.PermanentAddress, sizeof (EFI_MAC_ADDRESS));
- Status = mskc_init ();
Status = mskc_init (YukonDriver->Controller);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL;
@@ -509,18 +509,18 @@ SnpReceive ( ) { EFI_STATUS Status;
- YUKON_DRIVER *Snp;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This);
YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) {
- switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -538,7 +538,7 @@ SnpReceive ( goto ON_EXIT; }
- Status = mskc_receive (BufferSize, Buffer);
- Status = mskc_receive (YukonDriver->Controller, BufferSize, Buffer); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_READY) { goto ON_EXIT_NO_DEBUG;
@@ -678,7 +678,7 @@ SnpReceiveFilters ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; UINT32 newReceiveFilter;
@@ -743,7 +743,7 @@ SnpReceiveFilters ( }
YukonDriver->SnpMode.ReceiveFilterSetting = newReceiveFilter;
- mskc_rxfilter (YukonDriver->SnpMode.ReceiveFilterSetting, MCastFilterCnt, MCastFilter);
mskc_rxfilter (YukonDriver->Controller, YukonDriver->SnpMode.ReceiveFilterSetting, MCastFilterCnt, MCastFilter);
Status = EFI_SUCCESS; goto ON_EXIT;
@@ -788,7 +788,7 @@ SnpReset ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpReset()\n"));
@@ -858,7 +858,7 @@ SnpShutdown ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpShutdown()\n"));
@@ -890,7 +890,7 @@ SnpShutdown ( goto ON_ERROR_RESTORE_TPL; }
- mskc_shutdown ();
- mskc_shutdown (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStarted; Status = EFI_SUCCESS;
@@ -938,7 +938,7 @@ SnpStart ( IN EFI_SIMPLE_NETWORK_PROTOCOL *This ) {
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -966,7 +966,7 @@ SnpStart ( goto ON_ERROR_RESTORE_TPL; }
- Status = mskc_attach (YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
Status = mskc_attach (YukonDriver->Controller, YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL;
@@ -1025,7 +1025,7 @@ SnpStationAddress ( IN EFI_MAC_ADDRESS *New OPTIONAL ) {
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -1122,7 +1122,7 @@ SnpStatistics ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStatistics()\n"));
@@ -1242,7 +1242,7 @@ SnpStop ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStop()\n"));
@@ -1269,7 +1269,7 @@ SnpStop ( goto ON_ERROR_RESTORE_TPL; }
- mskc_detach ();
- mskc_detach (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStopped; gBS->SetMem (&YukonDriver->SnpMode.CurrentAddress, sizeof (EFI_MAC_ADDRESS), 0); Status = EFI_SUCCESS;
@@ -1407,7 +1407,7 @@ SnpTransmit ( gBS->CopyMem (&Frame->EtherType, &ProtocolNet, sizeof (UINT16)); }
- Status = mskc_transmit (BufferSize, Buffer);
Status = mskc_transmit (YukonDriver->Controller, BufferSize, Buffer);
ON_EXIT: gBS->RestoreTPL (OldTpl);
diff --git a/Drivers/Net/MarvellYukonDxe/e1000phy.c b/Drivers/Net/MarvellYukonDxe/e1000phy.c index dee4cdf..ca84138 100644 --- a/Drivers/Net/MarvellYukonDxe/e1000phy.c +++ b/Drivers/Net/MarvellYukonDxe/e1000phy.c @@ -57,6 +57,7 @@ #include <Library/MemoryAllocationLib.h> #include <Library/DebugLib.h> #include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseLib.h>
#include "if_media.h"
@@ -64,27 +65,30 @@
#include "e1000phyreg.h"
+static LIST_ENTRY e1000phy_drv_data_head;
+static void e1000phy_attach (const struct mii_attach_args *ma, EFI_HANDLE, struct e1000phy_softc *); static EFI_STATUS e1000phy_probe (const struct mii_attach_args *ma); -static void e1000phy_attach (const struct mii_attach_args *ma); static const struct mii_phydesc * mii_phy_match (const struct mii_attach_args *ma, const struct mii_phydesc *mpd); static const struct mii_phydesc * mii_phy_match_gen (const struct mii_attach_args *ma, const struct mii_phydesc *mpd, UINTN endlen); static EFI_STATUS mii_phy_dev_probe (const struct mii_attach_args *ma, const struct mii_phydesc *mpd);
-struct e1000phy_softc {
- struct mii_softc mii_sc;
- INTN mii_model;
- const struct msk_mii_data *mmd;
-}; +static EFI_STATUS e1000phy_get_ctrl_data_phy (EFI_HANDLE, INT32, struct e1000phy_softc **); +static EFI_STATUS e1000phy_add_ctrl_data (EFI_HANDLE, INT32, struct e1000phy_softc *); +static EFI_STATUS e1000phy_del_ctrl_data (EFI_HANDLE, INT32); +static EFI_STATUS e1000phy_find_drv_node (EFI_HANDLE, INT32, E1000PHY_LINKED_DRV_BUF**);
-struct e1000phy_softc *mPhySoftc; +void msk_miibus_statchg (INTN, EFI_HANDLE); +INTN msk_phy_readreg (INTN, INTN, EFI_HANDLE); +INTN msk_phy_writereg (INTN, INTN, INTN, EFI_HANDLE);
-static void mii_phy_update (INTN); -static void e1000phy_service (INTN); -static void e1000phy_status (struct mii_softc *); -static void e1000phy_reset (struct mii_softc *); -static void e1000phy_mii_phy_auto (void); +static void mii_phy_update (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_service (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_status (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_reset (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_mii_phy_auto (EFI_HANDLE, struct e1000phy_softc *);
static const struct mii_phydesc e1000phys[] = { MII_PHY_DESC (MARVELL, E1000), @@ -113,12 +117,15 @@ static const struct mii_phydesc e1000phys[] = { EFI_STATUS e1000_probe_and_attach ( struct mii_data *mii,
- const struct msk_mii_data *mmd
- )
- const struct msk_mii_data *mmd,
- EFI_HANDLE mController,
- INT32 mPort
Please don't use the m prefix for struct fields or function arguments. It is intended for variables with module scope
I should not be a problem to correct new variables. The mPhySoftc and mSoftc originally were global pointers but now passed as function parameters. Changing them will require a lot of renaming inside of many many functions. I tried to keep the changes to minimum but renaming these variables will make this patch pretty big. If you think it's worth to rename them, it can be done.
- ) { struct mii_attach_args ma; INTN bmsr; EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
Please don't use the m prefix for automatic [stack] variables either.
Same here. The mPhySoftc was a global pointer and it used in many functions.
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct e1000phy_softc),
@@ -129,13 +136,12 @@ e1000_probe_and_attach ( gBS->SetMem (mPhySoftc, sizeof (struct e1000phy_softc), 0); mPhySoftc->mmd = mmd;
- /*
*/
- Check to see if there is a PHY at this address. Note,
- many braindead PHYs report 0/0 in their ID registers,
- so we test for media in the BMSR.
- bmsr = PHY_READ (mPhySoftc, E1000_SR);
- bmsr = PHY_READ (mPhySoftc, E1000_SR, mController); if (bmsr == 0 || bmsr == 0xffff || (bmsr & (E1000_SR_EXTENDED_STATUS|E1000_SR_MEDIAMASK)) == 0) { /* Assume no PHY at this address. */ gBS->FreePool (mPhySoftc);
@@ -145,8 +151,8 @@ e1000_probe_and_attach ( /* * Extract the IDs. */
- ma.mii_id1 = PHY_READ (mPhySoftc, E1000_ID1);
- ma.mii_id2 = PHY_READ (mPhySoftc, E1000_ID2);
ma.mii_id1 = PHY_READ (mPhySoftc, E1000_ID1, mController);
ma.mii_id2 = PHY_READ (mPhySoftc, E1000_ID2, mController);
ma.mii_data = mii;
@@ -156,11 +162,36 @@ e1000_probe_and_attach ( return Status; }
- e1000phy_attach (&ma);
e1000phy_attach (&ma, mController, mPhySoftc);
Status = e1000phy_add_ctrl_data (mController, mPort, mPhySoftc);
if (EFI_ERROR (Status)) {
gBS->FreePool (mPhySoftc);
return Status;
}
return EFI_SUCCESS; }
EFI_STATUS
+e1000phy_dettach (
'detach' has only one 't'
- EFI_HANDLE mController,
- INT32 mPort
- )
+{
- EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
- Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc);
- if (!EFI_ERROR (Status)) {
- e1000phy_del_ctrl_data(mController, mPort);
- gBS->FreePool(mPhySoftc);
- }
- return Status;
+}
+EFI_STATUS e1000phy_probe ( const struct mii_attach_args *ma ) @@ -170,7 +201,9 @@ e1000phy_probe (
static void e1000phy_attach (
- const struct mii_attach_args *ma
- const struct mii_attach_args *ma,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { struct mii_softc *sc;
@@ -188,7 +221,7 @@ e1000phy_attach ( switch (mPhySoftc->mii_model) { case MII_MODEL_MARVELL_E1011: case MII_MODEL_MARVELL_E1112:
if (PHY_READ (mPhySoftc, E1000_ESSR) & E1000_ESSR_FIBER_LINK) {
if (PHY_READ (mPhySoftc, E1000_ESSR, mController) & E1000_ESSR_FIBER_LINK) { sc->mii_flags |= MIIF_HAVEFIBER; } break;
@@ -204,46 +237,48 @@ e1000phy_attach ( * that information should be used to select default * type of PHY. */
PHY_WRITE (mPhySoftc, E1000_EADR, 0);
}PHY_WRITE (mPhySoftc, E1000_EADR, 0, mController); break;
- e1000phy_reset (sc);
- e1000phy_reset (sc, mController, mPhySoftc);
- sc->mii_capabilities = PHY_READ (mPhySoftc, E1000_SR) & 0xFFFFFFFF;
- sc->mii_capabilities = PHY_READ (mPhySoftc, E1000_SR, mController) & 0xFFFFFFFF; if (sc->mii_capabilities & E1000_SR_EXTENDED_STATUS) {
- sc->mii_extcapabilities = PHY_READ (mPhySoftc, E1000_ESR);
sc->mii_extcapabilities = PHY_READ (mPhySoftc, E1000_ESR, mController); } }
static void e1000phy_reset (
- struct mii_softc *sc
- struct mii_softc *sc,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { UINT16 reg; UINT16 page;
- reg = PHY_READ (mPhySoftc, E1000_SCR);
- reg = PHY_READ (mPhySoftc, E1000_SCR, mController); if ((sc->mii_flags & MIIF_HAVEFIBER) != 0) { reg &= ~E1000_SCR_AUTO_X_MODE;
- PHY_WRITE (mPhySoftc, E1000_SCR, reg);
- PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); if (mPhySoftc->mii_model == MII_MODEL_MARVELL_E1112) { // Select 1000BASE-X only mode.
page = PHY_READ (mPhySoftc, E1000_EADR);
PHY_WRITE (mPhySoftc, E1000_EADR, 2);
reg = PHY_READ (mPhySoftc, E1000_SCR);
page = PHY_READ (mPhySoftc, E1000_EADR, mController);
PHY_WRITE (mPhySoftc, E1000_EADR, 2, mController);
reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg &= ~E1000_SCR_MODE_MASK; reg |= E1000_SCR_MODE_1000BX;
PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); if (mPhySoftc->mmd != NULL && mPhySoftc->mmd->pmd == 'P') { // Set SIGDET polarity low for SFP module
PHY_WRITE (mPhySoftc, E1000_EADR, 1);
reg = PHY_READ (mPhySoftc, E1000_SCR);
PHY_WRITE (mPhySoftc, E1000_EADR, 1, mController);
reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg |= E1000_SCR_FIB_SIGDET_POLARITY;
PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); }
PHY_WRITE (mPhySoftc, E1000_EADR, page);
} else { switch (mPhySoftc->mii_model) {PHY_WRITE (mPhySoftc, E1000_EADR, page, mController); }
@@ -270,7 +305,7 @@ e1000phy_reset ( E1000_SCR_SCRAMBLER_DISABLE); reg |= E1000_SCR_LPNP; // XXX Enable class A driver for Yukon FE+ A0
PHY_WRITE (mPhySoftc, 0x1C, PHY_READ (mPhySoftc, 0x1C) | 0x0001);
PHY_WRITE (mPhySoftc, 0x1C, PHY_READ (mPhySoftc, 0x1C, mController) | 0x0001, mController); break; default: reg &= ~E1000_SCR_AUTO_X_MODE;
@@ -281,15 +316,15 @@ e1000phy_reset ( /* Auto correction for reversed cable polarity. */ reg &= ~E1000_SCR_POLARITY_REVERSAL; }
- PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController);
if (mPhySoftc->mii_model == MII_MODEL_MARVELL_E1116 || mPhySoftc->mii_model == MII_MODEL_MARVELL_E1149) {
PHY_WRITE (mPhySoftc, E1000_EADR, 2);
reg = PHY_READ (mPhySoftc, E1000_SCR);
PHY_WRITE (mPhySoftc, E1000_EADR, 2, mController);
reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg |= E1000_SCR_RGMII_POWER_UP;
PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_EADR, 0);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController);
}PHY_WRITE (mPhySoftc, E1000_EADR, 0, mController); }
@@ -299,42 +334,45 @@ e1000phy_reset ( case MII_MODEL_MARVELL_E1118: break; case MII_MODEL_MARVELL_E1116:
page = PHY_READ (mPhySoftc, E1000_EADR);
page = PHY_READ (mPhySoftc, E1000_EADR, mController); /* Select page 3, LED control register. */
PHY_WRITE (mPhySoftc, E1000_EADR, 3);
PHY_WRITE (mPhySoftc, E1000_EADR, 3, mController); PHY_WRITE (mPhySoftc, E1000_SCR, E1000_SCR_LED_LOS (1) | /* Link/Act */ E1000_SCR_LED_INIT (8) | /* 10Mbps */ E1000_SCR_LED_STAT1 (7) | /* 100Mbps */
E1000_SCR_LED_STAT0 (7)); /* 1000Mbps */
E1000_SCR_LED_STAT0 (7), /* 1000Mbps */
mController); /* Set blink rate. */
PHY_WRITE (mPhySoftc, E1000_IER, E1000_PULSE_DUR (E1000_PULSE_170MS) | E1000_BLINK_RATE (E1000_BLINK_84MS));
PHY_WRITE (mPhySoftc, E1000_EADR, page);
PHY_WRITE (mPhySoftc, E1000_IER, E1000_PULSE_DUR (E1000_PULSE_170MS) | E1000_BLINK_RATE (E1000_BLINK_84MS), mController);
PHY_WRITE (mPhySoftc, E1000_EADR, page, mController); break; case MII_MODEL_MARVELL_E3016: /* LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED. */
PHY_WRITE (mPhySoftc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04);
PHY_WRITE (mPhySoftc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04, mController); /* Integrated register calibration workaround. */
PHY_WRITE (mPhySoftc, 0x1D, 17);
PHY_WRITE (mPhySoftc, 0x1E, 0x3F60);
PHY_WRITE (mPhySoftc, 0x1D, 17, mController);
PHY_WRITE (mPhySoftc, 0x1E, 0x3F60, mController); break; default: /* Force TX_CLK to 25MHz clock. */
reg = PHY_READ (mPhySoftc, E1000_ESCR);
reg = PHY_READ (mPhySoftc, E1000_ESCR, mController); reg |= E1000_ESCR_TX_CLK_25;
PHY_WRITE (mPhySoftc, E1000_ESCR, reg);
PHY_WRITE (mPhySoftc, E1000_ESCR, reg, mController); break;
}
/* Reset the PHY so all changes take effect. */
- reg = PHY_READ (mPhySoftc, E1000_CR);
- reg = PHY_READ (mPhySoftc, E1000_CR, mController); reg |= E1000_CR_RESET;
- PHY_WRITE (mPhySoftc, E1000_CR, reg);
PHY_WRITE (mPhySoftc, E1000_CR, reg, mController); }
static void mii_phy_update (
- INTN cmd
- INTN cmd,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { struct mii_softc *sc = &mPhySoftc->mii_sc;
@@ -344,7 +382,7 @@ mii_phy_update ( sc->mii_media_status != mii->mii_media_status || cmd == MII_MEDIACHG) {
- msk_miibus_statchg (mPhySoftc->mmd->port);
- msk_miibus_statchg (mPhySoftc->mmd->port, mController); sc->mii_media_active = mii->mii_media_active; sc->mii_media_status = mii->mii_media_status; }
@@ -352,27 +390,43 @@ mii_phy_update (
void e1000phy_tick (
- VOID
- EFI_HANDLE mController,
- INT32 mPort ) {
- e1000phy_service (MII_TICK);
EFI_STATUS Status;
struct e1000phy_softc *mPhySoftc;
Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc);
if (!EFI_ERROR (Status)) {
e1000phy_service (MII_TICK, mController, mPhySoftc);
} }
void e1000phy_mediachg (
- VOID
- EFI_HANDLE mController,
- INT32 mPort ) {
- struct mii_data *mii = mPhySoftc->mii_sc.mii_pdata;
- mii->mii_media_status = 0;
- mii->mii_media_active = IFM_NONE;
- e1000phy_service (MII_MEDIACHG);
EFI_STATUS Status;
struct e1000phy_softc *mPhySoftc;
Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc);
if (!EFI_ERROR (Status)) {
struct mii_data *mii = mPhySoftc->mii_sc.mii_pdata;
mii->mii_media_status = 0;
mii->mii_media_active = IFM_NONE;
e1000phy_service (MII_MEDIACHG, mController, mPhySoftc);
} }
static void e1000phy_service (
- INTN cmd
- )
- INTN cmd,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc
- ) { struct mii_softc *sc = &mPhySoftc->mii_sc; INTN reg;
@@ -385,7 +439,7 @@ e1000phy_service ( // // Always try to auto-negotiate //
e1000phy_mii_phy_auto ();
e1000phy_mii_phy_auto (mController, mPhySoftc); break; case MII_TICK:
@@ -393,7 +447,7 @@ e1000phy_service ( * check for link. * Read the status register twice; Link Status is latch-low. */
reg = PHY_READ (mPhySoftc, E1000_SR) | PHY_READ (mPhySoftc, E1000_SR);
reg = PHY_READ (mPhySoftc, E1000_SR, mController) | PHY_READ (mPhySoftc, E1000_SR, mController); if (reg & E1000_SR_LINK_STATUS) { sc->mii_ticks = 0; break;
@@ -411,21 +465,23 @@ e1000phy_service ( // Restart the auto-negotiation // sc->mii_ticks = 0;
e1000phy_reset (sc);
e1000phy_mii_phy_auto ();
e1000phy_reset (sc, mController, mPhySoftc);
e1000phy_mii_phy_auto (mController, mPhySoftc); break;
}
/* Update the media status. */
- e1000phy_status (sc);
e1000phy_status (sc, mController, mPhySoftc);
/* Callback if something changed. */
- mii_phy_update (cmd);
mii_phy_update (cmd, mController, mPhySoftc); }
static void e1000phy_status (
- struct mii_softc *sc
- struct mii_softc *sc,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { struct mii_data *mii = sc->mii_pdata;
@@ -439,9 +495,9 @@ e1000phy_status ( mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER;
- bmsr = PHY_READ (mPhySoftc, E1000_SR) | PHY_READ (mPhySoftc, E1000_SR);
- bmcr = PHY_READ (mPhySoftc, E1000_CR);
- ssr = PHY_READ (mPhySoftc, E1000_SSR);
bmsr = PHY_READ (mPhySoftc, E1000_SR, mController) | PHY_READ (mPhySoftc, E1000_SR, mController);
bmcr = PHY_READ (mPhySoftc, E1000_CR, mController);
ssr = PHY_READ (mPhySoftc, E1000_SSR, mController);
if (bmsr & E1000_SR_LINK_STATUS) { DEBUG ((EFI_D_NET, "Marvell Yukon: e1000phy_status, link up\n"));
@@ -489,8 +545,8 @@ e1000phy_status ( }
if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
- ar = PHY_READ (mPhySoftc, E1000_AR);
- lpar = PHY_READ (mPhySoftc, E1000_LPAR);
- ar = PHY_READ (mPhySoftc, E1000_AR, mController);
- lpar = PHY_READ (mPhySoftc, E1000_LPAR, mController); /* FLAG0==rx-flow-control FLAG1==tx-flow-control */ if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) { mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1;
@@ -506,8 +562,8 @@ e1000phy_status ( /* FLAG2 : local PHY resolved to MASTER */ if ((IFM_SUBTYPE (mii->mii_media_active) == IFM_1000_T) || (IFM_SUBTYPE (mii->mii_media_active) == IFM_1000_SX)) {
- PHY_READ (mPhySoftc, E1000_1GSR);
- gsr = PHY_READ (mPhySoftc, E1000_1GSR);
- PHY_READ (mPhySoftc, E1000_1GSR, mController);
- gsr = PHY_READ (mPhySoftc, E1000_1GSR, mController); if ((gsr & E1000_1GSR_MS_CONFIG_RES) != 0) { mii->mii_media_active |= IFM_FLAG2; }
@@ -516,7 +572,8 @@ e1000phy_status (
static void e1000phy_mii_phy_auto (
- VOID
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { struct mii_softc *sc;
@@ -525,20 +582,20 @@ e1000phy_mii_phy_auto ( DEBUG ((EFI_D_NET, "Marvell Yukon: e1000phy_mii_phy_auto negotiation started\n")); sc = &mPhySoftc->mii_sc; if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
- reg = PHY_READ (mPhySoftc, E1000_AR);
- reg = PHY_READ (mPhySoftc, E1000_AR, mController); reg |= E1000_AR_10T | E1000_AR_10T_FD | E1000_AR_100TX | E1000_AR_100TX_FD | E1000_AR_PAUSE | E1000_AR_ASM_DIR;
- PHY_WRITE (mPhySoftc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD);
- PHY_WRITE (mPhySoftc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD, mController); } else {
- PHY_WRITE (mPhySoftc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE);
PHY_WRITE (mPhySoftc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE, mController); }
if ((sc->mii_extcapabilities & (E1000_ESR_1000T_FD | E1000_ESR_1000T)) != 0) {
- PHY_WRITE (mPhySoftc, E1000_1GCR, E1000_1GCR_1000T_FD | E1000_1GCR_1000T);
- PHY_WRITE (mPhySoftc, E1000_1GCR, E1000_1GCR_1000T_FD | E1000_1GCR_1000T, mController); }
- PHY_WRITE (mPhySoftc, E1000_CR, E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG);
PHY_WRITE (mPhySoftc, E1000_CR, E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG, mController); }
//
@@ -589,3 +646,106 @@ mii_phy_dev_probe ( DEBUG ((EFI_D_NET, "Marvell Yukon: PHY not found (OUI=0x%x, MODEL=0x%x)\n", MII_OUI (ma->mii_id1, ma->mii_id2), MII_MODEL (ma->mii_id2))); return EFI_NOT_FOUND; }
+void +e1000phy_init_driver_list (void) +{
- InitializeListHead (&e1000phy_drv_data_head);
+}
+static +EFI_STATUS +e1000phy_get_ctrl_data_phy (
- EFI_HANDLE mController,
- INT32 mPort,
- struct e1000phy_softc **mPhySoftc
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- *mPhySoftc = mDrvNode->mPhySoftc;
- }
- return Status;
+}
+static +EFI_STATUS +e1000phy_add_ctrl_data (
- EFI_HANDLE mController,
- INT32 mPort,
- struct e1000phy_softc *mPhySoftc
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode);
- if (EFI_ERROR(Status)) {
- Status = gBS->AllocatePool (EfiBootServicesData,
sizeof (E1000PHY_LINKED_DRV_BUF),
(VOID**) &mDrvNode);
- if (!EFI_ERROR (Status)) {
mDrvNode->Signature = E1000PHY_DRV_SIGNATURE;
mDrvNode->mController = mController;
mDrvNode->mPort = mPort;
mDrvNode->mPhySoftc = mPhySoftc;
InsertTailList (&e1000phy_drv_data_head, &mDrvNode->Link);
- }
- } else {
- Status = EFI_ALREADY_STARTED;
- }
- return Status;
+}
+static +EFI_STATUS +e1000phy_del_ctrl_data (
- EFI_HANDLE mController,
- INT32 mPort
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- RemoveEntryList (&mDrvNode->Link);
- gBS->FreePool (mDrvNode);
- }
- return Status;
+}
+static +EFI_STATUS +e1000phy_find_drv_node (
- EFI_HANDLE mController,
- INT32 mPort,
- E1000PHY_LINKED_DRV_BUF **mDrvNode
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvBuffNode;
- EFI_STATUS Status;
- LIST_ENTRY *Node;
- Status = EFI_NOT_FOUND;
- Node = GetFirstNode (&e1000phy_drv_data_head);
- while (!IsNull (&e1000phy_drv_data_head, Node)) {
- mDrvBuffNode = E1000PHY_DRV_INFO_FROM_THIS (Node);
- if (mDrvBuffNode->mController == mController &&
mDrvBuffNode->mPort == mPort) {
*mDrvNode = mDrvBuffNode;
Status = EFI_SUCCESS;
break;
- }
- Node = GetNextNode (&e1000phy_drv_data_head, Node);
- }
- return Status;
+} diff --git a/Drivers/Net/MarvellYukonDxe/e1000phyreg.h b/Drivers/Net/MarvellYukonDxe/e1000phyreg.h index a87b1f1..d0bfd25 100644 --- a/Drivers/Net/MarvellYukonDxe/e1000phyreg.h +++ b/Drivers/Net/MarvellYukonDxe/e1000phyreg.h @@ -396,3 +396,26 @@ #define E1000_ESSR_GMII_FIBER 0x0007 #define E1000_ESSR_TBI_COPPER 0x000d #define E1000_ESSR_TBI_FIBER 0x0005
+struct e1000phy_softc {
- struct mii_softc mii_sc;
- INTN mii_model;
- const struct msk_mii_data *mmd;
+};
+typedef struct {
- UINT32 Signature;
- LIST_ENTRY Link;
- INT32 mPort;
- EFI_HANDLE mController;
- struct e1000phy_softc *mPhySoftc;
+} E1000PHY_LINKED_DRV_BUF;
+#define E1000PHY_DRV_SIGNATURE SIGNATURE_32 ('e', 'p', 'h', 'y')
+#define E1000PHY_DRV_INFO_FROM_THIS(a) \
- CR (a, \
E1000PHY_LINKED_DRV_BUF, \
Link, \
E1000PHY_DRV_SIGNATURE \
);
diff --git a/Drivers/Net/MarvellYukonDxe/if_msk.c b/Drivers/Net/MarvellYukonDxe/if_msk.c index d23f893..3f41d45 100644 --- a/Drivers/Net/MarvellYukonDxe/if_msk.c +++ b/Drivers/Net/MarvellYukonDxe/if_msk.c @@ -121,11 +121,7 @@ #include "if_mskreg.h" #include "if_msk.h"
-// -// Global Variables -// -static EFI_PCI_IO_PROTOCOL *mPciIo; -static struct msk_softc *mSoftc; +static LIST_ENTRY msk_drv_data_head;
#define MSK_CSUM_FEATURES (CSUM_TCP | CSUM_UDP)
@@ -189,49 +185,67 @@ static const CHAR8 *model_name[] = { // // Forward declarations // -static VOID mskc_setup_rambuffer (VOID); -static VOID mskc_reset (VOID); +static VOID mskc_setup_rambuffer (struct msk_softc *); +static VOID mskc_reset (EFI_PCI_IO_PROTOCOL *, struct msk_softc *);
-static EFI_STATUS msk_attach (INT32); -static VOID msk_detach (INT32); +static EFI_STATUS msk_attach (INT32, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_detach (INT32, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *);
static VOID mskc_tick (IN EFI_EVENT, IN VOID*); -static VOID msk_intr (VOID); -static VOID msk_intr_phy (struct msk_if_softc *); -static VOID msk_intr_gmac (struct msk_if_softc *); -static __inline VOID msk_rxput (struct msk_if_softc *); -static INTN msk_handle_events (VOID); -static VOID msk_handle_hwerr (struct msk_if_softc *, UINT32); -static VOID msk_intr_hwerr (VOID); -static VOID msk_rxeof (struct msk_if_softc *, UINT32, UINT32, INTN); -static VOID msk_txeof (struct msk_if_softc *, INTN); -static EFI_STATUS msk_encap (struct msk_if_softc *, MSK_SYSTEM_BUF *); -static VOID msk_start (INT32); -static VOID msk_set_prefetch (INTN, EFI_PHYSICAL_ADDRESS, UINT32); -static VOID msk_set_rambuffer (struct msk_if_softc *); -static VOID msk_set_tx_stfwd (struct msk_if_softc *); -static EFI_STATUS msk_init (struct msk_if_softc *); -static VOID msk_stop (struct msk_if_softc *); +static VOID msk_intr (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_intr_phy (struct msk_if_softc *, EFI_HANDLE); +static VOID msk_intr_gmac (struct msk_if_softc *, struct msk_softc *); +static __inline VOID msk_rxput (struct msk_if_softc *, struct msk_softc *); +static INTN msk_handle_events (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_handle_hwerr (struct msk_if_softc *, UINT32, struct msk_softc *); +static VOID msk_intr_hwerr (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_rxeof (struct msk_if_softc *, UINT32, UINT32, INTN, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_txeof (struct msk_if_softc *, INTN, EFI_PCI_IO_PROTOCOL *); +static EFI_STATUS msk_encap (struct msk_if_softc *, MSK_SYSTEM_BUF *, EFI_PCI_IO_PROTOCOL *); +static VOID msk_start (INT32, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_set_prefetch (INTN, EFI_PHYSICAL_ADDRESS, UINT32, struct msk_softc *); +static VOID msk_set_rambuffer (struct msk_if_softc *, struct msk_softc *); +static VOID msk_set_tx_stfwd (struct msk_if_softc *, struct msk_softc *); +static EFI_STATUS msk_init (struct msk_if_softc *, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_stop (struct msk_if_softc *, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); static VOID msk_phy_power (struct msk_softc *, INTN); -static EFI_STATUS msk_status_dma_alloc (VOID); -static VOID msk_status_dma_free (VOID); -static EFI_STATUS msk_txrx_dma_alloc (struct msk_if_softc *); -static VOID msk_txrx_dma_free (struct msk_if_softc *); -static EFI_STATUS msk_init_rx_ring (struct msk_if_softc *); +INTN msk_phy_readreg (INTN, INTN, EFI_HANDLE); +INTN msk_phy_writereg (INTN, INTN, INTN, EFI_HANDLE); +static EFI_STATUS msk_status_dma_alloc (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_status_dma_free (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static EFI_STATUS msk_txrx_dma_alloc (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *); +static VOID msk_txrx_dma_free (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *); +static EFI_STATUS msk_init_rx_ring (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); static VOID msk_init_tx_ring (struct msk_if_softc *); static __inline VOID msk_discard_rxbuf (struct msk_if_softc *, INTN); -static EFI_STATUS msk_newbuf (struct msk_if_softc *, INTN); +static EFI_STATUS msk_newbuf (struct msk_if_softc *, INTN, EFI_PCI_IO_PROTOCOL *);
static VOID msk_rxfilter ( struct msk_if_softc *sc_if, UINT32 FilterFlags, UINTN MCastFilterCnt,
- EFI_MAC_ADDRESS *MCastFilter
- EFI_MAC_ADDRESS *MCastFilter,
- EFI_HANDLE mController );
-static VOID msk_setvlan (struct msk_if_softc *);
-static VOID msk_stats_clear (struct msk_if_softc *); -static VOID msk_stats_update (struct msk_if_softc *); +static VOID msk_setvlan (struct msk_if_softc *, struct msk_softc *);
+static VOID msk_stats_clear (struct msk_if_softc *, struct msk_softc *); +static VOID msk_stats_update (struct msk_if_softc *, struct msk_softc *); +static VOID clear_pci_errors (EFI_PCI_IO_PROTOCOL *, struct msk_softc *);
+EFI_STATUS e1000_probe_and_attach (struct mii_data *, const struct msk_mii_data *, EFI_HANDLE, INT32); +void e1000phy_tick (EFI_HANDLE, INT32); +void e1000phy_mediachg (EFI_HANDLE, INT32); +void e1000phy_init_driver_list (void); +EFI_STATUS e1000phy_dettach (EFI_HANDLE, INT32);
+static EFI_STATUS msk_get_ctrl_data (EFI_HANDLE, EFI_PCI_IO_PROTOCOL **,
struct msk_softc **);
+static EFI_STATUS msk_get_ctrl_data_msks (EFI_HANDLE, struct msk_softc **); +static EFI_STATUS msk_add_ctrl_data (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *,
struct msk_softc *);
+static EFI_STATUS msk_del_ctrl_data (EFI_HANDLE); +static EFI_STATUS msk_find_drv_node (EFI_HANDLE, MSK_LINKED_DRV_BUF **);
// // Functions @@ -239,12 +253,20 @@ static VOID msk_stats_update (struct msk_if_softc *);
INTN msk_phy_readreg (
- INTN port,
- INTN reg
- INTN port,
- INTN reg,
- EFI_HANDLE mController ) {
- INTN i;
- INTN val;
INTN i;
INTN val;
EFI_STATUS Status;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc);
if (EFI_ERROR (Status)) {
return 0;
}
GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
@@ -267,12 +289,20 @@ msk_phy_readreg (
INTN msk_phy_writereg (
- INTN port,
- INTN reg,
- INTN val
INTN port,
INTN reg,
INTN val,
EFI_HANDLE mController ) { INTN i;
EFI_STATUS Status;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc);
if (EFI_ERROR (Status)) {
return 0;
}
GMAC_WRITE_2 (mSoftc, port, GM_SMI_DATA, val); GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
@@ -291,13 +321,23 @@ msk_phy_writereg (
VOID msk_miibus_statchg (
- INTN port
- INTN port,
- EFI_HANDLE mController ) {
- struct msk_if_softc *sc_if = mSoftc->msk_if[port];
- struct mii_data *mii = &sc_if->mii_d;
struct msk_if_softc *sc_if;
struct mii_data *mii; UINT32 gmac;
EFI_STATUS Status;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
sc_if = mSoftc->msk_if[port];
mii = &sc_if->mii_d; sc_if->msk_flags &= ~MSK_FLAG_LINK;
if ((mii->mii_media_status & (IFM_AVALID | IFM_ACTIVE)) == (IFM_AVALID | IFM_ACTIVE)) {
@@ -370,14 +410,14 @@ msk_miibus_statchg ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, GMAC_CTRL), gmac);
// Enable PHY interrupt for FIFO underrun/overflow
- msk_phy_writereg (port, PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR);
- msk_phy_writereg (port, PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR, mController); } else { // // Link state changed to down. // Disable PHY interrupts. // DEBUG ((EFI_D_NET, "Marvell Yukon: msk_miibus_statchg, link down\n"));
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0);
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0, mController); // Disable Rx/Tx MAC gmac = GMAC_READ_2 (mSoftc, port, GM_GP_CTRL); if ((GM_GPCR_RX_ENA | GM_GPCR_TX_ENA) != 0) {
@@ -418,12 +458,21 @@ ether_crc32_be (
VOID mskc_rxfilter (
- EFI_HANDLE mController, UINT32 FilterFlags, UINTN MCastFilterCnt, EFI_MAC_ADDRESS *MCastFilter ) {
- msk_rxfilter (mSoftc->msk_if[MSK_PORT_A], FilterFlags, MCastFilterCnt, MCastFilter);
EFI_STATUS Status;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
msk_rxfilter (mSoftc->msk_if[MSK_PORT_A], FilterFlags, MCastFilterCnt, MCastFilter, mController); }
static VOID
@@ -431,13 +480,21 @@ msk_rxfilter ( struct msk_if_softc *sc_if, UINT32 FilterFlags, UINTN MCastFilterCnt,
- EFI_MAC_ADDRESS *MCastFilter
- EFI_MAC_ADDRESS *MCastFilter,
- EFI_HANDLE mController ) {
- UINT32 mchash[2];
- UINT32 crc;
- UINT16 mode;
- INTN port = sc_if->msk_md.port;
UINT32 mchash[2];
UINT32 crc;
UINT16 mode;
INTN port = sc_if->msk_md.port;
EFI_STATUS Status;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
gBS->SetMem (mchash, sizeof (mchash), 0); mode = GMAC_READ_2 (mSoftc, port, GM_RX_CTRL);
@@ -472,7 +529,8 @@ msk_rxfilter ( static VOID msk_setvlan (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { //
@@ -485,7 +543,9 @@ msk_setvlan ( static EFI_STATUS msk_init_rx_ring (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_ring_data *rd;
@@ -511,7 +571,7 @@ msk_init_rx_ring ( prod = 0;
for (i = 0; i < nbuf; i++) {
Status = msk_newbuf (sc_if, prod);
Status = msk_newbuf (sc_if, prod, mPciIo); if (EFI_ERROR (Status)) { return Status; }
@@ -580,7 +640,8 @@ static EFI_STATUS msk_newbuf ( IN struct msk_if_softc *sc_if,
- IN INTN idx
- IN INTN idx,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_rx_desc *rx_le;
@@ -663,7 +724,7 @@ mskc_probe ( static VOID mskc_setup_rambuffer (
- VOID
- struct msk_softc *mSoftc ) { INTN next;
@@ -811,7 +872,8 @@ msk_phy_power ( static VOID clear_pci_errors (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -847,7 +909,8 @@ clear_pci_errors ( static VOID mskc_reset (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -877,7 +940,7 @@ mskc_reset ( CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_SET); CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_CLR);
- clear_pci_errors ();
- clear_pci_errors (mPciIo, mSoftc); switch (mSoftc->msk_bustype) { case MSK_PEX_BUS: // Clear all PEX errors
@@ -1055,7 +1118,10 @@ mskc_reset ( static EFI_STATUS msk_attach (
- INT32 Port
- INT32 Port,
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if;
@@ -1077,7 +1143,7 @@ msk_attach ( sc_if->msk_rxq = Q_R2; }
- Status = msk_txrx_dma_alloc (sc_if);
- Status = msk_txrx_dma_alloc (sc_if, mPciIo); if (EFI_ERROR (Status)) { return Status; }
@@ -1099,10 +1165,10 @@ msk_attach ( sc_if->MacAddress.Addr[0], sc_if->MacAddress.Addr[1], sc_if->MacAddress.Addr[2], sc_if->MacAddress.Addr[3], sc_if->MacAddress.Addr[4], sc_if->MacAddress.Addr[5]));
- Status = e1000_probe_and_attach (&sc_if->mii_d, &sc_if->msk_md);
- Status = e1000_probe_and_attach (&sc_if->mii_d, &sc_if->msk_md, mController, Port); if (EFI_ERROR (Status)) { mSoftc->msk_if[Port] = NULL;
- msk_detach (Port);
msk_detach (Port, mController, mPciIo, mSoftc); }
return (Status);
@@ -1114,7 +1180,8 @@ msk_attach ( */ EFI_STATUS mskc_attach (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN EFI_HANDLE mController,
- IN EFI_PCI_IO_PROTOCOL *mPciIo, OUT EFI_MAC_ADDRESS *Mac ) {
@@ -1123,8 +1190,8 @@ mskc_attach ( UINT8 *PciBarResources; EFI_STATUS Status; struct msk_if_softc *ScIf;
- struct msk_softc *mSoftc;
- mPciIo = PciIo; Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct msk_softc), (VOID**) &mSoftc);
@@ -1295,7 +1362,7 @@ mskc_attach ( break; }
- Status = msk_status_dma_alloc ();
- Status = msk_status_dma_alloc (mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; }
@@ -1305,9 +1372,9 @@ mskc_attach ( mSoftc->msk_intrhwemask = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT | Y2_IS_PCI_EXP | Y2_IS_PCI_NEXP;
// Reset the adapter
- mskc_reset ();
- mskc_reset (mPciIo, mSoftc);
- mskc_setup_rambuffer ();
mskc_setup_rambuffer (mSoftc);
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct msk_if_softc),
@@ -1315,9 +1382,16 @@ mskc_attach ( if (EFI_ERROR (Status)) { goto fail; }
- //Add controller to the list
- Status = msk_add_ctrl_data (mController, mPciIo, mSoftc);
- if (EFI_ERROR (Status)) {
- goto fail;
- }
- gBS->SetMem (ScIf, sizeof (struct msk_if_softc), 0); mSoftc->msk_if[MSK_PORT_A] = ScIf;
- Status = msk_attach (MSK_PORT_A);
- Status = msk_attach (MSK_PORT_A, mController, mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; }
@@ -1342,7 +1416,7 @@ mskc_attach ( } gBS->SetMem (ScIf, sizeof (struct msk_if_softc), 0); mSoftc->msk_if[MSK_PORT_B] = ScIf;
- Status = msk_attach (MSK_PORT_B);
- Status = msk_attach (MSK_PORT_B, mController, mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; }
@@ -1360,7 +1434,7 @@ mskc_attach ( EVT_NOTIFY_SIGNAL | EVT_TIMER, TPL_CALLBACK, mskc_tick,
mSoftc,
if (EFI_ERROR (Status)) {(VOID *)mController, &mSoftc->Timer );
@@ -1373,7 +1447,7 @@ mskc_attach (
fail: if (EFI_ERROR (Status)) {
- mskc_detach ();
mskc_detach (mController); }
return (Status);
@@ -1382,7 +1456,7 @@ RESTORE_PCI_ATTRIBS: // // Restore original PCI attributes //
- mPciIo->Attributes (
+mPciIo->Attributes ( mPciIo, EfiPciIoAttributeOperationSet, mSoftc->OriginalPciAttributes, @@ -1402,34 +1476,47 @@ RESTORE_PCI_ATTRIBS: static VOID msk_detach (
- INT32 Port
INT32 Port,
EFI_HANDLE mController,
EFI_PCI_IO_PROTOCOL *mPciIo,
struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if;
sc_if = mSoftc->msk_if[Port];
- msk_stop (sc_if);
- msk_stop (sc_if, mController, mPciIo, mSoftc);
- msk_txrx_dma_free (sc_if);
msk_txrx_dma_free (sc_if, mPciIo);
e1000phy_dettach (mController, Port); }
VOID mskc_detach (
- VOID
- EFI_HANDLE mController ) {
- EFI_TPL OldTpl;
EFI_TPL OldTpl;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
- msk_detach (MSK_PORT_A);
- msk_detach (MSK_PORT_A, mController, mPciIo, mSoftc); gBS->FreePool (mSoftc->msk_if[MSK_PORT_A]); mSoftc->msk_if[MSK_PORT_A] = NULL; } if (mSoftc->msk_if[MSK_PORT_B] != NULL) {
- msk_detach (MSK_PORT_B);
- msk_detach (MSK_PORT_B, mController, mPciIo, mSoftc); gBS->FreePool (mSoftc->msk_if[MSK_PORT_B]); mSoftc->msk_if[MSK_PORT_B] = NULL; }
@@ -1446,7 +1533,7 @@ mskc_detach ( // Put hardware reset. CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_SET);
- msk_status_dma_free ();
msk_status_dma_free (mPciIo, mSoftc);
if (mSoftc->Timer != NULL) { gBS->SetTimer (mSoftc->Timer, TimerCancel, 0);
@@ -1463,9 +1550,8 @@ mskc_detach ( mSoftc->OriginalPciAttributes, NULL );
- msk_del_ctrl_data (mController); gBS->FreePool (mSoftc);
mSoftc = NULL;
mPciIo = NULL;
gBS->RestoreTPL (OldTpl); }
@@ -1474,7 +1560,8 @@ mskc_detach ( static EFI_STATUS msk_status_dma_alloc (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -1504,7 +1591,8 @@ msk_status_dma_alloc ( static VOID msk_status_dma_free (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { if (mSoftc->msk_stat_map) {
@@ -1520,7 +1608,8 @@ msk_status_dma_free ( static EFI_STATUS msk_txrx_dma_alloc (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd;
@@ -1585,7 +1674,8 @@ fail: static VOID msk_txrx_dma_free (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd;
@@ -1640,7 +1730,8 @@ static EFI_STATUS msk_encap ( struct msk_if_softc *sc_if,
- MSK_SYSTEM_BUF *m_head
- MSK_SYSTEM_BUF *m_head,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd;
@@ -1713,12 +1804,20 @@ msk_encap (
EFI_STATUS mskc_transmit (
- UINTN BufferSize,
- VOID *Buffer
EFI_HANDLE mController,
UINTN BufferSize,
VOID *Buffer ) { MSK_LINKED_SYSTEM_BUF *LinkedSystemBuf; EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (MSK_LINKED_SYSTEM_BUF),
@@ -1734,23 +1833,33 @@ mskc_transmit ( LinkedSystemBuf->SystemBuf.Buf = Buffer; LinkedSystemBuf->SystemBuf.Length = BufferSize; InsertTailList (&mSoftc->TransmitQueueHead, &LinkedSystemBuf->Link);
- msk_start (MSK_PORT_A);
//Force to use the first MAC
//TODO: enable multi MAC support
msk_start (MSK_PORT_A, mPciIo, mSoftc); return EFI_SUCCESS; }
void mskc_getstatus (
IN EFI_HANDLE mController, OUT UINT32 *InterruptStatus, OPTIONAL OUT VOID **TxBuf OPTIONAL ) {
- //struct msk_chain_data* cdata; MSK_LINKED_SYSTEM_BUF *m_head;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
// Interrupt status is not read from the device when InterruptStatus is NULL if (InterruptStatus != NULL) { // Check the interrupt lines
- msk_intr ();
msk_intr (mController, mPciIo, mSoftc); }
// The transmit buffer status is not read when TxBuf is NULL
@@ -1771,7 +1880,9 @@ mskc_getstatus ( static VOID msk_start (
- INT32 Port
- INT32 Port,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -1793,7 +1904,7 @@ msk_start ( // don't have room, set the OACTIVE flag and wait // for the NIC to drain the ring. //
- Status = msk_encap (sc_if, &m_head->SystemBuf);
- Status = msk_encap (sc_if, &m_head->SystemBuf, mPciIo); if (EFI_ERROR (Status)) { break; }
@@ -1811,17 +1922,25 @@ msk_start (
VOID mskc_shutdown (
- VOID
- EFI_HANDLE mController ) {
- INTN i;
- EFI_TPL OldTpl;
INTN i;
EFI_TPL OldTpl;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (EFI_ERROR (Status)) {
return;
}
for (i = 0; i < mSoftc->msk_num_port; i++) { if (mSoftc->msk_if[i] != NULL) {
msk_stop (mSoftc->msk_if[i]);
} gBS->SetTimer (mSoftc->Timer, TimerCancel, 0);msk_stop (mSoftc->msk_if[i], mController, mPciIo, mSoftc); }
@@ -1834,13 +1953,22 @@ mskc_shutdown (
EFI_STATUS mskc_receive (
- IN EFI_HANDLE mController, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { MSK_LINKED_SYSTEM_BUF *mBuf;
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- msk_intr (); // check the interrupt lines
msk_intr (mController, mPciIo, mSoftc); // check the interrupt lines
if (IsListEmpty (&mSoftc->ReceiveQueueHead)) { *BufferSize = 0;
@@ -1859,6 +1987,7 @@ mskc_receive ( gBS->CopyMem (Buffer, mBuf->SystemBuf.Buf, *BufferSize); gBS->FreePool(mBuf->SystemBuf.Buf); gBS->FreePool (mBuf);
- return EFI_SUCCESS; }
@@ -1867,7 +1996,9 @@ msk_rxeof ( struct msk_if_softc *sc_if, UINT32 status, UINT32 control,
- INTN len
- INTN len,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -1909,7 +2040,7 @@ msk_rxeof ( m.DmaMapping = rxd->rx_m.DmaMapping; m.Length = rxd->rx_m.Length;
- Status = msk_newbuf (sc_if, cons);
- Status = msk_newbuf (sc_if, cons, mPciIo); if (EFI_ERROR (Status)) { // This is a dropped packet, but we aren't counting drops // Reuse old buffer
@@ -1951,7 +2082,8 @@ static VOID msk_txeof ( struct msk_if_softc *sc_if,
- INTN idx
- INTN idx,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd;
@@ -1997,11 +2129,23 @@ mskc_tick ( ) { EFI_TPL OldTpl;
EFI_PCI_IO_PROTOCOL *mPciIo;
struct msk_softc *mSoftc;
EFI_STATUS Status;
EFI_HANDLE mController;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- e1000phy_tick ();
- msk_handle_events ();
mController = (EFI_HANDLE)Context;
Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
if (!EFI_ERROR (Status)) {
//TODO: enable multi MAC support
if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
e1000phy_tick (mController, MSK_PORT_A);
}
msk_handle_events (mPciIo, mSoftc);
}
gBS->RestoreTPL (OldTpl); }
@@ -2009,13 +2153,14 @@ mskc_tick ( static VOID msk_intr_phy (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_HANDLE mController ) { UINT16 status;
- msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT);
- status = msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT);
msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT, mController);
status = msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT, mController);
// Handle FIFO Underrun/Overflow ? if ((status & PHY_M_IS_FIFO_ERROR)) {
@@ -2026,7 +2171,8 @@ msk_intr_phy ( static VOID msk_intr_gmac (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { UINT8 status;
@@ -2059,7 +2205,8 @@ static VOID msk_handle_hwerr ( struct msk_if_softc *sc_if,
- UINT32 status
- UINT32 status,
- struct msk_softc *mSoftc ) { if ((status & Y2_IS_PAR_RD1) != 0) {
@@ -2092,7 +2239,8 @@ msk_handle_hwerr ( static VOID msk_intr_hwerr (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { UINT32 status;
@@ -2123,7 +2271,7 @@ msk_intr_hwerr ( DEBUG ((EFI_D_NET, "Marvell Yukon: unexpected IRQ Master error\n")); } // Reset all bits in the PCI status register
- clear_pci_errors ();
clear_pci_errors (mPciIo, mSoftc); }
// Check for PCI Express Uncorrectable Error.
@@ -2164,10 +2312,10 @@ msk_intr_hwerr ( }
if ((status & Y2_HWE_L1_MASK) != 0 && mSoftc->msk_if[MSK_PORT_A] != NULL) {
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_A], status);
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_A], status, mSoftc); } if ((status & Y2_HWE_L2_MASK) != 0 && mSoftc->msk_if[MSK_PORT_B] != NULL) {
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_B], status >> 8);
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_B], status >> 8, mSoftc); } }
@@ -2175,7 +2323,8 @@ static __inline VOID msk_rxput (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { CSR_WRITE_2 (mSoftc, Y2_PREF_Q_ADDR (sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG), sc_if->msk_cdata.msk_rx_prod);
@@ -2184,7 +2333,8 @@ msk_rxput ( static INTN msk_handle_events (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if;
@@ -2223,7 +2373,7 @@ msk_handle_events (
switch (control & STLE_OP_MASK) { case OP_RXSTAT:
msk_rxeof (sc_if, status, control, len);
msk_rxeof (sc_if, status, control, len, mPciIo, mSoftc); rxprog++; // // Because there is no way to sync single Rx LE
@@ -2233,20 +2383,20 @@ msk_handle_events ( rxput[port]++; // Update prefetch unit if we've passed water mark if (rxput[port] >= sc_if->msk_cdata.msk_rx_putwm) {
msk_rxput (sc_if);
msk_rxput (sc_if, mSoftc); rxput[port] = 0; } break; case OP_TXINDEXLE: if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
msk_txeof (mSoftc->msk_if[MSK_PORT_A], status & STLE_TXA1_MSKL);
msk_txeof (mSoftc->msk_if[MSK_PORT_A], status & STLE_TXA1_MSKL, mPciIo); } if (mSoftc->msk_if[MSK_PORT_B] != NULL) { msk_txeof (mSoftc->msk_if[MSK_PORT_B], ((status & STLE_TXA2_MSKL) >> STLE_TXA2_SHIFTL) | ((len & STLE_TXA2_MSKH) <<
STLE_TXA2_SHIFTH));
STLE_TXA2_SHIFTH), mPciIo); } break; default:
@@ -2262,10 +2412,10 @@ msk_handle_events ( mSoftc->msk_stat_cons = cons;
if (rxput[MSK_PORT_A] > 0) {
- msk_rxput (mSoftc->msk_if[MSK_PORT_A]);
- msk_rxput (mSoftc->msk_if[MSK_PORT_A], mSoftc); } if (rxput[MSK_PORT_B] > 0) {
- msk_rxput (mSoftc->msk_if[MSK_PORT_B]);
msk_rxput (mSoftc->msk_if[MSK_PORT_B], mSoftc); }
return (mSoftc->msk_stat_cons != CSR_READ_2 (mSoftc, STAT_PUT_IDX));
@@ -2274,7 +2424,9 @@ msk_handle_events ( STATIC VOID msk_intr (
- VOID
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if0;
@@ -2297,16 +2449,16 @@ msk_intr ( sc_if1 = mSoftc->msk_if[MSK_PORT_B];
if ((Status & Y2_IS_IRQ_PHY1) != 0 && sc_if0 != NULL) {
- msk_intr_phy (sc_if0);
- msk_intr_phy (sc_if0, mController); } if ((Status & Y2_IS_IRQ_PHY2) != 0 && sc_if1 != NULL) {
- msk_intr_phy (sc_if1);
- msk_intr_phy (sc_if1, mController); } if ((Status & Y2_IS_IRQ_MAC1) != 0 && sc_if0 != NULL) {
- msk_intr_gmac (sc_if0);
- msk_intr_gmac (sc_if0, mSoftc); } if ((Status & Y2_IS_IRQ_MAC2) != 0 && sc_if1 != NULL) {
- msk_intr_gmac (sc_if1);
- msk_intr_gmac (sc_if1, mSoftc); } if ((Status & (Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2)) != 0) { DEBUG ((EFI_D_NET, "Marvell Yukon: Rx descriptor error\n"));
@@ -2321,10 +2473,10 @@ msk_intr ( CSR_READ_4 (mSoftc, B0_IMSK); } if ((Status & Y2_IS_HW_ERR) != 0) {
- msk_intr_hwerr ();
- msk_intr_hwerr (mPciIo, mSoftc); }
- domore = msk_handle_events ();
- domore = msk_handle_events (mPciIo, mSoftc); if ((Status & Y2_IS_STAT_BMU) != 0 && domore == 0) { CSR_WRITE_4 (mSoftc, STAT_CTRL, SC_STAT_CLR_IRQ); }
@@ -2336,7 +2488,8 @@ msk_intr ( static VOID msk_set_tx_stfwd (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { // Disable jumbo frames for Tx
@@ -2345,27 +2498,48 @@ msk_set_tx_stfwd (
EFI_STATUS mskc_init (
- VOID
- EFI_HANDLE mController ) {
- EFI_STATUS Status;
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
- // Just init port A
- Status = msk_init (mSoftc->msk_if[MSK_PORT_A]);
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); if (EFI_ERROR (Status)) { return Status; }
- if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
- Status = msk_init (mSoftc->msk_if[MSK_PORT_A], mController, mPciIo, mSoftc);
- if (EFI_ERROR (Status)) {
return Status;
- }
- }
- if (mSoftc->msk_if[MSK_PORT_B] != NULL) {
- Status = msk_init (mSoftc->msk_if[MSK_PORT_B], mController, mPciIo, mSoftc);
- if (EFI_ERROR (Status)) {
return Status;
- }
- }
- Status = gBS->SetTimer (mSoftc->Timer, TimerPeriodic, TICKS_PER_SECOND); if (EFI_ERROR (Status)) {
- mskc_shutdown ();
mskc_shutdown (mController); }
return Status; }
static EFI_STATUS msk_init (
- IN struct msk_if_softc *sc_if
- IN struct msk_if_softc *sc_if,
- IN EFI_HANDLE mController,
- IN EFI_PCI_IO_PROTOCOL *mPciIo,
- IN struct msk_softc *mSoftc
{ UINT8 *eaddr;)
@@ -2375,7 +2549,7 @@ msk_init ( INTN port = sc_if->msk_md.port;
// Cancel pending I/O and free all Rx/Tx buffers.
- msk_stop (sc_if);
msk_stop (sc_if, mController, mPciIo, mSoftc);
sc_if->msk_framesize = MAX_SUPPORTED_PACKET_SIZE;
@@ -2397,7 +2571,7 @@ msk_init ( CSR_READ_1 (mSoftc, MR_ADDR (port, GMAC_IRQ_SRC));
// Clear MIB stats
- msk_stats_clear (sc_if);
msk_stats_clear (sc_if, mSoftc);
// Disable FCS GMAC_WRITE_2 (mSoftc, port, GM_RX_CTRL, GM_RXCR_CRC_DIS);
@@ -2465,14 +2639,14 @@ msk_init ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, TX_GMF_CTRL_T), GMF_OPER_ON);
// Configure hardware VLAN tag insertion/stripping
- msk_setvlan (sc_if);
msk_setvlan (sc_if, mSoftc);
if ((sc_if->msk_flags & MSK_FLAG_RAMBUF) == 0) { // Set Rx Pause threshould. CSR_WRITE_2 (mSoftc, MR_ADDR (port, RX_GMF_LP_THR), MSK_ECU_LLPP); CSR_WRITE_2 (mSoftc, MR_ADDR (port, RX_GMF_UP_THR), MSK_ECU_ULPP); // Configure store-and-forward for Tx.
- msk_set_tx_stfwd (sc_if);
msk_set_tx_stfwd (sc_if, mSoftc); }
if (mSoftc->msk_hw_id == CHIP_ID_YUKON_FE_P && mSoftc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
@@ -2491,7 +2665,7 @@ msk_init ( CSR_WRITE_1 (mSoftc, MR_ADDR (port, TXA_CTRL), TXA_ENA_ARB);
// Setup RAM buffer
- msk_set_rambuffer (sc_if);
msk_set_rambuffer (sc_if, mSoftc);
// Disable Tx sync Queue CSR_WRITE_1 (mSoftc, RB_ADDR (sc_if->msk_txsq, RB_CTRL), RB_RST_SET);
@@ -2533,16 +2707,16 @@ msk_init ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, RX_GMF_TR_THR), 0x17a); CSR_WRITE_4 (mSoftc, MR_ADDR (port, RX_GMF_CTRL_T), RX_TRUNC_ON);
- msk_set_prefetch (sc_if->msk_txq, sc_if->msk_rdata.msk_tx_ring_paddr, MSK_TX_RING_CNT - 1);
msk_set_prefetch (sc_if->msk_txq, sc_if->msk_rdata.msk_tx_ring_paddr, MSK_TX_RING_CNT - 1, mSoftc); msk_init_tx_ring (sc_if);
// Disable Rx checksum offload and RSS hash CSR_WRITE_4 (mSoftc, Q_ADDR (sc_if->msk_rxq, Q_CSR), BMU_DIS_RX_CHKSUM | BMU_DIS_RX_RSS_HASH);
- msk_set_prefetch (sc_if->msk_rxq, sc_if->msk_rdata.msk_rx_ring_paddr, MSK_RX_RING_CNT - 1);
- Status = msk_init_rx_ring (sc_if);
- msk_set_prefetch (sc_if->msk_rxq, sc_if->msk_rdata.msk_rx_ring_paddr, MSK_RX_RING_CNT - 1, mSoftc);
- Status = msk_init_rx_ring (sc_if, mPciIo, mSoftc); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: Initialization failed: no memory for Rx buffers\n"));
- msk_stop (sc_if);
- msk_stop (sc_if, mController, mPciIo, mSoftc); return Status; }
@@ -2574,7 +2748,7 @@ msk_init ( CSR_READ_4 (mSoftc, B0_IMSK);
sc_if->msk_flags &= ~MSK_FLAG_LINK;
- e1000phy_mediachg ();
e1000phy_mediachg (mController, port);
return Status; }
@@ -2582,7 +2756,8 @@ msk_init ( STATIC VOID msk_set_rambuffer (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { INTN ltpp, utpp;
@@ -2626,9 +2801,10 @@ msk_set_rambuffer ( STATIC VOID msk_set_prefetch (
- INTN qaddr,
- INTN qaddr, EFI_PHYSICAL_ADDRESS addr,
- UINT32 count
- UINT32 count,
- struct msk_softc *mSoftc ) { // Reset the prefetch unit
@@ -2649,7 +2825,10 @@ msk_set_prefetch ( static VOID msk_stop (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_txdesc *txd;
@@ -2678,7 +2857,7 @@ msk_stop ( // Read again to ensure writing. GMAC_READ_2 (mSoftc, port, GM_GP_CTRL); // Update stats and clear counters
- msk_stats_update (sc_if);
msk_stats_update (sc_if, mSoftc);
// Stop Tx BMU CSR_WRITE_4 (mSoftc, Q_ADDR (sc_if->msk_txq, Q_CSR), BMU_STOP);
@@ -2700,7 +2879,7 @@ msk_stop ( // Disable all GMAC interrupt. CSR_WRITE_1 (mSoftc, MR_ADDR (port, GMAC_IRQ_MSK), 0); // Disable PHY interrupt. */
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0);
msk_phy_writereg (port, PHY_MARV_INT_MASK, 0, mController);
// Disable the RAM Interface Arbiter. CSR_WRITE_1 (mSoftc, MR_ADDR (port, TXA_CTRL), TXA_DIS_ARB);
@@ -2788,7 +2967,8 @@ msk_stop ( static VOID msk_stats_clear (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { UINT16 gmac;
@@ -2812,7 +2992,8 @@ msk_stats_clear ( static VOID msk_stats_update (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { struct msk_hw_stats *stats;
@@ -2877,5 +3058,125 @@ msk_stats_update ( GMAC_WRITE_2 (mSoftc, port, GM_PHY_ADDR, gmac); }
+void +mskc_init_driver_list (VOID) +{
- InitializeListHead (&msk_drv_data_head);
- e1000phy_init_driver_list ();
+}
+static +EFI_STATUS +msk_get_ctrl_data (
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL **mPciIo,
- struct msk_softc **mSoftc
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- *mSoftc = mDrvNode->mSoftc;
- *mPciIo = mDrvNode->mPciIo;
- }
- return Status;
+}
+static +EFI_STATUS +msk_get_ctrl_data_msks (
- EFI_HANDLE mController,
- struct msk_softc **mSoftc
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- *mSoftc = mDrvNode->mSoftc;
- }
- return Status;
+}
+static +EFI_STATUS +msk_add_ctrl_data (
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (EFI_ERROR(Status)) {
- Status = gBS->AllocatePool (EfiBootServicesData,
sizeof (MSK_LINKED_DRV_BUF),
(VOID**) &mDrvNode);
- if (!EFI_ERROR (Status)) {
mDrvNode->Signature = MSK_DRV_SIGNATURE;
mDrvNode->mController = mController;
mDrvNode->mPciIo = mPciIo;
mDrvNode->mSoftc = mSoftc;
InsertTailList (&msk_drv_data_head, &mDrvNode->Link);
- }
- } else {
- Status = EFI_ALREADY_STARTED;
- }
- return Status;
+}
+static +EFI_STATUS +msk_del_ctrl_data (
- EFI_HANDLE mController
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- RemoveEntryList (&mDrvNode->Link);
- gBS->FreePool (mDrvNode);
- }
- return Status;
+}
+static +EFI_STATUS +msk_find_drv_node (
- EFI_HANDLE mController,
- MSK_LINKED_DRV_BUF **mDrvNode
- )
+{
- MSK_LINKED_DRV_BUF *mDrvBuffNode;
- EFI_STATUS Status;
- LIST_ENTRY *Node;
- Status = EFI_NOT_FOUND;
- Node = GetFirstNode (&msk_drv_data_head);
- while (!IsNull (&msk_drv_data_head, Node)) {
- mDrvBuffNode = MSK_DRV_INFO_FROM_THIS (Node);
- if (mDrvBuffNode->mController == mController) {
*mDrvNode = mDrvBuffNode;
Status = EFI_SUCCESS;
break;
- }
- Node = GetNextNode (&msk_drv_data_head, Node);
- }
- return Status;
+}
- #undef MSK_READ_MIB32 #undef MSK_READ_MIB64
diff --git a/Drivers/Net/MarvellYukonDxe/if_msk.h b/Drivers/Net/MarvellYukonDxe/if_msk.h index 110c562..07990fe 100644 --- a/Drivers/Net/MarvellYukonDxe/if_msk.h +++ b/Drivers/Net/MarvellYukonDxe/if_msk.h @@ -14,19 +14,21 @@ **/
#include <Uefi.h> +#include <Protocol/PciIo.h>
#define MAX_SUPPORTED_PACKET_SIZE (1566) /* No jumbo frame size support */
EFI_STATUS mskc_probe (EFI_PCI_IO_PROTOCOL *PciIo);
-EFI_STATUS mskc_attach (EFI_PCI_IO_PROTOCOL *PciIo, EFI_MAC_ADDRESS *Mac); -void mskc_detach (void); +EFI_STATUS mskc_attach (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *PciIo, EFI_MAC_ADDRESS *Mac); +void mskc_detach (EFI_HANDLE);
-EFI_STATUS mskc_init (void); -void mskc_shutdown (void); +EFI_STATUS mskc_init (EFI_HANDLE); +void mskc_shutdown (EFI_HANDLE);
void mskc_rxfilter (
- IN EFI_HANDLE mController, IN UINT32 FilterFlags, IN UINTN MCastFilterCnt, IN EFI_MAC_ADDRESS *MCastFilter
@@ -34,18 +36,26 @@ mskc_rxfilter (
EFI_STATUS mskc_transmit (
IN EFI_HANDLE mController, IN UINTN BufferSize, IN VOID *Buffer );
EFI_STATUS mskc_receive (
IN EFI_HANDLE mController, IN OUT UINTN *BufferSize, OUT VOID *Buffer );
void mskc_getstatus (
IN EFI_HANDLE mController, OUT UINT32 *InterruptStatus, OPTIONAL OUT VOID **TxBuf OPTIONAL );
+void +mskc_init_driver_list (
- VOID
- );
diff --git a/Drivers/Net/MarvellYukonDxe/if_mskreg.h b/Drivers/Net/MarvellYukonDxe/if_mskreg.h index 7718536..9f11e8e 100644 --- a/Drivers/Net/MarvellYukonDxe/if_mskreg.h +++ b/Drivers/Net/MarvellYukonDxe/if_mskreg.h @@ -2466,6 +2466,23 @@ struct msk_softc { EFI_EVENT Timer; };
+typedef struct {
- UINT32 Signature;
- LIST_ENTRY Link;
- EFI_HANDLE mController;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
+} MSK_LINKED_DRV_BUF;
+#define MSK_DRV_SIGNATURE SIGNATURE_32 ('m', 's', 'k', 'c')
+#define MSK_DRV_INFO_FROM_THIS(a) \
CR (a, \
MSK_LINKED_DRV_BUF, \
Link, \
MSK_DRV_SIGNATURE \
);
#define MSK_USECS(sc, us) ((sc)->msk_clock * (us))
/* Softc for each logical interface. */
diff --git a/Drivers/Net/MarvellYukonDxe/miivar.h b/Drivers/Net/MarvellYukonDxe/miivar.h index 1903ef6..73fba3f 100644 --- a/Drivers/Net/MarvellYukonDxe/miivar.h +++ b/Drivers/Net/MarvellYukonDxe/miivar.h @@ -55,13 +55,6 @@ #define _DEV_MII_MIIVAR_H_
/*
- Callbacks from MII layer into network interface device driver.
- */
-INTN msk_phy_readreg (INTN, INTN); -INTN msk_phy_writereg (INTN, INTN, INTN); -void msk_miibus_statchg (INTN);
-/*
- A network interface driver has one of these structures in its softc.
- It is the interface from the network interface driver to the MII
- layer.
@@ -181,9 +174,9 @@ struct mii_phydesc { #define MII_PHY_DESC(a, b) { MII_OUI_ ## a, MII_MODEL_ ## a ## _ ## b, MII_STR_ ## a ## _ ## b } #define MII_PHY_END { 0, 0, NULL }
-#define PHY_READ(p, r) msk_phy_readreg ((p)->mmd->port, (r)) +#define PHY_READ(p, r, c) msk_phy_readreg ((p)->mmd->port, (r), (c))
-#define PHY_WRITE(p, r, v) msk_phy_writereg ((p)->mmd->port, (r), (v)) +#define PHY_WRITE(p, r, v, c) msk_phy_writereg ((p)->mmd->port, (r), (v), (c))
struct msk_mii_data { INTN port; @@ -191,8 +184,4 @@ struct msk_mii_data { INTN mii_flags; };
-EFI_STATUS e1000_probe_and_attach (struct mii_data *mii, const struct msk_mii_data *mmd); -void e1000phy_tick (void); -void e1000phy_mediachg (void);
- #endif /* _DEV_MII_MIIVAR_H_ */
-- 2.7.4
Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi
Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi
On 10/18/2016 12:44 PM, Daniil Egranov wrote:
Hi Ard,
Thanks for the review. Please see my comments related to "m" prefix.
Thanks,
Daniil
On 10/18/2016 05:12 AM, Ard Biesheuvel wrote:
Hi Daniil,
Thanks for looking into this.
On 17 October 2016 at 22:45, Daniil Egranov daniil.egranov@arm.com wrote:
The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
Drivers/Net/MarvellYukonDxe/DriverBinding.c | 6 +- Drivers/Net/MarvellYukonDxe/Snp.c | 46 +-- Drivers/Net/MarvellYukonDxe/e1000phy.c | 330 +++++++++++---- Drivers/Net/MarvellYukonDxe/e1000phyreg.h | 23 ++ Drivers/Net/MarvellYukonDxe/if_msk.c | 615 +++++++++++++++++++++------- Drivers/Net/MarvellYukonDxe/if_msk.h | 18 +- Drivers/Net/MarvellYukonDxe/if_mskreg.h | 17 + Drivers/Net/MarvellYukonDxe/miivar.h | 15 +- 8 files changed, 786 insertions(+), 284 deletions(-)
diff --git a/Drivers/Net/MarvellYukonDxe/DriverBinding.c b/Drivers/Net/MarvellYukonDxe/DriverBinding.c index 95068fa..fc684c0 100644 --- a/Drivers/Net/MarvellYukonDxe/DriverBinding.c +++ b/Drivers/Net/MarvellYukonDxe/DriverBinding.c @@ -192,14 +192,14 @@ MarvellYukonDriverStart ( // // Initialize Yukon card so we can get the MAC address //
- Status = mskc_attach (YukonDriver->PciIo,
&YukonDriver->SnpMode.PermanentAddress);
- Status = mskc_attach (Controller, YukonDriver->PciIo,
&YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { gBS->FreePool (YukonDriver); return Status; }
- mskc_detach();
mskc_detach (Controller);
// // Assign fields for device path
@@ -487,6 +487,8 @@ InitializeMarvellYukonDriver (
if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon:
InitializeMarvellYukonDriver(): Driver binding failed\n"));
} else {
mskc_init_driver_list (); }
return Status;
Could we have something like this instead, please?
""" if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: InitializeMarvellYukonDriver(): Driver binding failed\n")); return Status; } mskc_init_driver_list (); return EFI_SUCCESS; """
diff --git a/Drivers/Net/MarvellYukonDxe/Snp.c b/Drivers/Net/MarvellYukonDxe/Snp.c index 3d84f84..96cec5f 100644 --- a/Drivers/Net/MarvellYukonDxe/Snp.c +++ b/Drivers/Net/MarvellYukonDxe/Snp.c @@ -121,21 +121,21 @@ SnpGetStatus ( ) { EFI_STATUS Status;
- YUKON_DRIVER *Snp;
- YUKON_DRIVER *YukonDriver;
Could you split off this rename? (and all the associated white space only changes involving 'YUKON_DRIVER')
EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This);
- if (Snp == NULL) {
YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
if (YukonDriver == NULL) { return EFI_INVALID_PARAMETER; }
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) {
- switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -148,7 +148,7 @@ SnpGetStatus ( goto ON_EXIT; }
- mskc_getstatus (InterruptStatus, TxBuf);
mskc_getstatus (YukonDriver->Controller, InterruptStatus, TxBuf); Status = EFI_SUCCESS;
ON_EXIT:
@@ -199,7 +199,7 @@ SnpInitialize ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver;
... like this one ...
EFI_TPL OldTpl; DEBUG ((EFI_D_NET, "Marvell Yukon: SnpInitialize()\n"));
@@ -230,7 +230,7 @@ SnpInitialize ( gBS->SetMem (YukonDriver->SnpMode.MCastFilter, sizeof YukonDriver->SnpMode.MCastFilter, 0); gBS->CopyMem (&YukonDriver->SnpMode.CurrentAddress, &YukonDriver->SnpMode.PermanentAddress, sizeof (EFI_MAC_ADDRESS));
- Status = mskc_init ();
Status = mskc_init (YukonDriver->Controller);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL;
@@ -509,18 +509,18 @@ SnpReceive ( ) { EFI_STATUS Status;
- YUKON_DRIVER *Snp;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This);
YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) {
- switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -538,7 +538,7 @@ SnpReceive ( goto ON_EXIT; }
- Status = mskc_receive (BufferSize, Buffer);
- Status = mskc_receive (YukonDriver->Controller, BufferSize, Buffer); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_READY) { goto ON_EXIT_NO_DEBUG;
@@ -678,7 +678,7 @@ SnpReceiveFilters ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; UINT32 newReceiveFilter;
@@ -743,7 +743,7 @@ SnpReceiveFilters ( }
YukonDriver->SnpMode.ReceiveFilterSetting = newReceiveFilter;
- mskc_rxfilter (YukonDriver->SnpMode.ReceiveFilterSetting,
MCastFilterCnt, MCastFilter);
- mskc_rxfilter (YukonDriver->Controller,
YukonDriver->SnpMode.ReceiveFilterSetting, MCastFilterCnt, MCastFilter);
Status = EFI_SUCCESS; goto ON_EXIT;
@@ -788,7 +788,7 @@ SnpReset ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpReset()\n"));
@@ -858,7 +858,7 @@ SnpShutdown ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpShutdown()\n"));
@@ -890,7 +890,7 @@ SnpShutdown ( goto ON_ERROR_RESTORE_TPL; }
- mskc_shutdown ();
- mskc_shutdown (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStarted; Status = EFI_SUCCESS;
@@ -938,7 +938,7 @@ SnpStart ( IN EFI_SIMPLE_NETWORK_PROTOCOL *This ) {
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -966,7 +966,7 @@ SnpStart ( goto ON_ERROR_RESTORE_TPL; }
- Status = mskc_attach (YukonDriver->PciIo,
&YukonDriver->SnpMode.PermanentAddress);
- Status = mskc_attach (YukonDriver->Controller,
YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL;
@@ -1025,7 +1025,7 @@ SnpStationAddress ( IN EFI_MAC_ADDRESS *New OPTIONAL ) {
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -1122,7 +1122,7 @@ SnpStatistics ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStatistics()\n"));
@@ -1242,7 +1242,7 @@ SnpStop ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStop()\n"));
@@ -1269,7 +1269,7 @@ SnpStop ( goto ON_ERROR_RESTORE_TPL; }
- mskc_detach ();
- mskc_detach (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStopped; gBS->SetMem (&YukonDriver->SnpMode.CurrentAddress, sizeof
(EFI_MAC_ADDRESS), 0); Status = EFI_SUCCESS; @@ -1407,7 +1407,7 @@ SnpTransmit ( gBS->CopyMem (&Frame->EtherType, &ProtocolNet, sizeof (UINT16)); }
- Status = mskc_transmit (BufferSize, Buffer);
- Status = mskc_transmit (YukonDriver->Controller, BufferSize,
Buffer);
ON_EXIT: gBS->RestoreTPL (OldTpl); diff --git a/Drivers/Net/MarvellYukonDxe/e1000phy.c b/Drivers/Net/MarvellYukonDxe/e1000phy.c index dee4cdf..ca84138 100644 --- a/Drivers/Net/MarvellYukonDxe/e1000phy.c +++ b/Drivers/Net/MarvellYukonDxe/e1000phy.c @@ -57,6 +57,7 @@ #include <Library/MemoryAllocationLib.h> #include <Library/DebugLib.h> #include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseLib.h>
#include "if_media.h"
@@ -64,27 +65,30 @@
#include "e1000phyreg.h"
+static LIST_ENTRY e1000phy_drv_data_head;
+static void e1000phy_attach (const struct mii_attach_args *ma, EFI_HANDLE, struct e1000phy_softc *); static EFI_STATUS e1000phy_probe (const struct mii_attach_args *ma); -static void e1000phy_attach (const struct mii_attach_args *ma); static const struct mii_phydesc * mii_phy_match (const struct mii_attach_args *ma, const struct mii_phydesc *mpd); static const struct mii_phydesc * mii_phy_match_gen (const struct mii_attach_args *ma, const struct mii_phydesc *mpd, UINTN endlen); static EFI_STATUS mii_phy_dev_probe (const struct mii_attach_args *ma, const struct mii_phydesc *mpd);
-struct e1000phy_softc {
- struct mii_softc mii_sc;
- INTN mii_model;
- const struct msk_mii_data *mmd;
-}; +static EFI_STATUS e1000phy_get_ctrl_data_phy (EFI_HANDLE, INT32, struct e1000phy_softc **); +static EFI_STATUS e1000phy_add_ctrl_data (EFI_HANDLE, INT32, struct e1000phy_softc *); +static EFI_STATUS e1000phy_del_ctrl_data (EFI_HANDLE, INT32); +static EFI_STATUS e1000phy_find_drv_node (EFI_HANDLE, INT32, E1000PHY_LINKED_DRV_BUF**);
-struct e1000phy_softc *mPhySoftc; +void msk_miibus_statchg (INTN, EFI_HANDLE); +INTN msk_phy_readreg (INTN, INTN, EFI_HANDLE); +INTN msk_phy_writereg (INTN, INTN, INTN, EFI_HANDLE);
-static void mii_phy_update (INTN); -static void e1000phy_service (INTN); -static void e1000phy_status (struct mii_softc *); -static void e1000phy_reset (struct mii_softc *); -static void e1000phy_mii_phy_auto (void); +static void mii_phy_update (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_service (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_status (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_reset (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_mii_phy_auto (EFI_HANDLE, struct e1000phy_softc *);
static const struct mii_phydesc e1000phys[] = { MII_PHY_DESC (MARVELL, E1000), @@ -113,12 +117,15 @@ static const struct mii_phydesc e1000phys[] = { EFI_STATUS e1000_probe_and_attach ( struct mii_data *mii,
- const struct msk_mii_data *mmd
- )
- const struct msk_mii_data *mmd,
- EFI_HANDLE mController,
- INT32 mPort
Please don't use the m prefix for struct fields or function arguments. It is intended for variables with module scope
I should not be a problem to correct new variables. The mPhySoftc and mSoftc originally were global pointers but now passed as function parameters. Changing them will require a lot of renaming inside of many many functions. I tried to keep the changes to minimum but renaming these variables will make this patch pretty big.
The rename should be put in a separate patch to make it easy to review. That will keep down the size of the main patch.
Alan.
On 10/17/2016 05:45 PM, Daniil Egranov wrote:
The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
I tested this, and it does work on my hardware here.
I guess my biggest criticism of this patch is, why change all the function prototypes to take mSoftc, mController, and mPciIo parameters? In the FreeBSD[0] driver, the msk_softc is simply held by the msk_if_softc (which is the main object for each network controller (interface)). The PCI I/O could be held there too. Each function that needs a msk_softc can simply get it from the msk_if_softc when it needs it.
The FreeBSD driver, for the most part, passes around msk_if_softc pointers, which makes sense, since from those pointers you can get to everything else.
Is there a reason that would not work here? It seems like a much cleaner interface an fewer variables to keep track of and it wouldn't have to change function interfaces to have redundant parameters.
For example, have a look at FreeBSD's msk_phy_readreg() at [1]. It takes a msk_if_softc pointer and gets the msk_softc from it when it needs it. Your version of msk_phy_readreg() takes an mController parameter and then does a lookup of the msk_softc from a list[2] (every time you want to read a register!). The calling functions _have_ the msk_if_softc already. Just make msk_phy_readreg() take a msk_if_softc pointer (like the BSD driver does), and there would be no lookup required.
Alan.
[0] https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_mskreg.h https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c [1] https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c#L410 [2] msk_get_ctrl_data_msks() which calls msk_find_drv_node()
Drivers/Net/MarvellYukonDxe/DriverBinding.c | 6 +- Drivers/Net/MarvellYukonDxe/Snp.c | 46 +-- Drivers/Net/MarvellYukonDxe/e1000phy.c | 330 +++++++++++---- Drivers/Net/MarvellYukonDxe/e1000phyreg.h | 23 ++ Drivers/Net/MarvellYukonDxe/if_msk.c | 615 +++++++++++++++++++++------- Drivers/Net/MarvellYukonDxe/if_msk.h | 18 +- Drivers/Net/MarvellYukonDxe/if_mskreg.h | 17 + Drivers/Net/MarvellYukonDxe/miivar.h | 15 +- 8 files changed, 786 insertions(+), 284 deletions(-)
diff --git a/Drivers/Net/MarvellYukonDxe/DriverBinding.c b/Drivers/Net/MarvellYukonDxe/DriverBinding.c index 95068fa..fc684c0 100644 --- a/Drivers/Net/MarvellYukonDxe/DriverBinding.c +++ b/Drivers/Net/MarvellYukonDxe/DriverBinding.c @@ -192,14 +192,14 @@ MarvellYukonDriverStart ( // // Initialize Yukon card so we can get the MAC address //
- Status = mskc_attach (YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
- Status = mskc_attach (Controller, YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { gBS->FreePool (YukonDriver); return Status; }
- mskc_detach();
- mskc_detach (Controller);
// // Assign fields for device path @@ -487,6 +487,8 @@ InitializeMarvellYukonDriver ( if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: InitializeMarvellYukonDriver(): Driver binding failed\n"));
- } else {
- mskc_init_driver_list (); }
return Status; diff --git a/Drivers/Net/MarvellYukonDxe/Snp.c b/Drivers/Net/MarvellYukonDxe/Snp.c index 3d84f84..96cec5f 100644 --- a/Drivers/Net/MarvellYukonDxe/Snp.c +++ b/Drivers/Net/MarvellYukonDxe/Snp.c @@ -121,21 +121,21 @@ SnpGetStatus ( ) { EFI_STATUS Status;
- YUKON_DRIVER *Snp;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This);
- if (Snp == NULL) {
- YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
- if (YukonDriver == NULL) { return EFI_INVALID_PARAMETER; }
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) {
- switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -148,7 +148,7 @@ SnpGetStatus ( goto ON_EXIT; }
- mskc_getstatus (InterruptStatus, TxBuf);
- mskc_getstatus (YukonDriver->Controller, InterruptStatus, TxBuf); Status = EFI_SUCCESS;
ON_EXIT: @@ -199,7 +199,7 @@ SnpInitialize ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpInitialize()\n")); @@ -230,7 +230,7 @@ SnpInitialize ( gBS->SetMem (YukonDriver->SnpMode.MCastFilter, sizeof YukonDriver->SnpMode.MCastFilter, 0); gBS->CopyMem (&YukonDriver->SnpMode.CurrentAddress, &YukonDriver->SnpMode.PermanentAddress, sizeof (EFI_MAC_ADDRESS));
- Status = mskc_init ();
- Status = mskc_init (YukonDriver->Controller);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL; @@ -509,18 +509,18 @@ SnpReceive ( ) { EFI_STATUS Status;
- YUKON_DRIVER *Snp;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
if (This == NULL) { return EFI_INVALID_PARAMETER; }
- Snp = YUKON_DEV_FROM_THIS_SNP (This);
- YukonDriver = YUKON_DEV_FROM_THIS_SNP (This);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Snp->SnpMode.State) {
- switch (YukonDriver->SnpMode.State) { case EfiSimpleNetworkInitialized: break;
@@ -538,7 +538,7 @@ SnpReceive ( goto ON_EXIT; }
- Status = mskc_receive (BufferSize, Buffer);
- Status = mskc_receive (YukonDriver->Controller, BufferSize, Buffer); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_READY) { goto ON_EXIT_NO_DEBUG;
@@ -678,7 +678,7 @@ SnpReceiveFilters ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; UINT32 newReceiveFilter;
@@ -743,7 +743,7 @@ SnpReceiveFilters ( } YukonDriver->SnpMode.ReceiveFilterSetting = newReceiveFilter;
- mskc_rxfilter (YukonDriver->SnpMode.ReceiveFilterSetting, MCastFilterCnt, MCastFilter);
- mskc_rxfilter (YukonDriver->Controller, YukonDriver->SnpMode.ReceiveFilterSetting, MCastFilterCnt, MCastFilter);
Status = EFI_SUCCESS; goto ON_EXIT; @@ -788,7 +788,7 @@ SnpReset ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpReset()\n")); @@ -858,7 +858,7 @@ SnpShutdown ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpShutdown()\n")); @@ -890,7 +890,7 @@ SnpShutdown ( goto ON_ERROR_RESTORE_TPL; }
- mskc_shutdown ();
- mskc_shutdown (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStarted; Status = EFI_SUCCESS;
@@ -938,7 +938,7 @@ SnpStart ( IN EFI_SIMPLE_NETWORK_PROTOCOL *This ) {
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -966,7 +966,7 @@ SnpStart ( goto ON_ERROR_RESTORE_TPL; }
- Status = mskc_attach (YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
- Status = mskc_attach (YukonDriver->Controller, YukonDriver->PciIo, &YukonDriver->SnpMode.PermanentAddress);
if (EFI_ERROR (Status)) { goto ON_ERROR_RESTORE_TPL; @@ -1025,7 +1025,7 @@ SnpStationAddress ( IN EFI_MAC_ADDRESS *New OPTIONAL ) {
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl; EFI_STATUS Status;
@@ -1122,7 +1122,7 @@ SnpStatistics ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStatistics()\n")); @@ -1242,7 +1242,7 @@ SnpStop ( ) { EFI_STATUS Status;
- YUKON_DRIVER *YukonDriver;
- YUKON_DRIVER *YukonDriver; EFI_TPL OldTpl;
DEBUG ((EFI_D_NET, "Marvell Yukon: SnpStop()\n")); @@ -1269,7 +1269,7 @@ SnpStop ( goto ON_ERROR_RESTORE_TPL; }
- mskc_detach ();
- mskc_detach (YukonDriver->Controller); YukonDriver->SnpMode.State = EfiSimpleNetworkStopped; gBS->SetMem (&YukonDriver->SnpMode.CurrentAddress, sizeof (EFI_MAC_ADDRESS), 0); Status = EFI_SUCCESS;
@@ -1407,7 +1407,7 @@ SnpTransmit ( gBS->CopyMem (&Frame->EtherType, &ProtocolNet, sizeof (UINT16)); }
- Status = mskc_transmit (BufferSize, Buffer);
- Status = mskc_transmit (YukonDriver->Controller, BufferSize, Buffer);
ON_EXIT: gBS->RestoreTPL (OldTpl); diff --git a/Drivers/Net/MarvellYukonDxe/e1000phy.c b/Drivers/Net/MarvellYukonDxe/e1000phy.c index dee4cdf..ca84138 100644 --- a/Drivers/Net/MarvellYukonDxe/e1000phy.c +++ b/Drivers/Net/MarvellYukonDxe/e1000phy.c @@ -57,6 +57,7 @@ #include <Library/MemoryAllocationLib.h> #include <Library/DebugLib.h> #include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseLib.h> #include "if_media.h" @@ -64,27 +65,30 @@ #include "e1000phyreg.h" +static LIST_ENTRY e1000phy_drv_data_head;
+static void e1000phy_attach (const struct mii_attach_args *ma, EFI_HANDLE, struct e1000phy_softc *); static EFI_STATUS e1000phy_probe (const struct mii_attach_args *ma); -static void e1000phy_attach (const struct mii_attach_args *ma); static const struct mii_phydesc * mii_phy_match (const struct mii_attach_args *ma, const struct mii_phydesc *mpd); static const struct mii_phydesc * mii_phy_match_gen (const struct mii_attach_args *ma, const struct mii_phydesc *mpd, UINTN endlen); static EFI_STATUS mii_phy_dev_probe (const struct mii_attach_args *ma, const struct mii_phydesc *mpd); -struct e1000phy_softc {
- struct mii_softc mii_sc;
- INTN mii_model;
- const struct msk_mii_data *mmd;
-}; +static EFI_STATUS e1000phy_get_ctrl_data_phy (EFI_HANDLE, INT32, struct e1000phy_softc **); +static EFI_STATUS e1000phy_add_ctrl_data (EFI_HANDLE, INT32, struct e1000phy_softc *); +static EFI_STATUS e1000phy_del_ctrl_data (EFI_HANDLE, INT32); +static EFI_STATUS e1000phy_find_drv_node (EFI_HANDLE, INT32, E1000PHY_LINKED_DRV_BUF**); -struct e1000phy_softc *mPhySoftc; +void msk_miibus_statchg (INTN, EFI_HANDLE); +INTN msk_phy_readreg (INTN, INTN, EFI_HANDLE); +INTN msk_phy_writereg (INTN, INTN, INTN, EFI_HANDLE); -static void mii_phy_update (INTN); -static void e1000phy_service (INTN); -static void e1000phy_status (struct mii_softc *); -static void e1000phy_reset (struct mii_softc *); -static void e1000phy_mii_phy_auto (void); +static void mii_phy_update (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_service (INTN, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_status (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_reset (struct mii_softc *, EFI_HANDLE, struct e1000phy_softc *); +static void e1000phy_mii_phy_auto (EFI_HANDLE, struct e1000phy_softc *); static const struct mii_phydesc e1000phys[] = { MII_PHY_DESC (MARVELL, E1000), @@ -113,12 +117,15 @@ static const struct mii_phydesc e1000phys[] = { EFI_STATUS e1000_probe_and_attach ( struct mii_data *mii,
- const struct msk_mii_data *mmd
- )
- const struct msk_mii_data *mmd,
- EFI_HANDLE mController,
- INT32 mPort
- ) { struct mii_attach_args ma; INTN bmsr; EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct e1000phy_softc), @@ -129,13 +136,12 @@ e1000_probe_and_attach ( gBS->SetMem (mPhySoftc, sizeof (struct e1000phy_softc), 0); mPhySoftc->mmd = mmd;
- /*
*/
- Check to see if there is a PHY at this address. Note,
- many braindead PHYs report 0/0 in their ID registers,
- so we test for media in the BMSR.
- bmsr = PHY_READ (mPhySoftc, E1000_SR);
- bmsr = PHY_READ (mPhySoftc, E1000_SR, mController); if (bmsr == 0 || bmsr == 0xffff || (bmsr & (E1000_SR_EXTENDED_STATUS|E1000_SR_MEDIAMASK)) == 0) { /* Assume no PHY at this address. */ gBS->FreePool (mPhySoftc);
@@ -145,8 +151,8 @@ e1000_probe_and_attach ( /* * Extract the IDs. */
- ma.mii_id1 = PHY_READ (mPhySoftc, E1000_ID1);
- ma.mii_id2 = PHY_READ (mPhySoftc, E1000_ID2);
- ma.mii_id1 = PHY_READ (mPhySoftc, E1000_ID1, mController);
- ma.mii_id2 = PHY_READ (mPhySoftc, E1000_ID2, mController);
ma.mii_data = mii; @@ -156,11 +162,36 @@ e1000_probe_and_attach ( return Status; }
- e1000phy_attach (&ma);
- e1000phy_attach (&ma, mController, mPhySoftc);
- Status = e1000phy_add_ctrl_data (mController, mPort, mPhySoftc);
- if (EFI_ERROR (Status)) {
- gBS->FreePool (mPhySoftc);
- return Status;
- }
- return EFI_SUCCESS; }
EFI_STATUS +e1000phy_dettach (
- EFI_HANDLE mController,
- INT32 mPort
- )
+{
- EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
- Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc);
- if (!EFI_ERROR (Status)) {
- e1000phy_del_ctrl_data(mController, mPort);
- gBS->FreePool(mPhySoftc);
- }
- return Status;
+}
+EFI_STATUS e1000phy_probe ( const struct mii_attach_args *ma ) @@ -170,7 +201,9 @@ e1000phy_probe ( static void e1000phy_attach (
- const struct mii_attach_args *ma
- const struct mii_attach_args *ma,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { struct mii_softc *sc;
@@ -188,7 +221,7 @@ e1000phy_attach ( switch (mPhySoftc->mii_model) { case MII_MODEL_MARVELL_E1011: case MII_MODEL_MARVELL_E1112:
if (PHY_READ (mPhySoftc, E1000_ESSR) & E1000_ESSR_FIBER_LINK) {
if (PHY_READ (mPhySoftc, E1000_ESSR, mController) & E1000_ESSR_FIBER_LINK) { sc->mii_flags |= MIIF_HAVEFIBER; } break;
@@ -204,46 +237,48 @@ e1000phy_attach ( * that information should be used to select default * type of PHY. */
PHY_WRITE (mPhySoftc, E1000_EADR, 0);
}PHY_WRITE (mPhySoftc, E1000_EADR, 0, mController); break;
- e1000phy_reset (sc);
- e1000phy_reset (sc, mController, mPhySoftc);
- sc->mii_capabilities = PHY_READ (mPhySoftc, E1000_SR) & 0xFFFFFFFF;
- sc->mii_capabilities = PHY_READ (mPhySoftc, E1000_SR, mController) & 0xFFFFFFFF; if (sc->mii_capabilities & E1000_SR_EXTENDED_STATUS) {
- sc->mii_extcapabilities = PHY_READ (mPhySoftc, E1000_ESR);
- sc->mii_extcapabilities = PHY_READ (mPhySoftc, E1000_ESR, mController); } }
static void e1000phy_reset (
- struct mii_softc *sc
- struct mii_softc *sc,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { UINT16 reg; UINT16 page;
- reg = PHY_READ (mPhySoftc, E1000_SCR);
- reg = PHY_READ (mPhySoftc, E1000_SCR, mController); if ((sc->mii_flags & MIIF_HAVEFIBER) != 0) { reg &= ~E1000_SCR_AUTO_X_MODE;
- PHY_WRITE (mPhySoftc, E1000_SCR, reg);
- PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); if (mPhySoftc->mii_model == MII_MODEL_MARVELL_E1112) { // Select 1000BASE-X only mode.
page = PHY_READ (mPhySoftc, E1000_EADR);
PHY_WRITE (mPhySoftc, E1000_EADR, 2);
reg = PHY_READ (mPhySoftc, E1000_SCR);
page = PHY_READ (mPhySoftc, E1000_EADR, mController);
PHY_WRITE (mPhySoftc, E1000_EADR, 2, mController);
reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg &= ~E1000_SCR_MODE_MASK; reg |= E1000_SCR_MODE_1000BX;
PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); if (mPhySoftc->mmd != NULL && mPhySoftc->mmd->pmd == 'P') { // Set SIGDET polarity low for SFP module
PHY_WRITE (mPhySoftc, E1000_EADR, 1);
reg = PHY_READ (mPhySoftc, E1000_SCR);
PHY_WRITE (mPhySoftc, E1000_EADR, 1, mController);
reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg |= E1000_SCR_FIB_SIGDET_POLARITY;
PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController); }
PHY_WRITE (mPhySoftc, E1000_EADR, page);
} else { switch (mPhySoftc->mii_model) {PHY_WRITE (mPhySoftc, E1000_EADR, page, mController); }
@@ -270,7 +305,7 @@ e1000phy_reset ( E1000_SCR_SCRAMBLER_DISABLE); reg |= E1000_SCR_LPNP; // XXX Enable class A driver for Yukon FE+ A0
PHY_WRITE (mPhySoftc, 0x1C, PHY_READ (mPhySoftc, 0x1C) | 0x0001);
PHY_WRITE (mPhySoftc, 0x1C, PHY_READ (mPhySoftc, 0x1C, mController) | 0x0001, mController); break; default: reg &= ~E1000_SCR_AUTO_X_MODE;
@@ -281,15 +316,15 @@ e1000phy_reset ( /* Auto correction for reversed cable polarity. */ reg &= ~E1000_SCR_POLARITY_REVERSAL; }
- PHY_WRITE (mPhySoftc, E1000_SCR, reg);
- PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController);
if (mPhySoftc->mii_model == MII_MODEL_MARVELL_E1116 || mPhySoftc->mii_model == MII_MODEL_MARVELL_E1149) {
PHY_WRITE (mPhySoftc, E1000_EADR, 2);
reg = PHY_READ (mPhySoftc, E1000_SCR);
PHY_WRITE (mPhySoftc, E1000_EADR, 2, mController);
reg = PHY_READ (mPhySoftc, E1000_SCR, mController); reg |= E1000_SCR_RGMII_POWER_UP;
PHY_WRITE (mPhySoftc, E1000_SCR, reg);
PHY_WRITE (mPhySoftc, E1000_EADR, 0);
PHY_WRITE (mPhySoftc, E1000_SCR, reg, mController);
}PHY_WRITE (mPhySoftc, E1000_EADR, 0, mController); }
@@ -299,42 +334,45 @@ e1000phy_reset ( case MII_MODEL_MARVELL_E1118: break; case MII_MODEL_MARVELL_E1116:
page = PHY_READ (mPhySoftc, E1000_EADR);
page = PHY_READ (mPhySoftc, E1000_EADR, mController); /* Select page 3, LED control register. */
PHY_WRITE (mPhySoftc, E1000_EADR, 3);
PHY_WRITE (mPhySoftc, E1000_EADR, 3, mController); PHY_WRITE (mPhySoftc, E1000_SCR, E1000_SCR_LED_LOS (1) | /* Link/Act */ E1000_SCR_LED_INIT (8) | /* 10Mbps */ E1000_SCR_LED_STAT1 (7) | /* 100Mbps */
E1000_SCR_LED_STAT0 (7)); /* 1000Mbps */
E1000_SCR_LED_STAT0 (7), /* 1000Mbps */
mController); /* Set blink rate. */
PHY_WRITE (mPhySoftc, E1000_IER, E1000_PULSE_DUR (E1000_PULSE_170MS) | E1000_BLINK_RATE (E1000_BLINK_84MS));
PHY_WRITE (mPhySoftc, E1000_EADR, page);
PHY_WRITE (mPhySoftc, E1000_IER, E1000_PULSE_DUR (E1000_PULSE_170MS) | E1000_BLINK_RATE (E1000_BLINK_84MS), mController);
PHY_WRITE (mPhySoftc, E1000_EADR, page, mController); break; case MII_MODEL_MARVELL_E3016: /* LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED. */
PHY_WRITE (mPhySoftc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04);
PHY_WRITE (mPhySoftc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04, mController); /* Integrated register calibration workaround. */
PHY_WRITE (mPhySoftc, 0x1D, 17);
PHY_WRITE (mPhySoftc, 0x1E, 0x3F60);
PHY_WRITE (mPhySoftc, 0x1D, 17, mController);
PHY_WRITE (mPhySoftc, 0x1E, 0x3F60, mController); break; default: /* Force TX_CLK to 25MHz clock. */
reg = PHY_READ (mPhySoftc, E1000_ESCR);
reg = PHY_READ (mPhySoftc, E1000_ESCR, mController); reg |= E1000_ESCR_TX_CLK_25;
PHY_WRITE (mPhySoftc, E1000_ESCR, reg);
}PHY_WRITE (mPhySoftc, E1000_ESCR, reg, mController); break;
/* Reset the PHY so all changes take effect. */
- reg = PHY_READ (mPhySoftc, E1000_CR);
- reg = PHY_READ (mPhySoftc, E1000_CR, mController); reg |= E1000_CR_RESET;
- PHY_WRITE (mPhySoftc, E1000_CR, reg);
- PHY_WRITE (mPhySoftc, E1000_CR, reg, mController); }
static void mii_phy_update (
- INTN cmd
- INTN cmd,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { struct mii_softc *sc = &mPhySoftc->mii_sc;
@@ -344,7 +382,7 @@ mii_phy_update ( sc->mii_media_status != mii->mii_media_status || cmd == MII_MEDIACHG) {
- msk_miibus_statchg (mPhySoftc->mmd->port);
- msk_miibus_statchg (mPhySoftc->mmd->port, mController); sc->mii_media_active = mii->mii_media_active; sc->mii_media_status = mii->mii_media_status; }
@@ -352,27 +390,43 @@ mii_phy_update ( void e1000phy_tick (
- VOID
- EFI_HANDLE mController,
- INT32 mPort ) {
- e1000phy_service (MII_TICK);
- EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
- Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc);
- if (!EFI_ERROR (Status)) {
- e1000phy_service (MII_TICK, mController, mPhySoftc);
- } }
void e1000phy_mediachg (
- VOID
- EFI_HANDLE mController,
- INT32 mPort ) {
- struct mii_data *mii = mPhySoftc->mii_sc.mii_pdata;
- mii->mii_media_status = 0;
- mii->mii_media_active = IFM_NONE;
- e1000phy_service (MII_MEDIACHG);
- EFI_STATUS Status;
- struct e1000phy_softc *mPhySoftc;
- Status = e1000phy_get_ctrl_data_phy (mController, mPort, &mPhySoftc);
- if (!EFI_ERROR (Status)) {
- struct mii_data *mii = mPhySoftc->mii_sc.mii_pdata;
- mii->mii_media_status = 0;
- mii->mii_media_active = IFM_NONE;
- e1000phy_service (MII_MEDIACHG, mController, mPhySoftc);
- } }
static void e1000phy_service (
- INTN cmd
- )
- INTN cmd,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc
- ) { struct mii_softc *sc = &mPhySoftc->mii_sc; INTN reg;
@@ -385,7 +439,7 @@ e1000phy_service ( // // Always try to auto-negotiate //
e1000phy_mii_phy_auto ();
e1000phy_mii_phy_auto (mController, mPhySoftc); break;
case MII_TICK: @@ -393,7 +447,7 @@ e1000phy_service ( * check for link. * Read the status register twice; Link Status is latch-low. */
reg = PHY_READ (mPhySoftc, E1000_SR) | PHY_READ (mPhySoftc, E1000_SR);
reg = PHY_READ (mPhySoftc, E1000_SR, mController) | PHY_READ (mPhySoftc, E1000_SR, mController); if (reg & E1000_SR_LINK_STATUS) { sc->mii_ticks = 0; break;
@@ -411,21 +465,23 @@ e1000phy_service ( // Restart the auto-negotiation // sc->mii_ticks = 0;
e1000phy_reset (sc);
e1000phy_mii_phy_auto ();
e1000phy_reset (sc, mController, mPhySoftc);
}e1000phy_mii_phy_auto (mController, mPhySoftc); break;
/* Update the media status. */
- e1000phy_status (sc);
- e1000phy_status (sc, mController, mPhySoftc);
/* Callback if something changed. */
- mii_phy_update (cmd);
- mii_phy_update (cmd, mController, mPhySoftc); }
static void e1000phy_status (
- struct mii_softc *sc
- struct mii_softc *sc,
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { struct mii_data *mii = sc->mii_pdata;
@@ -439,9 +495,9 @@ e1000phy_status ( mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER;
- bmsr = PHY_READ (mPhySoftc, E1000_SR) | PHY_READ (mPhySoftc, E1000_SR);
- bmcr = PHY_READ (mPhySoftc, E1000_CR);
- ssr = PHY_READ (mPhySoftc, E1000_SSR);
- bmsr = PHY_READ (mPhySoftc, E1000_SR, mController) | PHY_READ (mPhySoftc, E1000_SR, mController);
- bmcr = PHY_READ (mPhySoftc, E1000_CR, mController);
- ssr = PHY_READ (mPhySoftc, E1000_SSR, mController);
if (bmsr & E1000_SR_LINK_STATUS) { DEBUG ((EFI_D_NET, "Marvell Yukon: e1000phy_status, link up\n")); @@ -489,8 +545,8 @@ e1000phy_status ( } if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
- ar = PHY_READ (mPhySoftc, E1000_AR);
- lpar = PHY_READ (mPhySoftc, E1000_LPAR);
- ar = PHY_READ (mPhySoftc, E1000_AR, mController);
- lpar = PHY_READ (mPhySoftc, E1000_LPAR, mController); /* FLAG0==rx-flow-control FLAG1==tx-flow-control */ if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) { mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1;
@@ -506,8 +562,8 @@ e1000phy_status ( /* FLAG2 : local PHY resolved to MASTER */ if ((IFM_SUBTYPE (mii->mii_media_active) == IFM_1000_T) || (IFM_SUBTYPE (mii->mii_media_active) == IFM_1000_SX)) {
- PHY_READ (mPhySoftc, E1000_1GSR);
- gsr = PHY_READ (mPhySoftc, E1000_1GSR);
- PHY_READ (mPhySoftc, E1000_1GSR, mController);
- gsr = PHY_READ (mPhySoftc, E1000_1GSR, mController); if ((gsr & E1000_1GSR_MS_CONFIG_RES) != 0) { mii->mii_media_active |= IFM_FLAG2; }
@@ -516,7 +572,8 @@ e1000phy_status ( static void e1000phy_mii_phy_auto (
- VOID
- EFI_HANDLE mController,
- struct e1000phy_softc *mPhySoftc ) { struct mii_softc *sc;
@@ -525,20 +582,20 @@ e1000phy_mii_phy_auto ( DEBUG ((EFI_D_NET, "Marvell Yukon: e1000phy_mii_phy_auto negotiation started\n")); sc = &mPhySoftc->mii_sc; if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
- reg = PHY_READ (mPhySoftc, E1000_AR);
- reg = PHY_READ (mPhySoftc, E1000_AR, mController); reg |= E1000_AR_10T | E1000_AR_10T_FD | E1000_AR_100TX | E1000_AR_100TX_FD | E1000_AR_PAUSE | E1000_AR_ASM_DIR;
- PHY_WRITE (mPhySoftc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD);
- PHY_WRITE (mPhySoftc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD, mController); } else {
- PHY_WRITE (mPhySoftc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE);
- PHY_WRITE (mPhySoftc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE, mController); }
if ((sc->mii_extcapabilities & (E1000_ESR_1000T_FD | E1000_ESR_1000T)) != 0) {
- PHY_WRITE (mPhySoftc, E1000_1GCR, E1000_1GCR_1000T_FD | E1000_1GCR_1000T);
- PHY_WRITE (mPhySoftc, E1000_1GCR, E1000_1GCR_1000T_FD | E1000_1GCR_1000T, mController); }
- PHY_WRITE (mPhySoftc, E1000_CR, E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG);
- PHY_WRITE (mPhySoftc, E1000_CR, E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG, mController); }
// @@ -589,3 +646,106 @@ mii_phy_dev_probe ( DEBUG ((EFI_D_NET, "Marvell Yukon: PHY not found (OUI=0x%x, MODEL=0x%x)\n", MII_OUI (ma->mii_id1, ma->mii_id2), MII_MODEL (ma->mii_id2))); return EFI_NOT_FOUND; }
+void +e1000phy_init_driver_list (void) +{
- InitializeListHead (&e1000phy_drv_data_head);
+}
+static +EFI_STATUS +e1000phy_get_ctrl_data_phy (
- EFI_HANDLE mController,
- INT32 mPort,
- struct e1000phy_softc **mPhySoftc
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- *mPhySoftc = mDrvNode->mPhySoftc;
- }
- return Status;
+}
+static +EFI_STATUS +e1000phy_add_ctrl_data (
- EFI_HANDLE mController,
- INT32 mPort,
- struct e1000phy_softc *mPhySoftc
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode);
- if (EFI_ERROR(Status)) {
- Status = gBS->AllocatePool (EfiBootServicesData,
sizeof (E1000PHY_LINKED_DRV_BUF),
(VOID**) &mDrvNode);
- if (!EFI_ERROR (Status)) {
mDrvNode->Signature = E1000PHY_DRV_SIGNATURE;
mDrvNode->mController = mController;
mDrvNode->mPort = mPort;
mDrvNode->mPhySoftc = mPhySoftc;
InsertTailList (&e1000phy_drv_data_head, &mDrvNode->Link);
- }
- } else {
- Status = EFI_ALREADY_STARTED;
- }
- return Status;
+}
+static +EFI_STATUS +e1000phy_del_ctrl_data (
- EFI_HANDLE mController,
- INT32 mPort
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = e1000phy_find_drv_node (mController, mPort, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- RemoveEntryList (&mDrvNode->Link);
- gBS->FreePool (mDrvNode);
- }
- return Status;
+}
+static +EFI_STATUS +e1000phy_find_drv_node (
- EFI_HANDLE mController,
- INT32 mPort,
- E1000PHY_LINKED_DRV_BUF **mDrvNode
- )
+{
- E1000PHY_LINKED_DRV_BUF *mDrvBuffNode;
- EFI_STATUS Status;
- LIST_ENTRY *Node;
- Status = EFI_NOT_FOUND;
- Node = GetFirstNode (&e1000phy_drv_data_head);
- while (!IsNull (&e1000phy_drv_data_head, Node)) {
- mDrvBuffNode = E1000PHY_DRV_INFO_FROM_THIS (Node);
- if (mDrvBuffNode->mController == mController &&
mDrvBuffNode->mPort == mPort) {
*mDrvNode = mDrvBuffNode;
Status = EFI_SUCCESS;
break;
- }
- Node = GetNextNode (&e1000phy_drv_data_head, Node);
- }
- return Status;
+} diff --git a/Drivers/Net/MarvellYukonDxe/e1000phyreg.h b/Drivers/Net/MarvellYukonDxe/e1000phyreg.h index a87b1f1..d0bfd25 100644 --- a/Drivers/Net/MarvellYukonDxe/e1000phyreg.h +++ b/Drivers/Net/MarvellYukonDxe/e1000phyreg.h @@ -396,3 +396,26 @@ #define E1000_ESSR_GMII_FIBER 0x0007 #define E1000_ESSR_TBI_COPPER 0x000d #define E1000_ESSR_TBI_FIBER 0x0005
+struct e1000phy_softc {
- struct mii_softc mii_sc;
- INTN mii_model;
- const struct msk_mii_data *mmd;
+};
+typedef struct {
- UINT32 Signature;
- LIST_ENTRY Link;
- INT32 mPort;
- EFI_HANDLE mController;
- struct e1000phy_softc *mPhySoftc;
+} E1000PHY_LINKED_DRV_BUF;
+#define E1000PHY_DRV_SIGNATURE SIGNATURE_32 ('e', 'p', 'h', 'y')
+#define E1000PHY_DRV_INFO_FROM_THIS(a) \
- CR (a, \
E1000PHY_LINKED_DRV_BUF, \
Link, \
E1000PHY_DRV_SIGNATURE \
);
diff --git a/Drivers/Net/MarvellYukonDxe/if_msk.c b/Drivers/Net/MarvellYukonDxe/if_msk.c index d23f893..3f41d45 100644 --- a/Drivers/Net/MarvellYukonDxe/if_msk.c +++ b/Drivers/Net/MarvellYukonDxe/if_msk.c @@ -121,11 +121,7 @@ #include "if_mskreg.h" #include "if_msk.h" -// -// Global Variables -// -static EFI_PCI_IO_PROTOCOL *mPciIo; -static struct msk_softc *mSoftc; +static LIST_ENTRY msk_drv_data_head; #define MSK_CSUM_FEATURES (CSUM_TCP | CSUM_UDP) @@ -189,49 +185,67 @@ static const CHAR8 *model_name[] = { // // Forward declarations // -static VOID mskc_setup_rambuffer (VOID); -static VOID mskc_reset (VOID); +static VOID mskc_setup_rambuffer (struct msk_softc *); +static VOID mskc_reset (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); -static EFI_STATUS msk_attach (INT32); -static VOID msk_detach (INT32); +static EFI_STATUS msk_attach (INT32, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_detach (INT32, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); static VOID mskc_tick (IN EFI_EVENT, IN VOID*); -static VOID msk_intr (VOID); -static VOID msk_intr_phy (struct msk_if_softc *); -static VOID msk_intr_gmac (struct msk_if_softc *); -static __inline VOID msk_rxput (struct msk_if_softc *); -static INTN msk_handle_events (VOID); -static VOID msk_handle_hwerr (struct msk_if_softc *, UINT32); -static VOID msk_intr_hwerr (VOID); -static VOID msk_rxeof (struct msk_if_softc *, UINT32, UINT32, INTN); -static VOID msk_txeof (struct msk_if_softc *, INTN); -static EFI_STATUS msk_encap (struct msk_if_softc *, MSK_SYSTEM_BUF *); -static VOID msk_start (INT32); -static VOID msk_set_prefetch (INTN, EFI_PHYSICAL_ADDRESS, UINT32); -static VOID msk_set_rambuffer (struct msk_if_softc *); -static VOID msk_set_tx_stfwd (struct msk_if_softc *); -static EFI_STATUS msk_init (struct msk_if_softc *); -static VOID msk_stop (struct msk_if_softc *); +static VOID msk_intr (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_intr_phy (struct msk_if_softc *, EFI_HANDLE); +static VOID msk_intr_gmac (struct msk_if_softc *, struct msk_softc *); +static __inline VOID msk_rxput (struct msk_if_softc *, struct msk_softc *); +static INTN msk_handle_events (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_handle_hwerr (struct msk_if_softc *, UINT32, struct msk_softc *); +static VOID msk_intr_hwerr (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_rxeof (struct msk_if_softc *, UINT32, UINT32, INTN, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_txeof (struct msk_if_softc *, INTN, EFI_PCI_IO_PROTOCOL *); +static EFI_STATUS msk_encap (struct msk_if_softc *, MSK_SYSTEM_BUF *, EFI_PCI_IO_PROTOCOL *); +static VOID msk_start (INT32, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_set_prefetch (INTN, EFI_PHYSICAL_ADDRESS, UINT32, struct msk_softc *); +static VOID msk_set_rambuffer (struct msk_if_softc *, struct msk_softc *); +static VOID msk_set_tx_stfwd (struct msk_if_softc *, struct msk_softc *); +static EFI_STATUS msk_init (struct msk_if_softc *, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_stop (struct msk_if_softc *, EFI_HANDLE, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); static VOID msk_phy_power (struct msk_softc *, INTN); -static EFI_STATUS msk_status_dma_alloc (VOID); -static VOID msk_status_dma_free (VOID); -static EFI_STATUS msk_txrx_dma_alloc (struct msk_if_softc *); -static VOID msk_txrx_dma_free (struct msk_if_softc *); -static EFI_STATUS msk_init_rx_ring (struct msk_if_softc *); +INTN msk_phy_readreg (INTN, INTN, EFI_HANDLE); +INTN msk_phy_writereg (INTN, INTN, INTN, EFI_HANDLE); +static EFI_STATUS msk_status_dma_alloc (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static VOID msk_status_dma_free (EFI_PCI_IO_PROTOCOL *, struct msk_softc *); +static EFI_STATUS msk_txrx_dma_alloc (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *); +static VOID msk_txrx_dma_free (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *); +static EFI_STATUS msk_init_rx_ring (struct msk_if_softc *, EFI_PCI_IO_PROTOCOL *, struct msk_softc *); static VOID msk_init_tx_ring (struct msk_if_softc *); static __inline VOID msk_discard_rxbuf (struct msk_if_softc *, INTN); -static EFI_STATUS msk_newbuf (struct msk_if_softc *, INTN); +static EFI_STATUS msk_newbuf (struct msk_if_softc *, INTN, EFI_PCI_IO_PROTOCOL *); static VOID msk_rxfilter ( struct msk_if_softc *sc_if, UINT32 FilterFlags, UINTN MCastFilterCnt,
- EFI_MAC_ADDRESS *MCastFilter
- EFI_MAC_ADDRESS *MCastFilter,
- EFI_HANDLE mController );
-static VOID msk_setvlan (struct msk_if_softc *);
-static VOID msk_stats_clear (struct msk_if_softc *); -static VOID msk_stats_update (struct msk_if_softc *); +static VOID msk_setvlan (struct msk_if_softc *, struct msk_softc *);
+static VOID msk_stats_clear (struct msk_if_softc *, struct msk_softc *); +static VOID msk_stats_update (struct msk_if_softc *, struct msk_softc *); +static VOID clear_pci_errors (EFI_PCI_IO_PROTOCOL *, struct msk_softc *);
+EFI_STATUS e1000_probe_and_attach (struct mii_data *, const struct msk_mii_data *, EFI_HANDLE, INT32); +void e1000phy_tick (EFI_HANDLE, INT32); +void e1000phy_mediachg (EFI_HANDLE, INT32); +void e1000phy_init_driver_list (void); +EFI_STATUS e1000phy_dettach (EFI_HANDLE, INT32);
+static EFI_STATUS msk_get_ctrl_data (EFI_HANDLE, EFI_PCI_IO_PROTOCOL **,
struct msk_softc **);
+static EFI_STATUS msk_get_ctrl_data_msks (EFI_HANDLE, struct msk_softc **); +static EFI_STATUS msk_add_ctrl_data (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *,
struct msk_softc *);
+static EFI_STATUS msk_del_ctrl_data (EFI_HANDLE); +static EFI_STATUS msk_find_drv_node (EFI_HANDLE, MSK_LINKED_DRV_BUF **); // // Functions @@ -239,12 +253,20 @@ static VOID msk_stats_update (struct msk_if_softc *); INTN msk_phy_readreg (
- INTN port,
- INTN reg
- INTN port,
- INTN reg,
- EFI_HANDLE mController ) {
- INTN i;
- INTN val;
- INTN i;
- INTN val;
- EFI_STATUS Status;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data_msks (mController, &mSoftc);
- if (EFI_ERROR (Status)) {
- return 0;
- }
GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD); @@ -267,12 +289,20 @@ msk_phy_readreg ( INTN msk_phy_writereg (
- INTN port,
- INTN reg,
- INTN val
- INTN port,
- INTN reg,
- INTN val,
- EFI_HANDLE mController ) { INTN i;
- EFI_STATUS Status;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data_msks (mController, &mSoftc);
- if (EFI_ERROR (Status)) {
- return 0;
- }
GMAC_WRITE_2 (mSoftc, port, GM_SMI_DATA, val); GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg)); @@ -291,13 +321,23 @@ msk_phy_writereg ( VOID msk_miibus_statchg (
- INTN port
- INTN port,
- EFI_HANDLE mController ) {
- struct msk_if_softc *sc_if = mSoftc->msk_if[port];
- struct mii_data *mii = &sc_if->mii_d;
- struct msk_if_softc *sc_if;
- struct mii_data *mii; UINT32 gmac;
- EFI_STATUS Status;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data_msks (mController, &mSoftc);
- if (EFI_ERROR (Status)) {
- return;
- }
- sc_if = mSoftc->msk_if[port];
- mii = &sc_if->mii_d; sc_if->msk_flags &= ~MSK_FLAG_LINK;
if ((mii->mii_media_status & (IFM_AVALID | IFM_ACTIVE)) == (IFM_AVALID | IFM_ACTIVE)) { @@ -370,14 +410,14 @@ msk_miibus_statchg ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, GMAC_CTRL), gmac); // Enable PHY interrupt for FIFO underrun/overflow
- msk_phy_writereg (port, PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR);
- msk_phy_writereg (port, PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR, mController); } else { // // Link state changed to down. // Disable PHY interrupts. // DEBUG ((EFI_D_NET, "Marvell Yukon: msk_miibus_statchg, link down\n"));
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0);
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0, mController); // Disable Rx/Tx MAC gmac = GMAC_READ_2 (mSoftc, port, GM_GP_CTRL); if ((GM_GPCR_RX_ENA | GM_GPCR_TX_ENA) != 0) {
@@ -418,12 +458,21 @@ ether_crc32_be ( VOID mskc_rxfilter (
- EFI_HANDLE mController, UINT32 FilterFlags, UINTN MCastFilterCnt, EFI_MAC_ADDRESS *MCastFilter ) {
- msk_rxfilter (mSoftc->msk_if[MSK_PORT_A], FilterFlags, MCastFilterCnt, MCastFilter);
- EFI_STATUS Status;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data_msks (mController, &mSoftc);
- if (EFI_ERROR (Status)) {
- return;
- }
- msk_rxfilter (mSoftc->msk_if[MSK_PORT_A], FilterFlags, MCastFilterCnt, MCastFilter, mController); }
static VOID @@ -431,13 +480,21 @@ msk_rxfilter ( struct msk_if_softc *sc_if, UINT32 FilterFlags, UINTN MCastFilterCnt,
- EFI_MAC_ADDRESS *MCastFilter
- EFI_MAC_ADDRESS *MCastFilter,
- EFI_HANDLE mController ) {
- UINT32 mchash[2];
- UINT32 crc;
- UINT16 mode;
- INTN port = sc_if->msk_md.port;
- UINT32 mchash[2];
- UINT32 crc;
- UINT16 mode;
- INTN port = sc_if->msk_md.port;
- EFI_STATUS Status;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data_msks (mController, &mSoftc);
- if (EFI_ERROR (Status)) {
- return;
- }
gBS->SetMem (mchash, sizeof (mchash), 0); mode = GMAC_READ_2 (mSoftc, port, GM_RX_CTRL); @@ -472,7 +529,8 @@ msk_rxfilter ( static VOID msk_setvlan (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { //
@@ -485,7 +543,9 @@ msk_setvlan ( static EFI_STATUS msk_init_rx_ring (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_ring_data *rd;
@@ -511,7 +571,7 @@ msk_init_rx_ring ( prod = 0; for (i = 0; i < nbuf; i++) {
Status = msk_newbuf (sc_if, prod);
Status = msk_newbuf (sc_if, prod, mPciIo); if (EFI_ERROR (Status)) { return Status; }
@@ -580,7 +640,8 @@ static EFI_STATUS msk_newbuf ( IN struct msk_if_softc *sc_if,
- IN INTN idx
- IN INTN idx,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_rx_desc *rx_le;
@@ -663,7 +724,7 @@ mskc_probe ( static VOID mskc_setup_rambuffer (
- VOID
- struct msk_softc *mSoftc ) { INTN next;
@@ -811,7 +872,8 @@ msk_phy_power ( static VOID clear_pci_errors (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -847,7 +909,8 @@ clear_pci_errors ( static VOID mskc_reset (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -877,7 +940,7 @@ mskc_reset ( CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_SET); CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_CLR);
- clear_pci_errors ();
- clear_pci_errors (mPciIo, mSoftc); switch (mSoftc->msk_bustype) { case MSK_PEX_BUS: // Clear all PEX errors
@@ -1055,7 +1118,10 @@ mskc_reset ( static EFI_STATUS msk_attach (
- INT32 Port
- INT32 Port,
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if;
@@ -1077,7 +1143,7 @@ msk_attach ( sc_if->msk_rxq = Q_R2; }
- Status = msk_txrx_dma_alloc (sc_if);
- Status = msk_txrx_dma_alloc (sc_if, mPciIo); if (EFI_ERROR (Status)) { return Status; }
@@ -1099,10 +1165,10 @@ msk_attach ( sc_if->MacAddress.Addr[0], sc_if->MacAddress.Addr[1], sc_if->MacAddress.Addr[2], sc_if->MacAddress.Addr[3], sc_if->MacAddress.Addr[4], sc_if->MacAddress.Addr[5]));
- Status = e1000_probe_and_attach (&sc_if->mii_d, &sc_if->msk_md);
- Status = e1000_probe_and_attach (&sc_if->mii_d, &sc_if->msk_md, mController, Port); if (EFI_ERROR (Status)) { mSoftc->msk_if[Port] = NULL;
- msk_detach (Port);
- msk_detach (Port, mController, mPciIo, mSoftc); }
return (Status); @@ -1114,7 +1180,8 @@ msk_attach ( */ EFI_STATUS mskc_attach (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN EFI_HANDLE mController,
- IN EFI_PCI_IO_PROTOCOL *mPciIo, OUT EFI_MAC_ADDRESS *Mac ) {
@@ -1123,8 +1190,8 @@ mskc_attach ( UINT8 *PciBarResources; EFI_STATUS Status; struct msk_if_softc *ScIf;
- struct msk_softc *mSoftc;
- mPciIo = PciIo; Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct msk_softc), (VOID**) &mSoftc);
@@ -1295,7 +1362,7 @@ mskc_attach ( break; }
- Status = msk_status_dma_alloc ();
- Status = msk_status_dma_alloc (mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; }
@@ -1305,9 +1372,9 @@ mskc_attach ( mSoftc->msk_intrhwemask = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT | Y2_IS_PCI_EXP | Y2_IS_PCI_NEXP; // Reset the adapter
- mskc_reset ();
- mskc_reset (mPciIo, mSoftc);
- mskc_setup_rambuffer ();
- mskc_setup_rambuffer (mSoftc);
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct msk_if_softc), @@ -1315,9 +1382,16 @@ mskc_attach ( if (EFI_ERROR (Status)) { goto fail; }
- //Add controller to the list
- Status = msk_add_ctrl_data (mController, mPciIo, mSoftc);
- if (EFI_ERROR (Status)) {
- goto fail;
- }
- gBS->SetMem (ScIf, sizeof (struct msk_if_softc), 0); mSoftc->msk_if[MSK_PORT_A] = ScIf;
- Status = msk_attach (MSK_PORT_A);
- Status = msk_attach (MSK_PORT_A, mController, mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; }
@@ -1342,7 +1416,7 @@ mskc_attach ( } gBS->SetMem (ScIf, sizeof (struct msk_if_softc), 0); mSoftc->msk_if[MSK_PORT_B] = ScIf;
- Status = msk_attach (MSK_PORT_B);
- Status = msk_attach (MSK_PORT_B, mController, mPciIo, mSoftc); if (EFI_ERROR (Status)) { goto fail; }
@@ -1360,7 +1434,7 @@ mskc_attach ( EVT_NOTIFY_SIGNAL | EVT_TIMER, TPL_CALLBACK, mskc_tick,
mSoftc,
if (EFI_ERROR (Status)) {(VOID *)mController, &mSoftc->Timer );
@@ -1373,7 +1447,7 @@ mskc_attach ( fail: if (EFI_ERROR (Status)) {
- mskc_detach ();
- mskc_detach (mController); }
return (Status); @@ -1382,7 +1456,7 @@ RESTORE_PCI_ATTRIBS: // // Restore original PCI attributes //
- mPciIo->Attributes (
+mPciIo->Attributes ( mPciIo, EfiPciIoAttributeOperationSet, mSoftc->OriginalPciAttributes, @@ -1402,34 +1476,47 @@ RESTORE_PCI_ATTRIBS: static VOID msk_detach (
- INT32 Port
- INT32 Port,
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if;
sc_if = mSoftc->msk_if[Port];
- msk_stop (sc_if);
- msk_stop (sc_if, mController, mPciIo, mSoftc);
- msk_txrx_dma_free (sc_if);
- msk_txrx_dma_free (sc_if, mPciIo);
- e1000phy_dettach (mController, Port); }
VOID mskc_detach (
- VOID
- EFI_HANDLE mController ) {
- EFI_TPL OldTpl;
- EFI_TPL OldTpl;
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
- if (EFI_ERROR (Status)) {
- return;
- }
- if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
- msk_detach (MSK_PORT_A);
- msk_detach (MSK_PORT_A, mController, mPciIo, mSoftc); gBS->FreePool (mSoftc->msk_if[MSK_PORT_A]); mSoftc->msk_if[MSK_PORT_A] = NULL; } if (mSoftc->msk_if[MSK_PORT_B] != NULL) {
- msk_detach (MSK_PORT_B);
- msk_detach (MSK_PORT_B, mController, mPciIo, mSoftc); gBS->FreePool (mSoftc->msk_if[MSK_PORT_B]); mSoftc->msk_if[MSK_PORT_B] = NULL; }
@@ -1446,7 +1533,7 @@ mskc_detach ( // Put hardware reset. CSR_WRITE_2 (mSoftc, B0_CTST, CS_RST_SET);
- msk_status_dma_free ();
- msk_status_dma_free (mPciIo, mSoftc);
if (mSoftc->Timer != NULL) { gBS->SetTimer (mSoftc->Timer, TimerCancel, 0); @@ -1463,9 +1550,8 @@ mskc_detach ( mSoftc->OriginalPciAttributes, NULL );
- msk_del_ctrl_data (mController); gBS->FreePool (mSoftc);
- mSoftc = NULL;
- mPciIo = NULL;
gBS->RestoreTPL (OldTpl); } @@ -1474,7 +1560,8 @@ mskc_detach ( static EFI_STATUS msk_status_dma_alloc (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -1504,7 +1591,8 @@ msk_status_dma_alloc ( static VOID msk_status_dma_free (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { if (mSoftc->msk_stat_map) {
@@ -1520,7 +1608,8 @@ msk_status_dma_free ( static EFI_STATUS msk_txrx_dma_alloc (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd;
@@ -1585,7 +1674,8 @@ fail: static VOID msk_txrx_dma_free (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd;
@@ -1640,7 +1730,8 @@ static EFI_STATUS msk_encap ( struct msk_if_softc *sc_if,
- MSK_SYSTEM_BUF *m_head
- MSK_SYSTEM_BUF *m_head,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd;
@@ -1713,12 +1804,20 @@ msk_encap ( EFI_STATUS mskc_transmit (
- UINTN BufferSize,
- VOID *Buffer
- EFI_HANDLE mController,
- UINTN BufferSize,
- VOID *Buffer ) { MSK_LINKED_SYSTEM_BUF *LinkedSystemBuf; EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
- if (EFI_ERROR (Status)) {
- return Status;
- }
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (MSK_LINKED_SYSTEM_BUF), @@ -1734,23 +1833,33 @@ mskc_transmit ( LinkedSystemBuf->SystemBuf.Buf = Buffer; LinkedSystemBuf->SystemBuf.Length = BufferSize; InsertTailList (&mSoftc->TransmitQueueHead, &LinkedSystemBuf->Link);
- msk_start (MSK_PORT_A);
- //Force to use the first MAC
- //TODO: enable multi MAC support
- msk_start (MSK_PORT_A, mPciIo, mSoftc); return EFI_SUCCESS; }
void mskc_getstatus (
- IN EFI_HANDLE mController, OUT UINT32 *InterruptStatus, OPTIONAL OUT VOID **TxBuf OPTIONAL ) {
- //struct msk_chain_data* cdata; MSK_LINKED_SYSTEM_BUF *m_head;
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
- if (EFI_ERROR (Status)) {
- return;
- }
// Interrupt status is not read from the device when InterruptStatus is NULL if (InterruptStatus != NULL) { // Check the interrupt lines
- msk_intr ();
- msk_intr (mController, mPciIo, mSoftc); }
// The transmit buffer status is not read when TxBuf is NULL @@ -1771,7 +1880,9 @@ mskc_getstatus ( static VOID msk_start (
- INT32 Port
- INT32 Port,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -1793,7 +1904,7 @@ msk_start ( // don't have room, set the OACTIVE flag and wait // for the NIC to drain the ring. //
- Status = msk_encap (sc_if, &m_head->SystemBuf);
- Status = msk_encap (sc_if, &m_head->SystemBuf, mPciIo); if (EFI_ERROR (Status)) { break; }
@@ -1811,17 +1922,25 @@ msk_start ( VOID mskc_shutdown (
- VOID
- EFI_HANDLE mController ) {
- INTN i;
- EFI_TPL OldTpl;
- INTN i;
- EFI_TPL OldTpl;
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
- if (EFI_ERROR (Status)) {
- return;
- }
- for (i = 0; i < mSoftc->msk_num_port; i++) { if (mSoftc->msk_if[i] != NULL) {
msk_stop (mSoftc->msk_if[i]);
} gBS->SetTimer (mSoftc->Timer, TimerCancel, 0);msk_stop (mSoftc->msk_if[i], mController, mPciIo, mSoftc); }
@@ -1834,13 +1953,22 @@ mskc_shutdown ( EFI_STATUS mskc_receive (
- IN EFI_HANDLE mController, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { MSK_LINKED_SYSTEM_BUF *mBuf;
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- msk_intr (); // check the interrupt lines
- msk_intr (mController, mPciIo, mSoftc); // check the interrupt lines
if (IsListEmpty (&mSoftc->ReceiveQueueHead)) { *BufferSize = 0; @@ -1859,6 +1987,7 @@ mskc_receive ( gBS->CopyMem (Buffer, mBuf->SystemBuf.Buf, *BufferSize); gBS->FreePool(mBuf->SystemBuf.Buf); gBS->FreePool (mBuf);
- return EFI_SUCCESS; }
@@ -1867,7 +1996,9 @@ msk_rxeof ( struct msk_if_softc *sc_if, UINT32 status, UINT32 control,
- INTN len
- INTN len,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { EFI_STATUS Status;
@@ -1909,7 +2040,7 @@ msk_rxeof ( m.DmaMapping = rxd->rx_m.DmaMapping; m.Length = rxd->rx_m.Length;
- Status = msk_newbuf (sc_if, cons);
- Status = msk_newbuf (sc_if, cons, mPciIo); if (EFI_ERROR (Status)) { // This is a dropped packet, but we aren't counting drops // Reuse old buffer
@@ -1951,7 +2082,8 @@ static VOID msk_txeof ( struct msk_if_softc *sc_if,
- INTN idx
- INTN idx,
- EFI_PCI_IO_PROTOCOL *mPciIo ) { struct msk_txdesc *txd;
@@ -1997,11 +2129,23 @@ mskc_tick ( ) { EFI_TPL OldTpl;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
- EFI_STATUS Status;
- EFI_HANDLE mController;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- e1000phy_tick ();
- msk_handle_events ();
- mController = (EFI_HANDLE)Context;
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc);
- if (!EFI_ERROR (Status)) {
- //TODO: enable multi MAC support
- if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
e1000phy_tick (mController, MSK_PORT_A);
- }
- msk_handle_events (mPciIo, mSoftc);
- }
gBS->RestoreTPL (OldTpl); } @@ -2009,13 +2153,14 @@ mskc_tick ( static VOID msk_intr_phy (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_HANDLE mController ) { UINT16 status;
- msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT);
- status = msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT);
- msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT, mController);
- status = msk_phy_readreg (sc_if->msk_md.port, PHY_MARV_INT_STAT, mController);
// Handle FIFO Underrun/Overflow ? if ((status & PHY_M_IS_FIFO_ERROR)) { @@ -2026,7 +2171,8 @@ msk_intr_phy ( static VOID msk_intr_gmac (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { UINT8 status;
@@ -2059,7 +2205,8 @@ static VOID msk_handle_hwerr ( struct msk_if_softc *sc_if,
- UINT32 status
- UINT32 status,
- struct msk_softc *mSoftc ) { if ((status & Y2_IS_PAR_RD1) != 0) {
@@ -2092,7 +2239,8 @@ msk_handle_hwerr ( static VOID msk_intr_hwerr (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { UINT32 status;
@@ -2123,7 +2271,7 @@ msk_intr_hwerr ( DEBUG ((EFI_D_NET, "Marvell Yukon: unexpected IRQ Master error\n")); } // Reset all bits in the PCI status register
- clear_pci_errors ();
- clear_pci_errors (mPciIo, mSoftc); }
// Check for PCI Express Uncorrectable Error. @@ -2164,10 +2312,10 @@ msk_intr_hwerr ( } if ((status & Y2_HWE_L1_MASK) != 0 && mSoftc->msk_if[MSK_PORT_A] != NULL) {
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_A], status);
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_A], status, mSoftc); } if ((status & Y2_HWE_L2_MASK) != 0 && mSoftc->msk_if[MSK_PORT_B] != NULL) {
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_B], status >> 8);
- msk_handle_hwerr (mSoftc->msk_if[MSK_PORT_B], status >> 8, mSoftc); } }
@@ -2175,7 +2323,8 @@ static __inline VOID msk_rxput (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { CSR_WRITE_2 (mSoftc, Y2_PREF_Q_ADDR (sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG), sc_if->msk_cdata.msk_rx_prod);
@@ -2184,7 +2333,8 @@ msk_rxput ( static INTN msk_handle_events (
- VOID
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if;
@@ -2223,7 +2373,7 @@ msk_handle_events ( switch (control & STLE_OP_MASK) { case OP_RXSTAT:
msk_rxeof (sc_if, status, control, len);
msk_rxeof (sc_if, status, control, len, mPciIo, mSoftc); rxprog++; // // Because there is no way to sync single Rx LE
@@ -2233,20 +2383,20 @@ msk_handle_events ( rxput[port]++; // Update prefetch unit if we've passed water mark if (rxput[port] >= sc_if->msk_cdata.msk_rx_putwm) {
msk_rxput (sc_if);
msk_rxput (sc_if, mSoftc); rxput[port] = 0; } break; case OP_TXINDEXLE: if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
msk_txeof (mSoftc->msk_if[MSK_PORT_A], status & STLE_TXA1_MSKL);
msk_txeof (mSoftc->msk_if[MSK_PORT_A], status & STLE_TXA1_MSKL, mPciIo); } if (mSoftc->msk_if[MSK_PORT_B] != NULL) { msk_txeof (mSoftc->msk_if[MSK_PORT_B], ((status & STLE_TXA2_MSKL) >> STLE_TXA2_SHIFTL) | ((len & STLE_TXA2_MSKH) <<
STLE_TXA2_SHIFTH));
STLE_TXA2_SHIFTH), mPciIo); } break; default:
@@ -2262,10 +2412,10 @@ msk_handle_events ( mSoftc->msk_stat_cons = cons; if (rxput[MSK_PORT_A] > 0) {
- msk_rxput (mSoftc->msk_if[MSK_PORT_A]);
- msk_rxput (mSoftc->msk_if[MSK_PORT_A], mSoftc); } if (rxput[MSK_PORT_B] > 0) {
- msk_rxput (mSoftc->msk_if[MSK_PORT_B]);
- msk_rxput (mSoftc->msk_if[MSK_PORT_B], mSoftc); }
return (mSoftc->msk_stat_cons != CSR_READ_2 (mSoftc, STAT_PUT_IDX)); @@ -2274,7 +2424,9 @@ msk_handle_events ( STATIC VOID msk_intr (
- VOID
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_if_softc *sc_if0;
@@ -2297,16 +2449,16 @@ msk_intr ( sc_if1 = mSoftc->msk_if[MSK_PORT_B]; if ((Status & Y2_IS_IRQ_PHY1) != 0 && sc_if0 != NULL) {
- msk_intr_phy (sc_if0);
- msk_intr_phy (sc_if0, mController); } if ((Status & Y2_IS_IRQ_PHY2) != 0 && sc_if1 != NULL) {
- msk_intr_phy (sc_if1);
- msk_intr_phy (sc_if1, mController); } if ((Status & Y2_IS_IRQ_MAC1) != 0 && sc_if0 != NULL) {
- msk_intr_gmac (sc_if0);
- msk_intr_gmac (sc_if0, mSoftc); } if ((Status & Y2_IS_IRQ_MAC2) != 0 && sc_if1 != NULL) {
- msk_intr_gmac (sc_if1);
- msk_intr_gmac (sc_if1, mSoftc); } if ((Status & (Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2)) != 0) { DEBUG ((EFI_D_NET, "Marvell Yukon: Rx descriptor error\n"));
@@ -2321,10 +2473,10 @@ msk_intr ( CSR_READ_4 (mSoftc, B0_IMSK); } if ((Status & Y2_IS_HW_ERR) != 0) {
- msk_intr_hwerr ();
- msk_intr_hwerr (mPciIo, mSoftc); }
- domore = msk_handle_events ();
- domore = msk_handle_events (mPciIo, mSoftc); if ((Status & Y2_IS_STAT_BMU) != 0 && domore == 0) { CSR_WRITE_4 (mSoftc, STAT_CTRL, SC_STAT_CLR_IRQ); }
@@ -2336,7 +2488,8 @@ msk_intr ( static VOID msk_set_tx_stfwd (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { // Disable jumbo frames for Tx
@@ -2345,27 +2498,48 @@ msk_set_tx_stfwd ( EFI_STATUS mskc_init (
- VOID
- EFI_HANDLE mController ) {
- EFI_STATUS Status;
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
- // Just init port A
- Status = msk_init (mSoftc->msk_if[MSK_PORT_A]);
- Status = msk_get_ctrl_data (mController, &mPciIo, &mSoftc); if (EFI_ERROR (Status)) { return Status; }
- if (mSoftc->msk_if[MSK_PORT_A] != NULL) {
- Status = msk_init (mSoftc->msk_if[MSK_PORT_A], mController, mPciIo, mSoftc);
- if (EFI_ERROR (Status)) {
return Status;
- }
- }
- if (mSoftc->msk_if[MSK_PORT_B] != NULL) {
- Status = msk_init (mSoftc->msk_if[MSK_PORT_B], mController, mPciIo, mSoftc);
- if (EFI_ERROR (Status)) {
return Status;
- }
- }
- Status = gBS->SetTimer (mSoftc->Timer, TimerPeriodic, TICKS_PER_SECOND); if (EFI_ERROR (Status)) {
- mskc_shutdown ();
- mskc_shutdown (mController); }
- return Status; }
static EFI_STATUS msk_init (
- IN struct msk_if_softc *sc_if
- IN struct msk_if_softc *sc_if,
- IN EFI_HANDLE mController,
- IN EFI_PCI_IO_PROTOCOL *mPciIo,
- IN struct msk_softc *mSoftc
{ UINT8 *eaddr;)
@@ -2375,7 +2549,7 @@ msk_init ( INTN port = sc_if->msk_md.port; // Cancel pending I/O and free all Rx/Tx buffers.
- msk_stop (sc_if);
- msk_stop (sc_if, mController, mPciIo, mSoftc);
sc_if->msk_framesize = MAX_SUPPORTED_PACKET_SIZE; @@ -2397,7 +2571,7 @@ msk_init ( CSR_READ_1 (mSoftc, MR_ADDR (port, GMAC_IRQ_SRC)); // Clear MIB stats
- msk_stats_clear (sc_if);
- msk_stats_clear (sc_if, mSoftc);
// Disable FCS GMAC_WRITE_2 (mSoftc, port, GM_RX_CTRL, GM_RXCR_CRC_DIS); @@ -2465,14 +2639,14 @@ msk_init ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, TX_GMF_CTRL_T), GMF_OPER_ON); // Configure hardware VLAN tag insertion/stripping
- msk_setvlan (sc_if);
- msk_setvlan (sc_if, mSoftc);
if ((sc_if->msk_flags & MSK_FLAG_RAMBUF) == 0) { // Set Rx Pause threshould. CSR_WRITE_2 (mSoftc, MR_ADDR (port, RX_GMF_LP_THR), MSK_ECU_LLPP); CSR_WRITE_2 (mSoftc, MR_ADDR (port, RX_GMF_UP_THR), MSK_ECU_ULPP); // Configure store-and-forward for Tx.
- msk_set_tx_stfwd (sc_if);
- msk_set_tx_stfwd (sc_if, mSoftc); }
if (mSoftc->msk_hw_id == CHIP_ID_YUKON_FE_P && mSoftc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) { @@ -2491,7 +2665,7 @@ msk_init ( CSR_WRITE_1 (mSoftc, MR_ADDR (port, TXA_CTRL), TXA_ENA_ARB); // Setup RAM buffer
- msk_set_rambuffer (sc_if);
- msk_set_rambuffer (sc_if, mSoftc);
// Disable Tx sync Queue CSR_WRITE_1 (mSoftc, RB_ADDR (sc_if->msk_txsq, RB_CTRL), RB_RST_SET); @@ -2533,16 +2707,16 @@ msk_init ( CSR_WRITE_4 (mSoftc, MR_ADDR (port, RX_GMF_TR_THR), 0x17a); CSR_WRITE_4 (mSoftc, MR_ADDR (port, RX_GMF_CTRL_T), RX_TRUNC_ON);
- msk_set_prefetch (sc_if->msk_txq, sc_if->msk_rdata.msk_tx_ring_paddr, MSK_TX_RING_CNT - 1);
- msk_set_prefetch (sc_if->msk_txq, sc_if->msk_rdata.msk_tx_ring_paddr, MSK_TX_RING_CNT - 1, mSoftc); msk_init_tx_ring (sc_if);
// Disable Rx checksum offload and RSS hash CSR_WRITE_4 (mSoftc, Q_ADDR (sc_if->msk_rxq, Q_CSR), BMU_DIS_RX_CHKSUM | BMU_DIS_RX_RSS_HASH);
- msk_set_prefetch (sc_if->msk_rxq, sc_if->msk_rdata.msk_rx_ring_paddr, MSK_RX_RING_CNT - 1);
- Status = msk_init_rx_ring (sc_if);
- msk_set_prefetch (sc_if->msk_rxq, sc_if->msk_rdata.msk_rx_ring_paddr, MSK_RX_RING_CNT - 1, mSoftc);
- Status = msk_init_rx_ring (sc_if, mPciIo, mSoftc); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Marvell Yukon: Initialization failed: no memory for Rx buffers\n"));
- msk_stop (sc_if);
- msk_stop (sc_if, mController, mPciIo, mSoftc); return Status; }
@@ -2574,7 +2748,7 @@ msk_init ( CSR_READ_4 (mSoftc, B0_IMSK); sc_if->msk_flags &= ~MSK_FLAG_LINK;
- e1000phy_mediachg ();
- e1000phy_mediachg (mController, port);
return Status; } @@ -2582,7 +2756,8 @@ msk_init ( STATIC VOID msk_set_rambuffer (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { INTN ltpp, utpp;
@@ -2626,9 +2801,10 @@ msk_set_rambuffer ( STATIC VOID msk_set_prefetch (
- INTN qaddr,
- INTN qaddr, EFI_PHYSICAL_ADDRESS addr,
- UINT32 count
- UINT32 count,
- struct msk_softc *mSoftc ) { // Reset the prefetch unit
@@ -2649,7 +2825,10 @@ msk_set_prefetch ( static VOID msk_stop (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc ) { struct msk_txdesc *txd;
@@ -2678,7 +2857,7 @@ msk_stop ( // Read again to ensure writing. GMAC_READ_2 (mSoftc, port, GM_GP_CTRL); // Update stats and clear counters
- msk_stats_update (sc_if);
- msk_stats_update (sc_if, mSoftc);
// Stop Tx BMU CSR_WRITE_4 (mSoftc, Q_ADDR (sc_if->msk_txq, Q_CSR), BMU_STOP); @@ -2700,7 +2879,7 @@ msk_stop ( // Disable all GMAC interrupt. CSR_WRITE_1 (mSoftc, MR_ADDR (port, GMAC_IRQ_MSK), 0); // Disable PHY interrupt. */
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0);
- msk_phy_writereg (port, PHY_MARV_INT_MASK, 0, mController);
// Disable the RAM Interface Arbiter. CSR_WRITE_1 (mSoftc, MR_ADDR (port, TXA_CTRL), TXA_DIS_ARB); @@ -2788,7 +2967,8 @@ msk_stop ( static VOID msk_stats_clear (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { UINT16 gmac;
@@ -2812,7 +2992,8 @@ msk_stats_clear ( static VOID msk_stats_update (
- struct msk_if_softc *sc_if
- struct msk_if_softc *sc_if,
- struct msk_softc *mSoftc ) { struct msk_hw_stats *stats;
@@ -2877,5 +3058,125 @@ msk_stats_update ( GMAC_WRITE_2 (mSoftc, port, GM_PHY_ADDR, gmac); } +void +mskc_init_driver_list (VOID) +{
- InitializeListHead (&msk_drv_data_head);
- e1000phy_init_driver_list ();
+}
+static +EFI_STATUS +msk_get_ctrl_data (
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL **mPciIo,
- struct msk_softc **mSoftc
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- *mSoftc = mDrvNode->mSoftc;
- *mPciIo = mDrvNode->mPciIo;
- }
- return Status;
+}
+static +EFI_STATUS +msk_get_ctrl_data_msks (
- EFI_HANDLE mController,
- struct msk_softc **mSoftc
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- *mSoftc = mDrvNode->mSoftc;
- }
- return Status;
+}
+static +EFI_STATUS +msk_add_ctrl_data (
- EFI_HANDLE mController,
- EFI_PCI_IO_PROTOCOL *mPciIo,
- struct msk_softc *mSoftc
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (EFI_ERROR(Status)) {
- Status = gBS->AllocatePool (EfiBootServicesData,
sizeof (MSK_LINKED_DRV_BUF),
(VOID**) &mDrvNode);
- if (!EFI_ERROR (Status)) {
mDrvNode->Signature = MSK_DRV_SIGNATURE;
mDrvNode->mController = mController;
mDrvNode->mPciIo = mPciIo;
mDrvNode->mSoftc = mSoftc;
InsertTailList (&msk_drv_data_head, &mDrvNode->Link);
- }
- } else {
- Status = EFI_ALREADY_STARTED;
- }
- return Status;
+}
+static +EFI_STATUS +msk_del_ctrl_data (
- EFI_HANDLE mController
- )
+{
- MSK_LINKED_DRV_BUF *mDrvNode;
- EFI_STATUS Status;
- Status = msk_find_drv_node (mController, &mDrvNode);
- if (!EFI_ERROR(Status)) {
- RemoveEntryList (&mDrvNode->Link);
- gBS->FreePool (mDrvNode);
- }
- return Status;
+}
+static +EFI_STATUS +msk_find_drv_node (
- EFI_HANDLE mController,
- MSK_LINKED_DRV_BUF **mDrvNode
- )
+{
- MSK_LINKED_DRV_BUF *mDrvBuffNode;
- EFI_STATUS Status;
- LIST_ENTRY *Node;
- Status = EFI_NOT_FOUND;
- Node = GetFirstNode (&msk_drv_data_head);
- while (!IsNull (&msk_drv_data_head, Node)) {
- mDrvBuffNode = MSK_DRV_INFO_FROM_THIS (Node);
- if (mDrvBuffNode->mController == mController) {
*mDrvNode = mDrvBuffNode;
Status = EFI_SUCCESS;
break;
- }
- Node = GetNextNode (&msk_drv_data_head, Node);
- }
- return Status;
+}
- #undef MSK_READ_MIB32 #undef MSK_READ_MIB64
diff --git a/Drivers/Net/MarvellYukonDxe/if_msk.h b/Drivers/Net/MarvellYukonDxe/if_msk.h index 110c562..07990fe 100644 --- a/Drivers/Net/MarvellYukonDxe/if_msk.h +++ b/Drivers/Net/MarvellYukonDxe/if_msk.h @@ -14,19 +14,21 @@ **/ #include <Uefi.h> +#include <Protocol/PciIo.h> #define MAX_SUPPORTED_PACKET_SIZE (1566) /* No jumbo frame size support */ EFI_STATUS mskc_probe (EFI_PCI_IO_PROTOCOL *PciIo); -EFI_STATUS mskc_attach (EFI_PCI_IO_PROTOCOL *PciIo, EFI_MAC_ADDRESS *Mac); -void mskc_detach (void); +EFI_STATUS mskc_attach (EFI_HANDLE, EFI_PCI_IO_PROTOCOL *PciIo, EFI_MAC_ADDRESS *Mac); +void mskc_detach (EFI_HANDLE); -EFI_STATUS mskc_init (void); -void mskc_shutdown (void); +EFI_STATUS mskc_init (EFI_HANDLE); +void mskc_shutdown (EFI_HANDLE); void mskc_rxfilter (
- IN EFI_HANDLE mController, IN UINT32 FilterFlags, IN UINTN MCastFilterCnt, IN EFI_MAC_ADDRESS *MCastFilter
@@ -34,18 +36,26 @@ mskc_rxfilter ( EFI_STATUS mskc_transmit (
- IN EFI_HANDLE mController, IN UINTN BufferSize, IN VOID *Buffer );
EFI_STATUS mskc_receive (
- IN EFI_HANDLE mController, IN OUT UINTN *BufferSize, OUT VOID *Buffer );
void mskc_getstatus (
- IN EFI_HANDLE mController, OUT UINT32 *InterruptStatus, OPTIONAL OUT VOID **TxBuf OPTIONAL );
+void +mskc_init_driver_list (
- VOID
- );
diff --git a/Drivers/Net/MarvellYukonDxe/if_mskreg.h b/Drivers/Net/MarvellYukonDxe/if_mskreg.h index 7718536..9f11e8e 100644 --- a/Drivers/Net/MarvellYukonDxe/if_mskreg.h +++ b/Drivers/Net/MarvellYukonDxe/if_mskreg.h @@ -2466,6 +2466,23 @@ struct msk_softc { EFI_EVENT Timer; }; +typedef struct {
- UINT32 Signature;
- LIST_ENTRY Link;
- EFI_HANDLE mController;
- EFI_PCI_IO_PROTOCOL *mPciIo;
- struct msk_softc *mSoftc;
+} MSK_LINKED_DRV_BUF;
+#define MSK_DRV_SIGNATURE SIGNATURE_32 ('m', 's', 'k', 'c')
+#define MSK_DRV_INFO_FROM_THIS(a) \
- CR (a, \
MSK_LINKED_DRV_BUF, \
Link, \
MSK_DRV_SIGNATURE \
);
- #define MSK_USECS(sc, us) ((sc)->msk_clock * (us))
/* Softc for each logical interface. */ diff --git a/Drivers/Net/MarvellYukonDxe/miivar.h b/Drivers/Net/MarvellYukonDxe/miivar.h index 1903ef6..73fba3f 100644 --- a/Drivers/Net/MarvellYukonDxe/miivar.h +++ b/Drivers/Net/MarvellYukonDxe/miivar.h @@ -55,13 +55,6 @@ #define _DEV_MII_MIIVAR_H_ /*
- Callbacks from MII layer into network interface device driver.
- */
-INTN msk_phy_readreg (INTN, INTN); -INTN msk_phy_writereg (INTN, INTN, INTN); -void msk_miibus_statchg (INTN);
-/*
- A network interface driver has one of these structures in its softc.
- It is the interface from the network interface driver to the MII
- layer.
@@ -181,9 +174,9 @@ struct mii_phydesc { #define MII_PHY_DESC(a, b) { MII_OUI_ ## a, MII_MODEL_ ## a ## _ ## b, MII_STR_ ## a ## _ ## b } #define MII_PHY_END { 0, 0, NULL } -#define PHY_READ(p, r) msk_phy_readreg ((p)->mmd->port, (r)) +#define PHY_READ(p, r, c) msk_phy_readreg ((p)->mmd->port, (r), (c)) -#define PHY_WRITE(p, r, v) msk_phy_writereg ((p)->mmd->port, (r), (v)) +#define PHY_WRITE(p, r, v, c) msk_phy_writereg ((p)->mmd->port, (r), (v), (c)) struct msk_mii_data { INTN port; @@ -191,8 +184,4 @@ struct msk_mii_data { INTN mii_flags; }; -EFI_STATUS e1000_probe_and_attach (struct mii_data *mii, const struct msk_mii_data *mmd); -void e1000phy_tick (void); -void e1000phy_mediachg (void);
- #endif /* _DEV_MII_MIIVAR_H_ */
On 19 October 2016 at 05:32, Alan Ott alan@softiron.co.uk wrote:
On 10/17/2016 05:45 PM, Daniil Egranov wrote:
The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
I tested this, and it does work on my hardware here.
I guess my biggest criticism of this patch is, why change all the function prototypes to take mSoftc, mController, and mPciIo parameters? In the FreeBSD[0] driver, the msk_softc is simply held by the msk_if_softc (which is the main object for each network controller (interface)). The PCI I/O could be held there too. Each function that needs a msk_softc can simply get it from the msk_if_softc when it needs it.
The FreeBSD driver, for the most part, passes around msk_if_softc pointers, which makes sense, since from those pointers you can get to everything else.
Is there a reason that would not work here? It seems like a much cleaner interface an fewer variables to keep track of and it wouldn't have to change function interfaces to have redundant parameters.
For example, have a look at FreeBSD's msk_phy_readreg() at [1]. It takes a msk_if_softc pointer and gets the msk_softc from it when it needs it. Your version of msk_phy_readreg() takes an mController parameter and then does a lookup of the msk_softc from a list[2] (every time you want to read a register!). The calling functions _have_ the msk_if_softc already. Just make msk_phy_readreg() take a msk_if_softc pointer (like the BSD driver does), and there would be no lookup required.
Thanks Alan.
You guys know this code way better than I do, but I tend to agree with Alan that
a) it makes sense to follow the FreeBSD code more closely b) the patch in its current form mixes too many types of changes c) adding linked lists to look up values that could be obtained in a more straightforward way seems unwise.
Hi Alan,
On 10/19/2016 11:37 AM, Ard Biesheuvel wrote:
On 19 October 2016 at 05:32, Alan Ott alan@softiron.co.uk wrote:
On 10/17/2016 05:45 PM, Daniil Egranov wrote:
The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
I tested this, and it does work on my hardware here.
Does it fail to detect the hardware or there is no communication? Do you have a dual MAC controller? I tested it on Juno with three Marvell cards and have not seen any issues.
I guess my biggest criticism of this patch is, why change all the function prototypes to take mSoftc, mController, and mPciIo parameters? In the FreeBSD[0] driver, the msk_softc is simply held by the msk_if_softc (which is the main object for each network controller (interface)). The PCI I/O could be held there too. Each function that needs a msk_softc can simply get it from the msk_if_softc when it needs it.
The FreeBSD driver, for the most part, passes around msk_if_softc pointers, which makes sense, since from those pointers you can get to everything else.
The same thing happens in the patch. The pointer to msk_softc passed around the functions. The MSK_LINKED_DRV_BUF structure is equal to FreeBSD msk_if_softc. The UEFI type variables kept outside of the original msk driver structures and passed as extra parameters to the functions.
The first approach was to save a pointer to the msk_softc for each controller and hold it as part of the driver's binding structure. However, the complication comes from the e1000phy.c. First, it has it's own PHY structure which has to be saved related to the controller. Second, it has dependency on the if_msk.c. It's calling functions from the if_msk.c which require access to the msk_softc structure so e1000phy has to tell the if_msk.c functions which msk_softc structure to use without having visibility to this structure. The mController is a common device descriptor between e1000phy and if_msk which binds them to the same controller (= dev in FreeBSD).
The msk_softc and e1000phy_softc lookup calls minimized to the UEFI driver interface functions and if_msk.c functions used by e1000phy.
The approach is similar to the FreeBSD one but using linked list to store the data, i do not see a big difference. If you will check the linked list node lookup, it's about the same as the device_get_softc() but with extra security checking. Also, the pointers to driver data structures stored privately inside of the linked list and not exposed to the outside world through SNP. The performance impact should be insignificant.
Is there a reason that would not work here? It seems like a much cleaner interface an fewer variables to keep track of and it wouldn't have to change function interfaces to have redundant parameters.
For example, have a look at FreeBSD's msk_phy_readreg() at [1]. It takes a msk_if_softc pointer and gets the msk_softc from it when it needs it. Your version of msk_phy_readreg() takes an mController parameter and then does a lookup of the msk_softc from a list[2] (every time you want to read a register!).
The same thing happens in FreeBSD driver, it returns the msk structure based on dev: struct msk_if_softc *sc_if; sc_if = device_get_softc(dev);
The UEFI driver does the same thing but adds extra security checking on the lookup: struct msk_softc *mSoftc; Status = msk_get_ctrl_data_msks (mController, &mSoftc);
The calling functions _have_ the msk_if_softc already. Just make msk_phy_readreg() take a msk_if_softc pointer (like the BSD driver does), and there would be no lookup required.
Thanks Alan.
You guys know this code way better than I do, but I tend to agree with Alan that
a) it makes sense to follow the FreeBSD code more closely b) the patch in its current form mixes too many types of changes c) adding linked lists to look up values that could be obtained in a more straightforward way seems unwise. _______________________________________________ Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi
On 19 Oct 2016, at 20:44, Daniil Egranov daniil.egranov@arm.com wrote:
Hi Alan,
On 10/19/2016 11:37 AM, Ard Biesheuvel wrote:
On 19 October 2016 at 05:32, Alan Ott alan@softiron.co.uk wrote:
On 10/17/2016 05:45 PM, Daniil Egranov wrote: The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
I tested this, and it does work on my hardware here.
Does it fail to detect the hardware or there is no communication? Do you have a dual MAC controller? I tested it on Juno with three Marvell cards and have not seen any issues.
It *does* work, so no problem here
I guess my biggest criticism of this patch is, why change all the function prototypes to take mSoftc, mController, and mPciIo parameters? In the FreeBSD[0] driver, the msk_softc is simply held by the msk_if_softc (which is the main object for each network controller (interface)). The PCI I/O could be held there too. Each function that needs a msk_softc can simply get it from the msk_if_softc when it needs it.
The FreeBSD driver, for the most part, passes around msk_if_softc pointers, which makes sense, since from those pointers you can get to everything else.
The same thing happens in the patch. The pointer to msk_softc passed around the functions. The MSK_LINKED_DRV_BUF structure is equal to FreeBSD msk_if_softc. The UEFI type variables kept outside of the original msk driver structures and passed as extra parameters to the functions.
The first approach was to save a pointer to the msk_softc for each controller and hold it as part of the driver's binding structure. However, the complication comes from the e1000phy.c. First, it has it's own PHY structure which has to be saved related to the controller. Second, it has dependency on the if_msk.c. It's calling functions from the if_msk.c which require access to the msk_softc structure so e1000phy has to tell the if_msk.c functions which msk_softc structure to use without having visibility to this structure. The mController is a common device descriptor between e1000phy and if_msk which binds them to the same controller (= dev in FreeBSD).
The msk_softc and e1000phy_softc lookup calls minimized to the UEFI driver interface functions and if_msk.c functions used by e1000phy.
The approach is similar to the FreeBSD one but using linked list to store the data, i do not see a big difference. If you will check the linked list node lookup, it's about the same as the device_get_softc() but with extra security checking. Also, the pointers to driver data structures stored privately inside of the linked list and not exposed to the outside world through SNP. The performance impact should be insignificant.
Is there a reason that would not work here? It seems like a much cleaner interface an fewer variables to keep track of and it wouldn't have to change function interfaces to have redundant parameters.
For example, have a look at FreeBSD's msk_phy_readreg() at [1]. It takes a msk_if_softc pointer and gets the msk_softc from it when it needs it. Your version of msk_phy_readreg() takes an mController parameter and then does a lookup of the msk_softc from a list[2] (every time you want to read a register!).
The same thing happens in FreeBSD driver, it returns the msk structure based on dev: struct msk_if_softc *sc_if; sc_if = device_get_softc(dev);
The UEFI driver does the same thing but adds extra security checking on the lookup: struct msk_softc *mSoftc; Status = msk_get_ctrl_data_msks (mController, &mSoftc);
The calling functions _have_ the msk_if_softc already. Just make msk_phy_readreg() take a msk_if_softc pointer (like the BSD driver does), and there would be no lookup required.
Thanks Alan.
You guys know this code way better than I do, but I tend to agree with Alan that
a) it makes sense to follow the FreeBSD code more closely b) the patch in its current form mixes too many types of changes c) adding linked lists to look up values that could be obtained in a more straightforward way seems unwise. _______________________________________________ Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi
On 10/19/2016 03:44 PM, Daniil Egranov wrote:
On 10/19/2016 11:37 AM, Ard Biesheuvel wrote:
On 19 October 2016 at 05:32, Alan Ott alan@softiron.co.uk wrote:
On 10/17/2016 05:45 PM, Daniil Egranov wrote:
The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
I tested this, and it does work on my hardware here.
Does it fail to detect the hardware or there is no communication? Do you have a dual MAC controller? I tested it on Juno with three Marvell cards and have not seen any issues.
I said it works. :)
I guess my biggest criticism of this patch is, why change all the function prototypes to take mSoftc, mController, and mPciIo parameters? In the FreeBSD[0] driver, the msk_softc is simply held by the msk_if_softc (which is the main object for each network controller (interface)). The PCI I/O could be held there too. Each function that needs a msk_softc can simply get it from the msk_if_softc when it needs it.
The FreeBSD driver, for the most part, passes around msk_if_softc pointers, which makes sense, since from those pointers you can get to everything else.
The same thing happens in the patch. The pointer to msk_softc passed around the functions. The MSK_LINKED_DRV_BUF structure is equal to FreeBSD msk_if_softc. The UEFI type variables kept outside of the original msk driver structures and passed as extra parameters to the functions.
What? No. the msk_if_softc in the UEFI driver is the same as the msk_if_softc in the FreeBSD driver. It's the same structure, and named the same thing. I'm saying to put a pointer to the msk_softc in the msk_if_softc, rather than passing the msk_softc (often named mSoftc) into every function that needs it.
I'm saying: 1. put a pointer to msk_softc into the msk_if_softc, like the FreeBSD driver has. 2. Pass msk_if_softc into functions like msk_phy_readreg(). See: https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c#L409 3. In functions like msk_phy_readreg(): 3a. just use the pointer to the msk_softc from the msk_if_softc when you need it, just like the BSD driver. 3b. Don't look up the msk_softc using msk_get_ctrl_data_msks(), because it walks a list.
The first approach was to save a pointer to the msk_softc for each controller and hold it as part of the driver's binding structure.
I don't know what you mean by "driver's binding structure." Which one are you talking about?
However, the complication comes from the e1000phy.c. First, it has it's own PHY structure which has to be saved related to the controller. Second, it has dependency on the if_msk.c. It's calling functions from the if_msk.c which require access to the msk_softc structure so e1000phy has to tell the if_msk.c functions which msk_softc structure to use without having visibility to this structure. The mController is a common device descriptor between e1000phy and if_msk which binds them to the same controller (= dev in FreeBSD).
The phy functions have an mii_softc, so add the appropriate things to that structure (such as the msk_if_softc) instead of passing them into every single function. You can connect them in the _attach() functions
In the BSD driver, there's infrastructure to match the PHY to the MAC. In our case, they could easily be matched up by the calls to PHY_READ(), PHY_WRITE(). if those macros were to take an mii_softc and if mii_softc were modified to hold a pointer to an msk_if_softc.
The msk_softc and e1000phy_softc lookup calls minimized to the UEFI driver interface functions and if_msk.c functions used by e1000phy.
The approach is similar to the FreeBSD one but using linked list to store the data, i do not see a big difference. If you will check the linked list node lookup, it's about the same as the device_get_softc() but with extra security checking.
No, device_get_softc() just returns a data pointer. It doesn't have to walk a list. It's O(1) instead of O(n).
Also, the pointers to driver data structures stored privately inside of the linked list and not exposed to the outside world through SNP. The performance impact should be insignificant.
It's the complexity of the code that's the issue. It's complex when it doesn't need to be.
Is there a reason that would not work here? It seems like a much cleaner interface an fewer variables to keep track of and it wouldn't have to change function interfaces to have redundant parameters.
For example, have a look at FreeBSD's msk_phy_readreg() at [1]. It takes a msk_if_softc pointer and gets the msk_softc from it when it needs it. Your version of msk_phy_readreg() takes an mController parameter and then does a lookup of the msk_softc from a list[2] (every time you want to read a register!).
The same thing happens in FreeBSD driver, it returns the msk structure based on dev: struct msk_if_softc *sc_if; sc_if = device_get_softc(dev);
device_get_softc() just gets a pointer to a device's private data pointer: https://www.freebsd.org/cgi/man.cgi?query=device_get_softc&sektion=9
It's returning a pointer, not walking a list.
The UEFI driver does the same thing but adds extra security checking on the lookup: struct msk_softc *mSoftc; Status = msk_get_ctrl_data_msks (mController, &mSoftc);
These are not the same. One just returns a pointer that it has access to (FreeBSD), the other walks a list (UEFI).
Alan.
Hi Alan,
On 10/19/2016 04:12 PM, Alan Ott wrote:
On 10/19/2016 03:44 PM, Daniil Egranov wrote:
On 10/19/2016 11:37 AM, Ard Biesheuvel wrote:
On 19 October 2016 at 05:32, Alan Ott alan@softiron.co.uk wrote:
On 10/17/2016 05:45 PM, Daniil Egranov wrote:
The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
I tested this, and it does work on my hardware here.
Does it fail to detect the hardware or there is no communication? Do you have a dual MAC controller? I tested it on Juno with three Marvell cards and have not seen any issues.
I said it works. :)
I misread it, sorry.
I guess my biggest criticism of this patch is, why change all the function prototypes to take mSoftc, mController, and mPciIo parameters? In the FreeBSD[0] driver, the msk_softc is simply held by the msk_if_softc (which is the main object for each network controller (interface)). The PCI I/O could be held there too. Each function that needs a msk_softc can simply get it from the msk_if_softc when it needs it.
The FreeBSD driver, for the most part, passes around msk_if_softc pointers, which makes sense, since from those pointers you can get to everything else.
The same thing happens in the patch. The pointer to msk_softc passed around the functions. The MSK_LINKED_DRV_BUF structure is equal to FreeBSD msk_if_softc. The UEFI type variables kept outside of the original msk driver structures and passed as extra parameters to the functions.
What? No. the msk_if_softc in the UEFI driver is the same as the msk_if_softc in the FreeBSD driver. It's the same structure, and named the same thing. I'm saying to put a pointer to the msk_softc in the msk_if_softc, rather than passing the msk_softc (often named mSoftc) into every function that needs it.
I am not talking about similarity between the UEFI msk_if_softc and FreeBSD msk_if_softc. I am talking about the MSK_LINKED_DRV_BUF structure containing a pointer to the msk_softc similar to the current FreeBSD msk_if_softc structure and used for the same purpose.
I'm saying:
- put a pointer to msk_softc into the msk_if_softc, like the FreeBSD
driver has. 2. Pass msk_if_softc into functions like msk_phy_readreg(). See: https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c#L409 3. In functions like msk_phy_readreg(): 3a. just use the pointer to the msk_softc from the msk_if_softc when you need it, just like the BSD driver.
I understand what you say. You want to pass it as part of the structure vs pass it as a function parameter. I doubt that the code complexity will be different. It's more interesting which way will be better performance wise.
3b. Don't look up the msk_softc using msk_get_ctrl_data_msks(), because it walks a list.
The msk_get_ctrl_data_msks() is not called all the time. It use to get a msk_softc pointer only when the driver interface functions is called and with e1000phy/if_msk interface calls. In all other cases, a pointier to the msk_softc will be already available.
I don't know what kind of issue you have with the linked list. Please explain. The UEFI linked list is very lite and as i explained before, it adds the data integrity checking with a little overhead. The driver is using the linked list in several places already.
The first approach was to save a pointer to the msk_softc for each controller and hold it as part of the driver's binding structure.
I don't know what you mean by "driver's binding structure." Which one are you talking about?
YUKON_DRIVER structure
However, the complication comes from the e1000phy.c. First, it has it's own PHY structure which has to be saved related to the controller. Second, it has dependency on the if_msk.c. It's calling functions from the if_msk.c which require access to the msk_softc structure so e1000phy has to tell the if_msk.c functions which msk_softc structure to use without having visibility to this structure. The mController is a common device descriptor between e1000phy and if_msk which binds them to the same controller (= dev in FreeBSD).
The phy functions have an mii_softc, so add the appropriate things to that structure (such as the msk_if_softc) instead of passing them into every single function. You can connect them in the _attach() functions
In the BSD driver, there's infrastructure to match the PHY to the MAC. In our case, they could easily be matched up by the calls to PHY_READ(), PHY_WRITE(). if those macros were to take an mii_softc and if mii_softc were modified to hold a pointer to an msk_if_softc.
No, I do not want to mix e1000phy and if_msk structures. The patch adds the controller id to PHY_READ() and PHY_WRITE() which is used to get a data pointer to the associated msk_softc structure. It's doing the same thing as you explained above without mixing the structures.
The msk_softc and e1000phy_softc lookup calls minimized to the UEFI driver interface functions and if_msk.c functions used by e1000phy.
The approach is similar to the FreeBSD one but using linked list to store the data, i do not see a big difference. If you will check the linked list node lookup, it's about the same as the device_get_softc() but with extra security checking.
No, device_get_softc() just returns a data pointer. It doesn't have to walk a list. It's O(1) instead of O(n).
Also, the pointers to driver data structures stored privately inside of the linked list and not exposed to the outside world through SNP. The performance impact should be insignificant.
It's the complexity of the code that's the issue. It's complex when it doesn't need to be.
I disagree. What you suggest has the same complexity. Also, what you suggest requires e1000phy_softc (for each port) and msk_softc pointers for each controller to be stored as part of the corresponding YUKON_DRIVER driver structure. As I explained above, I do not want to do it.
Is there a reason that would not work here? It seems like a much cleaner interface an fewer variables to keep track of and it wouldn't have to change function interfaces to have redundant parameters.
For example, have a look at FreeBSD's msk_phy_readreg() at [1]. It takes a msk_if_softc pointer and gets the msk_softc from it when it needs it. Your version of msk_phy_readreg() takes an mController parameter and then does a lookup of the msk_softc from a list[2] (every time you want to read a register!).
The same thing happens in FreeBSD driver, it returns the msk structure based on dev: struct msk_if_softc *sc_if; sc_if = device_get_softc(dev);
device_get_softc() just gets a pointer to a device's private data pointer: https://www.freebsd.org/cgi/man.cgi?query=device_get_softc&sektion=9
It's returning a pointer, not walking a list.
The UEFI driver does the same thing but adds extra security checking on the lookup: struct msk_softc *mSoftc; Status = msk_get_ctrl_data_msks (mController, &mSoftc);
These are not the same. One just returns a pointer that it has access to (FreeBSD), the other walks a list (UEFI).
The result is the same. The msk_get_ctrl_data_msks has extra steps and i already explained why.
Alan.
Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi
Thanks, Daniil
On 10/19/2016 10:03 PM, Daniil Egranov wrote:
On 10/19/2016 04:12 PM, Alan Ott wrote:
On 10/19/2016 03:44 PM, Daniil Egranov wrote:
On 10/19/2016 11:37 AM, Ard Biesheuvel wrote:
On 19 October 2016 at 05:32, Alan Ott alan@softiron.co.uk wrote:
On 10/17/2016 05:45 PM, Daniil Egranov wrote:
The patch adds support for multi-controller configuration.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniil Egranov daniil.egranov@arm.com
I tested this, and it does work on my hardware here.
Does it fail to detect the hardware or there is no communication? Do you have a dual MAC controller? I tested it on Juno with three Marvell cards and have not seen any issues.
I said it works. :)
I misread it, sorry.
I guess my biggest criticism of this patch is, why change all the function prototypes to take mSoftc, mController, and mPciIo parameters? In the FreeBSD[0] driver, the msk_softc is simply held by the msk_if_softc (which is the main object for each network controller (interface)). The PCI I/O could be held there too. Each function that needs a msk_softc can simply get it from the msk_if_softc when it needs it.
The FreeBSD driver, for the most part, passes around msk_if_softc pointers, which makes sense, since from those pointers you can get to everything else.
The same thing happens in the patch. The pointer to msk_softc passed around the functions. The MSK_LINKED_DRV_BUF structure is equal to FreeBSD msk_if_softc. The UEFI type variables kept outside of the original msk driver structures and passed as extra parameters to the functions.
What? No. the msk_if_softc in the UEFI driver is the same as the msk_if_softc in the FreeBSD driver. It's the same structure, and named the same thing. I'm saying to put a pointer to the msk_softc in the msk_if_softc, rather than passing the msk_softc (often named mSoftc) into every function that needs it.
I am not talking about similarity between the UEFI msk_if_softc and FreeBSD msk_if_softc. I am talking about the MSK_LINKED_DRV_BUF structure containing a pointer to the msk_softc similar to the current FreeBSD msk_if_softc structure and used for the same purpose.
I'm saying:
- put a pointer to msk_softc into the msk_if_softc, like the FreeBSD
driver has. 2. Pass msk_if_softc into functions like msk_phy_readreg(). See: https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c#L409 3. In functions like msk_phy_readreg(): 3a. just use the pointer to the msk_softc from the msk_if_softc when you need it, just like the BSD driver.
I understand what you say. You want to pass it as part of the structure vs pass it as a function parameter. I doubt that the code complexity will be different.
What's different is, the FreeBSD driver passes in what's needed instead of passing in a token that is used to walk a list to find the thing that that is needed. One is a whole lot more clear an concise.
It's more interesting which way will be better performance wise.
One executes in constant time, the other walks a list. One is constant time, the other is O(n).[1]
3b. Don't look up the msk_softc using msk_get_ctrl_data_msks(), because it walks a list.
The msk_get_ctrl_data_msks() is not called all the time. It use to get a msk_softc pointer only when the driver interface functions is called and with e1000phy/if_msk interface calls. In all other cases, a pointier to the msk_softc will be already available.
Your argument here seems to be that it's ok that the code is more complex and slow than it needs to be because it doesn't get called very often. The problem isn't the number of microseconds wasted; the problem is that it's more code and code complexity where there doesn't need to be code complexity.
You have multiple variables being thrown around: msk_softc (mSoftc) msk_if_softc (often sc_if) EFI_HANDLE (mController) EFI_PCI_PROTOCOL (mPciIo)
Put them in structures that logically make sense, rather than passing them all around separately. That's all I'm saying.
I don't know what kind of issue you have with the linked list. Please explain. The UEFI linked list is very lite and as i explained before, it adds the data integrity checking with a little overhead. The driver is using the linked list in several places already.
I don't have a problem with linked lists or the UEFI linked list implementation, but like any data structure, why should you have a linked list when you don't have to have a linked list? Why have a list and look-ups and lots of variables passed around independently of each other when you can do things like: sc_if->msk_softc instead?
The first approach was to save a pointer to the msk_softc for each controller and hold it as part of the driver's binding structure.
I don't know what you mean by "driver's binding structure." Which one are you talking about?
YUKON_DRIVER structure
However, the complication comes from the e1000phy.c. First, it has it's own PHY structure which has to be saved related to the controller. Second, it has dependency on the if_msk.c. It's calling functions from the if_msk.c which require access to the msk_softc structure so e1000phy has to tell the if_msk.c functions which msk_softc structure to use without having visibility to this structure. The mController is a common device descriptor between e1000phy and if_msk which binds them to the same controller (= dev in FreeBSD).
The phy functions have an mii_softc, so add the appropriate things to that structure (such as the msk_if_softc) instead of passing them into every single function. You can connect them in the _attach() functions
In the BSD driver, there's infrastructure to match the PHY to the MAC. In our case, they could easily be matched up by the calls to PHY_READ(), PHY_WRITE(). if those macros were to take an mii_softc and if mii_softc were modified to hold a pointer to an msk_if_softc.
No, I do not want to mix e1000phy and if_msk structures. The patch adds the controller id to PHY_READ() and PHY_WRITE() which is used to get a data pointer to the associated msk_softc structure. It's doing the same thing as you explained above without mixing the structures.
If you want to keep e1000phy and if_msk separate, then when you attach the phy, pass in what you need (mController, PciIo, etc), and store them somewhere in the phy's data structures. When possible, you should be passing one object around (preferably the one which describes the physical object you're working on, like the sc_if, or the mPhySoftC).
There are only three places where phy functions are called from if_msk(). If you don't want to make e1000phy dependent on if_msk, then make those three entry points the places where a phy structure (mii_softc?) is looked up, and then pass that phy structure around when inside the e1000phy code. It's much more simple that way.
Our case is of course complicated by the fact that the BSD driver has infrastructure which connects the phy and the mac drivers so that each can exist without knowing about the other, and UEFI does not.
The msk_softc and e1000phy_softc lookup calls minimized to the UEFI driver interface functions and if_msk.c functions used by e1000phy.
The approach is similar to the FreeBSD one but using linked list to store the data, i do not see a big difference. If you will check the linked list node lookup, it's about the same as the device_get_softc() but with extra security checking.
No, device_get_softc() just returns a data pointer. It doesn't have to walk a list. It's O(1) instead of O(n).
Also, the pointers to driver data structures stored privately inside of the linked list and not exposed to the outside world through SNP. The performance impact should be insignificant.
It's the complexity of the code that's the issue. It's complex when it doesn't need to be.
I disagree. What you suggest has the same complexity. Also, what you suggest requires e1000phy_softc (for each port) and msk_softc pointers for each controller to be stored as part of the corresponding YUKON_DRIVER driver structure. As I explained above, I do not want to do it.
How does following a pointer to an object have the same code complexity as calling a function which walks a list to get a pointer to that object?
Is there a reason that would not work here? It seems like a much cleaner interface an fewer variables to keep track of and it wouldn't have to change function interfaces to have redundant parameters.
For example, have a look at FreeBSD's msk_phy_readreg() at [1]. It takes a msk_if_softc pointer and gets the msk_softc from it when it needs it. Your version of msk_phy_readreg() takes an mController parameter and then does a lookup of the msk_softc from a list[2] (every time you want to read a register!).
The same thing happens in FreeBSD driver, it returns the msk structure based on dev: struct msk_if_softc *sc_if; sc_if = device_get_softc(dev);
device_get_softc() just gets a pointer to a device's private data pointer: https://www.freebsd.org/cgi/man.cgi?query=device_get_softc&sektion=9
It's returning a pointer, not walking a list.
The UEFI driver does the same thing but adds extra security checking on the lookup: struct msk_softc *mSoftc; Status = msk_get_ctrl_data_msks (mController, &mSoftc);
These are not the same. One just returns a pointer that it has access to (FreeBSD), the other walks a list (UEFI).
The result is the same. The msk_get_ctrl_data_msks has extra steps and i already explained why.
Yes extra steps and extra code that is not needed if you lay out the structures the right way. Look back at my example of msk_phy_readreg():
In FreeBSD, it looks like this: static int msk_phy_readreg(struct msk_if_softc *sc_if, int phy, int reg) { struct msk_softc *sc; int i, val;
sc = sc_if->msk_softc; ... }
In your patch, it looks like this: INTN msk_phy_readreg ( INTN port, INTN reg, EFI_HANDLE mController ) { INTN i; INTN val; EFI_STATUS Status; struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc); ... }
It has nothing to do with device_get_softc(). It has to do with the structures being laid out properly so that you have the data you need, rather than having to walk a list to look it up. The BSD version says sc_if->msk_softc, and your version says msk_get_ctrl_data_msks (mController, &mSoftc) which walks a list.
Alan.
[1] It is a small n, but even so, why have O(n) of any size when it can be O(1)?
On 10/20/2016 09:13 AM, Alan Ott wrote:
On 10/19/2016 10:03 PM, Daniil Egranov wrote:
On 10/19/2016 04:12 PM, Alan Ott wrote:
On 10/19/2016 03:44 PM, Daniil Egranov wrote:
On 10/19/2016 11:37 AM, Ard Biesheuvel wrote:
On 19 October 2016 at 05:32, Alan Ott alan@softiron.co.uk wrote:
On 10/17/2016 05:45 PM, Daniil Egranov wrote: > The patch adds support for multi-controller configuration. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Daniil Egranov daniil.egranov@arm.com
I tested this, and it does work on my hardware here.
Does it fail to detect the hardware or there is no communication? Do you have a dual MAC controller? I tested it on Juno with three Marvell cards and have not seen any issues.
I said it works. :)
I misread it, sorry.
I guess my biggest criticism of this patch is, why change all the function prototypes to take mSoftc, mController, and mPciIo parameters? In the FreeBSD[0] driver, the msk_softc is simply held by the msk_if_softc (which is the main object for each network controller (interface)). The PCI I/O could be held there too. Each function that needs a msk_softc can simply get it from the msk_if_softc when it needs it.
The FreeBSD driver, for the most part, passes around msk_if_softc pointers, which makes sense, since from those pointers you can get to everything else.
The same thing happens in the patch. The pointer to msk_softc passed around the functions. The MSK_LINKED_DRV_BUF structure is equal to FreeBSD msk_if_softc. The UEFI type variables kept outside of the original msk driver structures and passed as extra parameters to the functions.
What? No. the msk_if_softc in the UEFI driver is the same as the msk_if_softc in the FreeBSD driver. It's the same structure, and named the same thing. I'm saying to put a pointer to the msk_softc in the msk_if_softc, rather than passing the msk_softc (often named mSoftc) into every function that needs it.
I am not talking about similarity between the UEFI msk_if_softc and FreeBSD msk_if_softc. I am talking about the MSK_LINKED_DRV_BUF structure containing a pointer to the msk_softc similar to the current FreeBSD msk_if_softc structure and used for the same purpose.
I'm saying:
- put a pointer to msk_softc into the msk_if_softc, like the
FreeBSD driver has. 2. Pass msk_if_softc into functions like msk_phy_readreg(). See: https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c#L409
- In functions like msk_phy_readreg():
3a. just use the pointer to the msk_softc from the msk_if_softc when you need it, just like the BSD driver.
I understand what you say. You want to pass it as part of the structure vs pass it as a function parameter. I doubt that the code complexity will be different.
What's different is, the FreeBSD driver passes in what's needed instead of passing in a token that is used to walk a list to find the thing that that is needed. One is a whole lot more clear an concise.
It's more interesting which way will be better performance wise.
One executes in constant time, the other walks a list. One is constant time, the other is O(n).[1]
3b. Don't look up the msk_softc using msk_get_ctrl_data_msks(), because it walks a list.
The msk_get_ctrl_data_msks() is not called all the time. It use to get a msk_softc pointer only when the driver interface functions is called and with e1000phy/if_msk interface calls. In all other cases, a pointier to the msk_softc will be already available.
Your argument here seems to be that it's ok that the code is more complex and slow than it needs to be because it doesn't get called very often. The problem isn't the number of microseconds wasted; the problem is that it's more code and code complexity where there doesn't need to be code complexity.
You have multiple variables being thrown around: msk_softc (mSoftc) msk_if_softc (often sc_if) EFI_HANDLE (mController) EFI_PCI_PROTOCOL (mPciIo)
Put them in structures that logically make sense, rather than passing them all around separately. That's all I'm saying.
I don't know what kind of issue you have with the linked list. Please explain. The UEFI linked list is very lite and as i explained before, it adds the data integrity checking with a little overhead. The driver is using the linked list in several places already.
I don't have a problem with linked lists or the UEFI linked list implementation, but like any data structure, why should you have a linked list when you don't have to have a linked list? Why have a list and look-ups and lots of variables passed around independently of each other when you can do things like: sc_if->msk_softc instead?
What about multiple controllers. Where do you get a pointer to the sc_if for the particular controller?
The first approach was to save a pointer to the msk_softc for each controller and hold it as part of the driver's binding structure.
I don't know what you mean by "driver's binding structure." Which one are you talking about?
YUKON_DRIVER structure
However, the complication comes from the e1000phy.c. First, it has it's own PHY structure which has to be saved related to the controller. Second, it has dependency on the if_msk.c. It's calling functions from the if_msk.c which require access to the msk_softc structure so e1000phy has to tell the if_msk.c functions which msk_softc structure to use without having visibility to this structure. The mController is a common device descriptor between e1000phy and if_msk which binds them to the same controller (= dev in FreeBSD).
The phy functions have an mii_softc, so add the appropriate things to that structure (such as the msk_if_softc) instead of passing them into every single function. You can connect them in the _attach() functions
Currently, there are only two functions with the mii_softc as a parameter. The other functions needing the e1000phy_softc have to be modified to have the mii_softc as a parameter. There is no difference between passing either e1000phy_softc, mii_softc, or mii_if_softc in this case.
In the BSD driver, there's infrastructure to match the PHY to the MAC. In our case, they could easily be matched up by the calls to PHY_READ(), PHY_WRITE(). if those macros were to take an mii_softc and if mii_softc were modified to hold a pointer to an msk_if_softc.
No, I do not want to mix e1000phy and if_msk structures. The patch adds the controller id to PHY_READ() and PHY_WRITE() which is used to get a data pointer to the associated msk_softc structure. It's doing the same thing as you explained above without mixing the structures.
If you want to keep e1000phy and if_msk separate, then when you attach the phy, pass in what you need (mController, PciIo, etc), and store them somewhere in the phy's data structures. When possible, you should be passing one object around (preferably the one which describes the physical object you're working on, like the sc_if, or the mPhySoftC).
The mController object describes which mPhySoftC object should be used and then mPhySoftC object passed around. The mController passed from the if_msc for each controller instance. I do not see any difference in what the current patch code is doing and what you are saying.
There are only three places where phy functions are called from if_msk(). If you don't want to make e1000phy dependent on if_msk, then make those three entry points the places where a phy structure (mii_softc?) is looked up, and then pass that phy structure around when inside the e1000phy code. It's much more simple that way.
Our case is of course complicated by the fact that the BSD driver has infrastructure which connects the phy and the mac drivers so that each can exist without knowing about the other, and UEFI does not.
It's already done by passing the mController object from the e1000phy to if_msk. The if_msk functions lookup for the msk_softc using this object. It's pretty simple.
The msk_softc and e1000phy_softc lookup calls minimized to the UEFI driver interface functions and if_msk.c functions used by e1000phy.
The approach is similar to the FreeBSD one but using linked list to store the data, i do not see a big difference. If you will check the linked list node lookup, it's about the same as the device_get_softc() but with extra security checking.
No, device_get_softc() just returns a data pointer. It doesn't have to walk a list. It's O(1) instead of O(n).
Also, the pointers to driver data structures stored privately inside of the linked list and not exposed to the outside world through SNP. The performance impact should be insignificant.
It's the complexity of the code that's the issue. It's complex when it doesn't need to be.
I disagree. What you suggest has the same complexity. Also, what you suggest requires e1000phy_softc (for each port) and msk_softc pointers for each controller to be stored as part of the corresponding YUKON_DRIVER driver structure. As I explained above, I do not want to do it.
How does following a pointer to an object have the same code complexity as calling a function which walks a list to get a pointer to that object?
I think we are talking about two different things. Here is an example:
Here is the patched code:
static VOID clear_pci_errors ( EFI_PCI_IO_PROTOCOL *mPciIo, struct msk_softc *mSoftc ) { EFI_STATUS Status; UINT16 val;
....
}
Here is what you suggest:
static VOID clear_pci_errors ( struct msk_if_softc *sc_if ) { EFI_STATUS Status; UINT16 val; EFI_PCI_IO_PROTOCOL *mPciIo; struct msk_softc *mSoftc;
mPciIo = sc_if->mPciIo; mSoftc = sc_if->mSoftc; ....
}
There is no walk a list in most of the functions. Why do you think the complexity is different? Your suggestion will not work in places where msk_if_softc is not allocated or accessible:
// Reset the adapter mskc_reset (mPciIo, mSoftc);
mskc_setup_rambuffer (mSoftc);
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct *msk_if_softc*), (VOID**) &*ScIf*);
Now we are talking about a multi controller case and not a single instance case. The walk a list happens only in 5 interface functions used by SNP protocol functions and e1000phy/if_msk interface functions which do not have common objects. Once you have multiple controllers, the driver has to build the binding: EFI_HANDLE Controller(n) <-> msk_softc (n), e1000phy_softc(n) (x2 with two MACs) and store it. The purpose of the linked list is to keep these bindings. It has to be done one way or another, will it be a list or something else. Once the SNP function called, it passes the UEFI controller handle to the driver. The driver uses the corresponding msk_softc and e1000phy_softc stored in the linked list, it is simple like that. To be honest, i do not see any complexity in that.
Is there a reason that would not work here? It seems like a much cleaner interface an fewer variables to keep track of and it wouldn't have to change function interfaces to have redundant parameters.
For example, have a look at FreeBSD's msk_phy_readreg() at [1]. It takes a msk_if_softc pointer and gets the msk_softc from it when it needs it. Your version of msk_phy_readreg() takes an mController parameter and then does a lookup of the msk_softc from a list[2] (every time you want to read a register!).
The same thing happens in FreeBSD driver, it returns the msk structure based on dev: struct msk_if_softc *sc_if; sc_if = device_get_softc(dev);
device_get_softc() just gets a pointer to a device's private data pointer: https://www.freebsd.org/cgi/man.cgi?query=device_get_softc&sektion=9
It's returning a pointer, not walking a list.
The UEFI driver does the same thing but adds extra security checking on the lookup: struct msk_softc *mSoftc; Status = msk_get_ctrl_data_msks (mController, &mSoftc);
These are not the same. One just returns a pointer that it has access to (FreeBSD), the other walks a list (UEFI).
The result is the same. The msk_get_ctrl_data_msks has extra steps and i already explained why.
Yes extra steps and extra code that is not needed if you lay out the structures the right way. Look back at my example of msk_phy_readreg():
The lookup happens only in several cases when the structures are not directly accessible even if structures have a "right way" lay out. You still compare it to the new FreeBSD driver. This is the original UEFI driver msk_phy_readreg() function which is called from the e1000phy. The e1000phy does not know anything about msk_if_softc or msk_softc but as far as the mSoftc was global, it worked but now it has to lookup for mSoftc as you have in the patched version:
msk_phy_readreg ( INTN port, INTN reg ) { INTN i; INTN val;
GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
... }
In FreeBSD, it looks like this: static int msk_phy_readreg(struct msk_if_softc *sc_if, int phy, int reg) { struct msk_softc *sc; int i, val;
sc = sc_if->msk_softc; ... }
In your patch, it looks like this: INTN msk_phy_readreg ( INTN port, INTN reg, EFI_HANDLE mController ) { INTN i; INTN val; EFI_STATUS Status; struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc); ... }
It has nothing to do with device_get_softc(). It has to do with the structures being laid out properly so that you have the data you need, rather than having to walk a list to look it up. The BSD version says sc_if->msk_softc, and your version says msk_get_ctrl_data_msks (mController, &mSoftc) which walks a list.
Alan.
[1] It is a small n, but even so, why have O(n) of any size when it can be O(1)?
Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi
Thanks, Daniil
On 10/20/2016 07:23 PM, Daniil Egranov wrote:
On 10/20/2016 09:13 AM, Alan Ott wrote:
On 10/19/2016 10:03 PM, Daniil Egranov wrote:
On 10/19/2016 04:12 PM, Alan Ott wrote:
On 10/19/2016 03:44 PM, Daniil Egranov wrote:
On 10/19/2016 11:37 AM, Ard Biesheuvel wrote:
On 19 October 2016 at 05:32, Alan Ott alan@softiron.co.uk wrote: > On 10/17/2016 05:45 PM, Daniil Egranov wrote: >> The patch adds support for multi-controller configuration. >> >> Contributed-under: TianoCore Contribution Agreement 1.0 >> Signed-off-by: Daniil Egranov daniil.egranov@arm.com > > I tested this, and it does work on my hardware here.
Does it fail to detect the hardware or there is no communication? Do you have a dual MAC controller? I tested it on Juno with three Marvell cards and have not seen any issues.
I said it works. :)
I misread it, sorry.
> > I guess my biggest criticism of this patch is, why change all > the function > prototypes to take mSoftc, mController, and mPciIo parameters? > In the > FreeBSD[0] driver, the msk_softc is simply held by the > msk_if_softc (which > is the main object for each network controller (interface)). The > PCI I/O > could be held there too. Each function that needs a msk_softc > can simply get > it from the msk_if_softc when it needs it. > > The FreeBSD driver, for the most part, passes around > msk_if_softc pointers, > which makes sense, since from those pointers you can get to > everything else.
The same thing happens in the patch. The pointer to msk_softc passed around the functions. The MSK_LINKED_DRV_BUF structure is equal to FreeBSD msk_if_softc. The UEFI type variables kept outside of the original msk driver structures and passed as extra parameters to the functions.
What? No. the msk_if_softc in the UEFI driver is the same as the msk_if_softc in the FreeBSD driver. It's the same structure, and named the same thing. I'm saying to put a pointer to the msk_softc in the msk_if_softc, rather than passing the msk_softc (often named mSoftc) into every function that needs it.
I am not talking about similarity between the UEFI msk_if_softc and FreeBSD msk_if_softc. I am talking about the MSK_LINKED_DRV_BUF structure containing a pointer to the msk_softc similar to the current FreeBSD msk_if_softc structure and used for the same purpose.
I'm saying:
- put a pointer to msk_softc into the msk_if_softc, like the
FreeBSD driver has. 2. Pass msk_if_softc into functions like msk_phy_readreg(). See: https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c#L409
- In functions like msk_phy_readreg():
3a. just use the pointer to the msk_softc from the msk_if_softc when you need it, just like the BSD driver.
I understand what you say. You want to pass it as part of the structure vs pass it as a function parameter. I doubt that the code complexity will be different.
What's different is, the FreeBSD driver passes in what's needed instead of passing in a token that is used to walk a list to find the thing that that is needed. One is a whole lot more clear an concise.
It's more interesting which way will be better performance wise.
One executes in constant time, the other walks a list. One is constant time, the other is O(n).[1]
3b. Don't look up the msk_softc using msk_get_ctrl_data_msks(), because it walks a list.
The msk_get_ctrl_data_msks() is not called all the time. It use to get a msk_softc pointer only when the driver interface functions is called and with e1000phy/if_msk interface calls. In all other cases, a pointier to the msk_softc will be already available.
Your argument here seems to be that it's ok that the code is more complex and slow than it needs to be because it doesn't get called very often. The problem isn't the number of microseconds wasted; the problem is that it's more code and code complexity where there doesn't need to be code complexity.
You have multiple variables being thrown around: msk_softc (mSoftc) msk_if_softc (often sc_if) EFI_HANDLE (mController) EFI_PCI_PROTOCOL (mPciIo)
Put them in structures that logically make sense, rather than passing them all around separately. That's all I'm saying.
I don't know what kind of issue you have with the linked list. Please explain. The UEFI linked list is very lite and as i explained before, it adds the data integrity checking with a little overhead. The driver is using the linked list in several places already.
I don't have a problem with linked lists or the UEFI linked list implementation, but like any data structure, why should you have a linked list when you don't have to have a linked list? Why have a list and look-ups and lots of variables passed around independently of each other when you can do things like: sc_if->msk_softc instead?
What about multiple controllers. Where do you get a pointer to the sc_if for the particular controller?
In the BSD, there's an sc_if (msk_if_softc) for each logical interface (eth0:0 eth0:1, etc), and an sc (msk_softc) for each physical interface (eth0).
In our case, it's 1:1, since we don't have logical interfaces, so it's a 1:1 mapping. In the BSD they're linked together. sc_if has a pointer to the sc. We could (and should) easily have the same. It makes some of our problems easier.
Prior to your patch, in the UEFI, we had an sc_if which was dynamically allocated in mskc_attach() and an sc which was static. That didn't make any sense.
Look at how they are assembled in the BSD in msk_attach(): https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c#L1589
The first approach was to save a pointer to the msk_softc for each controller and hold it as part of the driver's binding structure.
I don't know what you mean by "driver's binding structure." Which one are you talking about?
YUKON_DRIVER structure
However, the complication comes from the e1000phy.c. First, it has it's own PHY structure which has to be saved related to the controller. Second, it has dependency on the if_msk.c. It's calling functions from the if_msk.c which require access to the msk_softc structure so e1000phy has to tell the if_msk.c functions which msk_softc structure to use without having visibility to this structure. The mController is a common device descriptor between e1000phy and if_msk which binds them to the same controller (= dev in FreeBSD).
The phy functions have an mii_softc, so add the appropriate things to that structure (such as the msk_if_softc) instead of passing them into every single function. You can connect them in the _attach() functions
Currently, there are only two functions with the mii_softc as a parameter. The other functions needing the e1000phy_softc have to be modified to have the mii_softc as a parameter. There is no difference between passing either e1000phy_softc, mii_softc, or mii_if_softc in this case.
Yes, that makes sense.
In the BSD driver, there's infrastructure to match the PHY to the MAC. In our case, they could easily be matched up by the calls to PHY_READ(), PHY_WRITE(). if those macros were to take an mii_softc and if mii_softc were modified to hold a pointer to an msk_if_softc.
No, I do not want to mix e1000phy and if_msk structures. The patch adds the controller id to PHY_READ() and PHY_WRITE() which is used to get a data pointer to the associated msk_softc structure. It's doing the same thing as you explained above without mixing the structures.
If you want to keep e1000phy and if_msk separate, then when you attach the phy, pass in what you need (mController, PciIo, etc), and store them somewhere in the phy's data structures. When possible, you should be passing one object around (preferably the one which describes the physical object you're working on, like the sc_if, or the mPhySoftC).
The mController object describes which mPhySoftC object should be used and then mPhySoftC object passed around. The mController passed from the if_msc for each controller instance. I do not see any difference in what the current patch code is doing and what you are saying.
There are only three places where phy functions are called from if_msk(). If you don't want to make e1000phy dependent on if_msk, then make those three entry points the places where a phy structure (mii_softc?) is looked up, and then pass that phy structure around when inside the e1000phy code. It's much more simple that way.
Our case is of course complicated by the fact that the BSD driver has infrastructure which connects the phy and the mac drivers so that each can exist without knowing about the other, and UEFI does not.
It's already done by passing the mController object from the e1000phy to if_msk. The if_msk functions lookup for the msk_softc using this object. It's pretty simple.
This is addressed in a comment below.
The msk_softc and e1000phy_softc lookup calls minimized to the UEFI driver interface functions and if_msk.c functions used by e1000phy.
The approach is similar to the FreeBSD one but using linked list to store the data, i do not see a big difference. If you will check the linked list node lookup, it's about the same as the device_get_softc() but with extra security checking.
No, device_get_softc() just returns a data pointer. It doesn't have to walk a list. It's O(1) instead of O(n).
Also, the pointers to driver data structures stored privately inside of the linked list and not exposed to the outside world through SNP. The performance impact should be insignificant.
It's the complexity of the code that's the issue. It's complex when it doesn't need to be.
I disagree. What you suggest has the same complexity. Also, what you suggest requires e1000phy_softc (for each port) and msk_softc pointers for each controller to be stored as part of the corresponding YUKON_DRIVER driver structure. As I explained above, I do not want to do it.
How does following a pointer to an object have the same code complexity as calling a function which walks a list to get a pointer to that object?
I think we are talking about two different things. Here is an example:
Here is the patched code:
static VOID clear_pci_errors ( EFI_PCI_IO_PROTOCOL *mPciIo, struct msk_softc *mSoftc ) { EFI_STATUS Status; UINT16 val;
....
}
Here is what you suggest:
static VOID clear_pci_errors ( struct msk_if_softc *sc_if ) { EFI_STATUS Status; UINT16 val; EFI_PCI_IO_PROTOCOL *mPciIo; struct msk_softc *mSoftc;
mPciIo = sc_if->mPciIo; mSoftc = sc_if->mSoftc; ....
}
Yes, that's exactly what I'm suggesting. The difference is that the interface is cleaner. You don't pass in an sc_if _and_ a PciIo, you just pass in an sc_if which _contains_ a PciIo.
When you say we are talking about different things, yes, there are multiple issues that I'm discussing. One is like you showed above, where it can simply be a matter of having the objects laid out a little differently to make the interfaces cleaner (and the patch smaller). Then there are other, different places where lookups are done instead. It's a large patch and you're doing a lot of different things in it, which is why we have some miscommunication.
There is no walk a list in most of the functions. Why do you think the complexity is different?
The complexity is different in the places where the list is walked when it doesn't have to be. I have showed you an example of this above. Not all the cases are the same in your code. Like I said there are multiple issues being discussed.
Your suggestion will not work in places where msk_if_softc is not allocated or accessible:
// Reset the adapter mskc_reset (mPciIo, mSoftc);
mskc_setup_rambuffer (mSoftc);
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct *msk_if_softc*), (VOID**) &*ScIf*);
I agree, but have a look at how the BSD driver works here.
mSoftC and mPciIo should go with the msk_softc (sc) rather than the msk_if_softc, and by that point you _do_ have an msk_softc.
In our case since interface (eth0:0, eth0:1, etc) and hardware (eth0) are 1:1, mskc_attach() and msk_attach() have kind of become mixed up together :/ .
Now we are talking about a multi controller case and not a single instance case. The walk a list happens only in 5 interface functions used by SNP protocol functions and e1000phy/if_msk interface functions which do not have common objects. Once you have multiple controllers, the driver has to build the binding: EFI_HANDLE Controller(n) <-> msk_softc (n), e1000phy_softc(n) (x2 with two MACs) and store it. The purpose of the linked list is to keep these bindings. It has to be done one way or another, will it be a list or something else. Once the SNP function called, it passes the UEFI controller handle to the driver. The driver uses the corresponding msk_softc and e1000phy_softc stored in the linked list, it is simple like that. To be honest, i do not see any complexity in that.
There are places where it's done where it's done where it doesn't have to be, like the example I gave. There are others. That's what I'm saying.
I think this can be done without a mapping.
What if the sc_if was created in mskc_attach() (where it is already) and returned and stored in the YUKON_DRIVER. That way all the calls to SnpTransmit(), SnpReceive(), etc., already have the sc_if, and it can be passed directly into the msk_* functions? I think that would fix almost all the issues.
> Is there a reason that would not work here? It seems like a much > cleaner > interface an fewer variables to keep track of and it wouldn't > have to change > function interfaces to have redundant parameters. > > For example, have a look at FreeBSD's msk_phy_readreg() at [1]. > It takes a > msk_if_softc pointer and gets the msk_softc from it when it > needs it. Your > version of msk_phy_readreg() takes an mController parameter and > then does a > lookup of the msk_softc from a list[2] (every time you want to > read a > register!).
The same thing happens in FreeBSD driver, it returns the msk structure based on dev: struct msk_if_softc *sc_if; sc_if = device_get_softc(dev);
device_get_softc() just gets a pointer to a device's private data pointer: https://www.freebsd.org/cgi/man.cgi?query=device_get_softc&sektion=9
It's returning a pointer, not walking a list.
The UEFI driver does the same thing but adds extra security checking on the lookup: struct msk_softc *mSoftc; Status = msk_get_ctrl_data_msks (mController, &mSoftc);
These are not the same. One just returns a pointer that it has access to (FreeBSD), the other walks a list (UEFI).
The result is the same. The msk_get_ctrl_data_msks has extra steps and i already explained why.
Yes extra steps and extra code that is not needed if you lay out the structures the right way. Look back at my example of msk_phy_readreg():
The lookup happens only in several cases when the structures are not directly accessible even if structures have a "right way" lay out. You still compare it to the new FreeBSD driver. This is the original UEFI driver msk_phy_readreg() function which is called from the e1000phy. The e1000phy does not know anything about msk_if_softc or msk_softc but as far as the mSoftc was global, it worked but now it has to lookup for mSoftc as you have in the patched version:
msk_phy_readreg ( INTN port, INTN reg ) { INTN i; INTN val;
GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
... }
The BSD driver's msk_phy_readreg() takes an sc_if. Could the phy code hold an opaque pointer to an sc_if, (or a void pointer) that the if_msk code passes to it (and then the phy code passes back) as a way of keeping the if_msk and the phy code loosely coupled?
In FreeBSD, it looks like this: static int msk_phy_readreg(struct msk_if_softc *sc_if, int phy, int reg) { struct msk_softc *sc; int i, val;
sc = sc_if->msk_softc; ... }
In your patch, it looks like this: INTN msk_phy_readreg ( INTN port, INTN reg, EFI_HANDLE mController ) { INTN i; INTN val; EFI_STATUS Status; struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc); ... }
It has nothing to do with device_get_softc(). It has to do with the structures being laid out properly so that you have the data you need, rather than having to walk a list to look it up. The BSD version says sc_if->msk_softc, and your version says msk_get_ctrl_data_msks (mController, &mSoftc) which walks a list.
Alan.
[1] It is a small n, but even so, why have O(n) of any size when it can be O(1)?
Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi
Thanks, Daniil
On 10/20/2016 10:14 PM, Alan Ott wrote:
On 10/20/2016 07:23 PM, Daniil Egranov wrote:
On 10/20/2016 09:13 AM, Alan Ott wrote:
On 10/19/2016 10:03 PM, Daniil Egranov wrote:
On 10/19/2016 04:12 PM, Alan Ott wrote:
On 10/19/2016 03:44 PM, Daniil Egranov wrote:
On 10/19/2016 11:37 AM, Ard Biesheuvel wrote: > On 19 October 2016 at 05:32, Alan Ott alan@softiron.co.uk wrote: >> On 10/17/2016 05:45 PM, Daniil Egranov wrote: >>> The patch adds support for multi-controller configuration. >>> >>> Contributed-under: TianoCore Contribution Agreement 1.0 >>> Signed-off-by: Daniil Egranov daniil.egranov@arm.com >> >> I tested this, and it does work on my hardware here.
Does it fail to detect the hardware or there is no communication? Do you have a dual MAC controller? I tested it on Juno with three Marvell cards and have not seen any issues.
I said it works. :)
I misread it, sorry.
>> >> I guess my biggest criticism of this patch is, why change all >> the function >> prototypes to take mSoftc, mController, and mPciIo parameters? >> In the >> FreeBSD[0] driver, the msk_softc is simply held by the >> msk_if_softc (which >> is the main object for each network controller (interface)). >> The PCI I/O >> could be held there too. Each function that needs a msk_softc >> can simply get >> it from the msk_if_softc when it needs it. >> >> The FreeBSD driver, for the most part, passes around >> msk_if_softc pointers, >> which makes sense, since from those pointers you can get to >> everything else.
The same thing happens in the patch. The pointer to msk_softc passed around the functions. The MSK_LINKED_DRV_BUF structure is equal to FreeBSD msk_if_softc. The UEFI type variables kept outside of the original msk driver structures and passed as extra parameters to the functions.
What? No. the msk_if_softc in the UEFI driver is the same as the msk_if_softc in the FreeBSD driver. It's the same structure, and named the same thing. I'm saying to put a pointer to the msk_softc in the msk_if_softc, rather than passing the msk_softc (often named mSoftc) into every function that needs it.
I am not talking about similarity between the UEFI msk_if_softc and FreeBSD msk_if_softc. I am talking about the MSK_LINKED_DRV_BUF structure containing a pointer to the msk_softc similar to the current FreeBSD msk_if_softc structure and used for the same purpose.
I'm saying:
- put a pointer to msk_softc into the msk_if_softc, like the
FreeBSD driver has. 2. Pass msk_if_softc into functions like msk_phy_readreg(). See: https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c#L409
- In functions like msk_phy_readreg():
3a. just use the pointer to the msk_softc from the msk_if_softc when you need it, just like the BSD driver.
I understand what you say. You want to pass it as part of the structure vs pass it as a function parameter. I doubt that the code complexity will be different.
What's different is, the FreeBSD driver passes in what's needed instead of passing in a token that is used to walk a list to find the thing that that is needed. One is a whole lot more clear an concise.
It's more interesting which way will be better performance wise.
One executes in constant time, the other walks a list. One is constant time, the other is O(n).[1]
3b. Don't look up the msk_softc using msk_get_ctrl_data_msks(), because it walks a list.
The msk_get_ctrl_data_msks() is not called all the time. It use to get a msk_softc pointer only when the driver interface functions is called and with e1000phy/if_msk interface calls. In all other cases, a pointier to the msk_softc will be already available.
Your argument here seems to be that it's ok that the code is more complex and slow than it needs to be because it doesn't get called very often. The problem isn't the number of microseconds wasted; the problem is that it's more code and code complexity where there doesn't need to be code complexity.
You have multiple variables being thrown around: msk_softc (mSoftc) msk_if_softc (often sc_if) EFI_HANDLE (mController) EFI_PCI_PROTOCOL (mPciIo)
Put them in structures that logically make sense, rather than passing them all around separately. That's all I'm saying.
I don't know what kind of issue you have with the linked list. Please explain. The UEFI linked list is very lite and as i explained before, it adds the data integrity checking with a little overhead. The driver is using the linked list in several places already.
I don't have a problem with linked lists or the UEFI linked list implementation, but like any data structure, why should you have a linked list when you don't have to have a linked list? Why have a list and look-ups and lots of variables passed around independently of each other when you can do things like: sc_if->msk_softc instead?
What about multiple controllers. Where do you get a pointer to the sc_if for the particular controller?
In the BSD, there's an sc_if (msk_if_softc) for each logical interface (eth0:0 eth0:1, etc), and an sc (msk_softc) for each physical interface (eth0).
In our case, it's 1:1, since we don't have logical interfaces, so it's a 1:1 mapping. In the BSD they're linked together. sc_if has a pointer to the sc. We could (and should) easily have the same. It makes some of our problems easier.
We still have a case for a dual MAC controller (which i believe is Marvell Yukon XL). It's defined as array of pointers in the msk_softc so we potentially have 1:2 mapping with the common msk_softc structure for a controller. The msk_softc (or msk_if_softc) has to be stored for each controller and passed to the driver like FreeBSD does with device_t structure. It can be done similar way but I'll talk about it below. I do not have Marvell controller with two ports so only first MAC will be used for now but once I'll find such a controller, it will be enabled.
Prior to your patch, in the UEFI, we had an sc_if which was dynamically allocated in mskc_attach() and an sc which was static. That didn't make any sense.
Look at how they are assembled in the BSD in msk_attach(): https://github.com/freebsd/freebsd/blob/master/sys/dev/msk/if_msk.c#L1589
I went back to old versions of driver and both msk_softc and msk_if_softc were dynamically allocated with AllocatePool() in all versions of this driver. The layout of this driver has been done long time ago and based on pretty old version of FreeBSD driver. I believe it's been done specifically for Juno platform without intention to be used with other Marvell controllers. The driver can be reworked to make it more similar to the current FreeBSD one but it's another task.
The first approach was to save a pointer to the msk_softc for each controller and hold it as part of the driver's binding structure.
I don't know what you mean by "driver's binding structure." Which one are you talking about?
YUKON_DRIVER structure
However, the complication comes from the e1000phy.c. First, it has it's own PHY structure which has to be saved related to the controller. Second, it has dependency on the if_msk.c. It's calling functions from the if_msk.c which require access to the msk_softc structure so e1000phy has to tell the if_msk.c functions which msk_softc structure to use without having visibility to this structure. The mController is a common device descriptor between e1000phy and if_msk which binds them to the same controller (= dev in FreeBSD).
The phy functions have an mii_softc, so add the appropriate things to that structure (such as the msk_if_softc) instead of passing them into every single function. You can connect them in the _attach() functions
Currently, there are only two functions with the mii_softc as a parameter. The other functions needing the e1000phy_softc have to be modified to have the mii_softc as a parameter. There is no difference between passing either e1000phy_softc, mii_softc, or mii_if_softc in this case.
Yes, that makes sense.
In the BSD driver, there's infrastructure to match the PHY to the MAC. In our case, they could easily be matched up by the calls to PHY_READ(), PHY_WRITE(). if those macros were to take an mii_softc and if mii_softc were modified to hold a pointer to an msk_if_softc.
No, I do not want to mix e1000phy and if_msk structures. The patch adds the controller id to PHY_READ() and PHY_WRITE() which is used to get a data pointer to the associated msk_softc structure. It's doing the same thing as you explained above without mixing the structures.
If you want to keep e1000phy and if_msk separate, then when you attach the phy, pass in what you need (mController, PciIo, etc), and store them somewhere in the phy's data structures. When possible, you should be passing one object around (preferably the one which describes the physical object you're working on, like the sc_if, or the mPhySoftC).
The mController object describes which mPhySoftC object should be used and then mPhySoftC object passed around. The mController passed from the if_msc for each controller instance. I do not see any difference in what the current patch code is doing and what you are saying.
There are only three places where phy functions are called from if_msk(). If you don't want to make e1000phy dependent on if_msk, then make those three entry points the places where a phy structure (mii_softc?) is looked up, and then pass that phy structure around when inside the e1000phy code. It's much more simple that way.
Our case is of course complicated by the fact that the BSD driver has infrastructure which connects the phy and the mac drivers so that each can exist without knowing about the other, and UEFI does not.
It's already done by passing the mController object from the e1000phy to if_msk. The if_msk functions lookup for the msk_softc using this object. It's pretty simple.
This is addressed in a comment below.
The msk_softc and e1000phy_softc lookup calls minimized to the UEFI driver interface functions and if_msk.c functions used by e1000phy.
The approach is similar to the FreeBSD one but using linked list to store the data, i do not see a big difference. If you will check the linked list node lookup, it's about the same as the device_get_softc() but with extra security checking.
No, device_get_softc() just returns a data pointer. It doesn't have to walk a list. It's O(1) instead of O(n).
Also, the pointers to driver data structures stored privately inside of the linked list and not exposed to the outside world through SNP. The performance impact should be insignificant.
It's the complexity of the code that's the issue. It's complex when it doesn't need to be.
I disagree. What you suggest has the same complexity. Also, what you suggest requires e1000phy_softc (for each port) and msk_softc pointers for each controller to be stored as part of the corresponding YUKON_DRIVER driver structure. As I explained above, I do not want to do it.
How does following a pointer to an object have the same code complexity as calling a function which walks a list to get a pointer to that object?
I think we are talking about two different things. Here is an example:
Here is the patched code:
static VOID clear_pci_errors ( EFI_PCI_IO_PROTOCOL *mPciIo, struct msk_softc *mSoftc ) { EFI_STATUS Status; UINT16 val;
....
}
Here is what you suggest:
static VOID clear_pci_errors ( struct msk_if_softc *sc_if ) { EFI_STATUS Status; UINT16 val; EFI_PCI_IO_PROTOCOL *mPciIo; struct msk_softc *mSoftc;
mPciIo = sc_if->mPciIo; mSoftc = sc_if->mSoftc; ....
}
Yes, that's exactly what I'm suggesting. The difference is that the interface is cleaner. You don't pass in an sc_if _and_ a PciIo, you just pass in an sc_if which _contains_ a PciIo.
When you say we are talking about different things, yes, there are multiple issues that I'm discussing. One is like you showed above, where it can simply be a matter of having the objects laid out a little differently to make the interfaces cleaner (and the patch smaller). Then there are other, different places where lookups are done instead. It's a large patch and you're doing a lot of different things in it, which is why we have some miscommunication.
I do not mind putting it inside of the structure. It's a matter of preference of defining an interface so which way is cleaner is subjective. In this case it make sense to follow the FreeBSD style, I'll rework it. However, I am not sure about the patch size with this changes. The parameters for several functions have to be changed, extracting pointers from the structure will add more code to each function. Also, mPort variable cannot be put inside of the structure as it points to the msk_if_softc defined in the msk_softc. The mPort comes as a driver external parameter and points to controller's msk_if_softc structure so it has to be kept as a function parameter.
There is no walk a list in most of the functions. Why do you think the complexity is different?
The complexity is different in the places where the list is walked when it doesn't have to be. I have showed you an example of this above. Not all the cases are the same in your code. Like I said there are multiple issues being discussed.
Your suggestion will not work in places where msk_if_softc is not allocated or accessible:
// Reset the adapter mskc_reset (mPciIo, mSoftc);
mskc_setup_rambuffer (mSoftc);
Status = gBS->AllocatePool (EfiBootServicesData, sizeof (struct *msk_if_softc*), (VOID**) &*ScIf*);
I agree, but have a look at how the BSD driver works here.
mSoftC and mPciIo should go with the msk_softc (sc) rather than the msk_if_softc, and by that point you _do_ have an msk_softc.
In our case since interface (eth0:0, eth0:1, etc) and hardware (eth0) are 1:1, mskc_attach() and msk_attach() have kind of become mixed up together :/ .
Now we are talking about a multi controller case and not a single instance case. The walk a list happens only in 5 interface functions used by SNP protocol functions and e1000phy/if_msk interface functions which do not have common objects. Once you have multiple controllers, the driver has to build the binding: EFI_HANDLE Controller(n) <-> msk_softc (n), e1000phy_softc(n) (x2 with two MACs) and store it. The purpose of the linked list is to keep these bindings. It has to be done one way or another, will it be a list or something else. Once the SNP function called, it passes the UEFI controller handle to the driver. The driver uses the corresponding msk_softc and e1000phy_softc stored in the linked list, it is simple like that. To be honest, i do not see any complexity in that.
There are places where it's done where it's done where it doesn't have to be, like the example I gave. There are others. That's what I'm saying.
I think this can be done without a mapping.
What if the sc_if was created in mskc_attach() (where it is already) and returned and stored in the YUKON_DRIVER. That way all the calls to SnpTransmit(), SnpReceive(), etc., already have the sc_if, and it can be passed directly into the msk_* functions? I think that would fix almost all the issues.
I agree. That is a best way for keeping driver's data associated with a controller. Storing the driver's data in YUKON_DRIVER I mention when i was talking about driver's binding structure earlier but there are couple concerns about it : 1. The driver's internal data can be access using the SNP pointer with the YUKON_DEV_FROM_THIS_SNP similar macro. Registering this data with an external protocol brings some security questions. That's a reason why i do not like to include it into the YUKON_DRIVER structure and want keeping it local to the driver in linked list or other form. 2. The e1000phy to if_msk interface without a shared object between them . That brings a complication to multiple controllers case. Fixing it may require significant changes in the driver structure.
To solve these two problems, the local linked list with the controller object was a simplest way with the current structure of the driver.
I will send another patch with the driver structures changes as you suggested, with name correction suggested by Ard, and with keeping linked list storage for the SNP interface function for now.
>> Is there a reason that would not work here? It seems like a >> much cleaner >> interface an fewer variables to keep track of and it wouldn't >> have to change >> function interfaces to have redundant parameters. >> >> For example, have a look at FreeBSD's msk_phy_readreg() at [1]. >> It takes a >> msk_if_softc pointer and gets the msk_softc from it when it >> needs it. Your >> version of msk_phy_readreg() takes an mController parameter and >> then does a >> lookup of the msk_softc from a list[2] (every time you want to >> read a >> register!).
The same thing happens in FreeBSD driver, it returns the msk structure based on dev: struct msk_if_softc *sc_if; sc_if = device_get_softc(dev);
device_get_softc() just gets a pointer to a device's private data pointer: https://www.freebsd.org/cgi/man.cgi?query=device_get_softc&sektion=9
It's returning a pointer, not walking a list.
The UEFI driver does the same thing but adds extra security checking on the lookup: struct msk_softc *mSoftc; Status = msk_get_ctrl_data_msks (mController, &mSoftc);
These are not the same. One just returns a pointer that it has access to (FreeBSD), the other walks a list (UEFI).
The result is the same. The msk_get_ctrl_data_msks has extra steps and i already explained why.
Yes extra steps and extra code that is not needed if you lay out the structures the right way. Look back at my example of msk_phy_readreg():
The lookup happens only in several cases when the structures are not directly accessible even if structures have a "right way" lay out. You still compare it to the new FreeBSD driver. This is the original UEFI driver msk_phy_readreg() function which is called from the e1000phy. The e1000phy does not know anything about msk_if_softc or msk_softc but as far as the mSoftc was global, it worked but now it has to lookup for mSoftc as you have in the patched version:
msk_phy_readreg ( INTN port, INTN reg ) { INTN i; INTN val;
GMAC_WRITE_2 (mSoftc, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
... }
The BSD driver's msk_phy_readreg() takes an sc_if. Could the phy code hold an opaque pointer to an sc_if, (or a void pointer) that the if_msk code passes to it (and then the phy code passes back) as a way of keeping the if_msk and the phy code loosely coupled?
Yes, that's an option. I am trying to avoid opaque pointers where its possible allowing a complier correctly track any type specific issues. I'll review this part of the code. It may remove msk_softc structure lookup here and do it only in the SNP interface functions.
In FreeBSD, it looks like this: static int msk_phy_readreg(struct msk_if_softc *sc_if, int phy, int reg) { struct msk_softc *sc; int i, val;
sc = sc_if->msk_softc; ... }
In your patch, it looks like this: INTN msk_phy_readreg ( INTN port, INTN reg, EFI_HANDLE mController ) { INTN i; INTN val; EFI_STATUS Status; struct msk_softc *mSoftc;
Status = msk_get_ctrl_data_msks (mController, &mSoftc); ... }
It has nothing to do with device_get_softc(). It has to do with the structures being laid out properly so that you have the data you need, rather than having to walk a list to look it up. The BSD version says sc_if->msk_softc, and your version says msk_get_ctrl_data_msks (mController, &mSoftc) which walks a list.
Alan.
[1] It is a small n, but even so, why have O(n) of any size when it can be O(1)?
Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi
Thanks, Daniil
Linaro-uefi mailing list Linaro-uefi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-uefi