Netdev List
 help / color / mirror / Atom feed
* Re: [PATCHv2 RFC net-next 4/7] tcp: replace dst_confirm with sk_dst_confirm
From: Eric Dumazet @ 2017-01-29 19:27 UTC (permalink / raw)
  To: Julian Anastasov; +Cc: netdev, linux-sctp, YueHaibing
In-Reply-To: <1485613578-19973-5-git-send-email-ja@ssi.bg>

On Sat, 2017-01-28 at 16:26 +0200, Julian Anastasov wrote:
> When same struct dst_entry can be used for many different
> neighbours we can not use it for pending confirmations.
> Use the new sk_dst_confirm() helper to propagate the
> indication from received packets to sock_confirm_neigh().
> 
> Reported-by: YueHaibing <yuehaibing@huawei.com>
> Fixes: 5110effee8fd ("net: Do delayed neigh confirmation.")
> Fixes: f2bb4bedf35d ("ipv4: Cache output routes in fib_info nexthops.")
> Signed-off-by: Julian Anastasov <ja@ssi.bg>
> ---

For the whole series,

Acked-by: Eric Dumazet <edumazet@google.com>

Thanks !

^ permalink raw reply

* Re: [PATCH net-next v2 0/2] gtp: simple gtp improvements
From: David Miller @ 2017-01-29 18:56 UTC (permalink / raw)
  To: aschultz; +Cc: pablo, netdev, Lionel.Gauthier, openbsc, laforge, elfring
In-Reply-To: <20170126152149.3284-1-aschultz@tpip.net>

From: Andreas Schultz <aschultz@tpip.net>
Date: Thu, 26 Jan 2017 16:21:47 +0100

> This is the part of the previous "simple gtp improvements" series
> that Pablo indicated should go into net-next.
> 
> The rcu_lock removal is small correctness changes. Passing invalid
> to user space allows for more standards compliant handling of invalid
> tunnels.

Series applied, thanks.

^ permalink raw reply

* Re: [PATCHv3 net-next 3/4] sctp: add support for generating stream reconf add incoming/outgoing streams request chunk
From: David Miller @ 2017-01-29 18:41 UTC (permalink / raw)
  To: marcelo.leitner
  Cc: David.Laight, lucien.xin, netdev, linux-sctp, nhorman, vyasevich
In-Reply-To: <20170129143117.GK3781@localhost.localdomain>

From: marcelo.leitner@gmail.com
Date: Sun, 29 Jan 2017 12:31:17 -0200

> On Mon, Jan 23, 2017 at 10:58:10AM -0500, David Miller wrote:
>> If this is "so critical" for end to end communication, why the heck
>> do you not see __packed sprinkled all over our definitions for IPV4,
>> IPV6, TCP, UDP, etc. headers?
>> 
>> Do you know why?  Because it's completely unnecessary...
> 
> Btw, virtually all sctp headers are currently tagged with __packed,
> since forever.
 ...
> I'm reviewing them all and will probably post a patch to remove them.

Thanks.

^ permalink raw reply

* Re: [PATCH stable v1 00/13] net: ethernet: aquantia: Add AQtion 2.5/5 GB NIC driver
From: David Miller @ 2017-01-29 18:34 UTC (permalink / raw)
  To: Alexander.Loktionov
  Cc: netdev, vomlehn, Simon.Edelhaus, Dmitrii.Tarakanov, Pavel.Belous
In-Reply-To: <cover.1485665881.git.vomlehn@texas.net>


We do not add new drivers to the -stable trees.

It is for bug fixes only.

^ permalink raw reply

* Re: [PATCH net-next v3 0/4] net: ipv6: Improve user experience with multipath routes
From: David Ahern @ 2017-01-29 18:02 UTC (permalink / raw)
  To: Roopa Prabhu; +Cc: netdev, nicolas.dichtel
In-Reply-To: <588D3EB9.1070107@cumulusnetworks.com>

On 1/28/17 6:00 PM, Roopa Prabhu wrote:
>> 4. Route Appends
>>    - IPv6 allows nexthops to be appended to an existing route. In this
>>      case one notification is sent per nexthop added
> 
> thanks for listing all of these...I think you mentioned this case to me..
> but I don't remember now why this notification is
> sent per nexthop added. This is an update to an existing multipath route.
> so seems like the notification should be a RTM_NEWROUTE with the full RTA_MULTIPATH route
> (similar to route add)

It could be; it's a question of what should userspace get -- the full route or the change? Append to me suggests the latter - userspace is told what changed. It is simpler kernel code wise to send the full new route. The append changes were done after our conversation. ;-)

> 
> Same holds for replace, I know the code might be tricky here...but the route replace
> is also an update to an existing multipath route and hence should be a RTM_NEWROUTE
> with the full multipath route (RTA_MULTIPATH) that changed (from userspace semantics POV)

It is. The only change on a replace is the encoding of all routes in RTA_MULTIPATH which is the point of this patch set. On successful replace, only 1 notification is sent with the full route.

> 
> I don't have a better solution, but with the above still being different, wondering
> if its worth the risk changing the api for just a few notifications.

Data centers are moving to L3, and multipath is a big part of that. Anyone who looks at ip -6 route enough knows it gets painful mentally pulling the individual routes into a single one. In addition, using RTA_MULTIPATH is more efficient at scale.

Furthermore, I have a follow on patch set that returns the route matched on an ip route get lookup. Returning the full multipath route is an important part to understanding the full context of the route to an address.

^ permalink raw reply

* RE: [PATCH net-next v2 2/2] qede: Add driver support for PTP.
From: Mintz, Yuval @ 2017-01-29 17:30 UTC (permalink / raw)
  To: Richard Cochran
  Cc: davem@davemloft.net, netdev@vger.kernel.org, Kalluru, Sudarsana
In-Reply-To: <20170129153536.GD2223@localhost.localdomain>

> > +static int qede_ptp_adjfreq(struct ptp_clock_info *info, s32 ppb) {
> > +	struct qede_ptp *ptp = container_of(info, struct qede_ptp,
> clock_info);
> > +	struct qede_dev *edev = ptp->edev;
> > +	int rc;
> > +
> > +	__qede_lock(edev);
> > +	if (edev->state == QEDE_STATE_OPEN) {
> > +		spin_lock_bh(&ptp->lock);
> > +		rc = ptp->ops->adjfreq(edev->cdev, ppb);
> 
> Why add this extra layer of indirection?
> 
> You could put these this test into qed_ptp_hw_adjfreq() and register that
> function directly.
> 

Which level of indirection? The usage of ptp->ops->() functions?

That's part of the driver structuring - qed is responsible for accessing HW
so it implements api functions for accessing PTP-related configuration,
while qede is responsible for the network interface and thus is the one to
register the clock and implements its API.

The operations ptp->ops->() originate from qed, so we can't refactor qede
state-logic there and use it directly.

^ permalink raw reply

* RE: [PATCH net-next v2 1/2] qed: Add infrastructure for PTP support.
From: Mintz, Yuval @ 2017-01-29 17:26 UTC (permalink / raw)
  To: Richard Cochran
  Cc: davem@davemloft.net, netdev@vger.kernel.org, Kalluru, Sudarsana
In-Reply-To: <20170129153134.GC2223@localhost.localdomain>

> > +/* Read Rx timestamp */
> > +static int qed_ptp_hw_read_rx_ts(struct qed_dev *cdev, u64
> > +*timestamp) {
> > +	struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
> > +	struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt;
> > +	u32 val;
> > +
> > +	*timestamp = 0;
> > +	val = qed_rd(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_SEQID);
> > +	if (!(val & QED_TIMESTAMP_MASK)) {
> > +		DP_INFO(p_hwfn, "Invalid Rx timestamp, buf_seqid = %d\n",
> val);
> > +		return -EINVAL;
> > +	}
> > +
> > +	val = qed_rd(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_TS_LSB);
> > +	*timestamp = qed_rd(p_hwfn, p_ptt,
> NIG_REG_LLH_PTP_HOST_BUF_TS_MSB);
> 
> You can already "Reset timestamp register to allow new timestamp" at this
> point, before combining the MSB and LSB.

We could - but what difference would it make?

> > +	*timestamp <<= 32;
> > +	*timestamp |= val;
> > +
> > +	/* Reset timestamp register to allow new timestamp */
> > +	qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_SEQID,
> > +	       QED_TIMESTAMP_MASK);
> > +
> > +	return 0;
> > +} 

^ permalink raw reply

* RE: [PATCH net-next v2 0/2] qed*: Add support for PTP
From: Mintz, Yuval @ 2017-01-29 17:23 UTC (permalink / raw)
  To: Richard Cochran
  Cc: davem@davemloft.net, netdev@vger.kernel.org, Kalluru, Sudarsana
In-Reply-To: <20170129150942.GA2223@localhost.localdomain>

> Can we please, PLEASE put the PHC maintainer onto CC when posting new
> PHC drivers?

Sorry about that. 

^ permalink raw reply

* Re: [PATCH 2/6] wl1251: Use request_firmware_prefer_user() for loading NVS calibration data
From: Luis R. Rodriguez @ 2017-01-29 17:10 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Kalle Valo, Arend Van Spriel, Ming Lei, Luis R. Rodriguez,
	Greg Kroah-Hartman, David Gnedt, Michal Kazior, Daniel Wagner,
	Tony Lindgren, Sebastian Reichel, Pavel Machek, Ivaylo Dimitrov,
	Aaro Koskinen, Grazvydas Ignotas,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170127131146.GI24223@pali>

On Fri, Jan 27, 2017 at 02:11:46PM +0100, Pali Rohár wrote:
> So there are only two options:
> 
> 1) Disallow it and so these users will have non-working wifi.
> 
> 2) Allow those data to be used as fallback mechanism.

There is one "custom fallback" user in kernel which we recently
determined was a total mistake. A sysfs interface should have
been defined to enable custom LED settings. Can't a series of
sysfs interfaces be used to enable override ? So is that not a
third option worth consideration?

  Luis

^ permalink raw reply

* [PATCH net-next V3 0/8] mlx4 misc improvements
From: Tariq Toukan @ 2017-01-29 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Tariq Toukan

Hi Dave,

This patchset contains several improvements and cleanups
from the team to the mlx4 Eth and core drivers.

Series generated against net-next commit:
4e8f2fc1a55d Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Thanks,
Tariq.

v3:
* Patch 6/9: forgot to actually update the commit message in v2, now it is.

v2:
* Patch 1/9: used EOPNOTSUPP and not ENOTSUPP.
* Patch 3/9: dropped, to be submitted separately in the future.
* Patch 6/9: updated commit message.

Alaa Hleihel (1):
  net/mlx4_core: Get num_tc using netdev_get_num_tc

Ariel Levkovich (1):
  net/mlx4_en: Adding support of turning off link autonegotiation via
    ethtool

Matan Barak (1):
  net/mlx4_core: Add resource alloc/dealloc debugging

Shaker Daibes (3):
  net/mlx4_en: Pass user MTU value to Firmware at set port command
  net/mlx4_en: Check the enabling mtu flag in SET_PORT wrapper flow
  net/mlx4_en: Check the enabling pptx/pprx flags in SET_PORT wrapper
    flow

Tariq Toukan (1):
  net/mlx4: Replace ENOSYS with better fitting error codes

Yishai Hadas (1):
  net/mlx4_core: Device revision support

 drivers/net/ethernet/mellanox/mlx4/en_ethtool.c    |  28 +++-
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c     |   8 +
 drivers/net/ethernet/mellanox/mlx4/en_port.h       |   1 -
 drivers/net/ethernet/mellanox/mlx4/en_tx.c         |   2 +-
 drivers/net/ethernet/mellanox/mlx4/fw.c            |   6 +-
 drivers/net/ethernet/mellanox/mlx4/main.c          |   6 +-
 drivers/net/ethernet/mellanox/mlx4/mlx4.h          |  11 +-
 drivers/net/ethernet/mellanox/mlx4/port.c          | 170 ++++++++++++++++-----
 .../net/ethernet/mellanox/mlx4/resource_tracker.c  |  51 ++++++-
 include/linux/mlx4/device.h                        |   8 +-
 10 files changed, 228 insertions(+), 63 deletions(-)

-- 
1.8.3.1

^ permalink raw reply

* [PATCH net-next V3 6/8] net/mlx4_en: Pass user MTU value to Firmware at set port command
From: Tariq Toukan @ 2017-01-29 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Shaker Daibes, Tariq Toukan
In-Reply-To: <1485708980-23468-1-git-send-email-tariqt@mellanox.com>

From: Shaker Daibes <shakerd@mellanox.com>

When starting the port, driver will inform Firmware about the actual MTU
which does not include implicit headers, such as FCS or VLAN tags.

Signed-off-by: Shaker Daibes <shakerd@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c |  8 +++
 drivers/net/ethernet/mellanox/mlx4/fw.c        |  2 +-
 drivers/net/ethernet/mellanox/mlx4/mlx4.h      |  7 ++-
 drivers/net/ethernet/mellanox/mlx4/port.c      | 71 ++++++++++++++++++++++++--
 include/linux/mlx4/device.h                    |  1 +
 5 files changed, 82 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index cfb4a9d67b45..60a021c34881 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1695,6 +1695,14 @@ int mlx4_en_start_port(struct net_device *dev)
 		       priv->port, err);
 		goto tx_err;
 	}
+
+	err = mlx4_SET_PORT_user_mtu(mdev->dev, priv->port, dev->mtu);
+	if (err) {
+		en_err(priv, "Failed to pass user MTU(%d) to Firmware for port %d, with error %d\n",
+		       dev->mtu, priv->port, err);
+		goto tx_err;
+	}
+
 	/* Set default qp number */
 	err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, priv->base_qpn, 0);
 	if (err) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index de39a5db4a6f..3fe885ce1902 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -2983,7 +2983,7 @@ static int mlx4_SET_PORT_phv_bit(struct mlx4_dev *dev, u8 port, u8 phv_bit)
 		return PTR_ERR(mailbox);
 	context = mailbox->buf;
 
-	context->v_ignore_fcs |=  SET_PORT_GEN_PHV_VALID;
+	context->flags2 |=  SET_PORT_GEN_PHV_VALID;
 	if (phv_bit)
 		context->phv_en |=  SET_PORT_GEN_PHV_EN;
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 88ee7d8a5923..1132d76ddfdf 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -487,6 +487,7 @@ struct mlx4_slave_state {
 	bool vst_qinq_supported;
 	u8 function;
 	dma_addr_t vhcr_dma;
+	u16 user_mtu[MLX4_MAX_PORTS + 1];
 	u16 mtu[MLX4_MAX_PORTS + 1];
 	__be32 ib_cap_mask[MLX4_MAX_PORTS + 1];
 	struct mlx4_slave_eqe eq[MLX4_MFUNC_MAX_EQES];
@@ -590,6 +591,7 @@ struct mlx4_mfunc_master_ctx {
 	struct mlx4_master_qp0_state qp0_state[MLX4_MAX_PORTS + 1];
 	int			init_port_ref[MLX4_MAX_PORTS + 1];
 	u16			max_mtu[MLX4_MAX_PORTS + 1];
+	u16			max_user_mtu[MLX4_MAX_PORTS + 1];
 	u8			pptx;
 	u8			pprx;
 	int			disable_mcast_ref[MLX4_MAX_PORTS + 1];
@@ -787,7 +789,7 @@ enum {
 
 struct mlx4_set_port_general_context {
 	u16 reserved1;
-	u8 v_ignore_fcs;
+	u8 flags2;
 	u8 flags;
 	union {
 		u8 ignore_fcs;
@@ -803,7 +805,8 @@ struct mlx4_set_port_general_context {
 	u16 reserved4;
 	u32 reserved5;
 	u8 phv_en;
-	u8 reserved6[3];
+	u8 reserved6[5];
+	__be16 user_mtu;
 };
 
 struct mlx4_set_port_rqp_calc_context {
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index b656dd5772e5..a7b0cdcb358a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -50,7 +50,8 @@
 #define MLX4_STATS_ERROR_COUNTERS_MASK		0x1ffc30ULL
 #define MLX4_STATS_PORT_COUNTERS_MASK		0x1fe00000ULL
 
-#define MLX4_FLAG_V_IGNORE_FCS_MASK		0x2
+#define MLX4_FLAG2_V_IGNORE_FCS_MASK		BIT(1)
+#define MLX4_FLAG2_V_USER_MTU_MASK		BIT(5)
 #define MLX4_IGNORE_FCS_MASK			0x1
 #define MLX4_TC_MAX_NUMBER			8
 
@@ -1239,6 +1240,38 @@ void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave)
 	return;
 }
 
+static void
+mlx4_en_set_port_user_mtu(struct mlx4_dev *dev, int slave, int port,
+			  struct mlx4_set_port_general_context *gen_context)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
+	struct mlx4_slave_state *slave_st = &master->slave_state[slave];
+	u16 user_mtu, prev_user_mtu;
+
+	/* User Mtu is configured as the max USER_MTU among all
+	 * the functions on the port.
+	 */
+	user_mtu = be16_to_cpu(gen_context->user_mtu);
+	user_mtu = min_t(int, user_mtu, dev->caps.eth_mtu_cap[port]);
+	prev_user_mtu = slave_st->user_mtu[port];
+	slave_st->user_mtu[port] = user_mtu;
+	if (user_mtu > master->max_user_mtu[port])
+		master->max_user_mtu[port] = user_mtu;
+	if (user_mtu < prev_user_mtu &&
+	    prev_user_mtu == master->max_user_mtu[port]) {
+		int i;
+
+		slave_st->user_mtu[port] = user_mtu;
+		master->max_user_mtu[port] = user_mtu;
+		for (i = 0; i < dev->num_slaves; i++)
+			master->max_user_mtu[port] =
+				max_t(u16, master->max_user_mtu[port],
+				      master->slave_state[i].user_mtu[port]);
+	}
+	gen_context->user_mtu = cpu_to_be16(master->max_user_mtu[port]);
+}
+
 static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
 				u8 op_mod, struct mlx4_cmd_mailbox *inbox)
 {
@@ -1269,7 +1302,9 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
 	is_eth = op_mod;
 	port_info = &priv->port[port];
 
-	/* Slaves cannot perform SET_PORT operations except changing MTU */
+	/* Slaves cannot perform SET_PORT operations,
+	 * except for changing MTU and USER_MTU.
+	 */
 	if (is_eth) {
 		if (slave != dev->caps.function &&
 		    in_modifier != MLX4_SET_PORT_GENERAL &&
@@ -1316,8 +1351,12 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
 					    master->slave_state[i].mtu[port]);
 				}
 			}
-
 			gen_context->mtu = cpu_to_be16(master->max_mtu[port]);
+
+			if (gen_context->flags2 & MLX4_FLAG2_V_USER_MTU_MASK)
+				mlx4_en_set_port_user_mtu(dev, slave, port,
+							  gen_context);
+
 			/* Slave cannot change Global Pause configuration */
 			if (slave != mlx4_master_func_num(dev) &&
 			    ((gen_context->pptx != master->pptx) ||
@@ -1608,6 +1647,30 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
 }
 EXPORT_SYMBOL(mlx4_SET_PORT_qpn_calc);
 
+int mlx4_SET_PORT_user_mtu(struct mlx4_dev *dev, u8 port, u16 user_mtu)
+{
+	struct mlx4_cmd_mailbox *mailbox;
+	struct mlx4_set_port_general_context *context;
+	u32 in_mod;
+	int err;
+
+	mailbox = mlx4_alloc_cmd_mailbox(dev);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	context = mailbox->buf;
+	context->flags2 |= MLX4_FLAG2_V_USER_MTU_MASK;
+	context->user_mtu = cpu_to_be16(user_mtu);
+
+	in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
+	err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE,
+		       MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
+		       MLX4_CMD_WRAPPED);
+
+	mlx4_free_cmd_mailbox(dev, mailbox);
+	return err;
+}
+EXPORT_SYMBOL(mlx4_SET_PORT_user_mtu);
+
 int mlx4_SET_PORT_fcs_check(struct mlx4_dev *dev, u8 port, u8 ignore_fcs_value)
 {
 	struct mlx4_cmd_mailbox *mailbox;
@@ -1619,7 +1682,7 @@ int mlx4_SET_PORT_fcs_check(struct mlx4_dev *dev, u8 port, u8 ignore_fcs_value)
 	if (IS_ERR(mailbox))
 		return PTR_ERR(mailbox);
 	context = mailbox->buf;
-	context->v_ignore_fcs |= MLX4_FLAG_V_IGNORE_FCS_MASK;
+	context->flags2 |= MLX4_FLAG2_V_IGNORE_FCS_MASK;
 	if (ignore_fcs_value)
 		context->ignore_fcs |= MLX4_IGNORE_FCS_MASK;
 	else
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index c3ac945b2759..7e66e4f62858 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -1374,6 +1374,7 @@ int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port,
 int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac);
 int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
 			  u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx);
+int mlx4_SET_PORT_user_mtu(struct mlx4_dev *dev, u8 port, u16 user_mtu);
 int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
 			   u8 promisc);
 int mlx4_SET_PORT_BEACON(struct mlx4_dev *dev, u8 port, u16 time);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next V3 1/8] net/mlx4: Replace ENOSYS with better fitting error codes
From: Tariq Toukan @ 2017-01-29 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Tariq Toukan
In-Reply-To: <1485708980-23468-1-git-send-email-tariqt@mellanox.com>

Conform the following warning:
WARNING: ENOSYS means 'invalid syscall nr' and nothing else.

Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/en_ethtool.c       | 2 +-
 drivers/net/ethernet/mellanox/mlx4/fw.c               | 2 +-
 drivers/net/ethernet/mellanox/mlx4/main.c             | 6 +++---
 drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index d5a9372ed84d..17a600b9f81b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -1980,7 +1980,7 @@ static int mlx4_en_get_module_info(struct net_device *dev,
 		modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
 		break;
 	default:
-		return -ENOSYS;
+		return -EINVAL;
 	}
 
 	return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 84bab9f0732e..25b5b32e958f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -672,7 +672,7 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u8 gen_or_port,
 	MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET);
 	func_cap->physical_port = field;
 	if (func_cap->physical_port != gen_or_port) {
-		err = -ENOSYS;
+		err = -EINVAL;
 		goto out;
 	}
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index bffa6f345f2f..15ef787e71ba 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -838,7 +838,7 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
 	 */
 	if (hca_param.global_caps) {
 		mlx4_err(dev, "Unknown hca global capabilities\n");
-		return -ENOSYS;
+		return -EINVAL;
 	}
 
 	mlx4_log_num_mgm_entry_size = hca_param.log_mc_entry_sz;
@@ -896,7 +896,7 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
 	    PF_CONTEXT_BEHAVIOUR_MASK) {
 		mlx4_err(dev, "Unknown pf context behaviour %x known flags %x\n",
 			 func_cap.pf_context_behaviour, PF_CONTEXT_BEHAVIOUR_MASK);
-		return -ENOSYS;
+		return -EINVAL;
 	}
 
 	dev->caps.num_ports		= func_cap.num_ports;
@@ -3492,7 +3492,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
 	mlx4_enable_msi_x(dev);
 	if ((mlx4_is_mfunc(dev)) &&
 	    !(dev->flags & MLX4_FLAG_MSI_X)) {
-		err = -ENOSYS;
+		err = -EOPNOTSUPP;
 		mlx4_err(dev, "INTx is not supported in multi-function mode, aborting\n");
 		goto err_free_eq;
 	}
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 6da6e01d07bd..84c74a79752a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -1396,7 +1396,7 @@ static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra)
 	case RES_MTT:
 		return remove_mtt_ok((struct res_mtt *)res, extra);
 	case RES_MAC:
-		return -ENOSYS;
+		return -EOPNOTSUPP;
 	case RES_EQ:
 		return remove_eq_ok((struct res_eq *)res);
 	case RES_COUNTER:
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next V3 5/8] net/mlx4_en: Adding support of turning off link autonegotiation via ethtool
From: Tariq Toukan @ 2017-01-29 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Ariel Levkovich, Tariq Toukan
In-Reply-To: <1485708980-23468-1-git-send-email-tariqt@mellanox.com>

From: Ariel Levkovich <lariel@mellanox.com>

This feature will allow the user to disable auto negotiation
on the port for mlx4 devices while setting the speed is limited
to 1GbE speeds.
Other speeds will not be accepted in autoneg off mode.

This functionality is permitted providing that the firmware
is compatible with this feature.
The above is determined by querying a new dedicated capability
bit in the device.

Signed-off-by: Ariel Levkovich <lariel@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 24 +++++++++++++++++++-----
 include/linux/mlx4/device.h                     |  7 ++++++-
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 785757f17687..ca730d4abbb4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -902,6 +902,7 @@ static __be32 speed_set_ptys_admin(struct mlx4_en_priv *priv, u32 speed,
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	struct mlx4_ptys_reg ptys_reg;
 	__be32 proto_admin;
+	u8 cur_autoneg;
 	int ret;
 
 	u32 ptys_adv = ethtool2ptys_link_modes(
@@ -931,10 +932,21 @@ static __be32 speed_set_ptys_admin(struct mlx4_en_priv *priv, u32 speed,
 		return 0;
 	}
 
-	proto_admin = link_ksettings->base.autoneg == AUTONEG_ENABLE ?
-		cpu_to_be32(ptys_adv) :
-		speed_set_ptys_admin(priv, speed,
-				     ptys_reg.eth_proto_cap);
+	cur_autoneg = ptys_reg.flags & MLX4_PTYS_AN_DISABLE_ADMIN ?
+				AUTONEG_DISABLE : AUTONEG_ENABLE;
+
+	if (link_ksettings->base.autoneg == AUTONEG_DISABLE) {
+		proto_admin = speed_set_ptys_admin(priv, speed,
+						   ptys_reg.eth_proto_cap);
+		if ((be32_to_cpu(proto_admin) &
+		     (MLX4_PROT_MASK(MLX4_1000BASE_CX_SGMII) |
+		      MLX4_PROT_MASK(MLX4_1000BASE_KX))) &&
+		    (ptys_reg.flags & MLX4_PTYS_AN_DISABLE_CAP))
+			ptys_reg.flags |= MLX4_PTYS_AN_DISABLE_ADMIN;
+	} else {
+		proto_admin = cpu_to_be32(ptys_adv);
+		ptys_reg.flags &= ~MLX4_PTYS_AN_DISABLE_ADMIN;
+	}
 
 	proto_admin &= ptys_reg.eth_proto_cap;
 	if (!proto_admin) {
@@ -942,7 +954,9 @@ static __be32 speed_set_ptys_admin(struct mlx4_en_priv *priv, u32 speed,
 		return -EINVAL; /* nothing to change due to bad input */
 	}
 
-	if (proto_admin == ptys_reg.eth_proto_admin)
+	if ((proto_admin == ptys_reg.eth_proto_admin) &&
+	    ((ptys_reg.flags & MLX4_PTYS_AN_DISABLE_CAP) &&
+	     (link_ksettings->base.autoneg == cur_autoneg)))
 		return 0; /* Nothing to change */
 
 	en_dbg(DRV, priv, "mlx4_ACCESS_PTYS_REG SET: ptys_reg.eth_proto_admin = 0x%x\n",
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 6533c16e27ad..c3ac945b2759 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -1539,8 +1539,13 @@ enum mlx4_ptys_proto {
 	MLX4_PTYS_EN = 1<<2,
 };
 
+enum mlx4_ptys_flags {
+	MLX4_PTYS_AN_DISABLE_CAP   = 1 << 5,
+	MLX4_PTYS_AN_DISABLE_ADMIN = 1 << 6,
+};
+
 struct mlx4_ptys_reg {
-	u8 resrvd1;
+	u8 flags;
 	u8 local_port;
 	u8 resrvd2;
 	u8 proto_mask;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next V3 7/8] net/mlx4_en: Check the enabling mtu flag in SET_PORT wrapper flow
From: Tariq Toukan @ 2017-01-29 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Shaker Daibes, Tariq Toukan
In-Reply-To: <1485708980-23468-1-git-send-email-tariqt@mellanox.com>

From: Shaker Daibes <shakerd@mellanox.com>

Make sure MTU mask flag is set using new field upon set port
request. In addition, move this code into a helper function for better
code readability.

Signed-off-by: Shaker Daibes <shakerd@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/port.c | 59 +++++++++++++++++++------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index a7b0cdcb358a..57a10575a7aa 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -52,6 +52,7 @@
 
 #define MLX4_FLAG2_V_IGNORE_FCS_MASK		BIT(1)
 #define MLX4_FLAG2_V_USER_MTU_MASK		BIT(5)
+#define MLX4_FLAG_V_MTU_MASK			BIT(0)
 #define MLX4_IGNORE_FCS_MASK			0x1
 #define MLX4_TC_MAX_NUMBER			8
 
@@ -1241,6 +1242,38 @@ void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave)
 }
 
 static void
+mlx4_en_set_port_mtu(struct mlx4_dev *dev, int slave, int port,
+		     struct mlx4_set_port_general_context *gen_context)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
+	struct mlx4_slave_state *slave_st = &master->slave_state[slave];
+	u16 mtu, prev_mtu;
+
+	/* Mtu is configured as the max USER_MTU among all
+	 * the functions on the port.
+	 */
+	mtu = be16_to_cpu(gen_context->mtu);
+	mtu = min_t(int, mtu, dev->caps.eth_mtu_cap[port] +
+		    ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
+	prev_mtu = slave_st->mtu[port];
+	slave_st->mtu[port] = mtu;
+	if (mtu > master->max_mtu[port])
+		master->max_mtu[port] = mtu;
+	if (mtu < prev_mtu && prev_mtu == master->max_mtu[port]) {
+		int i;
+
+		slave_st->mtu[port] = mtu;
+		master->max_mtu[port] = mtu;
+		for (i = 0; i < dev->num_slaves; i++)
+			master->max_mtu[port] =
+				max_t(u16, master->max_mtu[port],
+				      master->slave_state[i].mtu[port]);
+	}
+	gen_context->mtu = cpu_to_be16(master->max_mtu[port]);
+}
+
+static void
 mlx4_en_set_port_user_mtu(struct mlx4_dev *dev, int slave, int port,
 			  struct mlx4_set_port_general_context *gen_context)
 {
@@ -1278,7 +1311,6 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	struct mlx4_port_info *port_info;
 	struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
-	struct mlx4_slave_state *slave_st = &master->slave_state[slave];
 	struct mlx4_set_port_rqp_calc_context *qpn_context;
 	struct mlx4_set_port_general_context *gen_context;
 	struct mlx4_roce_gid_entry *gid_entry_tbl, *gid_entry_mbox, *gid_entry_mb1;
@@ -1289,7 +1321,6 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
 	int base;
 	u32 in_modifier;
 	u32 promisc;
-	u16 mtu, prev_mtu;
 	int err;
 	int i, j;
 	int offset;
@@ -1332,26 +1363,10 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
 			break;
 		case MLX4_SET_PORT_GENERAL:
 			gen_context = inbox->buf;
-			/* Mtu is configured as the max MTU among all the
-			 * the functions on the port. */
-			mtu = be16_to_cpu(gen_context->mtu);
-			mtu = min_t(int, mtu, dev->caps.eth_mtu_cap[port] +
-				    ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
-			prev_mtu = slave_st->mtu[port];
-			slave_st->mtu[port] = mtu;
-			if (mtu > master->max_mtu[port])
-				master->max_mtu[port] = mtu;
-			if (mtu < prev_mtu && prev_mtu ==
-						master->max_mtu[port]) {
-				slave_st->mtu[port] = mtu;
-				master->max_mtu[port] = mtu;
-				for (i = 0; i < dev->num_slaves; i++) {
-					master->max_mtu[port] =
-					max(master->max_mtu[port],
-					    master->slave_state[i].mtu[port]);
-				}
-			}
-			gen_context->mtu = cpu_to_be16(master->max_mtu[port]);
+
+			if (gen_context->flags & MLX4_FLAG_V_MTU_MASK)
+				mlx4_en_set_port_mtu(dev, slave, port,
+						     gen_context);
 
 			if (gen_context->flags2 & MLX4_FLAG2_V_USER_MTU_MASK)
 				mlx4_en_set_port_user_mtu(dev, slave, port,
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next V3 2/8] net/mlx4_core: Device revision support
From: Tariq Toukan @ 2017-01-29 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Yishai Hadas, Tariq Toukan
In-Reply-To: <1485708980-23468-1-git-send-email-tariqt@mellanox.com>

From: Yishai Hadas <yishaih@mellanox.com>

The device revision field returned by the NodeInfo MAD is incorrect
on ConnectX3 devices.

This patch is driver side handling to complete a FW fix added at 2.11.1172.
INIT_HCA - bit at offset 0x0C.12 is set to 1 so that FW will report
correct device revision.

Older FW versions won't be affected from turning on that bit,
no capability bit is needed.

Signed-off-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/fw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 25b5b32e958f..de39a5db4a6f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -1875,7 +1875,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
 	*((u8 *) mailbox->buf + INIT_HCA_VERSION_OFFSET) = INIT_HCA_VERSION;
 
 	*((u8 *) mailbox->buf + INIT_HCA_CACHELINE_SZ_OFFSET) =
-		(ilog2(cache_line_size()) - 4) << 5;
+		((ilog2(cache_line_size()) - 4) << 5) | (1 << 4);
 
 #if defined(__LITTLE_ENDIAN)
 	*(inbox + INIT_HCA_FLAGS_OFFSET / 4) &= ~cpu_to_be32(1 << 1);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next V3 3/8] net/mlx4_core: Add resource alloc/dealloc debugging
From: Tariq Toukan @ 2017-01-29 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Matan Barak, Tariq Toukan
In-Reply-To: <1485708980-23468-1-git-send-email-tariqt@mellanox.com>

From: Matan Barak <matanb@mellanox.com>

In order to aid debugging of functions that take a resource but
don't put it, add the last function name that successfully grabbed
this resource.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 .../net/ethernet/mellanox/mlx4/resource_tracker.c  | 49 ++++++++++++++++++++--
 1 file changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 84c74a79752a..6fe9f76ae656 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -77,6 +77,7 @@ struct res_common {
 	int			from_state;
 	int			to_state;
 	int			removing;
+	const char		*func_name;
 };
 
 enum {
@@ -837,6 +838,36 @@ static int mpt_mask(struct mlx4_dev *dev)
 	return dev->caps.num_mpts - 1;
 }
 
+static const char *mlx4_resource_type_to_str(enum mlx4_resource t)
+{
+	switch (t) {
+	case RES_QP:
+		return "QP";
+	case RES_CQ:
+		return "CQ";
+	case RES_SRQ:
+		return "SRQ";
+	case RES_XRCD:
+		return "XRCD";
+	case RES_MPT:
+		return "MPT";
+	case RES_MTT:
+		return "MTT";
+	case RES_MAC:
+		return "MAC";
+	case RES_VLAN:
+		return "VLAN";
+	case RES_COUNTER:
+		return "COUNTER";
+	case RES_FS_RULE:
+		return "FS_RULE";
+	case RES_EQ:
+		return "EQ";
+	default:
+		return "INVALID RESOURCE";
+	}
+}
+
 static void *find_res(struct mlx4_dev *dev, u64 res_id,
 		      enum mlx4_resource type)
 {
@@ -846,9 +877,9 @@ static void *find_res(struct mlx4_dev *dev, u64 res_id,
 				  res_id);
 }
 
-static int get_res(struct mlx4_dev *dev, int slave, u64 res_id,
-		   enum mlx4_resource type,
-		   void *res)
+static int _get_res(struct mlx4_dev *dev, int slave, u64 res_id,
+		    enum mlx4_resource type,
+		    void *res, const char *func_name)
 {
 	struct res_common *r;
 	int err = 0;
@@ -861,6 +892,10 @@ static int get_res(struct mlx4_dev *dev, int slave, u64 res_id,
 	}
 
 	if (r->state == RES_ANY_BUSY) {
+		mlx4_warn(dev,
+			  "%s(%d) trying to get resource %llx of type %s, but it's already taken by %s\n",
+			  func_name, slave, res_id, mlx4_resource_type_to_str(type),
+			  r->func_name);
 		err = -EBUSY;
 		goto exit;
 	}
@@ -872,6 +907,7 @@ static int get_res(struct mlx4_dev *dev, int slave, u64 res_id,
 
 	r->from_state = r->state;
 	r->state = RES_ANY_BUSY;
+	r->func_name = func_name;
 
 	if (res)
 		*((struct res_common **)res) = r;
@@ -881,6 +917,9 @@ static int get_res(struct mlx4_dev *dev, int slave, u64 res_id,
 	return err;
 }
 
+#define get_res(dev, slave, res_id, type, res) \
+	_get_res((dev), (slave), (res_id), (type), (res), __func__)
+
 int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev,
 				    enum mlx4_resource type,
 				    u64 res_id, int *slave)
@@ -911,8 +950,10 @@ static void put_res(struct mlx4_dev *dev, int slave, u64 res_id,
 
 	spin_lock_irq(mlx4_tlock(dev));
 	r = find_res(dev, res_id, type);
-	if (r)
+	if (r) {
 		r->state = r->from_state;
+		r->func_name = "";
+	}
 	spin_unlock_irq(mlx4_tlock(dev));
 }
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next V3 4/8] net/mlx4_core: Get num_tc using netdev_get_num_tc
From: Tariq Toukan @ 2017-01-29 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Alaa Hleihel, Tariq Toukan
In-Reply-To: <1485708980-23468-1-git-send-email-tariqt@mellanox.com>

From: Alaa Hleihel <alaa@mellanox.com>

Avoid reading num_tc directly from struct net_device, but use
the helper function netdev_get_num_tc.

Fixes: bc6a4744b827 ("net/mlx4_en: num cores tx rings for every UP")
Fixes: f5b6345ba8da ("net/mlx4_en: User prio mapping gets corrupted when changing number of channels")
Signed-off-by: Alaa Hleihel <alaa@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +-
 drivers/net/ethernet/mellanox/mlx4/en_tx.c      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 17a600b9f81b..785757f17687 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -1788,7 +1788,7 @@ static int mlx4_en_set_channels(struct net_device *dev,
 	netif_set_real_num_tx_queues(dev, priv->tx_ring_num[TX]);
 	netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
 
-	if (dev->num_tc)
+	if (netdev_get_num_tc(dev))
 		mlx4_en_setup_tc(dev, MLX4_EN_NUM_UP);
 
 	en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num[TX]);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 5886ad78058f..3ed42199d3f1 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -710,7 +710,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,
 	u16 rings_p_up = priv->num_tx_rings_p_up;
 	u8 up = 0;
 
-	if (dev->num_tc)
+	if (netdev_get_num_tc(dev))
 		return skb_tx_hash(dev, skb);
 
 	if (skb_vlan_tag_present(skb))
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next V3 8/8] net/mlx4_en: Check the enabling pptx/pprx flags in SET_PORT wrapper flow
From: Tariq Toukan @ 2017-01-29 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Shaker Daibes, Tariq Toukan
In-Reply-To: <1485708980-23468-1-git-send-email-tariqt@mellanox.com>

From: Shaker Daibes <shakerd@mellanox.com>

Make sure pptx/pprx mask flag is set using new fields upon set port
request. In addition, move this code into a helper function for better
code readability.

Signed-off-by: Shaker Daibes <shakerd@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/en_port.h |  1 -
 drivers/net/ethernet/mellanox/mlx4/mlx4.h    |  4 ++-
 drivers/net/ethernet/mellanox/mlx4/port.c    | 42 ++++++++++++++++++----------
 3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.h b/drivers/net/ethernet/mellanox/mlx4/en_port.h
index 040da4b16b1c..930f961fee42 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_port.h
+++ b/drivers/net/ethernet/mellanox/mlx4/en_port.h
@@ -35,7 +35,6 @@
 #define _MLX4_EN_PORT_H_
 
 
-#define SET_PORT_GEN_ALL_VALID	0x7
 #define SET_PORT_PROMISC_SHIFT	31
 #define SET_PORT_MC_PROMISC_SHIFT	30
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 1132d76ddfdf..7a495090b0bc 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -776,7 +776,9 @@ struct mlx4_vlan_table {
 	int			max;
 };
 
-#define SET_PORT_GEN_ALL_VALID		0x7
+#define SET_PORT_GEN_ALL_VALID	(MLX4_FLAG_V_MTU_MASK	| \
+				 MLX4_FLAG_V_PPRX_MASK	| \
+				 MLX4_FLAG_V_PPTX_MASK)
 #define SET_PORT_PROMISC_SHIFT		31
 #define SET_PORT_MC_PROMISC_SHIFT	30
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index 57a10575a7aa..5053c949148f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -53,6 +53,8 @@
 #define MLX4_FLAG2_V_IGNORE_FCS_MASK		BIT(1)
 #define MLX4_FLAG2_V_USER_MTU_MASK		BIT(5)
 #define MLX4_FLAG_V_MTU_MASK			BIT(0)
+#define MLX4_FLAG_V_PPRX_MASK			BIT(1)
+#define MLX4_FLAG_V_PPTX_MASK			BIT(2)
 #define MLX4_IGNORE_FCS_MASK			0x1
 #define MLX4_TC_MAX_NUMBER			8
 
@@ -1305,12 +1307,32 @@ void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave)
 	gen_context->user_mtu = cpu_to_be16(master->max_user_mtu[port]);
 }
 
+static void
+mlx4_en_set_port_global_pause(struct mlx4_dev *dev, int slave,
+			      struct mlx4_set_port_general_context *gen_context)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
+
+	/* Slave cannot change Global Pause configuration */
+	if (slave != mlx4_master_func_num(dev) &&
+	    (gen_context->pptx != master->pptx ||
+	     gen_context->pprx != master->pprx)) {
+		gen_context->pptx = master->pptx;
+		gen_context->pprx = master->pprx;
+		mlx4_warn(dev, "denying Global Pause change for slave:%d\n",
+			  slave);
+	} else {
+		master->pptx = gen_context->pptx;
+		master->pprx = gen_context->pprx;
+	}
+}
+
 static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
 				u8 op_mod, struct mlx4_cmd_mailbox *inbox)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	struct mlx4_port_info *port_info;
-	struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
 	struct mlx4_set_port_rqp_calc_context *qpn_context;
 	struct mlx4_set_port_general_context *gen_context;
 	struct mlx4_roce_gid_entry *gid_entry_tbl, *gid_entry_mbox, *gid_entry_mb1;
@@ -1372,19 +1394,11 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
 				mlx4_en_set_port_user_mtu(dev, slave, port,
 							  gen_context);
 
-			/* Slave cannot change Global Pause configuration */
-			if (slave != mlx4_master_func_num(dev) &&
-			    ((gen_context->pptx != master->pptx) ||
-			     (gen_context->pprx != master->pprx))) {
-				gen_context->pptx = master->pptx;
-				gen_context->pprx = master->pprx;
-				mlx4_warn(dev,
-					  "denying Global Pause change for slave:%d\n",
-					  slave);
-			} else {
-				master->pptx = gen_context->pptx;
-				master->pprx = gen_context->pprx;
-			}
+			if (gen_context->flags &
+			    (MLX4_FLAG_V_PPRX_MASK || MLX4_FLAG_V_PPTX_MASK))
+				mlx4_en_set_port_global_pause(dev, slave,
+							      gen_context);
+
 			break;
 		case MLX4_SET_PORT_GID_TABLE:
 			/* change to MULTIPLE entries: number of guest's gids
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH net-next v2 1/2] qed: Add infrastructure for PTP support.
From: Richard Cochran @ 2017-01-29 15:28 UTC (permalink / raw)
  To: Sudarsana Kalluru; +Cc: davem, netdev, Yuval.Mintz
In-Reply-To: <1485674903-27689-2-git-send-email-Sudarsana.Kalluru@cavium.com>

On Sat, Jan 28, 2017 at 11:28:22PM -0800, Sudarsana Kalluru wrote:
> +/* Adjust the HW clock by a rate given in parts-per-million (ppm) units.
> + * FW/HW accepts the adjustment value in terms of 3 parameters:
> + *   Drift period - adjustment happens once in certain number of nano seconds.
> + *   Drift value - time is adjusted by a certain value, for example by 5 ns.
> + *   Drift direction - add or subtract the adjustment value.
> + * The routine translates ppm into the adjustment triplet in an optimal manner.
> + */
> +static int qed_ptp_hw_adjfreq(struct qed_dev *cdev, s32 ppb)
> +{
> +	struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
> +	s64 period, period1, period2, dif, dif1, dif2;
> +	struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt;
> +	int drift_dir, best_val, best_period;
> +	s64 best_dif, temp, val;
> +	u32 drift_ctr_cfg = 0;
> +	u32 drift_state;
> +
> +	best_dif = 1000000000;
> +	best_period = 1;
> +	best_val = 0;
> +	drift_dir = 1;
> +
> +	if (ppb < 0) {
> +		ppb = -ppb;
> +		drift_dir = 0;
> +	}
> +
> +	if (ppb == 0) {
> +		/* No clock adjustment required */
> +		best_val = 0;
> +		best_period = 0xFFFFFFF;
> +	} else {
> +		/* Adjustment value is up to +/-7ns, find an optimal value in
> +		 * this range.
> +		 */
> +		for (val = 0; val <= 7; val++) {
> +			period1 = val * 1000000000;
> +			do_div(period1, ppb);

One,

> +			period1 -= 8;
> +			do_div(period1, 16);

two,

> +			if (period1 < 1)
> +				period1 = 1;
> +			if (period1 > 0xFFFFFFE)
> +				period1 = 0xFFFFFFE;
> +			period2 = period1 + 1;
> +
> +			temp = val * 1000000000;
> +			do_div(temp, (period1 * 16 + 8));

three,

> +			dif1 = ppb - temp;
> +			if (dif1 < 0)
> +				dif1 = -dif1;
> +
> +			temp = val * 1000000000;
> +			do_div(temp, (period2 * 16 + 8));

four times seven makes twenty-eight 64 bit divisions per adjustment!

Isn't there a smarter way to do this?

Also, the case where val=0 makes little sense.


Thanks,
Richard

> +			dif2 = ppb - temp;
> +			if (dif2 < 0)
> +				dif2 = -dif2;
> +
> +			dif = min_t(s64, dif1, dif2);
> +			period = (dif1 < dif2) ? period1 : period2;
> +			if (dif < best_dif) {
> +				best_dif = dif;
> +				best_val = (int)val;
> +				best_period = (int)period;
> +			}
> +		}
> +	}
> +
> +	drift_ctr_cfg = (best_period << QED_DRIFT_CNTR_TIME_QUANTA_SHIFT) |
> +			(best_val << QED_DRIFT_CNTR_ADJUSTMENT_SHIFT) |
> +			(drift_dir << QED_DRIFT_CNTR_DIRECTION_SHIFT);
> +
> +	qed_wr(p_hwfn, p_ptt, NIG_REG_TSGEN_RST_DRIFT_CNTR, 0x1);
> +
> +	drift_state = qed_rd(p_hwfn, p_ptt, NIG_REG_TSGEN_RST_DRIFT_CNTR);
> +	if (drift_state & 1) {
> +		qed_wr(p_hwfn, p_ptt, NIG_REG_TSGEN_DRIFT_CNTR_CONF,
> +		       drift_ctr_cfg);
> +	} else {
> +		DP_INFO(p_hwfn, "Drift counter is not reset\n");
> +		return -EINVAL;
> +	}
> +
> +	qed_wr(p_hwfn, p_ptt, NIG_REG_TSGEN_RST_DRIFT_CNTR, 0x0);
> +
> +	return 0;
> +}

^ permalink raw reply

* Re: [PATCH net-next v2 2/2] qede: Add driver support for PTP.
From: Richard Cochran @ 2017-01-29 15:35 UTC (permalink / raw)
  To: Sudarsana Kalluru; +Cc: davem, netdev, Yuval.Mintz
In-Reply-To: <1485674903-27689-3-git-send-email-Sudarsana.Kalluru@cavium.com>

On Sat, Jan 28, 2017 at 11:28:23PM -0800, Sudarsana Kalluru wrote:
> +/**
> + * qede_ptp_adjfreq
> + * @ptp: the ptp clock structure
> + * @ppb: parts per billion adjustment from base
> + *
> + * Adjust the frequency of the ptp cycle counter by the
> + * indicated ppb from the base frequency.
> + */
> +static int qede_ptp_adjfreq(struct ptp_clock_info *info, s32 ppb)
> +{
> +	struct qede_ptp *ptp = container_of(info, struct qede_ptp, clock_info);
> +	struct qede_dev *edev = ptp->edev;
> +	int rc;
> +
> +	__qede_lock(edev);
> +	if (edev->state == QEDE_STATE_OPEN) {
> +		spin_lock_bh(&ptp->lock);
> +		rc = ptp->ops->adjfreq(edev->cdev, ppb);

Why add this extra layer of indirection?

You could put these this test into qed_ptp_hw_adjfreq() and register
that function directly.

> +		spin_unlock_bh(&ptp->lock);
> +	} else {
> +		DP_ERR(edev, "PTP adjfreq called while interface is down\n");
> +		return -EFAULT;
> +	}
> +	__qede_unlock(edev);
> +
> +	return rc;
> +}

Thanks,
Richard

^ permalink raw reply

* Re: [PATCH net-next v2 1/2] qed: Add infrastructure for PTP support.
From: Richard Cochran @ 2017-01-29 15:31 UTC (permalink / raw)
  To: Sudarsana Kalluru; +Cc: davem, netdev, Yuval.Mintz
In-Reply-To: <1485674903-27689-2-git-send-email-Sudarsana.Kalluru@cavium.com>

On Sat, Jan 28, 2017 at 11:28:22PM -0800, Sudarsana Kalluru wrote:
> +/* Read Rx timestamp */
> +static int qed_ptp_hw_read_rx_ts(struct qed_dev *cdev, u64 *timestamp)
> +{
> +	struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
> +	struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt;
> +	u32 val;
> +
> +	*timestamp = 0;
> +	val = qed_rd(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_SEQID);
> +	if (!(val & QED_TIMESTAMP_MASK)) {
> +		DP_INFO(p_hwfn, "Invalid Rx timestamp, buf_seqid = %d\n", val);
> +		return -EINVAL;
> +	}
> +
> +	val = qed_rd(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_TS_LSB);
> +	*timestamp = qed_rd(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_TS_MSB);

You can already "Reset timestamp register to allow new timestamp" at
this point, before combining the MSB and LSB.

> +	*timestamp <<= 32;
> +	*timestamp |= val;
> +
> +	/* Reset timestamp register to allow new timestamp */
> +	qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_SEQID,
> +	       QED_TIMESTAMP_MASK);
> +
> +	return 0;
> +}

Thanks,
Richard

^ permalink raw reply

* Re: [PATCH stable v1 05/13] net: ethernet: aquantia: Support for NIC-specific code
From: Lino Sanfilippo @ 2017-01-29 15:06 UTC (permalink / raw)
  To: Alexander Loktionov, netdev, David VomLehn
  Cc: David S . Miller, Simon Edelhaus, Dmitrii Tarakanov, Pavel Belous,
	Dmitry Bezrukov
In-Reply-To: <b46be5c30bbf72be8825fafb299feb8954b35872.1485665881.git.vomlehn@texas.net>

On 29.01.2017 06:09, Alexander Loktionov wrote:

> +
> +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);

Initialization of err is superfluous.


> +	if (err < 0)
> +		goto err_exit;
> +
> +err_exit:
> +	return err;
> +}
> +
> +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) {

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


> +
> +static int aq_pci_probe(struct pci_dev *pdev,
> +			const struct pci_device_id *pci_id)
> +{
> +	struct aq_hw_ops *aq_hw_ops = NULL;
> +	struct aq_pci_func_s *aq_pci_func = NULL;
> +	int err = 0;
> +
> +	err = pci_enable_device(pdev);
> +	if (err < 0)
> +		goto err_exit;
> +	aq_hw_ops = aq_pci_probe_get_hw_ops_by_id(pdev);
> +	aq_pci_func = aq_pci_func_alloc(aq_hw_ops, pdev,
> +					&aq_ndev_ops, &aq_ethtool_ops);
> +	if (!aq_pci_func) {

pci_disable_device() is missing.

> +
> +static int __init aq_module_init(void)
> +{
> +	int err = 0;
> +
> +	err = pci_register_driver(&aq_pci_ops);
> +	if (err < 0)
> +		goto err_exit;
> +
> +err_exit:
> +	return err;
> +}
> +
> +static void __exit aq_module_exit(void)
> +{
> +	pci_unregister_driver(&aq_pci_ops);
> +}
>

This can be reduced to a single line:

module_pci_driver(aq_pci_ops);

> +
> +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(&self->header.busy_count);
> +	is_busy = true;

What is "is_busy" needed for? Furthermore busy_count seems to be meant
for synchronization with the xmit function. Why do they have to be 
synchronized?


> +
> +	ndev->stats.rx_packets = stats_rx.packets;
> +	ndev->stats.rx_bytes = stats_rx.bytes;
> +	ndev->stats.rx_errors = stats_rx.errors;
> +	ndev->stats.tx_packets = stats_tx.packets;
> +	ndev->stats.tx_bytes = stats_tx.bytes;
> +	ndev->stats.tx_errors = stats_tx.errors;

You should consider the use of u64_stats_update_begin() and friends to
update and retrieve statistics. Also why do you have to update the
stats in a timer?


> +
> +struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,
> +				   const struct ethtool_ops *et_ops,
> +				   struct device *dev,
> +				   struct aq_pci_func_s *aq_pci_func,
> +				   unsigned int port,
> +				   const struct aq_hw_ops *aq_hw_ops)
> +{
> +	struct net_device *ndev = NULL;
> +	struct aq_nic_s *self = NULL;
> +	int err = 0;
> +
> +	ndev = aq_nic_ndev_alloc();
> +	self = netdev_priv(ndev);
> +	if (!self) {

For this and all other checks of self:
how can self ever be NULL?

> +
> +int aq_nic_ndev_register(struct aq_nic_s *self)
> +{
> +	int err = 0;
> +	unsigned int i = 0U;
> +
> +	if (!self->ndev) {
> +		err = -EINVAL;
> +		goto err_exit;
> +	}
> +	err = self->aq_hw_ops.hw_get_mac_permanent(self->aq_hw,
> +			    self->aq_nic_cfg.aq_hw_caps,
> +			    self->ndev->dev_addr);
> +	if (err < 0)
> +		goto err_exit;
> +
> +#if defined(AQ_CFG_MAC_ADDR_PERMANENT)
> +	{
> +		static u8 mac_addr_permanent[] = AQ_CFG_MAC_ADDR_PERMANENT;
> +
> +		ether_addr_copy(self->ndev->dev_addr, mac_addr_permanent);
> +	}
> +#endif
> +	err = register_netdev(self->ndev);
> +	if (err < 0)
> +		goto err_exit;
> +

This looks racy. Note that as soon as you call register_netdev() your 
drivers open() function can be called. You have to setup everything
_before_ you call register_netdev().

> +	self->is_ndev_registered = true;
> +	netif_carrier_off(self->ndev);
> +
> +	for (i = AQ_CFG_VECS_MAX; i--;)
> +		aq_nic_ndev_queue_stop(self, i);
> +




> +
> +static unsigned int aq_nic_map_skb_frag(struct aq_nic_s *self,
> +					struct sk_buff *skb,
> +					struct aq_ring_buff_s *dx)
> +{
> +	unsigned int ret = 0U;
> +	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
> +	unsigned int frag_count = 0U;
> +
> +	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);

Mapping can fail. You have to check the result.

> +	dx->len_pkt = skb->len;
> +	dx->is_sop = 1U;
> +	dx->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 =
> +			(ip_hdr(skb)->protocol == IPPROTO_TCP) ? 1U : 0U;
> +		dx->is_udp_cso =
> +			(ip_hdr(skb)->protocol == IPPROTO_UDP) ? 1U : 0U;
> +	}
> +
> +	for (; nr_frags--; ++frag_count) {
> +		unsigned int frag_len;
> +		dma_addr_t frag_pa;
> +		skb_frag_t *frag = &skb_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);

Same here, you have to check if mapping was successful.

> +
> +int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
> +__releases(&ring->lock)
> +__acquires(&ring->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 = 0;

Please use NETDEV_TX_OK instead of 0 as the return value for successful 
transmission.

> +	bool is_nic_in_bad_state;
> +	bool is_busy = false;

What is "is_busy" needed for?

> +	struct aq_ring_buff_s buffers[AQ_CFG_SKB_FRAGS_MAX];

You allocate quite large buffers on a very limited resource (the kernel 
stack) only to copy the data from the local buffers to the xmit buffer
via aq_ring_tx_append_buffs(). Why dont map the xmit buffers directly?

> +
> +	frags = skb_shinfo(skb)->nr_frags + 1;
> +
> +	ring = self->aq_ring_tx[AQ_NIC_TCVEC2RING(self, tc, vec)];
> +
> +	atomic_inc(&self->header.busy_count);
> +	is_busy = true;
> +
> +	if (frags > AQ_CFG_SKB_FRAGS_MAX) {
> +		dev_kfree_skb_any(skb);
> +		goto err_exit;
> +	}
> +
> +	is_nic_in_bad_state = aq_utils_obj_test(&self->header.flags,
> +						AQ_NIC_FLAGS_IS_NOT_TX_READY) ||
> +						(aq_ring_avail_dx(ring) <
> +						AQ_CFG_SKB_FRAGS_MAX);
> +
> +	if (is_nic_in_bad_state) {
> +		aq_nic_ndev_queue_stop(self, ring->idx);
> +		err = NETDEV_TX_BUSY;
> +		goto err_exit;
> +	}
> +
> +	do {
> +		if (spin_trylock(&ring->header.lock)) {
> +			frags = aq_nic_map_skb(self, skb, &buffers[0]);
> +
> +			aq_ring_tx_append_buffs(ring, &buffers[0], 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);
> +			}
> +			spin_unlock(&ring->header.lock);
> +
> +			if (err >= 0) {
> +				++ring->stats.tx.packets;
> +				ring->stats.tx.bytes += skb->len;
> +			}
> +			break;
> +		}
> +	} while (--trys);

AFAICS busy_count is only used in the timer callback. Why do they have 
to be synchronized?

> +
> +int aq_nic_stop(struct aq_nic_s *self)
> +{
> +	struct aq_vec_s *aq_vec = NULL;
> +	unsigned int i = 0U;
> +
> +	for (i = 0U, aq_vec = self->aq_vec[0];
> +		self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
> +		aq_nic_ndev_queue_stop(self, i);
> +
> +	del_timer_sync(&self->service_timer);

This is not sufficient. You also have to make sure that the timer 
callback does not restart the timer.

> +
> +int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg)
> +{
> +	int err = 0;
> +
> +	if (!netif_running(self->ndev)) {
> +		err = 0;
> +		goto err_exit;
> +	}
> +	rtnl_lock();
> +	if (pm_msg->event & PM_EVENT_SLEEP || pm_msg->event & PM_EVENT_FREEZE) {
> +		self->power_state = AQ_HW_POWER_STATE_D3;
> +		netif_device_detach(self->ndev);
> +		netif_tx_stop_all_queues(self->ndev);
> +
> +		err = aq_nic_stop(self);
> +		if (err < 0)
> +			goto err_exit;

rtnl_unlock() is missing.

> +
> +		aq_nic_deinit(self);
> +	} else {
> +		err = aq_nic_init(self);
> +		if (err < 0)
> +			goto err_exit;
> +
> +		err = aq_nic_start(self);
> +		if (err < 0)
> +			goto err_exit;
> +
> +		netif_device_attach(self->ndev);
> +		netif_tx_start_all_queues(self->ndev);
> +	}
> +	rtnl_unlock();
> +
> +err_exit:
> +	return err;
> +}


Regards,
Lino

^ permalink raw reply

* Re: [PATCH net-next v2 0/2] qed*: Add support for PTP
From: Richard Cochran @ 2017-01-29 15:09 UTC (permalink / raw)
  To: Sudarsana Kalluru; +Cc: davem, netdev, Yuval.Mintz
In-Reply-To: <1485674903-27689-1-git-send-email-Sudarsana.Kalluru@cavium.com>

On Sat, Jan 28, 2017 at 11:28:21PM -0800, Sudarsana Kalluru wrote:
> From: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
> 
> Hi David,
>     The patch series adds required changes for qed/qede drivers for
> supporting the IEEE Precision Time Protocol (PTP).
> 
> Changes from previous versions:
> -------------------------------
> v2: Use do_div for 64-bit divisions
> 
> 
> Please consider applying this series to "net-next".

Can we please, PLEASE put the PHC maintainer onto CC when posting new
PHC drivers?

Thanks,
Richard

^ permalink raw reply

* pull-request: wireless-drivers 2017-01-29
From: Kalle Valo @ 2017-01-29 14:49 UTC (permalink / raw)
  To: David Miller
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Hi Dave,

small but important fixes for 4.10. Hopefully is the last pull request
for 4.10.

Please let me know if there are any problems.

Kalle

The following changes since commit 60f59ce0278557f7896d5158ae6d12a4855a72cc:

  rtlwifi: rtl_usb: Fix missing entry in USB driver's private data (2016-12-30 15:38:13 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git tags/wireless-drivers-for-davem-2017-01-29

for you to fetch changes up to 2b1d530cb3157f828fcaadd259613f59db3c6d1c:

  MAINTAINERS: ath9k-devel is closed (2017-01-28 09:15:50 +0200)

----------------------------------------------------------------
wireless-drivers fixes for 4.10

Most important here are fixes to two iwlwifi crashes, but there's also
a firmware naming fix for iwlwifi and a revert of an older bcma patch.

----------------------------------------------------------------
Jens Axboe (1):
      iwlwifi: fix kernel crash when unregistering thermal zone

Johannes Berg (1):
      iwlwifi: mvm: avoid crash on restart w/o reserved queues

Jürg Billeter (1):
      iwlwifi: fix double hyphen in MODULE_FIRMWARE for 8000

Kalle Valo (2):
      Merge tag 'iwlwifi-for-kalle-2017-01-23' of git://git.kernel.org/.../iwlwifi/iwlwifi-fixes
      MAINTAINERS: ath9k-devel is closed

Rafał Miłecki (1):
      Revert "bcma: init serial console directly from ChipCommon code"

 MAINTAINERS                                   |  1 -
 drivers/bcma/bcma_private.h                   |  3 +++
 drivers/bcma/driver_chipcommon.c              | 11 +++--------
 drivers/bcma/driver_mips.c                    |  3 +++
 drivers/net/wireless/intel/iwlwifi/iwl-8000.c |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  |  7 ++++---
 drivers/net/wireless/intel/iwlwifi/mvm/tt.c   | 12 ++++++++----
 7 files changed, 22 insertions(+), 17 deletions(-)

^ permalink raw reply

* Re: A PMTU auto-discovery error for large SCTP packets
From: Marcelo Ricardo Leitner @ 2017-01-29 14:39 UTC (permalink / raw)
  To: YUAN Jia; +Cc: 'linux-sctp@vger.kernel.org', 'network dev'
In-Reply-To: <07B7943445653648AD9B4DBB916BB48F1C265220@cnshjmbx01>

On Wed, Jan 25, 2017 at 06:40:10AM +0000, YUAN Jia wrote:
...
> I think that ‘sctp_manip_pkt’ should also behave like this. Isn’t it?

I believe so, yes.
Will you send a patch?

Btw, your host did have a MTU bigger than 1500, right? I'm just curious
on why such big packet was generated in the first place.

  Marcelo

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox