Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from David Miller:

 1) Don't insert ESP trailer twice in IPSEC code, from Huy Nguyen.

 2) The default crypto algorithm selection in Kconfig for IPSEC is out
    of touch with modern reality, fix this up. From Eric Biggers.

 3) bpftool is missing an entry for BPF_MAP_TYPE_RINGBUF, from Andrii
    Nakryiko.

 4) Missing init of ->frame_sz in xdp_convert_zc_to_xdp_frame(), from
    Hangbin Liu.

 5) Adjust packet alignment handling in ax88179_178a driver to match
    what the hardware actually does. From Jeremy Kerr.

 6) register_netdevice can leak in the case one of the notifiers fail,
    from Yang Yingliang.

 7) Use after free in ip_tunnel_lookup(), from Taehee Yoo.

 8) VLAN checks in sja1105 DSA driver need adjustments, from Vladimir
    Oltean.

 9) tg3 driver can sleep forever when we get enough EEH errors, fix from
    David Christensen.

10) Missing {READ,WRITE}_ONCE() annotations in various Intel ethernet
    drivers, from Ciara Loftus.

11) Fix scanning loop break condition in of_mdiobus_register(), from
    Florian Fainelli.

12) MTU limit is incorrect in ibmveth driver, from Thomas Falcon.

13) Endianness fix in mlxsw, from Ido Schimmel.

14) Use after free in smsc95xx usbnet driver, from Tuomas Tynkkynen.

15) Missing bridge mrp configuration validation, from Horatiu Vultur.

16) Fix circular netns references in wireguard, from Jason A. Donenfeld.

17) PTP initialization on recovery is not done properly in qed driver,
    from Alexander Lobakin.

18) Endian conversion of L4 ports in filters of cxgb4 driver is wrong,
    from Rahul Lakkireddy.

19) Don't clear bound device TX queue of socket prematurely otherwise we
    get problems with ktls hw offloading, from Tariq Toukan.

20) ipset can do atomics on unaligned memory, fix from Russell King.

21) Align ethernet addresses properly in bridging code, from Thomas
    Martitz.

22) Don't advertise ipv4 addresses on SCTP sockets having ipv6only set,
    from Marcelo Ricardo Leitner.

* git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (149 commits)
  rds: transport module should be auto loaded when transport is set
  sch_cake: fix a few style nits
  sch_cake: don't call diffserv parsing code when it is not needed
  sch_cake: don't try to reallocate or unshare skb unconditionally
  ethtool: fix error handling in linkstate_prepare_data()
  wil6210: account for napi_gro_receive never returning GRO_DROP
  hns: do not cast return value of napi_gro_receive to null
  socionext: account for napi_gro_receive never returning GRO_DROP
  wireguard: receive: account for napi_gro_receive never returning GRO_DROP
  vxlan: fix last fdb index during dump of fdb with nhid
  sctp: Don't advertise IPv4 addresses if ipv6only is set on the socket
  tc-testing: avoid action cookies with odd length.
  bpf: tcp: bpf_cubic: fix spurious HYSTART_DELAY exit upon drop in min RTT
  tcp_cubic: fix spurious HYSTART_DELAY exit upon drop in min RTT
  net: dsa: sja1105: fix tc-gate schedule with single element
  net: dsa: sja1105: recalculate gating subschedule after deleting tc-gate rules
  net: dsa: sja1105: unconditionally free old gating config
  net: dsa: sja1105: move sja1105_compose_gating_subschedule at the top
  net: macb: free resources on failure path of at91ether_open()
  net: macb: call pm_runtime_put_sync on failure path
  ...
This commit is contained in:
Linus Torvalds 2020-06-25 18:27:40 -07:00
commit 4a21185cda
223 changed files with 1973 additions and 1156 deletions

View File

@ -86,6 +86,20 @@ then the next program in the chain (A) will see those changes,
*not* the original input ``setsockopt`` arguments. The potentially
modified values will be then passed down to the kernel.
Large optval
============
When the ``optval`` is greater than the ``PAGE_SIZE``, the BPF program
can access only the first ``PAGE_SIZE`` of that data. So it has to options:
* Set ``optlen`` to zero, which indicates that the kernel should
use the original buffer from the userspace. Any modifications
done by the BPF program to the ``optval`` are ignored.
* Set ``optlen`` to the value less than ``PAGE_SIZE``, which
indicates that the kernel should use BPF's trimmed ``optval``.
When the BPF program returns with the ``optlen`` greater than
``PAGE_SIZE``, the userspace will receive ``EFAULT`` errno.
Example
=======

View File

@ -30,8 +30,8 @@ Socket API
The address family, socket addresses etc. are defined in the
include/net/af_ieee802154.h header or in the special header
in the userspace package (see either http://wpan.cakelab.org/ or the
git tree at https://github.com/linux-wpan/wpan-tools).
in the userspace package (see either https://linux-wpan.org/wpan-tools.html
or the git tree at https://github.com/linux-wpan/wpan-tools).
6LoWPAN Linux implementation
============================

View File

@ -8333,7 +8333,7 @@ M: Alexander Aring <alex.aring@gmail.com>
M: Stefan Schmidt <stefan@datenfreihafen.org>
L: linux-wpan@vger.kernel.org
S: Maintained
W: http://wpan.cakelab.org/
W: https://linux-wpan.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next.git
F: Documentation/networking/ieee802154.rst
@ -10808,7 +10808,7 @@ F: Documentation/devicetree/bindings/dma/mtk-*
F: drivers/dma/mediatek/
MEDIATEK ETHERNET DRIVER
M: Felix Fietkau <nbd@openwrt.org>
M: Felix Fietkau <nbd@nbd.name>
M: John Crispin <john@phrozen.org>
M: Sean Wang <sean.wang@mediatek.com>
M: Mark Lee <Mark-MC.Lee@mediatek.com>

View File

@ -572,6 +572,9 @@ static int bareudp2info(struct nlattr *data[], struct bareudp_conf *conf,
if (data[IFLA_BAREUDP_SRCPORT_MIN])
conf->sport_min = nla_get_u16(data[IFLA_BAREUDP_SRCPORT_MIN]);
if (data[IFLA_BAREUDP_MULTIPROTO_MODE])
conf->multi_proto_mode = true;
return 0;
}

View File

@ -1147,6 +1147,8 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
set_bit(0, priv->cfp.used);
set_bit(0, priv->cfp.unique);
/* Balance of_node_put() done by of_find_node_by_name() */
of_node_get(dn);
ports = of_find_node_by_name(dn, "ports");
if (ports) {
bcm_sf2_identify_ports(priv, ports);

View File

@ -7,6 +7,165 @@
#define SJA1105_SIZE_VL_STATUS 8
/* Insert into the global gate list, sorted by gate action time. */
static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
struct sja1105_rule *rule,
u8 gate_state, s64 entry_time,
struct netlink_ext_ack *extack)
{
struct sja1105_gate_entry *e;
int rc;
e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e)
return -ENOMEM;
e->rule = rule;
e->gate_state = gate_state;
e->interval = entry_time;
if (list_empty(&gating_cfg->entries)) {
list_add(&e->list, &gating_cfg->entries);
} else {
struct sja1105_gate_entry *p;
list_for_each_entry(p, &gating_cfg->entries, list) {
if (p->interval == e->interval) {
NL_SET_ERR_MSG_MOD(extack,
"Gate conflict");
rc = -EBUSY;
goto err;
}
if (e->interval < p->interval)
break;
}
list_add(&e->list, p->list.prev);
}
gating_cfg->num_entries++;
return 0;
err:
kfree(e);
return rc;
}
/* The gate entries contain absolute times in their e->interval field. Convert
* that to proper intervals (i.e. "0, 5, 10, 15" to "5, 5, 5, 5").
*/
static void
sja1105_gating_cfg_time_to_interval(struct sja1105_gating_config *gating_cfg,
u64 cycle_time)
{
struct sja1105_gate_entry *last_e;
struct sja1105_gate_entry *e;
struct list_head *prev;
list_for_each_entry(e, &gating_cfg->entries, list) {
struct sja1105_gate_entry *p;
prev = e->list.prev;
if (prev == &gating_cfg->entries)
continue;
p = list_entry(prev, struct sja1105_gate_entry, list);
p->interval = e->interval - p->interval;
}
last_e = list_last_entry(&gating_cfg->entries,
struct sja1105_gate_entry, list);
last_e->interval = cycle_time - last_e->interval;
}
static void sja1105_free_gating_config(struct sja1105_gating_config *gating_cfg)
{
struct sja1105_gate_entry *e, *n;
list_for_each_entry_safe(e, n, &gating_cfg->entries, list) {
list_del(&e->list);
kfree(e);
}
}
static int sja1105_compose_gating_subschedule(struct sja1105_private *priv,
struct netlink_ext_ack *extack)
{
struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg;
struct sja1105_rule *rule;
s64 max_cycle_time = 0;
s64 its_base_time = 0;
int i, rc = 0;
sja1105_free_gating_config(gating_cfg);
list_for_each_entry(rule, &priv->flow_block.rules, list) {
if (rule->type != SJA1105_RULE_VL)
continue;
if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
continue;
if (max_cycle_time < rule->vl.cycle_time) {
max_cycle_time = rule->vl.cycle_time;
its_base_time = rule->vl.base_time;
}
}
if (!max_cycle_time)
return 0;
dev_dbg(priv->ds->dev, "max_cycle_time %lld its_base_time %lld\n",
max_cycle_time, its_base_time);
gating_cfg->base_time = its_base_time;
gating_cfg->cycle_time = max_cycle_time;
gating_cfg->num_entries = 0;
list_for_each_entry(rule, &priv->flow_block.rules, list) {
s64 time;
s64 rbt;
if (rule->type != SJA1105_RULE_VL)
continue;
if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
continue;
/* Calculate the difference between this gating schedule's
* base time, and the base time of the gating schedule with the
* longest cycle time. We call it the relative base time (rbt).
*/
rbt = future_base_time(rule->vl.base_time, rule->vl.cycle_time,
its_base_time);
rbt -= its_base_time;
time = rbt;
for (i = 0; i < rule->vl.num_entries; i++) {
u8 gate_state = rule->vl.entries[i].gate_state;
s64 entry_time = time;
while (entry_time < max_cycle_time) {
rc = sja1105_insert_gate_entry(gating_cfg, rule,
gate_state,
entry_time,
extack);
if (rc)
goto err;
entry_time += rule->vl.cycle_time;
}
time += rule->vl.entries[i].interval;
}
}
sja1105_gating_cfg_time_to_interval(gating_cfg, max_cycle_time);
return 0;
err:
sja1105_free_gating_config(gating_cfg);
return rc;
}
/* The switch flow classification core implements TTEthernet, which 'thinks' in
* terms of Virtual Links (VL), a concept borrowed from ARINC 664 part 7.
* However it also has one other operating mode (VLLUPFORMAT=0) where it acts
@ -342,7 +501,9 @@ int sja1105_vl_redirect(struct sja1105_private *priv, int port,
NL_SET_ERR_MSG_MOD(extack,
"Can only redirect based on DMAC");
return -EOPNOTSUPP;
} else if (key->type != SJA1105_KEY_VLAN_AWARE_VL) {
} else if ((priv->vlan_state == SJA1105_VLAN_BEST_EFFORT ||
priv->vlan_state == SJA1105_VLAN_FILTERING_FULL) &&
key->type != SJA1105_KEY_VLAN_AWARE_VL) {
NL_SET_ERR_MSG_MOD(extack,
"Can only redirect based on {DMAC, VID, PCP}");
return -EOPNOTSUPP;
@ -388,173 +549,21 @@ int sja1105_vl_delete(struct sja1105_private *priv, int port,
kfree(rule);
}
rc = sja1105_compose_gating_subschedule(priv, extack);
if (rc)
return rc;
rc = sja1105_init_virtual_links(priv, extack);
if (rc)
return rc;
rc = sja1105_init_scheduling(priv);
if (rc < 0)
return rc;
return sja1105_static_config_reload(priv, SJA1105_VIRTUAL_LINKS);
}
/* Insert into the global gate list, sorted by gate action time. */
static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
struct sja1105_rule *rule,
u8 gate_state, s64 entry_time,
struct netlink_ext_ack *extack)
{
struct sja1105_gate_entry *e;
int rc;
e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e)
return -ENOMEM;
e->rule = rule;
e->gate_state = gate_state;
e->interval = entry_time;
if (list_empty(&gating_cfg->entries)) {
list_add(&e->list, &gating_cfg->entries);
} else {
struct sja1105_gate_entry *p;
list_for_each_entry(p, &gating_cfg->entries, list) {
if (p->interval == e->interval) {
NL_SET_ERR_MSG_MOD(extack,
"Gate conflict");
rc = -EBUSY;
goto err;
}
if (e->interval < p->interval)
break;
}
list_add(&e->list, p->list.prev);
}
gating_cfg->num_entries++;
return 0;
err:
kfree(e);
return rc;
}
/* The gate entries contain absolute times in their e->interval field. Convert
* that to proper intervals (i.e. "0, 5, 10, 15" to "5, 5, 5, 5").
*/
static void
sja1105_gating_cfg_time_to_interval(struct sja1105_gating_config *gating_cfg,
u64 cycle_time)
{
struct sja1105_gate_entry *last_e;
struct sja1105_gate_entry *e;
struct list_head *prev;
list_for_each_entry(e, &gating_cfg->entries, list) {
struct sja1105_gate_entry *p;
prev = e->list.prev;
if (prev == &gating_cfg->entries)
continue;
p = list_entry(prev, struct sja1105_gate_entry, list);
p->interval = e->interval - p->interval;
}
last_e = list_last_entry(&gating_cfg->entries,
struct sja1105_gate_entry, list);
if (last_e->list.prev != &gating_cfg->entries)
last_e->interval = cycle_time - last_e->interval;
}
static void sja1105_free_gating_config(struct sja1105_gating_config *gating_cfg)
{
struct sja1105_gate_entry *e, *n;
list_for_each_entry_safe(e, n, &gating_cfg->entries, list) {
list_del(&e->list);
kfree(e);
}
}
static int sja1105_compose_gating_subschedule(struct sja1105_private *priv,
struct netlink_ext_ack *extack)
{
struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg;
struct sja1105_rule *rule;
s64 max_cycle_time = 0;
s64 its_base_time = 0;
int i, rc = 0;
list_for_each_entry(rule, &priv->flow_block.rules, list) {
if (rule->type != SJA1105_RULE_VL)
continue;
if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
continue;
if (max_cycle_time < rule->vl.cycle_time) {
max_cycle_time = rule->vl.cycle_time;
its_base_time = rule->vl.base_time;
}
}
if (!max_cycle_time)
return 0;
dev_dbg(priv->ds->dev, "max_cycle_time %lld its_base_time %lld\n",
max_cycle_time, its_base_time);
sja1105_free_gating_config(gating_cfg);
gating_cfg->base_time = its_base_time;
gating_cfg->cycle_time = max_cycle_time;
gating_cfg->num_entries = 0;
list_for_each_entry(rule, &priv->flow_block.rules, list) {
s64 time;
s64 rbt;
if (rule->type != SJA1105_RULE_VL)
continue;
if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
continue;
/* Calculate the difference between this gating schedule's
* base time, and the base time of the gating schedule with the
* longest cycle time. We call it the relative base time (rbt).
*/
rbt = future_base_time(rule->vl.base_time, rule->vl.cycle_time,
its_base_time);
rbt -= its_base_time;
time = rbt;
for (i = 0; i < rule->vl.num_entries; i++) {
u8 gate_state = rule->vl.entries[i].gate_state;
s64 entry_time = time;
while (entry_time < max_cycle_time) {
rc = sja1105_insert_gate_entry(gating_cfg, rule,
gate_state,
entry_time,
extack);
if (rc)
goto err;
entry_time += rule->vl.cycle_time;
}
time += rule->vl.entries[i].interval;
}
}
sja1105_gating_cfg_time_to_interval(gating_cfg, max_cycle_time);
return 0;
err:
sja1105_free_gating_config(gating_cfg);
return rc;
}
int sja1105_vl_gate(struct sja1105_private *priv, int port,
struct netlink_ext_ack *extack, unsigned long cookie,
struct sja1105_key *key, u32 index, s32 prio,
@ -588,14 +597,12 @@ int sja1105_vl_gate(struct sja1105_private *priv, int port,
if (priv->vlan_state == SJA1105_VLAN_UNAWARE &&
key->type != SJA1105_KEY_VLAN_UNAWARE_VL) {
dev_err(priv->ds->dev, "1: vlan state %d key type %d\n",
priv->vlan_state, key->type);
NL_SET_ERR_MSG_MOD(extack,
"Can only gate based on DMAC");
return -EOPNOTSUPP;
} else if (key->type != SJA1105_KEY_VLAN_AWARE_VL) {
dev_err(priv->ds->dev, "2: vlan state %d key type %d\n",
priv->vlan_state, key->type);
} else if ((priv->vlan_state == SJA1105_VLAN_BEST_EFFORT ||
priv->vlan_state == SJA1105_VLAN_FILTERING_FULL) &&
key->type != SJA1105_KEY_VLAN_AWARE_VL) {
NL_SET_ERR_MSG_MOD(extack,
"Can only gate based on {DMAC, VID, PCP}");
return -EOPNOTSUPP;

View File

@ -6292,6 +6292,7 @@ int bnxt_hwrm_set_coal(struct bnxt *bp)
static void bnxt_hwrm_stat_ctx_free(struct bnxt *bp)
{
struct hwrm_stat_ctx_clr_stats_input req0 = {0};
struct hwrm_stat_ctx_free_input req = {0};
int i;
@ -6301,6 +6302,7 @@ static void bnxt_hwrm_stat_ctx_free(struct bnxt *bp)
if (BNXT_CHIP_TYPE_NITRO_A0(bp))
return;
bnxt_hwrm_cmd_hdr_init(bp, &req0, HWRM_STAT_CTX_CLR_STATS, -1, -1);
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_STAT_CTX_FREE, -1, -1);
mutex_lock(&bp->hwrm_cmd_lock);
@ -6310,7 +6312,11 @@ static void bnxt_hwrm_stat_ctx_free(struct bnxt *bp)
if (cpr->hw_stats_ctx_id != INVALID_STATS_CTX_ID) {
req.stat_ctx_id = cpu_to_le32(cpr->hw_stats_ctx_id);
if (BNXT_FW_MAJ(bp) <= 20) {
req0.stat_ctx_id = req.stat_ctx_id;
_hwrm_send_message(bp, &req0, sizeof(req0),
HWRM_CMD_TIMEOUT);
}
_hwrm_send_message(bp, &req, sizeof(req),
HWRM_CMD_TIMEOUT);
@ -6976,7 +6982,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
bp->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD;
bp->tx_push_thresh = 0;
if (flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED)
if ((flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) &&
BNXT_FW_MAJ(bp) > 217)
bp->tx_push_thresh = BNXT_TX_PUSH_THRESH;
hw_resc->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx);
@ -7240,8 +7247,9 @@ static int __bnxt_hwrm_ver_get(struct bnxt *bp, bool silent)
static int bnxt_hwrm_ver_get(struct bnxt *bp)
{
struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr;
u16 fw_maj, fw_min, fw_bld, fw_rsv;
u32 dev_caps_cfg, hwrm_ver;
int rc;
int rc, len;
bp->hwrm_max_req_len = HWRM_MAX_REQ_LEN;
mutex_lock(&bp->hwrm_cmd_lock);
@ -7273,9 +7281,22 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
resp->hwrm_intf_maj_8b, resp->hwrm_intf_min_8b,
resp->hwrm_intf_upd_8b);
snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "%d.%d.%d.%d",
resp->hwrm_fw_maj_8b, resp->hwrm_fw_min_8b,
resp->hwrm_fw_bld_8b, resp->hwrm_fw_rsvd_8b);
fw_maj = le16_to_cpu(resp->hwrm_fw_major);
if (bp->hwrm_spec_code > 0x10803 && fw_maj) {
fw_min = le16_to_cpu(resp->hwrm_fw_minor);
fw_bld = le16_to_cpu(resp->hwrm_fw_build);
fw_rsv = le16_to_cpu(resp->hwrm_fw_patch);
len = FW_VER_STR_LEN;
} else {
fw_maj = resp->hwrm_fw_maj_8b;
fw_min = resp->hwrm_fw_min_8b;
fw_bld = resp->hwrm_fw_bld_8b;
fw_rsv = resp->hwrm_fw_rsvd_8b;
len = BC_HWRM_STR_LEN;
}
bp->fw_ver_code = BNXT_FW_VER_CODE(fw_maj, fw_min, fw_bld, fw_rsv);
snprintf(bp->fw_ver_str, len, "%d.%d.%d.%d", fw_maj, fw_min, fw_bld,
fw_rsv);
if (strlen(resp->active_pkg_name)) {
int fw_ver_len = strlen(bp->fw_ver_str);
@ -11892,7 +11913,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->ethtool_ops = &bnxt_ethtool_ops;
pci_set_drvdata(pdev, dev);
bnxt_vpd_read_info(bp);
if (BNXT_PF(bp))
bnxt_vpd_read_info(bp);
rc = bnxt_alloc_hwrm_resources(bp);
if (rc)

View File

@ -1746,6 +1746,11 @@ struct bnxt {
#define PHY_VER_STR_LEN (FW_VER_STR_LEN - BC_HWRM_STR_LEN)
char fw_ver_str[FW_VER_STR_LEN];
char hwrm_ver_supp[FW_VER_STR_LEN];
u64 fw_ver_code;
#define BNXT_FW_VER_CODE(maj, min, bld, rsv) \
((u64)(maj) << 48 | (u64)(min) << 32 | (u64)(bld) << 16 | (rsv))
#define BNXT_FW_MAJ(bp) ((bp)->fw_ver_code >> 48)
__be16 vxlan_port;
u8 vxlan_port_cnt;
__le16 vxlan_fw_dst_port_id;

View File

@ -1889,7 +1889,8 @@ static void bnxt_tc_setup_indr_rel(void *cb_priv)
}
static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
struct flow_block_offload *f)
struct flow_block_offload *f, void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
{
struct bnxt_flower_indr_block_cb_priv *cb_priv;
struct flow_block_cb *block_cb;
@ -1907,9 +1908,10 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
cb_priv->bp = bp;
list_add(&cb_priv->list, &bp->tc_indr_block_list);
block_cb = flow_block_cb_alloc(bnxt_tc_setup_indr_block_cb,
cb_priv, cb_priv,
bnxt_tc_setup_indr_rel);
block_cb = flow_indr_block_cb_alloc(bnxt_tc_setup_indr_block_cb,
cb_priv, cb_priv,
bnxt_tc_setup_indr_rel, f,
netdev, data, bp, cleanup);
if (IS_ERR(block_cb)) {
list_del(&cb_priv->list);
kfree(cb_priv);
@ -1930,7 +1932,7 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct bnxt *bp,
if (!block_cb)
return -ENOENT;
flow_block_cb_remove(block_cb, f);
flow_indr_block_cb_remove(block_cb, f);
list_del(&block_cb->driver_list);
break;
default:
@ -1945,14 +1947,17 @@ static bool bnxt_is_netdev_indr_offload(struct net_device *netdev)
}
static int bnxt_tc_setup_indr_cb(struct net_device *netdev, void *cb_priv,
enum tc_setup_type type, void *type_data)
enum tc_setup_type type, void *type_data,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
{
if (!bnxt_is_netdev_indr_offload(netdev))
return -EOPNOTSUPP;
switch (type) {
case TC_SETUP_BLOCK:
return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data);
return bnxt_tc_setup_indr_block(netdev, cb_priv, type_data, data,
cleanup);
default:
break;
}
@ -2074,7 +2079,7 @@ void bnxt_shutdown_tc(struct bnxt *bp)
return;
flow_indr_dev_unregister(bnxt_tc_setup_indr_cb, bp,
bnxt_tc_setup_indr_block_cb);
bnxt_tc_setup_indr_rel);
rhashtable_destroy(&tc_info->flow_table);
rhashtable_destroy(&tc_info->l2_table);
rhashtable_destroy(&tc_info->decap_l2_table);

View File

@ -459,17 +459,6 @@ static inline void bcmgenet_rdma_ring_writel(struct bcmgenet_priv *priv,
genet_dma_ring_regs[r]);
}
static bool bcmgenet_hfb_is_filter_enabled(struct bcmgenet_priv *priv,
u32 f_index)
{
u32 offset;
u32 reg;
offset = HFB_FLT_ENABLE_V3PLUS + (f_index < 32) * sizeof(u32);
reg = bcmgenet_hfb_reg_readl(priv, offset);
return !!(reg & (1 << (f_index % 32)));
}
static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index)
{
u32 offset;
@ -533,19 +522,6 @@ static void bcmgenet_hfb_set_filter_length(struct bcmgenet_priv *priv,
bcmgenet_hfb_reg_writel(priv, reg, offset);
}
static int bcmgenet_hfb_find_unused_filter(struct bcmgenet_priv *priv)
{
u32 f_index;
/* First MAX_NUM_OF_FS_RULES are reserved for Rx NFC filters */
for (f_index = MAX_NUM_OF_FS_RULES;
f_index < priv->hw_params->hfb_filter_cnt; f_index++)
if (!bcmgenet_hfb_is_filter_enabled(priv, f_index))
return f_index;
return -ENOMEM;
}
static int bcmgenet_hfb_validate_mask(void *mask, size_t size)
{
while (size) {
@ -634,8 +610,9 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv,
{
struct ethtool_rx_flow_spec *fs = &rule->fs;
int err = 0, offset = 0, f_length = 0;
u16 val_16, mask_16;
u8 val_8, mask_8;
__be16 val_16;
u16 mask_16;
size_t size;
u32 *f_data;
@ -744,59 +721,6 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv,
return err;
}
/* bcmgenet_hfb_add_filter
*
* Add new filter to Hardware Filter Block to match and direct Rx traffic to
* desired Rx queue.
*
* f_data is an array of unsigned 32-bit integers where each 32-bit integer
* provides filter data for 2 bytes (4 nibbles) of Rx frame:
*
* bits 31:20 - unused
* bit 19 - nibble 0 match enable
* bit 18 - nibble 1 match enable
* bit 17 - nibble 2 match enable
* bit 16 - nibble 3 match enable
* bits 15:12 - nibble 0 data
* bits 11:8 - nibble 1 data
* bits 7:4 - nibble 2 data
* bits 3:0 - nibble 3 data
*
* Example:
* In order to match:
* - Ethernet frame type = 0x0800 (IP)
* - IP version field = 4
* - IP protocol field = 0x11 (UDP)
*
* The following filter is needed:
* u32 hfb_filter_ipv4_udp[] = {
* Rx frame offset 0x00: 0x00000000, 0x00000000, 0x00000000, 0x00000000,
* Rx frame offset 0x08: 0x00000000, 0x00000000, 0x000F0800, 0x00084000,
* Rx frame offset 0x10: 0x00000000, 0x00000000, 0x00000000, 0x00030011,
* };
*
* To add the filter to HFB and direct the traffic to Rx queue 0, call:
* bcmgenet_hfb_add_filter(priv, hfb_filter_ipv4_udp,
* ARRAY_SIZE(hfb_filter_ipv4_udp), 0);
*/
int bcmgenet_hfb_add_filter(struct bcmgenet_priv *priv, u32 *f_data,
u32 f_length, u32 rx_queue)
{
int f_index;
f_index = bcmgenet_hfb_find_unused_filter(priv);
if (f_index < 0)
return -ENOMEM;
if (f_length > priv->hw_params->hfb_filter_size)
return -EINVAL;
bcmgenet_hfb_set_filter(priv, f_data, f_length, rx_queue, f_index);
bcmgenet_hfb_enable_filter(priv, f_index);
return 0;
}
/* bcmgenet_hfb_clear
*
* Clear Hardware Filter Block and disable all filtering.
@ -2118,11 +2042,6 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
if (skb_padto(skb, ETH_ZLEN)) {
ret = NETDEV_TX_OK;
goto out;
}
/* Retain how many bytes will be sent on the wire, without TSB inserted
* by transmit checksum offload
*/
@ -2169,6 +2088,9 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
len_stat = (size << DMA_BUFLENGTH_SHIFT) |
(priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT);
/* Note: if we ever change from DMA_TX_APPEND_CRC below we
* will need to restore software padding of "runt" packets
*/
if (!i) {
len_stat |= DMA_TX_APPEND_CRC | DMA_SOP;
if (skb->ip_summed == CHECKSUM_PARTIAL)

View File

@ -18168,8 +18168,8 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
rtnl_lock();
/* We probably don't have netdev yet */
if (!netdev || !netif_running(netdev))
/* Could be second call or maybe we don't have netdev yet */
if (!netdev || tp->pcierr_recovery || !netif_running(netdev))
goto done;
/* We needn't recover from permanent error */

View File

@ -2558,7 +2558,7 @@ static int macb_open(struct net_device *dev)
err = macb_phylink_connect(bp);
if (err)
goto napi_exit;
goto reset_hw;
netif_tx_start_all_queues(dev);
@ -2567,9 +2567,11 @@ static int macb_open(struct net_device *dev)
return 0;
napi_exit:
reset_hw:
macb_reset_hw(bp);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
napi_disable(&queue->napi);
macb_free_consistent(bp);
pm_exit:
pm_runtime_put_sync(&bp->pdev->dev);
return err;
@ -3760,15 +3762,9 @@ static int macb_init(struct platform_device *pdev)
static struct sifive_fu540_macb_mgmt *mgmt;
/* Initialize and start the Receiver and Transmit subsystems */
static int at91ether_start(struct net_device *dev)
static int at91ether_alloc_coherent(struct macb *lp)
{
struct macb *lp = netdev_priv(dev);
struct macb_queue *q = &lp->queues[0];
struct macb_dma_desc *desc;
dma_addr_t addr;
u32 ctl;
int i;
q->rx_ring = dma_alloc_coherent(&lp->pdev->dev,
(AT91ETHER_MAX_RX_DESCR *
@ -3790,6 +3786,43 @@ static int at91ether_start(struct net_device *dev)
return -ENOMEM;
}
return 0;
}
static void at91ether_free_coherent(struct macb *lp)
{
struct macb_queue *q = &lp->queues[0];
if (q->rx_ring) {
dma_free_coherent(&lp->pdev->dev,
AT91ETHER_MAX_RX_DESCR *
macb_dma_desc_get_size(lp),
q->rx_ring, q->rx_ring_dma);
q->rx_ring = NULL;
}
if (q->rx_buffers) {
dma_free_coherent(&lp->pdev->dev,
AT91ETHER_MAX_RX_DESCR *
AT91ETHER_MAX_RBUFF_SZ,
q->rx_buffers, q->rx_buffers_dma);
q->rx_buffers = NULL;
}
}
/* Initialize and start the Receiver and Transmit subsystems */
static int at91ether_start(struct macb *lp)
{
struct macb_queue *q = &lp->queues[0];
struct macb_dma_desc *desc;
dma_addr_t addr;
u32 ctl;
int i, ret;
ret = at91ether_alloc_coherent(lp);
if (ret)
return ret;
addr = q->rx_buffers_dma;
for (i = 0; i < AT91ETHER_MAX_RX_DESCR; i++) {
desc = macb_rx_desc(q, i);
@ -3811,9 +3844,39 @@ static int at91ether_start(struct net_device *dev)
ctl = macb_readl(lp, NCR);
macb_writel(lp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE));
/* Enable MAC interrupts */
macb_writel(lp, IER, MACB_BIT(RCOMP) |
MACB_BIT(RXUBR) |
MACB_BIT(ISR_TUND) |
MACB_BIT(ISR_RLE) |
MACB_BIT(TCOMP) |
MACB_BIT(ISR_ROVR) |
MACB_BIT(HRESP));
return 0;
}
static void at91ether_stop(struct macb *lp)
{
u32 ctl;
/* Disable MAC interrupts */
macb_writel(lp, IDR, MACB_BIT(RCOMP) |
MACB_BIT(RXUBR) |
MACB_BIT(ISR_TUND) |
MACB_BIT(ISR_RLE) |
MACB_BIT(TCOMP) |
MACB_BIT(ISR_ROVR) |
MACB_BIT(HRESP));
/* Disable Receiver and Transmitter */
ctl = macb_readl(lp, NCR);
macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE)));
/* Free resources. */
at91ether_free_coherent(lp);
}
/* Open the ethernet interface */
static int at91ether_open(struct net_device *dev)
{
@ -3833,63 +3896,36 @@ static int at91ether_open(struct net_device *dev)
macb_set_hwaddr(lp);
ret = at91ether_start(dev);
ret = at91ether_start(lp);
if (ret)
return ret;
/* Enable MAC interrupts */
macb_writel(lp, IER, MACB_BIT(RCOMP) |
MACB_BIT(RXUBR) |
MACB_BIT(ISR_TUND) |
MACB_BIT(ISR_RLE) |
MACB_BIT(TCOMP) |
MACB_BIT(ISR_ROVR) |
MACB_BIT(HRESP));
goto pm_exit;
ret = macb_phylink_connect(lp);
if (ret)
return ret;
goto stop;
netif_start_queue(dev);
return 0;
stop:
at91ether_stop(lp);
pm_exit:
pm_runtime_put_sync(&lp->pdev->dev);
return ret;
}
/* Close the interface */
static int at91ether_close(struct net_device *dev)
{
struct macb *lp = netdev_priv(dev);
struct macb_queue *q = &lp->queues[0];
u32 ctl;
/* Disable Receiver and Transmitter */
ctl = macb_readl(lp, NCR);
macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE)));
/* Disable MAC interrupts */
macb_writel(lp, IDR, MACB_BIT(RCOMP) |
MACB_BIT(RXUBR) |
MACB_BIT(ISR_TUND) |
MACB_BIT(ISR_RLE) |
MACB_BIT(TCOMP) |
MACB_BIT(ISR_ROVR) |
MACB_BIT(HRESP));
netif_stop_queue(dev);
phylink_stop(lp->phylink);
phylink_disconnect_phy(lp->phylink);
dma_free_coherent(&lp->pdev->dev,
AT91ETHER_MAX_RX_DESCR *
macb_dma_desc_get_size(lp),
q->rx_ring, q->rx_ring_dma);
q->rx_ring = NULL;
dma_free_coherent(&lp->pdev->dev,
AT91ETHER_MAX_RX_DESCR * AT91ETHER_MAX_RBUFF_SZ,
q->rx_buffers, q->rx_buffers_dma);
q->rx_buffers = NULL;
at91ether_stop(lp);
return pm_runtime_put(&lp->pdev->dev);
}

View File

@ -1975,7 +1975,6 @@ int cudbg_collect_dump_context(struct cudbg_init *pdbg_init,
u8 mem_type[CTXT_INGRESS + 1] = { 0 };
struct cudbg_buffer temp_buff = { 0 };
struct cudbg_ch_cntxt *buff;
u64 *dst_off, *src_off;
u8 *ctx_buf;
u8 i, k;
int rc;
@ -2044,8 +2043,11 @@ int cudbg_collect_dump_context(struct cudbg_init *pdbg_init,
}
for (j = 0; j < max_ctx_qid; j++) {
__be64 *dst_off;
u64 *src_off;
src_off = (u64 *)(ctx_buf + j * SGE_CTXT_SIZE);
dst_off = (u64 *)buff->data;
dst_off = (__be64 *)buff->data;
/* The data is stored in 64-bit cpu order. Convert it
* to big endian before parsing.

View File

@ -136,6 +136,9 @@ static inline __u8 bitswap_1(unsigned char val)
((val & 0x02) << 5) |
((val & 0x01) << 7);
}
extern const char * const dcb_ver_array[];
#define CXGB4_DCB_ENABLED true
#else /* !CONFIG_CHELSIO_T4_DCB */

View File

@ -2379,7 +2379,6 @@ static const struct file_operations rss_vf_config_debugfs_fops = {
};
#ifdef CONFIG_CHELSIO_T4_DCB
extern char *dcb_ver_array[];
/* Data Center Briging information for each port.
*/

View File

@ -588,7 +588,7 @@ static void fw_caps_to_lmm(enum fw_port_type port_type,
/**
* lmm_to_fw_caps - translate ethtool Link Mode Mask to Firmware
* capabilities
* @et_lmm: ethtool Link Mode Mask
* @link_mode_mask: ethtool Link Mode Mask
*
* Translate ethtool Link Mode Mask into a Firmware Port capabilities
* value.

View File

@ -165,6 +165,9 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f,
unsigned int tid, bool dip, bool sip, bool dp,
bool sp)
{
u8 *nat_lp = (u8 *)&f->fs.nat_lport;
u8 *nat_fp = (u8 *)&f->fs.nat_fport;
if (dip) {
if (f->fs.type) {
set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W,
@ -236,8 +239,9 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f,
}
set_tcb_field(adap, f, tid, TCB_PDU_HDR_LEN_W, WORD_MASK,
(dp ? f->fs.nat_lport : 0) |
(sp ? f->fs.nat_fport << 16 : 0), 1);
(dp ? (nat_lp[1] | nat_lp[0] << 8) : 0) |
(sp ? (nat_fp[1] << 16 | nat_fp[0] << 24) : 0),
1);
}
/* Validate filter spec against configuration done on the card. */
@ -909,6 +913,9 @@ int set_filter_wr(struct adapter *adapter, int fidx)
fwr->fpm = htons(f->fs.mask.fport);
if (adapter->params.filter2_wr_support) {
u8 *nat_lp = (u8 *)&f->fs.nat_lport;
u8 *nat_fp = (u8 *)&f->fs.nat_fport;
fwr->natmode_to_ulp_type =
FW_FILTER2_WR_ULP_TYPE_V(f->fs.nat_mode ?
ULP_MODE_TCPDDP :
@ -916,8 +923,8 @@ int set_filter_wr(struct adapter *adapter, int fidx)
FW_FILTER2_WR_NATMODE_V(f->fs.nat_mode);
memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip));
memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip));
fwr->newlport = htons(f->fs.nat_lport);
fwr->newfport = htons(f->fs.nat_fport);
fwr->newlport = htons(nat_lp[1] | nat_lp[0] << 8);
fwr->newfport = htons(nat_fp[1] | nat_fp[0] << 8);
}
/* Mark the filter as "pending" and ship off the Filter Work Request.
@ -1105,16 +1112,16 @@ static bool is_addr_all_mask(u8 *ipmask, int family)
struct in_addr *addr;
addr = (struct in_addr *)ipmask;
if (addr->s_addr == 0xffffffff)
if (ntohl(addr->s_addr) == 0xffffffff)
return true;
} else if (family == AF_INET6) {
struct in6_addr *addr6;
addr6 = (struct in6_addr *)ipmask;
if (addr6->s6_addr32[0] == 0xffffffff &&
addr6->s6_addr32[1] == 0xffffffff &&
addr6->s6_addr32[2] == 0xffffffff &&
addr6->s6_addr32[3] == 0xffffffff)
if (ntohl(addr6->s6_addr32[0]) == 0xffffffff &&
ntohl(addr6->s6_addr32[1]) == 0xffffffff &&
ntohl(addr6->s6_addr32[2]) == 0xffffffff &&
ntohl(addr6->s6_addr32[3]) == 0xffffffff)
return true;
}
return false;

View File

@ -449,7 +449,7 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok)
* or -1
* @addr: the new MAC address value
* @persist: whether a new MAC allocation should be persistent
* @add_smt: if true also add the address to the HW SMT
* @smt_idx: the destination to store the new SMT index.
*
* Modifies an MPS filter and sets it to the new MAC address if
* @tcam_idx >= 0, or adds the MAC address to a new filter if
@ -1615,6 +1615,7 @@ static int tid_init(struct tid_info *t)
* @stid: the server TID
* @sip: local IP address to bind server to
* @sport: the server's TCP port
* @vlan: the VLAN header information
* @queue: queue to direct messages from this server to
*
* Create an IP server for the given port and address.
@ -2609,7 +2610,7 @@ int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
/* Clear out filter specifications */
memset(&f->fs, 0, sizeof(struct ch_filter_specification));
f->fs.val.lport = cpu_to_be16(sport);
f->fs.val.lport = be16_to_cpu(sport);
f->fs.mask.lport = ~0;
val = (u8 *)&sip;
if ((val[0] | val[1] | val[2] | val[3]) != 0) {
@ -5377,10 +5378,10 @@ static inline bool is_x_10g_port(const struct link_config *lc)
static int cfg_queues(struct adapter *adap)
{
u32 avail_qsets, avail_eth_qsets, avail_uld_qsets;
u32 i, n10g = 0, qidx = 0, n1g = 0;
u32 ncpus = num_online_cpus();
u32 niqflint, neq, num_ulds;
struct sge *s = &adap->sge;
u32 i, n10g = 0, qidx = 0;
u32 q10g = 0, q1g;
/* Reduce memory usage in kdump environment, disable all offload. */
@ -5426,7 +5427,6 @@ static int cfg_queues(struct adapter *adap)
if (n10g)
q10g = (avail_eth_qsets - (adap->params.nports - n10g)) / n10g;
n1g = adap->params.nports - n10g;
#ifdef CONFIG_CHELSIO_T4_DCB
/* For Data Center Bridging support we need to be able to support up
* to 8 Traffic Priorities; each of which will be assigned to its
@ -5444,7 +5444,8 @@ static int cfg_queues(struct adapter *adap)
else
q10g = max(8U, q10g);
while ((q10g * n10g) > (avail_eth_qsets - n1g * q1g))
while ((q10g * n10g) >
(avail_eth_qsets - (adap->params.nports - n10g) * q1g))
q10g--;
#else /* !CONFIG_CHELSIO_T4_DCB */

View File

@ -194,6 +194,7 @@ int cxgb4_ptp_redirect_rx_packet(struct adapter *adapter, struct port_info *pi)
}
/**
* cxgb4_ptp_adjfreq - Adjust frequency of PHC cycle counter
* @ptp: ptp clock structure
* @ppb: Desired frequency change in parts per billion
*
@ -229,7 +230,7 @@ static int cxgb4_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
/**
* cxgb4_ptp_fineadjtime - Shift the time of the hardware clock
* @ptp: ptp clock structure
* @adapter: board private structure
* @delta: Desired change in nanoseconds
*
* Adjust the timer by resetting the timecounter structure.

View File

@ -58,10 +58,6 @@ static struct ch_tc_pedit_fields pedits[] = {
PEDIT_FIELDS(IP6_, DST_63_32, 4, nat_lip, 4),
PEDIT_FIELDS(IP6_, DST_95_64, 4, nat_lip, 8),
PEDIT_FIELDS(IP6_, DST_127_96, 4, nat_lip, 12),
PEDIT_FIELDS(TCP_, SPORT, 2, nat_fport, 0),
PEDIT_FIELDS(TCP_, DPORT, 2, nat_lport, 0),
PEDIT_FIELDS(UDP_, SPORT, 2, nat_fport, 0),
PEDIT_FIELDS(UDP_, DPORT, 2, nat_lport, 0),
};
static struct ch_tc_flower_entry *allocate_flower_entry(void)
@ -156,14 +152,14 @@ static void cxgb4_process_flow_match(struct net_device *dev,
struct flow_match_ports match;
flow_rule_match_ports(rule, &match);
fs->val.lport = cpu_to_be16(match.key->dst);
fs->mask.lport = cpu_to_be16(match.mask->dst);
fs->val.fport = cpu_to_be16(match.key->src);
fs->mask.fport = cpu_to_be16(match.mask->src);
fs->val.lport = be16_to_cpu(match.key->dst);
fs->mask.lport = be16_to_cpu(match.mask->dst);
fs->val.fport = be16_to_cpu(match.key->src);
fs->mask.fport = be16_to_cpu(match.mask->src);
/* also initialize nat_lport/fport to same values */
fs->nat_lport = cpu_to_be16(match.key->dst);
fs->nat_fport = cpu_to_be16(match.key->src);
fs->nat_lport = fs->val.lport;
fs->nat_fport = fs->val.fport;
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
@ -354,12 +350,9 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
switch (offset) {
case PEDIT_TCP_SPORT_DPORT:
if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
offload_pedit(fs, cpu_to_be32(val) >> 16,
cpu_to_be32(mask) >> 16,
TCP_SPORT);
fs->nat_fport = val;
else
offload_pedit(fs, cpu_to_be32(val),
cpu_to_be32(mask), TCP_DPORT);
fs->nat_lport = val >> 16;
}
fs->nat_mode = NAT_MODE_ALL;
break;
@ -367,12 +360,9 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
switch (offset) {
case PEDIT_UDP_SPORT_DPORT:
if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
offload_pedit(fs, cpu_to_be32(val) >> 16,
cpu_to_be32(mask) >> 16,
UDP_SPORT);
fs->nat_fport = val;
else
offload_pedit(fs, cpu_to_be32(val),
cpu_to_be32(mask), UDP_DPORT);
fs->nat_lport = val >> 16;
}
fs->nat_mode = NAT_MODE_ALL;
}

View File

@ -48,7 +48,7 @@ static int fill_match_fields(struct adapter *adap,
bool next_header)
{
unsigned int i, j;
u32 val, mask;
__be32 val, mask;
int off, err;
bool found;
@ -228,7 +228,7 @@ int cxgb4_config_knode(struct net_device *dev, struct tc_cls_u32_offload *cls)
const struct cxgb4_next_header *next;
bool found = false;
unsigned int i, j;
u32 val, mask;
__be32 val, mask;
int off;
if (t->table[link_uhtid - 1].link_handle) {
@ -242,10 +242,10 @@ int cxgb4_config_knode(struct net_device *dev, struct tc_cls_u32_offload *cls)
/* Try to find matches that allow jumps to next header. */
for (i = 0; next[i].jump; i++) {
if (next[i].offoff != cls->knode.sel->offoff ||
next[i].shift != cls->knode.sel->offshift ||
next[i].mask != cls->knode.sel->offmask ||
next[i].offset != cls->knode.sel->off)
if (next[i].sel.offoff != cls->knode.sel->offoff ||
next[i].sel.offshift != cls->knode.sel->offshift ||
next[i].sel.offmask != cls->knode.sel->offmask ||
next[i].sel.off != cls->knode.sel->off)
continue;
/* Found a possible candidate. Find a key that
@ -257,9 +257,9 @@ int cxgb4_config_knode(struct net_device *dev, struct tc_cls_u32_offload *cls)
val = cls->knode.sel->keys[j].val;
mask = cls->knode.sel->keys[j].mask;
if (next[i].match_off == off &&
next[i].match_val == val &&
next[i].match_mask == mask) {
if (next[i].key.off == off &&
next[i].key.val == val &&
next[i].key.mask == mask) {
found = true;
break;
}

View File

@ -38,12 +38,12 @@
struct cxgb4_match_field {
int off; /* Offset from the beginning of the header to match */
/* Fill the value/mask pair in the spec if matched */
int (*val)(struct ch_filter_specification *f, u32 val, u32 mask);
int (*val)(struct ch_filter_specification *f, __be32 val, __be32 mask);
};
/* IPv4 match fields */
static inline int cxgb4_fill_ipv4_tos(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
f->val.tos = (ntohl(val) >> 16) & 0x000000FF;
f->mask.tos = (ntohl(mask) >> 16) & 0x000000FF;
@ -52,7 +52,7 @@ static inline int cxgb4_fill_ipv4_tos(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv4_frag(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
u32 mask_val;
u8 frag_val;
@ -74,7 +74,7 @@ static inline int cxgb4_fill_ipv4_frag(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv4_proto(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
f->val.proto = (ntohl(val) >> 16) & 0x000000FF;
f->mask.proto = (ntohl(mask) >> 16) & 0x000000FF;
@ -83,7 +83,7 @@ static inline int cxgb4_fill_ipv4_proto(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv4_src_ip(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.fip[0], &val, sizeof(u32));
memcpy(&f->mask.fip[0], &mask, sizeof(u32));
@ -92,7 +92,7 @@ static inline int cxgb4_fill_ipv4_src_ip(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv4_dst_ip(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.lip[0], &val, sizeof(u32));
memcpy(&f->mask.lip[0], &mask, sizeof(u32));
@ -111,7 +111,7 @@ static const struct cxgb4_match_field cxgb4_ipv4_fields[] = {
/* IPv6 match fields */
static inline int cxgb4_fill_ipv6_tos(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
f->val.tos = (ntohl(val) >> 20) & 0x000000FF;
f->mask.tos = (ntohl(mask) >> 20) & 0x000000FF;
@ -120,7 +120,7 @@ static inline int cxgb4_fill_ipv6_tos(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv6_proto(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
f->val.proto = (ntohl(val) >> 8) & 0x000000FF;
f->mask.proto = (ntohl(mask) >> 8) & 0x000000FF;
@ -129,7 +129,7 @@ static inline int cxgb4_fill_ipv6_proto(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv6_src_ip0(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.fip[0], &val, sizeof(u32));
memcpy(&f->mask.fip[0], &mask, sizeof(u32));
@ -138,7 +138,7 @@ static inline int cxgb4_fill_ipv6_src_ip0(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv6_src_ip1(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.fip[4], &val, sizeof(u32));
memcpy(&f->mask.fip[4], &mask, sizeof(u32));
@ -147,7 +147,7 @@ static inline int cxgb4_fill_ipv6_src_ip1(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv6_src_ip2(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.fip[8], &val, sizeof(u32));
memcpy(&f->mask.fip[8], &mask, sizeof(u32));
@ -156,7 +156,7 @@ static inline int cxgb4_fill_ipv6_src_ip2(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv6_src_ip3(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.fip[12], &val, sizeof(u32));
memcpy(&f->mask.fip[12], &mask, sizeof(u32));
@ -165,7 +165,7 @@ static inline int cxgb4_fill_ipv6_src_ip3(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv6_dst_ip0(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.lip[0], &val, sizeof(u32));
memcpy(&f->mask.lip[0], &mask, sizeof(u32));
@ -174,7 +174,7 @@ static inline int cxgb4_fill_ipv6_dst_ip0(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv6_dst_ip1(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.lip[4], &val, sizeof(u32));
memcpy(&f->mask.lip[4], &mask, sizeof(u32));
@ -183,7 +183,7 @@ static inline int cxgb4_fill_ipv6_dst_ip1(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv6_dst_ip2(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.lip[8], &val, sizeof(u32));
memcpy(&f->mask.lip[8], &mask, sizeof(u32));
@ -192,7 +192,7 @@ static inline int cxgb4_fill_ipv6_dst_ip2(struct ch_filter_specification *f,
}
static inline int cxgb4_fill_ipv6_dst_ip3(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
memcpy(&f->val.lip[12], &val, sizeof(u32));
memcpy(&f->mask.lip[12], &mask, sizeof(u32));
@ -216,7 +216,7 @@ static const struct cxgb4_match_field cxgb4_ipv6_fields[] = {
/* TCP/UDP match */
static inline int cxgb4_fill_l4_ports(struct ch_filter_specification *f,
u32 val, u32 mask)
__be32 val, __be32 mask)
{
f->val.fport = ntohl(val) >> 16;
f->mask.fport = ntohl(mask) >> 16;
@ -237,19 +237,13 @@ static const struct cxgb4_match_field cxgb4_udp_fields[] = {
};
struct cxgb4_next_header {
unsigned int offset; /* Offset to next header */
/* offset, shift, and mask added to offset above
/* Offset, shift, and mask added to beginning of the header
* to get to next header. Useful when using a header
* field's value to jump to next header such as IHL field
* in IPv4 header.
*/
unsigned int offoff;
u32 shift;
u32 mask;
/* match criteria to make this jump */
unsigned int match_off;
u32 match_val;
u32 match_mask;
struct tc_u32_sel sel;
struct tc_u32_key key;
/* location of jump to make */
const struct cxgb4_match_field *jump;
};
@ -258,26 +252,74 @@ struct cxgb4_next_header {
* IPv4 header.
*/
static const struct cxgb4_next_header cxgb4_ipv4_jumps[] = {
{ .offset = 0, .offoff = 0, .shift = 6, .mask = 0xF,
.match_off = 8, .match_val = 0x600, .match_mask = 0xFF00,
.jump = cxgb4_tcp_fields },
{ .offset = 0, .offoff = 0, .shift = 6, .mask = 0xF,
.match_off = 8, .match_val = 0x1100, .match_mask = 0xFF00,
.jump = cxgb4_udp_fields },
{ .jump = NULL }
{
/* TCP Jump */
.sel = {
.off = 0,
.offoff = 0,
.offshift = 6,
.offmask = cpu_to_be16(0x0f00),
},
.key = {
.off = 8,
.val = cpu_to_be32(0x00060000),
.mask = cpu_to_be32(0x00ff0000),
},
.jump = cxgb4_tcp_fields,
},
{
/* UDP Jump */
.sel = {
.off = 0,
.offoff = 0,
.offshift = 6,
.offmask = cpu_to_be16(0x0f00),
},
.key = {
.off = 8,
.val = cpu_to_be32(0x00110000),
.mask = cpu_to_be32(0x00ff0000),
},
.jump = cxgb4_udp_fields,
},
{ .jump = NULL },
};
/* Accept a rule with a jump directly past the 40 Bytes of IPv6 fixed header
* to get to transport layer header.
*/
static const struct cxgb4_next_header cxgb4_ipv6_jumps[] = {
{ .offset = 0x28, .offoff = 0, .shift = 0, .mask = 0,
.match_off = 4, .match_val = 0x60000, .match_mask = 0xFF0000,
.jump = cxgb4_tcp_fields },
{ .offset = 0x28, .offoff = 0, .shift = 0, .mask = 0,
.match_off = 4, .match_val = 0x110000, .match_mask = 0xFF0000,
.jump = cxgb4_udp_fields },
{ .jump = NULL }
{
/* TCP Jump */
.sel = {
.off = 40,
.offoff = 0,
.offshift = 0,
.offmask = 0,
},
.key = {
.off = 4,
.val = cpu_to_be32(0x00000600),
.mask = cpu_to_be32(0x0000ff00),
},
.jump = cxgb4_tcp_fields,
},
{
/* UDP Jump */
.sel = {
.off = 40,
.offoff = 0,
.offshift = 0,
.offmask = 0,
},
.key = {
.off = 4,
.val = cpu_to_be32(0x00001100),
.mask = cpu_to_be32(0x0000ff00),
},
.jump = cxgb4_udp_fields,
},
{ .jump = NULL },
};
struct cxgb4_link {

View File

@ -502,41 +502,20 @@ u64 cxgb4_select_ntuple(struct net_device *dev,
}
EXPORT_SYMBOL(cxgb4_select_ntuple);
/*
* Called when address resolution fails for an L2T entry to handle packets
* on the arpq head. If a packet specifies a failure handler it is invoked,
* otherwise the packet is sent to the device.
*/
static void handle_failed_resolution(struct adapter *adap, struct l2t_entry *e)
{
struct sk_buff *skb;
while ((skb = __skb_dequeue(&e->arpq)) != NULL) {
const struct l2t_skb_cb *cb = L2T_SKB_CB(skb);
spin_unlock(&e->lock);
if (cb->arp_err_handler)
cb->arp_err_handler(cb->handle, skb);
else
t4_ofld_send(adap, skb);
spin_lock(&e->lock);
}
}
/*
* Called when the host's neighbor layer makes a change to some entry that is
* loaded into the HW L2 table.
*/
void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
{
struct l2t_entry *e;
struct sk_buff_head *arpq = NULL;
struct l2t_data *d = adap->l2t;
unsigned int addr_len = neigh->tbl->key_len;
u32 *addr = (u32 *) neigh->primary_key;
int ifidx = neigh->dev->ifindex;
int hash = addr_hash(d, addr, addr_len, ifidx);
int hash, ifidx = neigh->dev->ifindex;
struct sk_buff_head *arpq = NULL;
struct l2t_data *d = adap->l2t;
struct l2t_entry *e;
hash = addr_hash(d, addr, addr_len, ifidx);
read_lock_bh(&d->lock);
for (e = d->l2tab[hash].first; e; e = e->next)
if (!addreq(e, addr) && e->ifindex == ifidx) {
@ -569,8 +548,25 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
write_l2e(adap, e, 0);
}
if (arpq)
handle_failed_resolution(adap, e);
if (arpq) {
struct sk_buff *skb;
/* Called when address resolution fails for an L2T
* entry to handle packets on the arpq head. If a
* packet specifies a failure handler it is invoked,
* otherwise the packet is sent to the device.
*/
while ((skb = __skb_dequeue(&e->arpq)) != NULL) {
const struct l2t_skb_cb *cb = L2T_SKB_CB(skb);
spin_unlock(&e->lock);
if (cb->arp_err_handler)
cb->arp_err_handler(cb->handle, skb);
else
t4_ofld_send(adap, skb);
spin_lock(&e->lock);
}
}
spin_unlock_bh(&e->lock);
}
@ -613,6 +609,7 @@ struct l2t_entry *t4_l2t_alloc_switching(struct adapter *adap, u16 vlan,
}
/**
* cxgb4_l2t_alloc_switching - Allocates an L2T entry for switch filters
* @dev: net_device pointer
* @vlan: VLAN Id
* @port: Associated port

View File

@ -598,7 +598,7 @@ struct sched_class *cxgb4_sched_class_alloc(struct net_device *dev,
/**
* cxgb4_sched_class_free - free a scheduling class
* @dev: net_device pointer
* @e: scheduling class
* @classid: scheduling class id to free
*
* Frees a scheduling class if there are no users.
*/

View File

@ -302,7 +302,7 @@ static void deferred_unmap_destructor(struct sk_buff *skb)
/**
* free_tx_desc - reclaims Tx descriptors and their buffers
* @adapter: the adapter
* @adap: the adapter
* @q: the Tx queue to reclaim descriptors from
* @n: the number of descriptors to reclaim
* @unmap: whether the buffers should be unmapped for DMA
@ -722,6 +722,7 @@ static inline unsigned int flits_to_desc(unsigned int n)
/**
* is_eth_imm - can an Ethernet packet be sent as immediate data?
* @skb: the packet
* @chip_ver: chip version
*
* Returns whether an Ethernet packet is small enough to fit as
* immediate data. Return value corresponds to headroom required.
@ -749,6 +750,7 @@ static inline int is_eth_imm(const struct sk_buff *skb, unsigned int chip_ver)
/**
* calc_tx_flits - calculate the number of flits for a packet Tx WR
* @skb: the packet
* @chip_ver: chip version
*
* Returns the number of flits needed for a Tx WR for the given Ethernet
* packet, including the needed WR and CPL headers.
@ -804,6 +806,7 @@ static inline unsigned int calc_tx_flits(const struct sk_buff *skb,
/**
* calc_tx_descs - calculate the number of Tx descriptors for a packet
* @skb: the packet
* @chip_ver: chip version
*
* Returns the number of Tx descriptors needed for the given Ethernet
* packet, including the needed WR and CPL headers.
@ -1425,12 +1428,10 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
qidx = skb_get_queue_mapping(skb);
if (ptp_enabled) {
spin_lock(&adap->ptp_lock);
if (!(adap->ptp_tx_skb)) {
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
adap->ptp_tx_skb = skb_get(skb);
} else {
spin_unlock(&adap->ptp_lock);
goto out_free;
}
q = &adap->sge.ptptxq;
@ -1444,11 +1445,8 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
#ifdef CONFIG_CHELSIO_T4_FCOE
ret = cxgb_fcoe_offload(skb, adap, pi, &cntrl);
if (unlikely(ret == -ENOTSUPP)) {
if (ptp_enabled)
spin_unlock(&adap->ptp_lock);
if (unlikely(ret == -EOPNOTSUPP))
goto out_free;
}
#endif /* CONFIG_CHELSIO_T4_FCOE */
chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
@ -1461,8 +1459,6 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
dev_err(adap->pdev_dev,
"%s: Tx ring %u full while queue awake!\n",
dev->name, qidx);
if (ptp_enabled)
spin_unlock(&adap->ptp_lock);
return NETDEV_TX_BUSY;
}
@ -1481,8 +1477,6 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
unlikely(cxgb4_map_skb(adap->pdev_dev, skb, sgl_sdesc->addr) < 0)) {
memset(sgl_sdesc->addr, 0, sizeof(sgl_sdesc->addr));
q->mapping_err++;
if (ptp_enabled)
spin_unlock(&adap->ptp_lock);
goto out_free;
}
@ -1533,8 +1527,7 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
if (iph->version == 4) {
iph->check = 0;
iph->tot_len = 0;
iph->check = (u16)(~ip_fast_csum((u8 *)iph,
iph->ihl));
iph->check = ~ip_fast_csum((u8 *)iph, iph->ihl);
}
if (skb->ip_summed == CHECKSUM_PARTIAL)
cntrl = hwcsum(adap->params.chip, skb);
@ -1630,8 +1623,6 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
txq_advance(&q->q, ndesc);
cxgb4_ring_tx_db(adap, &q->q, ndesc);
if (ptp_enabled)
spin_unlock(&adap->ptp_lock);
return NETDEV_TX_OK;
out_free:
@ -2377,6 +2368,16 @@ netdev_tx_t t4_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(qid >= pi->nqsets))
return cxgb4_ethofld_xmit(skb, dev);
if (is_ptp_enabled(skb, dev)) {
struct adapter *adap = netdev2adap(dev);
netdev_tx_t ret;
spin_lock(&adap->ptp_lock);
ret = cxgb4_eth_xmit(skb, dev);
spin_unlock(&adap->ptp_lock);
return ret;
}
return cxgb4_eth_xmit(skb, dev);
}
@ -2410,9 +2411,9 @@ static void eosw_txq_flush_pending_skbs(struct sge_eosw_txq *eosw_txq)
/**
* cxgb4_ethofld_send_flowc - Send ETHOFLD flowc request to bind eotid to tc.
* @dev - netdevice
* @eotid - ETHOFLD tid to bind/unbind
* @tc - traffic class. If set to FW_SCHED_CLS_NONE, then unbinds the @eotid
* @dev: netdevice
* @eotid: ETHOFLD tid to bind/unbind
* @tc: traffic class. If set to FW_SCHED_CLS_NONE, then unbinds the @eotid
*
* Send a FLOWC work request to bind an ETHOFLD TID to a traffic class.
* If @tc is set to FW_SCHED_CLS_NONE, then the @eotid is unbound from
@ -2691,7 +2692,6 @@ static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb)
/**
* txq_stop_maperr - stop a Tx queue due to I/O MMU exhaustion
* @adap: the adapter
* @q: the queue to stop
*
* Mark a Tx queue stopped due to I/O MMU exhaustion and resulting
@ -3286,7 +3286,7 @@ enum {
/**
* t4_systim_to_hwstamp - read hardware time stamp
* @adap: the adapter
* @adapter: the adapter
* @skb: the packet
*
* Read Time Stamp from MPS packet and insert in skb which
@ -3313,15 +3313,16 @@ static noinline int t4_systim_to_hwstamp(struct adapter *adapter,
hwtstamps = skb_hwtstamps(skb);
memset(hwtstamps, 0, sizeof(*hwtstamps));
hwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(*((u64 *)data)));
hwtstamps->hwtstamp = ns_to_ktime(get_unaligned_be64(data));
return RX_PTP_PKT_SUC;
}
/**
* t4_rx_hststamp - Recv PTP Event Message
* @adap: the adapter
* @adapter: the adapter
* @rsp: the response queue descriptor holding the RX_PKT message
* @rxq: the response queue holding the RX_PKT message
* @skb: the packet
*
* PTP enabled and MPS packet, read HW timestamp
@ -3345,7 +3346,7 @@ static int t4_rx_hststamp(struct adapter *adapter, const __be64 *rsp,
/**
* t4_tx_hststamp - Loopback PTP Transmit Event Message
* @adap: the adapter
* @adapter: the adapter
* @skb: the packet
* @dev: the ingress net device
*

View File

@ -103,6 +103,7 @@ static void t4_smte_free(struct smt_entry *e)
}
/**
* cxgb4_smt_release - Release SMT entry
* @e: smt entry to release
*
* Releases ref count and frees up an smt entry from SMT table
@ -231,6 +232,7 @@ static struct smt_entry *t4_smt_alloc_switching(struct adapter *adap, u16 pfvf,
}
/**
* cxgb4_smt_alloc_switching - Allocates an SMT entry for switch filters.
* @dev: net_device pointer
* @smac: MAC address to add to SMT
* Returns pointer to the SMT entry created

View File

@ -3163,7 +3163,7 @@ int t4_get_tp_version(struct adapter *adapter, u32 *vers)
/**
* t4_get_exprom_version - return the Expansion ROM version (if any)
* @adapter: the adapter
* @adap: the adapter
* @vers: where to place the version
*
* Reads the Expansion ROM header from FLASH and returns the version
@ -5310,7 +5310,7 @@ static unsigned int t4_use_ldst(struct adapter *adap)
* @cmd: TP fw ldst address space type
* @vals: where the indirect register values are stored/written
* @nregs: how many indirect registers to read/write
* @start_idx: index of first indirect register to read/write
* @start_index: index of first indirect register to read/write
* @rw: Read (1) or Write (0)
* @sleep_ok: if true we may sleep while awaiting command completion
*
@ -6115,7 +6115,7 @@ void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
/**
* compute_mps_bg_map - compute the MPS Buffer Group Map for a Port
* @adap: the adapter
* @adapter: the adapter
* @pidx: the port index
*
* Computes and returns a bitmap indicating which MPS buffer groups are
@ -6252,7 +6252,7 @@ static unsigned int t4_get_tp_e2c_map(struct adapter *adapter, int pidx)
/**
* t4_get_tp_ch_map - return TP ingress channels associated with a port
* @adapter: the adapter
* @adap: the adapter
* @pidx: the port index
*
* Returns a bitmap indicating which TP Ingress Channels are associated
@ -6589,7 +6589,7 @@ int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
* @phy_addr: the PHY address
* @mmd: the PHY MMD to access (0 for clause 22 PHYs)
* @reg: the register to write
* @valp: value to write
* @val: value to write
*
* Issues a FW command through the given mailbox to write a PHY register.
*/
@ -6615,7 +6615,7 @@ int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
/**
* t4_sge_decode_idma_state - decode the idma state
* @adap: the adapter
* @adapter: the adapter
* @state: the state idma is stuck in
*/
void t4_sge_decode_idma_state(struct adapter *adapter, int state)
@ -6782,7 +6782,7 @@ void t4_sge_decode_idma_state(struct adapter *adapter, int state)
* t4_sge_ctxt_flush - flush the SGE context cache
* @adap: the adapter
* @mbox: mailbox to use for the FW command
* @ctx_type: Egress or Ingress
* @ctxt_type: Egress or Ingress
*
* Issues a FW command through the given mailbox to flush the
* SGE context cache.
@ -6809,7 +6809,7 @@ int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox, int ctxt_type)
/**
* t4_read_sge_dbqtimers - read SGE Doorbell Queue Timer values
* @adap - the adapter
* @adap: the adapter
* @ndbqtimers: size of the provided SGE Doorbell Queue Timer table
* @dbqtimers: SGE Doorbell Queue Timer table
*
@ -7092,6 +7092,7 @@ static int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force)
/**
* t4_fw_restart - restart the firmware by taking the uP out of RESET
* @adap: the adapter
* @mbox: mailbox to use for the FW command
* @reset: if we want to do a RESET to restart things
*
* Restart firmware previously halted by t4_fw_halt(). On successful
@ -7630,6 +7631,8 @@ int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
* @nmac: number of MAC addresses needed (1 to 5)
* @mac: the MAC addresses of the VI
* @rss_size: size of RSS table slice associated with this VI
* @vivld: the destination to store the VI Valid value.
* @vin: the destination to store the VIN value.
*
* Allocates a virtual interface for the given physical port. If @mac is
* not %NULL it contains the MAC addresses of the VI as assigned by FW.
@ -7848,7 +7851,7 @@ int t4_free_raw_mac_filt(struct adapter *adap, unsigned int viid,
* t4_alloc_encap_mac_filt - Adds a mac entry in mps tcam with VNI support
* @adap: the adapter
* @viid: the VI id
* @mac: the MAC address
* @addr: the MAC address
* @mask: the mask
* @vni: the VNI id for the tunnel protocol
* @vni_mask: mask for the VNI id
@ -7897,11 +7900,11 @@ int t4_alloc_encap_mac_filt(struct adapter *adap, unsigned int viid,
* t4_alloc_raw_mac_filt - Adds a mac entry in mps tcam
* @adap: the adapter
* @viid: the VI id
* @mac: the MAC address
* @addr: the MAC address
* @mask: the mask
* @idx: index at which to add this entry
* @port_id: the port index
* @lookup_type: MAC address for inner (1) or outer (0) header
* @port_id: the port index
* @sleep_ok: call is allowed to sleep
*
* Adds the mac entry at the specified index using raw mac interface.
@ -8126,7 +8129,7 @@ int t4_free_mac_filt(struct adapter *adap, unsigned int mbox,
* @idx: index of existing filter for old value of MAC address, or -1
* @addr: the new MAC address value
* @persist: whether a new MAC allocation should be persistent
* @add_smt: if true also add the address to the HW SMT
* @smt_idx: the destination to store the new SMT index.
*
* Modifies an exact-match filter and sets it to the new MAC address.
* Note that in general it is not possible to modify the value of a given
@ -8448,7 +8451,6 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
/**
* t4_link_down_rc_str - return a string for a Link Down Reason Code
* @adap: the adapter
* @link_down_rc: Link Down Reason Code
*
* Returns a string representation of the Link Down Reason Code.
@ -8472,9 +8474,7 @@ static const char *t4_link_down_rc_str(unsigned char link_down_rc)
return reason[link_down_rc];
}
/**
* Return the highest speed set in the port capabilities, in Mb/s.
*/
/* Return the highest speed set in the port capabilities, in Mb/s. */
static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
{
#define TEST_SPEED_RETURN(__caps_speed, __speed) \
@ -9110,7 +9110,6 @@ found:
/**
* t4_prep_adapter - prepare SW and HW for operation
* @adapter: the adapter
* @reset: if true perform a HW reset
*
* Initialize adapter SW state for the various HW modules, set initial
* values for some adapter tunables, take PHYs out of reset, and
@ -10395,6 +10394,7 @@ int t4_sched_params(struct adapter *adapter, u8 type, u8 level, u8 mode,
/**
* t4_i2c_rd - read I2C data from adapter
* @adap: the adapter
* @mbox: mailbox to use for the FW command
* @port: Port number if per-port device; <0 if not
* @devid: per-port device ID or absolute device ID
* @offset: byte offset into device I2C space
@ -10450,7 +10450,7 @@ int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
/**
* t4_set_vlan_acl - Set a VLAN id for the specified VF
* @adapter: the adapter
* @adap: the adapter
* @mbox: mailbox to use for the FW command
* @vf: one of the VFs instantiated by the specified PF
* @vlan: The vlanid to be set

View File

@ -260,8 +260,7 @@ static int cxgb4vf_set_addr_hash(struct port_info *pi)
* @tcam_idx: TCAM index of existing filter for old value of MAC address,
* or -1
* @addr: the new MAC address value
* @persist: whether a new MAC allocation should be persistent
* @add_smt: if true also add the address to the HW SMT
* @persistent: whether a new MAC allocation should be persistent
*
* Modifies an MPS filter and sets it to the new MAC address if
* @tcam_idx >= 0, or adds the MAC address to a new filter if

View File

@ -1692,7 +1692,7 @@ static inline bool is_new_response(const struct rsp_ctrl *rc,
* restore_rx_bufs - put back a packet's RX buffers
* @gl: the packet gather list
* @fl: the SGE Free List
* @nfrags: how many fragments in @si
* @frags: how many fragments in @si
*
* Called when we find out that the current packet, @si, can't be
* processed right away for some reason. This is a very rare event and
@ -2054,7 +2054,7 @@ irq_handler_t t4vf_intr_handler(struct adapter *adapter)
/**
* sge_rx_timer_cb - perform periodic maintenance of SGE RX queues
* @data: the adapter
* @t: Rx timer
*
* Runs periodically from a timer to perform maintenance of SGE RX queues.
*
@ -2113,7 +2113,7 @@ static void sge_rx_timer_cb(struct timer_list *t)
/**
* sge_tx_timer_cb - perform periodic maintenance of SGE Tx queues
* @data: the adapter
* @t: Tx timer
*
* Runs periodically from a timer to perform maintenance of SGE TX queues.
*
@ -2405,6 +2405,7 @@ err:
* t4vf_sge_alloc_eth_txq - allocate an SGE Ethernet TX Queue
* @adapter: the adapter
* @txq: pointer to the new txq to be filled in
* @dev: the network device
* @devq: the network TX queue associated with the new txq
* @iqid: the relative ingress queue ID to which events relating to
* the new txq should be directed

View File

@ -389,9 +389,7 @@ static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
return cc_fec;
}
/**
* Return the highest speed set in the port capabilities, in Mb/s.
*/
/* Return the highest speed set in the port capabilities, in Mb/s. */
static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
{
#define TEST_SPEED_RETURN(__caps_speed, __speed) \
@ -1467,6 +1465,7 @@ int t4vf_identify_port(struct adapter *adapter, unsigned int viid,
* @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change
* @vlanex: 1 to enable hardware VLAN Tag extraction, 0 to disable it,
* -1 no change
* @sleep_ok: call is allowed to sleep
*
* Sets Rx properties of a virtual interface.
*/
@ -1906,7 +1905,7 @@ static const char *t4vf_link_down_rc_str(unsigned char link_down_rc)
/**
* t4vf_handle_get_port_info - process a FW reply message
* @pi: the port info
* @rpl: start of the FW message
* @cmd: start of the FW message
*
* Processes a GET_PORT_INFO FW reply message.
*/
@ -2137,8 +2136,6 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
return 0;
}
/**
*/
int t4vf_prep_adapter(struct adapter *adapter)
{
int err;

View File

@ -1595,6 +1595,24 @@ static int enetc_set_psfp(struct net_device *ndev, int en)
return 0;
}
static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
int i;
for (i = 0; i < priv->num_rx_rings; i++)
enetc_bdr_enable_rxvlan(&priv->si->hw, i, en);
}
static void enetc_enable_txvlan(struct net_device *ndev, bool en)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
int i;
for (i = 0; i < priv->num_tx_rings; i++)
enetc_bdr_enable_txvlan(&priv->si->hw, i, en);
}
int enetc_set_features(struct net_device *ndev,
netdev_features_t features)
{
@ -1604,6 +1622,14 @@ int enetc_set_features(struct net_device *ndev,
if (changed & NETIF_F_RXHASH)
enetc_set_rss(ndev, !!(features & NETIF_F_RXHASH));
if (changed & NETIF_F_HW_VLAN_CTAG_RX)
enetc_enable_rxvlan(ndev,
!!(features & NETIF_F_HW_VLAN_CTAG_RX));
if (changed & NETIF_F_HW_VLAN_CTAG_TX)
enetc_enable_txvlan(ndev,
!!(features & NETIF_F_HW_VLAN_CTAG_TX));
if (changed & NETIF_F_HW_TC)
err = enetc_set_psfp(ndev, !!(features & NETIF_F_HW_TC));

View File

@ -531,22 +531,22 @@ struct enetc_msg_cmd_header {
/* Common H/W utility functions */
static inline void enetc_enable_rxvlan(struct enetc_hw *hw, int si_idx,
bool en)
static inline void enetc_bdr_enable_rxvlan(struct enetc_hw *hw, int idx,
bool en)
{
u32 val = enetc_rxbdr_rd(hw, si_idx, ENETC_RBMR);
u32 val = enetc_rxbdr_rd(hw, idx, ENETC_RBMR);
val = (val & ~ENETC_RBMR_VTE) | (en ? ENETC_RBMR_VTE : 0);
enetc_rxbdr_wr(hw, si_idx, ENETC_RBMR, val);
enetc_rxbdr_wr(hw, idx, ENETC_RBMR, val);
}
static inline void enetc_enable_txvlan(struct enetc_hw *hw, int si_idx,
bool en)
static inline void enetc_bdr_enable_txvlan(struct enetc_hw *hw, int idx,
bool en)
{
u32 val = enetc_txbdr_rd(hw, si_idx, ENETC_TBMR);
u32 val = enetc_txbdr_rd(hw, idx, ENETC_TBMR);
val = (val & ~ENETC_TBMR_VIH) | (en ? ENETC_TBMR_VIH : 0);
enetc_txbdr_wr(hw, si_idx, ENETC_TBMR, val);
enetc_txbdr_wr(hw, idx, ENETC_TBMR, val);
}
static inline void enetc_set_bdr_prio(struct enetc_hw *hw, int bdr_idx,

View File

@ -649,14 +649,6 @@ static int enetc_pf_set_features(struct net_device *ndev,
netdev_features_t changed = ndev->features ^ features;
struct enetc_ndev_priv *priv = netdev_priv(ndev);
if (changed & NETIF_F_HW_VLAN_CTAG_RX)
enetc_enable_rxvlan(&priv->si->hw, 0,
!!(features & NETIF_F_HW_VLAN_CTAG_RX));
if (changed & NETIF_F_HW_VLAN_CTAG_TX)
enetc_enable_txvlan(&priv->si->hw, 0,
!!(features & NETIF_F_HW_VLAN_CTAG_TX));
if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
struct enetc_pf *pf = enetc_si_priv(priv->si);

View File

@ -699,7 +699,7 @@ static void hns_nic_rx_up_pro(struct hns_nic_ring_data *ring_data,
struct net_device *ndev = ring_data->napi.dev;
skb->protocol = eth_type_trans(skb, ndev);
(void)napi_gro_receive(&ring_data->napi, skb);
napi_gro_receive(&ring_data->napi, skb);
}
static int hns_desc_unused(struct hnae_ring *ring)

View File

@ -1715,7 +1715,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
}
netdev->min_mtu = IBMVETH_MIN_MTU;
netdev->max_mtu = ETH_MAX_MTU;
netdev->max_mtu = ETH_MAX_MTU - IBMVETH_BUFF_OH;
memcpy(netdev->dev_addr, mac_addr_p, ETH_ALEN);

View File

@ -1971,13 +1971,18 @@ static int do_reset(struct ibmvnic_adapter *adapter,
release_sub_crqs(adapter, 1);
} else {
rc = ibmvnic_reset_crq(adapter);
if (!rc)
if (rc == H_CLOSED || rc == H_SUCCESS) {
rc = vio_enable_interrupts(adapter->vdev);
if (rc)
netdev_err(adapter->netdev,
"Reset failed to enable interrupts. rc=%d\n",
rc);
}
}
if (rc) {
netdev_err(adapter->netdev,
"Couldn't initialize crq. rc=%d\n", rc);
"Reset couldn't initialize crq. rc=%d\n", rc);
goto out;
}

View File

@ -2070,6 +2070,9 @@ static int i40e_set_ringparam(struct net_device *netdev,
*/
rx_rings[i].tail = hw->hw_addr + I40E_PRTGEN_STATUS;
err = i40e_setup_rx_descriptors(&rx_rings[i]);
if (err)
goto rx_unwind;
err = i40e_alloc_rx_bi(&rx_rings[i]);
if (err)
goto rx_unwind;

View File

@ -439,11 +439,15 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev,
i40e_get_netdev_stats_struct_tx(ring, stats);
if (i40e_enabled_xdp_vsi(vsi)) {
ring++;
ring = READ_ONCE(vsi->xdp_rings[i]);
if (!ring)
continue;
i40e_get_netdev_stats_struct_tx(ring, stats);
}
ring++;
ring = READ_ONCE(vsi->rx_rings[i]);
if (!ring)
continue;
do {
start = u64_stats_fetch_begin_irq(&ring->syncp);
packets = ring->stats.packets;
@ -787,6 +791,8 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
for (q = 0; q < vsi->num_queue_pairs; q++) {
/* locate Tx ring */
p = READ_ONCE(vsi->tx_rings[q]);
if (!p)
continue;
do {
start = u64_stats_fetch_begin_irq(&p->syncp);
@ -800,8 +806,11 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
tx_linearize += p->tx_stats.tx_linearize;
tx_force_wb += p->tx_stats.tx_force_wb;
/* Rx queue is part of the same block as Tx queue */
p = &p[1];
/* locate Rx ring */
p = READ_ONCE(vsi->rx_rings[q]);
if (!p)
continue;
do {
start = u64_stats_fetch_begin_irq(&p->syncp);
packets = p->stats.packets;
@ -10824,10 +10833,10 @@ static void i40e_vsi_clear_rings(struct i40e_vsi *vsi)
if (vsi->tx_rings && vsi->tx_rings[0]) {
for (i = 0; i < vsi->alloc_queue_pairs; i++) {
kfree_rcu(vsi->tx_rings[i], rcu);
vsi->tx_rings[i] = NULL;
vsi->rx_rings[i] = NULL;
WRITE_ONCE(vsi->tx_rings[i], NULL);
WRITE_ONCE(vsi->rx_rings[i], NULL);
if (vsi->xdp_rings)
vsi->xdp_rings[i] = NULL;
WRITE_ONCE(vsi->xdp_rings[i], NULL);
}
}
}
@ -10861,7 +10870,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE)
ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
ring->itr_setting = pf->tx_itr_default;
vsi->tx_rings[i] = ring++;
WRITE_ONCE(vsi->tx_rings[i], ring++);
if (!i40e_enabled_xdp_vsi(vsi))
goto setup_rx;
@ -10879,7 +10888,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
set_ring_xdp(ring);
ring->itr_setting = pf->tx_itr_default;
vsi->xdp_rings[i] = ring++;
WRITE_ONCE(vsi->xdp_rings[i], ring++);
setup_rx:
ring->queue_index = i;
@ -10892,7 +10901,7 @@ setup_rx:
ring->size = 0;
ring->dcb_tc = 0;
ring->itr_setting = pf->rx_itr_default;
vsi->rx_rings[i] = ring;
WRITE_ONCE(vsi->rx_rings[i], ring);
}
return 0;

View File

@ -1194,7 +1194,7 @@ static void ice_vsi_clear_rings(struct ice_vsi *vsi)
for (i = 0; i < vsi->alloc_txq; i++) {
if (vsi->tx_rings[i]) {
kfree_rcu(vsi->tx_rings[i], rcu);
vsi->tx_rings[i] = NULL;
WRITE_ONCE(vsi->tx_rings[i], NULL);
}
}
}
@ -1202,7 +1202,7 @@ static void ice_vsi_clear_rings(struct ice_vsi *vsi)
for (i = 0; i < vsi->alloc_rxq; i++) {
if (vsi->rx_rings[i]) {
kfree_rcu(vsi->rx_rings[i], rcu);
vsi->rx_rings[i] = NULL;
WRITE_ONCE(vsi->rx_rings[i], NULL);
}
}
}
@ -1235,7 +1235,7 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi)
ring->vsi = vsi;
ring->dev = dev;
ring->count = vsi->num_tx_desc;
vsi->tx_rings[i] = ring;
WRITE_ONCE(vsi->tx_rings[i], ring);
}
/* Allocate Rx rings */
@ -1254,7 +1254,7 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi)
ring->netdev = vsi->netdev;
ring->dev = dev;
ring->count = vsi->num_rx_desc;
vsi->rx_rings[i] = ring;
WRITE_ONCE(vsi->rx_rings[i], ring);
}
return 0;

View File

@ -1702,7 +1702,7 @@ static int ice_xdp_alloc_setup_rings(struct ice_vsi *vsi)
xdp_ring->netdev = NULL;
xdp_ring->dev = dev;
xdp_ring->count = vsi->num_tx_desc;
vsi->xdp_rings[i] = xdp_ring;
WRITE_ONCE(vsi->xdp_rings[i], xdp_ring);
if (ice_setup_tx_ring(xdp_ring))
goto free_xdp_rings;
ice_set_ring_xdp(xdp_ring);

View File

@ -921,7 +921,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
ring->queue_index = txr_idx;
/* assign ring to adapter */
adapter->tx_ring[txr_idx] = ring;
WRITE_ONCE(adapter->tx_ring[txr_idx], ring);
/* update count and index */
txr_count--;
@ -948,7 +948,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
set_ring_xdp(ring);
/* assign ring to adapter */
adapter->xdp_ring[xdp_idx] = ring;
WRITE_ONCE(adapter->xdp_ring[xdp_idx], ring);
/* update count and index */
xdp_count--;
@ -991,7 +991,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter,
ring->queue_index = rxr_idx;
/* assign ring to adapter */
adapter->rx_ring[rxr_idx] = ring;
WRITE_ONCE(adapter->rx_ring[rxr_idx], ring);
/* update count and index */
rxr_count--;
@ -1020,13 +1020,13 @@ static void ixgbe_free_q_vector(struct ixgbe_adapter *adapter, int v_idx)
ixgbe_for_each_ring(ring, q_vector->tx) {
if (ring_is_xdp(ring))
adapter->xdp_ring[ring->queue_index] = NULL;
WRITE_ONCE(adapter->xdp_ring[ring->queue_index], NULL);
else
adapter->tx_ring[ring->queue_index] = NULL;
WRITE_ONCE(adapter->tx_ring[ring->queue_index], NULL);
}
ixgbe_for_each_ring(ring, q_vector->rx)
adapter->rx_ring[ring->queue_index] = NULL;
WRITE_ONCE(adapter->rx_ring[ring->queue_index], NULL);
adapter->q_vector[v_idx] = NULL;
napi_hash_del(&q_vector->napi);

View File

@ -7051,7 +7051,10 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
}
for (i = 0; i < adapter->num_rx_queues; i++) {
struct ixgbe_ring *rx_ring = adapter->rx_ring[i];
struct ixgbe_ring *rx_ring = READ_ONCE(adapter->rx_ring[i]);
if (!rx_ring)
continue;
non_eop_descs += rx_ring->rx_stats.non_eop_descs;
alloc_rx_page += rx_ring->rx_stats.alloc_rx_page;
alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed;
@ -7072,15 +7075,20 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
packets = 0;
/* gather some stats to the adapter struct that are per queue */
for (i = 0; i < adapter->num_tx_queues; i++) {
struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
struct ixgbe_ring *tx_ring = READ_ONCE(adapter->tx_ring[i]);
if (!tx_ring)
continue;
restart_queue += tx_ring->tx_stats.restart_queue;
tx_busy += tx_ring->tx_stats.tx_busy;
bytes += tx_ring->stats.bytes;
packets += tx_ring->stats.packets;
}
for (i = 0; i < adapter->num_xdp_queues; i++) {
struct ixgbe_ring *xdp_ring = adapter->xdp_ring[i];
struct ixgbe_ring *xdp_ring = READ_ONCE(adapter->xdp_ring[i]);
if (!xdp_ring)
continue;
restart_queue += xdp_ring->tx_stats.restart_queue;
tx_busy += xdp_ring->tx_stats.tx_busy;
bytes += xdp_ring->stats.bytes;

View File

@ -106,9 +106,11 @@
#define MVNETA_TX_IN_PRGRS BIT(1)
#define MVNETA_TX_FIFO_EMPTY BIT(8)
#define MVNETA_RX_MIN_FRAME_SIZE 0x247c
/* Only exists on Armada XP and Armada 370 */
#define MVNETA_SERDES_CFG 0x24A0
#define MVNETA_SGMII_SERDES_PROTO 0x0cc7
#define MVNETA_QSGMII_SERDES_PROTO 0x0667
#define MVNETA_HSGMII_SERDES_PROTO 0x1107
#define MVNETA_TYPE_PRIO 0x24bc
#define MVNETA_FORCE_UNI BIT(21)
#define MVNETA_TXQ_CMD_1 0x24e4
@ -3529,26 +3531,60 @@ static int mvneta_setup_txqs(struct mvneta_port *pp)
return 0;
}
static int mvneta_comphy_init(struct mvneta_port *pp)
static int mvneta_comphy_init(struct mvneta_port *pp, phy_interface_t interface)
{
int ret;
if (!pp->comphy)
return 0;
ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET,
pp->phy_interface);
ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, interface);
if (ret)
return ret;
return phy_power_on(pp->comphy);
}
static int mvneta_config_interface(struct mvneta_port *pp,
phy_interface_t interface)
{
int ret = 0;
if (pp->comphy) {
if (interface == PHY_INTERFACE_MODE_SGMII ||
interface == PHY_INTERFACE_MODE_1000BASEX ||
interface == PHY_INTERFACE_MODE_2500BASEX) {
ret = mvneta_comphy_init(pp, interface);
}
} else {
switch (interface) {
case PHY_INTERFACE_MODE_QSGMII:
mvreg_write(pp, MVNETA_SERDES_CFG,
MVNETA_QSGMII_SERDES_PROTO);
break;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
mvreg_write(pp, MVNETA_SERDES_CFG,
MVNETA_SGMII_SERDES_PROTO);
break;
case PHY_INTERFACE_MODE_2500BASEX:
mvreg_write(pp, MVNETA_SERDES_CFG,
MVNETA_HSGMII_SERDES_PROTO);
break;
default:
break;
}
}
pp->phy_interface = interface;
return ret;
}
static void mvneta_start_dev(struct mvneta_port *pp)
{
int cpu;
WARN_ON(mvneta_comphy_init(pp));
WARN_ON(mvneta_config_interface(pp, pp->phy_interface));
mvneta_max_rx_size_set(pp, pp->pkt_size);
mvneta_txq_max_tx_size_set(pp, pp->pkt_size);
@ -3926,14 +3962,10 @@ static void mvneta_mac_config(struct phylink_config *config, unsigned int mode,
if (state->speed == SPEED_2500)
new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE;
if (pp->comphy && pp->phy_interface != state->interface &&
(state->interface == PHY_INTERFACE_MODE_SGMII ||
state->interface == PHY_INTERFACE_MODE_1000BASEX ||
state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
pp->phy_interface = state->interface;
WARN_ON(phy_power_off(pp->comphy));
WARN_ON(mvneta_comphy_init(pp));
if (pp->phy_interface != state->interface) {
if (pp->comphy)
WARN_ON(phy_power_off(pp->comphy));
WARN_ON(mvneta_config_interface(pp, state->interface));
}
if (new_ctrl0 != gmac_ctrl0)
@ -4982,12 +5014,10 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
/* MAC Cause register should be cleared */
mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0);
if (phy_mode == PHY_INTERFACE_MODE_QSGMII)
mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO);
else if (phy_mode == PHY_INTERFACE_MODE_SGMII ||
phy_interface_mode_is_8023z(phy_mode))
mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
else if (!phy_interface_mode_is_rgmii(phy_mode))
if (phy_mode != PHY_INTERFACE_MODE_QSGMII &&
phy_mode != PHY_INTERFACE_MODE_SGMII &&
!phy_interface_mode_is_8023z(phy_mode) &&
!phy_interface_mode_is_rgmii(phy_mode))
return -EINVAL;
return 0;
@ -5176,10 +5206,10 @@ static int mvneta_probe(struct platform_device *pdev)
if (err < 0)
goto err_netdev;
err = mvneta_port_power_up(pp, phy_mode);
err = mvneta_port_power_up(pp, pp->phy_interface);
if (err < 0) {
dev_err(&pdev->dev, "can't power up port\n");
goto err_netdev;
return err;
}
/* Armada3700 network controller does not support per-cpu

View File

@ -407,7 +407,9 @@ static int
mlx5e_rep_indr_setup_block(struct net_device *netdev,
struct mlx5e_rep_priv *rpriv,
struct flow_block_offload *f,
flow_setup_cb_t *setup_cb)
flow_setup_cb_t *setup_cb,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
{
struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
struct mlx5e_rep_indr_block_priv *indr_priv;
@ -438,8 +440,10 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
list_add(&indr_priv->list,
&rpriv->uplink_priv.tc_indr_block_priv_list);
block_cb = flow_block_cb_alloc(setup_cb, indr_priv, indr_priv,
mlx5e_rep_indr_block_unbind);
block_cb = flow_indr_block_cb_alloc(setup_cb, indr_priv, indr_priv,
mlx5e_rep_indr_block_unbind,
f, netdev, data, rpriv,
cleanup);
if (IS_ERR(block_cb)) {
list_del(&indr_priv->list);
kfree(indr_priv);
@ -458,7 +462,7 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
if (!block_cb)
return -ENOENT;
flow_block_cb_remove(block_cb, f);
flow_indr_block_cb_remove(block_cb, f);
list_del(&block_cb->driver_list);
return 0;
default:
@ -469,15 +473,19 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev,
static
int mlx5e_rep_indr_setup_cb(struct net_device *netdev, void *cb_priv,
enum tc_setup_type type, void *type_data)
enum tc_setup_type type, void *type_data,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
{
switch (type) {
case TC_SETUP_BLOCK:
return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
mlx5e_rep_indr_setup_tc_cb);
mlx5e_rep_indr_setup_tc_cb,
data, cleanup);
case TC_SETUP_FT:
return mlx5e_rep_indr_setup_block(netdev, cb_priv, type_data,
mlx5e_rep_indr_setup_ft_cb);
mlx5e_rep_indr_setup_ft_cb,
data, cleanup);
default:
return -EOPNOTSUPP;
}
@ -496,7 +504,7 @@ int mlx5e_rep_tc_netdevice_event_register(struct mlx5e_rep_priv *rpriv)
void mlx5e_rep_tc_netdevice_event_unregister(struct mlx5e_rep_priv *rpriv)
{
flow_indr_dev_unregister(mlx5e_rep_indr_setup_cb, rpriv,
mlx5e_rep_indr_setup_tc_cb);
mlx5e_rep_indr_block_unbind);
}
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)

View File

@ -978,10 +978,10 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
lossy = !(pfc || pause_en);
thres_cells = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu);
mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, &thres_cells);
thres_cells = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, thres_cells);
delay_cells = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay,
pfc, pause_en);
mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, &delay_cells);
delay_cells = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, delay_cells);
total_cells = thres_cells + delay_cells;
taken_headroom_cells += total_cells;

View File

@ -374,17 +374,15 @@ mlxsw_sp_port_vlan_find_by_vid(const struct mlxsw_sp_port *mlxsw_sp_port,
return NULL;
}
static inline void
static inline u32
mlxsw_sp_port_headroom_8x_adjust(const struct mlxsw_sp_port *mlxsw_sp_port,
u16 *p_size)
u32 size_cells)
{
/* Ports with eight lanes use two headroom buffers between which the
* configured headroom size is split. Therefore, multiply the calculated
* headroom size by two.
*/
if (mlxsw_sp_port->mapping.width != 8)
return;
*p_size *= 2;
return mlxsw_sp_port->mapping.width == 8 ? 2 * size_cells : size_cells;
}
enum mlxsw_sp_flood_type {

View File

@ -312,7 +312,7 @@ static int mlxsw_sp_port_pb_init(struct mlxsw_sp_port *mlxsw_sp_port)
if (i == MLXSW_SP_PB_UNUSED)
continue;
mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, &size);
size = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, size);
mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, i, size);
}
mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl,

View File

@ -782,7 +782,7 @@ mlxsw_sp_span_port_buffer_update(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
speed = 0;
buffsize = mlxsw_sp_span_buffsize_get(mlxsw_sp, speed, mtu);
mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, (u16 *) &buffsize);
buffsize = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, buffsize);
mlxsw_reg_sbib_pack(sbib_pl, mlxsw_sp_port->local_port, buffsize);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
}

View File

@ -297,7 +297,7 @@ struct vxge_hw_fifo_config {
* @greedy_return: If Set it forces the device to return absolutely all RxD
* that are consumed and still on board when a timer interrupt
* triggers. If Clear, then if the device has already returned
* RxD before current timer interrupt trigerred and after the
* RxD before current timer interrupt triggered and after the
* previous timer interrupt triggered, then the device is not
* forced to returned the rest of the consumed RxD that it has
* on board which account for a byte count less than the one

View File

@ -861,7 +861,7 @@ static void nfp_flower_clean(struct nfp_app *app)
flush_work(&app_priv->cmsg_work);
flow_indr_dev_unregister(nfp_flower_indr_setup_tc_cb, app,
nfp_flower_setup_indr_block_cb);
nfp_flower_setup_indr_tc_release);
if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)
nfp_flower_qos_cleanup(app);

View File

@ -459,9 +459,10 @@ int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,
struct tc_cls_matchall_offload *flow);
void nfp_flower_stats_rlim_reply(struct nfp_app *app, struct sk_buff *skb);
int nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
enum tc_setup_type type, void *type_data);
int nfp_flower_setup_indr_block_cb(enum tc_setup_type type, void *type_data,
void *cb_priv);
enum tc_setup_type type, void *type_data,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb));
void nfp_flower_setup_indr_tc_release(void *cb_priv);
void
__nfp_flower_non_repr_priv_get(struct nfp_flower_non_repr_priv *non_repr_priv);

View File

@ -1619,8 +1619,8 @@ nfp_flower_indr_block_cb_priv_lookup(struct nfp_app *app,
return NULL;
}
int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
void *type_data, void *cb_priv)
static int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
void *type_data, void *cb_priv)
{
struct nfp_flower_indr_block_cb_priv *priv = cb_priv;
struct flow_cls_offload *flower = type_data;
@ -1637,7 +1637,7 @@ int nfp_flower_setup_indr_block_cb(enum tc_setup_type type,
}
}
static void nfp_flower_setup_indr_tc_release(void *cb_priv)
void nfp_flower_setup_indr_tc_release(void *cb_priv)
{
struct nfp_flower_indr_block_cb_priv *priv = cb_priv;
@ -1647,7 +1647,8 @@ static void nfp_flower_setup_indr_tc_release(void *cb_priv)
static int
nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
struct flow_block_offload *f)
struct flow_block_offload *f, void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
{
struct nfp_flower_indr_block_cb_priv *cb_priv;
struct nfp_flower_priv *priv = app->priv;
@ -1676,9 +1677,10 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
cb_priv->app = app;
list_add(&cb_priv->list, &priv->indr_block_cb_priv);
block_cb = flow_block_cb_alloc(nfp_flower_setup_indr_block_cb,
cb_priv, cb_priv,
nfp_flower_setup_indr_tc_release);
block_cb = flow_indr_block_cb_alloc(nfp_flower_setup_indr_block_cb,
cb_priv, cb_priv,
nfp_flower_setup_indr_tc_release,
f, netdev, data, app, cleanup);
if (IS_ERR(block_cb)) {
list_del(&cb_priv->list);
kfree(cb_priv);
@ -1699,7 +1701,7 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
if (!block_cb)
return -ENOENT;
flow_block_cb_remove(block_cb, f);
flow_indr_block_cb_remove(block_cb, f);
list_del(&block_cb->driver_list);
return 0;
default:
@ -1710,7 +1712,9 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
int
nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
enum tc_setup_type type, void *type_data)
enum tc_setup_type type, void *type_data,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb))
{
if (!nfp_fl_is_netdev_to_offload(netdev))
return -EOPNOTSUPP;
@ -1718,7 +1722,7 @@ nfp_flower_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
switch (type) {
case TC_SETUP_BLOCK:
return nfp_flower_setup_indr_tc_block(netdev, cb_priv,
type_data);
type_data, data, cleanup);
default:
return -EOPNOTSUPP;
}

View File

@ -147,7 +147,7 @@ struct pch_gbe_regs {
#define PCH_GBE_RH_ALM_FULL_8 0x00001000 /* 8 words */
#define PCH_GBE_RH_ALM_FULL_16 0x00002000 /* 16 words */
#define PCH_GBE_RH_ALM_FULL_32 0x00003000 /* 32 words */
/* RX FIFO Read Triger Threshold */
/* RX FIFO Read Trigger Threshold */
#define PCH_GBE_RH_RD_TRG_4 0x00000000 /* 4 words */
#define PCH_GBE_RH_RD_TRG_8 0x00000200 /* 8 words */
#define PCH_GBE_RH_RD_TRG_16 0x00000400 /* 16 words */

View File

@ -96,7 +96,8 @@ static void ionic_link_status_check(struct ionic_lif *lif)
u16 link_status;
bool link_up;
if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state))
if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state) ||
test_bit(IONIC_LIF_F_QUEUE_RESET, lif->state))
return;
link_status = le16_to_cpu(lif->info->status.link_status);
@ -1245,6 +1246,7 @@ static int ionic_init_nic_features(struct ionic_lif *lif)
netdev->hw_features |= netdev->hw_enc_features;
netdev->features |= netdev->hw_features;
netdev->vlan_features |= netdev->features & ~NETIF_F_VLAN_FEATURES;
netdev->priv_flags |= IFF_UNICAST_FLT |
IFF_LIVE_ADDR_CHANGE;
@ -1692,15 +1694,15 @@ static void ionic_stop_queues(struct ionic_lif *lif)
if (!test_and_clear_bit(IONIC_LIF_F_UP, lif->state))
return;
ionic_txrx_disable(lif);
netif_tx_disable(lif->netdev);
ionic_txrx_disable(lif);
}
int ionic_stop(struct net_device *netdev)
{
struct ionic_lif *lif = netdev_priv(netdev);
if (!netif_device_present(netdev))
if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
return 0;
ionic_stop_queues(lif);
@ -1983,18 +1985,19 @@ int ionic_reset_queues(struct ionic_lif *lif)
bool running;
int err = 0;
/* Put off the next watchdog timeout */
netif_trans_update(lif->netdev);
err = ionic_wait_for_bit(lif, IONIC_LIF_F_QUEUE_RESET);
if (err)
return err;
running = netif_running(lif->netdev);
if (running)
if (running) {
netif_device_detach(lif->netdev);
err = ionic_stop(lif->netdev);
if (!err && running)
}
if (!err && running) {
ionic_open(lif->netdev);
netif_device_attach(lif->netdev);
}
clear_bit(IONIC_LIF_F_QUEUE_RESET, lif->state);

View File

@ -271,7 +271,7 @@ static void qed_cxt_qm_iids(struct qed_hwfn *p_hwfn,
vf_tids += segs[NUM_TASK_PF_SEGMENTS].count;
}
iids->vf_cids += vf_cids * p_mngr->vf_count;
iids->vf_cids = vf_cids;
iids->tids += vf_tids * p_mngr->vf_count;
DP_VERBOSE(p_hwfn, QED_MSG_ILT,
@ -465,6 +465,20 @@ static struct qed_ilt_cli_blk *qed_cxt_set_blk(struct qed_ilt_cli_blk *p_blk)
return p_blk;
}
static void qed_cxt_ilt_blk_reset(struct qed_hwfn *p_hwfn)
{
struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
u32 cli_idx, blk_idx;
for (cli_idx = 0; cli_idx < MAX_ILT_CLIENTS; cli_idx++) {
for (blk_idx = 0; blk_idx < ILT_CLI_PF_BLOCKS; blk_idx++)
clients[cli_idx].pf_blks[blk_idx].total_size = 0;
for (blk_idx = 0; blk_idx < ILT_CLI_VF_BLOCKS; blk_idx++)
clients[cli_idx].vf_blks[blk_idx].total_size = 0;
}
}
int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *line_count)
{
struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
@ -484,6 +498,11 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *line_count)
p_mngr->pf_start_line = RESC_START(p_hwfn, QED_ILT);
/* Reset all ILT blocks at the beginning of ILT computing in order
* to prevent memory allocation for irrelevant blocks afterwards.
*/
qed_cxt_ilt_blk_reset(p_hwfn);
DP_VERBOSE(p_hwfn, QED_MSG_ILT,
"hwfn [%d] - Set context manager starting line to be 0x%08x\n",
p_hwfn->my_id, p_hwfn->p_cxt_mngr->pf_start_line);

View File

@ -5568,7 +5568,8 @@ static const char * const s_status_str[] = {
/* DBG_STATUS_INVALID_FILTER_TRIGGER_DWORDS */
"The filter/trigger constraint dword offsets are not enabled for recording",
/* DBG_STATUS_NO_MATCHING_FRAMING_MODE */
"No matching framing mode",
/* DBG_STATUS_VFC_READ_ERROR */
"Error reading from VFC",

View File

@ -980,7 +980,7 @@ int qed_llh_add_mac_filter(struct qed_dev *cdev,
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
union qed_llh_filter filter = {};
u8 filter_idx, abs_ppfid;
u8 filter_idx, abs_ppfid = 0;
u32 high, low, ref_cnt;
int rc = 0;
@ -1368,6 +1368,8 @@ static void qed_dbg_user_data_free(struct qed_hwfn *p_hwfn)
void qed_resc_free(struct qed_dev *cdev)
{
struct qed_rdma_info *rdma_info;
struct qed_hwfn *p_hwfn;
int i;
if (IS_VF(cdev)) {
@ -1385,7 +1387,8 @@ void qed_resc_free(struct qed_dev *cdev)
qed_llh_free(cdev);
for_each_hwfn(cdev, i) {
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
p_hwfn = cdev->hwfns + i;
rdma_info = p_hwfn->p_rdma_info;
qed_cxt_mngr_free(p_hwfn);
qed_qm_info_free(p_hwfn);
@ -1404,8 +1407,10 @@ void qed_resc_free(struct qed_dev *cdev)
qed_ooo_free(p_hwfn);
}
if (QED_IS_RDMA_PERSONALITY(p_hwfn))
if (QED_IS_RDMA_PERSONALITY(p_hwfn) && rdma_info) {
qed_spq_unregister_async_cb(p_hwfn, rdma_info->proto);
qed_rdma_info_free(p_hwfn);
}
qed_iov_free(p_hwfn);
qed_l2_free(p_hwfn);

View File

@ -2836,8 +2836,6 @@ int qed_iwarp_stop(struct qed_hwfn *p_hwfn)
if (rc)
return rc;
qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_IWARP);
return qed_iwarp_ll2_stop(p_hwfn);
}

View File

@ -113,7 +113,6 @@ void qed_roce_stop(struct qed_hwfn *p_hwfn)
break;
}
}
qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_ROCE);
}
static void qed_rdma_copy_gids(struct qed_rdma_qp *qp, __le32 *src_gid,

View File

@ -81,12 +81,17 @@ static void qed_vf_pf_req_end(struct qed_hwfn *p_hwfn, int req_status)
mutex_unlock(&(p_hwfn->vf_iov_info->mutex));
}
#define QED_VF_CHANNEL_USLEEP_ITERATIONS 90
#define QED_VF_CHANNEL_USLEEP_DELAY 100
#define QED_VF_CHANNEL_MSLEEP_ITERATIONS 10
#define QED_VF_CHANNEL_MSLEEP_DELAY 25
static int qed_send_msg2pf(struct qed_hwfn *p_hwfn, u8 *done, u32 resp_size)
{
union vfpf_tlvs *p_req = p_hwfn->vf_iov_info->vf2pf_request;
struct ustorm_trigger_vf_zone trigger;
struct ustorm_vf_zone *zone_data;
int rc = 0, time = 100;
int iter, rc = 0;
zone_data = (struct ustorm_vf_zone *)PXP_VF_BAR0_START_USDM_ZONE_B;
@ -126,11 +131,19 @@ static int qed_send_msg2pf(struct qed_hwfn *p_hwfn, u8 *done, u32 resp_size)
REG_WR(p_hwfn, (uintptr_t)&zone_data->trigger, *((u32 *)&trigger));
/* When PF would be done with the response, it would write back to the
* `done' address. Poll until then.
* `done' address from a coherent DMA zone. Poll until then.
*/
while ((!*done) && time) {
msleep(25);
time--;
iter = QED_VF_CHANNEL_USLEEP_ITERATIONS;
while (!*done && iter--) {
udelay(QED_VF_CHANNEL_USLEEP_DELAY);
dma_rmb();
}
iter = QED_VF_CHANNEL_MSLEEP_ITERATIONS;
while (!*done && iter--) {
msleep(QED_VF_CHANNEL_MSLEEP_DELAY);
dma_rmb();
}
if (!*done) {

View File

@ -1229,7 +1229,7 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
/* PTP not supported on VFs */
if (!is_vf)
qede_ptp_enable(edev, (mode == QEDE_PROBE_NORMAL));
qede_ptp_enable(edev);
edev->ops->register_ops(cdev, &qede_ll_ops, edev);
@ -1318,6 +1318,7 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
if (system_state == SYSTEM_POWER_OFF)
return;
qed_ops->common->remove(cdev);
edev->cdev = NULL;
/* Since this can happen out-of-sync with other flows,
* don't release the netdevice until after slowpath stop

View File

@ -412,6 +412,7 @@ void qede_ptp_disable(struct qede_dev *edev)
if (ptp->tx_skb) {
dev_kfree_skb_any(ptp->tx_skb);
ptp->tx_skb = NULL;
clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);
}
/* Disable PTP in HW */
@ -423,7 +424,7 @@ void qede_ptp_disable(struct qede_dev *edev)
edev->ptp = NULL;
}
static int qede_ptp_init(struct qede_dev *edev, bool init_tc)
static int qede_ptp_init(struct qede_dev *edev)
{
struct qede_ptp *ptp;
int rc;
@ -444,25 +445,19 @@ static int qede_ptp_init(struct qede_dev *edev, bool init_tc)
/* Init work queue for Tx timestamping */
INIT_WORK(&ptp->work, qede_ptp_task);
/* Init cyclecounter and timecounter. This is done only in the first
* load. If done in every load, PTP application will fail when doing
* unload / load (e.g. MTU change) while it is running.
*/
if (init_tc) {
memset(&ptp->cc, 0, sizeof(ptp->cc));
ptp->cc.read = qede_ptp_read_cc;
ptp->cc.mask = CYCLECOUNTER_MASK(64);
ptp->cc.shift = 0;
ptp->cc.mult = 1;
/* Init cyclecounter and timecounter */
memset(&ptp->cc, 0, sizeof(ptp->cc));
ptp->cc.read = qede_ptp_read_cc;
ptp->cc.mask = CYCLECOUNTER_MASK(64);
ptp->cc.shift = 0;
ptp->cc.mult = 1;
timecounter_init(&ptp->tc, &ptp->cc,
ktime_to_ns(ktime_get_real()));
}
timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real()));
return rc;
return 0;
}
int qede_ptp_enable(struct qede_dev *edev, bool init_tc)
int qede_ptp_enable(struct qede_dev *edev)
{
struct qede_ptp *ptp;
int rc;
@ -483,7 +478,7 @@ int qede_ptp_enable(struct qede_dev *edev, bool init_tc)
edev->ptp = ptp;
rc = qede_ptp_init(edev, init_tc);
rc = qede_ptp_init(edev);
if (rc)
goto err1;

View File

@ -41,7 +41,7 @@ void qede_ptp_rx_ts(struct qede_dev *edev, struct sk_buff *skb);
void qede_ptp_tx_ts(struct qede_dev *edev, struct sk_buff *skb);
int qede_ptp_hw_ts(struct qede_dev *edev, struct ifreq *req);
void qede_ptp_disable(struct qede_dev *edev);
int qede_ptp_enable(struct qede_dev *edev, bool init_tc);
int qede_ptp_enable(struct qede_dev *edev);
int qede_ptp_get_ts_info(struct qede_dev *edev, struct ethtool_ts_info *ts);
static inline void qede_ptp_record_rx_ts(struct qede_dev *edev,

View File

@ -105,6 +105,7 @@ static void qede_rdma_destroy_wq(struct qede_dev *edev)
qede_rdma_cleanup_event(edev);
destroy_workqueue(edev->rdma_info.rdma_wq);
edev->rdma_info.rdma_wq = NULL;
}
int qede_rdma_dev_add(struct qede_dev *edev, bool recovery)
@ -325,7 +326,7 @@ static void qede_rdma_add_event(struct qede_dev *edev,
if (edev->rdma_info.exp_recovery)
return;
if (!edev->rdma_info.qedr_dev)
if (!edev->rdma_info.qedr_dev || !edev->rdma_info.rdma_wq)
return;
/* We don't want the cleanup flow to start while we're allocating and

View File

@ -2114,8 +2114,11 @@ static void rtl_release_firmware(struct rtl8169_private *tp)
void r8169_apply_firmware(struct rtl8169_private *tp)
{
/* TODO: release firmware if rtl_fw_write_firmware signals failure. */
if (tp->rtl_fw)
if (tp->rtl_fw) {
rtl_fw_write_firmware(tp, tp->rtl_fw);
/* At least one firmware doesn't reset tp->ocp_base. */
tp->ocp_base = OCP_STD_PHY_BASE;
}
}
static void rtl8168_config_eee_mac(struct rtl8169_private *tp)

View File

@ -1044,8 +1044,9 @@ static int netsec_process_rx(struct netsec_priv *priv, int budget)
skb->ip_summed = CHECKSUM_UNNECESSARY;
next:
if ((skb && napi_gro_receive(&priv->napi, skb) != GRO_DROP) ||
xdp_result) {
if (skb)
napi_gro_receive(&priv->napi, skb);
if (skb || xdp_result) {
ndev->stats.rx_packets++;
ndev->stats.rx_bytes += xdp.data_end - xdp.data;
}

View File

@ -1649,6 +1649,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
geneve->collect_md = metadata;
geneve->use_udp6_rx_checksums = use_udp6_rx_checksums;
geneve->ttl_inherit = ttl_inherit;
geneve->df = df;
geneve_unquiesce(geneve, gs4, gs6);
return 0;

View File

@ -480,8 +480,7 @@ config MICROCHIP_T1_PHY
config MICROSEMI_PHY
tristate "Microsemi PHYs"
depends on MACSEC || MACSEC=n
select CRYPTO_AES
select CRYPTO_ECB
select CRYPTO_LIB_AES if MACSEC
help
Currently supports VSC8514, VSC8530, VSC8531, VSC8540 and VSC8541 PHYs

View File

@ -10,7 +10,7 @@
#include <linux/phy.h>
#include <dt-bindings/net/mscc-phy-vsc8531.h>
#include <crypto/skcipher.h>
#include <crypto/aes.h>
#include <net/macsec.h>
@ -500,39 +500,17 @@ static u32 vsc8584_macsec_flow_context_id(struct macsec_flow *flow)
static int vsc8584_macsec_derive_key(const u8 key[MACSEC_KEYID_LEN],
u16 key_len, u8 hkey[16])
{
struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
struct skcipher_request *req = NULL;
struct scatterlist src, dst;
DECLARE_CRYPTO_WAIT(wait);
u32 input[4] = {0};
const u8 input[AES_BLOCK_SIZE] = {0};
struct crypto_aes_ctx ctx;
int ret;
if (IS_ERR(tfm))
return PTR_ERR(tfm);
ret = aes_expandkey(&ctx, key, key_len);
if (ret)
return ret;
req = skcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) {
ret = -ENOMEM;
goto out;
}
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done,
&wait);
ret = crypto_skcipher_setkey(tfm, key, key_len);
if (ret < 0)
goto out;
sg_init_one(&src, input, 16);
sg_init_one(&dst, hkey, 16);
skcipher_request_set_crypt(req, &src, &dst, 16, NULL);
ret = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
out:
skcipher_request_free(req);
crypto_free_skcipher(tfm);
return ret;
aes_encrypt(&ctx, hkey, input);
memzero_explicit(&ctx, sizeof(ctx));
return 0;
}
static int vsc8584_macsec_transformation(struct phy_device *phydev,

View File

@ -840,7 +840,7 @@ static void phy_error(struct phy_device *phydev)
* phy_disable_interrupts - Disable the PHY interrupts from the PHY side
* @phydev: target phy_device struct
*/
static int phy_disable_interrupts(struct phy_device *phydev)
int phy_disable_interrupts(struct phy_device *phydev)
{
int err;

View File

@ -794,8 +794,10 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
/* Grab the bits from PHYIR2, and put them in the lower half */
phy_reg = mdiobus_read(bus, addr, MII_PHYSID2);
if (phy_reg < 0)
return -EIO;
if (phy_reg < 0) {
/* returning -ENODEV doesn't stop bus scanning */
return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO;
}
*phy_id |= phy_reg;
@ -1090,6 +1092,10 @@ int phy_init_hw(struct phy_device *phydev)
if (ret < 0)
return ret;
ret = phy_disable_interrupts(phydev);
if (ret)
return ret;
if (phydev->drv->config_init)
ret = phydev->drv->config_init(phydev);

View File

@ -1463,6 +1463,8 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
struct ethtool_pauseparam *pause)
{
struct phylink_link_state *config = &pl->link_config;
bool manual_changed;
int pause_state;
ASSERT_RTNL();
@ -1477,15 +1479,15 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
!pause->autoneg && pause->rx_pause != pause->tx_pause)
return -EINVAL;
mutex_lock(&pl->state_mutex);
config->pause = 0;
pause_state = 0;
if (pause->autoneg)
config->pause |= MLO_PAUSE_AN;
pause_state |= MLO_PAUSE_AN;
if (pause->rx_pause)
config->pause |= MLO_PAUSE_RX;
pause_state |= MLO_PAUSE_RX;
if (pause->tx_pause)
config->pause |= MLO_PAUSE_TX;
pause_state |= MLO_PAUSE_TX;
mutex_lock(&pl->state_mutex);
/*
* See the comments for linkmode_set_pause(), wrt the deficiencies
* with the current implementation. A solution to this issue would
@ -1502,18 +1504,35 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
linkmode_set_pause(config->advertising, pause->tx_pause,
pause->rx_pause);
/* If we have a PHY, phylib will call our link state function if the
* mode has changed, which will trigger a resolve and update the MAC
* configuration.
manual_changed = (config->pause ^ pause_state) & MLO_PAUSE_AN ||
(!(pause_state & MLO_PAUSE_AN) &&
(config->pause ^ pause_state) & MLO_PAUSE_TXRX_MASK);
config->pause = pause_state;
if (!pl->phydev && !test_bit(PHYLINK_DISABLE_STOPPED,
&pl->phylink_disable_state))
phylink_pcs_config(pl, true, &pl->link_config);
mutex_unlock(&pl->state_mutex);
/* If we have a PHY, a change of the pause frame advertisement will
* cause phylib to renegotiate (if AN is enabled) which will in turn
* call our phylink_phy_change() and trigger a resolve. Note that
* we can't hold our state mutex while calling phy_set_asym_pause().
*/
if (pl->phydev) {
if (pl->phydev)
phy_set_asym_pause(pl->phydev, pause->rx_pause,
pause->tx_pause);
} else if (!test_bit(PHYLINK_DISABLE_STOPPED,
&pl->phylink_disable_state)) {
phylink_pcs_config(pl, true, &pl->link_config);
/* If the manual pause settings changed, make sure we trigger a
* resolve to update their state; we can not guarantee that the
* link will cycle.
*/
if (manual_changed) {
pl->mac_link_dropped = true;
phylink_run_resolve(pl);
}
mutex_unlock(&pl->state_mutex);
return 0;
}

View File

@ -122,10 +122,13 @@ static int lan87xx_read_status(struct phy_device *phydev)
if (rc < 0)
return rc;
/* Wait max 640 ms to detect energy */
phy_read_poll_timeout(phydev, MII_LAN83C185_CTRL_STATUS, rc,
rc & MII_LAN83C185_ENERGYON, 10000,
640000, true);
/* Wait max 640 ms to detect energy and the timeout is not
* an actual error.
*/
read_poll_timeout(phy_read, rc,
rc & MII_LAN83C185_ENERGYON || rc < 0,
10000, 640000, true, phydev,
MII_LAN83C185_CTRL_STATUS);
if (rc < 0)
return rc;

View File

@ -1491,10 +1491,10 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
}
if (pkt_cnt == 0) {
/* Skip IP alignment psudo header */
skb_pull(skb, 2);
skb->len = pkt_len;
skb_set_tail_pointer(skb, pkt_len);
/* Skip IP alignment pseudo header */
skb_pull(skb, 2);
skb_set_tail_pointer(skb, skb->len);
skb->truesize = pkt_len + sizeof(struct sk_buff);
ax88179_rx_checksum(skb, pkt_hdr);
return 1;
@ -1503,8 +1503,9 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
ax_skb = skb_clone(skb, GFP_ATOMIC);
if (ax_skb) {
ax_skb->len = pkt_len;
ax_skb->data = skb->data + 2;
skb_set_tail_pointer(ax_skb, pkt_len);
/* Skip IP alignment pseudo header */
skb_pull(ax_skb, 2);
skb_set_tail_pointer(ax_skb, ax_skb->len);
ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
ax88179_rx_checksum(ax_skb, pkt_hdr);
usbnet_skb_return(dev, ax_skb);

View File

@ -1324,7 +1324,7 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
if (pdata) {
cancel_delayed_work(&pdata->carrier_check);
cancel_delayed_work_sync(&pdata->carrier_check);
netif_dbg(dev, ifdown, dev->net, "free pdata\n");
kfree(pdata);
pdata = NULL;

View File

@ -1380,6 +1380,8 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
struct vxlan_rdst *rd;
if (rcu_access_pointer(f->nh)) {
if (*idx < cb->args[2])
goto skip_nh;
err = vxlan_fdb_info(skb, vxlan, f,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
@ -1387,6 +1389,8 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
NLM_F_MULTI, NULL);
if (err < 0)
goto out;
skip_nh:
*idx += 1;
continue;
}

View File

@ -45,17 +45,18 @@ static int wg_open(struct net_device *dev)
if (dev_v6)
dev_v6->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_NONE;
mutex_lock(&wg->device_update_lock);
ret = wg_socket_init(wg, wg->incoming_port);
if (ret < 0)
return ret;
mutex_lock(&wg->device_update_lock);
goto out;
list_for_each_entry(peer, &wg->peer_list, peer_list) {
wg_packet_send_staged_packets(peer);
if (peer->persistent_keepalive_interval)
wg_packet_send_keepalive(peer);
}
out:
mutex_unlock(&wg->device_update_lock);
return 0;
return ret;
}
#ifdef CONFIG_PM_SLEEP
@ -225,6 +226,7 @@ static void wg_destruct(struct net_device *dev)
list_del(&wg->device_list);
rtnl_unlock();
mutex_lock(&wg->device_update_lock);
rcu_assign_pointer(wg->creating_net, NULL);
wg->incoming_port = 0;
wg_socket_reinit(wg, NULL, NULL);
/* The final references are cleared in the below calls to destroy_workqueue. */
@ -240,13 +242,11 @@ static void wg_destruct(struct net_device *dev)
skb_queue_purge(&wg->incoming_handshakes);
free_percpu(dev->tstats);
free_percpu(wg->incoming_handshakes_worker);
if (wg->have_creating_net_ref)
put_net(wg->creating_net);
kvfree(wg->index_hashtable);
kvfree(wg->peer_hashtable);
mutex_unlock(&wg->device_update_lock);
pr_debug("%s: Interface deleted\n", dev->name);
pr_debug("%s: Interface destroyed\n", dev->name);
free_netdev(dev);
}
@ -292,7 +292,7 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
struct wg_device *wg = netdev_priv(dev);
int ret = -ENOMEM;
wg->creating_net = src_net;
rcu_assign_pointer(wg->creating_net, src_net);
init_rwsem(&wg->static_identity.lock);
mutex_init(&wg->socket_update_lock);
mutex_init(&wg->device_update_lock);
@ -393,30 +393,26 @@ static struct rtnl_link_ops link_ops __read_mostly = {
.newlink = wg_newlink,
};
static int wg_netdevice_notification(struct notifier_block *nb,
unsigned long action, void *data)
static void wg_netns_pre_exit(struct net *net)
{
struct net_device *dev = ((struct netdev_notifier_info *)data)->dev;
struct wg_device *wg = netdev_priv(dev);
struct wg_device *wg;
ASSERT_RTNL();
if (action != NETDEV_REGISTER || dev->netdev_ops != &netdev_ops)
return 0;
if (dev_net(dev) == wg->creating_net && wg->have_creating_net_ref) {
put_net(wg->creating_net);
wg->have_creating_net_ref = false;
} else if (dev_net(dev) != wg->creating_net &&
!wg->have_creating_net_ref) {
wg->have_creating_net_ref = true;
get_net(wg->creating_net);
rtnl_lock();
list_for_each_entry(wg, &device_list, device_list) {
if (rcu_access_pointer(wg->creating_net) == net) {
pr_debug("%s: Creating namespace exiting\n", wg->dev->name);
netif_carrier_off(wg->dev);
mutex_lock(&wg->device_update_lock);
rcu_assign_pointer(wg->creating_net, NULL);
wg_socket_reinit(wg, NULL, NULL);
mutex_unlock(&wg->device_update_lock);
}
}
return 0;
rtnl_unlock();
}
static struct notifier_block netdevice_notifier = {
.notifier_call = wg_netdevice_notification
static struct pernet_operations pernet_ops = {
.pre_exit = wg_netns_pre_exit
};
int __init wg_device_init(void)
@ -429,18 +425,18 @@ int __init wg_device_init(void)
return ret;
#endif
ret = register_netdevice_notifier(&netdevice_notifier);
ret = register_pernet_device(&pernet_ops);
if (ret)
goto error_pm;
ret = rtnl_link_register(&link_ops);
if (ret)
goto error_netdevice;
goto error_pernet;
return 0;
error_netdevice:
unregister_netdevice_notifier(&netdevice_notifier);
error_pernet:
unregister_pernet_device(&pernet_ops);
error_pm:
#ifdef CONFIG_PM_SLEEP
unregister_pm_notifier(&pm_notifier);
@ -451,7 +447,7 @@ error_pm:
void wg_device_uninit(void)
{
rtnl_link_unregister(&link_ops);
unregister_netdevice_notifier(&netdevice_notifier);
unregister_pernet_device(&pernet_ops);
#ifdef CONFIG_PM_SLEEP
unregister_pm_notifier(&pm_notifier);
#endif

View File

@ -40,7 +40,7 @@ struct wg_device {
struct net_device *dev;
struct crypt_queue encrypt_queue, decrypt_queue;
struct sock __rcu *sock4, *sock6;
struct net *creating_net;
struct net __rcu *creating_net;
struct noise_static_identity static_identity;
struct workqueue_struct *handshake_receive_wq, *handshake_send_wq;
struct workqueue_struct *packet_crypt_wq;
@ -56,7 +56,6 @@ struct wg_device {
unsigned int num_peers, device_update_gen;
u32 fwmark;
u16 incoming_port;
bool have_creating_net_ref;
};
int wg_device_init(void);

View File

@ -511,11 +511,15 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
if (flags & ~__WGDEVICE_F_ALL)
goto out;
ret = -EPERM;
if ((info->attrs[WGDEVICE_A_LISTEN_PORT] ||
info->attrs[WGDEVICE_A_FWMARK]) &&
!ns_capable(wg->creating_net->user_ns, CAP_NET_ADMIN))
goto out;
if (info->attrs[WGDEVICE_A_LISTEN_PORT] || info->attrs[WGDEVICE_A_FWMARK]) {
struct net *net;
rcu_read_lock();
net = rcu_dereference(wg->creating_net);
ret = !net || !ns_capable(net->user_ns, CAP_NET_ADMIN) ? -EPERM : 0;
rcu_read_unlock();
if (ret)
goto out;
}
++wg->device_update_gen;

View File

@ -617,8 +617,8 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
memcpy(handshake->hash, hash, NOISE_HASH_LEN);
memcpy(handshake->chaining_key, chaining_key, NOISE_HASH_LEN);
handshake->remote_index = src->sender_index;
if ((s64)(handshake->last_initiation_consumption -
(initiation_consumption = ktime_get_coarse_boottime_ns())) < 0)
initiation_consumption = ktime_get_coarse_boottime_ns();
if ((s64)(handshake->last_initiation_consumption - initiation_consumption) < 0)
handshake->last_initiation_consumption = initiation_consumption;
handshake->state = HANDSHAKE_CONSUMED_INITIATION;
up_write(&handshake->lock);

View File

@ -414,14 +414,8 @@ static void wg_packet_consume_data_done(struct wg_peer *peer,
if (unlikely(routed_peer != peer))
goto dishonest_packet_peer;
if (unlikely(napi_gro_receive(&peer->napi, skb) == GRO_DROP)) {
++dev->stats.rx_dropped;
net_dbg_ratelimited("%s: Failed to give packet to userspace from peer %llu (%pISpfsc)\n",
dev->name, peer->internal_id,
&peer->endpoint.addr);
} else {
update_rx_stats(peer, message_data_len(len_before_trim));
}
napi_gro_receive(&peer->napi, skb);
update_rx_stats(peer, message_data_len(len_before_trim));
return;
dishonest_packet_peer:

View File

@ -347,6 +347,7 @@ static void set_sock_opts(struct socket *sock)
int wg_socket_init(struct wg_device *wg, u16 port)
{
struct net *net;
int ret;
struct udp_tunnel_sock_cfg cfg = {
.sk_user_data = wg,
@ -371,37 +372,47 @@ int wg_socket_init(struct wg_device *wg, u16 port)
};
#endif
rcu_read_lock();
net = rcu_dereference(wg->creating_net);
net = net ? maybe_get_net(net) : NULL;
rcu_read_unlock();
if (unlikely(!net))
return -ENONET;
#if IS_ENABLED(CONFIG_IPV6)
retry:
#endif
ret = udp_sock_create(wg->creating_net, &port4, &new4);
ret = udp_sock_create(net, &port4, &new4);
if (ret < 0) {
pr_err("%s: Could not create IPv4 socket\n", wg->dev->name);
return ret;
goto out;
}
set_sock_opts(new4);
setup_udp_tunnel_sock(wg->creating_net, new4, &cfg);
setup_udp_tunnel_sock(net, new4, &cfg);
#if IS_ENABLED(CONFIG_IPV6)
if (ipv6_mod_enabled()) {
port6.local_udp_port = inet_sk(new4->sk)->inet_sport;
ret = udp_sock_create(wg->creating_net, &port6, &new6);
ret = udp_sock_create(net, &port6, &new6);
if (ret < 0) {
udp_tunnel_sock_release(new4);
if (ret == -EADDRINUSE && !port && retries++ < 100)
goto retry;
pr_err("%s: Could not create IPv6 socket\n",
wg->dev->name);
return ret;
goto out;
}
set_sock_opts(new6);
setup_udp_tunnel_sock(wg->creating_net, new6, &cfg);
setup_udp_tunnel_sock(net, new6, &cfg);
}
#endif
wg_socket_reinit(wg, new4->sk, new6 ? new6->sk : NULL);
return 0;
ret = 0;
out:
put_net(net);
return ret;
}
void wg_socket_reinit(struct wg_device *wg, struct sock *new4,

View File

@ -897,7 +897,6 @@ static void wil_rx_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb)
void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid,
struct wil_net_stats *stats, bool gro)
{
gro_result_t rc = GRO_NORMAL;
struct wil6210_vif *vif = ndev_to_vif(ndev);
struct wil6210_priv *wil = ndev_to_wil(ndev);
struct wireless_dev *wdev = vif_to_wdev(vif);
@ -908,22 +907,16 @@ void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid,
*/
int mcast = is_multicast_ether_addr(da);
struct sk_buff *xmit_skb = NULL;
static const char * const gro_res_str[] = {
[GRO_MERGED] = "GRO_MERGED",
[GRO_MERGED_FREE] = "GRO_MERGED_FREE",
[GRO_HELD] = "GRO_HELD",
[GRO_NORMAL] = "GRO_NORMAL",
[GRO_DROP] = "GRO_DROP",
[GRO_CONSUMED] = "GRO_CONSUMED",
};
if (wdev->iftype == NL80211_IFTYPE_STATION) {
sa = wil_skb_get_sa(skb);
if (mcast && ether_addr_equal(sa, ndev->dev_addr)) {
/* mcast packet looped back to us */
rc = GRO_DROP;
dev_kfree_skb(skb);
goto stats;
ndev->stats.rx_dropped++;
stats->rx_dropped++;
wil_dbg_txrx(wil, "Rx drop %d bytes\n", len);
return;
}
} else if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) {
if (mcast) {
@ -967,26 +960,16 @@ void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid,
wil_rx_handle_eapol(vif, skb);
if (gro)
rc = napi_gro_receive(&wil->napi_rx, skb);
napi_gro_receive(&wil->napi_rx, skb);
else
netif_rx_ni(skb);
wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n",
len, gro_res_str[rc]);
}
stats:
/* statistics. rc set to GRO_NORMAL for AP bridging */
if (unlikely(rc == GRO_DROP)) {
ndev->stats.rx_dropped++;
stats->rx_dropped++;
wil_dbg_txrx(wil, "Rx drop %d bytes\n", len);
} else {
ndev->stats.rx_packets++;
stats->rx_packets++;
ndev->stats.rx_bytes += len;
stats->rx_bytes += len;
if (mcast)
ndev->stats.multicast++;
}
ndev->stats.rx_packets++;
stats->rx_packets++;
ndev->stats.rx_bytes += len;
stats->rx_bytes += len;
if (mcast)
ndev->stats.multicast++;
}
void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)

View File

@ -314,10 +314,15 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
child, addr);
if (of_mdiobus_child_is_phy(child)) {
/* -ENODEV is the return code that PHYLIB has
* standardized on to indicate that bus
* scanning should continue.
*/
rc = of_mdiobus_register_phy(mdio, child, addr);
if (rc && rc != -ENODEV)
if (!rc)
break;
if (rc != -ENODEV)
goto unregister;
break;
}
}
}

View File

@ -4544,9 +4544,6 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
int fallback = *(int *)reply->param;
QETH_CARD_TEXT(card, 4, "setaccb");
if (cmd->hdr.return_code)
return -EIO;
qeth_setadpparms_inspect_rc(cmd);
access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
QETH_CARD_TEXT_(card, 2, "rc=%d",
@ -4556,7 +4553,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%#x) on device %x: %#x\n",
access_ctrl_req->subcmd_code, CARD_DEVID(card),
cmd->data.setadapterparms.hdr.return_code);
switch (cmd->data.setadapterparms.hdr.return_code) {
switch (qeth_setadpparms_inspect_rc(cmd)) {
case SET_ACCESS_CTRL_RC_SUCCESS:
if (card->options.isolation == ISOLATION_MODE_NONE) {
dev_info(&card->gdev->dev,
@ -6840,9 +6837,11 @@ netdev_features_t qeth_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
struct qeth_card *card = dev->ml_priv;
/* Traffic with local next-hop is not eligible for some offloads: */
if (skb->ip_summed == CHECKSUM_PARTIAL) {
struct qeth_card *card = dev->ml_priv;
if (skb->ip_summed == CHECKSUM_PARTIAL &&
card->options.isolation != ISOLATION_MODE_FWD) {
netdev_features_t restricted = 0;
if (skb_is_gso(skb) && !netif_needs_gso(skb, features))

View File

@ -3157,7 +3157,7 @@ static inline int dev_recursion_level(void)
return this_cpu_read(softnet_data.xmit.recursion);
}
#define XMIT_RECURSION_LIMIT 10
#define XMIT_RECURSION_LIMIT 8
static inline bool dev_xmit_recursion(void)
{
return unlikely(__this_cpu_read(softnet_data.xmit.recursion) >

View File

@ -25,6 +25,12 @@
int ipt_register_table(struct net *net, const struct xt_table *table,
const struct ipt_replace *repl,
const struct nf_hook_ops *ops, struct xt_table **res);
void ipt_unregister_table_pre_exit(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops);
void ipt_unregister_table_exit(struct net *net, struct xt_table *table);
void ipt_unregister_table(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops);

View File

@ -29,6 +29,9 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
const struct nf_hook_ops *ops, struct xt_table **res);
void ip6t_unregister_table(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops);
void ip6t_unregister_table_pre_exit(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops);
void ip6t_unregister_table_exit(struct net *net, struct xt_table *table);
extern unsigned int ip6t_do_table(struct sk_buff *skb,
const struct nf_hook_state *state,
struct xt_table *table);

View File

@ -1416,6 +1416,7 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev,
int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
int phy_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
int phy_do_ioctl_running(struct net_device *dev, struct ifreq *ifr, int cmd);
int phy_disable_interrupts(struct phy_device *phydev);
void phy_request_interrupt(struct phy_device *phydev);
void phy_free_interrupt(struct phy_device *phydev);
void phy_print_status(struct phy_device *phydev);

View File

@ -207,28 +207,34 @@ static inline u32 qed_chain_get_cons_idx_u32(struct qed_chain *p_chain)
static inline u16 qed_chain_get_elem_left(struct qed_chain *p_chain)
{
u16 elem_per_page = p_chain->elem_per_page;
u32 prod = p_chain->u.chain16.prod_idx;
u32 cons = p_chain->u.chain16.cons_idx;
u16 used;
used = (u16) (((u32)0x10000 +
(u32)p_chain->u.chain16.prod_idx) -
(u32)p_chain->u.chain16.cons_idx);
if (prod < cons)
prod += (u32)U16_MAX + 1;
used = (u16)(prod - cons);
if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
used -= p_chain->u.chain16.prod_idx / p_chain->elem_per_page -
p_chain->u.chain16.cons_idx / p_chain->elem_per_page;
used -= prod / elem_per_page - cons / elem_per_page;
return (u16)(p_chain->capacity - used);
}
static inline u32 qed_chain_get_elem_left_u32(struct qed_chain *p_chain)
{
u16 elem_per_page = p_chain->elem_per_page;
u64 prod = p_chain->u.chain32.prod_idx;
u64 cons = p_chain->u.chain32.cons_idx;
u32 used;
used = (u32) (((u64)0x100000000ULL +
(u64)p_chain->u.chain32.prod_idx) -
(u64)p_chain->u.chain32.cons_idx);
if (prod < cons)
prod += (u64)U32_MAX + 1;
used = (u32)(prod - cons);
if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
used -= p_chain->u.chain32.prod_idx / p_chain->elem_per_page -
p_chain->u.chain32.cons_idx / p_chain->elem_per_page;
used -= (u32)(prod / elem_per_page - cons / elem_per_page);
return p_chain->capacity - used;
}

View File

@ -450,6 +450,7 @@ struct flow_block_indr {
struct net_device *dev;
enum flow_block_binder_type binder_type;
void *data;
void *cb_priv;
void (*cleanup)(struct flow_block_cb *block_cb);
};
@ -467,6 +468,13 @@ struct flow_block_cb {
struct flow_block_cb *flow_block_cb_alloc(flow_setup_cb_t *cb,
void *cb_ident, void *cb_priv,
void (*release)(void *cb_priv));
struct flow_block_cb *flow_indr_block_cb_alloc(flow_setup_cb_t *cb,
void *cb_ident, void *cb_priv,
void (*release)(void *cb_priv),
struct flow_block_offload *bo,
struct net_device *dev, void *data,
void *indr_cb_priv,
void (*cleanup)(struct flow_block_cb *block_cb));
void flow_block_cb_free(struct flow_block_cb *block_cb);
struct flow_block_cb *flow_block_cb_lookup(struct flow_block *block,
@ -488,6 +496,13 @@ static inline void flow_block_cb_remove(struct flow_block_cb *block_cb,
list_move(&block_cb->list, &offload->cb_list);
}
static inline void flow_indr_block_cb_remove(struct flow_block_cb *block_cb,
struct flow_block_offload *offload)
{
list_del(&block_cb->indr.list);
list_move(&block_cb->list, &offload->cb_list);
}
bool flow_block_cb_is_busy(flow_setup_cb_t *cb, void *cb_ident,
struct list_head *driver_block_list);
@ -532,11 +547,13 @@ static inline void flow_block_init(struct flow_block *flow_block)
}
typedef int flow_indr_block_bind_cb_t(struct net_device *dev, void *cb_priv,
enum tc_setup_type type, void *type_data);
enum tc_setup_type type, void *type_data,
void *data,
void (*cleanup)(struct flow_block_cb *block_cb));
int flow_indr_dev_register(flow_indr_block_bind_cb_t *cb, void *cb_priv);
void flow_indr_dev_unregister(flow_indr_block_bind_cb_t *cb, void *cb_priv,
flow_setup_cb_t *setup_cb);
void (*release)(void *cb_priv));
int flow_indr_dev_setup_offload(struct net_device *dev,
enum tc_setup_type type, void *data,
struct flow_block_offload *bo,

View File

@ -21,7 +21,7 @@
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* C bit indicates contol message when set, data message when unset.
* C bit indicates control message when set, data message when unset.
* For a control message, proto/ctype is interpreted as a type of
* control message. For data messages, proto/ctype is the IP protocol
* of the next header.

View File

@ -353,11 +353,13 @@ enum {
ipv4_is_anycast_6to4(a))
/* Flags used for the bind address copy functions. */
#define SCTP_ADDR6_ALLOWED 0x00000001 /* IPv6 address is allowed by
#define SCTP_ADDR4_ALLOWED 0x00000001 /* IPv4 address is allowed by
local sock family */
#define SCTP_ADDR4_PEERSUPP 0x00000002 /* IPv4 address is supported by
#define SCTP_ADDR6_ALLOWED 0x00000002 /* IPv6 address is allowed by
local sock family */
#define SCTP_ADDR4_PEERSUPP 0x00000004 /* IPv4 address is supported by
peer */
#define SCTP_ADDR6_PEERSUPP 0x00000004 /* IPv6 address is supported by
#define SCTP_ADDR6_PEERSUPP 0x00000008 /* IPv6 address is supported by
peer */
/* Reasons to retransmit. */

View File

@ -1848,7 +1848,6 @@ static inline int sk_rx_queue_get(const struct sock *sk)
static inline void sk_set_socket(struct sock *sk, struct socket *sock)
{
sk_tx_queue_clear(sk);
sk->sk_socket = sock;
}

View File

@ -1008,6 +1008,7 @@ struct xfrm_offload {
#define XFRM_GRO 32
#define XFRM_ESP_NO_TRAILER 64
#define XFRM_DEV_RESUME 128
#define XFRM_XMIT 256
__u32 status;
#define CRYPTO_SUCCESS 1

View File

@ -400,7 +400,7 @@ enum rxrpc_tx_point {
EM(rxrpc_cong_begin_retransmission, " Retrans") \
EM(rxrpc_cong_cleared_nacks, " Cleared") \
EM(rxrpc_cong_new_low_nack, " NewLowN") \
EM(rxrpc_cong_no_change, "") \
EM(rxrpc_cong_no_change, " -") \
EM(rxrpc_cong_progress, " Progres") \
EM(rxrpc_cong_retransmit_again, " ReTxAgn") \
EM(rxrpc_cong_rtt_window_end, " RttWinE") \

View File

@ -3168,7 +3168,7 @@ union bpf_attr {
* Return
* The id is returned or 0 in case the id could not be retrieved.
*
* void *bpf_ringbuf_output(void *ringbuf, void *data, u64 size, u64 flags)
* int bpf_ringbuf_output(void *ringbuf, void *data, u64 size, u64 flags)
* Description
* Copy *size* bytes from *data* into a ring buffer *ringbuf*.
* If BPF_RB_NO_WAKEUP is specified in *flags*, no notification of

View File

@ -36,7 +36,6 @@ enum br_mrp_port_state_type {
enum br_mrp_port_role_type {
BR_MRP_PORT_ROLE_PRIMARY,
BR_MRP_PORT_ROLE_SECONDARY,
BR_MRP_PORT_ROLE_NONE,
};
enum br_mrp_tlv_header_type {

View File

@ -64,10 +64,12 @@
/* supported values for SO_RDS_TRANSPORT */
#define RDS_TRANS_IB 0
#define RDS_TRANS_IWARP 1
#define RDS_TRANS_GAP 1
#define RDS_TRANS_TCP 2
#define RDS_TRANS_COUNT 3
#define RDS_TRANS_NONE (~0)
/* don't use RDS_TRANS_IWARP - it is deprecated */
#define RDS_TRANS_IWARP RDS_TRANS_GAP
/* IOCTLS commands for SOL_RDS */
#define SIOCRDSSETTOS (SIOCPROTOPRIVATE)

View File

@ -1276,16 +1276,23 @@ static bool __cgroup_bpf_prog_array_is_empty(struct cgroup *cgrp,
static int sockopt_alloc_buf(struct bpf_sockopt_kern *ctx, int max_optlen)
{
if (unlikely(max_optlen > PAGE_SIZE) || max_optlen < 0)
if (unlikely(max_optlen < 0))
return -EINVAL;
if (unlikely(max_optlen > PAGE_SIZE)) {
/* We don't expose optvals that are greater than PAGE_SIZE
* to the BPF program.
*/
max_optlen = PAGE_SIZE;
}
ctx->optval = kzalloc(max_optlen, GFP_USER);
if (!ctx->optval)
return -ENOMEM;
ctx->optval_end = ctx->optval + max_optlen;
return 0;
return max_optlen;
}
static void sockopt_free_buf(struct bpf_sockopt_kern *ctx)
@ -1319,13 +1326,13 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
*/
max_optlen = max_t(int, 16, *optlen);
ret = sockopt_alloc_buf(&ctx, max_optlen);
if (ret)
return ret;
max_optlen = sockopt_alloc_buf(&ctx, max_optlen);
if (max_optlen < 0)
return max_optlen;
ctx.optlen = *optlen;
if (copy_from_user(ctx.optval, optval, *optlen) != 0) {
if (copy_from_user(ctx.optval, optval, min(*optlen, max_optlen)) != 0) {
ret = -EFAULT;
goto out;
}
@ -1353,8 +1360,14 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
/* export any potential modifications */
*level = ctx.level;
*optname = ctx.optname;
*optlen = ctx.optlen;
*kernel_optval = ctx.optval;
/* optlen == 0 from BPF indicates that we should
* use original userspace data.
*/
if (ctx.optlen != 0) {
*optlen = ctx.optlen;
*kernel_optval = ctx.optval;
}
}
out:
@ -1385,12 +1398,12 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
__cgroup_bpf_prog_array_is_empty(cgrp, BPF_CGROUP_GETSOCKOPT))
return retval;
ret = sockopt_alloc_buf(&ctx, max_optlen);
if (ret)
return ret;
ctx.optlen = max_optlen;
max_optlen = sockopt_alloc_buf(&ctx, max_optlen);
if (max_optlen < 0)
return max_optlen;
if (!retval) {
/* If kernel getsockopt finished successfully,
* copy whatever was returned to the user back
@ -1404,10 +1417,8 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
goto out;
}
if (ctx.optlen > max_optlen)
ctx.optlen = max_optlen;
if (copy_from_user(ctx.optval, optval, ctx.optlen) != 0) {
if (copy_from_user(ctx.optval, optval,
min(ctx.optlen, max_optlen)) != 0) {
ret = -EFAULT;
goto out;
}
@ -1436,10 +1447,12 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
goto out;
}
if (copy_to_user(optval, ctx.optval, ctx.optlen) ||
put_user(ctx.optlen, optlen)) {
ret = -EFAULT;
goto out;
if (ctx.optlen != 0) {
if (copy_to_user(optval, ctx.optval, ctx.optlen) ||
put_user(ctx.optlen, optlen)) {
ret = -EFAULT;
goto out;
}
}
ret = ctx.retval;

Some files were not shown because too many files have changed in this diff Show More