1# 2# Copyright (c) 2014-2018, Matthew Macy (mmacy@mattmacy.io) 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are met: 7# 8# 1. Redistributions of source code must retain the above copyright notice, 9# this list of conditions and the following disclaimer. 10# 11# 2. Neither the name of Matthew Macy nor the names of its 12# contributors may be used to endorse or promote products derived from 13# this software without specific prior written permission. 14# 15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27# $FreeBSD$ 28# 29 30#include <sys/types.h> 31#include <sys/systm.h> 32#include <sys/socket.h> 33 34#include <machine/bus.h> 35#include <sys/bus.h> 36 37#include <net/ethernet.h> 38#include <net/if.h> 39#include <net/if_var.h> 40#include <net/if_media.h> 41#include <net/iflib.h> 42#include <net/if_clone.h> 43#include <net/if_dl.h> 44#include <net/if_types.h> 45 46INTERFACE ifdi; 47 48CODE { 49 50 static void 51 null_void_op(if_ctx_t _ctx __unused) 52 { 53 } 54 55 static int 56 null_knlist_add(if_ctx_t _ctx __unused, struct knote *_kn) 57 { 58 return (0); 59 } 60 61 static int 62 null_knote_event(if_ctx_t _ctx __unused, struct knote *_kn, int _hint) 63 { 64 return (0); 65 } 66 67 static void 68 null_timer_op(if_ctx_t _ctx __unused, uint16_t _qsidx __unused) 69 { 70 } 71 72 static int 73 null_int_op(if_ctx_t _ctx __unused) 74 { 75 return (0); 76 } 77 78 static int 79 null_int_int_op(if_ctx_t _ctx __unused, int arg0 __unused) 80 { 81 return (ENOTSUP); 82 } 83 84 static int 85 null_queue_intr_enable(if_ctx_t _ctx __unused, uint16_t _qid __unused) 86 { 87 return (ENOTSUP); 88 } 89 90 static void 91 null_led_func(if_ctx_t _ctx __unused, int _onoff __unused) 92 { 93 } 94 95 static void 96 null_vlan_register_op(if_ctx_t _ctx __unused, uint16_t vtag __unused) 97 { 98 } 99 100 static int 101 null_q_setup(if_ctx_t _ctx __unused, uint32_t _qid __unused) 102 { 103 return (0); 104 } 105 106 static int 107 null_i2c_req(if_ctx_t _sctx __unused, struct ifi2creq *_i2c __unused) 108 { 109 return (ENOTSUP); 110 } 111 112 static int 113 null_sysctl_int_delay(if_ctx_t _sctx __unused, if_int_delay_info_t _iidi __unused) 114 { 115 return (0); 116 } 117 118 static int 119 null_iov_init(if_ctx_t _ctx __unused, uint16_t num_vfs __unused, const nvlist_t *params __unused) 120 { 121 return (ENOTSUP); 122 } 123 124 static int 125 null_vf_add(if_ctx_t _ctx __unused, uint16_t num_vfs __unused, const nvlist_t *params __unused) 126 { 127 return (ENOTSUP); 128 } 129 130 static int 131 null_priv_ioctl(if_ctx_t _ctx __unused, u_long command, caddr_t *data __unused) 132 { 133 return (ENOTSUP); 134 } 135 136 static void 137 null_media_status(if_ctx_t ctx __unused, struct ifmediareq *ifmr) 138 { 139 ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; 140 ifmr->ifm_active = IFM_ETHER | IFM_25G_ACC | IFM_FDX; 141 } 142 143 static int 144 null_cloneattach(if_ctx_t ctx __unused, struct if_clone *ifc __unused, 145 const char *name __unused, caddr_t params __unused) 146 { 147 return (0); 148 } 149 150 static void 151 null_rx_clset(if_ctx_t _ctx __unused, uint16_t _flid __unused, 152 uint16_t _qid __unused, caddr_t *_sdcl __unused) 153 { 154 } 155 static void 156 null_object_info_get(if_ctx_t ctx __unused, void *data __unused, int size __unused) 157 { 158 } 159 static int 160 default_mac_set(if_ctx_t ctx, const uint8_t *mac) 161 { 162 struct ifnet *ifp = iflib_get_ifp(ctx); 163 struct sockaddr_dl *sdl; 164 165 if (ifp && ifp->if_addr) { 166 sdl = (struct sockaddr_dl *)ifp->if_addr->ifa_addr; 167 MPASS(sdl->sdl_type == IFT_ETHER); 168 memcpy(LLADDR(sdl), mac, ETHER_ADDR_LEN); 169 } 170 return (0); 171 } 172}; 173 174# 175# kevent interfaces 176# 177 178METHOD int knlist_add { 179 if_ctx_t _ctx; 180 struct knote *_kn; 181} DEFAULT null_knlist_add; 182 183METHOD int knote_event { 184 if_ctx_t _ctx; 185 struct knote *_kn; 186 int hint; 187} DEFAULT null_knote_event; 188 189 190# 191# query 192# 193 194METHOD int object_info_get { 195 if_ctx_t _ctx; 196 void *data; 197 int size; 198} DEFAULT null_object_info_get; 199 200# 201# bus interfaces 202# 203 204METHOD int attach_pre { 205 if_ctx_t _ctx; 206} DEFAULT null_int_op; 207 208METHOD int attach_post { 209 if_ctx_t _ctx; 210} DEFAULT null_int_op; 211 212METHOD int reinit_pre { 213 if_ctx_t _ctx; 214} DEFAULT null_int_op; 215 216METHOD int reinit_post { 217 if_ctx_t _ctx; 218} DEFAULT null_int_op; 219 220METHOD int cloneattach { 221 if_ctx_t _ctx; 222 struct if_clone *_ifc; 223 const char *_name; 224 caddr_t params; 225} DEFAULT null_cloneattach; 226 227METHOD int detach { 228 if_ctx_t _ctx; 229}; 230 231METHOD int suspend { 232 if_ctx_t _ctx; 233} DEFAULT null_int_op; 234 235METHOD int shutdown { 236 if_ctx_t _ctx; 237} DEFAULT null_int_op; 238 239METHOD int resume { 240 if_ctx_t _ctx; 241} DEFAULT null_int_op; 242 243# 244# downcall to driver to allocate its 245# own queue state and tie it to the parent 246# 247 248METHOD int tx_queues_alloc { 249 if_ctx_t _ctx; 250 caddr_t *_vaddrs; 251 uint64_t *_paddrs; 252 int ntxqs; 253 int ntxqsets; 254}; 255 256METHOD int rx_queues_alloc { 257 if_ctx_t _ctx; 258 caddr_t *_vaddrs; 259 uint64_t *_paddrs; 260 int nrxqs; 261 int nrxqsets; 262}; 263 264METHOD void queues_free { 265 if_ctx_t _ctx; 266} DEFAULT null_void_op; 267 268METHOD void rx_clset { 269 if_ctx_t _ctx; 270 uint16_t _fl; 271 uint16_t _qsetid; 272 caddr_t *_sdcl; 273} DEFAULT null_rx_clset; 274 275# 276# interface reset / stop 277# 278 279METHOD void init { 280 if_ctx_t _ctx; 281}; 282 283METHOD void stop { 284 if_ctx_t _ctx; 285}; 286 287# 288# interrupt setup and manipulation 289# 290 291METHOD int msix_intr_assign { 292 if_ctx_t _sctx; 293 int msix; 294} DEFAULT null_int_int_op; 295 296METHOD void intr_enable { 297 if_ctx_t _ctx; 298}; 299 300METHOD void intr_disable { 301 if_ctx_t _ctx; 302}; 303 304METHOD int rx_queue_intr_enable { 305 if_ctx_t _ctx; 306 uint16_t _qid; 307} DEFAULT null_queue_intr_enable; 308 309METHOD int tx_queue_intr_enable { 310 if_ctx_t _ctx; 311 uint16_t _qid; 312} DEFAULT null_queue_intr_enable; 313 314METHOD void link_intr_enable { 315 if_ctx_t _ctx; 316} DEFAULT null_void_op; 317 318# 319# interface configuration 320# 321 322METHOD void multi_set { 323 if_ctx_t _ctx; 324}; 325 326METHOD int mtu_set { 327 if_ctx_t _ctx; 328 uint32_t _mtu; 329}; 330METHOD int mac_set { 331 if_ctx_t _ctx; 332 const uint8_t *_mac; 333} DEFAULT default_mac_set; 334 335METHOD void media_set{ 336 if_ctx_t _ctx; 337} DEFAULT null_void_op; 338 339METHOD int promisc_set { 340 if_ctx_t _ctx; 341 int _flags; 342}; 343 344METHOD void crcstrip_set { 345 if_ctx_t _ctx; 346 int _onoff; 347 int _strip; 348}; 349 350# 351# IOV handling 352# 353 354METHOD void vflr_handle { 355 if_ctx_t _ctx; 356} DEFAULT null_void_op; 357 358METHOD int iov_init { 359 if_ctx_t _ctx; 360 uint16_t num_vfs; 361 const nvlist_t * params; 362} DEFAULT null_iov_init; 363 364METHOD void iov_uninit { 365 if_ctx_t _ctx; 366} DEFAULT null_void_op; 367 368METHOD int iov_vf_add { 369 if_ctx_t _ctx; 370 uint16_t num_vfs; 371 const nvlist_t * params; 372} DEFAULT null_vf_add; 373 374 375# 376# Device status 377# 378 379METHOD void update_admin_status { 380 if_ctx_t _ctx; 381}; 382 383METHOD void media_status { 384 if_ctx_t _ctx; 385 struct ifmediareq *_ifm; 386} DEFAULT null_media_status; 387 388METHOD int media_change { 389 if_ctx_t _ctx; 390} DEFAULT null_int_op; 391 392METHOD uint64_t get_counter { 393 if_ctx_t _ctx; 394 ift_counter cnt; 395}; 396 397METHOD int priv_ioctl { 398 if_ctx_t _ctx; 399 u_long _cmd; 400 caddr_t _data; 401} DEFAULT null_priv_ioctl; 402 403# 404# optional methods 405# 406 407METHOD int i2c_req { 408 if_ctx_t _ctx; 409 struct ifi2creq *_req; 410} DEFAULT null_i2c_req; 411 412METHOD int txq_setup { 413 if_ctx_t _ctx; 414 uint32_t _txqid; 415} DEFAULT null_q_setup; 416 417METHOD int rxq_setup { 418 if_ctx_t _ctx; 419 uint32_t _txqid; 420} DEFAULT null_q_setup; 421 422METHOD void timer { 423 if_ctx_t _ctx; 424 uint16_t _txqid; 425} DEFAULT null_timer_op; 426 427METHOD void watchdog_reset { 428 if_ctx_t _ctx; 429} DEFAULT null_void_op; 430 431METHOD void watchdog_reset_queue { 432 if_ctx_t _ctx; 433 uint16_t _q; 434} DEFAULT null_timer_op; 435 436METHOD void led_func { 437 if_ctx_t _ctx; 438 int _onoff; 439} DEFAULT null_led_func; 440 441METHOD void vlan_register { 442 if_ctx_t _ctx; 443 uint16_t _vtag; 444} DEFAULT null_vlan_register_op; 445 446METHOD void vlan_unregister { 447 if_ctx_t _ctx; 448 uint16_t _vtag; 449} DEFAULT null_vlan_register_op; 450 451METHOD int sysctl_int_delay { 452 if_ctx_t _sctx; 453 if_int_delay_info_t _iidi; 454} DEFAULT null_sysctl_int_delay; 455 456METHOD void debug { 457 if_ctx_t _ctx; 458} DEFAULT null_void_op; 459