|
@@ -17,11 +17,11 @@
|
|
|
#define __UNDEF_NO_VERSION__
|
|
|
|
|
|
#include <linux/etherdevice.h>
|
|
|
-#include <linux/pci.h>
|
|
|
#include <linux/sched.h>
|
|
|
#include <linux/firmware.h>
|
|
|
#include <linux/interrupt.h>
|
|
|
#include <linux/module.h>
|
|
|
+#include <linux/bcma/bcma.h>
|
|
|
#include <net/mac80211.h>
|
|
|
#include <defs.h>
|
|
|
#include "nicpci.h"
|
|
@@ -87,16 +87,14 @@ MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
|
|
|
MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
|
|
|
MODULE_LICENSE("Dual BSD/GPL");
|
|
|
|
|
|
-/* recognized PCI IDs */
|
|
|
-static DEFINE_PCI_DEVICE_TABLE(brcms_pci_id_table) = {
|
|
|
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, /* 43225 2G */
|
|
|
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, /* 43224 DUAL */
|
|
|
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, /* 4313 DUAL */
|
|
|
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, /* 43224 Ven */
|
|
|
- {0}
|
|
|
-};
|
|
|
|
|
|
-MODULE_DEVICE_TABLE(pci, brcms_pci_id_table);
|
|
|
+/* recognized BCMA Core IDs */
|
|
|
+static struct bcma_device_id brcms_coreid_table[] = {
|
|
|
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211,
|
|
|
+ BCMA_ANY_REV, BCMA_ANY_CLASS),
|
|
|
+ BCMA_CORETABLE_END
|
|
|
+};
|
|
|
+MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
|
|
|
|
|
|
#ifdef BCMDBG
|
|
|
static int msglevel = 0xdeadbeef;
|
|
@@ -724,7 +722,7 @@ static const struct ieee80211_ops brcms_ops = {
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
- * is called in brcms_pci_probe() context, therefore no locking required.
|
|
|
+ * is called in brcms_bcma_probe() context, therefore no locking required.
|
|
|
*/
|
|
|
static int brcms_set_hint(struct brcms_info *wl, char *abbrev)
|
|
|
{
|
|
@@ -864,25 +862,15 @@ static void brcms_free(struct brcms_info *wl)
|
|
|
#endif
|
|
|
kfree(t);
|
|
|
}
|
|
|
-
|
|
|
- /*
|
|
|
- * unregister_netdev() calls get_stats() which may read chip
|
|
|
- * registers so we cannot unmap the chip registers until
|
|
|
- * after calling unregister_netdev() .
|
|
|
- */
|
|
|
- if (wl->regsva)
|
|
|
- iounmap(wl->regsva);
|
|
|
-
|
|
|
- wl->regsva = NULL;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* called from both kernel as from this kernel module (error flow on attach)
|
|
|
* precondition: perimeter lock is not acquired.
|
|
|
*/
|
|
|
-static void brcms_remove(struct pci_dev *pdev)
|
|
|
+static void brcms_remove(struct bcma_device *pdev)
|
|
|
{
|
|
|
- struct ieee80211_hw *hw = pci_get_drvdata(pdev);
|
|
|
+ struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
|
|
|
struct brcms_info *wl = hw->priv;
|
|
|
|
|
|
if (wl->wlc) {
|
|
@@ -890,11 +878,10 @@ static void brcms_remove(struct pci_dev *pdev)
|
|
|
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
|
|
|
ieee80211_unregister_hw(hw);
|
|
|
}
|
|
|
- pci_disable_device(pdev);
|
|
|
|
|
|
brcms_free(wl);
|
|
|
|
|
|
- pci_set_drvdata(pdev, NULL);
|
|
|
+ bcma_set_drvdata(pdev, NULL);
|
|
|
ieee80211_free_hw(hw);
|
|
|
}
|
|
|
|
|
@@ -1002,11 +989,9 @@ static int ieee_hw_init(struct ieee80211_hw *hw)
|
|
|
* it as static.
|
|
|
*
|
|
|
*
|
|
|
- * is called in brcms_pci_probe() context, therefore no locking required.
|
|
|
+ * is called in brcms_bcma_probe() context, therefore no locking required.
|
|
|
*/
|
|
|
-static struct brcms_info *brcms_attach(u16 vendor, u16 device,
|
|
|
- resource_size_t regs,
|
|
|
- struct pci_dev *btparam, uint irq)
|
|
|
+static struct brcms_info *brcms_attach(struct bcma_device *pdev)
|
|
|
{
|
|
|
struct brcms_info *wl = NULL;
|
|
|
int unit, err;
|
|
@@ -1020,7 +1005,7 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device,
|
|
|
return NULL;
|
|
|
|
|
|
/* allocate private info */
|
|
|
- hw = pci_get_drvdata(btparam); /* btparam == pdev */
|
|
|
+ hw = bcma_get_drvdata(pdev);
|
|
|
if (hw != NULL)
|
|
|
wl = hw->priv;
|
|
|
if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
|
|
@@ -1032,26 +1017,22 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device,
|
|
|
/* setup the bottom half handler */
|
|
|
tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
|
|
|
|
|
|
- wl->regsva = ioremap_nocache(regs, PCI_BAR0_WINSZ);
|
|
|
- if (wl->regsva == NULL) {
|
|
|
- wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit);
|
|
|
- goto fail;
|
|
|
- }
|
|
|
spin_lock_init(&wl->lock);
|
|
|
spin_lock_init(&wl->isr_lock);
|
|
|
|
|
|
/* prepare ucode */
|
|
|
- if (brcms_request_fw(wl, btparam) < 0) {
|
|
|
+ if (brcms_request_fw(wl, pdev->bus->host_pci) < 0) {
|
|
|
wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
|
|
|
"%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
|
|
|
brcms_release_fw(wl);
|
|
|
- brcms_remove(btparam);
|
|
|
+ brcms_remove(pdev);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
/* common load-time initialization */
|
|
|
- wl->wlc = brcms_c_attach(wl, vendor, device, unit, false,
|
|
|
- wl->regsva, btparam, &err);
|
|
|
+ wl->wlc = brcms_c_attach((void *)wl, pdev->bus->host_pci->vendor,
|
|
|
+ pdev->bus->host_pci->device, unit, false,
|
|
|
+ pdev->bus->mmio, pdev->bus->host_pci, &err);
|
|
|
brcms_release_fw(wl);
|
|
|
if (!wl->wlc) {
|
|
|
wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
|
|
@@ -1063,11 +1044,12 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device,
|
|
|
wl->pub->ieee_hw = hw;
|
|
|
|
|
|
/* register our interrupt handler */
|
|
|
- if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
|
|
|
+ if (request_irq(pdev->bus->host_pci->irq, brcms_isr,
|
|
|
+ IRQF_SHARED, KBUILD_MODNAME, wl)) {
|
|
|
wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
|
|
|
goto fail;
|
|
|
}
|
|
|
- wl->irq = irq;
|
|
|
+ wl->irq = pdev->bus->host_pci->irq;
|
|
|
|
|
|
/* register module */
|
|
|
brcms_c_module_register(wl->pub, "linux", wl, NULL);
|
|
@@ -1114,37 +1096,18 @@ fail:
|
|
|
*
|
|
|
* Perimeter lock is initialized in the course of this function.
|
|
|
*/
|
|
|
-static int __devinit
|
|
|
-brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
+static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
|
|
|
{
|
|
|
- int rc;
|
|
|
struct brcms_info *wl;
|
|
|
struct ieee80211_hw *hw;
|
|
|
- u32 val;
|
|
|
-
|
|
|
- dev_info(&pdev->dev, "bus %d slot %d func %d irq %d\n",
|
|
|
- pdev->bus->number, PCI_SLOT(pdev->devfn),
|
|
|
- PCI_FUNC(pdev->devfn), pdev->irq);
|
|
|
|
|
|
- if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
|
|
|
- ((pdev->device != 0x0576) &&
|
|
|
- ((pdev->device & 0xff00) != 0x4300) &&
|
|
|
- ((pdev->device & 0xff00) != 0x4700) &&
|
|
|
- ((pdev->device < 43000) || (pdev->device > 43999))))
|
|
|
- return -ENODEV;
|
|
|
+ dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
|
|
|
+ pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
|
|
|
+ pdev->bus->host_pci->irq);
|
|
|
|
|
|
- rc = pci_enable_device(pdev);
|
|
|
- if (rc) {
|
|
|
- pr_err("%s: Cannot enable device %d-%d_%d\n",
|
|
|
- __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
|
|
|
- PCI_FUNC(pdev->devfn));
|
|
|
+ if ((pdev->id.manuf != BCMA_MANUF_BCM) ||
|
|
|
+ (pdev->id.id != BCMA_CORE_80211))
|
|
|
return -ENODEV;
|
|
|
- }
|
|
|
- pci_set_master(pdev);
|
|
|
-
|
|
|
- pci_read_config_dword(pdev, 0x40, &val);
|
|
|
- if ((val & 0x0000ff00) != 0)
|
|
|
- pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
|
|
|
|
|
|
hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops);
|
|
|
if (!hw) {
|
|
@@ -1154,14 +1117,11 @@ brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
|
|
|
SET_IEEE80211_DEV(hw, &pdev->dev);
|
|
|
|
|
|
- pci_set_drvdata(pdev, hw);
|
|
|
+ bcma_set_drvdata(pdev, hw);
|
|
|
|
|
|
memset(hw->priv, 0, sizeof(*wl));
|
|
|
|
|
|
- wl = brcms_attach(pdev->vendor, pdev->device,
|
|
|
- pci_resource_start(pdev, 0), pdev,
|
|
|
- pdev->irq);
|
|
|
-
|
|
|
+ wl = brcms_attach(pdev);
|
|
|
if (!wl) {
|
|
|
pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME,
|
|
|
__func__);
|
|
@@ -1170,16 +1130,23 @@ brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int brcms_suspend(struct pci_dev *pdev, pm_message_t state)
|
|
|
+static int brcms_pci_suspend(struct pci_dev *pdev)
|
|
|
+{
|
|
|
+ pci_save_state(pdev);
|
|
|
+ pci_disable_device(pdev);
|
|
|
+ return pci_set_power_state(pdev, PCI_D3hot);
|
|
|
+}
|
|
|
+
|
|
|
+static int brcms_suspend(struct bcma_device *pdev, pm_message_t state)
|
|
|
{
|
|
|
struct brcms_info *wl;
|
|
|
struct ieee80211_hw *hw;
|
|
|
|
|
|
- hw = pci_get_drvdata(pdev);
|
|
|
+ hw = bcma_get_drvdata(pdev);
|
|
|
wl = hw->priv;
|
|
|
if (!wl) {
|
|
|
wiphy_err(wl->wiphy,
|
|
|
- "brcms_suspend: pci_get_drvdata failed\n");
|
|
|
+ "brcms_suspend: bcma_get_drvdata failed\n");
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
@@ -1188,25 +1155,14 @@ static int brcms_suspend(struct pci_dev *pdev, pm_message_t state)
|
|
|
wl->pub->hw_up = false;
|
|
|
spin_unlock_bh(&wl->lock);
|
|
|
|
|
|
- pci_save_state(pdev);
|
|
|
- pci_disable_device(pdev);
|
|
|
- return pci_set_power_state(pdev, PCI_D3hot);
|
|
|
+ /* temporarily do suspend ourselves */
|
|
|
+ return brcms_pci_suspend(pdev->bus->host_pci);
|
|
|
}
|
|
|
|
|
|
-static int brcms_resume(struct pci_dev *pdev)
|
|
|
+static int brcms_pci_resume(struct pci_dev *pdev)
|
|
|
{
|
|
|
- struct brcms_info *wl;
|
|
|
- struct ieee80211_hw *hw;
|
|
|
int err = 0;
|
|
|
- u32 val;
|
|
|
-
|
|
|
- hw = pci_get_drvdata(pdev);
|
|
|
- wl = hw->priv;
|
|
|
- if (!wl) {
|
|
|
- wiphy_err(wl->wiphy,
|
|
|
- "wl: brcms_resume: pci_get_drvdata failed\n");
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
+ uint val;
|
|
|
|
|
|
err = pci_set_power_state(pdev, PCI_D0);
|
|
|
if (err)
|
|
@@ -1224,24 +1180,28 @@ static int brcms_resume(struct pci_dev *pdev)
|
|
|
if ((val & 0x0000ff00) != 0)
|
|
|
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
|
|
|
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int brcms_resume(struct bcma_device *pdev)
|
|
|
+{
|
|
|
/*
|
|
|
- * done. driver will be put in up state
|
|
|
- * in brcms_ops_add_interface() call.
|
|
|
+ * just do pci resume for now until bcma supports it.
|
|
|
*/
|
|
|
- return err;
|
|
|
+ return brcms_pci_resume(pdev->bus->host_pci);
|
|
|
}
|
|
|
|
|
|
-static struct pci_driver brcms_pci_driver = {
|
|
|
+static struct bcma_driver brcms_bcma_driver = {
|
|
|
.name = KBUILD_MODNAME,
|
|
|
- .probe = brcms_pci_probe,
|
|
|
+ .probe = brcms_bcma_probe,
|
|
|
.suspend = brcms_suspend,
|
|
|
.resume = brcms_resume,
|
|
|
.remove = __devexit_p(brcms_remove),
|
|
|
- .id_table = brcms_pci_id_table,
|
|
|
+ .id_table = brcms_coreid_table,
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * This is the main entry point for the WL driver.
|
|
|
+ * This is the main entry point for the brcmsmac driver.
|
|
|
*
|
|
|
* This function determines if a device pointed to by pdev is a WL device,
|
|
|
* and if so, performs a brcms_attach() on it.
|
|
@@ -1256,26 +1216,24 @@ static int __init brcms_module_init(void)
|
|
|
brcm_msg_level = msglevel;
|
|
|
#endif /* BCMDBG */
|
|
|
|
|
|
- error = pci_register_driver(&brcms_pci_driver);
|
|
|
+ error = bcma_driver_register(&brcms_bcma_driver);
|
|
|
+ printk(KERN_ERR "%s: register returned %d\n", __func__, error);
|
|
|
if (!error)
|
|
|
return 0;
|
|
|
|
|
|
-
|
|
|
-
|
|
|
return error;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * This function unloads the WL driver from the system.
|
|
|
+ * This function unloads the brcmsmac driver from the system.
|
|
|
*
|
|
|
- * This function unconditionally unloads the WL driver module from the
|
|
|
+ * This function unconditionally unloads the brcmsmac driver module from the
|
|
|
* system.
|
|
|
*
|
|
|
*/
|
|
|
static void __exit brcms_module_exit(void)
|
|
|
{
|
|
|
- pci_unregister_driver(&brcms_pci_driver);
|
|
|
-
|
|
|
+ bcma_driver_unregister(&brcms_bcma_driver);
|
|
|
}
|
|
|
|
|
|
module_init(brcms_module_init);
|
|
@@ -1562,7 +1520,7 @@ fail:
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Precondition: Since this function is called in brcms_pci_probe() context,
|
|
|
+ * Precondition: Since this function is called in brcms_bcma_probe() context,
|
|
|
* no locking is required.
|
|
|
*/
|
|
|
int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
|
|
@@ -1602,7 +1560,7 @@ void brcms_ucode_free_buf(void *p)
|
|
|
/*
|
|
|
* checks validity of all firmware images loaded from user space
|
|
|
*
|
|
|
- * Precondition: Since this function is called in brcms_pci_probe() context,
|
|
|
+ * Precondition: Since this function is called in brcms_bcma_probe() context,
|
|
|
* no locking is required.
|
|
|
*/
|
|
|
int brcms_check_firmwares(struct brcms_info *wl)
|