mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma updates from Jason Gunthorpe:
"Lighter that normal, but the now usual collection of driver fixes and
small improvements:
- Small fixes and minor improvements to cxgb4, bnxt_re, rxe, srp,
efa, cxgb4
- Update mlx4 to use the new umem APIs, avoiding direct use of
scatterlist
- Support ROCEv2 in erdma
- Remove various uncalled functions, constify bin_attribute
- Provide core infrastructure to catch netdev events and route them
to drivers, consolidating duplicated driver code
- Fix rare race condition crashes in mlx5 ODP flows"
* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (63 commits)
RDMA/mlx5: Fix implicit ODP use after free
RDMA/mlx5: Fix a race for an ODP MR which leads to CQE with error
RDMA/qib: Constify 'struct bin_attribute'
RDMA/hfi1: Constify 'struct bin_attribute'
RDMA/rxe: Fix the warning "__rxe_cleanup+0x12c/0x170 [rdma_rxe]"
RDMA/cxgb4: Notify rdma stack for IB_EVENT_QP_LAST_WQE_REACHED event
RDMA/bnxt_re: Allocate dev_attr information dynamically
RDMA/bnxt_re: Pass the context for ulp_irq_stop
RDMA/bnxt_re: Add support to handle DCB_CONFIG_CHANGE event
RDMA/bnxt_re: Query firmware defaults of CC params during probe
RDMA/bnxt_re: Add Async event handling support
bnxt_en: Add ULP call to notify async events
RDMA/mlx5: Fix indirect mkey ODP page count
MAINTAINERS: Update the bnxt_re maintainers
RDMA/hns: Clean up the legacy CONFIG_INFINIBAND_HNS
RDMA/rtrs: Add missing deinit() call
RDMA/efa: Align interrupt related fields to same type
RDMA/bnxt_re: Fix to drop reference to the mmap entry in case of error
RDMA/mlx5: Fix link status down event for MPV
RDMA/erdma: Support create_ah/destroy_ah in non-sleepable contexts
...
This commit is contained in:
@@ -4800,6 +4800,7 @@ F: drivers/scsi/mpi3mr/
|
||||
|
||||
BROADCOM NETXTREME-E ROCE DRIVER
|
||||
M: Selvin Xavier <selvin.xavier@broadcom.com>
|
||||
M: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.broadcom.com
|
||||
|
||||
@@ -1127,41 +1127,6 @@ err:
|
||||
}
|
||||
EXPORT_SYMBOL(ib_find_cached_pkey);
|
||||
|
||||
int ib_find_exact_cached_pkey(struct ib_device *device, u32 port_num,
|
||||
u16 pkey, u16 *index)
|
||||
{
|
||||
struct ib_pkey_cache *cache;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
int ret = -ENOENT;
|
||||
|
||||
if (!rdma_is_port_valid(device, port_num))
|
||||
return -EINVAL;
|
||||
|
||||
read_lock_irqsave(&device->cache_lock, flags);
|
||||
|
||||
cache = device->port_data[port_num].cache.pkey;
|
||||
if (!cache) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
*index = -1;
|
||||
|
||||
for (i = 0; i < cache->table_len; ++i)
|
||||
if (cache->table[i] == pkey) {
|
||||
*index = i;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
err:
|
||||
read_unlock_irqrestore(&device->cache_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_find_exact_cached_pkey);
|
||||
|
||||
int ib_get_cached_lmc(struct ib_device *device, u32 port_num, u8 *lmc)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
@@ -209,23 +209,6 @@ static void __ibdev_printk(const char *level, const struct ib_device *ibdev,
|
||||
printk("%s(NULL ib_device): %pV", level, vaf);
|
||||
}
|
||||
|
||||
void ibdev_printk(const char *level, const struct ib_device *ibdev,
|
||||
const char *format, ...)
|
||||
{
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
|
||||
vaf.fmt = format;
|
||||
vaf.va = &args;
|
||||
|
||||
__ibdev_printk(level, ibdev, &vaf);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
EXPORT_SYMBOL(ibdev_printk);
|
||||
|
||||
#define define_ibdev_printk_level(func, level) \
|
||||
void func(const struct ib_device *ibdev, const char *fmt, ...) \
|
||||
{ \
|
||||
@@ -2295,6 +2278,33 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev,
|
||||
}
|
||||
EXPORT_SYMBOL(ib_device_get_netdev);
|
||||
|
||||
/**
|
||||
* ib_query_netdev_port - Query the port number of a net_device
|
||||
* associated with an ibdev
|
||||
* @ibdev: IB device
|
||||
* @ndev: Network device
|
||||
* @port: IB port the net_device is connected to
|
||||
*/
|
||||
int ib_query_netdev_port(struct ib_device *ibdev, struct net_device *ndev,
|
||||
u32 *port)
|
||||
{
|
||||
struct net_device *ib_ndev;
|
||||
u32 port_num;
|
||||
|
||||
rdma_for_each_port(ibdev, port_num) {
|
||||
ib_ndev = ib_device_get_netdev(ibdev, port_num);
|
||||
if (ndev == ib_ndev) {
|
||||
*port = port_num;
|
||||
dev_put(ib_ndev);
|
||||
return 0;
|
||||
}
|
||||
dev_put(ib_ndev);
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_query_netdev_port);
|
||||
|
||||
/**
|
||||
* ib_device_get_by_netdev - Find an IB device associated with a netdev
|
||||
* @ndev: netdev to locate
|
||||
@@ -2761,6 +2771,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
|
||||
SET_DEVICE_OP(dev_ops, set_vf_guid);
|
||||
SET_DEVICE_OP(dev_ops, set_vf_link_state);
|
||||
SET_DEVICE_OP(dev_ops, ufile_hw_cleanup);
|
||||
SET_DEVICE_OP(dev_ops, report_port_event);
|
||||
|
||||
SET_OBJ_SIZE(dev_ops, ib_ah);
|
||||
SET_OBJ_SIZE(dev_ops, ib_counters);
|
||||
@@ -2854,11 +2865,62 @@ static const struct rdma_nl_cbs ibnl_ls_cb_table[RDMA_NL_LS_NUM_OPS] = {
|
||||
},
|
||||
};
|
||||
|
||||
void ib_dispatch_port_state_event(struct ib_device *ibdev, struct net_device *ndev)
|
||||
{
|
||||
enum ib_port_state curr_state;
|
||||
struct ib_event ibevent = {};
|
||||
u32 port;
|
||||
|
||||
if (ib_query_netdev_port(ibdev, ndev, &port))
|
||||
return;
|
||||
|
||||
curr_state = ib_get_curr_port_state(ndev);
|
||||
|
||||
write_lock_irq(&ibdev->cache_lock);
|
||||
if (ibdev->port_data[port].cache.last_port_state == curr_state) {
|
||||
write_unlock_irq(&ibdev->cache_lock);
|
||||
return;
|
||||
}
|
||||
ibdev->port_data[port].cache.last_port_state = curr_state;
|
||||
write_unlock_irq(&ibdev->cache_lock);
|
||||
|
||||
ibevent.event = (curr_state == IB_PORT_DOWN) ?
|
||||
IB_EVENT_PORT_ERR : IB_EVENT_PORT_ACTIVE;
|
||||
ibevent.device = ibdev;
|
||||
ibevent.element.port_num = port;
|
||||
ib_dispatch_event(&ibevent);
|
||||
}
|
||||
EXPORT_SYMBOL(ib_dispatch_port_state_event);
|
||||
|
||||
static void handle_port_event(struct net_device *ndev, unsigned long event)
|
||||
{
|
||||
struct ib_device *ibdev;
|
||||
|
||||
/* Currently, link events in bonding scenarios are still
|
||||
* reported by drivers that support bonding.
|
||||
*/
|
||||
if (netif_is_lag_master(ndev) || netif_is_lag_port(ndev))
|
||||
return;
|
||||
|
||||
ibdev = ib_device_get_by_netdev(ndev, RDMA_DRIVER_UNKNOWN);
|
||||
if (!ibdev)
|
||||
return;
|
||||
|
||||
if (ibdev->ops.report_port_event) {
|
||||
ibdev->ops.report_port_event(ibdev, ndev, event);
|
||||
goto put_ibdev;
|
||||
}
|
||||
|
||||
ib_dispatch_port_state_event(ibdev, ndev);
|
||||
|
||||
put_ibdev:
|
||||
ib_device_put(ibdev);
|
||||
};
|
||||
|
||||
static int ib_netdevice_event(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
|
||||
struct net_device *ib_ndev;
|
||||
struct ib_device *ibdev;
|
||||
u32 port;
|
||||
|
||||
@@ -2868,15 +2930,21 @@ static int ib_netdevice_event(struct notifier_block *this,
|
||||
if (!ibdev)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
rdma_for_each_port(ibdev, port) {
|
||||
ib_ndev = ib_device_get_netdev(ibdev, port);
|
||||
if (ndev == ib_ndev)
|
||||
rdma_nl_notify_event(ibdev, port,
|
||||
RDMA_NETDEV_RENAME_EVENT);
|
||||
dev_put(ib_ndev);
|
||||
if (ib_query_netdev_port(ibdev, ndev, &port)) {
|
||||
ib_device_put(ibdev);
|
||||
break;
|
||||
}
|
||||
|
||||
rdma_nl_notify_event(ibdev, port, RDMA_NETDEV_RENAME_EVENT);
|
||||
ib_device_put(ibdev);
|
||||
break;
|
||||
|
||||
case NETDEV_UP:
|
||||
case NETDEV_CHANGE:
|
||||
case NETDEV_DOWN:
|
||||
handle_port_event(ndev, event);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -462,86 +462,3 @@ int ib_ud_header_pack(struct ib_ud_header *header,
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_ud_header_pack);
|
||||
|
||||
/**
|
||||
* ib_ud_header_unpack - Unpack UD header struct from wire format
|
||||
* @header:UD header struct
|
||||
* @buf:Buffer to pack into
|
||||
*
|
||||
* ib_ud_header_pack() unpacks the UD header structure @header from wire
|
||||
* format in the buffer @buf.
|
||||
*/
|
||||
int ib_ud_header_unpack(void *buf,
|
||||
struct ib_ud_header *header)
|
||||
{
|
||||
ib_unpack(lrh_table, ARRAY_SIZE(lrh_table),
|
||||
buf, &header->lrh);
|
||||
buf += IB_LRH_BYTES;
|
||||
|
||||
if (header->lrh.link_version != 0) {
|
||||
pr_warn("Invalid LRH.link_version %u\n",
|
||||
header->lrh.link_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (header->lrh.link_next_header) {
|
||||
case IB_LNH_IBA_LOCAL:
|
||||
header->grh_present = 0;
|
||||
break;
|
||||
|
||||
case IB_LNH_IBA_GLOBAL:
|
||||
header->grh_present = 1;
|
||||
ib_unpack(grh_table, ARRAY_SIZE(grh_table),
|
||||
buf, &header->grh);
|
||||
buf += IB_GRH_BYTES;
|
||||
|
||||
if (header->grh.ip_version != 6) {
|
||||
pr_warn("Invalid GRH.ip_version %u\n",
|
||||
header->grh.ip_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (header->grh.next_header != 0x1b) {
|
||||
pr_warn("Invalid GRH.next_header 0x%02x\n",
|
||||
header->grh.next_header);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_warn("Invalid LRH.link_next_header %u\n",
|
||||
header->lrh.link_next_header);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ib_unpack(bth_table, ARRAY_SIZE(bth_table),
|
||||
buf, &header->bth);
|
||||
buf += IB_BTH_BYTES;
|
||||
|
||||
switch (header->bth.opcode) {
|
||||
case IB_OPCODE_UD_SEND_ONLY:
|
||||
header->immediate_present = 0;
|
||||
break;
|
||||
case IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE:
|
||||
header->immediate_present = 1;
|
||||
break;
|
||||
default:
|
||||
pr_warn("Invalid BTH.opcode 0x%02x\n", header->bth.opcode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (header->bth.transport_header_version != 0) {
|
||||
pr_warn("Invalid BTH.transport_header_version %u\n",
|
||||
header->bth.transport_header_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ib_unpack(deth_table, ARRAY_SIZE(deth_table),
|
||||
buf, &header->deth);
|
||||
buf += IB_DETH_BYTES;
|
||||
|
||||
if (header->immediate_present)
|
||||
memcpy(&header->immediate_data, buf, sizeof header->immediate_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_ud_header_unpack);
|
||||
|
||||
@@ -171,45 +171,3 @@ void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
|
||||
__ib_copy_path_rec_to_user(dst, src);
|
||||
}
|
||||
EXPORT_SYMBOL(ib_copy_path_rec_to_user);
|
||||
|
||||
void ib_copy_path_rec_from_user(struct sa_path_rec *dst,
|
||||
struct ib_user_path_rec *src)
|
||||
{
|
||||
u32 slid, dlid;
|
||||
|
||||
memset(dst, 0, sizeof(*dst));
|
||||
if ((ib_is_opa_gid((union ib_gid *)src->sgid)) ||
|
||||
(ib_is_opa_gid((union ib_gid *)src->dgid))) {
|
||||
dst->rec_type = SA_PATH_REC_TYPE_OPA;
|
||||
slid = opa_get_lid_from_gid((union ib_gid *)src->sgid);
|
||||
dlid = opa_get_lid_from_gid((union ib_gid *)src->dgid);
|
||||
} else {
|
||||
dst->rec_type = SA_PATH_REC_TYPE_IB;
|
||||
slid = ntohs(src->slid);
|
||||
dlid = ntohs(src->dlid);
|
||||
}
|
||||
memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid);
|
||||
memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid);
|
||||
|
||||
sa_path_set_dlid(dst, dlid);
|
||||
sa_path_set_slid(dst, slid);
|
||||
sa_path_set_raw_traffic(dst, src->raw_traffic);
|
||||
dst->flow_label = src->flow_label;
|
||||
dst->hop_limit = src->hop_limit;
|
||||
dst->traffic_class = src->traffic_class;
|
||||
dst->reversible = src->reversible;
|
||||
dst->numb_path = src->numb_path;
|
||||
dst->pkey = src->pkey;
|
||||
dst->sl = src->sl;
|
||||
dst->mtu_selector = src->mtu_selector;
|
||||
dst->mtu = src->mtu;
|
||||
dst->rate_selector = src->rate_selector;
|
||||
dst->rate = src->rate;
|
||||
dst->packet_life_time = src->packet_life_time;
|
||||
dst->preference = src->preference;
|
||||
dst->packet_life_time_selector = src->packet_life_time_selector;
|
||||
|
||||
/* TODO: No need to set this */
|
||||
sa_path_set_dmac_zero(dst);
|
||||
}
|
||||
EXPORT_SYMBOL(ib_copy_path_rec_from_user);
|
||||
|
||||
@@ -11,7 +11,7 @@ obj-$(CONFIG_INFINIBAND_OCRDMA) += ocrdma/
|
||||
obj-$(CONFIG_INFINIBAND_VMWARE_PVRDMA) += vmw_pvrdma/
|
||||
obj-$(CONFIG_INFINIBAND_USNIC) += usnic/
|
||||
obj-$(CONFIG_INFINIBAND_HFI1) += hfi1/
|
||||
obj-$(CONFIG_INFINIBAND_HNS) += hns/
|
||||
obj-$(CONFIG_INFINIBAND_HNS_HIP08) += hns/
|
||||
obj-$(CONFIG_INFINIBAND_QEDR) += qedr/
|
||||
obj-$(CONFIG_INFINIBAND_BNXT_RE) += bnxt_re/
|
||||
obj-$(CONFIG_INFINIBAND_ERDMA) += erdma/
|
||||
|
||||
@@ -204,7 +204,7 @@ struct bnxt_re_dev {
|
||||
struct bnxt_re_nq_record *nqr;
|
||||
|
||||
/* Device Resources */
|
||||
struct bnxt_qplib_dev_attr dev_attr;
|
||||
struct bnxt_qplib_dev_attr *dev_attr;
|
||||
struct bnxt_qplib_ctx qplib_ctx;
|
||||
struct bnxt_qplib_res qplib_res;
|
||||
struct bnxt_qplib_dpi dpi_privileged;
|
||||
@@ -229,6 +229,9 @@ struct bnxt_re_dev {
|
||||
DECLARE_HASHTABLE(srq_hash, MAX_SRQ_HASH_BITS);
|
||||
struct dentry *dbg_root;
|
||||
struct dentry *qp_debugfs;
|
||||
unsigned long event_bitmap;
|
||||
struct bnxt_qplib_cc_param cc_param;
|
||||
struct workqueue_struct *dcb_wq;
|
||||
};
|
||||
|
||||
#define to_bnxt_re_dev(ptr, member) \
|
||||
|
||||
@@ -37,18 +37,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <rdma/ib_addr.h>
|
||||
|
||||
#include "bnxt_ulp.h"
|
||||
#include "roce_hsi.h"
|
||||
#include "qplib_res.h"
|
||||
#include "qplib_sp.h"
|
||||
@@ -357,7 +348,7 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
|
||||
goto done;
|
||||
}
|
||||
bnxt_re_copy_err_stats(rdev, stats, err_s);
|
||||
if (_is_ext_stats_supported(rdev->dev_attr.dev_cap_flags) &&
|
||||
if (_is_ext_stats_supported(rdev->dev_attr->dev_cap_flags) &&
|
||||
!rdev->is_virtfn) {
|
||||
rc = bnxt_re_get_ext_stat(rdev, stats);
|
||||
if (rc) {
|
||||
|
||||
@@ -52,8 +52,6 @@
|
||||
#include <rdma/uverbs_ioctl.h>
|
||||
#include <linux/hashtable.h>
|
||||
|
||||
#include "bnxt_ulp.h"
|
||||
|
||||
#include "roce_hsi.h"
|
||||
#include "qplib_res.h"
|
||||
#include "qplib_sp.h"
|
||||
@@ -161,7 +159,7 @@ static int __qp_access_flags_to_ib(struct bnxt_qplib_chip_ctx *cctx, u8 qflags)
|
||||
static void bnxt_re_check_and_set_relaxed_ordering(struct bnxt_re_dev *rdev,
|
||||
struct bnxt_qplib_mrw *qplib_mr)
|
||||
{
|
||||
if (_is_relaxed_ordering_supported(rdev->dev_attr.dev_cap_flags2) &&
|
||||
if (_is_relaxed_ordering_supported(rdev->dev_attr->dev_cap_flags2) &&
|
||||
pcie_relaxed_ordering_enabled(rdev->en_dev->pdev))
|
||||
qplib_mr->flags |= CMDQ_REGISTER_MR_FLAGS_ENABLE_RO;
|
||||
}
|
||||
@@ -186,7 +184,7 @@ int bnxt_re_query_device(struct ib_device *ibdev,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
|
||||
struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
|
||||
struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
|
||||
|
||||
memset(ib_attr, 0, sizeof(*ib_attr));
|
||||
memcpy(&ib_attr->fw_ver, dev_attr->fw_ver,
|
||||
@@ -275,7 +273,7 @@ int bnxt_re_query_port(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attr *port_attr)
|
||||
{
|
||||
struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
|
||||
struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
|
||||
struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
|
||||
int rc;
|
||||
|
||||
memset(port_attr, 0, sizeof(*port_attr));
|
||||
@@ -333,8 +331,8 @@ void bnxt_re_query_fw_str(struct ib_device *ibdev, char *str)
|
||||
struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
|
||||
|
||||
snprintf(str, IB_FW_VERSION_NAME_MAX, "%d.%d.%d.%d",
|
||||
rdev->dev_attr.fw_ver[0], rdev->dev_attr.fw_ver[1],
|
||||
rdev->dev_attr.fw_ver[2], rdev->dev_attr.fw_ver[3]);
|
||||
rdev->dev_attr->fw_ver[0], rdev->dev_attr->fw_ver[1],
|
||||
rdev->dev_attr->fw_ver[2], rdev->dev_attr->fw_ver[3]);
|
||||
}
|
||||
|
||||
int bnxt_re_query_pkey(struct ib_device *ibdev, u32 port_num,
|
||||
@@ -585,7 +583,7 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd)
|
||||
mr->qplib_mr.pd = &pd->qplib_pd;
|
||||
mr->qplib_mr.type = CMDQ_ALLOCATE_MRW_MRW_FLAGS_PMR;
|
||||
mr->qplib_mr.access_flags = __from_ib_access_flags(mr_access_flags);
|
||||
if (!_is_alloc_mr_unified(rdev->dev_attr.dev_cap_flags)) {
|
||||
if (!_is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)) {
|
||||
rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mr->qplib_mr);
|
||||
if (rc) {
|
||||
ibdev_err(&rdev->ibdev, "Failed to alloc fence-HW-MR\n");
|
||||
@@ -1057,7 +1055,7 @@ static int bnxt_re_setup_swqe_size(struct bnxt_re_qp *qp,
|
||||
rdev = qp->rdev;
|
||||
qplqp = &qp->qplib_qp;
|
||||
sq = &qplqp->sq;
|
||||
dev_attr = &rdev->dev_attr;
|
||||
dev_attr = rdev->dev_attr;
|
||||
|
||||
align = sizeof(struct sq_send_hdr);
|
||||
ilsize = ALIGN(init_attr->cap.max_inline_data, align);
|
||||
@@ -1277,7 +1275,7 @@ static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp,
|
||||
rdev = qp->rdev;
|
||||
qplqp = &qp->qplib_qp;
|
||||
rq = &qplqp->rq;
|
||||
dev_attr = &rdev->dev_attr;
|
||||
dev_attr = rdev->dev_attr;
|
||||
|
||||
if (init_attr->srq) {
|
||||
struct bnxt_re_srq *srq;
|
||||
@@ -1314,7 +1312,7 @@ static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp)
|
||||
|
||||
rdev = qp->rdev;
|
||||
qplqp = &qp->qplib_qp;
|
||||
dev_attr = &rdev->dev_attr;
|
||||
dev_attr = rdev->dev_attr;
|
||||
|
||||
if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) {
|
||||
qplqp->rq.max_sge = dev_attr->max_qp_sges;
|
||||
@@ -1340,7 +1338,7 @@ static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
|
||||
rdev = qp->rdev;
|
||||
qplqp = &qp->qplib_qp;
|
||||
sq = &qplqp->sq;
|
||||
dev_attr = &rdev->dev_attr;
|
||||
dev_attr = rdev->dev_attr;
|
||||
|
||||
sq->max_sge = init_attr->cap.max_send_sge;
|
||||
entries = init_attr->cap.max_send_wr;
|
||||
@@ -1393,7 +1391,7 @@ static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp,
|
||||
|
||||
rdev = qp->rdev;
|
||||
qplqp = &qp->qplib_qp;
|
||||
dev_attr = &rdev->dev_attr;
|
||||
dev_attr = rdev->dev_attr;
|
||||
|
||||
if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) {
|
||||
entries = bnxt_re_init_depth(init_attr->cap.max_send_wr + 1, uctx);
|
||||
@@ -1442,7 +1440,7 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
|
||||
|
||||
rdev = qp->rdev;
|
||||
qplqp = &qp->qplib_qp;
|
||||
dev_attr = &rdev->dev_attr;
|
||||
dev_attr = rdev->dev_attr;
|
||||
|
||||
/* Setup misc params */
|
||||
ether_addr_copy(qplqp->smac, rdev->netdev->dev_addr);
|
||||
@@ -1612,7 +1610,7 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
|
||||
ib_pd = ib_qp->pd;
|
||||
pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
|
||||
rdev = pd->rdev;
|
||||
dev_attr = &rdev->dev_attr;
|
||||
dev_attr = rdev->dev_attr;
|
||||
qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
|
||||
|
||||
uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
|
||||
@@ -1840,7 +1838,7 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
|
||||
ib_pd = ib_srq->pd;
|
||||
pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
|
||||
rdev = pd->rdev;
|
||||
dev_attr = &rdev->dev_attr;
|
||||
dev_attr = rdev->dev_attr;
|
||||
srq = container_of(ib_srq, struct bnxt_re_srq, ib_srq);
|
||||
|
||||
if (srq_init_attr->attr.max_wr >= dev_attr->max_srq_wqes) {
|
||||
@@ -2044,7 +2042,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
|
||||
{
|
||||
struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
|
||||
struct bnxt_re_dev *rdev = qp->rdev;
|
||||
struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
|
||||
struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
|
||||
enum ib_qp_state curr_qp_state, new_qp_state;
|
||||
int rc, entries;
|
||||
unsigned int flags;
|
||||
@@ -3091,7 +3089,7 @@ int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct bnxt_re_ucontext *uctx =
|
||||
rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
|
||||
struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
|
||||
struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
|
||||
struct bnxt_qplib_chip_ctx *cctx;
|
||||
int cqe = attr->cqe;
|
||||
int rc, entries;
|
||||
@@ -3226,7 +3224,7 @@ int bnxt_re_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
|
||||
|
||||
cq = container_of(ibcq, struct bnxt_re_cq, ib_cq);
|
||||
rdev = cq->rdev;
|
||||
dev_attr = &rdev->dev_attr;
|
||||
dev_attr = rdev->dev_attr;
|
||||
if (!ibcq->uobject) {
|
||||
ibdev_err(&rdev->ibdev, "Kernel CQ Resize not supported");
|
||||
return -EOPNOTSUPP;
|
||||
@@ -4199,7 +4197,7 @@ static struct ib_mr *__bnxt_re_user_reg_mr(struct ib_pd *ib_pd, u64 length, u64
|
||||
mr->qplib_mr.access_flags = __from_ib_access_flags(mr_access_flags);
|
||||
mr->qplib_mr.type = CMDQ_ALLOCATE_MRW_MRW_FLAGS_MR;
|
||||
|
||||
if (!_is_alloc_mr_unified(rdev->dev_attr.dev_cap_flags)) {
|
||||
if (!_is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)) {
|
||||
rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mr->qplib_mr);
|
||||
if (rc) {
|
||||
ibdev_err(&rdev->ibdev, "Failed to allocate MR rc = %d", rc);
|
||||
@@ -4291,7 +4289,7 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
|
||||
struct bnxt_re_ucontext *uctx =
|
||||
container_of(ctx, struct bnxt_re_ucontext, ib_uctx);
|
||||
struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
|
||||
struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
|
||||
struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
|
||||
struct bnxt_re_user_mmap_entry *entry;
|
||||
struct bnxt_re_uctx_resp resp = {};
|
||||
struct bnxt_re_uctx_req ureq = {};
|
||||
@@ -4467,9 +4465,10 @@ int bnxt_re_mmap(struct ib_ucontext *ib_uctx, struct vm_area_struct *vma)
|
||||
case BNXT_RE_MMAP_TOGGLE_PAGE:
|
||||
/* Driver doesn't expect write access for user space */
|
||||
if (vma->vm_flags & VM_WRITE)
|
||||
return -EFAULT;
|
||||
ret = vm_insert_page(vma, vma->vm_start,
|
||||
virt_to_page((void *)bnxt_entry->mem_offset));
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = vm_insert_page(vma, vma->vm_start,
|
||||
virt_to_page((void *)bnxt_entry->mem_offset));
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
||||
@@ -79,17 +79,12 @@ MODULE_LICENSE("Dual BSD/GPL");
|
||||
/* globals */
|
||||
static DEFINE_MUTEX(bnxt_re_mutex);
|
||||
|
||||
static void bnxt_re_stop_irq(void *handle);
|
||||
static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev);
|
||||
static int bnxt_re_netdev_event(struct notifier_block *notifier,
|
||||
unsigned long event, void *ptr);
|
||||
static struct bnxt_re_dev *bnxt_re_from_netdev(struct net_device *netdev);
|
||||
static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type);
|
||||
static int bnxt_re_hwrm_qcaps(struct bnxt_re_dev *rdev);
|
||||
|
||||
static int bnxt_re_hwrm_qcfg(struct bnxt_re_dev *rdev, u32 *db_len,
|
||||
u32 *offset);
|
||||
static void bnxt_re_setup_cc(struct bnxt_re_dev *rdev, bool enable);
|
||||
static void bnxt_re_dispatch_event(struct ib_device *ibdev, struct ib_qp *qp,
|
||||
u8 port_num, enum ib_event_type event);
|
||||
static void bnxt_re_set_db_offset(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
struct bnxt_qplib_chip_ctx *cctx;
|
||||
@@ -153,6 +148,10 @@ static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
|
||||
|
||||
if (!rdev->chip_ctx)
|
||||
return;
|
||||
|
||||
kfree(rdev->dev_attr);
|
||||
rdev->dev_attr = NULL;
|
||||
|
||||
chip_ctx = rdev->chip_ctx;
|
||||
rdev->chip_ctx = NULL;
|
||||
rdev->rcfw.res = NULL;
|
||||
@@ -166,7 +165,7 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
struct bnxt_qplib_chip_ctx *chip_ctx;
|
||||
struct bnxt_en_dev *en_dev;
|
||||
int rc;
|
||||
int rc = -ENOMEM;
|
||||
|
||||
en_dev = rdev->en_dev;
|
||||
|
||||
@@ -182,7 +181,10 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)
|
||||
|
||||
rdev->qplib_res.cctx = rdev->chip_ctx;
|
||||
rdev->rcfw.res = &rdev->qplib_res;
|
||||
rdev->qplib_res.dattr = &rdev->dev_attr;
|
||||
rdev->dev_attr = kzalloc(sizeof(*rdev->dev_attr), GFP_KERNEL);
|
||||
if (!rdev->dev_attr)
|
||||
goto free_chip_ctx;
|
||||
rdev->qplib_res.dattr = rdev->dev_attr;
|
||||
rdev->qplib_res.is_vf = BNXT_EN_VF(en_dev);
|
||||
rdev->qplib_res.en_dev = en_dev;
|
||||
|
||||
@@ -190,16 +192,20 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)
|
||||
|
||||
bnxt_re_set_db_offset(rdev);
|
||||
rc = bnxt_qplib_map_db_bar(&rdev->qplib_res);
|
||||
if (rc) {
|
||||
kfree(rdev->chip_ctx);
|
||||
rdev->chip_ctx = NULL;
|
||||
return rc;
|
||||
}
|
||||
if (rc)
|
||||
goto free_dev_attr;
|
||||
|
||||
if (bnxt_qplib_determine_atomics(en_dev->pdev))
|
||||
ibdev_info(&rdev->ibdev,
|
||||
"platform doesn't support global atomics.");
|
||||
return 0;
|
||||
free_dev_attr:
|
||||
kfree(rdev->dev_attr);
|
||||
rdev->dev_attr = NULL;
|
||||
free_chip_ctx:
|
||||
kfree(rdev->chip_ctx);
|
||||
rdev->chip_ctx = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* SR-IOV helper functions */
|
||||
@@ -221,7 +227,7 @@ static void bnxt_re_limit_pf_res(struct bnxt_re_dev *rdev)
|
||||
struct bnxt_qplib_ctx *ctx;
|
||||
int i;
|
||||
|
||||
attr = &rdev->dev_attr;
|
||||
attr = rdev->dev_attr;
|
||||
ctx = &rdev->qplib_ctx;
|
||||
|
||||
ctx->qpc_count = min_t(u32, BNXT_RE_MAX_QPC_COUNT,
|
||||
@@ -235,7 +241,7 @@ static void bnxt_re_limit_pf_res(struct bnxt_re_dev *rdev)
|
||||
if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))
|
||||
for (i = 0; i < MAX_TQM_ALLOC_REQ; i++)
|
||||
rdev->qplib_ctx.tqm_ctx.qcount[i] =
|
||||
rdev->dev_attr.tqm_alloc_reqs[i];
|
||||
rdev->dev_attr->tqm_alloc_reqs[i];
|
||||
}
|
||||
|
||||
static void bnxt_re_limit_vf_res(struct bnxt_qplib_ctx *qplib_ctx, u32 num_vf)
|
||||
@@ -302,17 +308,123 @@ static void bnxt_re_vf_res_config(struct bnxt_re_dev *rdev)
|
||||
&rdev->qplib_ctx);
|
||||
}
|
||||
|
||||
static void bnxt_re_shutdown(struct auxiliary_device *adev)
|
||||
{
|
||||
struct bnxt_re_en_dev_info *en_info = auxiliary_get_drvdata(adev);
|
||||
struct bnxt_re_dcb_work {
|
||||
struct work_struct work;
|
||||
struct bnxt_re_dev *rdev;
|
||||
struct hwrm_async_event_cmpl cmpl;
|
||||
};
|
||||
|
||||
rdev = en_info->rdev;
|
||||
ib_unregister_device(&rdev->ibdev);
|
||||
bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE);
|
||||
static bool bnxt_re_is_qp1_qp(struct bnxt_re_qp *qp)
|
||||
{
|
||||
return qp->ib_qp.qp_type == IB_QPT_GSI;
|
||||
}
|
||||
|
||||
static void bnxt_re_stop_irq(void *handle)
|
||||
static struct bnxt_re_qp *bnxt_re_get_qp1_qp(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
struct bnxt_re_qp *qp;
|
||||
|
||||
mutex_lock(&rdev->qp_lock);
|
||||
list_for_each_entry(qp, &rdev->qp_list, list) {
|
||||
if (bnxt_re_is_qp1_qp(qp)) {
|
||||
mutex_unlock(&rdev->qp_lock);
|
||||
return qp;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&rdev->qp_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int bnxt_re_update_qp1_tos_dscp(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
struct bnxt_re_qp *qp;
|
||||
|
||||
if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))
|
||||
return 0;
|
||||
|
||||
qp = bnxt_re_get_qp1_qp(rdev);
|
||||
if (!qp)
|
||||
return 0;
|
||||
|
||||
qp->qplib_qp.modify_flags = CMDQ_MODIFY_QP_MODIFY_MASK_TOS_DSCP;
|
||||
qp->qplib_qp.tos_dscp = rdev->cc_param.qp1_tos_dscp;
|
||||
|
||||
return bnxt_qplib_modify_qp(&rdev->qplib_res, &qp->qplib_qp);
|
||||
}
|
||||
|
||||
static void bnxt_re_init_dcb_wq(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
rdev->dcb_wq = create_singlethread_workqueue("bnxt_re_dcb_wq");
|
||||
}
|
||||
|
||||
static void bnxt_re_uninit_dcb_wq(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
if (!rdev->dcb_wq)
|
||||
return;
|
||||
destroy_workqueue(rdev->dcb_wq);
|
||||
}
|
||||
|
||||
static void bnxt_re_dcb_wq_task(struct work_struct *work)
|
||||
{
|
||||
struct bnxt_re_dcb_work *dcb_work =
|
||||
container_of(work, struct bnxt_re_dcb_work, work);
|
||||
struct bnxt_re_dev *rdev = dcb_work->rdev;
|
||||
struct bnxt_qplib_cc_param *cc_param;
|
||||
int rc;
|
||||
|
||||
if (!rdev)
|
||||
goto free_dcb;
|
||||
|
||||
cc_param = &rdev->cc_param;
|
||||
rc = bnxt_qplib_query_cc_param(&rdev->qplib_res, cc_param);
|
||||
if (rc) {
|
||||
ibdev_dbg(&rdev->ibdev, "Failed to query ccparam rc:%d", rc);
|
||||
goto free_dcb;
|
||||
}
|
||||
if (cc_param->qp1_tos_dscp != cc_param->tos_dscp) {
|
||||
cc_param->qp1_tos_dscp = cc_param->tos_dscp;
|
||||
rc = bnxt_re_update_qp1_tos_dscp(rdev);
|
||||
if (rc) {
|
||||
ibdev_dbg(&rdev->ibdev, "%s: Failed to modify QP1 rc:%d",
|
||||
__func__, rc);
|
||||
goto free_dcb;
|
||||
}
|
||||
}
|
||||
|
||||
free_dcb:
|
||||
kfree(dcb_work);
|
||||
}
|
||||
|
||||
static void bnxt_re_async_notifier(void *handle, struct hwrm_async_event_cmpl *cmpl)
|
||||
{
|
||||
struct bnxt_re_dev *rdev = (struct bnxt_re_dev *)handle;
|
||||
struct bnxt_re_dcb_work *dcb_work;
|
||||
u32 data1, data2;
|
||||
u16 event_id;
|
||||
|
||||
event_id = le16_to_cpu(cmpl->event_id);
|
||||
data1 = le32_to_cpu(cmpl->event_data1);
|
||||
data2 = le32_to_cpu(cmpl->event_data2);
|
||||
|
||||
ibdev_dbg(&rdev->ibdev, "Async event_id = %d data1 = %d data2 = %d",
|
||||
event_id, data1, data2);
|
||||
|
||||
switch (event_id) {
|
||||
case ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE:
|
||||
dcb_work = kzalloc(sizeof(*dcb_work), GFP_ATOMIC);
|
||||
if (!dcb_work)
|
||||
break;
|
||||
|
||||
dcb_work->rdev = rdev;
|
||||
memcpy(&dcb_work->cmpl, cmpl, sizeof(*cmpl));
|
||||
INIT_WORK(&dcb_work->work, bnxt_re_dcb_wq_task);
|
||||
queue_work(rdev->dcb_wq, &dcb_work->work);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void bnxt_re_stop_irq(void *handle, bool reset)
|
||||
{
|
||||
struct bnxt_re_en_dev_info *en_info = auxiliary_get_drvdata(handle);
|
||||
struct bnxt_qplib_rcfw *rcfw;
|
||||
@@ -323,6 +435,14 @@ static void bnxt_re_stop_irq(void *handle)
|
||||
rdev = en_info->rdev;
|
||||
rcfw = &rdev->rcfw;
|
||||
|
||||
if (reset) {
|
||||
set_bit(ERR_DEVICE_DETACHED, &rdev->rcfw.cmdq.flags);
|
||||
set_bit(BNXT_RE_FLAG_ERR_DEVICE_DETACHED, &rdev->flags);
|
||||
wake_up_all(&rdev->rcfw.cmdq.waitq);
|
||||
bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1,
|
||||
IB_EVENT_DEVICE_FATAL);
|
||||
}
|
||||
|
||||
for (indx = BNXT_RE_NQ_IDX; indx < rdev->nqr->num_msix; indx++) {
|
||||
nq = &rdev->nqr->nq[indx - 1];
|
||||
bnxt_qplib_nq_stop_irq(nq, false);
|
||||
@@ -378,6 +498,7 @@ static void bnxt_re_start_irq(void *handle, struct bnxt_msix_entry *ent)
|
||||
}
|
||||
|
||||
static struct bnxt_ulp_ops bnxt_re_ulp_ops = {
|
||||
.ulp_async_notifier = bnxt_re_async_notifier,
|
||||
.ulp_irq_stop = bnxt_re_stop_irq,
|
||||
.ulp_irq_restart = bnxt_re_start_irq
|
||||
};
|
||||
@@ -839,17 +960,6 @@ static void bnxt_re_disassociate_ucontext(struct ib_ucontext *ibcontext)
|
||||
}
|
||||
|
||||
/* Device */
|
||||
|
||||
static struct bnxt_re_dev *bnxt_re_from_netdev(struct net_device *netdev)
|
||||
{
|
||||
struct ib_device *ibdev =
|
||||
ib_device_get_by_netdev(netdev, RDMA_DRIVER_BNXT_RE);
|
||||
if (!ibdev)
|
||||
return NULL;
|
||||
|
||||
return container_of(ibdev, struct bnxt_re_dev, ibdev);
|
||||
}
|
||||
|
||||
static ssize_t hw_rev_show(struct device *device, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
@@ -1627,12 +1737,11 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
|
||||
|
||||
/* Configure and allocate resources for qplib */
|
||||
rdev->qplib_res.rcfw = &rdev->rcfw;
|
||||
rc = bnxt_qplib_get_dev_attr(&rdev->rcfw, &rdev->dev_attr);
|
||||
rc = bnxt_qplib_get_dev_attr(&rdev->rcfw);
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
||||
rc = bnxt_qplib_alloc_res(&rdev->qplib_res, rdev->en_dev->pdev,
|
||||
rdev->netdev, &rdev->dev_attr);
|
||||
rc = bnxt_qplib_alloc_res(&rdev->qplib_res, rdev->netdev);
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
||||
@@ -1807,6 +1916,26 @@ static int bnxt_re_setup_qos(struct bnxt_re_dev *rdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bnxt_re_net_unregister_async_event(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
if (rdev->is_virtfn)
|
||||
return;
|
||||
|
||||
memset(&rdev->event_bitmap, 0, sizeof(rdev->event_bitmap));
|
||||
bnxt_register_async_events(rdev->en_dev, &rdev->event_bitmap,
|
||||
ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE);
|
||||
}
|
||||
|
||||
static void bnxt_re_net_register_async_event(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
if (rdev->is_virtfn)
|
||||
return;
|
||||
|
||||
rdev->event_bitmap |= (1 << ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE);
|
||||
bnxt_register_async_events(rdev->en_dev, &rdev->event_bitmap,
|
||||
ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE);
|
||||
}
|
||||
|
||||
static void bnxt_re_query_hwrm_intf_version(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
struct bnxt_en_dev *en_dev = rdev->en_dev;
|
||||
@@ -1886,6 +2015,9 @@ static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type)
|
||||
|
||||
bnxt_re_debugfs_rem_pdev(rdev);
|
||||
|
||||
bnxt_re_net_unregister_async_event(rdev);
|
||||
bnxt_re_uninit_dcb_wq(rdev);
|
||||
|
||||
if (test_and_clear_bit(BNXT_RE_FLAG_QOS_WORK_REG, &rdev->flags))
|
||||
cancel_delayed_work_sync(&rdev->worker);
|
||||
|
||||
@@ -2032,7 +2164,7 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 op_type)
|
||||
rdev->pacing.dbr_pacing = false;
|
||||
}
|
||||
}
|
||||
rc = bnxt_qplib_get_dev_attr(&rdev->rcfw, &rdev->dev_attr);
|
||||
rc = bnxt_qplib_get_dev_attr(&rdev->rcfw);
|
||||
if (rc)
|
||||
goto disable_rcfw;
|
||||
|
||||
@@ -2081,6 +2213,11 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 op_type)
|
||||
set_bit(BNXT_RE_FLAG_RESOURCES_INITIALIZED, &rdev->flags);
|
||||
|
||||
if (!rdev->is_virtfn) {
|
||||
/* Query f/w defaults of CC params */
|
||||
rc = bnxt_qplib_query_cc_param(&rdev->qplib_res, &rdev->cc_param);
|
||||
if (rc)
|
||||
ibdev_warn(&rdev->ibdev, "Failed to query CC defaults\n");
|
||||
|
||||
rc = bnxt_re_setup_qos(rdev);
|
||||
if (rc)
|
||||
ibdev_info(&rdev->ibdev,
|
||||
@@ -2099,6 +2236,9 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 op_type)
|
||||
|
||||
bnxt_re_debugfs_add_pdev(rdev);
|
||||
|
||||
bnxt_re_init_dcb_wq(rdev);
|
||||
bnxt_re_net_register_async_event(rdev);
|
||||
|
||||
return 0;
|
||||
free_sctx:
|
||||
bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
|
||||
@@ -2117,6 +2257,30 @@ fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void bnxt_re_setup_cc(struct bnxt_re_dev *rdev, bool enable)
|
||||
{
|
||||
struct bnxt_qplib_cc_param cc_param = {};
|
||||
|
||||
/* Do not enable congestion control on VFs */
|
||||
if (rdev->is_virtfn)
|
||||
return;
|
||||
|
||||
/* Currently enabling only for GenP5 adapters */
|
||||
if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))
|
||||
return;
|
||||
|
||||
if (enable) {
|
||||
cc_param.enable = 1;
|
||||
cc_param.tos_ecn = 1;
|
||||
}
|
||||
|
||||
cc_param.mask = (CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ENABLE_CC |
|
||||
CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_ECN);
|
||||
|
||||
if (bnxt_qplib_modify_cc(&rdev->qplib_res, &cc_param))
|
||||
ibdev_err(&rdev->ibdev, "Failed to setup CC enable = %d\n", enable);
|
||||
}
|
||||
|
||||
static void bnxt_re_update_en_info_rdev(struct bnxt_re_dev *rdev,
|
||||
struct bnxt_re_en_dev_info *en_info,
|
||||
struct auxiliary_device *adev)
|
||||
@@ -2163,20 +2327,10 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type)
|
||||
goto re_dev_uninit;
|
||||
}
|
||||
|
||||
rdev->nb.notifier_call = bnxt_re_netdev_event;
|
||||
rc = register_netdevice_notifier(&rdev->nb);
|
||||
if (rc) {
|
||||
rdev->nb.notifier_call = NULL;
|
||||
pr_err("%s: Cannot register to netdevice_notifier",
|
||||
ROCE_DRV_MODULE_NAME);
|
||||
goto re_dev_unreg;
|
||||
}
|
||||
bnxt_re_setup_cc(rdev, true);
|
||||
|
||||
return 0;
|
||||
|
||||
re_dev_unreg:
|
||||
ib_unregister_device(&rdev->ibdev);
|
||||
re_dev_uninit:
|
||||
bnxt_re_update_en_info_rdev(NULL, en_info, adev);
|
||||
bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE);
|
||||
@@ -2186,79 +2340,6 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void bnxt_re_setup_cc(struct bnxt_re_dev *rdev, bool enable)
|
||||
{
|
||||
struct bnxt_qplib_cc_param cc_param = {};
|
||||
|
||||
/* Do not enable congestion control on VFs */
|
||||
if (rdev->is_virtfn)
|
||||
return;
|
||||
|
||||
/* Currently enabling only for GenP5 adapters */
|
||||
if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))
|
||||
return;
|
||||
|
||||
if (enable) {
|
||||
cc_param.enable = 1;
|
||||
cc_param.tos_ecn = 1;
|
||||
}
|
||||
|
||||
cc_param.mask = (CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ENABLE_CC |
|
||||
CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_ECN);
|
||||
|
||||
if (bnxt_qplib_modify_cc(&rdev->qplib_res, &cc_param))
|
||||
ibdev_err(&rdev->ibdev, "Failed to setup CC enable = %d\n", enable);
|
||||
}
|
||||
|
||||
/*
|
||||
* "Notifier chain callback can be invoked for the same chain from
|
||||
* different CPUs at the same time".
|
||||
*
|
||||
* For cases when the netdev is already present, our call to the
|
||||
* register_netdevice_notifier() will actually get the rtnl_lock()
|
||||
* before sending NETDEV_REGISTER and (if up) NETDEV_UP
|
||||
* events.
|
||||
*
|
||||
* But for cases when the netdev is not already present, the notifier
|
||||
* chain is subjected to be invoked from different CPUs simultaneously.
|
||||
*
|
||||
* This is protected by the netdev_mutex.
|
||||
*/
|
||||
static int bnxt_re_netdev_event(struct notifier_block *notifier,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *real_dev, *netdev = netdev_notifier_info_to_dev(ptr);
|
||||
struct bnxt_re_dev *rdev;
|
||||
|
||||
real_dev = rdma_vlan_dev_real_dev(netdev);
|
||||
if (!real_dev)
|
||||
real_dev = netdev;
|
||||
|
||||
if (real_dev != netdev)
|
||||
goto exit;
|
||||
|
||||
rdev = bnxt_re_from_netdev(real_dev);
|
||||
if (!rdev)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_UP:
|
||||
case NETDEV_DOWN:
|
||||
case NETDEV_CHANGE:
|
||||
bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1,
|
||||
netif_carrier_ok(real_dev) ?
|
||||
IB_EVENT_PORT_ACTIVE :
|
||||
IB_EVENT_PORT_ERR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ib_device_put(&rdev->ibdev);
|
||||
exit:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
#define BNXT_ADEV_NAME "bnxt_en"
|
||||
|
||||
static void bnxt_re_remove_device(struct bnxt_re_dev *rdev, u8 op_type,
|
||||
@@ -2316,13 +2397,9 @@ static int bnxt_re_probe(struct auxiliary_device *adev,
|
||||
|
||||
rc = bnxt_re_add_device(adev, BNXT_RE_COMPLETE_INIT);
|
||||
if (rc)
|
||||
goto err;
|
||||
mutex_unlock(&bnxt_re_mutex);
|
||||
return 0;
|
||||
kfree(en_info);
|
||||
|
||||
err:
|
||||
mutex_unlock(&bnxt_re_mutex);
|
||||
kfree(en_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -2375,6 +2452,16 @@ static int bnxt_re_resume(struct auxiliary_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bnxt_re_shutdown(struct auxiliary_device *adev)
|
||||
{
|
||||
struct bnxt_re_en_dev_info *en_info = auxiliary_get_drvdata(adev);
|
||||
struct bnxt_re_dev *rdev;
|
||||
|
||||
rdev = en_info->rdev;
|
||||
ib_unregister_device(&rdev->ibdev);
|
||||
bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE);
|
||||
}
|
||||
|
||||
static const struct auxiliary_device_id bnxt_re_id_table[] = {
|
||||
{ .name = BNXT_ADEV_NAME ".rdma", },
|
||||
{},
|
||||
|
||||
@@ -343,6 +343,7 @@ struct bnxt_qplib_qp {
|
||||
u32 msn;
|
||||
u32 msn_tbl_sz;
|
||||
bool is_host_msn_tbl;
|
||||
u8 tos_dscp;
|
||||
};
|
||||
|
||||
#define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE sizeof(struct cq_base)
|
||||
|
||||
@@ -876,14 +876,13 @@ void bnxt_qplib_free_res(struct bnxt_qplib_res *res)
|
||||
bnxt_qplib_free_dpi_tbl(res, &res->dpi_tbl);
|
||||
}
|
||||
|
||||
int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev,
|
||||
struct net_device *netdev,
|
||||
struct bnxt_qplib_dev_attr *dev_attr)
|
||||
int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct net_device *netdev)
|
||||
{
|
||||
struct bnxt_qplib_dev_attr *dev_attr;
|
||||
int rc;
|
||||
|
||||
res->pdev = pdev;
|
||||
res->netdev = netdev;
|
||||
dev_attr = res->dattr;
|
||||
|
||||
rc = bnxt_qplib_alloc_sgid_tbl(res, &res->sgid_tbl, dev_attr->max_sgid);
|
||||
if (rc)
|
||||
|
||||
@@ -424,9 +424,7 @@ int bnxt_qplib_dealloc_dpi(struct bnxt_qplib_res *res,
|
||||
void bnxt_qplib_cleanup_res(struct bnxt_qplib_res *res);
|
||||
int bnxt_qplib_init_res(struct bnxt_qplib_res *res);
|
||||
void bnxt_qplib_free_res(struct bnxt_qplib_res *res);
|
||||
int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev,
|
||||
struct net_device *netdev,
|
||||
struct bnxt_qplib_dev_attr *dev_attr);
|
||||
int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct net_device *netdev);
|
||||
void bnxt_qplib_free_ctx(struct bnxt_qplib_res *res,
|
||||
struct bnxt_qplib_ctx *ctx);
|
||||
int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res,
|
||||
|
||||
@@ -88,9 +88,9 @@ static void bnxt_qplib_query_version(struct bnxt_qplib_rcfw *rcfw,
|
||||
fw_ver[3] = resp.fw_rsvd;
|
||||
}
|
||||
|
||||
int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
|
||||
struct bnxt_qplib_dev_attr *attr)
|
||||
int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw)
|
||||
{
|
||||
struct bnxt_qplib_dev_attr *attr = rcfw->res->dattr;
|
||||
struct creq_query_func_resp resp = {};
|
||||
struct bnxt_qplib_cmdqmsg msg = {};
|
||||
struct creq_query_func_resp_sb *sb;
|
||||
@@ -1022,3 +1022,116 @@ free_mem:
|
||||
dma_free_coherent(&rcfw->pdev->dev, sbuf.size, sbuf.sb, sbuf.dma_addr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void bnxt_qplib_read_cc_gen1(struct bnxt_qplib_cc_param_ext *cc_ext,
|
||||
struct creq_query_roce_cc_gen1_resp_sb_tlv *sb)
|
||||
{
|
||||
cc_ext->inact_th_hi = le16_to_cpu(sb->inactivity_th_hi);
|
||||
cc_ext->min_delta_cnp = le16_to_cpu(sb->min_time_between_cnps);
|
||||
cc_ext->init_cp = le16_to_cpu(sb->init_cp);
|
||||
cc_ext->tr_update_mode = sb->tr_update_mode;
|
||||
cc_ext->tr_update_cyls = sb->tr_update_cycles;
|
||||
cc_ext->fr_rtt = sb->fr_num_rtts;
|
||||
cc_ext->ai_rate_incr = sb->ai_rate_increase;
|
||||
cc_ext->rr_rtt_th = le16_to_cpu(sb->reduction_relax_rtts_th);
|
||||
cc_ext->ar_cr_th = le16_to_cpu(sb->additional_relax_cr_th);
|
||||
cc_ext->cr_min_th = le16_to_cpu(sb->cr_min_th);
|
||||
cc_ext->bw_avg_weight = sb->bw_avg_weight;
|
||||
cc_ext->cr_factor = sb->actual_cr_factor;
|
||||
cc_ext->cr_th_max_cp = le16_to_cpu(sb->max_cp_cr_th);
|
||||
cc_ext->cp_bias_en = sb->cp_bias_en;
|
||||
cc_ext->cp_bias = sb->cp_bias;
|
||||
cc_ext->cnp_ecn = sb->cnp_ecn;
|
||||
cc_ext->rtt_jitter_en = sb->rtt_jitter_en;
|
||||
cc_ext->bytes_per_usec = le16_to_cpu(sb->link_bytes_per_usec);
|
||||
cc_ext->cc_cr_reset_th = le16_to_cpu(sb->reset_cc_cr_th);
|
||||
cc_ext->cr_width = sb->cr_width;
|
||||
cc_ext->min_quota = sb->quota_period_min;
|
||||
cc_ext->max_quota = sb->quota_period_max;
|
||||
cc_ext->abs_max_quota = sb->quota_period_abs_max;
|
||||
cc_ext->tr_lb = le16_to_cpu(sb->tr_lower_bound);
|
||||
cc_ext->cr_prob_fac = sb->cr_prob_factor;
|
||||
cc_ext->tr_prob_fac = sb->tr_prob_factor;
|
||||
cc_ext->fair_cr_th = le16_to_cpu(sb->fairness_cr_th);
|
||||
cc_ext->red_div = sb->red_div;
|
||||
cc_ext->cnp_ratio_th = sb->cnp_ratio_th;
|
||||
cc_ext->ai_ext_rtt = le16_to_cpu(sb->exp_ai_rtts);
|
||||
cc_ext->exp_crcp_ratio = sb->exp_ai_cr_cp_ratio;
|
||||
cc_ext->low_rate_en = sb->use_rate_table;
|
||||
cc_ext->cpcr_update_th = le16_to_cpu(sb->cp_exp_update_th);
|
||||
cc_ext->ai_rtt_th1 = le16_to_cpu(sb->high_exp_ai_rtts_th1);
|
||||
cc_ext->ai_rtt_th2 = le16_to_cpu(sb->high_exp_ai_rtts_th2);
|
||||
cc_ext->cf_rtt_th = le16_to_cpu(sb->actual_cr_cong_free_rtts_th);
|
||||
cc_ext->sc_cr_th1 = le16_to_cpu(sb->severe_cong_cr_th1);
|
||||
cc_ext->sc_cr_th2 = le16_to_cpu(sb->severe_cong_cr_th2);
|
||||
cc_ext->l64B_per_rtt = le32_to_cpu(sb->link64B_per_rtt);
|
||||
cc_ext->cc_ack_bytes = sb->cc_ack_bytes;
|
||||
cc_ext->reduce_cf_rtt_th = le16_to_cpu(sb->reduce_init_cong_free_rtts_th);
|
||||
}
|
||||
|
||||
int bnxt_qplib_query_cc_param(struct bnxt_qplib_res *res,
|
||||
struct bnxt_qplib_cc_param *cc_param)
|
||||
{
|
||||
struct bnxt_qplib_tlv_query_rcc_sb *ext_sb;
|
||||
struct bnxt_qplib_rcfw *rcfw = res->rcfw;
|
||||
struct creq_query_roce_cc_resp resp = {};
|
||||
struct creq_query_roce_cc_resp_sb *sb;
|
||||
struct bnxt_qplib_cmdqmsg msg = {};
|
||||
struct cmdq_query_roce_cc req = {};
|
||||
struct bnxt_qplib_rcfw_sbuf sbuf;
|
||||
size_t resp_size;
|
||||
int rc;
|
||||
|
||||
/* Query the parameters from chip */
|
||||
bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, CMDQ_BASE_OPCODE_QUERY_ROCE_CC,
|
||||
sizeof(req));
|
||||
if (bnxt_qplib_is_chip_gen_p5_p7(res->cctx))
|
||||
resp_size = sizeof(*ext_sb);
|
||||
else
|
||||
resp_size = sizeof(*sb);
|
||||
|
||||
sbuf.size = ALIGN(resp_size, BNXT_QPLIB_CMDQE_UNITS);
|
||||
sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
|
||||
&sbuf.dma_addr, GFP_KERNEL);
|
||||
if (!sbuf.sb)
|
||||
return -ENOMEM;
|
||||
|
||||
req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
|
||||
bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
|
||||
sizeof(resp), 0);
|
||||
rc = bnxt_qplib_rcfw_send_message(res->rcfw, &msg);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
ext_sb = sbuf.sb;
|
||||
sb = bnxt_qplib_is_chip_gen_p5_p7(res->cctx) ? &ext_sb->base_sb :
|
||||
(struct creq_query_roce_cc_resp_sb *)ext_sb;
|
||||
|
||||
cc_param->enable = sb->enable_cc & CREQ_QUERY_ROCE_CC_RESP_SB_ENABLE_CC;
|
||||
cc_param->tos_ecn = (sb->tos_dscp_tos_ecn &
|
||||
CREQ_QUERY_ROCE_CC_RESP_SB_TOS_ECN_MASK) >>
|
||||
CREQ_QUERY_ROCE_CC_RESP_SB_TOS_ECN_SFT;
|
||||
cc_param->tos_dscp = (sb->tos_dscp_tos_ecn &
|
||||
CREQ_QUERY_ROCE_CC_RESP_SB_TOS_DSCP_MASK) >>
|
||||
CREQ_QUERY_ROCE_CC_RESP_SB_TOS_DSCP_SFT;
|
||||
cc_param->alt_tos_dscp = sb->alt_tos_dscp;
|
||||
cc_param->alt_vlan_pcp = sb->alt_vlan_pcp;
|
||||
|
||||
cc_param->g = sb->g;
|
||||
cc_param->nph_per_state = sb->num_phases_per_state;
|
||||
cc_param->init_cr = le16_to_cpu(sb->init_cr);
|
||||
cc_param->init_tr = le16_to_cpu(sb->init_tr);
|
||||
cc_param->cc_mode = sb->cc_mode;
|
||||
cc_param->inact_th = le16_to_cpu(sb->inactivity_th);
|
||||
cc_param->rtt = le16_to_cpu(sb->rtt);
|
||||
cc_param->tcp_cp = le16_to_cpu(sb->tcp_cp);
|
||||
cc_param->time_pph = sb->time_per_phase;
|
||||
cc_param->pkts_pph = sb->pkts_per_phase;
|
||||
if (bnxt_qplib_is_chip_gen_p5_p7(res->cctx)) {
|
||||
bnxt_qplib_read_cc_gen1(&cc_param->cc_ext, &ext_sb->gen1_sb);
|
||||
cc_param->inact_th |= (cc_param->cc_ext.inact_th_hi & 0x3F) << 16;
|
||||
}
|
||||
out:
|
||||
dma_free_coherent(&rcfw->pdev->dev, sbuf.size, sbuf.sb, sbuf.dma_addr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -296,6 +296,7 @@ struct bnxt_qplib_cc_param_ext {
|
||||
|
||||
struct bnxt_qplib_cc_param {
|
||||
u8 alt_vlan_pcp;
|
||||
u8 qp1_tos_dscp;
|
||||
u16 alt_tos_dscp;
|
||||
u8 cc_mode;
|
||||
u8 enable;
|
||||
@@ -325,8 +326,7 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
|
||||
int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
|
||||
struct bnxt_qplib_gid *gid, u16 gid_idx,
|
||||
const u8 *smac);
|
||||
int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
|
||||
struct bnxt_qplib_dev_attr *attr);
|
||||
int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw);
|
||||
int bnxt_qplib_set_func_resources(struct bnxt_qplib_res *res,
|
||||
struct bnxt_qplib_rcfw *rcfw,
|
||||
struct bnxt_qplib_ctx *ctx);
|
||||
@@ -355,6 +355,8 @@ int bnxt_qplib_modify_cc(struct bnxt_qplib_res *res,
|
||||
struct bnxt_qplib_cc_param *cc_param);
|
||||
int bnxt_qplib_read_context(struct bnxt_qplib_rcfw *rcfw, u8 type, u32 xid,
|
||||
u32 resp_size, void *resp_va);
|
||||
int bnxt_qplib_query_cc_param(struct bnxt_qplib_res *res,
|
||||
struct bnxt_qplib_cc_param *cc_param);
|
||||
|
||||
#define BNXT_VAR_MAX_WQE 4352
|
||||
#define BNXT_VAR_MAX_SLOT_ALIGN 256
|
||||
|
||||
@@ -1114,8 +1114,10 @@ static inline struct sk_buff *copy_gl_to_skb_pkt(const struct pkt_gl *gl,
|
||||
* The math here assumes sizeof cpl_pass_accept_req >= sizeof
|
||||
* cpl_rx_pkt.
|
||||
*/
|
||||
skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req) +
|
||||
sizeof(struct rss_header) - pktshift, GFP_ATOMIC);
|
||||
skb = alloc_skb(size_add(gl->tot_len,
|
||||
sizeof(struct cpl_pass_accept_req) +
|
||||
sizeof(struct rss_header)) - pktshift,
|
||||
GFP_ATOMIC);
|
||||
if (unlikely(!skb))
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -1599,6 +1599,7 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp,
|
||||
int count;
|
||||
int rq_flushed = 0, sq_flushed;
|
||||
unsigned long flag;
|
||||
struct ib_event ev;
|
||||
|
||||
pr_debug("qhp %p rchp %p schp %p\n", qhp, rchp, schp);
|
||||
|
||||
@@ -1607,6 +1608,13 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp,
|
||||
if (schp != rchp)
|
||||
spin_lock(&schp->lock);
|
||||
spin_lock(&qhp->lock);
|
||||
if (qhp->srq && qhp->attr.state == C4IW_QP_STATE_ERROR &&
|
||||
qhp->ibqp.event_handler) {
|
||||
ev.device = qhp->ibqp.device;
|
||||
ev.element.qp = &qhp->ibqp;
|
||||
ev.event = IB_EVENT_QP_LAST_WQE_REACHED;
|
||||
qhp->ibqp.event_handler(&ev, qhp->ibqp.qp_context);
|
||||
}
|
||||
|
||||
if (qhp->wq.flushed) {
|
||||
spin_unlock(&qhp->lock);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
|
||||
/*
|
||||
* Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved.
|
||||
* Copyright 2018-2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _EFA_H_
|
||||
@@ -57,15 +57,15 @@ struct efa_dev {
|
||||
u64 db_bar_addr;
|
||||
u64 db_bar_len;
|
||||
|
||||
unsigned int num_irq_vectors;
|
||||
int admin_msix_vector_idx;
|
||||
u32 num_irq_vectors;
|
||||
u32 admin_msix_vector_idx;
|
||||
struct efa_irq admin_irq;
|
||||
|
||||
struct efa_stats stats;
|
||||
|
||||
/* Array of completion EQs */
|
||||
struct efa_eq *eqs;
|
||||
unsigned int neqs;
|
||||
u32 neqs;
|
||||
|
||||
/* Only stores CQs with interrupts enabled */
|
||||
struct xarray cqs_xa;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
|
||||
/*
|
||||
* Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
|
||||
* Copyright 2018-2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _EFA_COM_H_
|
||||
@@ -65,7 +65,7 @@ struct efa_com_admin_queue {
|
||||
u16 depth;
|
||||
struct efa_com_admin_cq cq;
|
||||
struct efa_com_admin_sq sq;
|
||||
u16 msix_vector_idx;
|
||||
u32 msix_vector_idx;
|
||||
|
||||
unsigned long state;
|
||||
|
||||
@@ -89,7 +89,7 @@ struct efa_com_aenq {
|
||||
struct efa_aenq_handlers *aenq_handlers;
|
||||
dma_addr_t dma_addr;
|
||||
u32 cc; /* consumer counter */
|
||||
u16 msix_vector_idx;
|
||||
u32 msix_vector_idx;
|
||||
u16 depth;
|
||||
u8 phase;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
|
||||
/*
|
||||
* Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved.
|
||||
* Copyright 2018-2025 Amazon.com, Inc. or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -141,8 +141,7 @@ static int efa_request_irq(struct efa_dev *dev, struct efa_irq *irq)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void efa_setup_comp_irq(struct efa_dev *dev, struct efa_eq *eq,
|
||||
int vector)
|
||||
static void efa_setup_comp_irq(struct efa_dev *dev, struct efa_eq *eq, u32 vector)
|
||||
{
|
||||
u32 cpu;
|
||||
|
||||
@@ -305,7 +304,7 @@ static void efa_destroy_eq(struct efa_dev *dev, struct efa_eq *eq)
|
||||
efa_free_irq(dev, &eq->irq);
|
||||
}
|
||||
|
||||
static int efa_create_eq(struct efa_dev *dev, struct efa_eq *eq, u8 msix_vec)
|
||||
static int efa_create_eq(struct efa_dev *dev, struct efa_eq *eq, u32 msix_vec)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -328,21 +327,17 @@ err_free_comp_irq:
|
||||
|
||||
static int efa_create_eqs(struct efa_dev *dev)
|
||||
{
|
||||
unsigned int neqs = dev->dev_attr.max_eq;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
neqs = min_t(unsigned int, neqs,
|
||||
dev->num_irq_vectors - EFA_COMP_EQS_VEC_BASE);
|
||||
u32 neqs = dev->dev_attr.max_eq;
|
||||
int err, i;
|
||||
|
||||
neqs = min_t(u32, neqs, dev->num_irq_vectors - EFA_COMP_EQS_VEC_BASE);
|
||||
dev->neqs = neqs;
|
||||
dev->eqs = kcalloc(neqs, sizeof(*dev->eqs), GFP_KERNEL);
|
||||
if (!dev->eqs)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < neqs; i++) {
|
||||
err = efa_create_eq(dev, &dev->eqs[i],
|
||||
i + EFA_COMP_EQS_VEC_BASE);
|
||||
err = efa_create_eq(dev, &dev->eqs[i], i + EFA_COMP_EQS_VEC_BASE);
|
||||
if (err)
|
||||
goto err_destroy_eqs;
|
||||
}
|
||||
@@ -470,7 +465,6 @@ static void efa_ib_device_remove(struct efa_dev *dev)
|
||||
ibdev_info(&dev->ibdev, "Unregister ib device\n");
|
||||
ib_unregister_device(&dev->ibdev);
|
||||
efa_destroy_eqs(dev);
|
||||
efa_com_dev_reset(&dev->edev, EFA_REGS_RESET_NORMAL);
|
||||
efa_release_doorbell_bar(dev);
|
||||
}
|
||||
|
||||
@@ -643,12 +637,14 @@ err_disable_device:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static void efa_remove_device(struct pci_dev *pdev)
|
||||
static void efa_remove_device(struct pci_dev *pdev,
|
||||
enum efa_regs_reset_reason_types reset_reason)
|
||||
{
|
||||
struct efa_dev *dev = pci_get_drvdata(pdev);
|
||||
struct efa_com_dev *edev;
|
||||
|
||||
edev = &dev->edev;
|
||||
efa_com_dev_reset(edev, reset_reason);
|
||||
efa_com_admin_destroy(edev);
|
||||
efa_free_irq(dev, &dev->admin_irq);
|
||||
efa_disable_msix(dev);
|
||||
@@ -676,7 +672,7 @@ static int efa_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
return 0;
|
||||
|
||||
err_remove_device:
|
||||
efa_remove_device(pdev);
|
||||
efa_remove_device(pdev, EFA_REGS_RESET_INIT_ERR);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -685,7 +681,7 @@ static void efa_remove(struct pci_dev *pdev)
|
||||
struct efa_dev *dev = pci_get_drvdata(pdev);
|
||||
|
||||
efa_ib_device_remove(dev);
|
||||
efa_remove_device(pdev);
|
||||
efa_remove_device(pdev, EFA_REGS_RESET_NORMAL);
|
||||
}
|
||||
|
||||
static void efa_shutdown(struct pci_dev *pdev)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user