VirtualBox

Changeset 93675 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 10, 2022 9:45:11 AM (3 years ago)
Author:
vboxsync
Message:

Dev3C501/DevDP8390: Fixed saved state loading; force link restore after about 6 seconds because old drivers may not expect cable disconnects at all and will never notice.

Location:
trunk/src/VBox/Devices/Network
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/Dev3C501.cpp

    r93668 r93675  
    184184/** Maximum number of times we report a link down to the guest (failure to send frame) */
    185185#define ELNK_MAX_LINKDOWN_REPORTED      3
     186
     187/** Maximum number of times we postpone restoring a link that is temporarily down. */
     188#define ELNK_MAX_LINKRST_POSTPONED      3
    186189
    187190/** Maximum frame size we handle */
     
    392395    /** Number of times we've reported the link down. */
    393396    uint16_t                            cLinkDownReported;
     397    /** Number of times we've postponed the link restore. */
     398    uint16_t                            cLinkRestorePostponed;
    394399
    395400    /** The "hardware" MAC address. */
     
    16651670 * should be considered lost.
    16661671 */
    1667 static DECLCALLBACK(void) elnkTimerRestore(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, void *pvUser)
     1672static DECLCALLBACK(void) elnkR3TimerRestore(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, void *pvUser)
    16681673{
    16691674    RT_NOREF(pvUser);
     
    16731678
    16741679    rc = VERR_GENERAL_FAILURE;
    1675     if (pThis->cLinkDownReported <= ELNK_MAX_LINKDOWN_REPORTED)
     1680
     1681    /* The EhterLink cards have no concept of a link state, and cables were assumed to be
     1682     * permanently attached (AUI or BNC). We can simulate a disconnected cable by reporting
     1683     * collisions on transmit, but a guest that waits to receive something will never know.
     1684     * For that reason, the link is temporarily down, we will only postpone restoring it
     1685     * a couple of times, and then reconnect regardless of whether the guest noticed
     1686     * anything or not.
     1687     */
     1688    if (   (pThis->cLinkDownReported <= ELNK_MAX_LINKDOWN_REPORTED)
     1689        && (pThis->cLinkRestorePostponed <= ELNK_MAX_LINKRST_POSTPONED))
    16761690        rc = PDMDevHlpTimerSetMillies(pDevIns, hTimer, 1500);
    16771691    if (RT_FAILURE(rc))
     
    16821696            LogRel(("3C501#%d: The link is back up again after the restore.\n",
    16831697                    pThis->iInstance));
    1684             LogFunc(("#%d: Clearing ERR and CERR after load. cLinkDownReported=%d\n",
     1698            LogFunc(("#%d: cLinkDownReported=%d\n",
    16851699                 pThis->iInstance, pThis->cLinkDownReported));
    16861700            pThis->Led.Actual.s.fError = 0;
     
    16881702    }
    16891703    else
    1690         Log(("#%d elnkTimerRestore: cLinkDownReported=%d, wait another 1500ms...\n",
    1691              pThis->iInstance, pThis->cLinkDownReported));
     1704    {
     1705        LogFunc(("#%d: cLinkDownReported=%d, cLinkRestorePostponed=%d, wait another 1500ms...\n",
     1706                 pThis->iInstance, pThis->cLinkDownReported, pThis->cLinkRestorePostponed));
     1707        pThis->cLinkRestorePostponed++;
     1708    }
    16921709
    16931710    PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect);
     
    17001717 * @callback_method_impl{FNDBGFHANDLERDEV}
    17011718 */
    1702 static DECLCALLBACK(void) elnkInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     1719static DECLCALLBACK(void) elnkR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    17031720{
    17041721    PELNKSTATE          pThis = PDMDEVINS_2_DATA(pDevIns, PELNKSTATE);
     
    17401757    pHlp->pfnPrintf(pHlp, "  Buffer control  : %s\n", apszBuffCntrl[pThis->AuxCmd.buf_ctl]);
    17411758    pHlp->pfnPrintf(pHlp, "  Interrupt state : xmit=%u recv=%u dma=%u\n", pThis->IntrState.xmit_intr, pThis->IntrState.recv_intr, pThis->IntrState.dma_intr);
    1742     if (pThis->cLinkDownReported)
     1759    if (pThis->fLinkTempDown)
     1760    {
    17431761        pHlp->pfnPrintf(pHlp, "  Link down count : %d\n", pThis->cLinkDownReported);
     1762        pHlp->pfnPrintf(pHlp, "  Postpone count  : %d\n", pThis->cLinkRestorePostponed);
     1763    }
    17441764
    17451765    /* Dump the station address. */
     
    18141834        pThis->fLinkTempDown = true;
    18151835        pThis->cLinkDownReported = 0;
     1836        pThis->cLinkRestorePostponed = 0;
    18161837        pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1;
    18171838        int rc = PDMDevHlpTimerSetMillies(pDevIns, pThis->hTimerRestore, pThis->cMsLinkUpDelay);
     
    18741895    pHlp->pfnSSMPutBool(pSSM, pThis->fISR);
    18751896    pHlp->pfnSSMPutMem(pSSM, pThis->aStationAddr, sizeof(pThis->aStationAddr));
     1897
     1898    /* Save the configured MAC address. */
     1899    pHlp->pfnSSMPutMem(pSSM, &pThis->MacConfigured, sizeof(pThis->MacConfigured));
    18761900
    18771901    return VINF_SUCCESS;
     
    19251949        pHlp->pfnSSMGetBool(pSSM, &pThis->fLinkUp);
    19261950        pHlp->pfnSSMGetBool(pSSM, &pThis->fISR);
     1951        pHlp->pfnSSMGetMem(pSSM, &pThis->aStationAddr, sizeof(pThis->aStationAddr));
    19271952    }
    19281953
     
    21582183            pThis->fLinkTempDown = true;
    21592184            pThis->cLinkDownReported = 0;
     2185            pThis->cLinkRestorePostponed = 0;
    21602186            pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1;
    21612187            int rc = PDMDevHlpTimerSetMillies(pDevIns, pThis->hTimerRestore, pThis->cMsLinkUpDelay);
     
    21662192            /* Disconnect. */
    21672193            pThis->cLinkDownReported = 0;
     2194            pThis->cLinkRestorePostponed = 0;
    21682195            pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1;
    21692196        }
     
    23192346    {
    23202347        pThis->cLinkDownReported = 0x1000;
     2348        pThis->cLinkRestorePostponed = 0x1000;
    23212349        PDMDevHlpTimerStop(pDevIns, pThis->hTimerRestore);
    2322         elnkTimerRestore(pDevIns, pThis->hTimerRestore, pThis);
     2350        elnkR3TimerRestore(pDevIns, pThis->hTimerRestore, pThis);
    23232351    }
    23242352
     
    24762504        LogRel(("3C501#%d: Disabling DMA\n", iInstance));
    24772505
    2478     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, elnkTimerRestore, NULL, TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
     2506    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, elnkR3TimerRestore, NULL, TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
    24792507                              "3C501 Restore Timer", &pThis->hTimerRestore);
    24802508    if (RT_FAILURE(rc))
     
    25062534     */
    25072535    RTStrPrintf(szTmp, sizeof(szTmp), "elnk%d", pThis->iInstance);
    2508     PDMDevHlpDBGFInfoRegister(pDevIns, szTmp, "3C501 info", elnkInfo);
     2536    PDMDevHlpDBGFInfoRegister(pDevIns, szTmp, "3C501 info", elnkR3Info);
    25092537
    25102538    /*
  • trunk/src/VBox/Devices/Network/DevDP8390.cpp

    r93601 r93675  
    352352/** Maximum number of times we report a link down to the guest (failure to send frame) */
    353353#define DPNIC_MAX_LINKDOWN_REPORTED     3
     354
     355/** Maximum number of times we postpone restoring a link that is temporarily down. */
     356#define DPNIC_MAX_LINKRST_POSTPONED     3
    354357
    355358/** Maximum frame size we handle */
     
    886889    /** Number of times we've reported the link down. */
    887890    uint16_t                            cLinkDownReported;
     891    /** Number of times we've postponed the link restore. */
     892    uint16_t                            cLinkRestorePostponed;
    888893
    889894    /** The "hardware" MAC address. */
     
    39393944 * should be considered lost.
    39403945 */
    3941 static DECLCALLBACK(void) dpNicTimerRestore(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, void *pvUser)
     3946static DECLCALLBACK(void) dpNicR3TimerRestore(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, void *pvUser)
    39423947{
    39433948    RT_NOREF(pvUser);
     
    39473952
    39483953    rc = VERR_GENERAL_FAILURE;
    3949     if (pThis->cLinkDownReported <= DPNIC_MAX_LINKDOWN_REPORTED)
     3954
     3955    /* The DP8390 based cards have no concept of link state. Reporting collisions on all transmits
     3956     * is the best approximation of a disconnected cable that we can do. Some drivers (3C503) warn
     3957     * of possible disconnected cable, some don't. Many cards with DP8390 chips had permanently
     3958     * attached cables (AUI or BNC) and their drivers do not expect cables to be disconnected and
     3959     * re-connected at runtime. Guests which are waiting for a receive have no way to notice any
     3960     * problem, therefore we only postpone restoring a link a couple of times, and then reconnect
     3961     * regardless of whether the guest noticed anything or not.
     3962     */
     3963    if (   (pThis->cLinkDownReported <= DPNIC_MAX_LINKDOWN_REPORTED)
     3964        && (pThis->cLinkRestorePostponed <= DPNIC_MAX_LINKRST_POSTPONED))
    39503965        rc = PDMDevHlpTimerSetMillies(pDevIns, hTimer, 1500);
    39513966    if (RT_FAILURE(rc))
     
    39613976    }
    39623977    else
    3963         LogFunc(("#%d: cLinkDownReported=%d, wait another 1500ms...\n", pThis->iInstance, pThis->cLinkDownReported));
     3978    {
     3979        LogFunc(("#%d: cLinkDownReported=%d, cLinkRestorePostponed=%d, wait another 1500ms...\n",
     3980                 pThis->iInstance, pThis->cLinkDownReported, pThis->cLinkRestorePostponed));
     3981        pThis->cLinkRestorePostponed++;
     3982    }
    39643983
    39653984    PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect);
     
    39723991 * @callback_method_impl{FNDBGFHANDLERDEV}
    39733992 */
    3974 static DECLCALLBACK(void) dpNicInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     3993static DECLCALLBACK(void) dpNicR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    39753994{
    39763995    PDPNICSTATE     pThis = PDMDEVINS_2_DATA(pDevIns, PDPNICSTATE);
     
    41064125    if (pThis->fMaybeOutOfSpace)
    41074126        pHlp->pfnPrintf(pHlp, "  Waiting for receive space\n");
    4108     if (pThis->cLinkDownReported)
     4127    if (pThis->fLinkTempDown)
     4128    {
    41094129        pHlp->pfnPrintf(pHlp, "  Link down count %d\n", pThis->cLinkDownReported);
     4130        pHlp->pfnPrintf(pHlp, "  Postpone count  %d\n", pThis->cLinkRestorePostponed);
     4131    }
    41104132
    41114133    if ((pThis->uDevType == DEV_WD8003) || (pThis->uDevType == DEV_WD8013))
     
    42864308        pThis->fLinkTempDown = true;
    42874309        pThis->cLinkDownReported = 0;
     4310        pThis->cLinkRestorePostponed = 0;
    42884311        pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1;
    42894312        int rc = PDMDevHlpTimerSetMillies(pDevIns, pThis->hTimerRestore, pThis->cMsLinkUpDelay);
     
    44854508        pHlp->pfnSSMGetBool(pSSM, &pThis->ga.fGaIrq);
    44864509
    4487         /* Set IRQ and DMA based on IDCFR. */
    4488         pThis->uIsaIrq   = elGetIrqFromIdcfr(pThis->ga.IDCFR);
    4489         pThis->uElIsaDma = elGetDrqFromIdcfr(pThis->ga.IDCFR);
     4510        /* Set IRQ and DMA based on IDCFR if this is a 3C503. */
     4511        if (pThis->uDevType == DEV_3C503)
     4512        {
     4513            pThis->uIsaIrq   = elGetIrqFromIdcfr(pThis->ga.IDCFR);
     4514            pThis->uElIsaDma = elGetDrqFromIdcfr(pThis->ga.IDCFR);
     4515        }
    44904516    }
    44914517
     
    47514777            pThis->fLinkTempDown = true;
    47524778            pThis->cLinkDownReported = 0;
     4779            pThis->cLinkRestorePostponed = 0;
    47534780            pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1;
    47544781            int rc = PDMDevHlpTimerSetMillies(pDevIns, pThis->hTimerRestore, pThis->cMsLinkUpDelay);
     
    47594786            /* Disconnect. */
    47604787            pThis->cLinkDownReported = 0;
     4788            pThis->cLinkRestorePostponed = 0;
    47614789            pThis->Led.Asserted.s.fError = pThis->Led.Actual.s.fError = 1;
    47624790        }
     
    49134941    {
    49144942        pThis->cLinkDownReported = 0x1000;
     4943        pThis->cLinkRestorePostponed = 0x1000;
    49154944        PDMDevHlpTimerStop(pDevIns, pThis->hTimerRestore);
    4916         dpNicTimerRestore(pDevIns, pThis->hTimerRestore, pThis);
     4945        dpNicR3TimerRestore(pDevIns, pThis->hTimerRestore, pThis);
    49174946    }
    49184947
     
    52045233
    52055234
    5206     rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, dpNicTimerRestore, NULL, TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
     5235    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL, dpNicR3TimerRestore, NULL, TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
    52075236                              "DPNIC Link Restore Timer", &pThis->hTimerRestore);
    52085237    if (RT_FAILURE(rc))
     
    52345263     */
    52355264    RTStrPrintf(szTmp, sizeof(szTmp), "dpnic%d", pThis->iInstance);
    5236     PDMDevHlpDBGFInfoRegister(pDevIns, szTmp, "dpnic info", dpNicInfo);
     5265    PDMDevHlpDBGFInfoRegister(pDevIns, szTmp, "dpnic info", dpNicR3Info);
    52375266
    52385267    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette