Lines 42-48
Link Here
|
42 |
* |
42 |
* |
43 |
* A similar thing happens with the tx rings. The difference is the firmware |
43 |
* A similar thing happens with the tx rings. The difference is the firmware |
44 |
* stop processing buffers once the queue is full and until confirmation |
44 |
* stop processing buffers once the queue is full and until confirmation |
45 |
* of a successful transmition (tx_intr) has occurred. |
45 |
* of a successful transmition (tx_done) has occurred. |
46 |
* |
46 |
* |
47 |
* The command ring operates in the same manner as the tx queues. |
47 |
* The command ring operates in the same manner as the tx queues. |
48 |
* |
48 |
* |
Lines 447-452
Link Here
|
447 |
ic->ic_cryptocaps = |
447 |
ic->ic_cryptocaps = |
448 |
IEEE80211_CRYPTO_AES_CCM; |
448 |
IEEE80211_CRYPTO_AES_CCM; |
449 |
|
449 |
|
|
|
450 |
ic->ic_flags |= IEEE80211_F_DATAPAD; |
451 |
|
450 |
/* |
452 |
/* |
451 |
* Read in the eeprom and also setup the channels for |
453 |
* Read in the eeprom and also setup the channels for |
452 |
* net80211. We don't set the rates as net80211 does this for us |
454 |
* net80211. We don't set the rates as net80211 does this for us |
Lines 1378-1385
Link Here
|
1378 |
"adding chan %d (%dMHz) flags=0x%x maxpwr=%d passive=%d," |
1380 |
"adding chan %d (%dMHz) flags=0x%x maxpwr=%d passive=%d," |
1379 |
" offset %d\n", chan, c->ic_freq, |
1381 |
" offset %d\n", chan, c->ic_freq, |
1380 |
channels[i].flags, sc->maxpwr[chan], |
1382 |
channels[i].flags, sc->maxpwr[chan], |
1381 |
(c->ic_flags & IEEE80211_CHAN_PASSIVE) != 0, |
1383 |
IEEE80211_IS_CHAN_PASSIVE(c), ic->ic_nchans); |
1382 |
ic->ic_nchans); |
|
|
1383 |
} |
1384 |
} |
1384 |
} |
1385 |
} |
1385 |
|
1386 |
|
Lines 1695-1702
Link Here
|
1695 |
|
1696 |
|
1696 |
if (stat->len > WPI_STAT_MAXLEN) { |
1697 |
if (stat->len > WPI_STAT_MAXLEN) { |
1697 |
device_printf(sc->sc_dev, "invalid RX statistic header\n"); |
1698 |
device_printf(sc->sc_dev, "invalid RX statistic header\n"); |
1698 |
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1699 |
goto fail1; |
1699 |
return; |
|
|
1700 |
} |
1700 |
} |
1701 |
|
1701 |
|
1702 |
bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD); |
1702 |
bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD); |
Lines 1714-1728
Link Here
|
1714 |
if ((flags & WPI_RX_NOERROR) != WPI_RX_NOERROR) { |
1714 |
if ((flags & WPI_RX_NOERROR) != WPI_RX_NOERROR) { |
1715 |
DPRINTF(sc, WPI_DEBUG_RECV, "%s: RX flags error %x\n", |
1715 |
DPRINTF(sc, WPI_DEBUG_RECV, "%s: RX flags error %x\n", |
1716 |
__func__, flags); |
1716 |
__func__, flags); |
1717 |
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1717 |
goto fail1; |
1718 |
return; |
|
|
1719 |
} |
1718 |
} |
1720 |
/* Discard frames that are too short. */ |
1719 |
/* Discard frames that are too short. */ |
1721 |
if (len < sizeof (*wh)) { |
1720 |
if (len < sizeof (*wh)) { |
1722 |
DPRINTF(sc, WPI_DEBUG_RECV, "%s: frame too short: %d\n", |
1721 |
DPRINTF(sc, WPI_DEBUG_RECV, "%s: frame too short: %d\n", |
1723 |
__func__, len); |
1722 |
__func__, len); |
1724 |
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1723 |
goto fail1; |
1725 |
return; |
|
|
1726 |
} |
1724 |
} |
1727 |
|
1725 |
|
1728 |
m1 = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE); |
1726 |
m1 = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE); |
Lines 1729-1736
Link Here
|
1729 |
if (m1 == NULL) { |
1727 |
if (m1 == NULL) { |
1730 |
DPRINTF(sc, WPI_DEBUG_ANY, "%s: no mbuf to restock ring\n", |
1728 |
DPRINTF(sc, WPI_DEBUG_ANY, "%s: no mbuf to restock ring\n", |
1731 |
__func__); |
1729 |
__func__); |
1732 |
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1730 |
goto fail1; |
1733 |
return; |
|
|
1734 |
} |
1731 |
} |
1735 |
bus_dmamap_unload(ring->data_dmat, data->map); |
1732 |
bus_dmamap_unload(ring->data_dmat, data->map); |
1736 |
|
1733 |
|
Lines 1752-1759
Link Here
|
1752 |
ring->desc[ring->cur] = htole32(paddr); |
1749 |
ring->desc[ring->cur] = htole32(paddr); |
1753 |
bus_dmamap_sync(ring->data_dmat, ring->desc_dma.map, |
1750 |
bus_dmamap_sync(ring->data_dmat, ring->desc_dma.map, |
1754 |
BUS_DMASYNC_PREWRITE); |
1751 |
BUS_DMASYNC_PREWRITE); |
1755 |
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1752 |
goto fail1; |
1756 |
return; |
|
|
1757 |
} |
1753 |
} |
1758 |
|
1754 |
|
1759 |
m = data->m; |
1755 |
m = data->m; |
Lines 1777-1794
Link Here
|
1777 |
if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && |
1773 |
if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && |
1778 |
!IEEE80211_IS_MULTICAST(wh->i_addr1) && |
1774 |
!IEEE80211_IS_MULTICAST(wh->i_addr1) && |
1779 |
cip != NULL && cip->ic_cipher == IEEE80211_CIPHER_AES_CCM) { |
1775 |
cip != NULL && cip->ic_cipher == IEEE80211_CIPHER_AES_CCM) { |
1780 |
if ((flags & WPI_RX_CIPHER_MASK) != WPI_RX_CIPHER_CCMP) { |
1776 |
if ((flags & WPI_RX_CIPHER_MASK) != WPI_RX_CIPHER_CCMP) |
1781 |
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1777 |
goto fail2; |
1782 |
m_freem(m); |
1778 |
|
1783 |
return; |
|
|
1784 |
} |
1785 |
/* Check whether decryption was successful or not. */ |
1779 |
/* Check whether decryption was successful or not. */ |
1786 |
if ((flags & WPI_RX_DECRYPT_MASK) != WPI_RX_DECRYPT_OK) { |
1780 |
if ((flags & WPI_RX_DECRYPT_MASK) != WPI_RX_DECRYPT_OK) { |
1787 |
DPRINTF(sc, WPI_DEBUG_RECV, |
1781 |
DPRINTF(sc, WPI_DEBUG_RECV, |
1788 |
"CCMP decryption failed 0x%x\n", flags); |
1782 |
"CCMP decryption failed 0x%x\n", flags); |
1789 |
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1783 |
goto fail2; |
1790 |
m_freem(m); |
|
|
1791 |
return; |
1792 |
} |
1784 |
} |
1793 |
m->m_flags |= M_WEP; |
1785 |
m->m_flags |= M_WEP; |
1794 |
} |
1786 |
} |
Lines 1817-1822
Link Here
|
1817 |
(void)ieee80211_input_all(ic, m, stat->rssi, -WPI_RSSI_OFFSET); |
1809 |
(void)ieee80211_input_all(ic, m, stat->rssi, -WPI_RSSI_OFFSET); |
1818 |
|
1810 |
|
1819 |
WPI_LOCK(sc); |
1811 |
WPI_LOCK(sc); |
|
|
1812 |
|
1813 |
return; |
1814 |
|
1815 |
fail2: ieee80211_free_node(ni); |
1816 |
m_freem(m); |
1817 |
|
1818 |
fail1: if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1820 |
} |
1819 |
} |
1821 |
|
1820 |
|
1822 |
static void |
1821 |
static void |
Lines 1836-1841
Link Here
|
1836 |
struct mbuf *m; |
1835 |
struct mbuf *m; |
1837 |
struct ieee80211_node *ni; |
1836 |
struct ieee80211_node *ni; |
1838 |
struct ieee80211vap *vap; |
1837 |
struct ieee80211vap *vap; |
|
|
1838 |
int ackfailcnt = stat->ackfailcnt; |
1839 |
int status = le32toh(stat->status); |
1839 |
int status = le32toh(stat->status); |
1840 |
|
1840 |
|
1841 |
KASSERT(data->ni != NULL, ("no node")); |
1841 |
KASSERT(data->ni != NULL, ("no node")); |
Lines 1844-1850
Link Here
|
1844 |
|
1844 |
|
1845 |
DPRINTF(sc, WPI_DEBUG_XMIT, "%s: " |
1845 |
DPRINTF(sc, WPI_DEBUG_XMIT, "%s: " |
1846 |
"qid %d idx %d retries %d btkillcnt %d rate %x duration %d " |
1846 |
"qid %d idx %d retries %d btkillcnt %d rate %x duration %d " |
1847 |
"status %x\n", __func__, desc->qid, desc->idx, stat->ackfailcnt, |
1847 |
"status %x\n", __func__, desc->qid, desc->idx, ackfailcnt, |
1848 |
stat->btkillcnt, stat->rate, le32toh(stat->duration), status); |
1848 |
stat->btkillcnt, stat->rate, le32toh(stat->duration), status); |
1849 |
|
1849 |
|
1850 |
/* Unmap and free mbuf. */ |
1850 |
/* Unmap and free mbuf. */ |
Lines 1861-1871
Link Here
|
1861 |
if ((status & 0xff) != 1) { |
1861 |
if ((status & 0xff) != 1) { |
1862 |
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); |
1862 |
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); |
1863 |
ieee80211_ratectl_tx_complete(vap, ni, |
1863 |
ieee80211_ratectl_tx_complete(vap, ni, |
1864 |
IEEE80211_RATECTL_TX_FAILURE, &stat->ackfailcnt, NULL); |
1864 |
IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); |
1865 |
} else { |
1865 |
} else { |
1866 |
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); |
1866 |
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); |
1867 |
ieee80211_ratectl_tx_complete(vap, ni, |
1867 |
ieee80211_ratectl_tx_complete(vap, ni, |
1868 |
IEEE80211_RATECTL_TX_SUCCESS, &stat->ackfailcnt, NULL); |
1868 |
IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); |
1869 |
} |
1869 |
} |
1870 |
|
1870 |
|
1871 |
ieee80211_tx_complete(ni, m, (status & 0xff) != 1); |
1871 |
ieee80211_tx_complete(ni, m, (status & 0xff) != 1); |
Lines 1931-1940
Link Here
|
1931 |
hw = le32toh(sc->shared->next); |
1931 |
hw = le32toh(sc->shared->next); |
1932 |
hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1; |
1932 |
hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1; |
1933 |
|
1933 |
|
1934 |
if (sc->rxq.cur == hw) |
1934 |
while (sc->rxq.cur != hw) { |
1935 |
return; |
|
|
1936 |
|
1937 |
do { |
1938 |
sc->rxq.cur = (sc->rxq.cur + 1) % WPI_RX_RING_COUNT; |
1935 |
sc->rxq.cur = (sc->rxq.cur + 1) % WPI_RX_RING_COUNT; |
1939 |
|
1936 |
|
1940 |
struct wpi_rx_data *data = &sc->rxq.data[sc->rxq.cur]; |
1937 |
struct wpi_rx_data *data = &sc->rxq.data[sc->rxq.cur]; |
Lines 2020-2029
Link Here
|
2020 |
BUS_DMASYNC_POSTREAD); |
2017 |
BUS_DMASYNC_POSTREAD); |
2021 |
|
2018 |
|
2022 |
uint32_t *status = (uint32_t *)(desc + 1); |
2019 |
uint32_t *status = (uint32_t *)(desc + 1); |
2023 |
#ifdef WPI_DEBUG |
2020 |
|
2024 |
DPRINTF(sc, WPI_DEBUG_STATE, "state changed to %x\n", |
2021 |
DPRINTF(sc, WPI_DEBUG_STATE, "state changed to %x\n", |
2025 |
le32toh(*status)); |
2022 |
le32toh(*status)); |
2026 |
#endif |
2023 |
|
2027 |
if (le32toh(*status) & 1) { |
2024 |
if (le32toh(*status) & 1) { |
2028 |
ieee80211_runtask(ic, &sc->sc_radiooff_task); |
2025 |
ieee80211_runtask(ic, &sc->sc_radiooff_task); |
2029 |
return; |
2026 |
return; |
Lines 2061-2067
Link Here
|
2061 |
break; |
2058 |
break; |
2062 |
} |
2059 |
} |
2063 |
} |
2060 |
} |
2064 |
} while (sc->rxq.cur != hw); |
2061 |
} |
2065 |
|
2062 |
|
2066 |
/* Tell the firmware what we have processed. */ |
2063 |
/* Tell the firmware what we have processed. */ |
2067 |
wpi_update_rx_ring(sc); |
2064 |
wpi_update_rx_ring(sc); |
Lines 2081-2095
Link Here
|
2081 |
|
2078 |
|
2082 |
/* Wakeup RX and TX rings. */ |
2079 |
/* Wakeup RX and TX rings. */ |
2083 |
if (sc->rxq.update) { |
2080 |
if (sc->rxq.update) { |
|
|
2081 |
sc->rxq.update = 0; |
2084 |
wpi_update_rx_ring(sc); |
2082 |
wpi_update_rx_ring(sc); |
2085 |
sc->rxq.update = 0; |
|
|
2086 |
} |
2083 |
} |
2087 |
for (qid = 0; qid < WPI_NTXQUEUES; qid++) { |
2084 |
for (qid = 0; qid < WPI_NTXQUEUES; qid++) { |
2088 |
struct wpi_tx_ring *ring = &sc->txq[qid]; |
2085 |
struct wpi_tx_ring *ring = &sc->txq[qid]; |
2089 |
|
2086 |
|
2090 |
if (ring->update) { |
2087 |
if (ring->update) { |
|
|
2088 |
ring->update = 0; |
2091 |
wpi_update_tx_ring(sc, ring); |
2089 |
wpi_update_tx_ring(sc, ring); |
2092 |
ring->update = 0; |
|
|
2093 |
} |
2090 |
} |
2094 |
} |
2091 |
} |
2095 |
|
2092 |
|
Lines 2227-2232
Link Here
|
2227 |
static int |
2224 |
static int |
2228 |
wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf) |
2225 |
wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf) |
2229 |
{ |
2226 |
{ |
|
|
2227 |
struct ifnet *ifp = sc->sc_ifp; |
2228 |
struct ieee80211com *ic = ifp->if_l2com; |
2230 |
struct ieee80211_frame *wh; |
2229 |
struct ieee80211_frame *wh; |
2231 |
struct wpi_tx_cmd *cmd; |
2230 |
struct wpi_tx_cmd *cmd; |
2232 |
struct wpi_tx_data *data; |
2231 |
struct wpi_tx_data *data; |
Lines 2234-2241
Link Here
|
2234 |
struct wpi_tx_ring *ring; |
2233 |
struct wpi_tx_ring *ring; |
2235 |
struct mbuf *m1; |
2234 |
struct mbuf *m1; |
2236 |
bus_dma_segment_t *seg, segs[WPI_MAX_SCATTER]; |
2235 |
bus_dma_segment_t *seg, segs[WPI_MAX_SCATTER]; |
2237 |
u_int hdrlen; |
2236 |
int error, i, hdrspace, nsegs, totlen; |
2238 |
int error, i, nsegs, pad, totlen; |
|
|
2239 |
|
2237 |
|
2240 |
WPI_LOCK_ASSERT(sc); |
2238 |
WPI_LOCK_ASSERT(sc); |
2241 |
|
2239 |
|
Lines 2242-2256
Link Here
|
2242 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); |
2240 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); |
2243 |
|
2241 |
|
2244 |
wh = mtod(buf->m, struct ieee80211_frame *); |
2242 |
wh = mtod(buf->m, struct ieee80211_frame *); |
2245 |
hdrlen = ieee80211_anyhdrsize(wh); |
2243 |
hdrspace = ieee80211_anyhdrspace(ic, wh); |
2246 |
totlen = buf->m->m_pkthdr.len; |
2244 |
totlen = buf->m->m_pkthdr.len; |
2247 |
|
2245 |
|
2248 |
if (hdrlen & 3) { |
|
|
2249 |
/* First segment length must be a multiple of 4. */ |
2250 |
pad = 4 - (hdrlen & 3); |
2251 |
} else |
2252 |
pad = 0; |
2253 |
|
2254 |
ring = &sc->txq[buf->ac]; |
2246 |
ring = &sc->txq[buf->ac]; |
2255 |
desc = &ring->desc[ring->cur]; |
2247 |
desc = &ring->desc[ring->cur]; |
2256 |
data = &ring->data[ring->cur]; |
2248 |
data = &ring->data[ring->cur]; |
Lines 2265-2272
Link Here
|
2265 |
memcpy(cmd->data, buf->data, buf->size); |
2257 |
memcpy(cmd->data, buf->data, buf->size); |
2266 |
|
2258 |
|
2267 |
/* Save and trim IEEE802.11 header. */ |
2259 |
/* Save and trim IEEE802.11 header. */ |
2268 |
memcpy((uint8_t *)(cmd->data + buf->size), wh, hdrlen); |
2260 |
memcpy((uint8_t *)(cmd->data + buf->size), wh, hdrspace); |
2269 |
m_adj(buf->m, hdrlen); |
2261 |
m_adj(buf->m, hdrspace); |
2270 |
|
2262 |
|
2271 |
error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, buf->m, |
2263 |
error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, buf->m, |
2272 |
segs, &nsegs, BUS_DMA_NOWAIT); |
2264 |
segs, &nsegs, BUS_DMA_NOWAIT); |
Lines 2304-2313
Link Here
|
2304 |
__func__, ring->qid, ring->cur, totlen, nsegs); |
2296 |
__func__, ring->qid, ring->cur, totlen, nsegs); |
2305 |
|
2297 |
|
2306 |
/* Fill TX descriptor. */ |
2298 |
/* Fill TX descriptor. */ |
2307 |
desc->nsegs = WPI_PAD32(totlen + pad) << 4 | (1 + nsegs); |
2299 |
desc->nsegs = WPI_PAD32(totlen) << 4 | (1 + nsegs); |
2308 |
/* First DMA segment is used by the TX command. */ |
2300 |
/* First DMA segment is used by the TX command. */ |
2309 |
desc->segs[0].addr = htole32(data->cmd_paddr); |
2301 |
desc->segs[0].addr = htole32(data->cmd_paddr); |
2310 |
desc->segs[0].len = htole32(4 + buf->size + hdrlen + pad); |
2302 |
desc->segs[0].len = htole32(4 + buf->size + hdrspace); |
2311 |
/* Other DMA segments are for data payload. */ |
2303 |
/* Other DMA segments are for data payload. */ |
2312 |
seg = &segs[0]; |
2304 |
seg = &segs[0]; |
2313 |
for (i = 1; i <= nsegs; i++) { |
2305 |
for (i = 1; i <= nsegs; i++) { |
Lines 2353-2361
Link Here
|
2353 |
uint32_t flags; |
2345 |
uint32_t flags; |
2354 |
uint16_t qos; |
2346 |
uint16_t qos; |
2355 |
uint8_t tid, type; |
2347 |
uint8_t tid, type; |
2356 |
int ac, error, rate, ismcast, totlen; |
2348 |
int ac, error, rate, ismcast, hdrlen, totlen; |
2357 |
|
2349 |
|
2358 |
wh = mtod(m, struct ieee80211_frame *); |
2350 |
wh = mtod(m, struct ieee80211_frame *); |
|
|
2351 |
hdrlen = ieee80211_anyhdrsize(wh); |
2359 |
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; |
2352 |
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; |
2360 |
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); |
2353 |
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); |
2361 |
|
2354 |
|
Lines 2399-2410
Link Here
|
2399 |
/* 802.11 header may have moved. */ |
2392 |
/* 802.11 header may have moved. */ |
2400 |
wh = mtod(m, struct ieee80211_frame *); |
2393 |
wh = mtod(m, struct ieee80211_frame *); |
2401 |
} |
2394 |
} |
2402 |
totlen = m->m_pkthdr.len; |
2395 |
totlen = m->m_pkthdr.len - (hdrlen & 3); |
2403 |
|
2396 |
|
2404 |
if (ieee80211_radiotap_active_vap(vap)) { |
2397 |
if (ieee80211_radiotap_active_vap(vap)) { |
2405 |
struct wpi_tx_radiotap_header *tap = &sc->sc_txtap; |
2398 |
struct wpi_tx_radiotap_header *tap = &sc->sc_txtap; |
2406 |
|
2399 |
|
2407 |
tap->wt_flags = 0; |
2400 |
tap->wt_flags = IEEE80211_RADIOTAP_F_DATAPAD; |
2408 |
tap->wt_rate = rate; |
2401 |
tap->wt_rate = rate; |
2409 |
if (k != NULL) |
2402 |
if (k != NULL) |
2410 |
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; |
2403 |
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; |
Lines 2420-2425
Link Here
|
2420 |
flags |= WPI_TX_NEED_ACK; |
2413 |
flags |= WPI_TX_NEED_ACK; |
2421 |
} |
2414 |
} |
2422 |
|
2415 |
|
|
|
2416 |
if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) |
2417 |
flags |= WPI_TX_MORE_FRAG; /* Cannot happen yet. */ |
2418 |
|
2423 |
/* Check if frame must be protected using RTS/CTS or CTS-to-self. */ |
2419 |
/* Check if frame must be protected using RTS/CTS or CTS-to-self. */ |
2424 |
if (!ismcast) { |
2420 |
if (!ismcast) { |
2425 |
/* NB: Group frames are sent using CCK in 802.11b/g. */ |
2421 |
/* NB: Group frames are sent using CCK in 802.11b/g. */ |
Lines 2518-2528
Link Here
|
2518 |
struct wpi_buf tx_data; |
2514 |
struct wpi_buf tx_data; |
2519 |
uint32_t flags; |
2515 |
uint32_t flags; |
2520 |
uint8_t type; |
2516 |
uint8_t type; |
2521 |
int ac, rate, totlen; |
2517 |
int ac, rate, hdrlen, totlen; |
2522 |
|
2518 |
|
2523 |
wh = mtod(m, struct ieee80211_frame *); |
2519 |
wh = mtod(m, struct ieee80211_frame *); |
|
|
2520 |
hdrlen = ieee80211_anyhdrsize(wh); |
2524 |
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; |
2521 |
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; |
2525 |
totlen = m->m_pkthdr.len; |
2522 |
totlen = m->m_pkthdr.len - (hdrlen & 3); |
2526 |
|
2523 |
|
2527 |
ac = params->ibp_pri & 3; |
2524 |
ac = params->ibp_pri & 3; |
2528 |
|
2525 |
|
Lines 2544-2549
Link Here
|
2544 |
|
2541 |
|
2545 |
tap->wt_flags = 0; |
2542 |
tap->wt_flags = 0; |
2546 |
tap->wt_rate = rate; |
2543 |
tap->wt_rate = rate; |
|
|
2544 |
if (params->ibp_flags & IEEE80211_BPF_DATAPAD) |
2545 |
tap->wt_flags |= IEEE80211_RADIOTAP_F_DATAPAD; |
2547 |
|
2546 |
|
2548 |
ieee80211_radiotap_tx(vap, m); |
2547 |
ieee80211_radiotap_tx(vap, m); |
2549 |
} |
2548 |
} |
Lines 3434-3464
Link Here
|
3434 |
if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) |
3433 |
if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) |
3435 |
sc->rxon.flags |= htole32(WPI_RXON_AUTO | WPI_RXON_24GHZ); |
3434 |
sc->rxon.flags |= htole32(WPI_RXON_AUTO | WPI_RXON_24GHZ); |
3436 |
|
3435 |
|
|
|
3436 |
sc->rxon.filter = WPI_FILTER_MULTICAST; |
3437 |
switch (ic->ic_opmode) { |
3437 |
switch (ic->ic_opmode) { |
3438 |
case IEEE80211_M_STA: |
3438 |
case IEEE80211_M_STA: |
3439 |
sc->rxon.mode = WPI_MODE_STA; |
3439 |
sc->rxon.mode = WPI_MODE_STA; |
3440 |
sc->rxon.filter = htole32(WPI_FILTER_MULTICAST); |
|
|
3441 |
break; |
3440 |
break; |
3442 |
case IEEE80211_M_IBSS: |
3441 |
case IEEE80211_M_IBSS: |
3443 |
sc->rxon.mode = WPI_MODE_IBSS; |
3442 |
sc->rxon.mode = WPI_MODE_IBSS; |
3444 |
sc->rxon.filter = htole32(WPI_FILTER_BEACON | |
3443 |
sc->rxon.filter |= WPI_FILTER_BEACON; |
3445 |
WPI_FILTER_MULTICAST); |
|
|
3446 |
break; |
3444 |
break; |
3447 |
/* XXX workaround for passive channels selection */ |
3445 |
/* XXX workaround for passive channels selection */ |
3448 |
case IEEE80211_M_AHDEMO: |
3446 |
case IEEE80211_M_AHDEMO: |
3449 |
sc->rxon.filter = htole32(WPI_FILTER_MULTICAST); |
|
|
3450 |
/* FALLTHROUGH */ |
3451 |
case IEEE80211_M_HOSTAP: |
3447 |
case IEEE80211_M_HOSTAP: |
3452 |
sc->rxon.mode = WPI_MODE_HOSTAP; |
3448 |
sc->rxon.mode = WPI_MODE_HOSTAP; |
3453 |
break; |
3449 |
break; |
3454 |
case IEEE80211_M_MONITOR: |
3450 |
case IEEE80211_M_MONITOR: |
3455 |
sc->rxon.mode = WPI_MODE_MONITOR; |
3451 |
sc->rxon.mode = WPI_MODE_MONITOR; |
3456 |
sc->rxon.filter = htole32(WPI_FILTER_MULTICAST); |
|
|
3457 |
break; |
3452 |
break; |
3458 |
default: |
3453 |
default: |
3459 |
device_printf(sc->sc_dev, "unknown opmode %d\n", ic->ic_opmode); |
3454 |
device_printf(sc->sc_dev, "unknown opmode %d\n", ic->ic_opmode); |
3460 |
return EINVAL; |
3455 |
return EINVAL; |
3461 |
} |
3456 |
} |
|
|
3457 |
sc->rxon.filter = htole32(sc->rxon.filter); |
3462 |
wpi_set_promisc(sc); |
3458 |
wpi_set_promisc(sc); |
3463 |
sc->rxon.cck_mask = 0x0f; /* not yet negotiated */ |
3459 |
sc->rxon.cck_mask = 0x0f; /* not yet negotiated */ |
3464 |
sc->rxon.ofdm_mask = 0xff; /* not yet negotiated */ |
3460 |
sc->rxon.ofdm_mask = 0xff; /* not yet negotiated */ |
Lines 3677-3683
Link Here
|
3677 |
} else |
3673 |
} else |
3678 |
hdr->crc_threshold = WPI_SCAN_CRC_TH_NEVER; |
3674 |
hdr->crc_threshold = WPI_SCAN_CRC_TH_NEVER; |
3679 |
|
3675 |
|
3680 |
if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE)) |
3676 |
if (!IEEE80211_IS_CHAN_PASSIVE(c)) |
3681 |
chan->flags |= WPI_CHAN_ACTIVE; |
3677 |
chan->flags |= WPI_CHAN_ACTIVE; |
3682 |
|
3678 |
|
3683 |
/* |
3679 |
/* |
Lines 3702-3708
Link Here
|
3702 |
chan->rf_gain = 0x28; |
3698 |
chan->rf_gain = 0x28; |
3703 |
|
3699 |
|
3704 |
DPRINTF(sc, WPI_DEBUG_SCAN, "Scanning %u Passive: %d\n", |
3700 |
DPRINTF(sc, WPI_DEBUG_SCAN, "Scanning %u Passive: %d\n", |
3705 |
chan->chan, (c->ic_flags & IEEE80211_CHAN_PASSIVE) ? 1 : 0); |
3701 |
chan->chan, IEEE80211_IS_CHAN_PASSIVE(c)); |
3706 |
|
3702 |
|
3707 |
hdr->nchan++; |
3703 |
hdr->nchan++; |
3708 |
chan++; |
3704 |
chan++; |
Lines 3838-3848
Link Here
|
3838 |
struct wpi_softc *sc = ifp->if_softc; |
3834 |
struct wpi_softc *sc = ifp->if_softc; |
3839 |
int error; |
3835 |
int error; |
3840 |
|
3836 |
|
|
|
3837 |
WPI_LOCK(sc); |
3841 |
if ((error = wpi_setup_beacon(sc, ni)) != 0) { |
3838 |
if ((error = wpi_setup_beacon(sc, ni)) != 0) { |
3842 |
device_printf(sc->sc_dev, |
3839 |
device_printf(sc->sc_dev, |
3843 |
"%s: could not update beacon frame, error %d", __func__, |
3840 |
"%s: could not update beacon frame, error %d", __func__, |
3844 |
error); |
3841 |
error); |
3845 |
} |
3842 |
} |
|
|
3843 |
WPI_UNLOCK(sc); |
3846 |
} |
3844 |
} |
3847 |
|
3845 |
|
3848 |
static int |
3846 |
static int |
Lines 3939-3944
Link Here
|
3939 |
/* Enable power-saving mode if requested by user. */ |
3937 |
/* Enable power-saving mode if requested by user. */ |
3940 |
if (vap->iv_flags & IEEE80211_F_PMGTON) |
3938 |
if (vap->iv_flags & IEEE80211_F_PMGTON) |
3941 |
(void)wpi_set_pslevel(sc, 0, 3, 1); |
3939 |
(void)wpi_set_pslevel(sc, 0, 3, 1); |
|
|
3940 |
else |
3941 |
(void)wpi_set_pslevel(sc, 0, 0, 1); |
3942 |
|
3942 |
|
3943 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__); |
3943 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__); |
3944 |
|
3944 |
|
Lines 4384-4389
Link Here
|
4384 |
DELAY(20); |
4384 |
DELAY(20); |
4385 |
/* Disable L1-Active. */ |
4385 |
/* Disable L1-Active. */ |
4386 |
wpi_prph_setbits(sc, WPI_APMG_PCI_STT, WPI_APMG_PCI_STT_L1A_DIS); |
4386 |
wpi_prph_setbits(sc, WPI_APMG_PCI_STT, WPI_APMG_PCI_STT_L1A_DIS); |
|
|
4387 |
/* ??? */ |
4388 |
wpi_prph_clrbits(sc, WPI_APMG_PS, 0x00000E00); |
4387 |
wpi_nic_unlock(sc); |
4389 |
wpi_nic_unlock(sc); |
4388 |
|
4390 |
|
4389 |
return 0; |
4391 |
return 0; |