[PATCH net v2 3/6] net:ethernet:aquantia: Workaround for HW checksum bug.

2017-08-28 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The hardware has the HW Checksum Offload bug when small
TCP patckets (with length <= 60 bytes) has wrong "checksum valid" bit.

The solution is - ignore checksum valid bit for small packets
(with length <= 60 bytes) and mark this as CHECKSUM_NONE to allow
network stack recalculate checksum itself.

Fixes: ccf9a5ed14be ("net: ethernet: aquantia: Atlantic A0 and B0 specific 
functions.")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 6 ++
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 6 ++
 2 files changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index faeb493..c5a02df 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -629,6 +629,12 @@ static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s 
*self,
buff->is_udp_cso = (is_err & 0x10U) ? 0 : 1;
else if (0x0U == (pkt_type & 0x1CU))
buff->is_tcp_cso = (is_err & 0x10U) ? 0 : 1;
+
+   /* Checksum offload workaround for small packets */
+   if (rxd_wb->pkt_len <= 60) {
+   buff->is_ip_cso = 0U;
+   buff->is_cso_err = 0U;
+   }
}
 
is_err &= ~0x18U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 1bceb73..21784cc 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -645,6 +645,12 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s 
*self,
buff->is_udp_cso = buff->is_cso_err ? 0U : 1U;
else if (0x0U == (pkt_type & 0x1CU))
buff->is_tcp_cso = buff->is_cso_err ? 0U : 1U;
+
+   /* Checksum offload workaround for small packets */
+   if (rxd_wb->pkt_len <= 60) {
+   buff->is_ip_cso = 0U;
+   buff->is_cso_err = 0U;
+   }
}
 
is_err &= ~0x18U;
-- 
2.7.4



[PATCH net v2 2/6] net:ethernet:aquantia: Fix for number of RSS queues.

2017-08-28 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The number of RSS queues should be not more than numbers of CPU.
Its does not make sense to increase perfomance, and also cause problems on
some motherboards.

Fixes: 94f6c9e4cdf6 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 08b7275..d6d8e70 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -103,6 +103,8 @@ int aq_nic_cfg_start(struct aq_nic_s *self)
else
cfg->vecs = 1U;
 
+   cfg->num_rss_queues = min(cfg->vecs, AQ_CFG_NUM_RSS_QUEUES_DEF);
+
cfg->irq_type = aq_pci_func_get_irq_type(self->aq_pci_func);
 
if ((cfg->irq_type == AQ_HW_IRQ_LEGACY) ||
-- 
2.7.4



[PATCH net v2 1/6] net:ethernet:aquantia: Extra spinlocks removed.

2017-08-28 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This patch removes datapath spinlocks which does not perform any
useful work.

Fixes: 6e70637f9f1e ("net: ethernet: aquantia: Add ring support code")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c   | 42 +++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c  |  1 -
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h |  1 -
 drivers/net/ethernet/aquantia/atlantic/aq_vec.c   | 11 ++
 4 files changed, 14 insertions(+), 41 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 9ee1c50..08b7275 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -597,14 +597,11 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
 }
 
 int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
-__releases(>lock)
-__acquires(>lock)
 {
struct aq_ring_s *ring = NULL;
unsigned int frags = 0U;
unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;
unsigned int tc = 0U;
-   unsigned int trys = AQ_CFG_LOCK_TRYS;
int err = NETDEV_TX_OK;
bool is_nic_in_bad_state;
 
@@ -628,36 +625,21 @@ __acquires(>lock)
goto err_exit;
}
 
-   do {
-   if (spin_trylock(>header.lock)) {
-   frags = aq_nic_map_skb(self, skb, ring);
-
-   if (likely(frags)) {
-   err = self->aq_hw_ops.hw_ring_tx_xmit(
-   self->aq_hw,
-   ring, frags);
-   if (err >= 0) {
-   if (aq_ring_avail_dx(ring) <
-   AQ_CFG_SKB_FRAGS_MAX + 1)
-   aq_nic_ndev_queue_stop(
-   self,
-   ring->idx);
-
-   ++ring->stats.tx.packets;
-   ring->stats.tx.bytes += skb->len;
-   }
-   } else {
-   err = NETDEV_TX_BUSY;
-   }
+   frags = aq_nic_map_skb(self, skb, ring);
 
-   spin_unlock(>header.lock);
-   break;
-   }
-   } while (--trys);
+   if (likely(frags)) {
+   err = self->aq_hw_ops.hw_ring_tx_xmit(self->aq_hw,
+ ring,
+ frags);
+   if (err >= 0) {
+   if (aq_ring_avail_dx(ring) < AQ_CFG_SKB_FRAGS_MAX + 1)
+   aq_nic_ndev_queue_stop(self, ring->idx);
 
-   if (!trys) {
+   ++ring->stats.tx.packets;
+   ring->stats.tx.bytes += skb->len;
+   }
+   } else {
err = NETDEV_TX_BUSY;
-   goto err_exit;
}
 
 err_exit:
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 9a08179..ec5579f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -101,7 +101,6 @@ int aq_ring_init(struct aq_ring_s *self)
self->hw_head = 0;
self->sw_head = 0;
self->sw_tail = 0;
-   spin_lock_init(>header.lock);
return 0;
 }
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
index f6012b3..e12bcdf 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
@@ -17,7 +17,6 @@
 #define AQ_DIMOF(_ARY_)  ARRAY_SIZE(_ARY_)
 
 struct aq_obj_s {
-   spinlock_t lock; /* spinlock for nic/rings processing */
atomic_t flags;
 };
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
index ad5b4d4d..fee446a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -34,8 +34,6 @@ struct aq_vec_s {
 #define AQ_VEC_RX_ID 1
 
 static int aq_vec_poll(struct napi_struct *napi, int budget)
-__releases(>lock)
-__acquires(>lock)
 {
struct aq_vec_s *self = container_of(napi, struct aq_vec_s, napi);
struct aq_ring_s *ring = NULL;
@@ -47,7 +45,7 @@ __acquires(>lock)
 
if (!self) {
err = -EINVAL;
-   } else if (spin_trylock(>header.lock)) {
+ 

[PATCH net v2 0/6] net:ethernet:aquantia: Atlantic driver Update 2017-08-23

2017-08-28 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This series contains updates for aQuantia Atlantic driver.

It has bugfixes and some improvements.

Changes in v2:
 - "MCP state change" fix removed (will be sent as
a separate fix after further investigation.)

Igor Russkikh (1):
  net:ethernet:aquantia: Fix for multicast filter handling.

Pavel Belous (5):
  net:ethernet:aquantia: Extra spinlocks removed.
  net:ethernet:aquantia: Fix for number of RSS queues.
  net:ethernet:aquantia: Workaround for HW checksum bug.
  net:ethernet:aquantia: Fix for incorrect speed index.
  net:ethernet:aquantia: Show info message if bad firmware version
detected.

 drivers/net/ethernet/aquantia/atlantic/aq_hw.h |  3 +-
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 92 +++---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c   |  1 -
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h  |  1 -
 drivers/net/ethernet/aquantia/atlantic/aq_vec.c| 11 +--
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |  6 ++
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |  6 ++
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c| 10 ++-
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h|  3 +-
 9 files changed, 68 insertions(+), 65 deletions(-)

-- 
2.7.4



[PATCH net v2 6/6] net:ethernet:aquantia: Show info message if bad firmware version detected.

2017-08-28 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We should inform user about wrong firmware version
by printing message in dmesg.

Fixes: 3d2ff7eebe26 ("net: ethernet: aquantia: Atlantic hardware abstraction 
layer")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index 7a1332e..4f5ec9a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -141,6 +141,12 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
 
err = hw_atl_utils_ver_match(aq_hw_caps->fw_ver_expected,
 aq_hw_read_reg(self, 0x18U));
+
+   if (err < 0)
+   pr_err("%s: Bad FW version detected: expected=%x, actual=%x\n",
+  AQ_CFG_DRV_NAME,
+  aq_hw_caps->fw_ver_expected,
+  aq_hw_read_reg(self, 0x18U));
return err;
 }
 
-- 
2.7.4



[PATCH net v2 5/6] net:ethernet:aquantia: Fix for multicast filter handling.

2017-08-28 Thread Pavel Belous
From: Igor Russkikh 

Since the HW supports up to 32 multicast filters we should
track count of multicast filters to avoid overflow.
If we attempt to add >32 multicast filter - just set NETIF_ALLMULTI flag
instead.

Fixes: 94f6c9e4cdf6 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Igor Russkikh 
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index dce17a5..6ac9e26 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -669,11 +669,26 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, 
struct net_device *ndev)
netdev_for_each_mc_addr(ha, ndev) {
ether_addr_copy(self->mc_list.ar[i++], ha->addr);
++self->mc_list.count;
+
+   if (i >= AQ_CFG_MULTICAST_ADDRESS_MAX)
+   break;
}
 
-   return self->aq_hw_ops.hw_multicast_list_set(self->aq_hw,
+   if (i >= AQ_CFG_MULTICAST_ADDRESS_MAX) {
+   /* Number of filters is too big: atlantic does not support this.
+* Force all multi filter to support this.
+* With this we disable all UC filters and setup "all pass"
+* multicast mask
+*/
+   self->packet_filter |= IFF_ALLMULTI;
+   self->aq_hw->aq_nic_cfg->mc_list_count = 0;
+   return self->aq_hw_ops.hw_packet_filter_set(self->aq_hw,
+   self->packet_filter);
+   } else {
+   return self->aq_hw_ops.hw_multicast_list_set(self->aq_hw,
self->mc_list.ar,
self->mc_list.count);
+   }
 }
 
 int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu)
-- 
2.7.4



[PATCH net v2 4/6] net:ethernet:aquantia: Fix for incorrect speed index.

2017-08-28 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The driver choose the optimal interrupt throttling settings depends
of current link speed.
Due this bug link_status field from aq_hw is never updated and as result
always used same interrupt throttling values.

Fixes: 3d2ff7eebe26 ("net: ethernet: aquantia: Atlantic hardware abstraction 
layer")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_hw.h |  3 +--
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 31 ++
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c|  4 +--
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h|  3 +--
 4 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index fce0fd3..bf9b3f0 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -105,8 +105,7 @@ struct aq_hw_ops {
 
int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr);
 
-   int (*hw_get_link_status)(struct aq_hw_s *self,
- struct aq_hw_link_status_s *link_status);
+   int (*hw_get_link_status)(struct aq_hw_s *self);
 
int (*hw_set_link_speed)(struct aq_hw_s *self, u32 speed);
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index d6d8e70..dce17a5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -125,33 +125,30 @@ static void aq_nic_service_timer_cb(unsigned long param)
struct net_device *ndev = aq_nic_get_ndev(self);
int err = 0;
unsigned int i = 0U;
-   struct aq_hw_link_status_s link_status;
struct aq_ring_stats_rx_s stats_rx;
struct aq_ring_stats_tx_s stats_tx;
 
if (aq_utils_obj_test(>header.flags, AQ_NIC_FLAGS_IS_NOT_READY))
goto err_exit;
 
-   err = self->aq_hw_ops.hw_get_link_status(self->aq_hw, _status);
+   err = self->aq_hw_ops.hw_get_link_status(self->aq_hw);
if (err < 0)
goto err_exit;
 
-   self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
-   self->aq_nic_cfg.is_interrupt_moderation);
-
-   if (memcmp(_status, >link_status, sizeof(link_status))) {
-   if (link_status.mbps) {
-   aq_utils_obj_set(>header.flags,
-AQ_NIC_FLAG_STARTED);
-   aq_utils_obj_clear(>header.flags,
-  AQ_NIC_LINK_DOWN);
-   netif_carrier_on(self->ndev);
-   } else {
-   netif_carrier_off(self->ndev);
-   aq_utils_obj_set(>header.flags, AQ_NIC_LINK_DOWN);
-   }
+   self->link_status = self->aq_hw->aq_link_status;
 
-   self->link_status = link_status;
+   self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
+   self->aq_nic_cfg.is_interrupt_moderation);
+
+   if (self->link_status.mbps) {
+   aq_utils_obj_set(>header.flags,
+AQ_NIC_FLAG_STARTED);
+   aq_utils_obj_clear(>header.flags,
+  AQ_NIC_LINK_DOWN);
+   netif_carrier_on(self->ndev);
+   } else {
+   netif_carrier_off(self->ndev);
+   aq_utils_obj_set(>header.flags, AQ_NIC_LINK_DOWN);
}
 
memset(_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index 8d6d8f5..7a1332e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -313,11 +313,11 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
 err_exit:;
 }
 
-int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self,
-struct aq_hw_link_status_s *link_status)
+int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
 {
u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
+   struct aq_hw_link_status_s *link_status = >aq_link_status;
 
if (!link_speed_mask) {
link_status->mbps = 0U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index a66aee5..e0360a6 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -180,8 +180,7 @@ void hw_atl_utils_mpi_set(stru

[PATCH net 4/7] net:ethernet:aquantia: Fix for MCP state change.

2017-08-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The firmware state is controlled by writing value in to 0x368 register.
This value contain MCP state and desired link mode.
Because this value was incorrectly formed the firmware does not
resetting properly (ethtool -S shows the HW counters which
never resetting, even after reboot).

Fixes: 3d2ff7eebe26 "net: ethernet: aquantia: Atlantic hardware abstraction 
layer")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 .../net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c|  7 ---
 .../net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h| 13 +
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index 8d6d8f5..fcfbe42 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -280,10 +280,11 @@ err_exit:;
 int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed,
   enum hal_atl_utils_fw_state_e state)
 {
-   u32 ucp_0x368 = 0;
+   union hal_atl_utils_hw_mpi_state_reg ucp_0x368 = { 0 };
 
-   ucp_0x368 = (speed << HW_ATL_MPI_SPEED_SHIFT) | state;
-   aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, ucp_0x368);
+   ucp_0x368.u_speed = speed;
+   ucp_0x368.e_state = state;
+   aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, ucp_0x368.val);
 
return 0;
 }
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index a66aee5..fc69408a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -160,6 +160,19 @@ enum hal_atl_utils_fw_state_e {
MPI_POWER = 4,
 };
 
+union hal_atl_utils_hw_mpi_state_reg {
+   u32 val;
+   struct {
+   u8 e_state;
+   u8 reserved1;
+   u8 u_speed;
+   u8 reserved2:1;
+   u8 disable_dirty_wake:1;
+   u8 reserved3:2;
+   u8 u_downshift:4;
+   };
+};
+
 #define HAL_ATLANTIC_RATE_10GBIT(0)
 #define HAL_ATLANTIC_RATE_5G BIT(1)
 #define HAL_ATLANTIC_RATE_5GSR   BIT(2)
-- 
2.7.4



[PATCH net 7/7] net:ethernet:aquantia: Show info message if bad firmware version detected.

2017-08-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We should inform user about wrong firmware version
by printing message in dmesg.

Fixes: 3d2ff7eebe26 ("net: ethernet: aquantia: Atlantic hardware abstraction 
layer")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index eb3ae51..ad4cc53 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -141,6 +141,12 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
 
err = hw_atl_utils_ver_match(aq_hw_caps->fw_ver_expected,
 aq_hw_read_reg(self, 0x18U));
+
+   if (err < 0)
+   pr_err("%s: Bad FW version detected: expected=%x, actual=%x\n",
+  AQ_CFG_DRV_NAME,
+  aq_hw_caps->fw_ver_expected,
+  aq_hw_read_reg(self, 0x18U));
return err;
 }
 
-- 
2.7.4



[PATCH net 6/7] net:ethernet:aquantia: Fix for multicast filter handling.

2017-08-23 Thread Pavel Belous
From: Igor Russkikh 

Since the HW supports up to 32 multicast filters we should
track count of multicast filters to avoid overflow.
If we attempt to add >32 multicast filter - just set NETIF_ALLMULTI flag
instead.

Fixes: 94f6c9e4cdf6 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Igor Russkikh 
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index dce17a5..6ac9e26 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -669,11 +669,26 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, 
struct net_device *ndev)
netdev_for_each_mc_addr(ha, ndev) {
ether_addr_copy(self->mc_list.ar[i++], ha->addr);
++self->mc_list.count;
+
+   if (i >= AQ_CFG_MULTICAST_ADDRESS_MAX)
+   break;
}
 
-   return self->aq_hw_ops.hw_multicast_list_set(self->aq_hw,
+   if (i >= AQ_CFG_MULTICAST_ADDRESS_MAX) {
+   /* Number of filters is too big: atlantic does not support this.
+* Force all multi filter to support this.
+* With this we disable all UC filters and setup "all pass"
+* multicast mask
+*/
+   self->packet_filter |= IFF_ALLMULTI;
+   self->aq_hw->aq_nic_cfg->mc_list_count = 0;
+   return self->aq_hw_ops.hw_packet_filter_set(self->aq_hw,
+   self->packet_filter);
+   } else {
+   return self->aq_hw_ops.hw_multicast_list_set(self->aq_hw,
self->mc_list.ar,
self->mc_list.count);
+   }
 }
 
 int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu)
-- 
2.7.4



[PATCH net 2/7] net:ethernet:aquantia: Fix for number of RSS queues.

2017-08-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The number of RSS queues should be not more than numbers of CPU.
Its does not make sense to increase perfomance, and also cause problems on
some motherboards.

Fixes: 94f6c9e4cdf6 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 08b7275..d6d8e70 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -103,6 +103,8 @@ int aq_nic_cfg_start(struct aq_nic_s *self)
else
cfg->vecs = 1U;
 
+   cfg->num_rss_queues = min(cfg->vecs, AQ_CFG_NUM_RSS_QUEUES_DEF);
+
cfg->irq_type = aq_pci_func_get_irq_type(self->aq_pci_func);
 
if ((cfg->irq_type == AQ_HW_IRQ_LEGACY) ||
-- 
2.7.4



[PATCH net 1/7] net:ethernet:aquantia: Extra spinlocks removed.

2017-08-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This patch removes datapath spinlocks which does not perform any
useful work.

Fixes: 6e70637f9f1e ("net: ethernet: aquantia: Add ring support code")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c   | 42 +++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c  |  1 -
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h |  1 -
 drivers/net/ethernet/aquantia/atlantic/aq_vec.c   | 11 ++
 4 files changed, 14 insertions(+), 41 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 9ee1c50..08b7275 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -597,14 +597,11 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
 }
 
 int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
-__releases(>lock)
-__acquires(>lock)
 {
struct aq_ring_s *ring = NULL;
unsigned int frags = 0U;
unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;
unsigned int tc = 0U;
-   unsigned int trys = AQ_CFG_LOCK_TRYS;
int err = NETDEV_TX_OK;
bool is_nic_in_bad_state;
 
@@ -628,36 +625,21 @@ __acquires(>lock)
goto err_exit;
}
 
-   do {
-   if (spin_trylock(>header.lock)) {
-   frags = aq_nic_map_skb(self, skb, ring);
-
-   if (likely(frags)) {
-   err = self->aq_hw_ops.hw_ring_tx_xmit(
-   self->aq_hw,
-   ring, frags);
-   if (err >= 0) {
-   if (aq_ring_avail_dx(ring) <
-   AQ_CFG_SKB_FRAGS_MAX + 1)
-   aq_nic_ndev_queue_stop(
-   self,
-   ring->idx);
-
-   ++ring->stats.tx.packets;
-   ring->stats.tx.bytes += skb->len;
-   }
-   } else {
-   err = NETDEV_TX_BUSY;
-   }
+   frags = aq_nic_map_skb(self, skb, ring);
 
-   spin_unlock(>header.lock);
-   break;
-   }
-   } while (--trys);
+   if (likely(frags)) {
+   err = self->aq_hw_ops.hw_ring_tx_xmit(self->aq_hw,
+ ring,
+ frags);
+   if (err >= 0) {
+   if (aq_ring_avail_dx(ring) < AQ_CFG_SKB_FRAGS_MAX + 1)
+   aq_nic_ndev_queue_stop(self, ring->idx);
 
-   if (!trys) {
+   ++ring->stats.tx.packets;
+   ring->stats.tx.bytes += skb->len;
+   }
+   } else {
err = NETDEV_TX_BUSY;
-   goto err_exit;
}
 
 err_exit:
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 9a08179..ec5579f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -101,7 +101,6 @@ int aq_ring_init(struct aq_ring_s *self)
self->hw_head = 0;
self->sw_head = 0;
self->sw_tail = 0;
-   spin_lock_init(>header.lock);
return 0;
 }
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
index f6012b3..e12bcdf 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
@@ -17,7 +17,6 @@
 #define AQ_DIMOF(_ARY_)  ARRAY_SIZE(_ARY_)
 
 struct aq_obj_s {
-   spinlock_t lock; /* spinlock for nic/rings processing */
atomic_t flags;
 };
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
index ad5b4d4d..fee446a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -34,8 +34,6 @@ struct aq_vec_s {
 #define AQ_VEC_RX_ID 1
 
 static int aq_vec_poll(struct napi_struct *napi, int budget)
-__releases(>lock)
-__acquires(>lock)
 {
struct aq_vec_s *self = container_of(napi, struct aq_vec_s, napi);
struct aq_ring_s *ring = NULL;
@@ -47,7 +45,7 @@ __acquires(>lock)
 
if (!self) {
err = -EINVAL;
-   } else if (spin_trylock(>header.lock)) {
+ 

[PATCH net 0/7] net:ethernet:aquantia: Atlantic driver Update 2017-08-23

2017-08-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This series contains updates for aQuantia Atlantic driver.

It has bugfixes and some improvements.

Igor Russkikh (1):
  net:ethernet:aquantia: Fix for multicast filter handling.

Pavel Belous (6):
  net:ethernet:aquantia: Extra spinlocks removed.
  net:ethernet:aquantia: Fix for number of RSS queues.
  net:ethernet:aquantia: Workaround for HW checksum bug.
  net:ethernet:aquantia: Fix for MCP state change.
  net:ethernet:aquantia: Fix for incorrect speed index.
  net:ethernet:aquantia: Show info message if bad firmware version
detected.

 drivers/net/ethernet/aquantia/atlantic/aq_hw.h |  3 +-
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 92 +++---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c   |  1 -
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h  |  1 -
 drivers/net/ethernet/aquantia/atlantic/aq_vec.c| 11 +--
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |  6 ++
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |  6 ++
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c| 17 ++--
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h| 16 +++-
 9 files changed, 85 insertions(+), 68 deletions(-)

-- 
2.7.4



[PATCH net 5/7] net:ethernet:aquantia: Fix for incorrect speed index.

2017-08-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The driver choose the optimal interrupt throttling settings depends
of current link speed.
Due this bug link_status field from aq_hw is never updated and as result
always used same interrupt throttling values.

Fixes: 3d2ff7eebe26 ("net: ethernet: aquantia: Atlantic hardware abstraction 
layer")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_hw.h |  3 +--
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 31 ++
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c|  4 +--
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h|  3 +--
 4 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index fce0fd3..bf9b3f0 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -105,8 +105,7 @@ struct aq_hw_ops {
 
int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr);
 
-   int (*hw_get_link_status)(struct aq_hw_s *self,
- struct aq_hw_link_status_s *link_status);
+   int (*hw_get_link_status)(struct aq_hw_s *self);
 
int (*hw_set_link_speed)(struct aq_hw_s *self, u32 speed);
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index d6d8e70..dce17a5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -125,33 +125,30 @@ static void aq_nic_service_timer_cb(unsigned long param)
struct net_device *ndev = aq_nic_get_ndev(self);
int err = 0;
unsigned int i = 0U;
-   struct aq_hw_link_status_s link_status;
struct aq_ring_stats_rx_s stats_rx;
struct aq_ring_stats_tx_s stats_tx;
 
if (aq_utils_obj_test(>header.flags, AQ_NIC_FLAGS_IS_NOT_READY))
goto err_exit;
 
-   err = self->aq_hw_ops.hw_get_link_status(self->aq_hw, _status);
+   err = self->aq_hw_ops.hw_get_link_status(self->aq_hw);
if (err < 0)
goto err_exit;
 
-   self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
-   self->aq_nic_cfg.is_interrupt_moderation);
-
-   if (memcmp(_status, >link_status, sizeof(link_status))) {
-   if (link_status.mbps) {
-   aq_utils_obj_set(>header.flags,
-AQ_NIC_FLAG_STARTED);
-   aq_utils_obj_clear(>header.flags,
-  AQ_NIC_LINK_DOWN);
-   netif_carrier_on(self->ndev);
-   } else {
-   netif_carrier_off(self->ndev);
-   aq_utils_obj_set(>header.flags, AQ_NIC_LINK_DOWN);
-   }
+   self->link_status = self->aq_hw->aq_link_status;
 
-   self->link_status = link_status;
+   self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
+   self->aq_nic_cfg.is_interrupt_moderation);
+
+   if (self->link_status.mbps) {
+   aq_utils_obj_set(>header.flags,
+AQ_NIC_FLAG_STARTED);
+   aq_utils_obj_clear(>header.flags,
+  AQ_NIC_LINK_DOWN);
+   netif_carrier_on(self->ndev);
+   } else {
+   netif_carrier_off(self->ndev);
+   aq_utils_obj_set(>header.flags, AQ_NIC_LINK_DOWN);
}
 
memset(_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index fcfbe42..eb3ae51 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -314,11 +314,11 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
 err_exit:;
 }
 
-int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self,
-struct aq_hw_link_status_s *link_status)
+int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
 {
u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
+   struct aq_hw_link_status_s *link_status = >aq_link_status;
 
if (!link_speed_mask) {
link_status->mbps = 0U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index fc69408a..4f3e148 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -193,8 +193,7 @@ void hw_atl_utils_mpi_set(stru

[PATCH net 3/7] net:ethernet:aquantia: Workaround for HW checksum bug.

2017-08-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The hardware has the HW Checksum Offload bug when small
TCP patckets (with length <= 60 bytes) has wrong "checksum valid" bit.

The solution is - ignore checksum valid bit for small packets
(with length <= 60 bytes) and mark this as CHECKSUM_NONE to allow
network stack recalculate checksum itself.

Fixes: ccf9a5ed14be ("net: ethernet: aquantia: Atlantic A0 and B0 specific 
functions.")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 6 ++
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 6 ++
 2 files changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index faeb493..c5a02df 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -629,6 +629,12 @@ static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s 
*self,
buff->is_udp_cso = (is_err & 0x10U) ? 0 : 1;
else if (0x0U == (pkt_type & 0x1CU))
buff->is_tcp_cso = (is_err & 0x10U) ? 0 : 1;
+
+   /* Checksum offload workaround for small packets */
+   if (rxd_wb->pkt_len <= 60) {
+   buff->is_ip_cso = 0U;
+   buff->is_cso_err = 0U;
+   }
}
 
is_err &= ~0x18U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 1bceb73..21784cc 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -645,6 +645,12 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s 
*self,
buff->is_udp_cso = buff->is_cso_err ? 0U : 1U;
else if (0x0U == (pkt_type & 0x1CU))
buff->is_tcp_cso = buff->is_cso_err ? 0U : 1U;
+
+   /* Checksum offload workaround for small packets */
+   if (rxd_wb->pkt_len <= 60) {
+   buff->is_ip_cso = 0U;
+   buff->is_cso_err = 0U;
+   }
}
 
is_err &= ~0x18U;
-- 
2.7.4



[PATCH net-next] aquantia: Switch to use napi_gro_receive

2017-08-03 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Add support for GRO (generic receive offload) for aQuantia Atlantic driver.
This results in a perfomance improvement when GRO is enabled.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 7 +--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h | 5 -
 drivers/net/ethernet/aquantia/atlantic/aq_vec.c  | 1 +
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 9a08179..4b44575 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -134,7 +134,10 @@ static inline unsigned int aq_ring_dx_in_range(unsigned 
int h, unsigned int i,
 }
 
 #define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
-int aq_ring_rx_clean(struct aq_ring_s *self, int *work_done, int budget)
+int aq_ring_rx_clean(struct aq_ring_s *self,
+struct napi_struct *napi,
+int *work_done,
+int budget)
 {
struct net_device *ndev = aq_nic_get_ndev(self->aq_nic);
int err = 0;
@@ -240,7 +243,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self, int 
*work_done, int budget)
 
skb_record_rx_queue(skb, self->idx);
 
-   netif_receive_skb(skb);
+   napi_gro_receive(napi, skb);
 
++self->stats.rx.packets;
self->stats.rx.bytes += skb->len;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
index eecd6d1..782176c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
@@ -148,7 +148,10 @@ int aq_ring_init(struct aq_ring_s *self);
 void aq_ring_rx_deinit(struct aq_ring_s *self);
 void aq_ring_free(struct aq_ring_s *self);
 void aq_ring_tx_clean(struct aq_ring_s *self);
-int aq_ring_rx_clean(struct aq_ring_s *self, int *work_done, int budget);
+int aq_ring_rx_clean(struct aq_ring_s *self,
+struct napi_struct *napi,
+int *work_done,
+int budget);
 int aq_ring_rx_fill(struct aq_ring_s *self);
 
 #endif /* AQ_RING_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
index ad5b4d4d..ec390c5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -78,6 +78,7 @@ __acquires(>lock)
if (ring[AQ_VEC_RX_ID].sw_head !=
ring[AQ_VEC_RX_ID].hw_head) {
err = aq_ring_rx_clean([AQ_VEC_RX_ID],
+  napi,
   _done,
   budget - work_done);
if (err < 0)
-- 
2.7.4



Re: [PATCH][V2] ethernet: aquantia: remove redundant checks on error status

2017-05-11 Thread Pavel Belous



On 11.05.2017 21:29, Colin King wrote:

From: Colin Ian King <colin.k...@canonical.com>

The error status err is initialized as zero and then being checked
several times to see if it is less than zero even when it has not
been updated.  It may seem that the err should be assigned to the
return code of the call to the various *offload_en_set calls and
then we check for failure, however, these functions are void and
never actually return any status.

Since these error checks are redundant we can remove these
as well as err and the error exit label err_exit.

Detected by CoverityScan, CID#1398313 and CID#1398306 ("Logically
dead code")

Signed-off-by: Colin Ian King <colin.k...@canonical.com>


Acked-by: Pavel Belous <pavel.bel...@aquantia.com>

Regards,
Pavel


[PATCH] aquantia: Fix "ethtool -S" crash when adapter down.

2017-05-04 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This patch fixes the crash that happens when driver tries to collect statistics
from already released "aq_vec" object.
If adapter is in "down" state we still allow user to see statistics from HW.

V2: fixed braces around "aq_vec_free".

Fixes: 97bde5c4f909 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index cdb0299..9ee1c50 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -755,7 +755,7 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
count = 0U;
 
for (i = 0U, aq_vec = self->aq_vec[0];
-   self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
+   aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
data += count;
aq_vec_get_sw_stats(aq_vec, data, );
}
@@ -959,8 +959,10 @@ void aq_nic_free_hot_resources(struct aq_nic_s *self)
goto err_exit;
 
for (i = AQ_DIMOF(self->aq_vec); i--;) {
-   if (self->aq_vec[i])
+   if (self->aq_vec[i]) {
aq_vec_free(self->aq_vec[i]);
+   self->aq_vec[i] = NULL;
+   }
}
 
 err_exit:;
-- 
2.7.4



Re: [PATCH] aquantia: Fix "ethtool -S" crash when adapter down.

2017-05-04 Thread Pavel Belous



On 04.05.2017 21:17, Joe Perches wrote:

On Thu, 2017-05-04 at 20:08 +0300, Pavel Belous wrote:

I will prepare another patch with Lino and David M. comments.


I'm not submitting this because it'd just cause merge conflicts,
but
something you could do one day is remove the AQ_DIMOF macro
and just use ARRAY_SIZE directly.
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c  | 4 ++--
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h| 2 --
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c| 2 +-
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c| 2 +-
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | 2 +-
 5 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index cdb02991f249..cffae53414ba 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -154,7 +154,7 @@ static void aq_nic_service_timer_cb(unsigned long param)

memset(_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
memset(_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
-   for (i = AQ_DIMOF(self->aq_vec); i--;) {
+   for (i = ARRAY_SIZE(self->aq_vec); i--;) {
if (self->aq_vec[i])
aq_vec_add_stats(self->aq_vec[i], _rx, _tx);
}
@@ -958,7 +958,7 @@ void aq_nic_free_hot_resources(struct aq_nic_s *self)
if (!self)
goto err_exit;

-   for (i = AQ_DIMOF(self->aq_vec); i--;) {
+   for (i = ARRAY_SIZE(self->aq_vec); i--;) {
if (self->aq_vec[i])
aq_vec_free(self->aq_vec[i]);
}
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
index f6012b34abe6..64a8c3c781ff 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
@@ -14,8 +14,6 @@

 #include "aq_common.h"

-#define AQ_DIMOF(_ARY_)  ARRAY_SIZE(_ARY_)
-
 struct aq_obj_s {
spinlock_t lock; /* spinlock for nic/rings processing */
atomic_t flags;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 4ee15ff06a44..96c3360e7060 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -182,7 +182,7 @@ static int hw_atl_a0_hw_rss_set(struct aq_hw_s *self,
((i * 3U) & 0xFU));
}

-   for (i = AQ_DIMOF(bitary); i--;) {
+   for (i = ARRAY_SIZE(bitary); i--;) {
rpf_rss_redir_tbl_wr_data_set(self, bitary[i]);
rpf_rss_redir_tbl_addr_set(self, i);
rpf_rss_redir_wr_en_set(self, 1U);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 42150708191d..5a19eba31786 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -182,7 +182,7 @@ static int hw_atl_b0_hw_rss_set(struct aq_hw_s *self,
((i * 3U) & 0xFU));
}

-   for (i = AQ_DIMOF(bitary); i--;) {
+   for (i = ARRAY_SIZE(bitary); i--;) {
rpf_rss_redir_tbl_wr_data_set(self, bitary[i]);
rpf_rss_redir_tbl_addr_set(self, i);
rpf_rss_redir_wr_en_set(self, 1U);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index 8d6d8f5804da..922af5f36d37 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -385,7 +385,7 @@ int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
aq_hw_read_reg(self, 0x0374U) +
(40U * 4U),
mac_addr,
-   AQ_DIMOF(mac_addr));
+   ARRAY_SIZE(mac_addr));
if (err < 0) {
mac_addr[0] = 0U;
mac_addr[1] = 0U;



Thank you,
I will do it, little bit later.

Regards,
Pavel


Re: [PATCH] aquantia: Fix "ethtool -S" crash when adapter down.

2017-05-04 Thread Pavel Belous



On 04.05.2017 21:27, David Arcari wrote:

On 05/04/2017 01:09 PM, Pavel Belous wrote:



On 04.05.2017 19:51, David Miller wrote:

From: Lino Sanfilippo <linosanfili...@gmx.de>
Date: Thu, 4 May 2017 18:48:12 +0200


Hi Pavel,

On 04.05.2017 18:33, Pavel Belous wrote:

From: Pavel Belous <pavel.bel...@aquantia.com>

This patch fixes the crash that happens when driver tries to collect statistics
from already released "aq_vec" object.

Fixes: 97bde5c4f909 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index cdb0299..3a32573 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -755,7 +755,7 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
 count = 0U;

 for (i = 0U, aq_vec = self->aq_vec[0];
-self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
+aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
 data += count;
 aq_vec_get_sw_stats(aq_vec, data, );
 }
@@ -961,6 +961,7 @@ void aq_nic_free_hot_resources(struct aq_nic_s *self)
 for (i = AQ_DIMOF(self->aq_vec); i--;) {
 if (self->aq_vec[i])
 aq_vec_free(self->aq_vec[i]);
+self->aq_vec[i] = NULL;
 }

 err_exit:;



if the driver does not support statistics when the interface is down, would
not it be clearer
to check if netif_running() in get_stats() instead?


Yes, much cleaner.

Much better would be to have a cached software copy so that statistics
can be reported regardless of whether the device is down or not.



Thank you.
I will think about how to do it better.


It appears that the adapter is still reporting the cumulative hardware stats
even while its down.  The user is just losing the per queue stats.

Although the loss of the per queue stats is not ideal, this patch still fixes a
crash.

It might be worthwhile to refactor this patch as a short term solution and then
subsequently produce a version that contains cached statistics.  Assuming that
is amenable to everyone of course.

-DA



Yes, even adapter is in the down state user can still see statistics 
from the HW.

For example (adapter is down):

$ ethtool -S enp2s0
NIC statistics:
 InPackets: 3237727
 InUCast: 3237214
 InMCast: 391
 InBCast: 122
 InErrors: 0
 OutPackets: 14157898
 OutUCast: 14157089
 OutMCast: 304
 OutBCast: 505
 InUCastOctects: 226714406
 OutUCastOctects: 10463156
 InMCastOctects: 58046
 OutMCastOctects: 44817
 InBCastOctects: 12857
 OutBCastOctects: 41626
 InOctects: 226785309
 OutOctects: 10549599
 InPacketsDma: 0
 OutPacketsDma: 16
 InOctetsDma: 0
 OutOctetsDma: 2396
 InDroppedDma: 0
 Queue[0] InPackets: 0
 Queue[0] OutPackets: 0
 Queue[0] InJumboPackets: 0
 Queue[0] InLroPackets: 0
 Queue[0] InErrors: 0
 Queue[1] InPackets: 0
 Queue[1] OutPackets: 0
 Queue[1] InJumboPackets: 0
 Queue[1] InLroPackets: 0
 Queue[1] InErrors: 0
 Queue[2] InPackets: 0
 Queue[2] OutPackets: 0
 Queue[2] InJumboPackets: 0
 Queue[2] InLroPackets: 0
 Queue[2] InErrors: 0
 Queue[3] InPackets: 0
 Queue[3] OutPackets: 0
 Queue[3] InJumboPackets: 0
 Queue[3] InLroPackets: 0
 Queue[3] InErrors: 0

Lino, David what do you think?
If you agree I can re-submit the patch (with fixed braces).

Regards,
Pavel



Re: [PATCH] aquantia: Fix "ethtool -S" crash when adapter down.

2017-05-04 Thread Pavel Belous



On 04.05.2017 19:51, David Miller wrote:

From: Lino Sanfilippo <linosanfili...@gmx.de>
Date: Thu, 4 May 2017 18:48:12 +0200


Hi Pavel,

On 04.05.2017 18:33, Pavel Belous wrote:

From: Pavel Belous <pavel.bel...@aquantia.com>

This patch fixes the crash that happens when driver tries to collect statistics
from already released "aq_vec" object.

Fixes: 97bde5c4f909 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index cdb0299..3a32573 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -755,7 +755,7 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
count = 0U;

for (i = 0U, aq_vec = self->aq_vec[0];
-   self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
+   aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
data += count;
aq_vec_get_sw_stats(aq_vec, data, );
}
@@ -961,6 +961,7 @@ void aq_nic_free_hot_resources(struct aq_nic_s *self)
for (i = AQ_DIMOF(self->aq_vec); i--;) {
if (self->aq_vec[i])
aq_vec_free(self->aq_vec[i]);
+   self->aq_vec[i] = NULL;
}

 err_exit:;



if the driver does not support statistics when the interface is down, would not 
it be clearer
to check if netif_running() in get_stats() instead?


Yes, much cleaner.

Much better would be to have a cached software copy so that statistics
can be reported regardless of whether the device is down or not.



Thank you.
I will think about how to do it better.

Regards,
Pavel


Re: [PATCH] aquantia: Fix "ethtool -S" crash when adapter down.

2017-05-04 Thread Pavel Belous



On 04.05.2017 20:00, David Arcari wrote:

Hi Pavel,

On 05/04/2017 12:33 PM, Pavel Belous wrote:

From: Pavel Belous <pavel.bel...@aquantia.com>

This patch fixes the crash that happens when driver tries to collect statistics
from already released "aq_vec" object.

Fixes: 97bde5c4f909 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index cdb0299..3a32573 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -755,7 +755,7 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
count = 0U;

for (i = 0U, aq_vec = self->aq_vec[0];
-   self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
+   aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
data += count;
aq_vec_get_sw_stats(aq_vec, data, );
}
@@ -961,6 +961,7 @@ void aq_nic_free_hot_resources(struct aq_nic_s *self)
for (i = AQ_DIMOF(self->aq_vec); i--;) {
if (self->aq_vec[i])
aq_vec_free(self->aq_vec[i]);
+   self->aq_vec[i] = NULL;


I think you intended to to add { } to the if statement.  The code compiles as
is, but the indentation is not correct.

-DA


Oh. Sorry about that. I did not see the loss of braces during merge.
I will prepare another patch with Lino and David M. comments.

Regards,
Pavel.





}

 err_exit:;





[PATCH] aquantia: Fix "ethtool -S" crash when adapter down.

2017-05-04 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This patch fixes the crash that happens when driver tries to collect statistics
from already released "aq_vec" object.

Fixes: 97bde5c4f909 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index cdb0299..3a32573 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -755,7 +755,7 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
count = 0U;
 
for (i = 0U, aq_vec = self->aq_vec[0];
-   self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
+   aq_vec && self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i]) {
data += count;
aq_vec_get_sw_stats(aq_vec, data, );
}
@@ -961,6 +961,7 @@ void aq_nic_free_hot_resources(struct aq_nic_s *self)
for (i = AQ_DIMOF(self->aq_vec); i--;) {
if (self->aq_vec[i])
aq_vec_free(self->aq_vec[i]);
+   self->aq_vec[i] = NULL;
}
 
 err_exit:;
-- 
2.7.4



Re: [PATCH] net:ethernet:aquantia:atlantic: Switch to use napi_gro_receive

2017-05-04 Thread Pavel Belous



On 04.05.2017 17:42, David Miller wrote:

From: Pavel Belous <pavel.bel...@aquantia.com>
Date: Wed,  3 May 2017 19:57:10 +0300


From: Pavel Belous <pavel.bel...@aquantia.com>

Add support for GRO (generic receive offload) for aQuantia Atlantic driver.
This results in a perfomance improvement when GRO is enabled.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>


Please format your Subject line properly.

You have _way_ too many subsystem prefixes, and when there are more
than one they should be separated by spaces like "a: b: c:"

In this case an appropriate Subject line would be:

[PATCH net-next] aquantia: Switch to use napi_gro_receive().

But since this is a new feature, and the net-next tree is currently
closed, you will have to resubmit this when the net-next tree
opens.

Thank you.



Ok. I will re-submit the patch when net-next tree opens.

Thank you,
Pavel


[PATCH v2] aquantia: Fix driver name reported by ethtool

2017-05-03 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

V2: using "aquantia" subsystem tag.

The command "ethtool -i ethX" should display driver name (driver: atlantic)
instead vendor name (driver: aquantia).

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_cfg.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
index 5f99237..2149864 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
@@ -68,7 +68,7 @@
 
 #define AQ_CFG_DRV_AUTHOR  "aQuantia"
 #define AQ_CFG_DRV_DESC"aQuantia Corporation(R) Network Driver"
-#define AQ_CFG_DRV_NAME"aquantia"
+#define AQ_CFG_DRV_NAME"atlantic"
 #define AQ_CFG_DRV_VERSION __stringify(NIC_MAJOR_DRIVER_VERSION)"."\
__stringify(NIC_MINOR_DRIVER_VERSION)"."\
__stringify(NIC_BUILD_DRIVER_VERSION)"."\
-- 
2.7.4



[PATCH] net:ethernet:aquantia:atlantic: Fix driver name reported by ethtool

2017-05-03 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The command "ethtool -i ethX" should display driver name (driver: atlantic)
instead vendor name (driver: aquantia).

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_cfg.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
index 5f99237..2149864 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
@@ -68,7 +68,7 @@
 
 #define AQ_CFG_DRV_AUTHOR  "aQuantia"
 #define AQ_CFG_DRV_DESC"aQuantia Corporation(R) Network Driver"
-#define AQ_CFG_DRV_NAME"aquantia"
+#define AQ_CFG_DRV_NAME"atlantic"
 #define AQ_CFG_DRV_VERSION __stringify(NIC_MAJOR_DRIVER_VERSION)"."\
__stringify(NIC_MINOR_DRIVER_VERSION)"."\
__stringify(NIC_BUILD_DRIVER_VERSION)"."\
-- 
2.7.4



[PATCH] net:ethernet:aquantia:atlantic: Switch to use napi_gro_receive

2017-05-03 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Add support for GRO (generic receive offload) for aQuantia Atlantic driver.
This results in a perfomance improvement when GRO is enabled.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 7 +--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h | 5 -
 drivers/net/ethernet/aquantia/atlantic/aq_vec.c  | 1 +
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 3a8a4aa..c2f095d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -134,7 +134,10 @@ static inline unsigned int aq_ring_dx_in_range(unsigned 
int h, unsigned int i,
 }
 
 #define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
-int aq_ring_rx_clean(struct aq_ring_s *self, int *work_done, int budget)
+int aq_ring_rx_clean(struct aq_ring_s *self,
+struct napi_struct *napi,
+int *work_done,
+int budget)
 {
struct net_device *ndev = aq_nic_get_ndev(self->aq_nic);
int err = 0;
@@ -240,7 +243,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self, int 
*work_done, int budget)
 
skb_record_rx_queue(skb, self->idx);
 
-   netif_receive_skb(skb);
+   napi_gro_receive(napi, skb);
 
++self->stats.rx.packets;
self->stats.rx.bytes += skb->len;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
index eecd6d1..782176c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
@@ -148,7 +148,10 @@ int aq_ring_init(struct aq_ring_s *self);
 void aq_ring_rx_deinit(struct aq_ring_s *self);
 void aq_ring_free(struct aq_ring_s *self);
 void aq_ring_tx_clean(struct aq_ring_s *self);
-int aq_ring_rx_clean(struct aq_ring_s *self, int *work_done, int budget);
+int aq_ring_rx_clean(struct aq_ring_s *self,
+struct napi_struct *napi,
+int *work_done,
+int budget);
 int aq_ring_rx_fill(struct aq_ring_s *self);
 
 #endif /* AQ_RING_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
index ad5b4d4d..ec390c5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -78,6 +78,7 @@ __acquires(>lock)
if (ring[AQ_VEC_RX_ID].sw_head !=
ring[AQ_VEC_RX_ID].hw_head) {
err = aq_ring_rx_clean([AQ_VEC_RX_ID],
+  napi,
   _done,
   budget - work_done);
if (err < 0)
-- 
2.7.4



[PATCH v3 net 5/5] net:ethernet:aquantia: Reset is_gso flag when EOP reached.

2017-03-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We need to reset is_gso flag when EOP reached (entire LSO packet processed).

Fixes: bab6de8fd180 ("net: ethernet: aquantia:
 Atlantic A0 and B0 specific functions.")

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 1 +
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index a536875..4ee15ff 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -461,6 +461,7 @@ static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self,
if (unlikely(buff->is_eop)) {
txd->ctl |= HW_ATL_A0_TXD_CTL_EOP;
txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_WB;
+   is_gso = false;
}
}
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 69488c9..4215070 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -499,6 +499,7 @@ static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self,
if (unlikely(buff->is_eop)) {
txd->ctl |= HW_ATL_B0_TXD_CTL_EOP;
txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_WB;
+   is_gso = false;
}
}
 
-- 
2.7.4



[PATCH v3 net 3/5] net:ethernet:aquantia: Missing spinlock initialization.

2017-03-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Fix for missing initialization aq_ring header.lock spinlock.

Fixes: 018423e90bee ("net: ethernet: aquantia: Add ring support code")

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 0358e607..3a8a4aa 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -101,6 +101,7 @@ int aq_ring_init(struct aq_ring_s *self)
self->hw_head = 0;
self->sw_head = 0;
self->sw_tail = 0;
+   spin_lock_init(>header.lock);
return 0;
 }
 
-- 
2.7.4



[PATCH v3 net 4/5] net:ethernet:aquantia: Fix for LSO with IPv6.

2017-03-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Fix Context Command bit: L3 type = "0" for IPv4, "1" for IPv6.

Fixes: bab6de8fd180 ("net: ethernet: aquantia:
 Atlantic A0 and B0 specific functions.")

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c   | 3 +++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h  | 3 ++-
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 3 +++
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 3 +++
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index db2b51d..cdb0299 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -487,6 +487,9 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
dx_buff->mss = skb_shinfo(skb)->gso_size;
dx_buff->is_txc = 1U;
 
+   dx_buff->is_ipv6 =
+   (ip_hdr(skb)->version == 6) ? 1U : 0U;
+
dx = aq_ring_next_dx(ring, dx);
dx_buff = >buff_ring[dx];
++ret;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
index 2572546..eecd6d1 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
@@ -58,7 +58,8 @@ struct __packed aq_ring_buff_s {
u8 len_l2;
u8 len_l3;
u8 len_l4;
-   u8 rsvd2;
+   u8 is_ipv6:1;
+   u8 rsvd2:7;
u32 len_pkt;
};
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index a2b746a..a536875 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -433,6 +433,9 @@ static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self,
buff->len_l3 +
buff->len_l2);
is_gso = true;
+
+   if (buff->is_ipv6)
+   txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_IPV6;
} else {
buff_pa_len = buff->len;
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index cab2931..69488c9 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -471,6 +471,9 @@ static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self,
buff->len_l3 +
buff->len_l2);
is_gso = true;
+
+   if (buff->is_ipv6)
+   txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_IPV6;
} else {
buff_pa_len = buff->len;
 
-- 
2.7.4



[PATCH v3 net 0/5] net:ethernet:aquantia: Misc fixes for atlantic driver.

2017-03-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The following patchset containg several fixes for aQuantia AQtion driver
for net tree: A couple fixes for IPv6 and other fixes.

v1->v2: Fix compilation error (using HW_ATL_A0_TXD_CTL_CMD_IPV6 instead
HW_ATL_B0_TXD_CTL_CMD_IPV6).
v2->v3: Added "Fixes" tags.

Pavel Belous (5):
  net:ethernet:aquantia: Remove adapter re-opening when MTU changed.
  net:ethernet:aquantia: Fix packet type detection (TCP/UDP) for IPv6.
  net:ethernet:aquantia: Missing spinlock initialization.
  net:ethernet:aquantia: Fix for LSO with IPv6.
  net:ethernet:aquantia: Reset is_gso flag when EOP reached.

 drivers/net/ethernet/aquantia/atlantic/aq_main.c   |  5 -
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 23 ++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c   |  1 +
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h   |  3 ++-
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |  4 
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |  4 
 6 files changed, 30 insertions(+), 10 deletions(-)

-- 
2.7.4



[PATCH v3 net 2/5] net:ethernet:aquantia: Fix packet type detection (TCP/UDP) for IPv6.

2017-03-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

In order for the checksum offloads to work correctly we need to set the
packet type bit (TCP/UDP) in the TX context buffer.

Fixes: 97bde5c4f909 ("net: ethernet: aquantia: Support for NIC-specific code")

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index ee78444..db2b51d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -510,10 +510,22 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ?
1U : 0U;
-   dx_buff->is_tcp_cso =
-   (ip_hdr(skb)->protocol == IPPROTO_TCP) ? 1U : 0U;
-   dx_buff->is_udp_cso =
-   (ip_hdr(skb)->protocol == IPPROTO_UDP) ? 1U : 0U;
+
+   if (ip_hdr(skb)->version == 4) {
+   dx_buff->is_tcp_cso =
+   (ip_hdr(skb)->protocol == IPPROTO_TCP) ?
+   1U : 0U;
+   dx_buff->is_udp_cso =
+   (ip_hdr(skb)->protocol == IPPROTO_UDP) ?
+   1U : 0U;
+   } else if (ip_hdr(skb)->version == 6) {
+   dx_buff->is_tcp_cso =
+   (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP) ?
+   1U : 0U;
+   dx_buff->is_udp_cso =
+   (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP) ?
+   1U : 0U;
+   }
}
 
for (; nr_frags--; ++frag_count) {
-- 
2.7.4



[PATCH v3 net 1/5] net:ethernet:aquantia: Remove adapter re-opening when MTU changed.

2017-03-23 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Closing/opening the adapter is not needed at all.
The new MTU settings take effect immediately.

Fixes: 97bde5c4f909 ("net: ethernet: aquantia: Support for NIC-specific code")

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index d05fbfd..5d6c40d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -100,11 +100,6 @@ static int aq_ndev_change_mtu(struct net_device *ndev, int 
new_mtu)
goto err_exit;
ndev->mtu = new_mtu;
 
-   if (netif_running(ndev)) {
-   aq_ndev_close(ndev);
-   aq_ndev_open(ndev);
-   }
-
 err_exit:
return err;
 }
-- 
2.7.4



[PATCH v2 net] net:ethernet:aquantia: Fix for RX checksum offload.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Since AQC-100/107/108 chips supports hardware checksums for RX we should 
indicate this
via NETIF_F_RXCSUM flag.

v1->v2: 'Signed-off-by' tag added.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h | 1 +
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
index 1093ea1..0592a03 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
@@ -137,6 +137,7 @@ static struct aq_hw_caps_s hw_atl_a0_hw_caps_ = {
.tx_rings = HW_ATL_A0_TX_RINGS,
.rx_rings = HW_ATL_A0_RX_RINGS,
.hw_features = NETIF_F_HW_CSUM |
+   NETIF_F_RXCSUM |
NETIF_F_RXHASH |
NETIF_F_SG |
NETIF_F_TSO,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
index 8bdee3d..f3957e93 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
@@ -188,6 +188,7 @@ static struct aq_hw_caps_s hw_atl_b0_hw_caps_ = {
.tx_rings = HW_ATL_B0_TX_RINGS,
.rx_rings = HW_ATL_B0_RX_RINGS,
.hw_features = NETIF_F_HW_CSUM |
+   NETIF_F_RXCSUM |
NETIF_F_RXHASH |
NETIF_F_SG |
NETIF_F_TSO |
-- 
2.7.4



Re: [PATCH v2 net 0/5] net:ethernet:aquantia: Misc fixes for atlantic driver.

2017-03-22 Thread Pavel Belous



On 03/23/2017 12:44 AM, Florian Fainelli wrote:

On 03/22/2017 02:19 PM, Pavel Belous wrote:

From: Pavel Belous <pavel.bel...@aquantia.com>

The following patchset containg several fixes for aQuantia AQtion driver
for net tree: A couple fixes for IPv6 and other fixes.

v1->v2: Fix compilation error (using HW_ATL_A0_TXD_CTL_CMD_IPV6 instead
HW_ATL_B0_TXD_CTL_CMD_IPV6).


Since you are fixing bugs, can you add proper Fixes: <12-digit commit>
("Commit subject") tags for each commit?

Also, you may want to fix your subjects to be:

net: ethernet: aquantia: Remove adapter re-opening when MTU changed

Thanks!



Thank you, Florian.
I will add 'Fixes' tags in patchset v3.

Regards,
Pavel




Pavel Belous (5):
  net:ethernet:aquantia: Remove adapter re-opening when mtu changed.
  net:ethernet:aquantia: Fix packet type detection (TCP/UDP) for IPv6.
  net:ethernet:aquantia: Missing spinlock initialization.
  net:ethernet:aquantia: Fix for LSO with IPv6.
  net:ethernet:aquantia: Reset is_gso flag when EOP reached.

 drivers/net/ethernet/aquantia/atlantic/aq_main.c   |  5 -
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 23 ++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c   |  1 +
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h   |  3 ++-
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |  4 
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |  4 
 6 files changed, 30 insertions(+), 10 deletions(-)






[PATCH v2 net 4/5] net:ethernet:aquantia: Fix for LSO with IPv6.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Fix Context Command bit: L3 type = "0" for IPv4, "1" for IPv6.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c   | 3 +++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h  | 3 ++-
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 3 +++
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 3 +++
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index db2b51d..cdb0299 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -487,6 +487,9 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
dx_buff->mss = skb_shinfo(skb)->gso_size;
dx_buff->is_txc = 1U;
 
+   dx_buff->is_ipv6 =
+   (ip_hdr(skb)->version == 6) ? 1U : 0U;
+
dx = aq_ring_next_dx(ring, dx);
dx_buff = >buff_ring[dx];
++ret;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
index 2572546..eecd6d1 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
@@ -58,7 +58,8 @@ struct __packed aq_ring_buff_s {
u8 len_l2;
u8 len_l3;
u8 len_l4;
-   u8 rsvd2;
+   u8 is_ipv6:1;
+   u8 rsvd2:7;
u32 len_pkt;
};
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index a2b746a..a536875 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -433,6 +433,9 @@ static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self,
buff->len_l3 +
buff->len_l2);
is_gso = true;
+
+   if (buff->is_ipv6)
+   txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_IPV6;
} else {
buff_pa_len = buff->len;
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index cab2931..69488c9 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -471,6 +471,9 @@ static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self,
buff->len_l3 +
buff->len_l2);
is_gso = true;
+
+   if (buff->is_ipv6)
+   txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_IPV6;
} else {
buff_pa_len = buff->len;
 
-- 
2.7.4



[PATCH v2 net 5/5] net:ethernet:aquantia: Reset is_gso flag when EOP reached.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We need to reset is_gso flag when EOP reached (entire LSO packet processed).

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 1 +
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index a536875..4ee15ff 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -461,6 +461,7 @@ static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self,
if (unlikely(buff->is_eop)) {
txd->ctl |= HW_ATL_A0_TXD_CTL_EOP;
txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_WB;
+   is_gso = false;
}
}
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 69488c9..4215070 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -499,6 +499,7 @@ static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self,
if (unlikely(buff->is_eop)) {
txd->ctl |= HW_ATL_B0_TXD_CTL_EOP;
txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_WB;
+   is_gso = false;
}
}
 
-- 
2.7.4



[PATCH v2 net 1/5] net:ethernet:aquantia: Remove adapter re-opening when mtu changed.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Closing/opening the adapter is not needed at all.
The new mtu settings take effect immediately.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index d05fbfd..5d6c40d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -100,11 +100,6 @@ static int aq_ndev_change_mtu(struct net_device *ndev, int 
new_mtu)
goto err_exit;
ndev->mtu = new_mtu;
 
-   if (netif_running(ndev)) {
-   aq_ndev_close(ndev);
-   aq_ndev_open(ndev);
-   }
-
 err_exit:
return err;
 }
-- 
2.7.4



[PATCH v2 net 3/5] net:ethernet:aquantia: Missing spinlock initialization.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Fix for missing initialization aq_ring header.lock spinlock.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 0358e607..3a8a4aa 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -101,6 +101,7 @@ int aq_ring_init(struct aq_ring_s *self)
self->hw_head = 0;
self->sw_head = 0;
self->sw_tail = 0;
+   spin_lock_init(>header.lock);
return 0;
 }
 
-- 
2.7.4



[PATCH v2 net 0/5] net:ethernet:aquantia: Misc fixes for atlantic driver.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The following patchset containg several fixes for aQuantia AQtion driver
for net tree: A couple fixes for IPv6 and other fixes.

v1->v2: Fix compilation error (using HW_ATL_A0_TXD_CTL_CMD_IPV6 instead
HW_ATL_B0_TXD_CTL_CMD_IPV6).


Pavel Belous (5):
  net:ethernet:aquantia: Remove adapter re-opening when mtu changed.
  net:ethernet:aquantia: Fix packet type detection (TCP/UDP) for IPv6.
  net:ethernet:aquantia: Missing spinlock initialization.
  net:ethernet:aquantia: Fix for LSO with IPv6.
  net:ethernet:aquantia: Reset is_gso flag when EOP reached.

 drivers/net/ethernet/aquantia/atlantic/aq_main.c   |  5 -
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 23 ++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c   |  1 +
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h   |  3 ++-
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |  4 
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |  4 
 6 files changed, 30 insertions(+), 10 deletions(-)

-- 
2.7.4



[PATCH v2 net 2/5] net:ethernet:aquantia: Fix packet type detection (TCP/UDP) for IPv6.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

In order for the checksum offloads to work correctly we need to set the
packet type bit (TCP/UDP) in the TX context buffer.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index ee78444..db2b51d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -510,10 +510,22 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ?
1U : 0U;
-   dx_buff->is_tcp_cso =
-   (ip_hdr(skb)->protocol == IPPROTO_TCP) ? 1U : 0U;
-   dx_buff->is_udp_cso =
-   (ip_hdr(skb)->protocol == IPPROTO_UDP) ? 1U : 0U;
+
+   if (ip_hdr(skb)->version == 4) {
+   dx_buff->is_tcp_cso =
+   (ip_hdr(skb)->protocol == IPPROTO_TCP) ?
+   1U : 0U;
+   dx_buff->is_udp_cso =
+   (ip_hdr(skb)->protocol == IPPROTO_UDP) ?
+   1U : 0U;
+   } else if (ip_hdr(skb)->version == 6) {
+   dx_buff->is_tcp_cso =
+   (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP) ?
+   1U : 0U;
+   dx_buff->is_udp_cso =
+   (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP) ?
+   1U : 0U;
+   }
}
 
for (; nr_frags--; ++frag_count) {
-- 
2.7.4



Re: [PATCH net 4/5] net:ethernet:aquantia: Fix for LSO with IPv6.

2017-03-22 Thread Pavel Belous



On 03/22/2017 10:21 PM, David Arcari wrote:

Hi,

On 03/22/2017 01:06 PM, Pavel Belous wrote:

From: Pavel Belous <pavel.bel...@aquantia.com>

Fix Context Command bit: L3 type = "0" for IPv4, "1" for IPv6.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c   | 3 +++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h  | 3 ++-
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 3 +++
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 3 +++
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 95f9841..293b261 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -487,6 +487,9 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
dx_buff->mss = skb_shinfo(skb)->gso_size;
dx_buff->is_txc = 1U;

+   dx_buff->is_ipv6 =
+   (ip_hdr(skb)->version == 6) ? 1U : 0U;
+
dx = aq_ring_next_dx(ring, dx);
dx_buff = >buff_ring[dx];
++ret;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
index 2572546..eecd6d1 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
@@ -58,7 +58,8 @@ struct __packed aq_ring_buff_s {
u8 len_l2;
u8 len_l3;
u8 len_l4;
-   u8 rsvd2;
+   u8 is_ipv6:1;
+   u8 rsvd2:7;
u32 len_pkt;
};
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index a2b746a..d62436e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -433,6 +433,9 @@ static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self,
buff->len_l3 +
buff->len_l2);
is_gso = true;
+
+   if (buff->is_ipv6)
+   txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_IPV6;


I think this is a mistake.  I believe it should be HW_ATL_A0_TXD_CTL_CMD_IPV6.

AFAICT this file doesn't include hw_atl_b0_internal.h, so I don't believe this
will compile.

Thanks,

-DA


} else {
buff_pa_len = buff->len;

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index cab2931..69488c9 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -471,6 +471,9 @@ static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self,
buff->len_l3 +
buff->len_l2);
is_gso = true;
+
+   if (buff->is_ipv6)
+   txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_IPV6;
} else {
buff_pa_len = buff->len;






Thank you, David.
I will fix this in patchset v2.

Regards,
Pavel


[PATCH net] net:ethernet:aquantia: Fix for RX checksum offload.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Since AQC-100/107/08 chips supports hardware checksums for RX we should indicate
this via NETIF_F_RXCSUM flag.
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h | 1 +
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
index 1093ea1..0592a03 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
@@ -137,6 +137,7 @@ static struct aq_hw_caps_s hw_atl_a0_hw_caps_ = {
.tx_rings = HW_ATL_A0_TX_RINGS,
.rx_rings = HW_ATL_A0_RX_RINGS,
.hw_features = NETIF_F_HW_CSUM |
+   NETIF_F_RXCSUM |
NETIF_F_RXHASH |
NETIF_F_SG |
NETIF_F_TSO,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
index 8bdee3d..f3957e93 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
@@ -188,6 +188,7 @@ static struct aq_hw_caps_s hw_atl_b0_hw_caps_ = {
.tx_rings = HW_ATL_B0_TX_RINGS,
.rx_rings = HW_ATL_B0_RX_RINGS,
.hw_features = NETIF_F_HW_CSUM |
+   NETIF_F_RXCSUM |
NETIF_F_RXHASH |
NETIF_F_SG |
NETIF_F_TSO |
-- 
2.7.4



[PATCH net 5/5] net:ethernet:aquantia: Reset is_gso flag when EOP reached.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We need to reset is_gso flag when EOP reached (entire LSO packet processed).

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 1 +
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index d62436e..9db2efa 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -461,6 +461,7 @@ static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self,
if (unlikely(buff->is_eop)) {
txd->ctl |= HW_ATL_A0_TXD_CTL_EOP;
txd->ctl |= HW_ATL_A0_TXD_CTL_CMD_WB;
+   is_gso = false;
}
}
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 69488c9..4215070 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -499,6 +499,7 @@ static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self,
if (unlikely(buff->is_eop)) {
txd->ctl |= HW_ATL_B0_TXD_CTL_EOP;
txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_WB;
+   is_gso = false;
}
}
 
-- 
2.7.4



[PATCH net 0/5] net:ethernet:aquantia: Misc fixes for atlantic driver.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The following patchset containg several fixes for aQuantia AQtion driver
for net tree: A couple fixes for IPv6 and other fixes.

Pavel Belous (5):
  net:ethernet:aquantia: Remove adapter re-opening when mtu changed.
  net:ethernet:aquantia: Fix packet type detection (TCP/UDP) for IPv6.
  net:ethernet:aquantia: Missing spinlock initialization.
  net:ethernet:aquantia: Fix for LSO with IPv6.
  net:ethernet:aquantia: Reset is_gso flag when EOP reached.

 drivers/net/ethernet/aquantia/atlantic/aq_main.c   |  5 -
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 26 +-
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c   |  1 +
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h   |  3 ++-
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |  4 
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |  4 
 6 files changed, 31 insertions(+), 12 deletions(-)

-- 
2.7.4



[PATCH net 3/5] net:ethernet:aquantia: Missing spinlock initialization.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Fix for missing initialization aq_ring header.lock spinlock.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 0358e607..3a8a4aa 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -101,6 +101,7 @@ int aq_ring_init(struct aq_ring_s *self)
self->hw_head = 0;
self->sw_head = 0;
self->sw_tail = 0;
+   spin_lock_init(>header.lock);
return 0;
 }
 
-- 
2.7.4



[PATCH net 1/5] net:ethernet:aquantia: Remove adapter re-opening when mtu changed.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Closing/opening the adapter is not needed at all.
The new mtu settings take effect immediately.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index d05fbfd..5d6c40d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -100,11 +100,6 @@ static int aq_ndev_change_mtu(struct net_device *ndev, int 
new_mtu)
goto err_exit;
ndev->mtu = new_mtu;
 
-   if (netif_running(ndev)) {
-   aq_ndev_close(ndev);
-   aq_ndev_open(ndev);
-   }
-
 err_exit:
return err;
 }
-- 
2.7.4



[PATCH net 4/5] net:ethernet:aquantia: Fix for LSO with IPv6.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Fix Context Command bit: L3 type = "0" for IPv4, "1" for IPv6.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c   | 3 +++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h  | 3 ++-
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 3 +++
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 3 +++
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 95f9841..293b261 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -487,6 +487,9 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
dx_buff->mss = skb_shinfo(skb)->gso_size;
dx_buff->is_txc = 1U;
 
+   dx_buff->is_ipv6 =
+   (ip_hdr(skb)->version == 6) ? 1U : 0U;
+
dx = aq_ring_next_dx(ring, dx);
dx_buff = >buff_ring[dx];
++ret;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
index 2572546..eecd6d1 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
@@ -58,7 +58,8 @@ struct __packed aq_ring_buff_s {
u8 len_l2;
u8 len_l3;
u8 len_l4;
-   u8 rsvd2;
+   u8 is_ipv6:1;
+   u8 rsvd2:7;
u32 len_pkt;
};
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index a2b746a..d62436e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -433,6 +433,9 @@ static int hw_atl_a0_hw_ring_tx_xmit(struct aq_hw_s *self,
buff->len_l3 +
buff->len_l2);
is_gso = true;
+
+   if (buff->is_ipv6)
+   txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_IPV6;
} else {
buff_pa_len = buff->len;
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index cab2931..69488c9 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -471,6 +471,9 @@ static int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self,
buff->len_l3 +
buff->len_l2);
is_gso = true;
+
+   if (buff->is_ipv6)
+   txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_IPV6;
} else {
buff_pa_len = buff->len;
 
-- 
2.7.4



[PATCH net 2/5] net:ethernet:aquantia: Fix packet type detection (TCP/UDP) for IPv6.

2017-03-22 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

In order for the checksum offloads to work correctly we need to set the
packet type bit (TCP/UDP) in the TX context buffer.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 23 +--
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index ee78444..95f9841 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -508,12 +508,23 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
++ret;
 
if (skb->ip_summed == CHECKSUM_PARTIAL) {
-   dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ?
-   1U : 0U;
-   dx_buff->is_tcp_cso =
-   (ip_hdr(skb)->protocol == IPPROTO_TCP) ? 1U : 0U;
-   dx_buff->is_udp_cso =
-   (ip_hdr(skb)->protocol == IPPROTO_UDP) ? 1U : 0U;
+   dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ? 1U : 
0U;
+
+   if (ip_hdr(skb)->version == 4) {
+   dx_buff->is_tcp_cso =
+   (ip_hdr(skb)->protocol == IPPROTO_TCP) ?
+   1U : 0U;
+   dx_buff->is_udp_cso =
+   (ip_hdr(skb)->protocol == IPPROTO_UDP) ?
+   1U : 0U;
+   } else if (ip_hdr(skb)->version == 6) {
+   dx_buff->is_tcp_cso =
+   (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP) ?
+   1U : 0U;
+   dx_buff->is_udp_cso =
+   (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP) ?
+   1U : 0U;
+   }
}
 
for (; nr_frags--; ++frag_count) {
-- 
2.7.4



Re: [PATCH] net: ethernet: aquantia: set net_device mtu when mtu is changed

2017-03-13 Thread Pavel Belous


On 03/14/2017 02:07 AM, David Arcari wrote:

When the aquantia device mtu is changed the net_device structure is not
updated.  As a result the ip command does not properly reflect the mtu change.

Commit 5513e16421cb incorrectly assumed that __dev_set_mtu() was making the
assignment ndev->mtu = new_mtu;  This is not true in the case where the driver
has a ndo_change_mtu routine.

Fixes: 5513e16421cb ("net: ethernet: aquantia: Fixes for aq_ndev_change_mtu")

Cc: Pavel Belous <pavel.bel...@aquantia.com>
Signed-off-by: David Arcari <darc...@redhat.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index dad6362..d05fbfd 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -98,6 +98,7 @@ static int aq_ndev_change_mtu(struct net_device *ndev, int 
new_mtu)

if (err < 0)
goto err_exit;
+   ndev->mtu = new_mtu;

if (netif_running(ndev)) {
aq_ndev_close(ndev);



Tested-by: Pavel Belous <pavel.bel...@aquantia.com>


Re: [PATCH v2] net: ethernet: aquantia: set net_device mtu when mtu is changed

2017-03-10 Thread Pavel Belous



On 10.03.2017 17:47, David Arcari wrote:

Hi,

On 03/09/2017 05:43 PM, Lino Sanfilippo wrote:

Hi,

On 09.03.2017 22:03, David Arcari wrote:

When the aquantia device mtu is changed the net_device structure is not
updated.  As a result the ip command does not properly reflect the mtu change.

Commit 5513e16421cb incorrectly assumed that __dev_set_mtu() was making the
assignment ndev->mtu = new_mtu;  This is not true in the case where the driver
has a ndo_change_mtu routine.

Fixes: 5513e16421cb ("net: ethernet: aquantia: Fixes for aq_ndev_change_mtu")

v2: no longer close/open net-device after mtu change

Cc: Pavel Belous <pavel.bel...@aquantia.com>
Signed-off-by: David Arcari <darc...@redhat.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index dad6362..bba5ebd 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -96,15 +96,9 @@ static int aq_ndev_change_mtu(struct net_device *ndev, int 
new_mtu)
struct aq_nic_s *aq_nic = netdev_priv(ndev);
int err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);

-   if (err < 0)
-   goto err_exit;
+   if (!err)
+   ndev->mtu = new_mtu;

-   if (netif_running(ndev)) {
-   aq_ndev_close(ndev);
-   aq_ndev_open(ndev);
-   }
-
-err_exit:


Removing the restart has nothing to do with the bug you want to fix here, has 
it?
I suggest to send a separate patch for this.

Regards,
Lino



I'm fine with that.  Pavel does that work for you?

It would mean that the original version of this patch should be applied and
either you or I could send the follow-up patch.

Best,

-Dave



David,

Yes, I think for this it is better to make separate patch.
I can prepare a patch for "close/open netdev" myself.

Probably you need send the original version of this patch as "v3" (I'm 
no sure what it is possible to discard v2 and apply v1 instead.)


Thank you,
Pavel


Re: [PATCH v2] net: ethernet: aquantia: set net_device mtu when mtu is changed

2017-03-09 Thread Pavel Belous



On 10.03.2017 00:03, David Arcari wrote:

When the aquantia device mtu is changed the net_device structure is not
updated.  As a result the ip command does not properly reflect the mtu change.

Commit 5513e16421cb incorrectly assumed that __dev_set_mtu() was making the
assignment ndev->mtu = new_mtu;  This is not true in the case where the driver
has a ndo_change_mtu routine.

Fixes: 5513e16421cb ("net: ethernet: aquantia: Fixes for aq_ndev_change_mtu")

v2: no longer close/open net-device after mtu change

Cc: Pavel Belous <pavel.bel...@aquantia.com>
Signed-off-by: David Arcari <darc...@redhat.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index dad6362..bba5ebd 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -96,15 +96,9 @@ static int aq_ndev_change_mtu(struct net_device *ndev, int 
new_mtu)
struct aq_nic_s *aq_nic = netdev_priv(ndev);
int err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);

-   if (err < 0)
-   goto err_exit;
+   if (!err)
+   ndev->mtu = new_mtu;

-   if (netif_running(ndev)) {
-   aq_ndev_close(ndev);
-   aq_ndev_open(ndev);
-   }
-
-err_exit:
    return err;
 }




Tested-by: Pavel Belous <pavel.bel...@aquantia.com>


Re: [PATCH] net: ethernet: aquantia: set net_device mtu when mtu is changed

2017-03-09 Thread Pavel Belous



On 09.03.2017 23:28, David Arcari wrote:

On 03/09/2017 03:01 PM, David Arcari wrote:

On 03/09/2017 02:02 PM, Pavel Belous wrote:



On 09.03.2017 00:33, David Arcari wrote:

When the aquantia device mtu is changed the net_device structure is not
updated.  As a result the ip command does not properly reflect the mtu change.

Commit 5513e16421cb incorrectly assumed that __dev_set_mtu() was making the
assignment ndev->mtu = new_mtu;  This is not true in the case where the driver
has a ndo_change_mtu routine.

Fixes: 5513e16421cb ("net: ethernet: aquantia: Fixes for aq_ndev_change_mtu")

Cc: Pavel Belous <pavel.bel...@aquantia.com>
Signed-off-by: David Arcari <darc...@redhat.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index dad6362..d05fbfd 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -98,6 +98,7 @@ static int aq_ndev_change_mtu(struct net_device *ndev, int
new_mtu)

 if (err < 0)
 goto err_exit;
+ndev->mtu = new_mtu;

 if (netif_running(ndev)) {
 aq_ndev_close(ndev);



Thank you, David.

I think we should also remove closing/opening net-device after mtu changed.


Hi Pavel,

I'll go ahead and submit v2.

Thanks,

-Dave


Hi Pavel,

Before I post v2, won't that mean that if the interface is up that the user will
have to manually toggle it for the new mtu to take effect?

Is that the desired behavior?

Thanks,

-Dave





Regards,
Pavel






No. The new mtu will take effect immediately.
Closing/opening is not needed at all.


Regards,
Pavel


Re: [PATCH] net: ethernet: aquantia: call set_irq_affinity_hint before free_irq

2017-03-09 Thread Pavel Belous



On 09.03.2017 21:28, David Arcari wrote:

When a network interface controlled by the aquantia ethernet driver is brought
down a warning is output in dmesg (see below).

The problem is that aq_pci_func_free_irqs() is calling free_irq() before it is
calling irq_set_affinity_hint().

WARNING: CPU: 4 PID: 10068 at kernel/irq/manage.c:1503 __free_irq+0x24d/0x2b0

Call Trace:
 dump_stack+0x63/0x87
 __warn+0xd1/0xf0
 warn_slowpath_null+0x1d/0x20
 __free_irq+0x24d/0x2b0
 free_irq+0x39/0x90
 aq_pci_func_free_irqs+0x52/0xa0 [atlantic]
 aq_nic_stop+0xca/0xd0 [atlantic]
 aq_ndev_close+0x1d/0x40 [atlantic]
 __dev_close_many+0x99/0x100
 __dev_close+0x67/0xb0


Fixes: 36a4a50f4048 ("net: ethernet: aquantia: switch to pci_alloc_irq_vectors")

Cc: Christoph Hellwig <h...@lst.de>
Cc: Pavel Belous <pavel.bel...@aquantia.com>
Signed-off-by: David Arcari <darc...@redhat.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
index 581de71..4c6c882 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
@@ -213,9 +213,9 @@ void aq_pci_func_free_irqs(struct aq_pci_func_s *self)
if (!((1U << i) & self->msix_entry_mask))
continue;

-   free_irq(pci_irq_vector(pdev, i), self->aq_vec[i]);
if (pdev->msix_enabled)
irq_set_affinity_hint(pci_irq_vector(pdev, i), NULL);
+   free_irq(pci_irq_vector(pdev, i), self->aq_vec[i]);
self->msix_entry_mask &= ~(1U << i);
}
 }



Tested-by: Pavel Belous <pavel.bel...@aquantia.com>


Re: [PATCH] net: ethernet: aquantia: set net_device mtu when mtu is changed

2017-03-09 Thread Pavel Belous



On 09.03.2017 00:33, David Arcari wrote:

When the aquantia device mtu is changed the net_device structure is not
updated.  As a result the ip command does not properly reflect the mtu change.

Commit 5513e16421cb incorrectly assumed that __dev_set_mtu() was making the
assignment ndev->mtu = new_mtu;  This is not true in the case where the driver
has a ndo_change_mtu routine.

Fixes: 5513e16421cb ("net: ethernet: aquantia: Fixes for aq_ndev_change_mtu")

Cc: Pavel Belous <pavel.bel...@aquantia.com>
Signed-off-by: David Arcari <darc...@redhat.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index dad6362..d05fbfd 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -98,6 +98,7 @@ static int aq_ndev_change_mtu(struct net_device *ndev, int 
new_mtu)

if (err < 0)
goto err_exit;
+   ndev->mtu = new_mtu;

if (netif_running(ndev)) {
aq_ndev_close(ndev);



Thank you, David.

I think we should also remove closing/opening net-device after mtu changed.

Regards,
Pavel


[PATCH net-next v4 10/12] net: ethernet: aquantia: Fixed incorrect buff->len calculation.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

rxd_wb->pkt_len is the total length of the packet.
If we received a large packet (with length > AQ_CFG_RX_FRAME_MAX) then we
will get multiple buffers. We need to fix the length of the last buffer.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 4 ++--
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 1f38805..a2b746a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -659,8 +659,8 @@ static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s 
*self,
}
 
if (HW_ATL_A0_RXD_WB_STAT2_EOP & rxd_wb->status) {
-   buff->len = (rxd_wb->pkt_len &
-   (AQ_CFG_RX_FRAME_MAX - 1U));
+   buff->len = rxd_wb->pkt_len %
+   AQ_CFG_RX_FRAME_MAX;
buff->len = buff->len ?
buff->len : AQ_CFG_RX_FRAME_MAX;
buff->next = 0U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index e7e694f..cab2931 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -673,8 +673,8 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s 
*self,
}
 
if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
-   buff->len = (rxd_wb->pkt_len &
-   (AQ_CFG_RX_FRAME_MAX - 1U));
+   buff->len = rxd_wb->pkt_len %
+   AQ_CFG_RX_FRAME_MAX;
buff->len = buff->len ?
buff->len : AQ_CFG_RX_FRAME_MAX;
buff->next = 0U;
-- 
2.7.4



[PATCH net-next v4 05/12] net: ethernet: aquantia: Superfluous initialization of "err".

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Fixed superfluous initialization of err.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index 91c66f5..dad6362 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -87,14 +87,8 @@ static int aq_ndev_close(struct net_device *ndev)
 static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
struct aq_nic_s *aq_nic = netdev_priv(ndev);
-   int err = 0;
-
-   err = aq_nic_xmit(aq_nic, skb);
-   if (err < 0)
-   goto err_exit;
 
-err_exit:
-   return err;
+   return aq_nic_xmit(aq_nic, skb);
 }
 
 static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
-- 
2.7.4



[PATCH net-next v4 07/12] net: ethernet: aquantia: Using NETDEV_TX_OK instead 0.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Use NETDEV_TX_OK as the return value for successful transmission.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 646314c..019bcc7 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -568,7 +568,7 @@ __acquires(>lock)
unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;
unsigned int tc = 0U;
unsigned int trys = AQ_CFG_LOCK_TRYS;
-   int err = 0;
+   int err = NETDEV_TX_OK;
bool is_nic_in_bad_state;
struct aq_ring_buff_s buffers[AQ_CFG_SKB_FRAGS_MAX];
 
-- 
2.7.4



[PATCH net-next v4 12/12] net: ethernet: aquantia: Copying tx buffers is not needed.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This fix removes copying of tx biffers.
Now we use ring->buff_fing directly.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c  | 170 +--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c |  19 ---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h |   3 -
 3 files changed, 97 insertions(+), 95 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index bce312a..ee78444 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -468,95 +468,116 @@ int aq_nic_start(struct aq_nic_s *self)
return err;
 }
 
-static unsigned int aq_nic_map_skb_frag(struct aq_nic_s *self,
-   struct sk_buff *skb,
-   struct aq_ring_buff_s *dx)
+static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
+  struct sk_buff *skb,
+  struct aq_ring_s *ring)
 {
unsigned int ret = 0U;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int frag_count = 0U;
+   unsigned int dx = ring->sw_tail;
+   struct aq_ring_buff_s *dx_buff = >buff_ring[dx];
 
-   dx->flags = 0U;
-   dx->len = skb_headlen(skb);
-   dx->pa = dma_map_single(aq_nic_get_dev(self), skb->data, dx->len,
-   DMA_TO_DEVICE);
-   dx->len_pkt = skb->len;
-   dx->is_sop = 1U;
-   dx->is_mapped = 1U;
+   if (unlikely(skb_is_gso(skb))) {
+   dx_buff->flags = 0U;
+   dx_buff->len_pkt = skb->len;
+   dx_buff->len_l2 = ETH_HLEN;
+   dx_buff->len_l3 = ip_hdrlen(skb);
+   dx_buff->len_l4 = tcp_hdrlen(skb);
+   dx_buff->mss = skb_shinfo(skb)->gso_size;
+   dx_buff->is_txc = 1U;
+
+   dx = aq_ring_next_dx(ring, dx);
+   dx_buff = >buff_ring[dx];
+   ++ret;
+   }
+
+   dx_buff->flags = 0U;
+   dx_buff->len = skb_headlen(skb);
+   dx_buff->pa = dma_map_single(aq_nic_get_dev(self),
+skb->data,
+dx_buff->len,
+DMA_TO_DEVICE);
 
+   if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa)))
+   goto exit;
+
+   dx_buff->len_pkt = skb->len;
+   dx_buff->is_sop = 1U;
+   dx_buff->is_mapped = 1U;
++ret;
 
if (skb->ip_summed == CHECKSUM_PARTIAL) {
-   dx->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ? 1U : 0U;
-   dx->is_tcp_cso =
+   dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ?
+   1U : 0U;
+   dx_buff->is_tcp_cso =
(ip_hdr(skb)->protocol == IPPROTO_TCP) ? 1U : 0U;
-   dx->is_udp_cso =
+   dx_buff->is_udp_cso =
(ip_hdr(skb)->protocol == IPPROTO_UDP) ? 1U : 0U;
}
 
for (; nr_frags--; ++frag_count) {
-   unsigned int frag_len;
+   unsigned int frag_len = 0U;
dma_addr_t frag_pa;
skb_frag_t *frag = _shinfo(skb)->frags[frag_count];
 
frag_len = skb_frag_size(frag);
-
frag_pa = skb_frag_dma_map(aq_nic_get_dev(self), frag, 0,
   frag_len, DMA_TO_DEVICE);
 
+   if (unlikely(dma_mapping_error(aq_nic_get_dev(self), frag_pa)))
+   goto mapping_error;
+
while (frag_len > AQ_CFG_TX_FRAME_MAX) {
-   ++dx;
-   ++ret;
-   dx->flags = 0U;
-   dx->len = AQ_CFG_TX_FRAME_MAX;
-   dx->pa = frag_pa;
-   dx->is_mapped = 1U;
+   dx = aq_ring_next_dx(ring, dx);
+   dx_buff = >buff_ring[dx];
+
+   dx_buff->flags = 0U;
+   dx_buff->len = AQ_CFG_TX_FRAME_MAX;
+   dx_buff->pa = frag_pa;
+   dx_buff->is_mapped = 1U;
 
frag_len -= AQ_CFG_TX_FRAME_MAX;
frag_pa += AQ_CFG_TX_FRAME_MAX;
+   ++ret;
}
 
-   ++dx;
-   ++ret;
+   dx = aq_ring_next_dx(ring, dx);
+   dx_buff = >buff_ring[dx];
 
-   dx->flags = 0U;
-   dx->len = frag_len;
-   dx->pa = frag_pa;
-   dx->is_mapped = 1U;
+   dx_buff-

[PATCH net-next v4 04/12] net: ethernet: aquantia: Using module_pci_driver.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Remove boilerplate code by using macro module_pci_driver.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index 45c769e..91c66f5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -242,22 +242,4 @@ static struct pci_driver aq_pci_ops = {
.resume = aq_pci_resume,
 };
 
-static int __init aq_module_init(void)
-{
-   int err = 0;
-
-   err = pci_register_driver(_pci_ops);
-   if (err < 0)
-   goto err_exit;
-
-err_exit:
-   return err;
-}
-
-static void __exit aq_module_exit(void)
-{
-   pci_unregister_driver(_pci_ops);
-}
-
-module_init(aq_module_init);
-module_exit(aq_module_exit);
+module_pci_driver(aq_pci_ops);
-- 
2.7.4



[PATCH net-next v4 06/12] net: ethernet: aquantia: Fixed missing rtnl_unlock.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

rtnl_unlock should be called if error occurred.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 4b8d074..646314c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -932,7 +932,7 @@ int aq_nic_change_pm_state(struct aq_nic_s *self, 
pm_message_t *pm_msg)
 
if (!netif_running(self->ndev)) {
err = 0;
-   goto err_exit;
+   goto out;
}
rtnl_lock();
if (pm_msg->event & PM_EVENT_SLEEP || pm_msg->event & PM_EVENT_FREEZE) {
@@ -957,8 +957,9 @@ int aq_nic_change_pm_state(struct aq_nic_s *self, 
pm_message_t *pm_msg)
netif_device_attach(self->ndev);
netif_tx_start_all_queues(self->ndev);
}
-   rtnl_unlock();
 
 err_exit:
+   rtnl_unlock();
+out:
return err;
 }
-- 
2.7.4



[PATCH net-next v4 02/12] net: ethernet: aquantia: Removed busy_count field.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

 busy_count field and is_busy flag is not needed at all.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c   | 11 ---
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h |  1 -
 2 files changed, 12 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index aa22a7c..a153750 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -122,14 +122,11 @@ static void aq_nic_service_timer_cb(unsigned long param)
struct aq_nic_s *self = (struct aq_nic_s *)param;
struct net_device *ndev = aq_nic_get_ndev(self);
int err = 0;
-   bool is_busy = false;
unsigned int i = 0U;
struct aq_hw_link_status_s link_status;
struct aq_ring_stats_rx_s stats_rx;
struct aq_ring_stats_tx_s stats_tx;
 
-   atomic_inc(>header.busy_count);
-   is_busy = true;
if (aq_utils_obj_test(>header.flags, AQ_NIC_FLAGS_IS_NOT_READY))
goto err_exit;
 
@@ -170,8 +167,6 @@ static void aq_nic_service_timer_cb(unsigned long param)
ndev->stats.tx_errors = stats_tx.errors;
 
 err_exit:
-   if (is_busy)
-   atomic_dec(>header.busy_count);
mod_timer(>service_timer,
  jiffies + AQ_CFG_SERVICE_TIMER_INTERVAL);
 }
@@ -574,16 +569,12 @@ __acquires(>lock)
unsigned int trys = AQ_CFG_LOCK_TRYS;
int err = 0;
bool is_nic_in_bad_state;
-   bool is_busy = false;
struct aq_ring_buff_s buffers[AQ_CFG_SKB_FRAGS_MAX];
 
frags = skb_shinfo(skb)->nr_frags + 1;
 
ring = self->aq_ring_tx[AQ_NIC_TCVEC2RING(self, tc, vec)];
 
-   atomic_inc(>header.busy_count);
-   is_busy = true;
-
if (frags > AQ_CFG_SKB_FRAGS_MAX) {
dev_kfree_skb_any(skb);
goto err_exit;
@@ -629,8 +620,6 @@ __acquires(>lock)
}
 
 err_exit:
-   if (is_busy)
-   atomic_dec(>header.busy_count);
return err;
 }
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
index 4446bd9..f6012b3 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
@@ -19,7 +19,6 @@
 struct aq_obj_s {
spinlock_t lock; /* spinlock for nic/rings processing */
atomic_t flags;
-   atomic_t busy_count;
 };
 
 static inline void aq_utils_obj_set(atomic_t *flags, u32 mask)
-- 
2.7.4



[PATCH net-next v4 11/12] net: ethernet: aquantia: Fixed memory allocation if AQ_CFG_RX_FRAME_MAX > 1 page.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We should allocate the number of pages based on the config parameter
AQ_CFG_RX_FRAME_MAX.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 22bb75e..51f4e7f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -270,6 +270,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self, int 
*work_done, int budget)
 
 int aq_ring_rx_fill(struct aq_ring_s *self)
 {
+   unsigned int pages_order = fls(AQ_CFG_RX_FRAME_MAX / PAGE_SIZE +
+   (AQ_CFG_RX_FRAME_MAX % PAGE_SIZE ? 1 : 0)) - 1;
struct aq_ring_buff_s *buff = NULL;
int err = 0;
int i = 0;
@@ -282,7 +284,7 @@ int aq_ring_rx_fill(struct aq_ring_s *self)
buff->len = AQ_CFG_RX_FRAME_MAX;
 
buff->page = alloc_pages(GFP_ATOMIC | __GFP_COLD |
-__GFP_COMP, 0);
+__GFP_COMP, pages_order);
if (!buff->page) {
err = -ENOMEM;
goto err_exit;
-- 
2.7.4



[PATCH net-next v4 09/12] net: ethernet: aquantia: Call netdev_register after all initialized.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

netdev_register should be called when everything is initialized.
Also we should use net_device->reg_state field instead own
"is_ndev_registered" flag to avoid any race.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c  | 10 +-
 drivers/net/ethernet/aquantia/atlantic/aq_nic_internal.h |  1 -
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index a8a27c5..bce312a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -261,16 +261,16 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
ether_addr_copy(self->ndev->dev_addr, mac_addr_permanent);
}
 #endif
-   err = register_netdev(self->ndev);
-   if (err < 0)
-   goto err_exit;
 
-   self->is_ndev_registered = true;
netif_carrier_off(self->ndev);
 
for (i = AQ_CFG_VECS_MAX; i--;)
aq_nic_ndev_queue_stop(self, i);
 
+   err = register_netdev(self->ndev);
+   if (err < 0)
+   goto err_exit;
+
 err_exit:
return err;
 }
@@ -293,7 +293,7 @@ void aq_nic_ndev_free(struct aq_nic_s *self)
if (!self->ndev)
goto err_exit;
 
-   if (self->is_ndev_registered)
+   if (self->ndev->reg_state == NETREG_REGISTERED)
unregister_netdev(self->ndev);
 
if (self->aq_hw)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic_internal.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic_internal.h
index f81738a..e7d2711 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic_internal.h
@@ -22,7 +22,6 @@ struct aq_nic_s {
unsigned int aq_vecs;
unsigned int packet_filter;
unsigned int power_state;
-   bool is_ndev_registered;
u8 port;
struct aq_hw_ops aq_hw_ops;
struct aq_hw_caps_s aq_hw_caps;
-- 
2.7.4



[PATCH net-next v4 08/12] net: ethernet: aquantia: Null pointer check for aq_nic_ndev_alloc.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We should check for a null pointer for aq_nic_ndev_alloc
instead netdev_priv.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 019bcc7..a8a27c5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -202,12 +202,13 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct 
net_device_ops *ndev_ops,
int err = 0;
 
ndev = aq_nic_ndev_alloc();
-   self = netdev_priv(ndev);
-   if (!self) {
-   err = -EINVAL;
+   if (!ndev) {
+   err = -ENOMEM;
goto err_exit;
}
 
+   self = netdev_priv(ndev);
+
ndev->netdev_ops = ndev_ops;
ndev->ethtool_ops = et_ops;
 
-- 
2.7.4



[PATCH net-next v4 03/12] net: ethernet: aquantia: Fixes for aq_ndev_change_mtu

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

1)Removed unnecessary comparsion "old_mtu == new_mtu".
This check is not needed. Function aq_ndev_change_mtu wont be called
if mtu has not changed.

2)Removed extra assignment ndev->mtu = new_mtu;
This assignment already done inside __dev_set_mtu().

3)Use core MTU checking for min_mtu.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 12 +---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c  |  1 +
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index c17c70a..45c769e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -100,20 +100,10 @@ static int aq_ndev_start_xmit(struct sk_buff *skb, struct 
net_device *ndev)
 static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
 {
struct aq_nic_s *aq_nic = netdev_priv(ndev);
-   int err = 0;
+   int err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);
 
-   if (new_mtu == ndev->mtu) {
-   err = 0;
-   goto err_exit;
-   }
-   if (new_mtu < 68) {
-   err = -EINVAL;
-   goto err_exit;
-   }
-   err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);
if (err < 0)
goto err_exit;
-   ndev->mtu = new_mtu;
 
if (netif_running(ndev)) {
aq_ndev_close(ndev);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index a153750..4b8d074 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -214,6 +214,7 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct 
net_device_ops *ndev_ops,
SET_NETDEV_DEV(ndev, dev);
 
ndev->if_port = port;
+   ndev->min_mtu = ETH_MIN_MTU;
self->ndev = ndev;
 
self->aq_pci_func = aq_pci_func;
-- 
2.7.4



[PATCH net-next v4 00/12] net: ethernet: aquantia: improvements and fixes

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The following patchset contains improvements and fixes for aQuantia
AQtion ethernet driver from net-next tree.

Most fixes are based on the comments from Lino Sanfilippo.

Sanity testing was performed on real HW. No regression found.

v1->v2: 1)Removed buffers copying.
2)Fixed dma error handling.

v2->v3: 1)Fixes for aq_ndev_change_mtu:
-Use core MTU checking for min_mtu.
-Removed extra new_mtu assigment.
2)Reverse XMAS tree in aq_ring_rx_fill.
v3->v4: 1)Use ndev->reg_state instead "is_ndev_registered" flag.

Please review.
Thanks.
Pavel Belous (12):
  net: ethernet: aquantia: Removed extra assignment for skb->dev.
  net: ethernet: aquantia: Removed busy_count field.
  net: ethernet: aquantia: Fixes for aq_ndev_change_mtu
  net: ethernet: aquantia: Using module_pci_driver.
  net: ethernet: aquantia: Superfluous initialization of "err".
  net: ethernet: aquantia: Fixed missing rtnl_unlock.
  net: ethernet: aquantia: Using NETDEV_TX_OK instead 0.
  net: ethernet: aquantia: Null pointer check for aq_nic_ndev_alloc.
  net: ethernet: aquantia: Call netdev_register after all initialized.
  net: ethernet: aquantia: Fixed incorrect buff->len calculation.
  net: ethernet: aquantia: Fixed memory allocation if
AQ_CFG_RX_FRAME_MAX > 1 page.
  net: ethernet: aquantia: Copying tx buffers is not needed.

 drivers/net/ethernet/aquantia/atlantic/aq_main.c   |  40 +---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 206 +++--
 .../ethernet/aquantia/atlantic/aq_nic_internal.h   |   1 -
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c   |  24 +--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h   |   3 -
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h  |   1 -
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |   4 +-
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |   4 +-
 8 files changed, 121 insertions(+), 162 deletions(-)

-- 
2.7.4



[PATCH net-next v4 01/12] net: ethernet: aquantia: Removed extra assignment for skb->dev.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This assignment is not needed.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index fed6ac5..22bb75e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -209,7 +209,6 @@ int aq_ring_rx_clean(struct aq_ring_s *self, int 
*work_done, int budget)
goto err_exit;
}
 
-   skb->dev = ndev;
skb_put(skb, buff->len);
} else {
skb = netdev_alloc_skb(ndev, ETH_HLEN);
-- 
2.7.4



Re: [PATCH] net: aquantia: remove function aq_ring_tx_deinit

2017-02-20 Thread Pavel Belous
aq_vec_deinit(struct aq_vec_s *self)

for (i = 0U, ring = self->ring[0];
self->tx_rings > i; ++i, ring = self->ring[i]) {
-   aq_ring_tx_deinit([AQ_VEC_TX_ID]);
+   aq_ring_tx_clean([AQ_VEC_TX_ID]);
        aq_ring_rx_deinit([AQ_VEC_RX_ID]);
}
 err_exit:;



Tested-by: Pavel Belous <pavel.bel...@aquantia.com>


[PATCH net-next v3 12/12] net: ethernet: aquantia: Copying tx buffers is not needed.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This fix removes copying of tx biffers.
Now we use ring->buff_fing directly.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c  | 170 +--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c |  19 ---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h |   3 -
 3 files changed, 97 insertions(+), 95 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 0b208c4..5c80162 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -470,95 +470,116 @@ int aq_nic_start(struct aq_nic_s *self)
return err;
 }
 
-static unsigned int aq_nic_map_skb_frag(struct aq_nic_s *self,
-   struct sk_buff *skb,
-   struct aq_ring_buff_s *dx)
+static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
+  struct sk_buff *skb,
+  struct aq_ring_s *ring)
 {
unsigned int ret = 0U;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int frag_count = 0U;
+   unsigned int dx = ring->sw_tail;
+   struct aq_ring_buff_s *dx_buff = >buff_ring[dx];
 
-   dx->flags = 0U;
-   dx->len = skb_headlen(skb);
-   dx->pa = dma_map_single(aq_nic_get_dev(self), skb->data, dx->len,
-   DMA_TO_DEVICE);
-   dx->len_pkt = skb->len;
-   dx->is_sop = 1U;
-   dx->is_mapped = 1U;
+   if (unlikely(skb_is_gso(skb))) {
+   dx_buff->flags = 0U;
+   dx_buff->len_pkt = skb->len;
+   dx_buff->len_l2 = ETH_HLEN;
+   dx_buff->len_l3 = ip_hdrlen(skb);
+   dx_buff->len_l4 = tcp_hdrlen(skb);
+   dx_buff->mss = skb_shinfo(skb)->gso_size;
+   dx_buff->is_txc = 1U;
+
+   dx = aq_ring_next_dx(ring, dx);
+   dx_buff = >buff_ring[dx];
+   ++ret;
+   }
+
+   dx_buff->flags = 0U;
+   dx_buff->len = skb_headlen(skb);
+   dx_buff->pa = dma_map_single(aq_nic_get_dev(self),
+skb->data,
+dx_buff->len,
+DMA_TO_DEVICE);
 
+   if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa)))
+   goto exit;
+
+   dx_buff->len_pkt = skb->len;
+   dx_buff->is_sop = 1U;
+   dx_buff->is_mapped = 1U;
++ret;
 
if (skb->ip_summed == CHECKSUM_PARTIAL) {
-   dx->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ? 1U : 0U;
-   dx->is_tcp_cso =
+   dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ?
+   1U : 0U;
+   dx_buff->is_tcp_cso =
(ip_hdr(skb)->protocol == IPPROTO_TCP) ? 1U : 0U;
-   dx->is_udp_cso =
+   dx_buff->is_udp_cso =
(ip_hdr(skb)->protocol == IPPROTO_UDP) ? 1U : 0U;
}
 
for (; nr_frags--; ++frag_count) {
-   unsigned int frag_len;
+   unsigned int frag_len = 0U;
dma_addr_t frag_pa;
skb_frag_t *frag = _shinfo(skb)->frags[frag_count];
 
frag_len = skb_frag_size(frag);
-
frag_pa = skb_frag_dma_map(aq_nic_get_dev(self), frag, 0,
   frag_len, DMA_TO_DEVICE);
 
+   if (unlikely(dma_mapping_error(aq_nic_get_dev(self), frag_pa)))
+   goto mapping_error;
+
while (frag_len > AQ_CFG_TX_FRAME_MAX) {
-   ++dx;
-   ++ret;
-   dx->flags = 0U;
-   dx->len = AQ_CFG_TX_FRAME_MAX;
-   dx->pa = frag_pa;
-   dx->is_mapped = 1U;
+   dx = aq_ring_next_dx(ring, dx);
+   dx_buff = >buff_ring[dx];
+
+   dx_buff->flags = 0U;
+   dx_buff->len = AQ_CFG_TX_FRAME_MAX;
+   dx_buff->pa = frag_pa;
+   dx_buff->is_mapped = 1U;
 
frag_len -= AQ_CFG_TX_FRAME_MAX;
frag_pa += AQ_CFG_TX_FRAME_MAX;
+   ++ret;
}
 
-   ++dx;
-   ++ret;
+   dx = aq_ring_next_dx(ring, dx);
+   dx_buff = >buff_ring[dx];
 
-   dx->flags = 0U;
-   dx->len = frag_len;
-   dx->pa = frag_pa;
-   dx->is_mapped = 1U;
+   dx_buff-

[PATCH net-next v3 05/12] net: ethernet: aquantia: Superfluous initialization of "err".

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Fixed superfluous initialization of err.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index 91c66f5..dad6362 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -87,14 +87,8 @@ static int aq_ndev_close(struct net_device *ndev)
 static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
struct aq_nic_s *aq_nic = netdev_priv(ndev);
-   int err = 0;
-
-   err = aq_nic_xmit(aq_nic, skb);
-   if (err < 0)
-   goto err_exit;
 
-err_exit:
-   return err;
+   return aq_nic_xmit(aq_nic, skb);
 }
 
 static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
-- 
2.7.4



[PATCH net-next v3 11/12] net: ethernet: aquantia: Fixed memory allocation if AQ_CFG_RX_FRAME_MAX > 1 page.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We should allocate the number of pages based on the config parameter
AQ_CFG_RX_FRAME_MAX.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c  | 4 ++--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 4 +++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index fdd7d72..0b208c4 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -597,9 +597,9 @@ __acquires(>lock)
 
do {
if (spin_trylock(>header.lock)) {
-   frags = aq_nic_map_skb(self, skb, [0]);
+   frags = aq_nic_map_skb(self, skb, buffers);
 
-   aq_ring_tx_append_buffs(ring, [0], frags);
+   aq_ring_tx_append_buffs(ring, buffers, frags);
 
err = self->aq_hw_ops.hw_ring_tx_xmit(self->aq_hw,
  ring, frags);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 4c40644..042976d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -275,6 +275,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self, int 
*work_done, int budget)
 
 int aq_ring_rx_fill(struct aq_ring_s *self)
 {
+   unsigned int pages_order = fls(AQ_CFG_RX_FRAME_MAX / PAGE_SIZE +
+   (AQ_CFG_RX_FRAME_MAX % PAGE_SIZE ? 1 : 0)) - 1;
struct aq_ring_buff_s *buff = NULL;
int err = 0;
int i = 0;
@@ -287,7 +289,7 @@ int aq_ring_rx_fill(struct aq_ring_s *self)
buff->len = AQ_CFG_RX_FRAME_MAX;
 
buff->page = alloc_pages(GFP_ATOMIC | __GFP_COLD |
-__GFP_COMP, 0);
+__GFP_COMP, pages_order);
if (!buff->page) {
err = -ENOMEM;
goto err_exit;
-- 
2.7.4



[PATCH net-next v3 10/12] net: ethernet: aquantia: Fixed incorrect buff->len calculation.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

rxd_wb->pkt_len is the total length of the packet.
If we received a large packet (with length > AQ_CFG_RX_FRAME_MAX) then we
will get multiple buffers. We need to fix the length of the last buffer.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 4 ++--
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 1f38805..a2b746a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -659,8 +659,8 @@ static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s 
*self,
}
 
if (HW_ATL_A0_RXD_WB_STAT2_EOP & rxd_wb->status) {
-   buff->len = (rxd_wb->pkt_len &
-   (AQ_CFG_RX_FRAME_MAX - 1U));
+   buff->len = rxd_wb->pkt_len %
+   AQ_CFG_RX_FRAME_MAX;
buff->len = buff->len ?
buff->len : AQ_CFG_RX_FRAME_MAX;
buff->next = 0U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index e7e694f..cab2931 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -673,8 +673,8 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s 
*self,
}
 
if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
-   buff->len = (rxd_wb->pkt_len &
-   (AQ_CFG_RX_FRAME_MAX - 1U));
+   buff->len = rxd_wb->pkt_len %
+   AQ_CFG_RX_FRAME_MAX;
buff->len = buff->len ?
buff->len : AQ_CFG_RX_FRAME_MAX;
buff->next = 0U;
-- 
2.7.4



[PATCH net-next v3 04/12] net: ethernet: aquantia: Using module_pci_driver.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Remove boilerplate code by using macro module_pci_driver.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index 45c769e..91c66f5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -242,22 +242,4 @@ static struct pci_driver aq_pci_ops = {
.resume = aq_pci_resume,
 };
 
-static int __init aq_module_init(void)
-{
-   int err = 0;
-
-   err = pci_register_driver(_pci_ops);
-   if (err < 0)
-   goto err_exit;
-
-err_exit:
-   return err;
-}
-
-static void __exit aq_module_exit(void)
-{
-   pci_unregister_driver(_pci_ops);
-}
-
-module_init(aq_module_init);
-module_exit(aq_module_exit);
+module_pci_driver(aq_pci_ops);
-- 
2.7.4



[PATCH net-next v3 01/12] net: ethernet: aquantia: Removed extra assignment for skb->dev.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This assignment is not needed.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index dea9e9b..4c40644 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -214,7 +214,6 @@ int aq_ring_rx_clean(struct aq_ring_s *self, int 
*work_done, int budget)
goto err_exit;
}
 
-   skb->dev = ndev;
skb_put(skb, buff->len);
} else {
skb = netdev_alloc_skb(ndev, ETH_HLEN);
-- 
2.7.4



[PATCH net-next v3 07/12] net: ethernet: aquantia: Using NETDEV_TX_OK instead 0.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Use NETDEV_TX_OK as the return value for successful transmission.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 646314c..019bcc7 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -568,7 +568,7 @@ __acquires(>lock)
unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;
unsigned int tc = 0U;
unsigned int trys = AQ_CFG_LOCK_TRYS;
-   int err = 0;
+   int err = NETDEV_TX_OK;
bool is_nic_in_bad_state;
struct aq_ring_buff_s buffers[AQ_CFG_SKB_FRAGS_MAX];
 
-- 
2.7.4



[PATCH net-next v3 00/12] net: ethernet: aquantia: improvements and fixes

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The following patchset contains improvements and fixes for aQuantia
AQtion ethernet driver from net-next tree.

Most fixes are based on the comments from Lino Sanfilippo.

Sanity testing was performed on real HW. No regression found.

v1->v2 :1)Removed buffers copying.
2)Fixed dma error handling.

v2->v3 :1)Fixes for aq_ndev_change_mtu:
-Use core MTU checking for min_mtu.
-Removed extra new_mtu assigment.
2)Reverse XMAS tree in aq_ring_rx_fill.

Please review.
Thanks.
Pavel Belous (12):
  net: ethernet: aquantia: Removed extra assignment for skb->dev.
  net: ethernet: aquantia: Removed busy_count field.
  net: ethernet: aquantia: Fixes for aq_ndev_change_mtu
  net: ethernet: aquantia: Using module_pci_driver.
  net: ethernet: aquantia: Superfluous initialization of "err".
  net: ethernet: aquantia: Fixed missing rtnl_unlock.
  net: ethernet: aquantia: Using NETDEV_TX_OK instead 0.
  net: ethernet: aquantia: Null pointer check for aq_nic_ndev_alloc.
  net: ethernet: aquantia: Call netdev_register after all initialized.
  net: ethernet: aquantia: Fixed incorrect buff->len calculation.
  net: ethernet: aquantia: Fixed memory allocation if
AQ_CFG_RX_FRAME_MAX > 1 page.
  net: ethernet: aquantia: Copying tx buffers is not needed.

 drivers/net/ethernet/aquantia/atlantic/aq_main.c   |  40 +---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 206 +++--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c   |  24 +--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h   |   3 -
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h  |   1 -
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |   4 +-
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |   4 +-
 7 files changed, 122 insertions(+), 160 deletions(-)

-- 
2.7.4



[PATCH net-next v3 02/12] net: ethernet: aquantia: Removed busy_count field.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

 busy_count field and is_busy flag is not needed at all.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c   | 11 ---
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h |  1 -
 2 files changed, 12 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index aa22a7c..a153750 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -122,14 +122,11 @@ static void aq_nic_service_timer_cb(unsigned long param)
struct aq_nic_s *self = (struct aq_nic_s *)param;
struct net_device *ndev = aq_nic_get_ndev(self);
int err = 0;
-   bool is_busy = false;
unsigned int i = 0U;
struct aq_hw_link_status_s link_status;
struct aq_ring_stats_rx_s stats_rx;
struct aq_ring_stats_tx_s stats_tx;
 
-   atomic_inc(>header.busy_count);
-   is_busy = true;
if (aq_utils_obj_test(>header.flags, AQ_NIC_FLAGS_IS_NOT_READY))
goto err_exit;
 
@@ -170,8 +167,6 @@ static void aq_nic_service_timer_cb(unsigned long param)
ndev->stats.tx_errors = stats_tx.errors;
 
 err_exit:
-   if (is_busy)
-   atomic_dec(>header.busy_count);
mod_timer(>service_timer,
  jiffies + AQ_CFG_SERVICE_TIMER_INTERVAL);
 }
@@ -574,16 +569,12 @@ __acquires(>lock)
unsigned int trys = AQ_CFG_LOCK_TRYS;
int err = 0;
bool is_nic_in_bad_state;
-   bool is_busy = false;
struct aq_ring_buff_s buffers[AQ_CFG_SKB_FRAGS_MAX];
 
frags = skb_shinfo(skb)->nr_frags + 1;
 
ring = self->aq_ring_tx[AQ_NIC_TCVEC2RING(self, tc, vec)];
 
-   atomic_inc(>header.busy_count);
-   is_busy = true;
-
if (frags > AQ_CFG_SKB_FRAGS_MAX) {
dev_kfree_skb_any(skb);
goto err_exit;
@@ -629,8 +620,6 @@ __acquires(>lock)
}
 
 err_exit:
-   if (is_busy)
-   atomic_dec(>header.busy_count);
return err;
 }
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
index 4446bd9..f6012b3 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
@@ -19,7 +19,6 @@
 struct aq_obj_s {
spinlock_t lock; /* spinlock for nic/rings processing */
atomic_t flags;
-   atomic_t busy_count;
 };
 
 static inline void aq_utils_obj_set(atomic_t *flags, u32 mask)
-- 
2.7.4



[PATCH net-next v3 03/12] net: ethernet: aquantia: Fixes for aq_ndev_change_mtu

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

1)Removed unnecessary comparsion "old_mtu == new_mtu".
This check is not needed. Function aq_ndev_change_mtu wont be called
if mtu has not changed.

2)Removed extra assignment ndev->mtu = new_mtu;
This assignment already done inside __dev_set_mtu().

3)Use core MTU checking for min_mtu.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 12 +---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c  |  1 +
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index c17c70a..45c769e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -100,20 +100,10 @@ static int aq_ndev_start_xmit(struct sk_buff *skb, struct 
net_device *ndev)
 static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
 {
struct aq_nic_s *aq_nic = netdev_priv(ndev);
-   int err = 0;
+   int err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);
 
-   if (new_mtu == ndev->mtu) {
-   err = 0;
-   goto err_exit;
-   }
-   if (new_mtu < 68) {
-   err = -EINVAL;
-   goto err_exit;
-   }
-   err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);
if (err < 0)
goto err_exit;
-   ndev->mtu = new_mtu;
 
if (netif_running(ndev)) {
aq_ndev_close(ndev);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index a153750..4b8d074 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -214,6 +214,7 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct 
net_device_ops *ndev_ops,
SET_NETDEV_DEV(ndev, dev);
 
ndev->if_port = port;
+   ndev->min_mtu = ETH_MIN_MTU;
self->ndev = ndev;
 
self->aq_pci_func = aq_pci_func;
-- 
2.7.4



[PATCH net-next v3 09/12] net: ethernet: aquantia: Call netdev_register after all initialized.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

netdev_register should be called when everything is initialized.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index a8a27c5..fdd7d72 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -261,16 +261,18 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
ether_addr_copy(self->ndev->dev_addr, mac_addr_permanent);
}
 #endif
-   err = register_netdev(self->ndev);
-   if (err < 0)
-   goto err_exit;
 
-   self->is_ndev_registered = true;
netif_carrier_off(self->ndev);
 
for (i = AQ_CFG_VECS_MAX; i--;)
aq_nic_ndev_queue_stop(self, i);
 
+   err = register_netdev(self->ndev);
+   if (err < 0)
+   goto err_exit;
+
+   self->is_ndev_registered = true;
+
 err_exit:
return err;
 }
-- 
2.7.4



[PATCH net-next v3 06/12] net: ethernet: aquantia: Fixed missing rtnl_unlock.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

rtnl_unlock should be called if error occurred.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 4b8d074..646314c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -932,7 +932,7 @@ int aq_nic_change_pm_state(struct aq_nic_s *self, 
pm_message_t *pm_msg)
 
if (!netif_running(self->ndev)) {
err = 0;
-   goto err_exit;
+   goto out;
}
rtnl_lock();
if (pm_msg->event & PM_EVENT_SLEEP || pm_msg->event & PM_EVENT_FREEZE) {
@@ -957,8 +957,9 @@ int aq_nic_change_pm_state(struct aq_nic_s *self, 
pm_message_t *pm_msg)
netif_device_attach(self->ndev);
netif_tx_start_all_queues(self->ndev);
}
-   rtnl_unlock();
 
 err_exit:
+   rtnl_unlock();
+out:
return err;
 }
-- 
2.7.4



[PATCH net-next v3 08/12] net: ethernet: aquantia: Null pointer check for aq_nic_ndev_alloc.

2017-02-20 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We should check for a null pointer for aq_nic_ndev_alloc
instead netdev_priv.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
Reviewed-by: Lino Sanfilippo <linosanfili...@gmx.de>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 019bcc7..a8a27c5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -202,12 +202,13 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct 
net_device_ops *ndev_ops,
int err = 0;
 
ndev = aq_nic_ndev_alloc();
-   self = netdev_priv(ndev);
-   if (!self) {
-   err = -EINVAL;
+   if (!ndev) {
+   err = -ENOMEM;
goto err_exit;
}
 
+   self = netdev_priv(ndev);
+
ndev->netdev_ops = ndev_ops;
ndev->ethtool_ops = et_ops;
 
-- 
2.7.4



Re: [PATCH net-next v2 11/12] net: ethernet: aquantia: Fixed memory allocation if AQ_CFG_RX_FRAME_MAX > 1 page.

2017-02-18 Thread Pavel Belous



On 02/18/2017 02:50 PM, Lino Sanfilippo wrote:

Hi,

On 17.02.2017 22:07, Pavel Belous wrote:

From: Pavel Belous <pavel.bel...@aquantia.com>

We should allocate the number of pages based on the config parameter
AQ_CFG_RX_FRAME_MAX.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>



do {
if (spin_trylock(>header.lock)) {
-   frags = aq_nic_map_skb(self, skb, [0]);
+   frags = aq_nic_map_skb(self, skb, buffers);

-   aq_ring_tx_append_buffs(ring, [0], frags);
+   aq_ring_tx_append_buffs(ring, buffers, frags);



This change has nothing to do with what the commit message claims that the
patch is about. Please dont mix fixes and totally unrelated cleanups in one
patch.

Regards,
Lino



Sorry, its just small fix for readability.
I will remove it or put in separate patch in v3.

Regards,
Pavel


Re: [PATCH net-next v2 00/12] net: ethernet: aquantia: improvements and fixes

2017-02-18 Thread Pavel Belous


On 02/18/2017 02:56 PM, Lino Sanfilippo wrote:

Hi,

On 17.02.2017 22:07, Pavel Belous wrote:

From: Pavel Belous <pavel.bel...@aquantia.com>

The following patchset contains improvements and fixes for aQuantia
AQtion ethernet driver from net-next tree.

Most fixes are based on the comments from Lino Sanfilippo.

Sanity testing was performed on real HW. No regression found.

v1->v2 :Removed buffers copying.
Fixed dma error handling.


Please review.


You could have added all "reviewed-by" tags that you have received so
far for patches in the former version of this series. I think otherwise this
information will get lost.

Regards,
Lino



I was thinking to add this tag, but i was unsure.

Thank you, I will add "Reviewed-by" tags for reviewed patches from v1 
(not changed) in patches v3.


Regards,
Pavel


Re: [PATCH net-next v2 11/12] net: ethernet: aquantia: Fixed memory allocation if AQ_CFG_RX_FRAME_MAX > 1 page.

2017-02-18 Thread Pavel Belous

On 02/18/2017 01:43 AM, Andrew Lunn wrote:

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 4c40644..0877625 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -278,6 +278,8 @@ int aq_ring_rx_fill(struct aq_ring_s *self)
struct aq_ring_buff_s *buff = NULL;
int err = 0;
int i = 0;
+   unsigned int pages_order = fls(AQ_CFG_RX_FRAME_MAX / PAGE_SIZE +
+   (AQ_CFG_RX_FRAME_MAX % PAGE_SIZE ? 1 : 0)) - 1;


Reverse Christmas tree?

Andrew



Thank you.
I will fix it in v3.

Regards,
Pavel


[PATCH net-next v2 04/12] net: ethernet: aquantia: Using module_pci_driver.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Remove boilerplate code by using macro module_pci_driver.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index e5539c8..f7513cb 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -250,22 +250,4 @@ static struct pci_driver aq_pci_ops = {
.resume = aq_pci_resume,
 };
 
-static int __init aq_module_init(void)
-{
-   int err = 0;
-
-   err = pci_register_driver(_pci_ops);
-   if (err < 0)
-   goto err_exit;
-
-err_exit:
-   return err;
-}
-
-static void __exit aq_module_exit(void)
-{
-   pci_unregister_driver(_pci_ops);
-}
-
-module_init(aq_module_init);
-module_exit(aq_module_exit);
+module_pci_driver(aq_pci_ops);
-- 
2.7.4



[PATCH net-next v2 12/12] net: ethernet: aquantia: Copying tx buffers is not needed.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This fix removes copying of tx biffers.
Now we use ring->buff_fing directly.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c  | 170 +--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c |  19 ---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h |   3 -
 3 files changed, 97 insertions(+), 95 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 25dc9b4..46d43c4 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -469,95 +469,116 @@ int aq_nic_start(struct aq_nic_s *self)
return err;
 }
 
-static unsigned int aq_nic_map_skb_frag(struct aq_nic_s *self,
-   struct sk_buff *skb,
-   struct aq_ring_buff_s *dx)
+static unsigned int aq_nic_map_skb(struct aq_nic_s *self,
+  struct sk_buff *skb,
+  struct aq_ring_s *ring)
 {
unsigned int ret = 0U;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int frag_count = 0U;
+   unsigned int dx = ring->sw_tail;
+   struct aq_ring_buff_s *dx_buff = >buff_ring[dx];
 
-   dx->flags = 0U;
-   dx->len = skb_headlen(skb);
-   dx->pa = dma_map_single(aq_nic_get_dev(self), skb->data, dx->len,
-   DMA_TO_DEVICE);
-   dx->len_pkt = skb->len;
-   dx->is_sop = 1U;
-   dx->is_mapped = 1U;
+   if (unlikely(skb_is_gso(skb))) {
+   dx_buff->flags = 0U;
+   dx_buff->len_pkt = skb->len;
+   dx_buff->len_l2 = ETH_HLEN;
+   dx_buff->len_l3 = ip_hdrlen(skb);
+   dx_buff->len_l4 = tcp_hdrlen(skb);
+   dx_buff->mss = skb_shinfo(skb)->gso_size;
+   dx_buff->is_txc = 1U;
+
+   dx = aq_ring_next_dx(ring, dx);
+   dx_buff = >buff_ring[dx];
+   ++ret;
+   }
+
+   dx_buff->flags = 0U;
+   dx_buff->len = skb_headlen(skb);
+   dx_buff->pa = dma_map_single(aq_nic_get_dev(self),
+skb->data,
+dx_buff->len,
+DMA_TO_DEVICE);
 
+   if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa)))
+   goto exit;
+
+   dx_buff->len_pkt = skb->len;
+   dx_buff->is_sop = 1U;
+   dx_buff->is_mapped = 1U;
++ret;
 
if (skb->ip_summed == CHECKSUM_PARTIAL) {
-   dx->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ? 1U : 0U;
-   dx->is_tcp_cso =
+   dx_buff->is_ip_cso = (htons(ETH_P_IP) == skb->protocol) ?
+   1U : 0U;
+   dx_buff->is_tcp_cso =
(ip_hdr(skb)->protocol == IPPROTO_TCP) ? 1U : 0U;
-   dx->is_udp_cso =
+   dx_buff->is_udp_cso =
(ip_hdr(skb)->protocol == IPPROTO_UDP) ? 1U : 0U;
}
 
for (; nr_frags--; ++frag_count) {
-   unsigned int frag_len;
+   unsigned int frag_len = 0U;
dma_addr_t frag_pa;
skb_frag_t *frag = _shinfo(skb)->frags[frag_count];
 
frag_len = skb_frag_size(frag);
-
frag_pa = skb_frag_dma_map(aq_nic_get_dev(self), frag, 0,
   frag_len, DMA_TO_DEVICE);
 
+   if (unlikely(dma_mapping_error(aq_nic_get_dev(self), frag_pa)))
+   goto mapping_error;
+
while (frag_len > AQ_CFG_TX_FRAME_MAX) {
-   ++dx;
-   ++ret;
-   dx->flags = 0U;
-   dx->len = AQ_CFG_TX_FRAME_MAX;
-   dx->pa = frag_pa;
-   dx->is_mapped = 1U;
+   dx = aq_ring_next_dx(ring, dx);
+   dx_buff = >buff_ring[dx];
+
+   dx_buff->flags = 0U;
+   dx_buff->len = AQ_CFG_TX_FRAME_MAX;
+   dx_buff->pa = frag_pa;
+   dx_buff->is_mapped = 1U;
 
frag_len -= AQ_CFG_TX_FRAME_MAX;
frag_pa += AQ_CFG_TX_FRAME_MAX;
+   ++ret;
}
 
-   ++dx;
-   ++ret;
+   dx = aq_ring_next_dx(ring, dx);
+   dx_buff = >buff_ring[dx];
 
-   dx->flags = 0U;
-   dx->len = frag_len;
-   dx->pa = frag_pa;
-   dx->is_mapped = 1U;
+   dx_buff-

[PATCH net-next v2 10/12] net: ethernet: aquantia: Fixed incorrect buff->len calculation.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

rxd_wb->pkt_len is the total length of the packet.
If we received a large packet (with length > AQ_CFG_RX_FRAME_MAX) then we
will get multiple buffers. We need to fix the length of the last buffer.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 4 ++--
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 1f38805..a2b746a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -659,8 +659,8 @@ static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s 
*self,
}
 
if (HW_ATL_A0_RXD_WB_STAT2_EOP & rxd_wb->status) {
-   buff->len = (rxd_wb->pkt_len &
-   (AQ_CFG_RX_FRAME_MAX - 1U));
+   buff->len = rxd_wb->pkt_len %
+   AQ_CFG_RX_FRAME_MAX;
buff->len = buff->len ?
buff->len : AQ_CFG_RX_FRAME_MAX;
buff->next = 0U;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index e7e694f..cab2931 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -673,8 +673,8 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s 
*self,
}
 
if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
-   buff->len = (rxd_wb->pkt_len &
-   (AQ_CFG_RX_FRAME_MAX - 1U));
+   buff->len = rxd_wb->pkt_len %
+   AQ_CFG_RX_FRAME_MAX;
buff->len = buff->len ?
buff->len : AQ_CFG_RX_FRAME_MAX;
buff->next = 0U;
-- 
2.7.4



[PATCH net-next v2 11/12] net: ethernet: aquantia: Fixed memory allocation if AQ_CFG_RX_FRAME_MAX > 1 page.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We should allocate the number of pages based on the config parameter
AQ_CFG_RX_FRAME_MAX.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c  | 4 ++--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 4 +++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index daed4c1..25dc9b4 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -596,9 +596,9 @@ __acquires(>lock)
 
do {
if (spin_trylock(>header.lock)) {
-   frags = aq_nic_map_skb(self, skb, [0]);
+   frags = aq_nic_map_skb(self, skb, buffers);
 
-   aq_ring_tx_append_buffs(ring, [0], frags);
+   aq_ring_tx_append_buffs(ring, buffers, frags);
 
err = self->aq_hw_ops.hw_ring_tx_xmit(self->aq_hw,
  ring, frags);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 4c40644..0877625 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -278,6 +278,8 @@ int aq_ring_rx_fill(struct aq_ring_s *self)
struct aq_ring_buff_s *buff = NULL;
int err = 0;
int i = 0;
+   unsigned int pages_order = fls(AQ_CFG_RX_FRAME_MAX / PAGE_SIZE +
+   (AQ_CFG_RX_FRAME_MAX % PAGE_SIZE ? 1 : 0)) - 1;
 
for (i = aq_ring_avail_dx(self); i--;
self->sw_tail = aq_ring_next_dx(self, self->sw_tail)) {
@@ -287,7 +289,7 @@ int aq_ring_rx_fill(struct aq_ring_s *self)
buff->len = AQ_CFG_RX_FRAME_MAX;
 
buff->page = alloc_pages(GFP_ATOMIC | __GFP_COLD |
-__GFP_COMP, 0);
+__GFP_COMP, pages_order);
if (!buff->page) {
err = -ENOMEM;
goto err_exit;
-- 
2.7.4



[PATCH net-next v2 09/12] net: ethernet: aquantia: Call netdev_register after all initialized.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

netdev_register should be called when everything is initialized.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index e50fba2..daed4c1 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -260,16 +260,18 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
ether_addr_copy(self->ndev->dev_addr, mac_addr_permanent);
}
 #endif
-   err = register_netdev(self->ndev);
-   if (err < 0)
-   goto err_exit;
 
-   self->is_ndev_registered = true;
netif_carrier_off(self->ndev);
 
for (i = AQ_CFG_VECS_MAX; i--;)
aq_nic_ndev_queue_stop(self, i);
 
+   err = register_netdev(self->ndev);
+   if (err < 0)
+   goto err_exit;
+
+   self->is_ndev_registered = true;
+
 err_exit:
return err;
 }
-- 
2.7.4



[PATCH net-next v2 07/12] net: ethernet: aquantia: Using NETDEV_TX_OK instead 0.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Use NETDEV_TX_OK as the return value for successful transmission.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 1bf5975..4cf633c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -567,7 +567,7 @@ __acquires(>lock)
unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;
unsigned int tc = 0U;
unsigned int trys = AQ_CFG_LOCK_TRYS;
-   int err = 0;
+   int err = NETDEV_TX_OK;
bool is_nic_in_bad_state;
struct aq_ring_buff_s buffers[AQ_CFG_SKB_FRAGS_MAX];
 
-- 
2.7.4



[PATCH net-next v2 08/12] net: ethernet: aquantia: Null pointer check for aq_nic_ndev_alloc.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

We should check for a null pointer for aq_nic_ndev_alloc
instead netdev_priv.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 4cf633c..e50fba2 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -202,12 +202,13 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct 
net_device_ops *ndev_ops,
int err = 0;
 
ndev = aq_nic_ndev_alloc();
-   self = netdev_priv(ndev);
-   if (!self) {
-   err = -EINVAL;
+   if (!ndev) {
+   err = -ENOMEM;
goto err_exit;
}
 
+   self = netdev_priv(ndev);
+
ndev->netdev_ops = ndev_ops;
ndev->ethtool_ops = et_ops;
 
-- 
2.7.4



[PATCH net-next v2 00/12] net: ethernet: aquantia: improvements and fixes

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

The following patchset contains improvements and fixes for aQuantia
AQtion ethernet driver from net-next tree.

Most fixes are based on the comments from Lino Sanfilippo.

Sanity testing was performed on real HW. No regression found.

v1->v2 :Removed buffers copying.
Fixed dma error handling.


Please review.
Thanks.
Pavel Belous (12):
  net: ethernet: aquantia: Removed extra assignment for skb->dev.
  net: ethernet: aquantia: Removed busy_count field.
  net: ethernet: aquantia: Removed unnecessary comparsion "old_mtu ==
new_mtu".
  net: ethernet: aquantia: Using module_pci_driver.
  net: ethernet: aquantia: Superfluous initialization of "err".
  net: ethernet: aquantia: Fixed missing rtnl_unlock.
  net: ethernet: aquantia: Using NETDEV_TX_OK instead 0.
  net: ethernet: aquantia: Null pointer check for aq_nic_ndev_alloc.
  net: ethernet: aquantia: Call netdev_register after all initialized.
  net: ethernet: aquantia: Fixed incorrect buff->len calculation.
  net: ethernet: aquantia: Fixed memory allocation if
AQ_CFG_RX_FRAME_MAX > 1 page.
  net: ethernet: aquantia: Copying tx buffers is not needed.

 drivers/net/ethernet/aquantia/atlantic/aq_main.c   |  34 +---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 205 +++--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c   |  24 +--
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h   |   3 -
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h  |   1 -
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |   4 +-
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |   4 +-
 7 files changed, 122 insertions(+), 153 deletions(-)

-- 
2.7.4



[PATCH net-next v2 05/12] net: ethernet: aquantia: Superfluous initialization of "err".

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

Fixed superfluous initialization of err.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index f7513cb..68c19d3 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -87,14 +87,8 @@ static int aq_ndev_close(struct net_device *ndev)
 static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
struct aq_nic_s *aq_nic = netdev_priv(ndev);
-   int err = 0;
-
-   err = aq_nic_xmit(aq_nic, skb);
-   if (err < 0)
-   goto err_exit;
 
-err_exit:
-   return err;
+   return aq_nic_xmit(aq_nic, skb);
 }
 
 static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
-- 
2.7.4



[PATCH net-next v2 02/12] net: ethernet: aquantia: Removed busy_count field.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

 busy_count field and is_busy flag is not needed at all.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c   | 11 ---
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h |  1 -
 2 files changed, 12 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index aa22a7c..a153750 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -122,14 +122,11 @@ static void aq_nic_service_timer_cb(unsigned long param)
struct aq_nic_s *self = (struct aq_nic_s *)param;
struct net_device *ndev = aq_nic_get_ndev(self);
int err = 0;
-   bool is_busy = false;
unsigned int i = 0U;
struct aq_hw_link_status_s link_status;
struct aq_ring_stats_rx_s stats_rx;
struct aq_ring_stats_tx_s stats_tx;
 
-   atomic_inc(>header.busy_count);
-   is_busy = true;
if (aq_utils_obj_test(>header.flags, AQ_NIC_FLAGS_IS_NOT_READY))
goto err_exit;
 
@@ -170,8 +167,6 @@ static void aq_nic_service_timer_cb(unsigned long param)
ndev->stats.tx_errors = stats_tx.errors;
 
 err_exit:
-   if (is_busy)
-   atomic_dec(>header.busy_count);
mod_timer(>service_timer,
  jiffies + AQ_CFG_SERVICE_TIMER_INTERVAL);
 }
@@ -574,16 +569,12 @@ __acquires(>lock)
unsigned int trys = AQ_CFG_LOCK_TRYS;
int err = 0;
bool is_nic_in_bad_state;
-   bool is_busy = false;
struct aq_ring_buff_s buffers[AQ_CFG_SKB_FRAGS_MAX];
 
frags = skb_shinfo(skb)->nr_frags + 1;
 
ring = self->aq_ring_tx[AQ_NIC_TCVEC2RING(self, tc, vec)];
 
-   atomic_inc(>header.busy_count);
-   is_busy = true;
-
if (frags > AQ_CFG_SKB_FRAGS_MAX) {
dev_kfree_skb_any(skb);
goto err_exit;
@@ -629,8 +620,6 @@ __acquires(>lock)
}
 
 err_exit:
-   if (is_busy)
-   atomic_dec(>header.busy_count);
return err;
 }
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
index 4446bd9..f6012b3 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
@@ -19,7 +19,6 @@
 struct aq_obj_s {
spinlock_t lock; /* spinlock for nic/rings processing */
atomic_t flags;
-   atomic_t busy_count;
 };
 
 static inline void aq_utils_obj_set(atomic_t *flags, u32 mask)
-- 
2.7.4



[PATCH net-next v2 03/12] net: ethernet: aquantia: Removed unnecessary comparsion "old_mtu == new_mtu".

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This check is not needed. Function aq_ndev_change_mtu wont be called
if mtu has not changed.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_main.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index c17c70a..e5539c8 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -102,17 +102,15 @@ static int aq_ndev_change_mtu(struct net_device *ndev, 
int new_mtu)
struct aq_nic_s *aq_nic = netdev_priv(ndev);
int err = 0;
 
-   if (new_mtu == ndev->mtu) {
-   err = 0;
-   goto err_exit;
-   }
if (new_mtu < 68) {
err = -EINVAL;
goto err_exit;
}
+
err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);
if (err < 0)
goto err_exit;
+
ndev->mtu = new_mtu;
 
if (netif_running(ndev)) {
-- 
2.7.4



[PATCH net-next v2 01/12] net: ethernet: aquantia: Removed extra assignment for skb->dev.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

This assignment is not needed.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index dea9e9b..4c40644 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -214,7 +214,6 @@ int aq_ring_rx_clean(struct aq_ring_s *self, int 
*work_done, int budget)
goto err_exit;
}
 
-   skb->dev = ndev;
skb_put(skb, buff->len);
} else {
skb = netdev_alloc_skb(ndev, ETH_HLEN);
-- 
2.7.4



[PATCH net-next v2 06/12] net: ethernet: aquantia: Fixed missing rtnl_unlock.

2017-02-17 Thread Pavel Belous
From: Pavel Belous <pavel.bel...@aquantia.com>

rtnl_unlock should be called if error occurred.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index a153750..1bf5975 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -931,7 +931,7 @@ int aq_nic_change_pm_state(struct aq_nic_s *self, 
pm_message_t *pm_msg)
 
if (!netif_running(self->ndev)) {
err = 0;
-   goto err_exit;
+   goto out;
}
rtnl_lock();
if (pm_msg->event & PM_EVENT_SLEEP || pm_msg->event & PM_EVENT_FREEZE) {
@@ -956,8 +956,9 @@ int aq_nic_change_pm_state(struct aq_nic_s *self, 
pm_message_t *pm_msg)
netif_device_attach(self->ndev);
netif_tx_start_all_queues(self->ndev);
}
-   rtnl_unlock();
 
 err_exit:
+   rtnl_unlock();
+out:
return err;
 }
-- 
2.7.4



Re: [PATCH net-next 11/13] net: ethernet: aquantia: Refactoring buffers copying.

2017-02-15 Thread Pavel Belous

Thank you.

I will think about how to avoid copying..

Regards,
Pavel


On 16.02.2017 00:31, Lino Sanfilippo wrote:

On 15.02.2017 21:01, Pavel Belous wrote:

From: Pavel Belous <pavel.bel...@aquantia.com>

This fix simplified copying data to the ring buffer.
Also, there was an error in the code when the second memcpy
is called with zero length. It didn't break the driver, but it's bad.

Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 25

 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index 4c40644..8ebed0d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -108,18 +108,19 @@ void aq_ring_tx_append_buffs(struct aq_ring_s
*self,
  struct aq_ring_buff_s *buffer,
  unsigned int buffers)
 {
-if (likely(self->sw_tail + buffers < self->size)) {
-memcpy(>buff_ring[self->sw_tail], buffer,
-   sizeof(buffer[0]) * buffers);
-} else {
-unsigned int first_part = self->size - self->sw_tail;
-unsigned int second_part = buffers - first_part;
-
-memcpy(>buff_ring[self->sw_tail], buffer,
-   sizeof(buffer[0]) * first_part);
-
-memcpy(>buff_ring[0], [first_part],
-   sizeof(buffer[0]) * second_part);
+int buff_len = min(self->size - self->sw_tail, buffers);
+
+memcpy(>buff_ring[self->sw_tail],
+   buffer,
+   sizeof(struct aq_ring_buff_s) * buff_len);
+
+/* We are in the end of the ring.
+ *  Copy remains data to beginning of the ring
+ */
+if (buffers > buff_len) {
+memcpy(self->buff_ring,
+   [buff_len],
+   sizeof(struct aq_ring_buff_s) * (buffers - buff_len));
 }
 }


Well, you should really try to avoid copying the tx buffers _at all_.
E.g. by passing self->buff_ring to aq_ring_tx_append_buffs() instead of
the temporary array.

Regards,
Lino
buffer array.



Re: [PATCH net-next 10/13] net: ethernet: aquantia: Checking for success dma_map_single.

2017-02-15 Thread Pavel Belous

Ok, I will fix it in the patch v2.

Thank you.

Regards,
Pavel

On 16.02.2017 00:40, Lino Sanfilippo wrote:

On 15.02.2017 22:23, Lino Sanfilippo wrote:




In case of this error you have to undo all mappings that you have
done so far (i.e the complete frag list and the head buffer).



And, since mapping failed, set ret = 0 and handle this case in the
caller, too.

Regards,
Lino



  1   2   >