xref: /xnu-8019.80.24/bsd/skywalk/channel/kern_channel_event.c (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
1 /*
2  * Copyright (c) 2019 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #include <skywalk/os_skywalk_private.h>
30 #include <skywalk/nexus/netif/nx_netif.h>
31 
32 /* function to send the packet transmit status event on the channel */
33 errno_t
kern_channel_event_transmit_status(const kern_packet_t ph,const ifnet_t ifp)34 kern_channel_event_transmit_status(const kern_packet_t ph, const ifnet_t ifp)
35 {
36 	errno_t err;
37 	packet_id_t pktid;
38 	kern_return_t tx_status;
39 	struct nexus_adapter *devna;
40 	char buf[CHANNEL_EVENT_TX_STATUS_LEN]__attribute((aligned(sizeof(uint64_t))));
41 	struct __kern_channel_event *event =
42 	    (struct __kern_channel_event *)(void *)buf;
43 	os_channel_event_packet_transmit_status_t *ts_ev =
44 	    (os_channel_event_packet_transmit_status_t *)&event->ev_data;
45 
46 	if (!IF_FULLY_ATTACHED(ifp)) {
47 		return ENXIO;
48 	}
49 	devna = &NA(ifp)->nifna_up;
50 	ASSERT((devna->na_type == NA_NETIF_DEV) ||
51 	    (devna->na_type == NA_NETIF_COMPAT_DEV));
52 	if (devna->na_channel_event_notify == NULL) {
53 		return ENOTSUP;
54 	}
55 	/*
56 	 * currently interface advisory is only supported for netif
57 	 * in low latency mode.
58 	 */
59 	if (!NETIF_IS_LOW_LATENCY(NIFNA(devna)->nifna_netif)) {
60 		return ENOTSUP;
61 	}
62 	err = __packet_get_packetid(ph, &pktid);
63 	if (err != 0) {
64 		return err;
65 	}
66 	(void) __packet_get_tx_completion_status(ph, &tx_status);
67 	ASSERT(tx_status != 0);
68 	event->ev_type = CHANNEL_EVENT_PACKET_TRANSMIT_STATUS;
69 	event->ev_flags = 0;
70 	event->_reserved = 0;
71 	event->ev_dlen = sizeof(os_channel_event_packet_transmit_status_t);
72 	ts_ev->packet_status = tx_status;
73 	ts_ev->packet_id = pktid;
74 	return devna->na_channel_event_notify(devna, SK_PTR_ADDR_KPKT(ph),
75 	           event, CHANNEL_EVENT_TX_STATUS_LEN);
76 }
77 
78 /* routine to post kevent notification for the event ring */
79 void
kern_channel_event_notify(struct __kern_channel_ring * kring)80 kern_channel_event_notify(struct __kern_channel_ring *kring)
81 {
82 	ASSERT(kring->ckr_tx == NR_TX);
83 
84 	SK_DF(SK_VERB_EVENTS, "%s(%d) na \"%s\" (0x%llx) kr 0x%llx",
85 	    sk_proc_name_address(current_proc()), sk_proc_pid(current_proc()),
86 	    KRNA(kring)->na_name, SK_KVA(KRNA(kring)), SK_KVA(kring));
87 
88 	na_post_event(kring, TRUE, FALSE, FALSE, CHAN_FILT_HINT_CHANNEL_EVENT);
89 }
90 
91 /* sync routine for the event ring */
92 int
kern_channel_event_sync(struct __kern_channel_ring * kring,struct proc * p,uint32_t flags)93 kern_channel_event_sync(struct __kern_channel_ring *kring, struct proc *p,
94     uint32_t flags)
95 {
96 #pragma unused(p, flags)
97 	(void) kr_reclaim(kring);
98 	return 0;
99 }
100