1 1.30 joe /* $NetBSD: if_hvn.c,v 1.30 2025/02/17 23:28:48 joe Exp $ */ 2 1.1 nonaka /* $OpenBSD: if_hvn.c,v 1.39 2018/03/11 14:31:34 mikeb Exp $ */ 3 1.1 nonaka 4 1.1 nonaka /*- 5 1.1 nonaka * Copyright (c) 2009-2012,2016 Microsoft Corp. 6 1.1 nonaka * Copyright (c) 2010-2012 Citrix Inc. 7 1.1 nonaka * Copyright (c) 2012 NetApp Inc. 8 1.1 nonaka * Copyright (c) 2016 Mike Belopuhov <mike (at) esdenera.com> 9 1.1 nonaka * All rights reserved. 10 1.1 nonaka * 11 1.1 nonaka * Redistribution and use in source and binary forms, with or without 12 1.1 nonaka * modification, are permitted provided that the following conditions 13 1.1 nonaka * are met: 14 1.1 nonaka * 1. Redistributions of source code must retain the above copyright 15 1.1 nonaka * notice unmodified, this list of conditions, and the following 16 1.1 nonaka * disclaimer. 17 1.1 nonaka * 2. Redistributions in binary form must reproduce the above copyright 18 1.1 nonaka * notice, this list of conditions and the following disclaimer in the 19 1.1 nonaka * documentation and/or other materials provided with the distribution. 20 1.1 nonaka * 21 1.1 nonaka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 1.1 nonaka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 1.1 nonaka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 1.1 nonaka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 1.1 nonaka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 1.1 nonaka * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 1.1 nonaka * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.1 nonaka * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 1.1 nonaka * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 1.1 nonaka * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 1.1 nonaka */ 32 1.1 nonaka 33 1.1 nonaka /* 34 1.1 nonaka * The OpenBSD port was done under funding by Esdenera Networks GmbH. 35 1.1 nonaka */ 36 1.1 nonaka 37 1.1 nonaka #include <sys/cdefs.h> 38 1.30 joe __KERNEL_RCSID(0, "$NetBSD: if_hvn.c,v 1.30 2025/02/17 23:28:48 joe Exp $"); 39 1.1 nonaka 40 1.1 nonaka #ifdef _KERNEL_OPT 41 1.22 nonaka #include "opt_if_hvn.h" 42 1.1 nonaka #include "opt_inet.h" 43 1.1 nonaka #include "opt_inet6.h" 44 1.1 nonaka #endif 45 1.1 nonaka 46 1.1 nonaka #include <sys/param.h> 47 1.1 nonaka #include <sys/systm.h> 48 1.1 nonaka #include <sys/kernel.h> 49 1.1 nonaka #include <sys/device.h> 50 1.22 nonaka #include <sys/bitops.h> 51 1.1 nonaka #include <sys/bus.h> 52 1.22 nonaka #include <sys/condvar.h> 53 1.22 nonaka #include <sys/cpu.h> 54 1.22 nonaka #include <sys/evcnt.h> 55 1.1 nonaka #include <sys/intr.h> 56 1.1 nonaka #include <sys/kmem.h> 57 1.22 nonaka #include <sys/kthread.h> 58 1.22 nonaka #include <sys/mutex.h> 59 1.22 nonaka #include <sys/pcq.h> 60 1.22 nonaka #include <sys/sysctl.h> 61 1.22 nonaka #include <sys/workqueue.h> 62 1.1 nonaka 63 1.1 nonaka #include <net/if.h> 64 1.1 nonaka #include <net/if_ether.h> 65 1.1 nonaka #include <net/if_media.h> 66 1.22 nonaka #include <net/if_vlanvar.h> 67 1.22 nonaka #include <net/rss_config.h> 68 1.22 nonaka #include <netinet/in.h> 69 1.22 nonaka #include <netinet/ip.h> 70 1.22 nonaka #include <netinet/ip6.h> 71 1.22 nonaka #include <netinet/udp.h> 72 1.1 nonaka 73 1.1 nonaka #include <net/bpf.h> 74 1.1 nonaka 75 1.1 nonaka #include <dev/ic/ndisreg.h> 76 1.1 nonaka #include <dev/ic/rndisreg.h> 77 1.1 nonaka 78 1.1 nonaka #include <dev/hyperv/vmbusvar.h> 79 1.1 nonaka #include <dev/hyperv/if_hvnreg.h> 80 1.1 nonaka 81 1.1 nonaka #ifndef EVL_PRIO_BITS 82 1.1 nonaka #define EVL_PRIO_BITS 13 83 1.1 nonaka #endif 84 1.15 nonaka #ifndef EVL_CFI_BITS 85 1.15 nonaka #define EVL_CFI_BITS 12 86 1.15 nonaka #endif 87 1.1 nonaka 88 1.22 nonaka #define HVN_CHIM_SIZE (15 * 1024 * 1024) 89 1.22 nonaka 90 1.1 nonaka #define HVN_NVS_MSGSIZE 32 91 1.1 nonaka #define HVN_NVS_BUFSIZE PAGE_SIZE 92 1.1 nonaka 93 1.22 nonaka #define HVN_RING_BUFSIZE (128 * PAGE_SIZE) 94 1.22 nonaka #define HVN_RING_IDX2CPU(sc, idx) ((idx) % ncpu) 95 1.22 nonaka 96 1.22 nonaka #ifndef HVN_CHANNEL_MAX_COUNT_DEFAULT 97 1.22 nonaka #define HVN_CHANNEL_MAX_COUNT_DEFAULT 8 98 1.22 nonaka #endif 99 1.22 nonaka 100 1.22 nonaka #ifndef HVN_LINK_STATE_CHANGE_DELAY 101 1.22 nonaka #define HVN_LINK_STATE_CHANGE_DELAY 5000 102 1.22 nonaka #endif 103 1.22 nonaka 104 1.22 nonaka #define HVN_WORKQUEUE_PRI PRI_SOFTNET 105 1.22 nonaka 106 1.1 nonaka /* 107 1.1 nonaka * RNDIS control interface 108 1.1 nonaka */ 109 1.1 nonaka #define HVN_RNDIS_CTLREQS 4 110 1.1 nonaka #define HVN_RNDIS_BUFSIZE 512 111 1.1 nonaka 112 1.1 nonaka struct rndis_cmd { 113 1.1 nonaka uint32_t rc_id; 114 1.1 nonaka struct hvn_nvs_rndis rc_msg; 115 1.1 nonaka void *rc_req; 116 1.1 nonaka bus_dmamap_t rc_dmap; 117 1.1 nonaka bus_dma_segment_t rc_segs; 118 1.1 nonaka int rc_nsegs; 119 1.1 nonaka uint64_t rc_gpa; 120 1.1 nonaka struct rndis_packet_msg rc_cmp; 121 1.1 nonaka uint32_t rc_cmplen; 122 1.1 nonaka uint8_t rc_cmpbuf[HVN_RNDIS_BUFSIZE]; 123 1.1 nonaka int rc_done; 124 1.1 nonaka TAILQ_ENTRY(rndis_cmd) rc_entry; 125 1.22 nonaka kmutex_t rc_lock; 126 1.22 nonaka kcondvar_t rc_cv; 127 1.1 nonaka }; 128 1.1 nonaka TAILQ_HEAD(rndis_queue, rndis_cmd); 129 1.1 nonaka 130 1.22 nonaka #define HVN_MTU_MIN 68 131 1.22 nonaka #define HVN_MTU_MAX (65535 - ETHER_ADDR_LEN) 132 1.1 nonaka 133 1.1 nonaka #define HVN_RNDIS_XFER_SIZE 2048 134 1.1 nonaka 135 1.22 nonaka #define HVN_NDIS_TXCSUM_CAP_IP4 \ 136 1.22 nonaka (NDIS_TXCSUM_CAP_IP4 | NDIS_TXCSUM_CAP_IP4OPT) 137 1.22 nonaka #define HVN_NDIS_TXCSUM_CAP_TCP4 \ 138 1.22 nonaka (NDIS_TXCSUM_CAP_TCP4 | NDIS_TXCSUM_CAP_TCP4OPT) 139 1.22 nonaka #define HVN_NDIS_TXCSUM_CAP_TCP6 \ 140 1.22 nonaka (NDIS_TXCSUM_CAP_TCP6 | NDIS_TXCSUM_CAP_TCP6OPT | \ 141 1.22 nonaka NDIS_TXCSUM_CAP_IP6EXT) 142 1.22 nonaka #define HVN_NDIS_TXCSUM_CAP_UDP6 \ 143 1.22 nonaka (NDIS_TXCSUM_CAP_UDP6 | NDIS_TXCSUM_CAP_IP6EXT) 144 1.22 nonaka #define HVN_NDIS_LSOV2_CAP_IP6 \ 145 1.22 nonaka (NDIS_LSOV2_CAP_IP6EXT | NDIS_LSOV2_CAP_TCP6OPT) 146 1.22 nonaka 147 1.22 nonaka #define HVN_RNDIS_CMD_NORESP __BIT(0) 148 1.22 nonaka 149 1.22 nonaka #define HVN_NVS_CMD_NORESP __BIT(0) 150 1.22 nonaka 151 1.1 nonaka /* 152 1.1 nonaka * Tx ring 153 1.1 nonaka */ 154 1.22 nonaka #define HVN_TX_DESC 512 155 1.1 nonaka #define HVN_TX_FRAGS 15 /* 31 is the max */ 156 1.1 nonaka #define HVN_TX_FRAG_SIZE PAGE_SIZE 157 1.1 nonaka #define HVN_TX_PKT_SIZE 16384 158 1.1 nonaka 159 1.1 nonaka #define HVN_RNDIS_PKT_LEN \ 160 1.1 nonaka (sizeof(struct rndis_packet_msg) + \ 161 1.1 nonaka sizeof(struct rndis_pktinfo) + NDIS_VLAN_INFO_SIZE + \ 162 1.1 nonaka sizeof(struct rndis_pktinfo) + NDIS_TXCSUM_INFO_SIZE) 163 1.1 nonaka 164 1.22 nonaka #define HVN_PKTSIZE_MIN(align) \ 165 1.22 nonaka roundup2(ETHER_MIN_LEN + ETHER_VLAN_ENCAP_LEN - ETHER_CRC_LEN + \ 166 1.22 nonaka HVN_RNDIS_PKT_LEN, (align)) 167 1.22 nonaka #define HVN_PKTSIZE(m, align) \ 168 1.22 nonaka roundup2((m)->m_pkthdr.len + HVN_RNDIS_PKT_LEN, (align)) 169 1.22 nonaka 170 1.1 nonaka struct hvn_tx_desc { 171 1.1 nonaka uint32_t txd_id; 172 1.1 nonaka struct vmbus_gpa txd_sgl[HVN_TX_FRAGS + 1]; 173 1.1 nonaka int txd_nsge; 174 1.1 nonaka struct mbuf *txd_buf; 175 1.1 nonaka bus_dmamap_t txd_dmap; 176 1.1 nonaka struct vmbus_gpa txd_gpa; 177 1.1 nonaka struct rndis_packet_msg *txd_req; 178 1.22 nonaka TAILQ_ENTRY(hvn_tx_desc) txd_entry; 179 1.22 nonaka u_int txd_refs; 180 1.22 nonaka uint32_t txd_flags; 181 1.22 nonaka #define HVN_TXD_FLAG_ONAGG __BIT(0) 182 1.22 nonaka #define HVN_TXD_FLAG_DMAMAP __BIT(1) 183 1.22 nonaka uint32_t txd_chim_index; 184 1.22 nonaka int txd_chim_size; 185 1.22 nonaka STAILQ_ENTRY(hvn_tx_desc) txd_agg_entry; 186 1.22 nonaka STAILQ_HEAD(, hvn_tx_desc) txd_agg_list; 187 1.1 nonaka }; 188 1.1 nonaka 189 1.22 nonaka struct hvn_softc; 190 1.22 nonaka struct hvn_rx_ring; 191 1.22 nonaka 192 1.22 nonaka struct hvn_tx_ring { 193 1.22 nonaka struct hvn_softc *txr_softc; 194 1.22 nonaka struct vmbus_channel *txr_chan; 195 1.22 nonaka struct hvn_rx_ring *txr_rxr; 196 1.22 nonaka void *txr_si; 197 1.22 nonaka char txr_name[16]; 198 1.22 nonaka 199 1.22 nonaka int txr_id; 200 1.22 nonaka int txr_oactive; 201 1.22 nonaka int txr_suspended; 202 1.22 nonaka int txr_csum_assist; 203 1.22 nonaka uint64_t txr_caps_assist; 204 1.22 nonaka uint32_t txr_flags; 205 1.22 nonaka #define HVN_TXR_FLAG_UDP_HASH __BIT(0) 206 1.22 nonaka 207 1.22 nonaka struct evcnt txr_evpkts; 208 1.22 nonaka struct evcnt txr_evsends; 209 1.22 nonaka struct evcnt txr_evnodesc; 210 1.22 nonaka struct evcnt txr_evdmafailed; 211 1.22 nonaka struct evcnt txr_evdefrag; 212 1.22 nonaka struct evcnt txr_evpcqdrop; 213 1.22 nonaka struct evcnt txr_evtransmitdefer; 214 1.22 nonaka struct evcnt txr_evflushfailed; 215 1.22 nonaka struct evcnt txr_evchimneytried; 216 1.22 nonaka struct evcnt txr_evchimney; 217 1.22 nonaka struct evcnt txr_evvlanfixup; 218 1.22 nonaka struct evcnt txr_evvlanhwtagging; 219 1.22 nonaka struct evcnt txr_evvlantap; 220 1.22 nonaka 221 1.22 nonaka kmutex_t txr_lock; 222 1.22 nonaka pcq_t *txr_interq; 223 1.22 nonaka 224 1.22 nonaka uint32_t txr_avail; 225 1.22 nonaka TAILQ_HEAD(, hvn_tx_desc) txr_list; 226 1.22 nonaka struct hvn_tx_desc txr_desc[HVN_TX_DESC]; 227 1.22 nonaka uint8_t *txr_msgs; 228 1.22 nonaka struct hyperv_dma txr_dma; 229 1.22 nonaka 230 1.22 nonaka int txr_chim_size; 231 1.22 nonaka 232 1.22 nonaka /* Applied packet transmission aggregation limits. */ 233 1.22 nonaka int txr_agg_szmax; 234 1.22 nonaka short txr_agg_pktmax; 235 1.22 nonaka short txr_agg_align; 236 1.22 nonaka 237 1.22 nonaka /* Packet transmission aggregation states. */ 238 1.22 nonaka struct hvn_tx_desc *txr_agg_txd; 239 1.22 nonaka int txr_agg_szleft; 240 1.22 nonaka short txr_agg_pktleft; 241 1.22 nonaka struct rndis_packet_msg *txr_agg_prevpkt; 242 1.22 nonaka 243 1.22 nonaka /* Temporary stats for each sends. */ 244 1.22 nonaka int txr_stat_pkts; 245 1.22 nonaka int txr_stat_size; 246 1.22 nonaka int txr_stat_mcasts; 247 1.22 nonaka 248 1.22 nonaka int (*txr_sendpkt)(struct hvn_tx_ring *, 249 1.22 nonaka struct hvn_tx_desc *); 250 1.22 nonaka } __aligned(CACHE_LINE_SIZE); 251 1.22 nonaka 252 1.22 nonaka struct hvn_rx_ring { 253 1.22 nonaka struct hvn_softc *rxr_softc; 254 1.22 nonaka struct vmbus_channel *rxr_chan; 255 1.22 nonaka struct hvn_tx_ring *rxr_txr; 256 1.22 nonaka void *rxr_si; 257 1.22 nonaka bool rxr_workqueue; 258 1.22 nonaka char rxr_name[16]; 259 1.22 nonaka 260 1.22 nonaka struct work rxr_wk; 261 1.22 nonaka volatile bool rxr_onlist; 262 1.22 nonaka volatile bool rxr_onproc; 263 1.22 nonaka kmutex_t rxr_onwork_lock; 264 1.22 nonaka kcondvar_t rxr_onwork_cv; 265 1.22 nonaka 266 1.22 nonaka uint32_t rxr_flags; 267 1.22 nonaka #define HVN_RXR_FLAG_UDP_HASH __BIT(0) 268 1.22 nonaka 269 1.22 nonaka kmutex_t rxr_lock; 270 1.22 nonaka 271 1.22 nonaka struct evcnt rxr_evpkts; 272 1.22 nonaka struct evcnt rxr_evcsum_ip; 273 1.22 nonaka struct evcnt rxr_evcsum_tcp; 274 1.22 nonaka struct evcnt rxr_evcsum_udp; 275 1.22 nonaka struct evcnt rxr_evvlanhwtagging; 276 1.22 nonaka struct evcnt rxr_evintr; 277 1.22 nonaka struct evcnt rxr_evdefer; 278 1.22 nonaka struct evcnt rxr_evdeferreq; 279 1.22 nonaka struct evcnt rxr_evredeferreq; 280 1.22 nonaka 281 1.22 nonaka /* NVS */ 282 1.22 nonaka uint8_t *rxr_nvsbuf; 283 1.22 nonaka } __aligned(CACHE_LINE_SIZE); 284 1.22 nonaka 285 1.1 nonaka struct hvn_softc { 286 1.1 nonaka device_t sc_dev; 287 1.1 nonaka 288 1.1 nonaka struct vmbus_softc *sc_vmbus; 289 1.22 nonaka struct vmbus_channel *sc_prichan; 290 1.1 nonaka bus_dma_tag_t sc_dmat; 291 1.1 nonaka 292 1.1 nonaka struct ethercom sc_ec; 293 1.1 nonaka struct ifmedia sc_media; 294 1.1 nonaka struct if_percpuq *sc_ipq; 295 1.22 nonaka struct workqueue *sc_wq; 296 1.22 nonaka bool sc_txrx_workqueue; 297 1.22 nonaka kmutex_t sc_core_lock; 298 1.22 nonaka 299 1.22 nonaka kmutex_t sc_link_lock; 300 1.22 nonaka kcondvar_t sc_link_cv; 301 1.22 nonaka callout_t sc_link_tmout; 302 1.22 nonaka lwp_t *sc_link_lwp; 303 1.22 nonaka uint32_t sc_link_ev; 304 1.22 nonaka #define HVN_LINK_EV_STATE_CHANGE __BIT(0) 305 1.22 nonaka #define HVN_LINK_EV_NETWORK_CHANGE_TMOUT __BIT(1) 306 1.22 nonaka #define HVN_LINK_EV_NETWORK_CHANGE __BIT(2) 307 1.22 nonaka #define HVN_LINK_EV_RESUME_NETWORK __BIT(3) 308 1.22 nonaka #define HVN_LINK_EV_EXIT_THREAD __BIT(4) 309 1.1 nonaka int sc_link_state; 310 1.22 nonaka bool sc_link_onproc; 311 1.22 nonaka bool sc_link_pending; 312 1.22 nonaka bool sc_link_suspend; 313 1.22 nonaka 314 1.22 nonaka int sc_tx_process_limit; 315 1.22 nonaka int sc_rx_process_limit; 316 1.22 nonaka int sc_tx_intr_process_limit; 317 1.22 nonaka int sc_rx_intr_process_limit; 318 1.22 nonaka 319 1.22 nonaka struct sysctllog *sc_sysctllog; 320 1.22 nonaka 321 1.22 nonaka uint32_t sc_caps; 322 1.22 nonaka #define HVN_CAPS_VLAN __BIT(0) 323 1.22 nonaka #define HVN_CAPS_MTU __BIT(1) 324 1.22 nonaka #define HVN_CAPS_IPCS __BIT(2) 325 1.22 nonaka #define HVN_CAPS_TCP4CS __BIT(3) 326 1.22 nonaka #define HVN_CAPS_TCP6CS __BIT(4) 327 1.22 nonaka #define HVN_CAPS_UDP4CS __BIT(5) 328 1.22 nonaka #define HVN_CAPS_UDP6CS __BIT(6) 329 1.22 nonaka #define HVN_CAPS_TSO4 __BIT(7) 330 1.22 nonaka #define HVN_CAPS_TSO6 __BIT(8) 331 1.22 nonaka #define HVN_CAPS_HASHVAL __BIT(9) 332 1.22 nonaka #define HVN_CAPS_UDPHASH __BIT(10) 333 1.1 nonaka 334 1.1 nonaka uint32_t sc_flags; 335 1.22 nonaka #define HVN_SCF_ATTACHED __BIT(0) 336 1.22 nonaka #define HVN_SCF_RXBUF_CONNECTED __BIT(1) 337 1.22 nonaka #define HVN_SCF_CHIM_CONNECTED __BIT(2) 338 1.22 nonaka #define HVN_SCF_REVOKED __BIT(3) 339 1.22 nonaka #define HVN_SCF_HAS_RSSKEY __BIT(4) 340 1.22 nonaka #define HVN_SCF_HAS_RSSIND __BIT(5) 341 1.1 nonaka 342 1.1 nonaka /* NVS protocol */ 343 1.1 nonaka int sc_proto; 344 1.1 nonaka uint32_t sc_nvstid; 345 1.1 nonaka uint8_t sc_nvsrsp[HVN_NVS_MSGSIZE]; 346 1.1 nonaka int sc_nvsdone; 347 1.22 nonaka kmutex_t sc_nvsrsp_lock; 348 1.22 nonaka kcondvar_t sc_nvsrsp_cv; 349 1.1 nonaka 350 1.1 nonaka /* RNDIS protocol */ 351 1.1 nonaka int sc_ndisver; 352 1.1 nonaka uint32_t sc_rndisrid; 353 1.22 nonaka int sc_tso_szmax; 354 1.22 nonaka int sc_tso_sgmin; 355 1.22 nonaka uint32_t sc_rndis_agg_size; 356 1.22 nonaka uint32_t sc_rndis_agg_pkts; 357 1.22 nonaka uint32_t sc_rndis_agg_align; 358 1.1 nonaka struct rndis_queue sc_cntl_sq; /* submission queue */ 359 1.1 nonaka kmutex_t sc_cntl_sqlck; 360 1.1 nonaka struct rndis_queue sc_cntl_cq; /* completion queue */ 361 1.1 nonaka kmutex_t sc_cntl_cqlck; 362 1.1 nonaka struct rndis_queue sc_cntl_fq; /* free queue */ 363 1.1 nonaka kmutex_t sc_cntl_fqlck; 364 1.22 nonaka kcondvar_t sc_cntl_fqcv; 365 1.1 nonaka struct rndis_cmd sc_cntl_msgs[HVN_RNDIS_CTLREQS]; 366 1.1 nonaka struct hvn_nvs_rndis sc_data_msg; 367 1.1 nonaka 368 1.22 nonaka int sc_rss_ind_size; 369 1.22 nonaka uint32_t sc_rss_hash; /* setting, NDIS_HASH_ */ 370 1.22 nonaka uint32_t sc_rss_hcap; /* caps, NDIS_HASH_ */ 371 1.22 nonaka struct ndis_rssprm_toeplitz sc_rss; 372 1.22 nonaka 373 1.1 nonaka /* Rx ring */ 374 1.1 nonaka uint8_t *sc_rx_ring; 375 1.1 nonaka int sc_rx_size; 376 1.1 nonaka uint32_t sc_rx_hndl; 377 1.1 nonaka struct hyperv_dma sc_rx_dma; 378 1.22 nonaka struct hvn_rx_ring *sc_rxr; 379 1.22 nonaka int sc_nrxr; 380 1.22 nonaka int sc_nrxr_inuse; 381 1.1 nonaka 382 1.1 nonaka /* Tx ring */ 383 1.22 nonaka struct hvn_tx_ring *sc_txr; 384 1.22 nonaka int sc_ntxr; 385 1.22 nonaka int sc_ntxr_inuse; 386 1.22 nonaka 387 1.22 nonaka /* chimney sending buffers */ 388 1.22 nonaka uint8_t *sc_chim; 389 1.22 nonaka uint32_t sc_chim_hndl; 390 1.22 nonaka struct hyperv_dma sc_chim_dma; 391 1.22 nonaka kmutex_t sc_chim_bmap_lock; 392 1.22 nonaka u_long *sc_chim_bmap; 393 1.22 nonaka int sc_chim_bmap_cnt; 394 1.22 nonaka int sc_chim_cnt; 395 1.22 nonaka int sc_chim_szmax; 396 1.22 nonaka 397 1.22 nonaka /* Packet transmission aggregation user settings. */ 398 1.22 nonaka int sc_agg_size; 399 1.22 nonaka int sc_agg_pkts; 400 1.1 nonaka }; 401 1.1 nonaka 402 1.1 nonaka #define SC2IFP(_sc_) (&(_sc_)->sc_ec.ec_if) 403 1.1 nonaka #define IFP2SC(_ifp_) ((_ifp_)->if_softc) 404 1.1 nonaka 405 1.22 nonaka #ifndef HVN_TX_PROCESS_LIMIT_DEFAULT 406 1.22 nonaka #define HVN_TX_PROCESS_LIMIT_DEFAULT 128 407 1.22 nonaka #endif 408 1.22 nonaka #ifndef HVN_RX_PROCESS_LIMIT_DEFAULT 409 1.22 nonaka #define HVN_RX_PROCESS_LIMIT_DEFAULT 128 410 1.22 nonaka #endif 411 1.22 nonaka #ifndef HVN_TX_INTR_PROCESS_LIMIT_DEFAULT 412 1.22 nonaka #define HVN_TX_INTR_PROCESS_LIMIT_DEFAULT 256 413 1.22 nonaka #endif 414 1.22 nonaka #ifndef HVN_RX_INTR_PROCESS_LIMIT_DEFAULT 415 1.22 nonaka #define HVN_RX_INTR_PROCESS_LIMIT_DEFAULT 256 416 1.22 nonaka #endif 417 1.22 nonaka 418 1.22 nonaka /* 419 1.22 nonaka * See hvn_set_hlen(). 420 1.22 nonaka * 421 1.22 nonaka * This value is for Azure. For Hyper-V, set this above 422 1.22 nonaka * 65536 to disable UDP datagram checksum fixup. 423 1.22 nonaka */ 424 1.22 nonaka #ifndef HVN_UDP_CKSUM_FIXUP_MTU_DEFAULT 425 1.22 nonaka #define HVN_UDP_CKSUM_FIXUP_MTU_DEFAULT 1420 426 1.22 nonaka #endif 427 1.22 nonaka static int hvn_udpcs_fixup_mtu = HVN_UDP_CKSUM_FIXUP_MTU_DEFAULT; 428 1.22 nonaka 429 1.22 nonaka /* Limit chimney send size */ 430 1.22 nonaka static int hvn_tx_chimney_size = 0; 431 1.22 nonaka 432 1.22 nonaka /* # of channels to use; each channel has one RX ring and one TX ring */ 433 1.22 nonaka #ifndef HVN_CHANNEL_COUNT_DEFAULT 434 1.22 nonaka #define HVN_CHANNEL_COUNT_DEFAULT 0 435 1.22 nonaka #endif 436 1.22 nonaka static int hvn_channel_cnt = HVN_CHANNEL_COUNT_DEFAULT; 437 1.22 nonaka 438 1.22 nonaka /* # of transmit rings to use */ 439 1.22 nonaka #ifndef HVN_TX_RING_COUNT_DEFAULT 440 1.22 nonaka #define HVN_TX_RING_COUNT_DEFAULT 0 441 1.22 nonaka #endif 442 1.22 nonaka static int hvn_tx_ring_cnt = HVN_TX_RING_COUNT_DEFAULT; 443 1.22 nonaka 444 1.22 nonaka /* Packet transmission aggregation size limit */ 445 1.22 nonaka static int hvn_tx_agg_size = -1; 446 1.22 nonaka 447 1.22 nonaka /* Packet transmission aggregation count limit */ 448 1.22 nonaka static int hvn_tx_agg_pkts = -1; 449 1.1 nonaka 450 1.1 nonaka static int hvn_match(device_t, cfdata_t, void *); 451 1.1 nonaka static void hvn_attach(device_t, device_t, void *); 452 1.1 nonaka static int hvn_detach(device_t, int); 453 1.1 nonaka 454 1.1 nonaka CFATTACH_DECL_NEW(hvn, sizeof(struct hvn_softc), 455 1.1 nonaka hvn_match, hvn_attach, hvn_detach, NULL); 456 1.1 nonaka 457 1.1 nonaka static int hvn_ioctl(struct ifnet *, u_long, void *); 458 1.1 nonaka static int hvn_media_change(struct ifnet *); 459 1.1 nonaka static void hvn_media_status(struct ifnet *, struct ifmediareq *); 460 1.22 nonaka static void hvn_link_task(void *); 461 1.22 nonaka static void hvn_link_event(struct hvn_softc *, uint32_t); 462 1.22 nonaka static void hvn_link_netchg_tmout_cb(void *); 463 1.1 nonaka static int hvn_init(struct ifnet *); 464 1.22 nonaka static int hvn_init_locked(struct ifnet *); 465 1.1 nonaka static void hvn_stop(struct ifnet *, int); 466 1.22 nonaka static void hvn_stop_locked(struct ifnet *); 467 1.1 nonaka static void hvn_start(struct ifnet *); 468 1.22 nonaka static int hvn_transmit(struct ifnet *, struct mbuf *); 469 1.22 nonaka static void hvn_deferred_transmit(void *); 470 1.22 nonaka static int hvn_flush_txagg(struct hvn_tx_ring *); 471 1.22 nonaka static int hvn_encap(struct hvn_tx_ring *, struct hvn_tx_desc *, 472 1.22 nonaka struct mbuf *, int); 473 1.22 nonaka static int hvn_txpkt(struct hvn_tx_ring *, struct hvn_tx_desc *); 474 1.22 nonaka static void hvn_txeof(struct hvn_tx_ring *, uint64_t); 475 1.22 nonaka static int hvn_rx_ring_create(struct hvn_softc *, int); 476 1.1 nonaka static int hvn_rx_ring_destroy(struct hvn_softc *); 477 1.22 nonaka static void hvn_fixup_rx_data(struct hvn_softc *); 478 1.22 nonaka static int hvn_tx_ring_create(struct hvn_softc *, int); 479 1.1 nonaka static void hvn_tx_ring_destroy(struct hvn_softc *); 480 1.22 nonaka static void hvn_set_chim_size(struct hvn_softc *, int); 481 1.22 nonaka static uint32_t hvn_chim_alloc(struct hvn_softc *); 482 1.22 nonaka static void hvn_chim_free(struct hvn_softc *, uint32_t); 483 1.22 nonaka static void hvn_fixup_tx_data(struct hvn_softc *); 484 1.22 nonaka static struct mbuf * 485 1.22 nonaka hvn_set_hlen(struct mbuf *, int *); 486 1.22 nonaka static int hvn_txd_peek(struct hvn_tx_ring *); 487 1.22 nonaka static struct hvn_tx_desc * 488 1.22 nonaka hvn_txd_get(struct hvn_tx_ring *); 489 1.22 nonaka static void hvn_txd_put(struct hvn_tx_ring *, struct hvn_tx_desc *); 490 1.22 nonaka static void hvn_txd_gc(struct hvn_tx_ring *, struct hvn_tx_desc *); 491 1.22 nonaka static void hvn_txd_hold(struct hvn_tx_desc *); 492 1.22 nonaka static void hvn_txd_agg(struct hvn_tx_desc *, struct hvn_tx_desc *); 493 1.22 nonaka static int hvn_tx_ring_pending(struct hvn_tx_ring *); 494 1.22 nonaka static void hvn_tx_ring_qflush(struct hvn_softc *, struct hvn_tx_ring *); 495 1.22 nonaka static int hvn_get_rsscaps(struct hvn_softc *, int *); 496 1.22 nonaka static int hvn_set_rss(struct hvn_softc *, uint16_t); 497 1.22 nonaka static void hvn_fixup_rss_ind(struct hvn_softc *); 498 1.22 nonaka static int hvn_get_hwcaps(struct hvn_softc *, struct ndis_offload *); 499 1.22 nonaka static int hvn_set_capabilities(struct hvn_softc *, int); 500 1.1 nonaka static int hvn_get_lladdr(struct hvn_softc *, uint8_t *); 501 1.22 nonaka static void hvn_update_link_status(struct hvn_softc *); 502 1.22 nonaka static int hvn_get_mtu(struct hvn_softc *, uint32_t *); 503 1.22 nonaka static int hvn_channel_attach(struct hvn_softc *, struct vmbus_channel *); 504 1.22 nonaka static void hvn_channel_detach(struct hvn_softc *, struct vmbus_channel *); 505 1.22 nonaka static void hvn_channel_detach_all(struct hvn_softc *); 506 1.22 nonaka static int hvn_subchannel_attach(struct hvn_softc *); 507 1.22 nonaka static int hvn_synth_alloc_subchannels(struct hvn_softc *, int *); 508 1.22 nonaka static int hvn_synth_attachable(const struct hvn_softc *); 509 1.22 nonaka static int hvn_synth_attach(struct hvn_softc *, int); 510 1.22 nonaka static void hvn_synth_detach(struct hvn_softc *); 511 1.22 nonaka static void hvn_set_ring_inuse(struct hvn_softc *, int); 512 1.22 nonaka static void hvn_disable_rx(struct hvn_softc *); 513 1.22 nonaka static void hvn_drain_rxtx(struct hvn_softc *, int ); 514 1.22 nonaka static void hvn_suspend_data(struct hvn_softc *); 515 1.22 nonaka static void hvn_suspend_mgmt(struct hvn_softc *); 516 1.22 nonaka static void hvn_suspend(struct hvn_softc *) __unused; 517 1.22 nonaka static void hvn_resume_tx(struct hvn_softc *, int); 518 1.22 nonaka static void hvn_resume_data(struct hvn_softc *); 519 1.22 nonaka static void hvn_resume_mgmt(struct hvn_softc *); 520 1.22 nonaka static void hvn_resume(struct hvn_softc *) __unused; 521 1.22 nonaka static void hvn_init_sysctls(struct hvn_softc *); 522 1.1 nonaka 523 1.1 nonaka /* NSVP */ 524 1.22 nonaka static int hvn_nvs_init(struct hvn_softc *); 525 1.22 nonaka static void hvn_nvs_destroy(struct hvn_softc *); 526 1.22 nonaka static int hvn_nvs_attach(struct hvn_softc *, int); 527 1.22 nonaka static int hvn_nvs_connect_rxbuf(struct hvn_softc *); 528 1.22 nonaka static int hvn_nvs_disconnect_rxbuf(struct hvn_softc *); 529 1.22 nonaka static int hvn_nvs_connect_chim(struct hvn_softc *); 530 1.22 nonaka static int hvn_nvs_disconnect_chim(struct hvn_softc *); 531 1.22 nonaka static void hvn_handle_ring_work(struct work *, void *); 532 1.22 nonaka static void hvn_nvs_softintr(void *); 533 1.1 nonaka static void hvn_nvs_intr(void *); 534 1.22 nonaka static void hvn_nvs_intr1(struct hvn_rx_ring *, int, int); 535 1.22 nonaka static int hvn_nvs_cmd(struct hvn_softc *, void *, size_t, uint64_t, 536 1.22 nonaka u_int); 537 1.22 nonaka static int hvn_nvs_ack(struct hvn_rx_ring *, uint64_t); 538 1.1 nonaka static void hvn_nvs_detach(struct hvn_softc *); 539 1.22 nonaka static int hvn_nvs_alloc_subchannels(struct hvn_softc *, int *); 540 1.1 nonaka 541 1.1 nonaka /* RNDIS */ 542 1.22 nonaka static int hvn_rndis_init(struct hvn_softc *); 543 1.22 nonaka static void hvn_rndis_destroy(struct hvn_softc *); 544 1.22 nonaka static int hvn_rndis_attach(struct hvn_softc *, int); 545 1.22 nonaka static int hvn_rndis_cmd(struct hvn_softc *, struct rndis_cmd *, u_int); 546 1.22 nonaka static int hvn_rndis_input(struct hvn_rx_ring *, uint64_t, void *); 547 1.22 nonaka static int hvn_rxeof(struct hvn_rx_ring *, uint8_t *, uint32_t); 548 1.1 nonaka static void hvn_rndis_complete(struct hvn_softc *, uint8_t *, uint32_t); 549 1.22 nonaka static int hvn_rndis_output_sgl(struct hvn_tx_ring *, 550 1.22 nonaka struct hvn_tx_desc *); 551 1.22 nonaka static int hvn_rndis_output_chim(struct hvn_tx_ring *, 552 1.22 nonaka struct hvn_tx_desc *); 553 1.1 nonaka static void hvn_rndis_status(struct hvn_softc *, uint8_t *, uint32_t); 554 1.1 nonaka static int hvn_rndis_query(struct hvn_softc *, uint32_t, void *, size_t *); 555 1.22 nonaka static int hvn_rndis_query2(struct hvn_softc *, uint32_t, const void *, 556 1.22 nonaka size_t, void *, size_t *, size_t); 557 1.1 nonaka static int hvn_rndis_set(struct hvn_softc *, uint32_t, void *, size_t); 558 1.1 nonaka static int hvn_rndis_open(struct hvn_softc *); 559 1.1 nonaka static int hvn_rndis_close(struct hvn_softc *); 560 1.1 nonaka static void hvn_rndis_detach(struct hvn_softc *); 561 1.1 nonaka 562 1.1 nonaka static int 563 1.1 nonaka hvn_match(device_t parent, cfdata_t match, void *aux) 564 1.1 nonaka { 565 1.1 nonaka struct vmbus_attach_args *aa = aux; 566 1.1 nonaka 567 1.1 nonaka if (memcmp(aa->aa_type, &hyperv_guid_network, sizeof(*aa->aa_type))) 568 1.1 nonaka return 0; 569 1.1 nonaka return 1; 570 1.1 nonaka } 571 1.1 nonaka 572 1.1 nonaka static void 573 1.1 nonaka hvn_attach(device_t parent, device_t self, void *aux) 574 1.1 nonaka { 575 1.1 nonaka struct hvn_softc *sc = device_private(self); 576 1.1 nonaka struct vmbus_attach_args *aa = aux; 577 1.1 nonaka struct ifnet *ifp = SC2IFP(sc); 578 1.22 nonaka char xnamebuf[32]; 579 1.1 nonaka uint8_t enaddr[ETHER_ADDR_LEN]; 580 1.22 nonaka uint32_t mtu; 581 1.22 nonaka int tx_ring_cnt, ring_cnt; 582 1.22 nonaka int error; 583 1.1 nonaka 584 1.1 nonaka sc->sc_dev = self; 585 1.1 nonaka sc->sc_vmbus = (struct vmbus_softc *)device_private(parent); 586 1.22 nonaka sc->sc_prichan = aa->aa_chan; 587 1.1 nonaka sc->sc_dmat = sc->sc_vmbus->sc_dmat; 588 1.1 nonaka 589 1.1 nonaka aprint_naive("\n"); 590 1.1 nonaka aprint_normal(": Hyper-V NetVSC\n"); 591 1.1 nonaka 592 1.22 nonaka sc->sc_txrx_workqueue = true; 593 1.22 nonaka sc->sc_tx_process_limit = HVN_TX_PROCESS_LIMIT_DEFAULT; 594 1.22 nonaka sc->sc_rx_process_limit = HVN_RX_PROCESS_LIMIT_DEFAULT; 595 1.22 nonaka sc->sc_tx_intr_process_limit = HVN_TX_INTR_PROCESS_LIMIT_DEFAULT; 596 1.22 nonaka sc->sc_rx_intr_process_limit = HVN_RX_INTR_PROCESS_LIMIT_DEFAULT; 597 1.22 nonaka sc->sc_agg_size = hvn_tx_agg_size; 598 1.22 nonaka sc->sc_agg_pkts = hvn_tx_agg_pkts; 599 1.22 nonaka 600 1.22 nonaka mutex_init(&sc->sc_core_lock, MUTEX_DEFAULT, IPL_SOFTNET); 601 1.22 nonaka mutex_init(&sc->sc_link_lock, MUTEX_DEFAULT, IPL_NET); 602 1.22 nonaka cv_init(&sc->sc_link_cv, "hvnknkcv"); 603 1.22 nonaka callout_init(&sc->sc_link_tmout, CALLOUT_MPSAFE); 604 1.22 nonaka callout_setfunc(&sc->sc_link_tmout, hvn_link_netchg_tmout_cb, sc); 605 1.22 nonaka if (kthread_create(PRI_NONE, KTHREAD_MUSTJOIN | KTHREAD_MPSAFE, NULL, 606 1.22 nonaka hvn_link_task, sc, &sc->sc_link_lwp, "%slink", 607 1.22 nonaka device_xname(self))) { 608 1.22 nonaka aprint_error_dev(self, "failed to create link thread\n"); 609 1.1 nonaka return; 610 1.1 nonaka } 611 1.1 nonaka 612 1.22 nonaka snprintf(xnamebuf, sizeof(xnamebuf), "%srxtx", device_xname(self)); 613 1.22 nonaka if (workqueue_create(&sc->sc_wq, xnamebuf, hvn_handle_ring_work, 614 1.22 nonaka sc, HVN_WORKQUEUE_PRI, IPL_NET, WQ_PERCPU | WQ_MPSAFE)) { 615 1.22 nonaka aprint_error_dev(self, "failed to create workqueue\n"); 616 1.22 nonaka sc->sc_wq = NULL; 617 1.22 nonaka goto destroy_link_thread; 618 1.22 nonaka } 619 1.22 nonaka 620 1.22 nonaka ring_cnt = hvn_channel_cnt; 621 1.22 nonaka if (ring_cnt <= 0) { 622 1.22 nonaka ring_cnt = ncpu; 623 1.22 nonaka if (ring_cnt > HVN_CHANNEL_MAX_COUNT_DEFAULT) 624 1.22 nonaka ring_cnt = HVN_CHANNEL_MAX_COUNT_DEFAULT; 625 1.22 nonaka } else if (ring_cnt > ncpu) 626 1.22 nonaka ring_cnt = ncpu; 627 1.22 nonaka 628 1.22 nonaka tx_ring_cnt = hvn_tx_ring_cnt; 629 1.22 nonaka if (tx_ring_cnt <= 0 || tx_ring_cnt > ring_cnt) 630 1.22 nonaka tx_ring_cnt = ring_cnt; 631 1.22 nonaka 632 1.22 nonaka if (hvn_tx_ring_create(sc, tx_ring_cnt)) { 633 1.22 nonaka aprint_error_dev(self, "failed to create Tx ring\n"); 634 1.22 nonaka goto destroy_wq; 635 1.1 nonaka } 636 1.1 nonaka 637 1.22 nonaka if (hvn_rx_ring_create(sc, ring_cnt)) { 638 1.22 nonaka aprint_error_dev(self, "failed to create Rx ring\n"); 639 1.22 nonaka goto destroy_tx_ring; 640 1.1 nonaka } 641 1.1 nonaka 642 1.13 nonaka strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 643 1.1 nonaka ifp->if_softc = sc; 644 1.1 nonaka ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 645 1.22 nonaka ifp->if_extflags = IFEF_MPSAFE; 646 1.1 nonaka ifp->if_ioctl = hvn_ioctl; 647 1.1 nonaka ifp->if_start = hvn_start; 648 1.22 nonaka ifp->if_transmit = hvn_transmit; 649 1.1 nonaka ifp->if_init = hvn_init; 650 1.1 nonaka ifp->if_stop = hvn_stop; 651 1.22 nonaka ifp->if_baudrate = IF_Gbps(10); 652 1.1 nonaka 653 1.22 nonaka IFQ_SET_MAXLEN(&ifp->if_snd, uimax(HVN_TX_DESC - 1, IFQ_MAXLEN)); 654 1.1 nonaka IFQ_SET_READY(&ifp->if_snd); 655 1.1 nonaka 656 1.3 msaitoh /* Initialize ifmedia structures. */ 657 1.3 msaitoh sc->sc_ec.ec_ifmedia = &sc->sc_media; 658 1.18 nonaka ifmedia_init_with_lock(&sc->sc_media, IFM_IMASK, 659 1.22 nonaka hvn_media_change, hvn_media_status, &sc->sc_core_lock); 660 1.22 nonaka ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); 661 1.22 nonaka ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10G_T | IFM_FDX, 0, NULL); 662 1.22 nonaka ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10G_T, 0, NULL); 663 1.22 nonaka ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); 664 1.1 nonaka 665 1.21 riastrad if_initialize(ifp); 666 1.1 nonaka sc->sc_ipq = if_percpuq_create(ifp); 667 1.1 nonaka if_deferred_start_init(ifp, NULL); 668 1.1 nonaka 669 1.22 nonaka hvn_nvs_init(sc); 670 1.22 nonaka hvn_rndis_init(sc); 671 1.22 nonaka if (hvn_synth_attach(sc, ETHERMTU)) { 672 1.22 nonaka aprint_error_dev(self, "failed to attach synth\n"); 673 1.22 nonaka goto destroy_if_percpuq; 674 1.1 nonaka } 675 1.1 nonaka 676 1.1 nonaka aprint_normal_dev(self, "NVS %d.%d NDIS %d.%d\n", 677 1.1 nonaka sc->sc_proto >> 16, sc->sc_proto & 0xffff, 678 1.1 nonaka sc->sc_ndisver >> 16 , sc->sc_ndisver & 0xffff); 679 1.1 nonaka 680 1.1 nonaka if (hvn_get_lladdr(sc, enaddr)) { 681 1.1 nonaka aprint_error_dev(self, 682 1.1 nonaka "failed to obtain an ethernet address\n"); 683 1.22 nonaka goto detach_synth; 684 1.1 nonaka } 685 1.1 nonaka aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(enaddr)); 686 1.1 nonaka 687 1.22 nonaka /* 688 1.22 nonaka * Fixup TX/RX stuffs after synthetic parts are attached. 689 1.22 nonaka */ 690 1.22 nonaka hvn_fixup_tx_data(sc); 691 1.22 nonaka hvn_fixup_rx_data(sc); 692 1.22 nonaka 693 1.22 nonaka ifp->if_capabilities |= sc->sc_txr[0].txr_caps_assist & 694 1.22 nonaka (IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx | 695 1.22 nonaka IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx | 696 1.22 nonaka IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx | 697 1.22 nonaka IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx | 698 1.22 nonaka IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx); 699 1.22 nonaka /* XXX TSOv4, TSOv6 */ 700 1.22 nonaka if (sc->sc_caps & HVN_CAPS_VLAN) { 701 1.22 nonaka /* XXX not sure about VLAN_MTU. */ 702 1.22 nonaka sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING; 703 1.22 nonaka sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 704 1.22 nonaka } 705 1.22 nonaka sc->sc_ec.ec_capabilities |= ETHERCAP_JUMBO_MTU; 706 1.22 nonaka 707 1.1 nonaka ether_ifattach(ifp, enaddr); 708 1.22 nonaka 709 1.22 nonaka error = hvn_get_mtu(sc, &mtu); 710 1.22 nonaka if (error) 711 1.22 nonaka mtu = ETHERMTU; 712 1.22 nonaka if (mtu < ETHERMTU) { 713 1.22 nonaka DPRINTF("%s: fixup mtu %u -> %u\n", device_xname(sc->sc_dev), 714 1.22 nonaka ETHERMTU, mtu); 715 1.22 nonaka ifp->if_mtu = mtu; 716 1.22 nonaka } 717 1.22 nonaka 718 1.1 nonaka if_register(ifp); 719 1.1 nonaka 720 1.22 nonaka /* 721 1.22 nonaka * Kick off link status check. 722 1.22 nonaka */ 723 1.22 nonaka hvn_link_event(sc, HVN_LINK_EV_STATE_CHANGE); 724 1.22 nonaka 725 1.22 nonaka hvn_init_sysctls(sc); 726 1.22 nonaka 727 1.1 nonaka if (pmf_device_register(self, NULL, NULL)) 728 1.1 nonaka pmf_class_network_register(self, ifp); 729 1.1 nonaka else 730 1.1 nonaka aprint_error_dev(self, "couldn't establish power handler\n"); 731 1.1 nonaka 732 1.1 nonaka SET(sc->sc_flags, HVN_SCF_ATTACHED); 733 1.1 nonaka return; 734 1.1 nonaka 735 1.22 nonaka detach_synth: 736 1.22 nonaka hvn_synth_detach(sc); 737 1.22 nonaka hvn_rndis_destroy(sc); 738 1.22 nonaka hvn_nvs_destroy(sc); 739 1.22 nonaka destroy_if_percpuq: 740 1.13 nonaka if_percpuq_destroy(sc->sc_ipq); 741 1.22 nonaka hvn_rx_ring_destroy(sc); 742 1.22 nonaka destroy_tx_ring: 743 1.18 nonaka hvn_tx_ring_destroy(sc); 744 1.22 nonaka destroy_wq: 745 1.22 nonaka workqueue_destroy(sc->sc_wq); 746 1.22 nonaka sc->sc_wq = NULL; 747 1.22 nonaka destroy_link_thread: 748 1.22 nonaka hvn_link_event(sc, HVN_LINK_EV_EXIT_THREAD); 749 1.22 nonaka kthread_join(sc->sc_link_lwp); 750 1.22 nonaka callout_destroy(&sc->sc_link_tmout); 751 1.22 nonaka cv_destroy(&sc->sc_link_cv); 752 1.22 nonaka mutex_destroy(&sc->sc_link_lock); 753 1.22 nonaka mutex_destroy(&sc->sc_core_lock); 754 1.1 nonaka } 755 1.1 nonaka 756 1.1 nonaka static int 757 1.1 nonaka hvn_detach(device_t self, int flags) 758 1.1 nonaka { 759 1.1 nonaka struct hvn_softc *sc = device_private(self); 760 1.1 nonaka struct ifnet *ifp = SC2IFP(sc); 761 1.1 nonaka 762 1.1 nonaka if (!ISSET(sc->sc_flags, HVN_SCF_ATTACHED)) 763 1.1 nonaka return 0; 764 1.1 nonaka 765 1.22 nonaka if (vmbus_channel_is_revoked(sc->sc_prichan)) 766 1.22 nonaka SET(sc->sc_flags, HVN_SCF_REVOKED); 767 1.1 nonaka 768 1.1 nonaka pmf_device_deregister(self); 769 1.1 nonaka 770 1.22 nonaka mutex_enter(&sc->sc_core_lock); 771 1.22 nonaka 772 1.22 nonaka if (ifp->if_flags & IFF_RUNNING) 773 1.22 nonaka hvn_stop_locked(ifp); 774 1.22 nonaka /* 775 1.22 nonaka * NOTE: 776 1.27 andvar * hvn_stop() only suspends data, so management 777 1.22 nonaka * stuffs have to be suspended manually here. 778 1.22 nonaka */ 779 1.22 nonaka hvn_suspend_mgmt(sc); 780 1.22 nonaka 781 1.1 nonaka ether_ifdetach(ifp); 782 1.1 nonaka if_detach(ifp); 783 1.1 nonaka if_percpuq_destroy(sc->sc_ipq); 784 1.1 nonaka 785 1.22 nonaka hvn_link_event(sc, HVN_LINK_EV_EXIT_THREAD); 786 1.22 nonaka kthread_join(sc->sc_link_lwp); 787 1.22 nonaka callout_halt(&sc->sc_link_tmout, NULL); 788 1.22 nonaka 789 1.22 nonaka hvn_synth_detach(sc); 790 1.22 nonaka hvn_rndis_destroy(sc); 791 1.22 nonaka hvn_nvs_destroy(sc); 792 1.22 nonaka 793 1.22 nonaka mutex_exit(&sc->sc_core_lock); 794 1.22 nonaka 795 1.1 nonaka hvn_rx_ring_destroy(sc); 796 1.1 nonaka hvn_tx_ring_destroy(sc); 797 1.22 nonaka 798 1.22 nonaka workqueue_destroy(sc->sc_wq); 799 1.22 nonaka callout_destroy(&sc->sc_link_tmout); 800 1.22 nonaka cv_destroy(&sc->sc_link_cv); 801 1.22 nonaka mutex_destroy(&sc->sc_link_lock); 802 1.22 nonaka mutex_destroy(&sc->sc_core_lock); 803 1.22 nonaka 804 1.22 nonaka sysctl_teardown(&sc->sc_sysctllog); 805 1.1 nonaka 806 1.1 nonaka return 0; 807 1.1 nonaka } 808 1.1 nonaka 809 1.1 nonaka static int 810 1.1 nonaka hvn_ioctl(struct ifnet *ifp, u_long command, void * data) 811 1.1 nonaka { 812 1.1 nonaka struct hvn_softc *sc = IFP2SC(ifp); 813 1.22 nonaka struct ifreq *ifr = (struct ifreq *)data; 814 1.22 nonaka uint32_t mtu; 815 1.1 nonaka int s, error = 0; 816 1.1 nonaka 817 1.22 nonaka switch (command) { 818 1.22 nonaka case SIOCSIFMTU: 819 1.22 nonaka if (ifr->ifr_mtu < HVN_MTU_MIN || ifr->ifr_mtu > HVN_MTU_MAX) { 820 1.22 nonaka error = EINVAL; 821 1.22 nonaka break; 822 1.22 nonaka } 823 1.22 nonaka 824 1.22 nonaka mutex_enter(&sc->sc_core_lock); 825 1.22 nonaka 826 1.22 nonaka if (!(sc->sc_caps & HVN_CAPS_MTU)) { 827 1.22 nonaka /* Can't change MTU */ 828 1.22 nonaka mutex_exit(&sc->sc_core_lock); 829 1.22 nonaka error = EOPNOTSUPP; 830 1.22 nonaka break; 831 1.22 nonaka } 832 1.22 nonaka 833 1.22 nonaka if (ifp->if_mtu == ifr->ifr_mtu) { 834 1.22 nonaka mutex_exit(&sc->sc_core_lock); 835 1.22 nonaka break; 836 1.22 nonaka } 837 1.22 nonaka 838 1.22 nonaka /* 839 1.22 nonaka * Suspend this interface before the synthetic parts 840 1.22 nonaka * are ripped. 841 1.22 nonaka */ 842 1.22 nonaka hvn_suspend(sc); 843 1.22 nonaka 844 1.22 nonaka /* 845 1.22 nonaka * Detach the synthetics parts, i.e. NVS and RNDIS. 846 1.22 nonaka */ 847 1.22 nonaka hvn_synth_detach(sc); 848 1.22 nonaka 849 1.22 nonaka /* 850 1.22 nonaka * Reattach the synthetic parts, i.e. NVS and RNDIS, 851 1.22 nonaka * with the new MTU setting. 852 1.22 nonaka */ 853 1.22 nonaka error = hvn_synth_attach(sc, ifr->ifr_mtu); 854 1.22 nonaka if (error) { 855 1.22 nonaka mutex_exit(&sc->sc_core_lock); 856 1.22 nonaka break; 857 1.22 nonaka } 858 1.1 nonaka 859 1.22 nonaka error = hvn_get_mtu(sc, &mtu); 860 1.22 nonaka if (error) 861 1.22 nonaka mtu = ifr->ifr_mtu; 862 1.22 nonaka DPRINTF("%s: RNDIS mtu=%d\n", device_xname(sc->sc_dev), mtu); 863 1.22 nonaka 864 1.22 nonaka /* 865 1.22 nonaka * Commit the requested MTU, after the synthetic parts 866 1.22 nonaka * have been successfully attached. 867 1.22 nonaka */ 868 1.22 nonaka if (mtu >= ifr->ifr_mtu) { 869 1.22 nonaka mtu = ifr->ifr_mtu; 870 1.22 nonaka } else { 871 1.22 nonaka DPRINTF("%s: fixup mtu %d -> %u\n", 872 1.22 nonaka device_xname(sc->sc_dev), ifr->ifr_mtu, mtu); 873 1.22 nonaka } 874 1.22 nonaka ifp->if_mtu = mtu; 875 1.22 nonaka 876 1.22 nonaka /* 877 1.22 nonaka * Synthetic parts' reattach may change the chimney 878 1.22 nonaka * sending size; update it. 879 1.22 nonaka */ 880 1.22 nonaka if (sc->sc_txr[0].txr_chim_size > sc->sc_chim_szmax) 881 1.22 nonaka hvn_set_chim_size(sc, sc->sc_chim_szmax); 882 1.22 nonaka 883 1.22 nonaka /* 884 1.22 nonaka * All done! Resume the interface now. 885 1.22 nonaka */ 886 1.22 nonaka hvn_resume(sc); 887 1.22 nonaka 888 1.22 nonaka mutex_exit(&sc->sc_core_lock); 889 1.22 nonaka break; 890 1.22 nonaka default: 891 1.22 nonaka s = splnet(); 892 1.22 nonaka if (command == SIOCGIFMEDIA || command == SIOCSIFMEDIA) 893 1.22 nonaka error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command); 894 1.22 nonaka else 895 1.22 nonaka error = ether_ioctl(ifp, command, data); 896 1.22 nonaka splx(s); 897 1.22 nonaka if (error == ENETRESET) { 898 1.22 nonaka mutex_enter(&sc->sc_core_lock); 899 1.22 nonaka if (ifp->if_flags & IFF_RUNNING) 900 1.22 nonaka hvn_init_locked(ifp); 901 1.22 nonaka mutex_exit(&sc->sc_core_lock); 902 1.22 nonaka error = 0; 903 1.22 nonaka } 904 1.22 nonaka break; 905 1.1 nonaka } 906 1.1 nonaka 907 1.1 nonaka return error; 908 1.1 nonaka } 909 1.1 nonaka 910 1.1 nonaka static int 911 1.1 nonaka hvn_media_change(struct ifnet *ifp) 912 1.1 nonaka { 913 1.22 nonaka struct hvn_softc *sc = IFP2SC(ifp); 914 1.22 nonaka struct ifmedia *ifm = &sc->sc_media; 915 1.1 nonaka 916 1.22 nonaka if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 917 1.22 nonaka return EINVAL; 918 1.22 nonaka 919 1.22 nonaka switch (IFM_SUBTYPE(ifm->ifm_media)) { 920 1.22 nonaka case IFM_AUTO: 921 1.22 nonaka break; 922 1.22 nonaka default: 923 1.22 nonaka device_printf(sc->sc_dev, "Only auto media type\n"); 924 1.22 nonaka return EINVAL; 925 1.22 nonaka } 926 1.1 nonaka return 0; 927 1.1 nonaka } 928 1.1 nonaka 929 1.1 nonaka static void 930 1.1 nonaka hvn_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) 931 1.1 nonaka { 932 1.1 nonaka struct hvn_softc *sc = IFP2SC(ifp); 933 1.1 nonaka 934 1.22 nonaka ifmr->ifm_status = IFM_AVALID; 935 1.22 nonaka ifmr->ifm_active = IFM_ETHER; 936 1.22 nonaka 937 1.22 nonaka if (sc->sc_link_state != LINK_STATE_UP) { 938 1.22 nonaka ifmr->ifm_active |= IFM_NONE; 939 1.22 nonaka return; 940 1.22 nonaka } 941 1.22 nonaka 942 1.22 nonaka ifmr->ifm_status |= IFM_ACTIVE; 943 1.22 nonaka ifmr->ifm_active |= IFM_10G_T | IFM_FDX; 944 1.22 nonaka } 945 1.22 nonaka 946 1.22 nonaka static void 947 1.22 nonaka hvn_link_task(void *arg) 948 1.22 nonaka { 949 1.22 nonaka struct hvn_softc *sc = arg; 950 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 951 1.22 nonaka uint32_t event; 952 1.22 nonaka int old_link_state; 953 1.22 nonaka 954 1.22 nonaka mutex_enter(&sc->sc_link_lock); 955 1.22 nonaka sc->sc_link_onproc = false; 956 1.22 nonaka for (;;) { 957 1.22 nonaka if (sc->sc_link_ev == 0) { 958 1.22 nonaka cv_wait(&sc->sc_link_cv, &sc->sc_link_lock); 959 1.22 nonaka continue; 960 1.22 nonaka } 961 1.22 nonaka 962 1.22 nonaka sc->sc_link_onproc = true; 963 1.22 nonaka event = sc->sc_link_ev; 964 1.22 nonaka sc->sc_link_ev = 0; 965 1.22 nonaka mutex_exit(&sc->sc_link_lock); 966 1.22 nonaka 967 1.22 nonaka if (event & HVN_LINK_EV_EXIT_THREAD) 968 1.22 nonaka break; 969 1.22 nonaka 970 1.22 nonaka if (sc->sc_link_suspend) 971 1.22 nonaka goto next; 972 1.22 nonaka 973 1.22 nonaka if (event & HVN_LINK_EV_RESUME_NETWORK) { 974 1.22 nonaka if (sc->sc_link_pending) 975 1.22 nonaka event |= HVN_LINK_EV_NETWORK_CHANGE; 976 1.22 nonaka else 977 1.22 nonaka event |= HVN_LINK_EV_STATE_CHANGE; 978 1.22 nonaka } 979 1.22 nonaka 980 1.22 nonaka if (event & HVN_LINK_EV_NETWORK_CHANGE) { 981 1.22 nonaka /* Prevent any link status checks from running. */ 982 1.22 nonaka sc->sc_link_pending = true; 983 1.22 nonaka 984 1.22 nonaka /* 985 1.22 nonaka * Fake up a [link down --> link up] state change; 986 1.22 nonaka * 5 seconds delay is used, which closely simulates 987 1.22 nonaka * miibus reaction upon link down event. 988 1.22 nonaka */ 989 1.22 nonaka old_link_state = sc->sc_link_state; 990 1.22 nonaka sc->sc_link_state = LINK_STATE_DOWN; 991 1.22 nonaka if (old_link_state != sc->sc_link_state) { 992 1.22 nonaka if_link_state_change(ifp, LINK_STATE_DOWN); 993 1.22 nonaka } 994 1.22 nonaka #if defined(HVN_LINK_STATE_CHANGE_DELAY) && HVN_LINK_STATE_CHANGE_DELAY > 0 995 1.22 nonaka callout_schedule(&sc->sc_link_tmout, 996 1.22 nonaka mstohz(HVN_LINK_STATE_CHANGE_DELAY)); 997 1.22 nonaka #else 998 1.22 nonaka hvn_link_event(sc, HVN_LINK_EV_NETWORK_CHANGE_TMOUT); 999 1.22 nonaka #endif 1000 1.22 nonaka } else if (event & HVN_LINK_EV_NETWORK_CHANGE_TMOUT) { 1001 1.22 nonaka /* Re-allow link status checks. */ 1002 1.22 nonaka sc->sc_link_pending = false; 1003 1.22 nonaka hvn_update_link_status(sc); 1004 1.22 nonaka } else if (event & HVN_LINK_EV_STATE_CHANGE) { 1005 1.22 nonaka if (!sc->sc_link_pending) 1006 1.22 nonaka hvn_update_link_status(sc); 1007 1.22 nonaka } 1008 1.22 nonaka next: 1009 1.22 nonaka mutex_enter(&sc->sc_link_lock); 1010 1.22 nonaka sc->sc_link_onproc = false; 1011 1.22 nonaka } 1012 1.22 nonaka 1013 1.22 nonaka mutex_enter(&sc->sc_link_lock); 1014 1.22 nonaka sc->sc_link_onproc = false; 1015 1.22 nonaka mutex_exit(&sc->sc_link_lock); 1016 1.22 nonaka 1017 1.22 nonaka kthread_exit(0); 1018 1.22 nonaka } 1019 1.22 nonaka 1020 1.22 nonaka static void 1021 1.22 nonaka hvn_link_event(struct hvn_softc *sc, uint32_t ev) 1022 1.22 nonaka { 1023 1.22 nonaka 1024 1.22 nonaka mutex_enter(&sc->sc_link_lock); 1025 1.22 nonaka SET(sc->sc_link_ev, ev); 1026 1.22 nonaka cv_signal(&sc->sc_link_cv); 1027 1.22 nonaka mutex_exit(&sc->sc_link_lock); 1028 1.22 nonaka } 1029 1.22 nonaka 1030 1.22 nonaka static void 1031 1.22 nonaka hvn_link_netchg_tmout_cb(void *arg) 1032 1.22 nonaka { 1033 1.22 nonaka struct hvn_softc *sc = arg; 1034 1.1 nonaka 1035 1.22 nonaka hvn_link_event(sc, HVN_LINK_EV_NETWORK_CHANGE_TMOUT); 1036 1.1 nonaka } 1037 1.1 nonaka 1038 1.1 nonaka static int 1039 1.22 nonaka hvn_init(struct ifnet *ifp) 1040 1.1 nonaka { 1041 1.22 nonaka struct hvn_softc *sc = IFP2SC(ifp); 1042 1.22 nonaka int error; 1043 1.1 nonaka 1044 1.22 nonaka mutex_enter(&sc->sc_core_lock); 1045 1.22 nonaka error = hvn_init_locked(ifp); 1046 1.22 nonaka mutex_exit(&sc->sc_core_lock); 1047 1.1 nonaka 1048 1.22 nonaka return error; 1049 1.1 nonaka } 1050 1.1 nonaka 1051 1.1 nonaka static int 1052 1.22 nonaka hvn_init_locked(struct ifnet *ifp) 1053 1.1 nonaka { 1054 1.1 nonaka struct hvn_softc *sc = IFP2SC(ifp); 1055 1.1 nonaka int error; 1056 1.1 nonaka 1057 1.22 nonaka KASSERT(mutex_owned(&sc->sc_core_lock)); 1058 1.22 nonaka 1059 1.22 nonaka hvn_stop_locked(ifp); 1060 1.1 nonaka 1061 1.22 nonaka error = hvn_rndis_open(sc); 1062 1.1 nonaka if (error) 1063 1.1 nonaka return error; 1064 1.1 nonaka 1065 1.22 nonaka /* Clear TX 'suspended' bit. */ 1066 1.22 nonaka hvn_resume_tx(sc, sc->sc_ntxr_inuse); 1067 1.22 nonaka 1068 1.22 nonaka /* Everything is ready; unleash! */ 1069 1.22 nonaka ifp->if_flags |= IFF_RUNNING; 1070 1.22 nonaka 1071 1.22 nonaka return 0; 1072 1.1 nonaka } 1073 1.1 nonaka 1074 1.1 nonaka static void 1075 1.1 nonaka hvn_stop(struct ifnet *ifp, int disable) 1076 1.1 nonaka { 1077 1.1 nonaka struct hvn_softc *sc = IFP2SC(ifp); 1078 1.1 nonaka 1079 1.22 nonaka mutex_enter(&sc->sc_core_lock); 1080 1.22 nonaka hvn_stop_locked(ifp); 1081 1.22 nonaka mutex_exit(&sc->sc_core_lock); 1082 1.22 nonaka } 1083 1.22 nonaka 1084 1.22 nonaka static void 1085 1.22 nonaka hvn_stop_locked(struct ifnet *ifp) 1086 1.22 nonaka { 1087 1.22 nonaka struct hvn_softc *sc = IFP2SC(ifp); 1088 1.22 nonaka int i; 1089 1.22 nonaka 1090 1.22 nonaka KASSERT(mutex_owned(&sc->sc_core_lock)); 1091 1.22 nonaka 1092 1.22 nonaka /* Clear RUNNING bit ASAP. */ 1093 1.22 nonaka ifp->if_flags &= ~IFF_RUNNING; 1094 1.1 nonaka 1095 1.22 nonaka /* Suspend data transfers. */ 1096 1.22 nonaka hvn_suspend_data(sc); 1097 1.22 nonaka 1098 1.24 thorpej /* Clear OACTIVE state. */ 1099 1.22 nonaka for (i = 0; i < sc->sc_ntxr_inuse; i++) 1100 1.22 nonaka sc->sc_txr[i].txr_oactive = 0; 1101 1.1 nonaka } 1102 1.1 nonaka 1103 1.1 nonaka static void 1104 1.22 nonaka hvn_transmit_common(struct ifnet *ifp, struct hvn_tx_ring *txr, 1105 1.22 nonaka bool is_transmit) 1106 1.1 nonaka { 1107 1.1 nonaka struct hvn_tx_desc *txd; 1108 1.1 nonaka struct mbuf *m; 1109 1.22 nonaka int l2hlen = ETHER_HDR_LEN; 1110 1.1 nonaka 1111 1.22 nonaka KASSERT(mutex_owned(&txr->txr_lock)); 1112 1.22 nonaka 1113 1.22 nonaka if (!(ifp->if_flags & IFF_RUNNING)) 1114 1.22 nonaka return; 1115 1.22 nonaka if (txr->txr_oactive) 1116 1.22 nonaka return; 1117 1.22 nonaka if (txr->txr_suspended) 1118 1.1 nonaka return; 1119 1.1 nonaka 1120 1.1 nonaka for (;;) { 1121 1.22 nonaka if (!hvn_txd_peek(txr)) { 1122 1.1 nonaka /* transient */ 1123 1.22 nonaka txr->txr_oactive = 1; 1124 1.22 nonaka txr->txr_evnodesc.ev_count++; 1125 1.1 nonaka break; 1126 1.1 nonaka } 1127 1.1 nonaka 1128 1.22 nonaka if (is_transmit) 1129 1.22 nonaka m = pcq_get(txr->txr_interq); 1130 1.22 nonaka else 1131 1.22 nonaka IFQ_DEQUEUE(&ifp->if_snd, m); 1132 1.1 nonaka if (m == NULL) 1133 1.1 nonaka break; 1134 1.1 nonaka 1135 1.22 nonaka #if defined(INET) || defined(INET6) 1136 1.22 nonaka if (m->m_pkthdr.csum_flags & 1137 1.22 nonaka (M_CSUM_TCPv4|M_CSUM_UDPv4|M_CSUM_TCPv6|M_CSUM_UDPv6)) { 1138 1.22 nonaka m = hvn_set_hlen(m, &l2hlen); 1139 1.22 nonaka if (__predict_false(m == NULL)) { 1140 1.22 nonaka if_statinc(ifp, if_oerrors); 1141 1.22 nonaka continue; 1142 1.22 nonaka } 1143 1.22 nonaka } 1144 1.22 nonaka #endif 1145 1.22 nonaka 1146 1.22 nonaka txd = hvn_txd_get(txr); 1147 1.22 nonaka if (hvn_encap(txr, txd, m, l2hlen)) { 1148 1.1 nonaka /* the chain is too large */ 1149 1.16 thorpej if_statinc(ifp, if_oerrors); 1150 1.22 nonaka hvn_txd_put(txr, txd); 1151 1.1 nonaka m_freem(m); 1152 1.1 nonaka continue; 1153 1.1 nonaka } 1154 1.1 nonaka 1155 1.22 nonaka if (txr->txr_agg_pktleft == 0) { 1156 1.22 nonaka if (txr->txr_agg_txd != NULL) { 1157 1.22 nonaka hvn_flush_txagg(txr); 1158 1.22 nonaka } else { 1159 1.22 nonaka if (hvn_txpkt(txr, txd)) { 1160 1.22 nonaka /* txd is freed, but m is not. */ 1161 1.22 nonaka m_freem(m); 1162 1.22 nonaka if_statinc(ifp, if_oerrors); 1163 1.22 nonaka } 1164 1.22 nonaka } 1165 1.22 nonaka } 1166 1.22 nonaka } 1167 1.22 nonaka 1168 1.22 nonaka /* Flush pending aggerated transmission. */ 1169 1.22 nonaka if (txr->txr_agg_txd != NULL) 1170 1.22 nonaka hvn_flush_txagg(txr); 1171 1.22 nonaka } 1172 1.22 nonaka 1173 1.22 nonaka static void 1174 1.22 nonaka hvn_start(struct ifnet *ifp) 1175 1.22 nonaka { 1176 1.22 nonaka struct hvn_softc *sc = IFP2SC(ifp); 1177 1.22 nonaka struct hvn_tx_ring *txr = &sc->sc_txr[0]; 1178 1.22 nonaka 1179 1.22 nonaka mutex_enter(&txr->txr_lock); 1180 1.22 nonaka hvn_transmit_common(ifp, txr, false); 1181 1.22 nonaka mutex_exit(&txr->txr_lock); 1182 1.22 nonaka } 1183 1.22 nonaka 1184 1.22 nonaka static int 1185 1.22 nonaka hvn_select_txqueue(struct ifnet *ifp, struct mbuf *m __unused) 1186 1.22 nonaka { 1187 1.22 nonaka struct hvn_softc *sc = IFP2SC(ifp); 1188 1.22 nonaka u_int cpu; 1189 1.22 nonaka 1190 1.22 nonaka cpu = cpu_index(curcpu()); 1191 1.22 nonaka 1192 1.22 nonaka return cpu % sc->sc_ntxr_inuse; 1193 1.22 nonaka } 1194 1.22 nonaka 1195 1.22 nonaka static int 1196 1.22 nonaka hvn_transmit(struct ifnet *ifp, struct mbuf *m) 1197 1.22 nonaka { 1198 1.22 nonaka struct hvn_softc *sc = IFP2SC(ifp); 1199 1.22 nonaka struct hvn_tx_ring *txr; 1200 1.22 nonaka int qid; 1201 1.22 nonaka 1202 1.22 nonaka qid = hvn_select_txqueue(ifp, m); 1203 1.22 nonaka txr = &sc->sc_txr[qid]; 1204 1.22 nonaka 1205 1.22 nonaka if (__predict_false(!pcq_put(txr->txr_interq, m))) { 1206 1.22 nonaka mutex_enter(&txr->txr_lock); 1207 1.22 nonaka txr->txr_evpcqdrop.ev_count++; 1208 1.22 nonaka mutex_exit(&txr->txr_lock); 1209 1.22 nonaka m_freem(m); 1210 1.22 nonaka return ENOBUFS; 1211 1.22 nonaka } 1212 1.22 nonaka 1213 1.22 nonaka kpreempt_disable(); 1214 1.22 nonaka softint_schedule(txr->txr_si); 1215 1.22 nonaka kpreempt_enable(); 1216 1.22 nonaka return 0; 1217 1.22 nonaka } 1218 1.1 nonaka 1219 1.22 nonaka static void 1220 1.22 nonaka hvn_deferred_transmit(void *arg) 1221 1.22 nonaka { 1222 1.22 nonaka struct hvn_tx_ring *txr = arg; 1223 1.22 nonaka struct hvn_softc *sc = txr->txr_softc; 1224 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 1225 1.1 nonaka 1226 1.22 nonaka mutex_enter(&txr->txr_lock); 1227 1.22 nonaka txr->txr_evtransmitdefer.ev_count++; 1228 1.22 nonaka hvn_transmit_common(ifp, txr, true); 1229 1.22 nonaka mutex_exit(&txr->txr_lock); 1230 1.1 nonaka } 1231 1.1 nonaka 1232 1.1 nonaka static inline char * 1233 1.1 nonaka hvn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize, 1234 1.1 nonaka size_t datalen, uint32_t type) 1235 1.1 nonaka { 1236 1.1 nonaka struct rndis_pktinfo *pi; 1237 1.1 nonaka size_t pi_size = sizeof(*pi) + datalen; 1238 1.1 nonaka char *cp; 1239 1.1 nonaka 1240 1.1 nonaka KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <= 1241 1.1 nonaka pktsize); 1242 1.1 nonaka 1243 1.1 nonaka cp = (char *)pkt + pkt->rm_pktinfooffset + pkt->rm_pktinfolen; 1244 1.1 nonaka pi = (struct rndis_pktinfo *)cp; 1245 1.1 nonaka pi->rm_size = pi_size; 1246 1.1 nonaka pi->rm_type = type; 1247 1.1 nonaka pi->rm_pktinfooffset = sizeof(*pi); 1248 1.1 nonaka pkt->rm_pktinfolen += pi_size; 1249 1.1 nonaka pkt->rm_dataoffset += pi_size; 1250 1.1 nonaka pkt->rm_len += pi_size; 1251 1.1 nonaka 1252 1.1 nonaka return (char *)pi->rm_data; 1253 1.1 nonaka } 1254 1.1 nonaka 1255 1.22 nonaka static struct mbuf * 1256 1.22 nonaka hvn_pullup_hdr(struct mbuf *m, int len) 1257 1.1 nonaka { 1258 1.22 nonaka struct mbuf *mn; 1259 1.1 nonaka 1260 1.22 nonaka if (__predict_false(m->m_len < len)) { 1261 1.22 nonaka mn = m_pullup(m, len); 1262 1.22 nonaka if (mn == NULL) 1263 1.22 nonaka return NULL; 1264 1.22 nonaka m = mn; 1265 1.22 nonaka } 1266 1.22 nonaka return m; 1267 1.22 nonaka } 1268 1.1 nonaka 1269 1.22 nonaka /* 1270 1.22 nonaka * NOTE: If this function failed, the m would be freed. 1271 1.22 nonaka */ 1272 1.22 nonaka static struct mbuf * 1273 1.22 nonaka hvn_set_hlen(struct mbuf *m, int *l2hlenp) 1274 1.22 nonaka { 1275 1.22 nonaka const struct ether_header *eh; 1276 1.22 nonaka int l2hlen, off; 1277 1.1 nonaka 1278 1.22 nonaka m = hvn_pullup_hdr(m, sizeof(*eh)); 1279 1.22 nonaka if (m == NULL) 1280 1.22 nonaka return NULL; 1281 1.1 nonaka 1282 1.22 nonaka eh = mtod(m, const struct ether_header *); 1283 1.22 nonaka if (eh->ether_type == ntohs(ETHERTYPE_VLAN)) 1284 1.22 nonaka l2hlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 1285 1.22 nonaka else 1286 1.22 nonaka l2hlen = ETHER_HDR_LEN; 1287 1.1 nonaka 1288 1.22 nonaka #if defined(INET) 1289 1.22 nonaka if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) { 1290 1.22 nonaka const struct ip *ip; 1291 1.1 nonaka 1292 1.22 nonaka off = l2hlen + sizeof(*ip); 1293 1.22 nonaka m = hvn_pullup_hdr(m, off); 1294 1.22 nonaka if (m == NULL) 1295 1.22 nonaka return NULL; 1296 1.1 nonaka 1297 1.22 nonaka ip = (struct ip *)((mtod(m, uint8_t *)) + off); 1298 1.22 nonaka 1299 1.22 nonaka /* 1300 1.22 nonaka * UDP checksum offload does not work in Azure, if the 1301 1.22 nonaka * following conditions meet: 1302 1.22 nonaka * - sizeof(IP hdr + UDP hdr + payload) > 1420. 1303 1.22 nonaka * - IP_DF is not set in the IP hdr. 1304 1.22 nonaka * 1305 1.22 nonaka * Fallback to software checksum for these UDP datagrams. 1306 1.22 nonaka */ 1307 1.22 nonaka if ((m->m_pkthdr.csum_flags & M_CSUM_UDPv4) && 1308 1.22 nonaka m->m_pkthdr.len > hvn_udpcs_fixup_mtu + l2hlen && 1309 1.22 nonaka !(ntohs(ip->ip_off) & IP_DF)) { 1310 1.22 nonaka uint16_t *csump; 1311 1.22 nonaka 1312 1.22 nonaka off = l2hlen + 1313 1.22 nonaka M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data); 1314 1.22 nonaka m = hvn_pullup_hdr(m, off + sizeof(struct udphdr)); 1315 1.22 nonaka if (m == NULL) 1316 1.22 nonaka return NULL; 1317 1.22 nonaka 1318 1.22 nonaka csump = (uint16_t *)(mtod(m, uint8_t *) + off + 1319 1.22 nonaka M_CSUM_DATA_IPv4_OFFSET(m->m_pkthdr.csum_data)); 1320 1.22 nonaka *csump = cpu_in_cksum(m, m->m_pkthdr.len - off, off, 0); 1321 1.22 nonaka m->m_pkthdr.csum_flags &= ~M_CSUM_UDPv4; 1322 1.22 nonaka } 1323 1.22 nonaka } 1324 1.22 nonaka #endif /* INET */ 1325 1.22 nonaka #if defined(INET) && defined(INET6) 1326 1.22 nonaka else 1327 1.22 nonaka #endif /* INET && INET6 */ 1328 1.22 nonaka #if defined(INET6) 1329 1.22 nonaka { 1330 1.22 nonaka const struct ip6_hdr *ip6; 1331 1.22 nonaka 1332 1.22 nonaka off = l2hlen + sizeof(*ip6); 1333 1.22 nonaka m = hvn_pullup_hdr(m, off); 1334 1.22 nonaka if (m == NULL) 1335 1.22 nonaka return NULL; 1336 1.22 nonaka 1337 1.22 nonaka ip6 = (struct ip6_hdr *)((mtod(m, uint8_t *)) + l2hlen); 1338 1.22 nonaka if (ip6->ip6_nxt != IPPROTO_TCP && 1339 1.22 nonaka ip6->ip6_nxt != IPPROTO_UDP) { 1340 1.22 nonaka m_freem(m); 1341 1.22 nonaka return NULL; 1342 1.22 nonaka } 1343 1.22 nonaka } 1344 1.22 nonaka #endif /* INET6 */ 1345 1.22 nonaka 1346 1.22 nonaka *l2hlenp = l2hlen; 1347 1.22 nonaka 1348 1.22 nonaka return m; 1349 1.22 nonaka } 1350 1.22 nonaka 1351 1.22 nonaka static int 1352 1.22 nonaka hvn_flush_txagg(struct hvn_tx_ring *txr) 1353 1.22 nonaka { 1354 1.22 nonaka struct hvn_softc *sc = txr->txr_softc; 1355 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 1356 1.22 nonaka struct hvn_tx_desc *txd; 1357 1.22 nonaka struct mbuf *m; 1358 1.22 nonaka int error, pkts; 1359 1.22 nonaka 1360 1.22 nonaka txd = txr->txr_agg_txd; 1361 1.22 nonaka KASSERTMSG(txd != NULL, "no aggregate txdesc"); 1362 1.22 nonaka 1363 1.22 nonaka /* 1364 1.22 nonaka * Since hvn_txpkt() will reset this temporary stat, save 1365 1.22 nonaka * it now, so that oerrors can be updated properly, if 1366 1.22 nonaka * hvn_txpkt() ever fails. 1367 1.22 nonaka */ 1368 1.22 nonaka pkts = txr->txr_stat_pkts; 1369 1.22 nonaka 1370 1.22 nonaka /* 1371 1.22 nonaka * Since txd's mbuf will _not_ be freed upon hvn_txpkt() 1372 1.22 nonaka * failure, save it for later freeing, if hvn_txpkt() ever 1373 1.22 nonaka * fails. 1374 1.22 nonaka */ 1375 1.22 nonaka m = txd->txd_buf; 1376 1.22 nonaka error = hvn_txpkt(txr, txd); 1377 1.22 nonaka if (__predict_false(error)) { 1378 1.22 nonaka /* txd is freed, but m is not. */ 1379 1.22 nonaka m_freem(m); 1380 1.22 nonaka txr->txr_evflushfailed.ev_count++; 1381 1.22 nonaka if_statadd(ifp, if_oerrors, pkts); 1382 1.22 nonaka } 1383 1.22 nonaka 1384 1.22 nonaka /* Reset all aggregation states. */ 1385 1.22 nonaka txr->txr_agg_txd = NULL; 1386 1.22 nonaka txr->txr_agg_szleft = 0; 1387 1.22 nonaka txr->txr_agg_pktleft = 0; 1388 1.22 nonaka txr->txr_agg_prevpkt = NULL; 1389 1.22 nonaka 1390 1.22 nonaka return error; 1391 1.22 nonaka } 1392 1.22 nonaka 1393 1.22 nonaka static void * 1394 1.22 nonaka hvn_try_txagg(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd, int pktsz) 1395 1.22 nonaka { 1396 1.22 nonaka struct hvn_softc *sc = txr->txr_softc; 1397 1.22 nonaka struct hvn_tx_desc *agg_txd; 1398 1.22 nonaka struct rndis_packet_msg *pkt; 1399 1.22 nonaka void *chim; 1400 1.22 nonaka int olen; 1401 1.22 nonaka 1402 1.22 nonaka if (txr->txr_agg_txd != NULL) { 1403 1.22 nonaka if (txr->txr_agg_pktleft > 0 && txr->txr_agg_szleft > pktsz) { 1404 1.22 nonaka agg_txd = txr->txr_agg_txd; 1405 1.22 nonaka pkt = txr->txr_agg_prevpkt; 1406 1.22 nonaka 1407 1.22 nonaka /* 1408 1.22 nonaka * Update the previous RNDIS packet's total length, 1409 1.22 nonaka * it can be increased due to the mandatory alignment 1410 1.22 nonaka * padding for this RNDIS packet. And update the 1411 1.22 nonaka * aggregating txdesc's chimney sending buffer size 1412 1.22 nonaka * accordingly. 1413 1.22 nonaka * 1414 1.22 nonaka * XXX 1415 1.22 nonaka * Zero-out the padding, as required by the RNDIS spec. 1416 1.22 nonaka */ 1417 1.22 nonaka olen = pkt->rm_len; 1418 1.22 nonaka pkt->rm_len = roundup2(olen, txr->txr_agg_align); 1419 1.22 nonaka agg_txd->txd_chim_size += pkt->rm_len - olen; 1420 1.22 nonaka 1421 1.22 nonaka /* Link this txdesc to the parent. */ 1422 1.22 nonaka hvn_txd_agg(agg_txd, txd); 1423 1.22 nonaka 1424 1.22 nonaka chim = (uint8_t *)pkt + pkt->rm_len; 1425 1.22 nonaka /* Save the current packet for later fixup. */ 1426 1.22 nonaka txr->txr_agg_prevpkt = chim; 1427 1.22 nonaka 1428 1.22 nonaka txr->txr_agg_pktleft--; 1429 1.22 nonaka txr->txr_agg_szleft -= pktsz; 1430 1.22 nonaka if (txr->txr_agg_szleft <= 1431 1.22 nonaka HVN_PKTSIZE_MIN(txr->txr_agg_align)) { 1432 1.22 nonaka /* 1433 1.22 nonaka * Probably can't aggregate more packets, 1434 1.22 nonaka * flush this aggregating txdesc proactively. 1435 1.22 nonaka */ 1436 1.22 nonaka txr->txr_agg_pktleft = 0; 1437 1.22 nonaka } 1438 1.22 nonaka 1439 1.22 nonaka /* Done! */ 1440 1.22 nonaka return chim; 1441 1.22 nonaka } 1442 1.22 nonaka hvn_flush_txagg(txr); 1443 1.22 nonaka } 1444 1.22 nonaka 1445 1.22 nonaka txr->txr_evchimneytried.ev_count++; 1446 1.22 nonaka txd->txd_chim_index = hvn_chim_alloc(sc); 1447 1.22 nonaka if (txd->txd_chim_index == HVN_NVS_CHIM_IDX_INVALID) 1448 1.22 nonaka return NULL; 1449 1.22 nonaka txr->txr_evchimney.ev_count++; 1450 1.22 nonaka 1451 1.22 nonaka chim = sc->sc_chim + (txd->txd_chim_index * sc->sc_chim_szmax); 1452 1.22 nonaka 1453 1.22 nonaka if (txr->txr_agg_pktmax > 1 && 1454 1.22 nonaka txr->txr_agg_szmax > pktsz + HVN_PKTSIZE_MIN(txr->txr_agg_align)) { 1455 1.22 nonaka txr->txr_agg_txd = txd; 1456 1.22 nonaka txr->txr_agg_pktleft = txr->txr_agg_pktmax - 1; 1457 1.22 nonaka txr->txr_agg_szleft = txr->txr_agg_szmax - pktsz; 1458 1.22 nonaka txr->txr_agg_prevpkt = chim; 1459 1.22 nonaka } 1460 1.22 nonaka 1461 1.22 nonaka return chim; 1462 1.22 nonaka } 1463 1.22 nonaka 1464 1.22 nonaka static int 1465 1.22 nonaka hvn_encap(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd, struct mbuf *m, 1466 1.22 nonaka int l2hlen) 1467 1.22 nonaka { 1468 1.22 nonaka /* Used to pad ethernet frames with < ETHER_MIN_LEN bytes */ 1469 1.22 nonaka static const char zero_pad[ETHER_MIN_LEN]; 1470 1.22 nonaka struct hvn_softc *sc = txr->txr_softc; 1471 1.22 nonaka struct rndis_packet_msg *pkt; 1472 1.22 nonaka bus_dma_segment_t *seg; 1473 1.22 nonaka void *chim = NULL; 1474 1.22 nonaka size_t pktlen, pktsize; 1475 1.22 nonaka int l3hlen; 1476 1.22 nonaka int i, rv; 1477 1.22 nonaka 1478 1.22 nonaka if (ISSET(sc->sc_caps, HVN_CAPS_VLAN) && !vlan_has_tag(m)) { 1479 1.22 nonaka struct ether_vlan_header *evl; 1480 1.22 nonaka 1481 1.22 nonaka m = hvn_pullup_hdr(m, sizeof(*evl)); 1482 1.22 nonaka if (m == NULL) { 1483 1.22 nonaka DPRINTF("%s: failed to pullup mbuf\n", 1484 1.22 nonaka device_xname(sc->sc_dev)); 1485 1.22 nonaka return -1; 1486 1.22 nonaka } 1487 1.22 nonaka 1488 1.22 nonaka evl = mtod(m, struct ether_vlan_header *); 1489 1.22 nonaka if (evl->evl_encap_proto == htons(ETHERTYPE_VLAN)) { 1490 1.22 nonaka struct ether_header *eh; 1491 1.22 nonaka uint16_t proto = evl->evl_proto; 1492 1.22 nonaka 1493 1.22 nonaka vlan_set_tag(m, ntohs(evl->evl_tag)); 1494 1.22 nonaka 1495 1.22 nonaka /* 1496 1.22 nonaka * Trim VLAN tag from header. 1497 1.22 nonaka */ 1498 1.22 nonaka memmove((uint8_t *)evl + ETHER_VLAN_ENCAP_LEN, 1499 1.22 nonaka evl, ETHER_HDR_LEN); 1500 1.22 nonaka m_adj(m, ETHER_VLAN_ENCAP_LEN); 1501 1.22 nonaka 1502 1.22 nonaka eh = mtod(m, struct ether_header *); 1503 1.22 nonaka eh->ether_type = proto; 1504 1.22 nonaka 1505 1.22 nonaka /* 1506 1.22 nonaka * Re-padding. See sys/net/if_vlan.c:vlan_start(). 1507 1.22 nonaka */ 1508 1.22 nonaka if (m->m_pkthdr.len < (ETHER_MIN_LEN - ETHER_CRC_LEN + 1509 1.22 nonaka ETHER_VLAN_ENCAP_LEN)) { 1510 1.22 nonaka m_copyback(m, m->m_pkthdr.len, 1511 1.22 nonaka (ETHER_MIN_LEN - ETHER_CRC_LEN + 1512 1.22 nonaka ETHER_VLAN_ENCAP_LEN) - 1513 1.22 nonaka m->m_pkthdr.len, zero_pad); 1514 1.22 nonaka } 1515 1.22 nonaka 1516 1.22 nonaka txr->txr_evvlanfixup.ev_count++; 1517 1.22 nonaka } 1518 1.22 nonaka } 1519 1.22 nonaka 1520 1.22 nonaka pkt = txd->txd_req; 1521 1.22 nonaka pktsize = HVN_PKTSIZE(m, txr->txr_agg_align); 1522 1.22 nonaka if (pktsize < txr->txr_chim_size) { 1523 1.22 nonaka chim = hvn_try_txagg(txr, txd, pktsize); 1524 1.22 nonaka if (chim != NULL) 1525 1.22 nonaka pkt = chim; 1526 1.22 nonaka } else { 1527 1.22 nonaka if (txr->txr_agg_txd != NULL) 1528 1.22 nonaka hvn_flush_txagg(txr); 1529 1.22 nonaka } 1530 1.22 nonaka 1531 1.22 nonaka memset(pkt, 0, HVN_RNDIS_PKT_LEN); 1532 1.22 nonaka pkt->rm_type = REMOTE_NDIS_PACKET_MSG; 1533 1.22 nonaka pkt->rm_len = sizeof(*pkt) + m->m_pkthdr.len; 1534 1.22 nonaka pkt->rm_dataoffset = RNDIS_DATA_OFFSET; 1535 1.22 nonaka pkt->rm_datalen = m->m_pkthdr.len; 1536 1.22 nonaka pkt->rm_pktinfooffset = sizeof(*pkt); /* adjusted below */ 1537 1.22 nonaka pkt->rm_pktinfolen = 0; 1538 1.22 nonaka 1539 1.22 nonaka if (txr->txr_flags & HVN_TXR_FLAG_UDP_HASH) { 1540 1.22 nonaka char *cp; 1541 1.22 nonaka 1542 1.22 nonaka /* 1543 1.22 nonaka * Set the hash value for this packet, so that the host could 1544 1.22 nonaka * dispatch the TX done event for this packet back to this TX 1545 1.22 nonaka * ring's channel. 1546 1.22 nonaka */ 1547 1.22 nonaka cp = hvn_rndis_pktinfo_append(pkt, HVN_RNDIS_PKT_LEN, 1548 1.22 nonaka HVN_NDIS_HASH_VALUE_SIZE, HVN_NDIS_PKTINFO_TYPE_HASHVAL); 1549 1.22 nonaka memcpy(cp, &txr->txr_id, HVN_NDIS_HASH_VALUE_SIZE); 1550 1.22 nonaka } 1551 1.22 nonaka 1552 1.22 nonaka if (vlan_has_tag(m)) { 1553 1.22 nonaka uint32_t vlan; 1554 1.22 nonaka char *cp; 1555 1.22 nonaka uint16_t tag; 1556 1.22 nonaka 1557 1.22 nonaka tag = vlan_get_tag(m); 1558 1.22 nonaka vlan = NDIS_VLAN_INFO_MAKE(EVL_VLANOFTAG(tag), 1559 1.22 nonaka EVL_PRIOFTAG(tag), EVL_CFIOFTAG(tag)); 1560 1.22 nonaka cp = hvn_rndis_pktinfo_append(pkt, HVN_RNDIS_PKT_LEN, 1561 1.22 nonaka NDIS_VLAN_INFO_SIZE, NDIS_PKTINFO_TYPE_VLAN); 1562 1.22 nonaka memcpy(cp, &vlan, NDIS_VLAN_INFO_SIZE); 1563 1.22 nonaka txr->txr_evvlanhwtagging.ev_count++; 1564 1.22 nonaka } 1565 1.22 nonaka 1566 1.22 nonaka if (m->m_pkthdr.csum_flags & txr->txr_csum_assist) { 1567 1.22 nonaka uint32_t csum; 1568 1.22 nonaka char *cp; 1569 1.22 nonaka 1570 1.22 nonaka if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv6 | M_CSUM_UDPv6)) { 1571 1.22 nonaka csum = NDIS_TXCSUM_INFO_IPV6; 1572 1.22 nonaka l3hlen = M_CSUM_DATA_IPv6_IPHL(m->m_pkthdr.csum_data); 1573 1.22 nonaka if (m->m_pkthdr.csum_flags & M_CSUM_TCPv6) 1574 1.22 nonaka csum |= NDIS_TXCSUM_INFO_MKTCPCS(l2hlen + 1575 1.22 nonaka l3hlen); 1576 1.22 nonaka if (m->m_pkthdr.csum_flags & M_CSUM_UDPv6) 1577 1.22 nonaka csum |= NDIS_TXCSUM_INFO_MKUDPCS(l2hlen + 1578 1.22 nonaka l3hlen); 1579 1.22 nonaka } else { 1580 1.22 nonaka csum = NDIS_TXCSUM_INFO_IPV4; 1581 1.22 nonaka l3hlen = M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data); 1582 1.22 nonaka if (m->m_pkthdr.csum_flags & M_CSUM_IPv4) 1583 1.22 nonaka csum |= NDIS_TXCSUM_INFO_IPCS; 1584 1.22 nonaka if (m->m_pkthdr.csum_flags & M_CSUM_TCPv4) 1585 1.22 nonaka csum |= NDIS_TXCSUM_INFO_MKTCPCS(l2hlen + 1586 1.22 nonaka l3hlen); 1587 1.22 nonaka if (m->m_pkthdr.csum_flags & M_CSUM_UDPv4) 1588 1.22 nonaka csum |= NDIS_TXCSUM_INFO_MKUDPCS(l2hlen + 1589 1.22 nonaka l3hlen); 1590 1.22 nonaka } 1591 1.1 nonaka cp = hvn_rndis_pktinfo_append(pkt, HVN_RNDIS_PKT_LEN, 1592 1.1 nonaka NDIS_TXCSUM_INFO_SIZE, NDIS_PKTINFO_TYPE_CSUM); 1593 1.1 nonaka memcpy(cp, &csum, NDIS_TXCSUM_INFO_SIZE); 1594 1.1 nonaka } 1595 1.1 nonaka 1596 1.1 nonaka pktlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen; 1597 1.1 nonaka pkt->rm_pktinfooffset -= RNDIS_HEADER_OFFSET; 1598 1.1 nonaka 1599 1.22 nonaka /* 1600 1.22 nonaka * Fast path: Chimney sending. 1601 1.22 nonaka */ 1602 1.22 nonaka if (chim != NULL) { 1603 1.22 nonaka struct hvn_tx_desc *tgt_txd; 1604 1.22 nonaka 1605 1.22 nonaka tgt_txd = (txr->txr_agg_txd != NULL) ? txr->txr_agg_txd : txd; 1606 1.22 nonaka 1607 1.22 nonaka KASSERTMSG(pkt == chim, 1608 1.22 nonaka "RNDIS pkt not in chimney sending buffer"); 1609 1.22 nonaka KASSERTMSG(tgt_txd->txd_chim_index != HVN_NVS_CHIM_IDX_INVALID, 1610 1.22 nonaka "chimney sending buffer is not used"); 1611 1.22 nonaka 1612 1.22 nonaka tgt_txd->txd_chim_size += pkt->rm_len; 1613 1.22 nonaka m_copydata(m, 0, m->m_pkthdr.len, (uint8_t *)chim + pktlen); 1614 1.22 nonaka 1615 1.22 nonaka txr->txr_sendpkt = hvn_rndis_output_chim; 1616 1.22 nonaka goto done; 1617 1.22 nonaka } 1618 1.22 nonaka 1619 1.22 nonaka KASSERTMSG(txr->txr_agg_txd == NULL, "aggregating sglist txdesc"); 1620 1.22 nonaka KASSERTMSG(txd->txd_chim_index == HVN_NVS_CHIM_IDX_INVALID, 1621 1.22 nonaka "chimney buffer is used"); 1622 1.22 nonaka KASSERTMSG(pkt == txd->txd_req, "RNDIS pkt not in txdesc"); 1623 1.22 nonaka 1624 1.22 nonaka rv = bus_dmamap_load_mbuf(sc->sc_dmat, txd->txd_dmap, m, BUS_DMA_READ | 1625 1.22 nonaka BUS_DMA_NOWAIT); 1626 1.22 nonaka switch (rv) { 1627 1.22 nonaka case 0: 1628 1.22 nonaka break; 1629 1.22 nonaka case EFBIG: 1630 1.22 nonaka if (m_defrag(m, M_NOWAIT) != NULL) { 1631 1.22 nonaka txr->txr_evdefrag.ev_count++; 1632 1.22 nonaka if (bus_dmamap_load_mbuf(sc->sc_dmat, txd->txd_dmap, m, 1633 1.22 nonaka BUS_DMA_READ | BUS_DMA_NOWAIT) == 0) 1634 1.22 nonaka break; 1635 1.22 nonaka } 1636 1.22 nonaka /* FALLTHROUGH */ 1637 1.22 nonaka default: 1638 1.22 nonaka DPRINTF("%s: failed to load mbuf\n", device_xname(sc->sc_dev)); 1639 1.22 nonaka txr->txr_evdmafailed.ev_count++; 1640 1.22 nonaka return -1; 1641 1.22 nonaka } 1642 1.22 nonaka bus_dmamap_sync(sc->sc_dmat, txd->txd_dmap, 1643 1.22 nonaka 0, txd->txd_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE); 1644 1.22 nonaka SET(txd->txd_flags, HVN_TXD_FLAG_DMAMAP); 1645 1.22 nonaka 1646 1.1 nonaka /* Attach an RNDIS message to the first slot */ 1647 1.1 nonaka txd->txd_sgl[0].gpa_page = txd->txd_gpa.gpa_page; 1648 1.1 nonaka txd->txd_sgl[0].gpa_ofs = txd->txd_gpa.gpa_ofs; 1649 1.1 nonaka txd->txd_sgl[0].gpa_len = pktlen; 1650 1.1 nonaka txd->txd_nsge = txd->txd_dmap->dm_nsegs + 1; 1651 1.1 nonaka 1652 1.1 nonaka for (i = 0; i < txd->txd_dmap->dm_nsegs; i++) { 1653 1.1 nonaka seg = &txd->txd_dmap->dm_segs[i]; 1654 1.1 nonaka txd->txd_sgl[1 + i].gpa_page = atop(seg->ds_addr); 1655 1.1 nonaka txd->txd_sgl[1 + i].gpa_ofs = seg->ds_addr & PAGE_MASK; 1656 1.1 nonaka txd->txd_sgl[1 + i].gpa_len = seg->ds_len; 1657 1.1 nonaka } 1658 1.1 nonaka 1659 1.22 nonaka txd->txd_chim_index = HVN_NVS_CHIM_IDX_INVALID; 1660 1.22 nonaka txd->txd_chim_size = 0; 1661 1.22 nonaka txr->txr_sendpkt = hvn_rndis_output_sgl; 1662 1.22 nonaka done: 1663 1.22 nonaka txd->txd_buf = m; 1664 1.1 nonaka 1665 1.22 nonaka /* Update temporary stats for later use. */ 1666 1.22 nonaka txr->txr_stat_pkts++; 1667 1.22 nonaka txr->txr_stat_size += m->m_pkthdr.len; 1668 1.22 nonaka if (m->m_flags & M_MCAST) 1669 1.22 nonaka txr->txr_stat_mcasts++; 1670 1.1 nonaka 1671 1.1 nonaka return 0; 1672 1.1 nonaka } 1673 1.1 nonaka 1674 1.1 nonaka static void 1675 1.22 nonaka hvn_bpf_mtap(struct hvn_tx_ring *txr, struct mbuf *m, u_int direction) 1676 1.22 nonaka { 1677 1.22 nonaka struct hvn_softc *sc = txr->txr_softc; 1678 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 1679 1.22 nonaka struct ether_header *eh; 1680 1.22 nonaka struct ether_vlan_header evl; 1681 1.22 nonaka 1682 1.22 nonaka if (!vlan_has_tag(m)) { 1683 1.22 nonaka bpf_mtap(ifp, m, direction); 1684 1.22 nonaka return; 1685 1.22 nonaka } 1686 1.22 nonaka 1687 1.22 nonaka if (ifp->if_bpf == NULL) 1688 1.22 nonaka return; 1689 1.22 nonaka 1690 1.22 nonaka txr->txr_evvlantap.ev_count++; 1691 1.22 nonaka 1692 1.22 nonaka /* 1693 1.22 nonaka * Restore a VLAN tag for bpf. 1694 1.22 nonaka * 1695 1.22 nonaka * Do not modify contents of the original mbuf, 1696 1.22 nonaka * because Tx processing on the mbuf is still in progress. 1697 1.22 nonaka */ 1698 1.22 nonaka 1699 1.22 nonaka eh = mtod(m, struct ether_header *); 1700 1.30 joe memcpy(&evl, eh, ETHER_ADDR_LEN * 2); 1701 1.22 nonaka evl.evl_encap_proto = htons(ETHERTYPE_VLAN); 1702 1.22 nonaka evl.evl_tag = htons(vlan_get_tag(m)); 1703 1.22 nonaka evl.evl_proto = eh->ether_type; 1704 1.22 nonaka 1705 1.22 nonaka /* Do not tap ether header of the original mbuf. */ 1706 1.22 nonaka m_adj(m, sizeof(*eh)); 1707 1.22 nonaka 1708 1.22 nonaka bpf_mtap2(ifp->if_bpf, &evl, sizeof(evl), m, direction); 1709 1.22 nonaka 1710 1.22 nonaka /* Cannot restore ether header of the original mbuf, 1711 1.22 nonaka * but do not worry about it because just free it. */ 1712 1.22 nonaka } 1713 1.22 nonaka 1714 1.22 nonaka static int 1715 1.22 nonaka hvn_txpkt(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd) 1716 1.1 nonaka { 1717 1.22 nonaka struct hvn_softc *sc = txr->txr_softc; 1718 1.1 nonaka struct ifnet *ifp = SC2IFP(sc); 1719 1.22 nonaka const struct hvn_tx_desc *tmp_txd; 1720 1.22 nonaka int error; 1721 1.22 nonaka 1722 1.22 nonaka /* 1723 1.22 nonaka * Make sure that this txd and any aggregated txds are not 1724 1.22 nonaka * freed before bpf_mtap. 1725 1.22 nonaka */ 1726 1.22 nonaka hvn_txd_hold(txd); 1727 1.22 nonaka 1728 1.22 nonaka error = (*txr->txr_sendpkt)(txr, txd); 1729 1.22 nonaka if (error == 0) { 1730 1.22 nonaka hvn_bpf_mtap(txr, txd->txd_buf, BPF_D_OUT); 1731 1.22 nonaka STAILQ_FOREACH(tmp_txd, &txd->txd_agg_list, txd_agg_entry) 1732 1.22 nonaka hvn_bpf_mtap(txr, tmp_txd->txd_buf, BPF_D_OUT); 1733 1.22 nonaka 1734 1.22 nonaka if_statadd(ifp, if_opackets, txr->txr_stat_pkts); 1735 1.22 nonaka if_statadd(ifp, if_obytes, txr->txr_stat_size); 1736 1.22 nonaka if (txr->txr_stat_mcasts != 0) 1737 1.22 nonaka if_statadd(ifp, if_omcasts, txr->txr_stat_mcasts); 1738 1.22 nonaka txr->txr_evpkts.ev_count += txr->txr_stat_pkts; 1739 1.22 nonaka txr->txr_evsends.ev_count++; 1740 1.22 nonaka } 1741 1.22 nonaka 1742 1.22 nonaka hvn_txd_put(txr, txd); 1743 1.22 nonaka 1744 1.22 nonaka if (__predict_false(error)) { 1745 1.22 nonaka /* 1746 1.22 nonaka * Caller will perform further processing on the 1747 1.22 nonaka * associated mbuf, so don't free it in hvn_txd_put(); 1748 1.22 nonaka * only unload it from the DMA map in hvn_txd_put(), 1749 1.22 nonaka * if it was loaded. 1750 1.22 nonaka */ 1751 1.22 nonaka txd->txd_buf = NULL; 1752 1.22 nonaka hvn_txd_put(txr, txd); 1753 1.22 nonaka } 1754 1.22 nonaka 1755 1.22 nonaka /* Reset temporary stats, after this sending is done. */ 1756 1.22 nonaka txr->txr_stat_pkts = 0; 1757 1.22 nonaka txr->txr_stat_size = 0; 1758 1.22 nonaka txr->txr_stat_mcasts = 0; 1759 1.22 nonaka 1760 1.22 nonaka return error; 1761 1.22 nonaka } 1762 1.22 nonaka 1763 1.22 nonaka static void 1764 1.22 nonaka hvn_txeof(struct hvn_tx_ring *txr, uint64_t tid) 1765 1.22 nonaka { 1766 1.22 nonaka struct hvn_softc *sc = txr->txr_softc; 1767 1.22 nonaka struct hvn_tx_desc *txd; 1768 1.22 nonaka uint32_t id = tid >> 32; 1769 1.22 nonaka 1770 1.22 nonaka if ((tid & 0xffffffffU) != 0) 1771 1.22 nonaka return; 1772 1.22 nonaka 1773 1.22 nonaka id -= HVN_NVS_CHIM_SIG; 1774 1.22 nonaka if (id >= HVN_TX_DESC) { 1775 1.22 nonaka device_printf(sc->sc_dev, "tx packet index too large: %u", id); 1776 1.22 nonaka return; 1777 1.22 nonaka } 1778 1.22 nonaka 1779 1.22 nonaka txd = &txr->txr_desc[id]; 1780 1.22 nonaka 1781 1.22 nonaka if (txd->txd_buf == NULL) 1782 1.22 nonaka device_printf(sc->sc_dev, "no mbuf @%u\n", id); 1783 1.22 nonaka 1784 1.22 nonaka hvn_txd_put(txr, txd); 1785 1.22 nonaka } 1786 1.22 nonaka 1787 1.22 nonaka static int 1788 1.22 nonaka hvn_rx_ring_create(struct hvn_softc *sc, int ring_cnt) 1789 1.22 nonaka { 1790 1.22 nonaka struct hvn_rx_ring *rxr; 1791 1.22 nonaka int i; 1792 1.22 nonaka 1793 1.22 nonaka if (sc->sc_proto <= HVN_NVS_PROTO_VERSION_2) 1794 1.22 nonaka sc->sc_rx_size = 15 * 1024 * 1024; /* 15MB */ 1795 1.22 nonaka else 1796 1.22 nonaka sc->sc_rx_size = 16 * 1024 * 1024; /* 16MB */ 1797 1.22 nonaka sc->sc_rx_ring = hyperv_dma_alloc(sc->sc_dmat, &sc->sc_rx_dma, 1798 1.22 nonaka sc->sc_rx_size, PAGE_SIZE, PAGE_SIZE, sc->sc_rx_size / PAGE_SIZE); 1799 1.22 nonaka if (sc->sc_rx_ring == NULL) { 1800 1.22 nonaka DPRINTF("%s: failed to allocate Rx ring buffer\n", 1801 1.22 nonaka device_xname(sc->sc_dev)); 1802 1.22 nonaka return -1; 1803 1.22 nonaka } 1804 1.22 nonaka 1805 1.22 nonaka sc->sc_rxr = kmem_zalloc(sizeof(*rxr) * ring_cnt, KM_SLEEP); 1806 1.22 nonaka sc->sc_nrxr_inuse = sc->sc_nrxr = ring_cnt; 1807 1.22 nonaka 1808 1.22 nonaka for (i = 0; i < sc->sc_nrxr; i++) { 1809 1.22 nonaka rxr = &sc->sc_rxr[i]; 1810 1.22 nonaka rxr->rxr_softc = sc; 1811 1.22 nonaka if (i < sc->sc_ntxr) { 1812 1.22 nonaka rxr->rxr_txr = &sc->sc_txr[i]; 1813 1.22 nonaka rxr->rxr_txr->txr_rxr = rxr; 1814 1.22 nonaka } 1815 1.22 nonaka 1816 1.22 nonaka mutex_init(&rxr->rxr_lock, MUTEX_DEFAULT, IPL_NET); 1817 1.22 nonaka mutex_init(&rxr->rxr_onwork_lock, MUTEX_DEFAULT, IPL_NET); 1818 1.22 nonaka cv_init(&rxr->rxr_onwork_cv, "waitonwk"); 1819 1.22 nonaka 1820 1.22 nonaka snprintf(rxr->rxr_name, sizeof(rxr->rxr_name), 1821 1.22 nonaka "%s-rx%d", device_xname(sc->sc_dev), i); 1822 1.22 nonaka evcnt_attach_dynamic(&rxr->rxr_evpkts, EVCNT_TYPE_MISC, 1823 1.22 nonaka NULL, rxr->rxr_name, "packets received"); 1824 1.22 nonaka evcnt_attach_dynamic(&rxr->rxr_evcsum_ip, EVCNT_TYPE_MISC, 1825 1.22 nonaka NULL, rxr->rxr_name, "IP checksum"); 1826 1.22 nonaka evcnt_attach_dynamic(&rxr->rxr_evcsum_tcp, EVCNT_TYPE_MISC, 1827 1.22 nonaka NULL, rxr->rxr_name, "TCP checksum"); 1828 1.22 nonaka evcnt_attach_dynamic(&rxr->rxr_evcsum_udp, EVCNT_TYPE_MISC, 1829 1.22 nonaka NULL, rxr->rxr_name, "UDP checksum"); 1830 1.22 nonaka evcnt_attach_dynamic(&rxr->rxr_evvlanhwtagging, EVCNT_TYPE_MISC, 1831 1.22 nonaka NULL, rxr->rxr_name, "VLAN H/W tagging"); 1832 1.22 nonaka evcnt_attach_dynamic(&rxr->rxr_evintr, EVCNT_TYPE_INTR, 1833 1.22 nonaka NULL, rxr->rxr_name, "interrupt on ring"); 1834 1.22 nonaka evcnt_attach_dynamic(&rxr->rxr_evdefer, EVCNT_TYPE_MISC, 1835 1.22 nonaka NULL, rxr->rxr_name, "handled queue in workqueue"); 1836 1.22 nonaka evcnt_attach_dynamic(&rxr->rxr_evdeferreq, EVCNT_TYPE_MISC, 1837 1.22 nonaka NULL, rxr->rxr_name, "requested defer on ring"); 1838 1.22 nonaka evcnt_attach_dynamic(&rxr->rxr_evredeferreq, EVCNT_TYPE_MISC, 1839 1.22 nonaka NULL, rxr->rxr_name, "requested defer in workqueue"); 1840 1.22 nonaka 1841 1.22 nonaka rxr->rxr_nvsbuf = kmem_zalloc(HVN_NVS_BUFSIZE, KM_SLEEP); 1842 1.22 nonaka if (rxr->rxr_nvsbuf == NULL) { 1843 1.22 nonaka DPRINTF("%s: failed to allocate channel data buffer\n", 1844 1.22 nonaka device_xname(sc->sc_dev)); 1845 1.22 nonaka goto errout; 1846 1.22 nonaka } 1847 1.22 nonaka 1848 1.22 nonaka rxr->rxr_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, 1849 1.22 nonaka hvn_nvs_softintr, rxr); 1850 1.22 nonaka if (rxr->rxr_si == NULL) { 1851 1.22 nonaka DPRINTF("%s: failed to establish rx softint\n", 1852 1.22 nonaka device_xname(sc->sc_dev)); 1853 1.22 nonaka goto errout; 1854 1.22 nonaka } 1855 1.22 nonaka } 1856 1.22 nonaka 1857 1.22 nonaka return 0; 1858 1.22 nonaka 1859 1.22 nonaka errout: 1860 1.22 nonaka hvn_rx_ring_destroy(sc); 1861 1.22 nonaka return -1; 1862 1.22 nonaka } 1863 1.1 nonaka 1864 1.22 nonaka static int 1865 1.22 nonaka hvn_rx_ring_destroy(struct hvn_softc *sc) 1866 1.22 nonaka { 1867 1.22 nonaka struct hvn_rx_ring *rxr; 1868 1.22 nonaka int i; 1869 1.22 nonaka 1870 1.22 nonaka if (sc->sc_rxr != NULL) { 1871 1.22 nonaka for (i = 0; i < sc->sc_nrxr; i++) { 1872 1.22 nonaka rxr = &sc->sc_rxr[i]; 1873 1.22 nonaka 1874 1.22 nonaka if (rxr->rxr_si != NULL) { 1875 1.22 nonaka softint_disestablish(rxr->rxr_si); 1876 1.22 nonaka rxr->rxr_si = NULL; 1877 1.22 nonaka } 1878 1.22 nonaka 1879 1.22 nonaka if (rxr->rxr_nvsbuf != NULL) { 1880 1.22 nonaka kmem_free(rxr->rxr_nvsbuf, HVN_NVS_BUFSIZE); 1881 1.22 nonaka rxr->rxr_nvsbuf = NULL; 1882 1.22 nonaka } 1883 1.22 nonaka 1884 1.22 nonaka evcnt_detach(&rxr->rxr_evpkts); 1885 1.22 nonaka evcnt_detach(&rxr->rxr_evcsum_ip); 1886 1.22 nonaka evcnt_detach(&rxr->rxr_evcsum_tcp); 1887 1.22 nonaka evcnt_detach(&rxr->rxr_evcsum_udp); 1888 1.22 nonaka evcnt_detach(&rxr->rxr_evvlanhwtagging); 1889 1.22 nonaka evcnt_detach(&rxr->rxr_evintr); 1890 1.22 nonaka evcnt_detach(&rxr->rxr_evdefer); 1891 1.22 nonaka evcnt_detach(&rxr->rxr_evdeferreq); 1892 1.22 nonaka evcnt_detach(&rxr->rxr_evredeferreq); 1893 1.22 nonaka 1894 1.22 nonaka cv_destroy(&rxr->rxr_onwork_cv); 1895 1.22 nonaka mutex_destroy(&rxr->rxr_onwork_lock); 1896 1.22 nonaka mutex_destroy(&rxr->rxr_lock); 1897 1.22 nonaka } 1898 1.22 nonaka kmem_free(sc->sc_rxr, sizeof(*rxr) * sc->sc_nrxr); 1899 1.22 nonaka sc->sc_rxr = NULL; 1900 1.22 nonaka sc->sc_nrxr = 0; 1901 1.22 nonaka } 1902 1.22 nonaka if (sc->sc_rx_ring != NULL) { 1903 1.22 nonaka hyperv_dma_free(sc->sc_dmat, &sc->sc_rx_dma); 1904 1.22 nonaka sc->sc_rx_ring = NULL; 1905 1.22 nonaka } 1906 1.22 nonaka 1907 1.22 nonaka return 0; 1908 1.22 nonaka } 1909 1.22 nonaka 1910 1.22 nonaka static void 1911 1.22 nonaka hvn_fixup_rx_data(struct hvn_softc *sc) 1912 1.22 nonaka { 1913 1.22 nonaka struct hvn_rx_ring *rxr; 1914 1.22 nonaka int i; 1915 1.22 nonaka 1916 1.22 nonaka if (sc->sc_caps & HVN_CAPS_UDPHASH) { 1917 1.22 nonaka for (i = 0; i < sc->sc_nrxr; i++) { 1918 1.22 nonaka rxr = &sc->sc_rxr[i]; 1919 1.22 nonaka rxr->rxr_flags |= HVN_RXR_FLAG_UDP_HASH; 1920 1.22 nonaka } 1921 1.22 nonaka } 1922 1.22 nonaka } 1923 1.22 nonaka 1924 1.22 nonaka static int 1925 1.22 nonaka hvn_tx_ring_create(struct hvn_softc *sc, int ring_cnt) 1926 1.22 nonaka { 1927 1.22 nonaka struct hvn_tx_ring *txr; 1928 1.22 nonaka struct hvn_tx_desc *txd; 1929 1.22 nonaka bus_dma_segment_t *seg; 1930 1.22 nonaka size_t msgsize; 1931 1.22 nonaka int i, j; 1932 1.22 nonaka paddr_t pa; 1933 1.22 nonaka 1934 1.22 nonaka /* 1935 1.22 nonaka * Create TXBUF for chimney sending. 1936 1.22 nonaka * 1937 1.22 nonaka * NOTE: It is shared by all channels. 1938 1.22 nonaka */ 1939 1.22 nonaka sc->sc_chim = hyperv_dma_alloc(sc->sc_dmat, &sc->sc_chim_dma, 1940 1.22 nonaka HVN_CHIM_SIZE, PAGE_SIZE, 0, 1); 1941 1.22 nonaka if (sc->sc_chim == NULL) { 1942 1.22 nonaka DPRINTF("%s: failed to allocate chimney sending memory", 1943 1.22 nonaka device_xname(sc->sc_dev)); 1944 1.22 nonaka goto errout; 1945 1.22 nonaka } 1946 1.22 nonaka 1947 1.22 nonaka sc->sc_txr = kmem_zalloc(sizeof(*txr) * ring_cnt, KM_SLEEP); 1948 1.22 nonaka sc->sc_ntxr_inuse = sc->sc_ntxr = ring_cnt; 1949 1.22 nonaka 1950 1.22 nonaka msgsize = roundup(HVN_RNDIS_PKT_LEN, 128); 1951 1.22 nonaka 1952 1.22 nonaka for (j = 0; j < ring_cnt; j++) { 1953 1.22 nonaka txr = &sc->sc_txr[j]; 1954 1.22 nonaka txr->txr_softc = sc; 1955 1.22 nonaka txr->txr_id = j; 1956 1.22 nonaka 1957 1.22 nonaka mutex_init(&txr->txr_lock, MUTEX_DEFAULT, IPL_NET); 1958 1.22 nonaka txr->txr_interq = pcq_create(HVN_TX_DESC, KM_SLEEP); 1959 1.22 nonaka 1960 1.22 nonaka snprintf(txr->txr_name, sizeof(txr->txr_name), 1961 1.22 nonaka "%s-tx%d", device_xname(sc->sc_dev), j); 1962 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evpkts, EVCNT_TYPE_MISC, 1963 1.22 nonaka NULL, txr->txr_name, "packets transmit"); 1964 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evsends, EVCNT_TYPE_MISC, 1965 1.22 nonaka NULL, txr->txr_name, "sends"); 1966 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evnodesc, EVCNT_TYPE_MISC, 1967 1.22 nonaka NULL, txr->txr_name, "descriptor shortage"); 1968 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evdmafailed, EVCNT_TYPE_MISC, 1969 1.22 nonaka NULL, txr->txr_name, "DMA failure"); 1970 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evdefrag, EVCNT_TYPE_MISC, 1971 1.22 nonaka NULL, txr->txr_name, "mbuf defraged"); 1972 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evpcqdrop, EVCNT_TYPE_MISC, 1973 1.22 nonaka NULL, txr->txr_name, "dropped in pcq"); 1974 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evtransmitdefer, EVCNT_TYPE_MISC, 1975 1.22 nonaka NULL, txr->txr_name, "deferred transmit"); 1976 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evflushfailed, EVCNT_TYPE_MISC, 1977 1.22 nonaka NULL, txr->txr_name, "aggregation flush failure"); 1978 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evchimneytried, EVCNT_TYPE_MISC, 1979 1.22 nonaka NULL, txr->txr_name, "chimney send tried"); 1980 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evchimney, EVCNT_TYPE_MISC, 1981 1.22 nonaka NULL, txr->txr_name, "chimney send"); 1982 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evvlanfixup, EVCNT_TYPE_MISC, 1983 1.22 nonaka NULL, txr->txr_name, "VLAN fixup"); 1984 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evvlanhwtagging, EVCNT_TYPE_MISC, 1985 1.22 nonaka NULL, txr->txr_name, "VLAN H/W tagging"); 1986 1.22 nonaka evcnt_attach_dynamic(&txr->txr_evvlantap, EVCNT_TYPE_MISC, 1987 1.22 nonaka NULL, txr->txr_name, "VLAN bpf_mtap fixup"); 1988 1.22 nonaka 1989 1.22 nonaka txr->txr_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, 1990 1.22 nonaka hvn_deferred_transmit, txr); 1991 1.22 nonaka if (txr->txr_si == NULL) { 1992 1.22 nonaka aprint_error_dev(sc->sc_dev, 1993 1.22 nonaka "failed to establish softint for tx ring\n"); 1994 1.22 nonaka goto errout; 1995 1.22 nonaka } 1996 1.22 nonaka 1997 1.22 nonaka /* Allocate memory to store RNDIS messages */ 1998 1.22 nonaka txr->txr_msgs = hyperv_dma_alloc(sc->sc_dmat, &txr->txr_dma, 1999 1.22 nonaka msgsize * HVN_TX_DESC, PAGE_SIZE, 0, 1); 2000 1.22 nonaka if (txr->txr_msgs == NULL) { 2001 1.22 nonaka DPRINTF("%s: failed to allocate memory for RDNIS " 2002 1.22 nonaka "messages\n", device_xname(sc->sc_dev)); 2003 1.22 nonaka goto errout; 2004 1.22 nonaka } 2005 1.22 nonaka 2006 1.22 nonaka TAILQ_INIT(&txr->txr_list); 2007 1.22 nonaka for (i = 0; i < HVN_TX_DESC; i++) { 2008 1.22 nonaka txd = &txr->txr_desc[i]; 2009 1.22 nonaka txd->txd_chim_index = HVN_NVS_CHIM_IDX_INVALID; 2010 1.22 nonaka txd->txd_chim_size = 0; 2011 1.22 nonaka STAILQ_INIT(&txd->txd_agg_list); 2012 1.22 nonaka if (bus_dmamap_create(sc->sc_dmat, HVN_TX_PKT_SIZE, 2013 1.22 nonaka HVN_TX_FRAGS, HVN_TX_FRAG_SIZE, PAGE_SIZE, 2014 1.22 nonaka BUS_DMA_WAITOK, &txd->txd_dmap)) { 2015 1.22 nonaka DPRINTF("%s: failed to create map for TX " 2016 1.22 nonaka "descriptors\n", device_xname(sc->sc_dev)); 2017 1.22 nonaka goto errout; 2018 1.22 nonaka } 2019 1.22 nonaka seg = &txr->txr_dma.map->dm_segs[0]; 2020 1.22 nonaka pa = seg->ds_addr + (msgsize * i); 2021 1.22 nonaka txd->txd_gpa.gpa_page = atop(pa); 2022 1.22 nonaka txd->txd_gpa.gpa_ofs = pa & PAGE_MASK; 2023 1.22 nonaka txd->txd_gpa.gpa_len = msgsize; 2024 1.22 nonaka txd->txd_req = (void *)(txr->txr_msgs + (msgsize * i)); 2025 1.22 nonaka txd->txd_id = i + HVN_NVS_CHIM_SIG; 2026 1.22 nonaka TAILQ_INSERT_TAIL(&txr->txr_list, txd, txd_entry); 2027 1.22 nonaka } 2028 1.22 nonaka txr->txr_avail = HVN_TX_DESC; 2029 1.22 nonaka } 2030 1.22 nonaka 2031 1.22 nonaka return 0; 2032 1.22 nonaka 2033 1.22 nonaka errout: 2034 1.22 nonaka hvn_tx_ring_destroy(sc); 2035 1.22 nonaka return -1; 2036 1.1 nonaka } 2037 1.1 nonaka 2038 1.1 nonaka static void 2039 1.22 nonaka hvn_tx_ring_destroy(struct hvn_softc *sc) 2040 1.1 nonaka { 2041 1.22 nonaka struct hvn_tx_ring *txr; 2042 1.1 nonaka struct hvn_tx_desc *txd; 2043 1.22 nonaka int i, j; 2044 1.22 nonaka 2045 1.22 nonaka if (sc->sc_txr != NULL) { 2046 1.22 nonaka for (j = 0; j < sc->sc_ntxr; j++) { 2047 1.22 nonaka txr = &sc->sc_txr[j]; 2048 1.22 nonaka 2049 1.22 nonaka mutex_enter(&txr->txr_lock); 2050 1.22 nonaka for (i = 0; i < HVN_TX_DESC; i++) { 2051 1.22 nonaka txd = &txr->txr_desc[i]; 2052 1.22 nonaka hvn_txd_gc(txr, txd); 2053 1.22 nonaka } 2054 1.22 nonaka mutex_exit(&txr->txr_lock); 2055 1.22 nonaka for (i = 0; i < HVN_TX_DESC; i++) { 2056 1.22 nonaka txd = &txr->txr_desc[i]; 2057 1.22 nonaka if (txd->txd_dmap != NULL) { 2058 1.22 nonaka bus_dmamap_destroy(sc->sc_dmat, 2059 1.22 nonaka txd->txd_dmap); 2060 1.22 nonaka txd->txd_dmap = NULL; 2061 1.22 nonaka } 2062 1.22 nonaka } 2063 1.22 nonaka if (txr->txr_msgs != NULL) { 2064 1.22 nonaka hyperv_dma_free(sc->sc_dmat, &txr->txr_dma); 2065 1.22 nonaka txr->txr_msgs = NULL; 2066 1.22 nonaka } 2067 1.22 nonaka if (txr->txr_si != NULL) { 2068 1.22 nonaka softint_disestablish(txr->txr_si); 2069 1.22 nonaka txr->txr_si = NULL; 2070 1.22 nonaka } 2071 1.22 nonaka if (txr->txr_interq != NULL) { 2072 1.22 nonaka hvn_tx_ring_qflush(sc, txr); 2073 1.22 nonaka pcq_destroy(txr->txr_interq); 2074 1.22 nonaka txr->txr_interq = NULL; 2075 1.22 nonaka } 2076 1.22 nonaka 2077 1.22 nonaka evcnt_detach(&txr->txr_evpkts); 2078 1.22 nonaka evcnt_detach(&txr->txr_evsends); 2079 1.22 nonaka evcnt_detach(&txr->txr_evnodesc); 2080 1.22 nonaka evcnt_detach(&txr->txr_evdmafailed); 2081 1.22 nonaka evcnt_detach(&txr->txr_evdefrag); 2082 1.22 nonaka evcnt_detach(&txr->txr_evpcqdrop); 2083 1.22 nonaka evcnt_detach(&txr->txr_evtransmitdefer); 2084 1.22 nonaka evcnt_detach(&txr->txr_evflushfailed); 2085 1.22 nonaka evcnt_detach(&txr->txr_evchimneytried); 2086 1.22 nonaka evcnt_detach(&txr->txr_evchimney); 2087 1.22 nonaka evcnt_detach(&txr->txr_evvlanfixup); 2088 1.22 nonaka evcnt_detach(&txr->txr_evvlanhwtagging); 2089 1.22 nonaka evcnt_detach(&txr->txr_evvlantap); 2090 1.22 nonaka 2091 1.22 nonaka mutex_destroy(&txr->txr_lock); 2092 1.22 nonaka } 2093 1.22 nonaka 2094 1.22 nonaka kmem_free(sc->sc_txr, sizeof(*txr) * sc->sc_ntxr); 2095 1.22 nonaka sc->sc_txr = NULL; 2096 1.22 nonaka } 2097 1.22 nonaka 2098 1.22 nonaka if (sc->sc_chim != NULL) { 2099 1.22 nonaka hyperv_dma_free(sc->sc_dmat, &sc->sc_chim_dma); 2100 1.22 nonaka sc->sc_chim = NULL; 2101 1.22 nonaka } 2102 1.22 nonaka } 2103 1.22 nonaka 2104 1.22 nonaka static void 2105 1.22 nonaka hvn_set_chim_size(struct hvn_softc *sc, int chim_size) 2106 1.22 nonaka { 2107 1.22 nonaka struct hvn_tx_ring *txr; 2108 1.22 nonaka int i; 2109 1.22 nonaka 2110 1.22 nonaka for (i = 0; i < sc->sc_ntxr_inuse; i++) { 2111 1.22 nonaka txr = &sc->sc_txr[i]; 2112 1.22 nonaka txr->txr_chim_size = chim_size; 2113 1.22 nonaka } 2114 1.22 nonaka } 2115 1.22 nonaka 2116 1.22 nonaka #if LONG_BIT == 64 2117 1.22 nonaka #define ffsl(v) ffs64(v) 2118 1.22 nonaka #elif LONG_BIT == 32 2119 1.22 nonaka #define ffsl(v) ffs32(v) 2120 1.22 nonaka #else 2121 1.22 nonaka #error unsupport LONG_BIT 2122 1.22 nonaka #endif /* LONG_BIT */ 2123 1.22 nonaka 2124 1.22 nonaka static uint32_t 2125 1.22 nonaka hvn_chim_alloc(struct hvn_softc *sc) 2126 1.22 nonaka { 2127 1.22 nonaka uint32_t chim_idx = HVN_NVS_CHIM_IDX_INVALID; 2128 1.22 nonaka int i, idx; 2129 1.22 nonaka 2130 1.22 nonaka mutex_spin_enter(&sc->sc_chim_bmap_lock); 2131 1.22 nonaka for (i = 0; i < sc->sc_chim_bmap_cnt; i++) { 2132 1.22 nonaka idx = ffsl(~sc->sc_chim_bmap[i]); 2133 1.22 nonaka if (idx == 0) 2134 1.22 nonaka continue; 2135 1.22 nonaka 2136 1.22 nonaka --idx; /* ffsl is 1-based */ 2137 1.22 nonaka SET(sc->sc_chim_bmap[i], __BIT(idx)); 2138 1.22 nonaka 2139 1.22 nonaka chim_idx = i * LONG_BIT + idx; 2140 1.22 nonaka break; 2141 1.22 nonaka } 2142 1.22 nonaka mutex_spin_exit(&sc->sc_chim_bmap_lock); 2143 1.22 nonaka 2144 1.22 nonaka return chim_idx; 2145 1.22 nonaka } 2146 1.22 nonaka 2147 1.22 nonaka static void 2148 1.22 nonaka hvn_chim_free(struct hvn_softc *sc, uint32_t chim_idx) 2149 1.22 nonaka { 2150 1.22 nonaka u_long mask; 2151 1.22 nonaka uint32_t idx; 2152 1.22 nonaka 2153 1.22 nonaka idx = chim_idx / LONG_BIT; 2154 1.22 nonaka mask = __BIT(chim_idx % LONG_BIT); 2155 1.22 nonaka 2156 1.22 nonaka mutex_spin_enter(&sc->sc_chim_bmap_lock); 2157 1.22 nonaka CLR(sc->sc_chim_bmap[idx], mask); 2158 1.22 nonaka mutex_spin_exit(&sc->sc_chim_bmap_lock); 2159 1.22 nonaka } 2160 1.22 nonaka 2161 1.22 nonaka static void 2162 1.22 nonaka hvn_fixup_tx_data(struct hvn_softc *sc) 2163 1.22 nonaka { 2164 1.22 nonaka struct hvn_tx_ring *txr; 2165 1.22 nonaka uint64_t caps_assist; 2166 1.22 nonaka int csum_assist; 2167 1.22 nonaka int i; 2168 1.22 nonaka 2169 1.22 nonaka hvn_set_chim_size(sc, sc->sc_chim_szmax); 2170 1.22 nonaka if (hvn_tx_chimney_size > 0 && hvn_tx_chimney_size < sc->sc_chim_szmax) 2171 1.22 nonaka hvn_set_chim_size(sc, hvn_tx_chimney_size); 2172 1.22 nonaka 2173 1.22 nonaka caps_assist = 0; 2174 1.22 nonaka csum_assist = 0; 2175 1.22 nonaka if (sc->sc_caps & HVN_CAPS_IPCS) { 2176 1.22 nonaka caps_assist |= IFCAP_CSUM_IPv4_Tx; 2177 1.22 nonaka caps_assist |= IFCAP_CSUM_IPv4_Rx; 2178 1.22 nonaka csum_assist |= M_CSUM_IPv4; 2179 1.22 nonaka } 2180 1.22 nonaka if (sc->sc_caps & HVN_CAPS_TCP4CS) { 2181 1.22 nonaka caps_assist |= IFCAP_CSUM_TCPv4_Tx; 2182 1.22 nonaka caps_assist |= IFCAP_CSUM_TCPv4_Rx; 2183 1.22 nonaka csum_assist |= M_CSUM_TCPv4; 2184 1.22 nonaka } 2185 1.22 nonaka if (sc->sc_caps & HVN_CAPS_TCP6CS) { 2186 1.22 nonaka caps_assist |= IFCAP_CSUM_TCPv6_Tx; 2187 1.22 nonaka csum_assist |= M_CSUM_TCPv6; 2188 1.22 nonaka } 2189 1.22 nonaka if (sc->sc_caps & HVN_CAPS_UDP4CS) { 2190 1.22 nonaka caps_assist |= IFCAP_CSUM_UDPv4_Tx; 2191 1.22 nonaka caps_assist |= IFCAP_CSUM_UDPv4_Rx; 2192 1.22 nonaka csum_assist |= M_CSUM_UDPv4; 2193 1.22 nonaka } 2194 1.22 nonaka if (sc->sc_caps & HVN_CAPS_UDP6CS) { 2195 1.22 nonaka caps_assist |= IFCAP_CSUM_UDPv6_Tx; 2196 1.22 nonaka csum_assist |= M_CSUM_UDPv6; 2197 1.22 nonaka } 2198 1.22 nonaka for (i = 0; i < sc->sc_ntxr; i++) { 2199 1.22 nonaka txr = &sc->sc_txr[i]; 2200 1.22 nonaka txr->txr_caps_assist = caps_assist; 2201 1.22 nonaka txr->txr_csum_assist = csum_assist; 2202 1.22 nonaka } 2203 1.22 nonaka 2204 1.22 nonaka if (sc->sc_caps & HVN_CAPS_UDPHASH) { 2205 1.22 nonaka for (i = 0; i < sc->sc_ntxr; i++) { 2206 1.22 nonaka txr = &sc->sc_txr[i]; 2207 1.22 nonaka txr->txr_flags |= HVN_TXR_FLAG_UDP_HASH; 2208 1.22 nonaka } 2209 1.22 nonaka } 2210 1.22 nonaka } 2211 1.22 nonaka 2212 1.22 nonaka static int 2213 1.22 nonaka hvn_txd_peek(struct hvn_tx_ring *txr) 2214 1.22 nonaka { 2215 1.22 nonaka 2216 1.22 nonaka KASSERT(mutex_owned(&txr->txr_lock)); 2217 1.22 nonaka 2218 1.22 nonaka return txr->txr_avail; 2219 1.22 nonaka } 2220 1.22 nonaka 2221 1.22 nonaka static struct hvn_tx_desc * 2222 1.22 nonaka hvn_txd_get(struct hvn_tx_ring *txr) 2223 1.22 nonaka { 2224 1.22 nonaka struct hvn_tx_desc *txd; 2225 1.22 nonaka 2226 1.22 nonaka KASSERT(mutex_owned(&txr->txr_lock)); 2227 1.22 nonaka 2228 1.22 nonaka txd = TAILQ_FIRST(&txr->txr_list); 2229 1.22 nonaka KASSERT(txd != NULL); 2230 1.22 nonaka TAILQ_REMOVE(&txr->txr_list, txd, txd_entry); 2231 1.22 nonaka txr->txr_avail--; 2232 1.22 nonaka 2233 1.22 nonaka txd->txd_refs = 1; 2234 1.22 nonaka 2235 1.22 nonaka return txd; 2236 1.22 nonaka } 2237 1.22 nonaka 2238 1.22 nonaka static void 2239 1.22 nonaka hvn_txd_put(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd) 2240 1.22 nonaka { 2241 1.22 nonaka struct hvn_softc *sc = txr->txr_softc; 2242 1.22 nonaka struct hvn_tx_desc *tmp_txd; 2243 1.22 nonaka 2244 1.22 nonaka KASSERT(mutex_owned(&txr->txr_lock)); 2245 1.22 nonaka KASSERTMSG(!ISSET(txd->txd_flags, HVN_TXD_FLAG_ONAGG), 2246 1.22 nonaka "put an onagg txd %#x", txd->txd_flags); 2247 1.22 nonaka 2248 1.22 nonaka KASSERTMSG(txd->txd_refs > 0, "invalid txd refs %d", txd->txd_refs); 2249 1.22 nonaka if (atomic_dec_uint_nv(&txd->txd_refs) != 0) 2250 1.22 nonaka return; 2251 1.22 nonaka 2252 1.22 nonaka if (!STAILQ_EMPTY(&txd->txd_agg_list)) { 2253 1.22 nonaka while ((tmp_txd = STAILQ_FIRST(&txd->txd_agg_list)) != NULL) { 2254 1.22 nonaka KASSERTMSG(STAILQ_EMPTY(&tmp_txd->txd_agg_list), 2255 1.22 nonaka "resursive aggregation on aggregated txdesc"); 2256 1.22 nonaka KASSERTMSG( 2257 1.22 nonaka ISSET(tmp_txd->txd_flags, HVN_TXD_FLAG_ONAGG), 2258 1.22 nonaka "not aggregated txdesc"); 2259 1.22 nonaka KASSERTMSG( 2260 1.22 nonaka tmp_txd->txd_chim_index == HVN_NVS_CHIM_IDX_INVALID, 2261 1.22 nonaka "aggregated txdesc consumes chimney sending " 2262 1.22 nonaka "buffer: idx %u", tmp_txd->txd_chim_index); 2263 1.22 nonaka KASSERTMSG(tmp_txd->txd_chim_size == 0, 2264 1.22 nonaka "aggregated txdesc has non-zero chimney sending " 2265 1.22 nonaka "size: sz %u", tmp_txd->txd_chim_size); 2266 1.22 nonaka 2267 1.22 nonaka STAILQ_REMOVE_HEAD(&txd->txd_agg_list, txd_agg_entry); 2268 1.22 nonaka CLR(tmp_txd->txd_flags, HVN_TXD_FLAG_ONAGG); 2269 1.22 nonaka hvn_txd_put(txr, tmp_txd); 2270 1.22 nonaka } 2271 1.22 nonaka } 2272 1.22 nonaka 2273 1.22 nonaka if (txd->txd_chim_index != HVN_NVS_CHIM_IDX_INVALID) { 2274 1.22 nonaka KASSERTMSG(!ISSET(txd->txd_flags, HVN_TXD_FLAG_DMAMAP), 2275 1.22 nonaka "chim txd uses dmamap"); 2276 1.22 nonaka hvn_chim_free(sc, txd->txd_chim_index); 2277 1.22 nonaka txd->txd_chim_index = HVN_NVS_CHIM_IDX_INVALID; 2278 1.22 nonaka txd->txd_chim_size = 0; 2279 1.22 nonaka } else if (ISSET(txd->txd_flags, HVN_TXD_FLAG_DMAMAP)) { 2280 1.22 nonaka bus_dmamap_sync(sc->sc_dmat, txd->txd_dmap, 2281 1.22 nonaka 0, txd->txd_dmap->dm_mapsize, 2282 1.22 nonaka BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 2283 1.22 nonaka bus_dmamap_unload(sc->sc_dmat, txd->txd_dmap); 2284 1.22 nonaka CLR(txd->txd_flags, HVN_TXD_FLAG_DMAMAP); 2285 1.22 nonaka } 2286 1.22 nonaka 2287 1.28 rin m_freem(txd->txd_buf); 2288 1.28 rin txd->txd_buf = NULL; 2289 1.22 nonaka 2290 1.22 nonaka TAILQ_INSERT_TAIL(&txr->txr_list, txd, txd_entry); 2291 1.22 nonaka txr->txr_avail++; 2292 1.22 nonaka txr->txr_oactive = 0; 2293 1.22 nonaka } 2294 1.22 nonaka 2295 1.22 nonaka static void 2296 1.22 nonaka hvn_txd_gc(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd) 2297 1.22 nonaka { 2298 1.22 nonaka 2299 1.22 nonaka KASSERTMSG(txd->txd_refs == 0 || txd->txd_refs == 1, 2300 1.22 nonaka "invalid txd refs %d", txd->txd_refs); 2301 1.22 nonaka 2302 1.22 nonaka /* Aggregated txds will be freed by their aggregating txd. */ 2303 1.22 nonaka if (txd->txd_refs > 0 && !ISSET(txd->txd_flags, HVN_TXD_FLAG_ONAGG)) 2304 1.22 nonaka hvn_txd_put(txr, txd); 2305 1.22 nonaka } 2306 1.22 nonaka 2307 1.22 nonaka static void 2308 1.22 nonaka hvn_txd_hold(struct hvn_tx_desc *txd) 2309 1.22 nonaka { 2310 1.22 nonaka 2311 1.22 nonaka /* 0->1 transition will never work */ 2312 1.22 nonaka KASSERTMSG(txd->txd_refs > 0, "invalid txd refs %d", txd->txd_refs); 2313 1.22 nonaka 2314 1.22 nonaka atomic_inc_uint(&txd->txd_refs); 2315 1.22 nonaka } 2316 1.22 nonaka 2317 1.22 nonaka static void 2318 1.22 nonaka hvn_txd_agg(struct hvn_tx_desc *agg_txd, struct hvn_tx_desc *txd) 2319 1.22 nonaka { 2320 1.22 nonaka 2321 1.22 nonaka KASSERTMSG(!ISSET(agg_txd->txd_flags, HVN_TXD_FLAG_ONAGG), 2322 1.22 nonaka "recursive aggregation on aggregating txdesc"); 2323 1.22 nonaka KASSERTMSG(!ISSET(txd->txd_flags, HVN_TXD_FLAG_ONAGG), 2324 1.22 nonaka "already aggregated"); 2325 1.22 nonaka KASSERTMSG(STAILQ_EMPTY(&txd->txd_agg_list), 2326 1.22 nonaka "recursive aggregation on to-be-aggregated txdesc"); 2327 1.22 nonaka 2328 1.22 nonaka SET(txd->txd_flags, HVN_TXD_FLAG_ONAGG); 2329 1.22 nonaka STAILQ_INSERT_TAIL(&agg_txd->txd_agg_list, txd, txd_agg_entry); 2330 1.22 nonaka } 2331 1.22 nonaka 2332 1.22 nonaka static int 2333 1.22 nonaka hvn_tx_ring_pending(struct hvn_tx_ring *txr) 2334 1.22 nonaka { 2335 1.22 nonaka int pending = 0; 2336 1.22 nonaka 2337 1.22 nonaka mutex_enter(&txr->txr_lock); 2338 1.22 nonaka if (hvn_txd_peek(txr) != HVN_TX_DESC) 2339 1.22 nonaka pending = 1; 2340 1.22 nonaka mutex_exit(&txr->txr_lock); 2341 1.22 nonaka 2342 1.22 nonaka return pending; 2343 1.22 nonaka } 2344 1.22 nonaka 2345 1.22 nonaka static void 2346 1.22 nonaka hvn_tx_ring_qflush(struct hvn_softc *sc, struct hvn_tx_ring *txr) 2347 1.22 nonaka { 2348 1.1 nonaka struct mbuf *m; 2349 1.1 nonaka 2350 1.22 nonaka while ((m = pcq_get(txr->txr_interq)) != NULL) 2351 1.22 nonaka m_freem(m); 2352 1.22 nonaka } 2353 1.22 nonaka 2354 1.22 nonaka static int 2355 1.22 nonaka hvn_get_lladdr(struct hvn_softc *sc, uint8_t *enaddr) 2356 1.22 nonaka { 2357 1.22 nonaka size_t addrlen = ETHER_ADDR_LEN; 2358 1.22 nonaka int rv; 2359 1.22 nonaka 2360 1.22 nonaka rv = hvn_rndis_query(sc, OID_802_3_PERMANENT_ADDRESS, enaddr, &addrlen); 2361 1.22 nonaka if (rv == 0 && addrlen != ETHER_ADDR_LEN) 2362 1.22 nonaka rv = -1; 2363 1.22 nonaka return rv; 2364 1.22 nonaka } 2365 1.22 nonaka 2366 1.22 nonaka static void 2367 1.22 nonaka hvn_update_link_status(struct hvn_softc *sc) 2368 1.22 nonaka { 2369 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 2370 1.22 nonaka uint32_t state, old_link_state; 2371 1.22 nonaka size_t len = sizeof(state); 2372 1.22 nonaka int rv; 2373 1.22 nonaka 2374 1.22 nonaka rv = hvn_rndis_query(sc, OID_GEN_MEDIA_CONNECT_STATUS, &state, &len); 2375 1.22 nonaka if (rv != 0 || len != sizeof(state)) 2376 1.22 nonaka return; 2377 1.22 nonaka 2378 1.22 nonaka old_link_state = sc->sc_link_state; 2379 1.22 nonaka sc->sc_link_state = (state == NDIS_MEDIA_STATE_CONNECTED) ? 2380 1.22 nonaka LINK_STATE_UP : LINK_STATE_DOWN; 2381 1.22 nonaka if (old_link_state != sc->sc_link_state) { 2382 1.22 nonaka if_link_state_change(ifp, sc->sc_link_state); 2383 1.22 nonaka } 2384 1.22 nonaka } 2385 1.22 nonaka 2386 1.22 nonaka static int 2387 1.22 nonaka hvn_get_mtu(struct hvn_softc *sc, uint32_t *mtu) 2388 1.22 nonaka { 2389 1.22 nonaka size_t mtusz = sizeof(*mtu); 2390 1.22 nonaka int rv; 2391 1.22 nonaka 2392 1.22 nonaka rv = hvn_rndis_query(sc, OID_GEN_MAXIMUM_FRAME_SIZE, mtu, &mtusz); 2393 1.22 nonaka if (rv == 0 && mtusz != sizeof(*mtu)) 2394 1.22 nonaka rv = -1; 2395 1.22 nonaka return rv; 2396 1.22 nonaka } 2397 1.22 nonaka 2398 1.22 nonaka static int 2399 1.22 nonaka hvn_channel_attach(struct hvn_softc *sc, struct vmbus_channel *chan) 2400 1.22 nonaka { 2401 1.22 nonaka struct hvn_rx_ring *rxr; 2402 1.22 nonaka struct hvn_tx_ring *txr; 2403 1.22 nonaka int idx; 2404 1.22 nonaka 2405 1.22 nonaka idx = chan->ch_subidx; 2406 1.22 nonaka if (idx < 0 || idx >= sc->sc_nrxr_inuse) { 2407 1.22 nonaka DPRINTF("%s: invalid sub-channel %u\n", 2408 1.22 nonaka device_xname(sc->sc_dev), idx); 2409 1.22 nonaka return -1; 2410 1.22 nonaka } 2411 1.22 nonaka 2412 1.22 nonaka rxr = &sc->sc_rxr[idx]; 2413 1.22 nonaka rxr->rxr_chan = chan; 2414 1.22 nonaka 2415 1.22 nonaka if (idx < sc->sc_ntxr_inuse) { 2416 1.22 nonaka txr = &sc->sc_txr[idx]; 2417 1.22 nonaka txr->txr_chan = chan; 2418 1.22 nonaka } 2419 1.22 nonaka 2420 1.22 nonaka /* Bind this channel to a proper CPU. */ 2421 1.22 nonaka vmbus_channel_cpu_set(chan, HVN_RING_IDX2CPU(sc, idx)); 2422 1.22 nonaka 2423 1.22 nonaka chan->ch_flags &= ~CHF_BATCHED; 2424 1.22 nonaka 2425 1.22 nonaka /* Associate our interrupt handler with the channel */ 2426 1.22 nonaka if (vmbus_channel_open(chan, 2427 1.22 nonaka HVN_RING_BUFSIZE - sizeof(struct vmbus_bufring), NULL, 0, 2428 1.22 nonaka hvn_nvs_intr, rxr)) { 2429 1.22 nonaka DPRINTF("%s: failed to open channel\n", 2430 1.22 nonaka device_xname(sc->sc_dev)); 2431 1.22 nonaka return -1; 2432 1.22 nonaka } 2433 1.22 nonaka 2434 1.22 nonaka return 0; 2435 1.22 nonaka } 2436 1.22 nonaka 2437 1.22 nonaka static void 2438 1.22 nonaka hvn_channel_detach(struct hvn_softc *sc, struct vmbus_channel *chan) 2439 1.22 nonaka { 2440 1.22 nonaka 2441 1.22 nonaka vmbus_channel_close_direct(chan); 2442 1.22 nonaka } 2443 1.22 nonaka 2444 1.22 nonaka static void 2445 1.22 nonaka hvn_channel_detach_all(struct hvn_softc *sc) 2446 1.22 nonaka { 2447 1.22 nonaka struct vmbus_channel **subchans; 2448 1.22 nonaka int i, subchan_cnt = sc->sc_nrxr_inuse - 1; 2449 1.22 nonaka 2450 1.22 nonaka if (subchan_cnt > 0) { 2451 1.22 nonaka /* Detach the sub-channels. */ 2452 1.22 nonaka subchans = vmbus_subchannel_get(sc->sc_prichan, subchan_cnt); 2453 1.22 nonaka for (i = 0; i < subchan_cnt; i++) 2454 1.22 nonaka hvn_channel_detach(sc, subchans[i]); 2455 1.22 nonaka vmbus_subchannel_rel(subchans, subchan_cnt); 2456 1.22 nonaka } 2457 1.22 nonaka 2458 1.22 nonaka /* 2459 1.22 nonaka * Detach the primary channel, _after_ all sub-channels 2460 1.22 nonaka * are detached. 2461 1.22 nonaka */ 2462 1.22 nonaka hvn_channel_detach(sc, sc->sc_prichan); 2463 1.22 nonaka 2464 1.22 nonaka /* Wait for sub-channels to be destroyed, if any. */ 2465 1.22 nonaka vmbus_subchannel_drain(sc->sc_prichan); 2466 1.22 nonaka } 2467 1.22 nonaka 2468 1.22 nonaka static int 2469 1.22 nonaka hvn_subchannel_attach(struct hvn_softc *sc) 2470 1.22 nonaka { 2471 1.22 nonaka struct vmbus_channel **subchans; 2472 1.22 nonaka int subchan_cnt = sc->sc_nrxr_inuse - 1; 2473 1.22 nonaka int i, error = 0; 2474 1.22 nonaka 2475 1.22 nonaka KASSERTMSG(subchan_cnt > 0, "no sub-channels"); 2476 1.22 nonaka 2477 1.22 nonaka /* Attach the sub-channels. */ 2478 1.22 nonaka subchans = vmbus_subchannel_get(sc->sc_prichan, subchan_cnt); 2479 1.22 nonaka for (i = 0; i < subchan_cnt; ++i) { 2480 1.22 nonaka int error1; 2481 1.22 nonaka 2482 1.22 nonaka error1 = hvn_channel_attach(sc, subchans[i]); 2483 1.22 nonaka if (error1) { 2484 1.22 nonaka error = error1; 2485 1.22 nonaka /* Move on; all channels will be detached later. */ 2486 1.22 nonaka } 2487 1.22 nonaka } 2488 1.22 nonaka vmbus_subchannel_rel(subchans, subchan_cnt); 2489 1.22 nonaka 2490 1.22 nonaka if (error) { 2491 1.22 nonaka aprint_error_dev(sc->sc_dev, 2492 1.22 nonaka "sub-channels attach failed: %d\n", error); 2493 1.22 nonaka return error; 2494 1.22 nonaka } 2495 1.22 nonaka 2496 1.22 nonaka aprint_debug_dev(sc->sc_dev, "%d sub-channels attached\n", 2497 1.22 nonaka subchan_cnt); 2498 1.22 nonaka return 0; 2499 1.22 nonaka } 2500 1.22 nonaka 2501 1.22 nonaka static int 2502 1.22 nonaka hvn_synth_alloc_subchannels(struct hvn_softc *sc, int *nsubch) 2503 1.22 nonaka { 2504 1.22 nonaka struct vmbus_channel **subchans; 2505 1.22 nonaka int error, nchan, rxr_cnt; 2506 1.22 nonaka 2507 1.22 nonaka nchan = *nsubch + 1; 2508 1.22 nonaka if (nchan < 2) { 2509 1.22 nonaka /* Multiple RX/TX rings are not requested. */ 2510 1.22 nonaka *nsubch = 0; 2511 1.22 nonaka return 0; 2512 1.22 nonaka } 2513 1.22 nonaka 2514 1.22 nonaka /* 2515 1.22 nonaka * Query RSS capabilities, e.g. # of RX rings, and # of indirect 2516 1.22 nonaka * table entries. 2517 1.22 nonaka */ 2518 1.22 nonaka if (hvn_get_rsscaps(sc, &rxr_cnt)) { 2519 1.22 nonaka /* No RSS. */ 2520 1.22 nonaka *nsubch = 0; 2521 1.22 nonaka return 0; 2522 1.22 nonaka } 2523 1.22 nonaka 2524 1.22 nonaka aprint_debug_dev(sc->sc_dev, "RX rings offered %u, requested %d\n", 2525 1.22 nonaka rxr_cnt, nchan); 2526 1.22 nonaka 2527 1.22 nonaka if (nchan > rxr_cnt) 2528 1.22 nonaka nchan = rxr_cnt; 2529 1.22 nonaka if (nchan == 1) { 2530 1.22 nonaka aprint_debug_dev(sc->sc_dev, 2531 1.22 nonaka "only 1 channel is supported, no vRSS\n"); 2532 1.22 nonaka *nsubch = 0; 2533 1.22 nonaka return 0; 2534 1.22 nonaka } 2535 1.22 nonaka 2536 1.22 nonaka *nsubch = nchan - 1; 2537 1.22 nonaka error = hvn_nvs_alloc_subchannels(sc, nsubch); 2538 1.22 nonaka if (error || *nsubch == 0) { 2539 1.22 nonaka /* Failed to allocate sub-channels. */ 2540 1.22 nonaka *nsubch = 0; 2541 1.22 nonaka return 0; 2542 1.22 nonaka } 2543 1.22 nonaka 2544 1.22 nonaka /* 2545 1.22 nonaka * Wait for all sub-channels to become ready before moving on. 2546 1.22 nonaka */ 2547 1.22 nonaka subchans = vmbus_subchannel_get(sc->sc_prichan, *nsubch); 2548 1.22 nonaka vmbus_subchannel_rel(subchans, *nsubch); 2549 1.22 nonaka return 0; 2550 1.22 nonaka } 2551 1.22 nonaka 2552 1.22 nonaka static int 2553 1.22 nonaka hvn_synth_attachable(const struct hvn_softc *sc) 2554 1.22 nonaka { 2555 1.22 nonaka #if 0 2556 1.22 nonaka const struct hvn_rx_ring *rxr; 2557 1.22 nonaka int i; 2558 1.22 nonaka 2559 1.22 nonaka for (i = 0; i < sc->sc_nrxr; i++) { 2560 1.22 nonaka rxr = &sc->sc_rxr[i]; 2561 1.22 nonaka if (rxr->rxr_flags) 2562 1.22 nonaka return 0; 2563 1.22 nonaka } 2564 1.22 nonaka #endif 2565 1.22 nonaka return 1; 2566 1.22 nonaka } 2567 1.22 nonaka 2568 1.22 nonaka /* 2569 1.22 nonaka * Make sure that the RX filter is zero after the successful 2570 1.22 nonaka * RNDIS initialization. 2571 1.22 nonaka * 2572 1.22 nonaka * NOTE: 2573 1.22 nonaka * Under certain conditions on certain versions of Hyper-V, 2574 1.22 nonaka * the RNDIS rxfilter is _not_ zero on the hypervisor side 2575 1.22 nonaka * after the successful RNDIS initialization, which breaks 2576 1.22 nonaka * the assumption of any following code (well, it breaks the 2577 1.22 nonaka * RNDIS API contract actually). Clear the RNDIS rxfilter 2578 1.22 nonaka * explicitly, drain packets sneaking through, and drain the 2579 1.22 nonaka * interrupt taskqueues scheduled due to the stealth packets. 2580 1.22 nonaka */ 2581 1.22 nonaka static void 2582 1.22 nonaka hvn_init_fixat(struct hvn_softc *sc, int nchan) 2583 1.22 nonaka { 2584 1.22 nonaka 2585 1.22 nonaka hvn_disable_rx(sc); 2586 1.22 nonaka hvn_drain_rxtx(sc, nchan); 2587 1.22 nonaka } 2588 1.22 nonaka 2589 1.22 nonaka static void 2590 1.22 nonaka hvn_set_txagg(struct hvn_softc *sc) 2591 1.22 nonaka { 2592 1.22 nonaka struct hvn_tx_ring *txr; 2593 1.22 nonaka uint32_t size, pkts; 2594 1.22 nonaka int i; 2595 1.22 nonaka 2596 1.22 nonaka /* 2597 1.22 nonaka * Setup aggregation size. 2598 1.22 nonaka */ 2599 1.22 nonaka if (sc->sc_agg_size < 0) 2600 1.22 nonaka size = UINT32_MAX; 2601 1.22 nonaka else 2602 1.22 nonaka size = sc->sc_agg_size; 2603 1.22 nonaka 2604 1.22 nonaka if (size > sc->sc_rndis_agg_size) 2605 1.22 nonaka size = sc->sc_rndis_agg_size; 2606 1.22 nonaka 2607 1.22 nonaka /* NOTE: We only aggregate packets using chimney sending buffers. */ 2608 1.22 nonaka if (size > (uint32_t)sc->sc_chim_szmax) 2609 1.22 nonaka size = sc->sc_chim_szmax; 2610 1.22 nonaka 2611 1.22 nonaka if (size <= 2 * HVN_PKTSIZE_MIN(sc->sc_rndis_agg_align)) { 2612 1.22 nonaka /* Disable */ 2613 1.22 nonaka size = 0; 2614 1.22 nonaka pkts = 0; 2615 1.22 nonaka goto done; 2616 1.22 nonaka } 2617 1.22 nonaka 2618 1.22 nonaka /* NOTE: Type of the per TX ring setting is 'int'. */ 2619 1.22 nonaka if (size > INT_MAX) 2620 1.22 nonaka size = INT_MAX; 2621 1.22 nonaka 2622 1.22 nonaka /* 2623 1.22 nonaka * Setup aggregation packet count. 2624 1.22 nonaka */ 2625 1.22 nonaka if (sc->sc_agg_pkts < 0) 2626 1.22 nonaka pkts = UINT32_MAX; 2627 1.22 nonaka else 2628 1.22 nonaka pkts = sc->sc_agg_pkts; 2629 1.22 nonaka 2630 1.22 nonaka if (pkts > sc->sc_rndis_agg_pkts) 2631 1.22 nonaka pkts = sc->sc_rndis_agg_pkts; 2632 1.22 nonaka 2633 1.22 nonaka if (pkts <= 1) { 2634 1.22 nonaka /* Disable */ 2635 1.22 nonaka size = 0; 2636 1.22 nonaka pkts = 0; 2637 1.22 nonaka goto done; 2638 1.22 nonaka } 2639 1.22 nonaka 2640 1.22 nonaka /* NOTE: Type of the per TX ring setting is 'short'. */ 2641 1.22 nonaka if (pkts > SHRT_MAX) 2642 1.22 nonaka pkts = SHRT_MAX; 2643 1.22 nonaka 2644 1.22 nonaka done: 2645 1.22 nonaka /* NOTE: Type of the per TX ring setting is 'short'. */ 2646 1.22 nonaka if (sc->sc_rndis_agg_align > SHRT_MAX) { 2647 1.22 nonaka /* Disable */ 2648 1.22 nonaka size = 0; 2649 1.22 nonaka pkts = 0; 2650 1.22 nonaka } 2651 1.22 nonaka 2652 1.22 nonaka aprint_verbose_dev(sc->sc_dev, 2653 1.22 nonaka "TX aggregate size %u, pkts %u, align %u\n", 2654 1.22 nonaka size, pkts, sc->sc_rndis_agg_align); 2655 1.22 nonaka 2656 1.22 nonaka for (i = 0; i < sc->sc_ntxr_inuse; ++i) { 2657 1.22 nonaka txr = &sc->sc_txr[i]; 2658 1.22 nonaka 2659 1.22 nonaka mutex_enter(&txr->txr_lock); 2660 1.22 nonaka txr->txr_agg_szmax = size; 2661 1.22 nonaka txr->txr_agg_pktmax = pkts; 2662 1.22 nonaka txr->txr_agg_align = sc->sc_rndis_agg_align; 2663 1.22 nonaka mutex_exit(&txr->txr_lock); 2664 1.22 nonaka } 2665 1.22 nonaka } 2666 1.22 nonaka 2667 1.22 nonaka static int 2668 1.22 nonaka hvn_synth_attach(struct hvn_softc *sc, int mtu) 2669 1.22 nonaka { 2670 1.22 nonaka uint8_t rss_key[RSS_KEYSIZE]; 2671 1.22 nonaka uint32_t old_caps; 2672 1.22 nonaka int nchan = 1, nsubch; 2673 1.22 nonaka int i, error; 2674 1.22 nonaka 2675 1.22 nonaka if (!hvn_synth_attachable(sc)) 2676 1.22 nonaka return ENXIO; 2677 1.22 nonaka 2678 1.22 nonaka /* Save capabilities for later verification. */ 2679 1.22 nonaka old_caps = sc->sc_caps; 2680 1.22 nonaka sc->sc_caps = 0; 2681 1.22 nonaka 2682 1.22 nonaka /* Clear RSS stuffs. */ 2683 1.22 nonaka sc->sc_rss_ind_size = 0; 2684 1.22 nonaka sc->sc_rss_hash = 0; 2685 1.22 nonaka sc->sc_rss_hcap = 0; 2686 1.22 nonaka 2687 1.22 nonaka /* 2688 1.22 nonaka * Attach the primary channel _before_ attaching NVS and RNDIS. 2689 1.22 nonaka */ 2690 1.22 nonaka error = hvn_channel_attach(sc, sc->sc_prichan); 2691 1.22 nonaka if (error) { 2692 1.22 nonaka aprint_error_dev(sc->sc_dev, 2693 1.22 nonaka "failed to attach primary channel\n"); 2694 1.22 nonaka goto failed; 2695 1.22 nonaka } 2696 1.22 nonaka 2697 1.22 nonaka /* 2698 1.22 nonaka * Attach NVS. 2699 1.22 nonaka */ 2700 1.22 nonaka error = hvn_nvs_attach(sc, mtu); 2701 1.22 nonaka if (error) { 2702 1.22 nonaka aprint_error_dev(sc->sc_dev, "failed to init NVSP\n"); 2703 1.22 nonaka goto detach_channel; 2704 1.22 nonaka } 2705 1.22 nonaka 2706 1.22 nonaka /* 2707 1.22 nonaka * Attach RNDIS _after_ NVS is attached. 2708 1.22 nonaka */ 2709 1.22 nonaka error = hvn_rndis_attach(sc, mtu); 2710 1.22 nonaka if (error) { 2711 1.22 nonaka aprint_error_dev(sc->sc_dev, "failed to init RNDIS\n"); 2712 1.22 nonaka goto detach_nvs; 2713 1.22 nonaka } 2714 1.22 nonaka 2715 1.22 nonaka error = hvn_set_capabilities(sc, mtu); 2716 1.22 nonaka if (error) { 2717 1.22 nonaka aprint_error_dev(sc->sc_dev, "failed to setup offloading\n"); 2718 1.22 nonaka goto detach_rndis; 2719 1.22 nonaka } 2720 1.22 nonaka 2721 1.22 nonaka if ((sc->sc_flags & HVN_SCF_ATTACHED) && old_caps != sc->sc_caps) { 2722 1.22 nonaka device_printf(sc->sc_dev, "caps mismatch " 2723 1.22 nonaka "old 0x%08x, new 0x%08x\n", old_caps, sc->sc_caps); 2724 1.22 nonaka error = ENXIO; 2725 1.22 nonaka goto detach_rndis; 2726 1.22 nonaka } 2727 1.22 nonaka 2728 1.22 nonaka /* 2729 1.22 nonaka * Allocate sub-channels for multi-TX/RX rings. 2730 1.22 nonaka * 2731 1.22 nonaka * NOTE: 2732 1.22 nonaka * The # of RX rings that can be used is equivalent to the # of 2733 1.22 nonaka * channels to be requested. 2734 1.22 nonaka */ 2735 1.22 nonaka nsubch = sc->sc_nrxr - 1; 2736 1.22 nonaka error = hvn_synth_alloc_subchannels(sc, &nsubch); 2737 1.22 nonaka if (error) { 2738 1.22 nonaka aprint_error_dev(sc->sc_dev, 2739 1.22 nonaka "failed to allocate sub channels\n"); 2740 1.22 nonaka goto detach_synth; 2741 1.22 nonaka } 2742 1.22 nonaka 2743 1.22 nonaka /* 2744 1.22 nonaka * Set the # of TX/RX rings that could be used according to 2745 1.22 nonaka * the # of channels that NVS offered. 2746 1.22 nonaka */ 2747 1.22 nonaka nchan = nsubch + 1; 2748 1.22 nonaka hvn_set_ring_inuse(sc, nchan); 2749 1.22 nonaka 2750 1.22 nonaka if (nchan > 1) { 2751 1.22 nonaka /* 2752 1.22 nonaka * Attach the sub-channels. 2753 1.22 nonaka * 2754 1.22 nonaka * NOTE: hvn_set_ring_inuse() _must_ have been called. 2755 1.22 nonaka */ 2756 1.22 nonaka error = hvn_subchannel_attach(sc); 2757 1.22 nonaka if (error) { 2758 1.22 nonaka aprint_error_dev(sc->sc_dev, 2759 1.22 nonaka "failed to attach sub channels\n"); 2760 1.22 nonaka goto detach_synth; 2761 1.22 nonaka } 2762 1.22 nonaka 2763 1.22 nonaka /* 2764 1.22 nonaka * Configure RSS key and indirect table _after_ all sub-channels 2765 1.22 nonaka * are attached. 2766 1.22 nonaka */ 2767 1.22 nonaka if (!(sc->sc_flags & HVN_SCF_HAS_RSSKEY)) { 2768 1.22 nonaka /* Set the default RSS key. */ 2769 1.22 nonaka CTASSERT(sizeof(sc->sc_rss.rss_key) == sizeof(rss_key)); 2770 1.22 nonaka rss_getkey(rss_key); 2771 1.22 nonaka memcpy(&sc->sc_rss.rss_key, rss_key, 2772 1.22 nonaka sizeof(sc->sc_rss.rss_key)); 2773 1.22 nonaka sc->sc_flags |= HVN_SCF_HAS_RSSKEY; 2774 1.22 nonaka } 2775 1.22 nonaka 2776 1.22 nonaka if (!(sc->sc_flags & HVN_SCF_HAS_RSSIND)) { 2777 1.22 nonaka /* Setup RSS indirect table in round-robin fashion. */ 2778 1.22 nonaka for (i = 0; i < NDIS_HASH_INDCNT; i++) { 2779 1.22 nonaka sc->sc_rss.rss_ind[i] = i % nchan; 2780 1.22 nonaka } 2781 1.22 nonaka sc->sc_flags |= HVN_SCF_HAS_RSSIND; 2782 1.22 nonaka } else { 2783 1.22 nonaka /* 2784 1.22 nonaka * # of usable channels may be changed, so we have to 2785 1.22 nonaka * make sure that all entries in RSS indirect table 2786 1.22 nonaka * are valid. 2787 1.22 nonaka * 2788 1.22 nonaka * NOTE: hvn_set_ring_inuse() _must_ have been called. 2789 1.22 nonaka */ 2790 1.22 nonaka hvn_fixup_rss_ind(sc); 2791 1.22 nonaka } 2792 1.22 nonaka 2793 1.22 nonaka sc->sc_rss_hash = sc->sc_rss_hcap; 2794 1.22 nonaka error = hvn_set_rss(sc, NDIS_RSS_FLAG_NONE); 2795 1.22 nonaka if (error) { 2796 1.22 nonaka aprint_error_dev(sc->sc_dev, "failed to setup RSS\n"); 2797 1.22 nonaka goto detach_synth; 2798 1.22 nonaka } 2799 1.22 nonaka } 2800 1.22 nonaka 2801 1.22 nonaka /* 2802 1.22 nonaka * Fixup transmission aggregation setup. 2803 1.22 nonaka */ 2804 1.22 nonaka hvn_set_txagg(sc); 2805 1.22 nonaka hvn_init_fixat(sc, nchan); 2806 1.22 nonaka return 0; 2807 1.22 nonaka 2808 1.22 nonaka detach_synth: 2809 1.22 nonaka hvn_init_fixat(sc, nchan); 2810 1.22 nonaka hvn_synth_detach(sc); 2811 1.22 nonaka return error; 2812 1.22 nonaka 2813 1.22 nonaka detach_rndis: 2814 1.22 nonaka hvn_init_fixat(sc, nchan); 2815 1.22 nonaka hvn_rndis_detach(sc); 2816 1.22 nonaka detach_nvs: 2817 1.22 nonaka hvn_nvs_detach(sc); 2818 1.22 nonaka detach_channel: 2819 1.22 nonaka hvn_channel_detach(sc, sc->sc_prichan); 2820 1.22 nonaka failed: 2821 1.22 nonaka /* Restore old capabilities. */ 2822 1.22 nonaka sc->sc_caps = old_caps; 2823 1.22 nonaka return error; 2824 1.22 nonaka } 2825 1.22 nonaka 2826 1.22 nonaka static void 2827 1.22 nonaka hvn_synth_detach(struct hvn_softc *sc) 2828 1.22 nonaka { 2829 1.22 nonaka 2830 1.22 nonaka /* Detach the RNDIS first. */ 2831 1.22 nonaka hvn_rndis_detach(sc); 2832 1.22 nonaka 2833 1.22 nonaka /* Detach NVS. */ 2834 1.22 nonaka hvn_nvs_detach(sc); 2835 1.22 nonaka 2836 1.22 nonaka /* Detach all of the channels. */ 2837 1.22 nonaka hvn_channel_detach_all(sc); 2838 1.22 nonaka 2839 1.22 nonaka if (sc->sc_prichan->ch_sc->sc_proto >= VMBUS_VERSION_WIN10 && 2840 1.22 nonaka sc->sc_rx_hndl) { 2841 1.22 nonaka /* 2842 1.22 nonaka * Host is post-Win2016, disconnect RXBUF from primary channel 2843 1.22 nonaka * here. 2844 1.22 nonaka */ 2845 1.22 nonaka vmbus_handle_free(sc->sc_prichan, sc->sc_rx_hndl); 2846 1.22 nonaka sc->sc_rx_hndl = 0; 2847 1.22 nonaka } 2848 1.22 nonaka 2849 1.22 nonaka if (sc->sc_prichan->ch_sc->sc_proto >= VMBUS_VERSION_WIN10 && 2850 1.22 nonaka sc->sc_chim_hndl) { 2851 1.22 nonaka /* 2852 1.22 nonaka * Host is post-Win2016, disconnect chimney sending buffer 2853 1.22 nonaka * from primary channel here. 2854 1.22 nonaka */ 2855 1.22 nonaka vmbus_handle_free(sc->sc_prichan, sc->sc_chim_hndl); 2856 1.22 nonaka sc->sc_chim_hndl = 0; 2857 1.22 nonaka } 2858 1.22 nonaka } 2859 1.22 nonaka 2860 1.22 nonaka static void 2861 1.22 nonaka hvn_set_ring_inuse(struct hvn_softc *sc, int ring_cnt) 2862 1.22 nonaka { 2863 1.22 nonaka 2864 1.22 nonaka if (sc->sc_ntxr > ring_cnt) 2865 1.22 nonaka sc->sc_ntxr_inuse = ring_cnt; 2866 1.22 nonaka else 2867 1.22 nonaka sc->sc_ntxr_inuse = sc->sc_ntxr; 2868 1.22 nonaka sc->sc_nrxr_inuse = ring_cnt; 2869 1.22 nonaka } 2870 1.22 nonaka 2871 1.22 nonaka static void 2872 1.22 nonaka hvn_channel_drain(struct hvn_softc *sc, struct vmbus_channel *chan) 2873 1.22 nonaka { 2874 1.22 nonaka struct hvn_rx_ring *rxr; 2875 1.22 nonaka int i, s; 2876 1.22 nonaka 2877 1.22 nonaka for (rxr = NULL, i = 0; i < sc->sc_nrxr_inuse; i++) { 2878 1.22 nonaka rxr = &sc->sc_rxr[i]; 2879 1.22 nonaka if (rxr->rxr_chan == chan) 2880 1.22 nonaka break; 2881 1.22 nonaka } 2882 1.22 nonaka KASSERT(i < sc->sc_nrxr_inuse); 2883 1.22 nonaka 2884 1.22 nonaka /* 2885 1.22 nonaka * NOTE: 2886 1.22 nonaka * The TX bufring will not be drained by the hypervisor, 2887 1.22 nonaka * if the primary channel is revoked. 2888 1.22 nonaka */ 2889 1.22 nonaka while (!vmbus_channel_rx_empty(chan) || 2890 1.22 nonaka (!vmbus_channel_is_revoked(sc->sc_prichan) && 2891 1.22 nonaka !vmbus_channel_tx_empty(chan))) { 2892 1.22 nonaka DELAY(20); 2893 1.22 nonaka s = splnet(); 2894 1.22 nonaka hvn_nvs_intr1(rxr, sc->sc_tx_process_limit, 2895 1.22 nonaka sc->sc_rx_process_limit); 2896 1.22 nonaka splx(s); 2897 1.22 nonaka } 2898 1.22 nonaka 2899 1.22 nonaka mutex_enter(&rxr->rxr_onwork_lock); 2900 1.22 nonaka while (rxr->rxr_onlist || rxr->rxr_onproc) 2901 1.22 nonaka cv_wait(&rxr->rxr_onwork_cv, &rxr->rxr_onwork_lock); 2902 1.22 nonaka mutex_exit(&rxr->rxr_onwork_lock); 2903 1.22 nonaka } 2904 1.22 nonaka 2905 1.22 nonaka static void 2906 1.22 nonaka hvn_disable_rx(struct hvn_softc *sc) 2907 1.22 nonaka { 2908 1.22 nonaka 2909 1.22 nonaka /* 2910 1.22 nonaka * Disable RX by clearing RX filter forcefully. 2911 1.22 nonaka */ 2912 1.22 nonaka (void)hvn_rndis_close(sc); /* ignore error */ 2913 1.22 nonaka 2914 1.22 nonaka /* 2915 1.22 nonaka * Give RNDIS enough time to flush all pending data packets. 2916 1.22 nonaka */ 2917 1.22 nonaka DELAY(200); 2918 1.22 nonaka } 2919 1.22 nonaka 2920 1.22 nonaka static void 2921 1.22 nonaka hvn_drain_rxtx(struct hvn_softc *sc, int nchan) 2922 1.22 nonaka { 2923 1.22 nonaka struct vmbus_channel **subchans = NULL; 2924 1.22 nonaka int i, nsubch; 2925 1.22 nonaka 2926 1.22 nonaka /* 2927 1.22 nonaka * Drain RX/TX bufrings and interrupts. 2928 1.22 nonaka */ 2929 1.22 nonaka nsubch = nchan - 1; 2930 1.22 nonaka if (nsubch > 0) 2931 1.22 nonaka subchans = vmbus_subchannel_get(sc->sc_prichan, nsubch); 2932 1.22 nonaka 2933 1.22 nonaka if (subchans != NULL) { 2934 1.22 nonaka for (i = 0; i < nsubch; ++i) 2935 1.22 nonaka hvn_channel_drain(sc, subchans[i]); 2936 1.22 nonaka } 2937 1.22 nonaka hvn_channel_drain(sc, sc->sc_prichan); 2938 1.22 nonaka 2939 1.22 nonaka if (subchans != NULL) 2940 1.22 nonaka vmbus_subchannel_rel(subchans, nsubch); 2941 1.22 nonaka } 2942 1.22 nonaka 2943 1.22 nonaka static void 2944 1.22 nonaka hvn_suspend_data(struct hvn_softc *sc) 2945 1.22 nonaka { 2946 1.22 nonaka struct hvn_tx_ring *txr; 2947 1.22 nonaka int i, s; 2948 1.22 nonaka 2949 1.22 nonaka /* 2950 1.22 nonaka * Suspend TX. 2951 1.22 nonaka */ 2952 1.22 nonaka for (i = 0; i < sc->sc_ntxr_inuse; i++) { 2953 1.22 nonaka txr = &sc->sc_txr[i]; 2954 1.22 nonaka 2955 1.22 nonaka mutex_enter(&txr->txr_lock); 2956 1.22 nonaka txr->txr_suspended = 1; 2957 1.22 nonaka mutex_exit(&txr->txr_lock); 2958 1.22 nonaka /* No one is able send more packets now. */ 2959 1.22 nonaka 2960 1.22 nonaka /* 2961 1.22 nonaka * Wait for all pending sends to finish. 2962 1.22 nonaka * 2963 1.22 nonaka * NOTE: 2964 1.22 nonaka * We will _not_ receive all pending send-done, if the 2965 1.22 nonaka * primary channel is revoked. 2966 1.22 nonaka */ 2967 1.22 nonaka while (hvn_tx_ring_pending(txr) && 2968 1.22 nonaka !vmbus_channel_is_revoked(sc->sc_prichan)) { 2969 1.22 nonaka DELAY(20); 2970 1.22 nonaka s = splnet(); 2971 1.22 nonaka hvn_nvs_intr1(txr->txr_rxr, sc->sc_tx_process_limit, 2972 1.22 nonaka sc->sc_rx_process_limit); 2973 1.22 nonaka splx(s); 2974 1.22 nonaka } 2975 1.22 nonaka } 2976 1.22 nonaka 2977 1.22 nonaka /* 2978 1.22 nonaka * Disable RX. 2979 1.22 nonaka */ 2980 1.22 nonaka hvn_disable_rx(sc); 2981 1.22 nonaka 2982 1.22 nonaka /* 2983 1.22 nonaka * Drain RX/TX. 2984 1.22 nonaka */ 2985 1.22 nonaka hvn_drain_rxtx(sc, sc->sc_nrxr_inuse); 2986 1.22 nonaka } 2987 1.22 nonaka 2988 1.22 nonaka static void 2989 1.22 nonaka hvn_suspend_mgmt(struct hvn_softc *sc) 2990 1.22 nonaka { 2991 1.22 nonaka 2992 1.22 nonaka sc->sc_link_suspend = true; 2993 1.22 nonaka callout_halt(&sc->sc_link_tmout, NULL); 2994 1.22 nonaka 2995 1.22 nonaka /* Drain link state task */ 2996 1.22 nonaka mutex_enter(&sc->sc_link_lock); 2997 1.22 nonaka for (;;) { 2998 1.22 nonaka if (!sc->sc_link_onproc) 2999 1.22 nonaka break; 3000 1.22 nonaka mutex_exit(&sc->sc_link_lock); 3001 1.22 nonaka DELAY(20); 3002 1.22 nonaka mutex_enter(&sc->sc_link_lock); 3003 1.22 nonaka } 3004 1.22 nonaka mutex_exit(&sc->sc_link_lock); 3005 1.22 nonaka } 3006 1.22 nonaka 3007 1.22 nonaka static void 3008 1.22 nonaka hvn_suspend(struct hvn_softc *sc) 3009 1.22 nonaka { 3010 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 3011 1.22 nonaka 3012 1.22 nonaka if (ifp->if_flags & IFF_RUNNING) 3013 1.22 nonaka hvn_suspend_data(sc); 3014 1.22 nonaka hvn_suspend_mgmt(sc); 3015 1.22 nonaka } 3016 1.22 nonaka 3017 1.22 nonaka static void 3018 1.22 nonaka hvn_resume_tx(struct hvn_softc *sc, int ring_cnt) 3019 1.22 nonaka { 3020 1.22 nonaka struct hvn_tx_ring *txr; 3021 1.22 nonaka int i; 3022 1.22 nonaka 3023 1.22 nonaka for (i = 0; i < ring_cnt; i++) { 3024 1.22 nonaka txr = &sc->sc_txr[i]; 3025 1.22 nonaka mutex_enter(&txr->txr_lock); 3026 1.22 nonaka txr->txr_suspended = 0; 3027 1.22 nonaka mutex_exit(&txr->txr_lock); 3028 1.22 nonaka } 3029 1.22 nonaka } 3030 1.22 nonaka 3031 1.22 nonaka static void 3032 1.22 nonaka hvn_resume_data(struct hvn_softc *sc) 3033 1.22 nonaka { 3034 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 3035 1.22 nonaka struct hvn_tx_ring *txr; 3036 1.22 nonaka int i; 3037 1.22 nonaka 3038 1.22 nonaka /* 3039 1.22 nonaka * Re-enable RX. 3040 1.22 nonaka */ 3041 1.22 nonaka hvn_rndis_open(sc); 3042 1.22 nonaka 3043 1.22 nonaka /* 3044 1.22 nonaka * Make sure to clear suspend status on "all" TX rings, 3045 1.22 nonaka * since sc_ntxr_inuse can be changed after hvn_suspend_data(). 3046 1.22 nonaka */ 3047 1.22 nonaka hvn_resume_tx(sc, sc->sc_ntxr); 3048 1.22 nonaka 3049 1.22 nonaka /* 3050 1.22 nonaka * Flush unused mbuf, since sc_ntxr_inuse may be reduced. 3051 1.22 nonaka */ 3052 1.22 nonaka for (i = sc->sc_ntxr_inuse; i < sc->sc_ntxr; i++) 3053 1.22 nonaka hvn_tx_ring_qflush(sc, &sc->sc_txr[i]); 3054 1.22 nonaka 3055 1.22 nonaka /* 3056 1.22 nonaka * Kick start TX. 3057 1.22 nonaka */ 3058 1.22 nonaka for (i = 0; i < sc->sc_ntxr_inuse; i++) { 3059 1.22 nonaka txr = &sc->sc_txr[i]; 3060 1.22 nonaka mutex_enter(&txr->txr_lock); 3061 1.22 nonaka txr->txr_oactive = 0; 3062 1.22 nonaka 3063 1.22 nonaka /* ALTQ */ 3064 1.22 nonaka if (txr->txr_id == 0) 3065 1.22 nonaka if_schedule_deferred_start(ifp); 3066 1.22 nonaka softint_schedule(txr->txr_si); 3067 1.22 nonaka mutex_exit(&txr->txr_lock); 3068 1.22 nonaka } 3069 1.22 nonaka } 3070 1.22 nonaka 3071 1.22 nonaka static void 3072 1.22 nonaka hvn_resume_mgmt(struct hvn_softc *sc) 3073 1.22 nonaka { 3074 1.22 nonaka 3075 1.22 nonaka sc->sc_link_suspend = false; 3076 1.22 nonaka hvn_link_event(sc, HVN_LINK_EV_RESUME_NETWORK); 3077 1.22 nonaka } 3078 1.22 nonaka 3079 1.22 nonaka static void 3080 1.22 nonaka hvn_resume(struct hvn_softc *sc) 3081 1.22 nonaka { 3082 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 3083 1.22 nonaka 3084 1.22 nonaka if (ifp->if_flags & IFF_RUNNING) 3085 1.22 nonaka hvn_resume_data(sc); 3086 1.22 nonaka hvn_resume_mgmt(sc); 3087 1.22 nonaka } 3088 1.22 nonaka 3089 1.22 nonaka static int 3090 1.22 nonaka hvn_nvs_init(struct hvn_softc *sc) 3091 1.22 nonaka { 3092 1.22 nonaka 3093 1.22 nonaka mutex_init(&sc->sc_nvsrsp_lock, MUTEX_DEFAULT, IPL_NET); 3094 1.22 nonaka cv_init(&sc->sc_nvsrsp_cv, "nvsrspcv"); 3095 1.22 nonaka 3096 1.22 nonaka return 0; 3097 1.22 nonaka } 3098 1.22 nonaka 3099 1.22 nonaka static void 3100 1.22 nonaka hvn_nvs_destroy(struct hvn_softc *sc) 3101 1.22 nonaka { 3102 1.22 nonaka 3103 1.22 nonaka mutex_destroy(&sc->sc_nvsrsp_lock); 3104 1.22 nonaka cv_destroy(&sc->sc_nvsrsp_cv); 3105 1.22 nonaka } 3106 1.22 nonaka 3107 1.22 nonaka static int 3108 1.22 nonaka hvn_nvs_doinit(struct hvn_softc *sc, uint32_t proto) 3109 1.22 nonaka { 3110 1.22 nonaka struct hvn_nvs_init cmd; 3111 1.22 nonaka struct hvn_nvs_init_resp *rsp; 3112 1.22 nonaka uint64_t tid; 3113 1.22 nonaka int error; 3114 1.22 nonaka 3115 1.22 nonaka memset(&cmd, 0, sizeof(cmd)); 3116 1.22 nonaka cmd.nvs_type = HVN_NVS_TYPE_INIT; 3117 1.22 nonaka cmd.nvs_ver_min = cmd.nvs_ver_max = proto; 3118 1.22 nonaka 3119 1.22 nonaka tid = atomic_inc_uint_nv(&sc->sc_nvstid); 3120 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3121 1.22 nonaka error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0); 3122 1.22 nonaka if (error == 0) { 3123 1.22 nonaka rsp = (struct hvn_nvs_init_resp *)&sc->sc_nvsrsp; 3124 1.22 nonaka if (rsp->nvs_status != HVN_NVS_STATUS_OK) 3125 1.22 nonaka error = EINVAL; 3126 1.22 nonaka } 3127 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3128 1.22 nonaka 3129 1.22 nonaka return error; 3130 1.22 nonaka } 3131 1.22 nonaka 3132 1.22 nonaka static int 3133 1.22 nonaka hvn_nvs_conf_ndis(struct hvn_softc *sc, int mtu) 3134 1.22 nonaka { 3135 1.22 nonaka struct hvn_nvs_ndis_conf cmd; 3136 1.22 nonaka uint64_t tid; 3137 1.22 nonaka int error; 3138 1.22 nonaka 3139 1.22 nonaka memset(&cmd, 0, sizeof(cmd)); 3140 1.22 nonaka cmd.nvs_type = HVN_NVS_TYPE_NDIS_CONF; 3141 1.22 nonaka cmd.nvs_mtu = mtu + ETHER_HDR_LEN; 3142 1.22 nonaka cmd.nvs_caps = HVN_NVS_NDIS_CONF_VLAN; 3143 1.22 nonaka 3144 1.22 nonaka tid = atomic_inc_uint_nv(&sc->sc_nvstid); 3145 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3146 1.22 nonaka /* NOTE: No response. */ 3147 1.22 nonaka error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0); 3148 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3149 1.22 nonaka 3150 1.22 nonaka if (error == 0) 3151 1.22 nonaka sc->sc_caps |= HVN_CAPS_MTU | HVN_CAPS_VLAN; 3152 1.22 nonaka return error; 3153 1.22 nonaka } 3154 1.22 nonaka 3155 1.22 nonaka static int 3156 1.22 nonaka hvn_nvs_init_ndis(struct hvn_softc *sc) 3157 1.22 nonaka { 3158 1.22 nonaka struct hvn_nvs_ndis_init cmd; 3159 1.22 nonaka uint64_t tid; 3160 1.22 nonaka int error; 3161 1.22 nonaka 3162 1.22 nonaka memset(&cmd, 0, sizeof(cmd)); 3163 1.22 nonaka cmd.nvs_type = HVN_NVS_TYPE_NDIS_INIT; 3164 1.22 nonaka cmd.nvs_ndis_major = (sc->sc_ndisver & 0xffff0000) >> 16; 3165 1.22 nonaka cmd.nvs_ndis_minor = sc->sc_ndisver & 0x0000ffff; 3166 1.22 nonaka 3167 1.22 nonaka tid = atomic_inc_uint_nv(&sc->sc_nvstid); 3168 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3169 1.22 nonaka /* NOTE: No response. */ 3170 1.22 nonaka error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0); 3171 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3172 1.22 nonaka 3173 1.22 nonaka return error; 3174 1.22 nonaka } 3175 1.22 nonaka 3176 1.22 nonaka static int 3177 1.22 nonaka hvn_nvs_attach(struct hvn_softc *sc, int mtu) 3178 1.22 nonaka { 3179 1.22 nonaka static const uint32_t protos[] = { 3180 1.22 nonaka HVN_NVS_PROTO_VERSION_5, 3181 1.22 nonaka HVN_NVS_PROTO_VERSION_4, 3182 1.22 nonaka HVN_NVS_PROTO_VERSION_2, 3183 1.22 nonaka HVN_NVS_PROTO_VERSION_1 3184 1.22 nonaka }; 3185 1.22 nonaka int i; 3186 1.22 nonaka 3187 1.22 nonaka if (hyperv_ver_major >= 10) 3188 1.22 nonaka sc->sc_caps |= HVN_CAPS_UDPHASH; 3189 1.22 nonaka 3190 1.22 nonaka /* 3191 1.22 nonaka * Initialize NVS. 3192 1.22 nonaka */ 3193 1.22 nonaka if (sc->sc_flags & HVN_SCF_ATTACHED) { 3194 1.22 nonaka /* 3195 1.22 nonaka * NVS version and NDIS version MUST NOT be changed. 3196 1.22 nonaka */ 3197 1.22 nonaka DPRINTF("%s: reinit NVS version %#x, NDIS version %u.%u\n", 3198 1.22 nonaka device_xname(sc->sc_dev), sc->sc_proto, 3199 1.22 nonaka (sc->sc_ndisver >> 16), sc->sc_ndisver & 0xffff); 3200 1.22 nonaka 3201 1.22 nonaka if (hvn_nvs_doinit(sc, sc->sc_proto)) { 3202 1.22 nonaka DPRINTF("%s: failed to reinit NVSP version %#x\n", 3203 1.22 nonaka device_xname(sc->sc_dev), sc->sc_proto); 3204 1.22 nonaka return -1; 3205 1.22 nonaka } 3206 1.22 nonaka } else { 3207 1.22 nonaka /* 3208 1.22 nonaka * Find the supported NVS version and set NDIS version 3209 1.22 nonaka * accordingly. 3210 1.22 nonaka */ 3211 1.22 nonaka for (i = 0; i < __arraycount(protos); i++) { 3212 1.22 nonaka if (hvn_nvs_doinit(sc, protos[i]) == 0) 3213 1.22 nonaka break; 3214 1.22 nonaka } 3215 1.22 nonaka if (i == __arraycount(protos)) { 3216 1.22 nonaka DPRINTF("%s: failed to negotiate NVSP version\n", 3217 1.22 nonaka device_xname(sc->sc_dev)); 3218 1.22 nonaka return -1; 3219 1.22 nonaka } 3220 1.22 nonaka 3221 1.22 nonaka sc->sc_proto = protos[i]; 3222 1.22 nonaka if (sc->sc_proto <= HVN_NVS_PROTO_VERSION_4) 3223 1.22 nonaka sc->sc_ndisver = NDIS_VERSION_6_1; 3224 1.22 nonaka else 3225 1.22 nonaka sc->sc_ndisver = NDIS_VERSION_6_30; 3226 1.1 nonaka 3227 1.22 nonaka DPRINTF("%s: NVS version %#x, NDIS version %u.%u\n", 3228 1.22 nonaka device_xname(sc->sc_dev), sc->sc_proto, 3229 1.22 nonaka (sc->sc_ndisver >> 16), sc->sc_ndisver & 0xffff); 3230 1.1 nonaka } 3231 1.1 nonaka 3232 1.22 nonaka if (sc->sc_proto >= HVN_NVS_PROTO_VERSION_5) 3233 1.22 nonaka sc->sc_caps |= HVN_CAPS_HASHVAL; 3234 1.1 nonaka 3235 1.22 nonaka if (sc->sc_proto >= HVN_NVS_PROTO_VERSION_2) { 3236 1.22 nonaka /* 3237 1.22 nonaka * Configure NDIS before initializing it. 3238 1.22 nonaka */ 3239 1.22 nonaka if (hvn_nvs_conf_ndis(sc, mtu)) 3240 1.22 nonaka return -1; 3241 1.1 nonaka } 3242 1.1 nonaka 3243 1.22 nonaka /* 3244 1.22 nonaka * Initialize NDIS. 3245 1.22 nonaka */ 3246 1.22 nonaka if (hvn_nvs_init_ndis(sc)) 3247 1.22 nonaka return -1; 3248 1.22 nonaka 3249 1.22 nonaka /* 3250 1.22 nonaka * Connect RXBUF. 3251 1.22 nonaka */ 3252 1.22 nonaka if (hvn_nvs_connect_rxbuf(sc)) 3253 1.22 nonaka return -1; 3254 1.1 nonaka 3255 1.22 nonaka /* 3256 1.22 nonaka * Connect chimney sending buffer. 3257 1.22 nonaka */ 3258 1.22 nonaka if (hvn_nvs_connect_chim(sc)) 3259 1.22 nonaka return -1; 3260 1.1 nonaka 3261 1.22 nonaka return 0; 3262 1.1 nonaka } 3263 1.1 nonaka 3264 1.1 nonaka static int 3265 1.22 nonaka hvn_nvs_connect_rxbuf(struct hvn_softc *sc) 3266 1.1 nonaka { 3267 1.1 nonaka struct hvn_nvs_rxbuf_conn cmd; 3268 1.1 nonaka struct hvn_nvs_rxbuf_conn_resp *rsp; 3269 1.1 nonaka uint64_t tid; 3270 1.1 nonaka 3271 1.22 nonaka if (vmbus_handle_alloc(sc->sc_prichan, &sc->sc_rx_dma, sc->sc_rx_size, 3272 1.1 nonaka &sc->sc_rx_hndl)) { 3273 1.1 nonaka DPRINTF("%s: failed to obtain a PA handle\n", 3274 1.1 nonaka device_xname(sc->sc_dev)); 3275 1.22 nonaka return -1; 3276 1.1 nonaka } 3277 1.1 nonaka 3278 1.1 nonaka memset(&cmd, 0, sizeof(cmd)); 3279 1.1 nonaka cmd.nvs_type = HVN_NVS_TYPE_RXBUF_CONN; 3280 1.1 nonaka cmd.nvs_gpadl = sc->sc_rx_hndl; 3281 1.1 nonaka cmd.nvs_sig = HVN_NVS_RXBUF_SIG; 3282 1.1 nonaka 3283 1.1 nonaka tid = atomic_inc_uint_nv(&sc->sc_nvstid); 3284 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3285 1.22 nonaka if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0)) 3286 1.1 nonaka goto errout; 3287 1.1 nonaka 3288 1.1 nonaka rsp = (struct hvn_nvs_rxbuf_conn_resp *)&sc->sc_nvsrsp; 3289 1.1 nonaka if (rsp->nvs_status != HVN_NVS_STATUS_OK) { 3290 1.1 nonaka DPRINTF("%s: failed to set up the Rx ring\n", 3291 1.1 nonaka device_xname(sc->sc_dev)); 3292 1.1 nonaka goto errout; 3293 1.1 nonaka } 3294 1.22 nonaka 3295 1.22 nonaka SET(sc->sc_flags, HVN_SCF_RXBUF_CONNECTED); 3296 1.22 nonaka 3297 1.1 nonaka if (rsp->nvs_nsect > 1) { 3298 1.1 nonaka DPRINTF("%s: invalid number of Rx ring sections: %u\n", 3299 1.1 nonaka device_xname(sc->sc_dev), rsp->nvs_nsect); 3300 1.22 nonaka goto errout; 3301 1.1 nonaka } 3302 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3303 1.22 nonaka 3304 1.1 nonaka return 0; 3305 1.1 nonaka 3306 1.1 nonaka errout: 3307 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3308 1.22 nonaka hvn_nvs_disconnect_rxbuf(sc); 3309 1.1 nonaka return -1; 3310 1.1 nonaka } 3311 1.1 nonaka 3312 1.1 nonaka static int 3313 1.22 nonaka hvn_nvs_disconnect_rxbuf(struct hvn_softc *sc) 3314 1.1 nonaka { 3315 1.1 nonaka struct hvn_nvs_rxbuf_disconn cmd; 3316 1.1 nonaka uint64_t tid; 3317 1.22 nonaka int s, error; 3318 1.1 nonaka 3319 1.22 nonaka if (ISSET(sc->sc_flags, HVN_SCF_RXBUF_CONNECTED)) { 3320 1.22 nonaka memset(&cmd, 0, sizeof(cmd)); 3321 1.22 nonaka cmd.nvs_type = HVN_NVS_TYPE_RXBUF_DISCONN; 3322 1.22 nonaka cmd.nvs_sig = HVN_NVS_RXBUF_SIG; 3323 1.1 nonaka 3324 1.22 nonaka tid = atomic_inc_uint_nv(&sc->sc_nvstid); 3325 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3326 1.22 nonaka error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 3327 1.22 nonaka HVN_NVS_CMD_NORESP); 3328 1.22 nonaka if (error) { 3329 1.22 nonaka device_printf(sc->sc_dev, 3330 1.22 nonaka "failed to send rxbuf disconn: %d", error); 3331 1.22 nonaka } 3332 1.22 nonaka CLR(sc->sc_flags, HVN_SCF_RXBUF_CONNECTED); 3333 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3334 1.1 nonaka 3335 1.22 nonaka /* 3336 1.22 nonaka * Wait for the hypervisor to receive this NVS request. 3337 1.22 nonaka * 3338 1.22 nonaka * NOTE: 3339 1.22 nonaka * The TX bufring will not be drained by the hypervisor, 3340 1.22 nonaka * if the primary channel is revoked. 3341 1.22 nonaka */ 3342 1.22 nonaka while (!vmbus_channel_tx_empty(sc->sc_prichan) && 3343 1.22 nonaka !vmbus_channel_is_revoked(sc->sc_prichan)) { 3344 1.22 nonaka DELAY(20); 3345 1.22 nonaka s = splnet(); 3346 1.22 nonaka hvn_nvs_intr1(&sc->sc_rxr[0], sc->sc_tx_process_limit, 3347 1.22 nonaka sc->sc_rx_process_limit); 3348 1.22 nonaka splx(s); 3349 1.22 nonaka } 3350 1.22 nonaka /* 3351 1.22 nonaka * Linger long enough for NVS to disconnect RXBUF. 3352 1.22 nonaka */ 3353 1.22 nonaka DELAY(200); 3354 1.22 nonaka } 3355 1.1 nonaka 3356 1.22 nonaka if (sc->sc_prichan->ch_sc->sc_proto < VMBUS_VERSION_WIN10 && 3357 1.22 nonaka sc->sc_rx_hndl) { 3358 1.22 nonaka /* 3359 1.22 nonaka * Disconnect RXBUF from primary channel. 3360 1.22 nonaka */ 3361 1.22 nonaka vmbus_handle_free(sc->sc_prichan, sc->sc_rx_hndl); 3362 1.22 nonaka sc->sc_rx_hndl = 0; 3363 1.22 nonaka } 3364 1.1 nonaka 3365 1.1 nonaka return 0; 3366 1.1 nonaka } 3367 1.1 nonaka 3368 1.1 nonaka static int 3369 1.22 nonaka hvn_nvs_connect_chim(struct hvn_softc *sc) 3370 1.1 nonaka { 3371 1.22 nonaka struct hvn_nvs_chim_conn cmd; 3372 1.22 nonaka const struct hvn_nvs_chim_conn_resp *rsp; 3373 1.22 nonaka uint64_t tid; 3374 1.1 nonaka 3375 1.22 nonaka mutex_init(&sc->sc_chim_bmap_lock, MUTEX_DEFAULT, IPL_NET); 3376 1.1 nonaka 3377 1.22 nonaka /* 3378 1.22 nonaka * Connect chimney sending buffer GPADL to the primary channel. 3379 1.22 nonaka * 3380 1.22 nonaka * NOTE: 3381 1.22 nonaka * Only primary channel has chimney sending buffer connected to it. 3382 1.22 nonaka * Sub-channels just share this chimney sending buffer. 3383 1.22 nonaka */ 3384 1.22 nonaka if (vmbus_handle_alloc(sc->sc_prichan, &sc->sc_chim_dma, HVN_CHIM_SIZE, 3385 1.22 nonaka &sc->sc_chim_hndl)) { 3386 1.22 nonaka DPRINTF("%s: failed to obtain a PA handle for chimney\n", 3387 1.1 nonaka device_xname(sc->sc_dev)); 3388 1.22 nonaka return -1; 3389 1.1 nonaka } 3390 1.22 nonaka 3391 1.22 nonaka memset(&cmd, 0, sizeof(cmd)); 3392 1.22 nonaka cmd.nvs_type = HVN_NVS_TYPE_CHIM_CONN; 3393 1.22 nonaka cmd.nvs_gpadl = sc->sc_chim_hndl; 3394 1.22 nonaka cmd.nvs_sig = HVN_NVS_CHIM_SIG; 3395 1.22 nonaka 3396 1.22 nonaka tid = atomic_inc_uint_nv(&sc->sc_nvstid); 3397 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3398 1.22 nonaka if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0)) 3399 1.1 nonaka goto errout; 3400 1.22 nonaka 3401 1.22 nonaka rsp = (struct hvn_nvs_chim_conn_resp *)&sc->sc_nvsrsp; 3402 1.22 nonaka if (rsp->nvs_status != HVN_NVS_STATUS_OK) { 3403 1.22 nonaka DPRINTF("%s: failed to set up chimney sending buffer\n", 3404 1.1 nonaka device_xname(sc->sc_dev)); 3405 1.1 nonaka goto errout; 3406 1.1 nonaka } 3407 1.1 nonaka 3408 1.22 nonaka if (rsp->nvs_sectsz == 0 || 3409 1.22 nonaka (rsp->nvs_sectsz % sizeof(uint32_t)) != 0) { 3410 1.22 nonaka /* 3411 1.22 nonaka * Can't use chimney sending buffer; done! 3412 1.22 nonaka */ 3413 1.22 nonaka if (rsp->nvs_sectsz == 0) { 3414 1.22 nonaka device_printf(sc->sc_dev, 3415 1.22 nonaka "zero chimney sending buffer section size\n"); 3416 1.22 nonaka } else { 3417 1.22 nonaka device_printf(sc->sc_dev, 3418 1.22 nonaka "misaligned chimney sending buffers," 3419 1.22 nonaka " section size: %d", rsp->nvs_sectsz); 3420 1.1 nonaka } 3421 1.22 nonaka sc->sc_chim_szmax = 0; 3422 1.22 nonaka sc->sc_chim_cnt = 0; 3423 1.22 nonaka } else { 3424 1.22 nonaka sc->sc_chim_szmax = rsp->nvs_sectsz; 3425 1.22 nonaka sc->sc_chim_cnt = HVN_CHIM_SIZE / sc->sc_chim_szmax; 3426 1.1 nonaka } 3427 1.1 nonaka 3428 1.22 nonaka if (sc->sc_chim_szmax > 0) { 3429 1.22 nonaka if ((HVN_CHIM_SIZE % sc->sc_chim_szmax) != 0) { 3430 1.22 nonaka device_printf(sc->sc_dev, 3431 1.22 nonaka "chimney sending sections are not properly " 3432 1.22 nonaka "aligned\n"); 3433 1.22 nonaka } 3434 1.22 nonaka if ((sc->sc_chim_cnt % LONG_BIT) != 0) { 3435 1.22 nonaka device_printf(sc->sc_dev, 3436 1.22 nonaka "discard %d chimney sending sections\n", 3437 1.22 nonaka sc->sc_chim_cnt % LONG_BIT); 3438 1.22 nonaka } 3439 1.1 nonaka 3440 1.22 nonaka sc->sc_chim_bmap_cnt = sc->sc_chim_cnt / LONG_BIT; 3441 1.22 nonaka sc->sc_chim_bmap = kmem_zalloc(sc->sc_chim_bmap_cnt * 3442 1.22 nonaka sizeof(u_long), KM_SLEEP); 3443 1.22 nonaka } 3444 1.1 nonaka 3445 1.22 nonaka /* Done! */ 3446 1.22 nonaka SET(sc->sc_flags, HVN_SCF_CHIM_CONNECTED); 3447 1.1 nonaka 3448 1.22 nonaka aprint_verbose_dev(sc->sc_dev, "chimney sending buffer %d/%d\n", 3449 1.22 nonaka sc->sc_chim_szmax, sc->sc_chim_cnt); 3450 1.1 nonaka 3451 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3452 1.1 nonaka 3453 1.22 nonaka return 0; 3454 1.1 nonaka 3455 1.22 nonaka errout: 3456 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3457 1.22 nonaka hvn_nvs_disconnect_chim(sc); 3458 1.22 nonaka return -1; 3459 1.1 nonaka } 3460 1.1 nonaka 3461 1.1 nonaka static int 3462 1.22 nonaka hvn_nvs_disconnect_chim(struct hvn_softc *sc) 3463 1.1 nonaka { 3464 1.22 nonaka struct hvn_nvs_chim_disconn cmd; 3465 1.1 nonaka uint64_t tid; 3466 1.22 nonaka int s, error; 3467 1.1 nonaka 3468 1.22 nonaka if (ISSET(sc->sc_flags, HVN_SCF_CHIM_CONNECTED)) { 3469 1.22 nonaka memset(&cmd, 0, sizeof(cmd)); 3470 1.22 nonaka cmd.nvs_type = HVN_NVS_TYPE_CHIM_DISCONN; 3471 1.22 nonaka cmd.nvs_sig = HVN_NVS_CHIM_SIG; 3472 1.1 nonaka 3473 1.1 nonaka tid = atomic_inc_uint_nv(&sc->sc_nvstid); 3474 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3475 1.22 nonaka error = hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 3476 1.22 nonaka HVN_NVS_CMD_NORESP); 3477 1.22 nonaka if (error) { 3478 1.22 nonaka device_printf(sc->sc_dev, 3479 1.22 nonaka "failed to send chim disconn: %d", error); 3480 1.22 nonaka } 3481 1.22 nonaka CLR(sc->sc_flags, HVN_SCF_CHIM_CONNECTED); 3482 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3483 1.1 nonaka 3484 1.22 nonaka /* 3485 1.22 nonaka * Wait for the hypervisor to receive this NVS request. 3486 1.22 nonaka * 3487 1.22 nonaka * NOTE: 3488 1.22 nonaka * The TX bufring will not be drained by the hypervisor, 3489 1.22 nonaka * if the primary channel is revoked. 3490 1.22 nonaka */ 3491 1.22 nonaka while (!vmbus_channel_tx_empty(sc->sc_prichan) && 3492 1.22 nonaka !vmbus_channel_is_revoked(sc->sc_prichan)) { 3493 1.22 nonaka DELAY(20); 3494 1.22 nonaka s = splnet(); 3495 1.22 nonaka hvn_nvs_intr1(&sc->sc_rxr[0], sc->sc_tx_process_limit, 3496 1.22 nonaka sc->sc_rx_process_limit); 3497 1.22 nonaka splx(s); 3498 1.1 nonaka } 3499 1.22 nonaka /* 3500 1.22 nonaka * Linger long enough for NVS to disconnect chimney 3501 1.22 nonaka * sending buffer. 3502 1.22 nonaka */ 3503 1.22 nonaka DELAY(200); 3504 1.1 nonaka } 3505 1.22 nonaka 3506 1.22 nonaka if (sc->sc_prichan->ch_sc->sc_proto < VMBUS_VERSION_WIN10 && 3507 1.22 nonaka sc->sc_chim_hndl) { 3508 1.22 nonaka /* 3509 1.22 nonaka * Disconnect chimney sending buffer from primary channel. 3510 1.22 nonaka */ 3511 1.22 nonaka vmbus_handle_free(sc->sc_prichan, sc->sc_chim_hndl); 3512 1.22 nonaka sc->sc_chim_hndl = 0; 3513 1.1 nonaka } 3514 1.1 nonaka 3515 1.22 nonaka if (sc->sc_chim_bmap != NULL) { 3516 1.22 nonaka kmem_free(sc->sc_chim_bmap, sc->sc_chim_cnt / LONG_BIT); 3517 1.22 nonaka sc->sc_chim_bmap = NULL; 3518 1.22 nonaka sc->sc_chim_bmap_cnt = 0; 3519 1.1 nonaka } 3520 1.1 nonaka 3521 1.22 nonaka mutex_destroy(&sc->sc_chim_bmap_lock); 3522 1.1 nonaka 3523 1.1 nonaka return 0; 3524 1.1 nonaka } 3525 1.1 nonaka 3526 1.22 nonaka #define HVN_HANDLE_RING_DOTX __BIT(0) 3527 1.22 nonaka 3528 1.22 nonaka static int 3529 1.22 nonaka hvn_handle_ring(struct hvn_rx_ring *rxr, int txlimit, int rxlimit) 3530 1.1 nonaka { 3531 1.22 nonaka struct hvn_softc *sc = rxr->rxr_softc; 3532 1.1 nonaka struct vmbus_chanpkt_hdr *cph; 3533 1.1 nonaka const struct hvn_nvs_hdr *nvs; 3534 1.1 nonaka uint64_t rid; 3535 1.1 nonaka uint32_t rlen; 3536 1.22 nonaka int n, tx = 0, rx = 0; 3537 1.22 nonaka int result = 0; 3538 1.1 nonaka int rv; 3539 1.1 nonaka 3540 1.22 nonaka mutex_enter(&rxr->rxr_lock); 3541 1.1 nonaka for (;;) { 3542 1.22 nonaka rv = vmbus_channel_recv(rxr->rxr_chan, rxr->rxr_nvsbuf, 3543 1.1 nonaka HVN_NVS_BUFSIZE, &rlen, &rid, 1); 3544 1.1 nonaka if (rv != 0 || rlen == 0) { 3545 1.1 nonaka if (rv != EAGAIN) 3546 1.1 nonaka device_printf(sc->sc_dev, 3547 1.1 nonaka "failed to receive an NVSP packet\n"); 3548 1.1 nonaka break; 3549 1.1 nonaka } 3550 1.22 nonaka cph = (struct vmbus_chanpkt_hdr *)rxr->rxr_nvsbuf; 3551 1.1 nonaka nvs = (const struct hvn_nvs_hdr *)VMBUS_CHANPKT_CONST_DATA(cph); 3552 1.1 nonaka 3553 1.1 nonaka if (cph->cph_type == VMBUS_CHANPKT_TYPE_COMP) { 3554 1.1 nonaka switch (nvs->nvs_type) { 3555 1.1 nonaka case HVN_NVS_TYPE_INIT_RESP: 3556 1.1 nonaka case HVN_NVS_TYPE_RXBUF_CONNRESP: 3557 1.1 nonaka case HVN_NVS_TYPE_CHIM_CONNRESP: 3558 1.1 nonaka case HVN_NVS_TYPE_SUBCH_RESP: 3559 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3560 1.1 nonaka /* copy the response back */ 3561 1.1 nonaka memcpy(&sc->sc_nvsrsp, nvs, HVN_NVS_MSGSIZE); 3562 1.1 nonaka sc->sc_nvsdone = 1; 3563 1.22 nonaka cv_signal(&sc->sc_nvsrsp_cv); 3564 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3565 1.1 nonaka break; 3566 1.1 nonaka case HVN_NVS_TYPE_RNDIS_ACK: 3567 1.22 nonaka if (rxr->rxr_txr == NULL) 3568 1.22 nonaka break; 3569 1.22 nonaka 3570 1.22 nonaka result |= HVN_HANDLE_RING_DOTX; 3571 1.22 nonaka mutex_enter(&rxr->rxr_txr->txr_lock); 3572 1.22 nonaka hvn_txeof(rxr->rxr_txr, cph->cph_tid); 3573 1.22 nonaka mutex_exit(&rxr->rxr_txr->txr_lock); 3574 1.22 nonaka if (txlimit > 0 && ++tx >= txlimit) 3575 1.22 nonaka goto out; 3576 1.1 nonaka break; 3577 1.1 nonaka default: 3578 1.1 nonaka device_printf(sc->sc_dev, 3579 1.1 nonaka "unhandled NVSP packet type %u " 3580 1.1 nonaka "on completion\n", nvs->nvs_type); 3581 1.1 nonaka break; 3582 1.1 nonaka } 3583 1.1 nonaka } else if (cph->cph_type == VMBUS_CHANPKT_TYPE_RXBUF) { 3584 1.1 nonaka switch (nvs->nvs_type) { 3585 1.1 nonaka case HVN_NVS_TYPE_RNDIS: 3586 1.22 nonaka n = hvn_rndis_input(rxr, cph->cph_tid, cph); 3587 1.22 nonaka if (rxlimit > 0) { 3588 1.22 nonaka if (n < 0) 3589 1.22 nonaka goto out; 3590 1.22 nonaka rx += n; 3591 1.22 nonaka if (rx >= rxlimit) 3592 1.22 nonaka goto out; 3593 1.22 nonaka } 3594 1.1 nonaka break; 3595 1.1 nonaka default: 3596 1.1 nonaka device_printf(sc->sc_dev, 3597 1.1 nonaka "unhandled NVSP packet type %u " 3598 1.1 nonaka "on receive\n", nvs->nvs_type); 3599 1.1 nonaka break; 3600 1.1 nonaka } 3601 1.12 nonaka } else if (cph->cph_type == VMBUS_CHANPKT_TYPE_INBAND) { 3602 1.12 nonaka switch (nvs->nvs_type) { 3603 1.12 nonaka case HVN_NVS_TYPE_TXTBL_NOTE: 3604 1.12 nonaka /* Useless; ignore */ 3605 1.12 nonaka break; 3606 1.12 nonaka default: 3607 1.12 nonaka device_printf(sc->sc_dev, 3608 1.12 nonaka "got notify, nvs type %u\n", nvs->nvs_type); 3609 1.12 nonaka break; 3610 1.12 nonaka } 3611 1.1 nonaka } else 3612 1.1 nonaka device_printf(sc->sc_dev, 3613 1.1 nonaka "unknown NVSP packet type %u\n", cph->cph_type); 3614 1.1 nonaka } 3615 1.22 nonaka out: 3616 1.22 nonaka mutex_exit(&rxr->rxr_lock); 3617 1.22 nonaka 3618 1.22 nonaka return result; 3619 1.22 nonaka } 3620 1.22 nonaka 3621 1.22 nonaka static void 3622 1.22 nonaka hvn_nvs_intr1(struct hvn_rx_ring *rxr, int txlimit, int rxlimit) 3623 1.22 nonaka { 3624 1.22 nonaka struct hvn_softc *sc = rxr->rxr_softc; 3625 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 3626 1.22 nonaka struct hvn_tx_ring *txr = rxr->rxr_txr; 3627 1.22 nonaka int result; 3628 1.22 nonaka 3629 1.22 nonaka rxr->rxr_workqueue = sc->sc_txrx_workqueue; 3630 1.22 nonaka 3631 1.22 nonaka result = hvn_handle_ring(rxr, txlimit, rxlimit); 3632 1.22 nonaka 3633 1.22 nonaka if ((result & HVN_HANDLE_RING_DOTX) && txr != NULL) { 3634 1.22 nonaka mutex_enter(&txr->txr_lock); 3635 1.22 nonaka /* ALTQ */ 3636 1.22 nonaka if (txr->txr_id == 0) { 3637 1.22 nonaka if_schedule_deferred_start(ifp); 3638 1.22 nonaka } 3639 1.22 nonaka softint_schedule(txr->txr_si); 3640 1.22 nonaka mutex_exit(&txr->txr_lock); 3641 1.22 nonaka } 3642 1.22 nonaka } 3643 1.22 nonaka 3644 1.22 nonaka static void 3645 1.22 nonaka hvn_schedule_handle_ring(struct hvn_softc *sc, struct hvn_rx_ring *rxr, 3646 1.22 nonaka bool intr) 3647 1.22 nonaka { 3648 1.22 nonaka 3649 1.22 nonaka KASSERT(mutex_owned(&rxr->rxr_onwork_lock)); 3650 1.22 nonaka 3651 1.22 nonaka if (rxr->rxr_workqueue) { 3652 1.22 nonaka if (!rxr->rxr_onlist) { 3653 1.22 nonaka rxr->rxr_onlist = true; 3654 1.22 nonaka if (intr) 3655 1.22 nonaka rxr->rxr_evdeferreq.ev_count++; 3656 1.22 nonaka else 3657 1.22 nonaka rxr->rxr_evredeferreq.ev_count++; 3658 1.22 nonaka workqueue_enqueue(sc->sc_wq, &rxr->rxr_wk, NULL); 3659 1.22 nonaka } 3660 1.22 nonaka } else { 3661 1.22 nonaka rxr->rxr_onlist = true; 3662 1.22 nonaka if (intr) 3663 1.22 nonaka rxr->rxr_evdeferreq.ev_count++; 3664 1.22 nonaka else 3665 1.22 nonaka rxr->rxr_evredeferreq.ev_count++; 3666 1.22 nonaka softint_schedule(rxr->rxr_si); 3667 1.22 nonaka } 3668 1.22 nonaka } 3669 1.22 nonaka 3670 1.22 nonaka static void 3671 1.22 nonaka hvn_handle_ring_common(struct hvn_rx_ring *rxr) 3672 1.22 nonaka { 3673 1.22 nonaka struct hvn_softc *sc = rxr->rxr_softc; 3674 1.22 nonaka int txlimit = sc->sc_tx_process_limit; 3675 1.22 nonaka int rxlimit = sc->sc_rx_process_limit; 3676 1.22 nonaka 3677 1.22 nonaka rxr->rxr_evdefer.ev_count++; 3678 1.22 nonaka 3679 1.22 nonaka mutex_enter(&rxr->rxr_onwork_lock); 3680 1.22 nonaka rxr->rxr_onproc = true; 3681 1.22 nonaka rxr->rxr_onlist = false; 3682 1.22 nonaka mutex_exit(&rxr->rxr_onwork_lock); 3683 1.22 nonaka 3684 1.22 nonaka hvn_nvs_intr1(rxr, txlimit, rxlimit); 3685 1.22 nonaka 3686 1.22 nonaka mutex_enter(&rxr->rxr_onwork_lock); 3687 1.22 nonaka if (vmbus_channel_unpause(rxr->rxr_chan)) { 3688 1.22 nonaka vmbus_channel_pause(rxr->rxr_chan); 3689 1.22 nonaka hvn_schedule_handle_ring(sc, rxr, false); 3690 1.22 nonaka } 3691 1.22 nonaka rxr->rxr_onproc = false; 3692 1.22 nonaka cv_broadcast(&rxr->rxr_onwork_cv); 3693 1.22 nonaka mutex_exit(&rxr->rxr_onwork_lock); 3694 1.22 nonaka } 3695 1.22 nonaka 3696 1.22 nonaka static void 3697 1.22 nonaka hvn_handle_ring_work(struct work *wk, void *arg) 3698 1.22 nonaka { 3699 1.22 nonaka struct hvn_rx_ring *rxr = container_of(wk, struct hvn_rx_ring, rxr_wk); 3700 1.22 nonaka 3701 1.22 nonaka hvn_handle_ring_common(rxr); 3702 1.22 nonaka } 3703 1.22 nonaka 3704 1.22 nonaka static void 3705 1.22 nonaka hvn_nvs_softintr(void *arg) 3706 1.22 nonaka { 3707 1.22 nonaka struct hvn_rx_ring *rxr = arg; 3708 1.22 nonaka 3709 1.22 nonaka hvn_handle_ring_common(rxr); 3710 1.22 nonaka } 3711 1.22 nonaka 3712 1.22 nonaka static void 3713 1.22 nonaka hvn_nvs_intr(void *arg) 3714 1.22 nonaka { 3715 1.22 nonaka struct hvn_rx_ring *rxr = arg; 3716 1.22 nonaka struct hvn_softc *sc = rxr->rxr_softc; 3717 1.22 nonaka int txlimit = cold ? 0 : sc->sc_tx_intr_process_limit; 3718 1.22 nonaka int rxlimit = cold ? 0 : sc->sc_rx_intr_process_limit; 3719 1.22 nonaka 3720 1.22 nonaka rxr->rxr_evintr.ev_count++; 3721 1.22 nonaka 3722 1.22 nonaka KASSERT(!rxr->rxr_onproc); 3723 1.22 nonaka KASSERT(!rxr->rxr_onlist); 3724 1.1 nonaka 3725 1.22 nonaka vmbus_channel_pause(rxr->rxr_chan); 3726 1.22 nonaka 3727 1.22 nonaka hvn_nvs_intr1(rxr, txlimit, rxlimit); 3728 1.22 nonaka 3729 1.22 nonaka if (vmbus_channel_unpause(rxr->rxr_chan) && !cold) { 3730 1.22 nonaka vmbus_channel_pause(rxr->rxr_chan); 3731 1.22 nonaka mutex_enter(&rxr->rxr_onwork_lock); 3732 1.22 nonaka hvn_schedule_handle_ring(sc, rxr, true); 3733 1.22 nonaka mutex_exit(&rxr->rxr_onwork_lock); 3734 1.22 nonaka } 3735 1.1 nonaka } 3736 1.1 nonaka 3737 1.1 nonaka static int 3738 1.1 nonaka hvn_nvs_cmd(struct hvn_softc *sc, void *cmd, size_t cmdsize, uint64_t tid, 3739 1.22 nonaka u_int flags) 3740 1.1 nonaka { 3741 1.22 nonaka struct hvn_rx_ring *rxr = &sc->sc_rxr[0]; /* primary channel */ 3742 1.1 nonaka struct hvn_nvs_hdr *hdr = cmd; 3743 1.1 nonaka int tries = 10; 3744 1.1 nonaka int rv, s; 3745 1.1 nonaka 3746 1.22 nonaka KASSERT(mutex_owned(&sc->sc_nvsrsp_lock)); 3747 1.22 nonaka 3748 1.1 nonaka sc->sc_nvsdone = 0; 3749 1.1 nonaka 3750 1.1 nonaka do { 3751 1.22 nonaka rv = vmbus_channel_send(rxr->rxr_chan, cmd, cmdsize, 3752 1.1 nonaka tid, VMBUS_CHANPKT_TYPE_INBAND, 3753 1.22 nonaka ISSET(flags, HVN_NVS_CMD_NORESP) ? 0 : 3754 1.22 nonaka VMBUS_CHANPKT_FLAG_RC); 3755 1.1 nonaka if (rv == EAGAIN) { 3756 1.22 nonaka DELAY(1000); 3757 1.1 nonaka } else if (rv) { 3758 1.1 nonaka DPRINTF("%s: NVSP operation %u send error %d\n", 3759 1.1 nonaka device_xname(sc->sc_dev), hdr->nvs_type, rv); 3760 1.1 nonaka return rv; 3761 1.1 nonaka } 3762 1.1 nonaka } while (rv != 0 && --tries > 0); 3763 1.1 nonaka 3764 1.1 nonaka if (tries == 0 && rv != 0) { 3765 1.1 nonaka device_printf(sc->sc_dev, 3766 1.1 nonaka "NVSP operation %u send error %d\n", hdr->nvs_type, rv); 3767 1.1 nonaka return rv; 3768 1.1 nonaka } 3769 1.1 nonaka 3770 1.22 nonaka if (ISSET(flags, HVN_NVS_CMD_NORESP)) 3771 1.1 nonaka return 0; 3772 1.1 nonaka 3773 1.22 nonaka while (!sc->sc_nvsdone && !ISSET(sc->sc_flags, HVN_SCF_REVOKED)) { 3774 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3775 1.22 nonaka DELAY(1000); 3776 1.22 nonaka s = splnet(); 3777 1.22 nonaka hvn_nvs_intr1(rxr, 0, 0); 3778 1.22 nonaka splx(s); 3779 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3780 1.22 nonaka } 3781 1.1 nonaka 3782 1.1 nonaka return 0; 3783 1.1 nonaka } 3784 1.1 nonaka 3785 1.1 nonaka static int 3786 1.22 nonaka hvn_nvs_ack(struct hvn_rx_ring *rxr, uint64_t tid) 3787 1.1 nonaka { 3788 1.22 nonaka struct hvn_softc *sc __unused = rxr->rxr_softc; 3789 1.1 nonaka struct hvn_nvs_rndis_ack cmd; 3790 1.1 nonaka int tries = 5; 3791 1.1 nonaka int rv; 3792 1.1 nonaka 3793 1.1 nonaka cmd.nvs_type = HVN_NVS_TYPE_RNDIS_ACK; 3794 1.1 nonaka cmd.nvs_status = HVN_NVS_STATUS_OK; 3795 1.1 nonaka do { 3796 1.22 nonaka rv = vmbus_channel_send(rxr->rxr_chan, &cmd, sizeof(cmd), 3797 1.1 nonaka tid, VMBUS_CHANPKT_TYPE_COMP, 0); 3798 1.1 nonaka if (rv == EAGAIN) 3799 1.22 nonaka DELAY(10); 3800 1.1 nonaka else if (rv) { 3801 1.1 nonaka DPRINTF("%s: NVSP acknowledgement error %d\n", 3802 1.1 nonaka device_xname(sc->sc_dev), rv); 3803 1.1 nonaka return rv; 3804 1.1 nonaka } 3805 1.22 nonaka } while (rv != 0 && --tries > 0); 3806 1.22 nonaka return rv; 3807 1.22 nonaka } 3808 1.22 nonaka 3809 1.22 nonaka static void 3810 1.22 nonaka hvn_nvs_detach(struct hvn_softc *sc) 3811 1.22 nonaka { 3812 1.22 nonaka 3813 1.22 nonaka hvn_nvs_disconnect_rxbuf(sc); 3814 1.22 nonaka hvn_nvs_disconnect_chim(sc); 3815 1.22 nonaka } 3816 1.22 nonaka 3817 1.22 nonaka static int 3818 1.22 nonaka hvn_nvs_alloc_subchannels(struct hvn_softc *sc, int *nsubchp) 3819 1.22 nonaka { 3820 1.22 nonaka struct hvn_nvs_subch_req cmd; 3821 1.22 nonaka struct hvn_nvs_subch_resp *rsp; 3822 1.22 nonaka uint64_t tid; 3823 1.22 nonaka int nsubch, nsubch_req; 3824 1.22 nonaka 3825 1.22 nonaka nsubch_req = *nsubchp; 3826 1.22 nonaka KASSERTMSG(nsubch_req > 0, "invalid # of sub-channels %d", nsubch_req); 3827 1.22 nonaka 3828 1.22 nonaka memset(&cmd, 0, sizeof(cmd)); 3829 1.22 nonaka cmd.nvs_type = HVN_NVS_TYPE_SUBCH_REQ; 3830 1.22 nonaka cmd.nvs_op = HVN_NVS_SUBCH_OP_ALLOC; 3831 1.22 nonaka cmd.nvs_nsubch = nsubch_req; 3832 1.22 nonaka 3833 1.22 nonaka tid = atomic_inc_uint_nv(&sc->sc_nvstid); 3834 1.22 nonaka mutex_enter(&sc->sc_nvsrsp_lock); 3835 1.22 nonaka if (hvn_nvs_cmd(sc, &cmd, sizeof(cmd), tid, 0)) { 3836 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3837 1.22 nonaka return EIO; 3838 1.22 nonaka } 3839 1.22 nonaka 3840 1.22 nonaka rsp = (struct hvn_nvs_subch_resp *)&sc->sc_nvsrsp; 3841 1.22 nonaka if (rsp->nvs_status != HVN_NVS_STATUS_OK) { 3842 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3843 1.22 nonaka DPRINTF("%s: failed to alloc sub-channels\n", 3844 1.22 nonaka device_xname(sc->sc_dev)); 3845 1.22 nonaka return EIO; 3846 1.22 nonaka } 3847 1.22 nonaka 3848 1.22 nonaka nsubch = rsp->nvs_nsubch; 3849 1.22 nonaka if (nsubch > nsubch_req) { 3850 1.22 nonaka aprint_debug_dev(sc->sc_dev, 3851 1.22 nonaka "%u subchans are allocated, requested %d\n", 3852 1.22 nonaka nsubch, nsubch_req); 3853 1.22 nonaka nsubch = nsubch_req; 3854 1.22 nonaka } 3855 1.22 nonaka mutex_exit(&sc->sc_nvsrsp_lock); 3856 1.1 nonaka 3857 1.22 nonaka *nsubchp = nsubch; 3858 1.1 nonaka 3859 1.22 nonaka return 0; 3860 1.1 nonaka } 3861 1.1 nonaka 3862 1.1 nonaka static inline struct rndis_cmd * 3863 1.1 nonaka hvn_alloc_cmd(struct hvn_softc *sc) 3864 1.1 nonaka { 3865 1.1 nonaka struct rndis_cmd *rc; 3866 1.1 nonaka 3867 1.1 nonaka mutex_enter(&sc->sc_cntl_fqlck); 3868 1.1 nonaka while ((rc = TAILQ_FIRST(&sc->sc_cntl_fq)) == NULL) 3869 1.22 nonaka cv_wait(&sc->sc_cntl_fqcv, &sc->sc_cntl_fqlck); 3870 1.1 nonaka TAILQ_REMOVE(&sc->sc_cntl_fq, rc, rc_entry); 3871 1.1 nonaka mutex_exit(&sc->sc_cntl_fqlck); 3872 1.1 nonaka return rc; 3873 1.1 nonaka } 3874 1.1 nonaka 3875 1.1 nonaka static inline void 3876 1.1 nonaka hvn_submit_cmd(struct hvn_softc *sc, struct rndis_cmd *rc) 3877 1.1 nonaka { 3878 1.1 nonaka 3879 1.1 nonaka mutex_enter(&sc->sc_cntl_sqlck); 3880 1.1 nonaka TAILQ_INSERT_TAIL(&sc->sc_cntl_sq, rc, rc_entry); 3881 1.1 nonaka mutex_exit(&sc->sc_cntl_sqlck); 3882 1.1 nonaka } 3883 1.1 nonaka 3884 1.1 nonaka static inline struct rndis_cmd * 3885 1.1 nonaka hvn_complete_cmd(struct hvn_softc *sc, uint32_t id) 3886 1.1 nonaka { 3887 1.1 nonaka struct rndis_cmd *rc; 3888 1.1 nonaka 3889 1.1 nonaka mutex_enter(&sc->sc_cntl_sqlck); 3890 1.1 nonaka TAILQ_FOREACH(rc, &sc->sc_cntl_sq, rc_entry) { 3891 1.1 nonaka if (rc->rc_id == id) { 3892 1.1 nonaka TAILQ_REMOVE(&sc->sc_cntl_sq, rc, rc_entry); 3893 1.1 nonaka break; 3894 1.1 nonaka } 3895 1.1 nonaka } 3896 1.1 nonaka mutex_exit(&sc->sc_cntl_sqlck); 3897 1.1 nonaka if (rc != NULL) { 3898 1.1 nonaka mutex_enter(&sc->sc_cntl_cqlck); 3899 1.1 nonaka TAILQ_INSERT_TAIL(&sc->sc_cntl_cq, rc, rc_entry); 3900 1.1 nonaka mutex_exit(&sc->sc_cntl_cqlck); 3901 1.1 nonaka } 3902 1.1 nonaka return rc; 3903 1.1 nonaka } 3904 1.1 nonaka 3905 1.1 nonaka static inline void 3906 1.1 nonaka hvn_release_cmd(struct hvn_softc *sc, struct rndis_cmd *rc) 3907 1.1 nonaka { 3908 1.1 nonaka 3909 1.1 nonaka mutex_enter(&sc->sc_cntl_cqlck); 3910 1.1 nonaka TAILQ_REMOVE(&sc->sc_cntl_cq, rc, rc_entry); 3911 1.1 nonaka mutex_exit(&sc->sc_cntl_cqlck); 3912 1.1 nonaka } 3913 1.1 nonaka 3914 1.1 nonaka static inline int 3915 1.1 nonaka hvn_rollback_cmd(struct hvn_softc *sc, struct rndis_cmd *rc) 3916 1.1 nonaka { 3917 1.1 nonaka struct rndis_cmd *rn; 3918 1.1 nonaka 3919 1.1 nonaka mutex_enter(&sc->sc_cntl_sqlck); 3920 1.1 nonaka TAILQ_FOREACH(rn, &sc->sc_cntl_sq, rc_entry) { 3921 1.1 nonaka if (rn == rc) { 3922 1.1 nonaka TAILQ_REMOVE(&sc->sc_cntl_sq, rc, rc_entry); 3923 1.1 nonaka mutex_exit(&sc->sc_cntl_sqlck); 3924 1.1 nonaka return 0; 3925 1.1 nonaka } 3926 1.1 nonaka } 3927 1.1 nonaka mutex_exit(&sc->sc_cntl_sqlck); 3928 1.1 nonaka return -1; 3929 1.1 nonaka } 3930 1.1 nonaka 3931 1.1 nonaka static inline void 3932 1.1 nonaka hvn_free_cmd(struct hvn_softc *sc, struct rndis_cmd *rc) 3933 1.1 nonaka { 3934 1.1 nonaka 3935 1.1 nonaka memset(rc->rc_req, 0, sizeof(struct rndis_packet_msg)); 3936 1.1 nonaka memset(&rc->rc_cmp, 0, sizeof(rc->rc_cmp)); 3937 1.1 nonaka memset(&rc->rc_msg, 0, sizeof(rc->rc_msg)); 3938 1.1 nonaka mutex_enter(&sc->sc_cntl_fqlck); 3939 1.1 nonaka TAILQ_INSERT_TAIL(&sc->sc_cntl_fq, rc, rc_entry); 3940 1.22 nonaka cv_signal(&sc->sc_cntl_fqcv); 3941 1.1 nonaka mutex_exit(&sc->sc_cntl_fqlck); 3942 1.1 nonaka } 3943 1.1 nonaka 3944 1.1 nonaka static int 3945 1.22 nonaka hvn_rndis_init(struct hvn_softc *sc) 3946 1.1 nonaka { 3947 1.1 nonaka struct rndis_cmd *rc; 3948 1.22 nonaka int i; 3949 1.1 nonaka 3950 1.1 nonaka /* RNDIS control message queues */ 3951 1.1 nonaka TAILQ_INIT(&sc->sc_cntl_sq); 3952 1.1 nonaka TAILQ_INIT(&sc->sc_cntl_cq); 3953 1.1 nonaka TAILQ_INIT(&sc->sc_cntl_fq); 3954 1.1 nonaka mutex_init(&sc->sc_cntl_sqlck, MUTEX_DEFAULT, IPL_NET); 3955 1.1 nonaka mutex_init(&sc->sc_cntl_cqlck, MUTEX_DEFAULT, IPL_NET); 3956 1.1 nonaka mutex_init(&sc->sc_cntl_fqlck, MUTEX_DEFAULT, IPL_NET); 3957 1.22 nonaka cv_init(&sc->sc_cntl_fqcv, "nvsalloc"); 3958 1.1 nonaka 3959 1.1 nonaka for (i = 0; i < HVN_RNDIS_CTLREQS; i++) { 3960 1.1 nonaka rc = &sc->sc_cntl_msgs[i]; 3961 1.1 nonaka if (bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0, 3962 1.22 nonaka BUS_DMA_WAITOK, &rc->rc_dmap)) { 3963 1.1 nonaka DPRINTF("%s: failed to create RNDIS command map\n", 3964 1.1 nonaka device_xname(sc->sc_dev)); 3965 1.1 nonaka goto errout; 3966 1.1 nonaka } 3967 1.1 nonaka if (bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 3968 1.22 nonaka 0, &rc->rc_segs, 1, &rc->rc_nsegs, BUS_DMA_WAITOK)) { 3969 1.1 nonaka DPRINTF("%s: failed to allocate RNDIS command\n", 3970 1.1 nonaka device_xname(sc->sc_dev)); 3971 1.1 nonaka bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap); 3972 1.1 nonaka goto errout; 3973 1.1 nonaka } 3974 1.1 nonaka if (bus_dmamem_map(sc->sc_dmat, &rc->rc_segs, rc->rc_nsegs, 3975 1.22 nonaka PAGE_SIZE, (void **)&rc->rc_req, BUS_DMA_WAITOK)) { 3976 1.1 nonaka DPRINTF("%s: failed to allocate RNDIS command\n", 3977 1.1 nonaka device_xname(sc->sc_dev)); 3978 1.1 nonaka bus_dmamem_free(sc->sc_dmat, &rc->rc_segs, 3979 1.1 nonaka rc->rc_nsegs); 3980 1.1 nonaka bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap); 3981 1.1 nonaka goto errout; 3982 1.1 nonaka } 3983 1.1 nonaka memset(rc->rc_req, 0, PAGE_SIZE); 3984 1.1 nonaka if (bus_dmamap_load(sc->sc_dmat, rc->rc_dmap, rc->rc_req, 3985 1.22 nonaka PAGE_SIZE, NULL, BUS_DMA_WAITOK)) { 3986 1.1 nonaka DPRINTF("%s: failed to load RNDIS command map\n", 3987 1.1 nonaka device_xname(sc->sc_dev)); 3988 1.23 rin bus_dmamem_unmap(sc->sc_dmat, rc->rc_req, PAGE_SIZE); 3989 1.23 rin rc->rc_req = NULL; 3990 1.1 nonaka bus_dmamem_free(sc->sc_dmat, &rc->rc_segs, 3991 1.1 nonaka rc->rc_nsegs); 3992 1.1 nonaka bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap); 3993 1.1 nonaka goto errout; 3994 1.1 nonaka } 3995 1.1 nonaka rc->rc_gpa = atop(rc->rc_dmap->dm_segs[0].ds_addr); 3996 1.22 nonaka mutex_init(&rc->rc_lock, MUTEX_DEFAULT, IPL_NET); 3997 1.22 nonaka cv_init(&rc->rc_cv, "rndiscmd"); 3998 1.1 nonaka TAILQ_INSERT_TAIL(&sc->sc_cntl_fq, rc, rc_entry); 3999 1.1 nonaka } 4000 1.1 nonaka 4001 1.22 nonaka /* Initialize RNDIS Data command */ 4002 1.22 nonaka memset(&sc->sc_data_msg, 0, sizeof(sc->sc_data_msg)); 4003 1.22 nonaka sc->sc_data_msg.nvs_type = HVN_NVS_TYPE_RNDIS; 4004 1.22 nonaka sc->sc_data_msg.nvs_rndis_mtype = HVN_NVS_RNDIS_MTYPE_DATA; 4005 1.22 nonaka sc->sc_data_msg.nvs_chim_idx = HVN_NVS_CHIM_IDX_INVALID; 4006 1.22 nonaka 4007 1.22 nonaka return 0; 4008 1.22 nonaka 4009 1.22 nonaka errout: 4010 1.22 nonaka hvn_rndis_destroy(sc); 4011 1.22 nonaka return -1; 4012 1.22 nonaka } 4013 1.22 nonaka 4014 1.22 nonaka static void 4015 1.22 nonaka hvn_rndis_destroy(struct hvn_softc *sc) 4016 1.22 nonaka { 4017 1.22 nonaka struct rndis_cmd *rc; 4018 1.22 nonaka int i; 4019 1.22 nonaka 4020 1.22 nonaka for (i = 0; i < HVN_RNDIS_CTLREQS; i++) { 4021 1.22 nonaka rc = &sc->sc_cntl_msgs[i]; 4022 1.22 nonaka if (rc->rc_req == NULL) 4023 1.22 nonaka continue; 4024 1.22 nonaka 4025 1.22 nonaka TAILQ_REMOVE(&sc->sc_cntl_fq, rc, rc_entry); 4026 1.23 rin bus_dmamap_unload(sc->sc_dmat, rc->rc_dmap); 4027 1.23 rin bus_dmamem_unmap(sc->sc_dmat, rc->rc_req, PAGE_SIZE); 4028 1.23 rin rc->rc_req = NULL; 4029 1.22 nonaka bus_dmamem_free(sc->sc_dmat, &rc->rc_segs, rc->rc_nsegs); 4030 1.22 nonaka bus_dmamap_destroy(sc->sc_dmat, rc->rc_dmap); 4031 1.22 nonaka mutex_destroy(&rc->rc_lock); 4032 1.22 nonaka cv_destroy(&rc->rc_cv); 4033 1.22 nonaka } 4034 1.22 nonaka 4035 1.22 nonaka mutex_destroy(&sc->sc_cntl_sqlck); 4036 1.22 nonaka mutex_destroy(&sc->sc_cntl_cqlck); 4037 1.22 nonaka mutex_destroy(&sc->sc_cntl_fqlck); 4038 1.22 nonaka cv_destroy(&sc->sc_cntl_fqcv); 4039 1.22 nonaka } 4040 1.22 nonaka 4041 1.22 nonaka static int 4042 1.22 nonaka hvn_rndis_attach(struct hvn_softc *sc, int mtu) 4043 1.22 nonaka { 4044 1.22 nonaka struct rndis_init_req *req; 4045 1.22 nonaka struct rndis_init_comp *cmp; 4046 1.22 nonaka struct rndis_cmd *rc; 4047 1.22 nonaka int rv; 4048 1.22 nonaka 4049 1.1 nonaka rc = hvn_alloc_cmd(sc); 4050 1.1 nonaka 4051 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 4052 1.1 nonaka BUS_DMASYNC_PREREAD); 4053 1.1 nonaka 4054 1.1 nonaka rc->rc_id = atomic_inc_uint_nv(&sc->sc_rndisrid); 4055 1.1 nonaka 4056 1.1 nonaka req = rc->rc_req; 4057 1.1 nonaka req->rm_type = REMOTE_NDIS_INITIALIZE_MSG; 4058 1.1 nonaka req->rm_len = sizeof(*req); 4059 1.1 nonaka req->rm_rid = rc->rc_id; 4060 1.1 nonaka req->rm_ver_major = RNDIS_VERSION_MAJOR; 4061 1.1 nonaka req->rm_ver_minor = RNDIS_VERSION_MINOR; 4062 1.1 nonaka req->rm_max_xfersz = HVN_RNDIS_XFER_SIZE; 4063 1.1 nonaka 4064 1.1 nonaka rc->rc_cmplen = sizeof(*cmp); 4065 1.1 nonaka 4066 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 4067 1.1 nonaka BUS_DMASYNC_PREWRITE); 4068 1.1 nonaka 4069 1.22 nonaka if ((rv = hvn_rndis_cmd(sc, rc, 0)) != 0) { 4070 1.1 nonaka DPRINTF("%s: INITIALIZE_MSG failed, error %d\n", 4071 1.1 nonaka device_xname(sc->sc_dev), rv); 4072 1.1 nonaka hvn_free_cmd(sc, rc); 4073 1.22 nonaka return -1; 4074 1.1 nonaka } 4075 1.1 nonaka cmp = (struct rndis_init_comp *)&rc->rc_cmp; 4076 1.1 nonaka if (cmp->rm_status != RNDIS_STATUS_SUCCESS) { 4077 1.1 nonaka DPRINTF("%s: failed to init RNDIS, error %#x\n", 4078 1.1 nonaka device_xname(sc->sc_dev), cmp->rm_status); 4079 1.1 nonaka hvn_free_cmd(sc, rc); 4080 1.22 nonaka return -1; 4081 1.1 nonaka } 4082 1.1 nonaka 4083 1.22 nonaka sc->sc_rndis_agg_size = cmp->rm_pktmaxsz; 4084 1.22 nonaka sc->sc_rndis_agg_pkts = cmp->rm_pktmaxcnt; 4085 1.22 nonaka sc->sc_rndis_agg_align = __BIT(cmp->rm_align); 4086 1.22 nonaka 4087 1.22 nonaka if (sc->sc_rndis_agg_align < sizeof(uint32_t)) { 4088 1.22 nonaka /* 4089 1.25 andvar * The RNDIS packet message encap assumes that the RNDIS 4090 1.22 nonaka * packet message is at least 4 bytes aligned. Fix up the 4091 1.22 nonaka * alignment here, if the remote side sets the alignment 4092 1.22 nonaka * too low. 4093 1.22 nonaka */ 4094 1.22 nonaka aprint_verbose_dev(sc->sc_dev, 4095 1.22 nonaka "fixup RNDIS aggpkt align: %u -> %zu\n", 4096 1.22 nonaka sc->sc_rndis_agg_align, sizeof(uint32_t)); 4097 1.22 nonaka sc->sc_rndis_agg_align = sizeof(uint32_t); 4098 1.22 nonaka } 4099 1.22 nonaka 4100 1.22 nonaka aprint_verbose_dev(sc->sc_dev, 4101 1.22 nonaka "RNDIS ver %u.%u, aggpkt size %u, aggpkt cnt %u, aggpkt align %u\n", 4102 1.22 nonaka cmp->rm_ver_major, cmp->rm_ver_minor, sc->sc_rndis_agg_size, 4103 1.22 nonaka sc->sc_rndis_agg_pkts, sc->sc_rndis_agg_align); 4104 1.22 nonaka 4105 1.1 nonaka hvn_free_cmd(sc, rc); 4106 1.1 nonaka 4107 1.22 nonaka return 0; 4108 1.22 nonaka } 4109 1.22 nonaka 4110 1.22 nonaka static int 4111 1.22 nonaka hvn_get_rsscaps(struct hvn_softc *sc, int *nrxr) 4112 1.22 nonaka { 4113 1.22 nonaka struct ndis_rss_caps in, caps; 4114 1.22 nonaka size_t caps_len; 4115 1.22 nonaka int error, rxr_cnt, indsz, hash_fnidx; 4116 1.22 nonaka uint32_t hash_func = 0, hash_types = 0; 4117 1.22 nonaka 4118 1.22 nonaka *nrxr = 0; 4119 1.22 nonaka 4120 1.22 nonaka if (sc->sc_ndisver < NDIS_VERSION_6_20) 4121 1.22 nonaka return EOPNOTSUPP; 4122 1.22 nonaka 4123 1.22 nonaka memset(&in, 0, sizeof(in)); 4124 1.22 nonaka in.ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_CAPS; 4125 1.22 nonaka in.ndis_hdr.ndis_rev = NDIS_RSS_CAPS_REV_2; 4126 1.22 nonaka in.ndis_hdr.ndis_size = NDIS_RSS_CAPS_SIZE; 4127 1.22 nonaka 4128 1.22 nonaka caps_len = NDIS_RSS_CAPS_SIZE; 4129 1.22 nonaka error = hvn_rndis_query2(sc, OID_GEN_RECEIVE_SCALE_CAPABILITIES, 4130 1.22 nonaka &in, NDIS_RSS_CAPS_SIZE, &caps, &caps_len, NDIS_RSS_CAPS_SIZE_6_0); 4131 1.22 nonaka if (error) 4132 1.22 nonaka return error; 4133 1.22 nonaka 4134 1.22 nonaka /* 4135 1.22 nonaka * Preliminary verification. 4136 1.22 nonaka */ 4137 1.22 nonaka if (caps.ndis_hdr.ndis_type != NDIS_OBJTYPE_RSS_CAPS) { 4138 1.22 nonaka DPRINTF("%s: invalid NDIS objtype 0x%02x\n", 4139 1.22 nonaka device_xname(sc->sc_dev), caps.ndis_hdr.ndis_type); 4140 1.22 nonaka return EINVAL; 4141 1.22 nonaka } 4142 1.22 nonaka if (caps.ndis_hdr.ndis_rev < NDIS_RSS_CAPS_REV_1) { 4143 1.22 nonaka DPRINTF("%s: invalid NDIS objrev 0x%02x\n", 4144 1.22 nonaka device_xname(sc->sc_dev), caps.ndis_hdr.ndis_rev); 4145 1.22 nonaka return EINVAL; 4146 1.22 nonaka } 4147 1.22 nonaka if (caps.ndis_hdr.ndis_size > caps_len) { 4148 1.22 nonaka DPRINTF("%s: invalid NDIS objsize %u, data size %zu\n", 4149 1.22 nonaka device_xname(sc->sc_dev), caps.ndis_hdr.ndis_size, 4150 1.22 nonaka caps_len); 4151 1.22 nonaka return EINVAL; 4152 1.22 nonaka } else if (caps.ndis_hdr.ndis_size < NDIS_RSS_CAPS_SIZE_6_0) { 4153 1.22 nonaka DPRINTF("%s: invalid NDIS objsize %u\n", 4154 1.22 nonaka device_xname(sc->sc_dev), caps.ndis_hdr.ndis_size); 4155 1.22 nonaka return EINVAL; 4156 1.22 nonaka } 4157 1.22 nonaka 4158 1.22 nonaka /* 4159 1.22 nonaka * Save information for later RSS configuration. 4160 1.22 nonaka */ 4161 1.22 nonaka if (caps.ndis_nrxr == 0) { 4162 1.22 nonaka DPRINTF("%s: 0 RX rings!?\n", device_xname(sc->sc_dev)); 4163 1.22 nonaka return EINVAL; 4164 1.22 nonaka } 4165 1.22 nonaka rxr_cnt = caps.ndis_nrxr; 4166 1.22 nonaka aprint_debug_dev(sc->sc_dev, "%u Rx rings\n", rxr_cnt); 4167 1.22 nonaka 4168 1.22 nonaka if (caps.ndis_hdr.ndis_size == NDIS_RSS_CAPS_SIZE && 4169 1.22 nonaka caps.ndis_hdr.ndis_rev >= NDIS_RSS_CAPS_REV_2) { 4170 1.22 nonaka if (caps.ndis_nind > NDIS_HASH_INDCNT) { 4171 1.22 nonaka DPRINTF("%s: too many RSS indirect table entries %u\n", 4172 1.22 nonaka device_xname(sc->sc_dev), caps.ndis_nind); 4173 1.22 nonaka return EOPNOTSUPP; 4174 1.22 nonaka } 4175 1.22 nonaka if (!powerof2(caps.ndis_nind)) { 4176 1.22 nonaka DPRINTF("%s: RSS indirect table size is not power-of-2:" 4177 1.22 nonaka " %u\n", device_xname(sc->sc_dev), caps.ndis_nind); 4178 1.22 nonaka return EOPNOTSUPP; 4179 1.22 nonaka } 4180 1.22 nonaka 4181 1.22 nonaka indsz = caps.ndis_nind; 4182 1.22 nonaka } else { 4183 1.22 nonaka indsz = NDIS_HASH_INDCNT; 4184 1.22 nonaka } 4185 1.22 nonaka if (rxr_cnt > indsz) { 4186 1.22 nonaka aprint_debug_dev(sc->sc_dev, 4187 1.22 nonaka "# of RX rings (%u) > RSS indirect table size %u\n", 4188 1.22 nonaka rxr_cnt, indsz); 4189 1.22 nonaka rxr_cnt = indsz; 4190 1.22 nonaka } 4191 1.22 nonaka 4192 1.22 nonaka /* 4193 1.22 nonaka * NOTE: 4194 1.22 nonaka * Toeplitz is at the lowest bit, and it is prefered; so ffs(), 4195 1.22 nonaka * instead of fls(), is used here. 4196 1.22 nonaka */ 4197 1.22 nonaka hash_fnidx = ffs(caps.ndis_caps & NDIS_RSS_CAP_HASHFUNC_MASK); 4198 1.22 nonaka if (hash_fnidx == 0) { 4199 1.22 nonaka DPRINTF("%s: no hash functions, caps 0x%08x\n", 4200 1.22 nonaka device_xname(sc->sc_dev), caps.ndis_caps); 4201 1.22 nonaka return EOPNOTSUPP; 4202 1.22 nonaka } 4203 1.22 nonaka hash_func = 1 << (hash_fnidx - 1); /* ffs is 1-based */ 4204 1.22 nonaka 4205 1.22 nonaka if (caps.ndis_caps & NDIS_RSS_CAP_IPV4) 4206 1.22 nonaka hash_types |= NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4; 4207 1.22 nonaka if (caps.ndis_caps & NDIS_RSS_CAP_IPV6) 4208 1.22 nonaka hash_types |= NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6; 4209 1.22 nonaka if (caps.ndis_caps & NDIS_RSS_CAP_IPV6_EX) 4210 1.22 nonaka hash_types |= NDIS_HASH_IPV6_EX | NDIS_HASH_TCP_IPV6_EX; 4211 1.22 nonaka if (hash_types == 0) { 4212 1.22 nonaka DPRINTF("%s: no hash types, caps 0x%08x\n", 4213 1.22 nonaka device_xname(sc->sc_dev), caps.ndis_caps); 4214 1.22 nonaka return EOPNOTSUPP; 4215 1.22 nonaka } 4216 1.22 nonaka aprint_debug_dev(sc->sc_dev, "RSS caps %#x\n", caps.ndis_caps); 4217 1.22 nonaka 4218 1.22 nonaka sc->sc_rss_ind_size = indsz; 4219 1.22 nonaka sc->sc_rss_hcap = hash_func | hash_types; 4220 1.22 nonaka if (sc->sc_caps & HVN_CAPS_UDPHASH) { 4221 1.22 nonaka /* UDP 4-tuple hash is unconditionally enabled. */ 4222 1.22 nonaka sc->sc_rss_hcap |= NDIS_HASH_UDP_IPV4_X; 4223 1.22 nonaka } 4224 1.22 nonaka *nrxr = rxr_cnt; 4225 1.1 nonaka 4226 1.1 nonaka return 0; 4227 1.22 nonaka } 4228 1.22 nonaka 4229 1.22 nonaka static int 4230 1.22 nonaka hvn_set_rss(struct hvn_softc *sc, uint16_t flags) 4231 1.22 nonaka { 4232 1.22 nonaka struct ndis_rssprm_toeplitz *rss = &sc->sc_rss; 4233 1.22 nonaka struct ndis_rss_params *params = &rss->rss_params; 4234 1.22 nonaka int len; 4235 1.22 nonaka 4236 1.22 nonaka /* 4237 1.22 nonaka * Only NDIS 6.20+ is supported: 4238 1.22 nonaka * We only support 4bytes element in indirect table, which has been 4239 1.22 nonaka * adopted since NDIS 6.20. 4240 1.22 nonaka */ 4241 1.22 nonaka if (sc->sc_ndisver < NDIS_VERSION_6_20) 4242 1.22 nonaka return 0; 4243 1.22 nonaka 4244 1.22 nonaka /* XXX only one can be specified through, popcnt? */ 4245 1.22 nonaka KASSERTMSG((sc->sc_rss_hash & NDIS_HASH_FUNCTION_MASK), 4246 1.22 nonaka "no hash func %08x", sc->sc_rss_hash); 4247 1.22 nonaka KASSERTMSG((sc->sc_rss_hash & NDIS_HASH_STD), 4248 1.22 nonaka "no standard hash types %08x", sc->sc_rss_hash); 4249 1.22 nonaka KASSERTMSG(sc->sc_rss_ind_size > 0, "no indirect table size"); 4250 1.22 nonaka 4251 1.22 nonaka aprint_debug_dev(sc->sc_dev, "RSS indirect table size %d, hash %#x\n", 4252 1.22 nonaka sc->sc_rss_ind_size, sc->sc_rss_hash); 4253 1.22 nonaka 4254 1.22 nonaka len = NDIS_RSSPRM_TOEPLITZ_SIZE(sc->sc_rss_ind_size); 4255 1.22 nonaka 4256 1.22 nonaka memset(params, 0, sizeof(*params)); 4257 1.22 nonaka params->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS; 4258 1.22 nonaka params->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2; 4259 1.22 nonaka params->ndis_hdr.ndis_size = len; 4260 1.22 nonaka params->ndis_flags = flags; 4261 1.22 nonaka params->ndis_hash = 4262 1.22 nonaka sc->sc_rss_hash & (NDIS_HASH_FUNCTION_MASK | NDIS_HASH_STD); 4263 1.22 nonaka params->ndis_indsize = sizeof(rss->rss_ind[0]) * sc->sc_rss_ind_size; 4264 1.22 nonaka params->ndis_indoffset = 4265 1.22 nonaka offsetof(struct ndis_rssprm_toeplitz, rss_ind[0]); 4266 1.22 nonaka params->ndis_keysize = sizeof(rss->rss_key); 4267 1.22 nonaka params->ndis_keyoffset = 4268 1.22 nonaka offsetof(struct ndis_rssprm_toeplitz, rss_key[0]); 4269 1.22 nonaka 4270 1.22 nonaka return hvn_rndis_set(sc, OID_GEN_RECEIVE_SCALE_PARAMETERS, rss, len); 4271 1.22 nonaka } 4272 1.22 nonaka 4273 1.22 nonaka static void 4274 1.22 nonaka hvn_fixup_rss_ind(struct hvn_softc *sc) 4275 1.22 nonaka { 4276 1.22 nonaka struct ndis_rssprm_toeplitz *rss = &sc->sc_rss; 4277 1.22 nonaka int i, nchan; 4278 1.22 nonaka 4279 1.22 nonaka nchan = sc->sc_nrxr_inuse; 4280 1.22 nonaka KASSERTMSG(nchan > 1, "invalid # of channels %d", nchan); 4281 1.22 nonaka 4282 1.22 nonaka /* 4283 1.22 nonaka * Check indirect table to make sure that all channels in it 4284 1.22 nonaka * can be used. 4285 1.22 nonaka */ 4286 1.22 nonaka for (i = 0; i < NDIS_HASH_INDCNT; i++) { 4287 1.22 nonaka if (rss->rss_ind[i] >= nchan) { 4288 1.22 nonaka DPRINTF("%s: RSS indirect table %d fixup: %u -> %d\n", 4289 1.22 nonaka device_xname(sc->sc_dev), i, rss->rss_ind[i], 4290 1.22 nonaka nchan - 1); 4291 1.22 nonaka rss->rss_ind[i] = nchan - 1; 4292 1.22 nonaka } 4293 1.22 nonaka } 4294 1.22 nonaka } 4295 1.22 nonaka 4296 1.22 nonaka static int 4297 1.22 nonaka hvn_get_hwcaps(struct hvn_softc *sc, struct ndis_offload *caps) 4298 1.22 nonaka { 4299 1.22 nonaka struct ndis_offload in; 4300 1.22 nonaka size_t caps_len, len; 4301 1.22 nonaka int error; 4302 1.1 nonaka 4303 1.22 nonaka memset(&in, 0, sizeof(in)); 4304 1.22 nonaka in.ndis_hdr.ndis_type = NDIS_OBJTYPE_OFFLOAD; 4305 1.22 nonaka if (sc->sc_ndisver >= NDIS_VERSION_6_30) { 4306 1.22 nonaka in.ndis_hdr.ndis_rev = NDIS_OFFLOAD_REV_3; 4307 1.22 nonaka len = in.ndis_hdr.ndis_size = NDIS_OFFLOAD_SIZE; 4308 1.22 nonaka } else if (sc->sc_ndisver >= NDIS_VERSION_6_1) { 4309 1.22 nonaka in.ndis_hdr.ndis_rev = NDIS_OFFLOAD_REV_2; 4310 1.22 nonaka len = in.ndis_hdr.ndis_size = NDIS_OFFLOAD_SIZE_6_1; 4311 1.22 nonaka } else { 4312 1.22 nonaka in.ndis_hdr.ndis_rev = NDIS_OFFLOAD_REV_1; 4313 1.22 nonaka len = in.ndis_hdr.ndis_size = NDIS_OFFLOAD_SIZE_6_0; 4314 1.1 nonaka } 4315 1.22 nonaka 4316 1.22 nonaka caps_len = NDIS_OFFLOAD_SIZE; 4317 1.22 nonaka error = hvn_rndis_query2(sc, OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES, 4318 1.22 nonaka &in, len, caps, &caps_len, NDIS_OFFLOAD_SIZE_6_0); 4319 1.22 nonaka if (error) 4320 1.22 nonaka return error; 4321 1.22 nonaka 4322 1.22 nonaka /* 4323 1.22 nonaka * Preliminary verification. 4324 1.22 nonaka */ 4325 1.22 nonaka if (caps->ndis_hdr.ndis_type != NDIS_OBJTYPE_OFFLOAD) { 4326 1.22 nonaka DPRINTF("%s: invalid NDIS objtype 0x%02x\n", 4327 1.22 nonaka device_xname(sc->sc_dev), caps->ndis_hdr.ndis_type); 4328 1.22 nonaka return EINVAL; 4329 1.22 nonaka } 4330 1.22 nonaka if (caps->ndis_hdr.ndis_rev < NDIS_OFFLOAD_REV_1) { 4331 1.22 nonaka DPRINTF("%s: invalid NDIS objrev 0x%02x\n", 4332 1.22 nonaka device_xname(sc->sc_dev), caps->ndis_hdr.ndis_rev); 4333 1.22 nonaka return EINVAL; 4334 1.22 nonaka } 4335 1.22 nonaka if (caps->ndis_hdr.ndis_size > caps_len) { 4336 1.22 nonaka DPRINTF("%s: invalid NDIS objsize %u, data size %zu\n", 4337 1.22 nonaka device_xname(sc->sc_dev), caps->ndis_hdr.ndis_size, 4338 1.22 nonaka caps_len); 4339 1.22 nonaka return EINVAL; 4340 1.22 nonaka } else if (caps->ndis_hdr.ndis_size < NDIS_OFFLOAD_SIZE_6_0) { 4341 1.22 nonaka DPRINTF("%s: invalid NDIS objsize %u\n", 4342 1.22 nonaka device_xname(sc->sc_dev), caps->ndis_hdr.ndis_size); 4343 1.22 nonaka return EINVAL; 4344 1.22 nonaka } 4345 1.22 nonaka 4346 1.22 nonaka /* 4347 1.22 nonaka * NOTE: 4348 1.22 nonaka * caps->ndis_hdr.ndis_size MUST be checked before accessing 4349 1.22 nonaka * NDIS 6.1+ specific fields. 4350 1.22 nonaka */ 4351 1.22 nonaka aprint_debug_dev(sc->sc_dev, "hwcaps rev %u\n", 4352 1.22 nonaka caps->ndis_hdr.ndis_rev); 4353 1.22 nonaka 4354 1.22 nonaka aprint_debug_dev(sc->sc_dev, "hwcaps csum: " 4355 1.22 nonaka "ip4 tx 0x%x/0x%x rx 0x%x/0x%x, " 4356 1.22 nonaka "ip6 tx 0x%x/0x%x rx 0x%x/0x%x\n", 4357 1.22 nonaka caps->ndis_csum.ndis_ip4_txcsum, caps->ndis_csum.ndis_ip4_txenc, 4358 1.22 nonaka caps->ndis_csum.ndis_ip4_rxcsum, caps->ndis_csum.ndis_ip4_rxenc, 4359 1.22 nonaka caps->ndis_csum.ndis_ip6_txcsum, caps->ndis_csum.ndis_ip6_txenc, 4360 1.22 nonaka caps->ndis_csum.ndis_ip6_rxcsum, caps->ndis_csum.ndis_ip6_rxenc); 4361 1.22 nonaka aprint_debug_dev(sc->sc_dev, "hwcaps lsov2: " 4362 1.22 nonaka "ip4 maxsz %u minsg %u encap 0x%x, " 4363 1.22 nonaka "ip6 maxsz %u minsg %u encap 0x%x opts 0x%x\n", 4364 1.22 nonaka caps->ndis_lsov2.ndis_ip4_maxsz, caps->ndis_lsov2.ndis_ip4_minsg, 4365 1.22 nonaka caps->ndis_lsov2.ndis_ip4_encap, caps->ndis_lsov2.ndis_ip6_maxsz, 4366 1.22 nonaka caps->ndis_lsov2.ndis_ip6_minsg, caps->ndis_lsov2.ndis_ip6_encap, 4367 1.22 nonaka caps->ndis_lsov2.ndis_ip6_opts); 4368 1.22 nonaka 4369 1.22 nonaka return 0; 4370 1.1 nonaka } 4371 1.1 nonaka 4372 1.1 nonaka static int 4373 1.22 nonaka hvn_set_capabilities(struct hvn_softc *sc, int mtu) 4374 1.1 nonaka { 4375 1.22 nonaka struct ndis_offload hwcaps; 4376 1.1 nonaka struct ndis_offload_params params; 4377 1.22 nonaka size_t len; 4378 1.22 nonaka uint32_t caps = 0; 4379 1.22 nonaka int error, tso_maxsz, tso_minsg; 4380 1.22 nonaka 4381 1.22 nonaka error = hvn_get_hwcaps(sc, &hwcaps); 4382 1.22 nonaka if (error) { 4383 1.22 nonaka DPRINTF("%s: failed to query hwcaps\n", 4384 1.22 nonaka device_xname(sc->sc_dev)); 4385 1.22 nonaka return error; 4386 1.22 nonaka } 4387 1.1 nonaka 4388 1.22 nonaka /* NOTE: 0 means "no change" */ 4389 1.1 nonaka memset(¶ms, 0, sizeof(params)); 4390 1.1 nonaka 4391 1.1 nonaka params.ndis_hdr.ndis_type = NDIS_OBJTYPE_DEFAULT; 4392 1.1 nonaka if (sc->sc_ndisver < NDIS_VERSION_6_30) { 4393 1.1 nonaka params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_2; 4394 1.1 nonaka len = params.ndis_hdr.ndis_size = NDIS_OFFLOAD_PARAMS_SIZE_6_1; 4395 1.1 nonaka } else { 4396 1.1 nonaka params.ndis_hdr.ndis_rev = NDIS_OFFLOAD_PARAMS_REV_3; 4397 1.1 nonaka len = params.ndis_hdr.ndis_size = NDIS_OFFLOAD_PARAMS_SIZE; 4398 1.1 nonaka } 4399 1.1 nonaka 4400 1.22 nonaka /* 4401 1.22 nonaka * TSO4/TSO6 setup. 4402 1.22 nonaka */ 4403 1.22 nonaka tso_maxsz = IP_MAXPACKET; 4404 1.22 nonaka tso_minsg = 2; 4405 1.22 nonaka if (hwcaps.ndis_lsov2.ndis_ip4_encap & NDIS_OFFLOAD_ENCAP_8023) { 4406 1.22 nonaka caps |= HVN_CAPS_TSO4; 4407 1.22 nonaka params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON; 4408 1.22 nonaka 4409 1.22 nonaka if (hwcaps.ndis_lsov2.ndis_ip4_maxsz < tso_maxsz) 4410 1.22 nonaka tso_maxsz = hwcaps.ndis_lsov2.ndis_ip4_maxsz; 4411 1.22 nonaka if (hwcaps.ndis_lsov2.ndis_ip4_minsg > tso_minsg) 4412 1.22 nonaka tso_minsg = hwcaps.ndis_lsov2.ndis_ip4_minsg; 4413 1.22 nonaka } 4414 1.22 nonaka if ((hwcaps.ndis_lsov2.ndis_ip6_encap & NDIS_OFFLOAD_ENCAP_8023) && 4415 1.22 nonaka (hwcaps.ndis_lsov2.ndis_ip6_opts & HVN_NDIS_LSOV2_CAP_IP6) == 4416 1.22 nonaka HVN_NDIS_LSOV2_CAP_IP6) { 4417 1.22 nonaka caps |= HVN_CAPS_TSO6; 4418 1.22 nonaka params.ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON; 4419 1.22 nonaka 4420 1.22 nonaka if (hwcaps.ndis_lsov2.ndis_ip6_maxsz < tso_maxsz) 4421 1.22 nonaka tso_maxsz = hwcaps.ndis_lsov2.ndis_ip6_maxsz; 4422 1.22 nonaka if (hwcaps.ndis_lsov2.ndis_ip6_minsg > tso_minsg) 4423 1.22 nonaka tso_minsg = hwcaps.ndis_lsov2.ndis_ip6_minsg; 4424 1.22 nonaka } 4425 1.22 nonaka sc->sc_tso_szmax = 0; 4426 1.22 nonaka sc->sc_tso_sgmin = 0; 4427 1.22 nonaka if (caps & (HVN_CAPS_TSO4 | HVN_CAPS_TSO6)) { 4428 1.22 nonaka KASSERTMSG(tso_maxsz <= IP_MAXPACKET, 4429 1.22 nonaka "invalid NDIS TSO maxsz %d", tso_maxsz); 4430 1.22 nonaka KASSERTMSG(tso_minsg >= 2, 4431 1.22 nonaka "invalid NDIS TSO minsg %d", tso_minsg); 4432 1.22 nonaka if (tso_maxsz < tso_minsg * mtu) { 4433 1.22 nonaka DPRINTF("%s: invalid NDIS TSO config: " 4434 1.22 nonaka "maxsz %d, minsg %d, mtu %d; " 4435 1.22 nonaka "disable TSO4 and TSO6\n", device_xname(sc->sc_dev), 4436 1.22 nonaka tso_maxsz, tso_minsg, mtu); 4437 1.22 nonaka caps &= ~(HVN_CAPS_TSO4 | HVN_CAPS_TSO6); 4438 1.22 nonaka params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_OFF; 4439 1.22 nonaka params.ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_OFF; 4440 1.22 nonaka } else { 4441 1.22 nonaka sc->sc_tso_szmax = tso_maxsz; 4442 1.22 nonaka sc->sc_tso_sgmin = tso_minsg; 4443 1.22 nonaka aprint_debug_dev(sc->sc_dev, 4444 1.22 nonaka "NDIS TSO szmax %d sgmin %d\n", 4445 1.22 nonaka sc->sc_tso_szmax, sc->sc_tso_sgmin); 4446 1.22 nonaka } 4447 1.22 nonaka } 4448 1.22 nonaka 4449 1.22 nonaka /* IPv4 checksum */ 4450 1.22 nonaka if ((hwcaps.ndis_csum.ndis_ip4_txcsum & HVN_NDIS_TXCSUM_CAP_IP4) == 4451 1.22 nonaka HVN_NDIS_TXCSUM_CAP_IP4) { 4452 1.22 nonaka caps |= HVN_CAPS_IPCS; 4453 1.22 nonaka params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TX; 4454 1.22 nonaka } 4455 1.22 nonaka if (hwcaps.ndis_csum.ndis_ip4_rxcsum & NDIS_RXCSUM_CAP_IP4) { 4456 1.22 nonaka if (params.ndis_ip4csum == NDIS_OFFLOAD_PARAM_TX) 4457 1.22 nonaka params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; 4458 1.22 nonaka else 4459 1.22 nonaka params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_RX; 4460 1.22 nonaka } 4461 1.22 nonaka 4462 1.22 nonaka /* TCP4 checksum */ 4463 1.22 nonaka if ((hwcaps.ndis_csum.ndis_ip4_txcsum & HVN_NDIS_TXCSUM_CAP_TCP4) == 4464 1.22 nonaka HVN_NDIS_TXCSUM_CAP_TCP4) { 4465 1.22 nonaka caps |= HVN_CAPS_TCP4CS; 4466 1.22 nonaka params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TX; 4467 1.22 nonaka } 4468 1.22 nonaka if (hwcaps.ndis_csum.ndis_ip4_rxcsum & NDIS_RXCSUM_CAP_TCP4) { 4469 1.22 nonaka if (params.ndis_tcp4csum == NDIS_OFFLOAD_PARAM_TX) 4470 1.22 nonaka params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; 4471 1.22 nonaka else 4472 1.22 nonaka params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_RX; 4473 1.22 nonaka } 4474 1.22 nonaka 4475 1.22 nonaka /* UDP4 checksum */ 4476 1.22 nonaka if (hwcaps.ndis_csum.ndis_ip4_txcsum & NDIS_TXCSUM_CAP_UDP4) { 4477 1.22 nonaka caps |= HVN_CAPS_UDP4CS; 4478 1.22 nonaka params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TX; 4479 1.22 nonaka } 4480 1.22 nonaka if (hwcaps.ndis_csum.ndis_ip4_rxcsum & NDIS_RXCSUM_CAP_UDP4) { 4481 1.22 nonaka if (params.ndis_udp4csum == NDIS_OFFLOAD_PARAM_TX) 4482 1.22 nonaka params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; 4483 1.22 nonaka else 4484 1.22 nonaka params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_RX; 4485 1.22 nonaka } 4486 1.22 nonaka 4487 1.22 nonaka /* TCP6 checksum */ 4488 1.22 nonaka if ((hwcaps.ndis_csum.ndis_ip6_txcsum & HVN_NDIS_TXCSUM_CAP_TCP6) == 4489 1.22 nonaka HVN_NDIS_TXCSUM_CAP_TCP6) { 4490 1.22 nonaka caps |= HVN_CAPS_TCP6CS; 4491 1.22 nonaka params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TX; 4492 1.22 nonaka } 4493 1.22 nonaka if (hwcaps.ndis_csum.ndis_ip6_rxcsum & NDIS_RXCSUM_CAP_TCP6) { 4494 1.22 nonaka if (params.ndis_tcp6csum == NDIS_OFFLOAD_PARAM_TX) 4495 1.22 nonaka params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; 4496 1.22 nonaka else 4497 1.22 nonaka params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_RX; 4498 1.22 nonaka } 4499 1.22 nonaka 4500 1.22 nonaka /* UDP6 checksum */ 4501 1.22 nonaka if ((hwcaps.ndis_csum.ndis_ip6_txcsum & HVN_NDIS_TXCSUM_CAP_UDP6) == 4502 1.22 nonaka HVN_NDIS_TXCSUM_CAP_UDP6) { 4503 1.22 nonaka caps |= HVN_CAPS_UDP6CS; 4504 1.22 nonaka params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TX; 4505 1.22 nonaka } 4506 1.22 nonaka if (hwcaps.ndis_csum.ndis_ip6_rxcsum & NDIS_RXCSUM_CAP_UDP6) { 4507 1.22 nonaka if (params.ndis_udp6csum == NDIS_OFFLOAD_PARAM_TX) 4508 1.22 nonaka params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; 4509 1.22 nonaka else 4510 1.22 nonaka params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_RX; 4511 1.22 nonaka } 4512 1.22 nonaka 4513 1.22 nonaka aprint_debug_dev(sc->sc_dev, "offload csum: " 4514 1.22 nonaka "ip4 %u, tcp4 %u, udp4 %u, tcp6 %u, udp6 %u\n", 4515 1.22 nonaka params.ndis_ip4csum, params.ndis_tcp4csum, params.ndis_udp4csum, 4516 1.22 nonaka params.ndis_tcp6csum, params.ndis_udp6csum); 4517 1.22 nonaka aprint_debug_dev(sc->sc_dev, "offload lsov2: ip4 %u, ip6 %u\n", 4518 1.22 nonaka params.ndis_lsov2_ip4, params.ndis_lsov2_ip6); 4519 1.22 nonaka 4520 1.22 nonaka error = hvn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, ¶ms, len); 4521 1.22 nonaka if (error) { 4522 1.22 nonaka DPRINTF("%s: offload config failed: %d\n", 4523 1.22 nonaka device_xname(sc->sc_dev), error); 4524 1.22 nonaka return error; 4525 1.1 nonaka } 4526 1.1 nonaka 4527 1.22 nonaka aprint_debug_dev(sc->sc_dev, "offload config done\n"); 4528 1.22 nonaka sc->sc_caps |= caps; 4529 1.22 nonaka 4530 1.22 nonaka return 0; 4531 1.1 nonaka } 4532 1.1 nonaka 4533 1.1 nonaka static int 4534 1.22 nonaka hvn_rndis_cmd(struct hvn_softc *sc, struct rndis_cmd *rc, u_int flags) 4535 1.1 nonaka { 4536 1.22 nonaka struct hvn_rx_ring *rxr = &sc->sc_rxr[0]; /* primary channel */ 4537 1.1 nonaka struct hvn_nvs_rndis *msg = &rc->rc_msg; 4538 1.1 nonaka struct rndis_msghdr *hdr = rc->rc_req; 4539 1.1 nonaka struct vmbus_gpa sgl[1]; 4540 1.1 nonaka int tries = 10; 4541 1.1 nonaka int rv, s; 4542 1.1 nonaka 4543 1.1 nonaka msg->nvs_type = HVN_NVS_TYPE_RNDIS; 4544 1.1 nonaka msg->nvs_rndis_mtype = HVN_NVS_RNDIS_MTYPE_CTRL; 4545 1.1 nonaka msg->nvs_chim_idx = HVN_NVS_CHIM_IDX_INVALID; 4546 1.1 nonaka 4547 1.1 nonaka sgl[0].gpa_page = rc->rc_gpa; 4548 1.1 nonaka sgl[0].gpa_len = hdr->rm_len; 4549 1.1 nonaka sgl[0].gpa_ofs = 0; 4550 1.1 nonaka 4551 1.1 nonaka rc->rc_done = 0; 4552 1.1 nonaka 4553 1.22 nonaka mutex_enter(&rc->rc_lock); 4554 1.22 nonaka 4555 1.1 nonaka hvn_submit_cmd(sc, rc); 4556 1.1 nonaka 4557 1.1 nonaka do { 4558 1.22 nonaka rv = vmbus_channel_send_sgl(rxr->rxr_chan, sgl, 1, &rc->rc_msg, 4559 1.1 nonaka sizeof(*msg), rc->rc_id); 4560 1.1 nonaka if (rv == EAGAIN) { 4561 1.22 nonaka DELAY(1000); 4562 1.1 nonaka } else if (rv) { 4563 1.22 nonaka mutex_exit(&rc->rc_lock); 4564 1.1 nonaka DPRINTF("%s: RNDIS operation %u send error %d\n", 4565 1.1 nonaka device_xname(sc->sc_dev), hdr->rm_type, rv); 4566 1.1 nonaka hvn_rollback_cmd(sc, rc); 4567 1.1 nonaka return rv; 4568 1.1 nonaka } 4569 1.1 nonaka } while (rv != 0 && --tries > 0); 4570 1.1 nonaka 4571 1.1 nonaka if (tries == 0 && rv != 0) { 4572 1.22 nonaka mutex_exit(&rc->rc_lock); 4573 1.1 nonaka device_printf(sc->sc_dev, 4574 1.1 nonaka "RNDIS operation %u send error %d\n", hdr->rm_type, rv); 4575 1.22 nonaka hvn_rollback_cmd(sc, rc); 4576 1.1 nonaka return rv; 4577 1.1 nonaka } 4578 1.22 nonaka if (vmbus_channel_is_revoked(rxr->rxr_chan) || 4579 1.22 nonaka ISSET(flags, HVN_RNDIS_CMD_NORESP)) { 4580 1.13 nonaka /* No response */ 4581 1.22 nonaka mutex_exit(&rc->rc_lock); 4582 1.22 nonaka if (hvn_rollback_cmd(sc, rc)) 4583 1.22 nonaka hvn_release_cmd(sc, rc); 4584 1.13 nonaka return 0; 4585 1.13 nonaka } 4586 1.1 nonaka 4587 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 4588 1.1 nonaka BUS_DMASYNC_POSTWRITE); 4589 1.1 nonaka 4590 1.22 nonaka while (!rc->rc_done && !ISSET(sc->sc_flags, HVN_SCF_REVOKED)) { 4591 1.22 nonaka mutex_exit(&rc->rc_lock); 4592 1.22 nonaka DELAY(1000); 4593 1.22 nonaka s = splnet(); 4594 1.22 nonaka hvn_nvs_intr1(rxr, 0, 0); 4595 1.22 nonaka splx(s); 4596 1.22 nonaka mutex_enter(&rc->rc_lock); 4597 1.22 nonaka } 4598 1.22 nonaka mutex_exit(&rc->rc_lock); 4599 1.1 nonaka 4600 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 4601 1.1 nonaka BUS_DMASYNC_POSTREAD); 4602 1.1 nonaka 4603 1.22 nonaka if (!rc->rc_done) { 4604 1.22 nonaka rv = EINTR; 4605 1.1 nonaka if (hvn_rollback_cmd(sc, rc)) { 4606 1.1 nonaka hvn_release_cmd(sc, rc); 4607 1.1 nonaka rv = 0; 4608 1.1 nonaka } 4609 1.1 nonaka return rv; 4610 1.1 nonaka } 4611 1.1 nonaka 4612 1.1 nonaka hvn_release_cmd(sc, rc); 4613 1.1 nonaka return 0; 4614 1.1 nonaka } 4615 1.1 nonaka 4616 1.22 nonaka static int 4617 1.22 nonaka hvn_rndis_input(struct hvn_rx_ring *rxr, uint64_t tid, void *arg) 4618 1.1 nonaka { 4619 1.22 nonaka struct hvn_softc *sc = rxr->rxr_softc; 4620 1.1 nonaka struct vmbus_chanpkt_prplist *cp = arg; 4621 1.1 nonaka uint32_t off, len, type; 4622 1.22 nonaka int i, rv, rx = 0; 4623 1.22 nonaka bool qfull = false; 4624 1.1 nonaka 4625 1.1 nonaka if (sc->sc_rx_ring == NULL) { 4626 1.1 nonaka DPRINTF("%s: invalid rx ring\n", device_xname(sc->sc_dev)); 4627 1.22 nonaka return 0; 4628 1.1 nonaka } 4629 1.1 nonaka 4630 1.1 nonaka for (i = 0; i < cp->cp_range_cnt; i++) { 4631 1.1 nonaka off = cp->cp_range[i].gpa_ofs; 4632 1.1 nonaka len = cp->cp_range[i].gpa_len; 4633 1.1 nonaka 4634 1.1 nonaka KASSERT(off + len <= sc->sc_rx_size); 4635 1.1 nonaka KASSERT(len >= RNDIS_HEADER_OFFSET + 4); 4636 1.1 nonaka 4637 1.1 nonaka memcpy(&type, sc->sc_rx_ring + off, sizeof(type)); 4638 1.1 nonaka switch (type) { 4639 1.1 nonaka /* data message */ 4640 1.1 nonaka case REMOTE_NDIS_PACKET_MSG: 4641 1.22 nonaka rv = hvn_rxeof(rxr, sc->sc_rx_ring + off, len); 4642 1.22 nonaka if (rv == 1) 4643 1.22 nonaka rx++; 4644 1.22 nonaka else if (rv == -1) /* The receive queue is full. */ 4645 1.22 nonaka qfull = true; 4646 1.1 nonaka break; 4647 1.1 nonaka /* completion messages */ 4648 1.1 nonaka case REMOTE_NDIS_INITIALIZE_CMPLT: 4649 1.1 nonaka case REMOTE_NDIS_QUERY_CMPLT: 4650 1.1 nonaka case REMOTE_NDIS_SET_CMPLT: 4651 1.1 nonaka case REMOTE_NDIS_RESET_CMPLT: 4652 1.1 nonaka case REMOTE_NDIS_KEEPALIVE_CMPLT: 4653 1.1 nonaka hvn_rndis_complete(sc, sc->sc_rx_ring + off, len); 4654 1.1 nonaka break; 4655 1.1 nonaka /* notification message */ 4656 1.1 nonaka case REMOTE_NDIS_INDICATE_STATUS_MSG: 4657 1.1 nonaka hvn_rndis_status(sc, sc->sc_rx_ring + off, len); 4658 1.1 nonaka break; 4659 1.1 nonaka default: 4660 1.1 nonaka device_printf(sc->sc_dev, 4661 1.1 nonaka "unhandled RNDIS message type %u\n", type); 4662 1.1 nonaka break; 4663 1.1 nonaka } 4664 1.1 nonaka } 4665 1.1 nonaka 4666 1.22 nonaka hvn_nvs_ack(rxr, tid); 4667 1.22 nonaka 4668 1.22 nonaka if (qfull) 4669 1.22 nonaka return -1; 4670 1.22 nonaka return rx; 4671 1.1 nonaka } 4672 1.1 nonaka 4673 1.1 nonaka static inline struct mbuf * 4674 1.1 nonaka hvn_devget(struct hvn_softc *sc, void *buf, uint32_t len) 4675 1.1 nonaka { 4676 1.1 nonaka struct ifnet *ifp = SC2IFP(sc); 4677 1.1 nonaka struct mbuf *m; 4678 1.22 nonaka size_t size = len + ETHER_ALIGN + ETHER_VLAN_ENCAP_LEN; 4679 1.1 nonaka 4680 1.1 nonaka MGETHDR(m, M_NOWAIT, MT_DATA); 4681 1.1 nonaka if (m == NULL) 4682 1.1 nonaka return NULL; 4683 1.1 nonaka 4684 1.1 nonaka if (size > MHLEN) { 4685 1.1 nonaka if (size <= MCLBYTES) 4686 1.1 nonaka MCLGET(m, M_NOWAIT); 4687 1.1 nonaka else 4688 1.1 nonaka MEXTMALLOC(m, size, M_NOWAIT); 4689 1.1 nonaka if ((m->m_flags & M_EXT) == 0) { 4690 1.1 nonaka m_freem(m); 4691 1.1 nonaka return NULL; 4692 1.1 nonaka } 4693 1.1 nonaka } 4694 1.1 nonaka 4695 1.1 nonaka m->m_len = m->m_pkthdr.len = size; 4696 1.22 nonaka m_adj(m, ETHER_ALIGN + ETHER_VLAN_ENCAP_LEN); 4697 1.1 nonaka m_copyback(m, 0, len, buf); 4698 1.1 nonaka m_set_rcvif(m, ifp); 4699 1.1 nonaka return m; 4700 1.1 nonaka } 4701 1.1 nonaka 4702 1.22 nonaka #define HVN_RXINFO_CSUM __BIT(NDIS_PKTINFO_TYPE_CSUM) 4703 1.22 nonaka #define HVN_RXINFO_VLAN __BIT(NDIS_PKTINFO_TYPE_VLAN) 4704 1.22 nonaka #define HVN_RXINFO_HASHVAL __BIT(HVN_NDIS_PKTINFO_TYPE_HASHVAL) 4705 1.22 nonaka #define HVN_RXINFO_HASHINFO __BIT(HVN_NDIS_PKTINFO_TYPE_HASHINF) 4706 1.22 nonaka #define HVN_RXINFO_ALL (HVN_RXINFO_CSUM | \ 4707 1.22 nonaka HVN_RXINFO_VLAN | \ 4708 1.22 nonaka HVN_RXINFO_HASHVAL | \ 4709 1.22 nonaka HVN_RXINFO_HASHINFO) 4710 1.22 nonaka 4711 1.22 nonaka static int 4712 1.22 nonaka hvn_rxeof(struct hvn_rx_ring *rxr, uint8_t *buf, uint32_t len) 4713 1.1 nonaka { 4714 1.22 nonaka struct hvn_softc *sc = rxr->rxr_softc; 4715 1.1 nonaka struct ifnet *ifp = SC2IFP(sc); 4716 1.1 nonaka struct rndis_packet_msg *pkt; 4717 1.1 nonaka struct rndis_pktinfo *pi; 4718 1.1 nonaka struct mbuf *m; 4719 1.22 nonaka uint32_t mask, csum, vlan, hashval, hashinfo; 4720 1.1 nonaka 4721 1.1 nonaka if (!(ifp->if_flags & IFF_RUNNING)) 4722 1.22 nonaka return 0; 4723 1.1 nonaka 4724 1.1 nonaka if (len < sizeof(*pkt)) { 4725 1.1 nonaka device_printf(sc->sc_dev, "data packet too short: %u\n", 4726 1.1 nonaka len); 4727 1.22 nonaka return 0; 4728 1.1 nonaka } 4729 1.1 nonaka 4730 1.1 nonaka pkt = (struct rndis_packet_msg *)buf; 4731 1.1 nonaka if (pkt->rm_dataoffset + pkt->rm_datalen > len) { 4732 1.1 nonaka device_printf(sc->sc_dev, 4733 1.1 nonaka "data packet out of bounds: %u@%u\n", pkt->rm_dataoffset, 4734 1.1 nonaka pkt->rm_datalen); 4735 1.22 nonaka return 0; 4736 1.1 nonaka } 4737 1.1 nonaka 4738 1.1 nonaka if ((m = hvn_devget(sc, buf + RNDIS_HEADER_OFFSET + pkt->rm_dataoffset, 4739 1.1 nonaka pkt->rm_datalen)) == NULL) { 4740 1.16 thorpej if_statinc(ifp, if_ierrors); 4741 1.22 nonaka return 0; 4742 1.1 nonaka } 4743 1.1 nonaka 4744 1.1 nonaka if (pkt->rm_pktinfooffset + pkt->rm_pktinfolen > len) { 4745 1.1 nonaka device_printf(sc->sc_dev, 4746 1.1 nonaka "pktinfo is out of bounds: %u@%u vs %u\n", 4747 1.1 nonaka pkt->rm_pktinfolen, pkt->rm_pktinfooffset, len); 4748 1.1 nonaka goto done; 4749 1.1 nonaka } 4750 1.1 nonaka 4751 1.22 nonaka mask = csum = hashval = hashinfo = 0; 4752 1.22 nonaka vlan = 0xffffffff; 4753 1.1 nonaka pi = (struct rndis_pktinfo *)(buf + RNDIS_HEADER_OFFSET + 4754 1.1 nonaka pkt->rm_pktinfooffset); 4755 1.1 nonaka while (pkt->rm_pktinfolen > 0) { 4756 1.1 nonaka if (pi->rm_size > pkt->rm_pktinfolen) { 4757 1.1 nonaka device_printf(sc->sc_dev, 4758 1.1 nonaka "invalid pktinfo size: %u/%u\n", pi->rm_size, 4759 1.1 nonaka pkt->rm_pktinfolen); 4760 1.1 nonaka break; 4761 1.1 nonaka } 4762 1.1 nonaka 4763 1.1 nonaka switch (pi->rm_type) { 4764 1.1 nonaka case NDIS_PKTINFO_TYPE_CSUM: 4765 1.1 nonaka memcpy(&csum, pi->rm_data, sizeof(csum)); 4766 1.22 nonaka SET(mask, HVN_RXINFO_CSUM); 4767 1.1 nonaka break; 4768 1.1 nonaka case NDIS_PKTINFO_TYPE_VLAN: 4769 1.1 nonaka memcpy(&vlan, pi->rm_data, sizeof(vlan)); 4770 1.22 nonaka SET(mask, HVN_RXINFO_VLAN); 4771 1.22 nonaka break; 4772 1.22 nonaka case HVN_NDIS_PKTINFO_TYPE_HASHVAL: 4773 1.22 nonaka memcpy(&hashval, pi->rm_data, sizeof(hashval)); 4774 1.22 nonaka SET(mask, HVN_RXINFO_HASHVAL); 4775 1.22 nonaka break; 4776 1.22 nonaka case HVN_NDIS_PKTINFO_TYPE_HASHINF: 4777 1.22 nonaka memcpy(&hashinfo, pi->rm_data, sizeof(hashinfo)); 4778 1.22 nonaka SET(mask, HVN_RXINFO_HASHINFO); 4779 1.1 nonaka break; 4780 1.1 nonaka default: 4781 1.1 nonaka DPRINTF("%s: unhandled pktinfo type %u\n", 4782 1.1 nonaka device_xname(sc->sc_dev), pi->rm_type); 4783 1.22 nonaka goto next; 4784 1.22 nonaka } 4785 1.22 nonaka 4786 1.22 nonaka if (mask == HVN_RXINFO_ALL) { 4787 1.22 nonaka /* All found; done */ 4788 1.1 nonaka break; 4789 1.1 nonaka } 4790 1.22 nonaka next: 4791 1.1 nonaka pkt->rm_pktinfolen -= pi->rm_size; 4792 1.1 nonaka pi = (struct rndis_pktinfo *)((char *)pi + pi->rm_size); 4793 1.1 nonaka } 4794 1.1 nonaka 4795 1.22 nonaka /* 4796 1.22 nonaka * Final fixup. 4797 1.22 nonaka * - If there is no hash value, invalidate the hash info. 4798 1.22 nonaka */ 4799 1.22 nonaka if (!ISSET(mask, HVN_RXINFO_HASHVAL)) 4800 1.22 nonaka hashinfo = 0; 4801 1.22 nonaka 4802 1.22 nonaka if (csum != 0) { 4803 1.22 nonaka if (ISSET(csum, NDIS_RXCSUM_INFO_IPCS_OK) && 4804 1.22 nonaka ISSET(ifp->if_csum_flags_rx, M_CSUM_IPv4)) { 4805 1.22 nonaka SET(m->m_pkthdr.csum_flags, M_CSUM_IPv4); 4806 1.22 nonaka rxr->rxr_evcsum_ip.ev_count++; 4807 1.22 nonaka } 4808 1.22 nonaka if (ISSET(csum, NDIS_RXCSUM_INFO_TCPCS_OK) && 4809 1.22 nonaka ISSET(ifp->if_csum_flags_rx, M_CSUM_TCPv4)) { 4810 1.22 nonaka SET(m->m_pkthdr.csum_flags, M_CSUM_TCPv4); 4811 1.22 nonaka rxr->rxr_evcsum_tcp.ev_count++; 4812 1.22 nonaka } 4813 1.22 nonaka if (ISSET(csum, NDIS_RXCSUM_INFO_UDPCS_OK) && 4814 1.22 nonaka ISSET(ifp->if_csum_flags_rx, M_CSUM_UDPv4)) { 4815 1.22 nonaka SET(m->m_pkthdr.csum_flags, M_CSUM_UDPv4); 4816 1.22 nonaka rxr->rxr_evcsum_udp.ev_count++; 4817 1.22 nonaka } 4818 1.22 nonaka } 4819 1.22 nonaka 4820 1.22 nonaka if (vlan != 0xffffffff) { 4821 1.22 nonaka uint16_t t = NDIS_VLAN_INFO_ID(vlan); 4822 1.22 nonaka t |= NDIS_VLAN_INFO_PRI(vlan) << EVL_PRIO_BITS; 4823 1.22 nonaka t |= NDIS_VLAN_INFO_CFI(vlan) << EVL_CFI_BITS; 4824 1.22 nonaka 4825 1.22 nonaka if (ISSET(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWTAGGING)) { 4826 1.22 nonaka vlan_set_tag(m, t); 4827 1.22 nonaka rxr->rxr_evvlanhwtagging.ev_count++; 4828 1.22 nonaka } else { 4829 1.22 nonaka struct ether_header eh; 4830 1.22 nonaka struct ether_vlan_header *evl; 4831 1.22 nonaka 4832 1.22 nonaka KDASSERT(m->m_pkthdr.len >= sizeof(eh)); 4833 1.22 nonaka m_copydata(m, 0, sizeof(eh), &eh); 4834 1.22 nonaka M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_NOWAIT); 4835 1.22 nonaka KDASSERT(m != NULL); 4836 1.22 nonaka 4837 1.22 nonaka evl = mtod(m, struct ether_vlan_header *); 4838 1.30 joe memcpy(evl, &eh, ETHER_ADDR_LEN * 2); 4839 1.22 nonaka evl->evl_encap_proto = htons(ETHERTYPE_VLAN); 4840 1.22 nonaka evl->evl_tag = htons(t); 4841 1.22 nonaka evl->evl_proto = eh.ether_type; 4842 1.22 nonaka } 4843 1.22 nonaka } 4844 1.22 nonaka 4845 1.22 nonaka /* XXX RSS hash is not supported. */ 4846 1.22 nonaka 4847 1.1 nonaka done: 4848 1.22 nonaka rxr->rxr_evpkts.ev_count++; 4849 1.1 nonaka if_percpuq_enqueue(sc->sc_ipq, m); 4850 1.22 nonaka /* XXX Unable to detect that the receive queue is full. */ 4851 1.22 nonaka return 1; 4852 1.1 nonaka } 4853 1.1 nonaka 4854 1.1 nonaka static void 4855 1.1 nonaka hvn_rndis_complete(struct hvn_softc *sc, uint8_t *buf, uint32_t len) 4856 1.1 nonaka { 4857 1.1 nonaka struct rndis_cmd *rc; 4858 1.1 nonaka uint32_t id; 4859 1.1 nonaka 4860 1.1 nonaka memcpy(&id, buf + RNDIS_HEADER_OFFSET, sizeof(id)); 4861 1.1 nonaka if ((rc = hvn_complete_cmd(sc, id)) != NULL) { 4862 1.22 nonaka mutex_enter(&rc->rc_lock); 4863 1.1 nonaka if (len < rc->rc_cmplen) 4864 1.1 nonaka device_printf(sc->sc_dev, 4865 1.1 nonaka "RNDIS response %u too short: %u\n", id, len); 4866 1.1 nonaka else 4867 1.1 nonaka memcpy(&rc->rc_cmp, buf, rc->rc_cmplen); 4868 1.1 nonaka if (len > rc->rc_cmplen && 4869 1.1 nonaka len - rc->rc_cmplen > HVN_RNDIS_BUFSIZE) 4870 1.1 nonaka device_printf(sc->sc_dev, 4871 1.1 nonaka "RNDIS response %u too large: %u\n", id, len); 4872 1.1 nonaka else if (len > rc->rc_cmplen) 4873 1.1 nonaka memcpy(&rc->rc_cmpbuf, buf + rc->rc_cmplen, 4874 1.1 nonaka len - rc->rc_cmplen); 4875 1.1 nonaka rc->rc_done = 1; 4876 1.22 nonaka cv_signal(&rc->rc_cv); 4877 1.22 nonaka mutex_exit(&rc->rc_lock); 4878 1.1 nonaka } else { 4879 1.1 nonaka DPRINTF("%s: failed to complete RNDIS request id %u\n", 4880 1.1 nonaka device_xname(sc->sc_dev), id); 4881 1.1 nonaka } 4882 1.1 nonaka } 4883 1.1 nonaka 4884 1.1 nonaka static int 4885 1.22 nonaka hvn_rndis_output_sgl(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd) 4886 1.1 nonaka { 4887 1.22 nonaka struct hvn_softc *sc = txr->txr_softc; 4888 1.1 nonaka uint64_t rid = (uint64_t)txd->txd_id << 32; 4889 1.1 nonaka int rv; 4890 1.1 nonaka 4891 1.22 nonaka rv = vmbus_channel_send_sgl(txr->txr_chan, txd->txd_sgl, txd->txd_nsge, 4892 1.1 nonaka &sc->sc_data_msg, sizeof(sc->sc_data_msg), rid); 4893 1.1 nonaka if (rv) { 4894 1.1 nonaka DPRINTF("%s: RNDIS data send error %d\n", 4895 1.1 nonaka device_xname(sc->sc_dev), rv); 4896 1.1 nonaka return rv; 4897 1.1 nonaka } 4898 1.1 nonaka return 0; 4899 1.1 nonaka } 4900 1.1 nonaka 4901 1.22 nonaka static int 4902 1.22 nonaka hvn_rndis_output_chim(struct hvn_tx_ring *txr, struct hvn_tx_desc *txd) 4903 1.22 nonaka { 4904 1.22 nonaka struct hvn_nvs_rndis rndis; 4905 1.22 nonaka uint64_t rid = (uint64_t)txd->txd_id << 32; 4906 1.22 nonaka int rv; 4907 1.22 nonaka 4908 1.22 nonaka memset(&rndis, 0, sizeof(rndis)); 4909 1.22 nonaka rndis.nvs_type = HVN_NVS_TYPE_RNDIS; 4910 1.22 nonaka rndis.nvs_rndis_mtype = HVN_NVS_RNDIS_MTYPE_DATA; 4911 1.22 nonaka rndis.nvs_chim_idx = txd->txd_chim_index; 4912 1.22 nonaka rndis.nvs_chim_sz = txd->txd_chim_size; 4913 1.22 nonaka 4914 1.22 nonaka rv = vmbus_channel_send(txr->txr_chan, &rndis, sizeof(rndis), 4915 1.22 nonaka rid, VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC); 4916 1.22 nonaka if (rv) { 4917 1.22 nonaka DPRINTF("%s: RNDIS chimney data send error %d: idx %u, sz %u\n", 4918 1.22 nonaka device_xname(sc->sc_dev), rv, rndis.nvs_chim_idx, 4919 1.22 nonaka rndis.nvs_chim_sz); 4920 1.22 nonaka return rv; 4921 1.22 nonaka } 4922 1.22 nonaka return 0; 4923 1.22 nonaka } 4924 1.22 nonaka 4925 1.1 nonaka static void 4926 1.1 nonaka hvn_rndis_status(struct hvn_softc *sc, uint8_t *buf, uint32_t len) 4927 1.1 nonaka { 4928 1.1 nonaka uint32_t status; 4929 1.1 nonaka 4930 1.1 nonaka memcpy(&status, buf + RNDIS_HEADER_OFFSET, sizeof(status)); 4931 1.1 nonaka switch (status) { 4932 1.1 nonaka case RNDIS_STATUS_MEDIA_CONNECT: 4933 1.22 nonaka case RNDIS_STATUS_MEDIA_DISCONNECT: 4934 1.22 nonaka hvn_link_event(sc, HVN_LINK_EV_STATE_CHANGE); 4935 1.1 nonaka break; 4936 1.22 nonaka case RNDIS_STATUS_NETWORK_CHANGE: 4937 1.22 nonaka hvn_link_event(sc, HVN_LINK_EV_NETWORK_CHANGE); 4938 1.1 nonaka break; 4939 1.1 nonaka /* Ignore these */ 4940 1.1 nonaka case RNDIS_STATUS_OFFLOAD_CURRENT_CONFIG: 4941 1.22 nonaka case RNDIS_STATUS_LINK_SPEED_CHANGE: 4942 1.1 nonaka return; 4943 1.1 nonaka default: 4944 1.1 nonaka DPRINTF("%s: unhandled status %#x\n", device_xname(sc->sc_dev), 4945 1.1 nonaka status); 4946 1.1 nonaka return; 4947 1.1 nonaka } 4948 1.1 nonaka } 4949 1.1 nonaka 4950 1.1 nonaka static int 4951 1.1 nonaka hvn_rndis_query(struct hvn_softc *sc, uint32_t oid, void *res, size_t *length) 4952 1.1 nonaka { 4953 1.22 nonaka 4954 1.22 nonaka return hvn_rndis_query2(sc, oid, NULL, 0, res, length, 0); 4955 1.22 nonaka } 4956 1.22 nonaka 4957 1.22 nonaka static int 4958 1.22 nonaka hvn_rndis_query2(struct hvn_softc *sc, uint32_t oid, const void *idata, 4959 1.22 nonaka size_t idlen, void *odata, size_t *odlen, size_t min_odlen) 4960 1.22 nonaka { 4961 1.1 nonaka struct rndis_cmd *rc; 4962 1.1 nonaka struct rndis_query_req *req; 4963 1.1 nonaka struct rndis_query_comp *cmp; 4964 1.22 nonaka size_t olength = *odlen; 4965 1.1 nonaka int rv; 4966 1.1 nonaka 4967 1.1 nonaka rc = hvn_alloc_cmd(sc); 4968 1.1 nonaka 4969 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 4970 1.1 nonaka BUS_DMASYNC_PREREAD); 4971 1.1 nonaka 4972 1.1 nonaka rc->rc_id = atomic_inc_uint_nv(&sc->sc_rndisrid); 4973 1.1 nonaka 4974 1.1 nonaka req = rc->rc_req; 4975 1.1 nonaka req->rm_type = REMOTE_NDIS_QUERY_MSG; 4976 1.22 nonaka req->rm_len = sizeof(*req) + idlen; 4977 1.1 nonaka req->rm_rid = rc->rc_id; 4978 1.1 nonaka req->rm_oid = oid; 4979 1.1 nonaka req->rm_infobufoffset = sizeof(*req) - RNDIS_HEADER_OFFSET; 4980 1.22 nonaka if (idlen > 0) { 4981 1.22 nonaka KASSERT(sizeof(*req) + idlen <= PAGE_SIZE); 4982 1.22 nonaka req->rm_infobuflen = idlen; 4983 1.22 nonaka memcpy(req + 1, idata, idlen); 4984 1.22 nonaka } 4985 1.1 nonaka 4986 1.1 nonaka rc->rc_cmplen = sizeof(*cmp); 4987 1.1 nonaka 4988 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 4989 1.1 nonaka BUS_DMASYNC_PREWRITE); 4990 1.1 nonaka 4991 1.22 nonaka if ((rv = hvn_rndis_cmd(sc, rc, 0)) != 0) { 4992 1.1 nonaka DPRINTF("%s: QUERY_MSG failed, error %d\n", 4993 1.1 nonaka device_xname(sc->sc_dev), rv); 4994 1.1 nonaka hvn_free_cmd(sc, rc); 4995 1.1 nonaka return rv; 4996 1.1 nonaka } 4997 1.1 nonaka 4998 1.1 nonaka cmp = (struct rndis_query_comp *)&rc->rc_cmp; 4999 1.1 nonaka switch (cmp->rm_status) { 5000 1.1 nonaka case RNDIS_STATUS_SUCCESS: 5001 1.22 nonaka if (cmp->rm_infobuflen > olength || 5002 1.22 nonaka (min_odlen > 0 && cmp->rm_infobuflen < min_odlen)) { 5003 1.1 nonaka rv = EINVAL; 5004 1.1 nonaka break; 5005 1.1 nonaka } 5006 1.22 nonaka memcpy(odata, rc->rc_cmpbuf, cmp->rm_infobuflen); 5007 1.22 nonaka *odlen = cmp->rm_infobuflen; 5008 1.1 nonaka break; 5009 1.1 nonaka default: 5010 1.22 nonaka *odlen = 0; 5011 1.1 nonaka rv = EIO; 5012 1.1 nonaka break; 5013 1.1 nonaka } 5014 1.1 nonaka 5015 1.1 nonaka hvn_free_cmd(sc, rc); 5016 1.1 nonaka return rv; 5017 1.1 nonaka } 5018 1.1 nonaka 5019 1.1 nonaka static int 5020 1.1 nonaka hvn_rndis_set(struct hvn_softc *sc, uint32_t oid, void *data, size_t length) 5021 1.1 nonaka { 5022 1.1 nonaka struct rndis_cmd *rc; 5023 1.1 nonaka struct rndis_set_req *req; 5024 1.1 nonaka struct rndis_set_comp *cmp; 5025 1.1 nonaka int rv; 5026 1.1 nonaka 5027 1.1 nonaka rc = hvn_alloc_cmd(sc); 5028 1.1 nonaka 5029 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 5030 1.1 nonaka BUS_DMASYNC_PREREAD); 5031 1.1 nonaka 5032 1.1 nonaka rc->rc_id = atomic_inc_uint_nv(&sc->sc_rndisrid); 5033 1.1 nonaka 5034 1.1 nonaka req = rc->rc_req; 5035 1.1 nonaka req->rm_type = REMOTE_NDIS_SET_MSG; 5036 1.1 nonaka req->rm_len = sizeof(*req) + length; 5037 1.1 nonaka req->rm_rid = rc->rc_id; 5038 1.1 nonaka req->rm_oid = oid; 5039 1.1 nonaka req->rm_infobufoffset = sizeof(*req) - RNDIS_HEADER_OFFSET; 5040 1.1 nonaka 5041 1.1 nonaka rc->rc_cmplen = sizeof(*cmp); 5042 1.1 nonaka 5043 1.1 nonaka if (length > 0) { 5044 1.1 nonaka KASSERT(sizeof(*req) + length < PAGE_SIZE); 5045 1.1 nonaka req->rm_infobuflen = length; 5046 1.1 nonaka memcpy(req + 1, data, length); 5047 1.1 nonaka } 5048 1.1 nonaka 5049 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 5050 1.1 nonaka BUS_DMASYNC_PREWRITE); 5051 1.1 nonaka 5052 1.22 nonaka if ((rv = hvn_rndis_cmd(sc, rc, 0)) != 0) { 5053 1.1 nonaka DPRINTF("%s: SET_MSG failed, error %d\n", 5054 1.1 nonaka device_xname(sc->sc_dev), rv); 5055 1.1 nonaka hvn_free_cmd(sc, rc); 5056 1.1 nonaka return rv; 5057 1.1 nonaka } 5058 1.1 nonaka 5059 1.1 nonaka cmp = (struct rndis_set_comp *)&rc->rc_cmp; 5060 1.1 nonaka if (cmp->rm_status != RNDIS_STATUS_SUCCESS) 5061 1.1 nonaka rv = EIO; 5062 1.1 nonaka 5063 1.1 nonaka hvn_free_cmd(sc, rc); 5064 1.1 nonaka return rv; 5065 1.1 nonaka } 5066 1.1 nonaka 5067 1.1 nonaka static int 5068 1.1 nonaka hvn_rndis_open(struct hvn_softc *sc) 5069 1.1 nonaka { 5070 1.22 nonaka struct ifnet *ifp = SC2IFP(sc); 5071 1.1 nonaka uint32_t filter; 5072 1.1 nonaka int rv; 5073 1.1 nonaka 5074 1.22 nonaka if (ifp->if_flags & IFF_PROMISC) { 5075 1.1 nonaka filter = RNDIS_PACKET_TYPE_PROMISCUOUS; 5076 1.22 nonaka } else { 5077 1.22 nonaka filter = RNDIS_PACKET_TYPE_DIRECTED; 5078 1.22 nonaka if (ifp->if_flags & IFF_BROADCAST) 5079 1.22 nonaka filter |= RNDIS_PACKET_TYPE_BROADCAST; 5080 1.22 nonaka if (ifp->if_flags & IFF_ALLMULTI) 5081 1.22 nonaka filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; 5082 1.22 nonaka else { 5083 1.22 nonaka struct ethercom *ec = &sc->sc_ec; 5084 1.22 nonaka struct ether_multi *enm; 5085 1.22 nonaka struct ether_multistep step; 5086 1.22 nonaka 5087 1.22 nonaka ETHER_LOCK(ec); 5088 1.22 nonaka ETHER_FIRST_MULTI(step, ec, enm); 5089 1.22 nonaka /* TODO: support multicast list */ 5090 1.22 nonaka if (enm != NULL) 5091 1.22 nonaka filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; 5092 1.22 nonaka ETHER_UNLOCK(ec); 5093 1.22 nonaka } 5094 1.22 nonaka } 5095 1.1 nonaka 5096 1.1 nonaka rv = hvn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER, 5097 1.1 nonaka &filter, sizeof(filter)); 5098 1.1 nonaka if (rv) { 5099 1.1 nonaka DPRINTF("%s: failed to set RNDIS filter to %#x\n", 5100 1.1 nonaka device_xname(sc->sc_dev), filter); 5101 1.1 nonaka } 5102 1.1 nonaka return rv; 5103 1.1 nonaka } 5104 1.1 nonaka 5105 1.1 nonaka static int 5106 1.1 nonaka hvn_rndis_close(struct hvn_softc *sc) 5107 1.1 nonaka { 5108 1.1 nonaka uint32_t filter = 0; 5109 1.1 nonaka int rv; 5110 1.1 nonaka 5111 1.1 nonaka rv = hvn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER, 5112 1.1 nonaka &filter, sizeof(filter)); 5113 1.1 nonaka if (rv) { 5114 1.1 nonaka DPRINTF("%s: failed to clear RNDIS filter\n", 5115 1.1 nonaka device_xname(sc->sc_dev)); 5116 1.1 nonaka } 5117 1.1 nonaka return rv; 5118 1.1 nonaka } 5119 1.1 nonaka 5120 1.1 nonaka static void 5121 1.1 nonaka hvn_rndis_detach(struct hvn_softc *sc) 5122 1.1 nonaka { 5123 1.1 nonaka struct rndis_cmd *rc; 5124 1.1 nonaka struct rndis_halt_req *req; 5125 1.1 nonaka int rv; 5126 1.1 nonaka 5127 1.1 nonaka rc = hvn_alloc_cmd(sc); 5128 1.1 nonaka 5129 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 5130 1.1 nonaka BUS_DMASYNC_PREREAD); 5131 1.1 nonaka 5132 1.1 nonaka rc->rc_id = atomic_inc_uint_nv(&sc->sc_rndisrid); 5133 1.1 nonaka 5134 1.1 nonaka req = rc->rc_req; 5135 1.1 nonaka req->rm_type = REMOTE_NDIS_HALT_MSG; 5136 1.1 nonaka req->rm_len = sizeof(*req); 5137 1.1 nonaka req->rm_rid = rc->rc_id; 5138 1.1 nonaka 5139 1.1 nonaka bus_dmamap_sync(sc->sc_dmat, rc->rc_dmap, 0, PAGE_SIZE, 5140 1.1 nonaka BUS_DMASYNC_PREWRITE); 5141 1.1 nonaka 5142 1.22 nonaka /* No RNDIS completion; rely on NVS message send completion */ 5143 1.22 nonaka if ((rv = hvn_rndis_cmd(sc, rc, HVN_RNDIS_CMD_NORESP)) != 0) { 5144 1.1 nonaka DPRINTF("%s: HALT_MSG failed, error %d\n", 5145 1.1 nonaka device_xname(sc->sc_dev), rv); 5146 1.1 nonaka } 5147 1.1 nonaka hvn_free_cmd(sc, rc); 5148 1.22 nonaka } 5149 1.22 nonaka 5150 1.22 nonaka static void 5151 1.22 nonaka hvn_init_sysctls(struct hvn_softc *sc) 5152 1.22 nonaka { 5153 1.22 nonaka struct sysctllog **log; 5154 1.22 nonaka const struct sysctlnode *rnode, *cnode, *rxnode, *txnode; 5155 1.22 nonaka const char *dvname; 5156 1.22 nonaka int error; 5157 1.22 nonaka 5158 1.22 nonaka log = &sc->sc_sysctllog; 5159 1.22 nonaka dvname = device_xname(sc->sc_dev); 5160 1.22 nonaka 5161 1.22 nonaka error = sysctl_createv(log, 0, NULL, &rnode, 5162 1.22 nonaka 0, CTLTYPE_NODE, dvname, 5163 1.22 nonaka SYSCTL_DESCR("hvn information and settings"), 5164 1.22 nonaka NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 5165 1.22 nonaka if (error) 5166 1.22 nonaka goto err; 5167 1.22 nonaka 5168 1.22 nonaka error = sysctl_createv(log, 0, &rnode, &cnode, 5169 1.22 nonaka CTLFLAG_READWRITE, CTLTYPE_BOOL, "txrx_workqueue", 5170 1.22 nonaka SYSCTL_DESCR("Use workqueue for packet processing"), 5171 1.22 nonaka NULL, 0, &sc->sc_txrx_workqueue, 0, CTL_CREATE, CTL_EOL); 5172 1.22 nonaka if (error) 5173 1.22 nonaka goto out; 5174 1.22 nonaka 5175 1.22 nonaka error = sysctl_createv(log, 0, &rnode, &rxnode, 5176 1.22 nonaka 0, CTLTYPE_NODE, "rx", 5177 1.22 nonaka SYSCTL_DESCR("hvn information and settings for Rx"), 5178 1.22 nonaka NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 5179 1.22 nonaka if (error) 5180 1.22 nonaka goto out; 5181 1.13 nonaka 5182 1.22 nonaka error = sysctl_createv(log, 0, &rxnode, NULL, 5183 1.22 nonaka CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit", 5184 1.22 nonaka SYSCTL_DESCR("max number of Rx packets" 5185 1.22 nonaka " to process for interrupt processing"), 5186 1.22 nonaka NULL, 0, &sc->sc_rx_intr_process_limit, 0, CTL_CREATE, CTL_EOL); 5187 1.22 nonaka if (error) 5188 1.22 nonaka goto out; 5189 1.22 nonaka 5190 1.22 nonaka error = sysctl_createv(log, 0, &rxnode, NULL, 5191 1.22 nonaka CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit", 5192 1.22 nonaka SYSCTL_DESCR("max number of Rx packets" 5193 1.22 nonaka " to process for deferred processing"), 5194 1.22 nonaka NULL, 0, &sc->sc_rx_process_limit, 0, CTL_CREATE, CTL_EOL); 5195 1.22 nonaka if (error) 5196 1.22 nonaka goto out; 5197 1.22 nonaka 5198 1.22 nonaka error = sysctl_createv(log, 0, &rnode, &txnode, 5199 1.22 nonaka 0, CTLTYPE_NODE, "tx", 5200 1.22 nonaka SYSCTL_DESCR("hvn information and settings for Tx"), 5201 1.22 nonaka NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 5202 1.22 nonaka if (error) 5203 1.22 nonaka goto out; 5204 1.22 nonaka 5205 1.22 nonaka error = sysctl_createv(log, 0, &txnode, NULL, 5206 1.22 nonaka CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit", 5207 1.22 nonaka SYSCTL_DESCR("max number of Tx packets" 5208 1.22 nonaka " to process for interrupt processing"), 5209 1.22 nonaka NULL, 0, &sc->sc_tx_intr_process_limit, 0, CTL_CREATE, CTL_EOL); 5210 1.22 nonaka if (error) 5211 1.22 nonaka goto out; 5212 1.22 nonaka 5213 1.22 nonaka error = sysctl_createv(log, 0, &txnode, NULL, 5214 1.22 nonaka CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit", 5215 1.22 nonaka SYSCTL_DESCR("max number of Tx packets" 5216 1.22 nonaka " to process for deferred processing"), 5217 1.22 nonaka NULL, 0, &sc->sc_tx_process_limit, 0, CTL_CREATE, CTL_EOL); 5218 1.22 nonaka if (error) 5219 1.22 nonaka goto out; 5220 1.22 nonaka 5221 1.22 nonaka return; 5222 1.22 nonaka 5223 1.22 nonaka out: 5224 1.22 nonaka sysctl_teardown(log); 5225 1.22 nonaka sc->sc_sysctllog = NULL; 5226 1.22 nonaka err: 5227 1.22 nonaka aprint_error_dev(sc->sc_dev, "sysctl_createv failed (err = %d)\n", 5228 1.22 nonaka error); 5229 1.22 nonaka } 5230 1.22 nonaka 5231 1.22 nonaka SYSCTL_SETUP(sysctl_hw_hvn_setup, "sysctl hw.hvn setup") 5232 1.22 nonaka { 5233 1.22 nonaka const struct sysctlnode *rnode; 5234 1.22 nonaka const struct sysctlnode *cnode; 5235 1.22 nonaka int error; 5236 1.22 nonaka 5237 1.22 nonaka error = sysctl_createv(clog, 0, NULL, &rnode, 5238 1.22 nonaka CTLFLAG_PERMANENT, CTLTYPE_NODE, "hvn", 5239 1.22 nonaka SYSCTL_DESCR("hvn global controls"), 5240 1.22 nonaka NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 5241 1.22 nonaka if (error) 5242 1.22 nonaka goto fail; 5243 1.22 nonaka 5244 1.22 nonaka error = sysctl_createv(clog, 0, &rnode, &cnode, 5245 1.22 nonaka CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 5246 1.22 nonaka "udp_csum_fixup_mtu", 5247 1.22 nonaka SYSCTL_DESCR("UDP checksum offloding fixup MTU"), 5248 1.22 nonaka NULL, 0, &hvn_udpcs_fixup_mtu, sizeof(hvn_udpcs_fixup_mtu), 5249 1.22 nonaka CTL_CREATE, CTL_EOL); 5250 1.22 nonaka if (error) 5251 1.22 nonaka goto fail; 5252 1.22 nonaka 5253 1.22 nonaka error = sysctl_createv(clog, 0, &rnode, &cnode, 5254 1.22 nonaka CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 5255 1.22 nonaka "chimney_size", 5256 1.22 nonaka SYSCTL_DESCR("Chimney send packet size limit"), 5257 1.22 nonaka NULL, 0, &hvn_tx_chimney_size, sizeof(hvn_tx_chimney_size), 5258 1.22 nonaka CTL_CREATE, CTL_EOL); 5259 1.22 nonaka if (error) 5260 1.22 nonaka goto fail; 5261 1.22 nonaka 5262 1.22 nonaka error = sysctl_createv(clog, 0, &rnode, &cnode, 5263 1.22 nonaka CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 5264 1.22 nonaka "channel_count", 5265 1.22 nonaka SYSCTL_DESCR("# of channels to use"), 5266 1.22 nonaka NULL, 0, &hvn_channel_cnt, sizeof(hvn_channel_cnt), 5267 1.22 nonaka CTL_CREATE, CTL_EOL); 5268 1.22 nonaka if (error) 5269 1.22 nonaka goto fail; 5270 1.22 nonaka 5271 1.22 nonaka error = sysctl_createv(clog, 0, &rnode, &cnode, 5272 1.22 nonaka CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 5273 1.22 nonaka "tx_ring_count", 5274 1.22 nonaka SYSCTL_DESCR("# of transmit rings to use"), 5275 1.22 nonaka NULL, 0, &hvn_tx_ring_cnt, sizeof(hvn_tx_ring_cnt), 5276 1.22 nonaka CTL_CREATE, CTL_EOL); 5277 1.22 nonaka if (error) 5278 1.22 nonaka goto fail; 5279 1.22 nonaka 5280 1.22 nonaka return; 5281 1.22 nonaka 5282 1.22 nonaka fail: 5283 1.22 nonaka aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, error); 5284 1.1 nonaka } 5285