2019-05-27 09:55:01 +03:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2016-07-19 04:54:17 +03:00
|
|
|
/*
|
|
|
|
* Copyright Gavin Shan, IBM Corporation 2016.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/etherdevice.h>
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
#include <linux/skbuff.h>
|
|
|
|
|
|
|
|
#include <net/ncsi.h>
|
|
|
|
#include <net/net_namespace.h>
|
|
|
|
#include <net/sock.h>
|
2018-10-11 21:07:37 +03:00
|
|
|
#include <net/genetlink.h>
|
2016-07-19 04:54:17 +03:00
|
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
#include "ncsi-pkt.h"
|
|
|
|
|
|
|
|
u32 ncsi_calculate_checksum(unsigned char *data, int len)
|
|
|
|
{
|
|
|
|
u32 checksum = 0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i += 2)
|
|
|
|
checksum += (((u32)data[i] << 8) | data[i + 1]);
|
|
|
|
|
|
|
|
checksum = (~checksum + 1);
|
|
|
|
return checksum;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This function should be called after the data area has been
|
|
|
|
* populated completely.
|
|
|
|
*/
|
|
|
|
static void ncsi_cmd_build_header(struct ncsi_pkt_hdr *h,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
u32 checksum;
|
|
|
|
__be32 *pchecksum;
|
|
|
|
|
|
|
|
h->mc_id = 0;
|
|
|
|
h->revision = NCSI_PKT_REVISION;
|
|
|
|
h->reserved = 0;
|
|
|
|
h->id = nca->id;
|
|
|
|
h->type = nca->type;
|
|
|
|
h->channel = NCSI_TO_CHANNEL(nca->package,
|
|
|
|
nca->channel);
|
|
|
|
h->length = htons(nca->payload);
|
|
|
|
h->reserved1[0] = 0;
|
|
|
|
h->reserved1[1] = 0;
|
|
|
|
|
|
|
|
/* Fill with calculated checksum */
|
|
|
|
checksum = ncsi_calculate_checksum((unsigned char *)h,
|
|
|
|
sizeof(*h) + nca->payload);
|
|
|
|
pchecksum = (__be32 *)((void *)h + sizeof(struct ncsi_pkt_hdr) +
|
2019-08-20 03:24:02 +03:00
|
|
|
ALIGN(nca->payload, 4));
|
2016-07-19 04:54:17 +03:00
|
|
|
*pchecksum = htonl(checksum);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_default(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_sp(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_sp_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
cmd->hw_arbitration = nca->bytes[0];
|
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_dc(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_dc_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
cmd->ald = nca->bytes[0];
|
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_rc(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_rc_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_ae(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_ae_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
cmd->mc_id = nca->bytes[0];
|
|
|
|
cmd->mode = htonl(nca->dwords[1]);
|
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_sl(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_sl_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
cmd->mode = htonl(nca->dwords[0]);
|
|
|
|
cmd->oem_mode = htonl(nca->dwords[1]);
|
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_svf(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_svf_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2017-08-28 09:18:41 +03:00
|
|
|
cmd->vlan = htons(nca->words[1]);
|
|
|
|
cmd->index = nca->bytes[6];
|
|
|
|
cmd->enable = nca->bytes[7];
|
2016-07-19 04:54:17 +03:00
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_ev(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_ev_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2017-08-28 09:18:41 +03:00
|
|
|
cmd->mode = nca->bytes[3];
|
2016-07-19 04:54:17 +03:00
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_sma(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_sma_pkt *cmd;
|
|
|
|
int i;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
cmd->mac[i] = nca->bytes[i];
|
|
|
|
cmd->index = nca->bytes[6];
|
|
|
|
cmd->at_e = nca->bytes[7];
|
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_ebf(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_ebf_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
cmd->mode = htonl(nca->dwords[0]);
|
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_egmf(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_egmf_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
cmd->mode = htonl(nca->dwords[0]);
|
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ncsi_cmd_handler_snfc(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_snfc_pkt *cmd;
|
|
|
|
|
networking: convert many more places to skb_put_zero()
There were many places that my previous spatch didn't find,
as pointed out by yuan linyu in various patches.
The following spatch found many more and also removes the
now unnecessary casts:
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = skb_put(skb, len);
+p = skb_put_zero(skb, len);
|
-p = (t)skb_put(skb, len);
+p = skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
|
-p = (t *)skb_put(skb, sizeof(t));
+p = skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(skb_put(skb, len), 0, len);
+skb_put_zero(skb, len);
Apply it to the tree (with one manual fixup to keep the
comment in vxlan.c, which spatch removed.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:19 +03:00
|
|
|
cmd = skb_put_zero(skb, sizeof(*cmd));
|
2016-07-19 04:54:17 +03:00
|
|
|
cmd->mode = nca->bytes[0];
|
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-05 20:46:01 +03:00
|
|
|
static int ncsi_cmd_handler_oem(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_cmd_oem_pkt *cmd;
|
|
|
|
unsigned int len;
|
|
|
|
|
|
|
|
len = sizeof(struct ncsi_cmd_pkt_hdr) + 4;
|
|
|
|
if (nca->payload < 26)
|
|
|
|
len += 26;
|
|
|
|
else
|
|
|
|
len += nca->payload;
|
|
|
|
|
|
|
|
cmd = skb_put_zero(skb, len);
|
|
|
|
memcpy(&cmd->mfr_id, nca->data, nca->payload);
|
|
|
|
ncsi_cmd_build_header(&cmd->cmd.common, nca);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-07-19 04:54:17 +03:00
|
|
|
static struct ncsi_cmd_handler {
|
|
|
|
unsigned char type;
|
|
|
|
int payload;
|
|
|
|
int (*handler)(struct sk_buff *skb,
|
|
|
|
struct ncsi_cmd_arg *nca);
|
|
|
|
} ncsi_cmd_handlers[] = {
|
|
|
|
{ NCSI_PKT_CMD_CIS, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_SP, 4, ncsi_cmd_handler_sp },
|
|
|
|
{ NCSI_PKT_CMD_DP, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_EC, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_DC, 4, ncsi_cmd_handler_dc },
|
|
|
|
{ NCSI_PKT_CMD_RC, 4, ncsi_cmd_handler_rc },
|
|
|
|
{ NCSI_PKT_CMD_ECNT, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_DCNT, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_AE, 8, ncsi_cmd_handler_ae },
|
|
|
|
{ NCSI_PKT_CMD_SL, 8, ncsi_cmd_handler_sl },
|
|
|
|
{ NCSI_PKT_CMD_GLS, 0, ncsi_cmd_handler_default },
|
2017-08-28 09:18:41 +03:00
|
|
|
{ NCSI_PKT_CMD_SVF, 8, ncsi_cmd_handler_svf },
|
2016-07-19 04:54:17 +03:00
|
|
|
{ NCSI_PKT_CMD_EV, 4, ncsi_cmd_handler_ev },
|
|
|
|
{ NCSI_PKT_CMD_DV, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_SMA, 8, ncsi_cmd_handler_sma },
|
|
|
|
{ NCSI_PKT_CMD_EBF, 4, ncsi_cmd_handler_ebf },
|
|
|
|
{ NCSI_PKT_CMD_DBF, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_EGMF, 4, ncsi_cmd_handler_egmf },
|
|
|
|
{ NCSI_PKT_CMD_DGMF, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_SNFC, 4, ncsi_cmd_handler_snfc },
|
|
|
|
{ NCSI_PKT_CMD_GVI, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_GC, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_GP, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_GCPS, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_GNS, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_GNPTS, 0, ncsi_cmd_handler_default },
|
|
|
|
{ NCSI_PKT_CMD_GPS, 0, ncsi_cmd_handler_default },
|
2018-10-05 20:46:01 +03:00
|
|
|
{ NCSI_PKT_CMD_OEM, -1, ncsi_cmd_handler_oem },
|
2016-07-19 04:54:17 +03:00
|
|
|
{ NCSI_PKT_CMD_PLDM, 0, NULL },
|
|
|
|
{ NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default }
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct ncsi_request *ncsi_alloc_command(struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
|
|
|
struct ncsi_dev_priv *ndp = nca->ndp;
|
|
|
|
struct ncsi_dev *nd = &ndp->ndev;
|
|
|
|
struct net_device *dev = nd->dev;
|
|
|
|
int hlen = LL_RESERVED_SPACE(dev);
|
|
|
|
int tlen = dev->needed_tailroom;
|
|
|
|
int len = hlen + tlen;
|
|
|
|
struct sk_buff *skb;
|
|
|
|
struct ncsi_request *nr;
|
|
|
|
|
2016-10-04 03:25:51 +03:00
|
|
|
nr = ncsi_alloc_request(ndp, nca->req_flags);
|
2016-07-19 04:54:17 +03:00
|
|
|
if (!nr)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* NCSI command packet has 16-bytes header, payload, 4 bytes checksum.
|
|
|
|
* The packet needs padding if its payload is less than 26 bytes to
|
|
|
|
* meet 64 bytes minimal ethernet frame length.
|
|
|
|
*/
|
|
|
|
len += sizeof(struct ncsi_cmd_pkt_hdr) + 4;
|
|
|
|
if (nca->payload < 26)
|
|
|
|
len += 26;
|
|
|
|
else
|
|
|
|
len += nca->payload;
|
|
|
|
|
|
|
|
/* Allocate skb */
|
|
|
|
skb = alloc_skb(len, GFP_ATOMIC);
|
|
|
|
if (!skb) {
|
|
|
|
ncsi_free_request(nr);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
nr->cmd = skb;
|
|
|
|
skb_reserve(skb, hlen);
|
|
|
|
skb_reset_network_header(skb);
|
|
|
|
|
|
|
|
skb->dev = dev;
|
|
|
|
skb->protocol = htons(ETH_P_NCSI);
|
|
|
|
|
|
|
|
return nr;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
|
|
|
|
{
|
2019-08-22 00:24:52 +03:00
|
|
|
struct ncsi_cmd_handler *nch = NULL;
|
2016-07-19 04:54:17 +03:00
|
|
|
struct ncsi_request *nr;
|
2019-08-22 00:24:52 +03:00
|
|
|
unsigned char type;
|
2016-07-19 04:54:17 +03:00
|
|
|
struct ethhdr *eh;
|
|
|
|
int i, ret;
|
|
|
|
|
2019-08-22 00:24:52 +03:00
|
|
|
/* Use OEM generic handler for Netlink request */
|
|
|
|
if (nca->req_flags == NCSI_REQ_FLAG_NETLINK_DRIVEN)
|
|
|
|
type = NCSI_PKT_CMD_OEM;
|
|
|
|
else
|
|
|
|
type = nca->type;
|
|
|
|
|
2016-07-19 04:54:17 +03:00
|
|
|
/* Search for the handler */
|
|
|
|
for (i = 0; i < ARRAY_SIZE(ncsi_cmd_handlers); i++) {
|
2019-08-22 00:24:52 +03:00
|
|
|
if (ncsi_cmd_handlers[i].type == type) {
|
2016-07-19 04:54:17 +03:00
|
|
|
if (ncsi_cmd_handlers[i].handler)
|
|
|
|
nch = &ncsi_cmd_handlers[i];
|
|
|
|
else
|
|
|
|
nch = NULL;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!nch) {
|
|
|
|
netdev_err(nca->ndp->ndev.dev,
|
|
|
|
"Cannot send packet with type 0x%02x\n", nca->type);
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
2018-10-05 20:46:01 +03:00
|
|
|
/* Get packet payload length and allocate the request
|
|
|
|
* It is expected that if length set as negative in
|
|
|
|
* handler structure means caller is initializing it
|
|
|
|
* and setting length in nca before calling xmit function
|
|
|
|
*/
|
|
|
|
if (nch->payload >= 0)
|
|
|
|
nca->payload = nch->payload;
|
2016-07-19 04:54:17 +03:00
|
|
|
nr = ncsi_alloc_command(nca);
|
|
|
|
if (!nr)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2018-10-11 21:07:37 +03:00
|
|
|
/* track netlink information */
|
|
|
|
if (nca->req_flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
|
|
|
|
nr->snd_seq = nca->info->snd_seq;
|
|
|
|
nr->snd_portid = nca->info->snd_portid;
|
|
|
|
nr->nlhdr = *nca->info->nlhdr;
|
|
|
|
}
|
|
|
|
|
2016-07-19 04:54:17 +03:00
|
|
|
/* Prepare the packet */
|
|
|
|
nca->id = nr->id;
|
|
|
|
ret = nch->handler(nr->cmd, nca);
|
|
|
|
if (ret) {
|
|
|
|
ncsi_free_request(nr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill the ethernet header */
|
networking: make skb_push & __skb_push return void pointers
It seems like a historic accident that these return unsigned char *,
and in many places that means casts are required, more often than not.
Make these functions return void * and remove all the casts across
the tree, adding a (u8 *) cast only where the unsigned char pointer
was used directly, all done with the following spatch:
@@
expression SKB, LEN;
typedef u8;
identifier fn = { skb_push, __skb_push, skb_push_rcsum };
@@
- *(fn(SKB, LEN))
+ *(u8 *)fn(SKB, LEN)
@@
expression E, SKB, LEN;
identifier fn = { skb_push, __skb_push, skb_push_rcsum };
type T;
@@
- E = ((T *)(fn(SKB, LEN)))
+ E = fn(SKB, LEN)
@@
expression SKB, LEN;
identifier fn = { skb_push, __skb_push, skb_push_rcsum };
@@
- fn(SKB, LEN)[0]
+ *(u8 *)fn(SKB, LEN)
Note that the last part there converts from push(...)[0] to the
more idiomatic *(u8 *)push(...).
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-16 15:29:23 +03:00
|
|
|
eh = skb_push(nr->cmd, sizeof(*eh));
|
2016-07-19 04:54:17 +03:00
|
|
|
eh->h_proto = htons(ETH_P_NCSI);
|
|
|
|
eth_broadcast_addr(eh->h_dest);
|
2020-01-07 22:30:33 +03:00
|
|
|
|
|
|
|
/* If mac address received from device then use it for
|
|
|
|
* source address as unicast address else use broadcast
|
|
|
|
* address as source address
|
|
|
|
*/
|
|
|
|
if (nca->ndp->gma_flag == 1)
|
|
|
|
memcpy(eh->h_source, nca->ndp->ndev.dev->dev_addr, ETH_ALEN);
|
|
|
|
else
|
|
|
|
eth_broadcast_addr(eh->h_source);
|
2016-07-19 04:54:17 +03:00
|
|
|
|
|
|
|
/* Start the timer for the request that might not have
|
|
|
|
* corresponding response. Given NCSI is an internal
|
|
|
|
* connection a 1 second delay should be sufficient.
|
|
|
|
*/
|
|
|
|
nr->enabled = true;
|
|
|
|
mod_timer(&nr->timer, jiffies + 1 * HZ);
|
|
|
|
|
|
|
|
/* Send NCSI packet */
|
|
|
|
skb_get(nr->cmd);
|
|
|
|
ret = dev_queue_xmit(nr->cmd);
|
|
|
|
if (ret < 0) {
|
|
|
|
ncsi_free_request(nr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|