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

📄 smsc9118.c

📁 基于pxa270的linux下smsc9118的网卡驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if(mac_addr_hi16==0xFFFFFFFFUL) {
		SMSC_TRACE("  mac_addr_hi16    = 0x%08lX, will attempt to read from LAN9118",mac_addr_hi16);
		SMSC_TRACE("  mac_addr_lo32    = 0x%08lX, will attempt to read from LAN9118",mac_addr_lo32);
	} else {
		if(mac_addr_hi16&0xFFFF0000UL) {
			//The high word is reserved
			SMSC_WARNING("  mac_addr_hi16 = 0x%08lX, reserved bits are high.",mac_addr_hi16);
			mac_addr_hi16&=0x0000FFFFUL;
			SMSC_WARNING("    reseting to mac_addr_hi16 = 0x%08lX",mac_addr_hi16);
		}
		if(mac_addr_lo32&0x00000001UL) {
			//bit 0 is the I/G bit
			SMSC_WARNING("  mac_addr_lo32 = 0x%08lX, I/G bit is set.",mac_addr_lo32);
			mac_addr_lo32&=0xFFFFFFFEUL;
			SMSC_WARNING("    reseting to mac_addr_lo32 = 0x%08lX",mac_addr_lo32);			
		}
		SMSC_TRACE("  mac_addr_hi16    = 0x%08lX",mac_addr_hi16);
		SMSC_TRACE("  mac_addr_lo32    = 0x%08lX",mac_addr_lo32);
	}
	SMSC_TRACE(    "  debug_mode       = 0x%08lX",debug_mode);
	if(tx_fif_sz&(~HW_CFG_TX_FIF_SZ_)) {
		SMSC_WARNING("tx_fif_sz = 0x%08lX is invalid",tx_fif_sz);
		tx_fif_sz&=HW_CFG_TX_FIF_SZ_;
		SMSC_WARNING("  resetting tx_fif_sz to 0x%08lX",tx_fif_sz);
	}
	if(tx_fif_sz>0x000E0000UL) {
		SMSC_WARNING("tx_fif_sz = 0x%08lX is too high",tx_fif_sz);
		tx_fif_sz=0x000E0000UL;
		SMSC_WARNING(" resetting tx_fif_sz to 0x%08lX",tx_fif_sz);
	}
	if(tx_fif_sz<0x00020000UL) {
		SMSC_WARNING("tx_fif_sz = 0x%08lX is too low",tx_fif_sz);
		tx_fif_sz=0x00020000UL;
		SMSC_WARNING(" resetting tx_fif_sz to 0x%08lX",tx_fif_sz);
	}
	SMSC_TRACE(    "  tx_fif_sz        = 0x%08lX",tx_fif_sz);
	if(afc_cfg==0xFFFFFFFFUL) {
		SMSC_TRACE("  afc_cfg          = 0x%08lX, driver will decide",afc_cfg);
	} else {
		if(afc_cfg&0xFF000000UL) {
			SMSC_WARNING("afc_cfg = 0x%08lX is invalid",afc_cfg);
			afc_cfg&=0xFFFFFFFFUL;
			SMSC_WARNING(" resetting to afc_cfg = 0x%08lX, driver will decide",afc_cfg);
		} else {
			SMSC_TRACE(
				   "  afc_cfg          = 0x%08lX",afc_cfg);
		}
	}
	if(tasklets) {
		SMSC_TRACE("  tasklets         = 0x%08lX, Tasklets enabled",tasklets);
	} else {
		SMSC_TRACE("  tasklets         = 0, Tasklets disabled");
	}
	if(phy_addr==0xFFFFFFFFUL) {
		SMSC_TRACE("  phy_addr         = 0xFFFFFFFF, Use internal phy");
	} else if(phy_addr<=31UL) {
		SMSC_TRACE("  phy_addr         = 0x%08lX, use this address for external phy",phy_addr);
	} else {
		SMSC_TRACE("  phy_addr         = 0x%08lX, auto detect external phy",phy_addr);
	}
	if(max_throughput) {
		SMSC_TRACE("  max_throughput   = 0x%08lX, Use platform default",max_throughput);
	} else {
		SMSC_TRACE("  max_throughput   = 0x%08lX",max_throughput);
	}
	if(max_packet_count) {
		SMSC_TRACE("  max_packet_count = 0x%08lX, Use platform default",max_packet_count);
	} else {
		SMSC_TRACE("  max_packet_count = 0x%08lX",max_packet_count);
	}
	if(packet_cost) {
		SMSC_TRACE("  packet_cost      = 0x%08lX, Use platform default",packet_cost);
	} else {
		SMSC_TRACE("  packet_cost      = 0x%08lX",packet_cost);
	}
	if(burst_period) {
		SMSC_TRACE("  burst_period     = 0x%08lX, Use platform default",burst_period);
	} else {
		SMSC_TRACE("  burst_period     = 0x%08lX",burst_period);
	}
	if(max_work_load) {
		SMSC_TRACE("  max_work_load    = 0x%08lX, Use platform default",max_work_load);
	} else {
		SMSC_TRACE("  max_work_load    = 0x%08lX",max_work_load);
	}

	strcpy(SMSC9118.name,"eth%d");

	result=register_netdev(&SMSC9118);
	if(result) {
		SMSC_WARNING("error %i registering device",result);
	} else {
		device_present=1;
		SMSC_TRACE("  Interface Name = \"%s\"",SMSC9118.name);
	}
	result=result;//make lint happy
	SMSC_TRACE("<-- init_module()");
	return device_present ? 0 : -ENODEV;
}

void Smsc9118_cleanup_module(void)
{
	SMSC_TRACE("--> cleanup_module()");
	if(SMSC9118.priv!=NULL) {
		PPRIVATE_DATA privateData=(PPRIVATE_DATA)SMSC9118.priv;
		PPLATFORM_DATA platformData=(PPLATFORM_DATA)&(privateData->PlatformData);
		Platform_CleanUp(platformData);
		kfree(SMSC9118.priv);
		SMSC9118.priv=NULL;
	}
	unregister_netdev(&SMSC9118);
	SMSC_TRACE("<-- cleanup_module()");
}

int Smsc9118_init(struct net_device *dev)
{
	DWORD dwLanBase=0UL;
	DWORD dwIdRev=0UL;
	DWORD dwFpgaRev=0UL;
	PPRIVATE_DATA privateData=NULL;
	PPLATFORM_DATA platformData=NULL;
	BOOLEAN platformInitialized=FALSE;
	int result=-ENODEV;
	SMSC_TRACE("-->Smsc9118_init(dev=0x%08lX)",(DWORD)dev);

	if(dev==NULL) {
		SMSC_WARNING("Smsc9118_init(dev==NULL)");
		result=-EFAULT;
		goto DONE;
	}

	if(dev->priv!=NULL) {
		SMSC_WARNING("dev->priv!=NULL, going to overwrite pointer");
	}
	dev->priv=kmalloc(sizeof(PRIVATE_DATA),GFP_KERNEL);
	if(dev->priv==NULL) {
		SMSC_WARNING("Unable to allocate PRIVATE_DATA");
		result=-ENOMEM;
		goto DONE;
	}
	memset(dev->priv,0,sizeof(PRIVATE_DATA));
	privateData=(PPRIVATE_DATA)(dev->priv);
	platformData=&(privateData->PlatformData);

	dwLanBase=Platform_Initialize(
		platformData,
		lan_base,bus_width);

	if(dwLanBase==0UL) {
		SMSC_WARNING("dwLanBase==0x00000000");
		result=-ENODEV;
		goto DONE;
	}
	platformInitialized=TRUE;
	SMSC_TRACE("dwLanBase=0x%08lX",dwLanBase);

	if(check_mem_region(dwLanBase,LAN_REGISTER_EXTENT)!=0) {
		SMSC_WARNING("  Memory Region specified (0x%08lX to 0x%08lX) is not available.",
			dwLanBase,dwLanBase+LAN_REGISTER_EXTENT-1UL);
		result=-ENOMEM;
		goto DONE;
	}
	
	privateData->dwLanBase=dwLanBase;
	dwIdRev=Lan_GetRegDW(ID_REV);
	if(HIWORD(dwIdRev)==LOWORD(dwIdRev)) {
		//this may mean the chip is set for 32 bit 
		//  while the bus is reading as 16 bit
UNKNOWN_CHIP:
		SMSC_WARNING("  LAN9118 Family NOT Identified, dwIdRev==0x%08lX",dwIdRev);
		result=-ENODEV;
		goto DONE;
	}
	switch(dwIdRev&0xFFFF0000UL) {
	case 0x01180000UL:
		switch(dwIdRev&0x0000FFFFUL) {
		case 0UL:
			SMSC_TRACE("  LAN9118 Beacon identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=0;
			break;
		case 1UL:
			SMSC_TRACE("  LAN9118 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=1;
			break;
		case 2UL:
			SMSC_TRACE("  LAN9118 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		default:
			SMSC_TRACE("  LAN9118 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		};break;
	case 0x01170000UL:
		switch(dwIdRev&0x0000FFFFUL) {
		case 0UL:
			SMSC_TRACE("  LAN9117 Beacon identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=0;
			break;
		case 1UL:
			SMSC_TRACE("  LAN9117 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=1;
			break;
		case 2UL:
			SMSC_TRACE("  LAN9117 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		default:
			SMSC_TRACE("  LAN9117 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		};break;
	case 0x01160000UL:
		switch(dwIdRev&0x0000FFFFUL) {
		case 0UL:
			goto UNKNOWN_CHIP;
		case 1UL:
			SMSC_TRACE("  LAN9116 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=1;
			break;
		case 2UL:
			SMSC_TRACE("  LAN9116 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		default:
			SMSC_TRACE("  LAN9116 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		};break;
	case 0x01150000UL:
		switch(dwIdRev&0x0000FFFFUL) {
		case 0UL:
			goto UNKNOWN_CHIP;
		case 1UL:
			SMSC_TRACE("  LAN9115 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=1;
			break;
		case 2UL:
			SMSC_TRACE("  LAN9115 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		default:
			SMSC_TRACE("  LAN9115 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		};break;
	case 0x01120000UL:
		switch(dwIdRev&0x0000FFFFUL) {
		case 0UL:
			goto UNKNOWN_CHIP;
		case 1UL:
			SMSC_TRACE("  LAN9112 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=1;
			break;
		case 2UL:
			SMSC_TRACE("  LAN9112 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		default:
			SMSC_TRACE("  LAN9112 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=2;
			break;
		};break;
	case 0x118A0000UL:
		switch(dwIdRev&0x0000FFFFUL) {
		case 0UL:
			SMSC_TRACE("  LAN9218 Boylston identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=3;
			break;
		default:
			SMSC_TRACE("  LAN9218 Boylston identified (NEW), dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=3;
			break;
		};break;
	case 0x117A0000UL:
		switch(dwIdRev&0x0000FFFFUL) {
		case 0UL:
			SMSC_TRACE("  LAN9217 Boylston identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=3;
			break;
		default:
			SMSC_TRACE("  LAN9217 Boylston identified (NEW), dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=3;
			break;
		};break;
	case 0x116A0000UL:
		switch(dwIdRev&0x0000FFFFUL) {
		case 0UL:
			SMSC_TRACE("  LAN9216 Boylston identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=3;
			break;
		default:
			SMSC_TRACE("  LAN9216 Boylston identified (NEW), dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=3;
			break;
		};break;
	case 0x115A0000UL:
		switch(dwIdRev&0x0000FFFFUL) {
		case 0UL:
			SMSC_TRACE("  LAN9215 Boylston identified, dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=3;
			break;
		default:
			SMSC_TRACE("  LAN9215 Boylston identified (NEW), dwIdRev==0x%08lX",dwIdRev);
			privateData->dwGeneration=3;
			break;
		};break;
	}
	dwFpgaRev=Lan_GetRegDW(FPGA_REV);
	SMSC_TRACE("  FPGA_REV == 0x%08lX",dwFpgaRev);

	ether_setup(dev);
	dev->open=				Smsc9118_open;
	dev->stop=				Smsc9118_stop;
	dev->hard_start_xmit=	Smsc9118_hard_start_xmit;
	dev->get_stats=			Smsc9118_get_stats;
	dev->do_ioctl=			Smsc9118_do_ioctl;
	dev->set_multicast_list=Smsc9118_set_multicast_list;
	dev->flags|=IFF_MULTICAST;

	SET_MODULE_OWNER(dev);

	privateData->dwIdRev=dwIdRev;
	privateData->dwFpgaRev=dwFpgaRev&(0x000000FFUL);
	privateData->dev=dev;

	sprintf(privateData->ifName,"%s",dev->name);
	result=0;
    
DONE:
	if(result!=0) {
		if(dev!=NULL) {
			if(dev->priv!=NULL) {
				if(platformInitialized) {
					Platform_CleanUp(platformData);
				}
				kfree(dev->priv);
				dev->priv=NULL;
			}
		}
	}
	SMSC_TRACE("<--Smsc9118_init(), result=%d",result);
	return result;
}

int Smsc9118_open(struct net_device *dev)
{
	int i;
	int result=-ENODEV;
	PPRIVATE_DATA privateData=NULL;
	PPLATFORM_DATA platformData=NULL;
	BOOLEAN acquired_mem_region=FALSE;
	BOOLEAN acquired_isr=FALSE;
	SMSC_TRACE("-->Smsc9118_open(dev=0x%08lX)",(DWORD)dev);
	if(dev==NULL) {
		SMSC_WARNING("Smsc9118_open(dev==NULL)");
		result=-EFAULT;
		goto DONE;
	}
	privateData=(PPRIVATE_DATA)(dev->priv);
	if(privateData==NULL) {
		SMSC_WARNING("Smsc9118_open(privateData==NULL)");
		result=-EFAULT;
		goto DONE;
	}
	platformData=&(privateData->PlatformData);

	for (i = 0; i < GPT_SCHEDULE_DEPTH; i++) {
		privateData->GptFunction [i] = NULL;
	}
	privateData->Gpt_scheduled_slot_index = GPT_SCHEDULE_DEPTH;

	//get memory region
	if(check_mem_region(privateData->dwLanBase,LAN_REGISTER_EXTENT)!=0)
	{
		SMSC_WARNING("Device memory is already in use.");
		result=-ENOMEM;
		goto DONE;
	}
	request_mem_region(privateData->dwLanBase,LAN_REGISTER_EXTENT,"SMSC_LAN9118");
	acquired_mem_region=TRUE;

	//initialize the LAN9118
	{
		DWORD dwIntCfg=0;
		if(irq_pol) {
			dwIntCfg|=INT_CFG_IRQ_POL_;
		}
		if(irq_type) {
			dwIntCfg|=INT_CFG_IRQ_TYPE_;
		}
		if(!Lan_Initialize(privateData,dwIntCfg,tx_fif_sz,afc_cfg))
		{
			SMSC_WARNING("Failed Lan_Initialize");
			result=-ENODEV;

⌨️ 快捷键说明

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