View | Details | Raw Unified | Return to bug 197143 | Differences between
and this patch

Collapse All | Expand All

(-)sys/dev/wpi/if_wpi.c (-72 / +234 lines)
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).
(-)sys/dev/wpi/if_wpivar.h (+3 lines)
Lines 127-132 Link Here
127
	struct ieee80211_beacon_offsets	wv_boff;
127
	struct ieee80211_beacon_offsets	wv_boff;
128
	struct mtx			wv_mtx;
128
	struct mtx			wv_mtx;
129
129
130
	uint32_t			wv_gtk;
131
#define WPI_VAP_KEY(kid)		(1 << kid)
132
130
	int				(*wv_newstate)(struct ieee80211vap *,
133
	int				(*wv_newstate)(struct ieee80211vap *,
131
					    enum ieee80211_state, int);
134
					    enum ieee80211_state, int);
132
};
135
};

Return to bug 197143