static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
				      struct iwl_rxon_context *ctx,
				      bool send_if_empty)
{
	int i, not_empty = 0;
	u8 buff[sizeof(struct iwl_wep_cmd) +
		sizeof(struct iwl_wep_key) * WEP_KEYS_MAX];
	struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
	size_t cmd_size  = sizeof(struct iwl_wep_cmd);
	struct iwl_host_cmd cmd = {
		.id = ctx->wep_key_cmd,
		.data = { wep_cmd, },
		.flags = CMD_SYNC,
	};

	might_sleep();

	memset(wep_cmd, 0, cmd_size +
			(sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));

	for (i = 0; i < WEP_KEYS_MAX ; i++) {
		wep_cmd->key[i].key_index = i;
		if (ctx->wep_keys[i].key_size) {
			wep_cmd->key[i].key_offset = i;
			not_empty = 1;
		} else {
			wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
		}

		wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
		memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
				ctx->wep_keys[i].key_size);
	}

	wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
	wep_cmd->num_keys = WEP_KEYS_MAX;

	cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;

	cmd.len[0] = cmd_size;

	if (not_empty || send_if_empty)
		return trans_send_cmd(&priv->trans, &cmd);
	else
		return 0;
}

int iwl_restore_default_wep_keys(struct iwl_priv *priv,
				 struct iwl_rxon_context *ctx)
{
	lockdep_assert_held(&priv->mutex);

	return iwl_send_static_wepkey_cmd(priv, ctx, false);
}
예제 #2
0
static int iwl_send_scan_abort(struct iwl_priv *priv)
{
    int ret;
    struct iwl_rx_packet *pkt;
    struct iwl_host_cmd cmd = {
        .id = REPLY_SCAN_ABORT_CMD,
        .flags = CMD_SYNC | CMD_WANT_SKB,
    };

    /* Exit instantly with error when device is not ready
     * to receive scan abort command or it does not perform
     * hardware scan currently */
    if (!test_bit(STATUS_READY, &priv->status) ||
            !test_bit(STATUS_GEO_CONFIGURED, &priv->status) ||
            !test_bit(STATUS_SCAN_HW, &priv->status) ||
            test_bit(STATUS_FW_ERROR, &priv->status) ||
            test_bit(STATUS_EXIT_PENDING, &priv->status))
        return -EIO;

    ret = trans_send_cmd(&priv->trans, &cmd);
    if (ret)
        return ret;

    pkt = (struct iwl_rx_packet *)cmd.reply_page;
    if (pkt->u.status != CAN_ABORT_STATUS) {
        /* The scan abort will return 1 for success or
         * 2 for "failure".  A failure condition can be
         * due to simply not being in an active scan which
         * can occur if we send the scan abort before we
         * the microcode has notified us that a scan is
         * completed. */
        IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
        ret = -EIO;
    }

    iwl_free_pages(priv, cmd.reply_page);
    return ret;
}

static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
{
    /* check if scan was requested from mac80211 */
    if (priv->scan_request) {
        IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n");
        ieee80211_scan_completed(priv->hw, aborted);
    }

    priv->scan_type = IWL_SCAN_NORMAL;
    priv->scan_vif = NULL;
    priv->scan_request = NULL;
}

void iwl_force_scan_end(struct iwl_priv *priv)
{
    lockdep_assert_held(&priv->mutex);

    if (!test_bit(STATUS_SCANNING, &priv->status)) {
        IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n");
        return;
    }

    IWL_DEBUG_SCAN(priv, "Forcing scan end\n");
    clear_bit(STATUS_SCANNING, &priv->status);
    clear_bit(STATUS_SCAN_HW, &priv->status);
    clear_bit(STATUS_SCAN_ABORTING, &priv->status);
    iwl_complete_scan(priv, true);
}