diff options
author | Dmitry Bezrukov <dbezrukov@marvell.com> | 2020-05-22 11:19:39 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-05-23 00:08:28 +0300 |
commit | 0aa7bc3ee4652e0790f9b42c93c769b59b9f2308 (patch) | |
tree | 6fd3a6c835dafa5fd70fdec670bbb4d6b003cd8d /drivers/net/ethernet/aquantia/atlantic/hw_atl2 | |
parent | 593dd0fc202eed27de07c5df9ef24a3c00cf0c09 (diff) | |
download | linux-0aa7bc3ee4652e0790f9b42c93c769b59b9f2308.tar.xz |
net: atlantic: changes for multi-TC support
This patch contains the following changes:
* add cfg->is_ptp (used for PTP enable/disable switch, which
is described in more details below);
* add cfg->tc_mode (A1 supports 2 HW modes only);
* setup queue to TC mapping based on TC mode on A2;
* remove hw_tx_tc_mode_get / hw_rx_tc_mode_get hw_ops.
In the first generation of our hardware (A1), a whole traffic class is
consumed for PTP handling in FW (FW uses it to send the ptp data and to
send back timestamps).
The 'is_ptp' flag introduced in this patch will be used in to automatically
disable PTP when a conflicting configuration is detected, e.g. when
multiple TCs are enabled.
Signed-off-by: Dmitry Bezrukov <dbezrukov@marvell.com>
Co-developed-by: Mark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/aquantia/atlantic/hw_atl2')
-rw-r--r-- | drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c index ccdb74562270..a14118550882 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c @@ -91,16 +91,36 @@ static int hw_atl2_hw_reset(struct aq_hw_s *self) static int hw_atl2_hw_queue_to_tc_map_set(struct aq_hw_s *self) { - if (!hw_atl_rpb_rpf_rx_traf_class_mode_get(self)) { - aq_hw_write_reg(self, HW_ATL2_RX_Q_TC_MAP_ADR(0), 0x11110000); - aq_hw_write_reg(self, HW_ATL2_RX_Q_TC_MAP_ADR(8), 0x33332222); - aq_hw_write_reg(self, HW_ATL2_RX_Q_TC_MAP_ADR(16), 0x55554444); - aq_hw_write_reg(self, HW_ATL2_RX_Q_TC_MAP_ADR(24), 0x77776666); - } else { - aq_hw_write_reg(self, HW_ATL2_RX_Q_TC_MAP_ADR(0), 0x00000000); - aq_hw_write_reg(self, HW_ATL2_RX_Q_TC_MAP_ADR(8), 0x11111111); - aq_hw_write_reg(self, HW_ATL2_RX_Q_TC_MAP_ADR(16), 0x22222222); - aq_hw_write_reg(self, HW_ATL2_RX_Q_TC_MAP_ADR(24), 0x33333333); + struct aq_nic_cfg_s *cfg = self->aq_nic_cfg; + unsigned int tcs, q_per_tc; + unsigned int tc, q; + u32 value = 0; + + switch (cfg->tc_mode) { + case AQ_TC_MODE_8TCS: + tcs = 8; + q_per_tc = 4; + break; + case AQ_TC_MODE_4TCS: + tcs = 4; + q_per_tc = 8; + break; + default: + return -EINVAL; + } + + for (tc = 0; tc != tcs; tc++) { + unsigned int tc_q_offset = tc * q_per_tc; + + for (q = tc_q_offset; q != tc_q_offset + q_per_tc; q++) + value |= tc << HW_ATL2_RX_Q_TC_MAP_SHIFT(q); + + if (HW_ATL2_RX_Q_TC_MAP_ADR(q) != + HW_ATL2_RX_Q_TC_MAP_ADR(q - 1)) { + aq_hw_write_reg(self, HW_ATL2_RX_Q_TC_MAP_ADR(q - 1), + value); + value = 0; + } } return aq_hw_err_from_flags(self); |