return wlcore_set_key(wl, cmd, vif, sta, key_conf);
 }
 
+static int wl12xx_setup(struct wl1271 *wl);
+
 static struct wlcore_ops wl12xx_ops = {
+       .setup                  = wl12xx_setup,
        .identify_chip          = wl12xx_identify_chip,
        .identify_fw            = wl12xx_identify_fw,
        .boot                   = wl12xx_boot,
                },
 };
 
-static int __devinit wl12xx_probe(struct platform_device *pdev)
+static int wl12xx_setup(struct wl1271 *wl)
 {
-       struct wl12xx_platform_data *pdata = pdev->dev.platform_data;
-       struct wl1271 *wl;
-       struct ieee80211_hw *hw;
-       struct wl12xx_priv *priv;
-
-       hw = wlcore_alloc_hw(sizeof(*priv), WL12XX_AGGR_BUFFER_SIZE);
-       if (IS_ERR(hw)) {
-               wl1271_error("can't allocate hw");
-               return PTR_ERR(hw);
-       }
+       struct wl12xx_priv *priv = wl->priv;
+       struct wl12xx_platform_data *pdata = wl->pdev->dev.platform_data;
 
-       wl = hw->priv;
-       priv = wl->priv;
-       wl->ops = &wl12xx_ops;
-       wl->ptable = wl12xx_ptable;
        wl->rtable = wl12xx_rtable;
        wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
        wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
                        wl1271_error("Invalid tcxo parameter %s", tcxo_param);
        }
 
-       return wlcore_probe(wl, pdev);
+       return 0;
+}
+
+static int __devinit wl12xx_probe(struct platform_device *pdev)
+{
+       struct wl1271 *wl;
+       struct ieee80211_hw *hw;
+       int ret;
+
+       hw = wlcore_alloc_hw(sizeof(struct wl12xx_priv),
+                            WL12XX_AGGR_BUFFER_SIZE);
+       if (IS_ERR(hw)) {
+               wl1271_error("can't allocate hw");
+               ret = PTR_ERR(hw);
+               goto out;
+       }
+
+       wl = hw->priv;
+       wl->ops = &wl12xx_ops;
+       wl->ptable = wl12xx_ptable;
+       ret = wlcore_probe(wl, pdev);
+       if (ret)
+               goto out_free;
+
+       return ret;
+
+out_free:
+       wlcore_free_hw(wl);
+out:
+       return ret;
 }
 
 static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
 
        return buf_offset;
 }
 
+static int wl18xx_setup(struct wl1271 *wl);
+
 static struct wlcore_ops wl18xx_ops = {
+       .setup          = wl18xx_setup,
        .identify_chip  = wl18xx_identify_chip,
        .boot           = wl18xx_boot,
        .plt_init       = wl18xx_plt_init,
                },
 };
 
-static int __devinit wl18xx_probe(struct platform_device *pdev)
+static int wl18xx_setup(struct wl1271 *wl)
 {
-       struct wl1271 *wl;
-       struct ieee80211_hw *hw;
-       struct wl18xx_priv *priv;
+       struct wl18xx_priv *priv = wl->priv;
        int ret;
 
-       hw = wlcore_alloc_hw(sizeof(*priv), WL18XX_AGGR_BUFFER_SIZE);
-       if (IS_ERR(hw)) {
-               wl1271_error("can't allocate hw");
-               ret = PTR_ERR(hw);
-               goto out;
-       }
-
-       wl = hw->priv;
-       priv = wl->priv;
-       wl->ops = &wl18xx_ops;
-       wl->ptable = wl18xx_ptable;
        wl->rtable = wl18xx_rtable;
        wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
        wl->num_rx_desc = WL18XX_NUM_TX_DESCRIPTORS;
        if (num_rx_desc_param != -1)
                wl->num_rx_desc = num_rx_desc_param;
 
-       ret = wl18xx_conf_init(wl, &pdev->dev);
+       ret = wl18xx_conf_init(wl, wl->dev);
        if (ret < 0)
-               goto out_free;
+               return ret;
 
        /* If the module param is set, update it in conf */
        if (board_type_param) {
                } else {
                        wl1271_error("invalid board type '%s'",
                                board_type_param);
-                       ret = -EINVAL;
-                       goto out_free;
+                       return -EINVAL;
                }
        }
 
        if (priv->conf.phy.board_type >= NUM_BOARD_TYPES) {
                wl1271_error("invalid board type '%d'",
                        priv->conf.phy.board_type);
-               ret = -EINVAL;
-               goto out_free;
+               return -EINVAL;
        }
 
        if (low_band_component_param != -1)
                        priv->conf.ht.mode = HT_MODE_SISO20;
                else {
                        wl1271_error("invalid ht_mode '%s'", ht_mode_param);
-                       ret = -EINVAL;
-                       goto out_free;
+                       return -EINVAL;
                }
        }
 
        /* Enable 11a Band only if we have 5G antennas */
        wl->enable_11a = (priv->conf.phy.number_of_assembled_ant5 != 0);
 
-       return wlcore_probe(wl, pdev);
+       return 0;
+}
+
+static int __devinit wl18xx_probe(struct platform_device *pdev)
+{
+       struct wl1271 *wl;
+       struct ieee80211_hw *hw;
+       int ret;
+
+       hw = wlcore_alloc_hw(sizeof(struct wl18xx_priv),
+                            WL18XX_AGGR_BUFFER_SIZE);
+       if (IS_ERR(hw)) {
+               wl1271_error("can't allocate hw");
+               ret = PTR_ERR(hw);
+               goto out;
+       }
+
+       wl = hw->priv;
+       wl->ops = &wl18xx_ops;
+       wl->ptable = wl18xx_ptable;
+       ret = wlcore_probe(wl, pdev);
+       if (ret)
+               goto out_free;
+
+       return ret;
 
 out_free:
        wlcore_free_hw(wl);
 
 
        if (!wl->ops || !wl->ptable) {
                ret = -EINVAL;
-               goto out_free_hw;
+               goto out;
        }
 
+       wl->dev = &pdev->dev;
+       wl->pdev = pdev;
+       platform_set_drvdata(pdev, wl);
+
+       ret = wl->ops->setup(wl);
+       if (ret < 0)
+               goto out;
+
        BUG_ON(wl->num_tx_desc > WLCORE_MAX_TX_DESCRIPTORS);
 
        /* adjust some runtime configuration parameters */
        wl->irq = platform_get_irq(pdev, 0);
        wl->platform_quirks = pdata->platform_quirks;
        wl->set_power = pdata->set_power;
-       wl->dev = &pdev->dev;
        wl->if_ops = pdata->ops;
 
-       platform_set_drvdata(pdev, wl);
-
        if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
                irqflags = IRQF_TRIGGER_RISING;
        else
                                   pdev->name, wl);
        if (ret < 0) {
                wl1271_error("request_irq() failed: %d", ret);
-               goto out_free_hw;
+               goto out;
        }
 
 #ifdef CONFIG_PM
 out_irq:
        free_irq(wl->irq, wl);
 
-out_free_hw:
-       wlcore_free_hw(wl);
-
 out:
        return ret;
 }
 
 struct wl1271_rx_descriptor;
 
 struct wlcore_ops {
+       int (*setup)(struct wl1271 *wl);
        int (*identify_chip)(struct wl1271 *wl);
        int (*identify_fw)(struct wl1271 *wl);
        int (*boot)(struct wl1271 *wl);
        bool mac80211_registered;
 
        struct device *dev;
+       struct platform_device *pdev;
 
        void *if_priv;