wcmd.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. * File: wcmd.c
  20. *
  21. * Purpose: Handles the management command interface functions
  22. *
  23. * Author: Lyndon Chen
  24. *
  25. * Date: May 8, 2003
  26. *
  27. * Functions:
  28. * vnt_cmd_complete - Command Complete function
  29. * vnt_schedule_command - Push Command and wait Command Scheduler to do
  30. * vnt_cmd_timer_wait- Call back timer
  31. *
  32. * Revision History:
  33. *
  34. */
  35. #include "device.h"
  36. #include "mac.h"
  37. #include "wcmd.h"
  38. #include "power.h"
  39. #include "usbpipe.h"
  40. #include "rxtx.h"
  41. #include "rf.h"
  42. static void vnt_cmd_timer_wait(struct vnt_private *priv, unsigned long msecs)
  43. {
  44. schedule_delayed_work(&priv->run_command_work, msecs_to_jiffies(msecs));
  45. }
  46. static int vnt_cmd_complete(struct vnt_private *priv)
  47. {
  48. priv->command_state = WLAN_CMD_IDLE;
  49. if (priv->free_cmd_queue == CMD_Q_SIZE) {
  50. /* Command Queue Empty */
  51. priv->cmd_running = false;
  52. return true;
  53. }
  54. priv->command = priv->cmd_queue[priv->cmd_dequeue_idx];
  55. ADD_ONE_WITH_WRAP_AROUND(priv->cmd_dequeue_idx, CMD_Q_SIZE);
  56. priv->free_cmd_queue++;
  57. priv->cmd_running = true;
  58. switch (priv->command) {
  59. case WLAN_CMD_INIT_MAC80211:
  60. priv->command_state = WLAN_CMD_INIT_MAC80211_START;
  61. break;
  62. case WLAN_CMD_TBTT_WAKEUP:
  63. priv->command_state = WLAN_CMD_TBTT_WAKEUP_START;
  64. break;
  65. case WLAN_CMD_BECON_SEND:
  66. priv->command_state = WLAN_CMD_BECON_SEND_START;
  67. break;
  68. case WLAN_CMD_SETPOWER:
  69. priv->command_state = WLAN_CMD_SETPOWER_START;
  70. break;
  71. case WLAN_CMD_CHANGE_ANTENNA:
  72. priv->command_state = WLAN_CMD_CHANGE_ANTENNA_START;
  73. break;
  74. default:
  75. break;
  76. }
  77. vnt_cmd_timer_wait(priv, 0);
  78. return true;
  79. }
  80. void vnt_run_command(struct work_struct *work)
  81. {
  82. struct vnt_private *priv =
  83. container_of(work, struct vnt_private, run_command_work.work);
  84. if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
  85. return;
  86. if (priv->cmd_running != true)
  87. return;
  88. switch (priv->command_state) {
  89. case WLAN_CMD_INIT_MAC80211_START:
  90. if (priv->mac_hw)
  91. break;
  92. dev_info(&priv->usb->dev, "Starting mac80211\n");
  93. if (vnt_init(priv)) {
  94. /* If fail all ends TODO retry */
  95. dev_err(&priv->usb->dev, "failed to start\n");
  96. ieee80211_free_hw(priv->hw);
  97. return;
  98. }
  99. break;
  100. case WLAN_CMD_TBTT_WAKEUP_START:
  101. vnt_next_tbtt_wakeup(priv);
  102. break;
  103. case WLAN_CMD_BECON_SEND_START:
  104. if (!priv->vif)
  105. break;
  106. vnt_beacon_make(priv, priv->vif);
  107. vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
  108. break;
  109. case WLAN_CMD_SETPOWER_START:
  110. vnt_rf_setpower(priv, priv->current_rate,
  111. priv->hw->conf.chandef.chan->hw_value);
  112. break;
  113. case WLAN_CMD_CHANGE_ANTENNA_START:
  114. dev_dbg(&priv->usb->dev, "Change from Antenna%d to",
  115. priv->rx_antenna_sel);
  116. if (priv->rx_antenna_sel == 0) {
  117. priv->rx_antenna_sel = 1;
  118. if (priv->tx_rx_ant_inv == true)
  119. vnt_set_antenna_mode(priv, ANT_RXA);
  120. else
  121. vnt_set_antenna_mode(priv, ANT_RXB);
  122. } else {
  123. priv->rx_antenna_sel = 0;
  124. if (priv->tx_rx_ant_inv == true)
  125. vnt_set_antenna_mode(priv, ANT_RXB);
  126. else
  127. vnt_set_antenna_mode(priv, ANT_RXA);
  128. }
  129. break;
  130. default:
  131. break;
  132. }
  133. vnt_cmd_complete(priv);
  134. }
  135. int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd command)
  136. {
  137. if (priv->free_cmd_queue == 0)
  138. return false;
  139. priv->cmd_queue[priv->cmd_enqueue_idx] = command;
  140. ADD_ONE_WITH_WRAP_AROUND(priv->cmd_enqueue_idx, CMD_Q_SIZE);
  141. priv->free_cmd_queue--;
  142. if (priv->cmd_running == false)
  143. vnt_cmd_complete(priv);
  144. return true;
  145. }
  146. void vnt_reset_command_timer(struct vnt_private *priv)
  147. {
  148. priv->free_cmd_queue = CMD_Q_SIZE;
  149. priv->cmd_dequeue_idx = 0;
  150. priv->cmd_enqueue_idx = 0;
  151. priv->command_state = WLAN_CMD_IDLE;
  152. priv->cmd_running = false;
  153. }