--- /dev/null
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ *
+ * 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.GPL.
+ *
+ * Contact Information:
+ * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __iwl_3945_dev_h__
+#define __iwl_3945_dev_h__
+
+#define IWL_PCI_DEVICE(dev, subdev, cfg) \
+       .vendor = PCI_VENDOR_ID_INTEL,  .device = (dev), \
+       .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
+       .driver_data = (kernel_ulong_t)&(cfg)
+
+#define IWL_SKU_G       0x1
+#define IWL_SKU_A       0x2
+
+struct iwl_3945_cfg {
+       const char *name;
+       const char *fw_name;
+       unsigned int sku;
+};
+
+#endif /* __iwl_dev_h__ */
 
 #include <asm/unaligned.h>
 #include <net/mac80211.h>
 
+#include "iwl-3945-core.h"
 #include "iwl-3945.h"
 #include "iwl-helpers.h"
 #include "iwl-3945-rs.h"
        cancel_delayed_work(&priv->thermal_periodic);
 }
 
+static struct iwl_3945_cfg iwl3945_bg_cfg = {
+       .name = "3945BG",
+       .sku = IWL_SKU_G,
+};
+
+static struct iwl_3945_cfg iwl3945_abg_cfg = {
+       .name = "3945ABG",
+       .sku = IWL_SKU_A|IWL_SKU_G,
+};
+
 struct pci_device_id iwl3945_hw_card_ids[] = {
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4222)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4227)},
+       {IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)},
+       {IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)},
+       {IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)},
+       {IWL_PCI_DEVICE(0x4227, 0x1014, iwl3945_bg_cfg)},
+       {IWL_PCI_DEVICE(0x4222, PCI_ANY_ID, iwl3945_abg_cfg)},
+       {IWL_PCI_DEVICE(0x4227, PCI_ANY_ID, iwl3945_abg_cfg)},
        {0}
 };
 
 
        struct ieee80211_hw *hw;
        struct ieee80211_channel *ieee_channels;
        struct ieee80211_rate *ieee_rates;
+       struct iwl_3945_cfg *cfg; /* device configuration */
 
        /* temporary frame storage list */
        struct list_head free_frames;
        int is_open;
 
        u8 mac80211_registered;
-       int is_abg;
 
        u32 notif_missed_beacons;
 
 
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
 
+#include "iwl-core.h"
 #include "iwl-4965.h"
 #include "iwl-helpers.h"
 
        cancel_delayed_work(&priv->init_alive_start);
 }
 
+static struct iwl_cfg iwl4965_agn_cfg = {
+       .name = "4965AGN",
+       .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+};
+
 struct pci_device_id iwl4965_hw_card_ids[] = {
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4229)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4230)},
+       {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
+       {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
        {0}
 };
 
 
        struct ieee80211_hw *hw;
        struct ieee80211_channel *ieee_channels;
        struct ieee80211_rate *ieee_rates;
+       struct iwl_cfg *cfg;
 
        /* temporary frame storage list */
        struct list_head free_frames;
        int is_open;
 
        u8 mac80211_registered;
-       int is_abg;
 
        u32 notif_missed_beacons;
 
 
--- /dev/null
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ *
+ * 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.GPL.
+ *
+ * Contact Information:
+ * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __iwl_core_h__
+#define __iwl_core_h__
+
+#define IWL_PCI_DEVICE(dev, subdev, cfg) \
+       .vendor = PCI_VENDOR_ID_INTEL,  .device = (dev), \
+       .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
+       .driver_data = (kernel_ulong_t)&(cfg)
+
+#define IWL_SKU_G       0x1
+#define IWL_SKU_A       0x2
+#define IWL_SKU_N       0x8
+
+struct iwl_cfg {
+       const char *name;
+       const char *fw_name;
+       unsigned int sku;
+};
+
+#endif /* __iwl_core_h__ */
 
 
 #include <asm/div64.h>
 
+#include "iwl-3945-core.h"
 #include "iwl-3945.h"
 #include "iwl-helpers.h"
 
                                 geo_ch->flags);
        }
 
-       if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) {
+       if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
+            priv->cfg->sku & IWL_SKU_A) {
                printk(KERN_INFO DRV_NAME
                       ": Incorrectly detected BG card as ABG.  Please send "
                       "your PCI ID 0x%04X:0x%04X to maintainer.\n",
                       priv->pci_dev->device, priv->pci_dev->subsystem_device);
-               priv->is_abg = 0;
+                priv->cfg->sku &= ~IWL_SKU_A;
        }
 
        printk(KERN_INFO DRV_NAME
 static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        int err = 0;
-       u32 pci_id;
        struct iwl3945_priv *priv;
        struct ieee80211_hw *hw;
+       struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
        int i;
        DECLARE_MAC_BUF(mac);
 
        priv->hw = hw;
 
        priv->pci_dev = pdev;
+       priv->cfg = cfg;
 
        /* Select antenna (may be helpful if only one antenna is connected) */
        priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
 
        priv->iw_mode = IEEE80211_IF_TYPE_STA;
 
-       pci_id =
-           (priv->pci_dev->device << 16) | priv->pci_dev->subsystem_device;
-
-       switch (pci_id) {
-       case 0x42221005:        /* 0x4222 0x8086 0x1005 is BG SKU */
-       case 0x42221034:        /* 0x4222 0x8086 0x1034 is BG SKU */
-       case 0x42271014:        /* 0x4227 0x8086 0x1014 is BG SKU */
-       case 0x42221044:        /* 0x4222 0x8086 0x1044 is BG SKU */
-               priv->is_abg = 0;
-               break;
-
-       /*
-        * Rest are assumed ABG SKU -- if this is not the
-        * case then the card will get the wrong 'Detected'
-        * line in the kernel log however the code that
-        * initializes the GEO table will detect no A-band
-        * channels and remove the is_abg mask.
-        */
-       default:
-               priv->is_abg = 1;
-               break;
-       }
-
        printk(KERN_INFO DRV_NAME
-              ": Detected Intel PRO/Wireless 3945%sBG Network Connection\n",
-              priv->is_abg ? "A" : "");
+               ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
 
        /* Device-specific setup */
        if (iwl3945_hw_set_hw_setting(priv)) {
 
 
 #include <asm/div64.h>
 
+#include "iwl-core.h"
 #include "iwl-4965.h"
 #include "iwl-helpers.h"
 
                                 geo_ch->flags);
        }
 
-       if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) {
+       if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
+            priv->cfg->sku & IWL_SKU_A) {
                printk(KERN_INFO DRV_NAME
                       ": Incorrectly detected BG card as ABG.  Please send "
                       "your PCI ID 0x%04X:0x%04X to maintainer.\n",
                       priv->pci_dev->device, priv->pci_dev->subsystem_device);
-               priv->is_abg = 0;
+               priv->cfg->sku &= ~IWL_SKU_A;
        }
 
        printk(KERN_INFO DRV_NAME
        int err = 0;
        struct iwl4965_priv *priv;
        struct ieee80211_hw *hw;
+       struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
        int i;
        DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
        priv = hw->priv;
        priv->hw = hw;
+       priv->cfg = cfg;
 
        priv->pci_dev = pdev;
        priv->antenna = (enum iwl4965_antenna)iwl4965_param_antenna;
        /* Choose which receivers/antennas to use */
        iwl4965_set_rxon_chain(priv);
 
+
        printk(KERN_INFO DRV_NAME
-              ": Detected Intel Wireless WiFi Link 4965AGN\n");
+               ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
 
        /* Device-specific setup */
        if (iwl4965_hw_set_hw_setting(priv)) {