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_ */