aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2009-10-22 14:21:30 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-11-06 16:54:38 -0500
commit42fba21d56df644887488a29b158cc8916b9ba99 (patch)
tree2aec3f2ec4b1e96bcfd6079ad0550350bfd321a6 /drivers/net/wireless/mwl8k.c
parent04b147b19303724aac5ee8e56f113f1935a5c255 (diff)
mwl8k: add the commands used for AP firmware initialisation
Add the AP version of the GET_HW_SPEC command, as well as the SET_HW_SPEC command, for initialising AP firmware. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c133
1 files changed, 132 insertions, 1 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 90bf19cb6bf4..9b9ce7005da0 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -275,6 +275,7 @@ static const struct ieee80211_rate mwl8k_rates[] = {
275/* Firmware command codes */ 275/* Firmware command codes */
276#define MWL8K_CMD_CODE_DNLD 0x0001 276#define MWL8K_CMD_CODE_DNLD 0x0001
277#define MWL8K_CMD_GET_HW_SPEC 0x0003 277#define MWL8K_CMD_GET_HW_SPEC 0x0003
278#define MWL8K_CMD_SET_HW_SPEC 0x0004
278#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010 279#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010
279#define MWL8K_CMD_GET_STAT 0x0014 280#define MWL8K_CMD_GET_STAT 0x0014
280#define MWL8K_CMD_RADIO_CONTROL 0x001c 281#define MWL8K_CMD_RADIO_CONTROL 0x001c
@@ -305,6 +306,7 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
305 switch (cmd & ~0x8000) { 306 switch (cmd & ~0x8000) {
306 MWL8K_CMDNAME(CODE_DNLD); 307 MWL8K_CMDNAME(CODE_DNLD);
307 MWL8K_CMDNAME(GET_HW_SPEC); 308 MWL8K_CMDNAME(GET_HW_SPEC);
309 MWL8K_CMDNAME(SET_HW_SPEC);
308 MWL8K_CMDNAME(MAC_MULTICAST_ADR); 310 MWL8K_CMDNAME(MAC_MULTICAST_ADR);
309 MWL8K_CMDNAME(GET_STAT); 311 MWL8K_CMDNAME(GET_STAT);
310 MWL8K_CMDNAME(RADIO_CONTROL); 312 MWL8K_CMDNAME(RADIO_CONTROL);
@@ -1596,6 +1598,129 @@ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1596} 1598}
1597 1599
1598/* 1600/*
1601 * CMD_GET_HW_SPEC (AP version).
1602 */
1603struct mwl8k_cmd_get_hw_spec_ap {
1604 struct mwl8k_cmd_pkt header;
1605 __u8 hw_rev;
1606 __u8 host_interface;
1607 __le16 num_wcb;
1608 __le16 num_mcaddrs;
1609 __u8 perm_addr[ETH_ALEN];
1610 __le16 region_code;
1611 __le16 num_antenna;
1612 __le32 fw_rev;
1613 __le32 wcbbase0;
1614 __le32 rxwrptr;
1615 __le32 rxrdptr;
1616 __le32 ps_cookie;
1617 __le32 wcbbase1;
1618 __le32 wcbbase2;
1619 __le32 wcbbase3;
1620} __attribute__((packed));
1621
1622static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
1623{
1624 struct mwl8k_priv *priv = hw->priv;
1625 struct mwl8k_cmd_get_hw_spec_ap *cmd;
1626 int rc;
1627
1628 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1629 if (cmd == NULL)
1630 return -ENOMEM;
1631
1632 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
1633 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1634
1635 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1636 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1637
1638 rc = mwl8k_post_cmd(hw, &cmd->header);
1639
1640 if (!rc) {
1641 int off;
1642
1643 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
1644 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1645 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1646 priv->hw_rev = cmd->hw_rev;
1647
1648 off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
1649 iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off);
1650
1651 off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
1652 iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off);
1653
1654 off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
1655 iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off);
1656
1657 off = le32_to_cpu(cmd->wcbbase1) & 0xffff;
1658 iowrite32(cpu_to_le32(priv->txq[1].txd_dma), priv->sram + off);
1659
1660 off = le32_to_cpu(cmd->wcbbase2) & 0xffff;
1661 iowrite32(cpu_to_le32(priv->txq[2].txd_dma), priv->sram + off);
1662
1663 off = le32_to_cpu(cmd->wcbbase3) & 0xffff;
1664 iowrite32(cpu_to_le32(priv->txq[3].txd_dma), priv->sram + off);
1665 }
1666
1667 kfree(cmd);
1668 return rc;
1669}
1670
1671/*
1672 * CMD_SET_HW_SPEC.
1673 */
1674struct mwl8k_cmd_set_hw_spec {
1675 struct mwl8k_cmd_pkt header;
1676 __u8 hw_rev;
1677 __u8 host_interface;
1678 __le16 num_mcaddrs;
1679 __u8 perm_addr[ETH_ALEN];
1680 __le16 region_code;
1681 __le32 fw_rev;
1682 __le32 ps_cookie;
1683 __le32 caps;
1684 __le32 rx_queue_ptr;
1685 __le32 num_tx_queues;
1686 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
1687 __le32 flags;
1688 __le32 num_tx_desc_per_queue;
1689 __le32 total_rxd;
1690} __attribute__((packed));
1691
1692#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
1693
1694static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
1695{
1696 struct mwl8k_priv *priv = hw->priv;
1697 struct mwl8k_cmd_set_hw_spec *cmd;
1698 int rc;
1699 int i;
1700
1701 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1702 if (cmd == NULL)
1703 return -ENOMEM;
1704
1705 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_HW_SPEC);
1706 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1707
1708 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1709 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
1710 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
1711 for (i = 0; i < MWL8K_TX_QUEUES; i++)
1712 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
1713 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT);
1714 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1715 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
1716
1717 rc = mwl8k_post_cmd(hw, &cmd->header);
1718 kfree(cmd);
1719
1720 return rc;
1721}
1722
1723/*
1599 * CMD_MAC_MULTICAST_ADR. 1724 * CMD_MAC_MULTICAST_ADR.
1600 */ 1725 */
1601struct mwl8k_cmd_mac_multicast_adr { 1726struct mwl8k_cmd_mac_multicast_adr {
@@ -3211,7 +3336,13 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3211 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3336 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3212 3337
3213 /* Get config data, mac addrs etc */ 3338 /* Get config data, mac addrs etc */
3214 rc = mwl8k_cmd_get_hw_spec_sta(hw); 3339 if (priv->ap_fw) {
3340 rc = mwl8k_cmd_get_hw_spec_ap(hw);
3341 if (!rc)
3342 rc = mwl8k_cmd_set_hw_spec(hw);
3343 } else {
3344 rc = mwl8k_cmd_get_hw_spec_sta(hw);
3345 }
3215 if (rc) { 3346 if (rc) {
3216 printk(KERN_ERR "%s: Cannot initialise firmware\n", 3347 printk(KERN_ERR "%s: Cannot initialise firmware\n",
3217 wiphy_name(hw->wiphy)); 3348 wiphy_name(hw->wiphy));