1da14cebeSEric Cheng /* 2da14cebeSEric Cheng * CDDL HEADER START 3da14cebeSEric Cheng * 4da14cebeSEric Cheng * The contents of this file are subject to the terms of the 5da14cebeSEric Cheng * Common Development and Distribution License (the "License"). 6da14cebeSEric Cheng * You may not use this file except in compliance with the License. 7da14cebeSEric Cheng * 8da14cebeSEric Cheng * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da14cebeSEric Cheng * or http://www.opensolaris.org/os/licensing. 10da14cebeSEric Cheng * See the License for the specific language governing permissions 11da14cebeSEric Cheng * and limitations under the License. 12da14cebeSEric Cheng * 13da14cebeSEric Cheng * When distributing Covered Code, include this CDDL HEADER in each 14da14cebeSEric Cheng * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da14cebeSEric Cheng * If applicable, add the following below this CDDL HEADER, with the 16da14cebeSEric Cheng * fields enclosed by brackets "[]" replaced with your own identifying 17da14cebeSEric Cheng * information: Portions Copyright [yyyy] [name of copyright owner] 18da14cebeSEric Cheng * 19da14cebeSEric Cheng * CDDL HEADER END 20da14cebeSEric Cheng */ 21da14cebeSEric Cheng 22da14cebeSEric Cheng /* 230dc2366fSVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24da14cebeSEric Cheng * Use is subject to license terms. 25*9d03a7a8SRyan Zezeski * Copyright 2017 Joyent, Inc. 26da14cebeSEric Cheng */ 27da14cebeSEric Cheng 28da14cebeSEric Cheng #ifndef _SYS_MAC_SOFT_RING_H 29da14cebeSEric Cheng #define _SYS_MAC_SOFT_RING_H 30da14cebeSEric Cheng 31da14cebeSEric Cheng #ifdef __cplusplus 32da14cebeSEric Cheng extern "C" { 33da14cebeSEric Cheng #endif 34da14cebeSEric Cheng 35da14cebeSEric Cheng #include <sys/types.h> 36da14cebeSEric Cheng #include <sys/cpuvar.h> 370dc2366fSVenugopal Iyer #include <sys/cpupart.h> 38da14cebeSEric Cheng #include <sys/processor.h> 39da14cebeSEric Cheng #include <sys/stream.h> 40da14cebeSEric Cheng #include <sys/squeue.h> 41da14cebeSEric Cheng #include <sys/dlpi.h> 42da14cebeSEric Cheng #include <sys/mac_impl.h> 430dc2366fSVenugopal Iyer #include <sys/mac_stat.h> 44da14cebeSEric Cheng 45da14cebeSEric Cheng #define S_RING_NAMELEN 64 46da14cebeSEric Cheng 472b24ab6bSSebastien Roy #define MAX_SR_FANOUT 24 48da14cebeSEric Cheng 49da14cebeSEric Cheng extern boolean_t mac_soft_ring_enable; 50da14cebeSEric Cheng extern boolean_t mac_latency_optimize; 51da14cebeSEric Cheng 52da14cebeSEric Cheng typedef struct mac_soft_ring_s mac_soft_ring_t; 53da14cebeSEric Cheng typedef struct mac_soft_ring_set_s mac_soft_ring_set_t; 54da14cebeSEric Cheng 55da14cebeSEric Cheng typedef void (*mac_soft_ring_drain_func_t)(mac_soft_ring_t *); 56da14cebeSEric Cheng typedef mac_tx_cookie_t (*mac_tx_func_t)(mac_soft_ring_set_t *, mblk_t *, 57da14cebeSEric Cheng uintptr_t, uint16_t, mblk_t **); 58da14cebeSEric Cheng 59da14cebeSEric Cheng 60da14cebeSEric Cheng /* Tx notify callback */ 61da14cebeSEric Cheng typedef struct mac_tx_notify_cb_s { 62da14cebeSEric Cheng mac_cb_t mtnf_link; /* Linked list of callbacks */ 63da14cebeSEric Cheng mac_tx_notify_t mtnf_fn; /* The callback function */ 64da14cebeSEric Cheng void *mtnf_arg; /* Callback function argument */ 65da14cebeSEric Cheng } mac_tx_notify_cb_t; 66da14cebeSEric Cheng 67da14cebeSEric Cheng struct mac_soft_ring_s { 68da14cebeSEric Cheng /* Keep the most used members 64bytes cache aligned */ 69da14cebeSEric Cheng kmutex_t s_ring_lock; /* lock before using any member */ 70da14cebeSEric Cheng uint16_t s_ring_type; /* processing model of the sq */ 71da14cebeSEric Cheng uint16_t s_ring_state; /* state flags and message count */ 72da14cebeSEric Cheng int s_ring_count; /* # of mblocks in mac_soft_ring */ 73da14cebeSEric Cheng size_t s_ring_size; /* Size of data queued */ 74da14cebeSEric Cheng mblk_t *s_ring_first; /* first mblk chain or NULL */ 75da14cebeSEric Cheng mblk_t *s_ring_last; /* last mblk chain or NULL */ 76da14cebeSEric Cheng 77da14cebeSEric Cheng mac_direct_rx_t s_ring_rx_func; 78da14cebeSEric Cheng void *s_ring_rx_arg1; 79da14cebeSEric Cheng mac_resource_handle_t s_ring_rx_arg2; 80da14cebeSEric Cheng 81da14cebeSEric Cheng /* 82da14cebeSEric Cheng * Threshold after which packets get dropped. 83da14cebeSEric Cheng * Is always greater than s_ring_tx_hiwat 84da14cebeSEric Cheng */ 85da14cebeSEric Cheng int s_ring_tx_max_q_cnt; 86da14cebeSEric Cheng /* # of mblocks after which to apply flow control */ 87da14cebeSEric Cheng int s_ring_tx_hiwat; 88da14cebeSEric Cheng /* # of mblocks after which to relieve flow control */ 89da14cebeSEric Cheng int s_ring_tx_lowat; 90da14cebeSEric Cheng boolean_t s_ring_tx_woken_up; 91da14cebeSEric Cheng uint32_t s_ring_hiwat_cnt; /* times blocked for Tx descs */ 92da14cebeSEric Cheng 93da14cebeSEric Cheng void *s_ring_tx_arg1; 94da14cebeSEric Cheng void *s_ring_tx_arg2; 95da14cebeSEric Cheng 96da14cebeSEric Cheng /* Tx notify callback */ 97da14cebeSEric Cheng mac_cb_info_t s_ring_notify_cb_info; /* cb list info */ 98da14cebeSEric Cheng mac_cb_t *s_ring_notify_cb_list; /* The cb list */ 99da14cebeSEric Cheng 100da14cebeSEric Cheng clock_t s_ring_awaken; /* time async thread was awakened */ 101da14cebeSEric Cheng 102da14cebeSEric Cheng kthread_t *s_ring_run; /* Current thread processing sq */ 103da14cebeSEric Cheng processorid_t s_ring_cpuid; /* processor to bind to */ 104da14cebeSEric Cheng processorid_t s_ring_cpuid_save; /* saved cpuid during offline */ 105da14cebeSEric Cheng kcondvar_t s_ring_async; /* async thread blocks on */ 106da14cebeSEric Cheng clock_t s_ring_wait; /* lbolts to wait after a fill() */ 107da14cebeSEric Cheng timeout_id_t s_ring_tid; /* timer id of pending timeout() */ 108da14cebeSEric Cheng kthread_t *s_ring_worker; /* kernel thread id */ 109da14cebeSEric Cheng char s_ring_name[S_RING_NAMELEN + 1]; 110da14cebeSEric Cheng uint32_t s_ring_total_inpkt; 1110dc2366fSVenugopal Iyer uint32_t s_ring_total_rbytes; 112da14cebeSEric Cheng uint32_t s_ring_drops; 113da14cebeSEric Cheng struct mac_client_impl_s *s_ring_mcip; 114da14cebeSEric Cheng kstat_t *s_ring_ksp; 115da14cebeSEric Cheng 116da14cebeSEric Cheng /* Teardown, poll disable control ops */ 117da14cebeSEric Cheng kcondvar_t s_ring_client_cv; /* Client wait for control op */ 118da14cebeSEric Cheng 119da14cebeSEric Cheng mac_soft_ring_set_t *s_ring_set; /* The SRS this ring belongs to */ 120da14cebeSEric Cheng mac_soft_ring_t *s_ring_next; 121da14cebeSEric Cheng mac_soft_ring_t *s_ring_prev; 122da14cebeSEric Cheng mac_soft_ring_drain_func_t s_ring_drain_func; 1230dc2366fSVenugopal Iyer 1240dc2366fSVenugopal Iyer mac_tx_stats_t s_st_stat; 125da14cebeSEric Cheng }; 126da14cebeSEric Cheng 127da14cebeSEric Cheng typedef void (*mac_srs_drain_proc_t)(mac_soft_ring_set_t *, uint_t); 128da14cebeSEric Cheng 129da14cebeSEric Cheng /* Transmit side Soft Ring Set */ 130da14cebeSEric Cheng typedef struct mac_srs_tx_s { 131da14cebeSEric Cheng /* Members for Tx size processing */ 132da14cebeSEric Cheng uint32_t st_mode; 133da14cebeSEric Cheng mac_tx_func_t st_func; 134da14cebeSEric Cheng void *st_arg1; 135da14cebeSEric Cheng void *st_arg2; 136da14cebeSEric Cheng mac_group_t *st_group; /* TX group for share */ 137da14cebeSEric Cheng boolean_t st_woken_up; 138da14cebeSEric Cheng 139da14cebeSEric Cheng /* 140da14cebeSEric Cheng * st_max_q_cnt is the queue depth threshold to limit 141da14cebeSEric Cheng * outstanding packets on the Tx SRS. Once the limit 142da14cebeSEric Cheng * is reached, Tx SRS will drop packets until the 143da14cebeSEric Cheng * limit goes below the threshold. 144da14cebeSEric Cheng */ 145da14cebeSEric Cheng uint32_t st_max_q_cnt; /* max. outstanding packets */ 146da14cebeSEric Cheng /* 147da14cebeSEric Cheng * st_hiwat is used Tx serializer and bandwidth mode. 148da14cebeSEric Cheng * This is the queue depth threshold upto which 149da14cebeSEric Cheng * packets will get buffered with no flow-control 150da14cebeSEric Cheng * back pressure applied to the caller. Once this 151da14cebeSEric Cheng * threshold is reached, back pressure will be 152da14cebeSEric Cheng * applied to the caller of mac_tx() (mac_tx() starts 153da14cebeSEric Cheng * returning a cookie to indicate a blocked SRS). 154da14cebeSEric Cheng * st_hiwat should always be lesser than or equal to 155da14cebeSEric Cheng * st_max_q_cnt. 156da14cebeSEric Cheng */ 157da14cebeSEric Cheng uint32_t st_hiwat; /* mblk cnt to apply flow control */ 158da14cebeSEric Cheng uint32_t st_lowat; /* mblk cnt to relieve flow control */ 159da14cebeSEric Cheng uint32_t st_hiwat_cnt; /* times blocked for Tx descs */ 1600dc2366fSVenugopal Iyer mac_tx_stats_t st_stat; 1610dc2366fSVenugopal Iyer mac_capab_aggr_t st_capab_aggr; 1620dc2366fSVenugopal Iyer /* 1630dc2366fSVenugopal Iyer * st_soft_rings is used as an array to store aggr Tx soft 1640dc2366fSVenugopal Iyer * rings. When aggr_find_tx_ring() returns a pseudo ring, 1650dc2366fSVenugopal Iyer * the associated soft ring has to be found. st_soft_rings 1660dc2366fSVenugopal Iyer * array stores the soft ring associated with a pseudo Tx 1670dc2366fSVenugopal Iyer * ring and it can be accessed using the pseudo ring 1680dc2366fSVenugopal Iyer * index (mr_index). Note that the ring index is unique 1690dc2366fSVenugopal Iyer * for each ring in a group. 1700dc2366fSVenugopal Iyer */ 1710dc2366fSVenugopal Iyer mac_soft_ring_t **st_soft_rings; 172da14cebeSEric Cheng } mac_srs_tx_t; 173da14cebeSEric Cheng 174da14cebeSEric Cheng /* Receive side Soft Ring Set */ 175da14cebeSEric Cheng typedef struct mac_srs_rx_s { 176da14cebeSEric Cheng /* 177da14cebeSEric Cheng * Upcall Function for fanout, Rx processing etc. Perhaps 178da14cebeSEric Cheng * the same 3 members below can be used for Tx 179da14cebeSEric Cheng * processing, but looking around, mac_rx_func_t has 180da14cebeSEric Cheng * proliferated too much into various files at different 181da14cebeSEric Cheng * places. I am leaving the consolidation battle for 182da14cebeSEric Cheng * another day. 183da14cebeSEric Cheng */ 184da14cebeSEric Cheng mac_direct_rx_t sr_func; /* srs_lock */ 185da14cebeSEric Cheng void *sr_arg1; /* srs_lock */ 186da14cebeSEric Cheng mac_resource_handle_t sr_arg2; /* srs_lock */ 187da14cebeSEric Cheng mac_rx_func_t sr_lower_proc; /* Atomically changed */ 188da14cebeSEric Cheng uint32_t sr_poll_pkt_cnt; 189da14cebeSEric Cheng uint32_t sr_poll_thres; 190da14cebeSEric Cheng 191da14cebeSEric Cheng /* mblk cnt to apply flow control */ 192da14cebeSEric Cheng uint32_t sr_hiwat; 193da14cebeSEric Cheng /* mblk cnt to relieve flow control */ 194da14cebeSEric Cheng uint32_t sr_lowat; 1950dc2366fSVenugopal Iyer mac_rx_stats_t sr_stat; 196da14cebeSEric Cheng 197da14cebeSEric Cheng /* Times polling was enabled */ 198da14cebeSEric Cheng uint32_t sr_poll_on; 199da14cebeSEric Cheng /* Times polling was enabled by worker thread */ 200da14cebeSEric Cheng uint32_t sr_worker_poll_on; 201da14cebeSEric Cheng /* Times polling was disabled */ 202da14cebeSEric Cheng uint32_t sr_poll_off; 203da14cebeSEric Cheng /* Poll thread signalled count */ 204da14cebeSEric Cheng uint32_t sr_poll_thr_sig; 205da14cebeSEric Cheng /* Poll thread busy */ 206da14cebeSEric Cheng uint32_t sr_poll_thr_busy; 207da14cebeSEric Cheng /* SRS drains, stays in poll mode but doesn't poll */ 208da14cebeSEric Cheng uint32_t sr_poll_drain_no_poll; 209da14cebeSEric Cheng /* 210da14cebeSEric Cheng * SRS has nothing to do and no packets in H/W but 211da14cebeSEric Cheng * there is a backlog in softrings. SRS stays in 212da14cebeSEric Cheng * poll mode but doesn't do polling. 213da14cebeSEric Cheng */ 214da14cebeSEric Cheng uint32_t sr_poll_no_poll; 215da14cebeSEric Cheng /* Active polling restarted */ 216da14cebeSEric Cheng uint32_t sr_below_hiwat; 217da14cebeSEric Cheng /* Found packets in last poll so try and poll again */ 218da14cebeSEric Cheng uint32_t sr_poll_again; 219da14cebeSEric Cheng /* 220da14cebeSEric Cheng * Packets in queue but poll thread not allowed to process so 221da14cebeSEric Cheng * signal the worker thread. 222da14cebeSEric Cheng */ 223da14cebeSEric Cheng uint32_t sr_poll_sig_worker; 224da14cebeSEric Cheng /* 225da14cebeSEric Cheng * Poll thread has nothing to do and H/W has nothing so 226da14cebeSEric Cheng * reenable the interrupts. 227da14cebeSEric Cheng */ 228da14cebeSEric Cheng uint32_t sr_poll_intr_enable; 229da14cebeSEric Cheng /* 230da14cebeSEric Cheng * Poll thread has nothing to do and worker thread was already 231da14cebeSEric Cheng * running so it can decide to reenable interrupt or poll again. 232da14cebeSEric Cheng */ 233da14cebeSEric Cheng uint32_t sr_poll_goto_sleep; 234da14cebeSEric Cheng /* Worker thread goes back to draining the queue */ 235da14cebeSEric Cheng uint32_t sr_drain_again; 2368ac29891SEric Cheng /* More Packets in queue so signal the poll thread to drain */ 237ae6aa22aSVenugopal Iyer uint32_t sr_drain_poll_sig; 2388ac29891SEric Cheng /* More Packets in queue so signal the worker thread to drain */ 2398ac29891SEric Cheng uint32_t sr_drain_worker_sig; 240da14cebeSEric Cheng /* Poll thread is already running so worker has nothing to do */ 241da14cebeSEric Cheng uint32_t sr_drain_poll_running; 242da14cebeSEric Cheng /* We have packets already queued so keep polling */ 243da14cebeSEric Cheng uint32_t sr_drain_keep_polling; 244da14cebeSEric Cheng /* Drain is done and interrupts are reenabled */ 245da14cebeSEric Cheng uint32_t sr_drain_finish_intr; 246da14cebeSEric Cheng /* Polling thread needs to schedule worker wakeup */ 247da14cebeSEric Cheng uint32_t sr_poll_worker_wakeup; 248da14cebeSEric Cheng } mac_srs_rx_t; 249da14cebeSEric Cheng 250da14cebeSEric Cheng /* 251da14cebeSEric Cheng * mac_soft_ring_set_s: 252da14cebeSEric Cheng * This is used both for Tx and Rx side. The srs_type identifies Rx or 253da14cebeSEric Cheng * Tx type. 254da14cebeSEric Cheng * 255da14cebeSEric Cheng * Note that the structure is carefully crafted, with Rx elements coming 256da14cebeSEric Cheng * first followed by Tx specific members. Future additions to this 257da14cebeSEric Cheng * structure should follow the same guidelines. 258da14cebeSEric Cheng * 259da14cebeSEric Cheng * Rx-side notes: 260da14cebeSEric Cheng * mac_rx_classify_flow_add() always creates a mac_soft_ring_set_t and fn_flow 261da14cebeSEric Cheng * points to info from it (func = srs_lower_proc, arg = soft_ring_set). On 262da14cebeSEric Cheng * interrupt path, srs_lower_proc does B/W adjustment and switch to polling mode 263da14cebeSEric Cheng * (if poll capable) and feeds the packets to soft_ring_list via choosen 264da14cebeSEric Cheng * fanout type (specified by srs_type). In poll mode, the poll thread which is 265da14cebeSEric Cheng * also a pointer can pick up the packets and feed them to various 266da14cebeSEric Cheng * soft_ring_list. 267da14cebeSEric Cheng * 268da14cebeSEric Cheng * The srs_type can either be protocol based or fanout based where fanout itelf 269da14cebeSEric Cheng * can be various types 270da14cebeSEric Cheng * 271da14cebeSEric Cheng * The polling works by turning off interrupts as soon as a packets 272da14cebeSEric Cheng * are queued on the soft ring set. Once the backlog is clear and poll 273da14cebeSEric Cheng * thread return empty handed i.e. Rx ring doesn't have anything, the 274da14cebeSEric Cheng * interrupt is turned back on. For this purpose we keep a separate 275da14cebeSEric Cheng * srs_poll_pkt_cnt counter which tracks the packets queued between SRS 276da14cebeSEric Cheng * and the soft rings as well. The counter is incremented when packets 277da14cebeSEric Cheng * are queued and decremented when SRS processes them (in case it has 278da14cebeSEric Cheng * no soft rings) or the soft ring process them. Its important that 279da14cebeSEric Cheng * in case SRS has softrings, the decrement doesn't happen till the 280da14cebeSEric Cheng * packet is processed by the soft rings since it takes very little time 281da14cebeSEric Cheng * for SRS to queue packet from SRS to soft rings and it will keep 282da14cebeSEric Cheng * bringing more packets in the system faster than soft rings can 283da14cebeSEric Cheng * process them. 284da14cebeSEric Cheng * 285da14cebeSEric Cheng * Tx side notes: 286da14cebeSEric Cheng * The srs structure acts as a serializer with a worker thread. The 287da14cebeSEric Cheng * default behavior of srs though is to act as a pass-thru. The queues 288da14cebeSEric Cheng * (srs_first, srs_last, srs_count) get used when Tx ring runs out of Tx 289da14cebeSEric Cheng * descriptors or to enforce bandwidth limits. 290da14cebeSEric Cheng * 291da14cebeSEric Cheng * When multiple Tx rings are present, the SRS state will be set to 292da14cebeSEric Cheng * SRS_FANOUT_OTH. Outgoing packets coming into mac_tx_srs_process() 293da14cebeSEric Cheng * function will be fanned out to one of the Tx side soft rings based on 294da14cebeSEric Cheng * a hint passed in mac_tx_srs_process(). Each soft ring, in turn, will 295da14cebeSEric Cheng * be associated with a distinct h/w Tx ring. 296da14cebeSEric Cheng */ 297da14cebeSEric Cheng 298da14cebeSEric Cheng struct mac_soft_ring_set_s { 299da14cebeSEric Cheng /* 300da14cebeSEric Cheng * Common elements, common to both Rx and Tx SRS type. 301da14cebeSEric Cheng * The following block of fields are protected by srs_lock 302da14cebeSEric Cheng */ 303da14cebeSEric Cheng kmutex_t srs_lock; 304da14cebeSEric Cheng uint32_t srs_type; 305da14cebeSEric Cheng uint32_t srs_state; /* state flags */ 306da14cebeSEric Cheng uint32_t srs_count; 307da14cebeSEric Cheng mblk_t *srs_first; /* first mblk chain or NULL */ 308da14cebeSEric Cheng mblk_t *srs_last; /* last mblk chain or NULL */ 309da14cebeSEric Cheng kcondvar_t srs_async; /* cv for worker thread */ 310da14cebeSEric Cheng kcondvar_t srs_cv; /* cv for poll thread */ 311da14cebeSEric Cheng kcondvar_t srs_quiesce_done_cv; /* cv for removal */ 312da14cebeSEric Cheng timeout_id_t srs_tid; /* timeout id for pending timeout */ 313da14cebeSEric Cheng 314da14cebeSEric Cheng /* 315da14cebeSEric Cheng * List of soft rings & processing function. 316da14cebeSEric Cheng * The following block is protected by Rx quiescence. 317da14cebeSEric Cheng * i.e. they can be changed only after quiescing the SRS 318da14cebeSEric Cheng * Protected by srs_lock. 319da14cebeSEric Cheng */ 320da14cebeSEric Cheng mac_soft_ring_t *srs_soft_ring_head; 321da14cebeSEric Cheng mac_soft_ring_t *srs_soft_ring_tail; 322da14cebeSEric Cheng int srs_soft_ring_count; 323da14cebeSEric Cheng int srs_soft_ring_quiesced_count; 324da14cebeSEric Cheng int srs_soft_ring_condemned_count; 325da14cebeSEric Cheng mac_soft_ring_t **srs_tcp_soft_rings; 326da14cebeSEric Cheng int srs_tcp_ring_count; 327da14cebeSEric Cheng mac_soft_ring_t **srs_udp_soft_rings; 328da14cebeSEric Cheng int srs_udp_ring_count; 329da14cebeSEric Cheng mac_soft_ring_t **srs_oth_soft_rings; 330da14cebeSEric Cheng int srs_oth_ring_count; 3310dc2366fSVenugopal Iyer /* 3320dc2366fSVenugopal Iyer * srs_tx_soft_rings is used by tx_srs in 3330dc2366fSVenugopal Iyer * when operating in multi tx ring mode. 3340dc2366fSVenugopal Iyer */ 3350dc2366fSVenugopal Iyer mac_soft_ring_t **srs_tx_soft_rings; 3360dc2366fSVenugopal Iyer int srs_tx_ring_count; 337da14cebeSEric Cheng 338da14cebeSEric Cheng /* 339da14cebeSEric Cheng * Bandwidth control related members. 340da14cebeSEric Cheng * They are common to both Rx- and Tx-side. 341da14cebeSEric Cheng * Following protected by srs_lock 342da14cebeSEric Cheng */ 343da14cebeSEric Cheng mac_bw_ctl_t *srs_bw; 344da14cebeSEric Cheng size_t srs_size; /* Size of packets queued in bytes */ 345da14cebeSEric Cheng pri_t srs_pri; 346da14cebeSEric Cheng 347da14cebeSEric Cheng mac_soft_ring_set_t *srs_next; /* mac_srs_g_lock */ 348da14cebeSEric Cheng mac_soft_ring_set_t *srs_prev; /* mac_srs_g_lock */ 349da14cebeSEric Cheng 350da14cebeSEric Cheng /* Attribute specific drain func (BW ctl vs non-BW ctl) */ 351da14cebeSEric Cheng mac_srs_drain_proc_t srs_drain_func; /* Write once (WO) */ 352da14cebeSEric Cheng 353da14cebeSEric Cheng /* 354da14cebeSEric Cheng * If the associated ring is exclusively used by a mac client, e.g., 355da14cebeSEric Cheng * an aggregation, this fields is used to keep a reference to the 356da14cebeSEric Cheng * MAC client's pseudo ring. 357da14cebeSEric Cheng */ 358da14cebeSEric Cheng mac_resource_handle_t srs_mrh; 359da14cebeSEric Cheng /* 360da14cebeSEric Cheng * The following blocks are write once (WO) and valid for the life 361da14cebeSEric Cheng * of the SRS 362da14cebeSEric Cheng */ 363da14cebeSEric Cheng struct mac_client_impl_s *srs_mcip; /* back ptr to mac client */ 364da14cebeSEric Cheng void *srs_flent; /* back ptr to flent */ 365da14cebeSEric Cheng mac_ring_t *srs_ring; /* Ring Descriptor */ 366da14cebeSEric Cheng 367da14cebeSEric Cheng /* Teardown, disable control ops */ 368da14cebeSEric Cheng kcondvar_t srs_client_cv; /* Client wait for the control op */ 369da14cebeSEric Cheng 370da14cebeSEric Cheng kthread_t *srs_worker; /* WO, worker thread */ 371da14cebeSEric Cheng kthread_t *srs_poll_thr; /* WO, poll thread */ 372da14cebeSEric Cheng 373da14cebeSEric Cheng uint_t srs_ind; /* Round Robin indx for picking up SR */ 374da14cebeSEric Cheng processorid_t srs_worker_cpuid; /* processor to bind to */ 375da14cebeSEric Cheng processorid_t srs_worker_cpuid_save; /* saved cpuid during offline */ 376da14cebeSEric Cheng processorid_t srs_poll_cpuid; /* processor to bind to */ 377da14cebeSEric Cheng processorid_t srs_poll_cpuid_save; /* saved cpuid during offline */ 378da14cebeSEric Cheng uint_t srs_fanout_state; 379da14cebeSEric Cheng mac_cpus_t srs_cpu; 380da14cebeSEric Cheng 381da14cebeSEric Cheng mac_srs_rx_t srs_rx; 382da14cebeSEric Cheng mac_srs_tx_t srs_tx; 3830dc2366fSVenugopal Iyer kstat_t *srs_ksp; 384da14cebeSEric Cheng }; 385da14cebeSEric Cheng 386da14cebeSEric Cheng /* 387da14cebeSEric Cheng * type flags - combination allowed to process and drain the queue 388da14cebeSEric Cheng */ 389da14cebeSEric Cheng #define ST_RING_WORKER_ONLY 0x0001 /* Worker thread only */ 390da14cebeSEric Cheng #define ST_RING_ANY 0x0002 /* Any thread can process the queue */ 391da14cebeSEric Cheng #define ST_RING_TCP 0x0004 392da14cebeSEric Cheng #define ST_RING_UDP 0x0008 393da14cebeSEric Cheng #define ST_RING_OTH 0x0010 394da14cebeSEric Cheng 395da14cebeSEric Cheng #define ST_RING_BW_CTL 0x0020 396da14cebeSEric Cheng #define ST_RING_TX 0x0040 397da14cebeSEric Cheng 398da14cebeSEric Cheng /* 399da14cebeSEric Cheng * State flags. 400da14cebeSEric Cheng */ 401da14cebeSEric Cheng #define S_RING_PROC 0x0001 /* being processed */ 402da14cebeSEric Cheng #define S_RING_BOUND 0x0002 /* Worker thread is bound to a cpu */ 403da14cebeSEric Cheng #define S_RING_BLOCK 0x0004 /* No Tx descs */ 404da14cebeSEric Cheng #define S_RING_TX_HIWAT 0x0008 /* Tx high watermark reached */ 405da14cebeSEric Cheng 406da14cebeSEric Cheng #define S_RING_WAKEUP_CLIENT 0x0010 /* flow ctrl, client wakeup needed */ 407da14cebeSEric Cheng #define S_RING_BLANK 0x0020 /* Has been put into polling mode */ 408da14cebeSEric Cheng #define S_RING_CLIENT_WAIT 0x0040 /* Client waiting for control op */ 409da14cebeSEric Cheng 410da14cebeSEric Cheng #define S_RING_CONDEMNED 0x0100 /* Being torn down */ 411da14cebeSEric Cheng #define S_RING_CONDEMNED_DONE 0x0200 /* Being torn down */ 412da14cebeSEric Cheng #define S_RING_QUIESCE 0x0400 /* No traffic flow, transient flag */ 413da14cebeSEric Cheng #define S_RING_QUIESCE_DONE 0x0800 /* No traffic flow, transient flag */ 414da14cebeSEric Cheng 415da14cebeSEric Cheng #define S_RING_RESTART 0x1000 /* Go back to normal traffic flow */ 416da14cebeSEric Cheng #define S_RING_ENQUEUED 0x2000 /* Pkts enqueued in Tx soft ring */ 417da14cebeSEric Cheng 418da14cebeSEric Cheng /* 419da14cebeSEric Cheng * arguments for processors to bind to 420da14cebeSEric Cheng */ 421da14cebeSEric Cheng #define S_RING_BIND_NONE -1 422da14cebeSEric Cheng 423da14cebeSEric Cheng /* 424da14cebeSEric Cheng * defines for srs_type - identifies a link or a sub-flow 425da14cebeSEric Cheng * and other static characteristics of a SRS like a tx 426da14cebeSEric Cheng * srs, tcp only srs, etc. 427da14cebeSEric Cheng */ 428da14cebeSEric Cheng #define SRST_LINK 0x00000001 429da14cebeSEric Cheng #define SRST_FLOW 0x00000002 430da14cebeSEric Cheng #define SRST_NO_SOFT_RINGS 0x00000004 431da14cebeSEric Cheng #define SRST_TCP_ONLY 0x00000008 432da14cebeSEric Cheng 433da14cebeSEric Cheng #define SRST_FANOUT_PROTO 0x00000010 434da14cebeSEric Cheng #define SRST_FANOUT_SRC_IP 0x00000020 435da14cebeSEric Cheng #define SRST_FANOUT_OTH 0x00000040 436da14cebeSEric Cheng #define SRST_DEFAULT_GRP 0x00000080 437da14cebeSEric Cheng 438da14cebeSEric Cheng #define SRST_TX 0x00000100 439da14cebeSEric Cheng #define SRST_BW_CONTROL 0x00000200 440da14cebeSEric Cheng #define SRST_DIRECT_POLL 0x00000400 441da14cebeSEric Cheng 442da14cebeSEric Cheng #define SRST_DLS_BYPASS 0x00001000 443da14cebeSEric Cheng #define SRST_CLIENT_POLL_ENABLED 0x00002000 444da14cebeSEric Cheng 445da14cebeSEric Cheng /* 446da14cebeSEric Cheng * soft ring set flags. These bits are dynamic in nature and get 447da14cebeSEric Cheng * applied to srs_state. They reflect the state of SRS at any 448da14cebeSEric Cheng * point of time 449da14cebeSEric Cheng */ 450da14cebeSEric Cheng #define SRS_BLANK 0x00000001 451da14cebeSEric Cheng #define SRS_WORKER_BOUND 0x00000002 452da14cebeSEric Cheng #define SRS_POLL_BOUND 0x00000004 453da14cebeSEric Cheng #define SRS_POLLING_CAPAB 0x00000008 454da14cebeSEric Cheng 455da14cebeSEric Cheng #define SRS_PROC 0x00000010 456da14cebeSEric Cheng #define SRS_GET_PKTS 0x00000020 457da14cebeSEric Cheng #define SRS_POLLING 0x00000040 458da14cebeSEric Cheng #define SRS_BW_ENFORCED 0x00000080 459da14cebeSEric Cheng 460da14cebeSEric Cheng #define SRS_WORKER 0x00000100 461da14cebeSEric Cheng #define SRS_ENQUEUED 0x00000200 462da14cebeSEric Cheng #define SRS_ANY_PROCESS 0x00000400 463da14cebeSEric Cheng #define SRS_PROC_FAST 0x00000800 464da14cebeSEric Cheng 465da14cebeSEric Cheng #define SRS_POLL_PROC 0x00001000 466da14cebeSEric Cheng #define SRS_TX_BLOCKED 0x00002000 /* out of Tx descs */ 467da14cebeSEric Cheng #define SRS_TX_HIWAT 0x00004000 /* Tx count exceeds hiwat */ 468da14cebeSEric Cheng #define SRS_TX_WAKEUP_CLIENT 0x00008000 /* Flow-ctl: wakeup client */ 469da14cebeSEric Cheng 470da14cebeSEric Cheng #define SRS_CLIENT_PROC 0x00010000 471da14cebeSEric Cheng #define SRS_CLIENT_WAIT 0x00020000 472da14cebeSEric Cheng #define SRS_QUIESCE 0x00040000 473da14cebeSEric Cheng #define SRS_QUIESCE_DONE 0x00080000 474da14cebeSEric Cheng 475da14cebeSEric Cheng #define SRS_CONDEMNED 0x00100000 476da14cebeSEric Cheng #define SRS_CONDEMNED_DONE 0x00200000 477da14cebeSEric Cheng #define SRS_POLL_THR_QUIESCED 0x00400000 478da14cebeSEric Cheng #define SRS_RESTART 0x00800000 479da14cebeSEric Cheng 480da14cebeSEric Cheng #define SRS_RESTART_DONE 0x01000000 481da14cebeSEric Cheng #define SRS_POLL_THR_RESTART 0x02000000 482da14cebeSEric Cheng #define SRS_IN_GLIST 0x04000000 483da14cebeSEric Cheng #define SRS_POLL_THR_EXITED 0x08000000 484da14cebeSEric Cheng 485da14cebeSEric Cheng #define SRS_QUIESCE_PERM 0x10000000 486da14cebeSEric Cheng #define SRS_LATENCY_OPT 0x20000000 487ae6aa22aSVenugopal Iyer #define SRS_SOFTRING_QUEUE 0x40000000 488da14cebeSEric Cheng 489da14cebeSEric Cheng #define SRS_QUIESCED(srs) (srs->srs_state & SRS_QUIESCE_DONE) 490da14cebeSEric Cheng 491da14cebeSEric Cheng /* 492da14cebeSEric Cheng * If the SRS_QUIESCE_PERM flag is set, the SRS worker thread will not be 493da14cebeSEric Cheng * able to be restarted. 494da14cebeSEric Cheng */ 495da14cebeSEric Cheng #define SRS_QUIESCED_PERMANENT(srs) (srs->srs_state & SRS_QUIESCE_PERM) 496da14cebeSEric Cheng 497da14cebeSEric Cheng /* 498da14cebeSEric Cheng * soft ring set (SRS) Tx modes 499da14cebeSEric Cheng */ 500da14cebeSEric Cheng typedef enum { 501da14cebeSEric Cheng SRS_TX_DEFAULT = 0, 502da14cebeSEric Cheng SRS_TX_SERIALIZE, 503da14cebeSEric Cheng SRS_TX_FANOUT, 504da14cebeSEric Cheng SRS_TX_BW, 5050dc2366fSVenugopal Iyer SRS_TX_BW_FANOUT, 5060dc2366fSVenugopal Iyer SRS_TX_AGGR, 5070dc2366fSVenugopal Iyer SRS_TX_BW_AGGR 508da14cebeSEric Cheng } mac_tx_srs_mode_t; 509da14cebeSEric Cheng 510da14cebeSEric Cheng /* 511da14cebeSEric Cheng * SRS fanout states 512da14cebeSEric Cheng */ 513da14cebeSEric Cheng typedef enum { 514da14cebeSEric Cheng SRS_FANOUT_UNINIT = 0, 515da14cebeSEric Cheng SRS_FANOUT_INIT, 516da14cebeSEric Cheng SRS_FANOUT_REINIT 517da14cebeSEric Cheng } mac_srs_fanout_state_t; 518da14cebeSEric Cheng 519da14cebeSEric Cheng /* 520da14cebeSEric Cheng * Structure for dls statistics 521da14cebeSEric Cheng */ 522da14cebeSEric Cheng struct dls_kstats { 523da14cebeSEric Cheng kstat_named_t dlss_soft_ring_pkt_drop; 524da14cebeSEric Cheng }; 525da14cebeSEric Cheng 526da14cebeSEric Cheng extern struct dls_kstats dls_kstat; 527da14cebeSEric Cheng 528da14cebeSEric Cheng #define DLS_BUMP_STAT(x, y) (dls_kstat.x.value.ui32 += y) 529da14cebeSEric Cheng 530da14cebeSEric Cheng /* Turn dynamic polling off */ 531da14cebeSEric Cheng #define MAC_SRS_POLLING_OFF(mac_srs) { \ 532da14cebeSEric Cheng ASSERT(MUTEX_HELD(&(mac_srs)->srs_lock)); \ 533da14cebeSEric Cheng if (((mac_srs)->srs_state & (SRS_POLLING_CAPAB|SRS_POLLING)) == \ 534da14cebeSEric Cheng (SRS_POLLING_CAPAB|SRS_POLLING)) { \ 535da14cebeSEric Cheng (mac_srs)->srs_state &= ~SRS_POLLING; \ 536da14cebeSEric Cheng (void) mac_hwring_enable_intr((mac_ring_handle_t) \ 537da14cebeSEric Cheng (mac_srs)->srs_ring); \ 538da14cebeSEric Cheng (mac_srs)->srs_rx.sr_poll_off++; \ 539da14cebeSEric Cheng } \ 540da14cebeSEric Cheng } 541da14cebeSEric Cheng 542da14cebeSEric Cheng #define MAC_COUNT_CHAIN(mac_srs, head, tail, cnt, sz) { \ 543da14cebeSEric Cheng mblk_t *tmp; \ 544da14cebeSEric Cheng boolean_t bw_ctl = B_FALSE; \ 545da14cebeSEric Cheng \ 546da14cebeSEric Cheng ASSERT((head) != NULL); \ 547da14cebeSEric Cheng cnt = 0; \ 548da14cebeSEric Cheng sz = 0; \ 549da14cebeSEric Cheng if ((mac_srs)->srs_type & SRST_BW_CONTROL) \ 550da14cebeSEric Cheng bw_ctl = B_TRUE; \ 551da14cebeSEric Cheng tmp = tail = (head); \ 552da14cebeSEric Cheng if ((head)->b_next == NULL) { \ 553da14cebeSEric Cheng cnt = 1; \ 554da14cebeSEric Cheng if (bw_ctl) \ 555da14cebeSEric Cheng sz += msgdsize(head); \ 556da14cebeSEric Cheng } else { \ 557da14cebeSEric Cheng while (tmp != NULL) { \ 558da14cebeSEric Cheng tail = tmp; \ 559da14cebeSEric Cheng cnt++; \ 560da14cebeSEric Cheng if (bw_ctl) \ 561da14cebeSEric Cheng sz += msgdsize(tmp); \ 562da14cebeSEric Cheng tmp = tmp->b_next; \ 563da14cebeSEric Cheng } \ 564da14cebeSEric Cheng } \ 565da14cebeSEric Cheng } 566da14cebeSEric Cheng 567da14cebeSEric Cheng /* 568da14cebeSEric Cheng * Decrement the cumulative packet count in SRS and its 569da14cebeSEric Cheng * soft rings. If the srs_poll_pkt_cnt goes below lowat, then check 570da14cebeSEric Cheng * if if the interface was left in a polling mode and no one 571da14cebeSEric Cheng * is really processing the queue (to get the interface out 572da14cebeSEric Cheng * of poll mode). If no one is processing the queue, then 573da14cebeSEric Cheng * acquire the PROC and signal the poll thread to check the 574da14cebeSEric Cheng * interface for packets and get the interface back to interrupt 575da14cebeSEric Cheng * mode if nothing is found. 576da14cebeSEric Cheng */ 577da14cebeSEric Cheng #define MAC_UPDATE_SRS_COUNT_LOCKED(mac_srs, cnt) { \ 578da14cebeSEric Cheng mac_srs_rx_t *srs_rx = &(mac_srs)->srs_rx; \ 579da14cebeSEric Cheng ASSERT(MUTEX_HELD(&(mac_srs)->srs_lock)); \ 580da14cebeSEric Cheng \ 581da14cebeSEric Cheng srs_rx->sr_poll_pkt_cnt -= cnt; \ 582da14cebeSEric Cheng if ((srs_rx->sr_poll_pkt_cnt <= srs_rx->sr_poll_thres) && \ 583da14cebeSEric Cheng (((mac_srs)->srs_state & \ 584da14cebeSEric Cheng (SRS_POLLING|SRS_PROC|SRS_GET_PKTS)) == SRS_POLLING)) \ 585da14cebeSEric Cheng { \ 586da14cebeSEric Cheng (mac_srs)->srs_state |= (SRS_PROC|SRS_GET_PKTS); \ 587da14cebeSEric Cheng cv_signal(&(mac_srs)->srs_cv); \ 588da14cebeSEric Cheng srs_rx->sr_below_hiwat++; \ 589da14cebeSEric Cheng } \ 590da14cebeSEric Cheng } 591da14cebeSEric Cheng 592da14cebeSEric Cheng /* 593da14cebeSEric Cheng * The following two macros are used to update the inbound packet and byte. 594da14cebeSEric Cheng * count. The packet and byte count reflect the packets and bytes that are 595da14cebeSEric Cheng * taken out of the SRS's queue, i.e. indicating they are being delivered. 596da14cebeSEric Cheng * The srs_count and srs_size are updated in different locations as the 597da14cebeSEric Cheng * srs_size is also used to take into account any bandwidth limits. The 598da14cebeSEric Cheng * srs_size is updated only when a soft ring, if any, sends a packet up, 599da14cebeSEric Cheng * as opposed to updating it when the SRS sends a packet to the SR, i.e. 600da14cebeSEric Cheng * the srs_size reflects the packets in the SRS and SRs. These 601da14cebeSEric Cheng * macros decrement the srs_size and srs_count and also increment the 602da14cebeSEric Cheng * ipackets and ibytes stats resp. 603da14cebeSEric Cheng * 604da14cebeSEric Cheng * xxx-venu These are done under srs_lock, for now we still update 605da14cebeSEric Cheng * mci_stat_ibytes/mci_stat_ipackets atomically, need to check if 606da14cebeSEric Cheng * just updating them would be accurate enough. 607da14cebeSEric Cheng * 608da14cebeSEric Cheng * If we are updating these for a sub-flow SRS, then we need to also 609da14cebeSEric Cheng * updated it's MAC client bandwidth info, if the MAC client is also 610da14cebeSEric Cheng * bandwidth regulated. 611da14cebeSEric Cheng */ 612da14cebeSEric Cheng #define MAC_UPDATE_SRS_SIZE_LOCKED(srs, sz) { \ 613da14cebeSEric Cheng if ((srs)->srs_type & SRST_BW_CONTROL) { \ 614da14cebeSEric Cheng mutex_enter(&(srs)->srs_bw->mac_bw_lock); \ 615da14cebeSEric Cheng (srs)->srs_bw->mac_bw_sz -= (sz); \ 616da14cebeSEric Cheng (srs)->srs_bw->mac_bw_used += (sz); \ 617da14cebeSEric Cheng mutex_exit(&(srs)->srs_bw->mac_bw_lock); \ 618da14cebeSEric Cheng } \ 619da14cebeSEric Cheng } 620da14cebeSEric Cheng 621da14cebeSEric Cheng #define MAC_TX_UPDATE_BW_INFO(srs, sz) { \ 622da14cebeSEric Cheng (srs)->srs_bw->mac_bw_sz -= (sz); \ 623da14cebeSEric Cheng (srs)->srs_bw->mac_bw_used += (sz); \ 624da14cebeSEric Cheng } 625da14cebeSEric Cheng 6260dc2366fSVenugopal Iyer #define MAC_TX_SOFT_RINGS(mac_srs) ((mac_srs)->srs_tx_ring_count >= 1) 627da14cebeSEric Cheng 628da14cebeSEric Cheng /* Soft ring flags for teardown */ 629da14cebeSEric Cheng #define SRS_POLL_THR_OWNER (SRS_PROC | SRS_POLLING | SRS_GET_PKTS) 630da14cebeSEric Cheng #define SRS_PAUSE (SRS_CONDEMNED | SRS_QUIESCE) 631da14cebeSEric Cheng #define S_RING_PAUSE (S_RING_CONDEMNED | S_RING_QUIESCE) 632da14cebeSEric Cheng 633da14cebeSEric Cheng /* Soft rings */ 634da14cebeSEric Cheng extern void mac_soft_ring_init(void); 635da14cebeSEric Cheng extern void mac_soft_ring_finish(void); 636da14cebeSEric Cheng extern void mac_fanout_setup(mac_client_impl_t *, flow_entry_t *, 6370dc2366fSVenugopal Iyer mac_resource_props_t *, mac_direct_rx_t, void *, mac_resource_handle_t, 6380dc2366fSVenugopal Iyer cpupart_t *); 639da14cebeSEric Cheng 640da14cebeSEric Cheng extern void mac_soft_ring_worker_wakeup(mac_soft_ring_t *); 641da14cebeSEric Cheng extern void mac_soft_ring_blank(void *, time_t, uint_t, int); 642da14cebeSEric Cheng extern mblk_t *mac_soft_ring_poll(mac_soft_ring_t *, int); 643da14cebeSEric Cheng extern void mac_soft_ring_destroy(mac_soft_ring_t *); 644da14cebeSEric Cheng extern void mac_soft_ring_dls_bypass(void *, mac_direct_rx_t, void *); 645da14cebeSEric Cheng 646da14cebeSEric Cheng /* Rx SRS */ 647da14cebeSEric Cheng extern mac_soft_ring_set_t *mac_srs_create(struct mac_client_impl_s *, 648da14cebeSEric Cheng flow_entry_t *, uint32_t, mac_direct_rx_t, void *, mac_resource_handle_t, 649da14cebeSEric Cheng mac_ring_t *); 650da14cebeSEric Cheng extern void mac_srs_free(mac_soft_ring_set_t *); 651da14cebeSEric Cheng extern void mac_srs_signal(mac_soft_ring_set_t *, uint_t); 652da14cebeSEric Cheng extern cpu_t *mac_srs_bind(mac_soft_ring_set_t *, processorid_t); 6530dc2366fSVenugopal Iyer extern void mac_rx_srs_retarget_intr(mac_soft_ring_set_t *, processorid_t); 6540dc2366fSVenugopal Iyer extern void mac_tx_srs_retarget_intr(mac_soft_ring_set_t *); 655da14cebeSEric Cheng 656da14cebeSEric Cheng extern void mac_srs_quiesce_initiate(mac_soft_ring_set_t *); 657da14cebeSEric Cheng extern void mac_srs_client_poll_enable(struct mac_client_impl_s *, 658da14cebeSEric Cheng mac_soft_ring_set_t *); 659da14cebeSEric Cheng extern void mac_srs_client_poll_disable(struct mac_client_impl_s *, 660da14cebeSEric Cheng mac_soft_ring_set_t *); 661da14cebeSEric Cheng extern void mac_srs_client_poll_quiesce(struct mac_client_impl_s *, 662da14cebeSEric Cheng mac_soft_ring_set_t *); 663da14cebeSEric Cheng extern void mac_srs_client_poll_restart(struct mac_client_impl_s *, 664da14cebeSEric Cheng mac_soft_ring_set_t *); 665da14cebeSEric Cheng extern void mac_rx_srs_quiesce(mac_soft_ring_set_t *, uint_t); 666da14cebeSEric Cheng extern void mac_rx_srs_restart(mac_soft_ring_set_t *); 667da14cebeSEric Cheng extern void mac_rx_srs_subflow_process(void *, mac_resource_handle_t, mblk_t *, 668da14cebeSEric Cheng boolean_t); 669da14cebeSEric Cheng extern void mac_tx_srs_quiesce(mac_soft_ring_set_t *, uint_t); 670da14cebeSEric Cheng 671da14cebeSEric Cheng /* Tx SRS, Tx softring */ 672da14cebeSEric Cheng extern void mac_tx_srs_wakeup(mac_soft_ring_set_t *, mac_ring_handle_t); 6730dc2366fSVenugopal Iyer extern void mac_tx_srs_setup(struct mac_client_impl_s *, flow_entry_t *); 674da14cebeSEric Cheng extern mac_tx_func_t mac_tx_get_func(uint32_t); 675da14cebeSEric Cheng extern mblk_t *mac_tx_send(mac_client_handle_t, mac_ring_handle_t, mblk_t *, 676da14cebeSEric Cheng mac_tx_stats_t *); 677da14cebeSEric Cheng extern boolean_t mac_tx_srs_ring_present(mac_soft_ring_set_t *, mac_ring_t *); 6780dc2366fSVenugopal Iyer extern mac_soft_ring_t *mac_tx_srs_get_soft_ring(mac_soft_ring_set_t *, 6790dc2366fSVenugopal Iyer mac_ring_t *); 680da14cebeSEric Cheng extern void mac_tx_srs_add_ring(mac_soft_ring_set_t *, mac_ring_t *); 681da14cebeSEric Cheng extern void mac_tx_srs_del_ring(mac_soft_ring_set_t *, mac_ring_t *); 682da14cebeSEric Cheng extern mac_tx_cookie_t mac_tx_srs_no_desc(mac_soft_ring_set_t *, mblk_t *, 683da14cebeSEric Cheng uint16_t, mblk_t **); 684da14cebeSEric Cheng 685da14cebeSEric Cheng /* Subflow specific stuff */ 686da14cebeSEric Cheng extern int mac_srs_flow_create(struct mac_client_impl_s *, flow_entry_t *, 687da14cebeSEric Cheng mac_resource_props_t *, int, int, mac_direct_rx_t); 688da14cebeSEric Cheng extern void mac_srs_update_bwlimit(flow_entry_t *, mac_resource_props_t *); 689da14cebeSEric Cheng extern void mac_srs_adjust_subflow_bwlimit(struct mac_client_impl_s *); 690da14cebeSEric Cheng extern void mac_srs_update_drv(struct mac_client_impl_s *); 691da14cebeSEric Cheng extern void mac_update_srs_priority(mac_soft_ring_set_t *, pri_t); 692da14cebeSEric Cheng extern void mac_client_update_classifier(mac_client_impl_t *, boolean_t); 693da14cebeSEric Cheng 694da14cebeSEric Cheng extern void mac_soft_ring_intr_enable(void *); 695efe28d82SRajagopal Kunhappan extern boolean_t mac_soft_ring_intr_disable(void *); 6960dc2366fSVenugopal Iyer extern mac_soft_ring_t *mac_soft_ring_create(int, clock_t, uint16_t, 697da14cebeSEric Cheng pri_t, mac_client_impl_t *, mac_soft_ring_set_t *, 698da14cebeSEric Cheng processorid_t, mac_direct_rx_t, void *, mac_resource_handle_t); 699da14cebeSEric Cheng extern cpu_t *mac_soft_ring_bind(mac_soft_ring_t *, processorid_t); 700da14cebeSEric Cheng extern void mac_soft_ring_unbind(mac_soft_ring_t *); 7010dc2366fSVenugopal Iyer extern void mac_soft_ring_free(mac_soft_ring_t *); 702da14cebeSEric Cheng extern void mac_soft_ring_signal(mac_soft_ring_t *, uint_t); 703da14cebeSEric Cheng extern void mac_rx_soft_ring_process(mac_client_impl_t *, mac_soft_ring_t *, 704da14cebeSEric Cheng mblk_t *, mblk_t *, int, size_t); 705da14cebeSEric Cheng extern mac_tx_cookie_t mac_tx_soft_ring_process(mac_soft_ring_t *, 706da14cebeSEric Cheng mblk_t *, uint16_t, mblk_t **); 707da14cebeSEric Cheng extern void mac_srs_worker_quiesce(mac_soft_ring_set_t *); 708da14cebeSEric Cheng extern void mac_srs_worker_restart(mac_soft_ring_set_t *); 709da14cebeSEric Cheng extern void mac_rx_attach_flow_srs(mac_impl_t *, flow_entry_t *, 710da14cebeSEric Cheng mac_soft_ring_set_t *, mac_ring_t *, mac_classify_type_t); 711da14cebeSEric Cheng 712da14cebeSEric Cheng extern void mac_rx_srs_drain_bw(mac_soft_ring_set_t *, uint_t); 713da14cebeSEric Cheng extern void mac_rx_srs_drain(mac_soft_ring_set_t *, uint_t); 714da14cebeSEric Cheng extern void mac_rx_srs_process(void *, mac_resource_handle_t, mblk_t *, 715da14cebeSEric Cheng boolean_t); 716da14cebeSEric Cheng extern void mac_srs_worker(mac_soft_ring_set_t *); 717da14cebeSEric Cheng extern void mac_rx_srs_poll_ring(mac_soft_ring_set_t *); 718da14cebeSEric Cheng extern void mac_tx_srs_drain(mac_soft_ring_set_t *, uint_t); 719da14cebeSEric Cheng 720da14cebeSEric Cheng extern void mac_tx_srs_restart(mac_soft_ring_set_t *); 721da14cebeSEric Cheng extern void mac_rx_srs_remove(mac_soft_ring_set_t *); 722da14cebeSEric Cheng 723da14cebeSEric Cheng #ifdef __cplusplus 724da14cebeSEric Cheng } 725da14cebeSEric Cheng #endif 726da14cebeSEric Cheng 727da14cebeSEric Cheng #endif /* _SYS_MAC_SOFT_RING_H */ 728