Пример #1
0
static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
{
	struct ieee80211_sub_if_data *sdata;
	struct sta_info *sta;
	int ret;

	might_sleep();

	if (!key || !key->local->ops->set_key)
		return;

	assert_key_lock(key->local);

	if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
		return;

	sta = key->sta;
	sdata = key->sdata;

	if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
	      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
	      (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
		increment_tailroom_need_count(sdata);

	ret = drv_set_key(key->local, DISABLE_KEY, sdata,
			  sta ? &sta->sta : NULL, &key->conf);

	if (ret)
		sdata_err(sdata,
			  "failed to remove key (%d, %pM) from hardware (%d)\n",
			  key->conf.keyidx,
			  sta ? sta->sta.addr : bcast_addr, ret);

	key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
}
Пример #2
0
Файл: key.c Проект: DINKIN/tuo
static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
{
	const u8 *addr;
	int ret;
	DECLARE_MAC_BUF(mac);

	assert_key_lock();
	might_sleep();

	if (!key || !key->local->ops->set_key)
		return;

	spin_lock(&todo_lock);
	if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
		spin_unlock(&todo_lock);
		return;
	}
	spin_unlock(&todo_lock);

	addr = get_mac_for_key(key);

	ret = key->local->ops->set_key(local_to_hw(key->local), DISABLE_KEY,
				       key->sdata->dev->dev_addr, addr,
				       &key->conf);

	if (ret)
		printk(KERN_ERR "mac80211-%s: failed to remove key "
		       "(%d, %s) from hardware (%d)\n",
		       wiphy_name(key->local->hw.wiphy),
		       key->conf.keyidx, print_mac(mac, addr), ret);

	spin_lock(&todo_lock);
	key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
	spin_unlock(&todo_lock);
}
Пример #3
0
Файл: key.c Проект: DINKIN/tuo
static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
{
	const u8 *addr;
	int ret;
	DECLARE_MAC_BUF(mac);

	assert_key_lock();
	might_sleep();

	if (!key->local->ops->set_key)
		return;

	addr = get_mac_for_key(key);

	ret = key->local->ops->set_key(local_to_hw(key->local), SET_KEY,
				       key->sdata->dev->dev_addr, addr,
				       &key->conf);

	if (!ret) {
		spin_lock(&todo_lock);
		key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
		spin_unlock(&todo_lock);
	}

	if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP)
		printk(KERN_ERR "mac80211-%s: failed to set key "
		       "(%d, %s) to hardware (%d)\n",
		       wiphy_name(key->local->hw.wiphy),
		       key->conf.keyidx, print_mac(mac, addr), ret);
}
Пример #4
0
static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_sta *sta;
	int ret;

	assert_key_lock();
	might_sleep();

	if (!key->local->ops->set_key)
		return;

	sta = get_sta_for_key(key);

	sdata = key->sdata;
	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
		sdata = container_of(sdata->bss,
				     struct ieee80211_sub_if_data,
				     u.ap);

	ret = drv_set_key(key->local, SET_KEY, &sdata->vif, sta, &key->conf);

	if (!ret) {
		spin_lock(&todo_lock);
		key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
		spin_unlock(&todo_lock);
	}

	if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP)
		printk(KERN_ERR "mac80211-%s: failed to set key "
		       "(%d, %pM) to hardware (%d)\n",
		       wiphy_name(key->local->hw.wiphy),
		       key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
}
Пример #5
0
void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
{
	struct ieee80211_key *key;

	key = container_of(key_conf, struct ieee80211_key, conf);

	might_sleep();
	assert_key_lock(key->local);

	key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;

	synchronize_rcu();
}
Пример #6
0
static void
__ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
{
    struct ieee80211_key *key = NULL;

    assert_key_lock(sdata->local);

    if (idx >= NUM_DEFAULT_KEYS &&
            idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
        key = key_mtx_dereference(sdata->local, sdata->keys[idx]);

    rcu_assign_pointer(sdata->default_mgmt_key, key);

    ieee80211_debugfs_key_update_default(sdata);
}
Пример #7
0
static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
                                        int idx, bool uni, bool multi)
{
    struct ieee80211_key *key = NULL;

    assert_key_lock(sdata->local);

    if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
        key = key_mtx_dereference(sdata->local, sdata->keys[idx]);

    if (uni)
        rcu_assign_pointer(sdata->default_unicast_key, key);
    if (multi)
        rcu_assign_pointer(sdata->default_multicast_key, key);

    ieee80211_debugfs_key_update_default(sdata);
}
Пример #8
0
void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
{
    struct ieee80211_key *key;

    key = container_of(key_conf, struct ieee80211_key, conf);

    might_sleep();
    assert_key_lock(key->local);

    key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;

    /*
     * Flush TX path to avoid attempts to use this key
     * after this function returns. Until then, drivers
     * must be prepared to handle the key.
     */
    synchronize_rcu();
}
Пример #9
0
static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_sta *sta;
	int ret;

	assert_key_lock();
	might_sleep();

	if (!key || !key->local->ops->set_key)
		return;

	spin_lock_bh(&todo_lock);
	if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
		spin_unlock_bh(&todo_lock);
		return;
	}
	spin_unlock_bh(&todo_lock);

	sta = get_sta_for_key(key);
	sdata = key->sdata;

	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
		sdata = container_of(sdata->bss,
				     struct ieee80211_sub_if_data,
				     u.ap);

	ret = drv_set_key(key->local, DISABLE_KEY, &sdata->vif,
			  sta, &key->conf);

	if (ret)
		printk(KERN_ERR "mac80211-%s: failed to remove key "
		       "(%d, %pM) from hardware (%d)\n",
		       wiphy_name(key->local->hw.wiphy),
		       key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);

	spin_lock_bh(&todo_lock);
	key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
	spin_unlock_bh(&todo_lock);
}
Пример #10
0
static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
{
    struct ieee80211_sub_if_data *sdata;
    struct ieee80211_sta *sta;
    int ret;

    might_sleep();

    if (!key || !key->local->ops->set_key)
        return;

    assert_key_lock(key->local);

    if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
        return;

    sta = get_sta_for_key(key);
    sdata = key->sdata;

    if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
            (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
        increment_tailroom_need_count(sdata);

    if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
        sdata = container_of(sdata->bss,
                             struct ieee80211_sub_if_data,
                             u.ap);

    ret = drv_set_key(key->local, DISABLE_KEY, sdata,
                      sta, &key->conf);

    if (ret)
        wiphy_err(key->local->hw.wiphy,
                  "failed to remove key (%d, %pM) from hardware (%d)\n",
                  key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);

    key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
}
Пример #11
0
static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
{
    struct ieee80211_sub_if_data *sdata;
    struct ieee80211_sta *sta;
    int ret;

    might_sleep();

    if (!key->local->ops->set_key)
        goto out_unsupported;

    assert_key_lock(key->local);

    sta = get_sta_for_key(key);

    /*
     * If this is a per-STA GTK, check if it
     * is supported; if not, return.
     */
    if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
            !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
        goto out_unsupported;

    sdata = key->sdata;
    if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
        /*
         * The driver doesn't know anything about VLAN interfaces.
         * Hence, don't send GTKs for VLAN interfaces to the driver.
         */
        if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
            goto out_unsupported;
        sdata = container_of(sdata->bss,
                             struct ieee80211_sub_if_data,
                             u.ap);
    }

    ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);

    if (!ret) {
        key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;

        if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
                (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
            sdata->crypto_tx_tailroom_needed_cnt--;

        return 0;
    }

    if (ret != -ENOSPC && ret != -EOPNOTSUPP)
        wiphy_err(key->local->hw.wiphy,
                  "failed to set key (%d, %pM) to hardware (%d)\n",
                  key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);

out_unsupported:
    switch (key->conf.cipher) {
    case WLAN_CIPHER_SUITE_WEP40:
    case WLAN_CIPHER_SUITE_WEP104:
    case WLAN_CIPHER_SUITE_TKIP:
    case WLAN_CIPHER_SUITE_CCMP:
    case WLAN_CIPHER_SUITE_AES_CMAC:
        /* all of these we can do in software */
        return 0;
    default:
        return -EINVAL;
    }
}
Пример #12
0
static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
{
	struct ieee80211_sub_if_data *sdata;
	struct sta_info *sta;
	int ret;

	might_sleep();

	if (key->flags & KEY_FLAG_TAINTED) {
		/* If we get here, it's during resume and the key is
		 * tainted so shouldn't be used/programmed any more.
		 * However, its flags may still indicate that it was
		 * programmed into the device (since we're in resume)
		 * so clear that flag now to avoid trying to remove
		 * it again later.
		 */
		key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
		return -EINVAL;
	}

	if (!key->local->ops->set_key)
		goto out_unsupported;

	assert_key_lock(key->local);

	sta = key->sta;

	/*
	 * If this is a per-STA GTK, check if it
	 * is supported; if not, return.
	 */
	if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
	    !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
		goto out_unsupported;

	if (sta && !sta->uploaded)
		goto out_unsupported;

	sdata = key->sdata;
	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
		/*
		 * The driver doesn't know anything about VLAN interfaces.
		 * Hence, don't send GTKs for VLAN interfaces to the driver.
		 */
		if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
			goto out_unsupported;
	}

	ret = drv_set_key(key->local, SET_KEY, sdata,
			  sta ? &sta->sta : NULL, &key->conf);

	if (!ret) {
		key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;

		if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
			sdata->crypto_tx_tailroom_needed_cnt--;

		WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
			(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));

		return 0;
	}

	if (ret != -ENOSPC && ret != -EOPNOTSUPP)
		sdata_err(sdata,
			  "failed to set key (%d, %pM) to hardware (%d)\n",
			  key->conf.keyidx,
			  sta ? sta->sta.addr : bcast_addr, ret);

 out_unsupported:
	switch (key->conf.cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
	case WLAN_CIPHER_SUITE_TKIP:
	case WLAN_CIPHER_SUITE_CCMP:
	case WLAN_CIPHER_SUITE_AES_CMAC:
		/* all of these we can do in software */
		return 0;
	default:
		return -EINVAL;
	}
}
Пример #13
0
static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
{
	struct ieee80211_sub_if_data *sdata;
	struct sta_info *sta;
	int ret;

	might_sleep();

	if (!key->local->ops->set_key)
		goto out_unsupported;

	assert_key_lock(key->local);

	sta = key->sta;

	if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
	    !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
		goto out_unsupported;

	if (sta && !sta->uploaded)
		goto out_unsupported;

	sdata = key->sdata;
	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
		if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
			goto out_unsupported;
	}

	ret = drv_set_key(key->local, SET_KEY, sdata,
			  sta ? &sta->sta : NULL, &key->conf);

	if (!ret) {
		key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;

		if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
		      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
		      (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
			sdata->crypto_tx_tailroom_needed_cnt--;

		WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
			(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));

		return 0;
	}

	if (ret != -ENOSPC && ret != -EOPNOTSUPP)
		wiphy_err(key->local->hw.wiphy,
			  "failed to set key (%d, %pM) to hardware (%d)\n",
			  key->conf.keyidx,
			  sta ? sta->sta.addr : bcast_addr, ret);

 out_unsupported:
	switch (key->conf.cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
	case WLAN_CIPHER_SUITE_TKIP:
	case WLAN_CIPHER_SUITE_CCMP:
	case WLAN_CIPHER_SUITE_AES_CMAC:
		
		return 0;
	default:
		return -EINVAL;
	}
}