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

📄 if_wlp.c

📁 WaveLAN无线网卡Linux驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
				ifp->if_collisions += (tx_status & TX_NUMCOL);#ifdef WLP_STATS				sc->sc_numcol += (tx_status & TX_NUMCOL);				if (tx_status & TX_HRT_BET)					sc->sc_hrtbet++;				if (tx_status & TX_DEF)					sc->sc_txdef++;				if ((status & P0_S0_EVENT) == RETRANSMIT_DONE)					sc->sc_rexmit++;#endif				IOWrite1(0x00, P0_INT_ACK | P0_NOP);#ifdef WAVELAN_ROAMING				if (sc->sc_rs.rs_disabletx == 0)					ifp->if_flags &= ~IFF_OACTIVE;				sc->sc_rs.rs_activetx = 0;#else				ifp->if_flags &= ~IFF_OACTIVE;#endif				wlpstart(&sc->sc_ac.ac_if);	/* Restart Transmission */				continue;	/* Don't re-ack the INT */			}			break;		case DUMP_DONE:			{				char            tmpbuf[128];				/*				 * Dump the 72 bytes returned when in				 * Enhanced mode.				 */				printf("\nIntel 82593 Dump\n");				if (sc->sc_iftype == IFTYPE_REDWING) {					dump_bytes(sc->sc_maddr, 72);					/*					 * (1) Reset the Receive DMA Counter (Port 0x02 and 0x03)					 * (2) Reset the Page Control Port (Port 0x09)					 */					RW_ResetRXDMA();				} else if (sc->sc_iftype == IFTYPE_WAVELAN) {					WLP_PointRXBUF(0x00);					IORead(0x04, tmpbuf, 72);					dump_bytes(tmpbuf, 72);					WLP_ResetRXDMA();				}				IOWrite1(0x00, P0_RCV_ENABLE);			}			break;		case RCV_ABORT:		case STOP_REG_HIT:			{#ifdef WLP_STATS				sc->sc_stopreg++;#endif				/*				 * Disable receive AND make sure that it got				 * disabled.				 */				IOWrite1(0x00, P0_RCV_DISABLE);				DELAY(500);				IOWrite1(0x00, P0_NOP | P0_STATUS3);				if ((IORead1(0x00) & P0_S3_RCV_STATE) != 0x00) {					printf("wlp%d: Could not disable receive\n", sc->sc_unit);					/*					 * If this was a RCV ABORT and we					 * could not disable receive, we are					 * in trouble.  Now we must reset the					 * card.					 */					if ((status & P0_S0_EVENT) == RCV_ABORT)						wlpinit(sc);					/*					 * If this was a STOP REG HIT, we are					 * probably going to get a RCV ABORT					 * interrupt right after this. just					 * break out of the switch so that					 * the status register can be					 * re-check for interrupts.					 */					break;				}				/*				 * Reset the Ring Management on the 82593				 */				IOWrite1(0x00, P0_SWITCH_TO_P1);				IOWrite1(0x00, P1_RST_RING_MGMT);				IOWrite1(0x00, P1_SWITCH_TO_P0);				if (sc->sc_iftype == IFTYPE_REDWING) {					RW_ResetRXDMA();				} else if (sc->sc_iftype == IFTYPE_WAVELAN) {					WLP_ResetRXDMA();				}				sc->sc_rxnext = 0;				IOWrite1(0x00, P0_RCV_ENABLE);			}			break;		case MC_SETUP_DONE:			break;		case TDR_DONE:		case DIAGNOSE_PASSED:		case EXECUTION_ABORT:		case DIAGNOSE_FAILED:		case IA_SETUP_DONE:		case CONFIGURE_DONE:			printf("wlp%d received %s (IRQ %x)\n",			       sc->sc_unit, I82593_IRQ[status & P0_S0_EVENT], status & P0_S0_EVENT);			break;		default:			printf("wlp%d received unknown interrupt.\n", sc->sc_unit);		}		IOWrite1(0x00, P0_INT_ACK | P0_NOP);	}done:	/*	 * Enable INTs	 */#if 0	IOWrite1(0x00, P0_SWITCH_TO_P1);	IOWrite1(0x00, P1_ENABLE_INT);	IOWrite1(0x00, P1_SWITCH_TO_P0);#endif}/* * ====================================================================== * PACKET RECEPTION ROUTINE * ====================================================================== */static voidwlpread(sc, len, sigstat, rxaddr)	struct wlp_softc *sc;	u_int32_t       len;	u_int32_t       sigstat;	u_int32_t       rxaddr;{	struct ifnet   *ifp = &(sc->sc_ac.ac_if);	struct ether_header *eh = 0;	struct mbuf    *top = 0;	if (len > ETHER_MAX_LEN)		panic("wlpread: sc 0x%x len %d sigstat %x rxaddr %x\n",		      sc, len, sigstat, rxaddr);	MGETHDR(top, M_DONTWAIT, MT_HEADER);	if (!top)		goto bad;	top->m_pkthdr.rcvif = &sc->sc_ac.ac_if;	top->m_pkthdr.len = len;	if ((len + sizeof(sigstat)) > MINCLSIZE) {		MCLGET(top, M_DONTWAIT);		if((top->m_flags & M_EXT) == 0)			goto bad;		if (sc->sc_iftype == IFTYPE_REDWING) {			MEMRead(top->m_data, rxaddr, len);		} else if (sc->sc_iftype == IFTYPE_WAVELAN) {			IORead(0x04, top->m_data, len);		}		top->m_len = len;	} else {		u_int32_t tocopy;		tocopy = min(len, MHLEN);		if (sc->sc_iftype == IFTYPE_REDWING) {			MEMRead(top->m_data, rxaddr, tocopy);			rxaddr += tocopy;		} else if (sc->sc_iftype == IFTYPE_WAVELAN) {			IORead(0x04, top->m_data, tocopy);		}		top->m_len = tocopy;		len -= tocopy;		while (len > 0) {			register struct mbuf *m = 0;			MGET(m, M_DONTWAIT, MT_DATA);			if (!m)				goto bad;			tocopy = min(len, MLEN);			if (sc->sc_iftype == IFTYPE_REDWING) {				MEMRead(m->m_data, rxaddr, tocopy);				rxaddr += tocopy;			} else if (sc->sc_iftype == IFTYPE_WAVELAN) {				IORead(0x04, m->m_data, tocopy);			}			m->m_len = tocopy;			len -= tocopy;			m_cat(top, m);		}	}	eh = mtod(top, struct ether_header *);#if NBPFILTER > 0#ifdef MONARCH_ADHOC	/*	 *  Append the three sigstat values to the packet when	 *  tapping off.	 */	if (ifp->if_bpf) {		struct bpf_pktstat bps;		bps.bs_sigstat = sigstat;		bpf_mtap_withstat(ifp, top, &bps);	}#else	if (ifp->if_bpf)		bpf_mtap(ifp, top);#endif /* MONARCH_ADHOC */#endif /* NBPFILTER > 0 */	if (ifp->if_flags & IFF_PROMISC) {#define ETHER_MULTICAST(x)	((x)[0] & 1)#define ETHER_ADDR_MATCH(x,y)	(! bcmp((x), (y), ETHER_ADDR_LEN))		if (ETHER_MULTICAST(eh->ether_dhost) == 0 &&		    ETHER_ADDR_MATCH(eh->ether_dhost, sc->sc_ac.ac_enaddr) == 0) {			goto bad;		}	}	m_adj(top, sizeof(struct ether_header));#ifdef WAVELAN_ROAMING	/*	 * Don't pass BEACON packets up the protocol stack.	 */	if (ntohs(eh->ether_type) < 1500 &&	    bcmp(ether_wavelan_snaphdr, mtod(top, caddr_t),		 sizeof(ether_wavelan_snaphdr)) == 0) {		if (sc->sc_rs.rs_roam_enable == ROAM_ON) {			m_adj(top, sizeof(ether_wavelan_snaphdr));			wavelan_input(eh, top, sigstat);		}		m_freem(top);		return;	}#endif	sc->sc_sigstat = sigstat;	ether_input(ifp, eh, top);	return;bad:	if (top)		m_freem(top);	return;}intwlpioctl(ifp, cmd, data)	struct ifnet   *ifp;	int             cmd;	caddr_t         data;{	register struct ifaddr *ifa = (struct ifaddr *) data;	struct wlp_softc *sc = ifp->if_softc;	struct ifreq   *ifr = (struct ifreq *) data;	int             s, error = 0;	s = splimp();	if (sc->sc_gone) {		error = ENXIO;		goto done;	}	/*	 * ============================================================	 * Common ioctl()'s	 * ============================================================	 */	switch (cmd) {	case SIOCSIFADDR:		ifp->if_flags |= IFF_UP;		/* netifs are BUSY when UP */		switch (ifa->ifa_addr->sa_family) {#ifdef INET		case AF_INET:			wlpinit(sc);	/* before arpwhohas */			arp_ifinit((struct arpcom *) ifp, ifa);			break;#endif#ifdef INET6		case AF_INET6:			wlpinit(sc);			ndp6_ifinit(ifp, ifa);			break;#endif		default:			wlpinit(sc);			break;		}		break;	case SIOCGIFADDR:		{			struct sockaddr *sa;			sa = (struct sockaddr *) & ifr->ifr_data;			bcopy((caddr_t) sc->sc_ac.ac_enaddr,			      (caddr_t) sa->sa_data, ETHER_ADDR_LEN);		}		break;	case SIOCSIFFLAGS:		if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {			ifp->if_flags &= ~IFF_RUNNING;			wlpstop(sc);		} else {			/* reinitialize card on any parameter change */			wlpinit(sc);		}		break;	case SIOCSIFMTU:		/*		 * Set the interface MTU.		 */		if (ifr->ifr_mtu > ETHERMTU) {			error = EINVAL;		} else {			ifp->if_mtu = ifr->ifr_mtu;		}		break;	case SIOCADDMULTI:	case SIOCDELMULTI:		if (cmd == SIOCADDMULTI)			error = ether_addmulti(ifr, &sc->sc_ac);		else			error = ether_delmulti(ifr, &sc->sc_ac);		if (error == ENETRESET) {			wlpsetrcr(sc);			error = 0;		}		break;	case SIOCGIFSTATS:		get_ifstats(sc, ifr);		break;	default:		if (sc->sc_iftype == IFTYPE_WAVELAN)			error = wavelan_ioctl(ifp, cmd, data);		else			error = EINVAL;	}done:	splx(s);	return (error);}static voidwlpstop(sc)	struct wlp_softc *sc;{	/* Already at splimp() */	if (sc->sc_gone)		return;	IOWrite1(0x00, P0_RCV_DISABLE);}voidwlpsetrcr(sc)	struct wlp_softc *sc;{	struct ether_multi *enm;	u_int16_t       offset = 2;	if (sc->sc_iftype == IFTYPE_REDWING) {	} else if (sc->sc_iftype == IFTYPE_WAVELAN) {		WLP_PointTXBUF(WLP_TXBASE + 0x02);	}	for (enm = sc->sc_ac.ac_multiaddrs; enm; enm = enm->enm_next) {		u_int32_t       lo;		u_int32_t       hi;		lo = (enm->enm_addrlo[3] << 16) + (enm->enm_addrlo[4] << 8)			+ enm->enm_addrlo[5];		hi = (enm->enm_addrhi[3] << 16) + (enm->enm_addrhi[4] << 8)			+ enm->enm_addrhi[5];		while (lo <= hi) {			if (sc->sc_iftype == IFTYPE_REDWING) {				MEMWrite(enm->enm_addrlo, RW_RXWINDOW + offset, 3);				offset += 3;				MEMWrite1(RW_RXWINDOW + offset, ((lo >> 16) & 0xFF));				offset++;				MEMWrite1(RW_RXWINDOW + offset, ((lo >> 8) & 0xFF));				offset++;				MEMWrite1(RW_RXWINDOW + offset, (lo & 0xFF));				offset++;			} else if (sc->sc_iftype == IFTYPE_WAVELAN) {				IOWrite(0x04, enm->enm_addrlo, 3);				offset += 3;				IOWrite1(0x04, ((lo >> 16) & 0xFF));				offset++;				IOWrite1(0x04, ((lo >> 8) & 0xFF));				offset++;				IOWrite1(0x04, (lo & 0xFF));				offset++;			}			lo++;		}	}			/* for loop */	if (offset == 2)		goto done;	offset -= 2;	if (sc->sc_iftype == IFTYPE_REDWING) {		MEMWrite1(RW_RXWINDOW, (offset & 0xFF));		MEMWrite1(RW_RXWINDOW + 1, (offset >> 8) & 0xFF);		/*		 * (1) Reset the Page Control Port (Port 9)		 * (2) Reset the Transmit DMA Counters (Port 4 and 5)		 * (3) Issue the MC-SETUP command		 */#if 0		IOWrite1(0x09, (IORead1(0x09) & P9_RXBUF));#endif		RW_ResetTXDMA();	} else if (sc->sc_iftype == IFTYPE_WAVELAN) {		WLP_PointTXBUF(WLP_TXBASE);		IOWrite1(0x04, (offset & 0xFF));	/* Fill-in the length */		IOWrite1(0x04, (offset >> 8) & 0xFF);		WLP_ResetTXDMA();	}	/*	 * (1) Issue the MC-SETUP command	 */	IOWrite1(0x00, P0_MC_SETUP);done:	return;}/* * ====================================================================== * UTILITY ROUTINES * ====================================================================== */#if 0static voidwlpdump(sc)	struct wlp_softc *sc;{	/*	 * (1) Reset the 82593's internel status register pointer. 	 * (2) Disable packet reception	 * (3) Reset the Receive DMA	 * (4) Issue the DUMP command	 */	IOWrite1(0x00, P0_NOP);	IOWrite1(0x00, P0_RCV_DISABLE);	if (sc->sc_iftype == IFTYPE_REDWING) {		RW_ResetRXDMA();	} else if (sc->sc_iftype == IFTYPE_WAVELAN) {		WLP_ResetRXDMA();	}	IOWrite1(0x00, P0_DUMP);}#endifstatic voidget_ifstats(sc, ifr)	struct wlp_softc *sc;	struct ifreq   *ifr;{	struct ifstats *ifs = (struct ifstats *) ifr;	ifs->ifs_iftype = sc->sc_iftype;	ifs->ifs_unit = sc->sc_unit;	ifs->ifs_iobase = sc->sc_iobase;	ifs->ifs_iosize = sc->sc_iosize;	ifs->ifs_maddr = (int) sc->sc_maddr;	ifs->ifs_msize = sc->sc_msize;#ifdef WLP_STATS	ifs->ifs_istats.txcnt = sc->sc_txcnt;	ifs->ifs_istats.numcol = sc->sc_numcol;	ifs->ifs_istats.frtl = sc->sc_frtl;	ifs->ifs_istats.txdef = sc->sc_txdef;	ifs->ifs_istats.undrun = sc->sc_undrun;	ifs->ifs_istats.lostcts = sc->sc_lostcts;	ifs->ifs_istats.lostcrs = sc->sc_lostcrs;	ifs->ifs_istats.txok = sc->sc_txok;	ifs->ifs_istats.col = sc->sc_col;	ifs->ifs_istats.rxcnt = sc->sc_rxcnt;	ifs->ifs_istats.srtfrm = sc->sc_srtfrm;	ifs->ifs_istats.nosfd = sc->sc_nosfd;	ifs->ifs_istats.nadmch = sc->sc_nadmch;	ifs->ifs_istats.iamch = sc->sc_iamch;	ifs->ifs_istats.rcvcld = sc->sc_rcvcld;	ifs->ifs_istats.rxok = sc->sc_rxok;	ifs->ifs_istats.lenerr = sc->sc_lenerr;	ifs->ifs_istats.crcerr = sc->sc_crcerr;	ifs->ifs_istats.algerr = sc->sc_algerr;	ifs->ifs_istats.overrun = sc->sc_overrun;	ifs->ifs_istats.stopreg = sc->sc_stopreg;	ifs->ifs_istats.rexmit = sc->sc_rexmit;	ifs->ifs_istats.irqcnt = sc->sc_irqcnt;#endif	ifs->ifs_wstats.nwid = ((sc->sc_nwid[0] << 8) | sc->sc_nwid[1]);	wavelan_stats(sc, ifs);}static voiddump_bytes(tbuf, cnt)	caddr_t         tbuf;	u_int32_t       cnt;{	int             i;	cnt = cnt / 8;	for (i = 0; i < cnt; i++)		printf("byte %3d | %2x %2x %2x %2x %2x %2x %2x %2x\n",		       (i << 3), (u_char) tbuf[(i << 3) + 0], (u_char) tbuf[(i << 3) + 1],		   (u_char) tbuf[(i << 3) + 2], (u_char) tbuf[(i << 3) + 3],		   (u_char) tbuf[(i << 3) + 4], (u_char) tbuf[(i << 3) + 5],		  (u_char) tbuf[(i << 3) + 6], (u_char) tbuf[(i << 3) + 7]);	printf("\n");}

⌨️ 快捷键说明

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