summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2008-04-16 18:32:16 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2008-04-16 18:32:16 +0000
commit792a7af405f1bcd074df2d192736f0ff71180ce6 (patch)
treed1c8127338d31609e63b5a8c220604e11d416fa8 /sys/dev/pci
parentc257d1252aa088da82103c7952e3c42933d743da (diff)
Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state machines) as defined in the IEEE 802.11i standard. Software implementation of the TKIP (Temporal Key Integrity Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols. This diff doesn't implement any of the 802.1X authentication protocols and thus only PSK authentication (using pre-shared keys) is currently supported. In concrete terms, this adds support for WPA-PSK and WPA2-PSK protocols, both in station and hostap modes. The following drivers are marked as WPA-capable and should work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4), rum(4), upgt(4), and zyd(4) The following options have been added to ifconfig(8): wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher wpa-psk(8) can be used to generate keys from passphrases. tested by many@ ok deraadt@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_ipw.c111
-rw-r--r--sys/dev/pci/if_ipwvar.h4
-rw-r--r--sys/dev/pci/if_iwn.c35
-rw-r--r--sys/dev/pci/if_wpi.c33
4 files changed, 76 insertions, 107 deletions
diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c
index 9810a9f77d6..b6ff2171dcd 100644
--- a/sys/dev/pci/if_ipw.c
+++ b/sys/dev/pci/if_ipw.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: if_ipw.c,v 1.71 2008/02/23 20:38:08 hshoexer Exp $ */
+/* $OpenBSD: if_ipw.c,v 1.72 2008/04/16 18:32:15 damien Exp $ */
/*-
- * Copyright (c) 2004-2006
+ * Copyright (c) 2004-2008
* Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -496,7 +496,6 @@ ipw_dma_alloc(struct ipw_softc *sc)
error = ENOMEM;
goto fail;
}
-
MCLGET(sbuf->m, M_DONTWAIT);
if (!(sbuf->m->m_flags & M_EXT)) {
m_freem(sbuf->m);
@@ -645,15 +644,12 @@ ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
break;
-
case IEEE80211_M_IBSS:
imr->ifm_active |= IFM_IEEE80211_IBSS;
break;
-
case IEEE80211_M_MONITOR:
imr->ifm_active |= IFM_IEEE80211_MONITOR;
break;
-
case IEEE80211_M_AHDEMO:
case IEEE80211_M_HOSTAP:
/* should not get there */
@@ -835,7 +831,6 @@ ipw_data_intr(struct ipw_softc *sc, struct ipw_status *status,
ifp->if_ierrors++;
return;
}
-
MCLGET(mnew, M_DONTWAIT);
if (!(mnew->m_flags & M_EXT)) {
m_freem(mnew);
@@ -894,7 +889,6 @@ ipw_data_intr(struct ipw_softc *sc, struct ipw_status *status,
#endif
wh = mtod(m, struct ieee80211_frame *);
-
ni = ieee80211_find_rxnode(ic, wh);
/* send the frame to the upper layer */
@@ -1101,7 +1095,7 @@ ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len)
bus_dmamap_sync(sc->sc_dmat, sc->cmd_map, 0, sizeof (struct ipw_cmd),
BUS_DMASYNC_PREWRITE);
-
+
bus_dmamap_sync(sc->sc_dmat, sc->tbd_map,
sc->txcur * sizeof (struct ipw_bd), sizeof (struct ipw_bd),
BUS_DMASYNC_PREWRITE);
@@ -1122,6 +1116,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
struct ipw_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
+ struct ieee80211_key *k;
struct ipw_soft_bd *sbd;
struct ipw_soft_hdr *shdr;
struct ipw_soft_buf *sbuf;
@@ -1130,9 +1125,10 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
wh = mtod(m, struct ieee80211_frame *);
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- m = ieee80211_wep_crypt(ifp, m, 1);
- if (m == NULL)
+ if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
+ k = ieee80211_get_txkey(ic, wh, ni);
+
+ if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
return ENOBUFS;
/* packet header may have moved, reset our local pointer */
@@ -1163,7 +1159,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
shdr->hdr.type = htole32(IPW_HDR_TYPE_SEND);
shdr->hdr.subtype = htole32(0);
- shdr->hdr.encrypted = (wh->i_fc[1] & IEEE80211_FC1_WEP) ? 1 : 0;
+ shdr->hdr.encrypted = (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) ? 1 : 0;
shdr->hdr.encrypt = 0;
shdr->hdr.keyidx = 0;
shdr->hdr.keysz = 0;
@@ -1192,7 +1188,6 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
m_freem(m);
return ENOMEM;
}
-
M_DUP_PKTHDR(mnew, m);
if (m->m_pkthdr.len > MHLEN) {
MCLGET(mnew, M_DONTWAIT);
@@ -1202,7 +1197,6 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
return ENOMEM;
}
}
-
m_copydata(m, 0, m->m_pkthdr.len, mtod(mnew, caddr_t));
m_freem(m);
mnew->m_len = mnew->m_pkthdr.len;
@@ -1297,8 +1291,8 @@ ipw_start(struct ifnet *ifp)
{
struct ipw_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
- struct mbuf *m;
struct ieee80211_node *ni;
+ struct mbuf *m;
if (ic->ic_state != IEEE80211_S_RUN)
return;
@@ -1317,16 +1311,13 @@ ipw_start(struct ifnet *ifp)
if (ifp->if_bpf != NULL)
bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
#endif
-
m = ieee80211_encap(ifp, m, &ni);
if (m == NULL)
continue;
-
#if NBPFILTER > 0
if (ic->ic_rawbpf != NULL)
bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
#endif
-
if (ipw_tx_start(ifp, m, ni) != 0) {
if (ni != NULL)
ieee80211_release_node(ic, ni);
@@ -1452,14 +1443,13 @@ ipw_read_table2(struct ipw_softc *sc, uint32_t off, void *buf, uint32_t *len)
info = MEM_READ_4(sc, sc->table2_base + off + 4);
count = info >> 16;
- size = info & 0xffff;
+ size = info & 0xffff;
total = count * size;
if (total > *len) {
*len = total;
return EINVAL;
}
-
*len = total;
ipw_read_mem_1(sc, addr, buf, total);
@@ -1469,6 +1459,7 @@ ipw_read_table2(struct ipw_softc *sc, uint32_t off, void *buf, uint32_t *len)
void
ipw_stop_master(struct ipw_softc *sc)
{
+ uint32_t tmp;
int ntries;
/* disable interrupts */
@@ -1484,8 +1475,8 @@ ipw_stop_master(struct ipw_softc *sc)
printf("%s: timeout waiting for master\n",
sc->sc_dev.dv_xname);
- CSR_WRITE_4(sc, IPW_CSR_RST, CSR_READ_4(sc, IPW_CSR_RST) |
- IPW_RST_PRINCETON_RESET);
+ tmp = CSR_READ_4(sc, IPW_CSR_RST);
+ CSR_WRITE_4(sc, IPW_CSR_RST, tmp | IPW_RST_PRINCETON_RESET);
sc->flags &= ~IPW_FLAG_FW_INITED;
}
@@ -1493,13 +1484,14 @@ ipw_stop_master(struct ipw_softc *sc)
int
ipw_reset(struct ipw_softc *sc)
{
+ uint32_t tmp;
int ntries;
ipw_stop_master(sc);
/* move adapter to D0 state */
- CSR_WRITE_4(sc, IPW_CSR_CTL, CSR_READ_4(sc, IPW_CSR_CTL) |
- IPW_CTL_INIT);
+ tmp = CSR_READ_4(sc, IPW_CSR_CTL);
+ CSR_WRITE_4(sc, IPW_CSR_CTL, tmp | IPW_CTL_INIT);
/* wait for clock stabilization */
for (ntries = 0; ntries < 1000; ntries++) {
@@ -1510,13 +1502,13 @@ ipw_reset(struct ipw_softc *sc)
if (ntries == 1000)
return EIO;
- CSR_WRITE_4(sc, IPW_CSR_RST, CSR_READ_4(sc, IPW_CSR_RST) |
- IPW_RST_SW_RESET);
+ tmp = CSR_READ_4(sc, IPW_CSR_RST);
+ CSR_WRITE_4(sc, IPW_CSR_RST, tmp | IPW_RST_SW_RESET);
DELAY(10);
- CSR_WRITE_4(sc, IPW_CSR_CTL, CSR_READ_4(sc, IPW_CSR_CTL) |
- IPW_CTL_INIT);
+ tmp = CSR_READ_4(sc, IPW_CSR_CTL);
+ CSR_WRITE_4(sc, IPW_CSR_CTL, tmp | IPW_CTL_INIT);
return 0;
}
@@ -1526,6 +1518,7 @@ ipw_load_ucode(struct ipw_softc *sc, u_char *uc, int size)
{
int ntries;
+ /* voodoo from the Intel Linux driver */
MEM_WRITE_4(sc, 0x3000e0, 0x80000000);
CSR_WRITE_4(sc, IPW_CSR_RST, 0);
@@ -1577,7 +1570,7 @@ int
ipw_load_firmware(struct ipw_softc *sc, u_char *fw, int size)
{
u_char *p, *end;
- uint32_t dst;
+ uint32_t tmp, dst;
uint16_t len;
int error;
@@ -1605,8 +1598,8 @@ ipw_load_firmware(struct ipw_softc *sc, u_char *fw, int size)
/* tell the adapter to initialize the firmware */
CSR_WRITE_4(sc, IPW_CSR_RST, 0);
- CSR_WRITE_4(sc, IPW_CSR_CTL, CSR_READ_4(sc, IPW_CSR_CTL) |
- IPW_CTL_ALLOW_STANDBY);
+ tmp = CSR_READ_4(sc, IPW_CSR_CTL);
+ CSR_WRITE_4(sc, IPW_CSR_CTL, tmp | IPW_CTL_ALLOW_STANDBY);
/* wait at most one second for firmware initialization to complete */
if ((error = tsleep(sc, 0, "ipwinit", hz)) != 0) {
@@ -1615,8 +1608,9 @@ ipw_load_firmware(struct ipw_softc *sc, u_char *fw, int size)
return error;
}
- CSR_WRITE_4(sc, IPW_CSR_IO, CSR_READ_4(sc, IPW_CSR_IO) |
- IPW_IO_GPIO1_MASK | IPW_IO_GPIO3_MASK);
+ tmp = CSR_READ_4(sc, IPW_CSR_IO);
+ CSR_WRITE_4(sc, IPW_CSR_IO, tmp | IPW_IO_GPIO1_MASK |
+ IPW_IO_GPIO3_MASK);
return 0;
}
@@ -1624,52 +1618,42 @@ ipw_load_firmware(struct ipw_softc *sc, u_char *fw, int size)
int
ipw_read_firmware(struct ipw_softc *sc, struct ipw_firmware *fw)
{
- struct ipw_firmware_hdr *hdr;
+ const struct ipw_firmware_hdr *hdr;
const char *name;
- u_char *p;
size_t size;
int error;
switch (sc->sc_ic.ic_opmode) {
case IEEE80211_M_STA:
- case IEEE80211_M_HOSTAP:
name = "ipw-bss";
break;
-
case IEEE80211_M_IBSS:
- case IEEE80211_M_AHDEMO:
name = "ipw-ibss";
break;
-
case IEEE80211_M_MONITOR:
name = "ipw-monitor";
break;
+ default:
+ /* should not get there */
+ return ENODEV;
}
-
if ((error = loadfirmware(name, &fw->data, &size)) != 0)
return error;
- if (size < sizeof (struct ipw_firmware_hdr)) {
+ if (size < sizeof (*hdr)) {
error = EINVAL;
goto fail;
}
-
- p = fw->data;
- hdr = (struct ipw_firmware_hdr *)p;
- fw->main_size = letoh32(hdr->main_size);
+ hdr = (const struct ipw_firmware_hdr *)fw->data;
+ fw->main_size = letoh32(hdr->main_size);
fw->ucode_size = letoh32(hdr->ucode_size);
- p += sizeof (struct ipw_firmware_hdr);
- size -= sizeof (struct ipw_firmware_hdr);
-
- if (size < fw->main_size + fw->ucode_size) {
+ if (size < sizeof (*hdr) + fw->main_size + fw->ucode_size) {
error = EINVAL;
goto fail;
}
-
- fw->main = p;
- fw->ucode = p + fw->main_size;
- sc->fw_data = fw->data;
+ fw->main = fw->data + sizeof (*hdr);
+ fw->ucode = fw->main + fw->main_size;
return 0;
@@ -1692,18 +1676,17 @@ ipw_config(struct ipw_softc *sc)
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
- case IEEE80211_M_HOSTAP:
data = htole32(IPW_MODE_BSS);
break;
-
case IEEE80211_M_IBSS:
- case IEEE80211_M_AHDEMO:
data = htole32(IPW_MODE_IBSS);
break;
-
case IEEE80211_M_MONITOR:
data = htole32(IPW_MODE_MONITOR);
break;
+ default:
+ /* should not get there */
+ return ENODEV;
}
DPRINTF(("Setting mode to %u\n", letoh32(data)));
error = ipw_cmd(sc, IPW_CMD_SET_MODE, &data, sizeof data);
@@ -1892,7 +1875,6 @@ ipw_init(struct ifnet *ifp)
sc->sc_dev.dv_xname, error);
goto fail1;
}
-
if ((error = ipw_load_ucode(sc, fw.ucode, fw.ucode_size)) != 0) {
printf("%s: could not load microcode\n", sc->sc_dev.dv_xname);
goto fail2;
@@ -1924,8 +1906,8 @@ ipw_init(struct ifnet *ifp)
printf("%s: could not load firmware\n", sc->sc_dev.dv_xname);
goto fail2;
}
-
sc->flags |= IPW_FLAG_FW_INITED;
+ free(fw.data, M_DEVBUF);
/* retrieve information tables base addresses */
sc->table1_base = CSR_READ_4(sc, IPW_CSR_TABLE1_BASE);
@@ -1938,7 +1920,6 @@ ipw_init(struct ifnet *ifp)
sc->sc_dev.dv_xname);
goto fail2;
}
-
ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_flags |= IFF_RUNNING;
@@ -1969,14 +1950,6 @@ ipw_stop(struct ifnet *ifp, int disable)
for (i = 0; i < IPW_NTBD; i++)
ipw_release_sbd(sc, &sc->stbd_list[i]);
- /*
- * Free memory claimed by firmware.
- */
- if (sc->fw_data) {
- free(sc->fw_data, M_DEVBUF);
- sc->fw_data = NULL;
- }
-
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
}
diff --git a/sys/dev/pci/if_ipwvar.h b/sys/dev/pci/if_ipwvar.h
index 56348ad2f92..ca0d5b73a4d 100644
--- a/sys/dev/pci/if_ipwvar.h
+++ b/sys/dev/pci/if_ipwvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ipwvar.h,v 1.15 2008/02/23 21:35:41 hshoexer Exp $ */
+/* $OpenBSD: if_ipwvar.h,v 1.16 2008/04/16 18:32:15 damien Exp $ */
/*-
* Copyright (c) 2004-2006
@@ -158,6 +158,4 @@ struct ipw_softc {
#define sc_txtap sc_txtapu.th
int sc_txtap_len;
#endif
-
- void *fw_data;
};
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c
index 71f793a9bac..11eb562932e 100644
--- a/sys/dev/pci/if_iwn.c
+++ b/sys/dev/pci/if_iwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwn.c,v 1.17 2008/03/08 16:24:44 espie Exp $ */
+/* $OpenBSD: if_iwn.c,v 1.18 2008/04/16 18:32:15 damien Exp $ */
/*-
* Copyright (c) 2007
@@ -135,7 +135,7 @@ int iwn_ioctl(struct ifnet *, u_long, caddr_t);
int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
int iwn_setup_node_mrr(struct iwn_softc *, uint8_t, int);
int iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
- const struct ieee80211_key *);
+ struct ieee80211_key *);
void iwn_updateedca(struct ieee80211com *);
void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
int iwn_set_critical_temp(struct iwn_softc *);
@@ -293,6 +293,7 @@ iwn_attach(struct device *parent, struct device *self, void *aux)
/* set device capabilities */
ic->ic_caps =
IEEE80211_C_WEP | /* s/w WEP */
+ IEEE80211_C_RSN | /* WPA/RSN */
IEEE80211_C_MONITOR | /* monitor mode supported */
IEEE80211_C_TXPMGT | /* tx power management */
IEEE80211_C_SHSLOT | /* short slot time supported */
@@ -322,7 +323,9 @@ iwn_attach(struct device *parent, struct device *self, void *aux)
ieee80211_ifattach(ifp);
ic->ic_node_alloc = iwn_node_alloc;
ic->ic_newassoc = iwn_newassoc;
+#ifdef notyet
ic->ic_set_key = iwn_set_key;
+#endif
ic->ic_updateedca = iwn_updateedca;
/* override state transition machine */
@@ -1457,7 +1460,7 @@ iwn_notif_intr(struct iwn_softc *sc)
DPRINTFN(4,("rx notification qid=%x idx=%d flags=%x type=%d "
"len=%d\n", desc->qid, desc->idx, desc->flags, desc->type,
- letoh32(desc->len)));
+ letoh16(desc->len)));
if (!(desc->qid & 0x80)) /* reply to a command */
iwn_cmd_intr(sc, desc);
@@ -1674,12 +1677,13 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
struct iwn_tx_cmd *cmd;
struct iwn_cmd_data *tx;
struct ieee80211_frame *wh;
+ struct ieee80211_key *k;
struct mbuf *mnew;
bus_addr_t paddr;
uint32_t flags;
uint8_t type;
u_int hdrlen;
- int i, rate, error, pad, ovhd = 0;
+ int i, rate, error, pad;
desc = &ring->desc[ring->cur];
data = &ring->data[ring->cur];
@@ -1733,18 +1737,13 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
/* no need to bzero tx, all fields are reinitialized here */
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
- const struct ieee80211_key *key =
- &ic->ic_nw_keys[ic->ic_wep_txkey];
- if (key->k_cipher == IEEE80211_CIPHER_WEP40)
- tx->security = IWN_CIPHER_WEP40;
- else
- tx->security = IWN_CIPHER_WEP104;
- tx->security |= ic->ic_wep_txkey << 6;
- memcpy(&tx->key[3], key->k_key, key->k_len);
- /* compute crypto overhead */
- ovhd = IEEE80211_WEP_TOTLEN;
- } else
- tx->security = 0;
+ k = ieee80211_get_txkey(ic, wh, ni);
+
+ if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL)
+ return ENOBUFS;
+
+ wh = mtod(m0, struct ieee80211_frame *);
+ }
flags = IWN_TX_AUTO_SEQ;
if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
@@ -1759,7 +1758,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
/* check if RTS/CTS or CTS-to-self protection must be used */
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
/* multicast frames are not sent at OFDM rates in 802.11b/g */
- if (m0->m_pkthdr.len + ovhd + IEEE80211_CRC_LEN >
+ if (m0->m_pkthdr.len + IEEE80211_CRC_LEN >
ic->ic_rtsthreshold) {
flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
} else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
@@ -2256,7 +2255,7 @@ iwn_setup_node_mrr(struct iwn_softc *sc, uint8_t id, int async)
*/
int
iwn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
- const struct ieee80211_key *k)
+ struct ieee80211_key *k)
{
struct iwn_softc *sc = ic->ic_softc;
struct iwn_node_info node;
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c
index f0cd31a8a1e..0549b16de86 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.59 2008/03/08 16:24:45 espie Exp $ */
+/* $OpenBSD: if_wpi.c,v 1.60 2008/04/16 18:32:15 damien Exp $ */
/*-
* Copyright (c) 2006, 2007
@@ -130,7 +130,7 @@ int wpi_ioctl(struct ifnet *, u_long, caddr_t);
int wpi_cmd(struct wpi_softc *, int, const void *, int, int);
int wpi_mrr_setup(struct wpi_softc *);
int wpi_set_key(struct ieee80211com *, struct ieee80211_node *,
- const struct ieee80211_key *);
+ struct ieee80211_key *);
void wpi_updateedca(struct ieee80211com *);
void wpi_set_led(struct wpi_softc *, uint8_t, uint8_t, uint8_t);
void wpi_enable_tsf(struct wpi_softc *, struct ieee80211_node *);
@@ -270,6 +270,7 @@ wpi_attach(struct device *parent, struct device *self, void *aux)
/* set device capabilities */
ic->ic_caps =
IEEE80211_C_WEP | /* s/w WEP */
+ IEEE80211_C_RSN | /* WPA/RSN */
IEEE80211_C_MONITOR | /* monitor mode supported */
IEEE80211_C_TXPMGT | /* tx power management */
IEEE80211_C_SHSLOT | /* short slot time supported */
@@ -299,7 +300,9 @@ wpi_attach(struct device *parent, struct device *self, void *aux)
ieee80211_ifattach(ifp);
ic->ic_node_alloc = wpi_node_alloc;
ic->ic_newassoc = wpi_newassoc;
+#ifdef notyet
ic->ic_set_key = wpi_set_key;
+#endif
ic->ic_updateedca = wpi_updateedca;
/* override state transition machine */
@@ -1569,9 +1572,10 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
struct wpi_tx_cmd *cmd;
struct wpi_cmd_data *tx;
struct ieee80211_frame *wh;
+ struct ieee80211_key *k;
struct mbuf *mnew;
u_int hdrlen;
- int i, rate, error, ovhd = 0;
+ int i, rate, error;
desc = &ring->desc[ring->cur];
data = &ring->data[ring->cur];
@@ -1626,18 +1630,13 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
tx->flags = 0;
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
- const struct ieee80211_key *key =
- &ic->ic_nw_keys[ic->ic_wep_txkey];
- if (key->k_cipher == IEEE80211_CIPHER_WEP40)
- tx->security = WPI_CIPHER_WEP40;
- else
- tx->security = WPI_CIPHER_WEP104;
- tx->security |= ic->ic_wep_txkey << 6;
- memcpy(&tx->key[3], key->k_key, key->k_len);
- /* compute crypto overhead */
- ovhd = IEEE80211_WEP_TOTLEN;
- } else
- tx->security = 0;
+ k = ieee80211_get_txkey(ic, wh, ni);
+
+ if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL)
+ return ENOBUFS;
+
+ wh = mtod(m0, struct ieee80211_frame *);
+ }
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
tx->id = WPI_ID_BSS;
@@ -1648,7 +1647,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
/* check if RTS/CTS or CTS-to-self protection must be used */
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
/* multicast frames are not sent at OFDM rates in 802.11b/g */
- if (m0->m_pkthdr.len + ovhd + IEEE80211_CRC_LEN >
+ if (m0->m_pkthdr.len + IEEE80211_CRC_LEN >
ic->ic_rtsthreshold) {
tx->flags |= htole32(WPI_TX_NEED_RTS |
WPI_TX_FULL_TXOP);
@@ -2118,7 +2117,7 @@ wpi_mrr_setup(struct wpi_softc *sc)
*/
int
wpi_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
- const struct ieee80211_key *k)
+ struct ieee80211_key *k)
{
struct wpi_softc *sc = ic->ic_softc;
struct wpi_node_info node;