diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2006-05-20 12:44:48 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2006-05-20 12:44:48 +0000 |
commit | b2ac69817d0704895a8159fd55926cbdf5873120 (patch) | |
tree | e5a14133e7387b887d15eb85f93b119390060c9e /sys | |
parent | 2fd0dcc8d7ec117585d90a20915ca9238a2f246c (diff) |
- fix CCK mask for 802.11b/only
- add beacon command for future IBSS or HostAP mode support
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_wpi.c | 79 | ||||
-rw-r--r-- | sys/dev/pci/if_wpireg.h | 19 |
2 files changed, 93 insertions, 5 deletions
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c index 9249513eee2..01a57c8a288 100644 --- a/sys/dev/pci/if_wpi.c +++ b/sys/dev/pci/if_wpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wpi.c,v 1.8 2006/05/20 11:47:29 damien Exp $ */ +/* $OpenBSD: if_wpi.c,v 1.9 2006/05/20 12:44:47 damien Exp $ */ /*- * Copyright (c) 2006 @@ -131,6 +131,7 @@ int wpi_cmd(struct wpi_softc *, int, const void *, int, int); int wpi_mrr_setup(struct wpi_softc *); void wpi_set_led(struct wpi_softc *, uint8_t, uint8_t, uint8_t); void wpi_enable_tsf(struct wpi_softc *, struct ieee80211_node *); +int wpi_setup_beacon(struct wpi_softc *, struct ieee80211_node *); int wpi_auth(struct wpi_softc *); int wpi_scan(struct wpi_softc *); int wpi_config(struct wpi_softc *); @@ -1751,6 +1752,76 @@ wpi_enable_tsf(struct wpi_softc *sc, struct ieee80211_node *ni) printf("%s: could not enable TSF\n", sc->sc_dev.dv_xname); } +/* + * Build a beacon frame that the firmware will broadcast periodically in + * IBSS or HostAP modes. + */ +int +wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct wpi_tx_ring *ring = &sc->cmdq; + struct wpi_tx_desc *desc; + struct wpi_tx_data *data; + struct wpi_tx_cmd *cmd; + struct wpi_cmd_beacon *bcn; + struct mbuf *m0; + int error; + + desc = &ring->desc[ring->cur]; + data = &ring->data[ring->cur]; + + m0 = ieee80211_beacon_alloc(ic, ni); + if (m0 == NULL) { + printf("%s: could not allocate beacon frame\n", + sc->sc_dev.dv_xname); + return ENOMEM; + } + + cmd = &ring->cmd[ring->cur]; + cmd->code = WPI_CMD_SET_BEACON; + cmd->flags = 0; + cmd->qid = ring->qid; + cmd->idx = ring->cur; + + bcn = (struct wpi_cmd_beacon *)cmd->data; + bzero(bcn, sizeof (struct wpi_cmd_beacon)); + bcn->id = WPI_ID_BROADCAST; + bcn->lifetime = htole32(0xffffffff); + bcn->len = htole16(m0->m_pkthdr.len); + bcn->rate = 10; /* 1Mb/s */ + bcn->flags = htole32(WPI_TX_AUTO_SEQ | WPI_TX_INSERT_TSTAMP); + + /* save and trim IEEE802.11 header */ + m_copydata(m0, 0, sizeof (struct ieee80211_frame), (caddr_t)&bcn->wh); + m_adj(m0, sizeof (struct ieee80211_frame)); + + /* assume beacon frame is contiguous */ + error = bus_dmamap_load(sc->sc_dmat, data->map, mtod(m0, void *), + m0->m_pkthdr.len, NULL, BUS_DMA_NOWAIT); + if (error != 0) { + printf("%s: could not map beacon\n", sc->sc_dev.dv_xname); + m_freem(m0); + return error; + } + + data->m = m0; + + /* first scatter/gather segment is used by the beacon command */ + desc->flags = htole32(WPI_PAD32(m0->m_pkthdr.len) << 28 | 2 << 24); + desc->segs[0].physaddr = htole32(ring->cmd_dma.paddr + + ring->cur * sizeof (struct wpi_tx_cmd)); + desc->segs[0].len = htole32(4 + sizeof (struct wpi_cmd_beacon)); + desc->segs[1].physaddr = htole32(data->map->dm_segs[0].ds_addr); + desc->segs[1].len = htole32(data->map->dm_segs[0].ds_len); + + /* kick cmd ring */ + ring->cur = (ring->cur + 1) % WPI_CMD_RING_COUNT; + WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur); + + return 0; +} + int wpi_auth(struct wpi_softc *sc) { @@ -1763,7 +1834,7 @@ wpi_auth(struct wpi_softc *sc) IEEE80211_ADDR_COPY(sc->config.bssid, ni->ni_bssid); sc->config.chan = ieee80211_chan2ieee(ic, ni->ni_chan); if (ic->ic_curmode == IEEE80211_MODE_11B) { - sc->config.cck_mask = 0x0f; + sc->config.cck_mask = 0x03; sc->config.ofdm_mask = 0; } else if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) { sc->config.cck_mask = 0; @@ -1777,8 +1848,8 @@ wpi_auth(struct wpi_softc *sc) if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) sc->config.flags |= htole32(WPI_CONFIG_SHPREAMBLE); - DPRINTF(("config chan %d flags %x\n", sc->config.chan, - sc->config.flags)); + DPRINTF(("config chan %d flags %x cck %x ofdm %x\n", sc->config.chan, + sc->config.flags, sc->config.cck_mask, sc->config.ofdm_mask)); error = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->config, sizeof (struct wpi_config), 1); if (error != 0) { diff --git a/sys/dev/pci/if_wpireg.h b/sys/dev/pci/if_wpireg.h index fa341c0d6db..638ac34ff91 100644 --- a/sys/dev/pci/if_wpireg.h +++ b/sys/dev/pci/if_wpireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wpireg.h,v 1.2 2006/05/20 11:47:29 damien Exp $ */ +/* $OpenBSD: if_wpireg.h,v 1.3 2006/05/20 12:44:47 damien Exp $ */ /*- @@ -242,6 +242,7 @@ struct wpi_tx_cmd { #define WPI_CMD_SET_LED 72 #define WPI_CMD_SET_POWER_MODE 119 #define WPI_CMD_SCAN 128 +#define WPI_CMD_SET_BEACON 145 #define WPI_CMD_BLUETOOTH 155 #define WPI_CMD_TXPOWER 176 @@ -364,6 +365,22 @@ struct wpi_cmd_data { struct ieee80211_frame wh; } __packed; +/* structure for command WPI_CMD_SET_BEACON */ +struct wpi_cmd_beacon { + uint16_t len; + uint16_t reserved1; + uint32_t flags; /* same as wpi_cmd_data */ + uint8_t rate; + uint8_t id; + uint8_t reserved2[30]; + uint32_t lifetime; + uint32_t reserved3[2]; + uint16_t tim; + uint8_t timsz; + uint8_t reserved4; + struct ieee80211_frame wh; +} __packed; + /* structure for WPI_CMD_MRR_SETUP */ struct wpi_mrr_setup { uint32_t which; |