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

aq_hw_utils.c (2600B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* Atlantic Network Driver
      3 *
      4 * Copyright (C) 2014-2019 aQuantia Corporation
      5 * Copyright (C) 2019-2020 Marvell International Ltd.
      6 */
      7
      8/* File aq_hw_utils.c: Definitions of helper functions used across
      9 * hardware layer.
     10 */
     11
     12#include "aq_hw_utils.h"
     13
     14#include <linux/io-64-nonatomic-lo-hi.h>
     15
     16#include "aq_hw.h"
     17#include "aq_nic.h"
     18
     19void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk,
     20			 u32 shift, u32 val)
     21{
     22	if (msk ^ ~0) {
     23		u32 reg_old, reg_new;
     24
     25		reg_old = aq_hw_read_reg(aq_hw, addr);
     26		reg_new = (reg_old & (~msk)) | (val << shift);
     27
     28		if (reg_old != reg_new)
     29			aq_hw_write_reg(aq_hw, addr, reg_new);
     30	} else {
     31		aq_hw_write_reg(aq_hw, addr, val);
     32	}
     33}
     34
     35u32 aq_hw_read_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, u32 shift)
     36{
     37	return ((aq_hw_read_reg(aq_hw, addr) & msk) >> shift);
     38}
     39
     40u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg)
     41{
     42	u32 value = readl(hw->mmio + reg);
     43
     44	if (value == U32_MAX &&
     45	    readl(hw->mmio + hw->aq_nic_cfg->aq_hw_caps->hw_alive_check_addr) == U32_MAX)
     46		aq_utils_obj_set(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG);
     47
     48	return value;
     49}
     50
     51void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value)
     52{
     53	writel(value, hw->mmio + reg);
     54}
     55
     56/* Most of 64-bit registers are in LSW, MSW form.
     57   Counters are normally implemented by HW as latched pairs:
     58   reading LSW first locks MSW, to overcome LSW overflow
     59 */
     60u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg)
     61{
     62	u64 value = U64_MAX;
     63
     64	if (hw->aq_nic_cfg->aq_hw_caps->op64bit)
     65		value = readq(hw->mmio + reg);
     66	else
     67		value = lo_hi_readq(hw->mmio + reg);
     68
     69	if (value == U64_MAX &&
     70	    readl(hw->mmio + hw->aq_nic_cfg->aq_hw_caps->hw_alive_check_addr) == U32_MAX)
     71		aq_utils_obj_set(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG);
     72
     73	return value;
     74}
     75
     76void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value)
     77{
     78	if (hw->aq_nic_cfg->aq_hw_caps->op64bit)
     79		writeq(value, hw->mmio + reg);
     80	else
     81		lo_hi_writeq(value, hw->mmio + reg);
     82}
     83
     84int aq_hw_err_from_flags(struct aq_hw_s *hw)
     85{
     86	int err = 0;
     87
     88	if (aq_utils_obj_test(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG)) {
     89		err = -ENXIO;
     90		goto err_exit;
     91	}
     92	if (aq_utils_obj_test(&hw->flags, AQ_HW_FLAG_ERR_HW)) {
     93		err = -EIO;
     94		goto err_exit;
     95	}
     96
     97err_exit:
     98	return err;
     99}
    100
    101int aq_hw_num_tcs(struct aq_hw_s *hw)
    102{
    103	switch (hw->aq_nic_cfg->tc_mode) {
    104	case AQ_TC_MODE_8TCS:
    105		return 8;
    106	case AQ_TC_MODE_4TCS:
    107		return 4;
    108	default:
    109		break;
    110	}
    111
    112	return 1;
    113}
    114
    115int aq_hw_q_per_tc(struct aq_hw_s *hw)
    116{
    117	switch (hw->aq_nic_cfg->tc_mode) {
    118	case AQ_TC_MODE_8TCS:
    119		return 4;
    120	case AQ_TC_MODE_4TCS:
    121		return 8;
    122	default:
    123		return 4;
    124	}
    125}