aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c229
1 files changed, 123 insertions, 106 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 0d9824c7e28f..2e563662c9a2 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1557,16 +1557,19 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1557 return ret; 1557 return ret;
1558} 1558}
1559 1559
1560static void do_release_fw(struct b43_firmware_file *fw)
1561{
1562 release_firmware(fw->data);
1563 fw->data = NULL;
1564 fw->filename = NULL;
1565}
1566
1560static void b43_release_firmware(struct b43_wldev *dev) 1567static void b43_release_firmware(struct b43_wldev *dev)
1561{ 1568{
1562 release_firmware(dev->fw.ucode); 1569 do_release_fw(&dev->fw.ucode);
1563 dev->fw.ucode = NULL; 1570 do_release_fw(&dev->fw.pcm);
1564 release_firmware(dev->fw.pcm); 1571 do_release_fw(&dev->fw.initvals);
1565 dev->fw.pcm = NULL; 1572 do_release_fw(&dev->fw.initvals_band);
1566 release_firmware(dev->fw.initvals);
1567 dev->fw.initvals = NULL;
1568 release_firmware(dev->fw.initvals_band);
1569 dev->fw.initvals_band = NULL;
1570} 1573}
1571 1574
1572static void b43_print_fw_helptext(struct b43_wl *wl, bool error) 1575static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
@@ -1584,33 +1587,43 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
1584 1587
1585static int do_request_fw(struct b43_wldev *dev, 1588static int do_request_fw(struct b43_wldev *dev,
1586 const char *name, 1589 const char *name,
1587 const struct firmware **fw) 1590 struct b43_firmware_file *fw)
1588{ 1591{
1589 char path[sizeof(modparam_fwpostfix) + 32]; 1592 char path[sizeof(modparam_fwpostfix) + 32];
1593 const struct firmware *blob;
1590 struct b43_fw_header *hdr; 1594 struct b43_fw_header *hdr;
1591 u32 size; 1595 u32 size;
1592 int err; 1596 int err;
1593 1597
1594 if (!name) 1598 if (!name) {
1599 /* Don't fetch anything. Free possibly cached firmware. */
1600 do_release_fw(fw);
1595 return 0; 1601 return 0;
1602 }
1603 if (fw->filename) {
1604 if (strcmp(fw->filename, name) == 0)
1605 return 0; /* Already have this fw. */
1606 /* Free the cached firmware first. */
1607 do_release_fw(fw);
1608 }
1596 1609
1597 snprintf(path, ARRAY_SIZE(path), 1610 snprintf(path, ARRAY_SIZE(path),
1598 "b43%s/%s.fw", 1611 "b43%s/%s.fw",
1599 modparam_fwpostfix, name); 1612 modparam_fwpostfix, name);
1600 err = request_firmware(fw, path, dev->dev->dev); 1613 err = request_firmware(&blob, path, dev->dev->dev);
1601 if (err) { 1614 if (err) {
1602 b43err(dev->wl, "Firmware file \"%s\" not found " 1615 b43err(dev->wl, "Firmware file \"%s\" not found "
1603 "or load failed.\n", path); 1616 "or load failed.\n", path);
1604 return err; 1617 return err;
1605 } 1618 }
1606 if ((*fw)->size < sizeof(struct b43_fw_header)) 1619 if (blob->size < sizeof(struct b43_fw_header))
1607 goto err_format; 1620 goto err_format;
1608 hdr = (struct b43_fw_header *)((*fw)->data); 1621 hdr = (struct b43_fw_header *)(blob->data);
1609 switch (hdr->type) { 1622 switch (hdr->type) {
1610 case B43_FW_TYPE_UCODE: 1623 case B43_FW_TYPE_UCODE:
1611 case B43_FW_TYPE_PCM: 1624 case B43_FW_TYPE_PCM:
1612 size = be32_to_cpu(hdr->size); 1625 size = be32_to_cpu(hdr->size);
1613 if (size != (*fw)->size - sizeof(struct b43_fw_header)) 1626 if (size != blob->size - sizeof(struct b43_fw_header))
1614 goto err_format; 1627 goto err_format;
1615 /* fallthrough */ 1628 /* fallthrough */
1616 case B43_FW_TYPE_IV: 1629 case B43_FW_TYPE_IV:
@@ -1621,10 +1634,15 @@ static int do_request_fw(struct b43_wldev *dev,
1621 goto err_format; 1634 goto err_format;
1622 } 1635 }
1623 1636
1624 return err; 1637 fw->data = blob;
1638 fw->filename = name;
1639
1640 return 0;
1625 1641
1626err_format: 1642err_format:
1627 b43err(dev->wl, "Firmware file \"%s\" format error.\n", path); 1643 b43err(dev->wl, "Firmware file \"%s\" format error.\n", path);
1644 release_firmware(blob);
1645
1628 return -EPROTO; 1646 return -EPROTO;
1629} 1647}
1630 1648
@@ -1636,97 +1654,96 @@ static int b43_request_firmware(struct b43_wldev *dev)
1636 u32 tmshigh; 1654 u32 tmshigh;
1637 int err; 1655 int err;
1638 1656
1657 /* Get microcode */
1639 tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH); 1658 tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
1640 if (!fw->ucode) { 1659 if ((rev >= 5) && (rev <= 10))
1660 filename = "ucode5";
1661 else if ((rev >= 11) && (rev <= 12))
1662 filename = "ucode11";
1663 else if (rev >= 13)
1664 filename = "ucode13";
1665 else
1666 goto err_no_ucode;
1667 err = do_request_fw(dev, filename, &fw->ucode);
1668 if (err)
1669 goto err_load;
1670
1671 /* Get PCM code */
1672 if ((rev >= 5) && (rev <= 10))
1673 filename = "pcm5";
1674 else if (rev >= 11)
1675 filename = NULL;
1676 else
1677 goto err_no_pcm;
1678 err = do_request_fw(dev, filename, &fw->pcm);
1679 if (err)
1680 goto err_load;
1681
1682 /* Get initvals */
1683 switch (dev->phy.type) {
1684 case B43_PHYTYPE_A:
1685 if ((rev >= 5) && (rev <= 10)) {
1686 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
1687 filename = "a0g1initvals5";
1688 else
1689 filename = "a0g0initvals5";
1690 } else
1691 goto err_no_initvals;
1692 break;
1693 case B43_PHYTYPE_G:
1641 if ((rev >= 5) && (rev <= 10)) 1694 if ((rev >= 5) && (rev <= 10))
1642 filename = "ucode5"; 1695 filename = "b0g0initvals5";
1643 else if ((rev >= 11) && (rev <= 12))
1644 filename = "ucode11";
1645 else if (rev >= 13) 1696 else if (rev >= 13)
1646 filename = "ucode13"; 1697 filename = "lp0initvals13";
1647 else 1698 else
1648 goto err_no_ucode; 1699 goto err_no_initvals;
1649 err = do_request_fw(dev, filename, &fw->ucode); 1700 break;
1650 if (err) 1701 case B43_PHYTYPE_N:
1651 goto err_load; 1702 if ((rev >= 11) && (rev <= 12))
1703 filename = "n0initvals11";
1704 else
1705 goto err_no_initvals;
1706 break;
1707 default:
1708 goto err_no_initvals;
1652 } 1709 }
1653 if (!fw->pcm) { 1710 err = do_request_fw(dev, filename, &fw->initvals);
1711 if (err)
1712 goto err_load;
1713
1714 /* Get bandswitch initvals */
1715 switch (dev->phy.type) {
1716 case B43_PHYTYPE_A:
1717 if ((rev >= 5) && (rev <= 10)) {
1718 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
1719 filename = "a0g1bsinitvals5";
1720 else
1721 filename = "a0g0bsinitvals5";
1722 } else if (rev >= 11)
1723 filename = NULL;
1724 else
1725 goto err_no_initvals;
1726 break;
1727 case B43_PHYTYPE_G:
1654 if ((rev >= 5) && (rev <= 10)) 1728 if ((rev >= 5) && (rev <= 10))
1655 filename = "pcm5"; 1729 filename = "b0g0bsinitvals5";
1656 else if (rev >= 11) 1730 else if (rev >= 11)
1657 filename = NULL; 1731 filename = NULL;
1658 else 1732 else
1659 goto err_no_pcm;
1660 err = do_request_fw(dev, filename, &fw->pcm);
1661 if (err)
1662 goto err_load;
1663 }
1664 if (!fw->initvals) {
1665 switch (dev->phy.type) {
1666 case B43_PHYTYPE_A:
1667 if ((rev >= 5) && (rev <= 10)) {
1668 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
1669 filename = "a0g1initvals5";
1670 else
1671 filename = "a0g0initvals5";
1672 } else
1673 goto err_no_initvals;
1674 break;
1675 case B43_PHYTYPE_G:
1676 if ((rev >= 5) && (rev <= 10))
1677 filename = "b0g0initvals5";
1678 else if (rev >= 13)
1679 filename = "lp0initvals13";
1680 else
1681 goto err_no_initvals;
1682 break;
1683 case B43_PHYTYPE_N:
1684 if ((rev >= 11) && (rev <= 12))
1685 filename = "n0initvals11";
1686 else
1687 goto err_no_initvals;
1688 break;
1689 default:
1690 goto err_no_initvals; 1733 goto err_no_initvals;
1691 } 1734 break;
1692 err = do_request_fw(dev, filename, &fw->initvals); 1735 case B43_PHYTYPE_N:
1693 if (err) 1736 if ((rev >= 11) && (rev <= 12))
1694 goto err_load; 1737 filename = "n0bsinitvals11";
1695 } 1738 else
1696 if (!fw->initvals_band) {
1697 switch (dev->phy.type) {
1698 case B43_PHYTYPE_A:
1699 if ((rev >= 5) && (rev <= 10)) {
1700 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
1701 filename = "a0g1bsinitvals5";
1702 else
1703 filename = "a0g0bsinitvals5";
1704 } else if (rev >= 11)
1705 filename = NULL;
1706 else
1707 goto err_no_initvals;
1708 break;
1709 case B43_PHYTYPE_G:
1710 if ((rev >= 5) && (rev <= 10))
1711 filename = "b0g0bsinitvals5";
1712 else if (rev >= 11)
1713 filename = NULL;
1714 else
1715 goto err_no_initvals;
1716 break;
1717 case B43_PHYTYPE_N:
1718 if ((rev >= 11) && (rev <= 12))
1719 filename = "n0bsinitvals11";
1720 else
1721 goto err_no_initvals;
1722 break;
1723 default:
1724 goto err_no_initvals; 1739 goto err_no_initvals;
1725 } 1740 break;
1726 err = do_request_fw(dev, filename, &fw->initvals_band); 1741 default:
1727 if (err) 1742 goto err_no_initvals;
1728 goto err_load;
1729 } 1743 }
1744 err = do_request_fw(dev, filename, &fw->initvals_band);
1745 if (err)
1746 goto err_load;
1730 1747
1731 return 0; 1748 return 0;
1732 1749
@@ -1765,18 +1782,18 @@ static int b43_upload_microcode(struct b43_wldev *dev)
1765 int err = 0; 1782 int err = 0;
1766 1783
1767 /* Upload Microcode. */ 1784 /* Upload Microcode. */
1768 data = (__be32 *) (dev->fw.ucode->data + hdr_len); 1785 data = (__be32 *) (dev->fw.ucode.data->data + hdr_len);
1769 len = (dev->fw.ucode->size - hdr_len) / sizeof(__be32); 1786 len = (dev->fw.ucode.data->size - hdr_len) / sizeof(__be32);
1770 b43_shm_control_word(dev, B43_SHM_UCODE | B43_SHM_AUTOINC_W, 0x0000); 1787 b43_shm_control_word(dev, B43_SHM_UCODE | B43_SHM_AUTOINC_W, 0x0000);
1771 for (i = 0; i < len; i++) { 1788 for (i = 0; i < len; i++) {
1772 b43_write32(dev, B43_MMIO_SHM_DATA, be32_to_cpu(data[i])); 1789 b43_write32(dev, B43_MMIO_SHM_DATA, be32_to_cpu(data[i]));
1773 udelay(10); 1790 udelay(10);
1774 } 1791 }
1775 1792
1776 if (dev->fw.pcm) { 1793 if (dev->fw.pcm.data) {
1777 /* Upload PCM data. */ 1794 /* Upload PCM data. */
1778 data = (__be32 *) (dev->fw.pcm->data + hdr_len); 1795 data = (__be32 *) (dev->fw.pcm.data->data + hdr_len);
1779 len = (dev->fw.pcm->size - hdr_len) / sizeof(__be32); 1796 len = (dev->fw.pcm.data->size - hdr_len) / sizeof(__be32);
1780 b43_shm_control_word(dev, B43_SHM_HW, 0x01EA); 1797 b43_shm_control_word(dev, B43_SHM_HW, 0x01EA);
1781 b43_write32(dev, B43_MMIO_SHM_DATA, 0x00004000); 1798 b43_write32(dev, B43_MMIO_SHM_DATA, 0x00004000);
1782 /* No need for autoinc bit in SHM_HW */ 1799 /* No need for autoinc bit in SHM_HW */
@@ -1913,19 +1930,19 @@ static int b43_upload_initvals(struct b43_wldev *dev)
1913 size_t count; 1930 size_t count;
1914 int err; 1931 int err;
1915 1932
1916 hdr = (const struct b43_fw_header *)(fw->initvals->data); 1933 hdr = (const struct b43_fw_header *)(fw->initvals.data->data);
1917 ivals = (const struct b43_iv *)(fw->initvals->data + hdr_len); 1934 ivals = (const struct b43_iv *)(fw->initvals.data->data + hdr_len);
1918 count = be32_to_cpu(hdr->size); 1935 count = be32_to_cpu(hdr->size);
1919 err = b43_write_initvals(dev, ivals, count, 1936 err = b43_write_initvals(dev, ivals, count,
1920 fw->initvals->size - hdr_len); 1937 fw->initvals.data->size - hdr_len);
1921 if (err) 1938 if (err)
1922 goto out; 1939 goto out;
1923 if (fw->initvals_band) { 1940 if (fw->initvals_band.data) {
1924 hdr = (const struct b43_fw_header *)(fw->initvals_band->data); 1941 hdr = (const struct b43_fw_header *)(fw->initvals_band.data->data);
1925 ivals = (const struct b43_iv *)(fw->initvals_band->data + hdr_len); 1942 ivals = (const struct b43_iv *)(fw->initvals_band.data->data + hdr_len);
1926 count = be32_to_cpu(hdr->size); 1943 count = be32_to_cpu(hdr->size);
1927 err = b43_write_initvals(dev, ivals, count, 1944 err = b43_write_initvals(dev, ivals, count,
1928 fw->initvals_band->size - hdr_len); 1945 fw->initvals_band.data->size - hdr_len);
1929 if (err) 1946 if (err)
1930 goto out; 1947 goto out;
1931 } 1948 }