diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-18 07:18:37 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-18 07:18:37 +0300 |
commit | 817002475046737877915d87889a012d851650fa (patch) | |
tree | 1d0148791856595b7731b66702f59796ef9c75ab /drivers | |
parent | 27eabfaaf4a3049a1592d69ad9969577bcb62791 (diff) | |
parent | 461ee7f3286dd50be4726606819c4228bc485a17 (diff) | |
download | linux-817002475046737877915d87889a012d851650fa.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
1) Revert regression inducing change to the IPSEC template resolver,
from Steffen Klassert.
2) Peeloffs can cause the wrong sk to be waken up in SCTP, fix from Xin
Long.
3) Min packet MTU size is wrong in cpsw driver, from Grygorii Strashko.
4) Fix build failure in netfilter ctnetlink, from Arnd Bergmann.
5) ISDN hisax driver checks pnp_irq() for errors incorrectly, from
Arvind Yadav.
6) Fix fealnx driver build failure on MIPS, from Huacai Chen.
7) Fix into leak in SCTP, the scope_id of socket addresses is not
always filled in. From Eric W. Biederman.
8) MTU inheritance between physical function and representor fix in nfp
driver, from Dirk van der Merwe.
9) Fix memory leak in rsi driver, from Colin Ian King.
10) Fix expiration and generation ID handling of cached ipv4 redirect
routes, from Xin Long.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (40 commits)
net: usb: hso.c: remove unneeded DRIVER_LICENSE #define
ibmvnic: fix dma_mapping_error call
ipvlan: NULL pointer dereference panic in ipvlan_port_destroy
route: also update fnhe_genid when updating a route cache
route: update fnhe_expires for redirect when the fnhe exists
sctp: set frag_point in sctp_setsockopt_maxseg correctly
rsi: fix memory leak on buf and usb_reg_buf
net/netlabel: Add list_next_rcu() in rcu_dereference().
nfp: remove false positive offloads in flower vxlan
nfp: register flower reprs for egress dev offload
nfp: inherit the max_mtu from the PF netdev
nfp: fix vlan receive MAC statistics typo
nfp: fix flower offload metadata flag usage
virto_net: remove empty file 'virtio_net.'
net/sctp: Always set scope_id in sctp_inet6_skb_msgname
fealnx: Fix building error on MIPS
isdn: hisax: Fix pnp_irq's error checking for setup_teles3
isdn: hisax: Fix pnp_irq's error checking for setup_sedlbauer_isapnp
isdn: hisax: Fix pnp_irq's error checking for setup_niccy
isdn: hisax: Fix pnp_irq's error checking for setup_ix1micro
...
Diffstat (limited to 'drivers')
33 files changed, 255 insertions, 151 deletions
diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c index 62f9c43e2377..74c871495e81 100644 --- a/drivers/isdn/hisax/asuscom.c +++ b/drivers/isdn/hisax/asuscom.c @@ -348,7 +348,7 @@ int setup_asuscom(struct IsdnCard *card) } card->para[1] = pnp_port_start(pnp_d, 0); card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1]) { + if (card->para[0] == -1 || !card->para[1]) { printk(KERN_ERR "AsusPnP:some resources are missing %ld/%lx\n", card->para[0], card->para[1]); pnp_disable_dev(pnp_d); diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index daf3742cdef6..a18b605fb4f2 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -805,7 +805,7 @@ static int avm_pnp_setup(struct IsdnCardState *cs) cs->hw.avm.cfg_reg = pnp_port_start(pnp_avm_d, 0); cs->irq = pnp_irq(pnp_avm_d, 0); - if (!cs->irq) { + if (cs->irq == -1) { printk(KERN_ERR "FritzPnP:No IRQ\n"); return (0); } diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 38bdd3f7b960..d23df7a7784d 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -1093,7 +1093,7 @@ static int setup_diva_isapnp(struct IsdnCard *card) } card->para[1] = pnp_port_start(pnp_d, 0); card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1]) { + if (card->para[0] == -1 || !card->para[1]) { printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", card->para[0], card->para[1]); pnp_disable_dev(pnp_d); diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index b21c05820f44..0754c0743790 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c @@ -945,7 +945,7 @@ static int setup_elsa_isapnp(struct IsdnCard *card) card->para[1] = pnp_port_start(pnp_d, 0); card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1]) { + if (card->para[0] == -1 || !card->para[1]) { printk(KERN_ERR "Elsa PnP:some resources are missing %ld/%lx\n", card->para[0], card->para[1]); pnp_disable_dev(pnp_d); diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index d925f579bc80..4d3b4b2f2612 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -1423,7 +1423,7 @@ int setup_hfcsx(struct IsdnCard *card) } card->para[1] = pnp_port_start(pnp_d, 0); card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1]) { + if (card->para[0] == -1 || !card->para[1]) { printk(KERN_ERR "HFC PnP:some resources are missing %ld/%lx\n", card->para[0], card->para[1]); pnp_disable_dev(pnp_d); diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c index 380bbeda9c74..91b5219499ca 100644 --- a/drivers/isdn/hisax/hfcscard.c +++ b/drivers/isdn/hisax/hfcscard.c @@ -196,7 +196,7 @@ int setup_hfcs(struct IsdnCard *card) } card->para[1] = pnp_port_start(pnp_d, 0); card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1]) { + if (card->para[0] == -1 || !card->para[1]) { printk(KERN_ERR "HFC PnP:some resources are missing %ld/%lx\n", card->para[0], card->para[1]); pnp_disable_dev(pnp_d); diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index e4f7573ba9bf..7a7137d8664b 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -940,6 +940,8 @@ static int fcpnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) } adapter->io = pnp_port_start(pdev, 0); adapter->irq = pnp_irq(pdev, 0); + if (!adapter->io || adapter->irq == -1) + goto err_free; printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %d\n", (char *) dev_id->driver_data, adapter->io, adapter->irq); diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c index 1399ddd4f6cb..53e299be4304 100644 --- a/drivers/isdn/hisax/isurf.c +++ b/drivers/isdn/hisax/isurf.c @@ -238,7 +238,7 @@ int setup_isurf(struct IsdnCard *card) cs->hw.isurf.reset = pnp_port_start(pnp_d, 0); cs->hw.isurf.phymem = pnp_mem_start(pnp_d, 1); cs->irq = pnp_irq(pnp_d, 0); - if (!cs->irq || !cs->hw.isurf.reset || !cs->hw.isurf.phymem) { + if (cs->irq == -1 || !cs->hw.isurf.reset || !cs->hw.isurf.phymem) { printk(KERN_ERR "ISurfPnP:some resources are missing %d/%x/%lx\n", cs->irq, cs->hw.isurf.reset, cs->hw.isurf.phymem); pnp_disable_dev(pnp_d); diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c index 7ae39f5e865d..bfb79f3f0a49 100644 --- a/drivers/isdn/hisax/ix1_micro.c +++ b/drivers/isdn/hisax/ix1_micro.c @@ -256,7 +256,7 @@ int setup_ix1micro(struct IsdnCard *card) } card->para[1] = pnp_port_start(pnp_d, 0); card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1]) { + if (card->para[0] == -1 || !card->para[1]) { printk(KERN_ERR "ITK PnP:some resources are missing %ld/%lx\n", card->para[0], card->para[1]); pnp_disable_dev(pnp_d); diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c index e4c33cfe3ef4..dfbcd2eaa81a 100644 --- a/drivers/isdn/hisax/niccy.c +++ b/drivers/isdn/hisax/niccy.c @@ -261,7 +261,7 @@ int setup_niccy(struct IsdnCard *card) card->para[1] = pnp_port_start(pnp_d, 0); card->para[2] = pnp_port_start(pnp_d, 1); card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1] || + if (card->para[0] == -1 || !card->para[1] || !card->para[2]) { printk(KERN_ERR "NiccyPnP:some resources are " "missing %ld/%lx/%lx\n", diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c index f16a47bcef48..c0b97b893495 100644 --- a/drivers/isdn/hisax/sedlbauer.c +++ b/drivers/isdn/hisax/sedlbauer.c @@ -558,7 +558,7 @@ static int setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt) card->para[1] = pnp_port_start(pnp_d, 0); card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1]) { + if (card->para[0] == -1 || !card->para[1]) { printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n", card->para[0], card->para[1]); pnp_disable_dev(pnp_d); diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c index 38fb2c1a3f0f..1eef693f04f0 100644 --- a/drivers/isdn/hisax/teles3.c +++ b/drivers/isdn/hisax/teles3.c @@ -306,7 +306,7 @@ int setup_teles3(struct IsdnCard *card) card->para[2] = pnp_port_start(pnp_d, 1); card->para[1] = pnp_port_start(pnp_d, 0); card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1] || !card->para[2]) { + if (card->para[0] == -1 || !card->para[1] || !card->para[2]) { printk(KERN_ERR "Teles PnP:some resources are missing %ld/%lx/%lx\n", card->para[0], card->para[1], card->para[2]); pnp_disable_dev(pnp_d); diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c index 23053919ebf5..ae55da60ed0e 100644 --- a/drivers/net/ethernet/fealnx.c +++ b/drivers/net/ethernet/fealnx.c @@ -257,8 +257,8 @@ enum rx_desc_status_bits { RXFSD = 0x00000800, /* first descriptor */ RXLSD = 0x00000400, /* last descriptor */ ErrorSummary = 0x80, /* error summary */ - RUNT = 0x40, /* runt packet received */ - LONG = 0x20, /* long packet received */ + RUNTPKT = 0x40, /* runt packet received */ + LONGPKT = 0x20, /* long packet received */ FAE = 0x10, /* frame align error */ CRC = 0x08, /* crc error */ RXER = 0x04, /* receive error */ @@ -1628,7 +1628,7 @@ static int netdev_rx(struct net_device *dev) dev->name, rx_status); dev->stats.rx_errors++; /* end of a packet. */ - if (rx_status & (LONG | RUNT)) + if (rx_status & (LONGPKT | RUNTPKT)) dev->stats.rx_length_errors++; if (rx_status & RXER) dev->stats.rx_frame_errors++; diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 04aaacbc3d45..1dc4aef37d3a 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -849,7 +849,6 @@ static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter) { struct device *dev = &adapter->vdev->dev; union ibmvnic_crq crq; - dma_addr_t dma_addr; int len = 0; if (adapter->vpd->buff) @@ -879,7 +878,7 @@ static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter) adapter->vpd->dma_addr = dma_map_single(dev, adapter->vpd->buff, adapter->vpd->len, DMA_FROM_DEVICE); - if (dma_mapping_error(dev, dma_addr)) { + if (dma_mapping_error(dev, adapter->vpd->dma_addr)) { dev_err(dev, "Could not map VPD buffer\n"); kfree(adapter->vpd->buff); return -ENOMEM; diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index e0283bb24f06..8fcc90c0d2d3 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -125,6 +125,21 @@ nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr) return nfp_flower_cmsg_portmod(repr, false); } +static int +nfp_flower_repr_netdev_init(struct nfp_app *app, struct net_device *netdev) +{ + return tc_setup_cb_egdev_register(netdev, + nfp_flower_setup_tc_egress_cb, + netdev_priv(netdev)); +} + +static void +nfp_flower_repr_netdev_clean(struct nfp_app *app, struct net_device *netdev) +{ + tc_setup_cb_egdev_unregister(netdev, nfp_flower_setup_tc_egress_cb, + netdev_priv(netdev)); +} + static void nfp_flower_sriov_disable(struct nfp_app *app) { struct nfp_flower_priv *priv = app->priv; @@ -452,6 +467,9 @@ const struct nfp_app_type app_flower = { .vnic_init = nfp_flower_vnic_init, .vnic_clean = nfp_flower_vnic_clean, + .repr_init = nfp_flower_repr_netdev_init, + .repr_clean = nfp_flower_repr_netdev_clean, + .repr_open = nfp_flower_repr_netdev_open, .repr_stop = nfp_flower_repr_netdev_stop, diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index c90e72b7ff5a..e6b26c5ae6e0 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -52,8 +52,7 @@ struct nfp_app; #define NFP_FLOWER_MASK_ELEMENT_RS 1 #define NFP_FLOWER_MASK_HASH_BITS 10 -#define NFP_FL_META_FLAG_NEW_MASK 128 -#define NFP_FL_META_FLAG_LAST_MASK 1 +#define NFP_FL_META_FLAG_MANAGE_MASK BIT(7) #define NFP_FL_MASK_REUSE_TIME_NS 40000 #define NFP_FL_MASK_ID_LOCATION 1 @@ -197,5 +196,7 @@ void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4); void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4); void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb); void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb); +int nfp_flower_setup_tc_egress_cb(enum tc_setup_type type, void *type_data, + void *cb_priv); #endif diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c index 193520ef23f0..db977cf8e933 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c +++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c @@ -282,7 +282,7 @@ nfp_check_mask_add(struct nfp_app *app, char *mask_data, u32 mask_len, id = nfp_add_mask_table(app, mask_data, mask_len); if (id < 0) return false; - *meta_flags |= NFP_FL_META_FLAG_NEW_MASK; + *meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK; } *mask_id = id; @@ -299,6 +299,9 @@ nfp_check_mask_remove(struct nfp_app *app, char *mask_data, u32 mask_len, if (!mask_entry) return false; + if (meta_flags) + *meta_flags &= ~NFP_FL_META_FLAG_MANAGE_MASK; + *mask_id = mask_entry->mask_id; mask_entry->ref_cnt--; if (!mask_entry->ref_cnt) { @@ -306,7 +309,7 @@ nfp_check_mask_remove(struct nfp_app *app, char *mask_data, u32 mask_len, nfp_release_mask_id(app, *mask_id); kfree(mask_entry); if (meta_flags) - *meta_flags |= NFP_FL_META_FLAG_LAST_MASK; + *meta_flags |= NFP_FL_META_FLAG_MANAGE_MASK; } return true; diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index cdbb5464b790..f5d73b83dcc2 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -131,7 +131,8 @@ static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f) static int nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls, - struct tc_cls_flower_offload *flow) + struct tc_cls_flower_offload *flow, + bool egress) { struct flow_dissector_key_basic *mask_basic = NULL; struct flow_dissector_key_basic *key_basic = NULL; @@ -167,6 +168,9 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls, skb_flow_dissector_target(flow->dissector, FLOW_DISSECTOR_KEY_ENC_CONTROL, flow->key); + if (!egress) + return -EOPNOTSUPP; + if (mask_enc_ctl->addr_type != 0xffff || enc_ctl->addr_type != FLOW_DISSECTOR_KEY_IPV4_ADDRS) return -EOPNOTSUPP; @@ -194,6 +198,9 @@ nfp_flower_calculate_key_layers(struct nfp_fl_key_ls *ret_key_ls, key_layer |= NFP_FLOWER_LAYER_VXLAN; key_size += sizeof(struct nfp_flower_vxlan); + } else if (egress) { + /* Reject non tunnel matches offloaded to egress repr. */ + return -EOPNOTSUPP; } if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) { @@ -315,7 +322,7 @@ err_free_flow: */ static int nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, - struct tc_cls_flower_offload *flow) + struct tc_cls_flower_offload *flow, bool egress) { struct nfp_flower_priv *priv = app->priv; struct nfp_fl_payload *flow_pay; @@ -326,7 +333,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, if (!key_layer) return -ENOMEM; - err = nfp_flower_calculate_key_layers(key_layer, flow); + err = nfp_flower_calculate_key_layers(key_layer, flow, egress); if (err) goto err_free_key_ls; @@ -447,7 +454,7 @@ nfp_flower_get_stats(struct nfp_app *app, struct tc_cls_flower_offload *flow) static int nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev, - struct tc_cls_flower_offload *flower) + struct tc_cls_flower_offload *flower, bool egress) { if (!eth_proto_is_802_3(flower->common.protocol) || flower->common.chain_index) @@ -455,7 +462,7 @@ nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev, switch (flower->command) { case TC_CLSFLOWER_REPLACE: - return nfp_flower_add_offload(app, netdev, flower); + return nfp_flower_add_offload(app, netdev, flower, egress); case TC_CLSFLOWER_DESTROY: return nfp_flower_del_offload(app, netdev, flower); case TC_CLSFLOWER_STATS: @@ -465,6 +472,23 @@ nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev, return -EOPNOTSUPP; } +int nfp_flower_setup_tc_egress_cb(enum tc_setup_type type, void *type_data, + void *cb_priv) +{ + struct nfp_repr *repr = cb_priv; + + if (!tc_can_offload(repr->netdev)) + return -EOPNOTSUPP; + + switch (type) { + case TC_SETUP_CLSFLOWER: + return nfp_flower_repr_offload(repr->app, repr->netdev, + type_data, true); + default: + return -EOPNOTSUPP; + } +} + static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) { @@ -476,7 +500,7 @@ static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type, switch (type) { case TC_SETUP_CLSFLOWER: return nfp_flower_repr_offload(repr->app, repr->netdev, - type_data); + type_data, false); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.h b/drivers/net/ethernet/netronome/nfp/nfp_app.h index 54b67c9b8d5b..0e5e0305ad1c 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_app.h @@ -76,6 +76,8 @@ extern const struct nfp_app_type app_flower; * @vnic_free: free up app's vNIC state * @vnic_init: vNIC netdev was registered * @vnic_clean: vNIC netdev about to be unregistered + * @repr_init: representor about to be registered + * @repr_clean: representor about to be unregistered * @repr_open: representor netdev open callback * @repr_stop: representor netdev stop callback * @start: start application logic @@ -109,6 +111,9 @@ struct nfp_app_type { int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn); void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn); + int (*repr_init)(struct nfp_app *app, struct net_device *netdev); + void (*repr_clean)(struct nfp_app *app, struct net_device *netdev); + int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr); int (*repr_stop)(struct nfp_app *app, struct nfp_repr *repr); @@ -212,6 +217,21 @@ static inline int nfp_app_repr_stop(struct nfp_app *app, struct nfp_repr *repr) return app->type->repr_stop(app, repr); } +static inline int +nfp_app_repr_init(struct nfp_app *app, struct net_device *netdev) +{ + if (!app->type->repr_init) + return 0; + return app->type->repr_init(app, netdev); +} + +static inline void +nfp_app_repr_clean(struct nfp_app *app, struct net_device *netdev) +{ + if (app->type->repr_clean) + app->type->repr_clean(app, netdev); +} + static inline int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl) { app->ctrl = ctrl; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c index 60c8d733a37d..2801ecd09eab 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c @@ -104,7 +104,7 @@ static const struct nfp_et_stat nfp_mac_et_stats[] = { { "rx_frame_too_long_errors", NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS, }, { "rx_range_length_errors", NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS, }, - { "rx_vlan_reveive_ok", NFP_MAC_STATS_RX_VLAN_REVEIVE_OK, }, + { "rx_vlan_received_ok", NFP_MAC_STATS_RX_VLAN_RECEIVED_OK, }, { "rx_errors", NFP_MAC_STATS_RX_IN_ERRORS, }, { "rx_broadcast_pkts", NFP_MAC_STATS_RX_IN_BROADCAST_PKTS, }, { "rx_drop_events", NFP_MAC_STATS_RX_DROP_EVENTS, }, diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c index 1bce8c131bb9..924a05e05da0 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c @@ -258,6 +258,7 @@ const struct net_device_ops nfp_repr_netdev_ops = { static void nfp_repr_clean(struct nfp_repr *repr) { unregister_netdev(repr->netdev); + nfp_app_repr_clean(repr->app, repr->netdev); dst_release((struct dst_entry *)repr->dst); nfp_port_free(repr->port); } @@ -297,6 +298,8 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev, netdev->netdev_ops = &nfp_repr_netdev_ops; netdev->ethtool_ops = &nfp_port_ethtool_ops; + netdev->max_mtu = pf_netdev->max_mtu; + SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops); if (nfp_app_has_tc(app)) { @@ -304,12 +307,18 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev, netdev->hw_features |= NETIF_F_HW_TC; } - err = register_netdev(netdev); + err = nfp_app_repr_init(app, netdev); if (err) goto err_clean; + err = register_netdev(netdev); + if (err) + goto err_repr_clean; + return 0; +err_repr_clean: + nfp_app_repr_clean(app, netdev); err_clean: dst_release((struct dst_entry *)repr->dst); return err; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.h b/drivers/net/ethernet/netronome/nfp/nfp_port.h index 51dcb9c603ee..21bd4aa32646 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_port.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_port.h @@ -157,7 +157,7 @@ void nfp_devlink_port_unregister(struct nfp_port *port); /* unused 0x008 */ #define NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS (NFP_MAC_STATS_BASE + 0x010) #define NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS (NFP_MAC_STATS_BASE + 0x018) -#define NFP_MAC_STATS_RX_VLAN_REVEIVE_OK (NFP_MAC_STATS_BASE + 0x020) +#define NFP_MAC_STATS_RX_VLAN_RECEIVED_OK (NFP_MAC_STATS_BASE + 0x020) #define NFP_MAC_STATS_RX_IN_ERRORS (NFP_MAC_STATS_BASE + 0x028) #define NFP_MAC_STATS_RX_IN_BROADCAST_PKTS (NFP_MAC_STATS_BASE + 0x030) #define NFP_MAC_STATS_RX_DROP_EVENTS (NFP_MAC_STATS_BASE + 0x038) diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c index 6e15d3c10ebf..fe7c1f230028 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c @@ -1277,11 +1277,10 @@ static struct qed_dcbx_get *qed_dcbnl_get_dcbx(struct qed_hwfn *hwfn, { struct qed_dcbx_get *dcbx_info; - dcbx_info = kmalloc(sizeof(*dcbx_info), GFP_ATOMIC); + dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_ATOMIC); if (!dcbx_info) return NULL; - memset(dcbx_info, 0, sizeof(*dcbx_info)); if (qed_dcbx_query_params(hwfn, dcbx_info, type)) { kfree(dcbx_info); return NULL; diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index db8a4bcfc6c7..a73600dceb8b 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -119,8 +119,8 @@ do { \ #define CPDMA_RXCP 0x60 #define CPSW_POLL_WEIGHT 64 -#define CPSW_MIN_PACKET_SIZE 60 -#define CPSW_MAX_PACKET_SIZE (1500 + 14 + 4 + 4) +#define CPSW_MIN_PACKET_SIZE (VLAN_ETH_ZLEN) +#define CPSW_MAX_PACKET_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) #define RX_PRIORITY_MAPPING 0x76543210 #define TX_PRIORITY_MAPPING 0x33221100 diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 4958bb6b7376..88ddfb92122b 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -646,6 +646,10 @@ struct nvsp_message { #define NETVSC_RECEIVE_BUFFER_ID 0xcafe #define NETVSC_SEND_BUFFER_ID 0 +#define NETVSC_SUPPORTED_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | \ + NETIF_F_TSO | NETIF_F_IPV6_CSUM | \ + NETIF_F_TSO6) + #define VRSS_SEND_TAB_SIZE 16 /* must be power of 2 */ #define VRSS_CHANNEL_MAX 64 #define VRSS_CHANNEL_DEFAULT 8 diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index da216ca4f2b2..5129647d420c 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -2011,7 +2011,7 @@ static int netvsc_probe(struct hv_device *dev, memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); - /* hw_features computed in rndis_filter_device_add */ + /* hw_features computed in rndis_netdev_set_hwcaps() */ net->features = net->hw_features | NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 8b1242b8d8ef..7b637c7dd1e5 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -1131,69 +1131,20 @@ unlock: rtnl_unlock(); } -struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, - struct netvsc_device_info *device_info) +static int rndis_netdev_set_hwcaps(struct rndis_device *rndis_device, + struct netvsc_device *nvdev) { - struct net_device *net = hv_get_drvdata(dev); + struct net_device *net = rndis_device->ndev; struct net_device_context *net_device_ctx = netdev_priv(net); - struct netvsc_device *net_device; - struct rndis_device *rndis_device; struct ndis_offload hwcaps; struct ndis_offload_params offloads; - struct ndis_recv_scale_cap rsscap; - u32 rsscap_size = sizeof(struct ndis_recv_scale_cap); unsigned int gso_max_size = GSO_MAX_SIZE; - u32 mtu, size; - const struct cpumask *node_cpu_mask; - u32 num_possible_rss_qs; - int i, ret; - - rndis_device = get_rndis_device(); - if (!rndis_device) - return ERR_PTR(-ENODEV); - - /* - * Let the inner driver handle this first to create the netvsc channel - * NOTE! Once the channel is created, we may get a receive callback - * (RndisFilterOnReceive()) before this call is completed - */ - net_device = netvsc_device_add(dev, device_info); - if (IS_ERR(net_device)) { - kfree(rndis_device); - return net_device; - } - - /* Initialize the rndis device */ - net_device->max_chn = 1; - net_device->num_chn = 1; - - net_device->extension = rndis_device; - rndis_device->ndev = net; - - /* Send the rndis initialization message */ - ret = rndis_filter_init_device(rndis_device, net_device); - if (ret != 0) - goto err_dev_remv; - - /* Get the MTU from the host */ - size = sizeof(u32); - ret = rndis_filter_query_device(rndis_device, net_device, - RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, - &mtu, &size); - if (ret == 0 && size == sizeof(u32) && mtu < net->mtu) - net->mtu = mtu; - - /* Get the mac address */ - ret = rndis_filter_query_device_mac(rndis_device, net_device); - if (ret != 0) - goto err_dev_remv; - - memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN); + int ret; /* Find HW offload capabilities */ - ret = rndis_query_hwcaps(rndis_device, net_device, &hwcaps); + ret = rndis_query_hwcaps(rndis_device, nvdev, &hwcaps); if (ret != 0) - goto err_dev_remv; + return ret; /* A value of zero means "no change"; now turn on what we want. */ memset(&offloads, 0, sizeof(struct ndis_offload_params)); @@ -1201,8 +1152,12 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, /* Linux does not care about IP checksum, always does in kernel */ offloads.ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED; + /* Reset previously set hw_features flags */ + net->hw_features &= ~NETVSC_SUPPORTED_HW_FEATURES; + net_device_ctx->tx_checksum_mask = 0; + /* Compute tx offload settings based on hw capabilities */ - net->hw_features = NETIF_F_RXCSUM; + net->hw_features |= NETIF_F_RXCSUM; if ((hwcaps.csum.ip4_txcsum & NDIS_TXCSUM_ALL_TCP4) == NDIS_TXCSUM_ALL_TCP4) { /* Can checksum TCP */ @@ -1246,10 +1201,75 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, } } + /* In case some hw_features disappeared we need to remove them from + * net->features list as they're no longer supported. + */ + net->features &= ~NETVSC_SUPPORTED_HW_FEATURES | net->hw_features; + netif_set_gso_max_size(net, gso_max_size); - ret = rndis_filter_set_offload_params(net, net_device, &offloads); - if (ret) + ret = rndis_filter_set_offload_params(net, nvdev, &offloads); + + return ret; +} + +struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, + struct netvsc_device_info *device_info) +{ + struct net_device *net = hv_get_drvdata(dev); + struct netvsc_device *net_device; + struct rndis_device *rndis_device; + struct ndis_recv_scale_cap rsscap; + u32 rsscap_size = sizeof(struct ndis_recv_scale_cap); + u32 mtu, size; + const struct cpumask *node_cpu_mask; + u32 num_possible_rss_qs; + int i, ret; + + rndis_device = get_rndis_device(); + if (!rndis_device) + return ERR_PTR(-ENODEV); + + /* Let the inner driver handle this first to create the netvsc channel + * NOTE! Once the channel is created, we may get a receive callback + * (RndisFilterOnReceive()) before this call is completed + */ + net_device = netvsc_device_add(dev, device_info); + if (IS_ERR(net_device)) { + kfree(rndis_device); + return net_device; + } + + /* Initialize the rndis device */ + net_device->max_chn = 1; + net_device->num_chn = 1; + + net_device->extension = rndis_device; + rndis_device->ndev = net; + + /* Send the rndis initialization message */ + ret = rndis_filter_init_device(rndis_device, net_device); + if (ret != 0) + goto err_dev_remv; + + /* Get the MTU from the host */ + size = sizeof(u32); + ret = rndis_filter_query_device(rndis_device, net_device, + RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, + &mtu, &size); + if (ret == 0 && size == sizeof(u32) && mtu < net->mtu) + net->mtu = mtu; + + /* Get the mac address */ + ret = rndis_filter_query_device_mac(rndis_device, net_device); + if (ret != 0) + goto err_dev_remv; + + memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN); + + /* Query and set hardware capabilities */ + ret = rndis_netdev_set_hwcaps(rndis_device, net_device); + if (ret != 0) goto err_dev_remv; rndis_filter_query_device_link_status(rndis_device, net_device); diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index a266aa435d4d..30cb803e2fe5 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -107,16 +107,6 @@ static int ipvlan_port_create(struct net_device *dev) struct ipvl_port *port; int err, idx; - if (dev->type != ARPHRD_ETHER || dev->flags & IFF_LOOPBACK) { - netdev_err(dev, "Master is either lo or non-ether device\n"); - return -EINVAL; - } - - if (netdev_is_rx_handler_busy(dev)) { - netdev_err(dev, "Device is already in use.\n"); - return -EBUSY; - } - port = kzalloc(sizeof(struct ipvl_port), GFP_KERNEL); if (!port) return -ENOMEM; @@ -179,8 +169,9 @@ static void ipvlan_port_destroy(struct net_device *dev) static int ipvlan_init(struct net_device *dev) { struct ipvl_dev *ipvlan = netdev_priv(dev); - const struct net_device *phy_dev = ipvlan->phy_dev; - struct ipvl_port *port = ipvlan->port; + struct net_device *phy_dev = ipvlan->phy_dev; + struct ipvl_port *port; + int err; dev->state = (dev->state & ~IPVLAN_STATE_MASK) | (phy_dev->state & IPVLAN_STATE_MASK); @@ -196,18 +187,27 @@ static int ipvlan_init(struct net_device *dev) if (!ipvlan->pcpu_stats) return -ENOMEM; + if (!netif_is_ipvlan_port(phy_dev)) { + err = ipvlan_port_create(phy_dev); + if (err < 0) { + free_percpu(ipvlan->pcpu_stats); + return err; + } + } + port = ipvlan_port_get_rtnl(phy_dev); port->count += 1; - return 0; } static void ipvlan_uninit(struct net_device *dev) { struct ipvl_dev *ipvlan = netdev_priv(dev); - struct ipvl_port *port = ipvlan->port; + struct net_device *phy_dev = ipvlan->phy_dev; + struct ipvl_port *port; free_percpu(ipvlan->pcpu_stats); + port = ipvlan_port_get_rtnl(phy_dev); port->count -= 1; if (!port->count) ipvlan_port_destroy(port->dev); @@ -554,7 +554,6 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev, struct net_device *phy_dev; int err; u16 mode = IPVLAN_MODE_L3; - bool create = false; if (!tb[IFLA_LINK]) return -EINVAL; @@ -568,28 +567,41 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev, phy_dev = tmp->phy_dev; } else if (!netif_is_ipvlan_port(phy_dev)) { - err = ipvlan_port_create(phy_dev); - if (err < 0) - return err; - create = true; - } + /* Exit early if the underlying link is invalid or busy */ + if (phy_dev->type != ARPHRD_ETHER || + phy_dev->flags & IFF_LOOPBACK) { + netdev_err(phy_dev, + "Master is either lo or non-ether device\n"); + return -EINVAL; + } - if (data && data[IFLA_IPVLAN_MODE]) - mode = nla_get_u16(data[IFLA_IPVLAN_MODE]); + if (netdev_is_rx_handler_busy(phy_dev)) { + netdev_err(phy_dev, "Device is already in use.\n"); + return -EBUSY; + } + } - port = ipvlan_port_get_rtnl(phy_dev); ipvlan->phy_dev = phy_dev; ipvlan->dev = dev; - ipvlan->port = port; ipvlan->sfeatures = IPVLAN_FEATURES; ipvlan_adjust_mtu(ipvlan, phy_dev); INIT_LIST_HEAD(&ipvlan->addrs); - /* Flags are per port and latest update overrides. User has - * to be consistent in setting it just like the mode attribute. + /* TODO Probably put random address here to be presented to the + * world but keep using the physical-dev address for the outgoing + * packets. */ - if (data && data[IFLA_IPVLAN_FLAGS]) - ipvlan->port->flags = nla_get_u16(data[IFLA_IPVLAN_FLAGS]); + memcpy(dev->dev_addr, phy_dev->dev_addr, ETH_ALEN); + + dev->priv_flags |= IFF_IPVLAN_SLAVE; + + err = register_netdevice(dev); + if (err < 0) + return err; + + /* ipvlan_init() would have created the port, if required */ + port = ipvlan_port_get_rtnl(phy_dev); + ipvlan->port = port; /* If the port-id base is at the MAX value, then wrap it around and * begin from 0x1 again. This may be due to a busy system where lots @@ -609,31 +621,28 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev, err = ida_simple_get(&port->ida, 0x1, port->dev_id_start, GFP_KERNEL); if (err < 0) - goto destroy_ipvlan_port; + goto unregister_netdev; dev->dev_id = err; + /* Increment id-base to the next slot for the future assignment */ port->dev_id_start = err + 1; - /* TODO Probably put random address here to be presented to the - * world but keep using the physical-dev address for the outgoing - * packets. - */ - memcpy(dev->dev_addr, phy_dev->dev_addr, ETH_ALEN); + err = netdev_upper_dev_link(phy_dev, dev, extack); + if (err) + goto remove_ida; - dev->priv_flags |= IFF_IPVLAN_SLAVE; + /* Flags are per port and latest update overrides. User has + * to be consistent in setting it just like the mode attribute. + */ + if (data && data[IFLA_IPVLAN_FLAGS]) + port->flags = nla_get_u16(data[IFLA_IPVLAN_FLAGS]); - err = register_netdevice(dev); - if (err < 0) - goto remove_ida; + if (data && data[IFLA_IPVLAN_MODE]) + mode = nla_get_u16(data[IFLA_IPVLAN_MODE]); - err = netdev_upper_dev_link(phy_dev, dev, extack); - if (err) { - goto unregister_netdev; - } err = ipvlan_set_port_mode(port, mode); - if (err) { + if (err) goto unlink_netdev; - } list_add_tail_rcu(&ipvlan->pnode, &port->ipvlans); netif_stacked_transfer_operstate(phy_dev, dev); @@ -641,13 +650,10 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev, unlink_netdev: netdev_upper_dev_unlink(phy_dev, dev); -unregister_netdev: - unregister_netdevice(dev); remove_ida: ida_simple_remove(&port->ida, dev->dev_id); -destroy_ipvlan_port: - if (create) - ipvlan_port_destroy(phy_dev); +unregister_netdev: + unregister_netdevice(dev); return err; } EXPORT_SYMBOL_GPL(ipvlan_link_new); diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 2c98152d1e1b..1d025ab9568f 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -2411,7 +2411,7 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, if (!hdr) return -EMSGSIZE; - genl_dump_check_consistent(cb, hdr, &macsec_fam); + genl_dump_check_consistent(cb, hdr); if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) goto nla_put_failure; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 42d7edcc3106..981c931a7a1f 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -76,7 +76,6 @@ #define MOD_AUTHOR "Option Wireless" #define MOD_DESCRIPTION "USB High Speed Option driver" -#define MOD_LICENSE "GPL" #define HSO_MAX_NET_DEVICES 10 #define HSO__MAX_MTU 2048 @@ -3286,7 +3285,7 @@ module_exit(hso_exit); MODULE_AUTHOR(MOD_AUTHOR); MODULE_DESCRIPTION(MOD_DESCRIPTION); -MODULE_LICENSE(MOD_LICENSE); +MODULE_LICENSE("GPL"); /* change the debug level (eg: insmod hso.ko debug=0x04) */ MODULE_PARM_DESC(debug, "debug level mask [0x01 | 0x02 | 0x04 | 0x08 | 0x10]"); diff --git a/drivers/net/virtio_net. b/drivers/net/virtio_net. deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/net/virtio_net. +++ /dev/null diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 07a49f58070a..7c3600643c7f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2805,7 +2805,7 @@ static int mac80211_hwsim_get_radio(struct sk_buff *skb, return -EMSGSIZE; if (cb) - genl_dump_check_consistent(cb, hdr, &hwsim_genl_family); + genl_dump_check_consistent(cb, hdr); if (data->alpha2[0] && data->alpha2[1]) param.reg_alpha2 = data->alpha2; diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index 08730227cd18..8f8443833348 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -162,13 +162,13 @@ static int rsi_usb_reg_read(struct usb_device *usbdev, u8 *buf; int status = -ENOMEM; + if (len > RSI_USB_CTRL_BUF_SIZE) + return -EINVAL; + buf = kmalloc(RSI_USB_CTRL_BUF_SIZE, GFP_KERNEL); if (!buf) return status; - if (len > RSI_USB_CTRL_BUF_SIZE) - return -EINVAL; - status = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), USB_VENDOR_REGISTER_READ, @@ -207,13 +207,13 @@ static int rsi_usb_reg_write(struct usb_device *usbdev, u8 *usb_reg_buf; int status = -ENOMEM; + if (len > RSI_USB_CTRL_BUF_SIZE) + return -EINVAL; + usb_reg_buf = kmalloc(RSI_USB_CTRL_BUF_SIZE, GFP_KERNEL); if (!usb_reg_buf) return status; - if (len > RSI_USB_CTRL_BUF_SIZE) - return -EINVAL; - usb_reg_buf[0] = (value & 0x00ff); usb_reg_buf[1] = (value & 0xff00) >> 8; usb_reg_buf[2] = 0x0; |