Lines 232-239
Link Here
|
232 |
static void wpi_update_beacon(struct ieee80211vap *, int); |
232 |
static void wpi_update_beacon(struct ieee80211vap *, int); |
233 |
static void wpi_newassoc(struct ieee80211_node *, int); |
233 |
static void wpi_newassoc(struct ieee80211_node *, int); |
234 |
static int wpi_run(struct wpi_softc *, struct ieee80211vap *); |
234 |
static int wpi_run(struct wpi_softc *, struct ieee80211vap *); |
235 |
static int wpi_key_alloc(struct ieee80211vap *, struct ieee80211_key *, |
235 |
static int wpi_load_key(struct ieee80211_node *, |
236 |
ieee80211_keyix *, ieee80211_keyix *); |
236 |
const struct ieee80211_key *); |
|
|
237 |
static void wpi_load_key_cb(void *, struct ieee80211_node *); |
238 |
static int wpi_set_global_keys(struct ieee80211_node *); |
239 |
static int wpi_del_key(struct ieee80211_node *, |
240 |
const struct ieee80211_key *); |
241 |
static void wpi_del_key_cb(void *, struct ieee80211_node *); |
242 |
static int wpi_process_key(struct ieee80211vap *, |
243 |
const struct ieee80211_key *, int); |
237 |
static int wpi_key_set(struct ieee80211vap *, |
244 |
static int wpi_key_set(struct ieee80211vap *, |
238 |
const struct ieee80211_key *, |
245 |
const struct ieee80211_key *, |
239 |
const uint8_t mac[IEEE80211_ADDR_LEN]); |
246 |
const uint8_t mac[IEEE80211_ADDR_LEN]); |
Lines 623-629
Link Here
|
623 |
} |
630 |
} |
624 |
|
631 |
|
625 |
/* Override with driver methods. */ |
632 |
/* Override with driver methods. */ |
626 |
vap->iv_key_alloc = wpi_key_alloc; |
|
|
627 |
vap->iv_key_set = wpi_key_set; |
633 |
vap->iv_key_set = wpi_key_set; |
628 |
vap->iv_key_delete = wpi_key_delete; |
634 |
vap->iv_key_delete = wpi_key_delete; |
629 |
wvp->wv_newstate = vap->iv_newstate; |
635 |
wvp->wv_newstate = vap->iv_newstate; |
Lines 1775-1781
Link Here
|
1775 |
struct wpi_rx_data *data) |
1781 |
struct wpi_rx_data *data) |
1776 |
{ |
1782 |
{ |
1777 |
struct ifnet *ifp = sc->sc_ifp; |
1783 |
struct ifnet *ifp = sc->sc_ifp; |
1778 |
const struct ieee80211_cipher *cip = NULL; |
|
|
1779 |
struct ieee80211com *ic = ifp->if_l2com; |
1784 |
struct ieee80211com *ic = ifp->if_l2com; |
1780 |
struct wpi_rx_ring *ring = &sc->rxq; |
1785 |
struct wpi_rx_ring *ring = &sc->rxq; |
1781 |
struct wpi_rx_stat *stat; |
1786 |
struct wpi_rx_stat *stat; |
Lines 1863-1878
Link Here
|
1863 |
|
1868 |
|
1864 |
/* Grab a reference to the source node. */ |
1869 |
/* Grab a reference to the source node. */ |
1865 |
wh = mtod(m, struct ieee80211_frame *); |
1870 |
wh = mtod(m, struct ieee80211_frame *); |
1866 |
ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); |
|
|
1867 |
|
1871 |
|
1868 |
if (ni != NULL) |
|
|
1869 |
cip = ni->ni_ucastkey.wk_cipher; |
1870 |
if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && |
1872 |
if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) && |
1871 |
!IEEE80211_IS_MULTICAST(wh->i_addr1) && |
1873 |
(flags & WPI_RX_CIPHER_MASK) == WPI_RX_CIPHER_CCMP) { |
1872 |
cip != NULL && cip->ic_cipher == IEEE80211_CIPHER_AES_CCM) { |
|
|
1873 |
if ((flags & WPI_RX_CIPHER_MASK) != WPI_RX_CIPHER_CCMP) |
1874 |
goto fail2; |
1875 |
|
1876 |
/* Check whether decryption was successful or not. */ |
1874 |
/* Check whether decryption was successful or not. */ |
1877 |
if ((flags & WPI_RX_DECRYPT_MASK) != WPI_RX_DECRYPT_OK) { |
1875 |
if ((flags & WPI_RX_DECRYPT_MASK) != WPI_RX_DECRYPT_OK) { |
1878 |
DPRINTF(sc, WPI_DEBUG_RECV, |
1876 |
DPRINTF(sc, WPI_DEBUG_RECV, |
Lines 1882-1887
Link Here
|
1882 |
m->m_flags |= M_WEP; |
1880 |
m->m_flags |= M_WEP; |
1883 |
} |
1881 |
} |
1884 |
|
1882 |
|
|
|
1883 |
ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); |
1884 |
|
1885 |
if (ieee80211_radiotap_active(ic)) { |
1885 |
if (ieee80211_radiotap_active(ic)) { |
1886 |
struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap; |
1886 |
struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap; |
1887 |
|
1887 |
|
Lines 1909-1916
Link Here
|
1909 |
|
1909 |
|
1910 |
return; |
1910 |
return; |
1911 |
|
1911 |
|
1912 |
fail2: ieee80211_free_node(ni); |
1912 |
fail2: m_freem(m); |
1913 |
m_freem(m); |
|
|
1914 |
|
1913 |
|
1915 |
fail1: if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1914 |
fail1: if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1916 |
} |
1915 |
} |
Lines 3094-3101
Link Here
|
3094 |
wpi_add_node(struct wpi_softc *sc, struct ieee80211_node *ni) |
3093 |
wpi_add_node(struct wpi_softc *sc, struct ieee80211_node *ni) |
3095 |
{ |
3094 |
{ |
3096 |
struct ieee80211com *ic = ni->ni_ic; |
3095 |
struct ieee80211com *ic = ni->ni_ic; |
|
|
3096 |
struct wpi_vap *wvp = WPI_VAP(ni->ni_vap); |
3097 |
struct wpi_node *wn = WPI_NODE(ni); |
3097 |
struct wpi_node *wn = WPI_NODE(ni); |
3098 |
struct wpi_node_info node; |
3098 |
struct wpi_node_info node; |
|
|
3099 |
int error; |
3099 |
|
3100 |
|
3100 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
3101 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
3101 |
|
3102 |
|
Lines 3110-3116
Link Here
|
3110 |
node.action = htole32(WPI_ACTION_SET_RATE); |
3111 |
node.action = htole32(WPI_ACTION_SET_RATE); |
3111 |
node.antenna = WPI_ANTENNA_BOTH; |
3112 |
node.antenna = WPI_ANTENNA_BOTH; |
3112 |
|
3113 |
|
3113 |
return wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof node, 1); |
3114 |
error = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof node, 1); |
|
|
3115 |
if (error != 0) { |
3116 |
device_printf(sc->sc_dev, |
3117 |
"%s: wpi_cmd() call failed with error code %d\n", __func__, |
3118 |
error); |
3119 |
return error; |
3120 |
} |
3121 |
|
3122 |
if (wvp->wv_gtk != 0) { |
3123 |
error = wpi_set_global_keys(ni); |
3124 |
if (error != 0) { |
3125 |
device_printf(sc->sc_dev, |
3126 |
"%s: error while setting global keys\n", __func__); |
3127 |
return ENXIO; |
3128 |
} |
3129 |
} |
3130 |
|
3131 |
return 0; |
3114 |
} |
3132 |
} |
3115 |
|
3133 |
|
3116 |
/* |
3134 |
/* |
Lines 4237-4273
Link Here
|
4237 |
} |
4255 |
} |
4238 |
|
4256 |
|
4239 |
static int |
4257 |
static int |
4240 |
wpi_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, |
4258 |
wpi_load_key(struct ieee80211_node *ni, const struct ieee80211_key *k) |
4241 |
ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) |
|
|
4242 |
{ |
4259 |
{ |
4243 |
struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc; |
|
|
4244 |
|
4245 |
if (!(&vap->iv_nw_keys[0] <= k && |
4246 |
k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) { |
4247 |
if (k->wk_flags & IEEE80211_KEY_GROUP) { |
4248 |
/* should not happen */ |
4249 |
DPRINTF(sc, WPI_DEBUG_KEY, "%s: bogus group key\n", |
4250 |
__func__); |
4251 |
return 0; |
4252 |
} |
4253 |
*keyix = 0; /* NB: use key index 0 for ucast key */ |
4254 |
} else { |
4255 |
*keyix = *rxkeyix = k - vap->iv_nw_keys; |
4256 |
|
4257 |
if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) |
4258 |
k->wk_flags |= IEEE80211_KEY_SWCRYPT; |
4259 |
} |
4260 |
return 1; |
4261 |
} |
4262 |
|
4263 |
static int |
4264 |
wpi_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, |
4265 |
const uint8_t mac[IEEE80211_ADDR_LEN]) |
4266 |
{ |
4267 |
const struct ieee80211_cipher *cip = k->wk_cipher; |
4260 |
const struct ieee80211_cipher *cip = k->wk_cipher; |
4268 |
struct ieee80211com *ic = vap->iv_ic; |
4261 |
struct ieee80211vap *vap = ni->ni_vap; |
4269 |
struct ieee80211_node *ni = vap->iv_bss; |
4262 |
struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; |
4270 |
struct wpi_softc *sc = ic->ic_ifp->if_softc; |
|
|
4271 |
struct wpi_node *wn = WPI_NODE(ni); |
4263 |
struct wpi_node *wn = WPI_NODE(ni); |
4272 |
struct wpi_node_info node; |
4264 |
struct wpi_node_info node; |
4273 |
uint16_t kflags; |
4265 |
uint16_t kflags; |
Lines 4275-4295
Link Here
|
4275 |
|
4267 |
|
4276 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
4268 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
4277 |
|
4269 |
|
|
|
4270 |
if (wpi_check_node_entry(sc, wn->id) == 0) { |
4271 |
device_printf(sc->sc_dev, "%s: node does not exist\n", |
4272 |
__func__); |
4273 |
return 0; |
4274 |
} |
4275 |
|
4278 |
switch (cip->ic_cipher) { |
4276 |
switch (cip->ic_cipher) { |
4279 |
case IEEE80211_CIPHER_AES_CCM: |
4277 |
case IEEE80211_CIPHER_AES_CCM: |
4280 |
if (k->wk_flags & IEEE80211_KEY_GROUP) |
|
|
4281 |
return 1; |
4282 |
|
4283 |
kflags = WPI_KFLAG_CCMP; |
4278 |
kflags = WPI_KFLAG_CCMP; |
4284 |
break; |
4279 |
break; |
|
|
4280 |
|
4285 |
default: |
4281 |
default: |
4286 |
/* null_key_set() */ |
4282 |
device_printf(sc->sc_dev, "%s: unknown cipher %d\n", __func__, |
4287 |
return 1; |
4283 |
cip->ic_cipher); |
|
|
4284 |
return 0; |
4288 |
} |
4285 |
} |
4289 |
|
4286 |
|
4290 |
if (wn->id == WPI_ID_UNDEFINED) |
|
|
4291 |
return 0; |
4292 |
|
4293 |
kflags |= WPI_KFLAG_KID(k->wk_keyix); |
4287 |
kflags |= WPI_KFLAG_KID(k->wk_keyix); |
4294 |
if (k->wk_flags & IEEE80211_KEY_GROUP) |
4288 |
if (k->wk_flags & IEEE80211_KEY_GROUP) |
4295 |
kflags |= WPI_KFLAG_MULTICAST; |
4289 |
kflags |= WPI_KFLAG_MULTICAST; |
Lines 4300-4354
Link Here
|
4300 |
node.flags = WPI_FLAG_KEY_SET; |
4294 |
node.flags = WPI_FLAG_KEY_SET; |
4301 |
node.kflags = htole16(kflags); |
4295 |
node.kflags = htole16(kflags); |
4302 |
memcpy(node.key, k->wk_key, k->wk_keylen); |
4296 |
memcpy(node.key, k->wk_key, k->wk_keylen); |
|
|
4297 |
again: |
4298 |
DPRINTF(sc, WPI_DEBUG_KEY, |
4299 |
"%s: setting %s key id %d for node %d (%s)\n", __func__, |
4300 |
(kflags & WPI_KFLAG_MULTICAST) ? "group" : "ucast", k->wk_keyix, |
4301 |
node.id, ether_sprintf(ni->ni_macaddr)); |
4303 |
|
4302 |
|
4304 |
DPRINTF(sc, WPI_DEBUG_KEY, "set key id=%d for node %d\n", k->wk_keyix, |
|
|
4305 |
node.id); |
4306 |
|
4307 |
error = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof node, 1); |
4303 |
error = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof node, 1); |
4308 |
if (error != 0) { |
4304 |
if (error != 0) { |
4309 |
device_printf(sc->sc_dev, "can't update node info, error %d\n", |
4305 |
device_printf(sc->sc_dev, "can't update node info, error %d\n", |
4310 |
error); |
4306 |
error); |
4311 |
return 0; |
4307 |
return !error; |
4312 |
} |
4308 |
} |
4313 |
|
4309 |
|
|
|
4310 |
if (!(kflags & WPI_KFLAG_MULTICAST) && &vap->iv_nw_keys[0] <= k && |
4311 |
k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]) { |
4312 |
kflags |= WPI_KFLAG_MULTICAST; |
4313 |
node.kflags = htole16(kflags); |
4314 |
|
4315 |
goto again; |
4316 |
} |
4317 |
|
4314 |
return 1; |
4318 |
return 1; |
4315 |
} |
4319 |
} |
4316 |
|
4320 |
|
|
|
4321 |
static void |
4322 |
wpi_load_key_cb(void *arg, struct ieee80211_node *ni) |
4323 |
{ |
4324 |
const struct ieee80211_key *k = arg; |
4325 |
struct ieee80211vap *vap = ni->ni_vap; |
4326 |
struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; |
4327 |
struct wpi_node *wn = WPI_NODE(ni); |
4328 |
int error; |
4329 |
|
4330 |
if (vap->iv_bss == ni && wn->id == WPI_ID_UNDEFINED) |
4331 |
return; |
4332 |
|
4333 |
WPI_NT_LOCK(sc); |
4334 |
error = wpi_load_key(ni, k); |
4335 |
WPI_NT_UNLOCK(sc); |
4336 |
|
4337 |
if (error == 0) { |
4338 |
device_printf(sc->sc_dev, "%s: error while setting key\n", |
4339 |
__func__); |
4340 |
} |
4341 |
} |
4342 |
|
4317 |
static int |
4343 |
static int |
4318 |
wpi_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) |
4344 |
wpi_set_global_keys(struct ieee80211_node *ni) |
4319 |
{ |
4345 |
{ |
4320 |
const struct ieee80211_cipher *cip = k->wk_cipher; |
4346 |
struct ieee80211vap *vap = ni->ni_vap; |
4321 |
struct ieee80211com *ic = vap->iv_ic; |
4347 |
struct ieee80211_key *wk = &vap->iv_nw_keys[0]; |
4322 |
struct ieee80211_node *ni = vap->iv_bss; |
4348 |
int error = 1; |
4323 |
struct wpi_softc *sc = ic->ic_ifp->if_softc; |
4349 |
|
|
|
4350 |
for (; wk < &vap->iv_nw_keys[IEEE80211_WEP_NKID] && error; wk++) |
4351 |
if (wk->wk_keyix != IEEE80211_KEYIX_NONE) |
4352 |
error = wpi_load_key(ni, wk); |
4353 |
|
4354 |
return !error; |
4355 |
} |
4356 |
|
4357 |
static int |
4358 |
wpi_del_key(struct ieee80211_node *ni, const struct ieee80211_key *k) |
4359 |
{ |
4360 |
struct ieee80211vap *vap = ni->ni_vap; |
4361 |
struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; |
4324 |
struct wpi_node *wn = WPI_NODE(ni); |
4362 |
struct wpi_node *wn = WPI_NODE(ni); |
4325 |
struct wpi_node_info node; |
4363 |
struct wpi_node_info node; |
|
|
4364 |
uint16_t kflags; |
4365 |
int error; |
4326 |
|
4366 |
|
4327 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
4367 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
4328 |
|
4368 |
|
4329 |
switch (cip->ic_cipher) { |
4369 |
if (wpi_check_node_entry(sc, wn->id) == 0) { |
4330 |
case IEEE80211_CIPHER_AES_CCM: |
4370 |
DPRINTF(sc, WPI_DEBUG_KEY, "%s: node was removed\n", __func__); |
4331 |
break; |
4371 |
return 1; /* Nothing to do. */ |
4332 |
default: |
|
|
4333 |
/* null_key_delete() */ |
4334 |
return 1; |
4335 |
} |
4372 |
} |
4336 |
|
4373 |
|
4337 |
if (vap->iv_state != IEEE80211_S_RUN || |
4374 |
kflags = WPI_KFLAG_KID(k->wk_keyix); |
4338 |
(k->wk_flags & IEEE80211_KEY_GROUP)) |
4375 |
if (k->wk_flags & IEEE80211_KEY_GROUP) |
4339 |
return 1; /* Nothing to do. */ |
4376 |
kflags |= WPI_KFLAG_MULTICAST; |
4340 |
|
4377 |
|
4341 |
memset(&node, 0, sizeof node); |
4378 |
memset(&node, 0, sizeof node); |
4342 |
node.id = wn->id; |
4379 |
node.id = wn->id; |
4343 |
node.control = WPI_NODE_UPDATE; |
4380 |
node.control = WPI_NODE_UPDATE; |
4344 |
node.flags = WPI_FLAG_KEY_SET; |
4381 |
node.flags = WPI_FLAG_KEY_SET; |
|
|
4382 |
node.kflags = htole16(kflags); |
4383 |
again: |
4384 |
DPRINTF(sc, WPI_DEBUG_KEY, "%s: deleting %s key %d for node %d (%s)\n", |
4385 |
__func__, (kflags & WPI_KFLAG_MULTICAST) ? "group" : "ucast", |
4386 |
k->wk_keyix, node.id, ether_sprintf(ni->ni_macaddr)); |
4345 |
|
4387 |
|
4346 |
DPRINTF(sc, WPI_DEBUG_KEY, "delete keys for node %d\n", node.id); |
4388 |
error = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof node, 1); |
4347 |
(void)wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof node, 1); |
4389 |
if (error != 0) { |
|
|
4390 |
device_printf(sc->sc_dev, "can't update node info, error %d\n", |
4391 |
error); |
4392 |
return !error; |
4393 |
} |
4348 |
|
4394 |
|
|
|
4395 |
if (!(kflags & WPI_KFLAG_MULTICAST) && &vap->iv_nw_keys[0] <= k && |
4396 |
k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]) { |
4397 |
kflags |= WPI_KFLAG_MULTICAST; |
4398 |
node.kflags = htole16(kflags); |
4399 |
|
4400 |
goto again; |
4401 |
} |
4402 |
|
4349 |
return 1; |
4403 |
return 1; |
4350 |
} |
4404 |
} |
4351 |
|
4405 |
|
|
|
4406 |
static void |
4407 |
wpi_del_key_cb(void *arg, struct ieee80211_node *ni) |
4408 |
{ |
4409 |
const struct ieee80211_key *k = arg; |
4410 |
struct ieee80211vap *vap = ni->ni_vap; |
4411 |
struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; |
4412 |
struct wpi_node *wn = WPI_NODE(ni); |
4413 |
int error; |
4414 |
|
4415 |
if (vap->iv_bss == ni && wn->id == WPI_ID_UNDEFINED) |
4416 |
return; |
4417 |
|
4418 |
WPI_NT_LOCK(sc); |
4419 |
error = wpi_del_key(ni, k); |
4420 |
WPI_NT_UNLOCK(sc); |
4421 |
|
4422 |
if (error == 0) { |
4423 |
device_printf(sc->sc_dev, "%s: error while deleting key\n", |
4424 |
__func__); |
4425 |
} |
4426 |
} |
4427 |
|
4428 |
static int |
4429 |
wpi_process_key(struct ieee80211vap *vap, const struct ieee80211_key *k, |
4430 |
int set) |
4431 |
{ |
4432 |
struct ieee80211com *ic = vap->iv_ic; |
4433 |
struct wpi_softc *sc = ic->ic_ifp->if_softc; |
4434 |
struct wpi_vap *wvp = WPI_VAP(vap); |
4435 |
struct ieee80211_node *ni; |
4436 |
int error, ni_ref = 0; |
4437 |
|
4438 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
4439 |
|
4440 |
if (k->wk_flags & IEEE80211_KEY_SWCRYPT) { |
4441 |
/* Not for us. */ |
4442 |
return 1; |
4443 |
} |
4444 |
|
4445 |
if (!(k->wk_flags & IEEE80211_KEY_RECV)) { |
4446 |
/* XMIT keys are handled in wpi_tx_data(). */ |
4447 |
return 1; |
4448 |
} |
4449 |
|
4450 |
/* Handle group keys. */ |
4451 |
if (&vap->iv_nw_keys[0] <= k && |
4452 |
k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]) { |
4453 |
WPI_NT_LOCK(sc); |
4454 |
if (set) |
4455 |
wvp->wv_gtk |= WPI_VAP_KEY(k->wk_keyix); |
4456 |
else |
4457 |
wvp->wv_gtk &= ~WPI_VAP_KEY(k->wk_keyix); |
4458 |
WPI_NT_UNLOCK(sc); |
4459 |
|
4460 |
if (vap->iv_state == IEEE80211_S_RUN) { |
4461 |
ieee80211_iterate_nodes(&ic->ic_sta, |
4462 |
set ? wpi_load_key_cb : wpi_del_key_cb, (void *)k); |
4463 |
} |
4464 |
|
4465 |
return 1; |
4466 |
} |
4467 |
|
4468 |
switch (vap->iv_opmode) { |
4469 |
case IEEE80211_M_STA: |
4470 |
ni = vap->iv_bss; |
4471 |
break; |
4472 |
|
4473 |
case IEEE80211_M_IBSS: |
4474 |
case IEEE80211_M_AHDEMO: |
4475 |
ni = ieee80211_find_vap_node(&ic->ic_sta, vap, k->wk_macaddr); |
4476 |
if (ni == NULL) |
4477 |
return 0; /* should not happen */ |
4478 |
|
4479 |
ni_ref = 1; |
4480 |
break; |
4481 |
|
4482 |
default: |
4483 |
device_printf(sc->sc_dev, "%s: unknown opmode %d\n", __func__, |
4484 |
vap->iv_opmode); |
4485 |
return 0; |
4486 |
} |
4487 |
|
4488 |
WPI_NT_LOCK(sc); |
4489 |
if (set) |
4490 |
error = wpi_load_key(ni, k); |
4491 |
else |
4492 |
error = wpi_del_key(ni, k); |
4493 |
WPI_NT_UNLOCK(sc); |
4494 |
|
4495 |
if (ni_ref) |
4496 |
ieee80211_node_decref(ni); |
4497 |
|
4498 |
return error; |
4499 |
} |
4500 |
|
4501 |
static int |
4502 |
wpi_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, |
4503 |
const uint8_t mac[IEEE80211_ADDR_LEN]) |
4504 |
{ |
4505 |
return wpi_process_key(vap, k, 1); |
4506 |
} |
4507 |
|
4508 |
static int |
4509 |
wpi_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) |
4510 |
{ |
4511 |
return wpi_process_key(vap, k, 0); |
4512 |
} |
4513 |
|
4352 |
/* |
4514 |
/* |
4353 |
* This function is called after the runtime firmware notifies us of its |
4515 |
* This function is called after the runtime firmware notifies us of its |
4354 |
* readiness (called in a process context). |
4516 |
* readiness (called in a process context). |