Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 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: |
Malcolm Priestley | 60cecd2 | 2014-07-13 10:42:47 +0100 | [diff] [blame] | 28 | * vnt_cmd_complete - Command Complete function |
Malcolm Priestley | a83a859 | 2014-07-13 10:42:53 +0100 | [diff] [blame] | 29 | * vnt_schedule_command - Push Command and wait Command Scheduler to do |
Malcolm Priestley | 2cd98cd | 2014-07-13 10:42:48 +0100 | [diff] [blame] | 30 | * vnt_cmd_timer_wait- Call back timer |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 31 | * |
| 32 | * Revision History: |
| 33 | * |
| 34 | */ |
| 35 | |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 36 | #include "device.h" |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 37 | #include "mac.h" |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 38 | #include "wcmd.h" |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 39 | #include "power.h" |
Malcolm Priestley | 62c8526 | 2014-05-26 13:59:07 +0100 | [diff] [blame] | 40 | #include "usbpipe.h" |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 41 | #include "rxtx.h" |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 42 | #include "rf.h" |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 43 | |
Malcolm Priestley | 2cd98cd | 2014-07-13 10:42:48 +0100 | [diff] [blame] | 44 | static void vnt_cmd_timer_wait(struct vnt_private *priv, unsigned long msecs) |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 45 | { |
Malcolm Priestley | e30546d | 2014-07-12 07:53:39 +0100 | [diff] [blame] | 46 | schedule_delayed_work(&priv->run_command_work, msecs_to_jiffies(msecs)); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 47 | } |
| 48 | |
Malcolm Priestley | 60cecd2 | 2014-07-13 10:42:47 +0100 | [diff] [blame] | 49 | static int vnt_cmd_complete(struct vnt_private *priv) |
| 50 | { |
| 51 | |
| 52 | priv->command_state = WLAN_CMD_IDLE; |
| 53 | if (priv->free_cmd_queue == CMD_Q_SIZE) { |
| 54 | /* Command Queue Empty */ |
| 55 | priv->cmd_running = false; |
| 56 | return true; |
| 57 | } |
| 58 | |
| 59 | priv->command = priv->cmd_queue[priv->cmd_dequeue_idx]; |
| 60 | |
| 61 | ADD_ONE_WITH_WRAP_AROUND(priv->cmd_dequeue_idx, CMD_Q_SIZE); |
| 62 | priv->free_cmd_queue++; |
| 63 | priv->cmd_running = true; |
| 64 | |
| 65 | switch (priv->command) { |
| 66 | case WLAN_CMD_INIT_MAC80211: |
| 67 | priv->command_state = WLAN_CMD_INIT_MAC80211_START; |
| 68 | break; |
| 69 | |
| 70 | case WLAN_CMD_TBTT_WAKEUP: |
| 71 | priv->command_state = WLAN_CMD_TBTT_WAKEUP_START; |
| 72 | break; |
| 73 | |
| 74 | case WLAN_CMD_BECON_SEND: |
| 75 | priv->command_state = WLAN_CMD_BECON_SEND_START; |
| 76 | break; |
| 77 | |
| 78 | case WLAN_CMD_SETPOWER: |
| 79 | priv->command_state = WLAN_CMD_SETPOWER_START; |
| 80 | break; |
| 81 | |
| 82 | case WLAN_CMD_CHANGE_ANTENNA: |
| 83 | priv->command_state = WLAN_CMD_CHANGE_ANTENNA_START; |
| 84 | break; |
| 85 | |
Malcolm Priestley | 60cecd2 | 2014-07-13 10:42:47 +0100 | [diff] [blame] | 86 | default: |
| 87 | break; |
| 88 | } |
| 89 | |
Malcolm Priestley | 2cd98cd | 2014-07-13 10:42:48 +0100 | [diff] [blame] | 90 | vnt_cmd_timer_wait(priv, 0); |
Malcolm Priestley | 60cecd2 | 2014-07-13 10:42:47 +0100 | [diff] [blame] | 91 | |
| 92 | return true; |
| 93 | } |
| 94 | |
Malcolm Priestley | 592365ae4a | 2014-07-13 10:42:49 +0100 | [diff] [blame] | 95 | void vnt_run_command(struct work_struct *work) |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 96 | { |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 97 | struct vnt_private *priv = |
Malcolm Priestley | 94488a7 | 2013-09-27 16:48:14 +0100 | [diff] [blame] | 98 | container_of(work, struct vnt_private, run_command_work.work); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 99 | |
Malcolm Priestley | cbcc9a3 | 2014-07-24 21:13:20 +0100 | [diff] [blame] | 100 | if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) |
Malcolm Priestley | 17f3ced | 2013-10-14 19:51:45 +0100 | [diff] [blame] | 101 | return; |
| 102 | |
Malcolm Priestley | 33a60b8 | 2014-07-13 10:42:45 +0100 | [diff] [blame] | 103 | if (priv->cmd_running != true) |
Nandini Hanumanthagowda | cab086d | 2013-11-12 23:05:35 +0530 | [diff] [blame] | 104 | return; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 105 | |
Malcolm Priestley | ad74e91 | 2014-07-13 10:42:42 +0100 | [diff] [blame] | 106 | switch (priv->command_state) { |
Malcolm Priestley | 30816f8 | 2014-06-25 21:14:27 +0100 | [diff] [blame] | 107 | case WLAN_CMD_INIT_MAC80211_START: |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 108 | if (priv->mac_hw) |
Malcolm Priestley | 30816f8 | 2014-06-25 21:14:27 +0100 | [diff] [blame] | 109 | break; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 110 | |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 111 | dev_info(&priv->usb->dev, "Starting mac80211\n"); |
Malcolm Priestley | 30816f8 | 2014-06-25 21:14:27 +0100 | [diff] [blame] | 112 | |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 113 | if (vnt_init(priv)) { |
Malcolm Priestley | 30816f8 | 2014-06-25 21:14:27 +0100 | [diff] [blame] | 114 | /* If fail all ends TODO retry */ |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 115 | dev_err(&priv->usb->dev, "failed to start\n"); |
| 116 | ieee80211_free_hw(priv->hw); |
Malcolm Priestley | 30816f8 | 2014-06-25 21:14:27 +0100 | [diff] [blame] | 117 | return; |
| 118 | } |
| 119 | |
| 120 | break; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 121 | |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 122 | case WLAN_CMD_TBTT_WAKEUP_START: |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 123 | vnt_next_tbtt_wakeup(priv); |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 124 | break; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 125 | |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 126 | case WLAN_CMD_BECON_SEND_START: |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 127 | if (!priv->vif) |
Malcolm Priestley | f31a67a | 2014-06-25 21:14:30 +0100 | [diff] [blame] | 128 | break; |
| 129 | |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 130 | vnt_beacon_make(priv, priv->vif); |
Malcolm Priestley | f31a67a | 2014-06-25 21:14:30 +0100 | [diff] [blame] | 131 | |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 132 | vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX); |
Malcolm Priestley | f31a67a | 2014-06-25 21:14:30 +0100 | [diff] [blame] | 133 | |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 134 | break; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 135 | |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 136 | case WLAN_CMD_SETPOWER_START: |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 137 | |
Malcolm Priestley | 8b84c1d | 2014-07-20 15:33:19 +0100 | [diff] [blame] | 138 | vnt_rf_setpower(priv, priv->current_rate, |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 139 | priv->hw->conf.chandef.chan->hw_value); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 140 | |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 141 | break; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 142 | |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 143 | case WLAN_CMD_CHANGE_ANTENNA_START: |
Malcolm Priestley | f7f0485 | 2014-07-12 07:53:48 +0100 | [diff] [blame] | 144 | dev_dbg(&priv->usb->dev, "Change from Antenna%d to", |
Malcolm Priestley | 2044dbd | 2014-07-19 12:30:16 +0100 | [diff] [blame] | 145 | priv->rx_antenna_sel); |
Malcolm Priestley | cf07bb8 | 2014-07-12 07:53:42 +0100 | [diff] [blame] | 146 | |
Malcolm Priestley | 2044dbd | 2014-07-19 12:30:16 +0100 | [diff] [blame] | 147 | if (priv->rx_antenna_sel == 0) { |
| 148 | priv->rx_antenna_sel = 1; |
| 149 | if (priv->tx_rx_ant_inv == true) |
Malcolm Priestley | 41868bf | 2014-07-16 22:21:52 +0100 | [diff] [blame] | 150 | vnt_set_antenna_mode(priv, ANT_RXA); |
Nandini Hanumanthagowda | cab086d | 2013-11-12 23:05:35 +0530 | [diff] [blame] | 151 | else |
Malcolm Priestley | 41868bf | 2014-07-16 22:21:52 +0100 | [diff] [blame] | 152 | vnt_set_antenna_mode(priv, ANT_RXB); |
Nandini Hanumanthagowda | cab086d | 2013-11-12 23:05:35 +0530 | [diff] [blame] | 153 | } else { |
Malcolm Priestley | 2044dbd | 2014-07-19 12:30:16 +0100 | [diff] [blame] | 154 | priv->rx_antenna_sel = 0; |
| 155 | if (priv->tx_rx_ant_inv == true) |
Malcolm Priestley | 41868bf | 2014-07-16 22:21:52 +0100 | [diff] [blame] | 156 | vnt_set_antenna_mode(priv, ANT_RXB); |
Nandini Hanumanthagowda | cab086d | 2013-11-12 23:05:35 +0530 | [diff] [blame] | 157 | else |
Malcolm Priestley | 41868bf | 2014-07-16 22:21:52 +0100 | [diff] [blame] | 158 | vnt_set_antenna_mode(priv, ANT_RXA); |
Nandini Hanumanthagowda | cab086d | 2013-11-12 23:05:35 +0530 | [diff] [blame] | 159 | } |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 160 | break; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 161 | |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 162 | default: |
Nandini Hanumanthagowda | 97d59f8 | 2013-11-12 23:05:36 +0530 | [diff] [blame] | 163 | break; |
Malcolm Priestley | a83a859 | 2014-07-13 10:42:53 +0100 | [diff] [blame] | 164 | } |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 165 | |
Malcolm Priestley | 60cecd2 | 2014-07-13 10:42:47 +0100 | [diff] [blame] | 166 | vnt_cmd_complete(priv); |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 167 | } |
| 168 | |
Malcolm Priestley | 57981a6 | 2014-07-13 10:42:50 +0100 | [diff] [blame] | 169 | int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd command) |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 170 | { |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 171 | |
Malcolm Priestley | 33a60b8 | 2014-07-13 10:42:45 +0100 | [diff] [blame] | 172 | if (priv->free_cmd_queue == 0) |
Nandini Hanumanthagowda | 820c9b1 | 2013-11-12 23:05:37 +0530 | [diff] [blame] | 173 | return false; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 174 | |
Malcolm Priestley | 33a60b8 | 2014-07-13 10:42:45 +0100 | [diff] [blame] | 175 | priv->cmd_queue[priv->cmd_enqueue_idx] = command; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 176 | |
Malcolm Priestley | 33a60b8 | 2014-07-13 10:42:45 +0100 | [diff] [blame] | 177 | ADD_ONE_WITH_WRAP_AROUND(priv->cmd_enqueue_idx, CMD_Q_SIZE); |
| 178 | priv->free_cmd_queue--; |
Malcolm Priestley | f7e9ed4 | 2014-07-12 07:53:46 +0100 | [diff] [blame] | 179 | |
Malcolm Priestley | 33a60b8 | 2014-07-13 10:42:45 +0100 | [diff] [blame] | 180 | if (priv->cmd_running == false) |
Malcolm Priestley | 60cecd2 | 2014-07-13 10:42:47 +0100 | [diff] [blame] | 181 | vnt_cmd_complete(priv); |
Nandini Hanumanthagowda | 566597a | 2013-11-12 23:05:30 +0530 | [diff] [blame] | 182 | |
Nandini Hanumanthagowda | 820c9b1 | 2013-11-12 23:05:37 +0530 | [diff] [blame] | 183 | return true; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 184 | |
| 185 | } |
| 186 | |
Malcolm Priestley | 68cc161 | 2014-07-13 10:42:51 +0100 | [diff] [blame] | 187 | void vnt_reset_command_timer(struct vnt_private *priv) |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 188 | { |
Malcolm Priestley | 33a60b8 | 2014-07-13 10:42:45 +0100 | [diff] [blame] | 189 | priv->free_cmd_queue = CMD_Q_SIZE; |
| 190 | priv->cmd_dequeue_idx = 0; |
| 191 | priv->cmd_enqueue_idx = 0; |
Malcolm Priestley | ad74e91 | 2014-07-13 10:42:42 +0100 | [diff] [blame] | 192 | priv->command_state = WLAN_CMD_IDLE; |
Malcolm Priestley | 33a60b8 | 2014-07-13 10:42:45 +0100 | [diff] [blame] | 193 | priv->cmd_running = false; |
Forest Bond | 92b9679 | 2009-06-13 07:38:31 -0400 | [diff] [blame] | 194 | } |