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

📄 drivers_net_arm_ep93xx_eth_c_diff.htm

📁 linux2.6.11.6drivers_net_arm_ep93xx_eth_c
💻 HTM
📖 第 1 页 / 共 5 页
字号:
+}/*_phy_write()*/
+
+/*****************************************************************************
+* _phy_read()
+*****************************************************************************/
+static u16 _phy_read(struct net_device *pD, int idPhy, int reg)
+{
+	u16 dt;
+
+/*    _PRTK_ENTRY(("_phy_read(pD:0x%p,idPhy:%d,reg:0x%x)\n",pD,idPhy,reg)); */
+
+	phy_waitRdy();
+	RegWr32(REG_MIICmd,
+		MIICmd_OP_RD | ((idPhy & 0x1f) << 5) | ((reg & 0x1f) << 0));
+	phy_waitRdy();
+	dt = (unsigned short)RegRd32(REG_MIIData);
+
+/*    _PRTK_INFO(("_phy_read(): read 0x%x\n",dt));*/
+
+	return dt;
+}/*_phy_read()*/
+
+#ifndef _PRTK_DUMP
+#define _dbg_phy_dumpReg(pD)
+#else
+/*****************************************************************************
+* _dbg_phy_dumpReg()
+*****************************************************************************/
+static void _dbg_phy_dumpReg(struct net_device *pD)
+{
+	_PRTK_DUMP(("Dumping registers of Ethernet PHY\n"));
+	_PRTK_DUMP((" pD:0x%p, Eth Base Address:0x%x\n", pD,
+		    (unsigned int)pD->base_addr));
+
+	_PRTK_DUMP((" 0-3:0x%04x 0x%04x  0x%04x 0x%04x\n",
+		    phy_rd(0), phy_rd(1), phy_rd(2), phy_rd(3)));
+	_PRTK_DUMP((" 4-6:0x%04x 0x%04x  0x%04x\n",
+		    phy_rd(4), phy_rd(5), phy_rd(6)));
+	_PRTK_DUMP((" 16-19:0x%04x 0x%04x  0x%04x  0x%04x\n",
+		    phy_rd(16), phy_rd(17), phy_rd(18), phy_rd(19)));
+	_PRTK_DUMP((" 20:0x%04x\n", phy_rd(20)));
+}/*_dbg_phy_dumpReg()*/
+#endif				/*ifndef _PRTK_DUMP else */
+
+/*****************************************************************************
+* phy_autoNegotiation()
+*****************************************************************************/
+static int phy_autoNegotiation(struct net_device *pD)
+{
+	u16 val;
+	u16 oldVal;
+	u16 count = 0;
+
+	phy_wr(4, 0x01e1);	/* Set 802.3, 100M/10M Full/Half ability */
+	phy_wr(0, (1 << 12) | (1 << 9));	/* enable auto negotiation */
+	while (1) {
+		val = phy_rd(1);	/* read BM status Reg */
+		if (val & 0x0020) {	/* if Auto_Neg_complete? */
+			break;
+		} else {
+			if (count >= 3)
+				return -1;
+			mdelay(1000);	/* delay 1 second. */
+			count++;
+		}
+	}
+
+	/* CS8952 PHY needs the delay.  Otherwise it won't send the 1st frame. */
+	mdelay(1000);		/* delay 1 second. */
+
+	val = phy_rd(5);	/* read ANLPAR Reg */
+	if (val & 0x0140) {	/* if 100M_FDX or 10M_FDX? */
+		oldVal = RegRd16(REG_TestCTL);
+		/* Enable MAC's Full Duplex mode. */
+		RegWr16(REG_TestCTL, oldVal | TestCTL_MFDX);
+		/* printk("ep93xx_eth(): set MAC to Full Duplex mode\n"); */
+	} else {
+		/* printk("ep93xx_eth(): set MAC to Half Duplex mode\n"); */
+	}
+	/* TODO PJJ-added to get rid of _dbg_phy_dumpReg be sure returning zero is ok. */
+	gPhyAutoNegoDone = 1;
+	return 0;
+}
+
+/*****************************************************************************
+* phy_init()
+*****************************************************************************/
+static int phy_init(struct net_device *pD)
+{
+	u32 oldVal;
+	int status = -1;
+	u16 val;
+
+	_PRTK_ENTRY(("phy_init(pD:0x%x)\n", (unsigned int)pD));
+
+	oldVal = RegRd32(REG_SelfCTL);
+	RegWr32(REG_SelfCTL, 0x0e00);	/*Set MDC clock to be divided by 8
+					   and disable PreambleSuppress bit */
+
+	val = phy_rd(1);	/* read BM status Reg; Link Status Bit remains cleared
+				   until the Reg is read. */
+	val = phy_rd(1);	/* read BMStaReg again to get the current link status */
+	if (val & 0x0004) {	/* if Link Status == established? */
+		status = phy_autoNegotiation(pD);
+	}
+
+	RegWr32(REG_SelfCTL, oldVal);	/*restore the old value */
+
+	return status;
+}				/*phy_init() */
+
+/*****************************************************************************
+* phy_reset()
+*****************************************************************************/
+#if 0
+static int phy_reset(struct net_device *pD)
+{
+	int i;
+
+	_PRTK_ENTRY(("phy_reset(pD:0x%p)\n", pD));
+
+	phy_wr(0, 1 << 15);	/*reset PHY */
+	for (i = 0; i < 1000; i++)
+		if (0 == ((1 << 15) & phy_rd(0)))
+			break;
+	if (0 != ((1 << 15) & phy_rd(0))) {
+		_PRTK_HWFAIL(("phy_reset(): PHY reset does not self-clear\n"));
+		return -1;
+	}
+	/*if */
+	phy_wr(19, 0x00);	/*@ override default value from H/W pin that is not correct */
+	phy_wr(4, (1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (0x01 << 0));	/*advertise 100/10M full/half */
+	phy_wr(0, (1 << 12) | (1 << 9));	/*enable auto negotiation */
+
+	return 0;
+}				/*phy_reset() */
+#endif
+
+#ifndef _PRTK_DUMP
+# define _dbg_ep9312Eth_dumpQueues(pD)
+#else
+/*****************************************************************************
+* _dbg_ep9312Eth_dumpQueues()
+*****************************************************************************/
+static void _dbg_ep9312Eth_dumpQueues(struct net_device *pD)
+{
+
+	int i;
+
+	_PRTK_DUMP(("Dumping Descriptor/Status Queues\n"));
+	_PRTK_DUMP((" pD:0x%p, Base Address:0x%x\n", pD,
+		    (unsigned int)pD->base_addr));
+
+	_PRTK_DUMP((" o Rx Status Queue: at 0x%p, %d entries\n",
+		    pP->s.pQueRxSts, LEN_QueRxSts));
+	for (i = 0; i < LEN_QueRxSts; i++)
+		_PRTK_DUMP(("  - %2d: 0x%08x 0x%08x \n",
+			    i, (unsigned int)pP->s.pQueRxSts[i].w.e0,
+			    (unsigned int)pP->s.pQueRxSts[i].w.e1));
+
+	_PRTK_DUMP((" o Rx Descriptor Queue: at 0x%p, %d entries\n",
+		    pP->s.pQueRxDesc, LEN_QueRxDesc));
+	for (i = 0; i < LEN_QueRxDesc; i++)
+		_PRTK_DUMP(("  - %2d: 0x%08x 0x%08x \n",
+			    i, (unsigned int)pP->s.pQueRxDesc[i].w.e0,
+			    (unsigned int)pP->s.pQueRxDesc[i].w.e1));
+
+	_PRTK_DUMP((" o Tx Status Queue: at 0x%p, %d entries\n",
+		    pP->s.pQueTxSts, LEN_QueTxSts));
+	for (i = 0; i < LEN_QueTxSts; i++)
+		_PRTK_DUMP(("  - %2d: 0x%08x \n", i,
+			    (unsigned int)pP->s.pQueTxSts[i].w.e0));
+
+	_PRTK_DUMP((" o Tx Descriptor Queue: at 0x%p, %d entries\n",
+		    pP->s.pQueTxDesc, LEN_QueTxDesc));
+	for (i = 0; i < LEN_QueTxDesc; i++)
+		_PRTK_DUMP(("  - %2d: 0x%08x 0x%08x \n",
+			    i, (unsigned int)pP->s.pQueTxDesc[i].w.e0,
+			    (unsigned int)pP->s.pQueTxDesc[i].w.e1));
+}/*_dbg_ep9312Eth_dumpQueues()*/
+#endif				/*ifndef _PRTK_DUMP else */
+
+/*****************************************************************************
+* devQue_start()
+*
+  make descriptor queues active
+  allocate queue entries if needed
+  and set device registers up to make it operational
+  assume device has been initialized
+* 
+*****************************************************************************/
+static int devQue_start(struct net_device *pD)
+{
+	int err;
+	struct ep93xxEth_info *pP = netdev_priv(pD);
+	int i;
+	void *pBuf;
+	u32 phyA;
+
+	_PRTK_ENTRY(("devQue_start(pD:0x%p)\n", pD));
+
+	/*turn off device bus mastering */
+	RegWr32(REG_BMCtl, BMCtl_RxDis | BMCtl_TxDis | RegRd32(REG_BMCtl));
+	err = waitOnReg32(pD, REG_BMSts, BMSts_TxAct, ~BMSts_TxAct, 1);
+	err |= waitOnReg32(pD, REG_BMSts, BMSts_RxAct, ~BMSts_RxAct, 1);
+	if (err)
+		_PRTK_HWFAIL(("devQue_start(): BM does not stop\n"));
+
+	/*if */
+	/*Tx Status Queue */
+	memset(pP->s.pQueTxSts, 0, sizeof(pP->s.pQueTxSts[0]) * LEN_QueTxSts);	/*clear status */
+	pP->d.idxQueTxSts = 0;	/*init index */
+	RegWr32(REG_TxSBA, pP->s.phyQueTxSts);	/*base addr */
+	RegWr32(REG_TxSCA, pP->s.phyQueTxSts);	/*current addr */
+	RegWr16(REG_TxSBL, sizeof(pP->s.pQueTxSts[0]) * LEN_QueTxSts);	/*base len */
+	RegWr16(REG_TxSCL, sizeof(pP->s.pQueTxSts[0]) * LEN_QueTxSts);	/*current len */
+
+	/*Tx Descriptor Queue */
+	memset(pP->s.pQueTxDesc, 0, sizeof(pP->s.pQueTxDesc[0]) * LEN_QueTxDesc);	/*clear descriptor */
+	pP->d.idxQueTxDescHead = pP->d.idxQueTxDescTail = 0;	/*init index */
+	RegWr32(REG_TxDBA, pP->s.phyQueTxDesc);	/*base addr */
+	RegWr32(REG_TxDCA, pP->s.phyQueTxDesc);	/*current addr */
+	RegWr16(REG_TxDBL, sizeof(pP->s.pQueTxDesc[0]) * LEN_QueTxDesc);	/*base len */
+	RegWr16(REG_TxDCL, sizeof(pP->s.pQueTxDesc[0]) * LEN_QueTxDesc);	/*current len */
+
+	/*Rx Status Queue */
+	memset(pP->s.pQueRxSts, 0, sizeof(pP->s.pQueRxSts[0]) * LEN_QueRxSts);	/*clear status */
+	pP->d.idxQueRxSts = 0;	/*init index */
+	RegWr32(REG_RxSBA, pP->s.phyQueRxSts);	/*base addr */
+	RegWr32(REG_RxSCA, pP->s.phyQueRxSts);	/*current addr */
+	RegWr16(REG_RxSBL, sizeof(pP->s.pQueRxSts[0]) * LEN_QueRxSts);	/*base len */
+	RegWr16(REG_RxSCL, sizeof(pP->s.pQueRxSts[0]) * LEN_QueRxSts);	/*current len */
+
+	/*Rx Descriptor Queue */
+	memset(pP->s.pQueRxDesc, 0, sizeof(pP->s.pQueRxDesc[0]) * LEN_QueRxDesc);	/*clear descriptor */
+	phyA = pP->s.phyRxBuf;
+	for (i = 0; i < LEN_QueRxDesc; i++) {
+		pP->s.pQueRxDesc[i].f.bi = i;	/*Rx Buffer Index */
+		pP->s.pQueRxDesc[i].f.ba = phyA;	/*physical address of Rx Buf */
+		pP->s.pQueRxDesc[i].f.bl = LEN_RxBuf;	/*Rx Buffer Length */
+		phyA += (LEN_RxBuf + 3) & ~0x03;
+	}			/*for */
+	pP->d.idxQueRxDesc = 0;	/*init index */
+	RegWr32(REG_RxDBA, pP->s.phyQueRxDesc);	/*base addr */
+	RegWr32(REG_RxDCA, pP->s.phyQueRxDesc);	/*current addr */
+	RegWr16(REG_RxDBL, sizeof(pP->s.pQueRxDesc[0]) * LEN_QueRxDesc);	/*base len */
+	RegWr16(REG_RxDCL, sizeof(pP->s.pQueRxDesc[0]) * LEN_QueRxDesc);	/*current len */
+
+	/*init Rx Buffer Descriptors */
+	pBuf = pP->s.pRxBuf;
+	for (i = 0; i < LEN_QueRxDesc; i++) {
+		pP->s.pRxBufDesc[i].vaddr = pBuf;	/*system address of buffer */
+		pP->s.pRxBufDesc[i].pFreeRtn = NULL;	/*no freeing after use */
+		pBuf += (LEN_RxBuf + 3) & ~0x03;
+	}			/*for */
+
+	/*init Tx Buffer Descriptors */
+	memset(pP->s.pTxBufDesc, 0x0,
+	       sizeof(*pP->s.pTxBufDesc) * LEN_QueTxDesc);
+	pP->s.pTxBuf = &gTxDataBuff[0][0];
+	for (i = 0; i < LEN_QueTxDesc; i++) {
+		pP->s.pTxBufDesc[i].vaddr = &gTxDataBuff[i][0];	/*system address of buffer */
+		pP->s.pTxBufDesc[i].pFreeRtn = NULL;	/*no freeing after use */
+	}			/*for */
+
+	/*turn on device bus mastering */
+	RegWr32(REG_BMCtl, BMCtl_TxEn | BMCtl_RxEn | RegRd32(REG_BMCtl));
+	err =
+	    waitOnReg32(pD, REG_BMSts, BMSts_TxAct | BMSts_TxAct,
+			BMSts_TxAct | BMSts_TxAct, 1);
+	if (err)
+		_PRTK_HWFAIL(("devQue_start(): BM does not start\n"));
+
+	/*if */
+	/*Enqueue whole entries; this must be done after BM activation */
+	RegWr32(REG_RxSEQ, LEN_QueRxSts);	/*Rx Status Queue */
+	RegWr32(REG_RxDEQ, LEN_QueRxDesc);	/*Rx Descriptor queue */
+
+	return 0;
+}				/*devQue_start() */
+
+/*****************************************************************************
+* devQue_init()
+  init device descriptor queues at system level
+  device access is not recommended at this point
+* 
+*****************************************************************************/
+static int devQue_init(struct net_device *pD)
+{
+	struct ep93xxEth_info *pP = netdev_priv(pD);
+	void *pBuf;
+	int size;
+
+	_PRTK_ENTRY(("devQue_init(pD:0x%x)\n", (unsigned int)pD));
+
+	/*verify device Tx/Rx Descriptor/Status Queue data size */
+	if (8 != sizeof(union receiveDescriptor)) {
+		_PRTK_SWERR(("devQue_init(): size of receiveDescriptor is not 8 bytes!!!\n"));
+		return -1;
+	} else if (8 != sizeof(union receiveStatus)) {
+		_PRTK_SWERR(("devQue_init(): size of receiveStatus is not 8 bytes!!!\n"));
+		return -1;
+	} else if (8 != sizeof(union transmitDescriptor)) {
+		_PRTK_SWERR(("devQue_init(): size of transmitDescriptor is not 8 bytes!!!\n"));
+		return -1;
+	} else if (4 != sizeof(union transmitStatus)) {
+		_PRTK_SWERR(("devQue_init(): size of transmitStatus is not 4 bytes!!!\n"));
+		return -1;
+	}
+
+	/*else */
+	/*
+	   allocate kernel memory for whole queues
+	   best if non-cached memory block due to DMA access by the device
+	   if CPU doesn't have bus snooping
+	 */
+	size = sizeof(union receiveDescriptor) * (LEN_QueRxDesc + 1) +
+	    sizeof(union receiveStatus) * (LEN_QueRxSts + 1) +
+	    sizeof(union transmitDescriptor) * (LEN_QueTxDesc + 1) +
+	    sizeof(union transmitStatus) * (LEN_QueTxSts + 1) +
+	    sizeof(unsigned long) * 4;
+
+	pBuf = MALLOC_DMA(size, &pP->s.phyQueueBase);	/*request memory allocation */
+	if (!pBuf) {
+		_PRTK_SYSFAIL(("devQue_initAll(): fail to allocate memory for queues\n"));
+		return -1;
+	}
+
+	/*if */
+	/*
+	   assign memory to each queue
+	 */
+	pP->s.pQueRxDesc = (void *)Align32(pBuf);
+	pBuf =
+	    (char *)pBuf + sizeof(union receiveDescriptor) * (LEN_QueRxDesc +
+							      1);
+	pP->s.pQueRxSts = (void *)Align32(pBuf);
+	pBuf = (char *)pBuf + sizeof(union receiveStatus) * (LEN_QueRxSts + 1);
+	pP->s.pQueTxDesc = (void *)Align32(pBuf);
+	pBuf =
+	    (char *)pBuf + sizeof(union transmitDescriptor) * (LEN_QueTxDesc +
+							       1);
+	pP->s.pQueTxSts = (void *)Align32(pBuf);
+	pBuf = (char *)pBuf + sizeof(union transmitStatus) * (LEN_QueTxSts + 1);
+
+	/*
+	   store physical address of each queue
+	 */
+	pP->s.phyQueRxDesc = Align32(pP->s.phyQueueBase);
+	pP->s.phyQueRxSts =
+	    pP->s.phyQueRxDesc + ((u32) pP->s.pQueRxSts -
+				  (u32) pP->s.pQueRxDesc);
+	pP->s.phyQueTxDesc =
+	    pP->s.phyQueRxDesc + ((u32) pP->s.pQueTxDesc -
+				  (u32) pP->s.pQueRxDesc);
+	pP->s.phyQueTxSts =
+	    pP->s.phyQueRxDesc + ((u32) pP->s.pQueTxSts -
+				  (u32) pP->s.pQueRxDesc);
+

⌨️ 快捷键说明

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