Lines 227-234
Link Here
|
227 |
struct ieee80211_channel *); |
227 |
struct ieee80211_channel *); |
228 |
static int wpi_scan(struct wpi_softc *, struct ieee80211_channel *); |
228 |
static int wpi_scan(struct wpi_softc *, struct ieee80211_channel *); |
229 |
static int wpi_auth(struct wpi_softc *, struct ieee80211vap *); |
229 |
static int wpi_auth(struct wpi_softc *, struct ieee80211vap *); |
|
|
230 |
static int wpi_config_beacon(struct wpi_vap *); |
231 |
static int wpi_setup_beacon(struct wpi_softc *, struct ieee80211_node *); |
230 |
static void wpi_update_beacon(struct ieee80211vap *, int); |
232 |
static void wpi_update_beacon(struct ieee80211vap *, int); |
231 |
static int wpi_setup_beacon(struct wpi_softc *, struct ieee80211_node *); |
|
|
232 |
static void wpi_newassoc(struct ieee80211_node *, int); |
233 |
static void wpi_newassoc(struct ieee80211_node *, int); |
233 |
static int wpi_run(struct wpi_softc *, struct ieee80211vap *); |
234 |
static int wpi_run(struct wpi_softc *, struct ieee80211vap *); |
234 |
static int wpi_key_alloc(struct ieee80211vap *, struct ieee80211_key *, |
235 |
static int wpi_key_alloc(struct ieee80211vap *, struct ieee80211_key *, |
Lines 639-648
Link Here
|
639 |
wpi_vap_delete(struct ieee80211vap *vap) |
640 |
wpi_vap_delete(struct ieee80211vap *vap) |
640 |
{ |
641 |
{ |
641 |
struct wpi_vap *wvp = WPI_VAP(vap); |
642 |
struct wpi_vap *wvp = WPI_VAP(vap); |
|
|
643 |
struct wpi_buf *bcn = &wvp->wv_bcbuf; |
644 |
enum ieee80211_opmode opmode = vap->iv_opmode; |
642 |
|
645 |
|
643 |
ieee80211_ratectl_deinit(vap); |
646 |
ieee80211_ratectl_deinit(vap); |
644 |
ieee80211_vap_detach(vap); |
647 |
ieee80211_vap_detach(vap); |
645 |
|
648 |
|
|
|
649 |
if (opmode == IEEE80211_M_IBSS) { |
650 |
if (bcn->m != NULL) |
651 |
m_freem(bcn->m); |
652 |
} |
653 |
|
646 |
free(wvp, M_80211_VAP); |
654 |
free(wvp, M_80211_VAP); |
647 |
} |
655 |
} |
648 |
|
656 |
|
Lines 3945-3958
Link Here
|
3945 |
} |
3953 |
} |
3946 |
|
3954 |
|
3947 |
static int |
3955 |
static int |
|
|
3956 |
wpi_config_beacon(struct wpi_vap *wvp) |
3957 |
{ |
3958 |
struct ieee80211com *ic = wvp->vap.iv_ic; |
3959 |
struct ieee80211_beacon_offsets *bo = &wvp->wv_boff; |
3960 |
struct wpi_buf *bcn = &wvp->wv_bcbuf; |
3961 |
struct wpi_softc *sc = ic->ic_ifp->if_softc; |
3962 |
struct wpi_cmd_beacon *cmd = (struct wpi_cmd_beacon *)&bcn->data; |
3963 |
struct ieee80211_tim_ie *tie; |
3964 |
struct mbuf *m; |
3965 |
uint8_t *ptr; |
3966 |
int error; |
3967 |
|
3968 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
3969 |
|
3970 |
WPI_LOCK_ASSERT(sc); |
3971 |
|
3972 |
cmd->len = htole16(bcn->m->m_pkthdr.len); |
3973 |
cmd->plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ? |
3974 |
wpi_ridx_to_plcp[WPI_RIDX_OFDM6] : wpi_ridx_to_plcp[WPI_RIDX_CCK1]; |
3975 |
|
3976 |
/* XXX seems to be unused */ |
3977 |
if (*(bo->bo_tim) == IEEE80211_ELEMID_TIM) { |
3978 |
tie = (struct ieee80211_tim_ie *) bo->bo_tim; |
3979 |
ptr = mtod(bcn->m, uint8_t *); |
3980 |
|
3981 |
cmd->tim = htole16(bo->bo_tim - ptr); |
3982 |
cmd->timsz = tie->tim_len; |
3983 |
} |
3984 |
|
3985 |
/* Necessary for recursion in ieee80211_beacon_update(). */ |
3986 |
m = bcn->m; |
3987 |
bcn->m = m_dup(m, M_NOWAIT); |
3988 |
if (bcn->m == NULL) { |
3989 |
device_printf(sc->sc_dev, |
3990 |
"%s: could not copy beacon frame\n", __func__); |
3991 |
error = ENOMEM; |
3992 |
goto end; |
3993 |
} |
3994 |
|
3995 |
if ((error = wpi_cmd2(sc, bcn)) != 0) { |
3996 |
device_printf(sc->sc_dev, |
3997 |
"%s: could not update beacon frame, error %d", __func__, |
3998 |
error); |
3999 |
} |
4000 |
|
4001 |
/* Restore mbuf. */ |
4002 |
end: bcn->m = m; |
4003 |
|
4004 |
return error; |
4005 |
} |
4006 |
|
4007 |
static int |
3948 |
wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni) |
4008 |
wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni) |
3949 |
{ |
4009 |
{ |
3950 |
struct ieee80211com *ic = sc->sc_ifp->if_l2com; |
|
|
3951 |
struct wpi_vap *wvp = WPI_VAP(ni->ni_vap); |
4010 |
struct wpi_vap *wvp = WPI_VAP(ni->ni_vap); |
3952 |
struct wpi_buf *bcn = &wvp->wv_bcbuf; |
4011 |
struct wpi_buf *bcn = &wvp->wv_bcbuf; |
3953 |
struct ieee80211_beacon_offsets bo; |
4012 |
struct ieee80211_beacon_offsets *bo = &wvp->wv_boff; |
3954 |
struct wpi_cmd_beacon *cmd = (struct wpi_cmd_beacon *)&bcn->data; |
|
|
3955 |
struct mbuf *m; |
4013 |
struct mbuf *m; |
|
|
4014 |
int error; |
3956 |
|
4015 |
|
3957 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
4016 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
3958 |
|
4017 |
|
Lines 3959-3965
Link Here
|
3959 |
if (ni->ni_chan == IEEE80211_CHAN_ANYC) |
4018 |
if (ni->ni_chan == IEEE80211_CHAN_ANYC) |
3960 |
return EINVAL; |
4019 |
return EINVAL; |
3961 |
|
4020 |
|
3962 |
m = ieee80211_beacon_alloc(ni, &bo); |
4021 |
m = ieee80211_beacon_alloc(ni, bo); |
3963 |
if (m == NULL) { |
4022 |
if (m == NULL) { |
3964 |
device_printf(sc->sc_dev, |
4023 |
device_printf(sc->sc_dev, |
3965 |
"%s: could not allocate beacon frame\n", __func__); |
4024 |
"%s: could not allocate beacon frame\n", __func__); |
Lines 3966-3979
Link Here
|
3966 |
return ENOMEM; |
4025 |
return ENOMEM; |
3967 |
} |
4026 |
} |
3968 |
|
4027 |
|
3969 |
cmd->len = htole16(m->m_pkthdr.len); |
4028 |
if (bcn->m != NULL) |
3970 |
cmd->plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ? |
4029 |
m_freem(bcn->m); |
3971 |
wpi_ridx_to_plcp[WPI_RIDX_OFDM6] : wpi_ridx_to_plcp[WPI_RIDX_CCK1]; |
|
|
3972 |
|
4030 |
|
3973 |
/* NB: m will be freed in wpi_cmd_done() */ |
|
|
3974 |
bcn->m = m; |
4031 |
bcn->m = m; |
3975 |
|
4032 |
|
3976 |
return wpi_cmd2(sc, bcn); |
4033 |
error = wpi_config_beacon(wvp); |
|
|
4034 |
|
4035 |
return error; |
3977 |
} |
4036 |
} |
3978 |
|
4037 |
|
3979 |
static void |
4038 |
static void |
Lines 3980-3995
Link Here
|
3980 |
wpi_update_beacon(struct ieee80211vap *vap, int item) |
4039 |
wpi_update_beacon(struct ieee80211vap *vap, int item) |
3981 |
{ |
4040 |
{ |
3982 |
struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc; |
4041 |
struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc; |
|
|
4042 |
struct wpi_vap *wvp = WPI_VAP(vap); |
4043 |
struct wpi_buf *bcn = &wvp->wv_bcbuf; |
4044 |
struct ieee80211_beacon_offsets *bo = &wvp->wv_boff; |
3983 |
struct ieee80211_node *ni = vap->iv_bss; |
4045 |
struct ieee80211_node *ni = vap->iv_bss; |
3984 |
int error; |
4046 |
int mcast = 0; |
3985 |
|
4047 |
|
|
|
4048 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); |
4049 |
|
3986 |
WPI_LOCK(sc); |
4050 |
WPI_LOCK(sc); |
3987 |
if ((error = wpi_setup_beacon(sc, ni)) != 0) { |
4051 |
if (bcn->m == NULL) { |
3988 |
device_printf(sc->sc_dev, |
4052 |
bcn->m = ieee80211_beacon_alloc(ni, bo); |
3989 |
"%s: could not update beacon frame, error %d", __func__, |
4053 |
if (bcn->m == NULL) { |
3990 |
error); |
4054 |
device_printf(sc->sc_dev, |
|
|
4055 |
"%s: could not allocate beacon frame\n", __func__); |
4056 |
WPI_UNLOCK(sc); |
4057 |
|
4058 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, |
4059 |
__func__); |
4060 |
|
4061 |
return; |
4062 |
} |
3991 |
} |
4063 |
} |
3992 |
WPI_UNLOCK(sc); |
4064 |
WPI_UNLOCK(sc); |
|
|
4065 |
|
4066 |
if (item == IEEE80211_BEACON_TIM) |
4067 |
mcast = 1; /* TODO */ |
4068 |
|
4069 |
setbit(bo->bo_flags, item); |
4070 |
ieee80211_beacon_update(ni, bo, bcn->m, mcast); |
4071 |
|
4072 |
WPI_LOCK(sc); |
4073 |
wpi_config_beacon(wvp); |
4074 |
WPI_UNLOCK(sc); |
4075 |
|
4076 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__); |
3993 |
} |
4077 |
} |
3994 |
|
4078 |
|
3995 |
static void |
4079 |
static void |