rendered paste body#include <sys/cmn_err.h>#define ZYDNAME "zyd"uint8_tzyd_plcp_signal(uint16_t rate){ volatile uint8_t ret; cmn_err(CE_WARN, ZYDNAME, "%s: zyd_plcp_signal(): Enter.\n", __func__); cmn_err(CE_WARN, ZYDNAME, "%s: rate = %u\n", __func__, rate); switch ((int) rate) { /* CCK rates (returned values are device-dependent) */ case 2: ret = 0x0; case 4: ret = 0x1; case 11: ret = 0x2; case 22: ret = 0x3; /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ case 12: ret = 0xb; case 18: ret = 0xf; case 24: ret = 0xa; case 36: ret = 0xe; case 48: ret = 0x9; case 72: ret = 0xd; case 96: ret = 0x8; case 108: ret = 0xc; /* unsupported rates (should not get there) */ default: ret = 0xff; } cmn_err(CE_WARN, ZYDNAME, "%s: ret = %u (%x)\n", __func__, ret, ret); cmn_err(CE_WARN, ZYDNAME, "%s: Exit.\n", __func__); return ret;}/* * */zyd_reszyd_hw_send_frame(ieee80211com_t *ic, struct zyd_softc *sc, mblk_t *mp){ void *buffer; uint8_t *buf_data; struct zyd_tx_header *buf_hdr; struct ieee80211_frame *wh; struct ieee80211_node *in; struct ieee80211_key *k; mblk_t *m, *m0; int len, total_len, off, mblen; uint16_t frame_size, additional_size, rate; uint8_t service; cmn_err(CE_WARN, ZYDNAME, "%s: Enter.\n", __func__); m = allocb(msgdsize(mp) + 32, BPRI_MED); if (m == NULL) { sc->tx_nobuf++; return (ZYD_FAILURE); } for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) { mblen = MBLKL(m0); (void) memcpy(m->b_rptr + off, m0->b_rptr, mblen); off += mblen; } cmn_err(CE_WARN, ZYDNAME, "%s: m->b_wptr = 0x%x\n", __func__, m->b_wptr); m->b_wptr += off; cmn_err(CE_WARN, ZYDNAME, "%s: m->b_wptr = 0x%x\n", __func__, m->b_wptr); wh = (struct ieee80211_frame *)m->b_rptr; in = ieee80211_find_txnode(ic, wh->i_addr1); if (in == NULL) { freemsg(m); sc->tx_err++; return (ZYD_FAILURE); } in->in_inact = 0; (void) ieee80211_encap(ic, m, in); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { k = ieee80211_crypto_encap(ic, m); if (k == NULL) { sc->tx_err++; ieee80211_free_node(in); freemsg(m); return (ZYD_FAILURE); } /* packet header may have moved, reset our local pointer */ wh = (struct ieee80211_frame *)m->b_rptr; } /* * pickup a rate. May need work to make adaptive - at present, * picks best rate for mode. */ if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) { /* mgmt frames are sent at 1M */ rate = (uint16_t)in->in_rates.ir_rates[0]; } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { rate = (uint16_t)ic->ic_sup_rates[ic->ic_curmode]. ir_rates[ic->ic_fixed_rate]; } else { in->in_txrate = in->in_rates.ir_nrates - 1; rate = (uint16_t)ic->ic_sup_rates[ic->ic_curmode]. ir_rates[in->in_txrate]; } rate &= IEEE80211_RATE_VAL; if (rate == 0) /* XXX should not happen */ rate = 2; /* Get total length of frame */ len = msgsize(m); /* Total number of bytes to send to the chip */ total_len = sizeof (struct zyd_tx_header) + len; /* Allocate a buffer to store the packet */ buffer = kmem_alloc(total_len, KM_NOSLEEP); if (buffer == NULL) { ieee80211_free_node(in); freemsg(m); return (ZYD_FAILURE); } /* Get pointers to header buffer and 802.11 frame buffer */ buf_hdr = (struct zyd_tx_header *)buffer; buf_data = ((uint8_t *)buffer) + sizeof (struct zyd_tx_header); /*** Fill header information ***/ /* * Frame size in bytes including CRC32 checksum */ frame_size = (uint16_t)len + IEEE80211_FCS_LEN; buf_hdr->frame_size = LE_16(frame_size); /* * Compute "packet size". What the 10 stands for, * nobody knows. */ additional_size = sizeof (struct zyd_tx_header) + 10; cmn_err(CE_WARN, ZYDNAME, "%s: additional_size = %u\n", __func__, additional_size); cmn_err(CE_WARN, ZYDNAME, "%s: buf_hdr = 0x%x\n", __func__, buf_hdr); if (sc->mac_rev == ZYD_ZD1211) buf_hdr->packet_size = LE_16(frame_size + additional_size); else buf_hdr->packet_size = LE_16(additional_size); buf_hdr->rate_mod_flags = 0x0; cmn_err(CE_WARN, ZYDNAME, "%s: buf_hdr->packet_size = %u buf_hdr->rate_mod_flags = %u\n", __func__, buf_hdr->packet_size, buf_hdr->rate_mod_flags); cmn_err(CE_WARN, ZYDNAME, "%s: BEFORE zyd_plcp_signal\n", __func__); buf_hdr->rate_mod_flags = LE_8(zyd_plcp_signal(rate)); cmn_err(CE_WARN, ZYDNAME, "%s: AFTER zyd_plcp_signal\n", __func__); cmn_err(CE_WARN, ZYDNAME, "%s: buf_hdr->packet_size = %u buf_hdr->rate_mod_flags = %u\n", __func__, buf_hdr->packet_size, buf_hdr->rate_mod_flags); buf_hdr->type_flags = LE_8(ZYD_TX_FLAG_BACKOFF); cmn_err(CE_WARN, ZYDNAME, "%s: buf_hdr->packet_size = %u buf_hdr->rate_mod_flags = %u buf_hdr->type_flags = %u\n", __func__, buf_hdr->packet_size, buf_hdr->rate_mod_flags, buf_hdr->type_flags); if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { /* multicast frames are not sent at OFDM rates in 802.11b/g */ if (frame_size > ic->ic_rtsthreshold) { buf_hdr->type_flags |= ZYD_TX_FLAG_RTS; } else if (ZYD_RATE_IS_OFDM(rate) && (ic->ic_flags & IEEE80211_F_USEPROT)) { if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) buf_hdr->type_flags |= ZYD_TX_FLAG_CTS_TO_SELF; else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) buf_hdr->type_flags |= ZYD_TX_FLAG_RTS; } } else buf_hdr->type_flags |= ZYD_TX_FLAG_MULTICAST; if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) buf_hdr->type_flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); if (ZYD_RATE_IS_OFDM(rate)) { buf_hdr->rate_mod_flags |= ZYD_TX_RMF_OFDM; if (ic->ic_curmode == IEEE80211_MODE_11A) buf_hdr->rate_mod_flags |= ZYD_TX_RMF_5GHZ; } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) buf_hdr->rate_mod_flags |= ZYD_TX_RMF_SH_PREAMBLE; /* * Compute frame duration and length-extension service flag. */ service = 0x00; buf_hdr->frame_duration = LE_16((16 * frame_size + rate - 1) / rate); buf_hdr->service = LE_8(service); buf_hdr->next_frame_duration = LE_16(0); if (rate == 22) { const int remainder = (16 * frame_size) % 22; if (remainder != 0 && remainder < 7) buf_hdr->service |= ZYD_TX_SERVICE_LENGTH_EXTENSION; } /* Copy the 802.11 frame */ mcopymsg(m, buf_data); /* Send it to the device */ zyd_usb_send_packet(&sc->usb, buffer, total_len); ic->ic_stats.is_tx_frags++; ic->ic_stats.is_tx_bytes += buf_hdr->packet_size; /* Free memory */ ieee80211_free_node(in); kmem_free(buffer, total_len); buffer = NULL; buf_hdr = NULL; buf_data = NULL; cmn_err(CE_WARN, ZYDNAME, "%s: Exit. (ZYD_SUCCESS)\n", __func__); return (ZYD_SUCCESS);}