drivers/infiniband/hw/qedr/qedr_iw_cm.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/qedr/qedr_iw_cm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/qedr/qedr_iw_cm.c- Extension
.c- Size
- 21432 bytes
- Lines
- 820
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
net/ip.hnet/ipv6.hnet/udp.hnet/addrconf.hnet/route.hnet/ip6_route.hnet/flow.hqedr.hqedr_iw_cm.h
Detected Declarations
struct qedr_discon_workfunction Copyrightfunction qedr_fill_sockaddr6function qedr_iw_free_qpfunction qedr_iw_free_epfunction qedr_iw_mpa_requestfunction qedr_iw_issue_eventfunction qedr_iw_close_eventfunction qedr_iw_qp_eventfunction qedr_iw_disconnect_workerfunction qedr_iw_disconnect_eventfunction qedr_iw_passive_completefunction qedr_iw_active_completefunction qedr_iw_mpa_replyfunction qedr_iw_event_handlerfunction qedr_iw_get_vlan_ipv4function qedr_iw_get_vlan_ipv6function qedr_addr4_resolvefunction qedr_addr6_resolvefunction qedr_iw_connectfunction qedr_iw_create_listenfunction qedr_iw_destroy_listenfunction qedr_iw_acceptfunction qedr_iw_rejectfunction qedr_iw_qp_add_reffunction qedr_iw_qp_rem_ref
Annotated Snippet
struct qedr_discon_work {
struct work_struct work;
struct qedr_iw_ep *ep;
enum qed_iwarp_event_type event;
int status;
};
static void qedr_iw_disconnect_worker(struct work_struct *work)
{
struct qedr_discon_work *dwork =
container_of(work, struct qedr_discon_work, work);
struct qed_rdma_modify_qp_in_params qp_params = { 0 };
struct qedr_iw_ep *ep = dwork->ep;
struct qedr_dev *dev = ep->dev;
struct qedr_qp *qp = ep->qp;
struct iw_cm_event event;
/* The qp won't be released until we release the ep.
* the ep's refcnt was increased before calling this
* function, therefore it is safe to access qp
*/
if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_DISCONNECT,
&qp->iwarp_cm_flags))
goto out;
memset(&event, 0, sizeof(event));
event.status = dwork->status;
event.event = IW_CM_EVENT_DISCONNECT;
/* Success means graceful disconnect was requested. modifying
* to SQD is translated to graceful disconnect. O/w reset is sent
*/
if (dwork->status)
qp_params.new_state = QED_ROCE_QP_STATE_ERR;
else
qp_params.new_state = QED_ROCE_QP_STATE_SQD;
if (ep->cm_id)
ep->cm_id->event_handler(ep->cm_id, &event);
SET_FIELD(qp_params.modify_flags,
QED_RDMA_MODIFY_QP_VALID_NEW_STATE, 1);
dev->ops->rdma_modify_qp(dev->rdma_ctx, qp->qed_qp, &qp_params);
complete(&ep->qp->iwarp_cm_comp);
out:
kfree(dwork);
kref_put(&ep->refcnt, qedr_iw_free_ep);
}
static void
qedr_iw_disconnect_event(void *context,
struct qed_iwarp_cm_event_params *params)
{
struct qedr_discon_work *work;
struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
struct qedr_dev *dev = ep->dev;
work = kzalloc_obj(*work, GFP_ATOMIC);
if (!work)
return;
/* We can't get a close event before disconnect, but since
* we're scheduling a work queue we need to make sure close
* won't delete the ep, so we increase the refcnt
*/
kref_get(&ep->refcnt);
work->ep = ep;
work->event = params->event;
work->status = params->status;
INIT_WORK(&work->work, qedr_iw_disconnect_worker);
queue_work(dev->iwarp_wq, &work->work);
}
static void
qedr_iw_passive_complete(void *context,
struct qed_iwarp_cm_event_params *params)
{
struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
struct qedr_dev *dev = ep->dev;
/* We will only reach the following state if MPA_REJECT was called on
* passive. In this case there will be no associated QP.
*/
if ((params->status == -ECONNREFUSED) && (!ep->qp)) {
DP_DEBUG(dev, QEDR_MSG_IWARP,
Annotation
- Immediate include surface: `net/ip.h`, `net/ipv6.h`, `net/udp.h`, `net/addrconf.h`, `net/route.h`, `net/ip6_route.h`, `net/flow.h`, `qedr.h`.
- Detected declarations: `struct qedr_discon_work`, `function Copyright`, `function qedr_fill_sockaddr6`, `function qedr_iw_free_qp`, `function qedr_iw_free_ep`, `function qedr_iw_mpa_request`, `function qedr_iw_issue_event`, `function qedr_iw_close_event`, `function qedr_iw_qp_event`, `function qedr_iw_disconnect_worker`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.