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

rsi_91x_core.c (13084B)


      1/*
      2 * Copyright (c) 2014 Redpine Signals Inc.
      3 *
      4 * Permission to use, copy, modify, and/or distribute this software for any
      5 * purpose with or without fee is hereby granted, provided that the above
      6 * copyright notice and this permission notice appear in all copies.
      7 *
      8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15 */
     16
     17#include "rsi_mgmt.h"
     18#include "rsi_common.h"
     19#include "rsi_hal.h"
     20#include "rsi_coex.h"
     21
     22/**
     23 * rsi_determine_min_weight_queue() - This function determines the queue with
     24 *				      the min weight.
     25 * @common: Pointer to the driver private structure.
     26 *
     27 * Return: q_num: Corresponding queue number.
     28 */
     29static u8 rsi_determine_min_weight_queue(struct rsi_common *common)
     30{
     31	struct wmm_qinfo *tx_qinfo = common->tx_qinfo;
     32	u32 q_len = 0;
     33	u8 ii = 0;
     34
     35	for (ii = 0; ii < NUM_EDCA_QUEUES; ii++) {
     36		q_len = skb_queue_len(&common->tx_queue[ii]);
     37		if ((tx_qinfo[ii].pkt_contended) && q_len) {
     38			common->min_weight = tx_qinfo[ii].weight;
     39			break;
     40		}
     41	}
     42	return ii;
     43}
     44
     45/**
     46 * rsi_recalculate_weights() - This function recalculates the weights
     47 *			       corresponding to each queue.
     48 * @common: Pointer to the driver private structure.
     49 *
     50 * Return: recontend_queue bool variable
     51 */
     52static bool rsi_recalculate_weights(struct rsi_common *common)
     53{
     54	struct wmm_qinfo *tx_qinfo = common->tx_qinfo;
     55	bool recontend_queue = false;
     56	u8 ii = 0;
     57	u32 q_len = 0;
     58
     59	for (ii = 0; ii < NUM_EDCA_QUEUES; ii++) {
     60		q_len = skb_queue_len(&common->tx_queue[ii]);
     61		/* Check for the need of contention */
     62		if (q_len) {
     63			if (tx_qinfo[ii].pkt_contended) {
     64				tx_qinfo[ii].weight =
     65				((tx_qinfo[ii].weight > common->min_weight) ?
     66				 tx_qinfo[ii].weight - common->min_weight : 0);
     67			} else {
     68				tx_qinfo[ii].pkt_contended = 1;
     69				tx_qinfo[ii].weight = tx_qinfo[ii].wme_params;
     70				recontend_queue = true;
     71			}
     72		} else { /* No packets so no contention */
     73			tx_qinfo[ii].weight = 0;
     74			tx_qinfo[ii].pkt_contended = 0;
     75		}
     76	}
     77
     78	return recontend_queue;
     79}
     80
     81/**
     82 * rsi_get_num_pkts_dequeue() - This function determines the number of
     83 *		                packets to be dequeued based on the number
     84 *			        of bytes calculated using txop.
     85 *
     86 * @common: Pointer to the driver private structure.
     87 * @q_num: the queue from which pkts have to be dequeued
     88 *
     89 * Return: pkt_num: Number of pkts to be dequeued.
     90 */
     91static u32 rsi_get_num_pkts_dequeue(struct rsi_common *common, u8 q_num)
     92{
     93	struct rsi_hw *adapter = common->priv;
     94	struct sk_buff *skb;
     95	u32 pkt_cnt = 0;
     96	s16 txop = common->tx_qinfo[q_num].txop * 32;
     97	__le16 r_txop;
     98	struct ieee80211_rate rate;
     99	struct ieee80211_hdr *wh;
    100	struct ieee80211_vif *vif;
    101
    102	rate.bitrate = RSI_RATE_MCS0 * 5 * 10; /* Convert to Kbps */
    103	if (q_num == VI_Q)
    104		txop = ((txop << 5) / 80);
    105
    106	if (skb_queue_len(&common->tx_queue[q_num]))
    107		skb = skb_peek(&common->tx_queue[q_num]);
    108	else
    109		return 0;
    110
    111	do {
    112		wh = (struct ieee80211_hdr *)skb->data;
    113		vif = rsi_get_vif(adapter, wh->addr2);
    114		r_txop = ieee80211_generic_frame_duration(adapter->hw,
    115							  vif,
    116							  common->band,
    117							  skb->len, &rate);
    118		txop -= le16_to_cpu(r_txop);
    119		pkt_cnt += 1;
    120		/*checking if pkts are still there*/
    121		if (skb_queue_len(&common->tx_queue[q_num]) - pkt_cnt)
    122			skb = skb->next;
    123		else
    124			break;
    125
    126	} while (txop > 0);
    127
    128	return pkt_cnt;
    129}
    130
    131/**
    132 * rsi_core_determine_hal_queue() - This function determines the queue from
    133 *				    which packet has to be dequeued.
    134 * @common: Pointer to the driver private structure.
    135 *
    136 * Return: q_num: Corresponding queue number on success.
    137 */
    138static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
    139{
    140	bool recontend_queue = false;
    141	u32 q_len = 0;
    142	u8 q_num = INVALID_QUEUE;
    143	u8 ii = 0;
    144
    145	if (skb_queue_len(&common->tx_queue[MGMT_BEACON_Q])) {
    146		q_num = MGMT_BEACON_Q;
    147		return q_num;
    148	}
    149	if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) {
    150		if (!common->mgmt_q_block)
    151			q_num = MGMT_SOFT_Q;
    152		return q_num;
    153	}
    154
    155	if (common->hw_data_qs_blocked)
    156		return q_num;
    157
    158	if (common->pkt_cnt != 0) {
    159		--common->pkt_cnt;
    160		return common->selected_qnum;
    161	}
    162
    163get_queue_num:
    164	recontend_queue = false;
    165
    166	q_num = rsi_determine_min_weight_queue(common);
    167
    168	ii = q_num;
    169
    170	/* Selecting the queue with least back off */
    171	for (; ii < NUM_EDCA_QUEUES; ii++) {
    172		q_len = skb_queue_len(&common->tx_queue[ii]);
    173		if (((common->tx_qinfo[ii].pkt_contended) &&
    174		     (common->tx_qinfo[ii].weight < common->min_weight)) &&
    175		      q_len) {
    176			common->min_weight = common->tx_qinfo[ii].weight;
    177			q_num = ii;
    178		}
    179	}
    180
    181	if (q_num < NUM_EDCA_QUEUES)
    182		common->tx_qinfo[q_num].pkt_contended = 0;
    183
    184	/* Adjust the back off values for all queues again */
    185	recontend_queue = rsi_recalculate_weights(common);
    186
    187	q_len = skb_queue_len(&common->tx_queue[q_num]);
    188	if (!q_len) {
    189		/* If any queues are freshly contended and the selected queue
    190		 * doesn't have any packets
    191		 * then get the queue number again with fresh values
    192		 */
    193		if (recontend_queue)
    194			goto get_queue_num;
    195
    196		return INVALID_QUEUE;
    197	}
    198
    199	common->selected_qnum = q_num;
    200	q_len = skb_queue_len(&common->tx_queue[q_num]);
    201
    202	if (q_num == VO_Q || q_num == VI_Q) {
    203		common->pkt_cnt = rsi_get_num_pkts_dequeue(common, q_num);
    204		common->pkt_cnt -= 1;
    205	}
    206
    207	return q_num;
    208}
    209
    210/**
    211 * rsi_core_queue_pkt() - This functions enqueues the packet to the queue
    212 *			  specified by the queue number.
    213 * @common: Pointer to the driver private structure.
    214 * @skb: Pointer to the socket buffer structure.
    215 *
    216 * Return: None.
    217 */
    218static void rsi_core_queue_pkt(struct rsi_common *common,
    219			       struct sk_buff *skb)
    220{
    221	u8 q_num = skb->priority;
    222	if (q_num >= NUM_SOFT_QUEUES) {
    223		rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n",
    224			__func__, q_num);
    225		dev_kfree_skb(skb);
    226		return;
    227	}
    228
    229	skb_queue_tail(&common->tx_queue[q_num], skb);
    230}
    231
    232/**
    233 * rsi_core_dequeue_pkt() - This functions dequeues the packet from the queue
    234 *			    specified by the queue number.
    235 * @common: Pointer to the driver private structure.
    236 * @q_num: Queue number.
    237 *
    238 * Return: Pointer to sk_buff structure.
    239 */
    240static struct sk_buff *rsi_core_dequeue_pkt(struct rsi_common *common,
    241					    u8 q_num)
    242{
    243	if (q_num >= NUM_SOFT_QUEUES) {
    244		rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n",
    245			__func__, q_num);
    246		return NULL;
    247	}
    248
    249	return skb_dequeue(&common->tx_queue[q_num]);
    250}
    251
    252/**
    253 * rsi_core_qos_processor() - This function is used to determine the wmm queue
    254 *			      based on the backoff procedure. Data packets are
    255 *			      dequeued from the selected hal queue and sent to
    256 *			      the below layers.
    257 * @common: Pointer to the driver private structure.
    258 *
    259 * Return: None.
    260 */
    261void rsi_core_qos_processor(struct rsi_common *common)
    262{
    263	struct rsi_hw *adapter = common->priv;
    264	struct sk_buff *skb;
    265	unsigned long tstamp_1, tstamp_2;
    266	u8 q_num;
    267	int status;
    268
    269	tstamp_1 = jiffies;
    270	while (1) {
    271		q_num = rsi_core_determine_hal_queue(common);
    272		rsi_dbg(DATA_TX_ZONE,
    273			"%s: Queue number = %d\n", __func__, q_num);
    274
    275		if (q_num == INVALID_QUEUE) {
    276			rsi_dbg(DATA_TX_ZONE, "%s: No More Pkt\n", __func__);
    277			break;
    278		}
    279		if (common->hibernate_resume)
    280			break;
    281
    282		mutex_lock(&common->tx_lock);
    283
    284		status = adapter->check_hw_queue_status(adapter, q_num);
    285		if ((status <= 0)) {
    286			mutex_unlock(&common->tx_lock);
    287			break;
    288		}
    289
    290		if ((q_num < MGMT_SOFT_Q) &&
    291		    ((skb_queue_len(&common->tx_queue[q_num])) <=
    292		      MIN_DATA_QUEUE_WATER_MARK)) {
    293			if (ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
    294				ieee80211_wake_queue(adapter->hw,
    295						     WME_AC(q_num));
    296		}
    297
    298		skb = rsi_core_dequeue_pkt(common, q_num);
    299		if (skb == NULL) {
    300			rsi_dbg(ERR_ZONE, "skb null\n");
    301			mutex_unlock(&common->tx_lock);
    302			break;
    303		}
    304		if (q_num == MGMT_BEACON_Q) {
    305			status = rsi_send_pkt_to_bus(common, skb);
    306			dev_kfree_skb(skb);
    307		} else {
    308#ifdef CONFIG_RSI_COEX
    309			if (common->coex_mode > 1) {
    310				status = rsi_coex_send_pkt(common, skb,
    311							   RSI_WLAN_Q);
    312			} else {
    313#endif
    314				if (q_num == MGMT_SOFT_Q)
    315					status = rsi_send_mgmt_pkt(common, skb);
    316				else
    317					status = rsi_send_data_pkt(common, skb);
    318#ifdef CONFIG_RSI_COEX
    319			}
    320#endif
    321		}
    322
    323		if (status) {
    324			mutex_unlock(&common->tx_lock);
    325			break;
    326		}
    327
    328		common->tx_stats.total_tx_pkt_send[q_num]++;
    329
    330		tstamp_2 = jiffies;
    331		mutex_unlock(&common->tx_lock);
    332
    333		if (time_after(tstamp_2, tstamp_1 + (300 * HZ) / 1000))
    334			schedule();
    335	}
    336}
    337
    338struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr)
    339{
    340	int i;
    341
    342	for (i = 0; i < common->max_stations; i++) {
    343		if (!common->stations[i].sta)
    344			continue;
    345		if (!(memcmp(common->stations[i].sta->addr,
    346			     mac_addr, ETH_ALEN)))
    347			return &common->stations[i];
    348	}
    349	return NULL;
    350}
    351
    352struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac)
    353{
    354	struct ieee80211_vif *vif;
    355	int i;
    356
    357	for (i = 0; i < RSI_MAX_VIFS; i++) {
    358		vif = adapter->vifs[i];
    359		if (!vif)
    360			continue;
    361		if (!memcmp(vif->addr, mac, ETH_ALEN))
    362			return vif;
    363	}
    364	return NULL;
    365}
    366
    367/**
    368 * rsi_core_xmit() - This function transmits the packets received from mac80211
    369 * @common: Pointer to the driver private structure.
    370 * @skb: Pointer to the socket buffer structure.
    371 *
    372 * Return: None.
    373 */
    374void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
    375{
    376	struct rsi_hw *adapter = common->priv;
    377	struct ieee80211_tx_info *info;
    378	struct skb_info *tx_params;
    379	struct ieee80211_hdr *wh = NULL;
    380	struct ieee80211_vif *vif;
    381	u8 q_num, tid = 0;
    382	struct rsi_sta *rsta = NULL;
    383
    384	if ((!skb) || (!skb->len)) {
    385		rsi_dbg(ERR_ZONE, "%s: Null skb/zero Length packet\n",
    386			__func__);
    387		goto xmit_fail;
    388	}
    389	if (common->fsm_state != FSM_MAC_INIT_DONE) {
    390		rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__);
    391		goto xmit_fail;
    392	}
    393	if (common->wow_flags & RSI_WOW_ENABLED) {
    394		rsi_dbg(ERR_ZONE,
    395			"%s: Blocking Tx_packets when WOWLAN is enabled\n",
    396			__func__);
    397		goto xmit_fail;
    398	}
    399
    400	info = IEEE80211_SKB_CB(skb);
    401	tx_params = (struct skb_info *)info->driver_data;
    402	/* info->driver_data and info->control part of union so make copy */
    403	tx_params->have_key = !!info->control.hw_key;
    404	wh = (struct ieee80211_hdr *)&skb->data[0];
    405	tx_params->sta_id = 0;
    406
    407	vif = rsi_get_vif(adapter, wh->addr2);
    408	if (!vif)
    409		goto xmit_fail;
    410	tx_params->vif = vif;
    411	tx_params->vap_id = ((struct vif_priv *)vif->drv_priv)->vap_id;
    412	if ((ieee80211_is_mgmt(wh->frame_control)) ||
    413	    (ieee80211_is_ctl(wh->frame_control)) ||
    414	    (ieee80211_is_qos_nullfunc(wh->frame_control))) {
    415		if (ieee80211_is_assoc_req(wh->frame_control) ||
    416		    ieee80211_is_reassoc_req(wh->frame_control)) {
    417			struct ieee80211_bss_conf *bss = &vif->bss_conf;
    418
    419			common->eapol4_confirm = false;
    420			rsi_hal_send_sta_notify_frame(common,
    421						      RSI_IFTYPE_STATION,
    422						      STA_CONNECTED, bss->bssid,
    423						      bss->qos, bss->aid, 0,
    424						      vif);
    425		}
    426
    427		q_num = MGMT_SOFT_Q;
    428		skb->priority = q_num;
    429
    430		if (rsi_prepare_mgmt_desc(common, skb)) {
    431			rsi_dbg(ERR_ZONE, "Failed to prepare desc\n");
    432			goto xmit_fail;
    433		}
    434	} else {
    435		if (ieee80211_is_data_qos(wh->frame_control)) {
    436			u8 *qos = ieee80211_get_qos_ctl(wh);
    437
    438			tid = *qos & IEEE80211_QOS_CTL_TID_MASK;
    439			skb->priority = TID_TO_WME_AC(tid);
    440		} else {
    441			tid = IEEE80211_NONQOS_TID;
    442			skb->priority = BE_Q;
    443		}
    444
    445		q_num = skb->priority;
    446		tx_params->tid = tid;
    447
    448		if (((vif->type == NL80211_IFTYPE_AP) ||
    449		     (vif->type == NL80211_IFTYPE_P2P_GO)) &&
    450		    (!is_broadcast_ether_addr(wh->addr1)) &&
    451		    (!is_multicast_ether_addr(wh->addr1))) {
    452			rsta = rsi_find_sta(common, wh->addr1);
    453			if (!rsta)
    454				goto xmit_fail;
    455			tx_params->sta_id = rsta->sta_id;
    456		} else {
    457			tx_params->sta_id = 0;
    458		}
    459
    460		if (rsta) {
    461			/* Start aggregation if not done for this tid */
    462			if (!rsta->start_tx_aggr[tid]) {
    463				rsta->start_tx_aggr[tid] = true;
    464				ieee80211_start_tx_ba_session(rsta->sta,
    465							      tid, 0);
    466			}
    467		}
    468		if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
    469			q_num = MGMT_SOFT_Q;
    470			skb->priority = q_num;
    471		}
    472		if (rsi_prepare_data_desc(common, skb)) {
    473			rsi_dbg(ERR_ZONE, "Failed to prepare data desc\n");
    474			goto xmit_fail;
    475		}
    476	}
    477
    478	if ((q_num < MGMT_SOFT_Q) &&
    479	    ((skb_queue_len(&common->tx_queue[q_num]) + 1) >=
    480	     DATA_QUEUE_WATER_MARK)) {
    481		rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__);
    482		if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
    483			ieee80211_stop_queue(adapter->hw, WME_AC(q_num));
    484		rsi_set_event(&common->tx_thread.event);
    485		goto xmit_fail;
    486	}
    487
    488	rsi_core_queue_pkt(common, skb);
    489	rsi_dbg(DATA_TX_ZONE, "%s: ===> Scheduling TX thread <===\n", __func__);
    490	rsi_set_event(&common->tx_thread.event);
    491
    492	return;
    493
    494xmit_fail:
    495	rsi_dbg(ERR_ZONE, "%s: Failed to queue packet\n", __func__);
    496	/* Dropping pkt here */
    497	ieee80211_free_txskb(common->priv->hw, skb);
    498}