Commit 40db0b22 authored by Christian Lamparter's avatar Christian Lamparter Committed by John W. Linville

p54pci: cache firmware for suspend/resume

Johannes pointed out that the driver has cache the firmware for
suspend/resume cycles.
Signed-off-by: default avatarChristian Lamparter <chunkeey@web.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent ffed7858
...@@ -1524,16 +1524,24 @@ static int p54_start(struct ieee80211_hw *dev) ...@@ -1524,16 +1524,24 @@ static int p54_start(struct ieee80211_hw *dev)
mutex_lock(&priv->conf_mutex); mutex_lock(&priv->conf_mutex);
err = priv->open(dev); err = priv->open(dev);
if (!err) if (err)
priv->mode = NL80211_IFTYPE_MONITOR; goto out;
P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47); P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47);
P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94); P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94);
P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0); P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0); P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
err = p54_set_edcf(dev); err = p54_set_edcf(dev);
if (!err) if (err)
err = p54_init_stats(dev); goto out;
err = p54_init_stats(dev);
if (err)
goto out;
err = p54_setup_mac(dev, P54_FILTER_TYPE_NONE, NULL);
if (err)
goto out;
priv->mode = NL80211_IFTYPE_MONITOR;
out:
mutex_unlock(&priv->conf_mutex); mutex_unlock(&priv->conf_mutex);
return err; return err;
} }
......
...@@ -47,7 +47,6 @@ MODULE_DEVICE_TABLE(pci, p54p_table); ...@@ -47,7 +47,6 @@ MODULE_DEVICE_TABLE(pci, p54p_table);
static int p54p_upload_firmware(struct ieee80211_hw *dev) static int p54p_upload_firmware(struct ieee80211_hw *dev)
{ {
struct p54p_priv *priv = dev->priv; struct p54p_priv *priv = dev->priv;
const struct firmware *fw_entry = NULL;
__le32 reg; __le32 reg;
int err; int err;
__le32 *data; __le32 *data;
...@@ -73,23 +72,15 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev) ...@@ -73,23 +72,15 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
P54P_WRITE(ctrl_stat, reg); P54P_WRITE(ctrl_stat, reg);
wmb(); wmb();
err = request_firmware(&fw_entry, "isl3886pci", &priv->pdev->dev); /* wait for the firmware to reset properly */
if (err) { mdelay(10);
printk(KERN_ERR "%s (p54pci): cannot find firmware "
"(isl3886pci)\n", pci_name(priv->pdev));
err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev);
if (err)
return err;
}
err = p54_parse_firmware(dev, fw_entry); err = p54_parse_firmware(dev, priv->firmware);
if (err) { if (err)
release_firmware(fw_entry);
return err; return err;
}
data = (__le32 *) fw_entry->data; data = (__le32 *) priv->firmware->data;
remains = fw_entry->size; remains = priv->firmware->size;
device_addr = ISL38XX_DEV_FIRMWARE_ADDR; device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
while (remains) { while (remains) {
u32 i = 0; u32 i = 0;
...@@ -107,8 +98,6 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev) ...@@ -107,8 +98,6 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
P54P_READ(int_enable); P54P_READ(int_enable);
} }
release_firmware(fw_entry);
reg = P54P_READ(ctrl_stat); reg = P54P_READ(ctrl_stat);
reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN); reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET); reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
...@@ -500,15 +489,14 @@ static int __devinit p54p_probe(struct pci_dev *pdev, ...@@ -500,15 +489,14 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
if (mem_len < sizeof(struct p54p_csr)) { if (mem_len < sizeof(struct p54p_csr)) {
printk(KERN_ERR "%s (p54pci): Too short PCI resources\n", printk(KERN_ERR "%s (p54pci): Too short PCI resources\n",
pci_name(pdev)); pci_name(pdev));
pci_disable_device(pdev); goto err_disable_dev;
return err;
} }
err = pci_request_regions(pdev, "p54pci"); err = pci_request_regions(pdev, "p54pci");
if (err) { if (err) {
printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n", printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n",
pci_name(pdev)); pci_name(pdev));
return err; goto err_disable_dev;
} }
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
...@@ -561,6 +549,17 @@ static int __devinit p54p_probe(struct pci_dev *pdev, ...@@ -561,6 +549,17 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev);
err = request_firmware(&priv->firmware, "isl3886pci",
&priv->pdev->dev);
if (err) {
printk(KERN_ERR "%s (p54pci): cannot find firmware "
"(isl3886pci)\n", pci_name(priv->pdev));
err = request_firmware(&priv->firmware, "isl3886",
&priv->pdev->dev);
if (err)
goto err_free_common;
}
err = p54p_open(dev); err = p54p_open(dev);
if (err) if (err)
goto err_free_common; goto err_free_common;
...@@ -579,6 +578,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev, ...@@ -579,6 +578,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
return 0; return 0;
err_free_common: err_free_common:
release_firmware(priv->firmware);
p54_free_common(dev); p54_free_common(dev);
pci_free_consistent(pdev, sizeof(*priv->ring_control), pci_free_consistent(pdev, sizeof(*priv->ring_control),
priv->ring_control, priv->ring_control_dma); priv->ring_control, priv->ring_control_dma);
...@@ -592,6 +592,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev, ...@@ -592,6 +592,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
err_free_reg: err_free_reg:
pci_release_regions(pdev); pci_release_regions(pdev);
err_disable_dev:
pci_disable_device(pdev); pci_disable_device(pdev);
return err; return err;
} }
...@@ -606,6 +607,7 @@ static void __devexit p54p_remove(struct pci_dev *pdev) ...@@ -606,6 +607,7 @@ static void __devexit p54p_remove(struct pci_dev *pdev)
ieee80211_unregister_hw(dev); ieee80211_unregister_hw(dev);
priv = dev->priv; priv = dev->priv;
release_firmware(priv->firmware);
pci_free_consistent(pdev, sizeof(*priv->ring_control), pci_free_consistent(pdev, sizeof(*priv->ring_control),
priv->ring_control, priv->ring_control_dma); priv->ring_control, priv->ring_control_dma);
p54_free_common(dev); p54_free_common(dev);
......
...@@ -93,7 +93,7 @@ struct p54p_priv { ...@@ -93,7 +93,7 @@ struct p54p_priv {
struct pci_dev *pdev; struct pci_dev *pdev;
struct p54p_csr __iomem *map; struct p54p_csr __iomem *map;
struct tasklet_struct rx_tasklet; struct tasklet_struct rx_tasklet;
const struct firmware *firmware;
spinlock_t lock; spinlock_t lock;
struct p54p_ring_control *ring_control; struct p54p_ring_control *ring_control;
dma_addr_t ring_control_dma; dma_addr_t ring_control_dma;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment