Commit 43c670c8 authored by Igor Russkikh's avatar Igor Russkikh Committed by David S. Miller
Browse files

net: atlantic: A2 ingress / egress hw configuration



Chip generations are mostly compatible register-wise, but there are still
some differences. Therefore we've made some of first generation (A1) code
non-static to re-use it where possible.

Some pieces are A2 specific, in which case we redefine/extend such APIs.

Signed-off-by: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarMark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e54dcf4b
Loading
Loading
Loading
Loading
+22 −32
Original line number Diff line number Diff line
@@ -251,9 +251,10 @@ err_exit:
	return err;
}

static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
			     struct aq_nic_cfg_s *aq_nic_cfg)
{
	u64 rxcsum = !!(aq_nic_cfg->features & NETIF_F_RXCSUM);
	unsigned int i;

	/* TX checksums offloads*/
@@ -261,10 +262,8 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
	hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1);

	/* RX checksums offloads*/
	hw_atl_rpo_ipv4header_crc_offload_en_set(self, !!(aq_nic_cfg->features &
						 NETIF_F_RXCSUM));
	hw_atl_rpo_tcp_udp_crc_offload_en_set(self, !!(aq_nic_cfg->features &
					      NETIF_F_RXCSUM));
	hw_atl_rpo_ipv4header_crc_offload_en_set(self, rxcsum);
	hw_atl_rpo_tcp_udp_crc_offload_en_set(self, rxcsum);

	/* LSO offloads*/
	hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
@@ -384,7 +383,7 @@ static int hw_atl_b0_hw_init_rx_path(struct aq_hw_s *self)
	return aq_hw_err_from_flags(self);
}

static int hw_atl_b0_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr)
int hw_atl_b0_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr)
{
	unsigned int h = 0U;
	unsigned int l = 0U;
@@ -479,16 +478,14 @@ err_exit:
	return err;
}

static int hw_atl_b0_hw_ring_tx_start(struct aq_hw_s *self,
				      struct aq_ring_s *ring)
int hw_atl_b0_hw_ring_tx_start(struct aq_hw_s *self, struct aq_ring_s *ring)
{
	hw_atl_tdm_tx_desc_en_set(self, 1, ring->idx);

	return aq_hw_err_from_flags(self);
}

static int hw_atl_b0_hw_ring_rx_start(struct aq_hw_s *self,
				      struct aq_ring_s *ring)
int hw_atl_b0_hw_ring_rx_start(struct aq_hw_s *self, struct aq_ring_s *ring)
{
	hw_atl_rdm_rx_desc_en_set(self, 1, ring->idx);

@@ -511,8 +508,7 @@ static int hw_atl_b0_hw_tx_ring_tail_update(struct aq_hw_s *self,
	return 0;
}

static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self,
				     struct aq_ring_s *ring,
int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self, struct aq_ring_s *ring,
			      unsigned int frags)
{
	struct aq_ring_buff_s *buff = NULL;
@@ -600,8 +596,7 @@ static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self,
	return aq_hw_err_from_flags(self);
}

static int hw_atl_b0_hw_ring_rx_init(struct aq_hw_s *self,
				     struct aq_ring_s *aq_ring,
int hw_atl_b0_hw_ring_rx_init(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
			      struct aq_ring_param_s *aq_ring_param)
{
	u32 dma_desc_addr_msw = (u32)(((u64)aq_ring->dx_ring_pa) >> 32);
@@ -643,8 +638,7 @@ static int hw_atl_b0_hw_ring_rx_init(struct aq_hw_s *self,
	return aq_hw_err_from_flags(self);
}

static int hw_atl_b0_hw_ring_tx_init(struct aq_hw_s *self,
				     struct aq_ring_s *aq_ring,
int hw_atl_b0_hw_ring_tx_init(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
			      struct aq_ring_param_s *aq_ring_param)
{
	u32 dma_desc_msw_addr = (u32)(((u64)aq_ring->dx_ring_pa) >> 32);
@@ -673,8 +667,7 @@ static int hw_atl_b0_hw_ring_tx_init(struct aq_hw_s *self,
	return aq_hw_err_from_flags(self);
}

static int hw_atl_b0_hw_ring_rx_fill(struct aq_hw_s *self,
				     struct aq_ring_s *ring,
int hw_atl_b0_hw_ring_rx_fill(struct aq_hw_s *self, struct aq_ring_s *ring,
			      unsigned int sw_tail_old)
{
	for (; sw_tail_old != ring->sw_tail;
@@ -734,7 +727,7 @@ static int hw_atl_b0_hw_ring_hwts_rx_receive(struct aq_hw_s *self,
	return aq_hw_err_from_flags(self);
}

static int hw_atl_b0_hw_ring_tx_head_update(struct aq_hw_s *self,
int hw_atl_b0_hw_ring_tx_head_update(struct aq_hw_s *self,
				     struct aq_ring_s *ring)
{
	unsigned int hw_head_;
@@ -753,8 +746,7 @@ err_exit:
	return err;
}

static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
					struct aq_ring_s *ring)
int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, struct aq_ring_s *ring)
{
	for (; ring->hw_head != ring->sw_tail;
		ring->hw_head = aq_ring_next_dx(ring, ring->hw_head)) {
@@ -1071,16 +1063,14 @@ err_exit:
	return err;
}

static int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self,
				     struct aq_ring_s *ring)
int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
{
	hw_atl_tdm_tx_desc_en_set(self, 0U, ring->idx);

	return aq_hw_err_from_flags(self);
}

static int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self,
				     struct aq_ring_s *ring)
int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
{
	hw_atl_rdm_rx_desc_en_set(self, 0U, ring->idx);

+23 −0
Original line number Diff line number Diff line
@@ -37,6 +37,29 @@ int hw_atl_b0_hw_rss_hash_set(struct aq_hw_s *self,
			      struct aq_rss_parameters *rss_params);
int hw_atl_b0_hw_rss_set(struct aq_hw_s *self,
			 struct aq_rss_parameters *rss_params);
int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
			     struct aq_nic_cfg_s *aq_nic_cfg);

int hw_atl_b0_hw_ring_tx_start(struct aq_hw_s *self, struct aq_ring_s *ring);
int hw_atl_b0_hw_ring_rx_start(struct aq_hw_s *self, struct aq_ring_s *ring);

int hw_atl_b0_hw_ring_rx_init(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
			      struct aq_ring_param_s *aq_ring_param);
int hw_atl_b0_hw_ring_rx_fill(struct aq_hw_s *self, struct aq_ring_s *ring,
			      unsigned int sw_tail_old);
int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, struct aq_ring_s *ring);

int hw_atl_b0_hw_ring_tx_init(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
			      struct aq_ring_param_s *aq_ring_param);
int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self, struct aq_ring_s *ring,
			      unsigned int frags);
int hw_atl_b0_hw_ring_tx_head_update(struct aq_hw_s *self,
				     struct aq_ring_s *ring);

int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring);
int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self, struct aq_ring_s *ring);

int hw_atl_b0_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr);

int hw_atl_b0_hw_start(struct aq_hw_s *self);

+103 −73
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@

#include "aq_hw.h"
#include "aq_hw_utils.h"
#include "aq_ring.h"
#include "aq_nic.h"
#include "hw_atl/hw_atl_b0.h"
#include "hw_atl/hw_atl_utils.h"
@@ -174,12 +175,6 @@ static int hw_atl2_hw_rss_set(struct aq_hw_s *self,
	return hw_atl_b0_hw_rss_set(self, rss_params);
}

static int hw_atl2_hw_offload_set(struct aq_hw_s *self,
				  struct aq_nic_cfg_s *aq_nic_cfg)
{
	return -EOPNOTSUPP;
}

static int hw_atl2_hw_init_tx_path(struct aq_hw_s *self)
{
	/* Tx TC/RSS number config */
@@ -359,11 +354,6 @@ static int hw_atl2_hw_init_rx_path(struct aq_hw_s *self)
	return aq_hw_err_from_flags(self);
}

static int hw_atl2_hw_mac_addr_set(struct aq_hw_s *self, u8 *mac_addr)
{
	return -EOPNOTSUPP;
}

static int hw_atl2_hw_init(struct aq_hw_s *self, u8 *mac_addr)
{
	static u32 aq_hw_atl2_igcr_table_[4][2] = {
@@ -390,7 +380,7 @@ static int hw_atl2_hw_init(struct aq_hw_s *self, u8 *mac_addr)
	hw_atl2_hw_init_tx_path(self);
	hw_atl2_hw_init_rx_path(self);

	hw_atl2_hw_mac_addr_set(self, mac_addr);
	hw_atl_b0_hw_mac_addr_set(self, mac_addr);

	self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk);
	self->aq_fw_ops->set_state(self, MPI_INIT);
@@ -424,61 +414,24 @@ static int hw_atl2_hw_init(struct aq_hw_s *self, u8 *mac_addr)
				   ((HW_ATL2_ERR_INT << 0x10) |
				    (1U << 0x17)), 0U);

	hw_atl2_hw_offload_set(self, aq_nic_cfg);
	hw_atl_b0_hw_offload_set(self, aq_nic_cfg);

err_exit:
	return err;
}

static int hw_atl2_hw_ring_tx_start(struct aq_hw_s *self,
				    struct aq_ring_s *ring)
{
	return -EOPNOTSUPP;
}

static int hw_atl2_hw_ring_rx_start(struct aq_hw_s *self,
				    struct aq_ring_s *ring)
{
	return -EOPNOTSUPP;
}

static int hw_atl2_hw_ring_tx_xmit(struct aq_hw_s *self,
				   struct aq_ring_s *ring,
				   unsigned int frags)
{
	return -EOPNOTSUPP;
}

static int hw_atl2_hw_ring_rx_init(struct aq_hw_s *self,
				   struct aq_ring_s *aq_ring,
				   struct aq_ring_param_s *aq_ring_param)
{
	return -EOPNOTSUPP;
	return hw_atl_b0_hw_ring_rx_init(self, aq_ring, aq_ring_param);
}

static int hw_atl2_hw_ring_tx_init(struct aq_hw_s *self,
				   struct aq_ring_s *aq_ring,
				   struct aq_ring_param_s *aq_ring_param)
{
	return -EOPNOTSUPP;
}

static int hw_atl2_hw_ring_rx_fill(struct aq_hw_s *self, struct aq_ring_s *ring,
				   unsigned int sw_tail_old)
{
	return -EOPNOTSUPP;
}

static int hw_atl2_hw_ring_tx_head_update(struct aq_hw_s *self,
					  struct aq_ring_s *ring)
{
	return -EOPNOTSUPP;
}

static int hw_atl2_hw_ring_rx_receive(struct aq_hw_s *self,
				      struct aq_ring_s *ring)
{
	return -EOPNOTSUPP;
	return hw_atl_b0_hw_ring_tx_init(self, aq_ring, aq_ring_param);
}

#define IS_FILTER_ENABLED(_F_) ((packet_filter & (_F_)) ? 1U : 0U)
@@ -536,24 +489,101 @@ err_exit:

static int hw_atl2_hw_interrupt_moderation_set(struct aq_hw_s *self)
{
	return -EOPNOTSUPP;
}
	unsigned int i = 0U;
	u32 itr_tx = 2U;
	u32 itr_rx = 2U;

	switch (self->aq_nic_cfg->itr) {
	case  AQ_CFG_INTERRUPT_MODERATION_ON:
	case  AQ_CFG_INTERRUPT_MODERATION_AUTO:
		hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 0U);
		hw_atl_tdm_tdm_intr_moder_en_set(self, 1U);
		hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 0U);
		hw_atl_rdm_rdm_intr_moder_en_set(self, 1U);

		if (self->aq_nic_cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON) {
			/* HW timers are in 2us units */
			int tx_max_timer = self->aq_nic_cfg->tx_itr / 2;
			int tx_min_timer = tx_max_timer / 2;

			int rx_max_timer = self->aq_nic_cfg->rx_itr / 2;
			int rx_min_timer = rx_max_timer / 2;

			tx_max_timer = min(HW_ATL2_INTR_MODER_MAX,
					   tx_max_timer);
			tx_min_timer = min(HW_ATL2_INTR_MODER_MIN,
					   tx_min_timer);
			rx_max_timer = min(HW_ATL2_INTR_MODER_MAX,
					   rx_max_timer);
			rx_min_timer = min(HW_ATL2_INTR_MODER_MIN,
					   rx_min_timer);

			itr_tx |= tx_min_timer << 0x8U;
			itr_tx |= tx_max_timer << 0x10U;
			itr_rx |= rx_min_timer << 0x8U;
			itr_rx |= rx_max_timer << 0x10U;
		} else {
			static unsigned int hw_atl2_timers_table_tx_[][2] = {
				{0xfU, 0xffU}, /* 10Gbit */
				{0xfU, 0x1ffU}, /* 5Gbit */
				{0xfU, 0x1ffU}, /* 5Gbit 5GS */
				{0xfU, 0x1ffU}, /* 2.5Gbit */
				{0xfU, 0x1ffU}, /* 1Gbit */
				{0xfU, 0x1ffU}, /* 100Mbit */
			};
			static unsigned int hw_atl2_timers_table_rx_[][2] = {
				{0x6U, 0x38U},/* 10Gbit */
				{0xCU, 0x70U},/* 5Gbit */
				{0xCU, 0x70U},/* 5Gbit 5GS */
				{0x18U, 0xE0U},/* 2.5Gbit */
				{0x30U, 0x80U},/* 1Gbit */
				{0x4U, 0x50U},/* 100Mbit */
			};
			unsigned int mbps = self->aq_link_status.mbps;
			unsigned int speed_index;

static int hw_atl2_hw_stop(struct aq_hw_s *self)
{
	hw_atl_b0_hw_irq_disable(self, HW_ATL2_INT_MASK);
			speed_index = hw_atl_utils_mbps_2_speed_index(mbps);

	return 0;
			/* Update user visible ITR settings */
			self->aq_nic_cfg->tx_itr = hw_atl2_timers_table_tx_
							[speed_index][1] * 2;
			self->aq_nic_cfg->rx_itr = hw_atl2_timers_table_rx_
							[speed_index][1] * 2;

			itr_tx |= hw_atl2_timers_table_tx_
						[speed_index][0] << 0x8U;
			itr_tx |= hw_atl2_timers_table_tx_
						[speed_index][1] << 0x10U;

			itr_rx |= hw_atl2_timers_table_rx_
						[speed_index][0] << 0x8U;
			itr_rx |= hw_atl2_timers_table_rx_
						[speed_index][1] << 0x10U;
		}
		break;
	case AQ_CFG_INTERRUPT_MODERATION_OFF:
		hw_atl_tdm_tx_desc_wr_wb_irq_en_set(self, 1U);
		hw_atl_tdm_tdm_intr_moder_en_set(self, 0U);
		hw_atl_rdm_rx_desc_wr_wb_irq_en_set(self, 1U);
		hw_atl_rdm_rdm_intr_moder_en_set(self, 0U);
		itr_tx = 0U;
		itr_rx = 0U;
		break;
	}

static int hw_atl2_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
{
	return -EOPNOTSUPP;
	for (i = HW_ATL2_RINGS_MAX; i--;) {
		hw_atl2_reg_tx_intr_moder_ctrl_set(self, itr_tx, i);
		hw_atl_reg_rx_intr_moder_ctrl_set(self, itr_rx, i);
	}

static int hw_atl2_hw_ring_rx_stop(struct aq_hw_s *self, struct aq_ring_s *ring)
	return aq_hw_err_from_flags(self);
}

static int hw_atl2_hw_stop(struct aq_hw_s *self)
{
	return -EOPNOTSUPP;
	hw_atl_b0_hw_irq_disable(self, HW_ATL2_INT_MASK);

	return 0;
}

static struct aq_stats_s *hw_atl2_utils_get_hw_stats(struct aq_hw_s *self)
@@ -619,21 +649,21 @@ static int hw_atl2_hw_vlan_ctrl(struct aq_hw_s *self, bool enable)
const struct aq_hw_ops hw_atl2_ops = {
	.hw_soft_reset        = hw_atl2_utils_soft_reset,
	.hw_prepare           = hw_atl2_utils_initfw,
	.hw_set_mac_address   = hw_atl2_hw_mac_addr_set,
	.hw_set_mac_address   = hw_atl_b0_hw_mac_addr_set,
	.hw_init              = hw_atl2_hw_init,
	.hw_reset             = hw_atl2_hw_reset,
	.hw_start             = hw_atl_b0_hw_start,
	.hw_ring_tx_start     = hw_atl2_hw_ring_tx_start,
	.hw_ring_tx_stop      = hw_atl2_hw_ring_tx_stop,
	.hw_ring_rx_start     = hw_atl2_hw_ring_rx_start,
	.hw_ring_rx_stop      = hw_atl2_hw_ring_rx_stop,
	.hw_ring_tx_start     = hw_atl_b0_hw_ring_tx_start,
	.hw_ring_tx_stop      = hw_atl_b0_hw_ring_tx_stop,
	.hw_ring_rx_start     = hw_atl_b0_hw_ring_rx_start,
	.hw_ring_rx_stop      = hw_atl_b0_hw_ring_rx_stop,
	.hw_stop              = hw_atl2_hw_stop,

	.hw_ring_tx_xmit         = hw_atl2_hw_ring_tx_xmit,
	.hw_ring_tx_head_update  = hw_atl2_hw_ring_tx_head_update,
	.hw_ring_tx_xmit         = hw_atl_b0_hw_ring_tx_xmit,
	.hw_ring_tx_head_update  = hw_atl_b0_hw_ring_tx_head_update,

	.hw_ring_rx_receive      = hw_atl2_hw_ring_rx_receive,
	.hw_ring_rx_fill         = hw_atl2_hw_ring_rx_fill,
	.hw_ring_rx_receive      = hw_atl_b0_hw_ring_rx_receive,
	.hw_ring_rx_fill         = hw_atl_b0_hw_ring_rx_fill,

	.hw_irq_enable           = hw_atl_b0_hw_irq_enable,
	.hw_irq_disable          = hw_atl_b0_hw_irq_disable,
@@ -650,5 +680,5 @@ const struct aq_hw_ops hw_atl2_ops = {
	.hw_rss_hash_set             = hw_atl_b0_hw_rss_hash_set,
	.hw_get_hw_stats             = hw_atl2_utils_get_hw_stats,
	.hw_get_fw_version           = hw_atl2_utils_get_fw_version,
	.hw_set_offload              = hw_atl2_hw_offload_set,
	.hw_set_offload              = hw_atl_b0_hw_offload_set,
};
+3 −0
Original line number Diff line number Diff line
@@ -34,6 +34,9 @@
#define HW_ATL2_TC_MAX 1U
#define HW_ATL2_RSS_MAX 8U

#define HW_ATL2_INTR_MODER_MAX  0x1FF
#define HW_ATL2_INTR_MODER_MIN  0xFF

#define HW_ATL2_MIN_RXD \
	(ALIGN(AQ_CFG_SKB_FRAGS_MAX + 1U, AQ_HW_RXD_MULTIPLE))
#define HW_ATL2_MIN_TXD \
+8 −0
Original line number Diff line number Diff line
@@ -68,6 +68,14 @@ void hw_atl2_tpb_tx_buf_clk_gate_en_set(struct aq_hw_s *aq_hw, u32 clk_gate_en)
			    clk_gate_en);
}

void hw_atl2_reg_tx_intr_moder_ctrl_set(struct aq_hw_s *aq_hw,
					u32 tx_intr_moderation_ctl,
					u32 queue)
{
	aq_hw_write_reg(aq_hw, HW_ATL2_TX_INTR_MODERATION_CTL_ADR(queue),
			tx_intr_moderation_ctl);
}

void hw_atl2_tps_tx_pkt_shed_tc_data_max_credit_set(struct aq_hw_s *aq_hw,
						    u32 max_credit,
						    u32 tc)
Loading