Commit 0aa7bc3e authored by Dmitry Bezrukov's avatar Dmitry Bezrukov Committed by David S. Miller
Browse files

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: default avatarDmitry Bezrukov <dbezrukov@marvell.com>
Co-developed-by: default avatarMark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: default avatarMark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 593dd0fc
Loading
Loading
Loading
Loading
+6 −4
Original line number Original line Diff line number Diff line
@@ -18,6 +18,12 @@
#define AQ_HW_MAC_COUNTER_HZ   312500000ll
#define AQ_HW_MAC_COUNTER_HZ   312500000ll
#define AQ_HW_PHY_COUNTER_HZ   160000000ll
#define AQ_HW_PHY_COUNTER_HZ   160000000ll


enum aq_tc_mode {
	AQ_TC_MODE_INVALID = -1,
	AQ_TC_MODE_8TCS,
	AQ_TC_MODE_4TCS,
};

#define AQ_RX_FIRST_LOC_FVLANID     0U
#define AQ_RX_FIRST_LOC_FVLANID     0U
#define AQ_RX_LAST_LOC_FVLANID	   15U
#define AQ_RX_LAST_LOC_FVLANID	   15U
#define AQ_RX_FIRST_LOC_FETHERT    16U
#define AQ_RX_FIRST_LOC_FETHERT    16U
@@ -281,10 +287,6 @@ struct aq_hw_ops {
	int (*hw_set_offload)(struct aq_hw_s *self,
	int (*hw_set_offload)(struct aq_hw_s *self,
			      struct aq_nic_cfg_s *aq_nic_cfg);
			      struct aq_nic_cfg_s *aq_nic_cfg);


	int (*hw_tx_tc_mode_get)(struct aq_hw_s *self, u32 *tc_mode);

	int (*hw_rx_tc_mode_get)(struct aq_hw_s *self, u32 *tc_mode);

	int (*hw_ring_hwts_rx_fill)(struct aq_hw_s *self,
	int (*hw_ring_hwts_rx_fill)(struct aq_hw_s *self,
				    struct aq_ring_s *aq_ring);
				    struct aq_ring_s *aq_ring);


+17 −9
Original line number Original line Diff line number Diff line
@@ -89,6 +89,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
	cfg->is_autoneg = AQ_CFG_IS_AUTONEG_DEF;
	cfg->is_autoneg = AQ_CFG_IS_AUTONEG_DEF;


	cfg->is_lro = AQ_CFG_IS_LRO_DEF;
	cfg->is_lro = AQ_CFG_IS_LRO_DEF;
	cfg->is_ptp = true;


	/*descriptors */
	/*descriptors */
	cfg->rxds = min(cfg->aq_hw_caps->rxds_max, AQ_CFG_RXDS_DEF);
	cfg->rxds = min(cfg->aq_hw_caps->rxds_max, AQ_CFG_RXDS_DEF);
@@ -122,6 +123,11 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
		cfg->vecs = 1U;
		cfg->vecs = 1U;
	}
	}


	if (cfg->vecs <= 4)
		cfg->tc_mode = AQ_TC_MODE_8TCS;
	else
		cfg->tc_mode = AQ_TC_MODE_4TCS;

	/* Check if we have enough vectors allocated for
	/* Check if we have enough vectors allocated for
	 * link status IRQ. If no - we'll know link state from
	 * link status IRQ. If no - we'll know link state from
	 * slower service task.
	 * slower service task.
@@ -409,6 +415,7 @@ int aq_nic_init(struct aq_nic_s *self)
		aq_vec_init(aq_vec, self->aq_hw_ops, self->aq_hw);
		aq_vec_init(aq_vec, self->aq_hw_ops, self->aq_hw);
	}
	}


	if (aq_nic_get_cfg(self)->is_ptp) {
		err = aq_ptp_init(self, self->irqvecs - 1);
		err = aq_ptp_init(self, self->irqvecs - 1);
		if (err < 0)
		if (err < 0)
			goto err_exit;
			goto err_exit;
@@ -420,6 +427,7 @@ int aq_nic_init(struct aq_nic_s *self)
		err = aq_ptp_ring_init(self);
		err = aq_ptp_ring_init(self);
		if (err < 0)
		if (err < 0)
			goto err_exit;
			goto err_exit;
	}


	netif_carrier_off(self->ndev);
	netif_carrier_off(self->ndev);


+2 −0
Original line number Original line Diff line number Diff line
@@ -59,6 +59,8 @@ struct aq_nic_cfg_s {
	bool is_polling;
	bool is_polling;
	bool is_rss;
	bool is_rss;
	bool is_lro;
	bool is_lro;
	bool is_ptp;
	enum aq_tc_mode tc_mode;
	u32 priv_flags;
	u32 priv_flags;
	u8  tcs;
	u8  tcs;
	struct aq_rss_parameters aq_rss;
	struct aq_rss_parameters aq_rss;
+13 −14
Original line number Original line Diff line number Diff line
@@ -945,26 +945,29 @@ void aq_ptp_ring_deinit(struct aq_nic_s *aq_nic)
#define PTP_4TC_RING_IDX            16
#define PTP_4TC_RING_IDX            16
#define PTP_HWST_RING_IDX           31
#define PTP_HWST_RING_IDX           31


/* Index must be 8 (8 TCs) or 16 (4 TCs).
 * It depends on Traffic Class mode.
 */
static unsigned int ptp_ring_idx(const enum aq_tc_mode tc_mode)
{
	if (tc_mode == AQ_TC_MODE_8TCS)
		return PTP_8TC_RING_IDX;

	return PTP_4TC_RING_IDX;
}

int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
{
{
	struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
	struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
	unsigned int tx_ring_idx, rx_ring_idx;
	unsigned int tx_ring_idx, rx_ring_idx;
	struct aq_ring_s *hwts;
	struct aq_ring_s *hwts;
	u32 tx_tc_mode, rx_tc_mode;
	struct aq_ring_s *ring;
	struct aq_ring_s *ring;
	int err;
	int err;


	if (!aq_ptp)
	if (!aq_ptp)
		return 0;
		return 0;


	/* Index must to be 8 (8 TCs) or 16 (4 TCs).
	tx_ring_idx = ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);
	 * It depends from Traffic Class mode.
	 */
	aq_nic->aq_hw_ops->hw_tx_tc_mode_get(aq_nic->aq_hw, &tx_tc_mode);
	if (tx_tc_mode == 0)
		tx_ring_idx = PTP_8TC_RING_IDX;
	else
		tx_ring_idx = PTP_4TC_RING_IDX;


	ring = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic,
	ring = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic,
				tx_ring_idx, &aq_nic->aq_nic_cfg);
				tx_ring_idx, &aq_nic->aq_nic_cfg);
@@ -973,11 +976,7 @@ int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
		goto err_exit;
		goto err_exit;
	}
	}


	aq_nic->aq_hw_ops->hw_rx_tc_mode_get(aq_nic->aq_hw, &rx_tc_mode);
	rx_ring_idx = ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);
	if (rx_tc_mode == 0)
		rx_ring_idx = PTP_8TC_RING_IDX;
	else
		rx_ring_idx = PTP_4TC_RING_IDX;


	ring = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic,
	ring = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic,
				rx_ring_idx, &aq_nic->aq_nic_cfg);
				rx_ring_idx, &aq_nic->aq_nic_cfg);
+7 −18
Original line number Original line Diff line number Diff line
@@ -131,13 +131,16 @@ static int hw_atl_b0_tc_ptp_set(struct aq_hw_s *self)


static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
{
{
	struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
	u32 tx_buff_size = HW_ATL_B0_TXBUF_MAX;
	u32 tx_buff_size = HW_ATL_B0_TXBUF_MAX;
	u32 rx_buff_size = HW_ATL_B0_RXBUF_MAX;
	u32 rx_buff_size = HW_ATL_B0_RXBUF_MAX;
	unsigned int i_priority = 0U;
	unsigned int i_priority = 0U;
	u32 tc = 0U;
	u32 tc = 0U;


	if (cfg->is_ptp) {
		tx_buff_size -= HW_ATL_B0_PTP_TXBUF_SIZE;
		tx_buff_size -= HW_ATL_B0_PTP_TXBUF_SIZE;
		rx_buff_size -= HW_ATL_B0_PTP_RXBUF_SIZE;
		rx_buff_size -= HW_ATL_B0_PTP_RXBUF_SIZE;
	}


	/* TPS Descriptor rate init */
	/* TPS Descriptor rate init */
	hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U);
	hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U);
@@ -180,6 +183,7 @@ static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)


	hw_atl_b0_set_fc(self, self->aq_nic_cfg->fc.req, tc);
	hw_atl_b0_set_fc(self, self->aq_nic_cfg->fc.req, tc);


	if (cfg->is_ptp)
		hw_atl_b0_tc_ptp_set(self);
		hw_atl_b0_tc_ptp_set(self);


	/* QoS 802.1p priority -> TC mapping */
	/* QoS 802.1p priority -> TC mapping */
@@ -1079,18 +1083,6 @@ int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
	return aq_hw_err_from_flags(self);
	return aq_hw_err_from_flags(self);
}
}


static int hw_atl_b0_tx_tc_mode_get(struct aq_hw_s *self, u32 *tc_mode)
{
	*tc_mode = hw_atl_tpb_tps_tx_tc_mode_get(self);
	return aq_hw_err_from_flags(self);
}

static int hw_atl_b0_rx_tc_mode_get(struct aq_hw_s *self, u32 *tc_mode)
{
	*tc_mode = hw_atl_rpb_rpf_rx_traf_class_mode_get(self);
	return aq_hw_err_from_flags(self);
}

#define get_ptp_ts_val_u64(self, indx) \
#define get_ptp_ts_val_u64(self, indx) \
	((u64)(hw_atl_pcs_ptp_clock_get(self, indx) & 0xffff))
	((u64)(hw_atl_pcs_ptp_clock_get(self, indx) & 0xffff))


@@ -1508,9 +1500,6 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
	.hw_get_hw_stats             = hw_atl_utils_get_hw_stats,
	.hw_get_hw_stats             = hw_atl_utils_get_hw_stats,
	.hw_get_fw_version           = hw_atl_utils_get_fw_version,
	.hw_get_fw_version           = hw_atl_utils_get_fw_version,


	.hw_tx_tc_mode_get       = hw_atl_b0_tx_tc_mode_get,
	.hw_rx_tc_mode_get       = hw_atl_b0_rx_tc_mode_get,

	.hw_ring_hwts_rx_fill        = hw_atl_b0_hw_ring_hwts_rx_fill,
	.hw_ring_hwts_rx_fill        = hw_atl_b0_hw_ring_hwts_rx_fill,
	.hw_ring_hwts_rx_receive     = hw_atl_b0_hw_ring_hwts_rx_receive,
	.hw_ring_hwts_rx_receive     = hw_atl_b0_hw_ring_hwts_rx_receive,


Loading