cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

wcmd.c (3864B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
      4 * All rights reserved.
      5 *
      6 * Purpose: Handles the management command interface functions
      7 *
      8 * Author: Lyndon Chen
      9 *
     10 * Date: May 8, 2003
     11 *
     12 * Functions:
     13 *	vnt_cmd_complete - Command Complete function
     14 *	vnt_schedule_command - Push Command and wait Command Scheduler to do
     15 *	vnt_cmd_timer_wait- Call back timer
     16 *
     17 * Revision History:
     18 *
     19 */
     20
     21#include "device.h"
     22#include "mac.h"
     23#include "wcmd.h"
     24#include "power.h"
     25#include "usbpipe.h"
     26#include "rxtx.h"
     27#include "rf.h"
     28
     29static void vnt_cmd_timer_wait(struct vnt_private *priv, unsigned long msecs)
     30{
     31	schedule_delayed_work(&priv->run_command_work, msecs_to_jiffies(msecs));
     32}
     33
     34static u32 add_one_with_wrap_around(u32 var, u8 modulo)
     35{
     36	if (var >= (modulo - 1))
     37		var = 0;
     38	else
     39		var++;
     40	return var;
     41}
     42
     43static int vnt_cmd_complete(struct vnt_private *priv)
     44{
     45	priv->command_state = WLAN_CMD_IDLE;
     46	if (priv->free_cmd_queue == CMD_Q_SIZE) {
     47		/* Command Queue Empty */
     48		priv->cmd_running = false;
     49		return true;
     50	}
     51
     52	priv->command = priv->cmd_queue[priv->cmd_dequeue_idx];
     53
     54	priv->cmd_dequeue_idx = add_one_with_wrap_around(priv->cmd_dequeue_idx, CMD_Q_SIZE);
     55	priv->free_cmd_queue++;
     56	priv->cmd_running = true;
     57
     58	switch (priv->command) {
     59	case WLAN_CMD_INIT_MAC80211:
     60		priv->command_state = WLAN_CMD_INIT_MAC80211_START;
     61		break;
     62
     63	case WLAN_CMD_TBTT_WAKEUP:
     64		priv->command_state = WLAN_CMD_TBTT_WAKEUP_START;
     65		break;
     66
     67	case WLAN_CMD_BECON_SEND:
     68		priv->command_state = WLAN_CMD_BECON_SEND_START;
     69		break;
     70
     71	case WLAN_CMD_SETPOWER:
     72		priv->command_state = WLAN_CMD_SETPOWER_START;
     73		break;
     74
     75	case WLAN_CMD_CHANGE_ANTENNA:
     76		priv->command_state = WLAN_CMD_CHANGE_ANTENNA_START;
     77		break;
     78
     79	default:
     80		break;
     81	}
     82
     83	vnt_cmd_timer_wait(priv, 0);
     84
     85	return true;
     86}
     87
     88void vnt_run_command(struct work_struct *work)
     89{
     90	struct vnt_private *priv =
     91		container_of(work, struct vnt_private, run_command_work.work);
     92
     93	if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
     94		return;
     95
     96	if (!priv->cmd_running)
     97		return;
     98
     99	switch (priv->command_state) {
    100	case WLAN_CMD_INIT_MAC80211_START:
    101		if (priv->mac_hw)
    102			break;
    103
    104		dev_info(&priv->usb->dev, "Starting mac80211\n");
    105
    106		if (vnt_init(priv)) {
    107			/* If fail all ends TODO retry */
    108			dev_err(&priv->usb->dev, "failed to start\n");
    109			usb_set_intfdata(priv->intf, NULL);
    110			ieee80211_free_hw(priv->hw);
    111			return;
    112		}
    113
    114		break;
    115
    116	case WLAN_CMD_TBTT_WAKEUP_START:
    117		vnt_next_tbtt_wakeup(priv);
    118		break;
    119
    120	case WLAN_CMD_BECON_SEND_START:
    121		if (!priv->vif)
    122			break;
    123
    124		vnt_beacon_make(priv, priv->vif);
    125
    126		vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
    127
    128		break;
    129
    130	case WLAN_CMD_SETPOWER_START:
    131
    132		vnt_rf_setpower(priv, priv->hw->conf.chandef.chan);
    133
    134		break;
    135
    136	case WLAN_CMD_CHANGE_ANTENNA_START:
    137		dev_dbg(&priv->usb->dev, "Change from Antenna%d to",
    138			priv->rx_antenna_sel);
    139
    140		if (priv->rx_antenna_sel == 0) {
    141			priv->rx_antenna_sel = 1;
    142			if (priv->tx_rx_ant_inv)
    143				vnt_set_antenna_mode(priv, ANT_RXA);
    144			else
    145				vnt_set_antenna_mode(priv, ANT_RXB);
    146		} else {
    147			priv->rx_antenna_sel = 0;
    148			if (priv->tx_rx_ant_inv)
    149				vnt_set_antenna_mode(priv, ANT_RXB);
    150			else
    151				vnt_set_antenna_mode(priv, ANT_RXA);
    152		}
    153		break;
    154
    155	default:
    156		break;
    157	}
    158
    159	vnt_cmd_complete(priv);
    160}
    161
    162int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd command)
    163{
    164	if (priv->free_cmd_queue == 0)
    165		return false;
    166
    167	priv->cmd_queue[priv->cmd_enqueue_idx] = command;
    168
    169	priv->cmd_enqueue_idx = add_one_with_wrap_around(priv->cmd_enqueue_idx, CMD_Q_SIZE);
    170	priv->free_cmd_queue--;
    171
    172	if (!priv->cmd_running)
    173		vnt_cmd_complete(priv);
    174
    175	return true;
    176}
    177
    178void vnt_reset_command_timer(struct vnt_private *priv)
    179{
    180	priv->free_cmd_queue = CMD_Q_SIZE;
    181	priv->cmd_dequeue_idx = 0;
    182	priv->cmd_enqueue_idx = 0;
    183	priv->command_state = WLAN_CMD_IDLE;
    184	priv->cmd_running = false;
    185}