All pastes #928668 Raw Edit

Mine

public c v1 · immutable
·published 2008-03-05 05:56 UTC
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; break;        case 4:         ret = 0x1; break;        case 11:        ret = 0x2; break;        case 22:        ret = 0x3; break;        /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */        case 12:        ret = 0xb; break;        case 18:        ret = 0xf; break;        case 24:        ret = 0xa; break;        case 36:        ret = 0xe; break;        case 48:        ret = 0x9; break;        case 72:        ret = 0xd; break;        case 96:        ret = 0x8; break;        case 108:       ret = 0xc; break;       /* unsupported rates (should not get there) */        default:        ret = 0xff; break;    }    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);}