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

📄 if_gt.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 3 页
字号:
{u_int32_t portControlReg;unsigned int hashLengh[NUM_ETH_PORTS];    hashLengh[0] = EIGHT_K;     hashLengh[1] = HALF_K;    addressTableHashMode[port] = hashMode;    addressTableHashSize[port] = hashSize;    /* allocate memory for the address table */    addressTableBase[port] = (unsigned int)malloc(hashLengh[hashSize]*MAC_ENTRY_SIZE,                                                  M_DEVBUF, M_NOWAIT);    /*     *  Set-up ptr to hash table     */    GT_WRITE(ETH0_HASH_TABLE_PTR_REG+port*ETHERNET_PORTS_DIFFERENCE_OFFSETS,addressTableBase[port]);    /* fill all the address table with 0's */    memset((void*)addressTableBase[port],0,hashLengh[hashSize]*MAC_ENTRY_SIZE);    /* set hash size hash mode and HDM in the PCR */    portControlReg = 0x00000081;    portControlReg = portControlReg & ~(1 << HASH_DEFUALT_MODE);    portControlReg = portControlReg & ~(1 << HASH_MODE);    portControlReg = portControlReg & ~(1 << HASH_SIZE);    portControlReg = portControlReg |         (hashDefaultMode<<HASH_DEFUALT_MODE) |         (hashMode << HASH_MODE) |         (hashSize << HASH_SIZE);    GT_WRITE(ETH0_PORT_CONFIG_REG+port*ETHERNET_PORTS_DIFFERENCE_OFFSETS, portControlReg);    /* enableFiltering */    enableFiltering(port);    return TRUE;}  /****************************************************************************** * This function will add an entry to the address table and * depends on the hash mode and hash size that was initialized.* Inputs*   port - ETHERNET port number.*   macH - the 2 most significant bytes of the MAC address.*   macL - the 4 least significant bytes of the MAC address.*   skip - if 1 , skip this address.*   rd - the RD field in the address table.* Outputs*   address table entry is added.*   TRUE if success.*   FALSE if fail to make the assignment.*/intaddAddressTableEntry(port, macH, macL, rd, skip)    int port;    unsigned int macH;    unsigned int macL;    unsigned int rd;    unsigned int skip;{    unsigned int addressHighValue;    unsigned int addressLowValue;    void* entryNumber;    int hashBase = addressTableBase[port];     int i;    unsigned int addressLowRead;    unsigned int addressHighRead;    entryNumber = (void*)(hashBase +                           MAC_ENTRY_SIZE*hashTableFunction(macH,macL,(int)addressTableHashSize[port],                                                           (int)addressTableHashMode[port]));    addressLowValue = VALID | (skip<<SKIP_BIT) | (rd<<2) | (((macH>>8)&0xf)<<3) | (((macH>>12)&0xf)<<7) |		      (((macH>>0)&0xf)<<11) | (((macH>>4)&0xf)<<15) | 		      (((macL>>24)&0xf)<<19) | (((macL>>28)&0xf)<<23) | (((macL>>16)&0xf)<<27) |		      ((((macL>>20)&0x1)<<31));    addressHighValue = ((macL>>21)&0x7) | (((macL>>8)&0xf)<<3) | (((macL>>12)&0xf)<<7) | 	               (((macL>>0)&0xf)<<11) | (((macL>>4)&0xf)<<15);    /* find a free place */    for(i = 0 ; i < HOP_NUMBER ; i++)    {        addressLowRead = *(unsigned int*)(entryNumber+i*MAC_ENTRY_SIZE+4);        if((!(addressLowRead & VALID))/* || (addressLowRead & SKIP)*/)        {            entryNumber = entryNumber+i*MAC_ENTRY_SIZE;            break;        }        else /* if the address is the same locate it at the same position */        {            addressHighRead = *(unsigned int*)(entryNumber+i*MAC_ENTRY_SIZE);            if(((addressLowRead>>3)&0x1fffffff)==((addressLowValue>>3)&0x1fffffff)                && ((addressHighRead/*&0x7ffff*/)==(addressHighValue/*&0x7ffff*/)))            {                printf("addressHighRead = 0x%x addressHighValue = 0x%x\n",addressHighRead,addressHighValue);                entryNumber = entryNumber+i*MAC_ENTRY_SIZE;                break;            }        }                }    if(i == HOP_NUMBER)    {        printf("The address table section is full\n");        return 1;    }    /* write the address to the address table */    *(unsigned int*)(entryNumber) = addressHighValue;    *(unsigned int*)(entryNumber+4) = addressLowValue;    return 0;}/****************************************************************************** * int hashTableFunction(unsigned int macH,unsigned int macL,int HashSize,int hash_mode)* * This function will calculate the hash function of the address.* depends on the hash mode and hash size.* Inputs* macH - the 2 most significant bytes of the MAC address.* macL - the 4 least significant bytes of the MAC address.* hashMode - hash mode 0 or hash mode 1.* hashSize - the size of the hash table (0=8K ,1=1/2K).* Outputs* return the caculated entry.* TRUE if success.* FALSE if fail to make the assignment.*/int hashTableFunction(unsigned int macH,unsigned int macL,int HashSize,int hash_mode){unsigned int hashResult;unsigned int ethernetAddH;unsigned int ethernetAddL;unsigned int ethernetAdd0;unsigned int ethernetAdd1;unsigned int ethernetAdd2;unsigned int ethernetAdd3;unsigned int ethernetAddHSwapped = 0;unsigned int ethernetAddLSwapped = 0;	ethernetAddH = NIBBLE_SWAPPING_16_BIT(macH);	ethernetAddL = NIBBLE_SWAPPING_32_BIT(macL);	ethernetAddHSwapped = GT_NIBBLE(ethernetAddH&0xf)+((GT_NIBBLE((ethernetAddH>>4)&0xf))<<4)+		((GT_NIBBLE((ethernetAddH>>8)&0xf))<<8)+((GT_NIBBLE((ethernetAddH>>12)&0xf))<<12);	ethernetAddLSwapped = GT_NIBBLE(ethernetAddL&0xf)+((GT_NIBBLE((ethernetAddL>>4)&0xf))<<4)+		((GT_NIBBLE((ethernetAddL>>8)&0xf))<<8)+((GT_NIBBLE((ethernetAddL>>12)&0xf))<<12)+		((GT_NIBBLE((ethernetAddL>>16)&0xf))<<16)+((GT_NIBBLE((ethernetAddL>>20)&0xf))<<20)+		((GT_NIBBLE((ethernetAddL>>24)&0xf))<<24)+((GT_NIBBLE((ethernetAddL>>28)&0xf))<<28);	ethernetAddH = ethernetAddHSwapped;	ethernetAddL = ethernetAddLSwapped;	if(hash_mode == 0)	{		ethernetAdd0 = (ethernetAddL>>2) & 0x3f;		ethernetAdd1 = (ethernetAddL & 0x3) | ((ethernetAddL>>8) & 0x7f)<<2;		ethernetAdd2 = (ethernetAddL>>15) & 0x1ff;		ethernetAdd3 = ((ethernetAddL>>24) & 0xff) | ((ethernetAddH & 0x1)<<8);	}	else	{		ethernetAdd0 = FLIP_6_BITS((ethernetAddL) & 0x3f);		ethernetAdd1 = FLIP_9_BITS(((ethernetAddL>>6) & 0x1ff));		ethernetAdd2 = FLIP_9_BITS((ethernetAddL>>15) & 0x1ff);		ethernetAdd3 = FLIP_9_BITS((((ethernetAddL>>24) & 0xff) | ((ethernetAddH & 0x1)<<8)));	}	hashResult = (ethernetAdd0<<9) | (ethernetAdd1^ethernetAdd2^ethernetAdd3);	if(HashSize == _8K_TABLE)	{		hashResult = hashResult & 0xffff;	}	else	{		hashResult = hashResult & 0x7ff;	}	return hashResult;}/****************************************************************************** * boolean_t enableFiltering(int port)* * This function will set the Promiscuous mode to normal mode.* in ordet to enable Filtering.* Inputs* port - ETHERNET port number.* Outputs* address filtering will be enabled.* TRUE if success.* FALSE if fail to make the assignment.*/boolean_t enableFiltering(int port){u_int32_t portControlReg;    portControlReg = GT_READ(ETH0_PORT_CONFIG_REG+port*ETHERNET_PORTS_DIFFERENCE_OFFSETS);    portControlReg = portControlReg & ~(1<<PROMISCUOUS_MODE);    GT_WRITE(ETH0_PORT_CONFIG_REG+port*ETHERNET_PORTS_DIFFERENCE_OFFSETS, portControlReg);    return TRUE;}/****************************************************************************** * bool disableFiltering(int port)* * This function will set the Promiscuous mode to Promiscuous mode.* in order to disable Filtering.* Inputs* port - ETHERNET port number.* Outputs* address filtering will be enabled.* TRUE if success.* FALSE if fail to make the assignment.*/boolean_t disableFiltering(int port){u_int32_t portControlReg;    portControlReg = GT_READ(ETH0_PORT_CONFIG_REG+port*ETHERNET_PORTS_DIFFERENCE_OFFSETS);    portControlReg = portControlReg | (1<<PROMISCUOUS_MODE);    GT_WRITE(ETH0_PORT_CONFIG_REG+port*ETHERNET_PORTS_DIFFERENCE_OFFSETS, portControlReg);    return TRUE;}/****************************************************************************** * boolean_t scanAddressTable(int port)* * This function will scan and print all the address table valid entries.* Inputs* port - ETHERNET port number.* TRUE if success.* FALSE if fail to make the assignment.*/boolean_t scanAddressTable(int port){unsigned int entry=0;char dummyBuffer[100];    while(findFirstAddressTableEntry(port,&entry,dummyBuffer) != FALSE);    return TRUE;}/****************************************************************************** * boolean_t findFirstAddressTableEntry(int port,unsigned int* startEntry)* * This function will scan and print the first address table valid entry.* Inputs* port - ETHERNET port number.* TRUE if success.* FALSE if fail to make the assignment.*/boolean_t findFirstAddressTableEntry(int port,unsigned int* startEntry,char* resultBuffer){unsigned int currentEntry;unsigned int hashLengh[NUM_ETH_PORTS];unsigned int addressLowRead;unsigned int addressHighRead;unsigned int addressLowValue;unsigned int addressHighValue;unsigned int endTable;int hashSize;unsigned int firstEntry;    hashLengh[0] = EIGHT_K;     hashLengh[1] = HALF_K;    hashSize = addressTableHashSize[port];    endTable = (addressTableBase[port]+hashLengh[hashSize]*MAC_ENTRY_SIZE);    firstEntry = *startEntry;    currentEntry = addressTableBase[port]+((firstEntry)*MAC_ENTRY_SIZE);    while(currentEntry < endTable)    {        addressLowRead = *(unsigned int*)(currentEntry+4);        if(addressLowRead & VALID)        {            addressHighRead = *(unsigned int*)(currentEntry);            addressLowValue = (((addressHighRead>>11)&0xf)<<0) | (((addressHighRead>>15)&0xf)<<4) |                (((addressHighRead>>3)&0xf)<<8) | (((addressHighRead>>7)&0xf)<<12) |                (((addressLowRead>>27)&0xf)<<16) | (((addressHighRead>>0)&0x7)<<21) |                (((addressLowRead>>31)&0x1)<<20) | (((addressLowRead>>19)&0xf)<<24) |                (((addressLowRead>>23)&0xf)<<28);            addressHighValue = (((addressLowRead>>11)&0xf)<<0) | (((addressLowRead>>15)&0xf)<<4) |                (((addressLowRead>>3)&0xf)<<8) | (((addressLowRead>>7)&0xf)<<12);            printf("valid address %04x%08x was found in entry # 0x%x SKIP=%d RD=%d\n",                   addressHighValue,addressLowValue,firstEntry,                   (addressLowRead>>1)&0x1,(addressLowRead>>2)&0x1);            sprintf(resultBuffer,"%x!!!%02x!!!%02x!!!%02x!!!%02x!!!%02x!!!%02x!!!%x!!!%x!!!%x",firstEntry*8,(addressHighValue>>8)&0xff,                    (addressHighValue>>0)&0xff,(addressLowValue>>24)&0xff,(addressLowValue>>16)&0xff,                    (addressLowValue>>8)&0xff,(addressLowValue>>0)&0xff,                    ((addressLowRead>>2)&0x1),((addressLowRead>>1)&0x1),VALID);                                firstEntry++;            *startEntry = firstEntry;            return TRUE;        }        currentEntry += MAC_ENTRY_SIZE;        firstEntry ++;    }    return FALSE;}/****************************************************************************** * boolean_t addressTableDefragment(int port,int hashMode,int hashSize)* * This function will save all adresses in memory reinitialize the address table  * and add all the addresses to the new table.* Inputs* hashMode - hash mode 0 or hash mode 1.* hashSize - the size of the hash table.* port - ETHERNET port number.* Outputs* address table is reinitialized with the old addresses all skip addresses * will be deleted.* TRUE if success.* FALSE if fail to make the assignment.*/boolean_t addressTableDefragment(int port,int hashMode,int hashSize,int hashDefaultMode){ADDRESS_TABLE_STORE addresses[MAX_NUMBER_OF_ADDRESSES_TO_STORE];u_int32_t numberOfAddresses = 0;u_int32_t entry;u_int32_t endTable;u_int32_t addressLowRead;u_int32_t addressHighRead;u_int32_t addressLowValue;u_int32_t addressHighValue;u_int32_t hashLengh[NUM_ETH_PORTS];u_int32_t portControlReg;int i;    hashLengh[0] = EIGHT_K;     hashLengh[1] = HALF_K;    /* keep all addresses in memory */    endTable = (addressTableBase[port]+hashLengh[addressTableHashSize[port]]*MAC_ENTRY_SIZE);    for(entry = addressTableBase[port] ; entry < endTable ; entry+=MAC_ENTRY_SIZE)    {        addressLowRead = *(unsigned int*)(entry+4);        if(addressLowRead & VALID)        {            addressHighRead = *(unsigned int*)(entry);            addressLowValue = (((addressHighRead>>11)&0xf)<<0) | (((addressHighRead>>15)&0xf)<<4) |                (((addressHighRead>>3)&0xf)<<8) | (((addressHighRead>>7)&0xf)<<12) |                (((addressLowRead>>27)&0xf)<<16) | (((addressHighRead>>0)&0x7)<<21) |                (((addressLowRead>>31)&0x1)<<20) | (((addressLowRead>>19)&0xf)<<24) |                (((addressLowRead>>23)&0xf)<<28);            addressHighValue = (((addressLowRead>>11)&0xf)<<0) | (((addressLowRead>>15)&0xf)<<4) |                (((addressLowRead>>3)&0xf)<<8) | (((addressLowRead>>7)&0xf)<<12);            addresses[numberOfAddresses].macH = addressHighValue;            addresses[numberOfAddresses].macL = addressLowValue;            addresses[numberOfAddresses].rd = (addressLowRead>>2)&0x1;            addresses[numberOfAddresses].skip = (addressLowRead>>1)&0x1;            addresses[numberOfAddresses].valid = (addressLowRead)&0x1;            numberOfAddresses++;            if(numberOfAddresses > MAX_NUMBER_OF_ADDRESSES_TO_STORE)            {                printf("can't store so many addresses\n");                return 1;            } /* if(numberOfAddresses > MAX_NUMBER_OF_ADDRESSES_TO_STORE) */        } /* if(addressLowRead & VALID) */    } /* for(entry = addressTableBase[port] ; entry < endTable ; entry+=MAC_ENTRY_SIZE) */    /* clear the table */    addressTableClear(port);    /* if the table size is the same use the same table else allocate new one */    /* if the new table is smaller - do not allocate a new one */    if((hashSize == addressTableHashSize[port]) || (addressTableHashSize[port] == _8K_TABLE))    {        portControlReg = GT_READ(ETH0_PORT_CONFIG_REG+port*ETHERNET_PORTS_DIFFERENCE_OFFSETS);        portControlReg = portControlReg & ~(1 << HASH_DEFUALT_MODE);        portControlReg = portControlReg & ~(1 << HASH_MODE);        portControlReg = portControlReg & ~(1 << HASH_SIZE);        portControlReg = portControlReg |            (hashDefaultMode<<HASH_DEFUALT_MODE) |             (hashMode << HASH_MODE) |             (hashSize << HASH_SIZE);        GT_WRITE(ETH0_PORT_CONFIG_REG+port*ETHERNET_PORTS_DIFFERENCE_OFFSETS, portControlReg);    }    else    {        initAddressTable(port,hashMode,hashSize,hashDefaultMode);    }    /* add all the addresses to the table */    for(i = 0 ; i < numberOfAddresses ; i++)    {        if((addresses[i].skip == 0) & (addresses[i].valid == 1))        {            /* add only the valid and unskipped addresses */            addAddressTableEntry(port,addresses[i].macH,addresses[i].macL,addresses[i].rd,addresses[i].skip);        }    }    return 0;}/****************************************************************************** * boolean_t addressTableClear(int port)* * This function will clear the address table  * Inputs* port - ETHERNET port number.* Outputs* address table is clear.* TRUE if success.* FALSE if fail to make the assignment.*/boolean_t addressTableClear(int port){unsigned int hashLengh[NUM_ETH_PORTS];    hashLengh[0] = EIGHT_K;     hashLengh[1] = HALF_K;    memset((void*)addressTableBase[port],0,hashLengh[addressTableHashSize[port]]*MAC_ENTRY_SIZE);    return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -