Skip to content

Commit

Permalink
iwlagn: move context init after firmware loading
Browse files Browse the repository at this point in the history
The availability of contexts depends on the
firmware capabilities. Currently only the
presence of the second context depends on it,
but soon P2P support will also be different.
Move the context initialisation code to the
firmware-dependent setup before registering
with mac80211 to make it easier to handle.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Aug 8, 2011
1 parent ca9a460 commit 4d2a5d0
Showing 1 changed file with 89 additions and 92 deletions.
181 changes: 89 additions & 92 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,85 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
return 0;
}

static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
{
static const u8 iwlagn_bss_ac_to_fifo[] = {
IWL_TX_FIFO_VO,
IWL_TX_FIFO_VI,
IWL_TX_FIFO_BE,
IWL_TX_FIFO_BK,
};
static const u8 iwlagn_bss_ac_to_queue[] = {
0, 1, 2, 3,
};
static const u8 iwlagn_pan_ac_to_fifo[] = {
IWL_TX_FIFO_VO_IPAN,
IWL_TX_FIFO_VI_IPAN,
IWL_TX_FIFO_BE_IPAN,
IWL_TX_FIFO_BK_IPAN,
};
static const u8 iwlagn_pan_ac_to_queue[] = {
7, 6, 5, 4,
};
int i;

/*
* The default context is always valid,
* the PAN context depends on uCode.
*/
priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)
priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);

for (i = 0; i < NUM_IWL_RXON_CTX; i++)
priv->contexts[i].ctxid = i;

priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
BIT(NL80211_IFTYPE_ADHOC);
priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
BIT(NL80211_IFTYPE_STATION);
priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;

priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd =
REPLY_WIPAN_RXON_TIMING;
priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd =
REPLY_WIPAN_RXON_ASSOC;
priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM;
priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN;
priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
#ifdef CONFIG_IWL_P2P
priv->contexts[IWL_RXON_CTX_PAN].interface_modes |=
BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO);
#endif
priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;

BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
}


struct iwlagn_ucode_capabilities {
u32 max_probe_length;
u32 standard_phy_calibration_size;
Expand Down Expand Up @@ -1152,17 +1231,16 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
priv->new_scan_threshold_behaviour =
!!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);

if ((priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE) &&
(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) {
priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
} else
priv->sta_key_max_num = STA_KEY_MAX_NUM;
if (!(priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE))
ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;

if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
else
} else {
priv->sta_key_max_num = STA_KEY_MAX_NUM;
priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
}

/*
* figure out the offset of chain noise reset and gain commands
Expand All @@ -1178,6 +1256,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
priv->phy_calib_chain_noise_gain_cmd =
ucode_capa.standard_phy_calibration_size + 1;

/* initialize all valid contexts */
iwl_init_context(priv, ucode_capa.flags);

/**************************************************
* This is still part of probe() in a sense...
*
Expand Down Expand Up @@ -3528,28 +3609,6 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
return priv->cfg->lib->set_hw_params(priv);
}

static const u8 iwlagn_bss_ac_to_fifo[] = {
IWL_TX_FIFO_VO,
IWL_TX_FIFO_VI,
IWL_TX_FIFO_BE,
IWL_TX_FIFO_BK,
};

static const u8 iwlagn_bss_ac_to_queue[] = {
0, 1, 2, 3,
};

static const u8 iwlagn_pan_ac_to_fifo[] = {
IWL_TX_FIFO_VO_IPAN,
IWL_TX_FIFO_VI_IPAN,
IWL_TX_FIFO_BE_IPAN,
IWL_TX_FIFO_BK_IPAN,
};

static const u8 iwlagn_pan_ac_to_queue[] = {
7, 6, 5, 4,
};

/* This function both allocates and initializes hw and priv. */
static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
{
Expand All @@ -3572,65 +3631,6 @@ static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
return hw;
}

static void iwl_init_context(struct iwl_priv *priv)
{
int i;

/*
* The default context is always valid,
* more may be discovered when firmware
* is loaded.
*/
priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);

for (i = 0; i < NUM_IWL_RXON_CTX; i++)
priv->contexts[i].ctxid = i;

priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
BIT(NL80211_IFTYPE_ADHOC);
priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
BIT(NL80211_IFTYPE_STATION);
priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;

priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd =
REPLY_WIPAN_RXON_TIMING;
priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd =
REPLY_WIPAN_RXON_ASSOC;
priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM;
priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN;
priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
#ifdef CONFIG_IWL_P2P
priv->contexts[IWL_RXON_CTX_PAN].interface_modes |=
BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO);
#endif
priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;

BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
}

int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
{
int err = 0;
Expand Down Expand Up @@ -3733,9 +3733,6 @@ int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
priv->hw->wiphy->n_addresses++;
}

/* initialize all valid contexts */
iwl_init_context(priv);

/************************
* 5. Setup HW constants
************************/
Expand Down

0 comments on commit 4d2a5d0

Please sign in to comment.