Import of kernel-5.14.0-687.17.1.el9_8
This commit is contained in:
parent
9bb58011ba
commit
36c7b56810
@ -65,35 +65,43 @@ request, where user provides attributes that result in single pin match.
|
||||
Pin selection
|
||||
=============
|
||||
|
||||
In general, selected pin (the one which signal is driving the dpll
|
||||
device) can be obtained from ``DPLL_A_PIN_STATE`` attribute, and only
|
||||
one pin shall be in ``DPLL_PIN_STATE_CONNECTED`` state for any dpll
|
||||
device.
|
||||
Pin state (``DPLL_A_PIN_STATE``) reflects the administrative intent set
|
||||
by the user. Pin operational state (``DPLL_A_PIN_OPERSTATE``) reflects
|
||||
what the hardware is actually doing with the pin.
|
||||
|
||||
Pin selection can be done either manually or automatically, depending
|
||||
on hardware capabilities and active dpll device work mode
|
||||
(``DPLL_A_MODE`` attribute). The consequence is that there are
|
||||
differences for each mode in terms of available pin states, as well as
|
||||
for the states the user can request for a dpll device.
|
||||
differences for each mode in terms of available pin states the user can
|
||||
request for a dpll device.
|
||||
|
||||
In manual mode (``DPLL_MODE_MANUAL``) the user can request or receive
|
||||
one of following pin states:
|
||||
In manual mode (``DPLL_MODE_MANUAL``) the user can request one of
|
||||
following pin states:
|
||||
|
||||
- ``DPLL_PIN_STATE_CONNECTED`` - the pin is used to drive dpll device
|
||||
- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not used to drive dpll
|
||||
- ``DPLL_PIN_STATE_CONNECTED`` - the pin is selected to drive dpll
|
||||
device
|
||||
- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not selected to drive
|
||||
dpll device
|
||||
|
||||
In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request or
|
||||
receive one of following pin states:
|
||||
In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request one of
|
||||
following pin states:
|
||||
|
||||
- ``DPLL_PIN_STATE_SELECTABLE`` - the pin shall be considered as valid
|
||||
input for automatic selection algorithm
|
||||
- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin shall be not considered as
|
||||
a valid input for automatic selection algorithm
|
||||
|
||||
In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can only receive
|
||||
pin state ``DPLL_PIN_STATE_CONNECTED`` once automatic selection
|
||||
algorithm locks a dpll device with one of the inputs.
|
||||
The actual hardware status of a pin is reported via the operational
|
||||
state (``DPLL_A_PIN_OPERSTATE``) attribute nested under the parent
|
||||
device:
|
||||
|
||||
- ``DPLL_PIN_OPERSTATE_ACTIVE`` - pin is qualified and actively used
|
||||
by the DPLL
|
||||
- ``DPLL_PIN_OPERSTATE_STANDBY`` - pin is qualified but not actively
|
||||
used by the DPLL
|
||||
- ``DPLL_PIN_OPERSTATE_NO_SIGNAL`` - pin does not have a valid signal
|
||||
- ``DPLL_PIN_OPERSTATE_QUAL_FAILED`` - pin signal failed qualification
|
||||
checks
|
||||
|
||||
Shared pins
|
||||
===========
|
||||
@ -250,6 +258,26 @@ in the ``DPLL_A_PIN_PHASE_OFFSET`` attribute.
|
||||
``DPLL_A_PHASE_OFFSET_MONITOR`` attr state of a feature
|
||||
=============================== ========================
|
||||
|
||||
Fractional frequency offset
|
||||
===========================
|
||||
|
||||
The fractional frequency offset (FFO) is reported through two attributes
|
||||
that carry the same measurement at different precisions:
|
||||
|
||||
- ``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET`` in PPM (parts per million)
|
||||
- ``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT`` in PPT (parts per trillion)
|
||||
|
||||
Both attributes appear at the top level of a pin and inside each
|
||||
``pin-parent-device`` nest. Two FFO types are defined:
|
||||
|
||||
- ``DPLL_FFO_PORT_RXTX_RATE`` - RX vs TX symbol rate offset (top-level)
|
||||
- ``DPLL_FFO_PIN_DEVICE`` - pin vs parent DPLL offset (per-parent)
|
||||
|
||||
The driver declares which types it supports via the ``supported_ffo``
|
||||
bitmask in ``struct dpll_pin_ops``. The core only calls the ``ffo_get``
|
||||
callback for types the driver has opted into. The requested type is
|
||||
passed to the driver in the ``struct dpll_ffo_param``.
|
||||
|
||||
Frequency monitor
|
||||
=================
|
||||
|
||||
|
||||
@ -212,6 +212,27 @@ definitions:
|
||||
name: selectable
|
||||
doc: pin enabled for automatic input selection
|
||||
render-max: true
|
||||
-
|
||||
type: enum
|
||||
name: pin-operstate
|
||||
doc: |
|
||||
defines possible operational states of a pin with respect to its
|
||||
parent DPLL device, valid values for DPLL_A_PIN_OPERSTATE attribute
|
||||
entries:
|
||||
-
|
||||
name: active
|
||||
doc: pin is qualified and actively used by the DPLL
|
||||
value: 1
|
||||
-
|
||||
name: standby
|
||||
doc: pin is qualified but not actively used by the DPLL
|
||||
-
|
||||
name: no-signal
|
||||
doc: pin does not have a valid signal
|
||||
-
|
||||
name: qual-failed
|
||||
doc: pin signal failed qualification (e.g. frequency or phase monitor)
|
||||
render-max: true
|
||||
-
|
||||
type: flags
|
||||
name: pin-capabilities
|
||||
@ -427,12 +448,14 @@ attribute-sets:
|
||||
name: fractional-frequency-offset
|
||||
type: sint
|
||||
doc: |
|
||||
The FFO (Fractional Frequency Offset) between the RX and TX
|
||||
symbol rate on the media associated with the pin:
|
||||
(rx_frequency-tx_frequency)/rx_frequency
|
||||
The FFO (Fractional Frequency Offset) of the pin.
|
||||
At top level this represents the RX vs TX symbol rate
|
||||
offset on the media associated with the pin. Inside
|
||||
the pin-parent-device nest it represents the frequency
|
||||
offset between the pin and its parent DPLL device.
|
||||
Value is in PPM (parts per million).
|
||||
This may be implemented for example for pin of type
|
||||
PIN_TYPE_SYNCE_ETH_PORT.
|
||||
This is a lower-precision version of
|
||||
fractional-frequency-offset-ppt.
|
||||
-
|
||||
name: esync-frequency
|
||||
type: u64
|
||||
@ -471,12 +494,14 @@ attribute-sets:
|
||||
name: fractional-frequency-offset-ppt
|
||||
type: sint
|
||||
doc: |
|
||||
The FFO (Fractional Frequency Offset) of the pin with respect to
|
||||
the nominal frequency.
|
||||
Value = (frequency_measured - frequency_nominal) / frequency_nominal
|
||||
The FFO (Fractional Frequency Offset) of the pin.
|
||||
At top level this represents the RX vs TX symbol rate
|
||||
offset on the media associated with the pin. Inside
|
||||
the pin-parent-device nest it represents the frequency
|
||||
offset between the pin and its parent DPLL device.
|
||||
Value is in PPT (parts per trillion, 10^-12).
|
||||
Note: This attribute provides higher resolution than the standard
|
||||
fractional-frequency-offset (which is in PPM).
|
||||
This is a higher-precision version of
|
||||
fractional-frequency-offset.
|
||||
-
|
||||
name: measured-frequency
|
||||
type: u64
|
||||
@ -488,6 +513,14 @@ attribute-sets:
|
||||
Value of (DPLL_A_PIN_MEASURED_FREQUENCY %
|
||||
DPLL_PIN_MEASURED_FREQUENCY_DIVIDER) is a fractional part
|
||||
of a measured frequency value.
|
||||
-
|
||||
name: operstate
|
||||
type: u32
|
||||
enum: pin-operstate
|
||||
doc: |
|
||||
Operational state of the pin with respect to its parent DPLL
|
||||
device. Unlike state (which reflects the administrative intent),
|
||||
operstate reflects the actual hardware status.
|
||||
|
||||
-
|
||||
name: pin-parent-device
|
||||
@ -501,8 +534,14 @@ attribute-sets:
|
||||
name: prio
|
||||
-
|
||||
name: state
|
||||
-
|
||||
name: operstate
|
||||
-
|
||||
name: phase-offset
|
||||
-
|
||||
name: fractional-frequency-offset
|
||||
-
|
||||
name: fractional-frequency-offset-ppt
|
||||
-
|
||||
name: pin-parent-pin
|
||||
subset-of: pin
|
||||
|
||||
@ -547,10 +547,18 @@ void do_secure_storage_access(struct pt_regs *regs)
|
||||
page = phys_to_page(addr);
|
||||
if (unlikely(!try_get_page(page)))
|
||||
break;
|
||||
rc = arch_make_page_accessible(page);
|
||||
|
||||
rc = uv_convert_from_secure(addr);
|
||||
if (!rc)
|
||||
clear_bit(PG_arch_1, &page->flags);
|
||||
put_page(page);
|
||||
/*
|
||||
* There are some valid fixup types for kernel
|
||||
* accesses to donated secure memory. zeropad is one
|
||||
* of them.
|
||||
*/
|
||||
if (rc)
|
||||
BUG();
|
||||
return handle_fault_error_nolock(regs, 0);
|
||||
break;
|
||||
default:
|
||||
unreachable();
|
||||
|
||||
@ -4547,24 +4547,12 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cancel_tasks_sync(struct rbd_device *rbd_dev)
|
||||
{
|
||||
dout("%s rbd_dev %p\n", __func__, rbd_dev);
|
||||
|
||||
cancel_work_sync(&rbd_dev->acquired_lock_work);
|
||||
cancel_work_sync(&rbd_dev->released_lock_work);
|
||||
cancel_delayed_work_sync(&rbd_dev->lock_dwork);
|
||||
cancel_work_sync(&rbd_dev->unlock_work);
|
||||
}
|
||||
|
||||
/*
|
||||
* header_rwsem must not be held to avoid a deadlock with
|
||||
* rbd_dev_refresh() when flushing notifies.
|
||||
*/
|
||||
static void rbd_unregister_watch(struct rbd_device *rbd_dev)
|
||||
{
|
||||
cancel_tasks_sync(rbd_dev);
|
||||
|
||||
mutex_lock(&rbd_dev->watch_mutex);
|
||||
if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED)
|
||||
__rbd_unregister_watch(rbd_dev);
|
||||
@ -6541,10 +6529,18 @@ out_err:
|
||||
|
||||
static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)
|
||||
{
|
||||
dout("%s rbd_dev %p\n", __func__, rbd_dev);
|
||||
|
||||
disable_delayed_work_sync(&rbd_dev->lock_dwork);
|
||||
disable_work_sync(&rbd_dev->unlock_work);
|
||||
|
||||
down_write(&rbd_dev->lock_rwsem);
|
||||
if (__rbd_is_lock_owner(rbd_dev))
|
||||
__rbd_release_lock(rbd_dev);
|
||||
up_write(&rbd_dev->lock_rwsem);
|
||||
|
||||
flush_work(&rbd_dev->acquired_lock_work);
|
||||
flush_work(&rbd_dev->released_lock_work);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -883,7 +883,8 @@ dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
|
||||
WARN_ON(!ops->direction_get) ||
|
||||
WARN_ON(ops->measured_freq_get &&
|
||||
(!dpll_device_ops(dpll)->freq_monitor_get ||
|
||||
!dpll_device_ops(dpll)->freq_monitor_set)))
|
||||
!dpll_device_ops(dpll)->freq_monitor_set)) ||
|
||||
WARN_ON(ops->supported_ffo && !ops->ffo_get))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&dpll_lock);
|
||||
|
||||
@ -324,6 +324,30 @@ dpll_msg_add_pin_on_dpll_state(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dpll_msg_add_pin_operstate(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
struct dpll_pin_ref *ref,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
|
||||
struct dpll_device *dpll = ref->dpll;
|
||||
enum dpll_pin_operstate operstate;
|
||||
int ret;
|
||||
|
||||
if (!ops->operstate_on_dpll_get)
|
||||
return 0;
|
||||
ret = ops->operstate_on_dpll_get(pin,
|
||||
dpll_pin_on_dpll_priv(dpll, pin),
|
||||
dpll, dpll_priv(dpll),
|
||||
&operstate, extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (nla_put_u32(msg, DPLL_A_PIN_OPERSTATE, operstate))
|
||||
return -EMSGSIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dpll_msg_add_pin_direction(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
struct dpll_pin_ref *ref,
|
||||
@ -393,31 +417,34 @@ dpll_msg_add_phase_offset(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
|
||||
static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
struct dpll_pin_ref *ref,
|
||||
enum dpll_ffo_type type,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
|
||||
struct dpll_device *dpll = ref->dpll;
|
||||
s64 ffo;
|
||||
struct dpll_ffo_param ffo = { .type = type };
|
||||
int ret;
|
||||
|
||||
if (!ops->ffo_get)
|
||||
return 0;
|
||||
ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
|
||||
dpll, dpll_priv(dpll), &ffo, extack);
|
||||
/* RHEL: To maintain backward compatibility with older binary modules,
|
||||
* we must accept a value of zero for .supported_ffo when the type is
|
||||
* DPLL_FFO_PORT_RXTX_RATE.
|
||||
*/
|
||||
if (!ops->ffo_get ||
|
||||
!((ops->supported_ffo & BIT(type)) ||
|
||||
(!ops->supported_ffo && type == DPLL_FFO_PORT_RXTX_RATE)))
|
||||
return 0;
|
||||
ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(ref->dpll, pin),
|
||||
ref->dpll, dpll_priv(ref->dpll), &ffo, extack);
|
||||
if (ret) {
|
||||
if (ret == -ENODATA)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
/* Put the FFO value in PPM to preserve compatibility with older
|
||||
* programs.
|
||||
*/
|
||||
ret = nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
|
||||
div_s64(ffo, 1000000));
|
||||
if (ret)
|
||||
if (nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
|
||||
div_s64(ffo.ffo, 1000000)))
|
||||
return -EMSGSIZE;
|
||||
return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
|
||||
ffo);
|
||||
return nla_put_sint(msg,
|
||||
DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
|
||||
ffo.ffo);
|
||||
}
|
||||
|
||||
static int dpll_msg_add_measured_freq(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
@ -650,6 +677,9 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
if (ret)
|
||||
goto nest_cancel;
|
||||
ret = dpll_msg_add_pin_on_dpll_state(msg, pin, ref, extack);
|
||||
if (ret)
|
||||
goto nest_cancel;
|
||||
ret = dpll_msg_add_pin_operstate(msg, pin, ref, extack);
|
||||
if (ret)
|
||||
goto nest_cancel;
|
||||
ret = dpll_msg_add_pin_prio(msg, pin, ref, extack);
|
||||
@ -659,6 +689,10 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
if (ret)
|
||||
goto nest_cancel;
|
||||
ret = dpll_msg_add_phase_offset(msg, pin, ref, extack);
|
||||
if (ret)
|
||||
goto nest_cancel;
|
||||
ret = dpll_msg_add_ffo(msg, pin, ref,
|
||||
DPLL_FFO_PIN_DEVICE, extack);
|
||||
if (ret)
|
||||
goto nest_cancel;
|
||||
nla_nest_end(msg, attr);
|
||||
@ -721,7 +755,8 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
ret = dpll_msg_add_pin_phase_adjust(msg, pin, ref, extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = dpll_msg_add_ffo(msg, pin, ref, extack);
|
||||
ret = dpll_msg_add_ffo(msg, pin, ref,
|
||||
DPLL_FFO_PORT_RXTX_RATE, extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = dpll_msg_add_measured_freq(msg, pin, ref, extack);
|
||||
|
||||
@ -11,12 +11,15 @@
|
||||
#include <uapi/linux/dpll.h>
|
||||
|
||||
/* Common nested types */
|
||||
const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_PHASE_OFFSET + 1] = {
|
||||
const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_OPERSTATE + 1] = {
|
||||
[DPLL_A_PIN_PARENT_ID] = { .type = NLA_U32, },
|
||||
[DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
|
||||
[DPLL_A_PIN_PRIO] = { .type = NLA_U32, },
|
||||
[DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
|
||||
[DPLL_A_PIN_OPERSTATE] = NLA_POLICY_RANGE(NLA_U32, 1, 4),
|
||||
[DPLL_A_PIN_PHASE_OFFSET] = { .type = NLA_S64, },
|
||||
[DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET] = { .type = NLA_SINT, },
|
||||
[DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT] = { .type = NLA_SINT, },
|
||||
};
|
||||
|
||||
const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1] = {
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
#include <uapi/linux/dpll.h>
|
||||
|
||||
/* Common nested types */
|
||||
extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_PHASE_OFFSET + 1];
|
||||
extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_OPERSTATE + 1];
|
||||
extern const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1];
|
||||
extern const struct nla_policy dpll_reference_sync_nl_policy[DPLL_A_PIN_STATE + 1];
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index)
|
||||
{
|
||||
struct zl3073x_chan *chan = &zldev->chan[index];
|
||||
u64 val;
|
||||
int rc;
|
||||
|
||||
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_MON_STATUS(index),
|
||||
@ -25,8 +26,34 @@ int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return zl3073x_read_u8(zldev, ZL_REG_DPLL_REFSEL_STATUS(index),
|
||||
&chan->refsel_status);
|
||||
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_REFSEL_STATUS(index),
|
||||
&chan->refsel_status);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Read df_offset vs tracked reference */
|
||||
rc = zl3073x_poll_zero_u8(zldev, ZL_REG_DPLL_DF_READ(index),
|
||||
ZL_DPLL_DF_READ_SEM);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = zl3073x_write_u8(zldev, ZL_REG_DPLL_DF_READ(index),
|
||||
ZL_DPLL_DF_READ_SEM | ZL_DPLL_DF_READ_REF_OFST);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = zl3073x_poll_zero_u8(zldev, ZL_REG_DPLL_DF_READ(index),
|
||||
ZL_DPLL_DF_READ_SEM);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = zl3073x_read_u48(zldev, ZL_REG_DPLL_DF_OFFSET(index), &val);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
chan->df_offset = sign_extend64(val, 47);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -17,6 +17,7 @@ struct zl3073x_dev;
|
||||
* @ref_prio: reference priority registers (4 bits per ref, P/N packed)
|
||||
* @mon_status: monitor status register value
|
||||
* @refsel_status: reference selection status register value
|
||||
* @df_offset: frequency offset vs tracked reference in 2^-48 steps
|
||||
*/
|
||||
struct zl3073x_chan {
|
||||
struct_group(cfg,
|
||||
@ -26,6 +27,7 @@ struct zl3073x_chan {
|
||||
struct_group(stat,
|
||||
u8 mon_status;
|
||||
u8 refsel_status;
|
||||
s64 df_offset;
|
||||
);
|
||||
};
|
||||
|
||||
@ -37,6 +39,18 @@ int zl3073x_chan_state_set(struct zl3073x_dev *zldev, u8 index,
|
||||
|
||||
int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index);
|
||||
|
||||
/**
|
||||
* zl3073x_chan_df_offset_get - get cached df_offset vs tracked reference
|
||||
* @chan: pointer to channel state
|
||||
*
|
||||
* Return: frequency offset in 2^-48 steps
|
||||
*/
|
||||
static inline s64
|
||||
zl3073x_chan_df_offset_get(const struct zl3073x_chan *chan)
|
||||
{
|
||||
return chan->df_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* zl3073x_chan_mode_get - get DPLL channel operating mode
|
||||
* @chan: pointer to channel state
|
||||
|
||||
@ -704,44 +704,6 @@ zl3073x_ref_freq_meas_update(struct zl3073x_dev *zldev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* zl3073x_ref_ffo_update - update reference fractional frequency offsets
|
||||
* @zldev: pointer to zl3073x_dev structure
|
||||
*
|
||||
* The function asks device to latch the latest measured fractional
|
||||
* frequency offset values, reads and stores them into the ref state.
|
||||
*
|
||||
* Return: 0 on success, <0 on error
|
||||
*/
|
||||
static int
|
||||
zl3073x_ref_ffo_update(struct zl3073x_dev *zldev)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
rc = zl3073x_ref_freq_meas_latch(zldev,
|
||||
ZL_REF_FREQ_MEAS_CTRL_REF_FREQ_OFF);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Read DPLL-to-REFx frequency offset measurements */
|
||||
for (i = 0; i < ZL3073X_NUM_REFS; i++) {
|
||||
s32 value;
|
||||
|
||||
/* Read value stored in units of 2^-32 signed */
|
||||
rc = zl3073x_read_u32(zldev, ZL_REG_REF_FREQ(i), &value);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Convert to ppt
|
||||
* ffo = (10^12 * value) / 2^32
|
||||
* ffo = ( 5^12 * value) / 2^20
|
||||
*/
|
||||
zldev->ref[i].ffo = mul_s64_u64_shr(value, 244140625, 20);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
zl3073x_dev_periodic_work(struct kthread_work *work)
|
||||
{
|
||||
@ -776,13 +738,6 @@ zl3073x_dev_periodic_work(struct kthread_work *work)
|
||||
}
|
||||
}
|
||||
|
||||
/* Update references' fractional frequency offsets */
|
||||
rc = zl3073x_ref_ffo_update(zldev);
|
||||
if (rc)
|
||||
dev_warn(zldev->dev,
|
||||
"Failed to update fractional frequency offsets: %pe\n",
|
||||
ERR_PTR(rc));
|
||||
|
||||
list_for_each_entry(zldpll, &zldev->dplls, list)
|
||||
zl3073x_dpll_changes_check(zldpll);
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bug.h>
|
||||
@ -38,7 +39,7 @@
|
||||
* @prio: pin priority <0, 14>
|
||||
* @esync_control: embedded sync is controllable
|
||||
* @phase_gran: phase adjustment granularity
|
||||
* @pin_state: last saved pin state
|
||||
* @operstate: last saved operational state
|
||||
* @phase_offset: last saved pin phase offset
|
||||
* @freq_offset: last saved fractional frequency offset
|
||||
* @measured_freq: last saved measured frequency
|
||||
@ -55,9 +56,9 @@ struct zl3073x_dpll_pin {
|
||||
u8 prio;
|
||||
bool esync_control;
|
||||
s32 phase_gran;
|
||||
enum dpll_pin_state pin_state;
|
||||
enum dpll_pin_operstate operstate;
|
||||
s64 phase_offset;
|
||||
s64 freq_offset;
|
||||
atomic64_t freq_offset;
|
||||
u32 measured_freq;
|
||||
};
|
||||
|
||||
@ -295,11 +296,15 @@ zl3073x_dpll_input_pin_ref_sync_set(const struct dpll_pin *dpll_pin,
|
||||
static int
|
||||
zl3073x_dpll_input_pin_ffo_get(const struct dpll_pin *dpll_pin, void *pin_priv,
|
||||
const struct dpll_device *dpll, void *dpll_priv,
|
||||
s64 *ffo, struct netlink_ext_ack *extack)
|
||||
struct dpll_ffo_param *ffo,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct zl3073x_dpll_pin *pin = pin_priv;
|
||||
|
||||
*ffo = pin->freq_offset;
|
||||
if (pin->operstate != DPLL_PIN_OPERSTATE_ACTIVE)
|
||||
return -ENODATA;
|
||||
|
||||
ffo->ffo = atomic64_read(&pin->freq_offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -500,46 +505,41 @@ zl3073x_dpll_input_pin_phase_adjust_set(const struct dpll_pin *dpll_pin,
|
||||
}
|
||||
|
||||
/**
|
||||
* zl3073x_dpll_ref_state_get - get status for given input pin
|
||||
* zl3073x_dpll_ref_operstate_get - get operational state for input pin
|
||||
* @pin: pointer to pin
|
||||
* @state: place to store status
|
||||
* @operstate: place to store operational state
|
||||
*
|
||||
* Checks current status for the given input pin and stores the value
|
||||
* to @state.
|
||||
* Returns the actual hardware state of the pin: whether it is actively
|
||||
* used by the DPLL, has no signal, failed qualification, or is simply
|
||||
* not in use.
|
||||
*
|
||||
* Return: 0 on success, <0 on error
|
||||
*/
|
||||
static int
|
||||
zl3073x_dpll_ref_state_get(struct zl3073x_dpll_pin *pin,
|
||||
enum dpll_pin_state *state)
|
||||
zl3073x_dpll_ref_operstate_get(struct zl3073x_dpll_pin *pin,
|
||||
enum dpll_pin_operstate *operstate)
|
||||
{
|
||||
struct zl3073x_dpll *zldpll = pin->dpll;
|
||||
struct zl3073x_dev *zldev = zldpll->dev;
|
||||
const struct zl3073x_chan *chan;
|
||||
u8 ref;
|
||||
const struct zl3073x_ref *ref;
|
||||
u8 ref_id;
|
||||
|
||||
chan = zl3073x_chan_state_get(zldev, zldpll->id);
|
||||
ref = zl3073x_input_pin_ref_get(pin->id);
|
||||
ref_id = zl3073x_input_pin_ref_get(pin->id);
|
||||
|
||||
/* Check if the pin reference is connected */
|
||||
if (ref == zl3073x_dpll_connected_ref_get(zldpll)) {
|
||||
*state = DPLL_PIN_STATE_CONNECTED;
|
||||
/* Check if this pin is the currently locked reference */
|
||||
if (ref_id == zl3073x_dpll_connected_ref_get(zldpll)) {
|
||||
*operstate = DPLL_PIN_OPERSTATE_ACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the DPLL is running in automatic mode and the reference is
|
||||
* selectable and its monitor does not report any error then report
|
||||
* pin as selectable.
|
||||
*/
|
||||
if (zl3073x_chan_mode_get(chan) == ZL_DPLL_MODE_REFSEL_MODE_AUTO &&
|
||||
zl3073x_dev_ref_is_status_ok(zldev, ref) &&
|
||||
zl3073x_chan_ref_is_selectable(chan, ref)) {
|
||||
*state = DPLL_PIN_STATE_SELECTABLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise report the pin as disconnected */
|
||||
*state = DPLL_PIN_STATE_DISCONNECTED;
|
||||
/* Check reference monitor status */
|
||||
ref = zl3073x_ref_state_get(zldev, ref_id);
|
||||
if (ref->mon_status & ZL_REF_MON_STATUS_LOS)
|
||||
*operstate = DPLL_PIN_OPERSTATE_NO_SIGNAL;
|
||||
else if (!zl3073x_ref_is_status_ok(ref))
|
||||
*operstate = DPLL_PIN_OPERSTATE_QUAL_FAILED;
|
||||
else
|
||||
*operstate = DPLL_PIN_OPERSTATE_STANDBY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -551,10 +551,48 @@ zl3073x_dpll_input_pin_state_on_dpll_get(const struct dpll_pin *dpll_pin,
|
||||
void *dpll_priv,
|
||||
enum dpll_pin_state *state,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct zl3073x_dpll *zldpll = dpll_priv;
|
||||
struct zl3073x_dpll_pin *pin = pin_priv;
|
||||
const struct zl3073x_chan *chan;
|
||||
u8 mode, ref;
|
||||
|
||||
chan = zl3073x_chan_state_get(zldpll->dev, zldpll->id);
|
||||
ref = zl3073x_input_pin_ref_get(pin->id);
|
||||
mode = zl3073x_chan_mode_get(chan);
|
||||
|
||||
switch (mode) {
|
||||
case ZL_DPLL_MODE_REFSEL_MODE_REFLOCK:
|
||||
if (ref == zl3073x_chan_ref_get(chan))
|
||||
*state = DPLL_PIN_STATE_CONNECTED;
|
||||
else
|
||||
*state = DPLL_PIN_STATE_DISCONNECTED;
|
||||
break;
|
||||
case ZL_DPLL_MODE_REFSEL_MODE_AUTO:
|
||||
if (zl3073x_chan_ref_is_selectable(chan, ref))
|
||||
*state = DPLL_PIN_STATE_SELECTABLE;
|
||||
else
|
||||
*state = DPLL_PIN_STATE_DISCONNECTED;
|
||||
break;
|
||||
default:
|
||||
*state = DPLL_PIN_STATE_DISCONNECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
zl3073x_dpll_input_pin_operstate_on_dpll_get(const struct dpll_pin *dpll_pin,
|
||||
void *pin_priv,
|
||||
const struct dpll_device *dpll,
|
||||
void *dpll_priv,
|
||||
enum dpll_pin_operstate *operstate,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct zl3073x_dpll_pin *pin = pin_priv;
|
||||
|
||||
return zl3073x_dpll_ref_state_get(pin, state);
|
||||
return zl3073x_dpll_ref_operstate_get(pin, operstate);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1241,6 +1279,7 @@ zl3073x_dpll_freq_monitor_set(const struct dpll_device *dpll,
|
||||
}
|
||||
|
||||
static const struct dpll_pin_ops zl3073x_dpll_input_pin_ops = {
|
||||
.supported_ffo = BIT(DPLL_FFO_PIN_DEVICE),
|
||||
.direction_get = zl3073x_dpll_pin_direction_get,
|
||||
.esync_get = zl3073x_dpll_input_pin_esync_get,
|
||||
.esync_set = zl3073x_dpll_input_pin_esync_set,
|
||||
@ -1248,6 +1287,7 @@ static const struct dpll_pin_ops zl3073x_dpll_input_pin_ops = {
|
||||
.frequency_get = zl3073x_dpll_input_pin_frequency_get,
|
||||
.frequency_set = zl3073x_dpll_input_pin_frequency_set,
|
||||
.measured_freq_get = zl3073x_dpll_input_pin_measured_freq_get,
|
||||
.operstate_on_dpll_get = zl3073x_dpll_input_pin_operstate_on_dpll_get,
|
||||
.phase_offset_get = zl3073x_dpll_input_pin_phase_offset_get,
|
||||
.phase_adjust_get = zl3073x_dpll_input_pin_phase_adjust_get,
|
||||
.phase_adjust_set = zl3073x_dpll_input_pin_phase_adjust_set,
|
||||
@ -1663,7 +1703,7 @@ zl3073x_dpll_pin_phase_offset_check(struct zl3073x_dpll_pin *pin)
|
||||
* 2) For other pins use appropriate ref_phase register if the phase
|
||||
* monitor feature is enabled.
|
||||
*/
|
||||
if (pin->pin_state == DPLL_PIN_STATE_CONNECTED)
|
||||
if (pin->operstate == DPLL_PIN_OPERSTATE_ACTIVE)
|
||||
reg = ZL_REG_DPLL_PHASE_ERR_DATA(zldpll->id);
|
||||
else if (zldpll->phase_monitor)
|
||||
reg = ZL_REG_REF_PHASE(ref_id);
|
||||
@ -1695,37 +1735,29 @@ zl3073x_dpll_pin_phase_offset_check(struct zl3073x_dpll_pin *pin)
|
||||
}
|
||||
|
||||
/**
|
||||
* zl3073x_dpll_pin_ffo_check - check for pin fractional frequency offset change
|
||||
* zl3073x_dpll_pin_ffo_check - check for FFO change on active pin
|
||||
* @pin: pin to check
|
||||
*
|
||||
* Check for the given pin's fractional frequency change.
|
||||
*
|
||||
* Return: true on fractional frequency offset change, false otherwise
|
||||
* Return: true on change, false otherwise
|
||||
*/
|
||||
static bool
|
||||
zl3073x_dpll_pin_ffo_check(struct zl3073x_dpll_pin *pin)
|
||||
{
|
||||
struct zl3073x_dpll *zldpll = pin->dpll;
|
||||
struct zl3073x_dev *zldev = zldpll->dev;
|
||||
const struct zl3073x_ref *ref;
|
||||
u8 ref_id;
|
||||
const struct zl3073x_chan *chan;
|
||||
s64 ffo;
|
||||
|
||||
/* Get reference monitor status */
|
||||
ref_id = zl3073x_input_pin_ref_get(pin->id);
|
||||
ref = zl3073x_ref_state_get(zldev, ref_id);
|
||||
|
||||
/* Do not report ffo changes if the reference monitor report errors */
|
||||
if (!zl3073x_ref_is_status_ok(ref))
|
||||
if (pin->operstate != DPLL_PIN_OPERSTATE_ACTIVE)
|
||||
return false;
|
||||
|
||||
/* Compare with previous value */
|
||||
ffo = zl3073x_ref_ffo_get(ref);
|
||||
if (pin->freq_offset != ffo) {
|
||||
dev_dbg(zldev->dev, "%s freq offset changed: %lld -> %lld\n",
|
||||
pin->label, pin->freq_offset, ffo);
|
||||
pin->freq_offset = ffo;
|
||||
chan = zl3073x_chan_state_get(zldpll->dev, zldpll->id);
|
||||
ffo = mul_s64_u64_shr(zl3073x_chan_df_offset_get(chan),
|
||||
244140625, 36);
|
||||
|
||||
if (atomic64_xchg(&pin->freq_offset, ffo) != ffo) {
|
||||
dev_dbg(zldev->dev, "%s freq offset changed to: %lld\n",
|
||||
pin->label, ffo);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1828,7 +1860,7 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll)
|
||||
}
|
||||
|
||||
list_for_each_entry(pin, &zldpll->pins, list) {
|
||||
enum dpll_pin_state state;
|
||||
enum dpll_pin_operstate operstate;
|
||||
bool pin_changed = false;
|
||||
|
||||
/* Output pins change checks are not necessary because output
|
||||
@ -1837,18 +1869,18 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll)
|
||||
if (!zl3073x_dpll_is_input_pin(pin))
|
||||
continue;
|
||||
|
||||
rc = zl3073x_dpll_ref_state_get(pin, &state);
|
||||
rc = zl3073x_dpll_ref_operstate_get(pin, &operstate);
|
||||
if (rc) {
|
||||
dev_err(dev,
|
||||
"Failed to get %s on DPLL%u state: %pe\n",
|
||||
"Failed to get %s on DPLL%u oper state: %pe\n",
|
||||
pin->label, zldpll->id, ERR_PTR(rc));
|
||||
return;
|
||||
}
|
||||
|
||||
if (state != pin->pin_state) {
|
||||
dev_dbg(dev, "%s state changed: %u->%u\n", pin->label,
|
||||
pin->pin_state, state);
|
||||
pin->pin_state = state;
|
||||
if (operstate != pin->operstate) {
|
||||
dev_dbg(dev, "%s oper state changed: %u->%u\n",
|
||||
pin->label, pin->operstate, operstate);
|
||||
pin->operstate = operstate;
|
||||
pin_changed = true;
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@ struct zl3073x_dev;
|
||||
* @freq_ratio_n: FEC mode divisor
|
||||
* @sync_ctrl: reference sync control
|
||||
* @config: reference config
|
||||
* @ffo: current fractional frequency offset
|
||||
* @meas_freq: measured input frequency in Hz
|
||||
* @mon_status: reference monitor status
|
||||
*/
|
||||
@ -40,7 +39,6 @@ struct zl3073x_ref {
|
||||
u8 config;
|
||||
);
|
||||
struct_group(stat, /* Status */
|
||||
s64 ffo;
|
||||
u32 meas_freq;
|
||||
u8 mon_status;
|
||||
);
|
||||
@ -58,18 +56,6 @@ int zl3073x_ref_state_update(struct zl3073x_dev *zldev, u8 index);
|
||||
|
||||
int zl3073x_ref_freq_factorize(u32 freq, u16 *base, u16 *mult);
|
||||
|
||||
/**
|
||||
* zl3073x_ref_ffo_get - get current fractional frequency offset
|
||||
* @ref: pointer to ref state
|
||||
*
|
||||
* Return: the latest measured fractional frequency offset
|
||||
*/
|
||||
static inline s64
|
||||
zl3073x_ref_ffo_get(const struct zl3073x_ref *ref)
|
||||
{
|
||||
return ref->ffo;
|
||||
}
|
||||
|
||||
/**
|
||||
* zl3073x_ref_meas_freq_get - get measured input frequency
|
||||
* @ref: pointer to ref state
|
||||
|
||||
@ -98,7 +98,14 @@
|
||||
|
||||
#define ZL_REG_REF_MON_STATUS(_idx) \
|
||||
ZL_REG_IDX(_idx, 2, 0x02, 1, ZL3073X_NUM_REFS, 1)
|
||||
#define ZL_REF_MON_STATUS_OK 0 /* all bits zeroed */
|
||||
#define ZL_REF_MON_STATUS_OK 0
|
||||
#define ZL_REF_MON_STATUS_LOS BIT(0)
|
||||
#define ZL_REF_MON_STATUS_SCM BIT(1)
|
||||
#define ZL_REF_MON_STATUS_CFM BIT(2)
|
||||
#define ZL_REF_MON_STATUS_GST BIT(3)
|
||||
#define ZL_REF_MON_STATUS_PFM BIT(4)
|
||||
#define ZL_REF_MON_STATUS_ESYNC BIT(6)
|
||||
#define ZL_REF_MON_STATUS_SPLIT_XO BIT(7)
|
||||
|
||||
#define ZL_REG_DPLL_MON_STATUS(_idx) \
|
||||
ZL_REG_IDX(_idx, 2, 0x10, 1, ZL3073X_MAX_CHANNELS, 1)
|
||||
@ -157,6 +164,11 @@
|
||||
#define ZL_DPLL_MODE_REFSEL_MODE_NCO 4
|
||||
#define ZL_DPLL_MODE_REFSEL_REF GENMASK(7, 4)
|
||||
|
||||
#define ZL_REG_DPLL_DF_READ(_idx) \
|
||||
ZL_REG_IDX(_idx, 5, 0x28, 1, ZL3073X_MAX_CHANNELS, 1)
|
||||
#define ZL_DPLL_DF_READ_SEM BIT(4)
|
||||
#define ZL_DPLL_DF_READ_REF_OFST BIT(3)
|
||||
|
||||
#define ZL_REG_DPLL_MEAS_CTRL ZL_REG(5, 0x50, 1)
|
||||
#define ZL_DPLL_MEAS_CTRL_EN BIT(0)
|
||||
#define ZL_DPLL_MEAS_CTRL_AVG_FACTOR GENMASK(7, 4)
|
||||
@ -169,6 +181,16 @@
|
||||
#define ZL_REG_DPLL_PHASE_ERR_DATA(_idx) \
|
||||
ZL_REG_IDX(_idx, 5, 0x55, 6, ZL3073X_MAX_CHANNELS, 6)
|
||||
|
||||
/*******************************
|
||||
* Register Pages 6-7, DPLL Data
|
||||
*******************************/
|
||||
|
||||
#define ZL_REG_DPLL_DF_OFFSET_03(_idx) \
|
||||
ZL_REG_IDX(_idx, 6, 0x00, 6, 4, 0x20)
|
||||
#define ZL_REG_DPLL_DF_OFFSET_4 ZL_REG(7, 0x00, 6)
|
||||
#define ZL_REG_DPLL_DF_OFFSET(_idx) \
|
||||
((_idx) < 4 ? ZL_REG_DPLL_DF_OFFSET_03(_idx) : ZL_REG_DPLL_DF_OFFSET_4)
|
||||
|
||||
/***********************************
|
||||
* Register Page 9, Synth and Output
|
||||
***********************************/
|
||||
|
||||
@ -140,8 +140,9 @@ int mana_ib_install_cq_cb(struct mana_ib_dev *mdev, struct mana_ib_cq *cq)
|
||||
|
||||
if (cq->queue.id >= gc->max_num_cqs)
|
||||
return -EINVAL;
|
||||
/* Create CQ table entry */
|
||||
WARN_ON(gc->cq_table[cq->queue.id]);
|
||||
/* Create CQ table entry, sharing a CQ between WQs is not supported */
|
||||
if (gc->cq_table[cq->queue.id])
|
||||
return -EINVAL;
|
||||
if (cq->queue.kmem)
|
||||
gdma_cq = cq->queue.kmem;
|
||||
else
|
||||
|
||||
@ -21,6 +21,9 @@ static int mana_ib_cfg_vport_steering(struct mana_ib_dev *dev,
|
||||
|
||||
gc = mdev_to_gc(dev);
|
||||
|
||||
if (rx_hash_key_len > sizeof(req->hashkey))
|
||||
return -EINVAL;
|
||||
|
||||
req_buf_size = struct_size(req, indir_tab, MANA_INDIRECT_TABLE_DEF_SIZE);
|
||||
req = kzalloc(req_buf_size, GFP_KERNEL);
|
||||
if (!req)
|
||||
|
||||
@ -10731,12 +10731,10 @@ void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,
|
||||
struct bnxt_ntuple_filter *ntp_fltr;
|
||||
int i;
|
||||
|
||||
if (netif_running(bp->dev)) {
|
||||
bnxt_hwrm_vnic_free_one(bp, &rss_ctx->vnic);
|
||||
for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) {
|
||||
if (vnic->fw_rss_cos_lb_ctx[i] != INVALID_HW_RING_ID)
|
||||
bnxt_hwrm_vnic_ctx_free_one(bp, vnic, i);
|
||||
}
|
||||
bnxt_hwrm_vnic_free_one(bp, &rss_ctx->vnic);
|
||||
for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) {
|
||||
if (vnic->fw_rss_cos_lb_ctx[i] != INVALID_HW_RING_ID)
|
||||
bnxt_hwrm_vnic_ctx_free_one(bp, vnic, i);
|
||||
}
|
||||
if (!all)
|
||||
return;
|
||||
|
||||
@ -1756,6 +1756,27 @@ static int ibmveth_set_mac_addr(struct net_device *dev, void *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static netdev_features_t ibmveth_features_check(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
/* Some physical adapters do not support segmentation offload with
|
||||
* MSS < 224. Disable GSO for such packets to avoid adapter freeze.
|
||||
* Note: Single-segment packets (gso_segs == 1) don't need this check
|
||||
* as they bypass the LSO path and are transmitted without segmentation.
|
||||
*/
|
||||
if (skb_is_gso(skb)) {
|
||||
if (skb_shinfo(skb)->gso_size < IBMVETH_MIN_LSO_MSS) {
|
||||
netdev_warn_once(dev,
|
||||
"MSS %u too small for LSO, disabling GSO\n",
|
||||
skb_shinfo(skb)->gso_size);
|
||||
features &= ~NETIF_F_GSO_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
return vlan_features_check(skb, features);
|
||||
}
|
||||
|
||||
static const struct net_device_ops ibmveth_netdev_ops = {
|
||||
.ndo_open = ibmveth_open,
|
||||
.ndo_stop = ibmveth_close,
|
||||
@ -1767,6 +1788,7 @@ static const struct net_device_ops ibmveth_netdev_ops = {
|
||||
.ndo_set_features = ibmveth_set_features,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_set_mac_address = ibmveth_set_mac_addr,
|
||||
.ndo_features_check = ibmveth_features_check,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
.ndo_poll_controller = ibmveth_poll_controller,
|
||||
#endif
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#define IBMVETH_ILLAN_IPV4_TCP_CSUM 0x0000000000000002UL
|
||||
#define IBMVETH_ILLAN_ACTIVE_TRUNK 0x0000000000000001UL
|
||||
|
||||
#define IBMVETH_MIN_LSO_MSS 224 /* Minimum MSS for LSO */
|
||||
/* hcall macros */
|
||||
#define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \
|
||||
plpar_hcall_norets(H_REGISTER_LOGICAL_LAN, ua, buflst, rxq, fltlst, mac)
|
||||
|
||||
@ -2789,12 +2789,14 @@ void ice_vsi_set_napi_queues(struct ice_vsi *vsi)
|
||||
|
||||
ASSERT_RTNL();
|
||||
ice_for_each_rxq(vsi, q_idx)
|
||||
netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_RX,
|
||||
&vsi->rx_rings[q_idx]->q_vector->napi);
|
||||
if (vsi->rx_rings[q_idx] && vsi->rx_rings[q_idx]->q_vector)
|
||||
netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_RX,
|
||||
&vsi->rx_rings[q_idx]->q_vector->napi);
|
||||
|
||||
ice_for_each_txq(vsi, q_idx)
|
||||
netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_TX,
|
||||
&vsi->tx_rings[q_idx]->q_vector->napi);
|
||||
if (vsi->tx_rings[q_idx] && vsi->tx_rings[q_idx]->q_vector)
|
||||
netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_TX,
|
||||
&vsi->tx_rings[q_idx]->q_vector->napi);
|
||||
/* Also set the interrupt number for the NAPI */
|
||||
ice_for_each_q_vector(vsi, v_idx) {
|
||||
struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
|
||||
|
||||
@ -300,7 +300,8 @@ static int mlx5_dpll_state_on_dpll_set(const struct dpll_pin *pin,
|
||||
|
||||
static int mlx5_dpll_ffo_get(const struct dpll_pin *pin, void *pin_priv,
|
||||
const struct dpll_device *dpll, void *dpll_priv,
|
||||
s64 *ffo, struct netlink_ext_ack *extack)
|
||||
struct dpll_ffo_param *ffo,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlx5_dpll_synce_status synce_status;
|
||||
struct mlx5_dpll *mdpll = pin_priv;
|
||||
@ -309,10 +310,11 @@ static int mlx5_dpll_ffo_get(const struct dpll_pin *pin, void *pin_priv,
|
||||
err = mlx5_dpll_synce_status_get(mdpll->mdev, &synce_status);
|
||||
if (err)
|
||||
return err;
|
||||
return mlx5_dpll_pin_ffo_get(&synce_status, ffo);
|
||||
return mlx5_dpll_pin_ffo_get(&synce_status, &ffo->ffo);
|
||||
}
|
||||
|
||||
static const struct dpll_pin_ops mlx5_dpll_pins_ops = {
|
||||
.supported_ffo = BIT(DPLL_FFO_PORT_RXTX_RATE),
|
||||
.direction_get = mlx5_dpll_pin_direction_get,
|
||||
.state_on_dpll_get = mlx5_dpll_state_on_dpll_get,
|
||||
.state_on_dpll_set = mlx5_dpll_state_on_dpll_set,
|
||||
|
||||
@ -390,6 +390,19 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue)
|
||||
|
||||
static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status)
|
||||
{
|
||||
/*
|
||||
* Keep rcv_state at RECV_ERR even for the internal -ESHUTDOWN path.
|
||||
* nvmet_tcp_handle_icreq() can return -ESHUTDOWN after the ICReq has
|
||||
* already been consumed and queue teardown has started.
|
||||
*
|
||||
* If nvmet_tcp_data_ready() or nvmet_tcp_write_space() queues
|
||||
* nvmet_tcp_io_work() again before nvmet_tcp_release_queue_work()
|
||||
* cancels it, the queue must not keep that old receive state.
|
||||
* Otherwise the next nvmet_tcp_io_work() run can reach
|
||||
* nvmet_tcp_done_recv_pdu() and try to handle the same ICReq again.
|
||||
*
|
||||
* That is why queue->rcv_state needs to be updated before we return.
|
||||
*/
|
||||
queue->rcv_state = NVMET_TCP_RECV_ERR;
|
||||
if (status == -EPIPE || status == -ECONNRESET)
|
||||
kernel_sock_shutdown(queue->sock, SHUT_RDWR);
|
||||
@ -893,10 +906,25 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
|
||||
iov.iov_base = icresp;
|
||||
iov.iov_len = sizeof(*icresp);
|
||||
ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
spin_lock_bh(&queue->state_lock);
|
||||
if (queue->state == NVMET_TCP_Q_DISCONNECTING) {
|
||||
spin_unlock_bh(&queue->state_lock);
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
queue->state = NVMET_TCP_Q_FAILED;
|
||||
spin_unlock_bh(&queue->state_lock);
|
||||
return ret; /* queue removal will cleanup */
|
||||
}
|
||||
|
||||
spin_lock_bh(&queue->state_lock);
|
||||
if (queue->state == NVMET_TCP_Q_DISCONNECTING) {
|
||||
spin_unlock_bh(&queue->state_lock);
|
||||
/* Tell nvmet_tcp_socket_error() teardown is in progress. */
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
queue->state = NVMET_TCP_Q_LIVE;
|
||||
spin_unlock_bh(&queue->state_lock);
|
||||
nvmet_prepare_receive_pdu(queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1585,6 +1585,15 @@ static ssize_t bindings_show(const struct bus_type *bus, char *buf)
|
||||
|
||||
static BUS_ATTR_RO(bindings);
|
||||
|
||||
static ssize_t bindings_complete_count_show(const struct bus_type *bus,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%llu\n",
|
||||
atomic64_read(&ap_bindings_complete_count));
|
||||
}
|
||||
|
||||
static BUS_ATTR_RO(bindings_complete_count);
|
||||
|
||||
static ssize_t features_show(const struct bus_type *bus, char *buf)
|
||||
{
|
||||
int n = 0;
|
||||
@ -1625,6 +1634,7 @@ static struct attribute *ap_bus_attrs[] = {
|
||||
&bus_attr_aqmask.attr,
|
||||
&bus_attr_scans.attr,
|
||||
&bus_attr_bindings.attr,
|
||||
&bus_attr_bindings_complete_count.attr,
|
||||
&bus_attr_features.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -2751,7 +2751,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
if (!elsio->u.els_logo.els_logo_pyld) {
|
||||
/* ref: INIT */
|
||||
kref_put(&sp->cmd_kref, qla2x00_sp_release);
|
||||
qla2x00_free_fcport(fcport);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
@ -2776,7 +2775,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
if (rval != QLA_SUCCESS) {
|
||||
/* ref: INIT */
|
||||
kref_put(&sp->cmd_kref, qla2x00_sp_release);
|
||||
qla2x00_free_fcport(fcport);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
|
||||
@ -914,6 +914,12 @@ static void privcmd_close(struct vm_area_struct *vma)
|
||||
kfree(pages);
|
||||
}
|
||||
|
||||
static int privcmd_may_split(struct vm_area_struct *area, unsigned long addr)
|
||||
{
|
||||
/* Forbid splitting, avoids double free via privcmd_close(). */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static vm_fault_t privcmd_fault(struct vm_fault *vmf)
|
||||
{
|
||||
printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n",
|
||||
@ -925,6 +931,7 @@ static vm_fault_t privcmd_fault(struct vm_fault *vmf)
|
||||
|
||||
static const struct vm_operations_struct privcmd_vm_ops = {
|
||||
.close = privcmd_close,
|
||||
.may_split = privcmd_may_split,
|
||||
.fault = privcmd_fault
|
||||
};
|
||||
|
||||
|
||||
@ -317,6 +317,12 @@ static void gfs2_metapath_ra(struct gfs2_glock *gl, __be64 *start, __be64 *end)
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct buffer_head *
|
||||
metapath_dibh(struct metapath *mp)
|
||||
{
|
||||
return mp->mp_bh[0];
|
||||
}
|
||||
|
||||
static int __fillup_metapath(struct gfs2_inode *ip, struct metapath *mp,
|
||||
unsigned int x, unsigned int h)
|
||||
{
|
||||
@ -661,7 +667,7 @@ static int __gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
|
||||
{
|
||||
struct gfs2_inode *ip = GFS2_I(inode);
|
||||
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||
struct buffer_head *dibh = mp->mp_bh[0];
|
||||
struct buffer_head *dibh = metapath_dibh(mp);
|
||||
u64 bn;
|
||||
unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
|
||||
size_t dblks = iomap->length >> inode->i_blkbits;
|
||||
@ -1116,10 +1122,18 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
|
||||
goto out_unlock;
|
||||
break;
|
||||
default:
|
||||
goto out_unlock;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap, &mp);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
out:
|
||||
if (iomap->type == IOMAP_INLINE) {
|
||||
iomap->private = metapath_dibh(&mp);
|
||||
get_bh(iomap->private);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
release_metapath(&mp);
|
||||
@ -1133,6 +1147,9 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
|
||||
struct gfs2_inode *ip = GFS2_I(inode);
|
||||
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||
|
||||
if (iomap->private)
|
||||
brelse(iomap->private);
|
||||
|
||||
switch (flags & (IOMAP_WRITE | IOMAP_ZERO)) {
|
||||
case IOMAP_WRITE:
|
||||
if (flags & IOMAP_DIRECT)
|
||||
|
||||
@ -71,6 +71,22 @@ struct dpll_device_ops {
|
||||
RH_KABI_RESERVE(10)
|
||||
};
|
||||
|
||||
enum dpll_ffo_type {
|
||||
DPLL_FFO_PORT_RXTX_RATE,
|
||||
DPLL_FFO_PIN_DEVICE,
|
||||
|
||||
__DPLL_FFO_TYPE_MAX,
|
||||
};
|
||||
|
||||
/* RHEL: we have to keep 'ffo' field to be first to preserve compatibility
|
||||
* with older .ffo_get() callbacks that accepts 's64 *' as parameter instead
|
||||
* of 'struct dpll_ffo_param *'
|
||||
*/
|
||||
struct dpll_ffo_param {
|
||||
s64 ffo;
|
||||
enum dpll_ffo_type type;
|
||||
};
|
||||
|
||||
struct dpll_pin_ops {
|
||||
int (*frequency_set)(const struct dpll_pin *pin, void *pin_priv,
|
||||
const struct dpll_device *dpll, void *dpll_priv,
|
||||
@ -124,9 +140,13 @@ struct dpll_pin_ops {
|
||||
const struct dpll_device *dpll, void *dpll_priv,
|
||||
const s32 phase_adjust,
|
||||
struct netlink_ext_ack *extack);
|
||||
int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv,
|
||||
RH_KABI_REPLACE(int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv,
|
||||
const struct dpll_device *dpll, void *dpll_priv,
|
||||
s64 *ffo, struct netlink_ext_ack *extack);
|
||||
s64 *ffo, struct netlink_ext_ack *extack),
|
||||
int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv,
|
||||
const struct dpll_device *dpll, void *dpll_priv,
|
||||
struct dpll_ffo_param *ffo,
|
||||
struct netlink_ext_ack *extack))
|
||||
int (*esync_set)(const struct dpll_pin *pin, void *pin_priv,
|
||||
const struct dpll_device *dpll, void *dpll_priv,
|
||||
u64 freq, struct netlink_ext_ack *extack);
|
||||
@ -149,8 +169,13 @@ struct dpll_pin_ops {
|
||||
const struct dpll_device *dpll,
|
||||
void *dpll_priv, u64 *measured_freq,
|
||||
struct netlink_ext_ack *extack))
|
||||
RH_KABI_RESERVE(2)
|
||||
RH_KABI_RESERVE(3)
|
||||
RH_KABI_USE(2, int (*operstate_on_dpll_get)(const struct dpll_pin *pin,
|
||||
void *pin_priv,
|
||||
const struct dpll_device *dpll,
|
||||
void *dpll_priv,
|
||||
enum dpll_pin_operstate *operstate,
|
||||
struct netlink_ext_ack *extack))
|
||||
RH_KABI_USE(3, unsigned long supported_ffo)
|
||||
RH_KABI_RESERVE(4)
|
||||
RH_KABI_RESERVE(5)
|
||||
RH_KABI_RESERVE(6)
|
||||
|
||||
@ -14,7 +14,6 @@ struct tcf_pedit_key_ex {
|
||||
struct tcf_pedit_parms {
|
||||
struct tc_pedit_key *tcfp_keys;
|
||||
struct tcf_pedit_key_ex *tcfp_keys_ex;
|
||||
u32 tcfp_off_max_hint;
|
||||
unsigned char tcfp_nkeys;
|
||||
unsigned char tcfp_flags;
|
||||
struct rcu_head rcu;
|
||||
|
||||
@ -177,6 +177,28 @@ enum dpll_pin_state {
|
||||
DPLL_PIN_STATE_MAX = (__DPLL_PIN_STATE_MAX - 1)
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dpll_pin_operstate - defines possible operational states of a pin with
|
||||
* respect to its parent DPLL device, valid values for DPLL_A_PIN_OPERSTATE
|
||||
* attribute
|
||||
* @DPLL_PIN_OPERSTATE_ACTIVE: pin is qualified and actively used by the DPLL
|
||||
* @DPLL_PIN_OPERSTATE_STANDBY: pin is qualified but not actively used by the
|
||||
* DPLL
|
||||
* @DPLL_PIN_OPERSTATE_NO_SIGNAL: pin does not have a valid signal
|
||||
* @DPLL_PIN_OPERSTATE_QUAL_FAILED: pin signal failed qualification (e.g.
|
||||
* frequency or phase monitor)
|
||||
*/
|
||||
enum dpll_pin_operstate {
|
||||
DPLL_PIN_OPERSTATE_ACTIVE = 1,
|
||||
DPLL_PIN_OPERSTATE_STANDBY,
|
||||
DPLL_PIN_OPERSTATE_NO_SIGNAL,
|
||||
DPLL_PIN_OPERSTATE_QUAL_FAILED,
|
||||
|
||||
/* private: */
|
||||
__DPLL_PIN_OPERSTATE_MAX,
|
||||
DPLL_PIN_OPERSTATE_MAX = (__DPLL_PIN_OPERSTATE_MAX - 1)
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dpll_pin_capabilities - defines possible capabilities of a pin, valid
|
||||
* flags on DPLL_A_PIN_CAPABILITIES attribute
|
||||
@ -256,6 +278,7 @@ enum dpll_a_pin {
|
||||
DPLL_A_PIN_PHASE_ADJUST_GRAN,
|
||||
DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
|
||||
DPLL_A_PIN_MEASURED_FREQUENCY,
|
||||
DPLL_A_PIN_OPERSTATE,
|
||||
|
||||
__DPLL_A_PIN_MAX,
|
||||
DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
|
||||
kernel.rhel,1,Red Hat,kernel-core,5.14.0-687.15.1.el9.x86_64,mailto:secalert@redhat.com
|
||||
kernel.almalinux,1,AlmaLinux,kernel-core,5.14.0-687.15.1.el9.x86_64,mailto:security@almalinux.org
|
||||
kernel.rhel,1,Red Hat,kernel-core,5.14.0-687.17.1.el9.x86_64,mailto:secalert@redhat.com
|
||||
kernel.almalinux,1,AlmaLinux,kernel-core,5.14.0-687.17.1.el9.x86_64,mailto:security@almalinux.org
|
||||
|
||||
@ -959,6 +959,7 @@ void __noreturn make_task_dead(int signr)
|
||||
futex_exit_recursive(tsk);
|
||||
tsk->exit_state = EXIT_DEAD;
|
||||
refcount_inc(&tsk->rcu_users);
|
||||
preempt_disable();
|
||||
do_task_dead();
|
||||
}
|
||||
|
||||
|
||||
@ -5418,9 +5418,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
|
||||
|
||||
bt_dev_dbg(hdev, "");
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
|
||||
if (!conn)
|
||||
return;
|
||||
goto unlock;
|
||||
|
||||
conn->passkey_notify = __le32_to_cpu(ev->passkey);
|
||||
conn->passkey_entered = 0;
|
||||
@ -5429,6 +5431,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
|
||||
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
|
||||
conn->dst_type, conn->passkey_notify,
|
||||
conn->passkey_entered);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
|
||||
@ -5439,14 +5444,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
|
||||
|
||||
bt_dev_dbg(hdev, "");
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
|
||||
if (!conn)
|
||||
return;
|
||||
goto unlock;
|
||||
|
||||
switch (ev->type) {
|
||||
case HCI_KEYPRESS_STARTED:
|
||||
conn->passkey_entered = 0;
|
||||
return;
|
||||
goto unlock;
|
||||
|
||||
case HCI_KEYPRESS_ENTERED:
|
||||
conn->passkey_entered++;
|
||||
@ -5461,13 +5468,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
|
||||
break;
|
||||
|
||||
case HCI_KEYPRESS_COMPLETED:
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_MGMT))
|
||||
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
|
||||
conn->dst_type, conn->passkey_notify,
|
||||
conn->passkey_entered);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
|
||||
|
||||
@ -7126,7 +7126,8 @@ static void create_big_complete(struct hci_dev *hdev, void *data, int err)
|
||||
|
||||
static int hci_le_big_create_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, 0x11);
|
||||
DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis,
|
||||
HCI_MAX_ISO_BIS);
|
||||
struct hci_conn *conn = data;
|
||||
struct bt_iso_qos *qos = &conn->iso_qos;
|
||||
int err;
|
||||
|
||||
@ -1229,12 +1229,6 @@ static int isotp_release(struct socket *sock)
|
||||
so->ifindex = 0;
|
||||
so->bound = 0;
|
||||
|
||||
if (so->rx.buf != so->rx.sbuf)
|
||||
kfree(so->rx.buf);
|
||||
|
||||
if (so->tx.buf != so->tx.sbuf)
|
||||
kfree(so->tx.buf);
|
||||
|
||||
sock_orphan(sk);
|
||||
sock->sk = NULL;
|
||||
|
||||
@ -1602,6 +1596,21 @@ static int isotp_notifier(struct notifier_block *nb, unsigned long msg,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static void isotp_sock_destruct(struct sock *sk)
|
||||
{
|
||||
struct isotp_sock *so = isotp_sk(sk);
|
||||
|
||||
/* do the standard CAN sock destruct work */
|
||||
can_sock_destruct(sk);
|
||||
|
||||
/* free potential extended PDU buffers */
|
||||
if (so->rx.buf != so->rx.sbuf)
|
||||
kfree(so->rx.buf);
|
||||
|
||||
if (so->tx.buf != so->tx.sbuf)
|
||||
kfree(so->tx.buf);
|
||||
}
|
||||
|
||||
static int isotp_init(struct sock *sk)
|
||||
{
|
||||
struct isotp_sock *so = isotp_sk(sk);
|
||||
@ -1648,6 +1657,9 @@ static int isotp_init(struct sock *sk)
|
||||
list_add_tail(&so->notifier, &isotp_notifier_list);
|
||||
spin_unlock(&isotp_notifier_lock);
|
||||
|
||||
/* re-assign default can_sock_destruct() reference */
|
||||
sk->sk_destruct = isotp_sock_destruct;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -8890,7 +8890,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_bss *bss = (void *)cbss->priv;
|
||||
struct sta_info *new_sta = NULL;
|
||||
struct ieee80211_link_data *link;
|
||||
bool have_sta = false;
|
||||
struct sta_info *have_sta = NULL;
|
||||
bool mlo;
|
||||
int err;
|
||||
u16 new_links;
|
||||
@ -8909,11 +8909,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
||||
mlo = false;
|
||||
}
|
||||
|
||||
if (assoc) {
|
||||
rcu_read_lock();
|
||||
if (assoc)
|
||||
have_sta = sta_info_get(sdata, ap_mld_addr);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
if (mlo && !have_sta &&
|
||||
WARN_ON(sdata->vif.valid_links || sdata->vif.active_links))
|
||||
@ -9072,6 +9069,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
||||
out_release_chan:
|
||||
ieee80211_link_release_channel(link);
|
||||
out_err:
|
||||
if (mlo && have_sta)
|
||||
WARN_ON(__sta_info_destroy(have_sta));
|
||||
ieee80211_vif_set_links(sdata, 0, 0);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -4819,7 +4819,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
||||
struct sk_buff *skb = rx->skb;
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
static ieee80211_rx_result res;
|
||||
ieee80211_rx_result res;
|
||||
int orig_len = skb->len;
|
||||
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
int snap_offs = hdrlen;
|
||||
|
||||
@ -3565,11 +3565,11 @@ void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
|
||||
struct ieee80211_local *local =
|
||||
container_of(work, struct ieee80211_local, radar_detected_work);
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct ieee80211_chanctx *ctx;
|
||||
struct ieee80211_chanctx *ctx, *tmp;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
list_for_each_entry(ctx, &local->chanctx_list, list) {
|
||||
list_for_each_entry_safe(ctx, tmp, &local->chanctx_list, list) {
|
||||
if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
|
||||
continue;
|
||||
|
||||
|
||||
@ -4248,6 +4248,8 @@ int __init mptcp_proto_v6_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
mptcp_subflow_v6_init();
|
||||
|
||||
mptcp_v6_prot = mptcp_prot;
|
||||
strscpy(mptcp_v6_prot.name, "MPTCPv6", sizeof(mptcp_v6_prot.name));
|
||||
mptcp_v6_prot.slab = NULL;
|
||||
|
||||
@ -794,6 +794,7 @@ static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
|
||||
void __init mptcp_proto_init(void);
|
||||
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
|
||||
int __init mptcp_proto_v6_init(void);
|
||||
void __init mptcp_subflow_v6_init(void);
|
||||
#endif
|
||||
|
||||
struct sock *mptcp_sk_clone_init(const struct sock *sk,
|
||||
|
||||
@ -2103,7 +2103,15 @@ void __init mptcp_subflow_init(void)
|
||||
tcp_prot_override.release_cb = tcp_release_cb_override;
|
||||
tcp_prot_override.diag_destroy = tcp_abort_override;
|
||||
|
||||
mptcp_diag_subflow_init(&subflow_ulp_ops);
|
||||
|
||||
if (tcp_register_ulp(&subflow_ulp_ops) != 0)
|
||||
panic("MPTCP: failed to register subflows to ULP\n");
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
|
||||
void __init mptcp_subflow_v6_init(void)
|
||||
{
|
||||
/* In struct mptcp_subflow_request_sock, we assume the TCP request sock
|
||||
* structures for v4 and v6 have the same size. It should not changed in
|
||||
* the future but better to make sure to be warned if it is no longer
|
||||
@ -2139,10 +2147,5 @@ void __init mptcp_subflow_init(void)
|
||||
tcpv6_prot_override = tcpv6_prot;
|
||||
tcpv6_prot_override.release_cb = tcp_release_cb_override;
|
||||
tcpv6_prot_override.diag_destroy = tcp_abort_override;
|
||||
#endif
|
||||
|
||||
mptcp_diag_subflow_init(&subflow_ulp_ops);
|
||||
|
||||
if (tcp_register_ulp(&subflow_ulp_ops) != 0)
|
||||
panic("MPTCP: failed to register subflows to ULP\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/pkt_sched.h>
|
||||
@ -24,6 +25,7 @@
|
||||
#include <uapi/linux/tc_act/tc_pedit.h>
|
||||
#include <net/pkt_cls.h>
|
||||
#include <net/tc_wrapper.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
static struct tc_action_ops act_pedit_ops;
|
||||
|
||||
@ -242,7 +244,6 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
|
||||
goto out_free_ex;
|
||||
}
|
||||
|
||||
nparms->tcfp_off_max_hint = 0;
|
||||
nparms->tcfp_flags = parm->flags;
|
||||
nparms->tcfp_nkeys = parm->nkeys;
|
||||
|
||||
@ -268,14 +269,6 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
|
||||
BITS_PER_TYPE(int) - 1,
|
||||
nparms->tcfp_keys[i].shift);
|
||||
|
||||
/* The AT option can read a single byte, we can bound the actual
|
||||
* value with uchar max.
|
||||
*/
|
||||
cur += (0xff & offmask) >> nparms->tcfp_keys[i].shift;
|
||||
|
||||
/* Each key touches 4 bytes starting from the computed offset */
|
||||
nparms->tcfp_off_max_hint =
|
||||
max(nparms->tcfp_off_max_hint, cur + 4);
|
||||
}
|
||||
|
||||
p = to_pedit(*a);
|
||||
@ -318,15 +311,12 @@ static void tcf_pedit_cleanup(struct tc_action *a)
|
||||
call_rcu(&parms->rcu, tcf_pedit_cleanup_rcu);
|
||||
}
|
||||
|
||||
static bool offset_valid(struct sk_buff *skb, int offset)
|
||||
static bool offset_valid(struct sk_buff *skb, int offset, int len)
|
||||
{
|
||||
if (offset > 0 && offset > skb->len)
|
||||
if (offset < -(int)skb_headroom(skb))
|
||||
return false;
|
||||
|
||||
if (offset < 0 && -offset > skb_headroom(skb))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return offset <= (int)skb->len - len;
|
||||
}
|
||||
|
||||
static int pedit_l4_skb_offset(struct sk_buff *skb, int *hoffset, const int header_type)
|
||||
@ -393,18 +383,10 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
|
||||
struct tcf_pedit_key_ex *tkey_ex;
|
||||
struct tcf_pedit_parms *parms;
|
||||
struct tc_pedit_key *tkey;
|
||||
u32 max_offset;
|
||||
int i;
|
||||
|
||||
parms = rcu_dereference_bh(p->parms);
|
||||
|
||||
max_offset = (skb_transport_header_was_set(skb) ?
|
||||
skb_transport_offset(skb) :
|
||||
skb_network_offset(skb)) +
|
||||
parms->tcfp_off_max_hint;
|
||||
if (skb_ensure_writable(skb, min(skb->len, max_offset)))
|
||||
goto done;
|
||||
|
||||
tcf_lastuse_update(&p->tcf_tm);
|
||||
tcf_action_update_bstats(&p->common, skb);
|
||||
|
||||
@ -412,10 +394,11 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
|
||||
tkey_ex = parms->tcfp_keys_ex;
|
||||
|
||||
for (i = parms->tcfp_nkeys; i > 0; i--, tkey++) {
|
||||
int write_offset, write_len;
|
||||
int offset = tkey->off;
|
||||
int hoffset = 0;
|
||||
u32 *ptr, hdata;
|
||||
u32 val;
|
||||
u32 cur_val, val;
|
||||
u32 *ptr;
|
||||
int rc;
|
||||
|
||||
if (tkey_ex) {
|
||||
@ -433,13 +416,15 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
|
||||
|
||||
if (tkey->offmask) {
|
||||
u8 *d, _d;
|
||||
int at_offset;
|
||||
|
||||
if (!offset_valid(skb, hoffset + tkey->at)) {
|
||||
if (check_add_overflow(hoffset, (int)tkey->at, &at_offset) ||
|
||||
!offset_valid(skb, at_offset, sizeof(_d))) {
|
||||
pr_info_ratelimited("tc action pedit 'at' offset %d out of bounds\n",
|
||||
hoffset + tkey->at);
|
||||
goto bad;
|
||||
}
|
||||
d = skb_header_pointer(skb, hoffset + tkey->at,
|
||||
d = skb_header_pointer(skb, at_offset,
|
||||
sizeof(_d), &_d);
|
||||
if (!d)
|
||||
goto bad;
|
||||
@ -451,31 +436,51 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
|
||||
}
|
||||
}
|
||||
|
||||
if (!offset_valid(skb, hoffset + offset)) {
|
||||
pr_info_ratelimited("tc action pedit offset %d out of bounds\n", hoffset + offset);
|
||||
if (check_add_overflow(hoffset, offset, &write_offset)) {
|
||||
pr_info_ratelimited("tc action pedit offset overflow\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ptr = skb_header_pointer(skb, hoffset + offset,
|
||||
sizeof(hdata), &hdata);
|
||||
if (!ptr)
|
||||
if (!offset_valid(skb, write_offset, sizeof(*ptr))) {
|
||||
pr_info_ratelimited("tc action pedit offset %d out of bounds\n",
|
||||
write_offset);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (write_offset < 0) {
|
||||
if (skb_cow(skb, -write_offset))
|
||||
goto bad;
|
||||
if (write_offset + (int)sizeof(*ptr) > 0) {
|
||||
if (skb_ensure_writable(skb,
|
||||
min_t(int, skb->len,
|
||||
write_offset + (int)sizeof(*ptr))))
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
if (check_add_overflow(write_offset, (int)sizeof(*ptr),
|
||||
&write_len))
|
||||
goto bad;
|
||||
if (skb_ensure_writable(skb, min_t(int, skb->len,
|
||||
write_len)))
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ptr = (u32 *)(skb->data + write_offset);
|
||||
cur_val = get_unaligned(ptr);
|
||||
/* just do it, baby */
|
||||
switch (cmd) {
|
||||
case TCA_PEDIT_KEY_EX_CMD_SET:
|
||||
val = tkey->val;
|
||||
break;
|
||||
case TCA_PEDIT_KEY_EX_CMD_ADD:
|
||||
val = (*ptr + tkey->val) & ~tkey->mask;
|
||||
val = (cur_val + tkey->val) & ~tkey->mask;
|
||||
break;
|
||||
default:
|
||||
pr_info_ratelimited("tc action pedit bad command (%d)\n", cmd);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
*ptr = ((*ptr & tkey->mask) ^ val);
|
||||
if (ptr == &hdata)
|
||||
skb_store_bits(skb, hoffset + offset, ptr, 4);
|
||||
put_unaligned((cur_val & tkey->mask) ^ val, ptr);
|
||||
}
|
||||
|
||||
goto done;
|
||||
|
||||
@ -275,8 +275,8 @@ static inline bool has_tx_length_quirk(struct snd_usb_audio *chip)
|
||||
return chip->quirk_flags & QUIRK_FLAG_TX_LENGTH;
|
||||
}
|
||||
|
||||
static void prepare_silent_urb(struct snd_usb_endpoint *ep,
|
||||
struct snd_urb_ctx *ctx)
|
||||
static int prepare_silent_urb(struct snd_usb_endpoint *ep,
|
||||
struct snd_urb_ctx *ctx)
|
||||
{
|
||||
struct urb *urb = ctx->urb;
|
||||
unsigned int offs = 0;
|
||||
@ -289,28 +289,34 @@ static void prepare_silent_urb(struct snd_usb_endpoint *ep,
|
||||
extra = sizeof(packet_length);
|
||||
|
||||
for (i = 0; i < ctx->packets; ++i) {
|
||||
unsigned int offset;
|
||||
unsigned int length;
|
||||
int counts;
|
||||
int length;
|
||||
|
||||
counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, 0);
|
||||
length = counts * ep->stride; /* number of silent bytes */
|
||||
offset = offs * ep->stride + extra * i;
|
||||
urb->iso_frame_desc[i].offset = offset;
|
||||
length = snd_usb_endpoint_next_packet_size(ep, ctx, i, 0);
|
||||
if (length < 0)
|
||||
return length;
|
||||
length *= ep->stride; /* number of silent bytes */
|
||||
if (offs + length + extra > ctx->buffer_size)
|
||||
break;
|
||||
urb->iso_frame_desc[i].offset = offs;
|
||||
urb->iso_frame_desc[i].length = length + extra;
|
||||
if (extra) {
|
||||
packet_length = cpu_to_le32(length);
|
||||
memcpy(urb->transfer_buffer + offset,
|
||||
memcpy(urb->transfer_buffer + offs,
|
||||
&packet_length, sizeof(packet_length));
|
||||
offs += extra;
|
||||
}
|
||||
memset(urb->transfer_buffer + offset + extra,
|
||||
memset(urb->transfer_buffer + offs,
|
||||
ep->silence_value, length);
|
||||
offs += counts;
|
||||
offs += length;
|
||||
}
|
||||
|
||||
urb->number_of_packets = ctx->packets;
|
||||
urb->transfer_buffer_length = offs * ep->stride + ctx->packets * extra;
|
||||
if (!offs)
|
||||
return -EPIPE;
|
||||
|
||||
urb->number_of_packets = i;
|
||||
urb->transfer_buffer_length = offs;
|
||||
ctx->queued = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -332,8 +338,7 @@ static int prepare_outbound_urb(struct snd_usb_endpoint *ep,
|
||||
if (data_subs && ep->prepare_data_urb)
|
||||
return ep->prepare_data_urb(data_subs, urb, in_stream_lock);
|
||||
/* no data provider, so send silence */
|
||||
prepare_silent_urb(ep, ctx);
|
||||
break;
|
||||
return prepare_silent_urb(ep, ctx);
|
||||
|
||||
case SND_USB_ENDPOINT_TYPE_SYNC:
|
||||
if (snd_usb_get_speed(ep->chip->dev) >= USB_SPEED_HIGH) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user