Пример #1
0
static int
hn_rndis_halt(struct hn_softc *sc)
{
	struct vmbus_xact *xact;
	struct rndis_halt_req *halt;
	struct hn_nvs_sendctx sndc;
	size_t comp_len;

	xact = vmbus_xact_get(sc->hn_xact, sizeof(*halt));
	if (xact == NULL) {
		if_printf(sc->hn_ifp, "no xact for RNDIS halt\n");
		return (ENXIO);
	}
	halt = vmbus_xact_req_data(xact);
	halt->rm_type = REMOTE_NDIS_HALT_MSG;
	halt->rm_len = sizeof(*halt);
	halt->rm_rid = hn_rndis_rid(sc);

	/* No RNDIS completion; rely on NVS message send completion */
	hn_nvs_sendctx_init(&sndc, hn_nvs_sent_xact, xact);
	hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len);

	vmbus_xact_put(xact);
	if (bootverbose)
		if_printf(sc->hn_ifp, "RNDIS halt done\n");
	return (0);
}
Пример #2
0
static struct mbuf *
repack(struct sbsh_softc *sc, struct mbuf *m)
{
	struct mbuf  *m_new;

	MGETHDR(m_new, M_NOWAIT, MT_DATA);
	if (!m_new) {
		if_printf (&sc->arpcom.ac_if,
			   "unable to get mbuf.\n");
		return (NULL);
	}

	if (m->m_pkthdr.len > MHLEN) {
		MCLGET(m_new, M_NOWAIT);
		if (!(m_new->m_flags & M_EXT)) {
			m_freem(m_new);
			if_printf (&sc->arpcom.ac_if,
				   "unable to get mbuf cluster.\n");
			return (NULL);
		}
	}

	m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t));
	m_new->m_pkthdr.len = m_new->m_len = m->m_pkthdr.len;
	m_freem(m);
	return (m_new);
}
Пример #3
0
static int
txp_download_fw_wait(struct txp_softc *sc)
{
	u_int32_t i, r;

	for (i = 0; i < 10000; i++) {
		r = READ_REG(sc, TXP_ISR);
		if (r & TXP_INT_A2H_0)
			break;
		DELAY(50);
	}

	if (!(r & TXP_INT_A2H_0)) {
		if_printf(&sc->sc_arpcom.ac_if, "fw wait failed comm0\n");
		return (-1);
	}

	WRITE_REG(sc, TXP_ISR, TXP_INT_A2H_0);

	r = READ_REG(sc, TXP_A2H_0);
	if (r != STAT_WAITING_FOR_SEGMENT) {
		if_printf(&sc->sc_arpcom.ac_if, "fw not waiting for segment\n");
		return (-1);
	}
	return (0);
}
Пример #4
0
/*
 * DON'T use free_sent_buffers to drop the queue!
 */
static void
alloc_rx_buffers(struct sbsh_softc *sc)
{
	unsigned	cur_rbd = sc->regs->LRDR & 0x7f;
	struct mbuf	*m;

	while (sc->tail_rq != ((sc->head_rq - 1) & (RQLEN - 1))) {
		MGETHDR(m, M_NOWAIT, MT_DATA);
		if (!m) {
			if_printf (&sc->arpcom.ac_if,
				   "unable to get mbuf.\n");
			return;
		}

		if (SBNI16_MAX_FRAME > MHLEN) {
			MCLGET(m, M_NOWAIT);
			if (!(m->m_flags & M_EXT)) {
				m_freem(m);
				if_printf (&sc->arpcom.ac_if,
					   "unable to get mbuf cluster.\n");
				return;
			}
			m->m_pkthdr.len = m->m_len = MCLBYTES;
		}

		m_adj(m, 2);	/* align ip on longword boundaries */

		sc->rq[sc->tail_rq++] = m;
		sc->tail_rq &= (RQLEN - 1);

		sc->rbd[cur_rbd].address = vtophys(mtod(m, vm_offset_t));
		sc->rbd[cur_rbd].length  = 0;
		sc->regs->LRDR = cur_rbd = (cur_rbd + 1) & 0x7f;
	}
}
Пример #5
0
static void
le_dma_nocarrier(struct lance_softc *sc)
{
	struct le_dma_softc *lesc = (struct le_dma_softc *)sc;

	/*
	 * Check if the user has requested a certain cable type, and
	 * if so, honor that request.
	 */

	if (L64854_GCSR(lesc->sc_dma) & E_TP_AUI) {
		switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
		case IFM_10_5:
		case IFM_AUTO:
			if_printf(sc->sc_ifp, "lost carrier on UTP port, "
			    "switching to AUI port\n");
			le_dma_setaui(sc);
		}
	} else {
		switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
		case IFM_10_T:
		case IFM_AUTO:
			if_printf(sc->sc_ifp, "lost carrier on AUI port, "
			    "switching to UTP port\n");
			le_dma_setutp(sc);
		}
	}
}
Пример #6
0
static void
cx28975_interrupt(struct sbsh_softc *sc)
{
	volatile struct cx28975_cmdarea  *p = sc->cmdp;

	if (p->intr_host != 0xfe)
		return;

	if (p->out_ack & 0x80) {
		if (*((volatile u_int8_t *)p + 0x3c7) & 2) {
			if (sc->state != ACTIVE
			    && (*((volatile u_int8_t *)p + 0x3c0) & 0xc0) == 0x40) {
				activate(sc);
				if_printf(&sc->arpcom.ac_if, "connected to peer\n");
			} else if (sc->state == ACTIVE
				 && (*((volatile u_int8_t *)p + 0x3c0) & 0xc0) != 0x40) {
				deactivate(sc);
				if_printf(&sc->arpcom.ac_if, "carrier lost\n");
			}
		}

		p->intr_host = 0;
		p->out_ack = 0;
	} else {
		wakeup(sc);

		p->intr_host = 0;
	}
}
Пример #7
0
int
hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags)
{
	struct ndis_rssprm_toeplitz *rss = &sc->hn_rss;
	struct ndis_rss_params *prm = &rss->rss_params;
	int error, rss_size;

	/*
	 * Only NDIS 6.20+ is supported:
	 * We only support 4bytes element in indirect table, which has been
	 * adopted since NDIS 6.20.
	 */
	KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_20,
	    ("NDIS 6.20+ is required, NDIS version 0x%08x", sc->hn_ndis_ver));

	/* XXX only one can be specified through, popcnt? */
	KASSERT((sc->hn_rss_hash & NDIS_HASH_FUNCTION_MASK),
	    ("no hash func %08x", sc->hn_rss_hash));
	KASSERT((sc->hn_rss_hash & NDIS_HASH_STD),
	    ("no standard hash types %08x", sc->hn_rss_hash));
	KASSERT(sc->hn_rss_ind_size > 0, ("no indirect table size"));

	if (bootverbose) {
		if_printf(sc->hn_ifp, "RSS indirect table size %d, "
		    "hash 0x%08x\n", sc->hn_rss_ind_size, sc->hn_rss_hash);
	}

	/*
	 * NOTE:
	 * DO NOT whack rss_key and rss_ind, which are setup by the caller.
	 */
	memset(prm, 0, sizeof(*prm));
	rss_size = NDIS_RSSPRM_TOEPLITZ_SIZE(sc->hn_rss_ind_size);

	prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS;
	prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2;
	prm->ndis_hdr.ndis_size = rss_size;
	prm->ndis_flags = flags;
	prm->ndis_hash = sc->hn_rss_hash &
	    (NDIS_HASH_FUNCTION_MASK | NDIS_HASH_STD);
	prm->ndis_indsize = sizeof(rss->rss_ind[0]) * sc->hn_rss_ind_size;
	prm->ndis_indoffset =
	    __offsetof(struct ndis_rssprm_toeplitz, rss_ind[0]);
	prm->ndis_keysize = sizeof(rss->rss_key);
	prm->ndis_keyoffset =
	    __offsetof(struct ndis_rssprm_toeplitz, rss_key[0]);

	error = hn_rndis_set(sc, OID_GEN_RECEIVE_SCALE_PARAMETERS,
	    rss, rss_size);
	if (error) {
		if_printf(sc->hn_ifp, "RSS config failed: %d\n", error);
	} else {
		if (bootverbose)
			if_printf(sc->hn_ifp, "RSS config done\n");
	}
	return (error);
}
Пример #8
0
static int
hn_nvs_disconn_chim(struct hn_softc *sc)
{
	int error;

	if (sc->hn_flags & HN_FLAG_CHIM_CONNECTED) {
		struct hn_nvs_chim_disconn disconn;

		/*
		 * Disconnect chimney sending buffer from NVS.
		 */
		memset(&disconn, 0, sizeof(disconn));
		disconn.nvs_type = HN_NVS_TYPE_CHIM_DISCONN;
		disconn.nvs_sig = HN_NVS_CHIM_SIG;

		/* NOTE: No response. */
		error = hn_nvs_req_send(sc, &disconn, sizeof(disconn));
		if (error) {
			if_printf(sc->hn_ifp,
			    "send nvs chim disconn failed: %d\n", error);
			return (error);
		}
		sc->hn_flags &= ~HN_FLAG_CHIM_CONNECTED;

		/*
		 * Wait for the hypervisor to receive this NVS request.
		 */
		while (!vmbus_chan_tx_empty(sc->hn_prichan))
			pause("waittx", 1);
		/*
		 * Linger long enough for NVS to disconnect chimney
		 * sending buffer.
		 */
		pause("lingtx", (200 * hz) / 1000);
	}

	if (sc->hn_chim_gpadl != 0) {
		/*
		 * Disconnect chimney sending buffer from primary channel.
		 */
		error = vmbus_chan_gpadl_disconnect(sc->hn_prichan,
		    sc->hn_chim_gpadl);
		if (error) {
			if_printf(sc->hn_ifp,
			    "chim gpadl disconn failed: %d\n", error);
			return (error);
		}
		sc->hn_chim_gpadl = 0;
	}

	if (sc->hn_chim_bmap != NULL) {
		free(sc->hn_chim_bmap, M_DEVBUF);
		sc->hn_chim_bmap = NULL;
	}
	return (0);
}
Пример #9
0
static int
wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
	struct ieee80211_clone_params cp;
	struct ieee80211vap *vap;
	struct ieee80211com *ic;
	struct ifnet *ifp;
	int error;

	error = copyin(params, &cp, sizeof(cp));
	if (error)
		return error;
	ifp = ifunit(cp.icp_parent);
	if (ifp == NULL)
		return ENXIO;
	/* XXX move printfs to DIAGNOSTIC before release */
	if (ifp->if_type != IFT_IEEE80211) {
		if_printf(ifp, "%s: reject, not an 802.11 device\n", __func__);
		return ENXIO;
	}
	if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) {
		if_printf(ifp, "%s: invalid opmode %d\n",
		    __func__, cp.icp_opmode);
		return EINVAL;
	}
	ic = ifp->if_l2com;
	if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) {
		if_printf(ifp, "%s mode not supported\n",
		    ieee80211_opmode_name[cp.icp_opmode]);
		return EOPNOTSUPP;
	}
	if ((cp.icp_flags & IEEE80211_CLONE_TDMA) &&
#ifdef IEEE80211_SUPPORT_TDMA
	    (ic->ic_caps & IEEE80211_C_TDMA) == 0
#else
	    (1)
#endif
	) {
		if_printf(ifp, "TDMA not supported\n");
		return EOPNOTSUPP;
	}
#if __FreeBSD_version >= 1000020
	vap = ic->ic_vap_create(ic, wlanname, unit,
			cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
			cp.icp_flags & IEEE80211_CLONE_MACADDR ?
			    cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));
#else
	vap = ic->ic_vap_create(ic, ifc->ifc_name, unit,
			cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
			cp.icp_flags & IEEE80211_CLONE_MACADDR ?
			    cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));

#endif

	return (vap == NULL ? EIO : 0);
}
Пример #10
0
static int
hn_nvs_init(struct hn_softc *sc)
{
	int i, error;

	if (device_is_attached(sc->hn_dev)) {
		/*
		 * NVS version and NDIS version MUST NOT be changed.
		 */
		if (bootverbose) {
			if_printf(sc->hn_ifp, "reinit NVS version 0x%x, "
			    "NDIS version %u.%u\n", sc->hn_nvs_ver,
			    HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver),
			    HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver));
		}

		error = hn_nvs_doinit(sc, sc->hn_nvs_ver);
		if (error) {
			if_printf(sc->hn_ifp, "reinit NVS version 0x%x "
			    "failed: %d\n", sc->hn_nvs_ver, error);
			return (error);
		}
		goto done;
	}

	/*
	 * Find the supported NVS version and set NDIS version accordingly.
	 */
	for (i = 0; i < nitems(hn_nvs_version); ++i) {
		error = hn_nvs_doinit(sc, hn_nvs_version[i]);
		if (!error) {
			sc->hn_nvs_ver = hn_nvs_version[i];

			/* Set NDIS version according to NVS version. */
			sc->hn_ndis_ver = HN_NDIS_VERSION_6_30;
			if (sc->hn_nvs_ver <= HN_NVS_VERSION_4)
				sc->hn_ndis_ver = HN_NDIS_VERSION_6_1;

			if (bootverbose) {
				if_printf(sc->hn_ifp, "NVS version 0x%x, "
				    "NDIS version %u.%u\n", sc->hn_nvs_ver,
				    HN_NDIS_VERSION_MAJOR(sc->hn_ndis_ver),
				    HN_NDIS_VERSION_MINOR(sc->hn_ndis_ver));
			}
			goto done;
		}
	}
	if_printf(sc->hn_ifp, "no NVS available\n");
	return (ENXIO);

done:
	if (sc->hn_nvs_ver >= HN_NVS_VERSION_5)
		sc->hn_caps |= HN_CAP_HASHVAL;
	return (0);
}
Пример #11
0
static void
cac_timeout_callout(void *arg)
{
	struct ieee80211vap *vap = arg;
	struct ieee80211com *ic;
	struct ieee80211_dfs_state *dfs;
	int i;

	wlan_serialize_enter();
	ic = vap->iv_ic;
	dfs = &ic->ic_dfs;
	if (vap->iv_state != IEEE80211_S_CAC) {	/* NB: just in case */
		wlan_serialize_exit();
		return;
	}
	/*
	 * When radar is detected during a CAC we are woken
	 * up prematurely to switch to a new channel.
	 * Check the channel to decide how to act.
	 */
	if (IEEE80211_IS_CHAN_RADAR(ic->ic_curchan)) {
		ieee80211_notify_cac(ic, ic->ic_curchan,
		    IEEE80211_NOTIFY_CAC_RADAR);

		if_printf(vap->iv_ifp,
		    "CAC timer on channel %u (%u MHz) stopped due to radar\n",
		    ic->ic_curchan->ic_ieee, ic->ic_curchan->ic_freq);

		/* XXX clobbers any existing desired channel */
		/* NB: dfs->newchan may be NULL, that's ok */
		vap->iv_des_chan = dfs->newchan;
		/* XXX recursive lock need ieee80211_new_state_locked */
		ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
	} else {
		if_printf(vap->iv_ifp,
		    "CAC timer on channel %u (%u MHz) expired; "
		    "no radar detected\n",
		    ic->ic_curchan->ic_ieee, ic->ic_curchan->ic_freq);
		/*
		 * Mark all channels with the current frequency
		 * as having completed CAC; this keeps us from
		 * doing it again until we change channels.
		 */
		for (i = 0; i < ic->ic_nchans; i++) {
			struct ieee80211_channel *c = &ic->ic_channels[i];
			if (c->ic_freq == ic->ic_curchan->ic_freq)
				c->ic_state |= IEEE80211_CHANSTATE_CACDONE;
		}
		ieee80211_notify_cac(ic, ic->ic_curchan,
		    IEEE80211_NOTIFY_CAC_EXPIRE);
		ieee80211_cac_completeswitch(vap);
	}
	wlan_serialize_exit();
}
Пример #12
0
static const void *
hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid,
    size_t reqlen, size_t *comp_len0, uint32_t comp_type)
{
	const struct rndis_comp_hdr *comp;
	size_t comp_len, min_complen = *comp_len0;

	KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid));
	KASSERT(min_complen >= sizeof(*comp),
	    ("invalid minimum complete len %zu", min_complen));

	/*
	 * Execute the xact setup by the caller.
	 */
	comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_nvs_sendctx_none,
	    &comp_len);
	if (comp == NULL)
		return (NULL);

	/*
	 * Check this RNDIS complete message.
	 */
	if (comp_len < min_complen) {
		if (comp_len >= sizeof(*comp)) {
			/* rm_status field is valid */
			if_printf(sc->hn_ifp, "invalid RNDIS comp len %zu, "
			    "status 0x%08x\n", comp_len, comp->rm_status);
		} else {
			if_printf(sc->hn_ifp, "invalid RNDIS comp len %zu\n",
			    comp_len);
		}
		return (NULL);
	}
	if (comp->rm_len < min_complen) {
		if_printf(sc->hn_ifp, "invalid RNDIS comp msglen %u\n",
		    comp->rm_len);
		return (NULL);
	}
	if (comp->rm_type != comp_type) {
		if_printf(sc->hn_ifp, "unexpected RNDIS comp 0x%08x, "
		    "expect 0x%08x\n", comp->rm_type, comp_type);
		return (NULL);
	}
	if (comp->rm_rid != rid) {
		if_printf(sc->hn_ifp, "RNDIS comp rid mismatch %u, "
		    "expect %u\n", comp->rm_rid, rid);
		return (NULL);
	}
	/* All pass! */
	*comp_len0 = comp_len;
	return (comp);
}
Пример #13
0
static void
announce_radar(struct ifnet *ifp, const struct ieee80211_channel *curchan,
               const struct ieee80211_channel *newchan)
{
    if (newchan == NULL)
        if_printf(ifp, "radar detected on channel %u (%u MHz)\n",
                  curchan->ic_ieee, curchan->ic_freq);
    else
        if_printf(ifp, "radar detected on channel %u (%u MHz), "
                  "moving to channel %u (%u MHz)\n",
                  curchan->ic_ieee, curchan->ic_freq,
                  newchan->ic_ieee, newchan->ic_freq);
}
Пример #14
0
static void
sbsh_watchdog(struct ifnet *ifp)
{
	struct sbsh_softc	*sc = ifp->if_softc;

	if_printf(ifp, "transmit timeout\n");

	if (sc->regs->SR & TXS) {
		sc->regs->SR = TXS;
		if_printf(ifp, "interrupt posted but not delivered\n");
	}
	free_sent_buffers(sc);
}
Пример #15
0
/*
 * Net VSC on receive
 *
 * In the FreeBSD Hyper-V virtual world, this function deals exclusively
 * with virtual addresses.
 */
static void
hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
    struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
{
	const struct vmbus_chanpkt_rxbuf *pkt;
	const nvsp_msg *nvsp_msg_pkt;
	netvsc_packet vsc_pkt;
	netvsc_packet *net_vsc_pkt = &vsc_pkt;
	int count = 0;
	int i = 0;
	int status = nvsp_status_success;

	nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr);

	/* Make sure this is a valid nvsp packet */
	if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
		if_printf(rxr->hn_ifp, "packet hdr type %u is invalid!\n",
		    nvsp_msg_pkt->hdr.msg_type);
		return;
	}
	
	pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;

	if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
		if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n",
		    pkt->cp_rxbuf_id);
		return;
	}

	count = pkt->cp_rxbuf_cnt;

	/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
	for (i = 0; i < count; i++) {
		net_vsc_pkt->status = nvsp_status_success;
		net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
		    pkt->cp_rxbuf[i].rb_ofs);
		net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;

		hv_rf_on_receive(net_dev, rxr, net_vsc_pkt);
		if (net_vsc_pkt->status != nvsp_status_success) {
			status = nvsp_status_failure;
		}
	}
	
	/*
	 * Moved completion call back here so that all received 
	 * messages (not just data messages) will trigger a response
	 * message back to the host.
	 */
	hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status);
}
Пример #16
0
static int
hn_nvs_disconn_rxbuf(struct hn_softc *sc)
{
	int error;

	if (sc->hn_flags & HN_FLAG_RXBUF_CONNECTED) {
		struct hn_nvs_rxbuf_disconn disconn;

		/*
		 * Disconnect RXBUF from NVS.
		 */
		memset(&disconn, 0, sizeof(disconn));
		disconn.nvs_type = HN_NVS_TYPE_RXBUF_DISCONN;
		disconn.nvs_sig = HN_NVS_RXBUF_SIG;

		/* NOTE: No response. */
		error = hn_nvs_req_send(sc, &disconn, sizeof(disconn));
		if (error) {
			if_printf(sc->hn_ifp,
			    "send nvs rxbuf disconn failed: %d\n", error);
			return (error);
		}
		sc->hn_flags &= ~HN_FLAG_RXBUF_CONNECTED;

		/*
		 * Wait for the hypervisor to receive this NVS request.
		 */
		while (!vmbus_chan_tx_empty(sc->hn_prichan))
			pause("waittx", 1);
		/*
		 * Linger long enough for NVS to disconnect RXBUF.
		 */
		pause("lingtx", (200 * hz) / 1000);
	}

	if (sc->hn_rxbuf_gpadl != 0) {
		/*
		 * Disconnect RXBUF from primary channel.
		 */
		error = vmbus_chan_gpadl_disconnect(sc->hn_prichan,
		    sc->hn_rxbuf_gpadl);
		if (error) {
			if_printf(sc->hn_ifp,
			    "rxbuf gpadl disconn failed: %d\n", error);
			return (error);
		}
		sc->hn_rxbuf_gpadl = 0;
	}
	return (0);
}
Пример #17
0
static int
hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, size_t dlen)
{
	struct rndis_set_req *req;
	const struct rndis_set_comp *comp;
	struct vmbus_xact *xact;
	size_t reqlen, comp_len;
	uint32_t rid;
	int error;

	KASSERT(dlen > 0, ("invalid dlen %zu", dlen));

	reqlen = sizeof(*req) + dlen;
	xact = vmbus_xact_get(sc->hn_xact, reqlen);
	if (xact == NULL) {
		if_printf(sc->hn_ifp, "no xact for RNDIS set 0x%08x\n", oid);
		return (ENXIO);
	}
	rid = hn_rndis_rid(sc);
	req = vmbus_xact_req_data(xact);
	req->rm_type = REMOTE_NDIS_SET_MSG;
	req->rm_len = reqlen;
	req->rm_rid = rid;
	req->rm_oid = oid;
	req->rm_infobuflen = dlen;
	req->rm_infobufoffset = RNDIS_SET_REQ_INFOBUFOFFSET;
	/* Data immediately follows RNDIS set. */
	memcpy(req + 1, data, dlen);

	comp_len = sizeof(*comp);
	comp = hn_rndis_xact_execute(sc, xact, rid, reqlen, &comp_len,
	    REMOTE_NDIS_SET_CMPLT);
	if (comp == NULL) {
		if_printf(sc->hn_ifp, "exec RNDIS set 0x%08x failed\n", oid);
		error = EIO;
		goto done;
	}

	if (comp->rm_status != RNDIS_STATUS_SUCCESS) {
		if_printf(sc->hn_ifp, "RNDIS set 0x%08x failed: "
		    "status 0x%08x\n", oid, comp->rm_status);
		error = EIO;
		goto done;
	}
	error = 0;
done:
	vmbus_xact_put(xact);
	return (error);
}
Пример #18
0
static void
bwi_phy_init_11b_rev2(struct bwi_mac *mac)
{ 
	/* TODO:11B */
	if_printf(mac->mac_sc->sc_ifp,
		  "%s is not implemented yet\n", __func__);
}
Пример #19
0
/*
 * Queue a number of TPD. If there is not enough space none of the TPDs
 * is queued and an error code is returned.
 */
static int
hatm_queue_tpds(struct hatm_softc *sc, u_int count, struct tpd **list,
    u_int cid)
{
	u_int space;
	u_int i;

	if (count >= sc->tpdrq.size) {
		sc->istats.tdprq_full++;
		return (EBUSY);
	}

	if (sc->tpdrq.tail < sc->tpdrq.head)
		space = sc->tpdrq.head - sc->tpdrq.tail;
	else
		space = sc->tpdrq.head - sc->tpdrq.tail +  sc->tpdrq.size;

	if (space <= count) {
		sc->tpdrq.head =
		    (READ4(sc, HE_REGO_TPDRQ_H) >> HE_REGS_TPDRQ_H_H) &
		    (sc->tpdrq.size - 1);

		if (sc->tpdrq.tail < sc->tpdrq.head)
			space = sc->tpdrq.head - sc->tpdrq.tail;
		else
			space = sc->tpdrq.head - sc->tpdrq.tail +
			    sc->tpdrq.size;

		if (space <= count) {
			if_printf(sc->ifp, "TPDRQ full\n");
			sc->istats.tdprq_full++;
			return (EBUSY);
		}
	}
Пример #20
0
void
ep_get_media(struct ep_softc *sc)
{
	u_int16_t		config;
	
        GO_WINDOW(0);
        config = inw(BASE + EP_W0_CONFIG_CTRL);
        if (config & IS_AUI)
                sc->ep_connectors |= AUI;
        if (config & IS_BNC)
                sc->ep_connectors |= BNC;
        if (config & IS_UTP)
                sc->ep_connectors |= UTP;

        if (!(sc->ep_connectors & 7)) {
		if (bootverbose)
                	if_printf(&sc->arpcom.ac_if, "no connectors!\n");
        }

	/*
	 * This works for most of the cards so we'll do it here.
	 * The cards that require something different can override
	 * this later on.
	 */
	sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;

	return;
}
Пример #21
0
static void
amrr_node_init(struct ieee80211_node *ni)
{
	const struct ieee80211_rateset *rs = &ni->ni_rates;
	struct ieee80211vap *vap = ni->ni_vap;
	struct ieee80211_amrr *amrr = vap->iv_rs;
	struct ieee80211_amrr_node *amn;

	if (ni->ni_rctls == NULL) {
		ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node),
		    M_80211_RATECTL, M_NOWAIT|M_ZERO);
		if (amn == NULL) {
			if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
			    "structure\n");
			return;
		}
	} else
		amn = ni->ni_rctls;
	amn->amn_amrr = amrr;
	amn->amn_success = 0;
	amn->amn_recovery = 0;
	amn->amn_txcnt = amn->amn_retrycnt = 0;
	amn->amn_success_threshold = amrr->amrr_min_success_threshold;

	/* pick initial rate */
	for (amn->amn_rix = rs->rs_nrates - 1;
	     amn->amn_rix > 0 && (rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL) > 72;
	     amn->amn_rix--)
		;
	ni->ni_txrate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
	amn->amn_ticks = ticks;

	IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
	    "AMRR initial rate %d", ni->ni_txrate);
}
Пример #22
0
/*
 * Convert channel to IEEE channel number.
 */
u_int
ieee80211_chan2ieee(struct ieee80211com *ic, struct ieee80211_channel *c)
{
	if (ic->ic_channels <= c && c <= &ic->ic_channels[IEEE80211_CHAN_MAX])
		return c - ic->ic_channels;
	else if (c == IEEE80211_CHAN_ANYC)
		return IEEE80211_CHAN_ANY;
	else if (c != NULL) {
		if_printf(ic->ic_ifp, "invalid channel freq %u flags %x\n",
			c->ic_freq, c->ic_flags);
		return 0;		/* XXX */
	} else {
		if_printf(ic->ic_ifp, "invalid channel (NULL)\n");
		return 0;		/* XXX */
	}
}
Пример #23
0
/*
 * INTR arrived
 */
static void
lgue_intreof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
	struct ifnet *ifp;
	struct lgue_softc *sc;

	sc = priv;
	if (sc->lgue_dying)
		return;

	ifp = &sc->lgue_arpcom.ac_if;
	lwkt_serialize_enter(ifp->if_serializer);
	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
			lwkt_serialize_exit(ifp->if_serializer);
			return;
		}
		if_printf(ifp, "usb error on intr: %s\n", usbd_errstr(status));
		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall(sc->lgue_ep[LGUE_ENDPT_INTR]);
		lwkt_serialize_exit(ifp->if_serializer);
		return;
	}
	lgue_intrstart(ifp);
	lwkt_serialize_exit(ifp->if_serializer);
}
Пример #24
0
static int
null_output(struct ifnet *ifp, struct mbuf *m,
	struct sockaddr *dst, struct rtentry *ro)
{
	if_printf(ifp, "discard raw packet\n");
	return null_transmit(ifp, m);
}
static void
amrr_node_init(struct ieee80211_node *ni)
{
	const struct ieee80211_rateset *rs = NULL;
	struct ieee80211vap *vap = ni->ni_vap;
	struct ieee80211_amrr *amrr = vap->iv_rs;
	struct ieee80211_amrr_node *amn;
	uint8_t rate;

	if (ni->ni_rctls == NULL) {
		ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node),
		    M_80211_RATECTL, M_NOWAIT|M_ZERO);
		if (amn == NULL) {
			if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
			    "structure\n");
			return;
		}
	} else
		amn = ni->ni_rctls;

	amn->amn_amrr = amrr;
	amn->amn_success = 0;
	amn->amn_recovery = 0;
	amn->amn_txcnt = amn->amn_retrycnt = 0;
	amn->amn_success_threshold = amrr->amrr_min_success_threshold;

	rs = ieee80211_ratectl_get_rateset(ni);

	/* Initial rate - lowest */
	rate = rs->rs_rates[0];

	/* XXX clear the basic rate flag if it's not 11n */
	if (! ieee80211_ratectl_node_is11n(ni))
		rate &= IEEE80211_RATE_VAL;

	/* pick initial rate from the rateset - HT or otherwise */
	for (amn->amn_rix = rs->rs_nrates - 1; amn->amn_rix > 0;
	    amn->amn_rix--) {
		/* legacy - anything < 36mbit, stop searching */
		/* 11n - stop at MCS4 / MCS12 / MCS28 */
		if (ieee80211_ratectl_node_is11n(ni) &&
		    (rs->rs_rates[amn->amn_rix] & 0x7) < 4)
			break;
		else if ((rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL) <= 72)
			break;
		rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
	}

	/* if the rate is an 11n rate, ensure the MCS bit is set */
	if (ieee80211_ratectl_node_is11n(ni))
		rate |= IEEE80211_RATE_MCS;

	/* Assign initial rate from the rateset */
	ni->ni_txrate = rate;
	amn->amn_ticks = ticks;

	IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
	    "%s: AMRR: nrates=%d, initial rate %d",
		__func__, rs->rs_nrates, rate);
}
Пример #26
0
static int
txp_reset_adapter(struct txp_softc *sc)
{
	u_int32_t r;
	int i;

	WRITE_REG(sc, TXP_SRR, TXP_SRR_ALL);
	DELAY(1000);
	WRITE_REG(sc, TXP_SRR, 0);

	/* Should wait max 6 seconds */
	for (i = 0; i < 6000; i++) {
		r = READ_REG(sc, TXP_A2H_0);
		if (r == STAT_WAITING_FOR_HOST_REQUEST)
			break;
		DELAY(1000);
	}

	if (r != STAT_WAITING_FOR_HOST_REQUEST) {
		if_printf(&sc->sc_arpcom.ac_if, "reset hung\n");
		return (-1);
	}

	return (0);
}
Пример #27
0
/*
 * Handles creation of the ethernet header, then places outgoing packets into
 * the tx buffer for the NIC
 *
 * Parameters:
 *	m	The mbuf containing the packet to be sent (will be freed by
 *		this function or the NIC driver)
 *	ifp	The interface to send on
 *	dst	The destination ethernet address (source address will be looked
 *		up using ifp)
 *	etype	The ETHERTYPE_* value for the protocol that is being sent
 *
 * Returns:
 *	int	see errno.h, 0 for success
 */
static int
netdump_ether_output(struct mbuf *m, struct ifnet *ifp, struct ether_addr dst,
    u_short etype)
{
	struct ether_header *eh;

	if (((ifp->if_flags & (IFF_MONITOR | IFF_UP)) != IFF_UP) ||
	    (ifp->if_drv_flags & IFF_DRV_RUNNING) != IFF_DRV_RUNNING) {
		if_printf(ifp, "netdump_ether_output: interface isn't up\n");
		m_freem(m);
		return (ENETDOWN);
	}

	/* Fill in the ethernet header. */
	M_PREPEND(m, ETHER_HDR_LEN, M_NOWAIT);
	if (m == NULL) {
		printf("%s: out of mbufs\n", __func__);
		return (ENOBUFS);
	}
	eh = mtod(m, struct ether_header *);
	memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN);
	memcpy(eh->ether_dhost, dst.octet, ETHER_ADDR_LEN);
	eh->ether_type = htons(etype);
	return ((ifp->if_netdump_methods->nd_transmit)(ifp, m));
}
Пример #28
0
static const void *
hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact,
    void *req, int reqlen, size_t *resplen0, uint32_t type)
{
	struct hn_nvs_sendctx sndc;
	size_t resplen, min_resplen = *resplen0;
	const struct hn_nvs_hdr *hdr;
	int error;

	KASSERT(min_resplen >= sizeof(*hdr),
	    ("invalid minimum response len %zu", min_resplen));

	/*
	 * Execute the xact setup by the caller.
	 */
	hn_nvs_sendctx_init(&sndc, hn_nvs_sent_xact, xact);

	vmbus_xact_activate(xact);
	error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
	    req, reqlen, &sndc);
	if (error) {
		vmbus_xact_deactivate(xact);
		return (NULL);
	}
	if (HN_CAN_SLEEP(sc))
		hdr = vmbus_xact_wait(xact, &resplen);
	else
		hdr = vmbus_xact_busywait(xact, &resplen);

	/*
	 * Check this NVS response message.
	 */
	if (resplen < min_resplen) {
		if_printf(sc->hn_ifp, "invalid NVS resp len %zu\n", resplen);
		return (NULL);
	}
	if (hdr->nvs_type != type) {
		if_printf(sc->hn_ifp, "unexpected NVS resp 0x%08x, "
		    "expect 0x%08x\n", hdr->nvs_type, type);
		return (NULL);
	}
	/* All pass! */
	*resplen0 = resplen;
	return (hdr);
}
Пример #29
0
static int
hn_nvs_doinit(struct hn_softc *sc, uint32_t nvs_ver)
{
	struct vmbus_xact *xact;
	struct hn_nvs_init *init;
	const struct hn_nvs_init_resp *resp;
	size_t resp_len;
	uint32_t status;

	xact = vmbus_xact_get(sc->hn_xact, sizeof(*init));
	if (xact == NULL) {
		if_printf(sc->hn_ifp, "no xact for nvs init\n");
		return (ENXIO);
	}
	init = vmbus_xact_req_data(xact);
	init->nvs_type = HN_NVS_TYPE_INIT;
	init->nvs_ver_min = nvs_ver;
	init->nvs_ver_max = nvs_ver;

	resp_len = sizeof(*resp);
	resp = hn_nvs_xact_execute(sc, xact, init, sizeof(*init), &resp_len,
	    HN_NVS_TYPE_INIT_RESP);
	if (resp == NULL) {
		if_printf(sc->hn_ifp, "exec init failed\n");
		vmbus_xact_put(xact);
		return (EIO);
	}

	status = resp->nvs_status;
	vmbus_xact_put(xact);

	if (status != HN_NVS_STATUS_OK) {
		if (bootverbose) {
			/*
			 * Caller may try another NVS version, and will log
			 * error if there are no more NVS versions to try,
			 * so don't bark out loud here.
			 */
			if_printf(sc->hn_ifp, "nvs init failed for ver 0x%x\n",
			    nvs_ver);
		}
		return (EINVAL);
	}
	return (0);
}
Пример #30
0
/*
 * A frame has been uploaded: pass the resulting mbuf up to
 * the higher level protocols.
 */
static void
lgue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
	struct lgue_softc	*sc;
	struct mbuf		*m;
	struct ifnet	*ifp;
	int			total_len;

	sc = priv;
	if (sc->lgue_dying)
		return;

	ifp = &sc->lgue_arpcom.ac_if;

	total_len = 0;

	if (!(ifp->if_flags & IFF_RUNNING))
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
			return;
		if (usbd_ratecheck(&sc->lgue_rx_notice)) {
			if_printf(ifp, "usb error on rx:%s\n",
			    usbd_errstr(status));
		}
		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall(sc->lgue_ep[LGUE_ENDPT_RX]);
		goto done;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);

	if (total_len < sizeof(struct ether_header)) {
		IFNET_STAT_INC(ifp, ierrors, 1);
		goto done;
	}

	if (lgue_newbuf(sc, total_len, &m) == ENOBUFS) {
		IFNET_STAT_INC(ifp, ierrors, 1);
		return;
	}

	IFNET_STAT_INC(ifp, ipackets, 1);
	m_copyback(m, 0, total_len, sc->lgue_rx_buf);
	m->m_pkthdr.rcvif = ifp;
	m->m_pkthdr.len = m->m_len = total_len;

	usb_ether_input(m);
	lgue_rxstart(ifp);
	return;
done:
	usbd_setup_xfer(sc->lgue_rx_xfer, sc->lgue_ep[LGUE_ENDPT_RX], sc,
	    sc->lgue_rx_buf, LGUE_BUFSZ,
	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, lgue_rxeof);
	usbd_transfer(sc->lgue_rx_xfer);
}