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