diff options
Diffstat (limited to 'drivers/net/wireless/libertas/cmd.c')
-rw-r--r-- | drivers/net/wireless/libertas/cmd.c | 133 |
1 files changed, 57 insertions, 76 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index bb940cce3a73..79a8d0d48bf7 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -1028,24 +1028,18 @@ void lbs_queue_cmd(struct lbs_private *priv, | |||
1028 | u8 addtail) | 1028 | u8 addtail) |
1029 | { | 1029 | { |
1030 | unsigned long flags; | 1030 | unsigned long flags; |
1031 | struct cmd_ds_command *cmdptr; | ||
1032 | 1031 | ||
1033 | lbs_deb_enter(LBS_DEB_HOST); | 1032 | lbs_deb_enter(LBS_DEB_HOST); |
1034 | 1033 | ||
1035 | if (!cmdnode) { | 1034 | if (!cmdnode || !cmdnode->cmdbuf) { |
1036 | lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n"); | 1035 | lbs_deb_host("QUEUE_CMD: cmdnode or cmdbuf is NULL\n"); |
1037 | goto done; | ||
1038 | } | ||
1039 | |||
1040 | cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; | ||
1041 | if (!cmdptr) { | ||
1042 | lbs_deb_host("QUEUE_CMD: cmdptr is NULL\n"); | ||
1043 | goto done; | 1036 | goto done; |
1044 | } | 1037 | } |
1045 | 1038 | ||
1046 | /* Exit_PS command needs to be queued in the header always. */ | 1039 | /* Exit_PS command needs to be queued in the header always. */ |
1047 | if (le16_to_cpu(cmdptr->command) == CMD_802_11_PS_MODE) { | 1040 | if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { |
1048 | struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode; | 1041 | struct cmd_ds_802_11_ps_mode *psm = (void *) cmdnode->cmdbuf; |
1042 | |||
1049 | if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { | 1043 | if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { |
1050 | if (priv->psstate != PS_STATE_FULL_POWER) | 1044 | if (priv->psstate != PS_STATE_FULL_POWER) |
1051 | addtail = 0; | 1045 | addtail = 0; |
@@ -1062,7 +1056,7 @@ void lbs_queue_cmd(struct lbs_private *priv, | |||
1062 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 1056 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
1063 | 1057 | ||
1064 | lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n", | 1058 | lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n", |
1065 | le16_to_cpu(((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command)); | 1059 | le16_to_cpu(cmdnode->cmdbuf->command)); |
1066 | 1060 | ||
1067 | done: | 1061 | done: |
1068 | lbs_deb_leave(LBS_DEB_HOST); | 1062 | lbs_deb_leave(LBS_DEB_HOST); |
@@ -1079,7 +1073,7 @@ static int DownloadcommandToStation(struct lbs_private *priv, | |||
1079 | struct cmd_ctrl_node *cmdnode) | 1073 | struct cmd_ctrl_node *cmdnode) |
1080 | { | 1074 | { |
1081 | unsigned long flags; | 1075 | unsigned long flags; |
1082 | struct cmd_ds_command *cmdptr; | 1076 | struct cmd_header *cmd; |
1083 | int ret = -1; | 1077 | int ret = -1; |
1084 | u16 cmdsize; | 1078 | u16 cmdsize; |
1085 | u16 command; | 1079 | u16 command; |
@@ -1091,10 +1085,10 @@ static int DownloadcommandToStation(struct lbs_private *priv, | |||
1091 | goto done; | 1085 | goto done; |
1092 | } | 1086 | } |
1093 | 1087 | ||
1094 | cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; | 1088 | cmd = cmdnode->cmdbuf; |
1095 | 1089 | ||
1096 | spin_lock_irqsave(&priv->driver_lock, flags); | 1090 | spin_lock_irqsave(&priv->driver_lock, flags); |
1097 | if (!cmdptr || !cmdptr->size) { | 1091 | if (!cmd || !cmd->size) { |
1098 | lbs_deb_host("DNLD_CMD: cmdptr is NULL or zero\n"); | 1092 | lbs_deb_host("DNLD_CMD: cmdptr is NULL or zero\n"); |
1099 | __lbs_cleanup_and_insert_cmd(priv, cmdnode); | 1093 | __lbs_cleanup_and_insert_cmd(priv, cmdnode); |
1100 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 1094 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
@@ -1105,16 +1099,16 @@ static int DownloadcommandToStation(struct lbs_private *priv, | |||
1105 | priv->cur_cmd_retcode = 0; | 1099 | priv->cur_cmd_retcode = 0; |
1106 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 1100 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
1107 | 1101 | ||
1108 | cmdsize = le16_to_cpu(cmdptr->size); | 1102 | cmdsize = le16_to_cpu(cmd->size); |
1109 | command = le16_to_cpu(cmdptr->command); | 1103 | command = le16_to_cpu(cmd->command); |
1110 | 1104 | ||
1111 | lbs_deb_host("DNLD_CMD: command 0x%04x, size %d, jiffies %lu\n", | 1105 | lbs_deb_host("DNLD_CMD: command 0x%04x, size %d, jiffies %lu\n", |
1112 | command, cmdsize, jiffies); | 1106 | command, cmdsize, jiffies); |
1113 | lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", cmdnode->bufvirtualaddr, cmdsize); | 1107 | lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); |
1114 | 1108 | ||
1115 | cmdnode->cmdwaitqwoken = 0; | 1109 | cmdnode->cmdwaitqwoken = 0; |
1116 | 1110 | ||
1117 | ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize); | 1111 | ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); |
1118 | 1112 | ||
1119 | if (ret != 0) { | 1113 | if (ret != 0) { |
1120 | lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n"); | 1114 | lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n"); |
@@ -1265,7 +1259,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, | |||
1265 | 1259 | ||
1266 | lbs_set_cmd_ctrl_node(priv, cmdnode, wait_option, pdata_buf); | 1260 | lbs_set_cmd_ctrl_node(priv, cmdnode, wait_option, pdata_buf); |
1267 | 1261 | ||
1268 | cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; | 1262 | cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf; |
1269 | 1263 | ||
1270 | lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no); | 1264 | lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no); |
1271 | 1265 | ||
@@ -1556,41 +1550,35 @@ EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command); | |||
1556 | int lbs_allocate_cmd_buffer(struct lbs_private *priv) | 1550 | int lbs_allocate_cmd_buffer(struct lbs_private *priv) |
1557 | { | 1551 | { |
1558 | int ret = 0; | 1552 | int ret = 0; |
1559 | u32 ulbufsize; | 1553 | u32 bufsize; |
1560 | u32 i; | 1554 | u32 i; |
1561 | struct cmd_ctrl_node *tempcmd_array; | 1555 | struct cmd_ctrl_node *cmdarray; |
1562 | u8 *ptempvirtualaddr; | ||
1563 | 1556 | ||
1564 | lbs_deb_enter(LBS_DEB_HOST); | 1557 | lbs_deb_enter(LBS_DEB_HOST); |
1565 | 1558 | ||
1566 | /* Allocate and initialize cmdCtrlNode */ | 1559 | /* Allocate and initialize the command array */ |
1567 | ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER; | 1560 | bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS; |
1568 | 1561 | if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) { | |
1569 | if (!(tempcmd_array = kzalloc(ulbufsize, GFP_KERNEL))) { | ||
1570 | lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n"); | 1562 | lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n"); |
1571 | ret = -1; | 1563 | ret = -1; |
1572 | goto done; | 1564 | goto done; |
1573 | } | 1565 | } |
1574 | priv->cmd_array = tempcmd_array; | 1566 | priv->cmd_array = cmdarray; |
1575 | 1567 | ||
1576 | /* Allocate and initialize command buffers */ | 1568 | /* Allocate and initialize each command buffer in the command array */ |
1577 | ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER; | 1569 | for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { |
1578 | for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) { | 1570 | cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL); |
1579 | if (!(ptempvirtualaddr = kzalloc(ulbufsize, GFP_KERNEL))) { | 1571 | if (!cmdarray[i].cmdbuf) { |
1580 | lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n"); | 1572 | lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n"); |
1581 | ret = -1; | 1573 | ret = -1; |
1582 | goto done; | 1574 | goto done; |
1583 | } | 1575 | } |
1584 | |||
1585 | /* Update command buffer virtual */ | ||
1586 | tempcmd_array[i].bufvirtualaddr = ptempvirtualaddr; | ||
1587 | } | 1576 | } |
1588 | 1577 | ||
1589 | for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) { | 1578 | for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { |
1590 | init_waitqueue_head(&tempcmd_array[i].cmdwait_q); | 1579 | init_waitqueue_head(&cmdarray[i].cmdwait_q); |
1591 | lbs_cleanup_and_insert_cmd(priv, &tempcmd_array[i]); | 1580 | lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]); |
1592 | } | 1581 | } |
1593 | |||
1594 | ret = 0; | 1582 | ret = 0; |
1595 | 1583 | ||
1596 | done: | 1584 | done: |
@@ -1606,9 +1594,8 @@ done: | |||
1606 | */ | 1594 | */ |
1607 | int lbs_free_cmd_buffer(struct lbs_private *priv) | 1595 | int lbs_free_cmd_buffer(struct lbs_private *priv) |
1608 | { | 1596 | { |
1609 | u32 ulbufsize; /* Someone needs to die for this. Slowly and painfully */ | 1597 | struct cmd_ctrl_node *cmdarray; |
1610 | unsigned int i; | 1598 | unsigned int i; |
1611 | struct cmd_ctrl_node *tempcmd_array; | ||
1612 | 1599 | ||
1613 | lbs_deb_enter(LBS_DEB_HOST); | 1600 | lbs_deb_enter(LBS_DEB_HOST); |
1614 | 1601 | ||
@@ -1618,14 +1605,13 @@ int lbs_free_cmd_buffer(struct lbs_private *priv) | |||
1618 | goto done; | 1605 | goto done; |
1619 | } | 1606 | } |
1620 | 1607 | ||
1621 | tempcmd_array = priv->cmd_array; | 1608 | cmdarray = priv->cmd_array; |
1622 | 1609 | ||
1623 | /* Release shared memory buffers */ | 1610 | /* Release shared memory buffers */ |
1624 | ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER; | 1611 | for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { |
1625 | for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) { | 1612 | if (cmdarray[i].cmdbuf) { |
1626 | if (tempcmd_array[i].bufvirtualaddr) { | 1613 | kfree(cmdarray[i].cmdbuf); |
1627 | kfree(tempcmd_array[i].bufvirtualaddr); | 1614 | cmdarray[i].cmdbuf = NULL; |
1628 | tempcmd_array[i].bufvirtualaddr = NULL; | ||
1629 | } | 1615 | } |
1630 | } | 1616 | } |
1631 | 1617 | ||
@@ -1683,21 +1669,21 @@ struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv) | |||
1683 | * @param ptempnode A pointer to cmdCtrlNode structure | 1669 | * @param ptempnode A pointer to cmdCtrlNode structure |
1684 | * @return n/a | 1670 | * @return n/a |
1685 | */ | 1671 | */ |
1686 | static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode) | 1672 | static void cleanup_cmdnode(struct cmd_ctrl_node *cmdnode) |
1687 | { | 1673 | { |
1688 | lbs_deb_enter(LBS_DEB_HOST); | 1674 | lbs_deb_enter(LBS_DEB_HOST); |
1689 | 1675 | ||
1690 | if (!ptempnode) | 1676 | if (!cmdnode) |
1691 | return; | 1677 | return; |
1692 | ptempnode->cmdwaitqwoken = 1; | 1678 | cmdnode->cmdwaitqwoken = 1; |
1693 | wake_up_interruptible(&ptempnode->cmdwait_q); | 1679 | wake_up_interruptible(&cmdnode->cmdwait_q); |
1694 | ptempnode->wait_option = 0; | 1680 | cmdnode->wait_option = 0; |
1695 | ptempnode->pdata_buf = NULL; | 1681 | cmdnode->pdata_buf = NULL; |
1696 | ptempnode->callback = NULL; | 1682 | cmdnode->callback = NULL; |
1697 | ptempnode->callback_arg = 0; | 1683 | cmdnode->callback_arg = 0; |
1698 | 1684 | ||
1699 | if (ptempnode->bufvirtualaddr != NULL) | 1685 | if (cmdnode->cmdbuf != NULL) |
1700 | memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER); | 1686 | memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE); |
1701 | 1687 | ||
1702 | lbs_deb_leave(LBS_DEB_HOST); | 1688 | lbs_deb_leave(LBS_DEB_HOST); |
1703 | } | 1689 | } |
@@ -1739,7 +1725,7 @@ void lbs_set_cmd_ctrl_node(struct lbs_private *priv, | |||
1739 | int lbs_execute_next_command(struct lbs_private *priv) | 1725 | int lbs_execute_next_command(struct lbs_private *priv) |
1740 | { | 1726 | { |
1741 | struct cmd_ctrl_node *cmdnode = NULL; | 1727 | struct cmd_ctrl_node *cmdnode = NULL; |
1742 | struct cmd_ds_command *cmdptr; | 1728 | struct cmd_header *cmd; |
1743 | unsigned long flags; | 1729 | unsigned long flags; |
1744 | int ret = 0; | 1730 | int ret = 0; |
1745 | 1731 | ||
@@ -1765,22 +1751,21 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
1765 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 1751 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
1766 | 1752 | ||
1767 | if (cmdnode) { | 1753 | if (cmdnode) { |
1768 | cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; | 1754 | cmd = cmdnode->cmdbuf; |
1769 | 1755 | ||
1770 | if (is_command_allowed_in_ps(le16_to_cpu(cmdptr->command))) { | 1756 | if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) { |
1771 | if ((priv->psstate == PS_STATE_SLEEP) || | 1757 | if ((priv->psstate == PS_STATE_SLEEP) || |
1772 | (priv->psstate == PS_STATE_PRE_SLEEP)) { | 1758 | (priv->psstate == PS_STATE_PRE_SLEEP)) { |
1773 | lbs_deb_host( | 1759 | lbs_deb_host( |
1774 | "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n", | 1760 | "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n", |
1775 | le16_to_cpu(cmdptr->command), | 1761 | le16_to_cpu(cmd->command), |
1776 | priv->psstate); | 1762 | priv->psstate); |
1777 | ret = -1; | 1763 | ret = -1; |
1778 | goto done; | 1764 | goto done; |
1779 | } | 1765 | } |
1780 | lbs_deb_host("EXEC_NEXT_CMD: OK to send command " | 1766 | lbs_deb_host("EXEC_NEXT_CMD: OK to send command " |
1781 | "0x%04x in psstate %d\n", | 1767 | "0x%04x in psstate %d\n", |
1782 | le16_to_cpu(cmdptr->command), | 1768 | le16_to_cpu(cmd->command), priv->psstate); |
1783 | priv->psstate); | ||
1784 | } else if (priv->psstate != PS_STATE_FULL_POWER) { | 1769 | } else if (priv->psstate != PS_STATE_FULL_POWER) { |
1785 | /* | 1770 | /* |
1786 | * 1. Non-PS command: | 1771 | * 1. Non-PS command: |
@@ -1793,8 +1778,7 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
1793 | * otherwise send this command down to firmware | 1778 | * otherwise send this command down to firmware |
1794 | * immediately. | 1779 | * immediately. |
1795 | */ | 1780 | */ |
1796 | if (cmdptr->command != | 1781 | if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) { |
1797 | cpu_to_le16(CMD_802_11_PS_MODE)) { | ||
1798 | /* Prepare to send Exit PS, | 1782 | /* Prepare to send Exit PS, |
1799 | * this non PS command will be sent later */ | 1783 | * this non PS command will be sent later */ |
1800 | if ((priv->psstate == PS_STATE_SLEEP) | 1784 | if ((priv->psstate == PS_STATE_SLEEP) |
@@ -1813,8 +1797,7 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
1813 | * PS command. Ignore it if it is not Exit_PS. | 1797 | * PS command. Ignore it if it is not Exit_PS. |
1814 | * otherwise send it down immediately. | 1798 | * otherwise send it down immediately. |
1815 | */ | 1799 | */ |
1816 | struct cmd_ds_802_11_ps_mode *psm = | 1800 | struct cmd_ds_802_11_ps_mode *psm = (void *)cmd; |
1817 | &cmdptr->params.psmode; | ||
1818 | 1801 | ||
1819 | lbs_deb_host( | 1802 | lbs_deb_host( |
1820 | "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", | 1803 | "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", |
@@ -1848,7 +1831,7 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
1848 | } | 1831 | } |
1849 | list_del(&cmdnode->list); | 1832 | list_del(&cmdnode->list); |
1850 | lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", | 1833 | lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", |
1851 | le16_to_cpu(cmdptr->command)); | 1834 | le16_to_cpu(cmd->command)); |
1852 | DownloadcommandToStation(priv, cmdnode); | 1835 | DownloadcommandToStation(priv, cmdnode); |
1853 | } else { | 1836 | } else { |
1854 | /* | 1837 | /* |
@@ -2079,7 +2062,6 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command, | |||
2079 | unsigned long callback_arg) | 2062 | unsigned long callback_arg) |
2080 | { | 2063 | { |
2081 | struct cmd_ctrl_node *cmdnode; | 2064 | struct cmd_ctrl_node *cmdnode; |
2082 | struct cmd_header *send_cmd; | ||
2083 | unsigned long flags; | 2065 | unsigned long flags; |
2084 | int ret = 0; | 2066 | int ret = 0; |
2085 | 2067 | ||
@@ -2107,20 +2089,19 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command, | |||
2107 | goto done; | 2089 | goto done; |
2108 | } | 2090 | } |
2109 | 2091 | ||
2110 | send_cmd = (struct cmd_header *) cmdnode->bufvirtualaddr; | ||
2111 | cmdnode->wait_option = CMD_OPTION_WAITFORRSP; | 2092 | cmdnode->wait_option = CMD_OPTION_WAITFORRSP; |
2112 | cmdnode->callback = callback; | 2093 | cmdnode->callback = callback; |
2113 | cmdnode->callback_arg = callback_arg; | 2094 | cmdnode->callback_arg = callback_arg; |
2114 | 2095 | ||
2115 | /* Copy the incoming command to the buffer */ | 2096 | /* Copy the incoming command to the buffer */ |
2116 | memcpy(send_cmd, in_cmd, in_cmd_size); | 2097 | memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); |
2117 | 2098 | ||
2118 | /* Set sequence number, clean result, move to buffer */ | 2099 | /* Set sequence number, clean result, move to buffer */ |
2119 | priv->seqnum++; | 2100 | priv->seqnum++; |
2120 | send_cmd->command = cpu_to_le16(command); | 2101 | cmdnode->cmdbuf->command = cpu_to_le16(command); |
2121 | send_cmd->size = cpu_to_le16(in_cmd_size); | 2102 | cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); |
2122 | send_cmd->seqnum = cpu_to_le16(priv->seqnum); | 2103 | cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum); |
2123 | send_cmd->result = 0; | 2104 | cmdnode->cmdbuf->result = 0; |
2124 | 2105 | ||
2125 | lbs_deb_host("PREP_CMD: command 0x%04x\n", command); | 2106 | lbs_deb_host("PREP_CMD: command 0x%04x\n", command); |
2126 | 2107 | ||