* [PATCH 0/12] iwlwifi driver updates @ 2008-04-15 4:16 Reinette Chatre 2008-04-15 4:16 ` [PATCH 01/12] iwlwifi: generalize iwlwifi init flow Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre This patch series contains a few iwlwifi driver updates. Patches 3 to 7 introduces support for WEP HW encryption acceleration. It supports default and dynamic keys both PSK and 1X No changes in mac80211 were required. It also reorganizes security related code into a new file iwl-sta.c Please note that patch "iwlwifi: perform bss_info_changed post association work right away" depends on recent mac80211 patch: mac80211: no BSS changes to driver from beacons processed during scanning [PATCH 01/12] iwlwifi: generalize iwlwifi init flow [PATCH 02/12] iwlwifi: replace sprintf with scnprintf for debugfs output [PATCH 03/12] iwlwifi: add default WEP key host command [PATCH 04/12] iwlwifi: default WEP HW encryption [PATCH 05/12] iwlwifi: add 1X HW WEP support [PATCH 06/12] iwlwifi: maintain uCode key table state [PATCH 07/12] iwlwifi: moves security functions to iwl-sta.c [PATCH 08/12] iwlwifi: Fix byte count table for fragmented packets [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous [PATCH 10/12] iwlwifi: make Makefile more concise [PATCH 11/12] iwlwifi: perform bss_info_changed post association work right away [PATCH 12/12] iwlwifi: move shared pointers to iwl_priv Thank you Reinette ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 01/12] iwlwifi: generalize iwlwifi init flow 2008-04-15 4:16 [PATCH 0/12] iwlwifi driver updates Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 02/12] iwlwifi: replace sprintf with scnprintf for debugfs output Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Tomas Winkler, Ron Rindjunsky From: Tomas Winkler <tomas.winkler@intel.com> This patch creates handlers to support iwlwifi init flow for multiple HWs Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com> --- drivers/net/wireless/iwlwifi/iwl-4965.c | 149 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 11 ++- drivers/net/wireless/iwlwifi/iwl4965-base.c | 179 +++------------------------ 3 files changed, 174 insertions(+), 165 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 472ca3d..822169e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -114,6 +114,151 @@ static const u16 default_tid_to_tx_fifo[] = { #endif /*CONFIG_IWL4965_HT */ +/* check contents of special bootstrap uCode SRAM */ +static int iwl4965_verify_bsm(struct iwl_priv *priv) +{ + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + u32 reg; + u32 val; + + IWL_DEBUG_INFO("Begin verify bsm\n"); + + /* verify BSM SRAM contents */ + val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); + for (reg = BSM_SRAM_LOWER_BOUND; + reg < BSM_SRAM_LOWER_BOUND + len; + reg += sizeof(u32), image++) { + val = iwl_read_prph(priv, reg); + if (val != le32_to_cpu(*image)) { + IWL_ERROR("BSM uCode verification failed at " + "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", + BSM_SRAM_LOWER_BOUND, + reg - BSM_SRAM_LOWER_BOUND, len, + val, le32_to_cpu(*image)); + return -EIO; + } + } + + IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n"); + + return 0; +} + +/** + * iwl4965_load_bsm - Load bootstrap instructions + * + * BSM operation: + * + * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program + * in special SRAM that does not power down during RFKILL. When powering back + * up after power-saving sleeps (or during initial uCode load), the BSM loads + * the bootstrap program into the on-board processor, and starts it. + * + * The bootstrap program loads (via DMA) instructions and data for a new + * program from host DRAM locations indicated by the host driver in the + * BSM_DRAM_* registers. Once the new program is loaded, it starts + * automatically. + * + * When initializing the NIC, the host driver points the BSM to the + * "initialize" uCode image. This uCode sets up some internal data, then + * notifies host via "initialize alive" that it is complete. + * + * The host then replaces the BSM_DRAM_* pointer values to point to the + * normal runtime uCode instructions and a backup uCode data cache buffer + * (filled initially with starting data values for the on-board processor), + * then triggers the "initialize" uCode to load and launch the runtime uCode, + * which begins normal operation. + * + * When doing a power-save shutdown, runtime uCode saves data SRAM into + * the backup data cache in DRAM before SRAM is powered down. + * + * When powering back up, the BSM loads the bootstrap program. This reloads + * the runtime uCode instructions and the backup data cache into SRAM, + * and re-launches the runtime uCode from where it left off. + */ +static int iwl4965_load_bsm(struct iwl_priv *priv) +{ + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + dma_addr_t pinst; + dma_addr_t pdata; + u32 inst_len; + u32 data_len; + int i; + u32 done; + u32 reg_offset; + int ret; + + IWL_DEBUG_INFO("Begin load bsm\n"); + + /* make sure bootstrap program is no larger than BSM's SRAM size */ + if (len > IWL_MAX_BSM_SIZE) + return -EINVAL; + + /* Tell bootstrap uCode where to find the "Initialize" uCode + * in host DRAM ... host DRAM physical address bits 35:4 for 4965. + * NOTE: iwl4965_initialize_alive_start() will replace these values, + * after the "initialize" uCode has run, to point to + * runtime/protocol instructions and backup data cache. */ + pinst = priv->ucode_init.p_addr >> 4; + pdata = priv->ucode_init_data.p_addr >> 4; + inst_len = priv->ucode_init.len; + data_len = priv->ucode_init_data.len; + + ret = iwl_grab_nic_access(priv); + if (ret) + return ret; + + iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); + iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); + + /* Fill BSM memory with bootstrap instructions */ + for (reg_offset = BSM_SRAM_LOWER_BOUND; + reg_offset < BSM_SRAM_LOWER_BOUND + len; + reg_offset += sizeof(u32), image++) + _iwl_write_prph(priv, reg_offset, le32_to_cpu(*image)); + + ret = iwl4965_verify_bsm(priv); + if (ret) { + iwl_release_nic_access(priv); + return ret; + } + + /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ + iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); + iwl_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND); + iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); + + /* Load bootstrap code into instruction SRAM now, + * to prepare to load "initialize" uCode */ + iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START); + + /* Wait for load of bootstrap uCode to finish */ + for (i = 0; i < 100; i++) { + done = iwl_read_prph(priv, BSM_WR_CTRL_REG); + if (!(done & BSM_WR_CTRL_REG_BIT_START)) + break; + udelay(10); + } + if (i < 100) + IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); + else { + IWL_ERROR("BSM write did not complete!\n"); + return -EIO; + } + + /* Enable future boot loads whenever power management unit triggers it + * (e.g. when powering back up after power-save shutdown) */ + iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN); + + iwl_release_nic_access(priv); + + return 0; +} + static int iwl4965_init_drv(struct iwl_priv *priv) { int ret; @@ -4789,6 +4934,10 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { static struct iwl_lib_ops iwl4965_lib = { .init_drv = iwl4965_init_drv, + .hw_nic_init = iwl4965_hw_nic_init, + .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, + .alive_notify = iwl4965_alive_notify, + .load_ucode = iwl4965_load_bsm, .eeprom_ops = { .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6d82376..889fdba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -89,9 +89,18 @@ struct iwl_hcmd_utils_ops { struct iwl_lib_ops { /* iwlwifi driver (priv) init */ int (*init_drv)(struct iwl_priv *priv); + /* nic init */ + int (*hw_nic_init)(struct iwl_priv *priv); + /* alive notification */ + int (*alive_notify)(struct iwl_priv *priv); + /* check validity of rtc data address */ + int (*is_valid_rtc_data_addr)(u32 addr); + /* 1st ucode load */ + int (*load_ucode)(struct iwl_priv *priv); + /* rfkill */ + void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio); /* eeprom operations (as defined in iwl-eeprom.h) */ struct iwl_eeprom_ops eeprom_ops; - void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio); }; struct iwl_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 06e44da..ecc9cba 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -4305,7 +4305,7 @@ static void iwl4965_dump_nic_error_log(struct iwl_priv *priv) base = le32_to_cpu(priv->card_alive.error_event_table_ptr); - if (!iwl4965_hw_valid_rtc_data_addr(base)) { + if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { IWL_ERROR("Not valid error log pointer 0x%08X\n", base); return; } @@ -4400,7 +4400,7 @@ static void iwl4965_dump_nic_event_log(struct iwl_priv *priv) u32 size; /* # entries that we'll print */ base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (!iwl4965_hw_valid_rtc_data_addr(base)) { + if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { IWL_ERROR("Invalid event log pointer 0x%08X\n", base); return; } @@ -5175,156 +5175,6 @@ static int iwl4965_verify_ucode(struct iwl_priv *priv) return rc; } - -/* check contents of special bootstrap uCode SRAM */ -static int iwl4965_verify_bsm(struct iwl_priv *priv) -{ - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - u32 reg; - u32 val; - - IWL_DEBUG_INFO("Begin verify bsm\n"); - - /* verify BSM SRAM contents */ - val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); - for (reg = BSM_SRAM_LOWER_BOUND; - reg < BSM_SRAM_LOWER_BOUND + len; - reg += sizeof(u32), image ++) { - val = iwl_read_prph(priv, reg); - if (val != le32_to_cpu(*image)) { - IWL_ERROR("BSM uCode verification failed at " - "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", - BSM_SRAM_LOWER_BOUND, - reg - BSM_SRAM_LOWER_BOUND, len, - val, le32_to_cpu(*image)); - return -EIO; - } - } - - IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n"); - - return 0; -} - -/** - * iwl4965_load_bsm - Load bootstrap instructions - * - * BSM operation: - * - * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program - * in special SRAM that does not power down during RFKILL. When powering back - * up after power-saving sleeps (or during initial uCode load), the BSM loads - * the bootstrap program into the on-board processor, and starts it. - * - * The bootstrap program loads (via DMA) instructions and data for a new - * program from host DRAM locations indicated by the host driver in the - * BSM_DRAM_* registers. Once the new program is loaded, it starts - * automatically. - * - * When initializing the NIC, the host driver points the BSM to the - * "initialize" uCode image. This uCode sets up some internal data, then - * notifies host via "initialize alive" that it is complete. - * - * The host then replaces the BSM_DRAM_* pointer values to point to the - * normal runtime uCode instructions and a backup uCode data cache buffer - * (filled initially with starting data values for the on-board processor), - * then triggers the "initialize" uCode to load and launch the runtime uCode, - * which begins normal operation. - * - * When doing a power-save shutdown, runtime uCode saves data SRAM into - * the backup data cache in DRAM before SRAM is powered down. - * - * When powering back up, the BSM loads the bootstrap program. This reloads - * the runtime uCode instructions and the backup data cache into SRAM, - * and re-launches the runtime uCode from where it left off. - */ -static int iwl4965_load_bsm(struct iwl_priv *priv) -{ - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - dma_addr_t pinst; - dma_addr_t pdata; - u32 inst_len; - u32 data_len; - int rc; - int i; - u32 done; - u32 reg_offset; - - IWL_DEBUG_INFO("Begin load bsm\n"); - - /* make sure bootstrap program is no larger than BSM's SRAM size */ - if (len > IWL_MAX_BSM_SIZE) - return -EINVAL; - - /* Tell bootstrap uCode where to find the "Initialize" uCode - * in host DRAM ... host DRAM physical address bits 35:4 for 4965. - * NOTE: iwl4965_initialize_alive_start() will replace these values, - * after the "initialize" uCode has run, to point to - * runtime/protocol instructions and backup data cache. */ - pinst = priv->ucode_init.p_addr >> 4; - pdata = priv->ucode_init_data.p_addr >> 4; - inst_len = priv->ucode_init.len; - data_len = priv->ucode_init_data.len; - - rc = iwl_grab_nic_access(priv); - if (rc) - return rc; - - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); - - /* Fill BSM memory with bootstrap instructions */ - for (reg_offset = BSM_SRAM_LOWER_BOUND; - reg_offset < BSM_SRAM_LOWER_BOUND + len; - reg_offset += sizeof(u32), image++) - _iwl_write_prph(priv, reg_offset, - le32_to_cpu(*image)); - - rc = iwl4965_verify_bsm(priv); - if (rc) { - iwl_release_nic_access(priv); - return rc; - } - - /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ - iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); - iwl_write_prph(priv, BSM_WR_MEM_DST_REG, - RTC_INST_LOWER_BOUND); - iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); - - /* Load bootstrap code into instruction SRAM now, - * to prepare to load "initialize" uCode */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, - BSM_WR_CTRL_REG_BIT_START); - - /* Wait for load of bootstrap uCode to finish */ - for (i = 0; i < 100; i++) { - done = iwl_read_prph(priv, BSM_WR_CTRL_REG); - if (!(done & BSM_WR_CTRL_REG_BIT_START)) - break; - udelay(10); - } - if (i < 100) - IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); - else { - IWL_ERROR("BSM write did not complete!\n"); - return -EIO; - } - - /* Enable future boot loads whenever power management unit triggers it - * (e.g. when powering back up after power-save shutdown) */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, - BSM_WR_CTRL_REG_BIT_START_EN); - - iwl_release_nic_access(priv); - - return 0; -} - static void iwl4965_nic_start(struct iwl_priv *priv) { /* Remove all resets to allow NIC to operate */ @@ -5634,7 +5484,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv) */ static void iwl4965_alive_start(struct iwl_priv *priv) { - int rc = 0; + int ret = 0; IWL_DEBUG_INFO("Runtime Alive received.\n"); @@ -5657,10 +5507,10 @@ static void iwl4965_alive_start(struct iwl_priv *priv) iwlcore_clear_stations_table(priv); - rc = iwl4965_alive_notify(priv); - if (rc) { + ret = priv->cfg->ops->lib->alive_notify(priv); + if (ret) { IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", - rc); + ret); goto restart; } @@ -5835,7 +5685,8 @@ static void iwl4965_down(struct iwl_priv *priv) static int __iwl4965_up(struct iwl_priv *priv) { - int rc, i; + int i; + int ret; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { IWL_WARNING("Exit pending; will not bring the NIC up\n"); @@ -5870,10 +5721,10 @@ static int __iwl4965_up(struct iwl_priv *priv) iwl_rfkill_set_hw_state(priv); iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - rc = iwl4965_hw_nic_init(priv); - if (rc) { - IWL_ERROR("Unable to int nic\n"); - return rc; + ret = priv->cfg->ops->lib->hw_nic_init(priv); + if (ret) { + IWL_ERROR("Unable to init nic\n"); + return ret; } /* make sure rfkill handshake bits are cleared */ @@ -5906,10 +5757,10 @@ static int __iwl4965_up(struct iwl_priv *priv) /* load bootstrap state machine, * load bootstrap program into processor's memory, * prepare to load the "initialize" uCode */ - rc = iwl4965_load_bsm(priv); + ret = priv->cfg->ops->lib->load_ucode(priv); - if (rc) { - IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc); + if (ret) { + IWL_ERROR("Unable to set up bootstrap uCode: %d\n", ret); continue; } -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 02/12] iwlwifi: replace sprintf with scnprintf for debugfs output 2008-04-15 4:16 ` [PATCH 01/12] iwlwifi: generalize iwlwifi init flow Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 03/12] iwlwifi: add default WEP key host command Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Abhijeet Kolekar, Reinette Chatre From: Abhijeet Kolekar <abhijeet.kolekar@intel.com> The buffersize allocated is not accurate. Writing to these buffers with scnprintf is safer. Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 71 +++++++++++++++++----------- 1 files changed, 43 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 23632e5..cbea477 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -102,10 +102,14 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, struct iwl_priv *priv = (struct iwl_priv *)file->private_data; char buf[256]; int pos = 0; + const size_t bufsz = sizeof(buf); - pos += sprintf(buf+pos, "mgmt: %u\n", priv->tx_stats[0].cnt); - pos += sprintf(buf+pos, "ctrl: %u\n", priv->tx_stats[1].cnt); - pos += sprintf(buf+pos, "data: %u\n", priv->tx_stats[2].cnt); + pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", + priv->tx_stats[0].cnt); + pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", + priv->tx_stats[1].cnt); + pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", + priv->tx_stats[2].cnt); return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -117,10 +121,14 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, struct iwl_priv *priv = (struct iwl_priv *)file->private_data; char buf[256]; int pos = 0; + const size_t bufsz = sizeof(buf); - pos += sprintf(buf+pos, "mgmt: %u\n", priv->rx_stats[0].cnt); - pos += sprintf(buf+pos, "ctrl: %u\n", priv->rx_stats[1].cnt); - pos += sprintf(buf+pos, "data: %u\n", priv->rx_stats[2].cnt); + pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", + priv->rx_stats[0].cnt); + pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", + priv->rx_stats[1].cnt); + pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", + priv->rx_stats[2].cnt); return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -138,6 +146,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, int i; int pos = 0; struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + const size_t bufsz = sizeof(buf); printk(KERN_DEBUG "offset is: 0x%x\tlen is: 0x%x\n", priv->dbgfs->sram_offset, priv->dbgfs->sram_len); @@ -159,9 +168,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, break; } } - pos += sprintf(buf+pos, "0x%08x ", val); + pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); } - pos += sprintf(buf+pos, "\n"); + pos += scnprintf(buf + pos, bufsz - pos, "\n"); iwl_release_nic_access(priv); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); @@ -210,44 +219,50 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, if(!buf) return -ENOMEM; - pos += sprintf(buf+pos, "num of stations: %d\n\n", + pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", priv->num_stations); for (i = 0; i < max_sta; i++) { station = &priv->stations[i]; if (station->used) { - pos += sprintf(buf+pos, "station %d:\ngeneral data:\n", - i+1); + pos += scnprintf(buf + pos, bufsz - pos, + "station %d:\ngeneral data:\n", i+1); print_mac(mac, station->sta.sta.addr); - pos += sprintf(buf+pos, "id: %u\n", + pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n", station->sta.sta.sta_id); - pos += sprintf(buf+pos, "mode: %u\n", + pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n", station->sta.mode); - pos += sprintf(buf+pos, "flags: 0x%x\n", + pos += scnprintf(buf + pos, bufsz - pos, + "flags: 0x%x\n", station->sta.station_flags_msk); - pos += sprintf(buf+pos, "ps_status: %u\n", - station->ps_status); - - pos += sprintf(buf+pos, "tid data:\n"); - - pos += sprintf(buf+pos, "seq_num\t\ttxq_id\t"); - pos += sprintf(buf+pos, "frame_count\twait_for_ba\t"); - pos += sprintf(buf+pos, "start_idx\tbitmap0\t"); - pos += sprintf(buf+pos, "bitmap1\trate_n_flags\n"); + pos += scnprintf(buf + pos, bufsz - pos, + "ps_status: %u\n", station->ps_status); + pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); + pos += scnprintf(buf + pos, bufsz - pos, + "seq_num\t\ttxq_id\t"); + pos += scnprintf(buf + pos, bufsz - pos, + "frame_count\twait_for_ba\t"); + pos += scnprintf(buf + pos, bufsz - pos, + "start_idx\tbitmap0\t"); + pos += scnprintf(buf + pos, bufsz - pos, + "bitmap1\trate_n_flags\n"); for (j = 0; j < MAX_TID_COUNT; j++) { - pos += sprintf(buf+pos, "[%d]:\t\t%u\t", - j, station->tid[j].seq_number); - pos += sprintf(buf+pos, "%u\t\t%u\t\t%u\t\t", + pos += scnprintf(buf + pos, bufsz - pos, + "[%d]:\t\t%u\t", j, + station->tid[j].seq_number); + pos += scnprintf(buf + pos, bufsz - pos, + "%u\t\t%u\t\t%u\t\t", station->tid[j].agg.txq_id, station->tid[j].agg.frame_count, station->tid[j].agg.wait_for_ba); - pos += sprintf(buf+pos, "%u\t%llu\t%u\n", + pos += scnprintf(buf + pos, bufsz - pos, + "%u\t%llu\t%u\n", station->tid[j].agg.start_idx, (unsigned long long)station->tid[j].agg.bitmap, station->tid[j].agg.rate_n_flags); } - pos += sprintf(buf+pos, "\n"); + pos += scnprintf(buf + pos, bufsz - pos, "\n"); } } -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 03/12] iwlwifi: add default WEP key host command 2008-04-15 4:16 ` [PATCH 02/12] iwlwifi: replace sprintf with scnprintf for debugfs output Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 04/12] iwlwifi: default WEP HW encryption Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Emmanuel Grumbach, Tomas Winkler From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> This patch adds declaration for static WEP host command. This command will be used for default WEP group keys when no key mapping keys are used. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> --- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 27 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-hcmd.c | 1 + 2 files changed, 28 insertions(+), 0 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h index 7e36ecb..65cd8ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h @@ -84,6 +84,9 @@ enum { REPLY_REMOVE_STA = 0x19, /* not used */ REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ + /* Security */ + REPLY_WEPKEY = 0x20, + /* RX, TX, LEDs */ REPLY_TX = 0x1c, REPLY_RATE_SCALE = 0x47, /* 3945 only */ @@ -850,6 +853,30 @@ struct iwl4965_add_sta_resp { u8 status; /* ADD_STA_* */ } __attribute__ ((packed)); +/* + * REPLY_WEP_KEY = 0x20 + */ +struct iwl_wep_key { + u8 key_index; + u8 key_offset; + u8 reserved1[2]; + u8 key_size; + u8 reserved2[3]; + u8 key[16]; +} __attribute__ ((packed)); + +struct iwl_wep_cmd { + u8 num_keys; + u8 global_key_type; + u8 flags; + u8 reserved; + struct iwl_wep_key key[0]; +} __attribute__ ((packed)); + +#define WEP_KEY_WEP_TYPE 1 +#define WEP_KEYS_MAX 4 +#define WEP_INVALID_OFFSET 0xff +#define WEP_KEY_LEN_128 13 /****************************************************************************** * (4) diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 1f8c299..fdb27f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -51,6 +51,7 @@ const char *get_cmd_string(u8 cmd) IWL_CMD(REPLY_ADD_STA); IWL_CMD(REPLY_REMOVE_STA); IWL_CMD(REPLY_REMOVE_ALL_STA); + IWL_CMD(REPLY_WEPKEY); IWL_CMD(REPLY_TX); IWL_CMD(REPLY_RATE_SCALE); IWL_CMD(REPLY_LEDS_CMD); -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 04/12] iwlwifi: default WEP HW encryption 2008-04-15 4:16 ` [PATCH 03/12] iwlwifi: add default WEP key host command Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 05/12] iwlwifi: add 1X HW WEP support Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Emmanuel Grumbach, Tomas Winkler From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> This patch adds HW encryption support in default WEP mode. When no key mapping key/pairwise key is used. The key is broadcast key is used as default/global/static key. This code assumes that group cast key is added after pairwise key. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-4965.h | 3 + drivers/net/wireless/iwlwifi/iwl-sta.c | 119 +++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-sta.h | 46 ++++++++++ drivers/net/wireless/iwlwifi/iwl4965-base.c | 90 ++++++++++++--------- 5 files changed, 220 insertions(+), 40 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-sta.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-sta.h diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 2751e8a..741ea34 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -22,5 +22,5 @@ endif obj-$(CONFIG_IWL4965) += iwl4965.o -iwl4965-objs = iwl4965-base.o iwl-4965.o iwl-4965-rs.o +iwl4965-objs = iwl4965-base.o iwl-4965.o iwl-4965-rs.o iwl-sta.o diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 65e5367..93df29e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h @@ -1112,6 +1112,9 @@ struct iwl_priv { spinlock_t sta_lock; int num_stations; struct iwl4965_station_entry stations[IWL_STATION_COUNT]; + struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; + u8 default_wep_key; + u8 key_mapping_key; /* Indication if ieee80211_ops->open has been called */ u8 is_open; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c new file mode 100644 index 0000000..a48e228 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -0,0 +1,119 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * James P. Ketrenos <ipw2100-admin@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include <net/mac80211.h> + +#include "iwl-eeprom.h" +#include "iwl-4965.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-io.h" +#include "iwl-helpers.h" + +int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 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 = REPLY_WEPKEY, + .data = wep_cmd, + .meta.flags = CMD_ASYNC, + }; + + 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 (priv->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 = priv->wep_keys[i].key_size; + memcpy(&wep_cmd->key[i].key[3], priv->wep_keys[i].key, + priv->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 = cmd_size; + + if (not_empty || send_if_empty) + return iwl_send_cmd(priv, &cmd); + else + return 0; +} + +int iwl_remove_default_wep_key(struct iwl_priv *priv, + struct ieee80211_key_conf *key) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->default_wep_key--; + memset(&priv->wep_keys[key->keyidx], 0, sizeof(priv->wep_keys[0])); + ret = iwl_send_static_wepkey_cmd(priv, 1); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} + +int iwl_set_default_wep_key(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf) +{ + int ret; + unsigned long flags; + + keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->hw_key_idx = keyconf->keyidx; + priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->default_wep_key++; + + priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; + memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, + keyconf->keylen); + + ret = iwl_send_static_wepkey_cmd(priv, 0); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} + diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h new file mode 100644 index 0000000..50e9f14 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * James P. Ketrenos <ipw2100-admin@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ +#ifndef __iwl_sta_h__ +#define __iwl_sta_h__ + +#include <net/mac80211.h> + +#include "iwl-eeprom.h" +#include "iwl-core.h" +#include "iwl-4965.h" +#include "iwl-io.h" +#include "iwl-helpers.h" + +int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty); +int iwl_remove_default_wep_key(struct iwl_priv *priv, + struct ieee80211_key_conf *key); +int iwl_set_default_wep_key(struct iwl_priv *priv, + struct ieee80211_key_conf *key); + +#endif /* __iwl_sta_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index ecc9cba..dfd2b75 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -50,6 +50,7 @@ #include "iwl-core.h" #include "iwl-io.h" #include "iwl-helpers.h" +#include "iwl-sta.h" static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); @@ -941,6 +942,9 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) return -EIO; } priv->assoc_station_added = 1; + if (priv->default_wep_key && + iwl_send_static_wepkey_cmd(priv, 0)) + IWL_ERROR("Could not send WEP static key.\n"); } return 0; @@ -1180,6 +1184,8 @@ static int iwl4965_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) { unsigned long flags; + priv->key_mapping_key = 0; + spin_lock_irqsave(&priv->sta_lock, flags); memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key)); memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo)); @@ -1198,6 +1204,8 @@ static int iwl4965_set_dynamic_key(struct iwl_priv *priv, { int ret; + priv->key_mapping_key = 1; + switch (key->alg) { case ALG_CCMP: ret = iwl4965_set_ccmp_dynamic_key_info(priv, key, sta_id); @@ -1216,23 +1224,6 @@ static int iwl4965_set_dynamic_key(struct iwl_priv *priv, return ret; } -static int iwl4965_remove_static_key(struct iwl_priv *priv) -{ - int ret = -EOPNOTSUPP; - - return ret; -} - -static int iwl4965_set_static_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key) -{ - if (key->alg == ALG_WEP) - return -EOPNOTSUPP; - - IWL_ERROR("Static key invalid: alg %d\n", key->alg); - return -EINVAL; -} - static void iwl4965_clear_free_frames(struct iwl_priv *priv) { struct list_head *element; @@ -2115,6 +2106,10 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv, int sta_id) { struct iwl4965_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; + struct iwl_wep_key *wepkey; + int keyidx = 0; + + BUG_ON(ctl->key_idx > 3); switch (keyinfo->alg) { case ALG_CCMP: @@ -2133,16 +2128,24 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv, break; case ALG_WEP: - cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP | - (ctl->key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; - - if (keyinfo->keylen == 13) - cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; + wepkey = &priv->wep_keys[ctl->key_idx]; + cmd->cmd.tx.sec_ctl = 0; + if (priv->default_wep_key) { + /* the WEP key was sent as static */ + keyidx = ctl->key_idx; + memcpy(&cmd->cmd.tx.key[3], wepkey->key, + wepkey->key_size); + if (wepkey->key_size == WEP_KEY_LEN_128) + cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; + } else { + IWL_ERROR("No support for WEP key mappings key\n"); + } - memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen); + cmd->cmd.tx.sec_ctl |= (TX_CMD_SEC_WEP | + (keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT); IWL_DEBUG_TX("Configuring packet for WEP encryption " - "with key %d\n", ctl->key_idx); + "with key %d\n", keyidx); break; default: @@ -6989,7 +6992,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, DECLARE_MAC_BUF(mac); int ret = 0; u8 sta_id = IWL_INVALID_STATION; - u8 static_key; + u8 is_default_wep_key = 0; IWL_DEBUG_MAC80211("enter\n"); @@ -7002,33 +7005,42 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, /* only support pairwise keys */ return -EOPNOTSUPP; - /* FIXME: need to differenciate between static and dynamic key - * in the level of mac80211 */ - static_key = !iwl_is_associated(priv); + sta_id = iwl4965_hw_find_station(priv, addr); + if (sta_id == IWL_INVALID_STATION) { + IWL_DEBUG_MAC80211("leave - %s not in station map.\n", + print_mac(mac, addr)); + return -EINVAL; - if (!static_key) { - sta_id = iwl4965_hw_find_station(priv, addr); - if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_MAC80211("leave - %s not in station map.\n", - print_mac(mac, addr)); - return -EINVAL; - } } + mutex_lock(&priv->mutex); iwl4965_scan_cancel_timeout(priv, 100); + mutex_unlock(&priv->mutex); + + /* If we are getting WEP group key and we didn't receive any key mapping + * so far, we are in legacy wep mode (group key only), otherwise we are + * in 1X mode. + * In legacy wep mode, we use another host command to the uCode */ + if (key->alg == ALG_WEP && sta_id == priv->hw_setting.bcast_sta_id && + priv->iw_mode != IEEE80211_IF_TYPE_AP) { + if (cmd == SET_KEY) + is_default_wep_key = !priv->key_mapping_key; + else + is_default_wep_key = priv->default_wep_key; + } switch (cmd) { case SET_KEY: - if (static_key) - ret = iwl4965_set_static_key(priv, key); + if (is_default_wep_key) + ret = iwl_set_default_wep_key(priv, key); else ret = iwl4965_set_dynamic_key(priv, key, sta_id); IWL_DEBUG_MAC80211("enable hwcrypto key\n"); break; case DISABLE_KEY: - if (static_key) - ret = iwl4965_remove_static_key(priv); + if (is_default_wep_key) + ret = iwl_remove_default_wep_key(priv, key); else ret = iwl4965_clear_sta_key_info(priv, sta_id); -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 05/12] iwlwifi: add 1X HW WEP support 2008-04-15 4:16 ` [PATCH 04/12] iwlwifi: default WEP HW encryption Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 06/12] iwlwifi: maintain uCode key table state Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Emmanuel Grumbach, Tomas Winkler From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> This patch adds support for HW encryption/decryption in 1X WEP. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> --- drivers/net/wireless/iwlwifi/iwl-4965.h | 1 + drivers/net/wireless/iwlwifi/iwl-sta.c | 47 +++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-sta.h | 3 ++ drivers/net/wireless/iwlwifi/iwl4965-base.c | 9 ++++- 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 93df29e..23ab523 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h @@ -461,6 +461,7 @@ struct iwl4965_tid_data { struct iwl4965_hw_key { enum ieee80211_key_alg alg; int keylen; + u8 keyidx; struct ieee80211_key_conf *conf; u8 key[32]; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index a48e228..cb96419 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -35,6 +35,7 @@ #include "iwl-sta.h" #include "iwl-io.h" #include "iwl-helpers.h" +#include "iwl-4965.h" int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) { @@ -117,3 +118,49 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, return ret; } +int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + int ret; + + keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->hw_key_idx = keyconf->keyidx; + + key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (keyconf->keylen == WEP_KEY_LEN_128) + key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; + + if (sta_id == priv->hw_setting.bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].keyinfo.alg = keyconf->alg; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx; + + memcpy(priv->stations[sta_id].keyinfo.key, + keyconf->key, keyconf->keylen); + + memcpy(&priv->stations[sta_id].sta.key.key[3], + keyconf->key, keyconf->keylen); + + priv->stations[sta_id].sta.key.key_offset = sta_id % 8; /* FIXME */ + priv->stations[sta_id].sta.key.key_flags = key_flags; + + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + ret = iwl4965_send_add_station(priv, + &priv->stations[sta_id].sta, CMD_ASYNC); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 50e9f14..78e0254 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -42,5 +42,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, struct ieee80211_key_conf *key); int iwl_set_default_wep_key(struct iwl_priv *priv, struct ieee80211_key_conf *key); +int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id); #endif /* __iwl_sta_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index dfd2b75..37ab1c5 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -1214,7 +1214,7 @@ static int iwl4965_set_dynamic_key(struct iwl_priv *priv, ret = iwl4965_set_tkip_dynamic_key_info(priv, key, sta_id); break; case ALG_WEP: - ret = -EOPNOTSUPP; + ret = iwl_set_wep_dynamic_key_info(priv, key, sta_id); break; default: IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg); @@ -2138,7 +2138,12 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv, if (wepkey->key_size == WEP_KEY_LEN_128) cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; } else { - IWL_ERROR("No support for WEP key mappings key\n"); + /* the WEP key was sent as dynamic */ + keyidx = keyinfo->keyidx; + memcpy(&cmd->cmd.tx.key[3], keyinfo->key, + keyinfo->keylen); + if (keyinfo->keylen == WEP_KEY_LEN_128) + cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; } cmd->cmd.tx.sec_ctl |= (TX_CMD_SEC_WEP | -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 06/12] iwlwifi: maintain uCode key table state 2008-04-15 4:16 ` [PATCH 05/12] iwlwifi: add 1X HW WEP support Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 07/12] iwlwifi: moves security functions to iwl-sta.c Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Emmanuel Grumbach, Tomas Winkler From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> This patch fix book keeping of key table in the driver to be synchronized with uCode Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> --- drivers/net/wireless/iwlwifi/iwl-4965.h | 1 + drivers/net/wireless/iwlwifi/iwl-sta.c | 28 ++++++++++++++++++++++++-- drivers/net/wireless/iwlwifi/iwl-sta.h | 1 + drivers/net/wireless/iwlwifi/iwl4965-base.c | 10 ++++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 23ab523..daf157a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h @@ -1116,6 +1116,7 @@ struct iwl_priv { struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; u8 default_wep_key; u8 key_mapping_key; + unsigned long ucode_key_table; /* Indication if ieee80211_ops->open has been called */ u8 is_open; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index cb96419..41238f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -36,6 +36,18 @@ #include "iwl-io.h" #include "iwl-helpers.h" #include "iwl-4965.h" +#include "iwl-sta.h" + +int iwl_get_free_ucode_key_index(struct iwl_priv *priv) +{ + int i; + + for (i = 0; i < STA_KEY_MAX_NUM; i++) + if (test_and_set_bit(i, &priv->ucode_key_table)) + return i; + + return -1; +} int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) { @@ -81,14 +93,19 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) } int iwl_remove_default_wep_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key) + struct ieee80211_key_conf *keyconf) { int ret; unsigned long flags; spin_lock_irqsave(&priv->sta_lock, flags); + + if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table)) + IWL_ERROR("index %d not used in uCode key table.\n", + keyconf->keyidx); + priv->default_wep_key--; - memset(&priv->wep_keys[key->keyidx], 0, sizeof(priv->wep_keys[0])); + memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); ret = iwl_send_static_wepkey_cmd(priv, 1); spin_unlock_irqrestore(&priv->sta_lock, flags); @@ -108,6 +125,10 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, spin_lock_irqsave(&priv->sta_lock, flags); priv->default_wep_key++; + if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table)) + IWL_ERROR("index %d already used in uCode key table.\n", + keyconf->keyidx); + priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, keyconf->keylen); @@ -151,7 +172,8 @@ int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, memcpy(&priv->stations[sta_id].sta.key.key[3], keyconf->key, keyconf->keylen); - priv->stations[sta_id].sta.key.key_offset = sta_id % 8; /* FIXME */ + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); priv->stations[sta_id].sta.key.key_flags = key_flags; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 78e0254..3f1b205 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -37,6 +37,7 @@ #include "iwl-io.h" #include "iwl-helpers.h" +int iwl_get_free_ucode_key_index(struct iwl_priv *priv); int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty); int iwl_remove_default_wep_key(struct iwl_priv *priv, struct ieee80211_key_conf *key); diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 37ab1c5..da01896 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -1140,8 +1140,8 @@ static int iwl4965_set_ccmp_dynamic_key_info(struct iwl_priv *priv, memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, keyconf->keylen); - priv->stations[sta_id].sta.key.key_offset - = (sta_id % STA_KEY_MAX_NUM);/*FIXME*/ + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); priv->stations[sta_id].sta.key.key_flags = key_flags; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; @@ -1187,6 +1187,10 @@ static int iwl4965_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) priv->key_mapping_key = 0; spin_lock_irqsave(&priv->sta_lock, flags); + if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, + &priv->ucode_key_table)) + IWL_ERROR("index %d not used in uCode key table.\n", + priv->stations[sta_id].sta.key.key_offset); memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key)); memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo)); priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; @@ -6971,7 +6975,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, spin_lock_irqsave(&priv->sta_lock, flags); priv->stations[sta_id].sta.key.key_offset = - (sta_id % STA_KEY_MAX_NUM);/* FIXME */ + iwl_get_free_ucode_key_index(priv); priv->stations[sta_id].sta.key.key_flags = key_flags; priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 07/12] iwlwifi: moves security functions to iwl-sta.c 2008-04-15 4:16 ` [PATCH 06/12] iwlwifi: maintain uCode key table state Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 08/12] iwlwifi: Fix byte count table for fragmented packets Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Emmanuel Grumbach, Tomas Winkler From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> This patch moves security related functions to iwl-sta.c. Note that iwl4965_mac_update_tkip_key is still in iwl4965-base.c since it is a mac80211 handler. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> --- drivers/net/wireless/iwlwifi/iwl-sta.c | 119 ++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-sta.h | 7 +- drivers/net/wireless/iwlwifi/iwl4965-base.c | 120 +-------------------------- 3 files changed, 123 insertions(+), 123 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 41238f2..8765358 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -139,7 +139,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, return ret; } -int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, +static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, struct ieee80211_key_conf *keyconf, u8 sta_id) { @@ -186,3 +186,120 @@ int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, return ret; } + +static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + + key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (sta_id == priv->hw_setting.bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->hw_key_idx = keyconf->keyidx; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].keyinfo.alg = keyconf->alg; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, + keyconf->keylen); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, + keyconf->keylen); + + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); + priv->stations[sta_id].sta.key.key_flags = key_flags; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + spin_unlock_irqrestore(&priv->sta_lock, flags); + + IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); + return iwl4965_send_add_station(priv, + &priv->stations[sta_id].sta, CMD_ASYNC); +} + +static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + int ret = 0; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + keyconf->hw_key_idx = keyconf->keyidx; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].keyinfo.alg = keyconf->alg; + priv->stations[sta_id].keyinfo.conf = keyconf; + priv->stations[sta_id].keyinfo.keylen = 16; + + /* This copy is acutally not needed: we get the key with each TX */ + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} + +int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id) +{ + unsigned long flags; + + priv->key_mapping_key = 0; + + spin_lock_irqsave(&priv->sta_lock, flags); + if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, + &priv->ucode_key_table)) + IWL_ERROR("index %d not used in uCode key table.\n", + priv->stations[sta_id].sta.key.key_offset); + memset(&priv->stations[sta_id].keyinfo, 0, + sizeof(struct iwl4965_hw_key)); + memset(&priv->stations[sta_id].sta.key, 0, + sizeof(struct iwl4965_keyinfo)); + priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); + return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0); +} + +int iwl_set_dynamic_key(struct iwl_priv *priv, + struct ieee80211_key_conf *key, u8 sta_id) +{ + int ret; + + priv->key_mapping_key = 1; + + switch (key->alg) { + case ALG_CCMP: + ret = iwl_set_ccmp_dynamic_key_info(priv, key, sta_id); + break; + case ALG_TKIP: + ret = iwl_set_tkip_dynamic_key_info(priv, key, sta_id); + break; + case ALG_WEP: + ret = iwl_set_wep_dynamic_key_info(priv, key, sta_id); + break; + default: + IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg); + ret = -EINVAL; + } + + return ret; +} + diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 3f1b205..44f272e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -43,8 +43,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, struct ieee80211_key_conf *key); int iwl_set_default_wep_key(struct iwl_priv *priv, struct ieee80211_key_conf *key); -int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id); - +int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id); +int iwl_set_dynamic_key(struct iwl_priv *priv, + struct ieee80211_key_conf *key, u8 sta_id); #endif /* __iwl_sta_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index da01896..bfefb05 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -1112,122 +1112,6 @@ int iwl4965_send_add_station(struct iwl_priv *priv, return rc; } -static int iwl4965_set_ccmp_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - __le16 key_flags = 0; - - key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - - if (sta_id == priv->hw_setting.bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - keyconf->hw_key_idx = keyconf->keyidx; - - key_flags &= ~STA_KEY_FLG_INVALID; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.alg = keyconf->alg; - priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; - - memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, - keyconf->keylen); - - memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, - keyconf->keylen); - - priv->stations[sta_id].sta.key.key_offset = - iwl_get_free_ucode_key_index(priv); - priv->stations[sta_id].sta.key.key_flags = key_flags; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - spin_unlock_irqrestore(&priv->sta_lock, flags); - - IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); - return iwl4965_send_add_station(priv, - &priv->stations[sta_id].sta, CMD_ASYNC); -} - -static int iwl4965_set_tkip_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - int ret = 0; - - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - keyconf->hw_key_idx = keyconf->keyidx; - - spin_lock_irqsave(&priv->sta_lock, flags); - - priv->stations[sta_id].keyinfo.alg = keyconf->alg; - priv->stations[sta_id].keyinfo.conf = keyconf; - priv->stations[sta_id].keyinfo.keylen = 16; - - /* This copy is acutally not needed: we get the key with each TX */ - memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); - - memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16); - - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return ret; -} - -static int iwl4965_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) -{ - unsigned long flags; - - priv->key_mapping_key = 0; - - spin_lock_irqsave(&priv->sta_lock, flags); - if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, - &priv->ucode_key_table)) - IWL_ERROR("index %d not used in uCode key table.\n", - priv->stations[sta_id].sta.key.key_offset); - memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key)); - memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo)); - priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); - iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0); - return 0; -} - -static int iwl4965_set_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key, u8 sta_id) -{ - int ret; - - priv->key_mapping_key = 1; - - switch (key->alg) { - case ALG_CCMP: - ret = iwl4965_set_ccmp_dynamic_key_info(priv, key, sta_id); - break; - case ALG_TKIP: - ret = iwl4965_set_tkip_dynamic_key_info(priv, key, sta_id); - break; - case ALG_WEP: - ret = iwl_set_wep_dynamic_key_info(priv, key, sta_id); - break; - default: - IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg); - ret = -EINVAL; - } - - return ret; -} - static void iwl4965_clear_free_frames(struct iwl_priv *priv) { struct list_head *element; @@ -7043,7 +6927,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (is_default_wep_key) ret = iwl_set_default_wep_key(priv, key); else - ret = iwl4965_set_dynamic_key(priv, key, sta_id); + ret = iwl_set_dynamic_key(priv, key, sta_id); IWL_DEBUG_MAC80211("enable hwcrypto key\n"); break; @@ -7051,7 +6935,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (is_default_wep_key) ret = iwl_remove_default_wep_key(priv, key); else - ret = iwl4965_clear_sta_key_info(priv, sta_id); + ret = iwl_remove_dynamic_key(priv, sta_id); IWL_DEBUG_MAC80211("disable hwcrypto key\n"); break; -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 08/12] iwlwifi: Fix byte count table for fragmented packets 2008-04-15 4:16 ` [PATCH 07/12] iwlwifi: moves security functions to iwl-sta.c Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Tomas Winkler, Reinette Chatre From: Tomas Winkler <tomas.winkler@intel.com> This patch fix byte count table update. Table must be updated for each fragment Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> --- drivers/net/wireless/iwlwifi/iwl-4965.c | 13 +++++-------- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ++++ drivers/net/wireless/iwlwifi/iwl4965-base.c | 6 +++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 822169e..04fed5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -3141,18 +3141,16 @@ static void iwl4965_hw_card_show_info(struct iwl_priv *priv) #define IWL_TX_DELIMITER_SIZE 4 /** - * iwl4965_tx_queue_update_wr_ptr - Set up entry in Tx byte-count array + * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ -int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, u16 byte_cnt) +static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, + struct iwl4965_tx_queue *txq, + u16 byte_cnt) { int len; int txq_id = txq->q.id; struct iwl4965_shared *shared_data = priv->hw_setting.shared_virt; - if (txq->need_update == 0) - return 0; - len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; /* Set up byte count within first 256 entries */ @@ -3164,8 +3162,6 @@ int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. tfd_offset[IWL4965_QUEUE_SIZE + txq->q.write_ptr], byte_cnt, len); - - return 0; } /** @@ -4934,6 +4930,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { static struct iwl_lib_ops iwl4965_lib = { .init_drv = iwl4965_init_drv, + .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, .hw_nic_init = iwl4965_hw_nic_init, .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, .alive_notify = iwl4965_alive_notify, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 889fdba..23c21e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -89,6 +89,10 @@ struct iwl_hcmd_utils_ops { struct iwl_lib_ops { /* iwlwifi driver (priv) init */ int (*init_drv)(struct iwl_priv *priv); + + void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, + struct iwl4965_tx_queue *txq, + u16 byte_cnt); /* nic init */ int (*hw_nic_init)(struct iwl_priv *priv); /* alive notification */ diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index bfefb05..60c0b83 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -575,11 +575,11 @@ int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) txq->need_update = 1; /* Set up entry in queue's byte count circular buffer */ - ret = iwl4965_tx_queue_update_wr_ptr(priv, txq, 0); + priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0); /* Increment and update queue's write index */ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); - iwl4965_tx_queue_update_write_ptr(priv, txq); + ret = iwl4965_tx_queue_update_write_ptr(priv, txq); spin_unlock_irqrestore(&priv->hcmd_lock, flags); return ret ? ret : idx; @@ -2392,7 +2392,7 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, ieee80211_get_hdrlen(fc)); /* Set up entry for this TFD in Tx byte-count array */ - iwl4965_tx_queue_update_wr_ptr(priv, txq, len); + priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len); /* Tell device the write index *just past* this latest filled TFD */ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous 2008-04-15 4:16 ` [PATCH 08/12] iwlwifi: Fix byte count table for fragmented packets Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 10/12] iwlwifi: make Makefile more concise Reinette Chatre 2008-04-15 16:17 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous Pavel Roskin 0 siblings, 2 replies; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Acked-by: Tomas Winkler <tomas.winkler@intel.com> --- drivers/net/wireless/iwlwifi/iwl4965-base.c | 27 ++++++--------------------- 1 files changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 60c0b83..9fb9857 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -758,15 +758,8 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) { - int rc = 0; - struct iwl4965_rx_packet *res = NULL; + int ret = 0; struct iwl4965_rxon_assoc_cmd rxon_assoc; - struct iwl_host_cmd cmd = { - .id = REPLY_RXON_ASSOC, - .len = sizeof(rxon_assoc), - .meta.flags = CMD_WANT_SKB, - .data = &rxon_assoc, - }; const struct iwl4965_rxon_cmd *rxon1 = &priv->staging_rxon; const struct iwl4965_rxon_cmd *rxon2 = &priv->active_rxon; @@ -794,20 +787,12 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; - rc = iwl_send_cmd_sync(priv, &cmd); - if (rc) - return rc; - - res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; - if (res->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n"); - rc = -EIO; - } - - priv->alloc_rxb_skb--; - dev_kfree_skb_any(cmd.meta.u.skb); + ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, + sizeof(rxon_assoc), &rxon_assoc, NULL); + if (ret) + return ret; - return rc; + return ret; } /** -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 10/12] iwlwifi: make Makefile more concise 2008-04-15 4:16 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 11/12] iwlwifi: perform bss_info_changed post association work right away Reinette Chatre 2008-04-15 16:17 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous Pavel Roskin 1 sibling, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre Also change CONFIG_IWLCORE_RFKILL to CONFIG_IWLWIFI_RFKILL to be more consistent with other config variables. Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Acked-by: Tomas Winkler <tomas.winkler@intel.com> --- drivers/net/wireless/iwlwifi/Kconfig | 2 +- drivers/net/wireless/iwlwifi/Makefile | 29 ++++++++--------------------- drivers/net/wireless/iwlwifi/iwl-4965.h | 2 +- drivers/net/wireless/iwlwifi/iwl-rfkill.h | 2 +- 4 files changed, 11 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index bcaa61b..f844b73 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -6,7 +6,7 @@ config IWLWIFI_LEDS bool default n -config IWLCORE_RFKILL +config IWLWIFI_RFKILL boolean "IWLWIFI RF kill support" depends on IWLCORE select RFKILL diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 741ea34..4f3e88b 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,26 +1,13 @@ -obj-$(CONFIG_IWLCORE) += iwlcore.o -iwlcore-objs = iwl-core.o iwl-eeprom.o iwl-hcmd.o - -ifeq ($(CONFIG_IWLWIFI_DEBUGFS),y) - iwlcore-objs += iwl-debugfs.o -endif - -ifeq ($(CONFIG_IWLWIFI_LEDS),y) - iwlcore-objs += iwl-led.o -endif - -ifeq ($(CONFIG_IWLCORE_RFKILL),y) - iwlcore-objs += iwl-rfkill.o -endif +obj-$(CONFIG_IWLCORE) := iwlcore.o +iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o +iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o +iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o +iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o obj-$(CONFIG_IWL3945) += iwl3945.o -iwl3945-objs = iwl3945-base.o iwl-3945.o iwl-3945-rs.o - -ifeq ($(CONFIG_IWL3945_LEDS),y) - iwl3945-objs += iwl-3945-led.o -endif - +iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o +iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o obj-$(CONFIG_IWL4965) += iwl4965.o -iwl4965-objs = iwl4965-base.o iwl-4965.o iwl-4965-rs.o iwl-sta.o +iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o iwl-sta.o diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index daf157a..17c4bcf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h @@ -1034,7 +1034,7 @@ struct iwl_priv { * 4965's initialize alive response contains some calibration data. */ struct iwl4965_init_alive_resp card_alive_init; struct iwl4965_alive_resp card_alive; -#ifdef CONFIG_IWLCORE_RFKILL +#ifdef CONFIG_IWLWIFI_RFKILL struct iwl_rfkill_mngr rfkill_mngr; #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h index e7aa51a..a7f04b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h @@ -34,7 +34,7 @@ struct iwl_priv; #include <linux/input.h> -#ifdef CONFIG_IWLCORE_RFKILL +#ifdef CONFIG_IWLWIFI_RFKILL struct iwl_rfkill_mngr { struct rfkill *rfkill; struct input_dev *input_dev; -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 11/12] iwlwifi: perform bss_info_changed post association work right away 2008-04-15 4:16 ` [PATCH 10/12] iwlwifi: make Makefile more concise Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 2008-04-15 4:16 ` [PATCH 12/12] iwlwifi: move shared pointers to iwl_priv Reinette Chatre 0 siblings, 1 reply; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre Do not use workqueue for bss_info_changed post association work. When driver is notified of association the upper layer will be notified right after that the association is complete. Doing the post association work in a workqueue introduces a race condition where the upper layer may want to make use of the association, but it is not yet complete. Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Acked-by: Tomas Winkler <tomas.winkler@intel.com> --- This patch depends on "mac80211: no BSS changes to driver from beacons processed during scanning" drivers/net/wireless/iwlwifi/iwl4965-base.c | 31 +++++++++++++++++++------- 1 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 9fb9857..1f34340 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -1840,7 +1840,7 @@ static void iwl4965_set_flags_for_phymode(struct iwl_priv *priv, | RXON_FLG_CCK_MSK); priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; } else { - /* Copied from iwl4965_bg_post_associate() */ + /* Copied from iwl4965_post_associate() */ if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; else @@ -6004,10 +6004,8 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data) #define IWL_DELAY_NEXT_SCAN (HZ*2) -static void iwl4965_bg_post_associate(struct work_struct *data) +static void iwl4965_post_associate(struct iwl_priv *priv) { - struct iwl_priv *priv = container_of(data, struct iwl_priv, - post_associate.work); struct ieee80211_conf *conf = NULL; int ret = 0; DECLARE_MAC_BUF(mac); @@ -6025,12 +6023,10 @@ static void iwl4965_bg_post_associate(struct work_struct *data) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - mutex_lock(&priv->mutex); - if (!priv->vif || !priv->is_open) { - mutex_unlock(&priv->mutex); + if (!priv->vif || !priv->is_open) return; - } + iwl4965_scan_cancel_timeout(priv, 200); conf = ieee80211_get_hw_conf(priv->hw); @@ -6114,7 +6110,18 @@ static void iwl4965_bg_post_associate(struct work_struct *data) /* we have just associated, don't start scan too early */ priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; +} + + +static void iwl4965_bg_post_associate(struct work_struct *data) +{ + struct iwl_priv *priv = container_of(data, struct iwl_priv, + post_associate.work); + + mutex_lock(&priv->mutex); + iwl4965_post_associate(priv); mutex_unlock(&priv->mutex); + } static void iwl4965_bg_abort_scan(struct work_struct *work) @@ -6736,6 +6743,10 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, if (changes & BSS_CHANGED_ASSOC) { IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc); + /* This should never happen as this function should + * never be called from interrupt context. */ + if (WARN_ON_ONCE(in_interrupt())) + return; if (bss_conf->assoc) { priv->assoc_id = bss_conf->aid; priv->beacon_int = bss_conf->beacon_int; @@ -6743,7 +6754,9 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, priv->assoc_capability = bss_conf->assoc_capability; priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; - queue_work(priv->workqueue, &priv->post_associate.work); + mutex_lock(&priv->mutex); + iwl4965_post_associate(priv); + mutex_unlock(&priv->mutex); } else { priv->assoc_id = 0; IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc); -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 12/12] iwlwifi: move shared pointers to iwl_priv 2008-04-15 4:16 ` [PATCH 11/12] iwlwifi: perform bss_info_changed post association work right away Reinette Chatre @ 2008-04-15 4:16 ` Reinette Chatre 0 siblings, 0 replies; 17+ messages in thread From: Reinette Chatre @ 2008-04-15 4:16 UTC (permalink / raw) To: linville; +Cc: linux-wireless, ipw3945-devel, Tomas Winkler, Reinette Chatre From: Tomas Winkler <tomas.winkler@intel.com> This patch moves shared memory structure to iwl_priv Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> --- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 12 +++--- drivers/net/wireless/iwlwifi/iwl-4965.c | 55 ++++++++++++-------------- drivers/net/wireless/iwlwifi/iwl-4965.h | 11 +++-- drivers/net/wireless/iwlwifi/iwl4965-base.c | 6 +- 4 files changed, 40 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index de7bac1..3d098da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h @@ -1554,29 +1554,29 @@ struct iwl4965_sched_queue_byte_cnt_tbl { struct iwl4965_shared { struct iwl4965_sched_queue_byte_cnt_tbl queues_byte_cnt_tbls[IWL_MAX_NUM_QUEUES]; - __le32 val0; + __le32 rb_closed; /* __le32 rb_closed_stts_rb_num:12; */ #define IWL_rb_closed_stts_rb_num_POS 0 #define IWL_rb_closed_stts_rb_num_LEN 12 -#define IWL_rb_closed_stts_rb_num_SYM val0 +#define IWL_rb_closed_stts_rb_num_SYM rb_closed /* __le32 rsrv1:4; */ /* __le32 rb_closed_stts_rx_frame_num:12; */ #define IWL_rb_closed_stts_rx_frame_num_POS 16 #define IWL_rb_closed_stts_rx_frame_num_LEN 12 -#define IWL_rb_closed_stts_rx_frame_num_SYM val0 +#define IWL_rb_closed_stts_rx_frame_num_SYM rb_closed /* __le32 rsrv2:4; */ - __le32 val1; + __le32 frm_finished; /* __le32 frame_finished_stts_rb_num:12; */ #define IWL_frame_finished_stts_rb_num_POS 0 #define IWL_frame_finished_stts_rb_num_LEN 12 -#define IWL_frame_finished_stts_rb_num_SYM val1 +#define IWL_frame_finished_stts_rb_num_SYM frm_finished /* __le32 rsrv3:4; */ /* __le32 frame_finished_stts_rx_frame_num:12; */ #define IWL_frame_finished_stts_rx_frame_num_POS 16 #define IWL_frame_finished_stts_rx_frame_num_LEN 12 -#define IWL_frame_finished_stts_rx_frame_num_SYM val1 +#define IWL_frame_finished_stts_rx_frame_num_SYM frm_finished /* __le32 rsrv4:4; */ __le32 padding1; /* so that allocation will be aligned to 16B */ diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 04fed5e..a10a6e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -274,6 +274,18 @@ static int iwl4965_init_drv(struct iwl_priv *priv) spin_lock_init(&priv->hcmd_lock); spin_lock_init(&priv->lq_mngr.lock); + priv->shared_virt = pci_alloc_consistent(priv->pci_dev, + sizeof(struct iwl4965_shared), + &priv->shared_phys); + + if (!priv->shared_virt) { + ret = -ENOMEM; + goto err; + } + + memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared)); + + for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); @@ -546,15 +558,15 @@ static int iwl4965_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max) static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) { - int rc; + int ret; unsigned long flags; unsigned int rb_size; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_nic_access(priv); - if (rc) { + ret = iwl_grab_nic_access(priv); + if (ret) { spin_unlock_irqrestore(&priv->lock, flags); - return rc; + return ret; } if (priv->cfg->mod_params->amsdu_size_8K) @@ -574,15 +586,15 @@ static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) /* Tell device where in DRAM to update its Rx status */ iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, - (priv->hw_setting.shared_phys + - offsetof(struct iwl4965_shared, val0)) >> 4); + (priv->shared_phys + + offsetof(struct iwl4965_shared, rb_closed)) >> 4); /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | rb_size | - /*0x10 << 4 | */ + /* 0x10 << 4 | */ (RX_QUEUE_SIZE_LOG << FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); @@ -1966,7 +1978,7 @@ int iwl4965_alive_notify(struct iwl_priv *priv) /* Tel 4965 where to find Tx byte count tables */ iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, - (priv->hw_setting.shared_phys + + (priv->shared_phys + offsetof(struct iwl4965_shared, queues_byte_cnt_tbls)) >> 10); /* Disable chain mode for all queues */ @@ -2024,29 +2036,14 @@ int iwl4965_alive_notify(struct iwl_priv *priv) */ int iwl4965_hw_set_hw_setting(struct iwl_priv *priv) { - int ret = 0; if ((priv->cfg->mod_params->num_of_queues > IWL_MAX_NUM_QUEUES) || (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { IWL_ERROR("invalid queues_num, should be between %d and %d\n", IWL_MIN_NUM_QUEUES, IWL_MAX_NUM_QUEUES); - ret = -EINVAL; - goto out; - } - - /* Allocate area for Tx byte count tables and Rx queue status */ - priv->hw_setting.shared_virt = - pci_alloc_consistent(priv->pci_dev, - sizeof(struct iwl4965_shared), - &priv->hw_setting.shared_phys); - - if (!priv->hw_setting.shared_virt) { - ret = -ENOMEM; - goto out; + return -EINVAL; } - memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl4965_shared)); - priv->hw_setting.max_txq_num = priv->cfg->mod_params->num_of_queues; priv->hw_setting.tx_cmd_len = sizeof(struct iwl4965_tx_cmd); priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE; @@ -2061,8 +2058,7 @@ int iwl4965_hw_set_hw_setting(struct iwl_priv *priv) priv->hw_setting.tx_ant_num = 2; -out: - return ret; + return 0; } /** @@ -3014,9 +3010,8 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, int iwl4965_hw_get_rx_read(struct iwl_priv *priv) { - struct iwl4965_shared *shared_data = priv->hw_setting.shared_virt; - - return IWL_GET_BITS(*shared_data, rb_closed_stts_rb_num); + struct iwl4965_shared *s = priv->shared_virt; + return le32_to_cpu(s->rb_closed) & 0xFFF; } int iwl4965_hw_get_temperature(struct iwl_priv *priv) @@ -3149,7 +3144,7 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, { int len; int txq_id = txq->q.id; - struct iwl4965_shared *shared_data = priv->hw_setting.shared_virt; + struct iwl4965_shared *shared_data = priv->shared_virt; len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 17c4bcf..e5ab4c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h @@ -576,8 +576,6 @@ struct iwl4965_ibss_seq { * @max_rxq_log: Log-base-2 of max_rxq_size * @max_stations: * @bcast_sta_id: - * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status - * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status */ struct iwl4965_driver_hw_info { u16 max_txq_num; @@ -589,8 +587,6 @@ struct iwl4965_driver_hw_info { u16 max_rxq_log; u8 max_stations; u8 bcast_sta_id; - void *shared_virt; - dma_addr_t shared_phys; }; #define HT_SHORT_GI_20MHZ_ONLY (1 << 0) @@ -1147,9 +1143,14 @@ struct iwl_priv { /* Last Rx'd beacon timestamp */ u64 timestamp; u16 beacon_int; - struct iwl4965_driver_hw_info hw_setting; struct ieee80211_vif *vif; + struct iwl4965_driver_hw_info hw_setting; + /* driver/uCode shared Tx Byte Counts and Rx status */ + void *shared_virt; + /* Physical Pointer to Tx Byte Counts and Rx status */ + dma_addr_t shared_phys; + /* Current association information needed to configure the * hardware */ u16 assoc_id; diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 1f34340..5ec0af4 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -1219,11 +1219,11 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) static void iwl4965_unset_hw_setting(struct iwl_priv *priv) { - if (priv->hw_setting.shared_virt) + if (priv->shared_virt) pci_free_consistent(priv->pci_dev, sizeof(struct iwl4965_shared), - priv->hw_setting.shared_virt, - priv->hw_setting.shared_phys); + priv->shared_virt, + priv->shared_phys); } /** -- 1.5.3.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous 2008-04-15 4:16 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous Reinette Chatre 2008-04-15 4:16 ` [PATCH 10/12] iwlwifi: make Makefile more concise Reinette Chatre @ 2008-04-15 16:17 ` Pavel Roskin 2008-04-15 16:22 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assocasynchronous Chatre, Reinette 1 sibling, 1 reply; 17+ messages in thread From: Pavel Roskin @ 2008-04-15 16:17 UTC (permalink / raw) To: Reinette Chatre; +Cc: linville, linux-wireless, ipw3945-devel On Mon, 2008-04-14 at 21:16 -0700, Reinette Chatre wrote: > Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> > Acked-by: Tomas Winkler <tomas.winkler@intel.com> > --- > drivers/net/wireless/iwlwifi/iwl4965-base.c | 27 ++++++--------------------- > 1 files changed, 6 insertions(+), 21 deletions(-) > > diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c > index 60c0b83..9fb9857 100644 > --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c > +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c > @@ -758,15 +758,8 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) > > static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) Wrong patch description. Please swap 5 and 6 :-) -- Regards, Pavel Roskin ^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assocasynchronous 2008-04-15 16:17 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous Pavel Roskin @ 2008-04-15 16:22 ` Chatre, Reinette 2008-04-15 16:35 ` Pavel Roskin 0 siblings, 1 reply; 17+ messages in thread From: Chatre, Reinette @ 2008-04-15 16:22 UTC (permalink / raw) To: Pavel Roskin; +Cc: linville, linux-wireless, ipw3945-devel On Tuesday, April 15, 2008 9:17 AM, Pavel Roskin wrote: > On Mon, 2008-04-14 at 21:16 -0700, Reinette Chatre wrote: >> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> >> Acked-by: Tomas Winkler <tomas.winkler@intel.com> >> --- >> drivers/net/wireless/iwlwifi/iwl4965-base.c | 27 >> ++++++--------------------- 1 files changed, 6 insertions(+), 21 >> deletions(-) >> >> diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c > b/drivers/net/wireless/iwlwifi/iwl4965-base.c >> index 60c0b83..9fb9857 100644 >> --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c >> +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c >> @@ -758,15 +758,8 @@ static int > iwl4965_full_rxon_required(struct iwl_priv *priv) >> >> static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) > > Wrong patch description. Please swap 5 and 6 :-) Sorry - I do not understand your comment. Could you please elaborate? Thanks Reinette ^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assocasynchronous 2008-04-15 16:22 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assocasynchronous Chatre, Reinette @ 2008-04-15 16:35 ` Pavel Roskin 2008-04-15 16:38 ` Chatre, Reinette 0 siblings, 1 reply; 17+ messages in thread From: Pavel Roskin @ 2008-04-15 16:35 UTC (permalink / raw) To: Chatre, Reinette; +Cc: linville, linux-wireless, ipw3945-devel On Tue, 2008-04-15 at 09:22 -0700, Chatre, Reinette wrote: > >> static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) > > > > Wrong patch description. Please swap 5 and 6 :-) > > Sorry - I do not understand your comment. Could you please elaborate? The subject was: iwl4965: make iwl4956_send_rxon_assoc asynchronous (you also lost a space in this reply, but it was there) It should be: iwl4965: make iwl4965_send_rxon_assoc asynchronous In other words, replace 4956 with 4965 in the subject. I hope John can do it while applying. -- Regards, Pavel Roskin ^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assocasynchronous 2008-04-15 16:35 ` Pavel Roskin @ 2008-04-15 16:38 ` Chatre, Reinette 0 siblings, 0 replies; 17+ messages in thread From: Chatre, Reinette @ 2008-04-15 16:38 UTC (permalink / raw) To: Pavel Roskin; +Cc: linville, linux-wireless, ipw3945-devel On Tuesday, April 15, 2008 9:35 AM, Pavel Roskin wrote: > On Tue, 2008-04-15 at 09:22 -0700, Chatre, Reinette wrote: >>>> static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) >>> >>> Wrong patch description. Please swap 5 and 6 :-) >> >> Sorry - I do not understand your comment. Could you please elaborate? > > The subject was: > iwl4965: make iwl4956_send_rxon_assoc asynchronous > (you also lost a space in this reply, but it was there) > > It should be: > iwl4965: make iwl4965_send_rxon_assoc asynchronous > > In other words, replace 4956 with 4965 in the subject. I hope John > can do it while applying. oh no - great catch. John, could you please fix the typo in the patch description when you apply this one? Thank you very much Reinette ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2008-04-15 16:38 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-04-15 4:16 [PATCH 0/12] iwlwifi driver updates Reinette Chatre 2008-04-15 4:16 ` [PATCH 01/12] iwlwifi: generalize iwlwifi init flow Reinette Chatre 2008-04-15 4:16 ` [PATCH 02/12] iwlwifi: replace sprintf with scnprintf for debugfs output Reinette Chatre 2008-04-15 4:16 ` [PATCH 03/12] iwlwifi: add default WEP key host command Reinette Chatre 2008-04-15 4:16 ` [PATCH 04/12] iwlwifi: default WEP HW encryption Reinette Chatre 2008-04-15 4:16 ` [PATCH 05/12] iwlwifi: add 1X HW WEP support Reinette Chatre 2008-04-15 4:16 ` [PATCH 06/12] iwlwifi: maintain uCode key table state Reinette Chatre 2008-04-15 4:16 ` [PATCH 07/12] iwlwifi: moves security functions to iwl-sta.c Reinette Chatre 2008-04-15 4:16 ` [PATCH 08/12] iwlwifi: Fix byte count table for fragmented packets Reinette Chatre 2008-04-15 4:16 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous Reinette Chatre 2008-04-15 4:16 ` [PATCH 10/12] iwlwifi: make Makefile more concise Reinette Chatre 2008-04-15 4:16 ` [PATCH 11/12] iwlwifi: perform bss_info_changed post association work right away Reinette Chatre 2008-04-15 4:16 ` [PATCH 12/12] iwlwifi: move shared pointers to iwl_priv Reinette Chatre 2008-04-15 16:17 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assoc asynchronous Pavel Roskin 2008-04-15 16:22 ` [PATCH 09/12] iwl4965: make iwl4956_send_rxon_assocasynchronous Chatre, Reinette 2008-04-15 16:35 ` Pavel Roskin 2008-04-15 16:38 ` Chatre, Reinette
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).