* [PATCH 3/7] net: usb: asix88179_178a: add usbnet -> priv function
From: Ben Dooks @ 2018-10-12 9:16 UTC (permalink / raw)
To: davem, netdev
Cc: linux-usb, linux-kernel, linux-kernel, gregkh, bjorn,
steve.glendinning, Ben Dooks
In-Reply-To: <20181012091642.21294-1-ben.dooks@codethink.co.uk>
There are a number of places in the asix88179_178a driver where it gets the
private-data from the usbnet passed in. It would be sensible to have
one inline function to convert it and change all points in the driver
to use that.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
drivers/net/usb/ax88179_178a.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 9e8ad372f419..f4b64e7e7706 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -196,6 +196,11 @@ static const struct {
{7, 0xcc, 0x4c, 0x18, 8},
};
+static inline struct ax88179_data *usbnet_to_ax(struct usbnet *usb)
+{
+ return (struct ax88179_data *)usb->data;
+}
+
static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
u16 size, void *data, int in_pm)
{
@@ -678,7 +683,7 @@ ax88179_ethtool_set_eee(struct usbnet *dev, struct ethtool_eee *data)
static int ax88179_chk_eee(struct usbnet *dev)
{
struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
- struct ax88179_data *priv = (struct ax88179_data *)dev->data;
+ struct ax88179_data *priv = usbnet_to_ax(dev);
mii_ethtool_gset(&dev->mii, &ecmd);
@@ -781,7 +786,7 @@ static void ax88179_enable_eee(struct usbnet *dev)
static int ax88179_get_eee(struct net_device *net, struct ethtool_eee *edata)
{
struct usbnet *dev = netdev_priv(net);
- struct ax88179_data *priv = (struct ax88179_data *)dev->data;
+ struct ax88179_data *priv = usbnet_to_ax(dev);
edata->eee_enabled = priv->eee_enabled;
edata->eee_active = priv->eee_active;
@@ -792,7 +797,7 @@ static int ax88179_get_eee(struct net_device *net, struct ethtool_eee *edata)
static int ax88179_set_eee(struct net_device *net, struct ethtool_eee *edata)
{
struct usbnet *dev = netdev_priv(net);
- struct ax88179_data *priv = (struct ax88179_data *)dev->data;
+ struct ax88179_data *priv = usbnet_to_ax(dev);
int ret = -EOPNOTSUPP;
priv->eee_enabled = edata->eee_enabled;
@@ -841,7 +846,7 @@ static const struct ethtool_ops ax88179_ethtool_ops = {
static void ax88179_set_multicast(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct ax88179_data *data = (struct ax88179_data *)dev->data;
+ struct ax88179_data *data = usbnet_to_ax(dev);
u8 *m_filter = ((u8 *)dev->data) + 12;
data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE);
@@ -1228,7 +1233,7 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
u8 buf[5];
u16 *tmp16;
u8 *tmp;
- struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+ struct ax88179_data *ax179_data = usbnet_to_ax(dev);
struct ethtool_eee eee_data;
usbnet_get_endpoints(dev, intf);
@@ -1458,7 +1463,7 @@ ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
static int ax88179_link_reset(struct usbnet *dev)
{
- struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+ struct ax88179_data *ax179_data = usbnet_to_ax(dev);
u8 tmp[5], link_sts;
u16 mode, tmp16, delay = HZ / 10;
u32 tmp32 = 0x40000000;
@@ -1533,7 +1538,7 @@ static int ax88179_reset(struct usbnet *dev)
u8 buf[5];
u16 *tmp16;
u8 *tmp;
- struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+ struct ax88179_data *ax179_data = usbnet_to_ax(dev);
struct ethtool_eee eee_data;
tmp16 = (u16 *)buf;
--
2.19.1
^ permalink raw reply related
* [PATCH 2/7] net: asix: add usbnet -> priv function
From: Ben Dooks @ 2018-10-12 9:16 UTC (permalink / raw)
To: davem, netdev
Cc: linux-usb, linux-kernel, linux-kernel, gregkh, bjorn,
steve.glendinning, Ben Dooks
In-Reply-To: <20181012091642.21294-1-ben.dooks@codethink.co.uk>
There are a number of places in the asix driver where it gets the
private-data from the usbnet passed in. It would be sensible to have
one inline function to convert it and change all points in the driver
to use that.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
drivers/net/usb/asix.h | 5 +++++
drivers/net/usb/asix_common.c | 4 ++--
drivers/net/usb/asix_devices.c | 16 ++++++++--------
drivers/net/usb/ax88172a.c | 2 +-
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/net/usb/asix.h b/drivers/net/usb/asix.h
index 9a4171b90947..4bbb52669ac4 100644
--- a/drivers/net/usb/asix.h
+++ b/drivers/net/usb/asix.h
@@ -197,6 +197,11 @@ extern const struct driver_info ax88172a_info;
/* ASIX specific flags */
#define FLAG_EEPROM_MAC (1UL << 0) /* init device MAC from eeprom */
+static inline struct asix_data *usbnet_to_asix(struct usbnet *usb)
+{
+ return (struct asix_data *)&usb->data;
+}
+
int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
u16 size, void *data, int in_pm);
diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
index e95dd12edec4..1fd650faca5b 100644
--- a/drivers/net/usb/asix_common.c
+++ b/drivers/net/usb/asix_common.c
@@ -418,7 +418,7 @@ int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm)
void asix_set_multicast(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
u16 rx_ctl = AX_DEFAULT_RX_CTL;
if (net->flags & IFF_PROMISC) {
@@ -751,7 +751,7 @@ void asix_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
int asix_set_mac_address(struct net_device *net, void *p)
{
struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
struct sockaddr *addr = p;
if (netif_running(net))
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index b654f05b2ccd..8e387f06dccf 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -144,7 +144,7 @@ static const struct ethtool_ops ax88172_ethtool_ops = {
static void ax88172_set_multicast(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
u8 rx_ctl = 0x8c;
if (net->flags & IFF_PROMISC) {
@@ -332,7 +332,7 @@ static int ax88772_link_reset(struct usbnet *dev)
static int ax88772_reset(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
int ret;
/* Rewrite MAC address */
@@ -359,7 +359,7 @@ static int ax88772_reset(struct usbnet *dev)
static int ax88772_hw_reset(struct usbnet *dev, int in_pm)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
int ret, embd_phy;
u16 rx_ctl;
@@ -454,7 +454,7 @@ static int ax88772_hw_reset(struct usbnet *dev, int in_pm)
static int ax88772a_hw_reset(struct usbnet *dev, int in_pm)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
int ret, embd_phy;
u16 rx_ctl, phy14h, phy15h, phy16h;
u8 chipcode = 0;
@@ -795,7 +795,7 @@ static const struct ethtool_ops ax88178_ethtool_ops = {
static int marvell_phy_init(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
u16 reg;
netdev_dbg(dev->net, "marvell_phy_init()\n");
@@ -827,7 +827,7 @@ static int marvell_phy_init(struct usbnet *dev)
static int rtl8211cl_phy_init(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
netdev_dbg(dev->net, "rtl8211cl_phy_init()\n");
@@ -874,7 +874,7 @@ static int marvell_led_status(struct usbnet *dev, u16 speed)
static int ax88178_reset(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
int ret;
__le16 eeprom;
u8 status;
@@ -962,7 +962,7 @@ static int ax88178_link_reset(struct usbnet *dev)
{
u16 mode;
struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
u32 speed;
netdev_dbg(dev->net, "ax88178_link_reset()\n");
diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c
index 501576f53854..08f33c89f002 100644
--- a/drivers/net/usb/ax88172a.c
+++ b/drivers/net/usb/ax88172a.c
@@ -289,7 +289,7 @@ static void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf)
static int ax88172a_reset(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = usbnet_to_asix(dev);
struct ax88172a_private *priv = dev->driver_priv;
int ret;
u16 rx_ctl;
--
2.19.1
^ permalink raw reply related
* [PATCH 1/7] net: smsc75xx: add usbnet -> priv function
From: Ben Dooks @ 2018-10-12 9:16 UTC (permalink / raw)
To: davem, netdev
Cc: linux-usb, linux-kernel, linux-kernel, gregkh, bjorn,
steve.glendinning, Ben Dooks
In-Reply-To: <20181012091642.21294-1-ben.dooks@codethink.co.uk>
There are a number of places in the smsc75xx driver where it gets the
private-data from the usbnet passed in. It would be sensible to have
one inline function to convert it and change all points in the driver
to use that.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
drivers/net/usb/smsc75xx.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 05553d252446..6d12fcd9b4b0 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -73,6 +73,11 @@ struct smsc75xx_priv {
u8 suspend_flags;
};
+static inline struct smsc75xx_priv *usbnet_to_smsc(struct usbnet *dev)
+{
+ return (struct smsc75xx_priv *)dev->data[0];
+}
+
struct usb_context {
struct usb_ctrlrequest req;
struct usbnet *dev;
@@ -469,7 +474,7 @@ static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev)
static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr,
u32 length, u32 *buf)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
u32 dp_sel;
int i, ret;
@@ -553,7 +558,7 @@ static void smsc75xx_deferred_multicast_write(struct work_struct *param)
static void smsc75xx_set_multicast(struct net_device *netdev)
{
struct usbnet *dev = netdev_priv(netdev);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
unsigned long flags;
int i;
@@ -718,7 +723,7 @@ static void smsc75xx_ethtool_get_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
wolinfo->supported = SUPPORTED_WAKE;
wolinfo->wolopts = pdata->wolopts;
@@ -728,7 +733,7 @@ static int smsc75xx_ethtool_set_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
int ret;
pdata->wolopts = wolinfo->wolopts & SUPPORTED_WAKE;
@@ -945,7 +950,7 @@ static int smsc75xx_set_features(struct net_device *netdev,
netdev_features_t features)
{
struct usbnet *dev = netdev_priv(netdev);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
unsigned long flags;
int ret;
@@ -1051,7 +1056,7 @@ static int smsc75xx_phy_gig_workaround(struct usbnet *dev)
static int smsc75xx_reset(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
u32 buf;
int ret = 0, timeout;
@@ -1515,7 +1520,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
if (pdata) {
netif_dbg(dev, ifdown, dev->net, "free pdata\n");
kfree(pdata);
@@ -1571,7 +1576,7 @@ static int smsc75xx_write_wuff(struct usbnet *dev, int filter, u32 wuf_cfg,
static int smsc75xx_enter_suspend0(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
u32 val;
int ret;
@@ -1597,7 +1602,7 @@ static int smsc75xx_enter_suspend0(struct usbnet *dev)
static int smsc75xx_enter_suspend1(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
u32 val;
int ret;
@@ -1633,7 +1638,7 @@ static int smsc75xx_enter_suspend1(struct usbnet *dev)
static int smsc75xx_enter_suspend2(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
u32 val;
int ret;
@@ -1659,7 +1664,7 @@ static int smsc75xx_enter_suspend2(struct usbnet *dev)
static int smsc75xx_enter_suspend3(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
u32 val;
int ret;
@@ -1794,7 +1799,7 @@ static int smsc75xx_autosuspend(struct usbnet *dev, u32 link_up)
static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
u32 val, link_up;
int ret;
@@ -2095,7 +2100,7 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
static int smsc75xx_resume(struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = usbnet_to_smsc(dev);
u8 suspend_flags = pdata->suspend_flags;
int ret;
u32 val;
--
2.19.1
^ permalink raw reply related
* usbnet private-data accessor functions
From: Ben Dooks @ 2018-10-12 9:16 UTC (permalink / raw)
To: davem, netdev
Cc: linux-usb, linux-kernel, linux-kernel, gregkh, bjorn,
steve.glendinning
I have been looking at the usbnet drivers and the possibility of some
code cleanups. One of the things I've found is that changing the way
the drivers use the private data with the usbnet structure is often
hand-coded each time is needed.
An easy cleanp (and making it easier in the future to change the
access method) would be to add an inline conversion function to
each driver so that it is done in one place.
Future work would be to look at the usbnet.data and see if it could
be changed (such as moving to a union, allocation of the data after
the usbnet structure, or similar).
^ permalink raw reply
* [PATCH] netlink: replace __NLA_ENSURE implementation
From: Johannes Berg @ 2018-10-12 9:09 UTC (permalink / raw)
To: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
Cc: John Garry, Johannes Berg
From: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
John Garry reported that when we actually use the current
implementation of __NLA_ENSURE, he gets compiler warnings
from -Wvla since there's an array in there, and for some
reason the compiler cannot immediately prove that its size
is constant. It must eventually be able to prove it as we
can use this inside an initializer for a constant, but the
warning still shows up for him.
I haven't been able to reproduce the warning on gcc in any
case that actually should compile, though in the case that
a non-constant value is actually passed I do see both the
VLA warning as well as the non-constant initializer error.
This was with both gcc 7.3.1 (which John also reported to
be using) and 8.1.
However, since we already have BUILD_BUG_ON_ZERO() and I
just missed it when implementing this, just use it, which
avoids this whole issue because it uses the bitfield trick
to force compilation errors, rather than the array trick.
Reported-by: John Garry <john.garry-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Fixes: 3e48be05f3c7 ("netlink: add attribute range validation to policy")
Signed-off-by: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
include/net/netlink.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 589683091f16..094012174b6f 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -311,7 +311,7 @@ struct nla_policy {
#define NLA_POLICY_NESTED_ARRAY(maxattr, policy) \
{ .type = NLA_NESTED_ARRAY, .validation_data = policy, .len = maxattr }
-#define __NLA_ENSURE(condition) (sizeof(char[1 - 2*!(condition)]) - 1)
+#define __NLA_ENSURE(condition) BUILD_BUG_ON_ZERO(!(condition))
#define NLA_ENSURE_INT_TYPE(tp) \
(__NLA_ENSURE(tp == NLA_S8 || tp == NLA_U8 || \
tp == NLA_S16 || tp == NLA_U16 || \
--
2.14.4
^ permalink raw reply related
* [PATCH net-next] net: cdc_ncm: remove set but not used variable 'ctx'
From: YueHaibing @ 2018-10-12 1:49 UTC (permalink / raw)
To: Oliver Neukum, davem; +Cc: YueHaibing, linux-usb, netdev, kernel-janitors
Fixes gcc '-Wunused-but-set-variable' warning:
drivers/net/usb/cdc_ncm.c: In function 'cdc_ncm_status':
drivers/net/usb/cdc_ncm.c:1603:22: warning:
variable 'ctx' set but not used [-Wunused-but-set-variable]
struct cdc_ncm_ctx *ctx;
It not used any more after
commit fa83dbeee558 ("net: cdc_ncm: remove redundant "disconnected" flag")
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/usb/cdc_ncm.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 35a7d61..50c05d0f 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -1600,11 +1600,8 @@ int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
{
- struct cdc_ncm_ctx *ctx;
struct usb_cdc_notification *event;
- ctx = (struct cdc_ncm_ctx *)dev->data[0];
-
if (urb->actual_length < sizeof(*event))
return;
^ permalink raw reply related
* Re: [PATCH 6/8] usbnet: smsc95xx: fix memcpy for accessing rx-data
From: Sergei Shtylyov @ 2018-10-12 8:48 UTC (permalink / raw)
To: Ben Dooks, netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel
In-Reply-To: <20181012083405.19246-7-ben.dooks@codethink.co.uk>
Hello!
On 12.10.2018 11:34, Ben Dooks wrote:
> Change the RX code to use get_unaligned_le32() instead of the combo
> of memcpy and cpu_to_le32s(&var).
le32_to_cpus(), actually.
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
> drivers/net/usb/smsc95xx.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
> index 8ce190da8be0..03c3c02b569c 100644
> --- a/drivers/net/usb/smsc95xx.c
> +++ b/drivers/net/usb/smsc95xx.c
> @@ -618,9 +618,7 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
> return;
> }
>
> - memcpy(&intdata, urb->transfer_buffer, 4);
> - le32_to_cpus(&intdata);
> -
> + intdata = get_unaligned_le32(urb->transfer_buffer);
> netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata);
>
> if (intdata & INT_ENP_PHY_INT_)
> @@ -1922,8 +1920,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
> unsigned char *packet;
> u16 size;
>
> - memcpy(&header, skb->data, sizeof(header));
> - le32_to_cpus(&header);
> + header = get_unaligned_le32(skb->data);
> skb_pull(skb, 4 + NET_IP_ALIGN);
> packet = skb->data;
>
MBR, Sergei
^ permalink raw reply
* [PATCH 8/8] usbnet: smsc95xx: add rx_turbo attribute
From: Ben Dooks @ 2018-10-12 8:34 UTC (permalink / raw)
To: netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel, Ben Dooks
In-Reply-To: <20181012083405.19246-1-ben.dooks@codethink.co.uk>
Add attribute for the rx_turbo mode to allow run-time configuration of
this feature.
Note, this requires a restart of the device to take effect.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
drivers/net/usb/smsc95xx.c | 41 +++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 1eb0795ec90f..330c3cf5d6f6 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -73,6 +73,7 @@ struct smsc95xx_priv {
u8 features;
u8 suspend_flags;
u8 mdix_ctrl;
+ bool rx_turbo;
bool link_ok;
struct delayed_work carrier_check;
struct usbnet *dev;
@@ -1103,7 +1104,7 @@ static int smsc95xx_reset(struct usbnet *dev)
"Read Value from HW_CFG after writing HW_CFG_BIR_: 0x%08x\n",
read_buf);
- if (!turbo_mode) {
+ if (!pdata->rx_turbo) {
burst_cap = 0;
dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
} else if (dev->udev->speed == USB_SPEED_HIGH) {
@@ -1259,6 +1260,37 @@ static const struct net_device_ops smsc95xx_netdev_ops = {
.ndo_set_features = smsc95xx_set_features,
};
+static inline struct smsc95xx_priv *dev_to_priv(struct device *dev)
+{
+ struct usb_interface *ui = container_of(dev, struct usb_interface, dev);
+ return usbnet_to_smsc(usb_get_intfdata(ui));
+}
+
+/* Currently rx_turbo will not take effect until next close/open */
+static ssize_t rx_turbo_show(struct device *adev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct smsc95xx_priv *priv = dev_to_priv(adev);
+ return snprintf(buf, PAGE_SIZE, "%d", priv->rx_turbo);
+}
+
+static ssize_t rx_turbo_store(struct device *adev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct smsc95xx_priv *priv = dev_to_priv(adev);
+ bool res;
+
+ if (kstrtobool(buf, &res))
+ return -EINVAL;
+
+ priv->rx_turbo = res;
+ return count;
+}
+
+static DEVICE_ATTR_RW(rx_turbo);
+
static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
{
struct smsc95xx_priv *pdata = NULL;
@@ -1280,6 +1312,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
if (!pdata)
return -ENOMEM;
+ pdata->rx_turbo = turbo_mode;
spin_lock_init(&pdata->mac_cr_lock);
/* LAN95xx devices do not alter the computed checksum of 0 to 0xffff.
@@ -1328,6 +1361,11 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
INIT_DELAYED_WORK(&pdata->carrier_check, check_carrier);
schedule_delayed_work(&pdata->carrier_check, CARRIER_CHECK_DELAY);
+ ret = device_create_file(&dev->udev->dev, &dev_attr_rx_turbo);
+ if (ret)
+ netdev_warn(dev->net,
+ "failed to create rx_turbo attribute: %d\n", ret);
+
return 0;
}
@@ -1336,6 +1374,7 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
if (pdata) {
+ device_remove_file(&dev->udev->dev, &dev_attr_rx_turbo);
cancel_delayed_work(&pdata->carrier_check);
netif_dbg(dev, ifdown, dev->net, "free pdata\n");
kfree(pdata);
--
2.19.1
^ permalink raw reply related
* [PATCH 7/8] usbnet: smsc95xx: add usbnet -> priv function
From: Ben Dooks @ 2018-10-12 8:34 UTC (permalink / raw)
To: netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel, Ben Dooks
In-Reply-To: <20181012083405.19246-1-ben.dooks@codethink.co.uk>
There are a number of places in the smsc95xx driver where it gets the
private-data from the usbnet passed in. It would be sensible to have
one inline function to convert it and change all points in the driver
to use that.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
drivers/net/usb/smsc95xx.c | 47 +++++++++++++++++++++-----------------
1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 03c3c02b569c..1eb0795ec90f 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -78,6 +78,11 @@ struct smsc95xx_priv {
struct usbnet *dev;
};
+static inline struct smsc95xx_priv *usbnet_to_smsc(struct usbnet *dev)
+{
+ return (struct smsc95xx_priv *)dev->data[0];
+}
+
static bool turbo_mode = IS_ENABLED(CONFIG_USB_NET_SMSC95XX_TURBO);
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
@@ -467,7 +472,7 @@ static unsigned int smsc95xx_hash(char addr[ETH_ALEN])
static void smsc95xx_set_multicast(struct net_device *netdev)
{
struct usbnet *dev = netdev_priv(netdev);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
unsigned long flags;
int ret;
@@ -562,7 +567,7 @@ static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex,
static int smsc95xx_link_reset(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
struct mii_if_info *mii = &dev->mii;
struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
unsigned long flags;
@@ -630,7 +635,7 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
static void set_carrier(struct usbnet *dev, bool link)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
if (pdata->link_ok == link)
return;
@@ -759,7 +764,7 @@ static void smsc95xx_ethtool_get_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
wolinfo->supported = SUPPORTED_WAKE;
wolinfo->wolopts = pdata->wolopts;
@@ -769,7 +774,7 @@ static int smsc95xx_ethtool_set_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
int ret;
pdata->wolopts = wolinfo->wolopts & SUPPORTED_WAKE;
@@ -805,7 +810,7 @@ static int get_mdix_status(struct net_device *net)
static void set_mdix_status(struct net_device *net, __u8 mdix_ctrl)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
int buf;
if ((pdata->chip_id == ID_REV_CHIP_ID_9500A_) ||
@@ -854,7 +859,7 @@ static int smsc95xx_get_link_ksettings(struct net_device *net,
struct ethtool_link_ksettings *cmd)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
int retval;
retval = usbnet_get_link_ksettings(net, cmd);
@@ -869,7 +874,7 @@ static int smsc95xx_set_link_ksettings(struct net_device *net,
const struct ethtool_link_ksettings *cmd)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
int retval;
if (pdata->mdix_ctrl != cmd->base.eth_tp_mdix_ctrl)
@@ -951,7 +956,7 @@ static int smsc95xx_set_mac_address(struct usbnet *dev)
/* starts the TX path */
static int smsc95xx_start_tx_path(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
unsigned long flags;
int ret;
@@ -971,7 +976,7 @@ static int smsc95xx_start_tx_path(struct usbnet *dev)
/* Starts the Receive path */
static int smsc95xx_start_rx_path(struct usbnet *dev, int in_pm)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
unsigned long flags;
spin_lock_irqsave(&pdata->mac_cr_lock, flags);
@@ -1028,7 +1033,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
static int smsc95xx_reset(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
u32 read_buf, write_buf, burst_cap;
int ret = 0, timeout;
@@ -1271,7 +1276,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc95xx_priv),
GFP_KERNEL);
- pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ pdata = usbnet_to_smsc(dev);
if (!pdata)
return -ENOMEM;
@@ -1328,7 +1333,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
if (pdata) {
cancel_delayed_work(&pdata->carrier_check);
@@ -1388,7 +1393,7 @@ static int smsc95xx_link_ok_nopm(struct usbnet *dev)
static int smsc95xx_enter_suspend0(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
u32 val;
int ret;
@@ -1427,7 +1432,7 @@ static int smsc95xx_enter_suspend0(struct usbnet *dev)
static int smsc95xx_enter_suspend1(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
struct mii_if_info *mii = &dev->mii;
u32 val;
int ret;
@@ -1475,7 +1480,7 @@ static int smsc95xx_enter_suspend1(struct usbnet *dev)
static int smsc95xx_enter_suspend2(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
u32 val;
int ret;
@@ -1497,7 +1502,7 @@ static int smsc95xx_enter_suspend2(struct usbnet *dev)
static int smsc95xx_enter_suspend3(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
u32 val;
int ret;
@@ -1536,7 +1541,7 @@ static int smsc95xx_enter_suspend3(struct usbnet *dev)
static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
int ret;
if (!netif_running(dev->net)) {
@@ -1584,7 +1589,7 @@ static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up)
static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
u32 val, link_up;
int ret;
@@ -1848,7 +1853,7 @@ static int smsc95xx_resume(struct usb_interface *intf)
u32 val;
BUG_ON(!dev);
- pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ pdata = usbnet_to_smsc(dev);
suspend_flags = pdata->suspend_flags;
netdev_dbg(dev->net, "resume suspend_flags=0x%02x\n", suspend_flags);
@@ -2084,7 +2089,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
static int smsc95xx_manage_power(struct usbnet *dev, int on)
{
- struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct smsc95xx_priv *pdata = usbnet_to_smsc(dev);
dev->intf->needs_remote_wakeup = on;
--
2.19.1
^ permalink raw reply related
* [PATCH 6/8] usbnet: smsc95xx: fix memcpy for accessing rx-data
From: Ben Dooks @ 2018-10-12 8:34 UTC (permalink / raw)
To: netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel, Ben Dooks
In-Reply-To: <20181012083405.19246-1-ben.dooks@codethink.co.uk>
Change the RX code to use get_unaligned_le32() instead of the combo
of memcpy and cpu_to_le32s(&var).
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
drivers/net/usb/smsc95xx.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 8ce190da8be0..03c3c02b569c 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -618,9 +618,7 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
return;
}
- memcpy(&intdata, urb->transfer_buffer, 4);
- le32_to_cpus(&intdata);
-
+ intdata = get_unaligned_le32(urb->transfer_buffer);
netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata);
if (intdata & INT_ENP_PHY_INT_)
@@ -1922,8 +1920,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
unsigned char *packet;
u16 size;
- memcpy(&header, skb->data, sizeof(header));
- le32_to_cpus(&header);
+ header = get_unaligned_le32(skb->data);
skb_pull(skb, 4 + NET_IP_ALIGN);
packet = skb->data;
--
2.19.1
^ permalink raw reply related
* [PATCH 5/8] usbnet: smsc95xx: align tx-buffer to word
From: Ben Dooks @ 2018-10-12 8:34 UTC (permalink / raw)
To: netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel, Ben Dooks
In-Reply-To: <20181012083405.19246-1-ben.dooks@codethink.co.uk>
The tegra EHCI driver requires alignment of the buffer, so try and
make this better by pushing the buffer start back to an word
aligned address. At the worst this makes memcpy() easier as
it is word aligned, at best it makes sure the usb can directly
map the buffer.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
Changes since v1:
- Removed the module parameter
- Reworked the tx code to ensure retry if alignment changed
- Explicitly mention the EHCI in the tegra
- Deal with new simpler tx code
---
drivers/net/usb/Kconfig | 12 ++++++++++++
drivers/net/usb/smsc95xx.c | 22 +++++++++++++++++++---
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index c3ebc43a6582..1af6fb0cadb1 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -364,6 +364,18 @@ config USB_NET_SMSC95XX_TURBO
soft-irq load, thus making it useful to default the option
off for these.
+config USB_NET_SMSC95XX_TXALIGN
+ bool "Add bytes to align transmit buffers"
+ depends on USB_NET_SMSC95XX
+ default n
+ help
+ This option makes the tx buffers 32 bit aligned which might
+ help with systems that want tx data aligned to a 32 bit
+ boundary.
+
+ Using this option will mean there may be up to 3 bytes of
+ data per packet sent.
+
config USB_NET_GL620A
tristate "GeneSys GL620USB-A based cables"
depends on USB_USBNET
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 19e71fe15f6c..8ce190da8be0 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -2017,28 +2017,43 @@ static bool smsc95xx_can_tx_checksum(struct sk_buff *skb)
return skb->csum_offset < (len - (4 + 1));
}
+static inline u32 tx_align(struct sk_buff *skb)
+{
+#ifdef CONFIG_USB_NET_SMSC95XX_TXALIGN
+ return ((u32)skb->data) & 3;
+#else
+ return 0;
+#endif
+}
+
static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
struct sk_buff *skb, gfp_t flags)
{
bool csum = skb->ip_summed == CHECKSUM_PARTIAL;
int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
u32 tx_cmd_a, tx_cmd_b;
+ u32 align;
void *ptr;
/* We do not advertise SG, so skbs should be already linearized */
BUG_ON(skb_shinfo(skb)->nr_frags);
+retry_align:
+ align = tx_align(skb);
+
/* Make writable and expand header space by overhead if required */
- if (skb_cow_head(skb, overhead)) {
+ if (skb_cow_head(skb, overhead + align)) {
/* Must deallocate here as returning NULL to indicate error
* means the skb won't be deallocated in the caller.
*/
dev_kfree_skb_any(skb);
return NULL;
- }
+ } else if (tx_align(skb) != align)
+ goto retry_align;
tx_cmd_b = (u32)skb->len;
tx_cmd_a = tx_cmd_b | TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
+ tx_cmd_a |= align << 16;
if (csum) {
if (!smsc95xx_can_tx_checksum(skb)) {
@@ -2062,7 +2077,8 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
}
}
- ptr = skb_push(skb, 8);
+ /* TX command format is in section 5.4 of SMSC95XX datasbook */
+ ptr = skb_push(skb, 8 + align);
put_unaligned_le32(tx_cmd_a, ptr);
put_unaligned_le32(tx_cmd_b, ptr+4);
--
2.19.1
^ permalink raw reply related
* [PATCH 4/8] usbnet: smsc95xx: check for csum being in last four bytes
From: Ben Dooks @ 2018-10-12 8:34 UTC (permalink / raw)
To: netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel, Ben Dooks
In-Reply-To: <20181012083405.19246-1-ben.dooks@codethink.co.uk>
The manual states that the checksum cannot lie in the last DWORD of the
transmission, so add a basic check for this and fall back to software
checksumming the packet.
This only seems to trigger for ACK packets with no options or data to
return to the other end, and the use of the tx-alignment option makes
it more likely to happen.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
Fixes for v2:
- Fix spelling of check at Sergei's suggestion
- Move skb->len check into smsc95xx_can_tx_checksum()
- Change name of smsc95xx_can_checksum to explicitly say it is tx-csum
---
drivers/net/usb/smsc95xx.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 0c083d1b7f34..19e71fe15f6c 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -2000,6 +2000,23 @@ static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
return (high_16 << 16) | low_16;
}
+/* The TX CSUM won't work if the checksum lies in the last 4 bytes of the
+ * transmission. This is fairly unlikely, only seems to trigger with some
+ * short TCP ACK packets sent.
+ *
+ * Note, this calculation should probably check for the alignment of the
+ * data as well, but a straight check for csum being in the last four bytes
+ * of the packet should be ok for now.
+*/
+static bool smsc95xx_can_tx_checksum(struct sk_buff *skb)
+{
+ unsigned int len = skb->len - skb_checksum_start_offset(skb);
+
+ if (skb->len <= 45)
+ return false;
+ return skb->csum_offset < (len - (4 + 1));
+}
+
static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
struct sk_buff *skb, gfp_t flags)
{
@@ -2024,7 +2041,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
tx_cmd_a = tx_cmd_b | TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
if (csum) {
- if (skb->len <= 45) {
+ if (!smsc95xx_can_tx_checksum(skb)) {
/* workaround - hardware tx checksum does not work
* properly with extremely small packets */
long csstart = skb_checksum_start_offset(skb);
--
2.19.1
^ permalink raw reply related
* [PATCH 3/8] usbnet: smsc95xx: simplify tx_fixup code
From: Ben Dooks @ 2018-10-12 8:34 UTC (permalink / raw)
To: netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel, Ben Dooks
In-Reply-To: <20181012083405.19246-1-ben.dooks@codethink.co.uk>
The smsc95xx_tx_fixup is doing multiple calls to skb_push() to
put an 8-byte command header onto the packet. It would be easier
to do one skb_push() and then copy the data in once the push is
done.
We also make the code smaller by using proper unaligned puts for
the header. This merges in the CPU to LE32 conversion as well and
makes the whole sequence easier to understand hopefully.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
Since v1:
- Add alignment changes using put_unaligned_le32()
---
drivers/net/usb/smsc95xx.c | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index cb19aea139d3..0c083d1b7f34 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -2006,6 +2006,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
bool csum = skb->ip_summed == CHECKSUM_PARTIAL;
int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
u32 tx_cmd_a, tx_cmd_b;
+ void *ptr;
/* We do not advertise SG, so skbs should be already linearized */
BUG_ON(skb_shinfo(skb)->nr_frags);
@@ -2019,6 +2020,9 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
return NULL;
}
+ tx_cmd_b = (u32)skb->len;
+ tx_cmd_a = tx_cmd_b | TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
+
if (csum) {
if (skb->len <= 45) {
/* workaround - hardware tx checksum does not work
@@ -2032,24 +2036,18 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
csum = false;
} else {
u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
- skb_push(skb, 4);
- cpu_to_le32s(&csum_preamble);
- memcpy(skb->data, &csum_preamble, 4);
+ ptr = skb_push(skb, 4);
+ put_unaligned_le32(csum_preamble, ptr);
+
+ tx_cmd_a += 4;
+ tx_cmd_b += 4;
+ tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
}
}
- skb_push(skb, 4);
- tx_cmd_b = (u32)(skb->len - 4);
- if (csum)
- tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
- cpu_to_le32s(&tx_cmd_b);
- memcpy(skb->data, &tx_cmd_b, 4);
-
- skb_push(skb, 4);
- tx_cmd_a = (u32)(skb->len - 8) | TX_CMD_A_FIRST_SEG_ |
- TX_CMD_A_LAST_SEG_;
- cpu_to_le32s(&tx_cmd_a);
- memcpy(skb->data, &tx_cmd_a, 4);
+ ptr = skb_push(skb, 8);
+ put_unaligned_le32(tx_cmd_a, ptr);
+ put_unaligned_le32(tx_cmd_b, ptr+4);
return skb;
}
--
2.19.1
^ permalink raw reply related
* [PATCH 2/8] usbnet: smsc95xx: add kconfig for turbo mode
From: Ben Dooks @ 2018-10-12 8:33 UTC (permalink / raw)
To: netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel, Ben Dooks
In-Reply-To: <20181012083405.19246-1-ben.dooks@codethink.co.uk>
Add a configuration option for the default state of turbo mode
on the smsc95xx networking driver. Some systems it is better
to default this to off as it causes significant increases in
soft-irq load.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
drivers/net/usb/Kconfig | 13 +++++++++++++
drivers/net/usb/smsc95xx.c | 2 +-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 418b0904cecb..c3ebc43a6582 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -351,6 +351,19 @@ config USB_NET_SMSC95XX
This option adds support for SMSC LAN95XX based USB 2.0
10/100 Ethernet adapters.
+config USB_NET_SMSC95XX_TURBO
+ bool "Use turbo receive mode by default"
+ depends on USB_NET_SMSC95XX
+ default y
+ help
+ This options sets the default turbo mode settings for the
+ driver's receive path. These can also be altered by the
+ turbo_mode module parameter.
+
+ There are some systems where the turbo mode causes higher
+ soft-irq load, thus making it useful to default the option
+ off for these.
+
config USB_NET_GL620A
tristate "GeneSys GL620USB-A based cables"
depends on USB_USBNET
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 401ec9feb495..cb19aea139d3 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -78,7 +78,7 @@ struct smsc95xx_priv {
struct usbnet *dev;
};
-static bool turbo_mode = true;
+static bool turbo_mode = IS_ENABLED(CONFIG_USB_NET_SMSC95XX_TURBO);
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
--
2.19.1
^ permalink raw reply related
* [PATCH 1/8] usbnet: smsc95xx: fix rx packet alignment
From: Ben Dooks @ 2018-10-12 8:33 UTC (permalink / raw)
To: netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel, Ben Dooks
In-Reply-To: <20181012083405.19246-1-ben.dooks@codethink.co.uk>
The smsc95xx driver already takes into account the NET_IP_ALIGN
parameter when setting up the receive packet data, which means
we do not need to worry about aligning the packets in the usbnet
driver.
Adding the EVENT_NO_IP_ALIGN means that the IPv4 header is now
passed to the ip_rcv() routine with the start on an aligned address.
Tested on Raspberry Pi B3.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
drivers/net/usb/smsc95xx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 06b4d290784d..401ec9feb495 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1292,6 +1292,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->features |= NETIF_F_RXCSUM;
dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+ set_bit(EVENT_NO_IP_ALIGN, &dev->flags);
smsc95xx_init_mac_address(dev);
--
2.19.1
^ permalink raw reply related
* SMSC95XX updates for packet alignment and turbo mode (V2)
From: Ben Dooks @ 2018-10-12 8:33 UTC (permalink / raw)
To: netdev; +Cc: oneukum, davem, linux-usb, linux-kernel, linux-kernel
This is the new seris of SMSC95XX patches to deal with the issues we
found when working on this driver for a client. The new series has been
tested on an Raspberry Pi3 B.
Changes since v1:
- Change memcpy to use {get,put}_unaligned_le32() calls
- Merge tx fixups
- Added rx_turbo attribute
^ permalink raw reply
* Re: [GIT] Networking
From: Greg KH @ 2018-10-12 8:23 UTC (permalink / raw)
To: David Miller; +Cc: akpm, netdev, linux-kernel
In-Reply-To: <20181011.190615.78309421924776793.davem@davemloft.net>
On Thu, Oct 11, 2018 at 07:06:15PM -0700, David Miller wrote:
>
> 1) RXRPC receive path fixes from David Howells.
>
> 2) Re-export __skb_recv_udp(), from Jiri Kosina.
>
> 3) Fix refcounting in u32 classificer, from Al Viro.
>
> 4) Userspace netlink ABI fixes from Eugene Syromiatnikov.
>
> 5) Don't double iounmap on rmmod in ena driver, from Arthur
> Kiyanovski.
>
> 6) Fix devlink string attribute handling, we must pull a copy
> into a kernel buffer if the lifetime extends past the netlink
> request. From Moshe Shemesh.
>
> 7) Fix hangs in RDS, from Ka-Cheong Poon.
>
> 8) Fix recursive locking lockdep warnings in tipc, from Ying Xue.
>
> 9) Clear RX irq correctly in socionext, from Ilias Apalodimas.
>
> 10) bcm_sf2 fixes from Florian Fainelli.
>
> Please pull, thanks a lot!
>
> The following changes since commit c1d84a1b42ef70d8ae601df9cadedc7ed4f1beb1:
>
> Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (2018-10-06 02:11:30 -0700)
>
> are available in the Git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
>
Now merged, thanks.
greg k-h
^ permalink raw reply
* Re: [PATCH] virtio_net: enable tx after resuming from suspend
From: Jason Wang @ 2018-10-12 8:23 UTC (permalink / raw)
To: ake
Cc: Michael S. Tsirkin, David S. Miller, virtualization, netdev,
linux-kernel
In-Reply-To: <b294cbba-24a0-939d-98e8-d1483e3688a1@igel.co.jp>
On 2018年10月12日 12:30, ake wrote:
>
> On 2018年10月11日 22:06, Jason Wang wrote:
>>
>> On 2018年10月11日 18:22, ake wrote:
>>> On 2018年10月11日 18:44, Jason Wang wrote:
>>>> On 2018年10月11日 15:51, Ake Koomsin wrote:
>>>>> commit 713a98d90c5e ("virtio-net: serialize tx routine during reset")
>>>>> disabled the virtio tx before going to suspend to avoid a use after
>>>>> free.
>>>>> However, after resuming, it causes the virtio_net device to lose its
>>>>> network connectivity.
>>>>>
>>>>> To solve the issue, we need to enable tx after resuming.
>>>>>
>>>>> Fixes commit 713a98d90c5e ("virtio-net: serialize tx routine during
>>>>> reset")
>>>>> Signed-off-by: Ake Koomsin <ake@igel.co.jp>
>>>>> ---
>>>>> drivers/net/virtio_net.c | 1 +
>>>>> 1 file changed, 1 insertion(+)
>>>>>
>>>>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
>>>>> index dab504ec5e50..3453d80f5f81 100644
>>>>> --- a/drivers/net/virtio_net.c
>>>>> +++ b/drivers/net/virtio_net.c
>>>>> @@ -2256,6 +2256,7 @@ static int virtnet_restore_up(struct
>>>>> virtio_device *vdev)
>>>>> }
>>>>> netif_device_attach(vi->dev);
>>>>> + netif_start_queue(vi->dev);
>>>> I believe this is duplicated with netif_tx_wake_all_queues() in
>>>> netif_device_attach() above?
>>> Thank you for your review.
>>>
>>> If both netif_tx_wake_all_queues() and netif_start_queue() result in
>>> clearing __QUEUE_STATE_DRV_XOFF, then is it possible that some
>>> conditions in netif_device_attach() is not satisfied?
>> Yes, maybe. One case I can see now is when the device is down, in this
>> case netif_device_attach() won't try to wakeup the queue.
>>
>>> Without
>>> netif_start_queue(), the virtio_net device does not resume properly
>>> after waking up.
>> How do you trigger the issue? Just do suspend/resume?
> Yes, simply suspend and resume.
>
> Here is how I trigger the issue:
>
> 1) Start the Virtual Machine Manager GUI program.
> 2) Create a guest Linux OS. Make sure that the guest OS kernel is
> >= 4.12. Make sure that it uses virtio_net as its network device.
> In addition, make sure that the video adapter is VGA. Otherwise,
> waking up with the virtual power button does not work.
> 3) After installing the guest OS, log in, and test the network
> connectivity by ping the host machine.
> 4) Suspend. After this, the screen is blank.
> 5) Resume by hitting the virtual power button. The login screen
> appears again.
> 6) Log in again. The guest loses its network connection.
>
> In my test:
> Guest: Ubuntu 16.04/18.04 with kernel 4.15.0-36-generic
> Host: Ubuntu 16.04 with kernel 4.15.0-36-generic/4.4.0-137-generic
I can not reproduce this issue if virtio-net interface is up in guest
before the suspend. I'm using net-next.git and qemu master. But I do
reproduce when virtio-net interface is down in guest before suspend,
after resume, even if I make it up, the network is still lost.
I think the interface is up in your case, but please confirm this.
>
>>> Is it better to report this as a bug first?
>> Nope, you're very welcome to post patch directly.
>>
>>> If I am to do more
>>> investigation, what areas should I look into?
>> As you've figured out, you can start with why netif_tx_wake_all_queues()
>> were not executed?
>>
>> (Btw, does the issue disappear if you move netif_tx_disable() under the
>> check of netif_running() in virtnet_freeze_down()?)
> The issue disappears if I move netif_tx_disable() under the check of
> netif_running() in virtnet_freeze_down(). Moving netif_tx_disable()
> is probably better as its logic is consistent with
> netif_device_attach() implementation. If you are OK with this idea,
> I will submit another patch.
I think the it helps for the case when interface is down before suspend.
But it's still unclear why it help even if the interface is up
(netif_running() is true).
Please submit a patch but we should figure out why it help for a up
interface as well.
Thanks
>
>> Thanks
>>
>>> Best Regards
>>> Ake Koomsin
>>>
> Best Regards
^ permalink raw reply
* BUG: please report to dccp@vger.kernel.org => prev = 5, last = 5 at net/dccp/ccids/lib/packet_history.c:LINE/tfrc_rx_his
From: syzbot @ 2018-10-12 7:58 UTC (permalink / raw)
To: davem, dccp, garsilva, gerrit, linux-kernel, netdev,
syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: 771b65e89c8a Add linux-next specific files for 20181011
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=167d2376400000
kernel config: https://syzkaller.appspot.com/x/.config?x=45f1c06c4da0a925
dashboard link: https://syzkaller.appspot.com/bug?extid=e326127852f785c44347
compiler: gcc (GCC) 8.0.1 20180413 (experimental)
Unfortunately, I don't have any reproducer for this crash yet.
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+e326127852f785c44347@syzkaller.appspotmail.com
BUG: please report to dccp@vger.kernel.org => prev = 5, last = 5 at
net/dccp/ccids/lib/packet_history.c:425/tfrc_rx_hist_sample_rtt()
CPU: 1 PID: 16 Comm: ksoftirqd/1 Not tainted 4.19.0-rc7-next-20181011+ #92
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x244/0x3ab lib/dump_stack.c:113
tfrc_rx_hist_sample_rtt.cold.3+0x54/0x5c
net/dccp/ccids/lib/packet_history.c:422
ccid3_hc_rx_packet_recv+0x5c4/0xeb0 net/dccp/ccids/ccid3.c:767
ccid_hc_rx_packet_recv net/dccp/ccid.h:185 [inline]
dccp_deliver_input_to_ccids+0xf0/0x280 net/dccp/input.c:180
dccp_rcv_established+0x87/0xb0 net/dccp/input.c:378
dccp_v4_do_rcv+0x153/0x180 net/dccp/ipv4.c:656
sk_backlog_rcv include/net/sock.h:932 [inline]
__sk_receive_skb+0x3e0/0xeb0 net/core/sock.c:473
binder: send failed reply for transaction 41 to 27388:27389
dccp_v4_rcv+0x10f9/0x1f58 net/dccp/ipv4.c:877
ip_local_deliver_finish+0x2e9/0xda0 net/ipv4/ip_input.c:215
NF_HOOK include/linux/netfilter.h:289 [inline]
ip_local_deliver+0x1e4/0x740 net/ipv4/ip_input.c:256
dst_input include/net/dst.h:450 [inline]
ip_rcv_finish+0x1f9/0x300 net/ipv4/ip_input.c:415
NF_HOOK include/linux/netfilter.h:289 [inline]
ip_rcv+0xe8/0x600 net/ipv4/ip_input.c:524
__netif_receive_skb_one_core+0x14d/0x200 net/core/dev.c:4908
__netif_receive_skb+0x27/0x1e0 net/core/dev.c:5018
process_backlog+0x24e/0x7a0 net/core/dev.c:5822
napi_poll net/core/dev.c:6242 [inline]
net_rx_action+0x7fa/0x19b0 net/core/dev.c:6308
__do_softirq+0x30d/0xb26 kernel/softirq.c:292
run_ksoftirqd+0x5e/0x100 kernel/softirq.c:654
smpboot_thread_fn+0x68b/0xa00 kernel/smpboot.c:164
kthread+0x35a/0x440 kernel/kthread.c:246
ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352
dccp_close: ABORT with 52224 bytes unread
binder: send failed reply for transaction 43 to 27399:27404
dccp_close: ABORT with 3584 bytes unread
binder: send failed reply for transaction 45 to 27417:27418
binder: send failed reply for transaction 47 to 27424:27425
dccp_close: ABORT with 105984 bytes unread
dccp_close: ABORT with 105984 bytes unread
dccp_close: ABORT with 105984 bytes unread
nf_conntrack: default automatic helper assignment has been turned off for
security reasons and CT-based firewall rule not found. Use the iptables CT
target to attach helpers instead.
Dead loop on virtual device ip6_vti0, fix it urgently!
Dead loop on virtual device ip6_vti0, fix it urgently!
Dead loop on virtual device ip6_vti0, fix it urgently!
Dead loop on virtual device ip6_vti0, fix it urgently!
Dead loop on virtual device ip6_vti0, fix it urgently!
Dead loop on virtual device ip6_vti0, fix it urgently!
IPVS: sync thread started: state = BACKUP, mcast_ifn = team_slave_0, syncid
= 0, id = 0
Dead loop on virtual device ip6_vti0, fix it urgently!
IPVS: sync thread started: state = BACKUP, mcast_ifn = team_slave_0, syncid
= 0, id = 0
IPVS: ftp: loaded support on port[0] = 21
\x01: renamed from bpq0
IPVS: ftp: loaded support on port[0] = 21
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#bug-status-tracking for how to communicate with
syzbot.
^ permalink raw reply
* Re: [PATCH bpf-next v2 3/7] bpf: add MAP_LOOKUP_AND_DELETE_ELEM syscall
From: Alexei Starovoitov @ 2018-10-11 23:51 UTC (permalink / raw)
To: Mauricio Vasquez
Cc: Song Liu, Alexei Starovoitov, Daniel Borkmann, Networking
In-Reply-To: <44cde629-becb-09ee-1689-c82d87474367@polito.it>
On Wed, Oct 10, 2018 at 05:50:01PM -0500, Mauricio Vasquez wrote:
> > > Does it make sense to you?
> > I reread the other patch, and found it does NOT use the following logic for
> > queue and stack:
> >
> > rcu_read_lock();
> > ptr = map->ops->map_lookup_and_delete_elem(map, key);
> > if (ptr)
> > memcpy(value, ptr, value_size);
> >
> > I guess this part is not used at all? Can we just remove it?
> >
> > Thanks,
> > Song
>
> This is the base code for map_lookup_and_delete support, it is not used in
> queue/stack maps.
>
> I think we can leave it there, so when somebody implements lookup_and_delete
> for other maps doesn't have to care about implementing also this.
The code looks useful to me, but I also agree with Song. And in the kernel
we don't typically add 'almost dead code'.
May be provide an implementation of the lookup_and_delete for hash map
so it's actually used ?
imo it would be a useful feature to have for hash map and will clarify
the intent of it for all other maps and for stack/queue in particular.
^ permalink raw reply
* Re: [PATCH net-next] hv_netvsc: fix vf serial matching with pci slot info
From: Greg KH @ 2018-10-12 6:36 UTC (permalink / raw)
To: haiyangz; +Cc: davem, netdev, olaf, sthemmin, linux-kernel, devel, vkuznets
In-Reply-To: <20181011201434.30737-1-haiyangz@linuxonhyperv.com>
On Thu, Oct 11, 2018 at 08:14:34PM +0000, Haiyang Zhang wrote:
> From: Haiyang Zhang <haiyangz@microsoft.com>
>
> The VF device's serial number is saved as a string in PCI slot's
> kobj name, not the slot->number. This patch corrects the netvsc
> driver, so the VF device can be successfully paired with synthetic
> NIC.
>
> Fixes: 00d7ddba1143 ("hv_netvsc: pair VF based on serial number")
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
> drivers/net/hyperv/netvsc_drv.c | 15 +++++++++++----
> 1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> index 9bcaf204a7d4..8121ce34a39f 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -2030,14 +2030,15 @@ static void netvsc_vf_setup(struct work_struct *w)
> rtnl_unlock();
> }
>
> -/* Find netvsc by VMBus serial number.
> - * The PCI hyperv controller records the serial number as the slot.
> +/* Find netvsc by VF serial number.
> + * The PCI hyperv controller records the serial number as the slot kobj name.
> */
> static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
> {
> struct device *parent = vf_netdev->dev.parent;
> struct net_device_context *ndev_ctx;
> struct pci_dev *pdev;
> + u32 serial;
>
> if (!parent || !dev_is_pci(parent))
> return NULL; /* not a PCI device */
> @@ -2048,16 +2049,22 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
> return NULL;
> }
>
> + if (kstrtou32(pdev->slot->kobj.name, 10, &serial)) {
kobject_name()?
And that feels _very_ fragile to me. This is now an api that you are
guaranteeing will never change?
Good luck with that!
greg k-h
^ permalink raw reply
* [PATCH net-next v3 1/2] net/ncsi: Add NCSI Broadcom OEM command
From: Vijay Khemka @ 2018-10-11 23:05 UTC (permalink / raw)
To: Samuel Mendoza-Jonas, David S. Miller, netdev, linux-kernel
Cc: vijaykhemka, openbmc @ lists . ozlabs . org, Justin.Lee1, joel,
linux-aspeed
This patch adds OEM Broadcom commands and response handling. It also
defines OEM Get MAC Address handler to get and configure the device.
ncsi_oem_gma_handler_bcm: This handler send NCSI broadcom command for
getting mac address.
ncsi_rsp_handler_oem_bcm: This handles response received for all
broadcom OEM commands.
ncsi_rsp_handler_oem_bcm_gma: This handles get mac address response and
set it to device.
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
---
net/ncsi/Kconfig | 6 ++++
net/ncsi/internal.h | 8 +++++
net/ncsi/ncsi-manage.c | 70 ++++++++++++++++++++++++++++++++++++++++++
net/ncsi/ncsi-pkt.h | 8 +++++
net/ncsi/ncsi-rsp.c | 40 +++++++++++++++++++++++-
5 files changed, 131 insertions(+), 1 deletion(-)
diff --git a/net/ncsi/Kconfig b/net/ncsi/Kconfig
index 08a8a6031fd7..7f2b46108a24 100644
--- a/net/ncsi/Kconfig
+++ b/net/ncsi/Kconfig
@@ -10,3 +10,9 @@ config NET_NCSI
support. Enable this only if your system connects to a network
device via NCSI and the ethernet driver you're using supports
the protocol explicitly.
+config NCSI_OEM_CMD_GET_MAC
+ bool "Get NCSI OEM MAC Address"
+ depends on NET_NCSI
+ ---help---
+ This allows to get MAC address from NCSI firmware and set them back to
+ controller.
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
index 3d0a33b874f5..45883b32790e 100644
--- a/net/ncsi/internal.h
+++ b/net/ncsi/internal.h
@@ -71,6 +71,13 @@ enum {
/* OEM Vendor Manufacture ID */
#define NCSI_OEM_MFR_MLX_ID 0x8119
#define NCSI_OEM_MFR_BCM_ID 0x113d
+/* Broadcom specific OEM Command */
+#define NCSI_OEM_BCM_CMD_GMA 0x01 /* CMD ID for Get MAC */
+/* OEM Command payload lengths*/
+#define NCSI_OEM_BCM_CMD_GMA_LEN 12
+/* Mac address offset in OEM response */
+#define BCM_MAC_ADDR_OFFSET 28
+
struct ncsi_channel_version {
u32 version; /* Supported BCD encoded NCSI version */
@@ -240,6 +247,7 @@ enum {
ncsi_dev_state_probe_dp,
ncsi_dev_state_config_sp = 0x0301,
ncsi_dev_state_config_cis,
+ ncsi_dev_state_config_oem_gma,
ncsi_dev_state_config_clear_vids,
ncsi_dev_state_config_svf,
ncsi_dev_state_config_ev,
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index 091284760d21..75504ccd1b95 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -635,6 +635,39 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
return 0;
}
+#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
+
+/* NCSI OEM Command APIs */
+static void ncsi_oem_gma_handler_bcm(struct ncsi_cmd_arg *nca)
+{
+ int ret = 0;
+ unsigned char data[NCSI_OEM_BCM_CMD_GMA_LEN];
+
+ nca->payload = NCSI_OEM_BCM_CMD_GMA_LEN;
+
+ memset(data, 0, NCSI_OEM_BCM_CMD_GMA_LEN);
+ *(unsigned int *)data = ntohl(NCSI_OEM_MFR_BCM_ID);
+ data[5] = NCSI_OEM_BCM_CMD_GMA;
+
+ nca->data = data;
+
+ ret = ncsi_xmit_cmd(nca);
+ if (ret)
+ netdev_err(nca->ndp->ndev.dev,
+ "NCSI: Failed to transmit cmd 0x%x during configure\n",
+ nca->type);
+}
+
+/* OEM Command handlers initialization */
+static struct ncsi_oem_gma_handler {
+ unsigned int mfr_id;
+ void (*handler)(struct ncsi_cmd_arg *nca);
+} ncsi_oem_gma_handlers[] = {
+ { NCSI_OEM_MFR_BCM_ID, ncsi_oem_gma_handler_bcm }
+};
+
+#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */
+
static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
{
struct ncsi_dev *nd = &ndp->ndev;
@@ -685,6 +718,43 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
goto error;
}
+#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
+ nd->state = ncsi_dev_state_config_oem_gma;
+ break;
+ case ncsi_dev_state_config_oem_gma:
+ nca.type = NCSI_PKT_CMD_OEM;
+ nca.package = np->id;
+ nca.channel = nc->id;
+ ndp->pending_req_num = 1;
+
+ /* Check for manufacturer id and Find the handler */
+ struct ncsi_oem_gma_handler *nch = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ncsi_oem_gma_handlers); i++) {
+ if (ncsi_oem_gma_handlers[i].mfr_id ==
+ nc->version.mf_id) {
+ if (ncsi_oem_gma_handlers[i].handler)
+ nch = &ncsi_oem_gma_handlers[i];
+ else
+ nch = NULL;
+
+ break;
+ }
+ }
+
+ if (!nch) {
+ netdev_err(ndp->ndev.dev, "No handler available for GMA with MFR-ID (0x%x)\n",
+ nc->version.mf_id);
+ nd->state = ncsi_dev_state_config_clear_vids;
+ schedule_work(&ndp->work);
+ break;
+ }
+
+ /* Get Mac address from NCSI device */
+ nch->handler(&nca);
+#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */
+
nd->state = ncsi_dev_state_config_clear_vids;
break;
case ncsi_dev_state_config_clear_vids:
diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h
index 0f2087c8d42a..4d3f06be38bd 100644
--- a/net/ncsi/ncsi-pkt.h
+++ b/net/ncsi/ncsi-pkt.h
@@ -165,6 +165,14 @@ struct ncsi_rsp_oem_pkt {
unsigned char data[]; /* Payload data */
};
+/* Broadcom Response Data */
+struct ncsi_rsp_oem_bcm_pkt {
+ unsigned char ver; /* Payload Version */
+ unsigned char type; /* OEM Command type */
+ __be16 len; /* Payload Length */
+ unsigned char data[]; /* Cmd specific Data */
+};
+
/* Get Link Status */
struct ncsi_rsp_gls_pkt {
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
index d66b34749027..31672e967db2 100644
--- a/net/ncsi/ncsi-rsp.c
+++ b/net/ncsi/ncsi-rsp.c
@@ -596,12 +596,50 @@ static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
return 0;
}
+/* Response handler for Broadcom command Get Mac Address */
+static int ncsi_rsp_handler_oem_bcm_gma(struct ncsi_request *nr)
+{
+ struct ncsi_rsp_oem_pkt *rsp;
+ struct ncsi_dev_priv *ndp = nr->ndp;
+ struct net_device *ndev = ndp->ndev.dev;
+ int ret = 0;
+ const struct net_device_ops *ops = ndev->netdev_ops;
+ struct sockaddr saddr;
+
+ /* Get the response header */
+ rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
+
+ saddr.sa_family = ndev->type;
+ ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+ memcpy(saddr.sa_data, &rsp->data[BCM_MAC_ADDR_OFFSET], ETH_ALEN);
+ ret = ops->ndo_set_mac_address(ndev, &saddr);
+ if (ret < 0)
+ netdev_warn(ndev, "NCSI: Writing mac address to device failed\n");
+
+ return ret;
+}
+
+/* Response handler for Broadcom card */
+static int ncsi_rsp_handler_oem_bcm(struct ncsi_request *nr)
+{
+ struct ncsi_rsp_oem_pkt *rsp;
+ struct ncsi_rsp_oem_bcm_pkt *bcm;
+
+ /* Get the response header */
+ rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
+ bcm = (struct ncsi_rsp_oem_bcm_pkt *)(rsp->data);
+
+ if (bcm->type == NCSI_OEM_BCM_CMD_GMA)
+ return ncsi_rsp_handler_oem_bcm_gma(nr);
+ return 0;
+}
+
static struct ncsi_rsp_oem_handler {
unsigned int mfr_id;
int (*handler)(struct ncsi_request *nr);
} ncsi_rsp_oem_handlers[] = {
{ NCSI_OEM_MFR_MLX_ID, NULL },
- { NCSI_OEM_MFR_BCM_ID, NULL }
+ { NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm }
};
/* Response handler for OEM command */
--
2.17.1
^ permalink raw reply related
* RE: [PATCH net-next] hv_netvsc: fix vf serial matching with pci slot info
From: Vitaly Kuznetsov @ 2018-10-12 6:27 UTC (permalink / raw)
To: Haiyang Zhang
Cc: davem@davemloft.net, netdev@vger.kernel.org, KY Srinivasan,
Stephen Hemminger, olaf@aepfle.de, devel@linuxdriverproject.org,
linux-kernel@vger.kernel.org
In-Reply-To: <MWHPR21MB0176EB148DC772F9DC5845D2CAE10@MWHPR21MB0176.namprd21.prod.outlook.com>
Haiyang Zhang <haiyangz@microsoft.com> writes:
>> -----Original Message-----
>> From: Haiyang Zhang <haiyangz@linuxonhyperv.com>
>> Sent: Thursday, October 11, 2018 4:15 PM
>> To: davem@davemloft.net; netdev@vger.kernel.org
>> Cc: Haiyang Zhang <haiyangz@microsoft.com>; KY Srinivasan
>> <kys@microsoft.com>; Stephen Hemminger <sthemmin@microsoft.com>;
>> olaf@aepfle.de; vkuznets <vkuznets@redhat.com>;
>> devel@linuxdriverproject.org; linux-kernel@vger.kernel.org
>> Subject: [PATCH net-next] hv_netvsc: fix vf serial matching with pci slot info
>>
>> From: Haiyang Zhang <haiyangz@microsoft.com>
>>
>> The VF device's serial number is saved as a string in PCI slot's kobj name, not
>> the slot->number. This patch corrects the netvsc driver, so the VF device can be
>> successfully paired with synthetic NIC.
>>
>> Fixes: 00d7ddba1143 ("hv_netvsc: pair VF based on serial number")
>> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
>
> Thanks Stephen for the reminder -- I added the "reported-by" here:
>
> Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Thanks)
The difference in the hack I sent to Stephen was that instead of using
kstrtou32() and checking the return value I opted for snprintf() and
doing strncmp().
--
Vitaly
^ permalink raw reply
* Re: [PATCH bpf-next 3/8] bpf, sockmap: convert to generic sk_msg interface
From: Alexei Starovoitov @ 2018-10-11 22:57 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: john.fastabend, davejwatson, netdev
In-Reply-To: <20181011004547.16662-4-daniel@iogearbox.net>
On Thu, Oct 11, 2018 at 02:45:42AM +0200, Daniel Borkmann wrote:
> Add a generic sk_msg layer, and convert current sockmap and later
> kTLS over to make use of it. While sk_buff handles network packet
> representation from netdevice up to socket, sk_msg handles data
> representation from application to socket layer.
>
> This means that sk_msg framework spans across ULP users in the
> kernel, and enables features such as introspection or filtering
> of data with the help of BPF programs that operate on this data
> structure.
>
> Latter becomes in particular useful for kTLS where data encryption
> is deferred into the kernel, and as such enabling the kernel to
> perform L7 introspection and policy based on BPF for TLS connections
> where the record is being encrypted after BPF has run and came to
> a verdict. In order to get there, first step is to transform open
> coding of scatter-gather list handling into a common core framework
> that subsystems use.
>
> Joint work with John.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Signed-off-by: John Fastabend <john.fastabend@gmail.com>
> ---
> include/linux/bpf.h | 33 +-
> include/linux/bpf_types.h | 2 +-
> include/linux/filter.h | 21 -
> include/linux/skmsg.h | 371 +++++++
> include/net/tcp.h | 27 +
> kernel/bpf/Makefile | 5 -
> kernel/bpf/core.c | 2 -
> kernel/bpf/sockmap.c | 2610 ---------------------------------------------
> kernel/bpf/syscall.c | 6 +-
> net/Kconfig | 11 +
> net/core/Makefile | 2 +
> net/core/filter.c | 270 ++---
> net/core/skmsg.c | 763 +++++++++++++
> net/core/sock_map.c | 1002 +++++++++++++++++
> net/ipv4/Makefile | 1 +
> net/ipv4/tcp_bpf.c | 655 ++++++++++++
> net/strparser/Kconfig | 4 +-
> 17 files changed, 2925 insertions(+), 2860 deletions(-)
> +void sk_msg_trim(struct sock *sk, struct sk_msg *msg, int len)
> +{
> + int trim = msg->sg.size - len;
> + u32 i = msg->sg.end;
> +
> + if (trim <= 0) {
> + WARN_ON(trim < 0);
> + return;
> + }
> +
> + sk_msg_iter_var_prev(i);
> + msg->sg.size = len;
> + while (msg->sg.data[i].length &&
> + trim >= msg->sg.data[i].length) {
> + trim -= msg->sg.data[i].length;
> + sk_msg_free_elem(sk, msg, i, true);
> + sk_msg_iter_var_prev(i);
> + if (!trim)
> + goto out;
> + }
> +
> + msg->sg.data[i].length -= trim;
> + sk_mem_uncharge(sk, trim);
> +out:
> + /* If we trim data before curr pointer update copybreak and current
> + * so that any future copy operations start at new copy location.
> + * However trimed data that has not yet been used in a copy op
> + * does not require an update.
> + */
> + if (msg->sg.curr >= i) {
> + msg->sg.curr = i;//msg->sg.end;
is this a leftover of some debugging ?
I think such giant patchset is impossible to review in reasonable
amount of time. I guess you've considered splitting it, but
couldn't find a way to do so ?
May be expand the commit log a bit more to explain not only _why_
(which is typical requiremnt), but _how_ the patchset is doing it?
Overall sk_msg generalization looks great to me. Especially
considering how it's used in the next patches,
but details are scary. sockmap was plagued with bugs that
syzbot found. Are we changing it a lot again or it's mainly
copy-paste/split into different files plus rename?
I'm willing to take a leap of faith and merge it, but would
love if commit log could make it easier to see what is going on.
^ permalink raw reply
* Re: [PATCH net 0/2] net: dsa: bcm_sf2: Couple of fixes
From: David Miller @ 2018-10-11 22:20 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev, andrew, vivien.didelot
In-Reply-To: <05eb558e-b20c-fab0-e111-f73948069e5a@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 11 Oct 2018 15:02:54 -0700
> On 10/10/2018 10:53 PM, David Miller wrote:
>> From: Florian Fainelli <f.fainelli@gmail.com>
>> Date: Tue, 9 Oct 2018 16:48:56 -0700
>>
>>> Here are two fixes for the bcm_sf2 driver that were found during
>>> testing unbind and analysing another issue during system
>>> suspend/resume.
>>
>> Series applied and queued up for -stable, thanks.
>
> Did you push that series yet?
>
> git pull
> remote: Counting objects: 171, done.
> remote: Compressing objects: 100% (71/71), done.
> remote: Total 171 (delta 144), reused 118 (delta 100)
> Receiving objects: 100% (171/171), 32.80 KiB | 16.40 MiB/s, done.
> Resolving deltas: 100% (144/144), completed with 61 local objects.
> From https://git.kernel.org/pub/scm/linux/kernel/git/davem/net
> 52b5d6f5dcf0..052858663db3 master -> davem-net/master
>
> git rebase net/master sf2-fixes
> First, rewinding head to replay your work on top of it...
> Applying: net: dsa: bcm_sf2: Fix unbind ordering
> Applying: net: dsa: bcm_sf2: Call setup during switch resume
I applied them to net-next, sorry about that.
I'll add them to 'net' too.
Done.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox