Merge 5.15.126 into android14-5.15-lts

Changes in 5.15.126
	io_uring: gate iowait schedule on having pending requests
	perf: Fix function pointer case
	net/mlx5: Free irqs only on shutdown callback
	arm64: errata: Add workaround for TSB flush failures
	arm64: errata: Add detection for TRBE write to out-of-range
	iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
	iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
	iommu/arm-smmu-v3: Add explicit feature for nesting
	iommu/arm-smmu-v3: Document nesting-related errata
	arm64: dts: imx8mn-var-som: add missing pull-up for onboard PHY reset pinmux
	word-at-a-time: use the same return type for has_zero regardless of endianness
	KVM: s390: fix sthyi error handling
	wifi: cfg80211: Fix return value in scan logic
	net/mlx5: DR, fix memory leak in mlx5dr_cmd_create_reformat_ctx
	net/mlx5e: fix return value check in mlx5e_ipsec_remove_trailer()
	bpf: Add length check for SK_DIAG_BPF_STORAGE_REQ_MAP_FD parsing
	rtnetlink: let rtnl_bridge_setlink checks IFLA_BRIDGE_MODE length
	net: dsa: fix value check in bcm_sf2_sw_probe()
	perf test uprobe_from_different_cu: Skip if there is no gcc
	net: sched: cls_u32: Fix match key mis-addressing
	mISDN: hfcpci: Fix potential deadlock on &hc->lock
	qed: Fix kernel-doc warnings
	qed: Fix scheduling in a tasklet while getting stats
	net: annotate data-races around sk->sk_max_pacing_rate
	net: add missing READ_ONCE(sk->sk_rcvlowat) annotation
	net: add missing READ_ONCE(sk->sk_sndbuf) annotation
	net: add missing READ_ONCE(sk->sk_rcvbuf) annotation
	net: add missing data-race annotations around sk->sk_peek_off
	net: add missing data-race annotation for sk_ll_usec
	net/sched: taprio: Limit TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME to INT_MAX.
	bpf, cpumap: Handle skb as well when clean up ptr_ring
	net/sched: cls_u32: No longer copy tcf_result on update to avoid use-after-free
	net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after-free
	net/sched: cls_route: No longer copy tcf_result on update to avoid use-after-free
	bpf: sockmap: Remove preempt_disable in sock_map_sk_acquire
	net: ll_temac: Switch to use dev_err_probe() helper
	net: ll_temac: fix error checking of irq_of_parse_and_map()
	net: korina: handle clk prepare error in korina_probe()
	net: netsec: Ignore 'phy-mode' on SynQuacer in DT mode
	net: dcb: choose correct policy to parse DCB_ATTR_BCN
	s390/qeth: Don't call dev_close/dev_open (DOWN/UP)
	ip6mr: Fix skb_under_panic in ip6mr_cache_report()
	vxlan: Fix nexthop hash size
	net/mlx5: fs_core: Make find_closest_ft more generic
	net/mlx5: fs_core: Skip the FTs in the same FS_TYPE_PRIO_CHAINS fs_prio
	prestera: fix fallback to previous version on same major version
	tcp_metrics: fix addr_same() helper
	tcp_metrics: annotate data-races around tm->tcpm_stamp
	tcp_metrics: annotate data-races around tm->tcpm_lock
	tcp_metrics: annotate data-races around tm->tcpm_vals[]
	tcp_metrics: annotate data-races around tm->tcpm_net
	tcp_metrics: fix data-race in tcpm_suck_dst() vs fastopen
	scsi: zfcp: Defer fc_rport blocking until after ADISC response
	scsi: storvsc: Limit max_sectors for virtual Fibre Channel devices
	libceph: fix potential hang in ceph_osdc_notify()
	USB: zaurus: Add ID for A-300/B-500/C-700
	ceph: defer stopping mdsc delayed_work
	firmware: arm_scmi: Drop OF node reference in the transport channel setup
	x86/CPU/AMD: Do not leak quotient data after a division by 0
	exfat: use kvmalloc_array/kvfree instead of kmalloc_array/kfree
	exfat: release s_lock before calling dir_emit()
	mtd: spinand: toshiba: Fix ecc_get_status
	mtd: rawnand: meson: fix OOB available bytes for ECC
	arm64: dts: stratix10: fix incorrect I2C property for SCL signal
	net: tun_chr_open(): set sk_uid from current_fsuid()
	net: tap_open(): set sk_uid from current_fsuid()
	wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D (DBDC)
	rbd: prevent busy loop when requesting exclusive lock
	bpf: Disable preemption in bpf_event_output
	open: make RESOLVE_CACHED correctly test for O_TMPFILE
	drm/ttm: check null pointer before accessing when swapping
	bpf, cpumap: Make sure kthread is running before map update returns
	file: reinstate f_pos locking optimization for regular files
	fs/ntfs3: Use __GFP_NOWARN allocation at ntfs_load_attr_list()
	fs/sysv: Null check to prevent null-ptr-deref bug
	Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_ready_cb
	net: usbnet: Fix WARNING in usbnet_start_xmit/usb_submit_urb
	fs: Protect reconfiguration of sb read-write from racing writes
	ext2: Drop fragment support
	mtd: rawnand: omap_elm: Fix incorrect type in assignment
	mtd: rawnand: rockchip: fix oobfree offset and description
	mtd: rawnand: rockchip: Align hwecc vs. raw page helper layouts
	mtd: rawnand: fsl_upm: Fix an off-by one test in fun_exec_op()
	powerpc/mm/altmap: Fix altmap boundary check
	drm/imx/ipuv3: Fix front porch adjustment upon hactive aligning
	selftests/rseq: check if libc rseq support is registered
	selftests/rseq: Play nice with binaries statically linked against glibc 2.35+
	soundwire: bus: pm_runtime_request_resume on peripheral attachment
	soundwire: fix enumeration completion
	PM / wakeirq: support enabling wake-up irq after runtime_suspend called
	PM: sleep: wakeirq: fix wake irq arming
	Linux 5.15.126

Change-Id: I5d56ea11000b37a22ec3e38dcf4ab58622ca109f
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2023-08-25 17:00:47 +00:00
113 changed files with 3185 additions and 2227 deletions

View File

@@ -124,6 +124,10 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-500 | #841119,826419 | N/A | | ARM | MMU-500 | #841119,826419 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-600 | #1076982,1209401| N/A |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-700 | #2268618,2812531| N/A |
+----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 | | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 5 VERSION = 5
PATCHLEVEL = 15 PATCHLEVEL = 15
SUBLEVEL = 125 SUBLEVEL = 126
EXTRAVERSION = EXTRAVERSION =
NAME = Trick or Treat NAME = Trick or Treat

View File

@@ -912,6 +912,80 @@ config ARM64_ERRATUM_2139208
If unsure, say Y. If unsure, say Y.
config ARM64_WORKAROUND_TSB_FLUSH_FAILURE
bool
config ARM64_ERRATUM_2054223
bool "Cortex-A710: 2054223: workaround TSB instruction failing to flush trace"
default y
select ARM64_WORKAROUND_TSB_FLUSH_FAILURE
help
Enable workaround for ARM Cortex-A710 erratum 2054223
Affected cores may fail to flush the trace data on a TSB instruction, when
the PE is in trace prohibited state. This will cause losing a few bytes
of the trace cached.
Workaround is to issue two TSB consecutively on affected cores.
If unsure, say Y.
config ARM64_ERRATUM_2067961
bool "Neoverse-N2: 2067961: workaround TSB instruction failing to flush trace"
default y
select ARM64_WORKAROUND_TSB_FLUSH_FAILURE
help
Enable workaround for ARM Neoverse-N2 erratum 2067961
Affected cores may fail to flush the trace data on a TSB instruction, when
the PE is in trace prohibited state. This will cause losing a few bytes
of the trace cached.
Workaround is to issue two TSB consecutively on affected cores.
If unsure, say Y.
config ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
bool
config ARM64_ERRATUM_2253138
bool "Neoverse-N2: 2253138: workaround TRBE writing to address out-of-range"
depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
depends on CORESIGHT_TRBE
default y
select ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
help
This option adds the workaround for ARM Neoverse-N2 erratum 2253138.
Affected Neoverse-N2 cores might write to an out-of-range address, not reserved
for TRBE. Under some conditions, the TRBE might generate a write to the next
virtually addressed page following the last page of the TRBE address space
(i.e., the TRBLIMITR_EL1.LIMIT), instead of wrapping around to the base.
Work around this in the driver by always making sure that there is a
page beyond the TRBLIMITR_EL1.LIMIT, within the space allowed for the TRBE.
If unsure, say Y.
config ARM64_ERRATUM_2224489
bool "Cortex-A710: 2224489: workaround TRBE writing to address out-of-range"
depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
depends on CORESIGHT_TRBE
default y
select ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
help
This option adds the workaround for ARM Cortex-A710 erratum 2224489.
Affected Cortex-A710 cores might write to an out-of-range address, not reserved
for TRBE. Under some conditions, the TRBE might generate a write to the next
virtually addressed page following the last page of the TRBE address space
(i.e., the TRBLIMITR_EL1.LIMIT), instead of wrapping around to the base.
Work around this in the driver by always making sure that there is a
page beyond the TRBLIMITR_EL1.LIMIT, within the space allowed for the TRBE.
If unsure, say Y.
config CAVIUM_ERRATUM_22375 config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313" bool "Cavium erratum 22375, 24313"
default y default y

View File

@@ -129,7 +129,7 @@
status = "okay"; status = "okay";
clock-frequency = <100000>; clock-frequency = <100000>;
i2c-sda-falling-time-ns = <890>; /* hcnt */ i2c-sda-falling-time-ns = <890>; /* hcnt */
i2c-sdl-falling-time-ns = <890>; /* lcnt */ i2c-scl-falling-time-ns = <890>; /* lcnt */
adc@14 { adc@14 {
compatible = "lltc,ltc2497"; compatible = "lltc,ltc2497";

View File

@@ -162,7 +162,7 @@
status = "okay"; status = "okay";
clock-frequency = <100000>; clock-frequency = <100000>;
i2c-sda-falling-time-ns = <890>; /* hcnt */ i2c-sda-falling-time-ns = <890>; /* hcnt */
i2c-sdl-falling-time-ns = <890>; /* lcnt */ i2c-scl-falling-time-ns = <890>; /* lcnt */
adc@14 { adc@14 {
compatible = "lltc,ltc2497"; compatible = "lltc,ltc2497";

View File

@@ -351,7 +351,7 @@
MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x159
>; >;
}; };

View File

@@ -670,6 +670,21 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)), MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)),
.cpu_enable = cpu_clear_bf16_from_user_emulation, .cpu_enable = cpu_clear_bf16_from_user_emulation,
}, },
#endif
#ifdef CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE
{
.desc = "ARM erratum 2067961 or 2054223",
.capability = ARM64_WORKAROUND_TSB_FLUSH_FAILURE,
ERRATA_MIDR_RANGE_LIST(tsb_flush_fail_cpus),
},
#endif
#ifdef CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
{
.desc = "ARM erratum 2253138 or 2224489",
.capability = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
},
#endif #endif
{ {
} }

View File

@@ -34,7 +34,7 @@ static inline long find_zero(unsigned long mask)
return leading_zero_bits >> 3; return leading_zero_bits >> 3;
} }
static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
{ {
unsigned long rhs = val | c->low_bits; unsigned long rhs = val | c->low_bits;
*data = rhs; *data = rhs;

View File

@@ -313,8 +313,7 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
start = ALIGN_DOWN(start, page_size); start = ALIGN_DOWN(start, page_size);
if (altmap) { if (altmap) {
alt_start = altmap->base_pfn; alt_start = altmap->base_pfn;
alt_end = altmap->base_pfn + altmap->reserve + alt_end = altmap->base_pfn + altmap->reserve + altmap->free;
altmap->free + altmap->alloc + altmap->align;
} }
pr_debug("vmemmap_free %lx...%lx\n", start, end); pr_debug("vmemmap_free %lx...%lx\n", start, end);

View File

@@ -459,9 +459,9 @@ static int sthyi_update_cache(u64 *rc)
* *
* Fills the destination with system information returned by the STHYI * Fills the destination with system information returned by the STHYI
* instruction. The data is generated by emulation or execution of STHYI, * instruction. The data is generated by emulation or execution of STHYI,
* if available. The return value is the condition code that would be * if available. The return value is either a negative error value or
* returned, the rc parameter is the return code which is passed in * the condition code that would be returned, the rc parameter is the
* register R2 + 1. * return code which is passed in register R2 + 1.
*/ */
int sthyi_fill(void *dst, u64 *rc) int sthyi_fill(void *dst, u64 *rc)
{ {

View File

@@ -389,8 +389,8 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu)
*/ */
int handle_sthyi(struct kvm_vcpu *vcpu) int handle_sthyi(struct kvm_vcpu *vcpu)
{ {
int reg1, reg2, r = 0; int reg1, reg2, cc = 0, r = 0;
u64 code, addr, cc = 0, rc = 0; u64 code, addr, rc = 0;
struct sthyi_sctns *sctns = NULL; struct sthyi_sctns *sctns = NULL;
if (!test_kvm_facility(vcpu->kvm, 74)) if (!test_kvm_facility(vcpu->kvm, 74))
@@ -421,7 +421,10 @@ int handle_sthyi(struct kvm_vcpu *vcpu)
return -ENOMEM; return -ENOMEM;
cc = sthyi_fill(sctns, &rc); cc = sthyi_fill(sctns, &rc);
if (cc < 0) {
free_page((unsigned long)sctns);
return cc;
}
out: out:
if (!cc) { if (!cc) {
if (kvm_s390_pv_cpu_is_protected(vcpu)) { if (kvm_s390_pv_cpu_is_protected(vcpu)) {

View File

@@ -465,4 +465,5 @@
/* BUG word 2 */ /* BUG word 2 */
#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */ #define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */
#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */
#endif /* _ASM_X86_CPUFEATURES_H */ #endif /* _ASM_X86_CPUFEATURES_H */

View File

@@ -804,10 +804,12 @@ extern u16 get_llc_id(unsigned int cpu);
extern u32 amd_get_nodes_per_socket(void); extern u32 amd_get_nodes_per_socket(void);
extern u32 amd_get_highest_perf(void); extern u32 amd_get_highest_perf(void);
extern bool cpu_has_ibpb_brtype_microcode(void); extern bool cpu_has_ibpb_brtype_microcode(void);
extern void amd_clear_divider(void);
#else #else
static inline u32 amd_get_nodes_per_socket(void) { return 0; } static inline u32 amd_get_nodes_per_socket(void) { return 0; }
static inline u32 amd_get_highest_perf(void) { return 0; } static inline u32 amd_get_highest_perf(void) { return 0; }
static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; } static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; }
static inline void amd_clear_divider(void) { }
#endif #endif
static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves) static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)

View File

@@ -75,6 +75,10 @@ static const int amd_zenbleed[] =
AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf), AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf),
AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf)); AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf));
static const int amd_div0[] =
AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x00, 0x0, 0x2f, 0xf),
AMD_MODEL_RANGE(0x17, 0x50, 0x0, 0x5f, 0xf));
static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
{ {
int osvw_id = *erratum++; int osvw_id = *erratum++;
@@ -1140,6 +1144,11 @@ static void init_amd(struct cpuinfo_x86 *c)
check_null_seg_clears_base(c); check_null_seg_clears_base(c);
zenbleed_check(c); zenbleed_check(c);
if (cpu_has_amd_erratum(c, amd_div0)) {
pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n");
setup_force_cpu_bug(X86_BUG_DIV0);
}
} }
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
@@ -1300,3 +1309,13 @@ void amd_check_microcode(void)
{ {
on_each_cpu(zenbleed_check_cpu, NULL, 1); on_each_cpu(zenbleed_check_cpu, NULL, 1);
} }
/*
* Issue a DIV 0/1 insn to clear any division data from previous DIV
* operations.
*/
void noinstr amd_clear_divider(void)
{
asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0)
:: "a" (0), "d" (0), "r" (1));
}

View File

@@ -202,6 +202,8 @@ DEFINE_IDTENTRY(exc_divide_error)
{ {
do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE, do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE,
FPE_INTDIV, error_get_trap_addr(regs)); FPE_INTDIV, error_get_trap_addr(regs));
amd_clear_divider();
} }
DEFINE_IDTENTRY(exc_overflow) DEFINE_IDTENTRY(exc_overflow)

View File

@@ -25,8 +25,11 @@ extern u64 pm_runtime_active_time(struct device *dev);
#define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0) #define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0)
#define WAKE_IRQ_DEDICATED_MANAGED BIT(1) #define WAKE_IRQ_DEDICATED_MANAGED BIT(1)
#define WAKE_IRQ_DEDICATED_REVERSE BIT(2)
#define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \
WAKE_IRQ_DEDICATED_MANAGED) WAKE_IRQ_DEDICATED_MANAGED | \
WAKE_IRQ_DEDICATED_REVERSE)
#define WAKE_IRQ_DEDICATED_ENABLED BIT(3)
struct wake_irq { struct wake_irq {
struct device *dev; struct device *dev;
@@ -39,7 +42,8 @@ extern void dev_pm_arm_wake_irq(struct wake_irq *wirq);
extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq); extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq);
extern void dev_pm_enable_wake_irq_check(struct device *dev, extern void dev_pm_enable_wake_irq_check(struct device *dev,
bool can_change_status); bool can_change_status);
extern void dev_pm_disable_wake_irq_check(struct device *dev); extern void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable);
extern void dev_pm_enable_wake_irq_complete(struct device *dev);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP

View File

@@ -673,6 +673,8 @@ static int rpm_suspend(struct device *dev, int rpmflags)
if (retval) if (retval)
goto fail; goto fail;
dev_pm_enable_wake_irq_complete(dev);
no_callback: no_callback:
__update_runtime_status(dev, RPM_SUSPENDED); __update_runtime_status(dev, RPM_SUSPENDED);
pm_runtime_deactivate_timer(dev); pm_runtime_deactivate_timer(dev);
@@ -718,7 +720,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
return retval; return retval;
fail: fail:
dev_pm_disable_wake_irq_check(dev); dev_pm_disable_wake_irq_check(dev, true);
__update_runtime_status(dev, RPM_ACTIVE); __update_runtime_status(dev, RPM_ACTIVE);
dev->power.deferred_resume = false; dev->power.deferred_resume = false;
wake_up_all(&dev->power.wait_queue); wake_up_all(&dev->power.wait_queue);
@@ -901,7 +903,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
callback = RPM_GET_CALLBACK(dev, runtime_resume); callback = RPM_GET_CALLBACK(dev, runtime_resume);
dev_pm_disable_wake_irq_check(dev); dev_pm_disable_wake_irq_check(dev, false);
retval = rpm_callback(callback, dev); retval = rpm_callback(callback, dev);
if (retval) { if (retval) {
__update_runtime_status(dev, RPM_SUSPENDED); __update_runtime_status(dev, RPM_SUSPENDED);

View File

@@ -142,24 +142,7 @@ static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/** static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag)
* dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
* @dev: Device entry
* @irq: Device wake-up interrupt
*
* Unless your hardware has separate wake-up interrupts in addition
* to the device IO interrupts, you don't need this.
*
* Sets up a threaded interrupt handler for a device that has
* a dedicated wake-up interrupt in addition to the device IO
* interrupt.
*
* The interrupt starts disabled, and needs to be managed for
* the device by the bus code or the device driver using
* dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq()
* functions.
*/
int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
{ {
struct wake_irq *wirq; struct wake_irq *wirq;
int err; int err;
@@ -197,7 +180,7 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
if (err) if (err)
goto err_free_irq; goto err_free_irq;
wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED; wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag;
return err; return err;
@@ -210,8 +193,57 @@ err_free:
return err; return err;
} }
/**
* dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
* @dev: Device entry
* @irq: Device wake-up interrupt
*
* Unless your hardware has separate wake-up interrupts in addition
* to the device IO interrupts, you don't need this.
*
* Sets up a threaded interrupt handler for a device that has
* a dedicated wake-up interrupt in addition to the device IO
* interrupt.
*
* The interrupt starts disabled, and needs to be managed for
* the device by the bus code or the device driver using
* dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*()
* functions.
*/
int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
{
return __dev_pm_set_dedicated_wake_irq(dev, irq, 0);
}
EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq); EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq);
/**
* dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt
* with reverse enable ordering
* @dev: Device entry
* @irq: Device wake-up interrupt
*
* Unless your hardware has separate wake-up interrupts in addition
* to the device IO interrupts, you don't need this.
*
* Sets up a threaded interrupt handler for a device that has a dedicated
* wake-up interrupt in addition to the device IO interrupt. It sets
* the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend()
* to enable dedicated wake-up interrupt after running the runtime suspend
* callback for @dev.
*
* The interrupt starts disabled, and needs to be managed for
* the device by the bus code or the device driver using
* dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*()
* functions.
*/
int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq)
{
return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE);
}
EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse);
/** /**
* dev_pm_enable_wake_irq - Enable device wake-up interrupt * dev_pm_enable_wake_irq - Enable device wake-up interrupt
* @dev: Device * @dev: Device
@@ -282,25 +314,56 @@ void dev_pm_enable_wake_irq_check(struct device *dev,
return; return;
enable: enable:
enable_irq(wirq->irq); if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) {
enable_irq(wirq->irq);
wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
}
} }
/** /**
* dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
* @dev: Device * @dev: Device
* @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE
* *
* Disables wake-up interrupt conditionally based on status. * Disables wake-up interrupt conditionally based on status.
* Should be only called from rpm_suspend() and rpm_resume() path. * Should be only called from rpm_suspend() and rpm_resume() path.
*/ */
void dev_pm_disable_wake_irq_check(struct device *dev) void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable)
{ {
struct wake_irq *wirq = dev->power.wakeirq; struct wake_irq *wirq = dev->power.wakeirq;
if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
return; return;
if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
return;
if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) {
wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED;
disable_irq_nosync(wirq->irq); disable_irq_nosync(wirq->irq);
}
}
/**
* dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before
* @dev: Device using the wake IRQ
*
* Enable wake IRQ conditionally based on status, mainly used if want to
* enable wake IRQ after running ->runtime_suspend() which depends on
* WAKE_IRQ_DEDICATED_REVERSE.
*
* Should be only called from rpm_suspend() path.
*/
void dev_pm_enable_wake_irq_complete(struct device *dev)
{
struct wake_irq *wirq = dev->power.wakeirq;
if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
return;
if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
wirq->status & WAKE_IRQ_DEDICATED_REVERSE)
enable_irq(wirq->irq);
} }
/** /**
@@ -317,7 +380,7 @@ void dev_pm_arm_wake_irq(struct wake_irq *wirq)
if (device_may_wakeup(wirq->dev)) { if (device_may_wakeup(wirq->dev)) {
if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
!pm_runtime_status_suspended(wirq->dev)) !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
enable_irq(wirq->irq); enable_irq(wirq->irq);
enable_irq_wake(wirq->irq); enable_irq_wake(wirq->irq);
@@ -340,7 +403,7 @@ void dev_pm_disarm_wake_irq(struct wake_irq *wirq)
disable_irq_wake(wirq->irq); disable_irq_wake(wirq->irq);
if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
!pm_runtime_status_suspended(wirq->dev)) !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
disable_irq_nosync(wirq->irq); disable_irq_nosync(wirq->irq);
} }
} }

View File

@@ -3677,7 +3677,7 @@ static int rbd_lock(struct rbd_device *rbd_dev)
ret = ceph_cls_lock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, ret = ceph_cls_lock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,
RBD_LOCK_NAME, CEPH_CLS_LOCK_EXCLUSIVE, cookie, RBD_LOCK_NAME, CEPH_CLS_LOCK_EXCLUSIVE, cookie,
RBD_LOCK_TAG, "", 0); RBD_LOCK_TAG, "", 0);
if (ret) if (ret && ret != -EEXIST)
return ret; return ret;
__rbd_lock(rbd_dev, cookie); __rbd_lock(rbd_dev, cookie);
@@ -3880,7 +3880,7 @@ static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev)
&rbd_dev->header_oloc, RBD_LOCK_NAME, &rbd_dev->header_oloc, RBD_LOCK_NAME,
&lock_type, &lock_tag, &lockers, &num_lockers); &lock_type, &lock_tag, &lockers, &num_lockers);
if (ret) { if (ret) {
rbd_warn(rbd_dev, "failed to retrieve lockers: %d", ret); rbd_warn(rbd_dev, "failed to get header lockers: %d", ret);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
@@ -3942,8 +3942,10 @@ static int find_watcher(struct rbd_device *rbd_dev,
ret = ceph_osdc_list_watchers(osdc, &rbd_dev->header_oid, ret = ceph_osdc_list_watchers(osdc, &rbd_dev->header_oid,
&rbd_dev->header_oloc, &watchers, &rbd_dev->header_oloc, &watchers,
&num_watchers); &num_watchers);
if (ret) if (ret) {
rbd_warn(rbd_dev, "failed to get watchers: %d", ret);
return ret; return ret;
}
sscanf(locker->id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", &cookie); sscanf(locker->id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", &cookie);
for (i = 0; i < num_watchers; i++) { for (i = 0; i < num_watchers; i++) {
@@ -3987,8 +3989,12 @@ static int rbd_try_lock(struct rbd_device *rbd_dev)
locker = refreshed_locker = NULL; locker = refreshed_locker = NULL;
ret = rbd_lock(rbd_dev); ret = rbd_lock(rbd_dev);
if (ret != -EBUSY) if (!ret)
goto out; goto out;
if (ret != -EBUSY) {
rbd_warn(rbd_dev, "failed to lock header: %d", ret);
goto out;
}
/* determine if the current lock holder is still alive */ /* determine if the current lock holder is still alive */
locker = get_lock_owner_info(rbd_dev); locker = get_lock_owner_info(rbd_dev);
@@ -4091,11 +4097,8 @@ static int rbd_try_acquire_lock(struct rbd_device *rbd_dev)
ret = rbd_try_lock(rbd_dev); ret = rbd_try_lock(rbd_dev);
if (ret < 0) { if (ret < 0) {
rbd_warn(rbd_dev, "failed to lock header: %d", ret); rbd_warn(rbd_dev, "failed to acquire lock: %d", ret);
if (ret == -EBLOCKLISTED) goto out;
goto out;
ret = 1; /* request lock anyway */
} }
if (ret > 0) { if (ret > 0) {
up_write(&rbd_dev->lock_rwsem); up_write(&rbd_dev->lock_rwsem);
@@ -6631,12 +6634,11 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
cancel_delayed_work_sync(&rbd_dev->lock_dwork); cancel_delayed_work_sync(&rbd_dev->lock_dwork);
if (!ret) if (!ret)
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
}
if (ret) { rbd_warn(rbd_dev, "failed to acquire lock: %ld", ret);
rbd_warn(rbd_dev, "failed to acquire exclusive lock: %ld", ret);
return ret;
} }
if (ret)
return ret;
/* /*
* The lock may have been released by now, unless automatic lock * The lock may have been released by now, unless automatic lock

View File

@@ -106,8 +106,10 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
return -ENOMEM; return -ENOMEM;
shmem = of_parse_phandle(cdev->of_node, "shmem", idx); shmem = of_parse_phandle(cdev->of_node, "shmem", idx);
if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) {
of_node_put(shmem);
return -ENXIO; return -ENXIO;
}
ret = of_address_to_resource(shmem, 0, &res); ret = of_address_to_resource(shmem, 0, &res);
of_node_put(shmem); of_node_put(shmem);

View File

@@ -76,8 +76,10 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
return -ENOMEM; return -ENOMEM;
np = of_parse_phandle(cdev->of_node, "shmem", 0); np = of_parse_phandle(cdev->of_node, "shmem", 0);
if (!of_device_is_compatible(np, "arm,scmi-shmem")) if (!of_device_is_compatible(np, "arm,scmi-shmem")) {
of_node_put(np);
return -ENXIO; return -ENXIO;
}
ret = of_address_to_resource(np, 0, &res); ret = of_address_to_resource(np, 0, &res);
of_node_put(np); of_node_put(np);

View File

@@ -311,7 +311,7 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc)
dev_warn(ipu_crtc->dev, "8-pixel align hactive %d -> %d\n", dev_warn(ipu_crtc->dev, "8-pixel align hactive %d -> %d\n",
sig_cfg.mode.hactive, new_hactive); sig_cfg.mode.hactive, new_hactive);
sig_cfg.mode.hfront_porch = new_hactive - sig_cfg.mode.hactive; sig_cfg.mode.hfront_porch -= new_hactive - sig_cfg.mode.hactive;
sig_cfg.mode.hactive = new_hactive; sig_cfg.mode.hactive = new_hactive;
} }

View File

@@ -606,7 +606,8 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
if (bo->pin_count) { if (bo->pin_count) {
*locked = false; *locked = false;
*busy = false; if (busy)
*busy = false;
return false; return false;
} }

View File

@@ -897,6 +897,12 @@ static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu,
struct arm_smmu_cmdq_batch *cmds, struct arm_smmu_cmdq_batch *cmds,
struct arm_smmu_cmdq_ent *cmd) struct arm_smmu_cmdq_ent *cmd)
{ {
if (cmds->num == CMDQ_BATCH_ENTRIES - 1 &&
(smmu->options & ARM_SMMU_OPT_CMDQ_FORCE_SYNC)) {
arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, true);
cmds->num = 0;
}
if (cmds->num == CMDQ_BATCH_ENTRIES) { if (cmds->num == CMDQ_BATCH_ENTRIES) {
arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, false); arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, false);
cmds->num = 0; cmds->num = 0;
@@ -3459,6 +3465,44 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
return 0; return 0;
} }
#define IIDR_IMPLEMENTER_ARM 0x43b
#define IIDR_PRODUCTID_ARM_MMU_600 0x483
#define IIDR_PRODUCTID_ARM_MMU_700 0x487
static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
{
u32 reg;
unsigned int implementer, productid, variant, revision;
reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR);
implementer = FIELD_GET(IIDR_IMPLEMENTER, reg);
productid = FIELD_GET(IIDR_PRODUCTID, reg);
variant = FIELD_GET(IIDR_VARIANT, reg);
revision = FIELD_GET(IIDR_REVISION, reg);
switch (implementer) {
case IIDR_IMPLEMENTER_ARM:
switch (productid) {
case IIDR_PRODUCTID_ARM_MMU_600:
/* Arm erratum 1076982 */
if (variant == 0 && revision <= 2)
smmu->features &= ~ARM_SMMU_FEAT_SEV;
/* Arm erratum 1209401 */
if (variant < 2)
smmu->features &= ~ARM_SMMU_FEAT_NESTING;
break;
case IIDR_PRODUCTID_ARM_MMU_700:
/* Arm erratum 2812531 */
smmu->features &= ~ARM_SMMU_FEAT_BTM;
smmu->options |= ARM_SMMU_OPT_CMDQ_FORCE_SYNC;
/* Arm errata 2268618, 2812531 */
smmu->features &= ~ARM_SMMU_FEAT_NESTING;
break;
}
break;
}
}
static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
{ {
u32 reg; u32 reg;
@@ -3664,6 +3708,12 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
smmu->ias = max(smmu->ias, smmu->oas); smmu->ias = max(smmu->ias, smmu->oas);
if ((smmu->features & ARM_SMMU_FEAT_TRANS_S1) &&
(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
smmu->features |= ARM_SMMU_FEAT_NESTING;
arm_smmu_device_iidr_probe(smmu);
if (arm_smmu_sva_supported(smmu)) if (arm_smmu_sva_supported(smmu))
smmu->features |= ARM_SMMU_FEAT_SVA; smmu->features |= ARM_SMMU_FEAT_SVA;

View File

@@ -69,6 +69,12 @@
#define IDR5_VAX GENMASK(11, 10) #define IDR5_VAX GENMASK(11, 10)
#define IDR5_VAX_52_BIT 1 #define IDR5_VAX_52_BIT 1
#define ARM_SMMU_IIDR 0x18
#define IIDR_PRODUCTID GENMASK(31, 20)
#define IIDR_VARIANT GENMASK(19, 16)
#define IIDR_REVISION GENMASK(15, 12)
#define IIDR_IMPLEMENTER GENMASK(11, 0)
#define ARM_SMMU_CR0 0x20 #define ARM_SMMU_CR0 0x20
#define CR0_ATSCHK (1 << 4) #define CR0_ATSCHK (1 << 4)
#define CR0_CMDQEN (1 << 3) #define CR0_CMDQEN (1 << 3)
@@ -640,11 +646,13 @@ struct arm_smmu_device {
#define ARM_SMMU_FEAT_BTM (1 << 16) #define ARM_SMMU_FEAT_BTM (1 << 16)
#define ARM_SMMU_FEAT_SVA (1 << 17) #define ARM_SMMU_FEAT_SVA (1 << 17)
#define ARM_SMMU_FEAT_E2H (1 << 18) #define ARM_SMMU_FEAT_E2H (1 << 18)
#define ARM_SMMU_FEAT_NESTING (1 << 19)
u32 features; u32 features;
#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
#define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1) #define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1)
#define ARM_SMMU_OPT_MSIPOLL (1 << 2) #define ARM_SMMU_OPT_MSIPOLL (1 << 2)
#define ARM_SMMU_OPT_CMDQ_FORCE_SYNC (1 << 3)
u32 options; u32 options;
struct arm_smmu_cmdq cmdq; struct arm_smmu_cmdq cmdq;

View File

@@ -839,7 +839,7 @@ hfcpci_fill_fifo(struct bchannel *bch)
*z1t = cpu_to_le16(new_z1); /* now send data */ *z1t = cpu_to_le16(new_z1); /* now send data */
if (bch->tx_idx < bch->tx_skb->len) if (bch->tx_idx < bch->tx_skb->len)
return; return;
dev_kfree_skb(bch->tx_skb); dev_kfree_skb_any(bch->tx_skb);
if (get_next_bframe(bch)) if (get_next_bframe(bch))
goto next_t_frame; goto next_t_frame;
return; return;
@@ -895,7 +895,7 @@ hfcpci_fill_fifo(struct bchannel *bch)
} }
bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */ bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */
bz->f1 = new_f1; /* next frame */ bz->f1 = new_f1; /* next frame */
dev_kfree_skb(bch->tx_skb); dev_kfree_skb_any(bch->tx_skb);
get_next_bframe(bch); get_next_bframe(bch);
} }
@@ -1119,7 +1119,7 @@ tx_birq(struct bchannel *bch)
if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
hfcpci_fill_fifo(bch); hfcpci_fill_fifo(bch);
else { else {
dev_kfree_skb(bch->tx_skb); dev_kfree_skb_any(bch->tx_skb);
if (get_next_bframe(bch)) if (get_next_bframe(bch))
hfcpci_fill_fifo(bch); hfcpci_fill_fifo(bch);
} }
@@ -2277,7 +2277,7 @@ _hfcpci_softirq(struct device *dev, void *unused)
return 0; return 0;
if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) { if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) {
spin_lock(&hc->lock); spin_lock_irq(&hc->lock);
bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */ if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */
main_rec_hfcpci(bch); main_rec_hfcpci(bch);
@@ -2288,7 +2288,7 @@ _hfcpci_softirq(struct device *dev, void *unused)
main_rec_hfcpci(bch); main_rec_hfcpci(bch);
tx_birq(bch); tx_birq(bch);
} }
spin_unlock(&hc->lock); spin_unlock_irq(&hc->lock);
} }
return 0; return 0;
} }

View File

@@ -135,7 +135,7 @@ static int fun_exec_op(struct nand_chip *chip, const struct nand_operation *op,
unsigned int i; unsigned int i;
int ret; int ret;
if (op->cs > NAND_MAX_CHIPS) if (op->cs >= NAND_MAX_CHIPS)
return -EINVAL; return -EINVAL;
if (check_only) if (check_only)

View File

@@ -1180,7 +1180,6 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
struct meson_nfc *nfc = nand_get_controller_data(nand); struct meson_nfc *nfc = nand_get_controller_data(nand);
struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
struct mtd_info *mtd = nand_to_mtd(nand); struct mtd_info *mtd = nand_to_mtd(nand);
int nsectors = mtd->writesize / 1024;
int ret; int ret;
if (!mtd->name) { if (!mtd->name) {
@@ -1198,7 +1197,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand)
nand->options |= NAND_NO_SUBPAGE_WRITE; nand->options |= NAND_NO_SUBPAGE_WRITE;
ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps,
mtd->oobsize - 2 * nsectors); mtd->oobsize - 2);
if (ret) { if (ret) {
dev_err(nfc->dev, "failed to ECC init\n"); dev_err(nfc->dev, "failed to ECC init\n");
return -EINVAL; return -EINVAL;

View File

@@ -177,17 +177,17 @@ static void elm_load_syndrome(struct elm_info *info,
switch (info->bch_type) { switch (info->bch_type) {
case BCH8_ECC: case BCH8_ECC:
/* syndrome fragment 0 = ecc[9-12B] */ /* syndrome fragment 0 = ecc[9-12B] */
val = cpu_to_be32(*(u32 *) &ecc[9]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[9]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
/* syndrome fragment 1 = ecc[5-8B] */ /* syndrome fragment 1 = ecc[5-8B] */
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[5]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[5]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
/* syndrome fragment 2 = ecc[1-4B] */ /* syndrome fragment 2 = ecc[1-4B] */
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[1]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[1]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
/* syndrome fragment 3 = ecc[0B] */ /* syndrome fragment 3 = ecc[0B] */
@@ -197,35 +197,35 @@ static void elm_load_syndrome(struct elm_info *info,
break; break;
case BCH4_ECC: case BCH4_ECC:
/* syndrome fragment 0 = ecc[20-52b] bits */ /* syndrome fragment 0 = ecc[20-52b] bits */
val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) | val = ((__force u32)cpu_to_be32(*(u32 *)&ecc[3]) >> 4) |
((ecc[2] & 0xf) << 28); ((ecc[2] & 0xf) << 28);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
/* syndrome fragment 1 = ecc[0-20b] bits */ /* syndrome fragment 1 = ecc[0-20b] bits */
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12; val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 12;
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
break; break;
case BCH16_ECC: case BCH16_ECC:
val = cpu_to_be32(*(u32 *) &ecc[22]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[22]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[18]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[18]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[14]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[14]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[10]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[10]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[6]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[6]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[2]); val = (__force u32)cpu_to_be32(*(u32 *)&ecc[2]);
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
offset += 4; offset += 4;
val = cpu_to_be32(*(u32 *) &ecc[0]) >> 16; val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 16;
elm_write_reg(info, offset, val); elm_write_reg(info, offset, val);
break; break;
default: default:

View File

@@ -562,9 +562,10 @@ static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf,
* BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3 * BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3
* *
* The rk_nfc_ooblayout_free() function already has reserved * The rk_nfc_ooblayout_free() function already has reserved
* these 4 bytes with: * these 4 bytes together with 2 bytes for BBM
* by reducing it's length:
* *
* oob_region->offset = NFC_SYS_DATA_SIZE + 2; * oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2;
*/ */
if (!i) if (!i)
memcpy(rk_nfc_oob_ptr(chip, i), memcpy(rk_nfc_oob_ptr(chip, i),
@@ -597,7 +598,7 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
int pages_per_blk = mtd->erasesize / mtd->writesize; int pages_per_blk = mtd->erasesize / mtd->writesize;
int ret = 0, i, boot_rom_mode = 0; int ret = 0, i, boot_rom_mode = 0;
dma_addr_t dma_data, dma_oob; dma_addr_t dma_data, dma_oob;
u32 reg; u32 tmp;
u8 *oob; u8 *oob;
nand_prog_page_begin_op(chip, page, 0, NULL, 0); nand_prog_page_begin_op(chip, page, 0, NULL, 0);
@@ -624,6 +625,13 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
* *
* 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ... * 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ...
* *
* The code here just swaps the first 4 bytes with the last
* 4 bytes without losing any data.
*
* The chip->oob_poi data layout:
*
* BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3
*
* Configure the ECC algorithm supported by the boot ROM. * Configure the ECC algorithm supported by the boot ROM.
*/ */
if ((page < (pages_per_blk * rknand->boot_blks)) && if ((page < (pages_per_blk * rknand->boot_blks)) &&
@@ -634,21 +642,17 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
} }
for (i = 0; i < ecc->steps; i++) { for (i = 0; i < ecc->steps; i++) {
if (!i) { if (!i)
reg = 0xFFFFFFFF; oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE;
} else { else
oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
reg = oob[0] | oob[1] << 8 | oob[2] << 16 |
oob[3] << 24;
}
if (!i && boot_rom_mode) tmp = oob[0] | oob[1] << 8 | oob[2] << 16 | oob[3] << 24;
reg = (page & (pages_per_blk - 1)) * 4;
if (nfc->cfg->type == NFC_V9) if (nfc->cfg->type == NFC_V9)
nfc->oob_buf[i] = reg; nfc->oob_buf[i] = tmp;
else else
nfc->oob_buf[i * (oob_step / 4)] = reg; nfc->oob_buf[i * (oob_step / 4)] = tmp;
} }
dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf, dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf,
@@ -811,12 +815,17 @@ static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on,
goto timeout_err; goto timeout_err;
} }
for (i = 1; i < ecc->steps; i++) { for (i = 0; i < ecc->steps; i++) {
oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; if (!i)
oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE;
else
oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
if (nfc->cfg->type == NFC_V9) if (nfc->cfg->type == NFC_V9)
tmp = nfc->oob_buf[i]; tmp = nfc->oob_buf[i];
else else
tmp = nfc->oob_buf[i * (oob_step / 4)]; tmp = nfc->oob_buf[i * (oob_step / 4)];
*oob++ = (u8)tmp; *oob++ = (u8)tmp;
*oob++ = (u8)(tmp >> 8); *oob++ = (u8)(tmp >> 8);
*oob++ = (u8)(tmp >> 16); *oob++ = (u8)(tmp >> 16);
@@ -935,12 +944,8 @@ static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section,
if (section) if (section)
return -ERANGE; return -ERANGE;
/*
* The beginning of the OOB area stores the reserved data for the NFC,
* the size of the reserved data is NFC_SYS_DATA_SIZE bytes.
*/
oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2; oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2;
oob_region->offset = NFC_SYS_DATA_SIZE + 2; oob_region->offset = 2;
return 0; return 0;
} }

View File

@@ -73,7 +73,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
{ {
struct nand_device *nand = spinand_to_nand(spinand); struct nand_device *nand = spinand_to_nand(spinand);
u8 mbf = 0; u8 mbf = 0;
struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf);
switch (status & STATUS_ECC_MASK) { switch (status & STATUS_ECC_MASK) {
case STATUS_ECC_NO_BITFLIPS: case STATUS_ECC_NO_BITFLIPS:
@@ -92,7 +92,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
if (spi_mem_exec_op(spinand->spimem, &op)) if (spi_mem_exec_op(spinand->spimem, &op))
return nanddev_get_ecc_conf(nand)->strength; return nanddev_get_ecc_conf(nand)->strength;
mbf >>= 4; mbf = *(spinand->scratchbuf) >> 4;
if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
return nanddev_get_ecc_conf(nand)->strength; return nanddev_get_ecc_conf(nand)->strength;

View File

@@ -1422,7 +1422,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
if (IS_ERR(priv->clk)) if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk); return PTR_ERR(priv->clk);
clk_prepare_enable(priv->clk); ret = clk_prepare_enable(priv->clk);
if (ret)
return ret;
priv->clk_mdiv = devm_clk_get_optional(&pdev->dev, "sw_switch_mdiv"); priv->clk_mdiv = devm_clk_get_optional(&pdev->dev, "sw_switch_mdiv");
if (IS_ERR(priv->clk_mdiv)) { if (IS_ERR(priv->clk_mdiv)) {
@@ -1430,7 +1432,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
goto out_clk; goto out_clk;
} }
clk_prepare_enable(priv->clk_mdiv); ret = clk_prepare_enable(priv->clk_mdiv);
if (ret)
goto out_clk;
ret = bcm_sf2_sw_rst(priv); ret = bcm_sf2_sw_rst(priv);
if (ret) { if (ret) {

View File

@@ -1301,11 +1301,10 @@ static int korina_probe(struct platform_device *pdev)
else if (of_get_ethdev_address(pdev->dev.of_node, dev) < 0) else if (of_get_ethdev_address(pdev->dev.of_node, dev) < 0)
eth_hw_addr_random(dev); eth_hw_addr_random(dev);
clk = devm_clk_get_optional(&pdev->dev, "mdioclk"); clk = devm_clk_get_optional_enabled(&pdev->dev, "mdioclk");
if (IS_ERR(clk)) if (IS_ERR(clk))
return PTR_ERR(clk); return PTR_ERR(clk);
if (clk) { if (clk) {
clk_prepare_enable(clk);
lp->mii_clock_freq = clk_get_rate(clk); lp->mii_clock_freq = clk_get_rate(clk);
} else { } else {
lp->mii_clock_freq = 200000000; /* max possible input clk */ lp->mii_clock_freq = 200000000; /* max possible input clk */

View File

@@ -645,7 +645,8 @@ pick_fw_ver:
err = request_firmware_direct(&fw->bin, fw_path, fw->dev.dev); err = request_firmware_direct(&fw->bin, fw_path, fw->dev.dev);
if (err) { if (err) {
if (ver_maj == PRESTERA_SUPP_FW_MAJ_VER) { if (ver_maj != PRESTERA_PREV_FW_MAJ_VER ||
ver_min != PRESTERA_PREV_FW_MIN_VER) {
ver_maj = PRESTERA_PREV_FW_MAJ_VER; ver_maj = PRESTERA_PREV_FW_MAJ_VER;
ver_min = PRESTERA_PREV_FW_MIN_VER; ver_min = PRESTERA_PREV_FW_MIN_VER;

View File

@@ -121,7 +121,9 @@ static int mlx5e_ipsec_remove_trailer(struct sk_buff *skb, struct xfrm_state *x)
trailer_len = alen + plen + 2; trailer_len = alen + plen + 2;
pskb_trim(skb, skb->len - trailer_len); ret = pskb_trim(skb, skb->len - trailer_len);
if (unlikely(ret))
return ret;
if (skb->protocol == htons(ETH_P_IP)) { if (skb->protocol == htons(ETH_P_IP)) {
ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len); ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len);
ip_send_check(ipv4hdr); ip_send_check(ipv4hdr);

View File

@@ -981,7 +981,7 @@ void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev)
mutex_lock(&table->lock); /* sync with create/destroy_async_eq */ mutex_lock(&table->lock); /* sync with create/destroy_async_eq */
if (!mlx5_core_is_sf(dev)) if (!mlx5_core_is_sf(dev))
clear_rmap(dev); clear_rmap(dev);
mlx5_irq_table_destroy(dev); mlx5_irq_table_free_irqs(dev);
mutex_unlock(&table->lock); mutex_unlock(&table->lock);
} }

View File

@@ -802,7 +802,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
struct fs_node *iter = list_entry(start, struct fs_node, list); struct fs_node *iter = list_entry(start, struct fs_node, list);
struct mlx5_flow_table *ft = NULL; struct mlx5_flow_table *ft = NULL;
if (!root || root->type == FS_TYPE_PRIO_CHAINS) if (!root)
return NULL; return NULL;
list_for_each_advance_continue(iter, &root->children, reverse) { list_for_each_advance_continue(iter, &root->children, reverse) {
@@ -818,20 +818,42 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
return ft; return ft;
} }
/* If reverse is false then return the first flow table in next priority of static struct fs_node *find_prio_chains_parent(struct fs_node *parent,
* prio in the tree, else return the last flow table in the previous priority struct fs_node **child)
* of prio in the tree.
*/
static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool reverse)
{ {
struct fs_node *node = NULL;
while (parent && parent->type != FS_TYPE_PRIO_CHAINS) {
node = parent;
parent = parent->parent;
}
if (child)
*child = node;
return parent;
}
/* If reverse is false then return the first flow table next to the passed node
* in the tree, else return the last flow table before the node in the tree.
* If skip is true, skip the flow tables in the same prio_chains prio.
*/
static struct mlx5_flow_table *find_closest_ft(struct fs_node *node, bool reverse,
bool skip)
{
struct fs_node *prio_chains_parent = NULL;
struct mlx5_flow_table *ft = NULL; struct mlx5_flow_table *ft = NULL;
struct fs_node *curr_node; struct fs_node *curr_node;
struct fs_node *parent; struct fs_node *parent;
parent = prio->node.parent; if (skip)
curr_node = &prio->node; prio_chains_parent = find_prio_chains_parent(node, NULL);
parent = node->parent;
curr_node = node;
while (!ft && parent) { while (!ft && parent) {
ft = find_closest_ft_recursive(parent, &curr_node->list, reverse); if (parent != prio_chains_parent)
ft = find_closest_ft_recursive(parent, &curr_node->list,
reverse);
curr_node = parent; curr_node = parent;
parent = curr_node->parent; parent = curr_node->parent;
} }
@@ -839,15 +861,15 @@ static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool revers
} }
/* Assuming all the tree is locked by mutex chain lock */ /* Assuming all the tree is locked by mutex chain lock */
static struct mlx5_flow_table *find_next_chained_ft(struct fs_prio *prio) static struct mlx5_flow_table *find_next_chained_ft(struct fs_node *node)
{ {
return find_closest_ft(prio, false); return find_closest_ft(node, false, true);
} }
/* Assuming all the tree is locked by mutex chain lock */ /* Assuming all the tree is locked by mutex chain lock */
static struct mlx5_flow_table *find_prev_chained_ft(struct fs_prio *prio) static struct mlx5_flow_table *find_prev_chained_ft(struct fs_node *node)
{ {
return find_closest_ft(prio, true); return find_closest_ft(node, true, true);
} }
static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft, static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
@@ -859,7 +881,7 @@ static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
next_ns = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS; next_ns = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS;
fs_get_obj(prio, next_ns ? ft->ns->node.parent : ft->node.parent); fs_get_obj(prio, next_ns ? ft->ns->node.parent : ft->node.parent);
return find_next_chained_ft(prio); return find_next_chained_ft(&prio->node);
} }
static int connect_fts_in_prio(struct mlx5_core_dev *dev, static int connect_fts_in_prio(struct mlx5_core_dev *dev,
@@ -883,21 +905,55 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev,
return 0; return 0;
} }
static struct mlx5_flow_table *find_closet_ft_prio_chains(struct fs_node *node,
struct fs_node *parent,
struct fs_node **child,
bool reverse)
{
struct mlx5_flow_table *ft;
ft = find_closest_ft(node, reverse, false);
if (ft && parent == find_prio_chains_parent(&ft->node, child))
return ft;
return NULL;
}
/* Connect flow tables from previous priority of prio to ft */ /* Connect flow tables from previous priority of prio to ft */
static int connect_prev_fts(struct mlx5_core_dev *dev, static int connect_prev_fts(struct mlx5_core_dev *dev,
struct mlx5_flow_table *ft, struct mlx5_flow_table *ft,
struct fs_prio *prio) struct fs_prio *prio)
{ {
struct fs_node *prio_parent, *parent = NULL, *child, *node;
struct mlx5_flow_table *prev_ft; struct mlx5_flow_table *prev_ft;
int err = 0;
prev_ft = find_prev_chained_ft(prio); prio_parent = find_prio_chains_parent(&prio->node, &child);
if (prev_ft) {
/* return directly if not under the first sub ns of prio_chains prio */
if (prio_parent && !list_is_first(&child->list, &prio_parent->children))
return 0;
prev_ft = find_prev_chained_ft(&prio->node);
while (prev_ft) {
struct fs_prio *prev_prio; struct fs_prio *prev_prio;
fs_get_obj(prev_prio, prev_ft->node.parent); fs_get_obj(prev_prio, prev_ft->node.parent);
return connect_fts_in_prio(dev, prev_prio, ft); err = connect_fts_in_prio(dev, prev_prio, ft);
if (err)
break;
if (!parent) {
parent = find_prio_chains_parent(&prev_prio->node, &child);
if (!parent)
break;
}
node = child;
prev_ft = find_closet_ft_prio_chains(node, parent, &child, true);
} }
return 0; return err;
} }
static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio
@@ -1036,7 +1092,7 @@ static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table
if (err) if (err)
return err; return err;
next_ft = first_ft ? first_ft : find_next_chained_ft(prio); next_ft = first_ft ? first_ft : find_next_chained_ft(&prio->node);
err = connect_fwd_rules(dev, ft, next_ft); err = connect_fwd_rules(dev, ft, next_ft);
if (err) if (err)
return err; return err;
@@ -1111,7 +1167,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table); tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table);
next_ft = unmanaged ? ft_attr->next_ft : next_ft = unmanaged ? ft_attr->next_ft :
find_next_chained_ft(fs_prio); find_next_chained_ft(&fs_prio->node);
ft->def_miss_action = ns->def_miss_action; ft->def_miss_action = ns->def_miss_action;
ft->ns = ns; ft->ns = ns;
err = root->cmds->create_flow_table(root, ft, ft_attr->max_fte, next_ft); err = root->cmds->create_flow_table(root, ft, ft_attr->max_fte, next_ft);
@@ -2080,13 +2136,20 @@ EXPORT_SYMBOL(mlx5_del_flow_rules);
/* Assuming prio->node.children(flow tables) is sorted by level */ /* Assuming prio->node.children(flow tables) is sorted by level */
static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft) static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft)
{ {
struct fs_node *prio_parent, *child;
struct fs_prio *prio; struct fs_prio *prio;
fs_get_obj(prio, ft->node.parent); fs_get_obj(prio, ft->node.parent);
if (!list_is_last(&ft->node.list, &prio->node.children)) if (!list_is_last(&ft->node.list, &prio->node.children))
return list_next_entry(ft, node.list); return list_next_entry(ft, node.list);
return find_next_chained_ft(prio);
prio_parent = find_prio_chains_parent(&prio->node, &child);
if (prio_parent && list_is_first(&child->list, &prio_parent->children))
return find_closest_ft(&prio->node, false, false);
return find_next_chained_ft(&prio->node);
} }
static int update_root_ft_destroy(struct mlx5_flow_table *ft) static int update_root_ft_destroy(struct mlx5_flow_table *ft)

View File

@@ -16,6 +16,7 @@ int mlx5_irq_table_init(struct mlx5_core_dev *dev);
void mlx5_irq_table_cleanup(struct mlx5_core_dev *dev); void mlx5_irq_table_cleanup(struct mlx5_core_dev *dev);
int mlx5_irq_table_create(struct mlx5_core_dev *dev); int mlx5_irq_table_create(struct mlx5_core_dev *dev);
void mlx5_irq_table_destroy(struct mlx5_core_dev *dev); void mlx5_irq_table_destroy(struct mlx5_core_dev *dev);
void mlx5_irq_table_free_irqs(struct mlx5_core_dev *dev);
int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table); int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table);
int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table); int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table);
struct mlx5_irq_table *mlx5_irq_table_get(struct mlx5_core_dev *dev); struct mlx5_irq_table *mlx5_irq_table_get(struct mlx5_core_dev *dev);

View File

@@ -550,6 +550,24 @@ static void irq_pools_destroy(struct mlx5_irq_table *table)
irq_pool_free(table->pf_pool); irq_pool_free(table->pf_pool);
} }
static void mlx5_irq_pool_free_irqs(struct mlx5_irq_pool *pool)
{
struct mlx5_irq *irq;
unsigned long index;
xa_for_each(&pool->irqs, index, irq)
free_irq(irq->irqn, &irq->nh);
}
static void mlx5_irq_pools_free_irqs(struct mlx5_irq_table *table)
{
if (table->sf_ctrl_pool) {
mlx5_irq_pool_free_irqs(table->sf_comp_pool);
mlx5_irq_pool_free_irqs(table->sf_ctrl_pool);
}
mlx5_irq_pool_free_irqs(table->pf_pool);
}
/* irq_table API */ /* irq_table API */
int mlx5_irq_table_init(struct mlx5_core_dev *dev) int mlx5_irq_table_init(struct mlx5_core_dev *dev)
@@ -630,6 +648,17 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev)
pci_free_irq_vectors(dev->pdev); pci_free_irq_vectors(dev->pdev);
} }
void mlx5_irq_table_free_irqs(struct mlx5_core_dev *dev)
{
struct mlx5_irq_table *table = dev->priv.irq_table;
if (mlx5_core_is_sf(dev))
return;
mlx5_irq_pools_free_irqs(table);
pci_free_irq_vectors(dev->pdev);
}
int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table) int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table)
{ {
if (table->sf_comp_pool) if (table->sf_comp_pool)

View File

@@ -528,11 +528,12 @@ int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev,
err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
if (err) if (err)
return err; goto err_free_in;
*reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id); *reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id);
kvfree(in);
err_free_in:
kvfree(in);
return err; return err;
} }

View File

@@ -877,12 +877,13 @@ u32 qed_get_hsi_def_val(struct qed_dev *cdev, enum qed_hsi_def_type type);
/** /**
* @brief qed_concrete_to_sw_fid - get the sw function id from * qed_concrete_to_sw_fid(): Get the sw function id from
* the concrete value. * the concrete value.
* *
* @param concrete_fid * @cdev: Qed dev pointer.
* @concrete_fid: Concrete fid.
* *
* @return inline u8 * Return: inline u8.
*/ */
static inline u8 qed_concrete_to_sw_fid(struct qed_dev *cdev, static inline u8 qed_concrete_to_sw_fid(struct qed_dev *cdev,
u32 concrete_fid) u32 concrete_fid)

View File

@@ -28,24 +28,23 @@ struct qed_tid_mem {
}; };
/** /**
* @brief qedo_cid_get_cxt_info - Returns the context info for a specific cid * qed_cxt_get_cid_info(): Returns the context info for a specific cidi.
* *
* @p_hwfn: HW device data.
* @p_info: In/out.
* *
* @param p_hwfn * Return: Int.
* @param p_info in/out
*
* @return int
*/ */
int qed_cxt_get_cid_info(struct qed_hwfn *p_hwfn, int qed_cxt_get_cid_info(struct qed_hwfn *p_hwfn,
struct qed_cxt_info *p_info); struct qed_cxt_info *p_info);
/** /**
* @brief qed_cxt_get_tid_mem_info * qed_cxt_get_tid_mem_info(): Returns the tid mem info.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_info * @p_info: in/out.
* *
* @return int * Return: int.
*/ */
int qed_cxt_get_tid_mem_info(struct qed_hwfn *p_hwfn, int qed_cxt_get_tid_mem_info(struct qed_hwfn *p_hwfn,
struct qed_tid_mem *p_info); struct qed_tid_mem *p_info);
@@ -64,142 +63,155 @@ u32 qed_cxt_get_proto_cid_count(struct qed_hwfn *p_hwfn,
enum protocol_type type, u32 *vf_cid); enum protocol_type type, u32 *vf_cid);
/** /**
* @brief qed_cxt_set_pf_params - Set the PF params for cxt init * qed_cxt_set_pf_params(): Set the PF params for cxt init.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param rdma_tasks - requested maximum * @rdma_tasks: Requested maximum.
* @return int *
* Return: int.
*/ */
int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn, u32 rdma_tasks); int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn, u32 rdma_tasks);
/** /**
* @brief qed_cxt_cfg_ilt_compute - compute ILT init parameters * qed_cxt_cfg_ilt_compute(): Compute ILT init parameters.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param last_line * @last_line: Last_line.
* *
* @return int * Return: Int
*/ */
int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *last_line); int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *last_line);
/** /**
* @brief qed_cxt_cfg_ilt_compute_excess - how many lines can be decreased * qed_cxt_cfg_ilt_compute_excess(): How many lines can be decreased.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param used_lines * @used_lines: Used lines.
*
* Return: Int.
*/ */
u32 qed_cxt_cfg_ilt_compute_excess(struct qed_hwfn *p_hwfn, u32 used_lines); u32 qed_cxt_cfg_ilt_compute_excess(struct qed_hwfn *p_hwfn, u32 used_lines);
/** /**
* @brief qed_cxt_mngr_alloc - Allocate and init the context manager struct * qed_cxt_mngr_alloc(): Allocate and init the context manager struct.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_cxt_mngr_alloc(struct qed_hwfn *p_hwfn); int qed_cxt_mngr_alloc(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_cxt_mngr_free * qed_cxt_mngr_free() - Context manager free.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_cxt_mngr_free(struct qed_hwfn *p_hwfn); void qed_cxt_mngr_free(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_cxt_tables_alloc - Allocate ILT shadow, Searcher T2, acquired map * qed_cxt_tables_alloc(): Allocate ILT shadow, Searcher T2, acquired map.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_cxt_tables_alloc(struct qed_hwfn *p_hwfn); int qed_cxt_tables_alloc(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_cxt_mngr_setup - Reset the acquired CIDs * qed_cxt_mngr_setup(): Reset the acquired CIDs.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*/ */
void qed_cxt_mngr_setup(struct qed_hwfn *p_hwfn); void qed_cxt_mngr_setup(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_cxt_hw_init_common - Initailze ILT and DQ, common phase, per path. * qed_cxt_hw_init_common(): Initailze ILT and DQ, common phase, per path.
* *
* @p_hwfn: HW device data.
* *
* * Return: Void.
* @param p_hwfn
*/ */
void qed_cxt_hw_init_common(struct qed_hwfn *p_hwfn); void qed_cxt_hw_init_common(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_cxt_hw_init_pf - Initailze ILT and DQ, PF phase, per path. * qed_cxt_hw_init_pf(): Initailze ILT and DQ, PF phase, per path.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
*
* Return: Void.
*/ */
void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
/** /**
* @brief qed_qm_init_pf - Initailze the QM PF phase, per path * qed_qm_init_pf(): Initailze the QM PF phase, per path.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param is_pf_loading * @is_pf_loading: Is pf pending.
*
* Return: Void.
*/ */
void qed_qm_init_pf(struct qed_hwfn *p_hwfn, void qed_qm_init_pf(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, bool is_pf_loading); struct qed_ptt *p_ptt, bool is_pf_loading);
/** /**
* @brief Reconfigures QM pf on the fly * qed_qm_reconf(): Reconfigures QM pf on the fly.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* *
* @return int * Return: Int.
*/ */
int qed_qm_reconf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); int qed_qm_reconf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
#define QED_CXT_PF_CID (0xff) #define QED_CXT_PF_CID (0xff)
/** /**
* @brief qed_cxt_release - Release a cid * qed_cxt_release_cid(): Release a cid.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param cid * @cid: Cid.
*
* Return: Void.
*/ */
void qed_cxt_release_cid(struct qed_hwfn *p_hwfn, u32 cid); void qed_cxt_release_cid(struct qed_hwfn *p_hwfn, u32 cid);
/** /**
* @brief qed_cxt_release - Release a cid belonging to a vf-queue * _qed_cxt_release_cid(): Release a cid belonging to a vf-queue.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param cid * @cid: Cid.
* @param vfid - engine relative index. QED_CXT_PF_CID if belongs to PF * @vfid: Engine relative index. QED_CXT_PF_CID if belongs to PF.
*
* Return: Void.
*/ */
void _qed_cxt_release_cid(struct qed_hwfn *p_hwfn, u32 cid, u8 vfid); void _qed_cxt_release_cid(struct qed_hwfn *p_hwfn, u32 cid, u8 vfid);
/** /**
* @brief qed_cxt_acquire - Acquire a new cid of a specific protocol type * qed_cxt_acquire_cid(): Acquire a new cid of a specific protocol type.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param type * @type: Type.
* @param p_cid * @p_cid: Pointer cid.
* *
* @return int * Return: Int.
*/ */
int qed_cxt_acquire_cid(struct qed_hwfn *p_hwfn, int qed_cxt_acquire_cid(struct qed_hwfn *p_hwfn,
enum protocol_type type, u32 *p_cid); enum protocol_type type, u32 *p_cid);
/** /**
* @brief _qed_cxt_acquire - Acquire a new cid of a specific protocol type * _qed_cxt_acquire_cid(): Acquire a new cid of a specific protocol type
* for a vf-queue * for a vf-queue.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param type * @type: Type.
* @param p_cid * @p_cid: Pointer cid.
* @param vfid - engine relative index. QED_CXT_PF_CID if belongs to PF * @vfid: Engine relative index. QED_CXT_PF_CID if belongs to PF.
* *
* @return int * Return: Int.
*/ */
int _qed_cxt_acquire_cid(struct qed_hwfn *p_hwfn, int _qed_cxt_acquire_cid(struct qed_hwfn *p_hwfn,
enum protocol_type type, u32 *p_cid, u8 vfid); enum protocol_type type, u32 *p_cid, u8 vfid);

View File

@@ -15,44 +15,52 @@
#include "qed_int.h" #include "qed_int.h"
/** /**
* @brief qed_init_dp - initialize the debug level * qed_init_dp(): Initialize the debug level.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param dp_module * @dp_module: Module debug parameter.
* @param dp_level * @dp_level: Module debug level.
*
* Return: Void.
*/ */
void qed_init_dp(struct qed_dev *cdev, void qed_init_dp(struct qed_dev *cdev,
u32 dp_module, u32 dp_module,
u8 dp_level); u8 dp_level);
/** /**
* @brief qed_init_struct - initialize the device structure to * qed_init_struct(): Initialize the device structure to
* its defaults * its defaults.
* *
* @param cdev * @cdev: Qed dev pointer.
*
* Return: Void.
*/ */
void qed_init_struct(struct qed_dev *cdev); void qed_init_struct(struct qed_dev *cdev);
/** /**
* @brief qed_resc_free - * qed_resc_free: Free device resources.
* *
* @param cdev * @cdev: Qed dev pointer.
*
* Return: Void.
*/ */
void qed_resc_free(struct qed_dev *cdev); void qed_resc_free(struct qed_dev *cdev);
/** /**
* @brief qed_resc_alloc - * qed_resc_alloc(): Alloc device resources.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return int * Return: Int.
*/ */
int qed_resc_alloc(struct qed_dev *cdev); int qed_resc_alloc(struct qed_dev *cdev);
/** /**
* @brief qed_resc_setup - * qed_resc_setup(): Setup device resources.
* *
* @param cdev * @cdev: Qed dev pointer.
*
* Return: Void.
*/ */
void qed_resc_setup(struct qed_dev *cdev); void qed_resc_setup(struct qed_dev *cdev);
@@ -105,94 +113,113 @@ struct qed_hw_init_params {
}; };
/** /**
* @brief qed_hw_init - * qed_hw_init(): Init Qed hardware.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param p_params * @p_params: Pointers to params.
* *
* @return int * Return: Int.
*/ */
int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params); int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params);
/** /**
* @brief qed_hw_timers_stop_all - stop the timers HW block * qed_hw_timers_stop_all(): Stop the timers HW block.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return void * Return: void.
*/ */
void qed_hw_timers_stop_all(struct qed_dev *cdev); void qed_hw_timers_stop_all(struct qed_dev *cdev);
/** /**
* @brief qed_hw_stop - * qed_hw_stop(): Stop Qed hardware.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return int * Return: int.
*/ */
int qed_hw_stop(struct qed_dev *cdev); int qed_hw_stop(struct qed_dev *cdev);
/** /**
* @brief qed_hw_stop_fastpath -should be called incase * qed_hw_stop_fastpath(): Should be called incase
* slowpath is still required for the device, * slowpath is still required for the device,
* but fastpath is not. * but fastpath is not.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return int * Return: Int.
*/ */
int qed_hw_stop_fastpath(struct qed_dev *cdev); int qed_hw_stop_fastpath(struct qed_dev *cdev);
/** /**
* @brief qed_hw_start_fastpath -restart fastpath traffic, * qed_hw_start_fastpath(): Restart fastpath traffic,
* only if hw_stop_fastpath was called * only if hw_stop_fastpath was called.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_hw_start_fastpath(struct qed_hwfn *p_hwfn); int qed_hw_start_fastpath(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_hw_prepare - * qed_hw_prepare(): Prepare Qed hardware.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param personality - personality to initialize * @personality: Personality to initialize.
* *
* @return int * Return: Int.
*/ */
int qed_hw_prepare(struct qed_dev *cdev, int qed_hw_prepare(struct qed_dev *cdev,
int personality); int personality);
/** /**
* @brief qed_hw_remove - * qed_hw_remove(): Remove Qed hardware.
* *
* @param cdev * @cdev: Qed dev pointer.
*
* Return: Void.
*/ */
void qed_hw_remove(struct qed_dev *cdev); void qed_hw_remove(struct qed_dev *cdev);
/** /**
* @brief qed_ptt_acquire - Allocate a PTT window * qed_ptt_acquire(): Allocate a PTT window.
*
* @p_hwfn: HW device data.
*
* Return: struct qed_ptt.
* *
* Should be called at the entry point to the driver (at the beginning of an * Should be called at the entry point to the driver (at the beginning of an
* exported function) * exported function).
*
* @param p_hwfn
*
* @return struct qed_ptt
*/ */
struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn); struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_ptt_release - Release PTT Window * qed_ptt_acquire_context(): Allocate a PTT window honoring the context
* atomicy.
*
* @p_hwfn: HW device data.
* @is_atomic: Hint from the caller - if the func can sleep or not.
*
* Context: The function should not sleep in case is_atomic == true.
* Return: struct qed_ptt.
*
* Should be called at the entry point to the driver
* (at the beginning of an exported function).
*/
struct qed_ptt *qed_ptt_acquire_context(struct qed_hwfn *p_hwfn,
bool is_atomic);
/**
* qed_ptt_release(): Release PTT Window.
*
* @p_hwfn: HW device data.
* @p_ptt: P_ptt.
*
* Return: Void.
* *
* Should be called at the end of a flow - at the end of the function that * Should be called at the end of a flow - at the end of the function that
* acquired the PTT. * acquired the PTT.
*
*
* @param p_hwfn
* @param p_ptt
*/ */
void qed_ptt_release(struct qed_hwfn *p_hwfn, void qed_ptt_release(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt); struct qed_ptt *p_ptt);
@@ -205,15 +232,17 @@ enum qed_dmae_address_type_t {
}; };
/** /**
* @brief qed_dmae_host2grc - copy data from source addr to * qed_dmae_host2grc(): Copy data from source addr to
* dmae registers using the given ptt * dmae registers using the given ptt.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param source_addr * @source_addr: Source address.
* @param grc_addr (dmae_data_offset) * @grc_addr: GRC address (dmae_data_offset).
* @param size_in_dwords * @size_in_dwords: Size.
* @param p_params (default parameters will be used in case of NULL) * @p_params: (default parameters will be used in case of NULL).
*
* Return: Int.
*/ */
int int
qed_dmae_host2grc(struct qed_hwfn *p_hwfn, qed_dmae_host2grc(struct qed_hwfn *p_hwfn,
@@ -224,29 +253,34 @@ qed_dmae_host2grc(struct qed_hwfn *p_hwfn,
struct qed_dmae_params *p_params); struct qed_dmae_params *p_params);
/** /**
* @brief qed_dmae_grc2host - Read data from dmae data offset * qed_dmae_grc2host(): Read data from dmae data offset
* to source address using the given ptt * to source address using the given ptt.
* *
* @param p_ptt * @p_ptt: P_ptt.
* @param grc_addr (dmae_data_offset) * @grc_addr: GRC address (dmae_data_offset).
* @param dest_addr * @dest_addr: Destination Address.
* @param size_in_dwords * @size_in_dwords: Size.
* @param p_params (default parameters will be used in case of NULL) * @p_params: (default parameters will be used in case of NULL).
*
* Return: Int.
*/ */
int qed_dmae_grc2host(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, int qed_dmae_grc2host(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
u32 grc_addr, dma_addr_t dest_addr, u32 size_in_dwords, u32 grc_addr, dma_addr_t dest_addr, u32 size_in_dwords,
struct qed_dmae_params *p_params); struct qed_dmae_params *p_params);
/** /**
* @brief qed_dmae_host2host - copy data from to source address * qed_dmae_host2host(): Copy data from to source address
* to a destination adress (for SRIOV) using the given ptt * to a destination adrress (for SRIOV) using the given
* ptt.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param source_addr * @source_addr: Source address.
* @param dest_addr * @dest_addr: Destination address.
* @param size_in_dwords * @size_in_dwords: size.
* @param p_params (default parameters will be used in case of NULL) * @p_params: (default parameters will be used in case of NULL).
*
* Return: Int.
*/ */
int qed_dmae_host2host(struct qed_hwfn *p_hwfn, int qed_dmae_host2host(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
@@ -259,51 +293,51 @@ int qed_chain_alloc(struct qed_dev *cdev, struct qed_chain *chain,
void qed_chain_free(struct qed_dev *cdev, struct qed_chain *chain); void qed_chain_free(struct qed_dev *cdev, struct qed_chain *chain);
/** /**
* @@brief qed_fw_l2_queue - Get absolute L2 queue ID * qed_fw_l2_queue(): Get absolute L2 queue ID.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param src_id - relative to p_hwfn * @src_id: Relative to p_hwfn.
* @param dst_id - absolute per engine * @dst_id: Absolute per engine.
* *
* @return int * Return: Int.
*/ */
int qed_fw_l2_queue(struct qed_hwfn *p_hwfn, int qed_fw_l2_queue(struct qed_hwfn *p_hwfn,
u16 src_id, u16 src_id,
u16 *dst_id); u16 *dst_id);
/** /**
* @@brief qed_fw_vport - Get absolute vport ID * qed_fw_vport(): Get absolute vport ID.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param src_id - relative to p_hwfn * @src_id: Relative to p_hwfn.
* @param dst_id - absolute per engine * @dst_id: Absolute per engine.
* *
* @return int * Return: Int.
*/ */
int qed_fw_vport(struct qed_hwfn *p_hwfn, int qed_fw_vport(struct qed_hwfn *p_hwfn,
u8 src_id, u8 src_id,
u8 *dst_id); u8 *dst_id);
/** /**
* @@brief qed_fw_rss_eng - Get absolute RSS engine ID * qed_fw_rss_eng(): Get absolute RSS engine ID.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param src_id - relative to p_hwfn * @src_id: Relative to p_hwfn.
* @param dst_id - absolute per engine * @dst_id: Absolute per engine.
* *
* @return int * Return: Int.
*/ */
int qed_fw_rss_eng(struct qed_hwfn *p_hwfn, int qed_fw_rss_eng(struct qed_hwfn *p_hwfn,
u8 src_id, u8 src_id,
u8 *dst_id); u8 *dst_id);
/** /**
* @brief qed_llh_get_num_ppfid - Return the allocated number of LLH filter * qed_llh_get_num_ppfid(): Return the allocated number of LLH filter
* banks that are allocated to the PF. * banks that are allocated to the PF.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return u8 - Number of LLH filter banks * Return: u8 Number of LLH filter banks.
*/ */
u8 qed_llh_get_num_ppfid(struct qed_dev *cdev); u8 qed_llh_get_num_ppfid(struct qed_dev *cdev);
@@ -314,45 +348,50 @@ enum qed_eng {
}; };
/** /**
* @brief qed_llh_set_ppfid_affinity - Set the engine affinity for the given * qed_llh_set_ppfid_affinity(): Set the engine affinity for the given
* LLH filter bank. * LLH filter bank.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param ppfid - relative within the allocated ppfids ('0' is the default one). * @ppfid: Relative within the allocated ppfids ('0' is the default one).
* @param eng * @eng: Engine.
* *
* @return int * Return: Int.
*/ */
int qed_llh_set_ppfid_affinity(struct qed_dev *cdev, int qed_llh_set_ppfid_affinity(struct qed_dev *cdev,
u8 ppfid, enum qed_eng eng); u8 ppfid, enum qed_eng eng);
/** /**
* @brief qed_llh_set_roce_affinity - Set the RoCE engine affinity * qed_llh_set_roce_affinity(): Set the RoCE engine affinity.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param eng * @eng: Engine.
* *
* @return int * Return: Int.
*/ */
int qed_llh_set_roce_affinity(struct qed_dev *cdev, enum qed_eng eng); int qed_llh_set_roce_affinity(struct qed_dev *cdev, enum qed_eng eng);
/** /**
* @brief qed_llh_add_mac_filter - Add a LLH MAC filter into the given filter * qed_llh_add_mac_filter(): Add a LLH MAC filter into the given filter
* bank. * bank.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param ppfid - relative within the allocated ppfids ('0' is the default one). * @ppfid: Relative within the allocated ppfids ('0' is the default one).
* @param mac_addr - MAC to add * @mac_addr: MAC to add.
*
* Return: Int.
*/ */
int qed_llh_add_mac_filter(struct qed_dev *cdev, int qed_llh_add_mac_filter(struct qed_dev *cdev,
u8 ppfid, u8 mac_addr[ETH_ALEN]); u8 ppfid, u8 mac_addr[ETH_ALEN]);
/** /**
* @brief qed_llh_remove_mac_filter - Remove a LLH MAC filter from the given * qed_llh_remove_mac_filter(): Remove a LLH MAC filter from the given
* filter bank. * filter bank.
* *
* @param p_ptt * @cdev: Qed dev pointer.
* @param p_filter - MAC to remove * @ppfid: Ppfid.
* @mac_addr: MAC to remove
*
* Return: Void.
*/ */
void qed_llh_remove_mac_filter(struct qed_dev *cdev, void qed_llh_remove_mac_filter(struct qed_dev *cdev,
u8 ppfid, u8 mac_addr[ETH_ALEN]); u8 ppfid, u8 mac_addr[ETH_ALEN]);
@@ -368,15 +407,16 @@ enum qed_llh_prot_filter_type_t {
}; };
/** /**
* @brief qed_llh_add_protocol_filter - Add a LLH protocol filter into the * qed_llh_add_protocol_filter(): Add a LLH protocol filter into the
* given filter bank. * given filter bank.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param ppfid - relative within the allocated ppfids ('0' is the default one). * @ppfid: Relative within the allocated ppfids ('0' is the default one).
* @param type - type of filters and comparing * @type: Type of filters and comparing.
* @param source_port_or_eth_type - source port or ethertype to add * @source_port_or_eth_type: Source port or ethertype to add.
* @param dest_port - destination port to add * @dest_port: Destination port to add.
* @param type - type of filters and comparing *
* Return: Int.
*/ */
int int
qed_llh_add_protocol_filter(struct qed_dev *cdev, qed_llh_add_protocol_filter(struct qed_dev *cdev,
@@ -385,14 +425,14 @@ qed_llh_add_protocol_filter(struct qed_dev *cdev,
u16 source_port_or_eth_type, u16 dest_port); u16 source_port_or_eth_type, u16 dest_port);
/** /**
* @brief qed_llh_remove_protocol_filter - Remove a LLH protocol filter from * qed_llh_remove_protocol_filter(): Remove a LLH protocol filter from
* the given filter bank. * the given filter bank.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param ppfid - relative within the allocated ppfids ('0' is the default one). * @ppfid: Relative within the allocated ppfids ('0' is the default one).
* @param type - type of filters and comparing * @type: Type of filters and comparing.
* @param source_port_or_eth_type - source port or ethertype to add * @source_port_or_eth_type: Source port or ethertype to add.
* @param dest_port - destination port to add * @dest_port: Destination port to add.
*/ */
void void
qed_llh_remove_protocol_filter(struct qed_dev *cdev, qed_llh_remove_protocol_filter(struct qed_dev *cdev,
@@ -401,31 +441,31 @@ qed_llh_remove_protocol_filter(struct qed_dev *cdev,
u16 source_port_or_eth_type, u16 dest_port); u16 source_port_or_eth_type, u16 dest_port);
/** /**
* *@brief Cleanup of previous driver remains prior to load * qed_final_cleanup(): Cleanup of previous driver remains prior to load.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param id - For PF, engine-relative. For VF, PF-relative. * @id: For PF, engine-relative. For VF, PF-relative.
* @param is_vf - true iff cleanup is made for a VF. * @is_vf: True iff cleanup is made for a VF.
* *
* @return int * Return: Int.
*/ */
int qed_final_cleanup(struct qed_hwfn *p_hwfn, int qed_final_cleanup(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u16 id, bool is_vf); struct qed_ptt *p_ptt, u16 id, bool is_vf);
/** /**
* @brief qed_get_queue_coalesce - Retrieve coalesce value for a given queue. * qed_get_queue_coalesce(): Retrieve coalesce value for a given queue.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_coal - store coalesce value read from the hardware. * @coal: Store coalesce value read from the hardware.
* @param p_handle * @handle: P_handle.
* *
* @return int * Return: Int.
**/ **/
int qed_get_queue_coalesce(struct qed_hwfn *p_hwfn, u16 *coal, void *handle); int qed_get_queue_coalesce(struct qed_hwfn *p_hwfn, u16 *coal, void *handle);
/** /**
* @brief qed_set_queue_coalesce - Configure coalesce parameters for Rx and * qed_set_queue_coalesce(): Configure coalesce parameters for Rx and
* Tx queue. The fact that we can configure coalescing to up to 511, but on * Tx queue. The fact that we can configure coalescing to up to 511, but on
* varying accuracy [the bigger the value the less accurate] up to a mistake * varying accuracy [the bigger the value the less accurate] up to a mistake
* of 3usec for the highest values. * of 3usec for the highest values.
@@ -433,37 +473,38 @@ int qed_get_queue_coalesce(struct qed_hwfn *p_hwfn, u16 *coal, void *handle);
* should be in same range [i.e., either 0-0x7f, 0x80-0xff or 0x100-0x1ff] * should be in same range [i.e., either 0-0x7f, 0x80-0xff or 0x100-0x1ff]
* otherwise configuration would break. * otherwise configuration would break.
* *
* @rx_coal: Rx Coalesce value in micro seconds.
* @tx_coal: TX Coalesce value in micro seconds.
* @p_handle: P_handle.
* *
* @param rx_coal - Rx Coalesce value in micro seconds. * Return: Int.
* @param tx_coal - TX Coalesce value in micro seconds.
* @param p_handle
*
* @return int
**/ **/
int int
qed_set_queue_coalesce(u16 rx_coal, u16 tx_coal, void *p_handle); qed_set_queue_coalesce(u16 rx_coal, u16 tx_coal, void *p_handle);
/** /**
* @brief qed_pglueb_set_pfid_enable - Enable or disable PCI BUS MASTER * qed_pglueb_set_pfid_enable(): Enable or disable PCI BUS MASTER.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param b_enable - true/false * @b_enable: True/False.
* *
* @return int * Return: Int.
*/ */
int qed_pglueb_set_pfid_enable(struct qed_hwfn *p_hwfn, int qed_pglueb_set_pfid_enable(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, bool b_enable); struct qed_ptt *p_ptt, bool b_enable);
/** /**
* @brief db_recovery_add - add doorbell information to the doorbell * qed_db_recovery_add(): add doorbell information to the doorbell
* recovery mechanism. * recovery mechanism.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param db_addr - doorbell address * @db_addr: Doorbell address.
* @param db_data - address of where db_data is stored * @db_data: Address of where db_data is stored.
* @param db_width - doorbell is 32b pr 64b * @db_width: Doorbell is 32b pr 64b.
* @param db_space - doorbell recovery addresses are user or kernel space * @db_space: Doorbell recovery addresses are user or kernel space.
*
* Return: Int.
*/ */
int qed_db_recovery_add(struct qed_dev *cdev, int qed_db_recovery_add(struct qed_dev *cdev,
void __iomem *db_addr, void __iomem *db_addr,
@@ -472,13 +513,15 @@ int qed_db_recovery_add(struct qed_dev *cdev,
enum qed_db_rec_space db_space); enum qed_db_rec_space db_space);
/** /**
* @brief db_recovery_del - remove doorbell information from the doorbell * qed_db_recovery_del() - remove doorbell information from the doorbell
* recovery mechanism. db_data serves as key (db_addr is not unique). * recovery mechanism. db_data serves as key (db_addr is not unique).
* *
* @param cdev * @cdev: Qed dev pointer.
* @param db_addr - doorbell address * @db_addr: doorbell address.
* @param db_data - address where db_data is stored. Serves as key for the * @db_data: address where db_data is stored. Serves as key for the
* entry to delete. * entry to delete.
*
* Return: Int.
*/ */
int qed_db_recovery_del(struct qed_dev *cdev, int qed_db_recovery_del(struct qed_dev *cdev,
void __iomem *db_addr, void *db_data); void __iomem *db_addr, void *db_data);

View File

@@ -694,13 +694,14 @@ static void _qed_fcoe_get_pstats(struct qed_hwfn *p_hwfn,
} }
static int qed_fcoe_get_stats(struct qed_hwfn *p_hwfn, static int qed_fcoe_get_stats(struct qed_hwfn *p_hwfn,
struct qed_fcoe_stats *p_stats) struct qed_fcoe_stats *p_stats,
bool is_atomic)
{ {
struct qed_ptt *p_ptt; struct qed_ptt *p_ptt;
memset(p_stats, 0, sizeof(*p_stats)); memset(p_stats, 0, sizeof(*p_stats));
p_ptt = qed_ptt_acquire(p_hwfn); p_ptt = qed_ptt_acquire_context(p_hwfn, is_atomic);
if (!p_ptt) { if (!p_ptt) {
DP_ERR(p_hwfn, "Failed to acquire ptt\n"); DP_ERR(p_hwfn, "Failed to acquire ptt\n");
@@ -974,19 +975,27 @@ static int qed_fcoe_destroy_conn(struct qed_dev *cdev,
QED_SPQ_MODE_EBLOCK, NULL); QED_SPQ_MODE_EBLOCK, NULL);
} }
static int qed_fcoe_stats_context(struct qed_dev *cdev,
struct qed_fcoe_stats *stats,
bool is_atomic)
{
return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats, is_atomic);
}
static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats) static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats)
{ {
return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats); return qed_fcoe_stats_context(cdev, stats, false);
} }
void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
struct qed_mcp_fcoe_stats *stats) struct qed_mcp_fcoe_stats *stats,
bool is_atomic)
{ {
struct qed_fcoe_stats proto_stats; struct qed_fcoe_stats proto_stats;
/* Retrieve FW statistics */ /* Retrieve FW statistics */
memset(&proto_stats, 0, sizeof(proto_stats)); memset(&proto_stats, 0, sizeof(proto_stats));
if (qed_fcoe_stats(cdev, &proto_stats)) { if (qed_fcoe_stats_context(cdev, &proto_stats, is_atomic)) {
DP_VERBOSE(cdev, QED_MSG_STORAGE, DP_VERBOSE(cdev, QED_MSG_STORAGE,
"Failed to collect FCoE statistics\n"); "Failed to collect FCoE statistics\n");
return; return;

View File

@@ -28,8 +28,20 @@ int qed_fcoe_alloc(struct qed_hwfn *p_hwfn);
void qed_fcoe_setup(struct qed_hwfn *p_hwfn); void qed_fcoe_setup(struct qed_hwfn *p_hwfn);
void qed_fcoe_free(struct qed_hwfn *p_hwfn); void qed_fcoe_free(struct qed_hwfn *p_hwfn);
/**
* qed_get_protocol_stats_fcoe(): Fills provided statistics
* struct with statistics.
*
* @cdev: Qed dev pointer.
* @stats: Points to struct that will be filled with statistics.
* @is_atomic: Hint from the caller - if the func can sleep or not.
*
* Context: The function should not sleep in case is_atomic == true.
* Return: Void.
*/
void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
struct qed_mcp_fcoe_stats *stats); struct qed_mcp_fcoe_stats *stats,
bool is_atomic);
#else /* CONFIG_QED_FCOE */ #else /* CONFIG_QED_FCOE */
static inline int qed_fcoe_alloc(struct qed_hwfn *p_hwfn) static inline int qed_fcoe_alloc(struct qed_hwfn *p_hwfn)
{ {
@@ -40,7 +52,8 @@ static inline void qed_fcoe_setup(struct qed_hwfn *p_hwfn) {}
static inline void qed_fcoe_free(struct qed_hwfn *p_hwfn) {} static inline void qed_fcoe_free(struct qed_hwfn *p_hwfn) {}
static inline void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, static inline void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
struct qed_mcp_fcoe_stats *stats) struct qed_mcp_fcoe_stats *stats,
bool is_atomic)
{ {
} }
#endif /* CONFIG_QED_FCOE */ #endif /* CONFIG_QED_FCOE */

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,10 @@
#include "qed_reg_addr.h" #include "qed_reg_addr.h"
#include "qed_sriov.h" #include "qed_sriov.h"
#define QED_BAR_ACQUIRE_TIMEOUT 1000 #define QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT 1000
#define QED_BAR_ACQUIRE_TIMEOUT_USLEEP 1000
#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT 100000
#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY 10
/* Invalid values */ /* Invalid values */
#define QED_BAR_INVALID_OFFSET (cpu_to_le32(-1)) #define QED_BAR_INVALID_OFFSET (cpu_to_le32(-1))
@@ -84,12 +87,22 @@ void qed_ptt_pool_free(struct qed_hwfn *p_hwfn)
} }
struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn) struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn)
{
return qed_ptt_acquire_context(p_hwfn, false);
}
struct qed_ptt *qed_ptt_acquire_context(struct qed_hwfn *p_hwfn, bool is_atomic)
{ {
struct qed_ptt *p_ptt; struct qed_ptt *p_ptt;
unsigned int i; unsigned int i, count;
if (is_atomic)
count = QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT;
else
count = QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT;
/* Take the free PTT from the list */ /* Take the free PTT from the list */
for (i = 0; i < QED_BAR_ACQUIRE_TIMEOUT; i++) { for (i = 0; i < count; i++) {
spin_lock_bh(&p_hwfn->p_ptt_pool->lock); spin_lock_bh(&p_hwfn->p_ptt_pool->lock);
if (!list_empty(&p_hwfn->p_ptt_pool->free_list)) { if (!list_empty(&p_hwfn->p_ptt_pool->free_list)) {
@@ -105,7 +118,12 @@ struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn)
} }
spin_unlock_bh(&p_hwfn->p_ptt_pool->lock); spin_unlock_bh(&p_hwfn->p_ptt_pool->lock);
usleep_range(1000, 2000);
if (is_atomic)
udelay(QED_BAR_ACQUIRE_TIMEOUT_UDELAY);
else
usleep_range(QED_BAR_ACQUIRE_TIMEOUT_USLEEP,
QED_BAR_ACQUIRE_TIMEOUT_USLEEP * 2);
} }
DP_NOTICE(p_hwfn, "PTT acquire timeout - failed to allocate PTT\n"); DP_NOTICE(p_hwfn, "PTT acquire timeout - failed to allocate PTT\n");

View File

@@ -53,85 +53,94 @@ enum _dmae_cmd_crc_mask {
#define DMAE_MAX_CLIENTS 32 #define DMAE_MAX_CLIENTS 32
/** /**
* @brief qed_gtt_init - Initialize GTT windows * qed_gtt_init(): Initialize GTT windows.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_gtt_init(struct qed_hwfn *p_hwfn); void qed_gtt_init(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_ptt_invalidate - Forces all ptt entries to be re-configured * qed_ptt_invalidate(): Forces all ptt entries to be re-configured
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_ptt_invalidate(struct qed_hwfn *p_hwfn); void qed_ptt_invalidate(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_ptt_pool_alloc - Allocate and initialize PTT pool * qed_ptt_pool_alloc(): Allocate and initialize PTT pool.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return struct _qed_status - success (0), negative - error. * Return: struct _qed_status - success (0), negative - error.
*/ */
int qed_ptt_pool_alloc(struct qed_hwfn *p_hwfn); int qed_ptt_pool_alloc(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_ptt_pool_free - * qed_ptt_pool_free(): Free PTT pool.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_ptt_pool_free(struct qed_hwfn *p_hwfn); void qed_ptt_pool_free(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_ptt_get_hw_addr - Get PTT's GRC/HW address * qed_ptt_get_hw_addr(): Get PTT's GRC/HW address.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt
* *
* @return u32 * Return: u32.
*/ */
u32 qed_ptt_get_hw_addr(struct qed_hwfn *p_hwfn, u32 qed_ptt_get_hw_addr(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt); struct qed_ptt *p_ptt);
/** /**
* @brief qed_ptt_get_bar_addr - Get PPT's external BAR address * qed_ptt_get_bar_addr(): Get PPT's external BAR address.
* *
* @param p_hwfn * @p_ptt: P_ptt
* @param p_ptt
* *
* @return u32 * Return: u32.
*/ */
u32 qed_ptt_get_bar_addr(struct qed_ptt *p_ptt); u32 qed_ptt_get_bar_addr(struct qed_ptt *p_ptt);
/** /**
* @brief qed_ptt_set_win - Set PTT Window's GRC BAR address * qed_ptt_set_win(): Set PTT Window's GRC BAR address
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param new_hw_addr * @new_hw_addr: New HW address.
* @param p_ptt * @p_ptt: P_Ptt
*
* Return: Void.
*/ */
void qed_ptt_set_win(struct qed_hwfn *p_hwfn, void qed_ptt_set_win(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
u32 new_hw_addr); u32 new_hw_addr);
/** /**
* @brief qed_get_reserved_ptt - Get a specific reserved PTT * qed_get_reserved_ptt(): Get a specific reserved PTT.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param ptt_idx * @ptt_idx: Ptt Index.
* *
* @return struct qed_ptt * * Return: struct qed_ptt *.
*/ */
struct qed_ptt *qed_get_reserved_ptt(struct qed_hwfn *p_hwfn, struct qed_ptt *qed_get_reserved_ptt(struct qed_hwfn *p_hwfn,
enum reserved_ptts ptt_idx); enum reserved_ptts ptt_idx);
/** /**
* @brief qed_wr - Write value to BAR using the given ptt * qed_wr(): Write value to BAR using the given ptt.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param val * @val: Val.
* @param hw_addr * @hw_addr: HW address
*
* Return: Void.
*/ */
void qed_wr(struct qed_hwfn *p_hwfn, void qed_wr(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
@@ -139,26 +148,28 @@ void qed_wr(struct qed_hwfn *p_hwfn,
u32 val); u32 val);
/** /**
* @brief qed_rd - Read value from BAR using the given ptt * qed_rd(): Read value from BAR using the given ptt.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param val * @hw_addr: HW address
* @param hw_addr *
* Return: Void.
*/ */
u32 qed_rd(struct qed_hwfn *p_hwfn, u32 qed_rd(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
u32 hw_addr); u32 hw_addr);
/** /**
* @brief qed_memcpy_from - copy n bytes from BAR using the given * qed_memcpy_from(): Copy n bytes from BAR using the given ptt.
* ptt
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param dest * @dest: Destination.
* @param hw_addr * @hw_addr: HW address.
* @param n * @n: N
*
* Return: Void.
*/ */
void qed_memcpy_from(struct qed_hwfn *p_hwfn, void qed_memcpy_from(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
@@ -167,14 +178,15 @@ void qed_memcpy_from(struct qed_hwfn *p_hwfn,
size_t n); size_t n);
/** /**
* @brief qed_memcpy_to - copy n bytes to BAR using the given * qed_memcpy_to(): Copy n bytes to BAR using the given ptt
* ptt
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param hw_addr * @hw_addr: HW address.
* @param src * @src: Source.
* @param n * @n: N
*
* Return: Void.
*/ */
void qed_memcpy_to(struct qed_hwfn *p_hwfn, void qed_memcpy_to(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
@@ -182,83 +194,97 @@ void qed_memcpy_to(struct qed_hwfn *p_hwfn,
void *src, void *src,
size_t n); size_t n);
/** /**
* @brief qed_fid_pretend - pretend to another function when * qed_fid_pretend(): pretend to another function when
* accessing the ptt window. There is no way to unpretend * accessing the ptt window. There is no way to unpretend
* a function. The only way to cancel a pretend is to * a function. The only way to cancel a pretend is to
* pretend back to the original function. * pretend back to the original function.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param fid - fid field of pxp_pretend structure. Can contain * @fid: fid field of pxp_pretend structure. Can contain
* either pf / vf, port/path fields are don't care. * either pf / vf, port/path fields are don't care.
*
* Return: Void.
*/ */
void qed_fid_pretend(struct qed_hwfn *p_hwfn, void qed_fid_pretend(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
u16 fid); u16 fid);
/** /**
* @brief qed_port_pretend - pretend to another port when * qed_port_pretend(): Pretend to another port when accessing the ptt window
* accessing the ptt window
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param port_id - the port to pretend to * @port_id: The port to pretend to
*
* Return: Void.
*/ */
void qed_port_pretend(struct qed_hwfn *p_hwfn, void qed_port_pretend(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
u8 port_id); u8 port_id);
/** /**
* @brief qed_port_unpretend - cancel any previously set port * qed_port_unpretend(): Cancel any previously set port pretend
* pretend
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
*
* Return: Void.
*/ */
void qed_port_unpretend(struct qed_hwfn *p_hwfn, void qed_port_unpretend(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt); struct qed_ptt *p_ptt);
/** /**
* @brief qed_port_fid_pretend - pretend to another port and another function * qed_port_fid_pretend(): Pretend to another port and another function
* when accessing the ptt window * when accessing the ptt window
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param port_id - the port to pretend to * @port_id: The port to pretend to
* @param fid - fid field of pxp_pretend structure. Can contain either pf / vf. * @fid: fid field of pxp_pretend structure. Can contain either pf / vf.
*
* Return: Void.
*/ */
void qed_port_fid_pretend(struct qed_hwfn *p_hwfn, void qed_port_fid_pretend(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u8 port_id, u16 fid); struct qed_ptt *p_ptt, u8 port_id, u16 fid);
/** /**
* @brief qed_vfid_to_concrete - build a concrete FID for a * qed_vfid_to_concrete(): Build a concrete FID for a given VF ID
* given VF ID
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @vfid: VFID.
* @param vfid *
* Return: Void.
*/ */
u32 qed_vfid_to_concrete(struct qed_hwfn *p_hwfn, u8 vfid); u32 qed_vfid_to_concrete(struct qed_hwfn *p_hwfn, u8 vfid);
/** /**
* @brief qed_dmae_idx_to_go_cmd - map the idx to dmae cmd * qed_dmae_idx_to_go_cmd(): Map the idx to dmae cmd
* this is declared here since other files will require it. * this is declared here since other files will require it.
* @param idx *
* @idx: Index
*
* Return: Void.
*/ */
u32 qed_dmae_idx_to_go_cmd(u8 idx); u32 qed_dmae_idx_to_go_cmd(u8 idx);
/** /**
* @brief qed_dmae_info_alloc - Init the dmae_info structure * qed_dmae_info_alloc(): Init the dmae_info structure
* which is part of p_hwfn. * which is part of p_hwfn.
* @param p_hwfn *
* @p_hwfn: HW device data.
*
* Return: Int.
*/ */
int qed_dmae_info_alloc(struct qed_hwfn *p_hwfn); int qed_dmae_info_alloc(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_dmae_info_free - Free the dmae_info structure * qed_dmae_info_free(): Free the dmae_info structure
* which is part of p_hwfn * which is part of p_hwfn.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_dmae_info_free(struct qed_hwfn *p_hwfn); void qed_dmae_info_free(struct qed_hwfn *p_hwfn);
@@ -292,14 +318,16 @@ int qed_dmae_sanity(struct qed_hwfn *p_hwfn,
#define QED_HW_ERR_MAX_STR_SIZE 256 #define QED_HW_ERR_MAX_STR_SIZE 256
/** /**
* @brief qed_hw_err_notify - Notify upper layer driver and management FW * qed_hw_err_notify(): Notify upper layer driver and management FW
* about a HW error. * about a HW error.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param err_type * @err_type: Err Type.
* @param fmt - debug data buffer to send to the MFW * @fmt: Debug data buffer to send to the MFW
* @param ... - buffer format args * @...: buffer format args
*
* Return void.
*/ */
void __printf(4, 5) __cold qed_hw_err_notify(struct qed_hwfn *p_hwfn, void __printf(4, 5) __cold qed_hw_err_notify(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,

View File

@@ -12,23 +12,24 @@
#include "qed.h" #include "qed.h"
/** /**
* @brief qed_init_iro_array - init iro_arr. * qed_init_iro_array(): init iro_arr.
* *
* @cdev: Qed dev pointer.
* *
* @param cdev * Return: Void.
*/ */
void qed_init_iro_array(struct qed_dev *cdev); void qed_init_iro_array(struct qed_dev *cdev);
/** /**
* @brief qed_init_run - Run the init-sequence. * qed_init_run(): Run the init-sequence.
* *
* @p_hwfn: HW device data.
* @p_ptt: P_ptt.
* @phase: Phase.
* @phase_id: Phase ID.
* @modes: Mode.
* *
* @param p_hwfn * Return: _qed_status_t
* @param p_ptt
* @param phase
* @param phase_id
* @param modes
* @return _qed_status_t
*/ */
int qed_init_run(struct qed_hwfn *p_hwfn, int qed_init_run(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
@@ -37,30 +38,31 @@ int qed_init_run(struct qed_hwfn *p_hwfn,
int modes); int modes);
/** /**
* @brief qed_init_hwfn_allocate - Allocate RT array, Store 'values' ptrs. * qed_init_alloc(): Allocate RT array, Store 'values' ptrs.
* *
* @p_hwfn: HW device data.
* *
* @param p_hwfn * Return: _qed_status_t.
*
* @return _qed_status_t
*/ */
int qed_init_alloc(struct qed_hwfn *p_hwfn); int qed_init_alloc(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_init_hwfn_deallocate * qed_init_free(): Init HW function deallocate.
* *
* @p_hwfn: HW device data.
* *
* @param p_hwfn * Return: Void.
*/ */
void qed_init_free(struct qed_hwfn *p_hwfn); void qed_init_free(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_init_store_rt_reg - Store a configuration value in the RT array. * qed_init_store_rt_reg(): Store a configuration value in the RT array.
* *
* @p_hwfn: HW device data.
* @rt_offset: RT offset.
* @val: Val.
* *
* @param p_hwfn * Return: Void.
* @param rt_offset
* @param val
*/ */
void qed_init_store_rt_reg(struct qed_hwfn *p_hwfn, void qed_init_store_rt_reg(struct qed_hwfn *p_hwfn,
u32 rt_offset, u32 rt_offset,
@@ -72,15 +74,6 @@ void qed_init_store_rt_reg(struct qed_hwfn *p_hwfn,
#define OVERWRITE_RT_REG(hwfn, offset, val) \ #define OVERWRITE_RT_REG(hwfn, offset, val) \
qed_init_store_rt_reg(hwfn, offset, val) qed_init_store_rt_reg(hwfn, offset, val)
/**
* @brief
*
*
* @param p_hwfn
* @param rt_offset
* @param val
* @param size
*/
void qed_init_store_rt_agg(struct qed_hwfn *p_hwfn, void qed_init_store_rt_agg(struct qed_hwfn *p_hwfn,
u32 rt_offset, u32 rt_offset,
u32 *val, u32 *val,
@@ -90,11 +83,12 @@ void qed_init_store_rt_agg(struct qed_hwfn *p_hwfn,
qed_init_store_rt_agg(hwfn, offset, (u32 *)&val, sizeof(val)) qed_init_store_rt_agg(hwfn, offset, (u32 *)&val, sizeof(val))
/** /**
* @brief * qed_gtt_init(): Initialize GTT global windows and set admin window
* Initialize GTT global windows and set admin window * related params of GTT/PTT to default values.
* related params of GTT/PTT to default values.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return Void.
*/ */
void qed_gtt_init(struct qed_hwfn *p_hwfn); void qed_gtt_init(struct qed_hwfn *p_hwfn);
#endif #endif

View File

@@ -53,51 +53,54 @@ enum qed_coalescing_fsm {
}; };
/** /**
* @brief qed_int_igu_enable_int - enable device interrupts * qed_int_igu_enable_int(): Enable device interrupts.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param int_mode - interrupt mode to use * @int_mode: Interrupt mode to use.
*
* Return: Void.
*/ */
void qed_int_igu_enable_int(struct qed_hwfn *p_hwfn, void qed_int_igu_enable_int(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
enum qed_int_mode int_mode); enum qed_int_mode int_mode);
/** /**
* @brief qed_int_igu_disable_int - disable device interrupts * qed_int_igu_disable_int(): Disable device interrupts.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
*
* Return: Void.
*/ */
void qed_int_igu_disable_int(struct qed_hwfn *p_hwfn, void qed_int_igu_disable_int(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt); struct qed_ptt *p_ptt);
/** /**
* @brief qed_int_igu_read_sisr_reg - Reads the single isr multiple dpc * qed_int_igu_read_sisr_reg(): Reads the single isr multiple dpc
* register from igu. * register from igu.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return u64 * Return: u64.
*/ */
u64 qed_int_igu_read_sisr_reg(struct qed_hwfn *p_hwfn); u64 qed_int_igu_read_sisr_reg(struct qed_hwfn *p_hwfn);
#define QED_SP_SB_ID 0xffff #define QED_SP_SB_ID 0xffff
/** /**
* @brief qed_int_sb_init - Initializes the sb_info structure. * qed_int_sb_init(): Initializes the sb_info structure.
* *
* once the structure is initialized it can be passed to sb related functions. * @p_hwfn: HW device data.
* @p_ptt: P_ptt.
* @sb_info: points to an uninitialized (but allocated) sb_info structure
* @sb_virt_addr: SB Virtual address.
* @sb_phy_addr: SB Physial address.
* @sb_id: the sb_id to be used (zero based in driver)
* should use QED_SP_SB_ID for SP Status block
* *
* @param p_hwfn * Return: int.
* @param p_ptt
* @param sb_info points to an uninitialized (but
* allocated) sb_info structure
* @param sb_virt_addr
* @param sb_phy_addr
* @param sb_id the sb_id to be used (zero based in driver)
* should use QED_SP_SB_ID for SP Status block
* *
* @return int * Once the structure is initialized it can be passed to sb related functions.
*/ */
int qed_int_sb_init(struct qed_hwfn *p_hwfn, int qed_int_sb_init(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
@@ -106,82 +109,91 @@ int qed_int_sb_init(struct qed_hwfn *p_hwfn,
dma_addr_t sb_phy_addr, dma_addr_t sb_phy_addr,
u16 sb_id); u16 sb_id);
/** /**
* @brief qed_int_sb_setup - Setup the sb. * qed_int_sb_setup(): Setup the sb.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param sb_info initialized sb_info structure * @sb_info: Initialized sb_info structure.
*
* Return: Void.
*/ */
void qed_int_sb_setup(struct qed_hwfn *p_hwfn, void qed_int_sb_setup(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
struct qed_sb_info *sb_info); struct qed_sb_info *sb_info);
/** /**
* @brief qed_int_sb_release - releases the sb_info structure. * qed_int_sb_release(): Releases the sb_info structure.
* *
* once the structure is released, it's memory can be freed * @p_hwfn: HW device data.
* @sb_info: Points to an allocated sb_info structure.
* @sb_id: The sb_id to be used (zero based in driver)
* should never be equal to QED_SP_SB_ID
* (SP Status block).
* *
* @param p_hwfn * Return: int.
* @param sb_info points to an allocated sb_info structure
* @param sb_id the sb_id to be used (zero based in driver)
* should never be equal to QED_SP_SB_ID
* (SP Status block)
* *
* @return int * Once the structure is released, it's memory can be freed.
*/ */
int qed_int_sb_release(struct qed_hwfn *p_hwfn, int qed_int_sb_release(struct qed_hwfn *p_hwfn,
struct qed_sb_info *sb_info, struct qed_sb_info *sb_info,
u16 sb_id); u16 sb_id);
/** /**
* @brief qed_int_sp_dpc - To be called when an interrupt is received on the * qed_int_sp_dpc(): To be called when an interrupt is received on the
* default status block. * default status block.
* *
* @param p_hwfn - pointer to hwfn * @t: Tasklet.
*
* Return: Void.
* *
*/ */
void qed_int_sp_dpc(struct tasklet_struct *t); void qed_int_sp_dpc(struct tasklet_struct *t);
/** /**
* @brief qed_int_get_num_sbs - get the number of status * qed_int_get_num_sbs(): Get the number of status blocks configured
* blocks configured for this funciton in the igu. * for this funciton in the igu.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_sb_cnt_info * @p_sb_cnt_info: Pointer to SB count info.
* *
* @return int - number of status blocks configured * Return: Void.
*/ */
void qed_int_get_num_sbs(struct qed_hwfn *p_hwfn, void qed_int_get_num_sbs(struct qed_hwfn *p_hwfn,
struct qed_sb_cnt_info *p_sb_cnt_info); struct qed_sb_cnt_info *p_sb_cnt_info);
/** /**
* @brief qed_int_disable_post_isr_release - performs the cleanup post ISR * qed_int_disable_post_isr_release(): Performs the cleanup post ISR
* release. The API need to be called after releasing all slowpath IRQs * release. The API need to be called after releasing all slowpath IRQs
* of the device. * of the device.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* Return: Void.
*/ */
void qed_int_disable_post_isr_release(struct qed_dev *cdev); void qed_int_disable_post_isr_release(struct qed_dev *cdev);
/** /**
* @brief qed_int_attn_clr_enable - sets whether the general behavior is * qed_int_attn_clr_enable: Sets whether the general behavior is
* preventing attentions from being reasserted, or following the * preventing attentions from being reasserted, or following the
* attributes of the specific attention. * attributes of the specific attention.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param clr_enable * @clr_enable: Clear enable
*
* Return: Void.
* *
*/ */
void qed_int_attn_clr_enable(struct qed_dev *cdev, bool clr_enable); void qed_int_attn_clr_enable(struct qed_dev *cdev, bool clr_enable);
/** /**
* @brief - Doorbell Recovery handler. * qed_db_rec_handler(): Doorbell Recovery handler.
* Run doorbell recovery in case of PF overflow (and flush DORQ if * Run doorbell recovery in case of PF overflow (and flush DORQ if
* needed). * needed).
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
*
* Return: Int.
*/ */
int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
@@ -223,30 +235,34 @@ struct qed_igu_info {
}; };
/** /**
* @brief - Make sure the IGU CAM reflects the resources provided by MFW * qed_int_igu_reset_cam(): Make sure the IGU CAM reflects the resources
* provided by MFW.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
*
* Return: Void.
*/ */
int qed_int_igu_reset_cam(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); int qed_int_igu_reset_cam(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
/** /**
* @brief Translate the weakly-defined client sb-id into an IGU sb-id * qed_get_igu_sb_id(): Translate the weakly-defined client sb-id into
* an IGU sb-id
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param sb_id - user provided sb_id * @sb_id: user provided sb_id.
* *
* @return an index inside IGU CAM where the SB resides * Return: An index inside IGU CAM where the SB resides.
*/ */
u16 qed_get_igu_sb_id(struct qed_hwfn *p_hwfn, u16 sb_id); u16 qed_get_igu_sb_id(struct qed_hwfn *p_hwfn, u16 sb_id);
/** /**
* @brief return a pointer to an unused valid SB * qed_get_igu_free_sb(): Return a pointer to an unused valid SB
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param b_is_pf - true iff we want a SB belonging to a PF * @b_is_pf: True iff we want a SB belonging to a PF.
* *
* @return point to an igu_block, NULL if none is available * Return: Point to an igu_block, NULL if none is available.
*/ */
struct qed_igu_block *qed_get_igu_free_sb(struct qed_hwfn *p_hwfn, struct qed_igu_block *qed_get_igu_free_sb(struct qed_hwfn *p_hwfn,
bool b_is_pf); bool b_is_pf);
@@ -259,15 +275,15 @@ void qed_int_igu_init_pure_rt(struct qed_hwfn *p_hwfn,
void qed_int_igu_init_rt(struct qed_hwfn *p_hwfn); void qed_int_igu_init_rt(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_int_igu_read_cam - Reads the IGU CAM. * qed_int_igu_read_cam(): Reads the IGU CAM.
* This function needs to be called during hardware * This function needs to be called during hardware
* prepare. It reads the info from igu cam to know which * prepare. It reads the info from igu cam to know which
* status block is the default / base status block etc. * status block is the default / base status block etc.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* *
* @return int * Return: Int.
*/ */
int qed_int_igu_read_cam(struct qed_hwfn *p_hwfn, int qed_int_igu_read_cam(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt); struct qed_ptt *p_ptt);
@@ -275,24 +291,22 @@ int qed_int_igu_read_cam(struct qed_hwfn *p_hwfn,
typedef int (*qed_int_comp_cb_t)(struct qed_hwfn *p_hwfn, typedef int (*qed_int_comp_cb_t)(struct qed_hwfn *p_hwfn,
void *cookie); void *cookie);
/** /**
* @brief qed_int_register_cb - Register callback func for * qed_int_register_cb(): Register callback func for slowhwfn statusblock.
* slowhwfn statusblock.
* *
* Every protocol that uses the slowhwfn status block * @p_hwfn: HW device data.
* should register a callback function that will be called * @comp_cb: Function to be called when there is an
* once there is an update of the sp status block. * interrupt on the sp sb
* @cookie: Passed to the callback function
* @sb_idx: (OUT) parameter which gives the chosen index
* for this protocol.
* @p_fw_cons: Pointer to the actual address of the
* consumer for this protocol.
* *
* @param p_hwfn * Return: Int.
* @param comp_cb - function to be called when there is an
* interrupt on the sp sb
* *
* @param cookie - passed to the callback function * Every protocol that uses the slowhwfn status block
* @param sb_idx - OUT parameter which gives the chosen index * should register a callback function that will be called
* for this protocol. * once there is an update of the sp status block.
* @param p_fw_cons - pointer to the actual address of the
* consumer for this protocol.
*
* @return int
*/ */
int qed_int_register_cb(struct qed_hwfn *p_hwfn, int qed_int_register_cb(struct qed_hwfn *p_hwfn,
qed_int_comp_cb_t comp_cb, qed_int_comp_cb_t comp_cb,
@@ -301,37 +315,40 @@ int qed_int_register_cb(struct qed_hwfn *p_hwfn,
__le16 **p_fw_cons); __le16 **p_fw_cons);
/** /**
* @brief qed_int_unregister_cb - Unregisters callback * qed_int_unregister_cb(): Unregisters callback function from sp sb.
* function from sp sb.
* Partner of qed_int_register_cb -> should be called
* when no longer required.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param pi * @pi: Producer Index.
* *
* @return int * Return: Int.
*
* Partner of qed_int_register_cb -> should be called
* when no longer required.
*/ */
int qed_int_unregister_cb(struct qed_hwfn *p_hwfn, int qed_int_unregister_cb(struct qed_hwfn *p_hwfn,
u8 pi); u8 pi);
/** /**
* @brief qed_int_get_sp_sb_id - Get the slowhwfn sb id. * qed_int_get_sp_sb_id(): Get the slowhwfn sb id.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return u16 * Return: u16.
*/ */
u16 qed_int_get_sp_sb_id(struct qed_hwfn *p_hwfn); u16 qed_int_get_sp_sb_id(struct qed_hwfn *p_hwfn);
/** /**
* @brief Status block cleanup. Should be called for each status * qed_int_igu_init_pure_rt_single(): Status block cleanup.
* block that will be used -> both PF / VF * Should be called for each status
* block that will be used -> both PF / VF.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param igu_sb_id - igu status block id * @igu_sb_id: IGU status block id.
* @param opaque - opaque fid of the sb owner. * @opaque: Opaque fid of the sb owner.
* @param b_set - set(1) / clear(0) * @b_set: Set(1) / Clear(0).
*
* Return: Void.
*/ */
void qed_int_igu_init_pure_rt_single(struct qed_hwfn *p_hwfn, void qed_int_igu_init_pure_rt_single(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
@@ -340,15 +357,16 @@ void qed_int_igu_init_pure_rt_single(struct qed_hwfn *p_hwfn,
bool b_set); bool b_set);
/** /**
* @brief qed_int_cau_conf - configure cau for a given status * qed_int_cau_conf_sb(): Configure cau for a given status block.
* block
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param ptt * @p_ptt: P_ptt.
* @param sb_phys * @sb_phys: SB Physical.
* @param igu_sb_id * @igu_sb_id: IGU status block id.
* @param vf_number * @vf_number: VF number
* @param vf_valid * @vf_valid: VF valid or not.
*
* Return: Void.
*/ */
void qed_int_cau_conf_sb(struct qed_hwfn *p_hwfn, void qed_int_cau_conf_sb(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
@@ -358,52 +376,58 @@ void qed_int_cau_conf_sb(struct qed_hwfn *p_hwfn,
u8 vf_valid); u8 vf_valid);
/** /**
* @brief qed_int_alloc * qed_int_alloc(): QED interrupt alloc.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* *
* @return int * Return: Int.
*/ */
int qed_int_alloc(struct qed_hwfn *p_hwfn, int qed_int_alloc(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt); struct qed_ptt *p_ptt);
/** /**
* @brief qed_int_free * qed_int_free(): QED interrupt free.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_int_free(struct qed_hwfn *p_hwfn); void qed_int_free(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_int_setup * qed_int_setup(): QED interrupt setup.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
*
* Return: Void.
*/ */
void qed_int_setup(struct qed_hwfn *p_hwfn, void qed_int_setup(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt); struct qed_ptt *p_ptt);
/** /**
* @brief - Enable Interrupt & Attention for hw function * qed_int_igu_enable(): Enable Interrupt & Attention for hw function.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ptt * @p_ptt: P_ptt.
* @param int_mode * @int_mode: Interrut mode
* *
* @return int * Return: Int.
*/ */
int qed_int_igu_enable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, int qed_int_igu_enable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
enum qed_int_mode int_mode); enum qed_int_mode int_mode);
/** /**
* @brief - Initialize CAU status block entry * qed_init_cau_sb_entry(): Initialize CAU status block entry.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_sb_entry * @p_sb_entry: Pointer SB entry.
* @param pf_id * @pf_id: PF number
* @param vf_number * @vf_number: VF number
* @param vf_valid * @vf_valid: VF valid or not.
*
* Return: Void.
*/ */
void qed_init_cau_sb_entry(struct qed_hwfn *p_hwfn, void qed_init_cau_sb_entry(struct qed_hwfn *p_hwfn,
struct cau_sb_entry *p_sb_entry, struct cau_sb_entry *p_sb_entry,

View File

@@ -1000,13 +1000,14 @@ static void _qed_iscsi_get_pstats(struct qed_hwfn *p_hwfn,
} }
static int qed_iscsi_get_stats(struct qed_hwfn *p_hwfn, static int qed_iscsi_get_stats(struct qed_hwfn *p_hwfn,
struct qed_iscsi_stats *stats) struct qed_iscsi_stats *stats,
bool is_atomic)
{ {
struct qed_ptt *p_ptt; struct qed_ptt *p_ptt;
memset(stats, 0, sizeof(*stats)); memset(stats, 0, sizeof(*stats));
p_ptt = qed_ptt_acquire(p_hwfn); p_ptt = qed_ptt_acquire_context(p_hwfn, is_atomic);
if (!p_ptt) { if (!p_ptt) {
DP_ERR(p_hwfn, "Failed to acquire ptt\n"); DP_ERR(p_hwfn, "Failed to acquire ptt\n");
return -EAGAIN; return -EAGAIN;
@@ -1337,9 +1338,16 @@ static int qed_iscsi_destroy_conn(struct qed_dev *cdev,
QED_SPQ_MODE_EBLOCK, NULL); QED_SPQ_MODE_EBLOCK, NULL);
} }
static int qed_iscsi_stats_context(struct qed_dev *cdev,
struct qed_iscsi_stats *stats,
bool is_atomic)
{
return qed_iscsi_get_stats(QED_AFFIN_HWFN(cdev), stats, is_atomic);
}
static int qed_iscsi_stats(struct qed_dev *cdev, struct qed_iscsi_stats *stats) static int qed_iscsi_stats(struct qed_dev *cdev, struct qed_iscsi_stats *stats)
{ {
return qed_iscsi_get_stats(QED_AFFIN_HWFN(cdev), stats); return qed_iscsi_stats_context(cdev, stats, false);
} }
static int qed_iscsi_change_mac(struct qed_dev *cdev, static int qed_iscsi_change_mac(struct qed_dev *cdev,
@@ -1359,13 +1367,14 @@ static int qed_iscsi_change_mac(struct qed_dev *cdev,
} }
void qed_get_protocol_stats_iscsi(struct qed_dev *cdev, void qed_get_protocol_stats_iscsi(struct qed_dev *cdev,
struct qed_mcp_iscsi_stats *stats) struct qed_mcp_iscsi_stats *stats,
bool is_atomic)
{ {
struct qed_iscsi_stats proto_stats; struct qed_iscsi_stats proto_stats;
/* Retrieve FW statistics */ /* Retrieve FW statistics */
memset(&proto_stats, 0, sizeof(proto_stats)); memset(&proto_stats, 0, sizeof(proto_stats));
if (qed_iscsi_stats(cdev, &proto_stats)) { if (qed_iscsi_stats_context(cdev, &proto_stats, is_atomic)) {
DP_VERBOSE(cdev, QED_MSG_STORAGE, DP_VERBOSE(cdev, QED_MSG_STORAGE,
"Failed to collect ISCSI statistics\n"); "Failed to collect ISCSI statistics\n");
return; return;

View File

@@ -34,13 +34,19 @@ void qed_iscsi_setup(struct qed_hwfn *p_hwfn);
void qed_iscsi_free(struct qed_hwfn *p_hwfn); void qed_iscsi_free(struct qed_hwfn *p_hwfn);
/** /**
* @brief - Fills provided statistics struct with statistics. * qed_get_protocol_stats_iscsi(): Fills provided statistics
* struct with statistics.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param stats - points to struct that will be filled with statistics. * @stats: Points to struct that will be filled with statistics.
* @is_atomic: Hint from the caller - if the func can sleep or not.
*
* Context: The function should not sleep in case is_atomic == true.
* Return: Void.
*/ */
void qed_get_protocol_stats_iscsi(struct qed_dev *cdev, void qed_get_protocol_stats_iscsi(struct qed_dev *cdev,
struct qed_mcp_iscsi_stats *stats); struct qed_mcp_iscsi_stats *stats,
bool is_atomic);
#else /* IS_ENABLED(CONFIG_QED_ISCSI) */ #else /* IS_ENABLED(CONFIG_QED_ISCSI) */
static inline int qed_iscsi_alloc(struct qed_hwfn *p_hwfn) static inline int qed_iscsi_alloc(struct qed_hwfn *p_hwfn)
{ {
@@ -53,7 +59,8 @@ static inline void qed_iscsi_free(struct qed_hwfn *p_hwfn) {}
static inline void static inline void
qed_get_protocol_stats_iscsi(struct qed_dev *cdev, qed_get_protocol_stats_iscsi(struct qed_dev *cdev,
struct qed_mcp_iscsi_stats *stats) {} struct qed_mcp_iscsi_stats *stats,
bool is_atomic) {}
#endif /* IS_ENABLED(CONFIG_QED_ISCSI) */ #endif /* IS_ENABLED(CONFIG_QED_ISCSI) */
#endif #endif

View File

@@ -1863,7 +1863,8 @@ static void __qed_get_vport_stats(struct qed_hwfn *p_hwfn,
} }
static void _qed_get_vport_stats(struct qed_dev *cdev, static void _qed_get_vport_stats(struct qed_dev *cdev,
struct qed_eth_stats *stats) struct qed_eth_stats *stats,
bool is_atomic)
{ {
u8 fw_vport = 0; u8 fw_vport = 0;
int i; int i;
@@ -1872,10 +1873,11 @@ static void _qed_get_vport_stats(struct qed_dev *cdev,
for_each_hwfn(cdev, i) { for_each_hwfn(cdev, i) {
struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
struct qed_ptt *p_ptt = IS_PF(cdev) ? qed_ptt_acquire(p_hwfn) struct qed_ptt *p_ptt;
: NULL;
bool b_get_port_stats; bool b_get_port_stats;
p_ptt = IS_PF(cdev) ? qed_ptt_acquire_context(p_hwfn, is_atomic)
: NULL;
if (IS_PF(cdev)) { if (IS_PF(cdev)) {
/* The main vport index is relative first */ /* The main vport index is relative first */
if (qed_fw_vport(p_hwfn, 0, &fw_vport)) { if (qed_fw_vport(p_hwfn, 0, &fw_vport)) {
@@ -1900,6 +1902,13 @@ out:
} }
void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats) void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats)
{
qed_get_vport_stats_context(cdev, stats, false);
}
void qed_get_vport_stats_context(struct qed_dev *cdev,
struct qed_eth_stats *stats,
bool is_atomic)
{ {
u32 i; u32 i;
@@ -1908,7 +1917,7 @@ void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats)
return; return;
} }
_qed_get_vport_stats(cdev, stats); _qed_get_vport_stats(cdev, stats, is_atomic);
if (!cdev->reset_stats) if (!cdev->reset_stats)
return; return;
@@ -1960,7 +1969,7 @@ void qed_reset_vport_stats(struct qed_dev *cdev)
if (!cdev->reset_stats) { if (!cdev->reset_stats) {
DP_INFO(cdev, "Reset stats not allocated\n"); DP_INFO(cdev, "Reset stats not allocated\n");
} else { } else {
_qed_get_vport_stats(cdev, cdev->reset_stats); _qed_get_vport_stats(cdev, cdev->reset_stats, false);
cdev->reset_stats->common.link_change_count = 0; cdev->reset_stats->common.link_change_count = 0;
} }
} }

View File

@@ -92,18 +92,18 @@ struct qed_filter_mcast {
}; };
/** /**
* @brief qed_eth_rx_queue_stop - This ramrod closes an Rx queue * qed_eth_rx_queue_stop(): This ramrod closes an Rx queue.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_rxq Handler of queue to close * @p_rxq: Handler of queue to close
* @param eq_completion_only If True completion will be on * @eq_completion_only: If True completion will be on
* EQe, if False completion will be * EQe, if False completion will be
* on EQe if p_hwfn opaque * on EQe if p_hwfn opaque
* different from the RXQ opaque * different from the RXQ opaque
* otherwise on CQe. * otherwise on CQe.
* @param cqe_completion If True completion will be * @cqe_completion: If True completion will be receive on CQe.
* receive on CQe. *
* @return int * Return: Int.
*/ */
int int
qed_eth_rx_queue_stop(struct qed_hwfn *p_hwfn, qed_eth_rx_queue_stop(struct qed_hwfn *p_hwfn,
@@ -111,12 +111,12 @@ qed_eth_rx_queue_stop(struct qed_hwfn *p_hwfn,
bool eq_completion_only, bool cqe_completion); bool eq_completion_only, bool cqe_completion);
/** /**
* @brief qed_eth_tx_queue_stop - closes a Tx queue * qed_eth_tx_queue_stop(): Closes a Tx queue.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_txq - handle to Tx queue needed to be closed * @p_txq: handle to Tx queue needed to be closed.
* *
* @return int * Return: Int.
*/ */
int qed_eth_tx_queue_stop(struct qed_hwfn *p_hwfn, void *p_txq); int qed_eth_tx_queue_stop(struct qed_hwfn *p_hwfn, void *p_txq);
@@ -205,16 +205,15 @@ int qed_sp_vport_update(struct qed_hwfn *p_hwfn,
struct qed_spq_comp_cb *p_comp_data); struct qed_spq_comp_cb *p_comp_data);
/** /**
* @brief qed_sp_vport_stop - * qed_sp_vport_stop: This ramrod closes a VPort after all its
* RX and TX queues are terminated.
* An Assert is generated if any queues are left open.
* *
* This ramrod closes a VPort after all its RX and TX queues are terminated. * @p_hwfn: HW device data.
* An Assert is generated if any queues are left open. * @opaque_fid: Opaque FID
* @vport_id: VPort ID.
* *
* @param p_hwfn * Return: Int.
* @param opaque_fid
* @param vport_id VPort ID
*
* @return int
*/ */
int qed_sp_vport_stop(struct qed_hwfn *p_hwfn, u16 opaque_fid, u8 vport_id); int qed_sp_vport_stop(struct qed_hwfn *p_hwfn, u16 opaque_fid, u8 vport_id);
@@ -225,22 +224,21 @@ int qed_sp_eth_filter_ucast(struct qed_hwfn *p_hwfn,
struct qed_spq_comp_cb *p_comp_data); struct qed_spq_comp_cb *p_comp_data);
/** /**
* @brief qed_sp_rx_eth_queues_update - * qed_sp_eth_rx_queues_update(): This ramrod updates an RX queue.
* It is used for setting the active state
* of the queue and updating the TPA and
* SGE parameters.
* @p_hwfn: HW device data.
* @pp_rxq_handlers: An array of queue handlers to be updated.
* @num_rxqs: number of queues to update.
* @complete_cqe_flg: Post completion to the CQE Ring if set.
* @complete_event_flg: Post completion to the Event Ring if set.
* @comp_mode: Comp mode.
* @p_comp_data: Pointer Comp data.
* *
* This ramrod updates an RX queue. It is used for setting the active state * Return: Int.
* of the queue and updating the TPA and SGE parameters.
* *
* @note At the moment - only used by non-linux VFs. * Note At the moment - only used by non-linux VFs.
*
* @param p_hwfn
* @param pp_rxq_handlers An array of queue handlers to be updated.
* @param num_rxqs number of queues to update.
* @param complete_cqe_flg Post completion to the CQE Ring if set
* @param complete_event_flg Post completion to the Event Ring if set
* @param comp_mode
* @param p_comp_data
*
* @return int
*/ */
int int
@@ -252,35 +250,61 @@ qed_sp_eth_rx_queues_update(struct qed_hwfn *p_hwfn,
enum spq_mode comp_mode, enum spq_mode comp_mode,
struct qed_spq_comp_cb *p_comp_data); struct qed_spq_comp_cb *p_comp_data);
/**
* qed_get_vport_stats(): Fills provided statistics
* struct with statistics.
*
* @cdev: Qed dev pointer.
* @stats: Points to struct that will be filled with statistics.
*
* Return: Void.
*/
void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats); void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats);
/**
* qed_get_vport_stats_context(): Fills provided statistics
* struct with statistics.
*
* @cdev: Qed dev pointer.
* @stats: Points to struct that will be filled with statistics.
* @is_atomic: Hint from the caller - if the func can sleep or not.
*
* Context: The function should not sleep in case is_atomic == true.
* Return: Void.
*/
void qed_get_vport_stats_context(struct qed_dev *cdev,
struct qed_eth_stats *stats,
bool is_atomic);
void qed_reset_vport_stats(struct qed_dev *cdev); void qed_reset_vport_stats(struct qed_dev *cdev);
/** /**
* *@brief qed_arfs_mode_configure - * qed_arfs_mode_configure(): Enable or disable rfs mode.
* It must accept at least one of tcp or udp true
* and at least one of ipv4 or ipv6 true to enable
* rfs mode.
* *
**Enable or disable rfs mode. It must accept atleast one of tcp or udp true * @p_hwfn: HW device data.
**and atleast one of ipv4 or ipv6 true to enable rfs mode. * @p_ptt: P_ptt.
* * @p_cfg_params: arfs mode configuration parameters.
**@param p_hwfn
**@param p_ptt
**@param p_cfg_params - arfs mode configuration parameters.
* *
* Return. Void.
*/ */
void qed_arfs_mode_configure(struct qed_hwfn *p_hwfn, void qed_arfs_mode_configure(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, struct qed_ptt *p_ptt,
struct qed_arfs_config_params *p_cfg_params); struct qed_arfs_config_params *p_cfg_params);
/** /**
* @brief - qed_configure_rfs_ntuple_filter * qed_configure_rfs_ntuple_filter(): This ramrod should be used to add
* or remove arfs hw filter
* *
* This ramrod should be used to add or remove arfs hw filter * @p_hwfn: HW device data.
* @p_cb: Used for QED_SPQ_MODE_CB,where client would initialize
* it with cookie and callback function address, if not
* using this mode then client must pass NULL.
* @p_params: Pointer to params.
* *
* @params p_hwfn * Return: Void.
* @params p_cb - Used for QED_SPQ_MODE_CB,where client would initialize
* it with cookie and callback function address, if not
* using this mode then client must pass NULL.
* @params p_params
*/ */
int int
qed_configure_rfs_ntuple_filter(struct qed_hwfn *p_hwfn, qed_configure_rfs_ntuple_filter(struct qed_hwfn *p_hwfn,
@@ -374,16 +398,17 @@ qed_sp_eth_vport_start(struct qed_hwfn *p_hwfn,
struct qed_sp_vport_start_params *p_params); struct qed_sp_vport_start_params *p_params);
/** /**
* @brief - Starts an Rx queue, when queue_cid is already prepared * qed_eth_rxq_start_ramrod(): Starts an Rx queue, when queue_cid is
* already prepared
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_cid * @p_cid: Pointer CID.
* @param bd_max_bytes * @bd_max_bytes: Max bytes.
* @param bd_chain_phys_addr * @bd_chain_phys_addr: Chain physcial address.
* @param cqe_pbl_addr * @cqe_pbl_addr: PBL address.
* @param cqe_pbl_size * @cqe_pbl_size: PBL size.
* *
* @return int * Return: Int.
*/ */
int int
qed_eth_rxq_start_ramrod(struct qed_hwfn *p_hwfn, qed_eth_rxq_start_ramrod(struct qed_hwfn *p_hwfn,
@@ -393,15 +418,16 @@ qed_eth_rxq_start_ramrod(struct qed_hwfn *p_hwfn,
dma_addr_t cqe_pbl_addr, u16 cqe_pbl_size); dma_addr_t cqe_pbl_addr, u16 cqe_pbl_size);
/** /**
* @brief - Starts a Tx queue, where queue_cid is already prepared * qed_eth_txq_start_ramrod(): Starts a Tx queue, where queue_cid is
* already prepared
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_cid * @p_cid: Pointer CID.
* @param pbl_addr * @pbl_addr: PBL address.
* @param pbl_size * @pbl_size: PBL size.
* @param p_pq_params - parameters for choosing the PQ for this Tx queue * @pq_id: Parameters for choosing the PQ for this Tx queue.
* *
* @return int * Return: Int.
*/ */
int int
qed_eth_txq_start_ramrod(struct qed_hwfn *p_hwfn, qed_eth_txq_start_ramrod(struct qed_hwfn *p_hwfn,

View File

@@ -119,41 +119,41 @@ struct qed_ll2_info {
extern const struct qed_ll2_ops qed_ll2_ops_pass; extern const struct qed_ll2_ops qed_ll2_ops_pass;
/** /**
* @brief qed_ll2_acquire_connection - allocate resources, * qed_ll2_acquire_connection(): Allocate resources,
* starts rx & tx (if relevant) queues pair. Provides * starts rx & tx (if relevant) queues pair.
* connecion handler as output parameter. * Provides connecion handler as output
* parameter.
* *
* @cxt: Pointer to the hw-function [opaque to some].
* @data: Describes connection parameters.
* *
* @param cxt - pointer to the hw-function [opaque to some] * Return: Int.
* @param data - describes connection parameters
* @return int
*/ */
int qed_ll2_acquire_connection(void *cxt, struct qed_ll2_acquire_data *data); int qed_ll2_acquire_connection(void *cxt, struct qed_ll2_acquire_data *data);
/** /**
* @brief qed_ll2_establish_connection - start previously * qed_ll2_establish_connection(): start previously allocated LL2 queues pair
* allocated LL2 queues pair
* *
* @param cxt - pointer to the hw-function [opaque to some] * @cxt: Pointer to the hw-function [opaque to some].
* @param p_ptt * @connection_handle: LL2 connection's handle obtained from
* @param connection_handle LL2 connection's handle obtained from * qed_ll2_require_connection.
* qed_ll2_require_connection
* *
* @return 0 on success, failure otherwise * Return: 0 on success, failure otherwise.
*/ */
int qed_ll2_establish_connection(void *cxt, u8 connection_handle); int qed_ll2_establish_connection(void *cxt, u8 connection_handle);
/** /**
* @brief qed_ll2_post_rx_buffers - submit buffers to LL2 Rx queue. * qed_ll2_post_rx_buffer(): Submit buffers to LL2 Rx queue.
* *
* @param cxt - pointer to the hw-function [opaque to some] * @cxt: Pointer to the hw-function [opaque to some].
* @param connection_handle LL2 connection's handle obtained from * @connection_handle: LL2 connection's handle obtained from
* qed_ll2_require_connection * qed_ll2_require_connection.
* @param addr rx (physical address) buffers to submit * @addr: RX (physical address) buffers to submit.
* @param cookie * @buf_len: Buffer Len.
* @param notify_fw produce corresponding Rx BD immediately * @cookie: Cookie.
* @notify_fw: Produce corresponding Rx BD immediately.
* *
* @return 0 on success, failure otherwise * Return: 0 on success, failure otherwise.
*/ */
int qed_ll2_post_rx_buffer(void *cxt, int qed_ll2_post_rx_buffer(void *cxt,
u8 connection_handle, u8 connection_handle,
@@ -161,15 +161,15 @@ int qed_ll2_post_rx_buffer(void *cxt,
u16 buf_len, void *cookie, u8 notify_fw); u16 buf_len, void *cookie, u8 notify_fw);
/** /**
* @brief qed_ll2_prepare_tx_packet - request for start Tx BD * qed_ll2_prepare_tx_packet(): Request for start Tx BD
* to prepare Tx packet submission to FW. * to prepare Tx packet submission to FW.
* *
* @param cxt - pointer to the hw-function [opaque to some] * @cxt: Pointer to the hw-function [opaque to some].
* @param connection_handle * @connection_handle: Connection handle.
* @param pkt - info regarding the tx packet * @pkt: Info regarding the tx packet.
* @param notify_fw - issue doorbell to fw for this packet * @notify_fw: Issue doorbell to fw for this packet.
* *
* @return 0 on success, failure otherwise * Return: 0 on success, failure otherwise.
*/ */
int qed_ll2_prepare_tx_packet(void *cxt, int qed_ll2_prepare_tx_packet(void *cxt,
u8 connection_handle, u8 connection_handle,
@@ -177,81 +177,83 @@ int qed_ll2_prepare_tx_packet(void *cxt,
bool notify_fw); bool notify_fw);
/** /**
* @brief qed_ll2_release_connection - releases resources * qed_ll2_release_connection(): Releases resources allocated for LL2
* allocated for LL2 connection * connection.
* *
* @param cxt - pointer to the hw-function [opaque to some] * @cxt: Pointer to the hw-function [opaque to some].
* @param connection_handle LL2 connection's handle obtained from * @connection_handle: LL2 connection's handle obtained from
* qed_ll2_require_connection * qed_ll2_require_connection.
*
* Return: Void.
*/ */
void qed_ll2_release_connection(void *cxt, u8 connection_handle); void qed_ll2_release_connection(void *cxt, u8 connection_handle);
/** /**
* @brief qed_ll2_set_fragment_of_tx_packet - provides fragments to fill * qed_ll2_set_fragment_of_tx_packet(): Provides fragments to fill
* Tx BD of BDs requested by * Tx BD of BDs requested by
* qed_ll2_prepare_tx_packet * qed_ll2_prepare_tx_packet
* *
* @param cxt - pointer to the hw-function [opaque to some] * @cxt: Pointer to the hw-function [opaque to some].
* @param connection_handle LL2 connection's handle * @connection_handle: LL2 connection's handle obtained from
* obtained from * qed_ll2_require_connection.
* qed_ll2_require_connection * @addr: Address.
* @param addr * @nbytes: Number of bytes.
* @param nbytes
* *
* @return 0 on success, failure otherwise * Return: 0 on success, failure otherwise.
*/ */
int qed_ll2_set_fragment_of_tx_packet(void *cxt, int qed_ll2_set_fragment_of_tx_packet(void *cxt,
u8 connection_handle, u8 connection_handle,
dma_addr_t addr, u16 nbytes); dma_addr_t addr, u16 nbytes);
/** /**
* @brief qed_ll2_terminate_connection - stops Tx/Rx queues * qed_ll2_terminate_connection(): Stops Tx/Rx queues
* *
* @cxt: Pointer to the hw-function [opaque to some].
* @connection_handle: LL2 connection's handle obtained from
* qed_ll2_require_connection.
* *
* @param cxt - pointer to the hw-function [opaque to some] * Return: 0 on success, failure otherwise.
* @param connection_handle LL2 connection's handle
* obtained from
* qed_ll2_require_connection
*
* @return 0 on success, failure otherwise
*/ */
int qed_ll2_terminate_connection(void *cxt, u8 connection_handle); int qed_ll2_terminate_connection(void *cxt, u8 connection_handle);
/** /**
* @brief qed_ll2_get_stats - get LL2 queue's statistics * qed_ll2_get_stats(): Get LL2 queue's statistics
* *
* @cxt: Pointer to the hw-function [opaque to some].
* @connection_handle: LL2 connection's handle obtained from
* qed_ll2_require_connection.
* @p_stats: Pointer Status.
* *
* @param cxt - pointer to the hw-function [opaque to some] * Return: 0 on success, failure otherwise.
* @param connection_handle LL2 connection's handle obtained from
* qed_ll2_require_connection
* @param p_stats
*
* @return 0 on success, failure otherwise
*/ */
int qed_ll2_get_stats(void *cxt, int qed_ll2_get_stats(void *cxt,
u8 connection_handle, struct qed_ll2_stats *p_stats); u8 connection_handle, struct qed_ll2_stats *p_stats);
/** /**
* @brief qed_ll2_alloc - Allocates LL2 connections set * qed_ll2_alloc(): Allocates LL2 connections set.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_ll2_alloc(struct qed_hwfn *p_hwfn); int qed_ll2_alloc(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_ll2_setup - Inits LL2 connections set * qed_ll2_setup(): Inits LL2 connections set.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
* *
*/ */
void qed_ll2_setup(struct qed_hwfn *p_hwfn); void qed_ll2_setup(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_ll2_free - Releases LL2 connections set * qed_ll2_free(): Releases LL2 connections set
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
* *
*/ */
void qed_ll2_free(struct qed_hwfn *p_hwfn); void qed_ll2_free(struct qed_hwfn *p_hwfn);

View File

@@ -3054,7 +3054,7 @@ void qed_get_protocol_stats(struct qed_dev *cdev,
switch (type) { switch (type) {
case QED_MCP_LAN_STATS: case QED_MCP_LAN_STATS:
qed_get_vport_stats(cdev, &eth_stats); qed_get_vport_stats_context(cdev, &eth_stats, true);
stats->lan_stats.ucast_rx_pkts = stats->lan_stats.ucast_rx_pkts =
eth_stats.common.rx_ucast_pkts; eth_stats.common.rx_ucast_pkts;
stats->lan_stats.ucast_tx_pkts = stats->lan_stats.ucast_tx_pkts =
@@ -3062,10 +3062,10 @@ void qed_get_protocol_stats(struct qed_dev *cdev,
stats->lan_stats.fcs_err = -1; stats->lan_stats.fcs_err = -1;
break; break;
case QED_MCP_FCOE_STATS: case QED_MCP_FCOE_STATS:
qed_get_protocol_stats_fcoe(cdev, &stats->fcoe_stats); qed_get_protocol_stats_fcoe(cdev, &stats->fcoe_stats, true);
break; break;
case QED_MCP_ISCSI_STATS: case QED_MCP_ISCSI_STATS:
qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats); qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats, true);
break; break;
default: default:
DP_VERBOSE(cdev, QED_MSG_SP, DP_VERBOSE(cdev, QED_MSG_SP,

File diff suppressed because it is too large Load Diff

View File

@@ -6,47 +6,47 @@
#include <linux/types.h> #include <linux/types.h>
/** /**
* @brief qed_selftest_memory - Perform memory test * qed_selftest_memory(): Perform memory test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return int * Return: Int.
*/ */
int qed_selftest_memory(struct qed_dev *cdev); int qed_selftest_memory(struct qed_dev *cdev);
/** /**
* @brief qed_selftest_interrupt - Perform interrupt test * qed_selftest_interrupt(): Perform interrupt test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return int * Return: Int.
*/ */
int qed_selftest_interrupt(struct qed_dev *cdev); int qed_selftest_interrupt(struct qed_dev *cdev);
/** /**
* @brief qed_selftest_register - Perform register test * qed_selftest_register(): Perform register test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return int * Return: Int.
*/ */
int qed_selftest_register(struct qed_dev *cdev); int qed_selftest_register(struct qed_dev *cdev);
/** /**
* @brief qed_selftest_clock - Perform clock test * qed_selftest_clock(): Perform clock test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return int * Return: Int.
*/ */
int qed_selftest_clock(struct qed_dev *cdev); int qed_selftest_clock(struct qed_dev *cdev);
/** /**
* @brief qed_selftest_nvram - Perform nvram test * qed_selftest_nvram(): Perform nvram test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return int * Return: Int.
*/ */
int qed_selftest_nvram(struct qed_dev *cdev); int qed_selftest_nvram(struct qed_dev *cdev);

View File

@@ -31,23 +31,18 @@ struct qed_spq_comp_cb {
}; };
/** /**
* @brief qed_eth_cqe_completion - handles the completion of a * qed_eth_cqe_completion(): handles the completion of a
* ramrod on the cqe ring * ramrod on the cqe ring.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param cqe * @cqe: CQE.
* *
* @return int * Return: Int.
*/ */
int qed_eth_cqe_completion(struct qed_hwfn *p_hwfn, int qed_eth_cqe_completion(struct qed_hwfn *p_hwfn,
struct eth_slow_path_rx_cqe *cqe); struct eth_slow_path_rx_cqe *cqe);
/** /* QED Slow-hwfn queue interface */
* @file
*
* QED Slow-hwfn queue interface
*/
union ramrod_data { union ramrod_data {
struct pf_start_ramrod_data pf_start; struct pf_start_ramrod_data pf_start;
struct pf_update_ramrod_data pf_update; struct pf_update_ramrod_data pf_update;
@@ -207,117 +202,128 @@ struct qed_spq {
}; };
/** /**
* @brief qed_spq_post - Posts a Slow hwfn request to FW, or lacking that * qed_spq_post(): Posts a Slow hwfn request to FW, or lacking that
* Pends it to the future list. * Pends it to the future list.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_req * @p_ent: Ent.
* @fw_return_code: Return code from firmware.
* *
* @return int * Return: Int.
*/ */
int qed_spq_post(struct qed_hwfn *p_hwfn, int qed_spq_post(struct qed_hwfn *p_hwfn,
struct qed_spq_entry *p_ent, struct qed_spq_entry *p_ent,
u8 *fw_return_code); u8 *fw_return_code);
/** /**
* @brief qed_spq_allocate - Alloocates & initializes the SPQ and EQ. * qed_spq_alloc(): Alloocates & initializes the SPQ and EQ.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_spq_alloc(struct qed_hwfn *p_hwfn); int qed_spq_alloc(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_spq_setup - Reset the SPQ to its start state. * qed_spq_setup(): Reset the SPQ to its start state.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_spq_setup(struct qed_hwfn *p_hwfn); void qed_spq_setup(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_spq_deallocate - Deallocates the given SPQ struct. * qed_spq_free(): Deallocates the given SPQ struct.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_spq_free(struct qed_hwfn *p_hwfn); void qed_spq_free(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_spq_get_entry - Obtain an entrry from the spq * qed_spq_get_entry(): Obtain an entrry from the spq
* free pool list. * free pool list.
* *
* @p_hwfn: HW device data.
* @pp_ent: PP ENT.
* *
* * Return: Int.
* @param p_hwfn
* @param pp_ent
*
* @return int
*/ */
int int
qed_spq_get_entry(struct qed_hwfn *p_hwfn, qed_spq_get_entry(struct qed_hwfn *p_hwfn,
struct qed_spq_entry **pp_ent); struct qed_spq_entry **pp_ent);
/** /**
* @brief qed_spq_return_entry - Return an entry to spq free * qed_spq_return_entry(): Return an entry to spq free pool list.
* pool list
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ent * @p_ent: P ENT.
*
* Return: Void.
*/ */
void qed_spq_return_entry(struct qed_hwfn *p_hwfn, void qed_spq_return_entry(struct qed_hwfn *p_hwfn,
struct qed_spq_entry *p_ent); struct qed_spq_entry *p_ent);
/** /**
* @brief qed_eq_allocate - Allocates & initializes an EQ struct * qed_eq_alloc(): Allocates & initializes an EQ struct.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param num_elem number of elements in the eq * @num_elem: number of elements in the eq.
* *
* @return int * Return: Int.
*/ */
int qed_eq_alloc(struct qed_hwfn *p_hwfn, u16 num_elem); int qed_eq_alloc(struct qed_hwfn *p_hwfn, u16 num_elem);
/** /**
* @brief qed_eq_setup - Reset the EQ to its start state. * qed_eq_setup(): Reset the EQ to its start state.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_eq_setup(struct qed_hwfn *p_hwfn); void qed_eq_setup(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_eq_free - deallocates the given EQ struct. * qed_eq_free(): deallocates the given EQ struct.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_eq_free(struct qed_hwfn *p_hwfn); void qed_eq_free(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_eq_prod_update - update the FW with default EQ producer * qed_eq_prod_update(): update the FW with default EQ producer.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param prod * @prod: Prod.
*
* Return: Void.
*/ */
void qed_eq_prod_update(struct qed_hwfn *p_hwfn, void qed_eq_prod_update(struct qed_hwfn *p_hwfn,
u16 prod); u16 prod);
/** /**
* @brief qed_eq_completion - Completes currently pending EQ elements * qed_eq_completion(): Completes currently pending EQ elements.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param cookie * @cookie: Cookie.
* *
* @return int * Return: Int.
*/ */
int qed_eq_completion(struct qed_hwfn *p_hwfn, int qed_eq_completion(struct qed_hwfn *p_hwfn,
void *cookie); void *cookie);
/** /**
* @brief qed_spq_completion - Completes a single event * qed_spq_completion(): Completes a single event.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param echo - echo value from cookie (used for determining completion) * @echo: echo value from cookie (used for determining completion).
* @param p_data - data from cookie (used in callback function if applicable) * @fw_return_code: FW return code.
* @p_data: data from cookie (used in callback function if applicable).
* *
* @return int * Return: Int.
*/ */
int qed_spq_completion(struct qed_hwfn *p_hwfn, int qed_spq_completion(struct qed_hwfn *p_hwfn,
__le16 echo, __le16 echo,
@@ -325,44 +331,43 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn,
union event_ring_data *p_data); union event_ring_data *p_data);
/** /**
* @brief qed_spq_get_cid - Given p_hwfn, return cid for the hwfn's SPQ * qed_spq_get_cid(): Given p_hwfn, return cid for the hwfn's SPQ.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return u32 - SPQ CID * Return: u32 - SPQ CID.
*/ */
u32 qed_spq_get_cid(struct qed_hwfn *p_hwfn); u32 qed_spq_get_cid(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_consq_alloc - Allocates & initializes an ConsQ * qed_consq_alloc(): Allocates & initializes an ConsQ struct.
* struct
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_consq_alloc(struct qed_hwfn *p_hwfn); int qed_consq_alloc(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_consq_setup - Reset the ConsQ to its start state. * qed_consq_setup(): Reset the ConsQ to its start state.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return Void.
*/ */
void qed_consq_setup(struct qed_hwfn *p_hwfn); void qed_consq_setup(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_consq_free - deallocates the given ConsQ struct. * qed_consq_free(): deallocates the given ConsQ struct.
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return Void.
*/ */
void qed_consq_free(struct qed_hwfn *p_hwfn); void qed_consq_free(struct qed_hwfn *p_hwfn);
int qed_spq_pend_post(struct qed_hwfn *p_hwfn); int qed_spq_pend_post(struct qed_hwfn *p_hwfn);
/** /* Slow-hwfn low-level commands (Ramrods) function definitions. */
* @file
*
* @brief Slow-hwfn low-level commands (Ramrods) function definitions.
*/
#define QED_SP_EQ_COMPLETION 0x01 #define QED_SP_EQ_COMPLETION 0x01
#define QED_SP_CQE_COMPLETION 0x02 #define QED_SP_CQE_COMPLETION 0x02
@@ -377,12 +382,15 @@ struct qed_sp_init_data {
}; };
/** /**
* @brief Returns a SPQ entry to the pool / frees the entry if allocated. * qed_sp_destroy_request(): Returns a SPQ entry to the pool / frees the
* Should be called on in error flows after initializing the SPQ entry * entry if allocated. Should be called on in error
* and before posting it. * flows after initializing the SPQ entry
* and before posting it.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_ent * @p_ent: Ent.
*
* Return: Void.
*/ */
void qed_sp_destroy_request(struct qed_hwfn *p_hwfn, void qed_sp_destroy_request(struct qed_hwfn *p_hwfn,
struct qed_spq_entry *p_ent); struct qed_spq_entry *p_ent);
@@ -394,7 +402,14 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn,
struct qed_sp_init_data *p_data); struct qed_sp_init_data *p_data);
/** /**
* @brief qed_sp_pf_start - PF Function Start Ramrod * qed_sp_pf_start(): PF Function Start Ramrod.
*
* @p_hwfn: HW device data.
* @p_ptt: P_ptt.
* @p_tunn: P_tunn.
* @allow_npar_tx_switch: Allow NPAR TX Switch.
*
* Return: Int.
* *
* This ramrod is sent to initialize a physical function (PF). It will * This ramrod is sent to initialize a physical function (PF). It will
* configure the function related parameters and write its completion to the * configure the function related parameters and write its completion to the
@@ -404,12 +419,6 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn,
* allocated by the driver on host memory and its parameters are written * allocated by the driver on host memory and its parameters are written
* to the internal RAM of the UStorm by the Function Start Ramrod. * to the internal RAM of the UStorm by the Function Start Ramrod.
* *
* @param p_hwfn
* @param p_ptt
* @param p_tunn
* @param allow_npar_tx_switch
*
* @return int
*/ */
int qed_sp_pf_start(struct qed_hwfn *p_hwfn, int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
@@ -418,47 +427,33 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
bool allow_npar_tx_switch); bool allow_npar_tx_switch);
/** /**
* @brief qed_sp_pf_update - PF Function Update Ramrod * qed_sp_pf_update(): PF Function Update Ramrod.
*
* @p_hwfn: HW device data.
*
* Return: Int.
* *
* This ramrod updates function-related parameters. Every parameter can be * This ramrod updates function-related parameters. Every parameter can be
* updated independently, according to configuration flags. * updated independently, according to configuration flags.
*
* @param p_hwfn
*
* @return int
*/ */
int qed_sp_pf_update(struct qed_hwfn *p_hwfn); int qed_sp_pf_update(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_sp_pf_update_stag - Update firmware of new outer tag * qed_sp_pf_update_stag(): Update firmware of new outer tag.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_sp_pf_update_stag(struct qed_hwfn *p_hwfn); int qed_sp_pf_update_stag(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_sp_pf_stop - PF Function Stop Ramrod * qed_sp_pf_update_ufp(): PF ufp update Ramrod.
* *
* This ramrod is sent to close a Physical Function (PF). It is the last ramrod * @p_hwfn: HW device data.
* sent and the last completion written to the PFs Event Ring. This ramrod also
* deletes the context for the Slowhwfn connection on this PF.
* *
* @note Not required for first packet. * Return: Int.
*
* @param p_hwfn
*
* @return int
*/
/**
* @brief qed_sp_pf_update_ufp - PF ufp update Ramrod
*
* @param p_hwfn
*
* @return int
*/ */
int qed_sp_pf_update_ufp(struct qed_hwfn *p_hwfn); int qed_sp_pf_update_ufp(struct qed_hwfn *p_hwfn);
@@ -470,11 +465,11 @@ int qed_sp_pf_update_tunn_cfg(struct qed_hwfn *p_hwfn,
enum spq_mode comp_mode, enum spq_mode comp_mode,
struct qed_spq_comp_cb *p_comp_data); struct qed_spq_comp_cb *p_comp_data);
/** /**
* @brief qed_sp_heartbeat_ramrod - Send empty Ramrod * qed_sp_heartbeat_ramrod(): Send empty Ramrod.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_sp_heartbeat_ramrod(struct qed_hwfn *p_hwfn); int qed_sp_heartbeat_ramrod(struct qed_hwfn *p_hwfn);

View File

@@ -251,29 +251,31 @@ extern const struct qed_iov_hv_ops qed_iov_ops_pass;
#ifdef CONFIG_QED_SRIOV #ifdef CONFIG_QED_SRIOV
/** /**
* @brief Check if given VF ID @vfid is valid * qed_iov_is_valid_vfid(): Check if given VF ID @vfid is valid
* w.r.t. @b_enabled_only value * w.r.t. @b_enabled_only value
* if b_enabled_only = true - only enabled VF id is valid * if b_enabled_only = true - only enabled
* else any VF id less than max_vfs is valid * VF id is valid.
* else any VF id less than max_vfs is valid.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param rel_vf_id - Relative VF ID * @rel_vf_id: Relative VF ID.
* @param b_enabled_only - consider only enabled VF * @b_enabled_only: consider only enabled VF.
* @param b_non_malicious - true iff we want to validate vf isn't malicious. * @b_non_malicious: true iff we want to validate vf isn't malicious.
* *
* @return bool - true for valid VF ID * Return: bool - true for valid VF ID
*/ */
bool qed_iov_is_valid_vfid(struct qed_hwfn *p_hwfn, bool qed_iov_is_valid_vfid(struct qed_hwfn *p_hwfn,
int rel_vf_id, int rel_vf_id,
bool b_enabled_only, bool b_non_malicious); bool b_enabled_only, bool b_non_malicious);
/** /**
* @brief - Given a VF index, return index of next [including that] active VF. * qed_iov_get_next_active_vf(): Given a VF index, return index of
* next [including that] active VF.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param rel_vf_id * @rel_vf_id: VF ID.
* *
* @return MAX_NUM_VFS in case no further active VFs, otherwise index. * Return: MAX_NUM_VFS in case no further active VFs, otherwise index.
*/ */
u16 qed_iov_get_next_active_vf(struct qed_hwfn *p_hwfn, u16 rel_vf_id); u16 qed_iov_get_next_active_vf(struct qed_hwfn *p_hwfn, u16 rel_vf_id);
@@ -281,83 +283,92 @@ void qed_iov_bulletin_set_udp_ports(struct qed_hwfn *p_hwfn,
int vfid, u16 vxlan_port, u16 geneve_port); int vfid, u16 vxlan_port, u16 geneve_port);
/** /**
* @brief Read sriov related information and allocated resources * qed_iov_hw_info(): Read sriov related information and allocated resources
* reads from configuration space, shmem, etc. * reads from configuration space, shmem, etc.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_iov_hw_info(struct qed_hwfn *p_hwfn); int qed_iov_hw_info(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_add_tlv - place a given tlv on the tlv buffer at next offset * qed_add_tlv(): place a given tlv on the tlv buffer at next offset
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_iov * @offset: offset.
* @param type * @type: Type
* @param length * @length: Length.
* *
* @return pointer to the newly placed tlv * Return: pointer to the newly placed tlv
*/ */
void *qed_add_tlv(struct qed_hwfn *p_hwfn, u8 **offset, u16 type, u16 length); void *qed_add_tlv(struct qed_hwfn *p_hwfn, u8 **offset, u16 type, u16 length);
/** /**
* @brief list the types and lengths of the tlvs on the buffer * qed_dp_tlv_list(): list the types and lengths of the tlvs on the buffer
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param tlvs_list * @tlvs_list: Tlvs_list.
*
* Return: Void.
*/ */
void qed_dp_tlv_list(struct qed_hwfn *p_hwfn, void *tlvs_list); void qed_dp_tlv_list(struct qed_hwfn *p_hwfn, void *tlvs_list);
/** /**
* @brief qed_iov_alloc - allocate sriov related resources * qed_iov_alloc(): allocate sriov related resources
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_iov_alloc(struct qed_hwfn *p_hwfn); int qed_iov_alloc(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_iov_setup - setup sriov related resources * qed_iov_setup(): setup sriov related resources
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_iov_setup(struct qed_hwfn *p_hwfn); void qed_iov_setup(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_iov_free - free sriov related resources * qed_iov_free(): free sriov related resources
* *
* @param p_hwfn * @p_hwfn: HW device data.
*
* Return: Void.
*/ */
void qed_iov_free(struct qed_hwfn *p_hwfn); void qed_iov_free(struct qed_hwfn *p_hwfn);
/** /**
* @brief free sriov related memory that was allocated during hw_prepare * qed_iov_free_hw_info(): free sriov related memory that was
* allocated during hw_prepare
* *
* @param cdev * @cdev: Qed dev pointer.
*
* Return: Void.
*/ */
void qed_iov_free_hw_info(struct qed_dev *cdev); void qed_iov_free_hw_info(struct qed_dev *cdev);
/** /**
* @brief Mark structs of vfs that have been FLR-ed. * qed_iov_mark_vf_flr(): Mark structs of vfs that have been FLR-ed.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param disabled_vfs - bitmask of all VFs on path that were FLRed * @disabled_vfs: bitmask of all VFs on path that were FLRed
* *
* @return true iff one of the PF's vfs got FLRed. false otherwise. * Return: true iff one of the PF's vfs got FLRed. false otherwise.
*/ */
bool qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 *disabled_vfs); bool qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 *disabled_vfs);
/** /**
* @brief Search extended TLVs in request/reply buffer. * qed_iov_search_list_tlvs(): Search extended TLVs in request/reply buffer.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_tlvs_list - Pointer to tlvs list * @p_tlvs_list: Pointer to tlvs list
* @param req_type - Type of TLV * @req_type: Type of TLV
* *
* @return pointer to tlv type if found, otherwise returns NULL. * Return: pointer to tlv type if found, otherwise returns NULL.
*/ */
void *qed_iov_search_list_tlvs(struct qed_hwfn *p_hwfn, void *qed_iov_search_list_tlvs(struct qed_hwfn *p_hwfn,
void *p_tlvs_list, u16 req_type); void *p_tlvs_list, u16 req_type);

View File

@@ -688,13 +688,16 @@ struct qed_vf_iov {
}; };
/** /**
* @brief VF - Set Rx/Tx coalesce per VF's relative queue. * qed_vf_pf_set_coalesce(): VF - Set Rx/Tx coalesce per VF's relative queue.
* Coalesce value '0' will omit the configuration. * Coalesce value '0' will omit the
* configuration.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param rx_coal - coalesce value in micro second for rx queue * @rx_coal: coalesce value in micro second for rx queue.
* @param tx_coal - coalesce value in micro second for tx queue * @tx_coal: coalesce value in micro second for tx queue.
* @param p_cid - queue cid * @p_cid: queue cid.
*
* Return: Int.
* *
**/ **/
int qed_vf_pf_set_coalesce(struct qed_hwfn *p_hwfn, int qed_vf_pf_set_coalesce(struct qed_hwfn *p_hwfn,
@@ -702,148 +705,172 @@ int qed_vf_pf_set_coalesce(struct qed_hwfn *p_hwfn,
u16 tx_coal, struct qed_queue_cid *p_cid); u16 tx_coal, struct qed_queue_cid *p_cid);
/** /**
* @brief VF - Get coalesce per VF's relative queue. * qed_vf_pf_get_coalesce(): VF - Get coalesce per VF's relative queue.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_coal - coalesce value in micro second for VF queues. * @p_coal: coalesce value in micro second for VF queues.
* @param p_cid - queue cid * @p_cid: queue cid.
* *
* Return: Int.
**/ **/
int qed_vf_pf_get_coalesce(struct qed_hwfn *p_hwfn, int qed_vf_pf_get_coalesce(struct qed_hwfn *p_hwfn,
u16 *p_coal, struct qed_queue_cid *p_cid); u16 *p_coal, struct qed_queue_cid *p_cid);
#ifdef CONFIG_QED_SRIOV #ifdef CONFIG_QED_SRIOV
/** /**
* @brief Read the VF bulletin and act on it if needed * qed_vf_read_bulletin(): Read the VF bulletin and act on it if needed.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_change - qed fills 1 iff bulletin board has changed, 0 otherwise. * @p_change: qed fills 1 iff bulletin board has changed, 0 otherwise.
* *
* @return enum _qed_status * Return: enum _qed_status.
*/ */
int qed_vf_read_bulletin(struct qed_hwfn *p_hwfn, u8 *p_change); int qed_vf_read_bulletin(struct qed_hwfn *p_hwfn, u8 *p_change);
/** /**
* @brief Get link paramters for VF from qed * qed_vf_get_link_params(): Get link parameters for VF from qed
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param params - the link params structure to be filled for the VF * @params: the link params structure to be filled for the VF.
*
* Return: Void.
*/ */
void qed_vf_get_link_params(struct qed_hwfn *p_hwfn, void qed_vf_get_link_params(struct qed_hwfn *p_hwfn,
struct qed_mcp_link_params *params); struct qed_mcp_link_params *params);
/** /**
* @brief Get link state for VF from qed * qed_vf_get_link_state(): Get link state for VF from qed.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param link - the link state structure to be filled for the VF * @link: the link state structure to be filled for the VF
*
* Return: Void.
*/ */
void qed_vf_get_link_state(struct qed_hwfn *p_hwfn, void qed_vf_get_link_state(struct qed_hwfn *p_hwfn,
struct qed_mcp_link_state *link); struct qed_mcp_link_state *link);
/** /**
* @brief Get link capabilities for VF from qed * qed_vf_get_link_caps(): Get link capabilities for VF from qed.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_link_caps - the link capabilities structure to be filled for the VF * @p_link_caps: the link capabilities structure to be filled for the VF
*
* Return: Void.
*/ */
void qed_vf_get_link_caps(struct qed_hwfn *p_hwfn, void qed_vf_get_link_caps(struct qed_hwfn *p_hwfn,
struct qed_mcp_link_capabilities *p_link_caps); struct qed_mcp_link_capabilities *p_link_caps);
/** /**
* @brief Get number of Rx queues allocated for VF by qed * qed_vf_get_num_rxqs(): Get number of Rx queues allocated for VF by qed
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param num_rxqs - allocated RX queues * @num_rxqs: allocated RX queues
*
* Return: Void.
*/ */
void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs); void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs);
/** /**
* @brief Get number of Rx queues allocated for VF by qed * qed_vf_get_num_txqs(): Get number of Rx queues allocated for VF by qed
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param num_txqs - allocated RX queues * @num_txqs: allocated RX queues
*
* Return: Void.
*/ */
void qed_vf_get_num_txqs(struct qed_hwfn *p_hwfn, u8 *num_txqs); void qed_vf_get_num_txqs(struct qed_hwfn *p_hwfn, u8 *num_txqs);
/** /**
* @brief Get number of available connections [both Rx and Tx] for VF * qed_vf_get_num_cids(): Get number of available connections
* [both Rx and Tx] for VF
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param num_cids - allocated number of connections * @num_cids: allocated number of connections
*
* Return: Void.
*/ */
void qed_vf_get_num_cids(struct qed_hwfn *p_hwfn, u8 *num_cids); void qed_vf_get_num_cids(struct qed_hwfn *p_hwfn, u8 *num_cids);
/** /**
* @brief Get port mac address for VF * qed_vf_get_port_mac(): Get port mac address for VF.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param port_mac - destination location for port mac * @port_mac: destination location for port mac
*
* Return: Void.
*/ */
void qed_vf_get_port_mac(struct qed_hwfn *p_hwfn, u8 *port_mac); void qed_vf_get_port_mac(struct qed_hwfn *p_hwfn, u8 *port_mac);
/** /**
* @brief Get number of VLAN filters allocated for VF by qed * qed_vf_get_num_vlan_filters(): Get number of VLAN filters allocated
* for VF by qed.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param num_rxqs - allocated VLAN filters * @num_vlan_filters: allocated VLAN filters
*
* Return: Void.
*/ */
void qed_vf_get_num_vlan_filters(struct qed_hwfn *p_hwfn, void qed_vf_get_num_vlan_filters(struct qed_hwfn *p_hwfn,
u8 *num_vlan_filters); u8 *num_vlan_filters);
/** /**
* @brief Get number of MAC filters allocated for VF by qed * qed_vf_get_num_mac_filters(): Get number of MAC filters allocated
* for VF by qed
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param num_rxqs - allocated MAC filters * @num_mac_filters: allocated MAC filters
*
* Return: Void.
*/ */
void qed_vf_get_num_mac_filters(struct qed_hwfn *p_hwfn, u8 *num_mac_filters); void qed_vf_get_num_mac_filters(struct qed_hwfn *p_hwfn, u8 *num_mac_filters);
/** /**
* @brief Check if VF can set a MAC address * qed_vf_check_mac(): Check if VF can set a MAC address
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param mac * @mac: Mac.
* *
* @return bool * Return: bool.
*/ */
bool qed_vf_check_mac(struct qed_hwfn *p_hwfn, u8 *mac); bool qed_vf_check_mac(struct qed_hwfn *p_hwfn, u8 *mac);
/** /**
* @brief Set firmware version information in dev_info from VFs acquire response tlv * qed_vf_get_fw_version(): Set firmware version information
* in dev_info from VFs acquire response tlv
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param fw_major * @fw_major: FW major.
* @param fw_minor * @fw_minor: FW minor.
* @param fw_rev * @fw_rev: FW rev.
* @param fw_eng * @fw_eng: FW eng.
*
* Return: Void.
*/ */
void qed_vf_get_fw_version(struct qed_hwfn *p_hwfn, void qed_vf_get_fw_version(struct qed_hwfn *p_hwfn,
u16 *fw_major, u16 *fw_minor, u16 *fw_major, u16 *fw_minor,
u16 *fw_rev, u16 *fw_eng); u16 *fw_rev, u16 *fw_eng);
/** /**
* @brief hw preparation for VF * qed_vf_hw_prepare(): hw preparation for VF sends ACQUIRE message
* sends ACQUIRE message
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return int * Return: Int.
*/ */
int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn); int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn);
/** /**
* @brief VF - start the RX Queue by sending a message to the PF * qed_vf_pf_rxq_start(): start the RX Queue by sending a message to the PF
* @param p_hwfn
* @param p_cid - Only relative fields are relevant
* @param bd_max_bytes - maximum number of bytes per bd
* @param bd_chain_phys_addr - physical address of bd chain
* @param cqe_pbl_addr - physical address of pbl
* @param cqe_pbl_size - pbl size
* @param pp_prod - pointer to the producer to be
* used in fastpath
* *
* @return int * @p_hwfn: HW device data.
* @p_cid: Only relative fields are relevant
* @bd_max_bytes: maximum number of bytes per bd
* @bd_chain_phys_addr: physical address of bd chain
* @cqe_pbl_addr: physical address of pbl
* @cqe_pbl_size: pbl size
* @pp_prod: pointer to the producer to be used in fastpath
*
* Return: Int.
*/ */
int qed_vf_pf_rxq_start(struct qed_hwfn *p_hwfn, int qed_vf_pf_rxq_start(struct qed_hwfn *p_hwfn,
struct qed_queue_cid *p_cid, struct qed_queue_cid *p_cid,
@@ -853,18 +880,16 @@ int qed_vf_pf_rxq_start(struct qed_hwfn *p_hwfn,
u16 cqe_pbl_size, void __iomem **pp_prod); u16 cqe_pbl_size, void __iomem **pp_prod);
/** /**
* @brief VF - start the TX queue by sending a message to the * qed_vf_pf_txq_start(): VF - start the TX queue by sending a message to the
* PF. * PF.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param tx_queue_id - zero based within the VF * @p_cid: CID.
* @param sb - status block for this queue * @pbl_addr: PBL address.
* @param sb_index - index within the status block * @pbl_size: PBL Size.
* @param bd_chain_phys_addr - physical address of tx chain * @pp_doorbell: pointer to address to which to write the doorbell too.
* @param pp_doorbell - pointer to address to which to
* write the doorbell too..
* *
* @return int * Return: Int.
*/ */
int int
qed_vf_pf_txq_start(struct qed_hwfn *p_hwfn, qed_vf_pf_txq_start(struct qed_hwfn *p_hwfn,
@@ -873,90 +898,91 @@ qed_vf_pf_txq_start(struct qed_hwfn *p_hwfn,
u16 pbl_size, void __iomem **pp_doorbell); u16 pbl_size, void __iomem **pp_doorbell);
/** /**
* @brief VF - stop the RX queue by sending a message to the PF * qed_vf_pf_rxq_stop(): VF - stop the RX queue by sending a message to the PF.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_cid * @p_cid: CID.
* @param cqe_completion * @cqe_completion: CQE Completion.
* *
* @return int * Return: Int.
*/ */
int qed_vf_pf_rxq_stop(struct qed_hwfn *p_hwfn, int qed_vf_pf_rxq_stop(struct qed_hwfn *p_hwfn,
struct qed_queue_cid *p_cid, bool cqe_completion); struct qed_queue_cid *p_cid, bool cqe_completion);
/** /**
* @brief VF - stop the TX queue by sending a message to the PF * qed_vf_pf_txq_stop(): VF - stop the TX queue by sending a message to the PF.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param tx_qid * @p_cid: CID.
* *
* @return int * Return: Int.
*/ */
int qed_vf_pf_txq_stop(struct qed_hwfn *p_hwfn, struct qed_queue_cid *p_cid); int qed_vf_pf_txq_stop(struct qed_hwfn *p_hwfn, struct qed_queue_cid *p_cid);
/** /**
* @brief VF - send a vport update command * qed_vf_pf_vport_update(): VF - send a vport update command.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param params * @p_params: Params
* *
* @return int * Return: Int.
*/ */
int qed_vf_pf_vport_update(struct qed_hwfn *p_hwfn, int qed_vf_pf_vport_update(struct qed_hwfn *p_hwfn,
struct qed_sp_vport_update_params *p_params); struct qed_sp_vport_update_params *p_params);
/** /**
* qed_vf_pf_reset(): VF - send a close message to PF.
* *
* @brief VF - send a close message to PF * @p_hwfn: HW device data.
* *
* @param p_hwfn * Return: enum _qed_status
*
* @return enum _qed_status
*/ */
int qed_vf_pf_reset(struct qed_hwfn *p_hwfn); int qed_vf_pf_reset(struct qed_hwfn *p_hwfn);
/** /**
* @brief VF - free vf`s memories * qed_vf_pf_release(): VF - free vf`s memories.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return enum _qed_status * Return: enum _qed_status
*/ */
int qed_vf_pf_release(struct qed_hwfn *p_hwfn); int qed_vf_pf_release(struct qed_hwfn *p_hwfn);
/** /**
* @brief qed_vf_get_igu_sb_id - Get the IGU SB ID for a given * qed_vf_get_igu_sb_id(): Get the IGU SB ID for a given
* sb_id. For VFs igu sbs don't have to be contiguous * sb_id. For VFs igu sbs don't have to be contiguous
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param sb_id * @sb_id: SB ID.
* *
* @return INLINE u16 * Return: INLINE u16
*/ */
u16 qed_vf_get_igu_sb_id(struct qed_hwfn *p_hwfn, u16 sb_id); u16 qed_vf_get_igu_sb_id(struct qed_hwfn *p_hwfn, u16 sb_id);
/** /**
* @brief Stores [or removes] a configured sb_info. * qed_vf_set_sb_info(): Stores [or removes] a configured sb_info.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param sb_id - zero-based SB index [for fastpath] * @sb_id: zero-based SB index [for fastpath]
* @param sb_info - may be NULL [during removal]. * @p_sb: may be NULL [during removal].
*
* Return: Void.
*/ */
void qed_vf_set_sb_info(struct qed_hwfn *p_hwfn, void qed_vf_set_sb_info(struct qed_hwfn *p_hwfn,
u16 sb_id, struct qed_sb_info *p_sb); u16 sb_id, struct qed_sb_info *p_sb);
/** /**
* @brief qed_vf_pf_vport_start - perform vport start for VF. * qed_vf_pf_vport_start(): perform vport start for VF.
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param vport_id * @vport_id: Vport ID.
* @param mtu * @mtu: MTU.
* @param inner_vlan_removal * @inner_vlan_removal: Innter VLAN removal.
* @param tpa_mode * @tpa_mode: TPA mode
* @param max_buffers_per_cqe, * @max_buffers_per_cqe: Max buffer pre CQE.
* @param only_untagged - default behavior regarding vlan acceptance * @only_untagged: default behavior regarding vlan acceptance
* *
* @return enum _qed_status * Return: enum _qed_status
*/ */
int qed_vf_pf_vport_start(struct qed_hwfn *p_hwfn, int qed_vf_pf_vport_start(struct qed_hwfn *p_hwfn,
u8 vport_id, u8 vport_id,
@@ -966,11 +992,11 @@ int qed_vf_pf_vport_start(struct qed_hwfn *p_hwfn,
u8 max_buffers_per_cqe, u8 only_untagged); u8 max_buffers_per_cqe, u8 only_untagged);
/** /**
* @brief qed_vf_pf_vport_stop - stop the VF's vport * qed_vf_pf_vport_stop(): stop the VF's vport
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return enum _qed_status * Return: enum _qed_status
*/ */
int qed_vf_pf_vport_stop(struct qed_hwfn *p_hwfn); int qed_vf_pf_vport_stop(struct qed_hwfn *p_hwfn);
@@ -981,42 +1007,49 @@ void qed_vf_pf_filter_mcast(struct qed_hwfn *p_hwfn,
struct qed_filter_mcast *p_filter_cmd); struct qed_filter_mcast *p_filter_cmd);
/** /**
* @brief qed_vf_pf_int_cleanup - clean the SB of the VF * qed_vf_pf_int_cleanup(): clean the SB of the VF
* *
* @param p_hwfn * @p_hwfn: HW device data.
* *
* @return enum _qed_status * Return: enum _qed_status
*/ */
int qed_vf_pf_int_cleanup(struct qed_hwfn *p_hwfn); int qed_vf_pf_int_cleanup(struct qed_hwfn *p_hwfn);
/** /**
* @brief - return the link params in a given bulletin board * __qed_vf_get_link_params(): return the link params in a given bulletin board
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_params - pointer to a struct to fill with link params * @p_params: pointer to a struct to fill with link params
* @param p_bulletin * @p_bulletin: Bulletin.
*
* Return: Void.
*/ */
void __qed_vf_get_link_params(struct qed_hwfn *p_hwfn, void __qed_vf_get_link_params(struct qed_hwfn *p_hwfn,
struct qed_mcp_link_params *p_params, struct qed_mcp_link_params *p_params,
struct qed_bulletin_content *p_bulletin); struct qed_bulletin_content *p_bulletin);
/** /**
* @brief - return the link state in a given bulletin board * __qed_vf_get_link_state(): return the link state in a given bulletin board
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_link - pointer to a struct to fill with link state * @p_link: pointer to a struct to fill with link state
* @param p_bulletin * @p_bulletin: Bulletin.
*
* Return: Void.
*/ */
void __qed_vf_get_link_state(struct qed_hwfn *p_hwfn, void __qed_vf_get_link_state(struct qed_hwfn *p_hwfn,
struct qed_mcp_link_state *p_link, struct qed_mcp_link_state *p_link,
struct qed_bulletin_content *p_bulletin); struct qed_bulletin_content *p_bulletin);
/** /**
* @brief - return the link capabilities in a given bulletin board * __qed_vf_get_link_caps(): return the link capabilities in a given
* bulletin board
* *
* @param p_hwfn * @p_hwfn: HW device data.
* @param p_link - pointer to a struct to fill with link capabilities * @p_link_caps: pointer to a struct to fill with link capabilities
* @param p_bulletin * @p_bulletin: Bulletin.
*
* Return: Void.
*/ */
void __qed_vf_get_link_caps(struct qed_hwfn *p_hwfn, void __qed_vf_get_link_caps(struct qed_hwfn *p_hwfn,
struct qed_mcp_link_capabilities *p_link_caps, struct qed_mcp_link_capabilities *p_link_caps,
@@ -1029,9 +1062,13 @@ int qed_vf_pf_tunnel_param_update(struct qed_hwfn *p_hwfn,
u32 qed_vf_hw_bar_size(struct qed_hwfn *p_hwfn, enum BAR_ID bar_id); u32 qed_vf_hw_bar_size(struct qed_hwfn *p_hwfn, enum BAR_ID bar_id);
/** /**
* @brief - Ask PF to update the MAC address in it's bulletin board * qed_vf_pf_bulletin_update_mac(): Ask PF to update the MAC address in
* it's bulletin board
* *
* @param p_mac - mac address to be updated in bulletin board * @p_hwfn: HW device data.
* @p_mac: mac address to be updated in bulletin board
*
* Return: Int.
*/ */
int qed_vf_pf_bulletin_update_mac(struct qed_hwfn *p_hwfn, u8 *p_mac); int qed_vf_pf_bulletin_update_mac(struct qed_hwfn *p_hwfn, u8 *p_mac);

View File

@@ -2832,10 +2832,13 @@ static void qede_get_eth_tlv_data(void *dev, void *data)
} }
/** /**
* qede_io_error_detected - called when PCI error is detected * qede_io_error_detected(): Called when PCI error is detected
*
* @pdev: Pointer to PCI device * @pdev: Pointer to PCI device
* @state: The current pci connection state * @state: The current pci connection state
* *
*Return: pci_ers_result_t.
*
* This function is called after a PCI bus error affecting * This function is called after a PCI bus error affecting
* this device has been detected. * this device has been detected.
*/ */

View File

@@ -1851,6 +1851,17 @@ static int netsec_of_probe(struct platform_device *pdev,
return err; return err;
} }
/*
* SynQuacer is physically configured with TX and RX delays
* but the standard firmware claimed otherwise for a long
* time, ignore it.
*/
if (of_machine_is_compatible("socionext,developer-box") &&
priv->phy_interface != PHY_INTERFACE_MODE_RGMII_ID) {
dev_warn(&pdev->dev, "Outdated firmware reports incorrect PHY mode, overriding\n");
priv->phy_interface = PHY_INTERFACE_MODE_RGMII_ID;
}
priv->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); priv->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
if (!priv->phy_np) { if (!priv->phy_np) {
dev_err(&pdev->dev, "missing required property 'phy-handle'\n"); dev_err(&pdev->dev, "missing required property 'phy-handle'\n");

View File

@@ -1556,15 +1556,15 @@ static int temac_probe(struct platform_device *pdev)
} }
/* Error handle returned DMA RX and TX interrupts */ /* Error handle returned DMA RX and TX interrupts */
if (lp->rx_irq < 0) { if (lp->rx_irq <= 0) {
if (lp->rx_irq != -EPROBE_DEFER) rc = lp->rx_irq ?: -EINVAL;
dev_err(&pdev->dev, "could not get DMA RX irq\n"); return dev_err_probe(&pdev->dev, rc,
return lp->rx_irq; "could not get DMA RX irq\n");
} }
if (lp->tx_irq < 0) { if (lp->tx_irq <= 0) {
if (lp->tx_irq != -EPROBE_DEFER) rc = lp->tx_irq ?: -EINVAL;
dev_err(&pdev->dev, "could not get DMA TX irq\n"); return dev_err_probe(&pdev->dev, rc,
return lp->tx_irq; "could not get DMA TX irq\n");
} }
if (temac_np) { if (temac_np) {

View File

@@ -617,9 +617,23 @@ static const struct usb_device_id products[] = {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE, | USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD, .idVendor = 0x04DD,
.idProduct = 0x8005, /* A-300 */
ZAURUS_FAKE_INTERFACE,
.driver_info = 0,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x8006, /* B-500/SL-5600 */ .idProduct = 0x8006, /* B-500/SL-5600 */
ZAURUS_MASTER_INTERFACE, ZAURUS_MASTER_INTERFACE,
.driver_info = 0, .driver_info = 0,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x8006, /* B-500/SL-5600 */
ZAURUS_FAKE_INTERFACE,
.driver_info = 0,
}, { }, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE, | USB_DEVICE_ID_MATCH_DEVICE,
@@ -627,6 +641,13 @@ static const struct usb_device_id products[] = {
.idProduct = 0x8007, /* C-700 */ .idProduct = 0x8007, /* C-700 */
ZAURUS_MASTER_INTERFACE, ZAURUS_MASTER_INTERFACE,
.driver_info = 0, .driver_info = 0,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x8007, /* C-700 */
ZAURUS_FAKE_INTERFACE,
.driver_info = 0,
}, { }, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE, | USB_DEVICE_ID_MATCH_DEVICE,

View File

@@ -1771,6 +1771,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
} else if (!info->in || !info->out) } else if (!info->in || !info->out)
status = usbnet_get_endpoints (dev, udev); status = usbnet_get_endpoints (dev, udev);
else { else {
u8 ep_addrs[3] = {
info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0
};
dev->in = usb_rcvbulkpipe (xdev, info->in); dev->in = usb_rcvbulkpipe (xdev, info->in);
dev->out = usb_sndbulkpipe (xdev, info->out); dev->out = usb_sndbulkpipe (xdev, info->out);
if (!(info->flags & FLAG_NO_SETINT)) if (!(info->flags & FLAG_NO_SETINT))
@@ -1780,6 +1784,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
else else
status = 0; status = 0;
if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs))
status = -EINVAL;
} }
if (status >= 0 && dev->status) if (status >= 0 && dev->status)
status = init_status (dev, udev); status = init_status (dev, udev);

View File

@@ -289,9 +289,23 @@ static const struct usb_device_id products [] = {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE, | USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD, .idVendor = 0x04DD,
.idProduct = 0x8005, /* A-300 */
ZAURUS_FAKE_INTERFACE,
.driver_info = (unsigned long)&bogus_mdlm_info,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x8006, /* B-500/SL-5600 */ .idProduct = 0x8006, /* B-500/SL-5600 */
ZAURUS_MASTER_INTERFACE, ZAURUS_MASTER_INTERFACE,
.driver_info = ZAURUS_PXA_INFO, .driver_info = ZAURUS_PXA_INFO,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x8006, /* B-500/SL-5600 */
ZAURUS_FAKE_INTERFACE,
.driver_info = (unsigned long)&bogus_mdlm_info,
}, { }, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE, | USB_DEVICE_ID_MATCH_DEVICE,
@@ -299,6 +313,13 @@ static const struct usb_device_id products [] = {
.idProduct = 0x8007, /* C-700 */ .idProduct = 0x8007, /* C-700 */
ZAURUS_MASTER_INTERFACE, ZAURUS_MASTER_INTERFACE,
.driver_info = ZAURUS_PXA_INFO, .driver_info = ZAURUS_PXA_INFO,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x8007, /* C-700 */
ZAURUS_FAKE_INTERFACE,
.driver_info = (unsigned long)&bogus_mdlm_info,
}, { }, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE, | USB_DEVICE_ID_MATCH_DEVICE,

View File

@@ -123,12 +123,12 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
case MT_EE_5GHZ: case MT_EE_5GHZ:
dev->mphy.cap.has_5ghz = true; dev->mphy.cap.has_5ghz = true;
break; break;
case MT_EE_2GHZ:
dev->mphy.cap.has_2ghz = true;
break;
case MT_EE_DBDC: case MT_EE_DBDC:
dev->dbdc_support = true; dev->dbdc_support = true;
fallthrough; fallthrough;
case MT_EE_2GHZ:
dev->mphy.cap.has_2ghz = true;
break;
default: default:
dev->mphy.cap.has_2ghz = true; dev->mphy.cap.has_2ghz = true;
dev->mphy.cap.has_5ghz = true; dev->mphy.cap.has_5ghz = true;

View File

@@ -717,7 +717,6 @@ struct qeth_card_info {
u16 chid; u16 chid;
u8 ids_valid:1; /* cssid,iid,chid */ u8 ids_valid:1; /* cssid,iid,chid */
u8 dev_addr_is_registered:1; u8 dev_addr_is_registered:1;
u8 open_when_online:1;
u8 promisc_mode:1; u8 promisc_mode:1;
u8 use_v1_blkt:1; u8 use_v1_blkt:1;
u8 is_vm_nic:1; u8 is_vm_nic:1;

View File

@@ -5459,8 +5459,6 @@ int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc,
qeth_clear_ipacmd_list(card); qeth_clear_ipacmd_list(card);
rtnl_lock(); rtnl_lock();
card->info.open_when_online = card->dev->flags & IFF_UP;
dev_close(card->dev);
netif_device_detach(card->dev); netif_device_detach(card->dev);
netif_carrier_off(card->dev); netif_carrier_off(card->dev);
rtnl_unlock(); rtnl_unlock();

View File

@@ -2373,9 +2373,12 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok)
qeth_enable_hw_features(dev); qeth_enable_hw_features(dev);
qeth_l2_enable_brport_features(card); qeth_l2_enable_brport_features(card);
if (card->info.open_when_online) { if (netif_running(dev)) {
card->info.open_when_online = 0; local_bh_disable();
dev_open(dev, NULL); napi_schedule(&card->napi);
/* kick-start the NAPI softirq: */
local_bh_enable();
qeth_l2_set_rx_mode(dev);
} }
rtnl_unlock(); rtnl_unlock();
} }

View File

@@ -2029,9 +2029,11 @@ static int qeth_l3_set_online(struct qeth_card *card, bool carrier_ok)
netif_device_attach(dev); netif_device_attach(dev);
qeth_enable_hw_features(dev); qeth_enable_hw_features(dev);
if (card->info.open_when_online) { if (netif_running(dev)) {
card->info.open_when_online = 0; local_bh_disable();
dev_open(dev, NULL); napi_schedule(&card->napi);
/* kick-start the NAPI softirq: */
local_bh_enable();
} }
rtnl_unlock(); rtnl_unlock();
} }

View File

@@ -534,8 +534,7 @@ static void zfcp_fc_adisc_handler(void *data)
/* re-init to undo drop from zfcp_fc_adisc() */ /* re-init to undo drop from zfcp_fc_adisc() */
port->d_id = ntoh24(adisc_resp->adisc_port_id); port->d_id = ntoh24(adisc_resp->adisc_port_id);
/* port is good, unblock rport without going through erp */ /* port is still good, nothing to do */
zfcp_scsi_schedule_rport_register(port);
out: out:
atomic_andnot(ZFCP_STATUS_PORT_LINK_TEST, &port->status); atomic_andnot(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
put_device(&port->dev); put_device(&port->dev);
@@ -595,9 +594,6 @@ void zfcp_fc_link_test_work(struct work_struct *work)
int retval; int retval;
set_worker_desc("zadisc%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */ set_worker_desc("zadisc%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */
get_device(&port->dev);
port->rport_task = RPORT_DEL;
zfcp_scsi_rport_work(&port->rport_work);
/* only issue one test command at one time per port */ /* only issue one test command at one time per port */
if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST) if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST)

View File

@@ -406,6 +406,7 @@ static void storvsc_on_channel_callback(void *context);
#define STORVSC_FC_MAX_LUNS_PER_TARGET 255 #define STORVSC_FC_MAX_LUNS_PER_TARGET 255
#define STORVSC_FC_MAX_TARGETS 128 #define STORVSC_FC_MAX_TARGETS 128
#define STORVSC_FC_MAX_CHANNELS 8 #define STORVSC_FC_MAX_CHANNELS 8
#define STORVSC_FC_MAX_XFER_SIZE ((u32)(512 * 1024))
#define STORVSC_IDE_MAX_LUNS_PER_TARGET 64 #define STORVSC_IDE_MAX_LUNS_PER_TARGET 64
#define STORVSC_IDE_MAX_TARGETS 1 #define STORVSC_IDE_MAX_TARGETS 1
@@ -2071,6 +2072,9 @@ static int storvsc_probe(struct hv_device *device,
* protecting it from any weird value. * protecting it from any weird value.
*/ */
max_xfer_bytes = round_down(stor_device->max_transfer_bytes, HV_HYP_PAGE_SIZE); max_xfer_bytes = round_down(stor_device->max_transfer_bytes, HV_HYP_PAGE_SIZE);
if (is_fc)
max_xfer_bytes = min(max_xfer_bytes, STORVSC_FC_MAX_XFER_SIZE);
/* max_hw_sectors_kb */ /* max_hw_sectors_kb */
host->max_sectors = max_xfer_bytes >> 9; host->max_sectors = max_xfer_bytes >> 9;
/* /*

View File

@@ -828,8 +828,8 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
"%s: initializing enumeration and init completion for Slave %d\n", "%s: initializing enumeration and init completion for Slave %d\n",
__func__, slave->dev_num); __func__, slave->dev_num);
init_completion(&slave->enumeration_complete); reinit_completion(&slave->enumeration_complete);
init_completion(&slave->initialization_complete); reinit_completion(&slave->initialization_complete);
} else if ((status == SDW_SLAVE_ATTACHED) && } else if ((status == SDW_SLAVE_ATTACHED) &&
(slave->status == SDW_SLAVE_UNATTACHED)) { (slave->status == SDW_SLAVE_UNATTACHED)) {
@@ -837,7 +837,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
"%s: signaling enumeration completion for Slave %d\n", "%s: signaling enumeration completion for Slave %d\n",
__func__, slave->dev_num); __func__, slave->dev_num);
complete(&slave->enumeration_complete); complete_all(&slave->enumeration_complete);
} }
slave->status = status; slave->status = status;
mutex_unlock(&bus->bus_lock); mutex_unlock(&bus->bus_lock);
@@ -1840,7 +1840,19 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
"%s: signaling initialization completion for Slave %d\n", "%s: signaling initialization completion for Slave %d\n",
__func__, slave->dev_num); __func__, slave->dev_num);
complete(&slave->initialization_complete); complete_all(&slave->initialization_complete);
/*
* If the manager became pm_runtime active, the peripherals will be
* restarted and attach, but their pm_runtime status may remain
* suspended. If the 'update_slave_status' callback initiates
* any sort of deferred processing, this processing would not be
* cancelled on pm_runtime suspend.
* To avoid such zombie states, we queue a request to resume.
* This would be a no-op in case the peripheral was being resumed
* by e.g. the ALSA/ASoC framework.
*/
pm_request_resume(&slave->dev);
} }
} }

View File

@@ -4607,7 +4607,7 @@ static void delayed_work(struct work_struct *work)
dout("mdsc delayed_work\n"); dout("mdsc delayed_work\n");
if (mdsc->stopping) if (mdsc->stopping >= CEPH_MDSC_STOPPING_FLUSHED)
return; return;
mutex_lock(&mdsc->mutex); mutex_lock(&mdsc->mutex);
@@ -4786,7 +4786,7 @@ void send_flush_mdlog(struct ceph_mds_session *s)
void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc)
{ {
dout("pre_umount\n"); dout("pre_umount\n");
mdsc->stopping = 1; mdsc->stopping = CEPH_MDSC_STOPPING_BEGIN;
ceph_mdsc_iterate_sessions(mdsc, send_flush_mdlog, true); ceph_mdsc_iterate_sessions(mdsc, send_flush_mdlog, true);
ceph_mdsc_iterate_sessions(mdsc, lock_unlock_session, false); ceph_mdsc_iterate_sessions(mdsc, lock_unlock_session, false);

View File

@@ -370,6 +370,11 @@ struct cap_wait {
int want; int want;
}; };
enum {
CEPH_MDSC_STOPPING_BEGIN = 1,
CEPH_MDSC_STOPPING_FLUSHED = 2,
};
/* /*
* mds client state * mds client state
*/ */

View File

@@ -1227,6 +1227,16 @@ static void ceph_kill_sb(struct super_block *s)
ceph_mdsc_pre_umount(fsc->mdsc); ceph_mdsc_pre_umount(fsc->mdsc);
flush_fs_workqueues(fsc); flush_fs_workqueues(fsc);
/*
* Though the kill_anon_super() will finally trigger the
* sync_filesystem() anyway, we still need to do it here
* and then bump the stage of shutdown to stop the work
* queue as earlier as possible.
*/
sync_filesystem(s);
fsc->mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHED;
kill_anon_super(s); kill_anon_super(s);
fsc->client->extra_mon_dispatch = NULL; fsc->client->extra_mon_dispatch = NULL;

View File

@@ -69,7 +69,7 @@ static int exfat_allocate_bitmap(struct super_block *sb,
} }
sbi->map_sectors = ((need_map_size - 1) >> sbi->map_sectors = ((need_map_size - 1) >>
(sb->s_blocksize_bits)) + 1; (sb->s_blocksize_bits)) + 1;
sbi->vol_amap = kmalloc_array(sbi->map_sectors, sbi->vol_amap = kvmalloc_array(sbi->map_sectors,
sizeof(struct buffer_head *), GFP_KERNEL); sizeof(struct buffer_head *), GFP_KERNEL);
if (!sbi->vol_amap) if (!sbi->vol_amap)
return -ENOMEM; return -ENOMEM;
@@ -84,7 +84,7 @@ static int exfat_allocate_bitmap(struct super_block *sb,
while (j < i) while (j < i)
brelse(sbi->vol_amap[j++]); brelse(sbi->vol_amap[j++]);
kfree(sbi->vol_amap); kvfree(sbi->vol_amap);
sbi->vol_amap = NULL; sbi->vol_amap = NULL;
return -EIO; return -EIO;
} }
@@ -138,7 +138,7 @@ void exfat_free_bitmap(struct exfat_sb_info *sbi)
for (i = 0; i < sbi->map_sectors; i++) for (i = 0; i < sbi->map_sectors; i++)
__brelse(sbi->vol_amap[i]); __brelse(sbi->vol_amap[i]);
kfree(sbi->vol_amap); kvfree(sbi->vol_amap);
} }
int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync) int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync)

View File

@@ -211,7 +211,10 @@ static void exfat_free_namebuf(struct exfat_dentry_namebuf *nb)
exfat_init_namebuf(nb); exfat_init_namebuf(nb);
} }
/* skip iterating emit_dots when dir is empty */ /*
* Before calling dir_emit*(), sbi->s_lock should be released
* because page fault can occur in dir_emit*().
*/
#define ITER_POS_FILLED_DOTS (2) #define ITER_POS_FILLED_DOTS (2)
static int exfat_iterate(struct file *filp, struct dir_context *ctx) static int exfat_iterate(struct file *filp, struct dir_context *ctx)
{ {
@@ -226,11 +229,10 @@ static int exfat_iterate(struct file *filp, struct dir_context *ctx)
int err = 0, fake_offset = 0; int err = 0, fake_offset = 0;
exfat_init_namebuf(nb); exfat_init_namebuf(nb);
mutex_lock(&EXFAT_SB(sb)->s_lock);
cpos = ctx->pos; cpos = ctx->pos;
if (!dir_emit_dots(filp, ctx)) if (!dir_emit_dots(filp, ctx))
goto unlock; goto out;
if (ctx->pos == ITER_POS_FILLED_DOTS) { if (ctx->pos == ITER_POS_FILLED_DOTS) {
cpos = 0; cpos = 0;
@@ -242,16 +244,18 @@ static int exfat_iterate(struct file *filp, struct dir_context *ctx)
/* name buffer should be allocated before use */ /* name buffer should be allocated before use */
err = exfat_alloc_namebuf(nb); err = exfat_alloc_namebuf(nb);
if (err) if (err)
goto unlock; goto out;
get_new: get_new:
mutex_lock(&EXFAT_SB(sb)->s_lock);
if (ei->flags == ALLOC_NO_FAT_CHAIN && cpos >= i_size_read(inode)) if (ei->flags == ALLOC_NO_FAT_CHAIN && cpos >= i_size_read(inode))
goto end_of_dir; goto end_of_dir;
err = exfat_readdir(inode, &cpos, &de); err = exfat_readdir(inode, &cpos, &de);
if (err) { if (err) {
/* /*
* At least we tried to read a sector. Move cpos to next sector * At least we tried to read a sector.
* position (should be aligned). * Move cpos to next sector position (should be aligned).
*/ */
if (err == -EIO) { if (err == -EIO) {
cpos += 1 << (sb->s_blocksize_bits); cpos += 1 << (sb->s_blocksize_bits);
@@ -274,16 +278,10 @@ get_new:
inum = iunique(sb, EXFAT_ROOT_INO); inum = iunique(sb, EXFAT_ROOT_INO);
} }
/*
* Before calling dir_emit(), sb_lock should be released.
* Because page fault can occur in dir_emit() when the size
* of buffer given from user is larger than one page size.
*/
mutex_unlock(&EXFAT_SB(sb)->s_lock); mutex_unlock(&EXFAT_SB(sb)->s_lock);
if (!dir_emit(ctx, nb->lfn, strlen(nb->lfn), inum, if (!dir_emit(ctx, nb->lfn, strlen(nb->lfn), inum,
(de.attr & ATTR_SUBDIR) ? DT_DIR : DT_REG)) (de.attr & ATTR_SUBDIR) ? DT_DIR : DT_REG))
goto out_unlocked; goto out;
mutex_lock(&EXFAT_SB(sb)->s_lock);
ctx->pos = cpos; ctx->pos = cpos;
goto get_new; goto get_new;
@@ -291,9 +289,8 @@ end_of_dir:
if (!cpos && fake_offset) if (!cpos && fake_offset)
cpos = ITER_POS_FILLED_DOTS; cpos = ITER_POS_FILLED_DOTS;
ctx->pos = cpos; ctx->pos = cpos;
unlock:
mutex_unlock(&EXFAT_SB(sb)->s_lock); mutex_unlock(&EXFAT_SB(sb)->s_lock);
out_unlocked: out:
/* /*
* To improve performance, free namebuf after unlock sb_lock. * To improve performance, free namebuf after unlock sb_lock.
* If namebuf is not allocated, this function do nothing * If namebuf is not allocated, this function do nothing

View File

@@ -70,10 +70,7 @@ struct mb_cache;
* second extended-fs super-block data in memory * second extended-fs super-block data in memory
*/ */
struct ext2_sb_info { struct ext2_sb_info {
unsigned long s_frag_size; /* Size of a fragment in bytes */
unsigned long s_frags_per_block;/* Number of fragments per block */
unsigned long s_inodes_per_block;/* Number of inodes per block */ unsigned long s_inodes_per_block;/* Number of inodes per block */
unsigned long s_frags_per_group;/* Number of fragments in a group */
unsigned long s_blocks_per_group;/* Number of blocks in a group */ unsigned long s_blocks_per_group;/* Number of blocks in a group */
unsigned long s_inodes_per_group;/* Number of inodes in a group */ unsigned long s_inodes_per_group;/* Number of inodes in a group */
unsigned long s_itb_per_group; /* Number of inode table blocks per group */ unsigned long s_itb_per_group; /* Number of inode table blocks per group */
@@ -187,15 +184,6 @@ static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb)
#define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size) #define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size)
#define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino) #define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino)
/*
* Macro-instructions used to manage fragments
*/
#define EXT2_MIN_FRAG_SIZE 1024
#define EXT2_MAX_FRAG_SIZE 4096
#define EXT2_MIN_FRAG_LOG_SIZE 10
#define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size)
#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block)
/* /*
* Structure of a blocks group descriptor * Structure of a blocks group descriptor
*/ */

View File

@@ -670,10 +670,9 @@ static int ext2_setup_super (struct super_block * sb,
es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT); es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT);
le16_add_cpu(&es->s_mnt_count, 1); le16_add_cpu(&es->s_mnt_count, 1);
if (test_opt (sb, DEBUG)) if (test_opt (sb, DEBUG))
ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, fs=%lu, gc=%lu, " ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, gc=%lu, "
"bpg=%lu, ipg=%lu, mo=%04lx]", "bpg=%lu, ipg=%lu, mo=%04lx]",
EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
sbi->s_frag_size,
sbi->s_groups_count, sbi->s_groups_count,
EXT2_BLOCKS_PER_GROUP(sb), EXT2_BLOCKS_PER_GROUP(sb),
EXT2_INODES_PER_GROUP(sb), EXT2_INODES_PER_GROUP(sb),
@@ -1012,14 +1011,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
} }
} }
sbi->s_frag_size = EXT2_MIN_FRAG_SIZE <<
le32_to_cpu(es->s_log_frag_size);
if (sbi->s_frag_size == 0)
goto cantfind_ext2;
sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size;
sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb); sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb);
@@ -1045,11 +1037,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount; goto failed_mount;
} }
if (sb->s_blocksize != sbi->s_frag_size) { if (es->s_log_frag_size != es->s_log_block_size) {
ext2_msg(sb, KERN_ERR, ext2_msg(sb, KERN_ERR,
"error: fragsize %lu != blocksize %lu" "error: fragsize log %u != blocksize log %u",
"(not supported yet)", le32_to_cpu(es->s_log_frag_size), sb->s_blocksize_bits);
sbi->s_frag_size, sb->s_blocksize);
goto failed_mount; goto failed_mount;
} }
@@ -1059,12 +1050,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_blocks_per_group); sbi->s_blocks_per_group);
goto failed_mount; goto failed_mount;
} }
if (sbi->s_frags_per_group > sb->s_blocksize * 8) {
ext2_msg(sb, KERN_ERR,
"error: #fragments per group too big: %lu",
sbi->s_frags_per_group);
goto failed_mount;
}
if (sbi->s_inodes_per_group < sbi->s_inodes_per_block || if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
sbi->s_inodes_per_group > sb->s_blocksize * 8) { sbi->s_inodes_per_group > sb->s_blocksize * 8) {
ext2_msg(sb, KERN_ERR, ext2_msg(sb, KERN_ERR,

View File

@@ -1062,12 +1062,28 @@ unsigned long __fdget_raw(unsigned int fd)
return __fget_light(fd, 0); return __fget_light(fd, 0);
} }
/*
* Try to avoid f_pos locking. We only need it if the
* file is marked for FMODE_ATOMIC_POS, and it can be
* accessed multiple ways.
*
* Always do it for directories, because pidfd_getfd()
* can make a file accessible even if it otherwise would
* not be, and for directories this is a correctness
* issue, not a "POSIX requirement".
*/
static inline bool file_needs_f_pos_lock(struct file *file)
{
return (file->f_mode & FMODE_ATOMIC_POS) &&
(file_count(file) > 1 || S_ISDIR(file_inode(file)->i_mode));
}
unsigned long __fdget_pos(unsigned int fd) unsigned long __fdget_pos(unsigned int fd)
{ {
unsigned long v = __fdget(fd); unsigned long v = __fdget(fd);
struct file *file = (struct file *)(v & ~3); struct file *file = (struct file *)(v & ~3);
if (file && (file->f_mode & FMODE_ATOMIC_POS)) { if (file && file_needs_f_pos_lock(file)) {
v |= FDPUT_POS_UNLOCK; v |= FDPUT_POS_UNLOCK;
mutex_lock(&file->f_pos_lock); mutex_lock(&file->f_pos_lock);
} }

View File

@@ -52,7 +52,7 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)
if (!attr->non_res) { if (!attr->non_res) {
lsize = le32_to_cpu(attr->res.data_size); lsize = le32_to_cpu(attr->res.data_size);
le = kmalloc(al_aligned(lsize), GFP_NOFS); le = kmalloc(al_aligned(lsize), GFP_NOFS | __GFP_NOWARN);
if (!le) { if (!le) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
@@ -80,7 +80,7 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)
if (err < 0) if (err < 0)
goto out; goto out;
le = kmalloc(al_aligned(lsize), GFP_NOFS); le = kmalloc(al_aligned(lsize), GFP_NOFS | __GFP_NOWARN);
if (!le) { if (!le) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;

View File

@@ -1128,7 +1128,7 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
lookup_flags |= LOOKUP_IN_ROOT; lookup_flags |= LOOKUP_IN_ROOT;
if (how->resolve & RESOLVE_CACHED) { if (how->resolve & RESOLVE_CACHED) {
/* Don't bother even trying for create/truncate/tmpfile open */ /* Don't bother even trying for create/truncate/tmpfile open */
if (flags & (O_TRUNC | O_CREAT | O_TMPFILE)) if (flags & (O_TRUNC | O_CREAT | __O_TMPFILE))
return -EAGAIN; return -EAGAIN;
lookup_flags |= LOOKUP_CACHED; lookup_flags |= LOOKUP_CACHED;
} }

View File

@@ -862,6 +862,7 @@ int reconfigure_super(struct fs_context *fc)
struct super_block *sb = fc->root->d_sb; struct super_block *sb = fc->root->d_sb;
int retval; int retval;
bool remount_ro = false; bool remount_ro = false;
bool remount_rw = false;
bool force = fc->sb_flags & SB_FORCE; bool force = fc->sb_flags & SB_FORCE;
if (fc->sb_flags_mask & ~MS_RMT_MASK) if (fc->sb_flags_mask & ~MS_RMT_MASK)
@@ -879,7 +880,7 @@ int reconfigure_super(struct fs_context *fc)
bdev_read_only(sb->s_bdev)) bdev_read_only(sb->s_bdev))
return -EACCES; return -EACCES;
#endif #endif
remount_rw = !(fc->sb_flags & SB_RDONLY) && sb_rdonly(sb);
remount_ro = (fc->sb_flags & SB_RDONLY) && !sb_rdonly(sb); remount_ro = (fc->sb_flags & SB_RDONLY) && !sb_rdonly(sb);
} }
@@ -909,6 +910,14 @@ int reconfigure_super(struct fs_context *fc)
if (retval) if (retval)
return retval; return retval;
} }
} else if (remount_rw) {
/*
* We set s_readonly_remount here to protect filesystem's
* reconfigure code from writes from userspace until
* reconfigure finishes.
*/
sb->s_readonly_remount = 1;
smp_wmb();
} }
if (fc->ops->reconfigure) { if (fc->ops->reconfigure) {

View File

@@ -145,6 +145,10 @@ static int alloc_branch(struct inode *inode,
*/ */
parent = block_to_cpu(SYSV_SB(inode->i_sb), branch[n-1].key); parent = block_to_cpu(SYSV_SB(inode->i_sb), branch[n-1].key);
bh = sb_getblk(inode->i_sb, parent); bh = sb_getblk(inode->i_sb, parent);
if (!bh) {
sysv_free_block(inode->i_sb, branch[n].key);
break;
}
lock_buffer(bh); lock_buffer(bh);
memset(bh->b_data, 0, blocksize); memset(bh->b_data, 0, blocksize);
branch[n].bh = bh; branch[n].bh = bh;

View File

@@ -38,7 +38,7 @@ static inline long find_zero(unsigned long mask)
return (mask >> 8) ? byte : byte + 1; return (mask >> 8) ? byte : byte + 1;
} }
static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
{ {
unsigned long rhs = val | c->low_bits; unsigned long rhs = val | c->low_bits;
*data = rhs; *data = rhs;

View File

@@ -17,8 +17,8 @@
#ifdef CONFIG_PM #ifdef CONFIG_PM
extern int dev_pm_set_wake_irq(struct device *dev, int irq); extern int dev_pm_set_wake_irq(struct device *dev, int irq);
extern int dev_pm_set_dedicated_wake_irq(struct device *dev, extern int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq);
int irq); extern int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq);
extern void dev_pm_clear_wake_irq(struct device *dev); extern void dev_pm_clear_wake_irq(struct device *dev);
extern void dev_pm_enable_wake_irq(struct device *dev); extern void dev_pm_enable_wake_irq(struct device *dev);
extern void dev_pm_disable_wake_irq(struct device *dev); extern void dev_pm_disable_wake_irq(struct device *dev);
@@ -35,6 +35,11 @@ static inline int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
return 0; return 0;
} }
static inline int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq)
{
return 0;
}
static inline void dev_pm_clear_wake_irq(struct device *dev) static inline void dev_pm_clear_wake_irq(struct device *dev)
{ {
} }

View File

@@ -268,14 +268,15 @@ static inline dma_addr_t qed_chain_get_pbl_phys(const struct qed_chain *chain)
} }
/** /**
* @brief qed_chain_advance_page - * qed_chain_advance_page(): Advance the next element across pages for a
* linked chain.
* *
* Advance the next element across pages for a linked chain * @p_chain: P_chain.
* @p_next_elem: P_next_elem.
* @idx_to_inc: Idx_to_inc.
* @page_to_inc: page_to_inc.
* *
* @param p_chain * Return: Void.
* @param p_next_elem
* @param idx_to_inc
* @param page_to_inc
*/ */
static inline void static inline void
qed_chain_advance_page(struct qed_chain *p_chain, qed_chain_advance_page(struct qed_chain *p_chain,
@@ -336,12 +337,14 @@ qed_chain_advance_page(struct qed_chain *p_chain,
} while (0) } while (0)
/** /**
* @brief qed_chain_return_produced - * qed_chain_return_produced(): A chain in which the driver "Produces"
* elements should use this API
* to indicate previous produced elements
* are now consumed.
* *
* A chain in which the driver "Produces" elements should use this API * @p_chain: Chain.
* to indicate previous produced elements are now consumed.
* *
* @param p_chain * Return: Void.
*/ */
static inline void qed_chain_return_produced(struct qed_chain *p_chain) static inline void qed_chain_return_produced(struct qed_chain *p_chain)
{ {
@@ -353,15 +356,15 @@ static inline void qed_chain_return_produced(struct qed_chain *p_chain)
} }
/** /**
* @brief qed_chain_produce - * qed_chain_produce(): A chain in which the driver "Produces"
* elements should use this to get a pointer to
* the next element which can be "Produced". It's driver
* responsibility to validate that the chain has room for
* new element.
* *
* A chain in which the driver "Produces" elements should use this to get * @p_chain: Chain.
* a pointer to the next element which can be "Produced". It's driver
* responsibility to validate that the chain has room for new element.
* *
* @param p_chain * Return: void*, a pointer to next element.
*
* @return void*, a pointer to next element
*/ */
static inline void *qed_chain_produce(struct qed_chain *p_chain) static inline void *qed_chain_produce(struct qed_chain *p_chain)
{ {
@@ -395,14 +398,11 @@ static inline void *qed_chain_produce(struct qed_chain *p_chain)
} }
/** /**
* @brief qed_chain_get_capacity - * qed_chain_get_capacity(): Get the maximum number of BDs in chain
* *
* Get the maximum number of BDs in chain * @p_chain: Chain.
* *
* @param p_chain * Return: number of unusable BDs.
* @param num
*
* @return number of unusable BDs
*/ */
static inline u32 qed_chain_get_capacity(struct qed_chain *p_chain) static inline u32 qed_chain_get_capacity(struct qed_chain *p_chain)
{ {
@@ -410,12 +410,14 @@ static inline u32 qed_chain_get_capacity(struct qed_chain *p_chain)
} }
/** /**
* @brief qed_chain_recycle_consumed - * qed_chain_recycle_consumed(): Returns an element which was
* previously consumed;
* Increments producers so they could
* be written to FW.
* *
* Returns an element which was previously consumed; * @p_chain: Chain.
* Increments producers so they could be written to FW.
* *
* @param p_chain * Return: Void.
*/ */
static inline void qed_chain_recycle_consumed(struct qed_chain *p_chain) static inline void qed_chain_recycle_consumed(struct qed_chain *p_chain)
{ {
@@ -427,14 +429,13 @@ static inline void qed_chain_recycle_consumed(struct qed_chain *p_chain)
} }
/** /**
* @brief qed_chain_consume - * qed_chain_consume(): A Chain in which the driver utilizes data written
* by a different source (i.e., FW) should use this to
* access passed buffers.
* *
* A Chain in which the driver utilizes data written by a different source * @p_chain: Chain.
* (i.e., FW) should use this to access passed buffers.
* *
* @param p_chain * Return: void*, a pointer to the next buffer written.
*
* @return void*, a pointer to the next buffer written
*/ */
static inline void *qed_chain_consume(struct qed_chain *p_chain) static inline void *qed_chain_consume(struct qed_chain *p_chain)
{ {
@@ -468,9 +469,11 @@ static inline void *qed_chain_consume(struct qed_chain *p_chain)
} }
/** /**
* @brief qed_chain_reset - Resets the chain to its start state * qed_chain_reset(): Resets the chain to its start state.
* *
* @param p_chain pointer to a previously allocated chain * @p_chain: pointer to a previously allocated chain.
*
* Return Void.
*/ */
static inline void qed_chain_reset(struct qed_chain *p_chain) static inline void qed_chain_reset(struct qed_chain *p_chain)
{ {
@@ -519,13 +522,12 @@ static inline void qed_chain_reset(struct qed_chain *p_chain)
} }
/** /**
* @brief qed_chain_get_last_elem - * qed_chain_get_last_elem(): Returns a pointer to the last element of the
* chain.
* *
* Returns a pointer to the last element of the chain * @p_chain: Chain.
* *
* @param p_chain * Return: void*.
*
* @return void*
*/ */
static inline void *qed_chain_get_last_elem(struct qed_chain *p_chain) static inline void *qed_chain_get_last_elem(struct qed_chain *p_chain)
{ {
@@ -563,10 +565,13 @@ out:
} }
/** /**
* @brief qed_chain_set_prod - sets the prod to the given value * qed_chain_set_prod(): sets the prod to the given value.
* *
* @param prod_idx * @p_chain: Chain.
* @param p_prod_elem * @prod_idx: Prod Idx.
* @p_prod_elem: Prod elem.
*
* Return Void.
*/ */
static inline void qed_chain_set_prod(struct qed_chain *p_chain, static inline void qed_chain_set_prod(struct qed_chain *p_chain,
u32 prod_idx, void *p_prod_elem) u32 prod_idx, void *p_prod_elem)
@@ -610,9 +615,11 @@ static inline void qed_chain_set_prod(struct qed_chain *p_chain,
} }
/** /**
* @brief qed_chain_pbl_zero_mem - set chain memory to 0 * qed_chain_pbl_zero_mem(): set chain memory to 0.
* *
* @param p_chain * @p_chain: Chain.
*
* Return: Void.
*/ */
static inline void qed_chain_pbl_zero_mem(struct qed_chain *p_chain) static inline void qed_chain_pbl_zero_mem(struct qed_chain *p_chain)
{ {

View File

@@ -819,47 +819,47 @@ struct qed_common_cb_ops {
struct qed_selftest_ops { struct qed_selftest_ops {
/** /**
* @brief selftest_interrupt - Perform interrupt test * selftest_interrupt(): Perform interrupt test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*selftest_interrupt)(struct qed_dev *cdev); int (*selftest_interrupt)(struct qed_dev *cdev);
/** /**
* @brief selftest_memory - Perform memory test * selftest_memory(): Perform memory test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*selftest_memory)(struct qed_dev *cdev); int (*selftest_memory)(struct qed_dev *cdev);
/** /**
* @brief selftest_register - Perform register test * selftest_register(): Perform register test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*selftest_register)(struct qed_dev *cdev); int (*selftest_register)(struct qed_dev *cdev);
/** /**
* @brief selftest_clock - Perform clock test * selftest_clock(): Perform clock test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*selftest_clock)(struct qed_dev *cdev); int (*selftest_clock)(struct qed_dev *cdev);
/** /**
* @brief selftest_nvram - Perform nvram test * selftest_nvram(): Perform nvram test.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*selftest_nvram) (struct qed_dev *cdev); int (*selftest_nvram) (struct qed_dev *cdev);
}; };
@@ -927,47 +927,53 @@ struct qed_common_ops {
enum qed_hw_err_type err_type); enum qed_hw_err_type err_type);
/** /**
* @brief can_link_change - can the instance change the link or not * can_link_change(): can the instance change the link or not.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return true if link-change is allowed, false otherwise. * Return: true if link-change is allowed, false otherwise.
*/ */
bool (*can_link_change)(struct qed_dev *cdev); bool (*can_link_change)(struct qed_dev *cdev);
/** /**
* @brief set_link - set links according to params * set_link(): set links according to params.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param params - values used to override the default link configuration * @params: values used to override the default link configuration.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*set_link)(struct qed_dev *cdev, int (*set_link)(struct qed_dev *cdev,
struct qed_link_params *params); struct qed_link_params *params);
/** /**
* @brief get_link - returns the current link state. * get_link(): returns the current link state.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param if_link - structure to be filled with current link configuration. * @if_link: structure to be filled with current link configuration.
*
* Return: Void.
*/ */
void (*get_link)(struct qed_dev *cdev, void (*get_link)(struct qed_dev *cdev,
struct qed_link_output *if_link); struct qed_link_output *if_link);
/** /**
* @brief - drains chip in case Tx completions fail to arrive due to pause. * drain(): drains chip in case Tx completions fail to arrive due to pause.
* *
* @param cdev * @cdev: Qed dev pointer.
*
* Return: Int.
*/ */
int (*drain)(struct qed_dev *cdev); int (*drain)(struct qed_dev *cdev);
/** /**
* @brief update_msglvl - update module debug level * update_msglvl(): update module debug level.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param dp_module * @dp_module: Debug module.
* @param dp_level * @dp_level: Debug level.
*
* Return: Void.
*/ */
void (*update_msglvl)(struct qed_dev *cdev, void (*update_msglvl)(struct qed_dev *cdev,
u32 dp_module, u32 dp_module,
@@ -981,70 +987,73 @@ struct qed_common_ops {
struct qed_chain *p_chain); struct qed_chain *p_chain);
/** /**
* @brief nvm_flash - Flash nvm data. * nvm_flash(): Flash nvm data.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param name - file containing the data * @name: file containing the data.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*nvm_flash)(struct qed_dev *cdev, const char *name); int (*nvm_flash)(struct qed_dev *cdev, const char *name);
/** /**
* @brief nvm_get_image - reads an entire image from nvram * nvm_get_image(): reads an entire image from nvram.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param type - type of the request nvram image * @type: type of the request nvram image.
* @param buf - preallocated buffer to fill with the image * @buf: preallocated buffer to fill with the image.
* @param len - length of the allocated buffer * @len: length of the allocated buffer.
* *
* @return 0 on success, error otherwise * Return: 0 on success, error otherwise.
*/ */
int (*nvm_get_image)(struct qed_dev *cdev, int (*nvm_get_image)(struct qed_dev *cdev,
enum qed_nvm_images type, u8 *buf, u16 len); enum qed_nvm_images type, u8 *buf, u16 len);
/** /**
* @brief set_coalesce - Configure Rx coalesce value in usec * set_coalesce(): Configure Rx coalesce value in usec.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param rx_coal - Rx coalesce value in usec * @rx_coal: Rx coalesce value in usec.
* @param tx_coal - Tx coalesce value in usec * @tx_coal: Tx coalesce value in usec.
* @param qid - Queue index * @handle: Handle.
* @param sb_id - Status Block Id
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*set_coalesce)(struct qed_dev *cdev, int (*set_coalesce)(struct qed_dev *cdev,
u16 rx_coal, u16 tx_coal, void *handle); u16 rx_coal, u16 tx_coal, void *handle);
/** /**
* @brief set_led - Configure LED mode * set_led() - Configure LED mode.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param mode - LED mode * @mode: LED mode.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*set_led)(struct qed_dev *cdev, int (*set_led)(struct qed_dev *cdev,
enum qed_led_mode mode); enum qed_led_mode mode);
/** /**
* @brief attn_clr_enable - Prevent attentions from being reasserted * attn_clr_enable(): Prevent attentions from being reasserted.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param clr_enable * @clr_enable: Clear enable.
*
* Return: Void.
*/ */
void (*attn_clr_enable)(struct qed_dev *cdev, bool clr_enable); void (*attn_clr_enable)(struct qed_dev *cdev, bool clr_enable);
/** /**
* @brief db_recovery_add - add doorbell information to the doorbell * db_recovery_add(): add doorbell information to the doorbell
* recovery mechanism. * recovery mechanism.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param db_addr - doorbell address * @db_addr: Doorbell address.
* @param db_data - address of where db_data is stored * @db_data: Dddress of where db_data is stored.
* @param db_is_32b - doorbell is 32b pr 64b * @db_width: Doorbell is 32b or 64b.
* @param db_is_user - doorbell recovery addresses are user or kernel space * @db_space: Doorbell recovery addresses are user or kernel space.
*
* Return: Int.
*/ */
int (*db_recovery_add)(struct qed_dev *cdev, int (*db_recovery_add)(struct qed_dev *cdev,
void __iomem *db_addr, void __iomem *db_addr,
@@ -1053,114 +1062,130 @@ struct qed_common_ops {
enum qed_db_rec_space db_space); enum qed_db_rec_space db_space);
/** /**
* @brief db_recovery_del - remove doorbell information from the doorbell * db_recovery_del(): remove doorbell information from the doorbell
* recovery mechanism. db_data serves as key (db_addr is not unique). * recovery mechanism. db_data serves as key (db_addr is not unique).
* *
* @param cdev * @cdev: Qed dev pointer.
* @param db_addr - doorbell address * @db_addr: Doorbell address.
* @param db_data - address where db_data is stored. Serves as key for the * @db_data: Address where db_data is stored. Serves as key for the
* entry to delete. * entry to delete.
*
* Return: Int.
*/ */
int (*db_recovery_del)(struct qed_dev *cdev, int (*db_recovery_del)(struct qed_dev *cdev,
void __iomem *db_addr, void *db_data); void __iomem *db_addr, void *db_data);
/** /**
* @brief recovery_process - Trigger a recovery process * recovery_process(): Trigger a recovery process.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*recovery_process)(struct qed_dev *cdev); int (*recovery_process)(struct qed_dev *cdev);
/** /**
* @brief recovery_prolog - Execute the prolog operations of a recovery process * recovery_prolog(): Execute the prolog operations of a recovery process.
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*recovery_prolog)(struct qed_dev *cdev); int (*recovery_prolog)(struct qed_dev *cdev);
/** /**
* @brief update_drv_state - API to inform the change in the driver state. * update_drv_state(): API to inform the change in the driver state.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param active * @active: Active
* *
* Return: Int.
*/ */
int (*update_drv_state)(struct qed_dev *cdev, bool active); int (*update_drv_state)(struct qed_dev *cdev, bool active);
/** /**
* @brief update_mac - API to inform the change in the mac address * update_mac(): API to inform the change in the mac address.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param mac * @mac: MAC.
* *
* Return: Int.
*/ */
int (*update_mac)(struct qed_dev *cdev, u8 *mac); int (*update_mac)(struct qed_dev *cdev, u8 *mac);
/** /**
* @brief update_mtu - API to inform the change in the mtu * update_mtu(): API to inform the change in the mtu.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param mtu * @mtu: MTU.
* *
* Return: Int.
*/ */
int (*update_mtu)(struct qed_dev *cdev, u16 mtu); int (*update_mtu)(struct qed_dev *cdev, u16 mtu);
/** /**
* @brief update_wol - update of changes in the WoL configuration * update_wol(): Update of changes in the WoL configuration.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param enabled - true iff WoL should be enabled. * @enabled: true iff WoL should be enabled.
*
* Return: Int.
*/ */
int (*update_wol) (struct qed_dev *cdev, bool enabled); int (*update_wol) (struct qed_dev *cdev, bool enabled);
/** /**
* @brief read_module_eeprom * read_module_eeprom(): Read EEPROM.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param buf - buffer * @buf: buffer.
* @param dev_addr - PHY device memory region * @dev_addr: PHY device memory region.
* @param offset - offset into eeprom contents to be read * @offset: offset into eeprom contents to be read.
* @param len - buffer length, i.e., max bytes to be read * @len: buffer length, i.e., max bytes to be read.
*
* Return: Int.
*/ */
int (*read_module_eeprom)(struct qed_dev *cdev, int (*read_module_eeprom)(struct qed_dev *cdev,
char *buf, u8 dev_addr, u32 offset, u32 len); char *buf, u8 dev_addr, u32 offset, u32 len);
/** /**
* @brief get_affin_hwfn_idx * get_affin_hwfn_idx(): Get affine HW function.
* *
* @param cdev * @cdev: Qed dev pointer.
*
* Return: u8.
*/ */
u8 (*get_affin_hwfn_idx)(struct qed_dev *cdev); u8 (*get_affin_hwfn_idx)(struct qed_dev *cdev);
/** /**
* @brief read_nvm_cfg - Read NVM config attribute value. * read_nvm_cfg(): Read NVM config attribute value.
* @param cdev
* @param buf - buffer
* @param cmd - NVM CFG command id
* @param entity_id - Entity id
* *
* @cdev: Qed dev pointer.
* @buf: Buffer.
* @cmd: NVM CFG command id.
* @entity_id: Entity id.
*
* Return: Int.
*/ */
int (*read_nvm_cfg)(struct qed_dev *cdev, u8 **buf, u32 cmd, int (*read_nvm_cfg)(struct qed_dev *cdev, u8 **buf, u32 cmd,
u32 entity_id); u32 entity_id);
/** /**
* @brief read_nvm_cfg - Read NVM config attribute value. * read_nvm_cfg_len(): Read NVM config attribute value.
* @param cdev
* @param cmd - NVM CFG command id
* *
* @return config id length, 0 on error. * @cdev: Qed dev pointer.
* @cmd: NVM CFG command id.
*
* Return: config id length, 0 on error.
*/ */
int (*read_nvm_cfg_len)(struct qed_dev *cdev, u32 cmd); int (*read_nvm_cfg_len)(struct qed_dev *cdev, u32 cmd);
/** /**
* @brief set_grc_config - Configure value for grc config id. * set_grc_config(): Configure value for grc config id.
* @param cdev
* @param cfg_id - grc config id
* @param val - grc config value
* *
* @cdev: Qed dev pointer.
* @cfg_id: grc config id
* @val: grc config value
*
* Return: Int.
*/ */
int (*set_grc_config)(struct qed_dev *cdev, u32 cfg_id, u32 val); int (*set_grc_config)(struct qed_dev *cdev, u32 cfg_id, u32 val);
@@ -1397,18 +1422,16 @@ static inline u16 qed_sb_update_sb_idx(struct qed_sb_info *sb_info)
} }
/** /**
* qed_sb_ack(): This function creates an update command for interrupts
* that is written to the IGU.
* *
* @brief This function creates an update command for interrupts that is * @sb_info: This is the structure allocated and
* written to the IGU. * initialized per status block. Assumption is
* that it was initialized using qed_sb_init
* @int_cmd: Enable/Disable/Nop
* @upd_flg: Whether igu consumer should be updated.
* *
* @param sb_info - This is the structure allocated and * Return: inline void.
* initialized per status block. Assumption is
* that it was initialized using qed_sb_init
* @param int_cmd - Enable/Disable/Nop
* @param upd_flg - whether igu consumer should be
* updated.
*
* @return inline void
*/ */
static inline void qed_sb_ack(struct qed_sb_info *sb_info, static inline void qed_sb_ack(struct qed_sb_info *sb_info,
enum igu_int_cmd int_cmd, enum igu_int_cmd int_cmd,

View File

@@ -182,7 +182,7 @@ struct qed_iscsi_cb_ops {
* @param stats - pointer to struck that would be filled * @param stats - pointer to struck that would be filled
* we stats * we stats
* @return 0 on success, error otherwise. * @return 0 on success, error otherwise.
* @change_mac Change MAC of interface * @change_mac: Change MAC of interface
* @param cdev * @param cdev
* @param handle - the connection handle. * @param handle - the connection handle.
* @param mac - new MAC to configure. * @param mac - new MAC to configure.

View File

@@ -208,57 +208,57 @@ enum qed_ll2_xmit_flags {
struct qed_ll2_ops { struct qed_ll2_ops {
/** /**
* @brief start - initializes ll2 * start(): Initializes ll2.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param params - protocol driver configuration for the ll2. * @params: Protocol driver configuration for the ll2.
* *
* @return 0 on success, otherwise error value. * Return: 0 on success, otherwise error value.
*/ */
int (*start)(struct qed_dev *cdev, struct qed_ll2_params *params); int (*start)(struct qed_dev *cdev, struct qed_ll2_params *params);
/** /**
* @brief stop - stops the ll2 * stop(): Stops the ll2
* *
* @param cdev * @cdev: Qed dev pointer.
* *
* @return 0 on success, otherwise error value. * Return: 0 on success, otherwise error value.
*/ */
int (*stop)(struct qed_dev *cdev); int (*stop)(struct qed_dev *cdev);
/** /**
* @brief start_xmit - transmits an skb over the ll2 interface * start_xmit(): Transmits an skb over the ll2 interface
* *
* @param cdev * @cdev: Qed dev pointer.
* @param skb * @skb: SKB.
* @param xmit_flags - Transmit options defined by the enum qed_ll2_xmit_flags. * @xmit_flags: Transmit options defined by the enum qed_ll2_xmit_flags.
* *
* @return 0 on success, otherwise error value. * Return: 0 on success, otherwise error value.
*/ */
int (*start_xmit)(struct qed_dev *cdev, struct sk_buff *skb, int (*start_xmit)(struct qed_dev *cdev, struct sk_buff *skb,
unsigned long xmit_flags); unsigned long xmit_flags);
/** /**
* @brief register_cb_ops - protocol driver register the callback for Rx/Tx * register_cb_ops(): Protocol driver register the callback for Rx/Tx
* packets. Should be called before `start'. * packets. Should be called before `start'.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param cookie - to be passed to the callback functions. * @cookie: to be passed to the callback functions.
* @param ops - the callback functions to register for Rx / Tx. * @ops: the callback functions to register for Rx / Tx.
* *
* @return 0 on success, otherwise error value. * Return: 0 on success, otherwise error value.
*/ */
void (*register_cb_ops)(struct qed_dev *cdev, void (*register_cb_ops)(struct qed_dev *cdev,
const struct qed_ll2_cb_ops *ops, const struct qed_ll2_cb_ops *ops,
void *cookie); void *cookie);
/** /**
* @brief get LL2 related statistics * get_stats(): Get LL2 related statistics.
* *
* @param cdev * @cdev: Qed dev pointer.
* @param stats - pointer to struct that would be filled with stats * @stats: Pointer to struct that would be filled with stats.
* *
* @return 0 on success, error otherwise. * Return: 0 on success, error otherwise.
*/ */
int (*get_stats)(struct qed_dev *cdev, struct qed_ll2_stats *stats); int (*get_stats)(struct qed_dev *cdev, struct qed_ll2_stats *stats);
}; };

View File

@@ -171,6 +171,23 @@ struct nvmetcp_task_params {
* @param dest_port * @param dest_port
* @clear_all_filters: Clear all filters. * @clear_all_filters: Clear all filters.
* @param cdev * @param cdev
* @init_read_io: Init read IO.
* @task_params
* @cmd_pdu_header
* @nvme_cmd
* @sgl_task_params
* @init_write_io: Init write IO.
* @task_params
* @cmd_pdu_header
* @nvme_cmd
* @sgl_task_params
* @init_icreq_exchange: Exchange ICReq.
* @task_params
* @init_conn_req_pdu_hdr
* @tx_sgl_task_params
* @rx_sgl_task_params
* @init_task_cleanup: Init task cleanup.
* @task_params
*/ */
struct qed_nvmetcp_ops { struct qed_nvmetcp_ops {
const struct qed_common_ops *common; const struct qed_common_ops *common;

View File

@@ -497,12 +497,12 @@ static inline void vxlan_flag_attr_error(int attrtype,
} }
static inline bool vxlan_fdb_nh_path_select(struct nexthop *nh, static inline bool vxlan_fdb_nh_path_select(struct nexthop *nh,
int hash, u32 hash,
struct vxlan_rdst *rdst) struct vxlan_rdst *rdst)
{ {
struct fib_nh_common *nhc; struct fib_nh_common *nhc;
nhc = nexthop_path_fdb_result(nh, hash); nhc = nexthop_path_fdb_result(nh, hash >> 1);
if (unlikely(!nhc)) if (unlikely(!nhc))
return false; return false;

View File

@@ -7802,12 +7802,21 @@ static int io_run_task_work_sig(void)
return -EINTR; return -EINTR;
} }
static bool current_pending_io(void)
{
struct io_uring_task *tctx = current->io_uring;
if (!tctx)
return false;
return percpu_counter_read_positive(&tctx->inflight);
}
/* when returns >0, the caller should retry */ /* when returns >0, the caller should retry */
static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx, static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
struct io_wait_queue *iowq, struct io_wait_queue *iowq,
ktime_t *timeout) ktime_t *timeout)
{ {
int token, ret; int io_wait, ret;
/* make sure we run task_work before checking for signals */ /* make sure we run task_work before checking for signals */
ret = io_run_task_work_sig(); ret = io_run_task_work_sig();
@@ -7818,15 +7827,17 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
return 1; return 1;
/* /*
* Use io_schedule_prepare/finish, so cpufreq can take into account * Mark us as being in io_wait if we have pending requests, so cpufreq
* that the task is waiting for IO - turns out to be important for low * can take into account that the task is waiting for IO - turns out
* QD IO. * to be important for low QD IO.
*/ */
token = io_schedule_prepare(); io_wait = current->in_iowait;
if (current_pending_io())
current->in_iowait = 1;
ret = 1; ret = 1;
if (!schedule_hrtimeout(timeout, HRTIMER_MODE_ABS)) if (!schedule_hrtimeout(timeout, HRTIMER_MODE_ABS))
ret = -ETIME; ret = -ETIME;
io_schedule_finish(token); current->in_iowait = io_wait;
return ret; return ret;
} }

View File

@@ -26,6 +26,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/completion.h>
#include <trace/events/xdp.h> #include <trace/events/xdp.h>
#include <linux/netdevice.h> /* netif_receive_skb_list */ #include <linux/netdevice.h> /* netif_receive_skb_list */
@@ -70,6 +71,7 @@ struct bpf_cpu_map_entry {
struct rcu_head rcu; struct rcu_head rcu;
struct work_struct kthread_stop_wq; struct work_struct kthread_stop_wq;
struct completion kthread_running;
}; };
struct bpf_cpu_map { struct bpf_cpu_map {
@@ -133,11 +135,17 @@ static void __cpu_map_ring_cleanup(struct ptr_ring *ring)
* invoked cpu_map_kthread_stop(). Catch any broken behaviour * invoked cpu_map_kthread_stop(). Catch any broken behaviour
* gracefully and warn once. * gracefully and warn once.
*/ */
struct xdp_frame *xdpf; void *ptr;
while ((xdpf = ptr_ring_consume(ring))) while ((ptr = ptr_ring_consume(ring))) {
if (WARN_ON_ONCE(xdpf)) WARN_ON_ONCE(1);
xdp_return_frame(xdpf); if (unlikely(__ptr_test_bit(0, &ptr))) {
__ptr_clear_bit(0, &ptr);
kfree_skb(ptr);
continue;
}
xdp_return_frame(ptr);
}
} }
static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu) static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu)
@@ -157,7 +165,6 @@ static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu)
static void cpu_map_kthread_stop(struct work_struct *work) static void cpu_map_kthread_stop(struct work_struct *work)
{ {
struct bpf_cpu_map_entry *rcpu; struct bpf_cpu_map_entry *rcpu;
int err;
rcpu = container_of(work, struct bpf_cpu_map_entry, kthread_stop_wq); rcpu = container_of(work, struct bpf_cpu_map_entry, kthread_stop_wq);
@@ -167,14 +174,7 @@ static void cpu_map_kthread_stop(struct work_struct *work)
rcu_barrier(); rcu_barrier();
/* kthread_stop will wake_up_process and wait for it to complete */ /* kthread_stop will wake_up_process and wait for it to complete */
err = kthread_stop(rcpu->kthread); kthread_stop(rcpu->kthread);
if (err) {
/* kthread_stop may be called before cpu_map_kthread_run
* is executed, so we need to release the memory related
* to rcpu.
*/
put_cpu_map_entry(rcpu);
}
} }
static void cpu_map_bpf_prog_run_skb(struct bpf_cpu_map_entry *rcpu, static void cpu_map_bpf_prog_run_skb(struct bpf_cpu_map_entry *rcpu,
@@ -302,11 +302,11 @@ static int cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames,
return nframes; return nframes;
} }
static int cpu_map_kthread_run(void *data) static int cpu_map_kthread_run(void *data)
{ {
struct bpf_cpu_map_entry *rcpu = data; struct bpf_cpu_map_entry *rcpu = data;
complete(&rcpu->kthread_running);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
/* When kthread gives stop order, then rcpu have been disconnected /* When kthread gives stop order, then rcpu have been disconnected
@@ -469,6 +469,7 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value,
goto free_ptr_ring; goto free_ptr_ring;
/* Setup kthread */ /* Setup kthread */
init_completion(&rcpu->kthread_running);
rcpu->kthread = kthread_create_on_node(cpu_map_kthread_run, rcpu, numa, rcpu->kthread = kthread_create_on_node(cpu_map_kthread_run, rcpu, numa,
"cpumap/%d/map:%d", cpu, "cpumap/%d/map:%d", cpu,
map->id); map->id);
@@ -482,6 +483,12 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value,
kthread_bind(rcpu->kthread, cpu); kthread_bind(rcpu->kthread, cpu);
wake_up_process(rcpu->kthread); wake_up_process(rcpu->kthread);
/* Make sure kthread has been running, so kthread_stop() will not
* stop the kthread prematurely and all pending frames or skbs
* will be handled by the kthread before kthread_stop() returns.
*/
wait_for_completion(&rcpu->kthread_running);
return rcpu; return rcpu;
free_prog: free_prog:

View File

@@ -1224,6 +1224,11 @@ static int perf_mux_hrtimer_restart(struct perf_cpu_context *cpuctx)
return 0; return 0;
} }
static int perf_mux_hrtimer_restart_ipi(void *arg)
{
return perf_mux_hrtimer_restart(arg);
}
void perf_pmu_disable(struct pmu *pmu) void perf_pmu_disable(struct pmu *pmu)
{ {
int *count = this_cpu_ptr(pmu->pmu_disable_count); int *count = this_cpu_ptr(pmu->pmu_disable_count);
@@ -11138,8 +11143,7 @@ perf_event_mux_interval_ms_store(struct device *dev,
cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * timer); cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * timer);
cpu_function_call(cpu, cpu_function_call(cpu, perf_mux_hrtimer_restart_ipi, cpuctx);
(remote_function_f)perf_mux_hrtimer_restart, cpuctx);
} }
cpus_read_unlock(); cpus_read_unlock();
mutex_unlock(&mux_interval_mutex); mutex_unlock(&mux_interval_mutex);

View File

@@ -662,7 +662,6 @@ static DEFINE_PER_CPU(struct bpf_trace_sample_data, bpf_misc_sds);
u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy) void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy)
{ {
int nest_level = this_cpu_inc_return(bpf_event_output_nest_level);
struct perf_raw_frag frag = { struct perf_raw_frag frag = {
.copy = ctx_copy, .copy = ctx_copy,
.size = ctx_size, .size = ctx_size,
@@ -679,8 +678,12 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
}; };
struct perf_sample_data *sd; struct perf_sample_data *sd;
struct pt_regs *regs; struct pt_regs *regs;
int nest_level;
u64 ret; u64 ret;
preempt_disable();
nest_level = this_cpu_inc_return(bpf_event_output_nest_level);
if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(bpf_misc_sds.sds))) { if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(bpf_misc_sds.sds))) {
ret = -EBUSY; ret = -EBUSY;
goto out; goto out;
@@ -695,6 +698,7 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
ret = __bpf_perf_event_output(regs, map, flags, sd); ret = __bpf_perf_event_output(regs, map, flags, sd);
out: out:
this_cpu_dec(bpf_event_output_nest_level); this_cpu_dec(bpf_event_output_nest_level);
preempt_enable();
return ret; return ret;
} }

View File

@@ -3330,17 +3330,24 @@ static int linger_reg_commit_wait(struct ceph_osd_linger_request *lreq)
int ret; int ret;
dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id); dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
ret = wait_for_completion_interruptible(&lreq->reg_commit_wait); ret = wait_for_completion_killable(&lreq->reg_commit_wait);
return ret ?: lreq->reg_commit_error; return ret ?: lreq->reg_commit_error;
} }
static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq) static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq,
unsigned long timeout)
{ {
int ret; long left;
dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id); dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id);
ret = wait_for_completion_interruptible(&lreq->notify_finish_wait); left = wait_for_completion_killable_timeout(&lreq->notify_finish_wait,
return ret ?: lreq->notify_finish_error; ceph_timeout_jiffies(timeout));
if (left <= 0)
left = left ?: -ETIMEDOUT;
else
left = lreq->notify_finish_error; /* completed */
return left;
} }
/* /*
@@ -4890,7 +4897,8 @@ int ceph_osdc_notify(struct ceph_osd_client *osdc,
linger_submit(lreq); linger_submit(lreq);
ret = linger_reg_commit_wait(lreq); ret = linger_reg_commit_wait(lreq);
if (!ret) if (!ret)
ret = linger_notify_finish_wait(lreq); ret = linger_notify_finish_wait(lreq,
msecs_to_jiffies(2 * timeout * MSEC_PER_SEC));
else else
dout("lreq %p failed to initiate notify %d\n", lreq, ret); dout("lreq %p failed to initiate notify %d\n", lreq, ret);

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