Here is a grotty hack that lets the RTL8180L handle WEP in the
receive direction, while software handles WEP in the transmit direction. When net80211 calls rtw's rtw_key_set with a WEP key, I point the key's wk_cipher at our "fake" cipher, rtw_cipher_wep, which is alike to ieee80211_cipher_wep except it provides a different crypto-decapsulation routine, rtw_wep_decap. rtw_wep_decap copies the key passed to it by net80211, clears the key's SWCRYPT flag, and then calls wep_decap. Now wep_decap will decapsulate, but it will *not* re-decrypt. XXX I need to check whether the hardware supports 40-bit WEP, XXX 104-bit WEP, or both, and act accordingly.
This commit is contained in:
parent
5303f3b378
commit
dbad357b04
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtw.c,v 1.49 2005/06/27 05:49:13 dyoung Exp $ */
|
||||
/* $NetBSD: rtw.c,v 1.50 2005/06/28 07:19:33 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
*
|
||||
@ -34,7 +34,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.49 2005/06/27 05:49:13 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.50 2005/06/28 07:19:33 dyoung Exp $");
|
||||
|
||||
#include "bpfilter.h"
|
||||
|
||||
@ -94,6 +94,7 @@ int rtw_rxbufs_limit = RTW_RXQLEN;
|
||||
} while (0)
|
||||
|
||||
int rtw_dwelltime = 200; /* milliseconds */
|
||||
static struct ieee80211_cipher rtw_cipher_wep;
|
||||
|
||||
static void rtw_start(struct ifnet *);
|
||||
|
||||
@ -104,6 +105,7 @@ static int rtw_key_set(struct ieee80211com *, const struct ieee80211_key *,
|
||||
const u_int8_t[IEEE80211_ADDR_LEN]);
|
||||
static void rtw_key_update_end(struct ieee80211com *);
|
||||
static void rtw_key_update_begin(struct ieee80211com *);
|
||||
static int rtw_wep_decap(struct ieee80211_key *, struct mbuf *);
|
||||
static void rtw_wep_setkeys(struct rtw_softc *, struct ieee80211_key *, int);
|
||||
|
||||
static void rtw_led_attach(struct rtw_led_state *, void *);
|
||||
@ -528,6 +530,19 @@ rtw_chip_reset(struct rtw_regs *regs, const char *dvname)
|
||||
return rtw_chip_reset1(regs, dvname);
|
||||
}
|
||||
|
||||
static int
|
||||
rtw_wep_decap(struct ieee80211_key *k, struct mbuf *m)
|
||||
{
|
||||
struct ieee80211_key keycopy;
|
||||
|
||||
RTW_DPRINTF(RTW_DEBUG_KEY, ("%s:\n", __func__));
|
||||
|
||||
keycopy = *k;
|
||||
keycopy.wk_flags &= ~IEEE80211_KEY_SWCRYPT;
|
||||
|
||||
return (*ieee80211_cipher_wep.ic_decap)(&keycopy, m);
|
||||
}
|
||||
|
||||
static int
|
||||
rtw_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k)
|
||||
{
|
||||
@ -573,6 +588,11 @@ rtw_key_set(struct ieee80211com *ic, const struct ieee80211_key *k,
|
||||
if (k->wk_keyix >= IEEE80211_WEP_NKID)
|
||||
return 0;
|
||||
|
||||
if (k->wk_cipher == &ieee80211_cipher_wep) {
|
||||
rtw_cipher_wep = ieee80211_cipher_wep;
|
||||
rtw_cipher_wep.ic_decap = rtw_wep_decap;
|
||||
ic->ic_nw_keys[k->wk_keyix].wk_cipher = &rtw_cipher_wep;
|
||||
}
|
||||
sc->sc_flags &= ~RTW_F_DK_VALID;
|
||||
|
||||
return 1;
|
||||
@ -611,7 +631,7 @@ rtw_key_update_end(struct ieee80211com *ic)
|
||||
static void
|
||||
rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_key *wk, int txkey)
|
||||
{
|
||||
uint8_t cfg0, scr;
|
||||
uint8_t cfg0, psr, scr;
|
||||
int i, tx_key_len;
|
||||
struct rtw_regs *regs;
|
||||
union rtw_keys *rk;
|
||||
@ -621,13 +641,14 @@ rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_key *wk, int txkey)
|
||||
|
||||
(void)memset(rk->rk_keys, 0, sizeof(rk->rk_keys));
|
||||
|
||||
rtw_set_access(regs, RTW_ACCESS_CONFIG);
|
||||
|
||||
psr = RTW_READ8(regs, RTW_PSR);
|
||||
scr = RTW_READ8(regs, RTW_SCR);
|
||||
cfg0 = RTW_READ8(regs, RTW_CONFIG0);
|
||||
scr &= ~(RTW_SCR_KM_MASK | RTW_SCR_TXSECON | RTW_SCR_RXSECON);
|
||||
cfg0 &= ~(RTW_CONFIG0_WEP104 | RTW_CONFIG0_WEP40);
|
||||
|
||||
rtw_set_access(regs, RTW_ACCESS_CONFIG);
|
||||
|
||||
if ((sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) == 0)
|
||||
goto out;
|
||||
|
||||
@ -635,10 +656,10 @@ rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_key *wk, int txkey)
|
||||
|
||||
switch (tx_key_len) {
|
||||
case 5:
|
||||
scr |= RTW_SCR_KM_WEP40;
|
||||
scr |= RTW_SCR_RXSECON | RTW_SCR_KM_WEP40;
|
||||
break;
|
||||
case 13:
|
||||
scr |= RTW_SCR_KM_WEP104;
|
||||
scr |= RTW_SCR_RXSECON | RTW_SCR_KM_WEP104;
|
||||
break;
|
||||
default:
|
||||
goto out;
|
||||
@ -653,14 +674,19 @@ rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_key *wk, int txkey)
|
||||
}
|
||||
|
||||
out:
|
||||
RTW_WRITE8(regs, RTW_PSR, psr & ~RTW_PSR_PSEN);
|
||||
|
||||
bus_space_write_region_4(regs->r_bt, regs->r_bh,
|
||||
RTW_DK0, rk->rk_words,
|
||||
sizeof(rk->rk_words) / sizeof(rk->rk_words[0]));
|
||||
|
||||
bus_space_barrier(regs->r_bt, regs->r_bh, RTW_DK0,
|
||||
sizeof(rk->rk_words) / sizeof(rk->rk_words[0]),
|
||||
bus_space_barrier(regs->r_bt, regs->r_bh, RTW_DK0, sizeof(rk->rk_words),
|
||||
BUS_SPACE_BARRIER_SYNC);
|
||||
|
||||
printf("%s: psr = %#" PRIx8, sc->sc_dev.dv_xname, psr);
|
||||
|
||||
RTW_WRITE8(regs, RTW_PSR, psr);
|
||||
|
||||
RTW_WRITE8(regs, RTW_CONFIG0, cfg0);
|
||||
RTW_WBW(regs, RTW_CONFIG0, RTW_SCR);
|
||||
RTW_WRITE8(regs, RTW_SCR, scr);
|
||||
|
Loading…
Reference in New Issue
Block a user