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

📄 undi_nii.c

📁 网卡 BOOT ROM 的 64 住源程序。模块有:核心代码、H文件、网卡驱动程序、头代码文件。
💻 C
📖 第 1 页 / 共 3 页
字号:
static void nic_disable(struct dev *dev){	struct nic *nic = (struct nic *)dev;	int result;	result = shutdown(&cdb);	if (!result) {		printf("UNDI nic does not want to shutdown: %x\n", cdb.stat_code);	}	result = stop(&cdb);	if (!result) {		printf("UNDI nic does not want to stop: %x\n", cdb.stat_code);	}	undi_ifnum = 0;	undi_entry_point = 0;}static uint8_t undi_checksum(struct sw_undi *undi){	uint8_t undi_sum, *ptr;	int i;	ptr = (uint8_t *)undi;	undi_sum = 0;	for(i = 0; i < undi->len; i++) {		undi_sum += ((char *)undi)[i];	}	return undi_sum;}#if 0/* Debug functions */void print_nii(EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE *nii){	printf("NII Revision:  %lx\n", nii->Revision);	printf("NII ID:        %lx\n", nii->ID);	printf("NII ImageAddr: %lx\n", nii->ImageAddr);	printf("NII ImageSize: %x\n",  nii->ImageSize);	printf("NII StringID:  %c%c%c%c\n",  		nii->StringId[0], nii->StringId[1], nii->StringId[2], nii->StringId[3]);	printf("NII Type:      %hhx\n", nii->Type);	printf("NII Version:   %d.%d\n", nii->MajorVer, nii->MinorVer);	printf("NII IfNum:     %hhx\n", nii->IfNum);	printf("\n");}void print_sw_undi(struct sw_undi *undi){	int i;	printf("UNDI signature:      %c%c%c%c\n",		undi->signature[0], undi->signature[1],	undi->signature[2], undi->signature[3]);	printf("UNDI len:            %hhx\n", undi->len);	printf("UNDI fudge:          %hhx\n", undi->fudge);	printf("UNDI rev:            %hhx\n", undi->rev);	printf("UNDI ifcnt:          %hhx\n", undi->ifcnt);	printf("UNDI version:        %d.%d\n", undi->major, undi->minor);	printf("UNDI implementation: %x\n", undi->implementation);	printf("UNDI entry point:    %lx\n", undi->entry_point);	printf("UNDI bus type cnt:   %d\n", undi->bus_type_cnt);	for(i = 0; i < undi->bus_type_cnt; i++) {		printf("UNDI bus type:       %c%c%c%c\n", 			((undi->bus_type[i]) >>  0) & 0xff,			((undi->bus_type[i]) >>  8) & 0xff,			((undi->bus_type[i]) >> 16) & 0xff,			((undi->bus_type[i]) >> 24) & 0xff);	}	printf("UNDI sum:            %hhx\n", undi_checksum(undi));	printf("\n");}void print_init_info(struct db_init_info *info){	printf("init_info.memory_required:   %d\n", info->memory_required);	printf("init_info.frame_data_len:    %d\n", info->frame_data_len);	printf("init_info.link_speeds:       %d %d %d %d\n",		info->link_speeds[0], info->link_speeds[1],		info->link_speeds[2], info->link_speeds[3]);	printf("init_info.media_header_len:  %d\n", info->media_header_len);	printf("init_info.hw_addr_len:       %d\n", info->hw_addr_len);	printf("init_info.mcast_filter_cnt:  %d\n", info->mcast_filter_cnt);	printf("init_info.tx_buf_cnt:        %d\n", info->tx_buf_cnt);	printf("init_info.tx_buf_size:       %d\n", info->tx_buf_size);	printf("init_info.rx_buf_cnt:        %d\n", info->rx_buf_cnt);	printf("init_info.rx_buf_size:       %d\n", info->rx_buf_size);	printf("init_info.if_type:           %hhx\n", info->if_type);	printf("init_info.duplex:            %hhx\n", info->duplex);	printf("init_info.loopback:          %hhx\n", info->loopback);	printf("\n");}void print_config_info(struct db_config_info *info){	int i;	printf("config_info.bus_type: %c%c%c%c\n",		((info->pci.bus_type) >>  0) & 0xff,		((info->pci.bus_type) >>  8) & 0xff,		((info->pci.bus_type) >> 16) & 0xff,		((info->pci.bus_type) >> 24) & 0xff);	if (info->pci.bus_type != UNDI_BUS_TYPE_PCI) {		return;	}	printf("config_info.bus:      %hx\n", info->pci.bus);	printf("config_info.device:   %hhx\n", info->pci.device);	printf("config_info.function: %hhx\n", info->pci.function);	printf("config_info.config:\n");	for(i = 0; i < 256; i++) {		if ((i & 0xf) == 0) {			printf("[%hhx]", i);		}		printf(" %hhx", info->pci.config[i]);		if ((i & 0xf) == 0xf) {			printf("\n");		}	}	printf("\n");		}void print_cdb(struct cdb *cdb){	printf("\n");	printf("cdb.op_code:    %hx\n", cdb->op_code);	printf("cdb.op_flags:   %hx\n", cdb->op_flags);	printf("cdb.cpb_size:   %d\n",  cdb->cpb_size);	printf("cdb.db_size:    %d\n",  cdb->db_size);	printf("cdb.cpb_addr:   %lx\n", cdb->cpb_addr);	printf("cdb.db_addr:    %lx\n", cdb->db_addr);	printf("cdb.stat_code:  %lx\n", cdb->stat_code);	printf("cdb.stat_flags: %lx\n", cdb->stat_flags);	printf("cdb.ifnum       %d\n",  cdb->ifnum);	printf("cdb.control:    %hx\n", cdb->control);	printf("\n");}#endif #define ARPHRD_ETHER 1static int nic_setup(struct dev *dev, 	EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE *nii){	struct nic *nic = (struct nic *)dev;	int result;	struct sw_undi *undi;	struct db_init_info init_info;	struct cpb_initialize cpb_initialize;	struct db_initialize db_initialize;	struct db_station_address db_station_address;	int media_detect;	unsigned filter, no_filter;	int i;	/* Fail if I I'm not passed a valid nii */	if (!nii)		return 0;	/* Fail if this nit a SW UNDI interface */	if (nii->ID == 0)		return 0;	undi = phys_to_virt(nii->ID);		/* Verify the undi structure */	/* It must have a pxe signature */	if (memcmp(undi->signature, "!PXE", 4) != 0)		return 0;	/* It must have a valid checksum */	if (undi_checksum(undi) != 0)		return 0;	/* It must be software undi */	if (undi->implementation & UNDI_IMP_HW_UNDI)		return 0;	/* Setup to do undi calls */	undi_ifnum = nii->IfNum;	undi_entry_point = (void *)undi->entry_point;	/* Find the UNDI state... */	result = get_state(&cdb);	if (!result)		return 0;	/* See if the device is already initialized */	if ((cdb.stat_flags & CDB_STATFLAGS_GET_STATE_MASK) != 		CDB_STATFLAGS_GET_STATE_STOPPED) {		/* If so attempt to stop it */		if ((cdb.stat_flags & CDB_STATFLAGS_GET_STATE_MASK) ==			CDB_STATFLAGS_GET_STATE_INITIALIZED) {			result = shutdown(&cdb);			result = stop(&cdb);		}		else if ((cdb.stat_flags & CDB_STATFLAGS_GET_STATE_MASK) ==			CDB_STATFLAGS_GET_STATE_STARTED) {			result = stop(&cdb);		}		/* See if it did stop */		result = get_state(&cdb);		if (!result)			return 0;		/* If it didn't stop give up */		if ((cdb.stat_flags & CDB_STATFLAGS_GET_STATE_MASK) != 			CDB_STATFLAGS_GET_STATE_STOPPED)			return 0;		}	result = start(&cdb);	if (!result) {		printf("Device would not start: %x\n", cdb.stat_code);		return 0;	}	result = get_init_info(&cdb, &init_info);	if (!result) {		printf("Device wount not give init info: %x\n", cdb.stat_code);		stop(&cdb);		return 0;	}	/* See if the NIC can detect the presence of a cable */	media_detect = (cdb.stat_flags & CDB_STATFLAGS_CABLE_DETECT_MASK) == 		CDB_STATFLAGS_CABLE_DETECT_SUPPORTED;	if ((init_info.if_type != ARPHRD_ETHER) ||		(init_info.hw_addr_len != ETH_ALEN)) {		printf("Not ethernet\n");		stop(&cdb);		return 0;	}	if (init_info.memory_required > sizeof(buffer)) {		printf("NIC wants %d bytes I only have %ld bytes\n",			init_info.memory_required, sizeof(buffer));		stop(&cdb);		return 0;	}	/* Initialize the device */	memset(buffer, 0, sizeof(buffer));	memset(&cpb_initialize, 0, sizeof(cpb_initialize));	cpb_initialize.memory_addr   = virt_to_phys(&buffer);	cpb_initialize.memory_length = init_info.memory_required;	cpb_initialize.link_speed    = 0; /* auto detect */	/* UNDI nics will not take suggestions :( 	 * So let them figure out an appropriate buffer stragety on their own.	 */	cpb_initialize.tx_buf_cnt    = 0;	cpb_initialize.tx_buf_size   = 0;	cpb_initialize.rx_buf_cnt    = 0;	cpb_initialize.rx_buf_size   = 0;	cpb_initialize.duplex        = 0;	cpb_initialize.loopback      = 0;	result = initialize(&cdb, media_detect, &cpb_initialize, &db_initialize);	if (!result) {		printf("Device would not initialize: %x\n", cdb.stat_code);		stop(&cdb);		return 0;	}#if 0	/* It appears the memory_used parameter is never set correctly, ignore it */	if (db_initialize.memory_used > sizeof(buffer)) {		printf("NIC is using %d bytes I only have %ld bytes\n",			db_initialize.memory_used, sizeof(buffer));		printf("tx_buf_cnt:  %d\n", db_initialize.tx_buf_cnt);		printf("tx_buf_size: %d\n", db_initialize.tx_buf_size);		printf("rx_buf_cnt:  %d\n", db_initialize.rx_buf_cnt);		printf("rx_buf_size: %d\n", db_initialize.rx_buf_size);		nic_disable(dev);		return 0;	}	printf("NIC is using %d bytes\n",		db_initialize.memory_used);#endif	if (media_detect && (		    (cdb.stat_flags & ~CDB_STATFLAGS_STATUS_MASK) ==		    CDB_STATFLAGS_INITIALIZED_NO_MEDIA)) {		printf("No media present\n");		nic_disable(dev);		return 0;	}	/* Get the mac address */	result = station_address_read(&cdb, &db_station_address);	if (!result) {		printf("Could not read station address: %x\n",			cdb.stat_code);		nic_disable(dev);		return 0;	}	for(i = 0; i < ETH_ALEN; i++) {		nic->node_addr[i] = db_station_address.station_address[i];	}	printf("Ethernet addr: %!\n", nic->node_addr);	filter = CDB_OPFLAGS_RECEIVE_FILTER_ENABLE |		CDB_OPFLAGS_RECEIVE_FILTER_UNICAST |		CDB_OPFLAGS_RECEIVE_FILTER_BROADCAST;	no_filter = CDB_OPFLAGS_RECEIVE_FILTER_DISABLE |		CDB_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST |		CDB_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST; 		if (undi->implementation & UNDI_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) {		filter |= CDB_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;		no_filter |= CDB_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;	}	else if (undi->implementation & UNDI_IMP_PROMISCUOUS_RX_SUPPORTED) {		filter |= CDB_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;	}		result = receive_filters(&cdb, no_filter);	if (!result) {		printf("Could not clear receive filters: %x\n",			cdb.stat_code);		nic_disable(dev);		return 0;	}	result = receive_filters(&cdb, filter);	if (!result) {		printf("Could not set receive filters: %x\n",			cdb.stat_code);		nic_disable(dev);		return 0;	}		/* It would be nice to call get_config_info so I could pass	 * the type of nic, but that crashes some efi drivers.	 */	/* Everything worked!  */	dev->disable  = nic_disable;	nic->poll     = nic_poll;	nic->transmit = nic_transmit;	return 1;}/**************************************************************************PROBE - Look for an adapter, this routine's visible to the outside***************************************************************************/static int nic_probe(struct dev *dev, unsigned short *dummy __unused){	EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE *nii;	int index;	int result;	index = dev->index+ 1;	if (dev->how_probe == PROBE_AWAKE) {		index--;	}	for(result = 0; !result && (nii = lookup_efi_nic(index)); index++) {		result = nic_setup(dev, nii);		if (result) {			break;		}	}	dev->index = result ? index : -1;	return result;}static struct isa_driver nic_driver __isa_driver = {	.type     = NIC_DRIVER,	.name     = "undi_nii",	.probe    = nic_probe,	.ioaddrs  = 0,};

⌨️ 快捷键说明

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