| .. | .. |
|---|
| 1 | | -/* |
|---|
| 2 | | - * aQuantia Corporation Network Driver |
|---|
| 3 | | - * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 2 | +/* Atlantic Network Driver |
|---|
| 4 | 3 | * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 7 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 4 | + * Copyright (C) 2014-2019 aQuantia Corporation |
|---|
| 5 | + * Copyright (C) 2019-2020 Marvell International Ltd. |
|---|
| 8 | 6 | */ |
|---|
| 9 | 7 | |
|---|
| 10 | 8 | /* File aq_hw_utils.c: Definitions of helper functions used across |
|---|
| .. | .. |
|---|
| 12 | 10 | */ |
|---|
| 13 | 11 | |
|---|
| 14 | 12 | #include "aq_hw_utils.h" |
|---|
| 13 | + |
|---|
| 14 | +#include <linux/io-64-nonatomic-lo-hi.h> |
|---|
| 15 | + |
|---|
| 15 | 16 | #include "aq_hw.h" |
|---|
| 16 | 17 | #include "aq_nic.h" |
|---|
| 17 | 18 | |
|---|
| .. | .. |
|---|
| 40 | 41 | { |
|---|
| 41 | 42 | u32 value = readl(hw->mmio + reg); |
|---|
| 42 | 43 | |
|---|
| 43 | | - if ((~0U) == value && |
|---|
| 44 | | - (~0U) == readl(hw->mmio + |
|---|
| 45 | | - hw->aq_nic_cfg->aq_hw_caps->hw_alive_check_addr)) |
|---|
| 44 | + if (value == U32_MAX && |
|---|
| 45 | + readl(hw->mmio + hw->aq_nic_cfg->aq_hw_caps->hw_alive_check_addr) == U32_MAX) |
|---|
| 46 | 46 | aq_utils_obj_set(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG); |
|---|
| 47 | 47 | |
|---|
| 48 | 48 | return value; |
|---|
| .. | .. |
|---|
| 51 | 51 | void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value) |
|---|
| 52 | 52 | { |
|---|
| 53 | 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 | + */ |
|---|
| 60 | +u64 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 | + |
|---|
| 76 | +void 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); |
|---|
| 54 | 82 | } |
|---|
| 55 | 83 | |
|---|
| 56 | 84 | int aq_hw_err_from_flags(struct aq_hw_s *hw) |
|---|
| .. | .. |
|---|
| 69 | 97 | err_exit: |
|---|
| 70 | 98 | return err; |
|---|
| 71 | 99 | } |
|---|
| 100 | + |
|---|
| 101 | +int 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 | + |
|---|
| 115 | +int 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 | +} |
|---|