aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/cmd.c')
-rw-r--r--drivers/net/wireless/libertas/cmd.c133
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
1067done: 1061done:
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);
1556int lbs_allocate_cmd_buffer(struct lbs_private *priv) 1550int 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
1596done: 1584done:
@@ -1606,9 +1594,8 @@ done:
1606 */ 1594 */
1607int lbs_free_cmd_buffer(struct lbs_private *priv) 1595int 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 */
1686static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode) 1672static 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,
1739int lbs_execute_next_command(struct lbs_private *priv) 1725int 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