Commit 8ce84271 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:
* access cfg via aq_nic_get_cfg() in aq_nic_start() and aq_nic_map_skb();
* call aq_nic_get_dev() just once in aq_nic_map_skb();
* move ring allocation/deallocation out of aq_vec_alloc()/aq_vec_free();
* add the missing aq_nic_deinit() in atl_resume_common();
* rename 'tcs' field to 'tcs_max' in aq_hw_caps_s to differentiate it from
  the 'tcs' field in aq_nic_cfg_s, which is used for the current number of
  TCs;
* update _TC_MAX defines to the actual number of supported TCs;
* move tx_tc_mode register defines slightly higher (just to keep the order
  of definitions);
* separate variables for TX/RX buff_size in hw_atl*_hw_qos_set();
* use AQ_HW_*_TC instead of hardcoded magic numbers;
* actually use the 'ret' value in aq_mdo_add_secy();

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 59b8d277
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ struct aq_hw_caps_s {
	u32 mac_regs_count;
	u32 hw_alive_check_addr;
	u8 msix_irqs;
	u8 tcs;
	u8 tcs_max;
	u8 rxd_alignment;
	u8 rxd_size;
	u8 txd_alignment;
@@ -120,6 +120,8 @@ struct aq_stats_s {

#define AQ_HW_MULTICAST_ADDRESS_MAX     32U

#define AQ_HW_PTP_TC                    2U

#define AQ_HW_LED_BLINK    0x2U
#define AQ_HW_LED_DEFAULT  0x0U

+1 −1
Original line number Diff line number Diff line
@@ -478,7 +478,7 @@ static int aq_mdo_add_secy(struct macsec_context *ctx)

	set_bit(txsc_idx, &cfg->txsc_idx_busy);

	return 0;
	return ret;
}

static int aq_mdo_upd_secy(struct macsec_context *ctx)
+28 −15
Original line number Diff line number Diff line
@@ -399,9 +399,15 @@ int aq_nic_init(struct aq_nic_s *self)
		err = aq_phy_init(self->aq_hw);
	}

	for (i = 0U, aq_vec = self->aq_vec[0];
		self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
	for (i = 0U; i < self->aq_vecs; i++) {
		aq_vec = self->aq_vec[i];
		err = aq_vec_ring_alloc(aq_vec, self, i,
					aq_nic_get_cfg(self));
		if (err)
			goto err_exit;

		aq_vec_init(aq_vec, self->aq_hw_ops, self->aq_hw);
	}

	err = aq_ptp_init(self, self->irqvecs - 1);
	if (err < 0)
@@ -424,9 +430,12 @@ err_exit:
int aq_nic_start(struct aq_nic_s *self)
{
	struct aq_vec_s *aq_vec = NULL;
	struct aq_nic_cfg_s *cfg;
	unsigned int i = 0U;
	int err = 0;

	cfg = aq_nic_get_cfg(self);

	err = self->aq_hw_ops->hw_multicast_list_set(self->aq_hw,
						     self->mc_list.ar,
						     self->mc_list.count);
@@ -464,7 +473,7 @@ int aq_nic_start(struct aq_nic_s *self)
	timer_setup(&self->service_timer, aq_nic_service_timer_cb, 0);
	aq_nic_service_timer_cb(&self->service_timer);

	if (self->aq_nic_cfg.is_polling) {
	if (cfg->is_polling) {
		timer_setup(&self->polling_timer, aq_nic_polling_timer_cb, 0);
		mod_timer(&self->polling_timer, jiffies +
			  AQ_CFG_POLLING_TIMER_INTERVAL);
@@ -482,16 +491,16 @@ int aq_nic_start(struct aq_nic_s *self)
		if (err < 0)
			goto err_exit;

		if (self->aq_nic_cfg.link_irq_vec) {
		if (cfg->link_irq_vec) {
			int irqvec = pci_irq_vector(self->pdev,
						   self->aq_nic_cfg.link_irq_vec);
						    cfg->link_irq_vec);
			err = request_threaded_irq(irqvec, NULL,
						   aq_linkstate_threaded_isr,
						   IRQF_SHARED | IRQF_ONESHOT,
						   self->ndev->name, self);
			if (err < 0)
				goto err_exit;
			self->msix_entry_mask |= (1 << self->aq_nic_cfg.link_irq_vec);
			self->msix_entry_mask |= (1 << cfg->link_irq_vec);
		}

		err = self->aq_hw_ops->hw_irq_enable(self->aq_hw,
@@ -518,6 +527,8 @@ unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
			    struct aq_ring_s *ring)
{
	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(self);
	struct device *dev = aq_nic_get_dev(self);
	struct aq_ring_buff_s *first = NULL;
	u8 ipver = ip_hdr(skb)->version;
	struct aq_ring_buff_s *dx_buff;
@@ -559,7 +570,7 @@ unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
		need_context_tag = true;
	}

	if (self->aq_nic_cfg.is_vlan_tx_insert && skb_vlan_tag_present(skb)) {
	if (cfg->is_vlan_tx_insert && skb_vlan_tag_present(skb)) {
		dx_buff->vlan_tx_tag = skb_vlan_tag_get(skb);
		dx_buff->len_pkt = skb->len;
		dx_buff->is_vlan = 1U;
@@ -574,12 +585,12 @@ unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
	}

	dx_buff->len = skb_headlen(skb);
	dx_buff->pa = dma_map_single(aq_nic_get_dev(self),
	dx_buff->pa = dma_map_single(dev,
				     skb->data,
				     dx_buff->len,
				     DMA_TO_DEVICE);

	if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) {
	if (unlikely(dma_mapping_error(dev, dx_buff->pa))) {
		ret = 0;
		goto exit;
	}
@@ -611,13 +622,13 @@ unsigned int aq_nic_map_skb(struct aq_nic_s *self, struct sk_buff *skb,
			else
				buff_size = frag_len;

			frag_pa = skb_frag_dma_map(aq_nic_get_dev(self),
			frag_pa = skb_frag_dma_map(dev,
						   frag,
						   buff_offset,
						   buff_size,
						   DMA_TO_DEVICE);

			if (unlikely(dma_mapping_error(aq_nic_get_dev(self),
			if (unlikely(dma_mapping_error(dev,
						       frag_pa)))
				goto mapping_error;

@@ -651,12 +662,12 @@ mapping_error:
		if (!(dx_buff->is_gso_tcp || dx_buff->is_gso_udp) &&
		    !dx_buff->is_vlan && dx_buff->pa) {
			if (unlikely(dx_buff->is_sop)) {
				dma_unmap_single(aq_nic_get_dev(self),
				dma_unmap_single(dev,
						 dx_buff->pa,
						 dx_buff->len,
						 DMA_TO_DEVICE);
			} else {
				dma_unmap_page(aq_nic_get_dev(self),
				dma_unmap_page(dev,
					       dx_buff->pa,
					       dx_buff->len,
					       DMA_TO_DEVICE);
@@ -1145,9 +1156,11 @@ void aq_nic_deinit(struct aq_nic_s *self, bool link_down)
	if (!self)
		goto err_exit;

	for (i = 0U, aq_vec = self->aq_vec[0];
		self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
	for (i = 0U; i < self->aq_vecs; i++) {
		aq_vec = self->aq_vec[i];
		aq_vec_deinit(aq_vec);
		aq_vec_ring_free(aq_vec);
	}

	aq_ptp_unregister(self);
	aq_ptp_ring_deinit(self);
+3 −0
Original line number Diff line number Diff line
@@ -431,6 +431,9 @@ static int atl_resume_common(struct device *dev, bool deep)
	netif_tx_start_all_queues(nic->ndev);

err_exit:
	if (ret < 0)
		aq_nic_deinit(nic, true);

	rtnl_unlock();

	return ret;
+31 −16
Original line number Diff line number Diff line
@@ -103,16 +103,11 @@ err_exit:
struct aq_vec_s *aq_vec_alloc(struct aq_nic_s *aq_nic, unsigned int idx,
			      struct aq_nic_cfg_s *aq_nic_cfg)
{
	struct aq_ring_s *ring = NULL;
	struct aq_vec_s *self = NULL;
	unsigned int i = 0U;
	int err = 0;

	self = kzalloc(sizeof(*self), GFP_KERNEL);
	if (!self) {
		err = -ENOMEM;
	if (!self)
		goto err_exit;
	}

	self->aq_nic = aq_nic;
	self->aq_ring_param.vec_idx = idx;
@@ -128,10 +123,19 @@ struct aq_vec_s *aq_vec_alloc(struct aq_nic_s *aq_nic, unsigned int idx,
	netif_napi_add(aq_nic_get_ndev(aq_nic), &self->napi,
		       aq_vec_poll, AQ_CFG_NAPI_WEIGHT);

err_exit:
	return self;
}

int aq_vec_ring_alloc(struct aq_vec_s *self, struct aq_nic_s *aq_nic,
		      unsigned int idx, struct aq_nic_cfg_s *aq_nic_cfg)
{
	struct aq_ring_s *ring = NULL;
	unsigned int i = 0U;
	int err = 0;

	for (i = 0; i < aq_nic_cfg->tcs; ++i) {
		unsigned int idx_ring = AQ_NIC_TCVEC2RING(self->nic,
						self->tx_rings,
						self->aq_ring_param.vec_idx);
		unsigned int idx_ring = AQ_NIC_TCVEC2RING(aq_nic, i, idx);

		ring = aq_ring_tx_alloc(&self->ring[i][AQ_VEC_TX_ID], aq_nic,
					idx_ring, aq_nic_cfg);
@@ -156,11 +160,11 @@ struct aq_vec_s *aq_vec_alloc(struct aq_nic_s *aq_nic, unsigned int idx,

err_exit:
	if (err < 0) {
		aq_vec_free(self);
		aq_vec_ring_free(self);
		self = NULL;
	}

	return self;
	return err;
}

int aq_vec_init(struct aq_vec_s *self, const struct aq_hw_ops *aq_hw_ops,
@@ -269,6 +273,18 @@ err_exit:;
}

void aq_vec_free(struct aq_vec_s *self)
{
	if (!self)
		goto err_exit;

	netif_napi_del(&self->napi);

	kfree(self);

err_exit:;
}

void aq_vec_ring_free(struct aq_vec_s *self)
{
	struct aq_ring_s *ring = NULL;
	unsigned int i = 0U;
@@ -279,13 +295,12 @@ void aq_vec_free(struct aq_vec_s *self)
	for (i = 0U, ring = self->ring[0];
		self->tx_rings > i; ++i, ring = self->ring[i]) {
		aq_ring_free(&ring[AQ_VEC_TX_ID]);
		if (i < self->rx_rings)
			aq_ring_free(&ring[AQ_VEC_RX_ID]);
	}

	netif_napi_del(&self->napi);

	kfree(self);

	self->tx_rings = 0;
	self->rx_rings = 0;
err_exit:;
}

Loading