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

📄 wrapndis.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef CONFIG_NET_POLL_CONTROLLERstatic void ndis_poll_controller(struct net_device *dev){	struct wrap_ndis_device *wnd = netdev_priv(dev);	disable_irq(dev->irq);	ndis_isr(dev->irq, wnd ISR_PT_REGS_ARG);	enable_irq(dev->irq);}#endif/* called from BH context */static struct net_device_stats *ndis_get_stats(struct net_device *dev){	struct wrap_ndis_device *wnd = netdev_priv(dev);	return &wnd->net_stats;}/* called from BH context */static void ndis_set_multicast_list(struct net_device *dev){	struct wrap_ndis_device *wnd = netdev_priv(dev);	set_bit(SET_MULTICAST_LIST, &wnd->wrap_ndis_pending_work);	schedule_wrap_work(&wnd->wrap_ndis_work);}/* called from BH context */struct iw_statistics *get_iw_stats(struct net_device *dev){	struct wrap_ndis_device *wnd = netdev_priv(dev);	return &wnd->iw_stats;}static void update_iw_stats(struct wrap_ndis_device *wnd){	struct iw_statistics *iw_stats = &wnd->iw_stats;	struct ndis_wireless_stats ndis_stats;	NDIS_STATUS res;	ndis_rssi rssi;	int qual;	ENTER2("%p", wnd);	if (wnd->iw_stats_enabled == FALSE || !netif_carrier_ok(wnd->net_dev)) {		memset(iw_stats, 0, sizeof(*iw_stats));		EXIT2(return);	}	res = miniport_query_info(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi));	if (res == NDIS_STATUS_SUCCESS)		iw_stats->qual.level = rssi;	qual = 100 * (rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE);	if (qual < 0)		qual = 0;	else if (qual > 100)		qual = 100;	iw_stats->qual.noise = WL_NOISE;	iw_stats->qual.qual  = qual;	res = miniport_query_info(wnd, OID_802_11_STATISTICS,				  &ndis_stats, sizeof(ndis_stats));	if (res != NDIS_STATUS_SUCCESS)		EXIT2(return);	iw_stats->discard.retries = (unsigned long)ndis_stats.retry +		(unsigned long)ndis_stats.multi_retry;	iw_stats->discard.misc = (unsigned long)ndis_stats.fcs_err +		(unsigned long)ndis_stats.rtss_fail +		(unsigned long)ndis_stats.ack_fail +		(unsigned long)ndis_stats.frame_dup;	EXIT2(return);}static void set_multicast_list(struct wrap_ndis_device *wnd){	struct net_device *net_dev;	ULONG packet_filter;	NDIS_STATUS res;	net_dev = wnd->net_dev;	packet_filter = wnd->packet_filter;	TRACE2("0x%08x", packet_filter);	if (net_dev->flags & IFF_PROMISC) {		packet_filter |= NDIS_PACKET_TYPE_PROMISCUOUS |			NDIS_PACKET_TYPE_ALL_LOCAL;	} else if (net_dev->flags & IFF_ALLMULTI ||		   net_dev->mc_count > wnd->multicast_size) {		packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;		TRACE2("0x%08x", packet_filter);	} else if (net_dev->mc_count > 0) {		int i, size;		char *buf;		struct dev_mc_list *mclist;		size = min(wnd->multicast_size, net_dev->mc_count);		TRACE2("%d, %d", wnd->multicast_size, net_dev->mc_count);		buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);		if (!buf) {			WARNING("couldn't allocate memory");			EXIT2(return);		}		mclist = net_dev->mc_list;		for (i = 0; i < size && mclist; mclist = mclist->next) {			if (mclist->dmi_addrlen != ETH_ALEN)				continue;			memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);			TRACE2(MACSTRSEP, MAC2STR(mclist->dmi_addr));			i++;		}		res = miniport_set_info(wnd, OID_802_3_MULTICAST_LIST,					buf, i * ETH_ALEN);		if (res == NDIS_STATUS_SUCCESS && i > 0)			packet_filter |= NDIS_PACKET_TYPE_MULTICAST;		else			packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;		kfree(buf);	}	TRACE2("0x%08x", packet_filter);	res = set_packet_filter(wnd, packet_filter);	if (res)		TRACE1("couldn't set packet filter (%08X)", res);	EXIT2(return);}static void link_status_handler(struct wrap_ndis_device *wnd){	struct ndis_assoc_info *ndis_assoc_info;	union iwreq_data wrqu;	NDIS_STATUS res;	const int assoc_size = sizeof(*ndis_assoc_info) + IW_CUSTOM_MAX + 32;	int i;#if WIRELESS_EXT <= 17	unsigned char *wpa_assoc_info, *ies;	unsigned char *p;#endif	ENTER2("link: %d", netif_carrier_ok(wnd->net_dev));	if (wnd->physical_medium != NdisPhysicalMediumWirelessLan)		EXIT2(return);#ifndef CONFIG_NET_RADIO	EXIT2(return);#endif	if (!netif_carrier_ok(wnd->net_dev)) {		memset(&wrqu, 0, sizeof(wrqu));		wrqu.ap_addr.sa_family = ARPHRD_ETHER;		wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL);		/* In IBSS (ad-hoc) mode, it may be desirable to have		 * one node configured for association, but drivers		 * disassociate if last node disassociates; to		 * configure again, set essid */		if (wnd->infrastructure_mode == Ndis802_11IBSS &&		    wnd->essid.length > 0) {			set_essid(wnd, wnd->essid.essid, wnd->essid.length);			for (i = 0; i < MAX_ENCR_KEYS; i++) {				if (wnd->encr_info.keys[i].length <= 0)					continue;				add_wep_key(wnd, wnd->encr_info.keys[i].key,					    wnd->encr_info.keys[i].length, i);			}		}		EXIT2(return);	}	ndis_assoc_info = kmalloc(assoc_size, GFP_KERNEL);	if (!ndis_assoc_info) {		ERROR("couldn't allocate memory");		EXIT2(return);	}	memset(ndis_assoc_info, 0, assoc_size);	res = miniport_query_info(wnd, OID_802_11_ASSOCIATION_INFORMATION,				  ndis_assoc_info, assoc_size);	if (res) {		TRACE2("query assoc_info failed (%08X)", res);		kfree(ndis_assoc_info);		EXIT2(return);	}#if WIRELESS_EXT > 17	memset(&wrqu, 0, sizeof(wrqu));	wrqu.data.length = ndis_assoc_info->req_ie_length;	wireless_send_event(wnd->net_dev, IWEVASSOCREQIE, &wrqu,			    ((char *)ndis_assoc_info) +			    ndis_assoc_info->offset_req_ies);	wrqu.data.length = ndis_assoc_info->resp_ie_length;	wireless_send_event(wnd->net_dev, IWEVASSOCRESPIE, &wrqu,			    ((char *)ndis_assoc_info) +			    ndis_assoc_info->offset_resp_ies);#else	/* we need 28 extra bytes for the format strings */	if ((ndis_assoc_info->req_ie_length +	     ndis_assoc_info->resp_ie_length + 28) > IW_CUSTOM_MAX) {		WARNING("information element is too long! (%u,%u),"			"association information dropped",			ndis_assoc_info->req_ie_length,			ndis_assoc_info->resp_ie_length);		kfree(ndis_assoc_info);		EXIT2(return);	}	wpa_assoc_info = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);	if (!wpa_assoc_info) {		ERROR("couldn't allocate memory");		kfree(ndis_assoc_info);		EXIT2(return);	}	p = wpa_assoc_info;	p += sprintf(p, "ASSOCINFO(ReqIEs=");	ies = ((char *)ndis_assoc_info) + ndis_assoc_info->offset_req_ies;	for (i = 0; i < ndis_assoc_info->req_ie_length; i++)		p += sprintf(p, "%02x", ies[i]);	p += sprintf(p, " RespIEs=");	ies = ((char *)ndis_assoc_info) + ndis_assoc_info->offset_resp_ies;	for (i = 0; i < ndis_assoc_info->resp_ie_length; i++)		p += sprintf(p, "%02x", ies[i]);	p += sprintf(p, ")");	memset(&wrqu, 0, sizeof(wrqu));	wrqu.data.length = p - wpa_assoc_info;	wireless_send_event(wnd->net_dev, IWEVCUSTOM, &wrqu, wpa_assoc_info);	kfree(wpa_assoc_info);#endif	kfree(ndis_assoc_info);	get_ap_address(wnd, (char *)&wrqu.ap_addr.sa_data);	wrqu.ap_addr.sa_family = ARPHRD_ETHER;	wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL);	TRACE2(MACSTRSEP, MAC2STR(wrqu.ap_addr.sa_data));	EXIT2(return);}static void iw_stats_timer_proc(unsigned long data){	struct wrap_ndis_device *wnd = (struct wrap_ndis_device *)data;	ENTER2("");	if (wnd->iw_stats_interval <= 0)		EXIT2(return);	set_bit(COLLECT_IW_STATS, &wnd->wrap_ndis_pending_work);	schedule_wrap_work(&wnd->wrap_ndis_work);	mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval);}static void add_iw_stats_timer(struct wrap_ndis_device *wnd){	if (wnd->physical_medium != NdisPhysicalMediumWirelessLan)		return;	if (wnd->iw_stats_interval < 0)		wnd->iw_stats_interval *= -1;	wnd->iw_stats_timer.data = (unsigned long)wnd;	wnd->iw_stats_timer.function = iw_stats_timer_proc;	mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval);}static void del_iw_stats_timer(struct wrap_ndis_device *wnd){	ENTER2("");	wnd->iw_stats_interval *= -1;	del_timer_sync(&wnd->iw_stats_timer);	EXIT2(return);}static void hangcheck_proc(unsigned long data){	struct wrap_ndis_device *wnd = (struct wrap_ndis_device *)data;	BOOLEAN reset;	struct miniport_char *miniport;	ENTER2("");	if (wnd->hangcheck_interval <= 0)		EXIT2(return);	miniport = &wnd->wd->driver->ndis_driver->miniport;	if_serialize_lock(wnd);	reset = LIN2WIN1(miniport->hangcheck, wnd->nmb->adapter_ctx);	if_serialize_unlock(wnd);	if (reset) {		set_bit(MINIPORT_RESET, &wnd->wrap_ndis_pending_work);		schedule_wrap_work(&wnd->wrap_ndis_work);	}	mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval);	EXIT3(return);}void hangcheck_add(struct wrap_ndis_device *wnd){	if (!wnd->wd->driver->ndis_driver->miniport.hangcheck ||	    hangcheck_interval < 0)		EXIT2(return);	if (hangcheck_interval > 0)		wnd->hangcheck_interval = hangcheck_interval * HZ;	if (wnd->hangcheck_interval < 0)		wnd->hangcheck_interval *= -1;	wnd->hangcheck_timer.data = (unsigned long)wnd;	wnd->hangcheck_timer.function = hangcheck_proc;	mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval);	EXIT2(return);}void hangcheck_del(struct wrap_ndis_device *wnd){	ENTER2("");	if (wnd->hangcheck_interval > 0)		wnd->hangcheck_interval *= -1;	del_timer_sync(&wnd->hangcheck_timer);	EXIT2(return);}/* worker procedure to take care of setting/checking various states */static void wrap_ndis_worker(worker_param_t param){	struct wrap_ndis_device *wnd;	wnd = worker_param_data(param, struct wrap_ndis_device, wrap_ndis_work);	TRACE2("%lu", wnd->wrap_ndis_pending_work);	if (test_bit(SHUTDOWN, &wnd->wrap_ndis_pending_work))		EXIT3(return);	if (test_and_clear_bit(SET_MULTICAST_LIST, &wnd->wrap_ndis_pending_work))		set_multicast_list(wnd);	if (test_and_clear_bit(COLLECT_IW_STATS, &wnd->wrap_ndis_pending_work))		update_iw_stats(wnd);	if (test_and_clear_bit(LINK_STATUS_CHANGED,			       &wnd->wrap_ndis_pending_work))		link_status_handler(wnd);	if (test_and_clear_bit(MINIPORT_RESET, &wnd->wrap_ndis_pending_work))		miniport_reset(wnd);	EXIT3(return);}NDIS_STATUS ndis_reinit(struct wrap_ndis_device *wnd){	NDIS_STATUS status;	wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND;	status = miniport_set_power_state(wnd, NdisDeviceStateD3);	if (status != NDIS_STATUS_SUCCESS) {		ERROR("halting device %s failed: %08X", wnd->net_dev->name,		      status);		return status;	}	status = miniport_set_power_state(wnd, NdisDeviceStateD0);	if (status != NDIS_STATUS_SUCCESS)		ERROR("starting device %s failed: %08X", wnd->net_dev->name,		      status);	return status;}static void get_encryption_capa(struct wrap_ndis_device *wnd, char *buf,				const int buf_len){	int i, mode;	NDIS_STATUS res;	struct ndis_assoc_info ndis_assoc_info;	struct ndis_add_key ndis_key;	struct ndis_capability *c;	ENTER1("%p", wnd);	/* set network type to g, b, or a, in that order */	res = miniport_query_info(wnd, OID_802_11_NETWORK_TYPES_SUPPORTED,				  buf, buf_len);	if (res == NDIS_STATUS_SUCCESS) {		struct network_type_list *net_types;		unsigned long types = 0;		net_types = (typeof(net_types))buf;		for (i = 0; i < net_types->num; i++) {			TRACE2("%d", net_types->types[i]);			set_bit(net_types->types[i], &types);		}		if (types & Ndis802_11OFDM24)			mode = Ndis802_11OFDM24;		else if (types & Ndis802_11DS)			mode = Ndis802_11DS;		else if (types & Ndis802_11OFDM5)			mode = Ndis802_11OFDM5;		else			mode = Ndis802_11DS;		miniport_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, mode);	}	/* check if WEP is supported */	if (set_encr_mode(wnd, Ndis802_11Encryption1Enabled) == 0 &&	    get_encr_mode(wnd) == Ndis802_11Encryption1KeyAbsent)		set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr);	/* check if WPA is supported */	if (set_auth_mode(wnd, Ndis802_11AuthModeWPA) == 0 &&	    get_auth_mode(wnd) == Ndis802_11AuthModeWPA)		set_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth);	else		EXIT1(return);	if (set_auth_mode(wnd, Ndis802_11AuthModeWPAPSK) == 0 &&	    get_auth_mode(wnd) == Ndis802_11AuthModeWPAPSK)		set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth);	/* check for highest encryption */	mode = 0;	if (set_encr_mode(wnd, Ndis802_11Encryption3Enabled) == 0 &&	    (i = get_encr_mode(wnd)) > 0 &&	    (i == Ndis802_11Encryption3KeyAbsent ||	     i == Ndis802_11Encryption3Enabled))		mode = Ndis802_11Encryption3Enabled;	else if (set_encr_mode(wnd, Ndis802_11Encryption2Enabled) == 0 &&		 (i = get_encr_mode(wnd)) > 0 &&		 (i == Ndis802_11Encryption2KeyAbsent ||		  i == Ndis802_11Encryption2Enabled))		mode = Ndis802_11Encryption2Enabled;	else if (set_encr_mode(wnd, Ndis802_11Encryption1Enabled) == 0 &&		 (i = get_encr_mode(wnd)) > 0 &&		 (i == Ndis802_11Encryption1KeyAbsent ||		  i == Ndis802_11Encryption1Enabled))		mode = Ndis802_11Encryption1Enabled;	TRACE1("mode: %d", mode);	if (mode == 0)		EXIT1(return);	set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr);	if (mode == Ndis802_11Encryption1Enabled)		EXIT1(return);	ndis_key.length = 32;	ndis_key.index = 0xC0000001;

⌨️ 快捷键说明

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