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

📄 fxp.c

📁 minix3.1.1源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	scr= mii_read(fp, MII_SCR);	scr &= ~(MII_SCR_RES|MII_SCR_RES_1);	return (fp->fxp_mii_scr != scr);}/*===========================================================================* *				fxp_report_link				     * *===========================================================================*/static void fxp_report_link(fp)fxp_t *fp;{	port_t port;	u16_t mii_ctrl, mii_status, mii_id1, mii_id2, 		mii_ana, mii_anlpa, mii_ane, mii_extstat,		mii_ms_ctrl, mii_ms_status, scr;	u32_t oui;	int model, rev;	int f, link_up, ms_regs;	/* Assume an 82555 (compatible) PHY. The should be changed for	 * 82557 NICs with different PHYs	 */	ms_regs= 0;	/* No master/slave registers. */	fp->fxp_report_link= FALSE;	port= fp->fxp_base_port;	scr= mii_read(fp, MII_SCR);	scr &= ~(MII_SCR_RES|MII_SCR_RES_1);	fp->fxp_mii_scr= scr;	mii_ctrl= mii_read(fp, MII_CTRL);	mii_read(fp, MII_STATUS); /* Read the status register twice, why? */	mii_status= mii_read(fp, MII_STATUS);	mii_id1= mii_read(fp, MII_PHYID_H);	mii_id2= mii_read(fp, MII_PHYID_L);	mii_ana= mii_read(fp, MII_ANA);	mii_anlpa= mii_read(fp, MII_ANLPA);	mii_ane= mii_read(fp, MII_ANE);	if (mii_status & MII_STATUS_EXT_STAT)		mii_extstat= mii_read(fp, MII_EXT_STATUS);	else		mii_extstat= 0;	if (ms_regs)	{		mii_ms_ctrl= mii_read(fp, MII_MS_CTRL);		mii_ms_status= mii_read(fp, MII_MS_STATUS);	}	else	{		mii_ms_ctrl= 0;		mii_ms_status= 0;	}	/* How do we know about the link status? */	link_up= !!(mii_status & MII_STATUS_LS);	fp->fxp_link_up= link_up;	if (!link_up)	{#if VERBOSE		printf("%s: link down\n", fp->fxp_name);#endif		return;	}	oui= (mii_id1 << MII_PH_OUI_H_C_SHIFT) | 		((mii_id2 & MII_PL_OUI_L_MASK) >> MII_PL_OUI_L_SHIFT);	model= ((mii_id2 & MII_PL_MODEL_MASK) >> MII_PL_MODEL_SHIFT);	rev= (mii_id2 & MII_PL_REV_MASK);#if VERBOSE	printf("OUI 0x%06lx, Model 0x%02x, Revision 0x%x\n", oui, model, rev);#endif	if (mii_ctrl & (MII_CTRL_LB|MII_CTRL_PD|MII_CTRL_ISO))	{		printf("%s: PHY: ", fp->fxp_name);		f= 1;		if (mii_ctrl & MII_CTRL_LB)		{			printf("loopback mode");			f= 0;		}		if (mii_ctrl & MII_CTRL_PD)		{			if (!f) printf(", ");			f= 0;			printf("powered down");		}		if (mii_ctrl & MII_CTRL_ISO)		{			if (!f) printf(", ");			f= 0;			printf("isolated");		}		printf("\n");		return;	}	if (!(mii_ctrl & MII_CTRL_ANE))	{		printf("%s: manual config: ", fp->fxp_name);		switch(mii_ctrl & (MII_CTRL_SP_LSB|MII_CTRL_SP_MSB))		{		case MII_CTRL_SP_10:	printf("10 Mbps"); break;		case MII_CTRL_SP_100:	printf("100 Mbps"); break;		case MII_CTRL_SP_1000:	printf("1000 Mbps"); break;		case MII_CTRL_SP_RES:	printf("reserved speed"); break;		}		if (mii_ctrl & MII_CTRL_DM)			printf(", full duplex");		else			printf(", half duplex");		printf("\n");		return;	}	if (!debug) goto resspeed;	printf("%s: ", fp->fxp_name);	mii_print_stat_speed(mii_status, mii_extstat);	printf("\n");	if (!(mii_status & MII_STATUS_ANC))		printf("%s: auto-negotiation not complete\n", fp->fxp_name);	if (mii_status & MII_STATUS_RF)		printf("%s: remote fault detected\n", fp->fxp_name);	if (!(mii_status & MII_STATUS_ANA))	{		printf("%s: local PHY has no auto-negotiation ability\n",			fp->fxp_name);	}	if (!(mii_status & MII_STATUS_LS))		printf("%s: link down\n", fp->fxp_name);	if (mii_status & MII_STATUS_JD)		printf("%s: jabber condition detected\n", fp->fxp_name);	if (!(mii_status & MII_STATUS_EC))	{		printf("%s: no extended register set\n", fp->fxp_name);		goto resspeed;	}	if (!(mii_status & MII_STATUS_ANC))		goto resspeed;	printf("%s: local cap.: ", fp->fxp_name);	if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD))	{		printf("1000 Mbps: T-");		switch(mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD))		{		case MII_MSC_1000T_FD:	printf("FD"); break;		case MII_MSC_1000T_HD:	printf("HD"); break;		default:		printf("FD/HD"); break;		}		if (mii_ana)			printf(", ");	}	mii_print_techab(mii_ana);	printf("\n");	if (mii_ane & MII_ANE_PDF)		printf("%s: parallel detection fault\n", fp->fxp_name);	if (!(mii_ane & MII_ANE_LPANA))	{		printf("%s: link-partner does not support auto-negotiation\n",			fp->fxp_name);		goto resspeed;	}	printf("%s: remote cap.: ", fp->fxp_name);	if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD))	if (mii_ms_status & (MII_MSS_LP1000T_FD | MII_MSS_LP1000T_HD))	{		printf("1000 Mbps: T-");		switch(mii_ms_status &			(MII_MSS_LP1000T_FD | MII_MSS_LP1000T_HD))		{		case MII_MSS_LP1000T_FD:	printf("FD"); break;		case MII_MSS_LP1000T_HD:	printf("HD"); break;		default:			printf("FD/HD"); break;		}		if (mii_anlpa)			printf(", ");	}	mii_print_techab(mii_anlpa);	printf("\n");	if (ms_regs)	{		printf("%s: ", fp->fxp_name);		if (mii_ms_ctrl & MII_MSC_MS_MANUAL)		{			printf("manual %s",				(mii_ms_ctrl & MII_MSC_MS_VAL) ?				"MASTER" : "SLAVE");		}		else		{			printf("%s device",				(mii_ms_ctrl & MII_MSC_MULTIPORT) ?				"multiport" : "single-port");		}		if (mii_ms_ctrl & MII_MSC_RES)			printf(" reserved<0x%x>", mii_ms_ctrl & MII_MSC_RES);		printf(": ");		if (mii_ms_status & MII_MSS_FAULT)			printf("M/S config fault");		else if (mii_ms_status & MII_MSS_MASTER)			printf("MASTER");		else			printf("SLAVE");		printf("\n");	}	if (mii_ms_status & (MII_MSS_LP1000T_FD|MII_MSS_LP1000T_HD))	{		if (!(mii_ms_status & MII_MSS_LOCREC))		{			printf("%s: local receiver not OK\n",				fp->fxp_name);		}		if (!(mii_ms_status & MII_MSS_REMREC))		{			printf("%s: remote receiver not OK\n",				fp->fxp_name);		}	}	if (mii_ms_status & (MII_MSS_RES|MII_MSS_IDLE_ERR))	{		printf("%s", fp->fxp_name);		if (mii_ms_status & MII_MSS_RES)			printf(" reserved<0x%x>", mii_ms_status & MII_MSS_RES);		if (mii_ms_status & MII_MSS_IDLE_ERR)		{			printf(" idle error %d",				mii_ms_status & MII_MSS_IDLE_ERR);		}		printf("\n");	}resspeed:#if VERBOSE	printf("%s: link up, %d Mbps, %s duplex\n",		fp->fxp_name, (scr & MII_SCR_100) ? 100 : 10,		(scr & MII_SCR_FD) ? "full" : "half");#endif	;}/*===========================================================================* *				fxp_stop				     * *===========================================================================*/static void fxp_stop(){	int i;	port_t port;	fxp_t *fp;	for (i= 0, fp= &fxp_table[0]; i<FXP_PORT_NR; i++, fp++)	{		if (fp->fxp_mode != FM_ENABLED)			continue;		if (!(fp->fxp_flags & FF_ENABLED))			continue;		port= fp->fxp_base_port;		/* Reset device */		if (debug)			printf("%s: resetting device\n", fp->fxp_name);		fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET);	}	sys_exit(0);}/*===========================================================================* *				reply					     * *===========================================================================*/static void reply(fp, err, may_block)fxp_t *fp;int err;int may_block;{	message reply;	int status;	int r;	status = 0;	if (fp->fxp_flags & FF_PACK_SENT)		status |= DL_PACK_SEND;	if (fp->fxp_flags & FF_PACK_RECV)		status |= DL_PACK_RECV;	reply.m_type = DL_TASK_REPLY;	reply.DL_PORT = fp - fxp_table;	reply.DL_PROC = fp->fxp_client;	reply.DL_STAT = status | ((u32_t) err << 16);	reply.DL_COUNT = fp->fxp_read_s;#if 0	reply.DL_CLCK = get_uptime();#else	reply.DL_CLCK = 0;#endif	r= send(fp->fxp_client, &reply);	if (r == ELOCKED && may_block)	{#if 0		printW(); printf("send locked\n");#endif		return;	}	if (r < 0)		panic("FXP","fxp: send failed:", r);		fp->fxp_read_s = 0;	fp->fxp_flags &= ~(FF_PACK_SENT | FF_PACK_RECV);}/*===========================================================================* *				mess_reply				     * *===========================================================================*/static void mess_reply(req, reply_mess)message *req;message *reply_mess;{	if (send(req->m_source, reply_mess) != OK)		panic("FXP","fxp: unable to mess_reply", NO_NUM);}/*===========================================================================* *				put_userdata				     * *===========================================================================*/static void put_userdata(user_proc, user_addr, count, loc_addr)int user_proc;vir_bytes user_addr;vir_bytes count;void *loc_addr;{	int r;	r= sys_vircopy(SELF, D, (vir_bytes)loc_addr,		user_proc, D, user_addr, count);	if (r != OK)		panic("FXP","put_userdata: sys_vircopy failed", r);}/*===========================================================================* *				eeprom_read				     * *===========================================================================*/PRIVATE u16_t eeprom_read(fp, reg)fxp_t *fp;int reg;{	port_t port;	u16_t v;	int b, i, alen;	alen= fp->fxp_ee_addrlen;	if (!alen)	{		eeprom_addrsize(fp);		alen= fp->fxp_ee_addrlen;		assert(alen == 6 || alen == 8);	}	port= fp->fxp_base_port;	fxp_outb(port, CSR_EEPROM, CE_EECS);	/* Enable EEPROM */	v= EEPROM_READ_PREFIX;	for (i= EEPROM_PREFIX_LEN-1; i >= 0; i--)	{		b= ((v & (1 << i)) ? CE_EEDI : 0);		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */		micro_delay(EESK_PERIOD/2+1);		fxp_outb(port, CSR_EEPROM, CE_EECS | b);				micro_delay(EESK_PERIOD/2+1);	}		v= reg;	for (i= alen-1; i >= 0; i--)	{		b= ((v & (1 << i)) ? CE_EEDI : 0);		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */		micro_delay(EESK_PERIOD/2+1);		fxp_outb(port, CSR_EEPROM, CE_EECS | b);				micro_delay(EESK_PERIOD/2+1);	}	v= 0;	for (i= 0; i<16; i++)	{		fxp_outb(port, CSR_EEPROM, CE_EECS | CE_EESK); /* Clock */		micro_delay(EESK_PERIOD/2+1);		b= !!(fxp_inb(port, CSR_EEPROM) & CE_EEDO);		v= (v << 1) | b;		fxp_outb(port, CSR_EEPROM, CE_EECS );				micro_delay(EESK_PERIOD/2+1);	}	fxp_outb(port, CSR_EEPROM, 0);	/* Disable EEPROM */	micro_delay(EECS_DELAY);	return v;}/*===========================================================================* *				eeprom_addrsize				     * *===========================================================================*/PRIVATE void eeprom_addrsize(fp)fxp_t *fp;{	port_t port;	u16_t v;	int b, i;	port= fp->fxp_base_port;	/* Try to find out the size of the EEPROM */	fxp_outb(port, CSR_EEPROM, CE_EECS);	/* Enable EEPROM */	v= EEPROM_READ_PREFIX;	for (i= EEPROM_PREFIX_LEN-1; i >= 0; i--)	{		b= ((v & (1 << i)) ? CE_EEDI : 0);		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */		micro_delay(EESK_PERIOD/2+1);		fxp_outb(port, CSR_EEPROM, CE_EECS | b);				micro_delay(EESK_PERIOD/2+1);	}	for (i= 0; i<32; i++)	{		b= 0;		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */		micro_delay(EESK_PERIOD/2+1);		fxp_outb(port, CSR_EEPROM, CE_EECS | b);				micro_delay(EESK_PERIOD/2+1);		v= fxp_inb(port, CSR_EEPROM);		if (!(v & CE_EEDO))			break;	}	if (i >= 32)		panic("FXP","eeprom_addrsize: failed", NO_NUM);	fp->fxp_ee_addrlen= i+1;	/* Discard 16 data bits */	for (i= 0; i<16; i++)	{		fxp_outb(port, CSR_EEPROM, CE_EECS | CE_EESK); /* Clock */		micro_delay(EESK_PERIOD/2+1);		fxp_outb(port, CSR_EEPROM, CE_EECS );				micro_delay(EESK_PERIOD/2+1);	}	fxp_outb(port, CSR_EEPROM, 0);	/* Disable EEPROM */	micro_delay(EECS_DELAY);#if VERBOSE	printf("%s EEPROM address length: %d\n",		fp->fxp_name, fp->fxp_ee_addrlen);#endif}/*===========================================================================* *				mii_read				     * *===========================================================================*/PRIVATE u16_t mii_read(fp, reg)fxp_t *fp;int reg;{	clock_t t0,t1;	port_t port;	u32_t v;	port= fp->fxp_base_port;	assert(!fp->fxp_mii_busy);	fp->fxp_mii_busy++;	if (!(fxp_inl(port, CSR_MDI_CTL) & CM_READY))		panic("FXP","mii_read: MDI not ready", NO_NUM);	fxp_outl(port, CSR_MDI_CTL, CM_READ | (1 << CM_PHYADDR_SHIFT) |		(reg << CM_REG_SHIFT));	getuptime(&t0);	do {		v= fxp_inl(port, CSR_MDI_CTL);		if (v & CM_READY)			break;	} while (getuptime(&t1)==OK && (t1-t0) < MICROS_TO_TICKS(100000));	if (!(v & CM_READY))		panic("FXP","mii_read: MDI not ready after command", NO_NUM);	fp->fxp_mii_busy--;	assert(!fp->fxp_mii_busy);	return v & CM_DATA_MASK;}/*===========================================================================* *				fxp_set_timer				     * *===========================================================================*/PRIVATE void fxp_set_timer(tp, delta, watchdog)timer_t *tp;				/* timer to be set */clock_t delta;				/* in how many ticks */tmr_func_t watchdog;			/* watchdog function to be called */{	clock_t now;				/* current time */	int r;	/* Get the current time. */	r= getuptime(&now);	if (r != OK)		panic("FXP","unable to get uptime from clock", r);	/* Add the timer to the local timer queue. */	tmrs_settimer(&fxp_timers, tp, now + delta, watchdog, NULL);	/* Possibly reschedule an alarm call. This happens when a new timer	 * is added in front. 	 */	if (fxp_next_timeout == 0 || 		fxp_timers->tmr_exp_time < fxp_next_timeout)	{		fxp_next_timeout= fxp_timers->tmr_exp_time; #if VERBOSE		printf("fxp_set_timer: calling sys_setalarm for %d (now+%d)\n",			fxp_next_timeout, fxp_next_timeout-now);#endif		r= sys_setalarm(fxp_next_timeout, 1);		if (r != OK)			panic("FXP","unable to set synchronous alarm", r);	}}/*===========================================================================* *				fxp_expire_tmrs				     * *===========================================================================*/PRIVATE void fxp_expire_timers(){/* A synchronous alarm message was received. Check if there are any expired  * timers. Possibly reschedule the next alarm.   */  clock_t now;				/* current time */  timer_t *tp;  int r;  /* Get the current time to compare the timers against. */  r= getuptime(&now);  if (r != OK) 	panic("FXP","Unable to get uptime from clock.", r);  /* Scan the timers queue for expired timers. Dispatch the watchdog function   * for each expired timers. Possibly a new alarm call must be scheduled.   */  tmrs_exptimers(&fxp_timers, now, NULL);  if (fxp_timers == NULL)  	fxp_next_timeout= TMR_NEVER;  else  {  					  /* set new alarm */  	fxp_next_timeout = fxp_timers->tmr_exp_time;  	r= sys_setalarm(fxp_next_timeout, 1);  	if (r != OK) 		panic("FXP","Unable to set synchronous alarm.", r);  }}static void micro_delay(unsigned long usecs){	tickdelay(MICROS_TO_TICKS(usecs));}static u8_t do_inb(port_t port){	int r;	u32_t value;	r= sys_inb(port, &value);	if (r != OK)		panic("FXP","sys_inb failed", r);	return value;}static u32_t do_inl(port_t port){	int r;	u32_t value;	r= sys_inl(port, &value);	if (r != OK)		panic("FXP","sys_inl failed", r);	return value;}static void do_outb(port_t port, u8_t value){	int r;	r= sys_outb(port, value);	if (r != OK)		panic("FXP","sys_outb failed", r);}static void do_outl(port_t port, u32_t value){	int r;	r= sys_outl(port, value);	if (r != OK)		panic("FXP","sys_outl failed", r);}/* * $PchId: fxp.c,v 1.4 2005/01/31 22:10:37 philip Exp $ */

⌨️ 快捷键说明

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