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

📄 sl_lepus_gmac.c

📁 某个ARM9板子的实际bootloader 对裁剪
💻 C
📖 第 1 页 / 共 4 页
字号:
	//if (total_len > GMAC_MAX_ETH_FRAME_SIZE || !sg_len || !sg_list->buf)	if (total_len > GMAC_MAX_ETH_FRAME_SIZE)	{		// too long		isPtr->tx_dropped++;		//eth_drv_tx_done(sc,key,-EINVAL);    	return;    }        	// Select TX Queue   	tx_qid = 0;	swtxq = &tp->swtxq[tx_qid];  //  cyg_drv_mutex_lock((cyg_drv_mutex_t *)tp->tx_mutex);   	// if (wptr + 1) == (rptr), then cannot send    rwptr.bits32 = readl(swtxq->rwptr_reg);    // if (RWPTR_ADVANCE_ONE(rwptr.bits.wptr, swtxq->total_desc_num) == rwptr.bits.rptr)	// check finished desc or empty BD	// cannot check by read ptr of RW PTR register, 	// because the HW complete to send but the SW may NOT handle it	if (rwptr.bits.wptr >= rwptr.bits.rptr)		free_desc = swtxq->total_desc_num - rwptr.bits.wptr - 1 + rwptr.bits.rptr;	else 		free_desc = rwptr.bits.rptr - rwptr.bits.wptr - 1;	if (!free_desc)	{		//cyg_drv_mutex_unlock((cyg_drv_mutex_t *)tp->tx_mutex);		isPtr->tx_dropped++;		//eth_drv_tx_done(sc,key,-EINVAL);		printk("Stop here due to no available descriptor!\n");		while(1);    	return;    }#if 0	for (i=0; i<1; i++)	{		int wptr, rptr;				wptr = rwptr.bits.wptr;		rptr = rwptr.bits.rptr;		if (wptr == rptr)			break;		wptr = RWPTR_ADVANCE_ONE(wptr, swtxq->total_desc_num);		if (wptr == rptr)		{			//cyg_drv_mutex_unlock((cyg_drv_mutex_t *)tp->tx_mutex);			isPtr->tx_dropped++;			//eth_drv_tx_done(sc,key,-EINVAL);			while(1);    		return;		}	}#endif    curr_desc = (GMAC_TXDESC_T *)swtxq->desc_base + rwptr.bits.wptr;	//hal_cache_consistent_sync(curr_desc, sizeof(GMAC_TXDESC_T), PCI_DMA_FROMDEVICE);/*    #if (GMAC_DEBUG==1)    // if curr_desc->word2.buf_adr !=0 means that the ISR does NOT handle it    // if (curr_desc->word2.buf_adr)    if (swtxq->tx_skb[rwptr.bits.wptr])    {    	printk("Error! TX descriptor's buffer is not freed!\n");    	dev_kfree_skb(swtxq->tx_skb[rwptr.bits.wptr]);    	swtxq->tx_skb[rwptr.bits.wptr] = NULL;    }#endif*/		// called by eCOS Ethernet I/O	//skb = (struct sk_buff *)dev_alloc_skb(total_len);	//if (!skb)	//{	//	isPtr->tx_dropped++;	//	goto send_end;	//}	//tx_buf_adr = skb->data;	//skb->len = total_len;	//while (sg_len)	//{	//	memcpy(tx_buf_adr,(unsigned char*)sg_list->buf,sg_list->len);	//	tx_buf_adr += sg_list->len;	//	++sg_list;	//	--sg_len;	//}	if (mac_dump_txpkt)	{		printf("\nGMAC %d TxQid = %d Tx (Size = %d):\n", tp->port_id, tx_qid, total_len);		dm_byte((u32)bufp, (total_len > 64) ? 64 : total_len);	}	   	swtxq->total_sent++;	//swtxq->tx_skb[rwptr.bits.wptr] = skb;			/* set TX descriptor */	/* copy packet to descriptor buffer address */	curr_desc->word0.bits32 = 0;	curr_desc->word0.bits.buffer_size = total_len;    /* total frame byte count */	curr_desc->word1.bits32 = 0;	curr_desc->word1.bits.udp_chksum = 1;//skb->hw_udp_chksum;	curr_desc->word1.bits.tcp_chksum = 1;//skb->hw_tcp_chksum;	curr_desc->word1.bits.ip_chksum = 1;//skb->hw_ip_chksum;	curr_desc->word1.bits.ipv6_enable = 1;//skb->ipv6_enable;	curr_desc->word1.bits.mtu_enable = 0;//skb->mtu_enable;	curr_desc->word1.bits.byte_count = total_len;	//if(curr_desc->word2.buf_adr==NULL)	//{		memcpy((unsigned char *)(txbuf_ptr[rwptr.bits.wptr]), bufp, total_len);		curr_desc->word2.buf_adr = (unsigned int)txbuf_ptr[rwptr.bits.wptr]; //skb->data;	//}		curr_desc->word3.bits32 = 0;	curr_desc->word3.bits.sof_eof = 3;	curr_desc->word3.bits.eofie = 1;	curr_desc->word3.bits.mtu_size = 1500;//(skb->mtu_size) ? skb->mtu_size : 1500;   	swtxq->tx_curr_desc = curr_desc; 		//hal_cache_consistent_sync(skb->data, total_len, PCI_DMA_TODEVICE);	//hal_cache_consistent_sync(curr_desc, sizeof(GMAC_TXDESC_T), PCI_DMA_TODEVICE);		// Share Pin issue	//HAL_LOCK_SHARE_PIN();	SET_WPTR(swtxq->rwptr_reg, RWPTR_ADVANCE_ONE(rwptr.bits.wptr, swtxq->total_desc_num));	//HAL_UNLOCK_SHARE_PIN();	send_end:	//cyg_drv_mutex_unlock((cyg_drv_mutex_t *)tp->tx_mutex);		//eth_drv_tx_done(sc, key, 0);;	}//static int __init gmac_init_module(void)int toe_gmac_sl2312_init(void){	int 		i;	TOE_INFO_T	*toe;	unsigned long data,val;		mac_dump_rxpkt = 0;	mac_dump_txpkt = 0;		if (!gmac_initialized)	{		gmac_initialized = 1;		if(SPI_get_identifier())		{			gmac_num = 1;			SPI_default();		}		else			gmac_num = 0;			#ifdef LEPUS_ASIC				/* set GMAC global register */		val = REG32(SL2312_GLOBAL_BASE+0x10);    	val = val | 0x005f0000;    	REG32(SL2312_GLOBAL_BASE+0x10)=val;    	if(gmac_num)    		REG32(SL2312_GLOBAL_BASE+0x1c)=0x5787a7f0;    	else    		REG32(SL2312_GLOBAL_BASE+0x1c)=0xa7f0a7f0;    	REG32(SL2312_GLOBAL_BASE+0x20)=0x77777777;    	REG32(SL2312_GLOBAL_BASE+0x24)=0x77777777;    	REG32(SL2312_GLOBAL_BASE+0x2c)=0x09200030;    	//if(gmac_num)    	{    		val = readl(SL2312_GLOBAL_BASE+0x04);			if((val&(1<<20))==0){           // GMAC1 enable 				val = readl(SL2312_GLOBAL_BASE+0x30);				val = (val & 0xe7ffffff) | 0x08000000;				writel(val,SL2312_GLOBAL_BASE+0x30);			}		}#endif					// init private data		toe = (TOE_INFO_T *)&toe_private_data;		memset((void *)toe, 0, sizeof(TOE_INFO_T));				if(gmac_num)		{			//printf("gmac_num : %x\n",gmac_num);			toe->gmac.base_addr = TOE_GMAC1_BASE; //TOE_GMAC0_BASE;			toe->gmac.dma_base_addr = TOE_GMAC1_DMA_BASE;//TOE_GMAC0_DMA_BASE;			toe->gmac.auto_nego_cfg = 1;//cfg_get_mac_auto_nego(0);#ifdef LEPUS_ASIC			        	toe->gmac.speed_cfg = GMAC_SPEED_1000;        	toe->gmac.phy_mode = GMAC_PHY_RGMII_1000;//GMAC_PHY_MII;#else			toe->gmac.speed_cfg = GMAC_SPEED_100;			toe->gmac.phy_mode = GMAC_PHY_RGMII_100;//GMAC_PHY_MII;#endif           	toe->gmac.full_duplex_cfg = 1;        	//toe->gmac.phy_mode = GMAC_PHY_RGMII_1000;//GMAC_PHY_RGMII_100;//GMAC_PHY_MII;        	toe->gmac.port_id = GMAC_PORT1;//GMAC_PORT0;        	toe->gmac.phy_id = 1;//0;        	toe->gmac.phy_addr = 2;//0x11;        	toe->gmac.irq = SL2312_INTERRUPT_GMAC1;//SL2312_INTERRUPT_GMAC0;        	memcpy(toe->gmac.mac_addr1, sys_get_mac_addr(1), ETHER_ADDR_LEN);        	        				// check GMAC 0/1 existed on not	//		for (i=0; i<gmac_num; i++)	//		{				gmac_write_reg(toe->gmac.base_addr, GMAC_STA_ADD2, 0x55aa55aa, 0xffffffff);				data = gmac_read_reg(toe->gmac.base_addr, GMAC_STA_ADD2);				if (data == 0x55aa55aa)					toe->gmac.existed = GMAC_EXISTED_FLAG;	//		}		}		else		{			toe->gmac.base_addr = TOE_GMAC0_BASE; //TOE_GMAC0_BASE;			toe->gmac.dma_base_addr = TOE_GMAC0_DMA_BASE;//TOE_GMAC0_DMA_BASE;			toe->gmac.auto_nego_cfg = 1;//cfg_get_mac_auto_nego(0);#ifdef LEPUS_ASIC			        	toe->gmac.speed_cfg = GMAC_SPEED_1000;        	toe->gmac.phy_mode = GMAC_PHY_RGMII_1000;//GMAC_PHY_MII;#else			toe->gmac.speed_cfg = GMAC_SPEED_100;			toe->gmac.phy_mode = GMAC_PHY_RGMII_100;//GMAC_PHY_MII;#endif           	toe->gmac.full_duplex_cfg = 1;        	toe->gmac.port_id = GMAC_PORT0;//GMAC_PORT0;        	toe->gmac.phy_id = 0;//0;        	toe->gmac.phy_addr = 0x1;//1;//0x11;        	toe->gmac.irq = SL2312_INTERRUPT_GMAC0;//SL2312_INTERRUPT_GMAC0;        	memcpy(toe->gmac.mac_addr1, sys_get_mac_addr(0), ETHER_ADDR_LEN);        	        				// check GMAC 0/1 existed on not	//		for (i=0; i<GMAC_NUM; i++)	//		{				gmac_write_reg(toe->gmac.base_addr, GMAC_STA_ADD2, 0x55aa55aa, 0xffffffff);				data = gmac_read_reg(toe->gmac.base_addr, GMAC_STA_ADD2);				if (data == 0x55aa55aa)					toe->gmac.existed = GMAC_EXISTED_FLAG;	//		}		}			//FLAG_SWITCH = 0;		toe_gmac_sw_reset();		toe_init_free_queue();		toe_init_swtx_queue();		//toe_init_hwtx_queue();		toe_init_default_queue();		//toe_init_toe_queue();		//toe_init_class_queue();		//toe_init_interrupt_queue();		//toe_init_interrupt_config();						// Write GLOBAL_QUEUE_THRESHOLD_REG		// TBD				if (toe->gmac.existed)			toe_init_gmac(&toe->gmac);					}	//printf("toe->gmac.port_id : %x\n",toe->gmac.port_id);	    return TRUE;}	/*----------------------------------------------------------------------*	toe_init_gmac*----------------------------------------------------------------------*/bool toe_init_gmac(GMAC_INFO_T *tp){		TOE_INFO_T				*toe;	struct ether_drv_stats	*isPtr = (struct ether_drv_stats *)&tp->ifStatics;		if (!gmac_initialized)		return TRUE;			//tp->ndt = (void *)tab;	//tp->sc = sc;	//tp->flow_control_enable = 1;	tp->pre_phy_status = LINK_DOWN;	tp->full_duplex_status = tp->full_duplex_cfg;	tp->speed_status = tp->speed_status;	//cyg_drv_mutex_init((cyg_drv_mutex_t *)&tx_mutex[tp->port_id]);	//tp->tx_mutex = (void *)&tx_mutex[tp->port_id];    /* set PHY register to start autonegition process */    gmac_set_phy_status(tp);	//tp->flow_control_enable = 1;	/* GMAC initialization */	if ( toe_gmac_init_chip(tp) ) 	{		printk ("GMAC %d init fail\n", tp->port_id);	}	    /* allocates tx/rx descriptor and buffer memory */    /* enable tx/rx register */        toe_gmac_enable_tx_rx();        /* clear statistic counter */    toe_gmac_clear_counter(tp);		memset((void *)&tp->ifStatics, 0, sizeof(struct ether_drv_stats));	isPtr->duplex = 3;	isPtr->speed = 100000000;	isPtr->rx_resource = gmac_num ? 						  TOE_DEFAULT_Q1_DESC_NUM : TOE_DEFAULT_Q0_DESC_NUM;	isPtr->tx_queue_len = tp->swtxq[0].total_desc_num;	strcpy(isPtr->description, LEPUS_DRIVER_NAME);	strcpy(isPtr->snmp_chipset, DRV_NAME);	/* -----------------------------------------------------------	Enable GMAC interrupt & disable loopback 	Notes:		GMACx init routine (for eCOS) or open routine (for Linux)		enable the interrupt bits only which are selected for him.	--------------------------------------------------------------*/	toe = (TOE_INFO_T *)&toe_private_data;		// Enable Interrupt Bits	if (tp->port_id == 0)	{		tp->intr0_enabled = tp->intr0_selected = ~toe->intr0_select.bits32;		tp->intr1_enabled = tp->intr1_selected = ~toe->intr1_select.bits32;		tp->intr2_enabled = tp->intr2_selected = ~toe->intr2_select.bits32;		tp->intr3_enabled = tp->intr3_selected = ~toe->intr3_select.bits32;		tp->intr4_enabled = tp->intr4_selected = ~toe->intr4_select.bits32;			}	else	{		tp->intr0_enabled = tp->intr0_selected = toe->intr0_select.bits32;		tp->intr1_enabled = tp->intr1_selected = toe->intr1_select.bits32;		tp->intr2_enabled = tp->intr2_selected = toe->intr2_select.bits32; 		tp->intr3_enabled = tp->intr3_selected = toe->intr3_select.bits32; 		tp->intr4_enabled = tp->intr4_selected = toe->intr4_select.bits32; 	}		// enable only selected bits	gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_0_REG, 					tp->intr0_enabled, tp->intr0_selected);	gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_1_REG, 					tp->intr1_enabled, tp->intr1_selected);	gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_2_REG, 					tp->intr2_enabled, tp->intr2_selected);	gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_3_REG, 					tp->intr3_enabled, tp->intr3_selected);	gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_4_REG, 					tp->intr4_enabled, tp->intr4_selected);	// Level Trigger, Actiev HIGH	//hal_interrupt_configure(tp->irq, 1, 1);	//cyg_drv_interrupt_create(tp->irq,	//						 0,	//						 (unsigned int)sc,	//						 toe_gmac_isr,	//						 eth_drv_dsr,	//						 &intr_handle[tp->port_id],	//						 &intr_object[tp->port_id]);  	//cyg_drv_interrupt_attach(intr_handle[tp->port_id]);    /* start DMA process */    if (tp->existed)    {		toe_gmac_hw_start(tp);		//toe_gmac_enable_interrupt(tp->irq);		//	eth_drv_init(sc, tp->mac_addr1);	}	tp->flow_control_enable = 1;    return TRUE;}	#endif // LEPUS_FPGA

⌨️ 快捷键说明

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