aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
diff options
context:
space:
mode:
authorDmitry Bezrukov <dbezrukov@marvell.com>2020-05-22 11:19:39 +0300
committerDavid S. Miller <davem@davemloft.net>2020-05-22 14:08:28 -0700
commit0aa7bc3ee4652e0790f9b42c93c769b59b9f2308 (patch)
tree6fd3a6c835dafa5fd70fdec670bbb4d6b003cd8d /drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
parentnet: atlantic: move PTP TC initialization to a separate function (diff)
downloadlinux-dev-0aa7bc3ee4652e0790f9b42c93c769b59b9f2308.tar.xz
linux-dev-0aa7bc3ee4652e0790f9b42c93c769b59b9f2308.zip
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/hw_atl2.c')
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c40
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);