📄 vc.c
字号:
//
// Determine the pre-scale for the required cell rate.
// We find a closer value.
//
PreScale_Val = 0;
NumOfEntriesNeeded = 1;
if (pFlow->PeakCellRate < pHwInfo->CellClockRate)
{
//
// Rate = Schedule_table_rate / (PreScale_Val + 1);
// PreScale_Val = (Schedule_table_rate / Rate) - 1;
//
PreScale_Val = pHwInfo->CellClockRate / pFlow->PeakCellRate;
c = pHwInfo->CellClockRate % pFlow->PeakCellRate;
if ((c == 0) || (c < (pFlow->PeakCellRate/2)))
{
//
// if c = 0 --> Actual PCR == pFlow->PeakCellRate
//
// if c < (pFlow->PeakCellRate/2)
// --> Actual PCR > pFlow->PeakCellRate
// if c > (pFlow->PeakCellRate/2)
// --> Actual PCR < pFlow->PeakCellRate
//
PreScale_Val--;
}
if (PreScale_Val > MAX_PRESCALE_VAL)
{
PreScale_Val = MAX_PRESCALE_VAL;
}
}
else
{
//
// Calculate the number of entries are needed in CBR schedule table.
//
NumOfEntriesNeeded = pFlow->PeakCellRate / pHwInfo->CellClockRate;
c = pFlow->PeakCellRate % pHwInfo->CellClockRate;
if (c > (pFlow->PeakCellRate / 2))
{
//
// if c = 0 --> Actual PCR == pFlow->PeakCellRate
//
// if c < (pFlow->PeakCellRate/2)
// --> Actual PCR < pFlow->PeakCellRate
// if c > (pFlow->PeakCellRate/2)
// --> Actual PCR > pFlow->PeakCellRate
//
NumOfEntriesNeeded++;
}
}
//
// Do any rounding necessary....
fDone = FALSE;
do
{
//
// Determine the actual PCR.
//
ActualPeakCellRate = (pHwInfo->CellClockRate * NumOfEntriesNeeded) /
(PreScale_Val + 1);
//
// Round up or down?
//
if (fRoundFlowUp)
{
if (ActualPeakCellRate < pFlow->PeakCellRate)
{
if (PreScale_Val > 0)
{
PreScale_Val--;
}
else
{
NumOfEntriesNeeded++;
}
}
else
{
fDone = TRUE;
}
}
else
{
//
// Round flow down
//
if (ActualPeakCellRate > pFlow->PeakCellRate)
{
if (NumOfEntriesNeeded > 1)
{
NumOfEntriesNeeded--;
}
else
{
if (PreScale_Val < MAX_PRESCALE_VAL)
{
PreScale_Val++;
}
else
{
fDone = TRUE;
}
}
}
else
{
fDone = TRUE;
}
}
} while (!fDone);
ActualPeakCellRate = (pHwInfo->CellClockRate * NumOfEntriesNeeded) /
(PreScale_Val + 1);
if ((ActualPeakCellRate > pAdapter->MinimumCbrBandwidth) &&
(ActualPeakCellRate < pAdapter->RemainingTransmitBandwidth))
{
if ((ULONG)(MAX_ENTRIES_CBR_TBL - NumOfEntriesNeeded) >
pAdapter->TotalEntriesUsedonCBRs)
{
*pPreScaleVal = PreScale_Val;
*pNumOfEntries = NumOfEntriesNeeded;
//
// Save the actual cell rate with the flow parameters...
//
pFlow->PeakCellRate = ActualPeakCellRate;
}
else
{
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("Not enough entries on CBR schedule table.!\n"));
DBGBREAK(DBG_COMP_VC, DBG_LEVEL_ERR);
Status = NDIS_STATUS_FAILURE;
}
}
else
{
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("The adjust bandwidth is out of supporting range.!\n"));
DBGBREAK(DBG_COMP_VC, DBG_LEVEL_ERR);
Status = NDIS_STATUS_FAILURE;
}
} while (FALSE);
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
("<==tbAtm155AdjustTrafficParameters (Status: 0x%lx)\n", Status));
return(Status);
}
NDIS_STATUS
tbAtm155SetCbrTblsInSRAM(
IN PADAPTER_BLOCK pAdapter,
IN PVC_BLOCK pVc,
IN BOOLEAN fOpenVC
)
/*++
Routine Description:
This routine will setup the tables for CBR flow on on-board SRAM.
Arguments:
pAdapter - Pointer to the adapter to program.
pVc - Pointer to the VC_BLOCK that describes the VC we
are handling.
fOpenVC - TRUE: add more entries for the VC to CBR schedule table
FALSE: eliminate entries for the VC from CBR schedule table
Return Value:
NDIS_STATUS_SUCCESS if successful.
--*/
{
PHARDWARE_INFO pHwInfo = pAdapter->HardwareInfo;
TB155PCISAR_CNTRL1 regControl1;
TBATM155_CBR_SCHEDULE_ENTRY phData;
ULONG pCurrCbrTbl, pStCbrTbl, pAddr;
USHORT Idx;
NDIS_STATUS Status;
ULONG pEndCbrTbl;
USHORT CellInterval, Curr_CI;
USHORT Count_Fract_CI, Indx_Fract_CI;
ULONG pTemp;
BOOLEAN fFound1stEntry = FALSE;
TBATM155_CBR_SCHEDULE_ENTRY phOpenVc;
ULONG pEntryAddr_1st;
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
("==>tbAtm155SetCbrTblsInSRAM\n"));
TBATM155_READ_PORT(
&pHwInfo->TbAtm155_SAR->SAR_Cntrl1,
®Control1.reg);
if (regControl1.CBR_ST_Sel == 0)
{
//
// 1. Set CBR schedule table 1 is currently used.
// 2. Set the CBR schedule table 2 is selected.
// 3. Set CBR_ST_Sel bit to select CBR schedule table 2.
//
pCurrCbrTbl = pHwInfo->pSramCbrScheduleTbl_1;
pStCbrTbl = pHwInfo->pSramCbrScheduleTbl_2;
regControl1.CBR_ST_Sel = 1;
}
else
{
//
// 1. Set CBR schedule table 2 is Currently used.
// 2. Set the CBR schedule table 1 is selected.
// 3. Set CBR_ST_Sel bit to select CBR schedule table 1.
//
pCurrCbrTbl = pHwInfo->pSramCbrScheduleTbl_2;
pStCbrTbl = pHwInfo->pSramCbrScheduleTbl_1;
regControl1.CBR_ST_Sel = 0;
}
do
{
//
// 1. Copy contents of Schedule tables from "Current" to "Select"
// 2. Find the 1st "active=0" entry as well.
//
for (Idx = 0, pAddr = pStCbrTbl;
Idx < MAX_CBR_SCHEDULE_ENTRIES;
Idx++, pCurrCbrTbl++, pAddr++)
{
TBATM155_PH_READ_SRAM(pAdapter, pCurrCbrTbl, &phData.data, &Status);
if (NDIS_STATUS_SUCCESS != Status)
{
DBGPRINT(DBG_COMP_INIT,DBG_LEVEL_ERR,
("Failed rd CBR Schedule table (copy)! \n"));
break;
}
if ((fOpenVC == FALSE) && (phData.VC == pVc->VpiVci.Vci))
{
//
// if this entry is not void or the VC is de-activated.
//
phData.data = 0;
}
if (fFound1stEntry == FALSE)
{
if (phData.Active == 0)
{
//
// Found the 1st of the "active=0 entry.
// 1. remember the address
// 2. set the flag to indicate the entry has been found.
//
pEntryAddr_1st = pAddr;
fFound1stEntry = TRUE;
}
}
//
// copy this entry to destination also reset the EOT regardless.
//
phData.EOT = 0;
TBATM155_PH_WRITE_SRAM(pAdapter, pAddr, phData.data, &Status);
if (NDIS_STATUS_SUCCESS != Status)
{
DBGPRINT(DBG_COMP_INIT,DBG_LEVEL_ERR,
("Failed wr CBR Schedule table (Copy)! \n"));
break;
}
} // end of FOR
//
// Remember the end of destination CBR table to use later.
//
pEndCbrTbl = pAddr - 1;
if ((NDIS_STATUS_SUCCESS != Status) || (fOpenVC != TRUE))
{
//
// Exit, due to either
// 1. error detected, or
// 2. don't need to handle activate any entries for a new VC.
//
break;
}
//
// Calculate all of the variables for handling CDV, Cell Delay
// Variation, correctly.
//
CellInterval = (USHORT)(MAX_CBR_SCHEDULE_ENTRIES / pVc->CbrNumOfEntris);
Curr_CI = CellInterval;
Count_Fract_CI = 0;
if (MAX_CBR_SCHEDULE_ENTRIES % pVc->CbrNumOfEntris)
{
//
// Handle the fraction of the difference between the theorical
// interval and actual interval on CBR schedule table.
//
Count_Fract_CI = (USHORT) (pVc->CbrNumOfEntris /
(MAX_CBR_SCHEDULE_ENTRIES % pVc->CbrNumOfEntris));
Count_Fract_CI = Count_Fract_CI + 1;
Indx_Fract_CI = Count_Fract_CI;
}
//
// Set up the necessary entry data of the activated VC.
//
phOpenVc.data = 0;
phOpenVc.VC = (USHORT)pVc->VpiVci.Vci;
phOpenVc.Active = 1;
//
// Set up the entries of the VC
//
for (pAddr = pEntryAddr_1st, Idx = (USHORT)pVc->CbrNumOfEntris;
Idx > 0;
Curr_CI = CellInterval, Idx--)
{
TBATM155_PH_READ_SRAM(pAdapter, pAddr, &phData.data, &Status);
if (NDIS_STATUS_SUCCESS != Status)
{
DBGPRINT(DBG_COMP_INIT,DBG_LEVEL_ERR,
("Failed wr CBR Schedule table (Add more Entries)! \n"));
break;
}
if (phData.Active == 1)
{
//
// Let's find an available CBR entry around this pAddr.
//
for (pTemp = 1; TRUE; pTemp++)
{
//
// Let's looking for available entry around
// pAddr (+/-) pTemp
// Make sure not over the beginning and the end of
// the CBR table.
//
if ((pAddr + pTemp) <= pEndCbrTbl)
{
//
// Check if (pAddr + pTemp) entry is available
//
TBATM155_PH_READ_SRAM(
pAdapter,
(pAddr + pTemp),
&phData.data,
&Status);
if (NDIS_STATUS_SUCCESS != Status)
{
DBGPRINT(DBG_COMP_INIT,DBG_LEVEL_ERR,
("Failed wr CBR Schedule table (Add more Entries)! \n"));
break;
}
if (phData.Active == 0)
{
//
// Adjust Cell interval for the next entry.
//
pAddr += pTemp;
if (Curr_CI > (USHORT) pTemp)
{
Curr_CI = (USHORT)(Curr_CI - (USHORT) pTemp);
}
else
{
Curr_CI = 1;
}
break;
}
}
if ((pAddr - pTemp) >= pStCbrTbl)
{
//
// Check if (pAddr - pTemp) entry is available
//
TBATM155_PH_READ_SRAM(
pAdapter,
(pAddr - pTemp),
&phData.data,
&Status);
if (NDIS_STATUS_SUCCESS != Status)
{
DBGPRINT(DBG_COMP_INIT,DBG_LEVEL_ERR,
("Failed wr CBR Schedule table (Add more Entries)! \n"));
break;
}
if (phData.Active == 0)
{
//
// Adjust Cell interval for the next entry.
//
pAddr -= pTemp;
Curr_CI += (USHORT) pTemp;
break;
}
}
if (((pAddr + pTemp) > pEndCbrTbl) || ((pAddr - pTemp) < pStCbrTbl))
{
Status = NDIS_STATUS_FAILURE;
DBGPRINT(DBG_COMP_SPECIAL, DBG_LEVEL_ERR,
("Failed to write CBR Schedule table! \n"));
DBGBREAK(DBG_COMP_SPECIAL, DBG_LEVEL_FATAL);
break;
}
} // end of FOR (pTemp = 1; TRUE; pTemp++)
} // end of (phData.Active == 1)
if (NDIS_STATUS_SUCCESS != Status)
{
break;
}
TBATM155_PH_WRITE_SRAM(pAdapter, pAddr, phOpenVc.data, &Status);
if (NDIS_STATUS_SUCCESS != Status)
{
DBGPRINT(DBG_COMP_INIT,DBG_LEVEL_ERR,
("Failed wr CBR Schedule table (Copy)! \n"));
break;
}
if (Count_Fract_CI > 0)
{
Indx_Fract_CI--;
if (Indx_Fract_CI == 0)
{
Indx_Fract_CI = Count_Fract_CI;
Curr_CI++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -