⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vc.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
       //
       //	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,
       &regControl1.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 + -