0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include "device.h"
0022 #include "mac.h"
0023 #include "wcmd.h"
0024 #include "power.h"
0025 #include "usbpipe.h"
0026 #include "rxtx.h"
0027 #include "rf.h"
0028
0029 static void vnt_cmd_timer_wait(struct vnt_private *priv, unsigned long msecs)
0030 {
0031 schedule_delayed_work(&priv->run_command_work, msecs_to_jiffies(msecs));
0032 }
0033
0034 static u32 add_one_with_wrap_around(u32 var, u8 modulo)
0035 {
0036 if (var >= (modulo - 1))
0037 var = 0;
0038 else
0039 var++;
0040 return var;
0041 }
0042
0043 static int vnt_cmd_complete(struct vnt_private *priv)
0044 {
0045 priv->command_state = WLAN_CMD_IDLE;
0046 if (priv->free_cmd_queue == CMD_Q_SIZE) {
0047
0048 priv->cmd_running = false;
0049 return true;
0050 }
0051
0052 priv->command = priv->cmd_queue[priv->cmd_dequeue_idx];
0053
0054 priv->cmd_dequeue_idx = add_one_with_wrap_around(priv->cmd_dequeue_idx, CMD_Q_SIZE);
0055 priv->free_cmd_queue++;
0056 priv->cmd_running = true;
0057
0058 switch (priv->command) {
0059 case WLAN_CMD_INIT_MAC80211:
0060 priv->command_state = WLAN_CMD_INIT_MAC80211_START;
0061 break;
0062
0063 case WLAN_CMD_TBTT_WAKEUP:
0064 priv->command_state = WLAN_CMD_TBTT_WAKEUP_START;
0065 break;
0066
0067 case WLAN_CMD_BECON_SEND:
0068 priv->command_state = WLAN_CMD_BECON_SEND_START;
0069 break;
0070
0071 case WLAN_CMD_SETPOWER:
0072 priv->command_state = WLAN_CMD_SETPOWER_START;
0073 break;
0074
0075 case WLAN_CMD_CHANGE_ANTENNA:
0076 priv->command_state = WLAN_CMD_CHANGE_ANTENNA_START;
0077 break;
0078
0079 default:
0080 break;
0081 }
0082
0083 vnt_cmd_timer_wait(priv, 0);
0084
0085 return true;
0086 }
0087
0088 void vnt_run_command(struct work_struct *work)
0089 {
0090 struct vnt_private *priv =
0091 container_of(work, struct vnt_private, run_command_work.work);
0092
0093 if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
0094 return;
0095
0096 if (!priv->cmd_running)
0097 return;
0098
0099 switch (priv->command_state) {
0100 case WLAN_CMD_INIT_MAC80211_START:
0101 if (priv->mac_hw)
0102 break;
0103
0104 dev_info(&priv->usb->dev, "Starting mac80211\n");
0105
0106 if (vnt_init(priv)) {
0107
0108 dev_err(&priv->usb->dev, "failed to start\n");
0109 usb_set_intfdata(priv->intf, NULL);
0110 ieee80211_free_hw(priv->hw);
0111 return;
0112 }
0113
0114 break;
0115
0116 case WLAN_CMD_TBTT_WAKEUP_START:
0117 vnt_next_tbtt_wakeup(priv);
0118 break;
0119
0120 case WLAN_CMD_BECON_SEND_START:
0121 if (!priv->vif)
0122 break;
0123
0124 vnt_beacon_make(priv, priv->vif);
0125
0126 vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
0127
0128 break;
0129
0130 case WLAN_CMD_SETPOWER_START:
0131
0132 vnt_rf_setpower(priv, priv->hw->conf.chandef.chan);
0133
0134 break;
0135
0136 case WLAN_CMD_CHANGE_ANTENNA_START:
0137 dev_dbg(&priv->usb->dev, "Change from Antenna%d to",
0138 priv->rx_antenna_sel);
0139
0140 if (priv->rx_antenna_sel == 0) {
0141 priv->rx_antenna_sel = 1;
0142 if (priv->tx_rx_ant_inv)
0143 vnt_set_antenna_mode(priv, ANT_RXA);
0144 else
0145 vnt_set_antenna_mode(priv, ANT_RXB);
0146 } else {
0147 priv->rx_antenna_sel = 0;
0148 if (priv->tx_rx_ant_inv)
0149 vnt_set_antenna_mode(priv, ANT_RXB);
0150 else
0151 vnt_set_antenna_mode(priv, ANT_RXA);
0152 }
0153 break;
0154
0155 default:
0156 break;
0157 }
0158
0159 vnt_cmd_complete(priv);
0160 }
0161
0162 int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd command)
0163 {
0164 if (priv->free_cmd_queue == 0)
0165 return false;
0166
0167 priv->cmd_queue[priv->cmd_enqueue_idx] = command;
0168
0169 priv->cmd_enqueue_idx = add_one_with_wrap_around(priv->cmd_enqueue_idx, CMD_Q_SIZE);
0170 priv->free_cmd_queue--;
0171
0172 if (!priv->cmd_running)
0173 vnt_cmd_complete(priv);
0174
0175 return true;
0176 }
0177
0178 void vnt_reset_command_timer(struct vnt_private *priv)
0179 {
0180 priv->free_cmd_queue = CMD_Q_SIZE;
0181 priv->cmd_dequeue_idx = 0;
0182 priv->cmd_enqueue_idx = 0;
0183 priv->command_state = WLAN_CMD_IDLE;
0184 priv->cmd_running = false;
0185 }