天天看點

88E6390端口Link問題BUG解決

Marvell 88E6390是一款11端口全千兆以太網二層交換晶片,是一款較新的産品,晶片有原廠級别的BUG。我們的裝置以交換晶片1port-8配置為千兆電口,port9-10千兆光口。光口在打包(滿速率很快,低速時間較長,跟封包的總數有關系)一段時候之後拔掉網線,端口的狀态仍然為Link,led燈閃爍,跟沒有拔出網線端口的狀态一樣。溝通原廠給了解決方案,這裡分享出來,希望能夠幫助大家。

原廠的建議是在系統初始化的時候做如下配置:

88E6390端口Link問題BUG解決

 按照原廠這個建議在初始化qdStart();初始化之做上述的配置時序代碼如下;

/* load marvell chip driver */
    qdStart(gDevCpuPort, 0);

    /*init port patch ,[email protected]*/
    init_each_port();
           

配置時序代碼:

/*init port patch,[email protected],*/
void init_each_port()
{
	int port;
	int buf;
	
	/*step1:portstate for each port to be configured to disable
	*Port register 4 [1:0] = 0x0
	*/
	for(port=1;port <= MAX_PORT_NUM; port++)
	{
		readPort(port,0x4,&buf);
		buf &= 0xfffc;
		//printf("%s %s %d: buf=0x%04x\r\n",__FILE__,__FUNCTION__,__LINE__,buf);//[email protected],test
		writePort(port,0x4,buf);
	}

	/*step2:
	*For Port 9:
	*	Swith Port 5 register 0x1A = 0x01C0
	*	Swith Port 4 register 0x1A = 0xFD20
	*/
	writePort(0x5,0x1a,0x01C0);
	writePort(0x4,0x1a,0xFD20);
	
	/*step3:
	For Port 10:
	*	Swith Port 5 register 0x1A = 0x01C0
	*	Swith Port 4 register 0x1A = 0xFD40
	*/
	writePort(0x5,0x1a,0x01C0);
	writePort(0x4,0x1a,0xFD40);
	
	/*step4: Preform a software reset of swtich core:
	*	Global 1 Register 4 .15 = 1
	*/
		readGlobal(0x4,&buf);
		buf |= 0x8000;
		//printf("%s %s %d: buf=0x%04x\r\n",__FILE__,__FUNCTION__,__LINE__,buf);//zh[email protected],test
		writeGlobal(0x4,buf);
		
	/*step5: Change the PortState for each port back to the forwarding state
	*	Port register 4 [1:0] = 0x3
	*/
	for(port=1;port <= MAX_PORT_NUM; port++)
	{
		readPort(port,0x4,&buf);
		buf |= 0x3;
		//printf("%s %s %d: buf=0x%04x\r\n",__FILE__,__FUNCTION__,__LINE__,buf);//zhoulinh[email protected],test
		writePort(port,0x4,buf);
	}
	
	return 0;
}
           

這樣配置之後,光口慢速率打包端口狀态正常了,但是環網測試倒換時間本來是ms級别變成了s級别,檢視中斷沒有上來,讀取交換晶片的DevIntEn(Global 1 offset 0x4)位被置為0,中斷被關閉了。明明qdStart中有如下調用打開了中斷:

/* Enable phy interrupt for port link state changed */
    if((status=QDIntEnable(dev)) != GT_OK)
    {
        MSG_PRINT(("QDIntEnable return Failed\n"));
        return status;
    }
           

猜測可能software rest的時候被清,是以在調用 init_each_port()之後重新調用QDIntEnable(dev))得以解決、

以上是我分享的一點希望能幫到大家。

繼續閱讀