My apologies. This is the V2 patch despite the subject. On Fri, Nov 12, 2010 at 5:23 PM, Brian Cavagnolo <brian@xxxxxxxxxxx> wrote: > The mwl8k can operate in AP or STA mode, depending on the > firmware image that is loaded. By default, STA firmware is > loaded. Allow the user to override this default mode at > module load time. This saves an unnecessary firmware reload > for users only interested in AP mode. > > Also, the firmware image can be swapped to meet the user's > add_interface request. For example, suppose the STA > firmware is loaded, no STA interface has been added, and the > user adds an AP interface. In this case, the AP firmware > will be loaded to meet the request. > > Based on contributions from Pradeep Nemavat <pnemavat@xxxxxxxxxxx>, > Yogesh Powar <yogeshp@xxxxxxxxxxx>, and > Lennert Buytenhek <buytenh@xxxxxxxxxxxxxx>. > > Signed-off-by: Brian Cavagnolo <brian@xxxxxxxxxxx> > --- > drivers/net/wireless/mwl8k.c | 78 +++++++++++++++++++++++++++++++++++------ > 1 files changed, 66 insertions(+), 12 deletions(-) > > diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c > index 7bd8615..cbf7271 100644 > --- a/drivers/net/wireless/mwl8k.c > +++ b/drivers/net/wireless/mwl8k.c > @@ -29,6 +29,12 @@ > #define MWL8K_NAME KBUILD_MODNAME > #define MWL8K_VERSION "0.12" > > +/* Module parameters */ > +static unsigned ap_mode_default; > +module_param(ap_mode_default, bool, 0); > +MODULE_PARM_DESC(ap_mode_default, > + "Set to 1 to make ap mode the default instead of sta mode"); > + > /* Register definitions */ > #define MWL8K_HIU_GEN_PTR 0x00000c10 > #define MWL8K_MODE_STA 0x0000005a > @@ -92,7 +98,8 @@ struct rxd_ops { > struct mwl8k_device_info { > char *part_name; > char *helper_image; > - char *fw_image; > + char *fw_image_sta; > + char *fw_image_ap; > struct rxd_ops *ap_rxd_ops; > }; > > @@ -210,6 +217,12 @@ struct mwl8k_priv { > > /* Most recently reported noise in dBm */ > s8 noise; > + > + /* > + * preserve the queue configurations so they can be restored if/when > + * the firmware image is swapped. > + */ > + struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES]; > }; > > /* Per interface specific private data */ > @@ -401,7 +414,7 @@ static int mwl8k_request_fw(struct mwl8k_priv *priv, > fname, &priv->pdev->dev); > } > > -static int mwl8k_request_firmware(struct mwl8k_priv *priv) > +static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image) > { > struct mwl8k_device_info *di = priv->device_info; > int rc; > @@ -416,10 +429,10 @@ static int mwl8k_request_firmware(struct mwl8k_priv *priv) > } > } > > - rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw_ucode); > + rc = mwl8k_request_fw(priv, fw_image, &priv->fw_ucode); > if (rc) { > printk(KERN_ERR "%s: Error requesting firmware file %s\n", > - pci_name(priv->pdev), di->fw_image); > + pci_name(priv->pdev), fw_image); > mwl8k_release_fw(&priv->fw_helper); > return rc; > } > @@ -3345,13 +3358,16 @@ static void mwl8k_stop(struct ieee80211_hw *hw) > mwl8k_txq_reclaim(hw, i, INT_MAX, 1); > } > > +static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image); > + > static int mwl8k_add_interface(struct ieee80211_hw *hw, > struct ieee80211_vif *vif) > { > struct mwl8k_priv *priv = hw->priv; > struct mwl8k_vif *mwl8k_vif; > u32 macids_supported; > - int macid; > + int macid, rc; > + struct mwl8k_device_info *di; > > /* > * Reject interface creation if sniffer mode is active, as > @@ -3364,12 +3380,28 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw, > return -EINVAL; > } > > - > + di = priv->device_info; > switch (vif->type) { > case NL80211_IFTYPE_AP: > + if (!priv->ap_fw && di->fw_image_ap) { > + /* we must load the ap fw to meet this request */ > + if (!list_empty(&priv->vif_list)) > + return -EBUSY; > + rc = mwl8k_reload_firmware(hw, di->fw_image_ap); > + if (rc) > + return rc; > + } > macids_supported = priv->ap_macids_supported; > break; > case NL80211_IFTYPE_STATION: > + if (priv->ap_fw && di->fw_image_sta) { > + /* we must load the sta fw to meet this request */ > + if (!list_empty(&priv->vif_list)) > + return -EBUSY; > + rc = mwl8k_reload_firmware(hw, di->fw_image_sta); > + if (rc) > + return rc; > + } > macids_supported = priv->sta_macids_supported; > break; > default: > @@ -3805,6 +3837,9 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, > > rc = mwl8k_fw_lock(hw); > if (!rc) { > + BUG_ON(queue > MWL8K_TX_QUEUES - 1); > + memcpy(&priv->wmm_params[queue], params, sizeof(*params)); > + > if (!priv->wmm_enabled) > rc = mwl8k_cmd_set_wmm_mode(hw, 1); > > @@ -3908,17 +3943,18 @@ static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { > [MWL8363] = { > .part_name = "88w8363", > .helper_image = "mwl8k/helper_8363.fw", > - .fw_image = "mwl8k/fmimage_8363.fw", > + .fw_image_sta = "mwl8k/fmimage_8363.fw", > }, > [MWL8687] = { > .part_name = "88w8687", > .helper_image = "mwl8k/helper_8687.fw", > - .fw_image = "mwl8k/fmimage_8687.fw", > + .fw_image_sta = "mwl8k/fmimage_8687.fw", > }, > [MWL8366] = { > .part_name = "88w8366", > .helper_image = "mwl8k/helper_8366.fw", > - .fw_image = "mwl8k/fmimage_8366.fw", > + .fw_image_sta = "mwl8k/fmimage_8366.fw", > + .fw_image_ap = "mwl8k/fmimage_8366_ap-1.fw", > .ap_rxd_ops = &rxd_8366_ap_ops, > }, > }; > @@ -3929,6 +3965,7 @@ MODULE_FIRMWARE("mwl8k/helper_8687.fw"); > MODULE_FIRMWARE("mwl8k/fmimage_8687.fw"); > MODULE_FIRMWARE("mwl8k/helper_8366.fw"); > MODULE_FIRMWARE("mwl8k/fmimage_8366.fw"); > +MODULE_FIRMWARE("mwl8k/fmimage_8366_ap-1.fw"); > > static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { > { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, > @@ -3942,7 +3979,7 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { > }; > MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); > > -static int mwl8k_init_firmware(struct ieee80211_hw *hw) > +static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image) > { > struct mwl8k_priv *priv = hw->priv; > int rc; > @@ -3951,7 +3988,7 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw) > mwl8k_hw_reset(priv); > > /* Ask userland hotplug daemon for the device firmware */ > - rc = mwl8k_request_firmware(priv); > + rc = mwl8k_request_firmware(priv, fw_image); > if (rc) { > wiphy_err(hw->wiphy, "Firmware files not found\n"); > return rc; > @@ -4207,6 +4244,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, > static int printed_version; > struct ieee80211_hw *hw; > struct mwl8k_priv *priv; > + struct mwl8k_device_info *di; > int rc; > > if (!printed_version) { > @@ -4267,7 +4305,23 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, > } > } > > - rc = mwl8k_init_firmware(hw); > + /* > + * Choose the initial fw image depending on user input and availability > + * of images. > + */ > + di = priv->device_info; > + if (ap_mode_default && di->fw_image_ap) > + rc = mwl8k_init_firmware(hw, di->fw_image_ap); > + else if (!ap_mode_default && di->fw_image_sta) > + rc = mwl8k_init_firmware(hw, di->fw_image_sta); > + else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) { > + printk(KERN_WARNING "AP fw is unavailable. Using STA fw."); > + rc = mwl8k_init_firmware(hw, di->fw_image_sta); > + } else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) { > + printk(KERN_WARNING "STA fw is unavailable. Using AP fw."); > + rc = mwl8k_init_firmware(hw, di->fw_image_ap); > + } else > + rc = mwl8k_init_firmware(hw, di->fw_image_sta); > if (rc) > goto err_stop_firmware; > > -- > 1.7.1.1 > > -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html